@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,120 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useLayoutEffect, useRef, useState } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Whether a block has arrived on screen yet, so its stylesheet can bring it in.
|
|
5
|
+
*
|
|
6
|
+
* Every trigger CSS alone can offer is invisible somewhere, and both were tried here first. A
|
|
7
|
+
* timed animation fires when the element is created, so a block below the fold has finished
|
|
8
|
+
* arriving before a reader scrolls to it. A scroll-driven one — `animation-timeline: view()` —
|
|
9
|
+
* fires as the element enters the viewport, so a block that is *already* in view at the first
|
|
10
|
+
* frame is past the range before anything is painted, and an opening band never moves at all.
|
|
11
|
+
*
|
|
12
|
+
* What is wanted is "when it comes into view, counting already being there as coming into view",
|
|
13
|
+
* and that is the one thing a view timeline cannot say. An observer can, which is the whole reason
|
|
14
|
+
* this file exists.
|
|
15
|
+
*
|
|
16
|
+
* It answers `true` before it knows anything, and that is deliberate. A block hidden until
|
|
17
|
+
* JavaScript says otherwise is content behind a script — a reader with none, or one whose bundle
|
|
18
|
+
* failed, gets a blank band. So the resting answer is visible, and hiding is something this only
|
|
19
|
+
* does once it is running and has somewhere to put the block back.
|
|
20
|
+
*
|
|
21
|
+
* `useLayoutEffect` so the hiding lands before the browser paints. In an effect it would run after
|
|
22
|
+
* the first frame, and every block would show itself, hide, and come back — a flash on every
|
|
23
|
+
* section of the page.
|
|
24
|
+
*
|
|
25
|
+
* It fires once. A section that re-arrived every time a reader scrolled back up would be a page
|
|
26
|
+
* that will not settle, and the observer is disconnected rather than left listening.
|
|
27
|
+
*/
|
|
28
|
+
export function useReveal() {
|
|
29
|
+
const held = useRef(null);
|
|
30
|
+
const [revealed, setRevealed] = useState(true);
|
|
31
|
+
useLayoutEffect(() => {
|
|
32
|
+
const element = held.current;
|
|
33
|
+
if (element === null)
|
|
34
|
+
return;
|
|
35
|
+
// A reader who asked for less movement is not hidden and then shown; they are simply shown.
|
|
36
|
+
// The stylesheet drops the transition as well, so this is the half that matters: without it
|
|
37
|
+
// the block would still be hidden for a frame before appearing, which is the flicker that
|
|
38
|
+
// preference exists to remove.
|
|
39
|
+
//
|
|
40
|
+
// Asked defensively, like the observer below. A renderer with no `matchMedia` cannot be
|
|
41
|
+
// asked what the reader prefers, and the honest answer to a question that cannot be asked
|
|
42
|
+
// is the one that hides nothing.
|
|
43
|
+
const asked = typeof window.matchMedia === 'function';
|
|
44
|
+
if (asked && window.matchMedia('(prefers-reduced-motion: reduce)').matches)
|
|
45
|
+
return;
|
|
46
|
+
// Anything the browser cannot observe arrives already arrived, which is the same answer this
|
|
47
|
+
// hook starts on: seen rather than waiting.
|
|
48
|
+
if (typeof IntersectionObserver === 'undefined')
|
|
49
|
+
return;
|
|
50
|
+
/**
|
|
51
|
+
* A box that does not exist cannot come into view, so it is never hidden.
|
|
52
|
+
*
|
|
53
|
+
* `display: contents` is the case, and it cost a section its words: FeatureScroll's text column
|
|
54
|
+
* gives up its box on a phone so the picture can sit between the title and the line under it,
|
|
55
|
+
* an observer watching it was never going to report anything, and the copy stayed waiting for
|
|
56
|
+
* an arrival that could not happen. Permanently invisible content is the worst failure this
|
|
57
|
+
* hook has available to it, so it checks.
|
|
58
|
+
*
|
|
59
|
+
* A caller that wants motion for such a group watches something inside it that does have a box
|
|
60
|
+
* and marks the group — the ref and the attribute need not sit on the same element. This is the
|
|
61
|
+
* floor under that, not a substitute for it.
|
|
62
|
+
*/
|
|
63
|
+
if (element.getClientRects().length === 0)
|
|
64
|
+
return;
|
|
65
|
+
setRevealed(false);
|
|
66
|
+
/**
|
|
67
|
+
* The arrival is put off to the next frame, and that one frame is the whole of it.
|
|
68
|
+
*
|
|
69
|
+
* A transition needs a painted starting state. For a block already on screen the observer's
|
|
70
|
+
* first callback is delivered in the rendering steps of the frame the block was laid out in —
|
|
71
|
+
* so flipping there applies the landed state before the waiting one has ever been painted, and
|
|
72
|
+
* the browser has nothing to move between. It goes straight to the end, which looks exactly
|
|
73
|
+
* like no animation at all.
|
|
74
|
+
*
|
|
75
|
+
* That was the bug, and it hid itself well: a block below the fold worked, because the
|
|
76
|
+
* observer does not fire until a reader scrolls and by then the waiting state has been on
|
|
77
|
+
* screen for many frames. Everything a reader sees first — the heading, the first block, any
|
|
78
|
+
* band shown on its own — did not.
|
|
79
|
+
*/
|
|
80
|
+
let frame = 0;
|
|
81
|
+
const watching = new IntersectionObserver((entries) => {
|
|
82
|
+
if (!entries.some((entry) => entry.isIntersecting))
|
|
83
|
+
return;
|
|
84
|
+
watching.disconnect();
|
|
85
|
+
frame = window.requestAnimationFrame(() => {
|
|
86
|
+
frame = 0;
|
|
87
|
+
setRevealed(true);
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
// A tenth of the block, so a band a screen tall is not held back until a reader has scrolled
|
|
91
|
+
// most of it into view, and a short one is not brought in by a sliver at the edge.
|
|
92
|
+
{ threshold: 0.1 });
|
|
93
|
+
watching.observe(element);
|
|
94
|
+
return () => {
|
|
95
|
+
watching.disconnect();
|
|
96
|
+
if (frame !== 0)
|
|
97
|
+
window.cancelAnimationFrame(frame);
|
|
98
|
+
};
|
|
99
|
+
}, []);
|
|
100
|
+
return [
|
|
101
|
+
(element) => {
|
|
102
|
+
held.current = element;
|
|
103
|
+
},
|
|
104
|
+
revealed,
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* One part's place in the order its block arrives in.
|
|
109
|
+
*
|
|
110
|
+
* Spread onto each part that moves: `<p {...arriving(1)} …>`. Two spellings of one number, because
|
|
111
|
+
* CSS needs both and can do neither job with the other's — an attribute is what a selector can
|
|
112
|
+
* match, and a custom property is what `calc()` can multiply into a delay.
|
|
113
|
+
*
|
|
114
|
+
* The number is the reading order rather than the DOM order, and they are not always the same: a
|
|
115
|
+
* hero's picture sits before its words in the markup, because a band paints its ground before it
|
|
116
|
+
* sets type on it, and a reader still meets the claim first.
|
|
117
|
+
*/
|
|
118
|
+
export function arriving(at) {
|
|
119
|
+
return { 'data-reveal-at': at, style: { '--dds-reveal-at': at } };
|
|
120
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type FocusEvent, type MouseEvent, type PointerEvent } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* One block rotating between a few things in place — which one is in view, and every way a reader
|
|
4
|
+
* moves it, holds it or stops it.
|
|
5
|
+
*
|
|
6
|
+
* Shared because two blocks rotate, CtaBannerSlider and TestimonialSlider, and a carousel is the
|
|
7
|
+
* kind of thing that drifts: one stops on a press and the other does not, one swallows the click a swipe
|
|
8
|
+
* ends in and the other follows the link. The rules are stated once here and each block spreads
|
|
9
|
+
* what this hands back onto its own parts.
|
|
10
|
+
*
|
|
11
|
+
* The clock is not here. PaginationDots holds the timer and the reduced-motion stillness, and this
|
|
12
|
+
* tells it when to wait — so there is one clock per block, and it is the one a reader can see.
|
|
13
|
+
*
|
|
14
|
+
* What it hands back:
|
|
15
|
+
* - `root`, the ref for the block's own element, which the swipe threshold and the reading
|
|
16
|
+
* direction are read off;
|
|
17
|
+
* - `region`, spread on that element: the carousel's role description and the hold and stop
|
|
18
|
+
* handlers;
|
|
19
|
+
* - `track`, spread on the element holding the items: the swipe and what is announced;
|
|
20
|
+
* - `item(at)`, spread on each item: its group role, its "2 / 3" name and its inert state;
|
|
21
|
+
* - `dots`, spread on PaginationDots alongside the block's own label.
|
|
22
|
+
*
|
|
23
|
+
* Fewer than two items is a set with nothing to move to, drawn still rather than broken: every
|
|
24
|
+
* attribute that says "carousel" is left off and the dots are the block's to omit.
|
|
25
|
+
*/
|
|
26
|
+
export declare function useRotation(count: number, autoplay: boolean): {
|
|
27
|
+
current: number;
|
|
28
|
+
rotating: boolean;
|
|
29
|
+
root: import("react").RefObject<HTMLElement | null>;
|
|
30
|
+
region: {
|
|
31
|
+
'aria-roledescription': string | undefined;
|
|
32
|
+
onPointerEnter: (event: PointerEvent<HTMLElement>) => void;
|
|
33
|
+
onPointerLeave: (event: PointerEvent<HTMLElement>) => void;
|
|
34
|
+
onFocus: () => void;
|
|
35
|
+
onPointerDownCapture: (event: PointerEvent<HTMLElement>) => void;
|
|
36
|
+
onBlur: (event: FocusEvent<HTMLElement>) => void;
|
|
37
|
+
};
|
|
38
|
+
track: {
|
|
39
|
+
'aria-live': "polite" | "off";
|
|
40
|
+
onPointerDown: (event: PointerEvent<HTMLElement>) => void;
|
|
41
|
+
onPointerUp: (event: PointerEvent<HTMLElement>) => void;
|
|
42
|
+
onPointerCancel: () => void;
|
|
43
|
+
onPointerLeave: () => void;
|
|
44
|
+
onClickCapture: (event: MouseEvent<HTMLElement>) => void;
|
|
45
|
+
};
|
|
46
|
+
/** Whether an item is out of view: inert, hidden, and waiting rather than arrived. */
|
|
47
|
+
away: (at: number) => boolean;
|
|
48
|
+
item: (at: number) => {
|
|
49
|
+
role: string | undefined;
|
|
50
|
+
'aria-roledescription': string | undefined;
|
|
51
|
+
'aria-label': string | undefined;
|
|
52
|
+
'aria-hidden': true | undefined;
|
|
53
|
+
inert: true | undefined;
|
|
54
|
+
};
|
|
55
|
+
dots: {
|
|
56
|
+
page: number;
|
|
57
|
+
totalPages: number;
|
|
58
|
+
onPageChange: (page: number) => void;
|
|
59
|
+
autoplay: boolean;
|
|
60
|
+
paused: boolean;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* How soon after a swipe a click still belongs to it. The browser sends the click a swipe ends
|
|
5
|
+
* with straight after the release; anything later is a press of its own.
|
|
6
|
+
*/
|
|
7
|
+
const SWIPE_CLICK_MS = 300;
|
|
8
|
+
/** A token read off the block's own element, so it is the value the page actually resolved. */
|
|
9
|
+
function tokenOn(element, name) {
|
|
10
|
+
return element === null ? '' : getComputedStyle(element).getPropertyValue(name);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* One block rotating between a few things in place — which one is in view, and every way a reader
|
|
14
|
+
* moves it, holds it or stops it.
|
|
15
|
+
*
|
|
16
|
+
* Shared because two blocks rotate, CtaBannerSlider and TestimonialSlider, and a carousel is the
|
|
17
|
+
* kind of thing that drifts: one stops on a press and the other does not, one swallows the click a swipe
|
|
18
|
+
* ends in and the other follows the link. The rules are stated once here and each block spreads
|
|
19
|
+
* what this hands back onto its own parts.
|
|
20
|
+
*
|
|
21
|
+
* The clock is not here. PaginationDots holds the timer and the reduced-motion stillness, and this
|
|
22
|
+
* tells it when to wait — so there is one clock per block, and it is the one a reader can see.
|
|
23
|
+
*
|
|
24
|
+
* What it hands back:
|
|
25
|
+
* - `root`, the ref for the block's own element, which the swipe threshold and the reading
|
|
26
|
+
* direction are read off;
|
|
27
|
+
* - `region`, spread on that element: the carousel's role description and the hold and stop
|
|
28
|
+
* handlers;
|
|
29
|
+
* - `track`, spread on the element holding the items: the swipe and what is announced;
|
|
30
|
+
* - `item(at)`, spread on each item: its group role, its "2 / 3" name and its inert state;
|
|
31
|
+
* - `dots`, spread on PaginationDots alongside the block's own label.
|
|
32
|
+
*
|
|
33
|
+
* Fewer than two items is a set with nothing to move to, drawn still rather than broken: every
|
|
34
|
+
* attribute that says "carousel" is left off and the dots are the block's to omit.
|
|
35
|
+
*/
|
|
36
|
+
export function useRotation(count, autoplay) {
|
|
37
|
+
const rotating = count > 1;
|
|
38
|
+
const root = useRef(null);
|
|
39
|
+
const [index, setIndex] = useState(0);
|
|
40
|
+
/*
|
|
41
|
+
A pointer over the block or focus inside it, which holds the rotation only for as long as it
|
|
42
|
+
lasts. The rotation itself is PaginationDots' — the timer and the reduced-motion stillness — so
|
|
43
|
+
there is one clock, and this only tells it to wait while the reader is on the item.
|
|
44
|
+
*/
|
|
45
|
+
const [held, setHeld] = useState(false);
|
|
46
|
+
/*
|
|
47
|
+
Stopped for good once the reader presses anything in the block — an item, its action, a dot —
|
|
48
|
+
or swipes it. The WAI carousel pattern's rule: a reader who has touched the carousel is
|
|
49
|
+
reading it, and moving it on under them takes that back. It is also the way this offers a
|
|
50
|
+
stop without a control for one. A hold lets go; this does not.
|
|
51
|
+
*/
|
|
52
|
+
const [stopped, setStopped] = useState(false);
|
|
53
|
+
// A count that shrinks under the index would leave the track pointing past its end.
|
|
54
|
+
const current = count === 0 ? 0 : index % count;
|
|
55
|
+
const go = (to) => setIndex(((to % count) + count) % count);
|
|
56
|
+
// A move the reader made — a swipe — moves the set and stops it.
|
|
57
|
+
const step = (to) => {
|
|
58
|
+
setStopped(true);
|
|
59
|
+
go(to);
|
|
60
|
+
};
|
|
61
|
+
/*
|
|
62
|
+
A swipe is a pointer that travelled. How far counts as travelling is the smallest target the
|
|
63
|
+
package names, size.target.min: a move shorter than something a reader could aim at is a
|
|
64
|
+
press that wobbled, not a gesture.
|
|
65
|
+
*/
|
|
66
|
+
const from = useRef(null);
|
|
67
|
+
/*
|
|
68
|
+
When a gesture last travelled far enough to be a swipe, spent on the click the browser sends
|
|
69
|
+
after it. Without it a drag that starts and ends on an item's call to action both moves the set
|
|
70
|
+
and follows the link.
|
|
71
|
+
|
|
72
|
+
A time rather than a flag, because the click does not always come: a touch that travelled
|
|
73
|
+
usually ends with no click at all. A flag left standing then swallowed the next click that
|
|
74
|
+
arrived without a press on the track — Enter on the call to action, or a screen reader's
|
|
75
|
+
activation — and the link went nowhere. Only a click that follows the swipe closely is its own.
|
|
76
|
+
*/
|
|
77
|
+
const swipedAt = useRef(null);
|
|
78
|
+
const onPointerDown = (event) => {
|
|
79
|
+
// The primary pointer and, for a mouse, the primary button: a right-button drag or a second
|
|
80
|
+
// finger is not a swipe.
|
|
81
|
+
if (!event.isPrimary || (event.pointerType === 'mouse' && event.button !== 0))
|
|
82
|
+
return;
|
|
83
|
+
from.current = event.clientX;
|
|
84
|
+
swipedAt.current = null;
|
|
85
|
+
};
|
|
86
|
+
// The browser took the gesture — a vertical scroll, a system swipe — or the pointer left the
|
|
87
|
+
// track before it was let go, so there is no swipe to read. Left standing, the start of an
|
|
88
|
+
// abandoned drag would be measured against the next release on the track.
|
|
89
|
+
const onPointerCancel = () => {
|
|
90
|
+
from.current = null;
|
|
91
|
+
};
|
|
92
|
+
const onPointerUp = (event) => {
|
|
93
|
+
const start = from.current;
|
|
94
|
+
from.current = null;
|
|
95
|
+
if (start === null || !rotating || !event.isPrimary)
|
|
96
|
+
return;
|
|
97
|
+
const threshold = Number.parseFloat(tokenOn(root.current, '--size-target-min'));
|
|
98
|
+
const travel = event.clientX - start;
|
|
99
|
+
if (!Number.isFinite(threshold) || Math.abs(travel) < threshold)
|
|
100
|
+
return;
|
|
101
|
+
// Leftward travel brings the next item in from the end the reader is reading towards; in a
|
|
102
|
+
// right-to-left page that end is the left one, so the direction follows the page.
|
|
103
|
+
const rtl = root.current !== null && getComputedStyle(root.current).direction === 'rtl';
|
|
104
|
+
swipedAt.current = event.timeStamp;
|
|
105
|
+
step(current + ((travel < 0) !== rtl ? 1 : -1));
|
|
106
|
+
};
|
|
107
|
+
const onClickCapture = (event) => {
|
|
108
|
+
const at = swipedAt.current;
|
|
109
|
+
swipedAt.current = null;
|
|
110
|
+
if (at === null || event.timeStamp - at > SWIPE_CLICK_MS)
|
|
111
|
+
return;
|
|
112
|
+
event.preventDefault();
|
|
113
|
+
event.stopPropagation();
|
|
114
|
+
};
|
|
115
|
+
// Held while focus is anywhere inside, released only when it leaves the block altogether.
|
|
116
|
+
const onBlur = (event) => {
|
|
117
|
+
if (!event.currentTarget.contains(event.relatedTarget))
|
|
118
|
+
setHeld(false);
|
|
119
|
+
};
|
|
120
|
+
return {
|
|
121
|
+
current,
|
|
122
|
+
rotating,
|
|
123
|
+
root,
|
|
124
|
+
region: {
|
|
125
|
+
'aria-roledescription': rotating ? 'carousel' : undefined,
|
|
126
|
+
onPointerEnter: (event) => {
|
|
127
|
+
if (event.pointerType === 'mouse')
|
|
128
|
+
setHeld(true);
|
|
129
|
+
},
|
|
130
|
+
onPointerLeave: (event) => {
|
|
131
|
+
if (event.pointerType === 'mouse')
|
|
132
|
+
setHeld(false);
|
|
133
|
+
},
|
|
134
|
+
onFocus: () => setHeld(true),
|
|
135
|
+
// Any primary press in the block stops the rotation; the press itself still does what it does.
|
|
136
|
+
onPointerDownCapture: (event) => {
|
|
137
|
+
if (event.isPrimary && (event.pointerType !== 'mouse' || event.button === 0))
|
|
138
|
+
setStopped(true);
|
|
139
|
+
},
|
|
140
|
+
onBlur,
|
|
141
|
+
},
|
|
142
|
+
track: {
|
|
143
|
+
/*
|
|
144
|
+
An item that changes on its own is not announced — a reader would be talked over every few
|
|
145
|
+
seconds. One the reader moved to is, because they asked for it: whenever autoplay is off,
|
|
146
|
+
and whenever it is held — which it always is while focus is on a dot, the only way a
|
|
147
|
+
keyboard or screen reader user moves it.
|
|
148
|
+
*/
|
|
149
|
+
'aria-live': (rotating && (!autoplay || held || stopped) ? 'polite' : 'off'),
|
|
150
|
+
onPointerDown,
|
|
151
|
+
onPointerUp,
|
|
152
|
+
onPointerCancel,
|
|
153
|
+
onPointerLeave: onPointerCancel,
|
|
154
|
+
onClickCapture,
|
|
155
|
+
},
|
|
156
|
+
/** Whether an item is out of view: inert, hidden, and waiting rather than arrived. */
|
|
157
|
+
away: (at) => rotating && at !== current,
|
|
158
|
+
item: (at) => {
|
|
159
|
+
const away = rotating && at !== current;
|
|
160
|
+
return {
|
|
161
|
+
role: rotating ? 'group' : undefined,
|
|
162
|
+
'aria-roledescription': rotating ? 'slide' : undefined,
|
|
163
|
+
'aria-label': rotating ? `${at + 1} / ${count}` : undefined,
|
|
164
|
+
'aria-hidden': away || undefined,
|
|
165
|
+
inert: away || undefined,
|
|
166
|
+
};
|
|
167
|
+
},
|
|
168
|
+
dots: {
|
|
169
|
+
page: current + 1,
|
|
170
|
+
totalPages: count,
|
|
171
|
+
onPageChange: (page) => go(page - 1),
|
|
172
|
+
autoplay,
|
|
173
|
+
paused: held || stopped,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import './Accordion.css';
|
|
2
|
+
import { type AccordionProps } from './Accordion.types.js';
|
|
3
|
+
export type { AccordionProps };
|
|
4
|
+
/**
|
|
5
|
+
* A set of rows, and the two things about them that belong to the set rather than to any row:
|
|
6
|
+
* how deep they sit in the outline, and which one is open.
|
|
7
|
+
*
|
|
8
|
+
* The level is pushed down rather than set per row because every row of one accordion is at one
|
|
9
|
+
* depth by definition — a set whose rows disagreed would describe a hierarchy the design does
|
|
10
|
+
* not have, and a reader navigating by heading would be told it exists.
|
|
11
|
+
*
|
|
12
|
+
* One open row is not a setting here, which is where this parts company with Product's. A
|
|
13
|
+
* marketing page is read by scrolling, and a set that could hold every row open is the long page
|
|
14
|
+
* the accordion was put there to shorten. So the set always holds the answer: a row cannot see
|
|
15
|
+
* its siblings, and left to themselves they would all open.
|
|
16
|
+
*
|
|
17
|
+
* Seeded from whichever row arrived open, so a set that opens showing one keeps it. A row's own
|
|
18
|
+
* handler still runs — it is how a page learns what was pressed, and the only way it could.
|
|
19
|
+
*/
|
|
20
|
+
export declare function Accordion({ headingLevel, children, ...rest }: AccordionProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Children, cloneElement, isValidElement, useState } from 'react';
|
|
3
|
+
import './Accordion.css';
|
|
4
|
+
import { accordionDefaults, accordionParts } from './Accordion.types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Both handlers, the row's own first.
|
|
7
|
+
*
|
|
8
|
+
* `cloneElement` replaces rather than merges, so a row already reporting its own state would
|
|
9
|
+
* silently stop — and that is the handler a page is most likely to have written, since it is
|
|
10
|
+
* how they learn which row was opened.
|
|
11
|
+
*/
|
|
12
|
+
function chain(theirs, ours) {
|
|
13
|
+
if (theirs === undefined)
|
|
14
|
+
return ours;
|
|
15
|
+
return (expanded) => {
|
|
16
|
+
theirs(expanded);
|
|
17
|
+
ours(expanded);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A set of rows, and the two things about them that belong to the set rather than to any row:
|
|
22
|
+
* how deep they sit in the outline, and which one is open.
|
|
23
|
+
*
|
|
24
|
+
* The level is pushed down rather than set per row because every row of one accordion is at one
|
|
25
|
+
* depth by definition — a set whose rows disagreed would describe a hierarchy the design does
|
|
26
|
+
* not have, and a reader navigating by heading would be told it exists.
|
|
27
|
+
*
|
|
28
|
+
* One open row is not a setting here, which is where this parts company with Product's. A
|
|
29
|
+
* marketing page is read by scrolling, and a set that could hold every row open is the long page
|
|
30
|
+
* the accordion was put there to shorten. So the set always holds the answer: a row cannot see
|
|
31
|
+
* its siblings, and left to themselves they would all open.
|
|
32
|
+
*
|
|
33
|
+
* Seeded from whichever row arrived open, so a set that opens showing one keeps it. A row's own
|
|
34
|
+
* handler still runs — it is how a page learns what was pressed, and the only way it could.
|
|
35
|
+
*/
|
|
36
|
+
export function Accordion({ headingLevel = accordionDefaults.headingLevel, children, ...rest }) {
|
|
37
|
+
const rows = Children.toArray(children).filter(isValidElement);
|
|
38
|
+
const [open, setOpen] = useState(() => {
|
|
39
|
+
const first = rows.findIndex((row) => row.props.expanded === true);
|
|
40
|
+
return first === -1 ? null : first;
|
|
41
|
+
});
|
|
42
|
+
return (_jsx("div", { className: accordionParts.root, ...rest, children: rows.map((row, index) => {
|
|
43
|
+
const props = row.props;
|
|
44
|
+
/*
|
|
45
|
+
* A DOM element is left exactly as it arrived.
|
|
46
|
+
*
|
|
47
|
+
* `cloneElement` hands its second argument to whatever it is given, and an
|
|
48
|
+
* intrinsic element does not know what `expanded` is — React warns three times
|
|
49
|
+
* and puts `headinglevel="3"` in the markup. `allowedChildren` already says this
|
|
50
|
+
* is misuse, but a contract is not a runtime and the reader who did it by
|
|
51
|
+
* accident deserves a stray div rather than a console full of noise.
|
|
52
|
+
*
|
|
53
|
+
* Keyed on the type being a string, which is what an intrinsic element's is, so a
|
|
54
|
+
* page's own wrapper component still receives the set's answer and can forward
|
|
55
|
+
* it. Comparing against AccordionItem itself would refuse those too, and a
|
|
56
|
+
* component that renders a row is a reasonable thing for a page to have written.
|
|
57
|
+
*/
|
|
58
|
+
if (typeof row.type === 'string')
|
|
59
|
+
return row;
|
|
60
|
+
return cloneElement(row, {
|
|
61
|
+
key: row.key ?? index,
|
|
62
|
+
headingLevel,
|
|
63
|
+
expanded: open === index,
|
|
64
|
+
onExpandedChange: chain(props.onExpandedChange, (expanded) => {
|
|
65
|
+
setOpen(expanded ? index : null);
|
|
66
|
+
}),
|
|
67
|
+
});
|
|
68
|
+
}) }));
|
|
69
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export interface AccordionOwnProps {
|
|
3
|
+
/**
|
|
4
|
+
* `2` — The rows are the page's own sections, sitting directly under its title — a page that is nothing but questions is the case
|
|
5
|
+
* `3` — The default. The set sits under a section heading of its own, which is where an accordion usually is
|
|
6
|
+
* `4` — The set is inside a subsection that already carries a heading above it
|
|
7
|
+
*/
|
|
8
|
+
headingLevel?: '2' | '3' | '4';
|
|
9
|
+
/** Allowed: AccordionItem */
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
export type AccordionProps = AccordionOwnProps & Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'headingLevel'>;
|
|
13
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
14
|
+
export declare const accordionParts: {
|
|
15
|
+
readonly root: "dds-accordion";
|
|
16
|
+
};
|
|
17
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
18
|
+
export declare const accordionDefaults: {
|
|
19
|
+
readonly headingLevel: "3";
|
|
20
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// GENERATED from accordion.contract.json. Do not edit.
|
|
2
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
3
|
+
export const accordionParts = {
|
|
4
|
+
root: 'dds-accordion',
|
|
5
|
+
};
|
|
6
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
7
|
+
export const accordionDefaults = { headingLevel: '3' };
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/* GENERATED from accordionitem.contract.json. Do not edit. */
|
|
2
|
+
|
|
3
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem {
|
|
4
|
+
border-block-start-style: solid;
|
|
5
|
+
box-sizing: border-box;
|
|
6
|
+
display: block;
|
|
7
|
+
border-color: var(--color-border-subtle);
|
|
8
|
+
border-width: var(--border-width-default);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem .dds-accordionitem__heading {
|
|
12
|
+
display: block;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem .dds-accordionitem__trigger {
|
|
16
|
+
transition-property: color, outline-color, outline-width;
|
|
17
|
+
align-items: center;
|
|
18
|
+
appearance: none;
|
|
19
|
+
background: none;
|
|
20
|
+
border-style: none;
|
|
21
|
+
box-sizing: border-box;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
display: flex;
|
|
24
|
+
inline-size: 100%;
|
|
25
|
+
outline-style: solid;
|
|
26
|
+
padding-inline: 0;
|
|
27
|
+
text-align: start;
|
|
28
|
+
color: var(--color-fg-default);
|
|
29
|
+
gap: var(--space-gap-md);
|
|
30
|
+
min-block-size: var(--size-target-min);
|
|
31
|
+
min-inline-size: var(--size-target-min);
|
|
32
|
+
outline-width: var(--border-width-none);
|
|
33
|
+
padding-block: var(--space-inset-md);
|
|
34
|
+
transition-duration: var(--motion-duration-fast);
|
|
35
|
+
transition-timing-function: var(--motion-easing-standard);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem .dds-accordionitem__title {
|
|
39
|
+
text-align: start;
|
|
40
|
+
font-family: var(--font-label-md-family);
|
|
41
|
+
font-size: var(--font-label-md-size);
|
|
42
|
+
font-weight: var(--font-label-md-weight);
|
|
43
|
+
letter-spacing: var(--font-label-md-letter-spacing);
|
|
44
|
+
line-height: var(--font-label-md-line-height);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem .dds-accordionitem__marker {
|
|
48
|
+
transition-property: rotate;
|
|
49
|
+
color: var(--color-fg-muted);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem .dds-accordionitem__panel {
|
|
53
|
+
overflow: hidden;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem .dds-accordionitem__content {
|
|
57
|
+
overflow: hidden;
|
|
58
|
+
font-family: var(--font-body-md-family);
|
|
59
|
+
font-size: var(--font-body-md-size);
|
|
60
|
+
line-height: var(--font-body-md-line-height);
|
|
61
|
+
padding-block-end: var(--space-inset-md);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem[data-expanded="false"] .dds-accordionitem__panel {
|
|
65
|
+
display: none;
|
|
66
|
+
transition-duration: var(--motion-duration-normal);
|
|
67
|
+
transition-timing-function: var(--motion-easing-exit);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem[data-expanded="true"] .dds-accordionitem__panel {
|
|
71
|
+
display: grid;
|
|
72
|
+
transition-duration: var(--motion-duration-slow);
|
|
73
|
+
transition-timing-function: var(--motion-easing-enter);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem .dds-accordionitem__trigger:hover:where(:not(:disabled)) {
|
|
77
|
+
color: var(--color-fg-muted);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem .dds-accordionitem__trigger:focus-visible {
|
|
81
|
+
outline-color: var(--color-border-focus);
|
|
82
|
+
outline-width: var(--border-width-focus);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem[data-expanded="false"] .dds-accordionitem__marker {
|
|
86
|
+
transition-duration: var(--motion-duration-normal);
|
|
87
|
+
transition-timing-function: var(--motion-easing-exit);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem[data-expanded="true"] .dds-accordionitem__marker {
|
|
91
|
+
transition-duration: var(--motion-duration-slow);
|
|
92
|
+
transition-timing-function: var(--motion-easing-enter);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@media (prefers-reduced-motion: reduce) {
|
|
96
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem,
|
|
97
|
+
:where([data-dds-context="marketing"]) .dds-accordionitem * { transition: none !important; }
|
|
98
|
+
}
|
|
99
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import './AccordionItem.css';
|
|
2
|
+
import './accordion-item-impl.css';
|
|
3
|
+
import { type AccordionItemProps } from './AccordionItem.types.js';
|
|
4
|
+
export type { AccordionItemProps };
|
|
5
|
+
/**
|
|
6
|
+
* One row: a heading that stays, and the detail under it that does not.
|
|
7
|
+
*
|
|
8
|
+
* It works alone and it works in a set, and the difference is only who holds the
|
|
9
|
+
* answer. Alone, the row keeps its own — `expanded` is read once as the state it
|
|
10
|
+
* opens in, and every press after that is its own business. Inside an Accordion
|
|
11
|
+
* the set injects `expanded` on every render, so the row stops deciding and
|
|
12
|
+
* starts reporting: a row cannot see its siblings, which is exactly the fact that
|
|
13
|
+
* makes one-at-a-time impossible to arrange from here.
|
|
14
|
+
*
|
|
15
|
+
* `useState` seeded from the prop rather than derived from it. A row that read
|
|
16
|
+
* the prop every render would be uncontrolled and unable to move; one that
|
|
17
|
+
* ignored it could not be opened by the set. Holding both and preferring the
|
|
18
|
+
* injected value is what lets the same component be either — and it is why
|
|
19
|
+
* `expanded` declares no default: absent has to stay distinguishable from false,
|
|
20
|
+
* because absent is the only way a row knows nobody is controlling it.
|
|
21
|
+
*
|
|
22
|
+
* The heading is a `<div role="heading">` with the level as a number, not an
|
|
23
|
+
* `<h3>`. The level is a prop, and an element cannot be picked at runtime without
|
|
24
|
+
* six branches saying the same thing — the role and `aria-level` say it once.
|
|
25
|
+
*
|
|
26
|
+
* `aria-expanded` sits on the button rather than the panel, because that is what
|
|
27
|
+
* the reader is about to press: the state belongs to the thing they act on, not
|
|
28
|
+
* to a region they cannot see until it opens.
|
|
29
|
+
*
|
|
30
|
+
* The panel is a named region, and the name is the heading that opened it. A
|
|
31
|
+
* `region` is a landmark, and an unnamed one is worse than none — it fills a
|
|
32
|
+
* screen reader's landmark list with anonymous entries nobody can choose between.
|
|
33
|
+
* Naming it is what makes it worth having: a reader who has found the question
|
|
34
|
+
* can jump straight to the answer. Product declines the role instead, which is
|
|
35
|
+
* also correct and is the other way to avoid the same fault; it can afford to
|
|
36
|
+
* because its rows open independently and a set of them would proliferate
|
|
37
|
+
* landmarks, where only one of these is ever open.
|
|
38
|
+
*
|
|
39
|
+
* The panel stays mounted when shut. Unmounting it would take its height with it,
|
|
40
|
+
* so there would be nothing to move between — and it would take the words out of
|
|
41
|
+
* the browser's own find-on-page, which is how a reader looks for an answer they
|
|
42
|
+
* half remember.
|
|
43
|
+
*/
|
|
44
|
+
export declare function AccordionItem({ expanded, onExpandedChange, title, headingLevel, children, ...rest }: AccordionItemProps): import("react").JSX.Element;
|