fis-component 0.1.4 → 0.1.6

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/cjs/index.js CHANGED
@@ -65351,7 +65351,7 @@ function mergeRefs(...refs) {
65351
65351
  }
65352
65352
 
65353
65353
  const FISInputText = React.forwardRef((props, ref) => {
65354
- const { className, typeSuffix, textLabel = "", iconLabel, required, iconPrefix, sizeInput, showCount, message, negative, positive, maxLength = 500, disabled, onChange, onEnter, onKeyDown, onClickIconLabel, onClickSuffix, ...rest } = props;
65354
+ const { className, typeSuffix, textLabel = "", iconLabel, required, iconPrefix, sizeInput, showCount, message, negative, positive, maxLength = 500, disabled, onChange, onEnter, onKeyDown, onClickIconLabel, onClickSuffix, isTrimValue = true, ...rest } = props;
65355
65355
  // Internal ref to access DOM element for character count
65356
65356
  const internalRef = React.useRef(null);
65357
65357
  const [internalValue, setInternalValue] = React.useState("");
@@ -65386,7 +65386,22 @@ const FISInputText = React.forwardRef((props, ref) => {
65386
65386
  }
65387
65387
  }
65388
65388
  }, [onEnter]);
65389
- return (jsxRuntime.jsxs(DivContainerSC$6, { className: className, children: [(textLabel || iconLabel) && (jsxRuntime.jsx(FISInputLabel, { textLabel: textLabel, required: required, iconLabel: iconLabel, onClickIconLabel: onClickIconLabel })), jsxRuntime.jsx(FISInputField, { ...rest, ref: mergeRefs(ref, internalRef), typeSuffix: typeSuffix, sizeInput: sizeInput, iconPrefix: iconPrefix, onKeyPress: handleKeyPress, onChange: handleChange, disabled: disabled, negative: negative, maxLength: maxLength, onClickSuffix: onClickSuffix }), (message || showCount) && (jsxRuntime.jsxs(DivHintWrapperSC$1, { children: [jsxRuntime.jsx(SpanHintSC$3, { className: classNames({
65389
+ const handleBlur = React.useCallback((event) => {
65390
+ if (!isTrimValue) {
65391
+ rest.onBlur?.(event);
65392
+ return;
65393
+ }
65394
+ const trimmedValue = event.target.value.trim();
65395
+ event.target.value = trimmedValue;
65396
+ if (rest.value === undefined) {
65397
+ setInternalValue(trimmedValue);
65398
+ }
65399
+ else {
65400
+ forceUpdate();
65401
+ }
65402
+ rest.onBlur?.(event);
65403
+ }, [isTrimValue, rest.value, rest.onBlur]);
65404
+ return (jsxRuntime.jsxs(DivContainerSC$6, { className: className, children: [(textLabel || iconLabel) && (jsxRuntime.jsx(FISInputLabel, { textLabel: textLabel, required: required, iconLabel: iconLabel, onClickIconLabel: onClickIconLabel })), jsxRuntime.jsx(FISInputField, { ...rest, ref: mergeRefs(ref, internalRef), typeSuffix: typeSuffix, sizeInput: sizeInput, iconPrefix: iconPrefix, onKeyPress: handleKeyPress, onChange: handleChange, onBlur: handleBlur, disabled: disabled, negative: negative, maxLength: maxLength, onClickSuffix: onClickSuffix }), (message || showCount) && (jsxRuntime.jsxs(DivHintWrapperSC$1, { children: [jsxRuntime.jsx(SpanHintSC$3, { className: classNames({
65390
65405
  disabled: disabled,
65391
65406
  negative: negative,
65392
65407
  positive: positive,
@@ -66647,7 +66662,7 @@ const DivWrapperSC$5 = styled.div `
66647
66662
  gap: ${getTheme("com/input/vertical-gap")};
66648
66663
  `;
66649
66664
 
66650
- const FISInputStepper = React.forwardRef((props) => {
66665
+ const FISInputStepper = React.forwardRef((props, ref) => {
66651
66666
  const { min, max, step = 1, defaultValue, sizeInput = "md", StartIcon, EndIcon, negative, positive, message, iconLabel, textLabel = "", onClickIconLabel, disabled, readOnly, onChange, ...rest } = props;
66652
66667
  const [count, setCount] = React.useState(defaultValue !== undefined ? defaultValue : undefined);
66653
66668
  const handleIncrement = () => {
@@ -66679,7 +66694,7 @@ const FISInputStepper = React.forwardRef((props) => {
66679
66694
  "input-text-lg": sizeInput === "lg",
66680
66695
  }), children: [jsxRuntime.jsx(FISIconButton, { icon: StartIcon ? StartIcon : jsxRuntime.jsx(DecreIcon, {}), size: sizeInput === "lg" ? "md" : "sm", variant: "tertiary-invisible", onClick: handleDecrement, disabled: min !== undefined && count !== undefined && count <= min, className: classNames("decrement", {
66681
66696
  "disabled-button": disabled || readOnly,
66682
- }) }), jsxRuntime.jsx(InputSC$1, { ...rest, disabled: disabled, readOnly: readOnly, type: "number", value: count !== undefined ? count : "", className: classNames({
66697
+ }) }), jsxRuntime.jsx(InputSC$1, { ...rest, ref: ref, disabled: disabled, readOnly: readOnly, type: "number", value: count !== undefined ? count : "", className: classNames({
66683
66698
  negative: negative,
66684
66699
  "input-text-lg": sizeInput === "lg",
66685
66700
  }), onChange: handleChange }), jsxRuntime.jsx(FISIconButton, { icon: EndIcon ? EndIcon : jsxRuntime.jsx(IncreIcon, {}), size: sizeInput === "lg" ? "md" : "sm", variant: "tertiary-invisible", onClick: handleIncrement, disabled: max !== undefined && count !== undefined && count >= max, className: classNames("increment", {
@@ -68548,7 +68563,37 @@ const FISMenuSection = ({ label, withAction = false, actionText, actionLabel = f
68548
68563
  };
68549
68564
  FISMenuSection.displayName = "FISMenuSection";
68550
68565
 
68551
- const FISMenuSelect = ({ placeholder, groups, size = "md", multi = false, selectedValues = [], onChangeSelected, searchValue = "", onSearchChange, loading = false, noData = false, noResult = false, combobox, className, onClickMenu, loadingText = "Data loading...", noDataText = "No data", noResultText = "No result", removeSelectedText = "Remove selected", selectedGroupLabel = "Selected", maxHeight, onPopupScroll, }) => {
68566
+ /**
68567
+ * Normalizes a text value by:
68568
+ * - Removing all diacritic marks (e.g. Vietnamese accents)
68569
+ * - Converting the result to lowercase
68570
+ * - Trimming leading and trailing whitespace
68571
+ *
68572
+ * This is useful for case-insensitive and accent-insensitive text comparisons
68573
+ * or searches, especially for languages that use diacritics.
68574
+ *
68575
+ * @example
68576
+ * ```ts
68577
+ * normalizeText("Công nghệ thông tin"); // "cong nghe thong tin"
68578
+ * normalizeText(""); // ""
68579
+ * ```
68580
+ *
68581
+ * @param value - The input text to normalize. If falsy, an empty string is returned.
68582
+ * @returns The normalized, accent-stripped, lowercase, and trimmed string.
68583
+ */
68584
+ const normalizeText = (value) => {
68585
+ if (!value)
68586
+ return "";
68587
+ return value
68588
+ .normalize("NFD")
68589
+ .replace(/[\u0300-\u036f]/g, "")
68590
+ .replace(/đ/g, "d")
68591
+ .replace(/Đ/g, "D")
68592
+ .toLowerCase()
68593
+ .trim();
68594
+ };
68595
+
68596
+ const FISMenuSelect = ({ placeholder, groups, size = "md", multi = false, selectedValues = [], onChangeSelected, searchValue = "", onSearchChange, loading = false, noData = false, noResult = false, combobox, className, onClickMenu, loadingText = "Data loading...", noDataText = "No data", noResultText = "No result", removeSelectedText = "Remove selected", selectedGroupLabel = "Selected", maxHeight, onPopupScroll, normalizeTextSearch = false, }) => {
68552
68597
  const [localSearch, setLocalSearch] = React.useState(searchValue);
68553
68598
  const [debouncedSearchValue, setDebouncedSearchValue] = React.useState(searchValue);
68554
68599
  const debouncedSetSearch = React.useMemo(() => debounce$2((value) => setDebouncedSearchValue(value), 300), []);
@@ -68580,11 +68625,13 @@ const FISMenuSelect = ({ placeholder, groups, size = "md", multi = false, select
68580
68625
  if (search.trim()) {
68581
68626
  filteredItems = filteredItems.map((group) => ({
68582
68627
  ...group,
68583
- items: group.items.filter((item) => item?.label?.toLowerCase()?.includes(search?.toLowerCase())),
68628
+ items: group.items.filter((item) => normalizeTextSearch
68629
+ ? normalizeText(item?.label).includes(normalizeText(search))
68630
+ : item?.label?.toLowerCase()?.includes(search?.toLowerCase())),
68584
68631
  }));
68585
68632
  }
68586
68633
  return filteredItems.filter((group) => group.items.length > 0);
68587
- }, [groups, multi, selectedValues, search]);
68634
+ }, [groups, multi, selectedValues, search, normalizeTextSearch]);
68588
68635
  const selectedItemsGroup = React.useMemo(() => {
68589
68636
  if (!multi)
68590
68637
  return null;