@adres/mgda-ui 0.0.0-stage → 0.0.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.
Files changed (325) hide show
  1. package/brand-knowledge.json +451 -0
  2. package/knowledge/accordion.md +135 -0
  3. package/knowledge/activity-rings.md +123 -0
  4. package/knowledge/alert.md +184 -0
  5. package/knowledge/answer-actions.md +217 -0
  6. package/knowledge/aspect-ratio.md +82 -0
  7. package/knowledge/avatar.md +158 -0
  8. package/knowledge/badge.md +172 -0
  9. package/knowledge/bar-graph.md +167 -0
  10. package/knowledge/bento-grid.md +115 -0
  11. package/knowledge/blockquote.md +153 -0
  12. package/knowledge/box-list.md +177 -0
  13. package/knowledge/bullet-list.md +128 -0
  14. package/knowledge/button-group.md +179 -0
  15. package/knowledge/button.md +231 -0
  16. package/knowledge/calendar.md +168 -0
  17. package/knowledge/card.md +321 -0
  18. package/knowledge/cards-nav.md +170 -0
  19. package/knowledge/chain-of-thought.md +164 -0
  20. package/knowledge/chat-container.md +135 -0
  21. package/knowledge/chat-message.md +224 -0
  22. package/knowledge/checkbox-card.md +172 -0
  23. package/knowledge/checkbox.md +111 -0
  24. package/knowledge/citations.md +241 -0
  25. package/knowledge/combobox.md +265 -0
  26. package/knowledge/countdown-pill.md +153 -0
  27. package/knowledge/cta.md +118 -0
  28. package/knowledge/data-list.md +173 -0
  29. package/knowledge/data-table.md +220 -0
  30. package/knowledge/dialog.md +249 -0
  31. package/knowledge/drawer.md +236 -0
  32. package/knowledge/dropdown-menu.md +238 -0
  33. package/knowledge/dropzone.md +153 -0
  34. package/knowledge/email-chips-input.md +161 -0
  35. package/knowledge/empty-state.md +106 -0
  36. package/knowledge/entity-header.md +166 -0
  37. package/knowledge/feature-grid.md +120 -0
  38. package/knowledge/feedback-bar.md +127 -0
  39. package/knowledge/footer.md +116 -0
  40. package/knowledge/heading.md +189 -0
  41. package/knowledge/hero.md +361 -0
  42. package/knowledge/input-button.md +187 -0
  43. package/knowledge/input-group.md +185 -0
  44. package/knowledge/input.md +256 -0
  45. package/knowledge/inset.md +177 -0
  46. package/knowledge/kpi-card.md +206 -0
  47. package/knowledge/list-nav.md +181 -0
  48. package/knowledge/logo-cloud.md +102 -0
  49. package/knowledge/media-gallery.md +158 -0
  50. package/knowledge/message-actions.md +175 -0
  51. package/knowledge/nav-sidebar.md +225 -0
  52. package/knowledge/number-stepper.md +159 -0
  53. package/knowledge/page-header.md +109 -0
  54. package/knowledge/pagination.md +225 -0
  55. package/knowledge/popover.md +159 -0
  56. package/knowledge/pricing.md +132 -0
  57. package/knowledge/progress.md +156 -0
  58. package/knowledge/prompt-input.md +337 -0
  59. package/knowledge/prompt-suggestions.md +168 -0
  60. package/knowledge/quota-bar.md +160 -0
  61. package/knowledge/quote.md +116 -0
  62. package/knowledge/radio-card.md +172 -0
  63. package/knowledge/radio-group.md +135 -0
  64. package/knowledge/reasoning.md +142 -0
  65. package/knowledge/search.md +131 -0
  66. package/knowledge/section-nav.md +162 -0
  67. package/knowledge/segmented-control.md +181 -0
  68. package/knowledge/select-button.md +205 -0
  69. package/knowledge/select.md +210 -0
  70. package/knowledge/separator.md +75 -0
  71. package/knowledge/shimmer-text.md +140 -0
  72. package/knowledge/sidebar.md +227 -0
  73. package/knowledge/skeleton.md +142 -0
  74. package/knowledge/slider.md +133 -0
  75. package/knowledge/slideshow.md +159 -0
  76. package/knowledge/source.md +156 -0
  77. package/knowledge/spinner.md +120 -0
  78. package/knowledge/stat-strip.md +128 -0
  79. package/knowledge/stats.md +117 -0
  80. package/knowledge/step-indicator.md +157 -0
  81. package/knowledge/switch.md +88 -0
  82. package/knowledge/table.md +190 -0
  83. package/knowledge/tabs.md +169 -0
  84. package/knowledge/testimonials.md +115 -0
  85. package/knowledge/text-link.md +192 -0
  86. package/knowledge/text.md +194 -0
  87. package/knowledge/thinking-bar.md +115 -0
  88. package/knowledge/thinking-steps.md +140 -0
  89. package/knowledge/toaster.md +127 -0
  90. package/knowledge/toggle.md +113 -0
  91. package/knowledge/tool-call-card.md +241 -0
  92. package/knowledge/tooltip.md +120 -0
  93. package/knowledge/top-nav.md +138 -0
  94. package/knowledge.json +19854 -0
  95. package/package.json +94 -4
  96. package/src/components/accordion.stories.tsx +46 -0
  97. package/src/components/accordion.tsx +74 -0
  98. package/src/components/activity-rings.stories.tsx +73 -0
  99. package/src/components/activity-rings.tsx +121 -0
  100. package/src/components/alert.stories.tsx +43 -0
  101. package/src/components/alert.tsx +132 -0
  102. package/src/components/answer-actions.stories.tsx +54 -0
  103. package/src/components/answer-actions.test.tsx +37 -0
  104. package/src/components/answer-actions.tsx +313 -0
  105. package/src/components/aspect-ratio.stories.tsx +32 -0
  106. package/src/components/aspect-ratio.tsx +5 -0
  107. package/src/components/avatar.stories.tsx +40 -0
  108. package/src/components/avatar.tsx +154 -0
  109. package/src/components/badge.stories.tsx +27 -0
  110. package/src/components/badge.tsx +63 -0
  111. package/src/components/bar-graph.stories.tsx +28 -0
  112. package/src/components/bar-graph.tsx +204 -0
  113. package/src/components/bento-grid.stories.tsx +23 -0
  114. package/src/components/bento-grid.tsx +67 -0
  115. package/src/components/blockquote.stories.tsx +28 -0
  116. package/src/components/blockquote.tsx +88 -0
  117. package/src/components/box-list.stories.tsx +25 -0
  118. package/src/components/box-list.tsx +108 -0
  119. package/src/components/bullet-list.stories.tsx +22 -0
  120. package/src/components/bullet-list.tsx +101 -0
  121. package/src/components/button-group.stories.tsx +31 -0
  122. package/src/components/button-group.tsx +156 -0
  123. package/src/components/button.stories.tsx +66 -0
  124. package/src/components/button.test.ts +17 -0
  125. package/src/components/button.tsx +139 -0
  126. package/src/components/calendar.stories.tsx +25 -0
  127. package/src/components/calendar.tsx +367 -0
  128. package/src/components/card.stories.tsx +44 -0
  129. package/src/components/card.tsx +392 -0
  130. package/src/components/cards-nav.stories.tsx +35 -0
  131. package/src/components/cards-nav.tsx +115 -0
  132. package/src/components/chain-of-thought.stories.tsx +67 -0
  133. package/src/components/chain-of-thought.test.tsx +50 -0
  134. package/src/components/chain-of-thought.tsx +170 -0
  135. package/src/components/chat-container.stories.tsx +47 -0
  136. package/src/components/chat-container.test.tsx +49 -0
  137. package/src/components/chat-container.tsx +222 -0
  138. package/src/components/chat-message.stories.tsx +52 -0
  139. package/src/components/chat-message.test.tsx +36 -0
  140. package/src/components/chat-message.tsx +163 -0
  141. package/src/components/checkbox-card.stories.tsx +27 -0
  142. package/src/components/checkbox-card.tsx +200 -0
  143. package/src/components/checkbox.stories.tsx +26 -0
  144. package/src/components/checkbox.tsx +61 -0
  145. package/src/components/citations.stories.tsx +64 -0
  146. package/src/components/citations.test.tsx +61 -0
  147. package/src/components/citations.tsx +220 -0
  148. package/src/components/combobox.stories.tsx +184 -0
  149. package/src/components/combobox.test.tsx +82 -0
  150. package/src/components/combobox.tsx +407 -0
  151. package/src/components/countdown-pill.stories.tsx +24 -0
  152. package/src/components/countdown-pill.tsx +129 -0
  153. package/src/components/cta.stories.tsx +29 -0
  154. package/src/components/cta.tsx +52 -0
  155. package/src/components/data-list.stories.tsx +50 -0
  156. package/src/components/data-list.test.tsx +35 -0
  157. package/src/components/data-list.tsx +181 -0
  158. package/src/components/data-table.stories.tsx +29 -0
  159. package/src/components/data-table.tsx +200 -0
  160. package/src/components/dialog.stories.tsx +42 -0
  161. package/src/components/dialog.tsx +200 -0
  162. package/src/components/drawer.stories.tsx +48 -0
  163. package/src/components/drawer.tsx +385 -0
  164. package/src/components/dropdown-menu.stories.tsx +41 -0
  165. package/src/components/dropdown-menu.tsx +252 -0
  166. package/src/components/dropzone.stories.tsx +19 -0
  167. package/src/components/dropzone.tsx +250 -0
  168. package/src/components/email-chips-input.stories.tsx +135 -0
  169. package/src/components/email-chips-input.tsx +210 -0
  170. package/src/components/empty-state.stories.tsx +22 -0
  171. package/src/components/empty-state.tsx +35 -0
  172. package/src/components/entity-header.stories.tsx +43 -0
  173. package/src/components/entity-header.test.tsx +35 -0
  174. package/src/components/entity-header.tsx +92 -0
  175. package/src/components/feature-grid.stories.tsx +25 -0
  176. package/src/components/feature-grid.tsx +87 -0
  177. package/src/components/feedback-bar.stories.tsx +25 -0
  178. package/src/components/feedback-bar.test.tsx +24 -0
  179. package/src/components/feedback-bar.tsx +62 -0
  180. package/src/components/footer.stories.tsx +23 -0
  181. package/src/components/footer.tsx +78 -0
  182. package/src/components/heading.stories.tsx +45 -0
  183. package/src/components/heading.test.tsx +22 -0
  184. package/src/components/heading.tsx +77 -0
  185. package/src/components/hero.stories.tsx +38 -0
  186. package/src/components/hero.tsx +498 -0
  187. package/src/components/input-button.stories.tsx +19 -0
  188. package/src/components/input-button.tsx +112 -0
  189. package/src/components/input-group.stories.tsx +38 -0
  190. package/src/components/input-group.tsx +157 -0
  191. package/src/components/input.stories.tsx +31 -0
  192. package/src/components/input.tsx +284 -0
  193. package/src/components/inset.stories.tsx +29 -0
  194. package/src/components/inset.tsx +70 -0
  195. package/src/components/kpi-card.stories.tsx +29 -0
  196. package/src/components/kpi-card.tsx +284 -0
  197. package/src/components/list-nav.stories.tsx +22 -0
  198. package/src/components/list-nav.tsx +145 -0
  199. package/src/components/logo-cloud.stories.tsx +23 -0
  200. package/src/components/logo-cloud.tsx +42 -0
  201. package/src/components/media-gallery.stories.tsx +25 -0
  202. package/src/components/media-gallery.tsx +347 -0
  203. package/src/components/message-actions.stories.tsx +45 -0
  204. package/src/components/message-actions.test.tsx +32 -0
  205. package/src/components/message-actions.tsx +119 -0
  206. package/src/components/nav-sidebar.stories.tsx +58 -0
  207. package/src/components/nav-sidebar.test.tsx +54 -0
  208. package/src/components/nav-sidebar.tsx +462 -0
  209. package/src/components/number-stepper.stories.tsx +19 -0
  210. package/src/components/number-stepper.tsx +158 -0
  211. package/src/components/page-header.stories.tsx +25 -0
  212. package/src/components/page-header.tsx +64 -0
  213. package/src/components/pagination.stories.tsx +110 -0
  214. package/src/components/pagination.test.tsx +46 -0
  215. package/src/components/pagination.tsx +144 -0
  216. package/src/components/popover.stories.tsx +26 -0
  217. package/src/components/popover.tsx +62 -0
  218. package/src/components/pricing.stories.tsx +42 -0
  219. package/src/components/pricing.tsx +130 -0
  220. package/src/components/progress.stories.tsx +22 -0
  221. package/src/components/progress.tsx +189 -0
  222. package/src/components/prompt-input.stories.tsx +62 -0
  223. package/src/components/prompt-input.test.tsx +106 -0
  224. package/src/components/prompt-input.tsx +343 -0
  225. package/src/components/prompt-suggestions.stories.tsx +53 -0
  226. package/src/components/prompt-suggestions.test.tsx +37 -0
  227. package/src/components/prompt-suggestions.tsx +122 -0
  228. package/src/components/quota-bar.stories.tsx +19 -0
  229. package/src/components/quota-bar.tsx +191 -0
  230. package/src/components/quote.stories.tsx +18 -0
  231. package/src/components/quote.tsx +43 -0
  232. package/src/components/radio-card.stories.tsx +27 -0
  233. package/src/components/radio-card.tsx +225 -0
  234. package/src/components/radio-group.stories.tsx +32 -0
  235. package/src/components/radio-group.tsx +68 -0
  236. package/src/components/reasoning.stories.tsx +50 -0
  237. package/src/components/reasoning.test.tsx +48 -0
  238. package/src/components/reasoning.tsx +143 -0
  239. package/src/components/search.stories.tsx +18 -0
  240. package/src/components/search.tsx +133 -0
  241. package/src/components/section-nav.stories.tsx +59 -0
  242. package/src/components/section-nav.test.tsx +36 -0
  243. package/src/components/section-nav.tsx +146 -0
  244. package/src/components/segmented-control.stories.tsx +22 -0
  245. package/src/components/segmented-control.tsx +301 -0
  246. package/src/components/select-button.stories.tsx +27 -0
  247. package/src/components/select-button.tsx +174 -0
  248. package/src/components/select.stories.tsx +27 -0
  249. package/src/components/select.tsx +198 -0
  250. package/src/components/separator.stories.tsx +22 -0
  251. package/src/components/separator.tsx +23 -0
  252. package/src/components/shimmer-text.stories.tsx +23 -0
  253. package/src/components/shimmer-text.test.tsx +35 -0
  254. package/src/components/shimmer-text.tsx +43 -0
  255. package/src/components/sidebar.stories.tsx +25 -0
  256. package/src/components/sidebar.tsx +234 -0
  257. package/src/components/skeleton.stories.tsx +22 -0
  258. package/src/components/skeleton.tsx +96 -0
  259. package/src/components/slider.stories.tsx +20 -0
  260. package/src/components/slider.tsx +176 -0
  261. package/src/components/slideshow.stories.tsx +30 -0
  262. package/src/components/slideshow.tsx +291 -0
  263. package/src/components/source.stories.tsx +32 -0
  264. package/src/components/source.test.tsx +40 -0
  265. package/src/components/source.tsx +161 -0
  266. package/src/components/spinner.stories.tsx +19 -0
  267. package/src/components/spinner.tsx +76 -0
  268. package/src/components/stat-strip.stories.tsx +36 -0
  269. package/src/components/stat-strip.test.tsx +25 -0
  270. package/src/components/stat-strip.tsx +85 -0
  271. package/src/components/stats.stories.tsx +24 -0
  272. package/src/components/stats.tsx +83 -0
  273. package/src/components/step-indicator.stories.tsx +18 -0
  274. package/src/components/step-indicator.test.tsx +18 -0
  275. package/src/components/step-indicator.tsx +286 -0
  276. package/src/components/switch.stories.tsx +26 -0
  277. package/src/components/switch.tsx +32 -0
  278. package/src/components/table.stories.tsx +38 -0
  279. package/src/components/table.tsx +220 -0
  280. package/src/components/tabs.stories.tsx +25 -0
  281. package/src/components/tabs.tsx +276 -0
  282. package/src/components/testimonials.stories.tsx +22 -0
  283. package/src/components/testimonials.tsx +109 -0
  284. package/src/components/text-link.stories.tsx +47 -0
  285. package/src/components/text-link.test.tsx +18 -0
  286. package/src/components/text-link.tsx +88 -0
  287. package/src/components/text.stories.tsx +49 -0
  288. package/src/components/text.tsx +105 -0
  289. package/src/components/thinking-bar.stories.tsx +19 -0
  290. package/src/components/thinking-bar.test.tsx +27 -0
  291. package/src/components/thinking-bar.tsx +64 -0
  292. package/src/components/thinking-steps.stories.tsx +44 -0
  293. package/src/components/thinking-steps.test.tsx +42 -0
  294. package/src/components/thinking-steps.tsx +92 -0
  295. package/src/components/toaster.stories.tsx +80 -0
  296. package/src/components/toaster.tsx +36 -0
  297. package/src/components/toggle.stories.tsx +21 -0
  298. package/src/components/toggle.tsx +103 -0
  299. package/src/components/tool-call-card.stories.tsx +97 -0
  300. package/src/components/tool-call-card.test.tsx +88 -0
  301. package/src/components/tool-call-card.tsx +231 -0
  302. package/src/components/tooltip.stories.tsx +25 -0
  303. package/src/components/tooltip.tsx +43 -0
  304. package/src/components/top-nav.stories.tsx +20 -0
  305. package/src/components/top-nav.tsx +76 -0
  306. package/src/docs/Colors.stories.tsx +192 -0
  307. package/src/docs/GettingStarted.mdx +72 -0
  308. package/src/docs/Mcp.mdx +52 -0
  309. package/src/docs/Typography.stories.tsx +114 -0
  310. package/src/hooks/use-in-view.ts +32 -0
  311. package/src/hooks/use-reduced-motion.ts +26 -0
  312. package/src/index.ts +343 -0
  313. package/src/lib/cn.test.ts +67 -0
  314. package/src/lib/cn.ts +81 -0
  315. package/src/lib/motion.ts +109 -0
  316. package/src/lib/prefix-utilities.test.ts +56 -0
  317. package/src/lib/prefix-utilities.ts +50 -0
  318. package/src/styles/base.css +489 -0
  319. package/src/styles/motion.css +69 -0
  320. package/src/styles/overrides.css +44 -0
  321. package/src/styles/typography.css +173 -0
  322. package/src/theme/theme.css +391 -0
  323. package/src/theme/tokens.ts +29 -0
  324. package/src/theme/types.ts +26 -0
  325. package/README.md +0 -3
