@deriv-com/dds-marketing 1.0.2 → 1.1.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 (315) hide show
  1. package/.llm/components/awards.md +209 -0
  2. package/.llm/components/background.md +89 -40
  3. package/.llm/components/bottomsheet.md +5 -0
  4. package/.llm/components/comparisoncards.md +257 -0
  5. package/.llm/components/comparisontable.md +231 -0
  6. package/.llm/components/ctabanner.md +9 -12
  7. package/.llm/components/ctabannerslider.md +15 -2
  8. package/.llm/components/datatable.md +273 -0
  9. package/.llm/components/downloadbanner.md +283 -0
  10. package/.llm/components/featurecards.md +41 -3
  11. package/.llm/components/featurecardscarousel.md +311 -0
  12. package/.llm/components/featuresplit.md +5 -0
  13. package/.llm/components/featurestack.md +227 -0
  14. package/.llm/components/illustrationcard.md +2 -2
  15. package/.llm/components/illustrationscene.md +6 -10
  16. package/.llm/components/imagebanner.md +278 -0
  17. package/.llm/components/navbar.md +1 -1
  18. package/.llm/components/navbaritem.md +4 -0
  19. package/.llm/components/pageheader.md +4 -3
  20. package/.llm/components/paginationdots.md +6 -1
  21. package/.llm/components/producthero.md +35 -11
  22. package/.llm/components/resourcebanner.md +247 -0
  23. package/.llm/components/scenescroll.md +222 -0
  24. package/.llm/components/select.md +17 -0
  25. package/.llm/components/stats.md +219 -0
  26. package/.llm/components/steps.md +286 -0
  27. package/.llm/components/stickycards.md +251 -0
  28. package/.llm/components/tableheadercell.md +19 -0
  29. package/.llm/components/teamgrid.md +243 -0
  30. package/.llm/components/testimonialrow.md +5 -0
  31. package/.llm/components/testimonialslider.md +14 -1
  32. package/.llm/components/textarea.md +13 -0
  33. package/.llm/components/textinput.md +13 -0
  34. package/.llm/components/textscroll.md +187 -0
  35. package/.llm/components/tiers.md +227 -0
  36. package/.llm/digest/awards.md +45 -0
  37. package/.llm/digest/background.md +11 -10
  38. package/.llm/digest/bottomsheet.md +2 -0
  39. package/.llm/digest/comparisoncards.md +51 -0
  40. package/.llm/digest/comparisontable.md +53 -0
  41. package/.llm/digest/ctabanner.md +4 -4
  42. package/.llm/digest/ctabannerslider.md +4 -0
  43. package/.llm/digest/datatable.md +65 -0
  44. package/.llm/digest/downloadbanner.md +65 -0
  45. package/.llm/digest/featurecards.md +1 -1
  46. package/.llm/digest/featurecardscarousel.md +54 -0
  47. package/.llm/digest/featuresplit.md +1 -0
  48. package/.llm/digest/featurestack.md +48 -0
  49. package/.llm/digest/illustrationscene.md +2 -3
  50. package/.llm/digest/imagebanner.md +64 -0
  51. package/.llm/digest/navbaritem.md +1 -0
  52. package/.llm/digest/pageheader.md +2 -1
  53. package/.llm/digest/paginationdots.md +3 -1
  54. package/.llm/digest/producthero.md +4 -2
  55. package/.llm/digest/resourcebanner.md +53 -0
  56. package/.llm/digest/scenescroll.md +49 -0
  57. package/.llm/digest/select.md +5 -0
  58. package/.llm/digest/stats.md +46 -0
  59. package/.llm/digest/steps.md +55 -0
  60. package/.llm/digest/stickycards.md +52 -0
  61. package/.llm/digest/tableheadercell.md +4 -0
  62. package/.llm/digest/teamgrid.md +53 -0
  63. package/.llm/digest/testimonialrow.md +2 -0
  64. package/.llm/digest/testimonialslider.md +4 -0
  65. package/.llm/digest/textarea.md +4 -0
  66. package/.llm/digest/textinput.md +4 -0
  67. package/.llm/digest/textscroll.md +43 -0
  68. package/.llm/digest/tiers.md +50 -0
  69. package/.llm/index.md +19 -3
  70. package/.llm/tokens.md +26 -1
  71. package/AGENTS.md +17 -1
  72. package/dist/components/awards-data.d.ts +24 -0
  73. package/dist/components/awards-data.js +11 -0
  74. package/dist/components/block-image-data.d.ts +24 -0
  75. package/dist/components/block-image-data.js +9 -0
  76. package/dist/components/blocks/awards/Awards.css +134 -0
  77. package/dist/components/blocks/awards/Awards.d.ts +24 -0
  78. package/dist/components/blocks/awards/Awards.js +114 -0
  79. package/dist/components/blocks/awards/Awards.types.d.ts +31 -0
  80. package/dist/components/blocks/awards/Awards.types.js +16 -0
  81. package/dist/components/blocks/awards/awards-impl.css +222 -0
  82. package/dist/components/blocks/cards-of.d.ts +16 -0
  83. package/dist/components/blocks/cards-of.js +23 -0
  84. package/dist/components/blocks/comparison-cards/ComparisonCards.css +195 -0
  85. package/dist/components/blocks/comparison-cards/ComparisonCards.d.ts +24 -0
  86. package/dist/components/blocks/comparison-cards/ComparisonCards.js +75 -0
  87. package/dist/components/blocks/comparison-cards/ComparisonCards.types.d.ts +49 -0
  88. package/dist/components/blocks/comparison-cards/ComparisonCards.types.js +26 -0
  89. package/dist/components/blocks/comparison-cards/comparison-cards-impl.css +262 -0
  90. package/dist/components/blocks/comparison-table/ComparisonTable.css +111 -0
  91. package/dist/components/blocks/comparison-table/ComparisonTable.d.ts +25 -0
  92. package/dist/components/blocks/comparison-table/ComparisonTable.js +100 -0
  93. package/dist/components/blocks/comparison-table/ComparisonTable.types.d.ts +36 -0
  94. package/dist/components/blocks/comparison-table/ComparisonTable.types.js +15 -0
  95. package/dist/components/blocks/comparison-table/comparison-table-impl.css +143 -0
  96. package/dist/components/blocks/cta-banner/CtaBanner.css +1 -0
  97. package/dist/components/blocks/cta-banner/CtaBanner.js +2 -2
  98. package/dist/components/blocks/cta-banner/CtaBanner.types.d.ts +4 -3
  99. package/dist/components/blocks/cta-banner/CtaBanner.types.js +1 -1
  100. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.css +1 -0
  101. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.d.ts +1 -1
  102. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.js +6 -2
  103. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.d.ts +8 -0
  104. package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.js +1 -1
  105. package/dist/components/blocks/data-table/DataTable.css +170 -0
  106. package/dist/components/blocks/data-table/DataTable.d.ts +29 -0
  107. package/dist/components/blocks/data-table/DataTable.js +84 -0
  108. package/dist/components/blocks/data-table/DataTable.types.d.ts +69 -0
  109. package/dist/components/blocks/data-table/DataTable.types.js +19 -0
  110. package/dist/components/blocks/data-table/data-table-impl.css +155 -0
  111. package/dist/components/blocks/download-banner/DownloadBanner.css +228 -0
  112. package/dist/components/blocks/download-banner/DownloadBanner.d.ts +28 -0
  113. package/dist/components/blocks/download-banner/DownloadBanner.js +75 -0
  114. package/dist/components/blocks/download-banner/DownloadBanner.types.d.ts +56 -0
  115. package/dist/components/blocks/download-banner/DownloadBanner.types.js +23 -0
  116. package/dist/components/blocks/download-banner/download-banner-impl.css +216 -0
  117. package/dist/components/blocks/faq-accordion/FaqAccordion.css +1 -0
  118. package/dist/components/blocks/faq-accordion/faq-accordion-impl.css +3 -7
  119. package/dist/components/blocks/feature-bullets/FeatureBullets.css +1 -0
  120. package/dist/components/blocks/feature-bullets/feature-bullets-impl.css +14 -1
  121. package/dist/components/blocks/feature-cards/FeatureCards.css +1 -0
  122. package/dist/components/blocks/feature-cards/FeatureCards.d.ts +2 -1
  123. package/dist/components/blocks/feature-cards/FeatureCards.js +4 -21
  124. package/dist/components/blocks/feature-cards/feature-cards-impl.css +10 -9
  125. package/dist/components/blocks/feature-cards-carousel/FeatureCardsCarousel.css +115 -0
  126. package/dist/components/blocks/feature-cards-carousel/FeatureCardsCarousel.d.ts +30 -0
  127. package/dist/components/blocks/feature-cards-carousel/FeatureCardsCarousel.js +160 -0
  128. package/dist/components/blocks/feature-cards-carousel/FeatureCardsCarousel.types.d.ts +52 -0
  129. package/dist/components/blocks/feature-cards-carousel/FeatureCardsCarousel.types.js +17 -0
  130. package/dist/components/blocks/feature-cards-carousel/feature-cards-carousel-impl.css +207 -0
  131. package/dist/components/blocks/feature-scroll/FeatureScroll.css +1 -0
  132. package/dist/components/blocks/feature-split/FeatureSplit.css +1 -0
  133. package/dist/components/blocks/feature-split/feature-split-impl.css +14 -1
  134. package/dist/components/blocks/feature-stack/FeatureStack.css +86 -0
  135. package/dist/components/blocks/feature-stack/FeatureStack.d.ts +19 -0
  136. package/dist/components/blocks/feature-stack/FeatureStack.js +27 -0
  137. package/dist/components/blocks/feature-stack/FeatureStack.types.d.ts +34 -0
  138. package/dist/components/blocks/feature-stack/FeatureStack.types.js +14 -0
  139. package/dist/components/blocks/feature-stack/feature-stack-impl.css +87 -0
  140. package/dist/components/blocks/image-banner/ImageBanner.css +133 -0
  141. package/dist/components/blocks/image-banner/ImageBanner.d.ts +32 -0
  142. package/dist/components/blocks/image-banner/ImageBanner.js +41 -0
  143. package/dist/components/blocks/image-banner/ImageBanner.types.d.ts +54 -0
  144. package/dist/components/blocks/image-banner/ImageBanner.types.js +14 -0
  145. package/dist/components/blocks/image-banner/image-banner-impl.css +281 -0
  146. package/dist/components/blocks/landing-hero/LandingHero.css +1 -0
  147. package/dist/components/blocks/logo-columns/LogoColumns.css +1 -0
  148. package/dist/components/blocks/logo-rows/LogoRows.css +1 -0
  149. package/dist/components/blocks/page-header/PageHeader.css +1 -0
  150. package/dist/components/blocks/page-header/PageHeader.js +2 -2
  151. package/dist/components/blocks/page-header/PageHeader.types.d.ts +4 -2
  152. package/dist/components/blocks/page-header/PageHeader.types.js +1 -1
  153. package/dist/components/blocks/page-header/page-header-impl.css +5 -3
  154. package/dist/components/blocks/product-hero/ProductHero.css +8 -3
  155. package/dist/components/blocks/product-hero/ProductHero.d.ts +1 -1
  156. package/dist/components/blocks/product-hero/ProductHero.js +5 -2
  157. package/dist/components/blocks/product-hero/ProductHero.types.d.ts +5 -1
  158. package/dist/components/blocks/product-hero/ProductHero.types.js +1 -0
  159. package/dist/components/blocks/product-hero/product-hero-impl.css +43 -12
  160. package/dist/components/blocks/resource-banner/ResourceBanner.css +106 -0
  161. package/dist/components/blocks/resource-banner/ResourceBanner.d.ts +32 -0
  162. package/dist/components/blocks/resource-banner/ResourceBanner.js +51 -0
  163. package/dist/components/blocks/resource-banner/ResourceBanner.types.d.ts +44 -0
  164. package/dist/components/blocks/resource-banner/ResourceBanner.types.js +14 -0
  165. package/dist/components/blocks/resource-banner/resource-banner-impl.css +69 -0
  166. package/dist/components/blocks/scene-scroll/SceneScroll.css +93 -0
  167. package/dist/components/blocks/scene-scroll/SceneScroll.d.ts +36 -0
  168. package/dist/components/blocks/scene-scroll/SceneScroll.js +54 -0
  169. package/dist/components/blocks/scene-scroll/SceneScroll.types.d.ts +32 -0
  170. package/dist/components/blocks/scene-scroll/SceneScroll.types.js +15 -0
  171. package/dist/components/blocks/scene-scroll/scene-scroll-impl.css +275 -0
  172. package/dist/components/blocks/stats/Stats.css +139 -0
  173. package/dist/components/blocks/stats/Stats.d.ts +24 -0
  174. package/dist/components/blocks/stats/Stats.js +120 -0
  175. package/dist/components/blocks/stats/Stats.types.d.ts +36 -0
  176. package/dist/components/blocks/stats/Stats.types.js +19 -0
  177. package/dist/components/blocks/stats/stats-count.d.ts +34 -0
  178. package/dist/components/blocks/stats/stats-count.js +61 -0
  179. package/dist/components/blocks/stats/stats-impl.css +284 -0
  180. package/dist/components/blocks/stats/use-wheel.d.ts +37 -0
  181. package/dist/components/blocks/stats/use-wheel.js +126 -0
  182. package/dist/components/blocks/steps/Steps.css +202 -0
  183. package/dist/components/blocks/steps/Steps.d.ts +32 -0
  184. package/dist/components/blocks/steps/Steps.js +65 -0
  185. package/dist/components/blocks/steps/Steps.types.d.ts +48 -0
  186. package/dist/components/blocks/steps/Steps.types.js +21 -0
  187. package/dist/components/blocks/steps/steps-impl.css +216 -0
  188. package/dist/components/blocks/steps/use-turn.d.ts +33 -0
  189. package/dist/components/blocks/steps/use-turn.js +75 -0
  190. package/dist/components/blocks/sticky-cards/StickyCards.css +154 -0
  191. package/dist/components/blocks/sticky-cards/StickyCards.d.ts +35 -0
  192. package/dist/components/blocks/sticky-cards/StickyCards.js +153 -0
  193. package/dist/components/blocks/sticky-cards/StickyCards.types.d.ts +43 -0
  194. package/dist/components/blocks/sticky-cards/StickyCards.types.js +18 -0
  195. package/dist/components/blocks/sticky-cards/sticky-cards-impl.css +393 -0
  196. package/dist/components/blocks/team-grid/TeamGrid.css +159 -0
  197. package/dist/components/blocks/team-grid/TeamGrid.d.ts +28 -0
  198. package/dist/components/blocks/team-grid/TeamGrid.js +74 -0
  199. package/dist/components/blocks/team-grid/TeamGrid.types.d.ts +51 -0
  200. package/dist/components/blocks/team-grid/TeamGrid.types.js +20 -0
  201. package/dist/components/blocks/team-grid/team-grid-impl.css +129 -0
  202. package/dist/components/blocks/testimonial-row/TestimonialRow.css +1 -0
  203. package/dist/components/blocks/testimonial-row/TestimonialRow.d.ts +1 -1
  204. package/dist/components/blocks/testimonial-row/TestimonialRow.js +4 -3
  205. package/dist/components/blocks/testimonial-row/TestimonialRow.types.d.ts +3 -0
  206. package/dist/components/blocks/testimonial-row/TestimonialRow.types.js +1 -1
  207. package/dist/components/blocks/testimonial-row/testimonial-row-impl.css +8 -0
  208. package/dist/components/blocks/testimonial-slider/TestimonialSlider.css +1 -0
  209. package/dist/components/blocks/testimonial-slider/TestimonialSlider.d.ts +1 -1
  210. package/dist/components/blocks/testimonial-slider/TestimonialSlider.js +2 -2
  211. package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.d.ts +8 -0
  212. package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.js +1 -1
  213. package/dist/components/blocks/text-scroll/TextScroll.css +53 -0
  214. package/dist/components/blocks/text-scroll/TextScroll.d.ts +5 -0
  215. package/dist/components/blocks/text-scroll/TextScroll.js +71 -0
  216. package/dist/components/blocks/text-scroll/TextScroll.types.d.ts +22 -0
  217. package/dist/components/blocks/text-scroll/TextScroll.types.js +10 -0
  218. package/dist/components/blocks/text-scroll/text-scroll-impl.css +115 -0
  219. package/dist/components/blocks/tiers/Tiers.css +233 -0
  220. package/dist/components/blocks/tiers/Tiers.d.ts +32 -0
  221. package/dist/components/blocks/tiers/Tiers.js +68 -0
  222. package/dist/components/blocks/tiers/Tiers.types.d.ts +45 -0
  223. package/dist/components/blocks/tiers/Tiers.types.js +25 -0
  224. package/dist/components/blocks/tiers/tiers-impl.css +185 -0
  225. package/dist/components/blocks/use-rotation.d.ts +12 -2
  226. package/dist/components/blocks/use-rotation.js +6 -28
  227. package/dist/components/comparison-cards-data.d.ts +59 -0
  228. package/dist/components/comparison-cards-data.js +12 -0
  229. package/dist/components/comparison-table-data.d.ts +39 -0
  230. package/dist/components/comparison-table-data.js +11 -0
  231. package/dist/components/core/accordion-item/AccordionItem.css +1 -5
  232. package/dist/components/core/background/Background.css +23 -0
  233. package/dist/components/core/background/Background.d.ts +10 -4
  234. package/dist/components/core/background/Background.js +16 -7
  235. package/dist/components/core/background/Background.types.d.ts +11 -8
  236. package/dist/components/core/background/Background.types.js +3 -1
  237. package/dist/components/core/background/background-impl.css +334 -1
  238. package/dist/components/core/background/halftone.d.ts +11 -0
  239. package/dist/components/core/background/halftone.js +43 -3
  240. package/dist/components/core/background/patterns.d.ts +66 -0
  241. package/dist/components/core/background/patterns.js +244 -0
  242. package/dist/components/core/background/shader.d.ts +44 -0
  243. package/dist/components/core/background/shader.js +307 -0
  244. package/dist/components/core/background/use-shader.d.ts +11 -0
  245. package/dist/components/core/background/use-shader.js +25 -0
  246. package/dist/components/core/background/use-spotlight.d.ts +2 -1
  247. package/dist/components/core/background/use-spotlight.js +9 -1
  248. package/dist/components/core/bottom-sheet/BottomSheet.js +2 -2
  249. package/dist/components/core/bottom-sheet/BottomSheet.types.d.ts +3 -1
  250. package/dist/components/core/breadcrumb/Breadcrumb.d.ts +1 -0
  251. package/dist/components/core/breadcrumb/Breadcrumb.js +1 -0
  252. package/dist/components/core/breadcrumb/breadcrumb-impl.css +11 -0
  253. package/dist/components/core/button/button-impl.css +14 -1
  254. package/dist/components/core/illustration-card/IllustrationCard.js +1 -1
  255. package/dist/components/core/illustration-card/illustration-card-impl.css +20 -0
  256. package/dist/components/core/illustration-scene/IllustrationScene.css +4 -7
  257. package/dist/components/core/illustration-scene/IllustrationScene.types.d.ts +2 -3
  258. package/dist/components/core/illustration-scene/illustration-scene-impl.css +7 -1
  259. package/dist/components/core/link/Link.js +7 -3
  260. package/dist/components/core/link/link-impl.css +29 -2
  261. package/dist/components/core/navbar/Navbar.css +2 -2
  262. package/dist/components/core/navbar/Navbar.types.d.ts +1 -1
  263. package/dist/components/core/navbar-item/NavbarItem.d.ts +2 -1
  264. package/dist/components/core/navbar-item/NavbarItem.js +3 -10
  265. package/dist/components/core/navbar-item/NavbarItem.types.d.ts +4 -1
  266. package/dist/components/core/navbar-item/NavbarItem.types.js +1 -1
  267. package/dist/components/core/navbar-item/navbar-item-impl.css +10 -0
  268. package/dist/components/core/navbar-menu/navbar-menu-impl.css +9 -0
  269. package/dist/components/core/navbar-switcher/navbar-switcher-impl.css +19 -0
  270. package/dist/components/core/pagination/Pagination.js +1 -1
  271. package/dist/components/core/pagination/pagination-impl.css +9 -0
  272. package/dist/components/core/pagination-dots/PaginationDots.d.ts +1 -1
  273. package/dist/components/core/pagination-dots/PaginationDots.js +3 -3
  274. package/dist/components/core/pagination-dots/PaginationDots.types.d.ts +3 -1
  275. package/dist/components/core/segmented-control/SegmentedControl.css +4 -3
  276. package/dist/components/core/segmented-control/SegmentedControl.js +17 -3
  277. package/dist/components/core/segmented-control-item/SegmentedControlItem.css +2 -1
  278. package/dist/components/core/select/Select.js +3 -3
  279. package/dist/components/core/select/Select.types.d.ts +11 -1
  280. package/dist/components/core/select/Select.types.js +1 -1
  281. package/dist/components/core/tab-list/TabList.js +9 -1
  282. package/dist/components/core/table-header-cell/TableHeaderCell.d.ts +1 -1
  283. package/dist/components/core/table-header-cell/TableHeaderCell.js +5 -2
  284. package/dist/components/core/table-header-cell/TableHeaderCell.types.d.ts +7 -1
  285. package/dist/components/core/table-header-cell/TableHeaderCell.types.js +1 -1
  286. package/dist/components/core/text-area/TextArea.d.ts +1 -1
  287. package/dist/components/core/text-area/TextArea.js +2 -2
  288. package/dist/components/core/text-area/TextArea.types.d.ts +9 -1
  289. package/dist/components/core/text-area/TextArea.types.js +1 -1
  290. package/dist/components/core/text-input/TextInput.d.ts +1 -1
  291. package/dist/components/core/text-input/TextInput.js +2 -2
  292. package/dist/components/core/text-input/TextInput.types.d.ts +9 -1
  293. package/dist/components/core/text-input/TextInput.types.js +1 -1
  294. package/dist/components/data-table-data.d.ts +33 -0
  295. package/dist/components/data-table-data.js +12 -0
  296. package/dist/components/download-banner-data.d.ts +52 -0
  297. package/dist/components/download-banner-data.js +11 -0
  298. package/dist/components/index.d.ts +45 -0
  299. package/dist/components/index.js +32 -0
  300. package/dist/components/resource-banner-data.d.ts +34 -0
  301. package/dist/components/resource-banner-data.js +13 -0
  302. package/dist/components/scene-scroll-data.d.ts +24 -0
  303. package/dist/components/scene-scroll-data.js +9 -0
  304. package/dist/components/stats-data.d.ts +28 -0
  305. package/dist/components/stats-data.js +11 -0
  306. package/dist/components/steps-data.d.ts +38 -0
  307. package/dist/components/steps-data.js +13 -0
  308. package/dist/components/sticky-cards-data.d.ts +43 -0
  309. package/dist/components/sticky-cards-data.js +12 -0
  310. package/dist/components/team-grid-data.d.ts +38 -0
  311. package/dist/components/team-grid-data.js +11 -0
  312. package/dist/components/tiers-data.d.ts +47 -0
  313. package/dist/components/tiers-data.js +13 -0
  314. package/dist/marketing.css +77 -28
  315. package/package.json +1 -1
