@downcity/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/index.cjs +586 -0
- package/dist/index.d.cts +104 -0
- package/dist/index.d.ts +104 -0
- package/dist/index.js +529 -0
- package/package.json +69 -0
- package/src/styles.css +137 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
// src/lib/utils.ts
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import { twMerge } from "tailwind-merge";
|
|
4
|
+
function cn(...inputs) {
|
|
5
|
+
return twMerge(clsx(inputs));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// src/components/button.tsx
|
|
9
|
+
import { Button as ButtonPrimitive } from "@base-ui/react/button";
|
|
10
|
+
import { cva } from "class-variance-authority";
|
|
11
|
+
import { jsx } from "react/jsx-runtime";
|
|
12
|
+
var buttonVariants = cva(
|
|
13
|
+
"group/button inline-flex shrink-0 items-center justify-center rounded-[12px] border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/35 active:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
14
|
+
{
|
|
15
|
+
variants: {
|
|
16
|
+
variant: {
|
|
17
|
+
default: "bg-transparent text-foreground hover:bg-foreground/8 hover:text-foreground aria-expanded:bg-foreground/8 aria-expanded:text-foreground",
|
|
18
|
+
outline: "border-transparent bg-transparent text-foreground hover:bg-foreground/8 hover:text-foreground aria-expanded:bg-foreground/8 aria-expanded:text-foreground",
|
|
19
|
+
secondary: "border-transparent bg-transparent text-foreground hover:bg-foreground/8 hover:text-foreground aria-expanded:bg-foreground/8 aria-expanded:text-foreground",
|
|
20
|
+
ghost: "bg-transparent hover:bg-foreground/8 hover:text-foreground aria-expanded:bg-foreground/8 aria-expanded:text-foreground",
|
|
21
|
+
destructive: "bg-transparent text-destructive hover:bg-foreground/8 hover:text-destructive focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
|
|
22
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
23
|
+
},
|
|
24
|
+
size: {
|
|
25
|
+
default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
|
|
26
|
+
xs: "h-6 gap-1 rounded-[10px] px-2 text-xs in-data-[slot=button-group]:rounded-[10px] has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
27
|
+
sm: "h-8 gap-1 rounded-[11px] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-[11px] has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
|
28
|
+
lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3.5 has-data-[icon=inline-start]:pl-3.5",
|
|
29
|
+
icon: "size-9 rounded-[11px]",
|
|
30
|
+
"icon-xs": "size-6 rounded-[10px] in-data-[slot=button-group]:rounded-[10px] [&_svg:not([class*='size-'])]:size-3",
|
|
31
|
+
"icon-sm": "size-8 rounded-[11px] in-data-[slot=button-group]:rounded-[11px]",
|
|
32
|
+
"icon-lg": "size-10 rounded-[12px]"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
defaultVariants: {
|
|
36
|
+
variant: "default",
|
|
37
|
+
size: "default"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
function Button({
|
|
42
|
+
className,
|
|
43
|
+
variant = "default",
|
|
44
|
+
size = "default",
|
|
45
|
+
...props
|
|
46
|
+
}) {
|
|
47
|
+
return /* @__PURE__ */ jsx(
|
|
48
|
+
ButtonPrimitive,
|
|
49
|
+
{
|
|
50
|
+
"data-slot": "button",
|
|
51
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
52
|
+
...props
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/components/badge.tsx
|
|
58
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
59
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
60
|
+
import { cva as cva2 } from "class-variance-authority";
|
|
61
|
+
var badgeVariants = cva2(
|
|
62
|
+
"group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-colors focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/30 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
|
|
63
|
+
{
|
|
64
|
+
variants: {
|
|
65
|
+
variant: {
|
|
66
|
+
default: "border-neutral-900 bg-neutral-900 text-neutral-50 [a]:hover:bg-neutral-800",
|
|
67
|
+
secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-accent",
|
|
68
|
+
destructive: "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 [a]:hover:bg-destructive/20",
|
|
69
|
+
outline: "bg-card text-foreground [a]:hover:bg-secondary [a]:hover:text-foreground",
|
|
70
|
+
ghost: "hover:bg-card hover:text-foreground dark:hover:bg-muted/50",
|
|
71
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
defaultVariants: {
|
|
75
|
+
variant: "default"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
function Badge({
|
|
80
|
+
className,
|
|
81
|
+
variant = "default",
|
|
82
|
+
render,
|
|
83
|
+
...props
|
|
84
|
+
}) {
|
|
85
|
+
return useRender({
|
|
86
|
+
defaultTagName: "span",
|
|
87
|
+
props: mergeProps(
|
|
88
|
+
{
|
|
89
|
+
className: cn(badgeVariants({ variant }), className)
|
|
90
|
+
},
|
|
91
|
+
props
|
|
92
|
+
),
|
|
93
|
+
render,
|
|
94
|
+
state: {
|
|
95
|
+
slot: "badge",
|
|
96
|
+
variant
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/components/card.tsx
|
|
102
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
103
|
+
function Card({
|
|
104
|
+
className,
|
|
105
|
+
size = "default",
|
|
106
|
+
...props
|
|
107
|
+
}) {
|
|
108
|
+
return /* @__PURE__ */ jsx2(
|
|
109
|
+
"div",
|
|
110
|
+
{
|
|
111
|
+
"data-slot": "card",
|
|
112
|
+
"data-size": size,
|
|
113
|
+
className: cn(
|
|
114
|
+
"group/card flex flex-col gap-3 overflow-hidden rounded-[22px] bg-card text-sm text-card-foreground shadow-[0_1px_0_rgba(17,17,19,0.02),0_12px_28px_rgba(17,17,19,0.03)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-2 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none",
|
|
115
|
+
className
|
|
116
|
+
),
|
|
117
|
+
...props
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
function CardHeader({ className, ...props }) {
|
|
122
|
+
return /* @__PURE__ */ jsx2(
|
|
123
|
+
"div",
|
|
124
|
+
{
|
|
125
|
+
"data-slot": "card-header",
|
|
126
|
+
className: cn(
|
|
127
|
+
"group/card-header @container/card-header grid auto-rows-min items-start gap-1 px-5 pt-5 group-data-[size=sm]/card:px-4 group-data-[size=sm]/card:pt-4 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-3 group-data-[size=sm]/card:[.border-b]:pb-2",
|
|
128
|
+
className
|
|
129
|
+
),
|
|
130
|
+
...props
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
function CardTitle({ className, ...props }) {
|
|
135
|
+
return /* @__PURE__ */ jsx2(
|
|
136
|
+
"div",
|
|
137
|
+
{
|
|
138
|
+
"data-slot": "card-title",
|
|
139
|
+
className: cn(
|
|
140
|
+
"text-[1rem] leading-snug font-semibold tracking-[-0.02em] text-foreground group-data-[size=sm]/card:text-sm",
|
|
141
|
+
className
|
|
142
|
+
),
|
|
143
|
+
...props
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
function CardDescription({ className, ...props }) {
|
|
148
|
+
return /* @__PURE__ */ jsx2(
|
|
149
|
+
"div",
|
|
150
|
+
{
|
|
151
|
+
"data-slot": "card-description",
|
|
152
|
+
className: cn("text-sm leading-6 text-muted-foreground", className),
|
|
153
|
+
...props
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
function CardAction({ className, ...props }) {
|
|
158
|
+
return /* @__PURE__ */ jsx2(
|
|
159
|
+
"div",
|
|
160
|
+
{
|
|
161
|
+
"data-slot": "card-action",
|
|
162
|
+
className: cn(
|
|
163
|
+
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
|
|
164
|
+
className
|
|
165
|
+
),
|
|
166
|
+
...props
|
|
167
|
+
}
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
function CardContent({ className, ...props }) {
|
|
171
|
+
return /* @__PURE__ */ jsx2(
|
|
172
|
+
"div",
|
|
173
|
+
{
|
|
174
|
+
"data-slot": "card-content",
|
|
175
|
+
className: cn(
|
|
176
|
+
"px-5 pb-5 group-data-[size=sm]/card:px-4 group-data-[size=sm]/card:pb-4",
|
|
177
|
+
className
|
|
178
|
+
),
|
|
179
|
+
...props
|
|
180
|
+
}
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
function CardFooter({ className, ...props }) {
|
|
184
|
+
return /* @__PURE__ */ jsx2(
|
|
185
|
+
"div",
|
|
186
|
+
{
|
|
187
|
+
"data-slot": "card-footer",
|
|
188
|
+
className: cn(
|
|
189
|
+
"flex items-center bg-secondary px-5 py-3 group-data-[size=sm]/card:px-4 group-data-[size=sm]/card:py-2.5",
|
|
190
|
+
className
|
|
191
|
+
),
|
|
192
|
+
...props
|
|
193
|
+
}
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// src/components/dropdown-menu.tsx
|
|
198
|
+
import { Menu as MenuPrimitive } from "@base-ui/react/menu";
|
|
199
|
+
import { CheckIcon, ChevronRightIcon } from "lucide-react";
|
|
200
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
201
|
+
function DropdownMenu({ ...props }) {
|
|
202
|
+
return /* @__PURE__ */ jsx3(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
203
|
+
}
|
|
204
|
+
function DropdownMenuPortal({ ...props }) {
|
|
205
|
+
return /* @__PURE__ */ jsx3(MenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
|
|
206
|
+
}
|
|
207
|
+
function DropdownMenuTrigger({ ...props }) {
|
|
208
|
+
return /* @__PURE__ */ jsx3(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
209
|
+
}
|
|
210
|
+
function DropdownMenuContent({
|
|
211
|
+
align = "start",
|
|
212
|
+
alignOffset = 0,
|
|
213
|
+
side = "bottom",
|
|
214
|
+
sideOffset = 4,
|
|
215
|
+
className,
|
|
216
|
+
...props
|
|
217
|
+
}) {
|
|
218
|
+
return /* @__PURE__ */ jsx3(MenuPrimitive.Portal, { children: /* @__PURE__ */ jsx3(
|
|
219
|
+
MenuPrimitive.Positioner,
|
|
220
|
+
{
|
|
221
|
+
className: "isolate z-50 outline-none",
|
|
222
|
+
align,
|
|
223
|
+
alignOffset,
|
|
224
|
+
side,
|
|
225
|
+
sideOffset,
|
|
226
|
+
children: /* @__PURE__ */ jsx3(
|
|
227
|
+
MenuPrimitive.Popup,
|
|
228
|
+
{
|
|
229
|
+
"data-slot": "dropdown-menu-content",
|
|
230
|
+
className: cn(
|
|
231
|
+
"z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-[18px] border border-border/70 bg-popover/98 p-1.5 text-popover-foreground shadow-[0_10px_24px_rgba(24,24,27,0.045)] duration-100 outline-none backdrop-blur-xl data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
232
|
+
className
|
|
233
|
+
),
|
|
234
|
+
...props
|
|
235
|
+
}
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
) });
|
|
239
|
+
}
|
|
240
|
+
function DropdownMenuGroup({ ...props }) {
|
|
241
|
+
return /* @__PURE__ */ jsx3(MenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
|
|
242
|
+
}
|
|
243
|
+
function DropdownMenuLabel({
|
|
244
|
+
className,
|
|
245
|
+
inset,
|
|
246
|
+
...props
|
|
247
|
+
}) {
|
|
248
|
+
return /* @__PURE__ */ jsx3(
|
|
249
|
+
MenuPrimitive.GroupLabel,
|
|
250
|
+
{
|
|
251
|
+
"data-slot": "dropdown-menu-label",
|
|
252
|
+
"data-inset": inset,
|
|
253
|
+
className: cn(
|
|
254
|
+
"px-2.5 py-1.5 text-[0.62rem] font-medium uppercase tracking-[0.16em] text-muted-foreground data-inset:pl-7",
|
|
255
|
+
className
|
|
256
|
+
),
|
|
257
|
+
...props
|
|
258
|
+
}
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
function DropdownMenuItem({
|
|
262
|
+
className,
|
|
263
|
+
inset,
|
|
264
|
+
variant = "default",
|
|
265
|
+
...props
|
|
266
|
+
}) {
|
|
267
|
+
return /* @__PURE__ */ jsx3(
|
|
268
|
+
MenuPrimitive.Item,
|
|
269
|
+
{
|
|
270
|
+
"data-slot": "dropdown-menu-item",
|
|
271
|
+
"data-inset": inset,
|
|
272
|
+
"data-variant": variant,
|
|
273
|
+
className: cn(
|
|
274
|
+
"group/dropdown-menu-item relative flex min-h-10 cursor-default items-center gap-1.5 rounded-[12px] px-3 py-2 text-sm outline-hidden select-none focus:bg-secondary focus:text-foreground not-data-[variant=destructive]:focus:**:text-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",
|
|
275
|
+
className
|
|
276
|
+
),
|
|
277
|
+
...props
|
|
278
|
+
}
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
function DropdownMenuSub({ ...props }) {
|
|
282
|
+
return /* @__PURE__ */ jsx3(MenuPrimitive.SubmenuRoot, { "data-slot": "dropdown-menu-sub", ...props });
|
|
283
|
+
}
|
|
284
|
+
function DropdownMenuSubTrigger({
|
|
285
|
+
className,
|
|
286
|
+
inset,
|
|
287
|
+
children,
|
|
288
|
+
...props
|
|
289
|
+
}) {
|
|
290
|
+
return /* @__PURE__ */ jsxs(
|
|
291
|
+
MenuPrimitive.SubmenuTrigger,
|
|
292
|
+
{
|
|
293
|
+
"data-slot": "dropdown-menu-sub-trigger",
|
|
294
|
+
"data-inset": inset,
|
|
295
|
+
className: cn(
|
|
296
|
+
"flex min-h-10 cursor-default items-center gap-1.5 rounded-[12px] px-3 py-2 text-sm outline-hidden select-none focus:bg-secondary focus:text-foreground not-data-[variant=destructive]:focus:**:text-foreground data-inset:pl-7 data-popup-open:bg-secondary data-popup-open:text-foreground data-open:bg-secondary data-open:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
297
|
+
className
|
|
298
|
+
),
|
|
299
|
+
...props,
|
|
300
|
+
children: [
|
|
301
|
+
children,
|
|
302
|
+
/* @__PURE__ */ jsx3(ChevronRightIcon, { className: "ml-auto" })
|
|
303
|
+
]
|
|
304
|
+
}
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
function DropdownMenuSubContent({
|
|
308
|
+
align = "start",
|
|
309
|
+
alignOffset = -3,
|
|
310
|
+
side = "right",
|
|
311
|
+
sideOffset = 0,
|
|
312
|
+
className,
|
|
313
|
+
...props
|
|
314
|
+
}) {
|
|
315
|
+
return /* @__PURE__ */ jsx3(
|
|
316
|
+
DropdownMenuContent,
|
|
317
|
+
{
|
|
318
|
+
"data-slot": "dropdown-menu-sub-content",
|
|
319
|
+
className: cn(
|
|
320
|
+
"w-auto min-w-[96px] rounded-[18px] border border-border/70 bg-popover/98 p-1.5 text-popover-foreground shadow-[0_10px_24px_rgba(24,24,27,0.045)] duration-100 backdrop-blur-xl data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
321
|
+
className
|
|
322
|
+
),
|
|
323
|
+
align,
|
|
324
|
+
alignOffset,
|
|
325
|
+
side,
|
|
326
|
+
sideOffset,
|
|
327
|
+
...props
|
|
328
|
+
}
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
function DropdownMenuCheckboxItem({
|
|
332
|
+
className,
|
|
333
|
+
children,
|
|
334
|
+
checked,
|
|
335
|
+
inset,
|
|
336
|
+
...props
|
|
337
|
+
}) {
|
|
338
|
+
return /* @__PURE__ */ jsxs(
|
|
339
|
+
MenuPrimitive.CheckboxItem,
|
|
340
|
+
{
|
|
341
|
+
"data-slot": "dropdown-menu-checkbox-item",
|
|
342
|
+
"data-inset": inset,
|
|
343
|
+
className: cn(
|
|
344
|
+
"relative flex min-h-10 cursor-default items-center gap-1.5 rounded-[12px] py-2 pr-8 pl-3 text-sm outline-hidden select-none focus:bg-secondary focus:text-foreground focus:**:text-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
345
|
+
className
|
|
346
|
+
),
|
|
347
|
+
checked,
|
|
348
|
+
...props,
|
|
349
|
+
children: [
|
|
350
|
+
/* @__PURE__ */ jsx3(
|
|
351
|
+
"span",
|
|
352
|
+
{
|
|
353
|
+
className: "pointer-events-none absolute right-2 flex items-center justify-center",
|
|
354
|
+
"data-slot": "dropdown-menu-checkbox-item-indicator",
|
|
355
|
+
children: /* @__PURE__ */ jsx3(MenuPrimitive.CheckboxItemIndicator, { children: /* @__PURE__ */ jsx3(CheckIcon, {}) })
|
|
356
|
+
}
|
|
357
|
+
),
|
|
358
|
+
children
|
|
359
|
+
]
|
|
360
|
+
}
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
function DropdownMenuRadioGroup({ ...props }) {
|
|
364
|
+
return /* @__PURE__ */ jsx3(MenuPrimitive.RadioGroup, { "data-slot": "dropdown-menu-radio-group", ...props });
|
|
365
|
+
}
|
|
366
|
+
function DropdownMenuRadioItem({
|
|
367
|
+
className,
|
|
368
|
+
children,
|
|
369
|
+
inset,
|
|
370
|
+
...props
|
|
371
|
+
}) {
|
|
372
|
+
return /* @__PURE__ */ jsxs(
|
|
373
|
+
MenuPrimitive.RadioItem,
|
|
374
|
+
{
|
|
375
|
+
"data-slot": "dropdown-menu-radio-item",
|
|
376
|
+
"data-inset": inset,
|
|
377
|
+
className: cn(
|
|
378
|
+
"relative flex min-h-10 cursor-default items-center gap-1.5 rounded-[12px] py-2 pr-8 pl-3 text-sm outline-hidden select-none focus:bg-secondary focus:text-foreground focus:**:text-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
379
|
+
className
|
|
380
|
+
),
|
|
381
|
+
...props,
|
|
382
|
+
children: [
|
|
383
|
+
/* @__PURE__ */ jsx3(
|
|
384
|
+
"span",
|
|
385
|
+
{
|
|
386
|
+
className: "pointer-events-none absolute right-2 flex items-center justify-center",
|
|
387
|
+
"data-slot": "dropdown-menu-radio-item-indicator",
|
|
388
|
+
children: /* @__PURE__ */ jsx3(MenuPrimitive.RadioItemIndicator, { children: /* @__PURE__ */ jsx3(CheckIcon, {}) })
|
|
389
|
+
}
|
|
390
|
+
),
|
|
391
|
+
children
|
|
392
|
+
]
|
|
393
|
+
}
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
function DropdownMenuSeparator({
|
|
397
|
+
className,
|
|
398
|
+
...props
|
|
399
|
+
}) {
|
|
400
|
+
return /* @__PURE__ */ jsx3(
|
|
401
|
+
MenuPrimitive.Separator,
|
|
402
|
+
{
|
|
403
|
+
"data-slot": "dropdown-menu-separator",
|
|
404
|
+
className: cn("bg-border -mx-0.5 my-1 h-px", className),
|
|
405
|
+
...props
|
|
406
|
+
}
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
function DropdownMenuShortcut({
|
|
410
|
+
className,
|
|
411
|
+
...props
|
|
412
|
+
}) {
|
|
413
|
+
return /* @__PURE__ */ jsx3(
|
|
414
|
+
"span",
|
|
415
|
+
{
|
|
416
|
+
"data-slot": "dropdown-menu-shortcut",
|
|
417
|
+
className: cn(
|
|
418
|
+
"ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-foreground",
|
|
419
|
+
className
|
|
420
|
+
),
|
|
421
|
+
...props
|
|
422
|
+
}
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// src/components/popover.tsx
|
|
427
|
+
import { Popover as PopoverPrimitive } from "@base-ui/react/popover";
|
|
428
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
429
|
+
function Popover({ ...props }) {
|
|
430
|
+
return /* @__PURE__ */ jsx4(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
|
|
431
|
+
}
|
|
432
|
+
function PopoverTrigger({ ...props }) {
|
|
433
|
+
return /* @__PURE__ */ jsx4(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
434
|
+
}
|
|
435
|
+
function PopoverContent({
|
|
436
|
+
className,
|
|
437
|
+
side = "bottom",
|
|
438
|
+
sideOffset = 6,
|
|
439
|
+
align = "center",
|
|
440
|
+
alignOffset = 0,
|
|
441
|
+
...props
|
|
442
|
+
}) {
|
|
443
|
+
return /* @__PURE__ */ jsx4(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx4(
|
|
444
|
+
PopoverPrimitive.Positioner,
|
|
445
|
+
{
|
|
446
|
+
side,
|
|
447
|
+
sideOffset,
|
|
448
|
+
align,
|
|
449
|
+
alignOffset,
|
|
450
|
+
className: "isolate z-50",
|
|
451
|
+
children: /* @__PURE__ */ jsx4(
|
|
452
|
+
PopoverPrimitive.Popup,
|
|
453
|
+
{
|
|
454
|
+
"data-slot": "popover-content",
|
|
455
|
+
className: cn(
|
|
456
|
+
"z-50 origin-(--transform-origin) rounded-[18px] border border-border/70 bg-popover/98 text-popover-foreground shadow-[0_10px_24px_rgba(24,24,27,0.045)] outline-none backdrop-blur-xl data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
457
|
+
className
|
|
458
|
+
),
|
|
459
|
+
...props
|
|
460
|
+
}
|
|
461
|
+
)
|
|
462
|
+
}
|
|
463
|
+
) });
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// src/components/sonner.tsx
|
|
467
|
+
import { CircleCheckIcon, InfoIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon } from "lucide-react";
|
|
468
|
+
import { Toaster as Sonner } from "sonner";
|
|
469
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
470
|
+
function Toaster({ ...props }) {
|
|
471
|
+
return /* @__PURE__ */ jsx5(
|
|
472
|
+
Sonner,
|
|
473
|
+
{
|
|
474
|
+
className: "toaster group",
|
|
475
|
+
icons: {
|
|
476
|
+
success: /* @__PURE__ */ jsx5(CircleCheckIcon, { className: "size-4" }),
|
|
477
|
+
info: /* @__PURE__ */ jsx5(InfoIcon, { className: "size-4" }),
|
|
478
|
+
warning: /* @__PURE__ */ jsx5(TriangleAlertIcon, { className: "size-4" }),
|
|
479
|
+
error: /* @__PURE__ */ jsx5(OctagonXIcon, { className: "size-4" }),
|
|
480
|
+
loading: /* @__PURE__ */ jsx5(Loader2Icon, { className: "size-4 animate-spin" })
|
|
481
|
+
},
|
|
482
|
+
style: {
|
|
483
|
+
"--normal-bg": "var(--popover)",
|
|
484
|
+
"--normal-text": "var(--popover-foreground)",
|
|
485
|
+
"--normal-border": "var(--border)",
|
|
486
|
+
"--border-radius": "var(--radius)"
|
|
487
|
+
},
|
|
488
|
+
toastOptions: {
|
|
489
|
+
classNames: {
|
|
490
|
+
toast: "cn-toast"
|
|
491
|
+
}
|
|
492
|
+
},
|
|
493
|
+
...props
|
|
494
|
+
}
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
export {
|
|
498
|
+
Badge,
|
|
499
|
+
Button,
|
|
500
|
+
Card,
|
|
501
|
+
CardAction,
|
|
502
|
+
CardContent,
|
|
503
|
+
CardDescription,
|
|
504
|
+
CardFooter,
|
|
505
|
+
CardHeader,
|
|
506
|
+
CardTitle,
|
|
507
|
+
DropdownMenu,
|
|
508
|
+
DropdownMenuCheckboxItem,
|
|
509
|
+
DropdownMenuContent,
|
|
510
|
+
DropdownMenuGroup,
|
|
511
|
+
DropdownMenuItem,
|
|
512
|
+
DropdownMenuLabel,
|
|
513
|
+
DropdownMenuPortal,
|
|
514
|
+
DropdownMenuRadioGroup,
|
|
515
|
+
DropdownMenuRadioItem,
|
|
516
|
+
DropdownMenuSeparator,
|
|
517
|
+
DropdownMenuShortcut,
|
|
518
|
+
DropdownMenuSub,
|
|
519
|
+
DropdownMenuSubContent,
|
|
520
|
+
DropdownMenuSubTrigger,
|
|
521
|
+
DropdownMenuTrigger,
|
|
522
|
+
Popover,
|
|
523
|
+
PopoverContent,
|
|
524
|
+
PopoverTrigger,
|
|
525
|
+
Toaster,
|
|
526
|
+
badgeVariants,
|
|
527
|
+
buttonVariants,
|
|
528
|
+
cn
|
|
529
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@downcity/ui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Downcity UI SDK for React and Tailwind CSS applications.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://downcity.ai",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/wangenius/downcity.git",
|
|
11
|
+
"directory": "packages/downcity-ui"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/wangenius/downcity/issues"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"sideEffects": [
|
|
20
|
+
"./src/styles.css"
|
|
21
|
+
],
|
|
22
|
+
"main": "./dist/index.cjs",
|
|
23
|
+
"module": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"import": "./dist/index.js",
|
|
29
|
+
"require": "./dist/index.cjs"
|
|
30
|
+
},
|
|
31
|
+
"./styles.css": "./src/styles.css"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"src/styles.css"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsup src/index.ts --format esm,cjs --dts --clean",
|
|
39
|
+
"typecheck": "tsc --noEmit",
|
|
40
|
+
"prepublishOnly": "npm run build"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"react": "^19.0.0",
|
|
44
|
+
"react-dom": "^19.0.0"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@base-ui/react": "^1.3.0",
|
|
48
|
+
"class-variance-authority": "^0.7.1",
|
|
49
|
+
"clsx": "^2.1.1",
|
|
50
|
+
"lucide-react": "^0.577.0",
|
|
51
|
+
"sonner": "^2.0.7",
|
|
52
|
+
"tailwind-merge": "^3.5.0"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"react": "^19.0.0",
|
|
56
|
+
"react-dom": "^19.0.0",
|
|
57
|
+
"@types/react": "^19.0.0",
|
|
58
|
+
"@types/react-dom": "^19.0.0",
|
|
59
|
+
"tsup": "^8.5.0",
|
|
60
|
+
"typescript": "^5.9.2"
|
|
61
|
+
},
|
|
62
|
+
"keywords": [
|
|
63
|
+
"downcity",
|
|
64
|
+
"ui",
|
|
65
|
+
"react",
|
|
66
|
+
"tailwind",
|
|
67
|
+
"agent"
|
|
68
|
+
]
|
|
69
|
+
}
|