@superleapai/flow-ui 2.5.0 → 2.5.1

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/index.d.ts CHANGED
@@ -84,6 +84,8 @@ declare module "@superleapai/flow-ui" {
84
84
  getSdk(): any;
85
85
  isAvailable(): boolean;
86
86
  getDefaultConfig(): SuperLeapConfig;
87
+ /** Current base URL from merged config (null if not initialized). Used by file-input and other components. */
88
+ getBaseUrl(): string | null;
87
89
 
88
90
  // Bridge Methods (from crm.js)
89
91
 
package/index.js CHANGED
@@ -88,6 +88,7 @@
88
88
  require("./components/phone-input/phone-utils.js");
89
89
  require("./components/phone-input/phone-input.js");
90
90
  require("./components/checkbox.js");
91
+ require("./components/checkbox-group.js");
91
92
  require("./components/radio-group.js");
92
93
  require("./components/table.js");
93
94
  require("./components/tabs.js");
@@ -102,6 +103,7 @@
102
103
  getSdk: global.superleapClient.getSdk,
103
104
  isAvailable: global.superleapClient.isAvailable,
104
105
  getDefaultConfig: global.superleapClient.getDefaultConfig,
106
+ getBaseUrl: global.superleapClient.getBaseUrl,
105
107
  }
106
108
  : null;
107
109
 
@@ -117,6 +119,7 @@
117
119
  getSdk: window.superleapClient.getSdk,
118
120
  isAvailable: window.superleapClient.isAvailable,
119
121
  getDefaultConfig: window.superleapClient.getDefaultConfig,
122
+ getBaseUrl: window.superleapClient.getBaseUrl,
120
123
  }
121
124
  : null;
122
125
 
@@ -164,8 +167,8 @@
164
167
  "FileInput",
165
168
  "PhoneInput",
166
169
  "Checkbox",
170
+ "CheckboxGroup",
167
171
  "RadioGroup",
168
- "CardSelect",
169
172
  "SuperleapTable",
170
173
  "Tabs",
171
174
  "Steps",
@@ -198,6 +201,7 @@
198
201
  getSdk: client.getSdk.bind(client),
199
202
  isAvailable: client.isAvailable.bind(client),
200
203
  getDefaultConfig: client.getDefaultConfig.bind(client),
204
+ getBaseUrl: client.getBaseUrl.bind(client),
201
205
  // Bridge methods (from crm.js)
202
206
  connect: client.connect ? client.connect.bind(client) : undefined,
203
207
  isConnected: client.isConnected
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superleapai/flow-ui",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "A reusable design system for building multi-step forms with comprehensive UI components. Single file, clean globals, SDK included. Only FlowUI and SuperLeap exposed.",
5
5
  "main": "dist/superleap-flow.min.js",
6
6
  "types": "index.d.ts",
