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.cjs CHANGED
@@ -1695,12 +1695,30 @@ var Tooltip = function Tooltip(props) {
1695
1695
  top: top,
1696
1696
  left: left
1697
1697
  };
1698
+
1699
+ // Text element - support both string and React components
1700
+ var textElement = React.useMemo(function () {
1701
+ if (!text) return null;
1702
+
1703
+ // If text is already a React element, use it directly
1704
+ if (React__default["default"].isValidElement(text)) {
1705
+ return text;
1706
+ }
1707
+
1708
+ // If text is a string, wrap it in Text component
1709
+ if (typeof text === 'string') {
1710
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, text);
1711
+ }
1712
+
1713
+ // Fallback for other types (convert to string)
1714
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(text));
1715
+ }, [text]);
1698
1716
  return /*#__PURE__*/React__default["default"].createElement("div", {
1699
1717
  className: "tooltip"
1700
1718
  }, /*#__PURE__*/React__default["default"].createElement("span", {
1701
1719
  className: "tooltip-text",
1702
1720
  style: style
1703
- }, /*#__PURE__*/React__default["default"].createElement(Text, null, text)), props.children);
1721
+ }, textElement), props.children);
1704
1722
  };
1705
1723
 
1706
1724
  /**
@@ -2167,6 +2185,24 @@ var Button = function Button(props) {
2167
2185
  'aria-describedby': tooltip ? id + "-tooltip" : undefined
2168
2186
  };
2169
2187
 
2188
+ // Label text - support both string and React components
2189
+ var labelElement = React.useMemo(function () {
2190
+ if (!label) return null;
2191
+
2192
+ // If label is already a React element, use it directly
2193
+ if (React__default["default"].isValidElement(label)) {
2194
+ return label;
2195
+ }
2196
+
2197
+ // If label is a string, wrap it in Text component
2198
+ if (typeof label === 'string') {
2199
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, label);
2200
+ }
2201
+
2202
+ // Fallback for other types (convert to string)
2203
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(label));
2204
+ }, [label]);
2205
+
2170
2206
  // Icon configuration
2171
2207
  var iconProps = {
2172
2208
  icon: loading ? 'hourglass_empty' : icon,
@@ -2184,7 +2220,7 @@ var Button = function Button(props) {
2184
2220
  onBlur: handleBlur,
2185
2221
  onKeyDown: handleKeyDown,
2186
2222
  disabled: disabled || loading
2187
- }, 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", {
2223
+ }, ariaAttributes, restProps), (icon || loading) && /*#__PURE__*/React__default["default"].createElement(Icon, iconProps), labelElement, loading && !icon && /*#__PURE__*/React__default["default"].createElement("span", {
2188
2224
  className: "loading-text"
2189
2225
  }, "Loading..."));
2190
2226
  };