@@ -63,7 +63,7 @@ const FOCUSABLE = [
63
63
  * disagree eventually, and the consumer is the one that has to win.
64
64
  */
65
65
  export function BottomSheet(props) {
66
- const { open = bottomSheetDefaults.open, height = bottomSheetDefaults.height, title, showTitle = bottomSheetDefaults.showTitle, description, back, action, showClose = bottomSheetDefaults.showClose, showHandle = bottomSheetDefaults.showHandle, onOpenChange, children, id, ...rest } = props;
66
+ const { open = bottomSheetDefaults.open, height = bottomSheetDefaults.height, title, closeLabel, showTitle = bottomSheetDefaults.showTitle, description, back, action, showClose = bottomSheetDefaults.showClose, showHandle = bottomSheetDefaults.showHandle, onOpenChange, children, id, ...rest } = props;
67
67
  const fallbackId = useId();
68
68
  const rootId = id ?? fallbackId;
69
69
  const titleId = `${rootId}-title`;
@@ -335,7 +335,7 @@ export function BottomSheet(props) {
335
335
  /* The compact step. A sheet's exit sits on the row that names it, beside a title at the
336
336
  smallest heading step — at the default size the button stood taller than the words it
337
337
  sat next to and read as the loudest thing in the header. */
338
- size: "sm", label: `Close ${title}`,
338
+ size: "sm", label: closeLabel ?? `Close ${title}`,
339
339
  /* The bare glyph, not wrapped in an Icon. Which step belongs in a button of this size is
340
340
  ButtonIcon's own rule and it applies it by cloning — an Icon around it puts `dds-icon`
341
341
  on the svg at Icon's own default instead, which is a step and a half larger and beats
@@ -26,10 +26,12 @@ export interface BottomSheetOwnProps {
26
26
 
27
27
  The second argument is which of the four ways out the reader took, for a page that treats an abandoned task differently from a finished one. It is only ever called with false today — a sheet is opened by whatever opens it, never by itself — and the boolean is first anyway, so the shape does not have to change if that ever stops being true. */
28
28
  onOpenChange: (open: boolean, reason: 'close-button' | 'scrim' | 'escape' | 'drag') => void;
29
+ /** The accessible name of the close button. Without it the button is named "Close" and the title; pass it to translate that with the page. */
30
+ closeLabel?: string;
29
31
  /** Allowed: any content */
30
32
  children: ReactNode;
31
33
  }
32
- export type BottomSheetProps = BottomSheetOwnProps & Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'open' | 'height' | 'title' | 'showTitle' | 'description' | 'showClose' | 'back' | 'action' | 'showHandle' | 'onOpenChange'> & ({
34
+ export type BottomSheetProps = BottomSheetOwnProps & Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'open' | 'height' | 'title' | 'showTitle' | 'description' | 'showClose' | 'back' | 'action' | 'showHandle' | 'onOpenChange' | 'closeLabel'> & ({
33
35
  showHandle?: boolean;
34
36
  showClose?: false;
35
37
  } | {
@@ -1,4 +1,5 @@
1
1
  import './Breadcrumb.css';
2
+ import './breadcrumb-impl.css';
2
3
  import { type BreadcrumbProps } from './Breadcrumb.types.js';
3
4
  export type { BreadcrumbProps };
4
5
  /**
@@ -3,6 +3,7 @@ import { Children, Fragment } from 'react';
3
3
  import { ChevronRightRegularIcon } from '@deriv-com/quill-icons-web';
4
4
  import { Icon } from '../icon/Icon.js';
5
5
  import './Breadcrumb.css';
6
+ import './breadcrumb-impl.css';
6
7
  import { breadcrumbDefaults, breadcrumbParts } from './Breadcrumb.types.js';
7
8
  /**
8
9
  * A `<nav>` holding an ordered list of the levels above the current page.
@@ -0,0 +1,11 @@
1
+ /*
2
+ * What the contract cannot hold: a reading direction.
3
+ *
4
+ * The separator points from one level to the next. A right-to-left trail runs leftward, so the
5
+ * chevron is mirrored to point the way the trail reads — drawn as it ships, it pointed back at the
6
+ * level before it. The contract binds parts in states, and the direction a line is set in is
7
+ * neither.
8
+ */
9
+ :where([data-dds-context="marketing"]) .dds-breadcrumb .dds-breadcrumb__separator .dds-icon:dir(rtl) {
10
+ scale: -1 1;
11
+ }
@@ -34,13 +34,26 @@
34
34
  translate: var(--space-gap-xs);
35
35
  }
36
36
 
37
+ /**
38
+ * A right-to-left line reads leftward, so the arrow points left and the nudge goes left: the mark
39
+ * still moves on in the direction of reading, by the same gap.
40
+ */
41
+ :where([data-dds-context="marketing"]) .dds-button .dds-button__icon:dir(rtl) {
42
+ scale: -1 1;
43
+ }
44
+
45
+ :where([data-dds-context="marketing"]) .dds-button:hover .dds-button__icon:dir(rtl) {
46
+ translate: calc(-1 * var(--space-gap-xs));
47
+ }
48
+
37
49
  /**
38
50
  * A reader who asked for less motion gets none, rather than the same distance travelled
39
51
  * instantly. The generated sheet already drops the transition under this query, which on its
40
52
  * own would leave the four-pixel jump — the movement, minus the part that made it legible.
41
53
  */
42
54
  @media (prefers-reduced-motion: reduce) {
43
- :where([data-dds-context="marketing"]) .dds-button:hover .dds-button__icon {
55
+ :where([data-dds-context="marketing"]) .dds-button:hover .dds-button__icon,
56
+ :where([data-dds-context="marketing"]) .dds-button:hover .dds-button__icon:dir(rtl) {
44
57
  translate: 0;
45
58
  }
46
59
  }
@@ -78,5 +78,5 @@ export function IllustrationCard({ ratio = illustrationCardDefaults.ratio, label
78
78
  cancelAnimationFrame(queued);
79
79
  };
80
80
  }, []);
81
- return (_jsx("div", { ...rest, ref: pane, className: illustrationCardParts.root, "data-ratio": ratio, role: "img", "aria-label": label, children: _jsx("div", { ref: content, className: illustrationCardParts.content, inert: true, children: children }) }));
81
+ return (_jsx("div", { ...rest, ref: pane, className: illustrationCardParts.root, "data-ratio": ratio, "data-theme": "dark", role: "img", "aria-label": label, children: _jsx("div", { ref: content, className: illustrationCardParts.content, inert: true, children: children }) }));
82
82
  }
@@ -16,6 +16,26 @@
16
16
  backdrop-filter: blur(var(--size-backdrop-blur));
17
17
  }
18
18
 
19
+ /*
20
+ * Standing on its own, the glass is laid over the dark page rather than over whatever page it is on.
21
+ *
22
+ * The pane is dark in both themes — see `data-theme` in IllustrationCard.tsx — and the dark glass is
23
+ * a faint white, which is only the charcoal pane it is meant to be over the dark page's near-black.
24
+ * Over a light page the same glass came out near-white, behind the dark theme's white ink. So the
25
+ * dark page's ground goes under it, and the card is the same charcoal on every page.
26
+ *
27
+ * Not in a scene, where the glass is there to show the photograph through it.
28
+ */
29
+ :where([data-dds-context="marketing"]) .dds-illustrationcard {
30
+ background-color: var(--color-bg-page);
31
+ background-image: linear-gradient(var(--color-bg-surface-glass), var(--color-bg-surface-glass));
32
+ }
33
+
34
+ :where([data-dds-context="marketing"]) .dds-illustrationscene .dds-illustrationcard {
35
+ background-color: var(--color-bg-surface-glass);
36
+ background-image: none;
37
+ }
38
+
19
39
  /*
20
40
  * What the pane holds keeps its own size: nothing in it shrinks to make room, because a shrunk item
21
41
  * in a flex column overlaps the next one. Where the UI is taller than the pane, IllustrationCard
@@ -18,16 +18,13 @@
18
18
  background-color: var(--color-bg-surface);
19
19
  }
20
20
 
21
- :where([data-dds-context="marketing"]) .dds-illustrationscene[data-placement="center"] {
21
+ :where([data-dds-context="marketing"]) .dds-illustrationscene[data-placement="bottom"] {
22
+ align-items: end;
22
23
  justify-items: center;
23
24
  }
24
25
 
25
- :where([data-dds-context="marketing"]) .dds-illustrationscene[data-placement="end"] {
26
- justify-items: end;
27
- }
28
-
29
- :where([data-dds-context="marketing"]) .dds-illustrationscene[data-placement="start"] {
30
- justify-items: start;
26
+ :where([data-dds-context="marketing"]) .dds-illustrationscene[data-placement="center"] {
27
+ justify-items: center;
31
28
  }
32
29
 
33
30
  :where([data-dds-context="marketing"]) .dds-illustrationscene[data-ratio="landscape"] {
@@ -8,10 +8,9 @@ export interface IllustrationSceneOwnProps {
8
8
  ratio?: 'landscape' | 'square' | 'upright';
9
9
  /**
10
10
  * `center` — The default: the card in the middle of the frame. For a photograph whose subject frames the middle — a person looking down at what the card shows
11
- * `start` — The card towards the start edge, for a photograph whose subject is at the end
12
- * `end` — The card towards the end edge, for a photograph whose subject is at the start
11
+ * `bottom` — The card centred along the foot of the frame, held off it by the card's own inset — for a photograph whose subject fills the top: a face, a person reaching up, a skyline
13
12
  */
14
- placement?: 'center' | 'start' | 'end';
13
+ placement?: 'center' | 'bottom';
15
14
  /** Always. The photograph the scene is set in */
16
15
  src: string;
17
16
  /** Empty by default, because the card's `label` describes the whole picture and the photograph is decoration. Write one only where the photograph says something the label does not */
@@ -24,13 +24,19 @@
24
24
  * The card's share of the frame, per shape: a little under half of a wide frame, a little over half
25
25
  * of a square one, most of a tall one. Proportions of the frame rather than measures — a scene is
26
26
  * drawn at whatever width its column gives it, and the composition has to hold at all of them.
27
- * Held off the frame's edges by space.inset.card, so a card placed to one side never touches it.
27
+ * Held off the frame's edges by space.inset.card, so it never touches them.
28
28
  */
29
29
  :where([data-dds-context="marketing"]) .dds-illustrationscene > .dds-illustrationcard {
30
30
  inline-size: 46%;
31
31
  margin-inline: var(--space-inset-card);
32
32
  }
33
33
 
34
+ /* At the foot, the same inset below the card as either side of it. Only there: under a centred card
35
+ a margin would lift it off the middle by half the inset. */
36
+ :where([data-dds-context="marketing"]) .dds-illustrationscene[data-placement='bottom'] > .dds-illustrationcard {
37
+ margin-block-end: var(--space-inset-card);
38
+ }
39
+
34
40
  :where([data-dds-context="marketing"]) .dds-illustrationscene[data-ratio='square'] > .dds-illustrationcard {
35
41
  inline-size: 58%;
36
42
  }
@@ -123,9 +123,13 @@ export function Link({ variant = linkDefaults.variant, tone = linkDefaults.tone,
123
123
  same distance measured along the diagonal rather than four pixels twice.
124
124
  */
125
125
  style: {
126
+ /*
127
+ The two axes apart, so the stylesheet can turn the inline one round in a
128
+ right-to-left line — where the arrow is mirrored and travels the other way.
129
+ */
126
130
  ...(external
127
- ? { '--dds-link-arrow-travel': '18% -18%' }
128
- : { '--dds-link-arrow-travel': '25% 0' }),
131
+ ? { '--dds-link-arrow-travel-x': '18%', '--dds-link-arrow-travel-y': '-18%' }
132
+ : { '--dds-link-arrow-travel-x': '25%', '--dds-link-arrow-travel-y': '0%' }),
129
133
  /*
130
134
  A list link's mark rests displaced and at zero, and the pointer
131
135
  brings it to where it belongs — the arrival and the nudge are the
@@ -135,7 +139,7 @@ export function Link({ variant = linkDefaults.variant, tone = linkDefaults.tone,
135
139
  them.
136
140
  */
137
141
  ...(revealOnHover
138
- ? { '--dds-link-arrow-rest-travel': '-60% 0', '--dds-link-arrow-rest': '0' }
142
+ ? { '--dds-link-arrow-rest-travel-x': '-60%', '--dds-link-arrow-rest': '0' }
139
143
  : {}),
140
144
  }, children: _jsx(Icon, { size: "xs", children: trailing }) }))] }));
