kanto-ds 1.5.2 → 1.6.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.
Files changed (125) hide show
  1. package/README.md +10 -10
  2. package/dist/chunks/floating-B33g-M_1.js +63 -0
  3. package/dist/chunks/floating-B33g-M_1.js.map +1 -0
  4. package/dist/chunks/{index-STEEvEP7.js → index-TWJzttLX.js} +38 -15
  5. package/dist/chunks/index-TWJzttLX.js.map +1 -0
  6. package/dist/chunks/kt-calendar-CtwOby1R.js +780 -0
  7. package/dist/chunks/kt-calendar-CtwOby1R.js.map +1 -0
  8. package/dist/chunks/{kt-element-Djx2JcGl.js → kt-element-T0VbIBNp.js} +2 -2
  9. package/dist/chunks/{kt-element-Djx2JcGl.js.map → kt-element-T0VbIBNp.js.map} +1 -1
  10. package/dist/chunks/{listbox-llcUu_V-.js → listbox-LsUEyGhQ.js} +2 -2
  11. package/dist/chunks/{listbox-llcUu_V-.js.map → listbox-LsUEyGhQ.js.map} +1 -1
  12. package/dist/chunks/segmented-field-BBXR4XFL.js +384 -0
  13. package/dist/chunks/segmented-field-BBXR4XFL.js.map +1 -0
  14. package/dist/chunks/typed-date-CPAUNHzr.js +103 -0
  15. package/dist/chunks/typed-date-CPAUNHzr.js.map +1 -0
  16. package/dist/components/core/kt-avatar/kt-avatar.js +2 -2
  17. package/dist/components/core/kt-badge/kt-badge.js +2 -2
  18. package/dist/components/core/kt-button/kt-button.js +1 -1
  19. package/dist/components/core/kt-card/kt-card.js +1 -1
  20. package/dist/components/core/kt-code/kt-code.js +13 -13
  21. package/dist/components/core/kt-code/kt-code.js.map +1 -1
  22. package/dist/components/core/kt-icon/kt-icon.js +1 -1
  23. package/dist/components/core/kt-kbd/kt-kbd.js +5 -5
  24. package/dist/components/core/kt-kbd/kt-kbd.js.map +1 -1
  25. package/dist/components/core/kt-split-button/kt-split-button.js +3 -3
  26. package/dist/components/data/kt-chart/kt-chart.js +3 -3
  27. package/dist/components/data/kt-chart/kt-chart.js.map +1 -1
  28. package/dist/components/data/kt-meter/kt-meter.js +1 -1
  29. package/dist/components/data/kt-pagination/kt-pagination.js +2 -2
  30. package/dist/components/data/kt-stat/kt-stat.js +1 -1
  31. package/dist/components/data/kt-table/kt-table.js +85 -85
  32. package/dist/components/data/kt-table/kt-table.js.map +1 -1
  33. package/dist/components/data/kt-timeline/kt-timeline.js +1 -1
  34. package/dist/components/feedback/kt-alert/kt-alert.js +15 -15
  35. package/dist/components/feedback/kt-alert/kt-alert.js.map +1 -1
  36. package/dist/components/feedback/kt-empty-state/kt-empty-state.js +1 -1
  37. package/dist/components/feedback/kt-progress-bar/kt-progress-bar.js +1 -1
  38. package/dist/components/feedback/kt-skeleton/kt-skeleton.js +13 -13
  39. package/dist/components/feedback/kt-skeleton/kt-skeleton.js.map +1 -1
  40. package/dist/components/feedback/kt-toast/kt-toast.js +3 -3
  41. package/dist/components/feedback/kt-toast/kt-toast.js.map +1 -1
  42. package/dist/components/feedback/kt-toast-container/kt-toast-container.js +1 -1
  43. package/dist/components/feedback/kt-tooltip/kt-tooltip.js +1 -1
  44. package/dist/components/forms/kt-calendar/kt-calendar.d.ts +35 -9
  45. package/dist/components/forms/kt-calendar/kt-calendar.js +3 -3
  46. package/dist/components/forms/kt-checkbox/kt-checkbox.js +2 -2
  47. package/dist/components/forms/kt-date-input/kt-date-input.d.ts +65 -0
  48. package/dist/components/forms/kt-date-input/kt-date-input.js +241 -0
  49. package/dist/components/forms/kt-date-input/kt-date-input.js.map +1 -0
  50. package/dist/components/forms/kt-date-picker/kt-date-picker.d.ts +47 -3
  51. package/dist/components/forms/kt-date-picker/kt-date-picker.js +430 -199
  52. package/dist/components/forms/kt-date-picker/kt-date-picker.js.map +1 -1
  53. package/dist/components/forms/kt-drag-drop/kt-drag-drop.js +3 -3
  54. package/dist/components/forms/kt-drag-drop/kt-drag-drop.js.map +1 -1
  55. package/dist/components/forms/kt-form/kt-form.js +2 -2
  56. package/dist/components/forms/kt-input/kt-input.js +10 -10
  57. package/dist/components/forms/kt-input/kt-input.js.map +1 -1
  58. package/dist/components/forms/kt-input-menu/kt-input-menu.js +4 -4
  59. package/dist/components/forms/kt-label-input/kt-label-input.js +1 -1
  60. package/dist/components/forms/kt-multi-select/kt-multi-select.d.ts +113 -0
  61. package/dist/components/forms/kt-multi-select/kt-multi-select.js +532 -0
  62. package/dist/components/forms/kt-multi-select/kt-multi-select.js.map +1 -0
  63. package/dist/components/forms/kt-radio-group/kt-radio-group.js +56 -51
  64. package/dist/components/forms/kt-radio-group/kt-radio-group.js.map +1 -1
  65. package/dist/components/forms/kt-select/kt-select.js +4 -4
  66. package/dist/components/forms/kt-textarea/kt-textarea.js +2 -2
  67. package/dist/components/forms/kt-time-input/kt-time-input.d.ts +48 -0
  68. package/dist/components/forms/kt-time-input/kt-time-input.js +114 -0
  69. package/dist/components/forms/kt-time-input/kt-time-input.js.map +1 -0
  70. package/dist/components/forms/kt-toggle/kt-toggle.js +1 -1
  71. package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js +6 -6
  72. package/dist/components/navigation/kt-breadcrumb/kt-breadcrumb.js.map +1 -1
  73. package/dist/components/navigation/kt-header/kt-header.js +2 -2
  74. package/dist/components/navigation/kt-page-header/kt-page-header.js +1 -1
  75. package/dist/components/navigation/kt-segmented-control/kt-segmented-control.js +2 -2
  76. package/dist/components/navigation/kt-sub-menu-navigation/kt-sub-menu-navigation.js +2 -2
  77. package/dist/components/navigation/kt-tabs/kt-tabs.js +2 -2
  78. package/dist/components/navigation/kt-tabs/kt-tabs.js.map +1 -1
  79. package/dist/components/navigation/kt-toggle-button/kt-toggle-button.js +1 -1
  80. package/dist/components/navigation/kt-toggle-button-group/kt-toggle-button-group.js +2 -2
  81. package/dist/components/overlays/kt-collapsible/kt-collapsible.js +3 -3
  82. package/dist/components/overlays/kt-collapsible/kt-collapsible.js.map +1 -1
  83. package/dist/components/overlays/kt-confirm-dialog/kt-confirm-dialog.js +2 -2
  84. package/dist/components/overlays/kt-dropdown/kt-dropdown.js +24 -24
  85. package/dist/components/overlays/kt-dropdown/kt-dropdown.js.map +1 -1
  86. package/dist/components/overlays/kt-modal/kt-modal.js +2 -2
  87. package/dist/components/overlays/kt-side-panel/kt-side-panel.js +2 -2
  88. package/dist/custom-elements.json +2230 -842
  89. package/dist/index.d.ts +9 -1
  90. package/dist/index.js +316 -109
  91. package/dist/index.js.map +1 -1
  92. package/dist/internal/floating.d.ts +3 -0
  93. package/dist/internal/segmented-field.d.ts +114 -0
  94. package/dist/internal/segments.d.ts +30 -0
  95. package/dist/internal/strings.d.ts +30 -0
  96. package/dist/internal/typed-date.d.ts +33 -0
  97. package/dist/react/index.d.ts +23 -0
  98. package/dist/react/index.js +193 -169
  99. package/dist/react/index.js.map +1 -1
  100. package/dist/react/jsx.d.ts +20 -1
  101. package/dist/strings/index.js +1 -1
  102. package/dist/theme/accent.d.ts +51 -0
  103. package/dist/theme/appearance.d.ts +37 -0
  104. package/dist/tokens/README.md +100 -1
  105. package/dist/tokens/accents.css +80 -0
  106. package/dist/tokens/appearance.css +65 -0
  107. package/dist/tokens/base.css +3 -0
  108. package/dist/tokens/colors.css +78 -25
  109. package/dist/tokens/index.css +2 -0
  110. package/dist/tokens/responsive.css +160 -75
  111. package/dist/tokens/spacing.css +47 -28
  112. package/dist/tokens/theme-light.css +124 -38
  113. package/dist/tokens/typography.css +20 -13
  114. package/dist/vscode.css-custom-data.json +36 -1
  115. package/dist/vscode.html-custom-data.json +67 -2
  116. package/dist/vue/index.d.ts +6 -0
  117. package/dist/vue/index.js +11 -8
  118. package/dist/vue/index.js.map +1 -1
  119. package/dist/web-types.json +190 -3
  120. package/package.json +13 -1
  121. package/dist/chunks/floating-B7_Dahpn.js +0 -54
  122. package/dist/chunks/floating-B7_Dahpn.js.map +0 -1
  123. package/dist/chunks/index-STEEvEP7.js.map +0 -1
  124. package/dist/chunks/kt-calendar-B_hFdD9V.js +0 -640
  125. package/dist/chunks/kt-calendar-B_hFdD9V.js.map +0 -1
