@mich8060/unified-design-system 0.1.10

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 (454) hide show
  1. package/LICENSE +21 -0
  2. package/README.lib.md +103 -0
  3. package/README.md +265 -0
  4. package/dist/LICENSE +21 -0
  5. package/dist/README.md +103 -0
  6. package/dist/package.json +49 -0
  7. package/dist/styles.css +20544 -0
  8. package/dist/uds-components.es.js +67031 -0
  9. package/dist/uds-components.es.js.map +1 -0
  10. package/dist/uds-components.umd.js +67048 -0
  11. package/dist/uds-components.umd.js.map +1 -0
  12. package/package.json +158 -0
  13. package/src/styles/_typography.scss +932 -0
  14. package/src/styles/_utilities.scss +3738 -0
  15. package/src/styles/_variables.scss +620 -0
  16. package/src/styles/prism-custom.css +204 -0
  17. package/src/styles/prism-custom.scss +205 -0
  18. package/src/styles/tokens.css +1463 -0
  19. package/src/styles/tokens.scss +1116 -0
  20. package/src/ui/Accordion/Accordion.ai.md +69 -0
  21. package/src/ui/Accordion/Accordion.scss +87 -0
  22. package/src/ui/Accordion/Accordion.spec.ts +25 -0
  23. package/src/ui/Accordion/Accordion.stories.tsx +46 -0
  24. package/src/ui/Accordion/Accordion.test.tsx +54 -0
  25. package/src/ui/Accordion/Accordion.tsx +73 -0
  26. package/src/ui/Accordion/Accordion.types.ts +15 -0
  27. package/src/ui/Accordion/index.js +1 -0
  28. package/src/ui/ActionMenu/ActionMenu.ai.md +106 -0
  29. package/src/ui/ActionMenu/ActionMenu.jsx +437 -0
  30. package/src/ui/ActionMenu/ActionMenu.scss +252 -0
  31. package/src/ui/ActionMenu/ActionMenu.spec.ts +12 -0
  32. package/src/ui/ActionMenu/ActionMenu.stories.jsx +14 -0
  33. package/src/ui/ActionMenu/ActionMenu.stories.tsx +124 -0
  34. package/src/ui/ActionMenu/ActionMenu.test.tsx +1 -0
  35. package/src/ui/ActionMenu/ActionMenu.tsx +6 -0
  36. package/src/ui/ActionMenu/ActionMenu.types.ts +3 -0
  37. package/src/ui/ActionMenu/index.js +1 -0
  38. package/src/ui/Avatar/Avatar.ai.md +54 -0
  39. package/src/ui/Avatar/Avatar.jsx +49 -0
  40. package/src/ui/Avatar/Avatar.scss +87 -0
  41. package/src/ui/Avatar/Avatar.spec.ts +12 -0
  42. package/src/ui/Avatar/Avatar.stories.jsx +14 -0
  43. package/src/ui/Avatar/Avatar.stories.tsx +14 -0
  44. package/src/ui/Avatar/Avatar.test.tsx +1 -0
  45. package/src/ui/Avatar/Avatar.tsx +6 -0
  46. package/src/ui/Avatar/Avatar.types.ts +3 -0
  47. package/src/ui/Avatar/index.js +1 -0
  48. package/src/ui/Badge/Badge.ai.md +37 -0
  49. package/src/ui/Badge/Badge.jsx +64 -0
  50. package/src/ui/Badge/Badge.scss +84 -0
  51. package/src/ui/Badge/Badge.spec.ts +12 -0
  52. package/src/ui/Badge/Badge.stories.jsx +14 -0
  53. package/src/ui/Badge/Badge.stories.tsx +14 -0
  54. package/src/ui/Badge/Badge.test.tsx +1 -0
  55. package/src/ui/Badge/Badge.tsx +6 -0
  56. package/src/ui/Badge/Badge.types.ts +3 -0
  57. package/src/ui/Badge/index.js +1 -0
  58. package/src/ui/Branding/Branding.ai.md +81 -0
  59. package/src/ui/Branding/Branding.jsx +127 -0
  60. package/src/ui/Branding/Branding.scss +57 -0
  61. package/src/ui/Branding/Branding.spec.ts +12 -0
  62. package/src/ui/Branding/Branding.stories.jsx +14 -0
  63. package/src/ui/Branding/Branding.stories.tsx +14 -0
  64. package/src/ui/Branding/Branding.test.tsx +1 -0
  65. package/src/ui/Branding/Branding.tsx +6 -0
  66. package/src/ui/Branding/Branding.types.ts +3 -0
  67. package/src/ui/Branding/index.js +1 -0
  68. package/src/ui/Breadcrumb/Breadcrumb.ai.md +50 -0
  69. package/src/ui/Breadcrumb/Breadcrumb.jsx +167 -0
  70. package/src/ui/Breadcrumb/Breadcrumb.scss +46 -0
  71. package/src/ui/Breadcrumb/Breadcrumb.spec.ts +12 -0
  72. package/src/ui/Breadcrumb/Breadcrumb.stories.jsx +26 -0
  73. package/src/ui/Breadcrumb/Breadcrumb.stories.tsx +14 -0
  74. package/src/ui/Breadcrumb/Breadcrumb.test.tsx +1 -0
  75. package/src/ui/Breadcrumb/Breadcrumb.tsx +6 -0
  76. package/src/ui/Breadcrumb/Breadcrumb.types.ts +3 -0
  77. package/src/ui/Breadcrumb/index.js +2 -0
  78. package/src/ui/Button/Button.ai.md +122 -0
  79. package/src/ui/Button/Button.figma.tsx +49 -0
  80. package/src/ui/Button/Button.scss +188 -0
  81. package/src/ui/Button/Button.spec.ts +52 -0
  82. package/src/ui/Button/Button.stories.tsx +199 -0
  83. package/src/ui/Button/Button.test.tsx +85 -0
  84. package/src/ui/Button/Button.tsx +131 -0
  85. package/src/ui/Button/Button.types.ts +32 -0
  86. package/src/ui/Button/index.js +1 -0
  87. package/src/ui/Calendar/Calendar.ai.md +151 -0
  88. package/src/ui/Calendar/Calendar.jsx +504 -0
  89. package/src/ui/Calendar/Calendar.scss +451 -0
  90. package/src/ui/Calendar/Calendar.spec.ts +12 -0
  91. package/src/ui/Calendar/Calendar.stories.jsx +14 -0
  92. package/src/ui/Calendar/Calendar.stories.tsx +14 -0
  93. package/src/ui/Calendar/Calendar.test.tsx +1 -0
  94. package/src/ui/Calendar/Calendar.tsx +6 -0
  95. package/src/ui/Calendar/Calendar.types.ts +3 -0
  96. package/src/ui/Calendar/index.js +1 -0
  97. package/src/ui/Card/Card.ai.md +41 -0
  98. package/src/ui/Card/Card.jsx +25 -0
  99. package/src/ui/Card/Card.scss +47 -0
  100. package/src/ui/Card/Card.spec.ts +12 -0
  101. package/src/ui/Card/Card.stories.jsx +28 -0
  102. package/src/ui/Card/Card.stories.tsx +14 -0
  103. package/src/ui/Card/Card.test.tsx +1 -0
  104. package/src/ui/Card/Card.tsx +6 -0
  105. package/src/ui/Card/Card.types.ts +3 -0
  106. package/src/ui/Card/index.js +1 -0
  107. package/src/ui/Checkbox/Checkbox.ai.md +50 -0
  108. package/src/ui/Checkbox/Checkbox.jsx +73 -0
  109. package/src/ui/Checkbox/Checkbox.scss +115 -0
  110. package/src/ui/Checkbox/Checkbox.spec.ts +12 -0
  111. package/src/ui/Checkbox/Checkbox.stories.jsx +14 -0
  112. package/src/ui/Checkbox/Checkbox.stories.tsx +14 -0
  113. package/src/ui/Checkbox/Checkbox.test.tsx +1 -0
  114. package/src/ui/Checkbox/Checkbox.tsx +6 -0
  115. package/src/ui/Checkbox/Checkbox.types.ts +3 -0
  116. package/src/ui/Checkbox/index.js +1 -0
  117. package/src/ui/Chip/Chip.ai.md +43 -0
  118. package/src/ui/Chip/Chip.jsx +102 -0
  119. package/src/ui/Chip/Chip.scss +118 -0
  120. package/src/ui/Chip/Chip.spec.ts +12 -0
  121. package/src/ui/Chip/Chip.stories.jsx +14 -0
  122. package/src/ui/Chip/Chip.stories.tsx +14 -0
  123. package/src/ui/Chip/Chip.test.tsx +1 -0
  124. package/src/ui/Chip/Chip.tsx +6 -0
  125. package/src/ui/Chip/Chip.types.ts +3 -0
  126. package/src/ui/Chip/index.js +1 -0
  127. package/src/ui/Datepicker/Datepicker.ai.md +45 -0
  128. package/src/ui/Datepicker/Datepicker.jsx +330 -0
  129. package/src/ui/Datepicker/Datepicker.scss +206 -0
  130. package/src/ui/Datepicker/Datepicker.spec.ts +12 -0
  131. package/src/ui/Datepicker/Datepicker.stories.jsx +14 -0
  132. package/src/ui/Datepicker/Datepicker.stories.tsx +14 -0
  133. package/src/ui/Datepicker/Datepicker.test.tsx +1 -0
  134. package/src/ui/Datepicker/Datepicker.tsx +6 -0
  135. package/src/ui/Datepicker/Datepicker.types.ts +3 -0
  136. package/src/ui/Datepicker/index.js +2 -0
  137. package/src/ui/Divider/Divider.ai.md +34 -0
  138. package/src/ui/Divider/Divider.jsx +89 -0
  139. package/src/ui/Divider/Divider.scss +116 -0
  140. package/src/ui/Divider/Divider.spec.ts +12 -0
  141. package/src/ui/Divider/Divider.stories.jsx +14 -0
  142. package/src/ui/Divider/Divider.stories.tsx +14 -0
  143. package/src/ui/Divider/Divider.test.tsx +1 -0
  144. package/src/ui/Divider/Divider.tsx +6 -0
  145. package/src/ui/Divider/Divider.types.ts +3 -0
  146. package/src/ui/Divider/index.js +1 -0
  147. package/src/ui/DotStatus/DotStatus.ai.md +36 -0
  148. package/src/ui/DotStatus/DotStatus.jsx +64 -0
  149. package/src/ui/DotStatus/DotStatus.scss +87 -0
  150. package/src/ui/DotStatus/DotStatus.spec.ts +12 -0
  151. package/src/ui/DotStatus/DotStatus.stories.jsx +14 -0
  152. package/src/ui/DotStatus/DotStatus.stories.tsx +14 -0
  153. package/src/ui/DotStatus/DotStatus.test.tsx +1 -0
  154. package/src/ui/DotStatus/DotStatus.tsx +6 -0
  155. package/src/ui/DotStatus/DotStatus.types.ts +3 -0
  156. package/src/ui/DotStatus/index.js +1 -0
  157. package/src/ui/Dropdown/Dropdown.ai.md +118 -0
  158. package/src/ui/Dropdown/Dropdown.scss +129 -0
  159. package/src/ui/Dropdown/Dropdown.spec.ts +54 -0
  160. package/src/ui/Dropdown/Dropdown.stories.tsx +59 -0
  161. package/src/ui/Dropdown/Dropdown.test.tsx +37 -0
  162. package/src/ui/Dropdown/Dropdown.tsx +119 -0
  163. package/src/ui/Dropdown/Dropdown.types.ts +25 -0
  164. package/src/ui/Dropdown/index.js +1 -0
  165. package/src/ui/EventCard/EventCard.ai.md +101 -0
  166. package/src/ui/EventCard/EventCard.jsx +92 -0
  167. package/src/ui/EventCard/EventCard.scss +186 -0
  168. package/src/ui/EventCard/EventCard.spec.ts +12 -0
  169. package/src/ui/EventCard/EventCard.stories.jsx +14 -0
  170. package/src/ui/EventCard/EventCard.stories.tsx +14 -0
  171. package/src/ui/EventCard/EventCard.test.tsx +1 -0
  172. package/src/ui/EventCard/EventCard.tsx +6 -0
  173. package/src/ui/EventCard/EventCard.types.ts +3 -0
  174. package/src/ui/EventCard/index.js +1 -0
  175. package/src/ui/Field/Field.ai.md +69 -0
  176. package/src/ui/Field/Field.jsx +89 -0
  177. package/src/ui/Field/Field.scss +76 -0
  178. package/src/ui/Field/Field.spec.ts +12 -0
  179. package/src/ui/Field/Field.stories.jsx +14 -0
  180. package/src/ui/Field/Field.stories.tsx +14 -0
  181. package/src/ui/Field/Field.test.tsx +1 -0
  182. package/src/ui/Field/Field.tsx +6 -0
  183. package/src/ui/Field/Field.types.ts +3 -0
  184. package/src/ui/Field/index.js +1 -0
  185. package/src/ui/FileUpload/FileUpload.ai.md +38 -0
  186. package/src/ui/FileUpload/FileUpload.figma.tsx +28 -0
  187. package/src/ui/FileUpload/FileUpload.jsx +153 -0
  188. package/src/ui/FileUpload/FileUpload.scss +78 -0
  189. package/src/ui/FileUpload/FileUpload.spec.ts +12 -0
  190. package/src/ui/FileUpload/FileUpload.stories.jsx +14 -0
  191. package/src/ui/FileUpload/FileUpload.stories.tsx +14 -0
  192. package/src/ui/FileUpload/FileUpload.test.tsx +1 -0
  193. package/src/ui/FileUpload/FileUpload.tsx +6 -0
  194. package/src/ui/FileUpload/FileUpload.types.ts +3 -0
  195. package/src/ui/FileUpload/index.js +2 -0
  196. package/src/ui/Flex/Flex.ai.md +130 -0
  197. package/src/ui/Flex/Flex.jsx +53 -0
  198. package/src/ui/Flex/Flex.scss +119 -0
  199. package/src/ui/Flex/Flex.spec.ts +12 -0
  200. package/src/ui/Flex/Flex.stories.jsx +14 -0
  201. package/src/ui/Flex/Flex.stories.tsx +14 -0
  202. package/src/ui/Flex/Flex.test.tsx +1 -0
  203. package/src/ui/Flex/Flex.tsx +6 -0
  204. package/src/ui/Flex/Flex.types.ts +3 -0
  205. package/src/ui/Flex/index.js +1 -0
  206. package/src/ui/Icon/Icon.ai.md +46 -0
  207. package/src/ui/Icon/Icon.figma.tsx +22 -0
  208. package/src/ui/Icon/Icon.jsx +47 -0
  209. package/src/ui/Icon/Icon.scss +1 -0
  210. package/src/ui/Icon/Icon.spec.ts +12 -0
  211. package/src/ui/Icon/Icon.stories.jsx +14 -0
  212. package/src/ui/Icon/Icon.stories.tsx +14 -0
  213. package/src/ui/Icon/Icon.test.tsx +1 -0
  214. package/src/ui/Icon/Icon.tsx +6 -0
  215. package/src/ui/Icon/Icon.types.ts +3 -0
  216. package/src/ui/Icon/index.js +1 -0
  217. package/src/ui/ImageAspect/ImageAspect.ai.md +37 -0
  218. package/src/ui/ImageAspect/ImageAspect.jsx +56 -0
  219. package/src/ui/ImageAspect/ImageAspect.scss +62 -0
  220. package/src/ui/ImageAspect/ImageAspect.spec.ts +12 -0
  221. package/src/ui/ImageAspect/ImageAspect.stories.jsx +14 -0
  222. package/src/ui/ImageAspect/ImageAspect.stories.tsx +14 -0
  223. package/src/ui/ImageAspect/ImageAspect.test.tsx +1 -0
  224. package/src/ui/ImageAspect/ImageAspect.tsx +6 -0
  225. package/src/ui/ImageAspect/ImageAspect.types.ts +3 -0
  226. package/src/ui/ImageAspect/index.js +1 -0
  227. package/src/ui/Input/Input.ai.md +89 -0
  228. package/src/ui/Input/Input.figma.tsx +35 -0
  229. package/src/ui/Input/Input.scss +126 -0
  230. package/src/ui/Input/Input.spec.ts +54 -0
  231. package/src/ui/Input/Input.stories.tsx +72 -0
  232. package/src/ui/Input/Input.test.tsx +70 -0
  233. package/src/ui/Input/Input.tsx +91 -0
  234. package/src/ui/Input/Input.types.ts +22 -0
  235. package/src/ui/Input/index.js +2 -0
  236. package/src/ui/Key/Key.ai.md +31 -0
  237. package/src/ui/Key/Key.jsx +37 -0
  238. package/src/ui/Key/Key.scss +31 -0
  239. package/src/ui/Key/Key.spec.ts +12 -0
  240. package/src/ui/Key/Key.stories.jsx +14 -0
  241. package/src/ui/Key/Key.stories.tsx +14 -0
  242. package/src/ui/Key/Key.test.tsx +1 -0
  243. package/src/ui/Key/Key.tsx +6 -0
  244. package/src/ui/Key/Key.types.ts +3 -0
  245. package/src/ui/Key/index.js +1 -0
  246. package/src/ui/Menu/Menu.jsx +232 -0
  247. package/src/ui/Menu/Menu.scss +370 -0
  248. package/src/ui/Menu/Menu.spec.ts +12 -0
  249. package/src/ui/Menu/Menu.stories.jsx +41 -0
  250. package/src/ui/Menu/Menu.stories.tsx +14 -0
  251. package/src/ui/Menu/Menu.test.tsx +1 -0
  252. package/src/ui/Menu/Menu.tsx +6 -0
  253. package/src/ui/Menu/Menu.types.ts +3 -0
  254. package/src/ui/Menu/index.js +1 -0
  255. package/src/ui/MicroCalendar/MicroCalendar.ai.md +35 -0
  256. package/src/ui/MicroCalendar/MicroCalendar.jsx +393 -0
  257. package/src/ui/MicroCalendar/MicroCalendar.scss +289 -0
  258. package/src/ui/MicroCalendar/MicroCalendar.spec.ts +12 -0
  259. package/src/ui/MicroCalendar/MicroCalendar.stories.jsx +14 -0
  260. package/src/ui/MicroCalendar/MicroCalendar.stories.tsx +14 -0
  261. package/src/ui/MicroCalendar/MicroCalendar.test.tsx +1 -0
  262. package/src/ui/MicroCalendar/MicroCalendar.tsx +6 -0
  263. package/src/ui/MicroCalendar/MicroCalendar.types.ts +3 -0
  264. package/src/ui/MicroCalendar/index.js +1 -0
  265. package/src/ui/Modal/Modal.ai.md +150 -0
  266. package/src/ui/Modal/Modal.jsx +173 -0
  267. package/src/ui/Modal/Modal.scss +179 -0
  268. package/src/ui/Modal/Modal.spec.ts +12 -0
  269. package/src/ui/Modal/Modal.stories.jsx +14 -0
  270. package/src/ui/Modal/Modal.stories.tsx +14 -0
  271. package/src/ui/Modal/Modal.test.tsx +1 -0
  272. package/src/ui/Modal/Modal.tsx +6 -0
  273. package/src/ui/Modal/Modal.types.ts +3 -0
  274. package/src/ui/Modal/index.js +1 -0
  275. package/src/ui/Pagination/Pagination.ai.md +30 -0
  276. package/src/ui/Pagination/Pagination.jsx +237 -0
  277. package/src/ui/Pagination/Pagination.scss +182 -0
  278. package/src/ui/Pagination/Pagination.spec.ts +12 -0
  279. package/src/ui/Pagination/Pagination.stories.jsx +14 -0
  280. package/src/ui/Pagination/Pagination.stories.tsx +14 -0
  281. package/src/ui/Pagination/Pagination.test.tsx +1 -0
  282. package/src/ui/Pagination/Pagination.tsx +6 -0
  283. package/src/ui/Pagination/Pagination.types.ts +3 -0
  284. package/src/ui/Pagination/index.js +1 -0
  285. package/src/ui/PillToggle/PillToggle.ai.md +44 -0
  286. package/src/ui/PillToggle/PillToggle.jsx +56 -0
  287. package/src/ui/PillToggle/PillToggle.scss +84 -0
  288. package/src/ui/PillToggle/PillToggle.spec.ts +12 -0
  289. package/src/ui/PillToggle/PillToggle.stories.jsx +14 -0
  290. package/src/ui/PillToggle/PillToggle.stories.tsx +14 -0
  291. package/src/ui/PillToggle/PillToggle.test.tsx +1 -0
  292. package/src/ui/PillToggle/PillToggle.tsx +6 -0
  293. package/src/ui/PillToggle/PillToggle.types.ts +3 -0
  294. package/src/ui/PillToggle/index.js +1 -0
  295. package/src/ui/Playground/Playground.ai.md +96 -0
  296. package/src/ui/Playground/Playground.jsx +524 -0
  297. package/src/ui/Playground/Playground.scss +310 -0
  298. package/src/ui/Playground/Playground.spec.ts +12 -0
  299. package/src/ui/Playground/Playground.stories.jsx +14 -0
  300. package/src/ui/Playground/Playground.stories.tsx +14 -0
  301. package/src/ui/Playground/Playground.test.tsx +1 -0
  302. package/src/ui/Playground/Playground.tsx +6 -0
  303. package/src/ui/Playground/Playground.types.ts +3 -0
  304. package/src/ui/Playground/index.js +2 -0
  305. package/src/ui/ProgressCircle/ProgressCircle.ai.md +36 -0
  306. package/src/ui/ProgressCircle/ProgressCircle.jsx +147 -0
  307. package/src/ui/ProgressCircle/ProgressCircle.scss +143 -0
  308. package/src/ui/ProgressCircle/ProgressCircle.spec.ts +12 -0
  309. package/src/ui/ProgressCircle/ProgressCircle.stories.jsx +14 -0
  310. package/src/ui/ProgressCircle/ProgressCircle.stories.tsx +14 -0
  311. package/src/ui/ProgressCircle/ProgressCircle.test.tsx +1 -0
  312. package/src/ui/ProgressCircle/ProgressCircle.tsx +6 -0
  313. package/src/ui/ProgressCircle/ProgressCircle.types.ts +3 -0
  314. package/src/ui/ProgressCircle/index.js +1 -0
  315. package/src/ui/ProgressIndicator/ProgressIndicator.ai.md +27 -0
  316. package/src/ui/ProgressIndicator/ProgressIndicator.jsx +92 -0
  317. package/src/ui/ProgressIndicator/ProgressIndicator.scss +133 -0
  318. package/src/ui/ProgressIndicator/ProgressIndicator.spec.ts +12 -0
  319. package/src/ui/ProgressIndicator/ProgressIndicator.stories.jsx +14 -0
  320. package/src/ui/ProgressIndicator/ProgressIndicator.stories.tsx +14 -0
  321. package/src/ui/ProgressIndicator/ProgressIndicator.test.tsx +1 -0
  322. package/src/ui/ProgressIndicator/ProgressIndicator.tsx +6 -0
  323. package/src/ui/ProgressIndicator/ProgressIndicator.types.ts +3 -0
  324. package/src/ui/ProgressIndicator/index.js +1 -0
  325. package/src/ui/Radio/Radio.ai.md +53 -0
  326. package/src/ui/Radio/Radio.jsx +57 -0
  327. package/src/ui/Radio/Radio.scss +89 -0
  328. package/src/ui/Radio/Radio.spec.ts +12 -0
  329. package/src/ui/Radio/Radio.stories.jsx +14 -0
  330. package/src/ui/Radio/Radio.stories.tsx +14 -0
  331. package/src/ui/Radio/Radio.test.tsx +1 -0
  332. package/src/ui/Radio/Radio.tsx +6 -0
  333. package/src/ui/Radio/Radio.types.ts +3 -0
  334. package/src/ui/Radio/index.js +1 -0
  335. package/src/ui/Slider/Slider.ai.md +33 -0
  336. package/src/ui/Slider/Slider.jsx +283 -0
  337. package/src/ui/Slider/Slider.scss +156 -0
  338. package/src/ui/Slider/Slider.spec.ts +12 -0
  339. package/src/ui/Slider/Slider.stories.jsx +14 -0
  340. package/src/ui/Slider/Slider.stories.tsx +14 -0
  341. package/src/ui/Slider/Slider.test.tsx +1 -0
  342. package/src/ui/Slider/Slider.tsx +6 -0
  343. package/src/ui/Slider/Slider.types.ts +3 -0
  344. package/src/ui/Slider/index.js +1 -0
  345. package/src/ui/Status/Status.ai.md +36 -0
  346. package/src/ui/Status/Status.jsx +66 -0
  347. package/src/ui/Status/Status.scss +90 -0
  348. package/src/ui/Status/Status.spec.ts +12 -0
  349. package/src/ui/Status/Status.stories.jsx +14 -0
  350. package/src/ui/Status/Status.stories.tsx +14 -0
  351. package/src/ui/Status/Status.test.tsx +1 -0
  352. package/src/ui/Status/Status.tsx +6 -0
  353. package/src/ui/Status/Status.types.ts +3 -0
  354. package/src/ui/Status/index.js +1 -0
  355. package/src/ui/Steps/Steps.ai.md +56 -0
  356. package/src/ui/Steps/Steps.jsx +201 -0
  357. package/src/ui/Steps/Steps.scss +240 -0
  358. package/src/ui/Steps/Steps.spec.ts +12 -0
  359. package/src/ui/Steps/Steps.stories.jsx +14 -0
  360. package/src/ui/Steps/Steps.stories.tsx +14 -0
  361. package/src/ui/Steps/Steps.test.tsx +1 -0
  362. package/src/ui/Steps/Steps.tsx +6 -0
  363. package/src/ui/Steps/Steps.types.ts +3 -0
  364. package/src/ui/Steps/index.js +1 -0
  365. package/src/ui/Table/Table.ai.md +108 -0
  366. package/src/ui/Table/Table.jsx +143 -0
  367. package/src/ui/Table/Table.scss +90 -0
  368. package/src/ui/Table/Table.spec.ts +12 -0
  369. package/src/ui/Table/Table.stories.jsx +14 -0
  370. package/src/ui/Table/Table.stories.tsx +14 -0
  371. package/src/ui/Table/Table.test.tsx +1 -0
  372. package/src/ui/Table/Table.tsx +6 -0
  373. package/src/ui/Table/Table.types.ts +3 -0
  374. package/src/ui/Table/index.js +1 -0
  375. package/src/ui/Tabs/TabItem.jsx +80 -0
  376. package/src/ui/Tabs/Tabs.ai.md +52 -0
  377. package/src/ui/Tabs/Tabs.figma.tsx +30 -0
  378. package/src/ui/Tabs/Tabs.jsx +318 -0
  379. package/src/ui/Tabs/Tabs.scss +164 -0
  380. package/src/ui/Tabs/Tabs.spec.ts +12 -0
  381. package/src/ui/Tabs/Tabs.stories.jsx +18 -0
  382. package/src/ui/Tabs/Tabs.stories.tsx +14 -0
  383. package/src/ui/Tabs/Tabs.test.tsx +1 -0
  384. package/src/ui/Tabs/Tabs.tsx +6 -0
  385. package/src/ui/Tabs/Tabs.types.ts +3 -0
  386. package/src/ui/Tabs/index.js +3 -0
  387. package/src/ui/Tag/Tag.ai.md +59 -0
  388. package/src/ui/Tag/Tag.figma.tsx +29 -0
  389. package/src/ui/Tag/Tag.jsx +93 -0
  390. package/src/ui/Tag/Tag.scss +258 -0
  391. package/src/ui/Tag/Tag.spec.ts +12 -0
  392. package/src/ui/Tag/Tag.stories.jsx +14 -0
  393. package/src/ui/Tag/Tag.stories.tsx +14 -0
  394. package/src/ui/Tag/Tag.test.tsx +1 -0
  395. package/src/ui/Tag/Tag.tsx +6 -0
  396. package/src/ui/Tag/Tag.types.ts +3 -0
  397. package/src/ui/Tag/index.js +2 -0
  398. package/src/ui/Textarea/Textarea.ai.md +40 -0
  399. package/src/ui/Textarea/Textarea.figma.tsx +35 -0
  400. package/src/ui/Textarea/Textarea.jsx +68 -0
  401. package/src/ui/Textarea/Textarea.scss +71 -0
  402. package/src/ui/Textarea/Textarea.spec.ts +12 -0
  403. package/src/ui/Textarea/Textarea.stories.jsx +14 -0
  404. package/src/ui/Textarea/Textarea.stories.tsx +14 -0
  405. package/src/ui/Textarea/Textarea.test.tsx +1 -0
  406. package/src/ui/Textarea/Textarea.tsx +6 -0
  407. package/src/ui/Textarea/Textarea.types.ts +3 -0
  408. package/src/ui/Textarea/index.js +2 -0
  409. package/src/ui/Toast/Toast.ai.md +47 -0
  410. package/src/ui/Toast/Toast.jsx +75 -0
  411. package/src/ui/Toast/Toast.scss +132 -0
  412. package/src/ui/Toast/Toast.spec.ts +12 -0
  413. package/src/ui/Toast/Toast.stories.jsx +14 -0
  414. package/src/ui/Toast/Toast.stories.tsx +14 -0
  415. package/src/ui/Toast/Toast.test.tsx +1 -0
  416. package/src/ui/Toast/Toast.tsx +6 -0
  417. package/src/ui/Toast/Toast.types.ts +3 -0
  418. package/src/ui/Toast/index.js +2 -0
  419. package/src/ui/Toggle/Toggle.ai.md +37 -0
  420. package/src/ui/Toggle/Toggle.jsx +73 -0
  421. package/src/ui/Toggle/Toggle.scss +139 -0
  422. package/src/ui/Toggle/Toggle.spec.ts +12 -0
  423. package/src/ui/Toggle/Toggle.stories.jsx +14 -0
  424. package/src/ui/Toggle/Toggle.stories.tsx +14 -0
  425. package/src/ui/Toggle/Toggle.test.tsx +1 -0
  426. package/src/ui/Toggle/Toggle.tsx +6 -0
  427. package/src/ui/Toggle/Toggle.types.ts +3 -0
  428. package/src/ui/Toggle/index.js +1 -0
  429. package/src/ui/Tooltip/Tooltip.ai.md +33 -0
  430. package/src/ui/Tooltip/Tooltip.figma.tsx +24 -0
  431. package/src/ui/Tooltip/Tooltip.jsx +125 -0
  432. package/src/ui/Tooltip/Tooltip.scss +80 -0
  433. package/src/ui/Tooltip/Tooltip.spec.ts +12 -0
  434. package/src/ui/Tooltip/Tooltip.stories.jsx +14 -0
  435. package/src/ui/Tooltip/Tooltip.stories.tsx +14 -0
  436. package/src/ui/Tooltip/Tooltip.test.tsx +1 -0
  437. package/src/ui/Tooltip/Tooltip.tsx +6 -0
  438. package/src/ui/Tooltip/Tooltip.types.ts +3 -0
  439. package/src/ui/Tooltip/index.js +2 -0
  440. package/src/ui/UDS/UDS.jsx +52 -0
  441. package/src/ui/UDS/UDS.scss +49 -0
  442. package/src/ui/UDS/UDS.spec.ts +12 -0
  443. package/src/ui/UDS/UDS.stories.jsx +22 -0
  444. package/src/ui/UDS/UDS.stories.tsx +14 -0
  445. package/src/ui/UDS/UDS.test.tsx +1 -0
  446. package/src/ui/UDS/UDS.tsx +6 -0
  447. package/src/ui/UDS/UDS.types.ts +3 -0
  448. package/src/ui/UDS/index.js +1 -0
  449. package/src/ui/_spec/createMetaFromSpec.ts +35 -0
  450. package/src/ui/_spec/createStoryArgsFromSpec.ts +8 -0
  451. package/src/ui/_spec/generated/spec-props-reference.md +55 -0
  452. package/src/ui/_spec/specStorySync.test.ts +73 -0
  453. package/src/ui/_spec/types.ts +21 -0
  454. package/src/ui/index.js +66 -0
