@ixfx/components 0.2.5 → 0.2.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/bundle/index.d.ts +155 -29
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +1116 -310
- package/bundle/index.js.map +1 -1
- package/dist/ac-text.d.ts +2 -3
- package/dist/ac-text.d.ts.map +1 -1
- package/dist/ac-text.js +4 -4
- package/dist/ac-text.js.map +1 -1
- package/dist/{button-DgKUzE5o.js → button-B9ztaKyl.js} +4 -4
- package/dist/button-B9ztaKyl.js.map +1 -0
- package/dist/button.d.ts +3 -4
- package/dist/button.d.ts.map +1 -1
- package/dist/button.js +1 -1
- package/dist/checkbox.d.ts +1 -2
- package/dist/checkbox.d.ts.map +1 -1
- package/dist/checkbox.js +3 -3
- package/dist/checkbox.js.map +1 -1
- package/dist/colour-C3MQIjFJ-BJV-QC-3.js.map +1 -1
- package/dist/{colour-picker-Bw-AZoWx.js → colour-picker-BNqDz4wK.js} +5 -5
- package/dist/colour-picker-BNqDz4wK.js.map +1 -0
- package/dist/colour-picker.d.ts +2 -2
- package/dist/colour-picker.js +1 -1
- package/dist/crumbs.d.ts +2 -3
- package/dist/crumbs.d.ts.map +1 -1
- package/dist/crumbs.js +4 -4
- package/dist/crumbs.js.map +1 -1
- package/dist/data-display.d.ts +1 -2
- package/dist/data-display.d.ts.map +1 -1
- package/dist/data-display.js +2 -3
- package/dist/data-display.js.map +1 -1
- package/dist/decorate-O4m1U4l3.js +25 -0
- package/dist/decorate-O4m1U4l3.js.map +1 -0
- package/dist/defaults-FEZaGiYZ.js.map +1 -1
- package/dist/dist-By5URG0Y.js.map +1 -1
- package/dist/dist-D7kJgnSE.js.map +1 -1
- package/dist/editable-label.d.ts.map +1 -1
- package/dist/editable-label.js +3 -3
- package/dist/editable-label.js.map +1 -1
- package/dist/{hex-editor-Gib1Grg2.d.ts → hex-editor-2_s0Ua5t.d.ts} +3 -4
- package/dist/hex-editor-2_s0Ua5t.d.ts.map +1 -0
- package/dist/{hex-editor-Wd6ZtZA2.js → hex-editor-gH3mteMr.js} +4 -4
- package/dist/hex-editor-gH3mteMr.js.map +1 -0
- package/dist/hex.d.ts +1 -1
- package/dist/hex.js +1 -1
- package/dist/highlight-CAjwQ4GE.js.map +1 -1
- package/dist/{icon-BR5aTIiP.js → icon-CYACf6o8.js} +4 -4
- package/dist/icon-CYACf6o8.js.map +1 -0
- package/dist/{icon-DQKdfR7U.d.ts → icon-CeTDJhC7.d.ts} +3 -4
- package/dist/icon-CeTDJhC7.d.ts.map +1 -0
- package/dist/icons.d.ts +2 -2
- package/dist/icons.js +1 -1
- package/dist/icons.js.map +1 -1
- package/dist/{incr-search-BjCNClnC.js → incr-search-BZawvrfl.js} +109 -109
- package/dist/incr-search-BZawvrfl.js.map +1 -0
- package/dist/incr-search.d.ts +2 -2
- package/dist/incr-search.js +1 -1
- package/dist/index-B1hNR7Z9.d.ts.map +1 -1
- package/dist/{index-CpbBI3n7.d.ts → index-CnL9krsH.d.ts} +3 -4
- package/dist/index-CnL9krsH.d.ts.map +1 -0
- package/dist/{index-CPVcTTXo.d.ts → index-CwGkb9s1.d.ts} +6 -7
- package/dist/index-CwGkb9s1.d.ts.map +1 -0
- package/dist/{index-C5dK8RZa.d.ts → index-DrQjA8Gs.d.ts} +3 -4
- package/dist/index-DrQjA8Gs.d.ts.map +1 -0
- package/dist/{index-C9iBN908.d.ts → index-V2cJorlA.d.ts} +29 -29
- package/dist/index-V2cJorlA.d.ts.map +1 -0
- package/dist/{index-CQxanqXF.d.ts → index-kY5gxbkI.d.ts} +16 -17
- package/dist/index-kY5gxbkI.d.ts.map +1 -0
- package/dist/index.d.ts +144 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +813 -23
- package/dist/index.js.map +1 -1
- package/dist/keyboard-De_vOHLg.js.map +1 -1
- package/dist/{labelled-input-base-DS6-6C0r.js → labelled-input-base-BvgH7ldm.js} +2 -2
- package/dist/{labelled-input-base-DS6-6C0r.js.map → labelled-input-base-BvgH7ldm.js.map} +1 -1
- package/dist/{labelled-input-base-DnRh4reU.d.ts → labelled-input-base-D-Y7agky.d.ts} +2 -3
- package/dist/labelled-input-base-D-Y7agky.d.ts.map +1 -0
- package/dist/labelled-radial-input.d.ts +4 -5
- package/dist/labelled-radial-input.d.ts.map +1 -1
- package/dist/labelled-radial-input.js +5 -5
- package/dist/labelled-radial-input.js.map +1 -1
- package/dist/labelled-range-input.d.ts +1 -1
- package/dist/labelled-range-input.js +4 -4
- package/dist/labelled-range-input.js.map +1 -1
- package/dist/led.d.ts +2 -3
- package/dist/led.d.ts.map +1 -1
- package/dist/led.js +3 -3
- package/dist/led.js.map +1 -1
- package/dist/{menu-BV6UFx_z.js → menu-C3eANB5M.js} +12 -12
- package/dist/menu-C3eANB5M.js.map +1 -0
- package/dist/{menu-item-DEzL_Yjk.js → menu-item-6IU5weHi.js} +7 -7
- package/dist/menu-item-6IU5weHi.js.map +1 -0
- package/dist/{menu-item-Cikacp4F.d.ts → menu-item-ClQF2DKN.d.ts} +7 -8
- package/dist/menu-item-ClQF2DKN.d.ts.map +1 -0
- package/dist/menu.d.ts +3 -3
- package/dist/menu.js +2 -2
- package/dist/miller.d.ts +2 -3
- package/dist/miller.d.ts.map +1 -1
- package/dist/miller.js +4 -4
- package/dist/miller.js.map +1 -1
- package/dist/narrowed-text.d.ts +2 -3
- package/dist/narrowed-text.d.ts.map +1 -1
- package/dist/narrowed-text.js +4 -4
- package/dist/narrowed-text.js.map +1 -1
- package/dist/panel.d.ts +2 -3
- package/dist/panel.d.ts.map +1 -1
- package/dist/panel.js +4 -4
- package/dist/panel.js.map +1 -1
- package/dist/plots.d.ts +1 -1
- package/dist/plots.js +1 -1
- package/dist/polar-pad.d.ts +1 -2
- package/dist/polar-pad.d.ts.map +1 -1
- package/dist/polar-pad.js +3 -3
- package/dist/polar-pad.js.map +1 -1
- package/dist/{radial-input-CNJ8asY2.js → radial-input-Dbc6fgCK.js} +4 -4
- package/dist/radial-input-Dbc6fgCK.js.map +1 -0
- package/dist/{radial-input-xSTd4kEz.d.ts → radial-input-LUSBEycd.d.ts} +2 -3
- package/dist/radial-input-LUSBEycd.d.ts.map +1 -0
- package/dist/radial-input.d.ts +1 -1
- package/dist/radial-input.js +1 -1
- package/dist/range-input.d.ts +2 -3
- package/dist/range-input.d.ts.map +1 -1
- package/dist/range-input.js +3 -3
- package/dist/range-input.js.map +1 -1
- package/dist/range.d.ts +2 -3
- package/dist/range.d.ts.map +1 -1
- package/dist/range.js +3 -3
- package/dist/range.js.map +1 -1
- package/dist/registry-CZEB1YI9.js.map +1 -1
- package/dist/selecthorizontal.d.ts +2 -3
- package/dist/selecthorizontal.d.ts.map +1 -1
- package/dist/selecthorizontal.js +3 -3
- package/dist/selecthorizontal.js.map +1 -1
- package/dist/snap-container.d.ts +1 -2
- package/dist/snap-container.d.ts.map +1 -1
- package/dist/snap-container.js +3 -3
- package/dist/snap-container.js.map +1 -1
- package/dist/split-layout.d.ts +2 -3
- package/dist/split-layout.d.ts.map +1 -1
- package/dist/split-layout.js +3 -3
- package/dist/split-layout.js.map +1 -1
- package/dist/swipe.d.ts.map +1 -1
- package/dist/swipe.js +3 -3
- package/dist/swipe.js.map +1 -1
- package/dist/{tab-list-CFF7uSYH.d.ts → tab-list-BnqISNvO.d.ts} +5 -6
- package/dist/tab-list-BnqISNvO.d.ts.map +1 -0
- package/dist/tabs.d.ts +1 -1
- package/dist/tabs.js +3 -3
- package/dist/tabs.js.map +1 -1
- package/dist/tickled-controller-Cq1Va0rR.d.ts.map +1 -1
- package/dist/tickled-styles-Bg3QbcrD.js.map +1 -1
- package/dist/{timeline-DBWJsSjd.js → timeline-B62Sz6J_.js} +5 -5
- package/dist/timeline-B62Sz6J_.js.map +1 -0
- package/dist/timeline.d.ts +2 -2
- package/dist/timeline.js +1 -1
- package/dist/{tooltip-kfUBWYVB.d.ts → tooltip-CwGfb4lp.d.ts} +2 -3
- package/dist/tooltip-CwGfb4lp.d.ts.map +1 -0
- package/dist/tree-component-CQpoPo4s.d.ts.map +1 -1
- package/dist/tree-data-model-DGvRVOFY.js.map +1 -1
- package/dist/tree.d.ts +3 -4
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +4 -4
- package/dist/tree.js.map +1 -1
- package/dist/types-BKaqnpwx.d.ts.map +1 -1
- package/dist/{xy-axis-BANbgrI5.js → xy-axis-C7fNxDwY.js} +5 -5
- package/dist/xy-axis-C7fNxDwY.js.map +1 -0
- package/dist/{xy-axis-CIFok7MF.d.ts → xy-axis-D9uwpGTT.d.ts} +5 -6
- package/dist/xy-axis-D9uwpGTT.d.ts.map +1 -0
- package/dist/xy-pad.d.ts +1 -2
- package/dist/xy-pad.d.ts.map +1 -1
- package/dist/xy-pad.js +3 -3
- package/dist/xy-pad.js.map +1 -1
- package/package.json +15 -11
- package/dist/button-DgKUzE5o.js.map +0 -1
- package/dist/colour-picker-Bw-AZoWx.js.map +0 -1
- package/dist/decorate-BZbkqIhA.js +0 -9
- package/dist/hex-editor-Gib1Grg2.d.ts.map +0 -1
- package/dist/hex-editor-Wd6ZtZA2.js.map +0 -1
- package/dist/icon-BR5aTIiP.js.map +0 -1
- package/dist/icon-DQKdfR7U.d.ts.map +0 -1
- package/dist/incr-search-BjCNClnC.js.map +0 -1
- package/dist/index-C5dK8RZa.d.ts.map +0 -1
- package/dist/index-C9iBN908.d.ts.map +0 -1
- package/dist/index-CPVcTTXo.d.ts.map +0 -1
- package/dist/index-CQxanqXF.d.ts.map +0 -1
- package/dist/index-CpbBI3n7.d.ts.map +0 -1
- package/dist/labelled-input-base-DnRh4reU.d.ts.map +0 -1
- package/dist/menu-BV6UFx_z.js.map +0 -1
- package/dist/menu-item-Cikacp4F.d.ts.map +0 -1
- package/dist/menu-item-DEzL_Yjk.js.map +0 -1
- package/dist/radial-input-CNJ8asY2.js.map +0 -1
- package/dist/radial-input-xSTd4kEz.d.ts.map +0 -1
- package/dist/tab-list-CFF7uSYH.d.ts.map +0 -1
- package/dist/timeline-DBWJsSjd.js.map +0 -1
- package/dist/tooltip-kfUBWYVB.d.ts.map +0 -1
- package/dist/xy-axis-BANbgrI5.js.map +0 -1
- package/dist/xy-axis-CIFok7MF.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"narrowed-text.js","names":["#onNarrowedTextInit","#onItemClick","#handleSlotChange","#onContainerClick","#onInput","#onKeyDown","#onFocus","#onBlur","#onFocusTriggerClick","#renderItem"],"sources":["../src/narrowed-text/narrowed-text.ts"],"sourcesContent":["import type { PropertyValues } from 'lit';\nimport type { IncrSearch, IncrSearchState } from '../incr-search/index.js';\nimport type {\n NarrowedTextChangeDetail,\n NarrowedTextItem,\n Orientation,\n SelectionMode,\n} from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { customElement, property, query, state } from 'lit/decorators.js';\nimport {\n applyHighlights,\n buildHighlightTargets,\n clearHighlights,\n createIncrSearch,\n} from '../incr-search/index.js';\nimport { TickledController, tickledItemStyles, tickledStyles } from '../interaction/index.js';\n\nconst HIGHLIGHT_KEY = `narrowed-text-highlight`;\n\n@customElement(`ixfx-narrowed-text`)\nexport class NarrowedTextElement extends LitElement {\n @property({ type: String, attribute: `selection-mode` }) selectionMode: SelectionMode = `single`;\n @property({ type: Boolean, attribute: `required-selection` }) requiredSelection = false;\n @property({ type: String, attribute: `orientation` }) orientation: Orientation = `horizontal`;\n @property({ type: Boolean, attribute: `nowrap` }) nowrap = false;\n @property({ type: String, attribute: `separator` }) separator = ` `;\n @property({ type: String, attribute: `width` }) width: string | undefined;\n @property({ type: String, attribute: `height` }) height: string | undefined;\n @property({ type: Boolean, attribute: `preserve-filter` }) preserveFilter = false;\n @property({ type: String }) value = ``;\n\n @state() private _query = ``;\n @state() private _computedItems: NarrowedTextItem[] = [];\n @state() private _filteredItems: NarrowedTextItem[] = [];\n @state() private _isFocused = false;\n @query(`slot`) private _slot!: HTMLSlotElement;\n\n private _selectedValues: Set<string> = new Set();\n private _search: IncrSearch<NarrowedTextItem> = createIncrSearch<NarrowedTextItem>({\n selector: item => item.label ?? item.value,\n });\n\n private _searchState: IncrSearchState<NarrowedTextItem> | undefined;\n private _unsubSearch: (() => void) | undefined;\n\n // TickledController manages hover and keyboard focus\n private tickled = new TickledController<number>(this, {\n getItems: () => {\n return this._filteredItems.map((_, i) => ({\n id: i,\n enabled: true,\n }));\n },\n onTickle: (id) => {\n if (id === undefined || !this.shadowRoot)\n return;\n const itemsContainer = this.shadowRoot.querySelector(`.items`);\n if (!itemsContainer)\n return;\n const itemEls = itemsContainer.querySelectorAll(`.item`);\n const itemEl = itemEls[id];\n if (itemEl) {\n itemEl.scrollIntoView({ block: `nearest`, inline: `nearest` });\n }\n },\n });\n\n get selected(): string | string[] {\n if (this.selectionMode === `single`) {\n return this._selectedValues.values().next().value ?? ``;\n } else {\n return [...this._selectedValues];\n }\n }\n\n set selected(value: string | string[]) {\n if (this.selectionMode === `single`) {\n this._selectedValues.clear();\n if (value) {\n this._selectedValues.add(value as string);\n }\n } else {\n this._selectedValues.clear();\n if (Array.isArray(value)) {\n value.forEach(v => this._selectedValues.add(v));\n }\n }\n\n this._updateFilteredItems();\n }\n\noverride connectedCallback(): void {\n super.connectedCallback();\n this._unsubSearch = this._search.onChange((state) => {\n const results = state.results.map(r => r.item);\n for (const item of this._computedItems) {\n if (this._selectedValues.has(item.value) && !results.includes(item)) {\n results.push(item);\n }\n }\nthis._filteredItems = results;\n this._searchState = state;\n this.requestUpdate();\n });\n this.addEventListener(`narrowed-text-init`, () => this.#onNarrowedTextInit());\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._unsubSearch?.();\n this._search.dispose();\n clearHighlights({ key: HIGHLIGHT_KEY });\n this.removeEventListener(`narrowed-text-init`, () => this.#onNarrowedTextInit());\n }\n\n protected override firstUpdated(): void {\n this._updateComputedItems();\n }\n\n protected override updated(changedProperties: PropertyValues): void {\n if (changedProperties.has(`value`)) {\n this._updateSelectedFromValue();\n }\n this._applyHighlights();\n }\n\n #handleSlotChange = (): void => {\n this._updateComputedItems();\n };\n\n private _updateComputedItems(): void {\n const slottedElements = this.querySelectorAll(`[data-value]`);\n const items: NarrowedTextItem[] = [];\n\n slottedElements.forEach((el) => {\n const value = el.getAttribute(`data-value`) ?? ``;\n const label = el.getAttribute(`data-label`) ?? el.textContent?.trim() ?? value;\n const description = el.getAttribute(`data-description`) ?? undefined;\n const iconName = el.getAttribute(`data-icon-name`) ?? undefined;\n\n items.push({ value, label, description, iconName });\n });\n\n this._computedItems = items;\n void this._search.setItems(items);\n }\n\n private _updateSelectedFromValue(): void {\n if (this.selectionMode === `single`) {\n this._selectedValues.clear();\n if (this.value) {\n this._selectedValues.add(this.value);\n }\n } else {\n const values = this.value.split(`,`).filter(v => v.trim());\n this._selectedValues.clear();\n values.forEach(v => this._selectedValues.add(v.trim()));\n }\n\n this._updateFilteredItems();\n }\n\n private _updateFilteredItems(): void {\n void this._search.setQuery(this._query);\n }\n\n private _applyHighlights(): void {\n if (!this._query.trim() || !this._searchState || !this.shadowRoot) {\n clearHighlights({ key: HIGHLIGHT_KEY });\n return;\n }\n\n const targets = buildHighlightTargets(\n this.shadowRoot,\n `.item-label`,\n this._searchState.positionsByItem,\n (el) => {\n const v = el.getAttribute(`data-item-value`);\n return this._computedItems.find(i => i.value === v);\n },\n (el) => {\n const v = el.getAttribute(`data-item-value`);\n const i = this._computedItems.find(x => x.value === v);\n return i?.label ?? i?.value ?? ``;\n },\n );\n applyHighlights(targets, { key: HIGHLIGHT_KEY });\n }\n\n #onInput = (e: Event): void => {\n const input = e.target as HTMLInputElement;\n this._query = input.value;\n // Reset tickled to first item when query changes\n if (this._query.trim() && this._filteredItems.length > 0) {\n this.tickled.setTickled(0);\n } else {\n this.tickled.clearTickled();\n }\n this._updateFilteredItems();\n };\n\n#onKeyDown = (e: KeyboardEvent): void => {\n if (this._filteredItems.length === 0) {\n return;\n }\n\n switch (e.key) {\n case `Tab`: {\n if (e.shiftKey) {\n e.preventDefault();\n this.dispatchEvent(new CustomEvent(`narrowed-text-shift-tab`, {\n bubbles: true,\n composed: true,\n }));\n }\n return;\n }\n case `ArrowRight`: {\n if (this.orientation !== `horizontal`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n const lastIndex = this._filteredItems.length - 1;\n if (currentTickled !== undefined && currentTickled >= lastIndex) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`next`);\n break;\n }\n case `ArrowLeft`: {\n if (this.orientation !== `horizontal`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n if (currentTickled !== undefined && currentTickled <= 0) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`previous`);\n break;\n }\n case `ArrowDown`: {\n if (this.orientation !== `vertical`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n const lastIndex = this._filteredItems.length - 1;\n if (currentTickled !== undefined && currentTickled >= lastIndex) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`next`);\n break;\n }\n case `ArrowUp`: {\n if (this.orientation !== `vertical`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n if (currentTickled !== undefined && currentTickled <= 0) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`previous`);\n break;\n }\n case `Enter`: {\n e.preventDefault();\n const tickledItem = this._filteredItems[this.tickled.tickledId ?? -1];\n if (this.orientation !== `horizontal`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n const lastIndex = this._filteredItems.length - 1;\n if (currentTickled !== undefined && currentTickled >= lastIndex) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`next`);\n break;\n }\n case `ArrowLeft`: {\n if (this.orientation !== `horizontal`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n if (currentTickled !== undefined && currentTickled <= 0) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`previous`);\n break;\n }\n case `ArrowDown`: {\n if (this.orientation !== `vertical`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n const lastIndex = this._filteredItems.length - 1;\n if (currentTickled !== undefined && currentTickled >= lastIndex) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`next`);\n break;\n }\n case `ArrowUp`: {\n if (this.orientation !== `vertical`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n if (currentTickled !== undefined && currentTickled <= 0) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`previous`);\n break;\n }\n case `Enter`: {\n e.preventDefault();\n const tickledItem = this._filteredItems[this.tickled.tickledId ?? -1];\n if (tickledItem) {\n this._selectItem(tickledItem, false);\n // Enter always clears filter regardless of preserveFilter\n this._query = ``;\n this._updateFilteredItems();\n }\n break;\n }\n case ` `: {\n e.preventDefault();\n if (this.tickled.tickledId !== undefined && this._filteredItems[this.tickled.tickledId]) {\n this._selectItem(this._filteredItems[this.tickled.tickledId], false);\n }\n break;\n }\n case `Escape`: {\n e.preventDefault();\n this._query = ``;\n this.tickled.clearTickled();\n this._updateFilteredItems();\n break;\n }\n }\n };\n\n #onFocus = (): void => {\n this._isFocused = true;\n if (this._query.trim() && this._filteredItems.length > 0) {\n this.tickled.setTickled(0);\n }\n };\n\n #onNarrowedTextInit = (): void => {\n const input = this.shadowRoot?.querySelector(`.search-input`) as HTMLInputElement | null;\n if (input) {\n requestAnimationFrame(() => {\n input.focus();\n });\n }\n };\n\n focus(): void {\n // Override focus to focus internal input\n const input = this.shadowRoot?.querySelector(`.search-input`) as HTMLInputElement | null;\n if (input) {\n input.focus();\n } else {\n super.focus();\n }\n }\n\n blur(): void {\n const input = this.shadowRoot?.querySelector(`.search-input`) as HTMLInputElement | null;\n if (input) {\n input.blur();\n } else {\n super.blur();\n }\n };\n\n #onBlur = (): void => {\n this._isFocused = false;\n this.tickled.clearTickled();\n this.dispatchEvent(new CustomEvent(`narrowed-text-blur`, { bubbles: true, composed: true }));\n };\n\n #onFocusTriggerClick = (): void => {\n const input = this.shadowRoot?.querySelector(`.search-input`) as HTMLInputElement | null;\n input?.focus();\n };\n\n #onContainerClick = (e: MouseEvent): void => {\n const target = e.target as HTMLElement;\n if (target.classList.contains(`item`) || target.closest(`.item`)) {\n return;\n }\n const input = this.shadowRoot?.querySelector(`.search-input`) as HTMLInputElement | null;\n input?.focus();\n };\n\n #onItemClick(item: NarrowedTextItem): void {\n this._selectItem(item);\n const clickedIndex = this._filteredItems.findIndex(i => i.value === item.value);\n if (clickedIndex >= 0) {\n this.tickled.handlePointerEnter(clickedIndex);\n }\n const input = this.shadowRoot?.querySelector(`.search-input`) as HTMLInputElement | null;\n input?.focus();\n }\n\n private _selectItem(item: NarrowedTextItem, clearFilter = true): void {\n if (this.selectionMode === `single`) {\n if (this._selectedValues.has(item.value) && !this.requiredSelection) {\n this._selectedValues.clear();\n } else {\n this._selectedValues.clear();\n this._selectedValues.add(item.value);\n }\n } else {\n if (this._selectedValues.has(item.value)) {\n if (!this.requiredSelection || this._selectedValues.size > 1) {\n this._selectedValues.delete(item.value);\n }\n } else {\n this._selectedValues.add(item.value);\n }\n }\n\n this._updateValueFromSelected();\n this._updateFilteredItems();\n\n const selectedItems = this._computedItems.filter(i => this._selectedValues.has(i.value));\n\n this.dispatchEvent(new CustomEvent<NarrowedTextChangeDetail>(`change`, {\n detail: { item, query: this._query, selected: selectedItems },\n bubbles: true,\n composed: true,\n }));\n\n if (clearFilter && !this.preserveFilter && this._query) {\n this._query = ``;\n this._updateFilteredItems();\n }\n }\n\n private _updateValueFromSelected(): void {\n if (this.selectionMode === `single`) {\n this.value = [...this._selectedValues][0] ?? ``;\n } else {\n this.value = [...this._selectedValues].join(`,`);\n }\n }\n\n #renderItem(item: NarrowedTextItem, index: number) {\n const isTickled = this.tickled.isTickled(index);\n const isSelected = this._selectedValues.has(item.value);\n const label = item.label ?? item.value;\n\n return html`\n <div\n class=\"item ${isTickled ? `tickled` : ``} ${isSelected ? `selected` : ``}\"\n part=\"item\"\n role=\"option\"\n aria-selected=${isSelected}\n @click=${() => this.#onItemClick(item)}\n @pointerenter=${() => this.tickled.handlePointerEnter(index)}\n >\n ${item.iconName ? html`<ixfx-icon class=\"item-icon\" name=${item.iconName}></ixfx-icon>` : nothing}\n <span class=\"item-label\" part=\"label\" data-item-value=${item.value}>${label}</span>\n </div>\n `;\n }\n\n protected override render() {\n const isScrollable = this.width !== undefined || this.height !== undefined;\n\n return html`\n <slot @slotchange=${this.#handleSlotChange} style=\"display: none;\"></slot>\n <div\n class=\"container ${this.orientation} ${isScrollable ? `scrollable` : ``} ${this._isFocused ? `focused` : ``}\"\n part=\"container\"\n style=${this._getContainerStyle()}\n data-input-mode=${this.tickled.inputMode}\n @click=${this.#onContainerClick}\n >\n <input\n type=\"text\"\n class=\"search-input\"\n .value=${this._query}\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-label=\"Search items\"\n @input=${this.#onInput}\n @keydown=${this.#onKeyDown}\n @focus=${this.#onFocus}\n @blur=${this.#onBlur}\n >\n <div class=\"focus-trigger\" @click=${this.#onFocusTriggerClick}></div>\n <div \n class=\"items\" \n part=\"items\" \n role=\"listbox\"\n @pointerleave=${(e: PointerEvent) => this.tickled.handlePointerLeave(e)}\n >\n ${this._filteredItems.map((item, i) => this.#renderItem(item, i))}\n </div>\n </div>\n `;\n }\n\n private _getContainerStyle(): string {\n const styles: string[] = [];\n if (this.width) {\n styles.push(`width: ${this.width}`);\n }\n if (this.height) {\n styles.push(`height: ${this.height}`);\n }\n return styles.join(`; `);\n }\n\n static override styles = [tickledStyles, tickledItemStyles, css`\n :host {\n display: inline-block;\n position: relative;\n font-family: var(--font-family, system-ui, sans-serif);\n font-size: var(--text-m, 12px);\n color: var(--surface-2-text);\n --item-padding: var(--space-xs, 3px) var(--space-m, 8px);\n --item-border-radius: var(--radius-s, 3px);\n --item-icon-spacing: var(--space-xs, 3px);\n }\n\n .container {\n display: flex;\n position: relative;\n min-width: min-content;\n min-height: min-content;\n }\n\n .container.horizontal {\n flex-direction: row;\n align-items: stretch;\n }\n\n .container.vertical {\n flex-direction: column;\n }\n\n .container.scrollable {\n scrollbar-width: none;\n overflow-x: auto;\n overflow-y: hidden;\n .vertical {\n overflow-x: hidden;\n overflow-y: auto;\n }\n }\n\n .container.focused {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n\n .search-input {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n opacity: 0;\n cursor: text;\n z-index: 1;\n pointer-events: none;\n }\n\n .search-input:focus {\n outline: none;\n }\n\n .focus-trigger {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 0;\n cursor: text;\n }\n\n .items {\n display: flex;\n flex-wrap: wrap;\n gap: var(--item-spacing, var(--space-xs, 3px));\n align-items: center;\n width: 100%;\n height: 100%;\n min-height: var(--item-height, 28px);\n position: relative;\n z-index: 2;\n pointer-events: auto;\n }\n\n .container.horizontal .items {\n flex-direction: row;\n }\n\n .container.vertical .items {\n flex-direction: column;\n align-items: stretch;\n }\n\n :host([nowrap]) .items {\n flex-wrap: nowrap;\n }\n\n .item-icon {\n flex-shrink: 0;\n width: 1em;\n height: 1em;\n }\n\n .item-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n color: var(--item-label-color, var(--item-text, inherit));\n font-style: var(--item-label-font-style, var(--item-label-font-style-default, normal));\n text-decoration: var(--item-label-text-decoration, var(--item-label-text-decoration-default, none));\n text-underline-offset: var(--item-label-text-underline-offset, auto);\n }\n\n .item.selected .item-label {\n --item-label-color: var(--item-text-selected);\n --item-label-font-style: var(--item-label-font-style-selected, italic);\n }\n\n .item.tickled .item-label {\n --item-label-text-decoration: var(--item-label-text-decoration-tickled, underline dotted);\n --item-label-text-underline-offset: var(--item-label-text-underline-offset-tickled, 3px);\n }\n\n .item.active .item-label {\n --item-label-color: var(--item-text-selected);\n }\n\n .item.selected.tickled .item-label {\n --item-label-color: var(--item-text-selected);\n --item-label-font-style: var(--item-label-font-style-selected, italic);\n --item-label-text-decoration: var(--item-label-text-decoration-tickled, underline dotted);\n --item-label-text-underline-offset: var(--item-label-text-underline-offset-tickled, 3px);\n }\n\n ::highlight(narrowed-text-highlight) {\n background: var(--highlight-background, var(--accent));\n color: var(--highlight-color, var(--accent-text, #fff));\n border-radius: 2px;\n padding: 0 1px;\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-narrowed-text': NarrowedTextElement;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"narrowed-text.js","names":["#onNarrowedTextInit","#onItemClick","#handleSlotChange","#onContainerClick","#onInput","#onKeyDown","#onFocus","#onBlur","#onFocusTriggerClick","#renderItem","customElement"],"sources":["../src/narrowed-text/narrowed-text.ts"],"sourcesContent":["import type { PropertyValues } from 'lit';\nimport type { IncrSearch, IncrSearchState } from '../incr-search/index.js';\nimport type {\n NarrowedTextChangeDetail,\n NarrowedTextItem,\n Orientation,\n SelectionMode,\n} from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport {\n applyHighlights,\n buildHighlightTargets,\n clearHighlights,\n createIncrSearch,\n} from '../incr-search/index.js';\nimport { TickledController, tickledItemStyles, tickledStyles } from '../interaction/index.js';\n\nconst HIGHLIGHT_KEY = `narrowed-text-highlight`;\n\n@customElement(`ixfx-narrowed-text`)\nexport class NarrowedTextElement extends LitElement {\n @property({ type: String, attribute: `selection-mode` }) selectionMode: SelectionMode = `single`;\n @property({ type: Boolean, attribute: `required-selection` }) requiredSelection = false;\n @property({ type: String, attribute: `orientation` }) orientation: Orientation = `horizontal`;\n @property({ type: Boolean, attribute: `nowrap` }) nowrap = false;\n @property({ type: String, attribute: `separator` }) separator = ` `;\n @property({ type: String, attribute: `width` }) width: string | undefined;\n @property({ type: String, attribute: `height` }) height: string | undefined;\n @property({ type: Boolean, attribute: `preserve-filter` }) preserveFilter = false;\n @property({ type: String }) value = ``;\n\n @state() private _query = ``;\n @state() private _computedItems: NarrowedTextItem[] = [];\n @state() private _filteredItems: NarrowedTextItem[] = [];\n @state() private _isFocused = false;\n @query(`slot`) private _slot!: HTMLSlotElement;\n\n private _selectedValues: Set<string> = new Set();\n private _search: IncrSearch<NarrowedTextItem> = createIncrSearch<NarrowedTextItem>({\n selector: item => item.label ?? item.value,\n });\n\n private _searchState: IncrSearchState<NarrowedTextItem> | undefined;\n private _unsubSearch: (() => void) | undefined;\n\n // TickledController manages hover and keyboard focus\n private tickled = new TickledController<number>(this, {\n getItems: () => {\n return this._filteredItems.map((_, i) => ({\n id: i,\n enabled: true,\n }));\n },\n onTickle: (id) => {\n if (id === undefined || !this.shadowRoot)\n return;\n const itemsContainer = this.shadowRoot.querySelector(`.items`);\n if (!itemsContainer)\n return;\n const itemEls = itemsContainer.querySelectorAll(`.item`);\n const itemEl = itemEls[id];\n if (itemEl) {\n itemEl.scrollIntoView({ block: `nearest`, inline: `nearest` });\n }\n },\n });\n\n get selected(): string | string[] {\n if (this.selectionMode === `single`) {\n return this._selectedValues.values().next().value ?? ``;\n } else {\n return [...this._selectedValues];\n }\n }\n\n set selected(value: string | string[]) {\n if (this.selectionMode === `single`) {\n this._selectedValues.clear();\n if (value) {\n this._selectedValues.add(value as string);\n }\n } else {\n this._selectedValues.clear();\n if (Array.isArray(value)) {\n value.forEach(v => this._selectedValues.add(v));\n }\n }\n\n this._updateFilteredItems();\n }\n\noverride connectedCallback(): void {\n super.connectedCallback();\n this._unsubSearch = this._search.onChange((state) => {\n const results = state.results.map(r => r.item);\n for (const item of this._computedItems) {\n if (this._selectedValues.has(item.value) && !results.includes(item)) {\n results.push(item);\n }\n }\nthis._filteredItems = results;\n this._searchState = state;\n this.requestUpdate();\n });\n this.addEventListener(`narrowed-text-init`, () => this.#onNarrowedTextInit());\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._unsubSearch?.();\n this._search.dispose();\n clearHighlights({ key: HIGHLIGHT_KEY });\n this.removeEventListener(`narrowed-text-init`, () => this.#onNarrowedTextInit());\n }\n\n protected override firstUpdated(): void {\n this._updateComputedItems();\n }\n\n protected override updated(changedProperties: PropertyValues): void {\n if (changedProperties.has(`value`)) {\n this._updateSelectedFromValue();\n }\n this._applyHighlights();\n }\n\n #handleSlotChange = (): void => {\n this._updateComputedItems();\n };\n\n private _updateComputedItems(): void {\n const slottedElements = this.querySelectorAll(`[data-value]`);\n const items: NarrowedTextItem[] = [];\n\n slottedElements.forEach((el) => {\n const value = el.getAttribute(`data-value`) ?? ``;\n const label = el.getAttribute(`data-label`) ?? el.textContent?.trim() ?? value;\n const description = el.getAttribute(`data-description`) ?? undefined;\n const iconName = el.getAttribute(`data-icon-name`) ?? undefined;\n\n items.push({ value, label, description, iconName });\n });\n\n this._computedItems = items;\n void this._search.setItems(items);\n }\n\n private _updateSelectedFromValue(): void {\n if (this.selectionMode === `single`) {\n this._selectedValues.clear();\n if (this.value) {\n this._selectedValues.add(this.value);\n }\n } else {\n const values = this.value.split(`,`).filter(v => v.trim());\n this._selectedValues.clear();\n values.forEach(v => this._selectedValues.add(v.trim()));\n }\n\n this._updateFilteredItems();\n }\n\n private _updateFilteredItems(): void {\n void this._search.setQuery(this._query);\n }\n\n private _applyHighlights(): void {\n if (!this._query.trim() || !this._searchState || !this.shadowRoot) {\n clearHighlights({ key: HIGHLIGHT_KEY });\n return;\n }\n\n const targets = buildHighlightTargets(\n this.shadowRoot,\n `.item-label`,\n this._searchState.positionsByItem,\n (el) => {\n const v = el.getAttribute(`data-item-value`);\n return this._computedItems.find(i => i.value === v);\n },\n (el) => {\n const v = el.getAttribute(`data-item-value`);\n const i = this._computedItems.find(x => x.value === v);\n return i?.label ?? i?.value ?? ``;\n },\n );\n applyHighlights(targets, { key: HIGHLIGHT_KEY });\n }\n\n #onInput = (e: Event): void => {\n const input = e.target as HTMLInputElement;\n this._query = input.value;\n // Reset tickled to first item when query changes\n if (this._query.trim() && this._filteredItems.length > 0) {\n this.tickled.setTickled(0);\n } else {\n this.tickled.clearTickled();\n }\n this._updateFilteredItems();\n };\n\n#onKeyDown = (e: KeyboardEvent): void => {\n if (this._filteredItems.length === 0) {\n return;\n }\n\n switch (e.key) {\n case `Tab`: {\n if (e.shiftKey) {\n e.preventDefault();\n this.dispatchEvent(new CustomEvent(`narrowed-text-shift-tab`, {\n bubbles: true,\n composed: true,\n }));\n }\n return;\n }\n case `ArrowRight`: {\n if (this.orientation !== `horizontal`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n const lastIndex = this._filteredItems.length - 1;\n if (currentTickled !== undefined && currentTickled >= lastIndex) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`next`);\n break;\n }\n case `ArrowLeft`: {\n if (this.orientation !== `horizontal`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n if (currentTickled !== undefined && currentTickled <= 0) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`previous`);\n break;\n }\n case `ArrowDown`: {\n if (this.orientation !== `vertical`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n const lastIndex = this._filteredItems.length - 1;\n if (currentTickled !== undefined && currentTickled >= lastIndex) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`next`);\n break;\n }\n case `ArrowUp`: {\n if (this.orientation !== `vertical`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n if (currentTickled !== undefined && currentTickled <= 0) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`previous`);\n break;\n }\n case `Enter`: {\n e.preventDefault();\n const tickledItem = this._filteredItems[this.tickled.tickledId ?? -1];\n if (this.orientation !== `horizontal`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n const lastIndex = this._filteredItems.length - 1;\n if (currentTickled !== undefined && currentTickled >= lastIndex) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`next`);\n break;\n }\n case `ArrowLeft`: {\n if (this.orientation !== `horizontal`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n if (currentTickled !== undefined && currentTickled <= 0) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`previous`);\n break;\n }\n case `ArrowDown`: {\n if (this.orientation !== `vertical`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n const lastIndex = this._filteredItems.length - 1;\n if (currentTickled !== undefined && currentTickled >= lastIndex) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`next`);\n break;\n }\n case `ArrowUp`: {\n if (this.orientation !== `vertical`) {\n return;\n }\n const currentTickled = this.tickled.tickledId;\n if (currentTickled !== undefined && currentTickled <= 0) {\n return;\n }\n e.preventDefault();\n this.tickled.handleKeyboardNavigation(`previous`);\n break;\n }\n case `Enter`: {\n e.preventDefault();\n const tickledItem = this._filteredItems[this.tickled.tickledId ?? -1];\n if (tickledItem) {\n this._selectItem(tickledItem, false);\n // Enter always clears filter regardless of preserveFilter\n this._query = ``;\n this._updateFilteredItems();\n }\n break;\n }\n case ` `: {\n e.preventDefault();\n if (this.tickled.tickledId !== undefined && this._filteredItems[this.tickled.tickledId]) {\n this._selectItem(this._filteredItems[this.tickled.tickledId], false);\n }\n break;\n }\n case `Escape`: {\n e.preventDefault();\n this._query = ``;\n this.tickled.clearTickled();\n this._updateFilteredItems();\n break;\n }\n }\n };\n\n #onFocus = (): void => {\n this._isFocused = true;\n if (this._query.trim() && this._filteredItems.length > 0) {\n this.tickled.setTickled(0);\n }\n };\n\n #onNarrowedTextInit = (): void => {\n const input = this.shadowRoot?.querySelector(`.search-input`) as HTMLInputElement | null;\n if (input) {\n requestAnimationFrame(() => {\n input.focus();\n });\n }\n };\n\n focus(): void {\n // Override focus to focus internal input\n const input = this.shadowRoot?.querySelector(`.search-input`) as HTMLInputElement | null;\n if (input) {\n input.focus();\n } else {\n super.focus();\n }\n }\n\n blur(): void {\n const input = this.shadowRoot?.querySelector(`.search-input`) as HTMLInputElement | null;\n if (input) {\n input.blur();\n } else {\n super.blur();\n }\n };\n\n #onBlur = (): void => {\n this._isFocused = false;\n this.tickled.clearTickled();\n this.dispatchEvent(new CustomEvent(`narrowed-text-blur`, { bubbles: true, composed: true }));\n };\n\n #onFocusTriggerClick = (): void => {\n const input = this.shadowRoot?.querySelector(`.search-input`) as HTMLInputElement | null;\n input?.focus();\n };\n\n #onContainerClick = (e: MouseEvent): void => {\n const target = e.target as HTMLElement;\n if (target.classList.contains(`item`) || target.closest(`.item`)) {\n return;\n }\n const input = this.shadowRoot?.querySelector(`.search-input`) as HTMLInputElement | null;\n input?.focus();\n };\n\n #onItemClick(item: NarrowedTextItem): void {\n this._selectItem(item);\n const clickedIndex = this._filteredItems.findIndex(i => i.value === item.value);\n if (clickedIndex >= 0) {\n this.tickled.handlePointerEnter(clickedIndex);\n }\n const input = this.shadowRoot?.querySelector(`.search-input`) as HTMLInputElement | null;\n input?.focus();\n }\n\n private _selectItem(item: NarrowedTextItem, clearFilter = true): void {\n if (this.selectionMode === `single`) {\n if (this._selectedValues.has(item.value) && !this.requiredSelection) {\n this._selectedValues.clear();\n } else {\n this._selectedValues.clear();\n this._selectedValues.add(item.value);\n }\n } else {\n if (this._selectedValues.has(item.value)) {\n if (!this.requiredSelection || this._selectedValues.size > 1) {\n this._selectedValues.delete(item.value);\n }\n } else {\n this._selectedValues.add(item.value);\n }\n }\n\n this._updateValueFromSelected();\n this._updateFilteredItems();\n\n const selectedItems = this._computedItems.filter(i => this._selectedValues.has(i.value));\n\n this.dispatchEvent(new CustomEvent<NarrowedTextChangeDetail>(`change`, {\n detail: { item, query: this._query, selected: selectedItems },\n bubbles: true,\n composed: true,\n }));\n\n if (clearFilter && !this.preserveFilter && this._query) {\n this._query = ``;\n this._updateFilteredItems();\n }\n }\n\n private _updateValueFromSelected(): void {\n if (this.selectionMode === `single`) {\n this.value = [...this._selectedValues][0] ?? ``;\n } else {\n this.value = [...this._selectedValues].join(`,`);\n }\n }\n\n #renderItem(item: NarrowedTextItem, index: number) {\n const isTickled = this.tickled.isTickled(index);\n const isSelected = this._selectedValues.has(item.value);\n const label = item.label ?? item.value;\n\n return html`\n <div\n class=\"item ${isTickled ? `tickled` : ``} ${isSelected ? `selected` : ``}\"\n part=\"item\"\n role=\"option\"\n aria-selected=${isSelected}\n @click=${() => this.#onItemClick(item)}\n @pointerenter=${() => this.tickled.handlePointerEnter(index)}\n >\n ${item.iconName ? html`<ixfx-icon class=\"item-icon\" name=${item.iconName}></ixfx-icon>` : nothing}\n <span class=\"item-label\" part=\"label\" data-item-value=${item.value}>${label}</span>\n </div>\n `;\n }\n\n protected override render() {\n const isScrollable = this.width !== undefined || this.height !== undefined;\n\n return html`\n <slot @slotchange=${this.#handleSlotChange} style=\"display: none;\"></slot>\n <div\n class=\"container ${this.orientation} ${isScrollable ? `scrollable` : ``} ${this._isFocused ? `focused` : ``}\"\n part=\"container\"\n style=${this._getContainerStyle()}\n data-input-mode=${this.tickled.inputMode}\n @click=${this.#onContainerClick}\n >\n <input\n type=\"text\"\n class=\"search-input\"\n .value=${this._query}\n autocomplete=\"off\"\n spellcheck=\"false\"\n aria-label=\"Search items\"\n @input=${this.#onInput}\n @keydown=${this.#onKeyDown}\n @focus=${this.#onFocus}\n @blur=${this.#onBlur}\n >\n <div class=\"focus-trigger\" @click=${this.#onFocusTriggerClick}></div>\n <div \n class=\"items\" \n part=\"items\" \n role=\"listbox\"\n @pointerleave=${(e: PointerEvent) => this.tickled.handlePointerLeave(e)}\n >\n ${this._filteredItems.map((item, i) => this.#renderItem(item, i))}\n </div>\n </div>\n `;\n }\n\n private _getContainerStyle(): string {\n const styles: string[] = [];\n if (this.width) {\n styles.push(`width: ${this.width}`);\n }\n if (this.height) {\n styles.push(`height: ${this.height}`);\n }\n return styles.join(`; `);\n }\n\n static override styles = [tickledStyles, tickledItemStyles, css`\n :host {\n display: inline-block;\n position: relative;\n font-family: var(--font-family, system-ui, sans-serif);\n font-size: var(--text-m, 12px);\n color: var(--surface-2-text);\n --item-padding: var(--space-xs, 3px) var(--space-m, 8px);\n --item-border-radius: var(--radius-s, 3px);\n --item-icon-spacing: var(--space-xs, 3px);\n }\n\n .container {\n display: flex;\n position: relative;\n min-width: min-content;\n min-height: min-content;\n }\n\n .container.horizontal {\n flex-direction: row;\n align-items: stretch;\n }\n\n .container.vertical {\n flex-direction: column;\n }\n\n .container.scrollable {\n scrollbar-width: none;\n overflow-x: auto;\n overflow-y: hidden;\n .vertical {\n overflow-x: hidden;\n overflow-y: auto;\n }\n }\n\n .container.focused {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n\n .search-input {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n opacity: 0;\n cursor: text;\n z-index: 1;\n pointer-events: none;\n }\n\n .search-input:focus {\n outline: none;\n }\n\n .focus-trigger {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 0;\n cursor: text;\n }\n\n .items {\n display: flex;\n flex-wrap: wrap;\n gap: var(--item-spacing, var(--space-xs, 3px));\n align-items: center;\n width: 100%;\n height: 100%;\n min-height: var(--item-height, 28px);\n position: relative;\n z-index: 2;\n pointer-events: auto;\n }\n\n .container.horizontal .items {\n flex-direction: row;\n }\n\n .container.vertical .items {\n flex-direction: column;\n align-items: stretch;\n }\n\n :host([nowrap]) .items {\n flex-wrap: nowrap;\n }\n\n .item-icon {\n flex-shrink: 0;\n width: 1em;\n height: 1em;\n }\n\n .item-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n color: var(--item-label-color, var(--item-text, inherit));\n font-style: var(--item-label-font-style, var(--item-label-font-style-default, normal));\n text-decoration: var(--item-label-text-decoration, var(--item-label-text-decoration-default, none));\n text-underline-offset: var(--item-label-text-underline-offset, auto);\n }\n\n .item.selected .item-label {\n --item-label-color: var(--item-text-selected);\n --item-label-font-style: var(--item-label-font-style-selected, italic);\n }\n\n .item.tickled .item-label {\n --item-label-text-decoration: var(--item-label-text-decoration-tickled, underline dotted);\n --item-label-text-underline-offset: var(--item-label-text-underline-offset-tickled, 3px);\n }\n\n .item.active .item-label {\n --item-label-color: var(--item-text-selected);\n }\n\n .item.selected.tickled .item-label {\n --item-label-color: var(--item-text-selected);\n --item-label-font-style: var(--item-label-font-style-selected, italic);\n --item-label-text-decoration: var(--item-label-text-decoration-tickled, underline dotted);\n --item-label-text-underline-offset: var(--item-label-text-underline-offset-tickled, 3px);\n }\n\n ::highlight(narrowed-text-highlight) {\n background: var(--highlight-background, var(--accent));\n color: var(--highlight-color, var(--accent-text, #fff));\n border-radius: 2px;\n padding: 0 1px;\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-narrowed-text': NarrowedTextElement;\n }\n}\n"],"mappings":"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"}
|
package/dist/panel.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as _$lit from "lit";
|
|
2
1
|
import { LitElement } from "lit";
|
|
3
2
|
|
|
4
3
|
//#region src/panel/panel.d.ts
|
|
@@ -27,8 +26,8 @@ declare class PanelElement extends LitElement {
|
|
|
27
26
|
private _onCloseClick;
|
|
28
27
|
private _getCaretIcon;
|
|
29
28
|
protected updated(changed: Map<string, unknown>): void;
|
|
30
|
-
protected render():
|
|
31
|
-
static styles:
|
|
29
|
+
protected render(): import("lit").TemplateResult<1>;
|
|
30
|
+
static styles: import("lit").CSSResult;
|
|
32
31
|
}
|
|
33
32
|
declare global {
|
|
34
33
|
interface HTMLElementTagNameMap {
|
package/dist/panel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panel.d.ts","names":[],"sources":["../src/panel/panel.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"panel.d.ts","names":[],"sources":["../src/panel/panel.ts"],"mappings":";;;KAKY,gBAAA;AAAA,KACA,YAAA;AAAA,KACA,sBAAA;AAAA,UAEK,iBAAA;EAAA,SACN,SAAS;AAAA;AAAA,KAGR,gBAAA,GAAmB,WAAW,CAAC,iBAAA;AAAA,KAC/B,eAAA,GAAkB,WAAW;AAAA,UAExB,oBAAA;EACf,MAAA,EAAQ,gBAAA;EACR,KAAA,EAAO,eAAe;AAAA;AAAA,cAIX,YAAA,SAAqB,UAAA;EACY,SAAA;EACyB,WAAA,EAAa,gBAAA;EACrD,QAAA;EACD,KAAA;EACwB,QAAA;EACS,iBAAA,EAAmB,sBAAA;EACf,OAAA,EAAS,YAAA;EAAA,QAEzD,WAAA;EAAA,QAET,cAAA;EAAA,QAWA,aAAA;EAAA,QAUA,aAAA;EAAA,UAIW,OAAA,CAAQ,OAAA,EAAS,GAAA;EAAA,UAOjB,MAAA,CAAA,iBAAM,cAAA;EAAA,OAyDT,MAAA,gBAAM,SAAA;AAAA;AAAA,QAkShB,MAAA;EAAA,UACI,qBAAA;IACR,YAAA,EAAc,YAAY;EAAA;AAAA;AAAA,UAIb,YAAA;EACf,gBAAA,oBAAoC,oBAAA,EAClC,IAAA,EAAM,CAAA,EACN,QAAA,GAAW,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,oBAAA,CAAqB,CAAA,YAC3D,OAAA,aAAoB,uBAAA,eAEpB,IAAA,UACA,QAAA,EAAU,kCAAA,EACV,OAAA,aAAoB,uBAAA;AAAA"}
|
package/dist/panel.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as __decorate } from "./decorate-
|
|
2
|
-
import "./icon-
|
|
1
|
+
import { n as safeCustomElement, t as __decorate } from "./decorate-O4m1U4l3.js";
|
|
2
|
+
import "./icon-CYACf6o8.js";
|
|
3
3
|
import { LitElement, css, html, nothing } from "lit";
|
|
4
|
-
import {
|
|
4
|
+
import { property, state } from "lit/decorators.js";
|
|
5
5
|
//#region src/panel/panel.ts
|
|
6
6
|
let PanelElement = class PanelElement extends LitElement {
|
|
7
7
|
constructor(..._args) {
|
|
@@ -401,7 +401,7 @@ __decorate([property({
|
|
|
401
401
|
reflect: true
|
|
402
402
|
})], PanelElement.prototype, "variant", void 0);
|
|
403
403
|
__decorate([state()], PanelElement.prototype, "_isVertical", void 0);
|
|
404
|
-
PanelElement = __decorate([
|
|
404
|
+
PanelElement = __decorate([safeCustomElement(`ixfx-panel`)], PanelElement);
|
|
405
405
|
//#endregion
|
|
406
406
|
export { PanelElement };
|
|
407
407
|
|
package/dist/panel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panel.js","names":[],"sources":["../src/panel/panel.ts"],"sourcesContent":["import { css, html, LitElement, nothing } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport '../icons/icon.js';\n\nexport type PanelOrientation = `horizontal` | `vertical`;\nexport type PanelVariant = `titlebar` | `midline`;\nexport type PanelToggleInteraction = `implicit` | `explicit` | `disabled`;\n\nexport interface PanelToggleDetail {\n readonly collapsed: boolean;\n}\n\nexport type PanelToggleEvent = CustomEvent<PanelToggleDetail>;\nexport type PanelCloseEvent = CustomEvent<void>;\n\nexport interface PanelElementEventMap {\n toggle: PanelToggleEvent;\n close: PanelCloseEvent;\n}\n\n@customElement(`ixfx-panel`)\nexport class PanelElement extends LitElement {\n @property({ type: Boolean, reflect: true }) collapsed = false;\n @property({ type: String, attribute: `orientation`, reflect: true }) orientation: PanelOrientation = `horizontal`;\n @property({ type: Boolean }) closable = false;\n @property({ type: String }) title = ``;\n @property({ type: String, attribute: `icon-name` }) iconName = ``;\n @property({ type: String, attribute: `toggle-interaction` }) toggleInteraction: PanelToggleInteraction = `implicit`;\n @property({ type: String, attribute: `variant`, reflect: true }) variant: PanelVariant = `titlebar`;\n\n @state() private _isVertical = false;\n\n private _onToggleClick() {\n this.collapsed = !this.collapsed;\n this.dispatchEvent(\n new CustomEvent<PanelToggleDetail>(`toggle`, {\n detail: { collapsed: this.collapsed },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private _onCloseClick() {\n this.dispatchEvent(\n new CustomEvent<void>(`close`, {\n bubbles: true,\n composed: true,\n }),\n );\n this.remove();\n }\n\n private _getCaretIcon(): string {\n return `chevron-down`;\n }\n\n protected override updated(changed: Map<string, unknown>): void {\n super.updated(changed);\n if (changed.has(`orientation`)) {\n this._isVertical = this.orientation === `vertical`;\n }\n }\n\n protected override render() {\n const caretIcon = this._getCaretIcon();\n const showCaret = this.toggleInteraction !== `disabled`;\n const implicitToggle = this.toggleInteraction === `implicit`;\n\n const caretRotation = this._isVertical\n ? (this.collapsed ? `` : `-90deg`)\n : (this.collapsed ? `-90deg` : ``);\n\n return html`\n <div\n class=\"titlebar\"\n role=\"toolbar\"\n @click=${implicitToggle ? this._onToggleClick : nothing}\n >\n <div class=\"title-text-wrapper\">\n ${this.iconName ? html`<ixfx-icon class=\"title-icon\" name=${this.iconName}></ixfx-icon>` : nothing}\n <span class=\"title-text\">${this.title}</span>\n </div>\n\n <div class=\"toolbar\" @click=${(e: Event) => e.stopPropagation()}>\n <slot name=\"toolbar\"></slot>\n ${this.closable\n ? html`\n <button\n class=\"close-btn\"\n type=\"button\"\n aria-label=\"Close panel\"\n @click=${this._onCloseClick}\n >\n <ixfx-icon name=\"close\"></ixfx-icon>\n </button>\n `\n : nothing}\n ${showCaret\n ? html`\n <button\n class=\"caret-btn\"\n type=\"button\"\n aria-label=${this.collapsed ? `Expand panel` : `Collapse panel`}\n @click=${this._onToggleClick}\n >\n <ixfx-icon name=${caretIcon} prominence .rotate=${caretRotation.length > 0 ? caretRotation : nothing}></ixfx-icon>\n </button>\n `\n : nothing}\n </div>\n </div>\n\n <div class=\"content-wrapper\" ?expanded=${!this.collapsed}>\n <div class=\"content-inner\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n\n static override styles = css`\n :host {\n display: flex;\n flex-direction: column;\n background: var(--surface-3);\n border: var(--border-subtle);\n border-radius: var(--radius-m);\n overflow: hidden;\n box-sizing: border-box;\n }\n\n :host([orientation=\"vertical\"]) {\n flex-direction: row;\n align-self: flex-start;\n min-width: 0 !important;\n flex-shrink: 1;\n }\n\n .titlebar {\n display: flex;\n flex-direction: row;\n align-items: center;\n padding: var(--space-s) var(--space-m);\n background: var(--surface-4);\n color: var(--surface-3-text);\n min-height: 2em;\n flex-shrink: 0;\n }\n\n :host([orientation=\"vertical\"]) .titlebar {\n flex-direction: row;\n min-width: 2em;\n writing-mode: vertical-rl;\n text-orientation: mixed;\n }\n\n .caret-btn,\n .close-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: var(--space-xs);\n margin: 0;\n cursor: pointer;\n color: inherit;\n border-radius: var(--radius-s);\n transition: background var(--transition);\n opacity: var(--prominence-idle-opacity);\n }\n\n .caret-btn:hover,\n .close-btn:hover {\n background: var(--surface-5);\n opacity: var(--prominence-tickled-opacity);\n\n }\n\n .caret-btn:focus-visible,\n .close-btn:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 1px;\n }\n\n ixfx-icon {\n width: 1.25em;\n height: 1.25em;\n transition: transform var(--transition);\n }\n\n .title-icon {\n flex-shrink: 0;\n }\n\n .title-text {\n flex: 1;\n padding-left: 1ch;\n font-family: var(--font-family);\n font-size: var(--text-m);\n font-weight: var(--font-weight-bold, 600);\n white-space: nowrap;\n overflow: hidden;\n align-self: center;\n text-overflow: ellipsis;\n user-select: none;\n -webkit-user-select: none;\n }\n\n :host([toggle-interaction=\"implicit\"]) .titlebar {\n cursor: pointer;\n }\n\n :host([orientation=\"vertical\"]) .title-text {\n writing-mode: vertical-rl;\n padding-left: 0;\n padding-bottom: 1ch;\n text-orientation: mixed;\n transform: rotate(180deg);\n }\n\n .toolbar {\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n margin-left: auto;\n }\n\n :host([orientation=\"vertical\"]) .toolbar {\n flex-direction: column;\n margin-left: 0;\n margin-top: auto;\n writing-mode: horizontal-tb;\n }\n\n slot[name=\"toolbar\"] {\n display: contents;\n }\n\n ::slotted(slot[name=\"toolbar\"]) {\n display: contents;\n }\n\n .content-wrapper {\n interpolate-size: allow-keywords;\n overflow: hidden;\n height: 0;\n transition: height var(--transition, 0.2s ease-out);\n background: var(--surface-3);\n \n }\n\n .content-wrapper[expanded] {\n height: auto;\n }\n\n :host([orientation=\"vertical\"]) .content-wrapper {\n height: unset;\n width: 0;\n transition: width var(--transition, 0.2s ease-out);\n }\n\n :host([orientation=\"vertical\"]) .content-wrapper[expanded] {\n width: auto;\n }\n\n .content-inner {\n box-shadow: var(--deboss-3);\n\n min-height: 0;\n min-width: 0;\n overflow: hidden;\n padding: var(--space-m);\n transform: translateY(-100%);\n transition: transform var(--transition, 0.2s ease-out);\n }\n\n .content-wrapper[expanded] .content-inner {\n transform: translateY(0);\n }\n\n :host([orientation=\"vertical\"]) .content-inner {\n width: max-content;\n height:100%;\n transform: translateX(-100%);\n }\n\n :host([orientation=\"vertical\"]) .content-wrapper[expanded] .content-inner {\n transform: translateX(0);\n }\n\n .title-text-wrapper {\n display:flex;\n padding: 0 var(--space-s);\n }\n\n /* === Midline variant === */\n\n :host([variant=\"midline\"]) {\n border: none !important;\n border-radius: 0 !important;\n background: transparent;\n }\n\n :host([variant=\"midline\"][orientation=\"horizontal\"]) .titlebar,\n :host([variant=\"midline\"][orientation=\"vertical\"]) .titlebar {\n background: transparent;\n padding: var(--space-xs) var(--space-m);\n min-height: unset;\n position: relative;\n }\n\n :host([variant=\"midline\"][orientation=\"vertical\"]) .titlebar {\n padding: var(--space-m) var(--space-xs);\n min-width: unset;\n }\n\n :host([variant=\"midline\"]) .title-text-wrapper {\n position: relative;\n z-index: 1;\n display: flex;\n align-items: center;\n gap: var(--space-s);\n background: var(--surface-3);\n }\n\n :host([variant=\"midline\"]) .title-text {\n font-weight: normal;\n color: var(--surface-3-text);\n padding: 0 0.5ch 0 0.5ch;\n background: transparent;\n box-shadow: none;\n flex: unset;\n width: auto;\n white-space: nowrap;\n }\n\n :host([variant=\"midline\"]) .title-icon {\n background: transparent;\n flex-shrink: 0;\n }\n\n :host([variant=\"midline\"]) .caret-btn {\n position: relative;\n z-index: 1;\n background: var(--surface-3);\n opacity: 1;\n }\n\n :host([variant=\"midline\"][orientation=\"vertical\"]) .title-text {\n transform: rotate(180deg);\n padding: 0.5ch 0 0.5ch 0ch;\n }\n\n :host([variant=\"midline\"]) .toolbar {\n position: relative;\n z-index: 2;\n background: var(--surface-3);\n margin-left: 0;\n }\n\n :host([variant=\"midline\"][orientation=\"horizontal\"]) .toolbar {\n margin-left: auto;\n }\n\n /* Debossed line runs from after title-text to before toolbar */\n :host([variant=\"midline\"]) .titlebar::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 0;\n right: 0;\n height: 1px;\n transform: translateY(-50%);\n background: var(--surface-2);\n box-shadow:\n 0 -1px 0 var(--surface-5),\n 0 1px 0 var(--surface-1);\n z-index: 0;\n }\n\n /* For vertical midline, line runs vertically */\n :host([variant=\"midline\"][orientation=\"vertical\"]) .titlebar::after {\n top: 0;\n bottom: 0;\n left: 50%;\n right: unset;\n width: 1px;\n height: 100%;\n transform: translateX(-50%);\n box-shadow:\n -1px 0 0 var(--surface-5),\n 1px 0 0 var(--surface-1);\n }\n\n :host([variant=\"midline\"]) .content-inner {\n box-shadow: none;\n background: var(--surface-3);\n }\n\n :host([variant=\"midline\"]) .content-wrapper {\n background: transparent;\n }\n\n :host([variant=\"midline\"][orientation=\"vertical\"]) .content-wrapper {\n background: transparent;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-panel': PanelElement;\n }\n}\n\nexport interface PanelElement {\n addEventListener: (<K extends keyof PanelElementEventMap>(\n type: K,\n listener: (this: PanelElement, event: PanelElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}"],"mappings":";;;;;AAqBO,IAAA,eAAA,MAAM,qBAAqB,WAAW;;;mBACa;qBAC6C;kBAC7D;eACJ;kBAC2B;2BAC0C;iBAChB;qBAE1D;;CAE/B,iBAAyB;AACvB,OAAK,YAAY,CAAC,KAAK;AACvB,OAAK,cACH,IAAI,YAA+B,UAAU;GAC3C,QAAQ,EAAE,WAAW,KAAK,WAAW;GACrC,SAAS;GACT,UAAU;GACX,CAAC,CACH;;CAGH,gBAAwB;AACtB,OAAK,cACH,IAAI,YAAkB,SAAS;GAC7B,SAAS;GACT,UAAU;GACX,CAAC,CACH;AACD,OAAK,QAAQ;;CAGf,gBAAgC;AAC9B,SAAO;;CAGT,QAA2B,SAAqC;AAC9D,QAAM,QAAQ,QAAQ;AACtB,MAAI,QAAQ,IAAI,cAAc,CAC5B,MAAK,cAAc,KAAK,gBAAgB;;CAI5C,SAA4B;EAC1B,MAAM,YAAY,KAAK,eAAe;EACtC,MAAM,YAAY,KAAK,sBAAsB;EAC7C,MAAM,iBAAiB,KAAK,sBAAsB;EAElD,MAAM,gBAAgB,KAAK,cACtB,KAAK,YAAY,KAAK,WACtB,KAAK,YAAY,WAAW;AAEjC,SAAO,IAAI;;;;iBAIE,iBAAiB,KAAK,iBAAiB,QAAQ;;;YAGpD,KAAK,WAAW,IAAI,sCAAsC,KAAK,SAAS,iBAAiB,QAAQ;qCACxE,KAAK,MAAM;;;uCAGT,MAAa,EAAE,iBAAiB,CAAC;;YAE5D,KAAK,WACH,IAAI;;;;;uBAKK,KAAK,cAAc;;;;cAK5B,QAAQ;YACV,YACE,IAAI;;;;yBAIO,KAAK,YAAY,iBAAiB,iBAAiB;qBACvD,KAAK,eAAe;;8BAEX,UAAU,sBAAsB,cAAc,SAAS,IAAI,gBAAgB,QAAQ;;cAGnG,QAAQ;;;;+CAIyB,CAAC,KAAK,UAAU;;;;;;;;gBAQpC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAnG3B,SAAS;CAAE,MAAM;CAAS,SAAS;CAAM,CAAC,CAAA,EAAA,aAAA,WAAA,aAAA,KAAA,EAAA;YAC1C,SAAS;CAAE,MAAM;CAAQ,WAAW;CAAe,SAAS;CAAM,CAAC,CAAA,EAAA,aAAA,WAAA,eAAA,KAAA,EAAA;YACnE,SAAS,EAAE,MAAM,SAAS,CAAC,CAAA,EAAA,aAAA,WAAA,YAAA,KAAA,EAAA;YAC3B,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,EAAA,aAAA,WAAA,SAAA,KAAA,EAAA;YAC1B,SAAS;CAAE,MAAM;CAAQ,WAAW;CAAa,CAAC,CAAA,EAAA,aAAA,WAAA,YAAA,KAAA,EAAA;YAClD,SAAS;CAAE,MAAM;CAAQ,WAAW;CAAsB,CAAC,CAAA,EAAA,aAAA,WAAA,qBAAA,KAAA,EAAA;YAC3D,SAAS;CAAE,MAAM;CAAQ,WAAW;CAAW,SAAS;CAAM,CAAC,CAAA,EAAA,aAAA,WAAA,WAAA,KAAA,EAAA;YAE/D,OAAO,CAAA,EAAA,aAAA,WAAA,eAAA,KAAA,EAAA;2BAVT,cAAc,aAAa,CAAA,EAAA,aAAA"}
|
|
1
|
+
{"version":3,"file":"panel.js","names":["customElement"],"sources":["../src/panel/panel.ts"],"sourcesContent":["import { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport '../icons/icon.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nexport type PanelOrientation = `horizontal` | `vertical`;\nexport type PanelVariant = `titlebar` | `midline`;\nexport type PanelToggleInteraction = `implicit` | `explicit` | `disabled`;\n\nexport interface PanelToggleDetail {\n readonly collapsed: boolean;\n}\n\nexport type PanelToggleEvent = CustomEvent<PanelToggleDetail>;\nexport type PanelCloseEvent = CustomEvent<void>;\n\nexport interface PanelElementEventMap {\n toggle: PanelToggleEvent;\n close: PanelCloseEvent;\n}\n\n@customElement(`ixfx-panel`)\nexport class PanelElement extends LitElement {\n @property({ type: Boolean, reflect: true }) collapsed = false;\n @property({ type: String, attribute: `orientation`, reflect: true }) orientation: PanelOrientation = `horizontal`;\n @property({ type: Boolean }) closable = false;\n @property({ type: String }) title = ``;\n @property({ type: String, attribute: `icon-name` }) iconName = ``;\n @property({ type: String, attribute: `toggle-interaction` }) toggleInteraction: PanelToggleInteraction = `implicit`;\n @property({ type: String, attribute: `variant`, reflect: true }) variant: PanelVariant = `titlebar`;\n\n @state() private _isVertical = false;\n\n private _onToggleClick() {\n this.collapsed = !this.collapsed;\n this.dispatchEvent(\n new CustomEvent<PanelToggleDetail>(`toggle`, {\n detail: { collapsed: this.collapsed },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n private _onCloseClick() {\n this.dispatchEvent(\n new CustomEvent<void>(`close`, {\n bubbles: true,\n composed: true,\n }),\n );\n this.remove();\n }\n\n private _getCaretIcon(): string {\n return `chevron-down`;\n }\n\n protected override updated(changed: Map<string, unknown>): void {\n super.updated(changed);\n if (changed.has(`orientation`)) {\n this._isVertical = this.orientation === `vertical`;\n }\n }\n\n protected override render() {\n const caretIcon = this._getCaretIcon();\n const showCaret = this.toggleInteraction !== `disabled`;\n const implicitToggle = this.toggleInteraction === `implicit`;\n\n const caretRotation = this._isVertical\n ? (this.collapsed ? `` : `-90deg`)\n : (this.collapsed ? `-90deg` : ``);\n\n return html`\n <div\n class=\"titlebar\"\n role=\"toolbar\"\n @click=${implicitToggle ? this._onToggleClick : nothing}\n >\n <div class=\"title-text-wrapper\">\n ${this.iconName ? html`<ixfx-icon class=\"title-icon\" name=${this.iconName}></ixfx-icon>` : nothing}\n <span class=\"title-text\">${this.title}</span>\n </div>\n\n <div class=\"toolbar\" @click=${(e: Event) => e.stopPropagation()}>\n <slot name=\"toolbar\"></slot>\n ${this.closable\n ? html`\n <button\n class=\"close-btn\"\n type=\"button\"\n aria-label=\"Close panel\"\n @click=${this._onCloseClick}\n >\n <ixfx-icon name=\"close\"></ixfx-icon>\n </button>\n `\n : nothing}\n ${showCaret\n ? html`\n <button\n class=\"caret-btn\"\n type=\"button\"\n aria-label=${this.collapsed ? `Expand panel` : `Collapse panel`}\n @click=${this._onToggleClick}\n >\n <ixfx-icon name=${caretIcon} prominence .rotate=${caretRotation.length > 0 ? caretRotation : nothing}></ixfx-icon>\n </button>\n `\n : nothing}\n </div>\n </div>\n\n <div class=\"content-wrapper\" ?expanded=${!this.collapsed}>\n <div class=\"content-inner\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n\n static override styles = css`\n :host {\n display: flex;\n flex-direction: column;\n background: var(--surface-3);\n border: var(--border-subtle);\n border-radius: var(--radius-m);\n overflow: hidden;\n box-sizing: border-box;\n }\n\n :host([orientation=\"vertical\"]) {\n flex-direction: row;\n align-self: flex-start;\n min-width: 0 !important;\n flex-shrink: 1;\n }\n\n .titlebar {\n display: flex;\n flex-direction: row;\n align-items: center;\n padding: var(--space-s) var(--space-m);\n background: var(--surface-4);\n color: var(--surface-3-text);\n min-height: 2em;\n flex-shrink: 0;\n }\n\n :host([orientation=\"vertical\"]) .titlebar {\n flex-direction: row;\n min-width: 2em;\n writing-mode: vertical-rl;\n text-orientation: mixed;\n }\n\n .caret-btn,\n .close-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: var(--space-xs);\n margin: 0;\n cursor: pointer;\n color: inherit;\n border-radius: var(--radius-s);\n transition: background var(--transition);\n opacity: var(--prominence-idle-opacity);\n }\n\n .caret-btn:hover,\n .close-btn:hover {\n background: var(--surface-5);\n opacity: var(--prominence-tickled-opacity);\n\n }\n\n .caret-btn:focus-visible,\n .close-btn:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 1px;\n }\n\n ixfx-icon {\n width: 1.25em;\n height: 1.25em;\n transition: transform var(--transition);\n }\n\n .title-icon {\n flex-shrink: 0;\n }\n\n .title-text {\n flex: 1;\n padding-left: 1ch;\n font-family: var(--font-family);\n font-size: var(--text-m);\n font-weight: var(--font-weight-bold, 600);\n white-space: nowrap;\n overflow: hidden;\n align-self: center;\n text-overflow: ellipsis;\n user-select: none;\n -webkit-user-select: none;\n }\n\n :host([toggle-interaction=\"implicit\"]) .titlebar {\n cursor: pointer;\n }\n\n :host([orientation=\"vertical\"]) .title-text {\n writing-mode: vertical-rl;\n padding-left: 0;\n padding-bottom: 1ch;\n text-orientation: mixed;\n transform: rotate(180deg);\n }\n\n .toolbar {\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n margin-left: auto;\n }\n\n :host([orientation=\"vertical\"]) .toolbar {\n flex-direction: column;\n margin-left: 0;\n margin-top: auto;\n writing-mode: horizontal-tb;\n }\n\n slot[name=\"toolbar\"] {\n display: contents;\n }\n\n ::slotted(slot[name=\"toolbar\"]) {\n display: contents;\n }\n\n .content-wrapper {\n interpolate-size: allow-keywords;\n overflow: hidden;\n height: 0;\n transition: height var(--transition, 0.2s ease-out);\n background: var(--surface-3);\n \n }\n\n .content-wrapper[expanded] {\n height: auto;\n }\n\n :host([orientation=\"vertical\"]) .content-wrapper {\n height: unset;\n width: 0;\n transition: width var(--transition, 0.2s ease-out);\n }\n\n :host([orientation=\"vertical\"]) .content-wrapper[expanded] {\n width: auto;\n }\n\n .content-inner {\n box-shadow: var(--deboss-3);\n\n min-height: 0;\n min-width: 0;\n overflow: hidden;\n padding: var(--space-m);\n transform: translateY(-100%);\n transition: transform var(--transition, 0.2s ease-out);\n }\n\n .content-wrapper[expanded] .content-inner {\n transform: translateY(0);\n }\n\n :host([orientation=\"vertical\"]) .content-inner {\n width: max-content;\n height:100%;\n transform: translateX(-100%);\n }\n\n :host([orientation=\"vertical\"]) .content-wrapper[expanded] .content-inner {\n transform: translateX(0);\n }\n\n .title-text-wrapper {\n display:flex;\n padding: 0 var(--space-s);\n }\n\n /* === Midline variant === */\n\n :host([variant=\"midline\"]) {\n border: none !important;\n border-radius: 0 !important;\n background: transparent;\n }\n\n :host([variant=\"midline\"][orientation=\"horizontal\"]) .titlebar,\n :host([variant=\"midline\"][orientation=\"vertical\"]) .titlebar {\n background: transparent;\n padding: var(--space-xs) var(--space-m);\n min-height: unset;\n position: relative;\n }\n\n :host([variant=\"midline\"][orientation=\"vertical\"]) .titlebar {\n padding: var(--space-m) var(--space-xs);\n min-width: unset;\n }\n\n :host([variant=\"midline\"]) .title-text-wrapper {\n position: relative;\n z-index: 1;\n display: flex;\n align-items: center;\n gap: var(--space-s);\n background: var(--surface-3);\n }\n\n :host([variant=\"midline\"]) .title-text {\n font-weight: normal;\n color: var(--surface-3-text);\n padding: 0 0.5ch 0 0.5ch;\n background: transparent;\n box-shadow: none;\n flex: unset;\n width: auto;\n white-space: nowrap;\n }\n\n :host([variant=\"midline\"]) .title-icon {\n background: transparent;\n flex-shrink: 0;\n }\n\n :host([variant=\"midline\"]) .caret-btn {\n position: relative;\n z-index: 1;\n background: var(--surface-3);\n opacity: 1;\n }\n\n :host([variant=\"midline\"][orientation=\"vertical\"]) .title-text {\n transform: rotate(180deg);\n padding: 0.5ch 0 0.5ch 0ch;\n }\n\n :host([variant=\"midline\"]) .toolbar {\n position: relative;\n z-index: 2;\n background: var(--surface-3);\n margin-left: 0;\n }\n\n :host([variant=\"midline\"][orientation=\"horizontal\"]) .toolbar {\n margin-left: auto;\n }\n\n /* Debossed line runs from after title-text to before toolbar */\n :host([variant=\"midline\"]) .titlebar::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 0;\n right: 0;\n height: 1px;\n transform: translateY(-50%);\n background: var(--surface-2);\n box-shadow:\n 0 -1px 0 var(--surface-5),\n 0 1px 0 var(--surface-1);\n z-index: 0;\n }\n\n /* For vertical midline, line runs vertically */\n :host([variant=\"midline\"][orientation=\"vertical\"]) .titlebar::after {\n top: 0;\n bottom: 0;\n left: 50%;\n right: unset;\n width: 1px;\n height: 100%;\n transform: translateX(-50%);\n box-shadow:\n -1px 0 0 var(--surface-5),\n 1px 0 0 var(--surface-1);\n }\n\n :host([variant=\"midline\"]) .content-inner {\n box-shadow: none;\n background: var(--surface-3);\n }\n\n :host([variant=\"midline\"]) .content-wrapper {\n background: transparent;\n }\n\n :host([variant=\"midline\"][orientation=\"vertical\"]) .content-wrapper {\n background: transparent;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-panel': PanelElement;\n }\n}\n\nexport interface PanelElement {\n addEventListener: (<K extends keyof PanelElementEventMap>(\n type: K,\n listener: (this: PanelElement, event: PanelElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n"],"mappings":";;;;;AAsBO,IAAA,eAAA,MAAM,qBAAqB,WAAW;;;mBACa;qBAC6C;kBAC7D;eACJ;kBAC2B;2BAC0C;iBAChB;qBAE1D;;CAE/B,iBAAyB;EACvB,KAAK,YAAY,CAAC,KAAK;EACvB,KAAK,cACH,IAAI,YAA+B,UAAU;GAC3C,QAAQ,EAAE,WAAW,KAAK,UAAU;GACpC,SAAS;GACT,UAAU;EACZ,CAAC,CACH;CACF;CAEA,gBAAwB;EACtB,KAAK,cACH,IAAI,YAAkB,SAAS;GAC7B,SAAS;GACT,UAAU;EACZ,CAAC,CACH;EACA,KAAK,OAAO;CACd;CAEA,gBAAgC;EAC9B,OAAO;CACT;CAEA,QAA2B,SAAqC;EAC9D,MAAM,QAAQ,OAAO;EACrB,IAAI,QAAQ,IAAI,aAAa,GAC3B,KAAK,cAAc,KAAK,gBAAgB;CAE5C;CAEA,SAA4B;EAC1B,MAAM,YAAY,KAAK,cAAc;EACrC,MAAM,YAAY,KAAK,sBAAsB;EAC7C,MAAM,iBAAiB,KAAK,sBAAsB;EAElD,MAAM,gBAAgB,KAAK,cACtB,KAAK,YAAY,KAAK,WACtB,KAAK,YAAY,WAAW;EAEjC,OAAO,IAAI;;;;iBAIE,iBAAiB,KAAK,iBAAiB,QAAQ;;;YAGpD,KAAK,WAAW,IAAI,sCAAsC,KAAK,SAAS,iBAAiB,QAAQ;qCACxE,KAAK,MAAM;;;uCAGT,MAAa,EAAE,gBAAgB,EAAE;;YAE5D,KAAK,WACH,IAAI;;;;;uBAKK,KAAK,cAAc;;;;cAK5B,QAAQ;YACV,YACE,IAAI;;;;yBAIO,KAAK,YAAY,iBAAiB,iBAAiB;qBACvD,KAAK,eAAe;;8BAEX,UAAU,sBAAsB,cAAc,SAAS,IAAI,gBAAgB,QAAQ;;cAGnG,QAAQ;;;;+CAIyB,CAAC,KAAK,UAAU;;;;;;CAM7D;;gBAEyB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgS9B;YAnYG,SAAS;CAAE,MAAM;CAAS,SAAS;AAAK,CAAC,CAAA,GAAA,aAAA,WAAA,aAAA,KAAA,CAAA;YACzC,SAAS;CAAE,MAAM;CAAQ,WAAW;CAAe,SAAS;AAAK,CAAC,CAAA,GAAA,aAAA,WAAA,eAAA,KAAA,CAAA;YAClE,SAAS,EAAE,MAAM,QAAQ,CAAC,CAAA,GAAA,aAAA,WAAA,YAAA,KAAA,CAAA;YAC1B,SAAS,EAAE,MAAM,OAAO,CAAC,CAAA,GAAA,aAAA,WAAA,SAAA,KAAA,CAAA;YACzB,SAAS;CAAE,MAAM;CAAQ,WAAW;AAAY,CAAC,CAAA,GAAA,aAAA,WAAA,YAAA,KAAA,CAAA;YACjD,SAAS;CAAE,MAAM;CAAQ,WAAW;AAAqB,CAAC,CAAA,GAAA,aAAA,WAAA,qBAAA,KAAA,CAAA;YAC1D,SAAS;CAAE,MAAM;CAAQ,WAAW;CAAW,SAAS;AAAK,CAAC,CAAA,GAAA,aAAA,WAAA,WAAA,KAAA,CAAA;YAE9D,MAAM,CAAA,GAAA,aAAA,WAAA,eAAA,KAAA,CAAA;2BAVRA,kBAAc,YAAY,CAAA,GAAA,YAAA"}
|
package/dist/plots.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as SingleAxisAgeStyle, c as PlotDataSeriesOptions, d as ColourResult, f as applyAgeModification, h as readBaseColour, i as PlotSingleAxis, l as ColourMapConfig, m as parseColourScaleAttr, n as XyAgeStyle, o as SingleAxisDrawStyle, p as computeColour, r as XyDrawStyle, s as PlotDataSeries, t as PlotXyAxis, u as ColourMode } from "./xy-axis-
|
|
1
|
+
import { a as SingleAxisAgeStyle, c as PlotDataSeriesOptions, d as ColourResult, f as applyAgeModification, h as readBaseColour, i as PlotSingleAxis, l as ColourMapConfig, m as parseColourScaleAttr, n as XyAgeStyle, o as SingleAxisDrawStyle, p as computeColour, r as XyDrawStyle, s as PlotDataSeries, t as PlotXyAxis, u as ColourMode } from "./xy-axis-D9uwpGTT.js";
|
|
2
2
|
export { ColourMapConfig, ColourMode, ColourResult, PlotDataSeries, PlotDataSeriesOptions, PlotSingleAxis, PlotXyAxis, SingleAxisAgeStyle, SingleAxisDrawStyle, XyAgeStyle, XyDrawStyle, applyAgeModification, computeColour, parseColourScaleAttr, readBaseColour };
|
package/dist/plots.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as computeColour, i as applyAgeModification, n as PlotSingleAxis, o as parseColourScaleAttr, r as PlotDataSeries, s as readBaseColour, t as PlotXyAxis } from "./xy-axis-
|
|
1
|
+
import { a as computeColour, i as applyAgeModification, n as PlotSingleAxis, o as parseColourScaleAttr, r as PlotDataSeries, s as readBaseColour, t as PlotXyAxis } from "./xy-axis-C7fNxDwY.js";
|
|
2
2
|
export { PlotDataSeries, PlotSingleAxis, PlotXyAxis, applyAgeModification, computeColour, parseColourScaleAttr, readBaseColour };
|
package/dist/polar-pad.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import * as _$lit from "lit";
|
|
2
1
|
import { LitElement, PropertyValues, html } from "lit";
|
|
3
2
|
|
|
4
3
|
//#region src/polar-pad/polar-pad.d.ts
|
|
5
4
|
declare class PolarPad extends LitElement {
|
|
6
|
-
static styles:
|
|
5
|
+
static styles: import("lit").CSSResult;
|
|
7
6
|
/** Current angle in degrees. 0 = right, increases clockwise. */
|
|
8
7
|
angle: number;
|
|
9
8
|
/** Current radius 0–1. 0 = origin, 1 = edge. */
|
package/dist/polar-pad.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polar-pad.d.ts","names":[],"sources":["../src/polar-pad/polar-pad.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"polar-pad.d.ts","names":[],"sources":["../src/polar-pad/polar-pad.ts"],"mappings":";;;cAgKa,QAAA,SAAiB,UAAA;EAAA,OACZ,MAAA,gBAAM,SAAA;EAidM;EAzUA,KAAA;EAyUA;EAtUA,MAAA;;EAGA,KAAA;;EAGA,IAAA;;EAGuC,OAAA;;EAGG,UAAA;;EAGA,UAAA;;EAGD,SAAA;;EAGzB,QAAA;;EAGhB,KAAA;;EAG0B,UAAA;;EAGC,WAAA;EAAA,QAE/C,SAAA;EAAA,QACA,eAAA;EAAA,QACA,gBAAA;EAAA,QACA,YAAA;EAAA,QACA,UAAA;EAAA,QACA,WAAA;EAAA,QAMA,cAAA;EAAA,QAgBA,cAAA;EAAA,QAOA,YAAA;EAAA,QAeA,kBAAA;EAAA,QAuCA,UAAA;EAAA,QASA,QAAA;EAAA,QAIA,mBAAA;EAAA,QAiEA,WAAA;EAMC,OAAA,CAAQ,QAAA,EAAU,cAAA;EAKlB,oBAAA,CAAA;EAAA,QAUD,YAAA;EAAA,QAWA,aAAA;EAAA,QAiBA,UAAA;EAAA,QAMA,aAAA;EAUC,MAAA,CAAA,GAAU,UAAA,QAAkB,IAAA;;mBA+CpB,IAAA;AAAA;AAAA,KAOP,mBAAA;EAAA,SACD,KAAA;EAAA,SACA,MAAM;AAAA;AAAA,KAGL,kBAAA,GAAqB,WAAW,CAAC,mBAAA;AAAA,QAErC,MAAA;EAAA,UACI,qBAAA;IACR,gBAAA,EAAkB,QAAQ;EAAA;AAAA"}
|
package/dist/polar-pad.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as __decorate } from "./decorate-
|
|
1
|
+
import { n as safeCustomElement, t as __decorate } from "./decorate-O4m1U4l3.js";
|
|
2
2
|
import { LitElement, css, html, svg } from "lit";
|
|
3
|
-
import {
|
|
3
|
+
import { property } from "lit/decorators.js";
|
|
4
4
|
//#region src/polar-pad/polar-pad.ts
|
|
5
5
|
/**
|
|
6
6
|
* <ixfx-polar-pad> — circular pad for setting polar coordinates (angle + radius).
|
|
@@ -530,7 +530,7 @@ __decorate([property({
|
|
|
530
530
|
type: Number,
|
|
531
531
|
attribute: `stops-radius`
|
|
532
532
|
})], PolarPad.prototype, "stopsRadius", void 0);
|
|
533
|
-
PolarPad = __decorate([
|
|
533
|
+
PolarPad = __decorate([safeCustomElement(`ixfx-polar-pad`)], PolarPad);
|
|
534
534
|
//#endregion
|
|
535
535
|
export { PolarPad };
|
|
536
536
|
|
package/dist/polar-pad.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polar-pad.js","names":[],"sources":["../src/polar-pad/polar-pad.ts"],"sourcesContent":["import type { PropertyValues } from 'lit';\n/**\n * <ixfx-polar-pad> — circular pad for setting polar coordinates (angle + radius).\n *\n * The user clicks or drags within a circle to position a marker. The marker's\n * position encodes an angle (degrees, 0 = right, clockwise) and a radius (0–1).\n *\n * Properties / attributes\n * angle – current angle in degrees (0 = right, clockwise). Default: 0\n * radius – current radius 0–1 where 1 = edge. Default: 0.5\n * rings – number of concentric rings to draw (0 = none). Default: 0\n * rays – number of evenly-spaced radial spokes to draw (0 = none). Default: 0\n * show-ray – draw a line from the origin to the marker\n * show-origin – draw a dot at the centre\n * hide-cursor – hide cursor during drag and hover (default: false)\n * snap-value – when set, marker snaps to nearest ring/spoke depending on what's displayed\n * disabled – disable all interaction (default: false)\n *\n * Customisable CSS variables:\n *\n * Pad background\n * --pad-background – CSS `background` of the circular pad. Accepts any CSS background\n * value: solid colour, conic-gradient(), radial-gradient(), etc.\n * Dynamic CSS vars like --angle-deg / --radius-pct are available\n * so the gradient can track the current marker position.\n * Default: var(--surface-4)\n * --pad-border-color – stroke of the outer circle (default: --surface-6)\n * --pad-border-width – thickness of outer border (default: 1px)\n *\n * Marker\n * --marker-size – diameter of the draggable marker (default: 10cqb)\n * --marker-color – fill colour of the marker (default: --accent)\n * --marker-opacity – opacity of the marker (default: 1)\n * --marker-stroke – stroke colour of the marker (default: none)\n * --marker-stroke-width – stroke thickness of the marker (default: 0)\n *\n * Origin dot (show-origin)\n * --origin-size – diameter of the origin dot (default: 6cqb)\n * --origin-color – fill colour of the origin dot (default: --accent)\n * --origin-opacity – opacity of the origin dot (default: 1)\n *\n * Ray line (show-ray)\n * --ray-color – stroke colour (default: --surface-6)\n * --ray-width – thickness (default: 2px)\n * --ray-opacity – opacity (default: 1)\n * --ray-dash – stroke-dasharray value e.g. \"4 2\" (default: none)\n *\n * Concentric rings (rings > 0)\n * --ring-color – stroke colour (default: --surface-6)\n * --ring-width – thickness (default: 1px)\n * --ring-opacity – opacity (default: 1)\n * --ring-dash – stroke-dasharray e.g. \"4 2\" (default: none)\n *\n * Radial spokes (rays > 0)\n * --spoke-color – stroke colour (default: --surface-6)\n * --spoke-width – thickness (default: 1px)\n * --spoke-opacity – opacity (default: 1)\n * --spoke-dash – stroke-dasharray e.g. \"4 2\" (default: none)\n *\n * CSS variables set on host for external dynamic styling:\n * --angle-deg – current angle as unitless number in degrees\n * --angle-rad – current angle as unitless number in radians\n * --radius-pct – current radius as unitless number 0–100\n *\n * Events\n * input – CustomEvent<PolarPadInputDetail> { angle: number (deg), radius: number (0–1) }\n * bubbles + composed, fires continuously during drag\n * change – CustomEvent<PolarPadInputDetail> { angle: number (deg), radius: number (0–1) }\n * bubbles + composed, fires when drag ends\n */\nimport { css, html, LitElement, svg } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { KEY_STEP_DIVISOR } from '../keyboard.js';\n\n// ---------------------------------------------------------------------------\n// Geometry helpers\n// ---------------------------------------------------------------------------\n\nconst DEG_TO_RAD = Math.PI / 180;\nconst RAD_TO_DEG = 180 / Math.PI;\n\n/**\n * Convert polar (angle in radians, radius 0-1) to SVG coordinates.\n * SVG viewBox 0 0 100 100; origin at (50,50); full radius = 50.\n * Convention: 0 rad = right (+x), increases CLOCKWISE (+y = downward in SVG).\n */\nfunction polarToSvg(angleRad: number, radius: number): { x: number; y: number } {\n const r = radius * 50;\n return { x: 50 + Math.cos(angleRad) * r, y: 50 + Math.sin(angleRad) * r };\n}\n\n/**\n * Convert SVG coordinates back to polar (angle in radians 0..2π, radius 0-1).\n * SVG: Y increases downward. Convention: 0=right, CW positive.\n */\nfunction svgToPolar(svgX: number, svgY: number): { angleRad: number; radius: number } {\n const dx = svgX - 50;\n const dy = svgY - 50; // +dy = downward = clockwise\n const dist = Math.sqrt(dx * dx + dy * dy);\n const radius = Math.min(1, dist / 50);\n const raw = Math.atan2(dy, dx);\n const angleRad = ((raw % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI);\n return { angleRad, radius };\n}\n\nconst clamp01 = (v: number): number => Math.max(0, Math.min(1, v));\n\n// ---------------------------------------------------------------------------\n// Direction-aware snapping helpers\n// ---------------------------------------------------------------------------\n\nfunction snapAngle(angleDeg: number, prevAngleDeg: number, rays: number, snapEnabled: boolean): number {\n if (rays <= 0 || !snapEnabled) return angleDeg;\n const spokeDeg = 360 / rays;\n const normalized = ((angleDeg % 360) + 360) % 360;\n const nearest = Math.round(normalized / spokeDeg) * spokeDeg;\n const remainder = normalized % spokeDeg;\n const tie = Math.abs(remainder) < 0.0001 || Math.abs(spokeDeg - remainder) < 0.0001;\n if (tie) {\n let delta = angleDeg - prevAngleDeg;\n if (delta > 180) delta -= 360;\n if (delta < -180) delta += 360;\n const direction = delta >= 0 ? 1 : -1;\n return (nearest + direction * spokeDeg + 360) % 360;\n }\n return nearest;\n}\n\nfunction snapRadius(radius: number, prevRadius: number, rings: number, snapEnabled: boolean): number {\n if (rings <= 0 || !snapEnabled) return radius;\n const ringStep = 1 / rings;\n const nearest = Math.round(radius / ringStep) * ringStep;\n const remainder = radius % ringStep;\n const tie = Math.abs(remainder) < 0.0001 || Math.abs(ringStep - remainder) < 0.0001;\n if (tie) {\n const direction = radius >= prevRadius ? 1 : -1;\n return Math.max(0, Math.min(1, nearest + direction * ringStep));\n }\n return nearest;\n}\n\nfunction quantiseAngle(angleDeg: number, stops?: number): number {\n if (!stops || stops <= 1) return angleDeg;\n const stepDeg = 360 / stops;\n const normalized = ((angleDeg % 360) + 360) % 360;\n return Math.round(normalized / stepDeg) * stepDeg;\n}\n\nfunction quantiseRadius(radius: number, stops?: number): number {\n if (!stops || stops <= 1) return radius;\n const step = 1 / stops;\n return Math.round(radius / step) * step;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n@customElement(`ixfx-polar-pad`)\nexport class PolarPad extends LitElement {\n static override styles = css`\n :host {\n display: block;\n width: 200px;\n height: 200px;\n touch-action: none;\n user-select: none;\n container-type: size;\n\n /* Pad background */\n --pad-background: var(--surface-4, oklch(22% 0.02 240));\n --pad-border-color: var(--surface-6, oklch(35% 0.02 240));\n --pad-border-width: 1px;\n\n /* Marker */\n --marker-size: 10cqb;\n --marker-color: var(--accent, oklch(60% 0.15 140));\n --marker-opacity: 1;\n --marker-stroke: none;\n --marker-stroke-width: 0;\n\n /* Origin dot */\n --origin-size: 6cqb;\n --origin-color: var(--accent, oklch(60% 0.15 140));\n --origin-opacity: 1;\n\n /* Ray line */\n --ray-color: var(--surface-6, oklch(35% 0.02 240));\n --ray-width: 2px;\n --ray-opacity: 1;\n --ray-dash: none;\n\n /* Concentric rings */\n --ring-color: var(--surface-6, oklch(35% 0.02 240));\n --ring-width: 1px;\n --ring-opacity: 1;\n --ring-dash: none;\n\n /* Radial spokes */\n --spoke-color: var(--surface-6, oklch(35% 0.02 240));\n --spoke-width: 1px;\n --spoke-opacity: 1;\n --spoke-dash: none;\n }\n\n :host([disabled]) {\n opacity: 0.5;\n pointer-events: none;\n }\n\n .polar-pad-area {\n position: relative;\n width: 100%;\n height: 100%;\n cursor: var(--cursor-display, crosshair);\n }\n\n :host([dragging]) .polar-pad-area {\n cursor: none;\n }\n\n svg {\n width: 100%;\n height: 100%;\n overflow: visible;\n }\n\n .pad-background {\n /* Used on the foreignObject div — accepts any CSS background value */\n width: 100%;\n height: 100%;\n background: var(--pad-background);\n }\n\n .pad-border {\n fill: none;\n stroke: var(--pad-border-color);\n stroke-width: var(--pad-border-width);\n vector-effect: non-scaling-stroke;\n }\n\n .ring {\n fill: none;\n stroke: var(--ring-color);\n stroke-width: var(--ring-width);\n stroke-dasharray: var(--ring-dash);\n opacity: var(--ring-opacity);\n vector-effect: non-scaling-stroke;\n }\n\n .spoke {\n fill: none;\n stroke: var(--spoke-color);\n stroke-width: var(--spoke-width);\n stroke-dasharray: var(--spoke-dash);\n opacity: var(--spoke-opacity);\n vector-effect: non-scaling-stroke;\n }\n\n .ray {\n fill: none;\n stroke: var(--ray-color);\n stroke-width: var(--ray-width);\n stroke-dasharray: var(--ray-dash);\n opacity: var(--ray-opacity);\n vector-effect: non-scaling-stroke;\n }\n\n .origin-dot {\n fill: var(--origin-color);\n opacity: var(--origin-opacity);\n }\n\n .marker {\n fill: var(--marker-color);\n opacity: var(--marker-opacity);\n stroke: var(--marker-stroke);\n stroke-width: var(--marker-stroke-width);\n cursor: grab;\n }\n\n .marker:active {\n cursor: grabbing;\n }\n\n svg:focus {\n outline: none;\n }\n\n svg:focus-visible .pad-border {\n stroke: var(--accent);\n stroke-width: 3;\n }\n `;\n\n /** Current angle in degrees. 0 = right, increases clockwise. */\n @property({ type: Number }) angle = 0;\n\n /** Current radius 0–1. 0 = origin, 1 = edge. */\n @property({ type: Number }) radius = 0.5;\n\n /** Number of concentric rings to display. 0 = none. */\n @property({ type: Number }) rings = 0;\n\n /** Number of evenly-spaced radial spoke lines to display. 0 = none. */\n @property({ type: Number }) rays = 0;\n\n /** Show a line from origin to the marker. */\n @property({ type: Boolean, reflect: true, attribute: `show-ray` }) showRay = false;\n\n /** Show a dot at the origin (centre). */\n @property({ type: Boolean, reflect: true, attribute: `show-origin` }) showOrigin = false;\n\n /** Hide cursor during drag and hover. */\n @property({ type: Boolean, reflect: true, attribute: `hide-cursor` }) hideCursor = false;\n\n /** When set, marker snaps to nearest ring/spoke depending on what's displayed. */\n @property({ type: Boolean, attribute: `snap-value`, reflect: true }) snapValue = false;\n\n /** Disable all interaction (pointer and keyboard). */\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Number of quantised stops for both angle and radius. Overridden by stops-angle/stops-radius if set. */\n @property({ type: Number }) stops?: number;\n\n /** Number of quantised stops for angle. If set, overrides the stops setting for angle. */\n @property({ type: Number, attribute: `stops-angle` }) stopsAngle?: number;\n\n /** Number of quantised stops for radius. If set, overrides the stops setting for radius. */\n @property({ type: Number, attribute: `stops-radius` }) stopsRadius?: number;\n\n private _dragging = false;\n private _dragStartAngle = 0;\n private _dragStartRadius = 0;\n private _pressedKeys = new Set<string>();\n private _prevAngle = 0;\n private _prevRadius = 0;\n\n // -------------------------------------------------------------------------\n // Pointer handling\n // -------------------------------------------------------------------------\n\n private _onPointerDown = (e: PointerEvent): void => {\n e.preventDefault();\n const svg = this.renderRoot.querySelector(`svg`) as SVGSVGElement | undefined;\n (svg as HTMLElement | undefined)?.focus();\n const area = this.renderRoot.querySelector(`.polar-pad-area`) as HTMLElement | undefined;\n if (area)\n area.setPointerCapture(e.pointerId);\n this._dragging = true;\n this._dragStartAngle = this.angle;\n this._dragStartRadius = this.radius;\n this.setAttribute(`dragging`, ``);\n this._updateFromPointer(e);\n globalThis.addEventListener(`pointermove`, this._onPointerMove);\n globalThis.addEventListener(`pointerup`, this._onPointerUp);\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (!this._dragging)\n return;\n e.preventDefault();\n this._updateFromPointer(e);\n };\n\n private _onPointerUp = (): void => {\n const hasChanged = this.angle !== this._dragStartAngle || this.radius !== this._dragStartRadius;\n this._dragging = false;\n this.removeAttribute(`dragging`);\n globalThis.removeEventListener(`pointermove`, this._onPointerMove);\n globalThis.removeEventListener(`pointerup`, this._onPointerUp);\n if (hasChanged) {\n this.dispatchEvent(new CustomEvent<PolarPadInputDetail>(`change`, {\n detail: { angle: this.angle, radius: this.radius },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n private _updateFromPointer(e: PointerEvent): void {\n const area = this.renderRoot.querySelector(`.polar-pad-area`);\n if (!area)\n return;\n\n const rect = area.getBoundingClientRect();\n const size = Math.min(rect.width, rect.height);\n const svgX = ((e.clientX - rect.left) / size) * 100;\n const svgY = ((e.clientY - rect.top) / size) * 100;\n\n const { angleRad, radius } = svgToPolar(svgX, svgY);\n const newAngleDeg = angleRad * RAD_TO_DEG;\n const newRadius = clamp01(radius);\n\n this._prevAngle = this.angle;\n this._prevRadius = this.radius;\n\n const snappedAngle = snapAngle(newAngleDeg, this._prevAngle, this.rays, this.snapValue);\n const snappedRadius = snapRadius(newRadius, this._prevRadius, this.rings, this.snapValue);\n\n const effectiveStopsAngle = this.stopsAngle ?? this.stops;\n const effectiveStopsRadius = this.stopsRadius ?? this.stops;\n\n this.angle = quantiseAngle(snappedAngle, effectiveStopsAngle);\n this.radius = quantiseRadius(snappedRadius, effectiveStopsRadius);\n this._prevAngle = newAngleDeg;\n this._prevRadius = newRadius;\n\n this.dispatchEvent(new CustomEvent<PolarPadInputDetail>(`input`, {\n detail: { angle: this.angle, radius: this.radius },\n bubbles: true,\n composed: true,\n }));\n }\n\n // -------------------------------------------------------------------------\n // Keyboard handling\n // -------------------------------------------------------------------------\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (this.disabled) return;\n if ([`ArrowLeft`, `ArrowRight`, `ArrowUp`, `ArrowDown`].includes(e.key)) {\n e.preventDefault();\n this._pressedKeys.add(e.key);\n this._handleKeyboardMove(e.shiftKey);\n }\n };\n\n private _onKeyUp = (e: KeyboardEvent): void => {\n this._pressedKeys.delete(e.key);\n };\n\n private _handleKeyboardMove = (shiftKey: boolean): void => {\n const shiftDivisor = shiftKey ? KEY_STEP_DIVISOR : 1;\n const effectiveStopsAngle = this.stopsAngle ?? this.stops;\n const effectiveStopsRadius = this.stopsRadius ?? this.stops;\n\n let angleStep: number;\n if (effectiveStopsAngle && effectiveStopsAngle > 1) {\n angleStep = 360 / effectiveStopsAngle;\n } else {\n const angleRange = this.rays > 0 && this.snapValue ? this.rays : 20;\n angleStep = 360 / angleRange;\n }\n\n let radiusStep: number;\n if (effectiveStopsRadius && effectiveStopsRadius > 1) {\n radiusStep = 1 / effectiveStopsRadius;\n } else {\n radiusStep = 1 / 20;\n }\n\n angleStep /= shiftDivisor;\n radiusStep /= shiftDivisor;\n\n this._prevAngle = this.angle;\n this._prevRadius = this.radius;\n\n let newAngle = this.angle;\n let newRadius = this.radius;\n\n if (this._pressedKeys.has(`ArrowLeft`)) {\n newAngle -= angleStep;\n }\n if (this._pressedKeys.has(`ArrowRight`)) {\n newAngle += angleStep;\n }\n if (this._pressedKeys.has(`ArrowUp`)) {\n newRadius = Math.min(1, newRadius + radiusStep);\n }\n if (this._pressedKeys.has(`ArrowDown`)) {\n newRadius = Math.max(0, newRadius - radiusStep);\n }\n\n newAngle = ((newAngle % 360) + 360) % 360;\n\n let finalAngle = snapAngle(newAngle, this._prevAngle, this.rays, this.snapValue);\n let finalRadius = snapRadius(newRadius, this._prevRadius, this.rings, this.snapValue);\n\n finalAngle = quantiseAngle(finalAngle, effectiveStopsAngle);\n finalRadius = quantiseRadius(finalRadius, effectiveStopsRadius);\n\n if (finalAngle !== this.angle || finalRadius !== this.radius) {\n this.angle = finalAngle;\n this.radius = finalRadius;\n this.dispatchEvent(new CustomEvent<PolarPadInputDetail>(`input`, {\n detail: { angle: this.angle, radius: this.radius },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n // -------------------------------------------------------------------------\n // CSS variable sync\n // -------------------------------------------------------------------------\n\n private _setCssVars(): void {\n this.style.setProperty(`--angle-deg`, `${this.angle}`);\n this.style.setProperty(`--angle-rad`, `${this.angle * DEG_TO_RAD}`);\n this.style.setProperty(`--radius-pct`, `${clamp01(this.radius) * 100}`);\n }\n\n override updated(_changed: PropertyValues): void {\n super.updated(_changed);\n this._setCssVars();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._onPointerUp();\n this._pressedKeys.clear();\n }\n\n // -------------------------------------------------------------------------\n // SVG helpers\n // -------------------------------------------------------------------------\n\n private _renderRings() {\n if (this.rings <= 0)\n return ``;\n const items = [];\n for (let i = 1; i <= this.rings; i++) {\n const r = (i / this.rings) * 50;\n items.push(svg`<circle class=\"ring\" cx=\"50\" cy=\"50\" r=\"${r}\" />`);\n }\n return items;\n }\n\n private _renderSpokes() {\n if (this.rays <= 0)\n return ``;\n const items = [];\n for (let i = 0; i < this.rays; i++) {\n const angleRad = (i / this.rays) * 2 * Math.PI;\n const cos = Math.cos(angleRad);\n const sin = Math.sin(angleRad); // SVG +y downward matches CW convention directly\n const x1 = 50 + cos * 50;\n const y1 = 50 + sin * 50;\n const x2 = 50 - cos * 50;\n const y2 = 50 - sin * 50;\n items.push(svg`<line class=\"spoke\" x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" />`);\n }\n return items;\n }\n\n private _renderRay(markerX: number, markerY: number) {\n if (!this.showRay)\n return ``;\n return svg`<line class=\"ray\" x1=\"50\" y1=\"50\" x2=\"${markerX}\" y2=\"${markerY}\" />`;\n }\n\n private _renderOrigin() {\n if (!this.showOrigin)\n return ``;\n return svg`<circle class=\"origin-dot\" cx=\"50\" cy=\"50\" r=\"3\" style=\"r: calc(var(--origin-size) / 2)\" />`;\n }\n\n // -------------------------------------------------------------------------\n // Render\n // -------------------------------------------------------------------------\n\n override render(): ReturnType<typeof html> {\n const angleRad = this.angle * DEG_TO_RAD;\n const { x: markerX, y: markerY } = polarToSvg(angleRad, clamp01(this.radius));\n\n return html`\n <div class=\"polar-pad-area\"\n @pointerdown=${this._onPointerDown}\n @keydown=${this._onKeyDown}\n @keyup=${this._onKeyUp}\n @blur=${() => this._pressedKeys.clear()}>\n <svg viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"xMidYMid meet\"\n tabindex=${this.disabled ? -1 : 0}>\n <defs>\n <clipPath id=\"circle-clip-${this._uid}\">\n <circle cx=\"50\" cy=\"50\" r=\"50\" />\n </clipPath>\n </defs>\n\n <!-- clipped group: background + rings + spokes -->\n <g clip-path=\"url(#circle-clip-${this._uid})\">\n <foreignObject x=\"0\" y=\"0\" width=\"100\" height=\"100\">\n <div class=\"pad-background\" xmlns=\"http://www.w3.org/1999/xhtml\"></div>\n </foreignObject>\n ${this._renderRings()}\n ${this._renderSpokes()}\n </g>\n\n <!-- border circle (on top of clip, non-scaling stroke) -->\n <circle class=\"pad-border\" cx=\"50\" cy=\"50\" r=\"49.75\" />\n\n <!-- ray + origin + marker -->\n ${this._renderRay(markerX, markerY)}\n ${this._renderOrigin()}\n <circle\n class=\"marker\"\n cx=\"${markerX}\"\n cy=\"${markerY}\"\n r=\"5\"\n style=\"r: calc(var(--marker-size) / 2)\"\n />\n </svg>\n </div>\n `;\n }\n\n /** Stable per-instance uid for SVG clipPath IDs. */\n private readonly _uid = Math.random().toString(36).slice(2, 8);\n}\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type PolarPadInputDetail = {\n readonly angle: number; // degrees, 0 = right, clockwise\n readonly radius: number; // 0–1\n};\n\nexport type PolarPadInputEvent = CustomEvent<PolarPadInputDetail>;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-polar-pad': PolarPad;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"polar-pad.js","names":["customElement"],"sources":["../src/polar-pad/polar-pad.ts"],"sourcesContent":["import type { PropertyValues } from 'lit';\n/**\n * <ixfx-polar-pad> — circular pad for setting polar coordinates (angle + radius).\n *\n * The user clicks or drags within a circle to position a marker. The marker's\n * position encodes an angle (degrees, 0 = right, clockwise) and a radius (0–1).\n *\n * Properties / attributes\n * angle – current angle in degrees (0 = right, clockwise). Default: 0\n * radius – current radius 0–1 where 1 = edge. Default: 0.5\n * rings – number of concentric rings to draw (0 = none). Default: 0\n * rays – number of evenly-spaced radial spokes to draw (0 = none). Default: 0\n * show-ray – draw a line from the origin to the marker\n * show-origin – draw a dot at the centre\n * hide-cursor – hide cursor during drag and hover (default: false)\n * snap-value – when set, marker snaps to nearest ring/spoke depending on what's displayed\n * disabled – disable all interaction (default: false)\n *\n * Customisable CSS variables:\n *\n * Pad background\n * --pad-background – CSS `background` of the circular pad. Accepts any CSS background\n * value: solid colour, conic-gradient(), radial-gradient(), etc.\n * Dynamic CSS vars like --angle-deg / --radius-pct are available\n * so the gradient can track the current marker position.\n * Default: var(--surface-4)\n * --pad-border-color – stroke of the outer circle (default: --surface-6)\n * --pad-border-width – thickness of outer border (default: 1px)\n *\n * Marker\n * --marker-size – diameter of the draggable marker (default: 10cqb)\n * --marker-color – fill colour of the marker (default: --accent)\n * --marker-opacity – opacity of the marker (default: 1)\n * --marker-stroke – stroke colour of the marker (default: none)\n * --marker-stroke-width – stroke thickness of the marker (default: 0)\n *\n * Origin dot (show-origin)\n * --origin-size – diameter of the origin dot (default: 6cqb)\n * --origin-color – fill colour of the origin dot (default: --accent)\n * --origin-opacity – opacity of the origin dot (default: 1)\n *\n * Ray line (show-ray)\n * --ray-color – stroke colour (default: --surface-6)\n * --ray-width – thickness (default: 2px)\n * --ray-opacity – opacity (default: 1)\n * --ray-dash – stroke-dasharray value e.g. \"4 2\" (default: none)\n *\n * Concentric rings (rings > 0)\n * --ring-color – stroke colour (default: --surface-6)\n * --ring-width – thickness (default: 1px)\n * --ring-opacity – opacity (default: 1)\n * --ring-dash – stroke-dasharray e.g. \"4 2\" (default: none)\n *\n * Radial spokes (rays > 0)\n * --spoke-color – stroke colour (default: --surface-6)\n * --spoke-width – thickness (default: 1px)\n * --spoke-opacity – opacity (default: 1)\n * --spoke-dash – stroke-dasharray e.g. \"4 2\" (default: none)\n *\n * CSS variables set on host for external dynamic styling:\n * --angle-deg – current angle as unitless number in degrees\n * --angle-rad – current angle as unitless number in radians\n * --radius-pct – current radius as unitless number 0–100\n *\n * Events\n * input – CustomEvent<PolarPadInputDetail> { angle: number (deg), radius: number (0–1) }\n * bubbles + composed, fires continuously during drag\n * change – CustomEvent<PolarPadInputDetail> { angle: number (deg), radius: number (0–1) }\n * bubbles + composed, fires when drag ends\n */\nimport { css, html, LitElement, svg } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { KEY_STEP_DIVISOR } from '../keyboard.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\n// ---------------------------------------------------------------------------\n// Geometry helpers\n// ---------------------------------------------------------------------------\n\nconst DEG_TO_RAD = Math.PI / 180;\nconst RAD_TO_DEG = 180 / Math.PI;\n\n/**\n * Convert polar (angle in radians, radius 0-1) to SVG coordinates.\n * SVG viewBox 0 0 100 100; origin at (50,50); full radius = 50.\n * Convention: 0 rad = right (+x), increases CLOCKWISE (+y = downward in SVG).\n */\nfunction polarToSvg(angleRad: number, radius: number): { x: number; y: number } {\n const r = radius * 50;\n return { x: 50 + Math.cos(angleRad) * r, y: 50 + Math.sin(angleRad) * r };\n}\n\n/**\n * Convert SVG coordinates back to polar (angle in radians 0..2π, radius 0-1).\n * SVG: Y increases downward. Convention: 0=right, CW positive.\n */\nfunction svgToPolar(svgX: number, svgY: number): { angleRad: number; radius: number } {\n const dx = svgX - 50;\n const dy = svgY - 50; // +dy = downward = clockwise\n const dist = Math.sqrt(dx * dx + dy * dy);\n const radius = Math.min(1, dist / 50);\n const raw = Math.atan2(dy, dx);\n const angleRad = ((raw % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI);\n return { angleRad, radius };\n}\n\nconst clamp01 = (v: number): number => Math.max(0, Math.min(1, v));\n\n// ---------------------------------------------------------------------------\n// Direction-aware snapping helpers\n// ---------------------------------------------------------------------------\n\nfunction snapAngle(angleDeg: number, prevAngleDeg: number, rays: number, snapEnabled: boolean): number {\n if (rays <= 0 || !snapEnabled) return angleDeg;\n const spokeDeg = 360 / rays;\n const normalized = ((angleDeg % 360) + 360) % 360;\n const nearest = Math.round(normalized / spokeDeg) * spokeDeg;\n const remainder = normalized % spokeDeg;\n const tie = Math.abs(remainder) < 0.0001 || Math.abs(spokeDeg - remainder) < 0.0001;\n if (tie) {\n let delta = angleDeg - prevAngleDeg;\n if (delta > 180) delta -= 360;\n if (delta < -180) delta += 360;\n const direction = delta >= 0 ? 1 : -1;\n return (nearest + direction * spokeDeg + 360) % 360;\n }\n return nearest;\n}\n\nfunction snapRadius(radius: number, prevRadius: number, rings: number, snapEnabled: boolean): number {\n if (rings <= 0 || !snapEnabled) return radius;\n const ringStep = 1 / rings;\n const nearest = Math.round(radius / ringStep) * ringStep;\n const remainder = radius % ringStep;\n const tie = Math.abs(remainder) < 0.0001 || Math.abs(ringStep - remainder) < 0.0001;\n if (tie) {\n const direction = radius >= prevRadius ? 1 : -1;\n return Math.max(0, Math.min(1, nearest + direction * ringStep));\n }\n return nearest;\n}\n\nfunction quantiseAngle(angleDeg: number, stops?: number): number {\n if (!stops || stops <= 1) return angleDeg;\n const stepDeg = 360 / stops;\n const normalized = ((angleDeg % 360) + 360) % 360;\n return Math.round(normalized / stepDeg) * stepDeg;\n}\n\nfunction quantiseRadius(radius: number, stops?: number): number {\n if (!stops || stops <= 1) return radius;\n const step = 1 / stops;\n return Math.round(radius / step) * step;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n@customElement(`ixfx-polar-pad`)\nexport class PolarPad extends LitElement {\n static override styles = css`\n :host {\n display: block;\n width: 200px;\n height: 200px;\n touch-action: none;\n user-select: none;\n container-type: size;\n\n /* Pad background */\n --pad-background: var(--surface-4, oklch(22% 0.02 240));\n --pad-border-color: var(--surface-6, oklch(35% 0.02 240));\n --pad-border-width: 1px;\n\n /* Marker */\n --marker-size: 10cqb;\n --marker-color: var(--accent, oklch(60% 0.15 140));\n --marker-opacity: 1;\n --marker-stroke: none;\n --marker-stroke-width: 0;\n\n /* Origin dot */\n --origin-size: 6cqb;\n --origin-color: var(--accent, oklch(60% 0.15 140));\n --origin-opacity: 1;\n\n /* Ray line */\n --ray-color: var(--surface-6, oklch(35% 0.02 240));\n --ray-width: 2px;\n --ray-opacity: 1;\n --ray-dash: none;\n\n /* Concentric rings */\n --ring-color: var(--surface-6, oklch(35% 0.02 240));\n --ring-width: 1px;\n --ring-opacity: 1;\n --ring-dash: none;\n\n /* Radial spokes */\n --spoke-color: var(--surface-6, oklch(35% 0.02 240));\n --spoke-width: 1px;\n --spoke-opacity: 1;\n --spoke-dash: none;\n }\n\n :host([disabled]) {\n opacity: 0.5;\n pointer-events: none;\n }\n\n .polar-pad-area {\n position: relative;\n width: 100%;\n height: 100%;\n cursor: var(--cursor-display, crosshair);\n }\n\n :host([dragging]) .polar-pad-area {\n cursor: none;\n }\n\n svg {\n width: 100%;\n height: 100%;\n overflow: visible;\n }\n\n .pad-background {\n /* Used on the foreignObject div — accepts any CSS background value */\n width: 100%;\n height: 100%;\n background: var(--pad-background);\n }\n\n .pad-border {\n fill: none;\n stroke: var(--pad-border-color);\n stroke-width: var(--pad-border-width);\n vector-effect: non-scaling-stroke;\n }\n\n .ring {\n fill: none;\n stroke: var(--ring-color);\n stroke-width: var(--ring-width);\n stroke-dasharray: var(--ring-dash);\n opacity: var(--ring-opacity);\n vector-effect: non-scaling-stroke;\n }\n\n .spoke {\n fill: none;\n stroke: var(--spoke-color);\n stroke-width: var(--spoke-width);\n stroke-dasharray: var(--spoke-dash);\n opacity: var(--spoke-opacity);\n vector-effect: non-scaling-stroke;\n }\n\n .ray {\n fill: none;\n stroke: var(--ray-color);\n stroke-width: var(--ray-width);\n stroke-dasharray: var(--ray-dash);\n opacity: var(--ray-opacity);\n vector-effect: non-scaling-stroke;\n }\n\n .origin-dot {\n fill: var(--origin-color);\n opacity: var(--origin-opacity);\n }\n\n .marker {\n fill: var(--marker-color);\n opacity: var(--marker-opacity);\n stroke: var(--marker-stroke);\n stroke-width: var(--marker-stroke-width);\n cursor: grab;\n }\n\n .marker:active {\n cursor: grabbing;\n }\n\n svg:focus {\n outline: none;\n }\n\n svg:focus-visible .pad-border {\n stroke: var(--accent);\n stroke-width: 3;\n }\n `;\n\n /** Current angle in degrees. 0 = right, increases clockwise. */\n @property({ type: Number }) angle = 0;\n\n /** Current radius 0–1. 0 = origin, 1 = edge. */\n @property({ type: Number }) radius = 0.5;\n\n /** Number of concentric rings to display. 0 = none. */\n @property({ type: Number }) rings = 0;\n\n /** Number of evenly-spaced radial spoke lines to display. 0 = none. */\n @property({ type: Number }) rays = 0;\n\n /** Show a line from origin to the marker. */\n @property({ type: Boolean, reflect: true, attribute: `show-ray` }) showRay = false;\n\n /** Show a dot at the origin (centre). */\n @property({ type: Boolean, reflect: true, attribute: `show-origin` }) showOrigin = false;\n\n /** Hide cursor during drag and hover. */\n @property({ type: Boolean, reflect: true, attribute: `hide-cursor` }) hideCursor = false;\n\n /** When set, marker snaps to nearest ring/spoke depending on what's displayed. */\n @property({ type: Boolean, attribute: `snap-value`, reflect: true }) snapValue = false;\n\n /** Disable all interaction (pointer and keyboard). */\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Number of quantised stops for both angle and radius. Overridden by stops-angle/stops-radius if set. */\n @property({ type: Number }) stops?: number;\n\n /** Number of quantised stops for angle. If set, overrides the stops setting for angle. */\n @property({ type: Number, attribute: `stops-angle` }) stopsAngle?: number;\n\n /** Number of quantised stops for radius. If set, overrides the stops setting for radius. */\n @property({ type: Number, attribute: `stops-radius` }) stopsRadius?: number;\n\n private _dragging = false;\n private _dragStartAngle = 0;\n private _dragStartRadius = 0;\n private _pressedKeys = new Set<string>();\n private _prevAngle = 0;\n private _prevRadius = 0;\n\n // -------------------------------------------------------------------------\n // Pointer handling\n // -------------------------------------------------------------------------\n\n private _onPointerDown = (e: PointerEvent): void => {\n e.preventDefault();\n const svg = this.renderRoot.querySelector(`svg`) as SVGSVGElement | undefined;\n (svg as HTMLElement | undefined)?.focus();\n const area = this.renderRoot.querySelector(`.polar-pad-area`) as HTMLElement | undefined;\n if (area)\n area.setPointerCapture(e.pointerId);\n this._dragging = true;\n this._dragStartAngle = this.angle;\n this._dragStartRadius = this.radius;\n this.setAttribute(`dragging`, ``);\n this._updateFromPointer(e);\n globalThis.addEventListener(`pointermove`, this._onPointerMove);\n globalThis.addEventListener(`pointerup`, this._onPointerUp);\n };\n\n private _onPointerMove = (e: PointerEvent): void => {\n if (!this._dragging)\n return;\n e.preventDefault();\n this._updateFromPointer(e);\n };\n\n private _onPointerUp = (): void => {\n const hasChanged = this.angle !== this._dragStartAngle || this.radius !== this._dragStartRadius;\n this._dragging = false;\n this.removeAttribute(`dragging`);\n globalThis.removeEventListener(`pointermove`, this._onPointerMove);\n globalThis.removeEventListener(`pointerup`, this._onPointerUp);\n if (hasChanged) {\n this.dispatchEvent(new CustomEvent<PolarPadInputDetail>(`change`, {\n detail: { angle: this.angle, radius: this.radius },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n private _updateFromPointer(e: PointerEvent): void {\n const area = this.renderRoot.querySelector(`.polar-pad-area`);\n if (!area)\n return;\n\n const rect = area.getBoundingClientRect();\n const size = Math.min(rect.width, rect.height);\n const svgX = ((e.clientX - rect.left) / size) * 100;\n const svgY = ((e.clientY - rect.top) / size) * 100;\n\n const { angleRad, radius } = svgToPolar(svgX, svgY);\n const newAngleDeg = angleRad * RAD_TO_DEG;\n const newRadius = clamp01(radius);\n\n this._prevAngle = this.angle;\n this._prevRadius = this.radius;\n\n const snappedAngle = snapAngle(newAngleDeg, this._prevAngle, this.rays, this.snapValue);\n const snappedRadius = snapRadius(newRadius, this._prevRadius, this.rings, this.snapValue);\n\n const effectiveStopsAngle = this.stopsAngle ?? this.stops;\n const effectiveStopsRadius = this.stopsRadius ?? this.stops;\n\n this.angle = quantiseAngle(snappedAngle, effectiveStopsAngle);\n this.radius = quantiseRadius(snappedRadius, effectiveStopsRadius);\n this._prevAngle = newAngleDeg;\n this._prevRadius = newRadius;\n\n this.dispatchEvent(new CustomEvent<PolarPadInputDetail>(`input`, {\n detail: { angle: this.angle, radius: this.radius },\n bubbles: true,\n composed: true,\n }));\n }\n\n // -------------------------------------------------------------------------\n // Keyboard handling\n // -------------------------------------------------------------------------\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (this.disabled) return;\n if ([`ArrowLeft`, `ArrowRight`, `ArrowUp`, `ArrowDown`].includes(e.key)) {\n e.preventDefault();\n this._pressedKeys.add(e.key);\n this._handleKeyboardMove(e.shiftKey);\n }\n };\n\n private _onKeyUp = (e: KeyboardEvent): void => {\n this._pressedKeys.delete(e.key);\n };\n\n private _handleKeyboardMove = (shiftKey: boolean): void => {\n const shiftDivisor = shiftKey ? KEY_STEP_DIVISOR : 1;\n const effectiveStopsAngle = this.stopsAngle ?? this.stops;\n const effectiveStopsRadius = this.stopsRadius ?? this.stops;\n\n let angleStep: number;\n if (effectiveStopsAngle && effectiveStopsAngle > 1) {\n angleStep = 360 / effectiveStopsAngle;\n } else {\n const angleRange = this.rays > 0 && this.snapValue ? this.rays : 20;\n angleStep = 360 / angleRange;\n }\n\n let radiusStep: number;\n if (effectiveStopsRadius && effectiveStopsRadius > 1) {\n radiusStep = 1 / effectiveStopsRadius;\n } else {\n radiusStep = 1 / 20;\n }\n\n angleStep /= shiftDivisor;\n radiusStep /= shiftDivisor;\n\n this._prevAngle = this.angle;\n this._prevRadius = this.radius;\n\n let newAngle = this.angle;\n let newRadius = this.radius;\n\n if (this._pressedKeys.has(`ArrowLeft`)) {\n newAngle -= angleStep;\n }\n if (this._pressedKeys.has(`ArrowRight`)) {\n newAngle += angleStep;\n }\n if (this._pressedKeys.has(`ArrowUp`)) {\n newRadius = Math.min(1, newRadius + radiusStep);\n }\n if (this._pressedKeys.has(`ArrowDown`)) {\n newRadius = Math.max(0, newRadius - radiusStep);\n }\n\n newAngle = ((newAngle % 360) + 360) % 360;\n\n let finalAngle = snapAngle(newAngle, this._prevAngle, this.rays, this.snapValue);\n let finalRadius = snapRadius(newRadius, this._prevRadius, this.rings, this.snapValue);\n\n finalAngle = quantiseAngle(finalAngle, effectiveStopsAngle);\n finalRadius = quantiseRadius(finalRadius, effectiveStopsRadius);\n\n if (finalAngle !== this.angle || finalRadius !== this.radius) {\n this.angle = finalAngle;\n this.radius = finalRadius;\n this.dispatchEvent(new CustomEvent<PolarPadInputDetail>(`input`, {\n detail: { angle: this.angle, radius: this.radius },\n bubbles: true,\n composed: true,\n }));\n }\n };\n\n // -------------------------------------------------------------------------\n // CSS variable sync\n // -------------------------------------------------------------------------\n\n private _setCssVars(): void {\n this.style.setProperty(`--angle-deg`, `${this.angle}`);\n this.style.setProperty(`--angle-rad`, `${this.angle * DEG_TO_RAD}`);\n this.style.setProperty(`--radius-pct`, `${clamp01(this.radius) * 100}`);\n }\n\n override updated(_changed: PropertyValues): void {\n super.updated(_changed);\n this._setCssVars();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._onPointerUp();\n this._pressedKeys.clear();\n }\n\n // -------------------------------------------------------------------------\n // SVG helpers\n // -------------------------------------------------------------------------\n\n private _renderRings() {\n if (this.rings <= 0)\n return ``;\n const items = [];\n for (let i = 1; i <= this.rings; i++) {\n const r = (i / this.rings) * 50;\n items.push(svg`<circle class=\"ring\" cx=\"50\" cy=\"50\" r=\"${r}\" />`);\n }\n return items;\n }\n\n private _renderSpokes() {\n if (this.rays <= 0)\n return ``;\n const items = [];\n for (let i = 0; i < this.rays; i++) {\n const angleRad = (i / this.rays) * 2 * Math.PI;\n const cos = Math.cos(angleRad);\n const sin = Math.sin(angleRad); // SVG +y downward matches CW convention directly\n const x1 = 50 + cos * 50;\n const y1 = 50 + sin * 50;\n const x2 = 50 - cos * 50;\n const y2 = 50 - sin * 50;\n items.push(svg`<line class=\"spoke\" x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" />`);\n }\n return items;\n }\n\n private _renderRay(markerX: number, markerY: number) {\n if (!this.showRay)\n return ``;\n return svg`<line class=\"ray\" x1=\"50\" y1=\"50\" x2=\"${markerX}\" y2=\"${markerY}\" />`;\n }\n\n private _renderOrigin() {\n if (!this.showOrigin)\n return ``;\n return svg`<circle class=\"origin-dot\" cx=\"50\" cy=\"50\" r=\"3\" style=\"r: calc(var(--origin-size) / 2)\" />`;\n }\n\n // -------------------------------------------------------------------------\n // Render\n // -------------------------------------------------------------------------\n\n override render(): ReturnType<typeof html> {\n const angleRad = this.angle * DEG_TO_RAD;\n const { x: markerX, y: markerY } = polarToSvg(angleRad, clamp01(this.radius));\n\n return html`\n <div class=\"polar-pad-area\"\n @pointerdown=${this._onPointerDown}\n @keydown=${this._onKeyDown}\n @keyup=${this._onKeyUp}\n @blur=${() => this._pressedKeys.clear()}>\n <svg viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"xMidYMid meet\"\n tabindex=${this.disabled ? -1 : 0}>\n <defs>\n <clipPath id=\"circle-clip-${this._uid}\">\n <circle cx=\"50\" cy=\"50\" r=\"50\" />\n </clipPath>\n </defs>\n\n <!-- clipped group: background + rings + spokes -->\n <g clip-path=\"url(#circle-clip-${this._uid})\">\n <foreignObject x=\"0\" y=\"0\" width=\"100\" height=\"100\">\n <div class=\"pad-background\" xmlns=\"http://www.w3.org/1999/xhtml\"></div>\n </foreignObject>\n ${this._renderRings()}\n ${this._renderSpokes()}\n </g>\n\n <!-- border circle (on top of clip, non-scaling stroke) -->\n <circle class=\"pad-border\" cx=\"50\" cy=\"50\" r=\"49.75\" />\n\n <!-- ray + origin + marker -->\n ${this._renderRay(markerX, markerY)}\n ${this._renderOrigin()}\n <circle\n class=\"marker\"\n cx=\"${markerX}\"\n cy=\"${markerY}\"\n r=\"5\"\n style=\"r: calc(var(--marker-size) / 2)\"\n />\n </svg>\n </div>\n `;\n }\n\n /** Stable per-instance uid for SVG clipPath IDs. */\n private readonly _uid = Math.random().toString(36).slice(2, 8);\n}\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type PolarPadInputDetail = {\n readonly angle: number; // degrees, 0 = right, clockwise\n readonly radius: number; // 0–1\n};\n\nexport type PolarPadInputEvent = CustomEvent<PolarPadInputDetail>;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-polar-pad': PolarPad;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { t as __decorate } from "./decorate-
|
|
1
|
+
import { n as safeCustomElement, t as __decorate } from "./decorate-O4m1U4l3.js";
|
|
2
2
|
import { t as prominenceStyles } from "./prominence-CreDBdCs.js";
|
|
3
3
|
import { t as resolveStep } from "./keyboard-De_vOHLg.js";
|
|
4
4
|
import { LitElement, css, html, svg } from "lit";
|
|
5
|
-
import {
|
|
5
|
+
import { property } from "lit/decorators.js";
|
|
6
6
|
//#region src/radial-input/svg-utils.ts
|
|
7
7
|
const PI2 = Math.PI * 2;
|
|
8
8
|
const MIDPOINT_ANGLE = -Math.PI / 2;
|
|
@@ -842,8 +842,8 @@ __decorate([property({
|
|
|
842
842
|
type: Boolean,
|
|
843
843
|
reflect: true
|
|
844
844
|
})], RadialInputElement.prototype, "disabled", void 0);
|
|
845
|
-
RadialInputElement = __decorate([
|
|
845
|
+
RadialInputElement = __decorate([safeCustomElement(`ixfx-radial-input`)], RadialInputElement);
|
|
846
846
|
//#endregion
|
|
847
847
|
export { RadialInputElement as t };
|
|
848
848
|
|
|
849
|
-
//# sourceMappingURL=radial-input-
|
|
849
|
+
//# sourceMappingURL=radial-input-Dbc6fgCK.js.map
|