@edifice.io/react 2.5.17 → 2.5.18-develop-enabling.20260504105750

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.
Files changed (74) hide show
  1. package/dist/components/Card/Card.js +1 -1
  2. package/dist/components/Combobox/Combobox.js +1 -1
  3. package/dist/components/Dropdown/Dropdown.d.ts +7 -3
  4. package/dist/components/Dropdown/Dropdown.js +22 -7
  5. package/dist/components/Dropdown/DropdownCheckboxItem.d.ts +6 -1
  6. package/dist/components/Dropdown/DropdownCheckboxItem.js +11 -6
  7. package/dist/components/Dropdown/DropdownContext.d.ts +5 -0
  8. package/dist/components/Dropdown/DropdownItem.d.ts +6 -1
  9. package/dist/components/Dropdown/DropdownItem.js +10 -5
  10. package/dist/components/Dropdown/DropdownItemHidden.d.ts +12 -0
  11. package/dist/components/Dropdown/DropdownItemHidden.js +19 -0
  12. package/dist/components/Dropdown/DropdownRadioItem.d.ts +6 -1
  13. package/dist/components/Dropdown/DropdownRadioItem.js +11 -6
  14. package/dist/components/Dropdown/DropdownSearchInput.d.ts +20 -0
  15. package/dist/components/Dropdown/DropdownSearchInput.js +25 -0
  16. package/dist/components/Dropdown/useDropdownItemFilter.d.ts +12 -0
  17. package/dist/components/Dropdown/useDropdownItemFilter.js +19 -0
  18. package/dist/components/Form/FormControl.js +1 -1
  19. package/dist/components/Layout/components/WidgetApps.js +1 -1
  20. package/dist/components/Modal/Modal.js +1 -1
  21. package/dist/components/Pagination/Pagination.d.ts +17 -0
  22. package/dist/components/Pagination/Pagination.js +14 -0
  23. package/dist/components/Pagination/index.d.ts +1 -0
  24. package/dist/components/PreventPropagation/PreventPropagation.js +1 -1
  25. package/dist/components/PromotionCard/PromotionCard.js +1 -1
  26. package/dist/components/SearchBar/SearchBar.d.ts +2 -2
  27. package/dist/components/Table/components/Table.js +1 -1
  28. package/dist/components/index.d.ts +1 -0
  29. package/dist/hooks/useConf/useConf.d.ts +1 -1
  30. package/dist/hooks/useDropdown/useDropdown.js +9 -8
  31. package/dist/hooks/useSession/useSession.d.ts +1 -1
  32. package/dist/hooks/useThumbnail/useThumbnail.d.ts +1 -1
  33. package/dist/hooks/useThumbnail/useThumbnail.js +5 -1
  34. package/dist/hooks/useUpload/useUpload.js +2 -5
  35. package/dist/hooks/useWorkspaceFolders/useWorkspaceFolders.d.ts +12 -0
  36. package/dist/hooks/useWorkspaceFolders/useWorkspaceFolders.js +1 -1
  37. package/dist/hooks/useZendeskGuide/useZendeskGuide.js +1 -1
  38. package/dist/icons-apps.js +136 -134
  39. package/dist/index.js +2 -0
  40. package/dist/modules/editor/components/Editor/EditorPreview.js +1 -1
  41. package/dist/modules/icons/components/apps/IconLivretScolaire.d.ts +7 -0
  42. package/dist/modules/icons/components/apps/IconLivretScolaire.js +13 -0
  43. package/dist/modules/icons/components/apps/index.d.ts +1 -0
  44. package/dist/modules/modals/ResourceModal/ResourceModal.d.ts +1 -1
  45. package/dist/modules/modals/ResourceModal/ResourceModal.js +1 -1
  46. package/dist/modules/modals/ResourceModal/hooks/useUpdateMutation.d.ts +1 -1
  47. package/dist/modules/modals/ShareModal/ShareResources.d.ts +4 -53
  48. package/dist/modules/modals/ShareModal/apps/ShareBlog.d.ts +1 -1
  49. package/dist/modules/modals/ShareModal/hooks/useShareBookmark.js +2 -1
  50. package/dist/modules/modals/ShareModal/hooks/useShareMutation.d.ts +1 -1
  51. package/dist/modules/multimedia/ImageEditor/components/ImageEditor.js +24 -10
  52. package/dist/modules/multimedia/ImageEditor/effects/blur.d.ts +7 -5
  53. package/dist/modules/multimedia/ImageEditor/effects/blur.js +26 -18
  54. package/dist/modules/multimedia/ImageEditor/effects/constants.d.ts +2 -0
  55. package/dist/modules/multimedia/ImageEditor/effects/constants.js +4 -0
  56. package/dist/modules/multimedia/ImageEditor/effects/crop.d.ts +4 -5
  57. package/dist/modules/multimedia/ImageEditor/effects/crop.js +42 -26
  58. package/dist/modules/multimedia/ImageEditor/effects/misc.d.ts +10 -16
  59. package/dist/modules/multimedia/ImageEditor/effects/misc.js +27 -12
  60. package/dist/modules/multimedia/ImageEditor/effects/resize.d.ts +3 -7
  61. package/dist/modules/multimedia/ImageEditor/effects/resize.js +31 -22
  62. package/dist/modules/multimedia/ImageEditor/effects/rotate.js +2 -3
  63. package/dist/modules/multimedia/ImageEditor/hooks/useHistoryTool.js +40 -41
  64. package/dist/modules/multimedia/ImageEditor/hooks/useImageEditor.d.ts +1 -1
  65. package/dist/modules/multimedia/ImageEditor/hooks/useImageEditor.js +9 -3
  66. package/dist/modules/multimedia/ImageEditor/hooks/useImageEffects.js +4 -1
  67. package/dist/modules/multimedia/LinkerCard/LinkerCard._.d.ts +1 -1
  68. package/dist/modules/multimedia/MediaLibrary/MediaLibrary.js +1 -0
  69. package/dist/modules/multimedia/UploadCard/UploadCard._.d.ts +1 -1
  70. package/dist/modules/multimedia/UploadFiles/UploadFiles.js +4 -4
  71. package/dist/providers/EdificeClientProvider/EdificeClientProvider.context.d.ts +1 -1
  72. package/dist/utilities/react-query/react-query-utils.d.ts +1 -1
  73. package/package.json +52 -53
  74. package/dist/modules/multimedia/FileCard/FileCard._.d.ts +0 -17
