@choice-ui/react 1.7.8 → 1.8.1

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,5 +1,9 @@
1
1
  interface EmojiEmptyProps {
2
2
  variant?: "default" | "dark" | "light";
3
+ i18n?: {
4
+ title?: string;
5
+ description?: string;
6
+ };
3
7
  }
4
8
  export declare const EmojiEmpty: import('react').NamedExoticComponent<EmojiEmptyProps>;
5
9
  export {};
@@ -1,11 +1,17 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { memo } from "react";
3
3
  import { emojiEmptyTv } from "../tv.js";
4
- const EmojiEmpty = memo(function EmojiEmpty2({ variant = "dark" }) {
4
+ const EmojiEmpty = memo(function EmojiEmpty2({
5
+ variant = "dark",
6
+ i18n = {
7
+ title: "No emoji found",
8
+ description: "You can search for an emoji by name or use the search bar to find it."
9
+ }
10
+ }) {
5
11
  const tv = emojiEmptyTv({ variant });
6
12
  return /* @__PURE__ */ jsxs("div", { className: tv.container(), children: [
7
- /* @__PURE__ */ jsx("div", { className: tv.title(), children: "No emoji found" }),
8
- /* @__PURE__ */ jsx("p", { className: tv.description(), children: "You can search for an emoji by name or use the search bar to find it." })
13
+ /* @__PURE__ */ jsx("div", { className: tv.title(), children: i18n.title }),
14
+ /* @__PURE__ */ jsx("p", { className: tv.description(), children: i18n.description })
9
15
  ] });
10
16
  });
11
17
  export {
@@ -3,6 +3,9 @@ interface EmojiFooterProps {
3
3
  hoveredEmoji: EmojiData | null;
4
4
  selectedEmoji: EmojiData | null;
5
5
  variant?: "default" | "dark" | "light";
6
+ i18n?: {
7
+ pickAnEmoji?: string;
8
+ };
6
9
  }
7
- export declare function EmojiFooter({ hoveredEmoji, selectedEmoji, variant }: EmojiFooterProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare const EmojiFooter: import('react').NamedExoticComponent<EmojiFooterProps>;
8
11
  export {};
@@ -1,12 +1,20 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
+ import { memo } from "react";
2
3
  import { emojiFooterTv } from "../tv.js";
3
- function EmojiFooter({ hoveredEmoji, selectedEmoji, variant = "dark" }) {
4
+ const EmojiFooter = memo(function EmojiFooter2({
5
+ hoveredEmoji,
6
+ selectedEmoji,
7
+ variant = "dark",
8
+ i18n = {
9
+ pickAnEmoji: "Pick an emoji..."
10
+ }
11
+ }) {
4
12
  var _a, _b;
5
13
  const tv = emojiFooterTv({ variant });
6
14
  return /* @__PURE__ */ jsxs("div", { className: tv.footer(), children: [
7
15
  /* @__PURE__ */ jsx("div", { className: tv.emojiPreview(), children: ((_a = hoveredEmoji || selectedEmoji) == null ? void 0 : _a.emoji) || /* @__PURE__ */ jsx("div", { className: tv.emojiPreviewEmpty() }) }),
8
16
  /* @__PURE__ */ jsxs("div", { className: tv.emojiInfo(), children: [
9
- /* @__PURE__ */ jsx("div", { className: tv.emojiName(), children: (hoveredEmoji == null ? void 0 : hoveredEmoji.name) || (selectedEmoji == null ? void 0 : selectedEmoji.name) || "Pick an emoji..." }),
17
+ /* @__PURE__ */ jsx("div", { className: tv.emojiName(), children: (hoveredEmoji == null ? void 0 : hoveredEmoji.name) || (selectedEmoji == null ? void 0 : selectedEmoji.name) || i18n.pickAnEmoji }),
10
18
  hoveredEmoji || selectedEmoji ? /* @__PURE__ */ jsxs("div", { className: tv.emojiCode(), children: [
11
19
  ":",
12
20
  (_b = hoveredEmoji || selectedEmoji) == null ? void 0 : _b.nameUrl,
@@ -14,7 +22,7 @@ function EmojiFooter({ hoveredEmoji, selectedEmoji, variant = "dark" }) {
14
22
  ] }) : /* @__PURE__ */ jsx(Fragment, {})
15
23
  ] })
16
24
  ] });
17
- }
25
+ });
18
26
  export {
19
27
  EmojiFooter
20
28
  };
@@ -13,6 +13,22 @@ export interface EmojiPickerProps {
13
13
  showFooter?: boolean;
14
14
  value?: EmojiData | null;
15
15
  variant?: "default" | "dark" | "light";
16
+ i18n?: {
17
+ noEmojisFoundTitle?: string;
18
+ noEmojisFoundDescription?: string;
19
+ footerPickAnEmoji?: string;
20
+ categories?: {
21
+ frequentlyUsed: string;
22
+ smileysPeople: string;
23
+ animalsNature: string;
24
+ foodDrink: string;
25
+ travelPlaces: string;
26
+ activities: string;
27
+ objects: string;
28
+ symbols: string;
29
+ flags: string;
30
+ };
31
+ };
16
32
  }
17
33
  export declare const EmojiPicker: React.NamedExoticComponent<EmojiPickerProps>;
18
34
  export default EmojiPicker;
@@ -12,17 +12,6 @@ import { EmojiCategoryHeader } from "./components/emoji-category-header.js";
12
12
  import { EmojiItem } from "./components/emoji-item.js";
13
13
  import { EmojiEmpty } from "./components/emoji-empty.js";
14
14
  import { EmojiFooter } from "./components/emoji-footer.js";
15
- const categoriesWithIcons = [
16
- { id: "frequently_used", name: "Frequently used", icon: /* @__PURE__ */ jsx(EmojiFrequentlyUsed, {}) },
17
- { id: "smileys_people", name: "Smileys & People", icon: /* @__PURE__ */ jsx(EmojiSmileysPeople, {}) },
18
- { id: "animals_nature", name: "Animals & Nature", icon: /* @__PURE__ */ jsx(EmojiAnimalsNature, {}) },
19
- { id: "food_drink", name: "Food & Drink", icon: /* @__PURE__ */ jsx(EmojiFoodDrink, {}) },
20
- { id: "travel_places", name: "Travel & Places", icon: /* @__PURE__ */ jsx(EmojiTravelPlaces, {}) },
21
- { id: "activities", name: "Activities", icon: /* @__PURE__ */ jsx(EmojiActivity, {}) },
22
- { id: "objects", name: "Objects", icon: /* @__PURE__ */ jsx(EmojiObjects, {}) },
23
- { id: "symbols", name: "Symbols", icon: /* @__PURE__ */ jsx(EmojiSymbols, {}) },
24
- { id: "flags", name: "Flags", icon: /* @__PURE__ */ jsx(EmojiFlags, {}) }
25
- ];
26
15
  const EmojiPicker = memo(function EmojiPicker2({
27
16
  value,
28
17
  onChange,
@@ -35,11 +24,49 @@ const EmojiPicker = memo(function EmojiPicker2({
35
24
  showSearch = true,
36
25
  showFooter = true,
37
26
  children,
38
- variant = "dark"
27
+ variant = "dark",
28
+ i18n = {
29
+ noEmojisFoundTitle: "No emoji found",
30
+ noEmojisFoundDescription: "You can search for an emoji by name or use the search bar to find it.",
31
+ footerPickAnEmoji: "Pick an emoji...",
32
+ categories: {
33
+ frequentlyUsed: "Frequently used",
34
+ smileysPeople: "Smileys & People",
35
+ animalsNature: "Animals & Nature",
36
+ foodDrink: "Food & Drink",
37
+ travelPlaces: "Travel & Places",
38
+ activities: "Activities",
39
+ objects: "Objects",
40
+ symbols: "Symbols",
41
+ flags: "Flags"
42
+ }
43
+ }
39
44
  }) {
40
45
  const [searchQuery, setSearchQuery] = useState("");
41
46
  const [hoveredEmoji, setHoveredEmoji] = useState(null);
47
+ const safeColumns = Math.max(1, columns);
42
48
  const tv = emojiTv({ variant });
49
+ const categoriesWithIcons = useMemo(
50
+ () => {
51
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
52
+ return [
53
+ {
54
+ id: "frequently_used",
55
+ name: (_a = i18n.categories) == null ? void 0 : _a.frequentlyUsed,
56
+ icon: /* @__PURE__ */ jsx(EmojiFrequentlyUsed, {})
57
+ },
58
+ { id: "smileys_people", name: (_b = i18n.categories) == null ? void 0 : _b.smileysPeople, icon: /* @__PURE__ */ jsx(EmojiSmileysPeople, {}) },
59
+ { id: "animals_nature", name: (_c = i18n.categories) == null ? void 0 : _c.animalsNature, icon: /* @__PURE__ */ jsx(EmojiAnimalsNature, {}) },
60
+ { id: "food_drink", name: (_d = i18n.categories) == null ? void 0 : _d.foodDrink, icon: /* @__PURE__ */ jsx(EmojiFoodDrink, {}) },
61
+ { id: "travel_places", name: (_e = i18n.categories) == null ? void 0 : _e.travelPlaces, icon: /* @__PURE__ */ jsx(EmojiTravelPlaces, {}) },
62
+ { id: "activities", name: (_f = i18n.categories) == null ? void 0 : _f.activities, icon: /* @__PURE__ */ jsx(EmojiActivity, {}) },
63
+ { id: "objects", name: (_g = i18n.categories) == null ? void 0 : _g.objects, icon: /* @__PURE__ */ jsx(EmojiObjects, {}) },
64
+ { id: "symbols", name: (_h = i18n.categories) == null ? void 0 : _h.symbols, icon: /* @__PURE__ */ jsx(EmojiSymbols, {}) },
65
+ { id: "flags", name: (_i = i18n.categories) == null ? void 0 : _i.flags, icon: /* @__PURE__ */ jsx(EmojiFlags, {}) }
66
+ ];
67
+ },
68
+ [i18n.categories]
69
+ );
43
70
  const {
44
71
  categorizedData,
45
72
  categoryIndexMap,
@@ -48,8 +75,9 @@ const EmojiPicker = memo(function EmojiPicker2({
48
75
  findEmojiByChar
49
76
  } = useEmojiData({
50
77
  searchQuery,
51
- columns,
52
- showFrequentlyUsed
78
+ columns: safeColumns,
79
+ showFrequentlyUsed,
80
+ categoryNames: i18n.categories
53
81
  });
54
82
  const {
55
83
  scrollRef,
@@ -65,7 +93,7 @@ const EmojiPicker = memo(function EmojiPicker2({
65
93
  findEmojiPosition,
66
94
  searchQuery,
67
95
  value,
68
- columns
96
+ columns: safeColumns
69
97
  });
70
98
  const availableCategories = useMemo(() => {
71
99
  return categoriesWithIcons.filter((category) => {
@@ -74,7 +102,7 @@ const EmojiPicker = memo(function EmojiPicker2({
74
102
  }
75
103
  return true;
76
104
  });
77
- }, [showFrequentlyUsed]);
105
+ }, [categoriesWithIcons, showFrequentlyUsed]);
78
106
  const handleEmojiSelect = useEventCallback((emoji) => {
79
107
  markInternalUpdate();
80
108
  addToFrequentlyUsed(emoji.id);
@@ -90,7 +118,7 @@ const EmojiPicker = memo(function EmojiPicker2({
90
118
  const rootStyle = {
91
119
  "--emoji-height": `${height}px`,
92
120
  "--emoji-padding": `${PADDING}px`,
93
- "--emoji-columns": `${columns}`
121
+ "--emoji-columns": `${safeColumns}`
94
122
  };
95
123
  return /* @__PURE__ */ jsxs(
96
124
  "div",
@@ -193,7 +221,16 @@ const EmojiPicker = memo(function EmojiPicker2({
193
221
  },
194
222
  virtualItem.key
195
223
  );
196
- }) : /* @__PURE__ */ jsx(EmojiEmpty, { variant })
224
+ }) : /* @__PURE__ */ jsx(
225
+ EmojiEmpty,
226
+ {
227
+ variant,
228
+ i18n: {
229
+ title: i18n.noEmojisFoundTitle,
230
+ description: i18n.noEmojisFoundDescription
231
+ }
232
+ }
233
+ )
197
234
  }
198
235
  )
199
236
  }
@@ -205,7 +242,10 @@ const EmojiPicker = memo(function EmojiPicker2({
205
242
  {
206
243
  hoveredEmoji,
207
244
  selectedEmoji: value || null,
208
- variant
245
+ variant,
246
+ i18n: {
247
+ pickAnEmoji: i18n.footerPickAnEmoji
248
+ }
209
249
  }
210
250
  ),
211
251
  children
@@ -1,3 +1,3 @@
1
1
  export { useEmojiData } from './use-emoji-data';
2
2
  export { useEmojiScroll } from './use-emoji-scroll';
3
- export type { EmojiData, EmojiCategory, VirtualItem } from './use-emoji-data';
3
+ export type { EmojiData, EmojiCategory, VirtualItem, CategoryNames } from './use-emoji-data';
@@ -16,47 +16,50 @@ export type VirtualItem = {
16
16
  };
17
17
  export declare const categories: readonly [{
18
18
  readonly id: "frequently_used";
19
- readonly name: "Frequently used";
20
19
  }, {
21
20
  readonly id: "smileys_people";
22
- readonly name: "Smileys & People";
23
21
  readonly range: readonly [1, 460];
24
22
  }, {
25
23
  readonly id: "animals_nature";
26
- readonly name: "Animals & Nature";
27
24
  readonly range: readonly [465, 591];
28
25
  }, {
29
26
  readonly id: "food_drink";
30
- readonly name: "Food & Drink";
31
27
  readonly range: readonly [592, 712];
32
28
  }, {
33
29
  readonly id: "travel_places";
34
- readonly name: "Travel & Places";
35
30
  readonly range: readonly [713, 922];
36
31
  }, {
37
32
  readonly id: "activities";
38
- readonly name: "Activities";
39
33
  readonly range: readonly [923, 1001];
40
34
  }, {
41
35
  readonly id: "objects";
42
- readonly name: "Objects";
43
36
  readonly range: readonly [1002, 1234];
44
37
  }, {
45
38
  readonly id: "symbols";
46
- readonly name: "Symbols";
47
39
  readonly range: readonly [1235, 1451];
48
40
  }, {
49
41
  readonly id: "flags";
50
- readonly name: "Flags";
51
42
  readonly range: readonly [1452, 1719];
52
43
  }];
53
44
  export declare function getEmojiCategory(id: number): EmojiCategory;
45
+ export interface CategoryNames {
46
+ activities: string;
47
+ animalsNature: string;
48
+ flags: string;
49
+ foodDrink: string;
50
+ frequentlyUsed: string;
51
+ objects: string;
52
+ smileysPeople: string;
53
+ symbols: string;
54
+ travelPlaces: string;
55
+ }
54
56
  interface UseEmojiDataProps {
57
+ categoryNames?: CategoryNames;
55
58
  columns: number;
56
59
  searchQuery: string;
57
60
  showFrequentlyUsed: boolean;
58
61
  }
59
- export declare function useEmojiData({ searchQuery, columns, showFrequentlyUsed }: UseEmojiDataProps): {
62
+ export declare function useEmojiData({ searchQuery, columns, showFrequentlyUsed, categoryNames, }: UseEmojiDataProps): {
60
63
  categorizedData: VirtualItem[];
61
64
  categoryIndexMap: Map<EmojiCategory, number>;
62
65
  searchResults: {
@@ -2,15 +2,15 @@ import { useState, useEffect, useMemo } from "react";
2
2
  import { emojis } from "../utils/emoji-data.js";
3
3
  import { isBrowser } from "../../../../shared/utils/ssr.js";
4
4
  const categories = [
5
- { id: "frequently_used", name: "Frequently used" },
6
- { id: "smileys_people", name: "Smileys & People", range: [1, 460] },
7
- { id: "animals_nature", name: "Animals & Nature", range: [465, 591] },
8
- { id: "food_drink", name: "Food & Drink", range: [592, 712] },
9
- { id: "travel_places", name: "Travel & Places", range: [713, 922] },
10
- { id: "activities", name: "Activities", range: [923, 1001] },
11
- { id: "objects", name: "Objects", range: [1002, 1234] },
12
- { id: "symbols", name: "Symbols", range: [1235, 1451] },
13
- { id: "flags", name: "Flags", range: [1452, 1719] }
5
+ { id: "frequently_used" },
6
+ { id: "smileys_people", range: [1, 460] },
7
+ { id: "animals_nature", range: [465, 591] },
8
+ { id: "food_drink", range: [592, 712] },
9
+ { id: "travel_places", range: [713, 922] },
10
+ { id: "activities", range: [923, 1001] },
11
+ { id: "objects", range: [1002, 1234] },
12
+ { id: "symbols", range: [1235, 1451] },
13
+ { id: "flags", range: [1452, 1719] }
14
14
  ];
15
15
  const STORAGE_KEY = "emoji-picker-frequently-used";
16
16
  function getEmojiCategory(id) {
@@ -44,7 +44,34 @@ function saveFrequentlyUsedEmoji(emojiId) {
44
44
  } catch {
45
45
  }
46
46
  }
47
- function useEmojiData({ searchQuery, columns, showFrequentlyUsed }) {
47
+ const defaultCategoryNames = {
48
+ frequentlyUsed: "Frequently used",
49
+ smileysPeople: "Smileys & People",
50
+ animalsNature: "Animals & Nature",
51
+ foodDrink: "Food & Drink",
52
+ travelPlaces: "Travel & Places",
53
+ activities: "Activities",
54
+ objects: "Objects",
55
+ symbols: "Symbols",
56
+ flags: "Flags"
57
+ };
58
+ const categoryIdToI18nKey = {
59
+ frequently_used: "frequentlyUsed",
60
+ smileys_people: "smileysPeople",
61
+ animals_nature: "animalsNature",
62
+ food_drink: "foodDrink",
63
+ travel_places: "travelPlaces",
64
+ activities: "activities",
65
+ objects: "objects",
66
+ symbols: "symbols",
67
+ flags: "flags"
68
+ };
69
+ function useEmojiData({
70
+ searchQuery,
71
+ columns,
72
+ showFrequentlyUsed,
73
+ categoryNames = defaultCategoryNames
74
+ }) {
48
75
  const [frequentlyUsed, setFrequentlyUsed] = useState([]);
49
76
  useEffect(() => {
50
77
  if (showFrequentlyUsed) {
@@ -74,7 +101,7 @@ function useEmojiData({ searchQuery, columns, showFrequentlyUsed }) {
74
101
  items.push({
75
102
  type: "header",
76
103
  category: "frequently_used",
77
- title: "Frequently used"
104
+ title: categoryNames.frequentlyUsed
78
105
  });
79
106
  for (let i = 0; i < frequentlyUsed.length; i += columns) {
80
107
  items.push({
@@ -89,10 +116,11 @@ function useEmojiData({ searchQuery, columns, showFrequentlyUsed }) {
89
116
  (emoji) => emoji.id >= category.range[0] && emoji.id <= category.range[1]
90
117
  );
91
118
  if (categoryEmojis.length > 0) {
119
+ const i18nKey = categoryIdToI18nKey[category.id];
92
120
  items.push({
93
121
  type: "header",
94
122
  category: category.id,
95
- title: category.name
123
+ title: i18nKey ? categoryNames[i18nKey] : category.id
96
124
  });
97
125
  for (let i = 0; i < categoryEmojis.length; i += columns) {
98
126
  items.push({
@@ -103,7 +131,7 @@ function useEmojiData({ searchQuery, columns, showFrequentlyUsed }) {
103
131
  }
104
132
  });
105
133
  return items;
106
- }, [searchQuery, searchResults, frequentlyUsed, columns, showFrequentlyUsed]);
134
+ }, [searchQuery, searchResults, frequentlyUsed, columns, showFrequentlyUsed, categoryNames]);
107
135
  const categoryIndexMap = useMemo(() => {
108
136
  const map = /* @__PURE__ */ new Map();
109
137
  categorizedData.forEach((item, index) => {
@@ -17,6 +17,8 @@ function useEmojiScroll({
17
17
  const [currentVisibleCategory, setCurrentVisibleCategory] = useState("frequently_used");
18
18
  const isScrollingToTarget = useRef(false);
19
19
  const isInternalUpdate = useRef(false);
20
+ const scrollingTimeoutRef = useRef(null);
21
+ const internalUpdateTimeoutRef = useRef(null);
20
22
  const virtualizer = useVirtualizer({
21
23
  count: categorizedData.length,
22
24
  getScrollElement: () => scrollRef.current,
@@ -81,7 +83,10 @@ function useEmojiScroll({
81
83
  align: "start",
82
84
  behavior: "auto"
83
85
  });
84
- setTimeout(() => {
86
+ if (scrollingTimeoutRef.current) {
87
+ clearTimeout(scrollingTimeoutRef.current);
88
+ }
89
+ scrollingTimeoutRef.current = setTimeout(() => {
85
90
  isScrollingToTarget.current = false;
86
91
  }, 100);
87
92
  }
@@ -94,17 +99,33 @@ function useEmojiScroll({
94
99
  align: "center",
95
100
  behavior: "auto"
96
101
  });
97
- setTimeout(() => {
102
+ if (scrollingTimeoutRef.current) {
103
+ clearTimeout(scrollingTimeoutRef.current);
104
+ }
105
+ scrollingTimeoutRef.current = setTimeout(() => {
98
106
  isScrollingToTarget.current = false;
99
107
  }, 100);
100
108
  }
101
109
  });
102
110
  const markInternalUpdate = useEventCallback(() => {
103
111
  isInternalUpdate.current = true;
104
- setTimeout(() => {
112
+ if (internalUpdateTimeoutRef.current) {
113
+ clearTimeout(internalUpdateTimeoutRef.current);
114
+ }
115
+ internalUpdateTimeoutRef.current = setTimeout(() => {
105
116
  isInternalUpdate.current = false;
106
117
  }, 50);
107
118
  });
119
+ useEffect(() => {
120
+ return () => {
121
+ if (scrollingTimeoutRef.current) {
122
+ clearTimeout(scrollingTimeoutRef.current);
123
+ }
124
+ if (internalUpdateTimeoutRef.current) {
125
+ clearTimeout(internalUpdateTimeoutRef.current);
126
+ }
127
+ };
128
+ }, []);
108
129
  useEffect(() => {
109
130
  if (value && !searchQuery.trim() && !isInternalUpdate.current) {
110
131
  scrollToEmoji(value);
@@ -132,7 +132,7 @@ const emojiFooterTv = tcv({
132
132
  const emojiEmptyTv = tcv({
133
133
  slots: {
134
134
  container: "flex h-32 flex-col items-center justify-center p-4 text-center",
135
- title: "text-heading-display",
135
+ title: "text-body-large-strong",
136
136
  description: "mt-2 w-32"
137
137
  },
138
138
  variants: {
@@ -145,8 +145,18 @@ const iconButtonTv = tcv({
145
145
  },
146
146
  {
147
147
  variant: "submit",
148
+ active: false,
149
+ disabled: false,
150
+ class: {
151
+ button: ["focus-visible:shadow-focus", "hover:opacity-70", "active:opacity-70"]
152
+ }
153
+ },
154
+ {
155
+ variant: "submit",
156
+ active: true,
157
+ disabled: false,
148
158
  class: {
149
- button: "focus-visible:shadow-focus"
159
+ button: "opacity-70"
150
160
  }
151
161
  },
152
162
  {
@@ -7,7 +7,15 @@ import { TooltipArrow } from "./tooltip-arrow.js";
7
7
  import { tcx } from "../../../../shared/utils/tcx/tcx.js";
8
8
  const TooltipContent = forwardRef(
9
9
  function TooltipContent2(props, propRef) {
10
- const { className, withArrow = true, variant = "default", children, portalId, ...rest } = props;
10
+ const {
11
+ className,
12
+ withArrow = true,
13
+ variant = "default",
14
+ children,
15
+ portalId,
16
+ interactive = true,
17
+ ...rest
18
+ } = props;
11
19
  const state = useTooltipState();
12
20
  const ref = useMergeRefs([state.refs.setFloating, propRef]);
13
21
  const { isInstantPhase, currentId } = useDelayGroup(state.context, {
@@ -36,19 +44,27 @@ const TooltipContent = forwardRef(
36
44
  });
37
45
  const tv = useMemo(() => tooltipContentVariants({ variant }), [variant]);
38
46
  if (state.disabled || !isMounted) return null;
47
+ const floatingProps = state.getFloatingProps(rest);
39
48
  return /* @__PURE__ */ jsx(FloatingPortal, { id: portalId, children: /* @__PURE__ */ jsx(
40
49
  "div",
41
50
  {
42
51
  ref,
43
- style: state.floatingStyles,
44
- ...state.getFloatingProps(rest),
52
+ style: {
53
+ ...state.floatingStyles,
54
+ pointerEvents: interactive ? void 0 : "none"
55
+ },
56
+ ...floatingProps,
45
57
  className: "z-tooltip",
46
58
  children: /* @__PURE__ */ jsxs(
47
59
  "div",
48
60
  {
49
61
  className: tcx(tv.root({ className })),
50
62
  "data-state": state.open ? "open" : "closed",
51
- style: styles,
63
+ style: {
64
+ ...styles,
65
+ pointerEvents: interactive ? void 0 : "none",
66
+ cursor: interactive ? void 0 : "default"
67
+ },
52
68
  children: [
53
69
  children,
54
70
  withArrow && /* @__PURE__ */ jsx(TooltipArrow, { variant })
@@ -17,7 +17,8 @@ function TooltipRoot(props) {
17
17
  withArrow = true,
18
18
  variant = "default",
19
19
  offset = 8,
20
- portalId = PORTAL_ROOT_ID
20
+ portalId = PORTAL_ROOT_ID,
21
+ interactive = true
21
22
  } = props;
22
23
  const tooltip = useTooltip({
23
24
  placement,
@@ -36,6 +37,7 @@ function TooltipRoot(props) {
36
37
  variant,
37
38
  portalId,
38
39
  className,
40
+ interactive,
39
41
  children: [
40
42
  content,
41
43
  shortcut && /* @__PURE__ */ jsx(
@@ -4,6 +4,7 @@ import { KbdKey } from '../../kbd/src';
4
4
  export interface TooltipOptions {
5
5
  disabled?: boolean;
6
6
  initialOpen?: boolean;
7
+ interactive?: boolean;
7
8
  offset?: number;
8
9
  onOpenChange?: (open: boolean) => void;
9
10
  open?: boolean;
@@ -32,6 +33,7 @@ export interface TooltipProps {
32
33
  className?: string;
33
34
  content?: React.ReactNode;
34
35
  disabled?: boolean;
36
+ interactive?: boolean;
35
37
  offset?: number;
36
38
  onOpenChange?: (open: boolean) => void;
37
39
  open?: boolean;
@@ -45,6 +47,7 @@ export interface TooltipProps {
45
47
  withArrow?: boolean;
46
48
  }
47
49
  export interface TooltipContentProps extends React.HTMLProps<HTMLDivElement> {
50
+ interactive?: boolean;
48
51
  portalId?: string;
49
52
  variant?: "default" | "light";
50
53
  withArrow?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@choice-ui/react",
3
- "version": "1.7.8",
3
+ "version": "1.8.1",
4
4
  "description": "A desktop-first React UI component library built for professional desktop applications with comprehensive documentation",
5
5
  "sideEffects": false,
6
6
  "type": "module",