@superleapai/flow-ui 2.5.7 → 2.5.8
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/components/label.js +23 -1
- package/components/record-multiselect.js +5 -4
- package/components/record-select.js +5 -4
- package/components/richtext-editor.js +3 -4
- package/components/tooltip.js +186 -0
- package/core/flow.js +24 -7
- package/dist/output.css +1 -1
- package/dist/superleap-flow.min.js +2 -2
- package/index.js +1 -0
- package/package.json +1 -1
package/components/label.js
CHANGED
|
@@ -30,8 +30,11 @@
|
|
|
30
30
|
return parts.join(" ");
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
var INFO_ICON_SVG =
|
|
34
|
+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-info-circle"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0" /><path d="M12 9h.01" /><path d="M11 12h1v4h1" /></svg>';
|
|
35
|
+
|
|
33
36
|
/**
|
|
34
|
-
* Create a label element matching the Radix Label API (size, requiredPosition, optional, icon).
|
|
37
|
+
* Create a label element matching the Radix Label API (size, requiredPosition, optional, icon, helpText).
|
|
35
38
|
* @param {Object} config
|
|
36
39
|
* @param {string} config.label - Label text
|
|
37
40
|
* @param {boolean} [config.required=false] - Show required asterisk
|
|
@@ -39,6 +42,7 @@
|
|
|
39
42
|
* @param {boolean} [config.optional=false] - Show "(optional)" after label
|
|
40
43
|
* @param {string} [config.size='default'] - 'default' | 'small' | 'large'
|
|
41
44
|
* @param {HTMLElement} [config.icon] - Optional icon node
|
|
45
|
+
* @param {string} [config.helpText] - Optional help text; when set, shows info icon after required with Tooltip
|
|
42
46
|
* @param {string} [config.className] - Extra classes
|
|
43
47
|
* @param {string} [config.htmlFor] - For attribute
|
|
44
48
|
* @param {HTMLElement} [config.suffix] - Optional node appended after content (e.g. tooltip)
|
|
@@ -51,6 +55,7 @@
|
|
|
51
55
|
var optional = !!config.optional;
|
|
52
56
|
var size = config.size || "default";
|
|
53
57
|
var icon = config.icon;
|
|
58
|
+
var helpText = config.helpText != null ? String(config.helpText) : "";
|
|
54
59
|
var className = config.className || "";
|
|
55
60
|
var htmlFor = config.htmlFor;
|
|
56
61
|
var suffix = config.suffix;
|
|
@@ -95,6 +100,23 @@
|
|
|
95
100
|
labelEl.appendChild(rightAsterisk);
|
|
96
101
|
}
|
|
97
102
|
|
|
103
|
+
if (helpText) {
|
|
104
|
+
var infoWrap = document.createElement("span");
|
|
105
|
+
infoWrap.className = "box-content flex ml-4 size-16 items-center justify-center shrink-0 text-typography-tertiary-text cursor-pointer";
|
|
106
|
+
infoWrap.innerHTML = INFO_ICON_SVG;
|
|
107
|
+
var Tooltip =
|
|
108
|
+
(global.FlowUI && typeof global.FlowUI._getComponent === "function" && global.FlowUI._getComponent("Tooltip")) ||
|
|
109
|
+
global.Tooltip ||
|
|
110
|
+
(typeof window !== "undefined" && window.Tooltip);
|
|
111
|
+
if (Tooltip && typeof Tooltip.create === "function") {
|
|
112
|
+
var tooltipEl = Tooltip.create({ content: helpText, trigger: infoWrap, placement: "top" });
|
|
113
|
+
labelEl.appendChild(tooltipEl);
|
|
114
|
+
} else {
|
|
115
|
+
infoWrap.setAttribute("title", helpText);
|
|
116
|
+
labelEl.appendChild(infoWrap);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
98
120
|
if (optional) {
|
|
99
121
|
var optionalSpan = document.createElement("span");
|
|
100
122
|
optionalSpan.className = "optional-label text-typography-tertiary-text";
|
|
@@ -43,6 +43,8 @@
|
|
|
43
43
|
var CHECK_SVG =
|
|
44
44
|
'<svg width="14" height="14" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M11.4669 3.72684C11.7558 3.41574 12.2442 3.41574 12.5331 3.72684C12.822 4.03795 12.822 4.53753 12.5331 4.84863L6.81767 10.6736C6.52329 10.9901 6.05308 10.9901 5.7587 10.6736L2.46685 7.3463C2.17795 7.03519 2.17795 6.53561 2.46685 6.2245C2.75575 5.9134 3.24395 5.9134 3.53285 6.2245L6.28822 9.05351L11.4669 3.72684Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"/></svg>';
|
|
45
45
|
|
|
46
|
+
var SEARCH_FIELD = "search_field";
|
|
47
|
+
|
|
46
48
|
var SEARCH_ICON =
|
|
47
49
|
'<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>';
|
|
48
50
|
|
|
@@ -473,10 +475,9 @@
|
|
|
473
475
|
}
|
|
474
476
|
if (search && search.trim()) {
|
|
475
477
|
filters.push({
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
],
|
|
478
|
+
field: SEARCH_FIELD,
|
|
479
|
+
operator: "contains",
|
|
480
|
+
value: search.trim(),
|
|
480
481
|
});
|
|
481
482
|
}
|
|
482
483
|
if (filters.length > 0) {
|
|
@@ -46,6 +46,8 @@
|
|
|
46
46
|
var X_SVG =
|
|
47
47
|
'<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" xmlns="http://www.w3.org/2000/svg"><path d="M18 6L6 18M6 6l12 12"/></svg>';
|
|
48
48
|
|
|
49
|
+
var SEARCH_FIELD = "search_field";
|
|
50
|
+
|
|
49
51
|
var SEARCH_ICON =
|
|
50
52
|
'<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>';
|
|
51
53
|
|
|
@@ -552,10 +554,9 @@
|
|
|
552
554
|
}
|
|
553
555
|
if (search && search.trim()) {
|
|
554
556
|
filters.push({
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
],
|
|
557
|
+
field: SEARCH_FIELD,
|
|
558
|
+
operator: "contains",
|
|
559
|
+
value: search.trim(),
|
|
559
560
|
});
|
|
560
561
|
}
|
|
561
562
|
if (filters.length > 0) {
|
|
@@ -76,7 +76,6 @@
|
|
|
76
76
|
* @param {Object} config
|
|
77
77
|
* @param {string} [config.value] - Initial HTML content
|
|
78
78
|
* @param {string} [config.placeholder] - Placeholder when empty
|
|
79
|
-
* @param {number} [config.minHeightPx] - Min height of editor area (default 400)
|
|
80
79
|
* @param {boolean} [config.disabled]
|
|
81
80
|
* @param {Function} [config.onChange] - (html: string) => void
|
|
82
81
|
* @returns {HTMLElement} Wrapper element with getValue/setValue/setDisabled/getInput
|
|
@@ -84,7 +83,6 @@
|
|
|
84
83
|
function create(config) {
|
|
85
84
|
var value = config.value != null ? String(config.value) : "";
|
|
86
85
|
var placeholder = config.placeholder != null ? config.placeholder : "";
|
|
87
|
-
var minHeightPx = config.minHeightPx != null ? config.minHeightPx : 400;
|
|
88
86
|
var disabled = !!config.disabled;
|
|
89
87
|
var onChange = config.onChange;
|
|
90
88
|
|
|
@@ -103,9 +101,10 @@
|
|
|
103
101
|
var editorEl = document.createElement("div");
|
|
104
102
|
editorEl.contentEditable = !disabled;
|
|
105
103
|
editorEl.className = join(
|
|
106
|
-
"rich-text-editor-content max-w-none rounded-b-12 border-t border-borderColor-border-primary p-8 text-reg-14 text-typography-primary-text"
|
|
104
|
+
"rich-text-editor-content max-w-none rounded-b-12 border-t border-borderColor-border-primary p-8 text-reg-14 text-typography-primary-text overflow-y-auto"
|
|
107
105
|
);
|
|
108
|
-
editorEl.style.minHeight =
|
|
106
|
+
editorEl.style.minHeight = "15vh";
|
|
107
|
+
editorEl.style.maxHeight = "20vh";
|
|
109
108
|
if (value) editorEl.innerHTML = value;
|
|
110
109
|
editorEl.setAttribute("data-placeholder", placeholder);
|
|
111
110
|
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tooltip Component (vanilla JS)
|
|
3
|
+
* Shows a short label on hover/focus of a trigger element.
|
|
4
|
+
* Uses same styling conventions as Badge/Label (border-border-primary, typography, etc.).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
(function (global) {
|
|
8
|
+
"use strict";
|
|
9
|
+
|
|
10
|
+
var TOOLTIP_BASE =
|
|
11
|
+
"absolute z-50 rounded-4 border-1/2 border-black text-typography-invert-text shadow-default-medium px-8 py-6 text-reg-10 leading-5 max-w-[80vw] whitespace-normal break-words pointer-events-none";
|
|
12
|
+
|
|
13
|
+
var ARROW_SIZE = 6;
|
|
14
|
+
var TOOLTIP_BG = "var(--color-neutral-900)";
|
|
15
|
+
|
|
16
|
+
function join() {
|
|
17
|
+
return Array.prototype.filter.call(arguments, Boolean).join(" ");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function positionTooltip(triggerRect, tooltipEl, placement) {
|
|
21
|
+
var style = tooltipEl.style;
|
|
22
|
+
style.position = "fixed";
|
|
23
|
+
var cx = triggerRect.left + triggerRect.width / 2;
|
|
24
|
+
var cy = triggerRect.top + triggerRect.height / 2;
|
|
25
|
+
var gap = 4;
|
|
26
|
+
if (placement === "top") {
|
|
27
|
+
style.left = cx + "px";
|
|
28
|
+
style.top = triggerRect.top + "px";
|
|
29
|
+
style.transform = "translate(-50%, -100%) translateY(-" + gap + "px)";
|
|
30
|
+
} else if (placement === "bottom") {
|
|
31
|
+
style.left = cx + "px";
|
|
32
|
+
style.top = triggerRect.bottom + "px";
|
|
33
|
+
style.transform = "translate(-50%, " + gap + "px)";
|
|
34
|
+
} else if (placement === "left") {
|
|
35
|
+
style.left = triggerRect.left + "px";
|
|
36
|
+
style.top = cy + "px";
|
|
37
|
+
style.transform = "translate(-100%, -50%) translateX(-" + gap + "px)";
|
|
38
|
+
} else {
|
|
39
|
+
style.left = triggerRect.right + "px";
|
|
40
|
+
style.top = cy + "px";
|
|
41
|
+
style.transform = "translate(" + gap + "px, -50%)";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Create a tooltip wrapper: trigger element + tooltip that shows on hover/focus.
|
|
47
|
+
* @param {Object} config
|
|
48
|
+
* @param {string} config.content - Tooltip text
|
|
49
|
+
* @param {HTMLElement} [config.trigger] - Trigger element (if omitted, a span with label is created)
|
|
50
|
+
* @param {string} [config.label='Hover me'] - Label for default trigger when config.trigger is not provided
|
|
51
|
+
* @param {'top'|'bottom'|'left'|'right'} [config.placement='top'] - Where tooltip appears
|
|
52
|
+
* @param {string} [config.className] - Extra class for wrapper
|
|
53
|
+
* @param {string} [config.triggerClassName] - Extra class for default trigger span
|
|
54
|
+
* @returns {HTMLElement} Wrapper element (contains trigger; tooltip is portaled to body)
|
|
55
|
+
*/
|
|
56
|
+
function create(config) {
|
|
57
|
+
var content = config && (config.content != null ? String(config.content) : "");
|
|
58
|
+
var placement = (config && config.placement) || "top";
|
|
59
|
+
var className = (config && config.className) || "";
|
|
60
|
+
var triggerClassName = (config && config.triggerClassName) || "";
|
|
61
|
+
|
|
62
|
+
var triggerEl = config && config.trigger;
|
|
63
|
+
if (!triggerEl || !triggerEl.nodeType) {
|
|
64
|
+
var span = document.createElement("span");
|
|
65
|
+
span.className = join(
|
|
66
|
+
"inline-flex items-center cursor-pointer text-typography-secondary-text underline decoration-dotted underline-offset-2",
|
|
67
|
+
triggerClassName
|
|
68
|
+
);
|
|
69
|
+
span.setAttribute("tabindex", "0");
|
|
70
|
+
span.setAttribute("role", "button");
|
|
71
|
+
span.textContent = (config && config.label) || "Hover me";
|
|
72
|
+
triggerEl = span;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
var wrapper = document.createElement("div");
|
|
76
|
+
wrapper.className = join("relative inline-flex", className);
|
|
77
|
+
wrapper.appendChild(triggerEl);
|
|
78
|
+
|
|
79
|
+
var tooltipEl = document.createElement("div");
|
|
80
|
+
tooltipEl.className = join(TOOLTIP_BASE, "opacity-0 invisible transition-opacity duration-150");
|
|
81
|
+
tooltipEl.style.backgroundColor = TOOLTIP_BG;
|
|
82
|
+
tooltipEl.setAttribute("role", "tooltip");
|
|
83
|
+
tooltipEl.setAttribute("data-placement", placement);
|
|
84
|
+
|
|
85
|
+
var contentWrap = document.createElement("div");
|
|
86
|
+
contentWrap.textContent = content;
|
|
87
|
+
tooltipEl.appendChild(contentWrap);
|
|
88
|
+
|
|
89
|
+
var arrow = document.createElement("div");
|
|
90
|
+
arrow.setAttribute("data-tooltip-arrow", placement);
|
|
91
|
+
arrow.style.position = "absolute";
|
|
92
|
+
arrow.style.width = "0";
|
|
93
|
+
arrow.style.height = "0";
|
|
94
|
+
arrow.style.borderStyle = "solid";
|
|
95
|
+
arrow.style.pointerEvents = "none";
|
|
96
|
+
var s = ARROW_SIZE;
|
|
97
|
+
if (placement === "top") {
|
|
98
|
+
arrow.style.left = "50%";
|
|
99
|
+
arrow.style.bottom = "-" + s + "px";
|
|
100
|
+
arrow.style.marginLeft = "-" + s + "px";
|
|
101
|
+
arrow.style.borderWidth = s + "px " + s + "px 0 " + s + "px";
|
|
102
|
+
arrow.style.borderColor = TOOLTIP_BG + " transparent transparent transparent";
|
|
103
|
+
} else if (placement === "bottom") {
|
|
104
|
+
arrow.style.left = "50%";
|
|
105
|
+
arrow.style.top = "-" + s + "px";
|
|
106
|
+
arrow.style.marginLeft = "-" + s + "px";
|
|
107
|
+
arrow.style.borderWidth = "0 " + s + "px " + s + "px " + s + "px";
|
|
108
|
+
arrow.style.borderColor = "transparent transparent " + TOOLTIP_BG + " transparent";
|
|
109
|
+
} else if (placement === "left") {
|
|
110
|
+
arrow.style.top = "50%";
|
|
111
|
+
arrow.style.right = "-" + s + "px";
|
|
112
|
+
arrow.style.marginTop = "-" + s + "px";
|
|
113
|
+
arrow.style.borderWidth = s + "px 0 " + s + "px " + s + "px";
|
|
114
|
+
arrow.style.borderColor = "transparent transparent transparent " + TOOLTIP_BG;
|
|
115
|
+
} else {
|
|
116
|
+
arrow.style.top = "50%";
|
|
117
|
+
arrow.style.left = "-" + s + "px";
|
|
118
|
+
arrow.style.marginTop = "-" + s + "px";
|
|
119
|
+
arrow.style.borderWidth = s + "px " + s + "px " + s + "px 0";
|
|
120
|
+
arrow.style.borderColor = "transparent " + TOOLTIP_BG + " transparent transparent";
|
|
121
|
+
}
|
|
122
|
+
tooltipEl.appendChild(arrow);
|
|
123
|
+
|
|
124
|
+
document.body.appendChild(tooltipEl);
|
|
125
|
+
|
|
126
|
+
var showTimer;
|
|
127
|
+
var hideTimer;
|
|
128
|
+
var delay = 120;
|
|
129
|
+
|
|
130
|
+
function show() {
|
|
131
|
+
if (hideTimer) {
|
|
132
|
+
clearTimeout(hideTimer);
|
|
133
|
+
hideTimer = null;
|
|
134
|
+
}
|
|
135
|
+
showTimer = setTimeout(function () {
|
|
136
|
+
showTimer = null;
|
|
137
|
+
var rect = triggerEl.getBoundingClientRect();
|
|
138
|
+
positionTooltip(rect, tooltipEl, placement);
|
|
139
|
+
tooltipEl.style.opacity = "1";
|
|
140
|
+
tooltipEl.classList.remove("invisible");
|
|
141
|
+
}, delay);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function hide() {
|
|
145
|
+
if (showTimer) {
|
|
146
|
+
clearTimeout(showTimer);
|
|
147
|
+
showTimer = null;
|
|
148
|
+
}
|
|
149
|
+
hideTimer = setTimeout(function () {
|
|
150
|
+
hideTimer = null;
|
|
151
|
+
tooltipEl.style.opacity = "0";
|
|
152
|
+
tooltipEl.classList.add("invisible");
|
|
153
|
+
}, 80);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function handleShow() {
|
|
157
|
+
show();
|
|
158
|
+
}
|
|
159
|
+
function handleHide() {
|
|
160
|
+
hide();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
triggerEl.addEventListener("mouseenter", handleShow);
|
|
164
|
+
triggerEl.addEventListener("mouseleave", handleHide);
|
|
165
|
+
triggerEl.addEventListener("focus", handleShow);
|
|
166
|
+
triggerEl.addEventListener("blur", handleHide);
|
|
167
|
+
|
|
168
|
+
wrapper._tooltipDestroy = function () {
|
|
169
|
+
triggerEl.removeEventListener("mouseenter", handleShow);
|
|
170
|
+
triggerEl.removeEventListener("mouseleave", handleHide);
|
|
171
|
+
triggerEl.removeEventListener("focus", handleShow);
|
|
172
|
+
triggerEl.removeEventListener("blur", handleHide);
|
|
173
|
+
if (showTimer) clearTimeout(showTimer);
|
|
174
|
+
if (hideTimer) clearTimeout(hideTimer);
|
|
175
|
+
if (tooltipEl.parentNode) tooltipEl.parentNode.removeChild(tooltipEl);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
return wrapper;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
global.Tooltip = {
|
|
182
|
+
create: create,
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
console.log("[Tooltip] Module loaded successfully");
|
|
186
|
+
})(typeof window !== "undefined" ? window : this);
|
package/core/flow.js
CHANGED
|
@@ -126,14 +126,13 @@
|
|
|
126
126
|
let labelEl;
|
|
127
127
|
const LabelComponent = getComponent("Label");
|
|
128
128
|
if (LabelComponent && typeof LabelComponent.create === "function") {
|
|
129
|
-
const suffix = helpText && getComponent("Tooltip") ? getComponent("Tooltip").create(helpText) : null;
|
|
130
129
|
labelEl = LabelComponent.create({
|
|
131
130
|
label: label,
|
|
132
131
|
required: required,
|
|
133
132
|
requiredPosition: "right",
|
|
134
133
|
optional: false,
|
|
135
134
|
size: "default",
|
|
136
|
-
|
|
135
|
+
helpText: helpText || undefined,
|
|
137
136
|
});
|
|
138
137
|
} else {
|
|
139
138
|
// Fallback: inline label (no Label component)
|
|
@@ -153,7 +152,7 @@
|
|
|
153
152
|
labelContentWrapper.appendChild(document.createTextNode(label));
|
|
154
153
|
}
|
|
155
154
|
if (helpText && getComponent("Tooltip")) {
|
|
156
|
-
const tooltip = getComponent("Tooltip").create(helpText);
|
|
155
|
+
const tooltip = getComponent("Tooltip").create({ content: helpText, label: "?" });
|
|
157
156
|
if (tooltip) labelContentWrapper.appendChild(tooltip);
|
|
158
157
|
}
|
|
159
158
|
labelEl.appendChild(labelContentWrapper);
|
|
@@ -256,12 +255,11 @@
|
|
|
256
255
|
* @param {string} [config.placeholder] - Placeholder when empty
|
|
257
256
|
* @param {boolean} [config.required] - Whether field is required
|
|
258
257
|
* @param {string} [config.helpText] - Optional help text for tooltip
|
|
259
|
-
* @param {number} [config.minHeightPx] - Min height of editor area in pixels (default 400)
|
|
260
258
|
* @param {boolean} [config.disabled] - Whether editor is disabled
|
|
261
259
|
* @returns {HTMLElement} Field element
|
|
262
260
|
*/
|
|
263
261
|
function createRichTextEditor(config) {
|
|
264
|
-
const { label, fieldId, placeholder, required = false, helpText = null,
|
|
262
|
+
const { label, fieldId, placeholder, required = false, helpText = null, disabled = false } = config;
|
|
265
263
|
|
|
266
264
|
const field = createFieldWrapper(label, required, helpText);
|
|
267
265
|
field.setAttribute("data-field-id", fieldId);
|
|
@@ -271,7 +269,6 @@
|
|
|
271
269
|
const editorEl = getComponent("RichTextEditorComponent").create({
|
|
272
270
|
value: currentValue,
|
|
273
271
|
placeholder: placeholder || "",
|
|
274
|
-
minHeightPx,
|
|
275
272
|
disabled,
|
|
276
273
|
onChange: (html) => set(fieldId, html),
|
|
277
274
|
});
|
|
@@ -281,7 +278,7 @@
|
|
|
281
278
|
}
|
|
282
279
|
|
|
283
280
|
const fallback = document.createElement("textarea");
|
|
284
|
-
fallback.className = "textarea min-h-[
|
|
281
|
+
fallback.className = "textarea min-h-[15vh]";
|
|
285
282
|
fallback.placeholder = placeholder || `Enter ${label.toLowerCase()}`;
|
|
286
283
|
fallback.value = get(fieldId) || "";
|
|
287
284
|
fallback.disabled = disabled;
|
|
@@ -1766,6 +1763,23 @@
|
|
|
1766
1763
|
return createAvatar(config);
|
|
1767
1764
|
}
|
|
1768
1765
|
|
|
1766
|
+
/**
|
|
1767
|
+
* Create a tooltip wrapper (trigger + tooltip on hover/focus)
|
|
1768
|
+
* @param {Object} config - { content, trigger?, label?, placement?, className?, triggerClassName? }
|
|
1769
|
+
* @returns {HTMLElement} Wrapper element containing trigger
|
|
1770
|
+
*/
|
|
1771
|
+
function createTooltip(config) {
|
|
1772
|
+
const Tooltip = getComponent("Tooltip");
|
|
1773
|
+
if (Tooltip && typeof Tooltip.create === "function") {
|
|
1774
|
+
return Tooltip.create(config);
|
|
1775
|
+
}
|
|
1776
|
+
const span = document.createElement("span");
|
|
1777
|
+
span.className = "text-typography-tertiary-text";
|
|
1778
|
+
span.title = config && config.content ? config.content : "";
|
|
1779
|
+
span.textContent = (config && config.label) || (config && config.content) || "Hover me";
|
|
1780
|
+
return span;
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1769
1783
|
/**
|
|
1770
1784
|
* Create an avatar group (overlapping avatars, max 3 + remainder)
|
|
1771
1785
|
* @param {Object} config - { users: [{ id, name, image? }], size?, className? }
|
|
@@ -1910,6 +1924,9 @@
|
|
|
1910
1924
|
createBadge,
|
|
1911
1925
|
createLoader,
|
|
1912
1926
|
|
|
1927
|
+
// Tooltip
|
|
1928
|
+
createTooltip,
|
|
1929
|
+
|
|
1913
1930
|
// Avatar
|
|
1914
1931
|
createAvatar,
|
|
1915
1932
|
createVividAvatar,
|