@discourser/design-system 0.15.0 → 0.15.1
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/dist/{chunk-QC44JPCA.cjs → chunk-ABC7N32K.cjs} +316 -10
- package/dist/chunk-ABC7N32K.cjs.map +1 -0
- package/dist/{chunk-F7LHARS4.js → chunk-GD6Q2FUE.js} +446 -6
- package/dist/chunk-GD6Q2FUE.js.map +1 -0
- package/dist/{chunk-M7J7WKJY.js → chunk-SBKRSXSZ.js} +317 -11
- package/dist/chunk-SBKRSXSZ.js.map +1 -0
- package/dist/{chunk-QP4EJI3G.cjs → chunk-UNWXE6UB.cjs} +450 -2
- package/dist/chunk-UNWXE6UB.cjs.map +1 -0
- package/dist/components/Breadcrumb.d.ts +9 -0
- package/dist/components/Breadcrumb.d.ts.map +1 -0
- package/dist/components/Checkbox.d.ts +6 -6
- package/dist/components/Icons/ClockIcon.d.ts +6 -0
- package/dist/components/Icons/ClockIcon.d.ts.map +1 -0
- package/dist/components/Icons/GripDotsVerticalIcon.d.ts +6 -0
- package/dist/components/Icons/GripDotsVerticalIcon.d.ts.map +1 -0
- package/dist/components/Icons/index.d.ts +3 -0
- package/dist/components/Icons/index.d.ts.map +1 -0
- package/dist/components/ScenarioQueue/AddScenarioDialog.d.ts +16 -0
- package/dist/components/ScenarioQueue/AddScenarioDialog.d.ts.map +1 -0
- package/dist/components/ScenarioQueue/ScenarioCard.d.ts +10 -0
- package/dist/components/ScenarioQueue/ScenarioCard.d.ts.map +1 -0
- package/dist/components/ScenarioQueue/ScenarioCardDraggable.d.ts +15 -0
- package/dist/components/ScenarioQueue/ScenarioCardDraggable.d.ts.map +1 -0
- package/dist/components/ScenarioQueue/ScenarioQueue.d.ts +3 -0
- package/dist/components/ScenarioQueue/ScenarioQueue.d.ts.map +1 -0
- package/dist/components/ScenarioQueue/index.d.ts +6 -0
- package/dist/components/ScenarioQueue/index.d.ts.map +1 -0
- package/dist/components/ScenarioQueue/types.d.ts +56 -0
- package/dist/components/ScenarioQueue/types.d.ts.map +1 -0
- package/dist/components/index.cjs +65 -33
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/index.cjs +69 -37
- package/dist/index.js +2 -2
- package/dist/preset/index.cjs +2 -2
- package/dist/preset/index.d.ts.map +1 -1
- package/dist/preset/index.js +1 -1
- package/dist/preset/recipes/avatar.d.ts.map +1 -1
- package/dist/preset/recipes/breadcrumb.d.ts +2 -0
- package/dist/preset/recipes/breadcrumb.d.ts.map +1 -0
- package/dist/preset/recipes/checkbox.d.ts.map +1 -1
- package/dist/preset/recipes/field.d.ts.map +1 -1
- package/dist/preset/recipes/index.d.ts +3 -0
- package/dist/preset/recipes/index.d.ts.map +1 -1
- package/dist/preset/recipes/progress.d.ts.map +1 -1
- package/dist/preset/recipes/radio-group.d.ts.map +1 -1
- package/dist/preset/recipes/scenario-card.d.ts +2 -0
- package/dist/preset/recipes/scenario-card.d.ts.map +1 -0
- package/dist/preset/recipes/scenario-queue.d.ts +2 -0
- package/dist/preset/recipes/scenario-queue.d.ts.map +1 -0
- package/dist/preset/recipes/steps.d.ts.map +1 -1
- package/dist/preset/recipes/toast.d.ts.map +1 -1
- package/dist/preset/recipes/tooltip.d.ts.map +1 -1
- package/dist/preset/semantic-tokens.d.ts +12 -0
- package/dist/preset/semantic-tokens.d.ts.map +1 -1
- package/package.json +10 -1
- package/src/components/Breadcrumb.tsx +34 -0
- package/src/components/Icons/ClockIcon.tsx +40 -0
- package/src/components/Icons/GripDotsVerticalIcon.tsx +26 -0
- package/src/components/Icons/index.ts +2 -0
- package/src/components/ScenarioQueue/AddScenarioDialog.tsx +137 -0
- package/src/components/ScenarioQueue/ScenarioCard.tsx +120 -0
- package/src/components/ScenarioQueue/ScenarioCardDraggable.tsx +41 -0
- package/src/components/ScenarioQueue/ScenarioQueue.test.tsx +398 -0
- package/src/components/ScenarioQueue/ScenarioQueue.tsx +162 -0
- package/src/components/ScenarioQueue/index.ts +11 -0
- package/src/components/ScenarioQueue/types.ts +86 -0
- package/src/components/index.ts +19 -0
- package/src/preset/index.ts +9 -0
- package/src/preset/recipes/avatar.ts +1 -2
- package/src/preset/recipes/breadcrumb.ts +77 -0
- package/src/preset/recipes/checkbox.ts +1 -2
- package/src/preset/recipes/field.ts +1 -2
- package/src/preset/recipes/index.ts +7 -0
- package/src/preset/recipes/progress.ts +1 -2
- package/src/preset/recipes/radio-group.ts +1 -2
- package/src/preset/recipes/scenario-card.ts +151 -0
- package/src/preset/recipes/scenario-queue.ts +99 -0
- package/src/preset/recipes/steps.ts +1 -2
- package/src/preset/recipes/toast.ts +1 -2
- package/src/preset/recipes/tooltip.ts +1 -2
- package/src/preset/semantic-tokens.ts +4 -0
- package/src/test/setup.ts +12 -0
- package/dist/chunk-F7LHARS4.js.map +0 -1
- package/dist/chunk-M7J7WKJY.js.map +0 -1
- package/dist/chunk-QC44JPCA.cjs.map +0 -1
- package/dist/chunk-QP4EJI3G.cjs.map +0 -1
package/src/preset/index.ts
CHANGED
|
@@ -19,6 +19,9 @@ import { accordion } from './recipes/accordion';
|
|
|
19
19
|
import { drawer } from './recipes/drawer';
|
|
20
20
|
import { tabs } from './recipes/tabs';
|
|
21
21
|
|
|
22
|
+
// Park UI recipes - Navigation
|
|
23
|
+
import { breadcrumb } from './recipes/breadcrumb';
|
|
24
|
+
|
|
22
25
|
// Park UI recipes - Form Elements
|
|
23
26
|
import { switchRecipe } from './recipes/switch';
|
|
24
27
|
import { checkbox } from './recipes/checkbox';
|
|
@@ -44,6 +47,8 @@ import { heading } from './recipes/heading';
|
|
|
44
47
|
|
|
45
48
|
// Custom Components
|
|
46
49
|
import { stepper } from './recipes/stepper';
|
|
50
|
+
import { scenarioCard } from './recipes/scenario-card';
|
|
51
|
+
import { scenarioQueue } from './recipes/scenario-queue';
|
|
47
52
|
|
|
48
53
|
// Park UI theme extensions
|
|
49
54
|
import { layerStyles } from './layer-styles';
|
|
@@ -155,6 +160,8 @@ export const discourserPandaPreset = definePreset({
|
|
|
155
160
|
accordion,
|
|
156
161
|
drawer,
|
|
157
162
|
tabs,
|
|
163
|
+
// Navigation
|
|
164
|
+
breadcrumb,
|
|
158
165
|
// Form Elements
|
|
159
166
|
switchComponent: switchRecipe,
|
|
160
167
|
checkbox,
|
|
@@ -171,6 +178,8 @@ export const discourserPandaPreset = definePreset({
|
|
|
171
178
|
tooltip,
|
|
172
179
|
// Custom Components
|
|
173
180
|
stepper,
|
|
181
|
+
scenarioCard,
|
|
182
|
+
scenarioQueue,
|
|
174
183
|
},
|
|
175
184
|
},
|
|
176
185
|
},
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { avatarAnatomy } from '@ark-ui/react/anatomy'
|
|
2
1
|
import { defineSlotRecipe } from '@pandacss/dev'
|
|
3
2
|
|
|
4
3
|
export const avatar = defineSlotRecipe({
|
|
5
4
|
className: 'avatar',
|
|
6
|
-
slots:
|
|
5
|
+
slots: ['root', 'image', 'fallback'],
|
|
7
6
|
base: {
|
|
8
7
|
root: {
|
|
9
8
|
display: 'inline-flex',
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { defineSlotRecipe } from '@pandacss/dev'
|
|
2
|
+
|
|
3
|
+
export const breadcrumb = defineSlotRecipe({
|
|
4
|
+
className: 'breadcrumb',
|
|
5
|
+
slots: ['root', 'list', 'link', 'item', 'separator', 'ellipsis'],
|
|
6
|
+
base: {
|
|
7
|
+
list: {
|
|
8
|
+
alignItems: 'center',
|
|
9
|
+
display: 'flex',
|
|
10
|
+
listStyle: 'none',
|
|
11
|
+
wordBreak: 'break-word',
|
|
12
|
+
},
|
|
13
|
+
link: {
|
|
14
|
+
alignItems: 'center',
|
|
15
|
+
borderRadius: 'l1',
|
|
16
|
+
display: 'inline-flex',
|
|
17
|
+
focusRing: 'outside',
|
|
18
|
+
gap: '2',
|
|
19
|
+
outline: '0',
|
|
20
|
+
textDecoration: 'none',
|
|
21
|
+
transition: 'color',
|
|
22
|
+
_icon: { boxSize: '1em' },
|
|
23
|
+
},
|
|
24
|
+
item: {
|
|
25
|
+
display: 'inline-flex',
|
|
26
|
+
alignItems: 'center',
|
|
27
|
+
color: 'fg.muted',
|
|
28
|
+
_last: {
|
|
29
|
+
color: 'fg.default',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
separator: {
|
|
33
|
+
color: 'fg.subtle',
|
|
34
|
+
_icon: { boxSize: '1em' },
|
|
35
|
+
_rtl: { rotate: '180deg' },
|
|
36
|
+
},
|
|
37
|
+
ellipsis: {
|
|
38
|
+
alignItems: 'center',
|
|
39
|
+
color: 'fg.muted',
|
|
40
|
+
display: 'inline-flex',
|
|
41
|
+
justifyContent: 'center',
|
|
42
|
+
_icon: { boxSize: '1em' },
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
variants: {
|
|
47
|
+
variant: {
|
|
48
|
+
underline: {
|
|
49
|
+
link: {
|
|
50
|
+
textDecoration: 'underline',
|
|
51
|
+
textDecorationThickness: '0.1em',
|
|
52
|
+
textUnderlineOffset: '0.125em',
|
|
53
|
+
textDecorationColor: 'fg.subtle',
|
|
54
|
+
_hover: { textDecorationColor: 'fg.default' },
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
plain: {
|
|
58
|
+
link: {
|
|
59
|
+
color: 'fg.muted',
|
|
60
|
+
_hover: { color: 'fg.default' },
|
|
61
|
+
_currentPage: { color: 'fg.default' },
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
size: {
|
|
66
|
+
xs: { list: { gap: '1', textStyle: 'xs' } },
|
|
67
|
+
sm: { list: { gap: '1', textStyle: 'sm' } },
|
|
68
|
+
md: { list: { gap: '1.5', textStyle: 'md' } },
|
|
69
|
+
lg: { list: { gap: '2', textStyle: 'lg' } },
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
defaultVariants: {
|
|
74
|
+
variant: 'plain',
|
|
75
|
+
size: 'md',
|
|
76
|
+
},
|
|
77
|
+
})
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { checkboxAnatomy } from '@ark-ui/react/anatomy'
|
|
2
1
|
import { defineSlotRecipe } from '@pandacss/dev'
|
|
3
2
|
|
|
4
3
|
export const checkbox = defineSlotRecipe({
|
|
5
|
-
slots:
|
|
4
|
+
slots: ['root', 'label', 'control', 'indicator', 'group'],
|
|
6
5
|
className: 'checkbox',
|
|
7
6
|
base: {
|
|
8
7
|
root: {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { fieldAnatomy } from '@ark-ui/react/anatomy'
|
|
2
1
|
import { defineSlotRecipe } from '@pandacss/dev'
|
|
3
2
|
|
|
4
3
|
export const field = defineSlotRecipe({
|
|
5
4
|
className: 'field',
|
|
6
|
-
slots:
|
|
5
|
+
slots: ['root', 'errorText', 'helperText', 'input', 'label', 'select', 'textarea', 'requiredIndicator'],
|
|
7
6
|
base: {
|
|
8
7
|
root: {
|
|
9
8
|
display: 'flex',
|
|
@@ -11,6 +11,9 @@ export * from './accordion';
|
|
|
11
11
|
export * from './drawer';
|
|
12
12
|
export * from './tabs';
|
|
13
13
|
|
|
14
|
+
// Navigation
|
|
15
|
+
export * from './breadcrumb';
|
|
16
|
+
|
|
14
17
|
// Form elements
|
|
15
18
|
export * from './switch';
|
|
16
19
|
export * from './checkbox';
|
|
@@ -38,3 +41,7 @@ export * from './heading';
|
|
|
38
41
|
// Utilities
|
|
39
42
|
export * from './absolute-center';
|
|
40
43
|
export * from './group';
|
|
44
|
+
|
|
45
|
+
// Custom Components
|
|
46
|
+
export * from './scenario-card';
|
|
47
|
+
export * from './scenario-queue';
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { progressAnatomy } from '@ark-ui/react/anatomy'
|
|
2
1
|
import { defineSlotRecipe } from '@pandacss/dev'
|
|
3
2
|
|
|
4
3
|
export const progress = defineSlotRecipe({
|
|
5
|
-
slots:
|
|
4
|
+
slots: ['root', 'label', 'track', 'range', 'valueText', 'view', 'circle', 'circleTrack', 'circleRange'],
|
|
6
5
|
className: 'progress',
|
|
7
6
|
base: {
|
|
8
7
|
root: {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { radioGroupAnatomy } from '@ark-ui/react/anatomy'
|
|
2
1
|
import { defineSlotRecipe } from '@pandacss/dev'
|
|
3
2
|
|
|
4
3
|
export const radioGroup = defineSlotRecipe({
|
|
5
4
|
className: 'radio-group',
|
|
6
|
-
slots:
|
|
5
|
+
slots: ['root', 'label', 'item', 'itemText', 'itemControl', 'indicator'],
|
|
7
6
|
base: {
|
|
8
7
|
root: {
|
|
9
8
|
display: 'flex',
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { defineSlotRecipe } from '@pandacss/dev'
|
|
2
|
+
|
|
3
|
+
export const scenarioCard = defineSlotRecipe({
|
|
4
|
+
className: 'scenario-card',
|
|
5
|
+
// Slots cover only scenario-specific styling.
|
|
6
|
+
// Base card appearance (bg, border, borderRadius, overflow) comes from
|
|
7
|
+
// Card.Root variant="outline" via the card slot recipe.
|
|
8
|
+
// Layout structure (flex, gap, alignment) comes from Panda CSS JSX primitives.
|
|
9
|
+
slots: ['root', 'positionBadge', 'dragHandle', 'title', 'switchRow', 'switchLabel', 'difficultyBadge', 'durationBadge'],
|
|
10
|
+
base: {
|
|
11
|
+
root: {
|
|
12
|
+
// Left accent border — inactive cards use transparent to preserve card width.
|
|
13
|
+
borderLeftWidth: '3px',
|
|
14
|
+
borderLeftStyle: 'solid',
|
|
15
|
+
borderLeftColor: 'transparent',
|
|
16
|
+
// Custom purple-tinted shadow from Figma spec (0px 2px 8px 0px rgba(167,139,250,0.15)).
|
|
17
|
+
// This overrides Card.Root variant="elevated" (M3 level4) which is too heavy.
|
|
18
|
+
// Raw value intentional: this non-standard shadow has no M3 elevation equivalent.
|
|
19
|
+
boxShadow: '0px 2px 8px 0px rgba(167, 139, 250, 0.15)',
|
|
20
|
+
// Figma cards use neutral/99 (#FDFCF5) — a warm off-white.
|
|
21
|
+
// neutral.surface.bg resolves to white (#FFFFFF) in light mode, so we override.
|
|
22
|
+
bg: 'neutral.1',
|
|
23
|
+
transition: 'border-color',
|
|
24
|
+
transitionDuration: 'normal',
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
// Circle primitive handles: w/h (size="12"), borderRadius:full, flex centering.
|
|
28
|
+
// Recipe handles: visual appearance (border, color, font).
|
|
29
|
+
positionBadge: {
|
|
30
|
+
fontSize: 'md',
|
|
31
|
+
fontWeight: 'semibold',
|
|
32
|
+
flexShrink: 0,
|
|
33
|
+
borderWidth: '1px',
|
|
34
|
+
borderStyle: 'solid',
|
|
35
|
+
borderColor: 'neutral.6',
|
|
36
|
+
color: 'fg.default',
|
|
37
|
+
bg: 'transparent',
|
|
38
|
+
transition: 'all',
|
|
39
|
+
transitionDuration: 'normal',
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
dragHandle: {
|
|
43
|
+
display: 'flex',
|
|
44
|
+
alignItems: 'center',
|
|
45
|
+
justifyContent: 'center',
|
|
46
|
+
// TODO: Create semantic token (e.g. colors.icon.subdued) that maps to secondary.6
|
|
47
|
+
// Using palette bridge value directly until semantic token is defined
|
|
48
|
+
color: 'secondary.6',
|
|
49
|
+
cursor: 'grab',
|
|
50
|
+
flexShrink: 0,
|
|
51
|
+
width: '9',
|
|
52
|
+
height: '10',
|
|
53
|
+
_active: { cursor: 'grabbing' },
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
title: {
|
|
57
|
+
width: 'full',
|
|
58
|
+
fontSize: 'sm',
|
|
59
|
+
fontWeight: 'semibold',
|
|
60
|
+
lineHeight: '1.4',
|
|
61
|
+
color: 'fg.default',
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
// HStack handles: display:flex, alignItems:center, justifyContent:space-between.
|
|
65
|
+
switchRow: {
|
|
66
|
+
width: 'full',
|
|
67
|
+
pt: '1',
|
|
68
|
+
mt: '1',
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
switchLabel: {
|
|
72
|
+
fontSize: 'sm',
|
|
73
|
+
color: 'fg.muted',
|
|
74
|
+
fontWeight: 'medium',
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
// Difficulty pill: M3 container tokens selected by data-difficulty attribute.
|
|
78
|
+
// Default (beginner) = primaryContainer; overridden for intermediate/advanced.
|
|
79
|
+
difficultyBadge: {
|
|
80
|
+
display: 'inline-flex',
|
|
81
|
+
alignItems: 'center',
|
|
82
|
+
borderRadius: 'l2',
|
|
83
|
+
px: '2',
|
|
84
|
+
h: '5',
|
|
85
|
+
fontSize: 'xs',
|
|
86
|
+
fontWeight: 'medium',
|
|
87
|
+
bg: 'm3Primary.container',
|
|
88
|
+
color: 'onM3Primary.container',
|
|
89
|
+
'&[data-difficulty="intermediate"]': {
|
|
90
|
+
bg: 'm3Secondary.container',
|
|
91
|
+
color: 'onM3Secondary.container',
|
|
92
|
+
},
|
|
93
|
+
'&[data-difficulty="advanced"]': {
|
|
94
|
+
bg: 'm3Tertiary.container',
|
|
95
|
+
color: 'onM3Tertiary.container',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
// Duration pill: per-difficulty inverse palette colors.
|
|
100
|
+
// Default (beginner): inversePrimary → semanticDark.primary (#B1D18A light, #4C662B dark)
|
|
101
|
+
// Intermediate: inverseSecondary → semanticDark.secondary (#BFCBAD light, #586249 dark)
|
|
102
|
+
// Advanced: inverseTertiary → semanticDark.tertiary (#A0D0CB light, #386663 dark)
|
|
103
|
+
durationBadge: {
|
|
104
|
+
display: 'inline-flex',
|
|
105
|
+
alignItems: 'center',
|
|
106
|
+
gap: '1',
|
|
107
|
+
borderRadius: 'l2',
|
|
108
|
+
px: '2',
|
|
109
|
+
h: '5',
|
|
110
|
+
fontSize: 'xs',
|
|
111
|
+
fontWeight: 'medium',
|
|
112
|
+
bg: 'inversePrimary',
|
|
113
|
+
color: 'onSurface',
|
|
114
|
+
'&[data-difficulty="intermediate"]': {
|
|
115
|
+
bg: 'inverseSecondary',
|
|
116
|
+
},
|
|
117
|
+
'&[data-difficulty="advanced"]': {
|
|
118
|
+
bg: 'inverseTertiary',
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
variants: {
|
|
124
|
+
isActive: {
|
|
125
|
+
true: {
|
|
126
|
+
root: {
|
|
127
|
+
borderLeftColor: 'primary.6',
|
|
128
|
+
},
|
|
129
|
+
positionBadge: {
|
|
130
|
+
bg: 'primary.6',
|
|
131
|
+
color: 'white',
|
|
132
|
+
borderColor: 'primary.6',
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
false: {},
|
|
136
|
+
},
|
|
137
|
+
isDragging: {
|
|
138
|
+
true: {
|
|
139
|
+
root: {
|
|
140
|
+
opacity: '0.4',
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
false: {},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
defaultVariants: {
|
|
148
|
+
isActive: false,
|
|
149
|
+
isDragging: false,
|
|
150
|
+
},
|
|
151
|
+
})
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { defineSlotRecipe } from '@pandacss/dev'
|
|
2
|
+
|
|
3
|
+
export const scenarioQueue = defineSlotRecipe({
|
|
4
|
+
className: 'scenario-queue',
|
|
5
|
+
description: 'Panel component with tabs and draggable scenario cards',
|
|
6
|
+
|
|
7
|
+
slots: [
|
|
8
|
+
'root',
|
|
9
|
+
'header',
|
|
10
|
+
'title',
|
|
11
|
+
'count',
|
|
12
|
+
'tabsInner',
|
|
13
|
+
'tabList',
|
|
14
|
+
'tabsContent',
|
|
15
|
+
'scrollArea',
|
|
16
|
+
'emptyState',
|
|
17
|
+
'addButtonArea',
|
|
18
|
+
'addButton',
|
|
19
|
+
],
|
|
20
|
+
|
|
21
|
+
base: {
|
|
22
|
+
root: {
|
|
23
|
+
display: 'flex',
|
|
24
|
+
flexDirection: 'column',
|
|
25
|
+
h: 'full',
|
|
26
|
+
minH: '320px',
|
|
27
|
+
minW: '250px',
|
|
28
|
+
maxW: '300px',
|
|
29
|
+
overflow: 'hidden',
|
|
30
|
+
bg: 'surface',
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
header: {
|
|
34
|
+
px: '4',
|
|
35
|
+
pt: '4',
|
|
36
|
+
pb: '2',
|
|
37
|
+
flexShrink: 0,
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
title: {
|
|
41
|
+
fontWeight: 'semibold',
|
|
42
|
+
fontSize: 'md',
|
|
43
|
+
color: 'fg.default',
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
count: {
|
|
47
|
+
fontSize: 'xs',
|
|
48
|
+
color: 'fg.muted',
|
|
49
|
+
mt: '0.5',
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
// Applied directly to Tabs.Root className — handles the flex column growth
|
|
53
|
+
// and scroll containment without a redundant wrapper div.
|
|
54
|
+
tabsInner: {
|
|
55
|
+
flex: '1',
|
|
56
|
+
minHeight: '0',
|
|
57
|
+
overflow: 'hidden',
|
|
58
|
+
display: 'flex',
|
|
59
|
+
flexDirection: 'column',
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
tabList: {
|
|
63
|
+
px: '4',
|
|
64
|
+
flexShrink: 0,
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
// Applied to each Tabs.Content — allows independent scrolling per tab.
|
|
68
|
+
tabsContent: {
|
|
69
|
+
flex: '1',
|
|
70
|
+
minHeight: '0',
|
|
71
|
+
overflowY: 'auto',
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
// Block layout so cards size to natural height and the container scrolls.
|
|
75
|
+
scrollArea: {
|
|
76
|
+
px: '4',
|
|
77
|
+
py: '3',
|
|
78
|
+
'& > * + *': { marginTop: '6' },
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
// Center primitive handles the flex centering; recipe provides spacing/text.
|
|
82
|
+
emptyState: {
|
|
83
|
+
py: '12',
|
|
84
|
+
fontSize: 'sm',
|
|
85
|
+
color: 'fg.muted',
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
addButtonArea: {
|
|
89
|
+
px: '4',
|
|
90
|
+
pb: '4',
|
|
91
|
+
pt: '2',
|
|
92
|
+
flexShrink: 0,
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
addButton: {
|
|
96
|
+
width: 'full',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
})
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { stepsAnatomy } from '@ark-ui/react/anatomy';
|
|
2
1
|
import { defineSlotRecipe } from '@pandacss/dev';
|
|
3
2
|
|
|
4
3
|
export const steps = defineSlotRecipe({
|
|
5
4
|
className: 'steps',
|
|
6
|
-
slots:
|
|
5
|
+
slots: ['root', 'list', 'item', 'trigger', 'indicator', 'separator', 'content', 'nextTrigger', 'prevTrigger', 'progress'],
|
|
7
6
|
base: {},
|
|
8
7
|
});
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { toastAnatomy } from '@ark-ui/react/anatomy'
|
|
2
1
|
import { defineSlotRecipe } from '@pandacss/dev'
|
|
3
2
|
|
|
4
3
|
export const toast = defineSlotRecipe({
|
|
5
4
|
className: 'toast',
|
|
6
|
-
slots:
|
|
5
|
+
slots: ['group', 'root', 'title', 'description', 'actionTrigger', 'closeTrigger'],
|
|
7
6
|
base: {
|
|
8
7
|
root: {
|
|
9
8
|
alignItems: 'start',
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { tooltipAnatomy } from '@ark-ui/react/anatomy'
|
|
2
1
|
import { defineSlotRecipe } from '@pandacss/dev'
|
|
3
2
|
|
|
4
3
|
export const tooltip = defineSlotRecipe({
|
|
5
4
|
className: 'tooltip',
|
|
6
|
-
slots:
|
|
5
|
+
slots: ['trigger', 'arrow', 'arrowTip', 'positioner', 'content'],
|
|
7
6
|
base: {
|
|
8
7
|
content: {
|
|
9
8
|
'--tooltip-bg': 'colors.gray.solid.bg',
|
|
@@ -69,6 +69,10 @@ export const m3SemanticTokens = defineSemanticTokens.colors({
|
|
|
69
69
|
inverseSurface: { value: { base: semantic.inverseSurface, _dark: semanticDark.inverseSurface } },
|
|
70
70
|
inverseOnSurface: { value: { base: semantic.inverseOnSurface, _dark: semanticDark.inverseOnSurface } },
|
|
71
71
|
inversePrimary: { value: { base: semantic.inversePrimary, _dark: semanticDark.inversePrimary } },
|
|
72
|
+
// Not standard M3 tokens, but follow inversePrimary's pattern:
|
|
73
|
+
// light mode = dark-palette value, dark mode = light-palette value.
|
|
74
|
+
inverseSecondary: { value: { base: semanticDark.secondary, _dark: semantic.secondary } },
|
|
75
|
+
inverseTertiary: { value: { base: semanticDark.tertiary, _dark: semantic.tertiary } },
|
|
72
76
|
|
|
73
77
|
// Scrim/Shadow
|
|
74
78
|
scrim: { value: { base: semantic.scrim, _dark: semanticDark.scrim } },
|
package/src/test/setup.ts
CHANGED
|
@@ -6,6 +6,18 @@ import { toHaveNoViolations } from 'jest-axe';
|
|
|
6
6
|
// Extend Vitest's expect with jest-axe matchers
|
|
7
7
|
expect.extend(toHaveNoViolations);
|
|
8
8
|
|
|
9
|
+
// Mock ResizeObserver — JSDOM does not implement it, but @zag-js/tabs requires
|
|
10
|
+
// it to sync the active tab indicator rectangle position.
|
|
11
|
+
Object.defineProperty(window, 'ResizeObserver', {
|
|
12
|
+
writable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
value: class ResizeObserver {
|
|
15
|
+
observe() {}
|
|
16
|
+
unobserve() {}
|
|
17
|
+
disconnect() {}
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
9
21
|
// Cleanup after each test
|
|
10
22
|
afterEach(() => {
|
|
11
23
|
cleanup();
|