@odx/foundation 1.0.0-beta.86 → 1.0.0-beta.87

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.
@@ -1,5 +1,5 @@
1
1
  import { ListboxFormControl, OptionControl } from '../../lib/main.js';
2
- import { TemplateResult } from 'lit';
2
+ import { PropertyValues, TemplateResult } from 'lit';
3
3
  import { OdxDropdown } from '../dropdown/dropdown.js';
4
4
  import { OdxOption } from '../option/option.js';
5
5
  declare global {
@@ -13,11 +13,10 @@ export declare class OdxSelect extends ListboxFormControl<OptionControl> {
13
13
  protected readonly dropdown: OdxDropdown;
14
14
  maxVisibleSelectedOptions: number;
15
15
  constructor();
16
- firstUpdated(): void;
16
+ firstUpdated(props: PropertyValues<this>): void;
17
17
  isDropdownOpen(): boolean;
18
18
  showDropdown(): void;
19
19
  hideDropdown(): void;
20
20
  protected render(): TemplateResult;
21
- protected renderSelectedOptions(): TemplateResult;
22
21
  }
23
22
  //# sourceMappingURL=select.d.ts.map
@@ -5,9 +5,9 @@ import { html, isServer, unsafeCSS, css, nothing } from 'lit';
5
5
  import { when } from 'lit/directives/when.js';
6
6
  import { p as pick, e, a as autoUpdate, t as throttle, R as RovingTabindexController, r as round, g as debounce, n, i as c, j as e$1 } from './vendor.js';
7
7
  import { IsLocalized, setTranslation } from '@odx/foundation/i18n';
8
- import { repeat } from 'lit/directives/repeat.js';
9
8
  import { signal, computed } from '@preact/signals-core';
10
9
  import 'lit/html.js';
10
+ import { repeat } from 'lit/directives/repeat.js';
11
11
 
12
12
  const styles$1g = ":host{display:block}";
13
13
 
@@ -1279,7 +1279,7 @@ const _OdxAutocomplete = class _OdxAutocomplete extends FormControl {
1279
1279
  this.minQueryLength = 1;
1280
1280
  this.searchFn = (option, query2) => {
1281
1281
  if (!query2) return true;
1282
- return option.getTextLabel().toLowerCase().trim().includes(query2.toLowerCase().trim());
1282
+ return option.label.toLowerCase().includes(query2.toLowerCase().trim());
1283
1283
  };
1284
1284
  this.#handleControlSlotChange = () => {
1285
1285
  if (!this.control) return;
@@ -1325,7 +1325,7 @@ const _OdxAutocomplete = class _OdxAutocomplete extends FormControl {
1325
1325
  event.stopImmediatePropagation();
1326
1326
  }
1327
1327
  if (this.activeDescendants.activeItem && key.enter) {
1328
- this.#handleControlValueChange(this.activeDescendants.activeItem.getTextLabel());
1328
+ this.#handleControlValueChange(this.activeDescendants.activeItem.label);
1329
1329
  }
1330
1330
  };
1331
1331
  }
@@ -3223,23 +3223,26 @@ __decorateClass([
3223
3223
  ], _OdxSearchBar.prototype, "readonly", 2);
3224
3224
  let OdxSearchBar = _OdxSearchBar;
3225
3225
 
