@deriv-com/dds-marketing 0.1.0 → 1.0.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 +201 -0
- package/.llm/components/accordionitem.md +244 -0
- package/.llm/components/aspectratio.md +220 -0
- package/.llm/components/badge.md +239 -0
- package/.llm/components/bottomsheet.md +412 -0
- package/.llm/components/breadcrumb.md +205 -0
- package/.llm/components/breadcrumbitem.md +186 -0
- package/.llm/components/button.md +295 -0
- package/.llm/components/buttonicon.md +321 -0
- package/.llm/components/card.md +327 -0
- package/.llm/components/cardbody.md +435 -0
- package/.llm/components/cardbutton.md +273 -0
- package/.llm/components/checkbox.md +293 -0
- package/.llm/components/ctabanner.md +186 -0
- package/.llm/components/ctabannerslider.md +204 -0
- package/.llm/components/divider.md +238 -0
- package/.llm/components/dropdownmenu.md +461 -0
- package/.llm/components/faqaccordion.md +217 -0
- package/.llm/components/featurebullets.md +254 -0
- package/.llm/components/featurecards.md +313 -0
- package/.llm/components/featurescroll.md +284 -0
- package/.llm/components/featuresplit.md +249 -0
- package/.llm/components/filterchip.md +322 -0
- package/.llm/components/footer.md +416 -0
- package/.llm/components/footergroup.md +249 -0
- package/.llm/components/grid.md +667 -0
- package/.llm/components/icon.md +202 -0
- package/.llm/components/landinghero.md +254 -0
- package/.llm/components/link.md +362 -0
- package/.llm/components/logocolumns.md +235 -0
- package/.llm/components/logorows.md +212 -0
- package/.llm/components/menuitem.md +226 -0
- package/.llm/components/navbar.md +522 -0
- package/.llm/components/navbaritem.md +246 -0
- package/.llm/components/navbarmenu.md +327 -0
- package/.llm/components/navbarmenugroup.md +192 -0
- package/.llm/components/navbarpanel.md +263 -0
- package/.llm/components/navbarswitcher.md +351 -0
- package/.llm/components/navbarswitcheroption.md +164 -0
- package/.llm/components/option.md +276 -0
- package/.llm/components/pageheader.md +231 -0
- package/.llm/components/pagination.md +298 -0
- package/.llm/components/paginationdots.md +215 -0
- package/.llm/components/producthero.md +248 -0
- package/.llm/components/removablechip.md +255 -0
- package/.llm/components/row.md +389 -0
- package/.llm/components/scroller.md +478 -0
- package/.llm/components/searchinput.md +287 -0
- package/.llm/components/segmentedcontrol.md +366 -0
- package/.llm/components/segmentedcontrolitem.md +280 -0
- package/.llm/components/select.md +517 -0
- package/.llm/components/selectchip.md +375 -0
- package/.llm/components/spinner.md +230 -0
- package/.llm/components/stack.md +342 -0
- package/.llm/components/statusdot.md +213 -0
- package/.llm/components/subdomainnavbar.md +335 -0
- package/.llm/components/tab.md +299 -0
- package/.llm/components/table.md +668 -0
- package/.llm/components/tablebody.md +266 -0
- package/.llm/components/tablecell.md +256 -0
- package/.llm/components/tablehead.md +256 -0
- package/.llm/components/tableheadercell.md +306 -0
- package/.llm/components/tablerow.md +293 -0
- package/.llm/components/tablist.md +218 -0
- package/.llm/components/testimonialrow.md +235 -0
- package/.llm/components/testimonialslider.md +254 -0
- package/.llm/components/textarea.md +370 -0
- package/.llm/components/textinput.md +475 -0
- package/.llm/components/tooltip.md +275 -0
- package/.llm/components/typography.md +253 -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 +53 -0
- package/.llm/digest/buttonicon.md +61 -0
- package/.llm/digest/card.md +51 -0
- package/.llm/digest/cardbody.md +70 -0
- package/.llm/digest/cardbutton.md +50 -0
- package/.llm/digest/checkbox.md +63 -0
- package/.llm/digest/ctabanner.md +44 -0
- package/.llm/digest/ctabannerslider.md +45 -0
- package/.llm/digest/divider.md +52 -0
- package/.llm/digest/dropdownmenu.md +67 -0
- package/.llm/digest/faqaccordion.md +43 -0
- package/.llm/digest/featurebullets.md +52 -0
- package/.llm/digest/featurecards.md +49 -0
- package/.llm/digest/featurescroll.md +52 -0
- package/.llm/digest/featuresplit.md +54 -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/landinghero.md +53 -0
- package/.llm/digest/link.md +59 -0
- package/.llm/digest/logocolumns.md +55 -0
- package/.llm/digest/logorows.md +48 -0
- package/.llm/digest/menuitem.md +46 -0
- package/.llm/digest/navbar.md +75 -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/pageheader.md +49 -0
- package/.llm/digest/pagination.md +60 -0
- package/.llm/digest/paginationdots.md +43 -0
- package/.llm/digest/producthero.md +53 -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 +73 -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/testimonialrow.md +51 -0
- package/.llm/digest/testimonialslider.md +51 -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 +107 -0
- package/.llm/rules.md +146 -0
- package/.llm/tokens.md +385 -0
- package/AGENTS.md +189 -0
- package/LICENSE +21 -0
- package/README.md +78 -10
- package/dist/components/banner-data.d.ts +38 -0
- package/dist/components/banner-data.js +15 -0
- package/dist/components/blocks/block-reveal.css +90 -0
- package/dist/components/blocks/cta-banner/CtaBanner.css +66 -0
- package/dist/components/blocks/cta-banner/CtaBanner.d.ts +22 -0
- package/dist/components/blocks/cta-banner/CtaBanner.js +31 -0
- package/dist/components/blocks/cta-banner/CtaBanner.types.d.ts +29 -0
- package/dist/components/blocks/cta-banner/CtaBanner.types.js +13 -0
- package/dist/components/blocks/cta-banner/cta-banner-impl.css +29 -0
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.css +90 -0
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.d.ts +39 -0
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.js +60 -0
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.d.ts +41 -0
- package/dist/components/blocks/cta-banner-slider/CtaBannerSlider.types.js +15 -0
- package/dist/components/blocks/cta-banner-slider/cta-banner-slider-impl.css +73 -0
- package/dist/components/blocks/faq-accordion/FaqAccordion.css +54 -0
- package/dist/components/blocks/faq-accordion/FaqAccordion.d.ts +20 -0
- package/dist/components/blocks/faq-accordion/FaqAccordion.js +28 -0
- package/dist/components/blocks/faq-accordion/FaqAccordion.types.d.ts +25 -0
- package/dist/components/blocks/faq-accordion/FaqAccordion.types.js +10 -0
- package/dist/components/blocks/faq-accordion/faq-accordion-impl.css +54 -0
- package/dist/components/blocks/feature-bullets/FeatureBullets.css +139 -0
- package/dist/components/blocks/feature-bullets/FeatureBullets.d.ts +31 -0
- package/dist/components/blocks/feature-bullets/FeatureBullets.js +55 -0
- package/dist/components/blocks/feature-bullets/FeatureBullets.types.d.ts +39 -0
- package/dist/components/blocks/feature-bullets/FeatureBullets.types.js +16 -0
- package/dist/components/blocks/feature-bullets/feature-bullets-impl.css +104 -0
- package/dist/components/blocks/feature-cards/FeatureCards.css +84 -0
- package/dist/components/blocks/feature-cards/FeatureCards.d.ts +24 -0
- package/dist/components/blocks/feature-cards/FeatureCards.js +66 -0
- package/dist/components/blocks/feature-cards/FeatureCards.types.d.ts +33 -0
- package/dist/components/blocks/feature-cards/FeatureCards.types.js +14 -0
- package/dist/components/blocks/feature-cards/feature-cards-impl.css +245 -0
- package/dist/components/blocks/feature-scroll/FeatureScroll.css +137 -0
- package/dist/components/blocks/feature-scroll/FeatureScroll.d.ts +39 -0
- package/dist/components/blocks/feature-scroll/FeatureScroll.js +167 -0
- package/dist/components/blocks/feature-scroll/FeatureScroll.types.d.ts +40 -0
- package/dist/components/blocks/feature-scroll/FeatureScroll.types.js +17 -0
- package/dist/components/blocks/feature-scroll/feature-scroll-impl.css +292 -0
- package/dist/components/blocks/feature-split/FeatureSplit.css +95 -0
- package/dist/components/blocks/feature-split/FeatureSplit.d.ts +30 -0
- package/dist/components/blocks/feature-split/FeatureSplit.js +38 -0
- package/dist/components/blocks/feature-split/FeatureSplit.types.d.ts +39 -0
- package/dist/components/blocks/feature-split/FeatureSplit.types.js +14 -0
- package/dist/components/blocks/feature-split/feature-split-impl.css +83 -0
- package/dist/components/blocks/landing-hero/LandingHero.css +85 -0
- package/dist/components/blocks/landing-hero/LandingHero.d.ts +41 -0
- package/dist/components/blocks/landing-hero/LandingHero.js +54 -0
- package/dist/components/blocks/landing-hero/LandingHero.types.d.ts +37 -0
- package/dist/components/blocks/landing-hero/LandingHero.types.js +15 -0
- package/dist/components/blocks/landing-hero/landing-hero-impl.css +355 -0
- package/dist/components/blocks/logo-columns/LogoColumns.css +161 -0
- package/dist/components/blocks/logo-columns/LogoColumns.d.ts +23 -0
- package/dist/components/blocks/logo-columns/LogoColumns.js +46 -0
- package/dist/components/blocks/logo-columns/LogoColumns.types.d.ts +46 -0
- package/dist/components/blocks/logo-columns/LogoColumns.types.js +18 -0
- package/dist/components/blocks/logo-columns/logo-columns-impl.css +188 -0
- package/dist/components/blocks/logo-rows/LogoRows.css +122 -0
- package/dist/components/blocks/logo-rows/LogoRows.d.ts +20 -0
- package/dist/components/blocks/logo-rows/LogoRows.js +43 -0
- package/dist/components/blocks/logo-rows/LogoRows.types.d.ts +36 -0
- package/dist/components/blocks/logo-rows/LogoRows.types.js +16 -0
- package/dist/components/blocks/logo-rows/logo-rows-impl.css +179 -0
- package/dist/components/blocks/page-header/PageHeader.css +79 -0
- package/dist/components/blocks/page-header/PageHeader.d.ts +34 -0
- package/dist/components/blocks/page-header/PageHeader.js +43 -0
- package/dist/components/blocks/page-header/PageHeader.types.d.ts +32 -0
- package/dist/components/blocks/page-header/PageHeader.types.js +14 -0
- package/dist/components/blocks/page-header/page-header-impl.css +176 -0
- package/dist/components/blocks/product-hero/ProductHero.css +86 -0
- package/dist/components/blocks/product-hero/ProductHero.d.ts +35 -0
- package/dist/components/blocks/product-hero/ProductHero.js +48 -0
- package/dist/components/blocks/product-hero/ProductHero.types.d.ts +37 -0
- package/dist/components/blocks/product-hero/ProductHero.types.js +15 -0
- package/dist/components/blocks/product-hero/product-hero-impl.css +354 -0
- package/dist/components/blocks/testimonial-row/TestimonialRow.css +245 -0
- package/dist/components/blocks/testimonial-row/TestimonialRow.d.ts +20 -0
- package/dist/components/blocks/testimonial-row/TestimonialRow.js +128 -0
- package/dist/components/blocks/testimonial-row/TestimonialRow.types.d.ts +54 -0
- package/dist/components/blocks/testimonial-row/TestimonialRow.types.js +26 -0
- package/dist/components/blocks/testimonial-row/testimonial-row-impl.css +195 -0
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.css +181 -0
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.d.ts +22 -0
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.js +36 -0
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.d.ts +49 -0
- package/dist/components/blocks/testimonial-slider/TestimonialSlider.types.js +21 -0
- package/dist/components/blocks/testimonial-slider/testimonial-slider-impl.css +202 -0
- package/dist/components/blocks/use-reveal.d.ts +46 -0
- package/dist/components/blocks/use-reveal.js +120 -0
- package/dist/components/blocks/use-rotation.d.ts +62 -0
- package/dist/components/blocks/use-rotation.js +176 -0
- 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 +99 -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 +188 -0
- package/dist/components/core/button/Button.d.ts +27 -0
- package/dist/components/core/button/Button.js +57 -0
- package/dist/components/core/button/Button.types.d.ts +35 -0
- package/dist/components/core/button/Button.types.js +9 -0
- package/dist/components/core/button/button-impl.css +71 -0
- package/dist/components/core/button-icon/ButtonIcon.css +151 -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 +74 -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 +34 -0
- package/dist/components/core/card/Card.types.js +7 -0
- package/dist/components/core/card-body/CardBody.css +144 -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 +64 -0
- package/dist/components/core/card-body/CardBody.types.js +16 -0
- package/dist/components/core/card-body/card-body-impl.css +87 -0
- package/dist/components/core/card-button/CardButton.css +82 -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 +25 -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 +156 -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 +147 -0
- package/dist/components/core/dropdown-menu/DropdownMenu.d.ts +24 -0
- package/dist/components/core/dropdown-menu/DropdownMenu.js +311 -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 +150 -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 +91 -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 +134 -0
- package/dist/components/core/navbar/Navbar.d.ts +52 -0
- package/dist/components/core/navbar/Navbar.js +498 -0
- package/dist/components/core/navbar/Navbar.types.d.ts +68 -0
- package/dist/components/core/navbar/Navbar.types.js +17 -0
- package/dist/components/core/navbar/navbar-impl.css +597 -0
- package/dist/components/core/navbar/navbar-material.css +96 -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 +130 -0
- package/dist/components/core/navbar-menu/NavbarMenu.d.ts +6 -0
- package/dist/components/core/navbar-menu/NavbarMenu.js +187 -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 +118 -0
- package/dist/components/core/navbar-switcher/NavbarSwitcher.d.ts +21 -0
- package/dist/components/core/navbar-switcher/NavbarSwitcher.js +91 -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 +163 -0
- package/dist/components/core/pagination/Pagination.d.ts +30 -0
- package/dist/components/core/pagination/Pagination.js +366 -0
- package/dist/components/core/pagination/Pagination.types.d.ts +47 -0
- package/dist/components/core/pagination/Pagination.types.js +12 -0
- package/dist/components/core/pagination/pagination-impl.css +17 -0
- package/dist/components/core/pagination-dots/PaginationDots.css +60 -0
- package/dist/components/core/pagination-dots/PaginationDots.d.ts +25 -0
- package/dist/components/core/pagination-dots/PaginationDots.js +104 -0
- package/dist/components/core/pagination-dots/PaginationDots.types.d.ts +38 -0
- package/dist/components/core/pagination-dots/PaginationDots.types.js +9 -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 +401 -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 +162 -0
- package/dist/components/core/select-chip/SelectChip.d.ts +20 -0
- package/dist/components/core/select-chip/SelectChip.js +276 -0
- package/dist/components/core/select-chip/SelectChip.types.d.ts +62 -0
- package/dist/components/core/select-chip/SelectChip.types.js +14 -0
- package/dist/components/core/select-chip/select-chip-impl.css +49 -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 +97 -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 +149 -1
- package/dist/components/index.js +145 -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/logo-data.d.ts +24 -0
- package/dist/components/logo-data.js +11 -0
- package/dist/components/scroll-data.d.ts +64 -0
- package/dist/components/scroll-data.js +17 -0
- package/dist/components/testimonial-row-data.d.ts +51 -0
- package/dist/components/testimonial-row-data.js +11 -0
- package/dist/components/testimonial-slider-data.d.ts +26 -0
- package/dist/components/testimonial-slider-data.js +10 -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 +581 -162
- package/package.json +13 -4
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronLeftRegularIcon, ChevronRightRegularIcon, EllipsisRegularIcon } from '@deriv-com/quill-icons-web';
|
|
4
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
5
|
+
import { DropdownMenu } from '../dropdown-menu/DropdownMenu.js';
|
|
6
|
+
import { Icon } from '../icon/Icon.js';
|
|
7
|
+
import { MenuItem } from '../menu-item/MenuItem.js';
|
|
8
|
+
import './Pagination.css';
|
|
9
|
+
// Second, and it adds rather than corrects: the row stops clipping while a break's menu is
|
|
10
|
+
// open, which is a rule about two elements and cannot be a binding.
|
|
11
|
+
import './pagination-impl.css';
|
|
12
|
+
import { paginationDefaults, paginationParts } from './Pagination.types.js';
|
|
13
|
+
/**
|
|
14
|
+
* The glyph inside a step control.
|
|
15
|
+
*
|
|
16
|
+
* A constant rather than a map, the size axis having gone: there is one control measure
|
|
17
|
+
* here and so one mark that fits it. Written down rather than left to the glyph because a
|
|
18
|
+
* raw Quill icon ships its own width and height, and passing one straight through is how a
|
|
19
|
+
* step draws at the wrong size while every gate still passes.
|
|
20
|
+
*/
|
|
21
|
+
const GLYPH_SIZE = 'xs';
|
|
22
|
+
/**
|
|
23
|
+
* The most pages a break will offer in one menu.
|
|
24
|
+
*
|
|
25
|
+
* Fifty rows already outruns the surface and scrolls, which is the point at which a list stops
|
|
26
|
+
* being read and starts being searched — and a break in a set of five thousand stands for nearly
|
|
27
|
+
* all of them, so there is no length at which listing the run whole is honest. Past this the menu
|
|
28
|
+
* lists an evenly spaced sample of the run instead: the reader lands near the page they were after,
|
|
29
|
+
* and the break beside where they land stands for a shorter run and so steps through it more finely.
|
|
30
|
+
*/
|
|
31
|
+
const JUMP_LIMIT = 50;
|
|
32
|
+
/**
|
|
33
|
+
* The pages a break stands for, read off the numbers either side of it.
|
|
34
|
+
*
|
|
35
|
+
* The break itself carries no range. It does not need to: a gap sits between two numbered slots by
|
|
36
|
+
* construction, and everything between those two numbers is exactly what the row had no room to
|
|
37
|
+
* draw — so the range is a fact about the row rather than about the slot, and deriving it here is
|
|
38
|
+
* what keeps it true however the window arithmetic changes.
|
|
39
|
+
*/
|
|
40
|
+
function hidden(before, after) {
|
|
41
|
+
if (typeof before !== 'number' || typeof after !== 'number')
|
|
42
|
+
return [];
|
|
43
|
+
const from = before + 1;
|
|
44
|
+
const length = after - from;
|
|
45
|
+
if (length <= 0)
|
|
46
|
+
return [];
|
|
47
|
+
if (length <= JUMP_LIMIT)
|
|
48
|
+
return Array.from({ length }, (_, index) => from + index);
|
|
49
|
+
// Both ends of the run included, and evenly spaced between them. The stride is greater than one
|
|
50
|
+
// by definition here — the run is longer than the limit — so no two indexes can round onto the
|
|
51
|
+
// same page and the result is strictly increasing without being deduplicated.
|
|
52
|
+
const stride = (length - 1) / (JUMP_LIMIT - 1);
|
|
53
|
+
return Array.from({ length: JUMP_LIMIT }, (_, index) => from + Math.round(index * stride));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The pages worth showing, and where the row breaks.
|
|
57
|
+
*
|
|
58
|
+
* The first and last page are always offered, because they are the two a reader asks for
|
|
59
|
+
* by name — the start of the set and the end of it — and neither is reachable by stepping
|
|
60
|
+
* without pressing as many times as there are pages. Everything between is the window
|
|
61
|
+
* `siblingCount` opens around where the reader currently stands.
|
|
62
|
+
*
|
|
63
|
+
* The window is split rather than mirrored, and the odd one goes after the current page
|
|
64
|
+
* because forward is the direction the reader is travelling. At the default of one that
|
|
65
|
+
* makes the window the current page and the page after it, which is a row of six — and it
|
|
66
|
+
* holds the current page at the same place in that row on every page of the middle band,
|
|
67
|
+
* so the highlighted target stays put as the reader steps.
|
|
68
|
+
*
|
|
69
|
+
* The row holds the same number of targets on every page, which is why the arithmetic is
|
|
70
|
+
* shaped this way rather than the shorter form. That form let the ends of the set truncate
|
|
71
|
+
* the window, so a set of eight drew four targets on the first page and seven in the
|
|
72
|
+
* middle — and since the row is centred, those extra targets pushed both step controls
|
|
73
|
+
* outwards under the hand that had just pressed one.
|
|
74
|
+
*
|
|
75
|
+
* A break is drawn only where it stands for more than the page it replaced: `start > 3`
|
|
76
|
+
* means at least two pages sit unshown, and where only one does the row shows that page
|
|
77
|
+
* instead. An ellipsis occupying the width of the single page it names is punctuation that
|
|
78
|
+
* costs what it saves.
|
|
79
|
+
*/
|
|
80
|
+
function slots(current, last, siblings) {
|
|
81
|
+
const width = siblings + 5;
|
|
82
|
+
const before = Math.floor(siblings / 2);
|
|
83
|
+
const after = siblings - before;
|
|
84
|
+
const run = (from, to) => Array.from({ length: Math.max(0, to - from + 1) }, (_, index) => from + index);
|
|
85
|
+
if (last <= width)
|
|
86
|
+
return run(1, last);
|
|
87
|
+
const start = Math.max(2, current - before);
|
|
88
|
+
const end = Math.min(last - 1, current + after);
|
|
89
|
+
if (start <= 3)
|
|
90
|
+
return [...run(1, width - 2), 'gap', last];
|
|
91
|
+
if (end >= last - 2)
|
|
92
|
+
return [1, 'gap', ...run(last - width + 3, last)];
|
|
93
|
+
return [1, 'gap', ...run(start, end), 'gap', last];
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* What the row has to work with, measured, or null where there is nothing to measure.
|
|
97
|
+
*
|
|
98
|
+
* `overflowing` is the signal the decision hangs on, rather than a comparison of the room
|
|
99
|
+
* against the row's width. A `<nav>` in a block container takes the width it is given; a
|
|
100
|
+
* `<nav>` that is a flex item — a pagination row centred in a footer, which is most of
|
|
101
|
+
* them — is sized to its own contents instead, so `clientWidth` there is what the row
|
|
102
|
+
* already takes rather than what it may have. The list, though, only shrinks below its
|
|
103
|
+
* contents when something has constrained it, so its overflow is the one honest report of
|
|
104
|
+
* not fitting.
|
|
105
|
+
*
|
|
106
|
+
* Null where nothing can be measured. A width of zero is what an element out of the layout
|
|
107
|
+
* reports, and what jsdom reports for everything.
|
|
108
|
+
*/
|
|
109
|
+
function measurements(root, list) {
|
|
110
|
+
const rowGap = Number.parseFloat(getComputedStyle(root).columnGap) || 0;
|
|
111
|
+
const slotGap = Number.parseFloat(getComputedStyle(list).columnGap) || 0;
|
|
112
|
+
const steps = Array.from(root.children)
|
|
113
|
+
.filter((child) => child !== list)
|
|
114
|
+
.reduce((total, child) => total + child.offsetWidth + rowGap, 0);
|
|
115
|
+
const room = root.clientWidth - steps;
|
|
116
|
+
const widest = Array.from(list.children).reduce((most, child) => Math.max(most, child.offsetWidth), 0);
|
|
117
|
+
if (room <= 0 || widest <= 0)
|
|
118
|
+
return null;
|
|
119
|
+
return {
|
|
120
|
+
room,
|
|
121
|
+
holds: Math.floor((room + slotGap) / (widest + slotGap)),
|
|
122
|
+
// A pixel of tolerance, because a fractional layout rounds one way in the scroll width
|
|
123
|
+
// and the other in the client width.
|
|
124
|
+
overflowing: list.scrollWidth > list.clientWidth + 1,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* What the readout says under compact: a bare position, and the terseness is the point rather
|
|
129
|
+
* than a saving — the variant is chosen for a place with no width.
|
|
130
|
+
*/
|
|
131
|
+
function readout(current, last) {
|
|
132
|
+
return `${String(current)} / ${String(last)}`;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* A `<nav>` holding the ways through a set that has been divided into pages.
|
|
136
|
+
*
|
|
137
|
+
* Nothing about the reader's position is held here. `page` is the consumer's, because the
|
|
138
|
+
* results above this control are theirs too, and the two are one fact — a component keeping
|
|
139
|
+
* its own copy is how a row of numbers comes to disagree with what it describes.
|
|
140
|
+
*
|
|
141
|
+
* The one thing it does hold is how much of the window there is room for, which is not the
|
|
142
|
+
* reader's position but the container's width, and is a fact no consumer can pass because
|
|
143
|
+
* only the row can see it.
|
|
144
|
+
*
|
|
145
|
+
* Every control in the row is drawn here rather than borrowed, which is where this parts
|
|
146
|
+
* company with product's. There the steps are ButtonIcons and the numbered pages are
|
|
147
|
+
* Buttons; this package's ButtonIcon has no disabled state and says so in its own source,
|
|
148
|
+
* being a family of links, and a step at the end of the set has to be disabled rather than
|
|
149
|
+
* removed. Its Button was an anchor with a required href when this was built, and it has no quiet
|
|
150
|
+
* form, so a row of
|
|
151
|
+
* page numbers built from it would be a row of calls to action. Both are correct decisions
|
|
152
|
+
* for what those components are, and neither leaves anything to borrow.
|
|
153
|
+
*
|
|
154
|
+
* What a press is depends on the variant, and on `pageHref`. Given it, every route to a
|
|
155
|
+
* page is an anchor — the numbered targets and both steps — which is what gives a visitor
|
|
156
|
+
* cmd-click, a destination in the status bar and a link a crawler can follow. Without it
|
|
157
|
+
* they are buttons reporting through `onPageChange`.
|
|
158
|
+
*/
|
|
159
|
+
export function Pagination({ variant = paginationDefaults.variant, page = paginationDefaults.page, totalPages = paginationDefaults.totalPages, onPageChange, pageHref, siblingCount = paginationDefaults.siblingCount, label = paginationDefaults.label, previousLabel = paginationDefaults.previousLabel, nextLabel = paginationDefaults.nextLabel, morePagesLabel = paginationDefaults.morePagesLabel, ...rest }) {
|
|
160
|
+
// Clamped rather than trusted. A page beyond the set is what a consumer holds for the
|
|
161
|
+
// moment between a filter narrowing the results and their own state catching up, and a
|
|
162
|
+
// row that renders nothing during it reads as the component breaking rather than as the
|
|
163
|
+
// data moving. Truncated because nothing downstream means anything at 3.5.
|
|
164
|
+
// Truncated because nothing downstream — an index, a label, a comparison — means anything at
|
|
165
|
+
// 3.5, and floored at a real number because nothing downstream survives NaN or Infinity either:
|
|
166
|
+
// a total arriving as Math.ceil(total / size) is NaN for exactly as long as `total` is undefined,
|
|
167
|
+
// and a row built from it draws a page numbered NaN beside two empty menus.
|
|
168
|
+
const whole = (value, floor) => (Number.isFinite(value) ? Math.max(floor, Math.trunc(value)) : floor);
|
|
169
|
+
const last = whole(totalPages, 1);
|
|
170
|
+
const current = Math.min(whole(page, 1), last);
|
|
171
|
+
const siblings = whole(siblingCount, 0);
|
|
172
|
+
const atStart = current <= 1;
|
|
173
|
+
const atEnd = current >= last;
|
|
174
|
+
const rootRef = useRef(null);
|
|
175
|
+
const listRef = useRef(null);
|
|
176
|
+
/**
|
|
177
|
+
* How many siblings the row is drawing, which is the consumer's number until the width
|
|
178
|
+
* says otherwise. Null means nothing has been decided, and it is what every row starts
|
|
179
|
+
* at: a row that opened at its shortest and grew a moment later would be a visible flinch
|
|
180
|
+
* on every mount, and most containers have the room.
|
|
181
|
+
*/
|
|
182
|
+
const [fit, setFit] = useState(null);
|
|
183
|
+
const shown = fit === null ? siblings : Math.min(siblings, fit);
|
|
184
|
+
/**
|
|
185
|
+
* The room the row had when it last gave something up.
|
|
186
|
+
*
|
|
187
|
+
* Overflow is the only honest signal that the row does not fit, and a folded row does not
|
|
188
|
+
* overflow — so once folded, the row cannot tell from its own width whether the container
|
|
189
|
+
* has since grown. This remembers the width that forced it, and anything wider is worth
|
|
190
|
+
* trying the full window at again. Monotonic on purpose, so the two decisions cannot
|
|
191
|
+
* chase each other.
|
|
192
|
+
*/
|
|
193
|
+
const foldedAt = useRef(Number.POSITIVE_INFINITY);
|
|
194
|
+
const measure = useCallback(() => {
|
|
195
|
+
const root = rootRef.current;
|
|
196
|
+
const list = listRef.current;
|
|
197
|
+
if (root === null || list === null)
|
|
198
|
+
return;
|
|
199
|
+
/*
|
|
200
|
+
Not while a break's menu is open. The rule that keeps that menu out of the list's
|
|
201
|
+
scrollable overflow takes the clip away for as long as it is up, and overflow is the only
|
|
202
|
+
honest report of not fitting — so a measurement taken now would read a row that cannot clip
|
|
203
|
+
as a row with room to spare, and give the window back into a container that never had space
|
|
204
|
+
for it.
|
|
205
|
+
|
|
206
|
+
Read off the DOM rather than off state, which is where this parts company with product's.
|
|
207
|
+
There the row holds which break is open because it spends that state on the trigger's own
|
|
208
|
+
look — an open break keeps a container the way the current page does. Nothing here needs
|
|
209
|
+
that: the break is a part of ours and its open state is already on the element, published
|
|
210
|
+
by DropdownMenu as `aria-expanded`. Holding a second copy would be keeping a fact this
|
|
211
|
+
component does not own purely to answer one question. It is the same attribute the
|
|
212
|
+
stylesheet reads to stop the row clipping, so there is one source rather than two.
|
|
213
|
+
*/
|
|
214
|
+
if (list.querySelector('[aria-expanded="true"]') !== null)
|
|
215
|
+
return;
|
|
216
|
+
const measured = measurements(root, list);
|
|
217
|
+
if (measured === null)
|
|
218
|
+
return;
|
|
219
|
+
if (measured.overflowing) {
|
|
220
|
+
// A row of `holds` slots carries holds - 5 siblings once the four fixed slots and the
|
|
221
|
+
// current page are paid for. Never more than was asked for: this decides what the
|
|
222
|
+
// width forbids and the consumer decides the rest. Where even none of them fits there
|
|
223
|
+
// is nothing left to give up that would not cost the reader the page they are on or an
|
|
224
|
+
// end of the set, so the list scrolls — which is the point at which the column wanted
|
|
225
|
+
// compact rather than numbers.
|
|
226
|
+
const afford = Math.max(0, measured.holds - 5);
|
|
227
|
+
if (afford < shown) {
|
|
228
|
+
foldedAt.current = measured.room;
|
|
229
|
+
setFit(afford);
|
|
230
|
+
}
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (fit !== null && measured.room > foldedAt.current)
|
|
234
|
+
setFit(null);
|
|
235
|
+
}, [fit, shown]);
|
|
236
|
+
// Layout rather than a plain effect: between the two the browser would paint the full
|
|
237
|
+
// window in a container that cannot hold it, which is the clipped page for one frame.
|
|
238
|
+
useLayoutEffect(() => {
|
|
239
|
+
if (variant !== 'pages')
|
|
240
|
+
return;
|
|
241
|
+
measure();
|
|
242
|
+
}, [measure, variant, last, shown]);
|
|
243
|
+
/**
|
|
244
|
+
* The container changing width changes how much of the window there is room for.
|
|
245
|
+
*
|
|
246
|
+
* Absent where there is no ResizeObserver rather than fatal — the row keeps the window the
|
|
247
|
+
* last measurement allowed. jsdom is the environment that asks: the generated behaviour
|
|
248
|
+
* test runs there and reports every width as zero, which `measurements` declines to answer.
|
|
249
|
+
*/
|
|
250
|
+
useEffect(() => {
|
|
251
|
+
const root = rootRef.current;
|
|
252
|
+
if (root === null)
|
|
253
|
+
return;
|
|
254
|
+
if (variant !== 'pages')
|
|
255
|
+
return;
|
|
256
|
+
if (typeof ResizeObserver === 'undefined')
|
|
257
|
+
return;
|
|
258
|
+
const observer = new ResizeObserver(() => {
|
|
259
|
+
measure();
|
|
260
|
+
});
|
|
261
|
+
observer.observe(root);
|
|
262
|
+
return () => {
|
|
263
|
+
observer.disconnect();
|
|
264
|
+
};
|
|
265
|
+
}, [measure, variant]);
|
|
266
|
+
/**
|
|
267
|
+
* What a press means, in one place.
|
|
268
|
+
*
|
|
269
|
+
* An anchor needs none of this — the browser follows its href and nothing here runs. This is for
|
|
270
|
+
* the presses that are not anchors: every target when no pageHref was given, and the rows of a
|
|
271
|
+
* break's menu always, MenuItem taking no href of its own. Where a page has an address and the
|
|
272
|
+
* press cannot carry it, this is what walks the reader there.
|
|
273
|
+
*/
|
|
274
|
+
const goTo = (to) => {
|
|
275
|
+
if (onPageChange !== undefined)
|
|
276
|
+
onPageChange(to);
|
|
277
|
+
else if (pageHref !== undefined)
|
|
278
|
+
window.location.assign(pageHref(to));
|
|
279
|
+
};
|
|
280
|
+
const go = (to) => () => {
|
|
281
|
+
goTo(to);
|
|
282
|
+
};
|
|
283
|
+
// The row as slots, held here rather than mapped inside the JSX, because the arithmetic
|
|
284
|
+
// is a fact about the row rather than about any one slot.
|
|
285
|
+
const row = variant === 'pages' ? slots(current, last, shown) : [];
|
|
286
|
+
/**
|
|
287
|
+
* One step control, which is an anchor where there is a page to point at and a button
|
|
288
|
+
* otherwise.
|
|
289
|
+
*
|
|
290
|
+
* At either end of the set there is no page, so it is a disabled `<button>` even in link
|
|
291
|
+
* mode — the one place the two modes meet, and the reason this is drawn here rather than
|
|
292
|
+
* taken from ButtonIcon: a link cannot be disabled, which is exactly why that component
|
|
293
|
+
* declines to offer it.
|
|
294
|
+
*/
|
|
295
|
+
const stepControl = (to, name, disabled, glyph) => {
|
|
296
|
+
const mark = _jsx(Icon, { size: GLYPH_SIZE, children: glyph });
|
|
297
|
+
if (pageHref !== undefined && !disabled) {
|
|
298
|
+
return (_jsx("a", { className: paginationParts.step, href: pageHref(to), "aria-label": name, onClick: go(to), children: mark }));
|
|
299
|
+
}
|
|
300
|
+
return (_jsx("button", { className: paginationParts.step, type: "button", "aria-label": name, disabled: disabled, onClick: go(to), children: mark }));
|
|
301
|
+
};
|
|
302
|
+
return (_jsxs("nav", { ref: rootRef, className: paginationParts.root, "aria-label": label, "data-variant": variant, ...rest, children: [stepControl(current - 1, previousLabel, atStart, _jsx(ChevronLeftRegularIcon, {})), variant === 'pages' && (_jsx("div", { className: paginationParts.list, ref: listRef, children: row.map((slot, index) => {
|
|
303
|
+
if (slot === 'gap') {
|
|
304
|
+
const stands = row[index - 1];
|
|
305
|
+
/*
|
|
306
|
+
The break, which presses.
|
|
307
|
+
|
|
308
|
+
It was a span, and aria-hidden with it, on the argument that it names no page —
|
|
309
|
+
true, and the wrong half of the fact. What it stands for is every page the row had
|
|
310
|
+
no room to draw, which is exactly the set a reader who cannot see the page they
|
|
311
|
+
want is after, and the row was making them walk there.
|
|
312
|
+
|
|
313
|
+
A trigger handed to DropdownMenu, which that component did not accept until this
|
|
314
|
+
needed it — its own chevron note named an icon-only trigger as the case product has
|
|
315
|
+
the prop for and said neither case existed here. The menu behind it is
|
|
316
|
+
DropdownMenu's rather than a surface of ours: what happens when a menu opens, where
|
|
317
|
+
focus goes, what Escape does and what the arrow keys move through is described
|
|
318
|
+
once, in the component that exists to describe it.
|
|
319
|
+
|
|
320
|
+
No chevron: a passed trigger is drawn by whoever passed it, and a break wearing one
|
|
321
|
+
would read as a control with a set of its own rather than as the pages between two
|
|
322
|
+
numbers.
|
|
323
|
+
|
|
324
|
+
Keyed by the number in front of it rather than by its position in the row, so a
|
|
325
|
+
break whose range changes under a fold is a different break and takes its open menu
|
|
326
|
+
with it.
|
|
327
|
+
*/
|
|
328
|
+
return (_jsx(DropdownMenu, { label: morePagesLabel, trigger:
|
|
329
|
+
/*
|
|
330
|
+
This component's own button rather than a ButtonIcon, which is what it was
|
|
331
|
+
until the row was looked at. Product's break is a transparent secondary
|
|
332
|
+
ButtonIcon; nothing here is transparent — secondary paints a border — so the
|
|
333
|
+
break wore a ring none of the numbers beside it wear and read as a different
|
|
334
|
+
kind of thing in the row. DropdownMenu never asked for a ButtonIcon: it wires
|
|
335
|
+
whatever element it is handed, so this is a plain button carrying the break
|
|
336
|
+
part, and the part carries the same ground, corner and states as the page
|
|
337
|
+
targets either side of it.
|
|
338
|
+
*/
|
|
339
|
+
_jsx("button", { className: paginationParts.break, type: "button", "aria-label": morePagesLabel, children: _jsx(Icon, { size: GLYPH_SIZE, children: _jsx(EllipsisRegularIcon, {}) }) }), children: hidden(stands, row[index + 1]).map((to) => (_jsx(MenuItem, { onSelect: () => {
|
|
340
|
+
// The same split every other route to a page makes, and it has to be made
|
|
341
|
+
// here rather than by the row: MenuItem takes no href, so a menu row cannot
|
|
342
|
+
// be an anchor the way a numbered target is. Without this the menu reported
|
|
343
|
+
// to a handler the pages variant is not obliged to have — so in the
|
|
344
|
+
// configuration that variant is documented for, every row did nothing.
|
|
345
|
+
goTo(to);
|
|
346
|
+
}, children: String(to) }, to))) }, `gap-${String(stands ?? index)}`));
|
|
347
|
+
}
|
|
348
|
+
const isCurrent = slot === current;
|
|
349
|
+
// aria-current rather than aria-selected: these are destinations in a set of
|
|
350
|
+
// pages, not options in a listbox, and "page" is the token that says so. The
|
|
351
|
+
// current page's own target stays enabled and in the tab order — a reader who
|
|
352
|
+
// lands on it should hear which page they are on, and pressing it is a harmless
|
|
353
|
+
// no-op rather than a dead end.
|
|
354
|
+
//
|
|
355
|
+
// data-current beside it, saying the same thing to a different reader. The
|
|
356
|
+
// generated stylesheet selects on the data attribute, so without it the rule
|
|
357
|
+
// that fills the current page matches nothing and every number renders alike —
|
|
358
|
+
// which is exactly what shipped until it was looked at. The contract keeps them
|
|
359
|
+
// apart on purpose: what the current page announces and what it looks like are
|
|
360
|
+
// two decisions, and one should not be able to silently change the other.
|
|
361
|
+
if (pageHref !== undefined) {
|
|
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
|
+
}
|
|
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, {}))] }));
|
|
366
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'react';
|
|
2
|
+
export interface PaginationOwnProps {
|
|
3
|
+
/**
|
|
4
|
+
* `pages` — An index or archive whose pages have addresses of their own — a blog listing, a news archive, a resource library. The only variant offering a numbered target, so the only one on which reaching page fourteen costs a single press rather than thirteen, and the only one a crawler can follow past page one. It draws Buttons, which in this package are anchors, so it needs pageHref and the pages it points at have to exist as URLs. A page too far out to be drawn is still not a walk: the break between two runs of numbers presses, and offers the pages it stands for
|
|
5
|
+
* `compact` — A place with no room for a row of numbers — a card footer, a sidebar, a column at a phone's width. Position and the two steps, and nothing else. Like pages, its steps are anchors given pageHref and buttons without it
|
|
6
|
+
*/
|
|
7
|
+
variant?: 'pages' | 'compact';
|
|
8
|
+
/** Always — it is which page is on screen, counting from one, and the component renders around it rather than holding it. The consumer owns this because the results do: the page number and the rows beneath it are one fact, and a control keeping its own copy is how the two come to disagree. The default is the first page, which is where a set with nothing said about it starts */
|
|
9
|
+
page?: number;
|
|
10
|
+
/** How many pages the set has been divided into. It decides where the row ends, when the ellipsis appears, and when next goes disabled. The default of one is the honest answer for a set nothing has been said about, and it is also the case the component should not be used in at all — a single page has nothing to move between */
|
|
11
|
+
totalPages?: number;
|
|
12
|
+
/** What the page does when the reader asks for another one, counting from one. Required wherever the route to a page is a press rather than a destination: the numbered targets and the steps under any variant given no pageHref. Under pages it is the pageHref that carries the reader, so this is the reporting half rather than the moving one — useful for telling analytics, and unnecessary if nothing is listening. One of this and pageHref is needed; a component given neither draws a row nothing can move. */
|
|
13
|
+
onPageChange?: (page: number) => void;
|
|
14
|
+
/** The address of a page, given the page number. Passing it makes every route to a page an anchor: the numbered targets, and both steps. Required under the pages variant, which draws Buttons — and a Button in this package is an anchor with a destination, never a press the page handles. Pass it under compact too wherever the pages have real URLs, because an anchor is what gives a visitor cmd-click, a destination in the status bar, and a link a search engine can follow to page two. One of this and onPageChange is needed; a component given neither draws a row nothing can move. */
|
|
15
|
+
pageHref?: (page: number) => string;
|
|
16
|
+
/** How many numbered pages sit around the current one before the row breaks, under the pages variant. Around rather than either side: the window is split, with the odd one going forward, since the page the reader has not read is the one they most likely want. One is the current page and the one after it, a row of six; two is mirrored. The most it will show rather than a promise, since the row drops what the container cannot hold */
|
|
17
|
+
siblingCount?: number;
|
|
18
|
+
/** Always, and the default is almost always right. It names the landmark rather than the content — a screen reader user listing what is on a page hears this, and a nav with no name is one they cannot tell from the page's other navigation. Set it where a page carries two of these, so the two are distinguishable by what they page through */
|
|
19
|
+
label?: string;
|
|
20
|
+
/** The accessible name for the step-back control, which is a glyph and therefore announces nothing on its own. Override it to translate it, or where "page" is the wrong noun for what is being stepped through */
|
|
21
|
+
previousLabel?: string;
|
|
22
|
+
/** The accessible name for the step-forward control, for the reason previousLabel exists. Keep the two parallel: a pair reading "Next page" and "Go back" is two people's wording in one control */
|
|
23
|
+
nextLabel?: string;
|
|
24
|
+
/** The accessible name for the break between two runs of numbered pages — the control that opens a menu of the pages that break stands for. A glyph announces nothing, which is the position previousLabel and nextLabel are in, and this is passed the same way the two steps' names are, as the control's own accessible name. It names the menu as well as the control, so a reader who has opened it hears which menu they are in */
|
|
25
|
+
morePagesLabel?: string;
|
|
26
|
+
}
|
|
27
|
+
export type PaginationProps = PaginationOwnProps & Omit<HTMLAttributes<HTMLElement>, 'className' | 'variant' | 'page' | 'totalPages' | 'onPageChange' | 'pageHref' | 'siblingCount' | 'label' | 'previousLabel' | 'nextLabel' | 'morePagesLabel'>;
|
|
28
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
29
|
+
export declare const paginationParts: {
|
|
30
|
+
readonly root: "dds-pagination";
|
|
31
|
+
readonly list: "dds-pagination__list";
|
|
32
|
+
readonly summary: "dds-pagination__summary";
|
|
33
|
+
readonly step: "dds-pagination__step";
|
|
34
|
+
readonly page: "dds-pagination__page";
|
|
35
|
+
readonly break: "dds-pagination__break";
|
|
36
|
+
};
|
|
37
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
38
|
+
export declare const paginationDefaults: {
|
|
39
|
+
readonly variant: "pages";
|
|
40
|
+
readonly page: 1;
|
|
41
|
+
readonly totalPages: 1;
|
|
42
|
+
readonly siblingCount: 1;
|
|
43
|
+
readonly label: "Pagination";
|
|
44
|
+
readonly previousLabel: "Previous page";
|
|
45
|
+
readonly nextLabel: "Next page";
|
|
46
|
+
readonly morePagesLabel: "More pages";
|
|
47
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// GENERATED from pagination.contract.json. Do not edit.
|
|
2
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
3
|
+
export const paginationParts = {
|
|
4
|
+
root: 'dds-pagination',
|
|
5
|
+
list: 'dds-pagination__list',
|
|
6
|
+
summary: 'dds-pagination__summary',
|
|
7
|
+
step: 'dds-pagination__step',
|
|
8
|
+
page: 'dds-pagination__page',
|
|
9
|
+
break: 'dds-pagination__break',
|
|
10
|
+
};
|
|
11
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
12
|
+
export const paginationDefaults = { variant: 'pages', page: 1, totalPages: 1, siblingCount: 1, label: 'Pagination', previousLabel: 'Previous page', nextLabel: 'Next page', morePagesLabel: 'More pages' };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* What the contract cannot hold, which here is one rule about two elements.
|
|
3
|
+
*
|
|
4
|
+
* The row of targets scrolls when it cannot fit, which is the last resort after giving up
|
|
5
|
+
* siblings — and a scroll container clips. A break's menu is drawn inside that container, so
|
|
6
|
+
* the clip that saves the row from a half-drawn page also takes the top off the menu. The
|
|
7
|
+
* two cannot both be bindings: a binding carries one token for one part in one state, and
|
|
8
|
+
* this is the list's overflow answering to a descendant's aria-expanded.
|
|
9
|
+
*
|
|
10
|
+
* `:has` rather than a class the component toggles, because the fact is already in the DOM.
|
|
11
|
+
* DropdownMenu publishes `aria-expanded` on whatever trigger it was given, so the row does
|
|
12
|
+
* not have to hold a second copy of a state it does not own — and a copy is what would drift
|
|
13
|
+
* the first time a menu shut by a route the row did not hear about.
|
|
14
|
+
*/
|
|
15
|
+
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__list:has([aria-expanded='true']) {
|
|
16
|
+
overflow: visible;
|
|
17
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* GENERATED from paginationdots.contract.json. Do not edit. */
|
|
2
|
+
|
|
3
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots {
|
|
4
|
+
align-items: center;
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: row;
|
|
7
|
+
column-gap: var(--space-gap-sm);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots .dds-paginationdots__dot {
|
|
11
|
+
transition-property: outline-color, outline-width;
|
|
12
|
+
align-items: center;
|
|
13
|
+
appearance: none;
|
|
14
|
+
background-color: transparent;
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
color: inherit;
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
display: flex;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
outline-style: solid;
|
|
21
|
+
padding: 0;
|
|
22
|
+
border-radius: var(--radius-pill);
|
|
23
|
+
border-width: var(--border-width-none);
|
|
24
|
+
min-block-size: var(--size-target-min);
|
|
25
|
+
min-inline-size: var(--size-dot-diameter);
|
|
26
|
+
outline-width: var(--border-width-none);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots .dds-paginationdots__mark {
|
|
30
|
+
transition-property: inline-size, opacity;
|
|
31
|
+
background-color: currentcolor;
|
|
32
|
+
display: block;
|
|
33
|
+
flex: none;
|
|
34
|
+
block-size: var(--size-dot-diameter);
|
|
35
|
+
border-radius: var(--radius-pill);
|
|
36
|
+
inline-size: var(--size-dot-diameter);
|
|
37
|
+
opacity: var(--opacity-dot-rest);
|
|
38
|
+
transition-duration: var(--motion-duration-slow);
|
|
39
|
+
transition-timing-function: var(--motion-easing-shift);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots .dds-paginationdots__dot:focus-visible {
|
|
43
|
+
outline-color: var(--color-border-focus);
|
|
44
|
+
outline-width: var(--border-width-focus);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots .dds-paginationdots__mark[data-current="true"] {
|
|
48
|
+
inline-size: var(--size-dot-current);
|
|
49
|
+
opacity: var(--opacity-dot-current);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots[data-variant="accent"] .dds-paginationdots__dot {
|
|
53
|
+
color: var(--color-fg-brand-accent);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@media (prefers-reduced-motion: reduce) {
|
|
57
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots,
|
|
58
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots * { transition: none !important; }
|
|
59
|
+
}
|
|
60
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import './PaginationDots.css';
|
|
2
|
+
import { type PaginationDotsProps } from './PaginationDots.types.js';
|
|
3
|
+
export type { PaginationDotsProps };
|
|
4
|
+
/**
|
|
5
|
+
* A row of marks, one per position in a short sequence, every one a button that moves there — and,
|
|
6
|
+
* under `autoplay`, a row that moves on its own.
|
|
7
|
+
*
|
|
8
|
+
* Split out of Pagination, where it was a variant. A set of results and a slider's slides are
|
|
9
|
+
* different questions — how far does this run, against where am I — and the one variant that
|
|
10
|
+
* answered the second was the one that needed none of Pagination's other props. Steps are not
|
|
11
|
+
* here: whatever holds the row puts previous and next beside it, where its own layout wants them.
|
|
12
|
+
*
|
|
13
|
+
* Drawn in the ground's own ink. The marks are currentcolor, the rest at opacity.dot-rest and the
|
|
14
|
+
* current one solid and stretched to size.dot.current, so one row reads on any band without
|
|
15
|
+
* naming a colour.
|
|
16
|
+
*
|
|
17
|
+
* Nothing about position is held here: `page` is the consumer's, because the slide in view is
|
|
18
|
+
* theirs too, and the two are one fact. Autoplay therefore moves nothing itself — every
|
|
19
|
+
* motion.duration.dwell it reports the next position through onPageChange and waits for `page` to
|
|
20
|
+
* come back. A reader who presses a mark stops it for good. It holds while `paused` says so — the
|
|
21
|
+
* holder's hover, focus, or its own stop — and never moves for a reader who asked for less motion.
|
|
22
|
+
* There is no pause control, by decision: a press is the way to stop it, and the contract says what
|
|
23
|
+
* that does and does not give WCAG 2.2.2.
|
|
24
|
+
*/
|
|
25
|
+
export declare function PaginationDots({ variant, page, totalPages, onPageChange, autoplay, paused, label, itemLabel, }: PaginationDotsProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import './PaginationDots.css';
|
|
5
|
+
import { paginationDotsDefaults, paginationDotsParts, } from './PaginationDots.types.js';
|
|
6
|
+
/**
|
|
7
|
+
* The most marks the row will draw.
|
|
8
|
+
*
|
|
9
|
+
* A guard rather than a design threshold — the row is for a handful, and its guidance says so.
|
|
10
|
+
* What it guards against is a total wired straight from a result count: five thousand of them
|
|
11
|
+
* built five thousand buttons and took the page with it. Past this the marks give way to the
|
|
12
|
+
* position written as numbers, which a reader can see, where an empty row would read as broken.
|
|
13
|
+
*/
|
|
14
|
+
const DOT_LIMIT = 20;
|
|
15
|
+
/**
|
|
16
|
+
* A CSS time as milliseconds, the unit read rather than assumed: the same token arrives as `5000ms`
|
|
17
|
+
* from a dev server and `5s` once a minifier has been over it. Null for anything else, so the row
|
|
18
|
+
* holds still rather than inventing a timing.
|
|
19
|
+
*/
|
|
20
|
+
function milliseconds(value) {
|
|
21
|
+
const time = value.trim();
|
|
22
|
+
const amount = Number.parseFloat(time);
|
|
23
|
+
if (!Number.isFinite(amount))
|
|
24
|
+
return null;
|
|
25
|
+
if (/ms$/i.test(time))
|
|
26
|
+
return amount;
|
|
27
|
+
if (/s$/i.test(time))
|
|
28
|
+
return amount * 1000;
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Whether the reader has asked for less motion, kept current if they change it. Until it has been
|
|
33
|
+
* read — on the server, before the first effect — the answer is yes, the safe one: a row that
|
|
34
|
+
* starts still and then moves is better than one that moves for a frame for a reader who said not to.
|
|
35
|
+
*/
|
|
36
|
+
function usePrefersLessMotion() {
|
|
37
|
+
const [less, setLess] = useState(true);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (typeof window.matchMedia !== 'function')
|
|
40
|
+
return;
|
|
41
|
+
const query = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
42
|
+
const update = () => setLess(query.matches);
|
|
43
|
+
update();
|
|
44
|
+
query.addEventListener('change', update);
|
|
45
|
+
return () => query.removeEventListener('change', update);
|
|
46
|
+
}, []);
|
|
47
|
+
return less;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A row of marks, one per position in a short sequence, every one a button that moves there — and,
|
|
51
|
+
* under `autoplay`, a row that moves on its own.
|
|
52
|
+
*
|
|
53
|
+
* Split out of Pagination, where it was a variant. A set of results and a slider's slides are
|
|
54
|
+
* different questions — how far does this run, against where am I — and the one variant that
|
|
55
|
+
* answered the second was the one that needed none of Pagination's other props. Steps are not
|
|
56
|
+
* here: whatever holds the row puts previous and next beside it, where its own layout wants them.
|
|
57
|
+
*
|
|
58
|
+
* Drawn in the ground's own ink. The marks are currentcolor, the rest at opacity.dot-rest and the
|
|
59
|
+
* current one solid and stretched to size.dot.current, so one row reads on any band without
|
|
60
|
+
* naming a colour.
|
|
61
|
+
*
|
|
62
|
+
* Nothing about position is held here: `page` is the consumer's, because the slide in view is
|
|
63
|
+
* theirs too, and the two are one fact. Autoplay therefore moves nothing itself — every
|
|
64
|
+
* motion.duration.dwell it reports the next position through onPageChange and waits for `page` to
|
|
65
|
+
* come back. A reader who presses a mark stops it for good. It holds while `paused` says so — the
|
|
66
|
+
* holder's hover, focus, or its own stop — and never moves for a reader who asked for less motion.
|
|
67
|
+
* There is no pause control, by decision: a press is the way to stop it, and the contract says what
|
|
68
|
+
* that does and does not give WCAG 2.2.2.
|
|
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, }) {
|
|
71
|
+
const count = Math.max(0, Math.floor(totalPages));
|
|
72
|
+
const current = Math.min(Math.max(1, Math.floor(page)), Math.max(1, count));
|
|
73
|
+
const root = useRef(null);
|
|
74
|
+
const lessMotion = usePrefersLessMotion();
|
|
75
|
+
/*
|
|
76
|
+
Stopped for good once the reader presses a mark. A reader who chose a position has said where
|
|
77
|
+
they want to be, and moving them on from it five seconds later would take that back — the WAI
|
|
78
|
+
carousel pattern's rule, and the way this row offers a reader a stop without a control for it.
|
|
79
|
+
*/
|
|
80
|
+
const [stopped, setStopped] = useState(false);
|
|
81
|
+
const running = autoplay && !stopped && !paused && !lessMotion && count > 1 && onPageChange !== undefined;
|
|
82
|
+
// Read through a ref so a new handler on every render does not re-arm the timer.
|
|
83
|
+
const report = useRef(onPageChange);
|
|
84
|
+
report.current = onPageChange;
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
if (!running || root.current === null)
|
|
87
|
+
return;
|
|
88
|
+
const dwell = milliseconds(getComputedStyle(root.current).getPropertyValue('--motion-duration-dwell'));
|
|
89
|
+
if (dwell === null)
|
|
90
|
+
return;
|
|
91
|
+
const timer = window.setTimeout(() => report.current?.((current % count) + 1), dwell);
|
|
92
|
+
return () => window.clearTimeout(timer);
|
|
93
|
+
}, [running, current, count]);
|
|
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)}` }) }));
|
|
96
|
+
}
|
|
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
|
+
const here = at === current;
|
|
99
|
+
return (_jsx("button", { type: "button", className: paginationDotsParts.dot, "aria-label": `${itemLabel} ${String(at)}`, "aria-current": here ? 'true' : undefined, onClick: () => {
|
|
100
|
+
setStopped(true);
|
|
101
|
+
onPageChange?.(at);
|
|
102
|
+
}, children: _jsx("span", { className: paginationDotsParts.mark, "data-current": here ? 'true' : undefined }) }, at));
|
|
103
|
+
}) }));
|
|
104
|
+
}
|