@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,467 @@
1
+ <!-- GENERATED from text-input.contract.json. Do not edit. -->
2
+
3
+ # TextInput
4
+
5
+ One line of text a visitor types before they are a customer. A marketing page asks for very little and has no standing to ask for more: an email for a newsletter, a name and a message on a contact form, a work address to book a demo. Every one of those is a stranger deciding whether the thing on offer is worth handing something over for, and the field is where that decision gets made or lost.
6
+
7
+ That is the whole difference from a field in an application, and it is why this is not Product's TextInput with fewer props. An app's field is filled by someone who has already signed up, inside a task they have committed to, and can afford to ask for an account number in a particular format. A landing page's field is filled by someone with no account, no stake, and a back button — so it asks for one thing, says what it will do with it, and is legible enough at a glance that nobody has to work out what goes in it.
8
+
9
+ One field for one value — and it now carries the same furniture Product's does: affixes, ornaments, a clear button, an explanation beside the label, and the four verdicts a check can return. What is still not here is the family. A one-time code, a phone field with country logic, an amount field with its own arithmetic: those are components rather than props, and a page needing one has stopped being marketing.
10
+
11
+ ## Use when
12
+
13
+ - A page asks for an email — a newsletter, a waitlist, a download behind an address
14
+ - A short form stands between the reader and something they want: a demo booking, a contact request, a callback
15
+ - A value is genuinely one line and the reader can type it without looking anything up
16
+
17
+ ## Do not use
18
+
19
+ - The value is more than a line — a message, a description, an enquiry → nothing here does this
20
+ - The reader is choosing from a set rather than typing → nothing here does this
21
+ - The field is a query against something on the page → nothing here does this
22
+ - Asking for more than the page has earned. Every extra field is a reason to leave, and a marketing form is judged on how little it asks — a name and an email convert where a name, an email, a company, a role and a phone number do not
23
+ - Sensitive data. A landing page has no account, no session and usually no reason to be trusted with anything more than an address. Card numbers, identity documents and passwords belong behind a sign-in, on a page built to hold them
24
+ - A label the reader cannot see. The placeholder is not a label — it disappears the moment they type, taking with it the only thing telling them what the field was for, and it is the first thing lost when someone comes back to check what they filled in
25
+ - Layout. A disabled field holding a value the reader cannot change is not a way to present information — that is copy, and it reads better as copy
26
+
27
+ ## Anatomy
28
+
29
+ TextInput renders 16 elements. A token binding names the part it applies to.
30
+
31
+ - `root` — `<div>`, class `dds-textinput`. The field and everything that explains it, stacked. A column rather than a row: a label beside its field survives one language and one width, and a marketing page is neither — it is translated, and it is read at 360 pixels as often as at 1440.
32
+
33
+ It is the stacking context for the whole component, so the gap between the label, the control and whatever sits underneath is one decision made here rather than three margins that drift apart.
34
+ - `label-row` — `<div>`, class `dds-textinput__label-row`. Holds the label and, when there is one, the button that explains it. 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.
35
+
36
+ Always rendered, so the markup has one shape whether the field carries an explanation or not.
37
+ - `label` — `<label>`, class `dds-textinput__label`. What the field is for, in words, above it and always drawn.
38
+
39
+ Always, and this is the one thing about this component not open to negotiation. A placeholder is not a label: it vanishes on the first keystroke, so the reader loses it exactly when they start needing it, and it is gone entirely when they come back to check what they typed. A field labelled only by its placeholder is also a field a screen reader announces as "edit blank" the moment the user has typed anything at all.
40
+
41
+ It is a real `<label>` with a `for`, rather than an `aria-label` on the input. Clicking the words focuses the field, which is the behaviour every reader already expects and the one thing `aria-label` cannot give them.
42
+ - `required-mark` — `<span>`, class `dds-textinput__required-mark`. The mark beside the label saying this one cannot be skipped. Red, in `color.fg.required` rather than `color.fg.danger` — the same colour today and a separate decision, because required is not a verdict. A field marked required has not failed anything yet, and the day error red moves, this should not move with it unless somebody decides it should.
43
+
44
+ It is a mark and not the message. Carrying the requirement in colour alone would leave it to a reader who can see red, which is why `aria-required` on the field says the same thing in the accessibility tree and neither one is doing the job alone. Rendered only when `required` is set.
45
+ - `optional-mark` — `<span>`, class `dds-textinput__optional-mark`. The word beside the label saying this one may be skipped.
46
+
47
+ Not hidden from screen readers, unlike the required mark: there is no ARIA attribute for optional, so this text is the only thing carrying it. It joins the accessible name and is read as 'Label optional' — verbose, and the alternative is saying nothing at all. Rendered only when `optional` is set.
48
+ - `label-tooltip` — `<button>`, class `dds-textinput__label-tooltip`. The button that reveals the explanation, drawn beside the label rather than under it.
49
+
50
+ A tab stop by intent. An explanation only a pointer can reach is one half the people filling the form never see, and the cost is one stop before a field that opted into having more to say. Rendered only when `labelTooltip` is set.
51
+ - `control` — `<div>`, class `dds-textinput__control`. The box the reader aims at: the border, the ground, the radius and the focus ring live here rather than on the input.
52
+
53
+ A wrapper around a single input looks like an element that does nothing, and it is the opposite. It is what lets the field be styled as a target without touching the input's own box, which browsers style in ways that differ per platform and are not entirely overridable; and it is where a leading glyph or a clear button would attach the day this component earns one. Without it, adding either means re-drawing the border somewhere else and every bound token moves.
54
+ - `leading-icon` — `<span>`, class `dds-textinput__leading-icon`. A mark at the start of the field, before the value. Decoration that hints at what goes in the box — never the label, which is drawn above and always. Rendered only when `leadingIcon` is set.
55
+ - `prefix` — `<span>`, class `dds-textinput__prefix`. Fixed text before the value, inside the box — a currency mark, a scheme. Part of the field's furniture and not part of its value: it is never submitted, and the reader cannot select or edit it. Rendered only when `prefix` is set.
56
+ - `field` — `<input>`, class `dds-textinput__field`. The input itself, transparent and borderless — the control around it draws all of that. It carries the text, the placeholder, the type, and every state the browser owns.
57
+
58
+ Its own background is `transparent` rather than a ground of its own, so the control's ground shows through and the readonly and disabled states each need colouring in one place instead of two that can disagree.
59
+ - `suffix` — `<span>`, class `dds-textinput__suffix`. Fixed text after the value, inside the box — a unit, a domain. The same furniture as the prefix, at the other edge. Rendered only when `suffix` is set.
60
+ - `clear` — `<button>`, class `dds-textinput__clear`. The button that empties the field, drawn at its trailing edge once there is something to empty.
61
+
62
+ Gone when the value is not the reader's to change. Dimming it was not enough: the button sits inside the control, so the disabled state's opacity made it look unavailable while it stayed live and still emptied the field. Rendered only when `clearable` is set. Not rendered at all while `disabled` or `readonly`.
63
+ - `trailing-icon` — `<span>`, class `dds-textinput__trailing-icon`. A mark at the end of the field, after the value. It holds the trailing edge, and the clear button appears inside it rather than shoving it sideways on every keystroke. Rendered only when `trailingIcon` is set.
64
+ - `helper` — `<span>`, class `dds-textinput__helper`. Standing guidance under the field — what the address is for, what happens after they press send. It is there before anything goes wrong and stays there while the reader types.
65
+
66
+ On a marketing form this is often the most valuable line on the page: "We will only email you about the launch" is the sentence that decides whether the address is real, and it belongs under the field rather than in the privacy policy.
67
+
68
+ It gives way to the message when there is one. Both at once is two lines of small grey and red text under a field the reader is trying to fix, and the one that matters is the one they did not expect. Rendered only when `helperText` is set.
69
+ - `message` — `<span>`, class `dds-textinput__message`. What went wrong, and enough to fix it. Replaces the helper rather than joining it.
70
+
71
+ It says what to do, not that something is wrong: the field is already red and the reader can see that. "Enter an address like name@example.com" is a message; "Invalid" is the component telling the reader they have failed and leaving them there.
72
+
73
+ It is announced as well as drawn — `aria-describedby` points the field at it — because a reader who submitted and was bounced back to a field they cannot see the bottom of gets nothing from a red line.
74
+
75
+ A glyph sits beside the words, so a status is never carried by colour alone — red and the shape of a circled exclamation say the same thing to a reader who cannot tell the red from the grey. Rendered only when `status` is set.
76
+ - `message-icon` — `<span>`, class `dds-textinput__message-icon`. The box the status glyph sits in, and the reason it is a part rather than the bare Icon it started as.
77
+
78
+ Aligned to the start of the block axis, a glyph is a flex item as tall as itself — sixteen pixels against a line of type that is twenty-one — so its middle sat above the first line's and the words beside it read as pushed down. This is a box exactly one line of the message tall with the glyph centred in it, which puts the two middles on each other whatever the line turns out to hold.
79
+
80
+ It carries the message's own font size and line height and nothing else; the height is those two multiplied, which happens in text-input-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.
81
+
82
+ Apply these classes from the generated `textInputParts` constant rather than writing the strings by hand.
83
+
84
+ ## Composition
85
+
86
+ - Takes no children. Everything it renders comes from props
87
+
88
+ ## Props
89
+
90
+ ### size — `sm` | `md` | `lg` (default `md`)
91
+
92
+ - `sm` — A field in a dense desktop arrangement — a filter row above a list, a field beside body copy rather than heading a section. Not on a phone, where thirty-two is below what a finger reliably hits
93
+ - `md` — The default, and nearly every form on a page — an inline signup, a contact form in a section
94
+ - `lg` — A hero's single field, or a conversion band where the form is the reason the section exists and has to be found from a distance
95
+
96
+ ### status — `none` | `error` | `warning` | `success` | `pending` (default `none`)
97
+
98
+ - `none` — Nothing has been checked yet, which is the field for nearly all of its life — including before it has been filled in. Empty is not an error
99
+ - `error` — Validation has failed and the reader has to change the value before the form will go anywhere
100
+ - `warning` — The value is usable but worth a second look — a work address on a form that expected a personal one. The reader may keep it
101
+ - `success` — A check has run and passed, and saying so is worth a line — an address confirmed as deliverable before the reader commits to it
102
+ - `pending` — A check is in flight. The value is still the reader's to change while it runs
103
+ 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 reader nothing
104
+
105
+ ### type — `text` | `email` | `tel` | `url` (default `text`)
106
+
107
+ - `text` — A name, a company, anything with no keypad or validation of its own
108
+ - `email` — An address. It brings the right keypad on a phone — the @ without a modifier — which is the difference between a typo and a lost signup
109
+ - `tel` — A phone number, for the numeric keypad. It does no validation and should not pretend to: numbers differ by country and a field that rejects a valid one is worse than a field that accepts anything
110
+ - `url` — A website, on a form that asks for one
111
+ Never for: Standing in for validation. The type chooses a keypad and a browser hint; what makes an address real is checked after the reader has submitted, and said in the message
112
+
113
+ ### label — `string` **Required.**
114
+
115
+ Use when: Always — it names the field, it is drawn, and clicking it focuses the input. One or two words: 'Email', 'Full name', 'Work email'
116
+ Never for: A sentence, or an instruction. What the field will do with the value is the helper's job, and a label long enough to wrap stops being something the eye can pair with a box
117
+
118
+ ### labelTooltip — `string`
119
+
120
+ Use when: A field needs a sentence the label has no room for — why the address is being asked for, what happens to it
121
+ Never for: Anything the reader must read to fill the field in. A tooltip is opened on purpose, so what is behind it is what a reader chose to want; the format and the consequence belong in helperText, which is simply there
122
+
123
+ ### placeholder — `string`
124
+
125
+ Use when: Showing the shape of the value where the shape is not obvious — 'name@example.com' on an email field. It is an example, and it is allowed to be skipped
126
+ Never for: The label. It disappears on the first keystroke, it is gone when the reader comes back to check, and it is announced as nothing once the field has text in it
127
+
128
+ ### helperText — `string`
129
+
130
+ Use when: Saying what happens to the value — what the page will send, how often, what it will not do with the address. On a marketing form this is frequently what decides whether the reader types a real one
131
+ Never for: Repeating the label in a longer form. A field labelled 'Email' with a helper reading 'Enter your email' has spent a line saying nothing
132
+
133
+ ### leadingIcon — `node`
134
+
135
+ Accepts: QuillSystemIcon
136
+ Use when: A mark that says what the field takes at a glance — an envelope on an address, a globe on a site
137
+ Never for: The label. A glyph names nothing on its own, and a field identified only by a picture is a guess
138
+
139
+ ### prefix — `string`
140
+
141
+ Use when: A fixed part of the value the reader should not have to type — a currency mark, https://
142
+ Never for: Part of the value you expect back. It is furniture: it is never submitted and the reader cannot edit it
143
+
144
+ ### suffix — `string`
145
+
146
+ Use when: A fixed tail — a unit, a domain every address on this form shares
147
+ Never for: A unit the reader might need to change. If it is a choice it is a control, not a label stuck to the end of the box
148
+
149
+ ### trailingIcon — `node`
150
+
151
+ Accepts: QuillSystemIcon
152
+ Use when: A mark at the far edge that comments on the value rather than introducing it
153
+ Never for: Anything pressable. It is an ornament, not a control — a button in here has no name and no keyboard route
154
+
155
+ ### clearable — `boolean` (default `false`)
156
+
157
+ Use when: A field the reader is likely to retype rather than edit — a search term, a long address typed on a phone
158
+ Never for: A short field on a desktop form. Select-all and type is already one gesture, and the button costs a target inside the box for every field that has one
159
+
160
+ ### clearLabel — `string` **Required when clearable=true.**
161
+
162
+ Use when: Required whenever clearable is set. It is the button's only name — the glyph says nothing to a screen reader
163
+ Never for: Describing the field. 'Clear email address' names the action; 'Email address' names the thing it acts on and is read as a second field
164
+
165
+ ### inputMode — `numeric` | `decimal`
166
+
167
+ - `numeric` — Digits and nothing else — a postcode, a reference number
168
+ - `decimal` — A number that may carry a separator — an amount
169
+ Never for: Validation, or type. It chooses the keypad a phone raises and constrains nothing at all
170
+
171
+ ### statusMessage — `string` **Required when status=error, or when status=warning.**
172
+
173
+ Use when: Saying what to change, when the status is an error. It replaces the helper while it is showing
174
+ Never for: Announcing that something is wrong without saying what. The field is already red — a message reading 'Invalid' has added a colour and no information
175
+
176
+ ### required — `boolean` (default `false`)
177
+
178
+ Use when: The form cannot be sent without this one, and the reader is better off knowing before they reach the button. It draws the mark and sets aria-required
179
+ Never for: Validation. It says a field must be filled; whether what was filled in is any good is the status's job, after they submit
180
+
181
+ ### requiredMark — `text` | `asterisk` (default `text`)
182
+
183
+ - `text` — The default. The word 'required' says what it means in the reader's own language and needs no key
184
+ - `asterisk` — A dense form where the word would repeat down the column, and a legend explains the mark once
185
+ Never for: Carrying the requirement on its own. The mark is decorative either way — aria-required on the field is what says it to a screen reader
186
+
187
+ ### optional — `boolean` (default `false`)
188
+
189
+ Use when: Most of the form is required and one field is not. Marking the exception is what tells the reader anything
190
+ Never for: Every field on a form where nothing is required. Marking all of them says the same as marking none, and costs a word on each
191
+
192
+ Also accepts everything from `InputHTMLAttributes<HTMLInputElement>`.
193
+
194
+ ## States
195
+
196
+ States you set. Everything else is driven by the browser.
197
+
198
+ - `disabled` — The field is unavailable and nothing the reader does here will change that — a form waiting on something else to finish
199
+ Avoid when: The field is merely empty, or the form has not been submitted yet. A form that opens with half its fields switched off is a puzzle
200
+ - `readonly` — written `readOnly` in JSX — The value is fixed but still worth reading — an address carried over from the previous step. It stays focusable and its text stays selectable, which is what separates it from disabled
201
+ Avoid when: Presenting information the reader cannot change. That is copy, and a greyed-out box is a worse way to show it
202
+
203
+ ## Accessibility
204
+
205
+ 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.
206
+
207
+ - Announced as: `textbox`
208
+ - `Tab` — move focus
209
+ - programmatic label association
210
+ - aria-invalid when the status is an error
211
+ - aria-describedby pointing at statusMessage
212
+ - aria-describedby pointing at helperText when no status is showing
213
+ - aria-required when required
214
+
215
+ ## Rules
216
+
217
+ - **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.
218
+
219
+ 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.
220
+
221
+ 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.
222
+
223
+ 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.
224
+
225
+ 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.
226
+
227
+ 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.
228
+ Guidance only — cannot be checked automatically.
229
+ - **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.
230
+ Guidance only — cannot be checked automatically.
231
+ - **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.
232
+
233
+ 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.
234
+
235
+ 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.
236
+ Guidance only — cannot be checked automatically.
237
+ - **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.
238
+
239
+ 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.
240
+
241
+ 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.
242
+
243
+ 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.
244
+
245
+ 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.
246
+
247
+ 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.
248
+
249
+ 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.
250
+
251
+ 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.
252
+
253
+ 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.
254
+ Guidance only — cannot be checked automatically.
255
+ - **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.
256
+
257
+ 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.
258
+
259
+ 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.
260
+
261
+ 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.
262
+
263
+ 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.
264
+
265
+ 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.
266
+
267
+ 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.
268
+
269
+ 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.
270
+
271
+ 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.
272
+ Guidance only — cannot be checked automatically.
273
+ - **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.
274
+
275
+ 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.
276
+
277
+ 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.
278
+
279
+ 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.
280
+ Guidance only — cannot be checked automatically.
281
+
282
+ ## Anti-examples
283
+
284
+ ❌ TextInput for: The value is more than a line — a message, a description, an enquiry
285
+ Nothing here does this yet. A single-line field holding a paragraph shows the reader a sliver of what they wrote and no way to read it back, which on a contact form is the one place they most want to check themselves before sending.
286
+ → nothing in this system does this. Not a gap waiting to be filled — the case belongs outside it.
287
+
288
+ ❌ TextInput for: The reader is choosing from a set rather than typing
289
+ Nothing here does this either, and typing where a choice was meant is worse than it looks: free text has to be parsed, corrected and matched, and every mismatch is a submission the page silently loses.
290
+ → nothing in this system does this. Not a gap waiting to be filled — the case belongs outside it.
291
+
292
+ ❌ TextInput for: The field is a query against something on the page
293
+ A search is its own component, not a text field with a magnifier in it — it owns a submit gesture and what happens on empty. The clear button is here now; those two are not, and a field pressed into the job is still missing them.
294
+ → nothing in this system does this. Not a gap waiting to be filled — the case belongs outside it.
295
+
296
+ ❌ status=error + statusMessage missing or empty
297
+ A field turned red with nothing saying why is a reader stuck at a form with no way forward — and on a marketing page, a reader who leaves
298
+
299
+ ❌ status=warning + statusMessage missing or empty
300
+ A warning with nothing saying what to look at is a field the reader cannot act on
301
+
302
+ ❌ required=true + optional=true
303
+ A field is one or the other, and marking it both says nothing
304
+
305
+ ❌ clearable=true + clearLabel missing or empty
306
+ A button whose only content is a glyph is announced as nothing without a name
307
+
308
+ ## Example
309
+
310
+ ```tsx
311
+ import { TextInput } from '@deriv-com/dds-marketing'
312
+
313
+ <TextInput label="Work email" type="email" placeholder="name@example.com" helperText="We'll only email you about the launch." />
314
+ ```
315
+
316
+ ```tsx
317
+ import { useState } from 'react'
318
+ import { TextInput } from '@deriv-com/dds-marketing'
319
+
320
+ // Controlled: TextInput reports the DOM event, so the value is read off it.
321
+ // Unlike AmountInput and SearchInput, which declare an onChange that hands back the
322
+ // value itself — the two shapes look the same at the call site and are not.
323
+ const [value, setValue] = useState('')
324
+ <TextInput label="Work email" type="email" placeholder="name@example.com" helperText="We'll only email you about the launch." value={value} onChange={(event) => setValue(event.target.value)} />
325
+ ```
326
+
327
+ ## In use
328
+
329
+ ### Three sizes, three jobs
330
+
331
+ The small one suits a dense desktop row. The default sits in a section's form. The large one is for a hero or conversion band, where the field is the reason the section exists.
332
+
333
+ ```tsx
334
+ import { TextInput } from '@deriv-com/dds-marketing'
335
+
336
+ // sm — a field in a filter row, beside the copy
337
+ <TextInput size="sm" label="Work email" type="email" placeholder="name@example.com" />
338
+
339
+ // md — an inline signup in a section
340
+ <TextInput size="md" label="Work email" type="email" placeholder="name@example.com" />
341
+
342
+ // lg — the one field a hero asks for
343
+ <TextInput size="lg" label="Work email" type="email" placeholder="name@example.com" />
344
+ ```
345
+
346
+ ### What a failure owes the reader
347
+
348
+ The field is already red, so the message says what to change rather than that something is wrong. An error with nothing under it is a reader stuck at a form.
349
+
350
+ ```tsx
351
+ import { TextInput } from '@deriv-com/dds-marketing'
352
+
353
+ // The standing helper, before anything goes wrong
354
+ <TextInput label="Work email" type="email" placeholder="name@example.com" helperText="We'll only email you about the launch." />
355
+
356
+ // The message replaces it, and says what to do
357
+ <TextInput label="Work email" type="email" status="error" statusMessage="Enter an address like name@example.com" />
358
+ ```
359
+
360
+ ### Asking for less, and marking it
361
+
362
+ A marketing form is judged on how little it asks. Where a field cannot be skipped the mark says so before the reader reaches the button.
363
+
364
+ ```tsx
365
+ import { TextInput } from '@deriv-com/dds-marketing'
366
+
367
+ // Required — the mark sits beside the label
368
+ <TextInput label="Full name" required placeholder="Amara Okafor" />
369
+
370
+ // Optional, and unmarked — most fields here
371
+ <TextInput label="Company" placeholder="Where you work" />
372
+ ```
373
+
374
+ ### Type picks the keypad, not the rules
375
+
376
+ All four look identical here, and that is the point: the difference is the keypad a phone raises and the hint the browser gives. None of them validates anything.
377
+
378
+ ```tsx
379
+ import { TextInput } from '@deriv-com/dds-marketing'
380
+
381
+ // text — a name, with no keypad of its own
382
+ <TextInput label="Full name" type="text" placeholder="Amara Okafor" />
383
+
384
+ // email — brings the @ without a modifier
385
+ <TextInput label="Work email" type="email" placeholder="name@example.com" />
386
+
387
+ // tel — the numeric keypad, and no validation
388
+ <TextInput label="Phone" type="tel" placeholder="+44 20 7946 0000" />
389
+
390
+ // url — for a form that asks for a website
391
+ <TextInput label="Website" type="url" placeholder="https://example.com" />
392
+ ```
393
+
394
+ ### The four verdicts a check can return
395
+
396
+ None of these is a resting state. Each carries a message, because the colour is the part a colour-blind reader may miss and the shape beside it is the part that survives.
397
+
398
+ ```tsx
399
+ import { TextInput } from '@deriv-com/dds-marketing'
400
+
401
+ // error — the value has to change
402
+ <TextInput label="Work email" type="email" placeholder="name@example.com" status="error" statusMessage="Enter an address like name@example.com" />
403
+
404
+ // warning — usable, worth a second look
405
+ <TextInput label="Work email" type="email" placeholder="name@example.com" status="warning" statusMessage="That looks like a personal address. A work one reaches you faster." />
406
+
407
+ // success — a check ran and passed
408
+ <TextInput label="Work email" type="email" placeholder="name@example.com" status="success" statusMessage="We can reach you here." />
409
+
410
+ // pending — no spinner; the words are all
411
+ <TextInput label="Work email" type="email" placeholder="name@example.com" status="pending" statusMessage="Checking that address…" />
412
+ ```
413
+
414
+ ### What can sit inside the box
415
+
416
+ Ornaments and furniture, none of which is the label. A glyph names nothing and an affix is never submitted — the words above the field still say what it is for.
417
+
418
+ ```tsx
419
+ import { TextInput } from '@deriv-com/dds-marketing'
420
+ import { EnvelopeRegularIcon, LockRegularIcon } from '@deriv-com/quill-icons-web'
421
+
422
+ // prefix — a head you should not have to type
423
+ <TextInput label="Website" type="url" prefix="https://" placeholder="example.com" />
424
+
425
+ // suffix — a tail every value here shares
426
+ <TextInput label="Work email" type="text" suffix="@example.com" placeholder="amara" />
427
+
428
+ // clearable — appears once there is a value
429
+ <TextInput label="Work email" type="email" placeholder="name@example.com" clearable clearLabel="Clear work email" defaultValue="amara@example.com" />
430
+
431
+ // leadingIcon and trailingIcon — ornaments, not controls
432
+ <TextInput label="Work email" type="email" placeholder="name@example.com" leadingIcon={<EnvelopeRegularIcon />} trailingIcon={<LockRegularIcon />} />
433
+ ```
434
+
435
+ ### Marking what a form expects
436
+
437
+ Mark the exception, not the rule. A form where every field carries a mark has said the same as one where none does, and spent a word on each to say it.
438
+
439
+ ```tsx
440
+ import { TextInput } from '@deriv-com/dds-marketing'
441
+
442
+ // requiredMark text — the default, needs no key
443
+ <TextInput label="Full name" required requiredMark="text" placeholder="Amara Okafor" />
444
+
445
+ // requiredMark asterisk — for a dense form
446
+ <TextInput label="Full name" required requiredMark="asterisk" placeholder="Amara Okafor" />
447
+
448
+ // optional — the one field that may be skipped
449
+ <TextInput label="Company" optional placeholder="Where you work" />
450
+
451
+ // labelTooltip — reachable by keyboard, not only pointer
452
+ <TextInput label="Work email" type="email" placeholder="name@example.com" labelTooltip="We use this to send the launch note and nothing else." />
453
+ ```
454
+
455
+ ### inputMode picks the keypad
456
+
457
+ A hint to a phone about which keys to raise. Not validation and not type: the value is still text, and what makes it acceptable is still checked after the reader submits.
458
+
459
+ ```tsx
460
+ import { TextInput } from '@deriv-com/dds-marketing'
461
+
462
+ // numeric — digits and nothing else
463
+ <TextInput label="Postcode" inputMode="numeric" placeholder="90210" />
464
+
465
+ // decimal — identical here; a phone differs
466
+ <TextInput label="Budget" inputMode="decimal" placeholder="1500.00" />
467
+ ```