@windmorph/react 0.2.0 → 0.2.2

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.
Files changed (60) hide show
  1. package/dist/components/carousel/carousel-styles.d.ts +6 -15
  2. package/dist/components/carousel/carousel-styles.js +4 -7
  3. package/dist/components/carousel/carousel-styles.js.map +1 -1
  4. package/dist/components/checkbox/checkbox-tokens.d.ts +1 -1
  5. package/dist/components/chip/chip-tokens.d.ts +4 -4
  6. package/dist/components/date-picker/DatePicker.js +11 -4
  7. package/dist/components/date-picker/DatePicker.js.map +1 -1
  8. package/dist/components/date-picker/date-picker-styles.d.ts +6 -6
  9. package/dist/components/date-picker/date-picker-tokens.d.ts +1 -1
  10. package/dist/components/dialog/Dialog.d.ts +4 -2
  11. package/dist/components/dialog/Dialog.js +2 -2
  12. package/dist/components/dialog/Dialog.js.map +1 -1
  13. package/dist/components/dialog/dialog-tokens.d.ts +1 -1
  14. package/dist/components/icon-button/IconButton.d.ts +3 -0
  15. package/dist/components/icon-button/IconButton.js +3 -0
  16. package/dist/components/icon-button/IconButton.js.map +1 -1
  17. package/dist/components/list/List.d.ts +9 -0
  18. package/dist/components/list/List.js +7 -4
  19. package/dist/components/list/List.js.map +1 -1
  20. package/dist/components/list/list-styles.js +6 -6
  21. package/dist/components/list/list-styles.js.map +1 -1
  22. package/dist/components/list/list-tokens.d.ts +1 -1
  23. package/dist/components/list/list-tokens.js +50 -0
  24. package/dist/components/list/list-tokens.js.map +1 -1
  25. package/dist/components/menu/menu-tokens.d.ts +1 -1
  26. package/dist/components/navigation/NavigationRail.js +52 -15
  27. package/dist/components/navigation/NavigationRail.js.map +1 -1
  28. package/dist/components/navigation/nav-item-styles.js +4 -4
  29. package/dist/components/navigation/nav-item-styles.js.map +1 -1
  30. package/dist/components/search/SearchBar.js +19 -34
  31. package/dist/components/search/SearchBar.js.map +1 -1
  32. package/dist/components/search/SearchField.d.ts +111 -0
  33. package/dist/components/search/SearchField.js +128 -0
  34. package/dist/components/search/SearchField.js.map +1 -0
  35. package/dist/components/search/search-field-frame.js +36 -0
  36. package/dist/components/search/search-field-frame.js.map +1 -0
  37. package/dist/components/search/search-styles.d.ts +58 -0
  38. package/dist/components/search/search-styles.js +27 -2
  39. package/dist/components/search/search-styles.js.map +1 -1
  40. package/dist/components/select/search-list.js +8 -13
  41. package/dist/components/select/search-list.js.map +1 -1
  42. package/dist/components/sheet/SideSheet.d.ts +2 -0
  43. package/dist/components/sheet/SideSheet.js +1 -1
  44. package/dist/components/sheet/SideSheet.js.map +1 -1
  45. package/dist/components/snackbar/snackbar-tokens.d.ts +1 -1
  46. package/dist/components/text-field/TextField.js +19 -5
  47. package/dist/components/text-field/TextField.js.map +1 -1
  48. package/dist/components/toolbar/toolbar-styles.js +2 -2
  49. package/dist/components/toolbar/toolbar-styles.js.map +1 -1
  50. package/dist/components/tooltip/tooltip-tokens.d.ts +1 -1
  51. package/dist/index.d.ts +3 -2
  52. package/dist/index.js +3 -2
  53. package/dist/primitives/ButtonBase.js +1 -0
  54. package/dist/primitives/ButtonBase.js.map +1 -1
  55. package/dist/styles/generated/components.css +5 -0
  56. package/dist/styles/utilities.css +8 -0
  57. package/dist/styles.compiled.css +1 -1
  58. package/dist/theme/ThemeProvider.js +17 -0
  59. package/dist/theme/ThemeProvider.js.map +1 -1
  60. package/package.json +1 -1
@@ -43,15 +43,12 @@ export declare const carouselStyles: import("tailwind-variants").TVReturnType<{
43
43
  };
44
44
  false: {};
45
45
  };
46
- /** Full-bleed items fill the window edge to edge: no corners, focus ring inside. */
46
+ /** Full-bleed items fill the window edge to edge: no corners. */
47
47
  fullBleed: {
48
48
  true: {
49
49
  root: string;
50
- item: string;
51
- };
52
- false: {
53
- item: string;
54
50
  };
51
+ false: {};
55
52
  };
56
53
  }, {
57
54
  root: string[];
@@ -102,15 +99,12 @@ export declare const carouselStyles: import("tailwind-variants").TVReturnType<{
102
99
  };
103
100
  false: {};
104
101
  };
105
- /** Full-bleed items fill the window edge to edge: no corners, focus ring inside. */
102
+ /** Full-bleed items fill the window edge to edge: no corners. */
106
103
  fullBleed: {
107
104
  true: {
108
105
  root: string;
109
- item: string;
110
- };
111
- false: {
112
- item: string;
113
106
  };
107
+ false: {};
114
108
  };
115
109
  }, {
116
110
  root: string[];
@@ -161,15 +155,12 @@ export declare const carouselStyles: import("tailwind-variants").TVReturnType<{
161
155
  };
162
156
  false: {};
163
157
  };
164
- /** Full-bleed items fill the window edge to edge: no corners, focus ring inside. */
158
+ /** Full-bleed items fill the window edge to edge: no corners. */
165
159
  fullBleed: {
166
160
  true: {
167
161
  root: string;
168
- item: string;
169
- };
170
- false: {
171
- item: string;
172
162
  };
163
+ false: {};
173
164
  };