@@ -39,7 +39,7 @@ const Root = /* @__PURE__ */ forwardRef(({
39
39
  /* @__PURE__ */ jsx(Card.Header, {}),
40
40
  typeof children == "function" ? children(appCode) : children
41
41
  ] }) });
42
- }), Card = /* @__PURE__ */ Object.assign(Root, {
42
+ }), Card = Object.assign(Root, {
43
43
  Title: CardTitle,
44
44
  Text: CardText,
45
45
  Image: CardImage,
@@ -53,7 +53,7 @@ const ComboboxComponent = /* @__PURE__ */ forwardRef(({
53
53
  }, value, variant, renderInputGroup, renderSelectedItems, hasDefault: !!options.length, onFocus, onBlur, inputRef }),
54
54
  /* @__PURE__ */ jsx(Dropdown.Menu, { "data-testid": "combobox-search-menu", children: renderContent() })
55
55
  ] });
56
- }), Combobox = /* @__PURE__ */ Object.assign(ComboboxComponent, {
56
+ }), Combobox = Object.assign(ComboboxComponent, {
57
57
  Trigger: ComboboxTrigger
58
58
  });
59
59
  export {
@@ -81,7 +81,7 @@ declare const Dropdown: import('react').ForwardRefExoticComponent<DropdownProps
81
81
  Trigger: import('react').ForwardRefExoticComponent<Omit<import('./DropdownTrigger').DropdownTriggerProps, "ref"> & import('react').RefAttributes<HTMLButtonElement>>;
82
82
  Menu: import('react').ForwardRefExoticComponent<Omit<import('./DropdownMenu').DropdownMenuProps, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
83
83
  Item: {
84
- ({ type, icon, onClick, children, className, minWidth, disabled, ...restProps }: import('./DropdownItem').DropdownItemProps): import("react/jsx-runtime").JSX.Element;
84
+ ({ type, icon, onClick, children, className, minWidth, disabled, searchValue, ...restProps }: import('./DropdownItem').DropdownItemProps): import("react/jsx-runtime").JSX.Element;
85
85
  displayName: string;
86
86
  };
87
87
  Separator: {
@@ -89,13 +89,17 @@ declare const Dropdown: import('react').ForwardRefExoticComponent<DropdownProps
89
89
  displayName: string;
90
90
  };
91
91
  CheckboxItem: {
92
- ({ children, value, model, onChange, }: DropdownCheckboxItem): import("react/jsx-runtime").JSX.Element;
92
+ ({ children, value, model, onChange, searchValue, }: DropdownCheckboxItem): import("react/jsx-runtime").JSX.Element;
93
93
  displayName: string;
94
94
  };
95
95
  RadioItem: {
96
- ({ children, value, model, onChange, }: import('./DropdownRadioItem').DropdownRadioItemProps): import("react/jsx-runtime").JSX.Element;
96
+ ({ children, value, model, onChange, searchValue, }: import('./DropdownRadioItem').DropdownRadioItemProps): import("react/jsx-runtime").JSX.Element;
97
97
  displayName: string;
98
98
  };
99
99
  MenuGroup: import('react').ForwardRefExoticComponent<import('./DropdownMenuGroup').DropdownMenuGroupProps & import('react').RefAttributes<HTMLDivElement>>;
100
+ SearchInput: {
101
+ ({ placeholder, noResultsLabel, onSearch, }: import('./DropdownSearchInput').DropdownSearchInputProps): import("react/jsx-runtime").JSX.Element;
102
+ displayName: string;
103
+ };
100
104
  };
101
105
  export default Dropdown;
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { forwardRef, useImperativeHandle, useMemo, useEffect } from "react";
2
+ import { forwardRef, useState, useRef, useCallback, useImperativeHandle, useMemo, useEffect } from "react";
3
3
  import clsx from "clsx";
4
4
  import useDropdown from "../../hooks/useDropdown/useDropdown.js";
