ywana-core8 0.1.80 → 0.1.82

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/index.umd.js CHANGED
@@ -1688,12 +1688,30 @@
1688
1688
  top: top,
1689
1689
  left: left
1690
1690
  };
1691
+
1692
+ // Text element - support both string and React components
1693
+ var textElement = React.useMemo(function () {
1694
+ if (!text) return null;
1695
+
1696
+ // If text is already a React element, use it directly
1697
+ if (React__default["default"].isValidElement(text)) {
1698
+ return text;
1699
+ }
1700
+
1701
+ // If text is a string, wrap it in Text component
1702
+ if (typeof text === 'string') {
1703
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, text);
1704
+ }
1705
+
1706
+ // Fallback for other types (convert to string)
1707
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(text));
1708
+ }, [text]);
1691
1709
  return /*#__PURE__*/React__default["default"].createElement("div", {
1692
1710
  className: "tooltip"
1693
1711
  }, /*#__PURE__*/React__default["default"].createElement("span", {
1694
1712
  className: "tooltip-text",
1695
1713
  style: style
1696
- }, /*#__PURE__*/React__default["default"].createElement(Text, null, text)), props.children);
1714
+ }, textElement), props.children);
1697
1715
  };
1698
1716
 
1699
1717
  /**
@@ -2160,6 +2178,24 @@
2160
2178
  'aria-describedby': tooltip ? id + "-tooltip" : undefined
2161
2179
  };
2162
2180
 
2181
+ // Label text - support both string and React components
2182
+ var labelElement = React.useMemo(function () {
2183
+ if (!label) return null;
2184
+
2185
+ // If label is already a React element, use it directly
2186
+ if (React__default["default"].isValidElement(label)) {
2187
+ return label;
2188
+ }
2189
+
2190
+ // If label is a string, wrap it in Text component
2191
+ if (typeof label === 'string') {
2192
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, label);
2193
+ }
2194
+
2195
+ // Fallback for other types (convert to string)
2196
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(label));
2197
+ }, [label]);
2198
+
2163
2199
  // Icon configuration
2164
2200
  var iconProps = {
2165
2201
  icon: loading ? 'hourglass_empty' : icon,
@@ -2177,7 +2213,7 @@
2177
2213
  onBlur: handleBlur,
2178
2214
  onKeyDown: handleKeyDown,
2179
2215
  disabled: disabled || loading
2180
- }, ariaAttributes, restProps), (icon || loading) && /*#__PURE__*/React__default["default"].createElement(Icon, iconProps), label && /*#__PURE__*/React__default["default"].createElement(Text, null, label), loading && !icon && /*#__PURE__*/React__default["default"].createElement("span", {
2216
+ }, ariaAttributes, restProps), (icon || loading) && /*#__PURE__*/React__default["default"].createElement(Icon, iconProps), labelElement, loading && !icon && /*#__PURE__*/React__default["default"].createElement("span", {
2181
2217
  className: "loading-text"
2182
2218
  }, "Loading..."));
2183
2219
  };
@@ -2273,8 +2309,8 @@
2273
2309
  Button.propTypes = {
2274
2310
  /** Unique identifier for the button */
2275
2311
  id: PropTypes.string,
2276
- /** Button text label */
2277
- label: PropTypes.string,
2312
+ /** Button text label - can be string or React element */
2313
+ label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
2278
2314
  /** Icon name for Material Icons */
2279
2315
  icon: PropTypes.string,
2280
2316
  /** Click handler function */
@@ -3105,11 +3141,28 @@
3105
3141
  var style = props.img ? {
3106
3142
  backgroundImage: "url(" + props.img + ")"
3107
3143
  } : {};
3108
- var title = /*#__PURE__*/React__default["default"].createElement(Text, null, props.title);
3144
+
3145
+ // Title element - support both string and React components
3146
+ var titleElement = React.useMemo(function () {
3147
+ if (!props.title) return null;
3148
+
3149
+ // If title is already a React element, use it directly
3150
+ if (React__default["default"].isValidElement(props.title)) {
3151
+ return props.title;
3152
+ }
3153
+
3154
+ // If title is a string, wrap it in Text component
3155
+ if (typeof props.title === 'string') {
3156
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, props.title);
3157
+ }
3158
+
3159
+ // Fallback for other types (convert to string)
3160
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(props.title));
3161
+ }, [props.title]);
3109
3162
  return /*#__PURE__*/React__default["default"].createElement("header", {
3110
3163
  className: "header " + caption + " " + prominent + " " + dense + " " + theme + " " + props.className,
3111
3164
  style: style
3112
- }, icon, props.title ? /*#__PURE__*/React__default["default"].createElement("label", null, title) : null, /*#__PURE__*/React__default["default"].createElement("span", {
3165
+ }, icon, props.title ? /*#__PURE__*/React__default["default"].createElement("label", null, titleElement) : null, /*#__PURE__*/React__default["default"].createElement("span", {
3113
3166
  className: "actions"
3114
3167
  }, props.children));
3115
3168
  };
