@deriv-com/dds-marketing 0.2.0 → 1.0.1
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 +9 -1
- package/.llm/components/accordionitem.md +9 -1
- package/.llm/components/aspectratio.md +9 -1
- package/.llm/components/badge.md +9 -1
- package/.llm/components/bottomsheet.md +9 -1
- package/.llm/components/breadcrumb.md +9 -1
- package/.llm/components/breadcrumbitem.md +9 -1
- package/.llm/components/button.md +55 -27
- package/.llm/components/buttonicon.md +16 -8
- package/.llm/components/card.md +16 -2
- package/.llm/components/cardbody.md +29 -3
- package/.llm/components/cardbutton.md +16 -2
- package/.llm/components/checkbox.md +9 -1
- package/.llm/components/ctabanner.md +186 -0
- package/.llm/components/ctabannerslider.md +204 -0
- package/.llm/components/divider.md +9 -1
- package/.llm/components/dropdownmenu.md +15 -7
- 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 +9 -1
- package/.llm/components/footer.md +9 -1
- package/.llm/components/footergroup.md +9 -1
- package/.llm/components/grid.md +9 -1
- package/.llm/components/icon.md +21 -3
- package/.llm/components/landinghero.md +254 -0
- package/.llm/components/link.md +13 -5
- package/.llm/components/logocolumns.md +235 -0
- package/.llm/components/logorows.md +212 -0
- package/.llm/components/menuitem.md +9 -1
- package/.llm/components/navbar.md +80 -16
- package/.llm/components/navbaritem.md +10 -2
- package/.llm/components/navbarmenu.md +9 -1
- package/.llm/components/navbarmenugroup.md +9 -1
- package/.llm/components/navbarpanel.md +10 -2
- package/.llm/components/navbarswitcher.md +10 -2
- package/.llm/components/navbarswitcheroption.md +9 -1
- package/.llm/components/option.md +9 -1
- package/.llm/components/pageheader.md +231 -0
- package/.llm/components/pagination.md +27 -90
- package/.llm/components/paginationdots.md +215 -0
- package/.llm/components/producthero.md +248 -0
- package/.llm/components/removablechip.md +9 -1
- package/.llm/components/row.md +9 -1
- package/.llm/components/scroller.md +9 -1
- package/.llm/components/searchinput.md +9 -1
- package/.llm/components/segmentedcontrol.md +9 -1
- package/.llm/components/segmentedcontrolitem.md +9 -1
- package/.llm/components/select.md +9 -1
- package/.llm/components/selectchip.md +57 -16
- package/.llm/components/spinner.md +9 -1
- package/.llm/components/stack.md +9 -1
- package/.llm/components/statusdot.md +9 -1
- package/.llm/components/subdomainnavbar.md +9 -1
- package/.llm/components/tab.md +11 -3
- package/.llm/components/table.md +9 -1
- package/.llm/components/tablebody.md +9 -1
- package/.llm/components/tablecell.md +9 -1
- package/.llm/components/tablehead.md +9 -1
- package/.llm/components/tableheadercell.md +9 -1
- package/.llm/components/tablerow.md +9 -1
- package/.llm/components/tablist.md +9 -1
- package/.llm/components/testimonialrow.md +235 -0
- package/.llm/components/testimonialslider.md +254 -0
- package/.llm/components/textarea.md +9 -1
- package/.llm/components/textinput.md +9 -1
- package/.llm/components/tooltip.md +9 -1
- package/.llm/components/typography.md +9 -1
- package/.llm/digest/button.md +11 -6
- package/.llm/digest/buttonicon.md +2 -2
- package/.llm/digest/card.md +1 -0
- package/.llm/digest/cardbody.md +3 -1
- package/.llm/digest/cardbutton.md +1 -0
- package/.llm/digest/ctabanner.md +44 -0
- package/.llm/digest/ctabannerslider.md +45 -0
- package/.llm/digest/dropdownmenu.md +1 -1
- 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/landinghero.md +53 -0
- package/.llm/digest/logocolumns.md +55 -0
- package/.llm/digest/logorows.md +48 -0
- package/.llm/digest/navbar.md +18 -3
- package/.llm/digest/pageheader.md +49 -0
- package/.llm/digest/pagination.md +6 -17
- package/.llm/digest/paginationdots.md +43 -0
- package/.llm/digest/producthero.md +53 -0
- package/.llm/digest/selectchip.md +6 -1
- package/.llm/digest/testimonialrow.md +51 -0
- package/.llm/digest/testimonialslider.md +51 -0
- package/.llm/index.md +24 -3
- package/.llm/rules.md +43 -9
- package/.llm/tokens.md +56 -12
- package/AGENTS.md +32 -8
- package/README.md +41 -21
- 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-item/AccordionItem.css +6 -5
- package/dist/components/core/bottom-sheet/BottomSheet.css +1 -1
- package/dist/components/core/button/Button.css +63 -16
- package/dist/components/core/button/Button.d.ts +14 -12
- package/dist/components/core/button/Button.js +43 -14
- package/dist/components/core/button/Button.types.d.ts +9 -14
- package/dist/components/core/button/button-impl.css +25 -0
- package/dist/components/core/button-icon/ButtonIcon.css +31 -15
- package/dist/components/core/button-icon/ButtonIcon.d.ts +2 -2
- package/dist/components/core/button-icon/ButtonIcon.js +2 -2
- package/dist/components/core/button-icon/ButtonIcon.types.d.ts +4 -4
- package/dist/components/core/card/Card.css +13 -4
- package/dist/components/core/card/Card.types.d.ts +2 -1
- package/dist/components/core/card-body/CardBody.css +11 -6
- package/dist/components/core/card-body/CardBody.d.ts +1 -1
- package/dist/components/core/card-body/CardBody.js +2 -2
- package/dist/components/core/card-body/CardBody.types.d.ts +4 -1
- package/dist/components/core/card-body/CardBody.types.js +1 -0
- package/dist/components/core/card-button/CardButton.css +13 -4
- package/dist/components/core/card-button/CardButton.types.d.ts +2 -1
- package/dist/components/core/checkbox/Checkbox.css +8 -1
- package/dist/components/core/dropdown-menu/DropdownMenu.css +13 -12
- package/dist/components/core/dropdown-menu/DropdownMenu.d.ts +5 -3
- package/dist/components/core/dropdown-menu/DropdownMenu.js +5 -3
- package/dist/components/core/filter-chip/FilterChip.css +2 -1
- package/dist/components/core/footer/footer-impl.css +1 -1
- package/dist/components/core/footer-group/FooterGroup.css +8 -7
- package/dist/components/core/icon/Icon.css +1 -1
- package/dist/components/core/link/Link.css +1 -1
- package/dist/components/core/link/Link.js +5 -5
- package/dist/components/core/menu-item/MenuItem.css +1 -1
- package/dist/components/core/navbar/Navbar.css +7 -8
- package/dist/components/core/navbar/Navbar.d.ts +17 -1
- package/dist/components/core/navbar/Navbar.js +139 -12
- package/dist/components/core/navbar/Navbar.types.d.ts +23 -4
- package/dist/components/core/navbar/Navbar.types.js +1 -1
- package/dist/components/core/navbar/navbar-impl.css +10 -3
- package/dist/components/core/navbar/navbar-material.css +96 -0
- package/dist/components/core/navbar-item/NavbarItem.css +4 -4
- package/dist/components/core/navbar-menu/NavbarMenu.css +7 -5
- package/dist/components/core/navbar-menu/NavbarMenu.d.ts +1 -0
- package/dist/components/core/navbar-menu/NavbarMenu.js +1 -0
- package/dist/components/core/navbar-menu/navbar-menu-impl.css +7 -7
- package/dist/components/core/navbar-switcher/NavbarSwitcher.css +6 -5
- package/dist/components/core/navbar-switcher/NavbarSwitcher.d.ts +1 -0
- package/dist/components/core/navbar-switcher/NavbarSwitcher.js +2 -1
- package/dist/components/core/option/Option.css +1 -1
- package/dist/components/core/pagination/Pagination.css +1 -75
- package/dist/components/core/pagination/Pagination.d.ts +4 -4
- package/dist/components/core/pagination/Pagination.js +11 -51
- package/dist/components/core/pagination/Pagination.types.d.ts +5 -17
- package/dist/components/core/pagination/Pagination.types.js +1 -3
- 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 +3 -3
- package/dist/components/core/search-input/SearchInput.css +1 -1
- package/dist/components/core/segmented-control/SegmentedControl.css +1 -1
- package/dist/components/core/segmented-control-item/SegmentedControlItem.css +1 -1
- package/dist/components/core/select/Select.css +2 -1
- package/dist/components/core/select-chip/SelectChip.css +14 -7
- package/dist/components/core/select-chip/SelectChip.d.ts +1 -1
- package/dist/components/core/select-chip/SelectChip.js +7 -4
- package/dist/components/core/select-chip/SelectChip.types.d.ts +7 -1
- package/dist/components/core/select-chip/SelectChip.types.js +1 -1
- package/dist/components/core/select-chip/select-chip-impl.css +14 -3
- package/dist/components/core/status-dot/StatusDot.css +1 -1
- package/dist/components/core/subdomain-navbar/SubdomainNavbar.css +3 -3
- package/dist/components/core/tab/Tab.css +1 -1
- package/dist/components/core/tab/Tab.types.d.ts +1 -1
- package/dist/components/core/tab-list/TabList.css +1 -1
- package/dist/components/core/table/table-impl.css +36 -14
- package/dist/components/core/table-header-cell/TableHeaderCell.css +5 -5
- package/dist/components/core/text-area/TextArea.css +1 -1
- package/dist/components/core/text-input/TextInput.css +1 -1
- package/dist/components/core/tooltip/Tooltip.css +1 -1
- package/dist/components/core/typography/Typography.css +5 -5
- package/dist/components/index.d.ts +35 -0
- package/dist/components/index.js +30 -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/marketing.css +385 -14
- package/package.json +1 -6
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__list {
|
|
14
|
-
transition-property: gap;
|
|
15
14
|
align-items: center;
|
|
16
15
|
display: flex;
|
|
17
16
|
min-inline-size: 0;
|
|
@@ -32,34 +31,6 @@
|
|
|
32
31
|
line-height: var(--font-label-sm-line-height);
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__dot {
|
|
36
|
-
transition-property: color, min-inline-size, outline-color, outline-width;
|
|
37
|
-
align-items: center;
|
|
38
|
-
appearance: none;
|
|
39
|
-
background-color: transparent;
|
|
40
|
-
box-sizing: border-box;
|
|
41
|
-
cursor: pointer;
|
|
42
|
-
display: flex;
|
|
43
|
-
justify-content: center;
|
|
44
|
-
outline-style: solid;
|
|
45
|
-
border-radius: var(--radius-pill);
|
|
46
|
-
border-width: var(--border-width-none);
|
|
47
|
-
color: var(--color-bg-track);
|
|
48
|
-
min-block-size: var(--size-target-min);
|
|
49
|
-
outline-width: var(--border-width-none);
|
|
50
|
-
transition-duration: var(--motion-duration-fast);
|
|
51
|
-
transition-timing-function: var(--motion-easing-standard);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__dot-mark {
|
|
55
|
-
background-color: currentcolor;
|
|
56
|
-
display: block;
|
|
57
|
-
flex: none;
|
|
58
|
-
block-size: var(--size-dot-diameter);
|
|
59
|
-
border-radius: var(--radius-pill);
|
|
60
|
-
inline-size: var(--size-dot-diameter);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
34
|
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__step {
|
|
64
35
|
transition-property: background-color, opacity, outline-color, outline-width;
|
|
65
36
|
align-items: center;
|
|
@@ -125,10 +96,6 @@
|
|
|
125
96
|
background-color: var(--color-bg-hover);
|
|
126
97
|
}
|
|
127
98
|
|
|
128
|
-
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__dot:hover:where(:not(:disabled)) {
|
|
129
|
-
color: var(--color-bg-track-hover);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
99
|
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__page:hover:where(:not(:disabled)) {
|
|
133
100
|
background-color: var(--color-bg-hover);
|
|
134
101
|
}
|
|
@@ -141,10 +108,6 @@
|
|
|
141
108
|
background-color: var(--color-bg-active);
|
|
142
109
|
}
|
|
143
110
|
|
|
144
|
-
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__dot:active {
|
|
145
|
-
color: var(--color-bg-track-active);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
111
|
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__page:active {
|
|
149
112
|
background-color: var(--color-bg-active);
|
|
150
113
|
}
|
|
@@ -158,11 +121,6 @@
|
|
|
158
121
|
outline-width: var(--border-width-focus);
|
|
159
122
|
}
|
|
160
123
|
|
|
161
|
-
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__dot:focus-visible {
|
|
162
|
-
outline-color: var(--color-border-focus);
|
|
163
|
-
outline-width: var(--border-width-focus);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
124
|
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__page:focus-visible {
|
|
167
125
|
outline-color: var(--color-border-focus);
|
|
168
126
|
outline-width: var(--border-width-focus);
|
|
@@ -173,10 +131,6 @@
|
|
|
173
131
|
outline-width: var(--border-width-focus);
|
|
174
132
|
}
|
|
175
133
|
|
|
176
|
-
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__dot[data-current="true"] {
|
|
177
|
-
color: var(--color-bg-strong);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
134
|
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__page[data-current="true"] {
|
|
181
135
|
background-color: var(--color-bg-strong);
|
|
182
136
|
color: var(--color-fg-on-strong);
|
|
@@ -186,38 +140,10 @@
|
|
|
186
140
|
opacity: var(--opacity-disabled);
|
|
187
141
|
}
|
|
188
142
|
|
|
189
|
-
:where([data-dds-context="marketing"]) .dds-pagination[data-show-steps="false"] .dds-pagination__dot {
|
|
190
|
-
min-inline-size: var(--size-target-min);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
:where([data-dds-context="marketing"]) .dds-pagination[data-show-steps="true"] .dds-pagination__dot {
|
|
194
|
-
min-inline-size: var(--size-dot-diameter);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
143
|
:where([data-dds-context="marketing"]) .dds-pagination[data-variant="compact"] {
|
|
198
144
|
gap: var(--space-gap-sm);
|
|
199
145
|
}
|
|
200
146
|
|
|
201
|
-
:where([data-dds-context="marketing"]) .dds-pagination[data-variant="count"] {
|
|
202
|
-
gap: var(--space-gap-sm);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
:where([data-dds-context="marketing"]) .dds-pagination[data-variant="none"] {
|
|
206
|
-
gap: var(--space-gap-xs);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
:where([data-dds-context="marketing"]) .dds-pagination[data-variant="dots"][data-show-steps="false"] .dds-pagination__list {
|
|
210
|
-
gap: var(--space-gap-none);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
:where([data-dds-context="marketing"]) .dds-pagination[data-variant="dots"][data-show-steps="true"] .dds-pagination__list {
|
|
214
|
-
gap: var(--space-gap-xs);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__dot:disabled {
|
|
218
|
-
cursor: not-allowed;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
147
|
:where([data-dds-context="marketing"]) .dds-pagination .dds-pagination__step:disabled {
|
|
222
148
|
cursor: not-allowed;
|
|
223
149
|
}
|
|
@@ -232,6 +158,6 @@
|
|
|
232
158
|
|
|
233
159
|
@media (prefers-reduced-motion: reduce) {
|
|
234
160
|
:where([data-dds-context="marketing"]) .dds-pagination,
|
|
235
|
-
:where([data-dds-context="marketing"]) .dds-pagination * { transition: none; }
|
|
161
|
+
:where([data-dds-context="marketing"]) .dds-pagination * { transition: none !important; }
|
|
236
162
|
}
|
|
237
163
|
|
|
@@ -17,14 +17,14 @@ export type { PaginationProps };
|
|
|
17
17
|
* company with product's. There the steps are ButtonIcons and the numbered pages are
|
|
18
18
|
* Buttons; this package's ButtonIcon has no disabled state and says so in its own source,
|
|
19
19
|
* being a family of links, and a step at the end of the set has to be disabled rather than
|
|
20
|
-
* removed. Its Button
|
|
20
|
+
* removed. Its Button was an anchor with a required href when this was built, and it has no quiet
|
|
21
|
+
* form, so a row of
|
|
21
22
|
* page numbers built from it would be a row of calls to action. Both are correct decisions
|
|
22
23
|
* for what those components are, and neither leaves anything to borrow.
|
|
23
24
|
*
|
|
24
25
|
* What a press is depends on the variant, and on `pageHref`. Given it, every route to a
|
|
25
26
|
* page is an anchor — the numbered targets and both steps — which is what gives a visitor
|
|
26
27
|
* cmd-click, a destination in the status bar and a link a crawler can follow. Without it
|
|
27
|
-
* they are buttons reporting through `onPageChange`.
|
|
28
|
-
* buttons: a slide has no address.
|
|
28
|
+
* they are buttons reporting through `onPageChange`.
|
|
29
29
|
*/
|
|
30
|
-
export declare function Pagination({ variant,
|
|
30
|
+
export declare function Pagination({ variant, page, totalPages, onPageChange, pageHref, siblingCount, label, previousLabel, nextLabel, morePagesLabel, ...rest }: PaginationProps): import("react").JSX.Element;
|
|
@@ -19,16 +19,6 @@ import { paginationDefaults, paginationParts } from './Pagination.types.js';
|
|
|
19
19
|
* step draws at the wrong size while every gate still passes.
|
|
20
20
|
*/
|
|
21
21
|
const GLYPH_SIZE = 'xs';
|
|
22
|
-
/**
|
|
23
|
-
* The most marks the dots variant will draw.
|
|
24
|
-
*
|
|
25
|
-
* Twice the set size the variant asks for, so nothing anyone should be using it on comes
|
|
26
|
-
* near it. It is a guard rather than a design threshold: the marks are decoration, and one
|
|
27
|
-
* target per page meant a total wired straight from a result count built that many
|
|
28
|
-
* controls and took the page with it. Past this the marks give way to the readout in
|
|
29
|
-
* words, which is a degrade a reader can see — an empty row is not one.
|
|
30
|
-
*/
|
|
31
|
-
const DOT_LIMIT = 20;
|
|
32
22
|
/**
|
|
33
23
|
* The most pages a break will offer in one menu.
|
|
34
24
|
*
|
|
@@ -135,30 +125,11 @@ function measurements(root, list) {
|
|
|
135
125
|
};
|
|
136
126
|
}
|
|
137
127
|
/**
|
|
138
|
-
* What the readout says
|
|
139
|
-
*
|
|
140
|
-
* A range against a total is the better sentence and the one the count variant exists for,
|
|
141
|
-
* but it needs both halves: `pageSize` to know how wide a page is, and `totalItems` to know
|
|
142
|
-
* what it is a fraction of. Given one without the other it falls back to counting pages
|
|
143
|
-
* rather than guessing — a total this component invented would be indistinguishable, to the
|
|
144
|
-
* reader, from one the consumer supplied.
|
|
145
|
-
*
|
|
146
|
-
* The upper bound is clamped to the total because the last page is rarely full: 24 pages of
|
|
147
|
-
* 10 across 235 items ends at 235, and a readout claiming 240 of 235 is arithmetic the
|
|
148
|
-
* reader can see is wrong.
|
|
128
|
+
* What the readout says under compact: a bare position, and the terseness is the point rather
|
|
129
|
+
* than a saving — the variant is chosen for a place with no width.
|
|
149
130
|
*/
|
|
150
|
-
function readout(
|
|
151
|
-
|
|
152
|
-
// variant is chosen for a place with no width. It is also what keeps the two readouts
|
|
153
|
-
// from being the same sentence, count falling back to counting pages when it has no total.
|
|
154
|
-
if (variant === 'compact')
|
|
155
|
-
return `${String(current)} / ${String(last)}`;
|
|
156
|
-
if (totalItems === undefined || pageSize === undefined) {
|
|
157
|
-
return `Page ${String(current)} of ${String(last)}`;
|
|
158
|
-
}
|
|
159
|
-
const from = (current - 1) * pageSize + 1;
|
|
160
|
-
const to = Math.min(current * pageSize, totalItems);
|
|
161
|
-
return `${String(from)}–${String(to)} of ${String(totalItems)}`;
|
|
131
|
+
function readout(current, last) {
|
|
132
|
+
return `${String(current)} / ${String(last)}`;
|
|
162
133
|
}
|
|
163
134
|
/**
|
|
164
135
|
* A `<nav>` holding the ways through a set that has been divided into pages.
|
|
@@ -175,17 +146,17 @@ function readout(variant, current, last, totalItems, pageSize) {
|
|
|
175
146
|
* company with product's. There the steps are ButtonIcons and the numbered pages are
|
|
176
147
|
* Buttons; this package's ButtonIcon has no disabled state and says so in its own source,
|
|
177
148
|
* being a family of links, and a step at the end of the set has to be disabled rather than
|
|
178
|
-
* removed. Its Button
|
|
149
|
+
* removed. Its Button was an anchor with a required href when this was built, and it has no quiet
|
|
150
|
+
* form, so a row of
|
|
179
151
|
* page numbers built from it would be a row of calls to action. Both are correct decisions
|
|
180
152
|
* for what those components are, and neither leaves anything to borrow.
|
|
181
153
|
*
|
|
182
154
|
* What a press is depends on the variant, and on `pageHref`. Given it, every route to a
|
|
183
155
|
* page is an anchor — the numbered targets and both steps — which is what gives a visitor
|
|
184
156
|
* cmd-click, a destination in the status bar and a link a crawler can follow. Without it
|
|
185
|
-
* they are buttons reporting through `onPageChange`.
|
|
186
|
-
* buttons: a slide has no address.
|
|
157
|
+
* they are buttons reporting through `onPageChange`.
|
|
187
158
|
*/
|
|
188
|
-
export function Pagination({ variant = paginationDefaults.variant,
|
|
159
|
+
export function Pagination({ variant = paginationDefaults.variant, page = paginationDefaults.page, totalPages = paginationDefaults.totalPages, onPageChange, pageHref, siblingCount = paginationDefaults.siblingCount, label = paginationDefaults.label, previousLabel = paginationDefaults.previousLabel, nextLabel = paginationDefaults.nextLabel, morePagesLabel = paginationDefaults.morePagesLabel, ...rest }) {
|
|
189
160
|
// Clamped rather than trusted. A page beyond the set is what a consumer holds for the
|
|
190
161
|
// moment between a filter narrowing the results and their own state catching up, and a
|
|
191
162
|
// row that renders nothing during it reads as the component breaking rather than as the
|
|
@@ -200,17 +171,6 @@ export function Pagination({ variant = paginationDefaults.variant, showSteps = p
|
|
|
200
171
|
const siblings = whole(siblingCount, 0);
|
|
201
172
|
const atStart = current <= 1;
|
|
202
173
|
const atEnd = current >= last;
|
|
203
|
-
/*
|
|
204
|
-
Whether the steps are drawn, which is showSteps under dots and true everywhere else.
|
|
205
|
-
|
|
206
|
-
Inert outside dots rather than obeyed, in the way this component's other
|
|
207
|
-
variant-specific props already are. What makes dots the exception is that its middle is
|
|
208
|
-
the only one holding targets of its own — every position is a mark and every mark is a
|
|
209
|
-
button — so the row still works when the steps go. Under count and compact the steps are
|
|
210
|
-
the whole of what there is to press, and under pages the numbers reach the two ends and
|
|
211
|
-
the window between them, with stepping the way to anything else.
|
|
212
|
-
*/
|
|
213
|
-
const steps = variant === 'dots' ? showSteps : true;
|
|
214
174
|
const rootRef = useRef(null);
|
|
215
175
|
const listRef = useRef(null);
|
|
216
176
|
/**
|
|
@@ -262,7 +222,7 @@ export function Pagination({ variant = paginationDefaults.variant, showSteps = p
|
|
|
262
222
|
// width forbids and the consumer decides the rest. Where even none of them fits there
|
|
263
223
|
// is nothing left to give up that would not cost the reader the page they are on or an
|
|
264
224
|
// end of the set, so the list scrolls — which is the point at which the column wanted
|
|
265
|
-
//
|
|
225
|
+
// compact rather than numbers.
|
|
266
226
|
const afford = Math.max(0, measured.holds - 5);
|
|
267
227
|
if (afford < shown) {
|
|
268
228
|
foldedAt.current = measured.room;
|
|
@@ -339,7 +299,7 @@ export function Pagination({ variant = paginationDefaults.variant, showSteps = p
|
|
|
339
299
|
}
|
|
340
300
|
return (_jsx("button", { className: paginationParts.step, type: "button", "aria-label": name, disabled: disabled, onClick: go(to), children: mark }));
|
|
341
301
|
};
|
|
342
|
-
return (_jsxs("nav", { ref: rootRef, className: paginationParts.root, "aria-label": label, "data-variant": variant,
|
|
302
|
+
return (_jsxs("nav", { ref: rootRef, className: paginationParts.root, "aria-label": label, "data-variant": variant, ...rest, children: [stepControl(current - 1, previousLabel, atStart, _jsx(ChevronLeftRegularIcon, {})), variant === 'pages' && (_jsx("div", { className: paginationParts.list, ref: listRef, children: row.map((slot, index) => {
|
|
343
303
|
if (slot === 'gap') {
|
|
344
304
|
const stands = row[index - 1];
|
|
345
305
|
/*
|
|
@@ -402,5 +362,5 @@ export function Pagination({ variant = paginationDefaults.variant, showSteps = p
|
|
|
402
362
|
return (_jsx("a", { className: paginationParts.page, href: pageHref(slot), "aria-current": isCurrent ? 'page' : undefined, "data-current": isCurrent ? 'true' : undefined, onClick: go(slot), children: slot }, slot));
|
|
403
363
|
}
|
|
404
364
|
return (_jsx("button", { className: paginationParts.page, type: "button", "aria-current": isCurrent ? 'page' : undefined, "data-current": isCurrent ? 'true' : undefined, onClick: go(slot), children: slot }, slot));
|
|
405
|
-
}) })), variant === '
|
|
365
|
+
}) })), variant === 'compact' && (_jsx("span", { className: paginationParts.summary, children: readout(current, last) })), stepControl(current + 1, nextLabel, atEnd, _jsx(ChevronRightRegularIcon, {}))] }));
|
|
406
366
|
}
|
|
@@ -2,26 +2,17 @@ import type { HTMLAttributes } from 'react';
|
|
|
2
2
|
export interface PaginationOwnProps {
|
|
3
3
|
/**
|
|
4
4
|
* `pages` — An index or archive whose pages have addresses of their own — a blog listing, a news archive, a resource library. The only variant offering a numbered target, so the only one on which reaching page fourteen costs a single press rather than thirteen, and the only one a crawler can follow past page one. It draws Buttons, which in this package are anchors, so it needs pageHref and the pages it points at have to exist as URLs. A page too far out to be drawn is still not a walk: the break between two runs of numbers presses, and offers the pages it stands for
|
|
5
|
-
* `
|
|
6
|
-
* `compact` — A place with no room for a row of numbers — a card footer, a sidebar, a column at a phone's width. Position and the two steps, and nothing else. Like count, its steps are anchors given pageHref and buttons without it
|
|
7
|
-
* `none` — The two steps and nothing between them, for a place where position is either obvious or beside the point — a lightbox moving through images, a set of two. It is the least this component can be, and choosing it is a claim that the reader does not need to know where they are, which on a page with an address per position is a claim worth making deliberately
|
|
8
|
-
* `dots` — A carousel of cards, a testimonial slider, a walkthrough — a short visual sequence where the reader cares where they are rather than what that position is called. The marks are always buttons and the press is always the page's to handle, a slide having no address to link to; pageHref is ignored here rather than obeyed. The case it was built for is a set the reader swipes: pass showSteps={false} there and the row is marks alone, which is also the only variant still offering a target once the steps are gone. Keep the set under about ten — a dot carries no number, so beyond a handful the reader is counting marks too small and too many to count
|
|
5
|
+
* `compact` — A place with no room for a row of numbers — a card footer, a sidebar, a column at a phone's width. Position and the two steps, and nothing else. Like pages, its steps are anchors given pageHref and buttons without it
|
|
9
6
|
*/
|
|
10
|
-
variant?: 'pages' | '
|
|
11
|
-
/** Whether the two step controls are drawn, under the dots variant. True wherever this component is the way through the set, which is nearly all of them. False for a set the reader moves through some other way and this only reports — a carousel they swipe, a gallery with its own arrows — where a second pair underneath competes with the first. Dropping them also buys the width that lets a long row of marks fit a phone */
|
|
12
|
-
showSteps?: boolean;
|
|
7
|
+
variant?: 'pages' | 'compact';
|
|
13
8
|
/** Always — it is which page is on screen, counting from one, and the component renders around it rather than holding it. The consumer owns this because the results do: the page number and the rows beneath it are one fact, and a control keeping its own copy is how the two come to disagree. The default is the first page, which is where a set with nothing said about it starts */
|
|
14
9
|
page?: number;
|
|
15
10
|
/** How many pages the set has been divided into. It decides where the row ends, when the ellipsis appears, and when next goes disabled. The default of one is the honest answer for a set nothing has been said about, and it is also the case the component should not be used in at all — a single page has nothing to move between */
|
|
16
11
|
totalPages?: number;
|
|
17
|
-
/** What the page does when the reader asks for another one, counting from one. Required wherever the route to a page is a press rather than a destination: the
|
|
12
|
+
/** What the page does when the reader asks for another one, counting from one. Required wherever the route to a page is a press rather than a destination: the numbered targets and the steps under any variant given no pageHref. Under pages it is the pageHref that carries the reader, so this is the reporting half rather than the moving one — useful for telling analytics, and unnecessary if nothing is listening. One of this and pageHref is needed; a component given neither draws a row nothing can move. */
|
|
18
13
|
onPageChange?: (page: number) => void;
|
|
19
|
-
/** The address of a page, given the page number. Passing it makes every route to a page an anchor: the numbered targets, and both steps. Required under the pages variant, which draws Buttons — and a Button in this package is an anchor with a destination, never a press the page handles. Pass it under compact
|
|
14
|
+
/** The address of a page, given the page number. Passing it makes every route to a page an anchor: the numbered targets, and both steps. Required under the pages variant, which draws Buttons — and a Button in this package is an anchor with a destination, never a press the page handles. Pass it under compact too wherever the pages have real URLs, because an anchor is what gives a visitor cmd-click, a destination in the status bar, and a link a search engine can follow to page two. One of this and onPageChange is needed; a component given neither draws a row nothing can move. */
|
|
20
15
|
pageHref?: (page: number) => string;
|
|
21
|
-
/** How many results there are altogether, where that is known. It is what turns the count variant's readout from a position into a measure — "1–10 of 240" rather than "page 1 of 24" — which is the fact that tells a reader whether to keep stepping or narrow their filter instead */
|
|
22
|
-
totalItems?: number;
|
|
23
|
-
/** How many items each page holds, which is what lets the count variant work out the range on screen from the page number alone. Pass it alongside totalItems; on its own it has nothing to be a fraction of. It reports the size in force and does not offer to change it — a control for that is the consumer's to place, beside this one */
|
|
24
|
-
pageSize?: number;
|
|
25
16
|
/** How many numbered pages sit around the current one before the row breaks, under the pages variant. Around rather than either side: the window is split, with the odd one going forward, since the page the reader has not read is the one they most likely want. One is the current page and the one after it, a row of six; two is mirrored. The most it will show rather than a promise, since the row drops what the container cannot hold */
|
|
26
17
|
siblingCount?: number;
|
|
27
18
|
/** Always, and the default is almost always right. It names the landmark rather than the content — a screen reader user listing what is on a page hears this, and a nav with no name is one they cannot tell from the page's other navigation. Set it where a page carries two of these, so the two are distinguishable by what they page through */
|
|
@@ -33,14 +24,12 @@ export interface PaginationOwnProps {
|
|
|
33
24
|
/** The accessible name for the break between two runs of numbered pages — the control that opens a menu of the pages that break stands for. A glyph announces nothing, which is the position previousLabel and nextLabel are in, and this is passed the same way the two steps' names are, as the control's own accessible name. It names the menu as well as the control, so a reader who has opened it hears which menu they are in */
|
|
34
25
|
morePagesLabel?: string;
|
|
35
26
|
}
|
|
36
|
-
export type PaginationProps = PaginationOwnProps & Omit<HTMLAttributes<HTMLElement>, 'className' | 'variant' | '
|
|
27
|
+
export type PaginationProps = PaginationOwnProps & Omit<HTMLAttributes<HTMLElement>, 'className' | 'variant' | 'page' | 'totalPages' | 'onPageChange' | 'pageHref' | 'siblingCount' | 'label' | 'previousLabel' | 'nextLabel' | 'morePagesLabel'>;
|
|
37
28
|
/** The class each part carries. Apply these — do not retype them. */
|
|
38
29
|
export declare const paginationParts: {
|
|
39
30
|
readonly root: "dds-pagination";
|
|
40
31
|
readonly list: "dds-pagination__list";
|
|
41
32
|
readonly summary: "dds-pagination__summary";
|
|
42
|
-
readonly dot: "dds-pagination__dot";
|
|
43
|
-
readonly 'dot-mark': "dds-pagination__dot-mark";
|
|
44
33
|
readonly step: "dds-pagination__step";
|
|
45
34
|
readonly page: "dds-pagination__page";
|
|
46
35
|
readonly break: "dds-pagination__break";
|
|
@@ -48,7 +37,6 @@ export declare const paginationParts: {
|
|
|
48
37
|
/** Generated so defaults cannot drift from the contract. */
|
|
49
38
|
export declare const paginationDefaults: {
|
|
50
39
|
readonly variant: "pages";
|
|
51
|
-
readonly showSteps: true;
|
|
52
40
|
readonly page: 1;
|
|
53
41
|
readonly totalPages: 1;
|
|
54
42
|
readonly siblingCount: 1;
|
|
@@ -4,11 +4,9 @@ export const paginationParts = {
|
|
|
4
4
|
root: 'dds-pagination',
|
|
5
5
|
list: 'dds-pagination__list',
|
|
6
6
|
summary: 'dds-pagination__summary',
|
|
7
|
-
dot: 'dds-pagination__dot',
|
|
8
|
-
'dot-mark': 'dds-pagination__dot-mark',
|
|
9
7
|
step: 'dds-pagination__step',
|
|
10
8
|
page: 'dds-pagination__page',
|
|
11
9
|
break: 'dds-pagination__break',
|
|
12
10
|
};
|
|
13
11
|
/** Generated so defaults cannot drift from the contract. */
|
|
14
|
-
export const paginationDefaults = { variant: 'pages',
|
|
12
|
+
export const paginationDefaults = { variant: 'pages', page: 1, totalPages: 1, siblingCount: 1, label: 'Pagination', previousLabel: 'Previous page', nextLabel: 'Next page', morePagesLabel: 'More pages' };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* GENERATED from paginationdots.contract.json. Do not edit. */
|
|
2
|
+
|
|
3
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots {
|
|
4
|
+
align-items: center;
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: row;
|
|
7
|
+
column-gap: var(--space-gap-sm);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots .dds-paginationdots__dot {
|
|
11
|
+
transition-property: outline-color, outline-width;
|
|
12
|
+
align-items: center;
|
|
13
|
+
appearance: none;
|
|
14
|
+
background-color: transparent;
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
color: inherit;
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
display: flex;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
outline-style: solid;
|
|
21
|
+
padding: 0;
|
|
22
|
+
border-radius: var(--radius-pill);
|
|
23
|
+
border-width: var(--border-width-none);
|
|
24
|
+
min-block-size: var(--size-target-min);
|
|
25
|
+
min-inline-size: var(--size-dot-diameter);
|
|
26
|
+
outline-width: var(--border-width-none);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots .dds-paginationdots__mark {
|
|
30
|
+
transition-property: inline-size, opacity;
|
|
31
|
+
background-color: currentcolor;
|
|
32
|
+
display: block;
|
|
33
|
+
flex: none;
|
|
34
|
+
block-size: var(--size-dot-diameter);
|
|
35
|
+
border-radius: var(--radius-pill);
|
|
36
|
+
inline-size: var(--size-dot-diameter);
|
|
37
|
+
opacity: var(--opacity-dot-rest);
|
|
38
|
+
transition-duration: var(--motion-duration-slow);
|
|
39
|
+
transition-timing-function: var(--motion-easing-shift);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots .dds-paginationdots__dot:focus-visible {
|
|
43
|
+
outline-color: var(--color-border-focus);
|
|
44
|
+
outline-width: var(--border-width-focus);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots .dds-paginationdots__mark[data-current="true"] {
|
|
48
|
+
inline-size: var(--size-dot-current);
|
|
49
|
+
opacity: var(--opacity-dot-current);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots[data-variant="accent"] .dds-paginationdots__dot {
|
|
53
|
+
color: var(--color-fg-brand-accent);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@media (prefers-reduced-motion: reduce) {
|
|
57
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots,
|
|
58
|
+
:where([data-dds-context="marketing"]) .dds-paginationdots * { transition: none !important; }
|
|
59
|
+
}
|
|
60
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import './PaginationDots.css';
|
|
2
|
+
import { type PaginationDotsProps } from './PaginationDots.types.js';
|
|
3
|
+
export type { PaginationDotsProps };
|
|
4
|
+
/**
|
|
5
|
+
* A row of marks, one per position in a short sequence, every one a button that moves there — and,
|
|
6
|
+
* under `autoplay`, a row that moves on its own.
|
|
7
|
+
*
|
|
8
|
+
* Split out of Pagination, where it was a variant. A set of results and a slider's slides are
|
|
9
|
+
* different questions — how far does this run, against where am I — and the one variant that
|
|
10
|
+
* answered the second was the one that needed none of Pagination's other props. Steps are not
|
|
11
|
+
* here: whatever holds the row puts previous and next beside it, where its own layout wants them.
|
|
12
|
+
*
|
|
13
|
+
* Drawn in the ground's own ink. The marks are currentcolor, the rest at opacity.dot-rest and the
|
|
14
|
+
* current one solid and stretched to size.dot.current, so one row reads on any band without
|
|
15
|
+
* naming a colour.
|
|
16
|
+
*
|
|
17
|
+
* Nothing about position is held here: `page` is the consumer's, because the slide in view is
|
|
18
|
+
* theirs too, and the two are one fact. Autoplay therefore moves nothing itself — every
|
|
19
|
+
* motion.duration.dwell it reports the next position through onPageChange and waits for `page` to
|
|
20
|
+
* come back. A reader who presses a mark stops it for good. It holds while `paused` says so — the
|
|
21
|
+
* holder's hover, focus, or its own stop — and never moves for a reader who asked for less motion.
|
|
22
|
+
* There is no pause control, by decision: a press is the way to stop it, and the contract says what
|
|
23
|
+
* that does and does not give WCAG 2.2.2.
|
|
24
|
+
*/
|
|
25
|
+
export declare function PaginationDots({ variant, page, totalPages, onPageChange, autoplay, paused, label, itemLabel, }: PaginationDotsProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import './PaginationDots.css';
|
|
5
|
+
import { paginationDotsDefaults, paginationDotsParts, } from './PaginationDots.types.js';
|
|
6
|
+
/**
|
|
7
|
+
* The most marks the row will draw.
|
|
8
|
+
*
|
|
9
|
+
* A guard rather than a design threshold — the row is for a handful, and its guidance says so.
|
|
10
|
+
* What it guards against is a total wired straight from a result count: five thousand of them
|
|
11
|
+
* built five thousand buttons and took the page with it. Past this the marks give way to the
|
|
12
|
+
* position written as numbers, which a reader can see, where an empty row would read as broken.
|
|
13
|
+
*/
|
|
14
|
+
const DOT_LIMIT = 20;
|
|
15
|
+
/**
|
|
16
|
+
* A CSS time as milliseconds, the unit read rather than assumed: the same token arrives as `5000ms`
|
|
17
|
+
* from a dev server and `5s` once a minifier has been over it. Null for anything else, so the row
|
|
18
|
+
* holds still rather than inventing a timing.
|
|
19
|
+
*/
|
|
20
|
+
function milliseconds(value) {
|
|
21
|
+
const time = value.trim();
|
|
22
|
+
const amount = Number.parseFloat(time);
|
|
23
|
+
if (!Number.isFinite(amount))
|
|
24
|
+
return null;
|
|
25
|
+
if (/ms$/i.test(time))
|
|
26
|
+
return amount;
|
|
27
|
+
if (/s$/i.test(time))
|
|
28
|
+
return amount * 1000;
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Whether the reader has asked for less motion, kept current if they change it. Until it has been
|
|
33
|
+
* read — on the server, before the first effect — the answer is yes, the safe one: a row that
|
|
34
|
+
* starts still and then moves is better than one that moves for a frame for a reader who said not to.
|
|
35
|
+
*/
|
|
36
|
+
function usePrefersLessMotion() {
|
|
37
|
+
const [less, setLess] = useState(true);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (typeof window.matchMedia !== 'function')
|
|
40
|
+
return;
|
|
41
|
+
const query = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
42
|
+
const update = () => setLess(query.matches);
|
|
43
|
+
update();
|
|
44
|
+
query.addEventListener('change', update);
|
|
45
|
+
return () => query.removeEventListener('change', update);
|
|
46
|
+
}, []);
|
|
47
|
+
return less;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A row of marks, one per position in a short sequence, every one a button that moves there — and,
|
|
51
|
+
* under `autoplay`, a row that moves on its own.
|
|
52
|
+
*
|
|
53
|
+
* Split out of Pagination, where it was a variant. A set of results and a slider's slides are
|
|
54
|
+
* different questions — how far does this run, against where am I — and the one variant that
|
|
55
|
+
* answered the second was the one that needed none of Pagination's other props. Steps are not
|
|
56
|
+
* here: whatever holds the row puts previous and next beside it, where its own layout wants them.
|
|
57
|
+
*
|
|
58
|
+
* Drawn in the ground's own ink. The marks are currentcolor, the rest at opacity.dot-rest and the
|
|
59
|
+
* current one solid and stretched to size.dot.current, so one row reads on any band without
|
|
60
|
+
* naming a colour.
|
|
61
|
+
*
|
|
62
|
+
* Nothing about position is held here: `page` is the consumer's, because the slide in view is
|
|
63
|
+
* theirs too, and the two are one fact. Autoplay therefore moves nothing itself — every
|
|
64
|
+
* motion.duration.dwell it reports the next position through onPageChange and waits for `page` to
|
|
65
|
+
* come back. A reader who presses a mark stops it for good. It holds while `paused` says so — the
|
|
66
|
+
* holder's hover, focus, or its own stop — and never moves for a reader who asked for less motion.
|
|
67
|
+
* There is no pause control, by decision: a press is the way to stop it, and the contract says what
|
|
68
|
+
* that does and does not give WCAG 2.2.2.
|
|
69
|
+
*/
|
|
70
|
+
export function PaginationDots({ variant = paginationDotsDefaults.variant, page = paginationDotsDefaults.page, totalPages = paginationDotsDefaults.totalPages, onPageChange, autoplay = paginationDotsDefaults.autoplay, paused = paginationDotsDefaults.paused, label = paginationDotsDefaults.label, itemLabel = paginationDotsDefaults.itemLabel, }) {
|
|
71
|
+
const count = Math.max(0, Math.floor(totalPages));
|
|
72
|
+
const current = Math.min(Math.max(1, Math.floor(page)), Math.max(1, count));
|
|
73
|
+
const root = useRef(null);
|
|
74
|
+
const lessMotion = usePrefersLessMotion();
|
|
75
|
+
/*
|
|
76
|
+
Stopped for good once the reader presses a mark. A reader who chose a position has said where
|
|
77
|
+
they want to be, and moving them on from it five seconds later would take that back — the WAI
|
|
78
|
+
carousel pattern's rule, and the way this row offers a reader a stop without a control for it.
|
|
79
|
+
*/
|
|
80
|
+
const [stopped, setStopped] = useState(false);
|
|
81
|
+
const running = autoplay && !stopped && !paused && !lessMotion && count > 1 && onPageChange !== undefined;
|
|
82
|
+
// Read through a ref so a new handler on every render does not re-arm the timer.
|
|
83
|
+
const report = useRef(onPageChange);
|
|
84
|
+
report.current = onPageChange;
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
if (!running || root.current === null)
|
|
87
|
+
return;
|
|
88
|
+
const dwell = milliseconds(getComputedStyle(root.current).getPropertyValue('--motion-duration-dwell'));
|
|
89
|
+
if (dwell === null)
|
|
90
|
+
return;
|
|
91
|
+
const timer = window.setTimeout(() => report.current?.((current % count) + 1), dwell);
|
|
92
|
+
return () => window.clearTimeout(timer);
|
|
93
|
+
}, [running, current, count]);
|
|
94
|
+
if (count > DOT_LIMIT) {
|
|
95
|
+
return (_jsx("div", { className: paginationDotsParts.root, "data-variant": variant, role: "group", "aria-label": label, ref: root, children: _jsx("span", { role: "status", children: `${String(current)} / ${String(count)}` }) }));
|
|
96
|
+
}
|
|
97
|
+
return (_jsx("div", { className: paginationDotsParts.root, "data-variant": variant, role: "group", "aria-label": label, ref: root, children: Array.from({ length: count }, (_, index) => index + 1).map((at) => {
|
|
98
|
+
const here = at === current;
|
|
99
|
+
return (_jsx("button", { type: "button", className: paginationDotsParts.dot, "aria-label": `${itemLabel} ${String(at)}`, "aria-current": here ? 'true' : undefined, onClick: () => {
|
|
100
|
+
setStopped(true);
|
|
101
|
+
onPageChange?.(at);
|
|
102
|
+
}, children: _jsx("span", { className: paginationDotsParts.mark, "data-current": here ? 'true' : undefined }) }, at));
|
|
103
|
+
}) }));
|
|
104
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface PaginationDotsOwnProps {
|
|
2
|
+
/**
|
|
3
|
+
* `default` — The marks take the ink of whatever the row stands on — white on a coral or dark band, near-black on the page — so the row belongs to its ground. The usual choice, and the only one on a band.
|
|
4
|
+
* `accent` — On the bare page, where the row should carry the brand: the marks are color.fg.brand-accent, the current pill solid coral and the rest the same coral held back. The solid pill clears 3:1 against the page at 3.11:1, just; the resting marks do not, as at the default — so only on the page's own ground, where nothing takes the coral lower.
|
|
5
|
+
*/
|
|
6
|
+
variant?: 'default' | 'accent';
|
|
7
|
+
/** Which position the reader is on, counted from 1. The consumer holds it, because the slide or step in view is theirs too and the two are one fact. */
|
|
8
|
+
page?: number;
|
|
9
|
+
/** How many positions there are, which is how many marks the row draws. */
|
|
10
|
+
totalPages?: number;
|
|
11
|
+
/** Whenever the marks should move anything — called with the position pressed. The row does not move itself; the consumer sets page from it. */
|
|
12
|
+
onPageChange?: (page: number) => void;
|
|
13
|
+
/** The sequence should move on its own — a slider of promotions, a hero that rotates. The row advances page through onPageChange every motion.duration.dwell, wrapping from the last position to the first. It holds while `paused` is set, never moves for a reader who asked for less motion, and stops for good once the reader presses a mark. That last is the WAI carousel pattern's rule that a reader who has chosen a position is reading, not watching. That gives a reader a way to stop the rotation, which WCAG 2.2.2 asks for, but not a visible one: nothing says a press will stop it, so a page that needs 2.2.2 met plainly should still offer its own pause, or leave autoplay off. */
|
|
14
|
+
autoplay?: boolean;
|
|
15
|
+
/** Whatever holds the row wants the rotation held for now — while the pointer is over the slide or focus is inside it, so a reader is never moved on mid-sentence. It lets go when this goes false. */
|
|
16
|
+
paused?: boolean;
|
|
17
|
+
/** The name the row is announced by, as a group. Name what the positions are: 'Slides', 'Steps'. Translate it with the page. */
|
|
18
|
+
label?: string;
|
|
19
|
+
/** The word each mark is named by, before its number — 'Slide 2'. Translate it with the page; a language that puts the number first is the reason a sentence template would be better, and the reason this is not yet one. */
|
|
20
|
+
itemLabel?: string;
|
|
21
|
+
}
|
|
22
|
+
export type PaginationDotsProps = PaginationDotsOwnProps;
|
|
23
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
24
|
+
export declare const paginationDotsParts: {
|
|
25
|
+
readonly root: "dds-paginationdots";
|
|
26
|
+
readonly dot: "dds-paginationdots__dot";
|
|
27
|
+
readonly mark: "dds-paginationdots__mark";
|
|
28
|
+
};
|
|
29
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
30
|
+
export declare const paginationDotsDefaults: {
|
|
31
|
+
readonly variant: "default";
|
|
32
|
+
readonly page: 1;
|
|
33
|
+
readonly totalPages: 1;
|
|
34
|
+
readonly autoplay: false;
|
|
35
|
+
readonly paused: false;
|
|
36
|
+
readonly label: "Slides";
|
|
37
|
+
readonly itemLabel: "Slide";
|
|
38
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// GENERATED from pagination-dots.contract.json. Do not edit.
|
|
2
|
+
/** The class each part carries. Apply these — do not retype them. */
|
|
3
|
+
export const paginationDotsParts = {
|
|
4
|
+
root: 'dds-paginationdots',
|
|
5
|
+
dot: 'dds-paginationdots__dot',
|
|
6
|
+
mark: 'dds-paginationdots__mark',
|
|
7
|
+
};
|
|
8
|
+
/** Generated so defaults cannot drift from the contract. */
|
|
9
|
+
export const paginationDotsDefaults = { variant: 'default', page: 1, totalPages: 1, autoplay: false, paused: false, label: 'Slides', itemLabel: 'Slide' };
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
:where([data-dds-context="marketing"]) .dds-removablechip .dds-removablechip__remove:hover:where(:not(:disabled)) {
|
|
59
|
-
background-color: var(--color-bg-hover-
|
|
59
|
+
background-color: var(--color-bg-hover-on-brand-strong);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
:where([data-dds-context="marketing"]) .dds-removablechip .dds-removablechip__remove:active {
|
|
63
|
-
background-color: var(--color-bg-active-
|
|
63
|
+
background-color: var(--color-bg-active-on-brand-strong);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
:where([data-dds-context="marketing"]) .dds-removablechip .dds-removablechip__remove:focus-visible {
|
|
@@ -120,6 +120,6 @@
|
|
|
120
120
|
|
|
121
121
|
@media (prefers-reduced-motion: reduce) {
|
|
122
122
|
:where([data-dds-context="marketing"]) .dds-removablechip,
|
|
123
|
-
:where([data-dds-context="marketing"]) .dds-removablechip * { transition: none; }
|
|
123
|
+
:where([data-dds-context="marketing"]) .dds-removablechip * { transition: none !important; }
|
|
124
124
|
}
|
|
125
125
|
|
|
@@ -200,6 +200,6 @@
|
|
|
200
200
|
|
|
201
201
|
@media (prefers-reduced-motion: reduce) {
|
|
202
202
|
:where([data-dds-context="marketing"]) .dds-searchinput,
|
|
203
|
-
:where([data-dds-context="marketing"]) .dds-searchinput * { transition: none; }
|
|
203
|
+
:where([data-dds-context="marketing"]) .dds-searchinput * { transition: none !important; }
|
|
204
204
|
}
|
|
205
205
|
|
|
@@ -52,6 +52,6 @@
|
|
|
52
52
|
|
|
53
53
|
@media (prefers-reduced-motion: reduce) {
|
|
54
54
|
:where([data-dds-context="marketing"]) .dds-segmentedcontrol,
|
|
55
|
-
:where([data-dds-context="marketing"]) .dds-segmentedcontrol * { transition: none; }
|
|
55
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrol * { transition: none !important; }
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -146,6 +146,6 @@
|
|
|
146
146
|
|
|
147
147
|
@media (prefers-reduced-motion: reduce) {
|
|
148
148
|
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem,
|
|
149
|
-
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem * { transition: none; }
|
|
149
|
+
:where([data-dds-context="marketing"]) .dds-segmentedcontrolitem * { transition: none !important; }
|
|
150
150
|
}
|
|
151
151
|
|