@ttoss/ui 5.10.7 → 5.11.0

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/README.md CHANGED
@@ -89,7 +89,7 @@ export const customTheme: Theme = {
89
89
  - `ActionButton` - Action-specific buttons
90
90
  - `IconButton` - Icon-only buttons
91
91
  - `CloseButton` - Close/dismiss buttons
92
- - `Input` - Text input fields
92
+ - `Input` - Text input fields with icon support
93
93
  - `InputNumber` - Numeric input fields
94
94
  - `InputPassword` - Password input with reveal
95
95
  - `Textarea` - Multi-line text input
@@ -100,6 +100,115 @@ export const customTheme: Theme = {
100
100
  - `Slider` - Range slider controls
101
101
  - `SegmentedControl` - Multi-option selector
102
102
 
103
+ #### Input Component Features
104
+
105
+ The `Input` component supports leading and trailing icons with tooltips:
106
+
107
+ ```tsx
108
+ import { Input } from '@ttoss/ui';
109
+
110
+ // Simplified syntax - icon as string
111
+ <Input
112
+ placeholder="Search..."
113
+ leadingIcon="ant-design:search-outlined"
114
+ trailingIcon="ant-design:info-circle-outlined"
115
+ />
116
+
117
+ // Full syntax with tooltip and click handler
118
+ <Input
119
+ placeholder="Search..."
120
+ leadingIcon={{
121
+ icon: 'ant-design:search-outlined',
122
+ onClick: () => console.log('Search clicked'),
123
+ tooltip: 'Click to search'
124
+ }}
125
+ trailingIcon={{
126
+ icon: 'ant-design:info-circle-outlined',
127
+ tooltip: 'Additional information',
128
+ tooltipProps: { place: 'right' }
129
+ }}
130
+ />
131
+
132
+ // SVG icons from @iconify
133
+ import searchIcon from '@iconify/icons-mdi/search';
134
+
135
+ <Input
136
+ placeholder="Email"
137
+ leadingIcon={searchIcon}
138
+ />
139
+ ```
140
+
141
+ **Testing Input Icons:**
142
+
143
+ Use `data-testid` to identify icons in tests. The Input component provides test IDs for icon containers, and each icon has its own `data-testid="iconify-icon"`:
144
+
145
+ ```tsx
146
+ import { render, screen } from '@testing-library/react';
147
+
148
+ test('should render input with icons', () => {
149
+ render(
150
+ <Input placeholder="Search" leadingIcon="search" trailingIcon="info" />
151
+ );
152
+
153
+ // Get icon containers (for clicking and tooltip checks)
154
+ const leadingIconContainer = screen.getByTestId('input-leading-icon');
155
+ const trailingIconContainer = screen.getByTestId('input-trailing-icon');
156
+
157
+ expect(leadingIconContainer).toBeInTheDocument();
158
+ expect(trailingIconContainer).toBeInTheDocument();
159
+
160
+ // Get the actual icon elements (for checking icon properties)
161
+ const iconElement = leadingIconContainer.querySelector(
162
+ '[data-testid="iconify-icon"]'
163
+ );
164
+ expect(iconElement).toHaveAttribute('icon', 'search');
165
+ });
166
+
167
+ // Test icon clicks (click on container, where onClick is attached)
168
+ test('should call onClick when icon is clicked', async () => {
169
+ const handleClick = jest.fn();
170
+
171
+ render(
172
+ <Input
173
+ placeholder="Search"
174
+ leadingIcon={{ icon: 'search', onClick: handleClick }}
175
+ />
176
+ );
177
+
178
+ const leadingIcon = screen.getByTestId('input-leading-icon');
179
+ await userEvent.click(leadingIcon);
180
+ expect(handleClick).toHaveBeenCalled();
181
+ });
182
+
183
+ // Test tooltips (check container for tooltip attributes)
184
+ test('should render tooltip', () => {
185
+ render(
186
+ <Input
187
+ placeholder="Search"
188
+ leadingIcon={{ icon: 'search', tooltip: 'Search here' }}
189
+ />
190
+ );
191
+
192
+ const iconContainer = screen.getByTestId('input-leading-icon');
193
+ expect(iconContainer).toHaveAttribute(
194
+ 'data-tooltip-id',
195
+ 'input-leading-icon-tooltip'
196
+ );
197
+ });
198
+
199
+ // Alternative: Query all icons and differentiate by position
200
+ test('should render both icons using iconify-icon testid', () => {
201
+ render(<Input leadingIcon="search" trailingIcon="info" />);
202
+
203
+ const icons = screen.getAllByTestId('iconify-icon');
204
+ expect(icons).toHaveLength(2);
205
+ expect(icons[0]).toHaveAttribute('icon', 'search'); // leading
206
+ expect(icons[1]).toHaveAttribute('icon', 'info'); // trailing
207
+ });
208
+ ```
209
+
210
+ ````
211
+
103
212
  ### Feedback & Status
104
213
 
105
214
  - `Badge` - Status indicators and labels
@@ -134,7 +243,7 @@ export const AppStyles = () => (
134
243
  }}
135
244
  />
136
245
  );
