@lion/ui 0.16.0 → 0.17.0-menu-system.0
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.
- package/collapsible.js +1 -0
- package/components/button/src/LionButton.js +5 -0
- package/components/button/test-suites/LionButton.suite.js +1 -0
- package/components/calendar/src/LionCalendar.js +2 -0
- package/components/collapsible/src/DisclosureMixin.js +313 -0
- package/components/collapsible/types/DisclosureMixinTypes.ts +48 -0
- package/components/combobox/src/utils/makeMatchingTextBold.js +3 -1
- package/components/combobox/test/lion-combobox.test.js +105 -0
- package/components/form-core/src/form-group/FormGroupMixin.js +7 -0
- package/components/form-core/src/registration/FormRegistrarMixin.js +11 -0
- package/components/form-core/test/FormControlMixin.test.js +1 -0
- package/components/form-core/test/validate/Validator.test.js +2 -0
- package/components/form-core/test-suites/ValidateMixin.suite.js +2 -0
- package/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.js +1 -0
- package/components/input-datepicker/src/LionInputDatepicker.js +6 -2
- package/components/input-datepicker/src/localizeNamespaceLoader.js +1 -0
- package/components/input-datepicker/test/lion-input-datepicker.test.js +17 -2
- package/components/input-datepicker/translations/bg.js +1 -1
- package/components/input-datepicker/translations/cs.js +1 -1
- package/components/input-datepicker/translations/de.js +1 -1
- package/components/input-datepicker/translations/en.js +1 -1
- package/components/input-datepicker/translations/es.js +1 -1
- package/components/input-datepicker/translations/fr.js +1 -1
- package/components/input-datepicker/translations/hu.js +1 -1
- package/components/input-datepicker/translations/it.js +1 -1
- package/components/input-datepicker/translations/nl.js +1 -1
- package/components/input-datepicker/translations/pl.js +1 -1
- package/components/input-datepicker/translations/ro.js +1 -1
- package/components/input-datepicker/translations/ru.js +1 -1
- package/components/input-datepicker/translations/sk.js +1 -1
- package/components/input-datepicker/translations/tr.js +1 -1
- package/components/input-datepicker/translations/uk.js +1 -1
- package/components/input-datepicker/translations/zh.js +1 -1
- package/components/input-stepper/src/LionInputStepper.js +15 -7
- package/components/input-stepper/test-suites/lion-input-stepper.suite.js +28 -4
- package/components/localize/test/date/formatDate.test.js +1 -0
- package/components/menu/CHANGELOG.md +37 -0
- package/components/menu/README.md +335 -0
- package/components/menu/index.js +2 -0
- package/components/menu/lion-menu-overlay.js +3 -0
- package/components/menu/lion-menu.js +3 -0
- package/components/menu/lion-spinbutton.js +3 -0
- package/components/menu/lion-toolbar.js +3 -0
- package/components/menu/lion-tree.js +3 -0
- package/components/menu/package.json +46 -0
- package/components/menu/requirements.temp.md +12 -0
- package/components/menu/src/InteractiveListMixin.js +796 -0
- package/components/menu/src/LionMenu.js +250 -0
- package/components/menu/src/LionMenuHybrid.js +46 -0
- package/components/menu/src/LionMenuOverlay.js +155 -0
- package/components/menu/src/LionSpinbutton.js +213 -0
- package/components/menu/src/LionToolbar.js +94 -0
- package/components/menu/src/LionTree.js +52 -0
- package/components/menu/src/MultiLevelListMixin.js +275 -0
- package/components/menu/src/utils/isInView.js +26 -0
- package/components/menu/src/utils/listItemInteractions.js +104 -0
- package/components/menu/src/utils/uuid.js +3 -0
- package/components/menu/test/lion-menu.test.js +3 -0
- package/components/menu/test-suites/InteractiveListMixin.suite.js +142 -0
- package/components/menu/types/InteractiveListMixinTypes.d.ts +82 -0
- package/components/navigation-bar/README.md +1 -0
- package/components/navigation-bar/src/LionNavigationBar.js +449 -0
- package/components/navigation-bar/src/types.js +41 -0
- package/components/overlays/NEXT.md +49 -0
- package/components/overlays/src/OverlayController.js +165 -115
- package/components/overlays/src/OverlayMixin.js +75 -12
- package/components/overlays/src/OverlaysManager.js +102 -4
- package/components/overlays/src/overlayShadowDomStyle.js +2 -2
- package/components/overlays/src/utils/adopt-styles.js +2 -1
- package/components/overlays/src/utils/get-focusable-elements.js +4 -0
- package/components/overlays/src/utils/is-equal-config.js +4 -1
- package/components/overlays/test/OverlayController.test.js +117 -6
- package/components/overlays/test/OverlaysManager.test.js +1 -1
- package/components/overlays/types/OverlayConfig.ts +19 -4
- package/components/select-rich/test/lion-select-rich.test.js +3 -0
- package/custom-elements.json +12958 -2510
- package/dist-types/components/button/src/LionButton.d.ts +1 -0
- package/dist-types/components/button/src/LionButton.d.ts.map +1 -1
- package/dist-types/components/button/test-suites/LionButton.suite.d.ts.map +1 -1
- package/dist-types/components/calendar/src/LionCalendar.d.ts.map +1 -1
- package/dist-types/components/collapsible/src/DisclosureMixin.d.ts +3 -0
- package/dist-types/components/collapsible/src/DisclosureMixin.d.ts.map +1 -0
- package/dist-types/components/collapsible/types/DisclosureMixinTypes.d.ts +24 -0
- package/dist-types/components/collapsible/types/DisclosureMixinTypes.d.ts.map +1 -0
- package/dist-types/components/combobox/src/utils/makeMatchingTextBold.d.ts.map +1 -1
- package/dist-types/components/dialog/src/LionDialog.d.ts +2 -1
- package/dist-types/components/dialog/src/LionDialog.d.ts.map +1 -1
- package/dist-types/components/form-core/src/form-group/FormGroupMixin.d.ts.map +1 -1
- package/dist-types/components/form-core/src/registration/FormRegistrarMixin.d.ts.map +1 -1
- package/dist-types/components/form-core/test-suites/ValidateMixin.suite.d.ts.map +1 -1
- package/dist-types/components/form-core/test-suites/ValidateMixinFeedbackPart.suite.d.ts.map +1 -1
- package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts.map +1 -1
- package/dist-types/components/input-datepicker/src/localizeNamespaceLoader.d.ts.map +1 -1
- package/dist-types/components/input-stepper/src/LionInputStepper.d.ts +4 -2
- package/dist-types/components/input-stepper/src/LionInputStepper.d.ts.map +1 -1
- package/dist-types/components/input-stepper/test-suites/lion-input-stepper.suite.d.ts.map +1 -1
- package/dist-types/components/menu/index.d.ts +3 -0
- package/dist-types/components/menu/index.d.ts.map +1 -0
- package/dist-types/components/menu/lion-menu-overlay.d.ts +2 -0
- package/dist-types/components/menu/lion-menu-overlay.d.ts.map +1 -0
- package/dist-types/components/menu/lion-menu.d.ts +2 -0
- package/dist-types/components/menu/lion-menu.d.ts.map +1 -0
- package/dist-types/components/menu/lion-spinbutton.d.ts +2 -0
- package/dist-types/components/menu/lion-spinbutton.d.ts.map +1 -0
- package/dist-types/components/menu/lion-toolbar.d.ts +2 -0
- package/dist-types/components/menu/lion-toolbar.d.ts.map +1 -0
- package/dist-types/components/menu/lion-tree.d.ts +2 -0
- package/dist-types/components/menu/lion-tree.d.ts.map +1 -0
- package/dist-types/components/menu/src/InteractiveListMixin.d.ts +611 -0
- package/dist-types/components/menu/src/InteractiveListMixin.d.ts.map +1 -0
- package/dist-types/components/menu/src/LionMenu.d.ts +563 -0
- package/dist-types/components/menu/src/LionMenu.d.ts.map +1 -0
- package/dist-types/components/menu/src/LionMenuHybrid.d.ts +19 -0
- package/dist-types/components/menu/src/LionMenuHybrid.d.ts.map +1 -0
- package/dist-types/components/menu/src/LionMenuOverlay.d.ts +1006 -0
- package/dist-types/components/menu/src/LionMenuOverlay.d.ts.map +1 -0
- package/dist-types/components/menu/src/LionSpinbutton.d.ts +58 -0
- package/dist-types/components/menu/src/LionSpinbutton.d.ts.map +1 -0
- package/dist-types/components/menu/src/LionToolbar.d.ts +8 -0
- package/dist-types/components/menu/src/LionToolbar.d.ts.map +1 -0
- package/dist-types/components/menu/src/LionTree.d.ts +445 -0
- package/dist-types/components/menu/src/LionTree.d.ts.map +1 -0
- package/dist-types/components/menu/src/MultiLevelListMixin.d.ts +493 -0
- package/dist-types/components/menu/src/MultiLevelListMixin.d.ts.map +1 -0
- package/dist-types/components/menu/src/utils/isInView.d.ts +9 -0
- package/dist-types/components/menu/src/utils/isInView.d.ts.map +1 -0
- package/dist-types/components/menu/src/utils/listItemInteractions.d.ts +42 -0
- package/dist-types/components/menu/src/utils/listItemInteractions.d.ts.map +1 -0
- package/dist-types/components/menu/src/utils/uuid.d.ts +2 -0
- package/dist-types/components/menu/src/utils/uuid.d.ts.map +1 -0
- package/dist-types/components/menu/test/lion-menu.test.d.ts +2 -0
- package/dist-types/components/menu/test/lion-menu.test.d.ts.map +1 -0
- package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts +13 -0
- package/dist-types/components/menu/test-suites/InteractiveListMixin.suite.d.ts.map +1 -0
- package/dist-types/components/navigation-bar/src/LionNavigationBar.d.ts +226 -0
- package/dist-types/components/navigation-bar/src/LionNavigationBar.d.ts.map +1 -0
- package/dist-types/components/navigation-bar/src/types.d.ts +85 -0
- package/dist-types/components/navigation-bar/src/types.d.ts.map +1 -0
- package/dist-types/components/overlays/src/OverlayController.d.ts +7 -13
- package/dist-types/components/overlays/src/OverlayController.d.ts.map +1 -1
- package/dist-types/components/overlays/src/OverlayMixin.d.ts +3 -0
- package/dist-types/components/overlays/src/OverlayMixin.d.ts.map +1 -1
- package/dist-types/components/overlays/src/OverlaysManager.d.ts +33 -2
- package/dist-types/components/overlays/src/OverlaysManager.d.ts.map +1 -1
- package/dist-types/components/overlays/src/utils/get-focusable-elements.d.ts.map +1 -1
- package/dist-types/components/overlays/src/utils/is-equal-config.d.ts.map +1 -1
- package/dist-types/components/overlays/types/OverlayConfig.d.ts +6 -2
- package/dist-types/components/overlays/types/OverlayConfig.d.ts.map +1 -1
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts +11 -2
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
- package/dist-types/exports/define/lion-item.d.ts +2 -0
- package/dist-types/exports/define/lion-item.d.ts.map +1 -0
- package/dist-types/exports/define/lion-menu-overlay.d.ts +2 -0
- package/dist-types/exports/define/lion-menu-overlay.d.ts.map +1 -0
- package/dist-types/exports/define/lion-menu.d.ts +2 -0
- package/dist-types/exports/define/lion-menu.d.ts.map +1 -0
- package/dist-types/exports/define/lion-navigation-bar.d.ts +2 -0
- package/dist-types/exports/define/lion-navigation-bar.d.ts.map +1 -0
- package/dist-types/exports/define/lion-toolbar.d.ts +2 -0
- package/dist-types/exports/define/lion-toolbar.d.ts.map +1 -0
- package/dist-types/exports/define/lion-tree.d.ts +2 -0
- package/dist-types/exports/define/lion-tree.d.ts.map +1 -0
- package/dist-types/exports/menu.d.ts +7 -0
- package/dist-types/exports/menu.d.ts.map +1 -0
- package/dist-types/exports/navigation-bar.d.ts +2 -0
- package/dist-types/exports/navigation-bar.d.ts.map +1 -0
- package/dist-types/exports/overlays.d.ts +2 -0
- package/dist-types/exports/types/overlays.d.ts +1 -0
- package/dist-types/exports/types/overlays.d.ts.map +1 -1
- package/dist-types/tsconfig.tsbuildinfo +1 -1
- package/docs/components/checkbox-group/overview.md +2 -2
- package/docs/components/collapsible/overview.md +1 -1
- package/docs/components/combobox/overview.md +1 -1
- package/docs/components/combobox/use-cases.md +1 -1
- package/docs/components/dialog/overview.md +1 -1
- package/docs/components/fieldset/overview.md +5 -5
- package/docs/components/form/overview.md +3 -3
- package/docs/components/form/use-cases.md +2 -2
- package/docs/components/icon/use-cases.md +1 -1
- package/docs/components/index.md +1 -1
- package/docs/components/input/overview.md +1 -1
- package/docs/components/input-amount/overview.md +3 -3
- package/docs/components/input-date/overview.md +3 -3
- package/docs/components/input-datepicker/overview.md +5 -5
- package/docs/components/input-datepicker/use-cases.md +16 -1
- package/docs/components/input-email/overview.md +2 -2
- package/docs/components/input-file/overview.md +1 -1
- package/docs/components/input-iban/overview.md +2 -2
- package/docs/components/input-range/api-table.md +1 -1
- package/docs/components/input-range/overview.md +2 -2
- package/docs/components/input-stepper/api-table.md +2 -2
- package/docs/components/input-stepper/overview.md +1 -1
- package/docs/components/input-stepper/use-cases.md +26 -0
- package/docs/components/input-tel/overview.md +1 -1
- package/docs/components/input-tel/use-cases.md +6 -6
- package/docs/components/input-tel-dropdown/overview.md +1 -1
- package/docs/components/listbox/use-cases.md +1 -1
- package/docs/components/menu/api-table.md +450 -0
- package/docs/components/menu/applyMenuDemoStyles.js +173 -0
- package/docs/components/menu/extensions.md +216 -0
- package/docs/components/menu/index.md +13 -0
- package/docs/components/menu/overview.md +422 -0
- package/docs/components/radio-group/overview.md +3 -3
- package/docs/components/select/use-cases.md +1 -1
- package/docs/components/select-rich/api-table.md +1 -1
- package/docs/components/select-rich/use-cases.md +2 -2
- package/docs/components/tabs/examples.md +1 -1
- package/docs/fundamentals/index.md +4 -4
- package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
- package/docs/fundamentals/rationales/accessibility.md +1 -1
- package/docs/fundamentals/systems/core/SlotMixin.md +18 -18
- package/docs/fundamentals/systems/core/overview.md +1 -1
- package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
- package/docs/fundamentals/systems/form/interaction-states.md +0 -1
- package/docs/fundamentals/systems/form/model-value.md +1 -1
- package/docs/fundamentals/systems/form/overview.md +28 -28
- package/docs/fundamentals/systems/form/validate.md +2 -2
- package/docs/fundamentals/systems/localize/overview.md +4 -4
- package/docs/fundamentals/systems/localize/text.md +1 -1
- package/docs/fundamentals/systems/overlays/api-table.md +98 -50
- package/docs/fundamentals/systems/overlays/configuration.md +2 -2
- package/docs/fundamentals/systems/overlays/overview.md +5 -5
- package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
- package/docs/fundamentals/tools/helpers/overview.md +1 -1
- package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
- package/docs/guides/how-to/create-a-custom-field.md +5 -5
- package/docs/guides/how-to/create-a-form.md +4 -4
- package/docs/guides/how-to/extend-a-native-input.md +2 -2
- package/docs/guides/how-to/index.md +14 -0
- package/docs/guides/index.md +8 -8
- package/docs/guides/principles/index.md +5 -5
- package/docs/guides/principles/styling.md +1 -2
- package/exports/collapsible.js +1 -0
- package/exports/define/lion-item.js +3 -0
- package/exports/define/lion-menu-overlay.js +3 -0
- package/exports/define/lion-menu.js +3 -0
- package/exports/define/lion-navigation-bar.js +3 -0
- package/exports/define/lion-toolbar.js +3 -0
- package/exports/define/lion-tree.js +3 -0
- package/exports/menu.js +6 -0
- package/exports/navigation-bar.js +1 -0
- package/exports/overlays.js +2 -0
- package/exports/types/overlays.ts +1 -0
- package/menu.js +6 -0
- package/navigation-bar.js +1 -0
- package/overlays.js +2 -0
- package/package.json +1 -1
package/collapsible.js
CHANGED
|
@@ -52,6 +52,7 @@ export class LionButton extends DisabledWithTabIndexMixin(LitElement) {
|
|
|
52
52
|
vertical-align: middle;
|
|
53
53
|
line-height: 24px;
|
|
54
54
|
background-color: #eee; /* minimal styling to make it recognizable as btn */
|
|
55
|
+
color: black; /* if we set background, we should set color as well, like a native button */
|
|
55
56
|
padding: 8px; /* padding to fix with min-height */
|
|
56
57
|
outline: none; /* focus style handled below */
|
|
57
58
|
cursor: default; /* we should always see the default arrow, never a caret */
|
|
@@ -219,4 +220,8 @@ export class LionButton extends DisabledWithTabIndexMixin(LitElement) {
|
|
|
219
220
|
this.click();
|
|
220
221
|
}
|
|
221
222
|
}
|
|
223
|
+
|
|
224
|
+
// we want to be able to identify LionButtons w/o instanceof (for perf (loose dep) and dual version support),
|
|
225
|
+
// so we use a static property for that that doesn't get renamed by minifiers
|
|
226
|
+
static ['_$isLionButton$'] = true;
|
|
222
227
|
}
|
|
@@ -279,6 +279,7 @@ export function LionButtonSuite({ klass = LionButton } = {}) {
|
|
|
279
279
|
|
|
280
280
|
sameProperties.forEach(property => {
|
|
281
281
|
it(`has same value of the property "${property}" as in native button event`, () => {
|
|
282
|
+
// @ts-ignore - dynamic property access
|
|
282
283
|
expect(lionButtonEvent[property]).to.equal(nativeButtonEvent[property]);
|
|
283
284
|
});
|
|
284
285
|
});
|
|
@@ -928,6 +928,7 @@ export class LionCalendar extends LocalizeMixin(LitElement) {
|
|
|
928
928
|
if (type !== 'Date') {
|
|
929
929
|
tmpDate.setDate(1);
|
|
930
930
|
}
|
|
931
|
+
// @ts-ignore - dynamic method access
|
|
931
932
|
tmpDate[`set${type}`](tmpDate[`get${type}`]() + modify);
|
|
932
933
|
// if we've reset the day count,
|
|
933
934
|
// restore day count as best we can
|
|
@@ -935,6 +936,7 @@ export class LionCalendar extends LocalizeMixin(LitElement) {
|
|
|
935
936
|
const maxDays = new Date(tmpDate.getFullYear(), tmpDate.getMonth() + 1, 0).getDate();
|
|
936
937
|
tmpDate.setDate(Math.min(this.centralDate.getDate(), maxDays));
|
|
937
938
|
}
|
|
939
|
+
// @ts-ignore - dynamic property access
|
|
938
940
|
this[dateType] = tmpDate;
|
|
939
941
|
}
|
|
940
942
|
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('../types/DisclosureMixinTypes.js').DisclosureHost} DisclosureHost
|
|
3
|
+
* @typedef {import('../types/DisclosureMixinTypes.js').DisclosureMixin} DisclosureMixin
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// /**
|
|
7
|
+
// * @type {DisclosureMixin}
|
|
8
|
+
// */
|
|
9
|
+
// const DisclosureMixinImplementation = superclass =>
|
|
10
|
+
// // @ts-ignore https://github.com/microsoft/TypeScript/issues/36821#issuecomment-588375051
|
|
11
|
+
// class DisclosureMixin extends superclass {
|
|
12
|
+
// /** @type {any} */
|
|
13
|
+
// static get properties() {
|
|
14
|
+
// return {
|
|
15
|
+
// opened: { type: Boolean, reflect: true },
|
|
16
|
+
// handleFocus: { type: Boolean, attribute: 'handle-focus' },
|
|
17
|
+
// invokerInteraction: { type: String, attribute: 'invoker-interaction' },
|
|
18
|
+
// };
|
|
19
|
+
// }
|
|
20
|
+
|
|
21
|
+
// /**
|
|
22
|
+
// * @param {Element} focusableElOrWrapper
|
|
23
|
+
// * @returns {Element|null}
|
|
24
|
+
// */
|
|
25
|
+
// static _getFocusableInvokerEl(focusableElOrWrapper) {
|
|
26
|
+
// // return focusableElOrWrapper;
|
|
27
|
+
// return (
|
|
28
|
+
// focusableElOrWrapper &&
|
|
29
|
+
// (focusableElOrWrapper.hasAttribute('tabindex') || focusableElOrWrapper.tagName === 'BUTTON'
|
|
30
|
+
// ? focusableElOrWrapper
|
|
31
|
+
// : focusableElOrWrapper.querySelector('[role=button], button'))
|
|
32
|
+
// );
|
|
33
|
+
// }
|
|
34
|
+
|
|
35
|
+
// get _invokerNode() {
|
|
36
|
+
// const ctor = this.constructor;
|
|
37
|
+
// if (!this.__invokerNode) {
|
|
38
|
+
// const slottedNode = Array.from(this.children).find(child => child.slot === 'invoker');
|
|
39
|
+
// if (slottedNode) {
|
|
40
|
+
// this.__invokerNode = ctor._getFocusableInvokerEl(slottedNode);
|
|
41
|
+
// } else {
|
|
42
|
+
// this.__invokerNode =
|
|
43
|
+
// this.previousElementSibling?.hasAttribute('data-invoker') &&
|
|
44
|
+
// ctor._getFocusableInvokerEl(this.previousElementSibling);
|
|
45
|
+
// }
|
|
46
|
+
// }
|
|
47
|
+
// return this.__invokerNode;
|
|
48
|
+
// }
|
|
49
|
+
|
|
50
|
+
// get _contentNode() {
|
|
51
|
+
// if (!this._cachedOverlayContentNode) {
|
|
52
|
+
// this._cachedOverlayContentNode = Array.from(this.children).find(
|
|
53
|
+
// child => child.slot === 'content',
|
|
54
|
+
// );
|
|
55
|
+
// }
|
|
56
|
+
// return this._cachedOverlayContentNode;
|
|
57
|
+
// }
|
|
58
|
+
|
|
59
|
+
// constructor() {
|
|
60
|
+
// super();
|
|
61
|
+
// this.opened = false;
|
|
62
|
+
// /**
|
|
63
|
+
// * @type {'click'|'hover'}
|
|
64
|
+
// */
|
|
65
|
+
// this.invokerInteraction = 'click';
|
|
66
|
+
// /**
|
|
67
|
+
// * Puts focus on `_contentNode` on open and on `_invokerNode` on close.
|
|
68
|
+
// * @type {Boolean}
|
|
69
|
+
// */
|
|
70
|
+
// this.handleFocus = false;
|
|
71
|
+
// this.__disclosureNeedsSetup = true;
|
|
72
|
+
|
|
73
|
+
// this.toggle = this.toggle.bind(this);
|
|
74
|
+
// this.open = this.open.bind(this);
|
|
75
|
+
// this.close = this.close.bind(this);
|
|
76
|
+
|
|
77
|
+
// this.__handleAnimateComplete = this.__handleAnimateComplete.bind(this);
|
|
78
|
+
|
|
79
|
+
// this.__onInvokerMouseenter = this.__onInvokerMouseenter.bind(this);
|
|
80
|
+
// this.__onContentMouseenter = this.__onContentMouseenter.bind(this);
|
|
81
|
+
// this.__onInvokerMouseleave = this.__onInvokerMouseleave.bind(this);
|
|
82
|
+
// this.__onContentMouseleave = this.__onContentMouseleave.bind(this);
|
|
83
|
+
// }
|
|
84
|
+
|
|
85
|
+
// connectedCallback() {
|
|
86
|
+
// super.connectedCallback();
|
|
87
|
+
// // we do a setup after every connectedCallback as firstUpdated will only be called once
|
|
88
|
+
// this.__disclosureNeedsSetup = true;
|
|
89
|
+
// this.updateComplete.then(() => {
|
|
90
|
+
// if (this.__disclosureNeedsSetup) {
|
|
91
|
+
// this._setupDisclosure();
|
|
92
|
+
// }
|
|
93
|
+
// this.__disclosureNeedsSetup = false;
|
|
94
|
+
// });
|
|
95
|
+
// this.__setupAnimation();
|
|
96
|
+
// }
|
|
97
|
+
|
|
98
|
+
// disconnectedCallback() {
|
|
99
|
+
// super.disconnectedCallback();
|
|
100
|
+
// this._teardownDisclosure();
|
|
101
|
+
// this.__teardownAnimation();
|
|
102
|
+
// }
|
|
103
|
+
|
|
104
|
+
// /**
|
|
105
|
+
// * @overridable
|
|
106
|
+
// */
|
|
107
|
+
// _setupDisclosure() {
|
|
108
|
+
// console.log('_setupDisclosure', this.level);
|
|
109
|
+
|
|
110
|
+
// this._setupOpenCloseListeners();
|
|
111
|
+
// }
|
|
112
|
+
|
|
113
|
+
// /**
|
|
114
|
+
// * @overridable
|
|
115
|
+
// */
|
|
116
|
+
// _teardownDisclosure() {
|
|
117
|
+
// this._teardownOpenCloseListeners();
|
|
118
|
+
// }
|
|
119
|
+
|
|
120
|
+
// /**
|
|
121
|
+
// * @overridable
|
|
122
|
+
// */
|
|
123
|
+
// _setupOpenCloseListeners() {
|
|
124
|
+
// console.log('setup listeners', this.level);
|
|
125
|
+
// if (!this._invokerNode) {
|
|
126
|
+
// return;
|
|
127
|
+
// }
|
|
128
|
+
|
|
129
|
+
// const interactions = this.invokerInteraction.split(' ');
|
|
130
|
+
|
|
131
|
+
// if (interactions.includes('hover')) {
|
|
132
|
+
// this._invokerNode.addEventListener('mouseenter', this.__onInvokerMouseenter);
|
|
133
|
+
// this._contentNode?.addEventListener('mouseenter', this.__onContentMouseenter);
|
|
134
|
+
// this._invokerNode.addEventListener('mouseleave', this.__onInvokerMouseleave);
|
|
135
|
+
// this._contentNode?.addEventListener('mouseleave', this.__onContentMouseleave);
|
|
136
|
+
// }
|
|
137
|
+
// if (interactions.includes('click')) {
|
|
138
|
+
// this._invokerNode.addEventListener('click', this.toggle);
|
|
139
|
+
// }
|
|
140
|
+
// }
|
|
141
|
+
|
|
142
|
+
// __onInvokerMouseenter() {
|
|
143
|
+
// this.__invokerHover = true;
|
|
144
|
+
// this.open();
|
|
145
|
+
// }
|
|
146
|
+
|
|
147
|
+
// __onContentMouseenter() {
|
|
148
|
+
// this.__contentHover = true;
|
|
149
|
+
// console.log('this.__contentHover', this.__contentHover);
|
|
150
|
+
// this.open();
|
|
151
|
+
// }
|
|
152
|
+
|
|
153
|
+
// __onInvokerMouseleave() {
|
|
154
|
+
// setTimeout(() => {
|
|
155
|
+
// if (!this.__contentHover) {
|
|
156
|
+
// this.close();
|
|
157
|
+
// }
|
|
158
|
+
// });
|
|
159
|
+
// this.__invokerHover = false;
|
|
160
|
+
// }
|
|
161
|
+
|
|
162
|
+
// __onContentMouseleave() {
|
|
163
|
+
// setTimeout(() => {
|
|
164
|
+
// if (!this.__invokerHover) {
|
|
165
|
+
// this.close();
|
|
166
|
+
// }
|
|
167
|
+
// });
|
|
168
|
+
// this.__contentHover = false;
|
|
169
|
+
// }
|
|
170
|
+
|
|
171
|
+
// /**
|
|
172
|
+
// * @overridable
|
|
173
|
+
// */
|
|
174
|
+
// _teardownOpenCloseListeners() {
|
|
175
|
+
// if (!this._invokerNode) {
|
|
176
|
+
// return;
|
|
177
|
+
// }
|
|
178
|
+
|
|
179
|
+
// this._invokerNode.removeEventListener('mouseenter', this.open);
|
|
180
|
+
// this._invokerNode.removeEventListener('mouseleave', this.close);
|
|
181
|
+
// this._contentNode?.removeEventListener('mouseenter', this.open);
|
|
182
|
+
// this._contentNode?.removeEventListener('mouseleave', this.close);
|
|
183
|
+
|
|
184
|
+
// // console.log(this, 'removetCLick');
|
|
185
|
+
|
|
186
|
+
// this._invokerNode.removeEventListener('click', this.toggle);
|
|
187
|
+
// }
|
|
188
|
+
|
|
189
|
+
// // TODO: fire event on updated?
|
|
190
|
+
// /**
|
|
191
|
+
// * @override
|
|
192
|
+
// * @param {string} name
|
|
193
|
+
// * @param {any} oldValue
|
|
194
|
+
// */
|
|
195
|
+
// requestUpdate(name, oldValue) {
|
|
196
|
+
// super.requestUpdate(name, oldValue);
|
|
197
|
+
// if (name === 'opened') {
|
|
198
|
+
// this.dispatchEvent(new Event('opened-changed'));
|
|
199
|
+
// }
|
|
200
|
+
// }
|
|
201
|
+
|
|
202
|
+
// /**
|
|
203
|
+
// * @param {import('lit-element').PropertyValues } changedProperties
|
|
204
|
+
// */
|
|
205
|
+
// updated(changedProperties) {
|
|
206
|
+
// super.updated(changedProperties);
|
|
207
|
+
|
|
208
|
+
// if (changedProperties.has('opened')) {
|
|
209
|
+
// this._onOpenedChanged();
|
|
210
|
+
// }
|
|
211
|
+
// }
|
|
212
|
+
|
|
213
|
+
// /**
|
|
214
|
+
// * @param {import('lit-element').PropertyValues } changedProperties
|
|
215
|
+
// */
|
|
216
|
+
// firstUpdated(changedProperties) {
|
|
217
|
+
// super.firstUpdated(changedProperties);
|
|
218
|
+
// this._onOpenedChanged();
|
|
219
|
+
|
|
220
|
+
// if (this.handleFocus && !this._contentNode?.hasAttribute('tabindex')) {
|
|
221
|
+
// this._contentNode?.setAttribute('tabindex', '-1');
|
|
222
|
+
// }
|
|
223
|
+
// }
|
|
224
|
+
|
|
225
|
+
// /**
|
|
226
|
+
// * @overridable
|
|
227
|
+
// */
|
|
228
|
+
// async _onOpenedChanged() {
|
|
229
|
+
// this._invokerNode.setAttribute('aria-expanded', `${this.opened}`);
|
|
230
|
+
|
|
231
|
+
// if (this.opened) {
|
|
232
|
+
// this._contentNode.style.setProperty('display', '');
|
|
233
|
+
// await this._showAnimation({ contentNode: this._contentNode });
|
|
234
|
+
// this._onDisclosureShow();
|
|
235
|
+
// } else {
|
|
236
|
+
// this._onDisclosureHide();
|
|
237
|
+
// await this._hideAnimation({ contentNode: this._contentNode });
|
|
238
|
+
// this._contentNode.style.setProperty('display', 'none');
|
|
239
|
+
// }
|
|
240
|
+
// }
|
|
241
|
+
|
|
242
|
+
// _onDisclosureShow() {
|
|
243
|
+
// // if (this.checkedIndex != null) {
|
|
244
|
+
// // this.activeIndex = this.checkedIndex;
|
|
245
|
+
// // }
|
|
246
|
+
|
|
247
|
+
// if (this.handleFocus) {
|
|
248
|
+
// this._contentNode.focus();
|
|
249
|
+
// }
|
|
250
|
+
// }
|
|
251
|
+
|
|
252
|
+
// _onDisclosureHide() {
|
|
253
|
+
// if (this.handleFocus) {
|
|
254
|
+
// this._invokerNode.focus();
|
|
255
|
+
// }
|
|
256
|
+
// }
|
|
257
|
+
|
|
258
|
+
// /**
|
|
259
|
+
// * Show animation implementation in sub-classer.
|
|
260
|
+
// * @param {{ contentNode: HTMLElement; }} cfg
|
|
261
|
+
// */
|
|
262
|
+
// // eslint-disable-next-line class-methods-use-this, no-empty-function
|
|
263
|
+
// async _showAnimation(cfg) {
|
|
264
|
+
// this._refreshAnimateCompletePromise();
|
|
265
|
+
// }
|
|
266
|
+
|
|
267
|
+
// /**
|
|
268
|
+
// * Hide animation implementation in sub-classer.
|
|
269
|
+
// * @param {{ contentNode: HTMLElement; }} cfg
|
|
270
|
+
// */
|
|
271
|
+
// // eslint-disable-next-line class-methods-use-this, no-empty-function
|
|
272
|
+
// async _hideAnimation(cfg) {
|
|
273
|
+
// this._refreshAnimateCompletePromise();
|
|
274
|
+
// }
|
|
275
|
+
|
|
276
|
+
// _refreshAnimateCompletePromise() {
|
|
277
|
+
// this._animateComplete = new Promise(resolve => {
|
|
278
|
+
// // Note that when a lib like GSAP is used, neither 'transitionend' or 'animationend' will be called.
|
|
279
|
+
// // In such a case, a subclasser needs to resolve this pending promise by calling this method
|
|
280
|
+
// this._resolveAnimateComplete = resolve;
|
|
281
|
+
// });
|
|
282
|
+
// }
|
|
283
|
+
|
|
284
|
+
// __setupAnimation() {
|
|
285
|
+
// this._contentNode.addEventListener('transitionend', this.__handleAnimateComplete);
|
|
286
|
+
// this._contentNode.addEventListener('animationend', this.__handleAnimateComplete);
|
|
287
|
+
// }
|
|
288
|
+
|
|
289
|
+
// __teardownAnimation() {
|
|
290
|
+
// this._contentNode.removeEventListener('transitionend', this.__handleAnimateComplete);
|
|
291
|
+
// this._contentNode.removeEventListener('animationend', this.__handleAnimateComplete);
|
|
292
|
+
// }
|
|
293
|
+
|
|
294
|
+
// __handleAnimateComplete() {
|
|
295
|
+
// if (typeof this._resolveAnimateComplete === 'function') {
|
|
296
|
+
// this._resolveAnimateComplete();
|
|
297
|
+
// }
|
|
298
|
+
// }
|
|
299
|
+
|
|
300
|
+
// toggle() {
|
|
301
|
+
// // console.log('toggul', this);
|
|
302
|
+
// this.opened = !this.opened;
|
|
303
|
+
// }
|
|
304
|
+
|
|
305
|
+
// open() {
|
|
306
|
+
// this.opened = true;
|
|
307
|
+
// }
|
|
308
|
+
|
|
309
|
+
// close() {
|
|
310
|
+
// this.opened = false;
|
|
311
|
+
// }
|
|
312
|
+
// };
|
|
313
|
+
// export const DisclosureMixin = dedupeMixin(DisclosureMixinImplementation);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Constructor } from '@open-wc/dedupe-mixin';
|
|
2
|
+
import { LitElement } from 'lit';
|
|
3
|
+
|
|
4
|
+
export declare class DisclosureHost {
|
|
5
|
+
public opened: Boolean;
|
|
6
|
+
|
|
7
|
+
protected get _invokerNode(): HTMLElement;
|
|
8
|
+
|
|
9
|
+
protected get _contentNode(): HTMLElement;
|
|
10
|
+
|
|
11
|
+
public toggle(): void;
|
|
12
|
+
|
|
13
|
+
public open(): void;
|
|
14
|
+
|
|
15
|
+
public close(): void;
|
|
16
|
+
|
|
17
|
+
protected _onOpenedChanged(): Promise<void>;
|
|
18
|
+
|
|
19
|
+
protected _onDisclosureShow(): void;
|
|
20
|
+
|
|
21
|
+
protected _onDisclosureHide(): void;
|
|
22
|
+
|
|
23
|
+
protected _showAnimation(cfg: object): Promise<void>;
|
|
24
|
+
|
|
25
|
+
protected _hideAnimation(cfg: object): Promise<void>;
|
|
26
|
+
|
|
27
|
+
protected _refreshAnimateCompletePromise(): void;
|
|
28
|
+
|
|
29
|
+
protected _setupOpenCloseListeners(): void;
|
|
30
|
+
|
|
31
|
+
protected _teardownOpenCloseListeners(): void;
|
|
32
|
+
|
|
33
|
+
private __setupAnimation(): void;
|
|
34
|
+
|
|
35
|
+
private __teardownAnimation(): void;
|
|
36
|
+
|
|
37
|
+
private __handleAnimateComplete(): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export declare function DisclosureImplementation<T extends Constructor<LitElement>>(
|
|
41
|
+
superclass: T,
|
|
42
|
+
): T &
|
|
43
|
+
Constructor<DisclosureHost> &
|
|
44
|
+
DisclosureHost &
|
|
45
|
+
Pick<typeof DisclosureHost, keyof typeof DisclosureHost> &
|
|
46
|
+
Pick<typeof LitElement, keyof typeof LitElement>;
|
|
47
|
+
|
|
48
|
+
export type DisclosureMixin = typeof DisclosureImplementation;
|
|
@@ -9,7 +9,9 @@ export function makeMatchingTextBold(root, matchingString) {
|
|
|
9
9
|
if (childNode.nodeName === '#text') {
|
|
10
10
|
// check for match based on nodeValue
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
// Escape special regex characters in matchingString
|
|
13
|
+
const escapedString = matchingString.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
14
|
+
const re = new RegExp(`^(.*?)(${escapedString})(.*)$`, 'i');
|
|
13
15
|
// @ts-ignore
|
|
14
16
|
const match = childNode.nodeValue.match(re);
|
|
15
17
|
|
|
@@ -3227,6 +3227,7 @@ describe('lion-combobox', () => {
|
|
|
3227
3227
|
const [el, options] = await fruitFixture({ autocomplete: 'both', matchMode: 'all' });
|
|
3228
3228
|
await mimicUserTyping(/** @type {LionCombobox} */ (el), 'choke');
|
|
3229
3229
|
await el.updateComplete;
|
|
3230
|
+
// @ts-ignore - array index access
|
|
3230
3231
|
const labelledElement = options[0].querySelector('span[aria-label="Artichoke"]');
|
|
3231
3232
|
expect(labelledElement).to.not.be.null;
|
|
3232
3233
|
expect(labelledElement.innerText).to.equal('Artichoke');
|
|
@@ -3648,4 +3649,108 @@ describe('lion-combobox', () => {
|
|
|
3648
3649
|
expect(el.opened).to.be.true;
|
|
3649
3650
|
});
|
|
3650
3651
|
});
|
|
3652
|
+
|
|
3653
|
+
describe('Special Characters in Search', () => {
|
|
3654
|
+
it('correctly escapes all regex special characters in search queries', async () => {
|
|
3655
|
+
const el = /** @type {LionCombobox} */ (
|
|
3656
|
+
await fixture(html`
|
|
3657
|
+
<lion-combobox label="Search" name="foo">
|
|
3658
|
+
<lion-option .choiceValue="${'test.com'}">test.com</lion-option>
|
|
3659
|
+
<lion-option .choiceValue="${'func(arg)'}">func(arg)</lion-option>
|
|
3660
|
+
<lion-option .choiceValue="${'array[0]'}">array[0]</lion-option>
|
|
3661
|
+
<lion-option .choiceValue="${'C++'}">C++</lion-option>
|
|
3662
|
+
<lion-option .choiceValue="${'a * b'}">a * b</lion-option>
|
|
3663
|
+
<lion-option .choiceValue="${'What?'}">What?</lion-option>
|
|
3664
|
+
<lion-option .choiceValue="${'$100'}">$100</lion-option>
|
|
3665
|
+
<lion-option .choiceValue="${'x^2'}">x^2</lion-option>
|
|
3666
|
+
<lion-option .choiceValue="${'a | b'}">a | b</lion-option>
|
|
3667
|
+
<lion-option .choiceValue="${'path\\file'}">path\\file</lion-option>
|
|
3668
|
+
<lion-option .choiceValue="${'{name}'}">{name}</lion-option>
|
|
3669
|
+
<lion-option .choiceValue="${'user+tag@example.com'}">user+tag@example.com</lion-option>
|
|
3670
|
+
<lion-option .choiceValue="${'(a+b)*c^2$'}">>(a+b)*c^2$</lion-option>
|
|
3671
|
+
<lion-option .choiceValue="${'test|value?[x]'}">test|value?[x]</lion-option>
|
|
3672
|
+
<lion-option .choiceValue="${'file.{txt|md}\\n'}">file.{txt|md}\\n</lion-option>
|
|
3673
|
+
<lion-option .choiceValue="${'testXcom'}">testXcom</lion-option>
|
|
3674
|
+
<lion-option .choiceValue="${'funcXargX'}">funcXargX</lion-option>
|
|
3675
|
+
<lion-option .choiceValue="${'arrayX0X'}">arrayX0X</lion-option>
|
|
3676
|
+
</lion-combobox>
|
|
3677
|
+
`)
|
|
3678
|
+
);
|
|
3679
|
+
|
|
3680
|
+
// Test dot - should not act as wildcard
|
|
3681
|
+
await mimicUserTyping(el, 'test.com');
|
|
3682
|
+
await el.updateComplete;
|
|
3683
|
+
expect(getFilteredOptionValues(el)).to.eql(['test.com']);
|
|
3684
|
+
|
|
3685
|
+
// Test parentheses
|
|
3686
|
+
await mimicUserTyping(el, '(arg)');
|
|
3687
|
+
await el.updateComplete;
|
|
3688
|
+
expect(getFilteredOptionValues(el)).to.eql(['func(arg)']);
|
|
3689
|
+
|
|
3690
|
+
// Test square brackets
|
|
3691
|
+
await mimicUserTyping(el, '[0]');
|
|
3692
|
+
await el.updateComplete;
|
|
3693
|
+
expect(getFilteredOptionValues(el)).to.eql(['array[0]']);
|
|
3694
|
+
|
|
3695
|
+
// Test plus sign
|
|
3696
|
+
await mimicUserTyping(el, '+');
|
|
3697
|
+
await el.updateComplete;
|
|
3698
|
+
expect(getFilteredOptionValues(el)).to.eql(['C++', 'user+tag@example.com', '(a+b)*c^2$']);
|
|
3699
|
+
|
|
3700
|
+
// Test asterisk
|
|
3701
|
+
await mimicUserTyping(el, '*');
|
|
3702
|
+
await el.updateComplete;
|
|
3703
|
+
expect(getFilteredOptionValues(el)).to.eql(['a * b', '(a+b)*c^2$']);
|
|
3704
|
+
|
|
3705
|
+
// Test question mark
|
|
3706
|
+
await mimicUserTyping(el, '?');
|
|
3707
|
+
await el.updateComplete;
|
|
3708
|
+
expect(getFilteredOptionValues(el)).to.eql(['What?', 'test|value?[x]']);
|
|
3709
|
+
|
|
3710
|
+
// Test dollar sign
|
|
3711
|
+
await mimicUserTyping(el, '$');
|
|
3712
|
+
await el.updateComplete;
|
|
3713
|
+
expect(getFilteredOptionValues(el)).to.eql(['$100', '(a+b)*c^2$']);
|
|
3714
|
+
|
|
3715
|
+
// Test caret
|
|
3716
|
+
await mimicUserTyping(el, '^2');
|
|
3717
|
+
await el.updateComplete;
|
|
3718
|
+
expect(getFilteredOptionValues(el)).to.eql(['x^2', '(a+b)*c^2$']);
|
|
3719
|
+
|
|
3720
|
+
// Test pipe
|
|
3721
|
+
await mimicUserTyping(el, '|');
|
|
3722
|
+
await el.updateComplete;
|
|
3723
|
+
expect(getFilteredOptionValues(el)).to.eql(['a | b', 'test|value?[x]', 'file.{txt|md}\\n']);
|
|
3724
|
+
|
|
3725
|
+
// Test backslash
|
|
3726
|
+
await mimicUserTyping(el, '\\');
|
|
3727
|
+
await el.updateComplete;
|
|
3728
|
+
expect(getFilteredOptionValues(el)).to.eql(['path\\file', 'file.{txt|md}\\n']);
|
|
3729
|
+
|
|
3730
|
+
// Test curly braces
|
|
3731
|
+
await mimicUserTyping(el, '{name}');
|
|
3732
|
+
await el.updateComplete;
|
|
3733
|
+
expect(getFilteredOptionValues(el)).to.eql(['{name}']);
|
|
3734
|
+
|
|
3735
|
+
// Test complex combination with multiple special characters
|
|
3736
|
+
await mimicUserTyping(el, '(a+b)*c');
|
|
3737
|
+
await el.updateComplete;
|
|
3738
|
+
expect(getFilteredOptionValues(el)).to.eql(['(a+b)*c^2$']);
|
|
3739
|
+
|
|
3740
|
+
// Test email with plus and dot
|
|
3741
|
+
await mimicUserTyping(el, 'user+tag@example.com');
|
|
3742
|
+
await el.updateComplete;
|
|
3743
|
+
expect(getFilteredOptionValues(el)).to.eql(['user+tag@example.com']);
|
|
3744
|
+
|
|
3745
|
+
// Test combination with brackets, pipe and question mark
|
|
3746
|
+
await mimicUserTyping(el, 'value?[x]');
|
|
3747
|
+
await el.updateComplete;
|
|
3748
|
+
expect(getFilteredOptionValues(el)).to.eql(['test|value?[x]']);
|
|
3749
|
+
|
|
3750
|
+
// Test combination with dot, curly braces, pipe and backslash
|
|
3751
|
+
await mimicUserTyping(el, '.{txt|md}');
|
|
3752
|
+
await el.updateComplete;
|
|
3753
|
+
expect(getFilteredOptionValues(el)).to.eql(['file.{txt|md}\\n']);
|
|
3754
|
+
});
|
|
3755
|
+
});
|
|
3651
3756
|
});
|
|
@@ -352,11 +352,14 @@ const FormGroupMixinImplementation = superclass =>
|
|
|
352
352
|
this.formElements._keys().forEach(name => {
|
|
353
353
|
const elem = this.formElements[name];
|
|
354
354
|
if (elem instanceof FormControlsCollection) {
|
|
355
|
+
// @ts-ignore - dynamic property access
|
|
355
356
|
result[name] = elem.filter(el => _filterFn(el, property)).map(el => el[property]);
|
|
356
357
|
} else if (_filterFn(elem, property)) {
|
|
357
358
|
if (typeof elem._getFromAllFormElements === 'function') {
|
|
359
|
+
// @ts-ignore - dynamic property access
|
|
358
360
|
result[name] = elem._getFromAllFormElements(property);
|
|
359
361
|
} else {
|
|
362
|
+
// @ts-ignore - dynamic property access
|
|
360
363
|
result[name] = elem[property];
|
|
361
364
|
}
|
|
362
365
|
}
|
|
@@ -386,6 +389,7 @@ const FormGroupMixinImplementation = superclass =>
|
|
|
386
389
|
if (Array.isArray(this.formElements[name])) {
|
|
387
390
|
this.formElements[name].forEach(
|
|
388
391
|
(/** @type {FormControl} */ el, /** @type {number} */ index) => {
|
|
392
|
+
// @ts-ignore - dynamic property access
|
|
389
393
|
el[property] = values[name][index]; // eslint-disable-line no-param-reassign
|
|
390
394
|
},
|
|
391
395
|
);
|
|
@@ -393,6 +397,7 @@ const FormGroupMixinImplementation = superclass =>
|
|
|
393
397
|
if (this.formElements[name]) {
|
|
394
398
|
this.formElements[name][property] = values[name];
|
|
395
399
|
} else {
|
|
400
|
+
// @ts-ignore - dynamic property access
|
|
396
401
|
this.__pendingValues[property][name] = values[name];
|
|
397
402
|
}
|
|
398
403
|
});
|
|
@@ -406,6 +411,7 @@ const FormGroupMixinImplementation = superclass =>
|
|
|
406
411
|
_anyFormElementHas(property) {
|
|
407
412
|
return Object.keys(this.formElements).some(name => {
|
|
408
413
|
if (Array.isArray(this.formElements[name])) {
|
|
414
|
+
// @ts-ignore - dynamic property access
|
|
409
415
|
return this.formElements[name].some((/** @type {FormControl} */ el) => !!el[property]);
|
|
410
416
|
}
|
|
411
417
|
return !!this.formElements[name][property];
|
|
@@ -436,6 +442,7 @@ const FormGroupMixinImplementation = superclass =>
|
|
|
436
442
|
_everyFormElementHas(property) {
|
|
437
443
|
return Object.keys(this.formElements).every(name => {
|
|
438
444
|
if (Array.isArray(this.formElements[name])) {
|
|
445
|
+
// @ts-ignore - dynamic property access
|
|
439
446
|
return this.formElements[name].every((/** @type {FormControl} */ el) => !!el[property]);
|
|
440
447
|
}
|
|
441
448
|
return !!this.formElements[name][property];
|
|
@@ -162,15 +162,21 @@ const FormRegistrarMixinImplementation = superclass =>
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
if (name.substr(-2) === '[]') {
|
|
165
|
+
// @ts-ignore - dynamic named access to form elements
|
|
165
166
|
if (!Array.isArray(this.formElements[name])) {
|
|
167
|
+
// @ts-ignore
|
|
166
168
|
this.formElements[name] = new FormControlsCollection();
|
|
167
169
|
}
|
|
168
170
|
if (indexToInsertAt > 0) {
|
|
171
|
+
// @ts-ignore
|
|
169
172
|
this.formElements[name].splice(indexToInsertAt, 0, child);
|
|
170
173
|
} else {
|
|
174
|
+
// @ts-ignore
|
|
171
175
|
this.formElements[name].push(child);
|
|
172
176
|
}
|
|
177
|
+
// @ts-ignore
|
|
173
178
|
} else if (!this.formElements[name]) {
|
|
179
|
+
// @ts-ignore
|
|
174
180
|
this.formElements[name] = child;
|
|
175
181
|
} else {
|
|
176
182
|
console.info('Error Node:', child); // eslint-disable-line no-console
|
|
@@ -194,12 +200,17 @@ const FormRegistrarMixinImplementation = superclass =>
|
|
|
194
200
|
// 2. Handle name based object keys
|
|
195
201
|
if (this._isFormOrFieldset) {
|
|
196
202
|
const { name } = child; // FIXME: <-- ElementWithParentFormGroup should become LionFieldWithParentFormGroup so that "name" exists
|
|
203
|
+
// @ts-ignore - dynamic named access to form elements
|
|
197
204
|
if (name.substr(-2) === '[]' && this.formElements[name]) {
|
|
205
|
+
// @ts-ignore
|
|
198
206
|
const idx = this.formElements[name].indexOf(child);
|
|
199
207
|
if (idx > -1) {
|
|
208
|
+
// @ts-ignore
|
|
200
209
|
this.formElements[name].splice(idx, 1);
|
|
201
210
|
}
|
|
211
|
+
// @ts-ignore
|
|
202
212
|
} else if (this.formElements[name]) {
|
|
213
|
+
// @ts-ignore
|
|
203
214
|
delete this.formElements[name];
|
|
204
215
|
}
|
|
205
216
|
}
|
|
@@ -153,6 +153,7 @@ describe('FormControlMixin', () => {
|
|
|
153
153
|
el.shadowRoot?.querySelector('.form-field__label'),
|
|
154
154
|
);
|
|
155
155
|
Object.entries(expectedValues).forEach(([key, val]) => {
|
|
156
|
+
// @ts-ignore - dynamic style property access
|
|
156
157
|
expect(labelStyle[key]).to.equal(val);
|
|
157
158
|
});
|
|
158
159
|
});
|
|
@@ -191,7 +191,9 @@ describe('Validator', () => {
|
|
|
191
191
|
it('adds static ["_$isValidator$"] property as a marker to identify the Validator class across different lion versions (as instanceof cannot be used)', async () => {
|
|
192
192
|
const myValidator = new Validator();
|
|
193
193
|
|
|
194
|
+
// @ts-ignore - static property access
|
|
194
195
|
expect(myValidator.constructor['_$isValidator$']).to.exist;
|
|
196
|
+
// @ts-ignore - static property access
|
|
195
197
|
expect(myValidator.constructor['_$isValidator$']).to.be.true;
|
|
196
198
|
});
|
|
197
199
|
|
|
@@ -1554,11 +1554,13 @@ export function runValidateMixinSuite(customConfig) {
|
|
|
1554
1554
|
// eslint-disable-next-line no-restricted-syntax
|
|
1555
1555
|
for (const state of ['dirty', 'touched', 'prefilled', 'submitted']) {
|
|
1556
1556
|
counter += 1;
|
|
1557
|
+
// @ts-ignore - test property access
|
|
1557
1558
|
el[state] = false;
|
|
1558
1559
|
// eslint-disable-next-line no-await-in-loop
|
|
1559
1560
|
await el.updateComplete;
|
|
1560
1561
|
expect(spy.callCount).to.equal(counter);
|
|
1561
1562
|
counter += 1;
|
|
1563
|
+
// @ts-ignore - test property access
|
|
1562
1564
|
el[state] = true;
|
|
1563
1565
|
// eslint-disable-next-line no-await-in-loop
|
|
1564
1566
|
await el.updateComplete;
|