From 8a52d175ab8fdc3418effe1bc9cb286accf8ab31 Mon Sep 17 00:00:00 2001 From: Daniel Leroux Date: Fri, 5 Aug 2022 13:20:19 +0200 Subject: [PATCH] fix(core/dropdown): migrate to shadowdom --- packages/core/component-doc.json | 4 +- .../core/scss/v7/components/_dropdown.scss | 8 +- .../src/components/dropdown/dropdown.scss | 10 +++ .../core/src/components/dropdown/dropdown.tsx | 73 ++++++++++++++----- packages/react-test-app/src/App.tsx | 25 ++++++- 5 files changed, 95 insertions(+), 25 deletions(-) diff --git a/packages/core/component-doc.json b/packages/core/component-doc.json index a3806fcd6e0..747e6bdb661 100644 --- a/packages/core/component-doc.json +++ b/packages/core/component-doc.json @@ -1,5 +1,5 @@ { - "timestamp": "2022-08-05T07:16:39", + "timestamp": "2022-08-05T11:17:25", "compiler": { "name": "@stencil/core", "version": "2.15.2", @@ -1415,7 +1415,7 @@ }, { "filePath": "./src/components/dropdown/dropdown.tsx", - "encapsulation": "scoped", + "encapsulation": "shadow", "tag": "cw-dropdown", "readme": "# cw-dropdown\n\n\n", "docs": "", diff --git a/packages/core/scss/v7/components/_dropdown.scss b/packages/core/scss/v7/components/_dropdown.scss index 53d4b14fe39..434bccd7be5 100755 --- a/packages/core/scss/v7/components/_dropdown.scss +++ b/packages/core/scss/v7/components/_dropdown.scss @@ -57,7 +57,8 @@ .dropdown-menu { background-color: var(--theme-menu--background); @include text-default-single; - border: var(--theme-menu--border-thickness) solid var(--theme-menu--border--color); + border: var(--theme-menu--border-thickness) solid + var(--theme-menu--border--color); border-radius: var(--theme-menu--border-radius); max-width: 100vw; padding: $tiny-space 0; @@ -97,6 +98,11 @@ border: 1px solid transparent; color: var(--theme-menu-item--color); + &:focus { + background-color: var(--theme-menu-item--background); + color: var(--theme-menu-item--color); + } + &:focus-visible { outline: none; background-color: var(--theme-menu-item--background); diff --git a/packages/core/src/components/dropdown/dropdown.scss b/packages/core/src/components/dropdown/dropdown.scss index b19352df78e..a7e4ac9ca6e 100644 --- a/packages/core/src/components/dropdown/dropdown.scss +++ b/packages/core/src/components/dropdown/dropdown.scss @@ -1,3 +1,13 @@ +@import '~bootstrap/scss/functions'; +@import './../../../scss/v7/common-variables'; +@import '~bootstrap/scss/variables'; +@import '~bootstrap/scss/mixins'; +@import '~bootstrap/scss/dropdown'; + +@import './../../../scss/v7/mixins/fonts'; +@import './../../../scss/v7/mixins/text-truncation'; +@import './../../../scss/v7/components/dropdown'; + :host { min-width: 0px; } diff --git a/packages/core/src/components/dropdown/dropdown.tsx b/packages/core/src/components/dropdown/dropdown.tsx index c257c2902c1..8a5ce167d9a 100644 --- a/packages/core/src/components/dropdown/dropdown.tsx +++ b/packages/core/src/components/dropdown/dropdown.tsx @@ -1,13 +1,29 @@ /* * COPYRIGHT (c) Siemens AG 2018-2022 ALL RIGHTS RESERVED. */ -import { createPopper, Instance as PopperInstance, Placement, PositioningStrategy } from '@popperjs/core'; -import { Component, Element, Event, EventEmitter, h, Host, Listen, Method, Prop, Watch } from '@stencil/core'; +import { + createPopper, + Instance as PopperInstance, + Placement, + PositioningStrategy, +} from '@popperjs/core'; +import { + Component, + Element, + Event, + EventEmitter, + h, + Host, + Listen, + Method, + Prop, + Watch, +} from '@stencil/core'; @Component({ tag: 'cw-dropdown', styleUrl: 'dropdown.scss', - scoped: true, + shadow: true, }) export class Dropdown { @Element() hostElement!: HTMLCwDropdownElement; @@ -110,27 +126,39 @@ export class Dropdown { @Watch('show') async changedShow(newShow: boolean) { if (newShow) { - this.anchorElement = this.anchor ? this.resolveElement(this.anchor) : this.resolveElement(this.trigger); + this.anchorElement = this.anchor + ? this.resolveElement(this.anchor) + : this.resolveElement(this.trigger); if (this.anchorElement) { this.popperInstance?.destroy(); - this.popperInstance = createPopper(this.anchorElement, this.dropdownRef, { - placement: this.placement, - strategy: this.positioningStrategy, - onFirstUpdate: ({ elements }) => { - if (this.adjustDropdownWidthToReferenceWith || this.adjustDropdownWidthToReferenceWidth) { - const { popper, reference } = elements; - const width = reference.getBoundingClientRect().width; - popper.style.width = `${width}px`; - } - }, - }); + this.popperInstance = createPopper( + this.anchorElement, + this.dropdownRef, + { + placement: this.placement, + strategy: this.positioningStrategy, + onFirstUpdate: ({ elements }) => { + if ( + this.adjustDropdownWidthToReferenceWith || + this.adjustDropdownWidthToReferenceWidth + ) { + const { popper, reference } = elements; + const width = reference.getBoundingClientRect().width; + popper.style.width = `${width}px`; + } + }, + } + ); } } } @Watch('trigger') - changedTrigger(newTriggerValue: string | HTMLElement, oldTriggerValue: string | HTMLElement) { + changedTrigger( + newTriggerValue: string | HTMLElement, + oldTriggerValue: string | HTMLElement + ) { if (newTriggerValue) { this.registerListener(newTriggerValue); } @@ -146,7 +174,12 @@ export class Dropdown { clickOutside(event: Event) { const target = event.target as HTMLElement; - if (this.show === false || this.closeBehavior === false || this.anchorElement === target || this.triggerElement === target) { + if ( + this.show === false || + this.closeBehavior === false || + this.anchorElement === target || + this.triggerElement === target + ) { return; } @@ -196,10 +229,10 @@ export class Dropdown { render() { return ( (this.dropdownRef = ref)} + ref={(ref) => (this.dropdownRef = ref)} class={{ 'dropdown-menu': true, - 'show': this.show, + show: this.show, }} style={{ margin: '0', @@ -207,7 +240,7 @@ export class Dropdown { }} >
- { this.header ? : ''} + {this.header ? : ''}
diff --git a/packages/react-test-app/src/App.tsx b/packages/react-test-app/src/App.tsx index 837149a8dd5..af9807c4b0d 100644 --- a/packages/react-test-app/src/App.tsx +++ b/packages/react-test-app/src/App.tsx @@ -1,9 +1,30 @@ -import { CwIcon } from '@siemens/ix-react'; +import { CwDropdown, CwDropdownItem, CwIcon } from '@siemens/ix-react'; +import { useState } from 'react'; function App() { + const [items] = useState(['Item 1', 'Abc 2', 'Blabla 3']); + const [filter, setFilter] = useState(''); + return (
- + + + setFilter((e.target as HTMLInputElement).value)} + /> + + {items + .filter((i) => { + if (!filter) { + return true; + } + + return i.includes(filter); + }) + .map((i) => ( + + ))} +
); }