@discourser/design-system 0.15.0 → 0.17.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.
Files changed (229) hide show
  1. package/dist/chunk-2P7Z5PVP.cjs +2151 -0
  2. package/dist/chunk-2P7Z5PVP.cjs.map +1 -0
  3. package/dist/{chunk-QC44JPCA.cjs → chunk-PFWU7QSM.cjs} +777 -15
  4. package/dist/chunk-PFWU7QSM.cjs.map +1 -0
  5. package/dist/chunk-QC7LGFM3.js +2099 -0
  6. package/dist/chunk-QC7LGFM3.js.map +1 -0
  7. package/dist/{chunk-M7J7WKJY.js → chunk-SNUJBT5R.js} +778 -16
  8. package/dist/chunk-SNUJBT5R.js.map +1 -0
  9. package/dist/components/Accordion.figma.d.ts +2 -0
  10. package/dist/components/Accordion.figma.d.ts.map +1 -0
  11. package/dist/components/Breadcrumb.d.ts +11 -0
  12. package/dist/components/Breadcrumb.d.ts.map +1 -0
  13. package/dist/components/Breadcrumb.figma.d.ts +2 -0
  14. package/dist/components/Breadcrumb.figma.d.ts.map +1 -0
  15. package/dist/components/Checkbox.d.ts +6 -6
  16. package/dist/components/ContentCard/ContentCard.d.ts +13 -0
  17. package/dist/components/ContentCard/ContentCard.d.ts.map +1 -0
  18. package/dist/components/ContentCard/ContentCard.figma.d.ts +2 -0
  19. package/dist/components/ContentCard/ContentCard.figma.d.ts.map +1 -0
  20. package/dist/components/ContentCard/index.d.ts +2 -0
  21. package/dist/components/ContentCard/index.d.ts.map +1 -0
  22. package/dist/components/{Heading.d.ts → Header.d.ts} +3 -3
  23. package/dist/components/Header.d.ts.map +1 -0
  24. package/dist/components/Header.figma.d.ts +2 -0
  25. package/dist/components/Header.figma.d.ts.map +1 -0
  26. package/dist/components/Icons/AccountIcon.d.ts +6 -0
  27. package/dist/components/Icons/AccountIcon.d.ts.map +1 -0
  28. package/dist/components/Icons/ChevronUpIcon.d.ts +6 -0
  29. package/dist/components/Icons/ChevronUpIcon.d.ts.map +1 -0
  30. package/dist/components/Icons/ClockIcon.d.ts +6 -0
  31. package/dist/components/Icons/ClockIcon.d.ts.map +1 -0
  32. package/dist/components/Icons/DashboardIcon.d.ts +6 -0
  33. package/dist/components/Icons/DashboardIcon.d.ts.map +1 -0
  34. package/dist/components/Icons/DiscourserLogo.d.ts +6 -0
  35. package/dist/components/Icons/DiscourserLogo.d.ts.map +1 -0
  36. package/dist/components/Icons/DiscourserLogo.figma.d.ts +2 -0
  37. package/dist/components/Icons/DiscourserLogo.figma.d.ts.map +1 -0
  38. package/dist/components/Icons/GripDotsVerticalIcon.d.ts +6 -0
  39. package/dist/components/Icons/GripDotsVerticalIcon.d.ts.map +1 -0
  40. package/dist/components/Icons/HelpIcon.d.ts +6 -0
  41. package/dist/components/Icons/HelpIcon.d.ts.map +1 -0
  42. package/dist/components/Icons/NotebookIcon.d.ts +6 -0
  43. package/dist/components/Icons/NotebookIcon.d.ts.map +1 -0
  44. package/dist/components/Icons/RightArrowIcon.d.ts +6 -0
  45. package/dist/components/Icons/RightArrowIcon.d.ts.map +1 -0
  46. package/dist/components/Icons/ScenarioIcon.d.ts +6 -0
  47. package/dist/components/Icons/ScenarioIcon.d.ts.map +1 -0
  48. package/dist/components/Icons/index.d.ts +11 -0
  49. package/dist/components/Icons/index.d.ts.map +1 -0
  50. package/dist/components/NavigationMenu/NavigationMenu.d.ts +3 -0
  51. package/dist/components/NavigationMenu/NavigationMenu.d.ts.map +1 -0
  52. package/dist/components/NavigationMenu/NavigationMenu.figma.d.ts +2 -0
  53. package/dist/components/NavigationMenu/NavigationMenu.figma.d.ts.map +1 -0
  54. package/dist/components/NavigationMenu/index.d.ts +3 -0
  55. package/dist/components/NavigationMenu/index.d.ts.map +1 -0
  56. package/dist/components/NavigationMenu/types.d.ts +25 -0
  57. package/dist/components/NavigationMenu/types.d.ts.map +1 -0
  58. package/dist/components/QuickStartPage/QuickStartPage.d.ts +21 -0
  59. package/dist/components/QuickStartPage/QuickStartPage.d.ts.map +1 -0
  60. package/dist/components/QuickStartPage/index.d.ts +3 -0
  61. package/dist/components/QuickStartPage/index.d.ts.map +1 -0
  62. package/dist/components/ScenarioQueue/AddScenarioDialog.d.ts +16 -0
  63. package/dist/components/ScenarioQueue/AddScenarioDialog.d.ts.map +1 -0
  64. package/dist/components/ScenarioQueue/ScenarioCard.d.ts +10 -0
  65. package/dist/components/ScenarioQueue/ScenarioCard.d.ts.map +1 -0
  66. package/dist/components/ScenarioQueue/ScenarioCardDraggable.d.ts +15 -0
  67. package/dist/components/ScenarioQueue/ScenarioCardDraggable.d.ts.map +1 -0
  68. package/dist/components/ScenarioQueue/ScenarioQueue.d.ts +3 -0
  69. package/dist/components/ScenarioQueue/ScenarioQueue.d.ts.map +1 -0
  70. package/dist/components/ScenarioQueue/ScenarioQueue.figma.d.ts +2 -0
  71. package/dist/components/ScenarioQueue/ScenarioQueue.figma.d.ts.map +1 -0
  72. package/dist/components/ScenarioQueue/index.d.ts +6 -0
  73. package/dist/components/ScenarioQueue/index.d.ts.map +1 -0
  74. package/dist/components/ScenarioQueue/types.d.ts +56 -0
  75. package/dist/components/ScenarioQueue/types.d.ts.map +1 -0
  76. package/dist/components/ScenarioSettings/ScenarioSettings.d.ts +3 -0
  77. package/dist/components/ScenarioSettings/ScenarioSettings.d.ts.map +1 -0
  78. package/dist/components/ScenarioSettings/ScenarioSettings.figma.d.ts +2 -0
  79. package/dist/components/ScenarioSettings/ScenarioSettings.figma.d.ts.map +1 -0
  80. package/dist/components/ScenarioSettings/index.d.ts +3 -0
  81. package/dist/components/ScenarioSettings/index.d.ts.map +1 -0
  82. package/dist/components/ScenarioSettings/types.d.ts +54 -0
  83. package/dist/components/ScenarioSettings/types.d.ts.map +1 -0
  84. package/dist/components/index.cjs +110 -34
  85. package/dist/components/index.d.ts +16 -1
  86. package/dist/components/index.d.ts.map +1 -1
  87. package/dist/components/index.js +1 -1
  88. package/dist/figma-codex/config.d.ts +8 -0
  89. package/dist/figma-codex/config.d.ts.map +1 -0
  90. package/dist/figma-codex/fixtures/CompoundComponent/CompoundComponent.d.ts +6 -0
  91. package/dist/figma-codex/fixtures/CompoundComponent/CompoundComponent.d.ts.map +1 -0
  92. package/dist/figma-codex/fixtures/CompoundComponent/index.d.ts +2 -0
  93. package/dist/figma-codex/fixtures/CompoundComponent/index.d.ts.map +1 -0
  94. package/dist/figma-codex/fixtures/CompoundComponent.figma.d.ts +2 -0
  95. package/dist/figma-codex/fixtures/CompoundComponent.figma.d.ts.map +1 -0
  96. package/dist/figma-codex/fixtures/SimpleComponent.d.ts +8 -0
  97. package/dist/figma-codex/fixtures/SimpleComponent.d.ts.map +1 -0
  98. package/dist/figma-codex/fixtures/SimpleComponent.figma.d.ts +2 -0
  99. package/dist/figma-codex/fixtures/SimpleComponent.figma.d.ts.map +1 -0
  100. package/dist/figma-codex/generate.d.ts +6 -0
  101. package/dist/figma-codex/generate.d.ts.map +1 -0
  102. package/dist/figma-codex/parser.d.ts +18 -0
  103. package/dist/figma-codex/parser.d.ts.map +1 -0
  104. package/dist/figma-codex/resolver.d.ts +5 -0
  105. package/dist/figma-codex/resolver.d.ts.map +1 -0
  106. package/dist/figma-codex/schema.d.ts +60 -0
  107. package/dist/figma-codex/schema.d.ts.map +1 -0
  108. package/dist/figma-codex/writer.d.ts +8 -0
  109. package/dist/figma-codex/writer.d.ts.map +1 -0
  110. package/dist/figma-codex.json +373 -0
  111. package/dist/index.cjs +114 -38
  112. package/dist/index.js +2 -2
  113. package/dist/preset/index.cjs +2 -2
  114. package/dist/preset/index.d.ts.map +1 -1
  115. package/dist/preset/index.js +1 -1
  116. package/dist/preset/recipes/accordion.d.ts.map +1 -1
  117. package/dist/preset/recipes/avatar.d.ts.map +1 -1
  118. package/dist/preset/recipes/breadcrumb.d.ts +2 -0
  119. package/dist/preset/recipes/breadcrumb.d.ts.map +1 -0
  120. package/dist/preset/recipes/checkbox.d.ts.map +1 -1
  121. package/dist/preset/recipes/content-card.d.ts +2 -0
  122. package/dist/preset/recipes/content-card.d.ts.map +1 -0
  123. package/dist/preset/recipes/field.d.ts.map +1 -1
  124. package/dist/preset/recipes/index.d.ts +7 -0
  125. package/dist/preset/recipes/index.d.ts.map +1 -1
  126. package/dist/preset/recipes/navigation-menu.d.ts +2 -0
  127. package/dist/preset/recipes/navigation-menu.d.ts.map +1 -0
  128. package/dist/preset/recipes/progress.d.ts.map +1 -1
  129. package/dist/preset/recipes/radio-group.d.ts.map +1 -1
  130. package/dist/preset/recipes/scenario-card.d.ts +2 -0
  131. package/dist/preset/recipes/scenario-card.d.ts.map +1 -0
  132. package/dist/preset/recipes/scenario-queue.d.ts +2 -0
  133. package/dist/preset/recipes/scenario-queue.d.ts.map +1 -0
  134. package/dist/preset/recipes/scenario-settings.d.ts +2 -0
  135. package/dist/preset/recipes/scenario-settings.d.ts.map +1 -0
  136. package/dist/preset/recipes/steps.d.ts.map +1 -1
  137. package/dist/preset/recipes/toast.d.ts.map +1 -1
  138. package/dist/preset/recipes/tooltip.d.ts.map +1 -1
  139. package/dist/preset/semantic-tokens.d.ts +12 -0
  140. package/dist/preset/semantic-tokens.d.ts.map +1 -1
  141. package/package.json +35 -2
  142. package/src/components/Accordion.figma.tsx +20 -0
  143. package/src/components/Breadcrumb.figma.tsx +18 -0
  144. package/src/components/Breadcrumb.tsx +52 -0
  145. package/src/components/ContentCard/ContentCard.figma.tsx +21 -0
  146. package/src/components/ContentCard/ContentCard.test.tsx +197 -0
  147. package/src/components/ContentCard/ContentCard.tsx +19 -0
  148. package/src/components/ContentCard/index.ts +13 -0
  149. package/src/components/Header.figma.tsx +25 -0
  150. package/src/components/{Heading.tsx → Header.tsx} +2 -2
  151. package/src/components/Icons/AccountIcon.tsx +26 -0
  152. package/src/components/Icons/ChevronUpIcon.tsx +24 -0
  153. package/src/components/Icons/ClockIcon.tsx +40 -0
  154. package/src/components/Icons/DashboardIcon.tsx +47 -0
  155. package/src/components/Icons/Discourser-Logo.svg +14 -0
  156. package/src/components/Icons/DiscourserLogo.figma.tsx +10 -0
  157. package/src/components/Icons/DiscourserLogo.tsx +72 -0
  158. package/src/components/Icons/GripDotsVerticalIcon.tsx +26 -0
  159. package/src/components/Icons/HelpIcon.tsx +26 -0
  160. package/src/components/Icons/NotebookIcon.tsx +26 -0
  161. package/src/components/Icons/RightArrowIcon.tsx +23 -0
  162. package/src/components/Icons/ScenarioIcon.tsx +26 -0
  163. package/src/components/Icons/index.ts +13 -0
  164. package/src/components/NavigationMenu/NavigationMenu.figma.tsx +26 -0
  165. package/src/components/NavigationMenu/NavigationMenu.test.tsx +524 -0
  166. package/src/components/NavigationMenu/NavigationMenu.tsx +102 -0
  167. package/src/components/NavigationMenu/index.ts +2 -0
  168. package/src/components/NavigationMenu/types.ts +27 -0
  169. package/src/components/QuickStartPage/QuickStartPage.tsx +627 -0
  170. package/src/components/QuickStartPage/index.ts +2 -0
  171. package/src/components/ScenarioQueue/AddScenarioDialog.tsx +137 -0
  172. package/src/components/ScenarioQueue/ScenarioCard.tsx +120 -0
  173. package/src/components/ScenarioQueue/ScenarioCardDraggable.tsx +41 -0
  174. package/src/components/ScenarioQueue/ScenarioQueue.figma.tsx +37 -0
  175. package/src/components/ScenarioQueue/ScenarioQueue.test.tsx +398 -0
  176. package/src/components/ScenarioQueue/ScenarioQueue.tsx +162 -0
  177. package/src/components/ScenarioQueue/index.ts +11 -0
  178. package/src/components/ScenarioQueue/types.ts +86 -0
  179. package/src/components/ScenarioSettings/ScenarioSettings.figma.tsx +12 -0
  180. package/src/components/ScenarioSettings/ScenarioSettings.test.tsx +406 -0
  181. package/src/components/ScenarioSettings/ScenarioSettings.tsx +386 -0
  182. package/src/components/ScenarioSettings/index.ts +11 -0
  183. package/src/components/ScenarioSettings/types.ts +70 -0
  184. package/src/components/__tests__/Breadcrumb.test.tsx +94 -0
  185. package/src/components/index.ts +54 -1
  186. package/src/figma-codex/README.md +186 -0
  187. package/src/figma-codex/__tests__/config.test.ts +63 -0
  188. package/src/figma-codex/__tests__/generate.test.ts +78 -0
  189. package/src/figma-codex/__tests__/parser.test.ts +138 -0
  190. package/src/figma-codex/__tests__/resolver.test.ts +196 -0
  191. package/src/figma-codex/__tests__/writer.test.ts +111 -0
  192. package/src/figma-codex/config.ts +42 -0
  193. package/src/figma-codex/fixtures/CompoundComponent/CompoundComponent.tsx +17 -0
  194. package/src/figma-codex/fixtures/CompoundComponent/index.ts +1 -0
  195. package/src/figma-codex/fixtures/CompoundComponent.figma.tsx +14 -0
  196. package/src/figma-codex/fixtures/SimpleComponent.figma.tsx +10 -0
  197. package/src/figma-codex/fixtures/SimpleComponent.tsx +10 -0
  198. package/src/figma-codex/fixtures/expected-output.json +78 -0
  199. package/src/figma-codex/generate.ts +106 -0
  200. package/src/figma-codex/parser.ts +138 -0
  201. package/src/figma-codex/resolver.ts +280 -0
  202. package/src/figma-codex/schema.ts +79 -0
  203. package/src/figma-codex/writer.ts +54 -0
  204. package/src/preset/index.ts +15 -0
  205. package/src/preset/recipes/accordion.ts +8 -5
  206. package/src/preset/recipes/avatar.ts +1 -2
  207. package/src/preset/recipes/breadcrumb.ts +109 -0
  208. package/src/preset/recipes/checkbox.ts +1 -2
  209. package/src/preset/recipes/content-card.ts +124 -0
  210. package/src/preset/recipes/field.ts +1 -2
  211. package/src/preset/recipes/index.ts +11 -0
  212. package/src/preset/recipes/navigation-menu.ts +97 -0
  213. package/src/preset/recipes/progress.ts +1 -2
  214. package/src/preset/recipes/radio-group.ts +1 -2
  215. package/src/preset/recipes/scenario-card.ts +151 -0
  216. package/src/preset/recipes/scenario-queue.ts +99 -0
  217. package/src/preset/recipes/scenario-settings.ts +182 -0
  218. package/src/preset/recipes/steps.ts +1 -2
  219. package/src/preset/recipes/toast.ts +1 -2
  220. package/src/preset/recipes/tooltip.ts +1 -2
  221. package/src/preset/semantic-tokens.ts +4 -0
  222. package/src/test/setup.ts +15 -0
  223. package/dist/chunk-F7LHARS4.js +0 -869
  224. package/dist/chunk-F7LHARS4.js.map +0 -1
  225. package/dist/chunk-M7J7WKJY.js.map +0 -1
  226. package/dist/chunk-QC44JPCA.cjs.map +0 -1
  227. package/dist/chunk-QP4EJI3G.cjs +0 -902
  228. package/dist/chunk-QP4EJI3G.cjs.map +0 -1
  229. package/dist/components/Heading.d.ts.map +0 -1
