backport PR 1600

This commit is contained in:
Cory LaViska
2023-10-12 12:11:20 -04:00
parent 60b6803437
commit cc18a90a86
4 changed files with 56 additions and 13 deletions

View File

@@ -16,6 +16,7 @@ New versions of Web Awesome are released as-needed and generally occur when a cr
- Changed the `sl` prefix to `wa` for Web Awesome, including tags, events, etc.
- Changed `primary` variants to `brand` in all components
- Improved submenu selection by implementing the [safe triangle](https://www.smashingmagazine.com/2023/08/better-context-menus-safe-triangles/) method [#1550]
- Removed `default` from `<wa-button>` and made `neutral` the new default
- Removed the `circle` modifier from `<wa-button>` because button's no longer have a set height

View File

@@ -25,15 +25,8 @@
"./dist/react/*": "./dist/react/*",
"./dist/translations/*": "./dist/translations/*"
},
"files": [
"dist",
"cdn"
],
"keywords": [
"web components",
"custom elements",
"components"
],
"files": ["dist", "cdn"],
"keywords": ["web components", "custom elements", "components"],
"repository": {
"type": "git",
"url": "git+https://github.com/shoelace-style/shoelace.git"
@@ -136,9 +129,6 @@
"user-agent-data-types": "^0.3.0"
},
"lint-staged": {
"*.{ts,js}": [
"eslint --max-warnings 0 --cache --fix",
"prettier --write"
]
"*.{ts,js}": ["eslint --max-warnings 0 --cache --fix", "prettier --write"]
}
}

View File

@@ -7,6 +7,14 @@ export default css`
:host {
--submenu-offset: -2px;
/* Private */
--safe-triangle-cursor-x: 0;
--safe-triangle-cursor-y: 0;
--safe-triangle-submenu-start-x: 0;
--safe-triangle-submenu-start-y: 0;
--safe-triangle-submenu-end-x: 0;
--safe-triangle-submenu-end-y: 0;
display: block;
}
@@ -60,6 +68,22 @@ export default css`
margin-inline-start: var(--wa-space-xs);
}
/* Safe triangle */
.menu-item--submenu-expanded::after {
content: '';
position: fixed;
z-index: calc(var(--wa-z-index-dropdown) - 1);
top: 0;
right: 0;
bottom: 0;
left: 0;
clip-path: polygon(
var(--safe-triangle-cursor-x) var(--safe-triangle-cursor-y),
var(--safe-triangle-submenu-start-x) var(--safe-triangle-submenu-start-y),
var(--safe-triangle-submenu-end-x) var(--safe-triangle-submenu-end-y)
);
}
:host(:focus-visible) {
outline: none;
}

View File

@@ -49,6 +49,7 @@ export class SubmenuController implements ReactiveController {
private addListeners() {
if (!this.isConnected) {
this.host.addEventListener('mousemove', this.handleMouseMove);
this.host.addEventListener('mouseover', this.handleMouseOver);
this.host.addEventListener('keydown', this.handleKeyDown);
this.host.addEventListener('click', this.handleClick);
@@ -61,6 +62,7 @@ export class SubmenuController implements ReactiveController {
if (!this.isPopupConnected) {
if (this.popupRef.value) {
this.popupRef.value.addEventListener('mouseover', this.handlePopupMouseover);
this.popupRef.value.addEventListener('wa-reposition', this.handlePopupReposition);
this.isPopupConnected = true;
}
}
@@ -68,6 +70,7 @@ export class SubmenuController implements ReactiveController {
private removeListeners() {
if (this.isConnected) {
this.host.removeEventListener('mousemove', this.handleMouseMove);
this.host.removeEventListener('mouseover', this.handleMouseOver);
this.host.removeEventListener('keydown', this.handleKeyDown);
this.host.removeEventListener('click', this.handleClick);
@@ -77,11 +80,18 @@ export class SubmenuController implements ReactiveController {
if (this.isPopupConnected) {
if (this.popupRef.value) {
this.popupRef.value.removeEventListener('mouseover', this.handlePopupMouseover);
this.popupRef.value.removeEventListener('wa-reposition', this.handlePopupReposition);
this.isPopupConnected = false;
}
}
}
// Set the safe triangle cursor position
private handleMouseMove = (event: MouseEvent) => {
this.host.style.setProperty('--safe-triangle-cursor-x', `${event.clientX}px`);
this.host.style.setProperty('--safe-triangle-cursor-y', `${event.clientY}px`);
};
private handleMouseOver = () => {
if (this.hasSlotController.test('submenu')) {
this.enableSubmenu();
@@ -188,6 +198,24 @@ export class SubmenuController implements ReactiveController {
event.stopPropagation();
};
// Set the safe triangle values for the submenu when the position changes
private handlePopupReposition = () => {
const submenuSlot: HTMLSlotElement | null = this.host.renderRoot.querySelector("slot[name='submenu']");
const menu = submenuSlot?.assignedElements({ flatten: true }).filter(el => el.localName === 'wa-menu')[0];
const isRtl = this.localize.dir() === 'rtl';
if (!menu) {
return;
}
const { left, top, width, height } = menu.getBoundingClientRect();
this.host.style.setProperty('--safe-triangle-submenu-start-x', `${isRtl ? left + width : left}px`);
this.host.style.setProperty('--safe-triangle-submenu-start-y', `${top}px`);
this.host.style.setProperty('--safe-triangle-submenu-end-x', `${isRtl ? left + width : left}px`);
this.host.style.setProperty('--safe-triangle-submenu-end-y', `${top + height}px`);
};
private setSubmenuState(state: boolean) {
if (this.popupRef.value) {
if (this.popupRef.value.active !== state) {