3226
- const styles$o = "@layer base{:host{--_color-background: var(--odx-color-background-control-rest);--_color-foreground: var(--odx-color-foreground-rest);--_color-stroke: var(--odx-color-stroke-control-rest);--_control-size: var(--odx-size-225);--_padding-block: var(--odx-size-37);--_padding-inline: var(--odx-size-50);display:block;border-radius:var(--odx-border-radius-controls);cursor:pointer;max-inline-size:320px;overflow:hidden;color:var(--_color-foreground)}.base{display:flex;gap:var(--_padding-block);align-items:center;transition:var(--odx-transition-reduced);transition-property:background-color,border-color;border:var(--odx-border-width-thin) solid transparent;border-bottom-color:var(--_color-stroke);background-color:var(--_color-background);padding-inline:var(--_padding-inline);block-size:var(--_control-size);min-width:200px;overflow:hidden;text-align:start;user-select:none;&:focus-visible{outline:var(--odx-focus-ring-outline);outline-color:var(--odx-color-stroke-focus-outer)}}.value{display:flex;gap:var(--_padding-block);margin-inline-end:auto;font-weight:var(--odx-typography-font-weight-medium)}.indicator{font-size:var(--odx-size-175)}[part~=dropdown]{--max-block-size: 320px}odx-chip{--_border-radius: var(--odx-border-radius-controls)}slot[name=placeholder]{color:var(--odx-color-foreground-rest-subtle)}}@layer state{:host(:hover){--_color-background: var(--odx-color-background-control-hover);--_color-stroke: var(--odx-color-stroke-control-hover)}:host([multiple]):has(odx-chip) .base{padding-inline-start:var(--_padding-block)}:host([disabled]:not([readonly])){--_color-foreground: var(--odx-color-foreground-disabled-rest);--_color-background: var(--odx-color-background-disabled-rest);--_color-stroke: var(--odx-color-stroke-disabled-rest);cursor:not-allowed;slot[name=placeholder]{color:var(---_color-foreground)}}:host([readonly]){--_color-background: var(--odx-color-background-control-readonly);--_color-stroke: var(--odx-color-stroke-control-readonly);cursor:default;odx-chip{--_color-background: var(--odx-color-foreground-disabled-rest)}.indicator{color:var(--odx-color-foreground-rest-subtle)}}}";
3226
+ const styles$o = "@layer base{:host{--_color-background: var(--odx-color-background-control-rest);--_color-foreground: var(--odx-color-foreground-rest);--_color-stroke: var(--odx-color-stroke-control-rest);--_control-size: var(--odx-size-225);--_padding-block: var(--odx-size-37);--_padding-inline: var(--odx-size-50);display:block;border-radius:var(--odx-border-radius-controls);cursor:pointer;max-inline-size:320px;overflow:hidden;color:var(--_color-foreground)}.base{display:flex;gap:var(--_padding-block);align-items:center;transition:var(--odx-transition-reduced);transition-property:background-color,border-color;border:var(--odx-border-width-thin) solid transparent;border-bottom-color:var(--_color-stroke);background-color:var(--_color-background);padding-inline:var(--_padding-inline);block-size:var(--_control-size);min-width:200px;overflow:hidden;text-align:start;user-select:none;&:focus-visible{outline:var(--odx-focus-ring-outline);outline-color:var(--odx-color-stroke-focus-outer)}}.value{margin-inline-end:auto;font-weight:var(--odx-typography-font-weight-medium)}.indicator{font-size:var(--odx-size-175)}[part~=dropdown]{--max-block-size: 320px}odx-chip{--_border-radius: var(--odx-border-radius-controls)}slot[name=placeholder]{color:var(--odx-color-foreground-rest-subtle)}}@layer state{:host(:hover){--_color-background: var(--odx-color-background-control-hover);--_color-stroke: var(--odx-color-stroke-control-hover)}:host([multiple]):has(odx-chip) .base{padding-inline-start:var(--_padding-block)}:host([disabled]:not([readonly])){--_color-foreground: var(--odx-color-foreground-disabled-rest);--_color-background: var(--odx-color-background-disabled-rest);--_color-stroke: var(--odx-color-stroke-disabled-rest);cursor:not-allowed;slot[name=placeholder]{color:var(---_color-foreground)}}:host([readonly]){--_color-background: var(--odx-color-background-control-readonly);--_color-stroke: var(--odx-color-stroke-control-readonly);cursor:default;odx-chip{--_color-background: var(--odx-color-foreground-disabled-rest)}.indicator{color:var(--odx-color-foreground-rest-subtle)}}}";
3227
3227
 
3228
3228
  const _OdxSelect = class _OdxSelect extends ListboxFormControl {
3229
3229
  constructor() {
3230
3230
  super();
3231
3231
  this.maxVisibleSelectedOptions = 2;
3232
3232
  this.#handleSlotChange = () => {
3233
+ super.handleSlotChange();
3233
3234
  for (const option of this.options) {
3234
3235
  option.type = this.multiple ? "checkbox" : null;
3235
3236
  }
3236
3237
  };
3237
- this.#handleChipRemove = (option) => {
3238
- this.toggleOption(option, false);
3239
- };
3240
3238
  this.#handleBlur = () => {
3241
3239
  this.hideDropdown();
3242
3240
  };
3241
+ this.#handleToggleAll = (event) => {
3242
+ event.stopPropagation();
3243
+ event.preventDefault();
3244
+ this.value = this.value.length === this.options.length ? [] : this.options.map((option) => option.value);
3245
+ };
3243
3246
  this.#handleClear = (event) => {
3244
3247
  event.stopPropagation();
3245
3248
  event.preventDefault();
