@sekiui/elements 0.0.52 → 0.0.54
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/cdn/index.js +1 -1
- package/dist/cdn/seki-button.js +1 -1
- package/dist/cdn/seki-field-description.js +1 -1
- package/dist/cdn/seki-field-error.js +1 -1
- package/dist/cdn/seki-field-group.js +1 -1
- package/dist/cdn/seki-field-label.js +1 -1
- package/dist/cdn/seki-field-legend.js +1 -1
- package/dist/cdn/seki-field.js +1 -1
- package/dist/cdn/seki-fieldset.js +1 -1
- package/dist/cdn/seki-input.js +1 -1
- package/dist/cdn/seki-select-group.js +1 -1
- package/dist/cdn/seki-select-option.js +1 -1
- package/dist/cdn/seki-select.js +1 -1
- package/dist/cdn/seki-skeleton.js +1 -1
- package/dist/cdn/seki-tooltip.d.ts +11 -0
- package/dist/cdn/seki-tooltip.js +378 -0
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/seki-button.cjs.entry.js +1 -1
- package/dist/cjs/seki-field-description.cjs.entry.js +1 -1
- package/dist/cjs/seki-field-error.cjs.entry.js +1 -1
- package/dist/cjs/seki-field-group.cjs.entry.js +1 -1
- package/dist/cjs/seki-field-label.cjs.entry.js +1 -1
- package/dist/cjs/seki-field-legend.cjs.entry.js +1 -1
- package/dist/cjs/seki-field.cjs.entry.js +1 -1
- package/dist/cjs/seki-fieldset.cjs.entry.js +1 -1
- package/dist/cjs/seki-input.cjs.entry.js +1 -1
- package/dist/cjs/seki-select-group.cjs.entry.js +1 -1
- package/dist/cjs/seki-select-option.cjs.entry.js +1 -1
- package/dist/cjs/seki-select.cjs.entry.js +1 -1
- package/dist/cjs/seki-skeleton.cjs.entry.js +1 -1
- package/dist/cjs/seki-tooltip.cjs.entry.js +349 -0
- package/dist/cjs/sekiui.cjs.js +1 -1
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/button/seki-button.js +1 -1
- package/dist/collection/components/field/seki-field.js +1 -1
- package/dist/collection/components/field-description/seki-field-description.js +1 -1
- package/dist/collection/components/field-error/seki-field-error.js +1 -1
- package/dist/collection/components/field-group/seki-field-group.js +1 -1
- package/dist/collection/components/field-label/seki-field-label.js +1 -1
- package/dist/collection/components/field-legend/seki-field-legend.js +1 -1
- package/dist/collection/components/fieldset/seki-fieldset.js +1 -1
- package/dist/collection/components/input/seki-input.js +1 -1
- package/dist/collection/components/select/seki-select.js +1 -1
- package/dist/collection/components/select-group/seki-select-group.js +1 -1
- package/dist/collection/components/select-option/seki-select-option.js +1 -1
- package/dist/collection/components/skeleton/seki-skeleton.js +1 -1
- package/dist/collection/components/switch/seki-switch.js +1 -1
- package/dist/collection/components/tooltip/seki-tooltip.css +522 -0
- package/dist/collection/components/tooltip/seki-tooltip.js +608 -0
- package/dist/components/index.js +1 -1
- package/dist/components/seki-button.js +1 -1
- package/dist/components/seki-field-description.js +1 -1
- package/dist/components/seki-field-error.js +1 -1
- package/dist/components/seki-field-group.js +1 -1
- package/dist/components/seki-field-label.js +1 -1
- package/dist/components/seki-field-legend.js +1 -1
- package/dist/components/seki-field.js +1 -1
- package/dist/components/seki-fieldset.js +1 -1
- package/dist/components/seki-input.js +1 -1
- package/dist/components/seki-select-group.js +1 -1
- package/dist/components/seki-select-option.js +1 -1
- package/dist/components/seki-select.js +1 -1
- package/dist/components/seki-skeleton.js +1 -1
- package/dist/components/seki-tooltip.d.ts +11 -0
- package/dist/components/seki-tooltip.js +378 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/seki-button.entry.js +1 -1
- package/dist/esm/seki-field-description.entry.js +1 -1
- package/dist/esm/seki-field-error.entry.js +1 -1
- package/dist/esm/seki-field-group.entry.js +1 -1
- package/dist/esm/seki-field-label.entry.js +1 -1
- package/dist/esm/seki-field-legend.entry.js +1 -1
- package/dist/esm/seki-field.entry.js +1 -1
- package/dist/esm/seki-fieldset.entry.js +1 -1
- package/dist/esm/seki-input.entry.js +1 -1
- package/dist/esm/seki-select-group.entry.js +1 -1
- package/dist/esm/seki-select-option.entry.js +1 -1
- package/dist/esm/seki-select.entry.js +1 -1
- package/dist/esm/seki-skeleton.entry.js +1 -1
- package/dist/esm/seki-tooltip.entry.js +347 -0
- package/dist/esm/sekiui.js +1 -1
- package/dist/sekiui/index.esm.js +1 -1
- package/dist/sekiui/{p-23a61342.entry.js → p-0fba4e2d.entry.js} +1 -1
- package/dist/sekiui/{p-0f64a7dd.entry.js → p-386c00ac.entry.js} +1 -1
- package/dist/sekiui/{p-c878de6d.entry.js → p-431f46a1.entry.js} +1 -1
- package/dist/sekiui/{p-eb19f073.entry.js → p-434be19f.entry.js} +1 -1
- package/dist/sekiui/{p-62236175.entry.js → p-6bde807e.entry.js} +1 -1
- package/dist/sekiui/{p-c93edddc.entry.js → p-6ff91f7f.entry.js} +1 -1
- package/dist/sekiui/{p-4eef5a47.entry.js → p-7c2245be.entry.js} +1 -1
- package/dist/sekiui/{p-aad78e67.entry.js → p-80a41058.entry.js} +1 -1
- package/dist/sekiui/p-81709fc2.entry.js +1 -0
- package/dist/sekiui/{p-5852ad8e.entry.js → p-a36f1ac4.entry.js} +1 -1
- package/dist/sekiui/{p-d7492f49.entry.js → p-a56602b3.entry.js} +1 -1
- package/dist/sekiui/{p-20eb85c9.entry.js → p-bf942ad5.entry.js} +1 -1
- package/dist/sekiui/{p-93d70750.entry.js → p-de4735fb.entry.js} +1 -1
- package/dist/sekiui/{p-0e89720a.entry.js → p-e679d501.entry.js} +1 -1
- package/dist/sekiui/sekiui.esm.js +1 -1
- package/dist/types/components/tooltip/seki-tooltip.d.ts +147 -0
- package/dist/types/components.d.ts +152 -0
- package/package.json +1 -1
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
import { h } from "@stencil/core";
|
|
2
|
+
/**
|
|
3
|
+
* Tooltip Component
|
|
4
|
+
*
|
|
5
|
+
* A fully accessible tooltip component that displays contextual information
|
|
6
|
+
* on hover (desktop) and long-press (touch). Supports rich HTML content,
|
|
7
|
+
* intelligent positioning, keyboard navigation, and dark mode.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```html
|
|
11
|
+
* <seki-tooltip delay="300" side="top">
|
|
12
|
+
* <button slot="trigger">Help</button>
|
|
13
|
+
* <div slot="content">Helpful information</div>
|
|
14
|
+
* </seki-tooltip>
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export class SekiTooltip {
|
|
18
|
+
constructor() {
|
|
19
|
+
/**
|
|
20
|
+
* Milliseconds to delay before showing tooltip on hover
|
|
21
|
+
* @default 0
|
|
22
|
+
* @min 0
|
|
23
|
+
* @max 2000
|
|
24
|
+
*/
|
|
25
|
+
this.delay = 0;
|
|
26
|
+
/**
|
|
27
|
+
* Preferred positioning side for tooltip
|
|
28
|
+
* 'auto' uses intelligent repositioning based on viewport space
|
|
29
|
+
* @default 'auto'
|
|
30
|
+
*/
|
|
31
|
+
this.side = 'auto';
|
|
32
|
+
/**
|
|
33
|
+
* Disable tooltip interactions and visibility
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
this.disabled = false;
|
|
37
|
+
/**
|
|
38
|
+
* Pixels between tooltip and trigger element
|
|
39
|
+
* @default 8
|
|
40
|
+
* @min 0
|
|
41
|
+
*/
|
|
42
|
+
this.offset = 8;
|
|
43
|
+
/**
|
|
44
|
+
* Internal state: whether tooltip is currently visible
|
|
45
|
+
*/
|
|
46
|
+
this.isVisible = false;
|
|
47
|
+
/**
|
|
48
|
+
* Internal state: current calculated position
|
|
49
|
+
*/
|
|
50
|
+
this.currentPosition = 'top';
|
|
51
|
+
// Internal state tracking
|
|
52
|
+
this.showTimer = null;
|
|
53
|
+
this.hideTimer = null;
|
|
54
|
+
this.triggerEl = null;
|
|
55
|
+
this.longPressTimer = null;
|
|
56
|
+
this.touchStartX = 0;
|
|
57
|
+
this.touchStartY = 0;
|
|
58
|
+
/**
|
|
59
|
+
* Handle mouse enter on trigger
|
|
60
|
+
*/
|
|
61
|
+
this.onTriggerMouseEnter = () => {
|
|
62
|
+
if (this.disabled)
|
|
63
|
+
return;
|
|
64
|
+
// Clear hide timer if exists
|
|
65
|
+
if (this.hideTimer) {
|
|
66
|
+
clearTimeout(this.hideTimer);
|
|
67
|
+
this.hideTimer = null;
|
|
68
|
+
}
|
|
69
|
+
// Set show timer with delay
|
|
70
|
+
if (this.showTimer) {
|
|
71
|
+
clearTimeout(this.showTimer);
|
|
72
|
+
}
|
|
73
|
+
this.showTimer = window.setTimeout(() => {
|
|
74
|
+
this.show();
|
|
75
|
+
}, this.delay);
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Handle mouse leave from trigger
|
|
79
|
+
*/
|
|
80
|
+
this.onTriggerMouseLeave = () => {
|
|
81
|
+
// Clear show timer
|
|
82
|
+
if (this.showTimer) {
|
|
83
|
+
clearTimeout(this.showTimer);
|
|
84
|
+
this.showTimer = null;
|
|
85
|
+
}
|
|
86
|
+
// Debounce hide to allow moving back over trigger
|
|
87
|
+
if (this.hideTimer) {
|
|
88
|
+
clearTimeout(this.hideTimer);
|
|
89
|
+
}
|
|
90
|
+
this.hideTimer = window.setTimeout(() => {
|
|
91
|
+
this.hide();
|
|
92
|
+
}, 100);
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Handle focus on trigger (accessibility)
|
|
96
|
+
*/
|
|
97
|
+
this.onTriggerFocus = () => {
|
|
98
|
+
if (this.disabled)
|
|
99
|
+
return;
|
|
100
|
+
// Clear timers
|
|
101
|
+
if (this.showTimer)
|
|
102
|
+
clearTimeout(this.showTimer);
|
|
103
|
+
if (this.hideTimer)
|
|
104
|
+
clearTimeout(this.hideTimer);
|
|
105
|
+
this.showTimer = null;
|
|
106
|
+
this.hideTimer = null;
|
|
107
|
+
// Show immediately on focus (no delay)
|
|
108
|
+
this.show();
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Handle blur from trigger
|
|
112
|
+
*/
|
|
113
|
+
this.onTriggerBlur = () => {
|
|
114
|
+
// Clear timers
|
|
115
|
+
if (this.showTimer)
|
|
116
|
+
clearTimeout(this.showTimer);
|
|
117
|
+
if (this.hideTimer)
|
|
118
|
+
clearTimeout(this.hideTimer);
|
|
119
|
+
this.showTimer = null;
|
|
120
|
+
this.hideTimer = null;
|
|
121
|
+
// Hide immediately on blur
|
|
122
|
+
this.hide();
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Handle touch start (long-press detection)
|
|
126
|
+
*/
|
|
127
|
+
this.onTriggerTouchStart = (e) => {
|
|
128
|
+
if (this.disabled || !e.touches[0])
|
|
129
|
+
return;
|
|
130
|
+
this.touchStartX = e.touches[0].clientX;
|
|
131
|
+
this.touchStartY = e.touches[0].clientY;
|
|
132
|
+
// Start long-press timer (500ms)
|
|
133
|
+
if (this.longPressTimer)
|
|
134
|
+
clearTimeout(this.longPressTimer);
|
|
135
|
+
this.longPressTimer = window.setTimeout(() => {
|
|
136
|
+
this.show();
|
|
137
|
+
}, 500);
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Handle touch move (cancel long-press if movement > 10px)
|
|
141
|
+
*/
|
|
142
|
+
this.onTriggerTouchMove = (e) => {
|
|
143
|
+
if (!e.touches[0] || !this.longPressTimer)
|
|
144
|
+
return;
|
|
145
|
+
const dx = Math.abs(e.touches[0].clientX - this.touchStartX);
|
|
146
|
+
const dy = Math.abs(e.touches[0].clientY - this.touchStartY);
|
|
147
|
+
if (dx > 10 || dy > 10) {
|
|
148
|
+
// Movement too large, cancel long-press
|
|
149
|
+
clearTimeout(this.longPressTimer);
|
|
150
|
+
this.longPressTimer = null;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Handle touch end (cancel long-press if not yet fired)
|
|
155
|
+
*/
|
|
156
|
+
this.onTriggerTouchEnd = () => {
|
|
157
|
+
if (this.longPressTimer) {
|
|
158
|
+
clearTimeout(this.longPressTimer);
|
|
159
|
+
this.longPressTimer = null;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Handle Escape key to dismiss tooltip
|
|
164
|
+
*/
|
|
165
|
+
this.onEscapeKey = (event) => {
|
|
166
|
+
if (event.key === 'Escape' && this.isVisible) {
|
|
167
|
+
event.preventDefault();
|
|
168
|
+
this.hide();
|
|
169
|
+
// Keep focus on trigger
|
|
170
|
+
const trigger = this.el.querySelector('[slot="trigger"]');
|
|
171
|
+
if (trigger) {
|
|
172
|
+
trigger.focus();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Show tooltip programmatically
|
|
179
|
+
* @returns Promise resolves when tooltip is visible
|
|
180
|
+
*/
|
|
181
|
+
async show() {
|
|
182
|
+
if (this.disabled)
|
|
183
|
+
return;
|
|
184
|
+
// Clear any pending hide timer
|
|
185
|
+
if (this.hideTimer) {
|
|
186
|
+
clearTimeout(this.hideTimer);
|
|
187
|
+
this.hideTimer = null;
|
|
188
|
+
}
|
|
189
|
+
// Set visible state
|
|
190
|
+
this.isVisible = true;
|
|
191
|
+
// Calculate position
|
|
192
|
+
this.calculatePosition();
|
|
193
|
+
// Emit show event
|
|
194
|
+
this.showTooltip.emit({ triggerEl: this.triggerEl || this.el });
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Hide tooltip programmatically
|
|
198
|
+
* @returns Promise resolves when tooltip is hidden
|
|
199
|
+
*/
|
|
200
|
+
async hide() {
|
|
201
|
+
// Clear any pending show timer
|
|
202
|
+
if (this.showTimer) {
|
|
203
|
+
clearTimeout(this.showTimer);
|
|
204
|
+
this.showTimer = null;
|
|
205
|
+
}
|
|
206
|
+
// Set hidden state
|
|
207
|
+
this.isVisible = false;
|
|
208
|
+
// Emit hide event
|
|
209
|
+
this.hideTooltip.emit({ reason: 'blur' });
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Recalculate tooltip position
|
|
213
|
+
* Call after trigger element moves or window resizes
|
|
214
|
+
*/
|
|
215
|
+
async updatePosition() {
|
|
216
|
+
if (this.isVisible) {
|
|
217
|
+
this.calculatePosition();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Calculate tooltip position based on viewport
|
|
222
|
+
*/
|
|
223
|
+
calculatePosition() {
|
|
224
|
+
var _a;
|
|
225
|
+
// Get trigger element
|
|
226
|
+
const trigger = this.el.querySelector('[slot="trigger"]');
|
|
227
|
+
if (!trigger)
|
|
228
|
+
return;
|
|
229
|
+
this.triggerEl = trigger;
|
|
230
|
+
// Get tooltip element from shadow DOM
|
|
231
|
+
const tooltip = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.tooltip');
|
|
232
|
+
if (!tooltip)
|
|
233
|
+
return;
|
|
234
|
+
// Get trigger bounds
|
|
235
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
236
|
+
const tooltipRect = tooltip.getBoundingClientRect();
|
|
237
|
+
const viewport = {
|
|
238
|
+
width: window.innerWidth,
|
|
239
|
+
height: window.innerHeight,
|
|
240
|
+
};
|
|
241
|
+
// Calculate positions
|
|
242
|
+
const positions = {
|
|
243
|
+
top: {
|
|
244
|
+
x: triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2,
|
|
245
|
+
y: triggerRect.top - tooltipRect.height - this.offset,
|
|
246
|
+
},
|
|
247
|
+
bottom: {
|
|
248
|
+
x: triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2,
|
|
249
|
+
y: triggerRect.top + triggerRect.height + this.offset,
|
|
250
|
+
},
|
|
251
|
+
left: {
|
|
252
|
+
x: triggerRect.left - tooltipRect.width - this.offset,
|
|
253
|
+
y: triggerRect.top + triggerRect.height / 2 - tooltipRect.height / 2,
|
|
254
|
+
},
|
|
255
|
+
right: {
|
|
256
|
+
x: triggerRect.left + triggerRect.width + this.offset,
|
|
257
|
+
y: triggerRect.top + triggerRect.height / 2 - tooltipRect.height / 2,
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
// Check each position for viewport fit (8px margin minimum)
|
|
261
|
+
const margin = 8;
|
|
262
|
+
for (const [sideKey, pos] of Object.entries(positions)) {
|
|
263
|
+
const fits = pos.x >= margin &&
|
|
264
|
+
pos.x + tooltipRect.width <= viewport.width - margin &&
|
|
265
|
+
pos.y >= margin &&
|
|
266
|
+
pos.y + tooltipRect.height <= viewport.height - margin;
|
|
267
|
+
if (fits) {
|
|
268
|
+
this.currentPosition = sideKey;
|
|
269
|
+
this.applyPosition(tooltip, pos);
|
|
270
|
+
this.positioned.emit({ side: this.currentPosition, offset: this.offset });
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
// Fallback: use preferred side, clamp to viewport
|
|
275
|
+
const preferredSide = this.side === 'auto' ? 'top' : this.side;
|
|
276
|
+
const pos = positions[preferredSide] || positions.top;
|
|
277
|
+
this.currentPosition = preferredSide;
|
|
278
|
+
// Clamp to viewport
|
|
279
|
+
pos.x = Math.max(margin, Math.min(pos.x, viewport.width - tooltipRect.width - margin));
|
|
280
|
+
pos.y = Math.max(margin, Math.min(pos.y, viewport.height - tooltipRect.height - margin));
|
|
281
|
+
this.applyPosition(tooltip, pos);
|
|
282
|
+
this.positioned.emit({ side: this.currentPosition, offset: this.offset });
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Apply calculated position to tooltip element
|
|
286
|
+
*/
|
|
287
|
+
applyPosition(tooltip, pos) {
|
|
288
|
+
tooltip.style.position = 'fixed';
|
|
289
|
+
tooltip.style.left = `${pos.x}px`;
|
|
290
|
+
tooltip.style.top = `${pos.y}px`;
|
|
291
|
+
tooltip.style.zIndex = '1000';
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Attach event listeners to trigger
|
|
295
|
+
*/
|
|
296
|
+
attachTriggerListeners() {
|
|
297
|
+
const trigger = this.el.querySelector('[slot="trigger"]');
|
|
298
|
+
if (!trigger)
|
|
299
|
+
return;
|
|
300
|
+
// Mouse events
|
|
301
|
+
trigger.addEventListener('mouseenter', this.onTriggerMouseEnter);
|
|
302
|
+
trigger.addEventListener('mouseleave', this.onTriggerMouseLeave);
|
|
303
|
+
// Keyboard events (focus/blur)
|
|
304
|
+
trigger.addEventListener('focus', this.onTriggerFocus);
|
|
305
|
+
trigger.addEventListener('blur', this.onTriggerBlur);
|
|
306
|
+
// Touch events (long-press)
|
|
307
|
+
trigger.addEventListener('touchstart', this.onTriggerTouchStart);
|
|
308
|
+
trigger.addEventListener('touchmove', this.onTriggerTouchMove);
|
|
309
|
+
trigger.addEventListener('touchend', this.onTriggerTouchEnd);
|
|
310
|
+
// Escape key on document
|
|
311
|
+
document.addEventListener('keydown', this.onEscapeKey);
|
|
312
|
+
// Apply aria-describedby to trigger
|
|
313
|
+
const contentSlot = this.el.querySelector('[slot="content"]');
|
|
314
|
+
if (contentSlot) {
|
|
315
|
+
const contentId = `tooltip-${Math.random().toString(36).substr(2, 9)}`;
|
|
316
|
+
contentSlot.id = contentId;
|
|
317
|
+
trigger.setAttribute('aria-describedby', contentId);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Remove event listeners from trigger
|
|
322
|
+
*/
|
|
323
|
+
detachTriggerListeners() {
|
|
324
|
+
const trigger = this.el.querySelector('[slot="trigger"]');
|
|
325
|
+
if (!trigger)
|
|
326
|
+
return;
|
|
327
|
+
trigger.removeEventListener('mouseenter', this.onTriggerMouseEnter);
|
|
328
|
+
trigger.removeEventListener('mouseleave', this.onTriggerMouseLeave);
|
|
329
|
+
trigger.removeEventListener('focus', this.onTriggerFocus);
|
|
330
|
+
trigger.removeEventListener('blur', this.onTriggerBlur);
|
|
331
|
+
trigger.removeEventListener('touchstart', this.onTriggerTouchStart);
|
|
332
|
+
trigger.removeEventListener('touchmove', this.onTriggerTouchMove);
|
|
333
|
+
trigger.removeEventListener('touchend', this.onTriggerTouchEnd);
|
|
334
|
+
}
|
|
335
|
+
componentDidLoad() {
|
|
336
|
+
this.attachTriggerListeners();
|
|
337
|
+
}
|
|
338
|
+
disconnectedCallback() {
|
|
339
|
+
this.detachTriggerListeners();
|
|
340
|
+
// Clean up timers
|
|
341
|
+
if (this.showTimer)
|
|
342
|
+
clearTimeout(this.showTimer);
|
|
343
|
+
if (this.hideTimer)
|
|
344
|
+
clearTimeout(this.hideTimer);
|
|
345
|
+
if (this.longPressTimer)
|
|
346
|
+
clearTimeout(this.longPressTimer);
|
|
347
|
+
}
|
|
348
|
+
render() {
|
|
349
|
+
return (h("div", { key: '26ad92440881dc154c9fd364dd59d621eb949ba1', class: `tooltip ${this.isVisible ? 'tooltip--visible' : ''}`, role: "tooltip" }, h("slot", { key: 'f08dda70ba8fb3dc936e62c3fee51ddf60cd7585', name: "content" }), h("div", { key: '14daf9b8dcd099f01c6d4fb704c9dd4bc5081dc7', class: "tooltip-arrow" })));
|
|
350
|
+
}
|
|
351
|
+
static get is() { return "seki-tooltip"; }
|
|
352
|
+
static get encapsulation() { return "shadow"; }
|
|
353
|
+
static get originalStyleUrls() {
|
|
354
|
+
return {
|
|
355
|
+
"$": ["seki-tooltip.css"]
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
static get styleUrls() {
|
|
359
|
+
return {
|
|
360
|
+
"$": ["seki-tooltip.css"]
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
static get properties() {
|
|
364
|
+
return {
|
|
365
|
+
"delay": {
|
|
366
|
+
"type": "number",
|
|
367
|
+
"mutable": false,
|
|
368
|
+
"complexType": {
|
|
369
|
+
"original": "number",
|
|
370
|
+
"resolved": "number",
|
|
371
|
+
"references": {}
|
|
372
|
+
},
|
|
373
|
+
"required": false,
|
|
374
|
+
"optional": false,
|
|
375
|
+
"docs": {
|
|
376
|
+
"tags": [{
|
|
377
|
+
"name": "default",
|
|
378
|
+
"text": "0"
|
|
379
|
+
}, {
|
|
380
|
+
"name": "min",
|
|
381
|
+
"text": "0"
|
|
382
|
+
}, {
|
|
383
|
+
"name": "max",
|
|
384
|
+
"text": "2000"
|
|
385
|
+
}],
|
|
386
|
+
"text": "Milliseconds to delay before showing tooltip on hover"
|
|
387
|
+
},
|
|
388
|
+
"getter": false,
|
|
389
|
+
"setter": false,
|
|
390
|
+
"reflect": false,
|
|
391
|
+
"attribute": "delay",
|
|
392
|
+
"defaultValue": "0"
|
|
393
|
+
},
|
|
394
|
+
"side": {
|
|
395
|
+
"type": "string",
|
|
396
|
+
"mutable": false,
|
|
397
|
+
"complexType": {
|
|
398
|
+
"original": "TooltipSide",
|
|
399
|
+
"resolved": "\"auto\" | \"bottom\" | \"left\" | \"right\" | \"top\"",
|
|
400
|
+
"references": {
|
|
401
|
+
"TooltipSide": {
|
|
402
|
+
"location": "local",
|
|
403
|
+
"path": "/home/runner/work/seki-ui/seki-ui/src/components/tooltip/seki-tooltip.tsx",
|
|
404
|
+
"id": "src/components/tooltip/seki-tooltip.tsx::TooltipSide"
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
"required": false,
|
|
409
|
+
"optional": false,
|
|
410
|
+
"docs": {
|
|
411
|
+
"tags": [{
|
|
412
|
+
"name": "default",
|
|
413
|
+
"text": "'auto'"
|
|
414
|
+
}],
|
|
415
|
+
"text": "Preferred positioning side for tooltip\n'auto' uses intelligent repositioning based on viewport space"
|
|
416
|
+
},
|
|
417
|
+
"getter": false,
|
|
418
|
+
"setter": false,
|
|
419
|
+
"reflect": false,
|
|
420
|
+
"attribute": "side",
|
|
421
|
+
"defaultValue": "'auto'"
|
|
422
|
+
},
|
|
423
|
+
"disabled": {
|
|
424
|
+
"type": "boolean",
|
|
425
|
+
"mutable": false,
|
|
426
|
+
"complexType": {
|
|
427
|
+
"original": "boolean",
|
|
428
|
+
"resolved": "boolean",
|
|
429
|
+
"references": {}
|
|
430
|
+
},
|
|
431
|
+
"required": false,
|
|
432
|
+
"optional": false,
|
|
433
|
+
"docs": {
|
|
434
|
+
"tags": [{
|
|
435
|
+
"name": "default",
|
|
436
|
+
"text": "false"
|
|
437
|
+
}],
|
|
438
|
+
"text": "Disable tooltip interactions and visibility"
|
|
439
|
+
},
|
|
440
|
+
"getter": false,
|
|
441
|
+
"setter": false,
|
|
442
|
+
"reflect": false,
|
|
443
|
+
"attribute": "disabled",
|
|
444
|
+
"defaultValue": "false"
|
|
445
|
+
},
|
|
446
|
+
"offset": {
|
|
447
|
+
"type": "number",
|
|
448
|
+
"mutable": false,
|
|
449
|
+
"complexType": {
|
|
450
|
+
"original": "number",
|
|
451
|
+
"resolved": "number",
|
|
452
|
+
"references": {}
|
|
453
|
+
},
|
|
454
|
+
"required": false,
|
|
455
|
+
"optional": false,
|
|
456
|
+
"docs": {
|
|
457
|
+
"tags": [{
|
|
458
|
+
"name": "default",
|
|
459
|
+
"text": "8"
|
|
460
|
+
}, {
|
|
461
|
+
"name": "min",
|
|
462
|
+
"text": "0"
|
|
463
|
+
}],
|
|
464
|
+
"text": "Pixels between tooltip and trigger element"
|
|
465
|
+
},
|
|
466
|
+
"getter": false,
|
|
467
|
+
"setter": false,
|
|
468
|
+
"reflect": false,
|
|
469
|
+
"attribute": "offset",
|
|
470
|
+
"defaultValue": "8"
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
static get states() {
|
|
475
|
+
return {
|
|
476
|
+
"isVisible": {},
|
|
477
|
+
"currentPosition": {}
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
static get events() {
|
|
481
|
+
return [{
|
|
482
|
+
"method": "showTooltip",
|
|
483
|
+
"name": "showTooltip",
|
|
484
|
+
"bubbles": true,
|
|
485
|
+
"cancelable": true,
|
|
486
|
+
"composed": true,
|
|
487
|
+
"docs": {
|
|
488
|
+
"tags": [],
|
|
489
|
+
"text": "Event emitted when tooltip becomes visible"
|
|
490
|
+
},
|
|
491
|
+
"complexType": {
|
|
492
|
+
"original": "TooltipShowDetail",
|
|
493
|
+
"resolved": "TooltipShowDetail",
|
|
494
|
+
"references": {
|
|
495
|
+
"TooltipShowDetail": {
|
|
496
|
+
"location": "local",
|
|
497
|
+
"path": "/home/runner/work/seki-ui/seki-ui/src/components/tooltip/seki-tooltip.tsx",
|
|
498
|
+
"id": "src/components/tooltip/seki-tooltip.tsx::TooltipShowDetail"
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}, {
|
|
503
|
+
"method": "hideTooltip",
|
|
504
|
+
"name": "hideTooltip",
|
|
505
|
+
"bubbles": true,
|
|
506
|
+
"cancelable": true,
|
|
507
|
+
"composed": true,
|
|
508
|
+
"docs": {
|
|
509
|
+
"tags": [],
|
|
510
|
+
"text": "Event emitted when tooltip becomes hidden"
|
|
511
|
+
},
|
|
512
|
+
"complexType": {
|
|
513
|
+
"original": "TooltipHideDetail",
|
|
514
|
+
"resolved": "TooltipHideDetail",
|
|
515
|
+
"references": {
|
|
516
|
+
"TooltipHideDetail": {
|
|
517
|
+
"location": "local",
|
|
518
|
+
"path": "/home/runner/work/seki-ui/seki-ui/src/components/tooltip/seki-tooltip.tsx",
|
|
519
|
+
"id": "src/components/tooltip/seki-tooltip.tsx::TooltipHideDetail"
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}, {
|
|
524
|
+
"method": "positioned",
|
|
525
|
+
"name": "positioned",
|
|
526
|
+
"bubbles": true,
|
|
527
|
+
"cancelable": true,
|
|
528
|
+
"composed": true,
|
|
529
|
+
"docs": {
|
|
530
|
+
"tags": [],
|
|
531
|
+
"text": "Event emitted after tooltip position is calculated"
|
|
532
|
+
},
|
|
533
|
+
"complexType": {
|
|
534
|
+
"original": "TooltipPositionedDetail",
|
|
535
|
+
"resolved": "TooltipPositionedDetail",
|
|
536
|
+
"references": {
|
|
537
|
+
"TooltipPositionedDetail": {
|
|
538
|
+
"location": "local",
|
|
539
|
+
"path": "/home/runner/work/seki-ui/seki-ui/src/components/tooltip/seki-tooltip.tsx",
|
|
540
|
+
"id": "src/components/tooltip/seki-tooltip.tsx::TooltipPositionedDetail"
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}];
|
|
545
|
+
}
|
|
546
|
+
static get methods() {
|
|
547
|
+
return {
|
|
548
|
+
"show": {
|
|
549
|
+
"complexType": {
|
|
550
|
+
"signature": "() => Promise<void>",
|
|
551
|
+
"parameters": [],
|
|
552
|
+
"references": {
|
|
553
|
+
"Promise": {
|
|
554
|
+
"location": "global",
|
|
555
|
+
"id": "global::Promise"
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
"return": "Promise<void>"
|
|
559
|
+
},
|
|
560
|
+
"docs": {
|
|
561
|
+
"text": "Show tooltip programmatically",
|
|
562
|
+
"tags": [{
|
|
563
|
+
"name": "returns",
|
|
564
|
+
"text": "Promise resolves when tooltip is visible"
|
|
565
|
+
}]
|
|
566
|
+
}
|
|
567
|
+
},
|
|
568
|
+
"hide": {
|
|
569
|
+
"complexType": {
|
|
570
|
+
"signature": "() => Promise<void>",
|
|
571
|
+
"parameters": [],
|
|
572
|
+
"references": {
|
|
573
|
+
"Promise": {
|
|
574
|
+
"location": "global",
|
|
575
|
+
"id": "global::Promise"
|
|
576
|
+
}
|
|
577
|
+
},
|
|
578
|
+
"return": "Promise<void>"
|
|
579
|
+
},
|
|
580
|
+
"docs": {
|
|
581
|
+
"text": "Hide tooltip programmatically",
|
|
582
|
+
"tags": [{
|
|
583
|
+
"name": "returns",
|
|
584
|
+
"text": "Promise resolves when tooltip is hidden"
|
|
585
|
+
}]
|
|
586
|
+
}
|
|
587
|
+
},
|
|
588
|
+
"updatePosition": {
|
|
589
|
+
"complexType": {
|
|
590
|
+
"signature": "() => Promise<void>",
|
|
591
|
+
"parameters": [],
|
|
592
|
+
"references": {
|
|
593
|
+
"Promise": {
|
|
594
|
+
"location": "global",
|
|
595
|
+
"id": "global::Promise"
|
|
596
|
+
}
|
|
597
|
+
},
|
|
598
|
+
"return": "Promise<void>"
|
|
599
|
+
},
|
|
600
|
+
"docs": {
|
|
601
|
+
"text": "Recalculate tooltip position\nCall after trigger element moves or window resizes",
|
|
602
|
+
"tags": []
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
static get elementRef() { return "el"; }
|
|
608
|
+
}
|
package/dist/components/index.js
CHANGED
|
@@ -81,7 +81,7 @@ const SekiSwitch = /*@__PURE__*/ proxyCustomElement(class SekiSwitch extends H {
|
|
|
81
81
|
render() {
|
|
82
82
|
const isChecked = this.isChecked;
|
|
83
83
|
const dataState = isChecked ? 'checked' : 'unchecked';
|
|
84
|
-
return (h(Host, { key: '
|
|
84
|
+
return (h(Host, { key: '3046a6647d7cfd10bf9789aa9cf3b7a88b9a3a10', "data-state": dataState, "data-disabled": this.disabled ? '' : null }, h("div", { key: 'cd8423b9f7295e5e3ef9d7e64ead3fe6502386a2', class: "switch", part: "switch", role: "switch", "aria-checked": isChecked ? 'true' : 'false', "aria-disabled": this.disabled ? 'true' : undefined, "aria-label": this.ariaLabel || undefined, "aria-required": this.required ? 'true' : undefined, tabindex: this.disabled ? -1 : 0, onClick: this.handleClick }, h("span", { key: '618ab67d5fab80323f64ec0b1b342561be2585b0', class: "thumb", part: "thumb" })), this.name && (h("input", { key: 'd51e9108038b8796175082231ca3ce7e61106f31', type: "checkbox", name: this.name, value: this.value, checked: isChecked, required: this.required, disabled: this.disabled, style: { display: 'none' }, tabindex: -1, "aria-hidden": "true" }))));
|
|
85
85
|
}
|
|
86
86
|
static get style() { return sekiSwitchCss; }
|
|
87
87
|
}, [257, "seki-switch", {
|
|
@@ -35,7 +35,7 @@ const SekiButton$1 = /*@__PURE__*/ proxyCustomElement(class SekiButton extends H
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
render() {
|
|
38
|
-
return (h("button", { key: '
|
|
38
|
+
return (h("button", { key: '17841111481259910cd72cdcb861872918c86452', class: `button button--${this.variant} button--${this.size}`, type: this.type, disabled: this.disabled, "aria-disabled": this.disabled ? 'true' : null, "aria-label": this.ariaLabel }, h("slot", { key: '1a4dfb3cb9eb88af7065cd765c0056a93c94ecc1' })));
|
|
39
39
|
}
|
|
40
40
|
static get style() { return sekiButtonCss; }
|
|
41
41
|
}, [257, "seki-button", {
|
|
@@ -37,7 +37,7 @@ const SekiFieldDescription$1 = /*@__PURE__*/ proxyCustomElement(class SekiFieldD
|
|
|
37
37
|
return this.componentId;
|
|
38
38
|
}
|
|
39
39
|
render() {
|
|
40
|
-
return (h("div", { key: '
|
|
40
|
+
return (h("div", { key: '944a6268efe02b6b69725daf7503a9bcf8482f94', id: this.componentId, class: "description" }, h("slot", { key: '900d5afcf9662fe2e8f32acf55b21823389dbb59' })));
|
|
41
41
|
}
|
|
42
42
|
static get style() { return sekiFieldDescriptionCss; }
|
|
43
43
|
}, [257, "seki-field-description", {
|
|
@@ -57,7 +57,7 @@ const SekiFieldError$1 = /*@__PURE__*/ proxyCustomElement(class SekiFieldError e
|
|
|
57
57
|
}
|
|
58
58
|
render() {
|
|
59
59
|
const style = this.visible ? {} : { display: 'none' };
|
|
60
|
-
return (h("div", { key: '
|
|
60
|
+
return (h("div", { key: '23898d8cdf6e79e0710776895ac8a36c06262524', id: this.componentId, class: "error", "aria-live": "polite", style: style }, h("slot", { key: '7c40a36d065602eb635180ed0805bca9216c5015' })));
|
|
61
61
|
}
|
|
62
62
|
static get watchers() { return {
|
|
63
63
|
"visible": ["handleVisibleChange"]
|
|
@@ -19,7 +19,7 @@ const SekiFieldGroup$1 = /*@__PURE__*/ proxyCustomElement(class SekiFieldGroup e
|
|
|
19
19
|
const style = {
|
|
20
20
|
'--seki-field-group-gap': this.gap,
|
|
21
21
|
};
|
|
22
|
-
return (h("div", { key: '
|
|
22
|
+
return (h("div", { key: '32e2881723467de4e83135f38f339bd1334ea19f', class: "field-group", style: style }, h("slot", { key: '3909c9108222772376d916718003600d9d84f10f' })));
|
|
23
23
|
}
|
|
24
24
|
static get style() { return sekiFieldGroupCss; }
|
|
25
25
|
}, [257, "seki-field-group", {
|
|
@@ -17,7 +17,7 @@ const SekiFieldLabel$1 = /*@__PURE__*/ proxyCustomElement(class SekiFieldLabel e
|
|
|
17
17
|
}
|
|
18
18
|
render() {
|
|
19
19
|
const labelProps = this.htmlFor ? { for: this.htmlFor } : {};
|
|
20
|
-
return (h("label", Object.assign({ key: '
|
|
20
|
+
return (h("label", Object.assign({ key: 'c57011f8722920f073fc05ae3b260e581689c43e' }, labelProps), h("slot", { key: '6e807e411376526b20cf66d694766ce11065b734' }), this.required && h("span", { key: '53d676c377fa93c6d41c50856b4db598cf3c2c15', class: "required-indicator" }, " *")));
|
|
21
21
|
}
|
|
22
22
|
static get style() { return sekiFieldLabelCss; }
|
|
23
23
|
}, [257, "seki-field-label", {
|
|
@@ -11,7 +11,7 @@ const SekiFieldLegend$1 = /*@__PURE__*/ proxyCustomElement(class SekiFieldLegend
|
|
|
11
11
|
this.__attachShadow();
|
|
12
12
|
}
|
|
13
13
|
render() {
|
|
14
|
-
return (h("legend", { key: '
|
|
14
|
+
return (h("legend", { key: 'adcc0cb95335522fc66dc791a3cc063d2493c36b' }, h("slot", { key: '90a382f1eac9b23133f8daf927a2163491f09c38' })));
|
|
15
15
|
}
|
|
16
16
|
static get style() { return sekiFieldLegendCss; }
|
|
17
17
|
}, [257, "seki-field-legend"]);
|