@lion/ui 0.8.0 → 0.8.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 (89) hide show
  1. package/README.md +7 -7
  2. package/components/form/src/LionForm.js +3 -12
  3. package/components/form/test/lion-form.test.js +88 -1
  4. package/components/form-core/src/registration/FormRegisteringMixin.js +1 -1
  5. package/components/form-core/types/registration/FormRegisteringMixinTypes.ts +1 -1
  6. package/components/listbox/test-suites/ListboxMixin.suite.js +2 -2
  7. package/components/localize/src/LocalizeManager.js +3 -28
  8. package/components/overlays/src/OverlayController.js +1 -1
  9. package/custom-elements.json +107 -171
  10. package/dist-types/components/form/src/LionForm.d.ts.map +1 -1
  11. package/dist-types/components/form/test/lion-form.test.d.ts.map +1 -1
  12. package/dist-types/components/form-core/types/registration/FormRegisteringMixinTypes.d.ts +1 -1
  13. package/dist-types/components/form-integrations/test/helpers/helpers.d.ts +3 -3
  14. package/dist-types/components/form-integrations/test/helpers/helpers.d.ts.map +1 -1
  15. package/dist-types/components/localize/src/LocalizeManager.d.ts +1 -19
  16. package/dist-types/components/localize/src/LocalizeManager.d.ts.map +1 -1
  17. package/dist-types/tsconfig.tsbuildinfo +1 -1
  18. package/docs/components/checkbox-group/api-table.md +2 -2
  19. package/docs/components/checkbox-group/overview.md +2 -2
  20. package/docs/components/collapsible/overview.md +1 -1
  21. package/docs/components/combobox/overview.md +1 -1
  22. package/docs/components/combobox/use-cases.md +1 -1
  23. package/docs/components/dialog/overview.md +1 -1
  24. package/docs/components/fieldset/overview.md +5 -5
  25. package/docs/components/form/overview.md +3 -3
  26. package/docs/components/icon/use-cases.md +1 -1
  27. package/docs/components/input/api-table.md +1 -1
  28. package/docs/components/input/overview.md +1 -1
  29. package/docs/components/input-amount/api-table.md +1 -1
  30. package/docs/components/input-amount/overview.md +3 -3
  31. package/docs/components/input-date/api-table.md +1 -1
  32. package/docs/components/input-date/overview.md +3 -3
  33. package/docs/components/input-datepicker/api-table.md +1 -1
  34. package/docs/components/input-datepicker/overview.md +5 -5
  35. package/docs/components/input-email/api-table.md +1 -1
  36. package/docs/components/input-email/overview.md +2 -2
  37. package/docs/components/input-file/api-table.md +1 -1
  38. package/docs/components/input-file/overview.md +1 -1
  39. package/docs/components/input-iban/api-table.md +1 -1
  40. package/docs/components/input-iban/overview.md +2 -2
  41. package/docs/components/input-range/api-table.md +1 -1
  42. package/docs/components/input-range/overview.md +2 -2
  43. package/docs/components/input-stepper/api-table.md +1 -1
  44. package/docs/components/input-stepper/overview.md +1 -1
  45. package/docs/components/input-tel/api-table.md +1 -1
  46. package/docs/components/input-tel/overview.md +1 -1
  47. package/docs/components/input-tel/use-cases.md +6 -6
  48. package/docs/components/input-tel-dropdown/api-table.md +1 -1
  49. package/docs/components/input-tel-dropdown/overview.md +1 -1
  50. package/docs/components/listbox/api-table.md +1 -1
  51. package/docs/components/listbox/use-cases.md +1 -1
  52. package/docs/components/radio-group/api-table.md +1 -1
  53. package/docs/components/radio-group/overview.md +3 -3
  54. package/docs/components/select/api-table.md +1 -1
  55. package/docs/components/select/use-cases.md +1 -1
  56. package/docs/components/select-rich/use-cases.md +1 -1
  57. package/docs/components/switch/api-table.md +1 -1
  58. package/docs/components/tabs/examples.md +1 -1
  59. package/docs/components/textarea/api-table.md +1 -1
  60. package/docs/fundamentals/index.md +4 -4
  61. package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +1 -1
  62. package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +1 -1
  63. package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +1 -1
  64. package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +1 -1
  65. package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
  66. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  67. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  68. package/docs/fundamentals/rationales/accessibility.md +1 -1
  69. package/docs/fundamentals/systems/core/SlotMixin.md +1 -1
  70. package/docs/fundamentals/systems/core/overview.md +1 -1
  71. package/docs/fundamentals/systems/form/api-table.md +1 -1
  72. package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
  73. package/docs/fundamentals/systems/form/model-value.md +1 -1
  74. package/docs/fundamentals/systems/form/overview.md +28 -28
  75. package/docs/fundamentals/systems/form/validate.md +2 -2
  76. package/docs/fundamentals/systems/localize/api-table.md +0 -3
  77. package/docs/fundamentals/systems/localize/overview.md +4 -4
  78. package/docs/fundamentals/systems/overlays/configuration.md +2 -2
  79. package/docs/fundamentals/systems/overlays/overview.md +5 -5
  80. package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
  81. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  82. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  83. package/docs/guides/how-to/create-a-custom-field.md +5 -5
  84. package/docs/guides/how-to/create-a-form.md +4 -4
  85. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  86. package/docs/guides/index.md +8 -8
  87. package/docs/guides/principles/index.md +5 -5
  88. package/docs/guides/principles/styling.md +1 -1
  89. package/package.json +1 -1
