@duskmoon-dev/el-circle-menu 1.1.0
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/dist/cjs/index.js +193 -0
- package/dist/cjs/index.js.map +11 -0
- package/dist/cjs/register.js +196 -0
- package/dist/cjs/register.js.map +12 -0
- package/dist/esm/index.js +151 -0
- package/dist/esm/index.js.map +11 -0
- package/dist/esm/register.js +150 -0
- package/dist/esm/register.js.map +12 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/el-dm-circle-menu.d.ts +63 -0
- package/dist/types/el-dm-circle-menu.d.ts.map +1 -0
- package/dist/types/index.d.ts +19 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/register.d.ts +2 -0
- package/dist/types/register.d.ts.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
function __accessProp(key) {
|
|
6
|
+
return this[key];
|
|
7
|
+
}
|
|
8
|
+
var __toCommonJS = (from) => {
|
|
9
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
10
|
+
if (entry)
|
|
11
|
+
return entry;
|
|
12
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (var key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(entry, key))
|
|
16
|
+
__defProp(entry, key, {
|
|
17
|
+
get: __accessProp.bind(from, key),
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
__moduleCache.set(from, entry);
|
|
22
|
+
return entry;
|
|
23
|
+
};
|
|
24
|
+
var __moduleCache;
|
|
25
|
+
var __returnValue = (v) => v;
|
|
26
|
+
function __exportSetter(name, newValue) {
|
|
27
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
28
|
+
}
|
|
29
|
+
var __export = (target, all) => {
|
|
30
|
+
for (var name in all)
|
|
31
|
+
__defProp(target, name, {
|
|
32
|
+
get: all[name],
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
set: __exportSetter.bind(all, name)
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/index.ts
|
|
40
|
+
var exports_src = {};
|
|
41
|
+
__export(exports_src, {
|
|
42
|
+
register: () => register,
|
|
43
|
+
ElDmCircleMenu: () => ElDmCircleMenu
|
|
44
|
+
});
|
|
45
|
+
module.exports = __toCommonJS(exports_src);
|
|
46
|
+
|
|
47
|
+
// src/el-dm-circle-menu.ts
|
|
48
|
+
var import_el_base = require("@duskmoon-dev/el-base");
|
|
49
|
+
var import_circle_menu = require("@duskmoon-dev/core/components/circle-menu");
|
|
50
|
+
var COLOR_CLASSES = {
|
|
51
|
+
primary: "circle-menu-primary",
|
|
52
|
+
secondary: "circle-menu-secondary",
|
|
53
|
+
tertiary: "circle-menu-tertiary",
|
|
54
|
+
info: "circle-menu-info",
|
|
55
|
+
success: "circle-menu-success",
|
|
56
|
+
warning: "circle-menu-warning",
|
|
57
|
+
error: "circle-menu-error"
|
|
58
|
+
};
|
|
59
|
+
var SIZE_CLASSES = {
|
|
60
|
+
sm: "circle-menu-sm",
|
|
61
|
+
md: "",
|
|
62
|
+
lg: "circle-menu-lg"
|
|
63
|
+
};
|
|
64
|
+
var coreStyles = import_circle_menu.css.replace(/@layer\s+components\s*\{/, "").replace(/\}\s*$/, "");
|
|
65
|
+
var styles = import_el_base.css`
|
|
66
|
+
:host {
|
|
67
|
+
display: inline-flex;
|
|
68
|
+
vertical-align: middle;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
:host([hidden]) {
|
|
72
|
+
display: none !important;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
${coreStyles}
|
|
76
|
+
|
|
77
|
+
.circle-menu {
|
|
78
|
+
font-family: inherit;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* Hidden slot — items are cloned into the list */
|
|
82
|
+
.slot-holder {
|
|
83
|
+
display: none;
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
86
|
+
|
|
87
|
+
class ElDmCircleMenu extends import_el_base.BaseElement {
|
|
88
|
+
static properties = {
|
|
89
|
+
open: { type: Boolean, reflect: true, default: false },
|
|
90
|
+
color: { type: String, reflect: true },
|
|
91
|
+
size: { type: String, reflect: true }
|
|
92
|
+
};
|
|
93
|
+
#toggleId = `cm-${Math.random().toString(36).slice(2, 8)}`;
|
|
94
|
+
constructor() {
|
|
95
|
+
super();
|
|
96
|
+
this.attachStyles(styles);
|
|
97
|
+
}
|
|
98
|
+
_getContainerClasses() {
|
|
99
|
+
const classes = ["circle-menu"];
|
|
100
|
+
if (this.color && COLOR_CLASSES[this.color]) {
|
|
101
|
+
classes.push(COLOR_CLASSES[this.color]);
|
|
102
|
+
}
|
|
103
|
+
if (this.size && SIZE_CLASSES[this.size]) {
|
|
104
|
+
classes.push(SIZE_CLASSES[this.size]);
|
|
105
|
+
}
|
|
106
|
+
return classes.join(" ");
|
|
107
|
+
}
|
|
108
|
+
render() {
|
|
109
|
+
const classes = this._getContainerClasses();
|
|
110
|
+
return `
|
|
111
|
+
<nav class="${classes}" part="container">
|
|
112
|
+
<input
|
|
113
|
+
type="checkbox"
|
|
114
|
+
class="circle-menu-toggler"
|
|
115
|
+
id="${this.#toggleId}"
|
|
116
|
+
${this.open ? "checked" : ""}
|
|
117
|
+
aria-label="Toggle menu"
|
|
118
|
+
/>
|
|
119
|
+
<label class="circle-menu-label" for="${this.#toggleId}" part="toggle"></label>
|
|
120
|
+
<ul class="circle-menu-list" part="list" role="menu"></ul>
|
|
121
|
+
</nav>
|
|
122
|
+
<div class="slot-holder"><slot></slot></div>
|
|
123
|
+
`;
|
|
124
|
+
}
|
|
125
|
+
update() {
|
|
126
|
+
super.update();
|
|
127
|
+
this.#syncCheckbox();
|
|
128
|
+
this.#syncItems();
|
|
129
|
+
this.#attachToggleListener();
|
|
130
|
+
}
|
|
131
|
+
connectedCallback() {
|
|
132
|
+
super.connectedCallback();
|
|
133
|
+
const slot = this.shadowRoot?.querySelector("slot");
|
|
134
|
+
slot?.addEventListener("slotchange", () => this.#syncItems());
|
|
135
|
+
}
|
|
136
|
+
#syncCheckbox() {
|
|
137
|
+
const checkbox = this.shadowRoot?.querySelector(".circle-menu-toggler");
|
|
138
|
+
if (checkbox && checkbox.checked !== this.open) {
|
|
139
|
+
checkbox.checked = this.open;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
#syncItems() {
|
|
143
|
+
const list = this.shadowRoot?.querySelector(".circle-menu-list");
|
|
144
|
+
const slot = this.shadowRoot?.querySelector("slot");
|
|
145
|
+
if (!list || !slot)
|
|
146
|
+
return;
|
|
147
|
+
const assigned = slot.assignedElements();
|
|
148
|
+
list.innerHTML = "";
|
|
149
|
+
assigned.forEach((el) => {
|
|
150
|
+
const li = document.createElement("li");
|
|
151
|
+
li.className = "circle-menu-item";
|
|
152
|
+
li.setAttribute("role", "menuitem");
|
|
153
|
+
const clone = el.cloneNode(true);
|
|
154
|
+
li.appendChild(clone);
|
|
155
|
+
list.appendChild(li);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
#attachToggleListener() {
|
|
159
|
+
const checkbox = this.shadowRoot?.querySelector(".circle-menu-toggler");
|
|
160
|
+
if (!checkbox)
|
|
161
|
+
return;
|
|
162
|
+
checkbox.addEventListener("change", () => {
|
|
163
|
+
this.open = checkbox.checked;
|
|
164
|
+
this.emit("toggle", { open: this.open });
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
show() {
|
|
168
|
+
if (!this.open) {
|
|
169
|
+
this.open = true;
|
|
170
|
+
this.emit("toggle", { open: true });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
hide() {
|
|
174
|
+
if (this.open) {
|
|
175
|
+
this.open = false;
|
|
176
|
+
this.emit("toggle", { open: false });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
toggle() {
|
|
180
|
+
this.open = !this.open;
|
|
181
|
+
this.emit("toggle", { open: this.open });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/index.ts
|
|
186
|
+
function register() {
|
|
187
|
+
if (!customElements.get("el-dm-circle-menu")) {
|
|
188
|
+
customElements.define("el-dm-circle-menu", ElDmCircleMenu);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
//# debugId=3F91CAFC0F9EB74A64756E2164756E21
|
|
193
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/el-dm-circle-menu.ts", "../../src/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * DuskMoon Circle Menu Element\n *\n * A CSS-only radial circular navigation menu with hamburger/X toggle.\n * Items fan out in a circle when opened. Uses the checkbox toggle pattern\n * from @duskmoon-dev/core internally.\n *\n * @element el-dm-circle-menu\n *\n * @attr {boolean} open - Whether the menu is expanded\n * @attr {string} color - Color variant: primary, secondary, tertiary, info, success, warning, error\n * @attr {string} size - Size: sm, md, lg\n *\n * @slot - Default slot for menu items (a or button elements)\n *\n * @csspart container - The outer circle-menu container\n * @csspart toggle - The toggle label element\n * @csspart list - The menu items list\n *\n * @fires toggle - Fired when the menu opens or closes (detail: { open: boolean })\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-base';\nimport { css as circleMenuCSS } from '@duskmoon-dev/core/components/circle-menu';\n\nconst COLOR_CLASSES: Record<string, string> = {\n primary: 'circle-menu-primary',\n secondary: 'circle-menu-secondary',\n tertiary: 'circle-menu-tertiary',\n info: 'circle-menu-info',\n success: 'circle-menu-success',\n warning: 'circle-menu-warning',\n error: 'circle-menu-error',\n};\n\nconst SIZE_CLASSES: Record<string, string> = {\n sm: 'circle-menu-sm',\n md: '',\n lg: 'circle-menu-lg',\n};\n\nexport type CircleMenuColor =\n | 'primary'\n | 'secondary'\n | 'tertiary'\n | 'info'\n | 'success'\n | 'warning'\n | 'error';\nexport type CircleMenuSize = 'sm' | 'md' | 'lg';\n\n// Strip @layer wrapper for Shadow DOM compatibility\nconst coreStyles = circleMenuCSS\n .replace(/@layer\\s+components\\s*\\{/, '')\n .replace(/\\}\\s*$/, '');\n\nconst styles = css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n ${coreStyles}\n\n .circle-menu {\n font-family: inherit;\n }\n\n /* Hidden slot — items are cloned into the list */\n .slot-holder {\n display: none;\n }\n`;\n\nexport class ElDmCircleMenu extends BaseElement {\n static properties = {\n open: { type: Boolean, reflect: true, default: false },\n color: { type: String, reflect: true },\n size: { type: String, reflect: true },\n };\n\n declare open: boolean;\n declare color: CircleMenuColor;\n declare size: CircleMenuSize;\n\n #toggleId = `cm-${Math.random().toString(36).slice(2, 8)}`;\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n private _getContainerClasses(): string {\n const classes = ['circle-menu'];\n\n if (this.color && COLOR_CLASSES[this.color]) {\n classes.push(COLOR_CLASSES[this.color]);\n }\n\n if (this.size && SIZE_CLASSES[this.size]) {\n classes.push(SIZE_CLASSES[this.size]);\n }\n\n return classes.join(' ');\n }\n\n render(): string {\n const classes = this._getContainerClasses();\n return `\n <nav class=\"${classes}\" part=\"container\">\n <input\n type=\"checkbox\"\n class=\"circle-menu-toggler\"\n id=\"${this.#toggleId}\"\n ${this.open ? 'checked' : ''}\n aria-label=\"Toggle menu\"\n />\n <label class=\"circle-menu-label\" for=\"${this.#toggleId}\" part=\"toggle\"></label>\n <ul class=\"circle-menu-list\" part=\"list\" role=\"menu\"></ul>\n </nav>\n <div class=\"slot-holder\"><slot></slot></div>\n `;\n }\n\n update(): void {\n super.update();\n this.#syncCheckbox();\n this.#syncItems();\n this.#attachToggleListener();\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n\n const slot = this.shadowRoot?.querySelector('slot');\n slot?.addEventListener('slotchange', () => this.#syncItems());\n }\n\n #syncCheckbox(): void {\n const checkbox = this.shadowRoot?.querySelector(\n '.circle-menu-toggler',\n ) as HTMLInputElement | null;\n if (checkbox && checkbox.checked !== this.open) {\n checkbox.checked = this.open;\n }\n }\n\n #syncItems(): void {\n const list = this.shadowRoot?.querySelector('.circle-menu-list');\n const slot = this.shadowRoot?.querySelector('slot');\n if (!list || !slot) return;\n\n const assigned = slot.assignedElements();\n list.innerHTML = '';\n\n assigned.forEach((el) => {\n const li = document.createElement('li');\n li.className = 'circle-menu-item';\n li.setAttribute('role', 'menuitem');\n const clone = el.cloneNode(true) as HTMLElement;\n li.appendChild(clone);\n list.appendChild(li);\n });\n }\n\n #attachToggleListener(): void {\n const checkbox = this.shadowRoot?.querySelector(\n '.circle-menu-toggler',\n ) as HTMLInputElement | null;\n if (!checkbox) return;\n\n checkbox.addEventListener('change', () => {\n this.open = checkbox.checked;\n this.emit('toggle', { open: this.open });\n });\n }\n\n /**\n * Show the menu\n */\n show(): void {\n if (!this.open) {\n this.open = true;\n this.emit('toggle', { open: true });\n }\n }\n\n /**\n * Hide the menu\n */\n hide(): void {\n if (this.open) {\n this.open = false;\n this.emit('toggle', { open: false });\n }\n }\n\n /**\n * Toggle the menu open/closed\n */\n toggle(): void {\n this.open = !this.open;\n this.emit('toggle', { open: this.open });\n }\n}\n",
|
|
6
|
+
"/**\n * @duskmoon-dev/el-circle-menu\n *\n * DuskMoon Circle Menu custom element — a radial navigation menu\n */\n\nimport { ElDmCircleMenu } from './el-dm-circle-menu.js';\n\nexport { ElDmCircleMenu };\nexport type { CircleMenuColor, CircleMenuSize } from './el-dm-circle-menu.js';\n\n/**\n * Register the el-dm-circle-menu custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-circle-menu';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-circle-menu')) {\n customElements.define('el-dm-circle-menu', ElDmCircleMenu);\n }\n}\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "3F91CAFC0F9EB74A64756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
function __accessProp(key) {
|
|
6
|
+
return this[key];
|
|
7
|
+
}
|
|
8
|
+
var __toCommonJS = (from) => {
|
|
9
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
10
|
+
if (entry)
|
|
11
|
+
return entry;
|
|
12
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (var key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(entry, key))
|
|
16
|
+
__defProp(entry, key, {
|
|
17
|
+
get: __accessProp.bind(from, key),
|
|
18
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
__moduleCache.set(from, entry);
|
|
22
|
+
return entry;
|
|
23
|
+
};
|
|
24
|
+
var __moduleCache;
|
|
25
|
+
var __returnValue = (v) => v;
|
|
26
|
+
function __exportSetter(name, newValue) {
|
|
27
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
28
|
+
}
|
|
29
|
+
var __export = (target, all) => {
|
|
30
|
+
for (var name in all)
|
|
31
|
+
__defProp(target, name, {
|
|
32
|
+
get: all[name],
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
set: __exportSetter.bind(all, name)
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/index.ts
|
|
40
|
+
var exports_src = {};
|
|
41
|
+
__export(exports_src, {
|
|
42
|
+
register: () => register,
|
|
43
|
+
ElDmCircleMenu: () => ElDmCircleMenu
|
|
44
|
+
});
|
|
45
|
+
module.exports = __toCommonJS(exports_src);
|
|
46
|
+
|
|
47
|
+
// src/el-dm-circle-menu.ts
|
|
48
|
+
var import_el_base = require("@duskmoon-dev/el-base");
|
|
49
|
+
var import_circle_menu = require("@duskmoon-dev/core/components/circle-menu");
|
|
50
|
+
var COLOR_CLASSES = {
|
|
51
|
+
primary: "circle-menu-primary",
|
|
52
|
+
secondary: "circle-menu-secondary",
|
|
53
|
+
tertiary: "circle-menu-tertiary",
|
|
54
|
+
info: "circle-menu-info",
|
|
55
|
+
success: "circle-menu-success",
|
|
56
|
+
warning: "circle-menu-warning",
|
|
57
|
+
error: "circle-menu-error"
|
|
58
|
+
};
|
|
59
|
+
var SIZE_CLASSES = {
|
|
60
|
+
sm: "circle-menu-sm",
|
|
61
|
+
md: "",
|
|
62
|
+
lg: "circle-menu-lg"
|
|
63
|
+
};
|
|
64
|
+
var coreStyles = import_circle_menu.css.replace(/@layer\s+components\s*\{/, "").replace(/\}\s*$/, "");
|
|
65
|
+
var styles = import_el_base.css`
|
|
66
|
+
:host {
|
|
67
|
+
display: inline-flex;
|
|
68
|
+
vertical-align: middle;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
:host([hidden]) {
|
|
72
|
+
display: none !important;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
${coreStyles}
|
|
76
|
+
|
|
77
|
+
.circle-menu {
|
|
78
|
+
font-family: inherit;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* Hidden slot — items are cloned into the list */
|
|
82
|
+
.slot-holder {
|
|
83
|
+
display: none;
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
86
|
+
|
|
87
|
+
class ElDmCircleMenu extends import_el_base.BaseElement {
|
|
88
|
+
static properties = {
|
|
89
|
+
open: { type: Boolean, reflect: true, default: false },
|
|
90
|
+
color: { type: String, reflect: true },
|
|
91
|
+
size: { type: String, reflect: true }
|
|
92
|
+
};
|
|
93
|
+
#toggleId = `cm-${Math.random().toString(36).slice(2, 8)}`;
|
|
94
|
+
constructor() {
|
|
95
|
+
super();
|
|
96
|
+
this.attachStyles(styles);
|
|
97
|
+
}
|
|
98
|
+
_getContainerClasses() {
|
|
99
|
+
const classes = ["circle-menu"];
|
|
100
|
+
if (this.color && COLOR_CLASSES[this.color]) {
|
|
101
|
+
classes.push(COLOR_CLASSES[this.color]);
|
|
102
|
+
}
|
|
103
|
+
if (this.size && SIZE_CLASSES[this.size]) {
|
|
104
|
+
classes.push(SIZE_CLASSES[this.size]);
|
|
105
|
+
}
|
|
106
|
+
return classes.join(" ");
|
|
107
|
+
}
|
|
108
|
+
render() {
|
|
109
|
+
const classes = this._getContainerClasses();
|
|
110
|
+
return `
|
|
111
|
+
<nav class="${classes}" part="container">
|
|
112
|
+
<input
|
|
113
|
+
type="checkbox"
|
|
114
|
+
class="circle-menu-toggler"
|
|
115
|
+
id="${this.#toggleId}"
|
|
116
|
+
${this.open ? "checked" : ""}
|
|
117
|
+
aria-label="Toggle menu"
|
|
118
|
+
/>
|
|
119
|
+
<label class="circle-menu-label" for="${this.#toggleId}" part="toggle"></label>
|
|
120
|
+
<ul class="circle-menu-list" part="list" role="menu"></ul>
|
|
121
|
+
</nav>
|
|
122
|
+
<div class="slot-holder"><slot></slot></div>
|
|
123
|
+
`;
|
|
124
|
+
}
|
|
125
|
+
update() {
|
|
126
|
+
super.update();
|
|
127
|
+
this.#syncCheckbox();
|
|
128
|
+
this.#syncItems();
|
|
129
|
+
this.#attachToggleListener();
|
|
130
|
+
}
|
|
131
|
+
connectedCallback() {
|
|
132
|
+
super.connectedCallback();
|
|
133
|
+
const slot = this.shadowRoot?.querySelector("slot");
|
|
134
|
+
slot?.addEventListener("slotchange", () => this.#syncItems());
|
|
135
|
+
}
|
|
136
|
+
#syncCheckbox() {
|
|
137
|
+
const checkbox = this.shadowRoot?.querySelector(".circle-menu-toggler");
|
|
138
|
+
if (checkbox && checkbox.checked !== this.open) {
|
|
139
|
+
checkbox.checked = this.open;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
#syncItems() {
|
|
143
|
+
const list = this.shadowRoot?.querySelector(".circle-menu-list");
|
|
144
|
+
const slot = this.shadowRoot?.querySelector("slot");
|
|
145
|
+
if (!list || !slot)
|
|
146
|
+
return;
|
|
147
|
+
const assigned = slot.assignedElements();
|
|
148
|
+
list.innerHTML = "";
|
|
149
|
+
assigned.forEach((el) => {
|
|
150
|
+
const li = document.createElement("li");
|
|
151
|
+
li.className = "circle-menu-item";
|
|
152
|
+
li.setAttribute("role", "menuitem");
|
|
153
|
+
const clone = el.cloneNode(true);
|
|
154
|
+
li.appendChild(clone);
|
|
155
|
+
list.appendChild(li);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
#attachToggleListener() {
|
|
159
|
+
const checkbox = this.shadowRoot?.querySelector(".circle-menu-toggler");
|
|
160
|
+
if (!checkbox)
|
|
161
|
+
return;
|
|
162
|
+
checkbox.addEventListener("change", () => {
|
|
163
|
+
this.open = checkbox.checked;
|
|
164
|
+
this.emit("toggle", { open: this.open });
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
show() {
|
|
168
|
+
if (!this.open) {
|
|
169
|
+
this.open = true;
|
|
170
|
+
this.emit("toggle", { open: true });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
hide() {
|
|
174
|
+
if (this.open) {
|
|
175
|
+
this.open = false;
|
|
176
|
+
this.emit("toggle", { open: false });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
toggle() {
|
|
180
|
+
this.open = !this.open;
|
|
181
|
+
this.emit("toggle", { open: this.open });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/index.ts
|
|
186
|
+
function register() {
|
|
187
|
+
if (!customElements.get("el-dm-circle-menu")) {
|
|
188
|
+
customElements.define("el-dm-circle-menu", ElDmCircleMenu);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// src/register.ts
|
|
193
|
+
register();
|
|
194
|
+
|
|
195
|
+
//# debugId=529D599C86C02C5264756E2164756E21
|
|
196
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/el-dm-circle-menu.ts", "../../src/index.ts", "../../src/register.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * DuskMoon Circle Menu Element\n *\n * A CSS-only radial circular navigation menu with hamburger/X toggle.\n * Items fan out in a circle when opened. Uses the checkbox toggle pattern\n * from @duskmoon-dev/core internally.\n *\n * @element el-dm-circle-menu\n *\n * @attr {boolean} open - Whether the menu is expanded\n * @attr {string} color - Color variant: primary, secondary, tertiary, info, success, warning, error\n * @attr {string} size - Size: sm, md, lg\n *\n * @slot - Default slot for menu items (a or button elements)\n *\n * @csspart container - The outer circle-menu container\n * @csspart toggle - The toggle label element\n * @csspart list - The menu items list\n *\n * @fires toggle - Fired when the menu opens or closes (detail: { open: boolean })\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-base';\nimport { css as circleMenuCSS } from '@duskmoon-dev/core/components/circle-menu';\n\nconst COLOR_CLASSES: Record<string, string> = {\n primary: 'circle-menu-primary',\n secondary: 'circle-menu-secondary',\n tertiary: 'circle-menu-tertiary',\n info: 'circle-menu-info',\n success: 'circle-menu-success',\n warning: 'circle-menu-warning',\n error: 'circle-menu-error',\n};\n\nconst SIZE_CLASSES: Record<string, string> = {\n sm: 'circle-menu-sm',\n md: '',\n lg: 'circle-menu-lg',\n};\n\nexport type CircleMenuColor =\n | 'primary'\n | 'secondary'\n | 'tertiary'\n | 'info'\n | 'success'\n | 'warning'\n | 'error';\nexport type CircleMenuSize = 'sm' | 'md' | 'lg';\n\n// Strip @layer wrapper for Shadow DOM compatibility\nconst coreStyles = circleMenuCSS\n .replace(/@layer\\s+components\\s*\\{/, '')\n .replace(/\\}\\s*$/, '');\n\nconst styles = css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n ${coreStyles}\n\n .circle-menu {\n font-family: inherit;\n }\n\n /* Hidden slot — items are cloned into the list */\n .slot-holder {\n display: none;\n }\n`;\n\nexport class ElDmCircleMenu extends BaseElement {\n static properties = {\n open: { type: Boolean, reflect: true, default: false },\n color: { type: String, reflect: true },\n size: { type: String, reflect: true },\n };\n\n declare open: boolean;\n declare color: CircleMenuColor;\n declare size: CircleMenuSize;\n\n #toggleId = `cm-${Math.random().toString(36).slice(2, 8)}`;\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n private _getContainerClasses(): string {\n const classes = ['circle-menu'];\n\n if (this.color && COLOR_CLASSES[this.color]) {\n classes.push(COLOR_CLASSES[this.color]);\n }\n\n if (this.size && SIZE_CLASSES[this.size]) {\n classes.push(SIZE_CLASSES[this.size]);\n }\n\n return classes.join(' ');\n }\n\n render(): string {\n const classes = this._getContainerClasses();\n return `\n <nav class=\"${classes}\" part=\"container\">\n <input\n type=\"checkbox\"\n class=\"circle-menu-toggler\"\n id=\"${this.#toggleId}\"\n ${this.open ? 'checked' : ''}\n aria-label=\"Toggle menu\"\n />\n <label class=\"circle-menu-label\" for=\"${this.#toggleId}\" part=\"toggle\"></label>\n <ul class=\"circle-menu-list\" part=\"list\" role=\"menu\"></ul>\n </nav>\n <div class=\"slot-holder\"><slot></slot></div>\n `;\n }\n\n update(): void {\n super.update();\n this.#syncCheckbox();\n this.#syncItems();\n this.#attachToggleListener();\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n\n const slot = this.shadowRoot?.querySelector('slot');\n slot?.addEventListener('slotchange', () => this.#syncItems());\n }\n\n #syncCheckbox(): void {\n const checkbox = this.shadowRoot?.querySelector(\n '.circle-menu-toggler',\n ) as HTMLInputElement | null;\n if (checkbox && checkbox.checked !== this.open) {\n checkbox.checked = this.open;\n }\n }\n\n #syncItems(): void {\n const list = this.shadowRoot?.querySelector('.circle-menu-list');\n const slot = this.shadowRoot?.querySelector('slot');\n if (!list || !slot) return;\n\n const assigned = slot.assignedElements();\n list.innerHTML = '';\n\n assigned.forEach((el) => {\n const li = document.createElement('li');\n li.className = 'circle-menu-item';\n li.setAttribute('role', 'menuitem');\n const clone = el.cloneNode(true) as HTMLElement;\n li.appendChild(clone);\n list.appendChild(li);\n });\n }\n\n #attachToggleListener(): void {\n const checkbox = this.shadowRoot?.querySelector(\n '.circle-menu-toggler',\n ) as HTMLInputElement | null;\n if (!checkbox) return;\n\n checkbox.addEventListener('change', () => {\n this.open = checkbox.checked;\n this.emit('toggle', { open: this.open });\n });\n }\n\n /**\n * Show the menu\n */\n show(): void {\n if (!this.open) {\n this.open = true;\n this.emit('toggle', { open: true });\n }\n }\n\n /**\n * Hide the menu\n */\n hide(): void {\n if (this.open) {\n this.open = false;\n this.emit('toggle', { open: false });\n }\n }\n\n /**\n * Toggle the menu open/closed\n */\n toggle(): void {\n this.open = !this.open;\n this.emit('toggle', { open: this.open });\n }\n}\n",
|
|
6
|
+
"/**\n * @duskmoon-dev/el-circle-menu\n *\n * DuskMoon Circle Menu custom element — a radial navigation menu\n */\n\nimport { ElDmCircleMenu } from './el-dm-circle-menu.js';\n\nexport { ElDmCircleMenu };\nexport type { CircleMenuColor, CircleMenuSize } from './el-dm-circle-menu.js';\n\n/**\n * Register the el-dm-circle-menu custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-circle-menu';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-circle-menu')) {\n customElements.define('el-dm-circle-menu', ElDmCircleMenu);\n }\n}\n",
|
|
7
|
+
"import { register } from './index.js';\nregister();\n"
|
|
8
|
+
],
|
|
9
|
+
"mappings": "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",
|
|
10
|
+
"debugId": "529D599C86C02C5264756E2164756E21",
|
|
11
|
+
"names": []
|
|
12
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// src/el-dm-circle-menu.ts
|
|
2
|
+
import { BaseElement, css } from "@duskmoon-dev/el-base";
|
|
3
|
+
import { css as circleMenuCSS } from "@duskmoon-dev/core/components/circle-menu";
|
|
4
|
+
var COLOR_CLASSES = {
|
|
5
|
+
primary: "circle-menu-primary",
|
|
6
|
+
secondary: "circle-menu-secondary",
|
|
7
|
+
tertiary: "circle-menu-tertiary",
|
|
8
|
+
info: "circle-menu-info",
|
|
9
|
+
success: "circle-menu-success",
|
|
10
|
+
warning: "circle-menu-warning",
|
|
11
|
+
error: "circle-menu-error"
|
|
12
|
+
};
|
|
13
|
+
var SIZE_CLASSES = {
|
|
14
|
+
sm: "circle-menu-sm",
|
|
15
|
+
md: "",
|
|
16
|
+
lg: "circle-menu-lg"
|
|
17
|
+
};
|
|
18
|
+
var coreStyles = circleMenuCSS.replace(/@layer\s+components\s*\{/, "").replace(/\}\s*$/, "");
|
|
19
|
+
var styles = css`
|
|
20
|
+
:host {
|
|
21
|
+
display: inline-flex;
|
|
22
|
+
vertical-align: middle;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
:host([hidden]) {
|
|
26
|
+
display: none !important;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
${coreStyles}
|
|
30
|
+
|
|
31
|
+
.circle-menu {
|
|
32
|
+
font-family: inherit;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* Hidden slot — items are cloned into the list */
|
|
36
|
+
.slot-holder {
|
|
37
|
+
display: none;
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
class ElDmCircleMenu extends BaseElement {
|
|
42
|
+
static properties = {
|
|
43
|
+
open: { type: Boolean, reflect: true, default: false },
|
|
44
|
+
color: { type: String, reflect: true },
|
|
45
|
+
size: { type: String, reflect: true }
|
|
46
|
+
};
|
|
47
|
+
#toggleId = `cm-${Math.random().toString(36).slice(2, 8)}`;
|
|
48
|
+
constructor() {
|
|
49
|
+
super();
|
|
50
|
+
this.attachStyles(styles);
|
|
51
|
+
}
|
|
52
|
+
_getContainerClasses() {
|
|
53
|
+
const classes = ["circle-menu"];
|
|
54
|
+
if (this.color && COLOR_CLASSES[this.color]) {
|
|
55
|
+
classes.push(COLOR_CLASSES[this.color]);
|
|
56
|
+
}
|
|
57
|
+
if (this.size && SIZE_CLASSES[this.size]) {
|
|
58
|
+
classes.push(SIZE_CLASSES[this.size]);
|
|
59
|
+
}
|
|
60
|
+
return classes.join(" ");
|
|
61
|
+
}
|
|
62
|
+
render() {
|
|
63
|
+
const classes = this._getContainerClasses();
|
|
64
|
+
return `
|
|
65
|
+
<nav class="${classes}" part="container">
|
|
66
|
+
<input
|
|
67
|
+
type="checkbox"
|
|
68
|
+
class="circle-menu-toggler"
|
|
69
|
+
id="${this.#toggleId}"
|
|
70
|
+
${this.open ? "checked" : ""}
|
|
71
|
+
aria-label="Toggle menu"
|
|
72
|
+
/>
|
|
73
|
+
<label class="circle-menu-label" for="${this.#toggleId}" part="toggle"></label>
|
|
74
|
+
<ul class="circle-menu-list" part="list" role="menu"></ul>
|
|
75
|
+
</nav>
|
|
76
|
+
<div class="slot-holder"><slot></slot></div>
|
|
77
|
+
`;
|
|
78
|
+
}
|
|
79
|
+
update() {
|
|
80
|
+
super.update();
|
|
81
|
+
this.#syncCheckbox();
|
|
82
|
+
this.#syncItems();
|
|
83
|
+
this.#attachToggleListener();
|
|
84
|
+
}
|
|
85
|
+
connectedCallback() {
|
|
86
|
+
super.connectedCallback();
|
|
87
|
+
const slot = this.shadowRoot?.querySelector("slot");
|
|
88
|
+
slot?.addEventListener("slotchange", () => this.#syncItems());
|
|
89
|
+
}
|
|
90
|
+
#syncCheckbox() {
|
|
91
|
+
const checkbox = this.shadowRoot?.querySelector(".circle-menu-toggler");
|
|
92
|
+
if (checkbox && checkbox.checked !== this.open) {
|
|
93
|
+
checkbox.checked = this.open;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
#syncItems() {
|
|
97
|
+
const list = this.shadowRoot?.querySelector(".circle-menu-list");
|
|
98
|
+
const slot = this.shadowRoot?.querySelector("slot");
|
|
99
|
+
if (!list || !slot)
|
|
100
|
+
return;
|
|
101
|
+
const assigned = slot.assignedElements();
|
|
102
|
+
list.innerHTML = "";
|
|
103
|
+
assigned.forEach((el) => {
|
|
104
|
+
const li = document.createElement("li");
|
|
105
|
+
li.className = "circle-menu-item";
|
|
106
|
+
li.setAttribute("role", "menuitem");
|
|
107
|
+
const clone = el.cloneNode(true);
|
|
108
|
+
li.appendChild(clone);
|
|
109
|
+
list.appendChild(li);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
#attachToggleListener() {
|
|
113
|
+
const checkbox = this.shadowRoot?.querySelector(".circle-menu-toggler");
|
|
114
|
+
if (!checkbox)
|
|
115
|
+
return;
|
|
116
|
+
checkbox.addEventListener("change", () => {
|
|
117
|
+
this.open = checkbox.checked;
|
|
118
|
+
this.emit("toggle", { open: this.open });
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
show() {
|
|
122
|
+
if (!this.open) {
|
|
123
|
+
this.open = true;
|
|
124
|
+
this.emit("toggle", { open: true });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
hide() {
|
|
128
|
+
if (this.open) {
|
|
129
|
+
this.open = false;
|
|
130
|
+
this.emit("toggle", { open: false });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
toggle() {
|
|
134
|
+
this.open = !this.open;
|
|
135
|
+
this.emit("toggle", { open: this.open });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/index.ts
|
|
140
|
+
function register() {
|
|
141
|
+
if (!customElements.get("el-dm-circle-menu")) {
|
|
142
|
+
customElements.define("el-dm-circle-menu", ElDmCircleMenu);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
export {
|
|
146
|
+
register,
|
|
147
|
+
ElDmCircleMenu
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
//# debugId=2CE0B8F86A8FDDBE64756E2164756E21
|
|
151
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/el-dm-circle-menu.ts", "../../src/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * DuskMoon Circle Menu Element\n *\n * A CSS-only radial circular navigation menu with hamburger/X toggle.\n * Items fan out in a circle when opened. Uses the checkbox toggle pattern\n * from @duskmoon-dev/core internally.\n *\n * @element el-dm-circle-menu\n *\n * @attr {boolean} open - Whether the menu is expanded\n * @attr {string} color - Color variant: primary, secondary, tertiary, info, success, warning, error\n * @attr {string} size - Size: sm, md, lg\n *\n * @slot - Default slot for menu items (a or button elements)\n *\n * @csspart container - The outer circle-menu container\n * @csspart toggle - The toggle label element\n * @csspart list - The menu items list\n *\n * @fires toggle - Fired when the menu opens or closes (detail: { open: boolean })\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-base';\nimport { css as circleMenuCSS } from '@duskmoon-dev/core/components/circle-menu';\n\nconst COLOR_CLASSES: Record<string, string> = {\n primary: 'circle-menu-primary',\n secondary: 'circle-menu-secondary',\n tertiary: 'circle-menu-tertiary',\n info: 'circle-menu-info',\n success: 'circle-menu-success',\n warning: 'circle-menu-warning',\n error: 'circle-menu-error',\n};\n\nconst SIZE_CLASSES: Record<string, string> = {\n sm: 'circle-menu-sm',\n md: '',\n lg: 'circle-menu-lg',\n};\n\nexport type CircleMenuColor =\n | 'primary'\n | 'secondary'\n | 'tertiary'\n | 'info'\n | 'success'\n | 'warning'\n | 'error';\nexport type CircleMenuSize = 'sm' | 'md' | 'lg';\n\n// Strip @layer wrapper for Shadow DOM compatibility\nconst coreStyles = circleMenuCSS\n .replace(/@layer\\s+components\\s*\\{/, '')\n .replace(/\\}\\s*$/, '');\n\nconst styles = css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n ${coreStyles}\n\n .circle-menu {\n font-family: inherit;\n }\n\n /* Hidden slot — items are cloned into the list */\n .slot-holder {\n display: none;\n }\n`;\n\nexport class ElDmCircleMenu extends BaseElement {\n static properties = {\n open: { type: Boolean, reflect: true, default: false },\n color: { type: String, reflect: true },\n size: { type: String, reflect: true },\n };\n\n declare open: boolean;\n declare color: CircleMenuColor;\n declare size: CircleMenuSize;\n\n #toggleId = `cm-${Math.random().toString(36).slice(2, 8)}`;\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n private _getContainerClasses(): string {\n const classes = ['circle-menu'];\n\n if (this.color && COLOR_CLASSES[this.color]) {\n classes.push(COLOR_CLASSES[this.color]);\n }\n\n if (this.size && SIZE_CLASSES[this.size]) {\n classes.push(SIZE_CLASSES[this.size]);\n }\n\n return classes.join(' ');\n }\n\n render(): string {\n const classes = this._getContainerClasses();\n return `\n <nav class=\"${classes}\" part=\"container\">\n <input\n type=\"checkbox\"\n class=\"circle-menu-toggler\"\n id=\"${this.#toggleId}\"\n ${this.open ? 'checked' : ''}\n aria-label=\"Toggle menu\"\n />\n <label class=\"circle-menu-label\" for=\"${this.#toggleId}\" part=\"toggle\"></label>\n <ul class=\"circle-menu-list\" part=\"list\" role=\"menu\"></ul>\n </nav>\n <div class=\"slot-holder\"><slot></slot></div>\n `;\n }\n\n update(): void {\n super.update();\n this.#syncCheckbox();\n this.#syncItems();\n this.#attachToggleListener();\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n\n const slot = this.shadowRoot?.querySelector('slot');\n slot?.addEventListener('slotchange', () => this.#syncItems());\n }\n\n #syncCheckbox(): void {\n const checkbox = this.shadowRoot?.querySelector(\n '.circle-menu-toggler',\n ) as HTMLInputElement | null;\n if (checkbox && checkbox.checked !== this.open) {\n checkbox.checked = this.open;\n }\n }\n\n #syncItems(): void {\n const list = this.shadowRoot?.querySelector('.circle-menu-list');\n const slot = this.shadowRoot?.querySelector('slot');\n if (!list || !slot) return;\n\n const assigned = slot.assignedElements();\n list.innerHTML = '';\n\n assigned.forEach((el) => {\n const li = document.createElement('li');\n li.className = 'circle-menu-item';\n li.setAttribute('role', 'menuitem');\n const clone = el.cloneNode(true) as HTMLElement;\n li.appendChild(clone);\n list.appendChild(li);\n });\n }\n\n #attachToggleListener(): void {\n const checkbox = this.shadowRoot?.querySelector(\n '.circle-menu-toggler',\n ) as HTMLInputElement | null;\n if (!checkbox) return;\n\n checkbox.addEventListener('change', () => {\n this.open = checkbox.checked;\n this.emit('toggle', { open: this.open });\n });\n }\n\n /**\n * Show the menu\n */\n show(): void {\n if (!this.open) {\n this.open = true;\n this.emit('toggle', { open: true });\n }\n }\n\n /**\n * Hide the menu\n */\n hide(): void {\n if (this.open) {\n this.open = false;\n this.emit('toggle', { open: false });\n }\n }\n\n /**\n * Toggle the menu open/closed\n */\n toggle(): void {\n this.open = !this.open;\n this.emit('toggle', { open: this.open });\n }\n}\n",
|
|
6
|
+
"/**\n * @duskmoon-dev/el-circle-menu\n *\n * DuskMoon Circle Menu custom element — a radial navigation menu\n */\n\nimport { ElDmCircleMenu } from './el-dm-circle-menu.js';\n\nexport { ElDmCircleMenu };\nexport type { CircleMenuColor, CircleMenuSize } from './el-dm-circle-menu.js';\n\n/**\n * Register the el-dm-circle-menu custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-circle-menu';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-circle-menu')) {\n customElements.define('el-dm-circle-menu', ElDmCircleMenu);\n }\n}\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "2CE0B8F86A8FDDBE64756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// src/el-dm-circle-menu.ts
|
|
2
|
+
import { BaseElement, css } from "@duskmoon-dev/el-base";
|
|
3
|
+
import { css as circleMenuCSS } from "@duskmoon-dev/core/components/circle-menu";
|
|
4
|
+
var COLOR_CLASSES = {
|
|
5
|
+
primary: "circle-menu-primary",
|
|
6
|
+
secondary: "circle-menu-secondary",
|
|
7
|
+
tertiary: "circle-menu-tertiary",
|
|
8
|
+
info: "circle-menu-info",
|
|
9
|
+
success: "circle-menu-success",
|
|
10
|
+
warning: "circle-menu-warning",
|
|
11
|
+
error: "circle-menu-error"
|
|
12
|
+
};
|
|
13
|
+
var SIZE_CLASSES = {
|
|
14
|
+
sm: "circle-menu-sm",
|
|
15
|
+
md: "",
|
|
16
|
+
lg: "circle-menu-lg"
|
|
17
|
+
};
|
|
18
|
+
var coreStyles = circleMenuCSS.replace(/@layer\s+components\s*\{/, "").replace(/\}\s*$/, "");
|
|
19
|
+
var styles = css`
|
|
20
|
+
:host {
|
|
21
|
+
display: inline-flex;
|
|
22
|
+
vertical-align: middle;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
:host([hidden]) {
|
|
26
|
+
display: none !important;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
${coreStyles}
|
|
30
|
+
|
|
31
|
+
.circle-menu {
|
|
32
|
+
font-family: inherit;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* Hidden slot — items are cloned into the list */
|
|
36
|
+
.slot-holder {
|
|
37
|
+
display: none;
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
class ElDmCircleMenu extends BaseElement {
|
|
42
|
+
static properties = {
|
|
43
|
+
open: { type: Boolean, reflect: true, default: false },
|
|
44
|
+
color: { type: String, reflect: true },
|
|
45
|
+
size: { type: String, reflect: true }
|
|
46
|
+
};
|
|
47
|
+
#toggleId = `cm-${Math.random().toString(36).slice(2, 8)}`;
|
|
48
|
+
constructor() {
|
|
49
|
+
super();
|
|
50
|
+
this.attachStyles(styles);
|
|
51
|
+
}
|
|
52
|
+
_getContainerClasses() {
|
|
53
|
+
const classes = ["circle-menu"];
|
|
54
|
+
if (this.color && COLOR_CLASSES[this.color]) {
|
|
55
|
+
classes.push(COLOR_CLASSES[this.color]);
|
|
56
|
+
}
|
|
57
|
+
if (this.size && SIZE_CLASSES[this.size]) {
|
|
58
|
+
classes.push(SIZE_CLASSES[this.size]);
|
|
59
|
+
}
|
|
60
|
+
return classes.join(" ");
|
|
61
|
+
}
|
|
62
|
+
render() {
|
|
63
|
+
const classes = this._getContainerClasses();
|
|
64
|
+
return `
|
|
65
|
+
<nav class="${classes}" part="container">
|
|
66
|
+
<input
|
|
67
|
+
type="checkbox"
|
|
68
|
+
class="circle-menu-toggler"
|
|
69
|
+
id="${this.#toggleId}"
|
|
70
|
+
${this.open ? "checked" : ""}
|
|
71
|
+
aria-label="Toggle menu"
|
|
72
|
+
/>
|
|
73
|
+
<label class="circle-menu-label" for="${this.#toggleId}" part="toggle"></label>
|
|
74
|
+
<ul class="circle-menu-list" part="list" role="menu"></ul>
|
|
75
|
+
</nav>
|
|
76
|
+
<div class="slot-holder"><slot></slot></div>
|
|
77
|
+
`;
|
|
78
|
+
}
|
|
79
|
+
update() {
|
|
80
|
+
super.update();
|
|
81
|
+
this.#syncCheckbox();
|
|
82
|
+
this.#syncItems();
|
|
83
|
+
this.#attachToggleListener();
|
|
84
|
+
}
|
|
85
|
+
connectedCallback() {
|
|
86
|
+
super.connectedCallback();
|
|
87
|
+
const slot = this.shadowRoot?.querySelector("slot");
|
|
88
|
+
slot?.addEventListener("slotchange", () => this.#syncItems());
|
|
89
|
+
}
|
|
90
|
+
#syncCheckbox() {
|
|
91
|
+
const checkbox = this.shadowRoot?.querySelector(".circle-menu-toggler");
|
|
92
|
+
if (checkbox && checkbox.checked !== this.open) {
|
|
93
|
+
checkbox.checked = this.open;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
#syncItems() {
|
|
97
|
+
const list = this.shadowRoot?.querySelector(".circle-menu-list");
|
|
98
|
+
const slot = this.shadowRoot?.querySelector("slot");
|
|
99
|
+
if (!list || !slot)
|
|
100
|
+
return;
|
|
101
|
+
const assigned = slot.assignedElements();
|
|
102
|
+
list.innerHTML = "";
|
|
103
|
+
assigned.forEach((el) => {
|
|
104
|
+
const li = document.createElement("li");
|
|
105
|
+
li.className = "circle-menu-item";
|
|
106
|
+
li.setAttribute("role", "menuitem");
|
|
107
|
+
const clone = el.cloneNode(true);
|
|
108
|
+
li.appendChild(clone);
|
|
109
|
+
list.appendChild(li);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
#attachToggleListener() {
|
|
113
|
+
const checkbox = this.shadowRoot?.querySelector(".circle-menu-toggler");
|
|
114
|
+
if (!checkbox)
|
|
115
|
+
return;
|
|
116
|
+
checkbox.addEventListener("change", () => {
|
|
117
|
+
this.open = checkbox.checked;
|
|
118
|
+
this.emit("toggle", { open: this.open });
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
show() {
|
|
122
|
+
if (!this.open) {
|
|
123
|
+
this.open = true;
|
|
124
|
+
this.emit("toggle", { open: true });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
hide() {
|
|
128
|
+
if (this.open) {
|
|
129
|
+
this.open = false;
|
|
130
|
+
this.emit("toggle", { open: false });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
toggle() {
|
|
134
|
+
this.open = !this.open;
|
|
135
|
+
this.emit("toggle", { open: this.open });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/index.ts
|
|
140
|
+
function register() {
|
|
141
|
+
if (!customElements.get("el-dm-circle-menu")) {
|
|
142
|
+
customElements.define("el-dm-circle-menu", ElDmCircleMenu);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/register.ts
|
|
147
|
+
register();
|
|
148
|
+
|
|
149
|
+
//# debugId=A86C37A96CFDBA8364756E2164756E21
|
|
150
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/el-dm-circle-menu.ts", "../../src/index.ts", "../../src/register.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * DuskMoon Circle Menu Element\n *\n * A CSS-only radial circular navigation menu with hamburger/X toggle.\n * Items fan out in a circle when opened. Uses the checkbox toggle pattern\n * from @duskmoon-dev/core internally.\n *\n * @element el-dm-circle-menu\n *\n * @attr {boolean} open - Whether the menu is expanded\n * @attr {string} color - Color variant: primary, secondary, tertiary, info, success, warning, error\n * @attr {string} size - Size: sm, md, lg\n *\n * @slot - Default slot for menu items (a or button elements)\n *\n * @csspart container - The outer circle-menu container\n * @csspart toggle - The toggle label element\n * @csspart list - The menu items list\n *\n * @fires toggle - Fired when the menu opens or closes (detail: { open: boolean })\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-base';\nimport { css as circleMenuCSS } from '@duskmoon-dev/core/components/circle-menu';\n\nconst COLOR_CLASSES: Record<string, string> = {\n primary: 'circle-menu-primary',\n secondary: 'circle-menu-secondary',\n tertiary: 'circle-menu-tertiary',\n info: 'circle-menu-info',\n success: 'circle-menu-success',\n warning: 'circle-menu-warning',\n error: 'circle-menu-error',\n};\n\nconst SIZE_CLASSES: Record<string, string> = {\n sm: 'circle-menu-sm',\n md: '',\n lg: 'circle-menu-lg',\n};\n\nexport type CircleMenuColor =\n | 'primary'\n | 'secondary'\n | 'tertiary'\n | 'info'\n | 'success'\n | 'warning'\n | 'error';\nexport type CircleMenuSize = 'sm' | 'md' | 'lg';\n\n// Strip @layer wrapper for Shadow DOM compatibility\nconst coreStyles = circleMenuCSS\n .replace(/@layer\\s+components\\s*\\{/, '')\n .replace(/\\}\\s*$/, '');\n\nconst styles = css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n ${coreStyles}\n\n .circle-menu {\n font-family: inherit;\n }\n\n /* Hidden slot — items are cloned into the list */\n .slot-holder {\n display: none;\n }\n`;\n\nexport class ElDmCircleMenu extends BaseElement {\n static properties = {\n open: { type: Boolean, reflect: true, default: false },\n color: { type: String, reflect: true },\n size: { type: String, reflect: true },\n };\n\n declare open: boolean;\n declare color: CircleMenuColor;\n declare size: CircleMenuSize;\n\n #toggleId = `cm-${Math.random().toString(36).slice(2, 8)}`;\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n private _getContainerClasses(): string {\n const classes = ['circle-menu'];\n\n if (this.color && COLOR_CLASSES[this.color]) {\n classes.push(COLOR_CLASSES[this.color]);\n }\n\n if (this.size && SIZE_CLASSES[this.size]) {\n classes.push(SIZE_CLASSES[this.size]);\n }\n\n return classes.join(' ');\n }\n\n render(): string {\n const classes = this._getContainerClasses();\n return `\n <nav class=\"${classes}\" part=\"container\">\n <input\n type=\"checkbox\"\n class=\"circle-menu-toggler\"\n id=\"${this.#toggleId}\"\n ${this.open ? 'checked' : ''}\n aria-label=\"Toggle menu\"\n />\n <label class=\"circle-menu-label\" for=\"${this.#toggleId}\" part=\"toggle\"></label>\n <ul class=\"circle-menu-list\" part=\"list\" role=\"menu\"></ul>\n </nav>\n <div class=\"slot-holder\"><slot></slot></div>\n `;\n }\n\n update(): void {\n super.update();\n this.#syncCheckbox();\n this.#syncItems();\n this.#attachToggleListener();\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n\n const slot = this.shadowRoot?.querySelector('slot');\n slot?.addEventListener('slotchange', () => this.#syncItems());\n }\n\n #syncCheckbox(): void {\n const checkbox = this.shadowRoot?.querySelector(\n '.circle-menu-toggler',\n ) as HTMLInputElement | null;\n if (checkbox && checkbox.checked !== this.open) {\n checkbox.checked = this.open;\n }\n }\n\n #syncItems(): void {\n const list = this.shadowRoot?.querySelector('.circle-menu-list');\n const slot = this.shadowRoot?.querySelector('slot');\n if (!list || !slot) return;\n\n const assigned = slot.assignedElements();\n list.innerHTML = '';\n\n assigned.forEach((el) => {\n const li = document.createElement('li');\n li.className = 'circle-menu-item';\n li.setAttribute('role', 'menuitem');\n const clone = el.cloneNode(true) as HTMLElement;\n li.appendChild(clone);\n list.appendChild(li);\n });\n }\n\n #attachToggleListener(): void {\n const checkbox = this.shadowRoot?.querySelector(\n '.circle-menu-toggler',\n ) as HTMLInputElement | null;\n if (!checkbox) return;\n\n checkbox.addEventListener('change', () => {\n this.open = checkbox.checked;\n this.emit('toggle', { open: this.open });\n });\n }\n\n /**\n * Show the menu\n */\n show(): void {\n if (!this.open) {\n this.open = true;\n this.emit('toggle', { open: true });\n }\n }\n\n /**\n * Hide the menu\n */\n hide(): void {\n if (this.open) {\n this.open = false;\n this.emit('toggle', { open: false });\n }\n }\n\n /**\n * Toggle the menu open/closed\n */\n toggle(): void {\n this.open = !this.open;\n this.emit('toggle', { open: this.open });\n }\n}\n",
|
|
6
|
+
"/**\n * @duskmoon-dev/el-circle-menu\n *\n * DuskMoon Circle Menu custom element — a radial navigation menu\n */\n\nimport { ElDmCircleMenu } from './el-dm-circle-menu.js';\n\nexport { ElDmCircleMenu };\nexport type { CircleMenuColor, CircleMenuSize } from './el-dm-circle-menu.js';\n\n/**\n * Register the el-dm-circle-menu custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-circle-menu';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-circle-menu')) {\n customElements.define('el-dm-circle-menu', ElDmCircleMenu);\n }\n}\n",
|
|
7
|
+
"import { register } from './index.js';\nregister();\n"
|
|
8
|
+
],
|
|
9
|
+
"mappings": "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",
|
|
10
|
+
"debugId": "A86C37A96CFDBA8364756E2164756E21",
|
|
11
|
+
"names": []
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fileNames":["../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2021.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2022.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.dom.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2017.date.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2021.string.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2022.array.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2022.error.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2022.object.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2022.string.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/.bun/typescript@6.0.2/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../src/duskmoon-core.d.ts","../../../packages/base/dist/types/base-element.d.ts","../../../packages/base/dist/types/styles.d.ts","../../../packages/base/dist/types/animations.d.ts","../../../packages/base/dist/types/themes.d.ts","../../../packages/base/dist/types/mixins.d.ts","../../../packages/base/dist/types/types.d.ts","../../../packages/base/dist/types/validation.d.ts","../../../packages/base/dist/types/performance.d.ts","../../../packages/base/dist/types/index.d.ts","../src/el-dm-circle-menu.ts","../src/index.ts","../src/register.ts"],"fileIdsList":[[60,69],[70],[71],[61,62,63,64,65,66,67,68],[61],[66]],"fileInfos":[{"version":"bcd24271a113971ba9eb71ff8cb01bc6b0f872a85c23fdbe5d93065b375933cd","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f88bedbeb09c6f5a6645cb24c7c55f1aa22d19ae96c8e6959cbd8b85a707bc6","impliedFormat":1},{"version":"7fe93b39b810eadd916be8db880dd7f0f7012a5cc6ffb62de8f62a2117fa6f1f","impliedFormat":1},{"version":"bb0074cc08b84a2374af33d8bf044b80851ccc9e719a5e202eacf40db2c31600","impliedFormat":1},{"version":"1a7daebe4f45fb03d9ec53d60008fbf9ac45a697fdc89e4ce218bc94b94f94d6","impliedFormat":1},{"version":"f94b133a3cb14a288803be545ac2683e0d0ff6661bcd37e31aaaec54fc382aed","impliedFormat":1},{"version":"f59d0650799f8782fd74cf73c19223730c6d1b9198671b1c5b3a38e1188b5953","impliedFormat":1},{"version":"8a15b4607d9a499e2dbeed9ec0d3c0d7372c850b2d5f1fb259e8f6d41d468a84","impliedFormat":1},{"version":"26e0fe14baee4e127f4365d1ae0b276f400562e45e19e35fd2d4c296684715e6","impliedFormat":1},{"version":"d6b1eba8496bdd0eed6fc8a685768fe01b2da4a0388b5fe7df558290bffcf32f","affectsGlobalScope":true,"impliedFormat":1},{"version":"7f57fc4404ff020bc45b9c620aff2b40f700b95fe31164024c453a5e3c163c54","impliedFormat":1},{"version":"eadcffda2aa84802c73938e589b9e58248d74c59cb7fcbca6474e3435ac15504","affectsGlobalScope":true,"impliedFormat":1},{"version":"105ba8ff7ba746404fe1a2e189d1d3d2e0eb29a08c18dded791af02f29fb4711","affectsGlobalScope":true,"impliedFormat":1},{"version":"00343ca5b2e3d48fa5df1db6e32ea2a59afab09590274a6cccb1dbae82e60c7c","affectsGlobalScope":true,"impliedFormat":1},{"version":"ebd9f816d4002697cb2864bea1f0b70a103124e18a8cd9645eeccc09bdf80ab4","affectsGlobalScope":true,"impliedFormat":1},{"version":"2c1afac30a01772cd2a9a298a7ce7706b5892e447bb46bdbeef720f7b5da77ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"7b0225f483e4fa685625ebe43dd584bb7973bbd84e66a6ba7bbe175ee1048b4f","affectsGlobalScope":true,"impliedFormat":1},{"version":"c0a4b8ac6ce74679c1da2b3795296f5896e31c38e888469a8e0f99dc3305de60","affectsGlobalScope":true,"impliedFormat":1},{"version":"3084a7b5f569088e0146533a00830e206565de65cae2239509168b11434cd84f","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5079c53f0f141a0698faa903e76cb41cd664e3efb01cc17a5c46ec2eb0bef42","affectsGlobalScope":true,"impliedFormat":1},{"version":"32cafbc484dea6b0ab62cf8473182bbcb23020d70845b406f80b7526f38ae862","affectsGlobalScope":true,"impliedFormat":1},{"version":"fca4cdcb6d6c5ef18a869003d02c9f0fd95df8cfaf6eb431cd3376bc034cad36","affectsGlobalScope":true,"impliedFormat":1},{"version":"b93ec88115de9a9dc1b602291b85baf825c85666bf25985cc5f698073892b467","affectsGlobalScope":true,"impliedFormat":1},{"version":"f5c06dcc3fe849fcb297c247865a161f995cc29de7aa823afdd75aaaddc1419b","affectsGlobalScope":true,"impliedFormat":1},{"version":"b77e16112127a4b169ef0b8c3a4d730edf459c5f25fe52d5e436a6919206c4d7","affectsGlobalScope":true,"impliedFormat":1},{"version":"fbffd9337146eff822c7c00acbb78b01ea7ea23987f6c961eba689349e744f8c","affectsGlobalScope":true,"impliedFormat":1},{"version":"a995c0e49b721312f74fdfb89e4ba29bd9824c770bbb4021d74d2bf560e4c6bd","affectsGlobalScope":true,"impliedFormat":1},{"version":"c7b3542146734342e440a84b213384bfa188835537ddbda50d30766f0593aff9","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce6180fa19b1cccd07ee7f7dbb9a367ac19c0ed160573e4686425060b6df7f57","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f02e2476bccb9dbe21280d6090f0df17d2f66b74711489415a8aa4df73c9675","affectsGlobalScope":true,"impliedFormat":1},{"version":"45e3ab34c1c013c8ab2dc1ba4c80c780744b13b5676800ae2e3be27ae862c40c","affectsGlobalScope":true,"impliedFormat":1},{"version":"805c86f6cca8d7702a62a844856dbaa2a3fd2abef0536e65d48732441dde5b5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"e42e397f1a5a77994f0185fd1466520691456c772d06bf843e5084ceb879a0ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"f4c2b41f90c95b1c532ecc874bd3c111865793b23aebcc1c3cbbabcd5d76ffb0","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab26191cfad5b66afa11b8bf935ef1cd88fabfcb28d30b2dfa6fad877d050332","affectsGlobalScope":true,"impliedFormat":1},{"version":"2088bc26531e38fb05eedac2951480db5309f6be3fa4a08d2221abb0f5b4200d","affectsGlobalScope":true,"impliedFormat":1},{"version":"cb9d366c425fea79716a8fb3af0d78e6b22ebbab3bd64d25063b42dc9f531c1e","affectsGlobalScope":true,"impliedFormat":1},{"version":"500934a8089c26d57ebdb688fc9757389bb6207a3c8f0674d68efa900d2abb34","affectsGlobalScope":true,"impliedFormat":1},{"version":"689da16f46e647cef0d64b0def88910e818a5877ca5379ede156ca3afb780ac3","affectsGlobalScope":true,"impliedFormat":1},{"version":"bc21cc8b6fee4f4c2440d08035b7ea3c06b3511314c8bab6bef7a92de58a2593","affectsGlobalScope":true,"impliedFormat":1},{"version":"7ca53d13d2957003abb47922a71866ba7cb2068f8d154877c596d63c359fed25","affectsGlobalScope":true,"impliedFormat":1},{"version":"54725f8c4df3d900cb4dac84b64689ce29548da0b4e9b7c2de61d41c79293611","affectsGlobalScope":true,"impliedFormat":1},{"version":"e5594bc3076ac29e6c1ebda77939bc4c8833de72f654b6e376862c0473199323","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f3eb332c2d73e729f3364fcc0c2b375e72a121e8157d25a82d67a138c83a95c","affectsGlobalScope":true,"impliedFormat":1},{"version":"6f4427f9642ce8d500970e4e69d1397f64072ab73b97e476b4002a646ac743b1","affectsGlobalScope":true,"impliedFormat":1},{"version":"48915f327cd1dea4d7bd358d9dc7732f58f9e1626a29cc0c05c8c692419d9bb7","affectsGlobalScope":true,"impliedFormat":1},{"version":"b7bf9377723203b5a6a4b920164df22d56a43f593269ba6ae1fdc97774b68855","affectsGlobalScope":true,"impliedFormat":1},{"version":"db9709688f82c9e5f65a119c64d835f906efe5f559d08b11642d56eb85b79357","affectsGlobalScope":true,"impliedFormat":1},{"version":"4b25b8c874acd1a4cf8444c3617e037d444d19080ac9f634b405583fd10ce1f7","affectsGlobalScope":true,"impliedFormat":1},{"version":"37be57d7c90cf1f8112ee2636a068d8fd181289f82b744160ec56a7dc158a9f5","affectsGlobalScope":true,"impliedFormat":1},{"version":"a917a49ac94cd26b754ab84e113369a75d1a47a710661d7cd25e961cc797065f","affectsGlobalScope":true,"impliedFormat":1},{"version":"6d3261badeb7843d157ef3e6f5d1427d0eeb0af0cf9df84a62cfd29fd47ac86e","affectsGlobalScope":true,"impliedFormat":1},{"version":"195daca651dde22f2167ac0d0a05e215308119a3100f5e6268e8317d05a92526","affectsGlobalScope":true,"impliedFormat":1},{"version":"8b11e4285cd2bb164a4dc09248bdec69e9842517db4ca47c1ba913011e44ff2f","affectsGlobalScope":true,"impliedFormat":1},{"version":"0508571a52475e245b02bc50fa1394065a0a3d05277fbf5120c3784b85651799","affectsGlobalScope":true,"impliedFormat":1},{"version":"8f9af488f510c3015af3cc8c267a9e9d96c4dd38a1fdff0e11dc5a544711415b","affectsGlobalScope":true,"impliedFormat":1},{"version":"fc611fea8d30ea72c6bbfb599c9b4d393ce22e2f5bfef2172534781e7d138104","affectsGlobalScope":true,"impliedFormat":1},{"version":"1ce14b81c5cc821994aa8ec1d42b220dd41b27fcc06373bce3958af7421b77d4","affectsGlobalScope":true,"impliedFormat":1},{"version":"b3a048b3e9302ef9a34ef4ebb9aecfb28b66abb3bce577206a79fee559c230da","affectsGlobalScope":true,"impliedFormat":1},"dfd4ff5cc0322c5b4b1d92f8b0c46186c949690b6b4ff022a775e2d8dac54cfa","42526b6de804c10fd86f1cf55a6c660a74ee448e381f0f78356f223b75982280","28914adcfb92fa94199e1c887da7d67a7d9d736d9571627d6b02e55ff82f577b","b0a69607a92876948c2a42e3aa6703b0d724699468ed7e3c6e2a237d119a9db9","cdacb8e4ac607a46494d1187e073382c43e7269e8bf698502a285a8ccb470925","f5091ebbd718ea236a7f503df569deb07aff0621aa8f73ed90e419de88f006aa","d3a328c0eccf652bc8b6c14515a8b848a558b9d684e15a7c0c2e15de5016df57","1b5193795ee478857bf1115fed004151284dd4da883a5a4f22e62631c3b414ad","3be01044afc63501423c361deb531d3e95f5c2677f1f7a628802bd346988d62c","78d8d1ca7d54a437702c8a8c08764b6a49f2cf2ca357d0e459bfe89a06abf50a",{"version":"07686471418ce98cb86bce6e4eb10db21950f2dca2c5f10ffd261ef900891cd7","signature":"d3cb5cecc14d595941d289af4065fbd210eb31d9fb3ec7fec7dc21c2f63bbdd4"},{"version":"f133386d954312cc113937f7849925f306780b650e305091444fe73b372f0a2f","signature":"70b5edb16fddb59634bcfac86f932bfc32e6cf8825d7f6ebbad72e87dabb0a44"},{"version":"523786b383c76f3df2cd370f5c61009bc1565e3e65a37ff3865efb0923e06052","signature":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881"}],"root":[60,[70,72]],"options":{"composite":true,"declaration":true,"declarationMap":true,"emitDeclarationOnly":true,"esModuleInterop":true,"module":99,"outDir":"./types","rootDir":"../src","skipLibCheck":true,"sourceMap":true,"strict":true,"target":9},"referencedMap":[[70,1],[71,2],[72,3],[69,4],[65,5],[67,6]],"latestChangedDtsFile":"./types/register.d.ts","version":"6.0.2"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DuskMoon Circle Menu Element
|
|
3
|
+
*
|
|
4
|
+
* A CSS-only radial circular navigation menu with hamburger/X toggle.
|
|
5
|
+
* Items fan out in a circle when opened. Uses the checkbox toggle pattern
|
|
6
|
+
* from @duskmoon-dev/core internally.
|
|
7
|
+
*
|
|
8
|
+
* @element el-dm-circle-menu
|
|
9
|
+
*
|
|
10
|
+
* @attr {boolean} open - Whether the menu is expanded
|
|
11
|
+
* @attr {string} color - Color variant: primary, secondary, tertiary, info, success, warning, error
|
|
12
|
+
* @attr {string} size - Size: sm, md, lg
|
|
13
|
+
*
|
|
14
|
+
* @slot - Default slot for menu items (a or button elements)
|
|
15
|
+
*
|
|
16
|
+
* @csspart container - The outer circle-menu container
|
|
17
|
+
* @csspart toggle - The toggle label element
|
|
18
|
+
* @csspart list - The menu items list
|
|
19
|
+
*
|
|
20
|
+
* @fires toggle - Fired when the menu opens or closes (detail: { open: boolean })
|
|
21
|
+
*/
|
|
22
|
+
import { BaseElement } from '@duskmoon-dev/el-base';
|
|
23
|
+
export type CircleMenuColor = 'primary' | 'secondary' | 'tertiary' | 'info' | 'success' | 'warning' | 'error';
|
|
24
|
+
export type CircleMenuSize = 'sm' | 'md' | 'lg';
|
|
25
|
+
export declare class ElDmCircleMenu extends BaseElement {
|
|
26
|
+
#private;
|
|
27
|
+
static properties: {
|
|
28
|
+
open: {
|
|
29
|
+
type: BooleanConstructor;
|
|
30
|
+
reflect: boolean;
|
|
31
|
+
default: boolean;
|
|
32
|
+
};
|
|
33
|
+
color: {
|
|
34
|
+
type: StringConstructor;
|
|
35
|
+
reflect: boolean;
|
|
36
|
+
};
|
|
37
|
+
size: {
|
|
38
|
+
type: StringConstructor;
|
|
39
|
+
reflect: boolean;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
open: boolean;
|
|
43
|
+
color: CircleMenuColor;
|
|
44
|
+
size: CircleMenuSize;
|
|
45
|
+
constructor();
|
|
46
|
+
private _getContainerClasses;
|
|
47
|
+
render(): string;
|
|
48
|
+
update(): void;
|
|
49
|
+
connectedCallback(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Show the menu
|
|
52
|
+
*/
|
|
53
|
+
show(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Hide the menu
|
|
56
|
+
*/
|
|
57
|
+
hide(): void;
|
|
58
|
+
/**
|
|
59
|
+
* Toggle the menu open/closed
|
|
60
|
+
*/
|
|
61
|
+
toggle(): void;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=el-dm-circle-menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"el-dm-circle-menu.d.ts","sourceRoot":"","sources":["../../src/el-dm-circle-menu.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,WAAW,EAAO,MAAM,uBAAuB,CAAC;AAmBzD,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,WAAW,GACX,UAAU,GACV,MAAM,GACN,SAAS,GACT,SAAS,GACT,OAAO,CAAC;AACZ,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AA6BhD,qBAAa,cAAe,SAAQ,WAAW;;IAC7C,MAAM,CAAC,UAAU;;;;;;;;;;;;;;MAIf;IAEM,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,EAAE,cAAc,CAAC;;IAS7B,OAAO,CAAC,oBAAoB;IAc5B,MAAM,IAAI,MAAM;IAkBhB,MAAM,IAAI,IAAI;IAOd,iBAAiB,IAAI,IAAI;IA8CzB;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACH,MAAM,IAAI,IAAI;CAIf"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @duskmoon-dev/el-circle-menu
|
|
3
|
+
*
|
|
4
|
+
* DuskMoon Circle Menu custom element — a radial navigation menu
|
|
5
|
+
*/
|
|
6
|
+
import { ElDmCircleMenu } from './el-dm-circle-menu.js';
|
|
7
|
+
export { ElDmCircleMenu };
|
|
8
|
+
export type { CircleMenuColor, CircleMenuSize } from './el-dm-circle-menu.js';
|
|
9
|
+
/**
|
|
10
|
+
* Register the el-dm-circle-menu custom element
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { register } from '@duskmoon-dev/el-circle-menu';
|
|
15
|
+
* register();
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function register(): void;
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE9E;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,IAAI,IAAI,CAI/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/register.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@duskmoon-dev/el-circle-menu",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/cjs/index.js",
|
|
6
|
+
"module": "./dist/esm/index.js",
|
|
7
|
+
"types": "./dist/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/types/index.d.ts",
|
|
11
|
+
"import": "./dist/esm/index.js",
|
|
12
|
+
"require": "./dist/cjs/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./register": {
|
|
15
|
+
"types": "./dist/types/register.d.ts",
|
|
16
|
+
"import": "./dist/esm/register.js",
|
|
17
|
+
"require": "./dist/cjs/register.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"prebuild": "bun run clean",
|
|
25
|
+
"build": "bun run build:esm && bun run build:cjs && bun run build:types",
|
|
26
|
+
"build:esm": "bun build ./src/index.ts ./src/register.ts --outdir ./dist/esm --format esm --sourcemap --external @duskmoon-dev/el-base --external @duskmoon-dev/core",
|
|
27
|
+
"build:cjs": "bun build ./src/index.ts ./src/register.ts --outdir ./dist/cjs --format cjs --sourcemap --external @duskmoon-dev/el-base --external @duskmoon-dev/core",
|
|
28
|
+
"build:types": "tsc --emitDeclarationOnly --outDir ./dist/types",
|
|
29
|
+
"dev": "bun build ./src/index.ts --outdir ./dist/esm --format esm --sourcemap --external @duskmoon-dev/el-base --external @duskmoon-dev/core --watch",
|
|
30
|
+
"clean": "del-cli dist",
|
|
31
|
+
"test": "bun test",
|
|
32
|
+
"typecheck": "tsc --noEmit",
|
|
33
|
+
"format": "prettier --write 'src/**/*.ts' '*.json'",
|
|
34
|
+
"format:check": "prettier --check 'src/**/*.ts' '*.json'",
|
|
35
|
+
"lint": "eslint src",
|
|
36
|
+
"lint:check": "eslint src --max-warnings 0",
|
|
37
|
+
"lint:fix": "eslint src --fix",
|
|
38
|
+
"release": "bun publish",
|
|
39
|
+
"release:dry-run": "bun publish --dry-run"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@duskmoon-dev/el-base": "1.1.0",
|
|
43
|
+
"@duskmoon-dev/core": "^1.16.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"typescript": "^6.0.2"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"keywords": [
|
|
52
|
+
"duskmoon-dev",
|
|
53
|
+
"duskmoon",
|
|
54
|
+
"custom-elements",
|
|
55
|
+
"customelements",
|
|
56
|
+
"web-components",
|
|
57
|
+
"webcomponents",
|
|
58
|
+
"html",
|
|
59
|
+
"circle-menu",
|
|
60
|
+
"radial-menu",
|
|
61
|
+
"navigation"
|
|
62
|
+
]
|
|
63
|
+
}
|