From 4c90d3500db57f4482f857f88c8d62f52710b233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20H=C3=B8egh?= Date: Wed, 25 Jan 2023 20:06:10 +0100 Subject: [PATCH] break: remove web components and vue support (#1946) * docs: v10 release cleanups * chore: remove support for Web Components * chore: remove web-component related files * docs: add warning to docs + refactor * chore: remove support inside components * chore: remove component tagName * Remove everything related to web component * Remove `custom_method` and `custom_element` * update snapshots based on prop changes BREAKING CHANGE Remove support for Web Components and Vue. --- .../first-contribution/before-started.md | 1 - .../docs/contribute/style-guides/naming.md | 2 - .../src/docs/uilib/about-the-lib/releases.md | 3 +- .../releases/eufemia/v10-info.md | 16 +- .../src/docs/uilib/usage/customisation.md | 1 - .../customisation/component-properties.md | 35 +- .../usage/customisation/event-handling.md | 171 --- .../docs/uilib/usage/first-steps/angular.md | 45 - .../docs/uilib/usage/first-steps/bundles.md | 8 +- .../uilib/usage/first-steps/frameworks.md | 7 - .../uilib/usage/first-steps/the-basics.md | 2 - .../src/docs/uilib/usage/first-steps/vue.md | 51 - .../uilib/usage/first-steps/web-components.md | 190 --- .../src/shared/parts/Markdown.js | 9 - packages/dnb-eufemia/.eslintignore | 1 - packages/dnb-eufemia/.gitignore | 3 - packages/dnb-eufemia/rollup.config.js | 17 - .../postbuild/__tests__/postbuild.test.js | 5 +- .../tasks/__tests__/prepareTemplates.test.js | 12 - .../scripts/prebuild/tasks/generateTypes.js | 2 - .../prebuild/tasks/prepareTemplates.js | 6 +- .../scripts/prebuild/tasks/styleFactory.js | 1 - .../scripts/prebuild/tasks/themeFactory.js | 1 - .../dnb-eufemia/src/__tests__/index.test.js | 9 +- .../dnb-eufemia/src/__tests__/lib.test.js | 14 +- .../src/__tests__/web-components.test.js | 27 - .../src/components/__tests__/index.test.js | 9 +- .../src/components/__tests__/lib.test.js | 14 +- .../__tests__/web-components.test.js | 28 - .../src/components/accordion/Accordion.js | 9 +- .../accordion/AccordionPropTypes.js | 5 - .../components/accordion/AccordionProvider.js | 10 - .../__snapshots__/Accordion.test.js.snap | 2 - .../accordion/group/web-component.js | 15 - .../src/components/accordion/web-component.js | 11 - .../components/autocomplete/Autocomplete.js | 16 - .../__snapshots__/Autocomplete.test.js.snap | 18 - .../components/autocomplete/web-component.js | 15 - .../src/components/button/Button.d.ts | 2 - .../src/components/button/Button.js | 12 - .../__snapshots__/Button.test.js.snap | 8 - .../src/components/button/web-component.js | 11 - .../src/components/checkbox/Checkbox.js | 13 - .../__snapshots__/Checkbox.test.js.snap | 4 - .../src/components/checkbox/web-component.js | 11 - .../src/components/date-picker/DatePicker.js | 15 - .../__snapshots__/DatePicker.test.js.snap | 10 - .../components/date-picker/web-component.js | 11 - .../__snapshots__/Dialog.test.tsx.snap | 8 - .../__snapshots__/Drawer.test.tsx.snap | 8 - .../src/components/dropdown/Dropdown.js | 13 - .../__snapshots__/Dropdown.test.js.snap | 16 - .../src/components/dropdown/web-component.js | 11 - .../src/components/form-label/FormLabel.js | 6 - .../components/form-label/web-component.js | 11 - .../src/components/form-row/FormRow.js | 12 - .../__snapshots__/FormRow.test.js.snap | 2 - .../src/components/form-row/web-component.js | 11 - .../src/components/form-set/FormSet.js | 12 - .../__snapshots__/FormSet.test.js.snap | 2 - .../src/components/form-set/web-component.js | 11 - .../src/components/form-status/FormStatus.js | 10 - .../components/form-status/web-component.js | 11 - .../components/global-error/GlobalError.js | 14 +- .../__snapshots__/GlobalError.test.js.snap | 4 - .../components/global-error/web-component.js | 15 - .../components/global-status/GlobalStatus.js | 10 - .../__snapshots__/GlobalStatus.test.js.snap | 10 - .../components/global-status/web-component.js | 15 - .../src/components/heading/Heading.js | 6 - .../src/components/heading/web-component.js | 11 - .../components/help-button/web-component.js | 11 - .../components/icon-primary/IconPrimary.js | 5 - .../components/icon-primary/web-component.js | 15 - .../dnb-eufemia/src/components/icon/Icon.js | 10 - .../src/components/icon/IconPrimary.js | 5 - .../src/components/icon/web-component.js | 11 - .../components/input-masked/InputMasked.js | 15 +- .../__snapshots__/InputMasked.test.js.snap | 4 - .../components/input-masked/web-component.js | 15 - .../dnb-eufemia/src/components/input/Input.js | 11 - .../__snapshots__/Input.test.js.snap | 16 - .../__snapshots__/InputPassword.test.js.snap | 8 - .../src/components/input/web-component.js | 11 - packages/dnb-eufemia/src/components/lib.js | 19 - .../dnb-eufemia/src/components/logo/Logo.js | 6 - .../src/components/logo/web-component.js | 11 - .../src/components/modal/Modal.tsx | 6 +- .../__snapshots__/Modal.test.tsx.snap | 8 - .../src/components/modal/web-component.js | 11 - .../components/number-format/NumberFormat.js | 10 - .../components/number-format/web-component.js | 15 - .../src/components/pagination/Pagination.js | 19 - .../__snapshots__/Pagination.test.js.snap | 24 - .../components/pagination/web-component.js | 11 - .../progress-indicator/ProgressIndicator.js | 10 - .../progress-indicator/web-component.js | 15 - .../dnb-eufemia/src/components/radio/Radio.js | 13 - .../src/components/radio/RadioGroup.js | 17 - .../__snapshots__/Radio.test.js.snap | 12 - .../components/radio/group/web-component.js | 11 - .../src/components/radio/web-component.js | 11 - .../src/components/section/Section.tsx | 7 - .../section/stories/Section.stories.tsx | 3 +- .../src/components/section/web-component.js | 11 - .../__snapshots__/Skeleton.test.js.snap | 2 - .../src/components/skeleton/web-component.js | 11 - .../src/components/space/Space.tsx | 6 - .../src/components/space/web-component.js | 11 - .../step-indicator/StepIndicator.js | 16 +- .../__snapshots__/StepIndicator.test.js.snap | 60 - .../step-indicator/web-component.js | 15 - .../src/components/switch/Switch.js | 13 - .../__snapshots__/Switch.test.js.snap | 4 - .../src/components/switch/web-component.js | 11 - .../dnb-eufemia/src/components/tabs/Tabs.js | 6 - .../__tests__/__snapshots__/Tabs.test.js.snap | 16 - .../src/components/tabs/web-component.js | 11 - .../src/components/textarea/Textarea.js | 12 - .../__snapshots__/Textarea.test.js.snap | 4 - .../src/components/textarea/web-component.js | 11 - .../components/toggle-button/ToggleButton.js | 18 +- .../toggle-button/ToggleButtonGroup.js | 16 - .../__snapshots__/ToggleButton.test.js.snap | 42 - .../toggle-button/group/web-component.js | 15 - .../components/toggle-button/web-component.js | 15 - .../src/components/tooltip/web-component.js | 11 - packages/dnb-eufemia/src/components/vue.js | 41 - .../src/components/web-components.js | 10 - .../core/templates/components-lib-template.js | 19 - .../core/templates/extensions-lib-template.js | 20 - .../core/templates/fragments-lib-template.js | 23 - .../dnb-eufemia/src/elements/Blockquote.js | 1 - packages/dnb-eufemia/src/elements/Code.js | 1 - packages/dnb-eufemia/src/elements/Div.js | 1 - packages/dnb-eufemia/src/elements/H1.js | 1 - packages/dnb-eufemia/src/elements/H2.js | 1 - packages/dnb-eufemia/src/elements/H3.js | 1 - packages/dnb-eufemia/src/elements/H4.js | 1 - packages/dnb-eufemia/src/elements/H5.js | 1 - packages/dnb-eufemia/src/elements/H6.js | 1 - packages/dnb-eufemia/src/elements/Hr.js | 1 - packages/dnb-eufemia/src/elements/Img.js | 1 - packages/dnb-eufemia/src/elements/Ingress.js | 1 - packages/dnb-eufemia/src/elements/Lead.js | 1 - packages/dnb-eufemia/src/elements/Link.js | 1 - packages/dnb-eufemia/src/elements/P.js | 1 - .../dnb-eufemia/src/elements/Paragraph.js | 1 - packages/dnb-eufemia/src/elements/Span.js | 1 - .../esm/__tests__/dnb-ui-components.test.js | 4 - .../src/esm/__tests__/dnb-ui-elements.test.js | 4 - .../esm/__tests__/dnb-ui-extensions.test.js | 4 - .../src/esm/__tests__/dnb-ui-lib.test.js | 10 +- .../__tests__/dnb-ui-web-components.test.js | 17 - .../src/esm/dnb-ui-web-components.js | 9 - .../src/extensions/__tests__/index.test.js | 9 +- .../src/extensions/__tests__/lib.test.js | 14 +- .../__tests__/web-components.test.js | 28 - packages/dnb-eufemia/src/extensions/lib.js | 20 - .../extensions/payment-card/PaymentCard.js | 10 - .../extensions/payment-card/web-component.js | 11 - packages/dnb-eufemia/src/extensions/vue.js | 41 - .../src/extensions/web-components.js | 10 - .../src/fragments/drawer-list/DrawerList.js | 10 - .../drawer-list/DrawerListHelpers.js | 6 - .../__snapshots__/DrawerList.test.js.snap | 6 - .../fragments/drawer-list/web-component.js | 11 - packages/dnb-eufemia/src/fragments/lib.js | 23 - .../fragments/scroll-view/web-component.js | 11 - packages/dnb-eufemia/src/lib.js | 19 - .../__snapshots__/custom-element.test.js.snap | 11 - .../shared/__tests__/component-helper.test.js | 64 - .../shared/__tests__/custom-element.test.js | 241 ---- .../src/shared/component-helper.js | 25 - .../src/shared/custom-element-polyfill.js | 1255 ----------------- .../dnb-eufemia/src/shared/custom-element.js | 344 ----- .../shared/stories/WebComponent.stories.js | 158 --- .../umd/__tests__/dnb-ui-components.test.js | 6 +- .../src/umd/__tests__/dnb-ui-elements.test.js | 4 - .../umd/__tests__/dnb-ui-extensions.test.js | 4 - .../src/umd/__tests__/dnb-ui-lib.test.js | 4 - .../__tests__/dnb-ui-web-components.test.js | 20 - .../src/umd/dnb-ui-web-components.js | 9 - packages/dnb-eufemia/src/vue.js | 44 - packages/dnb-eufemia/src/web-components.js | 11 - 185 files changed, 34 insertions(+), 4403 deletions(-) delete mode 100644 packages/dnb-design-system-portal/src/docs/uilib/usage/customisation/event-handling.md delete mode 100644 packages/dnb-design-system-portal/src/docs/uilib/usage/first-steps/angular.md delete mode 100644 packages/dnb-design-system-portal/src/docs/uilib/usage/first-steps/frameworks.md delete mode 100644 packages/dnb-design-system-portal/src/docs/uilib/usage/first-steps/vue.md delete mode 100644 packages/dnb-design-system-portal/src/docs/uilib/usage/first-steps/web-components.md delete mode 100644 packages/dnb-eufemia/src/__tests__/web-components.test.js delete mode 100644 packages/dnb-eufemia/src/components/__tests__/web-components.test.js delete mode 100644 packages/dnb-eufemia/src/components/accordion/group/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/accordion/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/autocomplete/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/button/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/checkbox/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/date-picker/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/dropdown/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/form-label/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/form-row/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/form-set/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/form-status/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/global-error/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/global-status/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/heading/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/help-button/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/icon-primary/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/icon/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/input-masked/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/input/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/logo/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/modal/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/number-format/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/pagination/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/progress-indicator/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/radio/group/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/radio/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/section/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/skeleton/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/space/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/step-indicator/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/switch/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/tabs/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/textarea/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/toggle-button/group/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/toggle-button/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/tooltip/web-component.js delete mode 100644 packages/dnb-eufemia/src/components/vue.js delete mode 100644 packages/dnb-eufemia/src/components/web-components.js delete mode 100644 packages/dnb-eufemia/src/esm/__tests__/dnb-ui-web-components.test.js delete mode 100644 packages/dnb-eufemia/src/esm/dnb-ui-web-components.js delete mode 100644 packages/dnb-eufemia/src/extensions/__tests__/web-components.test.js delete mode 100644 packages/dnb-eufemia/src/extensions/payment-card/web-component.js delete mode 100644 packages/dnb-eufemia/src/extensions/vue.js delete mode 100644 packages/dnb-eufemia/src/extensions/web-components.js delete mode 100644 packages/dnb-eufemia/src/fragments/drawer-list/web-component.js delete mode 100644 packages/dnb-eufemia/src/fragments/scroll-view/web-component.js delete mode 100644 packages/dnb-eufemia/src/shared/__tests__/__snapshots__/custom-element.test.js.snap delete mode 100644 packages/dnb-eufemia/src/shared/__tests__/custom-element.test.js delete mode 100644 packages/dnb-eufemia/src/shared/custom-element-polyfill.js delete mode 100644 packages/dnb-eufemia/src/shared/custom-element.js delete mode 100644 packages/dnb-eufemia/src/shared/stories/WebComponent.stories.js delete mode 100644 packages/dnb-eufemia/src/umd/__tests__/dnb-ui-web-components.test.js delete mode 100644 packages/dnb-eufemia/src/umd/dnb-ui-web-components.js delete mode 100644 packages/dnb-eufemia/src/vue.js delete mode 100644 packages/dnb-eufemia/src/web-components.js diff --git a/packages/dnb-design-system-portal/src/docs/contribute/first-contribution/before-started.md b/packages/dnb-design-system-portal/src/docs/contribute/first-contribution/before-started.md index 9b26b31f10f..83cc0b5d4dd 100644 --- a/packages/dnb-design-system-portal/src/docs/contribute/first-contribution/before-started.md +++ b/packages/dnb-design-system-portal/src/docs/contribute/first-contribution/before-started.md @@ -205,7 +205,6 @@ As an example, we show the folder structure of component Breadcrumb. You can als #### Modifications - Adding theming files under a folder `style/themes` will unlock the possibility of having different themes in the future. Check out the [source for theming in Button](https://github.com/dnbexperience/eufemia/tree/main/packages/dnb-eufemia/src/components/button/style). -- Adding support for [Web Components](https://developer.mozilla.org/en-US/docs/Web/Web_Components) by including a file `web-component.js` in the folder structure. Check out how this is carried out by Button in the [source code](https://github.com/dnbexperience/eufemia/blob/main/packages/dnb-eufemia/src/components/button/web-component.js). You also have to add a tag name and register the web component inside the component declaration. ## Development environments diff --git a/packages/dnb-design-system-portal/src/docs/contribute/style-guides/naming.md b/packages/dnb-design-system-portal/src/docs/contribute/style-guides/naming.md index d063a6a4644..9ae82b13932 100644 --- a/packages/dnb-design-system-portal/src/docs/contribute/style-guides/naming.md +++ b/packages/dnb-design-system-portal/src/docs/contribute/style-guides/naming.md @@ -61,8 +61,6 @@ The DNB Design System Eufemia uses the following naming conventions. The decision to use `snake_case` was made to not just adopt React terms (`camelCase`), because we wanted to be open for future changes in the front end world. -But also the technical limitation that **Web Components** do not support `camelCase` made us more confident to use another case style. - HTML attributes uses `kebab-case`, so we needed something between. The aspect to distinguish between case styles will also make code easier to read and support future code changes and refactoring. diff --git a/packages/dnb-design-system-portal/src/docs/uilib/about-the-lib/releases.md b/packages/dnb-design-system-portal/src/docs/uilib/about-the-lib/releases.md index 7df245ef6f7..236b18c3ce4 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/about-the-lib/releases.md +++ b/packages/dnb-design-system-portal/src/docs/uilib/about-the-lib/releases.md @@ -15,8 +15,7 @@ You may also have a look at the [ **Git Here you find an overview of all major releases (versions) and changes, including migration guides: - - +- [**@dnb/eufemia@v10**](/uilib/about-the-lib/releases/eufemia/v10-info) _February, 1. 2023_ - [**@dnb/eufemia@v9**](/uilib/about-the-lib/releases/eufemia/v9-info) _March, 3. 2021_ - [**dnb-ui-lib@v8**](/uilib/about-the-lib/releases/dnb-ui-lib/v8-info) _December, 15. 2020_ - [**dnb-ui-lib@v7.2**](/uilib/about-the-lib/releases/dnb-ui-lib/v7.2-info) _November, 8. 2020_ diff --git a/packages/dnb-design-system-portal/src/docs/uilib/about-the-lib/releases/eufemia/v10-info.md b/packages/dnb-design-system-portal/src/docs/uilib/about-the-lib/releases/eufemia/v10-info.md index 99d4cf48827..67981943972 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/about-the-lib/releases/eufemia/v10-info.md +++ b/packages/dnb-design-system-portal/src/docs/uilib/about-the-lib/releases/eufemia/v10-info.md @@ -24,11 +24,9 @@ v10 of @dnb/eufemia contains _breaking changes_. As a migration process, you can 1. [Browser support](/uilib/usage/#supported-browsers-and-platforms) has been updated to support modern browsers only (es6). -### StepIndicator +## Web Components -1. Find the `active_item` property and replace it with `current_step`. -1. Find `use_navigation` and remove it or replace it with `mode="strict"` or `mode="loose"`. -1. URL support has been removed – so props like `active_url`, `url`, `url_future`, and `url_passed` are not supported anymore. You have to handle it by yourself from inside your application. Here is [an example](/uilib/components/step-indicator/#stepindicator-with-a-router). +1. The support for Web Components, Vue and Angular was removed. ### Breakpoints @@ -54,6 +52,12 @@ $layout-medium: map-get($breakpoints, 'medium'); $layout-large: map-get($breakpoints, 'large'); ``` +### StepIndicator + +1. Find the `active_item` property and replace it with `current_step`. +1. Find `use_navigation` and remove it or replace it with `mode="strict"` or `mode="loose"`. +1. URL support has been removed – so props like `active_url`, `url`, `url_future`, and `url_passed` are not supported anymore. You have to handle it by yourself from inside your application. Here is [an example](/uilib/components/step-indicator/#stepindicator-with-a-router). + ### Table 1. Ensure all table sub elements have a CSS Class: @@ -72,6 +76,7 @@ $layout-large: map-get($breakpoints, 'large'); 1. Find the snake_case `add_title` property and replace it with `addTitle`. 1. Find the snake_case `subtract_title` property and replace it with `subtractTitle`. 1. Remove `@dnb/eufemia/components/slider/style/dnb-range.min.css` and use the Eufemia Slider component instead. +1. `use_scrollwheel` and `on_init` properties, as well as the `raw_value` event value from Slider was removed in order to support multiple buttons. ### [Timeline](/uilib/components/timeline) @@ -136,7 +141,6 @@ Stopped supporting Internet Explorer (IE), as Microsoft formally ended support f ### Deprecations -- `use_scrollwheel` and `on_init` properties, as well as the `raw_value` event value from [Slider](/uilib/components/slider) was removed in order to support multiple buttons. - Helper class `.dnb-sr-only--inline` and SCSS mixin `srOnlyInline` was removed. - Helper class `.dnb-not-sr-only` and SCSS mixin `notSrOnly` was removed. - `import { SpacingHelper } from '@dnb/eufemia/shared'` was removed due to low usage. Use one of the [other exported helpers](/uilib/usage/layout/spacing). @@ -153,4 +157,4 @@ $ npm i @dnb/eufemia@10 $ yarn add @dnb/eufemia@10 ``` -_December, 24. 2022_ +_February, 1. 2023_ diff --git a/packages/dnb-design-system-portal/src/docs/uilib/usage/customisation.md b/packages/dnb-design-system-portal/src/docs/uilib/usage/customisation.md index 331517e23be..2d5e362c03c 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/usage/customisation.md +++ b/packages/dnb-design-system-portal/src/docs/uilib/usage/customisation.md @@ -13,7 +13,6 @@ import { Icon } from '@dnb/eufemia/src' For details, have a look at the submenu for all the customizations topics: - [Component Properties](/uilib/usage/customisation/component-properties) -- [Event Handling](/uilib/usage/customisation/event-handling) - [CSS Styles](/uilib/usage/customisation/styling) - [Importing the CSS](/uilib/usage/customisation/styling/consume-styles) - [Polyfill](/uilib/usage/customisation/styling/polyfill) diff --git a/packages/dnb-design-system-portal/src/docs/uilib/usage/customisation/component-properties.md b/packages/dnb-design-system-portal/src/docs/uilib/usage/customisation/component-properties.md index 5ceae419c2b..cfe0a98ae7f 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/usage/customisation/component-properties.md +++ b/packages/dnb-design-system-portal/src/docs/uilib/usage/customisation/component-properties.md @@ -12,7 +12,7 @@ Every [Component](/uilib/components) has its own `properties` to make them work ## Naming -Both the properties- and event names are using **snake case** to support a universal [naming convention](/contribute/naming), with a background and requirement on supporting [Web Components](/uilib/usage/first-steps/web-components). +Both the properties- and event names should use **camelCase** to support a universal [naming convention](/contribute/naming). ## Large Buttons & Icons @@ -68,36 +68,3 @@ render( ) `} - -## Web Components and properties - -> What if a property has to change at runtime? - -Changing a property (`props`) at runtime is a common thing in React. But also `@dnb/eufemia` web components support `prop` changes. -Keep in mind that not all components are tested to the last detail. -So, if you come over some special use cases, please contribute back and make a pull request. - - -{` -const Component = () => { - const time = new Date().toLocaleTimeString() - React.useEffect(() => { - Button.enableWebComponent() - }, []) - return ( - - ) -} -const RenderHelper = () => { - React.useEffect(() => { - const timer = setInterval(() => render(), 1e3) - return () => clearInterval(timer) - }, []) - return -} -render() -`} - diff --git a/packages/dnb-design-system-portal/src/docs/uilib/usage/customisation/event-handling.md b/packages/dnb-design-system-portal/src/docs/uilib/usage/customisation/event-handling.md deleted file mode 100644 index bd7230c9619..00000000000 --- a/packages/dnb-design-system-portal/src/docs/uilib/usage/customisation/event-handling.md +++ /dev/null @@ -1,171 +0,0 @@ ---- -title: 'Event Handling' -order: 2 ---- - -import ComponentBox from 'dnb-design-system-portal/src/shared/tags/ComponentBox' - -# Event Handling - -The `@dnb/eufemia` offers a couple of different ways to handling events: - -1. the declarative way to set and handle events (the way we SET the event is declarative) -1. the imperative way to set and handle events - -Have a look at the following basic examples: - -The `@dnb/eufemia` uses _snake case_ (**snake_case**) to define the event name property (e.g. `on_click` or `on_change`). Read more about the [naming conventions](/contribute/naming). - -## React - -Some of the most basic event handling in React. - -### Stateless Component - - -{` -const myHandler = () => alert('Hello') -render( - - ) - } - class Scope { - render_method = render_method - render_mock = render_mock - } - global.Scope = new Scope() - document.body.insertAdjacentHTML( - 'afterbegin', - `Startup Content` - ) - - registerElement('custom-element-render', CustomElementComponent, []) - const customElementRendered = document.getElementsByTagName( - 'custom-element-render' - ) - - expect(customElementRendered[0].textContent).toBe( - 'Startup Content + this button text' - ) - - expect(render_mock).toBeCalledTimes(1) - expect(render_mock).toHaveBeenCalledWith('return this') - - const ref = customElementRendered[0].getRef() - expect(React.isValidElement(ref)).toBe(true) - - const mounted = mount(ref) - expect(mounted.find('button').text()).toBe('button text') - - mounted.find('button').simulate('click') - - expect(eventHandler).toBeCalledTimes(1) - }) - - it('handles booleans and numbers gracefully', () => { - const renderedWith = jest.fn() - - class CustomElementComponent extends React.Component { - state = {} - static getDerivedStateFromProps(props, state) { - renderedWith(props.my_boolean, props.my_number) - return state - } - render() { - return <> - } - } - - document.body.insertAdjacentHTML( - 'afterbegin', - `Startup Content` - ) - - registerElement('custom-element-types', CustomElementComponent, []) - const customElementTypes = document.getElementsByTagName( - 'custom-element-types' - ) - - expect(renderedWith).toBeCalledTimes(1) - expect(renderedWith).toHaveBeenCalledWith(false, 1.1) - - customElementTypes[0].setProps({ - my_boolean: 'true', - my_number: '1.2', - }) - - expect(renderedWith).toBeCalledTimes(2) - expect(renderedWith).toHaveBeenCalledWith(true, 1.2) - }) - - it('have a "custom-element" with the correct element content value, even after changing the attribute value', () => { - const newAttributeValue = 'new-value' - customElement[0].setAttribute('observed-attribute', newAttributeValue) - expect(customElement[0].textContent).toBe(newAttributeValue) - }) - - it('handle "custom event" as expected', () => { - const eventCallback = jest.fn() - const eventParams = { value: 123 } - const eventId = customElement[0].addEvent('on_change', eventCallback) - - // call the event one time - customElement[0].fireEvent('on_change', eventParams) - customElement[0].removeEvent(eventId) - - // should not trigger the event - customElement[0].fireEvent('on_change', eventParams) - - // expect the event to be called once - expect(eventCallback.mock.calls.length).toBe(1) - - // and check for some more criterias - expect(eventCallback.mock.calls[0][0]).toBe(eventParams) - const eventId2 = customElement[0].addEvent('on_change', jest.fn()) - expect(eventId).not.toBe(eventId2) - }) - - it('handle "setProps" as expected', () => { - customElement[0].setProps('value', 456) - expect(customElement[0]._props.value).toBe(456) - - customElement[0].setProps({ - value: 789, - }) - expect(customElement[0]._props.value).toBe(789) - }) - - it('handle "getRef" as expected', () => { - const ref = customElement[0].getRef() - expect(React.isValidElement(ref)).toBe(true) - - const mounted = mount(ref) - expect(mounted.find('div').text()).toBe('new-value') - - customElement[0].setProps('value', 456) - - // mounted.setProps({ - // value: '456' - // }) - // mounted.setState({ - // content: '456' - // }) - - // mounted.instance().update() - // expect(mounted.find('div').text()).toBe(456) // we get here new-value - }) - - it('handle "native event" (CustomEvent) as expected', () => { - const eventCallback = jest.fn() - const detail = { value: 123 } - const customEvent = new CustomEvent('on_change', { - bubbles: true, - cancelable: true, - detail, - }) - customElement[0].addEventListener('on_change', eventCallback) - - // call the event one time - customElement[0].dispatchEvent(customEvent) - customElement[0].removeEventListener('on_change', eventCallback) - - // should not trigger the event - customElement[0].dispatchEvent(customEvent) - - // expect the event to be called once - expect(eventCallback.mock.calls.length).toBe(1) - expect(eventCallback.mock.calls[0][0].detail).toBe(detail) - }) -}) diff --git a/packages/dnb-eufemia/src/shared/component-helper.js b/packages/dnb-eufemia/src/shared/component-helper.js index 099cc5cfe7a..de5c00164c8 100644 --- a/packages/dnb-eufemia/src/shared/component-helper.js +++ b/packages/dnb-eufemia/src/shared/component-helper.js @@ -20,7 +20,6 @@ export { extendPropsWithContext, extendPropsWithContextInClassComponent, } from './helpers/extendPropsWithContext' -export { registerElement } from './custom-element' export { useEventEmitter } from './helpers/useEventEmitter' export { getPreviousSibling, warn } @@ -342,13 +341,6 @@ export const dispatchCustomElementEvent = ( const props = (src && src.props) || src - // call Web Component events - if (props.custom_element) { - if (typeof props.custom_element.fireEvent === 'function') { - ret = props.custom_element.fireEvent(eventName, eventObject) - } - } - // call the default snake case event if (eventName.includes('_')) { if (typeof props[eventName] === 'function') { @@ -431,23 +423,6 @@ export const toSnakeCase = (str) => export const toKebabCase = (str) => str.replace(/\B[A-Z]/g, (letter) => `-${letter}`).toLowerCase() -// Removed as we now run function props from Web Components (custom-element) -// export const pickRenderProps = (props, renderProps) => -// Object.entries(props) -// .filter(([key, value]) => { -// if ( -// typeof renderProps[key] !== 'undefined' || // TODO: remove this because of security notation -// key === 'children' || -// key === 'custom_method' -// ) -// return false -// return typeof value === 'function' -// }) -// .reduce((obj, [key, value]) => { -// obj[key] = value // TODO: remove this because of security notation -// return obj -// }, {}) - /** * [detectOutsideClick Detects a click outside a given DOM element] * @param {[type]} ignoreElement [The element we want to protect from a click] diff --git a/packages/dnb-eufemia/src/shared/custom-element-polyfill.js b/packages/dnb-eufemia/src/shared/custom-element-polyfill.js deleted file mode 100644 index b0d80a6a9b9..00000000000 --- a/packages/dnb-eufemia/src/shared/custom-element-polyfill.js +++ /dev/null @@ -1,1255 +0,0 @@ -/*! - -Copyright (C) 2014-2016 by Andrea Giammarchi - @WebReflection - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ -// global window Object -// optional polyfill info -// 'auto' used by default, everything is feature detected -// 'force' use the polyfill even if not fully needed -function installCustomElements(window, polyfill) { - 'use strict' - - // DO NOT USE THIS FILE DIRECTLY, IT WON'T WORK - // THIS IS A PROJECT BASED ON A BUILD SYSTEM - // THIS FILE IS JUST WRAPPED UP RESULTING IN - // build/document-register-element.node.js - - var document = window.document, - Object = window.Object - - var htmlClass = (function (info) { - // (C) Andrea Giammarchi - @WebReflection - MIT Style - var catchClass = /^[A-Z]+[a-z]/, - filterBy = function (re) { - var arr = [], - tag - for (tag in register) { - if (re.test(tag)) arr.push(tag) - } - return arr - }, - add = function (Class, tag) { - tag = tag.toLowerCase() - if (!(tag in register)) { - register[Class] = (register[Class] || []).concat(tag) - register[tag] = register[tag.toUpperCase()] = Class - } - }, - register = (Object.create || Object)(null), - htmlClass = {}, - i, - section, - tags, - Class - for (section in info) { - for (Class in info[section]) { - tags = info[section][Class] - register[Class] = tags - for (i = 0; i < tags.length; i++) { - register[tags[i].toLowerCase()] = register[ - tags[i].toUpperCase() - ] = Class - } - } - } - htmlClass.get = function get(tagOrClass) { - return typeof tagOrClass === 'string' - ? register[tagOrClass] || (catchClass.test(tagOrClass) ? [] : '') - : filterBy(tagOrClass) - } - htmlClass.set = function set(tag, Class) { - return ( - catchClass.test(tag) ? add(tag, Class) : add(Class, tag), htmlClass - ) - } - return htmlClass - })({ - collections: { - HTMLAllCollection: ['all'], - HTMLCollection: ['forms'], - HTMLFormControlsCollection: ['elements'], - HTMLOptionsCollection: ['options'], - }, - elements: { - Element: ['element'], - HTMLAnchorElement: ['a'], - HTMLAppletElement: ['applet'], - HTMLAreaElement: ['area'], - HTMLAttachmentElement: ['attachment'], - HTMLAudioElement: ['audio'], - HTMLBRElement: ['br'], - HTMLBaseElement: ['base'], - HTMLBodyElement: ['body'], - HTMLButtonElement: ['button'], - HTMLCanvasElement: ['canvas'], - HTMLContentElement: ['content'], - HTMLDListElement: ['dl'], - HTMLDataElement: ['data'], - HTMLDataListElement: ['datalist'], - HTMLDetailsElement: ['details'], - HTMLDialogElement: ['dialog'], - HTMLDirectoryElement: ['dir'], - HTMLDivElement: ['div'], - HTMLDocument: ['document'], - HTMLElement: [ - 'element', - 'abbr', - 'address', - 'article', - 'aside', - 'b', - 'bdi', - 'bdo', - 'cite', - 'code', - 'command', - 'dd', - 'dfn', - 'dt', - 'em', - 'figcaption', - 'figure', - 'footer', - 'header', - 'i', - 'kbd', - 'mark', - 'nav', - 'noscript', - 'rp', - 'rt', - 'ruby', - 's', - 'samp', - 'section', - 'small', - 'strong', - 'sub', - 'summary', - 'sup', - 'u', - 'var', - 'wbr', - ], - HTMLEmbedElement: ['embed'], - HTMLFieldSetElement: ['fieldset'], - HTMLFontElement: ['font'], - HTMLFormElement: ['form'], - HTMLFrameElement: ['frame'], - HTMLFrameSetElement: ['frameset'], - HTMLHRElement: ['hr'], - HTMLHeadElement: ['head'], - HTMLHeadingElement: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'], - HTMLHtmlElement: ['html'], - HTMLIFrameElement: ['iframe'], - HTMLImageElement: ['img'], - HTMLInputElement: ['input'], - HTMLKeygenElement: ['keygen'], - HTMLLIElement: ['li'], - HTMLLabelElement: ['label'], - HTMLLegendElement: ['legend'], - HTMLLinkElement: ['link'], - HTMLMapElement: ['map'], - HTMLMarqueeElement: ['marquee'], - HTMLMediaElement: ['media'], - HTMLMenuElement: ['menu'], - HTMLMenuItemElement: ['menuitem'], - HTMLMetaElement: ['meta'], - HTMLMeterElement: ['meter'], - HTMLModElement: ['del', 'ins'], - HTMLOListElement: ['ol'], - HTMLObjectElement: ['object'], - HTMLOptGroupElement: ['optgroup'], - HTMLOptionElement: ['option'], - HTMLOutputElement: ['output'], - HTMLParagraphElement: ['p'], - HTMLParamElement: ['param'], - HTMLPictureElement: ['picture'], - HTMLPreElement: ['pre'], - HTMLProgressElement: ['progress'], - HTMLQuoteElement: ['blockquote', 'q', 'quote'], - HTMLScriptElement: ['script'], - HTMLSelectElement: ['select'], - HTMLShadowElement: ['shadow'], - HTMLSlotElement: ['slot'], - HTMLSourceElement: ['source'], - HTMLSpanElement: ['span'], - HTMLStyleElement: ['style'], - HTMLTableCaptionElement: ['caption'], - HTMLTableCellElement: ['td', 'th'], - HTMLTableColElement: ['col', 'colgroup'], - HTMLTableElement: ['table'], - HTMLTableRowElement: ['tr'], - HTMLTableSectionElement: ['thead', 'tbody', 'tfoot'], - HTMLTemplateElement: ['template'], - HTMLTextAreaElement: ['textarea'], - HTMLTimeElement: ['time'], - HTMLTitleElement: ['title'], - HTMLTrackElement: ['track'], - HTMLUListElement: ['ul'], - HTMLUnknownElement: ['unknown', 'vhgroupv', 'vkeygen'], - HTMLVideoElement: ['video'], - }, - nodes: { - Attr: ['node'], - Audio: ['audio'], - CDATASection: ['node'], - CharacterData: ['node'], - Comment: ['#comment'], - Document: ['#document'], - DocumentFragment: ['#document-fragment'], - DocumentType: ['node'], - HTMLDocument: ['#document'], - Image: ['img'], - Option: ['option'], - ProcessingInstruction: ['node'], - ShadowRoot: ['#shadow-root'], - Text: ['#text'], - XMLDocument: ['xml'], - }, - }) - - // passed at runtime, configurable via nodejs module - if (typeof polyfill !== 'object') polyfill = { type: polyfill || 'auto' } - - var // V0 polyfill entry - REGISTER_ELEMENT = 'registerElement', - // IE < 11 only + old WebKit for attributes + feature detection - EXPANDO_UID = - '__' + REGISTER_ELEMENT + ((window.Math.random() * 10e4) >> 0), - // shortcuts and costants - ADD_EVENT_LISTENER = 'addEventListener', - ATTACHED = 'attached', - CALLBACK = 'Callback', - DETACHED = 'detached', - EXTENDS = 'extends', - ATTRIBUTE_CHANGED_CALLBACK = 'attributeChanged' + CALLBACK, - ATTACHED_CALLBACK = ATTACHED + CALLBACK, - CONNECTED_CALLBACK = 'connected' + CALLBACK, - DISCONNECTED_CALLBACK = 'disconnected' + CALLBACK, - CREATED_CALLBACK = 'created' + CALLBACK, - DETACHED_CALLBACK = DETACHED + CALLBACK, - ADDITION = 'ADDITION', - MODIFICATION = 'MODIFICATION', - REMOVAL = 'REMOVAL', - DOM_ATTR_MODIFIED = 'DOMAttrModified', - DOM_CONTENT_LOADED = 'DOMContentLoaded', - DOM_SUBTREE_MODIFIED = 'DOMSubtreeModified', - PREFIX_TAG = '<', - PREFIX_IS = '=', - // valid and invalid node names - validName = /^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/, - invalidNames = [ - 'ANNOTATION-XML', - 'COLOR-PROFILE', - 'FONT-FACE', - 'FONT-FACE-SRC', - 'FONT-FACE-URI', - 'FONT-FACE-FORMAT', - 'FONT-FACE-NAME', - 'MISSING-GLYPH', - ], - // registered types and their prototypes - types = [], - protos = [], - // to query subnodes - query = '', - // html shortcut used to feature detect - documentElement = document.documentElement, - // ES5 inline helpers || basic patches - indexOf = - types.indexOf || - function (v) { - for (var i = this.length; i-- && this[i] !== v; ) {} - return i - }, - // other helpers / shortcuts - OP = Object.prototype, - hOP = OP.hasOwnProperty, - iPO = OP.isPrototypeOf, - defineProperty = Object.defineProperty, - empty = [], - gOPD = Object.getOwnPropertyDescriptor, - gOPN = Object.getOwnPropertyNames, - gPO = Object.getPrototypeOf, - sPO = Object.setPrototypeOf, - // jshint proto: true - hasProto = !!Object.__proto__, - // V1 helpers - fixGetClass = false, - DRECEV1 = '__dreCEv1', - customElements = window.customElements, - usableCustomElements = - !/^force/.test(polyfill.type) && - !!( - customElements && - customElements.define && - customElements.get && - customElements.whenDefined - ), - Dict = Object.create || Object, - Map = - window.Map || - function Map() { - var K = [], - V = [], - i - return { - get: function (k) { - return V[indexOf.call(K, k)] - }, - set: function (k, v) { - i = indexOf.call(K, k) - if (i < 0) V[K.push(k) - 1] = v - else V[i] = v - }, - } - }, - Promise = - window.Promise || - function (fn) { - var notify = [], - done = false, - p = { - catch: function () { - return p - }, - then: function (cb) { - notify.push(cb) - if (done) setTimeout(resolve, 1) - return p - }, - } - function resolve(value) { - done = true - while (notify.length) notify.shift()(value) - } - fn(resolve) - return p - }, - justCreated = false, - constructors = Dict(null), - waitingList = Dict(null), - nodeNames = new Map(), - secondArgument = function (is) { - return is.toLowerCase() - }, - // used to create unique instances - create = - Object.create || - function Bridge(proto) { - // silly broken polyfill probably ever used but short enough to work - return proto ? ((Bridge.prototype = proto), new Bridge()) : this - }, - // will set the prototype if possible - // or copy over all properties - setPrototype = - sPO || - (hasProto - ? function (o, p) { - o.__proto__ = p - return o - } - : gOPN && gOPD - ? (function () { - function setProperties(o, p) { - for ( - var key, names = gOPN(p), i = 0, length = names.length; - i < length; - i++ - ) { - key = names[i] - if (!hOP.call(o, key)) { - defineProperty(o, key, gOPD(p, key)) - } - } - } - return function (o, p) { - do { - setProperties(o, p) - } while ((p = gPO(p)) && !iPO.call(p, o)) - return o - } - })() - : function (o, p) { - for (var key in p) { - o[key] = p[key] - } - return o - }), - // DOM shortcuts and helpers, if any - - MutationObserver = - window.MutationObserver || window.WebKitMutationObserver, - HTMLElementPrototype = ( - window.HTMLElement || - window.Element || - window.Node - ).prototype, - IE8 = !iPO.call(HTMLElementPrototype, documentElement), - safeProperty = IE8 - ? function (o, k, d) { - o[k] = d.value - return o - } - : defineProperty, - isValidNode = IE8 - ? function (node) { - return node.nodeType === 1 - } - : function (node) { - return iPO.call(HTMLElementPrototype, node) - }, - targets = IE8 && [], - attachShadow = HTMLElementPrototype.attachShadow, - cloneNode = HTMLElementPrototype.cloneNode, - dispatchEvent = HTMLElementPrototype.dispatchEvent, - getAttribute = HTMLElementPrototype.getAttribute, - hasAttribute = HTMLElementPrototype.hasAttribute, - removeAttribute = HTMLElementPrototype.removeAttribute, - setAttribute = HTMLElementPrototype.setAttribute, - // replaced later on - createElement = document.createElement, - patchedCreateElement = createElement, - // shared observer for all attributes - attributesObserver = MutationObserver && { - attributes: true, - characterData: true, - attributeOldValue: true, - }, - // useful to detect only if there's no MutationObserver - DOMAttrModified = - MutationObserver || - function (e) { - doesNotSupportDOMAttrModified = false - documentElement.removeEventListener( - DOM_ATTR_MODIFIED, - DOMAttrModified - ) - }, - // will both be used to make DOMNodeInserted asynchronous - asapQueue, - asapTimer = 0, - // internal flags - V0 = REGISTER_ELEMENT in document && !/^force-all/.test(polyfill.type), - setListener = true, - justSetup = false, - doesNotSupportDOMAttrModified = true, - dropDomContentLoaded = true, - // needed for the innerHTML helper - notFromInnerHTMLHelper = true, - // optionally defined later on - onSubtreeModified, - callDOMAttrModified, - getAttributesMirror, - observer, - observe, - // based on setting prototype capability - // will check proto or the expando attribute - // in order to setup the node once - patchIfNotAlready, - patch, - // used for tests - tmp - - // IE11 disconnectedCallback issue # - // to be tested before any createElement patch - if (MutationObserver) { - tmp = document.createElement('div') - tmp.innerHTML = '
' - new MutationObserver(function (mutations, observer) { - if ( - mutations[0] && - mutations[0].type == 'childList' && - !mutations[0].removedNodes[0].childNodes.length - ) { - tmp = gOPD(HTMLElementPrototype, 'innerHTML') - var set = tmp && tmp.set - if (set) - defineProperty(HTMLElementPrototype, 'innerHTML', { - set: function (value) { - while (this.lastChild) this.removeChild(this.lastChild) - set.call(this, value) - }, - }) - } - observer.disconnect() - tmp = null - }).observe(tmp, { childList: true, subtree: true }) - tmp.innerHTML = '' - } - - // only if needed - if (!V0) { - if (sPO || hasProto) { - patchIfNotAlready = function (node, proto) { - if (!iPO.call(proto, node)) { - setupNode(node, proto) - } - } - patch = setupNode - } else { - patchIfNotAlready = function (node, proto) { - if (!node[EXPANDO_UID]) { - node[EXPANDO_UID] = Object(true) - setupNode(node, proto) - } - } - patch = patchIfNotAlready - } - - if (IE8) { - doesNotSupportDOMAttrModified = false - ;(function () { - var descriptor = gOPD(HTMLElementPrototype, ADD_EVENT_LISTENER), - addEventListener = descriptor.value, - patchedRemoveAttribute = function (name) { - var e = new CustomEvent(DOM_ATTR_MODIFIED, { bubbles: true }) - e.attrName = name - e.prevValue = getAttribute.call(this, name) - e.newValue = null - e[REMOVAL] = e.attrChange = 2 - removeAttribute.call(this, name) - dispatchEvent.call(this, e) - }, - patchedSetAttribute = function (name, value) { - var had = hasAttribute.call(this, name), - old = had && getAttribute.call(this, name), - e = new CustomEvent(DOM_ATTR_MODIFIED, { bubbles: true }) - setAttribute.call(this, name, value) - e.attrName = name - e.prevValue = had ? old : null - e.newValue = value - if (had) { - e[MODIFICATION] = e.attrChange = 1 - } else { - e[ADDITION] = e.attrChange = 0 - } - dispatchEvent.call(this, e) - }, - onPropertyChange = function (e) { - // jshint eqnull:true - var node = e.currentTarget, - superSecret = node[EXPANDO_UID], - propertyName = e.propertyName, - event - if (superSecret.hasOwnProperty(propertyName)) { - superSecret = superSecret[propertyName] - event = new CustomEvent(DOM_ATTR_MODIFIED, { bubbles: true }) - event.attrName = superSecret.name - event.prevValue = superSecret.value || null - event.newValue = superSecret.value = - node[propertyName] || null - if (event.prevValue == null) { - event[ADDITION] = event.attrChange = 0 - } else { - event[MODIFICATION] = event.attrChange = 1 - } - dispatchEvent.call(node, event) - } - } - descriptor.value = function (type, handler, capture) { - if ( - type === DOM_ATTR_MODIFIED && - this[ATTRIBUTE_CHANGED_CALLBACK] && - this.setAttribute !== patchedSetAttribute - ) { - this[EXPANDO_UID] = { - className: { - name: 'class', - value: this.className, - }, - } - this.setAttribute = patchedSetAttribute - this.removeAttribute = patchedRemoveAttribute - addEventListener.call(this, 'propertychange', onPropertyChange) - } - addEventListener.call(this, type, handler, capture) - } - defineProperty( - HTMLElementPrototype, - ADD_EVENT_LISTENER, - descriptor - ) - })() - } else if (!MutationObserver) { - documentElement[ADD_EVENT_LISTENER]( - DOM_ATTR_MODIFIED, - DOMAttrModified - ) - documentElement.setAttribute(EXPANDO_UID, 1) - documentElement.removeAttribute(EXPANDO_UID) - if (doesNotSupportDOMAttrModified) { - onSubtreeModified = function (e) { - var node = this, - oldAttributes, - newAttributes, - key - if (node === e.target) { - oldAttributes = node[EXPANDO_UID] - node[EXPANDO_UID] = newAttributes = getAttributesMirror(node) - for (key in newAttributes) { - if (!(key in oldAttributes)) { - // attribute was added - return callDOMAttrModified( - 0, - node, - key, - oldAttributes[key], - newAttributes[key], - ADDITION - ) - } else if (newAttributes[key] !== oldAttributes[key]) { - // attribute was changed - return callDOMAttrModified( - 1, - node, - key, - oldAttributes[key], - newAttributes[key], - MODIFICATION - ) - } - } - // checking if it has been removed - for (key in oldAttributes) { - if (!(key in newAttributes)) { - // attribute removed - return callDOMAttrModified( - 2, - node, - key, - oldAttributes[key], - newAttributes[key], - REMOVAL - ) - } - } - } - } - callDOMAttrModified = function ( - attrChange, - currentTarget, - attrName, - prevValue, - newValue, - action - ) { - var e = { - attrChange: attrChange, - currentTarget: currentTarget, - attrName: attrName, - prevValue: prevValue, - newValue: newValue, - } - e[action] = attrChange - onDOMAttrModified(e) - } - getAttributesMirror = function (node) { - for ( - var attr, - name, - result = {}, - attributes = node.attributes, - i = 0, - length = attributes.length; - i < length; - i++ - ) { - attr = attributes[i] - name = attr.name - if (name !== 'setAttribute') { - result[name] = attr.value - } - } - return result - } - } - } - - // set as enumerable, writable and configurable - document[REGISTER_ELEMENT] = function registerElement(type, options) { - upperType = type.toUpperCase() - if (setListener) { - // only first time document.registerElement is used - // we need to set this listener - // setting it by default might slow down for no reason - setListener = false - if (MutationObserver) { - observer = (function (attached, detached) { - function checkEmAll(list, callback) { - for ( - var i = 0, length = list.length; - i < length; - callback(list[i++]) - ) {} - } - return new MutationObserver(function (records) { - for ( - var current, - node, - newValue, - i = 0, - length = records.length; - i < length; - i++ - ) { - current = records[i] - if (current.type === 'childList') { - checkEmAll(current.addedNodes, attached) - checkEmAll(current.removedNodes, detached) - } else { - node = current.target - if ( - notFromInnerHTMLHelper && - node[ATTRIBUTE_CHANGED_CALLBACK] && - current.attributeName !== 'style' - ) { - newValue = getAttribute.call( - node, - current.attributeName - ) - if (newValue !== current.oldValue) { - node[ATTRIBUTE_CHANGED_CALLBACK]( - current.attributeName, - current.oldValue, - newValue - ) - } - } - } - } - }) - })(executeAction(ATTACHED), executeAction(DETACHED)) - observe = function (node) { - observer.observe(node, { - childList: true, - subtree: true, - }) - return node - } - observe(document) - if (attachShadow) { - HTMLElementPrototype.attachShadow = function () { - return observe(attachShadow.apply(this, arguments)) - } - } - } else { - asapQueue = [] - document[ADD_EVENT_LISTENER]( - 'DOMNodeInserted', - onDOMNode(ATTACHED) - ) - document[ADD_EVENT_LISTENER]( - 'DOMNodeRemoved', - onDOMNode(DETACHED) - ) - } - - document[ADD_EVENT_LISTENER]( - DOM_CONTENT_LOADED, - onReadyStateChange - ) - document[ADD_EVENT_LISTENER]( - 'readystatechange', - onReadyStateChange - ) - - HTMLElementPrototype.cloneNode = function (deep) { - var node = cloneNode.call(this, !!deep), - i = getTypeIndex(node) - if (-1 < i) patch(node, protos[i]) - if (deep && query.length) - loopAndSetup(node.querySelectorAll(query)) - return node - } - } - - if (justSetup) return (justSetup = false) - - if ( - -2 < - indexOf.call(types, PREFIX_IS + upperType) + - indexOf.call(types, PREFIX_TAG + upperType) - ) { - throwTypeError(type) - } - - if ( - !validName.test(upperType) || - -1 < indexOf.call(invalidNames, upperType) - ) { - throw new Error('The type ' + type + ' is invalid') - } - - var constructor = function () { - return extending - ? document.createElement(nodeName, upperType) - : document.createElement(nodeName) - }, - opt = options || OP, - extending = hOP.call(opt, EXTENDS), - nodeName = extending ? options[EXTENDS].toUpperCase() : upperType, - upperType, - i - - if (extending && -1 < indexOf.call(types, PREFIX_TAG + nodeName)) { - throwTypeError(nodeName) - } - - i = types.push((extending ? PREFIX_IS : PREFIX_TAG) + upperType) - 1 - - query = query.concat( - query.length ? ',' : '', - extending - ? nodeName + '[is="' + type.toLowerCase() + '"]' - : nodeName - ) - - constructor.prototype = protos[i] = hOP.call(opt, 'prototype') - ? opt.prototype - : create(HTMLElementPrototype) - - if (query.length) - loopAndVerify(document.querySelectorAll(query), ATTACHED) - - return constructor - } - - document.createElement = patchedCreateElement = function ( - localName, - typeExtension - ) { - var is = getIs(typeExtension), - node = is - ? createElement.call(document, localName, secondArgument(is)) - : createElement.call(document, localName), - name = '' + localName, - i = indexOf.call( - types, - (is ? PREFIX_IS : PREFIX_TAG) + (is || name).toUpperCase() - ), - setup = -1 < i - if (is) { - node.setAttribute('is', (is = is.toLowerCase())) - if (setup) { - setup = isInQSA(name.toUpperCase(), is) - } - } - notFromInnerHTMLHelper = !document.createElement.innerHTMLHelper - if (setup) patch(node, protos[i]) - return node - } - } - - function ASAP() { - var queue = asapQueue.splice(0, asapQueue.length) - asapTimer = 0 - while (queue.length) { - queue.shift().call(null, queue.shift()) - } - } - - function loopAndVerify(list, action) { - for (var i = 0, length = list.length; i < length; i++) { - verifyAndSetupAndAction(list[i], action) - } - } - - function loopAndSetup(list) { - for (var i = 0, length = list.length, node; i < length; i++) { - node = list[i] - patch(node, protos[getTypeIndex(node)]) - } - } - - function executeAction(action) { - return function (node) { - if (isValidNode(node)) { - verifyAndSetupAndAction(node, action) - if (query.length) - loopAndVerify(node.querySelectorAll(query), action) - } - } - } - - function getTypeIndex(target) { - var is = getAttribute.call(target, 'is'), - nodeName = target.nodeName.toUpperCase(), - i = indexOf.call( - types, - is ? PREFIX_IS + is.toUpperCase() : PREFIX_TAG + nodeName - ) - return is && -1 < i && !isInQSA(nodeName, is) ? -1 : i - } - - function isInQSA(name, type) { - return -1 < query.indexOf(name + '[is="' + type + '"]') - } - - function onDOMAttrModified(e) { - var node = e.currentTarget, - attrChange = e.attrChange, - attrName = e.attrName, - target = e.target, - addition = e[ADDITION] || 2, - removal = e[REMOVAL] || 3 - if ( - notFromInnerHTMLHelper && - (!target || target === node) && - node[ATTRIBUTE_CHANGED_CALLBACK] && - attrName !== 'style' && - (e.prevValue !== e.newValue || - // IE9, IE10, and Opera 12 gotcha - (e.newValue === '' && - (attrChange === addition || attrChange === removal))) - ) { - node[ATTRIBUTE_CHANGED_CALLBACK]( - attrName, - attrChange === addition ? null : e.prevValue, - attrChange === removal ? null : e.newValue - ) - } - } - - function onDOMNode(action) { - var executor = executeAction(action) - return function (e) { - asapQueue.push(executor, e.target) - if (asapTimer) clearTimeout(asapTimer) - asapTimer = setTimeout(ASAP, 1) - } - } - - function onReadyStateChange(e) { - if (dropDomContentLoaded) { - dropDomContentLoaded = false - e.currentTarget.removeEventListener( - DOM_CONTENT_LOADED, - onReadyStateChange - ) - } - if (query.length) - loopAndVerify( - (e.target || document).querySelectorAll(query), - e.detail === DETACHED ? DETACHED : ATTACHED - ) - if (IE8) purge() - } - - function patchedSetAttribute(name, value) { - // jshint validthis:true - var self = this - setAttribute.call(self, name, value) - onSubtreeModified.call(self, { target: self }) - } - - function setupNode(node, proto) { - setPrototype(node, proto) - if (observer) { - observer.observe(node, attributesObserver) - } else { - if (doesNotSupportDOMAttrModified) { - node.setAttribute = patchedSetAttribute - node[EXPANDO_UID] = getAttributesMirror(node) - node[ADD_EVENT_LISTENER](DOM_SUBTREE_MODIFIED, onSubtreeModified) - } - node[ADD_EVENT_LISTENER](DOM_ATTR_MODIFIED, onDOMAttrModified) - } - if (node[CREATED_CALLBACK] && notFromInnerHTMLHelper) { - node.created = true - node[CREATED_CALLBACK]() - node.created = false - } - } - - function purge() { - for (var node, i = 0, length = targets.length; i < length; i++) { - node = targets[i] - if (!documentElement.contains(node)) { - length-- - targets.splice(i--, 1) - verifyAndSetupAndAction(node, DETACHED) - } - } - } - - function throwTypeError(type) { - throw new Error('A ' + type + ' type is already registered') - } - - function verifyAndSetupAndAction(node, action) { - var fn, - i = getTypeIndex(node), - counterAction - if (-1 < i) { - patchIfNotAlready(node, protos[i]) - i = 0 - if (action === ATTACHED && !node[ATTACHED]) { - node[DETACHED] = false - node[ATTACHED] = true - counterAction = 'connected' - i = 1 - if (IE8 && indexOf.call(targets, node) < 0) { - targets.push(node) - } - } else if (action === DETACHED && !node[DETACHED]) { - node[ATTACHED] = false - node[DETACHED] = true - counterAction = 'disconnected' - i = 1 - } - if ( - i && - (fn = node[action + CALLBACK] || node[counterAction + CALLBACK]) - ) - fn.call(node) - } - } - - // V1 in da House! - function CustomElementRegistry() {} - - CustomElementRegistry.prototype = { - constructor: CustomElementRegistry, - // a workaround for the stubborn WebKit - define: usableCustomElements - ? function (name, Class, options) { - if (options) { - CERDefine(name, Class, options) - } else { - var NAME = name.toUpperCase() - constructors[NAME] = { - constructor: Class, - create: [NAME], - } - nodeNames.set(Class, NAME) - customElements.define(name, Class) - } - } - : CERDefine, - get: usableCustomElements - ? function (name) { - return customElements.get(name) || get(name) - } - : get, - whenDefined: usableCustomElements - ? function (name) { - return Promise.race([ - customElements.whenDefined(name), - whenDefined(name), - ]) - } - : whenDefined, - } - - function CERDefine(name, Class, options) { - var is = (options && options[EXTENDS]) || '', - CProto = Class.prototype, - proto = create(CProto), - attributes = Class.observedAttributes || empty, - definition = { prototype: proto } - // TODO: is this needed at all since it's inherited? - // defineProperty(proto, 'constructor', {value: Class}); - safeProperty(proto, CREATED_CALLBACK, { - value: function () { - if (justCreated) justCreated = false - else if (!this[DRECEV1]) { - this[DRECEV1] = true - new Class(this) - if (CProto[CREATED_CALLBACK]) CProto[CREATED_CALLBACK].call(this) - var info = constructors[nodeNames.get(Class)] - if (!usableCustomElements || info.create.length > 1) { - notifyAttributes(this) - } - } - }, - }) - safeProperty(proto, ATTRIBUTE_CHANGED_CALLBACK, { - value: function (name) { - if (-1 < indexOf.call(attributes, name)) - CProto[ATTRIBUTE_CHANGED_CALLBACK].apply(this, arguments) - }, - }) - if (CProto[CONNECTED_CALLBACK]) { - safeProperty(proto, ATTACHED_CALLBACK, { - value: CProto[CONNECTED_CALLBACK], - }) - } - if (CProto[DISCONNECTED_CALLBACK]) { - safeProperty(proto, DETACHED_CALLBACK, { - value: CProto[DISCONNECTED_CALLBACK], - }) - } - if (is) definition[EXTENDS] = is - name = name.toUpperCase() - constructors[name] = { - constructor: Class, - create: is ? [is, secondArgument(name)] : [name], - } - nodeNames.set(Class, name) - document[REGISTER_ELEMENT](name.toLowerCase(), definition) - whenDefined(name) - waitingList[name].r() - } - - function get(name) { - var info = constructors[name.toUpperCase()] - return info && info.constructor - } - - function getIs(options) { - return typeof options === 'string' - ? options - : (options && options.is) || '' - } - - function notifyAttributes(self) { - var callback = self[ATTRIBUTE_CHANGED_CALLBACK], - attributes = callback ? self.attributes : empty, - i = attributes.length, - attribute - while (i--) { - attribute = attributes[i] // || attributes.item(i); - callback.call( - self, - attribute.name || attribute.nodeName, - null, - attribute.value || attribute.nodeValue - ) - } - } - - function whenDefined(name) { - name = name.toUpperCase() - if (!(name in waitingList)) { - waitingList[name] = {} - waitingList[name].p = new Promise(function (resolve) { - waitingList[name].r = resolve - }) - } - return waitingList[name].p - } - - function polyfillV1() { - if (customElements) delete window.customElements - defineProperty(window, 'customElements', { - configurable: true, - value: new CustomElementRegistry(), - }) - defineProperty(window, 'CustomElementRegistry', { - configurable: true, - value: CustomElementRegistry, - }) - for ( - var patchClass = function (name) { - var Class = window[name] - if (Class) { - window[name] = function CustomElementsV1(self) { - var info, isNative - if (!self) self = this - if (!self[DRECEV1]) { - justCreated = true - info = constructors[nodeNames.get(self.constructor)] - isNative = usableCustomElements && info.create.length === 1 - self = isNative - ? Reflect.construct(Class, empty, info.constructor) - : document.createElement.apply(document, info.create) - self[DRECEV1] = true - justCreated = false - if (!isNative) notifyAttributes(self) - } - return self - } - window[name].prototype = Class.prototype - try { - Class.prototype.constructor = window[name] - } catch (WebKit) { - fixGetClass = true - defineProperty(Class, DRECEV1, { value: window[name] }) - } - } - }, - Classes = htmlClass.get(/^HTML[A-Z]*[a-z]/), - i = Classes.length; - i--; - patchClass(Classes[i]) - ) {} - document.createElement = function (name, options) { - var is = getIs(options) - return is - ? patchedCreateElement.call(this, name, secondArgument(is)) - : patchedCreateElement.call(this, name) - } - if (!V0) { - justSetup = true - document[REGISTER_ELEMENT]('') - } - } - - // if customElements is not there at all - if (!customElements || /^force/.test(polyfill.type)) polyfillV1() - else if (!polyfill.noBuiltIn) { - // if available test extends work as expected - try { - ;(function (DRE, options, name) { - options[EXTENDS] = 'a' - DRE.prototype = create(HTMLAnchorElement.prototype) - DRE.prototype.constructor = DRE - window.customElements.define(name, DRE, options) - if ( - getAttribute.call( - document.createElement('a', { is: name }), - 'is' - ) !== name || - (usableCustomElements && - getAttribute.call(new DRE(), 'is') !== name) - ) { - throw options - } - })( - function DRE() { - return Reflect.construct(HTMLAnchorElement, [], DRE) - }, - {}, - 'document-register-element-a' - ) - } catch (o_O) { - // or force the polyfill if not - // and keep internal original reference - polyfillV1() - } - } - - // FireFox only issue - if (!polyfill.noBuiltIn) { - try { - createElement.call(document, 'a', 'a') - } catch (FireFox) { - secondArgument = function (is) { - return { is: is.toLowerCase() } - } - } - } -} - -export default installCustomElements diff --git a/packages/dnb-eufemia/src/shared/custom-element.js b/packages/dnb-eufemia/src/shared/custom-element.js deleted file mode 100644 index d508d4548ac..00000000000 --- a/packages/dnb-eufemia/src/shared/custom-element.js +++ /dev/null @@ -1,344 +0,0 @@ -/** - * Make React component available as a Web Component - * - */ - -import React from 'react' -import ReactDOM from 'react-dom' -import { ErrorHandler } from './error-helper' - -// import "custom-element-polyfill" - instead of import 'document-register-element' // https://github.com/WebReflection/document-register-element -// This way we can control the execution of the polyfill with customElementPolyfill() -import customElementPolyfill from './custom-element-polyfill' - -const isTest = - typeof process !== 'undefined' && process.env.NODE_ENV === 'test' -let hasPolyfill = isTest - -export const registeredElements = - (typeof window !== 'undefined' && - (window.registeredElements = window.registeredElements || [])) || - [] - -export const registerElement = ( - tagName, - ReactComponent, - propNames = null, - // remove id, because we never can have more than one of the same id - { attributesExcludelist = ['id'] } = {} -) => { - if (!tagName) { - tagName = ReactComponent.displayName || ReactComponent.name - } - - // stop here if we already have registered the tag - if (registeredElements.indexOf(tagName) !== -1) { - return // stop here - } - registeredElements.push(tagName) - - if (typeof document === 'undefined' || typeof window === 'undefined') { - return null - } - - //always run the customElementPolyfill unless we are in the build process - if (!hasPolyfill) { - hasPolyfill = true - customElementPolyfill(window) - } - - if (propNames) { - propNames = prepareDefaultProps(propNames) - } - - class HtmlClass extends HTMLElement { - static get observedAttributes() { - return propNames || [] - } - constructor(props) { - super(props) - this._elementRef = React.createRef() - this._customMethods = {} - this._customEvents = [] - this._isConnected = false - this._props = {} - } - connectedCallback() { - this.updateChildren() - this.renderElement() - this._isConnected = true - } - attributeChangedCallback(attrName, oldAttr, newAttr) { - if (!this._isConnected || oldAttr === newAttr) { - return false - } - this.renderElement() - return newAttr - } - // adoptedCallback: Invoked when the custom element is moved to a new document. - disconnectedCallback() { - if (!isTest) { - ReactDOM.unmountComponentAtNode(this) - } - if (this._children) delete this._children - if (this._isConnected) delete this._isConnected - if (this._elementRef) delete this._elementRef - if (this._customMethods) delete this._customMethods - if (this._customEvents) delete this._customEvents - - this._props = null - this._ref = null - } - updateChildren() { - this._children = [] - let i, - cn = this.childNodes, - v - for (i = cn.length; i--; ) { - v = toVdom(cn[i]) - if (v) { - this._children.push(v) - } - // TODO: we may remove this child - need more testing - // cn[i].remove() - } - } - connectEvents() { - const props = {} - for (let i = this.attributes.length; i--; ) { - props[this.attributes[i].name] = this.attributes[i].value - } - - if (props.events) { - props.event = props.events - delete props.events - } - - const events = [ - ...(props.event ? props.event.split(',') : []), - ...Object.entries(props) - .map(([key, value]) => { - if (key && /^(on_|on[A-Z]|render_)/.test(key)) { - return key + '=' + value - } - return null - }) - .filter(Boolean), - ] - - if (events.length > 0) { - events.forEach((eventDef) => { - // extract the prop name and callback function - let [type, func] = eventDef.split('=') - type = EVENT_TRANSLATIONS[type] || type - - // add a react function prop or event callback - props[type] = (...args) => { - try { - // NB: This code is not documented and not used - // Removed june 12, 2020 - // // check if there is a element returned, convert it to html then - // if (args[0]) { - // if (React.isValidElement(args[0])) { - // args[0] = [args[0]] - // } - // if (Array.isArray(args[0])) { - // const elems = [] - // // we have to overwrite the first arg like this - and can’t use map/reduce here - // args[0].forEach((elem) => { - // if (React.isValidElement(elem)) { - // const rootEl = document.createElement('div') // createDocumentFragment - // ReactDOM.render(elem, rootEl) - // elems.push(rootEl) - // } - // }) - // if (elems.length > 0) { - // args[0] = elems - // } - // } - // } - - // call the function, either it in a class or not - let [scope, fn] = func.split('.') - fn = fn ? window[scope][fn] : window[scope] - const component = fn.apply(scope, [...args]) - - // convert to react if we get an HTMLElement - // this is used for custom renderer - if (component instanceof HTMLElement) { - const children = [], - cn = component.childNodes, - a = component.attributes, - props = {} - - for (let i = cn.length; i--; ) { - children.push(toVdom(cn[i])) - // TODO: we may remove this child - need more testing - // cn[i].remove() - } - - for (let i = a.length; i--; ) { - props[PROP_TRANSLATIONS[a[i].name] || a[i].name] = - a[i].value - } - - const nodeName = component.nodeName.toLowerCase() - component.remove() - - return React.createElement(nodeName, props, children) - } - - return component - } catch (error) { - new ErrorHandler( - `The '${type}' event has failed. '${func}' has to exist on a 'window' scope!`, - error - ) - } - } - }) - - // do send this event to the react props - delete props.event - } - - return props - } - setProps(props, value) { - if (typeof props === 'string') { - props = { [props]: value } - } - return this.renderElement(props) - } - getRef() { - return this._ref - } - addEvent(eventName, eventCallback) { - const eventWrapper = (event) => eventCallback.apply(this, [event]) - this._customEvents?.push({ eventName, eventCallback, eventWrapper }) - return eventWrapper - } - removeEvent(eventId, removeCallback = null) { - this._customEvents = this._customEvents.reduce( - (accumulator, current) => { - if (removeCallback) { - const { eventCallback: eventWrapper } = current - if (eventWrapper !== removeCallback) { - accumulator.push(current) - } - } else { - const { eventWrapper } = current - if (eventWrapper !== eventId) { - accumulator.push(current) - } - } - return accumulator - }, - [] - ) - } - fireEvent(eventName, ...args) { - this._customEvents.forEach(({ eventName: name, eventCallback }) => { - if (name === eventName && typeof eventCallback === 'function') { - eventCallback.apply(this, [...args]) - } - }) - } - renderElement(props = {}) { - props = { ...this._props, ...this.connectEvents(), ...props } - - for (let p in props) { - if (props[p] === 'true') { - props[p] = true - } else if (props[p] === 'false') { - props[p] = false - } else if ( - typeof props[p] !== 'undefined' && - props[p] !== null && - !isNaN(Number(props[p])) - ) { - props[p] = Number(props[p]) - } - } - - // we don't allow ids - for (let i = attributesExcludelist.length; i--; ) { - if (props[attributesExcludelist[i]]) { - this.removeAttribute(attributesExcludelist[i]) - } - } - - if (this._children && this._children.length > 0) { - props.children = this._children // we have returned a () => before - } - - if (this._elementRef) { - props.ref = this._elementRef - } - if (!props.custom_element) { - props.custom_element = this - } - if (!props.custom_method) { - props.custom_method = (methodName, methodFunc) => { - this[methodName] = this._customMethods[methodName] = methodFunc - } - } - - this._props = props - this._ref = - ReactDOM.render(this._ref, this) - - return this - } - } - - return window.customElements.define(tagName, HtmlClass) -} - -// remove react props which has uppercase chars -const filterProps = (key) => - key && !/[A-Z]/.test(key) && !/children/.test(key) - -export const prepareDefaultProps = (defaultProps) => - Array.isArray(defaultProps) - ? defaultProps.filter(filterProps) - : Object.entries(defaultProps || {}) - .reduce((props, [key]) => { - props.push(key) - return props - }, []) - .filter(filterProps) - -const toVdom = (elem, name = null) => { - if (elem.nodeType === 3) return elem.nodeValue - if (elem.nodeType !== 1) return null - - let children = [], - props = {}, - i = 0, - a = elem.attributes, - cn = elem.childNodes - - for (i = a.length; i--; ) { - // a[i].name = PROP_TRANSLATIONS[a[i].name]||a[i].name - props[a[i].name] = a[i].value - } - for (i = cn.length; i--; ) { - children[i] = toVdom(cn[i]) - } - props.key = `key${Math.random() * 1000}` - - return React.createElement( - name || elem.nodeName.toLowerCase(), - props, - children - ) -} - -const PROP_TRANSLATIONS = { - class: 'className', - for: 'htmlFor', -} -const EVENT_TRANSLATIONS = { - onclick: 'onClick', -} diff --git a/packages/dnb-eufemia/src/shared/stories/WebComponent.stories.js b/packages/dnb-eufemia/src/shared/stories/WebComponent.stories.js deleted file mode 100644 index baa3bd8e47f..00000000000 --- a/packages/dnb-eufemia/src/shared/stories/WebComponent.stories.js +++ /dev/null @@ -1,158 +0,0 @@ -/** - * @dnb/eufemia Component Story - * - */ - -import React from 'react' -import { Wrapper, Box } from 'storybook-utils/helpers' -import '../../components/date-picker/web-component' -import '../../components/section/web-component' -import Button from '../../components/button/web-component' - -class Scope { - render(props) { - return <>{props.children} + this 1 - } - render2(props) { - return <>{props.children} + this 2 - } - render3(props) { - return <>{props.children} + this 3 - } -} -window.Scope = new Scope() - -export default { - title: 'Eufemia/Components/WebComponent', -} - -export const WebComponent = () => ( - - - - content - - - - - -) - -const DatePicker = () => { - const [show, setShow] = React.useState(true) - const ref = React.useRef() - - React.useEffect(() => { - console.log('ref.current', ref.current) - - if (ref.current.addEvent) { - ref.current.addEvent('on_change', (e) => { - console.log('.date-picker.on_change', e) - // myDate.innerHTML = e.date; // uses the return_format - }) - ref.current.addEvent('on_hide', (e) => { - console.log('.date-picker.on_hide', e) - }) - } - - if (ref.current.setProps) { - ref.current.setProps('start_date', '2019-05-17') - - ref.current.setProps('on_change', (e) => { - console.log('on_change', e) - }) - } - - myDatePicker = ref.current - }, []) - - return ( - <> - - - {show && ( - <> - {/* content */} - - - )} - - ) -} - -const Buttons = () => { - // const myButton = React.useRef() - // React.useEffect(() => {}) - - return ( -
- Set date - - - Update date - - - - Reset DatePicker - - - {/* dd.mm.yyyy */} -
- ) -} - -let myDatePicker -function DataManager() {} -DataManager.prototype.setDate = function () { - // console.log('setDate', e) - // myDatePicker.setAttribute('start_date', '2019-05-17') - myDatePicker.setProps('start_date', '2019-05-17') -} -DataManager.prototype.updateDatePicker = function () { - // console.log('updateDatePicker', e) - // myDatePicker.setAttribute('start_date', '2019-05-18') - myDatePicker.setProps('start_date', '2019-05-18') -} -DataManager.prototype.resetDatePicker = function () { - // console.log('resetDatePicker', e) - // myDatePicker.setAttribute('start_date', '') - myDatePicker.setProps('start_date', null) - // myDate.innerHTML = "dd.mm.yyyy"; - - // const elem = document.querySelector('.dnb-form-label') - // return elem - // const elem = - // return elem -} -window.MyDataManager = new DataManager() diff --git a/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-components.test.js b/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-components.test.js index ae51e15f24a..cbd3a6ad174 100644 --- a/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-components.test.js +++ b/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-components.test.js @@ -5,16 +5,12 @@ import '../../core/jest/jestSetup' import * as dnbComponents from '../dnb-ui-components' -import { registeredElements } from '../../shared/custom-element' -describe('UMD Web Components package', () => { +describe('UMD Components package', () => { it('has to have a named export of dnbComponents', () => { expect(dnbComponents).toBeType('object') }) it('has to have a Button Component', () => { expect(dnbComponents.Button).toBeType('function') }) - it('have "dnb-button" enabled in registeredElements', () => { - expect(registeredElements).not.toContain('dnb-button') - }) }) diff --git a/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-elements.test.js b/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-elements.test.js index 7aa0c7110a4..c1f9982d0c0 100644 --- a/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-elements.test.js +++ b/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-elements.test.js @@ -5,7 +5,6 @@ import '../../core/jest/jestSetup' import * as dnbElements from '../dnb-ui-elements' -import { registeredElements } from '../../shared/custom-element' describe('UMD Web Elements package', () => { it('has to have a named export of dnbElements', () => { @@ -14,7 +13,4 @@ describe('UMD Web Elements package', () => { it('has to have a Anchor Component', () => { expect(dnbElements.Anchor).toBeType('object') }) - it('have "dnb-anchor" enabled in registeredElements', () => { - expect(registeredElements).not.toContain('dnb-anchor') - }) }) diff --git a/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-extensions.test.js b/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-extensions.test.js index c9a2fa96899..445e9e29287 100644 --- a/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-extensions.test.js +++ b/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-extensions.test.js @@ -5,7 +5,6 @@ import '../../core/jest/jestSetup' import * as dnbExtensions from '../dnb-ui-extensions' -import { registeredElements } from '../../shared/custom-element' describe('UMD Web Extensions package', () => { it('has to have a named export of dnbExtensions', () => { @@ -14,7 +13,4 @@ describe('UMD Web Extensions package', () => { it('has to have a PaymentCard Component', () => { expect(dnbExtensions.PaymentCard).toBeType('function') }) - it('have "dnb-payment-card" enabled in registeredElements', () => { - expect(registeredElements).not.toContain('dnb-payment-card') - }) }) diff --git a/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-lib.test.js b/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-lib.test.js index e3bb614a038..66d589dfc7e 100644 --- a/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-lib.test.js +++ b/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-lib.test.js @@ -5,7 +5,6 @@ import '../../core/jest/jestSetup' import * as dnbLib from '../dnb-ui-lib' -import { registeredElements } from '../../shared/custom-element' describe('UMD main package', () => { it('has to have a named export of dnbLib', () => { @@ -17,7 +16,4 @@ describe('UMD main package', () => { it('has to have a Anchor Component', () => { expect(dnbLib.Anchor).toBeType('object') }) - it('has no Web Components enabled in registeredElements', () => { - expect(registeredElements).not.toContain('dnb-button') - }) }) diff --git a/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-web-components.test.js b/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-web-components.test.js deleted file mode 100644 index 0bc43dbbf11..00000000000 --- a/packages/dnb-eufemia/src/umd/__tests__/dnb-ui-web-components.test.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Abstract Test - * - */ - -import '../../core/jest/jestSetup' -import * as dnbWebComponents from '../dnb-ui-web-components' -import { registeredElements } from '../../shared/custom-element' - -describe('UMD Web Components package', () => { - it('has to have a named export of dnbWebComponents', () => { - expect(dnbWebComponents).toBeType('object') - }) - it('has to have a Button Component', () => { - expect(dnbWebComponents.Button).toBeType('function') - }) - it('have "dnb-button" enabled in registeredElements', () => { - expect(registeredElements).toContain('dnb-button') - }) -}) diff --git a/packages/dnb-eufemia/src/umd/dnb-ui-web-components.js b/packages/dnb-eufemia/src/umd/dnb-ui-web-components.js deleted file mode 100644 index 9bfe828761f..00000000000 --- a/packages/dnb-eufemia/src/umd/dnb-ui-web-components.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * UMD lib entry - * - */ - -export * from '../components/lib' - -import { enableWebComponents } from '../components/lib' -enableWebComponents() diff --git a/packages/dnb-eufemia/src/vue.js b/packages/dnb-eufemia/src/vue.js deleted file mode 100644 index e8bd618c24d..00000000000 --- a/packages/dnb-eufemia/src/vue.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Vue Index file - * - */ - -import { VuePlugin } from 'vuera' - -// import all the available libs -import * as componentsIndex from './components/lib' -import * as elementsIndex from './elements/lib' - -export * from './index' - -export default { - getComponents: (Vue) => { - Vue.use(VuePlugin) - const ret = {} - const components = { ...componentsIndex, ...elementsIndex } - for (const c in components) { - if (components?.[c]?.tagName) { - ret[components[c].tagName] = components[c] - } - } - return ret - }, - setIgnoredPatterns: (Vue) => { - const customPatterns = [] - const components = { ...componentsIndex, ...elementsIndex } - for (const c in components) { - if (components?.[c]?.tagName) { - customPatterns.push(components[c].tagName) - } - } - try { - Vue.config.ignoredPatterns = customPatterns - } catch (e) { - console.log( - 'setIgnoredPatterns failed on trying to set the "Vue.config.ignoredPatterns"', - e - ) - } - return Vue - }, -} diff --git a/packages/dnb-eufemia/src/web-components.js b/packages/dnb-eufemia/src/web-components.js deleted file mode 100644 index 7f92cb0e693..00000000000 --- a/packages/dnb-eufemia/src/web-components.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * This file is used to enable Web Components - * - */ - -// import all the available libs -import { enableWebComponents } from './lib' - -export * from './lib' - -enableWebComponents()