@@ -0,0 +1,241 @@
1
+ ---
2
+ # >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
3
+ derived:
4
+ schemaVersion: 1
5
+ id: citations
6
+ sourceFile: packages/design-system/src/components/citations.tsx
7
+ client: true
8
+ category: web-app-ai
9
+ categoryFromBarrel: web-app-ai
10
+ barrelExported: true
11
+ importPath: "@adres/mgda-ui"
12
+ exports:
13
+ - name: CitationMarker
14
+ kind: component
15
+ typeText: "({ source, onShow }: CitationMarkerProps) => Element"
16
+ - name: CitationMarkerProps
17
+ kind: type
18
+ - name: CitationSource
19
+ kind: type
20
+ - name: CitationSourceKind
21
+ kind: type
22
+ - name: formatSourceDate
23
+ kind: function
24
+ typeText: "(iso: string) => string"
25
+ - name: isStale
26
+ kind: function
27
+ typeText: "(date: string, asOf: string, days?: number) => boolean"
28
+ - name: SourceAvatar
29
+ kind: component
30
+ typeText: "({ kind, size }: SourceAvatarProps) => Element"
31
+ - name: SourceAvatarProps
32
+ kind: type
33
+ - name: SourceCard
34
+ kind: component
35
+ typeText: "ForwardRefExoticComponent<SourceCardProps & RefAttributes<HTMLDivElement>>"
36
+ - name: SourceCardProps
37
+ kind: type
38
+ - name: SourceList
39
+ kind: component
40
+ typeText: "ForwardRefExoticComponent<SourceListProps & RefAttributes<HTMLDivElement>>"
41
+ - name: SourceListProps
42
+ kind: type
43
+ - name: UnsupportedClaim
44
+ kind: component
45
+ typeText: "({ children, note }: UnsupportedClaimProps) => Element"
46
+ - name: UnsupportedClaimProps
47
+ kind: type
48
+ primaryExport: CitationMarker
49
+ subcomponents:
50
+ - SourceAvatar
51
+ - SourceCard
52
+ - SourceList
53
+ - UnsupportedClaim
54
+ props:
55
+ CitationMarker:
56
+ - name: onShow
57
+ type: "((id: number) => void)"
58
+ required: false
59
+ declaredIn: self
60
+ doc: "Adds \"Show in sources\" to the preview, e.g. to scroll to and highlight the source in a list."
61
+ - name: source
62
+ type: CitationSource
63
+ required: true
64
+ declaredIn: self
65
+ SourceAvatar:
66
+ - name: kind
67
+ type: CitationSourceKind
68
+ required: false
69
+ declaredIn: self
70
+ - name: size
71
+ type: "\"sm\" | \"xs\""
72
+ required: false
73
+ declaredIn: self
74
+ SourceCard:
75
+ - name: asOf
76
+ type: string
77
+ required: false
78
+ declaredIn: self
79
+ doc: "ISO \"today\" for the age check. Without it, no stale badge. Pass a fixed date to render the same on server and client."
80
+ - name: highlighted
81
+ type: boolean
82
+ required: false
83
+ declaredIn: self
84
+ doc: "Rings the card, e.g. after \"Show in sources\"."
85
+ - name: source
86
+ type: CitationSource
87
+ required: true
88
+ declaredIn: self
89
+ - name: staleAfterDays
90
+ type: number
91
+ required: false
92
+ declaredIn: self
93
+ doc: "Days after which the source is marked old."
94
+ - name: staleLabel
95
+ type: string
96
+ required: false
97
+ declaredIn: self
98
+ SourceList:
99
+ - name: asOf
100
+ type: string
101
+ required: false
102
+ declaredIn: self
103
+ - name: getSourceId
104
+ type: "((id: number) => string)"
105
+ required: false
106
+ declaredIn: self
107
+ doc: "DOM id for each card, so a marker's \"Show in sources\" can scroll to and focus it."
108
+ - name: highlighted
109
+ type: number
110
+ required: false
111
+ declaredIn: self
112
+ doc: "The source id to ring."
113
+ - name: initial
114
+ type: number
115
+ required: false
116
+ declaredIn: self
117
+ doc: "How many show before \"Show N more\". Defaults to all."
118
+ - name: onExpand
119
+ type: "(() => void)"
120
+ required: false
121
+ declaredIn: self
122
+ - name: sources
123
+ type: "CitationSource[]"
124
+ required: true
125
+ declaredIn: self
126
+ UnsupportedClaim:
127
+ - name: children
128
+ type: ReactNode
129
+ required: true
130
+ declaredIn: self
131
+ - name: note
132
+ type: string
133
+ required: false
134
+ declaredIn: self
135
+ doc: "Tooltip explaining the mark."
136
+ extendsProps: []
137
+ variants:
138
+ size:
139
+ kind: enum
140
+ options:
141
+ - sm
142
+ - xs
143
+ default: sm
144
+ on: SourceAvatar
145
+ variantSource: prop-union
146
+ compoundVariants: []
147
+ sizeMaps: []
148
+ dataSlots:
149
+ - source-card
150
+ - source-list
151
+ dependsOn:
152
+ internal:
153
+ - avatar
154
+ - badge
155
+ - button
156
+ - popover
157
+ - text
158
+ - text-link
159
+ - tooltip
160
+ lib:
161
+ - cn
162
+ hooks: []
163
+ external:
164
+ - lucide-react
165
+ - react
166
+ contexts: []
167
+ stories:
168
+ - exportName: Sources
169
+ id: components-citations--sources
170
+ - exportName: Collapsed
171
+ id: components-citations--collapsed
172
+ - exportName: Highlighted
173
+ id: components-citations--highlighted
174
+ - exportName: CitedAnswer
175
+ id: components-citations--cited-answer
176
+ storybookTitle: Components/Citations
177
+ docsId: components-citations--documentation
178
+ argTypeOptions: {}
179
+ resolvedCleanly: true
180
+ contractHash: "0c4ab9435b20"
181
+ factsHash: "2578f26d8544"
182
+ # >>> AUTHORED - humans own everything below this line. <<<
183
+ status: beta
184
+ summary: "Source citations for AI answers: numbered markers in the text that preview the passage used, a mark for claims no source backs, and a numbered source list with age warnings."
185
+ useWhen:
186
+ - "an assistant answer states facts that people should be able to check"
187
+ - "a claim in an answer has no source and should be marked as an estimate"
188
+ - "an answer lists its sources with the exact passage used and how old each is"
189
+ useInstead:
190
+ - id: blockquote
191
+ when: "quoting a passage on its own, not citing it from an answer"
192
+ - id: text-link
193
+ when: "a plain inline link with no preview or numbering"
194
+ related:
195
+ - chat-message
196
+ - popover
197
+ - blockquote
198
+ a11y:
199
+ notes:
200
+ - "Each marker is a button named \"Source N: title\" that opens the preview popover."
201
+ - "The unsupported-claim icon is a real button named \"Not backed by a source\" so keyboard users reach the tooltip."
202
+ - "SourceList is an ordered list labelled \"Sources\"; cards take focus (tabIndex -1) so \"Show in sources\" can move focus to them."
203
+ radixHandles: true
204
+ pitfalls:
205
+ - "Pass a fixed asOf date to SourceCard and SourceList; reading today's date on the server and client renders different badges."
206
+ - "Give getSourceId and focus the card yourself in onShow; the marker only calls back with the id."
207
+ - "Markers and the unsupported mark use tooltips and popovers, so mount a TooltipProvider above them."
208
+ canonicalSnippet: |
209
+ import { CitationMarker, SourceList } from "@adres/mgda-ui"
210
+
211
+ <p>
212
+ Listed at about AED 2,400 per sqft
213
+ <CitationMarker source={sources[0]} onShow={scrollToSource} />.
214
+ </p>
215
+ <SourceList sources={sources} asOf="2026-10-06" getSourceId={(id) => `source-${id}`} />
216
+ reviewedAt: 2026-10-06
217
+ reviewedAgainstContractHash: "0c4ab9435b20"
218
+ ---
219
+
220
+ ## Usage
221
+
222
+ Put a `CitationMarker` after each cited fact in the answer. It is a small
223
+ muted pill with the source kind's icon and number; opening it previews the publisher, date, title and the passage
224
+ used, with "Open" and, when `onShow` is set, "Show in sources". Wrap a claim
225
+ no source backs in `UnsupportedClaim` so it reads as the assistant's
226
+ estimate.
227
+
228
+ Under the answer, `SourceList` numbers the sources as `SourceCard`s with the
229
+ linked title, publisher, kind and date, an "Older than 6 months" badge past
230
+ `staleAfterDays`, and the passage. `initial` and `onExpand` fold long lists
231
+ behind "Show N more". Each source can carry a `kind` (`{ label, icon }`);
232
+ `SourceAvatar` shows that icon, for example stacked in a sources button.
233
+ `isStale` and `formatSourceDate` are exported.
234
+
235
+ ## Anatomy
236
+
237
+ - `CitationMarker` - numbered inline marker with a source preview.
238
+ - `UnsupportedClaim` - dashed warning underline plus an explained warning icon.
239
+ - `SourceCard` - one numbered source with its passage.
240
+ - `SourceList` - ordered list of source cards with "Show N more".
241
+ - `SourceAvatar` - the source kind's icon in a small avatar.
@@ -0,0 +1,265 @@
1
+ ---
2
+ # >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
3
+ derived:
4
+ schemaVersion: 1
5
+ id: combobox
6
+ sourceFile: packages/design-system/src/components/combobox.tsx
7
+ client: true
8
+ category: web-app-core-primitives
9
+ categoryFromBarrel: web-app-core-primitives
10
+ barrelExported: true
11
+ importPath: "@adres/mgda-ui"
12
+ exports:
13
+ - name: Combobox
14
+ kind: component
15
+ typeText: "({ items, value, onValueChange, onSelect, query: queryProp, onQueryChange, filter, startContent, emptyMessage, loading, loadingMessage, maxPerGroup, highlightMatches, placeholder, \"aria-label\": ariaLabel, id, name, size,...[truncated]"
16
+ - name: ComboboxItem
17
+ kind: type
18
+ - name: ComboboxProps
19
+ kind: type
20
+ - name: ComboboxSize
21
+ kind: type
22
+ - name: defaultComboboxFilter
23
+ kind: function
24
+ typeText: "(item: ComboboxItem, query: string) => boolean"
25
+ - name: groupComboboxItems
26
+ kind: function
27
+ typeText: "(items: ComboboxItem[], maxPerGroup?: number) => { name: string | undefined; items: ComboboxItem[]; }[]"
28
+ - name: nextEnabledIndex
29
+ kind: function
30
+ typeText: "(items: ComboboxItem[], from: number, direction: 1 | -1) => number"
31
+ - name: splitComboboxMatch
32
+ kind: function
33
+ typeText: "(text: string, query: string) => { before: string; match: string; after: string; }"
34
+ primaryExport: Combobox
35
+ subcomponents: []
36
+ props:
37
+ Combobox:
38
+ - name: aria-label
39
+ type: string
40
+ required: false
41
+ declaredIn: self
42
+ doc: "Accessible name. Required unless a <Label htmlFor={id}> names the input."
43
+ - name: className
44
+ type: string
45
+ required: false
46
+ declaredIn: self
47
+ - name: disabled
48
+ type: boolean
49
+ required: false
50
+ declaredIn: self
51
+ - name: emptyMessage
52
+ type: "((query: string) => ReactNode) | ReactNode"
53
+ required: false
54
+ declaredIn: self
55
+ doc: "Shown when the query matches nothing. Receives the trimmed query."
56
+ - name: filter
57
+ type: "((item: ComboboxItem, query: string) => boolean)"
58
+ required: false
59
+ declaredIn: self
60
+ doc: "Return true to keep an item. Default: case-insensitive match on label, description and keywords."
61
+ - name: highlightMatches
62
+ type: boolean
63
+ required: false
64
+ declaredIn: self
65
+ doc: "Bold the matched part of each label. Default true."
66
+ - name: id
67
+ type: string
68
+ required: false
69
+ declaredIn: self
70
+ - name: invalid
71
+ type: boolean
72
+ required: false
73
+ declaredIn: self
74
+ - name: items
75
+ type: "ComboboxItem[]"
76
+ required: true
77
+ declaredIn: self
78
+ - name: loading
79
+ type: boolean
80
+ required: false
81
+ declaredIn: self
82
+ doc: "Show a pending row instead of results, e.g. while fetching remote items."
83
+ - name: loadingMessage
84
+ type: ReactNode
85
+ required: false
86
+ declaredIn: self
87
+ - name: maxPerGroup
88
+ type: number
89
+ required: false
90
+ declaredIn: self
91
+ doc: "Cap the rows shown per group (or overall when ungrouped)."
92
+ - name: name
93
+ type: string
94
+ required: false
95
+ declaredIn: self
96
+ - name: onQueryChange
97
+ type: "((query: string) => void)"
98
+ required: false
99
+ declaredIn: self
100
+ - name: onSelect
101
+ type: "((item: ComboboxItem) => void)"
102
+ required: false
103
+ declaredIn: self
104
+ doc: "Called on every pick. Without `value`, the input clears after a pick (search launcher)."
105
+ - name: onValueChange
106
+ type: "((value: string | null) => void)"
107
+ required: false
108
+ declaredIn: self
109
+ - name: placeholder
110
+ type: string
111
+ required: false
112
+ declaredIn: self
113
+ - name: query
114
+ type: string
115
+ required: false
116
+ declaredIn: self
117
+ doc: "Controlled query. Leave unset to let the combobox own it."
118
+ - name: size
119
+ type: InputSize
120
+ required: false
121
+ declaredIn: self
122
+ - name: startContent
123
+ type: ReactNode
124
+ required: false
125
+ declaredIn: self
126
+ doc: "Shown instead of the item list while the query is empty, e.g. recent searches."
127
+ - name: value
128
+ type: string
129
+ required: false
130
+ declaredIn: self
131
+ doc: "Selected item's value. Set it (with onValueChange) for a picker that shows the choice in the input."
132
+ extendsProps: []
133
+ variants:
134
+ size:
135
+ kind: enum
136
+ options:
137
+ - sm
138
+ - md
139
+ - lg
140
+ default: md
141
+ on: Combobox
142
+ variantSource: prop-union
143
+ compoundVariants: []
144
+ sizeMaps:
145
+ - SIZE_TEXT
146
+ dataSlots:
147
+ - combobox
148
+ dependsOn:
149
+ internal:
150
+ - input
151
+ - spinner
152
+ lib:
153
+ - cn
154
+ hooks: []
155
+ external:
156
+ - "@radix-ui/react-popover"
157
+ - lucide-react
158
+ - react
159
+ contexts: []
160
+ stories:
161
+ - exportName: Default
162
+ id: components-combobox--default
163
+ - exportName: WithLabel
164
+ id: components-combobox--with-label
165
+ - exportName: SearchLauncher
166
+ id: components-combobox--search-launcher
167
+ - exportName: Loading
168
+ id: components-combobox--loading
169
+ - exportName: Invalid
170
+ id: components-combobox--invalid
171
+ - exportName: KeyboardSelection
172
+ id: components-combobox--keyboard-selection
173
+ - exportName: SearchSelection
174
+ id: components-combobox--search-selection
175
+ - exportName: RemoteResults
176
+ id: components-combobox--remote-results
177
+ storybookTitle: Components/Combobox
178
+ docsId: components-combobox--documentation
179
+ argTypeOptions: {}
180
+ resolvedCleanly: true
181
+ contractHash: b8d3d12095c6
182
+ factsHash: ec2144723e3f
183
+ # >>> AUTHORED - humans own everything below this line. <<<
184
+ status: beta
185
+ summary: "Text input with a filtered, keyboard-navigable list of options: a picker that keeps the chosen value, or a search launcher that clears after each pick."
186
+ useWhen:
187
+ - "a single choice from a list too long to scan in a Select, e.g. communities, projects or agents"
188
+ - "an app-wide search box that suggests grouped results while typing"
189
+ - "options load from a server as the user types, using query, onQueryChange and loading"
190
+ useInstead:
191
+ - id: select
192
+ when: "there are only a handful of options and typing to filter adds nothing"
193
+ - id: search
194
+ when: "the field filters a list already on the page and needs no suggestions"
195
+ - id: dropdown-menu
196
+ when: "the options are actions to run, not values to choose"
197
+ related:
198
+ - search
199
+ - select
200
+ - popover
201
+ a11y:
202
+ notes:
203
+ - "Implements the WAI-ARIA combobox pattern: role=combobox on the input, aria-expanded, aria-controls on the open listbox, and aria-activedescendant for the highlighted option. Focus never leaves the input."
204
+ - "Give it a name with aria-label, or with a <Label htmlFor={id}> and the id prop. Without either the input is announced only as 'combobox'."
205
+ - "The result count is announced through a polite live region while typing."
206
+ - "The trailing clear button is labelled 'Clear selection' in picker mode and 'Clear search' otherwise, and returns focus to the input."
207
+ - "Mark decorative item icons aria-hidden; the label is the option's accessible name."
208
+ keyboard:
209
+ - "ArrowDown / ArrowUp open the list and move through enabled options, wrapping at the ends; disabled options are skipped."
210
+ - "Home / End jump to the first or last enabled option while the list is open."
211
+ - "Enter picks the highlighted option. Typing highlights the first match, so Enter picks it straight away."
212
+ - "Escape closes the list and keeps the typed text; Tab closes it and moves on."
213
+ radixHandles: false
214
+ pitfalls:
215
+ - "Passing value turns on picker mode: the input shows the selected label and clearing it calls onValueChange(null). Leave value unset (undefined, not null) for a search launcher that clears after each pick."
216
+ - "startContent replaces the item list while the query is empty. Without it, an empty query lists every item, which suits a picker but not a large search index."
217
+ - "The default filter is a substring match on label, description and keywords. Pass filter for fuzzy or server-side matching, and set loading while results are fetched."
218
+ - "The list renders in a portal, so it is not clipped by overflow-hidden parents, but it also does not inherit their styles."
219
+ canonicalSnippet: |
220
+ import { Combobox } from "@adres/mgda-ui"
221
+
222
+ <Combobox
223
+ items={communities}
224
+ value={community}
225
+ onValueChange={setCommunity}
226
+ placeholder="Choose a community"
227
+ aria-label="Community"
228
+ />
229
+ reviewedAt: 2026-10-05
230
+ reviewedAgainstContractHash: b8d3d12095c6
231
+ ---
232
+
233
+ ## Usage
234
+
235
+ `Combobox` is the DS answer whenever typing should narrow a list of options.
236
+ It has two modes, chosen by whether you pass `value`:
237
+
238
+ - **Picker** (`value` + `onValueChange`): the chosen option's label stays in
239
+ the input, the selected option is marked in the list, and clearing the input
240
+ clears the value. Use it in forms in place of a `Select` with many options.
241
+ - **Search launcher** (`onSelect` only): each pick fires `onSelect` and the
242
+ input clears for the next search. Pair it with `startContent` for recent
243
+ searches and `group` on items for sections such as Properties and Agents.
244
+
245
+ Items are plain data. `group` sections them in first-seen order (capped by
246
+ `maxPerGroup`), `description` adds trailing detail such as a price, `icon`
247
+ adds a leading visual, and `keywords` adds hidden match text, for example a
248
+ property's community.
249
+
250
+ ### Remote results
251
+
252
+ ```tsx
253
+ <Combobox
254
+ items={results}
255
+ query={query}
256
+ onQueryChange={setQuery}
257
+ filter={() => true}
258
+ loading={isFetching}
259
+ onSelect={openResult}
260
+ aria-label="Search listings"
261
+ />
262
+ ```
263
+
264
+ Own the `query`, fetch on change, and pass `filter={() => true}` because the
265
+ server has already filtered.
@@ -0,0 +1,153 @@
1
+ ---
2
+ # >>> DERIVED - regenerated by `npm run knowledge:sync`. Do not edit. <<<
3
+ derived:
4
+ schemaVersion: 1
5
+ id: countdown-pill
6
+ sourceFile: packages/design-system/src/components/countdown-pill.tsx
7
+ client: true
8
+ category: web-app-patterns
9
+ categoryFromBarrel: web-app-patterns
10
+ barrelExported: true
11
+ importPath: "@adres/mgda-ui"
12
+ exports:
13
+ - name: CountdownPill
14
+ kind: component
15
+ typeText: "ForwardRefExoticComponent<CountdownPillProps & RefAttributes<HTMLDivElement>>"
16
+ - name: CountdownPillProps
17
+ kind: type
18
+ - name: CountdownSize
19
+ kind: type
20
+ - name: CountdownTone
21
+ kind: type
22
+ - name: getCountdownLabel
23
+ kind: function
24
+ typeText: "(dateIso: string, ongoingLabel: string, now?: number) => string"
25
+ primaryExport: CountdownPill
26
+ subcomponents: []
27
+ props:
28
+ CountdownPill:
29
+ - name: icon
30
+ type: ReactNode
31
+ required: false
32
+ declaredIn: self
33
+ doc: "Optional icon override. Defaults to a Clock glyph. Pass `null` to omit."
34
+ - name: label
35
+ type: string
36
+ required: false
37
+ declaredIn: self
38
+ doc: "Optional context label rendered before the value. e.g. `\"Starts in\"`, `\"Bidding ends in\"`."
39
+ - name: size
40
+ type: CountdownSize
41
+ required: false
42
+ declaredIn: self
43
+ doc: "Visual density."
44
+ - name: tone
45
+ type: CountdownTone
46
+ required: false
47
+ declaredIn: self
48
+ doc: "Visual urgency tier. Drives the value (and icon) color so the consumer can dial attention up or down without changing markup."
49
+ - name: value
50
+ type: string
51
+ required: true
52
+ declaredIn: self
53
+ doc: "The countdown text itself - the bit that gets emphasized. e.g. `\"2h 15m\"`, `\"3 days\"`, `\"Live now\"`."
54
+ extendsProps:
55
+ - "React.HTMLAttributes<HTMLDivElement>"
56
+ variants:
57
+ tone:
58
+ kind: enum
59
+ options:
60
+ - info
61
+ - success
62
+ - warning
63
+ - neutral
64
+ - critical
65
+ default: neutral
66
+ on: CountdownPill
67
+ size:
68
+ kind: enum
69
+ options:
70
+ - sm
71
+ - md
72
+ - lg
73
+ default: md
74
+ on: CountdownPill
75
+ variantSource: prop-union
76
+ compoundVariants: []
77
+ sizeMaps:
78
+ - GAP_CLASS
79
+ - ICON_CLASS
80
+ - LABEL_CLASS
81
+ - TONE_ICON
82
+ - TONE_VALUE
83
+ - VALUE_CLASS
84
+ dataSlots: []
85
+ dependsOn:
86
+ internal: []
87
+ lib:
88
+ - cn
89
+ hooks: []
90
+ external:
91
+ - lucide-react
92
+ - react
93
+ contexts: []
94
+ stories:
95
+ - exportName: Default
96
+ id: components-countdownpill--default
97
+ - exportName: Critical
98
+ id: components-countdownpill--critical
99
+ storybookTitle: Components/CountdownPill
100
+ docsId: components-countdownpill--documentation
101
+ argTypeOptions: {}
102
+ resolvedCleanly: true
103
+ contractHash: "8ad71d408603"
104
+ factsHash: "372ace40c571"
105
+ # >>> AUTHORED - humans own everything below this line. <<<
106
+ status: stable
107
+ summary: "An inline countdown display for time-to-event copy - a muted context label plus a large, tone-colored value, with a matching getCountdownLabel formatter."
108
+ useWhen:
109
+ - "showing time remaining until, or since, an event inline - session starts, deadlines, auction end times"
110
+ - "urgency should visually escalate as the deadline approaches, via tone"
111
+ useInstead:
112
+ - id: step-indicator
113
+ when: "the content is discrete steps in a process, not a countdown to a single point in time"
114
+ related:
115
+ - step-indicator
116
+ tokens:
117
+ - "--foreground"
118
+ - "--muted-foreground"
119
+ - "--primary"
120
+ - "--success-foreground"
121
+ - "--warning-foreground"
122
+ - "--destructive-foreground"
123
+ a11y:
124
+ notes:
125
+ - "Purely presentational text - no live region or ARIA is added, so a countdown that updates in place (e.g. on an interval) does not announce its own changes to screen readers. Wrap it in your own aria-live region if the live update itself needs to be announced, not just visible."
126
+ radixHandles: false
127
+ pitfalls:
128
+ - "CountdownPill is display-only - it does not tick down on its own or manage any timer. value is a static string recomputed and re-rendered by the caller, typically alongside getCountdownLabel on an interval."
129
+ - "tone is never inferred from the value or from time remaining - the component has no concept of how urgent a given duration is. Pick the tone in the consumer based on your own thresholds, and update it alongside value."
130
+ - "getCountdownLabel deliberately does not return a tone - it only formats the string (\"2h 15m\", \"3 days\", or your ongoingLabel). It will not also tell you how urgent that duration is."
131
+ canonicalSnippet: |
132
+ import { CountdownPill } from "@adres/mgda-ui"
133
+
134
+ <CountdownPill label="Starts in" value="2h 15m" tone="warning" />
135
+ reviewedAt: 2026-09-01
136
+ reviewedAgainstContractHash: "8ad71d408603"
137
+ ---
138
+
139
+ ## Usage
140
+
141
+ `CountdownPill` is for inline time-to-event copy - a session starting soon,
142
+ a bidding deadline, a limited-time offer. It pairs a muted context `label`
143
+ ("Starts in") with a large, `tone`-colored `value` ("2h 15m") that raises
144
+ attention as urgency increases. Reach for `StepIndicator` instead when the
145
+ content is discrete steps in a process, not a countdown to one point in
146
+ time.
147
+
148
+ The component is presentational only - it has no timer of its own. Compute
149
+ `value` yourself - the paired `getCountdownLabel(dateIso, ongoingLabel)`
150
+ helper formats an ISO timestamp into `"2h 15m"`/`"3 days"`/your ongoing
151
+ label - and re-render on whatever interval you choose. `tone` is likewise
152
+ never inferred; pick it from your own urgency thresholds and update it
153
+ alongside `value`.