@deriv-com/dds-marketing 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (460) hide show
  1. package/.llm/components/accordion.md +193 -0
  2. package/.llm/components/accordionitem.md +236 -0
  3. package/.llm/components/aspectratio.md +212 -0
  4. package/.llm/components/badge.md +231 -0
  5. package/.llm/components/bottomsheet.md +404 -0
  6. package/.llm/components/breadcrumb.md +197 -0
  7. package/.llm/components/breadcrumbitem.md +178 -0
  8. package/.llm/components/button.md +271 -0
  9. package/.llm/components/buttonicon.md +313 -0
  10. package/.llm/components/card.md +313 -0
  11. package/.llm/components/cardbody.md +409 -0
  12. package/.llm/components/cardbutton.md +259 -0
  13. package/.llm/components/checkbox.md +285 -0
  14. package/.llm/components/divider.md +230 -0
  15. package/.llm/components/dropdownmenu.md +453 -0
  16. package/.llm/components/filterchip.md +314 -0
  17. package/.llm/components/footer.md +408 -0
  18. package/.llm/components/footergroup.md +241 -0
  19. package/.llm/components/grid.md +659 -0
  20. package/.llm/components/icon.md +194 -0
  21. package/.llm/components/link.md +354 -0
  22. package/.llm/components/menuitem.md +218 -0
  23. package/.llm/components/navbar.md +458 -0
  24. package/.llm/components/navbaritem.md +238 -0
  25. package/.llm/components/navbarmenu.md +319 -0
  26. package/.llm/components/navbarmenugroup.md +184 -0
  27. package/.llm/components/navbarpanel.md +255 -0
  28. package/.llm/components/navbarswitcher.md +343 -0
  29. package/.llm/components/navbarswitcheroption.md +156 -0
  30. package/.llm/components/option.md +268 -0
  31. package/.llm/components/pagination.md +361 -0
  32. package/.llm/components/removablechip.md +247 -0
  33. package/.llm/components/row.md +381 -0
  34. package/.llm/components/scroller.md +470 -0
  35. package/.llm/components/searchinput.md +279 -0
  36. package/.llm/components/segmentedcontrol.md +358 -0
  37. package/.llm/components/segmentedcontrolitem.md +272 -0
  38. package/.llm/components/select.md +509 -0
  39. package/.llm/components/selectchip.md +334 -0
  40. package/.llm/components/spinner.md +222 -0
  41. package/.llm/components/stack.md +334 -0
  42. package/.llm/components/statusdot.md +205 -0
  43. package/.llm/components/subdomainnavbar.md +327 -0
  44. package/.llm/components/tab.md +291 -0
  45. package/.llm/components/table.md +660 -0
  46. package/.llm/components/tablebody.md +258 -0
  47. package/.llm/components/tablecell.md +248 -0
  48. package/.llm/components/tablehead.md +248 -0
  49. package/.llm/components/tableheadercell.md +298 -0
  50. package/.llm/components/tablerow.md +285 -0
  51. package/.llm/components/tablist.md +210 -0
  52. package/.llm/components/textarea.md +362 -0
  53. package/.llm/components/textinput.md +467 -0
  54. package/.llm/components/tooltip.md +267 -0
  55. package/.llm/components/typography.md +245 -0
  56. package/.llm/digest/accordion.md +43 -0
  57. package/.llm/digest/accordionitem.md +47 -0
  58. package/.llm/digest/aspectratio.md +47 -0
  59. package/.llm/digest/badge.md +45 -0
  60. package/.llm/digest/bottomsheet.md +69 -0
  61. package/.llm/digest/breadcrumb.md +38 -0
  62. package/.llm/digest/breadcrumbitem.md +43 -0
  63. package/.llm/digest/button.md +48 -0
  64. package/.llm/digest/buttonicon.md +61 -0
  65. package/.llm/digest/card.md +50 -0
  66. package/.llm/digest/cardbody.md +68 -0
  67. package/.llm/digest/cardbutton.md +49 -0
  68. package/.llm/digest/checkbox.md +63 -0
  69. package/.llm/digest/divider.md +52 -0
  70. package/.llm/digest/dropdownmenu.md +67 -0
  71. package/.llm/digest/filterchip.md +68 -0
  72. package/.llm/digest/footer.md +57 -0
  73. package/.llm/digest/footergroup.md +42 -0
  74. package/.llm/digest/grid.md +62 -0
  75. package/.llm/digest/icon.md +45 -0
  76. package/.llm/digest/link.md +59 -0
  77. package/.llm/digest/menuitem.md +46 -0
  78. package/.llm/digest/navbar.md +60 -0
  79. package/.llm/digest/navbaritem.md +54 -0
  80. package/.llm/digest/navbarmenu.md +54 -0
  81. package/.llm/digest/navbarmenugroup.md +40 -0
  82. package/.llm/digest/navbarpanel.md +53 -0
  83. package/.llm/digest/navbarswitcher.md +51 -0
  84. package/.llm/digest/navbarswitcheroption.md +37 -0
  85. package/.llm/digest/option.md +54 -0
  86. package/.llm/digest/pagination.md +71 -0
  87. package/.llm/digest/removablechip.md +51 -0
  88. package/.llm/digest/row.md +60 -0
  89. package/.llm/digest/scroller.md +59 -0
  90. package/.llm/digest/searchinput.md +56 -0
  91. package/.llm/digest/segmentedcontrol.md +59 -0
  92. package/.llm/digest/segmentedcontrolitem.md +59 -0
  93. package/.llm/digest/select.md +92 -0
  94. package/.llm/digest/selectchip.md +68 -0
  95. package/.llm/digest/spinner.md +52 -0
  96. package/.llm/digest/stack.md +56 -0
  97. package/.llm/digest/statusdot.md +46 -0
  98. package/.llm/digest/subdomainnavbar.md +54 -0
  99. package/.llm/digest/tab.md +60 -0
  100. package/.llm/digest/table.md +71 -0
  101. package/.llm/digest/tablebody.md +49 -0
  102. package/.llm/digest/tablecell.md +55 -0
  103. package/.llm/digest/tablehead.md +50 -0
  104. package/.llm/digest/tableheadercell.md +65 -0
  105. package/.llm/digest/tablerow.md +56 -0
  106. package/.llm/digest/tablist.md +46 -0
  107. package/.llm/digest/textarea.md +78 -0
  108. package/.llm/digest/textinput.md +95 -0
  109. package/.llm/digest/tooltip.md +58 -0
  110. package/.llm/digest/typography.md +59 -0
  111. package/.llm/index.md +86 -0
  112. package/.llm/rules.md +122 -0
  113. package/.llm/tokens.md +341 -0
  114. package/AGENTS.md +164 -0
  115. package/LICENSE +21 -0
  116. package/README.md +63 -15
  117. package/dist/components/core/accordion/Accordion.css +10 -0
  118. package/dist/components/core/accordion/Accordion.d.ts +20 -0
  119. package/dist/components/core/accordion/Accordion.js +69 -0
  120. package/dist/components/core/accordion/Accordion.types.d.ts +20 -0
  121. package/dist/components/core/accordion/Accordion.types.js +7 -0
  122. package/dist/components/core/accordion-item/AccordionItem.css +98 -0
  123. package/dist/components/core/accordion-item/AccordionItem.d.ts +44 -0
  124. package/dist/components/core/accordion-item/AccordionItem.js +63 -0
  125. package/dist/components/core/accordion-item/AccordionItem.types.d.ts +32 -0
  126. package/dist/components/core/accordion-item/AccordionItem.types.js +13 -0
  127. package/dist/components/core/accordion-item/accordion-item-impl.css +107 -0
  128. package/dist/components/core/badge/Badge.css +37 -0
  129. package/dist/components/core/badge/Badge.d.ts +37 -0
  130. package/dist/components/core/badge/Badge.js +40 -0
  131. package/dist/components/core/badge/Badge.types.d.ts +24 -0
  132. package/dist/components/core/badge/Badge.types.js +8 -0
  133. package/dist/components/core/badge/badge-impl.css +32 -0
  134. package/dist/components/core/bottom-sheet/BottomSheet.css +178 -0
  135. package/dist/components/core/bottom-sheet/BottomSheet.d.ts +22 -0
  136. package/dist/components/core/bottom-sheet/BottomSheet.js +359 -0
  137. package/dist/components/core/bottom-sheet/BottomSheet.types.d.ts +67 -0
  138. package/dist/components/core/bottom-sheet/BottomSheet.types.js +18 -0
  139. package/dist/components/core/bottom-sheet/bottom-sheet-impl.css +57 -0
  140. package/dist/components/core/breadcrumb/Breadcrumb.css +19 -0
  141. package/dist/components/core/breadcrumb/Breadcrumb.d.ts +16 -0
  142. package/dist/components/core/breadcrumb/Breadcrumb.js +22 -0
  143. package/dist/components/core/breadcrumb/Breadcrumb.types.d.ts +18 -0
  144. package/dist/components/core/breadcrumb/Breadcrumb.types.js +9 -0
  145. package/dist/components/core/breadcrumb-item/BreadcrumbItem.css +34 -0
  146. package/dist/components/core/breadcrumb-item/BreadcrumbItem.d.ts +12 -0
  147. package/dist/components/core/breadcrumb-item/BreadcrumbItem.js +15 -0
  148. package/dist/components/core/breadcrumb-item/BreadcrumbItem.types.d.ts +22 -0
  149. package/dist/components/core/breadcrumb-item/BreadcrumbItem.types.js +9 -0
  150. package/dist/components/core/button/Button.css +141 -0
  151. package/dist/components/core/button/Button.d.ts +25 -0
  152. package/dist/components/core/button/Button.js +28 -0
  153. package/dist/components/core/button/Button.types.d.ts +40 -0
  154. package/dist/components/core/button/Button.types.js +9 -0
  155. package/dist/components/core/button/button-impl.css +46 -0
  156. package/dist/components/core/button-icon/ButtonIcon.css +135 -0
  157. package/dist/components/core/button-icon/ButtonIcon.d.ts +34 -0
  158. package/dist/components/core/button-icon/ButtonIcon.js +117 -0
  159. package/dist/components/core/button-icon/ButtonIcon.types.d.ts +41 -0
  160. package/dist/components/core/button-icon/ButtonIcon.types.js +8 -0
  161. package/dist/components/core/card/Card.css +65 -0
  162. package/dist/components/core/card/Card.d.ts +24 -0
  163. package/dist/components/core/card/Card.js +26 -0
  164. package/dist/components/core/card/Card.types.d.ts +33 -0
  165. package/dist/components/core/card/Card.types.js +7 -0
  166. package/dist/components/core/card-body/CardBody.css +139 -0
  167. package/dist/components/core/card-body/CardBody.d.ts +62 -0
  168. package/dist/components/core/card-body/CardBody.js +97 -0
  169. package/dist/components/core/card-body/CardBody.types.d.ts +61 -0
  170. package/dist/components/core/card-body/CardBody.types.js +15 -0
  171. package/dist/components/core/card-body/card-body-impl.css +87 -0
  172. package/dist/components/core/card-button/CardButton.css +73 -0
  173. package/dist/components/core/card-button/CardButton.d.ts +27 -0
  174. package/dist/components/core/card-button/CardButton.js +37 -0
  175. package/dist/components/core/card-button/CardButton.types.d.ts +24 -0
  176. package/dist/components/core/card-button/CardButton.types.js +7 -0
  177. package/dist/components/core/card-button/card-button-impl.css +39 -0
  178. package/dist/components/core/checkbox/Checkbox.css +149 -0
  179. package/dist/components/core/checkbox/Checkbox.d.ts +21 -0
  180. package/dist/components/core/checkbox/Checkbox.js +97 -0
  181. package/dist/components/core/checkbox/Checkbox.types.d.ts +46 -0
  182. package/dist/components/core/checkbox/Checkbox.types.js +15 -0
  183. package/dist/components/core/checkbox/checkbox-impl.css +90 -0
  184. package/dist/components/core/divider/Divider.css +41 -0
  185. package/dist/components/core/divider/Divider.d.ts +46 -0
  186. package/dist/components/core/divider/Divider.js +51 -0
  187. package/dist/components/core/divider/Divider.types.d.ts +25 -0
  188. package/dist/components/core/divider/Divider.types.js +9 -0
  189. package/dist/components/core/dropdown-menu/DropdownMenu.css +146 -0
  190. package/dist/components/core/dropdown-menu/DropdownMenu.d.ts +22 -0
  191. package/dist/components/core/dropdown-menu/DropdownMenu.js +309 -0
  192. package/dist/components/core/dropdown-menu/DropdownMenu.types.d.ts +62 -0
  193. package/dist/components/core/dropdown-menu/DropdownMenu.types.js +12 -0
  194. package/dist/components/core/dropdown-menu/dropdown-menu-impl.css +70 -0
  195. package/dist/components/core/filter-chip/FilterChip.css +149 -0
  196. package/dist/components/core/filter-chip/FilterChip.d.ts +23 -0
  197. package/dist/components/core/filter-chip/FilterChip.js +37 -0
  198. package/dist/components/core/filter-chip/FilterChip.types.d.ts +53 -0
  199. package/dist/components/core/filter-chip/FilterChip.types.js +12 -0
  200. package/dist/components/core/footer/Footer.css +104 -0
  201. package/dist/components/core/footer/Footer.d.ts +43 -0
  202. package/dist/components/core/footer/Footer.js +53 -0
  203. package/dist/components/core/footer/Footer.types.d.ts +47 -0
  204. package/dist/components/core/footer/Footer.types.js +18 -0
  205. package/dist/components/core/footer/footer-impl.css +218 -0
  206. package/dist/components/core/footer-group/FooterGroup.css +90 -0
  207. package/dist/components/core/footer-group/FooterGroup.d.ts +32 -0
  208. package/dist/components/core/footer-group/FooterGroup.js +64 -0
  209. package/dist/components/core/footer-group/FooterGroup.types.d.ts +25 -0
  210. package/dist/components/core/footer-group/FooterGroup.types.js +12 -0
  211. package/dist/components/core/footer-group/footer-group-impl.css +78 -0
  212. package/dist/components/core/icon/Icon.css +40 -0
  213. package/dist/components/core/icon/Icon.d.ts +23 -0
  214. package/dist/components/core/icon/Icon.js +79 -0
  215. package/dist/components/core/icon/Icon.types.d.ts +24 -0
  216. package/dist/components/core/icon/Icon.types.js +7 -0
  217. package/dist/components/core/link/Link.css +89 -0
  218. package/dist/components/core/link/Link.d.ts +37 -0
  219. package/dist/components/core/link/Link.js +141 -0
  220. package/dist/components/core/link/Link.types.d.ts +41 -0
  221. package/dist/components/core/link/Link.types.js +9 -0
  222. package/dist/components/core/link/link-impl.css +168 -0
  223. package/dist/components/core/menu-item/MenuItem.css +70 -0
  224. package/dist/components/core/menu-item/MenuItem.d.ts +11 -0
  225. package/dist/components/core/menu-item/MenuItem.js +26 -0
  226. package/dist/components/core/menu-item/MenuItem.types.d.ts +28 -0
  227. package/dist/components/core/menu-item/MenuItem.types.js +9 -0
  228. package/dist/components/core/navbar/Navbar.css +135 -0
  229. package/dist/components/core/navbar/Navbar.d.ts +36 -0
  230. package/dist/components/core/navbar/Navbar.js +371 -0
  231. package/dist/components/core/navbar/Navbar.types.d.ts +49 -0
  232. package/dist/components/core/navbar/Navbar.types.js +17 -0
  233. package/dist/components/core/navbar/navbar-impl.css +590 -0
  234. package/dist/components/core/navbar-item/NavbarItem.css +75 -0
  235. package/dist/components/core/navbar-item/NavbarItem.d.ts +22 -0
  236. package/dist/components/core/navbar-item/NavbarItem.js +40 -0
  237. package/dist/components/core/navbar-item/NavbarItem.types.d.ts +34 -0
  238. package/dist/components/core/navbar-item/NavbarItem.types.js +10 -0
  239. package/dist/components/core/navbar-menu/NavbarMenu.css +128 -0
  240. package/dist/components/core/navbar-menu/NavbarMenu.d.ts +5 -0
  241. package/dist/components/core/navbar-menu/NavbarMenu.js +186 -0
  242. package/dist/components/core/navbar-menu/NavbarMenu.types.d.ts +45 -0
  243. package/dist/components/core/navbar-menu/NavbarMenu.types.js +12 -0
  244. package/dist/components/core/navbar-menu/navbar-menu-impl.css +186 -0
  245. package/dist/components/core/navbar-menu-group/NavbarMenuGroup.css +26 -0
  246. package/dist/components/core/navbar-menu-group/NavbarMenuGroup.d.ts +17 -0
  247. package/dist/components/core/navbar-menu-group/NavbarMenuGroup.js +22 -0
  248. package/dist/components/core/navbar-menu-group/NavbarMenuGroup.types.d.ts +14 -0
  249. package/dist/components/core/navbar-menu-group/NavbarMenuGroup.types.js +7 -0
  250. package/dist/components/core/navbar-panel/NavbarPanel.css +87 -0
  251. package/dist/components/core/navbar-panel/NavbarPanel.d.ts +34 -0
  252. package/dist/components/core/navbar-panel/NavbarPanel.js +46 -0
  253. package/dist/components/core/navbar-panel/NavbarPanel.types.d.ts +29 -0
  254. package/dist/components/core/navbar-panel/NavbarPanel.types.js +12 -0
  255. package/dist/components/core/navbar-panel/navbar-panel-impl.css +104 -0
  256. package/dist/components/core/navbar-panel/use-navbar-panel.d.ts +26 -0
  257. package/dist/components/core/navbar-panel/use-navbar-panel.js +135 -0
  258. package/dist/components/core/navbar-switcher/NavbarSwitcher.css +117 -0
  259. package/dist/components/core/navbar-switcher/NavbarSwitcher.d.ts +20 -0
  260. package/dist/components/core/navbar-switcher/NavbarSwitcher.js +90 -0
  261. package/dist/components/core/navbar-switcher/NavbarSwitcher.types.d.ts +46 -0
  262. package/dist/components/core/navbar-switcher/NavbarSwitcher.types.js +13 -0
  263. package/dist/components/core/navbar-switcher/navbar-switcher-impl.css +179 -0
  264. package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.css +39 -0
  265. package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.d.ts +16 -0
  266. package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.js +19 -0
  267. package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.types.d.ts +18 -0
  268. package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.types.js +7 -0
  269. package/dist/components/core/option/Option.css +133 -0
  270. package/dist/components/core/option/Option.d.ts +25 -0
  271. package/dist/components/core/option/Option.js +31 -0
  272. package/dist/components/core/option/Option.types.d.ts +44 -0
  273. package/dist/components/core/option/Option.types.js +14 -0
  274. package/dist/components/core/pagination/Pagination.css +237 -0
  275. package/dist/components/core/pagination/Pagination.d.ts +30 -0
  276. package/dist/components/core/pagination/Pagination.js +406 -0
  277. package/dist/components/core/pagination/Pagination.types.d.ts +59 -0
  278. package/dist/components/core/pagination/Pagination.types.js +14 -0
  279. package/dist/components/core/pagination/pagination-impl.css +17 -0
  280. package/dist/components/core/removable-chip/RemovableChip.css +125 -0
  281. package/dist/components/core/removable-chip/RemovableChip.d.ts +25 -0
  282. package/dist/components/core/removable-chip/RemovableChip.js +36 -0
  283. package/dist/components/core/removable-chip/RemovableChip.types.d.ts +38 -0
  284. package/dist/components/core/removable-chip/RemovableChip.types.js +13 -0
  285. package/dist/components/core/search-input/SearchInput.css +205 -0
  286. package/dist/components/core/search-input/SearchInput.d.ts +5 -0
  287. package/dist/components/core/search-input/SearchInput.js +81 -0
  288. package/dist/components/core/search-input/SearchInput.types.d.ts +43 -0
  289. package/dist/components/core/search-input/SearchInput.types.js +13 -0
  290. package/dist/components/core/search-input/search-input-impl.css +20 -0
  291. package/dist/components/core/segmented-control/SegmentedControl.css +57 -0
  292. package/dist/components/core/segmented-control/SegmentedControl.d.ts +37 -0
  293. package/dist/components/core/segmented-control/SegmentedControl.js +269 -0
  294. package/dist/components/core/segmented-control/SegmentedControl.types.d.ts +38 -0
  295. package/dist/components/core/segmented-control/SegmentedControl.types.js +8 -0
  296. package/dist/components/core/segmented-control/segmented-control-impl.css +57 -0
  297. package/dist/components/core/segmented-control-item/SegmentedControlItem.css +151 -0
  298. package/dist/components/core/segmented-control-item/SegmentedControlItem.d.ts +50 -0
  299. package/dist/components/core/segmented-control-item/SegmentedControlItem.js +101 -0
  300. package/dist/components/core/segmented-control-item/SegmentedControlItem.types.d.ts +37 -0
  301. package/dist/components/core/segmented-control-item/SegmentedControlItem.types.js +10 -0
  302. package/dist/components/core/segmented-control-item/segmented-control-item-impl.css +69 -0
  303. package/dist/components/core/select/Select.css +400 -0
  304. package/dist/components/core/select/Select.d.ts +29 -0
  305. package/dist/components/core/select/Select.js +524 -0
  306. package/dist/components/core/select/Select.types.d.ts +96 -0
  307. package/dist/components/core/select/Select.types.js +26 -0
  308. package/dist/components/core/select/select-impl.css +114 -0
  309. package/dist/components/core/select-chip/SelectChip.css +155 -0
  310. package/dist/components/core/select-chip/SelectChip.d.ts +20 -0
  311. package/dist/components/core/select-chip/SelectChip.js +273 -0
  312. package/dist/components/core/select-chip/SelectChip.types.d.ts +56 -0
  313. package/dist/components/core/select-chip/SelectChip.types.js +14 -0
  314. package/dist/components/core/select-chip/select-chip-impl.css +38 -0
  315. package/dist/components/core/spinner/Spinner.css +76 -0
  316. package/dist/components/core/spinner/Spinner.d.ts +5 -0
  317. package/dist/components/core/spinner/Spinner.js +29 -0
  318. package/dist/components/core/spinner/Spinner.types.d.ts +37 -0
  319. package/dist/components/core/spinner/Spinner.types.js +10 -0
  320. package/dist/components/core/spinner/spinner-impl.css +27 -0
  321. package/dist/components/core/status-dot/StatusDot.css +43 -0
  322. package/dist/components/core/status-dot/StatusDot.d.ts +35 -0
  323. package/dist/components/core/status-dot/StatusDot.js +46 -0
  324. package/dist/components/core/status-dot/StatusDot.types.d.ts +29 -0
  325. package/dist/components/core/status-dot/StatusDot.types.js +7 -0
  326. package/dist/components/core/status-dot/status-dot-impl.css +42 -0
  327. package/dist/components/core/subdomain-navbar/SubdomainNavbar.css +89 -0
  328. package/dist/components/core/subdomain-navbar/SubdomainNavbar.d.ts +21 -0
  329. package/dist/components/core/subdomain-navbar/SubdomainNavbar.js +127 -0
  330. package/dist/components/core/subdomain-navbar/SubdomainNavbar.types.d.ts +43 -0
  331. package/dist/components/core/subdomain-navbar/SubdomainNavbar.types.js +13 -0
  332. package/dist/components/core/subdomain-navbar/subdomain-navbar-impl.css +147 -0
  333. package/dist/components/core/tab/Tab.css +113 -0
  334. package/dist/components/core/tab/Tab.d.ts +36 -0
  335. package/dist/components/core/tab/Tab.js +53 -0
  336. package/dist/components/core/tab/Tab.types.d.ts +42 -0
  337. package/dist/components/core/tab/Tab.types.js +13 -0
  338. package/dist/components/core/tab/tab-impl.css +49 -0
  339. package/dist/components/core/tab-list/TabList.css +40 -0
  340. package/dist/components/core/tab-list/TabList.d.ts +26 -0
  341. package/dist/components/core/tab-list/TabList.js +124 -0
  342. package/dist/components/core/tab-list/TabList.types.d.ts +20 -0
  343. package/dist/components/core/tab-list/TabList.types.js +7 -0
  344. package/dist/components/core/tab-list/tab-list-impl.css +56 -0
  345. package/dist/components/core/table/Table.css +40 -0
  346. package/dist/components/core/table/Table.d.ts +19 -0
  347. package/dist/components/core/table/Table.js +55 -0
  348. package/dist/components/core/table/Table.types.d.ts +59 -0
  349. package/dist/components/core/table/Table.types.js +9 -0
  350. package/dist/components/core/table/table-impl.css +75 -0
  351. package/dist/components/core/table/use-table-sort.d.ts +43 -0
  352. package/dist/components/core/table/use-table-sort.js +51 -0
  353. package/dist/components/core/table-body/TableBody.css +6 -0
  354. package/dist/components/core/table-body/TableBody.d.ts +12 -0
  355. package/dist/components/core/table-body/TableBody.js +26 -0
  356. package/dist/components/core/table-body/TableBody.types.d.ts +36 -0
  357. package/dist/components/core/table-body/TableBody.types.js +7 -0
  358. package/dist/components/core/table-cell/TableCell.css +76 -0
  359. package/dist/components/core/table-cell/TableCell.d.ts +21 -0
  360. package/dist/components/core/table-cell/TableCell.js +31 -0
  361. package/dist/components/core/table-cell/TableCell.types.d.ts +43 -0
  362. package/dist/components/core/table-cell/TableCell.types.js +7 -0
  363. package/dist/components/core/table-head/TableHead.css +6 -0
  364. package/dist/components/core/table-head/TableHead.d.ts +22 -0
  365. package/dist/components/core/table-head/TableHead.js +52 -0
  366. package/dist/components/core/table-head/TableHead.types.d.ts +39 -0
  367. package/dist/components/core/table-head/TableHead.types.js +7 -0
  368. package/dist/components/core/table-head/table-head-impl.css +51 -0
  369. package/dist/components/core/table-header-cell/TableHeaderCell.css +126 -0
  370. package/dist/components/core/table-header-cell/TableHeaderCell.d.ts +21 -0
  371. package/dist/components/core/table-header-cell/TableHeaderCell.js +34 -0
  372. package/dist/components/core/table-header-cell/TableHeaderCell.types.d.ts +56 -0
  373. package/dist/components/core/table-header-cell/TableHeaderCell.types.js +9 -0
  374. package/dist/components/core/table-header-cell/table-header-cell-impl.css +74 -0
  375. package/dist/components/core/table-row/TableRow.css +18 -0
  376. package/dist/components/core/table-row/TableRow.d.ts +17 -0
  377. package/dist/components/core/table-row/TableRow.js +32 -0
  378. package/dist/components/core/table-row/TableRow.types.d.ts +45 -0
  379. package/dist/components/core/table-row/TableRow.types.js +7 -0
  380. package/dist/components/core/table-row/table-row-impl.css +31 -0
  381. package/dist/components/core/text-area/TextArea.css +325 -0
  382. package/dist/components/core/text-area/TextArea.d.ts +13 -0
  383. package/dist/components/core/text-area/TextArea.js +133 -0
  384. package/dist/components/core/text-area/TextArea.types.d.ts +67 -0
  385. package/dist/components/core/text-area/TextArea.types.js +19 -0
  386. package/dist/components/core/text-area/text-area-impl.css +36 -0
  387. package/dist/components/core/text-input/TextInput.css +400 -0
  388. package/dist/components/core/text-input/TextInput.d.ts +5 -0
  389. package/dist/components/core/text-input/TextInput.js +130 -0
  390. package/dist/components/core/text-input/TextInput.types.d.ts +96 -0
  391. package/dist/components/core/text-input/TextInput.types.js +24 -0
  392. package/dist/components/core/text-input/text-input-impl.css +36 -0
  393. package/dist/components/core/tooltip/Tooltip.css +101 -0
  394. package/dist/components/core/tooltip/Tooltip.d.ts +51 -0
  395. package/dist/components/core/tooltip/Tooltip.js +87 -0
  396. package/dist/components/core/tooltip/Tooltip.types.d.ts +38 -0
  397. package/dist/components/core/tooltip/Tooltip.types.js +9 -0
  398. package/dist/components/core/tooltip/TooltipAnchor.d.ts +52 -0
  399. package/dist/components/core/tooltip/TooltipAnchor.js +69 -0
  400. package/dist/components/core/tooltip/tooltip-anchor.css +145 -0
  401. package/dist/components/core/tooltip/tooltip-impl.css +54 -0
  402. package/dist/components/core/tooltip/use-tooltip.d.ts +111 -0
  403. package/dist/components/core/tooltip/use-tooltip.js +189 -0
  404. package/dist/components/core/typography/Typography.css +96 -0
  405. package/dist/components/core/typography/Typography.d.ts +297 -0
  406. package/dist/components/core/typography/Typography.js +28 -0
  407. package/dist/components/core/typography/Typography.types.d.ts +40 -0
  408. package/dist/components/core/typography/Typography.types.js +7 -0
  409. package/dist/components/css-time.d.ts +20 -0
  410. package/dist/components/css-time.js +30 -0
  411. package/dist/components/given.d.ts +7 -0
  412. package/dist/components/given.js +9 -0
  413. package/dist/components/hover-open.d.ts +34 -0
  414. package/dist/components/hover-open.js +90 -0
  415. package/dist/components/index.d.ts +114 -1
  416. package/dist/components/index.js +115 -2
  417. package/dist/components/layout/aspect-ratio/AspectRatio.css +29 -0
  418. package/dist/components/layout/aspect-ratio/AspectRatio.d.ts +24 -0
  419. package/dist/components/layout/aspect-ratio/AspectRatio.js +26 -0
  420. package/dist/components/layout/aspect-ratio/AspectRatio.types.d.ts +22 -0
  421. package/dist/components/layout/aspect-ratio/AspectRatio.types.js +7 -0
  422. package/dist/components/layout/aspect-ratio/aspect-ratio-impl.css +44 -0
  423. package/dist/components/layout/grid/Grid.css +76 -0
  424. package/dist/components/layout/grid/Grid.d.ts +31 -0
  425. package/dist/components/layout/grid/Grid.js +33 -0
  426. package/dist/components/layout/grid/Grid.types.d.ts +48 -0
  427. package/dist/components/layout/grid/Grid.types.js +7 -0
  428. package/dist/components/layout/grid/grid-impl.css +62 -0
  429. package/dist/components/layout/row/Row.css +85 -0
  430. package/dist/components/layout/row/Row.d.ts +32 -0
  431. package/dist/components/layout/row/Row.js +34 -0
  432. package/dist/components/layout/row/Row.types.d.ts +45 -0
  433. package/dist/components/layout/row/Row.types.js +7 -0
  434. package/dist/components/layout/scroller/Scroller.css +59 -0
  435. package/dist/components/layout/scroller/Scroller.d.ts +34 -0
  436. package/dist/components/layout/scroller/Scroller.js +36 -0
  437. package/dist/components/layout/scroller/Scroller.types.d.ts +38 -0
  438. package/dist/components/layout/scroller/Scroller.types.js +7 -0
  439. package/dist/components/layout/scroller/scroller-impl.css +45 -0
  440. package/dist/components/layout/stack/Stack.css +73 -0
  441. package/dist/components/layout/stack/Stack.d.ts +28 -0
  442. package/dist/components/layout/stack/Stack.js +30 -0
  443. package/dist/components/layout/stack/Stack.types.d.ts +41 -0
  444. package/dist/components/layout/stack/Stack.types.js +7 -0
  445. package/dist/components/visually-hidden.d.ts +22 -0
  446. package/dist/components/visually-hidden.js +31 -0
  447. package/dist/fonts/LICENSE-inter.txt +93 -0
  448. package/dist/fonts/LICENSE-red-hat-mono.txt +93 -0
  449. package/dist/fonts/fonts.css +111 -0
  450. package/dist/fonts/inter-cyrillic-ext-wght-normal.woff2 +0 -0
  451. package/dist/fonts/inter-cyrillic-wght-normal.woff2 +0 -0
  452. package/dist/fonts/inter-greek-ext-wght-normal.woff2 +0 -0
  453. package/dist/fonts/inter-greek-wght-normal.woff2 +0 -0
  454. package/dist/fonts/inter-latin-ext-wght-normal.woff2 +0 -0
  455. package/dist/fonts/inter-latin-wght-normal.woff2 +0 -0
  456. package/dist/fonts/inter-vietnamese-wght-normal.woff2 +0 -0
  457. package/dist/fonts/red-hat-mono-latin-ext-wght-normal.woff2 +0 -0
  458. package/dist/fonts/red-hat-mono-latin-wght-normal.woff2 +0 -0
  459. package/dist/marketing.css +289 -241
  460. package/package.json +18 -4
