Skip to content

Commit

Permalink
fix(core/dropdown): allow nested dropdown (#425)
Browse files Browse the repository at this point in the history
Co-authored-by: Lukas Maurer <lukas.maurer@siemens.com>
  • Loading branch information
danielleroux and nuke-ellington committed Mar 6, 2023
1 parent 44540b4 commit d2fcaaf
Show file tree
Hide file tree
Showing 15 changed files with 120 additions and 79 deletions.
3 changes: 1 addition & 2 deletions packages/core/component-doc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2703,7 +2703,6 @@
"reflectToAttr": false,
"docs": "Set label",
"docsTags": [],
"default": "''",
"values": [
{
"type": "string"
Expand Down Expand Up @@ -2735,7 +2734,7 @@
"mutable": false,
"attr": "variant",
"reflectToAttr": false,
"docs": "Button varaint",
"docs": "Button variant",
"docsTags": [],
"default": "'Primary'",
"values": [
Expand Down
3 changes: 0 additions & 3 deletions packages/core/scss/components/_dropdown.scss
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@
.dropdown-menu {
position: absolute;

max-height: 50vh;
overflow-y: auto;

background-color: var(--theme-menu--background);
@include text-default-single;
border: var(--theme-menu--border-thickness) solid
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ export namespace Components {
*/
"outline": boolean;
/**
* Button varaint
* Button variant
*/
"variant": Buttons;
}
Expand Down Expand Up @@ -2770,7 +2770,7 @@ declare namespace LocalJSX {
*/
"outline"?: boolean;
/**
* Button varaint
* Button variant
*/
"variant"?: Buttons;
}
Expand Down
11 changes: 5 additions & 6 deletions packages/core/src/components/divider/divider.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@

:host {
display: block;
position: initial;
position: relative;

.line {
width: auto;
border: 0.0625rem solid var(--theme-color-x-weak-bdr);
}
}
width: 100%;
border: 0.0625rem solid var(--theme-color-x-weak-bdr);
margin: 0.25rem 0px;
}
6 changes: 1 addition & 5 deletions packages/core/src/components/divider/divider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ import { Component, h, Host } from '@stencil/core';
})
export class Divider {
render() {
return (
<Host>
<div class="line"></div>
</Host>
);
return <Host></Host>;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
pointer-events: none;
}

.hide {
display: none;
}

.dropdown-button {
display: block;
position: relative;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Buttons } from '../button/button-variants';
})
export class DropdownButton {
/**
* Button varaint
* Button variant
*/
@Prop() variant: Buttons = 'Primary';

Expand All @@ -47,7 +47,7 @@ export class DropdownButton {
/**
* Set label
*/
@Prop() label = '';
@Prop() label: string;

/**
* Button icon
Expand Down Expand Up @@ -85,7 +85,7 @@ export class DropdownButton {
this.dropdownAnchor = ref;
}}
>
{this.label !== '' ? (
{this.label ? (
<ix-button
variant={this.variant}
outline={this.outline}
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/components/dropdown-item/dropdown-item.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
}
}

:focus {
background-color: transparent;
color: var(--theme-menu-item--color);
}

.checkmark {
position: absolute;
left: $small-space;
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/components/dropdown/dropdown.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,8 @@
:host {
min-width: 0px;
}

:host(.overflow) {
max-height: 50vh;
overflow-y: auto;
}
142 changes: 87 additions & 55 deletions packages/core/src/components/dropdown/dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -290,16 +290,37 @@ export class Dropdown {
}
}

private isNestedDropdown(element: Element) {
return element.closest('ix-dropdown');
}

private isAnchorSubmenu() {
const anchor = this.anchorElement?.closest('ix-dropdown-item');
if (!anchor) {
return false;
}

return true;
}

private toggle(event?: Event) {
event?.preventDefault();

if (this.isNestedDropdown(event.target as HTMLElement)) {
event?.stopPropagation();
}

this.show = !this.show;
this.showChanged.emit(this.show);
}

private open(event?: Event) {
event?.preventDefault();

if (this.isNestedDropdown(event.target as HTMLElement)) {
event?.stopPropagation();
}

this.show = true;
this.showChanged.emit(true);
}
Expand All @@ -314,66 +335,76 @@ export class Dropdown {
}

private async applyDropdownPosition() {
if (this.anchorElement && this.dropdownRef) {
let positionConfig: Partial<ComputePositionConfig> = {
strategy: this.positioningStrategy,
middleware: [],
};

if (this.placement.includes('auto')) {
positionConfig.middleware.push(flip());
} else {
positionConfig.placement = this.placement as
| BasePlacement
| PlacementWithAlignment;
}
if (!this.anchorElement) {
return;
}
if (!this.dropdownRef) {
return;
}
const isSubmenu = this.isAnchorSubmenu();

positionConfig.middleware = [
...positionConfig.middleware,
inline(),
shift(),
];
let positionConfig: Partial<ComputePositionConfig> = {
strategy: this.positioningStrategy,
middleware: [],
};

if (this.offset) {
positionConfig.middleware.push(offset(this.offset));
}
if (isSubmenu) {
positionConfig.placement = 'right-start';
}

if (this.autoUpdateCleanup) {
this.autoUpdateCleanup();
this.autoUpdateCleanup = null;
}
this.autoUpdateCleanup = autoUpdate(
this.anchorElement,
this.dropdownRef,
async () => {
const computeResponse = await computePosition(
this.anchorElement,
this.dropdownRef,
positionConfig
);
Object.assign(this.dropdownRef.style, {
top: '0',
left: '0',
transform: `translate(${Math.round(
computeResponse.x
)}px,${Math.round(computeResponse.y)}px)`,
if (this.placement.includes('auto') || isSubmenu) {
positionConfig.middleware.push(flip());
} else {
positionConfig.placement = this.placement as
| BasePlacement
| PlacementWithAlignment;
}

positionConfig.middleware = [
...positionConfig.middleware,
inline(),
shift(),
];

if (this.offset) {
positionConfig.middleware.push(offset(this.offset));
}

if (this.autoUpdateCleanup) {
this.autoUpdateCleanup();
this.autoUpdateCleanup = null;
}
this.autoUpdateCleanup = autoUpdate(
this.anchorElement,
this.dropdownRef,
async () => {
const computeResponse = await computePosition(
this.anchorElement,
this.dropdownRef,
positionConfig
);
Object.assign(this.dropdownRef.style, {
top: '0',
left: '0',
transform: `translate(${Math.round(computeResponse.x)}px,${Math.round(
computeResponse.y
)}px)`,
});
if (this.overwriteDropdownStyle) {
const overwriteStyle = await this.overwriteDropdownStyle({
dropdownRef: this.dropdownRef,
triggerRef: this.triggerElement as HTMLElement,
});
if (this.overwriteDropdownStyle) {
const overwriteStyle = await this.overwriteDropdownStyle({
dropdownRef: this.dropdownRef,
triggerRef: this.triggerElement as HTMLElement,
});

Object.assign(this.dropdownRef.style, overwriteStyle);
}
},
{
ancestorResize: true,
ancestorScroll: true,
elementResize: true,

Object.assign(this.dropdownRef.style, overwriteStyle);
}
);
}
},
{
ancestorResize: true,
ancestorScroll: true,
elementResize: true,
}
);
}

async componentDidLoad() {
Expand Down Expand Up @@ -407,6 +438,7 @@ export class Dropdown {
class={{
'dropdown-menu': true,
show: this.show,
overflow: true,
}}
style={{
margin: '0',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ix-dropdown renders 1`] = `
<ix-dropdown class="dropdown-menu" style="margin: 0; min-width: 0px; position: fixed;">
<ix-dropdown class="dropdown-menu overflow" style="margin: 0; min-width: 0px; position: fixed;">
<mock:shadow-root>
<div style="display: contents;">
<slot></slot>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe('ix-dropdown', () => {
await page.waitForChanges();

expect(page.root).toEqualHtml(`
<ix-dropdown class="dropdown-menu show" show="" style="margin: 0; min-width: 0px; position: fixed;">
<ix-dropdown class="dropdown-menu overflow show" show="" style="margin: 0; min-width: 0px; position: fixed;">
<mock:shadow-root>
<div style="display: contents;">
<slot></slot>
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/components/tree/tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ export class Tree {

private observer: MutationObserver;

private hasFirstRender = false;

private getVirtualizerOptions() {
const list = this.buildTreeList(this.model[this.root]);

Expand Down Expand Up @@ -232,6 +234,8 @@ export class Tree {
}

componentWillRender() {
this.hasFirstRender = true;

if (this.isListInitialized()) {
this.refreshList();
} else {
Expand All @@ -246,7 +250,7 @@ export class Tree {

@Watch('model')
modelChange() {
if (!this.isListInitialized()) {
if (this.hasFirstRender && !this.isListInitialized()) {
this.initList();
}
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit d2fcaaf

Please sign in to comment.