Skip to content

Commit

Permalink
feat(ui5-color-palette-popover): introduce open and opener proper…
Browse files Browse the repository at this point in the history
…ties (#7988)

- Introduces open and opener properties to declaratively open/close the popover
- Introduces close event fired when the popover closes due to user interaction - clicking outside, selecting a color, pressing esc, etc.
  • Loading branch information
ilhan007 authored Dec 14, 2023
1 parent b6b41f2 commit d3bda7e
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 89 deletions.
30 changes: 26 additions & 4 deletions packages/main/src/ColorPalette.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,16 @@ class ColorPalette extends UI5Element {
}
}

onAfterRendering() {
if (this.popupMode) {
if (this.showDefaultColor) {
this.focusFirstFocusableElement();
} else {
this.focusFirstDisplayColorElement();
}
}
}

selectColor(item: ColorPaletteItem) {
if (!item.value) {
return;
Expand Down Expand Up @@ -306,7 +316,7 @@ class ColorPalette extends UI5Element {
if (this.hasRecentColors) {
this.focusColorElement(this.colorPaletteNavigationElements[index + 1], this._itemNavigationRecentColors);
} else if (this.showDefaultColor) {
this.colorPaletteNavigationElements[0].focus();
this.firstFocusableElement.focus();
} else {
this.focusColorElement(this.displayedColors[0], this._itemNavigation);
}
Expand All @@ -324,7 +334,7 @@ class ColorPalette extends UI5Element {
if (isUp(e) && target === this.displayedColors[0] && this.colorPaletteNavigationElements.length > 1) {
e.stopPropagation();
if (this.showDefaultColor) {
this.colorPaletteNavigationElements[0].focus();
this.firstFocusableElement.focus();
} else if (!this.showDefaultColor && this.hasRecentColors) {
this.focusColorElement(lastElementInNavigation, this._itemNavigationRecentColors);
} else if (!this.showDefaultColor && this.showMoreColors) {
Expand All @@ -337,7 +347,7 @@ class ColorPalette extends UI5Element {
if (this.showDefaultColor && this.showMoreColors) {
this.colorPaletteNavigationElements[2].focus();
} else if (this.showDefaultColor && !this.showMoreColors && (!this.showRecentColors || !this.recentColors[0])) {
this.colorPaletteNavigationElements[0].focus();
this.firstFocusableElement.focus();
} else if (isRecentColorsNextElement) {
this.focusColorElement(lastElementInNavigation, this._itemNavigationRecentColors);
} else if (!this.showDefaultColor && this.showMoreColors) {
Expand All @@ -359,7 +369,7 @@ class ColorPalette extends UI5Element {
}
} else if (isDown(e)) {
if (this.showDefaultColor) {
this.colorPaletteNavigationElements[0].focus();
this.firstFocusableElement.focus();
} else {
e.stopPropagation();
this.focusColorElement(this.displayedColors[0], this._itemNavigation);
Expand All @@ -372,6 +382,18 @@ class ColorPalette extends UI5Element {
itemNavigation._focusCurrentItem();
}

focusFirstDisplayColorElement() {
this.focusColorElement(this.displayedColors[0], this._itemNavigation);
}

focusFirstFocusableElement() {
this.firstFocusableElement.focus();
}

get firstFocusableElement() {
return this.colorPaletteNavigationElements[0];
}

async _chooseCustomColor() {
const colorPicker = await this.getColorPicker();
this._setColor(colorPicker.color);
Expand Down
3 changes: 3 additions & 0 deletions packages/main/src/ColorPalettePopover.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
hide-arrow
content-only-on-desktop
placement-type="Bottom"
?open="{{_open}}"
.opener="{{opener}}"
@ui5-after-close="{{onAfterClose}}"
>
<div slot="header" class="ui5-cp-header">
<ui5-title
Expand Down
76 changes: 51 additions & 25 deletions packages/main/src/ColorPalettePopover.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
import DOMReference from "@ui5/webcomponents-base/dist/types/DOMReference.js";
import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
Expand Down Expand Up @@ -82,6 +83,13 @@ type ColorPalettePopoverItemClickEventDetail = ColorPaletteItemClickEventDetail;
},
},
})
/**
* Fired when the <code>ui5-color-palette-popover</code> is closed due to user interaction.
* @event sap.ui.webc.main.ColorPalettePopover#close
* @since 1.21.0
* @public
*/
@event("close")
class ColorPalettePopover extends UI5Element {
/**
* Defines whether the user can see the last used colors in the bottom of the component
Expand Down Expand Up @@ -124,6 +132,28 @@ class ColorPalettePopover extends UI5Element {
@property({ validator: CSSColor })
defaultColor?: string;

/**
* Defines the open | closed state of the popover.
* @public
* @type {boolean}
* @name sap.ui.webc.main.ColorPalettePopover.prototype.open
* @defaultvalue false
* @since 1.21.0
*/
@property({ type: Boolean })
open!: boolean;

/**
* Defines the ID or DOM Reference of the element that the popover is shown at.
* @public
* @type {sap.ui.webc.base.types.DOMReference}
* @name sap.ui.webc.main.ColorPalettePopover.prototype.opener
* @defaultvalue undefined
* @since 1.21.0
*/
@property({ validator: DOMReference })
opener?: HTMLElement | string;

/**
* Defines the content of the component.
* @type {sap.ui.webc.main.IColorPaletteItem[]}
Expand All @@ -136,8 +166,6 @@ class ColorPalettePopover extends UI5Element {

static i18nBundle: I18nBundle;

responsivePopover?: ResponsivePopover;

static async onDefine() {
ColorPalettePopover.i18nBundle = await getI18nBundle("@ui5/webcomponents");
}
Expand All @@ -146,13 +174,12 @@ class ColorPalettePopover extends UI5Element {
super();
}

_respPopover() {
this.responsivePopover = this.shadowRoot!.querySelector<ResponsivePopover>("[ui5-responsive-popover]")!;
return this.responsivePopover;
get responsivePopover() {
return this.shadowRoot!.querySelector<ResponsivePopover>("[ui5-responsive-popover]")!;
}

_colorPalette() {
return this.responsivePopover!.content[0].querySelector<ColorPalette>("[ui5-color-palette]")!;
get respPopover() {
return this.shadowRoot!.querySelector<ResponsivePopover>("[ui5-responsive-popover]")!;
}

/**
Expand All @@ -161,10 +188,13 @@ class ColorPalettePopover extends UI5Element {
* @public
* @method
* @name sap.ui.webc.main.ColorPalettePopover#showAt
* @deprecated The method is deprecated in favour of <code>open</code> and <code>opener</code> properties.
* @since 1.1.1
*/
showAt(opener: HTMLElement) {
this._openPopover(opener);
console.warn("The method 'showAt' is deprecated and will be removed in future, use 'open' and 'opener' props instead."); // eslint-disable-line
this.open = true;
this.opener = opener;
}

/**
Expand All @@ -175,27 +205,20 @@ class ColorPalettePopover extends UI5Element {
* @method
* @name sap.ui.webc.main.ColorPalettePopover#openPopover
* @since 1.0.0-rc.16
* @deprecated The method is deprecated in favour of <code>showAt</code>.
* @deprecated The method is deprecated in favour of <code>open</code> and <code>opener</code> properties.
*/
openPopover(opener: HTMLElement) {
console.warn("The method 'openPopover' is deprecated and will be removed in future, use 'showAt' instead."); // eslint-disable-line
this._openPopover(opener);
console.warn("The method 'openPopover' is deprecated and will be removed in future, use 'open' and 'opener' props instead."); // eslint-disable-line
this.showAt(opener);
}

_openPopover(opener: HTMLElement) {
this._respPopover();

this.responsivePopover!.showAt(opener, true);

if (this.showDefaultColor) {
this._colorPalette().colorPaletteNavigationElements[0].focus();
} else {
this._colorPalette().focusColorElement(this._colorPalette().colorPaletteNavigationElements[0], this._colorPalette()._itemNavigation);
}
closePopover() {
this.open = false;
}

closePopover() {
this.responsivePopover!.close();
onAfterClose() {
this.closePopover();
this.fireEvent("close");
}

onSelectedColor(e: CustomEvent<ColorPaletteItemClickEventDetail>) {
Expand All @@ -211,8 +234,7 @@ class ColorPalettePopover extends UI5Element {
* @returns {boolean}
*/
isOpen() {
this._respPopover();
return this.responsivePopover!.opened;
return this.open;
}

get colorPaletteColors() {
Expand All @@ -226,6 +248,10 @@ class ColorPalettePopover extends UI5Element {
get _cancelButtonLabel() {
return ColorPalettePopover.i18nBundle.getText(COLOR_PALETTE_DIALOG_CANCEL_BUTTON);
}

get _open() {
return this.open || undefined;
}
}

ColorPalettePopover.define();
Expand Down
2 changes: 1 addition & 1 deletion packages/main/src/Popover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ class Popover extends Popup {
if (this.opener instanceof HTMLElement) {
opener = this.opener;
} else if (typeof this.opener === "string") {
opener = (this.getRootNode() as Document).getElementById(this.opener);
opener = (this.getRootNode() as Document).getElementById(this.opener) || document.getElementById(this.opener);
}

if (!opener) {
Expand Down
4 changes: 4 additions & 0 deletions packages/main/src/themes/ColorPalettePopover.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
padding: 0;
}

[ui5-title], [ui5-button] {
margin-bottom: 1rem;
}

.ui5-cp-item-container {
padding: 0.3125rem 0.6875rem;
}
Loading

0 comments on commit d3bda7e

Please sign in to comment.