@@ -0,0 +1,241 @@
1
+ import { css as D, nothing as m, html as g } from "lit";
2
+ import { property as w, state as x, query as $ } from "lit/decorators.js";
3
+ import { classMap as C } from "lit/directives/class-map.js";
4
+ import { d as P } from "../../../chunks/kt-element-T0VbIBNp.js";
5
+ import { u as S, t as I } from "../../../chunks/events-r51msXNf.js";
6
+ import { F as q, f as E } from "../../../chunks/floating-B33g-M_1.js";
7
+ import { K as f } from "../../../chunks/segmented-field-BBXR4XFL.js";
8
+ import { d as y, p as u, t as v, c as b, f as Y } from "../../../chunks/kt-calendar-CtwOby1R.js";
9
+ import { d as K, e as L, t as M } from "../../../chunks/typed-date-CPAUNHzr.js";
10
+ import { s as l } from "../../../chunks/index-TWJzttLX.js";
11
+ import "../../core/kt-icon/kt-icon.js";
12
+ import "../../feedback/kt-tooltip/kt-tooltip.js";
13
+ var N = Object.defineProperty, c = (h, e, t, n) => {
14
+ for (var a = void 0, o = h.length - 1, i; o >= 0; o--)
15
+ (i = h[o]) && (a = i(e, t, a) || a);
16
+ return a && N(e, t, a), a;
17
+ };
18
+ class d extends f {
19
+ constructor() {
20
+ super(...arguments), this.calendar = !1, this.open = !1, this.placement = "bottom", this.panelId = S("kt-date-input-panel"), this.floating = new q(this, {
21
+ panel: () => this.shadowRoot?.querySelector(".panel"),
22
+ anchor: () => this.shadowRoot?.querySelector(".field"),
23
+ onPlace: (e) => {
24
+ this.placement = e === "top" ? "top" : "bottom";
25
+ }
26
+ }), this.onDocumentPointerDown = (e) => {
27
+ e.composedPath().includes(this) || this.close(!1);
28
+ };
29
+ }
30
+ static {
31
+ this.styles = [
32
+ f.styles,
33
+ E,
34
+ D`
35
+ :host {
36
+ position: relative;
37
+ }
38
+
39
+ .trigger {
40
+ display: inline-flex;
41
+ flex: none;
42
+ align-items: center;
43
+ justify-content: center;
44
+ width: calc(var(--field-height) - 12px);
45
+ height: calc(var(--field-height) - 12px);
46
+ margin-right: -4px;
47
+ padding: 0;
48
+ color: var(--text-muted);
49
+ background: none;
50
+ border: none;
51
+ border-radius: calc(var(--radius-input) - 2px);
52
+ cursor: pointer;
53
+ transition:
54
+ background-color var(--duration-instant),
55
+ color var(--duration-instant);
56
+ }
57
+ .trigger:hover:not(:disabled),
58
+ .trigger[aria-expanded='true'] {
59
+ color: var(--text-body);
60
+ background: var(--color-dark-22);
61
+ }
62
+ .trigger:disabled {
63
+ color: var(--text-disabled);
64
+ cursor: not-allowed;
65
+ }
66
+ .trigger:focus-visible {
67
+ outline: var(--outline-width) solid var(--color-primary-base);
68
+ }
69
+
70
+ /* Placed from the field by FloatingController. */
71
+ .panel {
72
+ box-sizing: border-box;
73
+ padding: var(--padding-expand);
74
+ background: var(--surface-popover);
75
+ border-radius: var(--radius-input);
76
+ visibility: hidden;
77
+ opacity: 0;
78
+ transform: translateY(-6px);
79
+ pointer-events: none;
80
+ transition:
81
+ opacity var(--duration-fast) var(--easing-standard),
82
+ transform var(--duration-fast) var(--easing-standard),
83
+ visibility 0s linear var(--duration-fast);
84
+ }
85
+ .panel.top:not(.open) {
86
+ transform: translateY(6px);
87
+ }
88
+ .panel.open {
89
+ visibility: visible;
90
+ opacity: 1;
91
+ transform: translateY(0);
92
+ pointer-events: auto;
93
+ transition:
94
+ opacity var(--duration-fast) var(--easing-standard),
95
+ transform var(--duration-fast) var(--easing-standard);
96
+ }
97
+ `
98
+ ];
99
+ }
100
+ // --- Segments ---
101
+ items() {
102
+ const e = l(), { order: t, separator: n } = K(this.resolvedLocale), a = Number(this.texts.month) || 0, o = this.texts.year?.length === 4 ? Number(this.texts.year) : 2e3, i = a >= 1 && a <= 12 ? y(o, a) : 31, r = {
103
+ day: {
104
+ key: "day",
105
+ label: e.segmentDay,
106
+ placeholder: e.placeholderDay,
107
+ spec: { min: 1, max: i, length: 2 }
108
+ },
109
+ month: {
110
+ key: "month",
111
+ label: e.segmentMonth,
112
+ placeholder: e.placeholderMonth,
113
+ spec: { min: 1, max: 12, length: 2 }
114
+ },
115
+ year: {
116
+ key: "year",
117
+ label: e.segmentYear,
118
+ placeholder: e.placeholderYear,
119
+ spec: { min: 1, max: 9999, length: 4 }
120
+ }
121
+ }, s = [];
122
+ return t.forEach((p, k) => {
123
+ k > 0 && s.push({ literal: n }), s.push(r[p]);
124
+ }), s;
125
+ }
126
+ fill(e) {
127
+ const t = u(e);
128
+ return t ? {
129
+ day: String(t.day).padStart(2, "0"),
130
+ month: String(t.month).padStart(2, "0"),
131
+ year: String(t.year).padStart(4, "0")
132
+ } : { day: "", month: "", year: "" };
133
+ }
134
+ read(e) {
135
+ const { day: t = "", month: n = "", year: a = "" } = e;
136
+ if (!t || !n || a.length < 4) return { value: null, error: "" };
137
+ const o = v(), i = {
138
+ value: null,
139
+ error: l().dateInvalid(L(this.resolvedLocale, o))
140
+ }, r = { year: Number(a), month: Number(n), day: Number(t) };
141
+ if (r.month < 1 || r.month > 12 || r.day < 1 || r.day > y(r.year, r.month)) return i;
142
+ const s = u(this.min), p = u(this.max);
143
+ return s && b(r, s) < 0 || p && b(r, p) > 0 ? { value: null, error: l().dateOutOfRange } : { value: Y(r), error: "" };
144
+ }
145
+ /** A year left at two digits is written out: 98 is 1998, 30 is 2030. */
146
+ completeOnBlur(e, t) {
147
+ if (e.key !== "year" || t.length === 0 || t.length > 2) return null;
148
+ const n = M(t, v().year);
149
+ return n === null ? null : String(n).padStart(4, "0");
150
+ }
151
+ requiredMessage() {
152
+ return l().dateRequired;
153
+ }
154
+ get expanded() {
155
+ return this.open;
156
+ }
157
+ // --- The calendar ---
158
+ disconnectedCallback() {
159
+ super.disconnectedCallback(), document.removeEventListener("pointerdown", this.onDocumentPointerDown);
160
+ }
161
+ // Untyped: `open` is private, so not among the keys PropertyValues<this> knows.
162
+ updated(e) {
163
+ e.has("open") && I(this.open, document, "pointerdown", this.onDocumentPointerDown), this.floating.sync(this.open);
164
+ }
165
+ async toggleCalendar() {
166
+ if (this.open) {
167
+ this.close(!0);
168
+ return;
169
+ }
170
+ this.inactive || (this.open = !0, await this.updateComplete, this.calendarElement?.focus());
171
+ }
172
+ close(e) {
173
+ this.open && (this.open = !1, e && this.focus());
174
+ }
175
+ onCalendarChange(e) {
176
+ e.stopPropagation(), this.commitValue(e.detail.value), this.close(!0);
177
+ }
178
+ onPanelKeyDown(e) {
179
+ e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), this.close(!0));
180
+ }
181
+ renderAfter() {
182
+ if (!this.calendar) return m;
183
+ const e = l();
184
+ return g`<button
185
+ part="trigger"
186
+ type="button"
187
+ class="trigger"
188
+ aria-label=${e.openCalendar}
189
+ aria-haspopup="dialog"
190
+ aria-expanded=${this.open ? "true" : "false"}
191
+ aria-controls=${this.panelId}
192
+ ?disabled=${this.inactive}
193
+ @click=${() => {
194
+ this.toggleCalendar();
195
+ }}
196
+ >
197
+ <kt-icon name="calendar" size="18"></kt-icon>
198
+ </button>
199
+ <div
200
+ part="panel"
201
+ id=${this.panelId}
202
+ popover="manual"
203
+ class=${C({
204
+ panel: !0,
205
+ floating: !0,
206
+ open: this.open,
207
+ top: this.placement === "top"
208
+ })}
209
+ role="dialog"
210
+ aria-modal="false"
211
+ aria-label=${e.selectDate}
212
+ @keydown=${this.onPanelKeyDown}
213
+ >
214
+ ${this.open ? g`<kt-calendar
215
+ .value=${this.value}
216
+ min=${this.min}
217
+ max=${this.max}
218
+ locale=${this.locale}
219
+ label=${this.label}
220
+ @kt-change=${this.onCalendarChange}
221
+ ></kt-calendar>` : m}
222
+ </div>`;
223
+ }
224
+ }
225
+ c([
226
+ w({ type: Boolean, reflect: !0 })
227
+ ], d.prototype, "calendar");
228
+ c([
229
+ x()
230
+ ], d.prototype, "open");
231
+ c([
232
+ x()
233
+ ], d.prototype, "placement");
234
+ c([
235
+ $("kt-calendar")
236
+ ], d.prototype, "calendarElement");
237
+ P("kt-date-input", d);
238
+ export {
239
+ d as KtDateInput
240
+ };
241
+ //# sourceMappingURL=kt-date-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kt-date-input.js","sources":["../../../../src/components/forms/kt-date-input/kt-date-input.ts"],"sourcesContent":["import { css, html, nothing, type PropertyValues, type TemplateResult } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { defineElement } from '#internal/kt-element';\nimport { toggleListener, uniqueId } from '#internal/events';\nimport { FloatingController, floatingStyles } from '#internal/floating';\nimport { KtSegmentedField, type FieldItem, type Segment } from '#internal/segmented-field';\nimport { compareDates, daysInMonth, formatDate, parseDate, today } from '#internal/date';\nimport { dateLayout, exampleDate, typedYear } from '#internal/typed-date';\nimport { strings } from '#internal/strings';\nimport '../kt-calendar/kt-calendar.js';\nimport type { KtCalendar } from '../kt-calendar/kt-calendar.js';\nimport '../../core/kt-icon/kt-icon.js';\nimport '../../feedback/kt-tooltip/kt-tooltip.js';\n\n/**\n * A date typed into its parts: day, month and year, each its own segment.\n *\n * The segments come in the order the reader's language writes a date —\n * `25/09/2026` in London, `09/25/2026` in New York, `25.09.2026` in Berlin —\n * and the focus moves on as each fills, so a date is eight keystrokes. The\n * arrows step a segment, a day never past its month's end. The value is ISO\n * 8601, `2026-09-25`, and `null` until the date is complete.\n *\n * With `calendar`, a button at the end opens a `<kt-calendar>` to pick from.\n *\n * @element kt-date-input\n *\n * @csspart field - The field.\n * @csspart segment - A day, month or year segment.\n * @csspart trigger - The calendar button, with `calendar`.\n * @csspart panel - The calendar popup, with `calendar`.\n *\n * @fires kt-change - The date became complete, changed, or stopped being one.\n * `detail: { value }` — the ISO date or `null`.\n *\n * @example\n * ```html\n * <kt-date-input label=\"Date of birth\" name=\"born\" max=\"2026-12-31\"></kt-date-input>\n * <kt-date-input label=\"Due date\" calendar value=\"2026-09-25\"></kt-date-input>\n * ```\n */\nexport class KtDateInput extends KtSegmentedField {\n static override styles = [\n KtSegmentedField.styles,\n floatingStyles,\n css`\n :host {\n position: relative;\n }\n\n .trigger {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: calc(var(--field-height) - 12px);\n height: calc(var(--field-height) - 12px);\n margin-right: -4px;\n padding: 0;\n color: var(--text-muted);\n background: none;\n border: none;\n border-radius: calc(var(--radius-input) - 2px);\n cursor: pointer;\n transition:\n background-color var(--duration-instant),\n color var(--duration-instant);\n }\n .trigger:hover:not(:disabled),\n .trigger[aria-expanded='true'] {\n color: var(--text-body);\n background: var(--color-dark-22);\n }\n .trigger:disabled {\n color: var(--text-disabled);\n cursor: not-allowed;\n }\n .trigger:focus-visible {\n outline: var(--outline-width) solid var(--color-primary-base);\n }\n\n /* Placed from the field by FloatingController. */\n .panel {\n box-sizing: border-box;\n padding: var(--padding-expand);\n background: var(--surface-popover);\n border-radius: var(--radius-input);\n visibility: hidden;\n opacity: 0;\n transform: translateY(-6px);\n pointer-events: none;\n transition:\n opacity var(--duration-fast) var(--easing-standard),\n transform var(--duration-fast) var(--easing-standard),\n visibility 0s linear var(--duration-fast);\n }\n .panel.top:not(.open) {\n transform: translateY(6px);\n }\n .panel.open {\n visibility: visible;\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n transition:\n opacity var(--duration-fast) var(--easing-standard),\n transform var(--duration-fast) var(--easing-standard);\n }\n `,\n ];\n\n /** Adds a button that opens a calendar to pick the date from. */\n @property({ type: Boolean, reflect: true })\n calendar = false;\n\n @state() private open = false;\n @state() private placement: 'bottom' | 'top' = 'bottom';\n\n @query('kt-calendar')\n private calendarElement?: KtCalendar;\n\n private readonly panelId = uniqueId('kt-date-input-panel');\n\n private floating = new FloatingController(this, {\n panel: () => this.shadowRoot?.querySelector<HTMLElement>('.panel'),\n anchor: () => this.shadowRoot?.querySelector('.field'),\n onPlace: (side) => {\n this.placement = side === 'top' ? 'top' : 'bottom';\n },\n });\n\n // --- Segments ---\n\n protected override items(): FieldItem[] {\n const s = strings();\n const { order, separator } = dateLayout(this.resolvedLocale);\n const month = Number(this.texts['month']) || 0;\n const year = this.texts['year']?.length === 4 ? Number(this.texts['year']) : 2000;\n // A day stops at its month's end once the month is known; a leap year\n // until the year is.\n const lastDay = month >= 1 && month <= 12 ? daysInMonth(year, month) : 31;\n\n const segments = {\n day: {\n key: 'day',\n label: s.segmentDay,\n placeholder: s.placeholderDay,\n spec: { min: 1, max: lastDay, length: 2 },\n },\n month: {\n key: 'month',\n label: s.segmentMonth,\n placeholder: s.placeholderMonth,\n spec: { min: 1, max: 12, length: 2 },\n },\n year: {\n key: 'year',\n label: s.segmentYear,\n placeholder: s.placeholderYear,\n spec: { min: 1, max: 9999, length: 4 },\n },\n };\n\n const items: FieldItem[] = [];\n order.forEach((part, index) => {\n if (index > 0) items.push({ literal: separator });\n items.push(segments[part]);\n });\n return items;\n }\n\n protected override fill(value: string | null): Record<string, string> {\n const date = parseDate(value);\n if (!date) return { day: '', month: '', year: '' };\n return {\n day: String(date.day).padStart(2, '0'),\n month: String(date.month).padStart(2, '0'),\n year: String(date.year).padStart(4, '0'),\n };\n }\n\n protected override read(texts: Record<string, string>): { value: string | null; error: string } {\n const { day = '', month = '', year = '' } = texts;\n // A year still being typed is not a year yet: four digits, or two written\n // out when the focus leaves them.\n if (!day || !month || year.length < 4) return { value: null, error: '' };\n\n const now = today();\n const invalid = {\n value: null,\n error: strings().dateInvalid(exampleDate(this.resolvedLocale, now)),\n };\n const date = { year: Number(year), month: Number(month), day: Number(day) };\n if (date.month < 1 || date.month > 12 || date.day < 1) return invalid;\n if (date.day > daysInMonth(date.year, date.month)) return invalid;\n\n const min = parseDate(this.min);\n const max = parseDate(this.max);\n if ((min && compareDates(date, min) < 0) || (max && compareDates(date, max) > 0)) {\n return { value: null, error: strings().dateOutOfRange };\n }\n return { value: formatDate(date), error: '' };\n }\n\n /** A year left at two digits is written out: 98 is 1998, 30 is 2030. */\n protected override completeOnBlur(segment: Segment, text: string): string | null {\n if (segment.key !== 'year' || text.length === 0 || text.length > 2) return null;\n const year = typedYear(text, today().year);\n return year === null ? null : String(year).padStart(4, '0');\n }\n\n protected override requiredMessage(): string {\n return strings().dateRequired;\n }\n\n protected override get expanded(): boolean {\n return this.open;\n }\n\n // --- The calendar ---\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n document.removeEventListener('pointerdown', this.onDocumentPointerDown);\n }\n\n // Untyped: `open` is private, so not among the keys PropertyValues<this> knows.\n override updated(changed: PropertyValues): void {\n if (changed.has('open')) {\n toggleListener(this.open, document, 'pointerdown', this.onDocumentPointerDown);\n }\n this.floating.sync(this.open);\n }\n\n private onDocumentPointerDown = (event: Event): void => {\n if (!event.composedPath().includes(this)) this.close(false);\n };\n\n private async toggleCalendar(): Promise<void> {\n if (this.open) {\n this.close(true);\n return;\n }\n if (this.inactive) return;\n this.open = true;\n await this.updateComplete;\n this.calendarElement?.focus();\n }\n\n private close(returnFocus: boolean): void {\n if (!this.open) return;\n this.open = false;\n if (returnFocus) this.focus();\n }\n\n private onCalendarChange(event: CustomEvent<{ value: string }>): void {\n // The calendar's own event stops here; the field reports its value.\n event.stopPropagation();\n this.commitValue(event.detail.value);\n this.close(true);\n }\n\n private onPanelKeyDown(event: KeyboardEvent): void {\n // The calendar keeps Escape while it shows its year and month panel.\n if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n this.close(true);\n }\n }\n\n protected override renderAfter(): TemplateResult | typeof nothing {\n if (!this.calendar) return nothing;\n const s = strings();\n return html`<button\n part=\"trigger\"\n type=\"button\"\n class=\"trigger\"\n aria-label=${s.openCalendar}\n aria-haspopup=\"dialog\"\n aria-expanded=${this.open ? 'true' : 'false'}\n aria-controls=${this.panelId}\n ?disabled=${this.inactive}\n @click=${() => void this.toggleCalendar()}\n >\n <kt-icon name=\"calendar\" size=\"18\"></kt-icon>\n </button>\n <div\n part=\"panel\"\n id=${this.panelId}\n popover=\"manual\"\n class=${classMap({\n panel: true,\n floating: true,\n open: this.open,\n top: this.placement === 'top',\n })}\n role=\"dialog\"\n aria-modal=\"false\"\n aria-label=${s.selectDate}\n @keydown=${this.onPanelKeyDown}\n >\n ${\n this.open\n ? html`<kt-calendar\n .value=${this.value}\n min=${this.min}\n max=${this.max}\n locale=${this.locale}\n label=${this.label}\n @kt-change=${this.onCalendarChange}\n ></kt-calendar>`\n : nothing\n }\n </div>`;\n }\n}\n\ndefineElement('kt-date-input', KtDateInput);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'kt-date-input': KtDateInput;\n }\n}\n"],"names":["KtDateInput","KtSegmentedField","uniqueId","FloatingController","side","event","floatingStyles","css","s","strings","order","separator","dateLayout","month","year","lastDay","daysInMonth","segments","items","part","index","value","date","parseDate","texts","day","now","today","invalid","exampleDate","min","max","compareDates","formatDate","segment","text","typedYear","changed","toggleListener","returnFocus","nothing","html","classMap","__decorateClass","property","state","query","defineElement"],"mappings":"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"}
@@ -2,7 +2,13 @@ import { type PropertyValues, type TemplateResult } from 'lit';
2
2
  import { KtElement } from '#internal/kt-element';
