@mindlogic-ai/logician-ui 5.0.0-alpha.2 → 5.0.0-alpha.20

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 (525) hide show
  1. package/README.md +1 -0
  2. package/dist/components/Avatar/Avatar.d.ts +68 -11
  3. package/dist/components/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/components/Avatar/Avatar.js +41 -5
  5. package/dist/components/Avatar/Avatar.js.map +1 -1
  6. package/dist/components/Avatar/Avatar.mjs +40 -5
  7. package/dist/components/Avatar/Avatar.mjs.map +1 -1
  8. package/dist/components/Avatar/index.d.ts +2 -2
  9. package/dist/components/Avatar/index.d.ts.map +1 -1
  10. package/dist/components/Badge/Badge.d.ts.map +1 -1
  11. package/dist/components/Badge/Badge.js +5 -3
  12. package/dist/components/Badge/Badge.js.map +1 -1
  13. package/dist/components/Badge/Badge.mjs +5 -3
  14. package/dist/components/Badge/Badge.mjs.map +1 -1
  15. package/dist/components/Badge/Badge.types.d.ts +7 -5
  16. package/dist/components/Badge/Badge.types.d.ts.map +1 -1
  17. package/dist/components/Banner/Banner.types.d.ts +24 -1
  18. package/dist/components/Banner/Banner.types.d.ts.map +1 -1
  19. package/dist/components/BottomSheet/BottomSheet.styles.d.ts +2 -2
  20. package/dist/components/Button/Button.d.ts.map +1 -1
  21. package/dist/components/Button/Button.js +31 -3
  22. package/dist/components/Button/Button.js.map +1 -1
  23. package/dist/components/Button/Button.mjs +31 -3
  24. package/dist/components/Button/Button.mjs.map +1 -1
  25. package/dist/components/Button/Button.types.d.ts +38 -1
  26. package/dist/components/Button/Button.types.d.ts.map +1 -1
  27. package/dist/components/Card/Card.types.d.ts +12 -0
  28. package/dist/components/Card/Card.types.d.ts.map +1 -1
  29. package/dist/components/CodeTabs/CodeTabs.styles.d.ts +6 -5
  30. package/dist/components/CodeTabs/CodeTabs.styles.d.ts.map +1 -1
  31. package/dist/components/CodeTabs/CodeTabs.styles.js +6 -5
  32. package/dist/components/CodeTabs/CodeTabs.styles.js.map +1 -1
  33. package/dist/components/CodeTabs/CodeTabs.styles.mjs +6 -5
  34. package/dist/components/CodeTabs/CodeTabs.styles.mjs.map +1 -1
  35. package/dist/components/ColorMode/ColorModeToggle.d.ts +7 -2
  36. package/dist/components/ColorMode/ColorModeToggle.d.ts.map +1 -1
  37. package/dist/components/ColorMode/ColorModeToggle.js +8 -3
  38. package/dist/components/ColorMode/ColorModeToggle.js.map +1 -1
  39. package/dist/components/ColorMode/ColorModeToggle.mjs +8 -3
  40. package/dist/components/ColorMode/ColorModeToggle.mjs.map +1 -1
  41. package/dist/components/Confetti/Confetti.types.d.ts +5 -1
  42. package/dist/components/Confetti/Confetti.types.d.ts.map +1 -1
  43. package/dist/components/Confetti/confettiColors.d.ts +5 -5
  44. package/dist/components/Confetti/confettiColors.js +5 -5
  45. package/dist/components/Confetti/confettiColors.mjs +5 -5
  46. package/dist/components/ErrorFallback/ErrorFallback.types.d.ts +6 -0
  47. package/dist/components/ErrorFallback/ErrorFallback.types.d.ts.map +1 -1
  48. package/dist/components/Form/FormModalFooter/FormModalFooter.d.ts +1 -1
  49. package/dist/components/Form/FormModalFooter/FormModalFooter.d.ts.map +1 -1
  50. package/dist/components/Form/FormModalFooter/FormModalFooter.js +2 -2
  51. package/dist/components/Form/FormModalFooter/FormModalFooter.js.map +1 -1
  52. package/dist/components/Form/FormModalFooter/FormModalFooter.mjs +2 -2
  53. package/dist/components/Form/FormModalFooter/FormModalFooter.mjs.map +1 -1
  54. package/dist/components/Form/FormModalFooter/FormModalFooter.types.d.ts +11 -1
  55. package/dist/components/Form/FormModalFooter/FormModalFooter.types.d.ts.map +1 -1
  56. package/dist/components/Form/FormSection/CollapsibleFormSection.js +1 -0
  57. package/dist/components/Form/FormSection/CollapsibleFormSection.js.map +1 -1
  58. package/dist/components/Form/FormSection/CollapsibleFormSection.mjs +1 -0
  59. package/dist/components/Form/FormSection/CollapsibleFormSection.mjs.map +1 -1
  60. package/dist/components/Input/Input.d.ts.map +1 -1
  61. package/dist/components/Input/Input.js +4 -0
  62. package/dist/components/Input/Input.js.map +1 -1
  63. package/dist/components/Input/Input.mjs +4 -0
  64. package/dist/components/Input/Input.mjs.map +1 -1
  65. package/dist/components/LineGraph/LineGraph.d.ts.map +1 -1
  66. package/dist/components/LineGraph/LineGraph.js +4 -5
  67. package/dist/components/LineGraph/LineGraph.js.map +1 -1
  68. package/dist/components/LineGraph/LineGraph.mjs +5 -6
  69. package/dist/components/LineGraph/LineGraph.mjs.map +1 -1
  70. package/dist/components/LineGraph/LineGraph.types.d.ts +12 -2
  71. package/dist/components/LineGraph/LineGraph.types.d.ts.map +1 -1
  72. package/dist/components/LineGraph/seriesColors.d.ts +12 -8
  73. package/dist/components/LineGraph/seriesColors.d.ts.map +1 -1
  74. package/dist/components/LineGraph/seriesColors.js +8 -7
  75. package/dist/components/LineGraph/seriesColors.js.map +1 -1
  76. package/dist/components/LineGraph/seriesColors.mjs +8 -7
  77. package/dist/components/LineGraph/seriesColors.mjs.map +1 -1
  78. package/dist/components/Masonry/Masonry.types.d.ts +8 -3
  79. package/dist/components/Masonry/Masonry.types.d.ts.map +1 -1
  80. package/dist/components/Menu/MenuItem.types.d.ts +8 -0
  81. package/dist/components/Menu/MenuItem.types.d.ts.map +1 -1
  82. package/dist/components/Modal/ModalCloseButton.d.ts +1 -1
  83. package/dist/components/Modal/ModalCloseButton.js +1 -1
  84. package/dist/components/Modal/ModalCloseButton.mjs +1 -1
  85. package/dist/components/NavList/NavList.d.ts +35 -0
  86. package/dist/components/NavList/NavList.d.ts.map +1 -0
  87. package/dist/components/NavList/NavList.js +113 -0
  88. package/dist/components/NavList/NavList.js.map +1 -0
  89. package/dist/components/NavList/NavList.mjs +111 -0
  90. package/dist/components/NavList/NavList.mjs.map +1 -0
  91. package/dist/components/NavList/NavList.styles.d.ts +90 -0
  92. package/dist/components/NavList/NavList.styles.d.ts.map +1 -0
  93. package/dist/components/NavList/NavList.styles.js +104 -0
  94. package/dist/components/NavList/NavList.styles.js.map +1 -0
  95. package/dist/components/NavList/NavList.styles.mjs +97 -0
  96. package/dist/components/NavList/NavList.styles.mjs.map +1 -0
  97. package/dist/components/NavList/NavList.translations.json.js +19 -0
  98. package/dist/components/NavList/NavList.translations.json.js.map +1 -0
  99. package/dist/components/NavList/NavList.translations.json.mjs +14 -0
  100. package/dist/components/NavList/NavList.translations.json.mjs.map +1 -0
  101. package/dist/components/NavList/NavList.types.d.ts +140 -0
  102. package/dist/components/NavList/NavList.types.d.ts.map +1 -0
  103. package/dist/components/NavList/NavListContext.d.ts +30 -0
  104. package/dist/components/NavList/NavListContext.d.ts.map +1 -0
  105. package/dist/components/NavList/NavListContext.js +16 -0
  106. package/dist/components/NavList/NavListContext.js.map +1 -0
  107. package/dist/components/NavList/NavListContext.mjs +13 -0
  108. package/dist/components/NavList/NavListContext.mjs.map +1 -0
  109. package/dist/components/NavList/NavListGroup.d.ts +31 -0
  110. package/dist/components/NavList/NavListGroup.d.ts.map +1 -0
  111. package/dist/components/NavList/NavListGroup.js +115 -0
  112. package/dist/components/NavList/NavListGroup.js.map +1 -0
  113. package/dist/components/NavList/NavListGroup.mjs +113 -0
  114. package/dist/components/NavList/NavListGroup.mjs.map +1 -0
  115. package/dist/components/NavList/NavListItem.d.ts +16 -0
  116. package/dist/components/NavList/NavListItem.d.ts.map +1 -0
  117. package/dist/components/NavList/NavListItem.js +284 -0
  118. package/dist/components/NavList/NavListItem.js.map +1 -0
  119. package/dist/components/NavList/NavListItem.mjs +282 -0
  120. package/dist/components/NavList/NavListItem.mjs.map +1 -0
  121. package/dist/components/NavList/NavListSkeleton.d.ts +17 -0
  122. package/dist/components/NavList/NavListSkeleton.d.ts.map +1 -0
  123. package/dist/components/NavList/NavListSkeleton.js +33 -0
  124. package/dist/components/NavList/NavListSkeleton.js.map +1 -0
  125. package/dist/components/NavList/NavListSkeleton.mjs +31 -0
  126. package/dist/components/NavList/NavListSkeleton.mjs.map +1 -0
  127. package/dist/components/NavList/index.d.ts +7 -0
  128. package/dist/components/NavList/index.d.ts.map +1 -0
  129. package/dist/components/Pagination/Pagination.d.ts +11 -10
  130. package/dist/components/Pagination/Pagination.d.ts.map +1 -1
  131. package/dist/components/Pagination/Pagination.js +11 -10
  132. package/dist/components/Pagination/Pagination.js.map +1 -1
  133. package/dist/components/Pagination/Pagination.mjs +11 -10
  134. package/dist/components/Pagination/Pagination.mjs.map +1 -1
  135. package/dist/components/ProgressBar/ProgressBar.types.d.ts +9 -0
  136. package/dist/components/ProgressBar/ProgressBar.types.d.ts.map +1 -1
  137. package/dist/components/RadialProgress/RadialProgress.types.d.ts +21 -1
  138. package/dist/components/RadialProgress/RadialProgress.types.d.ts.map +1 -1
  139. package/dist/components/SeeMoreButton/SeeMoreButton.types.d.ts +8 -0
  140. package/dist/components/SeeMoreButton/SeeMoreButton.types.d.ts.map +1 -1
  141. package/dist/components/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  142. package/dist/components/SegmentedControl/SegmentedControl.js +6 -7
  143. package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
  144. package/dist/components/SegmentedControl/SegmentedControl.mjs +6 -7
  145. package/dist/components/SegmentedControl/SegmentedControl.mjs.map +1 -1
  146. package/dist/components/SegmentedProgressBar/SegmentedProgressBar.types.d.ts +2 -0
  147. package/dist/components/SegmentedProgressBar/SegmentedProgressBar.types.d.ts.map +1 -1
  148. package/dist/components/Select/Combobox.d.ts +1 -1
  149. package/dist/components/Select/Combobox.d.ts.map +1 -1
  150. package/dist/components/Select/Combobox.js +9 -2
  151. package/dist/components/Select/Combobox.js.map +1 -1
  152. package/dist/components/Select/Combobox.mjs +10 -3
  153. package/dist/components/Select/Combobox.mjs.map +1 -1
  154. package/dist/components/Select/Select.d.ts +1 -1
  155. package/dist/components/Select/Select.d.ts.map +1 -1
  156. package/dist/components/Select/Select.js +14 -2
  157. package/dist/components/Select/Select.js.map +1 -1
  158. package/dist/components/Select/Select.mjs +15 -3
  159. package/dist/components/Select/Select.mjs.map +1 -1
  160. package/dist/components/Select/Select.styles.d.ts +97 -1
  161. package/dist/components/Select/Select.styles.d.ts.map +1 -1
  162. package/dist/components/Select/Select.styles.js +83 -0
  163. package/dist/components/Select/Select.styles.js.map +1 -1
  164. package/dist/components/Select/Select.styles.mjs +82 -1
  165. package/dist/components/Select/Select.styles.mjs.map +1 -1
  166. package/dist/components/Tabs/Tab/Tab.styles.d.ts +1 -1
  167. package/dist/components/Tabs/Tab/Tab.styles.js +1 -1
  168. package/dist/components/Tabs/Tab/Tab.styles.mjs +1 -1
  169. package/dist/components/Textarea/Textarea.d.ts.map +1 -1
  170. package/dist/components/Textarea/Textarea.js +4 -0
  171. package/dist/components/Textarea/Textarea.js.map +1 -1
  172. package/dist/components/Textarea/Textarea.mjs +4 -0
  173. package/dist/components/Textarea/Textarea.mjs.map +1 -1
  174. package/dist/components/Toast/Toast.styles.d.ts +6 -2
  175. package/dist/components/Toast/Toast.styles.d.ts.map +1 -1
  176. package/dist/components/Toast/Toast.styles.js +18 -10
  177. package/dist/components/Toast/Toast.styles.js.map +1 -1
  178. package/dist/components/Toast/Toast.styles.mjs +18 -10
  179. package/dist/components/Toast/Toast.styles.mjs.map +1 -1
  180. package/dist/components/Typography/Caption.d.ts.map +1 -1
  181. package/dist/components/Typography/Caption.js +1 -1
  182. package/dist/components/Typography/Caption.js.map +1 -1
  183. package/dist/components/Typography/Caption.mjs +1 -1
  184. package/dist/components/Typography/Caption.mjs.map +1 -1
  185. package/dist/components/Typography/H1.d.ts.map +1 -1
  186. package/dist/components/Typography/H1.js +1 -1
  187. package/dist/components/Typography/H1.js.map +1 -1
  188. package/dist/components/Typography/H1.mjs +1 -1
  189. package/dist/components/Typography/H1.mjs.map +1 -1
  190. package/dist/components/Typography/H2.d.ts.map +1 -1
  191. package/dist/components/Typography/H2.js +1 -1
  192. package/dist/components/Typography/H2.js.map +1 -1
  193. package/dist/components/Typography/H2.mjs +1 -1
  194. package/dist/components/Typography/H2.mjs.map +1 -1
  195. package/dist/components/Typography/H3.d.ts.map +1 -1
  196. package/dist/components/Typography/H3.js +1 -1
  197. package/dist/components/Typography/H3.js.map +1 -1
  198. package/dist/components/Typography/H3.mjs +1 -1
  199. package/dist/components/Typography/H3.mjs.map +1 -1
  200. package/dist/components/Typography/H4.d.ts.map +1 -1
  201. package/dist/components/Typography/H4.js +1 -1
  202. package/dist/components/Typography/H4.js.map +1 -1
  203. package/dist/components/Typography/H4.mjs +1 -1
  204. package/dist/components/Typography/H4.mjs.map +1 -1
  205. package/dist/components/Typography/H5.d.ts.map +1 -1
  206. package/dist/components/Typography/H5.js +1 -1
  207. package/dist/components/Typography/H5.js.map +1 -1
  208. package/dist/components/Typography/H5.mjs +1 -1
  209. package/dist/components/Typography/H5.mjs.map +1 -1
  210. package/dist/components/Typography/Link.d.ts.map +1 -1
  211. package/dist/components/Typography/Link.js +1 -1
  212. package/dist/components/Typography/Link.js.map +1 -1
  213. package/dist/components/Typography/Link.mjs +1 -1
  214. package/dist/components/Typography/Link.mjs.map +1 -1
  215. package/dist/components/Typography/Overline.d.ts.map +1 -1
  216. package/dist/components/Typography/Overline.js +1 -1
  217. package/dist/components/Typography/Overline.js.map +1 -1
  218. package/dist/components/Typography/Overline.mjs +1 -1
  219. package/dist/components/Typography/Overline.mjs.map +1 -1
  220. package/dist/components/Typography/Subtext.d.ts.map +1 -1
  221. package/dist/components/Typography/Subtext.js +1 -1
  222. package/dist/components/Typography/Subtext.js.map +1 -1
  223. package/dist/components/Typography/Subtext.mjs +1 -1
  224. package/dist/components/Typography/Subtext.mjs.map +1 -1
  225. package/dist/components/Typography/Subtitle.d.ts.map +1 -1
  226. package/dist/components/Typography/Subtitle.js +1 -1
  227. package/dist/components/Typography/Subtitle.js.map +1 -1
  228. package/dist/components/Typography/Subtitle.mjs +1 -1
  229. package/dist/components/Typography/Subtitle.mjs.map +1 -1
  230. package/dist/components/Typography/Text.d.ts.map +1 -1
  231. package/dist/components/Typography/Text.js +1 -1
  232. package/dist/components/Typography/Text.js.map +1 -1
  233. package/dist/components/Typography/Text.mjs +1 -1
  234. package/dist/components/Typography/Text.mjs.map +1 -1
  235. package/dist/hooks/useLanguage.d.ts +5 -0
  236. package/dist/hooks/useLanguage.d.ts.map +1 -1
  237. package/dist/hooks/useLanguage.js +7 -3
  238. package/dist/hooks/useLanguage.js.map +1 -1
  239. package/dist/hooks/useLanguage.mjs +7 -4
  240. package/dist/hooks/useLanguage.mjs.map +1 -1
  241. package/dist/hooks/useTranslate.d.ts.map +1 -1
  242. package/dist/hooks/useTranslate.js +8 -5
  243. package/dist/hooks/useTranslate.js.map +1 -1
  244. package/dist/hooks/useTranslate.mjs +8 -5
  245. package/dist/hooks/useTranslate.mjs.map +1 -1
  246. package/dist/index.d.ts +2 -1
  247. package/dist/index.d.ts.map +1 -1
  248. package/dist/index.js +13 -0
  249. package/dist/index.js.map +1 -1
  250. package/dist/index.mjs +7 -2
  251. package/dist/index.mjs.map +1 -1
  252. package/dist/theme/colors.d.ts +2 -2
  253. package/dist/theme/colors.d.ts.map +1 -1
  254. package/dist/theme/colors.js +54 -18
  255. package/dist/theme/colors.js.map +1 -1
  256. package/dist/theme/colors.mjs +55 -19
  257. package/dist/theme/colors.mjs.map +1 -1
  258. package/dist/theme/global.d.ts.map +1 -1
  259. package/dist/theme/global.js +19 -1
  260. package/dist/theme/global.js.map +1 -1
  261. package/dist/theme/global.mjs +19 -1
  262. package/dist/theme/global.mjs.map +1 -1
  263. package/dist/theme/index.d.ts.map +1 -1
  264. package/dist/theme/index.js +2 -0
  265. package/dist/theme/index.js.map +1 -1
  266. package/dist/theme/index.mjs +2 -0
  267. package/dist/theme/index.mjs.map +1 -1
  268. package/dist/theme/palette.generated.d.ts +232 -123
  269. package/dist/theme/palette.generated.d.ts.map +1 -1
  270. package/dist/theme/palette.generated.js +233 -123
  271. package/dist/theme/palette.generated.js.map +1 -1
  272. package/dist/theme/palette.generated.mjs +233 -124
  273. package/dist/theme/palette.generated.mjs.map +1 -1
  274. package/dist/theme/paletteSwatches.d.ts +20 -0
  275. package/dist/theme/paletteSwatches.d.ts.map +1 -1
  276. package/dist/theme/recipes/avatar.d.ts +30 -0
  277. package/dist/theme/recipes/avatar.d.ts.map +1 -0
  278. package/dist/theme/recipes/avatar.js +96 -0
  279. package/dist/theme/recipes/avatar.js.map +1 -0
  280. package/dist/theme/recipes/avatar.mjs +94 -0
  281. package/dist/theme/recipes/avatar.mjs.map +1 -0
  282. package/dist/translations/Defaults.translations.json.js +19 -1
  283. package/dist/translations/Defaults.translations.json.js.map +1 -1
  284. package/dist/translations/Defaults.translations.json.mjs +18 -2
  285. package/dist/translations/Defaults.translations.json.mjs.map +1 -1
  286. package/dist/utils/disabledControl.d.ts +8 -1
  287. package/dist/utils/disabledControl.d.ts.map +1 -1
  288. package/dist/utils/disabledControl.js +8 -1
  289. package/dist/utils/disabledControl.js.map +1 -1
  290. package/dist/utils/disabledControl.mjs +8 -1
  291. package/dist/utils/disabledControl.mjs.map +1 -1
  292. package/dist/utils/focusRing.d.ts +22 -0
  293. package/dist/utils/focusRing.d.ts.map +1 -1
  294. package/dist/utils/focusRing.js +22 -0
  295. package/dist/utils/focusRing.js.map +1 -1
  296. package/dist/utils/focusRing.mjs +21 -1
  297. package/dist/utils/focusRing.mjs.map +1 -1
  298. package/package.json +2 -1
  299. package/src/components/Accordion/Accordion.stories.tsx +85 -0
  300. package/src/components/Accordion/Accordion.usage.mdx +200 -0
  301. package/src/components/Appear/Appear.usage.mdx +107 -0
  302. package/src/components/Avatar/Avatar.recipe.test.tsx +176 -0
  303. package/src/components/Avatar/Avatar.stories.tsx +199 -24
  304. package/src/components/Avatar/Avatar.tsx +118 -21
  305. package/src/components/Avatar/Avatar.usage.mdx +185 -0
  306. package/src/components/Avatar/index.tsx +8 -1
  307. package/src/components/Badge/Badge.stories.tsx +193 -3
  308. package/src/components/Badge/Badge.tsx +5 -3
  309. package/src/components/Badge/Badge.types.ts +7 -5
  310. package/src/components/Badge/Badge.usage.mdx +265 -0
  311. package/src/components/Banner/Banner.stories.tsx +152 -2
  312. package/src/components/Banner/Banner.types.ts +30 -1
  313. package/src/components/Banner/Banner.usage.mdx +233 -0
  314. package/src/components/BottomSheet/BottomSheet.stories.tsx +168 -1
  315. package/src/components/BottomSheet/BottomSheet.test.tsx +2 -1
  316. package/src/components/BottomSheet/BottomSheet.usage.mdx +216 -0
  317. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +59 -0
  318. package/src/components/Breadcrumb/Breadcrumb.usage.mdx +181 -0
  319. package/src/components/Button/Button.focusableWhenDisabled.test.tsx +218 -0
  320. package/src/components/Button/Button.stories.tsx +332 -3
  321. package/src/components/Button/Button.tsx +46 -3
  322. package/src/components/Button/Button.types.ts +38 -1
  323. package/src/components/Button/Button.usage.mdx +358 -0
  324. package/src/components/Button/Button.variants.test.tsx +13 -1
  325. package/src/components/Card/Card.stories.tsx +106 -0
  326. package/src/components/Card/Card.types.ts +12 -0
  327. package/src/components/Card/Card.usage.mdx +216 -0
  328. package/src/components/Checkbox/Checkbox.stories.tsx +140 -13
  329. package/src/components/Checkbox/Checkbox.usage.mdx +214 -0
  330. package/src/components/Chip/Chip.usage.mdx +78 -0
  331. package/src/components/Code/Code.stories.tsx +60 -0
  332. package/src/components/Code/Code.usage.mdx +187 -0
  333. package/src/components/CodeTabs/CodeTabs.stories.tsx +53 -0
  334. package/src/components/CodeTabs/CodeTabs.styles.ts +6 -5
  335. package/src/components/CodeTabs/CodeTabs.usage.mdx +176 -0
  336. package/src/components/Collapsible/Collapsible.stories.tsx +58 -0
  337. package/src/components/Collapsible/Collapsible.usage.mdx +173 -0
  338. package/src/components/ColorMode/ColorMode.stories.tsx +50 -0
  339. package/src/components/ColorMode/ColorMode.usage.mdx +135 -0
  340. package/src/components/ColorMode/ColorModeToggle.tsx +10 -3
  341. package/src/components/Confetti/Confetti.types.ts +5 -1
  342. package/src/components/Confetti/Confetti.usage.mdx +111 -0
  343. package/src/components/Confetti/confettiColors.ts +5 -5
  344. package/src/components/Container/Container.stories.tsx +32 -0
  345. package/src/components/Container/Container.usage.mdx +130 -0
  346. package/src/components/CopyableCode/CopyableCode.stories.tsx +62 -0
  347. package/src/components/CopyableCode/CopyableCode.usage.mdx +168 -0
  348. package/src/components/CountBadge/CountBadge.stories.tsx +69 -0
  349. package/src/components/CountBadge/CountBadge.usage.mdx +215 -0
  350. package/src/components/CountUp/CountUp.usage.mdx +107 -0
  351. package/src/components/DatePicker/DatePicker.usage.mdx +177 -0
  352. package/src/components/DatePicker/RangeDatePicker.stories.tsx +87 -3
  353. package/src/components/ErrorFallback/ErrorFallback.types.ts +6 -0
  354. package/src/components/ErrorFallback/ErrorFallback.usage.mdx +127 -0
  355. package/src/components/ExpandableText/ExpandableText.stories.tsx +55 -0
  356. package/src/components/ExpandableText/ExpandableText.usage.mdx +176 -0
  357. package/src/components/FileInput/FileInput.stories.tsx +38 -1
  358. package/src/components/FileInput/FileInput.usage.mdx +178 -0
  359. package/src/components/FileItem/FileItem.stories.tsx +71 -0
  360. package/src/components/FileItem/FileItem.usage.mdx +180 -0
  361. package/src/components/FileList/FileList.stories.tsx +25 -0
  362. package/src/components/FileList/FileList.usage.mdx +165 -0
  363. package/src/components/FlyTo/FlyTo.usage.mdx +99 -0
  364. package/src/components/Form/Form.stories.tsx +149 -0
  365. package/src/components/Form/Form.usage.mdx +203 -0
  366. package/src/components/Form/FormModalFooter/FormModalFooter.stories.tsx +1 -1
  367. package/src/components/Form/FormModalFooter/FormModalFooter.test.tsx +19 -1
  368. package/src/components/Form/FormModalFooter/FormModalFooter.tsx +2 -0
  369. package/src/components/Form/FormModalFooter/FormModalFooter.types.ts +11 -1
  370. package/src/components/FormControl/FormControl.stories.tsx +35 -0
  371. package/src/components/FormControl/FormControl.usage.mdx +128 -0
  372. package/src/components/FormIntegration/FormIntegration.usage.mdx +158 -0
  373. package/src/components/FormLabel/FormLabel.stories.tsx +71 -0
  374. package/src/components/FormLabel/FormLabel.usage.mdx +125 -0
  375. package/src/components/Icon/Icon.stories.tsx +61 -1
  376. package/src/components/Icon/Icon.usage.mdx +158 -0
  377. package/src/components/IconButton/IconButton.stories.tsx +213 -5
  378. package/src/components/IconButton/IconButton.usage.mdx +275 -0
  379. package/src/components/InfoSprinkle/InfoSprinkle.stories.tsx +77 -1
  380. package/src/components/InfoSprinkle/InfoSprinkle.usage.mdx +189 -0
  381. package/src/components/InlineCode/InlineCode.stories.tsx +75 -0
  382. package/src/components/InlineCode/InlineCode.usage.mdx +142 -0
  383. package/src/components/Input/Input.stories.tsx +180 -0
  384. package/src/components/Input/Input.tsx +4 -0
  385. package/src/components/Input/Input.usage.mdx +278 -0
  386. package/src/components/LineGraph/LineGraph.stories.tsx +112 -0
  387. package/src/components/LineGraph/LineGraph.tsx +4 -5
  388. package/src/components/LineGraph/LineGraph.types.ts +12 -2
  389. package/src/components/LineGraph/LineGraph.usage.mdx +186 -0
  390. package/src/components/LineGraph/seriesColors.test.ts +10 -9
  391. package/src/components/LineGraph/seriesColors.ts +18 -16
  392. package/src/components/Loaders/Loaders.stories.tsx +93 -0
  393. package/src/components/Loaders/Loaders.usage.mdx +180 -0
  394. package/src/components/LogicianProvider/LogicianProvider.usage.mdx +98 -0
  395. package/src/components/Markdown/Markdown.stories.tsx +53 -0
  396. package/src/components/Markdown/Markdown.usage.mdx +182 -0
  397. package/src/components/Masonry/Masonry.stories.tsx +63 -1
  398. package/src/components/Masonry/Masonry.types.ts +8 -3
  399. package/src/components/Masonry/Masonry.usage.mdx +142 -0
  400. package/src/components/MaxLengthIndicator/MaxLengthIndicator.stories.tsx +57 -0
  401. package/src/components/MaxLengthIndicator/MaxLengthIndicator.usage.mdx +125 -0
  402. package/src/components/Menu/Menu.stories.tsx +146 -2
  403. package/src/components/Menu/Menu.usage.mdx +238 -0
  404. package/src/components/Menu/MenuItem.types.ts +8 -0
  405. package/src/components/Modal/Modal.stories.tsx +177 -1
  406. package/src/components/Modal/Modal.usage.mdx +262 -0
  407. package/src/components/Modal/ModalCloseButton.tsx +1 -1
  408. package/src/components/MonthPicker/MonthPicker.stories.tsx +30 -0
  409. package/src/components/MonthPicker/MonthPicker.usage.mdx +191 -0
  410. package/src/components/NavList/NavList.stories.tsx +927 -0
  411. package/src/components/NavList/NavList.styles.ts +114 -0
  412. package/src/components/NavList/NavList.test.tsx +1306 -0
  413. package/src/components/NavList/NavList.translations.json +9 -0
  414. package/src/components/NavList/NavList.tsx +160 -0
  415. package/src/components/NavList/NavList.types.ts +155 -0
  416. package/src/components/NavList/NavList.usage.mdx +545 -0
  417. package/src/components/NavList/NavListContext.ts +25 -0
  418. package/src/components/NavList/NavListGroup.tsx +243 -0
  419. package/src/components/NavList/NavListItem.tsx +543 -0
  420. package/src/components/NavList/NavListSkeleton.tsx +57 -0
  421. package/src/components/NavList/index.ts +15 -0
  422. package/src/components/Pagination/Pagination.stories.tsx +90 -1
  423. package/src/components/Pagination/Pagination.tsx +11 -10
  424. package/src/components/Pagination/Pagination.usage.mdx +186 -0
  425. package/src/components/PasswordInput/PasswordInput.stories.tsx +51 -0
  426. package/src/components/PasswordInput/PasswordInput.usage.mdx +193 -0
  427. package/src/components/PinInput/PinInput.stories.tsx +91 -0
  428. package/src/components/PinInput/PinInput.usage.mdx +194 -0
  429. package/src/components/Popover/Popover.stories.tsx +104 -1
  430. package/src/components/Popover/Popover.usage.mdx +197 -0
  431. package/src/components/ProgressBar/ProgressBar.stories.tsx +92 -1
  432. package/src/components/ProgressBar/ProgressBar.types.ts +9 -0
  433. package/src/components/ProgressBar/ProgressBar.usage.mdx +210 -0
  434. package/src/components/Pulse/Pulse.usage.mdx +102 -0
  435. package/src/components/RadialProgress/RadialProgress.stories.tsx +74 -1
  436. package/src/components/RadialProgress/RadialProgress.types.ts +21 -1
  437. package/src/components/RadialProgress/RadialProgress.usage.mdx +153 -0
  438. package/src/components/Radio/Radio.stories.tsx +119 -0
  439. package/src/components/Radio/Radio.usage.mdx +187 -0
  440. package/src/components/Reveal/Reveal.usage.mdx +105 -0
  441. package/src/components/ScaledContext/ScaledContext.usage.mdx +111 -0
  442. package/src/components/SeeMoreButton/SeeMoreButton.stories.tsx +146 -2
  443. package/src/components/SeeMoreButton/SeeMoreButton.types.ts +8 -0
  444. package/src/components/SeeMoreButton/SeeMoreButton.usage.mdx +213 -0
  445. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +69 -0
  446. package/src/components/SegmentedControl/SegmentedControl.tsx +6 -7
  447. package/src/components/SegmentedControl/SegmentedControl.usage.mdx +209 -0
  448. package/src/components/SegmentedProgressBar/SegmentedProgressBar.stories.tsx +54 -0
  449. package/src/components/SegmentedProgressBar/SegmentedProgressBar.types.ts +2 -0
  450. package/src/components/SegmentedProgressBar/SegmentedProgressBar.usage.mdx +145 -0
  451. package/src/components/Select/Combobox.tsx +28 -3
  452. package/src/components/Select/Select.clearTrigger.test.tsx +76 -0
  453. package/src/components/Select/Select.stories.tsx +290 -1
  454. package/src/components/Select/Select.styles.ts +89 -0
  455. package/src/components/Select/Select.tsx +28 -2
  456. package/src/components/Select/Select.usage.mdx +341 -0
  457. package/src/components/Shake/Shake.usage.mdx +107 -0
  458. package/src/components/Slider/Slider.stories.tsx +116 -0
  459. package/src/components/Slider/Slider.usage.mdx +179 -0
  460. package/src/components/Spinner/Spinner.stories.tsx +64 -0
  461. package/src/components/Spinner/Spinner.usage.mdx +136 -0
  462. package/src/components/SwapTransition/SwapTransition.usage.mdx +102 -0
  463. package/src/components/Switch/Switch.stories.tsx +131 -6
  464. package/src/components/Switch/Switch.usage.mdx +199 -0
  465. package/src/components/Table/Table.stories.tsx +159 -1
  466. package/src/components/Table/Table.usage.mdx +235 -0
  467. package/src/components/Tabs/Tab/Tab.styles.ts +1 -1
  468. package/src/components/Tabs/Tabs.stories.tsx +86 -0
  469. package/src/components/Tabs/Tabs.usage.mdx +263 -0
  470. package/src/components/Tag/Tag.stories.tsx +181 -4
  471. package/src/components/Tag/Tag.usage.mdx +257 -0
  472. package/src/components/Textarea/Textarea.stories.tsx +113 -0
  473. package/src/components/Textarea/Textarea.tsx +4 -0
  474. package/src/components/Textarea/Textarea.usage.mdx +186 -0
  475. package/src/components/Toast/Toast.stories.tsx +185 -3
  476. package/src/components/Toast/Toast.styles.ts +18 -10
  477. package/src/components/Toast/Toast.usage.mdx +265 -0
  478. package/src/components/Tooltip/Tooltip.stories.tsx +86 -1
  479. package/src/components/Tooltip/Tooltip.usage.mdx +219 -0
  480. package/src/components/Tree/Tree.stories.tsx +89 -0
  481. package/src/components/Tree/Tree.usage.mdx +207 -0
  482. package/src/components/Typography/Caption.tsx +0 -1
  483. package/src/components/Typography/H1.tsx +0 -1
  484. package/src/components/Typography/H2.tsx +0 -1
  485. package/src/components/Typography/H3.tsx +0 -1
  486. package/src/components/Typography/H4.tsx +0 -1
  487. package/src/components/Typography/H5.tsx +0 -1
  488. package/src/components/Typography/Link.tsx +0 -1
  489. package/src/components/Typography/Overline.tsx +0 -1
  490. package/src/components/Typography/Subtext.tsx +0 -1
  491. package/src/components/Typography/Subtitle.tsx +0 -1
  492. package/src/components/Typography/Text.tsx +0 -1
  493. package/src/components/Typography/Typography.stories.tsx +117 -0
  494. package/src/components/Typography/Typography.usage.mdx +257 -0
  495. package/src/components/Workflow/Workflow.usage.mdx +199 -0
  496. package/src/components/a11y.kwcag.test.tsx +66 -0
  497. package/src/components/claude.md +1 -1
  498. package/src/components/noRawScales.test.ts +5 -1
  499. package/src/foundations/BrandAssets.mdx +637 -0
  500. package/src/foundations/BrandAssets.stories.tsx +680 -0
  501. package/src/foundations/BrandColour.mdx +366 -0
  502. package/src/foundations/BrandColour.stories.tsx +343 -0
  503. package/src/guidelines/ComponentPageTemplate.mdx +84 -0
  504. package/src/guidelines/FeedbackActions.mdx +162 -23
  505. package/src/guidelines/_components/Lang.tsx +175 -0
  506. package/src/guidelines/_components/TokenTable.tsx +136 -0
  507. package/src/hooks/useLanguage.ts +8 -3
  508. package/src/hooks/useTranslate.test.tsx +46 -0
  509. package/src/hooks/useTranslate.ts +7 -5
  510. package/src/index.ts +7 -1
  511. package/src/theme/BazePalette.stories.tsx +111 -1
  512. package/src/theme/Palette.stories.tsx +2 -2
  513. package/src/theme/SemanticTokens.mdx +76 -17
  514. package/src/theme/claude.md +23 -9
  515. package/src/theme/colors.ts +71 -18
  516. package/src/theme/contrast.test.ts +57 -0
  517. package/src/theme/global.ts +20 -1
  518. package/src/theme/index.ts +2 -0
  519. package/src/theme/palette.generated.ts +233 -123
  520. package/src/theme/paletteSwatches.test.ts +1 -1
  521. package/src/theme/paletteSwatches.ts +35 -0
  522. package/src/theme/recipes/avatar.ts +92 -0
  523. package/src/translations/Defaults.translations.json +14 -0
  524. package/src/utils/disabledControl.ts +8 -1
  525. package/src/utils/focusRing.ts +23 -0