@@ -2280,8 +2316,8 @@ var ActionButton = function ActionButton(props) {
2280
2316
  Button.propTypes = {
2281
2317
  /** Unique identifier for the button */
2282
2318
  id: PropTypes.string,
2283
- /** Button text label */
2284
- label: PropTypes.string,
2319
+ /** Button text label - can be string or React element */
2320
+ label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
2285
2321
  /** Icon name for Material Icons */
2286
2322
  icon: PropTypes.string,
2287
2323
  /** Click handler function */
@@ -3112,11 +3148,28 @@ var Header = function Header(props) {
3112
3148
  var style = props.img ? {
3113
3149
  backgroundImage: "url(" + props.img + ")"
3114
3150
  } : {};
3115
- var title = /*#__PURE__*/React__default["default"].createElement(Text, null, props.title);
3151
+
3152
+ // Title element - support both string and React components
3153
+ var titleElement = React.useMemo(function () {
3154
+ if (!props.title) return null;
3155
+
3156
+ // If title is already a React element, use it directly
3157
+ if (React__default["default"].isValidElement(props.title)) {
3158
+ return props.title;
3159
+ }
3160
+
3161
+ // If title is a string, wrap it in Text component
3162
+ if (typeof props.title === 'string') {
3163
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, props.title);
3164
+ }
3165
+
3166
+ // Fallback for other types (convert to string)
3167
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(props.title));
3168
+ }, [props.title]);
3116
3169
  return /*#__PURE__*/React__default["default"].createElement("header", {
3117
3170
  className: "header " + caption + " " + prominent + " " + dense + " " + theme + " " + props.className,
3118
3171
  style: style
3119
- }, icon, props.title ? /*#__PURE__*/React__default["default"].createElement("label", null, title) : null, /*#__PURE__*/React__default["default"].createElement("span", {
3172
+ }, icon, props.title ? /*#__PURE__*/React__default["default"].createElement("label", null, titleElement) : null, /*#__PURE__*/React__default["default"].createElement("span", {
3120
3173
  className: "actions"
3121
3174
  }, props.children));
3122
3175
  };
@@ -3895,7 +3948,24 @@ var TextField = function TextField(props) {
3895
3948
  var labelStyle = label ? "" : "no-label";
3896
3949
  var labelPositionStyle = labelPosition == 'left' ? "label-left" : "label-top";
3897
3950
  var style = labelStyle + " " + labelPositionStyle + " " + borderStyle + " textfield-" + type;
3898
- var labelTxt = /*#__PURE__*/React__default["default"].createElement(Text, null, label);
3951
+
3952
+ // Label text - support both string and React components
3953
+ var labelTxt = React.useMemo(function () {
3954
+ if (!label) return null;
3955
+
3956
+ // If label is already a React element, use it directly
3957
+ if (React__default["default"].isValidElement(label)) {
3958
+ return label;
3959
+ }
3960
+
3961
+ // If label is a string, wrap it in Text component
3962
+ if (typeof label === 'string') {
3963
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, label);
3964
+ }
3965
+
3966
+ // Fallback for other types (convert to string)
3967
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(label));
3968
+ }, [label]);
3899
3969
  var placeholderTxt = site.translate ? site.translate(placeholder) : placeholder;
3900
3970
  return /*#__PURE__*/React__default["default"].createElement("div", {
3901
3971
  className: style + " " + id + " " + className,
@@ -3973,7 +4043,24 @@ var TextArea = function TextArea(props) {
3973
4043
  }
3974
4044
  var labelStyle = label ? "" : "no-label";
3975
4045
  var style = "textarea " + labelStyle + " textarea-" + type;
3976
- var labelTxt = /*#__PURE__*/React__default["default"].createElement(Text, null, label);
4046
+
4047
+ // Label text - support both string and React components
4048
+ var labelTxt = React.useMemo(function () {
4049
+ if (!label) return null;
4050
+
4051
+ // If label is already a React element, use it directly
4052
+ if (React__default["default"].isValidElement(label)) {
4053
+ return label;
4054
+ }
4055
+
4056
+ // If label is a string, wrap it in Text component
4057
+ if (typeof label === 'string') {
4058
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, label);
4059
+ }
4060
+
4061
+ // Fallback for other types (convert to string)
4062
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(label));
4063
+ }, [label]);
3977
4064
  var placeholderTxt = site.translate ? site.translate(placeholder) : placeholder;