@@ -0,0 +1,69 @@
1
+ # Accordion
2
+
3
+ Expandable/collapsible content sections for organizing information hierarchically.
4
+
5
+ ## When to Use
6
+ - FAQs, settings panels, or grouped content that benefits from progressive disclosure
7
+ - Reducing visual clutter by hiding secondary information behind headers
8
+
9
+ ## Props
10
+
11
+ ### Accordion (container)
12
+
13
+ | Prop | Type | Default | Description |
14
+ |------|------|---------|-------------|
15
+ | `children` | `ReactNode` | — | `AccordionItem` components |
16
+ | `className` | `string` | `""` | Additional CSS classes |
17
+
18
+ ### AccordionItem
19
+
20
+ | Prop | Type | Default | Description |
21
+ |------|------|---------|-------------|
22
+ | `label` | `string` | — | Header text for the item |
23
+ | `defaultExpanded` | `boolean` | `false` | Whether item starts expanded |
24
+ | `children` | `ReactNode` | — | Content shown when expanded |
25
+ | `className` | `string` | `""` | Additional CSS classes |
26
+ | `onToggle` | `function` | — | Callback `(isExpanded: boolean) => void` |
27
+
28
+ ## Examples
29
+
30
+ ### Basic accordion
31
+ ```jsx
32
+ <Accordion>
33
+ <AccordionItem label="Section 1">
34
+ <p>Content for section 1</p>
35
+ </AccordionItem>
36
+ <AccordionItem label="Section 2">
37
+ <p>Content for section 2</p>
38
+ </AccordionItem>
39
+ <AccordionItem label="Section 3" defaultExpanded>
40
+ <p>This section starts expanded</p>
41
+ </AccordionItem>
42
+ </Accordion>
43
+ ```
44
+
45
+ ### FAQ pattern
46
+ ```jsx
47
+ <Accordion>
48
+ {faqs.map((faq) => (
49
+ <AccordionItem key={faq.id} label={faq.question}>
50
+ <p>{faq.answer}</p>
51
+ </AccordionItem>
52
+ ))}
53
+ </Accordion>
54
+ ```
55
+
56
+ ## Import
57
+ ```jsx
58
+ import { Accordion, AccordionItem } from "@mich8060/chg-design-system";
59
+ // OR
60
+ import Accordion, { AccordionItem } from "@mich8060/chg-design-system/Accordion";
61
+ ```
62
+
63
+ ## Do's and Don'ts
64
+
65
+ ✅ **Do**: Use for content that doesn't all need to be visible at once
66
+ ✅ **Do**: Use `defaultExpanded` on the most important section
67
+
68
+ ❌ **Don't**: Nest accordions inside accordions
69
+ ❌ **Don't**: Put critical information only inside accordion items
@@ -0,0 +1,87 @@
1
+ @use "../../styles/typography" as *;
2
+
3
+ .accordion {
4
+ display: flex;
5
+ flex-direction: column;
6
+ width: 100%;
7
+
8
+ // ── Block: accordion-item ───────────────────────────
9
+ &-item {
10
+ display: flex;
11
+ flex-direction: column;
12
+ border-bottom: var(--uds-border-width-1) solid var(--uds-border-primary);
13
+ width: 100%;
14
+
15
+ &:last-child {
16
+ border-bottom: none;
17
+ }
18
+
19
+ // ── Element: header button ──────────────────────────
20
+ &__header {
21
+ @include uds-body-16-semibold;
22
+ display: flex;
23
+ align-items: center;
24
+ justify-content: space-between;
25
+ gap: var(--uds-gap-16);
26
+ padding: var(--uds-spacing-12) var(--uds-spacing-16);
27
+ background: var(--uds-surface-primary);
28
+ border: none;
29
+ cursor: pointer;
30
+ width: 100%;
31
+ text-align: left;
32
+ color: var(--uds-text-primary);
33
+ transition: background-color 0.3s ease;
34
+
35
+ &:hover {
36
+ background-color: var(--uds-surface-tertiary);
37
+ }
38
+
39
+ &:focus-visible {
40
+ outline: solid var(--uds-focus-ring-width) var(--uds-focus-ring-border);
41
+ outline-offset: var(--uds-focus-ring-offset);
42
+ }
43
+ }
44
+
45
+ // ── Element: label text ─────────────────────────────
46
+ &__label {
47
+ flex: 1;
48
+ line-height: 24px;
49
+ }
50
+
51
+ // ── Element: chevron icon ───────────────────────────
52
+ &__icon {
53
+ flex-shrink: 0;
54
+ transition: transform 0.3s ease;
55
+ color: var(--uds-text-primary);
56
+
57
+ &--expanded {
58
+ transform: rotate(180deg);
59
+ }
60
+ }
61
+
62
+ // ── Element: collapsible body ───────────────────────
63
+ &__body {
64
+ display: grid;
65
+ grid-template-rows: 0fr;
66
+ opacity: 0;
67
+ transition:
68
+ grid-template-rows 0.3s ease,
69
+ opacity 0.2s ease;
70
+
71
+ &--expanded {
72
+ grid-template-rows: 1fr;
73
+ opacity: 1;
74
+
75
+ .accordion-item__body-inner {
76
+ padding-bottom: var(--uds-spacing-24);
77
+ }
78
+ }
79
+
80
+ &-inner {
81
+ overflow: hidden;
82
+ padding: 0 var(--uds-spacing-16);
83
+ transition: padding 0.2s ease;
84
+ }
85
+ }
86
+ }
87
+ }
@@ -0,0 +1,25 @@
1
+ export const ACCORDION_BASE_CLASS = "accordion";
2
+ export const ACCORDION_ITEM_BASE_CLASS = "accordion-item";
3
+
4
+ export const ACCORDION_DEFAULTS = {
5
+ className: "",
6
+ } as const;
7
+
8
+ export const ACCORDION_ITEM_DEFAULTS = {
9
+ defaultExpanded: false,
10
+ className: "",
11
+ } as const;
12
+
13
+ export const ACCORDION_STORY_SPEC = {
14
+ defaults: {
15
+ expandedFirst: false as boolean,
16
+ },
17
+ stories: {
18
+ default: { expandedFirst: false },
19
+ firstExpanded: { expandedFirst: true },
20
+ },
21
+ items: [
22
+ { id: "section-one", label: "Section One", content: "First section content" },
23
+ { id: "section-two", label: "Section Two", content: "Second section content" },
24
+ ],
25
+ } as const;
@@ -0,0 +1,46 @@
1
+ import Accordion, { AccordionItem } from "./Accordion";
2
+ import { ACCORDION_STORY_SPEC } from "./Accordion.spec";
3
+ import { createStoryArgsFromSpec } from "../_spec/createStoryArgsFromSpec";
4
+
5
+ const fromSpec = createStoryArgsFromSpec(ACCORDION_STORY_SPEC.defaults);
6
+
7
+ export default {
8
+ title: "Components/Accordion",
9
+ component: Accordion,
10
+ tags: ["autodocs"],
11
+ args: ACCORDION_STORY_SPEC.defaults,
12
+ parameters: {},
13
+ argTypes: {
14
+ expandedFirst: {
15
+ control: "boolean",
16
+ description: "Expands the first accordion item by default.",
17
+ },
18
+ },
19
+ };
20
+
21
+ const renderFromSpec = (expandedFirst: boolean) => (
22
+ <Accordion>
23
+ {ACCORDION_STORY_SPEC.items.map((item, index) => (
24
+ <AccordionItem
25
+ key={item.id}
26
+ id={item.id}
27
+ label={item.label}
28
+ defaultExpanded={expandedFirst && index === 0}
29
+ >
30
+ {item.content}
31
+ </AccordionItem>
32
+ ))}
33
+ </Accordion>
34
+ );
35
+
36
+ export const Default = {
37
+ args: fromSpec(ACCORDION_STORY_SPEC.stories.default),
38
+ render: ({ expandedFirst }: { expandedFirst: boolean }) =>
39
+ renderFromSpec(expandedFirst),
40
+ };
41
+
42
+ export const FirstExpanded = {
43
+ args: fromSpec(ACCORDION_STORY_SPEC.stories.firstExpanded),
44
+ render: ({ expandedFirst }: { expandedFirst: boolean }) =>
45
+ renderFromSpec(expandedFirst),
46
+ };
@@ -0,0 +1,54 @@
1
+ import { describe, test } from "@jest/globals";
2
+ import { fireEvent, render, screen } from "@testing-library/react";
3
+ import Accordion, { AccordionItem } from "./Accordion";
4
+ import { ACCORDION_STORY_SPEC } from "./Accordion.spec";
5
+
6
+ describe("Accordion spec sync", () => {
7
+ test("renders all spec items", () => {
8
+ render(
9
+ <Accordion>
10
+ {ACCORDION_STORY_SPEC.items.map((item) => (
11
+ <AccordionItem key={item.id} id={item.id} label={item.label}>
12
+ {item.content}
13
+ </AccordionItem>
14
+ ))}
15
+ </Accordion>,
16
+ );
17
+
18
+ ACCORDION_STORY_SPEC.items.forEach((item) => {
19
+ expect(screen.getByRole("button", { name: item.label })).toBeInTheDocument();
20
+ });
21
+ });
22
+
23
+ test("toggles expanded state on click", () => {
24
+ render(
25
+ <Accordion>
26
+ <AccordionItem id="accordion-test" label="Toggle Section">
27
+ Body content
28
+ </AccordionItem>
29
+ </Accordion>,
30
+ );
31
+
32
+ const trigger = screen.getByRole("button", { name: "Toggle Section" });
33
+ expect(trigger).toHaveAttribute("aria-expanded", "false");
34
+
35
+ fireEvent.click(trigger);
36
+ expect(trigger).toHaveAttribute("aria-expanded", "true");
37
+
38
+ fireEvent.click(trigger);
39
+ expect(trigger).toHaveAttribute("aria-expanded", "false");
40
+ });
41
+
42
+ test("honors defaultExpanded", () => {
43
+ render(
44
+ <Accordion>
45
+ <AccordionItem id="accordion-expanded" label="Expanded Section" defaultExpanded>
46
+ Expanded body
47
+ </AccordionItem>
48
+ </Accordion>,
49
+ );
50
+
51
+ const trigger = screen.getByRole("button", { name: "Expanded Section" });
52
+ expect(trigger).toHaveAttribute("aria-expanded", "true");
53
+ });
54
+ });
@@ -0,0 +1,73 @@
1
+ import { useState } from "react";
2
+ import Icon from "../Icon/Icon";
3
+ import "./Accordion.scss";
4
+ import {
5
+ ACCORDION_BASE_CLASS,
6
+ ACCORDION_DEFAULTS,
7
+ ACCORDION_ITEM_BASE_CLASS,
8
+ ACCORDION_ITEM_DEFAULTS,
9
+ } from "./Accordion.spec";
10
+ import type { AccordionItemProps, AccordionProps } from "./Accordion.types";
11
+
12
+ const IconComponent = Icon as any;
13
+
14
+ export function AccordionItem({
15
+ label,
16
+ defaultExpanded = ACCORDION_ITEM_DEFAULTS.defaultExpanded,
17
+ children,
18
+ className = ACCORDION_ITEM_DEFAULTS.className,
19
+ onToggle,
20
+ id,
21
+ ...rest
22
+ }: AccordionItemProps) {
23
+ const [expanded, setExpanded] = useState(defaultExpanded);
24
+ const contentId = `accordion-content-${id || label}`;
25
+
26
+ const handleToggle = () => {
27
+ const newExpanded = !expanded;
28
+ setExpanded(newExpanded);
29
+ onToggle?.(newExpanded);
30
+ };
31
+
32
+ return (
33
+ <div className={`${ACCORDION_ITEM_BASE_CLASS} ${className}`.trim()} id={id} {...rest}>
34
+ <button
35
+ type="button"
36
+ className={`${ACCORDION_ITEM_BASE_CLASS}__header`}
37
+ onClick={handleToggle}
38
+ aria-expanded={expanded}
39
+ aria-controls={contentId}
40
+ >
41
+ <span className={`${ACCORDION_ITEM_BASE_CLASS}__label`}>{label}</span>
42
+ <IconComponent
43
+ name="CaretDown"
44
+ size={16}
45
+ appearance="bold"
46
+ className={`${ACCORDION_ITEM_BASE_CLASS}__icon ${
47
+ expanded ? `${ACCORDION_ITEM_BASE_CLASS}__icon--expanded` : ""
48
+ }`}
49
+ />
50
+ </button>
51
+ <div
52
+ id={contentId}
53
+ className={`${ACCORDION_ITEM_BASE_CLASS}__body ${
54
+ expanded ? `${ACCORDION_ITEM_BASE_CLASS}__body--expanded` : ""
55
+ }`}
56
+ >
57
+ <div className={`${ACCORDION_ITEM_BASE_CLASS}__body-inner`}>{children}</div>
58
+ </div>
59
+ </div>
60
+ );
61
+ }
62
+
63
+ export default function Accordion({
64
+ children,
65
+ className = ACCORDION_DEFAULTS.className,
66
+ ...rest
67
+ }: AccordionProps) {
68
+ return (
69
+ <div className={`${ACCORDION_BASE_CLASS} ${className}`.trim()} {...rest}>
70
+ {children}
71
+ </div>
72
+ );
73
+ }
@@ -0,0 +1,15 @@
1
+ import type { HTMLAttributes, ReactNode } from "react";
2
+
3
+ export interface AccordionProps extends HTMLAttributes<HTMLDivElement> {
4
+ children?: ReactNode;
5
+ className?: string;
6
+ }
7
+
8
+ export interface AccordionItemProps
9
+ extends Omit<HTMLAttributes<HTMLDivElement>, "onToggle"> {
10
+ label: string;
11
+ defaultExpanded?: boolean;
12
+ children?: ReactNode;
13
+ className?: string;
14
+ onToggle?: (expanded: boolean) => void;
15
+ }
@@ -0,0 +1 @@
1
+ export { default, AccordionItem } from "./Accordion";
@@ -0,0 +1,106 @@
1
+ # ActionMenu
2
+
3
+ Contextual dropdown menu triggered by a button, for grouping actions. Also used internally by the `Dropdown` component for its options popover.
4
+
5
+ ## When to Use
6
+ - "More actions" menus on cards, table rows, or list items
7
+ - Context menus with multiple actions
8
+ - Overflow menus in toolbars
9
+ - As the internal popup engine inside `Dropdown` (automatically — you don't compose it manually)
10
+
11
+ ## Props
12
+
13
+ | Prop | Type | Default | Description |
14
+ |------|------|---------|-------------|
15
+ | `trigger` | `ReactNode` | — | Element that opens the menu (usually a Button) |
16
+ | `items` | `array` | `[]` | Menu items (see Item Object) |
17
+ | `placement` | `string` | `"bottom-end"` | Menu placement: `"bottom-start"`, `"bottom-end"`, `"top-start"`, `"top-end"` |
18
+ | `fullWidth` | `boolean` | `false` | When `true`, menu stretches to match the trigger width |
19
+ | `disabled` | `boolean` | `false` | Whether the menu is disabled |
20
+ | `onOpenChange` | `function` | — | Callback when open state changes: `(isOpen: boolean) => void` |
21
+ | `className` | `string` | `""` | Additional CSS classes on the root wrapper |
22
+ | `menuClassName` | `string` | `""` | Additional CSS classes on the menu panel |
23
+
24
+ ### Item Object
25
+
26
+ | Property | Type | Description |
27
+ |----------|------|-------------|
28
+ | `label` | `string` | Item text |
29
+ | `icon` | `string` | Phosphor icon name |
30
+ | `onClick` | `function` | Click handler |
31
+ | `shortcut` | `string` | Keyboard shortcut label (rendered with `Key` component) |
32
+ | `active` | `boolean` | Active/selected state |
33
+ | `destructive` | `boolean` | Destructive/danger styling |
34
+ | `disabled` | `boolean` | Disabled state |
35
+ | `divider` | `boolean` | Render as divider instead of item |
36
+ | `items` | `array` | Nested submenu items |
37
+
38
+ ## Examples
39
+
40
+ ### Basic action menu
41
+ ```jsx
42
+ <ActionMenu
43
+ trigger={<Button layout="icon-only" icon="DotsThree" appearance="ghost" />}
44
+ items={[
45
+ { label: "Edit", icon: "PencilSimple", onClick: handleEdit },
46
+ { label: "Duplicate", icon: "Copy", onClick: handleDuplicate },
47
+ { divider: true },
48
+ { label: "Delete", icon: "Trash", destructive: true, onClick: handleDelete },
49
+ ]}
50
+ />
51
+ ```
52
+
53
+ ### Full-width menu
54
+ ```jsx
55
+ <ActionMenu
56
+ trigger={<Button>Choose Action</Button>}
57
+ items={actions}
58
+ fullWidth
59
+ placement="bottom-start"
60
+ />
61
+ ```
62
+
63
+ ### Listening to open/close
64
+ ```jsx
65
+ <ActionMenu
66
+ trigger={<Button icon="Gear">Settings</Button>}
67
+ items={settingsItems}
68
+ onOpenChange={(isOpen) => console.log("Menu open:", isOpen)}
69
+ />
70
+ ```
71
+
72
+ ### In a table row
73
+ ```jsx
74
+ const columns = [
75
+ // ...other columns
76
+ {
77
+ key: "actions",
78
+ label: "",
79
+ render: (_, row) => (
80
+ <ActionMenu
81
+ trigger={<Button layout="icon-only" icon="DotsThree" appearance="ghost" size="small" />}
82
+ items={[
83
+ { label: "View", onClick: () => navigate(`/items/${row.id}`) },
84
+ { label: "Edit", onClick: () => openEdit(row) },
85
+ { divider: true },
86
+ { label: "Delete", destructive: true, onClick: () => deleteItem(row.id) },
87
+ ]}
88
+ placement="bottom-end"
89
+ />
90
+ ),
91
+ },
92
+ ];
93
+ ```
94
+
95
+ ## Architecture Note
96
+
97
+ The `Dropdown` component composes ActionMenu internally — it maps its `options` into ActionMenu `items` and passes its select-style trigger button as ActionMenu's `trigger`. This means both components share a single popup engine for click-outside, keyboard navigation, and focus management, while remaining fully independent for consumers.
98
+
99
+ ## Do's and Don'ts
100
+
101
+ ✅ **Do**: Use a `Button` as the trigger element
102
+ ✅ **Do**: Use `fullWidth` + `placement="bottom-start"` when the menu should match the trigger width
103
+ ✅ **Do**: Use `onOpenChange` when you need to react to open/close state externally
104
+
105
+ ❌ **Don't**: Use ActionMenu for value selection in forms — use `Dropdown` instead
106
+ ❌ **Don't**: Add both `disabled` prop and disable the trigger — just use ActionMenu's `disabled`