174
165
  }, {
175
166
  root: string[];
@@ -13,7 +13,7 @@ const carouselStyles = tv({
13
13
  "data-dragging:cursor-grabbing data-dragging:[scroll-snap-type:none] data-dragging:select-none",
14
14
  "[&::-webkit-scrollbar]:hidden"
15
15
  ],
16
- item: "flex shrink-0 rounded-(--m3-carousel-corner)",
16
+ item: "flex shrink-0 rounded-(--m3-carousel-corner) focus-ring-inset",
17
17
  mask: [
18
18
  "grid size-full overflow-hidden bg-surface [&>*]:[grid-area:1/1] [&>*]:size-full",
19
19
  "[--m3-carousel-item-corner:var(--m3-carousel-corner)]",
@@ -65,13 +65,10 @@ const carouselStyles = tv({
65
65
  true: { item: "cursor-pointer data-disabled:cursor-default" },
66
66
  false: {}
67
67
  },
68
- /** Full-bleed items fill the window edge to edge: no corners, focus ring inside. */
68
+ /** Full-bleed items fill the window edge to edge: no corners. */
69
69
  fullBleed: {
70
- true: {
71
- root: "[--m3-carousel-corner:0px] [--m3-carousel-pressed-corner:0px]",
72
- item: "focus-ring-inset"
73
- },
74
- false: { item: "focus-ring" }
70
+ true: { root: "[--m3-carousel-corner:0px] [--m3-carousel-pressed-corner:0px]" },
71
+ false: {}
75
72
  }
76
73
  },
77
74
  compoundVariants: [
@@ -1 +1 @@
1
- {"version":3,"file":"carousel-styles.js","names":[],"sources":["../../../src/components/carousel/carousel-styles.ts"],"sourcesContent":["import { tv, type VariantProps } from '../../utils/tv';\n\n/*\n * Values follow the M3 Expressive carousel spec (2026-10-13) and Compose Material 3\n * (carousel/Carousel.kt, Keylines.kt, Strategy.kt):\n *\n * - Multi-browse and hero: 16px leading and trailing padding, 8px top and bottom, 8px\n * between items. Uncontained (and multi-aspect): 16px leading padding only. Full-screen:\n * no padding, 16px between items and no corners. Small items are 40–56px.\n * - Snapping: hero and full-screen move one item at a time (`scroll-snap-stop: always`);\n * multi-browse flings across many items and then snaps; uncontained and multi-aspect\n * scroll freely unless `snap=\"item\"`.\n * - Uncontained (and multi-aspect) items keep one size and flow past the end edge; only\n * multi-browse and hero items follow keylines.\n * - Each item's mask is filled with `surface`, the spec's container colour, so transparent\n * or still-loading content never shows what's behind the carousel.\n * - Items are masked with 28px (extra-large) corners, as Compose's samples do with\n * `maskClip(MaterialTheme.shapes.extraLarge)`; the component token\n * `--md-comp-carousel-item-container-shape` (`carousel-tokens.ts`) sets them. A\n * pressed item's corners tighten to `--m3-carousel-pressed-corner` (20px, large-increased)\n * on the fast spatial spring, the spec's \"changes the shape slightly\".\n *\n * The carousel scrolls natively. Items keep their natural slots (the large item size), and\n * a library-owned mask layer inside each is translated and clipped to its keyline on every\n * scroll frame, so the root is never transformed. The state layer is a library-owned\n * element sharing the mask's grid cell, painted over the item (nothing is positioned).\n * Under the mask, a press area follows it, widened to 48px for a small item (40–56px):\n * M3's touch target, taken from the 8px spacing, so neighbours never overlap.\n * Every class is written out in full.\n */\n\n/** Variant definitions for {@link Carousel}. */\nexport const carouselStyles = tv({\n slots: {\n root: [\n 'flex min-h-0 min-w-0',\n '[--m3-carousel-corner:var(--_md-comp-carousel-item-container-shape)]',\n '[--m3-carousel-pressed-corner:var(--md-sys-shape-corner-large-increased)]',\n ],\n scroller: [\n 'flex min-h-0 min-w-0 flex-1 outline-none [scrollbar-width:none]',\n 'data-dragging:cursor-grabbing data-dragging:[scroll-snap-type:none] data-dragging:select-none',\n '[&::-webkit-scrollbar]:hidden',\n ],\n item: 'flex shrink-0 rounded-(--m3-carousel-corner)',\n mask: [\n 'grid size-full overflow-hidden bg-surface [&>*]:[grid-area:1/1] [&>*]:size-full',\n '[--m3-carousel-item-corner:var(--m3-carousel-corner)]',\n 'data-pressed:[--m3-carousel-item-corner:var(--m3-carousel-pressed-corner)]',\n '[transition-property:--m3-carousel-item-corner]',\n '[transition-duration:var(--md-sys-motion-spring-spatial-fast-duration)]',\n '[transition-timing-function:var(--md-sys-motion-spring-spatial-fast-easing)]',\n 'motion-reduce:[transition-duration:0s]',\n 'data-disabled:opacity-38',\n ],\n stateLayer:\n 'pointer-events-none state-layer [--m3-state-layer-color:var(--md-sys-color-on-surface)]',\n // The item's press area, laid under the mask in the same place (a negative end margin,\n // so nothing is positioned).\n hitArea: 'h-full w-full shrink-0 -me-[100%]',\n },\n variants: {\n orientation: {\n // Overscroll is contained on the carousel's own axis only, so a swipe across it\n // (a vertical swipe on a horizontal carousel) still scrolls the page (2026-10-15).\n horizontal: {\n scroller: 'flex-row overflow-x-auto overflow-y-hidden overscroll-x-contain',\n item: 'h-full',\n },\n vertical: { scroller: 'flex-col overflow-x-hidden overflow-y-auto', item: 'w-full' },\n },\n /** `single` stops at every item, `many` lets a fling cross several, `none` doesn't snap. */\n snapping: { single: {}, many: {}, none: {} },\n /** The mask is clipped by the keylines on every scroll frame; otherwise by CSS. */\n masked: {\n // Only the mask and the press area under it take presses, not the rest of the slot, so\n // a press between items never lands on an item whose slot reaches there.\n true: {\n item: 'pointer-events-none',\n mask: 'pointer-events-auto',\n hitArea: 'pointer-events-auto',\n },\n false: { mask: '[clip-path:inset(0_round_var(--m3-carousel-item-corner))]' },\n },\n /** Multi-aspect items keep their own width, between 9:16 and 16:9 of the height. */\n aspect: {\n true: {\n item: [\n 'w-max min-w-[calc(var(--m3-carousel-cross-size)*9/16)]',\n 'max-w-[calc(var(--m3-carousel-cross-size)*16/9)]',\n ],\n mask: '[&>*]:h-full [&>*]:w-auto [&>*]:min-w-full [&>*]:max-w-full [&>*]:object-cover',\n },\n false: {},\n },\n interactive: { true: { item: 'cursor-pointer data-disabled:cursor-default' }, false: {} },\n /** Full-bleed items fill the window edge to edge: no corners, focus ring inside. */\n fullBleed: {\n true: {\n root: '[--m3-carousel-corner:0px] [--m3-carousel-pressed-corner:0px]',\n item: 'focus-ring-inset',\n },\n false: { item: 'focus-ring' },\n },\n },\n compoundVariants: [\n {\n snapping: ['single', 'many'],\n orientation: 'horizontal',\n class: { scroller: 'snap-x snap-mandatory', item: 'snap-start' },\n },\n {\n snapping: ['single', 'many'],\n orientation: 'vertical',\n class: { scroller: 'snap-y snap-mandatory', item: 'snap-start' },\n },\n { snapping: 'single', class: { item: 'snap-always' } },\n // A full-screen vertical carousel fills the window, so past its last item a swipe goes\n // on to the page instead of trapping it.\n { orientation: 'vertical', fullBleed: false, class: { scroller: 'overscroll-y-contain' } },\n ],\n defaultVariants: {\n orientation: 'horizontal',\n snapping: 'single',\n masked: true,\n aspect: false,\n interactive: false,\n fullBleed: false,\n },\n});\n\n/**\n * The variants of {@link carouselStyles}, for building on its styles. They are the recipe's keys, not\n * component props: their names (`hasIcon`, `isOpen`…) follow the classes and may change.\n */\nexport type CarouselStyleProps = VariantProps<typeof carouselStyles>;\n"],"mappings":";;;AAgCA,MAAa,iBAAiB,GAAG;CAC/B,OAAO;EACL,MAAM;GACJ;GACA;GACA;EACF;EACA,UAAU;GACR;GACA;GACA;EACF;EACA,MAAM;EACN,MAAM;GACJ;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,YACE;EAGF,SAAS;CACX;CACA,UAAU;EACR,aAAa;GAGX,YAAY;IACV,UAAU;IACV,MAAM;GACR;GACA,UAAU;IAAE,UAAU;IAA8C,MAAM;GAAS;EACrF;;EAEA,UAAU;GAAE,QAAQ,CAAC;GAAG,MAAM,CAAC;GAAG,MAAM,CAAC;EAAE;;EAE3C,QAAQ;GAGN,MAAM;IACJ,MAAM;IACN,MAAM;IACN,SAAS;GACX;GACA,OAAO,EAAE,MAAM,4DAA4D;EAC7E;;EAEA,QAAQ;GACN,MAAM;IACJ,MAAM,CACJ,0DACA,kDACF;IACA,MAAM;GACR;GACA,OAAO,CAAC;EACV;EACA,aAAa;GAAE,MAAM,EAAE,MAAM,8CAA8C;GAAG,OAAO,CAAC;EAAE;;EAExF,WAAW;GACT,MAAM;IACJ,MAAM;IACN,MAAM;GACR;GACA,OAAO,EAAE,MAAM,aAAa;EAC9B;CACF;CACA,kBAAkB;EAChB;GACE,UAAU,CAAC,UAAU,MAAM;GAC3B,aAAa;GACb,OAAO;IAAE,UAAU;IAAyB,MAAM;GAAa;EACjE;EACA;GACE,UAAU,CAAC,UAAU,MAAM;GAC3B,aAAa;GACb,OAAO;IAAE,UAAU;IAAyB,MAAM;GAAa;EACjE;EACA;GAAE,UAAU;GAAU,OAAO,EAAE,MAAM,cAAc;EAAE;EAGrD;GAAE,aAAa;GAAY,WAAW;GAAO,OAAO,EAAE,UAAU,uBAAuB;EAAE;CAC3F;CACA,iBAAiB;EACf,aAAa;EACb,UAAU;EACV,QAAQ;EACR,QAAQ;EACR,aAAa;EACb,WAAW;CACb;AACF,CAAC"}
1
+ {"version":3,"file":"carousel-styles.js","names":[],"sources":["../../../src/components/carousel/carousel-styles.ts"],"sourcesContent":["import { tv, type VariantProps } from '../../utils/tv';\n\n/*\n * Values follow the M3 Expressive carousel spec (2026-10-13) and Compose Material 3\n * (carousel/Carousel.kt, Keylines.kt, Strategy.kt):\n *\n * - Multi-browse and hero: 16px leading and trailing padding, 8px top and bottom, 8px\n * between items. Uncontained (and multi-aspect): 16px leading padding only. Full-screen:\n * no padding, 16px between items and no corners. Small items are 40–56px.\n * - Snapping: hero and full-screen move one item at a time (`scroll-snap-stop: always`);\n * multi-browse flings across many items and then snaps; uncontained and multi-aspect\n * scroll freely unless `snap=\"item\"`.\n * - Uncontained (and multi-aspect) items keep one size and flow past the end edge; only\n * multi-browse and hero items follow keylines.\n * - Each item's mask is filled with `surface`, the spec's container colour, so transparent\n * or still-loading content never shows what's behind the carousel.\n * - Items are masked with 28px (extra-large) corners, as Compose's samples do with\n * `maskClip(MaterialTheme.shapes.extraLarge)`; the component token\n * `--md-comp-carousel-item-container-shape` (`carousel-tokens.ts`) sets them. A\n * pressed item's corners tighten to `--m3-carousel-pressed-corner` (20px, large-increased)\n * on the fast spatial spring, the spec's \"changes the shape slightly\".\n *\n * The carousel scrolls natively. Items keep their natural slots (the large item size), and\n * a library-owned mask layer inside each is translated and clipped to its keyline on every\n * scroll frame, so the root is never transformed. The state layer is a library-owned\n * element sharing the mask's grid cell, painted over the item (nothing is positioned).\n * Under the mask, a press area follows it, widened to 48px for a small item (40–56px):\n * M3's touch target, taken from the 8px spacing, so neighbours never overlap.\n * Every class is written out in full.\n */\n\n/** Variant definitions for {@link Carousel}. */\nexport const carouselStyles = tv({\n slots: {\n root: [\n 'flex min-h-0 min-w-0',\n '[--m3-carousel-corner:var(--_md-comp-carousel-item-container-shape)]',\n '[--m3-carousel-pressed-corner:var(--md-sys-shape-corner-large-increased)]',\n ],\n scroller: [\n 'flex min-h-0 min-w-0 flex-1 outline-none [scrollbar-width:none]',\n 'data-dragging:cursor-grabbing data-dragging:[scroll-snap-type:none] data-dragging:select-none',\n '[&::-webkit-scrollbar]:hidden',\n ],\n // The focus ring is drawn inside: items sit against the scroller's edges in every layout\n // (Compose keeps the padding in the keylines), so a ring outside was cut where they meet.\n item: 'flex shrink-0 rounded-(--m3-carousel-corner) focus-ring-inset',\n mask: [\n 'grid size-full overflow-hidden bg-surface [&>*]:[grid-area:1/1] [&>*]:size-full',\n '[--m3-carousel-item-corner:var(--m3-carousel-corner)]',\n 'data-pressed:[--m3-carousel-item-corner:var(--m3-carousel-pressed-corner)]',\n '[transition-property:--m3-carousel-item-corner]',\n '[transition-duration:var(--md-sys-motion-spring-spatial-fast-duration)]',\n '[transition-timing-function:var(--md-sys-motion-spring-spatial-fast-easing)]',\n 'motion-reduce:[transition-duration:0s]',\n 'data-disabled:opacity-38',\n ],\n stateLayer:\n 'pointer-events-none state-layer [--m3-state-layer-color:var(--md-sys-color-on-surface)]',\n // The item's press area, laid under the mask in the same place (a negative end margin,\n // so nothing is positioned).\n hitArea: 'h-full w-full shrink-0 -me-[100%]',\n },\n variants: {\n orientation: {\n // Overscroll is contained on the carousel's own axis only, so a swipe across it\n // (a vertical swipe on a horizontal carousel) still scrolls the page (2026-10-15).\n horizontal: {\n scroller: 'flex-row overflow-x-auto overflow-y-hidden overscroll-x-contain',\n item: 'h-full',\n },\n vertical: { scroller: 'flex-col overflow-x-hidden overflow-y-auto', item: 'w-full' },\n },\n /** `single` stops at every item, `many` lets a fling cross several, `none` doesn't snap. */\n snapping: { single: {}, many: {}, none: {} },\n /** The mask is clipped by the keylines on every scroll frame; otherwise by CSS. */\n masked: {\n // Only the mask and the press area under it take presses, not the rest of the slot, so\n // a press between items never lands on an item whose slot reaches there.\n true: {\n item: 'pointer-events-none',\n mask: 'pointer-events-auto',\n hitArea: 'pointer-events-auto',\n },\n false: { mask: '[clip-path:inset(0_round_var(--m3-carousel-item-corner))]' },\n },\n /** Multi-aspect items keep their own width, between 9:16 and 16:9 of the height. */\n aspect: {\n true: {\n item: [\n 'w-max min-w-[calc(var(--m3-carousel-cross-size)*9/16)]',\n 'max-w-[calc(var(--m3-carousel-cross-size)*16/9)]',\n ],\n mask: '[&>*]:h-full [&>*]:w-auto [&>*]:min-w-full [&>*]:max-w-full [&>*]:object-cover',\n },\n false: {},\n },\n interactive: { true: { item: 'cursor-pointer data-disabled:cursor-default' }, false: {} },\n /** Full-bleed items fill the window edge to edge: no corners. */\n fullBleed: {\n true: { root: '[--m3-carousel-corner:0px] [--m3-carousel-pressed-corner:0px]' },\n false: {},\n },\n },\n compoundVariants: [\n {\n snapping: ['single', 'many'],\n orientation: 'horizontal',\n class: { scroller: 'snap-x snap-mandatory', item: 'snap-start' },\n },\n {\n snapping: ['single', 'many'],\n orientation: 'vertical',\n class: { scroller: 'snap-y snap-mandatory', item: 'snap-start' },\n },\n { snapping: 'single', class: { item: 'snap-always' } },\n // A full-screen vertical carousel fills the window, so past its last item a swipe goes\n // on to the page instead of trapping it.\n { orientation: 'vertical', fullBleed: false, class: { scroller: 'overscroll-y-contain' } },\n ],\n defaultVariants: {\n orientation: 'horizontal',\n snapping: 'single',\n masked: true,\n aspect: false,\n interactive: false,\n fullBleed: false,\n },\n});\n\n/**\n * The variants of {@link carouselStyles}, for building on its styles. They are the recipe's keys, not\n * component props: their names (`hasIcon`, `isOpen`…) follow the classes and may change.\n */\nexport type CarouselStyleProps = VariantProps<typeof carouselStyles>;\n"],"mappings":";;;AAgCA,MAAa,iBAAiB,GAAG;CAC/B,OAAO;EACL,MAAM;GACJ;GACA;GACA;EACF;EACA,UAAU;GACR;GACA;GACA;EACF;EAGA,MAAM;EACN,MAAM;GACJ;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EACA,YACE;EAGF,SAAS;CACX;CACA,UAAU;EACR,aAAa;GAGX,YAAY;IACV,UAAU;IACV,MAAM;GACR;GACA,UAAU;IAAE,UAAU;IAA8C,MAAM;GAAS;EACrF;;EAEA,UAAU;GAAE,QAAQ,CAAC;GAAG,MAAM,CAAC;GAAG,MAAM,CAAC;EAAE;;EAE3C,QAAQ;GAGN,MAAM;IACJ,MAAM;IACN,MAAM;IACN,SAAS;GACX;GACA,OAAO,EAAE,MAAM,4DAA4D;EAC7E;;EAEA,QAAQ;GACN,MAAM;IACJ,MAAM,CACJ,0DACA,kDACF;IACA,MAAM;GACR;GACA,OAAO,CAAC;EACV;EACA,aAAa;GAAE,MAAM,EAAE,MAAM,8CAA8C;GAAG,OAAO,CAAC;EAAE;;EAExF,WAAW;GACT,MAAM,EAAE,MAAM,gEAAgE;GAC9E,OAAO,CAAC;EACV;CACF;CACA,kBAAkB;EAChB;GACE,UAAU,CAAC,UAAU,MAAM;GAC3B,aAAa;GACb,OAAO;IAAE,UAAU;IAAyB,MAAM;GAAa;EACjE;EACA;GACE,UAAU,CAAC,UAAU,MAAM;GAC3B,aAAa;GACb,OAAO;IAAE,UAAU;IAAyB,MAAM;GAAa;EACjE;EACA;GAAE,UAAU;GAAU,OAAO,EAAE,MAAM,cAAc;EAAE;EAGrD;GAAE,aAAa;GAAY,WAAW;GAAO,OAAO,EAAE,UAAU,uBAAuB;EAAE;CAC3F;CACA,iBAAiB;EACf,aAAa;EACb,UAAU;EACV,QAAQ;EACR,QAAQ;EACR,aAAa;EACb,WAAW;CACb;AACF,CAAC"}
@@ -2,6 +2,6 @@ import { ComponentTokenSet } from "../../tokens/component.js";
2
2
  import "../../index.js";
3
3
  //#region src/components/checkbox/checkbox-tokens.d.ts
4
4
  /** The tokens of {@link Checkbox}: `--md-comp-checkbox-<part>`. */
5
- export declare const checkboxTokenSet: ComponentTokenSet<"selected-icon-color" | "selected-container-color" | "unselected-outline-color">;
5
+ export declare const checkboxTokenSet: ComponentTokenSet<"selected-container-color" | "selected-icon-color" | "unselected-outline-color">;
6
6
  //#endregion
7
7
  //# sourceMappingURL=checkbox-tokens.d.ts.map
@@ -2,12 +2,12 @@ import { ComponentTokenSet } from "../../tokens/component.js";
2
2
  import "../../index.js";
3
3
  //#region src/components/chip/chip-tokens.d.ts
4
4
  /** The tokens of {@link AssistChip}: `--md-comp-assist-chip-*`. */
5
- export declare const assistChipTokenSet: ComponentTokenSet<"label-text-color" | "container-shape" | "with-icon-icon-color" | "flat-outline-color" | "elevated-container-color">;
5
+ export declare const assistChipTokenSet: ComponentTokenSet<"container-shape" | "label-text-color" | "with-icon-icon-color" | "flat-outline-color" | "elevated-container-color">;
6
6
  /** The tokens of {@link SuggestionChip}: `--md-comp-suggestion-chip-*`. */
7
- export declare const suggestionChipTokenSet: ComponentTokenSet<"label-text-color" | "container-shape" | "flat-outline-color" | "elevated-container-color" | "with-leading-icon-leading-icon-color">;
7
+ export declare const suggestionChipTokenSet: ComponentTokenSet<"container-shape" | "label-text-color" | "flat-outline-color" | "elevated-container-color" | "with-leading-icon-leading-icon-color">;
8
8
  /** The tokens of {@link FilterChip}: `--md-comp-filter-chip-*`. */
9
- export declare const filterChipTokenSet: ComponentTokenSet<"selected-label-text-color" | "unselected-label-text-color" | "container-shape" | "with-leading-icon-unselected-leading-icon-color" | "flat-unselected-outline-color" | "flat-selected-container-color" | "elevated-unselected-container-color">;
9
+ export declare const filterChipTokenSet: ComponentTokenSet<"container-shape" | "selected-label-text-color" | "unselected-label-text-color" | "with-leading-icon-unselected-leading-icon-color" | "flat-unselected-outline-color" | "flat-selected-container-color" | "elevated-unselected-container-color">;
10
10
  /** The tokens of {@link InputChip}: `--md-comp-input-chip-*`. */
11
- export declare const inputChipTokenSet: ComponentTokenSet<"selected-container-color" | "selected-label-text-color" | "unselected-label-text-color" | "container-shape" | "unselected-outline-color">;
11
+ export declare const inputChipTokenSet: ComponentTokenSet<"container-shape" | "selected-container-color" | "selected-label-text-color" | "unselected-label-text-color" | "unselected-outline-color">;
12
12
  //#endregion
13
13
  //# sourceMappingURL=chip-tokens.d.ts.map
@@ -381,11 +381,18 @@ function RangeMonthList({ state, styles, className, classNames }) {
381
381
  useLayoutEffect(() => {
382
382
  const list = listRef.current;
383
383
  if (!list) return;
384
+ let opened = list.getClientRects().length > 0;
384
385
  list.scrollTop = initialTop.current;
385
- const measure = () => setView({
386
- top: list.scrollTop,
387
- height: list.clientHeight
388
- });
386
+ const measure = () => {
387
+ if (!opened && list.clientHeight > 0) {
388
+ opened = true;
389
+ list.scrollTop = initialTop.current;
390
+ }
391
+ setView({
392
+ top: list.scrollTop,
393
+ height: list.clientHeight
394
+ });
395
+ };
389
396
  measure();
390
397
  const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(measure);
391
398
  observer?.observe(list);
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.js","names":[],"sources":["../../../src/components/date-picker/DatePicker.tsx"],"sourcesContent":["'use client';\n\nimport {\n CalendarDate,\n createCalendar,\n getLocalTimeZone,\n maxDate,\n minDate,\n startOfWeek,\n toCalendarDate,\n today,\n type DateValue,\n} from '@internationalized/date';\nimport {\n useContext,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n type TransitionEvent,\n} from 'react';\nimport {\n mergeProps,\n useCalendar,\n useDateFormatter,\n useLocale,\n useRangeCalendar,\n type AriaButtonProps,\n} from 'react-aria';\nimport {\n useCalendarState,\n useRangeCalendarState,\n type CalendarState,\n type RangeCalendarState,\n} from 'react-stately';\nimport { useControlledState } from 'react-stately/useControlledState';\nimport { DomDirectionLocale } from '../../primitives/DomDirectionLocale';\nimport { useSizeTransform } from './use-size-transform';\nimport { useViewExit } from './use-view-exit';\nimport { usePresence } from '../../primitives/use-presence';\nimport { cn } from '../../utils/cn';\nimport { mergeDataTokens } from '../../utils/merge-data-tokens';\nimport {\n splitRootProps,\n type DescriptionAria,\n type WrapperRootDOMProps,\n} from '../../utils/root-props';\nimport { Button } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport { LazyTooltip } from '../tooltip/lazy-tooltip';\nimport { TooltipTrigger } from '../tooltip/tooltip-trigger';\nimport { CalendarGrid } from './CalendarGrid';\nimport { ChoiceButton, ShortcutIconButton, useMonthSwipe, usePickerKeys } from './calendar-parts';\nimport type { Density } from '../../tokens/density';\nimport { DateInput, type DateInputLabels } from './DateInput';\nimport { datePickerStyles } from './date-picker-styles';\nimport { PickerDialogContext } from './picker-dialog-context';\nimport {\n ArrowDropDownIcon,\n CalendarIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n EditIcon,\n} from './picker-icons';\n\n/** The picker's labels, for localisation. */\nexport interface DatePickerLabels extends DateInputLabels {\n /** The header's title in calendar mode. @default \"Select date\", or \"Select dates\" for a range */\n title: string;\n /**\n * The title in text input mode (the M3 modal date input's \"Enter date\").\n * @default \"Enter date\", or \"Enter dates\" for a range\n */\n inputTitle: string;\n /** Headline when nothing is selected. @default \"Selected date\" / \"Start date – End date\" */\n noSelection: string;\n /** The previous month button. @default \"Previous month\" */\n previousMonth: string;\n /** The next month button. @default \"Next month\" */\n nextMonth: string;\n /** Tooltip of the previous-month button, naming its shortcut. @default \"Previous month (Page Up)\" */\n previousMonthTooltip: string;\n /** Tooltip of the next-month button, naming its shortcut. @default \"Next month (Page Down)\" */\n nextMonthTooltip: string;\n /** The month and year button while the days show. @default \"Switch to selecting a year\" */\n showYears: string;\n /** The month and year button while the years show. @default \"Switch to selecting a day\" */\n showDays: string;\n /** Tooltip of the month and year button, naming its shortcut. @default \"Choose a year (Shift+Y)\" */\n yearsTooltip: string;\n /** Name of the year list. @default \"Year\" */\n yearList: string;\n /** The mode toggle in calendar mode. @default \"Switch to text input mode\" */\n inputMode: string;\n /** The mode toggle in text input mode. @default \"Switch to calendar input mode\" */\n calendarMode: string;\n /** Label of the input mode's field. @default \"Date\" */\n dateLabel: string;\n /** Label of a range's start field in input mode. @default \"Start date\" */\n startDateLabel: string;\n /**\n * Label of a range's end field in input mode, and the headline's end while a range is\n * being picked (\"Mar 20 – End date\"). @default \"End date\"\n */\n endDateLabel: string;\n}\n\nexport interface DatePickerClassNames {\n /** The picker's root; `className` is merged here too. */\n root?: string;\n /** The header: title, headline and mode toggle. */\n header?: string;\n /** The header's title (\"Select date\"). */\n title?: string;\n /** The header's headline: the chosen date or range. */\n headline?: string;\n /** The calendar or the text input below the header. */\n body?: string;\n /** The weekday names above the days. */\n weekday?: string;\n /** Each day of the calendar. */\n day?: string;\n /** Each year of the year list. */\n year?: string;\n /** The month and year button above the days, which shows the year list. */\n yearButton?: string;\n /** Each month's subhead in the range picker's scrolling month list. */\n monthSubhead?: string;\n}\n\nexport interface DateRangePickerClassNames extends DatePickerClassNames {\n /**\n * The band behind a range's days: each calendar cell it spans (`data-range` is `start`,\n * `middle` or `end`), whose background paints it.\n */\n rangeBand?: string;\n}\n\n// No `aria-description` and the like: the picker's root is a plain container, and no single\n// element in it stands for the whole picker.\ninterface DatePickerCommonProps extends Omit<WrapperRootDOMProps, DescriptionAria> {\n /** Earliest date allowed; earlier days are disabled. */\n min?: DateValue;\n /** Latest date allowed; later days are disabled. */\n max?: DateValue;\n /** Returns `true` for a day that can't be picked (it shows disabled). */\n isDateUnavailable?: (date: DateValue) => boolean;\n /** Show the header (title, headline and mode toggle). @default true */\n header?: boolean;\n /** Show the calendar ↔ text input toggle. @default true */\n modeToggle?: boolean;\n /** Start in calendar or text input mode. @default \"calendar\" */\n defaultMode?: 'calendar' | 'input';\n /**\n * First and last years of the year list (and of a range's month list). Years outside\n * `min` / `max` are shown disabled. @default [1900, 2100]\n */\n yearRange?: [number, number];\n /** Words the picker shows and announces, with English defaults. */\n labels?: Partial<DatePickerLabels>;\n /**\n * Web density of the input mode's text fields, `0` to `-3`: each step takes 4px off them\n * (56px at 0, 44px at -3). The calendar keeps its size: M3 doesn't make date pickers denser,\n * since their 48px day targets are part of their accessibility. Left out, the fields take\n * the density of the nearest `ThemeProvider` or `ThemeScope`.\n * @default 0\n */\n density?: Density;\n /** The root `<div>`'s id. */\n id?: string;\n /** Ref to the root `<div>` element. */\n ref?: Ref<HTMLDivElement>;\n /** Classes for the root element, merged with `classNames.root`; consumer classes win. */\n className?: string;\n /** Inline styles for the root element. */\n style?: CSSProperties;\n /** Classes for each part, by slot. */\n classNames?: DatePickerClassNames;\n /** `data-*` attributes go to the root. */\n [data: `data-${string}`]: string | number | boolean | undefined;\n}\n\nexport type DatePickerProps = DatePickerCommonProps & {\n /** The selected date (controlled); `null` for none. */\n value?: CalendarDate | null;\n /** Initial date when uncontrolled. @default null */\n defaultValue?: CalendarDate | null;\n /** Called with the date the user picks or types. */\n onChange?: (value: CalendarDate) => void;\n};\n\nexport interface DateRange {\n start: CalendarDate;\n end: CalendarDate;\n}\n\nexport type DateRangePickerProps = Omit<DatePickerCommonProps, 'classNames'> & {\n /** Classes for each part, by slot. */\n classNames?: DateRangePickerClassNames;\n /** The selected range (controlled); `null` for none. */\n value?: DateRange | null;\n /** Initial range when uncontrolled. @default null */\n defaultValue?: DateRange | null;\n /** Called with the range once both its start and end are picked or typed. */\n onChange?: (value: DateRange) => void;\n /**\n * `scroll` lists the months one under another and scrolls vertically, as the M3 modal\n * range picker does; `paged` shows one month at a time with previous / next buttons and\n * a year list, like the date picker. @default \"scroll\"\n */\n monthLayout?: 'scroll' | 'paged';\n};\n\n/**\n * M3 modal date picker (Compose's `DatePicker`): a header with the selected date, a month\n * grid you page with the arrows, a horizontal swipe or Page Up / Down, a year list, and a\n * text input mode. Put it in a {@link PickerDialog} for the modal form; {@link DateField}\n * is the docked form. Values are `@internationalized/date` dates.\n *\n * @example\n * <DatePicker value={date} onChange={setDate} />\n */\nexport function DatePicker(props: DatePickerProps) {\n return (\n <DomDirectionLocale>\n {(directionRef) => <SingleDatePicker {...props} directionRef={directionRef} />}\n </DomDirectionLocale>\n );\n}\n\n/**\n * M3 date range picker (Compose's `DateRangePicker`): select a start and an end date on a\n * vertically scrolling list of months, or type them in input mode.\n *\n * @example\n * <DateRangePicker value={range} onChange={setRange} />\n */\nexport function DateRangePicker(props: DateRangePickerProps) {\n return (\n <DomDirectionLocale>\n {(directionRef) => <RangeDatePicker {...props} directionRef={directionRef} />}\n </DomDirectionLocale>\n );\n}\n\ntype Inner<P> = P & { directionRef: (element: HTMLElement | null) => void };\n\nfunction SingleDatePicker(props: Inner<DatePickerProps>) {\n const { locale } = useLocale();\n const confirm = useContext(PickerDialogContext);\n const [value, setValue] = useControlledState(\n props.value,\n props.defaultValue ?? null,\n props.onChange as (value: CalendarDate | null) => void,\n );\n const state = useCalendarState({\n value,\n onChange: (date) => setValue(date as CalendarDate),\n minValue: props.min,\n maxValue: props.max,\n isDateUnavailable: props.isDateUnavailable,\n locale,\n createCalendar,\n });\n const formatter = useDateFormatter({ dateStyle: 'medium' });\n const labels = props.labels ?? {};\n const headline = value\n ? formatter.format(value.toDate(getLocalTimeZone()))\n : (labels.noSelection ?? 'Selected date');\n return (\n <PickerFrame\n {...props}\n range={false}\n state={state}\n headline={headline}\n input={\n <DateInput\n label={labels.dateLabel ?? 'Date'}\n value={value}\n onCommit={(date) => date && setValue(date)}\n onEnter={(date) => date && confirm?.requestConfirm()}\n min={props.min}\n max={props.max}\n isDateUnavailable={props.isDateUnavailable}\n labels={labels}\n density={props.density}\n className=\"w-full\"\n />\n }\n />\n );\n}\n\n/** Whole months from `from` to `to`. */\nconst monthsBetween = (from: CalendarDate, to: CalendarDate) =>\n (to.year - from.year) * 12 + (to.month - from.month);\n\nfunction RangeDatePicker({ monthLayout = 'scroll', ...props }: Inner<DateRangePickerProps>) {\n const { locale } = useLocale();\n const confirm = useContext(PickerDialogContext);\n const [value, setValue] = useControlledState(\n props.value,\n props.defaultValue ?? null,\n props.onChange as (value: DateRange | null) => void,\n );\n // The scrolling list shows every month of the year range (within min / max) at once.\n const [firstYear, lastYear] = props.yearRange ?? [1900, 2100];\n const scroll = monthLayout === 'scroll';\n const listStart = maxDate(\n new CalendarDate(firstYear, 1, 1),\n props.min ? toCalendarDate(props.min) : null,\n )!;\n const listEnd = minDate(\n new CalendarDate(lastYear, 12, 31),\n props.max ? toCalendarDate(props.max) : null,\n )!;\n const state = useRangeCalendarState({\n value,\n onChange: (range) => setValue(range as DateRange),\n minValue: scroll ? listStart : props.min,\n maxValue: scroll ? listEnd : props.max,\n isDateUnavailable: props.isDateUnavailable,\n visibleDuration: scroll ? { months: monthsBetween(listStart, listEnd) + 1 } : undefined,\n locale,\n createCalendar,\n });\n const formatter = useDateFormatter({ month: 'short', day: 'numeric' });\n const labels = props.labels ?? {};\n const format = (date: CalendarDate) => formatter.format(date.toDate(getLocalTimeZone()));\n // While a new range is being picked, its first day is the start and the end is still open\n // (Compose's headline: \"Mar 20 – End date\"), not the range it replaces.\n const anchor = state.anchorDate;\n const headline = anchor\n ? `${format(anchor)} – ${labels.endDateLabel ?? 'End date'}`\n : value\n ? `${format(value.start)} – ${format(value.end)}`\n : (labels.noSelection ?? 'Start date – End date');\n const common = {\n min: props.min,\n max: props.max,\n isDateUnavailable: props.isDateUnavailable,\n labels,\n density: props.density,\n className: 'w-full',\n };\n return (\n <PickerFrame\n {...props}\n range\n scroll={scroll}\n state={state}\n headline={headline}\n input={\n <>\n <DateInput\n {...common}\n label={labels.startDateLabel ?? 'Start date'}\n value={value?.start ?? null}\n onCommit={(start) =>\n start && setValue({ start, end: value && value.end >= start ? value.end : start })\n }\n />\n <DateInput\n {...common}\n label={labels.endDateLabel ?? 'End date'}\n value={value?.end ?? null}\n onCommit={(end) =>\n end && setValue({ start: value && value.start <= end ? value.start : end, end })\n }\n onEnter={(end) => end && value && confirm?.requestConfirm()}\n />\n </>\n }\n />\n );\n}\n\nfunction PickerFrame({\n range,\n scroll = false,\n state,\n headline,\n input,\n header = true,\n modeToggle = true,\n defaultMode = 'calendar',\n yearRange = [1900, 2100],\n labels = {},\n id,\n ref,\n className,\n style,\n classNames,\n directionRef,\n ...rest\n}: Inner<Omit<DatePickerCommonProps, 'classNames'>> & {\n classNames?: DateRangePickerClassNames | undefined;\n range: boolean;\n scroll?: boolean;\n state: CalendarState | RangeCalendarState;\n headline: string;\n input: ReactNode;\n value?: unknown;\n defaultValue?: unknown;\n onChange?: unknown;\n}) {\n const { root: data } = splitRootProps(rest, { wrapper: true });\n const [mode, setMode] = useState(defaultMode);\n // Set once the mode has been switched, so only a switch animates (not the first render).\n const [switched, setSwitched] = useState(false);\n const [years, setYears] = useState(false);\n // The picker's height follows the view on the default spatial spring (Compose's\n // `SizeTransform` in its display mode animation), as the views swap.\n const { attach: attachSize, capture: captureSize } = useSizeTransform<HTMLDivElement>(mode);\n // The outgoing view fades out as it slides away (Compose: up 48px as the input comes in,\n // down by its whole height as the calendar comes back), clipped with the new one.\n const {\n attachView: attachExitView,\n attachSlot: attachExitSlot,\n capture: captureExit,\n } = useViewExit(mode);\n const styles = datePickerStyles({ range });\n const title =\n mode === 'input'\n ? (labels.inputTitle ?? (range ? 'Enter dates' : 'Enter date'))\n : (labels.title ?? (range ? 'Select dates' : 'Select date'));\n const bodyProps = {\n styles,\n years,\n setYears,\n yearRange,\n labels,\n className: classNames?.body,\n classNames,\n };\n return (\n <div\n {...data}\n id={id}\n ref={(element) => {\n attachSize(element);\n directionRef(element);\n if (typeof ref === 'function') ref(element);\n else if (ref) ref.current = element;\n }}\n style={style}\n // The modal date picker's component tokens (date-picker-tokens.ts).\n data-tokens={mergeDataTokens('md-comp-date-picker-modal', data)}\n data-years={years || undefined}\n data-mode={mode}\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n {header && (\n <div className={styles.header({ class: classNames?.header })}>\n <div className={styles.title({ class: classNames?.title })}>{title}</div>\n <div className={styles.headlineRow()}>\n <div\n aria-live=\"polite\"\n data-slot=\"headline\"\n className={styles.headline({ class: classNames?.headline })}\n >\n {headline}\n </div>\n {modeToggle && (\n <IconButton\n variant=\"standard\"\n // The picker's surface isn't dense, only its input mode's fields.\n density={0}\n icon={mode === 'calendar' ? <EditIcon /> : <CalendarIcon />}\n aria-label={\n mode === 'calendar'\n ? (labels.inputMode ?? 'Switch to text input mode')\n : (labels.calendarMode ?? 'Switch to calendar input mode')\n }\n onPress={() => {\n captureSize();\n captureExit(mode === 'calendar' ? '-48px' : '100%');\n setSwitched(true);\n setMode(mode === 'calendar' ? 'input' : 'calendar');\n }}\n />\n )}\n </div>\n </div>\n )}\n <div className={styles.modeStack()}>\n <div\n key={mode}\n ref={attachExitView}\n data-enter={switched ? mode : undefined}\n className={styles.modeView()}\n >\n {mode === 'input' ? (\n <div className={styles.input({ class: classNames?.body })}>{input}</div>\n ) : range && scroll ? (\n <RangeMonthList state={state as RangeCalendarState} {...bodyProps} />\n ) : range ? (\n <RangeCalendarBody state={state as RangeCalendarState} {...bodyProps} />\n ) : (\n <SingleCalendarBody state={state as CalendarState} {...bodyProps} />\n )}\n </div>\n <div ref={attachExitSlot} aria-hidden=\"true\" inert className={styles.modeExit()} />\n </div>\n </div>\n );\n}\n\ninterface BodyProps {\n styles: ReturnType<typeof datePickerStyles>;\n years: boolean;\n setYears: (open: boolean) => void;\n yearRange: [number, number];\n labels: Partial<DatePickerLabels>;\n className?: string | undefined;\n classNames?: DateRangePickerClassNames | undefined;\n}\n\nfunction SingleCalendarBody({ state, ...props }: BodyProps & { state: CalendarState }) {\n const { calendarProps, prevButtonProps, nextButtonProps } = useCalendar({}, state);\n return (\n <CalendarBody\n {...props}\n state={state}\n calendarProps={calendarProps}\n prevButtonProps={prevButtonProps}\n nextButtonProps={nextButtonProps}\n />\n );\n}\n\nfunction RangeCalendarBody({ state, ...props }: BodyProps & { state: RangeCalendarState }) {\n const ref = useRef<HTMLDivElement>(null);\n const { calendarProps, prevButtonProps, nextButtonProps } = useRangeCalendar({}, state, ref);\n return (\n <CalendarBody\n {...props}\n bodyRef={ref}\n state={state}\n calendarProps={calendarProps}\n prevButtonProps={prevButtonProps}\n nextButtonProps={nextButtonProps}\n />\n );\n}\n\nfunction CalendarBody({\n state,\n calendarProps,\n prevButtonProps,\n nextButtonProps,\n styles,\n years,\n setYears,\n yearRange,\n labels,\n className,\n classNames,\n bodyRef,\n}: BodyProps & {\n state: CalendarState | RangeCalendarState;\n calendarProps: HTMLAttributes<HTMLElement>;\n prevButtonProps: AriaButtonProps;\n nextButtonProps: AriaButtonProps;\n bodyRef?: Ref<HTMLDivElement>;\n}) {\n const confirm = useContext(PickerDialogContext);\n const monthFormatter = useDateFormatter({ month: 'long', year: 'numeric' });\n const monthLabel = monthFormatter.format(state.visibleRange.start.toDate(getLocalTimeZone()));\n const menuRef = useRef<HTMLButtonElement>(null);\n const [focusYears, setFocusYears] = useState(false);\n // Compose shrinks the year list and fades it out (`shrinkVertically` + `fadeOut`); the\n // first of the two transitions to end removes it.\n const yearsPresence = usePresence(years, ['clip-path', 'opacity']);\n const { swipeProps, slideKey, slideDirection } = useMonthSwipe(state);\n const onKeyDownCapture = usePickerKeys(state, {\n onConfirm: confirm?.requestConfirm,\n onMonthMenu: () => menuRef.current?.focus(),\n onYearMenu: () => {\n setFocusYears(true);\n setYears(true);\n },\n });\n return (\n <div\n {...calendarProps}\n ref={bodyRef}\n onKeyDownCapture={onKeyDownCapture}\n className={styles.body({ class: className })}\n >\n <div className={styles.nav()}>\n <TooltipTrigger>\n <Button\n ref={menuRef}\n variant=\"text\"\n className={cn('text-on-surface-variant', classNames?.yearButton)}\n aria-label={`${monthLabel}, ${years ? (labels.showDays ?? 'Switch to selecting a day') : (labels.showYears ?? 'Switch to selecting a year')}`}\n onPress={() => {\n setFocusYears(false);\n setYears(!years);\n }}\n >\n {/* The drop-down arrow trails the label here, which Button's one leading icon can't do. */}\n <span className=\"inline-flex items-center gap-[8px]\">\n <span aria-live=\"polite\">{monthLabel}</span>\n <span\n aria-hidden=\"true\"\n className=\"inline-flex size-[20px] items-center justify-center\"\n >\n <span className={styles.yearButtonIcon()}>\n <ArrowDropDownIcon />\n </span>\n </span>\n </span>\n </Button>\n <LazyTooltip>{labels.yearsTooltip ?? 'Choose a year (Shift+Y)'}</LazyTooltip>\n </TooltipTrigger>\n {!years && (\n <div className={styles.navButtons()}>\n <ShortcutIconButton\n icon={<ChevronLeftIcon />}\n label={labels.previousMonth ?? 'Previous month'}\n tooltip={labels.previousMonthTooltip ?? 'Previous month (Page Up)'}\n onPress={prevButtonProps.onPress as () => void}\n disabled={prevButtonProps.isDisabled}\n />\n <ShortcutIconButton\n icon={<ChevronRightIcon />}\n label={labels.nextMonth ?? 'Next month'}\n tooltip={labels.nextMonthTooltip ?? 'Next month (Page Down)'}\n onPress={nextButtonProps.onPress as () => void}\n disabled={nextButtonProps.isDisabled}\n />\n </div>\n )}\n </div>\n {!years && (\n <div {...swipeProps} className={styles.swipe()}>\n <div key={slideKey} data-direction={slideDirection} className={styles.slide()}>\n <CalendarGrid state={state} styles={styles} classNames={classNames} />\n </div>\n </div>\n )}\n {/* Closing, the list stays over the grid until it has shrunk and faded away. */}\n {yearsPresence.isPresent && (\n <YearList\n state={state}\n styles={styles}\n yearRange={yearRange}\n className={classNames?.year}\n label={labels.yearList ?? 'Year'}\n autoFocus={focusYears}\n exiting={yearsPresence.isExiting}\n exitProps={yearsPresence.exitProps}\n onPick={() => setYears(false)}\n />\n )}\n </div>\n );\n}\n\n/**\n * The range picker's months, one under another in a vertical scroll (M3: \"To navigate\n * across months, scroll vertically\"), under a single weekday row. Only the months in view\n * (and the focused one) are rendered; the rest are spacers of the same fixed height.\n */\nfunction RangeMonthList({\n state,\n styles,\n className,\n classNames,\n}: BodyProps & { state: RangeCalendarState }) {\n const confirm = useContext(PickerDialogContext);\n const ref = useRef<HTMLDivElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const { calendarProps } = useRangeCalendar({}, state, ref);\n const { locale } = useLocale();\n const first = state.visibleRange.start;\n const count = monthsBetween(first, state.visibleRange.end) + 1;\n const focusedIndex = monthsBetween(first, state.focusedDate);\n const [view, setView] = useState(() => ({ top: focusedIndex * MONTH_HEIGHT, height: 0 }));\n const weekdays = useDateFormatter({ weekday: 'narrow' });\n const longWeekdays = useDateFormatter({ weekday: 'long' });\n const subhead = useDateFormatter({ month: 'long', year: 'numeric' });\n const onKeyDownCapture = usePickerKeys(state, {\n onConfirm: confirm?.requestConfirm,\n onMonthMenu: () => undefined,\n onYearMenu: () => undefined,\n });\n\n // Open on the focused month (the range's start, or today), then follow the scroll.\n const initialTop = useRef(view.top);\n useLayoutEffect(() => {\n const list = listRef.current;\n if (!list) return;\n list.scrollTop = initialTop.current;\n const measure = () => setView({ top: list.scrollTop, height: list.clientHeight });\n measure();\n const observer = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(measure);\n observer?.observe(list);\n list.addEventListener('scroll', measure, { passive: true });\n return () => {\n observer?.disconnect();\n list.removeEventListener('scroll', measure);\n };\n }, []);\n\n const height = view.height || MONTH_HEIGHT;\n let from = Math.max(0, Math.floor(view.top / MONTH_HEIGHT) - 1);\n let to = Math.min(count - 1, Math.floor((view.top + height) / MONTH_HEIGHT) + 1);\n if (state.isFocused) {\n from = Math.min(from, focusedIndex);\n to = Math.max(to, focusedIndex);\n }\n const weekStart = startOfWeek(today(getLocalTimeZone()), locale);\n\n return (\n <div\n {...mergeProps(calendarProps, { onKeyDownCapture })}\n ref={ref}\n className={styles.body({ class: cn('min-h-0 flex-1', className) })}\n >\n <div aria-hidden=\"true\" className={styles.weekdayRow()}>\n {Array.from({ length: 7 }, (_, index) => {\n const day = weekStart.add({ days: index }).toDate(getLocalTimeZone());\n return (\n <span\n key={index}\n title={longWeekdays.format(day)}\n className={styles.weekdayCell({ class: classNames?.weekday })}\n >\n {weekdays.format(day)}\n </span>\n );\n })}\n </div>\n <div ref={listRef} className={styles.months()}>\n <div style={{ height: from * MONTH_HEIGHT }} />\n {Array.from({ length: to - from + 1 }, (_, i) => {\n const month = first.add({ months: from + i });\n return (\n <div key={month.toString()} className=\"h-[336px]\">\n <div\n aria-hidden=\"true\"\n className={styles.monthSubhead({ class: classNames?.monthSubhead })}\n >\n {subhead.format(month.toDate(getLocalTimeZone()))}\n </div>\n <CalendarGrid state={state} styles={styles} month={month} classNames={classNames} />\n </div>\n );\n })}\n <div style={{ height: (count - 1 - to) * MONTH_HEIGHT }} />\n </div>\n </div>\n );\n}\n\n/** A month in the scrolling list: its 48px subhead and six 48px weeks. */\nconst MONTH_HEIGHT = 336;\n\nfunction YearList({\n state,\n styles,\n yearRange,\n className,\n label,\n autoFocus,\n exiting,\n exitProps,\n onPick,\n}: {\n state: CalendarState | RangeCalendarState;\n styles: ReturnType<typeof datePickerStyles>;\n yearRange: [number, number];\n className: string | undefined;\n label: string;\n autoFocus: boolean;\n /** Closing: drawn over the grid, out of the accessibility tree and taking no presses. */\n exiting: boolean;\n exitProps: { onTransitionEnd: (event: TransitionEvent<HTMLElement>) => void };\n onPick: () => void;\n}) {\n const current = today(getLocalTimeZone()).year;\n const focusedYear = state.focusedDate.year;\n const minYear = state.minValue?.year ?? -Infinity;\n const maxYear = state.maxValue?.year ?? Infinity;\n return (\n <div\n {...exitProps}\n role=\"radiogroup\"\n aria-label={label}\n aria-hidden={exiting || undefined}\n inert={exiting || undefined}\n data-exiting={exiting || undefined}\n className={styles.years()}\n ref={(element) => {\n if (exiting) return;\n // Open on the focused year, as Compose scrolls the year list to it.\n const selected = element?.querySelector<HTMLElement>('[aria-checked=\"true\"]');\n selected?.scrollIntoView?.({ block: 'center' });\n if (autoFocus) selected?.focus({ preventScroll: true });\n }}\n >\n {Array.from({ length: yearRange[1] - yearRange[0] + 1 }, (_, i) => yearRange[0] + i).map(\n (year) => (\n <ChoiceButton\n key={year}\n selected={year === focusedYear}\n disabled={year < minYear || year > maxYear}\n data-current={year === current || undefined}\n steps={YEAR_STEPS}\n className={styles.year({ class: className })}\n onPick={() => {\n state.setFocusedDate(state.focusedDate.set({ year }));\n onPick();\n }}\n >\n {year}\n </ChoiceButton>\n ),\n )}\n </div>\n );\n}\n\n/** Three years to a row. */\nconst YEAR_STEPS = { ArrowLeft: -1, ArrowRight: 1, ArrowUp: -3, ArrowDown: 3 };\n"],"mappings":"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"}
1
+ {"version":3,"file":"DatePicker.js","names":[],"sources":["../../../src/components/date-picker/DatePicker.tsx"],"sourcesContent":["'use client';\n\nimport {\n CalendarDate,\n createCalendar,\n getLocalTimeZone,\n maxDate,\n minDate,\n startOfWeek,\n toCalendarDate,\n today,\n type DateValue,\n} from '@internationalized/date';\nimport {\n useContext,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type HTMLAttributes,\n type ReactNode,\n type Ref,\n type TransitionEvent,\n} from 'react';\nimport {\n mergeProps,\n useCalendar,\n useDateFormatter,\n useLocale,\n useRangeCalendar,\n type AriaButtonProps,\n} from 'react-aria';\nimport {\n useCalendarState,\n useRangeCalendarState,\n type CalendarState,\n type RangeCalendarState,\n} from 'react-stately';\nimport { useControlledState } from 'react-stately/useControlledState';\nimport { DomDirectionLocale } from '../../primitives/DomDirectionLocale';\nimport { useSizeTransform } from './use-size-transform';\nimport { useViewExit } from './use-view-exit';\nimport { usePresence } from '../../primitives/use-presence';\nimport { cn } from '../../utils/cn';\nimport { mergeDataTokens } from '../../utils/merge-data-tokens';\nimport {\n splitRootProps,\n type DescriptionAria,\n type WrapperRootDOMProps,\n} from '../../utils/root-props';\nimport { Button } from '../button/Button';\nimport { IconButton } from '../icon-button/IconButton';\nimport { LazyTooltip } from '../tooltip/lazy-tooltip';\nimport { TooltipTrigger } from '../tooltip/tooltip-trigger';\nimport { CalendarGrid } from './CalendarGrid';\nimport { ChoiceButton, ShortcutIconButton, useMonthSwipe, usePickerKeys } from './calendar-parts';\nimport type { Density } from '../../tokens/density';\nimport { DateInput, type DateInputLabels } from './DateInput';\nimport { datePickerStyles } from './date-picker-styles';\nimport { PickerDialogContext } from './picker-dialog-context';\nimport {\n ArrowDropDownIcon,\n CalendarIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n EditIcon,\n} from './picker-icons';\n\n/** The picker's labels, for localisation. */\nexport interface DatePickerLabels extends DateInputLabels {\n /** The header's title in calendar mode. @default \"Select date\", or \"Select dates\" for a range */\n title: string;\n /**\n * The title in text input mode (the M3 modal date input's \"Enter date\").\n * @default \"Enter date\", or \"Enter dates\" for a range\n */\n inputTitle: string;\n /** Headline when nothing is selected. @default \"Selected date\" / \"Start date – End date\" */\n noSelection: string;\n /** The previous month button. @default \"Previous month\" */\n previousMonth: string;\n /** The next month button. @default \"Next month\" */\n nextMonth: string;\n /** Tooltip of the previous-month button, naming its shortcut. @default \"Previous month (Page Up)\" */\n previousMonthTooltip: string;\n /** Tooltip of the next-month button, naming its shortcut. @default \"Next month (Page Down)\" */\n nextMonthTooltip: string;\n /** The month and year button while the days show. @default \"Switch to selecting a year\" */\n showYears: string;\n /** The month and year button while the years show. @default \"Switch to selecting a day\" */\n showDays: string;\n /** Tooltip of the month and year button, naming its shortcut. @default \"Choose a year (Shift+Y)\" */\n yearsTooltip: string;\n /** Name of the year list. @default \"Year\" */\n yearList: string;\n /** The mode toggle in calendar mode. @default \"Switch to text input mode\" */\n inputMode: string;\n /** The mode toggle in text input mode. @default \"Switch to calendar input mode\" */\n calendarMode: string;\n /** Label of the input mode's field. @default \"Date\" */\n dateLabel: string;\n /** Label of a range's start field in input mode. @default \"Start date\" */\n startDateLabel: string;\n /**\n * Label of a range's end field in input mode, and the headline's end while a range is\n * being picked (\"Mar 20 – End date\"). @default \"End date\"\n */\n endDateLabel: string;\n}\n\nexport interface DatePickerClassNames {\n /** The picker's root; `className` is merged here too. */\n root?: string;\n /** The header: title, headline and mode toggle. */\n header?: string;\n /** The header's title (\"Select date\"). */\n title?: string;\n /** The header's headline: the chosen date or range. */\n headline?: string;\n /** The calendar or the text input below the header. */\n body?: string;\n /** The weekday names above the days. */\n weekday?: string;\n /** Each day of the calendar. */\n day?: string;\n /** Each year of the year list. */\n year?: string;\n /** The month and year button above the days, which shows the year list. */\n yearButton?: string;\n /** Each month's subhead in the range picker's scrolling month list. */\n monthSubhead?: string;\n}\n\nexport interface DateRangePickerClassNames extends DatePickerClassNames {\n /**\n * The band behind a range's days: each calendar cell it spans (`data-range` is `start`,\n * `middle` or `end`), whose background paints it.\n */\n rangeBand?: string;\n}\n\n// No `aria-description` and the like: the picker's root is a plain container, and no single\n// element in it stands for the whole picker.\ninterface DatePickerCommonProps extends Omit<WrapperRootDOMProps, DescriptionAria> {\n /** Earliest date allowed; earlier days are disabled. */\n min?: DateValue;\n /** Latest date allowed; later days are disabled. */\n max?: DateValue;\n /** Returns `true` for a day that can't be picked (it shows disabled). */\n isDateUnavailable?: (date: DateValue) => boolean;\n /** Show the header (title, headline and mode toggle). @default true */\n header?: boolean;\n /** Show the calendar ↔ text input toggle. @default true */\n modeToggle?: boolean;\n /** Start in calendar or text input mode. @default \"calendar\" */\n defaultMode?: 'calendar' | 'input';\n /**\n * First and last years of the year list (and of a range's month list). Years outside\n * `min` / `max` are shown disabled. @default [1900, 2100]\n */\n yearRange?: [number, number];\n /** Words the picker shows and announces, with English defaults. */\n labels?: Partial<DatePickerLabels>;\n /**\n * Web density of the input mode's text fields, `0` to `-3`: each step takes 4px off them\n * (56px at 0, 44px at -3). The calendar keeps its size: M3 doesn't make date pickers denser,\n * since their 48px day targets are part of their accessibility. Left out, the fields take\n * the density of the nearest `ThemeProvider` or `ThemeScope`.\n * @default 0\n */\n density?: Density;\n /** The root `<div>`'s id. */\n id?: string;\n /** Ref to the root `<div>` element. */\n ref?: Ref<HTMLDivElement>;\n /** Classes for the root element, merged with `classNames.root`; consumer classes win. */\n className?: string;\n /** Inline styles for the root element. */\n style?: CSSProperties;\n /** Classes for each part, by slot. */\n classNames?: DatePickerClassNames;\n /** `data-*` attributes go to the root. */\n [data: `data-${string}`]: string | number | boolean | undefined;\n}\n\nexport type DatePickerProps = DatePickerCommonProps & {\n /** The selected date (controlled); `null` for none. */\n value?: CalendarDate | null;\n /** Initial date when uncontrolled. @default null */\n defaultValue?: CalendarDate | null;\n /** Called with the date the user picks or types. */\n onChange?: (value: CalendarDate) => void;\n};\n\nexport interface DateRange {\n start: CalendarDate;\n end: CalendarDate;\n}\n\nexport type DateRangePickerProps = Omit<DatePickerCommonProps, 'classNames'> & {\n /** Classes for each part, by slot. */\n classNames?: DateRangePickerClassNames;\n /** The selected range (controlled); `null` for none. */\n value?: DateRange | null;\n /** Initial range when uncontrolled. @default null */\n defaultValue?: DateRange | null;\n /** Called with the range once both its start and end are picked or typed. */\n onChange?: (value: DateRange) => void;\n /**\n * `scroll` lists the months one under another and scrolls vertically, as the M3 modal\n * range picker does; `paged` shows one month at a time with previous / next buttons and\n * a year list, like the date picker. @default \"scroll\"\n */\n monthLayout?: 'scroll' | 'paged';\n};\n\n/**\n * M3 modal date picker (Compose's `DatePicker`): a header with the selected date, a month\n * grid you page with the arrows, a horizontal swipe or Page Up / Down, a year list, and a\n * text input mode. Put it in a {@link PickerDialog} for the modal form; {@link DateField}\n * is the docked form. Values are `@internationalized/date` dates.\n *\n * @example\n * <DatePicker value={date} onChange={setDate} />\n */\nexport function DatePicker(props: DatePickerProps) {\n return (\n <DomDirectionLocale>\n {(directionRef) => <SingleDatePicker {...props} directionRef={directionRef} />}\n </DomDirectionLocale>\n );\n}\n\n/**\n * M3 date range picker (Compose's `DateRangePicker`): select a start and an end date on a\n * vertically scrolling list of months, or type them in input mode.\n *\n * @example\n * <DateRangePicker value={range} onChange={setRange} />\n */\nexport function DateRangePicker(props: DateRangePickerProps) {\n return (\n <DomDirectionLocale>\n {(directionRef) => <RangeDatePicker {...props} directionRef={directionRef} />}\n </DomDirectionLocale>\n );\n}\n\ntype Inner<P> = P & { directionRef: (element: HTMLElement | null) => void };\n\nfunction SingleDatePicker(props: Inner<DatePickerProps>) {\n const { locale } = useLocale();\n const confirm = useContext(PickerDialogContext);\n const [value, setValue] = useControlledState(\n props.value,\n props.defaultValue ?? null,\n props.onChange as (value: CalendarDate | null) => void,\n );\n const state = useCalendarState({\n value,\n onChange: (date) => setValue(date as CalendarDate),\n minValue: props.min,\n maxValue: props.max,\n isDateUnavailable: props.isDateUnavailable,\n locale,\n createCalendar,\n });\n const formatter = useDateFormatter({ dateStyle: 'medium' });\n const labels = props.labels ?? {};\n const headline = value\n ? formatter.format(value.toDate(getLocalTimeZone()))\n : (labels.noSelection ?? 'Selected date');\n return (\n <PickerFrame\n {...props}\n range={false}\n state={state}\n headline={headline}\n input={\n <DateInput\n label={labels.dateLabel ?? 'Date'}\n value={value}\n onCommit={(date) => date && setValue(date)}\n onEnter={(date) => date && confirm?.requestConfirm()}\n min={props.min}\n max={props.max}\n isDateUnavailable={props.isDateUnavailable}\n labels={labels}\n density={props.density}\n className=\"w-full\"\n />\n }\n />\n );\n}\n\n/** Whole months from `from` to `to`. */\nconst monthsBetween = (from: CalendarDate, to: CalendarDate) =>\n (to.year - from.year) * 12 + (to.month - from.month);\n\nfunction RangeDatePicker({ monthLayout = 'scroll', ...props }: Inner<DateRangePickerProps>) {\n const { locale } = useLocale();\n const confirm = useContext(PickerDialogContext);\n const [value, setValue] = useControlledState(\n props.value,\n props.defaultValue ?? null,\n props.onChange as (value: DateRange | null) => void,\n );\n // The scrolling list shows every month of the year range (within min / max) at once.\n const [firstYear, lastYear] = props.yearRange ?? [1900, 2100];\n const scroll = monthLayout === 'scroll';\n const listStart = maxDate(\n new CalendarDate(firstYear, 1, 1),\n props.min ? toCalendarDate(props.min) : null,\n )!;\n const listEnd = minDate(\n new CalendarDate(lastYear, 12, 31),\n props.max ? toCalendarDate(props.max) : null,\n )!;\n const state = useRangeCalendarState({\n value,\n onChange: (range) => setValue(range as DateRange),\n minValue: scroll ? listStart : props.min,\n maxValue: scroll ? listEnd : props.max,\n isDateUnavailable: props.isDateUnavailable,\n visibleDuration: scroll ? { months: monthsBetween(listStart, listEnd) + 1 } : undefined,\n locale,\n createCalendar,\n });\n const formatter = useDateFormatter({ month: 'short', day: 'numeric' });\n const labels = props.labels ?? {};\n const format = (date: CalendarDate) => formatter.format(date.toDate(getLocalTimeZone()));\n // While a new range is being picked, its first day is the start and the end is still open\n // (Compose's headline: \"Mar 20 – End date\"), not the range it replaces.\n const anchor = state.anchorDate;\n const headline = anchor\n ? `${format(anchor)} – ${labels.endDateLabel ?? 'End date'}`\n : value\n ? `${format(value.start)} – ${format(value.end)}`\n : (labels.noSelection ?? 'Start date – End date');\n const common = {\n min: props.min,\n max: props.max,\n isDateUnavailable: props.isDateUnavailable,\n labels,\n density: props.density,\n className: 'w-full',\n };\n return (\n <PickerFrame\n {...props}\n range\n scroll={scroll}\n state={state}\n headline={headline}\n input={\n <>\n <DateInput\n {...common}\n label={labels.startDateLabel ?? 'Start date'}\n value={value?.start ?? null}\n onCommit={(start) =>\n start && setValue({ start, end: value && value.end >= start ? value.end : start })\n }\n />\n <DateInput\n {...common}\n label={labels.endDateLabel ?? 'End date'}\n value={value?.end ?? null}\n onCommit={(end) =>\n end && setValue({ start: value && value.start <= end ? value.start : end, end })\n }\n onEnter={(end) => end && value && confirm?.requestConfirm()}\n />\n </>\n }\n />\n );\n}\n\nfunction PickerFrame({\n range,\n scroll = false,\n state,\n headline,\n input,\n header = true,\n modeToggle = true,\n defaultMode = 'calendar',\n yearRange = [1900, 2100],\n labels = {},\n id,\n ref,\n className,\n style,\n classNames,\n directionRef,\n ...rest\n}: Inner<Omit<DatePickerCommonProps, 'classNames'>> & {\n classNames?: DateRangePickerClassNames | undefined;\n range: boolean;\n scroll?: boolean;\n state: CalendarState | RangeCalendarState;\n headline: string;\n input: ReactNode;\n value?: unknown;\n defaultValue?: unknown;\n onChange?: unknown;\n}) {\n const { root: data } = splitRootProps(rest, { wrapper: true });\n const [mode, setMode] = useState(defaultMode);\n // Set once the mode has been switched, so only a switch animates (not the first render).\n const [switched, setSwitched] = useState(false);\n const [years, setYears] = useState(false);\n // The picker's height follows the view on the default spatial spring (Compose's\n // `SizeTransform` in its display mode animation), as the views swap.\n const { attach: attachSize, capture: captureSize } = useSizeTransform<HTMLDivElement>(mode);\n // The outgoing view fades out as it slides away (Compose: up 48px as the input comes in,\n // down by its whole height as the calendar comes back), clipped with the new one.\n const {\n attachView: attachExitView,\n attachSlot: attachExitSlot,\n capture: captureExit,\n } = useViewExit(mode);\n const styles = datePickerStyles({ range });\n const title =\n mode === 'input'\n ? (labels.inputTitle ?? (range ? 'Enter dates' : 'Enter date'))\n : (labels.title ?? (range ? 'Select dates' : 'Select date'));\n const bodyProps = {\n styles,\n years,\n setYears,\n yearRange,\n labels,\n className: classNames?.body,\n classNames,\n };\n return (\n <div\n {...data}\n id={id}\n ref={(element) => {\n attachSize(element);\n directionRef(element);\n if (typeof ref === 'function') ref(element);\n else if (ref) ref.current = element;\n }}\n style={style}\n // The modal date picker's component tokens (date-picker-tokens.ts).\n data-tokens={mergeDataTokens('md-comp-date-picker-modal', data)}\n data-years={years || undefined}\n data-mode={mode}\n className={styles.root({ class: cn(classNames?.root, className) })}\n >\n {header && (\n <div className={styles.header({ class: classNames?.header })}>\n <div className={styles.title({ class: classNames?.title })}>{title}</div>\n <div className={styles.headlineRow()}>\n <div\n aria-live=\"polite\"\n data-slot=\"headline\"\n className={styles.headline({ class: classNames?.headline })}\n >\n {headline}\n </div>\n {modeToggle && (\n <IconButton\n variant=\"standard\"\n // The picker's surface isn't dense, only its input mode's fields.\n density={0}\n icon={mode === 'calendar' ? <EditIcon /> : <CalendarIcon />}\n aria-label={\n mode === 'calendar'\n ? (labels.inputMode ?? 'Switch to text input mode')\n : (labels.calendarMode ?? 'Switch to calendar input mode')\n }\n onPress={() => {\n captureSize();\n captureExit(mode === 'calendar' ? '-48px' : '100%');\n setSwitched(true);\n setMode(mode === 'calendar' ? 'input' : 'calendar');\n }}\n />\n )}\n </div>\n </div>\n )}\n <div className={styles.modeStack()}>\n <div\n key={mode}\n ref={attachExitView}\n data-enter={switched ? mode : undefined}\n className={styles.modeView()}\n >\n {mode === 'input' ? (\n <div className={styles.input({ class: classNames?.body })}>{input}</div>\n ) : range && scroll ? (\n <RangeMonthList state={state as RangeCalendarState} {...bodyProps} />\n ) : range ? (\n <RangeCalendarBody state={state as RangeCalendarState} {...bodyProps} />\n ) : (\n <SingleCalendarBody state={state as CalendarState} {...bodyProps} />\n )}\n </div>\n <div ref={attachExitSlot} aria-hidden=\"true\" inert className={styles.modeExit()} />\n </div>\n </div>\n );\n}\n\ninterface BodyProps {\n styles: ReturnType<typeof datePickerStyles>;\n years: boolean;\n setYears: (open: boolean) => void;\n yearRange: [number, number];\n labels: Partial<DatePickerLabels>;\n className?: string | undefined;\n classNames?: DateRangePickerClassNames | undefined;\n}\n\nfunction SingleCalendarBody({ state, ...props }: BodyProps & { state: CalendarState }) {\n const { calendarProps, prevButtonProps, nextButtonProps } = useCalendar({}, state);\n return (\n <CalendarBody\n {...props}\n state={state}\n calendarProps={calendarProps}\n prevButtonProps={prevButtonProps}\n nextButtonProps={nextButtonProps}\n />\n );\n}\n\nfunction RangeCalendarBody({ state, ...props }: BodyProps & { state: RangeCalendarState }) {\n const ref = useRef<HTMLDivElement>(null);\n const { calendarProps, prevButtonProps, nextButtonProps } = useRangeCalendar({}, state, ref);\n return (\n <CalendarBody\n {...props}\n bodyRef={ref}\n state={state}\n calendarProps={calendarProps}\n prevButtonProps={prevButtonProps}\n nextButtonProps={nextButtonProps}\n />\n );\n}\n\nfunction CalendarBody({\n state,\n calendarProps,\n prevButtonProps,\n nextButtonProps,\n styles,\n years,\n setYears,\n yearRange,\n labels,\n className,\n classNames,\n bodyRef,\n}: BodyProps & {\n state: CalendarState | RangeCalendarState;\n calendarProps: HTMLAttributes<HTMLElement>;\n prevButtonProps: AriaButtonProps;\n nextButtonProps: AriaButtonProps;\n bodyRef?: Ref<HTMLDivElement>;\n}) {\n const confirm = useContext(PickerDialogContext);\n const monthFormatter = useDateFormatter({ month: 'long', year: 'numeric' });\n const monthLabel = monthFormatter.format(state.visibleRange.start.toDate(getLocalTimeZone()));\n const menuRef = useRef<HTMLButtonElement>(null);\n const [focusYears, setFocusYears] = useState(false);\n // Compose shrinks the year list and fades it out (`shrinkVertically` + `fadeOut`); the\n // first of the two transitions to end removes it.\n const yearsPresence = usePresence(years, ['clip-path', 'opacity']);\n const { swipeProps, slideKey, slideDirection } = useMonthSwipe(state);\n const onKeyDownCapture = usePickerKeys(state, {\n onConfirm: confirm?.requestConfirm,\n onMonthMenu: () => menuRef.current?.focus(),\n onYearMenu: () => {\n setFocusYears(true);\n setYears(true);\n },\n });\n return (\n <div\n {...calendarProps}\n ref={bodyRef}\n onKeyDownCapture={onKeyDownCapture}\n className={styles.body({ class: className })}\n >\n <div className={styles.nav()}>\n <TooltipTrigger>\n <Button\n ref={menuRef}\n variant=\"text\"\n className={cn('text-on-surface-variant', classNames?.yearButton)}\n aria-label={`${monthLabel}, ${years ? (labels.showDays ?? 'Switch to selecting a day') : (labels.showYears ?? 'Switch to selecting a year')}`}\n onPress={() => {\n setFocusYears(false);\n setYears(!years);\n }}\n >\n {/* The drop-down arrow trails the label here, which Button's one leading icon can't do. */}\n <span className=\"inline-flex items-center gap-[8px]\">\n <span aria-live=\"polite\">{monthLabel}</span>\n <span\n aria-hidden=\"true\"\n className=\"inline-flex size-[20px] items-center justify-center\"\n >\n <span className={styles.yearButtonIcon()}>\n <ArrowDropDownIcon />\n </span>\n </span>\n </span>\n </Button>\n <LazyTooltip>{labels.yearsTooltip ?? 'Choose a year (Shift+Y)'}</LazyTooltip>\n </TooltipTrigger>\n {!years && (\n <div className={styles.navButtons()}>\n <ShortcutIconButton\n icon={<ChevronLeftIcon />}\n label={labels.previousMonth ?? 'Previous month'}\n tooltip={labels.previousMonthTooltip ?? 'Previous month (Page Up)'}\n onPress={prevButtonProps.onPress as () => void}\n disabled={prevButtonProps.isDisabled}\n />\n <ShortcutIconButton\n icon={<ChevronRightIcon />}\n label={labels.nextMonth ?? 'Next month'}\n tooltip={labels.nextMonthTooltip ?? 'Next month (Page Down)'}\n onPress={nextButtonProps.onPress as () => void}\n disabled={nextButtonProps.isDisabled}\n />\n </div>\n )}\n </div>\n {!years && (\n <div {...swipeProps} className={styles.swipe()}>\n <div key={slideKey} data-direction={slideDirection} className={styles.slide()}>\n <CalendarGrid state={state} styles={styles} classNames={classNames} />\n </div>\n </div>\n )}\n {/* Closing, the list stays over the grid until it has shrunk and faded away. */}\n {yearsPresence.isPresent && (\n <YearList\n state={state}\n styles={styles}\n yearRange={yearRange}\n className={classNames?.year}\n label={labels.yearList ?? 'Year'}\n autoFocus={focusYears}\n exiting={yearsPresence.isExiting}\n exitProps={yearsPresence.exitProps}\n onPick={() => setYears(false)}\n />\n )}\n </div>\n );\n}\n\n/**\n * The range picker's months, one under another in a vertical scroll (M3: \"To navigate\n * across months, scroll vertically\"), under a single weekday row. Only the months in view\n * (and the focused one) are rendered; the rest are spacers of the same fixed height.\n */\nfunction RangeMonthList({\n state,\n styles,\n className,\n classNames,\n}: BodyProps & { state: RangeCalendarState }) {\n const confirm = useContext(PickerDialogContext);\n const ref = useRef<HTMLDivElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const { calendarProps } = useRangeCalendar({}, state, ref);\n const { locale } = useLocale();\n const first = state.visibleRange.start;\n const count = monthsBetween(first, state.visibleRange.end) + 1;\n const focusedIndex = monthsBetween(first, state.focusedDate);\n const [view, setView] = useState(() => ({ top: focusedIndex * MONTH_HEIGHT, height: 0 }));\n const weekdays = useDateFormatter({ weekday: 'narrow' });\n const longWeekdays = useDateFormatter({ weekday: 'long' });\n const subhead = useDateFormatter({ month: 'long', year: 'numeric' });\n const onKeyDownCapture = usePickerKeys(state, {\n onConfirm: confirm?.requestConfirm,\n onMonthMenu: () => undefined,\n onYearMenu: () => undefined,\n });\n\n // Open on the focused month (the range's start, or today), then follow the scroll.\n const initialTop = useRef(view.top);\n useLayoutEffect(() => {\n const list = listRef.current;\n if (!list) return;\n // A list out of sight (`display: none` above it) can't scroll, so it scrolls to the focused\n // month once it shows; it used to open on the range's first month.\n let opened = list.getClientRects().length > 0;\n list.scrollTop = initialTop.current;\n const measure = () => {\n if (!opened && list.clientHeight > 0) {\n opened = true;\n list.scrollTop = initialTop.current;\n }\n setView({ top: list.scrollTop, height: list.clientHeight });\n };\n measure();\n const observer = typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(measure);\n observer?.observe(list);\n list.addEventListener('scroll', measure, { passive: true });\n return () => {\n observer?.disconnect();\n list.removeEventListener('scroll', measure);\n };\n }, []);\n\n const height = view.height || MONTH_HEIGHT;\n let from = Math.max(0, Math.floor(view.top / MONTH_HEIGHT) - 1);\n let to = Math.min(count - 1, Math.floor((view.top + height) / MONTH_HEIGHT) + 1);\n if (state.isFocused) {\n from = Math.min(from, focusedIndex);\n to = Math.max(to, focusedIndex);\n }\n const weekStart = startOfWeek(today(getLocalTimeZone()), locale);\n\n return (\n <div\n {...mergeProps(calendarProps, { onKeyDownCapture })}\n ref={ref}\n className={styles.body({ class: cn('min-h-0 flex-1', className) })}\n >\n <div aria-hidden=\"true\" className={styles.weekdayRow()}>\n {Array.from({ length: 7 }, (_, index) => {\n const day = weekStart.add({ days: index }).toDate(getLocalTimeZone());\n return (\n <span\n key={index}\n title={longWeekdays.format(day)}\n className={styles.weekdayCell({ class: classNames?.weekday })}\n >\n {weekdays.format(day)}\n </span>\n );\n })}\n </div>\n <div ref={listRef} className={styles.months()}>\n <div style={{ height: from * MONTH_HEIGHT }} />\n {Array.from({ length: to - from + 1 }, (_, i) => {\n const month = first.add({ months: from + i });\n return (\n <div key={month.toString()} className=\"h-[336px]\">\n <div\n aria-hidden=\"true\"\n className={styles.monthSubhead({ class: classNames?.monthSubhead })}\n >\n {subhead.format(month.toDate(getLocalTimeZone()))}\n </div>\n <CalendarGrid state={state} styles={styles} month={month} classNames={classNames} />\n </div>\n );\n })}\n <div style={{ height: (count - 1 - to) * MONTH_HEIGHT }} />\n </div>\n </div>\n );\n}\n\n/** A month in the scrolling list: its 48px subhead and six 48px weeks. */\nconst MONTH_HEIGHT = 336;\n\nfunction YearList({\n state,\n styles,\n yearRange,\n className,\n label,\n autoFocus,\n exiting,\n exitProps,\n onPick,\n}: {\n state: CalendarState | RangeCalendarState;\n styles: ReturnType<typeof datePickerStyles>;\n yearRange: [number, number];\n className: string | undefined;\n label: string;\n autoFocus: boolean;\n /** Closing: drawn over the grid, out of the accessibility tree and taking no presses. */\n exiting: boolean;\n exitProps: { onTransitionEnd: (event: TransitionEvent<HTMLElement>) => void };\n onPick: () => void;\n}) {\n const current = today(getLocalTimeZone()).year;\n const focusedYear = state.focusedDate.year;\n const minYear = state.minValue?.year ?? -Infinity;\n const maxYear = state.maxValue?.year ?? Infinity;\n return (\n <div\n {...exitProps}\n role=\"radiogroup\"\n aria-label={label}\n aria-hidden={exiting || undefined}\n inert={exiting || undefined}\n data-exiting={exiting || undefined}\n className={styles.years()}\n ref={(element) => {\n if (exiting) return;\n // Open on the focused year, as Compose scrolls the year list to it.\n const selected = element?.querySelector<HTMLElement>('[aria-checked=\"true\"]');\n selected?.scrollIntoView?.({ block: 'center' });\n if (autoFocus) selected?.focus({ preventScroll: true });\n }}\n >\n {Array.from({ length: yearRange[1] - yearRange[0] + 1 }, (_, i) => yearRange[0] + i).map(\n (year) => (\n <ChoiceButton\n key={year}\n selected={year === focusedYear}\n disabled={year < minYear || year > maxYear}\n data-current={year === current || undefined}\n steps={YEAR_STEPS}\n className={styles.year({ class: className })}\n onPick={() => {\n state.setFocusedDate(state.focusedDate.set({ year }));\n onPick();\n }}\n >\n {year}\n </ChoiceButton>\n ),\n )}\n </div>\n );\n}\n\n/** Three years to a row. */\nconst YEAR_STEPS = { ArrowLeft: -1, ArrowRight: 1, ArrowUp: -3, ArrowDown: 3 };\n"],"mappings":"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"}
@@ -158,11 +158,11 @@ export declare const dockedDatePickerStyles: import("tailwind-variants").TVRetur
158
158
  [key: string]: import("tailwind-variants").ClassValue | {
159
159
  panel?: import("tailwind-variants").ClassValue;
160
160
  actions?: import("tailwind-variants").ClassValue;
161
- item?: import("tailwind-variants").ClassValue;
162
161
  header?: import("tailwind-variants").ClassValue;
163
162
  view?: import("tailwind-variants").ClassValue;
164
- list?: import("tailwind-variants").ClassValue;
163
+ item?: import("tailwind-variants").ClassValue;
165
164
  check?: import("tailwind-variants").ClassValue;
165
+ list?: import("tailwind-variants").ClassValue;
166
166
  menuIcon?: import("tailwind-variants").ClassValue;
167
167
  group?: import("tailwind-variants").ClassValue;
168
168
  calendar?: import("tailwind-variants").ClassValue;
@@ -174,11 +174,11 @@ export declare const dockedDatePickerStyles: import("tailwind-variants").TVRetur
174
174
  [x: string]: import("tailwind-variants").ClassValue | {
175
175
  panel?: import("tailwind-variants").ClassValue;
176
176
  actions?: import("tailwind-variants").ClassValue;
177
- item?: import("tailwind-variants").ClassValue;
178
177
  header?: import("tailwind-variants").ClassValue;
179
178
  view?: import("tailwind-variants").ClassValue;
180
- list?: import("tailwind-variants").ClassValue;
179
+ item?: import("tailwind-variants").ClassValue;
181
180
  check?: import("tailwind-variants").ClassValue;
181
+ list?: import("tailwind-variants").ClassValue;
182
182
  menuIcon?: import("tailwind-variants").ClassValue;
183
183
  group?: import("tailwind-variants").ClassValue;
184
184
  calendar?: import("tailwind-variants").ClassValue;
@@ -202,11 +202,11 @@ export declare const dockedDatePickerStyles: import("tailwind-variants").TVRetur
202
202
  [key: string]: import("tailwind-variants").ClassValue | {
203
203
  panel?: import("tailwind-variants").ClassValue;
204
204
  actions?: import("tailwind-variants").ClassValue;
205
- item?: import("tailwind-variants").ClassValue;
206
205
  header?: import("tailwind-variants").ClassValue;
207
206
  view?: import("tailwind-variants").ClassValue;
208
- list?: import("tailwind-variants").ClassValue;
207
+ item?: import("tailwind-variants").ClassValue;
209
208
  check?: import("tailwind-variants").ClassValue;
209
+ list?: import("tailwind-variants").ClassValue;
210
210
  menuIcon?: import("tailwind-variants").ClassValue;
211
211
  group?: import("tailwind-variants").ClassValue;
212
212
  calendar?: import("tailwind-variants").ClassValue;
@@ -2,6 +2,6 @@ import { ComponentTokenSet } from "../../tokens/component.js";
2
2
  import "../../index.js";
3
3
  //#region src/components/date-picker/date-picker-tokens.d.ts
4
4
  /** The tokens of {@link DatePicker}, {@link DateRangePicker} and the date {@link PickerDialog}. */
5
- export declare const datePickerTokenSet: ComponentTokenSet<"container-color" | "container-elevation" | "container-shape" | "header-headline-color" | "date-selected-container-color" | "date-selected-label-text-color" | "date-today-container-outline-color" | "date-today-label-text-color" | "range-selection-active-indicator-container-color">;
5
+ export declare const datePickerTokenSet: ComponentTokenSet<"container-color" | "container-shape" | "container-elevation" | "header-headline-color" | "date-selected-container-color" | "date-selected-label-text-color" | "date-today-container-outline-color" | "date-today-label-text-color" | "range-selection-active-indicator-container-color">;
6
6
  //#endregion
7
7
  //# sourceMappingURL=date-picker-tokens.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { ClosedBy } from "../../utils/closed-by.js";
2
- import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
2
+ import { CSSProperties, ComponentPropsWithRef, ReactElement, ReactNode } from "react";
3
3
  import { AriaDialogProps } from "react-aria";
4
4
  //#region src/components/dialog/Dialog.d.ts
5
5
  /**
@@ -216,6 +216,8 @@ export interface DialogHeaderProps extends Omit<ComponentPropsWithRef<'div'>, 't
216
216
  * from closing it too. @default false
217
217
  */
218
218
  closeDisabled?: boolean;
219
+ /** Replaces the full-screen close button's icon. */
220
+ closeIcon?: ReactElement;
219
221
  /** Classes for each part, by slot. */
220
222
  classNames?: DialogHeaderClassNames;
221
223
  }
@@ -233,7 +235,7 @@ export interface DialogHeaderProps extends Omit<ComponentPropsWithRef<'div'>, 't
233
235
  * <DialogActions>…</DialogActions>
234
236
  * </Dialog>
235
237
  */
236
- export declare function DialogHeader({ children, labels, action, divider, closeDisabled, className, classNames, ...props }: DialogHeaderProps): import("react").JSX.Element;
238
+ export declare function DialogHeader({ children, labels, action, divider, closeDisabled, closeIcon, className, classNames, ...props }: DialogHeaderProps): import("react").JSX.Element;
237
239
  export interface DialogContentProps extends ComponentPropsWithRef<'div'> {
238
240
  /**
239
241
  * The basic dialog's optional dividers: 1px `outline-variant` lines across the panel
@@ -325,7 +325,7 @@ const DEFAULT_HEADER_LABELS = { close: "Close" };
325
325
  * <DialogActions>…</DialogActions>
326
326
  * </Dialog>
327
327
  */
328
- function DialogHeader({ children, labels, action, divider = false, closeDisabled = false, className, classNames, ...props }) {
328
+ function DialogHeader({ children, labels, action, divider = false, closeDisabled = false, closeIcon, className, classNames, ...props }) {
329
329
  const { titleProps, hasIcon, fullScreen, close, setHeaderAction } = useContext(DialogPartsContext);
330
330
  const hasAction = action !== void 0;
331
331
  useLayoutEffect(() => {
@@ -344,7 +344,7 @@ function DialogHeader({ children, labels, action, divider = false, closeDisabled
344
344
  fullScreen !== "never" && /* @__PURE__ */ jsx(IconButton, {
345
345
  variant: "standard",
346
346
  density: 0,
347
- icon: /* @__PURE__ */ jsx(CloseIcon, {}),
347
+ icon: closeIcon ?? /* @__PURE__ */ jsx(CloseIcon, {}),
348
348
  "aria-label": labels?.close ?? DEFAULT_HEADER_LABELS.close,
349
349
  disabled: closeDisabled,
350
350
  onPress: close,