3978
4065
  return /*#__PURE__*/React__default["default"].createElement("div", {
3979
4066
  className: "" + style,
@@ -4144,7 +4231,24 @@ var DateRange = function DateRange(props) {
4144
4231
  var next = Object.assign({}, form, (_Object$assign = {}, _Object$assign[id] = value, _Object$assign));
4145
4232
  setForm(next);
4146
4233
  }
4147
- var labelTxt = label ? /*#__PURE__*/React__default["default"].createElement(Text, null, label) : null;
4234
+
4235
+ // Label text - support both string and React components
4236
+ var labelTxt = React.useMemo(function () {
4237
+ if (!label) return null;
4238
+
4239
+ // If label is already a React element, use it directly
4240
+ if (React__default["default"].isValidElement(label)) {
4241
+ return label;
4242
+ }
4243
+
4244
+ // If label is a string, wrap it in Text component
4245
+ if (typeof label === 'string') {
4246
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, label);
4247
+ }
4248
+
4249
+ // Fallback for other types (convert to string)
4250
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(label));
4251
+ }, [label]);
4148
4252
  return /*#__PURE__*/React__default["default"].createElement("div", {
4149
4253
  className: "date-range"
4150
4254
  }, label ? /*#__PURE__*/React__default["default"].createElement("label", null, labelTxt) : null, /*#__PURE__*/React__default["default"].createElement(TextField, {
@@ -4172,7 +4276,24 @@ var PasswordField = function PasswordField(props) {
4172
4276
  function toggle() {
4173
4277
  setShow(!show);
4174
4278
  }
4175
- var labelTxt = label ? /*#__PURE__*/React__default["default"].createElement(Text, null, label) : null;
4279
+
4280
+ // Label text - support both string and React components
4281
+ var labelTxt = React.useMemo(function () {
4282
+ if (!label) return null;
4283
+
4284
+ // If label is already a React element, use it directly
4285
+ if (React__default["default"].isValidElement(label)) {
4286
+ return label;
4287
+ }
4288
+
4289
+ // If label is a string, wrap it in Text component
4290
+ if (typeof label === 'string') {
4291
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, label);
4292
+ }
4293
+
4294
+ // Fallback for other types (convert to string)
4295
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(label));
4296
+ }, [label]);
4176
4297
  return /*#__PURE__*/React__default["default"].createElement("div", {
4177
4298
  className: "password-field"
4178
4299
  }, /*#__PURE__*/React__default["default"].createElement(TextField, {
@@ -4189,8 +4310,8 @@ var PasswordField = function PasswordField(props) {
4189
4310
  }));
4190
4311
  };
4191
4312
 
4192
- 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"],
4193
- _excluded2$5 = ["items", "children", "selected", "onSelect", "groupBy", "groupRenderer", "searchTerm", "onSearch", "searchable", "searchPlaceholder", "multiSelect", "dense", "disabled", "animated", "cssClasses", "ariaAttributes", "style"],
4313
+ 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"],
4314
+ _excluded2$5 = ["items", "children", "selected", "onSelect", "groupBy", "groupRenderer", "searchTerm", "onSearch", "searchable", "searchPlaceholder", "searchPosition", "multiSelect", "dense", "disabled", "animated", "cssClasses", "ariaAttributes", "style"],
4194
4315
  _excluded3$2 = ["id", "icon", "iconTooltip", "line1", "line2", "meta", "avatar", "badge", "actions", "disabled"];
4195
4316
 
4196
4317
  /**
@@ -4217,6 +4338,8 @@ var List = function List(props) {
4217
4338
  searchPlaceholder = _props$searchPlacehol === void 0 ? "Search..." : _props$searchPlacehol,
4218
4339
  _props$searchBy = props.searchBy,
4219
4340
  searchBy = _props$searchBy === void 0 ? ['line1', 'line2'] : _props$searchBy,
4341
+ _props$searchPosition = props.searchPosition,
4342
+ searchPosition = _props$searchPosition === void 0 ? 'top' : _props$searchPosition,
4220
4343
  _props$sortable = props.sortable,
4221
4344
  sortable = _props$sortable === void 0 ? false : _props$sortable,
4222
4345
  sortBy = props.sortBy,
@@ -4228,6 +4351,8 @@ var List = function List(props) {
4228
4351
  onMultiSelect = props.onMultiSelect,
4229
4352
  _props$dense = props.dense,
4230
4353
  dense = _props$dense === void 0 ? false : _props$dense,
4354
+ _props$outlined = props.outlined,
4355
+ outlined = _props$outlined === void 0 ? false : _props$outlined,
4231
4356
  _props$disabled = props.disabled,
4232
4357
  disabled = _props$disabled === void 0 ? false : _props$disabled,
4233
4358
  _props$animated = props.animated,
@@ -4276,7 +4401,7 @@ var List = function List(props) {
4276
4401
  }, [disabled, multiSelect, selected, onSelect, onMultiSelect]);
4277
4402
 
4278
4403
  // Handle search
4279
- var handleSearch = React.useCallback(function (searchId, value) {
4404
+ var handleSearch = React.useCallback(function (_, value) {
4280
4405
  setSearchTerm(value);
4281
4406
  }, []);
4282
4407
 
@@ -4317,8 +4442,23 @@ var List = function List(props) {
4317
4442
  if (onSort) onSort(newConfig);
4318
4443
  }, [sortable, sortConfig, onSort]);
4319
4444
 
4445
+ // Search component
4446
+ var SearchComponent = function SearchComponent() {
4447
+ return searchable && /*#__PURE__*/React__default["default"].createElement("div", {
4448
+ className: "list__search"
4449
+ }, /*#__PURE__*/React__default["default"].createElement(TextField, {
4450
+ id: "list-search",
4451
+ placeholder: searchPlaceholder,
4452
+ value: searchTerm,
4453
+ onChange: handleSearch,
4454
+ icon: "search",
4455
+ outlined: true,
4456
+ size: "small"
4457
+ }));
4458
+ };
4459
+
4320
4460
  // Generate CSS classes
4321
- var cssClasses = ['list', dense && 'list--dense', disabled && 'list--disabled', animated && 'list--animated', loading && 'list--loading', className].filter(Boolean).join(' ');
4461
+ var cssClasses = ['list', dense && 'list--dense', outlined && 'list--outlined', disabled && 'list--disabled', animated && 'list--animated', loading && 'list--loading', className].filter(Boolean).join(' ');
4322
4462
 
4323
4463
  // Accessibility attributes
4324
4464
  var ariaAttributes = {
@@ -4345,22 +4485,12 @@ var List = function List(props) {
4345
4485
  return /*#__PURE__*/React__default["default"].createElement("div", _extends({
4346
4486
  className: cssClasses,
4347
4487
  style: style
4348
- }, ariaAttributes, restProps), searchable && /*#__PURE__*/React__default["default"].createElement("div", {
4349
- className: "list__search"
4350
- }, /*#__PURE__*/React__default["default"].createElement(TextField, {
4351
- id: "list-search",
4352
- placeholder: searchPlaceholder,
4353
- value: searchTerm,
4354
- onChange: handleSearch,
4355
- icon: "search",
4356
- outlined: true,
4357
- size: "small"
4358
- })), /*#__PURE__*/React__default["default"].createElement("div", {
4488
+ }, ariaAttributes, restProps), searchPosition === 'top' && /*#__PURE__*/React__default["default"].createElement(SearchComponent, null), /*#__PURE__*/React__default["default"].createElement("div", {
4359
4489
  className: "list__empty"
4360
4490
  }, /*#__PURE__*/React__default["default"].createElement(Icon, {
4361
4491
  icon: emptyIcon,
4362
4492
  size: "large"
4363
- }), /*#__PURE__*/React__default["default"].createElement(Text, null, emptyMessage)), children);
4493
+ }), /*#__PURE__*/React__default["default"].createElement(Text, null, emptyMessage)), searchPosition === 'bottom' && /*#__PURE__*/React__default["default"].createElement(SearchComponent, null), children);
4364
4494
  }
