@haiilo/catalyst 1.0.2 → 1.1.1

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 (65) hide show
  1. package/dist/catalyst/catalyst.css +1 -1
  2. package/dist/catalyst/catalyst.esm.js +1 -1
  3. package/dist/catalyst/catalyst.esm.js.map +1 -1
  4. package/dist/catalyst/p-a4d0b054.entry.js +10 -0
  5. package/dist/catalyst/p-a4d0b054.entry.js.map +1 -0
  6. package/dist/catalyst/scss/utils/_sizing.mixins.scss +1 -1
  7. package/dist/cjs/cat-alert_23.cjs.entry.js +320 -129
  8. package/dist/cjs/cat-alert_23.cjs.entry.js.map +1 -1
  9. package/dist/cjs/catalyst.cjs.js +1 -1
  10. package/dist/cjs/loader.cjs.js +1 -1
  11. package/dist/collection/components/cat-alert/cat-alert.css +13 -19
  12. package/dist/collection/components/cat-alert/cat-alert.js +19 -20
  13. package/dist/collection/components/cat-alert/cat-alert.js.map +1 -1
  14. package/dist/collection/components/cat-avatar/cat-avatar.css +8 -8
  15. package/dist/collection/components/cat-badge/cat-badge.css +20 -26
  16. package/dist/collection/components/cat-badge/cat-badge.js +9 -12
  17. package/dist/collection/components/cat-badge/cat-badge.js.map +1 -1
  18. package/dist/collection/components/cat-card/cat-card.js +2 -3
  19. package/dist/collection/components/cat-card/cat-card.js.map +1 -1
  20. package/dist/collection/components/cat-checkbox/cat-checkbox.css +1 -1
  21. package/dist/collection/components/cat-select/cat-select.css +6 -1
  22. package/dist/collection/components/cat-select/cat-select.js +290 -89
  23. package/dist/collection/components/cat-select/cat-select.js.map +1 -1
  24. package/dist/collection/components/cat-select-demo/cat-select-demo.js +43 -30
  25. package/dist/collection/components/cat-select-demo/cat-select-demo.js.map +1 -1
  26. package/dist/collection/components/cat-tooltip/cat-tooltip.css +26 -2
  27. package/dist/collection/components/cat-tooltip/cat-tooltip.js +51 -3
  28. package/dist/collection/components/cat-tooltip/cat-tooltip.js.map +1 -1
  29. package/dist/collection/index.js.map +1 -1
  30. package/dist/collection/scss/utils/_sizing.mixins.scss +1 -1
  31. package/dist/collection/utils/setDefault.js +9 -0
  32. package/dist/collection/utils/setDefault.js.map +1 -0
  33. package/dist/components/cat-alert.js +16 -14
  34. package/dist/components/cat-alert.js.map +1 -1
  35. package/dist/components/cat-avatar2.js +1 -1
  36. package/dist/components/cat-avatar2.js.map +1 -1
  37. package/dist/components/cat-badge.js +9 -9
  38. package/dist/components/cat-badge.js.map +1 -1
  39. package/dist/components/cat-card.js +2 -2
  40. package/dist/components/cat-card.js.map +1 -1
  41. package/dist/components/cat-checkbox2.js +1 -1
  42. package/dist/components/cat-checkbox2.js.map +1 -1
  43. package/dist/components/cat-select-demo.js +33 -22
  44. package/dist/components/cat-select-demo.js.map +1 -1
  45. package/dist/components/cat-select2.js +238 -77
  46. package/dist/components/cat-select2.js.map +1 -1
  47. package/dist/components/cat-tooltip.js +17 -3
  48. package/dist/components/cat-tooltip.js.map +1 -1
  49. package/dist/components/setDefault.js +12 -0
  50. package/dist/components/setDefault.js.map +1 -0
  51. package/dist/esm/cat-alert_23.entry.js +321 -130
  52. package/dist/esm/cat-alert_23.entry.js.map +1 -1
  53. package/dist/esm/catalyst.js +1 -1
  54. package/dist/esm/loader.js +1 -1
  55. package/dist/types/components/cat-alert/cat-alert.d.ts +3 -3
  56. package/dist/types/components/cat-badge/cat-badge.d.ts +2 -2
  57. package/dist/types/components/cat-select/cat-select.d.ts +34 -1
  58. package/dist/types/components/cat-select-demo/cat-select-demo.d.ts +3 -0
  59. package/dist/types/components/cat-tooltip/cat-tooltip.d.ts +8 -0
  60. package/dist/types/components.d.ts +37 -5
  61. package/dist/types/index.d.ts +1 -1
  62. package/dist/types/utils/setDefault.d.ts +6 -0
  63. package/package.json +2 -2
  64. package/dist/catalyst/p-a2ddc7fa.entry.js +0 -10
  65. package/dist/catalyst/p-a2ddc7fa.entry.js.map +0 -1
@@ -504,7 +504,7 @@ var autosizeInput = function (element, options) {
504
504
  }
