@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.
- package/.llm/components/accordion.md +193 -0
- package/.llm/components/accordionitem.md +236 -0
- package/.llm/components/aspectratio.md +212 -0
- package/.llm/components/badge.md +231 -0
- package/.llm/components/bottomsheet.md +404 -0
- package/.llm/components/breadcrumb.md +197 -0
- package/.llm/components/breadcrumbitem.md +178 -0
- package/.llm/components/button.md +271 -0
- package/.llm/components/buttonicon.md +313 -0
- package/.llm/components/card.md +313 -0
- package/.llm/components/cardbody.md +409 -0
- package/.llm/components/cardbutton.md +259 -0
- package/.llm/components/checkbox.md +285 -0
- package/.llm/components/divider.md +230 -0
- package/.llm/components/dropdownmenu.md +453 -0
- package/.llm/components/filterchip.md +314 -0
- package/.llm/components/footer.md +408 -0
- package/.llm/components/footergroup.md +241 -0
- package/.llm/components/grid.md +659 -0
- package/.llm/components/icon.md +194 -0
- package/.llm/components/link.md +354 -0
- package/.llm/components/menuitem.md +218 -0
- package/.llm/components/navbar.md +458 -0
- package/.llm/components/navbaritem.md +238 -0
- package/.llm/components/navbarmenu.md +319 -0
- package/.llm/components/navbarmenugroup.md +184 -0
- package/.llm/components/navbarpanel.md +255 -0
- package/.llm/components/navbarswitcher.md +343 -0
- package/.llm/components/navbarswitcheroption.md +156 -0
- package/.llm/components/option.md +268 -0
- package/.llm/components/pagination.md +361 -0
- package/.llm/components/removablechip.md +247 -0
- package/.llm/components/row.md +381 -0
- package/.llm/components/scroller.md +470 -0
- package/.llm/components/searchinput.md +279 -0
- package/.llm/components/segmentedcontrol.md +358 -0
- package/.llm/components/segmentedcontrolitem.md +272 -0
- package/.llm/components/select.md +509 -0
- package/.llm/components/selectchip.md +334 -0
- package/.llm/components/spinner.md +222 -0
- package/.llm/components/stack.md +334 -0
- package/.llm/components/statusdot.md +205 -0
- package/.llm/components/subdomainnavbar.md +327 -0
- package/.llm/components/tab.md +291 -0
- package/.llm/components/table.md +660 -0
- package/.llm/components/tablebody.md +258 -0
- package/.llm/components/tablecell.md +248 -0
- package/.llm/components/tablehead.md +248 -0
- package/.llm/components/tableheadercell.md +298 -0
- package/.llm/components/tablerow.md +285 -0
- package/.llm/components/tablist.md +210 -0
- package/.llm/components/textarea.md +362 -0
- package/.llm/components/textinput.md +467 -0
- package/.llm/components/tooltip.md +267 -0
- package/.llm/components/typography.md +245 -0
- package/.llm/digest/accordion.md +43 -0
- package/.llm/digest/accordionitem.md +47 -0
- package/.llm/digest/aspectratio.md +47 -0
- package/.llm/digest/badge.md +45 -0
- package/.llm/digest/bottomsheet.md +69 -0
- package/.llm/digest/breadcrumb.md +38 -0
- package/.llm/digest/breadcrumbitem.md +43 -0
- package/.llm/digest/button.md +48 -0
- package/.llm/digest/buttonicon.md +61 -0
- package/.llm/digest/card.md +50 -0
- package/.llm/digest/cardbody.md +68 -0
- package/.llm/digest/cardbutton.md +49 -0
- package/.llm/digest/checkbox.md +63 -0
- package/.llm/digest/divider.md +52 -0
- package/.llm/digest/dropdownmenu.md +67 -0
- package/.llm/digest/filterchip.md +68 -0
- package/.llm/digest/footer.md +57 -0
- package/.llm/digest/footergroup.md +42 -0
- package/.llm/digest/grid.md +62 -0
- package/.llm/digest/icon.md +45 -0
- package/.llm/digest/link.md +59 -0
- package/.llm/digest/menuitem.md +46 -0
- package/.llm/digest/navbar.md +60 -0
- package/.llm/digest/navbaritem.md +54 -0
- package/.llm/digest/navbarmenu.md +54 -0
- package/.llm/digest/navbarmenugroup.md +40 -0
- package/.llm/digest/navbarpanel.md +53 -0
- package/.llm/digest/navbarswitcher.md +51 -0
- package/.llm/digest/navbarswitcheroption.md +37 -0
- package/.llm/digest/option.md +54 -0
- package/.llm/digest/pagination.md +71 -0
- package/.llm/digest/removablechip.md +51 -0
- package/.llm/digest/row.md +60 -0
- package/.llm/digest/scroller.md +59 -0
- package/.llm/digest/searchinput.md +56 -0
- package/.llm/digest/segmentedcontrol.md +59 -0
- package/.llm/digest/segmentedcontrolitem.md +59 -0
- package/.llm/digest/select.md +92 -0
- package/.llm/digest/selectchip.md +68 -0
- package/.llm/digest/spinner.md +52 -0
- package/.llm/digest/stack.md +56 -0
- package/.llm/digest/statusdot.md +46 -0
- package/.llm/digest/subdomainnavbar.md +54 -0
- package/.llm/digest/tab.md +60 -0
- package/.llm/digest/table.md +71 -0
- package/.llm/digest/tablebody.md +49 -0
- package/.llm/digest/tablecell.md +55 -0
- package/.llm/digest/tablehead.md +50 -0
- package/.llm/digest/tableheadercell.md +65 -0
- package/.llm/digest/tablerow.md +56 -0
- package/.llm/digest/tablist.md +46 -0
- package/.llm/digest/textarea.md +78 -0
- package/.llm/digest/textinput.md +95 -0
- package/.llm/digest/tooltip.md +58 -0
- package/.llm/digest/typography.md +59 -0
- package/.llm/index.md +86 -0
- package/.llm/rules.md +122 -0
- package/.llm/tokens.md +341 -0
- package/AGENTS.md +164 -0
- package/LICENSE +21 -0
- package/README.md +63 -15
- package/dist/components/core/accordion/Accordion.css +10 -0
- package/dist/components/core/accordion/Accordion.d.ts +20 -0
- package/dist/components/core/accordion/Accordion.js +69 -0
- package/dist/components/core/accordion/Accordion.types.d.ts +20 -0
- package/dist/components/core/accordion/Accordion.types.js +7 -0
- package/dist/components/core/accordion-item/AccordionItem.css +98 -0
- package/dist/components/core/accordion-item/AccordionItem.d.ts +44 -0
- package/dist/components/core/accordion-item/AccordionItem.js +63 -0
- package/dist/components/core/accordion-item/AccordionItem.types.d.ts +32 -0
- package/dist/components/core/accordion-item/AccordionItem.types.js +13 -0
- package/dist/components/core/accordion-item/accordion-item-impl.css +107 -0
- package/dist/components/core/badge/Badge.css +37 -0
- package/dist/components/core/badge/Badge.d.ts +37 -0
- package/dist/components/core/badge/Badge.js +40 -0
- package/dist/components/core/badge/Badge.types.d.ts +24 -0
- package/dist/components/core/badge/Badge.types.js +8 -0
- package/dist/components/core/badge/badge-impl.css +32 -0
- package/dist/components/core/bottom-sheet/BottomSheet.css +178 -0
- package/dist/components/core/bottom-sheet/BottomSheet.d.ts +22 -0
- package/dist/components/core/bottom-sheet/BottomSheet.js +359 -0
- package/dist/components/core/bottom-sheet/BottomSheet.types.d.ts +67 -0
- package/dist/components/core/bottom-sheet/BottomSheet.types.js +18 -0
- package/dist/components/core/bottom-sheet/bottom-sheet-impl.css +57 -0
- package/dist/components/core/breadcrumb/Breadcrumb.css +19 -0
- package/dist/components/core/breadcrumb/Breadcrumb.d.ts +16 -0
- package/dist/components/core/breadcrumb/Breadcrumb.js +22 -0
- package/dist/components/core/breadcrumb/Breadcrumb.types.d.ts +18 -0
- package/dist/components/core/breadcrumb/Breadcrumb.types.js +9 -0
- package/dist/components/core/breadcrumb-item/BreadcrumbItem.css +34 -0
- package/dist/components/core/breadcrumb-item/BreadcrumbItem.d.ts +12 -0
- package/dist/components/core/breadcrumb-item/BreadcrumbItem.js +15 -0
- package/dist/components/core/breadcrumb-item/BreadcrumbItem.types.d.ts +22 -0
- package/dist/components/core/breadcrumb-item/BreadcrumbItem.types.js +9 -0
- package/dist/components/core/button/Button.css +141 -0
- package/dist/components/core/button/Button.d.ts +25 -0
- package/dist/components/core/button/Button.js +28 -0
- package/dist/components/core/button/Button.types.d.ts +40 -0
- package/dist/components/core/button/Button.types.js +9 -0
- package/dist/components/core/button/button-impl.css +46 -0
- package/dist/components/core/button-icon/ButtonIcon.css +135 -0
- package/dist/components/core/button-icon/ButtonIcon.d.ts +34 -0
- package/dist/components/core/button-icon/ButtonIcon.js +117 -0
- package/dist/components/core/button-icon/ButtonIcon.types.d.ts +41 -0
- package/dist/components/core/button-icon/ButtonIcon.types.js +8 -0
- package/dist/components/core/card/Card.css +65 -0
- package/dist/components/core/card/Card.d.ts +24 -0
- package/dist/components/core/card/Card.js +26 -0
- package/dist/components/core/card/Card.types.d.ts +33 -0
- package/dist/components/core/card/Card.types.js +7 -0
- package/dist/components/core/card-body/CardBody.css +139 -0
- package/dist/components/core/card-body/CardBody.d.ts +62 -0
- package/dist/components/core/card-body/CardBody.js +97 -0
- package/dist/components/core/card-body/CardBody.types.d.ts +61 -0
- package/dist/components/core/card-body/CardBody.types.js +15 -0
- package/dist/components/core/card-body/card-body-impl.css +87 -0
- package/dist/components/core/card-button/CardButton.css +73 -0
- package/dist/components/core/card-button/CardButton.d.ts +27 -0
- package/dist/components/core/card-button/CardButton.js +37 -0
- package/dist/components/core/card-button/CardButton.types.d.ts +24 -0
- package/dist/components/core/card-button/CardButton.types.js +7 -0
- package/dist/components/core/card-button/card-button-impl.css +39 -0
- package/dist/components/core/checkbox/Checkbox.css +149 -0
- package/dist/components/core/checkbox/Checkbox.d.ts +21 -0
- package/dist/components/core/checkbox/Checkbox.js +97 -0
- package/dist/components/core/checkbox/Checkbox.types.d.ts +46 -0
- package/dist/components/core/checkbox/Checkbox.types.js +15 -0
- package/dist/components/core/checkbox/checkbox-impl.css +90 -0
- package/dist/components/core/divider/Divider.css +41 -0
- package/dist/components/core/divider/Divider.d.ts +46 -0
- package/dist/components/core/divider/Divider.js +51 -0
- package/dist/components/core/divider/Divider.types.d.ts +25 -0
- package/dist/components/core/divider/Divider.types.js +9 -0
- package/dist/components/core/dropdown-menu/DropdownMenu.css +146 -0
- package/dist/components/core/dropdown-menu/DropdownMenu.d.ts +22 -0
- package/dist/components/core/dropdown-menu/DropdownMenu.js +309 -0
- package/dist/components/core/dropdown-menu/DropdownMenu.types.d.ts +62 -0
- package/dist/components/core/dropdown-menu/DropdownMenu.types.js +12 -0
- package/dist/components/core/dropdown-menu/dropdown-menu-impl.css +70 -0
- package/dist/components/core/filter-chip/FilterChip.css +149 -0
- package/dist/components/core/filter-chip/FilterChip.d.ts +23 -0
- package/dist/components/core/filter-chip/FilterChip.js +37 -0
- package/dist/components/core/filter-chip/FilterChip.types.d.ts +53 -0
- package/dist/components/core/filter-chip/FilterChip.types.js +12 -0
- package/dist/components/core/footer/Footer.css +104 -0
- package/dist/components/core/footer/Footer.d.ts +43 -0
- package/dist/components/core/footer/Footer.js +53 -0
- package/dist/components/core/footer/Footer.types.d.ts +47 -0
- package/dist/components/core/footer/Footer.types.js +18 -0
- package/dist/components/core/footer/footer-impl.css +218 -0
- package/dist/components/core/footer-group/FooterGroup.css +90 -0
- package/dist/components/core/footer-group/FooterGroup.d.ts +32 -0
- package/dist/components/core/footer-group/FooterGroup.js +64 -0
- package/dist/components/core/footer-group/FooterGroup.types.d.ts +25 -0
- package/dist/components/core/footer-group/FooterGroup.types.js +12 -0
- package/dist/components/core/footer-group/footer-group-impl.css +78 -0
- package/dist/components/core/icon/Icon.css +40 -0
- package/dist/components/core/icon/Icon.d.ts +23 -0
- package/dist/components/core/icon/Icon.js +79 -0
- package/dist/components/core/icon/Icon.types.d.ts +24 -0
- package/dist/components/core/icon/Icon.types.js +7 -0
- package/dist/components/core/link/Link.css +89 -0
- package/dist/components/core/link/Link.d.ts +37 -0
- package/dist/components/core/link/Link.js +141 -0
- package/dist/components/core/link/Link.types.d.ts +41 -0
- package/dist/components/core/link/Link.types.js +9 -0
- package/dist/components/core/link/link-impl.css +168 -0
- package/dist/components/core/menu-item/MenuItem.css +70 -0
- package/dist/components/core/menu-item/MenuItem.d.ts +11 -0
- package/dist/components/core/menu-item/MenuItem.js +26 -0
- package/dist/components/core/menu-item/MenuItem.types.d.ts +28 -0
- package/dist/components/core/menu-item/MenuItem.types.js +9 -0
- package/dist/components/core/navbar/Navbar.css +135 -0
- package/dist/components/core/navbar/Navbar.d.ts +36 -0
- package/dist/components/core/navbar/Navbar.js +371 -0
- package/dist/components/core/navbar/Navbar.types.d.ts +49 -0
- package/dist/components/core/navbar/Navbar.types.js +17 -0
- package/dist/components/core/navbar/navbar-impl.css +590 -0
- package/dist/components/core/navbar-item/NavbarItem.css +75 -0
- package/dist/components/core/navbar-item/NavbarItem.d.ts +22 -0
- package/dist/components/core/navbar-item/NavbarItem.js +40 -0
- package/dist/components/core/navbar-item/NavbarItem.types.d.ts +34 -0
- package/dist/components/core/navbar-item/NavbarItem.types.js +10 -0
- package/dist/components/core/navbar-menu/NavbarMenu.css +128 -0
- package/dist/components/core/navbar-menu/NavbarMenu.d.ts +5 -0
- package/dist/components/core/navbar-menu/NavbarMenu.js +186 -0
- package/dist/components/core/navbar-menu/NavbarMenu.types.d.ts +45 -0
- package/dist/components/core/navbar-menu/NavbarMenu.types.js +12 -0
- package/dist/components/core/navbar-menu/navbar-menu-impl.css +186 -0
- package/dist/components/core/navbar-menu-group/NavbarMenuGroup.css +26 -0
- package/dist/components/core/navbar-menu-group/NavbarMenuGroup.d.ts +17 -0
- package/dist/components/core/navbar-menu-group/NavbarMenuGroup.js +22 -0
- package/dist/components/core/navbar-menu-group/NavbarMenuGroup.types.d.ts +14 -0
- package/dist/components/core/navbar-menu-group/NavbarMenuGroup.types.js +7 -0
- package/dist/components/core/navbar-panel/NavbarPanel.css +87 -0
- package/dist/components/core/navbar-panel/NavbarPanel.d.ts +34 -0
- package/dist/components/core/navbar-panel/NavbarPanel.js +46 -0
- package/dist/components/core/navbar-panel/NavbarPanel.types.d.ts +29 -0
- package/dist/components/core/navbar-panel/NavbarPanel.types.js +12 -0
- package/dist/components/core/navbar-panel/navbar-panel-impl.css +104 -0
- package/dist/components/core/navbar-panel/use-navbar-panel.d.ts +26 -0
- package/dist/components/core/navbar-panel/use-navbar-panel.js +135 -0
- package/dist/components/core/navbar-switcher/NavbarSwitcher.css +117 -0
- package/dist/components/core/navbar-switcher/NavbarSwitcher.d.ts +20 -0
- package/dist/components/core/navbar-switcher/NavbarSwitcher.js +90 -0
- package/dist/components/core/navbar-switcher/NavbarSwitcher.types.d.ts +46 -0
- package/dist/components/core/navbar-switcher/NavbarSwitcher.types.js +13 -0
- package/dist/components/core/navbar-switcher/navbar-switcher-impl.css +179 -0
- package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.css +39 -0
- package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.d.ts +16 -0
- package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.js +19 -0
- package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.types.d.ts +18 -0
- package/dist/components/core/navbar-switcher-option/NavbarSwitcherOption.types.js +7 -0
- package/dist/components/core/option/Option.css +133 -0
- package/dist/components/core/option/Option.d.ts +25 -0
- package/dist/components/core/option/Option.js +31 -0
- package/dist/components/core/option/Option.types.d.ts +44 -0
- package/dist/components/core/option/Option.types.js +14 -0
- package/dist/components/core/pagination/Pagination.css +237 -0
- package/dist/components/core/pagination/Pagination.d.ts +30 -0
- package/dist/components/core/pagination/Pagination.js +406 -0
- package/dist/components/core/pagination/Pagination.types.d.ts +59 -0
- package/dist/components/core/pagination/Pagination.types.js +14 -0
- package/dist/components/core/pagination/pagination-impl.css +17 -0
- package/dist/components/core/removable-chip/RemovableChip.css +125 -0
- package/dist/components/core/removable-chip/RemovableChip.d.ts +25 -0
- package/dist/components/core/removable-chip/RemovableChip.js +36 -0
- package/dist/components/core/removable-chip/RemovableChip.types.d.ts +38 -0
- package/dist/components/core/removable-chip/RemovableChip.types.js +13 -0
- package/dist/components/core/search-input/SearchInput.css +205 -0
- package/dist/components/core/search-input/SearchInput.d.ts +5 -0
- package/dist/components/core/search-input/SearchInput.js +81 -0
- package/dist/components/core/search-input/SearchInput.types.d.ts +43 -0
- package/dist/components/core/search-input/SearchInput.types.js +13 -0
- package/dist/components/core/search-input/search-input-impl.css +20 -0
- package/dist/components/core/segmented-control/SegmentedControl.css +57 -0
- package/dist/components/core/segmented-control/SegmentedControl.d.ts +37 -0
- package/dist/components/core/segmented-control/SegmentedControl.js +269 -0
- package/dist/components/core/segmented-control/SegmentedControl.types.d.ts +38 -0
- package/dist/components/core/segmented-control/SegmentedControl.types.js +8 -0
- package/dist/components/core/segmented-control/segmented-control-impl.css +57 -0
- package/dist/components/core/segmented-control-item/SegmentedControlItem.css +151 -0
- package/dist/components/core/segmented-control-item/SegmentedControlItem.d.ts +50 -0
- package/dist/components/core/segmented-control-item/SegmentedControlItem.js +101 -0
- package/dist/components/core/segmented-control-item/SegmentedControlItem.types.d.ts +37 -0
- package/dist/components/core/segmented-control-item/SegmentedControlItem.types.js +10 -0
- package/dist/components/core/segmented-control-item/segmented-control-item-impl.css +69 -0
- package/dist/components/core/select/Select.css +400 -0
- package/dist/components/core/select/Select.d.ts +29 -0
- package/dist/components/core/select/Select.js +524 -0
- package/dist/components/core/select/Select.types.d.ts +96 -0
- package/dist/components/core/select/Select.types.js +26 -0
- package/dist/components/core/select/select-impl.css +114 -0
- package/dist/components/core/select-chip/SelectChip.css +155 -0
- package/dist/components/core/select-chip/SelectChip.d.ts +20 -0
- package/dist/components/core/select-chip/SelectChip.js +273 -0
- package/dist/components/core/select-chip/SelectChip.types.d.ts +56 -0
- package/dist/components/core/select-chip/SelectChip.types.js +14 -0
- package/dist/components/core/select-chip/select-chip-impl.css +38 -0
- package/dist/components/core/spinner/Spinner.css +76 -0
- package/dist/components/core/spinner/Spinner.d.ts +5 -0
- package/dist/components/core/spinner/Spinner.js +29 -0
- package/dist/components/core/spinner/Spinner.types.d.ts +37 -0
- package/dist/components/core/spinner/Spinner.types.js +10 -0
- package/dist/components/core/spinner/spinner-impl.css +27 -0
- package/dist/components/core/status-dot/StatusDot.css +43 -0
- package/dist/components/core/status-dot/StatusDot.d.ts +35 -0
- package/dist/components/core/status-dot/StatusDot.js +46 -0
- package/dist/components/core/status-dot/StatusDot.types.d.ts +29 -0
- package/dist/components/core/status-dot/StatusDot.types.js +7 -0
- package/dist/components/core/status-dot/status-dot-impl.css +42 -0
- package/dist/components/core/subdomain-navbar/SubdomainNavbar.css +89 -0
- package/dist/components/core/subdomain-navbar/SubdomainNavbar.d.ts +21 -0
- package/dist/components/core/subdomain-navbar/SubdomainNavbar.js +127 -0
- package/dist/components/core/subdomain-navbar/SubdomainNavbar.types.d.ts +43 -0
- package/dist/components/core/subdomain-navbar/SubdomainNavbar.types.js +13 -0
- package/dist/components/core/subdomain-navbar/subdomain-navbar-impl.css +147 -0
- package/dist/components/core/tab/Tab.css +113 -0
- package/dist/components/core/tab/Tab.d.ts +36 -0
- package/dist/components/core/tab/Tab.js +53 -0
- package/dist/components/core/tab/Tab.types.d.ts +42 -0
- package/dist/components/core/tab/Tab.types.js +13 -0
- package/dist/components/core/tab/tab-impl.css +49 -0
- package/dist/components/core/tab-list/TabList.css +40 -0
- package/dist/components/core/tab-list/TabList.d.ts +26 -0
- package/dist/components/core/tab-list/TabList.js +124 -0
- package/dist/components/core/tab-list/TabList.types.d.ts +20 -0
- package/dist/components/core/tab-list/TabList.types.js +7 -0
- package/dist/components/core/tab-list/tab-list-impl.css +56 -0
- package/dist/components/core/table/Table.css +40 -0
- package/dist/components/core/table/Table.d.ts +19 -0
- package/dist/components/core/table/Table.js +55 -0
- package/dist/components/core/table/Table.types.d.ts +59 -0
- package/dist/components/core/table/Table.types.js +9 -0
- package/dist/components/core/table/table-impl.css +75 -0
- package/dist/components/core/table/use-table-sort.d.ts +43 -0
- package/dist/components/core/table/use-table-sort.js +51 -0
- package/dist/components/core/table-body/TableBody.css +6 -0
- package/dist/components/core/table-body/TableBody.d.ts +12 -0
- package/dist/components/core/table-body/TableBody.js +26 -0
- package/dist/components/core/table-body/TableBody.types.d.ts +36 -0
- package/dist/components/core/table-body/TableBody.types.js +7 -0
- package/dist/components/core/table-cell/TableCell.css +76 -0
- package/dist/components/core/table-cell/TableCell.d.ts +21 -0
- package/dist/components/core/table-cell/TableCell.js +31 -0
- package/dist/components/core/table-cell/TableCell.types.d.ts +43 -0
- package/dist/components/core/table-cell/TableCell.types.js +7 -0
- package/dist/components/core/table-head/TableHead.css +6 -0
- package/dist/components/core/table-head/TableHead.d.ts +22 -0
- package/dist/components/core/table-head/TableHead.js +52 -0
- package/dist/components/core/table-head/TableHead.types.d.ts +39 -0
- package/dist/components/core/table-head/TableHead.types.js +7 -0
- package/dist/components/core/table-head/table-head-impl.css +51 -0
- package/dist/components/core/table-header-cell/TableHeaderCell.css +126 -0
- package/dist/components/core/table-header-cell/TableHeaderCell.d.ts +21 -0
- package/dist/components/core/table-header-cell/TableHeaderCell.js +34 -0
- package/dist/components/core/table-header-cell/TableHeaderCell.types.d.ts +56 -0
- package/dist/components/core/table-header-cell/TableHeaderCell.types.js +9 -0
- package/dist/components/core/table-header-cell/table-header-cell-impl.css +74 -0
- package/dist/components/core/table-row/TableRow.css +18 -0
- package/dist/components/core/table-row/TableRow.d.ts +17 -0
- package/dist/components/core/table-row/TableRow.js +32 -0
- package/dist/components/core/table-row/TableRow.types.d.ts +45 -0
- package/dist/components/core/table-row/TableRow.types.js +7 -0
- package/dist/components/core/table-row/table-row-impl.css +31 -0
- package/dist/components/core/text-area/TextArea.css +325 -0
- package/dist/components/core/text-area/TextArea.d.ts +13 -0
- package/dist/components/core/text-area/TextArea.js +133 -0
- package/dist/components/core/text-area/TextArea.types.d.ts +67 -0
- package/dist/components/core/text-area/TextArea.types.js +19 -0
- package/dist/components/core/text-area/text-area-impl.css +36 -0
- package/dist/components/core/text-input/TextInput.css +400 -0
- package/dist/components/core/text-input/TextInput.d.ts +5 -0
- package/dist/components/core/text-input/TextInput.js +130 -0
- package/dist/components/core/text-input/TextInput.types.d.ts +96 -0
- package/dist/components/core/text-input/TextInput.types.js +24 -0
- package/dist/components/core/text-input/text-input-impl.css +36 -0
- package/dist/components/core/tooltip/Tooltip.css +101 -0
- package/dist/components/core/tooltip/Tooltip.d.ts +51 -0
- package/dist/components/core/tooltip/Tooltip.js +87 -0
- package/dist/components/core/tooltip/Tooltip.types.d.ts +38 -0
- package/dist/components/core/tooltip/Tooltip.types.js +9 -0
- package/dist/components/core/tooltip/TooltipAnchor.d.ts +52 -0
- package/dist/components/core/tooltip/TooltipAnchor.js +69 -0
- package/dist/components/core/tooltip/tooltip-anchor.css +145 -0
- package/dist/components/core/tooltip/tooltip-impl.css +54 -0
- package/dist/components/core/tooltip/use-tooltip.d.ts +111 -0
- package/dist/components/core/tooltip/use-tooltip.js +189 -0
- package/dist/components/core/typography/Typography.css +96 -0
- package/dist/components/core/typography/Typography.d.ts +297 -0
- package/dist/components/core/typography/Typography.js +28 -0
- package/dist/components/core/typography/Typography.types.d.ts +40 -0
- package/dist/components/core/typography/Typography.types.js +7 -0
- package/dist/components/css-time.d.ts +20 -0
- package/dist/components/css-time.js +30 -0
- package/dist/components/given.d.ts +7 -0
- package/dist/components/given.js +9 -0
- package/dist/components/hover-open.d.ts +34 -0
- package/dist/components/hover-open.js +90 -0
- package/dist/components/index.d.ts +114 -1
- package/dist/components/index.js +115 -2
- package/dist/components/layout/aspect-ratio/AspectRatio.css +29 -0
- package/dist/components/layout/aspect-ratio/AspectRatio.d.ts +24 -0
- package/dist/components/layout/aspect-ratio/AspectRatio.js +26 -0
- package/dist/components/layout/aspect-ratio/AspectRatio.types.d.ts +22 -0
- package/dist/components/layout/aspect-ratio/AspectRatio.types.js +7 -0
- package/dist/components/layout/aspect-ratio/aspect-ratio-impl.css +44 -0
- package/dist/components/layout/grid/Grid.css +76 -0
- package/dist/components/layout/grid/Grid.d.ts +31 -0
- package/dist/components/layout/grid/Grid.js +33 -0
- package/dist/components/layout/grid/Grid.types.d.ts +48 -0
- package/dist/components/layout/grid/Grid.types.js +7 -0
- package/dist/components/layout/grid/grid-impl.css +62 -0
- package/dist/components/layout/row/Row.css +85 -0
- package/dist/components/layout/row/Row.d.ts +32 -0
- package/dist/components/layout/row/Row.js +34 -0
- package/dist/components/layout/row/Row.types.d.ts +45 -0
- package/dist/components/layout/row/Row.types.js +7 -0
- package/dist/components/layout/scroller/Scroller.css +59 -0
- package/dist/components/layout/scroller/Scroller.d.ts +34 -0
- package/dist/components/layout/scroller/Scroller.js +36 -0
- package/dist/components/layout/scroller/Scroller.types.d.ts +38 -0
- package/dist/components/layout/scroller/Scroller.types.js +7 -0
- package/dist/components/layout/scroller/scroller-impl.css +45 -0
- package/dist/components/layout/stack/Stack.css +73 -0
- package/dist/components/layout/stack/Stack.d.ts +28 -0
- package/dist/components/layout/stack/Stack.js +30 -0
- package/dist/components/layout/stack/Stack.types.d.ts +41 -0
- package/dist/components/layout/stack/Stack.types.js +7 -0
- package/dist/components/visually-hidden.d.ts +22 -0
- package/dist/components/visually-hidden.js +31 -0
- package/dist/fonts/LICENSE-inter.txt +93 -0
- package/dist/fonts/LICENSE-red-hat-mono.txt +93 -0
- package/dist/fonts/fonts.css +111 -0
- package/dist/fonts/inter-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/inter-cyrillic-wght-normal.woff2 +0 -0
- package/dist/fonts/inter-greek-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/inter-greek-wght-normal.woff2 +0 -0
- package/dist/fonts/inter-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/inter-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/inter-vietnamese-wght-normal.woff2 +0 -0
- package/dist/fonts/red-hat-mono-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/red-hat-mono-latin-wght-normal.woff2 +0 -0
- package/dist/marketing.css +289 -241
- package/package.json +18 -4
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Children, cloneElement, isValidElement, useCallback, useEffect, useLayoutEffect, useRef, useState, } from "react";
|
|
4
|
+
import "./SegmentedControl.css";
|
|
5
|
+
import "./segmented-control-impl.css";
|
|
6
|
+
import { segmentedControlItemParts } from "../segmented-control-item/SegmentedControlItem.types.js";
|
|
7
|
+
import { segmentedControlDefaults, segmentedControlParts, } from "./SegmentedControl.types.js";
|
|
8
|
+
/**
|
|
9
|
+
* How far each key moves along the row, or where it lands outright.
|
|
10
|
+
*
|
|
11
|
+
* Both axes answer, and the row is horizontal. A vertical pair on a horizontal control
|
|
12
|
+
* costs nothing and spares the reader a guess about which keys this one listens for —
|
|
13
|
+
* the alternative is a control that ignores half the arrows for no reason it can explain.
|
|
14
|
+
*/
|
|
15
|
+
const KEYS = {
|
|
16
|
+
ArrowRight: 1,
|
|
17
|
+
ArrowDown: 1,
|
|
18
|
+
ArrowLeft: -1,
|
|
19
|
+
ArrowUp: -1,
|
|
20
|
+
Home: "first",
|
|
21
|
+
End: "last",
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Both handlers, the segment's own first.
|
|
25
|
+
*
|
|
26
|
+
* `cloneElement` replaces rather than merges, so a segment already reporting its own
|
|
27
|
+
* presses would silently stop — and that is the handler a page is most likely to have
|
|
28
|
+
* written, since it is how they learn which segment was pressed.
|
|
29
|
+
*/
|
|
30
|
+
function chain(theirs, ours) {
|
|
31
|
+
if (theirs === undefined)
|
|
32
|
+
return ours;
|
|
33
|
+
return (value) => {
|
|
34
|
+
theirs(value);
|
|
35
|
+
ours(value);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A row of mutually exclusive values, and the three things about them that belong to the
|
|
40
|
+
* row rather than to any one segment: which is chosen, how tall they all are, and
|
|
41
|
+
* whether the choice can be made at all.
|
|
42
|
+
*
|
|
43
|
+
* It measures one thing — where the chosen segment sits — so the pill can travel to it.
|
|
44
|
+
* That is the whole reason the pill is a single element this component positions rather
|
|
45
|
+
* than a ground each segment paints: two grounds cross-fading always reads as two
|
|
46
|
+
* grounds, and no selector can answer where a sibling is. No container query reaches it
|
|
47
|
+
* either, the question being about a sibling's position rather than a box's own width.
|
|
48
|
+
*
|
|
49
|
+
* The measurement is deliberately small: one element per change, read for its offset and
|
|
50
|
+
* its size. Not the whole row, not on scroll, not per frame.
|
|
51
|
+
*
|
|
52
|
+
* It measures the segment itself rather than a wrapper around it, which is where this
|
|
53
|
+
* parts company with Product's. `offsetLeft` is read from the nearest positioned
|
|
54
|
+
* ancestor, and the segment's is this element — the groove is `position: relative` and
|
|
55
|
+
* the segment, though positioned itself, has nothing positioned between the two. Product
|
|
56
|
+
* wraps each segment in a box of its own because its own layout decisions live there;
|
|
57
|
+
* here the row divides itself, so the wrapper would be a part with nothing to bind and
|
|
58
|
+
* one more element between the pill and the thing it is measuring.
|
|
59
|
+
*
|
|
60
|
+
* What it does own is the radio pattern, which stops being optional the moment the
|
|
61
|
+
* segments carry `role="radio"`. One tab stop for the whole row, the arrow keys inside
|
|
62
|
+
* it, and selection following focus — because there is always exactly one answer, so
|
|
63
|
+
* moving focus without changing the answer would leave the reader looking at one segment
|
|
64
|
+
* while another is in force.
|
|
65
|
+
*
|
|
66
|
+
* A `value` naming no segment chooses none of them. Falling back to the first would tell
|
|
67
|
+
* the reader a value is in force that the page never set, and hide whatever caused the
|
|
68
|
+
* mismatch — a stale piece of state, a segment that has not loaded yet.
|
|
69
|
+
*/
|
|
70
|
+
export function SegmentedControl({ layout = segmentedControlDefaults.layout, size = segmentedControlDefaults.size, disabled = segmentedControlDefaults.disabled,
|
|
71
|
+
// No fallback, because there is no default to fall back to. The contract requires it:
|
|
72
|
+
// the question the segments are answers to is the one thing nothing else can supply.
|
|
73
|
+
label, value, onChange, children, ...rest }) {
|
|
74
|
+
const rootRef = useRef(null);
|
|
75
|
+
const segments = Children.toArray(children).filter((isValidElement));
|
|
76
|
+
/**
|
|
77
|
+
* Whether the consumer owns which value is in force.
|
|
78
|
+
*
|
|
79
|
+
* Naming a value is the whole of it — there is no second prop to remember and no mode
|
|
80
|
+
* to set.
|
|
81
|
+
*/
|
|
82
|
+
const controlled = value !== undefined;
|
|
83
|
+
const seeded = segments.findIndex((segment) => segment.props.selected === true);
|
|
84
|
+
/**
|
|
85
|
+
* Which segment the reader has chosen, or null while they have chosen none.
|
|
86
|
+
*
|
|
87
|
+
* Unread while controlled. The row does not keep a second opinion alongside the
|
|
88
|
+
* consumer's: a press updates their state, their state comes back as `value`, and a
|
|
89
|
+
* row holding its own answer as well is how the two come to disagree.
|
|
90
|
+
*/
|
|
91
|
+
const [picked, setPicked] = useState(null);
|
|
92
|
+
/**
|
|
93
|
+
* The seed this row has already taken, so a new one can be told from the old.
|
|
94
|
+
*
|
|
95
|
+
* `picked ?? seeded` alone meant the reader's first press won forever: after it, a
|
|
96
|
+
* consumer moving `selected` was ignored for the life of the component. Compared
|
|
97
|
+
* during render rather than in an effect, which is React's own answer for state
|
|
98
|
+
* derived from props — an effect would paint one frame of the stale segment first, and
|
|
99
|
+
* that frame is the bug in miniature.
|
|
100
|
+
*/
|
|
101
|
+
const [seenSeed, setSeenSeed] = useState(seeded);
|
|
102
|
+
if (seeded !== seenSeed) {
|
|
103
|
+
setSeenSeed(seeded);
|
|
104
|
+
setPicked(null);
|
|
105
|
+
}
|
|
106
|
+
const named = segments.findIndex((segment) => segment.props.value === value);
|
|
107
|
+
const active = controlled
|
|
108
|
+
? named === -1
|
|
109
|
+
? null
|
|
110
|
+
: named
|
|
111
|
+
: (seeded === seenSeed ? picked : null) ?? (seeded === -1 ? null : seeded);
|
|
112
|
+
/**
|
|
113
|
+
* Where the tab stop sits.
|
|
114
|
+
*
|
|
115
|
+
* The chosen segment, or the first when nothing is chosen — which is the radiogroup
|
|
116
|
+
* pattern, and the reason it matters is that -1 on every segment would make the whole
|
|
117
|
+
* row unreachable by keyboard the moment a `value` named nothing.
|
|
118
|
+
*/
|
|
119
|
+
const stop = active ?? 0;
|
|
120
|
+
/**
|
|
121
|
+
* Where the pill is, or null when nothing is chosen and there is nothing to mark.
|
|
122
|
+
*
|
|
123
|
+
* Held as state rather than written to the DOM directly, so the pill is positioned by
|
|
124
|
+
* a render like everything else and React is never surprised by an attribute it did
|
|
125
|
+
* not write.
|
|
126
|
+
*/
|
|
127
|
+
const [pill, setPill] = useState(null);
|
|
128
|
+
const measure = useCallback(() => {
|
|
129
|
+
const root = rootRef.current;
|
|
130
|
+
if (root === null)
|
|
131
|
+
return;
|
|
132
|
+
if (active === null) {
|
|
133
|
+
setPill(null);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
/*
|
|
137
|
+
Queried by class rather than indexed into the children: the pill is a child of this
|
|
138
|
+
element too, so the nth child and the nth segment stopped being the same thing the
|
|
139
|
+
moment it arrived.
|
|
140
|
+
|
|
141
|
+
Read off the segment's own generated constant rather than typed out here — the
|
|
142
|
+
class belongs to another component, and a literal would make this measurement
|
|
143
|
+
depend on a name nothing checks: rename the part and the pill stops working with
|
|
144
|
+
every gate still green.
|
|
145
|
+
*/
|
|
146
|
+
const box = root.querySelectorAll(`:scope > .${segmentedControlItemParts.root}`)[active];
|
|
147
|
+
if (box === undefined) {
|
|
148
|
+
setPill(null);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
setPill({
|
|
152
|
+
x: box.offsetLeft,
|
|
153
|
+
y: box.offsetTop,
|
|
154
|
+
w: box.offsetWidth,
|
|
155
|
+
h: box.offsetHeight,
|
|
156
|
+
});
|
|
157
|
+
}, [active]);
|
|
158
|
+
// Layout rather than a plain effect: between the two the pill would be painted at its
|
|
159
|
+
// previous place, which is a frame of it sitting under the wrong word.
|
|
160
|
+
useLayoutEffect(measure, [measure, segments.length, size, layout]);
|
|
161
|
+
/*
|
|
162
|
+
The row changing shape moves the segment underneath the pill.
|
|
163
|
+
|
|
164
|
+
Absent where there is no ResizeObserver rather than fatal — the pill stays where the
|
|
165
|
+
last measurement put it, which is correct until something resizes and is a mark in
|
|
166
|
+
the right place either way at the moment it is drawn. jsdom is the environment that
|
|
167
|
+
asks: the generated behaviour test runs there.
|
|
168
|
+
*/
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
const root = rootRef.current;
|
|
171
|
+
if (root === null)
|
|
172
|
+
return;
|
|
173
|
+
if (typeof ResizeObserver === "undefined")
|
|
174
|
+
return;
|
|
175
|
+
const observer = new ResizeObserver(() => measure());
|
|
176
|
+
observer.observe(root);
|
|
177
|
+
return () => observer.disconnect();
|
|
178
|
+
}, [measure]);
|
|
179
|
+
/**
|
|
180
|
+
* An arrow key chooses the segment it lands on, by the same route a press does.
|
|
181
|
+
*
|
|
182
|
+
* Focused and then clicked rather than notified through a channel of this component's
|
|
183
|
+
* own. The segment's `onSelect` is how a page hears about a press, and giving the
|
|
184
|
+
* keyboard a second route would mean two ways to hear about one event — with the
|
|
185
|
+
* keyboard one silently missing from every consumer who only wired up the first.
|
|
186
|
+
*
|
|
187
|
+
* The focus moves as well as the selection. A focus left behind on the old segment
|
|
188
|
+
* would put the ring on one word and the choice on another, and the next arrow key
|
|
189
|
+
* would then step from the wrong place.
|
|
190
|
+
*/
|
|
191
|
+
const onKeyDown = (event) => {
|
|
192
|
+
// A closed row moves nothing. The reader still reaches it and still hears why.
|
|
193
|
+
if (disabled)
|
|
194
|
+
return;
|
|
195
|
+
const step = KEYS[event.key];
|
|
196
|
+
if (step === undefined)
|
|
197
|
+
return;
|
|
198
|
+
if (segments.length === 0)
|
|
199
|
+
return;
|
|
200
|
+
// Before anything moves: the arrows would otherwise scroll the page, and Home and
|
|
201
|
+
// End would jump to the top and bottom of it, which is a long way from a row of three.
|
|
202
|
+
event.preventDefault();
|
|
203
|
+
/*
|
|
204
|
+
Every segment the reader can actually land on. A barred one is stepped over rather
|
|
205
|
+
than focused, and that is not a courtesy: selection follows focus here, so focusing
|
|
206
|
+
a segment whose press is refused would leave the ring on one word and the answer on
|
|
207
|
+
another — the one thing this pattern may not do. It also keeps the forbidden pair
|
|
208
|
+
out of reach, since the only way to select is to land on it.
|
|
209
|
+
*/
|
|
210
|
+
const reachable = segments
|
|
211
|
+
.map((segment, index) => ({ segment, index }))
|
|
212
|
+
.filter(({ segment }) => segment.props.disabled !== true)
|
|
213
|
+
.map(({ index }) => index);
|
|
214
|
+
// Every option barred. Nothing to move to, and no row for the reader to be wrong about.
|
|
215
|
+
if (reachable.length === 0)
|
|
216
|
+
return;
|
|
217
|
+
const here = reachable.indexOf(stop);
|
|
218
|
+
const next = step === "first"
|
|
219
|
+
? reachable[0]
|
|
220
|
+
: step === "last"
|
|
221
|
+
? reachable[reachable.length - 1]
|
|
222
|
+
: here === -1
|
|
223
|
+
? // The tab stop is itself barred, which a consumer can arrange by disabling
|
|
224
|
+
// a segment after it was chosen. Land on the first thing that answers.
|
|
225
|
+
reachable[0]
|
|
226
|
+
: reachable[(here + step + reachable.length) % reachable.length];
|
|
227
|
+
if (next === undefined)
|
|
228
|
+
return;
|
|
229
|
+
const target = rootRef.current?.querySelectorAll(`.${segmentedControlItemParts.root}`)[next];
|
|
230
|
+
target?.focus();
|
|
231
|
+
target?.click();
|
|
232
|
+
};
|
|
233
|
+
return (_jsxs("div", { ...rest, ref: rootRef, className: segmentedControlParts.root, role: "radiogroup", "aria-label": label, "aria-disabled": disabled ? true : undefined, "data-layout": layout, "data-size": size, "data-disabled": String(disabled), onKeyDown: onKeyDown, children: [_jsx("span", { className: segmentedControlParts.indicator, hidden: pill === null, style: pill === null
|
|
234
|
+
? undefined
|
|
235
|
+
: {
|
|
236
|
+
blockSize: `${pill.h}px`,
|
|
237
|
+
inlineSize: `${pill.w}px`,
|
|
238
|
+
translate: `${pill.x}px ${pill.y}px`,
|
|
239
|
+
} }), segments.map((segment, index) => cloneElement(segment, {
|
|
240
|
+
// Both are the row's to decide, and both overwrite whatever the segment was
|
|
241
|
+
// given: one chosen value, one height. Availability is the segment's own — the
|
|
242
|
+
// row has no disabled to hand down, because its own closes the question rather
|
|
243
|
+
// than any one answer.
|
|
244
|
+
size,
|
|
245
|
+
selected: index === active,
|
|
246
|
+
// One stop for the whole row. Every segment stays findable — the arrow keys
|
|
247
|
+
// reach them — and a reader tabs into the question rather than through the
|
|
248
|
+
// answers.
|
|
249
|
+
tabIndex: index === stop ? 0 : -1,
|
|
250
|
+
/*
|
|
251
|
+
The segment's own handler runs either way: it is how a page learns what was
|
|
252
|
+
chosen. The row records the choice only when nobody else is holding it — a
|
|
253
|
+
controlled row that also moved its own copy would have two answers to one
|
|
254
|
+
question and show the stale one for a frame.
|
|
255
|
+
|
|
256
|
+
Suppressed entirely while the row is closed, rather than by handing each
|
|
257
|
+
segment a `disabled` it would then carry into the chosen one — a pair the
|
|
258
|
+
item forbids. `cloneElement` replaces rather than merges, so undefined takes
|
|
259
|
+
the consumer's handler with it, which is the point: a closed row runs nothing.
|
|
260
|
+
*/
|
|
261
|
+
onSelect: disabled
|
|
262
|
+
? undefined
|
|
263
|
+
: chain(segment.props.onSelect, (pressed) => {
|
|
264
|
+
if (!controlled)
|
|
265
|
+
setPicked(index);
|
|
266
|
+
onChange?.(pressed);
|
|
267
|
+
}),
|
|
268
|
+
}))] }));
|
|
269
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export interface SegmentedControlOwnProps {
|
|
3
|
+
/**
|
|
4
|
+
* `hug` — Every segment takes the width of its own words and the row takes the total. The default, and what suits a control sharing a line with something else — beside a heading, above a card, at the end of a toolbar. The reader sees labels of unequal length, which is how words look
|
|
5
|
+
* `fill` — The segments split the container into equal shares and the row stretches across it. For a control as wide as whatever it heads — a period switch above a pricing table — where the segments should read as equals of matching weight rather than as a collection of names
|
|
6
|
+
*/
|
|
7
|
+
layout?: 'hug' | 'fill';
|
|
8
|
+
/**
|
|
9
|
+
* `sm` — A control seated in something already dense — a filter row, a picker in a navigation bar. Desktop only: below what a finger reliably hits
|
|
10
|
+
* `md` — The default. Sized to a medium control, so the row lines up with the fields and buttons next to it
|
|
11
|
+
* `lg` — A choice in a hero or a conversion band, where the control is the point of the section rather than an adjustment within it
|
|
12
|
+
*/
|
|
13
|
+
size?: 'sm' | 'md' | 'lg';
|
|
14
|
+
/** The question cannot be answered yet — a period switch above prices that have not loaded, a plan picker before an account is chosen. The whole groove dims as one object and the row stops answering the pointer and the arrow keys */
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
/** Always — a radiogroup with no name is announced as a set of choices with nothing said about what they are choices of. Name the question rather than the act: 'Billing period', not 'Choose a billing period' */
|
|
17
|
+
label: string;
|
|
18
|
+
/** The page is holding which segment is in force, which is the ordinary case here — the choice drives a price, a figure or a card rendered beside the control, so the page already has the answer. Passing it makes the row controlled: it shows what it is told and reports presses through onChange.
|
|
19
|
+
|
|
20
|
+
Leave it off and the row holds its own answer, seeded from whichever segment arrived selected. That suits a control whose effect is entirely local. */
|
|
21
|
+
value?: string;
|
|
22
|
+
/** Whenever value is — together they are how a page holds the choice. It is called with the chosen segment's value after that segment's own onSelect, so a segment that reports its own presses keeps doing so inside a row */
|
|
23
|
+
onChange?: (value: string) => void;
|
|
24
|
+
/** Allowed: SegmentedControlItem */
|
|
25
|
+
children: ReactNode;
|
|
26
|
+
}
|
|
27
|
+
export type SegmentedControlProps = SegmentedControlOwnProps & Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'layout' | 'size' | 'disabled' | 'label' | 'value' | 'onChange'>;
|
|
28
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
29
|
+
export declare const segmentedControlParts: {
|
|
30
|
+
readonly root: "dds-segmentedcontrol";
|
|
31
|
+
readonly indicator: "dds-segmentedcontrol__indicator";
|
|
32
|
+
};
|
|
33
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
34
|
+
export declare const segmentedControlDefaults: {
|
|
35
|
+
readonly layout: "hug";
|
|
36
|
+
readonly size: "md";
|
|
37
|
+
readonly disabled: false;
|
|
38
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// GENERATED from segmented-control.contract.json. Do not edit.
|
|
2
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
3
|
+
export const segmentedControlParts = {
|
|
4
|
+
root: 'dds-segmentedcontrol',
|
|
5
|
+
indicator: 'dds-segmentedcontrol__indicator',
|
|
6
|
+
};
|
|
7
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
8
|
+
export const segmentedControlDefaults = { layout: 'hug', size: 'md', disabled: false };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Scoped to this package, like the generated sheet beside it.
|
|
3
|
+
*
|
|
4
|
+
* `:where([data-dds-context="marketing"])` confines these rules without contributing
|
|
5
|
+
* specificity, so every override below still ties or beats exactly what it did
|
|
6
|
+
* before — several here are written a class deeper than they look in order to
|
|
7
|
+
* match generated CSS, and a scope that carried weight would break all of them.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/* Implementation CSS that the contract's staticCss cannot express. */
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* In fill, every segment takes an equal share of the row.
|
|
14
|
+
*
|
|
15
|
+
* `flex: 1 1 0` rather than a width: a basis of zero is what makes the shares equal
|
|
16
|
+
* regardless of how long each word is, which is the whole difference between fill and
|
|
17
|
+
* hug — hug lets the words decide and fill refuses to. The segment's own
|
|
18
|
+
* `min-inline-size` still holds underneath it, so the equal shares have a floor and a
|
|
19
|
+
* narrow screen crowds the row rather than drawing targets a finger cannot hit.
|
|
20
|
+
*
|
|
21
|
+
* Written here rather than in either contract because it belongs to neither on its own.
|
|
22
|
+
* It is the row's decision — the same segment in a hug row must not stretch — and the
|
|
23
|
+
* rule has to reach another component's root, which no contract field can address: a
|
|
24
|
+
* contract styles its own parts, and the segment is not one of this component's.
|
|
25
|
+
*/
|
|
26
|
+
:where([data-dds-context="marketing"])
|
|
27
|
+
.dds-segmentedcontrol[data-layout="fill"]
|
|
28
|
+
.dds-segmentedcontrolitem {
|
|
29
|
+
flex: 1 1 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/*
|
|
33
|
+
* What the pill's travel is made of.
|
|
34
|
+
*
|
|
35
|
+
* `transition-property` is a list of property names, which no token can be — so it is
|
|
36
|
+
* here, while how long the travel takes and on what curve are decisions and live in the
|
|
37
|
+
* contract as motion.duration.normal and motion.easing.standard. The reduced-motion
|
|
38
|
+
* guard the generator writes covers `.dds-segmentedcontrol *`, so this is switched off
|
|
39
|
+
* with everything else.
|
|
40
|
+
*
|
|
41
|
+
* `translate` and the two sizes rather than `inset` and `width`: these are the
|
|
42
|
+
* properties the pill is actually set with, and translate is the one a browser can
|
|
43
|
+
* animate without laying the row out again on every frame. Both axes are listed because
|
|
44
|
+
* the row's height changes with `size` and its width with the words in it, and a pill
|
|
45
|
+
* that jumped on one axis while easing on the other would read as broken rather than as
|
|
46
|
+
* fast.
|
|
47
|
+
*
|
|
48
|
+
* Two classes deep, and that is load-bearing rather than tidy. The generated rule for
|
|
49
|
+
* this part is `.dds-segmentedcontrol .dds-segmentedcontrol__indicator`, so a bare class
|
|
50
|
+
* here would lose on specificity however late it loaded — the quiet way an override of
|
|
51
|
+
* generated CSS fails, and one that costs the pill its travel with every gate still green.
|
|
52
|
+
*/
|
|
53
|
+
:where([data-dds-context="marketing"])
|
|
54
|
+
.dds-segmentedcontrol
|
|
55
|
+
.dds-segmentedcontrol__indicator {
|
|
56
|
+
transition-property: translate, inline-size, block-size;
|
|
57
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/* GENERATED from segmentedcontrolitem.contract.json. Do not edit. */
|
|
2
|
+
|
|
3
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem {
|
|
4
|
+
transition-property: background-color, opacity, outline-color, outline-width;
|
|
5
|
+
align-items: center;
|
|
6
|
+
appearance: none;
|
|
7
|
+
background-color: transparent;
|
|
8
|
+
border-style: none;
|
|
9
|
+
box-sizing: border-box;
|
|
10
|
+
cursor: pointer;
|
|
11
|
+
display: inline-flex;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
outline-style: solid;
|
|
14
|
+
padding-block: 0;
|
|
15
|
+
position: relative;
|
|
16
|
+
text-decoration: none;
|
|
17
|
+
white-space: nowrap;
|
|
18
|
+
border-radius: var(--radius-pill);
|
|
19
|
+
gap: var(--space-gap-xs);
|
|
20
|
+
min-block-size: var(--size-target-min);
|
|
21
|
+
min-inline-size: var(--size-target-min);
|
|
22
|
+
outline-width: var(--border-width-none);
|
|
23
|
+
transition-duration: var(--motion-duration-fast);
|
|
24
|
+
transition-timing-function: var(--motion-easing-standard);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem .dds-segmentedcontrolitem__sizer {
|
|
28
|
+
block-size: 0;
|
|
29
|
+
display: block;
|
|
30
|
+
overflow: hidden;
|
|
31
|
+
pointer-events: none;
|
|
32
|
+
visibility: hidden;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem .dds-segmentedcontrolitem__label {
|
|
36
|
+
transition-property: color, font-weight;
|
|
37
|
+
transition-duration: var(--motion-duration-fast);
|
|
38
|
+
transition-timing-function: var(--motion-easing-standard);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem:focus-visible {
|
|
42
|
+
outline-color: var(--color-border-focus);
|
|
43
|
+
outline-width: var(--border-width-focus);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-disabled="true"] {
|
|
47
|
+
opacity: var(--opacity-disabled);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-selected="false"] .dds-segmentedcontrolitem__icon {
|
|
51
|
+
color: var(--color-fg-muted);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-selected="false"] .dds-segmentedcontrolitem__label {
|
|
55
|
+
color: var(--color-fg-muted);
|
|
56
|
+
font-weight: var(--font-body-md-weight);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-selected="true"] .dds-segmentedcontrolitem__icon {
|
|
60
|
+
color: var(--color-fg-default);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-selected="true"] .dds-segmentedcontrolitem__label {
|
|
64
|
+
color: var(--color-fg-default);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-size="lg"] {
|
|
68
|
+
padding-inline: var(--space-control-lg);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-size="lg"] .dds-segmentedcontrolitem__icon {
|
|
72
|
+
block-size: var(--icon-control-lg);
|
|
73
|
+
inline-size: var(--icon-control-lg);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-size="lg"] .dds-segmentedcontrolitem__label {
|
|
77
|
+
font-family: var(--font-label-md-family);
|
|
78
|
+
font-size: var(--font-label-md-size);
|
|
79
|
+
letter-spacing: var(--font-label-md-letter-spacing);
|
|
80
|
+
line-height: var(--font-label-md-line-height);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-size="lg"] .dds-segmentedcontrolitem__sizer {
|
|
84
|
+
font-weight: var(--font-label-md-weight);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-size="md"] {
|
|
88
|
+
padding-inline: var(--space-control-md);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-size="md"] .dds-segmentedcontrolitem__icon {
|
|
92
|
+
block-size: var(--icon-control-md);
|
|
93
|
+
inline-size: var(--icon-control-md);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-size="md"] .dds-segmentedcontrolitem__label {
|
|
97
|
+
font-family: var(--font-label-sm-family);
|
|
98
|
+
font-size: var(--font-label-sm-size);
|
|
99
|
+
letter-spacing: var(--font-label-sm-letter-spacing);
|
|
100
|
+
line-height: var(--font-label-sm-line-height);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-size="md"] .dds-segmentedcontrolitem__sizer {
|
|
104
|
+
font-weight: var(--font-label-sm-weight);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-size="sm"] {
|
|
108
|
+
padding-inline: var(--space-control-sm);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-size="sm"] .dds-segmentedcontrolitem__icon {
|
|
112
|
+
block-size: var(--icon-control-sm);
|
|
113
|
+
inline-size: var(--icon-control-sm);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-size="sm"] .dds-segmentedcontrolitem__label {
|
|
117
|
+
font-family: var(--font-label-sm-family);
|
|
118
|
+
font-size: var(--font-label-sm-size);
|
|
119
|
+
letter-spacing: var(--font-label-sm-letter-spacing);
|
|
120
|
+
line-height: var(--font-label-sm-line-height);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-size="sm"] .dds-segmentedcontrolitem__sizer {
|
|
124
|
+
font-weight: var(--font-label-sm-weight);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-selected="true"][data-size="lg"] .dds-segmentedcontrolitem__label {
|
|
128
|
+
font-weight: var(--font-label-md-weight);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-selected="true"][data-size="md"] .dds-segmentedcontrolitem__label {
|
|
132
|
+
font-weight: var(--font-label-sm-weight);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-selected="true"][data-size="sm"] .dds-segmentedcontrolitem__label {
|
|
136
|
+
font-weight: var(--font-label-sm-weight);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem[data-selected="false"][data-disabled="false"]:hover:where(:not(:disabled)) {
|
|
140
|
+
background-color: var(--color-bg-hover);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem .dds-segmentedcontrolitem__icon {
|
|
144
|
+
transition-property: color;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@media (prefers-reduced-motion: reduce) {
|
|
148
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem,
|
|
149
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem * { transition: none; }
|
|
150
|
+
}
|
|
151
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import "./SegmentedControlItem.css";
|
|
2
|
+
import "./segmented-control-item-impl.css";
|
|
3
|
+
import { type SegmentedControlItemProps } from "./SegmentedControlItem.types.js";
|
|
4
|
+
export type { SegmentedControlItemProps };
|
|
5
|
+
/**
|
|
6
|
+
* One segment in a row, as a radio.
|
|
7
|
+
*
|
|
8
|
+
* A `<button>` carrying `role="radio"` rather than an `<input type="radio">`, and the
|
|
9
|
+
* reason is the label: a real radio input cannot hold a glyph beside its text, so the
|
|
10
|
+
* mark and the words would have to live in a sibling `<label>` and the box the reader
|
|
11
|
+
* presses would stop being the box that paints. The role and `aria-checked` give a
|
|
12
|
+
* screen reader everything the input would have, and `SegmentedControl` supplies the
|
|
13
|
+
* rest of the pattern — one tab stop, and the arrow keys inside it.
|
|
14
|
+
*
|
|
15
|
+
* Two of the props are the row's rather than the consumer's. `selected` is, because only
|
|
16
|
+
* one segment may be chosen and a segment cannot see its siblings; `size` is, because a
|
|
17
|
+
* row at mixed heights is not a row. Both are overwritten on every render of the group.
|
|
18
|
+
* `disabled` is the consumer's, and bars this one option while the rest still answer.
|
|
19
|
+
*
|
|
20
|
+
* It declares no height. The row fixes its own to the control ramp and stretches its
|
|
21
|
+
* segments inside it, so a segment is whatever the control is less the inset either
|
|
22
|
+
* side — which is what spares this package the second size ramp Product keeps in step
|
|
23
|
+
* with the first by hand.
|
|
24
|
+
*
|
|
25
|
+
* `disabled` is `aria-disabled` and a data attribute, never the native attribute. A
|
|
26
|
+
* native `disabled` removes the button from the accessibility tree, so a reader would
|
|
27
|
+
* not be told the option is there and unavailable — they would never learn it exists,
|
|
28
|
+
* which is the one outcome this prop is for. Being non-native it has to be enforced
|
|
29
|
+
* here, so `onClick` is swallowed while it holds. The stylesheet reads `data-disabled`
|
|
30
|
+
* for the same reason: `:disabled` would never match, and a rule written against it is
|
|
31
|
+
* one the browser discards in silence.
|
|
32
|
+
*
|
|
33
|
+
* Both data attributes are written in either direction rather than omitted when false.
|
|
34
|
+
* A styling axis is read by attribute selectors both ways — the hover tint is bound on
|
|
35
|
+
* `selected: false` and `disabled: false` — and an attribute absent when false matches
|
|
36
|
+
* neither.
|
|
37
|
+
*
|
|
38
|
+
* The spread goes before the attributes this component decides rather than after, which
|
|
39
|
+
* is the opposite of Tab in this package. Those are attributes the component owns, so a
|
|
40
|
+
* consumer overriding one meant to; these *are* the component. A `data-selected` from
|
|
41
|
+
* outside would repaint the segment into a state its own prop contradicts, and an
|
|
42
|
+
* `aria-checked` from outside would tell the reader a different value is in force.
|
|
43
|
+
* `tabIndex` is deliberately left in the spread, because that one is the row's to set —
|
|
44
|
+
* it is how the roving tab stop arrives.
|
|
45
|
+
*
|
|
46
|
+
* `value` is destructured rather than left in the rest spread even though it is read
|
|
47
|
+
* here: on a `<button>` a `value` attribute means something else entirely, and the row
|
|
48
|
+
* reads this one off the element's props without it ever needing to reach the DOM.
|
|
49
|
+
*/
|
|
50
|
+
export declare function SegmentedControlItem({ selected, disabled, size, value, label, icon, onSelect, onClick, ...rest }: SegmentedControlItemProps): import("react").JSX.Element;
|