141
145
  }
@@ -144,14 +144,28 @@
144
144
  }
145
145
 
146
146
  :where([data-dds-context="marketing"]) .dds-link__icon-trailing .dds-icon {
147
- translate: var(--dds-link-arrow-rest-travel, 0 0);
147
+ translate: calc(var(--dds-link-arrow-rest-travel-x, 0%) * var(--dds-link-arrow-sign, 1)) 0;
148
148
  transition-property: translate;
149
149
  transition-duration: var(--motion-duration-normal);
150
150
  transition-timing-function: var(--motion-easing-standard);
151
151
  }
152
152
 
153
153
  :where([data-dds-context="marketing"]) .dds-link:hover .dds-link__icon-trailing .dds-icon {
154
- translate: var(--dds-link-arrow-travel, 0 0);
154
+ translate: calc(var(--dds-link-arrow-travel-x, 0%) * var(--dds-link-arrow-sign, 1)) var(--dds-link-arrow-travel-y, 0%);
155
+ }
156
+
157
+ /*
158
+ * A right-to-left line reads the other way, so the arrow points the other way: mirrored, and
159
+ * travelling along the line it now points down. Mirroring the glyph and not the box around it,
160
+ * because the box carries the gap to the words as padding on its inline start, and a mirrored box
161
+ * would draw the arrow against the words with the gap on its far side.
162
+ *
163
+ * The external arrow mirrors too — up and to the start of the line, which is where "out of this
164
+ * page" points in a script that reads leftward.
165
+ */
166
+ :where([data-dds-context="marketing"]) .dds-link__icon-trailing .dds-icon:dir(rtl) {
167
+ --dds-link-arrow-sign: -1;
168
+ scale: -1 1;
155
169
  }