@@ -3888,7 +3941,24 @@
3888
3941
  var labelStyle = label ? "" : "no-label";
3889
3942
  var labelPositionStyle = labelPosition == 'left' ? "label-left" : "label-top";
3890
3943
  var style = labelStyle + " " + labelPositionStyle + " " + borderStyle + " textfield-" + type;
3891
- var labelTxt = /*#__PURE__*/React__default["default"].createElement(Text, null, label);
3944
+
3945
+ // Label text - support both string and React components
3946
+ var labelTxt = React.useMemo(function () {
3947
+ if (!label) return null;
3948
+
3949
+ // If label is already a React element, use it directly
3950
+ if (React__default["default"].isValidElement(label)) {
3951
+ return label;
3952
+ }
3953
+
3954
+ // If label is a string, wrap it in Text component
3955
+ if (typeof label === 'string') {
3956
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, label);
3957
+ }
3958
+
3959
+ // Fallback for other types (convert to string)
3960
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(label));
3961
+ }, [label]);
3892
3962
  var placeholderTxt = site.translate ? site.translate(placeholder) : placeholder;
3893
3963
  return /*#__PURE__*/React__default["default"].createElement("div", {
3894
3964
  className: style + " " + id + " " + className,
@@ -3966,7 +4036,24 @@
3966
4036
  }
3967
4037
  var labelStyle = label ? "" : "no-label";
3968
4038
  var style = "textarea " + labelStyle + " textarea-" + type;
3969
- var labelTxt = /*#__PURE__*/React__default["default"].createElement(Text, null, label);
4039
+
4040
+ // Label text - support both string and React components
4041
+ var labelTxt = React.useMemo(function () {
4042
+ if (!label) return null;
4043
+
4044
+ // If label is already a React element, use it directly
4045
+ if (React__default["default"].isValidElement(label)) {
4046
+ return label;
4047
+ }
4048
+
4049
+ // If label is a string, wrap it in Text component
4050
+ if (typeof label === 'string') {
4051
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, label);
4052
+ }
4053
+
4054
+ // Fallback for other types (convert to string)
4055
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(label));
4056
+ }, [label]);
3970
4057
  var placeholderTxt = site.translate ? site.translate(placeholder) : placeholder;
