@rufous/ui 0.2.85 → 0.2.87

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/main.cjs CHANGED
@@ -2079,17 +2079,17 @@ function AutocompleteInner(props, _ref) {
2079
2079
  setInputStr(v != null ? getOptionLabel(v) : "");
2080
2080
  }
2081
2081
  }, [value, multiple, getOptionLabel, controlledInput]);
2082
- const selectOption = (opt) => {
2082
+ const selectOption = (opt, event) => {
2083
2083
  if (getOptionDisabled?.(opt)) return;
2084
2084
  if (multiple) {
2085
2085
  const already = isSelected(opt);
2086
2086
  const next = already ? selectedValues.filter((v) => !isEqual(v, opt)) : [...selectedValues, opt];
2087
- onChange?.(next);
2087
+ onChange?.(event, next, already ? "removeOption" : "selectOption");
2088
2088
  setInputStr("");
2089
2089
  onInputChange?.("");
2090
2090
  inputRef.current?.focus();
2091
2091
  } else {
2092
- onChange?.(opt);
2092
+ onChange?.(event, opt, "selectOption");
2093
2093
  setInputStr(getOptionLabel(opt));
2094
2094
  onInputChange?.(getOptionLabel(opt));
2095
2095
  closePopup(true);
@@ -2098,7 +2098,7 @@ function AutocompleteInner(props, _ref) {
2098
2098
  };
2099
2099
  const clearAll = (e) => {
2100
2100
  e.stopPropagation();
2101
- onChange?.(multiple ? [] : null);
2101
+ onChange?.(e, multiple ? [] : null, "clear");
2102
2102
  setInputStr("");
2103
2103
  onInputChange?.("");
2104
2104
  inputRef.current?.focus();
@@ -2106,7 +2106,7 @@ function AutocompleteInner(props, _ref) {
2106
2106
  const removeTag = (opt, e) => {
2107
2107
  e.stopPropagation();
2108
2108
  const next = selectedValues.filter((v) => !isEqual(v, opt));
2109
- onChange?.(next);
2109
+ onChange?.(e, next, "removeOption");
2110
2110
  };
2111
2111
  const handleInputChange = (e) => {
2112
2112
  const v = e.target.value;
@@ -2144,9 +2144,9 @@ function AutocompleteInner(props, _ref) {
2144
2144
  return;
2145
2145
  }
2146
2146
  if (focusedIdx >= 0 && focusedIdx < selectableOptions.length) {
2147
- selectOption(selectableOptions[focusedIdx].option);
2147
+ selectOption(selectableOptions[focusedIdx].option, e);
2148
2148
  } else if (freeSolo && activeInput) {
2149
- onChange?.(activeInput);
2149
+ onChange?.(e, activeInput, "freeSolo");
2150
2150
  if (!multiple) closePopup();
2151
2151
  }
2152
2152
  } else if (e.key === "Escape") {
@@ -2309,7 +2309,7 @@ function AutocompleteInner(props, _ref) {
2309
2309
  onMouseEnter: () => setFocusedIdx(flatIdx),
2310
2310
  onMouseLeave: () => setFocusedIdx(-1),
2311
2311
  onMouseDown: (e) => e.preventDefault(),
2312
- onClick: () => selectOption(option)
2312
+ onClick: (e) => selectOption(option, e)
2313
2313
  },
2314
2314
  renderOption ? renderOption(option, { selected, focused, index: flatIdx }) : /* @__PURE__ */ import_react18.default.createElement("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, label2),
2315
2315
  !renderOption && /* @__PURE__ */ import_react18.default.createElement("span", { className: "rf-autocomplete__option-check" }, /* @__PURE__ */ import_react18.default.createElement(CheckIcon, null))
@@ -2537,7 +2537,7 @@ var AddressLookup = ({
2537
2537
  {
2538
2538
  options: countries.map((c) => c.name),
2539
2539
  value: value.country || null,
2540
- onChange: (v) => handleCountryChange(v || ""),
2540
+ onChange: (_e, v) => handleCountryChange(v || ""),
2541
2541
  label: "Country",
2542
2542
  fullWidth: true,
2543
2543
  required,
@@ -2548,7 +2548,7 @@ var AddressLookup = ({
2548
2548
  {
2549
2549
  options: states.map((s2) => s2.name),
2550
2550
  value: value.state || null,
2551
- onChange: (v) => handleStateChange(v || ""),
2551
+ onChange: (_e, v) => handleStateChange(v || ""),
2552
2552
  label: "State",
2553
2553
  fullWidth: true,
2554
2554
  required,
@@ -2559,7 +2559,7 @@ var AddressLookup = ({
2559
2559
  {
2560
2560
  options: cities.map((c) => c.name),
2561
2561
  value: value.city || null,
2562
- onChange: (v) => handleChange("city", v || ""),
2562
+ onChange: (_e, v) => handleChange("city", v || ""),
2563
2563
  label: "City",
2564
2564
  fullWidth: true,
2565
2565
  required,
@@ -4919,6 +4919,7 @@ var Select = import_react24.default.forwardRef(function Select2(props, ref) {
4919
4919
  const [focusedIdx, setFocusedIdx] = (0, import_react24.useState)(-1);
4920
4920
  const [popupStyle, setPopupStyle] = (0, import_react24.useState)({});
4921
4921
  const containerRef = (0, import_react24.useRef)(null);
4922
+ const popupRef = (0, import_react24.useRef)(null);
4922
4923
  const listRef = (0, import_react24.useRef)(null);
4923
4924
  const inputId = (0, import_react24.useRef)(`rf-sel-${Math.random().toString(36).slice(2, 9)}`).current;
4924
4925
  const sxClass = useSx(sx);
@@ -4957,7 +4958,7 @@ var Select = import_react24.default.forwardRef(function Select2(props, ref) {
4957
4958
  (0, import_react24.useEffect)(() => {
4958
4959
  if (!open) return;
4959
4960
  const handleOutside = (e) => {
4960
- if (containerRef.current && !containerRef.current.contains(e.target)) {
4961
+ if (containerRef.current && !containerRef.current.contains(e.target) && popupRef.current && !popupRef.current.contains(e.target)) {
4961
4962
  closePopup();
4962
4963
  }
4963
4964
  };
@@ -4970,14 +4971,14 @@ var Select = import_react24.default.forwardRef(function Select2(props, ref) {
4970
4971
  window.removeEventListener("resize", calcPopupStyle);
4971
4972
  };
4972
4973
  }, [open, closePopup, calcPopupStyle]);
4973
- const selectOption = (0, import_react24.useCallback)((opt) => {
4974
+ const selectOption = (0, import_react24.useCallback)((opt, event) => {
4974
4975
  if (opt.disabled) return;
4975
4976
  if (multiple) {
4976
4977
  const already = isSelected(opt.value);
4977
4978
  const next = already ? selectedValues.filter((v) => v !== opt.value) : [...selectedValues, opt.value];
4978
- onChange?.(next);
4979
+ onChange?.(event, next);
4979
4980
  } else {
4980
- onChange?.(opt.value);
4981
+ onChange?.(event, opt.value);
4981
4982
  closePopup();
4982
4983
  }
4983
4984
  }, [multiple, isSelected, selectedValues, onChange, closePopup]);
@@ -5013,7 +5014,7 @@ var Select = import_react24.default.forwardRef(function Select2(props, ref) {
5013
5014
  }
5014
5015
  if (focusedIdx >= 0) {
5015
5016
  const opt = selectableOpts[focusedIdx];
5016
- if (opt) selectOption(opt);
5017
+ if (opt) selectOption(opt, e);
5017
5018
  }
5018
5019
  } else if (e.key === "Escape") {
5019
5020
  closePopup();
@@ -5089,7 +5090,7 @@ var Select = import_react24.default.forwardRef(function Select2(props, ref) {
5089
5090
  ),
5090
5091
  helperText && /* @__PURE__ */ import_react24.default.createElement("div", { className: `rf-text-field__helper-text${error ? " rf-text-field__helper-text--error" : ""}` }, helperText),
5091
5092
  open && !disabled && import_react_dom5.default.createPortal(
5092
- /* @__PURE__ */ import_react24.default.createElement("div", { className: "rf-select__popup", role: "presentation", style: popupStyle }, /* @__PURE__ */ import_react24.default.createElement("ul", { ref: listRef, className: "rf-select__listbox", role: "listbox", "aria-multiselectable": multiple }, options.map((opt, idx) => {
5093
+ /* @__PURE__ */ import_react24.default.createElement("div", { ref: popupRef, className: "rf-select__popup", role: "presentation", style: popupStyle }, /* @__PURE__ */ import_react24.default.createElement("ul", { ref: listRef, className: "rf-select__listbox", role: "listbox", "aria-multiselectable": multiple }, options.map((opt, idx) => {
5093
5094
  const selected = isSelected(opt.value);
5094
5095
  const focused = focusedIdx === idx;
5095
5096
  return /* @__PURE__ */ import_react24.default.createElement(
@@ -5109,7 +5110,7 @@ var Select = import_react24.default.forwardRef(function Select2(props, ref) {
5109
5110
  onMouseEnter: () => setFocusedIdx(idx),
5110
5111
  onMouseLeave: () => setFocusedIdx(-1),
5111
5112
  onMouseDown: (e) => e.preventDefault(),
5112
- onClick: () => selectOption(opt)
5113
+ onClick: (e) => selectOption(opt, e)
5113
5114
  },
5114
5115
  /* @__PURE__ */ import_react24.default.createElement("span", { className: "rf-select__option-label" }, opt.label),
5115
5116
  /* @__PURE__ */ import_react24.default.createElement("span", { className: "rf-select__option-check", "aria-hidden": "true" }, /* @__PURE__ */ import_react24.default.createElement(CheckIcon2, null))
package/dist/main.d.cts CHANGED
@@ -674,7 +674,7 @@ interface AutocompleteProps<T = string> {
674
674
  /** Controlled value — T for single, T[] for multiple, null to clear */
675
675
  value?: T | T[] | null;
676
676
  /** Called when the value changes */
677
- onChange?: (value: T | T[] | null) => void;
677
+ onChange?: (event: React__default.SyntheticEvent, value: T | T[] | null, reason: 'selectOption' | 'removeOption' | 'clear' | 'freeSolo') => void;
678
678
  /** Controlled text in the input */
679
679
  inputValue?: string;
680
680
  /** Called on every keystroke */
@@ -838,7 +838,7 @@ type SelectOption = {
838
838
  interface SelectProps {
839
839
  options: SelectOption[] | string[];
840
840
  value?: string | number | null;
841
- onChange?: (value: string | number | null) => void;
841
+ onChange?: (event: React__default.SyntheticEvent, value: string | number | (string | number)[] | null) => void;
842
842
  label?: string;
843
843
  placeholder?: string;
844
844
  variant?: "outlined" | "filled" | "standard";
package/dist/main.d.ts CHANGED
@@ -674,7 +674,7 @@ interface AutocompleteProps<T = string> {
674
674
  /** Controlled value — T for single, T[] for multiple, null to clear */
675
675
  value?: T | T[] | null;
676
676
  /** Called when the value changes */
677
- onChange?: (value: T | T[] | null) => void;
677
+ onChange?: (event: React__default.SyntheticEvent, value: T | T[] | null, reason: 'selectOption' | 'removeOption' | 'clear' | 'freeSolo') => void;
678
678
  /** Controlled text in the input */
679
679
  inputValue?: string;
680
680
  /** Called on every keystroke */
@@ -838,7 +838,7 @@ type SelectOption = {
838
838
  interface SelectProps {
839
839
  options: SelectOption[] | string[];
840
840
  value?: string | number | null;
841
- onChange?: (value: string | number | null) => void;
841
+ onChange?: (event: React__default.SyntheticEvent, value: string | number | (string | number)[] | null) => void;
842
842
  label?: string;
843
843
  placeholder?: string;
844
844
  variant?: "outlined" | "filled" | "standard";
package/dist/main.js CHANGED
@@ -1918,17 +1918,17 @@ function AutocompleteInner(props, _ref) {
1918
1918
  setInputStr(v != null ? getOptionLabel(v) : "");
1919
1919
  }
1920
1920
  }, [value, multiple, getOptionLabel, controlledInput]);
1921
- const selectOption = (opt) => {
1921
+ const selectOption = (opt, event) => {
1922
1922
  if (getOptionDisabled?.(opt)) return;
1923
1923
  if (multiple) {
1924
1924
  const already = isSelected(opt);
1925
1925
  const next = already ? selectedValues.filter((v) => !isEqual(v, opt)) : [...selectedValues, opt];
1926
- onChange?.(next);
1926
+ onChange?.(event, next, already ? "removeOption" : "selectOption");
1927
1927
  setInputStr("");
1928
1928
  onInputChange?.("");
1929
1929
  inputRef.current?.focus();
1930
1930
  } else {
1931
- onChange?.(opt);
1931
+ onChange?.(event, opt, "selectOption");
1932
1932
  setInputStr(getOptionLabel(opt));
1933
1933
  onInputChange?.(getOptionLabel(opt));
1934
1934
  closePopup(true);
@@ -1937,7 +1937,7 @@ function AutocompleteInner(props, _ref) {
1937
1937
  };
1938
1938
  const clearAll = (e) => {
1939
1939
  e.stopPropagation();
1940
- onChange?.(multiple ? [] : null);
1940
+ onChange?.(e, multiple ? [] : null, "clear");
1941
1941
  setInputStr("");
1942
1942
  onInputChange?.("");
1943
1943
  inputRef.current?.focus();
@@ -1945,7 +1945,7 @@ function AutocompleteInner(props, _ref) {
1945
1945
  const removeTag = (opt, e) => {
1946
1946
  e.stopPropagation();
1947
1947
  const next = selectedValues.filter((v) => !isEqual(v, opt));
1948
- onChange?.(next);
1948
+ onChange?.(e, next, "removeOption");
1949
1949
  };
1950
1950
  const handleInputChange = (e) => {
1951
1951
  const v = e.target.value;
@@ -1983,9 +1983,9 @@ function AutocompleteInner(props, _ref) {
1983
1983
  return;
1984
1984
  }
1985
1985
  if (focusedIdx >= 0 && focusedIdx < selectableOptions.length) {
1986
- selectOption(selectableOptions[focusedIdx].option);
1986
+ selectOption(selectableOptions[focusedIdx].option, e);
1987
1987
  } else if (freeSolo && activeInput) {
1988
- onChange?.(activeInput);
1988
+ onChange?.(e, activeInput, "freeSolo");
1989
1989
  if (!multiple) closePopup();
1990
1990
  }
1991
1991
  } else if (e.key === "Escape") {
@@ -2148,7 +2148,7 @@ function AutocompleteInner(props, _ref) {
2148
2148
  onMouseEnter: () => setFocusedIdx(flatIdx),
2149
2149
  onMouseLeave: () => setFocusedIdx(-1),
2150
2150
  onMouseDown: (e) => e.preventDefault(),
2151
- onClick: () => selectOption(option)
2151
+ onClick: (e) => selectOption(option, e)
2152
2152
  },
2153
2153
  renderOption ? renderOption(option, { selected, focused, index: flatIdx }) : /* @__PURE__ */ React69.createElement("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, label2),
2154
2154
  !renderOption && /* @__PURE__ */ React69.createElement("span", { className: "rf-autocomplete__option-check" }, /* @__PURE__ */ React69.createElement(CheckIcon, null))
@@ -2376,7 +2376,7 @@ var AddressLookup = ({
2376
2376
  {
2377
2377
  options: countries.map((c) => c.name),
2378
2378
  value: value.country || null,
2379
- onChange: (v) => handleCountryChange(v || ""),
2379
+ onChange: (_e, v) => handleCountryChange(v || ""),
2380
2380
  label: "Country",
2381
2381
  fullWidth: true,
2382
2382
  required,
@@ -2387,7 +2387,7 @@ var AddressLookup = ({
2387
2387
  {
2388
2388
  options: states.map((s2) => s2.name),
2389
2389
  value: value.state || null,
2390
- onChange: (v) => handleStateChange(v || ""),
2390
+ onChange: (_e, v) => handleStateChange(v || ""),
2391
2391
  label: "State",
2392
2392
  fullWidth: true,
2393
2393
  required,
@@ -2398,7 +2398,7 @@ var AddressLookup = ({
2398
2398
  {
2399
2399
  options: cities.map((c) => c.name),
2400
2400
  value: value.city || null,
2401
- onChange: (v) => handleChange("city", v || ""),
2401
+ onChange: (_e, v) => handleChange("city", v || ""),
2402
2402
  label: "City",
2403
2403
  fullWidth: true,
2404
2404
  required,
@@ -4794,6 +4794,7 @@ var Select = React76.forwardRef(function Select2(props, ref) {
4794
4794
  const [focusedIdx, setFocusedIdx] = useState10(-1);
4795
4795
  const [popupStyle, setPopupStyle] = useState10({});
4796
4796
  const containerRef = useRef10(null);
4797
+ const popupRef = useRef10(null);
4797
4798
  const listRef = useRef10(null);
4798
4799
  const inputId = useRef10(`rf-sel-${Math.random().toString(36).slice(2, 9)}`).current;
4799
4800
  const sxClass = useSx(sx);
@@ -4832,7 +4833,7 @@ var Select = React76.forwardRef(function Select2(props, ref) {
4832
4833
  useEffect10(() => {
4833
4834
  if (!open) return;
4834
4835
  const handleOutside = (e) => {
4835
- if (containerRef.current && !containerRef.current.contains(e.target)) {
4836
+ if (containerRef.current && !containerRef.current.contains(e.target) && popupRef.current && !popupRef.current.contains(e.target)) {
4836
4837
  closePopup();
4837
4838
  }
4838
4839
  };
@@ -4845,14 +4846,14 @@ var Select = React76.forwardRef(function Select2(props, ref) {
4845
4846
  window.removeEventListener("resize", calcPopupStyle);
4846
4847
  };
4847
4848
  }, [open, closePopup, calcPopupStyle]);
4848
- const selectOption = useCallback4((opt) => {
4849
+ const selectOption = useCallback4((opt, event) => {
4849
4850
  if (opt.disabled) return;
4850
4851
  if (multiple) {
4851
4852
  const already = isSelected(opt.value);
4852
4853
  const next = already ? selectedValues.filter((v) => v !== opt.value) : [...selectedValues, opt.value];
4853
- onChange?.(next);
4854
+ onChange?.(event, next);
4854
4855
  } else {
4855
- onChange?.(opt.value);
4856
+ onChange?.(event, opt.value);
4856
4857
  closePopup();
4857
4858
  }
4858
4859
  }, [multiple, isSelected, selectedValues, onChange, closePopup]);
@@ -4888,7 +4889,7 @@ var Select = React76.forwardRef(function Select2(props, ref) {
4888
4889
  }
4889
4890
  if (focusedIdx >= 0) {
4890
4891
  const opt = selectableOpts[focusedIdx];
4891
- if (opt) selectOption(opt);
4892
+ if (opt) selectOption(opt, e);
4892
4893
  }
4893
4894
  } else if (e.key === "Escape") {
4894
4895
  closePopup();
@@ -4964,7 +4965,7 @@ var Select = React76.forwardRef(function Select2(props, ref) {
4964
4965
  ),
4965
4966
  helperText && /* @__PURE__ */ React76.createElement("div", { className: `rf-text-field__helper-text${error ? " rf-text-field__helper-text--error" : ""}` }, helperText),
4966
4967
  open && !disabled && ReactDOM4.createPortal(
4967
- /* @__PURE__ */ React76.createElement("div", { className: "rf-select__popup", role: "presentation", style: popupStyle }, /* @__PURE__ */ React76.createElement("ul", { ref: listRef, className: "rf-select__listbox", role: "listbox", "aria-multiselectable": multiple }, options.map((opt, idx) => {
4968
+ /* @__PURE__ */ React76.createElement("div", { ref: popupRef, className: "rf-select__popup", role: "presentation", style: popupStyle }, /* @__PURE__ */ React76.createElement("ul", { ref: listRef, className: "rf-select__listbox", role: "listbox", "aria-multiselectable": multiple }, options.map((opt, idx) => {
4968
4969
  const selected = isSelected(opt.value);
4969
4970
  const focused = focusedIdx === idx;
4970
4971
  return /* @__PURE__ */ React76.createElement(
@@ -4984,7 +4985,7 @@ var Select = React76.forwardRef(function Select2(props, ref) {
4984
4985
  onMouseEnter: () => setFocusedIdx(idx),
4985
4986
  onMouseLeave: () => setFocusedIdx(-1),
4986
4987
  onMouseDown: (e) => e.preventDefault(),
4987
- onClick: () => selectOption(opt)
4988
+ onClick: (e) => selectOption(opt, e)
4988
4989
  },
4989
4990
  /* @__PURE__ */ React76.createElement("span", { className: "rf-select__option-label" }, opt.label),
4990
4991
  /* @__PURE__ */ React76.createElement("span", { className: "rf-select__option-check", "aria-hidden": "true" }, /* @__PURE__ */ React76.createElement(CheckIcon2, null))
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rufous/ui",
3
3
  "private": false,
4
- "version": "0.2.85",
4
+ "version": "0.2.87",
5
5
  "type": "module",
6
6
  "description": "Experimental: A lightweight React UI component library (Beta)",
7
7
  "style": "./dist/main.css",