@taprootio/espalier 4.7.0 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14670,7 +14670,7 @@
14670
14670
  "declarations": [
14671
14671
  {
14672
14672
  "kind": "class",
14673
- "description": "A date / datetime / time / range picker built on the browser-native\n[Temporal API](https://tc39.es/proposal-temporal/docs/) and the\nnative Popover API. It participates in native `<form>` elements\nvia `ElementInternals`, so its value is submitted with the form\njust like a built-in `<input type=\"date\">`.\n\nWrap the picker in an [esp-form-item](/components/form-item) for a\nlabel, validation messages, and consistent spacing with other\nEspalier form controls.\n\n```html\n<esp-form-item label=\"Birthday\">\n <esp-date-picker value=\"1990-06-15\"></esp-date-picker>\n</esp-form-item>\n```\n\nThe picker supports four modes. Use the `mode` attribute to switch\nbetween a single date, a date-and-time, a time-only, or a date\nrange:\n\n```html\n<esp-form-item label=\"Appointment\">\n <esp-date-picker mode=\"datetime\" value=\"2025-09-01T14:30:00\"></esp-date-picker>\n</esp-form-item>\n```\n\nFor date range selection the value uses ISO 8601 interval notation\n(`start/end`). Click once to set the start, then click again to\nset the end. If the second click is before the first, the dates\nare automatically swapped:\n\n```html\n<esp-form-item label=\"Trip dates\">\n <esp-date-picker mode=\"range\" value=\"2025-07-01/2025-07-14\"></esp-date-picker>\n</esp-form-item>\n```\n\nConstrain the selectable range with `min` and `max`. Dates outside\nthe range are greyed out and cannot be selected. The picker also\nreports `rangeUnderflow` / `rangeOverflow` through the Constraint\nValidation API:\n\n```html\n<esp-form-item label=\"Check-in (next 30 days)\">\n <esp-date-picker id=\"checkin-picker\"></esp-date-picker>\n</esp-form-item>\n<script>\n const picker = document.getElementById(\"checkin-picker\");\n const today = Temporal.Now.plainDateISO();\n picker.min = today.toString();\n picker.max = today.add({ days: 30 }).toString();\n</script>\n```\n\nBecause the picker is form-associated, its value is included when\nthe form is submitted and it responds to form resets:\n\n```html\n<form id=\"booking-form\">\n <esp-form-item label=\"Departure\">\n <esp-date-picker name=\"departure\" required></esp-date-picker>\n </esp-form-item>\n <esp-button label=\"Submit\"></esp-button>\n</form>\n<script>\n const form = document.getElementById(\"booking-form\");\n const picker = findByTagName(\"esp-date-picker\")[0];\n picker.addEventListener(\"esp-value-changed\", (event) => {\n console.log(\"Selected:\", event.detail);\n });\n</script>\n```\n\n> **Runtime requirement:** The Temporal API must be available. If\n> target browsers do not yet ship it natively, load a polyfill such\n> as `temporal-polyfill` in the document `<head>` before using this\n> component.",
14673
+ "description": "A date / datetime / time / range picker built on the browser-native\n[Temporal API](https://tc39.es/proposal-temporal/docs/) and the\nnative Popover API. It participates in native `<form>` elements\nvia `ElementInternals`, so its value is submitted with the form\njust like a built-in `<input type=\"date\">`.\n\nWrap the picker in an [esp-form-item](/components/form-item) for a\nlabel, validation messages, and consistent spacing with other\nEspalier form controls.\n\n```html\n<esp-form-item label=\"Birthday\">\n <esp-date-picker value=\"1990-06-15\"></esp-date-picker>\n</esp-form-item>\n```\n\nThe picker supports four modes. Use the `mode` attribute to switch\nbetween a single date, a date-and-time, a time-only, or a date\nrange:\n\n```html\n<esp-form-item label=\"Appointment\">\n <esp-date-picker mode=\"datetime\" value=\"2025-09-01T14:30:00\"></esp-date-picker>\n</esp-form-item>\n```\n\nFor date range selection the value uses ISO 8601 interval notation\n(`start/end`). Click once to set the start, then click again to\nset the end. If the second click is before the first, the dates\nare automatically swapped:\n\n```html\n<esp-form-item label=\"Trip dates\">\n <esp-date-picker mode=\"range\" value=\"2025-07-01/2025-07-14\"></esp-date-picker>\n</esp-form-item>\n```\n\nConstrain the selectable range with `min` and `max`. Dates outside\nthe range are greyed out and cannot be selected. The picker also\nreports `rangeUnderflow` / `rangeOverflow` through the Constraint\nValidation API:\n\n```html\n<esp-form-item label=\"Check-in (next 30 days)\">\n <esp-date-picker id=\"checkin-picker\"></esp-date-picker>\n</esp-form-item>\n<script>\n const picker = document.getElementById(\"checkin-picker\");\n const today = Temporal.Now.plainDateISO();\n picker.min = today.toString();\n picker.max = today.add({ days: 30 }).toString();\n</script>\n```\n\nTo reach a distant date quickly, click the month or the year in the\ncalendar header. The month opens a grid of the twelve months and the\nyear opens a scrolling list of years; choosing one moves the calendar\nthere without changing the value. The header arrows step by month on\nthe day grid, by year on the month grid, and by a page on the year\nlist, and `Escape` returns to the day grid:\n\n```html\n<esp-form-item label=\"Date of birth\">\n <esp-date-picker value=\"1985-03-22\"></esp-date-picker>\n</esp-form-item>\n```\n\nBecause the picker is form-associated, its value is included when\nthe form is submitted and it responds to form resets:\n\n```html\n<form id=\"booking-form\">\n <esp-form-item label=\"Departure\">\n <esp-date-picker name=\"departure\" required></esp-date-picker>\n </esp-form-item>\n <esp-button label=\"Submit\"></esp-button>\n</form>\n<script>\n const form = document.getElementById(\"booking-form\");\n const picker = findByTagName(\"esp-date-picker\")[0];\n picker.addEventListener(\"esp-value-changed\", (event) => {\n console.log(\"Selected:\", event.detail);\n });\n</script>\n```\n\n> **Runtime requirement:** The Temporal API must be available. If\n> target browsers do not yet ship it natively, load a polyfill such\n> as `temporal-polyfill` in the document `<head>` before using this\n> component.",
14674
14674
  "name": "EspalierDatePicker",
14675
14675
  "members": [
14676
14676
  {
@@ -14725,6 +14725,11 @@
14725
14725
  "name": "timePickerRef",
14726
14726
  "privacy": "private"
14727
14727
  },
14728
+ {
14729
+ "kind": "field",
14730
+ "name": "yearListRef",
14731
+ "privacy": "private"
14732
+ },
14728
14733
  {
14729
14734
  "kind": "field",
14730
14735
  "name": "_containRepositionFrame",
@@ -14872,6 +14877,46 @@
14872
14877
  "privacy": "protected",
14873
14878
  "description": "The date that has keyboard focus inside the grid."
14874
14879
  },
14880
+ {
14881
+ "kind": "field",
14882
+ "name": "_surface",
14883
+ "type": {
14884
+ "text": "CalendarSurface"
14885
+ },
14886
+ "privacy": "private",
14887
+ "default": "\"days\"",
14888
+ "description": "Which surface the calendar body is showing."
14889
+ },
14890
+ {
14891
+ "kind": "field",
14892
+ "name": "_jumpFocus",
14893
+ "type": {
14894
+ "text": "number"
14895
+ },
14896
+ "privacy": "private",
14897
+ "default": "0",
14898
+ "description": "The month (1–12) or year holding the roving tabindex on the jump\nsurface, so keyboard movement there never disturbs `focusedDate`."
14899
+ },
14900
+ {
14901
+ "kind": "field",
14902
+ "name": "_yearWindow",
14903
+ "type": {
14904
+ "text": "number[]"
14905
+ },
14906
+ "privacy": "private",
14907
+ "default": "[]",
14908
+ "description": "The years the year surface lists, generated each time it opens."
14909
+ },
14910
+ {
14911
+ "kind": "field",
14912
+ "name": "_pinnedBodySize",
14913
+ "type": {
14914
+ "text": "{ width: number; height: number } | null"
14915
+ },
14916
+ "privacy": "private",
14917
+ "default": "null",
14918
+ "description": "The day grid's measured box while a jump surface is showing. The body\nis pinned to it so the popover keeps its footprint and position: the\npopover is sized `min-content`, so without the pin the narrower month\ngrid or year list would shrink it, and `_positionPopover` measures on\nopen and on scroll/resize tracking, never on a content swap."
14919
+ },
14875
14920
  {
14876
14921
  "kind": "field",
14877
14922
  "name": "open",
@@ -15451,6 +15496,269 @@
15451
15496
  }
15452
15497
  ]
15453
15498
  },
15499
+ {
15500
+ "kind": "method",
15501
+ "name": "_setViewMonth",
15502
+ "privacy": "private",
15503
+ "return": {
15504
+ "type": {
15505
+ "text": "void"
15506
+ }
15507
+ },
15508
+ "parameters": [
15509
+ {
15510
+ "name": "month",
15511
+ "type": {
15512
+ "text": "Temporal.PlainYearMonth"
15513
+ }
15514
+ }
15515
+ ],
15516
+ "description": "Show `month`, carrying the focused day across: clamped to the month's\nlength, then into `min` / `max` when the bound falls in this month, so\nthe roving day is one that can take focus — a disabled day cell\nrefuses it and focus would fall to the document."
15517
+ },
15518
+ {
15519
+ "kind": "method",
15520
+ "name": "_navigateHeader",
15521
+ "privacy": "private",
15522
+ "return": {
15523
+ "type": {
15524
+ "text": "void"
15525
+ }
15526
+ },
15527
+ "parameters": [
15528
+ {
15529
+ "name": "direction",
15530
+ "type": {
15531
+ "text": "-1 | 1"
15532
+ }
15533
+ }
15534
+ ],
15535
+ "description": "The header arrows act on whichever surface is showing."
15536
+ },
15537
+ {
15538
+ "kind": "method",
15539
+ "name": "_toggleSurface",
15540
+ "privacy": "private",
15541
+ "return": {
15542
+ "type": {
15543
+ "text": "void"
15544
+ }
15545
+ },
15546
+ "parameters": [
15547
+ {
15548
+ "name": "surface",
15549
+ "type": {
15550
+ "text": "CalendarSurface"
15551
+ }
15552
+ }
15553
+ ],
15554
+ "description": "Open `surface`, or return to the day grid when it is already showing."
15555
+ },
15556
+ {
15557
+ "kind": "method",
15558
+ "name": "_showSurface",
15559
+ "privacy": "private",
15560
+ "return": {
15561
+ "type": {
15562
+ "text": "void"
15563
+ }
15564
+ },
15565
+ "parameters": [
15566
+ {
15567
+ "name": "surface",
15568
+ "type": {
15569
+ "text": "CalendarSurface"
15570
+ }
15571
+ }
15572
+ ]
15573
+ },
15574
+ {
15575
+ "kind": "method",
15576
+ "name": "_openYearWindow",
15577
+ "privacy": "private",
15578
+ "return": {
15579
+ "type": {
15580
+ "text": "void"
15581
+ }
15582
+ },
15583
+ "parameters": [
15584
+ {
15585
+ "name": "preferred",
15586
+ "type": {
15587
+ "text": "number"
15588
+ }
15589
+ }
15590
+ ],
15591
+ "description": "Generate the year list around the view year and put the roving\ntabindex on `preferred`, clamped into the window: the view year when\nthe surface opens, the current keyboard position when a bound change\nrebuilds the list underneath it."
15592
+ },
15593
+ {
15594
+ "kind": "method",
15595
+ "name": "_applySurfaceChange",
15596
+ "privacy": "private",
15597
+ "return": {
15598
+ "type": {
15599
+ "text": "void"
15600
+ }
15601
+ },
15602
+ "parameters": [
15603
+ {
15604
+ "name": "previous",
15605
+ "type": {
15606
+ "text": "CalendarSurface | undefined"
15607
+ }
15608
+ }
15609
+ ],
15610
+ "description": "Runs from `updated()` once the new surface is in the DOM: pin or\nrelease the body height, centre the year list, and move focus into\nthe surface. Focus is left alone on the first render and while the\npopover is closed."
15611
+ },
15612
+ {
15613
+ "kind": "method",
15614
+ "name": "_focusSurface",
15615
+ "privacy": "private",
15616
+ "return": {
15617
+ "type": {
15618
+ "text": "void"
15619
+ }
15620
+ },
15621
+ "description": "Focus the element holding the roving tabindex on the current surface."
15622
+ },
15623
+ {
15624
+ "kind": "method",
15625
+ "name": "_chooseMonth",
15626
+ "privacy": "private",
15627
+ "return": {
15628
+ "type": {
15629
+ "text": "void"
15630
+ }
15631
+ },
15632
+ "parameters": [
15633
+ {
15634
+ "name": "month",
15635
+ "type": {
15636
+ "text": "number"
15637
+ }
15638
+ }
15639
+ ]
15640
+ },
15641
+ {
15642
+ "kind": "method",
15643
+ "name": "_chooseYear",
15644
+ "privacy": "private",
15645
+ "return": {
15646
+ "type": {
15647
+ "text": "void"
15648
+ }
15649
+ },
15650
+ "parameters": [
15651
+ {
15652
+ "name": "year",
15653
+ "type": {
15654
+ "text": "number"
15655
+ }
15656
+ }
15657
+ ]
15658
+ },
15659
+ {
15660
+ "kind": "method",
15661
+ "name": "_handleMonthKeyDown",
15662
+ "privacy": "private",
15663
+ "return": {
15664
+ "type": {
15665
+ "text": "void"
15666
+ }
15667
+ },
15668
+ "parameters": [
15669
+ {
15670
+ "name": "ev",
15671
+ "type": {
15672
+ "text": "KeyboardEvent"
15673
+ }
15674
+ }
15675
+ ],
15676
+ "description": "Keyboard handler for the month surface.\n\n| Key | Action |\n|-----------------------|---------------------------------|\n| `ArrowLeft` / `Right` | Previous / next month |\n| `ArrowUp` / `Down` | Same column, previous / next row |\n| `Home` / `End` | January / December |\n| `PageUp` / `PageDown` | Previous / next year |\n| `Enter` / `Space` | Choose the focused month |\n| `Escape` | Return to the day grid |"
15677
+ },
15678
+ {
15679
+ "kind": "method",
15680
+ "name": "_handleYearKeyDown",
15681
+ "privacy": "private",
15682
+ "return": {
15683
+ "type": {
15684
+ "text": "void"
15685
+ }
15686
+ },
15687
+ "parameters": [
15688
+ {
15689
+ "name": "ev",
15690
+ "type": {
15691
+ "text": "KeyboardEvent"
15692
+ }
15693
+ }
15694
+ ],
15695
+ "description": "Keyboard handler for the year surface.\n\n| Key | Action |\n|-----------------------|---------------------------------|\n| `ArrowUp` / `Down` | Previous / next year |\n| `PageUp` / `PageDown` | One visible page up / down |\n| `Home` / `End` | First / last listed year |\n| `Enter` / `Space` | Choose the focused year |\n| `Escape` | Return to the day grid |"
15696
+ },
15697
+ {
15698
+ "kind": "method",
15699
+ "name": "_moveYearFocus",
15700
+ "privacy": "private",
15701
+ "return": {
15702
+ "type": {
15703
+ "text": "boolean"
15704
+ }
15705
+ },
15706
+ "parameters": [
15707
+ {
15708
+ "name": "delta",
15709
+ "type": {
15710
+ "text": "number"
15711
+ }
15712
+ }
15713
+ ],
15714
+ "description": "Move the year surface's roving tabindex by `delta` entries, kept in view. Returns whether it moved."
15715
+ },
15716
+ {
15717
+ "kind": "method",
15718
+ "name": "_focusSurfaceAfterUpdate",
15719
+ "privacy": "private",
15720
+ "return": {
15721
+ "type": {
15722
+ "text": "void"
15723
+ }
15724
+ }
15725
+ },
15726
+ {
15727
+ "kind": "method",
15728
+ "name": "_yearPageSize",
15729
+ "privacy": "private",
15730
+ "return": {
15731
+ "type": {
15732
+ "text": "number"
15733
+ }
15734
+ },
15735
+ "description": "Years that fit in the list's visible height; the arrows and PageUp/PageDown move by this."
15736
+ },
15737
+ {
15738
+ "kind": "method",
15739
+ "name": "_scrollYearIntoView",
15740
+ "privacy": "private",
15741
+ "return": {
15742
+ "type": {
15743
+ "text": "void"
15744
+ }
15745
+ },
15746
+ "parameters": [
15747
+ {
15748
+ "name": "year",
15749
+ "type": {
15750
+ "text": "number"
15751
+ }
15752
+ },
15753
+ {
15754
+ "name": "block",
15755
+ "type": {
15756
+ "text": "\"center\" | \"nearest\""
15757
+ }
15758
+ }
15759
+ ],
15760
+ "description": "Scroll the year list so `year` is centred or just inside the visible\nbox. The list's own `scrollTop` is set rather than `scrollIntoView`,\nwhich would also scroll every ancestor — including the document\nbehind the top-layer popover."
15761
+ },
15454
15762
  {
15455
15763
  "kind": "method",
15456
15764
  "name": "_moveFocus",
@@ -15652,7 +15960,7 @@
15652
15960
  }
15653
15961
  }
