fis-component 0.0.87 → 0.0.89

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.
@@ -1,13 +1,14 @@
1
1
  import { InputLabelProps } from "../Input/InputLabel";
2
2
  import { MenuProps } from "../MenuSelect/types";
3
3
  import { SelectFieldProps } from "../SelectItem";
4
+ export interface SelectOptionItem<T = string | number> {
5
+ label: string;
6
+ description?: string;
7
+ value: T;
8
+ }
4
9
  export interface SelectOption<T = string | number> {
5
10
  groupLabel?: string;
6
- items: {
7
- label: string;
8
- description?: string;
9
- value: T;
10
- }[];
11
+ items: SelectOptionItem<T>[];
11
12
  }
12
13
  type BaseSelectProps<T extends string | number> = Partial<InputLabelProps> & Omit<MenuProps, "groups" | "multi" | "selectedValues" | "onChangeSelected" | "onClickMenu" | "size" | "placeholder"> & Omit<SelectFieldProps, "value" | "onChange"> & {
13
14
  options: SelectOption<T>[];
@@ -25,13 +26,13 @@ export type SingleSelectProps<T extends string | number> = BaseSelectProps<T> &
25
26
  multi?: false;
26
27
  value: T;
27
28
  onChange: (value: T) => void;
28
- displayValue?: (value: SelectOption<T>) => string;
29
+ displayValue?: (item: SelectOptionItem<T>) => string;
29
30
  };
30
31
  export type MultiSelectProps<T extends string | number> = BaseSelectProps<T> & {
31
32
  multi: true;
32
33
  value: T[];
33
34
  onChange: (value: T[]) => void;
34
- displayValue?: (value: SelectOption<T>[]) => string;
35
+ displayValue?: (items: SelectOptionItem<T>[]) => string;
35
36
  };
36
37
  export type SelectProps<T extends string | number> = SingleSelectProps<T> | MultiSelectProps<T>;
37
38
  export {};
