@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,359 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useId, useRef, useState } from 'react';
|
|
4
|
+
import { ButtonIcon } from '../button-icon/ButtonIcon.js';
|
|
5
|
+
import { XmarkSolidIcon } from '@deriv-com/quill-icons-web';
|
|
6
|
+
import './BottomSheet.css';
|
|
7
|
+
import './bottom-sheet-impl.css';
|
|
8
|
+
import { given } from '../../given.js';
|
|
9
|
+
import { visuallyHidden } from '../../visually-hidden.js';
|
|
10
|
+
import { bottomSheetDefaults, bottomSheetParts } from './BottomSheet.types.js';
|
|
11
|
+
/**
|
|
12
|
+
* How far down the sheet has to be pulled before letting go dismisses it.
|
|
13
|
+
*
|
|
14
|
+
* A share of the sheet's own height rather than a distance, because the same distance means
|
|
15
|
+
* different things on different sheets. A fixed one was the first answer here, and the same
|
|
16
|
+
* number came to two fifths of a short sheet and a twelfth of a full-screen one — a heave on one
|
|
17
|
+
* and a twitch on the other. A third is far enough that resting a finger on the handle does not
|
|
18
|
+
* throw the task away, on either.
|
|
19
|
+
*
|
|
20
|
+
* Floored, because a third of a very short sheet is a few pixels and a sheet should not come away
|
|
21
|
+
* in your hand. Neither number is a design token: nothing here is drawn, and no brand or mode has
|
|
22
|
+
* a different idea of how far a flick is.
|
|
23
|
+
*/
|
|
24
|
+
const DRAG_FRACTION = 0.3;
|
|
25
|
+
const DRAG_FLOOR = 32;
|
|
26
|
+
/** Everything focus can rest on, for holding it inside the sheet while the sheet is open. */
|
|
27
|
+
/**
|
|
28
|
+
* Things that answer a pointer themselves, and so are never the start of a sheet drag.
|
|
29
|
+
*
|
|
30
|
+
* A Slider takes its own pointerdown and moves a thumb with it; without this the same gesture
|
|
31
|
+
* bubbled to the sheet and pulled that too, so setting a value halfway threw the task away. The
|
|
32
|
+
* rest are here for the smaller version of the same thing: a press that slides off a button is a
|
|
33
|
+
* press the reader changed their mind about, not a dismissal.
|
|
34
|
+
*
|
|
35
|
+
* Matched on what an element is rather than on whether it has a handler, there being no way to
|
|
36
|
+
* ask. A consumer's own draggable widget is not covered and cannot be — the escape hatch for that
|
|
37
|
+
* is to stop the event before it reaches the sheet.
|
|
38
|
+
*/
|
|
39
|
+
const OWNS_ITS_GESTURE = 'button, a, input, select, textarea, [role="slider"], [draggable="true"]';
|
|
40
|
+
const FOCUSABLE = [
|
|
41
|
+
'a[href]',
|
|
42
|
+
'button:not([disabled])',
|
|
43
|
+
'input:not([disabled])',
|
|
44
|
+
'select:not([disabled])',
|
|
45
|
+
'textarea:not([disabled])',
|
|
46
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
47
|
+
].join(',');
|
|
48
|
+
/**
|
|
49
|
+
* A panel that rises from the bottom edge to hold one focused task.
|
|
50
|
+
*
|
|
51
|
+
* Mounted whether it is open or not, which is the decision everything else here follows from.
|
|
52
|
+
* A sheet that mounts on opening has no previous state to animate out of, so the reveal would
|
|
53
|
+
* be a jump — and the contract's `open` axis is what the stylesheet varies, which it cannot do
|
|
54
|
+
* to an element that is not there. What keeps a shut sheet out of the reading order and out of
|
|
55
|
+
* the tab order is `visibility: hidden` in the generated CSS rather than anything written here:
|
|
56
|
+
* an `aria-hidden` or an `inert` set from this file would say the same thing twice, and the two
|
|
57
|
+
* would disagree the first time one of them changed.
|
|
58
|
+
*
|
|
59
|
+
* It owns none of its own openness. Every way out — the close button, the scrim, Escape, the
|
|
60
|
+
* drag — reports through `onOpenChange` and changes nothing, so a page that does not answer that
|
|
61
|
+
* callback has a sheet that cannot be closed. That is the same shape every other controlled
|
|
62
|
+
* component in this package takes, and the reason is the same: two things holding one fact
|
|
63
|
+
* disagree eventually, and the consumer is the one that has to win.
|
|
64
|
+
*/
|
|
65
|
+
export function BottomSheet(props) {
|
|
66
|
+
const { open = bottomSheetDefaults.open, height = bottomSheetDefaults.height, title, showTitle = bottomSheetDefaults.showTitle, description, back, action, showClose = bottomSheetDefaults.showClose, showHandle = bottomSheetDefaults.showHandle, onOpenChange, children, id, ...rest } = props;
|
|
67
|
+
const fallbackId = useId();
|
|
68
|
+
const rootId = id ?? fallbackId;
|
|
69
|
+
const titleId = `${rootId}-title`;
|
|
70
|
+
const descriptionId = `${rootId}-description`;
|
|
71
|
+
/**
|
|
72
|
+
* The box holding the panel and the controls above it, which is the sheet as far as everything
|
|
73
|
+
* here is concerned: what carries the dialog role, what focus is held inside, and what moves.
|
|
74
|
+
*
|
|
75
|
+
* The panel is not any of those things, and that is the point of the box. The controls sit
|
|
76
|
+
* outside the panel because the panel clips, and an element outside the thing that declares
|
|
77
|
+
* `aria-modal` is outside the task — a close button announced by nothing and reached by no Tab.
|
|
78
|
+
* Trapping on the box puts them back inside the one root that both answers to.
|
|
79
|
+
*/
|
|
80
|
+
const frame = useRef(null);
|
|
81
|
+
/**
|
|
82
|
+
* Where focus was before the sheet took it, so it can be given back.
|
|
83
|
+
*
|
|
84
|
+
* A ref rather than state: nothing renders from it, and writing it would otherwise re-render
|
|
85
|
+
* the sheet at the exact moment it is being opened. Returned on close rather than on unmount,
|
|
86
|
+
* because this component does not unmount — see the note above.
|
|
87
|
+
*/
|
|
88
|
+
const returnFocusTo = useRef(null);
|
|
89
|
+
/**
|
|
90
|
+
* Whether the sheet was open on the last render, so focus moves on a change and not on mount.
|
|
91
|
+
*
|
|
92
|
+
* Initialised to the first render's own value, which is what keeps a sheet that mounts *already*
|
|
93
|
+
* open from taking focus. That is a specimen — a documentation page, the preview's gallery — and
|
|
94
|
+
* a specimen that grabs focus on mount is worse than it sounds: the browser scrolls whatever
|
|
95
|
+
* gains focus into view, so a page of open sheets opens scrolled to the last of them.
|
|
96
|
+
*
|
|
97
|
+
* The same guard DropdownMenu carries, arrived at from the same failure. Nothing is lost for a
|
|
98
|
+
* consumer: a sheet is mounted shut and then opened, which is a change and still moves focus.
|
|
99
|
+
*/
|
|
100
|
+
const wasOpen = useRef(open);
|
|
101
|
+
/** The content, so a gesture beginning in it can be told from one beginning on the chrome. */
|
|
102
|
+
const body = useRef(null);
|
|
103
|
+
/** What a gesture in progress needs to be judged by, or null while there is none. */
|
|
104
|
+
const drag = useRef(null);
|
|
105
|
+
/**
|
|
106
|
+
* How far the sheet has been pulled, as a share of its own height, or null when nothing is
|
|
107
|
+
* pulling it.
|
|
108
|
+
*
|
|
109
|
+
* A percentage rather than a distance, and the same one the stylesheet uses: a shut sheet is
|
|
110
|
+
* translated `0 100%`, so a finger halfway down is `0 50%` and the gesture and the animation
|
|
111
|
+
* are speaking the same unit. Nothing has to convert, and there is no pixel measure written
|
|
112
|
+
* into this file for a component that may not carry one.
|
|
113
|
+
*/
|
|
114
|
+
const [pulled, setPulled] = useState(null);
|
|
115
|
+
const describes = given(description);
|
|
116
|
+
/**
|
|
117
|
+
* What each end of the line above the sheet has in it, or nothing.
|
|
118
|
+
*
|
|
119
|
+
* Both ends used to arrive together whether or not either had anything to hold, because each
|
|
120
|
+
* was reserving the other's width and an empty slot was what kept a centred title on the
|
|
121
|
+
* sheet's centre line. Ranged against the frame rather than sitting in the row, an end holds
|
|
122
|
+
* nothing open — so an empty one is a positioned box with no content and no reason to exist.
|
|
123
|
+
*
|
|
124
|
+
* Neither end decides whether the sheet can be left. A press outside it and Escape always work:
|
|
125
|
+
* they are what a reader tries when a sheet offers them nothing else, and a surface that answers
|
|
126
|
+
* neither is a trap rather than a decision.
|
|
127
|
+
*/
|
|
128
|
+
const goesBack = back !== undefined && back !== null;
|
|
129
|
+
const acts = action !== undefined && action !== null;
|
|
130
|
+
/** The trailing end holds the exit, whatever else is in it — so either fills it. */
|
|
131
|
+
const trails = showClose || acts;
|
|
132
|
+
/**
|
|
133
|
+
* Focus into the sheet on opening, and back to the opener on closing.
|
|
134
|
+
*
|
|
135
|
+
* The first focusable thing inside, or the sheet itself where there is nothing — a dialog with
|
|
136
|
+
* focus left outside it is one a screen-reader user is told about and cannot reach, and a
|
|
137
|
+
* keyboard user tabs into the page behind the scrim rather than into the task.
|
|
138
|
+
*
|
|
139
|
+
* Keyed on `open` alone. The effect must not run when the content inside changes, or a sheet
|
|
140
|
+
* whose body re-renders steals focus back to its first control while somebody is typing in
|
|
141
|
+
* its third.
|
|
142
|
+
*/
|
|
143
|
+
useEffect(() => {
|
|
144
|
+
const changed = wasOpen.current !== open;
|
|
145
|
+
wasOpen.current = open;
|
|
146
|
+
if (!changed)
|
|
147
|
+
return;
|
|
148
|
+
if (open) {
|
|
149
|
+
const previous = document.activeElement;
|
|
150
|
+
returnFocusTo.current = previous instanceof HTMLElement ? previous : null;
|
|
151
|
+
const first = frame.current?.querySelector(FOCUSABLE);
|
|
152
|
+
if (first !== null && first !== undefined)
|
|
153
|
+
first.focus();
|
|
154
|
+
else
|
|
155
|
+
frame.current?.focus();
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
// Only what this sheet took. Without the check, a sheet that has never been open returns
|
|
159
|
+
// focus to whatever the page was doing on first render and steals it on mount.
|
|
160
|
+
const opener = returnFocusTo.current;
|
|
161
|
+
returnFocusTo.current = null;
|
|
162
|
+
opener?.focus();
|
|
163
|
+
}, [open]);
|
|
164
|
+
/**
|
|
165
|
+
* Escape, listened for on the document rather than on the sheet.
|
|
166
|
+
*
|
|
167
|
+
* Focus is inside the sheet while it is open, so a handler on the surface would catch it —
|
|
168
|
+
* until something inside opens a menu of its own, or the reader clicks the scrim and focus
|
|
169
|
+
* lands on the body. The document hears it either way, and the listener is bound only while
|
|
170
|
+
* the sheet is open, so a page holding six sheets is not running six handlers on every key.
|
|
171
|
+
*/
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
if (!open)
|
|
174
|
+
return;
|
|
175
|
+
const onKeyDown = (event) => {
|
|
176
|
+
if (event.key !== 'Escape')
|
|
177
|
+
return;
|
|
178
|
+
// Not if something inside already answered it. A DropdownMenu open inside the sheet calls
|
|
179
|
+
// preventDefault on its own Escape, and without this check one press shuts the list and
|
|
180
|
+
// throws the sheet away with it — the reader loses the task for correcting the answer.
|
|
181
|
+
if (event.defaultPrevented)
|
|
182
|
+
return;
|
|
183
|
+
onOpenChange(false, 'escape');
|
|
184
|
+
};
|
|
185
|
+
document.addEventListener('keydown', onKeyDown);
|
|
186
|
+
return () => document.removeEventListener('keydown', onKeyDown);
|
|
187
|
+
});
|
|
188
|
+
/**
|
|
189
|
+
* Tab held inside the sheet, wrapping at both ends.
|
|
190
|
+
*
|
|
191
|
+
* Read at the moment of the keystroke rather than kept in a list, because what is focusable
|
|
192
|
+
* inside a task changes as the task is done — a disabled submit becomes enabled, a row is
|
|
193
|
+
* added. A list captured on open would send the reader to an element that is no longer there.
|
|
194
|
+
*/
|
|
195
|
+
const onKeyDown = (event) => {
|
|
196
|
+
if (event.key !== 'Tab' || !open)
|
|
197
|
+
return;
|
|
198
|
+
const found = frame.current?.querySelectorAll(FOCUSABLE);
|
|
199
|
+
const focusable = found === undefined ? [] : Array.from(found);
|
|
200
|
+
if (focusable.length === 0) {
|
|
201
|
+
// Nothing to move to, so the only correct thing is to stay. Letting it through would put
|
|
202
|
+
// focus on the page behind a scrim that refuses the pointer.
|
|
203
|
+
event.preventDefault();
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const first = focusable[0];
|
|
207
|
+
const last = focusable[focusable.length - 1];
|
|
208
|
+
const on = document.activeElement;
|
|
209
|
+
if (event.shiftKey && (on === first || on === frame.current)) {
|
|
210
|
+
event.preventDefault();
|
|
211
|
+
last.focus();
|
|
212
|
+
}
|
|
213
|
+
else if (!event.shiftKey && on === last) {
|
|
214
|
+
event.preventDefault();
|
|
215
|
+
first.focus();
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* A drag on the sheet's chrome, which the sheet follows.
|
|
220
|
+
*
|
|
221
|
+
* Not on the content, and that line is the browser's rather than a preference. The content
|
|
222
|
+
* scrolls, and a touch gesture beginning in a scroll container belongs to the scroller: the
|
|
223
|
+
* browser claims every downward swipe that starts there, cancels ours one move in, and does it
|
|
224
|
+
* whether or not there is anything to scroll. The whole surface did answer a pull once — but
|
|
225
|
+
* only ever with a mouse, because on a phone the content half of that rule could not run at all.
|
|
226
|
+
*
|
|
227
|
+
* So it is one sentence on every input: pull the header, scroll the content. A mouse can no
|
|
228
|
+
* longer dismiss from a place a finger cannot, which is worth more than the gesture it costs.
|
|
229
|
+
* The alternative is a component whose behaviour has to be described per device, and a reader
|
|
230
|
+
* who learns the sheet on a phone and is wrong about it on a laptop.
|
|
231
|
+
*
|
|
232
|
+
* It still waits for the first move rather than claiming the gesture on contact, because upward
|
|
233
|
+
* is never a pull — there is nothing above the sheet to bring it into. Decided once and not
|
|
234
|
+
* revisited, so a finger that wanders back up mid-pull does not hand the sheet away.
|
|
235
|
+
*/
|
|
236
|
+
const onPointerDown = (event) => {
|
|
237
|
+
const target = event.target;
|
|
238
|
+
if (target.closest?.(OWNS_ITS_GESTURE) !== null)
|
|
239
|
+
return;
|
|
240
|
+
// The content's gestures are the scroller's. Asked of the element, not of `scrollTop`: a list
|
|
241
|
+
// with nothing to scroll is still a scroll container, and the browser treats it as one.
|
|
242
|
+
if (body.current?.contains(target) === true)
|
|
243
|
+
return;
|
|
244
|
+
drag.current = {
|
|
245
|
+
from: event.clientY,
|
|
246
|
+
// Measured once. The sheet cannot change height mid-gesture, and asking for it on every
|
|
247
|
+
// frame would be a layout read in the one place that has to keep up with a finger.
|
|
248
|
+
height: frame.current?.offsetHeight ?? 0,
|
|
249
|
+
pulling: false,
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* How far down this pointer is from where it started, floored at nothing.
|
|
254
|
+
*
|
|
255
|
+
* The start is passed in rather than read off the ref, and that is not a style choice: the
|
|
256
|
+
* release handler clears the ref before it works out what the gesture meant, so a version of
|
|
257
|
+
* this that reached for `drag.current` measured from the top of the window instead. Every pull
|
|
258
|
+
* cleared the threshold, and a sheet nudged a few pixels dismissed itself.
|
|
259
|
+
*/
|
|
260
|
+
const travelled = (event, from) => Math.max(0, event.clientY - from);
|
|
261
|
+
const onPointerMove = (event) => {
|
|
262
|
+
const held = drag.current;
|
|
263
|
+
if (held === null)
|
|
264
|
+
return;
|
|
265
|
+
if (!held.pulling) {
|
|
266
|
+
// Still deciding. Anything but a downward pull hands the gesture back for good.
|
|
267
|
+
if (event.clientY <= held.from) {
|
|
268
|
+
drag.current = null;
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
held.pulling = true;
|
|
272
|
+
/*
|
|
273
|
+
Captured here rather than on contact, which matters more than it looks. Capturing on
|
|
274
|
+
pointerdown takes every gesture the sheet is touched by — including a scroll — and the
|
|
275
|
+
list underneath then never moves. Claimed only once this is known to be a drag.
|
|
276
|
+
|
|
277
|
+
It is also what makes the release land: without it the handler ran only when the finger
|
|
278
|
+
happened to still be over the sheet, so a firm flick past the sheet's own edge released
|
|
279
|
+
onto the page behind and did nothing. Measured, before and after.
|
|
280
|
+
*/
|
|
281
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
282
|
+
}
|
|
283
|
+
const share = held.height === 0 ? 0 : (travelled(event, held.from) / held.height) * 100;
|
|
284
|
+
setPulled(Math.min(100, share));
|
|
285
|
+
};
|
|
286
|
+
const onPointerUp = (event) => {
|
|
287
|
+
const held = drag.current;
|
|
288
|
+
drag.current = null;
|
|
289
|
+
event.currentTarget.releasePointerCapture?.(event.pointerId);
|
|
290
|
+
// Let go of the offset either way: from here the stylesheet owns where the sheet is, and it
|
|
291
|
+
// carries it the rest of the way down or back to rest, from wherever the finger left it.
|
|
292
|
+
setPulled(null);
|
|
293
|
+
// A gesture that never became a drag is a press, or a scroll. Neither dismisses.
|
|
294
|
+
if (held === null || !held.pulling)
|
|
295
|
+
return;
|
|
296
|
+
const far = Math.max(held.height * DRAG_FRACTION, DRAG_FLOOR);
|
|
297
|
+
if (travelled(event, held.from) >= far)
|
|
298
|
+
onOpenChange(false, 'drag');
|
|
299
|
+
};
|
|
300
|
+
/** A gesture the system took over — a back-swipe, a notification pulled down. Not a dismissal. */
|
|
301
|
+
const onPointerCancel = () => {
|
|
302
|
+
drag.current = null;
|
|
303
|
+
setPulled(null);
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* The pull, which the sheet always answers.
|
|
307
|
+
*
|
|
308
|
+
* Not conditioned on the handle being drawn, for the reason the scrim and Escape are not: a
|
|
309
|
+
* reader pulls a sheet down because it is a sheet, and whether a bar was painted at the top is
|
|
310
|
+
* not something they consulted first. `showHandle` draws the affordance; the way out is the
|
|
311
|
+
* sheet's either way.
|
|
312
|
+
*/
|
|
313
|
+
const dragging = { onPointerDown, onPointerMove, onPointerUp, onPointerCancel };
|
|
314
|
+
/**
|
|
315
|
+
* The way out, in one place whatever the sheet holds: above the panel, at the trailing corner,
|
|
316
|
+
* and last in its end so nothing is drawn outside it.
|
|
317
|
+
*
|
|
318
|
+
* It used to move with the title — opposite a centred one, gathered with the action once the
|
|
319
|
+
* title started at the leading edge — because both were competing for the same row. Out of that
|
|
320
|
+
* row there is nothing to move around, and the corner is the one place worth pinning it to: an
|
|
321
|
+
* exit that shifts to make room for whatever else the screen adds is an exit somewhere else on
|
|
322
|
+
* every sheet, and a reader who has learnt one is wrong about the next.
|
|
323
|
+
*/
|
|
324
|
+
const close = (_jsx(ButtonIcon
|
|
325
|
+
/* No ring. The sheet is already a surface that has said what it is — a panel over a
|
|
326
|
+
scrim — so an edge around its exit would be the loudest thing in the header. This is
|
|
327
|
+
the variant ButtonIcon gained for it; Pagination wanted the same thing and had to draw
|
|
328
|
+
its own button, which is the gap this closes. */
|
|
329
|
+
, {
|
|
330
|
+
/* No ring. The sheet is already a surface that has said what it is — a panel over a
|
|
331
|
+
scrim — so an edge around its exit would be the loudest thing in the header. This is
|
|
332
|
+
the variant ButtonIcon gained for it; Pagination wanted the same thing and had to draw
|
|
333
|
+
its own button, which is the gap this closes. */
|
|
334
|
+
variant: "plain",
|
|
335
|
+
/* The compact step. A sheet's exit sits on the row that names it, beside a title at the
|
|
336
|
+
smallest heading step — at the default size the button stood taller than the words it
|
|
337
|
+
sat next to and read as the loudest thing in the header. */
|
|
338
|
+
size: "sm", label: `Close ${title}`,
|
|
339
|
+
/* The bare glyph, not wrapped in an Icon. Which step belongs in a button of this size is
|
|
340
|
+
ButtonIcon's own rule and it applies it by cloning — an Icon around it puts `dds-icon`
|
|
341
|
+
on the svg at Icon's own default instead, which is a step and a half larger and beats
|
|
342
|
+
the binding. That is how the exit came to stand at twenty-four pixels beside a sixteen
|
|
343
|
+
pixel back arrow handed in bare. */
|
|
344
|
+
icon: _jsx(XmarkSolidIcon, {}), onClick: () => onOpenChange(false, 'close-button') }));
|
|
345
|
+
return (_jsxs("div", { className: bottomSheetParts.root, "data-open": String(open), "data-height": height, onKeyDown: onKeyDown, ...rest, children: [_jsx("div", { className: bottomSheetParts.scrim, onClick: () => onOpenChange(false, 'scrim') }), _jsx("div", { ref: frame, className: bottomSheetParts.frame, role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, "aria-describedby": describes ? descriptionId : undefined,
|
|
346
|
+
/* So focus has somewhere to land in a sheet holding nothing focusable — a task that is
|
|
347
|
+
text and a single action still has to be readable from the top. Not a tab stop: -1
|
|
348
|
+
takes focus from script and never from Tab, so it costs the reader nothing. */
|
|
349
|
+
tabIndex: -1,
|
|
350
|
+
/* Where the finger has it, and no easing while the finger is there: the generated rule
|
|
351
|
+
carries a 300ms ease-out, which applied to every move would leave the sheet trailing
|
|
352
|
+
a third of a second behind the hand. The duration is the token that means "does not
|
|
353
|
+
animate at all" rather than a number written here, and it is gone the moment the
|
|
354
|
+
gesture is — so the stylesheet resumes owning both the position and the reduced-motion
|
|
355
|
+
guard that comes with it. */
|
|
356
|
+
style: pulled === null
|
|
357
|
+
? undefined
|
|
358
|
+
: { translate: `0 ${pulled}%`, transitionDuration: 'var(--motion-duration-instant)' }, children: _jsxs("div", { className: bottomSheetParts.surface, ...dragging, children: [showHandle ? (_jsx("div", { className: bottomSheetParts.handle, "aria-hidden": "true" })) : null, _jsxs("header", { className: bottomSheetParts.header, children: [goesBack ? _jsx("div", { className: bottomSheetParts.leading, children: back }) : null, _jsxs("div", { className: bottomSheetParts.heading, children: [_jsx("h2", { className: bottomSheetParts.title, id: titleId, style: showTitle ? undefined : visuallyHidden, children: title }), describes ? (_jsx("p", { className: bottomSheetParts.description, id: descriptionId, children: description })) : null] }), trails ? (_jsxs("div", { className: bottomSheetParts.trailing, children: [action, showClose ? close : null] })) : null] }), _jsx("div", { ref: body, className: bottomSheetParts.body, children: children })] }) })] }));
|
|
359
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export interface BottomSheetOwnProps {
|
|
3
|
+
/** The sheet is showing. The consumer owns this outright — the sheet never sets it, and asks to be closed through onOpenChange instead.
|
|
4
|
+
|
|
5
|
+
Flipping it is the whole animation. The layer fades from opacity.hidden and the sheet scales up from motion.scale.enter about its own bottom edge, over motion.duration.slow on motion.easing.enter, so it reads as rising from the screen's edge rather than appearing over the middle of it. Shutting is not animated: transition-duration is motion.duration.instant while closed, because the reader has already asked to be somewhere else. Do not write a transition of your own — the stylesheet declares transition-property from what this axis changes, and a second declaration would both override that list and escape the prefers-reduced-motion guard generated with it. */
|
|
6
|
+
open?: boolean;
|
|
7
|
+
/** Always. It is the sheet's accessible name as well as its heading, so a sheet without one is announced as a dialog and nothing else. A noun phrase naming the task, in sentence case: "Filter results", not "Would you like to filter these results?" */
|
|
8
|
+
title: string;
|
|
9
|
+
/** The default, and almost always right. Turn it off where the content immediately under the header already names the task and a second visible name would say it twice — a picker whose first row is the heading, a sheet that is one photograph. The title is still rendered and still announced either way; only its pixels go. */
|
|
10
|
+
showTitle?: boolean;
|
|
11
|
+
/** The title needs qualifying — what the task applies to, or what it still needs before it can be done. "Date and both airports required", or the account a transfer is coming from. It sits directly under the title and is announced with it. */
|
|
12
|
+
description?: string;
|
|
13
|
+
/** The sheet is a step rather than the whole task — one of a sequence, or a panel reached from another panel — and the reader needs the step before it. One control, icon-only, at the leading edge above the sheet, opposite the way out.
|
|
14
|
+
|
|
15
|
+
It is your ButtonIcon, so the glyph and the variant are yours; secondary is what sits level with the close button. The size is not — see below.
|
|
16
|
+
|
|
17
|
+
It does not close the sheet and is not reported through onOpenChange: going back is the consumer's own navigation between whatever the sheet is showing, and a sheet that treated it as a way out would throw the task away on the one press that meant "not this bit". */
|
|
18
|
+
back?: ReactNode;
|
|
19
|
+
/** The screen needs one more control above the sheet — a confirm for a form the sheet is collecting, help for a task that needs explaining. One control, icon-only, at the trailing end beside the way out and immediately before it: the close button keeps the corner, and this sits inside it.
|
|
20
|
+
|
|
21
|
+
It is your ButtonIcon, so its variant is yours: primary for a confirm that has to carry weight, destructive for one that removes something, secondary to sit level with the close. The size is not — see below.
|
|
22
|
+
|
|
23
|
+
It asks for `showClose`, and the reason is the corner: an action alone at the trailing end sits exactly where a reader reaches for the exit, and is pressed by somebody who meant to leave. Where the sheet is a step in a sequence, the control that goes back belongs at the other end — that is `back`, not this. */
|
|
24
|
+
action?: ReactNode;
|
|
25
|
+
/** Always. The sheet does not close itself, so this is the only way out — write the first argument straight back to `open`. Named the way DropdownMenu names its own, because a reader who has wired one controlled disclosure in this package should not have to learn a second word for the same job.
|
|
26
|
+
|
|
27
|
+
The second argument is which of the four ways out the reader took, for a page that treats an abandoned task differently from a finished one. It is only ever called with false today — a sheet is opened by whatever opens it, never by itself — and the boolean is first anyway, so the shape does not have to change if that ever stops being true. */
|
|
28
|
+
onOpenChange: (open: boolean, reason: 'close-button' | 'scrim' | 'escape' | 'drag') => void;
|
|
29
|
+
/** Allowed: any content */
|
|
30
|
+
children: ReactNode;
|
|
31
|
+
}
|
|
32
|
+
export type BottomSheetProps = BottomSheetOwnProps & Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'open' | 'height' | 'title' | 'showTitle' | 'description' | 'showClose' | 'back' | 'action' | 'showHandle' | 'onOpenChange'> & ({
|
|
33
|
+
showHandle?: boolean;
|
|
34
|
+
showClose?: false;
|
|
35
|
+
} | {
|
|
36
|
+
showHandle: false;
|
|
37
|
+
showClose?: boolean;
|
|
38
|
+
}) & ({
|
|
39
|
+
height?: 'hug' | 'tall' | 'full';
|
|
40
|
+
showClose: true;
|
|
41
|
+
} | {
|
|
42
|
+
height?: Exclude<'hug' | 'tall' | 'full', 'full'>;
|
|
43
|
+
showClose?: boolean;
|
|
44
|
+
});
|
|
45
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
46
|
+
export declare const bottomSheetParts: {
|
|
47
|
+
readonly root: "dds-bottomsheet";
|
|
48
|
+
readonly scrim: "dds-bottomsheet__scrim";
|
|
49
|
+
readonly frame: "dds-bottomsheet__frame";
|
|
50
|
+
readonly surface: "dds-bottomsheet__surface";
|
|
51
|
+
readonly handle: "dds-bottomsheet__handle";
|
|
52
|
+
readonly header: "dds-bottomsheet__header";
|
|
53
|
+
readonly leading: "dds-bottomsheet__leading";
|
|
54
|
+
readonly heading: "dds-bottomsheet__heading";
|
|
55
|
+
readonly title: "dds-bottomsheet__title";
|
|
56
|
+
readonly trailing: "dds-bottomsheet__trailing";
|
|
57
|
+
readonly description: "dds-bottomsheet__description";
|
|
58
|
+
readonly body: "dds-bottomsheet__body";
|
|
59
|
+
};
|
|
60
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
61
|
+
export declare const bottomSheetDefaults: {
|
|
62
|
+
readonly open: false;
|
|
63
|
+
readonly height: "hug";
|
|
64
|
+
readonly showTitle: true;
|
|
65
|
+
readonly showClose: false;
|
|
66
|
+
readonly showHandle: true;
|
|
67
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// GENERATED from bottom-sheet.contract.json. Do not edit.
|
|
2
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
3
|
+
export const bottomSheetParts = {
|
|
4
|
+
root: 'dds-bottomsheet',
|
|
5
|
+
scrim: 'dds-bottomsheet__scrim',
|
|
6
|
+
frame: 'dds-bottomsheet__frame',
|
|
7
|
+
surface: 'dds-bottomsheet__surface',
|
|
8
|
+
handle: 'dds-bottomsheet__handle',
|
|
9
|
+
header: 'dds-bottomsheet__header',
|
|
10
|
+
leading: 'dds-bottomsheet__leading',
|
|
11
|
+
heading: 'dds-bottomsheet__heading',
|
|
12
|
+
title: 'dds-bottomsheet__title',
|
|
13
|
+
trailing: 'dds-bottomsheet__trailing',
|
|
14
|
+
description: 'dds-bottomsheet__description',
|
|
15
|
+
body: 'dds-bottomsheet__body',
|
|
16
|
+
};
|
|
17
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
18
|
+
export const bottomSheetDefaults = { open: false, height: 'hug', showTitle: true, showClose: false, showHandle: true };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Scoped to this package, like the generated sheet beside it.
|
|
3
|
+
*
|
|
4
|
+
* `:where([data-dds-context="marketing"])` confines these rules without contributing
|
|
5
|
+
* specificity, so every override below still ties or beats exactly what it did
|
|
6
|
+
* before — several here are written a class deeper than they look in order to
|
|
7
|
+
* match generated CSS, and a scope that carried weight would break all of them.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Above the page this interrupts, which a contract cannot hold either: an integer with no unit.
|
|
12
|
+
*
|
|
13
|
+
* The root is `position: fixed; inset: 0` and carried no z-index at all, on the assumption that a
|
|
14
|
+
* sheet is the last thing in the document and painting order alone puts it over the page. Two
|
|
15
|
+
* components already documented that assumption failing rather than fixing it: DatePicker and
|
|
16
|
+
* DateRangePicker mount a sheet in the middle of a form, and both had to mark their own root and
|
|
17
|
+
* lift it from their own stylesheet, because a fixed box at `z-index: auto` loses to any
|
|
18
|
+
* positioned element after it — the next field down painted straight through the sheet.
|
|
19
|
+
*
|
|
20
|
+
* That workaround was the sheet's bug being paid for by its callers, and every future caller
|
|
21
|
+
* would have paid it again. `layer.overlay` puts the order where the thing being ordered is.
|
|
22
|
+
* The two pickers still lift their fields — a host that has to sit at the overlay's level so the
|
|
23
|
+
* overlay inside it is not trapped below what follows — but they now read the same role rather
|
|
24
|
+
* than a literal, so the two can no longer drift apart.
|
|
25
|
+
*
|
|
26
|
+
* The role for anything that interrupts the reader, which today is this alone: nothing should outrank
|
|
27
|
+
* another by an accident of stylesheet order. Whatever reports from elsewhere would sit above it at
|
|
28
|
+
* `layer.notification`.
|
|
29
|
+
*/
|
|
30
|
+
:where([data-dds-context="marketing"]) .dds-bottomsheet {
|
|
31
|
+
z-index: var(--layer-overlay);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/*
|
|
35
|
+
* The title centres when there is a way back at the leading end, and ranges to the start when
|
|
36
|
+
* there is not.
|
|
37
|
+
*
|
|
38
|
+
* Which is a relationship rather than a prop, and so cannot be a binding: what decides it is
|
|
39
|
+
* whether the header holds a leading end, and `back` is a slot the page fills rather than a value
|
|
40
|
+
* the contract can switch on. `:has()` asks the question directly — the same kind of positional
|
|
41
|
+
* fact the head of a table asks about its second row.
|
|
42
|
+
*
|
|
43
|
+
* It is worth the asymmetry because the two rows are different objects. With a control at each
|
|
44
|
+
* end the header reads as a bar between them, and a title ranged to one edge sits against a button
|
|
45
|
+
* rather than in the row. With nothing at the leading end there is no bar to be between: a centred
|
|
46
|
+
* title would float with the whole left of the row empty behind it, which reads as a mistake.
|
|
47
|
+
*
|
|
48
|
+
* It centres in the space the ends leave rather than on the sheet, which is off true by half the
|
|
49
|
+
* difference between them. That is the honest limit of doing this in flow, and it is small where
|
|
50
|
+
* it applies — a row with a way back has a control at both ends, and the two are close to the same
|
|
51
|
+
* width. It was not small when the alignment was a prop that could be asked for on a row with one
|
|
52
|
+
* end, which is why that prop is gone.
|
|
53
|
+
*/
|
|
54
|
+
:where([data-dds-context="marketing"]) .dds-bottomsheet__header:has(.dds-bottomsheet__leading) .dds-bottomsheet__title,
|
|
55
|
+
:where([data-dds-context="marketing"]) .dds-bottomsheet__header:has(.dds-bottomsheet__leading) .dds-bottomsheet__description {
|
|
56
|
+
text-align: center;
|
|
57
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* GENERATED from breadcrumb.contract.json. Do not edit. */
|
|
2
|
+
|
|
3
|
+
:where([data-dds-context="marketing"]) .dds-breadcrumb .dds-breadcrumb__list {
|
|
4
|
+
align-items: center;
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-wrap: wrap;
|
|
7
|
+
list-style: none;
|
|
8
|
+
margin: 0;
|
|
9
|
+
padding: 0;
|
|
10
|
+
gap: var(--space-gap-xs);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
:where([data-dds-context="marketing"]) .dds-breadcrumb .dds-breadcrumb__separator {
|
|
14
|
+
align-items: center;
|
|
15
|
+
display: flex;
|
|
16
|
+
flex: none;
|
|
17
|
+
color: var(--color-fg-tertiary);
|
|
18
|
+
}
|
|
19
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import './Breadcrumb.css';
|
|
2
|
+
import { type BreadcrumbProps } from './Breadcrumb.types.js';
|
|
3
|
+
export type { BreadcrumbProps };
|
|
4
|
+
/**
|
|
5
|
+
* A `<nav>` holding an ordered list of the levels above the current page.
|
|
6
|
+
*
|
|
7
|
+
* The separators are this component's, not the item's. An item cannot know
|
|
8
|
+
* whether it is first, so a chevron it rendered for itself would either need its
|
|
9
|
+
* position passed in or a `li + li` selector, which the generated stylesheet
|
|
10
|
+
* has no way to express. Interleaving here keeps both problems out of
|
|
11
|
+
* BreadcrumbItem and out of the CSS.
|
|
12
|
+
*
|
|
13
|
+
* Each separator is its own `<li>` because an `<ol>` may contain nothing else,
|
|
14
|
+
* and it is `aria-hidden` because it is punctuation.
|
|
15
|
+
*/
|
|
16
|
+
export declare function Breadcrumb({ label, children, ...rest }: BreadcrumbProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Children, Fragment } from 'react';
|
|
3
|
+
import { ChevronRightRegularIcon } from '@deriv-com/quill-icons-web';
|
|
4
|
+
import { Icon } from '../icon/Icon.js';
|
|
5
|
+
import './Breadcrumb.css';
|
|
6
|
+
import { breadcrumbDefaults, breadcrumbParts } from './Breadcrumb.types.js';
|
|
7
|
+
/**
|
|
8
|
+
* A `<nav>` holding an ordered list of the levels above the current page.
|
|
9
|
+
*
|
|
10
|
+
* The separators are this component's, not the item's. An item cannot know
|
|
11
|
+
* whether it is first, so a chevron it rendered for itself would either need its
|
|
12
|
+
* position passed in or a `li + li` selector, which the generated stylesheet
|
|
13
|
+
* has no way to express. Interleaving here keeps both problems out of
|
|
14
|
+
* BreadcrumbItem and out of the CSS.
|
|
15
|
+
*
|
|
16
|
+
* Each separator is its own `<li>` because an `<ol>` may contain nothing else,
|
|
17
|
+
* and it is `aria-hidden` because it is punctuation.
|
|
18
|
+
*/
|
|
19
|
+
export function Breadcrumb({ label = breadcrumbDefaults.label, children, ...rest }) {
|
|
20
|
+
const levels = Children.toArray(children);
|
|
21
|
+
return (_jsx("nav", { className: breadcrumbParts.root, "aria-label": label, ...rest, children: _jsx("ol", { className: breadcrumbParts.list, children: levels.map((level, index) => (_jsxs(Fragment, { children: [index > 0 && (_jsx("li", { className: breadcrumbParts.separator, "aria-hidden": "true", children: _jsx(Icon, { size: "xs", children: _jsx(ChevronRightRegularIcon, {}) }) })), level] }, index))) }) }));
|
|
22
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export interface BreadcrumbOwnProps {
|
|
3
|
+
/** Always, and the default is almost always right. It names the landmark rather than the page — a screen reader user listing the landmarks on a page hears this, and "Breadcrumb" is the word they are listening for */
|
|
4
|
+
label?: string;
|
|
5
|
+
/** Allowed: BreadcrumbItem */
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
export type BreadcrumbProps = BreadcrumbOwnProps & Omit<HTMLAttributes<HTMLElement>, 'className' | 'label'>;
|
|
9
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
10
|
+
export declare const breadcrumbParts: {
|
|
11
|
+
readonly root: "dds-breadcrumb";
|
|
12
|
+
readonly list: "dds-breadcrumb__list";
|
|
13
|
+
readonly separator: "dds-breadcrumb__separator";
|
|
14
|
+
};
|
|
15
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
16
|
+
export declare const breadcrumbDefaults: {
|
|
17
|
+
readonly label: "Breadcrumb";
|
|
18
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// GENERATED from breadcrumb.contract.json. Do not edit.
|
|
2
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
3
|
+
export const breadcrumbParts = {
|
|
4
|
+
root: 'dds-breadcrumb',
|
|
5
|
+
list: 'dds-breadcrumb__list',
|
|
6
|
+
separator: 'dds-breadcrumb__separator',
|
|
7
|
+
};
|
|
8
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
9
|
+
export const breadcrumbDefaults = { label: 'Breadcrumb' };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* GENERATED from breadcrumbitem.contract.json. Do not edit. */
|
|
2
|
+
|
|
3
|
+
:where([data-dds-context="marketing"]) .dds-breadcrumbitem {
|
|
4
|
+
align-items: center;
|
|
5
|
+
display: flex;
|
|
6
|
+
font-family: var(--font-label-sm-family);
|
|
7
|
+
font-size: var(--font-label-sm-size);
|
|
8
|
+
letter-spacing: var(--font-label-sm-letter-spacing);
|
|
9
|
+
line-height: var(--font-label-sm-line-height);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
:where([data-dds-context="marketing"]) .dds-breadcrumbitem .dds-breadcrumbitem__link {
|
|
13
|
+
outline-style: solid;
|
|
14
|
+
text-decoration-line: none;
|
|
15
|
+
border-radius: var(--radius-subtle);
|
|
16
|
+
color: var(--color-fg-muted);
|
|
17
|
+
font-weight: var(--font-body-sm-weight);
|
|
18
|
+
outline-width: var(--border-width-none);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
:where([data-dds-context="marketing"]) .dds-breadcrumbitem .dds-breadcrumbitem__current {
|
|
22
|
+
color: var(--color-fg-default);
|
|
23
|
+
font-weight: var(--font-label-sm-weight);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
:where([data-dds-context="marketing"]) .dds-breadcrumbitem .dds-breadcrumbitem__link:hover {
|
|
27
|
+
color: var(--color-fg-default);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
:where([data-dds-context="marketing"]) .dds-breadcrumbitem .dds-breadcrumbitem__link:focus-visible {
|
|
31
|
+
outline-color: var(--color-border-focus);
|
|
32
|
+
outline-width: var(--border-width-focus);
|
|
33
|
+
}
|
|
34
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import './BreadcrumbItem.css';
|
|
2
|
+
import { type BreadcrumbItemProps } from './BreadcrumbItem.types.js';
|
|
3
|
+
export type { BreadcrumbItemProps };
|
|
4
|
+
/**
|
|
5
|
+
* One level of a trail: a link back to it, or the current page as plain text.
|
|
6
|
+
*
|
|
7
|
+
* `current` wins over `href`. The two together ask for a link from the page to
|
|
8
|
+
* itself — a tab stop that goes nowhere — so the component declines.
|
|
9
|
+
*
|
|
10
|
+
* `aria-current="page"` is what identifies the current level to a screen reader.
|
|
11
|
+
*/
|
|
12
|
+
export declare function BreadcrumbItem({ label, href, current, ...rest }: BreadcrumbItemProps): import("react").JSX.Element;
|