15654
15962
  ],
15655
- "description": "Full keyboard handler for the calendar grid following the\nWAI-ARIA Grid / Date Picker pattern.\n\n| Key | Action |\n|-------------------|-------------------------------------------|\n| `ArrowLeft` | Previous day |\n| `ArrowRight` | Next day |\n| `ArrowUp` | Same weekday, previous week |\n| `ArrowDown` | Same weekday, next week |\n| `Home` | First day of the current week (Monday) |\n| `End` | Last day of the current week (Sunday) |\n| `PageUp` | Same day, previous month (Shift: prev yr) |\n| `PageDown` | Same day, next month (Shift: next yr) |\n| `Enter` / `Space` | Select focusedDate |\n| `Escape` | Close popup, return focus to trigger |"
15963
+ "description": "Full keyboard handler for the calendar grid following the\nWAI-ARIA Grid / Date Picker pattern.\n\n| Key | Action |\n|-------------------|-------------------------------------------|\n| `ArrowLeft` | Previous day |\n| `ArrowRight` | Next day |\n| `ArrowUp` | Same weekday, previous week |\n| `ArrowDown` | Same weekday, next week |\n| `Home` | First day of the current week (Monday) |\n| `End` | Last day of the current week (Sunday) |\n| `PageUp` | Same day, previous month (Shift: prev yr) |\n| `PageDown` | Same day, next month (Shift: next yr) |\n| `Enter` / `Space` | Select focusedDate |\n| `Escape` | Close popup, return focus to trigger |\n\nThe handler is bound on the whole calendar so a focused header arrow\nor title control still navigates the grid with these keys (and the\ngrid takes focus back). The one exception is native activation:\n`Enter` / `Space` on a header button must click it, not select the\nfocused date, so those two keys are left to the button. While a jump\nsurface is showing, that surface owns its keys (`_handleMonthKeyDown`\n/ `_handleYearKeyDown`) and only `Escape` — from the header — is\nhandled here, returning to the day grid."
15656
15964
  },
