@f-ewald/components 0.7.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +70 -47
  2. package/custom-elements.json +2236 -966
  3. package/dist/calendar-entry.d.ts +33 -0
  4. package/dist/calendar-entry.d.ts.map +1 -0
  5. package/dist/calendar-entry.js +64 -0
  6. package/dist/calendar-entry.js.map +1 -0
  7. package/dist/calendar-month.d.ts +67 -0
  8. package/dist/calendar-month.d.ts.map +1 -0
  9. package/dist/calendar-month.js +455 -0
  10. package/dist/calendar-month.js.map +1 -0
  11. package/dist/calendar-year.d.ts +43 -0
  12. package/dist/calendar-year.d.ts.map +1 -0
  13. package/dist/calendar-year.js +136 -0
  14. package/dist/calendar-year.js.map +1 -0
  15. package/dist/form-select.d.ts +21 -2
  16. package/dist/form-select.d.ts.map +1 -1
  17. package/dist/form-select.js +431 -27
  18. package/dist/form-select.js.map +1 -1
  19. package/dist/index.d.ts +3 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +3 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/map-circle.d.ts +3 -0
  24. package/dist/map-circle.d.ts.map +1 -1
  25. package/dist/map-circle.js +3 -0
  26. package/dist/map-circle.js.map +1 -1
  27. package/dist/tokens.css +4 -0
  28. package/dist/tokens.d.ts.map +1 -1
  29. package/dist/tokens.js +3 -0
  30. package/dist/tokens.js.map +1 -1
  31. package/dist/utils/calendar.d.ts +77 -0
  32. package/dist/utils/calendar.d.ts.map +1 -0
  33. package/dist/utils/calendar.js +135 -0
  34. package/dist/utils/calendar.js.map +1 -0
  35. package/docs/calendar-entry.md +53 -0
  36. package/docs/calendar-month.md +77 -0
  37. package/docs/calendar-year.md +53 -0
  38. package/docs/form-select.md +15 -3
  39. package/docs/map-circle.md +4 -0
  40. package/llms.txt +117 -28
  41. package/package.json +10 -2
  42. package/dist/map-point.d.ts +0 -31
  43. package/dist/map-point.d.ts.map +0 -1
  44. package/dist/map-point.js +0 -83
  45. package/dist/map-point.js.map +0 -1
  46. package/docs/map-point.md +0 -44
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-month.js","sourceRoot":"","sources":["../src/calendar-month.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, css, html, nothing } from \"lit\";\nimport { customElement, property, queryAssignedElements, state } from \"lit/decorators.js\";\nimport { repeat } from \"lit/directives/repeat.js\";\nimport { CalendarEntry } from \"./calendar-entry.js\";\nimport { tokens } from \"./tokens.js\";\nimport {\n CALENDAR_ENTRY_ATTRIBUTES,\n WEEKDAY_ABBR,\n assignLanes,\n daysInMonth,\n isWeekend,\n monthName,\n overlapsRange,\n readCalendarEntryElement,\n resolveEntry,\n toIsoDate,\n type LanedEntry,\n type ResolvedCalendarEntry,\n} from \"./utils/calendar.js\";\n\n/**\n * One month rendered as a top-to-bottom list of days — weekends and today\n * highlighted, with declarative `calendar-entry` children shown as colored\n * bars spanning the days they cover. An entry's title uses its first visible\n * day; every remaining visible day becomes one shared body for wrapped\n * details and an optional ending footer. Overlapping entries stack into\n * side-by-side lanes rather than being layered/hidden. Read-only.\n *\n * Lanes are computed independently per instance, from only the entries\n * overlapping this month — an entry spanning a month boundary may therefore\n * land in a different lane index in the adjacent month's `calendar-month`.\n * This is an accepted v1 limitation: cross-month lane continuity would\n * require a shared parent (`calendar-year`) to assign lanes globally.\n *\n * Entry attributes and slotted title/detail text are observed, so a\n * standalone month re-renders when consumers update declarative metadata.\n *\n * @element calendar-month\n * @slot - Declarative `calendar-entry` elements to render for this month.\n */\n@customElement(\"calendar-month\")\nexport class CalendarMonth extends LitElement {\n /** Calendar year, e.g. `2026`. */\n @property({ type: Number, reflect: true }) year: number = new Date().getFullYear();\n\n /** Calendar month, 1-12 (January = 1). */\n @property({ type: Number, reflect: true }) month = 1;\n\n @queryAssignedElements({ selector: \"calendar-entry\" })\n private readonly _entryElements!: CalendarEntry[];\n\n /** Bumped when entry elements, attributes, or slotted text change to force a re-render. */\n @state() private _entriesVersion = 0;\n\n private _entriesObserver?: MutationObserver;\n\n static override styles = [\n tokens,\n css`\n :host {\n display: block;\n font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);\n font-size: var(--ui-font-size-sm, 0.75rem);\n }\n .month-name {\n margin: 0 0 0.5rem;\n color: var(--ui-text, #0f172a);\n font-size: var(--ui-font-size, 0.875rem);\n font-weight: 600;\n }\n table {\n width: 100%;\n border-collapse: collapse;\n table-layout: fixed;\n }\n .day-row td {\n padding: 0.25rem 0.5rem;\n border-bottom: 1px solid var(--ui-border, #e2e8f0);\n }\n .day-row.weekend {\n background: var(--ui-surface-muted, #f8fafc);\n }\n .day-row.today {\n background: color-mix(in srgb, var(--ui-primary, #4f46e5) 10%, transparent);\n }\n .day-number {\n width: 1.5rem;\n color: var(--ui-text-muted, #64748b);\n font-variant-numeric: tabular-nums;\n text-align: right;\n white-space: nowrap;\n }\n .day-row.today .day-number {\n color: var(--ui-primary, #4f46e5);\n font-weight: 700;\n }\n .day-weekday {\n width: 2.25rem;\n color: var(--ui-text-muted, #64748b);\n white-space: nowrap;\n }\n .day-row.today .day-weekday {\n color: var(--ui-primary, #4f46e5);\n font-weight: 600;\n }\n .day-row.weekend .day-weekday {\n font-weight: 600;\n }\n .lane-cell {\n padding: 0.1rem 0.4rem;\n }\n .entry-bar {\n border-radius: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n transition: box-shadow 120ms ease;\n white-space: nowrap;\n }\n .entry-bar.entry-hovered,\n .entry-bar.entry-focused {\n box-shadow: inset 0 0 0 100vmax var(--ui-hover-overlay, rgb(255 255 255 / 0.32));\n }\n .entry-bar.segment-single {\n border-radius: var(--ui-radius-sm, 0.25rem);\n }\n .entry-bar.segment-start {\n border-radius: var(--ui-radius-sm, 0.25rem) var(--ui-radius-sm, 0.25rem) 0 0;\n }\n .entry-bar.segment-end {\n border-radius: 0 0 var(--ui-radius-sm, 0.25rem) var(--ui-radius-sm, 0.25rem);\n }\n .entry-bar.segment-start,\n .entry-bar.segment-middle {\n border-bottom: 0;\n }\n .entry-bar.neutral {\n background: color-mix(in srgb, var(--ui-text-muted, #64748b) 15%, var(--ui-surface, #fff));\n color: var(--ui-text-muted, #64748b);\n }\n .entry-bar.info {\n background: color-mix(in srgb, #0ea5e9 15%, var(--ui-surface, #fff));\n color: #0ea5e9;\n }\n .entry-bar.primary {\n background: color-mix(in srgb, var(--ui-primary, #4f46e5) 15%, var(--ui-surface, #fff));\n color: var(--ui-primary, #4f46e5);\n }\n .entry-bar.success {\n background: color-mix(in srgb, var(--ui-success, #16a34a) 15%, var(--ui-surface, #fff));\n color: var(--ui-success, #16a34a);\n }\n .entry-bar.warning {\n background: color-mix(in srgb, #d97706 15%, var(--ui-surface, #fff));\n color: #d97706;\n }\n .entry-bar.danger {\n background: color-mix(in srgb, var(--ui-danger, #dc2626) 15%, var(--ui-surface, #fff));\n color: var(--ui-danger, #dc2626);\n }\n .entry-line {\n display: block;\n overflow: hidden;\n }\n .day-row td.entry-title-cell {\n position: relative;\n padding: 0;\n }\n .entry-title {\n box-sizing: border-box;\n font-weight: 500;\n padding: 0.15rem 0.4rem;\n pointer-events: none;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n .entry-details {\n display: -webkit-box;\n min-height: 0;\n max-height: var(--entry-detail-max-height, 1.15em);\n flex: 0 0 auto;\n overflow: hidden;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: var(--entry-detail-lines, 1);\n font-size: var(--ui-font-size-xs, 0.6875rem);\n font-weight: 400;\n line-height: 1.15;\n overflow-wrap: anywhere;\n text-overflow: ellipsis;\n white-space: normal;\n }\n .entry-detail {\n min-height: 1.15em;\n }\n .day-row td.entry-body-cell {\n position: relative;\n padding: 0;\n vertical-align: top;\n }\n .entry-body {\n position: absolute;\n inset: 0;\n box-sizing: border-box;\n display: flex;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n padding: 0.15rem 0.4rem;\n color: inherit;\n pointer-events: none;\n }\n .entry-footer {\n flex: 0 0 auto;\n min-height: 1.15em;\n margin-top: auto;\n border-top: 1px solid color-mix(in srgb, currentColor 20%, transparent);\n padding-top: 0.15rem;\n font-size: var(--ui-font-size-xs, 0.6875rem);\n font-weight: 500;\n line-height: 1.15;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .entry-link {\n position: absolute;\n z-index: 1;\n inset: 0;\n border-radius: inherit;\n color: inherit;\n cursor: pointer;\n text-decoration: none;\n }\n .entry-link:focus-visible {\n outline: 2px solid var(--ui-primary, #4f46e5);\n outline-offset: -2px;\n box-shadow: var(--ui-focus-ring, 0 0 0 3px rgb(79 70 229 / 0.35)) inset;\n }\n @media (forced-colors: active) {\n .entry-link:focus-visible {\n outline-color: Highlight;\n box-shadow: none;\n }\n }\n slot {\n display: none;\n }\n `,\n ];\n\n /** Observes declarative entry attributes and slotted text for live updates. */\n override connectedCallback(): void {\n super.connectedCallback();\n this._entriesVersion++;\n this._entriesObserver ??= new MutationObserver(() => this._entriesVersion++);\n this._entriesObserver.observe(this, {\n attributes: true,\n attributeFilter: CALENDAR_ENTRY_ATTRIBUTES,\n characterData: true,\n childList: true,\n subtree: true,\n });\n }\n\n /** Releases the entry observer when this month disconnects. */\n override disconnectedCallback(): void {\n this._entriesObserver?.disconnect();\n super.disconnectedCallback();\n }\n\n /** Restores hover/focus classes from the live DOM after Lit updates or reuses cells. */\n protected override updated(): void {\n this._syncEntryInteractions();\n }\n\n /** Re-renders when declarative `calendar-entry` children are added or removed. */\n private _handleSlotChange(): void {\n this._entriesVersion++;\n }\n\n /** Finds the laned entry (if any) covering `date` in a given lane. */\n private _entryFor(laned: LanedEntry[], lane: number, date: Date): LanedEntry | undefined {\n return laned.find((entry) => entry.lane === lane && entry.startDate <= date && date <= entry.endDate);\n }\n\n /** Classifies one day of an entry so only the outer endpoints are rounded. */\n private _segmentClass(entry: LanedEntry, date: Date): string {\n const startsHere = date.getTime() === entry.startDate.getTime();\n const endsHere = date.getTime() === entry.endDate.getTime();\n if (startsHere && endsHere) return \"segment-single\";\n if (startsHere) return \"segment-start\";\n if (endsHere) return \"segment-end\";\n return \"segment-middle\";\n }\n\n /** Current render key shared by an entry's title and body cells. */\n private _entryKey(entry: LanedEntry): string {\n return `${entry.lane}|${entry.start}|${entry.end}|${entry.label}|${entry.href ?? \"\"}`;\n }\n\n /** Toggles one interaction class on every rendered cell belonging to an entry. */\n private _setEntryInteraction(entryKey: string, className: string, active: boolean): void {\n for (const cell of this.renderRoot.querySelectorAll<HTMLElement>(\".entry-bar\")) {\n if (cell.dataset.entryKey === entryKey) {\n cell.classList.toggle(className, active);\n }\n }\n }\n\n /** Reconciles classes against the links actually hovered or focused after a render. */\n private _syncEntryInteractions(): void {\n for (const cell of this.renderRoot.querySelectorAll<HTMLElement>(\".entry-bar\")) {\n cell.classList.remove(\"entry-hovered\", \"entry-focused\");\n }\n for (const link of this.renderRoot.querySelectorAll<HTMLElement>(\".entry-link:hover\")) {\n this._setEntryInteraction(link.dataset.entryKey ?? \"\", \"entry-hovered\", true);\n }\n const activeElement = this.shadowRoot?.activeElement;\n if (activeElement instanceof HTMLElement && activeElement.matches(\".entry-link\")) {\n this._setEntryInteraction(activeElement.dataset.entryKey ?? \"\", \"entry-focused\", true);\n }\n }\n\n /** Renders a transparent full-cell link without wrapping the visible text. */\n private _renderEntryLink(entry: LanedEntry, accessibleText: string) {\n const entryKey = this._entryKey(entry);\n return entry.href\n ? html`<a\n class=\"entry-link\"\n href=${entry.href}\n aria-label=${accessibleText}\n data-entry-key=${entryKey}\n @pointerenter=${() => this._setEntryInteraction(entryKey, \"entry-hovered\", true)}\n @pointerleave=${() => this._setEntryInteraction(entryKey, \"entry-hovered\", false)}\n @focus=${() => this._setEntryInteraction(entryKey, \"entry-focused\", true)}\n @blur=${() => this._setEntryInteraction(entryKey, \"entry-focused\", false)}\n ></a>`\n : nothing;\n }\n\n /** Joins the event title, details, and visible footer for tooltips and accessible link names. */\n private _entryBodyText(entry: LanedEntry, showFooter: boolean): string {\n return [entry.label, ...(entry.details ?? []), showFooter ? entry.footer : undefined]\n .filter((line): line is string => Boolean(line))\n .join(\"\\n\");\n }\n\n /** Renders the shared details body, with the footer reserved at its bottom edge. */\n private _renderEntryBody(\n entry: LanedEntry,\n showFooter: boolean,\n detailLineClamp: number,\n showTitleFallback = false,\n ) {\n const sourceDetails = entry.details ?? [];\n const footer = showFooter ? entry.footer : undefined;\n const details =\n showTitleFallback && sourceDetails.length === 0 && !footer\n ? [entry.label]\n : sourceDetails;\n const bodyText = this._entryBodyText(entry, showFooter);\n return html`\n ${this._renderEntryLink(entry, bodyText)}\n <div class=\"entry-body\" aria-hidden=${entry.href ? \"true\" : nothing}>\n ${detailLineClamp > 0 && details.length > 0\n ? html`\n <div\n class=\"entry-details\"\n style=${`--entry-detail-lines: ${detailLineClamp}; --entry-detail-max-height: ${\n detailLineClamp * 1.15\n }em`}\n >\n ${details.map((detail) => html`<div class=\"entry-detail\">${detail}</div>`)}\n </div>\n `\n : nothing}\n ${footer ? html`<div class=\"entry-footer\" title=${footer}>${footer}</div>` : nothing}\n </div>\n `;\n }\n\n /** Renders a row-spanning body cell with whole-line detail and footer budgets. */\n private _renderEntryBodyCell(\n entry: LanedEntry,\n bodyRows: number,\n reachesEventEnd: boolean,\n showTitleFallback = false,\n ) {\n const segmentClass = reachesEventEnd ? \"segment-end\" : \"segment-middle\";\n const footerLineBudget = reachesEventEnd && entry.footer ? 1 : 0;\n const detailLineClamp = Math.max(0, bodyRows - footerLineBudget);\n const bodyText = this._entryBodyText(entry, reachesEventEnd);\n return html`\n <td\n class=\"lane-cell entry-bar entry-body-cell ${entry.color} ${segmentClass}\"\n data-entry-key=${this._entryKey(entry)}\n rowspan=${bodyRows}\n title=${entry.href ? nothing : bodyText}\n >\n ${this._renderEntryBody(entry, reachesEventEnd, detailLineClamp, showTitleFallback)}\n </td>\n `;\n }\n\n /** Renders a lane's title/body cell, skips rows covered by a body rowspan, or emits an empty spacer. */\n private _renderLaneCell(\n laned: LanedEntry[],\n lane: number,\n date: Date,\n monthStart: Date,\n monthEnd: Date,\n ) {\n const entry = this._entryFor(laned, lane, date);\n if (!entry) {\n return html`<td class=\"lane-cell empty\"></td>`;\n }\n\n const firstVisibleDay = entry.startDate > monthStart ? entry.startDate : monthStart;\n const lastVisibleDay = entry.endDate < monthEnd ? entry.endDate : monthEnd;\n const dayOffset = date.getDate() - firstVisibleDay.getDate();\n const visibleDayCount = lastVisibleDay.getDate() - firstVisibleDay.getDate() + 1;\n const isMultiDayEntry = entry.startDate.getTime() !== entry.endDate.getTime();\n const isEndingOnlyClip =\n visibleDayCount === 1 &&\n isMultiDayEntry &&\n date.getTime() === entry.endDate.getTime();\n if (isEndingOnlyClip) {\n return this._renderEntryBodyCell(entry, 1, true, true);\n }\n if (dayOffset > 1) return nothing;\n\n if (dayOffset === 1) {\n const bodyRows = visibleDayCount - 1;\n const reachesEventEnd = lastVisibleDay.getTime() === entry.endDate.getTime();\n return this._renderEntryBodyCell(entry, bodyRows, reachesEventEnd);\n }\n\n return html`\n <td\n class=\"lane-cell entry-bar entry-title-cell ${entry.color} ${this._segmentClass(entry, date)}\"\n data-entry-key=${this._entryKey(entry)}\n title=${entry.href ? nothing : entry.label}\n >\n ${this._renderEntryLink(entry, entry.label)}\n <span class=\"entry-line entry-title\" aria-hidden=${entry.href ? \"true\" : nothing}>\n ${entry.label}\n </span>\n </td>\n `;\n }\n\n protected override render() {\n const totalDays = daysInMonth(this.year, this.month);\n const monthStart = new Date(this.year, this.month - 1, 1);\n const monthEnd = new Date(this.year, this.month - 1, totalDays);\n\n const resolved = this._entryElements\n .map(readCalendarEntryElement)\n .map(resolveEntry)\n .filter((entry): entry is ResolvedCalendarEntry => entry !== null)\n .filter((entry) => overlapsRange(entry, monthStart, monthEnd));\n const { entries: laned, laneCount } = assignLanes(resolved);\n const todayIso = toIsoDate(new Date());\n const lanes = Array.from({ length: Math.max(laneCount, 1) }, (_, i) => i);\n\n return html`\n <div class=\"month\">\n <h4 class=\"month-name\">${monthName(this.month)} ${this.year}</h4>\n <table>\n <tbody>\n ${repeat(\n Array.from({ length: totalDays }, (_, i) => i + 1),\n (d) => d,\n (d) => {\n const date = new Date(this.year, this.month - 1, d);\n const dow = date.getDay();\n const weekendCls = isWeekend(date) ? \"weekend\" : \"\";\n const todayCls = toIsoDate(date) === todayIso ? \"today\" : \"\";\n return html`\n <tr class=\"day-row ${weekendCls} ${todayCls}\">\n <td class=\"day-number\">${d}</td>\n <td class=\"day-weekday\">${WEEKDAY_ABBR[dow]}</td>\n ${lanes.map((lane) => this._renderLaneCell(laned, lane, date, monthStart, monthEnd))}\n </tr>\n `;\n },\n )}\n </tbody>\n </table>\n <slot @slotchange=${this._handleSlotChange}></slot>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"calendar-month\": CalendarMonth;\n }\n}\n"]}
@@ -0,0 +1,43 @@
1
+ import { LitElement } from "lit";
2
+ import "./calendar-month.js";
3
+ /**
4
+ * A full year of `calendar-month` blocks, generated from declarative
5
+ * `calendar-entry` children. Each entry is re-projected into the
6
+ * `calendar-month` blocks it overlaps as a freshly-created `calendar-entry`
7
+ * element — the original elements stay slotted here and are never moved,
8
+ * since a DOM node can only have one parent. Read-only.
9
+ *
10
+ * @element calendar-year
11
+ * @slot - Declarative `calendar-entry` elements spanning the displayed year.
12
+ */
13
+ export declare class CalendarYear extends LitElement {
14
+ /** Calendar year to render all 12 months for, e.g. `2026`. */
15
+ year: number;
16
+ private readonly _entryElements;
17
+ /** Bumped whenever entry elements, attributes, or slotted text change to force a re-render. */
18
+ private _entriesVersion;
19
+ private _entriesObserver?;
20
+ private readonly _entryKeys;
21
+ private _nextEntryKey;
22
+ static styles: import("lit").CSSResult[];
23
+ /**
24
+ * Watches slotted `calendar-entry` attributes and title/detail text.
25
+ * Neither reflected-property changes nor edits inside assigned elements
26
+ * fire this component's `slotchange`, so a subtree observer keeps the
27
+ * projected month entries synchronized.
28
+ */
29
+ connectedCallback(): void;
30
+ /** Releases the mutation observer when the element disconnects. */
31
+ disconnectedCallback(): void;
32
+ /** Re-renders when declarative `calendar-entry` children are added or removed. */
33
+ private _handleSlotChange;
34
+ /** Returns an immutable identity for each original slotted entry. */
35
+ private _entryKey;
36
+ protected render(): import("lit-html").TemplateResult<1>;
37
+ }
38
+ declare global {
39
+ interface HTMLElementTagNameMap {
40
+ "calendar-year": CalendarYear;
41
+ }
42
+ }
43
+ //# sourceMappingURL=calendar-year.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-year.d.ts","sourceRoot":"","sources":["../src/calendar-year.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,MAAM,KAAK,CAAC;AAKrD,OAAO,qBAAqB,CAAC;AAc7B;;;;;;;;;GASG;AACH,qBACa,YAAa,SAAQ,UAAU;IAC1C,8DAA8D;IACnB,IAAI,EAAE,MAAM,CAA4B;IAGnF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAmB;IAElD,+FAA+F;IACtF,OAAO,CAAC,eAAe,CAAK;IAErC,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwC;IACnE,OAAO,CAAC,aAAa,CAAK;IAE1B,OAAgB,MAAM,4BAgBpB;IAEF;;;;;OAKG;IACM,iBAAiB,IAAI,IAAI,CAWjC;IAED,mEAAmE;IAC1D,oBAAoB,IAAI,IAAI,CAGpC;IAED,kFAAkF;IAClF,OAAO,CAAC,iBAAiB;IAIzB,qEAAqE;IACrE,OAAO,CAAC,SAAS;IASjB,UAAmB,MAAM,yCA0CxB;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,eAAe,EAAE,YAAY,CAAC;KAC/B;CACF"}
@@ -0,0 +1,136 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { LitElement, css, html, nothing } from "lit";
8
+ import { customElement, property, queryAssignedElements, state } from "lit/decorators.js";
9
+ import { ifDefined } from "lit/directives/if-defined.js";
10
+ import { repeat } from "lit/directives/repeat.js";
11
+ import "./calendar-month.js";
12
+ import { tokens } from "./tokens.js";
13
+ import { CALENDAR_ENTRY_ATTRIBUTES, daysInMonth, overlapsRange, readCalendarEntryElement, resolveEntry, } from "./utils/calendar.js";
14
+ const MONTHS = Array.from({ length: 12 }, (_, i) => i + 1);
15
+ /**
16
+ * A full year of `calendar-month` blocks, generated from declarative
17
+ * `calendar-entry` children. Each entry is re-projected into the
18
+ * `calendar-month` blocks it overlaps as a freshly-created `calendar-entry`
19
+ * element — the original elements stay slotted here and are never moved,
20
+ * since a DOM node can only have one parent. Read-only.
21
+ *
22
+ * @element calendar-year
23
+ * @slot - Declarative `calendar-entry` elements spanning the displayed year.
24
+ */
25
+ let CalendarYear = class CalendarYear extends LitElement {
26
+ constructor() {
27
+ super(...arguments);
28
+ /** Calendar year to render all 12 months for, e.g. `2026`. */
29
+ this.year = new Date().getFullYear();
30
+ /** Bumped whenever entry elements, attributes, or slotted text change to force a re-render. */
31
+ this._entriesVersion = 0;
32
+ this._entryKeys = new WeakMap();
33
+ this._nextEntryKey = 0;
34
+ }
35
+ static { this.styles = [
36
+ tokens,
37
+ css `
38
+ :host {
39
+ display: block;
40
+ font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);
41
+ }
42
+ .year {
43
+ display: grid;
44
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
45
+ gap: 1.5rem;
46
+ }
47
+ slot {
48
+ display: none;
49
+ }
50
+ `,
51
+ ]; }
52
+ /**
53
+ * Watches slotted `calendar-entry` attributes and title/detail text.
54
+ * Neither reflected-property changes nor edits inside assigned elements
55
+ * fire this component's `slotchange`, so a subtree observer keeps the
56
+ * projected month entries synchronized.
57
+ */
58
+ connectedCallback() {
59
+ super.connectedCallback();
60
+ this._entriesVersion++;
61
+ this._entriesObserver ??= new MutationObserver(() => this._entriesVersion++);
62
+ this._entriesObserver.observe(this, {
63
+ attributes: true,
64
+ attributeFilter: CALENDAR_ENTRY_ATTRIBUTES,
65
+ characterData: true,
66
+ childList: true,
67
+ subtree: true,
68
+ });
69
+ }
70
+ /** Releases the mutation observer when the element disconnects. */
71
+ disconnectedCallback() {
72
+ this._entriesObserver?.disconnect();
73
+ super.disconnectedCallback();
74
+ }
75
+ /** Re-renders when declarative `calendar-entry` children are added or removed. */
76
+ _handleSlotChange() {
77
+ this._entriesVersion++;
78
+ }
79
+ /** Returns an immutable identity for each original slotted entry. */
80
+ _entryKey(element) {
81
+ let key = this._entryKeys.get(element);
82
+ if (!key) {
83
+ key = `entry-${this._nextEntryKey++}`;
84
+ this._entryKeys.set(element, key);
85
+ }
86
+ return key;
87
+ }
88
+ render() {
89
+ const entries = this._entryElements
90
+ .map((element) => {
91
+ const entry = resolveEntry(readCalendarEntryElement(element));
92
+ return entry ? { ...entry, projectionKey: this._entryKey(element) } : null;
93
+ })
94
+ .filter((entry) => entry !== null);
95
+ return html `
96
+ <div class="year">
97
+ ${repeat(MONTHS, (m) => m, (m) => {
98
+ const monthStart = new Date(this.year, m - 1, 1);
99
+ const monthEnd = new Date(this.year, m - 1, daysInMonth(this.year, m));
100
+ const monthEntries = entries.filter((entry) => overlapsRange(entry, monthStart, monthEnd));
101
+ return html `
102
+ <calendar-month .year=${this.year} .month=${m}>
103
+ ${repeat(monthEntries, (entry) => entry.projectionKey, (entry) => html `
104
+ <calendar-entry
105
+ start=${entry.start}
106
+ end=${entry.end}
107
+ label=${entry.label}
108
+ color=${entry.color}
109
+ href=${ifDefined(entry.href)}
110
+ >
111
+ ${(entry.details ?? []).map((detail) => html `<span slot="detail">${detail}</span>`)}
112
+ ${entry.footer ? html `<span slot="footer">${entry.footer}</span>` : nothing}
113
+ </calendar-entry>
114
+ `)}
115
+ </calendar-month>
116
+ `;
117
+ })}
118
+ </div>
119
+ <slot @slotchange=${this._handleSlotChange}></slot>
120
+ `;
121
+ }
122
+ };
123
+ __decorate([
124
+ property({ type: Number, reflect: true })
125
+ ], CalendarYear.prototype, "year", void 0);
126
+ __decorate([
127
+ queryAssignedElements({ selector: "calendar-entry" })
128
+ ], CalendarYear.prototype, "_entryElements", void 0);
129
+ __decorate([
130
+ state()
131
+ ], CalendarYear.prototype, "_entriesVersion", void 0);
132
+ CalendarYear = __decorate([
133
+ customElement("calendar-year")
134
+ ], CalendarYear);
135
+ export { CalendarYear };
136
+ //# sourceMappingURL=calendar-year.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-year.js","sourceRoot":"","sources":["../src/calendar-year.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, css, html, nothing } from \"lit\";\nimport { customElement, property, queryAssignedElements, state } from \"lit/decorators.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\nimport { repeat } from \"lit/directives/repeat.js\";\nimport { CalendarEntry } from \"./calendar-entry.js\";\nimport \"./calendar-month.js\";\nimport { tokens } from \"./tokens.js\";\nimport {\n CALENDAR_ENTRY_ATTRIBUTES,\n daysInMonth,\n overlapsRange,\n readCalendarEntryElement,\n resolveEntry,\n type ResolvedCalendarEntry,\n} from \"./utils/calendar.js\";\n\nconst MONTHS = Array.from({ length: 12 }, (_, i) => i + 1);\ntype ProjectedCalendarEntry = ResolvedCalendarEntry & { projectionKey: string };\n\n/**\n * A full year of `calendar-month` blocks, generated from declarative\n * `calendar-entry` children. Each entry is re-projected into the\n * `calendar-month` blocks it overlaps as a freshly-created `calendar-entry`\n * element — the original elements stay slotted here and are never moved,\n * since a DOM node can only have one parent. Read-only.\n *\n * @element calendar-year\n * @slot - Declarative `calendar-entry` elements spanning the displayed year.\n */\n@customElement(\"calendar-year\")\nexport class CalendarYear extends LitElement {\n /** Calendar year to render all 12 months for, e.g. `2026`. */\n @property({ type: Number, reflect: true }) year: number = new Date().getFullYear();\n\n @queryAssignedElements({ selector: \"calendar-entry\" })\n private readonly _entryElements!: CalendarEntry[];\n\n /** Bumped whenever entry elements, attributes, or slotted text change to force a re-render. */\n @state() private _entriesVersion = 0;\n\n private _entriesObserver?: MutationObserver;\n private readonly _entryKeys = new WeakMap<CalendarEntry, string>();\n private _nextEntryKey = 0;\n\n static override styles = [\n tokens,\n css`\n :host {\n display: block;\n font-family: var(--ui-font, ui-sans-serif, system-ui, sans-serif);\n }\n .year {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));\n gap: 1.5rem;\n }\n slot {\n display: none;\n }\n `,\n ];\n\n /**\n * Watches slotted `calendar-entry` attributes and title/detail text.\n * Neither reflected-property changes nor edits inside assigned elements\n * fire this component's `slotchange`, so a subtree observer keeps the\n * projected month entries synchronized.\n */\n override connectedCallback(): void {\n super.connectedCallback();\n this._entriesVersion++;\n this._entriesObserver ??= new MutationObserver(() => this._entriesVersion++);\n this._entriesObserver.observe(this, {\n attributes: true,\n attributeFilter: CALENDAR_ENTRY_ATTRIBUTES,\n characterData: true,\n childList: true,\n subtree: true,\n });\n }\n\n /** Releases the mutation observer when the element disconnects. */\n override disconnectedCallback(): void {\n this._entriesObserver?.disconnect();\n super.disconnectedCallback();\n }\n\n /** Re-renders when declarative `calendar-entry` children are added or removed. */\n private _handleSlotChange(): void {\n this._entriesVersion++;\n }\n\n /** Returns an immutable identity for each original slotted entry. */\n private _entryKey(element: CalendarEntry): string {\n let key = this._entryKeys.get(element);\n if (!key) {\n key = `entry-${this._nextEntryKey++}`;\n this._entryKeys.set(element, key);\n }\n return key;\n }\n\n protected override render() {\n const entries = this._entryElements\n .map((element) => {\n const entry = resolveEntry(readCalendarEntryElement(element));\n return entry ? { ...entry, projectionKey: this._entryKey(element) } : null;\n })\n .filter((entry): entry is ProjectedCalendarEntry => entry !== null);\n\n return html`\n <div class=\"year\">\n ${repeat(\n MONTHS,\n (m) => m,\n (m) => {\n const monthStart = new Date(this.year, m - 1, 1);\n const monthEnd = new Date(this.year, m - 1, daysInMonth(this.year, m));\n const monthEntries = entries.filter((entry) => overlapsRange(entry, monthStart, monthEnd));\n return html`\n <calendar-month .year=${this.year} .month=${m}>\n ${repeat(\n monthEntries,\n (entry) => entry.projectionKey,\n (entry) => html`\n <calendar-entry\n start=${entry.start}\n end=${entry.end}\n label=${entry.label}\n color=${entry.color}\n href=${ifDefined(entry.href)}\n >\n ${(entry.details ?? []).map((detail) => html`<span slot=\"detail\">${detail}</span>`)}\n ${entry.footer ? html`<span slot=\"footer\">${entry.footer}</span>` : nothing}\n </calendar-entry>\n `,\n )}\n </calendar-month>\n `;\n },\n )}\n </div>\n <slot @slotchange=${this._handleSlotChange}></slot>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"calendar-year\": CalendarYear;\n }\n}\n"]}
@@ -1,8 +1,12 @@
1
- import { LitElement, type PropertyValues } from "lit";
1
+ import { LitElement, type PropertyValues, type TemplateResult } from "lit";
2
2
  /** A single selectable option. */