@@ -0,0 +1,137 @@
1
+ 'use client'
2
+ import type { ReactNode } from 'react'
3
+ import { css } from 'styled-system/css'
4
+ import * as Dialog from '../Dialog'
5
+
6
+ interface AddScenarioDialogProps {
7
+ open: boolean
8
+ onClose: () => void
9
+ /** Render prop slot — consumer injects their scenario collection here. */
10
+ renderContent?: (props: { onClose: () => void }) => ReactNode
11
+ /** Called when user clicks "Browse More Scenarios" in the footer */
12
+ onBrowseMore?: () => void
13
+ /** Called when user clicks "Build Custom Scenario" in the footer */
14
+ onBuildCustom?: () => void
15
+ }
16
+
17
+ const dialogContentClass = css({
18
+ width: 'full',
19
+ maxWidth: '560px',
20
+ maxHeight: '80vh',
21
+ display: 'flex',
22
+ flexDirection: 'column',
23
+ })
24
+
25
+ const dialogBodyClass = css({
26
+ flex: '1',
27
+ overflowY: 'auto',
28
+ py: '0',
29
+ px: '6',
30
+ })
31
+
32
+ const footerLinkClass = css({
33
+ display: 'inline-flex',
34
+ alignItems: 'center',
35
+ gap: '1',
36
+ fontSize: 'sm',
37
+ color: 'primary.solid.bg',
38
+ fontWeight: 'medium',
39
+ textDecoration: 'none',
40
+ cursor: 'pointer',
41
+ bg: 'transparent',
42
+ border: 'none',
43
+ p: '0',
44
+ _hover: { textDecoration: 'underline' },
45
+ _focusVisible: { focusVisibleRing: 'outside' },
46
+ })
47
+
48
+ export function AddScenarioDialog({
49
+ open,
50
+ onClose,
51
+ renderContent,
52
+ onBrowseMore,
53
+ onBuildCustom,
54
+ }: AddScenarioDialogProps) {
55
+ return (
56
+ <Dialog.Root open={open} onOpenChange={({ open: isOpen }) => !isOpen && onClose()}>
57
+ <Dialog.Backdrop />
58
+ <Dialog.Positioner>
59
+ <Dialog.Content className={dialogContentClass}>
60
+ <Dialog.Header>
61
+ <Dialog.Title>Add Scenario</Dialog.Title>
62
+ <Dialog.CloseTrigger asChild>
63
+ <button
64
+ aria-label="Close"
65
+ className={css({
66
+ display: 'flex',
67
+ alignItems: 'center',
68
+ justifyContent: 'center',
69
+ borderRadius: 'l1',
70
+ w: '6',
71
+ h: '6',
72
+ color: 'fg.muted',
73
+ bg: 'transparent',
74
+ border: 'none',
75
+ cursor: 'pointer',
76
+ fontSize: 'lg',
77
+ _hover: { bg: 'neutral.subtle.bg', color: 'fg.default' },
78
+ })}
79
+ >
80
+
81
+ </button>
82
+ </Dialog.CloseTrigger>
83
+ </Dialog.Header>
84
+
85
+ {/* Scrollable body — consumer owns this content */}
86
+ <Dialog.Body className={dialogBodyClass}>
87
+ {renderContent ? (
88
+ renderContent({ onClose })
89
+ ) : (
90
+ // Storybook placeholder
91
+ <div
92
+ className={css({
93
+ display: 'flex',
94
+ alignItems: 'center',
95
+ justifyContent: 'center',
96
+ minH: '48',
97
+ borderRadius: 'l2',
98
+ bg: 'neutral.subtle.bg',
99
+ color: 'fg.muted',
100
+ fontSize: 'sm',
101
+ borderWidth: '1px',
102
+ borderStyle: 'dashed',
103
+ borderColor: 'border.default',
104
+ })}
105
+ >
106
+ Scenario collection renders here
107
+ </div>
108
+ )}
109
+ </Dialog.Body>
110
+
111
+ <Dialog.Footer>
112
+ <button
113
+ type="button"
114
+ className={footerLinkClass}
115
+ onClick={() => {
116
+ onBrowseMore?.()
117
+ onClose()
118
+ }}
119
+ >
120
+ Browse More Scenarios →
121
+ </button>
122
+ <button
123
+ type="button"
124
+ className={footerLinkClass}
125
+ onClick={() => {
126
+ onBuildCustom?.()
127
+ onClose()
128
+ }}
129
+ >
130
+ Build Custom Scenario →
131
+ </button>
132
+ </Dialog.Footer>
133
+ </Dialog.Content>
134
+ </Dialog.Positioner>
135
+ </Dialog.Root>
136
+ )
137
+ }
@@ -0,0 +1,120 @@
1
+ 'use client'
2
+ import { type ComponentProps, forwardRef } from 'react'
3
+ import { Box, Circle, HStack, VStack } from 'styled-system/jsx'
4
+ import { scenarioCard } from 'styled-system/recipes'
5
+ import * as Card from '../Card'
6
+ import { ClockIcon } from '../Icons/ClockIcon'
7
+ import { GripDotsVerticalIcon } from '../Icons/GripDotsVerticalIcon'
8
+ import * as Switch from '../Switch'
9
+ import {
10
+ type ScenarioCardProps,
11
+ difficultyLabel,
12
+ } from './types'
13
+
14
+ export interface ScenarioCardElementProps
15
+ extends ScenarioCardProps,
16
+ Omit<ComponentProps<'div'>, 'children'> {
17
+ /** Callback ref for the root element (used by ScenarioCardDraggable) */
18
+ rootRef?: (el: HTMLDivElement | null) => void
19
+ /** Callback ref for the drag handle (used by ScenarioCardDraggable) */
20
+ handleRef?: (el: HTMLDivElement | null) => void
21
+ }
22
+
23
+ export const ScenarioCard = forwardRef<HTMLDivElement, ScenarioCardElementProps>(
24
+ function ScenarioCard(
25
+ {
26
+ scenario,
27
+ position,
28
+ isActive,
29
+ showRequeueSwitch = false,
30
+ onRequeue,
31
+ isRepeat = false,
32
+ isDragging = false,
33
+ rootRef,
34
+ handleRef,
35
+ className: _className,
36
+ ...rest
37
+ },
38
+ _ref,
39
+ ) {
40
+ const styles = scenarioCard({ isActive, isDragging })
41
+
42
+ return (
43
+ <Card.Root
44
+ ref={rootRef}
45
+ className={styles.root}
46
+ variant="elevated"
47
+ css={{
48
+ boxShadow: '0px 2px 8px 0px rgba(167, 139, 250, 0.15)',
49
+ // neutral.surface.bg resolves to white in light mode; Figma uses neutral/99 (#FDFCF5)
50
+ bg: 'neutral.1',
51
+ }}
52
+ {...rest}
53
+ >
54
+ <VStack gap="2.5" pl="5" pr="3" py="2.5" alignItems="flex-start">
55
+ {/* Top row: drag handle (left) + position badge (right) — queue tab only */}
56
+ {!showRequeueSwitch && (
57
+ <HStack justify="space-between" alignItems="flex-start" w="full" py="2" pr="2.5">
58
+ <Box
59
+ ref={handleRef}
60
+ className={styles.dragHandle}
61
+ aria-label="Drag to reorder"
62
+ >
63
+ <GripDotsVerticalIcon w="9" h="10" aria-hidden="true" />
64
+ </Box>
65
+ <Circle
66
+ size={isActive ? "12" : "11"}
67
+ className={styles.positionBadge}
68
+ aria-label={`Position ${position}`}
69
+ >
70
+ {position}
71
+ </Circle>
72
+ </HStack>
73
+ )}
74
+
75
+ {/* Title */}
76
+ <Box px="1" py="1.5" w="full">
77
+ <p className={styles.title}>{scenario.title}</p>
78
+ </Box>
79
+
80
+ {/* Badge column: difficulty stacked above duration, matching Figma flex-col layout */}
81
+ <VStack gap="3" alignItems="flex-start" py="2.5">
82
+ <Box
83
+ className={styles.difficultyBadge}
84
+ data-difficulty={scenario.difficulty}
85
+ >
86
+ {difficultyLabel[scenario.difficulty]}
87
+ </Box>
88
+
89
+ <Box className={styles.durationBadge} data-difficulty={scenario.difficulty}>
90
+ <ClockIcon w="3" h="3" aria-hidden="true" />
91
+ {scenario.duration}
92
+ </Box>
93
+
94
+ {isRepeat && (
95
+ <Box className={styles.durationBadge} data-difficulty={scenario.difficulty}>Repeat</Box>
96
+ )}
97
+ </VStack>
98
+
99
+ {/* Re-queue switch row (completed tab only) */}
100
+ {showRequeueSwitch && (
101
+ <HStack className={styles.switchRow} justify="space-between">
102
+ <span className={styles.switchLabel}>Re-queue</span>
103
+ <Switch.Root
104
+ size="sm"
105
+ defaultChecked
106
+ onCheckedChange={(details) => {
107
+ if (!details.checked) onRequeue?.(scenario.id)
108
+ }}
109
+ aria-label={`Re-queue ${scenario.title}`}
110
+ >
111
+ <Switch.HiddenInput />
112
+ <Switch.Control css={{ _checked: { bg: 'secondary.6' } }} />
113
+ </Switch.Root>
114
+ </HStack>
115
+ )}
116
+ </VStack>
117
+ </Card.Root>
118
+ )
119
+ },
120
+ )
@@ -0,0 +1,41 @@
1
+ 'use client'
2
+ import { useSortable } from '@dnd-kit/react/sortable'
3
+ import { ScenarioCard } from './ScenarioCard'
4
+ import type { Scenario } from './types'
5
+
6
+ interface ScenarioCardDraggableProps {
7
+ scenario: Scenario
8
+ /** 0-based index in the current list (required by useSortable) */
9
+ index: number
10
+ /** 1-based display position shown in the position badge */
11
+ position: number
12
+ /** Whether this is the active (first) card */
13
+ isActive: boolean
14
+ /** Whether this card was previously completed and re-queued */
15
+ isRepeat?: boolean
16
+ }
17
+
18
+ export function ScenarioCardDraggable({
19
+ scenario,
20
+ index,
21
+ position,
22
+ isActive,
23
+ isRepeat,
24
+ }: ScenarioCardDraggableProps) {
25
+ const { ref, handleRef, isDragging } = useSortable({
26
+ id: scenario.id,
27
+ index,
28
+ })
29
+
30
+ return (
31
+ <ScenarioCard
32
+ scenario={scenario}
33
+ position={position}
34
+ isActive={isActive}
35
+ isDragging={isDragging}
36
+ isRepeat={isRepeat}
37
+ rootRef={ref}
38
+ handleRef={handleRef}
39
+ />
40
+ )
41
+ }
@@ -0,0 +1,37 @@
1
+ import figma from '@figma/code-connect';
2
+ import { ScenarioQueue } from './ScenarioQueue';
3
+
4
+ const scenarios = [
5
+ {
6
+ id: '1',
7
+ title: 'UX Research & Design Interview',
8
+ category: 'UX Design',
9
+ difficulty: 'beginner' as const,
10
+ duration: '10-15 min',
11
+ status: 'queued' as const,
12
+ },
13
+ {
14
+ id: '2',
15
+ title: 'Business Analysis ROI Design Presentation',
16
+ category: 'Business',
17
+ difficulty: 'intermediate' as const,
18
+ duration: '15-25 min',
19
+ status: 'queued' as const,
20
+ },
21
+ {
22
+ id: '3',
23
+ title: 'Product Redesign Challenge',
24
+ category: 'Product',
25
+ difficulty: 'advanced' as const,
26
+ duration: '25-35 min',
27
+ status: 'queued' as const,
28
+ },
29
+ ];
30
+
31
+ figma.connect(
32
+ ScenarioQueue,
33
+ 'https://www.figma.com/design/GaHmFfmvO4loUzuZS4TgEz/Discourser.AI--V1?node-id=478-5757',
34
+ {
35
+ example: () => <ScenarioQueue scenarios={scenarios} />,
36
+ },
37
+ );