package/dist/esm/index.js CHANGED
@@ -64954,38 +64954,23 @@ const FISInputText = forwardRef((props, ref) => {
64954
64954
  const { className, typeSuffix, textLabel = "", iconLabel, required, iconPrefix, sizeInput, showCount, message, negative, positive, maxLength = 500, disabled, onChange, onEnter, onKeyDown, onClickIconLabel, onClickSuffix, ...rest } = props;
64955
64955
  // Internal ref to access DOM element for character count
64956
64956
  const internalRef = React__default.useRef(null);
64957
- const [internalValue, setInternalValue] = React__default.useState(rest.value || rest.defaultValue || "");
64957
+ const [internalValue, setInternalValue] = React__default.useState("");
64958
64958
  // State to trigger re-render for character count (React Hook Form compatibility)
64959
64959
  const [, forceUpdate] = React__default.useReducer((x) => x + 1, 0);
64960
- // Sync internal value with controlled value prop
64961
- React__default.useEffect(() => {
64962
- if (rest.value !== undefined) {
64963
- setInternalValue(rest.value);
64964
- }
64965
- }, [rest.value]);
64966
- // Get current value for display (controlled vs uncontrolled)
64960
+ // Get current value for display (prioritize DOM for React Hook Form)
64967
64961
  const getCurrentValue = () => {
64968
- // Always prioritize DOM value for React Hook Form compatibility
64969
- const domValue = internalRef.current?.value;
64970
- if (domValue !== undefined) {
64971
- return domValue;
64972
- }
64973
- // Fallback to controlled value prop
64974
- if (rest.value !== undefined) {
64975
- return rest.value;
64976
- }
64977
- // Fallback to internal state for uncontrolled mode
64978
- return internalValue ?? "";
64962
+ return (internalRef.current?.value ??
64963
+ rest.value ??
64964
+ internalValue ??
64965
+ "");
64979
64966
  };
64980
64967
  const handleChange = React__default.useCallback((event) => {
64981
- const newValue = event.target.value;
64982
64968
  // Update internal state for uncontrolled mode
64983
64969
  if (rest.value === undefined) {
64984
- setInternalValue(newValue);
64970
+ setInternalValue(event.target.value);
64985
64971
  }
64986
64972
  else {
64987
64973
  // Force re-render only for controlled mode (React Hook Form case)
64988
- // This ensures character count updates when value prop doesn't change
64989
64974
  forceUpdate();
64990
64975
  }
64991
64976
  if (onChange) {
@@ -66038,13 +66023,26 @@ styled.div `
66038
66023
  const FISInputArea = forwardRef((props, ref) => {
66039
66024
  const { className, required = false, textLabel = "", iconLabel, iconSuffix, disabled = false, readOnly = false, negative, message, positive, maxLength = 50, showCount, size = "md", fixedWidth, onClickIconLabel, onClickIconSuffix, onChange, onEnter, ...rest } = props;
66040
66025
  const [internalValue, setInternalValue] = React__default.useState("");
66026
+ // State to trigger re-render for character count (React Hook Form compatibility)
66027
+ const [, forceUpdate] = React__default.useReducer((x) => x + 1, 0);
66041
66028
  const inputRef = React__default.useRef(null);
66029
+ // Get current value for display (prioritize DOM for React Hook Form)
66030
+ const getCurrentValue = () => {
66031
+ return (inputRef.current?.value ?? rest.value ?? internalValue ?? "");
66032
+ };
66042
66033
  const handleChange = React__default.useCallback((event) => {
66043
- setInternalValue(event.target.value);
66034
+ // Update internal state for uncontrolled mode
66035
+ if (rest.value === undefined) {
66036
+ setInternalValue(event.target.value);
66037
+ }
66038
+ else {
66039
+ // Force re-render only for controlled mode (React Hook Form case)
66040
+ forceUpdate();
66041
+ }
66044
66042
  if (onChange) {
66045
66043
  onChange(event);
66046
66044
  }
66047
- }, [onChange]);
66045
+ }, [onChange, rest.value]);
66048
66046
  const handleKeyPress = React__default.useCallback((event) => {
66049
66047
  if (!event)
66050
66048
  return;
@@ -66054,28 +66052,6 @@ const FISInputArea = forwardRef((props, ref) => {
66054
66052
  }
66055
66053
  }
66056
66054
  }, [onEnter]);
66057
- useImperativeHandle(ref, () => {
66058
- const inputElement = inputRef.current;
66059
- return {
66060
- ...inputElement,
66061
- focus: () => {
66062
- if (inputRef.current) {
66063
- inputRef.current.focus();
66064
- }
66065
- },
66066
- blur: () => {
66067
- if (inputRef.current) {
66068
- inputRef.current.blur();
66069
- }
66070
- },
66071
- clear: () => {
66072
- if (inputRef.current) {
66073
- inputRef.current.value = "";
66074
- setInternalValue("");
66075
- }
66076
- },
66077
- };
66078
- });
66079
66055
  const handleResize = (e) => {
66080
66056
  e.preventDefault();
66081
66057
  e.stopPropagation();
@@ -66116,7 +66092,7 @@ const FISInputArea = forwardRef((props, ref) => {
66116
66092
  "input-area-lg": size === "lg",
66117
66093
  "input-area-icon": iconSuffix,
66118
66094
  negative,
66119
- }), style: { width: fixedWidth ? `${fixedWidth}px` : "auto" }, children: [jsx(TextAreaSC, { ...rest, onChange: handleChange, onKeyDown: handleKeyPress, ref: inputRef, disabled: disabled, className: classNames({
66095
+ }), style: { width: fixedWidth ? `${fixedWidth}px` : "auto" }, children: [jsx(TextAreaSC, { ...rest, onChange: handleChange, onKeyDown: handleKeyPress, ref: mergeRefs(ref, inputRef), disabled: disabled, className: classNames({
66120
66096
  negative,
66121
66097
  "input-area-lg": size === "lg",
66122
66098
  "input-area-icon": iconSuffix,
@@ -66127,8 +66103,8 @@ const FISInputArea = forwardRef((props, ref) => {
66127
66103
  negative,
66128
66104
  positive,
66129
66105
  }), children: message ? message : "" }), jsx(DivCountSC, { children: showCount && maxLength > 0 && (jsxs("span", { className: classNames("text-area__count", {
66130
- negative: internalValue.length > maxLength,
66131
- }), children: [internalValue?.replaceAll("\n", "")?.length, "/", maxLength] })) })] })] }));
66106
+ negative: getCurrentValue()?.length > maxLength,
66107
+ }), children: [getCurrentValue()?.length, "/", maxLength] })) })] })] }));
66132
66108
  });
66133
66109
  FISInputArea.displayName = "FISInputArea";
66134
66110
 
@@ -73666,45 +73642,21 @@ const FISSelect = forwardRef(({ className, style, size = "md", options, value, d
73666
73642
  strategy: "fixed",
73667
73643
  }), []);
73668
73644
  const { styles, attributes } = usePopper(referenceElement, popperElement, popperOptions);
73669
- const originalOptionsRef = useRef(options);
73670
- useEffect(() => {
73671
- // Keep track of all items including selected ones
73672
- const allItems = new Map();
73673
- // Add items from current options
73674
- options.forEach((group) => {
73675
- group.items.forEach((item) => {
73676
- allItems.set(item.value, item);
73677
- });
73678
- });
73679
- // Add selected items that might not be in current options
73680
- if (multi && Array.isArray(value)) {
73681
- const selectedItems = originalOptionsRef.current
73682
- .flatMap((group) => group.items)
73683
- .filter((item) => value.includes(item.value));
73684
- selectedItems.forEach((item) => {
73685
- allItems.set(item.value, item);
73686
- });
73687
- }
73688
- // Update originalOptionsRef with all items
73689
- originalOptionsRef.current = [
73690
- {
73691
- items: Array.from(allItems.values()),
73692
- },
73693
- ];
73694
- }, [options, value, multi]);
73695
73645
  const selectedItems = useMemo$1(() => {
73696
73646
  const allItems = options.flatMap((group) => group.items);
73697
73647
  if (multi) {
73698
- return allItems.filter((item) => value.includes(item.value));
73648
+ const selectedArray = Array.isArray(value) ? value : [];
73649
+ return allItems.filter((item) => selectedArray.includes(item.value));
73699
73650
  }
73700
73651
  else {
73701
73652
  const found = allItems.find((item) => item.value === value);
73702
73653
  return found ? [found] : [];
73703
73654
  }
73704
73655
  }, [value, multi, options]);
73705
- const computedDisplayValue = () => {
73656
+ const computedDisplayValue = useMemo$1(() => {
73706
73657
  if (multi) {
73707
- const count = value.length;
73658
+ const selectedArray = Array.isArray(value) ? value : [];
73659
+ const count = selectedArray.length;
73708
73660
  if (count === 0) {
73709
73661
  return "";
73710
73662
  }
@@ -73713,17 +73665,18 @@ const FISSelect = forwardRef(({ className, style, size = "md", options, value, d
73713
73665
  : `Selected ${count.toString().padStart(2, "0")} option${count !== 1 ? "s" : ""}`;
73714
73666
  }
73715
73667
  else {
73716
- if (!selectedItems[0])
73668
+ const firstItem = selectedItems[0];
73669
+ if (!firstItem)
73717
73670
  return "";
73718
- return (displayValue?.(selectedItems[0]) || selectedItems[0].label);
73671
+ return displayValue?.(firstItem) || firstItem.label;
73719
73672
  }
73720
- };
73673
+ }, [multi, value, multiDisplayText, selectedItems, displayValue]);
73721
73674
  const handleToggle = useCallback(() => {
73722
73675
  if (!disabled)
73723
73676
  setIsOpen((prev) => !prev);
73724
73677
  }, [disabled]);
73725
73678
  const handleOptionRemove = useCallback((option) => {
73726
- if (multi) {
73679
+ if (multi && Array.isArray(value)) {
73727
73680
  const newValues = value.filter((v) => v !== option.value);
73728
73681
  onChange(newValues);
73729
73682
  }
@@ -73751,8 +73704,10 @@ const FISSelect = forwardRef(({ className, style, size = "md", options, value, d
73751
73704
  multi,
73752
73705
  size: isMenuSize(size) ? size : "md",
73753
73706
  selectedValues: multi
73754
- ? value
73755
- : value
73707
+ ? Array.isArray(value)
73708
+ ? value
73709
+ : []
73710
+ : value !== undefined && value !== null
73756
73711
  ? [value]
73757
73712
  : [],
73758
73713
  onChangeSelected: handleMenuChange,
@@ -73776,18 +73731,21 @@ const FISSelect = forwardRef(({ className, style, size = "md", options, value, d
73776
73731
  restProps,
73777
73732
  ]);
73778
73733
  useEffect(() => {
73734
+ if (!isOpen)
73735
+ return;
73779
73736
  const handleClickOutside = (event) => {
73737
+ const target = event.target;
73780
73738
  if (referenceElement &&
73781
- !referenceElement.contains(event.target) &&
73739
+ !referenceElement.contains(target) &&
73782
73740
  popperElement &&
73783
- !popperElement.contains(event.target)) {
73741
+ !popperElement.contains(target)) {
73784
73742
  setIsOpen(false);
73785
73743
  }
73786
73744
  };
73787
73745
  document.addEventListener("mousedown", handleClickOutside);
73788
73746
  return () => document.removeEventListener("mousedown", handleClickOutside);
73789
- }, [referenceElement, popperElement]);
73790
- return (jsxs(DivWrapperSC$1, { className: className, style: style, children: [(textLabel || iconLabel) && (jsx(FISInputLabel, { textLabel: textLabel, required: required, iconLabel: iconLabel, onClickIconLabel: onClickIconLabel })), jsx(DivInputWrapperSC, { ref: setReferenceElement, onClick: handleToggle, "$hasValue": !!value, children: jsx(FISSelectItem, { ...restProps, ref: ref, size: size, placeholder: placeholder, iconSuffix: isOpen ? jsx(ArrowUpIcon, {}) : jsx(ArrowDownIcon, {}), value: computedDisplayValue(), disabled: disabled, activeDropdown: isOpen, negative: negative }) }), message && (jsx(SpanHintSC$3, { className: classNames({ disabled, negative, positive }), children: message })), multi && value.length > 0 && (jsx(SelectedTagsWrapper, { children: jsx(MultipleValue, { options: selectedItems, onRemove: handleOptionRemove }) })), isOpen && (jsx(Portal, { portal: portal, children: jsx(DivDropdownMenuSC, { ref: setPopperElement, style: {
73747
+ }, [isOpen, referenceElement, popperElement]);
73748
+ return (jsxs(DivWrapperSC$1, { className: className, style: style, children: [(textLabel || iconLabel) && (jsx(FISInputLabel, { textLabel: textLabel, required: required, iconLabel: iconLabel, onClickIconLabel: onClickIconLabel })), jsx(DivInputWrapperSC, { ref: setReferenceElement, onClick: handleToggle, "$hasValue": !!value, children: jsx(FISSelectItem, { ...restProps, ref: ref, size: size, placeholder: placeholder, iconSuffix: isOpen ? jsx(ArrowUpIcon, {}) : jsx(ArrowDownIcon, {}), value: computedDisplayValue, disabled: disabled, activeDropdown: isOpen, negative: negative }) }), message && (jsx(SpanHintSC$3, { className: classNames({ disabled, negative, positive }), children: message })), multi && Array.isArray(value) && value.length > 0 && (jsx(SelectedTagsWrapper, { children: jsx(MultipleValue, { options: selectedItems, onRemove: handleOptionRemove }) })), isOpen && (jsx(Portal, { portal: portal, children: jsx(DivDropdownMenuSC, { ref: setPopperElement, style: {
73791
73749
  ...styles.popper,
73792
73750
  width: referenceElement?.offsetWidth,
73793
73751
  zIndex: 9999,