@lion/ui 0.1.3 → 0.1.5

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 (107) hide show
  1. package/README.md +222 -0
  2. package/components/combobox/src/LionCombobox.js +107 -68
  3. package/components/combobox/src/utils/makeMatchingTextBold.js +68 -0
  4. package/components/combobox/test/lion-combobox.test.js +210 -4
  5. package/components/combobox/translations/bg.js +3 -0
  6. package/components/combobox/translations/cs.js +3 -0
  7. package/components/combobox/translations/de.js +3 -0
  8. package/components/combobox/translations/en.js +3 -0
  9. package/components/combobox/translations/es.js +3 -0
  10. package/components/combobox/translations/fr.js +3 -0
  11. package/components/combobox/translations/hu.js +3 -0
  12. package/components/combobox/translations/it.js +3 -0
  13. package/components/combobox/translations/nl.js +3 -0
  14. package/components/combobox/translations/pl.js +3 -0
  15. package/components/combobox/translations/ro.js +3 -0
  16. package/components/combobox/translations/ru.js +3 -0
  17. package/components/combobox/translations/sk.js +3 -0
  18. package/components/combobox/translations/uk.js +3 -0
  19. package/components/combobox/translations/zh.js +3 -0
  20. package/custom-elements.json +668 -0
  21. package/dist-types/components/combobox/src/LionCombobox.d.ts +14 -1
  22. package/dist-types/components/combobox/src/LionCombobox.d.ts.map +1 -1
  23. package/dist-types/components/combobox/src/utils/makeMatchingTextBold.d.ts +10 -0
  24. package/dist-types/components/combobox/src/utils/makeMatchingTextBold.d.ts.map +1 -0
  25. package/dist-types/components/combobox/test/lion-combobox.test.d.ts +1 -0
  26. package/dist-types/components/combobox/test/lion-combobox.test.d.ts.map +1 -1
  27. package/dist-types/components/combobox/translations/bg.d.ts +5 -0
  28. package/dist-types/components/combobox/translations/bg.d.ts.map +1 -0
  29. package/dist-types/components/combobox/translations/cs.d.ts +5 -0
  30. package/dist-types/components/combobox/translations/cs.d.ts.map +1 -0
  31. package/dist-types/components/combobox/translations/de.d.ts +5 -0
  32. package/dist-types/components/combobox/translations/de.d.ts.map +1 -0
  33. package/dist-types/components/combobox/translations/en.d.ts +5 -0
  34. package/dist-types/components/combobox/translations/en.d.ts.map +1 -0
  35. package/dist-types/components/combobox/translations/es.d.ts +5 -0
  36. package/dist-types/components/combobox/translations/es.d.ts.map +1 -0
  37. package/dist-types/components/combobox/translations/fr.d.ts +5 -0
  38. package/dist-types/components/combobox/translations/fr.d.ts.map +1 -0
  39. package/dist-types/components/combobox/translations/hu.d.ts +5 -0
  40. package/dist-types/components/combobox/translations/hu.d.ts.map +1 -0
  41. package/dist-types/components/combobox/translations/it.d.ts +5 -0
  42. package/dist-types/components/combobox/translations/it.d.ts.map +1 -0
  43. package/dist-types/components/combobox/translations/nl.d.ts +5 -0
  44. package/dist-types/components/combobox/translations/nl.d.ts.map +1 -0
  45. package/dist-types/components/combobox/translations/pl.d.ts +5 -0
  46. package/dist-types/components/combobox/translations/pl.d.ts.map +1 -0
  47. package/dist-types/components/combobox/translations/ro.d.ts +5 -0
  48. package/dist-types/components/combobox/translations/ro.d.ts.map +1 -0
  49. package/dist-types/components/combobox/translations/ru.d.ts +5 -0
  50. package/dist-types/components/combobox/translations/ru.d.ts.map +1 -0
  51. package/dist-types/components/combobox/translations/sk.d.ts +5 -0
  52. package/dist-types/components/combobox/translations/sk.d.ts.map +1 -0
  53. package/dist-types/components/combobox/translations/uk.d.ts +5 -0
  54. package/dist-types/components/combobox/translations/uk.d.ts.map +1 -0
  55. package/dist-types/components/combobox/translations/zh.d.ts +5 -0
  56. package/dist-types/components/combobox/translations/zh.d.ts.map +1 -0
  57. package/dist-types/exports/combobox.d.ts +1 -0
  58. package/dist-types/tsconfig.tsbuildinfo +1 -1
  59. package/docs/components/checkbox-group/overview.md +2 -2
  60. package/docs/components/collapsible/overview.md +1 -1
  61. package/docs/components/combobox/overview.md +1 -1
  62. package/docs/components/combobox/use-cases.md +40 -16
  63. package/docs/components/dialog/overview.md +1 -1
  64. package/docs/components/fieldset/overview.md +5 -5
  65. package/docs/components/form/overview.md +3 -3
  66. package/docs/components/icon/use-cases.md +1 -1
  67. package/docs/components/input/overview.md +1 -1
  68. package/docs/components/input-amount/overview.md +3 -3
  69. package/docs/components/input-date/overview.md +3 -3
  70. package/docs/components/input-datepicker/overview.md +5 -5
  71. package/docs/components/input-email/overview.md +2 -2
  72. package/docs/components/input-iban/overview.md +2 -2
  73. package/docs/components/input-range/overview.md +2 -2
  74. package/docs/components/input-stepper/overview.md +1 -1
  75. package/docs/components/input-tel/overview.md +1 -1
  76. package/docs/components/input-tel/use-cases.md +6 -6
  77. package/docs/components/input-tel-dropdown/overview.md +1 -1
  78. package/docs/components/listbox/src/listboxData.js +66 -0
  79. package/docs/components/radio-group/overview.md +3 -3
  80. package/docs/components/select-rich/use-cases.md +1 -1
  81. package/docs/components/tabs/examples.md +1 -1
  82. package/docs/fundamentals/index.md +4 -4
  83. package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +1 -1
  84. package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +1 -1
  85. package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +1 -1
  86. package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +1 -1
  87. package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
  88. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  89. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  90. package/docs/fundamentals/systems/core/overview.md +1 -1
  91. package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
  92. package/docs/fundamentals/systems/form/model-value.md +1 -1
  93. package/docs/fundamentals/systems/form/overview.md +28 -28
  94. package/docs/fundamentals/systems/form/validate.md +1 -1
  95. package/docs/fundamentals/systems/localize/overview.md +4 -4
  96. package/docs/fundamentals/systems/overlays/configuration.md +2 -2
  97. package/docs/fundamentals/systems/overlays/overview.md +5 -5
  98. package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
  99. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  100. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  101. package/docs/guides/how-to/create-a-custom-field.md +5 -5
  102. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  103. package/docs/guides/index.md +8 -8
  104. package/docs/guides/principles/index.md +5 -5
  105. package/docs/guides/principles/styling.md +1 -1
  106. package/exports/combobox.js +4 -0
  107. package/package.json +9 -1