@@ -1,283 +0,0 @@
1
- /**
2
- * CardSelect Component (vanilla JS)
3
- * Full-width clickable card selection with icon, title, description, and check indicator.
4
- * Drop-in replacement / upgrade to RadioGroup when visual card UI is preferred.
5
- */
6
-
7
- (function (global) {
8
- "use strict";
9
-
10
- var COLORS = {
11
- selectedBorder: "#175259",
12
- unselectedBorder: "#e5e7eb",
13
- selectedBg: "#f0f9f8",
14
- unselectedBg: "#ffffff",
15
- selectedShadow: "0px 0px 0px 2px #e9f7f5",
16
- unselectedShadow: "0px 1.5px 4px -1px rgba(10,9,11,0.07)",
17
- hoverBorder: "#9ca3af",
18
- hoverShadow: "0px 5px 13px -5px rgba(10,9,11,0.05), 0px 2px 4px -1px rgba(10,9,11,0.02)",
19
- iconSelectedBg: "#d0ede9",
20
- iconUnselectedBg: "#f3f4f6",
21
- iconSelectedColor: "#175259",
22
- iconUnselectedColor: "#6b7280",
23
- titleSelected: "#175259",
24
- titleUnselected: "#111827",
25
- descSelected: "#35b18b",
26
- descUnselected: "#6b7280",
27
- checkBorderSelected: "#175259",
28
- checkBorderUnselected: "#d1d5db",
29
- checkBgSelected: "#175259",
30
- checkBgUnselected: "transparent",
31
- };
32
-
33
- var CHECK_ICON =
34
- '<svg width="10" height="10" viewBox="0 0 10 10" fill="none"><path d="M2 5l2.5 2.5L8 3" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>';
35
-
36
- function join() {
37
- return Array.prototype.filter.call(arguments, Boolean).join(" ");
38
- }
39
-
40
- function applyCardStyles(card, isSelected) {
41
- card.style.borderColor = isSelected ? COLORS.selectedBorder : COLORS.unselectedBorder;
42
- card.style.background = isSelected ? COLORS.selectedBg : COLORS.unselectedBg;
43
- card.style.boxShadow = isSelected ? COLORS.selectedShadow : COLORS.unselectedShadow;
44
- }
45
-
46
- function applyIconStyles(iconWrapper, isSelected) {
47
- iconWrapper.style.background = isSelected ? COLORS.iconSelectedBg : COLORS.iconUnselectedBg;
48
- iconWrapper.style.color = isSelected ? COLORS.iconSelectedColor : COLORS.iconUnselectedColor;
49
- }
50
-
51
- function applyTitleStyles(titleEl, isSelected) {
52
- titleEl.style.color = isSelected ? COLORS.titleSelected : COLORS.titleUnselected;
53
- }
54
-
55
- function applyDescStyles(descEl, isSelected) {
56
- descEl.style.color = isSelected ? COLORS.descSelected : COLORS.descUnselected;
57
- }
58
-
59
- function applyCheckStyles(checkEl, isSelected) {
60
- checkEl.style.borderColor = isSelected ? COLORS.checkBorderSelected : COLORS.checkBorderUnselected;
61
- checkEl.style.background = isSelected ? COLORS.checkBgSelected : COLORS.checkBgUnselected;
62
- checkEl.innerHTML = isSelected ? CHECK_ICON : "";
63
- }
64
-
65
- /**
66
- * Create a card select component
67
- * @param {Object} config
68
- * @param {string} [config.name] - name attribute for the group (used for id generation)
69
- * @param {Array} config.options - array of { value, label, description?, icon?, disabled? }
70
- * @param {string} [config.defaultValue] - initial selected value
71
- * @param {string} [config.value] - controlled value (takes priority over defaultValue)
72
- * @param {boolean} [config.disabled] - disable all cards
73
- * @param {string} [config.className] - extra class on wrapper
74
- * @param {Function} [config.onChange] - change handler (receives selected value)
75
- * @returns {HTMLElement} wrapper element with getValue/setValue/setDisabled API
76
- */
77
- function create(config) {
78
- var opts = config || {};
79
- var name = opts.name || "card-select-" + Math.random().toString(36).substr(2, 9);
80
- var options = opts.options || [];
81
- var defaultValue = opts.defaultValue;
82
- var selectedValue = opts.value !== undefined ? opts.value : defaultValue;
83
- var disabled = !!opts.disabled;
84
- var className = opts.className || "";
85
- var onChange = opts.onChange;
86
-
87
- // Wrapper container
88
- var wrapper = document.createElement("div");
89
- wrapper.setAttribute("role", "radiogroup");
90
- wrapper.setAttribute("dir", "ltr");
91
- wrapper.className = join("flex flex-col gap-3 w-full", className);
92
-
93
- function updateAllCards(newValue) {
94
- var cards = wrapper.querySelectorAll("[data-card-value]");
95
- cards.forEach(function (card) {
96
- var cv = card.dataset.cardValue;
97
- var active = cv === newValue;
98
- applyCardStyles(card, active);
99
- card.setAttribute("aria-checked", active ? "true" : "false");
100
- var iw = card.querySelector("[data-icon]");
101
- var titleEl = card.querySelector("[data-title]");
102
- var descEl = card.querySelector("[data-desc]");
103
- var checkEl = card.querySelector("[data-check]");
104
- if (iw) applyIconStyles(iw, active);
105
- if (titleEl) applyTitleStyles(titleEl, active);
106
- if (descEl) applyDescStyles(descEl, active);
107
- if (checkEl) applyCheckStyles(checkEl, active);
108
- });
109
- }
110
-
111
- options.forEach(function (option, index) {
112
- var optionValue = option.value;
113
- var optionLabel = option.label || option.value;
114
- var optionDesc = option.description || "";
115
- var optionIcon = option.icon || "";
116
- var optionDisabled = disabled || !!option.disabled;
117
- var isSelected = optionValue === selectedValue;
118
-
119
- // Card element
120
- var card = document.createElement("div");
121
- card.dataset.cardValue = optionValue;
122
- card.id = name + "-card-" + index;
123
- card.setAttribute("role", "radio");
124
- card.setAttribute("aria-checked", isSelected ? "true" : "false");
125
- card.setAttribute("tabindex", optionDisabled ? "-1" : "0");
126
-
127
- card.style.cssText = [
128
- "display: flex",
129
- "align-items: flex-start",
130
- "gap: 16px",
131
- "padding: 18px 20px",
132
- "border-radius: 10px",
133
- "border: 1.5px solid " + (isSelected ? COLORS.selectedBorder : COLORS.unselectedBorder),
134
- "background: " + (isSelected ? COLORS.selectedBg : COLORS.unselectedBg),
135
- "cursor: " + (optionDisabled ? "not-allowed" : "pointer"),
136
- "transition: border-color 0.15s, background 0.15s, box-shadow 0.15s",
137
- "box-shadow: " + (isSelected ? COLORS.selectedShadow : COLORS.unselectedShadow),
138
- "user-select: none",
139
- optionDisabled ? "opacity: 0.5" : "",
140
- ].filter(Boolean).join("; ");
141
-
142
- // Icon wrapper (only rendered when icon is provided)
143
- if (optionIcon) {
144
- var iconWrapper = document.createElement("div");
145
- iconWrapper.dataset.icon = "";
146
- iconWrapper.style.cssText = [
147
- "flex-shrink: 0",
148
- "width: 44px",
149
- "height: 44px",
150
- "border-radius: 8px",
151
- "background: " + (isSelected ? COLORS.iconSelectedBg : COLORS.iconUnselectedBg),
152
- "display: flex",
153
- "align-items: center",
154
- "justify-content: center",
155
- "color: " + (isSelected ? COLORS.iconSelectedColor : COLORS.iconUnselectedColor),
156
- "transition: background 0.15s, color 0.15s",
157
- ].join("; ");
158
- iconWrapper.innerHTML = optionIcon;
159
- card.appendChild(iconWrapper);
160
- }
161
-
162
- // Text wrapper
163
- var textWrapper = document.createElement("div");
164
- textWrapper.style.cssText = "display: flex; flex-direction: column; gap: 4px; flex: 1;";
165
-
166
- var titleEl = document.createElement("span");
167
- titleEl.dataset.title = "";
168
- titleEl.textContent = optionLabel;
169
- titleEl.style.cssText = [
170
- "font-size: 14px",
171
- "font-weight: 600",
172
- "color: " + (isSelected ? COLORS.titleSelected : COLORS.titleUnselected),
173
- "line-height: 1.4",
174
- "transition: color 0.15s",
175
- ].join("; ");
176
- textWrapper.appendChild(titleEl);
177
-
178
- if (optionDesc) {
179
- var descEl = document.createElement("span");
180
- descEl.dataset.desc = "";
181
- descEl.textContent = optionDesc;
182
- descEl.style.cssText = [
183
- "font-size: 12px",
184
- "color: " + (isSelected ? COLORS.descSelected : COLORS.descUnselected),
185
- "line-height: 1.5",
186
- "transition: color 0.15s",
187
- ].join("; ");
188
- textWrapper.appendChild(descEl);
189
- }
190
-
191
- card.appendChild(textWrapper);
192
-
193
- // Check indicator (radio circle in top-right)
194
- var checkEl = document.createElement("div");
195
- checkEl.dataset.check = "";
196
- checkEl.style.cssText = [
197
- "flex-shrink: 0",
198
- "width: 18px",
199
- "height: 18px",
200
- "border-radius: 50%",
201
- "border: 2px solid " + (isSelected ? COLORS.checkBorderSelected : COLORS.checkBorderUnselected),
202
- "background: " + (isSelected ? COLORS.checkBgSelected : COLORS.checkBgUnselected),
203
- "display: flex",
204
- "align-items: center",
205
- "justify-content: center",
206
- "margin-top: 2px",
207
- "transition: all 0.15s",
208
- ].join("; ");
209
- if (isSelected) {
210
- checkEl.innerHTML = CHECK_ICON;
211
- }
212
- card.appendChild(checkEl);
213
-
214
- // Hover and focus styles
215
- if (!optionDisabled) {
216
- card.addEventListener("mouseenter", function () {
217
- if (card.getAttribute("aria-checked") !== "true") {
218
- card.style.borderColor = COLORS.hoverBorder;
219
- card.style.boxShadow = COLORS.hoverShadow;
220
- }
221
- });
222
- card.addEventListener("mouseleave", function () {
223
- if (card.getAttribute("aria-checked") !== "true") {
224
- card.style.borderColor = COLORS.unselectedBorder;
225
- card.style.boxShadow = COLORS.unselectedShadow;
226
- }
227
- });
228
-
229
- // Click handler
230
- card.addEventListener("click", function () {
231
- if (optionDisabled || disabled) return;
232
- selectedValue = optionValue;
233
- updateAllCards(selectedValue);
234
- if (typeof onChange === "function") {
235
- onChange(selectedValue);
236
- }
237
- });
238
-
239
- // Keyboard support
240
- card.addEventListener("keydown", function (e) {
241
- if (optionDisabled || disabled) return;
242
- if (e.key === " " || e.key === "Enter") {
243
- e.preventDefault();
244
- card.click();
245
- }
246
- });
247
- }
248
-
249
- wrapper.appendChild(card);
250
- });
251
-
252
- // Public API
253
- wrapper.getValue = function () {
254
- return selectedValue !== undefined ? selectedValue : null;
255
- };
256
-
257
- wrapper.setValue = function (newValue) {
258
- selectedValue = newValue;
259
- updateAllCards(newValue);
260
- };
261
-
262
- wrapper.setDisabled = function (isDisabled) {
263
- disabled = !!isDisabled;
264
- wrapper.querySelectorAll("[data-card-value]").forEach(function (card) {
265
- card.style.cursor = disabled ? "not-allowed" : "pointer";
266
- card.style.opacity = disabled ? "0.5" : "1";
267
- card.setAttribute("tabindex", disabled ? "-1" : "0");
268
- });
269
- };
270
-
271
- return wrapper;
272
- }
273
-
274
- var CardSelect = {
275
- create: create,
276
- };
277
-
278
- if (typeof module !== "undefined" && module.exports) {
279
- module.exports = CardSelect;
280
- } else {
281
- global.CardSelect = CardSelect;
282
- }
283
- })(typeof window !== "undefined" ? window : this);