@trycompai/design-system 1.0.0 → 1.0.2
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/package.json +6 -3
- package/src/components/atoms/badge.tsx +49 -0
- package/src/components/{ui → atoms}/button.tsx +6 -1
- package/src/components/{ui → atoms}/checkbox.tsx +3 -3
- package/src/components/{ui → atoms}/heading.tsx +6 -6
- package/src/components/atoms/index.ts +21 -0
- package/src/components/atoms/kbd.tsx +21 -0
- package/src/components/atoms/logo.tsx +52 -0
- package/src/components/{ui → atoms}/slider.tsx +4 -4
- package/src/components/{ui → atoms}/spinner.tsx +3 -3
- package/src/components/atoms/stack.tsx +97 -0
- package/src/components/{ui → atoms}/switch.tsx +1 -1
- package/src/components/{ui → atoms}/text.tsx +5 -1
- package/src/components/{ui → atoms}/textarea.tsx +8 -2
- package/src/components/{ui → atoms}/toggle.tsx +3 -6
- package/src/components/{ui → molecules}/accordion.tsx +3 -3
- package/src/components/molecules/ai-chat.tsx +217 -0
- package/src/components/{ui → molecules}/alert.tsx +5 -5
- package/src/components/{ui → molecules}/breadcrumb.tsx +9 -8
- package/src/components/{ui → molecules}/card.tsx +24 -5
- package/src/components/molecules/command-search.tsx +147 -0
- package/src/components/molecules/empty.tsx +82 -0
- package/src/components/{ui → molecules}/field.tsx +16 -37
- package/src/components/{ui → molecules}/hover-card.tsx +2 -8
- package/src/components/molecules/index.ts +29 -0
- package/src/components/{ui → molecules}/input-group.tsx +1 -1
- package/src/components/molecules/input-otp.tsx +70 -0
- package/src/components/{ui → molecules}/item.tsx +18 -36
- package/src/components/molecules/page-header.tsx +80 -0
- package/src/components/{ui → molecules}/pagination.tsx +14 -23
- package/src/components/{ui → molecules}/popover.tsx +4 -2
- package/src/components/molecules/radio-group.tsx +33 -0
- package/src/components/{ui → molecules}/scroll-area.tsx +8 -11
- package/src/components/{ui → molecules}/section.tsx +3 -3
- package/src/components/{ui → molecules}/select.tsx +22 -10
- package/src/components/molecules/settings.tsx +169 -0
- package/src/components/{ui → molecules}/table.tsx +16 -3
- package/src/components/molecules/tabs.tsx +70 -0
- package/src/components/molecules/theme-switcher.tsx +176 -0
- package/src/components/{ui → molecules}/toggle-group.tsx +1 -1
- package/src/components/organisms/alert-dialog.tsx +135 -0
- package/src/components/organisms/app-shell.tsx +822 -0
- package/src/components/{ui → organisms}/calendar.tsx +6 -7
- package/src/components/{ui → organisms}/carousel.tsx +9 -11
- package/src/components/{ui → organisms}/chart.tsx +9 -24
- package/src/components/{ui → organisms}/combobox.tsx +7 -7
- package/src/components/{ui → organisms}/command.tsx +3 -3
- package/src/components/{ui → organisms}/context-menu.tsx +23 -53
- package/src/components/{ui → organisms}/dialog.tsx +3 -3
- package/src/components/{ui → organisms}/dropdown-menu.tsx +8 -6
- package/src/components/organisms/index.ts +17 -0
- package/src/components/{ui → organisms}/menubar.tsx +3 -3
- package/src/components/organisms/navigation-menu.tsx +137 -0
- package/src/components/organisms/page-layout.tsx +95 -0
- package/src/components/{ui → organisms}/sheet.tsx +7 -7
- package/src/components/{ui → organisms}/sidebar.tsx +61 -86
- package/src/components/organisms/sonner.tsx +41 -0
- package/src/components/ui/index.ts +3 -61
- package/src/fonts/TWKLausanne/TWKLausanne-300-Italic.woff +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-300-Italic.woff2 +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-300.woff +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-300.woff2 +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-350-Italic.woff +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-350-Italic.woff2 +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-350.woff +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-350.woff2 +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-400-Italic.woff +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-400-Italic.woff2 +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-400.woff +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-400.woff2 +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-700-Italic.woff +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-700-Italic.woff2 +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-700.woff +0 -0
- package/src/fonts/TWKLausanne/TWKLausanne-700.woff2 +0 -0
- package/src/styles/globals.css +167 -23
- package/src/components/ui/alert-dialog.tsx +0 -161
- package/src/components/ui/badge.tsx +0 -48
- package/src/components/ui/empty.tsx +0 -94
- package/src/components/ui/input-otp.tsx +0 -84
- package/src/components/ui/kbd.tsx +0 -26
- package/src/components/ui/navigation-menu.tsx +0 -147
- package/src/components/ui/page-header.tsx +0 -51
- package/src/components/ui/page-layout.tsx +0 -65
- package/src/components/ui/radio-group.tsx +0 -37
- package/src/components/ui/sonner.tsx +0 -43
- package/src/components/ui/stack.tsx +0 -72
- package/src/components/ui/tabs.tsx +0 -69
- /package/src/components/{ui → atoms}/aspect-ratio.tsx +0 -0
- /package/src/components/{ui → atoms}/avatar.tsx +0 -0
- /package/src/components/{ui → atoms}/container.tsx +0 -0
- /package/src/components/{ui → atoms}/input.tsx +0 -0
- /package/src/components/{ui → atoms}/label.tsx +0 -0
- /package/src/components/{ui → atoms}/progress.tsx +0 -0
- /package/src/components/{ui → atoms}/separator.tsx +0 -0
- /package/src/components/{ui → atoms}/skeleton.tsx +0 -0
- /package/src/components/{ui → molecules}/button-group.tsx +0 -0
- /package/src/components/{ui → molecules}/collapsible.tsx +0 -0
- /package/src/components/{ui → molecules}/grid.tsx +0 -0
- /package/src/components/{ui → molecules}/resizable.tsx +0 -0
- /package/src/components/{ui → molecules}/tooltip.tsx +0 -0
- /package/src/components/{ui → organisms}/drawer.tsx +0 -0
package/src/styles/globals.css
CHANGED
|
@@ -1,39 +1,120 @@
|
|
|
1
1
|
@import 'tailwindcss';
|
|
2
2
|
@import 'tw-animate-css';
|
|
3
3
|
|
|
4
|
+
/* Ramp font: Lausanne */
|
|
5
|
+
@font-face {
|
|
6
|
+
font-family: 'Lausanne';
|
|
7
|
+
src:
|
|
8
|
+
url('../fonts/TWKLausanne/TWKLausanne-300.woff2') format('woff2'),
|
|
9
|
+
url('../fonts/TWKLausanne/TWKLausanne-300.woff') format('woff');
|
|
10
|
+
font-weight: 300;
|
|
11
|
+
font-style: normal;
|
|
12
|
+
font-display: swap;
|
|
13
|
+
}
|
|
14
|
+
@font-face {
|
|
15
|
+
font-family: 'Lausanne';
|
|
16
|
+
src:
|
|
17
|
+
url('../fonts/TWKLausanne/TWKLausanne-300-Italic.woff2') format('woff2'),
|
|
18
|
+
url('../fonts/TWKLausanne/TWKLausanne-300-Italic.woff') format('woff');
|
|
19
|
+
font-weight: 300;
|
|
20
|
+
font-style: italic;
|
|
21
|
+
font-display: swap;
|
|
22
|
+
}
|
|
23
|
+
@font-face {
|
|
24
|
+
font-family: 'Lausanne';
|
|
25
|
+
src:
|
|
26
|
+
url('../fonts/TWKLausanne/TWKLausanne-350.woff2') format('woff2'),
|
|
27
|
+
url('../fonts/TWKLausanne/TWKLausanne-350.woff') format('woff');
|
|
28
|
+
font-weight: 350;
|
|
29
|
+
font-style: normal;
|
|
30
|
+
font-display: swap;
|
|
31
|
+
}
|
|
32
|
+
@font-face {
|
|
33
|
+
font-family: 'Lausanne';
|
|
34
|
+
src:
|
|
35
|
+
url('../fonts/TWKLausanne/TWKLausanne-350-Italic.woff2') format('woff2'),
|
|
36
|
+
url('../fonts/TWKLausanne/TWKLausanne-350-Italic.woff') format('woff');
|
|
37
|
+
font-weight: 350;
|
|
38
|
+
font-style: italic;
|
|
39
|
+
font-display: swap;
|
|
40
|
+
}
|
|
41
|
+
@font-face {
|
|
42
|
+
font-family: 'Lausanne';
|
|
43
|
+
src:
|
|
44
|
+
url('../fonts/TWKLausanne/TWKLausanne-400.woff2') format('woff2'),
|
|
45
|
+
url('../fonts/TWKLausanne/TWKLausanne-400.woff') format('woff');
|
|
46
|
+
font-weight: 400;
|
|
47
|
+
font-style: normal;
|
|
48
|
+
font-display: swap;
|
|
49
|
+
}
|
|
50
|
+
@font-face {
|
|
51
|
+
font-family: 'Lausanne';
|
|
52
|
+
src:
|
|
53
|
+
url('../fonts/TWKLausanne/TWKLausanne-400-Italic.woff2') format('woff2'),
|
|
54
|
+
url('../fonts/TWKLausanne/TWKLausanne-400-Italic.woff') format('woff');
|
|
55
|
+
font-weight: 400;
|
|
56
|
+
font-style: italic;
|
|
57
|
+
font-display: swap;
|
|
58
|
+
}
|
|
59
|
+
@font-face {
|
|
60
|
+
font-family: 'Lausanne';
|
|
61
|
+
src:
|
|
62
|
+
url('../fonts/TWKLausanne/TWKLausanne-700.woff2') format('woff2'),
|
|
63
|
+
url('../fonts/TWKLausanne/TWKLausanne-700.woff') format('woff');
|
|
64
|
+
font-weight: 700;
|
|
65
|
+
font-style: normal;
|
|
66
|
+
font-display: swap;
|
|
67
|
+
}
|
|
68
|
+
@font-face {
|
|
69
|
+
font-family: 'Lausanne';
|
|
70
|
+
src:
|
|
71
|
+
url('../fonts/TWKLausanne/TWKLausanne-700-Italic.woff2') format('woff2'),
|
|
72
|
+
url('../fonts/TWKLausanne/TWKLausanne-700-Italic.woff') format('woff');
|
|
73
|
+
font-weight: 700;
|
|
74
|
+
font-style: italic;
|
|
75
|
+
font-display: swap;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Include design system components in Tailwind's content scan */
|
|
79
|
+
@source "../components/**/*.tsx";
|
|
80
|
+
|
|
4
81
|
@custom-variant dark (&:is(.dark *));
|
|
5
82
|
|
|
6
83
|
@layer base {
|
|
7
84
|
:root {
|
|
85
|
+
--font-sans: 'Lausanne', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
|
8
86
|
--background: oklch(1 0 0);
|
|
9
87
|
--foreground: oklch(0.145 0 0);
|
|
10
88
|
--card: oklch(1 0 0);
|
|
11
89
|
--card-foreground: oklch(0.145 0 0);
|
|
12
90
|
--popover: oklch(1 0 0);
|
|
13
91
|
--popover-foreground: oklch(0.145 0 0);
|
|
14
|
-
--primary: oklch(0.
|
|
15
|
-
--primary-foreground: oklch(0.
|
|
16
|
-
--secondary: oklch(0.
|
|
92
|
+
--primary: oklch(0.596 0.145 163.225);
|
|
93
|
+
--primary-foreground: oklch(0.979 0.021 166.113);
|
|
94
|
+
--secondary: oklch(0.92 0.001 286.375);
|
|
17
95
|
--secondary-foreground: oklch(0.21 0.006 285.885);
|
|
18
|
-
--muted: oklch(0.
|
|
96
|
+
--muted: oklch(0.91 0 0);
|
|
19
97
|
--muted-foreground: oklch(0.556 0 0);
|
|
20
|
-
--accent: oklch(0.
|
|
98
|
+
--accent: oklch(0.91 0 0);
|
|
21
99
|
--accent-foreground: oklch(0.205 0 0);
|
|
22
100
|
--destructive: oklch(0.58 0.22 27);
|
|
101
|
+
--success: oklch(0.6 0.16 145);
|
|
102
|
+
--warning: oklch(0.75 0.15 85);
|
|
103
|
+
--info: oklch(0.6 0.15 250);
|
|
23
104
|
--border: oklch(0.922 0 0);
|
|
24
105
|
--input: oklch(0.922 0 0);
|
|
25
106
|
--ring: oklch(0.708 0 0);
|
|
26
|
-
--chart-1: oklch(0.
|
|
27
|
-
--chart-2: oklch(0.
|
|
28
|
-
--chart-3: oklch(0.
|
|
29
|
-
--chart-4: oklch(0.
|
|
30
|
-
--chart-5: oklch(0.
|
|
31
|
-
--radius: 0.
|
|
107
|
+
--chart-1: oklch(0.845 0.143 164.978);
|
|
108
|
+
--chart-2: oklch(0.765 0.177 163.223);
|
|
109
|
+
--chart-3: oklch(0.696 0.17 162.48);
|
|
110
|
+
--chart-4: oklch(0.596 0.145 163.225);
|
|
111
|
+
--chart-5: oklch(0.508 0.118 165.612);
|
|
112
|
+
--radius: 0.3rem;
|
|
32
113
|
--sidebar: oklch(0.985 0 0);
|
|
33
114
|
--sidebar-foreground: oklch(0.145 0 0);
|
|
34
|
-
--sidebar-primary: oklch(0.
|
|
35
|
-
--sidebar-primary-foreground: oklch(0.
|
|
36
|
-
--sidebar-accent: oklch(0.
|
|
115
|
+
--sidebar-primary: oklch(0.596 0.145 163.225);
|
|
116
|
+
--sidebar-primary-foreground: oklch(0.979 0.021 166.113);
|
|
117
|
+
--sidebar-accent: oklch(0.91 0 0);
|
|
37
118
|
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
38
119
|
--sidebar-border: oklch(0.922 0 0);
|
|
39
120
|
--sidebar-ring: oklch(0.708 0 0);
|
|
@@ -45,8 +126,8 @@
|
|
|
45
126
|
--card-foreground: oklch(0.985 0 0);
|
|
46
127
|
--popover: oklch(0.205 0 0);
|
|
47
128
|
--popover-foreground: oklch(0.985 0 0);
|
|
48
|
-
--primary: oklch(0.
|
|
49
|
-
--primary-foreground: oklch(0.
|
|
129
|
+
--primary: oklch(0.696 0.17 162.48);
|
|
130
|
+
--primary-foreground: oklch(0.262 0.051 172.552);
|
|
50
131
|
--secondary: oklch(0.274 0.006 286.033);
|
|
51
132
|
--secondary-foreground: oklch(0.985 0 0);
|
|
52
133
|
--muted: oklch(0.269 0 0);
|
|
@@ -54,18 +135,21 @@
|
|
|
54
135
|
--accent: oklch(0.371 0 0);
|
|
55
136
|
--accent-foreground: oklch(0.985 0 0);
|
|
56
137
|
--destructive: oklch(0.704 0.191 22.216);
|
|
138
|
+
--success: oklch(0.7 0.16 145);
|
|
139
|
+
--warning: oklch(0.8 0.15 85);
|
|
140
|
+
--info: oklch(0.7 0.15 250);
|
|
57
141
|
--border: oklch(1 0 0 / 10%);
|
|
58
142
|
--input: oklch(1 0 0 / 15%);
|
|
59
143
|
--ring: oklch(0.556 0 0);
|
|
60
|
-
--chart-1: oklch(0.
|
|
61
|
-
--chart-2: oklch(0.
|
|
62
|
-
--chart-3: oklch(0.
|
|
63
|
-
--chart-4: oklch(0.
|
|
64
|
-
--chart-5: oklch(0.
|
|
144
|
+
--chart-1: oklch(0.845 0.143 164.978);
|
|
145
|
+
--chart-2: oklch(0.765 0.177 163.223);
|
|
146
|
+
--chart-3: oklch(0.696 0.17 162.48);
|
|
147
|
+
--chart-4: oklch(0.596 0.145 163.225);
|
|
148
|
+
--chart-5: oklch(0.508 0.118 165.612);
|
|
65
149
|
--sidebar: oklch(0.205 0 0);
|
|
66
150
|
--sidebar-foreground: oklch(0.985 0 0);
|
|
67
|
-
--sidebar-primary: oklch(0.
|
|
68
|
-
--sidebar-primary-foreground: oklch(0.
|
|
151
|
+
--sidebar-primary: oklch(0.696 0.17 162.48);
|
|
152
|
+
--sidebar-primary-foreground: oklch(0.262 0.051 172.552);
|
|
69
153
|
--sidebar-accent: oklch(0.269 0 0);
|
|
70
154
|
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
71
155
|
--sidebar-border: oklch(1 0 0 / 10%);
|
|
@@ -74,6 +158,7 @@
|
|
|
74
158
|
}
|
|
75
159
|
|
|
76
160
|
@theme inline {
|
|
161
|
+
--font-sans: 'Lausanne', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
|
77
162
|
--color-background: var(--background);
|
|
78
163
|
--color-foreground: var(--foreground);
|
|
79
164
|
--color-card: var(--card);
|
|
@@ -90,6 +175,9 @@
|
|
|
90
175
|
--color-accent-foreground: var(--accent-foreground);
|
|
91
176
|
--color-destructive: var(--destructive);
|
|
92
177
|
--color-destructive-foreground: var(--destructive-foreground);
|
|
178
|
+
--color-success: var(--success);
|
|
179
|
+
--color-warning: var(--warning);
|
|
180
|
+
--color-info: var(--info);
|
|
93
181
|
--color-border: var(--border);
|
|
94
182
|
--color-input: var(--input);
|
|
95
183
|
--color-ring: var(--ring);
|
|
@@ -116,7 +204,63 @@
|
|
|
116
204
|
* {
|
|
117
205
|
@apply border-border outline-ring/50;
|
|
118
206
|
}
|
|
207
|
+
html {
|
|
208
|
+
font-family: var(--font-sans);
|
|
209
|
+
}
|
|
119
210
|
body {
|
|
120
211
|
@apply bg-background text-foreground;
|
|
212
|
+
font-family: var(--font-sans);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* Lausanne-only weight mapping.
|
|
217
|
+
We DO NOT have 500/600 files, so make Tailwind's common semantic weights resolve to real faces. */
|
|
218
|
+
@layer utilities {
|
|
219
|
+
.font-normal {
|
|
220
|
+
font-weight: 350;
|
|
221
|
+
}
|
|
222
|
+
.font-medium {
|
|
223
|
+
font-weight: 400;
|
|
224
|
+
}
|
|
225
|
+
.font-semibold {
|
|
226
|
+
font-weight: 700;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/* View Transitions API for smooth page transitions */
|
|
231
|
+
@view-transition {
|
|
232
|
+
navigation: auto;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
::view-transition-old(page-content) {
|
|
236
|
+
animation: fade-out 250ms ease-out forwards;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
::view-transition-new(page-content) {
|
|
240
|
+
animation: fade-in 250ms ease-out forwards;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
@keyframes fade-out {
|
|
244
|
+
from { opacity: 1; }
|
|
245
|
+
to { opacity: 0; }
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
@keyframes fade-in {
|
|
249
|
+
from { opacity: 0; }
|
|
250
|
+
to { opacity: 1; }
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* Page content animation fallback for non-View Transitions browsers */
|
|
254
|
+
[data-slot="page-layout"] {
|
|
255
|
+
view-transition-name: page-content;
|
|
256
|
+
animation: page-enter 250ms ease-out;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
@keyframes page-enter {
|
|
260
|
+
from {
|
|
261
|
+
opacity: 0;
|
|
262
|
+
}
|
|
263
|
+
to {
|
|
264
|
+
opacity: 1;
|
|
121
265
|
}
|
|
122
266
|
}
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import { AlertDialog as AlertDialogPrimitive } from '@base-ui/react/alert-dialog';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
|
|
4
|
-
import { cn } from '../../../lib/utils';
|
|
5
|
-
import { Button } from './button';
|
|
6
|
-
|
|
7
|
-
function AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {
|
|
8
|
-
return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) {
|
|
12
|
-
return <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) {
|
|
16
|
-
return <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function AlertDialogOverlay({ className, ...props }: AlertDialogPrimitive.Backdrop.Props) {
|
|
20
|
-
return (
|
|
21
|
-
<AlertDialogPrimitive.Backdrop
|
|
22
|
-
data-slot="alert-dialog-overlay"
|
|
23
|
-
className={cn(
|
|
24
|
-
'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 isolate z-50',
|
|
25
|
-
className,
|
|
26
|
-
)}
|
|
27
|
-
{...props}
|
|
28
|
-
/>
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function AlertDialogContent({
|
|
33
|
-
className,
|
|
34
|
-
size = 'default',
|
|
35
|
-
...props
|
|
36
|
-
}: AlertDialogPrimitive.Popup.Props & {
|
|
37
|
-
size?: 'default' | 'sm';
|
|
38
|
-
}) {
|
|
39
|
-
return (
|
|
40
|
-
<AlertDialogPortal>
|
|
41
|
-
<AlertDialogOverlay />
|
|
42
|
-
<AlertDialogPrimitive.Popup
|
|
43
|
-
data-slot="alert-dialog-content"
|
|
44
|
-
data-size={size}
|
|
45
|
-
className={cn(
|
|
46
|
-
'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 bg-background ring-foreground/10 gap-4 rounded-xl p-4 ring-1 duration-100 data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 outline-none',
|
|
47
|
-
className,
|
|
48
|
-
)}
|
|
49
|
-
{...props}
|
|
50
|
-
/>
|
|
51
|
-
</AlertDialogPortal>
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function AlertDialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
56
|
-
return (
|
|
57
|
-
<div
|
|
58
|
-
data-slot="alert-dialog-header"
|
|
59
|
-
className={cn(
|
|
60
|
-
'grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]',
|
|
61
|
-
className,
|
|
62
|
-
)}
|
|
63
|
-
{...props}
|
|
64
|
-
/>
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function AlertDialogFooter({ className, ...props }: React.ComponentProps<'div'>) {
|
|
69
|
-
return (
|
|
70
|
-
<div
|
|
71
|
-
data-slot="alert-dialog-footer"
|
|
72
|
-
className={cn(
|
|
73
|
-
'bg-muted/50 -mx-4 -mb-4 rounded-b-xl border-t p-4 flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end',
|
|
74
|
-
className,
|
|
75
|
-
)}
|
|
76
|
-
{...props}
|
|
77
|
-
/>
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function AlertDialogMedia({ className, ...props }: React.ComponentProps<'div'>) {
|
|
82
|
-
return (
|
|
83
|
-
<div
|
|
84
|
-
data-slot="alert-dialog-media"
|
|
85
|
-
className={cn(
|
|
86
|
-
"bg-muted mb-2 inline-flex size-10 items-center justify-center rounded-md sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-6",
|
|
87
|
-
className,
|
|
88
|
-
)}
|
|
89
|
-
{...props}
|
|
90
|
-
/>
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function AlertDialogTitle({
|
|
95
|
-
className,
|
|
96
|
-
...props
|
|
97
|
-
}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
|
|
98
|
-
return (
|
|
99
|
-
<AlertDialogPrimitive.Title
|
|
100
|
-
data-slot="alert-dialog-title"
|
|
101
|
-
className={cn(
|
|
102
|
-
'text-sm font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2',
|
|
103
|
-
className,
|
|
104
|
-
)}
|
|
105
|
-
{...props}
|
|
106
|
-
/>
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function AlertDialogDescription({
|
|
111
|
-
className,
|
|
112
|
-
...props
|
|
113
|
-
}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
|
|
114
|
-
return (
|
|
115
|
-
<AlertDialogPrimitive.Description
|
|
116
|
-
data-slot="alert-dialog-description"
|
|
117
|
-
className={cn(
|
|
118
|
-
'text-muted-foreground *:[a]:hover:text-foreground text-sm text-balance md:text-pretty *:[a]:underline *:[a]:underline-offset-3',
|
|
119
|
-
className,
|
|
120
|
-
)}
|
|
121
|
-
{...props}
|
|
122
|
-
/>
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function AlertDialogAction({
|
|
127
|
-
variant = 'default',
|
|
128
|
-
...props
|
|
129
|
-
}: Omit<React.ComponentProps<typeof Button>, 'className'>) {
|
|
130
|
-
return <Button data-slot="alert-dialog-action" variant={variant} {...props} />;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function AlertDialogCancel({
|
|
134
|
-
variant = 'secondary',
|
|
135
|
-
size = 'default',
|
|
136
|
-
...props
|
|
137
|
-
}: Omit<AlertDialogPrimitive.Close.Props, 'className'> &
|
|
138
|
-
Pick<React.ComponentProps<typeof Button>, 'variant' | 'size'>) {
|
|
139
|
-
return (
|
|
140
|
-
<AlertDialogPrimitive.Close
|
|
141
|
-
data-slot="alert-dialog-cancel"
|
|
142
|
-
render={<Button variant={variant} size={size} />}
|
|
143
|
-
{...props}
|
|
144
|
-
/>
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export {
|
|
149
|
-
AlertDialog,
|
|
150
|
-
AlertDialogAction,
|
|
151
|
-
AlertDialogCancel,
|
|
152
|
-
AlertDialogContent,
|
|
153
|
-
AlertDialogDescription,
|
|
154
|
-
AlertDialogFooter,
|
|
155
|
-
AlertDialogHeader,
|
|
156
|
-
AlertDialogMedia,
|
|
157
|
-
AlertDialogOverlay,
|
|
158
|
-
AlertDialogPortal,
|
|
159
|
-
AlertDialogTitle,
|
|
160
|
-
AlertDialogTrigger,
|
|
161
|
-
};
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { mergeProps } from '@base-ui/react/merge-props';
|
|
2
|
-
import { useRender } from '@base-ui/react/use-render';
|
|
3
|
-
import { cva, type VariantProps } from 'class-variance-authority';
|
|
4
|
-
|
|
5
|
-
const badgeVariants = cva(
|
|
6
|
-
'h-5 gap-1 rounded-4xl border px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! inline-flex items-center justify-center w-fit whitespace-nowrap shrink-0 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-colors overflow-hidden group/badge',
|
|
7
|
-
{
|
|
8
|
-
variants: {
|
|
9
|
-
variant: {
|
|
10
|
-
default: 'border-transparent bg-primary text-primary-foreground [a]:hover:bg-primary/80',
|
|
11
|
-
secondary:
|
|
12
|
-
'border-transparent bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80',
|
|
13
|
-
destructive:
|
|
14
|
-
'border-transparent bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20',
|
|
15
|
-
outline:
|
|
16
|
-
'border-border bg-transparent text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground',
|
|
17
|
-
ghost:
|
|
18
|
-
'border-transparent bg-transparent hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50',
|
|
19
|
-
link: 'border-transparent bg-transparent text-primary underline-offset-4 hover:underline',
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
defaultVariants: {
|
|
23
|
-
variant: 'default',
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
type BadgeProps = Omit<useRender.ComponentProps<'span'>, 'className'> &
|
|
29
|
-
VariantProps<typeof badgeVariants>;
|
|
30
|
-
|
|
31
|
-
function Badge({ variant = 'default', render, ...props }: BadgeProps) {
|
|
32
|
-
return useRender({
|
|
33
|
-
defaultTagName: 'span',
|
|
34
|
-
props: mergeProps<'span'>(
|
|
35
|
-
{
|
|
36
|
-
className: badgeVariants({ variant }),
|
|
37
|
-
},
|
|
38
|
-
props,
|
|
39
|
-
),
|
|
40
|
-
render,
|
|
41
|
-
state: {
|
|
42
|
-
slot: 'badge',
|
|
43
|
-
variant,
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export { Badge, badgeVariants };
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { cva, type VariantProps } from 'class-variance-authority';
|
|
2
|
-
|
|
3
|
-
import { cn } from '../../../lib/utils';
|
|
4
|
-
|
|
5
|
-
function Empty({ className, ...props }: React.ComponentProps<'div'>) {
|
|
6
|
-
return (
|
|
7
|
-
<div
|
|
8
|
-
data-slot="empty"
|
|
9
|
-
className={cn(
|
|
10
|
-
'gap-4 rounded-lg border-dashed p-12 flex w-full min-w-0 flex-1 flex-col items-center justify-center text-center text-balance',
|
|
11
|
-
className,
|
|
12
|
-
)}
|
|
13
|
-
{...props}
|
|
14
|
-
/>
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function EmptyHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
19
|
-
return (
|
|
20
|
-
<div
|
|
21
|
-
data-slot="empty-header"
|
|
22
|
-
className={cn('gap-2 flex max-w-sm flex-col items-center', className)}
|
|
23
|
-
{...props}
|
|
24
|
-
/>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const emptyMediaVariants = cva(
|
|
29
|
-
'mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0',
|
|
30
|
-
{
|
|
31
|
-
variants: {
|
|
32
|
-
variant: {
|
|
33
|
-
default: 'bg-transparent',
|
|
34
|
-
icon: "bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6",
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
defaultVariants: {
|
|
38
|
-
variant: 'default',
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
function EmptyMedia({
|
|
44
|
-
className,
|
|
45
|
-
variant = 'default',
|
|
46
|
-
...props
|
|
47
|
-
}: React.ComponentProps<'div'> & VariantProps<typeof emptyMediaVariants>) {
|
|
48
|
-
return (
|
|
49
|
-
<div
|
|
50
|
-
data-slot="empty-icon"
|
|
51
|
-
data-variant={variant}
|
|
52
|
-
className={cn(emptyMediaVariants({ variant, className }))}
|
|
53
|
-
{...props}
|
|
54
|
-
/>
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function EmptyTitle({ className, ...props }: React.ComponentProps<'div'>) {
|
|
59
|
-
return (
|
|
60
|
-
<div
|
|
61
|
-
data-slot="empty-title"
|
|
62
|
-
className={cn('text-lg font-medium tracking-tight', className)}
|
|
63
|
-
{...props}
|
|
64
|
-
/>
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function EmptyDescription({ className, ...props }: React.ComponentProps<'p'>) {
|
|
69
|
-
return (
|
|
70
|
-
<div
|
|
71
|
-
data-slot="empty-description"
|
|
72
|
-
className={cn(
|
|
73
|
-
'text-sm/relaxed text-muted-foreground [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',
|
|
74
|
-
className,
|
|
75
|
-
)}
|
|
76
|
-
{...props}
|
|
77
|
-
/>
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function EmptyContent({ className, ...props }: React.ComponentProps<'div'>) {
|
|
82
|
-
return (
|
|
83
|
-
<div
|
|
84
|
-
data-slot="empty-content"
|
|
85
|
-
className={cn(
|
|
86
|
-
'gap-4 text-sm flex w-full max-w-sm min-w-0 flex-col items-center text-balance',
|
|
87
|
-
className,
|
|
88
|
-
)}
|
|
89
|
-
{...props}
|
|
90
|
-
/>
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle };
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { OTPInput, OTPInputContext } from 'input-otp';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
|
|
4
|
-
import { MinusIcon } from 'lucide-react';
|
|
5
|
-
import { cn } from '../../../lib/utils';
|
|
6
|
-
|
|
7
|
-
function InputOTP({
|
|
8
|
-
className,
|
|
9
|
-
containerClassName,
|
|
10
|
-
...props
|
|
11
|
-
}: React.ComponentProps<typeof OTPInput> & {
|
|
12
|
-
containerClassName?: string;
|
|
13
|
-
}) {
|
|
14
|
-
return (
|
|
15
|
-
<OTPInput
|
|
16
|
-
data-slot="input-otp"
|
|
17
|
-
containerClassName={cn(
|
|
18
|
-
'cn-input-otp flex items-center has-disabled:opacity-50',
|
|
19
|
-
containerClassName,
|
|
20
|
-
)}
|
|
21
|
-
spellCheck={false}
|
|
22
|
-
className={cn('disabled:cursor-not-allowed', className)}
|
|
23
|
-
{...props}
|
|
24
|
-
/>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function InputOTPGroup({ className, ...props }: React.ComponentProps<'div'>) {
|
|
29
|
-
return (
|
|
30
|
-
<div
|
|
31
|
-
data-slot="input-otp-group"
|
|
32
|
-
className={cn(
|
|
33
|
-
'has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive rounded-md has-aria-invalid:ring-[3px] flex items-center',
|
|
34
|
-
className,
|
|
35
|
-
)}
|
|
36
|
-
{...props}
|
|
37
|
-
/>
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function InputOTPSlot({
|
|
42
|
-
index,
|
|
43
|
-
className,
|
|
44
|
-
...props
|
|
45
|
-
}: React.ComponentProps<'div'> & {
|
|
46
|
-
index: number;
|
|
47
|
-
}) {
|
|
48
|
-
const inputOTPContext = React.useContext(OTPInputContext);
|
|
49
|
-
const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {};
|
|
50
|
-
|
|
51
|
-
return (
|
|
52
|
-
<div
|
|
53
|
-
data-slot="input-otp-slot"
|
|
54
|
-
data-active={isActive}
|
|
55
|
-
className={cn(
|
|
56
|
-
'dark:bg-input/30 border-input data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive size-9 border-y border-r text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:ring-[3px] relative flex items-center justify-center data-[active=true]:z-10',
|
|
57
|
-
className,
|
|
58
|
-
)}
|
|
59
|
-
{...props}
|
|
60
|
-
>
|
|
61
|
-
{char}
|
|
62
|
-
{hasFakeCaret && (
|
|
63
|
-
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
|
|
64
|
-
<div className="animate-caret-blink bg-foreground h-4 w-px duration-1000 bg-foreground h-4 w-px" />
|
|
65
|
-
</div>
|
|
66
|
-
)}
|
|
67
|
-
</div>
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function InputOTPSeparator({ ...props }: React.ComponentProps<'div'>) {
|
|
72
|
-
return (
|
|
73
|
-
<div
|
|
74
|
-
data-slot="input-otp-separator"
|
|
75
|
-
className="[&_svg:not([class*='size-'])]:size-4 flex items-center"
|
|
76
|
-
role="separator"
|
|
77
|
-
{...props}
|
|
78
|
-
>
|
|
79
|
-
<MinusIcon />
|
|
80
|
-
</div>
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot };
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { cn } from '../../../lib/utils';
|
|
2
|
-
|
|
3
|
-
function Kbd({ className, ...props }: React.ComponentProps<'kbd'>) {
|
|
4
|
-
return (
|
|
5
|
-
<kbd
|
|
6
|
-
data-slot="kbd"
|
|
7
|
-
className={cn(
|
|
8
|
-
"bg-muted text-muted-foreground [[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10 h-5 w-fit min-w-5 gap-1 rounded-sm px-1 font-sans text-xs font-medium [&_svg:not([class*='size-'])]:size-3 pointer-events-none inline-flex items-center justify-center select-none",
|
|
9
|
-
className,
|
|
10
|
-
)}
|
|
11
|
-
{...props}
|
|
12
|
-
/>
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function KbdGroup({ className, ...props }: React.ComponentProps<'div'>) {
|
|
17
|
-
return (
|
|
18
|
-
<kbd
|
|
19
|
-
data-slot="kbd-group"
|
|
20
|
-
className={cn('gap-1 inline-flex items-center', className)}
|
|
21
|
-
{...props}
|
|
22
|
-
/>
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export { Kbd, KbdGroup };
|