package/README.md CHANGED
@@ -26,15 +26,15 @@
26
26
  </p>
27
27
 
28
28
  <p align="center">
29
- <a href="https://lion-web.netlify.app">Website</a>
29
+ <a href="https://lion.js.org">Website</a>
30
30
  ·
31
- <a href="https://lion-web.netlify.app/fundamentals/">Fundamentals</a>
31
+ <a href="https://lion.js.org/fundamentals/">Fundamentals</a>
32
32
  ·
33
- <a href="https://lion-web.netlify.app/guides/">Guides</a>
33
+ <a href="https://lion.js.org/guides/">Guides</a>
34
34
  ·
35
- <a href="https://lion-web.netlify.app/components/">Components</a>
35
+ <a href="https://lion.js.org/components/">Components</a>
36
36
  ·
37
- <a href="https://lion-web.netlify.app/blog/">Blog</a>
37
+ <a href="https://lion.js.org/blog/">Blog</a>
38
38
  </p>
39
39
 
40
40
  **Lion is a set of highly performant, accessible and flexible Web Components.!**
@@ -50,7 +50,7 @@ They provide an unopinionated, white-label layer that can be extended to your ow
50
50
  > Note: Our demo examples might look simple and not very stylish. This is on purpose. They are designed to be basic so you can easily add your own styles to them to match your intended design, without dealing with styles that are already there.
51
51
 
52
52
  <p align="center">
53
- <a href="https://lion-web.netlify.app/guides/"><strong>Explore the Lion Guides&nbsp;&nbsp;▶</strong></a>
53
+ <a href="https://lion.js.org/guides/"><strong>Explore the Lion Guides&nbsp;&nbsp;▶</strong></a>
54
54
  </p>
55
55
 
56
56
  ## How to install
@@ -158,7 +158,7 @@ This means you only have to apply your own Design System: by delivering styles,
158
158
 
159
159
  ## Coding guidelines
160
160
 