3
3
  import '../kt-calendar/kt-calendar.js';
4
4
  import '../../core/kt-icon/kt-icon.js';
5
+ import '../../feedback/kt-tooltip/kt-tooltip.js';
5
6
  export type KtDatePickerSize = 'small' | 'medium' | 'large';
7
+ /** A ready-made period offered beside the calendar: a label and an ISO interval. */
8
+ export interface KtDatePreset {
9
+ readonly label: string;
10
+ readonly value: string;
11
+ }
6
12
  /**
7
13
  * A date field with a calendar, for one day or a period.
8
14
  *
@@ -11,14 +17,22 @@ export type KtDatePickerSize = 'small' | 'medium' | 'large';
11
17
  * the field shows is the same date formatted for the reader's language, and
12
18
  * the calendar starts its weeks on the day their region does.
13
19
  *
20
+ * The field takes a date typed the way the reader writes it — `25/09/2026` in
21
+ * London, `9/25/2026` in New York, `25 sept.` in Paris, ISO anywhere — on Enter
22
+ * or when it is left. What does not read as a date is flagged, and the value
23
+ * it had is kept.
24
+ *
14
25
  * The popup is a `<kt-calendar>`, with its keyboard model and its month and
15
26
  * year views: the WAI-ARIA date picker dialog pattern, where Escape closes the
16
27
  * dialog and hands focus back to the field, and tabbing out closes it too.
17
28
  *
18
29
  * @element kt-date-picker
19
30
  *
20
- * @csspart trigger - The field.
31
+ * @csspart field - The field.
32
+ * @csspart input - The text the date is typed into.
33
+ * @csspart trigger - The button that opens the calendar.
21
34
  * @csspart panel - The calendar popup.
35
+ * @csspart presets - The column of ready-made periods, with `range`.
22
36
  * @csspart calendar - The `<kt-calendar>` inside it.
23
37
  *
24
38
  * @fires kt-change - A date or a whole period was chosen, or the value cleared.
@@ -33,12 +47,20 @@ export type KtDatePickerSize = 'small' | 'medium' | 'large';
33
47
  export declare class KtDatePicker extends KtElement {
34
48
  static readonly formAssociated = true;
35
49
  static styles: import("lit").CSSResultGroup[];
36
- private trigger?;
50
+ private input?;
37
51
  private calendar?;
38
52
  private internals;
39
53
  private defaultValue;
40
54
  private readonly panelId;
41
55
  private open;
56
+ /** What is typed, while it differs from the value shown. */
57
+ private text;
58
+ private editing;
59
+ /** Why the typed text was turned down, if it was. */
60
+ private typedError;
61
+ private focused;
62
+ /** Set at each opening on a narrow screen: one month, the periods above it. */
63
+ private compact;
42
64
  private placement;