@@ -3258,9 +3261,9 @@ const _OdxSelect = class _OdxSelect extends ListboxFormControl {
3258
3261
  static {
3259
3262
  customElement("odx-select", styles$o)(_OdxSelect);
3260
3263
  }
3261
- firstUpdated() {
3262
- const referenceElement = this.shadowRoot?.querySelector(".base") ?? null;
3263
- this.dropdown.mountPopover(referenceElement);
3264
+ firstUpdated(props) {
3265
+ super.firstUpdated(props);
3266
+ this.dropdown.mountPopover(this.shadowRoot?.querySelector(".base") ?? null);
3264
3267
  }
3265
3268
  isDropdownOpen() {
3266
3269
  return this.dropdown.isPopoverOpen();
@@ -3272,12 +3275,13 @@ const _OdxSelect = class _OdxSelect extends ListboxFormControl {
3272
3275
  this.dropdown.hidePopover();
3273
3276
  }
3274
3277
  render() {
3278
+ const allSelected = this.value.length === this.options.length;
3275
3279
  return html`
3276
3280
  <div class="base" tabindex="0">
3277
3281
  <div class="value" odxPreventTextOverflow>
3278
3282
  ${when(
3279
3283
  this.selectedOptions.length,
3280
- () => this.renderSelectedOptions(),
3284
+ () => html`${this.selectedOptions.map((option) => option.label).join(", ")}`,
3281
3285
  () => html`<slot name="placeholder">Select options</slot>`
3282
3286
  )}
3283
3287
  </div>
@@ -3288,35 +3292,22 @@ const _OdxSelect = class _OdxSelect extends ListboxFormControl {
3288
3292
  <odx-icon class="indicator" name="core::chevron-down"></odx-icon>
3289
3293
  </div>
3290
3294
  <odx-dropdown part="dropdown" role="listbox" tabindex="-1" ?disabled=${this.disabled || this.readonly} match-reference-width>
3295
+ ${when(
3296
+ this.multiple,
3297
+ () => html`
3298
+ <odx-option type="checkbox" @click=${this.#handleToggleAll} ?selected=${allSelected}>Toggle all</odx-option>
3299
+ `
3300
+ )}
3291
3301
  <slot @slotchange=${this.#handleSlotChange}></slot>
3292
3302
  </odx-dropdown>
3293
3303
  `;
3294
3304
  }
3295
- renderSelectedOptions() {
3296
- if (!this.multiple) {
3297
- return html`${this.selectedOptions[0]?.label}`;
3298
- }
3299
- if (this.disabled || this.readonly) {
3300
- return html`${this.selectedOptions.length} Selected`;
3301
- }
3302
- const renderChip = (option) => {
3303
- return html`
3304
- <odx-chip removable tabindex="-1" @remove=${() => this.#handleChipRemove(option)} >
3305
- ${option.getTextLabel()}
3306
- </odx-chip>
3307
- `;
3308
- };
3309
- return html`
3310
- ${repeat(this.selectedOptions.slice(0, this.maxVisibleSelectedOptions), renderChip)}
3311
- ${when(this.selectedOptions.length > this.maxVisibleSelectedOptions, () => html`<odx-chip ?disabled=${this.disabled}>+${this.selectedOptions.length - this.maxVisibleSelectedOptions}</odx-chip>`)}
3312
- `;
3313
- }
3314
3305
  #isClearable() {
3315
3306
  return !(this.multiple || this.disabled || this.readonly || this.required) && this.selectedOptions.length > 0;
3316
3307
  }
3317
3308
  #handleSlotChange;
3318
- #handleChipRemove;
3319
3309
  #handleBlur;
3310
+ #handleToggleAll;
3320
3311
  #handleClear;
3321
3312
  #handleSelect;
3322
3313
  };
@@ -16,7 +16,7 @@ export declare abstract class ListboxFormControl<Option extends OptionControl> e
16
16
  protected canSelect(option: Option): boolean;
17
17
  toggleOption(option: Option, state?: boolean): void;
18
18
  connectedCallback(): void;
19
- protected firstUpdated(props: PropertyValues<this>): void;
19
+ protected handleSlotChange(): void;
20
20
  protected updateValue(option?: Option): void;
21
21
  protected willUpdate(props: PropertyValues<this>): void;
22
22
  protected updateSelection(): void;
@@ -11,7 +11,6 @@ export declare abstract class OptionControl extends OptionControl_base implement
11
11
  value: string;
12
12
  selected: boolean;
13
13
  type?: 'checkbox' | null;
14
- getTextLabel(): string;
15
14
  canActivate(): boolean;
16
15
  canSelect(): boolean;
17
16
  isActive(): boolean;
package/dist/main.js CHANGED
@@ -474,10 +474,7 @@ class OptionControl extends CanBeDisabled(CustomElement) {
474
474
  this.#label = value;
475
475
  }
476
476
  get label() {
477
- return this.#label || this.getTextLabel();
478
- }
479
- getTextLabel() {
480
- return this.textContent?.trim() ?? "";
477
+ return (this.#label || this.textContent?.trim()) ?? "";
481
478
  }
482
479
  canActivate() {
483
480
  return !(this.disabled || this.hidden);
@@ -523,7 +520,6 @@ __decorateClass([
523
520
  class ListboxFormControl extends FormControl {
524
521
  constructor() {
525
522
  super();
526
- this.#selectedOptions = /* @__PURE__ */ new Map();
527
523
  this.activeDescendants = new ActiveDescendantsController(this, {
528
524
  getItems: () => this.options,
529
525
  onChange: (_, option, firstChange) => {
@@ -567,9 +563,8 @@ class ListboxFormControl extends FormControl {
567
563
  this.addEventListener("keydown", this.#handleKeydown);
568
564
  }
569
565
  }
570
- #selectedOptions;
571
566
  get selectedOptions() {
572
- return Array.from(this.#selectedOptions.values());
567
+ return this.options.filter((option) => option.selected);
573
568
  }
574
569
  get selectedIndices() {
575
570
  return this.selectedOptions.map((option) => this.options.indexOf(option));
@@ -595,12 +590,9 @@ class ListboxFormControl extends FormControl {
595
590
  this.role ||= "listbox";
596
591
  this.id ||= getUniqueId(this.localName);
597
592
  }
598
- firstUpdated(props) {
599
- super.firstUpdated(props);
600
- for (const option of this.options) {
601
- if (!option.selected) continue;
602
- this.updateValue(option);
603
- }
593
+ handleSlotChange() {
594
+ this.value ||= this.multiple ? this.selectedOptions.map((option) => option.value) : this.selectedOptions[0]?.value ?? "";
595
+ this.requestUpdate("value");
604
596
  }
605
597
  updateValue(option) {
606
598
  const oldValue = this.value;
@@ -626,21 +618,15 @@ class ListboxFormControl extends FormControl {
626
618
  this.#handleMultipleChange();
627
619
  }
628
620
  if (props.has("required") || props.has("value")) {
629
- const [selectedOption] = this.#selectedOptions.values();
630
- if (!selectedOption?.selected) return;
631
- this.setValidity({ valueMissing: this.required && this.value.length === 0 }, selectedOption);
621
+ if (!this.selectedOptions[0]?.selected) return;
622
+ this.setValidity({ valueMissing: this.required && this.value.length === 0 }, this.selectedOptions[0]);
632
623
  }
633
624
  }
634
625
  updateSelection() {
635
- if (this.disabled) return;
626
+ if (this.disabled || this.options.length === 0) return;
636
627
  for (const option of this.options ?? []) {
637
628
  if (option.disabled) continue;
638
629
  option.selected = this.multiple ? this.value.includes(option.value) : this.value === option.value;
639
- if (option.selected) {
640
- this.#selectedOptions.set(option.value, option);
641
- } else {
642
- this.#selectedOptions.delete(option.value);
643
- }
644
630
  }
645
631
  }
646
632
  #handleOptionSelection(option) {
@@ -652,10 +638,8 @@ class ListboxFormControl extends FormControl {
652
638
  for (const option of this.options) {
653
639
  option.type = optionType;
654
640
  }
655
- if (this.multiple) return;
656
- const [selectedOption] = this.#selectedOptions.values();
657
- if (selectedOption) {
658
- this.updateValue(selectedOption);
641
+ if (!this.multiple && this.selectedOptions[0]) {
642
+ this.updateValue(this.selectedOptions[0]);
659
643
  }
660
644
  }
661
645
  #handleBlur;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@odx/foundation",
3
3
  "description": "A library of Web Component building blocks for ODX",
4
- "version": "1.0.0-beta.86",
4
+ "version": "1.0.0-beta.87",
5
5
  "author": "Drägerwerk AG & Co.KGaA",
6
6
  "license": "SEE LICENSE IN LICENSE",
7
7
  "homepage": "https://odx.draeger.com",