3971
4058
  return /*#__PURE__*/React__default["default"].createElement("div", {
3972
4059
  className: "" + style,
@@ -4137,7 +4224,24 @@
4137
4224
  var next = Object.assign({}, form, (_Object$assign = {}, _Object$assign[id] = value, _Object$assign));
4138
4225
  setForm(next);
4139
4226
  }
4140
- var labelTxt = label ? /*#__PURE__*/React__default["default"].createElement(Text, null, label) : null;
4227
+
4228
+ // Label text - support both string and React components
4229
+ var labelTxt = React.useMemo(function () {
4230
+ if (!label) return null;
4231
+
4232
+ // If label is already a React element, use it directly
4233
+ if (React__default["default"].isValidElement(label)) {
4234
+ return label;
4235
+ }
4236
+
4237
+ // If label is a string, wrap it in Text component
4238
+ if (typeof label === 'string') {
4239
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, label);
4240
+ }
4241
+
4242
+ // Fallback for other types (convert to string)
4243
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(label));
4244
+ }, [label]);
4141
4245
  return /*#__PURE__*/React__default["default"].createElement("div", {
4142
4246
  className: "date-range"
4143
4247
  }, label ? /*#__PURE__*/React__default["default"].createElement("label", null, labelTxt) : null, /*#__PURE__*/React__default["default"].createElement(TextField, {
@@ -4165,7 +4269,24 @@
4165
4269
  function toggle() {
4166
4270
  setShow(!show);
4167
4271
  }
4168
- var labelTxt = label ? /*#__PURE__*/React__default["default"].createElement(Text, null, label) : null;
4272
+
4273
+ // Label text - support both string and React components
4274
+ var labelTxt = React.useMemo(function () {
4275
+ if (!label) return null;
4276
+
4277
+ // If label is already a React element, use it directly
4278
+ if (React__default["default"].isValidElement(label)) {
4279
+ return label;
4280
+ }
4281
+
4282
+ // If label is a string, wrap it in Text component
4283
+ if (typeof label === 'string') {
4284
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, label);
4285
+ }
4286
+
4287
+ // Fallback for other types (convert to string)
4288
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(label));
4289
+ }, [label]);
4169
4290
  return /*#__PURE__*/React__default["default"].createElement("div", {
4170
4291
  className: "password-field"
4171
4292
  }, /*#__PURE__*/React__default["default"].createElement(TextField, {
@@ -4182,8 +4303,8 @@
4182
4303
  }));
4183
4304
  };
4184
4305
 
4185
- var _excluded$a = ["items", "children", "selected", "onSelect", "groupBy", "groupRenderer", "loading", "empty", "emptyMessage", "emptyIcon", "searchable", "searchPlaceholder", "searchBy", "sortable", "sortBy", "sortDirection", "onSort", "multiSelect", "onMultiSelect", "dense", "disabled", "animated", "virtualized", "itemHeight", "maxHeight", "className", "style", "ariaLabel", "role"],
4186
- _excluded2$5 = ["items", "children", "selected", "onSelect", "groupBy", "groupRenderer", "searchTerm", "onSearch", "searchable", "searchPlaceholder", "multiSelect", "dense", "disabled", "animated", "cssClasses", "ariaAttributes", "style"],
4306
+ var _excluded$a = ["items", "children", "selected", "onSelect", "groupBy", "groupRenderer", "loading", "empty", "emptyMessage", "emptyIcon", "searchable", "searchPlaceholder", "searchBy", "searchPosition", "sortable", "sortBy", "sortDirection", "onSort", "multiSelect", "onMultiSelect", "dense", "outlined", "disabled", "animated", "virtualized", "itemHeight", "maxHeight", "className", "style", "ariaLabel", "role"],
4307
+ _excluded2$5 = ["items", "children", "selected", "onSelect", "groupBy", "groupRenderer", "searchTerm", "onSearch", "searchable", "searchPlaceholder", "searchPosition", "multiSelect", "dense", "disabled", "animated", "cssClasses", "ariaAttributes", "style"],
4187
4308
  _excluded3$2 = ["id", "icon", "iconTooltip", "line1", "line2", "meta", "avatar", "badge", "actions", "disabled"];
4188
4309
 