@@ -13,6 +13,7 @@ import { LionCombobox } from '@lion/ui/combobox.js';
13
13
  * @typedef {import('../types/SelectionDisplay.js').SelectionDisplay} SelectionDisplay
14
14
  * @typedef {import('../../listbox/types/ListboxMixinTypes.js').ListboxHost} ListboxHost
15
15
  * @typedef {import('../../form-core/types/FormControlMixinTypes.js').FormControlHost} FormControlHost
16
+ * @typedef {import('@lion/ui/listbox.js').LionOption} LionOption
16
17
  */
17
18
 
18
19
  /**
@@ -669,6 +670,25 @@ describe('lion-combobox', () => {
669
670
  expect(el.checkedIndex).to.equal(-1);
670
671
  });
671
672
 
673
+ it('has the correct Overlay Config defined', async () => {
674
+ const el = /** @type {LionCombobox} */ (
675
+ await fixture(html`
676
+ <lion-combobox name="foo" .showAllOnEmpty="${true}">
677
+ <lion-option .choiceValue="${'Artichoke'}">Artichoke</lion-option>
678
+ <lion-option .choiceValue="${'Chard'}">Chard</lion-option>
679
+ <lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
680
+ <lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
681
+ </lion-combobox>
682
+ `)
683
+ );
684
+ // @ts-ignore [allow-protected] in test
685
+ expect(el._defineOverlayConfig().elementToFocusAfterHide).to.equal(undefined);
686
+ // @ts-ignore [allow-protected] in test
687
+ expect(el._defineOverlayConfig().invokerNode).to.equal(el._inputNode);
688
+ // @ts-ignore [allow-protected] in test
689
+ expect(el._defineOverlayConfig().visibilityTriggerFunction).to.equal(undefined);
690
+ });
691
+
672
692
  // NB: If this becomes a suite, move to separate file