4365
4495
 
4366
4496
  // Render grouped or normal list
@@ -4377,17 +4507,7 @@ var List = function List(props) {
4377
4507
  className: cssClasses,
4378
4508
  style: style,
4379
4509
  ref: listRef
4380
- }, ariaAttributes, restProps), searchable && /*#__PURE__*/React__default["default"].createElement("div", {
4381
- className: "list__search"
4382
- }, /*#__PURE__*/React__default["default"].createElement(TextField, {
4383
- id: "list-search",
4384
- placeholder: searchPlaceholder,
4385
- value: searchTerm,
4386
- onChange: handleSearch,
4387
- icon: "search",
4388
- outlined: true,
4389
- size: "small"
4390
- })), sortable && sortBy && /*#__PURE__*/React__default["default"].createElement("div", {
4510
+ }, ariaAttributes, restProps), searchPosition === 'top' && /*#__PURE__*/React__default["default"].createElement(SearchComponent, null), sortable && sortBy && /*#__PURE__*/React__default["default"].createElement("div", {
4391
4511
  className: "list__sort"
4392
4512
  }, /*#__PURE__*/React__default["default"].createElement("button", {
4393
4513
  className: "list__sort-button",
@@ -4416,7 +4536,7 @@ var List = function List(props) {
4416
4536
  disabled: disabled,
4417
4537
  animated: animated
4418
4538
  });
4419
- })), children);
4539
+ })), searchPosition === 'bottom' && /*#__PURE__*/React__default["default"].createElement(SearchComponent, null), children);
4420
4540
  };