4189
4310
  /**
@@ -4210,6 +4331,8 @@
4210
4331
  searchPlaceholder = _props$searchPlacehol === void 0 ? "Search..." : _props$searchPlacehol,
4211
4332
  _props$searchBy = props.searchBy,
4212
4333
  searchBy = _props$searchBy === void 0 ? ['line1', 'line2'] : _props$searchBy,
4334
+ _props$searchPosition = props.searchPosition,
4335
+ searchPosition = _props$searchPosition === void 0 ? 'top' : _props$searchPosition,
4213
4336
  _props$sortable = props.sortable,
4214
4337
  sortable = _props$sortable === void 0 ? false : _props$sortable,
4215
4338
  sortBy = props.sortBy,
@@ -4221,6 +4344,8 @@
4221
4344
  onMultiSelect = props.onMultiSelect,
4222
4345
  _props$dense = props.dense,
4223
4346
  dense = _props$dense === void 0 ? false : _props$dense,
4347
+ _props$outlined = props.outlined,
4348
+ outlined = _props$outlined === void 0 ? false : _props$outlined,
4224
4349
  _props$disabled = props.disabled,
4225
4350
  disabled = _props$disabled === void 0 ? false : _props$disabled,
4226
4351
  _props$animated = props.animated,
@@ -4269,7 +4394,7 @@
4269
4394
  }, [disabled, multiSelect, selected, onSelect, onMultiSelect]);
4270
4395
 
4271
4396
  // Handle search
4272
- var handleSearch = React.useCallback(function (searchId, value) {
4397
+ var handleSearch = React.useCallback(function (_, value) {
4273
4398
  setSearchTerm(value);
4274
4399
  }, []);
4275
4400
 
@@ -4310,8 +4435,23 @@
4310
4435
  if (onSort) onSort(newConfig);
4311
4436
  }, [sortable, sortConfig, onSort]);
4312
4437
 
4438
+ // Search component
4439
+ var SearchComponent = function SearchComponent() {
4440
+ return searchable && /*#__PURE__*/React__default["default"].createElement("div", {
4441
+ className: "list__search"
4442
+ }, /*#__PURE__*/React__default["default"].createElement(TextField, {
4443
+ id: "list-search",
4444
+ placeholder: searchPlaceholder,
4445
+ value: searchTerm,
4446
+ onChange: handleSearch,
4447
+ icon: "search",
4448
+ outlined: true,
4449
+ size: "small"
4450
+ }));
4451
+ };
4452
+
4313
4453
  // Generate CSS classes
4314
- var cssClasses = ['list', dense && 'list--dense', disabled && 'list--disabled', animated && 'list--animated', loading && 'list--loading', className].filter(Boolean).join(' ');
4454
+ var cssClasses = ['list', dense && 'list--dense', outlined && 'list--outlined', disabled && 'list--disabled', animated && 'list--animated', loading && 'list--loading', className].filter(Boolean).join(' ');
4315
4455
 
4316
4456
  // Accessibility attributes
4317
4457
  var ariaAttributes = {
@@ -4338,22 +4478,12 @@
4338
4478
  return /*#__PURE__*/React__default["default"].createElement("div", _extends({
4339
4479
  className: cssClasses,
4340
4480
  style: style
4341
- }, ariaAttributes, restProps), searchable && /*#__PURE__*/React__default["default"].createElement("div", {
4342
- className: "list__search"
4343
- }, /*#__PURE__*/React__default["default"].createElement(TextField, {
4344
- id: "list-search",
4345
- placeholder: searchPlaceholder,
4346
- value: searchTerm,
4347
- onChange: handleSearch,
4348
- icon: "search",
4349
- outlined: true,
4350
- size: "small"
4351
- })), /*#__PURE__*/React__default["default"].createElement("div", {
4481
+ }, ariaAttributes, restProps), searchPosition === 'top' && /*#__PURE__*/React__default["default"].createElement(SearchComponent, null), /*#__PURE__*/React__default["default"].createElement("div", {
4352
4482
  className: "list__empty"
4353
4483
  }, /*#__PURE__*/React__default["default"].createElement(Icon, {
4354
4484
  icon: emptyIcon,
4355
4485
  size: "large"
4356
- }), /*#__PURE__*/React__default["default"].createElement(Text, null, emptyMessage)), children);
4486
+ }), /*#__PURE__*/React__default["default"].createElement(Text, null, emptyMessage)), searchPosition === 'bottom' && /*#__PURE__*/React__default["default"].createElement(SearchComponent, null), children);
4357
4487
  }
4358
4488
 
4359
4489
  // Render grouped or normal list
@@ -4370,17 +4500,7 @@
4370
4500
  className: cssClasses,
4371
4501
  style: style,
4372
4502
  ref: listRef