673
693
  describe('Subclassers', () => {
674
694
  it('allows to control overlay visibility via "_showOverlayCondition"', async () => {
@@ -879,8 +899,26 @@ describe('lion-combobox', () => {
879
899
 
880
900
  expect(el.checkedIndex).to.equal(-1);
881
901
  await el.feedbackComplete;
882
- expect(el.hasFeedbackFor).to.include('error');
883
- expect(el.showsFeedbackFor).to.include('error');
902
+ expect(el.hasFeedbackFor).to.include('error', 'hasFeedbackFor');
903
+ await el.feedbackComplete;
904
+ expect(el.showsFeedbackFor).to.include('error', 'showsFeedbackFor');
905
+ });
906
+
907
+ it('dropdown has a label', async () => {
908
+ const el = /** @type {LionCombobox} */ (
909
+ await fixture(html`
910
+ <lion-combobox name="foo" .validators=${[new Required()]}>
911
+ <lion-option checked .choiceValue="${'Artichoke'}">Artichoke</lion-option>
912
+ <lion-option .choiceValue="${'Chard'}">Chard</lion-option>
913
+ <lion-option .choiceValue="${'Chicory'}">Chicory</lion-option>
914
+ <lion-option .choiceValue="${'Victoria Plum'}">Victoria Plum</lion-option>
915
+ </lion-combobox>
916
+ `)
917
+ );
918
+ const { _overlayCtrl } = getComboboxMembers(el);
919
+ expect(_overlayCtrl.contentWrapperNode.getAttribute('aria-label')).to.equal(
920
+ 'Combobox options popup',
921
+ );
884
922
  });
885
923
  });
886
924
  });