15657
15965
  {
15658
15966
  "kind": "method",
@@ -15673,6 +15981,18 @@
15673
15981
  ],
15674
15982
  "description": "Called on `pointerenter` for each day cell when in range mode\nduring the `start` phase."
15675
15983
  },
15984
+ {
15985
+ "kind": "field",
15986
+ "name": "ARROW_LABELS",
15987
+ "type": {
15988
+ "text": "Record<CalendarSurface, [string, string]>"
15989
+ },
15990
+ "privacy": "private",
15991
+ "static": true,
15992
+ "readonly": true,
15993
+ "default": "{ days: [\"Previous month\", \"Next month\"], months: [\"Previous year\", \"Next year\"], years: [\"Earlier years\", \"Later years\"], }",
15994
+ "description": "Accessible names for the header arrows on each surface."
15995
+ },
15676
15996
  {
15677
15997
  "kind": "method",
15678
15998
  "name": "_renderCalendar",
@@ -15683,6 +16003,49 @@
15683
16003
  }
15684
16004
  }
15685
16005
  },
16006
+ {
16007
+ "kind": "method",
16008
+ "name": "_renderTitle",
16009
+ "privacy": "private",
16010
+ "return": {
16011
+ "type": {
16012
+ "text": "TemplateResult"
16013
+ }
16014
+ },
16015
+ "description": "The month and year title. Both parts are controls that open a jump\nsurface, rendered as the plain heading text the title has always\nbeen; users discover them by clicking. Native `<button>`s rather\nthan `esp-button`: its chrome, padding, and focus surface would\nchange the header's footprint, and the `.cal-title-part` reset keeps\nthe typography identical to the former span. Each part stays\nrendered while its own surface is showing, carrying\n`aria-expanded=\"true\"` and `aria-controls` for it, so pressing it\nagain returns to the day grid. The single space between the parts\nis literal so the title keeps its width."
16016
+ },
16017
+ {
16018
+ "kind": "method",
16019
+ "name": "_renderDaySurface",
16020
+ "privacy": "private",
16021
+ "return": {
16022
+ "type": {
16023
+ "text": "TemplateResult"
16024
+ }
16025
+ }
16026
+ },
16027
+ {
16028
+ "kind": "method",
16029
+ "name": "_renderMonthSurface",
16030
+ "privacy": "private",
16031
+ "return": {
16032
+ "type": {
16033
+ "text": "TemplateResult"
16034
+ }
16035
+ },
16036
+ "description": "The twelve months of the title's year as a 3×4 listbox. A month with\nno selectable day under `min` / `max` is marked disabled but stays\nfocusable, so the roving tabindex can never land on an element that\nrefuses focus. The cells are native `<button>`s like the day cells:\nthey share `.day-cell`'s rest, hover, selected, disabled, and focus\nrules so the surfaces read as the same calendar, which `esp-button`'s\nown chrome would break."
16037
+ },
16038
+ {
16039
+ "kind": "method",
16040
+ "name": "_renderYearSurface",
16041
+ "privacy": "private",
16042
+ "return": {
16043
+ "type": {
16044
+ "text": "TemplateResult"
16045
+ }
16046
+ },
16047
+ "description": "The year window as a vertically scrolling listbox. Native `<button>`\ncells for the same reason as the month surface."
16048
+ },
15686
16049
  {
15687
16050
  "kind": "method",
15688
16051
  "name": "_renderGridRows",
@@ -16683,6 +17046,14 @@
16683
17046
  }
