@ponti-studios/ui 0.1.2 → 0.4.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/LICENSE +21 -0
- package/README.md +7 -7
- package/THIRD_PARTY_NOTICES.md +17 -0
- package/dist/index.js +988 -640
- package/dist/index.js.map +1 -1
- package/package.json +41 -41
- package/src/animations.css +42 -383
- package/src/components/data-display/accordion.tsx +22 -10
- package/src/components/data-display/filter-chip.stories.tsx +38 -0
- package/src/components/data-display/filter-chip.tsx +10 -4
- package/src/components/data-display/index.ts +5 -0
- package/src/components/data-display/metric-card.stories.tsx +48 -0
- package/src/components/data-display/metric-card.tsx +20 -0
- package/src/components/data-display/sort-controls.stories.tsx +45 -0
- package/src/components/data-display/sort-controls.tsx +99 -0
- package/src/components/data-display/sort-row.tsx +74 -0
- package/src/components/data-display/table.tsx +5 -9
- package/src/components/feedback/alert.tsx +4 -4
- package/src/components/feedback/empty-state.tsx +16 -6
- package/src/components/feedback/file-upload-status-badge.stories.tsx +28 -0
- package/src/components/feedback/file-upload-status-badge.tsx +33 -0
- package/src/components/feedback/file-upload-status.stories.tsx +57 -0
- package/src/components/feedback/file-upload-status.tsx +152 -0
- package/src/components/feedback/index.ts +9 -0
- package/src/components/feedback/progress-bar.stories.tsx +39 -0
- package/src/components/feedback/progress-bar.tsx +21 -0
- package/src/components/feedback/progress.stories.tsx +8 -6
- package/src/components/feedback/progress.tsx +3 -3
- package/src/components/feedback/skeleton.stories.tsx +36 -0
- package/src/components/feedback/skeleton.tsx +7 -0
- package/src/components/feedback/spinner.tsx +2 -2
- package/src/components/feedback/update-guard.stories.tsx +32 -0
- package/src/components/feedback/update-guard.tsx +280 -0
- package/src/components/forms/calendar.tsx +14 -11
- package/src/components/forms/date-month-select.stories.tsx +26 -0
- package/src/components/forms/date-month-select.tsx +70 -0
- package/src/components/forms/date-picker.tsx +3 -3
- package/src/components/forms/drop-zone.stories.tsx +56 -0
- package/src/components/forms/drop-zone.tsx +146 -0
- package/src/components/forms/entity-select.stories.tsx +65 -0
- package/src/components/forms/entity-select.tsx +79 -0
- package/src/components/forms/field.tsx +3 -3
- package/src/components/forms/group-by-select.stories.tsx +26 -0
- package/src/components/forms/group-by-select.tsx +47 -0
- package/src/components/forms/index.ts +10 -0
- package/src/components/forms/input.stories.tsx +4 -4
- package/src/components/forms/input.tsx +1 -1
- package/src/components/forms/passkey-management.stories.tsx +81 -0
- package/src/components/forms/passkey-management.tsx +138 -0
- package/src/components/forms/radio-group.tsx +14 -13
- package/src/components/forms/select.stories.tsx +4 -4
- package/src/components/forms/select.tsx +47 -48
- package/src/components/forms/slider.stories.tsx +5 -2
- package/src/components/forms/slider.tsx +39 -17
- package/src/components/forms/stepper.tsx +4 -4
- package/src/components/forms/switch.stories.tsx +1 -1
- package/src/components/forms/switch.tsx +2 -2
- package/src/components/forms/textarea.stories.tsx +2 -2
- package/src/components/forms/textarea.tsx +1 -1
- package/src/components/layout/index.ts +3 -0
- package/src/components/layout/scroll-area.stories.tsx +4 -4
- package/src/components/layout/scroll-area.tsx +23 -21
- package/src/components/layout/section-intro.stories.tsx +29 -0
- package/src/components/layout/section-intro.tsx +31 -0
- package/src/components/layout/surface-panel.stories.tsx +32 -0
- package/src/components/layout/surface-panel.tsx +15 -0
- package/src/components/navigation/app-navigation.stories.tsx +2 -2
- package/src/components/navigation/app-navigation.tsx +13 -13
- package/src/components/navigation/index.ts +4 -0
- package/src/components/navigation/pagination-controls.stories.tsx +41 -0
- package/src/components/navigation/pagination-controls.tsx +50 -0
- package/src/components/navigation/route-link.stories.tsx +30 -0
- package/src/components/navigation/route-link.tsx +42 -0
- package/src/components/navigation/tabs.stories.tsx +5 -5
- package/src/components/navigation/tabs.tsx +8 -8
- package/src/components/overlays/alert-dialog.tsx +22 -25
- package/src/components/overlays/command.tsx +98 -26
- package/src/components/overlays/dialog.tsx +5 -5
- package/src/components/overlays/dropdown-menu.stories.tsx +0 -5
- package/src/components/overlays/dropdown-menu.tsx +49 -31
- package/src/components/overlays/popover.stories.tsx +2 -2
- package/src/components/overlays/popover.tsx +43 -14
- package/src/components/overlays/sheet.stories.tsx +2 -2
- package/src/components/overlays/sheet.tsx +51 -17
- package/src/components/primitives/avatar.tsx +9 -5
- package/src/components/primitives/badge.tsx +11 -12
- package/src/components/primitives/button.tsx +49 -23
- package/src/components/primitives/card.stories.tsx +2 -2
- package/src/components/primitives/card.tsx +2 -5
- package/src/components/primitives/index.ts +2 -0
- package/src/components/primitives/label.stories.tsx +1 -1
- package/src/components/primitives/label.tsx +5 -6
- package/src/components/primitives/status-badge.stories.tsx +52 -0
- package/src/components/primitives/status-badge.tsx +33 -0
- package/src/constants/chart-colors.ts +7 -7
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-sort.ts +20 -0
- package/src/index.ts +30 -11
- package/src/styles.css +100 -974
- package/src/tokens/chart-colors.stories.tsx +192 -0
- package/src/tokens/color-systems.stories.tsx +20 -112
- package/src/tokens/foundations.stories.tsx +58 -100
- package/src/tokens/generated/dark.colors.generated.ts +29 -0
- package/src/tokens/generated/dark.css +29 -0
- package/src/tokens/generated/foundations.css +148 -0
- package/src/tokens/generated/foundations.generated.ts +451 -0
- package/src/tokens/generated/light.colors.generated.ts +29 -0
- package/src/tokens/generated/light.css +29 -0
- package/src/tokens/index.ts +79 -16
- package/src/tokens/layout.stories.tsx +23 -91
- package/src/tokens/colors.ts +0 -156
- package/src/tokens/motion.ts +0 -51
- package/src/tokens/radii.ts +0 -10
- package/src/tokens/shadows.ts +0 -34
- package/src/tokens/spacing.ts +0 -30
- package/src/tokens/typography.ts +0 -42
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ponti-studios/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Shared UI component library for ponti-studios labs",
|
|
6
|
-
"license": "
|
|
6
|
+
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://github.com/ponti-studios/labs.git",
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
17
|
"dist",
|
|
18
|
-
"src"
|
|
18
|
+
"src",
|
|
19
|
+
"THIRD_PARTY_NOTICES.md"
|
|
19
20
|
],
|
|
20
21
|
"type": "module",
|
|
21
22
|
"sideEffects": [
|
|
@@ -70,61 +71,60 @@
|
|
|
70
71
|
"./styles.css": "./src/styles.css",
|
|
71
72
|
"./animations.css": "./src/animations.css"
|
|
72
73
|
},
|
|
74
|
+
"scripts": {
|
|
75
|
+
"build": "vite build",
|
|
76
|
+
"dev": "vite",
|
|
77
|
+
"storybook": "style-dictionary build --config style-dictionary.dark-storybook.json && storybook dev -p 6006",
|
|
78
|
+
"check:source": "node tokens/check-source.mjs",
|
|
79
|
+
"test:a11y": "vitest --run --config vitest.config.ts",
|
|
80
|
+
"tokens:build": "style-dictionary build --config style-dictionary.foundations.json && style-dictionary build --config style-dictionary.light.json && style-dictionary build --config style-dictionary.dark.json && style-dictionary build --config style-dictionary.dark-storybook.json",
|
|
81
|
+
"tokens:check": "pnpm run tokens:build && node tokens/check-foundations.mjs && git diff --exit-code -- src/tokens/generated",
|
|
82
|
+
"typecheck": "tsc --noEmit",
|
|
83
|
+
"lint": "oxlint src --fix",
|
|
84
|
+
"format": "oxfmt src --write",
|
|
85
|
+
"prepack": "pnpm run tokens:check && pnpm run check:source && pnpm run typecheck && pnpm run build"
|
|
86
|
+
},
|
|
73
87
|
"dependencies": {
|
|
74
88
|
"@base-ui/react": "^1.6.0",
|
|
75
|
-
"@radix-ui/
|
|
76
|
-
"@radix-ui/react-alert-dialog": "^1.1.17",
|
|
77
|
-
"@radix-ui/react-avatar": "^1.2.2",
|
|
78
|
-
"@radix-ui/react-dialog": "^1.1.17",
|
|
79
|
-
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
80
|
-
"@radix-ui/react-label": "^2.1.10",
|
|
81
|
-
"@radix-ui/react-popover": "^1.1.19",
|
|
82
|
-
"@radix-ui/react-progress": "^1.1.10",
|
|
83
|
-
"@radix-ui/react-radio-group": "^1.4.1",
|
|
84
|
-
"@radix-ui/react-select": "^2.3.1",
|
|
85
|
-
"@radix-ui/react-slider": "^1.4.1",
|
|
86
|
-
"@radix-ui/react-slot": "^1.3.0",
|
|
87
|
-
"@radix-ui/react-switch": "^1.2.6",
|
|
88
|
-
"@radix-ui/react-tabs": "^1.1.15",
|
|
89
|
+
"@radix-ui/colors": "^3.0.0",
|
|
89
90
|
"class-variance-authority": "^0.7.1",
|
|
90
91
|
"clsx": "^2.1.1",
|
|
91
|
-
"cmdk": "^1.1.1",
|
|
92
92
|
"date-fns": "^4.1.0",
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"react-day-picker": "^9.11.1",
|
|
93
|
+
"lucide-react": "^1.24.0",
|
|
94
|
+
"react-day-picker": "^10.0.1",
|
|
96
95
|
"tailwind-merge": "^3.6.0"
|
|
97
96
|
},
|
|
98
97
|
"devDependencies": {
|
|
99
98
|
"@chromatic-com/storybook": "^5.2.1",
|
|
100
|
-
"@storybook/addon-
|
|
101
|
-
"@storybook/addon-
|
|
102
|
-
"@storybook/addon-
|
|
103
|
-
"@storybook/
|
|
104
|
-
"@
|
|
105
|
-
"@
|
|
99
|
+
"@storybook/addon-a11y": "10.5.3",
|
|
100
|
+
"@storybook/addon-docs": "^10.5.3",
|
|
101
|
+
"@storybook/addon-links": "^10.5.3",
|
|
102
|
+
"@storybook/addon-onboarding": "^10.5.3",
|
|
103
|
+
"@storybook/addon-themes": "10.5.3",
|
|
104
|
+
"@storybook/addon-vitest": "10.5.3",
|
|
105
|
+
"@storybook/react-vite": "^10.5.3",
|
|
106
|
+
"@tailwindcss/vite": "catalog:",
|
|
107
|
+
"@types/node": "catalog:",
|
|
106
108
|
"@types/react": "^19.2.17",
|
|
107
109
|
"@types/react-dom": "^19.2.3",
|
|
108
110
|
"@vitejs/plugin-react": "^6.0.3",
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
+
"@vitest/browser": "4.1.10",
|
|
112
|
+
"@vitest/browser-playwright": "4.1.10",
|
|
113
|
+
"oxfmt": "catalog:shared",
|
|
114
|
+
"oxlint": "catalog:shared",
|
|
115
|
+
"playwright": "catalog:",
|
|
111
116
|
"react": "^19.2.7",
|
|
112
117
|
"react-dom": "^19.2.7",
|
|
113
|
-
"storybook": "^10.
|
|
114
|
-
"
|
|
118
|
+
"storybook": "^10.5.3",
|
|
119
|
+
"style-dictionary": "5.5.0",
|
|
120
|
+
"tailwindcss": "catalog:",
|
|
115
121
|
"typescript": "6.0.3",
|
|
116
|
-
"vite": "
|
|
122
|
+
"vite": "catalog:",
|
|
123
|
+
"vitest": "catalog:"
|
|
117
124
|
},
|
|
118
125
|
"peerDependencies": {
|
|
119
126
|
"react": "^18.2.0 || ^19.0.0",
|
|
120
127
|
"react-dom": "^18.2.0 || ^19.0.0"
|
|
121
128
|
},
|
|
122
|
-
"
|
|
123
|
-
|
|
124
|
-
"dev": "vite",
|
|
125
|
-
"storybook": "storybook dev -p 6006",
|
|
126
|
-
"typecheck": "tsc --noEmit",
|
|
127
|
-
"lint": "oxlint src --fix",
|
|
128
|
-
"format": "oxfmt src --write"
|
|
129
|
-
}
|
|
130
|
-
}
|
|
129
|
+
"packageManager": "pnpm@10.30.3"
|
|
130
|
+
}
|
package/src/animations.css
CHANGED
|
@@ -1,437 +1,96 @@
|
|
|
1
|
-
@
|
|
2
|
-
.motion-anim-enter,
|
|
3
|
-
.motion-anim-exit,
|
|
4
|
-
.motion-anim-enter-top,
|
|
5
|
-
.motion-anim-enter-bottom,
|
|
6
|
-
.motion-anim-enter-left,
|
|
7
|
-
.motion-anim-enter-right,
|
|
8
|
-
.motion-anim-breezy,
|
|
9
|
-
.motion-anim-breezy-loop,
|
|
10
|
-
.motion-anim-breezy-progress,
|
|
11
|
-
.motion-anim-breezy-stagger > * {
|
|
12
|
-
animation: none !important;
|
|
13
|
-
opacity: 1 !important;
|
|
14
|
-
transform: none !important;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
@keyframes motion-enter {
|
|
19
|
-
from {
|
|
20
|
-
opacity: 0;
|
|
21
|
-
transform: translateY(6px);
|
|
22
|
-
}
|
|
23
|
-
to {
|
|
24
|
-
opacity: 1;
|
|
25
|
-
transform: translateY(0);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@keyframes motion-exit {
|
|
30
|
-
from {
|
|
31
|
-
opacity: 1;
|
|
32
|
-
transform: translateY(0);
|
|
33
|
-
}
|
|
34
|
-
to {
|
|
35
|
-
opacity: 0;
|
|
36
|
-
transform: translateY(4px);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
@keyframes motion-enter-top {
|
|
41
|
-
from {
|
|
42
|
-
opacity: 0;
|
|
43
|
-
transform: translateY(-6px);
|
|
44
|
-
}
|
|
45
|
-
to {
|
|
46
|
-
opacity: 1;
|
|
47
|
-
transform: translateY(0);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
@keyframes motion-exit-top {
|
|
52
|
-
from {
|
|
53
|
-
opacity: 1;
|
|
54
|
-
transform: translateY(0);
|
|
55
|
-
}
|
|
56
|
-
to {
|
|
57
|
-
opacity: 0;
|
|
58
|
-
transform: translateY(-4px);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
@keyframes motion-enter-bottom {
|
|
63
|
-
from {
|
|
64
|
-
opacity: 0;
|
|
65
|
-
transform: translateY(6px);
|
|
66
|
-
}
|
|
67
|
-
to {
|
|
68
|
-
opacity: 1;
|
|
69
|
-
transform: translateY(0);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
@keyframes motion-exit-bottom {
|
|
74
|
-
from {
|
|
75
|
-
opacity: 1;
|
|
76
|
-
transform: translateY(0);
|
|
77
|
-
}
|
|
78
|
-
to {
|
|
79
|
-
opacity: 0;
|
|
80
|
-
transform: translateY(6px);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
@keyframes motion-enter-left {
|
|
1
|
+
@keyframes accordion-down {
|
|
85
2
|
from {
|
|
86
|
-
|
|
87
|
-
transform: translateX(-6px);
|
|
3
|
+
height: 0;
|
|
88
4
|
}
|
|
89
5
|
to {
|
|
90
|
-
|
|
91
|
-
transform: translateX(0);
|
|
6
|
+
height: var(--accordion-content-height);
|
|
92
7
|
}
|
|
93
8
|
}
|
|
94
|
-
|
|
95
|
-
@keyframes motion-exit-left {
|
|
9
|
+
@keyframes accordion-up {
|
|
96
10
|
from {
|
|
97
|
-
|
|
98
|
-
transform: translateX(0);
|
|
11
|
+
height: var(--accordion-content-height);
|
|
99
12
|
}
|
|
100
13
|
to {
|
|
101
|
-
|
|
102
|
-
transform: translateX(-4px);
|
|
14
|
+
height: 0;
|
|
103
15
|
}
|
|
104
16
|
}
|
|
105
|
-
|
|
106
|
-
@keyframes motion-enter-right {
|
|
17
|
+
@keyframes fade-in {
|
|
107
18
|
from {
|
|
108
19
|
opacity: 0;
|
|
109
|
-
transform: translateX(6px);
|
|
110
20
|
}
|
|
111
21
|
to {
|
|
112
22
|
opacity: 1;
|
|
113
|
-
transform: translateX(0);
|
|
114
23
|
}
|
|
115
24
|
}
|
|
116
|
-
|
|
117
|
-
@keyframes motion-exit-right {
|
|
25
|
+
@keyframes fade-out {
|
|
118
26
|
from {
|
|
119
27
|
opacity: 1;
|
|
120
|
-
transform: translateX(0);
|
|
121
28
|
}
|
|
122
29
|
to {
|
|
123
30
|
opacity: 0;
|
|
124
|
-
transform: translateX(4px);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/*
|
|
129
|
-
* Sheet/drawer slide — full off-canvas travel (not the 4-6px "nudge" used by
|
|
130
|
-
* the motion-enter/exit-* keyframes above, which are meant for small popovers).
|
|
131
|
-
* Gated on the real [data-state] attribute so open/closed never race — see
|
|
132
|
-
* the note above the data-state fade/zoom rules for why that matters here.
|
|
133
|
-
*/
|
|
134
|
-
@keyframes sheet-slide-in-from-right {
|
|
135
|
-
from {
|
|
136
|
-
transform: translateX(100%);
|
|
137
|
-
}
|
|
138
|
-
to {
|
|
139
|
-
transform: translateX(0);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
@keyframes sheet-slide-out-to-right {
|
|
143
|
-
from {
|
|
144
|
-
transform: translateX(0);
|
|
145
|
-
}
|
|
146
|
-
to {
|
|
147
|
-
transform: translateX(100%);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
@keyframes sheet-slide-in-from-bottom {
|
|
151
|
-
from {
|
|
152
|
-
transform: translateY(100%);
|
|
153
|
-
}
|
|
154
|
-
to {
|
|
155
|
-
transform: translateY(0);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
@keyframes sheet-slide-out-to-bottom {
|
|
159
|
-
from {
|
|
160
|
-
transform: translateY(0);
|
|
161
|
-
}
|
|
162
|
-
to {
|
|
163
|
-
transform: translateY(100%);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
.sheet-responsive[data-state="open"] {
|
|
168
|
-
animation: sheet-slide-in-from-bottom 480ms cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
169
|
-
}
|
|
170
|
-
.sheet-responsive[data-state="closed"] {
|
|
171
|
-
animation: sheet-slide-out-to-bottom 280ms cubic-bezier(0.4, 0, 1, 1) both;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
@media (min-width: 768px) {
|
|
175
|
-
.sheet-responsive[data-state="open"] {
|
|
176
|
-
animation-name: sheet-slide-in-from-right;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
.sheet-responsive[data-state="closed"] {
|
|
180
|
-
animation-name: sheet-slide-out-to-right;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
@media (prefers-reduced-motion: reduce) {
|
|
185
|
-
.sheet-responsive {
|
|
186
|
-
animation: none !important;
|
|
187
|
-
transform: none !important;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
@keyframes motion-breezy-wave {
|
|
192
|
-
0% {
|
|
193
|
-
transform: translateY(0);
|
|
194
|
-
opacity: 0.9;
|
|
195
|
-
}
|
|
196
|
-
40% {
|
|
197
|
-
transform: translateY(-4px);
|
|
198
|
-
opacity: 1;
|
|
199
|
-
}
|
|
200
|
-
70% {
|
|
201
|
-
transform: translateY(2px);
|
|
202
|
-
opacity: 0.92;
|
|
203
|
-
}
|
|
204
|
-
100% {
|
|
205
|
-
transform: translateY(0);
|
|
206
|
-
opacity: 0.9;
|
|
207
31
|
}
|
|
208
32
|
}
|
|
209
|
-
|
|
210
|
-
@keyframes motion-breezy-stream {
|
|
211
|
-
0% {
|
|
212
|
-
transform: translateX(-100%);
|
|
213
|
-
}
|
|
214
|
-
100% {
|
|
215
|
-
transform: translateX(100%);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
.motion-anim-enter {
|
|
220
|
-
animation: motion-enter 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
221
|
-
}
|
|
222
|
-
.motion-anim-exit {
|
|
223
|
-
animation: motion-exit 120ms cubic-bezier(0.4, 0, 1, 1) both;
|
|
224
|
-
}
|
|
225
|
-
.motion-anim-enter-top {
|
|
226
|
-
animation: motion-enter-top 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
227
|
-
}
|
|
228
|
-
.motion-anim-exit-top {
|
|
229
|
-
animation: motion-exit-top 120ms cubic-bezier(0.4, 0, 1, 1) both;
|
|
230
|
-
}
|
|
231
|
-
.motion-anim-enter-bottom {
|
|
232
|
-
animation: motion-enter-bottom 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
233
|
-
}
|
|
234
|
-
.motion-anim-exit-bottom {
|
|
235
|
-
animation: motion-exit-bottom 120ms cubic-bezier(0.4, 0, 1, 1) both;
|
|
236
|
-
}
|
|
237
|
-
.motion-anim-enter-left {
|
|
238
|
-
animation: motion-enter-left 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
239
|
-
}
|
|
240
|
-
.motion-anim-exit-left {
|
|
241
|
-
animation: motion-exit-left 120ms cubic-bezier(0.4, 0, 1, 1) both;
|
|
242
|
-
}
|
|
243
|
-
.motion-anim-enter-right {
|
|
244
|
-
animation: motion-enter-right 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
245
|
-
}
|
|
246
|
-
.motion-anim-exit-right {
|
|
247
|
-
animation: motion-exit-right 120ms cubic-bezier(0.4, 0, 1, 1) both;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
.motion-anim-breezy {
|
|
251
|
-
animation: motion-breezy-wave 320ms cubic-bezier(0.32, 0.72, 0.28, 1) forwards;
|
|
252
|
-
}
|
|
253
|
-
.motion-anim-breezy-loop {
|
|
254
|
-
animation: motion-breezy-wave 1.8s cubic-bezier(0.32, 0.72, 0.28, 1) infinite;
|
|
255
|
-
}
|
|
256
|
-
.motion-anim-breezy-progress {
|
|
257
|
-
animation: motion-breezy-stream 1.8s linear infinite;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
.motion-anim-breezy-stagger > * {
|
|
261
|
-
animation: motion-breezy-wave 1.8s cubic-bezier(0.32, 0.72, 0.28, 1) infinite;
|
|
262
|
-
}
|
|
263
|
-
.motion-anim-breezy-stagger > *:nth-child(1) {
|
|
264
|
-
animation-delay: 0ms;
|
|
265
|
-
}
|
|
266
|
-
.motion-anim-breezy-stagger > *:nth-child(2) {
|
|
267
|
-
animation-delay: 120ms;
|
|
268
|
-
}
|
|
269
|
-
.motion-anim-breezy-stagger > *:nth-child(3) {
|
|
270
|
-
animation-delay: 240ms;
|
|
271
|
-
}
|
|
272
|
-
.motion-anim-breezy-stagger > *:nth-child(4) {
|
|
273
|
-
animation-delay: 360ms;
|
|
274
|
-
}
|
|
275
|
-
.motion-anim-breezy-stagger > *:nth-child(5) {
|
|
276
|
-
animation-delay: 480ms;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
@keyframes accordion-down {
|
|
33
|
+
@keyframes zoom-in {
|
|
280
34
|
from {
|
|
281
35
|
opacity: 0;
|
|
282
|
-
transform:
|
|
283
|
-
transform-origin: top;
|
|
36
|
+
transform: scale(0.95);
|
|
284
37
|
}
|
|
285
38
|
to {
|
|
286
39
|
opacity: 1;
|
|
287
|
-
transform:
|
|
40
|
+
transform: scale(1);
|
|
288
41
|
}
|
|
289
42
|
}
|
|
290
|
-
|
|
291
|
-
@keyframes accordion-up {
|
|
43
|
+
@keyframes zoom-out {
|
|
292
44
|
from {
|
|
293
45
|
opacity: 1;
|
|
294
|
-
transform:
|
|
295
|
-
transform-origin: top;
|
|
46
|
+
transform: scale(1);
|
|
296
47
|
}
|
|
297
48
|
to {
|
|
298
49
|
opacity: 0;
|
|
299
|
-
transform:
|
|
50
|
+
transform: scale(0.95);
|
|
300
51
|
}
|
|
301
52
|
}
|
|
302
53
|
|
|
303
|
-
.animate-accordion-down,
|
|
304
|
-
[data-state="open"].animate-accordion-down {
|
|
305
|
-
animation: accordion-down 400ms cubic-bezier(0.32, 0.72, 0.28, 1) both;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
.animate-accordion-up,
|
|
309
|
-
[data-state="closed"].animate-accordion-up {
|
|
310
|
-
animation: accordion-up 300ms cubic-bezier(0.32, 0.72, 0.28, 1) both;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
54
|
.animate-in {
|
|
314
|
-
animation:
|
|
55
|
+
animation:
|
|
56
|
+
fade-in 150ms ease-out,
|
|
57
|
+
zoom-in 150ms ease-out;
|
|
315
58
|
}
|
|
316
59
|
.animate-out {
|
|
317
|
-
animation:
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
animation: motion-enter 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
321
|
-
}
|
|
322
|
-
.fade-out {
|
|
323
|
-
animation: motion-exit 120ms cubic-bezier(0.4, 0, 1, 1) both;
|
|
60
|
+
animation:
|
|
61
|
+
fade-out 120ms ease-in,
|
|
62
|
+
zoom-out 120ms ease-in;
|
|
324
63
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
* These utility classes exist alongside their opposite (open + closed, or
|
|
328
|
-
* visible + hidden) on the same element at all times — only the `data-state`
|
|
329
|
-
* attribute value actually changes between renders. Each selector below must
|
|
330
|
-
* be qualified with the matching `[data-state="..."]` attribute so only the
|
|
331
|
-
* currently-active variant applies; without it, cascade order alone decides
|
|
332
|
-
* the winner (whichever rule is declared last), regardless of real state.
|
|
333
|
-
*/
|
|
334
|
-
[data-state="open"].data-\[state\=open\]\:animate-in {
|
|
335
|
-
animation: motion-enter 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
64
|
+
.fade-in-0 {
|
|
65
|
+
animation-name: fade-in;
|
|
336
66
|
}
|
|
337
|
-
|
|
338
|
-
animation:
|
|
67
|
+
.fade-out-0 {
|
|
68
|
+
animation-name: fade-out;
|
|
339
69
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
[data-state="open"].data-\[state\=open\]\:fade-in-90,
|
|
343
|
-
[data-state="visible"].data-\[state\=visible\]\:fade-in {
|
|
344
|
-
animation: motion-enter 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
70
|
+
.zoom-in-95 {
|
|
71
|
+
animation-name: zoom-in;
|
|
345
72
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
[data-state="hidden"].data-\[state\=hidden\]\:fade-out {
|
|
349
|
-
animation: motion-exit 120ms cubic-bezier(0.4, 0, 1, 1) both;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
[data-state="open"].data-\[state\=open\]\:zoom-in-90,
|
|
353
|
-
[data-state="open"].data-\[state\=open\]\:zoom-in-95 {
|
|
354
|
-
animation: motion-enter 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
73
|
+
.zoom-out-95 {
|
|
74
|
+
animation-name: zoom-out;
|
|
355
75
|
}
|
|
356
|
-
|
|
357
|
-
|
|
76
|
+
.data-open\:animate-in[data-open],
|
|
77
|
+
.data-open\:animate-in[data-state="open"] {
|
|
78
|
+
animation:
|
|
79
|
+
fade-in 150ms ease-out,
|
|
80
|
+
zoom-in 150ms ease-out;
|
|
358
81
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
* qualified with the matching [data-side="..."] attribute — otherwise
|
|
365
|
-
* cascade order alone picks a winner regardless of actual placement.
|
|
366
|
-
*/
|
|
367
|
-
[data-side="bottom"].data-\[side\=bottom\]\:slide-in-from-top-2 {
|
|
368
|
-
animation: motion-enter-top 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
369
|
-
}
|
|
370
|
-
[data-side="top"].data-\[side\=top\]\:slide-in-from-bottom-2 {
|
|
371
|
-
animation: motion-enter-bottom 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
372
|
-
}
|
|
373
|
-
[data-side="left"].data-\[side\=left\]\:slide-in-from-right-2 {
|
|
374
|
-
animation: motion-enter-right 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
375
|
-
}
|
|
376
|
-
[data-side="right"].data-\[side\=right\]\:slide-in-from-left-2 {
|
|
377
|
-
animation: motion-enter-left 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
.slide-in-from-bottom-10,
|
|
381
|
-
.slide-in-from-bottom-0 {
|
|
382
|
-
animation: motion-enter-bottom 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
383
|
-
}
|
|
384
|
-
.slide-in-from-left-52 {
|
|
385
|
-
animation: motion-enter-left 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
386
|
-
}
|
|
387
|
-
.slide-in-from-right-52 {
|
|
388
|
-
animation: motion-enter-right 150ms cubic-bezier(0, 0, 0.2, 1) both;
|
|
389
|
-
}
|
|
390
|
-
.slide-out-to-left-52 {
|
|
391
|
-
animation: motion-exit-left 120ms cubic-bezier(0.4, 0, 1, 1) both;
|
|
392
|
-
}
|
|
393
|
-
.slide-out-to-right-52 {
|
|
394
|
-
animation: motion-exit-right 120ms cubic-bezier(0.4, 0, 1, 1) both;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
.note-picker-panel {
|
|
398
|
-
transition:
|
|
399
|
-
opacity 150ms cubic-bezier(0, 0, 0.2, 1),
|
|
400
|
-
transform 150ms cubic-bezier(0, 0, 0.2, 1),
|
|
401
|
-
overlay 150ms allow-discrete,
|
|
402
|
-
display 150ms allow-discrete;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
.note-picker-panel[open] {
|
|
406
|
-
opacity: 1;
|
|
407
|
-
transform: translateY(0) scale(1);
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
@starting-style {
|
|
411
|
-
.note-picker-panel[open] {
|
|
412
|
-
opacity: 0;
|
|
413
|
-
transform: translateY(8px) scale(0.98);
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
/*
|
|
418
|
-
* View Transitions: opt-in only.
|
|
419
|
-
* The browser's default root crossfade animates every diffed pixel of the
|
|
420
|
-
* whole page using mix-blend-mode: plus-lighter, which visibly flashes white
|
|
421
|
-
* on any element whose color changes during the transition (e.g. a nav item
|
|
422
|
-
* going from inactive to active). Disabling the root group's animation makes
|
|
423
|
-
* transitions opt-in — only elements with an explicit view-transition-name
|
|
424
|
-
* (set inline via style.viewTransitionName) animate; everything else swaps
|
|
425
|
-
* instantly with no crossfade artifact.
|
|
426
|
-
*/
|
|
427
|
-
::view-transition-group(root) {
|
|
428
|
-
animation-duration: 0s;
|
|
82
|
+
.data-closed\:animate-out[data-closed],
|
|
83
|
+
.data-closed\:animate-out[data-state="closed"] {
|
|
84
|
+
animation:
|
|
85
|
+
fade-out 120ms ease-in,
|
|
86
|
+
zoom-out 120ms ease-in;
|
|
429
87
|
}
|
|
430
88
|
|
|
431
89
|
@media (prefers-reduced-motion: reduce) {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
90
|
+
.animate-in,
|
|
91
|
+
.animate-out,
|
|
92
|
+
[data-open],
|
|
93
|
+
[data-closed] {
|
|
435
94
|
animation: none !important;
|
|
436
95
|
}
|
|
437
96
|
}
|
|
@@ -1,11 +1,26 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion";
|
|
2
2
|
import { ChevronDown } from "lucide-react";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
5
5
|
import { cn } from "../../lib/utils";
|
|
6
6
|
|
|
7
|
-
function Accordion({
|
|
8
|
-
|
|
7
|
+
function Accordion({
|
|
8
|
+
type,
|
|
9
|
+
collapsible: _collapsible,
|
|
10
|
+
className,
|
|
11
|
+
...props
|
|
12
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Root> & {
|
|
13
|
+
type?: "single" | "multiple";
|
|
14
|
+
collapsible?: boolean;
|
|
15
|
+
}) {
|
|
16
|
+
return (
|
|
17
|
+
<AccordionPrimitive.Root
|
|
18
|
+
data-slot="accordion"
|
|
19
|
+
multiple={type === "multiple"}
|
|
20
|
+
{...props}
|
|
21
|
+
className={cn("w-full", className)}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
9
24
|
}
|
|
10
25
|
|
|
11
26
|
function AccordionItem({
|
|
@@ -15,10 +30,7 @@ function AccordionItem({
|
|
|
15
30
|
return (
|
|
16
31
|
<AccordionPrimitive.Item
|
|
17
32
|
data-slot="accordion-item"
|
|
18
|
-
className={cn(
|
|
19
|
-
"border-default bg-canvas mb-2 overflow-hidden rounded-md border last:mb-0",
|
|
20
|
-
className,
|
|
21
|
-
)}
|
|
33
|
+
className={cn("mb-2 overflow-hidden rounded-md border last:mb-0", className)}
|
|
22
34
|
{...props}
|
|
23
35
|
/>
|
|
24
36
|
);
|
|
@@ -50,15 +62,15 @@ function AccordionContent({
|
|
|
50
62
|
className,
|
|
51
63
|
children,
|
|
52
64
|
...props
|
|
53
|
-
}: React.ComponentProps<typeof AccordionPrimitive.
|
|
65
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Panel>) {
|
|
54
66
|
return (
|
|
55
|
-
<AccordionPrimitive.
|
|
67
|
+
<AccordionPrimitive.Panel
|
|
56
68
|
data-slot="accordion-content"
|
|
57
69
|
className="animate-accordion-down overflow-hidden text-sm"
|
|
58
70
|
{...props}
|
|
59
71
|
>
|
|
60
72
|
<div className={cn("px-4 pt-2 pb-3", className)}>{children}</div>
|
|
61
|
-
</AccordionPrimitive.
|
|
73
|
+
</AccordionPrimitive.Panel>
|
|
62
74
|
);
|
|
63
75
|
}
|
|
64
76
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
|
|
3
|
+
import { FilterChip } from "./filter-chip";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: "DataDisplay/FilterChip",
|
|
7
|
+
component: FilterChip,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
args: {
|
|
10
|
+
onRemove: () => {},
|
|
11
|
+
},
|
|
12
|
+
} satisfies Meta<typeof FilterChip>;
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
type Story = StoryObj<typeof meta>;
|
|
16
|
+
|
|
17
|
+
export const Default: Story = {
|
|
18
|
+
args: { label: "Status: Active" },
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const Editable: Story = {
|
|
22
|
+
args: { label: "Status: Active", onClick: () => {} },
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const LongLabel: Story = {
|
|
26
|
+
args: { label: "Created between Jan 1, 2026 and Jul 24, 2026" },
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const Group: Story = {
|
|
30
|
+
args: { label: "Filters" },
|
|
31
|
+
render: () => (
|
|
32
|
+
<div className="flex flex-wrap gap-2">
|
|
33
|
+
<FilterChip label="Status: Active" onRemove={() => {}} onClick={() => {}} />
|
|
34
|
+
<FilterChip label="Team: Design" onRemove={() => {}} onClick={() => {}} />
|
|
35
|
+
<FilterChip label="Archived" onRemove={() => {}} />
|
|
36
|
+
</div>
|
|
37
|
+
),
|
|
38
|
+
};
|