4421
4541
 
4422
4542
  /**
@@ -4436,6 +4556,8 @@ var GroupedList = function GroupedList(props) {
4436
4556
  searchable = _props$searchable2 === void 0 ? false : _props$searchable2,
4437
4557
  _props$searchPlacehol2 = props.searchPlaceholder,
4438
4558
  searchPlaceholder = _props$searchPlacehol2 === void 0 ? "Search..." : _props$searchPlacehol2,
4559
+ _props$searchPosition2 = props.searchPosition,
4560
+ searchPosition = _props$searchPosition2 === void 0 ? 'top' : _props$searchPosition2,
4439
4561
  _props$multiSelect2 = props.multiSelect,
4440
4562
  multiSelect = _props$multiSelect2 === void 0 ? false : _props$multiSelect2,
4441
4563
  _props$dense2 = props.dense,
@@ -4482,20 +4604,25 @@ var GroupedList = function GroupedList(props) {
4482
4604
  return next;
4483
4605
  });
4484
4606
  }, []);
4607
+
4608
+ // Search component for grouped list
4609
+ var GroupedSearchComponent = function GroupedSearchComponent() {
4610
+ return searchable && /*#__PURE__*/React__default["default"].createElement("div", {
4611
+ className: "list__search"
4612
+ }, /*#__PURE__*/React__default["default"].createElement(TextField, {
4613
+ id: "grouped-list-search",
4614
+ placeholder: searchPlaceholder,
4615
+ value: searchTerm,
4616
+ onChange: onSearch,
4617
+ icon: "search",
4618
+ outlined: true,
4619
+ size: "small"
4620
+ }));
4621
+ };
4485
4622
  return /*#__PURE__*/React__default["default"].createElement("div", _extends({
4486
4623
  className: cssClasses + " grouped",
4487
4624
  style: style
4488
- }, ariaAttributes, restProps), searchable && /*#__PURE__*/React__default["default"].createElement("div", {
4489
- className: "list__search"
4490
- }, /*#__PURE__*/React__default["default"].createElement(TextField, {
4491
- id: "grouped-list-search",
4492
- placeholder: searchPlaceholder,
4493
- value: searchTerm,
4494
- onChange: onSearch,
4495
- icon: "search",
4496
- outlined: true,
4497
- size: "small"
4498
- })), groups.map(function (group) {
4625
+ }, ariaAttributes, restProps), searchPosition === 'top' && /*#__PURE__*/React__default["default"].createElement(GroupedSearchComponent, null), groups.map(function (group) {
4499
4626
  var isCollapsed = collapsedGroups.has(group.name);
4500
4627
  var groupTitle = groupRenderer ? groupRenderer(group) : /*#__PURE__*/React__default["default"].createElement(Text, null, group.name);
4501
4628
  return /*#__PURE__*/React__default["default"].createElement(React.Fragment, {
@@ -4538,7 +4665,7 @@ var GroupedList = function GroupedList(props) {
4538
4665
  animated: animated
4539
4666
  });
4540
4667
  })));
4541
- }), children);
4668
+ }), searchPosition === 'bottom' && /*#__PURE__*/React__default["default"].createElement(GroupedSearchComponent, null), children);
4542
4669
  };
4543
4670
 
4544
4671
  /**
@@ -4639,14 +4766,14 @@ var ListItem = function ListItem(_ref) {
4639
4766
  }, /*#__PURE__*/React__default["default"].createElement(Text, {
4640
4767
  className: "list__item-line2",
4641
4768
  size: "small"
4642
- }, line2))), meta && /*#__PURE__*/React__default["default"].createElement("div", {
4769
+ }, line2))), actions && /*#__PURE__*/React__default["default"].createElement("div", {
4770
+ className: "list__item-actions",
4771
+ role: "toolbar"
4772
+ }, actions), meta && /*#__PURE__*/React__default["default"].createElement("div", {
4643
4773
  className: "list__item-meta"
4644
4774
  }, typeof meta === 'string' ? /*#__PURE__*/React__default["default"].createElement(Text, {
4645
4775
  size: "small"
4646
- }, meta) : meta), actions && /*#__PURE__*/React__default["default"].createElement("div", {
4647
- className: "list__item-actions",
4648
- role: "toolbar"
4649
- }, actions));
4776
+ }, meta) : meta));
4650
4777
  };
