@verbb/plugin-kit-web 2.0.4 → 2.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/chunks/decorate-W02hmVTt.js.map +1 -1
- package/dist/chunks/{pk-calendar-CcV-La-9.js → pk-calendar-TEFA09cI.js} +61 -6
- package/dist/chunks/pk-calendar-TEFA09cI.js.map +1 -0
- package/dist/chunks/{pk-color-input-D4L0DE5S.js → pk-color-input-CNnmHJJB.js} +10 -2
- package/dist/chunks/{pk-color-input-D4L0DE5S.js.map → pk-color-input-CNnmHJJB.js.map} +1 -1
- package/dist/chunks/{pk-date-picker-DIoQlPI9.js → pk-date-picker-x-qkpQWF.js} +26 -6
- package/dist/chunks/pk-date-picker-x-qkpQWF.js.map +1 -0
- package/dist/chunks/{pk-editable-table-wtsSKfzS.js → pk-editable-table-DVqOEz3W.js} +3 -3
- package/dist/chunks/pk-editable-table-DVqOEz3W.js.map +1 -0
- package/dist/chunks/{register-22v142C-.js → register-BYPBQHrq.js} +5 -5
- package/dist/chunks/{register-22v142C-.js.map → register-BYPBQHrq.js.map} +1 -1
- package/dist/components/calendar/pk-calendar.d.ts +5 -1
- package/dist/components/calendar/pk-calendar.d.ts.map +1 -1
- package/dist/components/calendar/pk-calendar.js +1 -1
- package/dist/components/calendar.js +1 -1
- package/dist/components/color-input/pk-color-input.d.ts +1 -0
- package/dist/components/color-input/pk-color-input.d.ts.map +1 -1
- package/dist/components/color-input/pk-color-input.js +1 -1
- package/dist/components/color-input.js +1 -1
- package/dist/components/date-picker/pk-date-picker.d.ts +9 -1
- package/dist/components/date-picker/pk-date-picker.d.ts.map +1 -1
- package/dist/components/date-picker/pk-date-picker.js +1 -1
- package/dist/components/date-picker.js +1 -1
- package/dist/components/editable-table/pk-editable-table.d.ts +1 -1
- package/dist/components/editable-table/pk-editable-table.d.ts.map +1 -1
- package/dist/components/editable-table/pk-editable-table.js +1 -1
- package/dist/components/editable-table.js +1 -1
- package/dist/index.js +5 -5
- package/dist/register.js +5 -5
- package/dist/utils/date.d.ts +9 -0
- package/dist/utils/date.d.ts.map +1 -1
- package/dist-loader/chunks/{pk-calendar-Ir5izQJH.js → pk-calendar-CoJWxcxi.js} +60 -5
- package/dist-loader/chunks/{pk-color-input-BEmVZXSP.js → pk-color-input-B73zaGYj.js} +9 -1
- package/dist-loader/chunks/{pk-date-picker-B3eWgHtv.js → pk-date-picker-CE4TlRRZ.js} +25 -5
- package/dist-loader/chunks/{pk-field-CIfymz5G.js → pk-field-BbKmQmTF.js} +226 -134
- package/dist-loader/components/calendar/calendar.js +1 -1
- package/dist-loader/components/color-input/color-input.js +1 -1
- package/dist-loader/components/date-picker/date-picker.js +1 -1
- package/dist-loader/components/editable-table/editable-table.js +2 -2
- package/dist-loader/components/field/field.js +1 -1
- package/dist-loader/components/tiptap/tiptap-editor.js +1 -1
- package/package.json +7 -7
- package/dist/chunks/pk-calendar-CcV-La-9.js.map +0 -1
- package/dist/chunks/pk-date-picker-DIoQlPI9.js.map +0 -1
- package/dist/chunks/pk-editable-table-wtsSKfzS.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 2.0.6 - 2026-07-21
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- Released alongside the other `@verbb/plugin-kit-*` packages to keep versions aligned.
|
|
9
|
+
|
|
10
|
+
## 2.0.5 - 2026-07-21
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `pk-calendar` and `pk-date-picker` gain a third `mode`, `multiple`, alongside `single` / `range`. Multi-date selection serializes as a comma-separated, deduped, ascending-sorted ISO list (e.g. `2026-01-03,2026-01-05`) for both the `value` property and the submitted form value; clicking a day toggles it and the panel stays open, with a `"N dates selected"` count summary. New `parseDateList` / `formatDateList` / `toggleDateInList` helpers in `utils/date`.
|
|
14
|
+
- `pk-color-input` gains a `readonly` boolean (matching `pk-input`): the hex field is read-only, the native swatch picker is disabled, and input handlers no-op.
|
|
15
|
+
|
|
5
16
|
## 2.0.4 - 2026-07-21
|
|
6
17
|
|
|
7
18
|
### Fixed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorate-W02hmVTt.js","names":[],"sources":["../../src/base/styles.ts","../../src/base/shadow-reset.styles.ts","../../src/base/pk-element.ts"],"sourcesContent":["import { css, unsafeCSS, type CSSResultGroup } from 'lit';\n\nconst sharedStyleSheets = new Map<string, CSSStyleSheet>();\n\n/**\n * Share constructable stylesheets across component instances ( pattern).\n * Falls back to an injected `<style>` tag when adoptedStyleSheets aren't supported.\n */\nexport function adoptStyles(\n shadowRoot: ShadowRoot,\n styleResults: CSSResultGroup[],\n cacheKey?: string,\n): void {\n const cssText = styleResults\n .flatMap((result) => (Array.isArray(result) ? result : [result]))\n .map((result) => {\n if ('cssText' in result && typeof result.cssText === 'string') {\n return result.cssText;\n }\n\n return unsafeCSS(result).cssText;\n })\n .join('\\n');\n\n if (!('adoptedStyleSheets' in Document.prototype) || typeof CSSStyleSheet === 'undefined') {\n const styleKey = cacheKey ?? String(styleResults.length);\n\n if (!shadowRoot.querySelector(`style[data-pk-adopted-styles=\"${styleKey}\"]`)) {\n const style = document.createElement('style');\n style.dataset.pkAdoptedStyles = styleKey;\n style.textContent = cssText;\n shadowRoot.prepend(style);\n }\n\n return;\n }\n\n const key = cacheKey ?? cssText;\n let sheet = sharedStyleSheets.get(key);\n\n if (!sheet) {\n sheet = new CSSStyleSheet();\n sheet.replaceSync(cssText);\n sharedStyleSheets.set(key, sheet);\n }\n\n shadowRoot.adoptedStyleSheets = [...shadowRoot.adoptedStyleSheets, sheet];\n}\n\nexport const hostDisplayInlineBlock = css`\n @layer pk-component {\n :host {\n display: inline-block;\n vertical-align: middle;\n }\n }\n`;\n\nexport const focusRing = css`\n .pk-focus-ring:focus {\n outline: none;\n }\n\n .pk-focus-ring:focus-visible {\n box-shadow: var(--pk-shadow-focus);\n }\n`;\n","import { css } from 'lit';\n\n/**\n * Shadow-root baseline — box model + inherited typography inside every pk-* component.\n * Applied via PkElement.createRenderRoot(); does not replace per-component styles.\n */\nexport const shadowResetStyles = css`\n @layer pk-reset {\n :host {\n box-sizing: border-box;\n }\n\n :host *,\n :host *::before,\n :host *::after {\n box-sizing: border-box;\n }\n\n :host(:not([hidden])) {\n /* Prevent UA / CP margin on unstyled custom element hosts in light DOM. */\n margin: 0;\n }\n }\n`;\n","import { LitElement } from 'lit';\n\nimport { adoptStyles } from './styles.js';\nimport { shadowResetStyles } from './shadow-reset.styles.js';\n\nexport type PkElementErrorDetail = {\n tagName: string;\n message: string;\n stack?: string;\n};\n\ndeclare global {\n interface GlobalEventHandlersEventMap {\n 'pk-error': CustomEvent<PkElementErrorDetail>;\n }\n}\n\n/**\n * Base class for Plugin Kit web components.\n * Open shadow root; Lit adopts constructable stylesheets where supported.\n *\n * `performUpdate` is wrapped so a single control failure degrades inline instead of\n * taking down the whole CP surface (React error boundaries do not see Lit throws).\n */\nexport class PkElement extends LitElement {\n static override shadowRootOptions: ShadowRootInit = {\n mode: 'open',\n delegatesFocus: true,\n };\n\n /** When set, subclasses should skip normal render — base shows a minimal error shell. */\n protected pkRenderFailed = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Host marker for document/shadow peers (e.g. Tailwind preflight). Must not set\n // attributes in the constructor — CE rules forbid that on createElement().\n if (!this.hasAttribute('data-pk')) {\n this.setAttribute('data-pk', '');\n }\n }\n\n override createRenderRoot(): HTMLElement | DocumentFragment {\n const root = super.createRenderRoot();\n adoptStyles(root as ShadowRoot, [shadowResetStyles], 'pk-shadow-reset');\n return root;\n }\n\n override performUpdate(): void {\n if (this.pkRenderFailed) {\n return;\n }\n\n try {\n const result = super.performUpdate();\n\n // Lit deprecates returning a Promise from performUpdate — handle async render\n // failures without making this override async (avoids dev-mode update-queue bugs).\n // Lit may return void; keep a Promise guard for older async performUpdate paths.\n if ((result as unknown) instanceof Promise) {\n void (result as Promise<unknown>).catch((error: unknown) => {\n this.handleRenderFailure(error);\n });\n }\n } catch (error) {\n this.handleRenderFailure(error);\n }\n }\n\n protected handleRenderFailure(error: unknown): void {\n const err = error instanceof Error ? error : new Error(String(error));\n this.pkRenderFailed = true;\n\n this.dispatchEvent(\n new CustomEvent<PkElementErrorDetail>('pk-error', {\n detail: {\n tagName: this.localName || this.tagName.toLowerCase(),\n message: err.message,\n stack: err.stack,\n },\n bubbles: true,\n composed: true,\n }),\n );\n\n // Last-resort inline fallback — plain DOM so we do not recurse through Lit render().\n try {\n const root = this.renderRoot as ShadowRoot | HTMLElement | undefined;\n\n if (root) {\n root.textContent = '';\n const shell = document.createElement('div');\n shell.setAttribute('part', 'error');\n shell.setAttribute('role', 'alert');\n shell.textContent = 'This control failed to load.';\n root.appendChild(shell);\n }\n } catch {\n /* never throw from the error handler */\n }\n }\n}\n"],"mappings":";;AAEA,IAAM,oCAAoB,IAAI,KAA4B;;;;;AAM1D,SAAgB,YACZ,YACA,cACA,UACI;CACJ,MAAM,UAAU,aACX,SAAS,WAAY,MAAM,QAAQ,OAAO,GAAG,SAAS,CAAC,OAAO,CAAE,CAChE,KAAK,WAAW;AACb,MAAI,aAAa,UAAU,OAAO,OAAO,YAAY,SACjD,QAAO,OAAO;AAGlB,SAAO,UAAU,OAAO,CAAC;GAC3B,CACD,KAAK,KAAK;AAEf,KAAI,EAAE,wBAAwB,SAAS,cAAc,OAAO,kBAAkB,aAAa;EACvF,MAAM,WAAW,YAAY,OAAO,aAAa,OAAO;AAExD,MAAI,CAAC,WAAW,cAAc,iCAAiC,SAAS,IAAI,EAAE;GAC1E,MAAM,QAAQ,SAAS,cAAc,QAAQ;AAC7C,SAAM,QAAQ,kBAAkB;AAChC,SAAM,cAAc;AACpB,cAAW,QAAQ,MAAM;;AAG7B;;CAGJ,MAAM,MAAM,YAAY;CACxB,IAAI,QAAQ,kBAAkB,IAAI,IAAI;AAEtC,KAAI,CAAC,OAAO;AACR,UAAQ,IAAI,eAAe;AAC3B,QAAM,YAAY,QAAQ;AAC1B,oBAAkB,IAAI,KAAK,MAAM;;AAGrC,YAAW,qBAAqB,CAAC,GAAG,WAAW,oBAAoB,MAAM;;AAG7E,IAAa,yBAAyB,GAAG;;;;;;;;AAShB,GAAG;;;;;;;;;;;;;;;ACpD5B,IAAa,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;ACkBpC,IAAa,YAAb,cAA+B,WAAW;;;wBAOX;;;2BANyB;GAChD,MAAM;GACN,gBAAgB;GACnB;;CAKD,oBAAmC;AAC/B,QAAM,mBAAmB;AAGzB,MAAI,CAAC,KAAK,aAAa,UAAU,CAC7B,MAAK,aAAa,WAAW,GAAG;;CAIxC,mBAA4D;EACxD,MAAM,OAAO,MAAM,kBAAkB;AACrC,cAAY,MAAoB,CAAC,kBAAkB,EAAE,kBAAkB;AACvE,SAAO;;CAGX,gBAA+B;AAC3B,MAAI,KAAK,eACL;AAGJ,MAAI;GACA,MAAM,SAAS,MAAM,eAAe;AAKpC,OAAK,kBAA8B,QACzB,
|
|
1
|
+
{"version":3,"file":"decorate-W02hmVTt.js","names":[],"sources":["../../src/base/styles.ts","../../src/base/shadow-reset.styles.ts","../../src/base/pk-element.ts"],"sourcesContent":["import { css, unsafeCSS, type CSSResultGroup } from 'lit';\n\nconst sharedStyleSheets = new Map<string, CSSStyleSheet>();\n\n/**\n * Share constructable stylesheets across component instances ( pattern).\n * Falls back to an injected `<style>` tag when adoptedStyleSheets aren't supported.\n */\nexport function adoptStyles(\n shadowRoot: ShadowRoot,\n styleResults: CSSResultGroup[],\n cacheKey?: string,\n): void {\n const cssText = styleResults\n .flatMap((result) => (Array.isArray(result) ? result : [result]))\n .map((result) => {\n if ('cssText' in result && typeof result.cssText === 'string') {\n return result.cssText;\n }\n\n return unsafeCSS(result).cssText;\n })\n .join('\\n');\n\n if (!('adoptedStyleSheets' in Document.prototype) || typeof CSSStyleSheet === 'undefined') {\n const styleKey = cacheKey ?? String(styleResults.length);\n\n if (!shadowRoot.querySelector(`style[data-pk-adopted-styles=\"${styleKey}\"]`)) {\n const style = document.createElement('style');\n style.dataset.pkAdoptedStyles = styleKey;\n style.textContent = cssText;\n shadowRoot.prepend(style);\n }\n\n return;\n }\n\n const key = cacheKey ?? cssText;\n let sheet = sharedStyleSheets.get(key);\n\n if (!sheet) {\n sheet = new CSSStyleSheet();\n sheet.replaceSync(cssText);\n sharedStyleSheets.set(key, sheet);\n }\n\n shadowRoot.adoptedStyleSheets = [...shadowRoot.adoptedStyleSheets, sheet];\n}\n\nexport const hostDisplayInlineBlock = css`\n @layer pk-component {\n :host {\n display: inline-block;\n vertical-align: middle;\n }\n }\n`;\n\nexport const focusRing = css`\n .pk-focus-ring:focus {\n outline: none;\n }\n\n .pk-focus-ring:focus-visible {\n box-shadow: var(--pk-shadow-focus);\n }\n`;\n","import { css } from 'lit';\n\n/**\n * Shadow-root baseline — box model + inherited typography inside every pk-* component.\n * Applied via PkElement.createRenderRoot(); does not replace per-component styles.\n */\nexport const shadowResetStyles = css`\n @layer pk-reset {\n :host {\n box-sizing: border-box;\n }\n\n :host *,\n :host *::before,\n :host *::after {\n box-sizing: border-box;\n }\n\n :host(:not([hidden])) {\n /* Prevent UA / CP margin on unstyled custom element hosts in light DOM. */\n margin: 0;\n }\n }\n`;\n","import { LitElement } from 'lit';\n\nimport { adoptStyles } from './styles.js';\nimport { shadowResetStyles } from './shadow-reset.styles.js';\n\nexport type PkElementErrorDetail = {\n tagName: string;\n message: string;\n stack?: string;\n};\n\ndeclare global {\n interface GlobalEventHandlersEventMap {\n 'pk-error': CustomEvent<PkElementErrorDetail>;\n }\n}\n\n/**\n * Base class for Plugin Kit web components.\n * Open shadow root; Lit adopts constructable stylesheets where supported.\n *\n * `performUpdate` is wrapped so a single control failure degrades inline instead of\n * taking down the whole CP surface (React error boundaries do not see Lit throws).\n */\nexport class PkElement extends LitElement {\n static override shadowRootOptions: ShadowRootInit = {\n mode: 'open',\n delegatesFocus: true,\n };\n\n /** When set, subclasses should skip normal render — base shows a minimal error shell. */\n protected pkRenderFailed = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Host marker for document/shadow peers (e.g. Tailwind preflight). Must not set\n // attributes in the constructor — CE rules forbid that on createElement().\n if (!this.hasAttribute('data-pk')) {\n this.setAttribute('data-pk', '');\n }\n }\n\n override createRenderRoot(): HTMLElement | DocumentFragment {\n const root = super.createRenderRoot();\n adoptStyles(root as ShadowRoot, [shadowResetStyles], 'pk-shadow-reset');\n return root;\n }\n\n override performUpdate(): void {\n if (this.pkRenderFailed) {\n return;\n }\n\n try {\n const result = super.performUpdate();\n\n // Lit deprecates returning a Promise from performUpdate — handle async render\n // failures without making this override async (avoids dev-mode update-queue bugs).\n // Lit may return void; keep a Promise guard for older async performUpdate paths.\n if ((result as unknown) instanceof Promise) {\n void (result as unknown as Promise<unknown>).catch((error: unknown) => {\n this.handleRenderFailure(error);\n });\n }\n } catch (error) {\n this.handleRenderFailure(error);\n }\n }\n\n protected handleRenderFailure(error: unknown): void {\n const err = error instanceof Error ? error : new Error(String(error));\n this.pkRenderFailed = true;\n\n this.dispatchEvent(\n new CustomEvent<PkElementErrorDetail>('pk-error', {\n detail: {\n tagName: this.localName || this.tagName.toLowerCase(),\n message: err.message,\n stack: err.stack,\n },\n bubbles: true,\n composed: true,\n }),\n );\n\n // Last-resort inline fallback — plain DOM so we do not recurse through Lit render().\n try {\n const root = this.renderRoot as ShadowRoot | HTMLElement | undefined;\n\n if (root) {\n root.textContent = '';\n const shell = document.createElement('div');\n shell.setAttribute('part', 'error');\n shell.setAttribute('role', 'alert');\n shell.textContent = 'This control failed to load.';\n root.appendChild(shell);\n }\n } catch {\n /* never throw from the error handler */\n }\n }\n}\n"],"mappings":";;AAEA,IAAM,oCAAoB,IAAI,KAA4B;;;;;AAM1D,SAAgB,YACZ,YACA,cACA,UACI;CACJ,MAAM,UAAU,aACX,SAAS,WAAY,MAAM,QAAQ,OAAO,GAAG,SAAS,CAAC,OAAO,CAAE,CAChE,KAAK,WAAW;AACb,MAAI,aAAa,UAAU,OAAO,OAAO,YAAY,SACjD,QAAO,OAAO;AAGlB,SAAO,UAAU,OAAO,CAAC;GAC3B,CACD,KAAK,KAAK;AAEf,KAAI,EAAE,wBAAwB,SAAS,cAAc,OAAO,kBAAkB,aAAa;EACvF,MAAM,WAAW,YAAY,OAAO,aAAa,OAAO;AAExD,MAAI,CAAC,WAAW,cAAc,iCAAiC,SAAS,IAAI,EAAE;GAC1E,MAAM,QAAQ,SAAS,cAAc,QAAQ;AAC7C,SAAM,QAAQ,kBAAkB;AAChC,SAAM,cAAc;AACpB,cAAW,QAAQ,MAAM;;AAG7B;;CAGJ,MAAM,MAAM,YAAY;CACxB,IAAI,QAAQ,kBAAkB,IAAI,IAAI;AAEtC,KAAI,CAAC,OAAO;AACR,UAAQ,IAAI,eAAe;AAC3B,QAAM,YAAY,QAAQ;AAC1B,oBAAkB,IAAI,KAAK,MAAM;;AAGrC,YAAW,qBAAqB,CAAC,GAAG,WAAW,oBAAoB,MAAM;;AAG7E,IAAa,yBAAyB,GAAG;;;;;;;;AAShB,GAAG;;;;;;;;;;;;;;;ACpD5B,IAAa,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;ACkBpC,IAAa,YAAb,cAA+B,WAAW;;;wBAOX;;;2BANyB;GAChD,MAAM;GACN,gBAAgB;GACnB;;CAKD,oBAAmC;AAC/B,QAAM,mBAAmB;AAGzB,MAAI,CAAC,KAAK,aAAa,UAAU,CAC7B,MAAK,aAAa,WAAW,GAAG;;CAIxC,mBAA4D;EACxD,MAAM,OAAO,MAAM,kBAAkB;AACrC,cAAY,MAAoB,CAAC,kBAAkB,EAAE,kBAAkB;AACvE,SAAO;;CAGX,gBAA+B;AAC3B,MAAI,KAAK,eACL;AAGJ,MAAI;GACA,MAAM,SAAS,MAAM,eAAe;AAKpC,OAAK,kBAA8B,QACzB,QAAuC,OAAO,UAAmB;AACnE,SAAK,oBAAoB,MAAM;KACjC;WAED,OAAO;AACZ,QAAK,oBAAoB,MAAM;;;CAIvC,oBAA8B,OAAsB;EAChD,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AACrE,OAAK,iBAAiB;AAEtB,OAAK,cACD,IAAI,YAAkC,YAAY;GAC9C,QAAQ;IACJ,SAAS,KAAK,aAAa,KAAK,QAAQ,aAAa;IACrD,SAAS,IAAI;IACb,OAAO,IAAI;IACd;GACD,SAAS;GACT,UAAU;GACb,CAAC,CACL;AAGD,MAAI;GACA,MAAM,OAAO,KAAK;AAElB,OAAI,MAAM;AACN,SAAK,cAAc;IACnB,MAAM,QAAQ,SAAS,cAAc,MAAM;AAC3C,UAAM,aAAa,QAAQ,QAAQ;AACnC,UAAM,aAAa,QAAQ,QAAQ;AACnC,UAAM,cAAc;AACpB,SAAK,YAAY,MAAM;;UAEvB"}
|
|
@@ -69,6 +69,40 @@ function formatRange(range) {
|
|
|
69
69
|
if (!from && to) return formatIsoDate(to);
|
|
70
70
|
return `${formatIsoDate(from)}/${formatIsoDate(to)}`;
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Multi-date ("multiple" mode) serialization: a comma-separated list of ISO dates.
|
|
74
|
+
* Always parsed/emitted deduped and sorted ascending so the stored value is stable
|
|
75
|
+
* regardless of the order the user clicked days.
|
|
76
|
+
*/
|
|
77
|
+
function parseDateList(value) {
|
|
78
|
+
if (!value) return [];
|
|
79
|
+
const seen = /* @__PURE__ */ new Set();
|
|
80
|
+
const dates = [];
|
|
81
|
+
for (const part of value.split(",")) {
|
|
82
|
+
const date = parseIsoDate(part.trim());
|
|
83
|
+
if (!date) continue;
|
|
84
|
+
const iso = formatIsoDate(date);
|
|
85
|
+
if (seen.has(iso)) continue;
|
|
86
|
+
seen.add(iso);
|
|
87
|
+
dates.push(date);
|
|
88
|
+
}
|
|
89
|
+
dates.sort((a, b) => a.getTime() - b.getTime());
|
|
90
|
+
return dates;
|
|
91
|
+
}
|
|
92
|
+
function formatDateList(dates) {
|
|
93
|
+
const seen = /* @__PURE__ */ new Set();
|
|
94
|
+
for (const date of dates) {
|
|
95
|
+
const iso = formatIsoDate(date ?? null);
|
|
96
|
+
if (iso) seen.add(iso);
|
|
97
|
+
}
|
|
98
|
+
return [...seen].sort().join(",");
|
|
99
|
+
}
|
|
100
|
+
/** Toggle a day in/out of a multi-date list, returning the new sorted CSV value. */
|
|
101
|
+
function toggleDateInList(value, date) {
|
|
102
|
+
if (!formatIsoDate(date)) return value ?? "";
|
|
103
|
+
const existing = parseDateList(value);
|
|
104
|
+
return formatDateList(existing.some((entry) => isSameDay(entry, date)) ? existing.filter((entry) => !isSameDay(entry, date)) : [...existing, date]);
|
|
105
|
+
}
|
|
72
106
|
function isSameDay(a, b) {
|
|
73
107
|
if (!a || !b) return false;
|
|
74
108
|
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
@@ -807,6 +841,7 @@ var PkCalendar = class PkCalendar extends PkElement {
|
|
|
807
841
|
}
|
|
808
842
|
syncCustomStates() {
|
|
809
843
|
this.toggleAttribute("data-range", this.mode === "range");
|
|
844
|
+
this.toggleAttribute("data-multiple", this.mode === "multiple");
|
|
810
845
|
this.toggleAttribute("data-week-numbers", this.withWeekNumbers);
|
|
811
846
|
}
|
|
812
847
|
get resolvedLocale() {
|
|
@@ -815,8 +850,14 @@ var PkCalendar = class PkCalendar extends PkElement {
|
|
|
815
850
|
get resolvedToday() {
|
|
816
851
|
return parseIsoDate(this.today) ?? todayDate();
|
|
817
852
|
}
|
|
853
|
+
/** Representative selected date used to anchor the view/focus across all modes. */
|
|
854
|
+
get primarySelectedDate() {
|
|
855
|
+
if (this.mode === "single") return parseIsoDate(this.value);
|
|
856
|
+
if (this.mode === "multiple") return parseDateList(this.value)[0] ?? null;
|
|
857
|
+
return parseRange(this.value).from;
|
|
858
|
+
}
|
|
818
859
|
get resolvedFocusedDate() {
|
|
819
|
-
return parseIsoDate(this.focusedDate) ?? coerceToDate(this.
|
|
860
|
+
return parseIsoDate(this.focusedDate) ?? coerceToDate(this.primarySelectedDate) ?? this.resolvedToday;
|
|
820
861
|
}
|
|
821
862
|
get isDisabledMatcher() {
|
|
822
863
|
return buildDisabledMatcher({
|
|
@@ -851,6 +892,10 @@ var PkCalendar = class PkCalendar extends PkElement {
|
|
|
851
892
|
get valueAsRange() {
|
|
852
893
|
return parseRange(this.value);
|
|
853
894
|
}
|
|
895
|
+
/** Sorted, deduped selection for `multiple` mode (empty otherwise). */
|
|
896
|
+
get valueAsDates() {
|
|
897
|
+
return this.mode === "multiple" ? parseDateList(this.value) : [];
|
|
898
|
+
}
|
|
854
899
|
focus(options) {
|
|
855
900
|
const selector = this.view === "days" ? ".day.is-roving" : this.view === "months" ? ".view-item.is-roving" : ".view-item.is-roving";
|
|
856
901
|
this.renderRoot.querySelector(selector)?.focus(options);
|
|
@@ -919,6 +964,15 @@ var PkCalendar = class PkCalendar extends PkElement {
|
|
|
919
964
|
this.announce(formatDisplayDate(date, this.resolvedLocale));
|
|
920
965
|
return;
|
|
921
966
|
}
|
|
967
|
+
if (this.mode === "multiple") {
|
|
968
|
+
const wasSelected = parseDateList(this.value).some((entry) => isSameDay(entry, date));
|
|
969
|
+
this.value = toggleDateInList(this.value, date);
|
|
970
|
+
this.focusedDate = formatIsoDate(date);
|
|
971
|
+
this.emitInput();
|
|
972
|
+
this.emitChange();
|
|
973
|
+
this.announce(`${wasSelected ? "Removed" : "Added"} ${formatDisplayDate(date, this.resolvedLocale)}`);
|
|
974
|
+
return;
|
|
975
|
+
}
|
|
922
976
|
if (!this.rangeAnchor) {
|
|
923
977
|
this.rangeAnchor = date;
|
|
924
978
|
this.value = formatIsoDate(date);
|
|
@@ -1056,6 +1110,7 @@ var PkCalendar = class PkCalendar extends PkElement {
|
|
|
1056
1110
|
const isDisabled = this.isDisabledMatcher(date);
|
|
1057
1111
|
const range = parseRange(this.value);
|
|
1058
1112
|
const selectedSingle = this.mode === "single" && isSameDay(parseIsoDate(this.value), date);
|
|
1113
|
+
const selectedMultiple = this.mode === "multiple" && parseDateList(this.value).some((entry) => isSameDay(entry, date));
|
|
1059
1114
|
const rangeStart = this.mode === "range" && isSameDay(range.from, date);
|
|
1060
1115
|
const rangeEnd = this.mode === "range" && isSameDay(range.to, date);
|
|
1061
1116
|
const rangeInner = this.mode === "range" && range.from && range.to && date.getTime() > range.from.getTime() && date.getTime() < range.to.getTime();
|
|
@@ -1074,7 +1129,7 @@ var PkCalendar = class PkCalendar extends PkElement {
|
|
|
1074
1129
|
today: isSameDay(date, this.resolvedToday),
|
|
1075
1130
|
weekend: this.weekendDays.has(date.getDay()),
|
|
1076
1131
|
disabled: isDisabled,
|
|
1077
|
-
selected: selectedSingle || rangeStart || rangeEnd,
|
|
1132
|
+
selected: selectedSingle || selectedMultiple || rangeStart || rangeEnd,
|
|
1078
1133
|
rangeStart,
|
|
1079
1134
|
rangeEnd,
|
|
1080
1135
|
rangeInner: Boolean(rangeInner),
|
|
@@ -1174,7 +1229,7 @@ var PkCalendar = class PkCalendar extends PkElement {
|
|
|
1174
1229
|
renderMonthsView() {
|
|
1175
1230
|
const year = this.viewAnchor.getFullYear();
|
|
1176
1231
|
const formatter = new Intl.DateTimeFormat(this.resolvedLocale, { month: "long" });
|
|
1177
|
-
const selectedMonth =
|
|
1232
|
+
const selectedMonth = this.primarySelectedDate?.getMonth();
|
|
1178
1233
|
const rovingMonth = this.focusedMonth ?? this.resolvedFocusedDate.getMonth();
|
|
1179
1234
|
const items = [];
|
|
1180
1235
|
for (let monthIndex = 0; monthIndex < 12; monthIndex += 1) {
|
|
@@ -1213,7 +1268,7 @@ var PkCalendar = class PkCalendar extends PkElement {
|
|
|
1213
1268
|
renderYearsView() {
|
|
1214
1269
|
const centerYear = this.viewAnchor.getFullYear();
|
|
1215
1270
|
const decadeStart = Math.floor(centerYear / 12) * 12;
|
|
1216
|
-
const selectedYear =
|
|
1271
|
+
const selectedYear = this.primarySelectedDate?.getFullYear();
|
|
1217
1272
|
const rovingYear = this.focusedYear ?? this.resolvedFocusedDate.getFullYear();
|
|
1218
1273
|
const items = [];
|
|
1219
1274
|
for (let offset = 0; offset < 12; offset += 1) {
|
|
@@ -1405,6 +1460,6 @@ __decorate([state()], PkCalendar.prototype, "focusedYear", void 0);
|
|
|
1405
1460
|
__decorate([state()], PkCalendar.prototype, "daySlotNames", void 0);
|
|
1406
1461
|
PkCalendar = __decorate([customElement("pk-calendar")], PkCalendar);
|
|
1407
1462
|
//#endregion
|
|
1408
|
-
export {
|
|
1463
|
+
export { parseIsoDate as a, parseDateList as i, coerceToDate as n, parseRange as o, formatIsoDate as r, PkCalendar as t };
|
|
1409
1464
|
|
|
1410
|
-
//# sourceMappingURL=pk-calendar-
|
|
1465
|
+
//# sourceMappingURL=pk-calendar-TEFA09cI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pk-calendar-TEFA09cI.js","names":[],"sources":["../../src/utils/date.ts","../../src/utils/date-matchers.ts","../../src/utils/week-info.ts","../../src/components/calendar/pk-calendar.styles.ts","../../src/components/calendar/pk-calendar.ts"],"sourcesContent":["/** ISO date helpers — ported from `date-picker/internal/iso`. */\n\nconst ISO_DATE = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\n\nexport function parseIsoDate(value: string | Date | null | undefined): Date | null {\n if (value == null || value === '') {\n return null;\n }\n\n // React/v1 DatePicker often passes a Date; never call string methods on it.\n if (value instanceof Date) {\n return coerceToDate(value);\n }\n\n if (typeof value !== 'string') {\n return null;\n }\n\n const match = ISO_DATE.exec(value.trim());\n\n if (!match) {\n return null;\n }\n\n const year = Number(match[1]);\n const month = Number(match[2]);\n const day = Number(match[3]);\n\n if (month < 1 || month > 12 || day < 1 || day > 31) {\n return null;\n }\n\n const date = new Date(year, month - 1, day);\n\n if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {\n return null;\n }\n\n return date;\n}\n\nexport function formatIsoDate(date: Date | null | undefined): string {\n if (!date || Number.isNaN(date.getTime())) {\n return '';\n }\n\n const year = String(date.getFullYear()).padStart(4, '0');\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n\n return `${year}-${month}-${day}`;\n}\n\nexport function coerceToDate(value: unknown): Date | null {\n if (value == null) {\n return null;\n }\n\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) {\n return null;\n }\n\n return new Date(value.getFullYear(), value.getMonth(), value.getDate());\n }\n\n return parseIsoDate(String(value));\n}\n\nexport type DateRange = {\n from: Date | null;\n to: Date | null;\n};\n\nexport function parseRange(value: string | null | undefined): DateRange {\n if (!value) {\n return { from: null, to: null };\n }\n\n const parts = value.split('/');\n\n if (parts.length === 1) {\n return { from: parseIsoDate(parts[0]), to: null };\n }\n\n const from = parseIsoDate(parts[0]);\n const to = parseIsoDate(parts[1]);\n\n if (!from || !to) {\n return { from, to };\n }\n\n return from.getTime() <= to.getTime()\n ? { from, to }\n : { from: to, to: from };\n}\n\nexport function formatRange(range: DateRange | null | undefined): string {\n if (!range) {\n return '';\n }\n\n const { from, to } = range;\n\n if (!from && !to) {\n return '';\n }\n\n if (from && !to) {\n return formatIsoDate(from);\n }\n\n if (!from && to) {\n return formatIsoDate(to);\n }\n\n return `${formatIsoDate(from)}/${formatIsoDate(to)}`;\n}\n\n/**\n * Multi-date (\"multiple\" mode) serialization: a comma-separated list of ISO dates.\n * Always parsed/emitted deduped and sorted ascending so the stored value is stable\n * regardless of the order the user clicked days.\n */\nexport function parseDateList(value: string | null | undefined): Date[] {\n if (!value) {\n return [];\n }\n\n const seen = new Set<string>();\n const dates: Date[] = [];\n\n for (const part of value.split(',')) {\n const date = parseIsoDate(part.trim());\n\n if (!date) {\n continue;\n }\n\n const iso = formatIsoDate(date);\n\n if (seen.has(iso)) {\n continue;\n }\n\n seen.add(iso);\n dates.push(date);\n }\n\n dates.sort((a, b) => a.getTime() - b.getTime());\n\n return dates;\n}\n\nexport function formatDateList(dates: ReadonlyArray<Date | null | undefined>): string {\n const seen = new Set<string>();\n\n for (const date of dates) {\n const iso = formatIsoDate(date ?? null);\n\n if (iso) {\n seen.add(iso);\n }\n }\n\n return [...seen].sort().join(',');\n}\n\n/** Toggle a day in/out of a multi-date list, returning the new sorted CSV value. */\nexport function toggleDateInList(value: string | null | undefined, date: Date): string {\n const iso = formatIsoDate(date);\n\n if (!iso) {\n return value ?? '';\n }\n\n const existing = parseDateList(value);\n const next = existing.some((entry) => isSameDay(entry, date))\n ? existing.filter((entry) => !isSameDay(entry, date))\n : [...existing, date];\n\n return formatDateList(next);\n}\n\nexport function isSameDay(a: Date | null | undefined, b: Date | null | undefined): boolean {\n if (!a || !b) {\n return false;\n }\n\n return a.getFullYear() === b.getFullYear()\n && a.getMonth() === b.getMonth()\n && a.getDate() === b.getDate();\n}\n\nexport function isSameMonth(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();\n}\n\nexport function addDays(date: Date, days: number): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);\n}\n\nexport function addMonths(date: Date, months: number): Date {\n const target = new Date(date.getFullYear(), date.getMonth() + months, 1);\n const lastDay = daysInMonth(target.getFullYear(), target.getMonth());\n\n return new Date(target.getFullYear(), target.getMonth(), Math.min(date.getDate(), lastDay));\n}\n\nexport function addYears(date: Date, years: number): Date {\n return addMonths(date, years * 12);\n}\n\nexport function daysInMonth(year: number, month: number): number {\n return new Date(year, month + 1, 0).getDate();\n}\n\nexport function startOfMonth(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), 1);\n}\n\nexport function todayDate(): Date {\n const now = new Date();\n\n return new Date(now.getFullYear(), now.getMonth(), now.getDate());\n}\n\nexport function diffDays(a: Date, b: Date): number {\n const ms = a.getTime() - b.getTime();\n\n return Math.round(ms / 86_400_000);\n}\n\n/** ISO 8601 week number for the given date. */\nexport function isoWeekNumber(date: Date): number {\n const target = new Date(date.getFullYear(), date.getMonth(), date.getDate());\n const dayNum = (target.getDay() + 6) % 7;\n target.setDate(target.getDate() - dayNum + 3);\n\n const firstThursday = new Date(target.getFullYear(), 0, 4);\n const firstDayNum = (firstThursday.getDay() + 6) % 7;\n firstThursday.setDate(firstThursday.getDate() - firstDayNum + 3);\n\n return 1 + Math.round((target.getTime() - firstThursday.getTime()) / (7 * 86_400_000));\n}\n\nexport function formatDisplayDate(date: Date, locale?: string): string {\n return new Intl.DateTimeFormat(locale || undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n }).format(date);\n}\n","/** Date disabling matchers — ported from `date-picker/internal/matchers`. */\n\nimport {\n isSameDay,\n parseIsoDate,\n} from './date.js';\n\nexport type DisabledMatcherOptions = {\n min?: Date | null;\n max?: Date | null;\n disabledDates?: Date[];\n disabledDaysOfWeek?: number[];\n disablePast?: boolean;\n disableFuture?: boolean;\n today: Date;\n isDateDisabled?: (date: Date) => boolean;\n};\n\nexport function buildDisabledMatcher(options: DisabledMatcherOptions): (date: Date) => boolean {\n const {\n min,\n max,\n disabledDates = [],\n disabledDaysOfWeek = [],\n disablePast = false,\n disableFuture = false,\n today,\n isDateDisabled,\n } = options;\n\n const minTime = min?.getTime() ?? Number.NEGATIVE_INFINITY;\n const maxTime = max?.getTime() ?? Number.POSITIVE_INFINITY;\n const todayTime = today.getTime();\n const dayOfWeekSet = new Set(disabledDaysOfWeek);\n const dateTimeSet = new Set(disabledDates.map((date) => date.getTime()));\n\n return function isDisabled(date: Date): boolean {\n const time = date.getTime();\n\n if (time < minTime || time > maxTime) {\n return true;\n }\n\n if (disablePast && time < todayTime) {\n return true;\n }\n\n if (disableFuture && time > todayTime) {\n return true;\n }\n\n if (dayOfWeekSet.size && dayOfWeekSet.has(date.getDay())) {\n return true;\n }\n\n if (dateTimeSet.size && dateTimeSet.has(time)) {\n return true;\n }\n\n if (isDateDisabled?.(date)) {\n return true;\n }\n\n return false;\n };\n}\n\nexport function parseDisabledDates(value: string | string[] | Date[] | null | undefined): Date[] {\n if (value == null || value === '') {\n return [];\n }\n\n const list = Array.isArray(value) ? value : value.split(/\\s+/);\n const out: Date[] = [];\n\n for (const item of list) {\n if (item instanceof Date) {\n if (!Number.isNaN(item.getTime())) {\n out.push(new Date(item.getFullYear(), item.getMonth(), item.getDate()));\n }\n\n continue;\n }\n\n const parsed = parseIsoDate(String(item).trim());\n\n if (parsed) {\n out.push(parsed);\n }\n }\n\n return out;\n}\n\nconst WEEKDAY_NAMES = {\n sun: 0,\n mon: 1,\n tue: 2,\n wed: 3,\n thu: 4,\n fri: 5,\n sat: 6,\n} as const;\n\nexport type WeekdayName = keyof typeof WEEKDAY_NAMES;\n\nexport function parseDaysOfWeek(value: string | null | undefined): number[] {\n if (value == null || value === '') {\n return [];\n }\n\n const tokens = String(value).toLowerCase().split(/\\s+/).filter(Boolean);\n const out = new Set<number>();\n\n for (const token of tokens) {\n if (token in WEEKDAY_NAMES) {\n out.add(WEEKDAY_NAMES[token as WeekdayName]);\n }\n }\n\n return [...out];\n}\n\nexport function includesDay(arr: Date[], target: Date): boolean {\n return arr.some((date) => isSameDay(date, target));\n}\n\nexport function anyDisabledInRange(\n start: Date,\n end: Date,\n isDisabled: (date: Date) => boolean,\n): boolean {\n const rangeStart = start.getTime() <= end.getTime() ? start : end;\n const rangeEnd = start.getTime() <= end.getTime() ? end : start;\n const cursor = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), rangeStart.getDate());\n\n while (cursor.getTime() <= rangeEnd.getTime()) {\n if (isDisabled(cursor)) {\n return true;\n }\n\n cursor.setDate(cursor.getDate() + 1);\n }\n\n return false;\n}\n\nexport function allDisabledInRange(\n start: Date,\n end: Date,\n isDisabled: (date: Date) => boolean,\n): boolean {\n const rangeStart = start.getTime() <= end.getTime() ? start : end;\n const rangeEnd = start.getTime() <= end.getTime() ? end : start;\n const cursor = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), rangeStart.getDate());\n\n while (cursor.getTime() <= rangeEnd.getTime()) {\n if (!isDisabled(cursor)) {\n return false;\n }\n\n cursor.setDate(cursor.getDate() + 1);\n }\n\n return true;\n}\n","/** Locale week info — ported from `date-picker/internal/week-info`. */\n\nexport type WeekdayName = 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat';\n\nexport type WeekInfo = {\n /** First day of the week (1=Monday … 7=Sunday, per Intl spec). */\n firstDay: number;\n /** Weekend day numbers (1=Monday … 7=Sunday). */\n weekend: number[];\n};\n\nconst SUNDAY_FIRST = new Set([\n 'US', 'CA', 'MX', 'BR', 'JP', 'PH', 'IL', 'AU', 'NZ', 'ZA',\n 'CO', 'VE', 'PE', 'EC', 'GT', 'HN', 'NI', 'SV', 'CR', 'PA',\n 'DO', 'PR', 'JM', 'TT', 'BS', 'BB', 'BZ', 'BO', 'BM', 'TW',\n 'HK', 'MO', 'SG', 'TH', 'ET', 'KE',\n]);\n\nconst SATURDAY_FIRST = new Set(['SA', 'AE', 'QA', 'KW', 'BH', 'OM', 'YE', 'JO', 'SY', 'IQ', 'EG', 'SD', 'DZ', 'LY']);\n\nconst FRI_SAT_WEEKEND = new Set([\n 'SA', 'AE', 'QA', 'KW', 'BH', 'OM', 'YE', 'JO', 'EG', 'SD',\n 'DZ', 'LY', 'SY', 'IQ', 'IL',\n]);\n\nfunction regionFromLocale(locale: string): string | null {\n try {\n const parsed = new Intl.Locale(locale);\n const region = parsed.maximize().region;\n\n return region ?? null;\n } catch {\n return null;\n }\n}\n\nfunction fallbackWeekInfo(locale: string): WeekInfo {\n const region = regionFromLocale(locale);\n let firstDay = 1;\n\n if (region && SUNDAY_FIRST.has(region)) {\n firstDay = 7;\n } else if (region && SATURDAY_FIRST.has(region)) {\n firstDay = 6;\n }\n\n const weekend = region && FRI_SAT_WEEKEND.has(region) ? [5, 6] : [6, 7];\n\n return { firstDay, weekend };\n}\n\nexport function getWeekInfo(locale: string): WeekInfo {\n try {\n const parsed = new Intl.Locale(locale) as Intl.Locale & {\n getWeekInfo?: () => WeekInfo;\n weekInfo?: WeekInfo;\n };\n\n const info = typeof parsed.getWeekInfo === 'function'\n ? parsed.getWeekInfo()\n : parsed.weekInfo;\n\n if (info && typeof info.firstDay === 'number' && Array.isArray(info.weekend)) {\n return { firstDay: info.firstDay, weekend: info.weekend };\n }\n } catch {\n // fall through\n }\n\n return fallbackWeekInfo(locale);\n}\n\n/** Convert Intl first day (1=Mon..7=Sun) to JS `Date.getDay()` (0=Sun..6=Sat). */\nexport function intlFirstDayToJsDay(intlFirstDay: number): number {\n return intlFirstDay === 7 ? 0 : intlFirstDay;\n}\n\nexport function intlWeekendToJsDays(intlWeekend: number[]): number[] {\n return intlWeekend.map(intlFirstDayToJsDay);\n}\n\nexport function resolveFirstDayOfWeek(\n attribute: 'auto' | WeekdayName,\n locale: string,\n): number {\n if (attribute !== 'auto') {\n const map: Record<WeekdayName, number> = {\n sun: 0,\n mon: 1,\n tue: 2,\n wed: 3,\n thu: 4,\n fri: 5,\n sat: 6,\n };\n\n return map[attribute];\n }\n\n return intlFirstDayToJsDay(getWeekInfo(locale).firstDay);\n}\n","import { css } from 'lit';\n\nimport { iconStyles } from '../../base/icon.styles.js';\n\nexport const pkCalendarStyles = css`\n ${iconStyles}\n @layer pk-component {\n :host {\n display: inline-block;\n width: fit-content;\n max-width: 100%;\n color: var(--pk-color-gray-900);\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: 1;\n --pk-date-cell-size: 1.75rem;\n --pk-date-cell-radius: 100%;\n --pk-date-gap: 0.25rem;\n --pk-date-column-min: var(--pk-date-cell-size);\n --pk-date-column-gap: 0;\n }\n\n :host([weekday-format='short']) {\n --pk-date-column-min: 2.125rem;\n --pk-date-column-gap: 0.125rem;\n }\n\n :host([weekday-format='long']) {\n --pk-date-column-min: 3.375rem;\n --pk-date-column-gap: 0.125rem;\n }\n\n :host([weekday-format='long']) .weekday {\n font-size: 0.7rem;\n }\n\n :host([size='xs']) {\n --pk-date-cell-size: 1.5rem;\n font-size: 11px;\n }\n\n :host([size='sm']) {\n --pk-date-cell-size: 1.625rem;\n font-size: 12px;\n }\n\n :host([size='lg']) {\n --pk-date-cell-size: 2rem;\n font-size: 14px;\n }\n\n :host([size='xl']) {\n --pk-date-cell-size: 2.25rem;\n font-size: 15px;\n }\n\n :host([disabled]) {\n opacity: 0.5;\n pointer-events: none;\n }\n\n .base {\n display: flex;\n flex-direction: column;\n gap: var(--pk-date-gap);\n width: fit-content;\n padding: 0.5rem;\n border: var(--pk-calendar-border, var(--pk-input-border));\n border-radius: var(--pk-radius-md);\n background: var(--pk-calendar-background, var(--pk-color-white));\n }\n\n :host(:not([bordered])) {\n --pk-calendar-border: 0;\n --pk-calendar-background: transparent;\n }\n\n .header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.25rem;\n min-height: var(--pk-date-cell-size);\n padding-inline: 0.125rem;\n }\n\n .title {\n flex: 1;\n margin: 0;\n padding: 0.25rem 0.5rem;\n border: 0;\n border-radius: var(--pk-radius-sm);\n background: transparent;\n color: var(--pk-color-gray-900);\n font: inherit;\n font-size: 13px;\n font-weight: 500;\n line-height: 1.2;\n text-align: center;\n cursor: pointer;\n user-select: none;\n }\n\n .title:hover:not(:disabled) {\n background: var(--pk-color-slate-100);\n }\n\n .nav-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--pk-date-cell-size);\n height: var(--pk-date-cell-size);\n margin: 0;\n padding: 0.25rem;\n border: 0;\n border-radius: var(--pk-radius-sm);\n background: transparent;\n color: var(--pk-color-gray-600);\n cursor: pointer;\n }\n\n .nav-button:hover:not(:disabled) {\n background: var(--pk-color-slate-100);\n color: var(--pk-color-gray-900);\n }\n\n .nav-button:disabled {\n opacity: 0.35;\n cursor: not-allowed;\n }\n\n .nav-button .icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 12px;\n height: 12px;\n flex-shrink: 0;\n }\n\n .nav-button .icon svg {\n display: block;\n width: 12px;\n height: 12px;\n }\n\n .months {\n display: flex;\n gap: 1rem;\n }\n\n .month {\n display: flex;\n flex-direction: column;\n width: fit-content;\n min-width: calc(var(--pk-date-column-min) * 7 + var(--pk-date-column-gap) * 6);\n }\n\n :host([data-week-numbers]) .month {\n min-width: calc(\n var(--pk-date-cell-size) + var(--pk-date-column-gap) + var(--pk-date-column-min) * 7 + var(--pk-date-column-gap) * 6\n );\n }\n\n .month-label {\n margin-bottom: 0.5rem;\n font-size: 12px;\n font-weight: 500;\n text-align: center;\n color: var(--pk-color-gray-700);\n }\n\n .weekdays,\n .week {\n display: grid;\n grid-template-columns: repeat(7, minmax(var(--pk-date-column-min), 1fr));\n column-gap: var(--pk-date-column-gap);\n align-items: center;\n width: 100%;\n }\n\n :host([data-week-numbers]) .weekdays,\n :host([data-week-numbers]) .week {\n grid-template-columns: var(--pk-date-cell-size) repeat(7, minmax(var(--pk-date-column-min), 1fr));\n }\n\n .grid {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n width: 100%;\n margin-top: 0.2rem;\n }\n\n .weeknumber-header,\n .weeknumber {\n display: flex;\n align-items: center;\n justify-content: center;\n height: var(--pk-date-cell-size);\n color: var(--pk-color-gray-500);\n font-size: 0.8rem;\n font-weight: 400;\n user-select: none;\n }\n\n .weekday {\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: var(--pk-date-column-min);\n height: var(--pk-date-cell-size);\n padding-inline: 0.125rem;\n color: var(--pk-color-gray-500);\n font-size: 0.8rem;\n font-weight: 400;\n line-height: 1.1;\n text-align: center;\n white-space: nowrap;\n user-select: none;\n }\n\n .day,\n .day.is-placeholder {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n justify-self: center;\n width: var(--pk-date-cell-size);\n min-width: var(--pk-date-cell-size);\n max-width: var(--pk-date-cell-size);\n height: var(--pk-date-cell-size);\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: var(--pk-color-gray-900);\n font: inherit;\n font-size: 13px;\n font-weight: 400;\n line-height: 1;\n cursor: pointer;\n }\n\n .day.is-range-start,\n .day.is-range-end,\n .day.is-range-inner,\n .day.is-range-preview {\n justify-self: stretch;\n width: 100%;\n min-width: 0;\n max-width: none;\n }\n\n .day.is-range-start.is-range-end {\n justify-self: center;\n width: var(--pk-date-cell-size);\n min-width: var(--pk-date-cell-size);\n max-width: var(--pk-date-cell-size);\n }\n\n .day:focus-visible {\n outline: 2px solid var(--pk-color-blue-500);\n outline-offset: 1px;\n z-index: 1;\n }\n\n .day.is-outside {\n opacity: 0.6;\n }\n\n .day.is-disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n /* Day grid — circular today ring (fixed cell size, not column width) */\n .day.is-today:not(.is-range-start):not(.is-range-end):not(.is-range-inner)::after {\n content: '';\n position: absolute;\n inset: 0;\n border: 1px solid var(--pk-color-blue-500);\n border-radius: var(--pk-date-cell-radius);\n pointer-events: none;\n }\n\n .day.is-selected:not(.is-range-start):not(.is-range-end):not(.is-range-inner) {\n background: var(--pk-color-gray-200);\n border-radius: var(--pk-date-cell-radius);\n color: var(--pk-color-gray-900);\n font-weight: 400;\n }\n\n .day.is-range-start,\n .day.is-range-end {\n background: var(--pk-color-gray-200);\n color: var(--pk-color-gray-900);\n font-weight: 400;\n }\n\n .day.is-range-start.is-range-end {\n border-radius: var(--pk-date-cell-radius);\n }\n\n .day.is-range-start:not(.is-range-end) {\n border-radius: var(--pk-date-cell-radius) 0 0 var(--pk-date-cell-radius);\n }\n\n .day.is-range-end:not(.is-range-start) {\n border-radius: 0 var(--pk-date-cell-radius) var(--pk-date-cell-radius) 0;\n }\n\n .day.is-range-inner {\n background: var(--pk-color-gray-200);\n border-radius: 0;\n }\n\n .day.is-range-preview:not(.is-range-start):not(.is-range-end) {\n background: var(--pk-color-gray-200);\n opacity: 0.7;\n }\n\n .day.is-placeholder {\n visibility: hidden;\n pointer-events: none;\n }\n\n .live-region {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n slot[name='footer']::slotted(*) {\n display: block;\n padding-top: 0.25rem;\n }\n\n .view-grid {\n display: grid;\n grid-template-columns: repeat(3, minmax(var(--pk-date-cell-size), 1fr));\n gap: 0.25rem;\n width: 100%;\n min-width: calc(var(--pk-date-column-min) * 7 + var(--pk-date-column-gap) * 6);\n }\n\n .view-row {\n display: contents;\n }\n\n .view-cell {\n display: contents;\n }\n\n .view-item {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: var(--pk-date-cell-size);\n margin: 0;\n padding: 0.375rem 0.5rem;\n border: 0;\n border-radius: var(--pk-radius-sm);\n background: transparent;\n color: var(--pk-color-gray-900);\n font: inherit;\n font-size: 13px;\n cursor: pointer;\n }\n\n .view-item.is-selected {\n background: var(--pk-color-gray-200);\n font-weight: 500;\n }\n\n /* Month/year grid — rectangular today outline */\n .view-item.is-today:not(.is-selected) {\n box-shadow: inset 0 0 0 1px var(--pk-color-blue-500);\n border-radius: var(--pk-radius-sm);\n }\n\n .view-item.is-disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n .view-item:focus-visible {\n outline: 2px solid var(--pk-color-blue-500);\n outline-offset: 1px;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport type { PropertyValues } from 'lit';\n\nimport { chevronLeft, chevronRight, renderIconHtml } from '../../icons/index.js';\nimport { PkElement } from '../../base/pk-element.js';\nimport { HasSlotController } from '../../internal/has-slot.js';\nimport {\n addDays,\n addMonths,\n addYears,\n coerceToDate,\n diffDays,\n formatDisplayDate,\n formatIsoDate,\n formatRange,\n isoWeekNumber,\n isSameDay,\n isSameMonth,\n parseDateList,\n parseIsoDate,\n parseRange,\n startOfMonth,\n todayDate,\n toggleDateInList,\n type DateRange,\n} from '../../utils/date.js';\nimport {\n allDisabledInRange,\n buildDisabledMatcher,\n parseDaysOfWeek,\n parseDisabledDates,\n} from '../../utils/date-matchers.js';\nimport {\n getWeekInfo,\n intlWeekendToJsDays,\n resolveFirstDayOfWeek,\n type WeekdayName,\n} from '../../utils/week-info.js';\nimport { pkCalendarStyles } from './pk-calendar.styles.js';\n\nexport type PkCalendarMode = 'single' | 'range' | 'multiple';\nexport type PkCalendarSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl';\nexport type PkCalendarFirstDayOfWeek = 'auto' | WeekdayName;\nexport type PkCalendarView = 'days' | 'months' | 'years';\nexport type PkCalendarPageBy = 'months' | 'single';\nexport type PkCalendarDayContent = (date: Date) => string | null;\n\nconst CHEVRON_LEFT = renderIconHtml(chevronLeft);\nconst CHEVRON_RIGHT = renderIconHtml(chevronRight);\n\ntype DayState = {\n date: Date;\n monthAnchor: Date;\n outside: boolean;\n today: boolean;\n weekend: boolean;\n disabled: boolean;\n selected: boolean;\n rangeStart: boolean;\n rangeEnd: boolean;\n rangeInner: boolean;\n rangePreview: boolean;\n roving: boolean;\n};\n\n/**\n * Inline calendar grid — mirrors React `Calendar` ( `pk-date-picker` API).\n *\n * @slot previous-icon\n * @slot next-icon\n * @slot footer\n * @slot day-YYYY-MM-DD - Custom content for a specific day cell\n *\n * @event input - Value changes during interaction\n * @event change - User commits a new value\n * @event pk-focus-day - Focused day changed; `detail.date`\n * @event pk-view-change - View changed; `detail.view`, `detail.date`\n */\n@customElement('pk-calendar')\nexport class PkCalendar extends PkElement {\n static override styles = pkCalendarStyles;\n\n private readonly hasSlotController = new HasSlotController(this, 'footer', 'previous-icon', 'next-icon');\n\n @property({ reflect: true })\n mode: PkCalendarMode = 'single';\n\n @property({ reflect: true })\n size: PkCalendarSize = 'default';\n\n @property({ reflect: true })\n value = '';\n\n @property({ reflect: true })\n min = '';\n\n @property({ reflect: true })\n max = '';\n\n @property({ reflect: true })\n today = '';\n\n @property({ reflect: true })\n view: PkCalendarView = 'days';\n\n @property({ type: Number, reflect: true })\n months: 1 | 2 = 1;\n\n @property({ attribute: 'page-by', reflect: true })\n pageBy: PkCalendarPageBy = 'months';\n\n @property({ attribute: 'focused-date', reflect: true })\n focusedDate = '';\n\n @property({ attribute: 'first-day-of-week', reflect: true })\n firstDayOfWeek: PkCalendarFirstDayOfWeek = 'auto';\n\n @property({ attribute: 'with-outside-days', type: Boolean, reflect: true })\n withOutsideDays = true;\n\n @property({ attribute: 'with-week-numbers', type: Boolean, reflect: true })\n withWeekNumbers = false;\n\n @property({ attribute: 'weekday-format', reflect: true })\n weekdayFormat: 'narrow' | 'short' | 'long' = 'narrow';\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n /** When false, omits the outer frame — use inside popovers (e.g. `pk-date-picker`). */\n @property({ type: Boolean, reflect: true })\n bordered = true;\n\n @property({ attribute: 'disabled-dates' })\n disabledDatesRaw = '';\n\n @property({ attribute: 'disabled-days-of-week', reflect: true })\n disabledDaysOfWeek = '';\n\n @property({ attribute: 'disable-past', type: Boolean, reflect: true })\n disablePast = false;\n\n @property({ attribute: 'disable-future', type: Boolean, reflect: true })\n disableFuture = false;\n\n @property({ attribute: 'min-range', type: Number })\n minRange = 0;\n\n @property({ attribute: 'max-range', type: Number })\n maxRange = 0;\n\n @property({ reflect: true })\n locale = '';\n\n @property({ attribute: false })\n isDateDisabled?: (date: Date) => boolean;\n\n @property({ attribute: false })\n dayContent?: PkCalendarDayContent;\n\n @state()\n private viewAnchor = startOfMonth(todayDate());\n\n @state()\n private rangeAnchor: Date | null = null;\n\n @state()\n private hoverDate: Date | null = null;\n\n @state()\n private liveAnnouncement = '';\n\n @state()\n private focusedMonth: number | null = null;\n\n @state()\n private focusedYear: number | null = null;\n\n @state()\n private daySlotNames: string[] = [];\n\n private childrenObserver?: MutationObserver;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.syncViewAnchor();\n this.syncCustomStates();\n this.updateDaySlots();\n this.childrenObserver = new MutationObserver(() => this.updateDaySlots());\n this.childrenObserver.observe(this, { childList: true, attributes: true, attributeFilter: ['slot'] });\n }\n\n override disconnectedCallback(): void {\n this.childrenObserver?.disconnect();\n super.disconnectedCallback();\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n if (changed.has('value') || changed.has('focusedDate') || changed.has('mode')) {\n this.syncViewAnchor();\n }\n\n if (changed.has('disabled') || changed.has('readonly') || changed.has('mode') || changed.has('withWeekNumbers')) {\n this.syncCustomStates();\n }\n\n if (changed.has('view')) {\n this.emitViewChange();\n }\n\n super.willUpdate(changed);\n }\n\n private updateDaySlots(): void {\n const names = [...this.children]\n .map((child) => child.getAttribute('slot'))\n .filter((name): name is string => Boolean(name?.startsWith('day-')));\n\n if (names.join(',') !== this.daySlotNames.join(',')) {\n this.daySlotNames = names;\n }\n }\n\n private syncCustomStates(): void {\n this.toggleAttribute('data-range', this.mode === 'range');\n this.toggleAttribute('data-multiple', this.mode === 'multiple');\n this.toggleAttribute('data-week-numbers', this.withWeekNumbers);\n }\n\n private get resolvedLocale(): string {\n return this.locale || this.lang || document.documentElement.lang || 'en';\n }\n\n private get resolvedToday(): Date {\n return parseIsoDate(this.today) ?? todayDate();\n }\n\n /** Representative selected date used to anchor the view/focus across all modes. */\n private get primarySelectedDate(): Date | null {\n if (this.mode === 'single') {\n return parseIsoDate(this.value);\n }\n\n if (this.mode === 'multiple') {\n return parseDateList(this.value)[0] ?? null;\n }\n\n return parseRange(this.value).from;\n }\n\n private get resolvedFocusedDate(): Date {\n return parseIsoDate(this.focusedDate)\n ?? coerceToDate(this.primarySelectedDate)\n ?? this.resolvedToday;\n }\n\n private get isDisabledMatcher(): (date: Date) => boolean {\n return buildDisabledMatcher({\n min: parseIsoDate(this.min),\n max: parseIsoDate(this.max),\n disabledDates: parseDisabledDates(this.disabledDatesRaw),\n disabledDaysOfWeek: parseDaysOfWeek(this.disabledDaysOfWeek),\n disablePast: this.disablePast,\n disableFuture: this.disableFuture,\n today: this.resolvedToday,\n isDateDisabled: this.isDateDisabled,\n });\n }\n\n private get weekendDays(): Set<number> {\n return new Set(intlWeekendToJsDays(getWeekInfo(this.resolvedLocale).weekend));\n }\n\n private get pageStep(): number {\n return this.pageBy === 'single' ? 1 : this.months;\n }\n\n private get visibleMonthAnchors(): Date[] {\n const anchors = [this.viewAnchor];\n\n if (this.months === 2) {\n anchors.push(startOfMonth(addMonths(this.viewAnchor, 1)));\n }\n\n return anchors;\n }\n\n private syncViewAnchor(): void {\n const focus = this.resolvedFocusedDate;\n\n if (!this.visibleMonthAnchors.some((anchor) => isSameMonth(focus, anchor))) {\n this.viewAnchor = startOfMonth(focus);\n }\n }\n\n get valueAsDate(): Date | null {\n return this.mode === 'single' ? parseIsoDate(this.value) : null;\n }\n\n get valueAsRange(): DateRange {\n return parseRange(this.value);\n }\n\n /** Sorted, deduped selection for `multiple` mode (empty otherwise). */\n get valueAsDates(): Date[] {\n return this.mode === 'multiple' ? parseDateList(this.value) : [];\n }\n\n focus(options?: FocusOptions): void {\n const selector = this.view === 'days'\n ? '.day.is-roving'\n : this.view === 'months'\n ? '.view-item.is-roving'\n : '.view-item.is-roving';\n\n this.renderRoot.querySelector<HTMLButtonElement>(selector)?.focus(options);\n }\n\n goToDate(date: string | Date): void {\n const parsed = coerceToDate(date);\n\n if (!parsed) {\n return;\n }\n\n this.viewAnchor = startOfMonth(parsed);\n this.focusedDate = formatIsoDate(parsed);\n this.view = 'days';\n }\n\n goToToday(): void {\n this.goToDate(this.resolvedToday);\n }\n\n clear(): void {\n if (this.disabled || this.readonly) {\n return;\n }\n\n this.value = '';\n this.rangeAnchor = null;\n this.hoverDate = null;\n this.emitInput();\n this.emitChange();\n }\n\n private emitInput(): void {\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n }\n\n private emitChange(): void {\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n private emitFocusDay(date: Date): void {\n this.dispatchEvent(new CustomEvent('pk-focus-day', {\n detail: { date },\n bubbles: true,\n composed: true,\n }));\n }\n\n private emitViewChange(): void {\n this.dispatchEvent(new CustomEvent('pk-view-change', {\n detail: { view: this.view, date: this.resolvedFocusedDate },\n bubbles: true,\n composed: true,\n }));\n }\n\n private announce(message: string): void {\n this.liveAnnouncement = `${message}\\u200B`;\n }\n\n private setView(next: PkCalendarView): void {\n if (this.view === next) {\n return;\n }\n\n this.view = next;\n }\n\n private handlePrevious = (): void => {\n if (this.view === 'days') {\n this.viewAnchor = addMonths(this.viewAnchor, -this.pageStep);\n return;\n }\n\n if (this.view === 'months') {\n this.viewAnchor = addYears(this.viewAnchor, -1);\n return;\n }\n\n this.viewAnchor = addYears(this.viewAnchor, -12);\n };\n\n private handleNext = (): void => {\n if (this.view === 'days') {\n this.viewAnchor = addMonths(this.viewAnchor, this.pageStep);\n return;\n }\n\n if (this.view === 'months') {\n this.viewAnchor = addYears(this.viewAnchor, 1);\n return;\n }\n\n this.viewAnchor = addYears(this.viewAnchor, 12);\n };\n\n private handleTitleClick = (): void => {\n if (this.disabled) {\n return;\n }\n\n if (this.view === 'days') {\n this.setView('months');\n this.focusedMonth = this.resolvedFocusedDate.getMonth();\n return;\n }\n\n if (this.view === 'months') {\n this.setView('years');\n this.focusedYear = this.resolvedFocusedDate.getFullYear();\n }\n };\n\n private handleDayClick(date: Date, disabled: boolean): void {\n if (this.disabled || this.readonly || disabled) {\n return;\n }\n\n if (this.mode === 'single') {\n this.value = formatIsoDate(date);\n this.focusedDate = formatIsoDate(date);\n this.emitInput();\n this.emitChange();\n this.announce(formatDisplayDate(date, this.resolvedLocale));\n return;\n }\n\n if (this.mode === 'multiple') {\n // Each click toggles the day in/out of the set; the picker keeps the panel\n // open so several dates can be chosen before dismissing.\n const wasSelected = parseDateList(this.value).some((entry) => isSameDay(entry, date));\n this.value = toggleDateInList(this.value, date);\n this.focusedDate = formatIsoDate(date);\n this.emitInput();\n this.emitChange();\n this.announce(\n `${wasSelected ? 'Removed' : 'Added'} ${formatDisplayDate(date, this.resolvedLocale)}`,\n );\n return;\n }\n\n if (!this.rangeAnchor) {\n this.rangeAnchor = date;\n this.value = formatIsoDate(date);\n this.focusedDate = formatIsoDate(date);\n this.emitInput();\n return;\n }\n\n const from = this.rangeAnchor;\n const to = date;\n const ordered = from.getTime() <= to.getTime()\n ? { from, to }\n : { from: to, to: from };\n\n if (this.minRange > 0 && diffDays(ordered.to, ordered.from) + 1 < this.minRange) {\n this.announce(`Range must be at least ${this.minRange} days`);\n return;\n }\n\n if (this.maxRange > 0 && diffDays(ordered.to, ordered.from) + 1 > this.maxRange) {\n this.announce(`Range must be at most ${this.maxRange} days`);\n return;\n }\n\n this.value = formatRange(ordered);\n this.focusedDate = formatIsoDate(date);\n this.rangeAnchor = null;\n this.hoverDate = null;\n this.emitInput();\n this.emitChange();\n this.announce(`${formatDisplayDate(ordered.from, this.resolvedLocale)} – ${formatDisplayDate(ordered.to, this.resolvedLocale)}`);\n }\n\n private handleDayHover(date: Date): void {\n if (this.mode !== 'range' || !this.rangeAnchor) {\n return;\n }\n\n this.hoverDate = date;\n this.emitFocusDay(date);\n }\n\n private handleGridMouseLeave = (): void => {\n this.hoverDate = null;\n };\n\n private handleMonthPick(monthIndex: number): void {\n if (this.disabled || this.readonly) {\n return;\n }\n\n const next = new Date(this.viewAnchor.getFullYear(), monthIndex, 1);\n\n if (this.isMonthFullyDisabled(next)) {\n return;\n }\n\n this.viewAnchor = next;\n this.focusedDate = formatIsoDate(next);\n this.setView('days');\n }\n\n private handleYearPick(year: number): void {\n if (this.disabled || this.readonly) {\n return;\n }\n\n const next = new Date(year, this.viewAnchor.getMonth(), 1);\n\n if (this.isYearFullyDisabled(year)) {\n return;\n }\n\n this.viewAnchor = next;\n this.focusedDate = formatIsoDate(next);\n this.setView('months');\n this.focusedMonth = next.getMonth();\n }\n\n private handleDayKeyDown(event: KeyboardEvent, date: Date, disabled: boolean): void {\n if (disabled) {\n return;\n }\n\n let next: Date | null = null;\n\n switch (event.key) {\n case 'ArrowLeft':\n next = addDays(date, -1);\n break;\n case 'ArrowRight':\n next = addDays(date, 1);\n break;\n case 'ArrowUp':\n next = addDays(date, -7);\n break;\n case 'ArrowDown':\n next = addDays(date, 7);\n break;\n case 'PageUp':\n next = addMonths(date, -1);\n break;\n case 'PageDown':\n next = addMonths(date, 1);\n break;\n case 'Home':\n next = startOfMonth(date);\n break;\n case 'End':\n next = new Date(date.getFullYear(), date.getMonth() + 1, 0);\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this.handleDayClick(date, disabled);\n return;\n case 'Escape':\n if (this.rangeAnchor) {\n event.preventDefault();\n this.rangeAnchor = null;\n this.hoverDate = null;\n this.requestUpdate();\n }\n\n return;\n default:\n return;\n }\n\n event.preventDefault();\n\n if (!next) {\n return;\n }\n\n this.focusedDate = formatIsoDate(next);\n\n if (!this.visibleMonthAnchors.some((anchor) => isSameMonth(next!, anchor))) {\n this.viewAnchor = startOfMonth(next);\n }\n\n this.emitFocusDay(next);\n this.requestUpdate();\n queueMicrotask(() => this.focus());\n }\n\n private isMonthFullyDisabled(monthStart: Date): boolean {\n const end = new Date(monthStart.getFullYear(), monthStart.getMonth() + 1, 0);\n return allDisabledInRange(monthStart, end, this.isDisabledMatcher);\n }\n\n private isYearFullyDisabled(year: number): boolean {\n const start = new Date(year, 0, 1);\n const end = new Date(year, 11, 31);\n return allDisabledInRange(start, end, this.isDisabledMatcher);\n }\n\n private formatWeekdayLabel(date: Date): string {\n if (this.weekdayFormat === 'narrow') {\n // Match react-day-picker cccccc — two-letter labels (Su, Mo, Tu…)\n const short = new Intl.DateTimeFormat(this.resolvedLocale, { weekday: 'short' }).format(date);\n return short.slice(0, 2);\n }\n\n return new Intl.DateTimeFormat(this.resolvedLocale, { weekday: this.weekdayFormat }).format(date);\n }\n\n private buildWeekdayLabels(): string[] {\n const firstDay = resolveFirstDayOfWeek(this.firstDayOfWeek, this.resolvedLocale);\n const labels: string[] = [];\n\n for (let index = 0; index < 7; index += 1) {\n const day = (firstDay + index) % 7;\n const date = new Date(2024, 0, day === 0 ? 7 : day);\n labels.push(this.formatWeekdayLabel(date));\n }\n\n return labels;\n }\n\n private buildMonthDays(monthAnchor: Date): Date[] {\n const firstDay = resolveFirstDayOfWeek(this.firstDayOfWeek, this.resolvedLocale);\n const monthStart = startOfMonth(monthAnchor);\n const offset = (monthStart.getDay() - firstDay + 7) % 7;\n const gridStart = addDays(monthStart, -offset);\n const days: Date[] = [];\n\n for (let index = 0; index < 42; index += 1) {\n days.push(addDays(gridStart, index));\n }\n\n return days;\n }\n\n private computeDayState(date: Date, monthAnchor: Date): DayState {\n const isDisabled = this.isDisabledMatcher(date);\n const range = parseRange(this.value);\n const selectedSingle = this.mode === 'single' && isSameDay(parseIsoDate(this.value), date);\n const selectedMultiple = this.mode === 'multiple'\n && parseDateList(this.value).some((entry) => isSameDay(entry, date));\n const rangeStart = this.mode === 'range' && isSameDay(range.from, date);\n const rangeEnd = this.mode === 'range' && isSameDay(range.to, date);\n const rangeInner = this.mode === 'range'\n && range.from\n && range.to\n && date.getTime() > range.from.getTime()\n && date.getTime() < range.to.getTime();\n\n let rangePreview = false;\n\n if (this.mode === 'range' && this.rangeAnchor && this.hoverDate) {\n const anchor = this.rangeAnchor;\n const hover = this.hoverDate;\n const start = anchor.getTime() <= hover.getTime() ? anchor : hover;\n const end = anchor.getTime() <= hover.getTime() ? hover : anchor;\n\n rangePreview = date.getTime() >= start.getTime() && date.getTime() <= end.getTime();\n }\n\n return {\n date,\n monthAnchor,\n outside: !isSameMonth(date, monthAnchor),\n today: isSameDay(date, this.resolvedToday),\n weekend: this.weekendDays.has(date.getDay()),\n disabled: isDisabled,\n selected: selectedSingle || selectedMultiple || rangeStart || rangeEnd,\n rangeStart,\n rangeEnd,\n rangeInner: Boolean(rangeInner),\n rangePreview,\n roving: isSameDay(date, this.resolvedFocusedDate),\n };\n }\n\n private renderDayContent(state: DayState) {\n const slotName = `day-${formatIsoDate(state.date)}`;\n\n if (this.daySlotNames.includes(slotName)) {\n return html`<slot name=${slotName}></slot>`;\n }\n\n const custom = this.dayContent?.(state.date);\n\n if (custom) {\n return unsafeHTML(custom);\n }\n\n return html`<span part=\"day-label\">${state.date.getDate()}</span>`;\n }\n\n private renderDay(state: DayState) {\n if (!this.withOutsideDays && state.outside) {\n return html`<span part=\"day-placeholder\" class=\"day is-placeholder\" aria-hidden=\"true\"></span>`;\n }\n\n const label = formatDisplayDate(state.date, this.resolvedLocale);\n\n return html`\n <button\n type=\"button\"\n part=\"day\"\n class=${classMap({\n day: true,\n 'is-outside': state.outside,\n 'is-today': state.today,\n 'is-weekend': state.weekend,\n 'is-disabled': state.disabled,\n 'is-selected': state.selected,\n 'is-range-start': state.rangeStart,\n 'is-range-end': state.rangeEnd,\n 'is-range-inner': state.rangeInner,\n 'is-range-preview': state.rangePreview,\n 'is-roving': state.roving,\n })}\n tabindex=${state.roving ? '0' : '-1'}\n ?disabled=${state.disabled}\n aria-label=${label}\n aria-selected=${state.selected ? 'true' : 'false'}\n aria-current=${state.today ? 'date' : nothing}\n @click=${() => this.handleDayClick(state.date, state.disabled)}\n @mouseenter=${() => this.handleDayHover(state.date)}\n @keydown=${(event: KeyboardEvent) => this.handleDayKeyDown(event, state.date, state.disabled)}\n >\n ${this.renderDayContent(state)}\n </button>\n `;\n }\n\n private getMonthWeeks(monthAnchor: Date): Date[][] {\n const days = this.buildMonthDays(monthAnchor);\n const weeks: Date[][] = [];\n\n for (let index = 0; index < days.length; index += 7) {\n weeks.push(days.slice(index, index + 7));\n }\n\n if (this.withOutsideDays) {\n return weeks;\n }\n\n return weeks.filter((week) => week.some((date) => isSameMonth(date, monthAnchor)));\n }\n\n private renderMonth(monthAnchor: Date, showLabel = false) {\n const weekdays = this.buildWeekdayLabels();\n const title = new Intl.DateTimeFormat(this.resolvedLocale, {\n month: 'long',\n year: 'numeric',\n }).format(monthAnchor);\n\n const weeks = this.getMonthWeeks(monthAnchor);\n\n return html`\n <div part=\"month\" class=\"month\">\n ${showLabel\n ? html`<div part=\"month-label\" class=\"month-label\">${title}</div>`\n : nothing}\n <div part=\"weekdays\" class=\"weekdays\" role=\"row\">\n ${this.withWeekNumbers\n ? html`<span part=\"weeknumbers\" class=\"weeknumber-header\" role=\"columnheader\">#</span>`\n : nothing}\n ${weekdays.map((weekday) => html`\n <span part=\"weekday\" class=\"weekday\" role=\"columnheader\">${weekday}</span>\n `)}\n </div>\n <div\n part=\"grid\"\n class=\"grid\"\n role=\"grid\"\n aria-label=${title}\n @mouseleave=${this.handleGridMouseLeave}\n >\n ${weeks.map((week) => html`\n <div part=\"week\" class=\"week\" role=\"row\">\n ${this.withWeekNumbers\n ? html`<span part=\"weeknumber\" class=\"weeknumber\" role=\"gridcell\">${isoWeekNumber(week[0])}</span>`\n : nothing}\n ${week.map((date) => this.renderDay(this.computeDayState(date, monthAnchor)))}\n </div>\n `)}\n </div>\n </div>\n `;\n }\n\n private renderViewRows(items: Array<ReturnType<typeof html>>) {\n const rows: Array<ReturnType<typeof html>> = [];\n\n for (let index = 0; index < items.length; index += 3) {\n rows.push(html`\n <div part=\"view-row\" class=\"view-row\" role=\"row\">\n ${items.slice(index, index + 3)}\n </div>\n `);\n }\n\n return rows;\n }\n\n private renderMonthsView() {\n const year = this.viewAnchor.getFullYear();\n const formatter = new Intl.DateTimeFormat(this.resolvedLocale, { month: 'long' });\n const selectedDate = this.primarySelectedDate;\n const selectedMonth = selectedDate?.getMonth();\n const rovingMonth = this.focusedMonth ?? this.resolvedFocusedDate.getMonth();\n const items = [];\n\n for (let monthIndex = 0; monthIndex < 12; monthIndex += 1) {\n const monthStart = new Date(year, monthIndex, 1);\n const disabled = this.isMonthFullyDisabled(monthStart);\n const selected = selectedMonth === monthIndex;\n const todayMonth = this.resolvedToday.getFullYear() === year && this.resolvedToday.getMonth() === monthIndex;\n const roving = rovingMonth === monthIndex;\n\n items.push(html`\n <div part=\"view-cell\" class=\"view-cell\" role=\"gridcell\">\n <button\n type=\"button\"\n part=\"view-item ${todayMonth ? 'view-item-today' : ''} ${selected ? 'view-item-selected' : ''} ${disabled ? 'view-item-disabled' : ''}\"\n class=${classMap({\n 'view-item': true,\n 'is-today': todayMonth,\n 'is-selected': selected,\n 'is-disabled': disabled,\n 'is-roving': roving,\n })}\n tabindex=${roving ? '0' : '-1'}\n ?disabled=${disabled}\n @click=${() => this.handleMonthPick(monthIndex)}\n >\n ${formatter.format(monthStart)}\n </button>\n </div>\n `);\n }\n\n return html`\n <div part=\"view-grid\" class=\"view-grid\" role=\"grid\">\n ${this.renderViewRows(items)}\n </div>\n `;\n }\n\n private renderYearsView() {\n const centerYear = this.viewAnchor.getFullYear();\n const decadeStart = Math.floor(centerYear / 12) * 12;\n const selectedDate = this.primarySelectedDate;\n const selectedYear = selectedDate?.getFullYear();\n const rovingYear = this.focusedYear ?? this.resolvedFocusedDate.getFullYear();\n const items = [];\n\n for (let offset = 0; offset < 12; offset += 1) {\n const year = decadeStart + offset;\n const disabled = this.isYearFullyDisabled(year);\n const selected = selectedYear === year;\n const todayYear = this.resolvedToday.getFullYear() === year;\n const roving = rovingYear === year;\n\n items.push(html`\n <div part=\"view-cell\" class=\"view-cell\" role=\"gridcell\">\n <button\n type=\"button\"\n part=\"view-item ${todayYear ? 'view-item-today' : ''} ${selected ? 'view-item-selected' : ''} ${disabled ? 'view-item-disabled' : ''}\"\n class=${classMap({\n 'view-item': true,\n 'is-today': todayYear,\n 'is-selected': selected,\n 'is-disabled': disabled,\n 'is-roving': roving,\n })}\n tabindex=${roving ? '0' : '-1'}\n ?disabled=${disabled}\n @click=${() => this.handleYearPick(year)}\n >\n ${year}\n </button>\n </div>\n `);\n }\n\n return html`\n <div part=\"view-grid\" class=\"view-grid\" role=\"grid\">\n ${this.renderViewRows(items)}\n </div>\n `;\n }\n\n private renderHeaderTitle() {\n if (this.view === 'months') {\n return String(this.viewAnchor.getFullYear());\n }\n\n if (this.view === 'years') {\n const centerYear = this.viewAnchor.getFullYear();\n const decadeStart = Math.floor(centerYear / 12) * 12;\n return `${decadeStart} – ${decadeStart + 11}`;\n }\n\n if (this.months === 2) {\n const first = new Intl.DateTimeFormat(this.resolvedLocale, { month: 'long', year: 'numeric' }).format(this.viewAnchor);\n const second = new Intl.DateTimeFormat(this.resolvedLocale, { month: 'long', year: 'numeric' }).format(addMonths(this.viewAnchor, 1));\n return `${first} – ${second}`;\n }\n\n return new Intl.DateTimeFormat(this.resolvedLocale, {\n month: 'long',\n year: 'numeric',\n }).format(this.viewAnchor);\n }\n\n override render() {\n const showDualLabels = this.view === 'days' && this.months === 2;\n\n return html`\n <div part=\"base\" class=\"base\">\n <div part=\"header\" class=\"header\">\n <button\n type=\"button\"\n part=\"previous\"\n class=\"nav-button\"\n aria-label=\"Previous\"\n ?disabled=${this.disabled}\n @click=${this.handlePrevious}\n >\n <slot name=\"previous-icon\">\n <span class=\"icon\" aria-hidden=\"true\">${unsafeSVG(CHEVRON_LEFT)}</span>\n </slot>\n </button>\n <button\n type=\"button\"\n part=\"title\"\n class=\"title\"\n ?disabled=${this.disabled}\n @click=${this.view === 'years' ? undefined : this.handleTitleClick}\n >\n ${this.renderHeaderTitle()}\n </button>\n <button\n type=\"button\"\n part=\"next\"\n class=\"nav-button\"\n aria-label=\"Next\"\n ?disabled=${this.disabled}\n @click=${this.handleNext}\n >\n <slot name=\"next-icon\">\n <span class=\"icon\" aria-hidden=\"true\">${unsafeSVG(CHEVRON_RIGHT)}</span>\n </slot>\n </button>\n </div>\n\n <div part=\"months\" class=\"months\">\n ${this.view === 'days'\n ? this.visibleMonthAnchors.map((anchor) => this.renderMonth(anchor, showDualLabels))\n : this.view === 'months'\n ? this.renderMonthsView()\n : this.renderYearsView()}\n </div>\n\n ${this.hasSlotController.test('footer')\n ? html`<div part=\"footer\"><slot name=\"footer\"></slot></div>`\n : nothing}\n\n <div class=\"live-region\" aria-live=\"polite\" aria-atomic=\"true\">\n ${this.liveAnnouncement}\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-calendar': PkCalendar;\n }\n}\n"],"mappings":"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"}
|
|
@@ -263,6 +263,7 @@ var PkColorInput = class PkColorInput extends PkFormAssociatedElement {
|
|
|
263
263
|
this.assumeInteractionOn = ["blur", "input"];
|
|
264
264
|
this.size = "default";
|
|
265
265
|
this.fitCell = false;
|
|
266
|
+
this.readonly = false;
|
|
266
267
|
this.invalid = false;
|
|
267
268
|
this.value = "";
|
|
268
269
|
this.defaultValue = "";
|
|
@@ -325,11 +326,13 @@ var PkColorInput = class PkColorInput extends PkFormAssociatedElement {
|
|
|
325
326
|
}));
|
|
326
327
|
}
|
|
327
328
|
handleHexInput(event) {
|
|
329
|
+
if (this.disabled || this.readonly) return;
|
|
328
330
|
const nextHex = sanitizeHex(event.target.value);
|
|
329
331
|
this.hexValue = nextHex;
|
|
330
332
|
this.emitChange();
|
|
331
333
|
}
|
|
332
334
|
handlePickerChange(event) {
|
|
335
|
+
if (this.disabled || this.readonly) return;
|
|
333
336
|
const nextHex = sanitizeHex(event.target.value);
|
|
334
337
|
this.hexValue = nextHex;
|
|
335
338
|
this.emitChange();
|
|
@@ -352,7 +355,7 @@ var PkColorInput = class PkColorInput extends PkFormAssociatedElement {
|
|
|
352
355
|
class="swatch-picker"
|
|
353
356
|
type="color"
|
|
354
357
|
.value=${previewColor}
|
|
355
|
-
?disabled=${this.disabled}
|
|
358
|
+
?disabled=${this.disabled || this.readonly}
|
|
356
359
|
aria-label="Color picker"
|
|
357
360
|
@input=${this.handlePickerChange}
|
|
358
361
|
/>
|
|
@@ -367,6 +370,7 @@ var PkColorInput = class PkColorInput extends PkFormAssociatedElement {
|
|
|
367
370
|
maxlength="6"
|
|
368
371
|
.value=${this.hexValue}
|
|
369
372
|
?disabled=${this.disabled}
|
|
373
|
+
?readonly=${this.readonly}
|
|
370
374
|
?required=${this.required}
|
|
371
375
|
aria-label=${this.ariaLabel ?? nothing}
|
|
372
376
|
aria-invalid=${this.invalid ? "true" : nothing}
|
|
@@ -382,6 +386,10 @@ __decorate([property({
|
|
|
382
386
|
reflect: true,
|
|
383
387
|
attribute: "fit-cell"
|
|
384
388
|
})], PkColorInput.prototype, "fitCell", void 0);
|
|
389
|
+
__decorate([property({
|
|
390
|
+
type: Boolean,
|
|
391
|
+
reflect: true
|
|
392
|
+
})], PkColorInput.prototype, "readonly", void 0);
|
|
385
393
|
__decorate([property({
|
|
386
394
|
type: Boolean,
|
|
387
395
|
reflect: true
|
|
@@ -395,4 +403,4 @@ PkColorInput = __decorate([customElement("pk-color-input")], PkColorInput);
|
|
|
395
403
|
//#endregion
|
|
396
404
|
export { PkColorInput as t };
|
|
397
405
|
|
|
398
|
-
//# sourceMappingURL=pk-color-input-
|
|
406
|
+
//# sourceMappingURL=pk-color-input-CNnmHJJB.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pk-color-input-D4L0DE5S.js","names":[],"sources":["../../src/components/color-input/pk-color-input.styles.ts","../../src/components/color-input/pk-color-input.ts"],"sourcesContent":["import { css } from 'lit';\n\n/**\n * Size scale matches pk-input (xs / sm / default / lg). Metrics are shifted so\n * former `lg` (2.125rem / ~34px) is default — aligned with base input chrome.\n * `xl` is kept as a deprecated alias of `lg`.\n */\nexport const pkColorInputStyles = css`\n @layer pk-component {\n :host {\n display: inline-block;\n position: relative;\n /* Former lg min-width — default now matches input default chrome. */\n min-width: 6.75rem;\n font-family: var(--pk-font-family);\n vertical-align: middle;\n }\n\n :host([size='xs']) {\n min-width: 5.5rem;\n }\n\n :host([size='sm']) {\n min-width: 6.125rem;\n }\n\n :host([size='lg']),\n :host([size='xl']) {\n min-width: 7.375rem;\n }\n\n :host([fit-cell]) {\n display: block;\n width: 100%;\n min-width: 0;\n max-width: 100%;\n height: 100%;\n }\n\n :host([fit-cell]) .root {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .root {\n position: relative;\n display: inline-block;\n width: 100%;\n }\n\n .swatch {\n position: absolute;\n top: 50%;\n left: 0.5rem;\n z-index: 2;\n width: 1.25rem;\n height: 1.25rem;\n transform: translateY(-50%);\n border-radius: var(--pk-radius-sm);\n }\n\n :host([size='xs']) .swatch {\n left: 0.375rem;\n width: 1rem;\n height: 1rem;\n }\n\n :host([size='sm']) .swatch {\n left: 0.375rem;\n width: 1.25rem;\n height: 1.25rem;\n }\n\n :host([size='lg']) .swatch,\n :host([size='xl']) .swatch {\n left: 0.5rem;\n width: 1.5rem;\n height: 1.5rem;\n }\n\n :host([fit-cell]) .swatch {\n left: 0.5rem;\n width: 1rem;\n height: 1rem;\n }\n\n .swatch-preview {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.15);\n }\n\n .swatch-preview.is-transparent {\n background-color: #fff;\n background-image:\n linear-gradient(45deg, #d1d5db 25%, transparent 25%),\n linear-gradient(-45deg, #d1d5db 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, #d1d5db 75%),\n linear-gradient(-45deg, transparent 75%, #d1d5db 75%);\n background-size: 8px 8px;\n background-position: 0 0, 0 4px, 4px -4px, -4px 0;\n }\n\n .swatch-picker {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n border: 0;\n opacity: 0;\n cursor: pointer;\n appearance: none;\n }\n\n .swatch-picker:disabled {\n cursor: not-allowed;\n }\n\n .hash {\n position: absolute;\n top: 50%;\n left: 2.125rem;\n z-index: 1;\n transform: translateY(-50%);\n color: var(--pk-color-gray-300);\n font-family: var(--pk-font-family-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace);\n font-size: var(--pk-font-size-mono, 0.9em);\n line-height: var(--pk-line-height-mono, 1.5);\n pointer-events: none;\n user-select: none;\n }\n\n :host([size='xs']) .hash {\n left: 1.625rem;\n }\n\n :host([size='sm']) .hash {\n left: 2rem;\n }\n\n :host([size='lg']) .hash,\n :host([size='xl']) .hash {\n left: 2.5rem;\n }\n\n :host([fit-cell]) .hash {\n left: 1.75rem;\n }\n\n .hex-input {\n display: block;\n width: 100%;\n /* Former lg — matches pk-input default chrome (~34px). */\n height: 2.125rem;\n margin: 0;\n padding-inline: 3rem 0.75rem;\n border: var(--pk-input-border);\n border-radius: var(--pk-input-border-radius);\n background: var(--pk-input-bg);\n color: var(--pk-color-gray-700);\n font-family: var(--pk-font-family-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace);\n font-size: var(--pk-font-size-mono, 0.9em);\n line-height: var(--pk-line-height-mono, 1.5);\n outline: none;\n box-sizing: border-box;\n transition: border-color 0.12s ease, box-shadow 0.12s ease;\n }\n\n :host([size='xs']) .hex-input {\n height: 1.625rem;\n padding-inline: 2.25rem 0.625rem;\n }\n\n :host([size='sm']) .hex-input {\n height: 1.875rem;\n padding-inline: 2.75rem 0.75rem;\n }\n\n :host([size='lg']) .hex-input,\n :host([size='xl']) .hex-input {\n height: 2.375rem;\n padding-inline: 3.25rem 0.875rem;\n }\n\n :host([fit-cell]) .hex-input {\n width: 100%;\n max-width: 100%;\n height: 100%;\n padding-inline: 2.25rem 0.5rem;\n border: 0;\n border-radius: 0;\n background: transparent;\n }\n\n .hex-input:focus,\n .hex-input:focus-visible {\n border-color: var(--pk-color-sky-600);\n box-shadow: var(--pk-input-focus-shadow);\n }\n\n :host([invalid]) .hex-input:focus,\n :host([invalid]) .hex-input:focus-visible {\n border-color: var(--pk-color-rose-600);\n box-shadow: var(--pk-input-invalid-focus-shadow);\n }\n\n :host([fit-cell]:not([invalid])) .hex-input:focus,\n :host([fit-cell]:not([invalid])) .hex-input:focus-visible {\n box-shadow: inset 0 0 0 1px var(--pk-color-gray-200);\n }\n\n :host([fit-cell][invalid]) .hex-input,\n :host([fit-cell][invalid]) .hex-input:focus,\n :host([fit-cell][invalid]) .hex-input:focus-visible {\n box-shadow: inset 0 0 0 1px var(--pk-color-rose-600);\n }\n\n .hex-input:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n :host([invalid]) .hex-input {\n border-color: var(--pk-color-rose-600);\n }\n\n :host([disabled]) .swatch {\n opacity: 0.5;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { PkFormAssociatedElement } from '../../base/pk-form-associated-element.js';\nimport { MirrorValidator, RequiredValidator } from '../../validators/index.js';\nimport { pkColorInputStyles } from './pk-color-input.styles.js';\n\n/** Public scale is xs / sm / default / lg (`xl` aliases `lg` for compatibility). */\nexport type PkColorInputSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl';\n\nconst DEFAULT_COLOR = '#000000';\n\nfunction sanitizeHex(value: string): string {\n return String(value || '')\n .replace(/^#/, '')\n .replace(/[^0-9a-fA-F]/g, '')\n .slice(0, 6)\n .toLowerCase();\n}\n\nfunction isCompleteHex(value: string): boolean {\n return value.length === 3 || value.length === 6;\n}\n\nfunction expandShortHex(value: string): string {\n if (value.length !== 3) {\n return value;\n }\n\n return value.split('').map((char) => `${char}${char}`).join('');\n}\n\nfunction toPickerValue(hex: string): string {\n if (hex.length === 6) {\n return `#${hex}`;\n }\n\n if (hex.length === 3) {\n return `#${expandShortHex(hex)}`;\n }\n\n return DEFAULT_COLOR;\n}\n\n/**\n * Color input — swatch picker + hex text field (Craft ColorInput parity).\n * Form-associated; submits `#rrggbb` or empty string.\n *\n * @csspart swatch - Swatch container\n * @csspart input - Hex text input\n */\n@customElement('pk-color-input')\nexport class PkColorInput extends PkFormAssociatedElement {\n static override styles = pkColorInputStyles;\n\n static override get validators() {\n return [...super.validators, MirrorValidator(), RequiredValidator()];\n }\n\n override assumeInteractionOn = ['blur', 'input'];\n\n @property({ reflect: true })\n size: PkColorInputSize = 'default';\n\n @property({ type: Boolean, reflect: true, attribute: 'fit-cell' })\n fitCell = false;\n\n @property({ type: Boolean, reflect: true })\n invalid = false;\n\n @property()\n value = '';\n\n @property({ attribute: 'default-value' })\n defaultValue = '';\n\n @property({ attribute: 'aria-label' })\n ariaLabel: string | null = null;\n\n @query('.hex-input')\n override input!: HTMLInputElement;\n\n @state()\n private hexValue = '';\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.syncHexFromValue();\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n if (changed.has('value')) {\n this.syncHexFromValue();\n }\n\n super.willUpdate(changed);\n }\n\n private syncHexFromValue(): void {\n this.hexValue = sanitizeHex(this.value);\n }\n\n protected override get validationTarget(): HTMLElement {\n return this.input;\n }\n\n protected override syncFormValue(): void {\n const submitted = this.hexValue ? `#${this.hexValue}` : '';\n this.setFormValue(submitted, submitted);\n }\n\n protected override resetToDefaultValue(): void {\n this.value = this.defaultValue;\n this.hexValue = sanitizeHex(this.defaultValue);\n }\n\n protected override restoreFormState(state: string | File | FormData | null): void {\n if (typeof state === 'string') {\n this.value = state;\n this.hexValue = sanitizeHex(state);\n }\n }\n\n private emitChange(): void {\n const next = this.hexValue ? `#${this.hexValue}` : '';\n this.value = next;\n\n this.dispatchEvent(new CustomEvent('pk-change', {\n detail: { value: next },\n bubbles: true,\n composed: true,\n }));\n\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n private handleHexInput(event: Event): void {\n const nextHex = sanitizeHex((event.target as HTMLInputElement).value);\n this.hexValue = nextHex;\n this.emitChange();\n }\n\n private handlePickerChange(event: Event): void {\n const nextHex = sanitizeHex((event.target as HTMLInputElement).value);\n this.hexValue = nextHex;\n this.emitChange();\n }\n\n override render() {\n const previewColor = toPickerValue(this.hexValue);\n const isTransparent = !isCompleteHex(this.hexValue);\n\n return html`\n <div class=\"root\">\n <div part=\"swatch\" class=\"swatch\">\n <div\n class=${classMap({\n 'swatch-preview': true,\n 'is-transparent': isTransparent,\n })}\n style=${isTransparent ? nothing : `background-color: ${previewColor}`}\n ></div>\n <input\n part=\"picker\"\n class=\"swatch-picker\"\n type=\"color\"\n .value=${previewColor}\n ?disabled=${this.disabled}\n aria-label=\"Color picker\"\n @input=${this.handlePickerChange}\n />\n </div>\n <span class=\"hash\" aria-hidden=\"true\">#</span>\n <input\n part=\"input\"\n class=\"hex-input\"\n type=\"text\"\n inputmode=\"text\"\n autocomplete=\"off\"\n maxlength=\"6\"\n .value=${this.hexValue}\n ?disabled=${this.disabled}\n ?required=${this.required}\n aria-label=${this.ariaLabel ?? nothing}\n aria-invalid=${this.invalid ? 'true' : nothing}\n @input=${this.handleHexInput}\n />\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-color-input': PkColorInput;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pk-color-input-CNnmHJJB.js","names":[],"sources":["../../src/components/color-input/pk-color-input.styles.ts","../../src/components/color-input/pk-color-input.ts"],"sourcesContent":["import { css } from 'lit';\n\n/**\n * Size scale matches pk-input (xs / sm / default / lg). Metrics are shifted so\n * former `lg` (2.125rem / ~34px) is default — aligned with base input chrome.\n * `xl` is kept as a deprecated alias of `lg`.\n */\nexport const pkColorInputStyles = css`\n @layer pk-component {\n :host {\n display: inline-block;\n position: relative;\n /* Former lg min-width — default now matches input default chrome. */\n min-width: 6.75rem;\n font-family: var(--pk-font-family);\n vertical-align: middle;\n }\n\n :host([size='xs']) {\n min-width: 5.5rem;\n }\n\n :host([size='sm']) {\n min-width: 6.125rem;\n }\n\n :host([size='lg']),\n :host([size='xl']) {\n min-width: 7.375rem;\n }\n\n :host([fit-cell]) {\n display: block;\n width: 100%;\n min-width: 0;\n max-width: 100%;\n height: 100%;\n }\n\n :host([fit-cell]) .root {\n display: block;\n width: 100%;\n height: 100%;\n }\n\n .root {\n position: relative;\n display: inline-block;\n width: 100%;\n }\n\n .swatch {\n position: absolute;\n top: 50%;\n left: 0.5rem;\n z-index: 2;\n width: 1.25rem;\n height: 1.25rem;\n transform: translateY(-50%);\n border-radius: var(--pk-radius-sm);\n }\n\n :host([size='xs']) .swatch {\n left: 0.375rem;\n width: 1rem;\n height: 1rem;\n }\n\n :host([size='sm']) .swatch {\n left: 0.375rem;\n width: 1.25rem;\n height: 1.25rem;\n }\n\n :host([size='lg']) .swatch,\n :host([size='xl']) .swatch {\n left: 0.5rem;\n width: 1.5rem;\n height: 1.5rem;\n }\n\n :host([fit-cell]) .swatch {\n left: 0.5rem;\n width: 1rem;\n height: 1rem;\n }\n\n .swatch-preview {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.15);\n }\n\n .swatch-preview.is-transparent {\n background-color: #fff;\n background-image:\n linear-gradient(45deg, #d1d5db 25%, transparent 25%),\n linear-gradient(-45deg, #d1d5db 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, #d1d5db 75%),\n linear-gradient(-45deg, transparent 75%, #d1d5db 75%);\n background-size: 8px 8px;\n background-position: 0 0, 0 4px, 4px -4px, -4px 0;\n }\n\n .swatch-picker {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n border: 0;\n opacity: 0;\n cursor: pointer;\n appearance: none;\n }\n\n .swatch-picker:disabled {\n cursor: not-allowed;\n }\n\n .hash {\n position: absolute;\n top: 50%;\n left: 2.125rem;\n z-index: 1;\n transform: translateY(-50%);\n color: var(--pk-color-gray-300);\n font-family: var(--pk-font-family-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace);\n font-size: var(--pk-font-size-mono, 0.9em);\n line-height: var(--pk-line-height-mono, 1.5);\n pointer-events: none;\n user-select: none;\n }\n\n :host([size='xs']) .hash {\n left: 1.625rem;\n }\n\n :host([size='sm']) .hash {\n left: 2rem;\n }\n\n :host([size='lg']) .hash,\n :host([size='xl']) .hash {\n left: 2.5rem;\n }\n\n :host([fit-cell]) .hash {\n left: 1.75rem;\n }\n\n .hex-input {\n display: block;\n width: 100%;\n /* Former lg — matches pk-input default chrome (~34px). */\n height: 2.125rem;\n margin: 0;\n padding-inline: 3rem 0.75rem;\n border: var(--pk-input-border);\n border-radius: var(--pk-input-border-radius);\n background: var(--pk-input-bg);\n color: var(--pk-color-gray-700);\n font-family: var(--pk-font-family-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace);\n font-size: var(--pk-font-size-mono, 0.9em);\n line-height: var(--pk-line-height-mono, 1.5);\n outline: none;\n box-sizing: border-box;\n transition: border-color 0.12s ease, box-shadow 0.12s ease;\n }\n\n :host([size='xs']) .hex-input {\n height: 1.625rem;\n padding-inline: 2.25rem 0.625rem;\n }\n\n :host([size='sm']) .hex-input {\n height: 1.875rem;\n padding-inline: 2.75rem 0.75rem;\n }\n\n :host([size='lg']) .hex-input,\n :host([size='xl']) .hex-input {\n height: 2.375rem;\n padding-inline: 3.25rem 0.875rem;\n }\n\n :host([fit-cell]) .hex-input {\n width: 100%;\n max-width: 100%;\n height: 100%;\n padding-inline: 2.25rem 0.5rem;\n border: 0;\n border-radius: 0;\n background: transparent;\n }\n\n .hex-input:focus,\n .hex-input:focus-visible {\n border-color: var(--pk-color-sky-600);\n box-shadow: var(--pk-input-focus-shadow);\n }\n\n :host([invalid]) .hex-input:focus,\n :host([invalid]) .hex-input:focus-visible {\n border-color: var(--pk-color-rose-600);\n box-shadow: var(--pk-input-invalid-focus-shadow);\n }\n\n :host([fit-cell]:not([invalid])) .hex-input:focus,\n :host([fit-cell]:not([invalid])) .hex-input:focus-visible {\n box-shadow: inset 0 0 0 1px var(--pk-color-gray-200);\n }\n\n :host([fit-cell][invalid]) .hex-input,\n :host([fit-cell][invalid]) .hex-input:focus,\n :host([fit-cell][invalid]) .hex-input:focus-visible {\n box-shadow: inset 0 0 0 1px var(--pk-color-rose-600);\n }\n\n .hex-input:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n :host([invalid]) .hex-input {\n border-color: var(--pk-color-rose-600);\n }\n\n :host([disabled]) .swatch {\n opacity: 0.5;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { PkFormAssociatedElement } from '../../base/pk-form-associated-element.js';\nimport { MirrorValidator, RequiredValidator } from '../../validators/index.js';\nimport { pkColorInputStyles } from './pk-color-input.styles.js';\n\n/** Public scale is xs / sm / default / lg (`xl` aliases `lg` for compatibility). */\nexport type PkColorInputSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl';\n\nconst DEFAULT_COLOR = '#000000';\n\nfunction sanitizeHex(value: string): string {\n return String(value || '')\n .replace(/^#/, '')\n .replace(/[^0-9a-fA-F]/g, '')\n .slice(0, 6)\n .toLowerCase();\n}\n\nfunction isCompleteHex(value: string): boolean {\n return value.length === 3 || value.length === 6;\n}\n\nfunction expandShortHex(value: string): string {\n if (value.length !== 3) {\n return value;\n }\n\n return value.split('').map((char) => `${char}${char}`).join('');\n}\n\nfunction toPickerValue(hex: string): string {\n if (hex.length === 6) {\n return `#${hex}`;\n }\n\n if (hex.length === 3) {\n return `#${expandShortHex(hex)}`;\n }\n\n return DEFAULT_COLOR;\n}\n\n/**\n * Color input — swatch picker + hex text field (Craft ColorInput parity).\n * Form-associated; submits `#rrggbb` or empty string.\n *\n * @csspart swatch - Swatch container\n * @csspart input - Hex text input\n */\n@customElement('pk-color-input')\nexport class PkColorInput extends PkFormAssociatedElement {\n static override styles = pkColorInputStyles;\n\n static override get validators() {\n return [...super.validators, MirrorValidator(), RequiredValidator()];\n }\n\n override assumeInteractionOn = ['blur', 'input'];\n\n @property({ reflect: true })\n size: PkColorInputSize = 'default';\n\n @property({ type: Boolean, reflect: true, attribute: 'fit-cell' })\n fitCell = false;\n\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n @property({ type: Boolean, reflect: true })\n invalid = false;\n\n @property()\n value = '';\n\n @property({ attribute: 'default-value' })\n defaultValue = '';\n\n @property({ attribute: 'aria-label' })\n ariaLabel: string | null = null;\n\n @query('.hex-input')\n override input!: HTMLInputElement;\n\n @state()\n private hexValue = '';\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.syncHexFromValue();\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n if (changed.has('value')) {\n this.syncHexFromValue();\n }\n\n super.willUpdate(changed);\n }\n\n private syncHexFromValue(): void {\n this.hexValue = sanitizeHex(this.value);\n }\n\n protected override get validationTarget(): HTMLElement {\n return this.input;\n }\n\n protected override syncFormValue(): void {\n const submitted = this.hexValue ? `#${this.hexValue}` : '';\n this.setFormValue(submitted, submitted);\n }\n\n protected override resetToDefaultValue(): void {\n this.value = this.defaultValue;\n this.hexValue = sanitizeHex(this.defaultValue);\n }\n\n protected override restoreFormState(state: string | File | FormData | null): void {\n if (typeof state === 'string') {\n this.value = state;\n this.hexValue = sanitizeHex(state);\n }\n }\n\n private emitChange(): void {\n const next = this.hexValue ? `#${this.hexValue}` : '';\n this.value = next;\n\n this.dispatchEvent(new CustomEvent('pk-change', {\n detail: { value: next },\n bubbles: true,\n composed: true,\n }));\n\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n private handleHexInput(event: Event): void {\n // Readonly must not mutate the value even if a stray input event slips through.\n if (this.disabled || this.readonly) {\n return;\n }\n\n const nextHex = sanitizeHex((event.target as HTMLInputElement).value);\n this.hexValue = nextHex;\n this.emitChange();\n }\n\n private handlePickerChange(event: Event): void {\n if (this.disabled || this.readonly) {\n return;\n }\n\n const nextHex = sanitizeHex((event.target as HTMLInputElement).value);\n this.hexValue = nextHex;\n this.emitChange();\n }\n\n override render() {\n const previewColor = toPickerValue(this.hexValue);\n const isTransparent = !isCompleteHex(this.hexValue);\n\n return html`\n <div class=\"root\">\n <div part=\"swatch\" class=\"swatch\">\n <div\n class=${classMap({\n 'swatch-preview': true,\n 'is-transparent': isTransparent,\n })}\n style=${isTransparent ? nothing : `background-color: ${previewColor}`}\n ></div>\n <input\n part=\"picker\"\n class=\"swatch-picker\"\n type=\"color\"\n .value=${previewColor}\n ?disabled=${this.disabled || this.readonly}\n aria-label=\"Color picker\"\n @input=${this.handlePickerChange}\n />\n </div>\n <span class=\"hash\" aria-hidden=\"true\">#</span>\n <input\n part=\"input\"\n class=\"hex-input\"\n type=\"text\"\n inputmode=\"text\"\n autocomplete=\"off\"\n maxlength=\"6\"\n .value=${this.hexValue}\n ?disabled=${this.disabled}\n ?readonly=${this.readonly}\n ?required=${this.required}\n aria-label=${this.ariaLabel ?? nothing}\n aria-invalid=${this.invalid ? 'true' : nothing}\n @input=${this.handleHexInput}\n />\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-color-input': PkColorInput;\n }\n}\n"],"mappings":"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"}
|
|
@@ -15,7 +15,7 @@ import "./pk-popup-CgiXok-U.js";
|
|
|
15
15
|
import { i as waitForPopupReposition } from "./popup-placement-animation-WlEXnS85.js";
|
|
16
16
|
import { n as isPointerInsideOverlay } from "./popup-pointer-DMnuZDQl.js";
|
|
17
17
|
import { n as readLegacyInstructions } from "./field-labels-CoU9dnNq.js";
|
|
18
|
-
import { a as
|
|
18
|
+
import { a as parseIsoDate, i as parseDateList, n as coerceToDate, o as parseRange, r as formatIsoDate } from "./pk-calendar-TEFA09cI.js";
|
|
19
19
|
import { css, html, nothing } from "lit";
|
|
20
20
|
import { classMap } from "lit/directives/class-map.js";
|
|
21
21
|
import { customElement, property, query, state } from "lit/decorators.js";
|
|
@@ -379,15 +379,26 @@ var PkDatePicker = class PkDatePicker extends PkFormAssociatedElement {
|
|
|
379
379
|
this.setState("open", this.open);
|
|
380
380
|
this.controlElement?.toggleAttribute("data-popup-open", this.open);
|
|
381
381
|
}
|
|
382
|
-
if (changed.has("mode"))
|
|
382
|
+
if (changed.has("mode")) {
|
|
383
|
+
this.setState("range", this.mode === "range");
|
|
384
|
+
this.setState("multiple", this.mode === "multiple");
|
|
385
|
+
}
|
|
383
386
|
super.willUpdate(changed);
|
|
384
387
|
}
|
|
385
388
|
updateDaySlots() {
|
|
386
389
|
const names = [...this.children].map((child) => child.getAttribute("slot")).filter((name) => Boolean(name?.startsWith("day-")));
|
|
387
390
|
if (names.join(",") !== this.daySlotNames.join(",")) this.daySlotNames = names;
|
|
388
391
|
}
|
|
392
|
+
/**
|
|
393
|
+
* `value` accepts a Date at the boundary (Formie/v1) but is normalized to an ISO
|
|
394
|
+
* string in willUpdate. Coerce defensively so string-typed consumers (form value,
|
|
395
|
+
* parseRange) never receive a Date if they read before the next update tick.
|
|
396
|
+
*/
|
|
397
|
+
get valueString() {
|
|
398
|
+
return this.value instanceof Date ? formatIsoDate(coerceToDate(this.value)) : this.value;
|
|
399
|
+
}
|
|
389
400
|
syncFormValue() {
|
|
390
|
-
this.setValue(this.
|
|
401
|
+
this.setValue(this.valueString || "");
|
|
391
402
|
}
|
|
392
403
|
resetToDefaultValue() {
|
|
393
404
|
this.value = this.defaultValue;
|
|
@@ -400,8 +411,13 @@ var PkDatePicker = class PkDatePicker extends PkFormAssociatedElement {
|
|
|
400
411
|
}
|
|
401
412
|
get displayText() {
|
|
402
413
|
if (!this.value) return this.placeholder;
|
|
414
|
+
if (this.mode === "multiple") {
|
|
415
|
+
const count = parseDateList(this.valueString).length;
|
|
416
|
+
if (count === 0) return this.placeholder;
|
|
417
|
+
return `${count} date${count === 1 ? "" : "s"} selected`;
|
|
418
|
+
}
|
|
403
419
|
if (this.mode === "range") {
|
|
404
|
-
const range = parseRange(this.
|
|
420
|
+
const range = parseRange(this.valueString);
|
|
405
421
|
if (range.from && range.to) return `${formatHostDate(range.from, this.resolvedLocale)} – ${formatHostDate(range.to, this.resolvedLocale)}`;
|
|
406
422
|
if (range.from) return formatHostDate(range.from, this.resolvedLocale);
|
|
407
423
|
return this.placeholder;
|
|
@@ -413,7 +429,11 @@ var PkDatePicker = class PkDatePicker extends PkFormAssociatedElement {
|
|
|
413
429
|
return this.mode === "single" ? parseIsoDate(this.value) : null;
|
|
414
430
|
}
|
|
415
431
|
get valueAsRange() {
|
|
416
|
-
return parseRange(this.
|
|
432
|
+
return parseRange(this.valueString);
|
|
433
|
+
}
|
|
434
|
+
/** Sorted, deduped selection for `multiple` mode (empty otherwise). */
|
|
435
|
+
get valueAsDates() {
|
|
436
|
+
return this.mode === "multiple" ? parseDateList(this.valueString) : [];
|
|
417
437
|
}
|
|
418
438
|
async show() {
|
|
419
439
|
await this.openPanel();
|
|
@@ -715,4 +735,4 @@ PkDatePicker = __decorate([customElement("pk-date-picker")], PkDatePicker);
|
|
|
715
735
|
//#endregion
|
|
716
736
|
export { PkDatePicker as t };
|
|
717
737
|
|
|
718
|
-
//# sourceMappingURL=pk-date-picker-
|
|
738
|
+
//# sourceMappingURL=pk-date-picker-x-qkpQWF.js.map
|