16684
17047
  }
16685
17048
  ]
17049
+ },
17050
+ {
17051
+ "kind": "variable",
17052
+ "name": "selected"
17053
+ },
17054
+ {
17055
+ "kind": "variable",
17056
+ "name": "disabled"
16686
17057
  }
16687
17058
  ],
16688
17059
  "exports": [
@@ -76118,6 +76489,48 @@
76118
76489
  "declarations": [],
76119
76490
  "exports": []
76120
76491
  },
76492
+ {
76493
+ "kind": "javascript-module",
76494
+ "path": "dist/shared/theme-properties.js",
76495
+ "declarations": [
76496
+ {
76497
+ "kind": "function",
76498
+ "name": "computeThemeProperties",
76499
+ "return": {
76500
+ "type": {
76501
+ "text": "Record<string, string>"
76502
+ }
76503
+ },
76504
+ "parameters": [
76505
+ {
76506
+ "name": "theme",
76507
+ "type": {
76508
+ "text": "EspalierTheme"
76509
+ },
76510
+ "description": "A resolved theme."
76511
+ },
76512
+ {
76513
+ "name": "scheme",
76514
+ "type": {
76515
+ "text": "ThemeScheme"
76516
+ },
76517
+ "description": "The scheme to compute, matching the theme it came from."
76518
+ }
76519
+ ],
76520
+ "description": "Compute every CSS custom property for a resolved theme and scheme.\n\nThe result is a flat record keyed by property name including the leading\n`--`, exactly as `esp-root` writes it: scheme indicator, seed, variant and\ndata colors, the lightness ramp, APCA-enforced semantic colors, data\ncompanions, the type and space scales, font families and weights, and the\noptional background-image and vellum properties a theme declares.\n\nPass a **resolved** theme — one merged over `DEFAULT_LIGHT_THEME` or\n`DEFAULT_DARK_THEME` with `mergeTheme` from `./shared/theme`. An unparseable\n`seedColor` yields an empty record rather than throwing, and an unresolvable\ncolor source falls back to the seed with a `console.warn`, so a bad theme\nrenders branded rather than broken; use `validateTheme(encodeTheme(partial))`\nfrom `./shared/theme` to surface those before rendering."
76521
+ }
76522
+ ],
76523
+ "exports": [
76524
+ {
76525
+ "kind": "js",
76526
+ "name": "computeThemeProperties",
76527
+ "declaration": {
76528
+ "name": "computeThemeProperties",
76529
+ "module": "dist/shared/theme-properties.js"
76530
+ }
76531
+ }
76532
+ ]
76533
+ },
76121
76534
  {
76122
76535
  "kind": "javascript-module",
76123
76536
  "path": "dist/shared/theme-swatches.js",
@@ -92546,6 +92959,104 @@
92546
92959
  ],