4373
- }, ariaAttributes, restProps), searchable && /*#__PURE__*/React__default["default"].createElement("div", {
4374
- className: "list__search"
4375
- }, /*#__PURE__*/React__default["default"].createElement(TextField, {
4376
- id: "list-search",
4377
- placeholder: searchPlaceholder,
4378
- value: searchTerm,
4379
- onChange: handleSearch,
4380
- icon: "search",
4381
- outlined: true,
4382
- size: "small"
4383
- })), sortable && sortBy && /*#__PURE__*/React__default["default"].createElement("div", {
4503
+ }, ariaAttributes, restProps), searchPosition === 'top' && /*#__PURE__*/React__default["default"].createElement(SearchComponent, null), sortable && sortBy && /*#__PURE__*/React__default["default"].createElement("div", {
4384
4504
  className: "list__sort"
4385
4505
  }, /*#__PURE__*/React__default["default"].createElement("button", {
4386
4506
  className: "list__sort-button",
@@ -4409,7 +4529,7 @@
4409
4529
  disabled: disabled,
4410
4530
  animated: animated
4411
4531
  });
4412
- })), children);
4532
+ })), searchPosition === 'bottom' && /*#__PURE__*/React__default["default"].createElement(SearchComponent, null), children);
4413
4533
  };
4414
4534
 
4415
4535
  /**
@@ -4429,6 +4549,8 @@
4429
4549
  searchable = _props$searchable2 === void 0 ? false : _props$searchable2,
4430
4550
  _props$searchPlacehol2 = props.searchPlaceholder,
4431
4551
  searchPlaceholder = _props$searchPlacehol2 === void 0 ? "Search..." : _props$searchPlacehol2,
4552
+ _props$searchPosition2 = props.searchPosition,
4553
+ searchPosition = _props$searchPosition2 === void 0 ? 'top' : _props$searchPosition2,
4432
4554
  _props$multiSelect2 = props.multiSelect,
4433
4555
  multiSelect = _props$multiSelect2 === void 0 ? false : _props$multiSelect2,
4434
4556
  _props$dense2 = props.dense,
@@ -4475,20 +4597,25 @@
4475
4597
  return next;
4476
4598
  });
4477
4599
  }, []);
4600
+
4601
+ // Search component for grouped list
4602
+ var GroupedSearchComponent = function GroupedSearchComponent() {
4603
+ return searchable && /*#__PURE__*/React__default["default"].createElement("div", {
4604
+ className: "list__search"
4605
+ }, /*#__PURE__*/React__default["default"].createElement(TextField, {
4606
+ id: "grouped-list-search",
4607
+ placeholder: searchPlaceholder,
4608
+ value: searchTerm,
4609
+ onChange: onSearch,
4610
+ icon: "search",
4611
+ outlined: true,
4612
+ size: "small"
4613
+ }));
4614
+ };
4478
4615
  return /*#__PURE__*/React__default["default"].createElement("div", _extends({
4479
4616
  className: cssClasses + " grouped",
4480
4617
  style: style
4481
- }, ariaAttributes, restProps), searchable && /*#__PURE__*/React__default["default"].createElement("div", {
4482
- className: "list__search"
4483
- }, /*#__PURE__*/React__default["default"].createElement(TextField, {
4484
- id: "grouped-list-search",
4485
- placeholder: searchPlaceholder,
4486
- value: searchTerm,
4487
- onChange: onSearch,
4488
- icon: "search",
4489
- outlined: true,
4490
- size: "small"
4491
- })), groups.map(function (group) {
4618
+ }, ariaAttributes, restProps), searchPosition === 'top' && /*#__PURE__*/React__default["default"].createElement(GroupedSearchComponent, null), groups.map(function (group) {
4492
4619
  var isCollapsed = collapsedGroups.has(group.name);
4493
4620
  var groupTitle = groupRenderer ? groupRenderer(group) : /*#__PURE__*/React__default["default"].createElement(Text, null, group.name);
4494
4621
  return /*#__PURE__*/React__default["default"].createElement(React.Fragment, {
@@ -4531,7 +4658,7 @@
4531
4658
  animated: animated
4532
4659
  });
4533
4660
  })));
4534
- }), children);
4661
+ }), searchPosition === 'bottom' && /*#__PURE__*/React__default["default"].createElement(GroupedSearchComponent, null), children);
4535
4662
  };
4536
4663
 
