Skip to content

Commit ec62f7a

Browse files
committed
Better menu shadows.
1 parent f71ce8f commit ec62f7a

6 files changed

Lines changed: 42 additions & 28 deletions

File tree

README.md

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -201,20 +201,19 @@ The menu supports light and dark themes via the `theme` option. Use `'auto'` to
201201

202202
Custom styling can be applied via the `className` options on each component, or by overriding the CSS custom properties:
203203

204-
| Variable | Description | Light Default | Dark Default |
205-
| -------------------------------------- | ----------------------- | ---------------------------- | --------------------------- |
206-
| `--context-menu-bg` | Menu background color | `white` | `#141414` |
207-
| `--context-menu-shadow` | Menu box shadow | `0 2px 8px rgba(0,0,0,0.15)` | `0 2px 8px rgba(0,0,0,0.3)` |
208-
| `--context-menu-border-radius` | Menu border radius | `4px` | `4px` |
209-
| `--context-menu-min-width` | Menu minimum width | `200px` | `200px` |
210-
| `--context-menu-item-text-color` | Item text color | `black` | `white` |
211-
| `--context-menu-item-font-size` | Item font size | `13px` | `13px` |
212-
| `--context-menu-item-focus-bg` | Focused item background | `#e8e8e8` | `#444444` |
213-
| `--context-menu-item-active-bg` | Active item background | `#f3f3f3` | `#2a2a2a` |
214-
| `--context-menu-item-disabled-opacity` | Disabled item opacity | `0.5` | `0.5` |
215-
| `--context-menu-button-height` | Button height | `30px` | `30px` |
216-
| `--context-menu-button-radius` | Button border radius | `3px` | `3px` |
217-
| `--context-menu-separator-color` | Separator line color | `#e8e8e8` | `#505050` |
204+
| Variable | Description | Light Default | Dark Default |
205+
| -------------------------------------- | ----------------------- | ------------- | ------------ |
206+
| `--context-menu-bg` | Menu background color | `white` | `#141414` |
207+
| `--context-menu-border-radius` | Menu border radius | `5px` | `5px` |
208+
| `--context-menu-min-width` | Menu minimum width | `200px` | `200px` |
209+
| `--context-menu-item-text-color` | Item text color | `black` | `white` |
210+
| `--context-menu-item-font-size` | Item font size | `13px` | `13px` |
211+
| `--context-menu-item-focus-bg` | Focused item background | `#e8e8e8` | `#444444` |
212+
| `--context-menu-item-active-bg` | Active item background | `#f3f3f3` | `#2a2a2a` |
213+
| `--context-menu-item-disabled-opacity` | Disabled item opacity | `0.5` | `0.5` |
214+
| `--context-menu-button-height` | Button height | `30px` | `30px` |
215+
| `--context-menu-button-radius` | Button border radius | `3px` | `3px` |
216+
| `--context-menu-separator-color` | Separator line color | `#e8e8e8` | `#505050` |
218217

219218
## License
220219

assets/screenshot.png

-77 KB
Loading

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mapbox-gl-contextmenu",
3-
"version": "1.0.11",
3+
"version": "1.0.12",
44
"description": "A contextmenu plugin for Mapbox GL JS",
55
"type": "module",
66
"main": "./dist/index.cjs",

src/components/ContextMenu/ContextMenu.module.scss

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
@mixin dark-mode-vars {
22
--context-menu-bg: #141414;
3-
--context-menu-shadow: 0 4px 26px -6px rgba(0, 0, 0, 0.4),
4-
0 2px 12px -4px rgba(0, 0, 0, 0.2);
53
--context-menu-item-text-color: white;
64
--context-menu-item-focus-bg: #444444;
75
--context-menu-item-active-bg: #2a2a2a;
@@ -14,8 +12,9 @@
1412
margin: 0;
1513
padding: 4px 0;
1614
background: var(--context-menu-bg);
17-
border-radius: var(--context-menu-border-radius, 4px);
18-
box-shadow: var(--context-menu-shadow);
15+
border-radius: var(--context-menu-border-radius, 5px);
16+
box-shadow: 0 2px 10px -4px rgba(0, 0, 0, 0.25),
17+
0 1px 4px -2px rgba(0, 0, 0, 0.12);
1918
min-width: var(--context-menu-min-width, 200px);
2019
opacity: 0;
2120
pointer-events: none;
@@ -25,8 +24,6 @@
2524
outline: none;
2625

2726
--context-menu-bg: white;
28-
--context-menu-shadow: 0 4px 26px -6px rgba(0, 0, 0, 0.25),
29-
0 2px 12px -4px rgba(0, 0, 0, 0.12);
3027
--context-menu-item-font-size: 13px;
3128
--context-menu-item-text-color: black;
3229
--context-menu-item-focus-bg: #e8e8e8;
@@ -50,3 +47,8 @@
5047
pointer-events: auto;
5148
visibility: visible;
5249
}
50+
51+
.submenu {
52+
box-shadow: 0 3px 18px -5px rgba(0, 0, 0, 0.28),
53+
0 2px 8px -3px rgba(0, 0, 0, 0.14);
54+
}

