@lion/ui 0.0.2 → 0.0.4
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/components/core/src/SlotMixin.js +180 -42
- package/components/core/test/SlotMixin.test.js +355 -145
- package/components/core/types/SlotMixinTypes.ts +12 -1
- package/components/input-tel/src/LionInputTel.js +0 -9
- package/components/input-tel-dropdown/src/LionInputTelDropdown.js +32 -29
- package/components/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.js +5 -6
- package/components/localize/src/number/parseNumber.js +15 -36
- package/components/localize/test/number/parseNumber.test.js +3 -12
- package/components/localize/types/LocalizeMixinTypes.ts +1 -1
- package/custom-elements.json +1435 -133
- package/dist-types/components/calendar/src/LionCalendar.d.ts +1 -37
- package/dist-types/components/calendar/src/LionCalendar.d.ts.map +1 -1
- package/dist-types/components/core/src/SlotMixin.d.ts +2 -0
- package/dist-types/components/core/src/SlotMixin.d.ts.map +1 -1
- package/dist-types/components/core/test/SlotMixin.test.d.ts +1 -1
- package/dist-types/components/core/test/SlotMixin.test.d.ts.map +1 -1
- package/dist-types/components/core/types/SlotMixinTypes.d.ts +9 -1
- package/dist-types/components/core/types/SlotMixinTypes.d.ts.map +1 -1
- package/dist-types/components/input-amount/src/LionInputAmount.d.ts +1 -37
- package/dist-types/components/input-amount/src/LionInputAmount.d.ts.map +1 -1
- package/dist-types/components/input-date/src/LionInputDate.d.ts +1 -37
- package/dist-types/components/input-date/src/LionInputDate.d.ts.map +1 -1
- package/dist-types/components/input-datepicker/src/LionCalendarOverlayFrame.d.ts +1 -37
- package/dist-types/components/input-datepicker/src/LionCalendarOverlayFrame.d.ts.map +1 -1
- package/dist-types/components/input-email/src/LionInputEmail.d.ts +1 -37
- package/dist-types/components/input-email/src/LionInputEmail.d.ts.map +1 -1
- package/dist-types/components/input-iban/src/LionInputIban.d.ts +1 -37
- package/dist-types/components/input-iban/src/LionInputIban.d.ts.map +1 -1
- package/dist-types/components/input-tel/src/LionInputTel.d.ts +1 -42
- package/dist-types/components/input-tel/src/LionInputTel.d.ts.map +1 -1
- package/dist-types/components/input-tel-dropdown/src/LionInputTelDropdown.d.ts +14 -8
- package/dist-types/components/input-tel-dropdown/src/LionInputTelDropdown.d.ts.map +1 -1
- package/dist-types/components/input-tel-dropdown/test-suites/LionInputTelDropdown.suite.d.ts.map +1 -1
- package/dist-types/components/localize/src/LocalizeMixin.d.ts +1 -37
- package/dist-types/components/localize/src/LocalizeMixin.d.ts.map +1 -1
- package/dist-types/components/localize/src/number/parseNumber.d.ts.map +1 -1
- package/dist-types/components/localize/types/LocalizeMixinTypes.d.ts +1 -1
- package/dist-types/components/localize/types/LocalizeMixinTypes.d.ts.map +1 -1
- package/dist-types/components/pagination/src/LionPagination.d.ts +1 -37
- package/dist-types/components/pagination/src/LionPagination.d.ts.map +1 -1
- package/dist-types/components/progress-indicator/src/LionProgressIndicator.d.ts +1 -37
- package/dist-types/components/progress-indicator/src/LionProgressIndicator.d.ts.map +1 -1
- package/dist-types/exports/core.d.ts +1 -0
- package/dist-types/exports/core.d.ts.map +1 -1
- package/dist-types/exports/form-core.d.ts +2 -0
- package/dist-types/exports/form-core.d.ts.map +1 -1
- package/dist-types/exports/input-tel-dropdown.d.ts +2 -0
- package/dist-types/exports/input-tel-dropdown.d.ts.map +1 -1
- package/dist-types/exports/input-tel.d.ts +1 -0
- package/dist-types/exports/input-tel.d.ts.map +1 -1
- package/dist-types/exports/localize.d.ts +3 -0
- package/dist-types/exports/localize.d.ts.map +1 -1
- package/dist-types/exports/overlays.d.ts +4 -0
- package/dist-types/exports/overlays.d.ts.map +1 -1
- package/dist-types/tsconfig.tsbuildinfo +1 -1
- package/docs/components/accordion/index.md +3 -0
- package/docs/components/accordion/overview.md +129 -0
- package/docs/components/accordion/reference.md +47 -0
- package/docs/components/accordion/use-cases.md +252 -0
- package/docs/components/button/examples.md +30 -0
- package/docs/components/button/index.md +3 -0
- package/docs/components/button/overview.md +30 -0
- package/docs/components/button/src/icon.svg.js +5 -0
- package/docs/components/button/use-cases.md +106 -0
- package/docs/components/calendar/index.md +3 -0
- package/docs/components/calendar/overview.md +49 -0
- package/docs/components/calendar/use-cases.md +192 -0
- package/docs/components/checkbox-group/index.md +3 -0
- package/docs/components/checkbox-group/overview.md +40 -0
- package/docs/components/checkbox-group/use-cases.md +256 -0
- package/docs/components/collapsible/assets/CustomCollapsible.js +113 -0
- package/docs/components/collapsible/assets/applyDemoCollapsibleStyles.js +37 -0
- package/docs/components/collapsible/examples.md +83 -0
- package/docs/components/collapsible/index.md +3 -0
- package/docs/components/collapsible/overview.md +39 -0
- package/docs/components/collapsible/use-cases.md +79 -0
- package/docs/components/combobox/examples.md +153 -0
- package/docs/components/combobox/index.md +3 -0
- package/docs/components/combobox/overview.md +51 -0
- package/docs/components/combobox/src/LinkMixin.js +60 -0
- package/docs/components/combobox/src/demo-selection-display.js +191 -0
- package/docs/components/combobox/src/gh-combobox/gh-button.js +69 -0
- package/docs/components/combobox/src/gh-combobox/gh-combobox.js +508 -0
- package/docs/components/combobox/src/google-combobox/assets/google-clear-icon.js +9 -0
- package/docs/components/combobox/src/google-combobox/assets/google-search-icon.js +9 -0
- package/docs/components/combobox/src/google-combobox/assets/google-voice-search-icon.js +19 -0
- package/docs/components/combobox/src/google-combobox/assets/googlelogo_color_272x92dp.png +0 -0
- package/docs/components/combobox/src/google-combobox/google-combobox.js +460 -0
- package/docs/components/combobox/src/lazyRender.js +29 -0
- package/docs/components/combobox/src/levenshtein.js +95 -0
- package/docs/components/combobox/src/md-combobox/MdFieldMixin.js +341 -0
- package/docs/components/combobox/src/md-combobox/md-combobox.js +89 -0
- package/docs/components/combobox/src/md-combobox/md-input.js +5 -0
- package/docs/components/combobox/src/md-combobox/style/load-roboto.js +6 -0
- package/docs/components/combobox/src/md-combobox/style/md-ripple.js +81 -0
- package/docs/components/combobox/src/wa-combobox/wa-combobox.js +368 -0
- package/docs/components/combobox/use-cases.md +377 -0
- package/docs/components/dialog/index.md +3 -0
- package/docs/components/dialog/overview.md +63 -0
- package/docs/components/dialog/src/demo-dialog-style.js +3 -0
- package/docs/components/dialog/src/demoStyle.js +39 -0
- package/docs/components/dialog/src/slots-dialog-content.js +32 -0
- package/docs/components/dialog/src/styled-dialog-content.js +38 -0
- package/docs/components/dialog/use-cases.md +154 -0
- package/docs/components/drawer/index.md +3 -0
- package/docs/components/drawer/overview.md +68 -0
- package/docs/components/drawer/src/demoStyle.js +71 -0
- package/docs/components/drawer/use-cases.md +194 -0
- package/docs/components/fieldset/index.md +3 -0
- package/docs/components/fieldset/overview.md +49 -0
- package/docs/components/fieldset/use-cases.md +185 -0
- package/docs/components/form/index.md +3 -0
- package/docs/components/form/overview.md +43 -0
- package/docs/components/form/use-cases.md +72 -0
- package/docs/components/icon/assets/bugs/bug01.svg.js +2 -0
- package/docs/components/icon/assets/bugs/bug02.svg.js +2 -0
- package/docs/components/icon/assets/bugs/bug05.svg.js +2 -0
- package/docs/components/icon/assets/bugs/bug06.svg.js +2 -0
- package/docs/components/icon/assets/bugs/bug08.svg.js +2 -0
- package/docs/components/icon/assets/bugs/bug12.svg.js +2 -0
- package/docs/components/icon/assets/bugs/bug19.svg.js +2 -0
- package/docs/components/icon/assets/bugs/bug23.svg.js +2 -0
- package/docs/components/icon/assets/bugs/bug24.svg.js +2 -0
- package/docs/components/icon/assets/iconset-bugs.js +11 -0
- package/docs/components/icon/assets/iconset-misc.js +3 -0
- package/docs/components/icon/assets/iconset-space.js +31 -0
- package/docs/components/icon/assets/misc/arrowLeft.svg.js +6 -0
- package/docs/components/icon/assets/space/aliens-spaceship.svg.js +2 -0
- package/docs/components/icon/assets/space/meteor.svg.js +2 -0
- package/docs/components/icon/assets/space/moon-flag.svg.js +2 -0
- package/docs/components/icon/assets/space/moon.svg.js +2 -0
- package/docs/components/icon/assets/space/night.svg.js +2 -0
- package/docs/components/icon/assets/space/orbit.svg.js +2 -0
- package/docs/components/icon/assets/space/planet.svg.js +2 -0
- package/docs/components/icon/assets/space/robot.svg.js +2 -0
- package/docs/components/icon/assets/space/rocket.svg.js +2 -0
- package/docs/components/icon/assets/space/satellite.svg.js +2 -0
- package/docs/components/icon/assets/space/signal.svg.js +2 -0
- package/docs/components/icon/assets/space/space-helmet.svg.js +2 -0
- package/docs/components/icon/assets/space/sun.svg.js +2 -0
- package/docs/components/icon/assets/space/telescope.svg.js +2 -0
- package/docs/components/icon/index.md +3 -0
- package/docs/components/icon/overview.md +40 -0
- package/docs/components/icon/use-cases.md +93 -0
- package/docs/components/index.md +7 -0
- package/docs/components/input/index.md +3 -0
- package/docs/components/input/overview.md +36 -0
- package/docs/components/input/use-cases.md +77 -0
- package/docs/components/input-amount/index.md +3 -0
- package/docs/components/input-amount/overview.md +49 -0
- package/docs/components/input-amount/use-cases.md +122 -0
- package/docs/components/input-date/index.md +3 -0
- package/docs/components/input-date/overview.md +39 -0
- package/docs/components/input-date/use-cases.md +83 -0
- package/docs/components/input-datepicker/index.md +3 -0
- package/docs/components/input-datepicker/overview.md +42 -0
- package/docs/components/input-datepicker/use-cases.md +78 -0
- package/docs/components/input-email/index.md +3 -0
- package/docs/components/input-email/overview.md +32 -0
- package/docs/components/input-email/use-cases.md +48 -0
- package/docs/components/input-iban/index.md +3 -0
- package/docs/components/input-iban/overview.md +37 -0
- package/docs/components/input-iban/use-cases.md +102 -0
- package/docs/components/input-range/index.md +3 -0
- package/docs/components/input-range/overview.md +34 -0
- package/docs/components/input-range/use-cases.md +108 -0
- package/docs/components/input-stepper/index.md +3 -0
- package/docs/components/input-stepper/overview.md +36 -0
- package/docs/components/input-stepper/use-cases.md +41 -0
- package/docs/components/input-tel/index.md +3 -0
- package/docs/components/input-tel/overview.md +62 -0
- package/docs/components/input-tel/src/h-region-code-table.js +109 -0
- package/docs/components/input-tel/use-cases.md +307 -0
- package/docs/components/input-tel-dropdown/examples.md +32 -0
- package/docs/components/input-tel-dropdown/index.md +3 -0
- package/docs/components/input-tel-dropdown/overview.md +38 -0
- package/docs/components/input-tel-dropdown/src/intl-input-tel-dropdown.js +127 -0
- package/docs/components/input-tel-dropdown/use-cases.md +159 -0
- package/docs/components/listbox/index.md +3 -0
- package/docs/components/listbox/overview.md +42 -0
- package/docs/components/listbox/src/listboxData.js +65 -0
- package/docs/components/listbox/use-cases.md +147 -0
- package/docs/components/pagination/index.md +3 -0
- package/docs/components/pagination/overview.md +29 -0
- package/docs/components/pagination/use-cases.md +99 -0
- package/docs/components/progress-indicator/assets/my-determinate-progress-bar.js +30 -0
- package/docs/components/progress-indicator/assets/my-indeterminate-progress-spinner.js +55 -0
- package/docs/components/progress-indicator/examples.md +125 -0
- package/docs/components/progress-indicator/index.md +3 -0
- package/docs/components/progress-indicator/overview.md +36 -0
- package/docs/components/radio-group/index.md +3 -0
- package/docs/components/radio-group/overview.md +46 -0
- package/docs/components/radio-group/use-cases.md +140 -0
- package/docs/components/select/index.md +3 -0
- package/docs/components/select/overview.md +44 -0
- package/docs/components/select/use-cases.md +55 -0
- package/docs/components/select-rich/examples.md +31 -0
- package/docs/components/select-rich/index.md +3 -0
- package/docs/components/select-rich/overview.md +46 -0
- package/docs/components/select-rich/src/flagStyles.js +1250 -0
- package/docs/components/select-rich/src/flags.png +0 -0
- package/docs/components/select-rich/src/flags@2x.png +0 -0
- package/docs/components/select-rich/src/intl-select-rich.js +194 -0
- package/docs/components/select-rich/src/regionMetaList.js +1717 -0
- package/docs/components/select-rich/use-cases.md +370 -0
- package/docs/components/steps/index.md +3 -0
- package/docs/components/steps/overview.md +63 -0
- package/docs/components/steps/use-cases.md +163 -0
- package/docs/components/switch/index.md +3 -0
- package/docs/components/switch/overview.md +75 -0
- package/docs/components/switch/reference.md +39 -0
- package/docs/components/switch/use-cases.md +76 -0
- package/docs/components/tabs/examples.md +23 -0
- package/docs/components/tabs/index.md +3 -0
- package/docs/components/tabs/overview.md +48 -0
- package/docs/components/tabs/src/lea-tab-panel.js +24 -0
- package/docs/components/tabs/src/lea-tab.js +45 -0
- package/docs/components/tabs/src/lea-tabs.js +28 -0
- package/docs/components/tabs/use-cases.md +219 -0
- package/docs/components/textarea/index.md +3 -0
- package/docs/components/textarea/overview.md +35 -0
- package/docs/components/textarea/use-cases.md +95 -0
- package/docs/components/tooltip/examples.md +39 -0
- package/docs/components/tooltip/index.md +3 -0
- package/docs/components/tooltip/overview.md +44 -0
- package/docs/components/tooltip/use-cases.md +208 -0
- package/docs/fundamentals/index.md +19 -0
- package/docs/fundamentals/node-tools/babel-plugin-extend-docs/index.md +1 -0
- package/docs/fundamentals/node-tools/babel-plugin-extend-docs/overview.md +233 -0
- package/docs/fundamentals/node-tools/index.md +1 -0
- package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +68 -0
- package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +111 -0
- package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +69 -0
- package/docs/fundamentals/node-tools/providence-analytics/assets/_mermaid.svg.js +1202 -0
- package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +22 -0
- package/docs/fundamentals/node-tools/providence-analytics/index.md +1 -0
- package/docs/fundamentals/node-tools/providence-analytics/overview.md +192 -0
- package/docs/fundamentals/node-tools/publish-docs/index.md +1 -0
- package/docs/fundamentals/node-tools/publish-docs/overview.md +136 -0
- package/docs/fundamentals/node-tools/remark-extend/index.md +1 -0
- package/docs/fundamentals/node-tools/remark-extend/overview.md +274 -0
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/index.md +1 -0
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +285 -0
- package/docs/fundamentals/rationales/TypeScript.md +18 -0
- package/docs/fundamentals/rationales/index.md +1 -0
- package/docs/fundamentals/rationales/side-effects.md +203 -0
- package/docs/fundamentals/rationales/versioning.md +35 -0
- package/docs/fundamentals/systems/core/index.md +3 -0
- package/docs/fundamentals/systems/core/overview.md +85 -0
- package/docs/fundamentals/systems/form/assets/FormatMixinDiagram-1.svg +1 -0
- package/docs/fundamentals/systems/form/assets/FormatMixinDiagram-2.svg +1 -0
- package/docs/fundamentals/systems/form/assets/FormatMixinDiagram-3.svg +84 -0
- package/docs/fundamentals/systems/form/assets/h-output.js +155 -0
- package/docs/fundamentals/systems/form/formatting-and-parsing.md +245 -0
- package/docs/fundamentals/systems/form/index.md +3 -0
- package/docs/fundamentals/systems/form/interaction-states.md +177 -0
- package/docs/fundamentals/systems/form/model-value.md +35 -0
- package/docs/fundamentals/systems/form/overview.md +82 -0
- package/docs/fundamentals/systems/form/styling.md +101 -0
- package/docs/fundamentals/systems/form/use-cases.md +156 -0
- package/docs/fundamentals/systems/form/validate.md +929 -0
- package/docs/fundamentals/systems/icon/index.md +3 -0
- package/docs/fundamentals/systems/icon/overview.md +124 -0
- package/docs/fundamentals/systems/index.md +1 -0
- package/docs/fundamentals/systems/localize/assets/all-locales.js +437 -0
- package/docs/fundamentals/systems/localize/assets/en-AU.js +6 -0
- package/docs/fundamentals/systems/localize/assets/en-GB.js +6 -0
- package/docs/fundamentals/systems/localize/assets/en-US.js +6 -0
- package/docs/fundamentals/systems/localize/assets/en.js +4 -0
- package/docs/fundamentals/systems/localize/assets/nl-BE.js +6 -0
- package/docs/fundamentals/systems/localize/assets/nl-NL.js +6 -0
- package/docs/fundamentals/systems/localize/assets/nl.js +4 -0
- package/docs/fundamentals/systems/localize/dates.md +195 -0
- package/docs/fundamentals/systems/localize/index.md +3 -0
- package/docs/fundamentals/systems/localize/numbers.md +217 -0
- package/docs/fundamentals/systems/localize/overview.md +48 -0
- package/docs/fundamentals/systems/localize/rationale.md +62 -0
- package/docs/fundamentals/systems/localize/text.md +125 -0
- package/docs/fundamentals/systems/localize/use-cases.md +319 -0
- package/docs/fundamentals/systems/overlays/assets/applyDemoOverlayStyles.js +22 -0
- package/docs/fundamentals/systems/overlays/assets/demo-overlay-backdrop.js +48 -0
- package/docs/fundamentals/systems/overlays/assets/demo-overlay-system.js +42 -0
- package/docs/fundamentals/systems/overlays/assets/umbrella-form.js +133 -0
- package/docs/fundamentals/systems/overlays/configuration.md +453 -0
- package/docs/fundamentals/systems/overlays/form-integration.md +65 -0
- package/docs/fundamentals/systems/overlays/index.md +3 -0
- package/docs/fundamentals/systems/overlays/overview.md +118 -0
- package/docs/fundamentals/systems/overlays/rationale.md +232 -0
- package/docs/fundamentals/systems/overlays/scope.md +176 -0
- package/docs/fundamentals/systems/overlays/use-cases.md +699 -0
- package/docs/fundamentals/tools/ajax/assets/naga.json +9 -0
- package/docs/fundamentals/tools/ajax/assets/pabu.json +9 -0
- package/docs/fundamentals/tools/ajax/index.md +3 -0
- package/docs/fundamentals/tools/ajax/overview.md +128 -0
- package/docs/fundamentals/tools/ajax/use-cases.md +456 -0
- package/docs/fundamentals/tools/helpers/action-logger.md +165 -0
- package/docs/fundamentals/tools/helpers/index.md +3 -0
- package/docs/fundamentals/tools/helpers/overview.md +30 -0
- package/docs/fundamentals/tools/index.md +1 -0
- package/docs/fundamentals/tools/singleton-manager/index.md +3 -0
- package/docs/fundamentals/tools/singleton-manager/overview.md +304 -0
- package/docs/guides/how-to/create-a-custom-field.md +200 -0
- package/docs/guides/how-to/extend-a-native-input.md +66 -0
- package/docs/guides/how-to/get-started.md +77 -0
- package/docs/guides/how-to/index.md +1 -0
- package/docs/guides/index.md +34 -0
- package/docs/guides/principles/definitions-and-terms.md +41 -0
- package/docs/guides/principles/index.md +26 -0
- package/docs/guides/principles/scoped-elements.md +103 -0
- package/docs/guides/principles/styling.md +32 -0
- package/docs/guides/principles/subclasser-apis.md +28 -0
- package/docs/override.js +15 -0
- package/exports/core.js +2 -0
- package/exports/form-core.js +3 -0
- package/exports/input-tel-dropdown.js +3 -0
- package/exports/input-tel.js +2 -0
- package/exports/localize.js +4 -0
- package/exports/overlays.js +5 -0
- package/package.json +3 -2
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
import sinon from 'sinon';
|
|
2
|
-
import { defineCE, expect, fixture } from '@open-wc/testing';
|
|
2
|
+
import { defineCE, expect, fixture, unsafeStatic, html } from '@open-wc/testing';
|
|
3
3
|
import { ScopedElementsMixin } from '@open-wc/scoped-elements';
|
|
4
4
|
import { SlotMixin } from '@lion/ui/core.js';
|
|
5
|
-
import { LitElement
|
|
5
|
+
import { LitElement } from 'lit';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {import('../types/SlotMixinTypes.js').SlotHost} SlotHost
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const mockedRenderTarget = document.createElement('div');
|
|
7
12
|
function mockScopedRegistry() {
|
|
13
|
+
const outputObj = { createElementCallCount: 0 };
|
|
8
14
|
// @ts-expect-error wait for browser support
|
|
9
|
-
ShadowRoot.prototype.createElement = () => {
|
|
15
|
+
ShadowRoot.prototype.createElement = () => {
|
|
16
|
+
outputObj.createElementCallCount += 1;
|
|
17
|
+
// Return an element that lit can use as render target
|
|
18
|
+
return mockedRenderTarget;
|
|
19
|
+
};
|
|
10
20
|
// @ts-expect-error wait for browser support
|
|
11
21
|
window.CustomElementRegistry = class {};
|
|
22
|
+
return outputObj;
|
|
12
23
|
}
|
|
13
24
|
|
|
14
25
|
function unMockScopedRegistry() {
|
|
@@ -19,7 +30,7 @@ function unMockScopedRegistry() {
|
|
|
19
30
|
}
|
|
20
31
|
|
|
21
32
|
describe('SlotMixin', () => {
|
|
22
|
-
it('inserts provided element into
|
|
33
|
+
it('inserts provided element into light dom and sets slot', async () => {
|
|
23
34
|
const tag = defineCE(
|
|
24
35
|
class extends SlotMixin(LitElement) {
|
|
25
36
|
get slots() {
|
|
@@ -34,7 +45,7 @@ describe('SlotMixin', () => {
|
|
|
34
45
|
expect(el.children[0].slot).to.equal('feedback');
|
|
35
46
|
});
|
|
36
47
|
|
|
37
|
-
it("supports
|
|
48
|
+
it("supports default slot with ''", async () => {
|
|
38
49
|
const tag = defineCE(
|
|
39
50
|
class extends SlotMixin(LitElement) {
|
|
40
51
|
get slots() {
|
|
@@ -50,7 +61,7 @@ describe('SlotMixin', () => {
|
|
|
50
61
|
expect(el.children[0]).dom.to.equal('<div></div>');
|
|
51
62
|
});
|
|
52
63
|
|
|
53
|
-
it('supports
|
|
64
|
+
it('supports default slot in conjunction with named slots', async () => {
|
|
54
65
|
const tag = defineCE(
|
|
55
66
|
class extends SlotMixin(LitElement) {
|
|
56
67
|
get slots() {
|
|
@@ -104,63 +115,6 @@ describe('SlotMixin', () => {
|
|
|
104
115
|
expect(slot.innerText).to.equal('');
|
|
105
116
|
});
|
|
106
117
|
|
|
107
|
-
it('supports complex dom trees as element', async () => {
|
|
108
|
-
const tag = defineCE(
|
|
109
|
-
class extends SlotMixin(LitElement) {
|
|
110
|
-
constructor() {
|
|
111
|
-
super();
|
|
112
|
-
this.foo = 'bar';
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
get slots() {
|
|
116
|
-
return {
|
|
117
|
-
...super.slots,
|
|
118
|
-
feedback: () => {
|
|
119
|
-
const el = document.createElement('div');
|
|
120
|
-
el.setAttribute('foo', this.foo);
|
|
121
|
-
const subEl = document.createElement('p');
|
|
122
|
-
subEl.innerText = 'cat';
|
|
123
|
-
el.appendChild(subEl);
|
|
124
|
-
return el;
|
|
125
|
-
},
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
);
|
|
130
|
-
const el = await fixture(`<${tag}></${tag}>`);
|
|
131
|
-
expect(el.children[0].slot).to.equal('feedback');
|
|
132
|
-
expect(el.children[0].getAttribute('foo')).to.equal('bar');
|
|
133
|
-
expect(/** @type HTMLParagraphElement */ (el.children[0].children[0]).innerText).to.equal(
|
|
134
|
-
'cat',
|
|
135
|
-
);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it('supports conditional slots', async () => {
|
|
139
|
-
let renderSlot = true;
|
|
140
|
-
const tag = defineCE(
|
|
141
|
-
class extends SlotMixin(LitElement) {
|
|
142
|
-
get slots() {
|
|
143
|
-
return {
|
|
144
|
-
...super.slots,
|
|
145
|
-
conditional: () => {
|
|
146
|
-
if (renderSlot) {
|
|
147
|
-
const el = document.createElement('div');
|
|
148
|
-
el.id = 'someSlot';
|
|
149
|
-
return el;
|
|
150
|
-
}
|
|
151
|
-
return undefined;
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
},
|
|
156
|
-
);
|
|
157
|
-
const elSlot = await fixture(`<${tag}><${tag}>`);
|
|
158
|
-
expect(elSlot.querySelector('#someSlot')).to.exist;
|
|
159
|
-
renderSlot = false;
|
|
160
|
-
const elNoSlot = await fixture(`<${tag}><${tag}>`);
|
|
161
|
-
expect(elNoSlot.querySelector('#someSlot')).to.not.exist;
|
|
162
|
-
});
|
|
163
|
-
|
|
164
118
|
it("allows to check which slots have been created via this._isPrivateSlot('slotname')", async () => {
|
|
165
119
|
let renderSlot = true;
|
|
166
120
|
class SlotPrivateText extends SlotMixin(LitElement) {
|
|
@@ -188,102 +142,358 @@ describe('SlotMixin', () => {
|
|
|
188
142
|
expect(elNoSlot.didCreateConditionalSlot()).to.be.false;
|
|
189
143
|
});
|
|
190
144
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
template: () => html`<span>text</span>`,
|
|
198
|
-
};
|
|
199
|
-
}
|
|
145
|
+
describe('Rerender', () => {
|
|
146
|
+
it('supports rerender when SlotRerenderObject provided', async () => {
|
|
147
|
+
const tag = defineCE(
|
|
148
|
+
// @ts-expect-error
|
|
149
|
+
class extends SlotMixin(LitElement) {
|
|
150
|
+
static properties = { currentValue: Number };
|
|
200
151
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
);
|
|
206
|
-
const el = await fixture(`<${tag}></${tag}>`);
|
|
207
|
-
const slot = /** @type HTMLSpanElement */ (
|
|
208
|
-
Array.from(el.children).find(elm => elm.slot === 'template')
|
|
209
|
-
);
|
|
210
|
-
expect(slot.slot).to.equal('template');
|
|
211
|
-
expect(slot.tagName).to.equal('SPAN');
|
|
212
|
-
});
|
|
152
|
+
constructor() {
|
|
153
|
+
super();
|
|
154
|
+
this.currentValue = 0;
|
|
155
|
+
}
|
|
213
156
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
157
|
+
get slots() {
|
|
158
|
+
return {
|
|
159
|
+
...super.slots,
|
|
160
|
+
template: () => ({ template: html`<span>${this.currentValue}</span> ` }),
|
|
161
|
+
};
|
|
162
|
+
}
|
|
217
163
|
|
|
218
|
-
|
|
164
|
+
render() {
|
|
165
|
+
return html`<slot name="template"></slot>`;
|
|
166
|
+
}
|
|
219
167
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
168
|
+
get _templateNode() {
|
|
169
|
+
return /** @type HTMLSpanElement */ (
|
|
170
|
+
Array.from(this.children).find(elm => elm.slot === 'template')
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
);
|
|
175
|
+
const el = /** @type {* & SlotHost} */ (await fixture(`<${tag}></${tag}>`));
|
|
176
|
+
await el.updateComplete;
|
|
177
|
+
|
|
178
|
+
expect(el._templateNode.slot).to.equal('template');
|
|
179
|
+
expect(el._templateNode.textContent?.trim()).to.equal('0');
|
|
180
|
+
|
|
181
|
+
el.currentValue = 1;
|
|
182
|
+
await el.updateComplete;
|
|
183
|
+
|
|
184
|
+
expect(el._templateNode.textContent?.trim()).to.equal('1');
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('keeps focus after rerender', async () => {
|
|
188
|
+
const tag = defineCE(
|
|
189
|
+
// @ts-expect-error
|
|
190
|
+
class extends SlotMixin(LitElement) {
|
|
191
|
+
static properties = { currentValue: Number };
|
|
192
|
+
|
|
193
|
+
constructor() {
|
|
194
|
+
super();
|
|
195
|
+
this.currentValue = 0;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
get slots() {
|
|
199
|
+
return {
|
|
200
|
+
...super.slots,
|
|
201
|
+
'focusable-node': () => ({
|
|
202
|
+
template: html`<input /> `,
|
|
203
|
+
}),
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
render() {
|
|
208
|
+
return html`<slot name="focusable-node"></slot>`;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
get _focusableNode() {
|
|
212
|
+
return /** @type HTMLSpanElement */ (
|
|
213
|
+
Array.from(this.children).find(elm => elm.slot === 'focusable-node')
|
|
214
|
+
?.firstElementChild
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
);
|
|
219
|
+
const el = /** @type {* & SlotHost} */ (await fixture(`<${tag}></${tag}>`));
|
|
220
|
+
|
|
221
|
+
el._focusableNode.focus();
|
|
222
|
+
expect(document.activeElement).to.equal(el._focusableNode);
|
|
223
|
+
|
|
224
|
+
el.currentValue = 1;
|
|
225
|
+
await el.updateComplete;
|
|
226
|
+
|
|
227
|
+
expect(document.activeElement).to.equal(el._focusableNode);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('keeps focus after rerendering complex shadow root into slot', async () => {
|
|
231
|
+
const complexSlotTagName = defineCE(
|
|
232
|
+
class extends LitElement {
|
|
233
|
+
render() {
|
|
234
|
+
return html`
|
|
235
|
+
<input />
|
|
236
|
+
<button>I will be focused</button>
|
|
237
|
+
`;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
get _buttonNode() {
|
|
224
241
|
// @ts-expect-error
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
242
|
+
return this.shadowRoot.querySelector('button');
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
);
|
|
229
246
|
|
|
230
|
-
|
|
231
|
-
return {
|
|
232
|
-
...super.slots,
|
|
233
|
-
template: () => html`<scoped-el></scoped-el>`,
|
|
234
|
-
};
|
|
235
|
-
}
|
|
247
|
+
const complexSlotTag = unsafeStatic(complexSlotTagName);
|
|
236
248
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
);
|
|
249
|
+
const tagName = defineCE(
|
|
250
|
+
// @ts-expect-error
|
|
251
|
+
class extends SlotMixin(LitElement) {
|
|
252
|
+
static properties = { currentValue: Number };
|
|
242
253
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
254
|
+
constructor() {
|
|
255
|
+
super();
|
|
256
|
+
this.currentValue = 0;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
get slots() {
|
|
260
|
+
return {
|
|
261
|
+
...super.slots,
|
|
262
|
+
'focusable-node': () => ({
|
|
263
|
+
template: html`<${complexSlotTag}> </${complexSlotTag}> `,
|
|
264
|
+
}),
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
render() {
|
|
269
|
+
return html`<slot name="focusable-node"></slot>`;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
get _focusableNode() {
|
|
273
|
+
return /** @type HTMLSpanElement */ (
|
|
274
|
+
Array.from(this.children).find(elm => elm.slot === 'focusable-node')
|
|
275
|
+
?.firstElementChild
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
);
|
|
280
|
+
const el = /** @type {* & SlotHost} */ (await fixture(`<${tagName}></${tagName}>`));
|
|
253
281
|
|
|
254
|
-
|
|
282
|
+
el._focusableNode._buttonNode.focus();
|
|
283
|
+
|
|
284
|
+
expect(el._focusableNode.shadowRoot.activeElement).to.equal(el._focusableNode._buttonNode);
|
|
285
|
+
|
|
286
|
+
el.currentValue = 1;
|
|
287
|
+
await el.updateComplete;
|
|
288
|
+
|
|
289
|
+
expect(document.activeElement).to.equal(el._focusableNode);
|
|
290
|
+
expect(el._focusableNode.shadowRoot.activeElement).to.equal(el._focusableNode._buttonNode);
|
|
291
|
+
});
|
|
255
292
|
});
|
|
256
293
|
|
|
257
|
-
|
|
258
|
-
|
|
294
|
+
describe('SlotFunctionResult types', () => {
|
|
295
|
+
it('supports complex dom trees as element (type "Element")', async () => {
|
|
296
|
+
const tag = defineCE(
|
|
297
|
+
class extends SlotMixin(LitElement) {
|
|
298
|
+
constructor() {
|
|
299
|
+
super();
|
|
300
|
+
this.foo = 'bar';
|
|
301
|
+
}
|
|
259
302
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
303
|
+
get slots() {
|
|
304
|
+
return {
|
|
305
|
+
...super.slots,
|
|
306
|
+
feedback: () => {
|
|
307
|
+
const el = document.createElement('div');
|
|
308
|
+
el.setAttribute('foo', this.foo);
|
|
309
|
+
const subEl = document.createElement('p');
|
|
310
|
+
subEl.innerText = 'cat';
|
|
311
|
+
el.appendChild(subEl);
|
|
312
|
+
return el;
|
|
313
|
+
},
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
);
|
|
318
|
+
const el = await fixture(`<${tag}></${tag}>`);
|
|
319
|
+
expect(el.children[0].slot).to.equal('feedback');
|
|
320
|
+
expect(el.children[0].getAttribute('foo')).to.equal('bar');
|
|
321
|
+
expect(/** @type HTMLParagraphElement */ (el.children[0].children[0]).innerText).to.equal(
|
|
322
|
+
'cat',
|
|
323
|
+
);
|
|
324
|
+
});
|
|
269
325
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
326
|
+
it('supports conditional slots (type "undefined")', async () => {
|
|
327
|
+
let renderSlot = true;
|
|
328
|
+
const tag = defineCE(
|
|
329
|
+
class extends SlotMixin(LitElement) {
|
|
330
|
+
get slots() {
|
|
331
|
+
return {
|
|
332
|
+
...super.slots,
|
|
333
|
+
conditional: () => {
|
|
334
|
+
if (renderSlot) {
|
|
335
|
+
const el = document.createElement('div');
|
|
336
|
+
el.id = 'someSlot';
|
|
337
|
+
return el;
|
|
338
|
+
}
|
|
339
|
+
return undefined;
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
);
|
|
345
|
+
const elSlot = await fixture(`<${tag}><${tag}>`);
|
|
346
|
+
expect(elSlot.querySelector('#someSlot')).to.exist;
|
|
347
|
+
renderSlot = false;
|
|
348
|
+
const elNoSlot = await fixture(`<${tag}><${tag}>`);
|
|
349
|
+
expect(elNoSlot.querySelector('#someSlot')).to.not.exist;
|
|
350
|
+
});
|
|
276
351
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
352
|
+
it('supports templates (type "TemplateResult")', async () => {
|
|
353
|
+
const tag = defineCE(
|
|
354
|
+
class extends SlotMixin(LitElement) {
|
|
355
|
+
get slots() {
|
|
356
|
+
return {
|
|
357
|
+
...super.slots,
|
|
358
|
+
template: () => html`<span>text</span>`,
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
render() {
|
|
363
|
+
return html`<slot name="template"></slot>`;
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
);
|
|
367
|
+
const el = await fixture(`<${tag}></${tag}>`);
|
|
368
|
+
const slot = /** @type HTMLSpanElement */ (
|
|
369
|
+
Array.from(el.children).find(elm => elm.slot === 'template')
|
|
370
|
+
);
|
|
371
|
+
expect(slot.slot).to.equal('template');
|
|
372
|
+
expect(slot.tagName).to.equal('SPAN');
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
it('supports afterRender logic (type "{ template:TemplateResults; afterRender: Function}" )', async () => {
|
|
376
|
+
let varThatProvesAfterRenderIsCalled = 'not called';
|
|
377
|
+
|
|
378
|
+
const tag = defineCE(
|
|
379
|
+
// @ts-expect-error
|
|
380
|
+
class extends SlotMixin(LitElement) {
|
|
381
|
+
static properties = { currentValue: Number };
|
|
382
|
+
|
|
383
|
+
constructor() {
|
|
384
|
+
super();
|
|
385
|
+
this.currentValue = 0;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
get slots() {
|
|
389
|
+
return {
|
|
390
|
+
...super.slots,
|
|
391
|
+
template: () => ({
|
|
392
|
+
template: html`<span>${this.currentValue}</span>, `,
|
|
393
|
+
afterRender: () => {
|
|
394
|
+
varThatProvesAfterRenderIsCalled = 'called';
|
|
395
|
+
},
|
|
396
|
+
}),
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
render() {
|
|
401
|
+
return html`<slot name="template"></slot>`;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
get _templateNode() {
|
|
405
|
+
return /** @type HTMLSpanElement */ (
|
|
406
|
+
Array.from(this.children).find(elm => elm.slot === 'template')?.firstElementChild
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
);
|
|
411
|
+
const el = /** @type {* & SlotHost} */ (await fixture(`<${tag}></${tag}>`));
|
|
412
|
+
expect(el._templateNode.textContent).to.equal('0');
|
|
413
|
+
|
|
414
|
+
el.currentValue = 1;
|
|
415
|
+
await el.updateComplete;
|
|
416
|
+
|
|
417
|
+
expect(varThatProvesAfterRenderIsCalled).to.equal('called');
|
|
418
|
+
expect(el._templateNode.textContent).to.equal('1');
|
|
419
|
+
});
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
describe('Scoped Registries', () => {
|
|
423
|
+
it('supports scoped elements when polyfill loaded', async () => {
|
|
424
|
+
const outputObj = mockScopedRegistry();
|
|
425
|
+
|
|
426
|
+
class ScopedEl extends LitElement {}
|
|
427
|
+
|
|
428
|
+
const tagName = defineCE(
|
|
429
|
+
class extends ScopedElementsMixin(SlotMixin(LitElement)) {
|
|
430
|
+
static get scopedElements() {
|
|
431
|
+
return {
|
|
432
|
+
// @ts-expect-error
|
|
433
|
+
...super.scopedElements,
|
|
434
|
+
'scoped-elm': ScopedEl,
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
get slots() {
|
|
439
|
+
return {
|
|
440
|
+
...super.slots,
|
|
441
|
+
template: () => html`<scoped-elm></scoped-elm>`,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
render() {
|
|
446
|
+
return html`<slot name="template"></slot>`;
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
const tag = unsafeStatic(tagName);
|
|
452
|
+
await fixture(html`<${tag}></${tag}>`);
|
|
453
|
+
|
|
454
|
+
expect(outputObj.createElementCallCount).to.equal(1);
|
|
455
|
+
|
|
456
|
+
unMockScopedRegistry();
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
it('does not scope elements when polyfill not loaded', async () => {
|
|
460
|
+
class ScopedEl extends LitElement {}
|
|
461
|
+
|
|
462
|
+
const tagName = defineCE(
|
|
463
|
+
class extends ScopedElementsMixin(SlotMixin(LitElement)) {
|
|
464
|
+
static get scopedElements() {
|
|
465
|
+
return {
|
|
466
|
+
// @ts-expect-error
|
|
467
|
+
...super.scopedElements,
|
|
468
|
+
'scoped-el': ScopedEl,
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
get slots() {
|
|
473
|
+
return {
|
|
474
|
+
...super.slots,
|
|
475
|
+
template: () => html`<scoped-el></scoped-el>`,
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
render() {
|
|
480
|
+
return html`<slot name="template"></slot>`;
|
|
481
|
+
}
|
|
482
|
+
},
|
|
483
|
+
);
|
|
484
|
+
|
|
485
|
+
const renderTarget = document.createElement('div');
|
|
486
|
+
const el = document.createElement(tagName);
|
|
487
|
+
|
|
488
|
+
// We don't use fixture, so we limit the amount of calls to document.createElement
|
|
489
|
+
const docSpy = sinon.spy(document, 'createElement');
|
|
490
|
+
document.body.appendChild(renderTarget);
|
|
491
|
+
renderTarget.appendChild(el);
|
|
492
|
+
|
|
493
|
+
expect(docSpy.callCount).to.equal(2);
|
|
282
494
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
expect(docSpy).to.have.been.calledTwice;
|
|
287
|
-
docSpy.restore();
|
|
495
|
+
document.body.removeChild(renderTarget);
|
|
496
|
+
docSpy.restore();
|
|
497
|
+
});
|
|
288
498
|
});
|
|
289
499
|
});
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import { Constructor } from '@open-wc/dedupe-mixin';
|
|
2
2
|
import { TemplateResult, LitElement } from 'lit';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Implicitly creates a wrapper node that allows for rerenders
|
|
6
|
+
*/
|
|
7
|
+
export type SlotRerenderObject = {
|
|
8
|
+
template: TemplateResult;
|
|
9
|
+
/* Add logic that will be performed after the render */
|
|
10
|
+
afterRender?: Function;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type SlotFunctionResult = TemplateResult | Element | SlotRerenderObject | undefined;
|
|
14
|
+
|
|
15
|
+
declare function slotFunction(): SlotFunctionResult;
|
|
5
16
|
|
|
6
17
|
export type SlotsMap = {
|
|
7
18
|
[key: string]: typeof slotFunction;
|
|
@@ -305,20 +305,11 @@ export class LionInputTel extends LocalizeMixin(LionInput) {
|
|
|
305
305
|
// This should trigger a rerender in shadow dom
|
|
306
306
|
this._phoneUtil = /** @type {AwesomePhoneNumber} */ (PhoneUtilManager.PhoneUtil);
|
|
307
307
|
// This should trigger a rerender in light dom
|
|
308
|
-
this._scheduleLightDomRender();
|
|
309
308
|
// Format when libPhoneNumber is loaded
|
|
310
309
|
this._calculateValues({ source: null });
|
|
311
310
|
this.__calculateActiveRegion();
|
|
312
311
|
}
|
|
313
312
|
|
|
314
|
-
/**
|
|
315
|
-
* This allows to hook into the update hook
|
|
316
|
-
* @protected
|
|
317
|
-
*/
|
|
318
|
-
_scheduleLightDomRender() {
|
|
319
|
-
this._needsLightDomRender += 1;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
313
|
/**
|
|
323
314
|
* @private
|
|
324
315
|
*/
|