@waggylabs/yumekit 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -0
- package/dist/components/y-appbar.js +40 -33
- package/dist/components/y-button.js +1 -0
- package/dist/components/y-dialog.js +1 -1
- package/dist/components/y-menu.d.ts +1 -27
- package/dist/components/y-menu.js +23 -4
- package/dist/components/y-panel.js +45 -24
- package/dist/components/y-select.js +4 -2
- package/dist/components/y-table.js +2 -2
- package/dist/components/y-theme.js +13 -11
- package/dist/icons/all.js +17 -2
- package/dist/icons/index.d.ts +0 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +162 -117
- package/dist/styles/variables.css +3 -0
- package/dist/yumekit.min.js +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="logo.svg" alt="Yumekit Logo" width="120" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">Yumekit</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
A modern, themeable Web Components UI kit — no framework required.
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/@waggylabs/yumekit"><img src="https://img.shields.io/npm/v/@waggylabs/yumekit" alt="npm version" /></a>
|
|
13
|
+
<a href="https://github.com/waggylabs/yumekit/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@waggylabs/yumekit" alt="license" /></a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Overview
|
|
19
|
+
|
|
20
|
+
YumeKit is a collection of 23 production-ready custom elements built with native Web Components. It works with any framework — or none at all — and ships with a comprehensive design token system, built-in theming, an icon registry, and full TypeScript support.
|
|
21
|
+
|
|
22
|
+
- **Zero dependencies** — built entirely on web standards
|
|
23
|
+
- **Framework-agnostic** — works with React, Vue, Svelte, or plain HTML
|
|
24
|
+
- **Themeable** — four built-in themes plus support for fully custom themes
|
|
25
|
+
- **Accessible** — ARIA-compliant, keyboard navigable, form-associated inputs
|
|
26
|
+
- **Tree-shakeable** — import only the components you use
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install @waggylabs/yumekit
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
### Via CDN (script tag)
|
|
41
|
+
|
|
42
|
+
The IIFE bundle includes all components and icons. Drop it into any HTML page:
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<script src="https://cdn.jsdelivr.net/npm/@waggylabs/yumekit/dist/yumekit.min.js"></script>
|
|
46
|
+
|
|
47
|
+
<y-button color="primary">Click me</y-button>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Via ESM (recommended)
|
|
51
|
+
|
|
52
|
+
Import the full library or individual components for tree-shaking:
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
// Full library
|
|
56
|
+
import "@waggylabs/yumekit";
|
|
57
|
+
|
|
58
|
+
// Individual components
|
|
59
|
+
import "@waggylabs/yumekit/components/y-theme";
|
|
60
|
+
import "@waggylabs/yumekit/components/y-button";
|
|
61
|
+
import "@waggylabs/yumekit/components/y-input";
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Then use the `<y-theme>` component to apply a theme:
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<y-theme name="blue-light">
|
|
68
|
+
<!-- your app content -->
|
|
69
|
+
</y-theme>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Components
|
|
75
|
+
|
|
76
|
+
| Component | Element | Description |
|
|
77
|
+
| --------- | -------------- | ------------------------------------------ |
|
|
78
|
+
| App Bar | `<y-appbar>` | Top or side navigation bar |
|
|
79
|
+
| Avatar | `<y-avatar>` | User avatar with shape and color variants |
|
|
80
|
+
| Badge | `<y-badge>` | Status badge or label |
|
|
81
|
+
| Button | `<y-button>` | Button with icon, size, and style variants |
|
|
82
|
+
| Card | `<y-card>` | Content card container |
|
|
83
|
+
| Checkbox | `<y-checkbox>` | Form checkbox input |
|
|
84
|
+
| Dialog | `<y-dialog>` | Modal dialog |
|
|
85
|
+
| Drawer | `<y-drawer>` | Side drawer / sidebar |
|
|
86
|
+
| Icon | `<y-icon>` | SVG icon display |
|
|
87
|
+
| Input | `<y-input>` | Text input field |
|
|
88
|
+
| Menu | `<y-menu>` | Dropdown navigation menu |
|
|
89
|
+
| Panel | `<y-panel>` | Accordion panel |
|
|
90
|
+
| Panel Bar | `<y-panelbar>` | Accordion panel group |
|
|
91
|
+
| Progress | `<y-progress>` | Progress bar |
|
|
92
|
+
| Radio | `<y-radio>` | Radio button input |
|
|
93
|
+
| Select | `<y-select>` | Select / dropdown input |
|
|
94
|
+
| Slider | `<y-slider>` | Range slider input |
|
|
95
|
+
| Switch | `<y-switch>` | Toggle switch |
|
|
96
|
+
| Table | `<y-table>` | Data table |
|
|
97
|
+
| Tabs | `<y-tabs>` | Tabbed interface |
|
|
98
|
+
| Tag | `<y-tag>` | Tag / chip label |
|
|
99
|
+
| Theme | `<y-theme>` | Theme provider |
|
|
100
|
+
| Toast | `<y-toast>` | Notification toast |
|
|
101
|
+
| Tooltip | `<y-tooltip>` | Tooltip / popover |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## TypeScript
|
|
106
|
+
|
|
107
|
+
Type definitions are included. React-specific type augmentations are available at `@waggylabs/yumekit/react`.
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import "@waggylabs/yumekit";
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
MIT © [WaggyLabs](https://github.com/waggylabs)
|
|
@@ -221,6 +221,7 @@ class YumeButton extends HTMLElement {
|
|
|
221
221
|
.button {
|
|
222
222
|
box-sizing: border-box;
|
|
223
223
|
display: inline-flex;
|
|
224
|
+
width: 100%;
|
|
224
225
|
min-height: var(--button-min-height, var(--sizing-medium, 40px));
|
|
225
226
|
min-width: var(--button-min-width, var(--sizing-medium, 40px));
|
|
226
227
|
padding: var(--button-padding, var(--component-button-padding-medium));
|
|
@@ -836,6 +837,31 @@ if (!customElements.get("y-icon")) {
|
|
|
836
837
|
customElements.define("y-icon", YumeIcon);
|
|
837
838
|
}
|
|
838
839
|
|
|
840
|
+
/* ================================================================== */
|
|
841
|
+
/* Centralized SVG icon strings for the YumeKit component library. */
|
|
842
|
+
/* */
|
|
843
|
+
/* Each static icon also lives in its own .svg file in this directory */
|
|
844
|
+
/* so it can be used standalone (e.g. <img src="…">, CSS background, */
|
|
845
|
+
/* design tools, etc.). The strings below mirror those files — keep */
|
|
846
|
+
/* them in sync when editing an icon. */
|
|
847
|
+
/* ================================================================== */
|
|
848
|
+
|
|
849
|
+
/* ── Chevrons ─────────────────────────────────────────────────────── */
|
|
850
|
+
|
|
851
|
+
const chevronRight = `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>`;
|
|
852
|
+
|
|
853
|
+
const chevronDown = `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>`;
|
|
854
|
+
|
|
855
|
+
/* ── Double chevrons (collapse / expand) ──────────────────────────── */
|
|
856
|
+
|
|
857
|
+
const collapseLeft = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="11 17 6 12 11 7"/><polyline points="18 17 13 12 18 7"/></svg>`;
|
|
858
|
+
|
|
859
|
+
const expandRight = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="13 17 18 12 13 7"/><polyline points="6 17 11 12 6 7"/></svg>`;
|
|
860
|
+
|
|
861
|
+
/* ── Menu (hamburger) ────────────────────────────────────────────── */
|
|
862
|
+
|
|
863
|
+
const menu = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" y1="6" x2="20" y2="6"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="18" x2="20" y2="18"/></svg>`;
|
|
864
|
+
|
|
839
865
|
class YumeMenu extends HTMLElement {
|
|
840
866
|
static get observedAttributes() {
|
|
841
867
|
return ["items", "anchor", "visible", "direction", "size"];
|
|
@@ -972,10 +998,16 @@ class YumeMenu extends HTMLElement {
|
|
|
972
998
|
});
|
|
973
999
|
}
|
|
974
1000
|
|
|
1001
|
+
if (!item.children?.length) {
|
|
1002
|
+
li.addEventListener("click", () => {
|
|
1003
|
+
this.visible = false;
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
1006
|
+
|
|
975
1007
|
if (item.children?.length) {
|
|
976
1008
|
const indicator = document.createElement("span");
|
|
977
1009
|
indicator.className = "submenu-indicator";
|
|
978
|
-
indicator.
|
|
1010
|
+
indicator.innerHTML = chevronRight;
|
|
979
1011
|
li.appendChild(indicator);
|
|
980
1012
|
|
|
981
1013
|
const submenu = this._createMenuList(item.children);
|
|
@@ -1129,8 +1161,6 @@ class YumeMenu extends HTMLElement {
|
|
|
1129
1161
|
border-radius: var(--component-menu-border-radius, 4px);
|
|
1130
1162
|
box-shadow: var(--component-menu-shadow, 0 2px 8px rgba(0, 0, 0, 0.15));
|
|
1131
1163
|
min-width: 150px;
|
|
1132
|
-
max-height: 300px;
|
|
1133
|
-
overflow-y: auto;
|
|
1134
1164
|
}
|
|
1135
1165
|
|
|
1136
1166
|
li.menuitem {
|
|
@@ -1142,6 +1172,7 @@ class YumeMenu extends HTMLElement {
|
|
|
1142
1172
|
white-space: nowrap;
|
|
1143
1173
|
color: var(--component-menu-color, #f7f7fa);
|
|
1144
1174
|
font-size: var(--font-size-button, 1em);
|
|
1175
|
+
position: relative;
|
|
1145
1176
|
}
|
|
1146
1177
|
|
|
1147
1178
|
li.menuitem:hover {
|
|
@@ -1161,7 +1192,8 @@ class YumeMenu extends HTMLElement {
|
|
|
1161
1192
|
}
|
|
1162
1193
|
|
|
1163
1194
|
.submenu-indicator {
|
|
1164
|
-
|
|
1195
|
+
display: inline-flex;
|
|
1196
|
+
align-items: center;
|
|
1165
1197
|
margin-left: 0.5rem;
|
|
1166
1198
|
opacity: 0.6;
|
|
1167
1199
|
}
|
|
@@ -1186,31 +1218,6 @@ if (!customElements.get("y-menu")) {
|
|
|
1186
1218
|
customElements.define("y-menu", YumeMenu);
|
|
1187
1219
|
}
|
|
1188
1220
|
|
|
1189
|
-
/* ================================================================== */
|
|
1190
|
-
/* Centralized SVG icon strings for the YumeKit component library. */
|
|
1191
|
-
/* */
|
|
1192
|
-
/* Each static icon also lives in its own .svg file in this directory */
|
|
1193
|
-
/* so it can be used standalone (e.g. <img src="…">, CSS background, */
|
|
1194
|
-
/* design tools, etc.). The strings below mirror those files — keep */
|
|
1195
|
-
/* them in sync when editing an icon. */
|
|
1196
|
-
/* ================================================================== */
|
|
1197
|
-
|
|
1198
|
-
/* ── Chevrons ─────────────────────────────────────────────────────── */
|
|
1199
|
-
|
|
1200
|
-
const chevronRight = `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>`;
|
|
1201
|
-
|
|
1202
|
-
const chevronDown = `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>`;
|
|
1203
|
-
|
|
1204
|
-
/* ── Double chevrons (collapse / expand) ──────────────────────────── */
|
|
1205
|
-
|
|
1206
|
-
const collapseLeft = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="11 17 6 12 11 7"/><polyline points="18 17 13 12 18 7"/></svg>`;
|
|
1207
|
-
|
|
1208
|
-
const expandRight = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="13 17 18 12 13 7"/><polyline points="6 17 11 12 6 7"/></svg>`;
|
|
1209
|
-
|
|
1210
|
-
/* ── Menu (hamburger) ────────────────────────────────────────────── */
|
|
1211
|
-
|
|
1212
|
-
const menu = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" y1="6" x2="20" y2="6"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="18" x2="20" y2="18"/></svg>`;
|
|
1213
|
-
|
|
1214
1221
|
class YumeAppbar extends HTMLElement {
|
|
1215
1222
|
static get observedAttributes() {
|
|
1216
1223
|
return [
|
|
@@ -1574,21 +1581,21 @@ class YumeAppbar extends HTMLElement {
|
|
|
1574
1581
|
const sizeConfig = {
|
|
1575
1582
|
small: {
|
|
1576
1583
|
padding: "var(--spacing-x-small, 4px)",
|
|
1577
|
-
collapsedWidth: "40px",
|
|
1584
|
+
collapsedWidth: "var(--component-appbar-collapsed-width-small, 40px)",
|
|
1578
1585
|
bodyGap: "2px",
|
|
1579
1586
|
buttonSize: "small",
|
|
1580
1587
|
iconSize: "small",
|
|
1581
1588
|
},
|
|
1582
1589
|
medium: {
|
|
1583
1590
|
padding: "var(--spacing-small, 6px)",
|
|
1584
|
-
collapsedWidth: "52px",
|
|
1591
|
+
collapsedWidth: "var(--component-appbar-collapsed-width-medium, 52px)",
|
|
1585
1592
|
bodyGap: "3px",
|
|
1586
1593
|
buttonSize: "medium",
|
|
1587
1594
|
iconSize: "medium",
|
|
1588
1595
|
},
|
|
1589
1596
|
large: {
|
|
1590
1597
|
padding: "var(--spacing-medium, 8px)",
|
|
1591
|
-
collapsedWidth: "64px",
|
|
1598
|
+
collapsedWidth: "var(--component-appbar-collapsed-width-large, 64px)",
|
|
1592
1599
|
bodyGap: "4px",
|
|
1593
1600
|
buttonSize: "large",
|
|
1594
1601
|
iconSize: "large",
|
|
@@ -1840,7 +1847,7 @@ class YumeAppbar extends HTMLElement {
|
|
|
1840
1847
|
bar.style.setProperty("--_appbar-body-gap", cfg.bodyGap);
|
|
1841
1848
|
bar.style.setProperty(
|
|
1842
1849
|
"--_icon-col-width",
|
|
1843
|
-
`calc(${cfg.collapsedWidth} - 2 * var(--_appbar-padding) - 2 * var(--component-appbar-border-width, var(--component-sidebar-border-width, 2px)))`,
|
|
1850
|
+
`calc(${cfg.collapsedWidth} - 2 * var(--_appbar-padding) - 2 * var(--component-appbar-border-width, var(--component-sidebar-border-width, 2px)) - 2 * var(--component-button-border-width, 1px))`,
|
|
1844
1851
|
);
|
|
1845
1852
|
|
|
1846
1853
|
const header = document.createElement("div");
|
|
@@ -219,6 +219,7 @@ class YumeButton extends HTMLElement {
|
|
|
219
219
|
.button {
|
|
220
220
|
box-sizing: border-box;
|
|
221
221
|
display: inline-flex;
|
|
222
|
+
width: 100%;
|
|
222
223
|
min-height: var(--button-min-height, var(--sizing-medium, 40px));
|
|
223
224
|
min-width: var(--button-min-width, var(--sizing-medium, 40px));
|
|
224
225
|
padding: var(--button-padding, var(--component-button-padding-medium));
|
|
@@ -126,11 +126,11 @@ class YumeDialog extends HTMLElement {
|
|
|
126
126
|
display: none;
|
|
127
127
|
align-items: center;
|
|
128
128
|
justify-content: center;
|
|
129
|
-
background: rgba(0,0,0,0.5);
|
|
130
129
|
z-index: var(--component-dialog-z-index, 1000);
|
|
131
130
|
}
|
|
132
131
|
:host([visible]) { display: flex; }
|
|
133
132
|
:host([show-backdrop]) {
|
|
133
|
+
background: rgba(0,0,0,0.5);
|
|
134
134
|
backdrop-filter: blur(var(--component-dialog-backdrop-blur, 4px));
|
|
135
135
|
-webkit-backdrop-filter: blur(var(--component-dialog-backdrop-blur, 4px));
|
|
136
136
|
}
|
|
@@ -1,27 +1 @@
|
|
|
1
|
-
|
|
2
|
-
static get observedAttributes(): string[];
|
|
3
|
-
static _closeAll(except: any): void;
|
|
4
|
-
_onAnchorClick(e: any): void;
|
|
5
|
-
_onDocumentClick(e: any): void;
|
|
6
|
-
_onScrollOrResize(): void;
|
|
7
|
-
connectedCallback(): void;
|
|
8
|
-
set items(val: any);
|
|
9
|
-
get items(): any;
|
|
10
|
-
disconnectedCallback(): void;
|
|
11
|
-
attributeChangedCallback(name: any, oldVal: any, newVal: any): void;
|
|
12
|
-
set anchor(val: string);
|
|
13
|
-
get anchor(): string;
|
|
14
|
-
set visible(val: boolean);
|
|
15
|
-
get visible(): boolean;
|
|
16
|
-
set direction(val: string);
|
|
17
|
-
get direction(): string;
|
|
18
|
-
set size(val: string);
|
|
19
|
-
get size(): string;
|
|
20
|
-
_createMenuList(items: any): HTMLUListElement;
|
|
21
|
-
_findTemplate(name: any): Element;
|
|
22
|
-
_setupAnchor(): void;
|
|
23
|
-
_anchorEl: any;
|
|
24
|
-
_teardownAnchor(): void;
|
|
25
|
-
_updatePosition(): void;
|
|
26
|
-
render(): void;
|
|
27
|
-
}
|
|
1
|
+
export {};
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/* ================================================================== */
|
|
2
|
+
/* Centralized SVG icon strings for the YumeKit component library. */
|
|
3
|
+
/* */
|
|
4
|
+
/* Each static icon also lives in its own .svg file in this directory */
|
|
5
|
+
/* so it can be used standalone (e.g. <img src="…">, CSS background, */
|
|
6
|
+
/* design tools, etc.). The strings below mirror those files — keep */
|
|
7
|
+
/* them in sync when editing an icon. */
|
|
8
|
+
/* ================================================================== */
|
|
9
|
+
|
|
10
|
+
/* ── Chevrons ─────────────────────────────────────────────────────── */
|
|
11
|
+
|
|
12
|
+
const chevronRight = `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>`;
|
|
13
|
+
|
|
1
14
|
class YumeMenu extends HTMLElement {
|
|
2
15
|
static get observedAttributes() {
|
|
3
16
|
return ["items", "anchor", "visible", "direction", "size"];
|
|
@@ -134,10 +147,16 @@ class YumeMenu extends HTMLElement {
|
|
|
134
147
|
});
|
|
135
148
|
}
|
|
136
149
|
|
|
150
|
+
if (!item.children?.length) {
|
|
151
|
+
li.addEventListener("click", () => {
|
|
152
|
+
this.visible = false;
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
137
156
|
if (item.children?.length) {
|
|
138
157
|
const indicator = document.createElement("span");
|
|
139
158
|
indicator.className = "submenu-indicator";
|
|
140
|
-
indicator.
|
|
159
|
+
indicator.innerHTML = chevronRight;
|
|
141
160
|
li.appendChild(indicator);
|
|
142
161
|
|
|
143
162
|
const submenu = this._createMenuList(item.children);
|
|
@@ -291,8 +310,6 @@ class YumeMenu extends HTMLElement {
|
|
|
291
310
|
border-radius: var(--component-menu-border-radius, 4px);
|
|
292
311
|
box-shadow: var(--component-menu-shadow, 0 2px 8px rgba(0, 0, 0, 0.15));
|
|
293
312
|
min-width: 150px;
|
|
294
|
-
max-height: 300px;
|
|
295
|
-
overflow-y: auto;
|
|
296
313
|
}
|
|
297
314
|
|
|
298
315
|
li.menuitem {
|
|
@@ -304,6 +321,7 @@ class YumeMenu extends HTMLElement {
|
|
|
304
321
|
white-space: nowrap;
|
|
305
322
|
color: var(--component-menu-color, #f7f7fa);
|
|
306
323
|
font-size: var(--font-size-button, 1em);
|
|
324
|
+
position: relative;
|
|
307
325
|
}
|
|
308
326
|
|
|
309
327
|
li.menuitem:hover {
|
|
@@ -323,7 +341,8 @@ class YumeMenu extends HTMLElement {
|
|
|
323
341
|
}
|
|
324
342
|
|
|
325
343
|
.submenu-indicator {
|
|
326
|
-
|
|
344
|
+
display: inline-flex;
|
|
345
|
+
align-items: center;
|
|
327
346
|
margin-left: 0.5rem;
|
|
328
347
|
opacity: 0.6;
|
|
329
348
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
/* ================================================================== */
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
const
|
|
11
|
+
const chevronDown = `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>`;
|
|
12
12
|
|
|
13
13
|
class YumePanel extends HTMLElement {
|
|
14
14
|
static get observedAttributes() {
|
|
@@ -191,17 +191,13 @@ class YumePanel extends HTMLElement {
|
|
|
191
191
|
return;
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
composed: true,
|
|
202
|
-
}),
|
|
203
|
-
);
|
|
204
|
-
}
|
|
194
|
+
this.dispatchEvent(
|
|
195
|
+
new CustomEvent("select", {
|
|
196
|
+
detail: { selected: true },
|
|
197
|
+
bubbles: true,
|
|
198
|
+
composed: true,
|
|
199
|
+
}),
|
|
200
|
+
);
|
|
205
201
|
});
|
|
206
202
|
|
|
207
203
|
header.addEventListener("keydown", (e) => {
|
|
@@ -211,6 +207,21 @@ class YumePanel extends HTMLElement {
|
|
|
211
207
|
}
|
|
212
208
|
});
|
|
213
209
|
|
|
210
|
+
const arrow = this.shadowRoot.querySelector(".arrow");
|
|
211
|
+
if (arrow) {
|
|
212
|
+
arrow.addEventListener("click", (e) => {
|
|
213
|
+
e.stopPropagation();
|
|
214
|
+
this.toggle();
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
arrow.addEventListener("keydown", (e) => {
|
|
218
|
+
if (e.key === " " || e.key === "Enter") {
|
|
219
|
+
e.preventDefault();
|
|
220
|
+
this.toggle();
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
214
225
|
const childrenSlot = this.shadowRoot.querySelector(
|
|
215
226
|
'slot[name="children"]',
|
|
216
227
|
);
|
|
@@ -254,13 +265,13 @@ class YumePanel extends HTMLElement {
|
|
|
254
265
|
|
|
255
266
|
updateExpandedState() {
|
|
256
267
|
const hasChildren = this.hasChildren();
|
|
257
|
-
const
|
|
268
|
+
const arrow = this.shadowRoot.querySelector(".arrow");
|
|
258
269
|
const isExpanded = this.expanded && hasChildren;
|
|
259
270
|
|
|
260
271
|
this._expanded = isExpanded;
|
|
261
272
|
|
|
262
|
-
if (
|
|
263
|
-
|
|
273
|
+
if (arrow) {
|
|
274
|
+
arrow.setAttribute("aria-expanded", String(isExpanded));
|
|
264
275
|
}
|
|
265
276
|
}
|
|
266
277
|
|
|
@@ -315,10 +326,6 @@ class YumePanel extends HTMLElement {
|
|
|
315
326
|
background: var(--component-panel-hover-background);
|
|
316
327
|
}
|
|
317
328
|
|
|
318
|
-
:host([data-has-children="false"]) .header {
|
|
319
|
-
cursor: default;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
329
|
.header ::slotted([slot="icon"]) {
|
|
323
330
|
margin-right: 6px;
|
|
324
331
|
}
|
|
@@ -334,9 +341,23 @@ class YumePanel extends HTMLElement {
|
|
|
334
341
|
display: inline-flex;
|
|
335
342
|
align-items: center;
|
|
336
343
|
justify-content: center;
|
|
344
|
+
transition: transform 0.2s ease;
|
|
345
|
+
background: none;
|
|
346
|
+
border: none;
|
|
347
|
+
padding: 0;
|
|
348
|
+
cursor: pointer;
|
|
349
|
+
color: inherit;
|
|
350
|
+
flex-shrink: 0;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.arrow:focus-visible {
|
|
354
|
+
outline: 2px solid var(--component-panel-accent, currentColor);
|
|
355
|
+
border-radius: 2px;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.arrow svg {
|
|
337
359
|
width: 20px;
|
|
338
360
|
height: 20px;
|
|
339
|
-
transition: transform 0.2s ease;
|
|
340
361
|
}
|
|
341
362
|
|
|
342
363
|
:host([expanded]) .arrow {
|
|
@@ -366,12 +387,12 @@ class YumePanel extends HTMLElement {
|
|
|
366
387
|
|
|
367
388
|
this.shadowRoot.adoptedStyleSheets = [sheet];
|
|
368
389
|
this.shadowRoot.innerHTML = `
|
|
369
|
-
<div class="header" part="header" role="button" tabindex="0"
|
|
390
|
+
<div class="header" part="header" role="button" tabindex="0">
|
|
370
391
|
<slot name="icon"></slot>
|
|
371
392
|
<slot name="label"><slot></slot></slot>
|
|
372
|
-
<
|
|
373
|
-
${
|
|
374
|
-
</
|
|
393
|
+
<button class="arrow" id="arrow" part="arrow" tabindex="0" aria-expanded="false" aria-label="Toggle children">
|
|
394
|
+
${chevronDown}
|
|
395
|
+
</button>
|
|
375
396
|
</div>
|
|
376
397
|
<div class="children" id="childrenContainer" part="children">
|
|
377
398
|
<slot name="children"></slot>
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
/* ================================================================== */
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
const
|
|
11
|
+
const chevronDown = `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>`;
|
|
12
12
|
|
|
13
13
|
class YumeSelect extends HTMLElement {
|
|
14
14
|
static formAssociated = true;
|
|
@@ -490,6 +490,8 @@ class YumeSelect extends HTMLElement {
|
|
|
490
490
|
}
|
|
491
491
|
|
|
492
492
|
.chevron-icon svg {
|
|
493
|
+
width: 20px;
|
|
494
|
+
height: 20px;
|
|
493
495
|
transition: transform 0.2s ease;
|
|
494
496
|
transform-origin: center;
|
|
495
497
|
}
|
|
@@ -516,7 +518,7 @@ class YumeSelect extends HTMLElement {
|
|
|
516
518
|
<div class="select-container ${isInvalid ? "is-invalid" : ""}" tabindex="0">
|
|
517
519
|
<div class="value-display">${this.getDisplayText()}</div>
|
|
518
520
|
<div class="chevron-icon" part="chevron-icon">
|
|
519
|
-
${
|
|
521
|
+
${chevronDown}
|
|
520
522
|
</div>
|
|
521
523
|
</div>
|
|
522
524
|
${!isLabelTop ? '<div class="label-wrapper"><slot name="label"></slot></div>' : ""}
|
|
@@ -195,7 +195,7 @@ class YumeTable extends HTMLElement {
|
|
|
195
195
|
position: relative;
|
|
196
196
|
padding: ${paddingVar};
|
|
197
197
|
text-align: left;
|
|
198
|
-
font-weight:
|
|
198
|
+
font-weight: 400;
|
|
199
199
|
font-size: var(--font-size-paragraph, 1em);
|
|
200
200
|
white-space: nowrap;
|
|
201
201
|
background: transparent;
|
|
@@ -233,7 +233,7 @@ class YumeTable extends HTMLElement {
|
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
tbody td.row-header {
|
|
236
|
-
font-weight:
|
|
236
|
+
font-weight: 400;
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
${
|