161
- Check out our [coding guidelines](https://lion-web.netlify.app/guides/principles/definitions-and-terms/) for more detailed information.
161
+ Check out our [coding guidelines](https://lion.js.org/guides/principles/definitions-and-terms/) for more detailed information.
162
162
 
163
163
  ## How to contribute
164
164
 
@@ -10,15 +10,6 @@ const throwFormNodeError = () => {
10
10
  );
11
11
  };
12
12
 
13
- /**
14
- * @param {FormRegistrarHost} formEl
15
- * @returns {boolean}
16
- */
17
- function hasFocusableChildren(formEl) {
18
- // this implies all children have the same type (either all of them are focusable or none of them are)
19
- return formEl.formElements?.some(child => child._focusableNode);
20
- }
21
-
22
13
  /**
23
14
  * LionForm: form wrapper providing extra features and integration with lion-field elements.
24
15
  *
@@ -104,10 +95,10 @@ export class LionForm extends LionFieldset {
104
95
  element.formElements.find(child => child.hasFeedbackFor.includes('error')) ||
105
96
  element.formElements[0];
106
97
 
107
- if (hasFocusableChildren(firstFormElWithError)) {
108
- this._setFocusOnFirstErroneousFormElement(firstFormElWithError);
109
- } else {
98
+ if (firstFormElWithError._focusableNode) {
110
99
  firstFormElWithError._focusableNode.focus();
100
+ } else {
101
+ this._setFocusOnFirstErroneousFormElement(firstFormElWithError);
111
102
  }
112
103
  }
113
104
 
@@ -5,6 +5,10 @@ import '@lion/ui/define/lion-field.js';
5
5
  import '@lion/ui/define/lion-validation-feedback.js';
6
6
  import '@lion/ui/define/lion-listbox.js';
7
7
  import '@lion/ui/define/lion-option.js';
8
+ import '@lion/ui/define/lion-checkbox-group.js';
9
+ import '@lion/ui/define/lion-checkbox.js';
10
+ import '@lion/ui/define/lion-radio-group.js';
11
+ import '@lion/ui/define/lion-radio.js';
8
12
  import '@lion/ui/define/lion-form.js';
9
13
  import {
10
14
  aTimeout,
@@ -264,10 +268,31 @@ describe('<lion-form>', () => {
264
268
  button.click();
265
269
  expect(dispatchSpy.args[0][0].type).to.equal('submit');
266
270
  const fieldset = el.formElements[0];
267
- // @ts-ignore [allow-protected] in test
268
271
  expect(document.activeElement).to.equal(fieldset.formElements[0]._inputNode);
269
272
  });
270
273
 
274
+ it('sets focus on submit to the first form element within a erroneous fieldset within another fieldset', async () => {
275
+ const el = await fixture(html`
276
+ <lion-form>
277
+ <form>
278
+ <lion-fieldset name="parentFieldset">
279
+ <lion-fieldset name="childFieldset" .validators="${[new Required()]}">
280
+ <${childTag} name="firstName"></${childTag}>
281
+ </lion-fieldset>
282
+ </lion-fieldset>
283
+
284
+ <button type="submit">submit</button>
285
+ </form>
286
+ </lion-form>
287
+ `);
288
+ const button = /** @type {HTMLButtonElement} */ (el.querySelector('button'));
289
+ const parentFieldSetEl = el.formElements[0];
290
+ const childFieldsetEl = parentFieldSetEl.formElements[0];
291
+ const inputEl = childFieldsetEl.formElements[0];
292
+ button.click();
293
+ expect(document.activeElement).to.equal(inputEl._focusableNode);
294
+ });
295
+
271
296
  it('sets focus on submit to the first form element within a erroneous listbox', async () => {
272
297
  const el = await fixture(html`
273
298
  <lion-form>
@@ -285,4 +310,66 @@ describe('<lion-form>', () => {
285
310
  const listboxEl = el.formElements[0];
286
311
  expect(document.activeElement).to.equal(listboxEl._inputNode);
287
312
  });
313
+
314
+ it('sets focus on submit to the first form element within a erroneous listbox within a fieldset', async () => {
315
+ const el = await fixture(html`
316
+ <lion-form>
317
+ <form>
318
+ <lion-fieldset name="fieldset">
319
+ <lion-listbox name="name" .validators="${[new Required()]}">
320
+ <lion-option value="a">a</lion-option>
321
+ <lion-option value="b">b</lion-option>
322
+ </lion-listbox>
323
+ </lion-fieldset>
324
+ <button type="submit">submit</button>
325
+ </form>
326
+ </lion-form>
327
+ `);
328
+ const button = /** @type {HTMLButtonElement} */ (el.querySelector('button'));
329
+ button.click();
330
+ const fieldsetEl = el.formElements[0];
331
+ const listboxEl = fieldsetEl.formElements[0];
332
+ expect(document.activeElement).to.equal(listboxEl._inputNode);
333
+ });
334
+
335
+ it('sets focus on submit to the first form element within a erroneous checkbox-group', async () => {
336
+ const el = await fixture(html`
337
+ <lion-form>
338
+ <form>
339
+ <lion-checkbox-group name="name" .validators="${[new Required()]}">
340
+ <lion-checkbox .choiceValue=${'a'} label="a"></lion-checkbox>
341
+ <lion-checkbox .choiceValue=${'b'} label="b"></lion-checkbox>
342
+ </lion-checkbox-group>
343
+ <button type="submit">submit</button>
344
+ </form>
345
+ </lion-form>
346
+ `);
347
+ const button = /** @type {HTMLButtonElement} */ (el.querySelector('button'));
348
+ const checkboxGroupEl = el.formElements[0];
349
+ const checkboxEl = checkboxGroupEl.formElements[0];
350
+ button.click();
351
+ expect(document.activeElement).to.equal(checkboxEl._focusableNode);
352
+ });
353
+
354
+ it('sets focus on submit to the first form element within a erroneous radio-group', async () => {
355
+ const el = await fixture(html`
356
+ <lion-form>
357
+ <form>
358
+ <lion-radio-group name="name" .validators="${[new Required()]}">
359
+ <lion-radio .choiceValue=${'a'} label="a"></lion-radio>
360
+ <lion-radio .choiceValue=${'b'} label="b"></lion-radio>
361
+ </lion-radio-group>
362
+ </lion-fieldset>
363
+
364
+ <button type="submit">submit</button>
365
+ </form>
366
+ </lion-form>
367
+ `);
368
+ const button = /** @type {HTMLButtonElement} */ (el.querySelector('button'));
369
+
370
+ const radioGroupEl = el.formElements[0];
371
+ const radioEl = radioGroupEl.formElements[0];
372
+ button.click();
373
+ expect(document.activeElement).to.equal(radioEl._focusableNode);
374
+ });
288
375
  });
@@ -40,7 +40,7 @@ const FormRegisteringMixinImplementation = superclass =>
40
40
  * To encourage accessibility best practices, `form-element-register` events
41
41
  * do not pierce through shadow roots. This forces the developer to create form groups and fieldsets that automatically allow the creation of accessible relationships in the same dom tree.
42
42
  Use this option if you know what you're doing. It will then be possible to nest FormControls
43
- inside shadow dom. See https://lion-web.netlify.app/fundamentals/rationales/accessibility/#shadow-roots-and-accessibility
43
+ inside shadow dom. See https://lion.js.org/fundamentals/rationales/accessibility/#shadow-roots-and-accessibility
44
44
  */
45
45
  this.allowCrossRootRegistration = false;
46
46
  }
@@ -16,7 +16,7 @@ export declare class FormRegisteringHost {
16
16
  * do not pierce through shadow roots. This forces the developer to create form groups and fieldsets that
17
17
  * automatically allow the creation of accessible relationships in the same dom tree.
18
18
  * Use this option if you know what you're doing. It will then be possible to nest FormControls
19
- * inside shadow dom. See https://lion-web.netlify.app/fundamentals/rationales/accessibility#shadow-roots-and-accessibility
19
+ * inside shadow dom. See https://lion.js.org/fundamentals/rationales/accessibility#shadow-roots-and-accessibility
20
20
  */
21
21
  allowCrossRootRegistration: boolean;
22
22
 
@@ -400,7 +400,7 @@ export function runListboxMixinSuite(customConfig = {}) {
400
400
  `);
401
401
  await el.updateComplete;
402
402
  await el.updateComplete; // need 2 awaits as overlay.show is an async function
403
- // for more info about why we need the ignoreRules, see: https://lion-web.netlify.app/fundamentals/systems/overlays/rationale/#considerations
403
+ // for more info about why we need the ignoreRules, see: https://lion.js.org/fundamentals/systems/overlays/rationale/#considerations
404
404
  await expect(el).to.be.accessible({ ignoredRules: ['aria-allowed-role'] });
405
405
  });