156
170
 
157
171
  /*
@@ -166,3 +180,16 @@
166
180
  translate: none;
167
181
  }
168
182
  }
183
+
184
+ /*
185
+ * A link that inherits its ink draws its focus ring in that ink.
186
+ *
187
+ * `tone="inherit"` is the link a page puts on a ground of its own — a dark panel, the brand's
188
+ * band — where color.border.focus, the page's near-black in light mode, sat on a near-black panel
189
+ * at about 1.2:1 and the ring vanished: ResourceBanner's links in light mode, TeamGrid's on the dark
190
+ * band. The words already contrast with whatever they sit on, which is what `inherit` is for, so
191
+ * the ring takes the words' colour and reads wherever they do.
192
+ */
193
+ :where([data-dds-context="marketing"]) .dds-link[data-tone="inherit"]:focus-visible {
194
+ outline-color: currentcolor;
195
+ }
@@ -121,11 +121,11 @@
121
121
  }
122
122
 
123
123
  :where([data-dds-context="marketing"]) .dds-navbar[data-tone="inverse"] .dds-navbar__cluster {
124
- background-color: var(--color-bg-surface-translucent-on-brand-strong);
124
+ background-color: var(--color-bg-surface-translucent-tint-on-brand-strong);
125
125
  }
126
126
 
