juxscript 1.0.20 → 1.0.21
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/bin/cli.js +121 -72
- package/lib/components/alert.ts +143 -92
- package/lib/components/badge.ts +93 -94
- package/lib/components/base/BaseComponent.ts +397 -0
- package/lib/components/base/FormInput.ts +322 -0
- package/lib/components/button.ts +40 -131
- package/lib/components/card.ts +57 -79
- package/lib/components/charts/areachart.ts +315 -0
- package/lib/components/charts/barchart.ts +421 -0
- package/lib/components/charts/doughnutchart.ts +263 -0
- package/lib/components/charts/lib/BaseChart.ts +402 -0
- package/lib/components/{chart-types.ts → charts/lib/chart-types.ts} +1 -1
- package/lib/components/{chart-utils.ts → charts/lib/chart-utils.ts} +1 -1
- package/lib/components/{chart.ts → charts/lib/chart.ts} +3 -3
- package/lib/components/checkbox.ts +255 -204
- package/lib/components/code.ts +31 -78
- package/lib/components/container.ts +113 -130
- package/lib/components/data.ts +37 -5
- package/lib/components/datepicker.ts +180 -147
- package/lib/components/dialog.ts +218 -221
- package/lib/components/divider.ts +63 -87
- package/lib/components/docs-data.json +498 -2404
- package/lib/components/dropdown.ts +191 -236
- package/lib/components/element.ts +196 -145
- package/lib/components/fileupload.ts +253 -167
- package/lib/components/guard.ts +92 -0
- package/lib/components/heading.ts +31 -97
- package/lib/components/helpers.ts +13 -6
- package/lib/components/hero.ts +51 -114
- package/lib/components/icon.ts +33 -120
- package/lib/components/icons.ts +2 -1
- package/lib/components/include.ts +76 -3
- package/lib/components/input.ts +155 -407
- package/lib/components/kpicard.ts +16 -16
- package/lib/components/list.ts +358 -261
- package/lib/components/loading.ts +142 -211
- package/lib/components/menu.ts +63 -152
- package/lib/components/modal.ts +42 -129
- package/lib/components/nav.ts +79 -101
- package/lib/components/paragraph.ts +38 -102
- package/lib/components/progress.ts +108 -166
- package/lib/components/radio.ts +283 -234
- package/lib/components/script.ts +19 -87
- package/lib/components/select.ts +189 -199
- package/lib/components/sidebar.ts +110 -141
- package/lib/components/style.ts +19 -82
- package/lib/components/switch.ts +254 -183
- package/lib/components/table.ts +1078 -208
- package/lib/components/tabs.ts +42 -106
- package/lib/components/theme-toggle.ts +73 -165
- package/lib/components/tooltip.ts +85 -316
- package/lib/components/write.ts +108 -127
- package/lib/jux.ts +67 -41
- package/machinery/build.js +466 -0
- package/machinery/compiler.js +354 -105
- package/machinery/server.js +23 -100
- package/machinery/watcher.js +153 -130
- package/package.json +1 -1
- package/presets/base.css +1166 -0
- package/presets/notion.css +2 -1975
- package/lib/adapters/base-adapter.js +0 -35
- package/lib/adapters/index.js +0 -33
- package/lib/adapters/mysql-adapter.js +0 -65
- package/lib/adapters/postgres-adapter.js +0 -70
- package/lib/adapters/sqlite-adapter.js +0 -56
- package/lib/components/areachart.ts +0 -1128
- package/lib/components/areachartsmooth.ts +0 -1380
- package/lib/components/barchart.ts +0 -1322
- package/lib/components/doughnutchart.ts +0 -1259
- package/lib/components/footer.ts +0 -165
- package/lib/components/header.ts +0 -187
- package/lib/components/layout.ts +0 -239
- package/lib/components/main.ts +0 -137
- package/lib/layouts/default.jux +0 -8
- package/lib/layouts/figma.jux +0 -0
- /package/lib/{themes → components/charts/lib}/charts.js +0 -0
|
@@ -1,222 +1,109 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { BaseComponent } from './base/BaseComponent.js';
|
|
2
|
+
|
|
3
|
+
// Event definitions
|
|
4
|
+
const TRIGGER_EVENTS = [] as const;
|
|
5
|
+
const CALLBACK_EVENTS = [] as const;
|
|
3
6
|
|
|
4
7
|
export interface TooltipOptions {
|
|
5
8
|
text?: string;
|
|
6
9
|
position?: 'top' | 'bottom' | 'left' | 'right';
|
|
7
|
-
trigger?: 'hover' | 'click' | 'focus';
|
|
8
10
|
style?: string;
|
|
9
11
|
class?: string;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
type TooltipState = {
|
|
13
15
|
text: string;
|
|
14
|
-
|
|
15
|
-
position: 'top' | 'bottom' | 'left' | 'right';
|
|
16
|
-
trigger: 'hover' | 'click' | 'focus';
|
|
16
|
+
position: string;
|
|
17
17
|
style: string;
|
|
18
18
|
class: string;
|
|
19
|
-
isVisible: boolean;
|
|
20
19
|
};
|
|
21
20
|
|
|
22
|
-
export class Tooltip {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
_id: string;
|
|
26
|
-
id: string;
|
|
27
|
-
private _tooltipElement: HTMLElement | null = null;
|
|
28
|
-
private _targetElement: HTMLElement | null = null;
|
|
29
|
-
|
|
30
|
-
// CRITICAL: Store bind/sync instructions for deferred wiring
|
|
31
|
-
private _bindings: Array<{ event: string, handler: Function }> = [];
|
|
32
|
-
private _syncBindings: Array<{
|
|
33
|
-
property: string,
|
|
34
|
-
stateObj: State<any>,
|
|
35
|
-
toState?: Function,
|
|
36
|
-
toComponent?: Function
|
|
37
|
-
}> = [];
|
|
21
|
+
export class Tooltip extends BaseComponent<TooltipState> {
|
|
22
|
+
private _tooltip: HTMLElement | null = null;
|
|
23
|
+
private _target: HTMLElement | null = null;
|
|
38
24
|
|
|
39
25
|
constructor(id: string, options: TooltipOptions = {}) {
|
|
40
|
-
|
|
41
|
-
this.id = id;
|
|
42
|
-
|
|
43
|
-
this.state = {
|
|
26
|
+
super(id, {
|
|
44
27
|
text: options.text ?? '',
|
|
45
28
|
position: options.position ?? 'top',
|
|
46
|
-
trigger: options.trigger ?? 'hover',
|
|
47
29
|
style: options.style ?? '',
|
|
48
|
-
class: options.class ?? ''
|
|
49
|
-
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/* -------------------------
|
|
54
|
-
* Fluent API
|
|
55
|
-
* ------------------------- */
|
|
56
|
-
|
|
57
|
-
text(value: string): this {
|
|
58
|
-
this.state.text = value;
|
|
59
|
-
if (this._tooltipElement) {
|
|
60
|
-
this._tooltipElement.textContent = value;
|
|
61
|
-
}
|
|
62
|
-
return this;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
position(value: 'top' | 'bottom' | 'left' | 'right'): this {
|
|
66
|
-
this.state.position = value;
|
|
67
|
-
return this;
|
|
30
|
+
class: options.class ?? ''
|
|
31
|
+
});
|
|
68
32
|
}
|
|
69
33
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return this;
|
|
34
|
+
protected getTriggerEvents(): readonly string[] {
|
|
35
|
+
return TRIGGER_EVENTS;
|
|
73
36
|
}
|
|
74
37
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return this;
|
|
38
|
+
protected getCallbackEvents(): readonly string[] {
|
|
39
|
+
return CALLBACK_EVENTS;
|
|
78
40
|
}
|
|
79
41
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
42
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
43
|
+
* FLUENT API
|
|
44
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
84
45
|
|
|
85
|
-
|
|
86
|
-
this.
|
|
46
|
+
text(value: string): this {
|
|
47
|
+
this.state.text = value;
|
|
87
48
|
return this;
|
|
88
49
|
}
|
|
89
50
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
throw new Error(`Tooltip.sync: Expected a State object for property "${property}"`);
|
|
93
|
-
}
|
|
94
|
-
this._syncBindings.push({ property, stateObj, toState, toComponent });
|
|
51
|
+
position(value: 'top' | 'bottom' | 'left' | 'right'): this {
|
|
52
|
+
this.state.position = value;
|
|
95
53
|
return this;
|
|
96
54
|
}
|
|
97
55
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
*/
|
|
101
|
-
attachTo(target: string | HTMLElement | any): this {
|
|
102
|
-
let targetElement: HTMLElement | null = null;
|
|
103
|
-
|
|
104
|
-
if (typeof target === 'string') {
|
|
105
|
-
const el = document.querySelector(target);
|
|
106
|
-
if (!el || !(el instanceof HTMLElement)) {
|
|
107
|
-
throw new Error(`Tooltip: Target element "${target}" not found`);
|
|
108
|
-
}
|
|
109
|
-
targetElement = el;
|
|
110
|
-
} else if (target instanceof HTMLElement) {
|
|
111
|
-
targetElement = target;
|
|
112
|
-
} else if (target && target.container) {
|
|
113
|
-
targetElement = target.container;
|
|
114
|
-
} else if (target && target._id) {
|
|
115
|
-
const el = document.getElementById(target._id);
|
|
116
|
-
if (!el) {
|
|
117
|
-
throw new Error(`Tooltip: Target element with id "${target._id}" not found`);
|
|
118
|
-
}
|
|
119
|
-
targetElement = el;
|
|
120
|
-
} else {
|
|
121
|
-
throw new Error('Tooltip: Invalid target element');
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
this._targetElement = targetElement;
|
|
125
|
-
this._createTooltip();
|
|
126
|
-
this._attachEventListeners();
|
|
56
|
+
attachTo(target: HTMLElement | null): this {
|
|
57
|
+
if (!target) return this;
|
|
127
58
|
|
|
59
|
+
this._target = target;
|
|
60
|
+
this._setupTooltip();
|
|
128
61
|
return this;
|
|
129
62
|
}
|
|
130
63
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
this.state.isVisible = true;
|
|
135
|
-
this._tooltipElement.classList.add('jux-tooltip-visible');
|
|
136
|
-
this._positionTooltip();
|
|
137
|
-
}
|
|
64
|
+
/* ═════════════════════════════════════════════════════════════════
|
|
65
|
+
* RENDER
|
|
66
|
+
* ═════════════════════════════════════════════════════════════════ */
|
|
138
67
|
|
|
139
|
-
|
|
140
|
-
if (!this.
|
|
141
|
-
|
|
142
|
-
this.state.isVisible = false;
|
|
143
|
-
this._tooltipElement.classList.remove('jux-tooltip-visible');
|
|
144
|
-
}
|
|
68
|
+
private _setupTooltip(): void {
|
|
69
|
+
if (!this._target) return;
|
|
145
70
|
|
|
146
|
-
/* -------------------------
|
|
147
|
-
* Helpers
|
|
148
|
-
* ------------------------- */
|
|
149
|
-
|
|
150
|
-
private _createTooltip(): void {
|
|
151
71
|
const { text, position, style, class: className } = this.state;
|
|
152
72
|
|
|
73
|
+
// Create tooltip element
|
|
153
74
|
const tooltip = document.createElement('div');
|
|
154
75
|
tooltip.className = `jux-tooltip jux-tooltip-${position}`;
|
|
155
|
-
tooltip.id =
|
|
76
|
+
tooltip.id = this._id;
|
|
77
|
+
if (className) tooltip.className += ` ${className}`;
|
|
78
|
+
if (style) tooltip.setAttribute('style', style);
|
|
156
79
|
tooltip.textContent = text;
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
tooltip.className += ` ${className}`;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (style) {
|
|
163
|
-
tooltip.setAttribute('style', style);
|
|
164
|
-
}
|
|
80
|
+
tooltip.style.display = 'none';
|
|
81
|
+
this._tooltip = tooltip;
|
|
165
82
|
|
|
166
83
|
document.body.appendChild(tooltip);
|
|
167
|
-
this._tooltipElement = tooltip;
|
|
168
|
-
|
|
169
|
-
this._injectDefaultStyles();
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
private _attachEventListeners(): void {
|
|
173
|
-
if (!this._targetElement) return;
|
|
174
|
-
|
|
175
|
-
const { trigger } = this.state;
|
|
176
84
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
this.
|
|
180
|
-
}
|
|
181
|
-
this._targetElement.addEventListener('click', () => {
|
|
182
|
-
if (this.state.isVisible) {
|
|
183
|
-
this.hide();
|
|
184
|
-
} else {
|
|
185
|
-
this.show();
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
} else if (trigger === 'focus') {
|
|
189
|
-
this._targetElement.addEventListener('focus', () => this.show());
|
|
190
|
-
this._targetElement.addEventListener('blur', () => this.hide());
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Wire up sync bindings
|
|
194
|
-
this._syncBindings.forEach(({ property, stateObj, toState, toComponent }) => {
|
|
195
|
-
if (property === 'text') {
|
|
196
|
-
const transformToComponent = toComponent || ((v: any) => String(v));
|
|
85
|
+
// Show on hover
|
|
86
|
+
this._target.addEventListener('mouseenter', () => {
|
|
87
|
+
this._show();
|
|
88
|
+
});
|
|
197
89
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
if (this._tooltipElement) {
|
|
201
|
-
this._tooltipElement.textContent = transformed;
|
|
202
|
-
}
|
|
203
|
-
this.state.text = transformed;
|
|
204
|
-
});
|
|
205
|
-
}
|
|
90
|
+
this._target.addEventListener('mouseleave', () => {
|
|
91
|
+
this._hide();
|
|
206
92
|
});
|
|
93
|
+
|
|
94
|
+
this._injectTooltipStyles();
|
|
207
95
|
}
|
|
208
96
|
|
|
209
|
-
private
|
|
210
|
-
if (!this.
|
|
97
|
+
private _show(): void {
|
|
98
|
+
if (!this._tooltip || !this._target) return;
|
|
211
99
|
|
|
212
|
-
const targetRect = this.
|
|
213
|
-
const tooltipRect = this.
|
|
214
|
-
const { position } = this.state;
|
|
100
|
+
const targetRect = this._target.getBoundingClientRect();
|
|
101
|
+
const tooltipRect = this._tooltip.getBoundingClientRect();
|
|
215
102
|
|
|
216
103
|
let top = 0;
|
|
217
104
|
let left = 0;
|
|
218
105
|
|
|
219
|
-
switch (position) {
|
|
106
|
+
switch (this.state.position) {
|
|
220
107
|
case 'top':
|
|
221
108
|
top = targetRect.top - tooltipRect.height - 8;
|
|
222
109
|
left = targetRect.left + (targetRect.width - tooltipRect.width) / 2;
|
|
@@ -235,168 +122,50 @@ export class Tooltip {
|
|
|
235
122
|
break;
|
|
236
123
|
}
|
|
237
124
|
|
|
238
|
-
this.
|
|
239
|
-
this.
|
|
125
|
+
this._tooltip.style.top = `${top}px`;
|
|
126
|
+
this._tooltip.style.left = `${left}px`;
|
|
127
|
+
this._tooltip.style.display = 'block';
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private _hide(): void {
|
|
131
|
+
if (this._tooltip) {
|
|
132
|
+
this._tooltip.style.display = 'none';
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
render(targetId?: string): this {
|
|
137
|
+
// Tooltips don't render to containers, they attach to targets
|
|
138
|
+
console.warn('Tooltip: Use .attachTo(element) instead of .render()');
|
|
139
|
+
return this;
|
|
240
140
|
}
|
|
241
141
|
|
|
242
|
-
private
|
|
142
|
+
private _injectTooltipStyles(): void {
|
|
243
143
|
const styleId = 'jux-tooltip-styles';
|
|
244
144
|
if (document.getElementById(styleId)) return;
|
|
245
145
|
|
|
246
146
|
const style = document.createElement('style');
|
|
247
147
|
style.id = styleId;
|
|
248
148
|
style.textContent = `
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
.jux-tooltip-top::after {
|
|
268
|
-
content: '';
|
|
269
|
-
position: absolute;
|
|
270
|
-
top: 100%;
|
|
271
|
-
left: 50%;
|
|
272
|
-
transform: translateX(-50%);
|
|
273
|
-
border: 5px solid transparent;
|
|
274
|
-
border-top-color: #1f2937;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
.jux-tooltip-bottom::after {
|
|
278
|
-
content: '';
|
|
279
|
-
position: absolute;
|
|
280
|
-
bottom: 100%;
|
|
281
|
-
left: 50%;
|
|
282
|
-
transform: translateX(-50%);
|
|
283
|
-
border: 5px solid transparent;
|
|
284
|
-
border-bottom-color: #1f2937;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
.jux-tooltip-left::after {
|
|
288
|
-
content: '';
|
|
289
|
-
position: absolute;
|
|
290
|
-
left: 100%;
|
|
291
|
-
top: 50%;
|
|
292
|
-
transform: translateY(-50%);
|
|
293
|
-
border: 5px solid transparent;
|
|
294
|
-
border-left-color: #1f2937;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
.jux-tooltip-right::after {
|
|
298
|
-
content: '';
|
|
299
|
-
position: absolute;
|
|
300
|
-
right: 100%;
|
|
301
|
-
top: 50%;
|
|
302
|
-
transform: translateY(-50%);
|
|
303
|
-
border: 5px solid transparent;
|
|
304
|
-
border-right-color: #1f2937;
|
|
305
|
-
}
|
|
306
|
-
`;
|
|
149
|
+
.jux-tooltip {
|
|
150
|
+
position: fixed;
|
|
151
|
+
background: #1f2937;
|
|
152
|
+
color: white;
|
|
153
|
+
padding: 6px 12px;
|
|
154
|
+
border-radius: 6px;
|
|
155
|
+
font-size: 12px;
|
|
156
|
+
white-space: nowrap;
|
|
157
|
+
z-index: 10000;
|
|
158
|
+
pointer-events: none;
|
|
159
|
+
animation: jux-tooltip-fade 0.2s;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@keyframes jux-tooltip-fade {
|
|
163
|
+
from { opacity: 0; }
|
|
164
|
+
to { opacity: 1; }
|
|
165
|
+
}
|
|
166
|
+
`;
|
|
307
167
|
document.head.appendChild(style);
|
|
308
168
|
}
|
|
309
|
-
|
|
310
|
-
render(targetId?: string): this {
|
|
311
|
-
// === 1. SETUP: Get or create container ===
|
|
312
|
-
let container: HTMLElement;
|
|
313
|
-
if (targetId) {
|
|
314
|
-
const target = document.querySelector(targetId);
|
|
315
|
-
if (!target || !(target instanceof HTMLElement)) {
|
|
316
|
-
throw new Error(`Tooltip: Target "${targetId}" not found`);
|
|
317
|
-
}
|
|
318
|
-
container = target;
|
|
319
|
-
} else {
|
|
320
|
-
container = getOrCreateContainer(this._id);
|
|
321
|
-
}
|
|
322
|
-
this.container = container;
|
|
323
|
-
|
|
324
|
-
// === 2. PREPARE: Destructure state ===
|
|
325
|
-
const { text, content, position, trigger, style, class: className } = this.state;
|
|
326
|
-
|
|
327
|
-
// === 3. BUILD: Create DOM elements ===
|
|
328
|
-
const wrapper = document.createElement('div');
|
|
329
|
-
wrapper.className = 'jux-tooltip-wrapper';
|
|
330
|
-
wrapper.id = this._id;
|
|
331
|
-
if (className) wrapper.className += ` ${className}`;
|
|
332
|
-
if (style) wrapper.setAttribute('style', style);
|
|
333
|
-
|
|
334
|
-
const contentEl = document.createElement('div');
|
|
335
|
-
contentEl.className = 'jux-tooltip-content';
|
|
336
|
-
contentEl.innerHTML = content;
|
|
337
|
-
wrapper.appendChild(contentEl);
|
|
338
|
-
|
|
339
|
-
const tooltip = document.createElement('div');
|
|
340
|
-
tooltip.className = `jux-tooltip jux-tooltip-${position}`;
|
|
341
|
-
tooltip.id = `${this._id}-tooltip`;
|
|
342
|
-
tooltip.textContent = text;
|
|
343
|
-
tooltip.style.display = 'none';
|
|
344
|
-
wrapper.appendChild(tooltip);
|
|
345
|
-
|
|
346
|
-
// === 4. WIRE: Attach event listeners and sync bindings ===
|
|
347
|
-
|
|
348
|
-
// Tooltip trigger behavior
|
|
349
|
-
if (trigger === 'hover') {
|
|
350
|
-
wrapper.addEventListener('mouseenter', () => {
|
|
351
|
-
tooltip.style.display = 'block';
|
|
352
|
-
});
|
|
353
|
-
wrapper.addEventListener('mouseleave', () => {
|
|
354
|
-
tooltip.style.display = 'none';
|
|
355
|
-
});
|
|
356
|
-
} else if (trigger === 'click') {
|
|
357
|
-
wrapper.addEventListener('click', () => {
|
|
358
|
-
tooltip.style.display = tooltip.style.display === 'none' ? 'block' : 'none';
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
// Wire custom bindings from .bind() calls
|
|
363
|
-
this._bindings.forEach(({ event, handler }) => {
|
|
364
|
-
wrapper.addEventListener(event, handler as EventListener);
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
// Wire sync bindings from .sync() calls
|
|
368
|
-
this._syncBindings.forEach(({ property, stateObj, toState, toComponent }) => {
|
|
369
|
-
if (property === 'text') {
|
|
370
|
-
const transformToComponent = toComponent || ((v: any) => String(v));
|
|
371
|
-
|
|
372
|
-
stateObj.subscribe((val: any) => {
|
|
373
|
-
const transformed = transformToComponent(val);
|
|
374
|
-
tooltip.textContent = transformed;
|
|
375
|
-
this.state.text = transformed;
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
else if (property === 'content') {
|
|
379
|
-
const transformToComponent = toComponent || ((v: any) => String(v));
|
|
380
|
-
|
|
381
|
-
stateObj.subscribe((val: any) => {
|
|
382
|
-
const transformed = transformToComponent(val);
|
|
383
|
-
contentEl.innerHTML = transformed;
|
|
384
|
-
this.state.content = transformed;
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
// === 5. RENDER: Append to DOM and finalize ===
|
|
390
|
-
container.appendChild(wrapper);
|
|
391
|
-
return this;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
renderTo(juxComponent: any): this {
|
|
395
|
-
if (!juxComponent?._id) {
|
|
396
|
-
throw new Error('Tooltip.renderTo: Invalid component');
|
|
397
|
-
}
|
|
398
|
-
return this.render(`#${juxComponent._id}`);
|
|
399
|
-
}
|
|
400
169
|
}
|
|
401
170
|
|
|
402
171
|
export function tooltip(id: string, options: TooltipOptions = {}): Tooltip {
|