@@ -1341,6 +1379,7 @@ describe('lion-combobox', () => {
1341
1379
  `)
1342
1380
  );
1343
1381
  const { _inputNode } = getComboboxMembers(el);
1382
+ await el.updateComplete;
1344
1383
  expect(_inputNode.value).to.equal('');
1345
1384
 
1346
1385
  /**
@@ -1355,9 +1394,10 @@ describe('lion-combobox', () => {
1355
1394
  await el.updateComplete;
1356
1395
  el.autocomplete = autocomplete;
1357
1396
  el.setCheckedIndex(index);
1397
+ await el.updateComplete;
1358
1398
  el.opened = false;
1359
1399
  await el.updateComplete;
1360
- expect(_inputNode.value).to.equal(valueOnClose);
1400
+ expect(_inputNode.value).to.equal(valueOnClose, autocomplete);
1361
1401
  }
1362
1402
 
1363
1403
  await performChecks('none', 0, 'Artichoke');
@@ -1632,7 +1672,7 @@ describe('lion-combobox', () => {
1632
1672
  });
1633
1673
  });
1634
1674
 
1635
- it('highlights matching options', async () => {
1675
+ it('highlights first occcurence of matching option', async () => {
1636
1676
  const el = /** @type {LionCombobox} */ (
1637
1677
  await fixture(html`
1638
1678
  <lion-combobox name="foo" match-mode="all">
@@ -1645,6 +1685,16 @@ describe('lion-combobox', () => {
1645
1685
  );
1646
1686
  const options = el.formElements;
1647
1687
 
1688
+ mimicUserTyping(/** @type {LionCombobox} */ (el), 'c');
1689
+
1690
+ await el.updateComplete;
1691
+ expect(options[0]).lightDom.to.equal(`<span aria-label="Artichoke">Arti<b>c</b>hoke</span>`);
1692
+ expect(options[1]).lightDom.to.equal(`<span aria-label="Chard"><b>C</b>hard</span>`);
1693
+ expect(options[2]).lightDom.to.equal(`<span aria-label="Chicory"><b>C</b>hicory</span>`);
1694
+ expect(options[3]).lightDom.to.equal(
1695
+ `<span aria-label="Victoria Plum">Vi<b>c</b>toria Plum</span>`,
1696
+ );
1697
+
1648
1698
  mimicUserTyping(/** @type {LionCombobox} */ (el), 'ch');
1649
1699
 
1650
1700
  await el.updateComplete;
@@ -1662,6 +1712,48 @@ describe('lion-combobox', () => {
1662
1712
  expect(options[3]).lightDom.to.equal(`Victoria Plum`);
1663
1713
  });
1664
1714
 
1715
+ it('highlights matching complex options', async () => {
1716
+ const el = /** @type {LionCombobox} */ (
1717
+ await fixture(html`
1718
+ <lion-combobox name="foo" match-mode="all">
1719
+ <lion-option .choiceValue="${'Artichoke'}">
1720
+ <div>Artichoke</div>
1721
+ <small>Cardoon</small>
1722
+ </lion-option>
1723
+ <lion-option .choiceValue="${'Chard'}">
1724
+ <div>Chard</div>
1725
+ <small>Beet</small>
1726
+ </lion-option>
1727
+ <lion-option .choiceValue="${'Chicory'}">
1728
+ <div>Chicory</div>
1729
+ <small>Chicory</small>
1730
+ </lion-option>
1731
+ <lion-option .choiceValue="${'Victoria Plum'}">
1732
+ <div>Victoria Plum</div>
1733
+ <small>Prunus domestica</small>
1734
+ </lion-option>
1735
+ </lion-combobox>
1736
+ `)
1737
+ );
1738
+ const options = el.formElements;
1739
+
1740
+ mimicUserTyping(/** @type {LionCombobox} */ (el), 'ch');
1741
+
1742
+ await el.updateComplete;
1743
+ expect(options[0]).lightDom.to.equal(
1744
+ `<span aria-label=" Artichoke Cardoon "><div>Arti<b>ch</b>oke</div><small>Cardoon</small>`,
1745
+ );
1746
+ expect(options[1]).lightDom.to.equal(
1747
+ `<span aria-label=" Chard Beet "><div><b>Ch</b>ard</div><small>Beet</small>`,
1748
+ );
1749
+ expect(options[2]).lightDom.to.equal(
1750
+ `<span aria-label=" Chicory Chicory "><div><b>Ch</b>icory</div><small><b>Ch</b>icory</small>`,
1751
+ );
1752
+ expect(options[3]).lightDom.to.equal(
1753
+ `<div>Victoria Plum</div><small>Prunus domestica</small>`,
1754
+ );
1755
+ });
1756
+
1665
1757
  it('synchronizes textbox when autocomplete is "inline" or "both"', async () => {
1666
1758
  const el = /** @type {LionCombobox} */ (
1667
1759
  await fixture(html`
@@ -1977,6 +2069,8 @@ describe('lion-combobox', () => {
1977
2069
  const { _inputNode } = getComboboxMembers(el);
1978
2070
 
1979
2071
  async function performChecks() {
2072
+ await el.updateComplete;
2073
+
1980
2074
  el.formElements[0].click();
1981
2075
  await el.updateComplete;
1982
2076
 
@@ -1999,6 +2093,98 @@ describe('lion-combobox', () => {
1999
2093
  await performChecks();
2000
2094
  });
2001
2095
  });
2096
+
2097
+ it('allows to override "_onFilterMatch" and "_onFilterUmatch"', async () => {
2098
+ class X extends LionCombobox {
2099
+ /**
2100
+ * @overridable
2101
+ * @param {LionOption & {__originalInnerHTML?:string}} option
2102
+ * @param {string} matchingString
2103
+ * @protected
2104
+ */
2105
+ _onFilterMatch(option, matchingString) {
2106
+ Array.from(option.children).forEach(child => {
2107
+ if (child.hasAttribute('data-key')) {
2108
+ this._highlightMatchedOption(child, matchingString);
2109
+ }
2110
+ });
2111
+ // Alternatively, an extension can add an animation here
2112
+ // option.style.display = '';
2113
+ }
2114
+
2115
+ /**
2116
+ * @overridable
2117
+ * @param {LionOption & {__originalInnerHTML?:string}} option
2118
+ * @param {string} [curValue]
2119
+ * @param {string} [prevValue]
2120
+ * @protected
2121
+ */
2122
+ // eslint-disable-next-line no-unused-vars
2123
+ _onFilterUnmatch(option, curValue, prevValue) {
2124
+ Array.from(option.children).forEach(child => {
2125
+ if (child.hasAttribute('data-key')) {
2126
+ this._unhighlightMatchedOption(child);
2127
+ }
2128
+ });
2129
+ // Alternatively, an extension can add an animation here
2130
+ // option.style.display = 'none';
2131
+ }
2132
+ }
2133
+ const tagName = defineCE(X);
2134
+ const tag = unsafeStatic(tagName);
2135
+
2136
+ const el = /** @type {LionCombobox} */ (
2137
+ await fixture(html`
2138
+ <${tag} name="foo" autocomplete="both">
2139
+ <lion-option .choiceValue="${'Artichoke'}">
2140
+ <div data-key>Artichoke</div>
2141
+ <small>Cardoon</small>
2142
+ </lion-option>
2143
+ <lion-option .choiceValue="${'Chard'}">
2144
+ <div data-key>Chard</div>
2145
+ <small>Beet</small>
2146
+ </lion-option>
2147
+ <lion-option .choiceValue="${'Chicory'}">
2148
+ <div data-key>Chicory</div>
2149
+ <small>Chicory</small>
2150
+ </lion-option>
2151
+ <lion-option .choiceValue="${'Victoria Plum'}">
2152
+ <div data-key>Victoria Plum</div>
2153
+ <small>Prunus domestica</small>
2154
+ </lion-option>
2155
+ </${tag}>
2156
+ `)
2157
+ );
2158
+ const options = el.formElements;
2159
+
2160
+ mimicUserTyping(/** @type {LionCombobox} */ (el), 'ch');
2161
+
2162
+ await el.updateComplete;
2163
+ expect(options[0]).lightDom.to.equal(
2164
+ `<div data-key><span aria-label="Artichoke">Arti<b>ch</b>oke</span></div><small>Cardoon</small>`,
2165
+ );
2166
+ expect(options[1]).lightDom.to.equal(
2167
+ `<div data-key><span aria-label="Chard"><b>Ch</b>ard</div></span><small>Beet</small>`,
2168
+ );
2169
+ expect(options[2]).lightDom.to.equal(
2170
+ `<div data-key><span aria-label="Chicory"><b>Ch</b>icory</span></div><small>Chicory</small>`,
2171
+ );
2172
+ expect(options[3]).lightDom.to.equal(
2173
+ `<div data-key>Victoria Plum</div><small>Prunus domestica</small>`,
2174
+ );
2175
+
2176
+ mimicUserTyping(/** @type {LionCombobox} */ (el), 'D');
2177
+
2178
+ await el.updateComplete;
2179
+ expect(options[0]).lightDom.to.equal(`<div data-key>Artichoke</div><small>Cardoon</small>`);
2180
+ expect(options[1]).lightDom.to.equal(
2181
+ `<div data-key><span aria-label="Chard">Char<b>d</b></div></span><small>Beet</small>`,
2182
+ );
2183
+ expect(options[2]).lightDom.to.equal(`<div data-key>Chicory</div><small>Chicory</small>`);
2184
+ expect(options[3]).lightDom.to.equal(
2185
+ `<div data-key>Victoria Plum</div><small>Prunus domestica</small>`,
2186
+ );
2187
+ });
2002
2188
  });
2003
2189
 
2004
2190
  describe('Active index behavior', () => {
@@ -2278,6 +2464,26 @@ describe('lion-combobox', () => {
2278
2464
  expect(labelledElement).to.not.be.null;
2279
2465
  expect(labelledElement.innerText).to.equal('Artichoke');
2280
2466
  });
2467
+
2468
+ it('adds aria-label to highlighted complex options', async () => {
2469
+ const el = /** @type {LionCombobox} */ (
2470
+ await fixture(html`
2471
+ <lion-combobox name="foo" match-mode="all">
2472
+ <lion-option .choiceValue="${'Artichoke'}">
2473
+ <div>Artichoke</div>
2474
+ <small>Cardoon</small>
2475
+ </lion-option>
2476
+ </lion-combobox>
2477
+ `)
2478
+ );
2479
+ const options = el.formElements;
2480
+
2481
+ mimicUserTyping(/** @type {LionCombobox} */ (el), 'choke');
2482
+ await el.updateComplete;
2483
+ const labelledElement = options[0].querySelector('span[aria-label=" Artichoke Cardoon "]');
2484
+ expect(labelledElement).to.not.be.null;
2485
+ expect(labelledElement.innerText).to.equal('Artichoke\nCardoon');
2486
+ });
2281
2487
  });
2282
2488
  });
2283
2489
 
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Изскачащ прозорец за опции за комбинирано поле',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Vyskakovací okno možností ComboBox',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Popup-Fenster für Kombibox-Optionen',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Combobox options popup',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Ventana emergente de opciones de cuadro combinado',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Fenêtre popup des options de la boîte combinée',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Kombinált lista opcióinak felugró ablaka',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Finestra a comparsa opzioni ComboBox',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Pop-up van opties',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Wyskakujące okno opcji pola wyboru',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Fereastra pop-up cu opţiuni Combobox',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Всплывающее окно параметров поля со списком',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Vyskakovacie okno možností kombinovaného poľa',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: 'Спливаюче вікно параметрів поля зі списком',
3
+ };
@@ -0,0 +1,3 @@
1
+ export default {
2
+ optionsPopup: '组合框选项弹出框',
3
+ };