@lion/ui 0.1.1 → 0.1.3

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 (74) hide show
  1. package/components/form-integrations/test/form-group-methods.test.js +3 -3
  2. package/components/form-integrations/test/form-integrations.test.js +3 -3
  3. package/components/form-integrations/test/helpers/umbrella-form.js +3 -3
  4. package/components/localize/src/LocalizeManager.js +19 -3
  5. package/components/localize/test/LocalizeManager.test.js +18 -1
  6. package/components/select-rich/src/LionSelectRich.js +6 -0
  7. package/components/select-rich/test/lion-select-rich.test.js +33 -0
  8. package/custom-elements.json +379 -0
  9. package/dist-types/components/localize/src/LocalizeManager.d.ts +6 -2
  10. package/dist-types/components/localize/src/LocalizeManager.d.ts.map +1 -1
  11. package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
  12. package/dist-types/exports/types/core.d.ts +5 -0
  13. package/dist-types/exports/types/core.d.ts.map +1 -1
  14. package/dist-types/exports/types/form-core.d.ts +16 -0
  15. package/dist-types/exports/types/form-core.d.ts.map +1 -1
  16. package/dist-types/exports/types/localize.d.ts +1 -0
  17. package/dist-types/exports/types/localize.d.ts.map +1 -1
  18. package/dist-types/exports/types/overlays.d.ts +1 -0
  19. package/dist-types/exports/types/overlays.d.ts.map +1 -1
  20. package/dist-types/tsconfig.tsbuildinfo +1 -1
  21. package/docs/components/checkbox-group/overview.md +2 -2
  22. package/docs/components/collapsible/overview.md +1 -1
  23. package/docs/components/combobox/overview.md +1 -1
  24. package/docs/components/combobox/use-cases.md +1 -1
  25. package/docs/components/dialog/overview.md +1 -1
  26. package/docs/components/fieldset/overview.md +5 -5
  27. package/docs/components/form/overview.md +3 -3
  28. package/docs/components/form/use-cases.md +2 -2
  29. package/docs/components/icon/use-cases.md +1 -1
  30. package/docs/components/input/overview.md +1 -1
  31. package/docs/components/input-amount/overview.md +3 -3
  32. package/docs/components/input-date/overview.md +3 -3
  33. package/docs/components/input-datepicker/overview.md +5 -5
  34. package/docs/components/input-email/overview.md +2 -2
  35. package/docs/components/input-iban/overview.md +2 -2
  36. package/docs/components/input-range/overview.md +2 -2
  37. package/docs/components/input-stepper/overview.md +1 -1
  38. package/docs/components/input-tel/overview.md +1 -1
  39. package/docs/components/input-tel/use-cases.md +6 -6
  40. package/docs/components/input-tel-dropdown/overview.md +1 -1
  41. package/docs/components/radio-group/overview.md +3 -3
  42. package/docs/components/select-rich/use-cases.md +1 -1
  43. package/docs/components/tabs/examples.md +1 -1
  44. package/docs/fundamentals/index.md +4 -4
  45. package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +1 -1
  46. package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +1 -1
  47. package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +1 -1
  48. package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +1 -1
  49. package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
  50. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  51. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  52. package/docs/fundamentals/systems/core/overview.md +1 -1
  53. package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
  54. package/docs/fundamentals/systems/form/model-value.md +1 -1
  55. package/docs/fundamentals/systems/form/overview.md +28 -28
  56. package/docs/fundamentals/systems/form/use-cases.md +3 -3
  57. package/docs/fundamentals/systems/form/validate.md +1 -1
  58. package/docs/fundamentals/systems/localize/overview.md +4 -4
  59. package/docs/fundamentals/systems/overlays/assets/umbrella-form.js +3 -3
  60. package/docs/fundamentals/systems/overlays/configuration.md +2 -2
  61. package/docs/fundamentals/systems/overlays/overview.md +5 -5
  62. package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
  63. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  64. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  65. package/docs/guides/how-to/create-a-custom-field.md +5 -5
  66. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  67. package/docs/guides/index.md +8 -8
  68. package/docs/guides/principles/index.md +5 -5
  69. package/docs/guides/principles/styling.md +1 -1
  70. package/exports/types/core.ts +5 -0
  71. package/exports/types/form-core.ts +16 -0
  72. package/exports/types/localize.ts +1 -0
  73. package/exports/types/overlays.ts +1 -0
  74. package/package.json +1 -1
@@ -45,7 +45,7 @@ import '@lion/ui/define/lion-validation-feedback.js';
45
45
  */
46
46
 
