@ixfx/components 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/bundle/index.d.ts +67 -6
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +170 -1
  4. package/bundle/index.js.map +1 -1
  5. package/bundle/style.css +80 -0
  6. package/dist/ac-text.d.ts +1 -1
  7. package/dist/button.d.ts +1 -1
  8. package/dist/button.d.ts.map +1 -1
  9. package/dist/colour-picker.d.ts +1 -1
  10. package/dist/crumbs.d.ts +1 -1
  11. package/dist/{icon-BUwP1CZ1.d.ts → icon-DpA9x2Ve.d.ts} +2 -2
  12. package/dist/icon-DpA9x2Ve.d.ts.map +1 -0
  13. package/dist/icons.d.ts +2 -2
  14. package/dist/{index-RqMh1i-O.d.ts → index-BtGFYfaK.d.ts} +2 -2
  15. package/dist/{index-RqMh1i-O.d.ts.map → index-BtGFYfaK.d.ts.map} +1 -1
  16. package/dist/{index-BUB5SICW.d.ts → index-CoqtMSd9.d.ts} +2 -2
  17. package/dist/{index-BUB5SICW.d.ts.map → index-CoqtMSd9.d.ts.map} +1 -1
  18. package/dist/{index-BKAlRgbq.d.ts → index-D_ftz_IT.d.ts} +2 -2
  19. package/dist/{index-BKAlRgbq.d.ts.map → index-D_ftz_IT.d.ts.map} +1 -1
  20. package/dist/{index-B1UKcA7l.d.ts → index-DfEkTGvT.d.ts} +3 -3
  21. package/dist/{index-B1UKcA7l.d.ts.map → index-DfEkTGvT.d.ts.map} +1 -1
  22. package/dist/index.d.ts +70 -9
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +170 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/{labelled-input-base-Dp_9KP0G.d.ts → labelled-input-base-DiTme1JO.d.ts} +2 -2
  27. package/dist/{labelled-input-base-Dp_9KP0G.d.ts.map → labelled-input-base-DiTme1JO.d.ts.map} +1 -1
  28. package/dist/labelled-radial-input.d.ts +2 -2
  29. package/dist/labelled-radial-input.d.ts.map +1 -1
  30. package/dist/labelled-range-input.d.ts +1 -1
  31. package/dist/{menu-item-CQ4Qg731.d.ts → menu-item-DSyf9f_L.d.ts} +2 -2
  32. package/dist/{menu-item-CQ4Qg731.d.ts.map → menu-item-DSyf9f_L.d.ts.map} +1 -1
  33. package/dist/menu.d.ts +2 -2
  34. package/dist/panel.d.ts +1 -1
  35. package/dist/style.css +80 -0
  36. package/dist/{tab-list-VtWT-_FG.d.ts → tab-list-BohmbvqF.d.ts} +2 -2
  37. package/dist/{tab-list-VtWT-_FG.d.ts.map → tab-list-BohmbvqF.d.ts.map} +1 -1
  38. package/dist/tabs.d.ts +1 -1
  39. package/docs-user/README.md +1 -0
  40. package/docs-user/form.md +108 -0
  41. package/docs-user/tabs.md +11 -2
  42. package/package.json +1 -1
  43. package/dist/icon-BUwP1CZ1.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -2863,6 +2863,132 @@ __decorate([property({
2863
2863
  __decorate([property({ type: Number })], EditableNumber.prototype, "precision", void 0);
2864
2864
  EditableNumber = __decorate([safeCustomElement(`ixfx-editable-number`)], EditableNumber);
2865
2865
  //#endregion
2866
+ //#region src/form/form-group.ts
2867
+ let FormGroupElement = class FormGroupElement extends LitElement {
2868
+ constructor(..._args) {
2869
+ super(..._args);
2870
+ this.label = ``;
2871
+ }
2872
+ createRenderRoot() {
2873
+ return this;
2874
+ }
2875
+ connectedCallback() {
2876
+ super.connectedCallback();
2877
+ this._observer = new MutationObserver(() => this._moveChildren());
2878
+ }
2879
+ firstUpdated() {
2880
+ this._fieldset = this.querySelector(`fieldset`) ?? void 0;
2881
+ if (this._fieldset) {
2882
+ this._observer?.observe(this, { childList: true });
2883
+ this._moveChildren();
2884
+ }
2885
+ }
2886
+ disconnectedCallback() {
2887
+ super.disconnectedCallback();
2888
+ this._observer?.disconnect();
2889
+ }
2890
+ _moveChildren() {
2891
+ if (!this._fieldset) return;
2892
+ Array.from(this.children).filter((el) => el.tagName !== `FIELDSET`).forEach((el) => {
2893
+ this._fieldset.appendChild(el);
2894
+ });
2895
+ }
2896
+ render() {
2897
+ return html`<fieldset><legend>${this.label}</legend></fieldset>`;
2898
+ }
2899
+ };
2900
+ __decorate([property({ type: String })], FormGroupElement.prototype, "label", void 0);
2901
+ FormGroupElement = __decorate([safeCustomElement(`ixfx-form-group`)], FormGroupElement);
2902
+ //#endregion
2903
+ //#region src/form/form-part.ts
2904
+ let idCounter = 0;
2905
+ let FormPartElement = class FormPartElement extends LitElement {
2906
+ constructor(..._args) {
2907
+ super(..._args);
2908
+ this.label = ``;
2909
+ }
2910
+ createRenderRoot() {
2911
+ return this;
2912
+ }
2913
+ connectedCallback() {
2914
+ super.connectedCallback();
2915
+ this._ensureId();
2916
+ }
2917
+ _ensureId() {
2918
+ const control = this.querySelector(`input, select, textarea, [name]`);
2919
+ if (!control) return;
2920
+ if (!control.id) {
2921
+ this._id = `ixfx-form-part-${++idCounter}`;
2922
+ control.id = this._id;
2923
+ } else this._id = control.id;
2924
+ }
2925
+ render() {
2926
+ if (!this._id) this._ensureId();
2927
+ return html`<label for=${this._id ?? ``}>${this.label}</label>`;
2928
+ }
2929
+ };
2930
+ __decorate([property({ type: String })], FormPartElement.prototype, "label", void 0);
2931
+ FormPartElement = __decorate([safeCustomElement(`ixfx-form-part`)], FormPartElement);
2932
+ //#endregion
2933
+ //#region src/form/form-values.ts
2934
+ function collectFormValues(root) {
2935
+ const values = {};
2936
+ root.querySelectorAll(`[name]`).forEach((el) => {
2937
+ const name = el.getAttribute(`name`);
2938
+ if (!name) return;
2939
+ if (el instanceof HTMLInputElement) {
2940
+ if (el.type === `radio`) {
2941
+ if (el.checked) values[name] = el.value;
2942
+ } else if (el.type === `checkbox`) values[name] = el.checked;
2943
+ else values[name] = el.value;
2944
+ } else if (el instanceof HTMLSelectElement) {
2945
+ if (el.multiple) values[name] = Array.from(el.selectedOptions).map((opt) => opt.value);
2946
+ else values[name] = el.value;
2947
+ } else if (el instanceof HTMLTextAreaElement) values[name] = el.value;
2948
+ else if (`value` in el) values[name] = el.value;
2949
+ });
2950
+ return values;
2951
+ }
2952
+ function applyFormValues(root, data) {
2953
+ root.querySelectorAll(`[name]`).forEach((el) => {
2954
+ const name = el.getAttribute(`name`);
2955
+ if (!name || !(name in data)) return;
2956
+ const value = data[name];
2957
+ if (el instanceof HTMLInputElement) {
2958
+ if (el.type === `radio`) el.checked = el.value === value;
2959
+ else if (el.type === `checkbox`) el.checked = Boolean(value);
2960
+ else el.value = String(value ?? ``);
2961
+ el.dispatchEvent(new Event(`input`, { bubbles: true }));
2962
+ el.dispatchEvent(new Event(`change`, { bubbles: true }));
2963
+ } else if (el instanceof HTMLSelectElement) {
2964
+ if (el.multiple && Array.isArray(value)) Array.from(el.options).forEach((opt) => {
2965
+ opt.selected = value.includes(opt.value);
2966
+ });
2967
+ else el.value = String(value ?? ``);
2968
+ el.dispatchEvent(new Event(`input`, { bubbles: true }));
2969
+ el.dispatchEvent(new Event(`change`, { bubbles: true }));
2970
+ } else if (el instanceof HTMLTextAreaElement) {
2971
+ el.value = String(value ?? ``);
2972
+ el.dispatchEvent(new Event(`input`, { bubbles: true }));
2973
+ el.dispatchEvent(new Event(`change`, { bubbles: true }));
2974
+ } else if (`value` in el) el.value = value;
2975
+ });
2976
+ }
2977
+ //#endregion
2978
+ //#region src/form/form.ts
2979
+ let FormElement = class FormElement extends LitElement {
2980
+ createRenderRoot() {
2981
+ return this;
2982
+ }
2983
+ getValues() {
2984
+ return collectFormValues(this);
2985
+ }
2986
+ setValues(data) {
2987
+ applyFormValues(this, data);
2988
+ }
2989
+ };
2990
+ FormElement = __decorate([safeCustomElement(`ixfx-form`)], FormElement);
2991
+ //#endregion
2866
2992
  //#region src/grouped-item-lister/grouped-item-lister.ts
2867
2993
  const UNGROUPED_KEY = `__ungrouped__`;
2868
2994
  let GroupedItemListerElement = class GroupedItemListerElement extends LitElement {
@@ -5274,6 +5400,11 @@ TabPanelElement = __decorate([safeCustomElement(`ixfx-tab-panel`)], TabPanelElem
5274
5400
  //#endregion
5275
5401
  //#region src/tabs/tab-panels.ts
5276
5402
  let TabPanelsElement = class TabPanelsElement extends LitElement {
5403
+ /**
5404
+ * The `ixfx-tab-list` this panels element is associated with, established by
5405
+ * `syncWithList()`. Used by `selectTab()` to activate the matching header.
5406
+ */
5407
+ #list;
5277
5408
  render() {
5278
5409
  return html`<slot></slot>`;
5279
5410
  }
@@ -5293,6 +5424,7 @@ let TabPanelsElement = class TabPanelsElement extends LitElement {
5293
5424
  if (this.onSelectedPanel) this.onSelectedPanel(el.id, el);
5294
5425
  }
5295
5426
  syncWithList(el) {
5427
+ this.#list = el;
5296
5428
  const doSync = () => {
5297
5429
  const t = el.getSelectedElement();
5298
5430
  if (!t) return;
@@ -5314,6 +5446,43 @@ let TabPanelsElement = class TabPanelsElement extends LitElement {
5314
5446
  }
5315
5447
  return found;
5316
5448
  }
5449
+ /**
5450
+ * Select a tab as if the user clicked it — activates the matching header in
5451
+ * the associated `ixfx-tab-list` (deactivating the others) and shows its
5452
+ * panel.
5453
+ *
5454
+ * `nameOrTitle` may be the label text of a tab (e.g. `'Home'`, matched
5455
+ * case-insensitively) or the panel id its `for` attribute points at
5456
+ * (e.g. `'panel-home'`). If no tab matches, `nameOrTitle` is tried directly
5457
+ * as a panel id.
5458
+ *
5459
+ * The tab list must first be associated via `syncWithList()` for the header
5460
+ * to be activated; panel selection works regardless.
5461
+ *
5462
+ * Returns true if a panel was found and selected.
5463
+ */
5464
+ selectTab(nameOrTitle) {
5465
+ const item = this.#findTabItem(nameOrTitle);
5466
+ if (item) {
5467
+ this.#list?.selectElement(item);
5468
+ return this.selectPanel(item.getAttribute(`for`) ?? ``) === true;
5469
+ }
5470
+ return this.selectPanel(nameOrTitle) === true;
5471
+ }
5472
+ #findTabItem(nameOrTitle) {
5473
+ const list = this.#list;
5474
+ if (!list) return void 0;
5475
+ const items = Array.from(list.querySelectorAll(`ixfx-tab-list-item`));
5476
+ for (const item of items) if (item.getAttribute(`for`) === nameOrTitle) return item;
5477
+ const label = nameOrTitle.trim().toLowerCase();
5478
+ for (const item of items) if (this.#labelOf(item).toLowerCase() === label) return item;
5479
+ }
5480
+ /** The tab's visible label text, excluding any `slot="toolbar"` content. */
5481
+ #labelOf(item) {
5482
+ const clone = item.cloneNode(true);
5483
+ clone.querySelectorAll(`[slot="toolbar"]`).forEach((el) => el.remove());
5484
+ return (clone.textContent ?? ``).trim();
5485
+ }
5317
5486
  static {
5318
5487
  this.styles = css`
5319
5488
  :host {
@@ -5625,6 +5794,6 @@ function init() {
5625
5794
  console.log(`Init`);
5626
5795
  }
5627
5796
  //#endregion
5628
- export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, EditableLabel, EditableNumber, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, SelectHorizontalElement, SliderInputElement, SnapContainer, SplitButton, SplitLayoutElement, SwipeElement, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TimelineController, TimelineTrackTabElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, VerticalListElement, XyPad, applyAgeModification, applyHighlights, attachTimelineInteractions, buildHighlightTargets, clearHighlights, collectDataResult, computeColour, createAcCompletionProvider, createElementIncrSearch, createFuzzySearch, createIncrSearch, createPillRenderer, createTreeListAdapter, createVerticalListAdapter, getIcon, hasIcon, iconBus, init, monitorIndeterminate, parseColourScaleAttr, readBaseColour, registerIcon, resolveCssVars, resolveGrid, svgToDataUri, timelineStyles };
5797
+ export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, SelectHorizontalElement, SliderInputElement, SnapContainer, SplitButton, SplitLayoutElement, SwipeElement, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TimelineController, TimelineTrackTabElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, VerticalListElement, XyPad, applyAgeModification, applyHighlights, attachTimelineInteractions, buildHighlightTargets, clearHighlights, collectDataResult, computeColour, createAcCompletionProvider, createElementIncrSearch, createFuzzySearch, createIncrSearch, createPillRenderer, createTreeListAdapter, createVerticalListAdapter, getIcon, hasIcon, iconBus, init, monitorIndeterminate, parseColourScaleAttr, readBaseColour, registerIcon, resolveCssVars, resolveGrid, svgToDataUri, timelineStyles };
5629
5798
 
5630
5799
  //# sourceMappingURL=index.js.map