505
505
  };
506
506
 
507
- const catSelectCss = ".hint-section{display:flex;gap:0.5rem;flex-direction:column}.hint-section .input-hint,.hint-section ::slotted([slot=hint]){font-size:0.875rem;line-height:1rem;font-weight:var(--cat-font-weight-body, 400);margin:0 !important}:host-context(.cat-error) .hint-section{color:#d9340d}:host{display:flex;flex-direction:column;gap:0.5rem;position:relative;margin-bottom:1rem}:host([hidden]){display:none}label{align-self:flex-start}label.hidden{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.input-optional{margin-left:0.25rem;font-size:0.75rem;line-height:1rem;font-weight:var(--cat-font-weight-body, 400);color:rgb(var(--cat-font-color-muted, 105, 118, 135))}.select-wrapper{display:flex;align-items:flex-start;background:white;border-radius:0.25rem;box-shadow:0 0 0 1px #d7dbe0;transition:box-shadow 0.13s linear;padding:0.25rem}.select-wrapper:not(.select-disabled):hover{box-shadow:0 0 0 2px #d7dbe0}.select-wrapper:not(.select-disabled):focus-within{outline:2px solid rgb(var(--cat-border-color-focus, 0, 113, 255))}:host(.cat-error) .select-wrapper{box-shadow:0 0 0 1px #d9340d}:host(.cat-error) .select-wrapper:not(.input-disabled):hover{box-shadow:0 0 0 2px #d9340d}.select-disabled{background:#f8f8fb;cursor:not-allowed;color:rgb(var(--cat-font-color-muted, 105, 118, 135));pointer-events:none}.select-wrapper-inner{display:flex;flex:1 1 auto;flex-wrap:wrap;align-items:center;gap:0.25rem;min-width:0}.select-wrapper-inner>cat-avatar{padding-left:0.25rem}.select-wrapper-inner cat-avatar{--cat-avatar-size:1.25rem}.select-input{font:inherit;background:none;border:none;outline:none;padding:0.375rem 0.5rem;flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}.select-disabled .select-input{cursor:inherit}.select-pills{display:contents}.pill{display:inline-flex;align-items:center;gap:0.5rem;padding:0.25rem 0.5rem;background:#ebecf0;border-radius:0.125rem;white-space:nowrap;min-width:0}.pill>span{overflow:hidden;text-overflow:ellipsis}.pill>cat-button{margin-right:-0.25rem;margin-left:-0.25rem}.select-btn{transition:transform 0.13s linear}.select-btn::part(button){outline:none}cat-spinner{padding:0.375rem}.select-btn-open{transform:rotate(180deg)}.select-dropdown{position:absolute;right:0;background:white;display:none;overflow:auto;box-shadow:0 1px 4px 0 rgba(16, 29, 48, 0.2);border-radius:0.25rem;z-index:100}.select-options-wrapper{max-height:16rem;width:100%}.select-empty{margin:1rem 0;padding:0 1.25rem}.select-options{list-style-type:none;margin:0;padding:0.5rem 0}.select-options cat-checkbox,.select-options .select-option-single{margin:0;padding:0.5rem 1rem}.select-option-inner{display:flex;gap:0.5rem;--cat-avatar-size:1.25rem}.select-option-single{cursor:pointer}.select-input-transparent-caret{caret-color:transparent}.select-option-empty,.select-option-loading{padding:0.5rem 1rem}.select-option:hover{background-color:rgba(105, 118, 135, 0.05)}.select-option-active{outline:2px solid rgb(var(--cat-border-color-focus, 0, 113, 255));outline-offset:-2px}.select-option-label{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}.select-option-description{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;color:rgb(var(--cat-font-color-muted, 105, 118, 135))}";
507
+ const catSelectCss = ".hint-section{display:flex;gap:0.5rem;flex-direction:column}.hint-section .input-hint,.hint-section ::slotted([slot=hint]){font-size:0.875rem;line-height:1rem;font-weight:var(--cat-font-weight-body, 400);margin:0 !important}:host-context(.cat-error) .hint-section{color:#d9340d}:host{display:flex;flex-direction:column;gap:0.5rem;position:relative;margin-bottom:1rem}:host([hidden]){display:none}label{align-self:flex-start}label.hidden{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.input-optional{margin-left:0.25rem;font-size:0.75rem;line-height:1rem;font-weight:var(--cat-font-weight-body, 400);color:rgb(var(--cat-font-color-muted, 105, 118, 135))}.select-wrapper{display:flex;align-items:flex-start;background:white;border-radius:0.25rem;box-shadow:0 0 0 1px #d7dbe0;transition:box-shadow 0.13s linear;padding:0.25rem}.select-wrapper:not(.select-disabled):hover{box-shadow:0 0 0 2px #d7dbe0}.select-wrapper:not(.select-disabled):focus-within{outline:2px solid rgb(var(--cat-border-color-focus, 0, 113, 255))}:host(.cat-error) .select-wrapper{box-shadow:0 0 0 1px #d9340d}:host(.cat-error) .select-wrapper:not(.input-disabled):hover{box-shadow:0 0 0 2px #d9340d}.select-disabled{background:#f8f8fb;cursor:not-allowed;color:rgb(var(--cat-font-color-muted, 105, 118, 135));pointer-events:none}.select-wrapper-inner{display:flex;flex:1 1 auto;flex-wrap:wrap;align-items:center;gap:0.25rem;min-width:0}.select-wrapper-inner>cat-avatar{padding-left:0.25rem}.select-wrapper-inner cat-avatar{--cat-avatar-size:1.25rem}.select-input{font:inherit;background:none;border:none;outline:none;padding:0.375rem 0.5rem;flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}.select-disabled .select-input{cursor:inherit}.select-pills{display:contents}.pill{display:inline-flex;align-items:center;gap:0.5rem;padding:0.25rem 0.5rem;background:#f2f4f7;border-radius:0.125rem;white-space:nowrap;min-width:0}.pill>span{overflow:hidden;text-overflow:ellipsis;flex:1 1 0%}.pill>cat-button{margin-right:-0.25rem;margin-left:-0.25rem}.select-btn{transition:transform 0.13s linear}.select-btn::part(button){outline:none}cat-spinner{padding:0.375rem}.select-btn-open{transform:rotate(180deg)}.select-dropdown{position:absolute;right:0;background:white;display:none;overflow:auto;box-shadow:0 1px 4px 0 rgba(16, 29, 48, 0.2);border-radius:0.25rem;z-index:100}.select-options-wrapper{max-height:16rem;width:100%}.select-empty{margin:1rem 0;padding:0 1.25rem}.select-options{list-style-type:none;margin:0;padding:0.5rem 0}.select-options cat-checkbox,.select-options .select-option-single{margin:0;padding:0.5rem 1rem}.select-option-inner{display:flex;gap:0.5rem;--cat-avatar-size:1.25rem}.select-option-text{flex:1 1 0%}.select-option-single{cursor:pointer}.select-input-transparent-caret{caret-color:transparent}.select-option-empty,.select-option-loading{padding:0.5rem 1rem}.select-option:hover{background-color:rgba(105, 118, 135, 0.05)}.select-option-active{outline:2px solid rgb(var(--cat-border-color-focus, 0, 113, 255));outline-offset:-2px}.select-option-label{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}.select-option-description{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;color:rgb(var(--cat-font-color-muted, 105, 118, 135))}";
508
508
 