@@ -0,0 +1,543 @@
1
+ import {
2
+ AriaAttributes,
3
+ Children,
4
+ cloneElement,
5
+ forwardRef,
6
+ isValidElement,
7
+ MouseEvent,
8
+ MouseEventHandler,
9
+ ReactElement,
10
+ ReactNode,
11
+ SyntheticEvent,
12
+ useEffect,
13
+ useId,
14
+ useRef,
15
+ useState,
16
+ } from 'react';
17
+ import {
18
+ Box,
19
+ chakra,
20
+ LocaleProvider,
21
+ useLocaleContext,
22
+ VisuallyHidden,
23
+ } from '@chakra-ui/react';
24
+
25
+ import { Tooltip } from '@/components/Tooltip';
26
+ import { useTranslate } from '@/hooks/useTranslate';
27
+ import { disabledText } from '@/utils/disabledControl';
28
+ import { focusRingInset } from '@/utils/focusRing';
29
+
30
+ import {
31
+ byOrientation,
32
+ inheritDirection,
33
+ localeFor,
34
+ NAV_LIST_RAMP,
35
+ pressedFill,
36
+ } from './NavList.styles';
37
+ import NavListTranslations from './NavList.translations.json';
38
+ import { NavListItemProps } from './NavList.types';
39
+ import { useNavListContext } from './NavListContext';
40
+
41
+ /**
42
+ * One row: a link (`href`, or `asChild` around a router link) or, with only
43
+ * `onClick`, a `<button type="button">`.
44
+ *
45
+ * Both are native, so activation is the platform's: Enter follows a link,
46
+ * Enter and Space press a button, and Tab moves between rows. There is no
47
+ * arrow-key handling on purpose — a rail of links is not a composite widget,
48
+ * and roving focus would hide every row but one from the tab order.
49
+ */
50
+ type RouterChildProps = {
51
+ children?: ReactNode;
52
+ onClick?: MouseEventHandler<HTMLElement>;
53
+ target?: string;
54
+ 'aria-current'?: AriaAttributes['aria-current'];
55
+ };
56
+
57
+ /** The label span is cut off by its ellipsis. */
58
+ // Every selector below names the row by this attribute, not by `data-part`:
59
+ // the tooltip trigger's own `data-part="trigger"` lands on the same element.
60
+ const ROW = '[data-nav-list-row]';
61
+ const ACTION = '[data-part="trailing-action"]';
62
+ /** Touch screens: no hover to reveal on, and a finger needs the space kept. */
63
+ const NO_HOVER = '@media (hover: none), (pointer: coarse)';
64
+ /** The row, not the action beside it, is being pressed. */
65
+ const PRESSED = `&:has(${ROW}:active)`;
66
+
67
+ const isTruncated = (el: HTMLElement | null) =>
68
+ el != null && el.scrollWidth > el.clientWidth + 1;
69
+
70
+ export const NavListItem = forwardRef<HTMLElement, NavListItemProps>(
71
+ (
72
+ {
73
+ children,
74
+ href,
75
+ asChild = false,
76
+ onClick,
77
+ isCurrent = false,
78
+ isDisabled = false,
79
+ leadingVisual,
80
+ trailingVisual,
81
+ trailingAction,
82
+ trailingActionVisibility = 'always',
83
+ tooltip,
84
+ tooltipPlacement = 'top',
85
+ ...rest
86
+ },
87
+ ref
88
+ ) => {
89
+ const { orientation, isCollapsed, tooltipDir, revealCurrent } =
90
+ useNavListContext();
91
+ const translate = useTranslate(NavListTranslations);
92
+ const labelRef = useRef<HTMLSpanElement>(null);
93
+ const descriptionId = useId();
94
+ const [isTooltipOpen, setIsTooltipOpen] = useState(false);
95
+
96
+ useEffect(() => {
97
+ if (isCurrent) revealCurrent();
98
+ }, [isCurrent, revealCurrent]);
99
+ const isLink = asChild || href != null;
100
+
101
+ const child = isLink && asChild ? Children.only(children) : null;
102
+ if (asChild && !isValidElement<RouterChildProps>(child)) {
103
+ throw new Error(
104
+ 'NavList.Item with asChild needs exactly one element child'
105
+ );
106
+ }
107
+ const routerChild = child as ReactElement<RouterChildProps> | null;
108
+ const label = routerChild ? routerChild.props.children : children;
109
+ const opensNewWindow =
110
+ !isDisabled &&
111
+ isLink &&
112
+ (routerChild?.props.target ?? (rest as { target?: string }).target) ===
113
+ '_blank';
114
+
115
+ const inherited = useLocaleContext();
116
+ const content = (
117
+ <LocaleProvider locale={inherited.locale}>
118
+ {leadingVisual != null && (
119
+ <chakra.span
120
+ aria-hidden
121
+ display="inline-flex"
122
+ alignItems="center"
123
+ flexShrink={0}
124
+ >
125
+ {leadingVisual}
126
+ </chakra.span>
127
+ )}
128
+ {/* One label element in both modes, so toggling the rail fades it
129
+ instead of swapping it: collapsed it is transparent and 1px wide —
130
+ the size VisuallyHidden uses, which every screen reader still
131
+ reads — and stays the row's accessible name. */}
132
+ <chakra.span
133
+ ref={labelRef}
134
+ data-part="label"
135
+ flex={byOrientation(orientation, '1 1 auto', '0 0 auto')}
136
+ minW={isCollapsed ? '1px' : 0}
137
+ overflow="hidden"
138
+ textOverflow="ellipsis"
139
+ whiteSpace="nowrap"
140
+ opacity={isCollapsed ? 0 : 1}
141
+ animationStyle="feedback"
142
+ transitionProperty="opacity"
143
+ >
144
+ {label}
145
+ </chakra.span>
146
+ {/* KWCAG 2.1 — a link that opens a new window says so in its name. */}
147
+ {opensNewWindow && (
148
+ <VisuallyHidden>{` (${translate('nav_list_opens_new_window')})`}</VisuallyHidden>
149
+ )}
150
+ {trailingVisual != null && (
151
+ <chakra.span
152
+ display="inline-flex"
153
+ alignItems="center"
154
+ flexShrink={0}
155
+ ms="auto"
156
+ color={isDisabled ? 'disabled.fg' : NAV_LIST_RAMP.trailing}
157
+ fontWeight="normal"
158
+ fontVariantNumeric="tabular-nums"
159
+ // Fades with the label. `visibility` flips at the END of the fade
160
+ // (it is discrete), which is when the count leaves the row's name.
161
+ opacity={isCollapsed ? 0 : 1}
162
+ visibility={isCollapsed ? 'hidden' : 'visible'}
163
+ animationStyle="feedback"
164
+ transitionProperty="opacity, visibility"
165
+ >
166
+ {trailingVisual}
167
+ </chakra.span>
168
+ )}
169
+ </LocaleProvider>
170
+ );
171
+
172
+ // One tooltip per row, three jobs. Collapsed: the label, beside the icon.
173
+ // `tooltip`: the caller's description. Otherwise: the label again, only
174
+ // while the ellipsis is actually cutting it off.
175
+ const tooltipKind = isCollapsed
176
+ ? 'label'
177
+ : tooltip != null
178
+ ? 'description'
179
+ : 'overflow';
180
+
181
+ // The overflow tooltip is gated at the trigger: zag skips opening when the
182
+ // event that would open it was `defaultPrevented`, and the row's own
183
+ // handlers run before zag's. A controlled `open` cannot do this — zag
184
+ // enters its open state first and only re-syncs when the prop CHANGES.
185
+ const restHandlers = rest as {
186
+ onPointerMove?: (e: SyntheticEvent) => void;
187
+ onPointerOver?: (e: SyntheticEvent) => void;
188
+ onFocus?: (e: SyntheticEvent) => void;
189
+ };
190
+ // A POINTER also waits for the label to finish fading when the rail is
191
+ // toggled, so no tooltip flashes over a row that is still changing shape:
192
+ // the label one only once the label is fully gone, the others only once
193
+ // it is fully back. The next pointermove after the fade opens it. Focus
194
+ // is never held back — a cancelled focus is not re-fired, so a row
195
+ // focused mid-fade would never show its label.
196
+ const isSettled = () => {
197
+ const el = labelRef.current;
198
+ if (!el) return true;
199
+ const opacity = parseFloat(getComputedStyle(el).opacity);
200
+ if (Number.isNaN(opacity)) return true;
201
+ return isCollapsed ? opacity === 0 : opacity === 1;
202
+ };
203
+ const gate =
204
+ (handler?: (e: SyntheticEvent) => void, waitForFade = true) =>
205
+ (event: SyntheticEvent) => {
206
+ if (
207
+ (waitForFade && !isSettled()) ||
208
+ (tooltipKind === 'overflow' && !isTruncated(labelRef.current))
209
+ )
210
+ event.preventDefault();
211
+ handler?.(event);
212
+ };
213
+ const tooltipGate = {
214
+ onPointerMove: gate(restHandlers.onPointerMove),
215
+ onPointerOver: gate(restHandlers.onPointerOver),
216
+ onFocus: gate(restHandlers.onFocus, false),
217
+ };
218
+
219
+ // The description is a visually hidden element of its own, referenced
220
+ // all the time — not the tooltip, which zag only references while it is
221
+ // open. A disabled row cannot take focus, so a description that existed
222
+ // only while open would never reach a keyboard or screen-reader user,
223
+ // which is exactly when "why is this disabled" matters. The tooltip
224
+ // itself is then never a description (`aria-label` on its root takes its
225
+ // id away), and while it is open the row's own value — the caller's ids,
226
+ // or an empty list — outranks the dangling id zag would leave behind.
227
+ const callerDescribedBy = (rest as { 'aria-describedby'?: string })[
228
+ 'aria-describedby'
229
+ ];
230
+ const describedBy =
231
+ [callerDescribedBy, tooltip != null ? descriptionId : undefined]
232
+ .filter(Boolean)
233
+ .join(' ') || (isTooltipOpen ? '' : undefined);
234
+ const describedByProps = { 'aria-describedby': describedBy };
235
+
236
+ const handleClick = (event: MouseEvent<HTMLElement>) => {
237
+ // Belt and braces: a disabled `<button>` fires no click and a disabled
238
+ // link has no `href`, so this only guards a caller who forces one.
239
+ if (isDisabled) {
240
+ event.preventDefault();
241
+ return;
242
+ }
243
+ onClick?.(event);
244
+ };
245
+
246
+ // `hover`: the action floats over the end of the label instead of keeping
247
+ // its own column, so a resting row spends its full width on the label —
248
+ // the app's HoverRevealedKebab. The row and the action share one grid
249
+ // cell's row; the row spans both columns at rest and gives the second one
250
+ // back to the action when it shows. Only the label's end moves: the row
251
+ // is as tall as it ever was, so nothing below it shifts. Vertical only —
252
+ // a horizontal row is as wide as its label, so there is nothing to give.
253
+ const overlaysAction =
254
+ trailingActionVisibility === 'hover' &&
255
+ trailingAction != null &&
256
+ !isCollapsed;
257
+
258
+ // The fill lives on the `<li>`, not the row, so a trailing action sits on
259
+ // the same surface: hovering the action keeps the row lit, and the current
260
+ // row's fill runs under its action instead of stopping short of it.
261
+ const rowStyles = {
262
+ display: 'flex',
263
+ alignItems: 'center',
264
+ gap: 2,
265
+ flex: byOrientation(orientation, '1 1 auto', '0 0 auto'),
266
+ minW: 0,
267
+ // The same inline padding and start alignment in both modes, so the
268
+ // icon does not move when the rail is toggled: at 2.5 a row is the
269
+ // 40px square around an `sm` icon. The `<li>` is what narrows.
270
+ minH: isCollapsed ? 10 : 9,
271
+ px: 2.5,
272
+ py: 2,
273
+ // Clips the label and count while the rail narrows around them. Only
274
+ // collapsed, so an expanded row never clips a badge or a dot that a
275
+ // visual draws past its own box.
276
+ overflow: isCollapsed ? 'hidden' : undefined,
277
+ borderRadius: 'md',
278
+ border: 'none',
279
+ bg: 'transparent',
280
+ textAlign: 'start',
281
+ textDecoration: 'none',
282
+ textStyle: 'p',
283
+ cursor: 'pointer',
284
+ color: isCurrent ? NAV_LIST_RAMP.currentLabel : NAV_LIST_RAMP.label,
285
+ fontWeight: isCurrent ? 'bold' : 'normal',
286
+ _hover: { textDecoration: 'none' },
287
+ _disabled: { ...disabledText, cursor: 'not-allowed' },
288
+ ...inheritDirection,
289
+ ...(overlaysAction && { gridRow: 1, gridColumn: '1 / -1' }),
290
+ // Inset: rows sit 2px apart and a horizontal rail scrolls, so the
291
+ // outward ring would land on the neighbour or be clipped.
292
+ ...focusRingInset,
293
+ } as const;
294
+
295
+ // Both state attributes go on the element that carries the role, and on
296
+ // the router child's own props when there is one (its props win the
297
+ // `asChild` merge). `data-current` is the hook for scroll-to-current.
298
+ const stateProps = {
299
+ 'aria-current': isCurrent ? (isLink ? 'page' : 'true') : undefined,
300
+ 'data-current': isCurrent ? '' : undefined,
301
+ 'data-nav-list-row': '',
302
+ } as const;
303
+
304
+ let row: ReactElement;
305
+ if (!isLink) {
306
+ row = (
307
+ <chakra.button
308
+ ref={ref as React.Ref<HTMLButtonElement>}
309
+ type="button"
310
+ disabled={isDisabled}
311
+ {...stateProps}
312
+ onClick={handleClick}
313
+ {...rowStyles}
314
+ // The prop type is the anchor's; the global attributes and style
315
+ // props it carries are the same on a button.
316
+ {...(rest as unknown as React.ComponentProps<typeof chakra.button>)}
317
+ {...describedByProps}
318
+ {...tooltipGate}
319
+ >
320
+ {content}
321
+ </chakra.button>
322
+ );
323
+ } else {
324
+ const linkProps = {
325
+ ref: ref as React.Ref<HTMLAnchorElement>,
326
+ ...rowStyles,
327
+ ...rest,
328
+ ...describedByProps,
329
+ ...tooltipGate,
330
+ };
331
+
332
+ if (isDisabled) {
333
+ // A disabled link has no destination, so it is not rendered as one —
334
+ // not even the router link, which would keep its href for middle-click,
335
+ // "open in new tab" and prefetch. Still announced as a link, with
336
+ // `aria-disabled`, the same way whether or not `asChild` was used. With
337
+ // no `href` it is out of the tab order.
338
+ row = (
339
+ <chakra.a
340
+ role="link"
341
+ aria-disabled="true"
342
+ {...stateProps}
343
+ {...linkProps}
344
+ target={undefined}
345
+ >
346
+ {content}
347
+ </chakra.a>
348
+ );
349
+ } else if (routerChild) {
350
+ // Our state goes on the CHILD's props, not on the slot: Chakra's
351
+ // `asChild` merge lets the child's own props win, so a router NavLink
352
+ // that sets its own `aria-current` would otherwise contradict
353
+ // `isCurrent`. The child's own click handler still runs, after ours.
354
+ row = (
355
+ <chakra.a asChild {...linkProps}>
356
+ {cloneElement(
357
+ routerChild,
358
+ {
359
+ ...stateProps,
360
+ ...describedByProps,
361
+ onClick: (event: MouseEvent<HTMLElement>) => {
362
+ handleClick(event);
363
+ routerChild.props.onClick?.(event);
364
+ },
365
+ },
366
+ content
367
+ )}
368
+ </chakra.a>
369
+ );
370
+ } else {
371
+ row = (
372
+ <chakra.a
373
+ href={href}
374
+ {...stateProps}
375
+ onClick={handleClick}
376
+ {...linkProps}
377
+ >
378
+ {content}
379
+ </chakra.a>
380
+ );
381
+ }
382
+ }
383
+
384
+ // The two label tooltips name the tooltip itself (`aria-label`), which
385
+ // takes it out of the trigger's description — the row is already called that.
386
+ const tooltipContent =
387
+ tooltipKind === 'description' ? (
388
+ tooltip
389
+ ) : isCollapsed && tooltip != null ? (
390
+ <>
391
+ {label}
392
+ <Box>{tooltip}</Box>
393
+ </>
394
+ ) : (
395
+ label
396
+ );
397
+ const labelText =
398
+ typeof label === 'string' || typeof label === 'number'
399
+ ? String(label)
400
+ : undefined;
401
+ // Beside the icon, towards the content: the rail is on the right of
402
+ // a right-to-left page. Popper placements are physical.
403
+ const placement =
404
+ isCollapsed || tooltipPlacement === 'end'
405
+ ? tooltipDir === 'rtl'
406
+ ? 'left'
407
+ : 'right'
408
+ : 'top';
409
+ // An expanded row's end tooltip measures from the whole `<li>`, not the
410
+ // row link: with a trailing action the link stops short of the row's
411
+ // end, and the tooltip would sit over the action.
412
+ const anchorsToItem = !isCollapsed && tooltipPlacement === 'end';
413
+ const withTooltip = (
414
+ <Tooltip
415
+ content={tooltipContent}
416
+ placement={placement}
417
+ {...(anchorsToItem && {
418
+ positioning: {
419
+ placement,
420
+ getAnchorRect: (el) =>
421
+ el instanceof HTMLElement
422
+ ? (el.closest('li')?.getBoundingClientRect() ?? null)
423
+ : null,
424
+ },
425
+ })}
426
+ onOpenChange={({ open }) => setIsTooltipOpen(open)}
427
+ // Zag only checks that this is set — it takes the content's id and
428
+ // role away, so the trigger is never described by the tooltip. Not
429
+ // rendered anywhere. The description, if any, is `descriptionId`.
430
+ aria-label={labelText ?? 'tooltip'}
431
+ contentProps={{ 'aria-hidden': true }}
432
+ >
433
+ {row}
434
+ </Tooltip>
435
+ );
436
+
437
+ const fills = isDisabled
438
+ ? undefined
439
+ : {
440
+ // On the `<li>`, like the hover fill, so the press covers the
441
+ // action's end of the row too — but only a press on the ROW: a
442
+ // press on the action is the action's, and lights its own button.
443
+ // No `>` inside `:has()`: jsdom's selector engine throws on a
444
+ // relative selector, which would break every consumer's tests.
445
+ [PRESSED]: pressedFill,
446
+ };
447
+ // Shown: hovered, focus anywhere in the row, or the action's menu open.
448
+ const shown = [`&:hover > ${ACTION}`, `&:focus-within > ${ACTION}`].join(
449
+ ', '
450
+ );
451
+ const revealOnHover =
452
+ trailingActionVisibility === 'hover'
453
+ ? {
454
+ [`& > ${ACTION}`]: { opacity: 0 },
455
+ [shown]: { opacity: 1 },
456
+ // Its own rule: `:has()` is not forgiving, and a browser without
457
+ // it would drop every selector listed beside it.
458
+ [`& > ${ACTION}:has([aria-expanded="true"], [data-state="open"])`]:
459
+ { opacity: 1 },
460
+ // Touch: always shown, and with its space kept.
461
+ [NO_HOVER]: {
462
+ [`& > ${ACTION}`]: { opacity: 1 },
463
+ ...(overlaysAction && { [`& > ${ROW}`]: { gridColumn: 1 } }),
464
+ },
465
+ ...(overlaysAction && {
466
+ // The row gives the action its column back exactly when the
467
+ // action shows, so the label ends before it.
468
+ [`&:hover > ${ROW}, &:focus-within > ${ROW}`]: { gridColumn: 1 },
469
+ [`&:has(${ACTION} [aria-expanded="true"], ${ACTION} [data-state="open"]) > ${ROW}`]:
470
+ { gridColumn: 1 },
471
+ }),
472
+ }
473
+ : undefined;
474
+
475
+ return (
476
+ <chakra.li
477
+ display={
478
+ overlaysAction ? byOrientation(orientation, 'grid', 'flex') : 'flex'
479
+ }
480
+ gridTemplateColumns={overlaysAction ? 'minmax(0, 1fr) auto' : undefined}
481
+ alignItems="center"
482
+ gap={0.5}
483
+ flexShrink={0}
484
+ minW={0}
485
+ // Narrows to the square when the rail collapses, on the label's clock,
486
+ // so the fill shrinks with the rail instead of snapping to 40px.
487
+ maxW={isCollapsed ? 10 : byOrientation(orientation, '100%', 'none')}
488
+ animationStyle="feedback"
489
+ transitionProperty="max-width"
490
+ borderRadius="md"
491
+ bg={isCurrent ? NAV_LIST_RAMP.currentFill : 'transparent'}
492
+ _hover={
493
+ isDisabled
494
+ ? undefined
495
+ : {
496
+ bg: NAV_LIST_RAMP.hoverFill,
497
+ // Again inside hover: Chakra's hover rule is as specific as the
498
+ // press rule and comes later, so a pointer press would lose.
499
+ [PRESSED]: pressedFill,
500
+ }
501
+ }
502
+ css={{ ...fills, ...revealOnHover }}
503
+ >
504
+ {/* Zag stamps `dir` on the portalled tooltip from Ark's locale (`ltr`
505
+ unless a LocaleProvider says otherwise), so a tooltip in an RTL
506
+ rail would set its text left to right. The list measures the
507
+ direction after mount, and a tooltip only opens after that. The
508
+ row lays out from CSS (`inheritDirection`), never from this; its
509
+ content gets the caller's own locale back. */}
510
+ <LocaleProvider locale={localeFor(inherited, tooltipDir)}>
511
+ {withTooltip}
512
+ </LocaleProvider>
513
+ {tooltip != null && (
514
+ // `hidden`, not visually hidden: a description reference still
515
+ // reads hidden text, and browse mode does not read it a second time.
516
+ <chakra.span id={descriptionId} hidden>
517
+ {tooltip}
518
+ </chakra.span>
519
+ )}
520
+ {trailingAction != null && !isCollapsed && (
521
+ <chakra.span
522
+ data-part="trailing-action"
523
+ display="inline-flex"
524
+ alignItems="center"
525
+ flexShrink={0}
526
+ pe={0.5}
527
+ // Over the row's end, above its fill and its focus ring.
528
+ {...(overlaysAction && {
529
+ gridRow: 1,
530
+ gridColumn: 2,
531
+ position: 'relative',
532
+ zIndex: 1,
533
+ })}
534
+ >
535
+ {trailingAction}
536
+ </chakra.span>
537
+ )}
538
+ </chakra.li>
539
+ );
540
+ }
541
+ );
542
+
543
+ NavListItem.displayName = 'NavList.Item';
@@ -0,0 +1,57 @@
1
+ import { forwardRef } from 'react';
2
+ import { chakra, Skeleton } from '@chakra-ui/react';
3
+
4
+ import { byOrientation, listStyles } from './NavList.styles';
5
+ import { NavListSkeletonProps } from './NavList.types';
6
+
7
+ /** Widths that vary row to row, so the placeholder does not read as a table. */
8
+ const WIDTHS = ['72%', '56%', '84%', '64%', '48%', '76%'];
9
+
10
+ /**
11
+ * Placeholder rows while a rail's entries load, with the same row height,
12
+ * radius and gap as the real list, so nothing moves when it swaps in.
13
+ *
14
+ * Render it INSTEAD of the `NavList`, not inside it. It is `aria-hidden`: a
15
+ * column of grey bars says nothing to a screen reader, and "loading" belongs
16
+ * to the region that is loading (`aria-busy`, or a status message) rather
17
+ * than to one of its placeholders.
18
+ *
19
+ * Counts that are still loading are not this — leave `trailingVisual` unset
20
+ * until they arrive, and the row keeps its label.
21
+ */
22
+ export const NavListSkeleton = forwardRef<
23
+ HTMLUListElement,
24
+ NavListSkeletonProps
25
+ >(({ count = 5, orientation = 'vertical', ...rest }, ref) => (
26
+ <chakra.ul ref={ref} aria-hidden {...listStyles(orientation)} {...rest}>
27
+ {Array.from({ length: count }, (_, i) => (
28
+ <chakra.li
29
+ key={i}
30
+ display="flex"
31
+ alignItems="center"
32
+ flexShrink={0}
33
+ // The row's own box: `minH`, padding and one line of `p` text, so
34
+ // the placeholder is exactly as tall as the row that replaces it.
35
+ minH={9}
36
+ px={2.5}
37
+ py={2}
38
+ textStyle="p"
39
+ w={byOrientation(orientation, 'auto', '96px')}
40
+ >
41
+ <Skeleton
42
+ h={4}
43
+ w={byOrientation(orientation, WIDTHS[i % WIDTHS.length], 'full')}
44
+ borderRadius="sm"
45
+ // A placeholder that stops pulsing is still a placeholder; there
46
+ // is no progress for the motion to carry.
47
+ _motionReduce={{ animation: 'none' }}
48
+ />
49
+ <chakra.span w={0} overflow="hidden">
50
+ {'\u00A0'}
51
+ </chakra.span>
52
+ </chakra.li>
53
+ ))}
54
+ </chakra.ul>
55
+ ));
56
+
57
+ NavListSkeleton.displayName = 'NavList.Skeleton';
@@ -0,0 +1,15 @@
1
+ export { NavList } from './NavList';
2
+ export { NAV_LIST_RAMP } from './NavList.styles';
3
+ export type {
4
+ NavListGroupProps,
5
+ NavListItemProps,
6
+ NavListOrientation,
7
+ NavListProps,
8
+ NavListResponsiveOrientation,
9
+ NavListSkeletonProps,
10
+ NavListTooltipPlacement,
11
+ NavListTrailingActionVisibility,
12
+ } from './NavList.types';
13
+ export { NavListGroup } from './NavListGroup';
14
+ export { NavListItem } from './NavListItem';
15
+ export { NavListSkeleton } from './NavListSkeleton';