@edifice.io/react 2.2.8-develop-b2school.20250603143923 → 2.2.8-develop-b2school.20250606132301

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.
@@ -19,6 +19,9 @@ export interface ComboboxProps extends React.InputHTMLAttributes<HTMLInputElemen
19
19
  renderNoResult?: ReactNode;
20
20
  hasDefault?: boolean;
21
21
  }
22
+ export interface ComboboxRef {
23
+ focus: () => void;
24
+ }
22
25
  export interface OptionListItemType {
23
26
  /**
24
27
  * Value
@@ -41,46 +44,7 @@ export interface OptionListItemType {
41
44
  */
42
45
  disabled?: boolean;
43
46
  }
44
- /**
45
- * A component that combines an input field with a dropdown list of selectable options.
46
- *
47
- * @component
48
- * @example
49
- * ```tsx
50
- * <Combobox
51
- * onSearchResultsChange={(values) => console.log(values)}
52
- * onSearchInputChange={(e) => console.log(e.target.value)}
53
- * options={[{ value: '1', label: 'Option 1' }]}
54
- * value=""
55
- * isLoading={false}
56
- * noResult={false}
57
- * />
58
- * ```
59
- *
60
- * @param props - The component props
61
- * @param props.onFocus - Callback fired when the input is focused
62
- * @param props.onBlur - Callback fired when the input is blured
63
- * @param props.onSearchResultsChange - Callback fired when the selected values change
64
- * @param props.onSearchInputChange - Callback fired when the search input value changes
65
- * @param props.options - Array of options to display in the dropdown
66
- * @param props.value - Current value of the search input
67
- * @param props.isLoading - Whether the component is in a loading state
68
- * @param props.noResult - Whether to show a "no results" message
69
- * @param props.searchMinLength - Minimum number of characters required to trigger search
70
- * @param props.placeholder - Placeholder text for the input field
71
- * @param props.variant - Visual variant of the input ('outline' or 'ghost')
72
- * @param props.renderInputGroup - Custom render function for the input group
73
- * @param props.renderList - Custom render function for the dropdown list
74
- * @param props.renderListItem - Custom render function for each option item
75
- * @param props.renderSelectedItems - Custom render function for selected items
76
- * @param props.renderNoResult - Custom render function for no results message
77
- * @param props.hasDefault - Whether to show default options
78
- *
79
- * @extends {React.InputHTMLAttributes<HTMLInputElement>}
80
- */
81
- declare const Combobox: {
82
- ({ onFocus, onBlur, onSearchResultsChange, onSearchInputChange, onSearchInputKeyUp, options, value, isLoading, noResult, searchMinLength, placeholder, variant, renderInputGroup, renderList, renderListItem, renderSelectedItems, renderNoResult, }: ComboboxProps): import("react/jsx-runtime").JSX.Element;
83
- Trigger: ({ placeholder, value, searchMinLength, onFocus, onBlur, handleSearchInputChange, handleSearchInputKeyUp, renderInputGroup, variant, renderSelectedItems, hasDefault, }: import('./ComboboxTrigger').ComboboxTriggerProps) => import("react/jsx-runtime").JSX.Element;
84
- displayName: string;
47
+ declare const Combobox: import('react').ForwardRefExoticComponent<ComboboxProps & import('react').RefAttributes<ComboboxRef>> & {
48
+ Trigger: ({ placeholder, value, searchMinLength, onFocus, onBlur, handleSearchInputChange, handleSearchInputKeyUp, renderInputGroup, variant, renderSelectedItems, hasDefault, inputRef, }: import('./ComboboxTrigger').ComboboxTriggerProps) => import("react/jsx-runtime").JSX.Element;
85
49
  };
86
50
  export default Combobox;
@@ -1,10 +1,10 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
- import { useState, useEffect, Fragment } from "react";
2
+ import { forwardRef, useRef, useState, useEffect, useImperativeHandle, Fragment } from "react";
3
3
  import { useTranslation } from "react-i18next";
4
4
  import ComboboxTrigger from "./ComboboxTrigger.js";
5
5
  import Dropdown from "../Dropdown/Dropdown.js";
6
6
  import Loading from "../Loading/Loading.js";
7
- const Combobox = ({
7
+ const ComboboxComponent = /* @__PURE__ */ forwardRef(({
8
8
  onFocus,
9
9
  onBlur,
10
10
  onSearchResultsChange,
@@ -22,30 +22,38 @@ const Combobox = ({
22
22
  renderListItem,
23
23
  renderSelectedItems,
24
24
  renderNoResult
25
- }) => {
25
+ }, ref) => {
26
26
  const {
27
27
  t
28
- } = useTranslation(), [localValue, setLocalValue] = useState([]);
28
+ } = useTranslation(), inputRef = useRef(null), [localValue, setLocalValue] = useState([]);
29
29
  useEffect(() => {
30
30
  onSearchResultsChange == null || onSearchResultsChange(localValue);
31
31
  }, [localValue]);
32
- const handleOptionClick = (value2) => {
33
- setLocalValue([value2]);
34
- }, renderContent = () => isLoading ? /* @__PURE__ */ jsxs("div", { className: "d-flex align-items-center p-4", children: [
32
+ const focusInput = () => {
33
+ var _a;
34
+ (_a = inputRef.current) == null || _a.focus();
35
+ }, handleOptionClick = (value2) => {
36
+ setLocalValue([value2]), focusInput();
37
+ };
38
+ useImperativeHandle(ref, () => ({
39
+ focus: focusInput
40
+ }));
41
+ const renderContent = () => isLoading ? /* @__PURE__ */ jsxs("div", { className: "d-flex align-items-center p-4", children: [
35
42
  /* @__PURE__ */ jsx(Loading, { isLoading }),
36
43
  /* @__PURE__ */ jsx("span", { className: "ps-4", children: t("explorer.search.pending") })
37
44
  ] }) : noResult ? renderNoResult || /* @__PURE__ */ jsx("div", { className: "p-4", children: t("portal.no.result") }) : renderList ? renderList(options) : options.map((option, index) => /* @__PURE__ */ jsxs(Fragment, { children: [
38
45
  /* @__PURE__ */ jsx(Dropdown.Item, { type: "select", icon: option.icon, onClick: () => handleOptionClick(option.value), disabled: option.disabled, children: renderListItem ? renderListItem(option) : option.label }),
39
46
  (option.withSeparator || option.withSeparator === void 0) && index < options.length - 1 && /* @__PURE__ */ jsx(Dropdown.Separator, {})
40
47
  ] }, index));
41
- return /* @__PURE__ */ jsxs(Dropdown, { block: !0, focusOnVisible: !1, openOnSpace: !1, children: [
48
+ return /* @__PURE__ */ jsxs(Dropdown, { block: !0, focusOnVisible: !1, openOnSpace: !1, focusOnMouseEnter: !1, children: [
42
49
  /* @__PURE__ */ jsx(Combobox.Trigger, { placeholder, searchMinLength, handleSearchInputChange: onSearchInputChange, handleSearchInputKeyUp: (event) => {
43
50
  onSearchInputKeyUp == null || onSearchInputKeyUp(event);
44
- }, value, variant, renderInputGroup, renderSelectedItems, hasDefault: !!options.length, onFocus, onBlur }),
51
+ }, value, variant, renderInputGroup, renderSelectedItems, hasDefault: !!options.length, onFocus, onBlur, inputRef }),
45
52
  /* @__PURE__ */ jsx(Dropdown.Menu, { children: renderContent() })
46
53
  ] });
47
- };
48
- Combobox.Trigger = ComboboxTrigger;
54
+ }), Combobox = /* @__PURE__ */ Object.assign(ComboboxComponent, {
55
+ Trigger: ComboboxTrigger
56
+ });
49
57
  export {
50
58
  Combobox as default
51
59
  };
@@ -11,6 +11,7 @@ export interface ComboboxTriggerProps extends React.ComponentPropsWithRef<'input
11
11
  hasDefault: boolean;
12
12
  onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
13
13
  onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
14
+ inputRef?: React.Ref<HTMLInputElement>;
14
15
  }
15
16
  /**
16
17
  * A trigger component for the Combobox that handles user input and displays selected items.
@@ -36,5 +37,5 @@ export interface ComboboxTriggerProps extends React.ComponentPropsWithRef<'input
36
37
  *
37
38
  * @returns {JSX.Element} A form control containing an input field with optional input group and selected items
38
39
  */
39
- declare const ComboboxTrigger: ({ placeholder, value, searchMinLength, onFocus, onBlur, handleSearchInputChange, handleSearchInputKeyUp, renderInputGroup, variant, renderSelectedItems, hasDefault, }: ComboboxTriggerProps) => import("react/jsx-runtime").JSX.Element;
40
+ declare const ComboboxTrigger: ({ placeholder, value, searchMinLength, onFocus, onBlur, handleSearchInputChange, handleSearchInputKeyUp, renderInputGroup, variant, renderSelectedItems, hasDefault, inputRef, }: ComboboxTriggerProps) => import("react/jsx-runtime").JSX.Element;
40
41
  export default ComboboxTrigger;
@@ -15,7 +15,8 @@ const ComboboxTrigger = ({
15
15
  renderInputGroup,
16
16
  variant = "outline",
17
17
  renderSelectedItems,
18
- hasDefault
18
+ hasDefault,
19
+ inputRef
19
20
  }) => {
20
21
  const {
21
22
  triggerProps,
@@ -38,7 +39,8 @@ const ComboboxTrigger = ({
38
39
  },
39
40
  onKeyUp: (event) => {
40
41
  handleSearchInputKeyUp == null || handleSearchInputKeyUp(event);
41
- }
42
+ },
43
+ ref: inputRef
42
44
  }, classNameVariant = variant === "ghost" ? " border-0" : "", classNameInput = clsx(classNameVariant, renderSelectedItems ? "flex-fill w-auto " : "");
43
45
  return useEffect(() => {
44
46
  setVisible(value.length >= searchMinLength);
@@ -40,6 +40,10 @@ export interface DropdownProps {
40
40
  * Whether to open the dropdown on space key press.
41
41
  */
42
42
  openOnSpace?: boolean;
43
+ /**
44
+ * Whether to focus the element on mouse enter.
45
+ */
46
+ focusOnMouseEnter?: boolean;
43
47
  }
44
48
  export type DropdownMenuOptions = {
45
49
  /**
@@ -65,7 +69,7 @@ export type DropdownMenuOptions = {
65
69
  type: 'divider';
66
70
  };
67
71
  declare const Dropdown: {
68
- ({ children, block, overflow, noWrap, placement, extraTriggerKeyDownHandler, onToggle, isTriggerHovered, focusOnVisible, openOnSpace, }: DropdownProps): import("react/jsx-runtime").JSX.Element;
72
+ ({ children, block, overflow, noWrap, placement, extraTriggerKeyDownHandler, onToggle, isTriggerHovered, focusOnVisible, openOnSpace, focusOnMouseEnter, }: DropdownProps): import("react/jsx-runtime").JSX.Element;
69
73
  displayName: string;
70
74
  } & {
71
75
  Trigger: import('react').ForwardRefExoticComponent<Omit<import('./DropdownTrigger').DropdownTriggerProps, "ref"> & import('react').RefAttributes<HTMLButtonElement>>;
@@ -21,7 +21,8 @@ const Root = ({
21
21
  onToggle,
22
22
  isTriggerHovered = !1,
23
23
  focusOnVisible = !0,
24
- openOnSpace = !0
24
+ openOnSpace = !0,
25
+ focusOnMouseEnter = !0
25
26
  }) => {
26
27
  const {
27
28
  visible,
@@ -31,7 +32,7 @@ const Root = ({
31
32
  itemProps,
32
33
  itemRefs,
33
34
  setVisible
34
- } = useDropdown(placement, extraTriggerKeyDownHandler, isTriggerHovered, focusOnVisible, openOnSpace), ref = useClickOutside(() => {
35
+ } = useDropdown(placement, extraTriggerKeyDownHandler, isTriggerHovered, focusOnVisible, openOnSpace, focusOnMouseEnter), ref = useClickOutside(() => {
35
36
  setVisible(!1);
36
37
  }), value = useMemo(() => ({
37
38
  visible,
@@ -38,7 +38,7 @@ function useDate() {
38
38
  const computedDate = toComputedDate(date);
39
39
  if (!(computedDate != null && computedDate.isValid())) return "";
40
40
  const now = dayjs();
41
- return computedDate.isSame(now, "date") ? now.diff(computedDate, "hours") <= 3 ? computedDate.fromNow() : computedDate.format(t("date.format.currentDay")) : computedDate.isSame(now.subtract(1, "day"), "date") ? t("date.format.yesterday") : now.diff(computedDate, "days") <= 7 ? computedDate.format(t("date.format.currentWeek")) : computedDate.isSame(now, "year") ? computedDate.format(t("date.format.currentYear")) : computedDate.format(t("date.format.previousYear"));
41
+ return computedDate.isSame(now, "date") ? computedDate.fromNow() : computedDate.isSame(now.subtract(1, "day"), "date") ? t("date.format.yesterday") : now.diff(computedDate, "days") <= 7 ? computedDate.format(t("date.format.currentWeek")) : computedDate.isSame(now, "year") ? computedDate.format(t("date.format.currentYear")) : computedDate.format(t("date.format.previousYear"));
42
42
  }, [currentLanguage, parseDate]), fromNow = useCallback((date) => {
43
43
  const computedDate = toComputedDate(date);
44
44
  return computedDate != null && computedDate.isValid() ? computedDate.fromNow() : "";
@@ -29,5 +29,5 @@ export interface UseDropdownProps {
29
29
  setVisible: Dispatch<SetStateAction<boolean>>;
30
30
  openOnSpace?: boolean;
31
31
  }
32
- declare const useDropdown: (placement: Placement | undefined, extraTriggerKeyDownHandler?: (event: React.KeyboardEvent<HTMLButtonElement>) => void, isTriggerHovered?: boolean, focusOnVisible?: boolean, openOnSpace?: boolean) => UseDropdownProps;
32
+ declare const useDropdown: (placement: Placement | undefined, extraTriggerKeyDownHandler?: (event: React.KeyboardEvent<HTMLButtonElement>) => void, isTriggerHovered?: boolean, focusOnVisible?: boolean, openOnSpace?: boolean, focusOnMouseEnter?: boolean) => UseDropdownProps;
33
33
  export default useDropdown;
@@ -1,7 +1,7 @@
1
1
  import { useId, useState, useRef, useEffect, useCallback } from "react";
2
2
  import { useFloating, offset, size, flip, autoUpdate, useHover, safePolygon } from "@floating-ui/react";
3
3
  import { mergeRefs } from "../../utilities/refs/ref.js";
4
- const useDropdown = (placement, extraTriggerKeyDownHandler, isTriggerHovered = !1, focusOnVisible = !0, openOnSpace = !0) => {
4
+ const useDropdown = (placement, extraTriggerKeyDownHandler, isTriggerHovered = !1, focusOnVisible = !0, openOnSpace = !0, focusOnMouseEnter = !0) => {
5
5
  const id = useId(), [visible, setVisible] = useState(!1), [activeIndex, setActiveIndex] = useState(-1), [isFocused, setIsFocused] = useState(null), {
6
6
  refs,
7
7
  floatingStyles,
@@ -84,8 +84,10 @@ const useDropdown = (placement, extraTriggerKeyDownHandler, isTriggerHovered = !
84
84
  }
85
85
  extraTriggerKeyDownHandler == null || extraTriggerKeyDownHandler(event), stopEvents(flag, event);
86
86
  }, [closeDropdown, openDropdown]), onMenuItemMouseEnter = (event) => {
87
- const index = Object.values(itemRefs.current).findIndex((item) => item.id === event.currentTarget.getAttribute("id"));
88
- setActiveIndex(index);
87
+ if (focusOnMouseEnter) {
88
+ const index = Object.values(itemRefs.current).findIndex((item) => item.id === event.currentTarget.getAttribute("id"));
89
+ setActiveIndex(index);
90
+ }
89
91
  }, onMenuItemKeyDown = useCallback((event, onSuccess) => {
90
92
  let flag = !1;
91
93
  if (event.shiftKey)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edifice.io/react",
3
- "version": "2.2.8-develop-b2school.20250603143923",
3
+ "version": "2.2.8-develop-b2school.20250606132301",
4
4
  "description": "Edifice React Library",
5
5
  "keywords": [
6
6
  "react",
@@ -118,9 +118,9 @@
118
118
  "react-slugify": "^3.0.3",
119
119
  "swiper": "^10.1.0",
120
120
  "ua-parser-js": "^1.0.36",
121
- "@edifice.io/bootstrap": "2.2.8-develop-b2school.20250603143923",
122
- "@edifice.io/tiptap-extensions": "2.2.8-develop-b2school.20250603143923",
123
- "@edifice.io/utilities": "2.2.8-develop-b2school.20250603143923"
121
+ "@edifice.io/bootstrap": "2.2.8-develop-b2school.20250606132301",
122
+ "@edifice.io/tiptap-extensions": "2.2.8-develop-b2school.20250606132301",
123
+ "@edifice.io/utilities": "2.2.8-develop-b2school.20250606132301"
124
124
  },
125
125
  "devDependencies": {
126
126
  "@babel/plugin-transform-react-pure-annotations": "^7.23.3",
@@ -151,8 +151,8 @@
151
151
  "vite": "^5.4.11",
152
152
  "vite-plugin-dts": "^4.1.0",
153
153
  "vite-tsconfig-paths": "^5.0.1",
154
- "@edifice.io/client": "2.2.8-develop-b2school.20250603143923",
155
- "@edifice.io/config": "2.2.8-develop-b2school.20250603143923"
154
+ "@edifice.io/client": "2.2.8-develop-b2school.20250606132301",
155
+ "@edifice.io/config": "2.2.8-develop-b2school.20250606132301"
156
156
  },
157
157
  "peerDependencies": {
158
158
  "@react-spring/web": "^9.7.5",