127
127
  :where([data-dds-context="marketing"]) .dds-navbar[data-tone="inverse"] .dds-navbar__ground {
128
- background-color: var(--color-bg-surface-translucent-on-brand-strong);
128
+ background-color: var(--color-bg-surface-translucent-tint-on-brand-strong);
129
129
  }
130
130
 
131
131
  :where([data-dds-context="marketing"]) .dds-navbar[data-tone="inverse"] .dds-navbar__trigger:focus-visible {
@@ -2,7 +2,7 @@ import type { HTMLAttributes, ReactNode } from 'react';
2
2
  export interface NavbarOwnProps {
3
3
  /**
4
4
  * `default` — The page begins on a light ground, which is most marketing pages. The bar paints in ink and the pill is paper
5
- * `inverse` — The first section of the page paints its own dark ground and the bar stands on it — a dark hero, a photograph, a brand-coloured takeover. The bar's ink runs light, and the pill and the collapsed bar take the dark see-through material — a near-opaque black base, a white tint and a blur — so a light photograph behind cannot wash them out
5
+ * `inverse` — The first section of the page paints its own dark ground and the bar stands on it — a dark hero, a photograph, a brand-coloured takeover. The bar's ink runs light, and the pill and the collapsed bar take a frosted white glass — a faint white base, a white tint over it and a blur — so the dark ground or the photograph shows through it, lightened, rather than a black slab standing on it. Choose a photograph dark where the bar sits: the glass lightens what is behind it and does not darken it
6
6
  */
7
7
  tone?: 'default' | 'inverse';
8
8
  /** Always — it names the navigation landmark, and a page with an unnamed one tells a screen-reader user there is navigation here without saying which navigation. Name the set rather than the act: 'Main', not 'Main navigation' — the role already supplies the word, and a name carrying it is announced as 'main navigation navigation' */
@@ -1,4 +1,5 @@
1
1
  import './NavbarItem.css';
2
+ import './navbar-item-impl.css';
2
3
  import { type NavbarItemProps } from './NavbarItem.types.js';
3
4
  export type { NavbarItemProps };
4
5
  /**
@@ -19,4 +20,4 @@ export type { NavbarItemProps };
19
20
  * section you are in is one you can return to the top of, and a reader who lands
20
21
  * on it should hear which section that is rather than meet a dead stop.
21
22
  */
22
- export declare function NavbarItem({ current, tone, href, icon, external, children, ...rest }: NavbarItemProps): import("react").JSX.Element;
23
+ export declare function NavbarItem({ current, tone, href, icon, external, externalLabel, children, ...rest }: NavbarItemProps): import("react").JSX.Element;
@@ -2,17 +2,10 @@
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { ArrowUpRightRegularIcon } from '@deriv-com/quill-icons-web';
4
4
  import './NavbarItem.css';
5
+ import './navbar-item-impl.css';
5
6
  import { Icon } from '../icon/Icon.js';
6
7
  import { visuallyHidden } from '../../visually-hidden.js';
7
8
  import { navbarItemDefaults, navbarItemParts } from './NavbarItem.types.js';
8
- /**
9
- * What the words become when the destination leaves the site.
10
- *
11
- * Appended to the content rather than replacing it with an `aria-label`: a label
12
- * replaces the words a sighted reader is looking at, and somebody using both
13
- * hears one thing and sees another. This keeps them the same sentence.
14
- */
15
- const OPENS_ELSEWHERE = '(opens in a new tab)';
16
9
  /**
17
10
  * One place the site has, in the bar across the top of it.
18
11
  *
@@ -31,10 +24,10 @@ const OPENS_ELSEWHERE = '(opens in a new tab)';
31
24
  * section you are in is one you can return to the top of, and a reader who lands
32
25
  * on it should hear which section that is rather than meet a dead stop.
33
26
  */
34
- export function NavbarItem({ current = navbarItemDefaults.current, tone = navbarItemDefaults.tone, href, icon, external = navbarItemDefaults.external, children, ...rest }) {
27
+ export function NavbarItem({ current = navbarItemDefaults.current, tone = navbarItemDefaults.tone, href, icon, external = navbarItemDefaults.external, externalLabel = navbarItemDefaults.externalLabel, children, ...rest }) {
35
28
  return (_jsxs("a", { ...rest, href: href, className: navbarItemParts.root, "data-current": String(current), "data-tone": tone, "aria-current": current ? 'page' : undefined,
36
29
  // Both, or neither. `target` without `rel` hands the opened document a live
37
30
  // reference back to this one; `rel` without `target` guards a navigation
38
31
  // that never leaves.
39
- target: external ? '_blank' : undefined, rel: external ? 'noreferrer' : undefined, children: [icon !== undefined && icon !== null && (_jsx("span", { className: navbarItemParts.icon, children: icon })), _jsx("span", { className: navbarItemParts.label, children: children }), external && (_jsxs(_Fragment, { children: [_jsx("span", { className: navbarItemParts.external, "aria-hidden": "true", children: _jsx(Icon, { size: "xs", children: _jsx(ArrowUpRightRegularIcon, {}) }) }), _jsx("span", { style: visuallyHidden, children: ` ${OPENS_ELSEWHERE}` })] }))] }));
32
+ target: external ? '_blank' : undefined, rel: external ? 'noreferrer' : undefined, children: [icon !== undefined && icon !== null && (_jsx("span", { className: navbarItemParts.icon, children: icon })), _jsx("span", { className: navbarItemParts.label, children: children }), external && (_jsxs(_Fragment, { children: [_jsx("span", { className: navbarItemParts.external, "aria-hidden": "true", children: _jsx(Icon, { size: "xs", children: _jsx(ArrowUpRightRegularIcon, {}) }) }), _jsx("span", { style: visuallyHidden, children: ` ${externalLabel}` })] }))] }));
40
33
  }