509
509
  const INIT_STATE = {
510
510
  term: '',
@@ -568,6 +568,10 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
568
568
  * Whether the select should show a clear button.
569
569
  */
570
570
  this.clearable = false;
571
+ /**
572
+ * Whether the select should add new items.
573
+ */
574
+ this.tags = false;
571
575
  }
572
576
  onConnectorChange(connector) {
573
577
  this.reset(connector);
@@ -587,11 +591,25 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
587
591
  this.hide();
588
592
  }
589
593
  const idsSelected = this.state.selection.map(item => item.item.id);
590
- if (this.multiple) {
591
- this.value = idsSelected;
594
+ if (!this.tags) {
595
+ if (this.multiple) {
596
+ this.value = idsSelected;
597
+ }
598
+ else {
599
+ this.value = idsSelected.length ? idsSelected[0] : '';
600
+ }
592
601
  }
593
602
  else {
594
- this.value = idsSelected.length ? idsSelected[0] : '';
603
+ const ids = idsSelected.filter(id => !id.startsWith(`select-${this.id}-tag`));
604
+ const tags = this.state.selection
605
+ .filter(item => item.item.id.startsWith(`select-${this.id}-tag`))
606
+ .map(item => item.render.label);
607
+ if (this.multiple) {
608
+ this.value = { ids, tags };
609
+ }
610
+ else {
611
+ this.value = { id: ids.length ? ids[0] : '', tag: tags.length ? tags[0] : '' };
612
+ }
595
613
  }
596
614
  this.catChange.emit();
597
615
  }
@@ -612,7 +630,12 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
612
630
  }