406
406
 
@@ -412,7 +412,7 @@ export function runListboxMixinSuite(customConfig = {}) {
412
412
  <${optionTag} .choiceValue=${20}>Item 2</${optionTag}>
413
413
  </${tag}>
414
414
  `);
415
- // for more info about why we need the ignoreRules, see: https://lion-web.netlify.app/fundamentals/systems/overlays/rationale/#considerations
415
+ // for more info about why we need the ignoreRules, see: https://lion.js.org/fundamentals/systems/overlays/rationale/#considerations
416
416
  await expect(el).to.be.accessible({ ignoredRules: ['aria-allowed-role'] });
417
417
  });
418
418
 
@@ -12,7 +12,7 @@ import isLocalizeESModule from './isLocalizeESModule.js';
12
12
  /**
13
13
  * `LocalizeManager` manages your translations (includes loading)
14
14
  */
15
- export class LocalizeManager {
15
+ export class LocalizeManager extends EventTarget {
16
16
  // eslint-disable-line no-unused-vars
17
17
  constructor({
18
18
  autoLoadOnLocaleChange = false,
@@ -20,8 +20,8 @@ export class LocalizeManager {
20
20
  showKeyAsFallback = false,
21
21
  allowOverridesForExistingNamespaces = false,
22
22
  } = {}) {
23
- /** @private */
24
- this.__delegationTarget = document.createDocumentFragment();
23
+ super();
24
+
25
25
  /** @protected */
26
26
  this._autoLoadOnLocaleChange = !!autoLoadOnLocaleChange;
27
27
  /** @protected */
@@ -480,31 +480,6 @@ export class LocalizeManager {
480
480
  return locale.substring(0, 2);
481
481
  }
482
482
 
483
- /**
484
- * @param {string} type
485
- * @param {EventListener} listener
486
- * @param {...Object} options
487
- */
488
- addEventListener(type, listener, ...options) {
489
- this.__delegationTarget.addEventListener(type, listener, ...options);
490
- }
491
-
492
- /**
493
- * @param {string} type
494
- * @param {EventListener} listener
495
- * @param {...Object} options
496
- */
497
- removeEventListener(type, listener, ...options) {
498
- this.__delegationTarget.removeEventListener(type, listener, ...options);
499
- }
500
-
501
- /**
502
- * @param {CustomEvent} event
503
- */
504
- dispatchEvent(event) {
505
- this.__delegationTarget.dispatchEvent(event);
506
- }
507
-
508
483
  /**
509
484
  * @param {string} newLocale
510
485
  * @param {string} oldLocale
@@ -578,7 +578,7 @@ export class OverlayController extends EventTarget {
578
578
  // The role="dialog" is set on the contentNode (or another role), so role="none"
579
579
  // is valid here, although AXE complains about this setup.
580
580
  // For now we need to add `ignoredRules: ['aria-allowed-role']` in your AXE tests.
581
- // see: https://lion-web.netlify.app/fundamentals/systems/overlays/rationale/#considerations
581
+ // see: https://lion.js.org/fundamentals/systems/overlays/rationale/#considerations
582
582
  wrappingDialogElement.setAttribute('role', 'none');
583
583
  wrappingDialogElement.setAttribute('data-overlay-outer-wrapper', '');
584
584
  // N.B. position: fixed is needed to escape out of 'overflow: hidden'