4537
4664
  /**
@@ -4632,14 +4759,14 @@
4632
4759
  }, /*#__PURE__*/React__default["default"].createElement(Text, {
4633
4760
  className: "list__item-line2",
4634
4761
  size: "small"
4635
- }, line2))), meta && /*#__PURE__*/React__default["default"].createElement("div", {
4762
+ }, line2))), actions && /*#__PURE__*/React__default["default"].createElement("div", {
4763
+ className: "list__item-actions",
4764
+ role: "toolbar"
4765
+ }, actions), meta && /*#__PURE__*/React__default["default"].createElement("div", {
4636
4766
  className: "list__item-meta"
4637
4767
  }, typeof meta === 'string' ? /*#__PURE__*/React__default["default"].createElement(Text, {
4638
4768
  size: "small"
4639
- }, meta) : meta), actions && /*#__PURE__*/React__default["default"].createElement("div", {
4640
- className: "list__item-actions",
4641
- role: "toolbar"
4642
- }, actions));
4769
+ }, meta) : meta));
4643
4770
  };
4644
4771
 
4645
4772
  // PropTypes for List component
@@ -4681,6 +4808,8 @@
4681
4808
  searchPlaceholder: PropTypes.string,
4682
4809
  /** Properties to search by */
4683
4810
  searchBy: PropTypes.arrayOf(PropTypes.string),
4811
+ /** Search position */
4812
+ searchPosition: PropTypes.oneOf(['top', 'bottom']),
4684
4813
  /** Enable sorting */
4685
4814
  sortable: PropTypes.bool,
4686
4815
  /** Property to sort by */
@@ -4695,6 +4824,8 @@
4695
4824
  onMultiSelect: PropTypes.func,
4696
4825
  /** Dense layout */
4697
4826
  dense: PropTypes.bool,
4827
+ /** Outlined variant with borders */
4828
+ outlined: PropTypes.bool,
4698
4829
  /** Disabled state */
4699
4830
  disabled: PropTypes.bool,
4700
4831
  /** Enable animations */
@@ -9661,6 +9792,9 @@
9661
9792
  var _useState4 = React.useState(true),
9662
9793
  isValid = _useState4[0],
9663
9794
  setIsValid = _useState4[1];
9795
+ var _useState5 = React.useState(false),
9796
+ hasBeenTouched = _useState5[0],
9797
+ setHasBeenTouched = _useState5[1];
9664
9798
  var inputRef = React.useRef(null);
9665
9799
  var debounceRef = React.useRef(null);
9666
9800
 
@@ -9669,8 +9803,14 @@
9669
9803
  console.warn('TextField2 component: id prop is required');
9670
9804
  }
9671
9805
 
9672
- // Validate value and set error states
9806
+ // Validate value and set error states - only after user interaction
9673
9807
  React.useEffect(function () {
9808
+ // Don't validate required fields until user has interacted with the field
9809
+ if (!hasBeenTouched && required && !value) {
9810
+ setIsValid(true);
9811
+ setInternalError('');
9812
+ return;
9813
+ }
9674
9814
  if (validation && value !== undefined) {
9675
9815
  var validationResult = validation(value);
9676
9816
  var valid = typeof validationResult === 'boolean' ? validationResult : validationResult.valid;
@@ -9680,14 +9820,14 @@
9680
9820
  if (onValidation) {
9681
9821
  onValidation(id, valid, errorMessage);
9682
9822
  }
9683
- } else if (required && !value) {
9823
+ } else if (required && !value && hasBeenTouched) {
9684
9824
  setIsValid(false);
9685
9825
  setInternalError('This field is required');
9686
9826
  } else {
9687
9827
  setIsValid(true);
9688
9828
  setInternalError('');
9689
9829
  }
9690
- }, [value, required, id]); // Removed validation and onValidation from dependencies to prevent infinite loops
9830
+ }, [value, required, id, hasBeenTouched]); // Added hasBeenTouched to dependencies
9691
9831
 
9692
9832
  // Handle input changes with debouncing