5
5
  import DropdownCheckboxItem from "./DropdownCheckboxItem.js";
@@ -8,6 +8,7 @@ import DropdownItem from "./DropdownItem.js";
8
8
  import DropdownMenu from "./DropdownMenu.js";
9
9
  import DropdownMenuGroup from "./DropdownMenuGroup.js";
10
10
  import DropdownRadioItem from "./DropdownRadioItem.js";
11
+ import DropdownSearchInput from "./DropdownSearchInput.js";
11
12
  import DropdownSeparator from "./DropdownSeparator.js";
12
13
  import DropdownTrigger from "./DropdownTrigger.js";
13
14
  import useClickOutside from "../../hooks/useClickOutside/useClickOutside.js";
@@ -24,7 +25,15 @@ const Root = /* @__PURE__ */ forwardRef(({
24
25
  openOnSpace = !0,
25
26
  focusOnMouseEnter = !0
26
27
  }, refDropdown) => {
27
- const {
28
+ const [searchQuery, setSearchQuery] = useState(""), [hasMatches, setHasMatches] = useState(!0), matchMapRef = useRef(/* @__PURE__ */ new Map()), reportMatch = useCallback((id, isMatch) => {
29
+ matchMapRef.current.set(id, isMatch);
30
+ const next = [...matchMapRef.current.values()].some(Boolean);
31
+ setHasMatches((prev) => prev !== next ? next : prev);
32
+ }, []), unregisterMatch = useCallback((id) => {
33
+ matchMapRef.current.delete(id);
34
+ const next = matchMapRef.current.size === 0 || [...matchMapRef.current.values()].some(Boolean);
35
+ setHasMatches((prev) => prev !== next ? next : prev);
36
+ }, []), {
28
37
  visible,
29
38
  isFocused,
30
39
  triggerProps,
@@ -58,23 +67,29 @@ const Root = /* @__PURE__ */ forwardRef(({
58
67
  block,
59
68
  setVisible,
60
69
  openDropdown,
61
- closeDropdown
62
- }), [visible, isFocused, triggerProps, menuProps, itemProps, itemRefs, block, setVisible, openDropdown, closeDropdown]), dropdown = clsx("dropdown", {
70
+ closeDropdown,
71
+ searchQuery,
72
+ setSearchQuery,
73
+ hasMatches,
74
+ reportMatch,
75
+ unregisterMatch
76
+ }), [visible, isFocused, triggerProps, menuProps, itemProps, itemRefs, block, setVisible, openDropdown, closeDropdown, searchQuery, hasMatches, reportMatch, unregisterMatch]), dropdown = clsx("dropdown", {
63
77
  "w-100": block,
64
78
  "dropdown-nowrap": noWrap,
65
79
  overflow
66
80
  });
67
81
  return useEffect(() => {
68
- onToggle == null || onToggle(visible);
82
+ onToggle == null || onToggle(visible), visible || setSearchQuery("");
69
83
  }, [visible]), /* @__PURE__ */ jsx(DropdownContext.Provider, { value, children: /* @__PURE__ */ jsx("div", { ref, className: dropdown, children: typeof children == "function" ? children(triggerProps, itemRefs, setVisible) : children }) });
70
- }), Dropdown = /* @__PURE__ */ Object.assign(Root, {
84
+ }), Dropdown = Object.assign(Root, {
71
85
  Trigger: DropdownTrigger,
72
86
  Menu: DropdownMenu,
73
87
  Item: DropdownItem,
74
88
  Separator: DropdownSeparator,
75
89
  CheckboxItem: DropdownCheckboxItem,
76
90
  RadioItem: DropdownRadioItem,
77
- MenuGroup: DropdownMenuGroup
91
+ MenuGroup: DropdownMenuGroup,
92
+ SearchInput: DropdownSearchInput
78
93
  });
79
94
  export {
80
95
  Dropdown as default
@@ -16,9 +16,14 @@ interface DropdownCheckboxItem {
16
16
  * OnKeyDown handler
17
17
  */
18
18
  onChange: (value: string | number) => void;
19
+ /**
20
+ * Value used to filter this item when `Dropdown.SearchInput` is present.
21
+ * If provided, the item is hidden when the search query doesn't match.
22
+ */
23
+ searchValue?: string;
19
24
  }
20
25
  declare const DropdownCheckboxItem: {
21
- ({ children, value, model, onChange, }: DropdownCheckboxItem): import("react/jsx-runtime").JSX.Element;
26
+ ({ children, value, model, onChange, searchValue, }: DropdownCheckboxItem): import("react/jsx-runtime").JSX.Element;
22
27
  displayName: string;
23
28
  };
24
29
  export default DropdownCheckboxItem;
@@ -1,33 +1,38 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { useId } from "react";
3
2
  import clsx from "clsx";
4
3
  import { useDropdownContext } from "./DropdownContext.js";
4
+ import { useDropdownItemFilter } from "./useDropdownItemFilter.js";
5
+ import DropdownItemHidden from "./DropdownItemHidden.js";
5
6
  import Checkbox from "../Checkbox/Checkbox.js";
6
7
  const DropdownCheckboxItem = ({
7
8
  children,
8
9
  value,
9
10
  model,
10
- onChange
11
+ onChange,
12
+ searchValue
11
13
  }) => {
12
14
  const {
13
15
  itemProps,
14
16
  itemRefs,
15
17
  isFocused
16
18
  } = useDropdownContext(), {
19
+ id,
20
+ isFiltered
21
+ } = useDropdownItemFilter(searchValue), {
17
22
  onMenuItemKeyDown,
18
23
  onMenuItemMouseEnter
19
- } = itemProps, id = useId(), checked = model.includes(value), checkboxProps = {
24
+ } = itemProps, checked = model.includes(value), checkboxProps = {
20
25
  value,
21
26
  model,
22
27
  checked,
23
28
  readOnly: !0
24
29
  }, dropdownCheckboxItem = clsx("dropdown-item c-pointer", {
25
30
  focus: isFocused === id
26
- });
27
- return /* @__PURE__ */ jsx("div", { id, ref: (el) => itemRefs.current[id] = el, role: "menuitemcheckbox", "aria-checked": checked, onMouseUp: () => onChange(value), onKeyDown: (event) => onMenuItemKeyDown(event, () => onChange(value)), onMouseEnter: onMenuItemMouseEnter, tabIndex: checked ? 0 : -1, className: dropdownCheckboxItem, children: /* @__PURE__ */ jsxs("div", { className: "d-flex gap-8 align-items-center justify-content-between position-relative", children: [
31
+ }), content = /* @__PURE__ */ jsxs("div", { className: "d-flex gap-8 align-items-center justify-content-between position-relative", children: [
28
32
  children,
29
33
  /* @__PURE__ */ jsx(Checkbox, { ...checkboxProps })
30
- ] }) });
34
+ ] });
35
+ return isFiltered ? /* @__PURE__ */ jsx(DropdownItemHidden, { collapse: !0, children: content }) : /* @__PURE__ */ jsx("div", { id, ref: (el) => itemRefs.current[id] = el, role: "menuitemcheckbox", "aria-checked": checked, onMouseUp: () => onChange(value), onKeyDown: (event) => onMenuItemKeyDown(event, () => onChange(value)), onMouseEnter: onMenuItemMouseEnter, tabIndex: checked ? 0 : -1, className: dropdownCheckboxItem, children: content });
31
36
  };