@@ -0,0 +1,362 @@
1
+ <!-- GENERATED from text-area.contract.json. Do not edit. -->
2
+
3
+ # TextArea
4
+
5
+ A field for what a visitor wants to say in their own words — the message on a contact form, the 'tell us about your project' on an enquiry, the reason someone is applying to partner. One value still, like TextInput, but a value with no shape the page can guess at.
6
+
7
+ That is the whole reason it is not TextInput with a taller box. A single line shows a reader a sliver of what they wrote and no way to read it back, and the one place they most want to check themselves is the paragraph they are about to send a stranger. So it grows as they type, up to a limit, and past that limit it scrolls rather than pushing the submit button off the screen.
8
+
9
+ It is the most expensive thing a marketing form can ask for. Every other field is a fact the reader already knows — a name, an address; this one asks them to compose something, which is why a form that opens with it converts worse than one that earns it. Ask for it last, ask for it once, and say what it is for.
10
+
11
+ ## Use when
12
+
13
+ - A contact form asks what the reader actually wants — the message, the enquiry, the question
14
+ - An application or partner form asks someone to describe what they do in their own words
15
+ - Feedback, where the value of the answer is precisely the part no set of options would have caught
16
+
17
+ ## Do not use
18
+
19
+ - The value is one line — a name, an address, a company → nothing here does this
20
+ - The reader is choosing from a set rather than composing → nothing here does this
21
+ - The page is presenting text rather than collecting it → nothing here does this
22
+ - Opening a form with it. The reader has not decided to spend that much on the page yet, and a large empty box is what tells them how much is being asked
23
+ - Sensitive data. A landing page has no account and no session, and a field big enough for a paragraph is big enough for something that belongs behind a sign-in
24
+ - Anything the page will parse. If the answer has a shape, ask for its shape
25
+
26
+ ## Anatomy
27
+
28
+ TextArea renders 13 elements. A token binding names the part it applies to.
29
+
30
+ - `root` — `<div>`, class `dds-textarea`. Stacks three things: the label row, the box holding the field, and the row beneath it. None of the three is the field itself — which is the shape this arrived at rather than started with, once a tooltip needed to sit beside the label and an icon inside the box. Carries the size and status attributes, which is what lets every part below respond to them.
31
+ - `label-row` — `<div>`, class `dds-textarea__label-row`. Holds the label and, when there is one, the button that explains it. A row exists because the trigger cannot sit inside the <label>: a label forwards its clicks to the field, so a button in there is an ambiguous target and the no-nested-interactive rule refuses it. Always rendered, so the markup has one shape whether the field carries an explanation or not.
32
+ - `label` — `<label>`, class `dds-textarea__label`. Names the field. Always rendered — a field whose label is optional is a field that ships unlabelled.
33
+
34
+ Its height is reserved at size.target.min whether or not the explanation is there. The trigger beside it is a target before it is a mark, so it is at least that tall — and a row taking its height from its contents was two different heights depending on a prop: passing labelTooltip pushed the field, the helper and everything under them down by six pixels. The reserve goes here rather than on the row because a label clipped for a screen reader is out of flow, and a row reserving height for something out of flow is a gap over nothing.
35
+ - `required-mark` — `<span>`, class `dds-textarea__required-mark`. Marks the field as one the user must fill — the word "required", or an asterisk when requiredMark says so. Lowercase and close to the label, so the two read as one phrase rather than as a label with a badge beside it. Hidden from screen readers either way, because aria-required on the field already says it and hearing both says it twice. Which is also what keeps the asterisk usable at all: the glyph carries nothing on its own, so a form using it needs a legend, and a screen reader is told by the attribute rather than by a star. Rendered only when `required` is set.
36
+ - `optional-mark` — `<span>`, class `dds-textarea__optional-mark`. Says "optional" beside the label, lowercase like its counterpart. Not hidden from screen readers: there is no ARIA attribute for optional, so this text is the only thing that carries it — which means it becomes part of the field's accessible name, read as "Label optional". Rendered only when `optional` is set.
37
+ - `label-tooltip` — `<button>`, class `dds-textarea__label-tooltip`. Reveals the explanation, on hover and on focus. A button rather than a bare mark because it is a tab stop by intent: an explanation only a pointer can reach is one half the people using the form never see. Its box is wider than its mark on purpose — the glyph is sized to read beside the label and a target is sized to be hit, which are two decisions. It sits above the field rather than in it, which is the only place it could: the field is a block of lines with no trailing edge to speak of, and a second tab stop inside a prose field would come between the writing and whatever follows it.
38
+
39
+ It paints a background on hover, which is the only thing that shows where the target is. The mark is sixteen pixels and the target is twenty-four, and those are separate decisions by this system’s own rule — so a mark that only changes colour leaves the eight pixels around it invisible until a press either lands or does not. The fill is the same one ButtonIcon uses for a button with no fill of its own, because it is the same button.
40
+
41
+ A press darkens the fill further, and nothing moves. A scale would be the other way to say it, and on a mark this size it moves an edge by a pixel — cost without payoff. The fill also says something a one-shot animation cannot: it holds for as long as the button is held, which is what a stepper repeating ten times a second needs to show. The same two fills ButtonIcon uses, because it is the same button. Rendered only when `labelTooltip` is set.
42
+ - `control` — `<div>`, class `dds-textarea__control`. The box the user sees: the border, the fill, the corner and the inset. The textarea drew all of that itself until a leading icon needed somewhere to sit — a <textarea> can hold text and nothing else, so nothing could ever be inside the box while the textarea was the box. Aligned to the start rather than centred, which is the whole difference from TextInput: there the icon and the value share one line, here the value is a block of lines and an icon centred against it would float in the middle of a paragraph and drift down as the field grew.
43
+ - `field` — `<textarea>`, class `dds-textarea__field`. The control the user types into. Transparent and borderless inside the box, which the control part draws — so the text, the placeholder and the caret are all this element has left to be about. Its height starts at rows and follows the text up to maxRows, after which it scrolls; the browser’s own drag handle is suppressed, because two mechanisms for one height is one too many and only one of them has to be found.
44
+ - `footer` — `<div>`, class `dds-textarea__footer`. The row under the field, holding whatever is being said about it on the left and the count on the right. A row rather than two stacked lines, because a message and a count are one thought about the same field. Its presence follows its contents rather than any one prop: a helper, a status message or a limit each brings it, and with none of them it is absent rather than empty — an empty row in a column with a gap would cost a gap and hold nothing. Rendered when any of `helperText`, `status`, `maxLength` is set, and not otherwise.
45
+ - `helper` — `<span>`, class `dds-textarea__helper`. Guidance the user needs before they type — a format, a constraint, why the field is being asked for. Hidden once the field has a status, because that slot belongs to the status message: guidance shown beside a field reporting something would read as though nothing were wrong. A span rather than a paragraph so it has the same box as the error that replaces it — a <p> carries the browser's own margin, which no token can reach, and the two swapping would shift the layout they exist to keep still. Rendered only when `helperText` is set.
46
+ - `message` — `<span>`, class `dds-textarea__message`. The glyph for the status and what the status means, in the colour of the status. The glyph takes that colour from the text beside it rather than binding one, and is decorative to a screen reader because the words say the same thing — its shape is what separates an error from a warning for a reader who cannot tell those two colours apart. Takes the helper text's place rather than stacking beneath it, so the layout does not shift and the user is never told two things at once. A success status may be silent — it is the one status the contract does not require a message for, an error, a warning and a pending check each needing one — in which case only the border reports it. Rendered only when `status` is set.
47
+ - `message-icon` — `<span>`, class `dds-textarea__message-icon`. The box the status glyph sits in, one line of the message tall with the glyph centred in it.
48
+
49
+ Aligned to the start of the block axis a glyph is as tall as itself, so its middle sits above the first line's and the words beside it read as pushed down. The height is the message's font size times its line height, computed in text-area-impl.css because a binding carries one token and not an expression over two. Absent for a pending check, which has no glyph — marketing has no Spinner to turn. Rendered only when `status` is set.
50
+ - `counter` — `<span>`, class `dds-textarea__counter`. How much of the limit is left, shown only where there is a limit. A maxLength without this refuses a keystroke and says nothing, which is the fault it exists to prevent — so the two arrive together rather than being two decisions a form can get half right. Read out when the field takes focus and not on every keystroke: a count that announces itself as it changes talks over the person typing. Rendered only when `maxLength` is set.
51
+
52
+ Apply these classes from the generated `textAreaParts` constant rather than writing the strings by hand.
53
+
54
+ ## Composition
55
+
56
+ - Takes no children. Everything it renders comes from props
57
+ - Never contains: `Button`, `TextInput` — in children or in any prop that takes a node
58
+
59
+ ## Props
60
+
61
+ ### size — `sm` | `md` | `lg` (default `md`)
62
+
63
+ - `sm` — A note field in a dense form, where the box sits among other controls rather than being what the section is for. The height is unchanged — only the corner tightens
64
+ - `md` — The default, and nearly every form on a page — a contact form in a section, an enquiry beside the copy that prompted it
65
+ - `lg` — A form that is the reason the section exists, matched to the fields around it
66
+
67
+ Use when: Choosing the type and the inset, which is all size means here. It does not set a height — that comes from rows and from the text, so a size and a height are two separate things to decide
68
+
69
+ ### status — `none` | `error` | `warning` | `success` | `pending` (default `none`)
70
+
71
+ - `none` — Nothing has been checked yet, or the value passed and saying so would be noise
72
+ - `error` — The value cannot be accepted and the user has to change it
73
+ - `warning` — The value is accepted but likely wrong — an address that failed a lookup, a name that does not match the account. The user may continue
74
+ - `success` — The value was checked against something and passed, and confirming that is worth the space — an available username, a verified code
75
+ - `pending` — A check is in flight and its outcome is not known yet — a description going through moderation, an address being looked up, a note being scanned before it is filed. The text stays editable throughout, and the border does not change: pending is not a verdict, so nothing about the box should read as one
76
+
77
+ Use when: The outcome of a check, and whether one is running. A prose field is judged after it is written rather than while it is being written, so pending is about a check the page started and not about the typing — moderation, a lookup, anything the reader has to wait on. Where nothing is waiting and nothing has been checked, none is the answer
78
+ Never for: Decoration, or a permanent state. A status is the result of checking a value, so a field that always looks like a warning is telling the user nothing
79
+
80
+ ### label — `string` **Required.**
81
+
82
+ Use when: Always — an input without a label is unusable by screen readers. A noun phrase naming the value, in sentence case: "Email address", not "Enter your email address"
83
+ Never for: The format or the rule, which belong in helperText — a label that explains has stopped naming. And it is a string rather than a node because what joins a label here is the component's own: the required and optional marks render inside it already, so markup passed in would be competing with parts that are declared
84
+
85
+ ### labelTooltip — `string`
86
+
87
+ Use when: A short explanation the label has no room for and the field does not always need on screen — why a description is asked for, what a reviewer will do with it, what counts as enough detail. Revealed on hover and on focus, so it costs no vertical space above a field that is already the tallest thing on the form
88
+ Never for: Anything the user needs before they start writing, which is helperText and belongs on screen. A tooltip is for the reader who stops to ask, and a prose field is exactly where somebody will not stop — they are already typing. And never for the format or the limit: a rule nobody reads is a rule nobody follows, and maxLength has a count of its own for that
89
+
90
+ ### placeholder — `string`
91
+
92
+ Use when: Showing an example of the value's shape, alongside helperText that states the rule
93
+ Never for: The label, or the only place the format is stated. Placeholder text disappears the moment the user types and is not an accessible name
94
+
95
+ ### helperText — `string`
96
+
97
+ Use when: The user needs to know something before they type — a format, a limit, or why this is being asked
98
+ Never for: Validation results, which belong in statusMessage and appear only once validation has run. Note what happens when both are set: any status other than none hides this and shows statusMessage in its place, so guidance and a verdict are never on screen together and the layout does not shift between them
99
+
100
+ ### rows — `number` (default `3`)
101
+
102
+ Use when: The height the field starts at, in lines, which is also the shortest it ever gets. Three says a sentence or two is expected; ten asks for an essay before anybody has read the label, so the number is a statement about the answer wanted
103
+
104
+ ### maxRows — `number` (default `10`)
105
+
106
+ Use when: Where the growing stops and the scrolling starts. Needed rather than optional: a field that grows without limit pushes whatever follows it off the screen, and a submit button nobody can reach is worse than a paragraph nobody can see all of. This and rows are the whole of the height decision, and it is made per placement rather than per person: a reply box a support agent lives in gets a larger number than a one-line-or-two field on a sign-up form. There is deliberately no prop offering the browser’s drag handle as an alternative. A handle is reachable by mouse and by nothing else, so choosing it for a placement hands touch and keyboard users a fixed box with no way past it — and whoever picked it, on a desktop, never feels that. A number here works for everyone
107
+ Never for: A number below rows. The two are a floor and a ceiling, and the contract cannot say so — illegalCombinations compares a prop to a value, never a prop to a prop — so the field takes the larger of the two as its ceiling and opens at the height rows asked for.
108
+
109
+ ### maxLength — `number`
110
+
111
+ Use when: The most the field will accept, which also brings the count that shows it. Give it where the limit is real — a message a system will truncate, a field a database will refuse — and leave it out where prose is simply prose
112
+ Never for: A limit the page enforces later. A field that accepts 400 characters and a form that rejects them is a field that lied, and the count would have been counting toward the wrong number
113
+
114
+ ### statusMessage — `string` **Required when status=error, or when status=warning, or when status=pending.**
115
+
116
+ Use when: Saying what the status means: what is wrong and how to fix it, what to look at, or what was confirmed. Required for an error, a warning and a pending check — the first two because neither is actionable without it, and the third because a wait with nothing said is a field that has stopped responding. The contract refuses all three combinations. Optional for a success, which the border may report on its own
117
+ Never for: Restating the status. "Error" beside a red field says nothing the colour has not already said, and the colour is the part a colour-blind user may not get
118
+
119
+ ### required — `boolean` (default `false`)
120
+
121
+ Use when: The form cannot be submitted without this field, and the user should know before they reach the end
122
+ Never for: Validation. It marks and announces the field as required and nothing more — whether the value is acceptable is still decided by the consumer and said through status and statusMessage, so the browser never raises a message of its own that this system cannot style
123
+
124
+ ### requiredMark — `text` | `asterisk` (default `text`)
125
+
126
+ - `text` — Short forms, public ones, and anywhere the label row has room. The safer default: it needs nothing looked up, it still means something read out of context, and the asterisk convention is learned rather than obvious — which a sign-up or a verification flow cannot assume of everyone using it
127
+ - `asterisk` — Long or dense forms, where the word repeats down the page and one legend can say it once instead — and forms whose labels are too tight for a translated word, since "Required" becomes "Erforderlich" and an asterisk is the same width in every language. Only where a legend is visible from the fields it governs: across steps or a long scroll it is not, and the glyph then says nothing
128
+
129
+ Use when: Choosing how a required field says so. Decide which state is the exception first — mark the required fields or the optional ones, whichever are fewer — and only then how to mark it
130
+ Never for: Varying within one form. Whichever is chosen is a decision for the whole form: a page marking some labels with a word and others with a glyph reads as two conventions and teaches neither
131
+
132
+ ### optional — `boolean` (default `false`)
133
+
134
+ Use when: Most fields on the form are required, so the few that are not are worth marking instead
135
+ Never for: Marking every optional field on a form where most are optional — a marker on almost every label is noise, and the useful signal is whichever state is the exception
136
+
137
+ Also accepts everything from `TextareaHTMLAttributes<HTMLTextAreaElement>`.
138
+
139
+ ## States
140
+
141
+ States you set. Everything else is driven by the browser.
142
+
143
+ - `disabled` — The field is unavailable and the user cannot make it available here
144
+ Avoid when: The field is merely empty — that is what validation is for
145
+ - `readonly` — written `readOnly` in JSX — The value is fixed but still worth reading — a pre-filled account number, a computed total, something awaiting verification. The field stays focusable and its text selectable, which is what separates it from disabled
146
+ Avoid when: The field is unavailable rather than fixed. That is disabled, and it recedes
147
+
148
+ ## Accessibility
149
+
150
+ Guaranteed by the component. Write none of it by hand: the ids these attributes point at are generated per instance, so an attribute set from outside either says the same thing twice or points at nothing.
151
+
152
+ - Announced as: `textbox`
153
+ - `Tab` — move focus
154
+ - programmatic label association
155
+ - aria-invalid when the status is an error
156
+ - aria-describedby pointing at statusMessage
157
+ - aria-describedby pointing at helperText when no status is showing
158
+ - aria-required when required
159
+ - the count is described rather than announced — read when the field takes focus, and not again on every keystroke, because a number that talks as it changes talks over the typing
160
+ - aria-busy while a check is in flight, and a spinner beside the message that says what is being waited on
161
+
162
+ ## Rules
163
+
164
+ - **On a phone a section's actions stack and each fills the width, including when there is only one** — On a phone a page's actions stack, and each one fills the width. Not most of it, and not the width its label happens to need — the whole column.
165
+
166
+ Two side by side is what this replaces. On the narrowest screen each gets half a column minus the gap, which is rarely enough for a real label: the words wrap inside the pills, the two buttons come out different heights, and the pair reads as a broken row rather than as a choice. Stacked, each has the whole width and neither has to shorten its words to fit.
167
+
168
+ A single action fills too, and that is the part worth saying, because it is the one that looks unnecessary. A lone button has the room to sit at its natural width and still should not: a full-width control is the phone's convention for the thing the screen is asking you to do, and a pill hugging its label reads as one option among others that are not there. It also makes the target predictable — the whole width, wherever the thumb lands — which a centred pill does not.
169
+
170
+ Filling is the row's job rather than the button's. A button has no width of its own and is not given one; the row it sits in becomes a column and stretches its children, so nothing about the control changes and the same button is full width here and its own size on a desktop.
171
+
172
+ This is the phone's breakpoint, size.breakpoint.md, and not the wider one that decides whether a heading is centred. Those are different questions and they break at different widths: a heading stops being centred when the measure is the screen, while a button stops being full width much sooner than that — stretched across a tablet it is a long way from its own label, and a label centred in a metre of pill is harder to hit than one in a pill the size of the words.
173
+
174
+ What this is not about is every row of controls. A set of filter chips, a pagination strip, a toolbar, a link sitting after a sentence — none of these is the page asking for something, and stacking them to full width would turn a strip the eye skims into a list it has to read. The test is whether the row is the call to action the section was written for.
175
+ Guidance only — cannot be checked automatically.
176
+ - **Never nest one interactive element inside another** — Nested interactive elements produce ambiguous hit targets and an unreachable inner control for keyboard and screen-reader users. This is why the rule cannot live on any single component — it constrains Button, Link, Input and Switch simultaneously.
177
+ Guidance only — cannot be checked automatically.
178
+ - **A section that paints a ground sets the ink to go with it** — A page sits on color.bg.page, and a section that separates itself from it takes one of three grounds. color.bg.subtle is the light one and needs nothing further — the page's own ink still reads on it. The other two are dark and do not: color.bg.brand-strong takes color.fg.on-brand-strong, and color.bg.brand takes color.fg.on-solid. Both are white, and both are written as the role rather than the white they resolve to. Set one of those backgrounds without its ink and the text inherits whatever the page was already using, which is near-black on a dark band — legible to nobody, and invisible to every check here, because each pair passes contrast on its own and nothing can tell whether a section used both.
179
+
180
+ color.bg.brand carries a second limit that is not about forgetting. Its ink measures 3.39:1, which clears the 3:1 a heading needs and misses the 4.5:1 running copy needs. A coral band may carry a headline and a call to action; a paragraph on one is text the reader has to work through at a ratio the waiver on that role does not cover — the waiver says so itself. A section with copy in it takes color.bg.brand-strong, which is near-black and carries white at full contrast.
181
+
182
+ color.bg.strong is not a section ground. It is the inverted fill for an action that has to outrank what surrounds it, and the components that paint it — Button and ButtonIcon in their inverse form — already set both halves in one rule, which is the pattern a hand-painted section has to copy.
183
+ Guidance only — cannot be checked automatically.
184
+ - **Every gap inside a section names the relationship it expresses, and the same relationship keeps its measure when it turns on its side** — A section's spacing is named by the relationship it expresses, not chosen by size. Every gap in a section has a role token, and reaching for a step off the generic scale because it happens to be the right number is how two sections written by two people stop lining up: the numbers agree today and drift the first time one of them is tuned.
185
+
186
+ The heading group is three steps, not one gap. An eyebrow sits nearer its title than the title sits to its description, and the actions sit further from the description than either — space.heading.eyebrow-title, space.heading.title-description, space.heading.description-actions, in that order. A single `gap` on the group cannot say this; it sets all three the same and the block reads as evenly spaced lines rather than as a mark, a name and a paragraph. The eyebrow has to identify itself for this to work, because a group that opens with a title must not give its description the eyebrow's tighter step.
187
+
188
+ The step between a title and its description follows the size of the title, which is why there are two of it. What a reader sees is not the gap but the gap plus the leading above it, and leading scales with the type: under a display title the leading is most of the space, under a card's title it is half as deep. One value for both makes a card look loose at the size that made a section look right. So space.heading.title-description is the display step and space.heading.title-description-compact is the step at a card's size, and the choice is made by how big the title is rather than by what kind of block it sits in.
189
+
190
+ Every one of those steps is smaller than the gap below the group, and that ordering is what holds the group together as one thing. space.heading.content is the step between a heading group and the content it introduces, and it is the widest measure inside a section: the one gap the eye reads as a change of subject rather than as a continuation.
191
+
192
+ That step is the same whether the content is under the heading or beside it. A split is the same relationship turned on its side — a heading group and the content it introduces — so the space between the two halves is space.heading.content, not a gutter. When the split collapses to one column on a phone the gap becomes vertical again, which is where it started, and nothing has to change for that to be right.
193
+
194
+ space.grid.gutter is between two things of the same kind. Two cards in a row are the same kind; the two halves of a split are not, which is why the gutter is the wrong measure there even when the number would have looked acceptable. The gutter runs on both axes, so a grid reads as an even field rather than as rows with a seam down them.
195
+
196
+ space.inset.card is the card's, not the page's. A row of cards padded differently is a row of different cards, and the fill is the only edge they have. A page composing a row does not get to choose it.
197
+
198
+ Column count is not a breakpoint decision. A row holds as many columns as fit before a column would be narrower than size.grid.column-min, and drops one when they would not. Written as a fixed count that collapses at a breakpoint, a four-up row keeps four columns at every width above the phone and sets its copy two or three words to a line through the whole of the tablet range — and on a narrow desktop, which no breakpoint sits on at all. The threshold is a property of the row rather than of a card: a card fills whatever cell it is given.
199
+
200
+ What this does not cover is the space above and below a section, which is space.section.default and space.section.compact, and the page's own side margin, which is space.inset.page. Those are the section's outside; everything here is its inside.
201
+ Guidance only — cannot be checked automatically.
202
+ - **A section's title is centred over stacked content, starts beside content in columns, and starts on a phone** — Two arrangements, and the title's alignment is decided by which one it is introducing rather than chosen per section.
203
+
204
+ Content stacked under the title — a row of cards, an accordion, a set of steps — takes a centred title. The heading group and the block below it share one axis, so a centred title is symmetric with the thing it names, and the eye drops from the middle of the words to the middle of the set. A title starting at the left over a centred or full-width block reads as belonging to the first column rather than to all of them.
205
+
206
+ Content beside the title — a split, a picture in the other half, anything laid out in columns — takes a title that starts where its content starts. The two share a left edge, and that edge is what says they are one thing read across rather than two stacked. Centring the title there breaks the only alignment the reader has to hold the halves together, and it drifts further from its content the wider the page gets.
207
+
208
+ The heading group is what carries this, not the heading alone. An eyebrow, a title and a description are read as one block and align together; aligning the title without them leaves a centred heading over start-aligned copy, which reads as a mistake rather than as a choice.
209
+
210
+ Centred means all of it, not just the words. A badge, a row of actions, a picture — these are flex children, and a flex child is placed by align-items rather than by text-align, so a block that only sets the text leaves everything that is not text at the start. A hero is the case that shows it: its title and copy centred while its badge and its buttons did not.
211
+
212
+ A capped block centres itself as well as its words. A heading group takes size.heading-group.max, and a cap that is not centred leaves the measure at the start of the column with the words centred inside it — composed, and a long way left of the middle it appears to be in.
213
+
214
+ Both arrangements go to the start on a phone. A centred block reverts below the breakpoint, and the reason is the measure: on a phone the measure is the screen, so a centred title wraps to three or four ragged lines and the eye loses the left edge it was tracking — the same symmetry that reads as composure on a desktop is what makes it hard to scan on a phone. Centring there has to be asked for twice, and a section title is not one of the things that asks: it is centred because there is room for it, and on a phone there is not. Going back to the start means all of it too, and a capped block is the one that hides a leftover: its words go to the start while its measure stays in the middle of the column, which reads as a title still centred over a badge and buttons that are not — the box in the middle and the line inside it at the edge.
215
+
216
+ A hero is a section like any other: its badge, title, copy and actions are one stacked block, so it is centred on a desktop and starts on a phone with everything else.
217
+
218
+ What this is not about is a page whose body is a form or a document. A title over a sign-up form or a guide is not introducing a set of content — it is the first line of the thing itself, and it keeps the alignment the body has, which for running text is the start. The distinction is whether the block below is content the title names or content the title is part of.
219
+ Guidance only — cannot be checked automatically.
220
+ - **Anything a pointer has to hit is at least 24px in both directions** — A control sized by its contents is as big as its contents, and a glyph is chosen for how it reads rather than for how easily it is hit. An icon-only button with no padding is a 16px target — smaller than the pad of a finger, and smaller than the tremor of a hand using a mouse.
221
+
222
+ WCAG 2.2 asks for 24 by 24 CSS pixels at AA. The exceptions are narrower than they look: inline targets inside a sentence are exempt, and so is a small target with 24px of clear space around it — but a clear button sits against the field it empties, and a field is itself a target, so the spacing exemption does not apply to the case that keeps arising.
223
+
224
+ The target and the mark are separate decisions, and conflating them is what produces both faults. Growing the glyph to 24px makes it shout; leaving the button at 16px makes it hard to hit. So the glyph keeps the size that reads correctly beside its text, and the box around it declares a minimum of its own — which is what size.target.min is for.
225
+
226
+ Declared rather than emergent. Padding plus contents does clear 24px in several components today, and it is the weaker statement: it is a size nobody wrote down, so it moves when the type scale or the glyph does, and nothing says it was meant to be a target at all.
227
+ Guidance only — cannot be checked automatically.
228
+
229
+ ## Anti-examples
230
+
231
+ ❌ TextArea for: The value is one line — a name, an address, a company
232
+ TextInput. A box three lines tall asks for three lines, and a reader who gives one has been shown a form that misjudged what it wanted from them.
233
+ → nothing in this system does this. Not a gap waiting to be filled — the case belongs outside it.
234
+
235
+ ❌ TextArea for: The reader is choosing from a set rather than composing
236
+ Nothing here does this yet. Free text where a choice was meant has to be parsed, corrected and matched, and every mismatch is a submission the page silently loses.
237
+ → nothing in this system does this. Not a gap waiting to be filled — the case belongs outside it.
238
+
239
+ ❌ TextArea for: The page is presenting text rather than collecting it
240
+ That is copy. A read-only field holding a paragraph is a paragraph in a box, with a scrollbar the reader did not ask for and none of the typography the page sets for prose.
241
+ → nothing in this system does this. Not a gap waiting to be filled — the case belongs outside it.
242
+
243
+ ❌ required=true + optional=true
244
+ A field is one or the other, and marking it both says nothing
245
+
246
+ ❌ status=error + statusMessage missing or empty
247
+ An error with no explanation leaves the user stuck
248
+
249
+ ❌ status=warning + statusMessage missing or empty
250
+ A warning with no explanation is a field the user cannot act on
251
+
252
+ ❌ status=pending + statusMessage missing or empty
253
+ A wait with nothing said is a field that has stopped responding. TextInput allows this and puts a spinner at the trailing edge of its box instead — a one-line field has room beside the value. The same position here is the bottom-right corner of a block, which is the counter and, past maxRows, the scrollbar. So there is nowhere inside the field for a mark to go, and the words in the footer are the only thing that can carry it
254
+
255
+ ## Example
256
+
257
+ ```tsx
258
+ import { TextArea } from '@deriv-com/dds-marketing'
259
+
260
+ <TextArea label="Your message" placeholder="What can we help with?" helperText="We reply to every enquiry within two working days." rows={4} maxLength={500} />
261
+ ```
262
+
263
+ ```tsx
264
+ import { useState } from 'react'
265
+ import { TextArea } from '@deriv-com/dds-marketing'
266
+
267
+ // Controlled: TextArea reports the DOM event, so the value is read off it.
268
+ // Unlike AmountInput and SearchInput, which declare an onChange that hands back the
269
+ // value itself — the two shapes look the same at the call site and are not.
270
+ const [value, setValue] = useState('')
271
+ <TextArea label="Your message" placeholder="What can we help with?" helperText="We reply to every enquiry within two working days." rows={4} maxLength={500} value={value} onChange={(event) => setValue(event.target.value)} />
272
+ ```
273
+
274
+ ## In use
275
+
276
+ ### Three sizes, three jobs
277
+
278
+ The small one only tightens the corner — rows set the height. The default sits in a section's contact form. The large one matches a form the section is built around.
279
+
280
+ ```tsx
281
+ import { TextArea } from '@deriv-com/dds-marketing'
282
+
283
+ // sm — only the corner; rows still set the height
284
+ <TextArea label="Your message" placeholder="What can we help with?" size="sm" />
285
+
286
+ // md — a contact form inside a section
287
+ <TextArea label="Your message" placeholder="What can we help with?" size="md" />
288
+
289
+ // lg — the form a whole band is built around
290
+ <TextArea label="Your message" placeholder="What can we help with?" size="lg" />
291
+ ```
292
+
293
+ ### It grows with what is typed
294
+
295
+ rows is the floor and maxRows the ceiling. Past the ceiling the box stops growing and scrolls, so a long message never pushes the submit button off the screen.
296
+
297
+ ```tsx
298
+ import { TextArea } from '@deriv-com/dds-marketing'
299
+
300
+ // The default — three lines, room for ten
301
+ <TextArea label="Your message" placeholder="What can we help with?" />
302
+
303
+ // A short box that still grows to ten
304
+ <TextArea label="Your message" placeholder="What can we help with?" rows={2} />
305
+
306
+ // A box that never grows: floor meets ceiling
307
+ <TextArea label="Your message" placeholder="What can we help with?" rows={4} maxRows={4} />
308
+ ```
309
+
310
+ ### Saying how much room there is
311
+
312
+ maxLength draws a count beside the helper. The limit is the one the page will honour — a field that accepts 500 and a form that rejects them is a field that lied.
313
+
314
+ ```tsx
315
+ import { TextArea } from '@deriv-com/dds-marketing'
316
+
317
+ // A limit, and the count that goes with it
318
+ <TextArea label="Your message" placeholder="What can we help with?" maxLength={500} />
319
+
320
+ // A limit beside a helper, sharing the footer
321
+ <TextArea label="Your message" placeholder="What can we help with?" maxLength={500} helperText="Tell us roughly what you need — detail helps us route it." />
322
+ ```
323
+
324
+ ### The four verdicts a check can return
325
+
326
+ Each carries a message. The colour is the part a colour-blind reader may miss and the shape beside it is the part that survives.
327
+
328
+ ```tsx
329
+ import { TextArea } from '@deriv-com/dds-marketing'
330
+
331
+ // error — the message has to change
332
+ <TextArea label="Your message" placeholder="What can we help with?" status="error" statusMessage="Tell us a little about what you need before sending." />
333
+
334
+ // warning — it will send, but it is thin
335
+ <TextArea label="Your message" placeholder="What can we help with?" status="warning" statusMessage="A sentence or two helps us route this to the right person." />
336
+
337
+ // success — a check ran and passed
338
+ <TextArea label="Your message" placeholder="What can we help with?" status="success" statusMessage="Thanks — we have everything we need." />
339
+
340
+ // pending — no spinner; the words are all
341
+ <TextArea label="Your message" placeholder="What can we help with?" status="pending" statusMessage="Sending your message…" />
342
+ ```
343
+
344
+ ### Marking what the form expects
345
+
346
+ Mark the exception, not the rule. A form where every field carries a mark has said the same as one where none does.
347
+
348
+ ```tsx
349
+ import { TextArea } from '@deriv-com/dds-marketing'
350
+
351
+ // required — the word, which needs no key
352
+ <TextArea label="Your message" placeholder="What can we help with?" required requiredMark="text" />
353
+
354
+ // requiredMark asterisk — for a dense form
355
+ <TextArea label="Your message" placeholder="What can we help with?" required requiredMark="asterisk" />
356
+
357
+ // optional — the one field that may be skipped
358
+ <TextArea label="Your message" placeholder="What can we help with?" optional />
359
+
360
+ // labelTooltip — a sentence the label has no room for
361
+ <TextArea label="Your message" placeholder="What can we help with?" labelTooltip="We use this to route your enquiry, and nothing else." />
362
+ ```