613
631
  onBlur(event) {
614
632
  if (!this.multiple && this.state.activeOptionIndex >= 0) {
615
- this.select(this.state.options[this.state.activeOptionIndex]);
633
+ if (this.tags && this.state.options[this.state.activeOptionIndex].item.id === `select-${this.id}-option-tag`) {
634
+ this.createTag(this.state.term);
635
+ }
636
+ else {
637
+ this.select(this.state.options[this.state.activeOptionIndex]);
638
+ }
616
639
  }
617
640
  this.hide();
618
641
  this.patchState({ activeSelectionIndex: -1 });
@@ -624,8 +647,19 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
624
647
  if (['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
625
648
  this.onArrowKeyDown(event);
626
649
  }
627
- else if (['Enter', ' '].includes(event.key)) {
628
- if (isInputFocused && this.state.activeOptionIndex >= 0) {
650
+ else if (['Enter', ' '].includes(event.key) && isInputFocused) {
651
+ if (this.tags &&
652
+ this.state.activeOptionIndex === 0 &&
653
+ this.state.options[0].item.id === `select-${this.id}-option-tag`) {
654
+ event.preventDefault();
655
+ if (this.multiple) {
656
+ this.toggleTag(this.state.options[0]);
657
+ }
658
+ else {
659
+ this.createTag(this.state.options[0].render.label);
660
+ }
661
+ }
662
+ else if (this.state.activeOptionIndex >= 0) {
629
663
  event.preventDefault();
630
664
  if (this.multiple) {
631
665
  this.toggle(this.state.options[this.state.activeOptionIndex]);
@@ -634,6 +668,9 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
634
668
  this.select(this.state.options[this.state.activeOptionIndex]);
635
669
  }
636
670
  }
671
+ else if (this.tags && event.key === 'Enter' && this.state.activeOptionIndex < 0) {
672
+ this.createTag(this.state.term);
673
+ }
637
674
  }
638
675
  else if (event.key === 'Escape') {
639
676
  this.hide();
@@ -657,7 +694,12 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
657
694
  this.patchState({ activeSelectionIndex: -1, activeOptionIndex: -1 });
658
695
  }
659
696
  else if (this.state.activeOptionIndex >= 0) {
660
- this.select(this.state.options[this.state.activeOptionIndex]);
697
+ if (this.tags && this.state.options[this.state.activeOptionIndex].item.id === `select-${this.id}-option-tag`) {
698
+ this.createTag(this.state.term);
699
+ }
700
+ else {
701
+ this.select(this.state.options[this.state.activeOptionIndex]);
702
+ }
661
703
  }
662
704
  }
663
705
  else if (event.key.length === 1) {
@@ -695,12 +737,28 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
695
737
  this.subscription = this.term$
696
738
  .asObservable()
697
739
  .pipe(debounce(term => (term ? timer(this.debounce) : of(0))), distinctUntilChanged(), tap(() => (number$ = this.more$.pipe(filter(() => !this.state.isLoading), scan(n => n + 1, 0), startWith(0)))), tap(() => this.patchState({ options: [] })), switchMap(term => number$.pipe(tap(() => this.patchState({ isLoading: true })), switchMap(number => this.connectorSafe.retrieve(term, number)), tap(page => this.patchState({ isLoading: false, totalElements: page.totalElements })), takeWhile(page => !page.last, true), scan((items, page) => [...items, ...page.content], []))))
698
- .subscribe(items => this.patchState({
699
- options: items === null || items === void 0 ? void 0 : items.map(item => ({
700
- item,
740
+ .subscribe(items => {
741
+ var _a;
742
+ const options = items === null || items === void 0 ? void 0 : items.map(item => ({
743
+ item: Object.assign(Object.assign({}, item), { id: this.connectorSafe.customId ? this.connectorSafe.customId(item) : item.id }),
701
744
  render: this.connectorSafe.render(item)
702
- }))
703
- }));
745
+ }));
746
+ if (this.tags &&
747
+ this.state.term.trim().length &&
748
+ !options.find(value1 => value1.render.label.toLowerCase() === this.state.term.toLowerCase())) {
749
+ let label;
750
+ if (this.isAlreadyCreated(this.state.term)) {
751
+ label = (_a = this.state.selection.find(item => item.render.label.toLowerCase() === this.state.term.toLowerCase())) === null || _a === void 0 ? void 0 : _a.render.label;
752
+ }
753
+ options.unshift({
754
+ item: { id: `select-${this.id}-option-tag` },
755
+ render: { label: label ? label : this.state.term }
756
+ });
757
+ }
758
+ this.patchState({
759
+ options
760
+ });
761
+ });
704
762
  }
705
763
  render() {
706
764
  return (h(Host, null, (this.hasSlottedLabel || this.label) && (h("label", { htmlFor: this.id, class: { hidden: this.labelHidden } }, h("span", { part: "label" }, (this.hasSlottedLabel && h("slot", { name: "label" })) || this.label, !this.required && (h("span", { class: "input-optional", "aria-hidden": "true" }, "(", this.i18n.t('input.optional'), ")"))))), h("div", { class: { 'select-wrapper': true, 'select-disabled': this.disabled }, ref: el => (this.trigger = el), id: this.id, role: "combobox", "aria-expanded": this.state.isOpen || this.isPillboxActive(), "aria-controls": this.isPillboxActive() ? `select-pillbox-${this.id}` : `select-listbox-${this.id}`, "aria-required": this.required, "aria-activedescendant": this.activeDescendant, onClick: e => this.onClick(e) }, h("div", { class: "select-wrapper-inner" }, this.multiple && this.state.selection.length ? (h("div", { id: `select-pillbox-${this.id}`, role: "listbox", "aria-orientation": "horizontal", class: "select-pills" }, this.state.selection.map((item, i) => (h("span", { class: {
@@ -710,16 +768,35 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
710
768
  }, role: "option", "aria-selected": "true", id: `select-${this.id}-selection-${i}` }, item.render.avatar ? (h("cat-avatar", { label: item.render.label, round: item.render.avatar.round, src: item.render.avatar.src, initials: '' })) : null, h("span", null, item.render.label), !this.disabled && (h("cat-button", { size: "xs", variant: "text", icon: "16-cross", iconOnly: true, a11yLabel: this.i18n.t('select.deselect'), onClick: () => this.deselect(item.item.id), tabIndex: -1 }))))))) : this.state.selection.length && this.state.selection[0].render.avatar ? (h("cat-avatar", { label: this.state.selection[0].render.label, round: this.state.selection[0].render.avatar.round, src: this.state.selection[0].render.avatar.src, initials: '' })) : null, h("input", { class: "select-input", ref: el => (this.input = el), "aria-controls": this.isPillboxActive() ? `select-pillbox-${this.id}` : `select-listbox-${this.id}`, "aria-activedescendant": this.activeDescendant, onInput: () => this.onInput(), value: !this.multiple ? this.state.term : undefined, placeholder: this.placeholder, disabled: this.disabled || this.state.isResolving })), this.state.isResolving && h("cat-spinner", null), (this.state.selection.length || this.state.term.length) &&
711
769
  !this.disabled &&
712
770
  !this.state.isResolving &&
713
- this.clearable ? (h("cat-button", { id: `select-clear-btn-${this.id}`, iconOnly: true, icon: "cross-circle-outlined", variant: "text", size: "s", a11yLabel: this.i18n.t('input.clear'), onClick: () => this.clear() })) : null, !this.state.isResolving && (h("cat-button", { iconOnly: true, icon: "chevron-down-outlined", class: { 'select-btn': true, 'select-btn-open': this.state.isOpen }, variant: "text", size: "s", a11yLabel: this.state.isOpen ? this.i18n.t('select.close') : this.i18n.t('select.open'), "aria-controls": `select-listbox-${this.id}`, "aria-expanded": this.state.isOpen, tabIndex: -1, disabled: this.disabled || this.state.isResolving }))), this.hintSection, h("div", { class: "select-dropdown", ref: el => (this.dropdown = el), style: { display: this.state.isOpen ? 'block' : undefined } }, this.state.isOpen && (h("cat-scrollable", { class: "select-options-wrapper", scrolledBuffer: 56, noOverflowX: true, noOverscroll: true, noScrolledInit: true, onScrolledBottom: () => this.more$.next() }, h("ul", { class: "select-options", role: "listbox", "aria-multiselectable": this.multiple, "aria-setsize": this.state.totalElements, id: `select-listbox-${this.id}` }, this.state.options.map((item, i) => (h("li", { role: "option", class: "select-option", id: `select-${this.id}-option-${i}`, "aria-selected": this.isSelected(item.item.id) ? 'true' : 'false' }, this.multiple ? (h("cat-checkbox", { class: { 'select-option-active': this.state.activeOptionIndex === i }, checked: this.isSelected(item.item.id), tabIndex: -1, labelLeft: true, onFocus: () => { var _a; return (_a = this.input) === null || _a === void 0 ? void 0 : _a.focus(); }, onCatChange: e => {
714
- this.toggle(item);
715
- e.stopPropagation();
716
- } }, h("span", { slot: "label", class: "select-option-inner" }, item.render.avatar ? (h("cat-avatar", { label: item.render.label, round: item.render.avatar.round, src: item.render.avatar.src, initials: '' })) : null, h("span", { class: "select-option-text" }, h("span", { class: "select-option-label" }, item.render.label), h("span", { class: "select-option-description" }, item.render.description))))) : (h("div", { class: {
717
- 'select-option-inner': true,
718
- 'select-option-single': true,
719
- 'select-option-active': this.state.activeOptionIndex === i
720
- }, onFocus: () => { var _a; return (_a = this.input) === null || _a === void 0 ? void 0 : _a.focus(); }, onClick: () => this.select(item), tabIndex: -1 }, item.render.avatar ? (h("cat-avatar", { label: item.render.label, round: item.render.avatar.round, src: item.render.avatar.src, initials: '' })) : null, h("span", { class: "select-option-text" }, h("span", { class: "select-option-label" }, item.render.label), h("span", { class: "select-option-description" }, item.render.description))))))), this.state.isLoading
771
+ this.clearable ? (h("cat-button", { id: `select-clear-btn-${this.id}`, iconOnly: true, icon: "cross-circle-outlined", variant: "text", size: "s", a11yLabel: this.i18n.t('input.clear'), onClick: () => this.clear() })) : null, !this.state.isResolving && (h("cat-button", { iconOnly: true, icon: "chevron-down-outlined", class: { 'select-btn': true, 'select-btn-open': this.state.isOpen }, variant: "text", size: "s", a11yLabel: this.state.isOpen ? this.i18n.t('select.close') : this.i18n.t('select.open'), "aria-controls": `select-listbox-${this.id}`, "aria-expanded": this.state.isOpen, tabIndex: -1, disabled: this.disabled || this.state.isResolving }))), this.hintSection, h("div", { class: "select-dropdown", ref: el => (this.dropdown = el), style: { display: this.state.isOpen ? 'block' : undefined } }, this.state.isOpen && (h("cat-scrollable", { class: "select-options-wrapper", scrolledBuffer: 56, noOverflowX: true, noOverscroll: true, noScrolledInit: true, onScrolledBottom: () => this.more$.next() }, h("ul", { class: "select-options", role: "listbox", "aria-multiselectable": this.multiple, "aria-setsize": this.state.totalElements, id: `select-listbox-${this.id}` }, this.optionsList, this.state.isLoading
721
772
  ? Array.from(Array(CatSelect.SKELETON_COUNT)).map(() => (h("li", { class: "select-option-loading" }, h("cat-skeleton", { variant: "body", lines: 1 }), h("cat-skeleton", { variant: "body", lines: 1 }))))
722
- : !this.state.options.length && h("li", { class: "select-option-empty" }, this.i18n.t('select.empty'))))))));
773
+ : !this.state.options.length &&
774
+ !this.tags && h("li", { class: "select-option-empty" }, this.i18n.t('select.empty'))))))));
775
+ }
776
+ get optionsList() {
777
+ return this.state.options.map((item, i) => {
778
+ const isTagOption = this.tags && item.item.id === `select-${this.id}-option-tag`;
779
+ const getAriaSelected = () => {
780
+ if (isTagOption) {
781
+ return this.isAlreadyCreated(item.render.label) ? 'true' : 'false';
782
+ }
783
+ return this.isSelected(item.item.id) ? 'true' : 'false';
784
+ };
785
+ const getLabel = () => {
786
+ if (isTagOption) {
787
+ return item.render.label + this.tagTextHelp;
788
+ }
789
+ return item.render.label;
790
+ };
791
+ return (h("li", { role: "option", class: "select-option", id: `select-${this.id}-option-${i}`, "aria-selected": getAriaSelected() }, this.multiple ? (h("cat-checkbox", { class: { 'select-option-active': this.state.activeOptionIndex === i }, checked: !isTagOption ? this.isSelected(item.item.id) : this.isAlreadyCreated(item.render.label), tabIndex: -1, labelLeft: true, onFocus: () => { var _a; return (_a = this.input) === null || _a === void 0 ? void 0 : _a.focus(); }, onCatChange: e => {
792
+ !isTagOption ? this.toggle(item) : this.toggleTag(item);
793
+ e.stopPropagation();
794
+ } }, h("span", { slot: "label", class: "select-option-inner" }, item.render.avatar ? (h("cat-avatar", { label: item.render.label, round: item.render.avatar.round, src: item.render.avatar.src, initials: '' })) : null, h("span", { class: "select-option-text" }, h("span", { class: "select-option-label" }, getLabel()), h("span", { class: "select-option-description" }, item.render.description))))) : (h("div", { class: {
795
+ 'select-option-inner': true,
796
+ 'select-option-single': true,
797
+ 'select-option-active': this.state.activeOptionIndex === i
798
+ }, onFocus: () => { var _a; return (_a = this.input) === null || _a === void 0 ? void 0 : _a.focus(); }, onClick: () => (isTagOption ? this.createTag(item.render.label) : this.select(item)), tabIndex: -1 }, item.render.avatar ? (h("cat-avatar", { label: item.render.label, round: item.render.avatar.round, src: item.render.avatar.src, initials: '' })) : null, h("span", { class: "select-option-text" }, h("span", { class: "select-option-label" }, getLabel()), h("span", { class: "select-option-description" }, item.render.description))))));
799
+ });
723
800
  }