137
- ```
246
+ ````
138
247
 
139
248
  #### Animations
140
249
 
package/dist/esm/index.js CHANGED
@@ -385,41 +385,64 @@ var InfiniteLinearProgress = /* @__PURE__ */__name(() => {
385
385
 
386
386
  // src/components/Input.tsx
387
387
  import { Icon as Icon4 } from "@ttoss/react-icons";
388
- import * as React7 from "react";
389
388
  import { Input as InputUI } from "theme-ui";
390
- var Input = /* @__PURE__ */React7.forwardRef(({
389
+ var isInputIconConfig = /* @__PURE__ */__name(icon => {
390
+ return icon !== void 0 && typeof icon === "object" && "icon" in icon && (typeof icon.icon === "string" || typeof icon.icon === "object" && "body" in icon.icon);
391
+ }, "isInputIconConfig");
392
+ var normalizeIcon = /* @__PURE__ */__name(icon => {
393
+ if (!icon) {
394
+ return void 0;
395
+ }
396
+ if (isInputIconConfig(icon)) {
397
+ return icon;
398
+ }
399
+ return {
400
+ icon
401
+ };
402
+ }, "normalizeIcon");
403
+ var Input = /* @__PURE__ */__name(({
391
404
  leadingIcon,
392
405
  trailingIcon: trailingIconProp,
393
- onLeadingIconClick,
394
- onTrailingIconClick,
395
406
  className,
396
407
  sx,
397
408
  ...inputProps
398
- }, ref) => {
399
- const trailingIcon = inputProps["aria-invalid"] ? "warning-alt" : trailingIconProp;
400
- const isWarning = !inputProps["aria-invalid"] && trailingIcon === "warning-alt";
401
- return /* @__PURE__ */React7.createElement(Flex, {
402
- className: `${className} ${isWarning ? "is-warning" : ""}`,
409
+ }) => {
410
+ const normalizedLeadingIcon = normalizeIcon(leadingIcon);
411
+ const normalizedTrailingIconProp = normalizeIcon(trailingIconProp);
412
+ const ariaInvalid = inputProps["aria-invalid"];
413
+ const isInvalid = ariaInvalid === true || ariaInvalid === "true";
414
+ const trailingIcon = isInvalid ? {
415
+ ...normalizedTrailingIconProp,
416
+ icon: "warning-alt"
417
+ } : normalizedTrailingIconProp;
418
+ const isWarning = !isInvalid && trailingIcon?.icon === "warning-alt";
419
+ const wrapperClassName = [className, isWarning && "is-warning"].filter(Boolean).join(" ");
420
+ return /* @__PURE__ */React.createElement(Flex, {
421
+ className: wrapperClassName,
403
422
  sx: {
404
423
  ...sx,
405
424
  position: "relative",
406
425
  padding: 0,
407
426
  border: "none"
408
427
  }
409
- }, leadingIcon && /* @__PURE__ */React7.createElement(Text, {
428
+ }, normalizedLeadingIcon && /* @__PURE__ */React.createElement(React.Fragment, null, /* @__PURE__ */React.createElement(Text, {
429
+ "data-testid": "input-leading-icon",
430
+ "data-tooltip-id": normalizedLeadingIcon.tooltip ? "input-leading-icon-tooltip" : void 0,
410
431
  sx: {
411
432
  position: "absolute",
412
433
  alignSelf: "center",
413
434
  left: "1rem",
414
- cursor: onLeadingIconClick ? "pointer" : "default"
435
+ cursor: normalizedLeadingIcon.onClick ? "pointer" : "default"
415
436
  },
416
- onClick: onLeadingIconClick,
437
+ onClick: normalizedLeadingIcon.onClick,
417
438
  variant: "leading-icon"
418
- }, /* @__PURE__ */React7.createElement(Icon4, {
439
+ }, /* @__PURE__ */React.createElement(Icon4, {
419
440
  inline: true,
420
- icon: leadingIcon
421
- })), /* @__PURE__ */React7.createElement(InputUI, {
422
- ref,
441
+ icon: normalizedLeadingIcon.icon
442
+ })), normalizedLeadingIcon.tooltip && /* @__PURE__ */React.createElement(Tooltip, {
443
+ id: "input-leading-icon-tooltip",
444
+ ...normalizedLeadingIcon.tooltipProps
445
+ }, normalizedLeadingIcon.tooltip)), /* @__PURE__ */React.createElement(InputUI, {
423
446
  sx: {
424
447
  fontFamily: "body",
425
448
  paddingY: "3",
@@ -431,29 +454,33 @@ var Input = /* @__PURE__ */React7.forwardRef(({
431
454
  },
432
455
  className,
433
456
  ...inputProps
434
- }), trailingIcon && /* @__PURE__ */React7.createElement(Text, {
457
+ }), trailingIcon && /* @__PURE__ */React.createElement(React.Fragment, null, /* @__PURE__ */React.createElement(Text, {
458
+ "data-testid": "input-trailing-icon",
459
+ "data-tooltip-id": trailingIcon.tooltip ? "input-trailing-icon-tooltip" : void 0,
435
460
  sx: {
436
461
  position: "absolute",
437
462
  right: "1rem",
438
463
  alignSelf: "center",
439
464
  color: isWarning ? "feedback.text.caution.default" : void 0,
440
- cursor: onTrailingIconClick ? "pointer" : "default",
465
+ cursor: trailingIcon.onClick ? "pointer" : "default",
441
466
  fontSize: "xl"
442
467
  },
443
468
  variant: "trailing-icon",
444
- onClick: onTrailingIconClick
445
- }, /* @__PURE__ */React7.createElement(Icon4, {
469
+ onClick: trailingIcon.onClick
470
+ }, /* @__PURE__ */React.createElement(Icon4, {
446
471
  inline: true,
447
- icon: trailingIcon
448
- })));
449
- });
450
- Input.displayName = "Input";
472
+ icon: trailingIcon.icon
473
+ })), trailingIcon.tooltip && /* @__PURE__ */React.createElement(Tooltip, {
474
+ id: "input-trailing-icon-tooltip",
475
+ ...trailingIcon.tooltipProps
476
+ }, trailingIcon.tooltip)));
477
+ }, "Input");
451
478
 
452
479
  // src/components/InputNumber.tsx
453
480
  import { Icon as Icon5 } from "@ttoss/react-icons";
454
- import * as React8 from "react";
481
+ import * as React7 from "react";
455
482
  import { Input as Input2 } from "theme-ui";
456
- var InputNumber = /* @__PURE__ */React8.forwardRef(({
483
+ var InputNumber = /* @__PURE__ */React7.forwardRef(({
457
484
  sx,
458
485
  value,
459
486
  infoIcon,
@@ -461,7 +488,7 @@ var InputNumber = /* @__PURE__ */React8.forwardRef(({
461
488
  onClickInfoIcon,
462
489
  ...inputProps
463
490
  }, ref) => {
464
- const sxProps = React8.useMemo(() => {
491
+ const sxProps = React7.useMemo(() => {
465
492
  const size = String(typeof value === "undefined" ? 0 : value).length;
466
493
  if (inputProps["aria-invalid"] === "true") {
467
494
  return {
@@ -513,7 +540,7 @@ var InputNumber = /* @__PURE__ */React8.forwardRef(({
513
540
  }
514
541
  onChange(value + 1);
515
542
  }, "handleChangeDown");
516
- return /* @__PURE__ */React8.createElement(Flex, {
543
+ return /* @__PURE__ */React7.createElement(Flex, {
517
544
  sx: {
518
545
  width: "fit-content",
519
546
  ...sx,
@@ -523,7 +550,7 @@ var InputNumber = /* @__PURE__ */React8.forwardRef(({
523
550
  },
524
551
  ref,
525
552
  "aria-invalid": inputProps["aria-invalid"]
526
- }, /* @__PURE__ */React8.createElement(Input2, {
553
+ }, /* @__PURE__ */React7.createElement(Input2, {
527
554
  ref,
528
555
  variant: "forms.inputNumber",
529
556
  sx: sxProps,
@@ -533,7 +560,7 @@ var InputNumber = /* @__PURE__ */React8.forwardRef(({
533
560
  }, "onChange"),
534
561
  value,
535
562
  ...inputProps
536
- }), /* @__PURE__ */React8.createElement(Text, {
563
+ }), /* @__PURE__ */React7.createElement(Text, {
537
564
  sx: {
538
565
  position: "absolute",
539
566
  alignSelf: "center",
@@ -542,9 +569,9 @@ var InputNumber = /* @__PURE__ */React8.forwardRef(({
542
569
  cursor: "pointer"
543
570
  },
544
571
  onClick: handleChangeUp
545
- }, /* @__PURE__ */React8.createElement(Icon5, {
572
+ }, /* @__PURE__ */React7.createElement(Icon5, {
546
573
  icon: "picker-down"
547
- })), infoIcon && /* @__PURE__ */React8.createElement(Text, {
574
+ })), infoIcon && /* @__PURE__ */React7.createElement(Text, {
548
575
  sx: {
549
576
  position: "absolute",
550
577
  alignSelf: "center",
@@ -553,9 +580,9 @@ var InputNumber = /* @__PURE__ */React8.forwardRef(({
553
580
  cursor: onClickInfoIcon ? "pointer" : "default"
554
581
  },
555
582
  onClick: onClickInfoIcon
556
- }, /* @__PURE__ */React8.createElement(Icon5, {
583
+ }, /* @__PURE__ */React7.createElement(Icon5, {
557
584
  icon: "info"
558
- })), /* @__PURE__ */React8.createElement(Text, {
585
+ })), /* @__PURE__ */React7.createElement(Text, {
559
586
  sx: {
560
587
  position: "absolute",
561
588
  alignSelf: "center",
@@ -564,23 +591,23 @@ var InputNumber = /* @__PURE__ */React8.forwardRef(({
564
591
  cursor: "pointer"
565
592
  },
566
593
  onClick: handleChangeDown
567
- }, /* @__PURE__ */React8.createElement(Icon5, {
594
+ }, /* @__PURE__ */React7.createElement(Icon5, {
568
595
  icon: "picker-up"
569
596
  })));
570
597
  });
571
598
  InputNumber.displayName = "InputNumber";
572
599
 
573
- // src/components/InputPassword/InputPassword.tsx
574
- import * as React10 from "react";
575
-
576
- // src/components/InputPassword/useHidePassInput.ts
577
- import * as React9 from "react";
578
- var useHidePassInput = /* @__PURE__ */__name((defaultValue = true) => {
579
- const [hidePass, setHidePass] = React9.useState(Boolean(defaultValue));
600
+ // src/components/InputPassword.tsx
601
+ import * as React8 from "react";
602
+ var InputPassword = /* @__PURE__ */__name(({
603
+ showPasswordByDefault = false,
604
+ ...inputPasswordProps
605
+ }) => {
606
+ const [hidePass, setHidePass] = React8.useState(Boolean(!showPasswordByDefault));
580
607
  const {
581
608
  icon,
582
609
  inputType
583
- } = React9.useMemo(() => {
610
+ } = React8.useMemo(() => {
584
611
  return {
585
612
  icon: hidePass ? "view-off" : "view-on",
586
613
  inputType: hidePass ? "password" : "text"
@@ -591,36 +618,19 @@ var useHidePassInput = /* @__PURE__ */__name((defaultValue = true) => {
591
618
  return !prev;
592
619
  });
593
620
  }, "handleClick");
594
- return {
595
- handleClick,
596
- icon,
597
- inputType
598
- };
599
- }, "useHidePassInput");
600
-
601
- // src/components/InputPassword/InputPassword.tsx
602
- var InputPassword = /* @__PURE__ */React10.forwardRef(({
603
- showPasswordByDefault,
604
- ...inputPasswordProps
605
- }, ref) => {
606
- const {
607
- handleClick,
608
- icon,
609
- inputType
610
- } = useHidePassInput(!showPasswordByDefault);
611
- return /* @__PURE__ */React10.createElement(Input, {
612
- ref,
621
+ return /* @__PURE__ */React8.createElement(Input, {
613
622
  ...inputPasswordProps,
614
- trailingIcon: icon,
615
- onTrailingIconClick: handleClick,
623
+ trailingIcon: {
624
+ icon,
625
+ onClick: handleClick
626
+ },
616
627
  type: inputType
617
628
  });
618
- });
619
- InputPassword.displayName = "InputPassword";
629
+ }, "InputPassword");
620
630
 
621
631
  // src/components/Label.tsx
622
632
  import { Icon as Icon6 } from "@ttoss/react-icons";
623
- import * as React11 from "react";
633
+ import * as React9 from "react";
624
634
  import { Label as LabelUi } from "theme-ui";
625
635
  var TOOLTIP_LABEL = "tooltip";
626
636
  var Label = /* @__PURE__ */__name(({
@@ -629,9 +639,9 @@ var Label = /* @__PURE__ */__name(({
629
639
  sx,
630
640
  ...props
631
641
  }) => {
632
- const id = React11.useId();
642
+ const id = React9.useId();
633
643
  const tooltipId = `${id}-tooltip`;
634
- return /* @__PURE__ */React11.createElement(LabelUi, {
644
+ return /* @__PURE__ */React9.createElement(LabelUi, {
635
645
  "data-tooltip-id": tooltipId,
636
646
  sx: {
637
647
  alignItems: "center",
@@ -642,19 +652,19 @@ var Label = /* @__PURE__ */__name(({
642
652
  ...sx
643
653
  },
644
654
  ...props
645
- }, children, tooltip && /* @__PURE__ */React11.createElement(Text, {
655
+ }, children, tooltip && /* @__PURE__ */React9.createElement(Text, {
646
656
  sx: {
647
657
  color: "currentcolor",
648
658
  cursor: "pointer"
649
659
  },
650
660
  "aria-label": TOOLTIP_LABEL
651
- }, tooltip.icon ? /* @__PURE__ */React11.createElement(Icon6, {
661
+ }, tooltip.icon ? /* @__PURE__ */React9.createElement(Icon6, {
652
662
  inline: true,
653
663
  icon: tooltip.icon
654
- }) : /* @__PURE__ */React11.createElement(Icon6, {
664
+ }) : /* @__PURE__ */React9.createElement(Icon6, {
655
665
  inline: true,
656
666
  icon: "fluent:info-24-regular"
657
- }), /* @__PURE__ */React11.createElement(Tooltip, {
667
+ }), /* @__PURE__ */React9.createElement(Tooltip, {
658
668
  id: tooltipId,
659
669
  openOnClick: tooltip.openOnClick,
660
670
  clickable: tooltip.clickable,
@@ -667,14 +677,14 @@ var Label = /* @__PURE__ */__name(({
667
677
  }, "Label");
668
678
 
669
679
  // src/components/Link.tsx
670
- import * as React12 from "react";
680
+ import * as React10 from "react";
671
681
  import { Link as LinkUi } from "theme-ui";
672
- var Link = /* @__PURE__ */React12.forwardRef(({
682
+ var Link = /* @__PURE__ */React10.forwardRef(({
673
683
  quiet,
674
684
  className,
675
685
  ...props
676
686
  }, ref) => {
677
- return /* @__PURE__ */React12.createElement(LinkUi, {
687
+ return /* @__PURE__ */React10.createElement(LinkUi, {
678
688
  className: `${quiet ? "quiet" : ""} ${className ?? ""}`,
679
689
  ...props,
680
690
  ref
@@ -689,7 +699,7 @@ import { Paragraph } from "theme-ui";
689
699
  import { Radio } from "theme-ui";
690
700
 
691
701
  // src/components/SegmentedControl.tsx
692
- import * as React13 from "react";
702
+ import * as React11 from "react";
693
703
  import { Box as Box3, Flex as Flex2 } from "theme-ui";
694
704
  var SegmentedControl = /* @__PURE__ */__name(({
695
705
  options,
@@ -701,8 +711,8 @@ var SegmentedControl = /* @__PURE__ */__name(({
701
711
  sx,
702
712
  ...rest
703
713
  }) => {
704
- const [internalValue, setInternalValue] = React13.useState(propValue || defaultValue);
705
- React13.useEffect(() => {
714
+ const [internalValue, setInternalValue] = React11.useState(propValue || defaultValue);
715
+ React11.useEffect(() => {
706
716
  if (propValue !== void 0) {
707
717
  setInternalValue(propValue);
708
718
  }
@@ -720,7 +730,7 @@ var SegmentedControl = /* @__PURE__ */__name(({
720
730
  } : option;
721
731
  });
722
732
  const currentValue = propValue !== void 0 ? propValue : internalValue;
723
- return /* @__PURE__ */React13.createElement(Flex2, {
733
+ return /* @__PURE__ */React11.createElement(Flex2, {
724
734
  className,
725
735
  sx: {
726
736
  width: "100%",
@@ -803,18 +813,18 @@ var SegmentedControl = /* @__PURE__ */__name(({
803
813
  ...sx
804
814
  },
805
815
  ...rest
806
- }, /* @__PURE__ */React13.createElement("div", {
816
+ }, /* @__PURE__ */React11.createElement("div", {
807
817
  className: "rc-segmented"
808
- }, /* @__PURE__ */React13.createElement(Flex2, {
818
+ }, /* @__PURE__ */React11.createElement(Flex2, {
809
819
  className: "rc-segmented-group custom-segmented-group"
810
820
  }, normalizedOptions.map((option, index) => {
811
821
  const isSelected = option.value === currentValue;
812
822
  const isLastItem = index === normalizedOptions.length - 1;
813
823
  const isItemDisabled = disabled || option.disabled;
814
824
  const showDivider = !isLastItem && option.value !== currentValue && normalizedOptions[index + 1].value !== currentValue;
815
- return /* @__PURE__ */React13.createElement(React13.Fragment, {
825
+ return /* @__PURE__ */React11.createElement(React11.Fragment, {
816
826
  key: `${index}-${option.value}`
817
- }, /* @__PURE__ */React13.createElement(Box3, {
827
+ }, /* @__PURE__ */React11.createElement(Box3, {
818
828
  as: "label",
819
829
  className: `rc-segmented-item ${isSelected ? "rc-segmented-item-selected" : ""} ${isItemDisabled ? "rc-segmented-item-disabled" : ""}`,
820
830
  onClick: /* @__PURE__ */__name(() => {
@@ -822,7 +832,7 @@ var SegmentedControl = /* @__PURE__ */__name(({
822
832
  handleChange(option.value);
823
833
  }
824
834
  }, "onClick")
825
- }, /* @__PURE__ */React13.createElement("input", {
835
+ }, /* @__PURE__ */React11.createElement("input", {
826
836
  type: "radio",
827
837
  value: option.value,
828
838
  checked: isSelected,
@@ -832,9 +842,9 @@ var SegmentedControl = /* @__PURE__ */__name(({
832
842
  handleChange(option.value);
833
843
  }
834
844
  }, "onChange")
835
- }), /* @__PURE__ */React13.createElement("div", {
845
+ }), /* @__PURE__ */React11.createElement("div", {
836
846
  className: "rc-segmented-item-label"
837
- }, option.label)), showDivider && /* @__PURE__ */React13.createElement(Box3, {
847
+ }, option.label)), showDivider && /* @__PURE__ */React11.createElement(Box3, {
838
848
  className: "segmented-divider",
839
849
  sx: {
840
850
  height: "60%",
@@ -845,7 +855,7 @@ var SegmentedControl = /* @__PURE__ */__name(({
845
855
  zIndex: 3
846
856
  }
847
857
  }));
848
- }), currentValue !== void 0 && /* @__PURE__ */React13.createElement("div", {
858
+ }), currentValue !== void 0 && /* @__PURE__ */React11.createElement("div", {
849
859
  className: "rc-segmented-thumb",
850
860
  style: {
851
861
  width: `${100 / normalizedOptions.length}%`,
@@ -858,7 +868,7 @@ var SegmentedControl = /* @__PURE__ */__name(({
858
868
 
859
869
  // src/components/Select.tsx
860
870
  import { Icon as Icon7 } from "@ttoss/react-icons";
861
- import * as React14 from "react";
871
+ import * as React12 from "react";
862
872
  import ReactSelect, { components } from "react-select";
863
873
  var Control = /* @__PURE__ */__name(props => {
864
874
  const isDisabled = props.selectProps.isDisabled;
@@ -878,7 +888,7 @@ var Control = /* @__PURE__ */__name(props => {
878
888
  }
879
889
  return "display.background.secondary.default";
880
890
  })();
881
- return /* @__PURE__ */React14.createElement(Box, {
891
+ return /* @__PURE__ */React12.createElement(Box, {
882
892
  sx: {
883
893
  ".react-select__control": {
884
894
  borderColor,
@@ -887,7 +897,7 @@ var Control = /* @__PURE__ */__name(props => {
887
897
  paddingY: "3"
888
898
  }
889
899
  }
890
- }, /* @__PURE__ */React14.createElement(components.Control, props));
900
+ }, /* @__PURE__ */React12.createElement(components.Control, props));
891
901
  }, "Control");
892
902
  var DropdownIndicator = /* @__PURE__ */__name(props => {
893
903
  const isDisabled = props.selectProps.isDisabled;
@@ -897,7 +907,7 @@ var DropdownIndicator = /* @__PURE__ */__name(props => {
897
907
  }
898
908
  return "text";
899
909
  })();
900
- return /* @__PURE__ */React14.createElement(Text, {
910
+ return /* @__PURE__ */React12.createElement(Text, {
901
911
  sx: {
902
912
  fontSize: "md",
903
913
  color,
@@ -905,14 +915,14 @@ var DropdownIndicator = /* @__PURE__ */__name(props => {
905
915
  display: "flex",
906
916
  alignItems: "center"
907
917
  }
908
- }, /* @__PURE__ */React14.createElement(Icon7, {
918
+ }, /* @__PURE__ */React12.createElement(Icon7, {
909
919
  icon: "picker-down"
910
920
  }));
911
921
  }, "DropdownIndicator");
912
922
  var IndicatorsContainer = /* @__PURE__ */__name(({
913
923
  children
914
924
  }) => {
915
- return /* @__PURE__ */React14.createElement(Box, {
925
+ return /* @__PURE__ */React12.createElement(Box, {
916
926
  sx: {
917
927
  marginLeft: "4",
918
928
  border: "none"
@@ -922,7 +932,7 @@ var IndicatorsContainer = /* @__PURE__ */__name(({
922
932
  var Placeholder = /* @__PURE__ */__name(({
923
933
  children
924
934
  }) => {
925
- return /* @__PURE__ */React14.createElement(Text, {
935
+ return /* @__PURE__ */React12.createElement(Text, {
926
936
  sx: {
927
937
  color: "onMuted",
928
938
  alignSelf: "center"
@@ -940,10 +950,10 @@ var SelectContainer = /* @__PURE__ */__name(({
940
950
  return (
941
951
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
942
952
  /* @__PURE__ */
943
- React14.createElement(Box, {
953
+ React12.createElement(Box, {
944
954
  sx,
945
955
  css: css2
946
- }, /* @__PURE__ */React14.createElement(components.SelectContainer, props, children))
956
+ }, /* @__PURE__ */React12.createElement(components.SelectContainer, props, children))
947
957
  );
948
958
  }, "SelectContainer");
949
959
  var ValueContainer = /* @__PURE__ */__name(({
@@ -969,26 +979,26 @@ var ValueContainer = /* @__PURE__ */__name(({
969
979
  }
970
980
  return leadingIcon || "search";
971
981
  })();
972
- return /* @__PURE__ */React14.createElement(Flex, {
982
+ return /* @__PURE__ */React12.createElement(Flex, {
973
983
  sx: {
974
984
  gap: "4",
975
985
  flex: 1
976
986
  }
977
- }, finalLeadingIcon && /* @__PURE__ */React14.createElement(Text, {
987
+ }, finalLeadingIcon && /* @__PURE__ */React12.createElement(Text, {
978
988
  sx: {
979
989
  alignSelf: "center",
980
990
  pointerEvents: "none",
981
991
  lineHeight: 0,
982
992
  fontSize: "md"
983
993
  }
984
- }, /* @__PURE__ */React14.createElement(Icon7, {
994
+ }, /* @__PURE__ */React12.createElement(Icon7, {
985
995
  icon: finalLeadingIcon
986
- })), /* @__PURE__ */React14.createElement(Flex, {
996
+ })), /* @__PURE__ */React12.createElement(Flex, {
987
997
  sx: {
988
998
  flex: 1,
989
999
  alignItems: "center"
990
1000
  }
991
- }, children), (trailingIcon || hasError) && /* @__PURE__ */React14.createElement(Text, {
1001
+ }, children), (trailingIcon || hasError) && /* @__PURE__ */React12.createElement(Text, {
992
1002
  className: hasError ? "error-icon" : "",
993
1003
  sx: {
994
1004
  alignSelf: "center",
@@ -997,11 +1007,11 @@ var ValueContainer = /* @__PURE__ */__name(({
997
1007
  fontSize: "md",
998
1008
  color: trailingIconColor
999
1009
  }
1000
- }, /* @__PURE__ */React14.createElement(Icon7, {
1010
+ }, /* @__PURE__ */React12.createElement(Icon7, {
1001
1011
  icon: hasError ? "warning-alt" : trailingIcon
1002
1012
  })));
1003
1013
  }, "ValueContainer");
1004
- var Select = /* @__PURE__ */React14.forwardRef(({
1014
+ var Select = /* @__PURE__ */React12.forwardRef(({
1005
1015
  ...props
1006
1016
  }, ref) => {
1007
1017
  const value = props.options?.find(option => {
@@ -1010,7 +1020,7 @@ var Select = /* @__PURE__ */React14.forwardRef(({
1010
1020
  }
1011
1021
  return false;
1012
1022
  });
1013
- return /* @__PURE__ */React14.createElement(ReactSelect, {
1023
+ return /* @__PURE__ */React12.createElement(ReactSelect, {
1014
1024
  ref,
1015
1025
  /**
1016
1026
  * https://react-select.com/components
@@ -1092,7 +1102,7 @@ var Switch = /* @__PURE__ */__name(props => {
1092
1102
  }, "Switch");
1093
1103
 
1094
1104
  // src/components/Tag.tsx
1095
- import * as React15 from "react";
1105
+ import * as React13 from "react";
1096
1106
  var tagVariantMap = {
1097
1107
  positive: {
1098
1108
  bg: "feedback.background.positive.default",
@@ -1149,7 +1159,7 @@ var Tag = /* @__PURE__ */__name(({
1149
1159
  alignItems: "center"
1150
1160
  };
1151
1161
  if (Array.isArray(children)) {
1152
- return /* @__PURE__ */React15.createElement(Box, {
1162
+ return /* @__PURE__ */React13.createElement(Box, {
1153
1163
  as: "span",
1154
1164
  sx: {
1155
1165
  ml: 2,
@@ -1159,7 +1169,7 @@ var Tag = /* @__PURE__ */__name(({
1159
1169
  ...sx
1160
1170
  }
1161
1171
  }, children.map((child, i) => {
1162
- return /* @__PURE__ */React15.createElement(Box, {
1172
+ return /* @__PURE__ */React13.createElement(Box, {
1163
1173
  key: i,
1164
1174
  as: "span",
1165
1175
  sx: {
@@ -1173,7 +1183,7 @@ var Tag = /* @__PURE__ */__name(({
1173
1183
  }, child);
1174
1184
  }));
1175
1185
  }
1176
- return /* @__PURE__ */React15.createElement(Box, {
1186
+ return /* @__PURE__ */React13.createElement(Box, {
1177
1187
  as: "span",
1178
1188
  sx: {
1179
1189
  ...baseStyles,
@@ -1184,15 +1194,15 @@ var Tag = /* @__PURE__ */__name(({
1184
1194
 
1185
1195
  // src/components/Textarea.tsx
1186
1196
  import { Icon as Icon8 } from "@ttoss/react-icons";
1187
- import * as React16 from "react";
1197
+ import * as React14 from "react";
1188
1198
  import { Textarea as TextareaUI } from "theme-ui";
1189
- var Textarea = /* @__PURE__ */React16.forwardRef(({
1199
+ var Textarea = /* @__PURE__ */React14.forwardRef(({
1190
1200
  trailingIcon,
1191
1201
  className,
1192
1202
  sx,
1193
1203
  ...textareaProps
1194
1204
  }, ref) => {
1195
- return /* @__PURE__ */React16.createElement(Flex, {
1205
+ return /* @__PURE__ */React14.createElement(Flex, {
1196
1206
  className,
1197
1207
  sx: {
1198
1208
  ...sx,
@@ -1200,7 +1210,7 @@ var Textarea = /* @__PURE__ */React16.forwardRef(({
1200
1210
  padding: 0,
1201
1211
  border: "none"
1202
1212
  }
1203
- }, /* @__PURE__ */React16.createElement(TextareaUI, {
1213
+ }, /* @__PURE__ */React14.createElement(TextareaUI, {
1204
1214
  ref,
1205
1215
  sx: {
1206
1216
  fontFamily: "body",
@@ -1212,13 +1222,13 @@ var Textarea = /* @__PURE__ */React16.forwardRef(({
1212
1222
  },
1213
1223
  className,
1214
1224
  ...textareaProps
1215
- }), trailingIcon && /* @__PURE__ */React16.createElement(Text, {
1225
+ }), trailingIcon && /* @__PURE__ */React14.createElement(Text, {
1216
1226
  sx: {
1217
1227
  position: "absolute",
1218
1228
  right: "1.25rem",
1219
1229
  top: "0.75rem"
1220
1230
  }
1221
- }, /* @__PURE__ */React16.createElement(Icon8, {
1231
+ }, /* @__PURE__ */React14.createElement(Icon8, {
1222
1232
  inline: true,
1223
1233
  icon: trailingIcon
1224
1234
  })));
@@ -1299,16 +1309,16 @@ var Tooltip = /* @__PURE__ */__name(({
1299
1309
  // src/theme/ThemeProvider.tsx
1300
1310
  import { css, Global } from "@emotion/react";
1301
1311
  import { BruttalFonts, BruttalTheme } from "@ttoss/theme/Bruttal";
1302
- import * as React17 from "react";
1312
+ import * as React15 from "react";
1303
1313
  import { ThemeUIProvider } from "theme-ui";
1304
1314
  var ThemeProvider = /* @__PURE__ */__name(({
1305
1315
  children,
1306
1316
  theme = BruttalTheme,
1307
1317
  fonts = BruttalFonts
1308
1318
  }) => {
1309
- return /* @__PURE__ */React17.createElement(React17.Fragment, null, /* @__PURE__ */React17.createElement(ThemeUIProvider, {
1319
+ return /* @__PURE__ */React15.createElement(React15.Fragment, null, /* @__PURE__ */React15.createElement(ThemeUIProvider, {
1310
1320
  theme
1311
- }, /* @__PURE__ */React17.createElement(Global, {
1321
+ }, /* @__PURE__ */React15.createElement(Global, {
1312
1322
  styles: css`