src/components/ContextMenu/ContextMenu.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ export interface ContextMenuOptions {
1313
theme?: ContextMenuTheme;
1414
/** The menu width as a CSS value (e.g., "200px") or number in pixels. */
1515
width?: string | number;
16+
/**
17+
* Whether this menu is a submenu. Submenus have elevated shadow styling.
18+
* @internal
19+
*/
20+
isSubmenu?: boolean;
1621
}
1722

1823
export default class ContextMenu {
@@ -22,6 +27,7 @@ export default class ContextMenu {
2227
private _width: string | number | undefined;
2328
protected _menuEl: HTMLElement | null = null;
2429
private _container: HTMLElement | null = null;
30+
private _isSubmenu: boolean = false;
2531

2632
protected _handlers: Record<string, EventListener | null> = {};
2733

@@ -35,6 +41,7 @@ export default class ContextMenu {
3541
: styles.menu;
3642
this._theme = options?.theme ?? "auto";
3743
this._width = options?.width;
44+
this._isSubmenu = options?.isSubmenu ?? false;
3845
}
3946

4047
/**
@@ -77,9 +84,7 @@ export default class ContextMenu {
7784
*/
7885
set className(value: string) {
7986
this._className = value;
80-
if (this._menuEl) {
81-
this._menuEl.className = value;
82-
}
87+
this._applyClassName();
8388
}
8489

8590
/**
@@ -381,8 +386,7 @@ export default class ContextMenu {
381386
if (!this._container) return;
382387

383388
const menu = createElement("menu", {
384-
role: "menu",
385-
class: this._className
389+
role: "menu"
386390
});
387391
menu.style.position = "absolute";
388392
menu.setAttribute("tabindex", "-1"); // Essential for focusing the menu itself
@@ -407,10 +411,19 @@ export default class ContextMenu {
407411

408412
this._menuEl = menu;
409413

414+
this._applyClassName();
410415
this._updateWidth();
411416
this._updateTheme();
412417
}
413418

419+
private _applyClassName(): void {
420+
if (!this._menuEl) return;
421+
this._menuEl.className = this._className;
422+
if (this._isSubmenu) {
423+
this._menuEl.classList.add(styles.submenu);
424+
}
425+
}
426+
414427
private _updateWidth(): void {
415428
if (!this._menuEl) return;
416429

src/components/ContextMenuSubmenu/ContextMenuSubmenu.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import itemStyles from "../ContextMenuItem/ContextMenuItem.module.scss";
88
import chevronSvg from "../../icons/chevron-right.svg?raw";
99

1010
/** Horizontal overlap between submenu and parent menu item (in pixels) */
11-
const SUBMENU_OVERLAP = 2;
11+
const SUBMENU_OVERLAP = 6;
1212

1313
/**
1414
* Configuration options for creating a context menu submenu.
@@ -71,7 +71,7 @@ export default class ContextMenuSubmenu extends ContextMenuItem {
7171
*/
7272
constructor(options: ContextMenuSubmenuOptions) {
7373
super(options);
74-
this._submenu = new ContextMenu();
74+
this._submenu = new ContextMenu({ isSubmenu: true });
7575
this._showDelay = options.showDelay ?? 300;
7676
this._hideDelay = options.hideDelay ?? 200;
7777
}

0 commit comments

Comments
 (0)