kaneo (minimalist kanban) fork to experiment adding a tangled integration
github.com/usekaneo/kaneo
1"use client";
2
3import { mergeProps } from "@base-ui/react/merge-props";
4import { useRender } from "@base-ui/react/use-render";
5
6import { cn } from "@/lib/cn";
7
8function Card({
9 className,
10 render,
11 ...props
12}: useRender.ComponentProps<"div">) {
13 const defaultProps = {
14 className: cn(
15 "relative flex flex-col rounded-2xl border bg-card not-dark:bg-clip-padding text-card-foreground shadow-xs/5 before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-2xl)-1px)] before:shadow-[0_1px_--theme(--color-black/4%)] dark:before:shadow-[0_-1px_--theme(--color-white/6%)]",
16 className,
17 ),
18 "data-slot": "card",
19 };
20
21 return useRender({
22 defaultTagName: "div",
23 props: mergeProps<"div">(defaultProps, props),
24 render,
25 });
26}
27
28function CardFrame({
29 className,
30 render,
31 ...props
32}: useRender.ComponentProps<"div">) {
33 const defaultProps = {
34 className: cn(
35 "[--clip-top:-1rem] [--clip-bottom:-1rem] *:data-[slot=card]:first:[--clip-top:1px] *:data-[slot=card]:last:[--clip-bottom:1px] flex flex-col relative rounded-2xl border bg-card before:bg-muted/72 not-dark:bg-clip-padding text-card-foreground shadow-xs/5 before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-2xl)-1px)] before:shadow-[0_1px_--theme(--color-black/4%)] dark:before:shadow-[0_-1px_--theme(--color-white/6%)] *:data-[slot=card]:-m-px *:not-last:data-[slot=card]:rounded-b-xl *:not-last:data-[slot=card]:before:rounded-b-[calc(var(--radius-xl)-1px)] *:not-first:data-[slot=card]:rounded-t-xl *:not-first:data-[slot=card]:before:rounded-t-[calc(var(--radius-xl)-1px)] *:data-[slot=card]:[clip-path:inset(var(--clip-top)_1px_var(--clip-bottom)_1px_round_calc(var(--radius-2xl)-1px))] *:data-[slot=card]:shadow-none *:data-[slot=card]:before:hidden *:data-[slot=card]:bg-clip-padding",
36 className,
37 ),
38 "data-slot": "card-frame",
39 };
40
41 return useRender({
42 defaultTagName: "div",
43 props: mergeProps<"div">(defaultProps, props),
44 render,
45 });
46}
47
48function CardFrameHeader({
49 className,
50 render,
51 ...props
52}: useRender.ComponentProps<"div">) {
53 const defaultProps = {
54 className: cn("relative flex flex-col px-6 py-4", className),
55 "data-slot": "card-frame-header",
56 };
57
58 return useRender({
59 defaultTagName: "div",
60 props: mergeProps<"div">(defaultProps, props),
61 render,
62 });
63}
64
65function CardFrameTitle({
66 className,
67 render,
68 ...props
69}: useRender.ComponentProps<"div">) {
70 const defaultProps = {
71 className: cn("font-semibold text-sm", className),
72 "data-slot": "card-frame-title",
73 };
74
75 return useRender({
76 defaultTagName: "div",
77 props: mergeProps<"div">(defaultProps, props),
78 render,
79 });
80}
81
82function CardFrameDescription({
83 className,
84 render,
85 ...props
86}: useRender.ComponentProps<"div">) {
87 const defaultProps = {
88 className: cn("text-muted-foreground text-sm", className),
89 "data-slot": "card-frame-description",
90 };
91
92 return useRender({
93 defaultTagName: "div",
94 props: mergeProps<"div">(defaultProps, props),
95 render,
96 });
97}
98
99function CardFrameFooter({
100 className,
101 render,
102 ...props
103}: useRender.ComponentProps<"div">) {
104 const defaultProps = {
105 className: cn("px-6 py-4", className),
106 "data-slot": "card-frame-footer",
107 };
108
109 return useRender({
110 defaultTagName: "div",
111 props: mergeProps<"div">(defaultProps, props),
112 render,
113 });
114}
115
116function CardHeader({
117 className,
118 render,
119 ...props
120}: useRender.ComponentProps<"div">) {
121 const defaultProps = {
122 className: cn(
123 "grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 p-6 in-[[data-slot=card]:has(>[data-slot=card-panel])]:pb-4 has-data-[slot=card-action]:grid-cols-[1fr_auto]",
124 className,
125 ),
126 "data-slot": "card-header",
127 };
128
129 return useRender({
130 defaultTagName: "div",
131 props: mergeProps<"div">(defaultProps, props),
132 render,
133 });
134}
135
136function CardTitle({
137 className,
138 render,
139 ...props
140}: useRender.ComponentProps<"div">) {
141 const defaultProps = {
142 className: cn("font-semibold text-lg leading-none", className),
143 "data-slot": "card-title",
144 };
145
146 return useRender({
147 defaultTagName: "div",
148 props: mergeProps<"div">(defaultProps, props),
149 render,
150 });
151}
152
153function CardDescription({
154 className,
155 render,
156 ...props
157}: useRender.ComponentProps<"div">) {
158 const defaultProps = {
159 className: cn("text-muted-foreground text-sm", className),
160 "data-slot": "card-description",
161 };
162
163 return useRender({
164 defaultTagName: "div",
165 props: mergeProps<"div">(defaultProps, props),
166 render,
167 });
168}
169
170function CardAction({
171 className,
172 render,
173 ...props
174}: useRender.ComponentProps<"div">) {
175 const defaultProps = {
176 className: cn(
177 "col-start-2 row-span-2 row-start-1 self-start justify-self-end inline-flex",
178 className,
179 ),
180 "data-slot": "card-action",
181 };
182
183 return useRender({
184 defaultTagName: "div",
185 props: mergeProps<"div">(defaultProps, props),
186 render,
187 });
188}
189
190function CardPanel({
191 className,
192 render,
193 ...props
194}: useRender.ComponentProps<"div">) {
195 const defaultProps = {
196 className: cn(
197 "flex-1 p-6 in-[[data-slot=card]:has(>[data-slot=card-header]:not(.border-b))]:pt-0 in-[[data-slot=card]:has(>[data-slot=card-footer]:not(.border-t))]:pb-0",
198 className,
199 ),
200 "data-slot": "card-panel",
201 };
202
203 return useRender({
204 defaultTagName: "div",
205 props: mergeProps<"div">(defaultProps, props),
206 render,
207 });
208}
209
210function CardFooter({
211 className,
212 render,
213 ...props
214}: useRender.ComponentProps<"div">) {
215 const defaultProps = {
216 className: cn(
217 "flex items-center p-6 in-[[data-slot=card]:has(>[data-slot=card-panel])]:pt-4",
218 className,
219 ),
220 "data-slot": "card-footer",
221 };
222
223 return useRender({
224 defaultTagName: "div",
225 props: mergeProps<"div">(defaultProps, props),
226 render,
227 });
228}
229
230export {
231 Card,
232 CardFrame,
233 CardFrameHeader,
234 CardFrameTitle,
235 CardFrameDescription,
236 CardFrameFooter,
237 CardAction,
238 CardDescription,
239 CardFooter,
240 CardHeader,
241 CardPanel,
242 CardPanel as CardContent,
243 CardTitle,
244};