@@ -9,10 +9,12 @@ export interface NavbarItemOwnProps {
9
9
  href: string;
10
10
  /** The bar's sections are quicker to tell apart by a mark than by reading them, which is rare on a marketing site and usual in an application */
11
11
  icon?: ReactNode;
12
+ /** What a screen reader hears after an external destination's name, since the arrow that shows it to everyone else is hidden. Translate it with the page. */
13
+ externalLabel?: string;
12
14
  /** Allowed: text */
13
15
  children: ReactNode;
14
16
  }
15
- export type NavbarItemProps = NavbarItemOwnProps & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'className' | 'current' | 'tone' | 'href' | 'icon' | 'external'> & ({
17
+ export type NavbarItemProps = NavbarItemOwnProps & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'className' | 'current' | 'tone' | 'href' | 'icon' | 'external' | 'externalLabel'> & ({
16
18
  current?: boolean;
17
19
  external?: false;
18
20
  } | {
@@ -31,4 +33,5 @@ export declare const navbarItemDefaults: {
31
33
  readonly current: false;
32
34
  readonly tone: "default";
33
35
  readonly external: false;
36
+ readonly externalLabel: "(opens in a new tab)";
34
37
  };
@@ -7,4 +7,4 @@ export const navbarItemParts = {
7
7
  external: 'dds-navbaritem__external',
8
8
  };
9
9
  /** Generated so defaults cannot drift from the contract. */
10
- export const navbarItemDefaults = { current: false, tone: 'default', external: false };
10
+ export const navbarItemDefaults = { current: false, tone: 'default', external: false, externalLabel: '(opens in a new tab)' };
@@ -0,0 +1,10 @@
1
+ /*
2
+ * What the contract cannot hold: a reading direction.
3
+ *
4
+ * The external mark points out of the page along the line, up and to its end. In a right-to-left
5
+ * line the end is on the left, so the arrow is mirrored to point there; as it ships it pointed
6
+ * back into the words it qualifies.
7
+ */
8
+ :where([data-dds-context="marketing"]) .dds-navbaritem .dds-navbaritem__external .dds-icon:dir(rtl) {
9
+ scale: -1 1;
10
+ }
@@ -34,6 +34,15 @@
34
34
  translate: -50%;
35
35
  }
36
36
 
37
+ /*
38
+ * Centred in a right-to-left line too. `inset-inline-start: 50%` is the right edge there, while a
39
+ * translate is physical and still pulled the panel leftward — so it opened a whole panel-width to
40
+ * the left of where it hangs. Half its width back towards the inline start, which is rightward.
41
+ */
42
+ :where([data-dds-context="marketing"]) .dds-navbarmenu .dds-navbarmenu__surface:dir(rtl) {
43
+ translate: 50%;
44
+ }
45
+
37
46
  /*
38
47
  * Above the bar it hangs from, which a contract cannot hold: an integer with no unit.
39
48
  *
@@ -30,6 +30,15 @@
30
30
  z-index: var(--layer-popup);
31
31
  }
32
32
 
33
+ /*
34
+ * Centred in a right-to-left line too. `inset-inline-start: 50%` is the right edge there, while a
35
+ * translate is physical and still pulled the panel leftward — so it opened a whole panel-width to
36
+ * the left of where it hangs. Half its width back towards the inline start, which is rightward.
37
+ */
38
+ :where([data-dds-context="marketing"]) .dds-navbarswitcher[data-presentation='floating'] .dds-navbarswitcher__surface:dir(rtl) {
39
+ translate: 50%;
40
+ }
41
+
33
42
  /*
34
43
  * And in the panel it is a page rather than a panel.
35
44
  *
@@ -177,3 +186,13 @@
177
186
  block-size: 100%;
178
187
  inline-size: auto;
179
188
  }
189
+
190
+ /*
191
+ * In the panel, the chevron points to the page that opens beside it and the back mark to the one
192
+ * it came from — both along the line. Mirrored in a right-to-left line, where beside is leftward.
193
+ * The trigger's own chevron points down and is left alone.
194
+ */
195
+ :where([data-dds-context="marketing"]) .dds-navbarswitcher .dds-navbarswitcher__chevron .dds-icon:dir(rtl),
196
+ :where([data-dds-context="marketing"]) .dds-navbarswitcher .dds-navbarswitcher__back .dds-icon:dir(rtl) {
197
+ scale: -1 1;
198
+ }
@@ -362,5 +362,5 @@ export function Pagination({ variant = paginationDefaults.variant, page = pagina
362
362
  return (_jsx("a", { className: paginationParts.page, href: pageHref(slot), "aria-current": isCurrent ? 'page' : undefined, "data-current": isCurrent ? 'true' : undefined, onClick: go(slot), children: slot }, slot));
363
363
  }
364
364
  return (_jsx("button", { className: paginationParts.page, type: "button", "aria-current": isCurrent ? 'page' : undefined, "data-current": isCurrent ? 'true' : undefined, onClick: go(slot), children: slot }, slot));
365
- }) })), variant === 'compact' && (_jsx("span", { className: paginationParts.summary, children: readout(current, last) })), stepControl(current + 1, nextLabel, atEnd, _jsx(ChevronRightRegularIcon, {}))] }));
365
+ }) })), variant === 'compact' && (_jsx("span", { className: paginationParts.summary, dir: "ltr", children: readout(current, last) })), stepControl(current + 1, nextLabel, atEnd, _jsx(ChevronRightRegularIcon, {}))] }));
366
366
  }
