fis-component 0.1.5 → 0.1.7

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
@@ -66662,7 +66662,7 @@ const DivWrapperSC$5 = styled.div `
66662
66662
  gap: ${getTheme("com/input/vertical-gap")};
66663
66663
  `;
66664
66664
 
66665
- const FISInputStepper = React.forwardRef((props) => {
66665
+ const FISInputStepper = React.forwardRef((props, ref) => {
66666
66666
  const { min, max, step = 1, defaultValue, sizeInput = "md", StartIcon, EndIcon, negative, positive, message, iconLabel, textLabel = "", onClickIconLabel, disabled, readOnly, onChange, ...rest } = props;
66667
66667
  const [count, setCount] = React.useState(defaultValue !== undefined ? defaultValue : undefined);
66668
66668
  const handleIncrement = () => {
@@ -66694,7 +66694,7 @@ const FISInputStepper = React.forwardRef((props) => {
66694
66694
  "input-text-lg": sizeInput === "lg",
66695
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", {
66696
66696
  "disabled-button": disabled || readOnly,
66697
- }) }), 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({
66698
66698
  negative: negative,
66699
66699
  "input-text-lg": sizeInput === "lg",
66700
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", {
@@ -68563,9 +68563,40 @@ const FISMenuSection = ({ label, withAction = false, actionText, actionLabel = f
68563
68563
  };
68564
68564
  FISMenuSection.displayName = "FISMenuSection";
68565
68565
 
68566
- 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, focusSearchInput = true, onPopupScroll, normalizeTextSearch = false, }) => {
68567
68597
  const [localSearch, setLocalSearch] = React.useState(searchValue);
68568
68598
  const [debouncedSearchValue, setDebouncedSearchValue] = React.useState(searchValue);
68599
+ const searchInputRef = React.useRef(null);
68569
68600
  const debouncedSetSearch = React.useMemo(() => debounce$2((value) => setDebouncedSearchValue(value), 300), []);
68570
68601
  React.useEffect(() => {
68571
68602
  debouncedSetSearch(localSearch);
@@ -68595,11 +68626,13 @@ const FISMenuSelect = ({ placeholder, groups, size = "md", multi = false, select
68595
68626
  if (search.trim()) {
68596
68627
  filteredItems = filteredItems.map((group) => ({
68597
68628
  ...group,
68598
- items: group.items.filter((item) => item?.label?.toLowerCase()?.includes(search?.toLowerCase())),
68629
+ items: group.items.filter((item) => normalizeTextSearch
68630
+ ? normalizeText(item?.label).includes(normalizeText(search))
68631
+ : item?.label?.toLowerCase()?.includes(search?.toLowerCase())),
68599
68632
  }));
68600
68633
  }
68601
68634
  return filteredItems.filter((group) => group.items.length > 0);
68602
- }, [groups, multi, selectedValues, search]);
68635
+ }, [groups, multi, selectedValues, search, normalizeTextSearch]);
68603
68636
  const selectedItemsGroup = React.useMemo(() => {
68604
68637
  if (!multi)
68605
68638
  return null;
@@ -68659,7 +68692,12 @@ const FISMenuSelect = ({ placeholder, groups, size = "md", multi = false, select
68659
68692
  onClickMenu?.();
68660
68693
  }
68661
68694
  };
68662
- return (jsxRuntime.jsxs(DivContainerSC$4, { "$maxHeight": maxHeight, className: className, children: [showInput && !combobox && (jsxRuntime.jsx(DivSearchSC, { children: jsxRuntime.jsx(FISInputText, { iconPrefix: jsxRuntime.jsx(SearchIcon, {}), placeholder: placeholder, value: search, onChange: handleSearchChange }) })), loading && (jsxRuntime.jsxs(DivLoaderSC, { children: [jsxRuntime.jsx(FISProgressCircular, { size: size, variant: "indeterminate" }), jsxRuntime.jsx(PTitleSC$2, { children: loadingText })] })), !loading && noData && (jsxRuntime.jsxs(DivLoaderSC, { children: [jsxRuntime.jsx(DivIconDataSC, { children: jsxRuntime.jsx(NoDataIcon, {}) }), jsxRuntime.jsx(PTitleSC$2, { children: noDataText })] })), !loading && !noData && (shouldShowNoResult || noResult) && (jsxRuntime.jsxs(DivLoaderSC, { children: [jsxRuntime.jsx(DivIconDataSC, { children: jsxRuntime.jsx(NoResultIcon, {}) }), jsxRuntime.jsx(PTitleSC$2, { children: noResultText })] })), !shouldShowNoResult && !noData && !loading && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(MenuContent, { "$removeSelectedGroup": !!removeSelectedGroup, onScroll: onPopupScroll, children: groupsToRender.map((group, index) => (jsxRuntime.jsxs(DivWrapperSC$4, { children: [index !== 0 && jsxRuntime.jsx(FISMenuSection, { withDivider: true }), group?.groupLabel && (jsxRuntime.jsx(FISMenuSection, { label: group?.groupLabel })), group.items.map((item, idx) => (jsxRuntime.jsx(FISTooltip, { title: item.label, variant: "primary", children: jsxRuntime.jsx(FISMenuItem, { title: item.label, description: item.description, size: size, onClickMenu: () => handleItemClick(item), selected: selectedValues.includes(item.value), type: "select" }) }, idx)))] }, index))) }), removeSelectedGroup && (jsxRuntime.jsx(FixedBottomSection, { children: jsxRuntime.jsx(DivWrapperSC$4, { children: removeSelectedGroup.items.map((item, idx) => (jsxRuntime.jsx(FISTooltip, { title: item.label, variant: "primary", children: jsxRuntime.jsx(FISMenuItem, { title: item.label, description: item.description, size: size, onClickMenu: () => onChangeSelected?.([]), type: "select", iconPrefix: jsxRuntime.jsx(RemoveIcon, {}), negative: true }) }, idx))) }) }))] }))] }));
68695
+ React.useEffect(() => {
68696
+ if (focusSearchInput && searchInputRef.current) {
68697
+ searchInputRef.current.focus();
68698
+ }
68699
+ }, [focusSearchInput]);
68700
+ return (jsxRuntime.jsxs(DivContainerSC$4, { "$maxHeight": maxHeight, className: className, children: [showInput && !combobox && (jsxRuntime.jsx(DivSearchSC, { children: jsxRuntime.jsx(FISInputText, { iconPrefix: jsxRuntime.jsx(SearchIcon, {}), placeholder: placeholder, value: search, onChange: handleSearchChange, ref: searchInputRef }) })), loading && (jsxRuntime.jsxs(DivLoaderSC, { children: [jsxRuntime.jsx(FISProgressCircular, { size: size, variant: "indeterminate" }), jsxRuntime.jsx(PTitleSC$2, { children: loadingText })] })), !loading && noData && (jsxRuntime.jsxs(DivLoaderSC, { children: [jsxRuntime.jsx(DivIconDataSC, { children: jsxRuntime.jsx(NoDataIcon, {}) }), jsxRuntime.jsx(PTitleSC$2, { children: noDataText })] })), !loading && !noData && (shouldShowNoResult || noResult) && (jsxRuntime.jsxs(DivLoaderSC, { children: [jsxRuntime.jsx(DivIconDataSC, { children: jsxRuntime.jsx(NoResultIcon, {}) }), jsxRuntime.jsx(PTitleSC$2, { children: noResultText })] })), !shouldShowNoResult && !noData && !loading && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(MenuContent, { "$removeSelectedGroup": !!removeSelectedGroup, onScroll: onPopupScroll, children: groupsToRender.map((group, index) => (jsxRuntime.jsxs(DivWrapperSC$4, { children: [index !== 0 && jsxRuntime.jsx(FISMenuSection, { withDivider: true }), group?.groupLabel && (jsxRuntime.jsx(FISMenuSection, { label: group?.groupLabel })), group.items.map((item, idx) => (jsxRuntime.jsx(FISTooltip, { title: item.label, variant: "primary", children: jsxRuntime.jsx(FISMenuItem, { title: item.label, description: item.description, size: size, onClickMenu: () => handleItemClick(item), selected: selectedValues.includes(item.value), type: "select" }) }, idx)))] }, index))) }), removeSelectedGroup && (jsxRuntime.jsx(FixedBottomSection, { children: jsxRuntime.jsx(DivWrapperSC$4, { children: removeSelectedGroup.items.map((item, idx) => (jsxRuntime.jsx(FISTooltip, { title: item.label, variant: "primary", children: jsxRuntime.jsx(FISMenuItem, { title: item.label, description: item.description, size: size, onClickMenu: () => onChangeSelected?.([]), type: "select", iconPrefix: jsxRuntime.jsx(RemoveIcon, {}), negative: true }) }, idx))) }) }))] }))] }));
68663
68701
  };
68664
68702
  FISMenuSelect.displayName = "FISMenuSelect";
68665
68703