32
37
  export {
33
38
  DropdownCheckboxItem as default
@@ -2,6 +2,11 @@ import { UseDropdownProps } from '../../hooks/useDropdown/useDropdown';
2
2
  type OmittedProps = Omit<UseDropdownProps, 'triggerRef' | 'menuRef'>;
3
3
  export interface DropdownContextProps extends OmittedProps {
4
4
  block?: boolean;
5
+ searchQuery: string;
6
+ setSearchQuery: (query: string) => void;
7
+ hasMatches: boolean;
8
+ reportMatch: (id: string, isMatch: boolean) => void;
9
+ unregisterMatch: (id: string) => void;
5
10
  }
6
11
  export declare const DropdownContext: import('react').Context<DropdownContextProps | null>;
7
12
  export declare const useDropdownContext: () => DropdownContextProps;
@@ -29,9 +29,14 @@ export interface DropdownItemProps {
29
29
  * Disabled status
30
30
  */
31
31
  disabled?: boolean;
32
+ /**
33
+ * Value used to filter this item when `Dropdown.SearchInput` is present.
34
+ * If provided, the item is hidden when the search query doesn't match.
35
+ */
36
+ searchValue?: string;
32
37
  }
33
38
  declare const DropdownItem: {
34
- ({ type, icon, onClick, children, className, minWidth, disabled, ...restProps }: DropdownItemProps): import("react/jsx-runtime").JSX.Element;
39
+ ({ type, icon, onClick, children, className, minWidth, disabled, searchValue, ...restProps }: DropdownItemProps): import("react/jsx-runtime").JSX.Element;
35
40
  displayName: string;
36
41
  };
37
42
  export default DropdownItem;
@@ -1,7 +1,8 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { useId } from "react";
3
2
  import clsx from "clsx";
4
3
  import { useDropdownContext } from "./DropdownContext.js";
4
+ import { useDropdownItemFilter } from "./useDropdownItemFilter.js";
5
+ import DropdownItemHidden from "./DropdownItemHidden.js";
5
6
  const DropdownItem = ({
6
7
  type = "action",
7
8
  icon,
@@ -10,6 +11,7 @@ const DropdownItem = ({
10
11
  className,
11
12
  minWidth,
12
13
  disabled,
14
+ searchValue,
13
15
  ...restProps
14
16
  }) => {
15
17
  const {
@@ -17,12 +19,15 @@ const DropdownItem = ({
17
19
  itemRefs,
18
20
  isFocused
19
21
  } = useDropdownContext(), {
22
+ id,
23
+ isFiltered
24
+ } = useDropdownItemFilter(searchValue), {
20
25
  onMenuItemKeyDown,
21
26
  onMenuItemMouseEnter,
22
27
  onMenuItemClick
23
28
  } = itemProps, handleOnClick = (event) => {
24
29
  disabled || (onClick == null || onClick(event), type === "action" && (onMenuItemClick(), event.stopPropagation()));
25
- }, id = useId(), dropdownItem = clsx("dropdown-item", {
30
+ }, dropdownItem = clsx("dropdown-item", {
26
31
  focus: isFocused === id
27
32
  }, {
28
33
  "text-gray-600": disabled
@@ -30,11 +35,11 @@ const DropdownItem = ({
30
35
  ...minWidth && {
31
36
  minWidth: `${minWidth}px`
32
37
  }
33
- };
34
- return /* @__PURE__ */ jsx("div", { id, role: "menuitem", style, ref: (el) => itemRefs.current[id] = el, tabIndex: isFocused === id ? 0 : -1, className: dropdownItem, "aria-current": isFocused === id, onClick: handleOnClick, onMouseEnter: onMenuItemMouseEnter, onKeyDown: (event) => onMenuItemKeyDown(event, onClick), ...restProps, children: /* @__PURE__ */ jsxs("div", { className: "d-flex gap-8 align-items-center", children: [
38
+ }, content = /* @__PURE__ */ jsxs("div", { className: "d-flex gap-8 align-items-center", children: [
35
39
  icon,
36
40
  children
37
- ] }) });
41
+ ] });
42
+ return isFiltered ? /* @__PURE__ */ jsx(DropdownItemHidden, { children: content }) : /* @__PURE__ */ jsx("div", { id, role: "menuitem", style, ref: (el) => itemRefs.current[id] = el, tabIndex: isFocused === id ? 0 : -1, className: dropdownItem, "aria-current": isFocused === id, onClick: handleOnClick, onMouseEnter: onMenuItemMouseEnter, onKeyDown: (event) => onMenuItemKeyDown(event, onClick), ...restProps, children: content });
38
43
  };
39
44
  export {
40
45
  DropdownItem as default
@@ -0,0 +1,12 @@
1
+ import { ReactNode } from 'react';
2
+ interface DropdownItemHiddenProps {
3
+ children: ReactNode;
4
+ /**
5
+ * When true, collapses height to 0 while keeping the item in the flow.
6
+ * Use this when the container width must stay stable during search filtering.
7
+ * Defaults to false (display: none).
8
+ */
9
+ collapse?: boolean;
10
+ }
11
+ declare const DropdownItemHidden: ({ children, collapse, }: DropdownItemHiddenProps) => import("react/jsx-runtime").JSX.Element;
12
+ export default DropdownItemHidden;
@@ -0,0 +1,19 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ const DropdownItemHidden = ({
3
+ children,
4
+ collapse
5
+ }) => /* @__PURE__ */ jsx("div", { "aria-hidden": "true", style: collapse ? {
6
+ height: 0,
7
+ overflow: "hidden",
8
+ margin: 0,
9
+ pointerEvents: "none",
10
+ width: "100%",
11
+ maxWidth: "max-content"
12
+ } : {
13
+ display: "none",
14
+ width: "100%",
15
+ maxWidth: "max-content"
16
+ }, children });
17
+ export {
18
+ DropdownItemHidden as default
19
+ };
@@ -16,9 +16,14 @@ export interface DropdownRadioItemProps {
16
16
  * onKeyDown, onMouseUp handlers
17
17
  */
18
18
  onChange: (value: string) => void;
19
+ /**
20
+ * Value used to filter this item when `Dropdown.SearchInput` is present.
21
+ * If provided, the item is hidden when the search query doesn't match.
22
+ */
23
+ searchValue?: string;
19
24
  }
20
25
  declare const DropdownRadioItem: {
21
- ({ children, value, model, onChange, }: DropdownRadioItemProps): import("react/jsx-runtime").JSX.Element;
26
+ ({ children, value, model, onChange, searchValue, }: DropdownRadioItemProps): import("react/jsx-runtime").JSX.Element;
22
27
  displayName: string;
23
28
  };
24
29
  export default DropdownRadioItem;
@@ -1,33 +1,38 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { useId } from "react";
3
2
  import clsx from "clsx";
4
3
  import { useDropdownContext } from "./DropdownContext.js";
4
+ import { useDropdownItemFilter } from "./useDropdownItemFilter.js";
5
+ import DropdownItemHidden from "./DropdownItemHidden.js";
5
6
  import Radio from "../Radio/Radio.js";
6
7
  const DropdownRadioItem = ({
7
8
  children,
8
9
  value,
9
10
  model,
10
- onChange
11
+ onChange,
12
+ searchValue
11
13
  }) => {
12
14
  const {
13
15
  itemProps,
14
16
  itemRefs,
15
17
  isFocused
16
18
  } = useDropdownContext(), {
19
+ id,
20
+ isFiltered
21
+ } = useDropdownItemFilter(searchValue), {
17
22
  onMenuItemKeyDown,
18
23
  onMenuItemMouseEnter
19
- } = itemProps, id = useId(), radioProps = {
24
+ } = itemProps, radioProps = {
20
25
  value,
21
26
  model,
22
27
  checked: value === model,
23
28
  readOnly: !0
24
29
  }, dropdownRadioItem = clsx("dropdown-item c-pointer", {
25
30
  focus: isFocused === id
26
- });
27
- return /* @__PURE__ */ jsx("div", { id, ref: (el) => itemRefs.current[id] = el, role: "menuitemradio", "aria-checked": value === model, onMouseUp: () => onChange(value), onKeyDown: (event) => onMenuItemKeyDown(event, () => onChange(value)), onMouseEnter: onMenuItemMouseEnter, tabIndex: value === model ? 0 : -1, className: dropdownRadioItem, children: /* @__PURE__ */ jsxs("div", { className: "d-flex gap-8 align-items-center justify-content-between position-relative", children: [
31
+ }), content = /* @__PURE__ */ jsxs("div", { className: "d-flex gap-8 align-items-center justify-content-between position-relative", children: [
28
32
  children,
29
33
  /* @__PURE__ */ jsx(Radio, { ...radioProps, className: "position-absolute start-0 end-0 top-0 bottom-0 opacity-0" })
30
- ] }) });
34
+ ] });
35
+ return isFiltered ? /* @__PURE__ */ jsx(DropdownItemHidden, { children: content }) : /* @__PURE__ */ jsx("div", { id, ref: (el) => itemRefs.current[id] = el, role: "menuitemradio", "aria-checked": value === model, onMouseUp: () => onChange(value), onKeyDown: (event) => onMenuItemKeyDown(event, () => onChange(value)), onMouseEnter: onMenuItemMouseEnter, tabIndex: value === model ? 0 : -1, className: dropdownRadioItem, children: content });
31
36
  };
32
37
  export {
33
38
  DropdownRadioItem as default
@@ -0,0 +1,20 @@
1
+ export interface DropdownSearchInputProps {
2
+ /**
3
+ * Placeholder text for the search input
4
+ */
5
+ placeholder?: string;
6
+ /**
7
+ * Label shown when no items match the search query
8
+ */
9
+ noResultsLabel?: string;
10
+ /**
11
+ * Called whenever the search query changes.
12
+ * Useful to track the current query outside the Dropdown context.
13
+ */
14
+ onSearch?: (query: string) => void;
15
+ }
16
+ declare const DropdownSearchInput: {
17
+ ({ placeholder, noResultsLabel, onSearch, }: DropdownSearchInputProps): import("react/jsx-runtime").JSX.Element;
18
+ displayName: string;
19
+ };
20
+ export default DropdownSearchInput;
@@ -0,0 +1,25 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useDropdownContext } from "./DropdownContext.js";
3
+ import SearchBar from "../SearchBar/SearchBar.js";
4
+ const DropdownSearchInput = ({
5
+ placeholder = "Rechercher...",
6
+ noResultsLabel = "Pas de résultat",
7
+ onSearch
8
+ }) => {
9
+ const {
10
+ searchQuery,
11
+ setSearchQuery,
12
+ hasMatches
13
+ } = useDropdownContext();
14
+ return /* @__PURE__ */ jsxs("div", { className: "px-8 pb-8", children: [
15
+ /* @__PURE__ */ jsx(SearchBar, { isVariant: !0, clearable: !0, size: "md", placeholder, value: searchQuery, onChange: (e) => {
16
+ setSearchQuery(e.target.value), onSearch == null || onSearch(e.target.value);
17
+ }, onKeyDown: (e) => {
18
+ ["ArrowUp", "ArrowDown", "Enter", " "].includes(e.key) && e.stopPropagation();
19
+ } }),
20
+ searchQuery && !hasMatches && /* @__PURE__ */ jsx("p", { className: "body-2 text-gray-700 text-center mt-8 mb-0", children: noResultsLabel })
21
+ ] });
22
+ };
23
+ export {
24
+ DropdownSearchInput as default
25
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Shared filtering logic for Dropdown item components.
3
+ * Computes whether the item is hidden by the current search query,
4
+ * and keeps the match registry in sync via reportMatch/unregisterMatch.
5
+ *
6
+ * @returns `id` – stable element id to spread on the DOM node and itemRefs
7
+ * @returns `isFiltered` – true when the item should be hidden
8
+ */
9
+ export declare const useDropdownItemFilter: (searchValue: string | undefined) => {
10
+ id: string;
11
+ isFiltered: boolean;
12
+ };
@@ -0,0 +1,19 @@
1
+ import { useId, useLayoutEffect } from "react";
2
+ import { useDropdownContext } from "./DropdownContext.js";
3
+ const useDropdownItemFilter = (searchValue) => {
4
+ const {
5
+ searchQuery,
6
+ reportMatch,
7
+ unregisterMatch
8
+ } = useDropdownContext(), id = useId(), isFiltered = searchValue !== void 0 && searchQuery !== "" && !searchValue.toLowerCase().includes(searchQuery.toLowerCase());
9
+ return useLayoutEffect(() => {
10
+ if (searchValue !== void 0)
11
+ return reportMatch(id, !isFiltered), () => unregisterMatch(id);
12
+ }, [id, isFiltered, searchValue, reportMatch, unregisterMatch]), {
13
+ id,
14
+ isFiltered
15
+ };
16
+ };
17
+ export {
18
+ useDropdownItemFilter
19
+ };
@@ -22,7 +22,7 @@ const Root = /* @__PURE__ */ forwardRef(({
22
22
  status
23
23
  }), [id, isOptional, isReadOnly, isRequired, status]);
24
24
  return /* @__PURE__ */ jsx(Context.Provider, { value: values, children: /* @__PURE__ */ jsx("div", { ref, className, ...restProps, children }) });
25
- }), FormControl = /* @__PURE__ */ Object.assign(Root, {
25
+ }), FormControl = Object.assign(Root, {
26
26
  Label,
27
27
  Input,
28
28
  Text: FormText
@@ -14,7 +14,7 @@ const WidgetAppsFooter = () => {
14
14
  } = useTranslation(), getAppName = (data) => data.prefix && data.prefix.length > 1 ? t(data.prefix.substring(1)) : t(data.displayName) || "";
15
15
  return /* @__PURE__ */ jsxs("div", { className: "widget-body d-flex flex-wrap", children: [
16
16
  !bookmarkedApps.length && /* @__PURE__ */ jsx("div", { className: "text-dark", children: t("navbar.myapps.more") }),
17
- bookmarkedApps.slice(0, 6).map((app, index) => /* @__PURE__ */ jsx("a", { href: app.address, title: getAppName(app), className: "bookmarked-app", target: appToOpenOnBlank.includes(app.name) || app.isExternal || app.category === "connector" ? "_blank" : void 0, rel: appToOpenOnBlank.includes(app.name) || app.isExternal || app.category === "connector" ? "noopener noreferrer" : void 0, children: /* @__PURE__ */ jsx(AppIcon, { app, size: "32" }) }, index))
17
+ bookmarkedApps.slice(0, 6).map((app, index) => /* @__PURE__ */ jsx("a", { href: app.address, title: getAppName(app), className: "bookmarked-app", target: appToOpenOnBlank.includes(app.name) || app.isExternal || app.target === "_blank" ? "_blank" : void 0, rel: appToOpenOnBlank.includes(app.name) || app.isExternal || app.target === "_blank" ? "noopener noreferrer" : void 0, children: /* @__PURE__ */ jsx(AppIcon, { app, size: "32" }) }, index))
18
18
  ] });
19
19
  };
20
20
  export {
@@ -62,7 +62,7 @@ const Root = /* @__PURE__ */ forwardRef(({
62
62
  opacity: 0.65
63
63
  } })
64
64
  ] })) });
65
- }), Modal = /* @__PURE__ */ Object.assign(Root, {
65
+ }), Modal = Object.assign(Root, {
66
66
  Header: ModalHeader,
67
67
  Subtitle: ModalSubtitle,
68
68
  Body: ModalBody,
@@ -0,0 +1,17 @@
1
+ export interface PaginationProps {
2
+ /** Current page (1-based) */
3
+ current: number;
4
+ /** Total number of items */
5
+ total: number;
6
+ /** Number of items per page */
7
+ pageSize: number;
8
+ /** Called when the page changes */
9
+ onChange: (page: number) => void;
10
+ /** Optional class for styling purpose */
11
+ className?: string;
12
+ }
13
+ /**
14
+ * Pagination component for navigating through pages of results.
15
+ * Wraps antd Pagination with a simplified, stable API.
16
+ */
17
+ export declare function Pagination({ current, total, pageSize, onChange, className, }: PaginationProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Pagination as Pagination$1 } from "antd";
3
+ function Pagination({
4
+ current,
5
+ total,
6
+ pageSize,
7
+ onChange,
8
+ className
9
+ }) {
10
+ return /* @__PURE__ */ jsx(Pagination$1, { align: "center", showSizeChanger: !1, current, total, pageSize, onChange, className });
11
+ }
12
+ export {
13
+ Pagination
14
+ };
@@ -0,0 +1 @@
1
+ export * from './Pagination';
@@ -3,7 +3,7 @@ const Root = ({
3
3
  children
4
4
  }) => /* @__PURE__ */ jsx("div", { onClick: (e) => {
5
5
  e.stopPropagation();
6
- }, children }), PreventPropagation = /* @__PURE__ */ Object.assign(Root, {});
6
+ }, children }), PreventPropagation = Object.assign(Root, {});
7
7
  export {
8
8
  PreventPropagation as default
9
9
  };