@@ -15,3 +15,12 @@
15
15
  :where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__list:has([aria-expanded='true']) {
16
16
  overflow: visible;
17
17
  }
18
+
19
+ /*
20
+ * The step chevrons point along the row: previous towards its start, next towards its end. A
21
+ * right-to-left row puts previous on the right, so both are mirrored; as they ship, previous
22
+ * pointed outward and next pointed back across the pages.
23
+ */
24
+ :where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__step .dds-icon:dir(rtl) {
25
+ scale: -1 1;
26
+ }
@@ -22,4 +22,4 @@ export type { PaginationDotsProps };
22
22
  * There is no pause control, by decision: a press is the way to stop it, and the contract says what
23
23
  * that does and does not give WCAG 2.2.2.
24
24
  */
25
- export declare function PaginationDots({ variant, page, totalPages, onPageChange, autoplay, paused, label, itemLabel, }: PaginationDotsProps): import("react").JSX.Element;
25
+ export declare function PaginationDots({ variant, page, totalPages, onPageChange, autoplay, paused, label, itemLabel, positionLabel, }: PaginationDotsProps): import("react").JSX.Element;
@@ -67,7 +67,7 @@ function usePrefersLessMotion() {
67
67
  * There is no pause control, by decision: a press is the way to stop it, and the contract says what
68
68
  * that does and does not give WCAG 2.2.2.
69
69
  */
70
- export function PaginationDots({ variant = paginationDotsDefaults.variant, page = paginationDotsDefaults.page, totalPages = paginationDotsDefaults.totalPages, onPageChange, autoplay = paginationDotsDefaults.autoplay, paused = paginationDotsDefaults.paused, label = paginationDotsDefaults.label, itemLabel = paginationDotsDefaults.itemLabel, }) {
70
+ export function PaginationDots({ variant = paginationDotsDefaults.variant, page = paginationDotsDefaults.page, totalPages = paginationDotsDefaults.totalPages, onPageChange, autoplay = paginationDotsDefaults.autoplay, paused = paginationDotsDefaults.paused, label = paginationDotsDefaults.label, itemLabel = paginationDotsDefaults.itemLabel, positionLabel, }) {
71
71
  const count = Math.max(0, Math.floor(totalPages));
72
72
  const current = Math.min(Math.max(1, Math.floor(page)), Math.max(1, count));
73
73
  const root = useRef(null);
@@ -92,11 +92,11 @@ export function PaginationDots({ variant = paginationDotsDefaults.variant, page
92
92
  return () => window.clearTimeout(timer);
93
93
  }, [running, current, count]);
94
94
  if (count > DOT_LIMIT) {
95
- return (_jsx("div", { className: paginationDotsParts.root, "data-variant": variant, role: "group", "aria-label": label, ref: root, children: _jsx("span", { role: "status", children: `${String(current)} / ${String(count)}` }) }));
95
+ return (_jsx("div", { className: paginationDotsParts.root, "data-variant": variant, role: "group", "aria-label": label, ref: root, children: _jsx("span", { role: "status", dir: "ltr", children: `${String(current)} / ${String(count)}` }) }));
96
96
  }
97
97
  return (_jsx("div", { className: paginationDotsParts.root, "data-variant": variant, role: "group", "aria-label": label, ref: root, children: Array.from({ length: count }, (_, index) => index + 1).map((at) => {
98
98
  const here = at === current;
99
- return (_jsx("button", { type: "button", className: paginationDotsParts.dot, "aria-label": `${itemLabel} ${String(at)}`, "aria-current": here ? 'true' : undefined, onClick: () => {
99
+ return (_jsx("button", { type: "button", className: paginationDotsParts.dot, "aria-label": positionLabel?.(at, count) ?? `${itemLabel} ${String(at)}`, "aria-current": here ? 'true' : undefined, onClick: () => {
100
100
  setStopped(true);
101
101
  onPageChange?.(at);
102
102
  }, children: _jsx("span", { className: paginationDotsParts.mark, "data-current": here ? 'true' : undefined }) }, at));
@@ -16,8 +16,10 @@ export interface PaginationDotsOwnProps {
16
16
  paused?: boolean;
17
17
  /** The name the row is announced by, as a group. Name what the positions are: 'Slides', 'Steps'. Translate it with the page. */
18
18
  label?: string;
19
- /** The word each mark is named by, before its number — 'Slide 2'. Translate it with the page; a language that puts the number first is the reason a sentence template would be better, and the reason this is not yet one. */
19
+ /** The word each mark is named by, before its number — 'Slide 2'. Translate it with the page; a language that puts the number first, or writes it in its own digits, passes positionLabel instead. */
20
20
  itemLabel?: string;
21
+ /** Each mark's accessible name as a sentence, given its position counting from one and how many there are — for a language whose order is not the word then the number, or whose digits are not these. Wins over itemLabel where both are given. */
22
+ positionLabel?: (position: number, count: number) => string;
21
23
  }
22
24
  export type PaginationDotsProps = PaginationDotsOwnProps;
23
25
  /** The class each part carries. Apply these — do not retype them. */
@@ -5,6 +5,7 @@
5
5
  align-items: stretch;
6
6
  box-sizing: border-box;
7
7
  display: flex;
8
+ overflow-wrap: anywhere;
8
9
  position: relative;
9
10
  background-color: var(--color-bg-track);
10
11
  border-radius: var(--radius-pill);
@@ -39,15 +40,15 @@
39
40
  }
40
41
 
41
42
  :where([data-dds-context="marketing"]) .dds-segmentedcontrol[data-size="lg"] {
42
- block-size: var(--size-control-lg);
43
+ min-block-size: var(--size-control-lg);
43
44
  }
44
45
 
45
46
  :where([data-dds-context="marketing"]) .dds-segmentedcontrol[data-size="md"] {
46
- block-size: var(--size-control-md);
47
+ min-block-size: var(--size-control-md);
47
48
  }
48
49
 
49
50
  :where([data-dds-context="marketing"]) .dds-segmentedcontrol[data-size="sm"] {
50
- block-size: var(--size-control-sm);
51
+ min-block-size: var(--size-control-sm);
51
52
  }
52
53
 
53
54
  @media (prefers-reduced-motion: reduce) {
@@ -148,8 +148,14 @@ label, value, onChange, children, ...rest }) {
148
148
  setPill(null);
149
149
  return;
150
150
  }
151
+ /*
152
+ Measured from the row's inline start, which is where the pill is anchored. offsetLeft is
153
+ physical, so in a right-to-left row it counted from the edge the pill was not standing
154
+ on, and every segment's pill landed one row-width minus a segment to the right of it.
155
+ */
156
+ const rtl = getComputedStyle(root).direction === "rtl";
151
157
  setPill({
152
- x: box.offsetLeft,
158
+ x: rtl ? box.offsetLeft + box.offsetWidth - root.clientWidth : box.offsetLeft,
153
159
  y: box.offsetTop,
154
160
  w: box.offsetWidth,
155
161
  h: box.offsetHeight,
@@ -192,9 +198,17 @@ label, value, onChange, children, ...rest }) {
192
198
  // A closed row moves nothing. The reader still reaches it and still hears why.
193
199
  if (disabled)
194
200
  return;
195
- const step = KEYS[event.key];
196
- if (step === undefined)
201
+ const keyed = KEYS[event.key];
202
+ if (keyed === undefined)
197
203
  return;
204
+ /*
205
+ The horizontal arrows follow the row as it is drawn. In a right-to-left row the first
206
+ segment is on the right, so ArrowRight goes back towards it and ArrowLeft goes on.
207
+ */
208
+ const horizontal = event.key === "ArrowRight" || event.key === "ArrowLeft";
209
+ const step = horizontal && typeof keyed === "number" && getComputedStyle(event.currentTarget).direction === "rtl"
210
+ ? -keyed
211
+ : keyed;
198
212
  if (segments.length === 0)
199
213
  return;
200
214
  // Before anything moves: the arrows would otherwise scroll the page, and Home and
@@ -13,8 +13,9 @@
13
13
  outline-style: solid;
14
14
  padding-block: 0;
15
15
  position: relative;
16
+ text-align: center;
16
17
  text-decoration: none;
17
- white-space: nowrap;
18
+ white-space: normal;
18
19
  border-radius: var(--radius-pill);
19
20
  gap: var(--space-gap-xs);
20
21
  min-block-size: var(--size-target-min);
@@ -96,7 +96,7 @@ function words(node) {
96
96
  * reader tabbing out of a control has said they are done with it.
97
97
  */
98
98
  export function Select(props) {
99
- const { size = selectDefaults.size, status = selectDefaults.status, fixed = selectDefaults.fixed, label, labelTooltip, placeholder, helperText, value, defaultValue, onChange, open, defaultOpen, onOpenChange, searchable = selectDefaults.searchable, emptyLabel, required = selectDefaults.required, requiredMark = selectDefaults.requiredMark, optional = selectDefaults.optional, statusMessage, children, id, ...rest } = props;
99
+ const { size = selectDefaults.size, status = selectDefaults.status, fixed = selectDefaults.fixed, label, labelTooltip, placeholder, helperText, value, defaultValue, onChange, open, defaultOpen, onOpenChange, searchable = selectDefaults.searchable, emptyLabel, required = selectDefaults.required, requiredMark = selectDefaults.requiredMark, optional = selectDefaults.optional, requiredLabel = selectDefaults.requiredLabel, optionalLabel = selectDefaults.optionalLabel, labelTooltipLabel, searchLabel, statusMessage, children, id, ...rest } = props;
100
100
  const fallbackId = useId();
101
101
  const rootId = id ?? fallbackId;
102
102
  const labelId = `${rootId}-label`;
@@ -473,7 +473,7 @@ export function Select(props) {
473
473
  being read for the child ids below and then applied to nothing, so `<Select id="country">`
474
474
  put "country" on no element at all and any anchor or `getElementById` naming it found
475
475
  nothing. */
476
- id: rootId, "data-size": size, "data-status": status, "data-fixed": String(fixed), children: [_jsxs("div", { className: selectParts['label-row'], children: [_jsxs("span", { className: selectParts.label, id: labelId, children: [label, required ? (_jsx("span", { className: selectParts['required-mark'], "aria-hidden": "true", children: requiredMark === 'asterisk' ? '*' : 'required' })) : null, optional ? _jsx("span", { className: selectParts['optional-mark'], children: "optional" }) : null] }), given(labelTooltip) ? (_jsx(TooltipAnchor, { content: labelTooltip, placement: "top", children: _jsx("button", { type: "button", className: selectParts['label-tooltip'], "aria-label": `About ${label}`, children: _jsx(Icon, { size: selectGlyphStep[size], children: _jsx(CircleInfoRegularIcon, {}) }) }) })) : null] }), _jsxs("div", { className: selectParts.control, ref: box, children: [_jsxs("button", { ref: trigger, type: "button", className: selectParts.field, role: "combobox", "aria-labelledby": labelId, "aria-controls": listId, "aria-expanded": expanded, "aria-haspopup": "listbox", "aria-activedescendant": expanded && activeIndex !== -1 ? rowId(activeIndex) : undefined, "aria-invalid": status === 'error' || undefined, "aria-required": required || undefined, "aria-busy": checking || undefined, "aria-disabled": fixed || undefined, "aria-describedby": messageId, onClick: fixed ? undefined : () => (expanded ? setOpen(false) : openAt(onTheAnswer())), onKeyDown: fixed ? undefined : onKeyDown, ...rest, children: [_jsxs("span", { className: selectParts.answer, children: [taken?.props.leadingIcon, _jsx("span", { className: selectParts.value, "data-placeholder": taken === undefined || undefined, children: taken?.props.children ?? placeholder })] }), _jsx("span", { className: selectParts['trailing-icon'], "aria-hidden": "true", children: _jsx(Icon, { size: selectGlyphStep[size], children: _jsx(ChevronDownRegularIcon, { style: expanded ? { rotate: '180deg' } : undefined }) }) })] }), expanded ? (_jsxs("div", { className: selectParts.popup, children: [searchable ? (
476
+ id: rootId, "data-size": size, "data-status": status, "data-fixed": String(fixed), children: [_jsxs("div", { className: selectParts['label-row'], children: [_jsxs("span", { className: selectParts.label, id: labelId, children: [label, required ? (_jsx("span", { className: selectParts['required-mark'], "aria-hidden": "true", children: requiredMark === 'asterisk' ? '*' : requiredLabel })) : null, optional ? _jsx("span", { className: selectParts['optional-mark'], children: optionalLabel }) : null] }), given(labelTooltip) ? (_jsx(TooltipAnchor, { content: labelTooltip, placement: "top", children: _jsx("button", { type: "button", className: selectParts['label-tooltip'], "aria-label": labelTooltipLabel ?? `About ${label}`, children: _jsx(Icon, { size: selectGlyphStep[size], children: _jsx(CircleInfoRegularIcon, {}) }) }) })) : null] }), _jsxs("div", { className: selectParts.control, ref: box, children: [_jsxs("button", { ref: trigger, type: "button", className: selectParts.field, role: "combobox", "aria-labelledby": labelId, "aria-controls": listId, "aria-expanded": expanded, "aria-haspopup": "listbox", "aria-activedescendant": expanded && activeIndex !== -1 ? rowId(activeIndex) : undefined, "aria-invalid": status === 'error' || undefined, "aria-required": required || undefined, "aria-busy": checking || undefined, "aria-disabled": fixed || undefined, "aria-describedby": messageId, onClick: fixed ? undefined : () => (expanded ? setOpen(false) : openAt(onTheAnswer())), onKeyDown: fixed ? undefined : onKeyDown, ...rest, children: [_jsxs("span", { className: selectParts.answer, children: [taken?.props.leadingIcon, _jsx("span", { className: selectParts.value, "data-placeholder": taken === undefined || undefined, children: taken?.props.children ?? placeholder })] }), _jsx("span", { className: selectParts['trailing-icon'], "aria-hidden": "true", children: _jsx(Icon, { size: selectGlyphStep[size], children: _jsx(ChevronDownRegularIcon, { style: expanded ? { rotate: '180deg' } : undefined }) }) })] }), expanded ? (_jsxs("div", { className: selectParts.popup, children: [searchable ? (
477
477
  /* The field the answers are narrowed with, above them rather than in the box — a
478
478
  <ul> may hold options and little else, so this could not live in the list, and the
479
479
  box below is a button, which nothing can be typed into. */
@@ -495,7 +495,7 @@ export function Select(props) {
495
495
  arrives at without being told what it is for. Clipped rather than drawn, which
496
496
  is SearchInput's own default — the placeholder below carries the words for an
497
497
  eye. */
498
- label: `Search ${label}`, placeholder: `Search ${label}`, clearLabel: "Clear search", value: query, onChange: narrow, "aria-controls": listId, "aria-activedescendant": activeIndex === -1 ? undefined : rowId(activeIndex), onKeyDown: onSearchKeyDown }) })) : null, _jsx("ul", { className: selectParts.listbox, id: listId, role: "listbox", "aria-labelledby": labelId, children: visible.map((option, index) => cloneElement(option, {
498
+ label: searchLabel ?? `Search ${label}`, placeholder: searchLabel ?? `Search ${label}`, clearLabel: "Clear search", value: query, onChange: narrow, "aria-controls": listId, "aria-activedescendant": activeIndex === -1 ? undefined : rowId(activeIndex), onKeyDown: onSearchKeyDown }) })) : null, _jsx("ul", { className: selectParts.listbox, id: listId, role: "listbox", "aria-labelledby": labelId, children: visible.map((option, index) => cloneElement(option, {
499
499
  key: option.props.value ?? index,
500
500
  id: rowId(index),
501
501
  /* Marketing's Option is drawn at two steps where this control has three, so a