3
3
  export interface SelectOption {
4
4
  value: string;
5
5
  label: string;
6
+ /** Optional pre-rendered icon template displayed before the label. */
7
+ icon?: TemplateResult;
8
+ /** Square icon size in pixels. Defaults to 16 when `icon` is set. */
9
+ iconSize?: number;
6
10
  }
7
11
  /**
8
12
  * A styled dropdown select: a trigger button showing the current option's
@@ -17,6 +21,13 @@ export interface SelectOption {
17
21
  * bar, a status picker) keep shrink-to-fit auto-width unchanged. To make an
18
22
  * instance full-width, size the host itself: `form-select { width: 100%; }`.
19
23
  *
24
+ * Set `searchable` to replace the button trigger with an editable combobox
25
+ * that filters the predefined options by case-insensitive label infix. Typed
26
+ * text is only a query: `value` changes exclusively when an actual option is
27
+ * selected, and an uncommitted query is discarded when the list closes.
28
+ * Each option may also provide a pre-rendered `icon` and square `iconSize`;
29
+ * iconless options reserve no leading space.
30
+ *
20
31
  * @element form-select
21
32
  * @fires change - Fired with `{ value: string }` when a different option is picked.
22
33
  */
@@ -31,12 +42,20 @@ export declare class FormSelect extends LitElement {
31
42
  label: string;
32
43
  /** Disables the trigger, preventing the popover from opening. */
33
44
  disabled: boolean;
45
+ /**
46
+ * Enables editable, case-insensitive infix filtering by option label.
47
+ * Typed text never becomes the selected `value`.
48
+ */
49
+ searchable: boolean;
34
50
  private _open;
35
51
  private _activeIndex;
52
+ private _query;
36
53
  disconnectedCallback(): void;
37
54
  protected updated(changed: PropertyValues): void;
38
55
  private renderListbox;
39
- render(): import("lit-html").TemplateResult<1>;
56
+ private renderSearchTrigger;
57
+ private renderButtonTrigger;
58
+ render(): TemplateResult<1>;
40
59
  }