@@ -17,7 +17,7 @@ const Root = ({
17
17
  borderColor,
18
18
  backgroundColor
19
19
  }, children });
20
- }, PromotionCard = /* @__PURE__ */ Object.assign(Root, {
20
+ }, PromotionCard = Object.assign(Root, {
21
21
  Header: PromotionCardHeader,
22
22
  Body: PromotionCardBody,
23
23
  Icon: PromotionCardIcon,
@@ -3,7 +3,7 @@ import { Size } from '../../types';
3
3
  /**
4
4
  * Base props shared by both SearchBar variants
5
5
  */
6
- export interface BaseProps extends Omit<React.ComponentPropsWithoutRef<'input'>, 'size'> {
6
+ interface BaseProps extends Omit<React.ComponentPropsWithoutRef<'input'>, 'size'> {
7
7
  /**
8
8
  * String or template literal key for i18next translation
9
9
  */
@@ -67,7 +67,7 @@ type DynamicSearchBar = {
67
67
  /**
68
68
  * Props for the SearchBar component
69
69
  */
70
- export type Props = DefaultSearchBar | DynamicSearchBar;
70
+ type Props = DefaultSearchBar | DynamicSearchBar;
71
71
  export type SearchBarProps = BaseProps & Props;
72
72
  /**
73
73
  * SearchBar component to handle dynamic or static search input
@@ -13,7 +13,7 @@ const Root = /* @__PURE__ */ forwardRef(({
13
13
  overflowY: "auto"
14
14
  } : {}, children: /* @__PURE__ */ jsx("table", { ref, className: "table align-middle mb-0", style: {
15
15
  overflow: maxHeight ? "visible" : "hidden"
16
- }, children }) })), Table = /* @__PURE__ */ Object.assign(Root, {
16
+ }, children }) })), Table = Object.assign(Root, {
17
17
  Thead: TableThead,
18
18
  Th: TableTh,
19
19
  Tbody: TableTbody,
@@ -33,6 +33,7 @@ export * from './Logo';
33
33
  export * from './MediaViewer';
34
34
  export * from './Menu';
35
35
  export * from './Modal';
36
+ export * from './Pagination';
36
37
  export * from './Popover';
37
38
  export * from './PreventPropagation';
38
39
  export * from './PromotionCard';
@@ -1,4 +1,4 @@
1
1
  import { App, IGetConf } from '@edifice.io/client';
2
2
  export default function useConf({ appCode }: {
3
3
  appCode: App;
4
- }): import('../../../node_modules/@tanstack/react-query').UseQueryResult<IGetConf, Error>;
4
+ }): import('@tanstack/react-query').UseQueryResult<IGetConf, Error>;
@@ -47,17 +47,16 @@ const useDropdown = (placement, extraTriggerKeyDownHandler, isTriggerHovered = !
47
47
  }
48
48
  }