9693
9833
  var handleChange = React.useCallback(function (event) {
@@ -9695,6 +9835,11 @@
9695
9835
  event.stopPropagation();
9696
9836
  var newValue = event.target.value;
9697
9837
 
9838
+ // Mark field as touched on first change
9839
+ if (!hasBeenTouched) {
9840
+ setHasBeenTouched(true);
9841
+ }
9842
+
9698
9843
  // Clear previous debounce
9699
9844
  if (debounceRef.current) {
9700
9845
  clearTimeout(debounceRef.current);
@@ -9706,7 +9851,7 @@
9706
9851
  } else {
9707
9852
  if (onChange) onChange(id, newValue, event);
9708
9853
  }
9709
- }, [disabled, readOnly, id, onChange, debounceMs]);
9854
+ }, [disabled, readOnly, id, onChange, debounceMs, hasBeenTouched]);
9710
9855
 
9711
9856
  // Handle key press events
9712
9857
  var handleKeyPress = React.useCallback(function (event) {
@@ -9738,8 +9883,13 @@
9738
9883
  var handleBlur = React.useCallback(function (event) {
9739
9884
  if (disabled) return;
9740
9885
  setIsFocused(false);
9886
+
9887
+ // Mark field as touched on blur if it hasn't been touched yet
9888
+ if (!hasBeenTouched) {
9889
+ setHasBeenTouched(true);
9890
+ }
9741
9891
  if (onBlur) onBlur(event);
9742
- }, [disabled, onBlur]);
9892
+ }, [disabled, onBlur, hasBeenTouched]);
9743
9893
 
9744
9894
  // Handle clear action
9745
9895
  var handleClear = React.useCallback(function () {
@@ -9795,8 +9945,23 @@
9795
9945
  autoComplete: autoComplete
9796
9946
  }, ariaAttributes, restProps);
9797
9947
 
9798
- // Label text
9799
- var labelTxt = label ? /*#__PURE__*/React__default["default"].createElement(Text, null, label) : null;
9948
+ // Label text - support both string and React components
9949
+ var labelTxt = React.useMemo(function () {
9950
+ if (!label) return null;
9951
+
9952
+ // If label is already a React element, use it directly
9953
+ if (React__default["default"].isValidElement(label)) {
9954
+ return label;
9955
+ }
9956
+
9957
+ // If label is a string, wrap it in Text component
9958
+ if (typeof label === 'string') {
9959
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, label);
9960
+ }
9961
+
9962
+ // Fallback for other types (convert to string)
9963
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(label));
9964
+ }, [label]);
9800
9965
  var placeholderTxt = site != null && site.translate ? site.translate(placeholder) : placeholder;
9801
9966
 
9802
9967
  // Error/helper text
@@ -9874,8 +10039,8 @@
9874
10039
  type: PropTypes.oneOf(['text', 'email', 'password', 'number', 'tel', 'url', 'search', 'date', 'time', 'datetime-local', 'month', 'week', 'textarea']),
9875
10040
  /** Additional CSS classes */
9876
10041
  className: PropTypes.string,
9877
- /** Field label */
9878
- label: PropTypes.string,
10042
+ /** Field label - can be string or React element */
10043
+ label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
9879
10044
  /** Label position */
9880
10045
  labelPosition: PropTypes.oneOf(['top', 'left']),
9881
10046
  /** Placeholder text */
@@ -10004,18 +10169,18 @@
10004
10169
  onSearch = props.onSearch,
10005
10170
  restProps = _objectWithoutPropertiesLoose(props, _excluded2$3);
10006
10171
  React.useContext(SiteContext);
10007
- var _useState5 = React.useState(false),
10008
- isOpen = _useState5[0],
10009
- setIsOpen = _useState5[1];
10010
- var _useState6 = React.useState(''),
10011
- searchTerm = _useState6[0],
10012
- setSearchTerm = _useState6[1];
10013
- var _useState7 = React.useState(-1),
10014
- focusedIndex = _useState7[0],
10015
- setFocusedIndex = _useState7[1];
10016
- var _useState8 = React.useState(''),
10017
- internalError = _useState8[0],
10018
- setInternalError = _useState8[1];
10172
+ var _useState6 = React.useState(false),
10173
+ isOpen = _useState6[0],
10174
+ setIsOpen = _useState6[1];
10175
+ var _useState7 = React.useState(''),
10176
+ searchTerm = _useState7[0],
10177
+ setSearchTerm = _useState7[1];
10178
+ var _useState8 = React.useState(-1),
10179
+ focusedIndex = _useState8[0],
10180
+ setFocusedIndex = _useState8[1];
10181
+ var _useState9 = React.useState(''),
10182
+ internalError = _useState9[0],
10183
+ setInternalError = _useState9[1];
10019
10184
  var dropdownRef = React.useRef(null);