41
60
  declare global {
42
61
  interface HTMLElementTagNameMap {
@@ -1 +1 @@
1
- {"version":3,"file":"form-select.d.ts","sourceRoot":"","sources":["../src/form-select.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAK1E,kCAAkC;AAClC,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBACa,UAAW,SAAQ,UAAU;;IACxC,OAAgB,MAAM,4BA2EpB;IAEF,2CAA2C;IACX,OAAO,EAAE,YAAY,EAAE,CAAM;IAC7D,qEAAqE;IACzD,KAAK,SAAM;IACvB,kDAAkD;IACtC,KAAK,SAAM;IACvB,iEAAiE;IACpC,QAAQ,UAAS;IAErC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,YAAY,CAAM;IAE1B,oBAAoB,IAAI,IAAI,CAGpC;IAED,UAAmB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAQxD;IAmDD,OAAO,CAAC,aAAa;IAuBZ,MAAM,yCAkBd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
1
+ {"version":3,"file":"form-select.d.ts","sourceRoot":"","sources":["../src/form-select.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAIV,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,KAAK,CAAC;AAKb,kCAAkC;AAClC,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBACa,UAAW,SAAQ,UAAU;;IACxC,OAAgB,MAAM,4BAuKpB;IAEF,2CAA2C;IACX,OAAO,EAAE,YAAY,EAAE,CAAM;IAC7D,qEAAqE;IACzD,KAAK,SAAM;IACvB,kDAAkD;IACtC,KAAK,SAAM;IACvB,iEAAiE;IACpC,QAAQ,UAAS;IAC9C;;;OAGG;IACyC,UAAU,UAAS;IAEtD,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,MAAM,CAAuB;IAWrC,oBAAoB,IAAI,IAAI,CAWpC;IAED,UAAmB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CA2BxD;IAkPD,OAAO,CAAC,aAAa;IA8BrB,OAAO,CAAC,mBAAmB;IA2C3B,OAAO,CAAC,mBAAmB;IAoBlB,MAAM,sBAQd;CACF;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}