92547
92960
  "description": "Return `true` if the date falls outside the min/max range."
92548
92961
  },
92962
+ {
92963
+ "kind": "function",
92964
+ "name": "isMonthDisabled",
92965
+ "return": {
92966
+ "type": {
92967
+ "text": "boolean"
92968
+ }
92969
+ },
92970
+ "parameters": [
92971
+ {
92972
+ "name": "month",
92973
+ "type": {
92974
+ "text": "Temporal.PlainYearMonth"
92975
+ }
92976
+ },
92977
+ {
92978
+ "name": "min",
92979
+ "type": {
92980
+ "text": "Temporal.PlainDate | null"
92981
+ }
92982
+ },
92983
+ {
92984
+ "name": "max",
92985
+ "type": {
92986
+ "text": "Temporal.PlainDate | null"
92987
+ }
92988
+ }
92989
+ ],
92990
+ "description": "Return `true` when no day of the month is selectable under min/max.\nInverted bounds (`min` after `max`) leave no selectable day anywhere,\nso every month is disabled rather than only those outside both."
92991
+ },
92992
+ {
92993
+ "kind": "function",
92994
+ "name": "clampMonthToBounds",
92995
+ "return": {
92996
+ "type": {
92997
+ "text": "Temporal.PlainYearMonth"
92998
+ }
92999
+ },
93000
+ "parameters": [
93001
+ {
93002
+ "name": "month",
93003
+ "type": {
93004
+ "text": "Temporal.PlainYearMonth"
93005
+ }
93006
+ },
93007
+ {
93008
+ "name": "min",
93009
+ "type": {
93010
+ "text": "Temporal.PlainDate | null"
93011
+ }
93012
+ },
93013
+ {
93014
+ "name": "max",
93015
+ "type": {
93016
+ "text": "Temporal.PlainDate | null"
93017
+ }
93018
+ }
93019
+ ],
93020
+ "description": "Clamp a year-month into the selectable range, so jumping to a year\nwhose first or last months fall outside `min` / `max` lands on the\nnearest month that still has a selectable day."
93021
+ },
93022
+ {
93023
+ "kind": "function",
93024
+ "name": "generateYearWindow",
93025
+ "return": {
93026
+ "type": {
93027
+ "text": "number[]"
93028
+ }
93029
+ },
93030
+ "parameters": [
93031
+ {
93032
+ "name": "viewYear",
93033
+ "type": {
93034
+ "text": "number"
93035
+ }
93036
+ },
93037
+ {
93038
+ "name": "min",
93039
+ "type": {
93040
+ "text": "Temporal.PlainDate | null"
93041
+ }
93042
+ },
93043
+ {
93044
+ "name": "max",
93045
+ "type": {
93046
+ "text": "Temporal.PlainDate | null"
93047
+ }
93048
+ },
93049
+ {
93050
+ "name": "before",
93051
+ "default": "YEAR_WINDOW_BEFORE"
93052
+ },
93053
+ {
93054
+ "name": "after",
93055
+ "default": "YEAR_WINDOW_AFTER"
93056
+ }
93057
+ ],
93058
+ "description": "The years the year jump surface lists: a window around `viewYear`,\nclipped to `min` / `max` when they are set. Every year inside a\nclipped window has at least one selectable day, so nothing in it\nneeds disabling. When the view sits entirely outside the bounds the\nwindow opens at the nearer bound instead of coming back empty. Inverted\nbounds have no selectable year at all and yield an empty window; the\ncomponent keeps focus on a header control in that case."
93059
+ },
92549
93060
  {
92550
93061
  "kind": "function",
92551
93062
  "name": "getSelectedDate",
@@ -92666,6 +93177,30 @@
92666
93177
  "module": "dist/date-picker/helpers/calendar-grid.js"
92667
93178
  }