724
801
  get hintSection() {
725
802
  const hasSlottedHint = !!this.hostElement.querySelector('[slot="hint"]');
@@ -732,21 +809,27 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
732
809
  throw new Error('CatSelectConnector not set');
733
810
  }
734
811
  resolve() {
735
- var _a;
736
812
  this.patchState({ isResolving: true });
737
- let ids;
738
- if (this.multiple) {
739
- ids = this.value;
740
- }
741
- else {
742
- ids = [this.value];
813
+ const ids = this.initIds();
814
+ let tags;
815
+ if (this.tags) {
816
+ tags = this.initTags();
743
817
  }
744
- const data$ = ((_a = this.value) === null || _a === void 0 ? void 0 : _a.length) ? this.connectorSafe.resolve(ids).pipe(first()) : of([]);
745
- data$.pipe(catchError(() => of([]))).subscribe(items => this.patchState({
746
- isResolving: false,
747
- selection: items === null || items === void 0 ? void 0 : items.map(item => ({ item, render: this.connectorSafe.render(item) })),
748
- term: !this.multiple && items.length ? this.connectorSafe.render(items[0]).label : ''
749
- }));
818
+ const data$ = ids.length ? this.connectorSafe.resolve(ids).pipe(first()) : of([]);
819
+ data$.pipe(catchError(() => of([]))).subscribe(items => {
820
+ const selection = items.length ? items === null || items === void 0 ? void 0 : items.map(item => ({ item, render: this.connectorSafe.render(item) })) : [];
821
+ if (this.tags) {
822
+ tags === null || tags === void 0 ? void 0 : tags.forEach((tag, index) => {
823
+ const item = { id: `select-${this.id}-tag-${index}`, name: tag };
824
+ selection.push({ item, render: { label: item.name } });
825
+ });
826
+ }
827
+ this.patchState({
828
+ isResolving: false,
829
+ selection,
830
+ term: !this.multiple && selection.length ? selection[0].render.label : ''
831
+ });
832
+ });
750
833
  }
751
834
  show() {
752
835
  var _a;
@@ -771,7 +854,6 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
771
854
  return this.state.selection.findIndex(s => s.item.id === id) >= 0;
772
855
  }
773
856
  select(item) {
774
- var _a;
775
857
  if (!this.isSelected(item.item.id)) {
776
858
  let newSelection;
777
859
  if (this.multiple) {
@@ -782,11 +864,13 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
782
864
  this.search(item.render.label);
783
865
  }
784
866
  this.patchState({ selection: newSelection });
867
+ if (this.multiple && this.state.term.trim() && this.input) {
868
+ this.patchState({ term: '', activeOptionIndex: -1 });
869
+ this.term$.next('');
870
+ this.input.value = '';
871
+ }
785
872
  }
786
- if (!this.multiple) {
787
- this.hide();
788
- (_a = this.input) === null || _a === void 0 ? void 0 : _a.classList.add('select-input-transparent-caret');
789
- }
873
+ this.setTransparentCaret();
790
874
  }
791
875
  deselect(id) {
792
876
  if (this.isSelected(id)) {
@@ -833,7 +917,12 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
833
917
  }
834
918
  onInput() {
835
919
  var _a;
836
- this.search(((_a = this.input) === null || _a === void 0 ? void 0 : _a.value) || '');
920
+ this.search(((_a = this.input) === null || _a === void 0 ? void 0 : _a.value.trim()) || '');
921
+ if (!this.multiple && this.state.selection.length) {
922
+ const selectionClone = [...this.state.selection];
923
+ selectionClone.pop();
924
+ this.patchState({ selection: selectionClone });
925
+ }
837
926
  this.show();
838
927
  }
839
928
  update() {
@@ -871,52 +960,122 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
871
960
  var _a, _b;
872
961
  let preventDefault = false;
873
962
  (_a = this.input) === null || _a === void 0 ? void 0 : _a.focus();
874
- if (event.key === 'ArrowDown') {
875
- preventDefault = true;
876
- this.state.isOpen
877
- ? this.patchState({
878
- activeOptionIndex: Math.min(this.state.activeOptionIndex + 1, this.state.options.length - 1),
879
- activeSelectionIndex: -1
880
- })
881
- : this.show();
882
- }
883
- else if (event.key === 'ArrowUp') {
884
- preventDefault = true;
885
- this.state.activeOptionIndex >= 0
886
- ? this.patchState({
887
- activeOptionIndex: Math.max(this.state.activeOptionIndex - 1, -1),
888
- activeSelectionIndex: -1
889
- })
890
- : this.hide();
891
- }
892
- else if (event.key === 'ArrowLeft') {
893
- if (((_b = this.input) === null || _b === void 0 ? void 0 : _b.selectionStart) === 0) {
963
+ switch (event.key) {
964
+ case 'ArrowDown':
894
965
  preventDefault = true;
895
- let index;
896
- this.state.activeSelectionIndex > 0
897
- ? (index = Math.max(this.state.activeSelectionIndex - 1, -1))
898
- : (index = this.state.selection.length - 1);
899
- this.patchState({ activeSelectionIndex: index, activeOptionIndex: -1 });
900
- }
901
- }
902
- else if (event.key === 'ArrowRight') {
903
- if (this.state.activeSelectionIndex >= 0) {
966
+ this.state.isOpen
967
+ ? this.patchState({
968
+ activeOptionIndex: Math.min(this.state.activeOptionIndex + 1, this.state.options.length - 1),
969
+ activeSelectionIndex: -1
970
+ })
971
+ : this.show();
972
+ break;
973
+ case 'ArrowUp':
904
974
  preventDefault = true;
905
- let index = -1;
906
- if (this.state.activeSelectionIndex < this.state.selection.length - 1) {
907
- index = Math.min(this.state.activeSelectionIndex + 1, this.state.selection.length - 1);
975
+ this.state.activeOptionIndex >= 0
976
+ ? this.patchState({
977
+ activeOptionIndex: Math.max(this.state.activeOptionIndex - 1, -1),
978
+ activeSelectionIndex: -1
979
+ })
980
+ : this.hide();
981
+ break;
982
+ case 'ArrowLeft':
983
+ if (((_b = this.input) === null || _b === void 0 ? void 0 : _b.selectionStart) === 0) {
984
+ preventDefault = true;
985
+ let index;
986
+ this.state.activeSelectionIndex > 0
987
+ ? (index = Math.max(this.state.activeSelectionIndex - 1, -1))
988
+ : (index = this.state.selection.length - 1);
989
+ this.patchState({ activeSelectionIndex: index, activeOptionIndex: -1 });
908
990
  }
909
- else if (!this.state.term) {
910
- index = 0;
991
+ break;
992
+ case 'ArrowRight':
993
+ if (this.state.activeSelectionIndex >= 0) {
994
+ preventDefault = true;
995
+ let index = -1;
996
+ if (this.state.activeSelectionIndex < this.state.selection.length - 1) {
997
+ index = Math.min(this.state.activeSelectionIndex + 1, this.state.selection.length - 1);
998
+ }
999
+ else if (!this.state.term) {
1000
+ index = 0;
1001
+ }
1002
+ this.patchState({ activeSelectionIndex: index, activeOptionIndex: -1 });
911
1003
  }
912
- this.patchState({ activeSelectionIndex: index, activeOptionIndex: -1 });
913
- }
914
1004
  }
915
1005
  if (preventDefault) {
916
1006
  event.preventDefault();
917
1007
  event.stopPropagation();
918
1008
  }
919
1009
  }
1010
+ get tagTextHelp() {
1011
+ return this.tagHint && !this.isAlreadyCreated(this.state.term) ? ' (' + this.tagHint + ')' : '';
1012
+ }
1013
+ isAlreadyCreated(term) {
1014
+ return this.state.selection.findIndex(item => item.render.label.toLowerCase() === term.toLowerCase()) >= 0;
1015
+ }
1016
+ createTag(term) {
1017
+ if (term.trim().length && !this.isAlreadyCreated(term)) {
1018
+ const value = this.value;
1019
+ const tags = value === null || value === void 0 ? void 0 : value.tags;
1020
+ const tag = { id: `select-${this.id}-tag-${tags ? tags.length : 0}`, name: term };
1021
+ this.select({ item: tag, render: { label: tag.name } });
1022
+ }
1023
+ this.setTransparentCaret();
1024
+ }
1025
+ initIds() {
1026
+ let ids = [];
1027
+ if (this.value) {
1028
+ if (!this.tags) {
1029
+ if (this.multiple) {
1030
+ ids = this.value;
1031
+ }
1032
+ else {
1033
+ ids = [this.value];
1034
+ }
1035
+ }
1036
+ else {
1037
+ if (this.multiple) {
1038
+ const value = this.value;
1039
+ ids = value.ids ? value.ids : [];
1040
+ }
1041
+ else {
1042
+ const value = this.value;
1043
+ ids = value.id ? [value.id] : [];
1044
+ }
1045
+ }
1046
+ }
1047
+ return ids;
1048
+ }
1049
+ initTags() {
1050
+ let tags = [];
1051
+ if (this.value) {
1052
+ if (this.multiple) {
1053
+ const value = this.value;
1054
+ tags = value.tags ? value.tags : [];
1055
+ }
1056
+ else {
1057
+ const value = this.value;
1058
+ tags = value.tag ? [value.tag] : [];
1059
+ }
1060
+ }
1061
+ return tags;
1062
+ }
1063
+ toggleTag(item) {
1064
+ this.isAlreadyCreated(item.render.label) ? this.removeTag(item.render.label) : this.createTag(item.render.label);
1065
+ }
1066
+ removeTag(label) {
1067
+ if (this.isAlreadyCreated(label)) {
1068
+ const item = this.state.selection.find(item => item.render.label.toLowerCase() === label.toLowerCase());
1069
+ item && this.deselect(item.item.id);
1070
+ }
1071
+ }
1072
+ setTransparentCaret() {
1073
+ var _a;
1074
+ if (!this.multiple) {
1075
+ this.hide();
1076
+ (_a = this.input) === null || _a === void 0 ? void 0 : _a.classList.add('select-input-transparent-caret');
1077
+ }
1078
+ }
920
1079
  get hostElement() { return this; }
921
1080
  static get watchers() { return {
922
1081
  "connector": ["onConnectorChange"],
@@ -936,6 +1095,8 @@ const CatSelect = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
936
1095
  "labelHidden": [4, "label-hidden"],
937
1096
  "required": [4],
938
1097
  "clearable": [4],
1098
+ "tags": [4],
1099
+ "tagHint": [1, "tag-hint"],
939
1100
  "connector": [32],
940
1101
  "state": [32],
941
1102
  "hasSlottedLabel": [32],