47
47
  const fullyPrefilledSerializedValue = {
48
- full_name: { first_name: 'Lorem', last_name: 'Ipsum' },
48
+ fullName: { firstName: 'Lorem', lastName: 'Ipsum' },
49
49
  date: '2000-12-12',
50
50
  datepicker: '2020-12-12',
51
51
  bio: 'Lorem',
@@ -69,7 +69,7 @@ const fullyPrefilledSerializedValue = {
69
69
  };
70
70
 
71
71
  const fullyChangedSerializedValue = {
72
- full_name: { first_name: 'LoremChanged', last_name: 'IpsumChanged' },
72
+ fullName: { firstName: 'LoremChanged', lastName: 'IpsumChanged' },
73
73
  date: '1999-12-12',
74
74
  datepicker: '1986-12-12',
75
75
  bio: 'LoremChanged',
@@ -177,7 +177,7 @@ describe(`Submitting/Resetting/Clearing Form`, async () => {
177
177
  await elementUpdated(formEl);
178
178
  await formEl.updateComplete;
179
179
  expect(formEl.serializedValue).to.eql({
180
- full_name: { first_name: '', last_name: '' },
180
+ fullName: { firstName: '', lastName: '' },
181
181
  date: '',
182
182
  datepicker: '',
183
183
  bio: '',
@@ -29,7 +29,7 @@ describe('Form Integrations', () => {
29
29
  const formEl = el._lionFormNode;
30
30
 
31
31
  expect(formEl.serializedValue).to.eql({
32
- full_name: { first_name: '', last_name: '' },
32
+ fullName: { firstName: '', lastName: '' },
33
33
  date: '2000-12-12',
34
34
  datepicker: '2020-12-12',
35
35
  bio: '',
@@ -62,7 +62,7 @@ describe('Form Integrations', () => {
62
62
  await inputTelDropdownEl?.updateComplete;
63
63
 
64
64
  expect(formEl.formattedValue).to.eql({
65
- full_name: { first_name: '', last_name: '' },
65
+ fullName: { firstName: '', lastName: '' },
66
66
  date: '12/12/2000',
67
67
  datepicker: '12/12/2020',
68
68
  bio: '',
@@ -91,7 +91,7 @@ describe('Form Integrations', () => {
91
91
  await fixture(
92
92
  html`<umbrella-form
93
93
  .serializedValue="${{
94
- full_name: { first_name: '', last_name: '' },
94
+ fullName: { firstName: '', lastName: '' },
95
95
  date: '2000-12-12',
96
96
  datepicker: '2020-12-12',
97
97
  bio: '',
@@ -50,14 +50,14 @@ export class UmbrellaForm extends LitElement {
50
50
  return html`
51
51
  <lion-form .serializedValue="${this.__serializedValue}">
52
52
  <form>
53
- <lion-fieldset name="full_name">
53
+ <lion-fieldset name="fullName">
54
54
  <lion-input
55
- name="first_name"
55
+ name="firstName"
56
56
  label="First Name"
57
57
  .validators="${[new Required()]}"
58
58
  ></lion-input>
59
59
  <lion-input
60
- name="last_name"
60
+ name="lastName"
61
61
  label="Last Name"
62
62
  .validators="${[new Required()]}"
63
63
  ></lion-input>
@@ -18,6 +18,7 @@ export class LocalizeManager {
18
18
  autoLoadOnLocaleChange = false,
19
19
  fallbackLocale = '',
20
20
  showKeyAsFallback = false,
21
+ allowOverridesForExistingNamespaces = false,
21
22
  } = {}) {
22
23
  /** @private */
23
24
  this.__delegationTarget = document.createDocumentFragment();
@@ -28,6 +29,9 @@ export class LocalizeManager {
28
29
  /** @protected */
29
30
  this._showKeyAsFallback = showKeyAsFallback;
30
31
 
32
+ /** @private */
33
+ this.__allowOverridesForExistingNamespaces = allowOverridesForExistingNamespaces;
34
+
31
35
  /**
32
36
  * @type {Object.<string, Object.<string, Object>>}
33
37
  * @private
@@ -199,17 +203,29 @@ export class LocalizeManager {
199
203
  * @param {string} locale
200
204
  * @param {string} namespace
201
205
  * @param {object} data
202
- * @throws {Error} Namespace can be added only once, for a given locale
206
+ * @throws {Error} Namespace can be added only once, for a given locale unless allowOverridesForExistingNamespaces
207
+ * is set to `true`
203
208
  */
204
209
  addData(locale, namespace, data) {
205
- if (this._isNamespaceInCache(locale, namespace)) {
210
+ if (
211
+ !this.__allowOverridesForExistingNamespaces &&
212
+ this._isNamespaceInCache(locale, namespace)
213
+ ) {
206
214
  throw new Error(
207
215
  `Namespace "${namespace}" has been already added for the locale "${locale}".`,
208
216
  );
209
217
  }
210
218
 
211
219
  this.__storage[locale] = this.__storage[locale] || {};
212
- this.__storage[locale][namespace] = data;
220
+
221
+ if (this.__allowOverridesForExistingNamespaces) {
222
+ this.__storage[locale][namespace] = {
223
+ ...this.__storage[locale][namespace],
224
+ ...data,
225
+ };
226
+ } else {
227
+ this.__storage[locale][namespace] = data;
228
+ }
213
229
  }
214
230
 
215
231
  /**
@@ -155,7 +155,7 @@ describe('LocalizeManager', () => {
155
155
  });
156
156
  });
157
157
 
158
- it('prevents mutating existing data for the same locale & namespace', () => {
158
+ it('prevents mutating existing data for the same locale & namespace when "allowOverridesForExistingNamespaces" option is not given in constructor', () => {
159
159
  manager = new LocalizeManager();
160
160
  const { storage } = getProtectedMembers(manager);
161
161
 
@@ -169,6 +169,23 @@ describe('LocalizeManager', () => {
169
169
  'en-GB': { 'lion-hello': { greeting: 'Hi!' } },
170
170
  });
171
171
  });
172
+
173
+ it('allows mutating existing data for the same locale & namespace when "allowOverridesForExistingNamespaces" option is set to "true" in constructor', () => {
174
+ manager = new LocalizeManager({ allowOverridesForExistingNamespaces: true });
175
+ const { storage } = getProtectedMembers(manager);
176
+
177
+ manager.addData('en-GB', 'lion-hello', { greeting: 'Hi!' });
178
+
179
+ expect(storage).to.deep.equal({
180
+ 'en-GB': { 'lion-hello': { greeting: 'Hi!' } },
181
+ });
182
+
183
+ manager.addData('en-GB', 'lion-hello', { greeting: 'Hi!', alternative: 'Hello!' });
184
+
185
+ expect(storage).to.deep.equal({
186
+ 'en-GB': { 'lion-hello': { greeting: 'Hi!', alternative: 'Hello!' } },
187
+ });
188
+ });
172
189
  });
173
190
 
174
191
  describe('loading via dynamic imports', () => {
@@ -369,6 +369,11 @@ export class LionSelectRich extends SlotMixin(ScopedElementsMixin(OverlayMixin(L
369
369
  if (this.hasNoDefaultSelected) {
370
370
  this._noDefaultSelectedInheritsWidth();
371
371
  }
372
+
373
+ // When `trapsKeyboardFocus:true` is configured in our overlay, we need to make sure
374
+ // that our element with [role=listbox] gets focus. The `containFocus` util will look
375
+ // for an element with [autofocus] (otherwise it sets focus to `contentNode` (the 'root' of the overlay))
376
+ this._listboxNode.setAttribute('autofocus', '');
372
377
  }
373
378
 
374
379
  /** @private */
@@ -382,6 +387,7 @@ export class LionSelectRich extends SlotMixin(ScopedElementsMixin(OverlayMixin(L
382
387
  /** @private */
383
388
  __overlayOnHide() {
384
389
  this._invokerNode.focus();
390
+ this._listboxNode.removeAttribute('autofocus');
385
391
  }
386
392
 
387
393
  /**
@@ -424,6 +424,39 @@ describe('lion-select-rich', () => {
424
424
  expect(el.singleOption).to.be.false;
425
425
  expect(_invokerNode.singleOption).to.be.false;
426
426
  });
427
+
428
+ it('adds/removes the autofocus attribute to/from _listboxNode', async () => {
429
+ const el = await fixture(html` <lion-select-rich></lion-select-rich> `);
430
+ const { _listboxNode } = getSelectRichMembers(el);
431
+
432
+ expect(_listboxNode.hasAttribute('autofocus')).to.be.false;
433
+
434
+ el.opened = true;
435
+ await el.updateComplete;
436
+ expect(_listboxNode.hasAttribute('autofocus')).to.be.true;
437
+
438
+ el.opened = false;
439
+ await el.updateComplete;
440
+ await el.updateComplete; // safari takes a little longer
441
+ expect(_listboxNode.hasAttribute('autofocus')).to.be.false;
442
+ });
443
+
444
+ it('adds focus to element with [role=listbox] when trapsKeyboardFocus is true', async () => {
445
+ const el = await fixture(
446
+ html` <lion-select-rich .config=${{ trapsKeyboardFocus: true }}></lion-select-rich> `,
447
+ );
448
+ const { _listboxNode } = getSelectRichMembers(el);
449
+ expect(document.activeElement).to.not.equal(_listboxNode);
450
+
451
+ el.opened = true;
452
+ await el.updateComplete;
453
+ expect(document.activeElement).to.equal(_listboxNode);
454
+
455
+ el.opened = false;
456
+ await el.updateComplete;
457
+ await el.updateComplete; // safari takes a little longer
458
+ expect(document.activeElement).to.not.equal(_listboxNode);
459
+ });
427
460
  });
428
461
 
429
462
  describe('interaction-mode', () => {