49
49
  }, [activeIndex]);
50
- const nextItem = () => {
51
- const itemCount = Object.values(itemRefs.current).length;
52
- setActiveIndex((prevIndex) => (prevIndex + 1) % itemCount);
50
+ const visibleItemCount = () => Object.values(itemRefs.current).filter(Boolean).length, nextItem = () => {
51
+ const count = visibleItemCount();
52
+ setActiveIndex((prevIndex) => (prevIndex + 1) % count);
53
53
  }, previousItem = () => {
54
- const itemCount = Object.values(itemRefs.current).length;
55
- setActiveIndex((prevIndex) => (prevIndex - 1 + itemCount) % itemCount);
54
+ const count = visibleItemCount();
55
+ setActiveIndex((prevIndex) => (prevIndex - 1 + count) % count);
56
56
  }, firstItem = () => {
57
57
  setActiveIndex(0);
58
58
  }, lastItem = () => {
59
- const itemCount = Object.values(itemRefs.current).length;
60
- setActiveIndex(itemCount - 1);
59
+ setActiveIndex(visibleItemCount() - 1);
61
60
  }, openDropdown = useCallback(() => {
62
61
  setVisible(!0);
63
62
  }, []), closeDropdown = useCallback(() => {
@@ -73,6 +72,8 @@ const useDropdown = (placement, extraTriggerKeyDownHandler, isTriggerHovered = !
73
72
  case "Space":
74
73
  if (!openOnSpace)
75
74
  break;
75
+ openDropdown(), flag = !0;
76
+ break;
76
77
  case "Enter":
77
78
  case "ArrowDown":
78
79
  case "Down":
@@ -90,7 +91,7 @@ const useDropdown = (placement, extraTriggerKeyDownHandler, isTriggerHovered = !
90
91
  extraTriggerKeyDownHandler == null || extraTriggerKeyDownHandler(event), stopEvents(flag, event);
91
92
  }, [closeDropdown, openDropdown]), onMenuItemMouseEnter = (event) => {
92
93
  if (focusOnMouseEnter) {
93
- const index = Object.values(itemRefs.current).findIndex((item) => item.id === event.currentTarget.getAttribute("id"));
94
+ const index = Object.values(itemRefs.current).filter((item) => !!item).findIndex((item) => item.id === event.currentTarget.getAttribute("id"));
94
95
  setActiveIndex(index);
95
96
  }
96
97
  }, onMenuItemKeyDown = useCallback((event, onSuccess) => {
@@ -1,2 +1,2 @@
1
1
  import { IGetSession } from '@edifice.io/client';
2
- export default function useSession(): import('../../../node_modules/@tanstack/react-query').UseQueryResult<IGetSession, Error>;
2
+ export default function useSession(): import('@tanstack/react-query').UseQueryResult<IGetSession, Error>;
@@ -10,5 +10,5 @@ type LazyLoadOptions = {
10
10
  * with respect to the [`intersectionOptions`](https://github.com/thebuilder/react-intersection-observer/tree/dceba7f52aebea4d62d539bc55a1db129226bb6c?tab=readme-ov-file#options)
11
11
  * @return `true` if `src` is available, or false otherwise, or `null` while not tested.
12
12
  */
13
- export default function useThumbnail(src: string, options?: LazyLoadOptions): boolean | null;
13
+ export default function useThumbnail(src: string | null | undefined, options?: LazyLoadOptions): boolean | null;
14
14
  export {};