92668
93179
  },
93180
+ {
93181
+ "kind": "js",
93182
+ "name": "isMonthDisabled",
93183
+ "declaration": {
93184
+ "name": "isMonthDisabled",
93185
+ "module": "dist/date-picker/helpers/calendar-grid.js"
93186
+ }
93187
+ },
93188
+ {
93189
+ "kind": "js",
93190
+ "name": "clampMonthToBounds",
93191
+ "declaration": {
93192
+ "name": "clampMonthToBounds",
93193
+ "module": "dist/date-picker/helpers/calendar-grid.js"
93194
+ }
93195
+ },
93196
+ {
93197
+ "kind": "js",
93198
+ "name": "generateYearWindow",
93199
+ "declaration": {
93200
+ "name": "generateYearWindow",
93201
+ "module": "dist/date-picker/helpers/calendar-grid.js"
93202
+ }
93203
+ },
92669
93204
  {
92670
93205
  "kind": "js",
92671
93206
  "name": "getSelectedDate",
@@ -92734,6 +93269,41 @@
92734
93269
  "default": "[ \"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\", ]",
92735
93270
  "description": "Month names for the header."
92736
93271
  },
93272
+ {
93273
+ "kind": "variable",
93274
+ "name": "MONTH_SHORT_NAMES",
93275
+ "type": {
93276
+ "text": "array"
93277
+ },
93278
+ "default": "[ \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\", ]",
93279
+ "description": "Three-letter month labels for the month jump surface's 3×4 grid."
93280
+ },
93281
+ {
93282
+ "kind": "variable",
93283
+ "name": "MONTH_GRID_COLS",
93284
+ "type": {
93285
+ "text": "number"
93286
+ },
93287
+ "default": "3",
93288
+ "description": "Columns in the month jump surface."
93289
+ },
93290
+ {
93291
+ "kind": "variable",
93292
+ "name": "YEAR_WINDOW_BEFORE",
93293
+ "type": {
93294
+ "text": "number"
93295
+ },
93296
+ "default": "100",
93297
+ "description": "Years the year jump surface lists before and after the view year when\n`min` / `max` do not bound it. A hundred years back covers every\nrealistic birth date; fifty forward covers expiry and planning dates."
93298
+ },
93299
+ {
93300
+ "kind": "variable",
93301
+ "name": "YEAR_WINDOW_AFTER",
93302
+ "type": {
93303
+ "text": "number"
93304
+ },
93305
+ "default": "50"
93306
+ },
92737
93307
  {
92738
93308
  "kind": "variable",
92739
93309
  "name": "HOURS_12",
@@ -92786,6 +93356,38 @@
92786
93356
  "module": "dist/date-picker/helpers/constants.js"
92787
93357
  }
92788
93358
  },