43
65
  private floating;
44
66
  /** ISO date, or `start/end` interval with `range`. `null` when empty. */
@@ -68,6 +90,12 @@ export declare class KtDatePicker extends KtElement {
68
90
  required: boolean;
69
91
  /** Shows a button that empties the field once it holds a value. */
70
92
  clearable: boolean;
93
+ /**
94
+ * Ready-made periods offered beside the calendar, with `range`. Unset: the
95
+ * periods a dashboard asks for most — today, the last 7 and 30 days, this
96
+ * month and last, this year. An empty list hides the column.
97
+ */
98
+ presets: readonly KtDatePreset[] | undefined;
71
99
  /** Error message. A non-empty value puts the field in its error state. */
72
100
  error: string;
73
101
  connectedCallback(): void;
@@ -89,12 +117,28 @@ export declare class KtDatePicker extends KtElement {
89
117
  private onDocumentPointerDown;
90
118
  /** Tabbing out of the calendar closes it; moving within it does not. */
91
119
  private onFocusOut;
120
+ /** Below this width, a period's two months and their periods do not fit. */
121
+ private static readonly WIDE_ENOUGH;
92
122
  private show;
93
123
  private close;
94
124
  private toggle;
125
+ /** A click in the text opens the calendar, leaving the focus to type. */
126
+ private openForTyping;
95
127
  private onCalendarChange;
128
+ /** A preset, or today: committed at once, the calendar closed. */
129
+ private apply;
130
+ /** Whether any of a period falls outside min and max. */
131
+ private outOfBounds;
132
+ private renderPresets;
96
133
  private clear;
97
- private onTriggerKeyDown;
134
+ private onInput;
135
+ /**
136
+ * Reads what was typed into the value. Text that is not a date, or is a date
137
+ * outside min and max, is flagged and the value kept; an empty field empties
138
+ * the value.
139
+ */
140
+ private commitTyped;
141
+ private onInputKeyDown;
98
142
  private onPanelKeyDown;
99
143
  render(): TemplateResult;
100
144
  }