10020
10185
  var inputRef = React.useRef(null);
10021
10186
  var listRef = React.useRef(null);
@@ -10443,18 +10608,18 @@
10443
10608
  onChange = props.onChange,
10444
10609
  onValidation = props.onValidation,
10445
10610
  restProps = _objectWithoutPropertiesLoose(props, _excluded3$1);
10446
- var _useState9 = React.useState({
10611
+ var _useState0 = React.useState({
10447
10612
  from: '',
10448
10613
  to: ''
10449
10614
  }),
10450
- form = _useState9[0],
10451
- setForm = _useState9[1];
10452
- var _useState0 = React.useState(''),
10453
- internalError = _useState0[0],
10454
- setInternalError = _useState0[1];
10455
- var _useState1 = React.useState(true),
10456
- isValid = _useState1[0],
10457
- setIsValid = _useState1[1];
10615
+ form = _useState0[0],
10616
+ setForm = _useState0[1];
10617
+ var _useState1 = React.useState(''),
10618
+ internalError = _useState1[0],
10619
+ setInternalError = _useState1[1];
10620
+ var _useState10 = React.useState(true),
10621
+ isValid = _useState10[0],
10622
+ setIsValid = _useState10[1];
10458
10623
 
10459
10624
  // Validate required props
10460
10625
  if (!id) {
@@ -13005,25 +13170,32 @@
13005
13170
  function ok(forcedPwd) {
13006
13171
  if (onOK && canOK()) onOK(user, forcedPwd || password);
13007
13172
  }
13173
+
13174
+ // Helper function for backward compatibility
13175
+ // TextField2 now supports both strings and React elements
13008
13176
  function tx(txt) {
13177
+ // For TextField2, we can pass strings directly for better performance
13178
+ // But keep this function for backward compatibility with other components
13009
13179
  return /*#__PURE__*/React__default["default"].createElement(Text, null, txt);
13010
13180
  }
13011
- function changeUser(id, value) {
13181
+ function changeUser(_, value) {
13012
13182
  setUser(value);
13013
13183
  }
13014
- function changePassword(id, value) {
13184
+ function changePassword(_, value) {
13015
13185
  setPassword(value);
13016
13186
  }
13017
13187
  return /*#__PURE__*/React__default["default"].createElement("div", {
13018
13188
  className: "login-box"
13019
- }, /*#__PURE__*/React__default["default"].createElement("main", null, /*#__PURE__*/React__default["default"].createElement(TextField, {
13189
+ }, /*#__PURE__*/React__default["default"].createElement("main", null, /*#__PURE__*/React__default["default"].createElement(TextField2, {
13190
+ id: "loginbox-user",
13020
13191
  label: tx(userLabel),
13021
13192
  value: user,
13022
13193
  onChange: changeUser,
13023
13194
  onEnter: ok,
13024
13195
  outlined: true,
13025
- autoComplete: "on"
13026
- }), /*#__PURE__*/React__default["default"].createElement(TextField, {
13196
+ autoComplete: "username",
13197
+ required: true
13198
+ }), /*#__PURE__*/React__default["default"].createElement(TextField2, {
13027
13199
  id: "loginbox-password",
13028
13200
  label: tx(passwordLabel),
13029
13201
  value: password,
@@ -13031,7 +13203,8 @@
13031
13203
  onEnter: ok,
13032
13204
  type: "password",
13033
13205
  outlined: true,
13034
- autoComplete: "on"
13206
+ autoComplete: "current-password",
13207
+ required: true
13035
13208
  })), /*#__PURE__*/React__default["default"].createElement("footer", null, loading ? /*#__PURE__*/React__default["default"].createElement("div", {
13036
13209
  className: "load-box"
13037
13210
  }, /*#__PURE__*/React__default["default"].createElement(Icon, {