93359
+ {
93360
+ "kind": "js",
93361
+ "name": "MONTH_SHORT_NAMES",
93362
+ "declaration": {
93363
+ "name": "MONTH_SHORT_NAMES",
93364
+ "module": "dist/date-picker/helpers/constants.js"
93365
+ }
93366
+ },
93367
+ {
93368
+ "kind": "js",
93369
+ "name": "MONTH_GRID_COLS",
93370
+ "declaration": {
93371
+ "name": "MONTH_GRID_COLS",
93372
+ "module": "dist/date-picker/helpers/constants.js"
93373
+ }
93374
+ },
93375
+ {
93376
+ "kind": "js",
93377
+ "name": "YEAR_WINDOW_BEFORE",
93378
+ "declaration": {
93379
+ "name": "YEAR_WINDOW_BEFORE",
93380
+ "module": "dist/date-picker/helpers/constants.js"
93381
+ }
93382
+ },
93383
+ {
93384
+ "kind": "js",
93385
+ "name": "YEAR_WINDOW_AFTER",
93386
+ "declaration": {
93387
+ "name": "YEAR_WINDOW_AFTER",
93388
+ "module": "dist/date-picker/helpers/constants.js"
93389
+ }
93390
+ },
92789
93391
  {
92790
93392
  "kind": "js",
92791
93393
  "name": "HOURS_12",
@@ -92929,7 +93531,7 @@
92929
93531
  {
92930
93532
  "kind": "variable",
92931
93533
  "name": "datePickerStyles",
92932
- "default": "css` /* ── Error state ─────────────────────────────────── */ .temporal-error { font-family: var( --_esp-font-body-effective, var(--esp-font-body, var(--_esp-font-body-fallback)) ); font-size: var(--esp-type-small); color: var(--esp-color-danger-text); padding: var(--esp-size-padding); } /* ── Trigger field ───────────────────────────────── */ .esp-field { display: grid; grid-template-columns: 1fr min-content; cursor: pointer; > input.esp-input { cursor: pointer; width: auto; } > .field-icon { display: grid; place-content: center; cursor: pointer; > svg { height: calc(1.2 * var(--esp-size-font)); width: calc(1.2 * var(--esp-size-font)); margin: 0 var(--esp-size-tiny); } } } /* ── Popover shell (native top-layer) ────────────── */ .picker-popover { position: fixed; inset: unset; margin: 0; padding: var(--esp-size-small); border-radius: var(--esp-size-border-radius); border: 1px solid var(--esp-color-border); background: var(--esp-color-layer-1); box-shadow: 0 4px 16px var(--esp-color-shadow); color: var(--esp-color-text); font-family: var( --_esp-font-body-effective, var(--esp-font-body, var(--_esp-font-body-fallback)) ); font-size: var(--esp-size-font); opacity: 0; transition: opacity 150ms ease-in; overflow: visible; } .picker-popover.visible { opacity: 1; } /* ── Calendar ────────────────────────────────────── */ .calendar { display: flex; flex-direction: column; gap: var(--esp-size-tiny); user-select: none; overflow: hidden; } .cal-body { will-change: transform; } .cal-header { display: flex; align-items: center; justify-content: space-between; padding-bottom: var(--esp-size-tiny); } .cal-title { font-weight: bold; font-size: var(--esp-type-normal); color: var(--esp-color-headings); } .nav-btn { display: grid; place-content: center; background: none; border: none; cursor: pointer; padding: var(--esp-size-tiny); border-radius: var(--esp-size-border-radius); color: var(--esp-color-text); transition: background-color 120ms ease; > svg { height: var(--esp-size-normal); width: var(--esp-size-normal); } &:hover { background-color: var(--esp-color-layer-3); } &:focus-visible { outline: 2px solid var(--esp-color-action-text); outline-offset: -2px; } } /* ── Weekday labels ──────────────────────────────── */ .weekday-row { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; } .weekday-label { font-size: var(--esp-type-tiny); font-weight: 600; color: var(--esp-color-headings); text-decoration: none; padding: var(--esp-size-tiny) 0; } /* ── Day grid ────────────────────────────────────── */ .day-grid { display: flex; flex-direction: column; } /* Show the focused-day ring only when the grid itself contains focus, so it disappears when the user tabs to the nav arrows or time picker. */ .day-grid:focus-within .day-cell.focused { outline: 2px solid var(--esp-color-action-text); outline-offset: -2px; z-index: 1; } .day-row { display: grid; grid-template-columns: repeat(7, 1fr); } /* ── Day cell ────────────────────────────────────── */ .day-cell { --_cell-size: 2.4em; position: relative; display: grid; place-content: center; width: var(--_cell-size); height: var(--_cell-size); border: none; border-radius: var(--esp-size-border-radius); background: none; cursor: pointer; font-family: inherit; font-size: inherit; color: var(--esp-color-text); transition: background-color 100ms ease, color 100ms ease; &:hover:not(.disabled):not(.selected) { background-color: var(--esp-color-layer-3); } &:focus-visible { outline: 2px solid var(--esp-color-action-text); outline-offset: -2px; z-index: 1; } /* Outside month — dim */ &.outside-month { opacity: 0.38; } /* Today ring */ &.today { font-weight: bold; box-shadow: inset 0 0 0 1px var(--esp-color-border); border-radius: var(--esp-size-border-radius); } /* Selected / range endpoints */ &.selected { background-color: var(--esp-color-layer-3); color: var(--esp-color-action-text); font-weight: bold; } /* Range span highlight — washed-out brand colour */ &.in-range { background-color: oklch(from var(--esp-color-layer-3) calc(l + 0.15) calc(c * 0.4) h); border-radius: 0; } &.range-start { border-radius: var(--esp-size-border-radius) 0 0 var(--esp-size-border-radius); } &.range-end { border-radius: 0 var(--esp-size-border-radius) var(--esp-size-border-radius) 0; } /* Disabled */ &.disabled { opacity: 0.3; cursor: not-allowed; } } /* ── Time picker ─────────────────────────────────── */ .time-picker { display: flex; align-items: center; flex-wrap: nowrap; gap: var(--esp-size-tiny); padding-top: var(--esp-size-small); border-top: 1px solid var(--esp-color-border); margin-top: var(--esp-size-small); white-space: nowrap; /* Push the action buttons to the right edge */ > esp-button:first-of-type { margin-left: auto; } } /* Only-time mode: no top border */ :host([mode=\"time\"]) .time-picker { border-top: none; margin-top: 0; padding-top: 0; } .popover-actions { display: flex; gap: var(--esp-size-tiny); align-items: center; justify-content: flex-end; padding-top: var(--esp-size-small); border-top: 1px solid var(--esp-color-border); margin-top: var(--esp-size-small); } .time-sep { font-size: var(--esp-type-medium); font-weight: bold; color: var(--esp-color-headings); padding: 0 2px; } `",
93534
+ "default": "css` /* ── Error state ─────────────────────────────────── */ .temporal-error { font-family: var( --_esp-font-body-effective, var(--esp-font-body, var(--_esp-font-body-fallback)) ); font-size: var(--esp-type-small); color: var(--esp-color-danger-text); padding: var(--esp-size-padding); } /* ── Trigger field ───────────────────────────────── */ .esp-field { display: grid; grid-template-columns: 1fr min-content; cursor: pointer; > input.esp-input { cursor: pointer; width: auto; } > .field-icon { display: grid; place-content: center; cursor: pointer; > svg { height: calc(1.2 * var(--esp-size-font)); width: calc(1.2 * var(--esp-size-font)); margin: 0 var(--esp-size-tiny); } } } /* ── Popover shell (native top-layer) ────────────── */ .picker-popover { position: fixed; inset: unset; margin: 0; padding: var(--esp-size-small); border-radius: var(--esp-size-border-radius); border: 1px solid var(--esp-color-border); background: var(--esp-color-layer-1); box-shadow: 0 4px 16px var(--esp-color-shadow); color: var(--esp-color-text); font-family: var( --_esp-font-body-effective, var(--esp-font-body, var(--_esp-font-body-fallback)) ); font-size: var(--esp-size-font); opacity: 0; transition: opacity 150ms ease-in; overflow: visible; } .picker-popover.visible { opacity: 1; } /* ── Calendar ────────────────────────────────────── */ .calendar { --_cell-size: 2.4em; display: flex; flex-direction: column; gap: var(--esp-size-tiny); user-select: none; /* Clip the swiping body, but with a margin so the title controls' outset focus ring (2px offset + 2px width) paints above the header: the header has no padding above the title, so a hard clip at the box edge cut the ring's top. Browsers without overflow-clip-margin clip at the edge, as hidden did. */ overflow: clip; overflow-clip-margin: 4px; } .cal-body { will-change: transform; } .cal-header { display: flex; align-items: center; justify-content: space-between; padding-bottom: var(--esp-size-tiny); } .cal-title { font-weight: bold; font-size: var(--esp-type-normal); color: var(--esp-color-headings); } /* The month and year are buttons that open the jump surfaces, but the title must look exactly as it did as a span: every native button default is reset and the typography is inherited from .cal-title. Users discover the controls by clicking; the pointer cursor is the only pointer affordance, and the focus ring shows for keyboard focus only. No hover or expanded treatment, by design. */ .cal-title-part { appearance: none; display: inline; margin: 0; padding: 0; border: 0; border-radius: var(--esp-size-border-radius); background: none; font: inherit; letter-spacing: inherit; color: inherit; cursor: pointer; /* Outset, unlike .nav-btn's inset ring: an inset ring would cross the glyphs of a padding-less control. The ring's top lies outside the calendar box; .calendar's overflow-clip-margin lets it paint. */ &:focus-visible { outline: 2px solid var(--esp-color-action-text); outline-offset: 2px; } } .nav-btn { display: grid; place-content: center; background: none; border: none; cursor: pointer; padding: var(--esp-size-tiny); border-radius: var(--esp-size-border-radius); color: var(--esp-color-text); transition: background-color 120ms ease; > svg { height: var(--esp-size-normal); width: var(--esp-size-normal); } &:hover { background-color: var(--esp-color-layer-3); } &:focus-visible { outline: 2px solid var(--esp-color-action-text); outline-offset: -2px; } } /* ── Weekday labels ──────────────────────────────── */ .weekday-row { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; } .weekday-label { font-size: var(--esp-type-tiny); font-weight: 600; color: var(--esp-color-headings); text-decoration: none; padding: var(--esp-size-tiny) 0; } /* ── Day grid ────────────────────────────────────── */ .day-grid { display: flex; flex-direction: column; } /* Show the focused-day ring only when the grid itself contains focus, so it disappears when the user tabs to the nav arrows or time picker. */ .day-grid:focus-within .day-cell.focused { outline: 2px solid var(--esp-color-action-text); outline-offset: -2px; z-index: 1; } .day-row { display: grid; grid-template-columns: repeat(7, 1fr); } /* ── Day, month, and year cells ──────────────────── */ /* The month and year surfaces reuse the day cell's rest, hover, selected, disabled, and focus treatments so they read as the same calendar; only the geometry and the day-specific states differ. */ .day-cell, .jump-cell { position: relative; display: grid; place-content: center; border: none; border-radius: var(--esp-size-border-radius); background: none; cursor: pointer; font-family: inherit; font-size: inherit; color: var(--esp-color-text); transition: background-color 100ms ease, color 100ms ease; &:hover:not(.disabled):not(.selected) { background-color: var(--esp-color-layer-3); } &:focus-visible { outline: 2px solid var(--esp-color-action-text); outline-offset: -2px; z-index: 1; } /* Selected / range endpoints */ &.selected { background-color: var(--esp-color-layer-3); color: var(--esp-color-action-text); font-weight: bold; } } .day-cell { width: var(--_cell-size); height: var(--_cell-size); /* Outside month — dim */ &.outside-month { opacity: 0.38; } /* Today ring */ &.today { font-weight: bold; box-shadow: inset 0 0 0 1px var(--esp-color-border); border-radius: var(--esp-size-border-radius); } /* Range span highlight — washed-out brand colour */ &.in-range { background-color: oklch(from var(--esp-color-layer-3) calc(l + 0.15) calc(c * 0.4) h); border-radius: 0; } &.range-start { border-radius: var(--esp-size-border-radius) 0 0 var(--esp-size-border-radius); } &.range-end { border-radius: 0 var(--esp-size-border-radius) var(--esp-size-border-radius) 0; } } /* Disabled — declared after the day-specific states at the same specificity, so a disabled day that is also outside the month keeps the disabled opacity, as it did before the surfaces shared the cell rules. */ .day-cell.disabled, .jump-cell.disabled { opacity: 0.3; cursor: not-allowed; } /* ── Month and year jump surfaces ────────────────── */ /* A surface fills the body, which is pinned to the day grid's measured height while the surface is showing (see _applySurfaceChange), so the popover keeps its footprint and position. */ .jump-surface { box-sizing: border-box; block-size: 100%; } .month-surface { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 1fr; gap: var(--esp-size-tiny); } .year-surface { /* Relative so each year's offsetTop is measured against the list, which is what _scrollYearIntoView positions by. */ position: relative; display: flex; flex-direction: column; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; } .year-cell { flex: 0 0 auto; min-block-size: var(--_cell-size); } /* ── Time picker ─────────────────────────────────── */ .time-picker { display: flex; align-items: center; flex-wrap: nowrap; gap: var(--esp-size-tiny); padding-top: var(--esp-size-small); border-top: 1px solid var(--esp-color-border); margin-top: var(--esp-size-small); white-space: nowrap; /* Push the action buttons to the right edge */ > esp-button:first-of-type { margin-left: auto; } } /* Only-time mode: no top border */ :host([mode=\"time\"]) .time-picker { border-top: none; margin-top: 0; padding-top: 0; } .popover-actions { display: flex; gap: var(--esp-size-tiny); align-items: center; justify-content: flex-end; padding-top: var(--esp-size-small); border-top: 1px solid var(--esp-color-border); margin-top: var(--esp-size-small); } .time-sep { font-size: var(--esp-type-medium); font-weight: bold; color: var(--esp-color-headings); padding: 0 2px; } `",
92933
93535
  "description": "Component-specific styles for `esp-date-picker`."
92934
93536
  }
92935
93537
  ],