funuicss 3.7.3 → 3.7.5

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/ui/input/Input.js CHANGED
@@ -62,7 +62,7 @@ var pi_1 = require("react-icons/pi");
62
62
  var theme_1 = require("../theme/theme");
63
63
  var componentUtils_1 = require("../../utils/componentUtils");
64
64
  var getDynamicIcon_1 = require("../../utils/getDynamicIcon");
65
- var FileUpload_1 = require("./FileUpload"); // Import the FileUpload component
65
+ var FileUpload_1 = require("./FileUpload");
66
66
  // Status icons mapping
67
67
  var statusIcons = {
68
68
  success: react_1.default.createElement(pi_1.PiCheckCircle, null),
@@ -83,26 +83,39 @@ var generateInputClasses = function (_a) {
83
83
  var noLabelClass = hasNoLabel ? 'no_label' : '';
84
84
  return "\n ".concat(statusClass, "\n ").concat(roundedClass, "\n ").concat(bgClass, "\n ").concat(funcss || '', "\n ").concat(flatClass, "\n ").concat(cornerClass, "\n ").concat(borderClass, "\n ").concat(additionalClasses, "\n ").concat(noPrefixClass, "\n ").concat(noLabelClass, "\n input\n ").trim().replace(/\s+/g, ' ');
85
85
  };
86
- // Iconic Input Wrapper Component
86
+ // Iconic Input Wrapper Component - UPDATED to match Button's pattern
87
87
  var IconicInputWrapper = function (_a) {
88
- var startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, iconicBg = _a.iconicBg, funcss = _a.funcss, children = _a.children;
89
- var effectiveStartIcon = prefix !== undefined ? prefix : startIcon;
90
- var effectiveEndIcon = suffix !== undefined ? suffix : endIcon;
91
- if (!effectiveStartIcon && !effectiveEndIcon) {
88
+ var startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, iconicBg = _a.iconicBg, funcss = _a.funcss, stringPrefix = _a.stringPrefix, stringSuffix = _a.stringSuffix, children = _a.children;
89
+ // Match Button's pattern exactly - use proper priority
90
+ var effectiveStartIcon = startIcon !== undefined ? startIcon : prefix;
91
+ var effectiveEndIcon = endIcon !== undefined ? endIcon : suffix;
92
+ // Determine which icons to show - MATCH BUTTON'S PATTERN EXACTLY
93
+ var showPrefix = effectiveStartIcon !== undefined && effectiveStartIcon !== null;
94
+ var showSuffix = effectiveEndIcon !== undefined && effectiveEndIcon !== null;
95
+ if (!showPrefix && !showSuffix) {
92
96
  return react_1.default.createElement(react_1.default.Fragment, null, children);
93
97
  }
94
- return (react_1.default.createElement("div", { className: "icon-container ".concat(effectiveStartIcon ? 'has-left-icon' : '', " ").concat(funcss || '') },
95
- effectiveStartIcon && (react_1.default.createElement("div", { className: "leftIcon", style: {
98
+ // Helper function to check if element is a React element
99
+ function isReactElement(node) {
100
+ return react_1.default.isValidElement(node);
101
+ }
102
+ return (react_1.default.createElement("div", { className: "icon-container ".concat(showPrefix ? 'has-left-icon' : '', " ").concat(funcss || '') },
103
+ showPrefix && (react_1.default.createElement("div", { className: "leftIcon", style: {
96
104
  backgroundColor: iconicBg || '',
97
105
  border: iconicBg ? "0.1rem ".concat(iconicBg, " solid") : '',
98
- } }, effectiveStartIcon)),
106
+ } }, isReactElement(startIcon) ? startIcon
107
+ : isReactElement(prefix) ? prefix
108
+ : isReactElement(effectiveStartIcon) ? effectiveStartIcon
109
+ : stringPrefix ? effectiveStartIcon : '')),
99
110
  children,
100
- effectiveEndIcon && (react_1.default.createElement("div", { className: "rightIcon", style: { backgroundColor: iconicBg || '' } }, effectiveEndIcon))));
111
+ showSuffix && (react_1.default.createElement("div", { className: "rightIcon", style: { backgroundColor: iconicBg || '' } }, isReactElement(endIcon) ? endIcon
112
+ : isReactElement(suffix) ? suffix
113
+ : isReactElement(effectiveEndIcon) ? effectiveEndIcon
114
+ : stringSuffix ? effectiveEndIcon : ""))));
101
115
  };
102
116
  // Input Container with Floating Label
103
117
  var InputContainer = function (_a) {
104
118
  var label = _a.label, status = _a.status, helperText = _a.helperText, children = _a.children, isFocused = _a.isFocused, hasValue = _a.hasValue, fullWidth = _a.fullWidth, id = _a.id, startIcon = _a.startIcon, prefix = _a.prefix, _b = _a.alwaysActiveLabel, alwaysActiveLabel = _b === void 0 ? false : _b;
105
- // For select inputs and date/time inputs, label is always active
106
119
  var showFloatingLabel = label && (alwaysActiveLabel || isFocused || hasValue);
107
120
  return (react_1.default.createElement("div", { className: "input-wrapper ".concat(fullWidth ? 'full-width' : '') },
108
121
  react_1.default.createElement("div", { className: "input-container-with-label" },
@@ -119,21 +132,19 @@ var TextInput = function (_a) {
119
132
  var _f = (0, react_1.useState)(value !== undefined ? String(value) : defaultValue || ''), inputValue = _f[0], setInputValue = _f[1];
120
133
  var _g = (0, react_1.useState)(null), prefixNode = _g[0], setPrefixNode = _g[1];
121
134
  var _h = (0, react_1.useState)(null), suffixNode = _h[0], setSuffixNode = _h[1];
135
+ var _j = (0, react_1.useState)(false), hasValidStringPrefix = _j[0], setHasValidStringPrefix = _j[1];
136
+ var _k = (0, react_1.useState)(false), hasValidStringSuffix = _k[0], setHasValidStringSuffix = _k[1];
122
137
  var inputRef = (0, react_1.useRef)(null);
123
- // Check if this is a date/time input type for always active label
124
138
  var isDateTimeInput = ['date', 'time', 'month', 'week', 'datetime-local'].includes(type || '');
125
- // Handle value changes - only update if value is truly defined (not empty string)
126
139
  (0, react_1.useEffect)(function () {
127
140
  if (value !== undefined && value !== '') {
128
141
  setInputValue(String(value));
129
142
  }
130
143
  else if (value === '') {
131
- // Allow empty string to clear the input
132
144
  setInputValue('');
133
145
  }
134
146
  }, [value]);
135
147
  var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Input', variant).mergeWithLocal;
136
- // Create local props object including stringPrefix/stringSuffix
137
148
  var localProps = {
138
149
  status: status,
139
150
  funcss: funcss,
@@ -150,12 +161,10 @@ var TextInput = function (_a) {
150
161
  prefix: prefix,
151
162
  suffix: suffix,
152
163
  iconicBg: iconicBg,
153
- stringPrefix: stringPrefix, // Include in local props
164
+ stringPrefix: stringPrefix,
154
165
  stringSuffix: stringSuffix,
155
166
  };
156
- // Merge with config - LOCAL PROPS OVERRIDE CONFIG
157
167
  var mergedProps = mergeWithLocal(localProps).props;
158
- // Extract final values - local props take precedence, but handle empty strings properly
159
168
  var final = {
160
169
  status: status !== undefined ? status : mergedProps.status,
161
170
  funcss: funcss !== undefined ? funcss : mergedProps.funcss,
@@ -172,36 +181,92 @@ var TextInput = function (_a) {
172
181
  prefix: prefix !== undefined ? prefix : mergedProps.prefix,
173
182
  suffix: suffix !== undefined ? suffix : mergedProps.suffix,
174
183
  iconicBg: iconicBg !== undefined ? iconicBg : mergedProps.iconicBg,
175
- stringPrefix: stringPrefix !== undefined ? stringPrefix : mergedProps.stringPrefix, // Handle both local and config
176
- stringSuffix: stringSuffix !== undefined ? stringSuffix : mergedProps.stringSuffix, // Handle both local and config
184
+ stringPrefix: stringPrefix !== undefined ? stringPrefix : mergedProps.stringPrefix,
185
+ stringSuffix: stringSuffix !== undefined ? stringSuffix : mergedProps.stringSuffix,
177
186
  };
178
- // Handle stringPrefix - use final value (local or config)
187
+ // Handle stringPrefix - MATCH BUTTON'S PATTERN EXACTLY
179
188
  (0, react_1.useEffect)(function () {
180
189
  var effectiveStringPrefix = final.stringPrefix;
181
- if (effectiveStringPrefix) {
182
- (0, getDynamicIcon_1.getDynamicIcon)(effectiveStringPrefix).then(function (node) { return setPrefixNode(node); });
183
- }
184
- else {
190
+ if (!effectiveStringPrefix || effectiveStringPrefix.trim() === '') {
185
191
  setPrefixNode(null);
192
+ setHasValidStringPrefix(false);
193
+ return;
186
194
  }
195
+ (0, getDynamicIcon_1.getDynamicIcon)(effectiveStringPrefix).then(function (node) {
196
+ if (node) {
197
+ setPrefixNode(node);
198
+ setHasValidStringPrefix(true);
199
+ }
200
+ else {
201
+ setPrefixNode(null);
202
+ setHasValidStringPrefix(false);
203
+ }
204
+ });
187
205
  }, [final.stringPrefix]);
188
- // Handle stringSuffix - use final value (local or config)
206
+ // Handle stringSuffix - MATCH BUTTON'S PATTERN EXACTLY
189
207
  (0, react_1.useEffect)(function () {
190
208
  var effectiveStringSuffix = final.stringSuffix;
191
- if (effectiveStringSuffix) {
192
- (0, getDynamicIcon_1.getDynamicIcon)(effectiveStringSuffix).then(function (node) { return setSuffixNode(node); });
193
- }
194
- else {
209
+ if (!effectiveStringSuffix || effectiveStringSuffix.trim() === '') {
195
210
  setSuffixNode(null);
211
+ setHasValidStringSuffix(false);
212
+ return;
196
213
  }
214
+ (0, getDynamicIcon_1.getDynamicIcon)(effectiveStringSuffix).then(function (node) {
215
+ if (node) {
216
+ setSuffixNode(node);
217
+ setHasValidStringSuffix(true);
218
+ }
219
+ else {
220
+ setSuffixNode(null);
221
+ setHasValidStringSuffix(false);
222
+ }
223
+ });
197
224
  }, [final.stringSuffix]);
198
225
  var themeVariant = (0, theme_1.useVariant)().variant;
199
- // Determine effective icons: stringPrefix/stringSuffix take priority, then local, then config
200
- var effectivePrefix = prefixNode || final.prefix || final.startIcon;
201
- var effectiveSuffix = suffixNode || final.suffix || final.endIcon;
202
- // Check if there's no start icon or prefix
226
+ // Determine which prefix to show with proper priority - MATCH BUTTON'S PATTERN
227
+ var showPrefix = react_1.default.useMemo(function () {
228
+ // Priority order: startIcon (local) > prefix (local) > stringPrefix (dynamic)
229
+ if (final.startIcon)
230
+ return true;
231
+ if (final.prefix)
232
+ return true;
233
+ if (hasValidStringPrefix && prefixNode)
234
+ return true;
235
+ return false;
236
+ }, [final.startIcon, final.prefix, hasValidStringPrefix, prefixNode]);
237
+ // Determine which suffix to show with proper priority - MATCH BUTTON'S PATTERN
238
+ var showSuffix = react_1.default.useMemo(function () {
239
+ // Priority order: endIcon (local) > suffix (local) > stringSuffix (dynamic)
240
+ if (final.endIcon)
241
+ return true;
242
+ if (final.suffix)
243
+ return true;
244
+ if (hasValidStringSuffix && suffixNode)
245
+ return true;
246
+ return false;
247
+ }, [final.endIcon, final.suffix, hasValidStringSuffix, suffixNode]);
248
+ // Get effective icons following Button's priority pattern
249
+ var effectivePrefix = react_1.default.useMemo(function () {
250
+ // Priority: startIcon > prefix > stringPrefix
251
+ if (final.startIcon)
252
+ return final.startIcon;
253
+ if (final.prefix)
254
+ return final.prefix;
255
+ if (hasValidStringPrefix)
256
+ return prefixNode;
257
+ return null;
258
+ }, [final.startIcon, final.prefix, hasValidStringPrefix, prefixNode]);
259
+ var effectiveSuffix = react_1.default.useMemo(function () {
260
+ // Priority: endIcon > suffix > stringSuffix
261
+ if (final.endIcon)
262
+ return final.endIcon;
263
+ if (final.suffix)
264
+ return final.suffix;
265
+ if (hasValidStringSuffix)
266
+ return suffixNode;
267
+ return null;
268
+ }, [final.endIcon, final.suffix, hasValidStringSuffix, suffixNode]);
203
269
  var hasNoPrefix = !effectivePrefix;
204
- // Check if there's no label
205
270
  var hasNoLabel = !label;
206
271
  var className = generateInputClasses({
207
272
  status: final.status,
@@ -213,7 +278,7 @@ var TextInput = function (_a) {
213
278
  rightRounded: final.rightRounded,
214
279
  bordered: final.bordered,
215
280
  borderless: final.borderless,
216
- hasNoPrefix: hasNoPrefix, // Add no_prefix class when no start icon/prefix
281
+ hasNoPrefix: hasNoPrefix,
217
282
  hasNoLabel: hasNoLabel,
218
283
  });
219
284
  var style = final.fullWidth ? { width: '100%' } : undefined;
@@ -233,32 +298,31 @@ var TextInput = function (_a) {
233
298
  if (rest.onBlur)
234
299
  rest.onBlur(e);
235
300
  };
236
- // Show placeholder only when label is active (focused or has value)
237
301
  var showPlaceholder = placeholder && label && (isFocused || !!inputValue);
238
302
  var inputElement = (react_1.default.createElement("input", __assign({ ref: inputRef, id: id, name: name, className: className, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, defaultValue: defaultValue, type: type, placeholder: showPlaceholder ? placeholder : (!label ? placeholder : ''), style: style, value: inputValue }, rest)));
239
- var wrappedInput = (react_1.default.createElement(IconicInputWrapper, { startIcon: effectivePrefix, endIcon: effectiveSuffix, iconicBg: final.iconicBg, funcss: final.funcss }, inputElement));
303
+ // Only use iconic wrapper when we have icons, matching Button's pattern
304
+ var wrappedInput = showPrefix || showSuffix ? (react_1.default.createElement(IconicInputWrapper, { startIcon: effectivePrefix, endIcon: effectiveSuffix, iconicBg: final.iconicBg, funcss: final.funcss, stringPrefix: stringPrefix, stringSuffix: stringSuffix }, inputElement)) : (inputElement);
240
305
  return (react_1.default.createElement(InputContainer, { startIcon: effectivePrefix, label: label, status: final.status, helperText: helperText, isFocused: isFocused, hasValue: !!inputValue, fullWidth: final.fullWidth, id: id, alwaysActiveLabel: isDateTimeInput }, wrappedInput));
241
306
  };
242
307
  exports.TextInput = TextInput;
243
- // Select Component
308
+ // Select Component - UPDATED to match pattern
244
309
  var SelectInput = function (_a) {
245
310
  var id = _a.id, name = _a.name, value = _a.value, defaultValue = _a.defaultValue, onChange = _a.onChange, status = _a.status, funcss = _a.funcss, bg = _a.bg, fullWidth = _a.fullWidth, flat = _a.flat, bordered = _a.bordered, borderless = _a.borderless, rounded = _a.rounded, leftRounded = _a.leftRounded, rightRounded = _a.rightRounded, startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, stringPrefix = _a.stringPrefix, stringSuffix = _a.stringSuffix, iconicBg = _a.iconicBg, _b = _a.options, options = _b === void 0 ? [] : _b, label = _a.label, helperText = _a.helperText, _c = _a.variant, variant = _c === void 0 ? '' : _c, rest = __rest(_a, ["id", "name", "value", "defaultValue", "onChange", "status", "funcss", "bg", "fullWidth", "flat", "bordered", "borderless", "rounded", "leftRounded", "rightRounded", "startIcon", "endIcon", "prefix", "suffix", "stringPrefix", "stringSuffix", "iconicBg", "options", "label", "helperText", "variant"]);
246
311
  var _d = (0, react_1.useState)(false), isFocused = _d[0], setIsFocused = _d[1];
247
312
  var _e = (0, react_1.useState)(value !== undefined ? String(value) : defaultValue || ''), selectValue = _e[0], setSelectValue = _e[1];
248
313
  var _f = (0, react_1.useState)(null), prefixNode = _f[0], setPrefixNode = _f[1];
249
314
  var _g = (0, react_1.useState)(null), suffixNode = _g[0], setSuffixNode = _g[1];
250
- // Handle value changes - only update if value is truly defined (not empty string)
315
+ var _h = (0, react_1.useState)(false), hasValidStringPrefix = _h[0], setHasValidStringPrefix = _h[1];
316
+ var _j = (0, react_1.useState)(false), hasValidStringSuffix = _j[0], setHasValidStringSuffix = _j[1];
251
317
  (0, react_1.useEffect)(function () {
252
318
  if (value !== undefined && value !== '') {
253
319
  setSelectValue(String(value));
254
320
  }
255
321
  else if (value === '') {
256
- // Allow empty string to clear the select
257
322
  setSelectValue('');
258
323
  }
259
324
  }, [value]);
260
325
  var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Input', variant).mergeWithLocal;
261
- // Create local props object including stringPrefix/stringSuffix
262
326
  var localProps = {
263
327
  status: status,
264
328
  funcss: funcss,
@@ -275,12 +339,10 @@ var SelectInput = function (_a) {
275
339
  prefix: prefix,
276
340
  suffix: suffix,
277
341
  iconicBg: iconicBg,
278
- stringPrefix: stringPrefix, // Include in local props
342
+ stringPrefix: stringPrefix,
279
343
  stringSuffix: stringSuffix,
280
344
  };
281
- // Merge with config - LOCAL PROPS OVERRIDE CONFIG
282
345
  var mergedProps = mergeWithLocal(localProps).props;
283
- // Extract final values - local props take precedence, but handle empty strings properly
284
346
  var final = {
285
347
  status: status !== undefined ? status : mergedProps.status,
286
348
  funcss: funcss !== undefined ? funcss : mergedProps.funcss,
@@ -297,37 +359,93 @@ var SelectInput = function (_a) {
297
359
  prefix: prefix !== undefined ? prefix : mergedProps.prefix,
298
360
  suffix: suffix !== undefined ? suffix : mergedProps.suffix,
299
361
  iconicBg: iconicBg !== undefined ? iconicBg : mergedProps.iconicBg,
300
- stringPrefix: stringPrefix !== undefined ? stringPrefix : mergedProps.stringPrefix, // Handle both local and config
301
- stringSuffix: stringSuffix !== undefined ? stringSuffix : mergedProps.stringSuffix, // Handle both local and config
362
+ stringPrefix: stringPrefix !== undefined ? stringPrefix : mergedProps.stringPrefix,
363
+ stringSuffix: stringSuffix !== undefined ? stringSuffix : mergedProps.stringSuffix,
302
364
  };
303
- // Handle stringPrefix - use final value (local or config)
365
+ // Handle stringPrefix - MATCH BUTTON'S PATTERN EXACTLY
304
366
  (0, react_1.useEffect)(function () {
305
367
  var effectiveStringPrefix = final.stringPrefix;
306
- if (effectiveStringPrefix) {
307
- (0, getDynamicIcon_1.getDynamicIcon)(effectiveStringPrefix).then(function (node) { return setPrefixNode(node); });
308
- }
309
- else {
368
+ if (!effectiveStringPrefix || effectiveStringPrefix.trim() === '') {
310
369
  setPrefixNode(null);
370
+ setHasValidStringPrefix(false);
371
+ return;
311
372
  }
373
+ (0, getDynamicIcon_1.getDynamicIcon)(effectiveStringPrefix).then(function (node) {
374
+ if (node) {
375
+ setPrefixNode(node);
376
+ setHasValidStringPrefix(true);
377
+ }
378
+ else {
379
+ setPrefixNode(null);
380
+ setHasValidStringPrefix(false);
381
+ }
382
+ });
312
383
  }, [final.stringPrefix]);
313
- // Handle stringSuffix - use final value (local or config)
384
+ // Handle stringSuffix - MATCH BUTTON'S PATTERN EXACTLY
314
385
  (0, react_1.useEffect)(function () {
315
386
  var effectiveStringSuffix = final.stringSuffix;
316
- if (effectiveStringSuffix) {
317
- (0, getDynamicIcon_1.getDynamicIcon)(effectiveStringSuffix).then(function (node) { return setSuffixNode(node); });
318
- }
319
- else {
387
+ if (!effectiveStringSuffix || effectiveStringSuffix.trim() === '') {
320
388
  setSuffixNode(null);
389
+ setHasValidStringSuffix(false);
390
+ return;
321
391
  }
392
+ (0, getDynamicIcon_1.getDynamicIcon)(effectiveStringSuffix).then(function (node) {
393
+ if (node) {
394
+ setSuffixNode(node);
395
+ setHasValidStringSuffix(true);
396
+ }
397
+ else {
398
+ setSuffixNode(null);
399
+ setHasValidStringSuffix(false);
400
+ }
401
+ });
322
402
  }, [final.stringSuffix]);
323
403
  var selectHasValue = !!selectValue;
324
404
  var themeVariant = (0, theme_1.useVariant)().variant;
325
- // Determine effective icons
326
- var effectivePrefix = prefixNode || final.prefix || final.startIcon;
327
- var effectiveSuffix = suffixNode || final.suffix || final.endIcon;
328
- // Check if there's no start icon or prefix
405
+ // Determine which prefix to show with proper priority - MATCH BUTTON'S PATTERN
406
+ var showPrefix = react_1.default.useMemo(function () {
407
+ // Priority order: startIcon (local) > prefix (local) > stringPrefix (dynamic)
408
+ if (final.startIcon)
409
+ return true;
410
+ if (final.prefix)
411
+ return true;
412
+ if (hasValidStringPrefix && prefixNode)
413
+ return true;
414
+ return false;
415
+ }, [final.startIcon, final.prefix, hasValidStringPrefix, prefixNode]);
416
+ // Determine which suffix to show with proper priority - MATCH BUTTON'S PATTERN
417
+ var showSuffix = react_1.default.useMemo(function () {
418
+ // Priority order: endIcon (local) > suffix (local) > stringSuffix (dynamic)
419
+ if (final.endIcon)
420
+ return true;
421
+ if (final.suffix)
422
+ return true;
423
+ if (hasValidStringSuffix && suffixNode)
424
+ return true;
425
+ return false;
426
+ }, [final.endIcon, final.suffix, hasValidStringSuffix, suffixNode]);
427
+ // Get effective icons following Button's priority pattern
428
+ var effectivePrefix = react_1.default.useMemo(function () {
429
+ // Priority: startIcon > prefix > stringPrefix
430
+ if (final.startIcon)
431
+ return final.startIcon;
432
+ if (final.prefix)
433
+ return final.prefix;
434
+ if (hasValidStringPrefix)
435
+ return prefixNode;
436
+ return null;
437
+ }, [final.startIcon, final.prefix, hasValidStringPrefix, prefixNode]);
438
+ var effectiveSuffix = react_1.default.useMemo(function () {
439
+ // Priority: endIcon > suffix > stringSuffix
440
+ if (final.endIcon)
441
+ return final.endIcon;
442
+ if (final.suffix)
443
+ return final.suffix;
444
+ if (hasValidStringSuffix)
445
+ return suffixNode;
446
+ return null;
447
+ }, [final.endIcon, final.suffix, hasValidStringSuffix, suffixNode]);
329
448
  var hasNoPrefix = !effectivePrefix;
330
- // Check if there's no label
331
449
  var hasNoLabel = !label;
332
450
  var className = generateInputClasses({
333
451
  status: final.status,
@@ -339,7 +457,7 @@ var SelectInput = function (_a) {
339
457
  rightRounded: final.rightRounded,
340
458
  bordered: final.bordered,
341
459
  borderless: final.borderless,
342
- hasNoPrefix: hasNoPrefix, // Add no_prefix class when no start icon/prefix
460
+ hasNoPrefix: hasNoPrefix,
343
461
  hasNoLabel: hasNoLabel,
344
462
  });
345
463
  var style = final.fullWidth ? { width: '100%' } : undefined;
@@ -360,29 +478,29 @@ var SelectInput = function (_a) {
360
478
  rest.onBlur(e);
361
479
  };
362
480
  var selectElement = (react_1.default.createElement("select", __assign({ id: id, name: name, className: className, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, defaultValue: defaultValue, value: selectValue, style: style }, rest), options.map(function (option) { return (react_1.default.createElement("option", { key: option.value, value: option.value }, option.text)); })));
363
- var wrappedSelect = (react_1.default.createElement(IconicInputWrapper, { startIcon: effectivePrefix, endIcon: effectiveSuffix, iconicBg: final.iconicBg, funcss: final.funcss }, selectElement));
481
+ // Only use iconic wrapper when we have icons, matching Button's pattern
482
+ var wrappedSelect = showPrefix || showSuffix ? (react_1.default.createElement(IconicInputWrapper, { startIcon: effectivePrefix, endIcon: effectiveSuffix, iconicBg: final.iconicBg, funcss: final.funcss, stringPrefix: stringPrefix, stringSuffix: stringSuffix }, selectElement)) : (selectElement);
364
483
  return (react_1.default.createElement(InputContainer, { startIcon: effectivePrefix, label: label, status: final.status, helperText: helperText, isFocused: isFocused, hasValue: selectHasValue, fullWidth: final.fullWidth, id: id, alwaysActiveLabel: true }, wrappedSelect));
365
484
  };
366
485
  exports.SelectInput = SelectInput;
367
- // Textarea Component
486
+ // Textarea Component - UPDATED to match pattern
368
487
  var TextareaInput = function (_a) {
369
488
  var id = _a.id, name = _a.name, value = _a.value, defaultValue = _a.defaultValue, onChange = _a.onChange, status = _a.status, funcss = _a.funcss, bg = _a.bg, fullWidth = _a.fullWidth, flat = _a.flat, bordered = _a.bordered, borderless = _a.borderless, rounded = _a.rounded, leftRounded = _a.leftRounded, rightRounded = _a.rightRounded, startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, stringPrefix = _a.stringPrefix, stringSuffix = _a.stringSuffix, iconicBg = _a.iconicBg, label = _a.label, helperText = _a.helperText, _b = _a.rows, rows = _b === void 0 ? 2 : _b, _c = _a.variant, variant = _c === void 0 ? '' : _c, placeholder = _a.placeholder, rest = __rest(_a, ["id", "name", "value", "defaultValue", "onChange", "status", "funcss", "bg", "fullWidth", "flat", "bordered", "borderless", "rounded", "leftRounded", "rightRounded", "startIcon", "endIcon", "prefix", "suffix", "stringPrefix", "stringSuffix", "iconicBg", "label", "helperText", "rows", "variant", "placeholder"]);
370
489
  var _d = (0, react_1.useState)(false), isFocused = _d[0], setIsFocused = _d[1];
371
490
  var _e = (0, react_1.useState)(value !== undefined ? String(value) : defaultValue || ''), textValue = _e[0], setTextValue = _e[1];
372
491
  var _f = (0, react_1.useState)(null), prefixNode = _f[0], setPrefixNode = _f[1];
373
492
  var _g = (0, react_1.useState)(null), suffixNode = _g[0], setSuffixNode = _g[1];
374
- // Handle value changes - only update if value is truly defined (not empty string)
493
+ var _h = (0, react_1.useState)(false), hasValidStringPrefix = _h[0], setHasValidStringPrefix = _h[1];
494
+ var _j = (0, react_1.useState)(false), hasValidStringSuffix = _j[0], setHasValidStringSuffix = _j[1];
375
495
  (0, react_1.useEffect)(function () {
376
496
  if (value !== undefined && value !== '') {
377
497
  setTextValue(String(value));
378
498
  }
379
499
  else if (value === '') {
380
- // Allow empty string to clear the textarea
381
500
  setTextValue('');
382
501
  }
383
502
  }, [value]);
384
503
  var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Input', variant).mergeWithLocal;
385
- // Create local props object including stringPrefix/stringSuffix
386
504
  var localProps = {
387
505
  status: status,
388
506
  funcss: funcss,
@@ -399,12 +517,10 @@ var TextareaInput = function (_a) {
399
517
  prefix: prefix,
400
518
  suffix: suffix,
401
519
  iconicBg: iconicBg,
402
- stringPrefix: stringPrefix, // Include in local props
520
+ stringPrefix: stringPrefix,
403
521
  stringSuffix: stringSuffix,
404
522
  };
405
- // Merge with config - LOCAL PROPS OVERRIDE CONFIG
406
523
  var mergedProps = mergeWithLocal(localProps).props;
407
- // Extract final values - local props take precedence, but handle empty strings properly
408
524
  var final = {
409
525
  status: status !== undefined ? status : mergedProps.status,
410
526
  funcss: funcss !== undefined ? funcss : mergedProps.funcss,
@@ -421,36 +537,92 @@ var TextareaInput = function (_a) {
421
537
  prefix: prefix !== undefined ? prefix : mergedProps.prefix,
422
538
  suffix: suffix !== undefined ? suffix : mergedProps.suffix,
423
539
  iconicBg: iconicBg !== undefined ? iconicBg : mergedProps.iconicBg,
424
- stringPrefix: stringPrefix !== undefined ? stringPrefix : mergedProps.stringPrefix, // Handle both local and config
425
- stringSuffix: stringSuffix !== undefined ? stringSuffix : mergedProps.stringSuffix, // Handle both local and config
540
+ stringPrefix: stringPrefix !== undefined ? stringPrefix : mergedProps.stringPrefix,
541
+ stringSuffix: stringSuffix !== undefined ? stringSuffix : mergedProps.stringSuffix,
426
542
  };
427
- // Handle stringPrefix - use final value (local or config)
543
+ // Handle stringPrefix - MATCH BUTTON'S PATTERN EXACTLY
428
544
  (0, react_1.useEffect)(function () {
429
545
  var effectiveStringPrefix = final.stringPrefix;
430
- if (effectiveStringPrefix) {
431
- (0, getDynamicIcon_1.getDynamicIcon)(effectiveStringPrefix).then(function (node) { return setPrefixNode(node); });
432
- }
433
- else {
546
+ if (!effectiveStringPrefix || effectiveStringPrefix.trim() === '') {
434
547
  setPrefixNode(null);
548
+ setHasValidStringPrefix(false);
549
+ return;
435
550
  }
551
+ (0, getDynamicIcon_1.getDynamicIcon)(effectiveStringPrefix).then(function (node) {
552
+ if (node) {
553
+ setPrefixNode(node);
554
+ setHasValidStringPrefix(true);
555
+ }
556
+ else {
557
+ setPrefixNode(null);
558
+ setHasValidStringPrefix(false);
559
+ }
560
+ });
436
561
  }, [final.stringPrefix]);
437
- // Handle stringSuffix - use final value (local or config)
562
+ // Handle stringSuffix - MATCH BUTTON'S PATTERN EXACTLY
438
563
  (0, react_1.useEffect)(function () {
439
564
  var effectiveStringSuffix = final.stringSuffix;
440
- if (effectiveStringSuffix) {
441
- (0, getDynamicIcon_1.getDynamicIcon)(effectiveStringSuffix).then(function (node) { return setSuffixNode(node); });
442
- }
443
- else {
565
+ if (!effectiveStringSuffix || effectiveStringSuffix.trim() === '') {
444
566
  setSuffixNode(null);
567
+ setHasValidStringSuffix(false);
568
+ return;
445
569
  }
570
+ (0, getDynamicIcon_1.getDynamicIcon)(effectiveStringSuffix).then(function (node) {
571
+ if (node) {
572
+ setSuffixNode(node);
573
+ setHasValidStringSuffix(true);
574
+ }
575
+ else {
576
+ setSuffixNode(null);
577
+ setHasValidStringSuffix(false);
578
+ }
579
+ });
446
580
  }, [final.stringSuffix]);
447
581
  var themeVariant = (0, theme_1.useVariant)().variant;
448
- // Determine effective icons
449
- var effectivePrefix = prefixNode || final.prefix || final.startIcon;
450
- var effectiveSuffix = suffixNode || final.suffix || final.endIcon;
451
- // Check if there's no start icon or prefix
582
+ // Determine which prefix to show with proper priority - MATCH BUTTON'S PATTERN
583
+ var showPrefix = react_1.default.useMemo(function () {
584
+ // Priority order: startIcon (local) > prefix (local) > stringPrefix (dynamic)
585
+ if (final.startIcon)
586
+ return true;
587
+ if (final.prefix)
588
+ return true;
589
+ if (hasValidStringPrefix && prefixNode)
590
+ return true;
591
+ return false;
592
+ }, [final.startIcon, final.prefix, hasValidStringPrefix, prefixNode]);
593
+ // Determine which suffix to show with proper priority - MATCH BUTTON'S PATTERN
594
+ var showSuffix = react_1.default.useMemo(function () {
595
+ // Priority order: endIcon (local) > suffix (local) > stringSuffix (dynamic)
596
+ if (final.endIcon)
597
+ return true;
598
+ if (final.suffix)
599
+ return true;
600
+ if (hasValidStringSuffix && suffixNode)
601
+ return true;
602
+ return false;
603
+ }, [final.endIcon, final.suffix, hasValidStringSuffix, suffixNode]);
604
+ // Get effective icons following Button's priority pattern
605
+ var effectivePrefix = react_1.default.useMemo(function () {
606
+ // Priority: startIcon > prefix > stringPrefix
607
+ if (final.startIcon)
608
+ return final.startIcon;
609
+ if (final.prefix)
610
+ return final.prefix;
611
+ if (hasValidStringPrefix)
612
+ return prefixNode;
613
+ return null;
614
+ }, [final.startIcon, final.prefix, hasValidStringPrefix, prefixNode]);
615
+ var effectiveSuffix = react_1.default.useMemo(function () {
616
+ // Priority: endIcon > suffix > stringSuffix
617
+ if (final.endIcon)
618
+ return final.endIcon;
619
+ if (final.suffix)
620
+ return final.suffix;
621
+ if (hasValidStringSuffix)
622
+ return suffixNode;
623
+ return null;
624
+ }, [final.endIcon, final.suffix, hasValidStringSuffix, suffixNode]);
452
625
  var hasNoPrefix = !effectivePrefix;
453
- // Check if there's no label
454
626
  var hasNoLabel = !label;
455
627
  var className = generateInputClasses({
456
628
  status: final.status,
@@ -462,7 +634,7 @@ var TextareaInput = function (_a) {
462
634
  rightRounded: final.rightRounded,
463
635
  bordered: final.bordered,
464
636
  borderless: final.borderless,
465
- hasNoPrefix: hasNoPrefix, // Add no_prefix class when no start icon/prefix
637
+ hasNoPrefix: hasNoPrefix,
466
638
  hasNoLabel: hasNoLabel,
467
639
  });
468
640
  var style = final.fullWidth ? { width: '100%' } : undefined;
@@ -482,21 +654,19 @@ var TextareaInput = function (_a) {
482
654
  if (rest.onBlur)
483
655
  rest.onBlur(e);
484
656
  };
485
- // Show placeholder only when label is active (focused or has value)
486
657
  var showPlaceholder = placeholder && label && (isFocused || !!textValue);
487
658
  var textareaElement = (react_1.default.createElement("textarea", __assign({ id: id, name: name, className: className, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, defaultValue: defaultValue, placeholder: showPlaceholder ? placeholder : (!label ? placeholder : ''), style: style, value: textValue, rows: rows }, rest)));
488
- var wrappedTextarea = (react_1.default.createElement(IconicInputWrapper, { startIcon: effectivePrefix, endIcon: effectiveSuffix, iconicBg: final.iconicBg, funcss: final.funcss }, textareaElement));
659
+ // Only use iconic wrapper when we have icons, matching Button's pattern
660
+ var wrappedTextarea = showPrefix || showSuffix ? (react_1.default.createElement(IconicInputWrapper, { startIcon: effectivePrefix, endIcon: effectiveSuffix, iconicBg: final.iconicBg, funcss: final.funcss, stringPrefix: stringPrefix, stringSuffix: stringSuffix }, textareaElement)) : (textareaElement);
489
661
  return (react_1.default.createElement(InputContainer, { startIcon: effectivePrefix, label: label, status: final.status, helperText: helperText, isFocused: isFocused, hasValue: !!textValue, fullWidth: final.fullWidth, id: id }, wrappedTextarea));
490
662
  };
491
663
  exports.TextareaInput = TextareaInput;
492
664
  var Input = function (_a) {
493
665
  var select = _a.select, multiline = _a.multiline, file = _a.file, noBorder = _a.noBorder, startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, stringPrefix = _a.stringPrefix, stringSuffix = _a.stringSuffix, iconicBg = _a.iconicBg, type = _a.type, _b = _a.variant, variant = _b === void 0 ? '' : _b, props = __rest(_a, ["select", "multiline", "file", "noBorder", "startIcon", "endIcon", "prefix", "suffix", "stringPrefix", "stringSuffix", "iconicBg", "type", "variant"]);
494
666
  var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Input', variant).mergeWithLocal;
495
- // Create local props object including stringPrefix/stringSuffix
496
667
  var localProps = __assign(__assign({}, props), { startIcon: startIcon, endIcon: endIcon, prefix: prefix, suffix: suffix, iconicBg: iconicBg, stringPrefix: stringPrefix, stringSuffix: stringSuffix, type: type });
497
668
  var mergedProps = mergeWithLocal(localProps).props;
498
669
  var inputProps = __assign(__assign(__assign({}, props), mergedProps), { variant: variant, borderless: noBorder !== undefined ? noBorder : (props.borderless !== undefined ? props.borderless : mergedProps.borderless), type: type });
499
- // If type is file or file prop is true, use FileUpload component
500
670
  if (file || type === 'file') {
501
671
  return react_1.default.createElement(FileUpload_1.FileUpload, __assign({}, inputProps));
502
672
  }