4651
4778
 
4652
4779
  // PropTypes for List component
@@ -4688,6 +4815,8 @@ List.propTypes = {
4688
4815
  searchPlaceholder: PropTypes.string,
4689
4816
  /** Properties to search by */
4690
4817
  searchBy: PropTypes.arrayOf(PropTypes.string),
4818
+ /** Search position */
4819
+ searchPosition: PropTypes.oneOf(['top', 'bottom']),
4691
4820
  /** Enable sorting */
4692
4821
  sortable: PropTypes.bool,
4693
4822
  /** Property to sort by */
@@ -4702,6 +4831,8 @@ List.propTypes = {
4702
4831
  onMultiSelect: PropTypes.func,
4703
4832
  /** Dense layout */
4704
4833
  dense: PropTypes.bool,
4834
+ /** Outlined variant with borders */
4835
+ outlined: PropTypes.bool,
4705
4836
  /** Disabled state */
4706
4837
  disabled: PropTypes.bool,
4707
4838
  /** Enable animations */
@@ -9668,6 +9799,9 @@ var TextField2 = function TextField2(props) {
9668
9799
  var _useState4 = React.useState(true),
9669
9800
  isValid = _useState4[0],
9670
9801
  setIsValid = _useState4[1];
9802
+ var _useState5 = React.useState(false),
9803
+ hasBeenTouched = _useState5[0],
9804
+ setHasBeenTouched = _useState5[1];
9671
9805
  var inputRef = React.useRef(null);
9672
9806
  var debounceRef = React.useRef(null);
9673
9807
 
@@ -9676,8 +9810,14 @@ var TextField2 = function TextField2(props) {
9676
9810
  console.warn('TextField2 component: id prop is required');
9677
9811
  }
9678
9812
 
9679
- // Validate value and set error states
9813
+ // Validate value and set error states - only after user interaction
9680
9814
  React.useEffect(function () {
9815
+ // Don't validate required fields until user has interacted with the field
9816
+ if (!hasBeenTouched && required && !value) {
9817
+ setIsValid(true);
9818
+ setInternalError('');
9819
+ return;
9820
+ }
9681
9821
  if (validation && value !== undefined) {
9682
9822
  var validationResult = validation(value);
9683
9823
  var valid = typeof validationResult === 'boolean' ? validationResult : validationResult.valid;
@@ -9687,14 +9827,14 @@ var TextField2 = function TextField2(props) {
9687
9827
  if (onValidation) {
9688
9828
  onValidation(id, valid, errorMessage);
9689
9829
  }
9690
- } else if (required && !value) {
9830
+ } else if (required && !value && hasBeenTouched) {
9691
9831
  setIsValid(false);
9692
9832
  setInternalError('This field is required');
9693
9833
  } else {
9694
9834
  setIsValid(true);
9695
9835
  setInternalError('');
9696
9836
  }
9697
- }, [value, required, id]); // Removed validation and onValidation from dependencies to prevent infinite loops
9837
+ }, [value, required, id, hasBeenTouched]); // Added hasBeenTouched to dependencies
9698
9838
 
9699
9839
  // Handle input changes with debouncing
9700
9840
  var handleChange = React.useCallback(function (event) {
@@ -9702,6 +9842,11 @@ var TextField2 = function TextField2(props) {
9702
9842
  event.stopPropagation();
9703
9843
  var newValue = event.target.value;
9704
9844
 
9845
+ // Mark field as touched on first change
9846
+ if (!hasBeenTouched) {
9847
+ setHasBeenTouched(true);
9848
+ }
9849
+
9705
9850
  // Clear previous debounce
9706
9851
  if (debounceRef.current) {
9707
9852
  clearTimeout(debounceRef.current);
@@ -9713,7 +9858,7 @@ var TextField2 = function TextField2(props) {
9713
9858
  } else {
9714
9859
  if (onChange) onChange(id, newValue, event);
9715
9860
  }
9716
- }, [disabled, readOnly, id, onChange, debounceMs]);
9861
+ }, [disabled, readOnly, id, onChange, debounceMs, hasBeenTouched]);
9717
9862
 
9718
9863
  // Handle key press events
9719
9864
  var handleKeyPress = React.useCallback(function (event) {
@@ -9745,8 +9890,13 @@ var TextField2 = function TextField2(props) {
9745
9890
  var handleBlur = React.useCallback(function (event) {
9746
9891
  if (disabled) return;
9747
9892
  setIsFocused(false);
9893
+
9894
+ // Mark field as touched on blur if it hasn't been touched yet
9895
+ if (!hasBeenTouched) {
9896
+ setHasBeenTouched(true);
9897
+ }
9748
9898
  if (onBlur) onBlur(event);
9749
- }, [disabled, onBlur]);
9899
+ }, [disabled, onBlur, hasBeenTouched]);
9750
9900
 
9751
9901
  // Handle clear action
9752
9902
  var handleClear = React.useCallback(function () {
@@ -9802,8 +9952,23 @@ var TextField2 = function TextField2(props) {
9802
9952
  autoComplete: autoComplete
9803
9953
  }, ariaAttributes, restProps);
9804
9954
 
9805
- // Label text
9806
- var labelTxt = label ? /*#__PURE__*/React__default["default"].createElement(Text, null, label) : null;
9955
+ // Label text - support both string and React components
9956
+ var labelTxt = React.useMemo(function () {
9957
+ if (!label) return null;
9958
+
9959
+ // If label is already a React element, use it directly
9960
+ if (React__default["default"].isValidElement(label)) {
9961
+ return label;
9962
+ }
9963
+
9964
+ // If label is a string, wrap it in Text component
9965
+ if (typeof label === 'string') {
9966
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, label);
9967
+ }
9968
+
9969
+ // Fallback for other types (convert to string)
9970
+ return /*#__PURE__*/React__default["default"].createElement(Text, null, String(label));
9971
+ }, [label]);
9807
9972
  var placeholderTxt = site != null && site.translate ? site.translate(placeholder) : placeholder;
9808
9973
 
9809
9974
  // Error/helper text
@@ -9881,8 +10046,8 @@ TextField2.propTypes = {
9881
10046
  type: PropTypes.oneOf(['text', 'email', 'password', 'number', 'tel', 'url', 'search', 'date', 'time', 'datetime-local', 'month', 'week', 'textarea']),
9882
10047
  /** Additional CSS classes */
9883
10048
  className: PropTypes.string,
9884
- /** Field label */
9885
- label: PropTypes.string,
10049
+ /** Field label - can be string or React element */
10050
+ label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
9886
10051
  /** Label position */
9887
10052
  labelPosition: PropTypes.oneOf(['top', 'left']),
9888
10053
  /** Placeholder text */
@@ -10011,18 +10176,18 @@ var DropDown2 = function DropDown2(props) {
10011
10176
  onSearch = props.onSearch,
10012
10177
  restProps = _objectWithoutPropertiesLoose(props, _excluded2$3);
10013
10178
  React.useContext(SiteContext);
10014
- var _useState5 = React.useState(false),
10015
- isOpen = _useState5[0],
10016
- setIsOpen = _useState5[1];
10017
- var _useState6 = React.useState(''),
10018
- searchTerm = _useState6[0],
10019
- setSearchTerm = _useState6[1];
10020
- var _useState7 = React.useState(-1),
10021
- focusedIndex = _useState7[0],
10022
- setFocusedIndex = _useState7[1];
10023
- var _useState8 = React.useState(''),
10024
- internalError = _useState8[0],
10025
- setInternalError = _useState8[1];
10179
+ var _useState6 = React.useState(false),
10180
+ isOpen = _useState6[0],
10181
+ setIsOpen = _useState6[1];
10182
+ var _useState7 = React.useState(''),
10183
+ searchTerm = _useState7[0],
10184
+ setSearchTerm = _useState7[1];
10185
+ var _useState8 = React.useState(-1),
10186
+ focusedIndex = _useState8[0],
10187
+ setFocusedIndex = _useState8[1];
10188
+ var _useState9 = React.useState(''),
10189
+ internalError = _useState9[0],
10190
+ setInternalError = _useState9[1];
10026
10191
  var dropdownRef = React.useRef(null);
10027
10192
  var inputRef = React.useRef(null);
10028
10193
  var listRef = React.useRef(null);
@@ -10450,18 +10615,18 @@ var DateRange2 = function DateRange2(props) {
10450
10615
  onChange = props.onChange,
10451
10616
  onValidation = props.onValidation,
10452
10617
  restProps = _objectWithoutPropertiesLoose(props, _excluded3$1);
10453
- var _useState9 = React.useState({
10618
+ var _useState0 = React.useState({
10454
10619
  from: '',
10455
10620
  to: ''
10456
10621
  }),
10457
- form = _useState9[0],
10458
- setForm = _useState9[1];
10459
- var _useState0 = React.useState(''),
10460
- internalError = _useState0[0],
10461
- setInternalError = _useState0[1];
10462
- var _useState1 = React.useState(true),
10463
- isValid = _useState1[0],
10464
- setIsValid = _useState1[1];
10622
+ form = _useState0[0],
10623
+ setForm = _useState0[1];
10624
+ var _useState1 = React.useState(''),
10625
+ internalError = _useState1[0],
10626
+ setInternalError = _useState1[1];
10627
+ var _useState10 = React.useState(true),
10628
+ isValid = _useState10[0],
10629
+ setIsValid = _useState10[1];
10465
10630
 
10466
10631
  // Validate required props
10467
10632
  if (!id) {
@@ -13012,25 +13177,32 @@ var LoginBox = function LoginBox(_ref) {
13012
13177
  function ok(forcedPwd) {
13013
13178
  if (onOK && canOK()) onOK(user, forcedPwd || password);
13014
13179
  }
13180
+
13181
+ // Helper function for backward compatibility
13182
+ // TextField2 now supports both strings and React elements
13015
13183
  function tx(txt) {
13184
+ // For TextField2, we can pass strings directly for better performance
13185
+ // But keep this function for backward compatibility with other components
13016
13186
  return /*#__PURE__*/React__default["default"].createElement(Text, null, txt);
13017
13187
  }
13018
- function changeUser(id, value) {
13188
+ function changeUser(_, value) {
13019
13189
  setUser(value);
13020
13190
  }
13021
- function changePassword(id, value) {
13191
+ function changePassword(_, value) {
13022
13192
  setPassword(value);
13023
13193
  }
13024
13194
  return /*#__PURE__*/React__default["default"].createElement("div", {
13025
13195
  className: "login-box"
13026
- }, /*#__PURE__*/React__default["default"].createElement("main", null, /*#__PURE__*/React__default["default"].createElement(TextField, {
13196
+ }, /*#__PURE__*/React__default["default"].createElement("main", null, /*#__PURE__*/React__default["default"].createElement(TextField2, {
13197
+ id: "loginbox-user",
13027
13198
  label: tx(userLabel),
13028
13199
  value: user,
13029
13200
  onChange: changeUser,
13030
13201
  onEnter: ok,
13031
13202
  outlined: true,
13032
- autoComplete: "on"
13033
- }), /*#__PURE__*/React__default["default"].createElement(TextField, {
13203
+ autoComplete: "username",
13204
+ required: true
13205
+ }), /*#__PURE__*/React__default["default"].createElement(TextField2, {
13034
13206
  id: "loginbox-password",
13035
13207
  label: tx(passwordLabel),
13036
13208
  value: password,
@@ -13038,7 +13210,8 @@ var LoginBox = function LoginBox(_ref) {
13038
13210
  onEnter: ok,
13039
13211
  type: "password",
13040
13212
  outlined: true,
13041
- autoComplete: "on"
13213
+ autoComplete: "current-password",
13214
+ required: true
13042
13215
  })), /*#__PURE__*/React__default["default"].createElement("footer", null, loading ? /*#__PURE__*/React__default["default"].createElement("div", {
13043
13216
  className: "load-box"
13044
13217
  }, /*#__PURE__*/React__default["default"].createElement(Icon, {