@aquera/nile-elements 0.1.67-beta-1.5 → 0.1.67-beta-1.6
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/demo/index.html +13 -6
- package/dist/index.js +51 -48
- package/dist/nile-rich-text-editor/nile-rich-text-editor.cjs.js +1 -1
- package/dist/nile-rich-text-editor/nile-rich-text-editor.cjs.js.map +1 -1
- package/dist/nile-rich-text-editor/nile-rich-text-editor.css.cjs.js +1 -1
- package/dist/nile-rich-text-editor/nile-rich-text-editor.css.cjs.js.map +1 -1
- package/dist/nile-rich-text-editor/nile-rich-text-editor.css.esm.js +11 -8
- package/dist/nile-rich-text-editor/nile-rich-text-editor.esm.js +1 -1
- package/dist/nile-rich-text-editor/nile-rte-select.cjs.js +1 -1
- package/dist/nile-rich-text-editor/nile-rte-select.cjs.js.map +1 -1
- package/dist/nile-rich-text-editor/nile-rte-select.esm.js +39 -39
- package/dist/nile-rich-text-editor/utils.cjs.js.map +1 -1
- package/dist/src/nile-rich-text-editor/nile-rich-text-editor.css.js +11 -8
- package/dist/src/nile-rich-text-editor/nile-rich-text-editor.css.js.map +1 -1
- package/dist/src/nile-rich-text-editor/nile-rich-text-editor.js +33 -25
- package/dist/src/nile-rich-text-editor/nile-rich-text-editor.js.map +1 -1
- package/dist/src/nile-rich-text-editor/nile-rte-select.js +62 -57
- package/dist/src/nile-rich-text-editor/nile-rte-select.js.map +1 -1
- package/dist/src/nile-rich-text-editor/rte-utils/content.d.ts +2 -0
- package/dist/src/nile-rich-text-editor/rte-utils/content.js +25 -0
- package/dist/src/nile-rich-text-editor/rte-utils/content.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/css.d.ts +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/css.js +9 -0
- package/dist/src/nile-rich-text-editor/rte-utils/css.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/dom.d.ts +2 -0
- package/dist/src/nile-rich-text-editor/rte-utils/dom.js +48 -0
- package/dist/src/nile-rich-text-editor/rte-utils/dom.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/formatting.d.ts +2 -0
- package/dist/src/nile-rich-text-editor/rte-utils/formatting.js +69 -0
- package/dist/src/nile-rich-text-editor/rte-utils/formatting.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/keys.d.ts +2 -0
- package/dist/src/nile-rich-text-editor/rte-utils/keys.js +38 -0
- package/dist/src/nile-rich-text-editor/rte-utils/keys.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/lists.d.ts +2 -0
- package/dist/src/nile-rich-text-editor/rte-utils/lists.js +28 -0
- package/dist/src/nile-rich-text-editor/rte-utils/lists.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/selection.d.ts +17 -0
- package/dist/src/nile-rich-text-editor/rte-utils/selection.js +39 -0
- package/dist/src/nile-rich-text-editor/rte-utils/selection.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/toolbar.d.ts +28 -0
- package/dist/src/nile-rich-text-editor/rte-utils/toolbar.js +161 -0
- package/dist/src/nile-rich-text-editor/rte-utils/toolbar.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/toolbarState.d.ts +13 -0
- package/dist/src/nile-rich-text-editor/rte-utils/toolbarState.js +119 -0
- package/dist/src/nile-rich-text-editor/rte-utils/toolbarState.js.map +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/vars.d.ts +1 -0
- package/dist/src/nile-rich-text-editor/rte-utils/vars.js +14 -0
- package/dist/src/nile-rich-text-editor/rte-utils/vars.js.map +1 -0
- package/dist/src/nile-rich-text-editor/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/nile-rich-text-editor/nile-rich-text-editor.css.ts +11 -8
- package/src/nile-rich-text-editor/nile-rich-text-editor.ts +46 -26
- package/src/nile-rich-text-editor/nile-rte-select.ts +178 -173
- package/src/nile-rich-text-editor/utils.ts +342 -341
package/package.json
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
"description": "Webcomponent nile-elements following open-wc recommendations",
|
4
4
|
"license": "MIT",
|
5
5
|
"author": "nile-elements",
|
6
|
-
"version": "0.1.67-beta-1.
|
6
|
+
"version": "0.1.67-beta-1.6",
|
7
7
|
"main": "dist/src/index.js",
|
8
8
|
"type": "module",
|
9
9
|
"module": "dist/src/index.js",
|
@@ -19,7 +19,7 @@ nile-rte-toolbar-item > nile-button::part(base) {
|
|
19
19
|
|
20
20
|
|
21
21
|
.toolbar, nile-rte-toolbar {
|
22
|
-
display:flex; align-items:center; gap:
|
22
|
+
display:flex; align-items:center; gap:6px; padding:8px;
|
23
23
|
border:1px solid #e5e7eb; border-bottom:none; border-radius:8px 8px 0 0; background:#fff;
|
24
24
|
}
|
25
25
|
|
@@ -66,14 +66,17 @@ font-weight: bold;}
|
|
66
66
|
display: inline-flex;
|
67
67
|
align-items: center;
|
68
68
|
justify-content: center;
|
69
|
-
|
70
|
-
padding: 0 8px;
|
71
|
-
border: 1px solid var(--nile-color-border, #d9d9d9);
|
69
|
+
/* border: 1px solid var(--nile-color-border, #d9d9d9); */
|
72
70
|
border-radius: 6px;
|
73
71
|
background: #fff;
|
74
72
|
cursor: pointer;
|
75
|
-
|
73
|
+
border:none;
|
74
|
+
|
76
75
|
|
76
|
+
}
|
77
|
+
nile-button.rte-color-trigger::part(base){
|
78
|
+
width:32px; height:32px; padding:0px 6px;
|
79
|
+
}
|
77
80
|
.rte-color-trigger .glyph-stack {
|
78
81
|
display: grid; /* stack vertically */
|
79
82
|
grid-auto-rows: max-content;
|
@@ -85,17 +88,17 @@ font-weight: bold;}
|
|
85
88
|
.rte-color-trigger .glyph {
|
86
89
|
font-size: 14px;
|
87
90
|
line-height: 1;
|
88
|
-
margin-bottom: 2px;
|
91
|
+
margin-bottom: 2px;
|
89
92
|
}
|
90
93
|
|
91
94
|
.rte-color-trigger .underline {
|
92
95
|
width: 18px;
|
93
96
|
height: 3px;
|
94
97
|
border-radius: 2px;
|
95
|
-
background: currentColor;
|
98
|
+
background: currentColor;
|
96
99
|
}
|
97
100
|
|
98
|
-
|
101
|
+
|
99
102
|
.rte-color-trigger .swatch-box {
|
100
103
|
width: 18px;
|
101
104
|
height: 16px;
|
@@ -33,8 +33,8 @@ const DEFAULT_ICONS: Record<string, string> = {
|
|
33
33
|
center: 'format_align_middle',
|
34
34
|
right: 'format_align_right',
|
35
35
|
justify: 'format_align_justify',
|
36
|
-
ul: '
|
37
|
-
ol: '
|
36
|
+
ul: 'format_list_bulleted',
|
37
|
+
ol: 'format_list_numbered',
|
38
38
|
clear: 'error',
|
39
39
|
};
|
40
40
|
|
@@ -355,28 +355,28 @@ private bgSwatchEl: HTMLElement | null = null;
|
|
355
355
|
input.title = label;
|
356
356
|
input.value = value;
|
357
357
|
|
358
|
-
|
359
|
-
let trigger = child.querySelector(':scope > button.rte-color-trigger') as HTMLButtonElement | null;
|
358
|
+
let trigger = child.querySelector(':scope > nile-button') as HTMLElement | null;
|
360
359
|
if (!trigger) {
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
360
|
+
const nb = document.createElement('nile-button');
|
361
|
+
(nb as any).variant = 'ghost';
|
362
|
+
nb.className = 'rte-color-trigger';
|
363
|
+
nb.setAttribute('aria-label', label);
|
364
|
+
|
366
365
|
if (mode === 'background') {
|
367
|
-
|
368
|
-
<span class="swatch-box" aria-hidden="true"></span>
|
369
|
-
`;
|
366
|
+
nb.innerHTML = `<span class="swatch-box" aria-hidden="true"></span>`;
|
370
367
|
} else {
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
368
|
+
nb.innerHTML = `
|
369
|
+
<span class="glyph-stack" aria-hidden="true">
|
370
|
+
<span class="glyph">A</span>
|
371
|
+
<span class="underline"></span>
|
372
|
+
</span>
|
376
373
|
`;
|
377
374
|
}
|
378
|
-
|
375
|
+
|
376
|
+
child.appendChild(nb);
|
377
|
+
trigger = nb;
|
379
378
|
}
|
379
|
+
|
380
380
|
|
381
381
|
// Cache swatch elements to update later
|
382
382
|
const underline = trigger.querySelector('.underline') as HTMLElement | null;
|
@@ -672,33 +672,52 @@ private ensureAtLeastOneParagraph() {
|
|
672
672
|
if (!this.editorEl) return;
|
673
673
|
this.ensureAtLeastOneParagraph();
|
674
674
|
|
675
|
-
|
675
|
+
|
676
676
|
const clone = this.editorEl.cloneNode(true) as HTMLElement;
|
677
677
|
|
678
|
-
|
678
|
+
|
679
679
|
const origWalker = document.createTreeWalker(this.editorEl, NodeFilter.SHOW_ELEMENT);
|
680
680
|
const cloneWalker = document.createTreeWalker(clone, NodeFilter.SHOW_ELEMENT);
|
681
681
|
|
682
|
+
|
683
|
+
const importantProps = [
|
684
|
+
'font-weight',
|
685
|
+
'font-style',
|
686
|
+
'text-decoration',
|
687
|
+
'color',
|
688
|
+
'background-color',
|
689
|
+
'font-size',
|
690
|
+
'font-family',
|
691
|
+
'text-align',
|
692
|
+
'line-height',
|
693
|
+
'letter-spacing',
|
694
|
+
'white-space',
|
695
|
+
'vertical-align'
|
696
|
+
];
|
697
|
+
|
682
698
|
while (origWalker.nextNode() && cloneWalker.nextNode()) {
|
683
699
|
const origEl = origWalker.currentNode as HTMLElement;
|
684
700
|
const cloneEl = cloneWalker.currentNode as HTMLElement;
|
685
701
|
const computed = window.getComputedStyle(origEl);
|
686
702
|
|
687
|
-
|
688
|
-
const cssText =
|
703
|
+
|
704
|
+
const cssText = importantProps
|
689
705
|
.map(prop => `${prop}:${computed.getPropertyValue(prop)}`)
|
690
706
|
.join(';');
|
691
707
|
|
692
|
-
|
708
|
+
|
709
|
+
if (cssText.trim()) {
|
710
|
+
cloneEl.setAttribute('style', cssText);
|
711
|
+
}
|
693
712
|
}
|
694
713
|
|
695
|
-
|
714
|
+
|
696
715
|
this.content = clone.innerHTML;
|
697
716
|
|
698
|
-
|
717
|
+
|
699
718
|
if (this.previewEl) this.previewEl.innerHTML = this.content;
|
700
719
|
|
701
|
-
|
720
|
+
|
702
721
|
this.dispatchEvent(new CustomEvent('content-changed', {
|
703
722
|
detail: { content: this.content },
|
704
723
|
bubbles: true,
|
@@ -708,6 +727,7 @@ private ensureAtLeastOneParagraph() {
|
|
708
727
|
|
709
728
|
|
710
729
|
|
730
|
+
|
711
731
|
}
|
712
732
|
|
713
733
|
declare global {
|
@@ -1,195 +1,180 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
1
|
+
// nile-rte-select.ts
|
2
|
+
import { LitElement, html } from 'lit';
|
3
|
+
import { customElement, property, state } from 'lit/decorators.js';
|
4
|
+
|
5
|
+
type HeadingTag = 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
6
|
+
type GenericOption = { value: string; label?: string; icon?: string };
|
7
|
+
type HeadingOption = { value: HeadingTag; label?: string; icon?: string };
|
8
|
+
type NormalizedOption = { value: string; label: string; icon?: string };
|
9
|
+
|
10
|
+
const HEADING_ALLOWLIST: ReadonlySet<HeadingTag> = new Set([
|
11
|
+
'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
|
12
|
+
]);
|
13
|
+
|
14
|
+
function isHeadingTag(v: string): v is HeadingTag {
|
15
|
+
return HEADING_ALLOWLIST.has(v as HeadingTag);
|
16
|
+
}
|
17
|
+
|
18
|
+
@customElement('nile-rte-select')
|
19
|
+
export class NileRteSelect extends LitElement {
|
20
|
+
protected createRenderRoot() { return this; }
|
21
|
+
|
22
|
+
/** 'heading' | 'font' | 'align' */
|
23
|
+
@property({ type: String }) type = '';
|
24
|
+
|
25
|
+
/** JSON: [{ value, label?, icon? }, ...] (attribute-based; runtime-validated) */
|
26
|
+
@property({ type: String }) options = '[]';
|
27
|
+
|
28
|
+
/** Programmatic options (preferred for TS safety). */
|
29
|
+
@property({ attribute: false })
|
30
|
+
optionsObj?: Array<GenericOption | HeadingOption>;
|
31
|
+
|
32
|
+
/** Fallback label for trigger (e.g., "Align") */
|
33
|
+
@property({ type: String }) label = '';
|
34
|
+
|
35
|
+
@state() private selectedValue = '';
|
36
|
+
|
37
|
+
private mapAlignIcon(v: string) {
|
38
|
+
const map: Record<string,string> = {
|
39
|
+
left: 'format_align_left',
|
40
|
+
center: 'format_align_middle',
|
41
|
+
right: 'format_align_right',
|
42
|
+
justify: 'format_align_justify'
|
43
|
+
};
|
44
|
+
return map[v] || 'format_align_left';
|
16
45
|
}
|
17
46
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
47
|
+
private get parsedOptions(): NormalizedOption[] {
|
48
|
+
// Prefer programmatic options if present (gives TS compile-time checks)
|
49
|
+
const source: unknown = this.optionsObj ?? this.options;
|
50
|
+
|
51
|
+
const rawArray: any[] = (() => {
|
52
|
+
if (Array.isArray(source)) return source;
|
53
|
+
try { return JSON.parse(String(source)); } catch { return []; }
|
54
|
+
})();
|
55
|
+
|
56
|
+
// Normalize to consistent shape
|
57
|
+
let items: NormalizedOption[] = rawArray.map((o: any) => {
|
58
|
+
const value: string = o?.value ?? o;
|
59
|
+
const label: string = o?.label ?? o?.value ?? o;
|
60
|
+
const icon: string | undefined =
|
61
|
+
o?.icon ?? (this.type === 'align' ? this.mapAlignIcon(String(value)) : undefined);
|
62
|
+
return { value, label, icon };
|
63
|
+
});
|
64
|
+
|
65
|
+
// If type is heading, enforce allowlist (runtime validation)
|
66
|
+
if (this.type === 'heading') {
|
67
|
+
const before = items.length;
|
68
|
+
items = items.filter(i => isHeadingTag(i.value));
|
69
|
+
if (items.length !== before) {
|
70
|
+
}
|
71
|
+
// If current selection is invalid for heading, reset
|
72
|
+
if (this.selectedValue && !isHeadingTag(this.selectedValue)) {
|
73
|
+
this.selectedValue = '';
|
74
|
+
}
|
75
|
+
}
|
31
76
|
|
32
|
-
|
33
|
-
|
77
|
+
return items;
|
78
|
+
}
|
34
79
|
|
35
|
-
|
80
|
+
private ensureDefault() {
|
81
|
+
if (!this.selectedValue) {
|
82
|
+
const first = this.parsedOptions[0];
|
83
|
+
if (first) this.selectedValue = first.value;
|
84
|
+
}
|
85
|
+
}
|
36
86
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
right: 'format_align_right',
|
42
|
-
justify: 'format_align_justify'
|
43
|
-
};
|
44
|
-
return map[v] || 'align-left';
|
87
|
+
private onSelect(value: string) {
|
88
|
+
if (this.type === 'heading' && !isHeadingTag(value)) {
|
89
|
+
console.warn(`[nile-rte-select] Ignoring invalid heading value: ${value}`);
|
90
|
+
return;
|
45
91
|
}
|
92
|
+
this.selectedValue = value;
|
93
|
+
this.dispatchEvent(new CustomEvent('change', {
|
94
|
+
detail: value, bubbles: true, composed: true
|
95
|
+
}));
|
96
|
+
}
|
46
97
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
const rawArray: any[] = (() => {
|
52
|
-
if (Array.isArray(source)) return source;
|
53
|
-
try { return JSON.parse(String(source)); } catch { return []; }
|
54
|
-
})();
|
55
|
-
|
56
|
-
// Normalize to consistent shape
|
57
|
-
let items: NormalizedOption[] = rawArray.map((o: any) => {
|
58
|
-
const value: string = o?.value ?? o;
|
59
|
-
const label: string = o?.label ?? o?.value ?? o;
|
60
|
-
const icon: string | undefined =
|
61
|
-
o?.icon ?? (this.type === 'align' ? this.mapAlignIcon(String(value)) : undefined);
|
62
|
-
return { value, label, icon };
|
63
|
-
});
|
64
|
-
|
65
|
-
// If type is heading, enforce allowlist (runtime validation)
|
66
|
-
if (this.type === 'heading') {
|
67
|
-
const before = items.length;
|
68
|
-
items = items.filter(i => isHeadingTag(i.value));
|
69
|
-
if (items.length !== before) {
|
70
|
-
}
|
71
|
-
// If current selection is invalid for heading, reset
|
72
|
-
if (this.selectedValue && !isHeadingTag(this.selectedValue)) {
|
73
|
-
this.selectedValue = '';
|
74
|
-
}
|
75
|
-
}
|
98
|
+
connectedCallback(): void {
|
99
|
+
super.connectedCallback();
|
100
|
+
this.injectLocalStyles();
|
101
|
+
}
|
76
102
|
|
77
|
-
|
78
|
-
|
103
|
+
private injectLocalStyles() {
|
104
|
+
if (this.querySelector('style[data-rte-select-style]')) return;
|
79
105
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
106
|
+
const style = document.createElement('style');
|
107
|
+
style.setAttribute('data-rte-select-style', 'true');
|
108
|
+
style.textContent = `
|
109
|
+
nile-menu.rte-align-menu::part(menu__items-wrapper) {
|
110
|
+
display: flex;
|
84
111
|
}
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
if (this.type === 'heading' && !isHeadingTag(value)) {
|
89
|
-
console.warn(`[nile-rte-select] Ignoring invalid heading value: ${value}`);
|
90
|
-
return;
|
112
|
+
nile-menu.rte-align-menu,
|
113
|
+
nile-menu.rte-default-menu {
|
114
|
+
margin-top: 0px;
|
91
115
|
}
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
116
|
+
nile-button.rte-align-trigger::part(base),
|
117
|
+
nile-button.rte-default-trigger::part(base) {
|
118
|
+
min-width: 32px;
|
119
|
+
height: 32px;
|
120
|
+
padding: 0px 6px;
|
121
|
+
box-shadow: none;
|
122
|
+
}
|
123
|
+
nile-button.rte-align-trigger::part(base) {
|
124
|
+
|
97
125
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
126
|
+
border: none;
|
127
|
+
}
|
128
|
+
`;
|
129
|
+
this.insertBefore(style, this.firstChild);
|
130
|
+
}
|
102
131
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
style.setAttribute('data-rte-select-style', 'true');
|
108
|
-
style.textContent = `
|
109
|
-
nile-menu.rte-align-menu::part(menu__items-wrapper) {
|
110
|
-
display: flex;
|
111
|
-
}
|
112
|
-
nile-menu.rte-align-menu,
|
113
|
-
nile-menu.rte-default-menu {
|
114
|
-
margin-top: 0px;
|
115
|
-
}
|
116
|
-
nile-button.rte-align-trigger::part(base),
|
117
|
-
nile-button.rte-default-trigger::part(base) {
|
118
|
-
min-width: 32px;
|
119
|
-
height: 32px;
|
120
|
-
padding: 0px 6px;
|
121
|
-
box-shadow: none;
|
122
|
-
}
|
123
|
-
`;
|
124
|
-
this.insertBefore(style, this.firstChild);
|
125
|
-
}
|
132
|
+
render() {
|
133
|
+
const opts = this.parsedOptions;
|
134
|
+
this.ensureDefault();
|
135
|
+
const current = opts.find(o => o.value === this.selectedValue);
|
126
136
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
// ► Align: icon-only items + icon trigger
|
133
|
-
if (this.type === 'align') {
|
134
|
-
const trigger = current?.icon
|
135
|
-
? html`<nile-icon name="${current.icon}"></nile-icon>`
|
136
|
-
: (this.label || 'Align');
|
137
|
-
|
138
|
-
return html`
|
139
|
-
<nile-dropdown class="rte-align-dd">
|
140
|
-
<nile-button slot="trigger" variant="tertiary" class="rte-align-trigger">
|
141
|
-
${trigger}
|
142
|
-
</nile-button>
|
143
|
-
<nile-menu class="rte-align-menu">
|
144
|
-
${opts.map(o => html`
|
145
|
-
<nile-menu-item
|
146
|
-
class="rte-align-item"
|
147
|
-
?active=${o.value === this.selectedValue}
|
148
|
-
@click=${() => this.onSelect(o.value)}>
|
149
|
-
<nile-icon name="${o.icon}"></nile-icon>
|
150
|
-
</nile-menu-item>
|
151
|
-
`)}
|
152
|
-
</nile-menu>
|
153
|
-
</nile-dropdown>
|
154
|
-
`;
|
155
|
-
}
|
137
|
+
// ► Align: icon-only items + icon trigger
|
138
|
+
if (this.type === 'align') {
|
139
|
+
const trigger = current?.icon
|
140
|
+
? html`<nile-icon name="${current.icon}"></nile-icon>`
|
141
|
+
: (this.label || 'Align');
|
156
142
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
${o.label}
|
176
|
-
</nile-menu-item>
|
177
|
-
`)}
|
178
|
-
</nile-menu>
|
179
|
-
</nile-dropdown>
|
180
|
-
`;
|
181
|
-
}
|
143
|
+
return html`
|
144
|
+
<nile-dropdown class="rte-align-dd">
|
145
|
+
<nile-button slot="trigger" variant="tertiary" class="rte-align-trigger">
|
146
|
+
${trigger}
|
147
|
+
</nile-button>
|
148
|
+
<nile-menu class="rte-align-menu">
|
149
|
+
${opts.map(o => html`
|
150
|
+
<nile-menu-item
|
151
|
+
class="rte-align-item"
|
152
|
+
?active=${o.value === this.selectedValue}
|
153
|
+
@click=${() => this.onSelect(o.value)}>
|
154
|
+
<nile-icon name="${o.icon}"></nile-icon>
|
155
|
+
</nile-menu-item>
|
156
|
+
`)}
|
157
|
+
</nile-menu>
|
158
|
+
</nile-dropdown>
|
159
|
+
`;
|
160
|
+
}
|
182
161
|
|
183
|
-
|
184
|
-
|
162
|
+
// ► Font: show labels, preview fonts in items and trigger
|
163
|
+
if (this.type === 'font') {
|
164
|
+
const triggerText = current?.label || this.label || 'Font';
|
185
165
|
return html`
|
186
166
|
<nile-dropdown class="rte-default-dd">
|
187
|
-
<nile-button
|
167
|
+
<nile-button
|
168
|
+
slot="trigger"
|
169
|
+
variant="tertiary"
|
170
|
+
class="rte-default-trigger"
|
171
|
+
style="font-family: ${current?.value || 'inherit'}">
|
188
172
|
${triggerText} <nile-icon name="arrowdown"></nile-icon>
|
189
173
|
</nile-button>
|
190
174
|
<nile-menu class="rte-default-menu">
|
191
175
|
${opts.map(o => html`
|
192
176
|
<nile-menu-item
|
177
|
+
style="font-family: ${o.value}"
|
193
178
|
?active=${o.value === this.selectedValue}
|
194
179
|
@click=${() => this.onSelect(o.value)}>
|
195
180
|
${o.label}
|
@@ -199,10 +184,30 @@
|
|
199
184
|
</nile-dropdown>
|
200
185
|
`;
|
201
186
|
}
|
187
|
+
|
188
|
+
// ► Default (e.g., heading): text items; heading values are validated already
|
189
|
+
const triggerText = current?.label || this.label || 'Select';
|
190
|
+
return html`
|
191
|
+
<nile-dropdown class="rte-default-dd">
|
192
|
+
<nile-button slot="trigger" variant="tertiary" class="rte-default-trigger">
|
193
|
+
${triggerText} <nile-icon name="arrowdown"></nile-icon>
|
194
|
+
</nile-button>
|
195
|
+
<nile-menu class="rte-default-menu">
|
196
|
+
${opts.map(o => html`
|
197
|
+
<nile-menu-item
|
198
|
+
?active=${o.value === this.selectedValue}
|
199
|
+
@click=${() => this.onSelect(o.value)}>
|
200
|
+
${o.label}
|
201
|
+
</nile-menu-item>
|
202
|
+
`)}
|
203
|
+
</nile-menu>
|
204
|
+
</nile-dropdown>
|
205
|
+
`;
|
202
206
|
}
|
207
|
+
}
|
203
208
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
}
|
209
|
+
declare global {
|
210
|
+
interface HTMLElementTagNameMap {
|
211
|
+
'nile-rte-select': NileRteSelect;
|
208
212
|
}
|
213
|
+
}
|