1313
1323
  ${fonts.map(url => {
1314
1324
  return `@import url('${url}');`;
package/dist/index.d.ts CHANGED
@@ -2,10 +2,10 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { IconType } from '@ttoss/react-icons';
3
3
  import * as React from 'react';
4
4
  import * as theme_ui from 'theme-ui';
5
- import { ButtonProps as ButtonProps$1, BadgeProps as BadgeProps$1, CardProps, BoxProps, CheckboxProps as CheckboxProps$1, CloseProps, TextProps, IconButtonProps as IconButtonProps$1, InputProps as InputProps$1, LabelProps as LabelProps$1, LinkProps as LinkProps$1, FlexProps, SxProp, SwitchProps, ThemeUIStyleObject, TextareaProps as TextareaProps$1, Theme } from 'theme-ui';
5
+ import { ButtonProps as ButtonProps$1, BadgeProps as BadgeProps$1, CardProps, BoxProps, CheckboxProps as CheckboxProps$1, CloseProps, TextProps, IconButtonProps as IconButtonProps$1, SxProp, InputProps as InputProps$1, LabelProps as LabelProps$1, LinkProps as LinkProps$1, FlexProps, SwitchProps, ThemeUIStyleObject, TextareaProps as TextareaProps$1, Theme } from 'theme-ui';
6
6
  export { BaseStyles, Box, BoxProps, CardProps, ContainerProps, Divider, DividerProps, Flex, FlexProps, Global, Grid, GridProps, Heading, HeadingProps, Image, ImageProps, Progress as LinearProgress, ProgressProps as LinearProgressProps, Paragraph, ParagraphProps, Radio, RadioProps, Slider, SliderProps, Spinner, SpinnerProps, SwitchProps, SxProp, Text, TextProps, Theme, ThemeUIStyleObject } from 'theme-ui';
7
- import { Props } from 'react-select';
8
7
  import { ITooltip } from 'react-tooltip';
8
+ import { Props } from 'react-select';
9
9
  export { Keyframes, keyframes } from '@emotion/react';
10
10
  export { useBreakpointIndex, useResponsiveValue } from '@theme-ui/match-media';
11
11
 
@@ -61,13 +61,20 @@ declare const IconButton: (props: IconButtonProps) => react_jsx_runtime.JSX.Elem
61
61
 
62
62
  declare const InfiniteLinearProgress: () => react_jsx_runtime.JSX.Element;
63
63
 
64
+ type TooltipProps = ITooltip & SxProp;
65
+ declare const Tooltip: ({ variant, sx, ...props }: TooltipProps) => react_jsx_runtime.JSX.Element;
66
+
67
+ interface InputIconConfig {
68
+ icon: IconType;
69
+ onClick?: () => void;
70
+ tooltip?: string;
71
+ tooltipProps?: Omit<TooltipProps, 'children' | 'anchorSelect'>;
72
+ }
64
73
  interface InputProps extends InputProps$1 {
65
- leadingIcon?: IconType;
66
- onLeadingIconClick?: () => void;
67
- trailingIcon?: IconType;
68
- onTrailingIconClick?: () => void;
74
+ leadingIcon?: InputIconConfig | IconType;
75
+ trailingIcon?: InputIconConfig | IconType;
69
76
  }
70
- declare const Input: React.ForwardRefExoticComponent<Omit<InputProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
77
+ declare const Input: ({ leadingIcon, trailingIcon: trailingIconProp, className, sx, ...inputProps }: InputProps) => react_jsx_runtime.JSX.Element;
71
78
 
72
79
  type InputNumberProps = Omit<InputProps$1, 'type' | 'variant' | 'onChange'> & {
73
80
  onChange: (value: number) => void;
@@ -77,10 +84,10 @@ type InputNumberProps = Omit<InputProps$1, 'type' | 'variant' | 'onChange'> & {
77
84
  };
78
85
  declare const InputNumber: React.ForwardRefExoticComponent<Omit<InputNumberProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
79
86
 
80
- type InputPasswordProps = Omit<InputProps, 'trailingIcon' | 'onTrailingIconClick' | 'type'> & {
87
+ type InputPasswordProps = Omit<InputProps, 'trailingIcon' | 'type'> & {
81
88
  showPasswordByDefault?: boolean;
82
89
  };
83
- declare const InputPassword: React.ForwardRefExoticComponent<Omit<InputPasswordProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
90
+ declare const InputPassword: ({ showPasswordByDefault, ...inputPasswordProps }: InputPasswordProps) => react_jsx_runtime.JSX.Element;
84
91
 
85
92
  type LabelProps = LabelProps$1 & {
86
93
  tooltip?: {
@@ -172,8 +179,6 @@ interface TextareaProps extends TextareaProps$1 {
172
179
  }
173
180
  declare const Textarea: React.ForwardRefExoticComponent<Omit<TextareaProps, "ref"> & React.RefAttributes<HTMLTextAreaElement>>;
174
181
 
175
- declare const Tooltip: ({ variant, sx, ...props }: ITooltip & SxProp) => react_jsx_runtime.JSX.Element;
176
-
177
182
  type ThemeProviderProps = {
178
183
  children?: React.ReactNode;
179
184
  theme?: Theme;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/ui",
3
- "version": "5.10.7",
3
+ "version": "5.11.0",
4
4
  "description": "Primitive layout, typographic, and other components for styling applications.",
5
5
  "license": "MIT",
6
6
  "author": "ttoss",
@@ -24,17 +24,17 @@
24
24
  ],
25
25
  "sideEffects": false,
26
26
  "dependencies": {
27
- "@theme-ui/match-media": "^0.17.1",
27
+ "@theme-ui/match-media": "^0.17.2",
28
28
  "rc-segmented": "^2.7.0",
29
- "react-select": "^5.9.0",
30
- "react-tooltip": "^5.28.0",
31
- "theme-ui": "^0.17.1",
32
- "@ttoss/theme": "^2.6.10"
29
+ "react-select": "^5.10.2",
30
+ "react-tooltip": "^5.30.0",
31
+ "theme-ui": "^0.17.2",
32
+ "@ttoss/theme": "^2.7.0"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "@emotion/react": "^11",
36
36
  "react": ">=16.8.0",
37
- "@ttoss/react-icons": "^0.5.2"
37
+ "@ttoss/react-icons": "^0.5.3"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@emotion/react": "^11.14.0",
@@ -44,9 +44,9 @@
44
44
  "jest": "^30.2.0",
45
45
  "react": "^19.2.0",
46
46
  "tsup": "^8.5.1",
47
- "@ttoss/config": "^1.35.11",
48
- "@ttoss/test-utils": "^3.0.3",
49
- "@ttoss/react-icons": "^0.5.2"
47
+ "@ttoss/test-utils": "^3.0.4",
48
+ "@ttoss/react-icons": "^0.5.3",
49
+ "@ttoss/config": "^1.35.12"
50
50
  },
51
51
  "keywords": [
52
52
  "React",