@choice-ui/react 2.0.0 → 2.0.2

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 (53) hide show
  1. package/dist/components/button/dist/index.d.ts +2 -9
  2. package/dist/components/button/dist/index.js +45 -19
  3. package/dist/components/checkbox/dist/index.d.ts +10 -1
  4. package/dist/components/checkbox/dist/index.js +49 -5
  5. package/dist/components/code-block/dist/index.d.ts +11 -14
  6. package/dist/components/code-block/dist/index.js +120 -93
  7. package/dist/components/colors/dist/index.d.ts +39 -6
  8. package/dist/components/colors/src/color-image-paint/color-image-paint.js +2 -2
  9. package/dist/components/dropdown/dist/index.d.ts +6 -0
  10. package/dist/components/dropdown/dist/index.js +20 -10
  11. package/dist/components/emoji-picker/dist/index.d.ts +30 -1
  12. package/dist/components/emoji-picker/dist/index.js +148 -44
  13. package/dist/components/form/src/adapters/range-adapter.js +2 -2
  14. package/dist/components/icon-button/dist/index.d.ts +1 -1
  15. package/dist/components/icon-button/dist/index.js +39 -0
  16. package/dist/components/list/dist/index.d.ts +1 -1
  17. package/dist/components/md-render/dist/index.d.ts +2 -1
  18. package/dist/components/md-render/dist/index.js +5 -9
  19. package/dist/components/md-render/src/components/markdown-block.d.ts +3 -0
  20. package/dist/components/md-render/src/md-render.js +4 -0
  21. package/dist/components/md-render/src/types.d.ts +3 -0
  22. package/dist/components/menus/dist/index.d.ts +5 -0
  23. package/dist/components/menus/dist/index.js +32 -3
  24. package/dist/components/modal/dist/index.js +2 -2
  25. package/dist/components/notifications/dist/index.d.ts +1 -5
  26. package/dist/components/numeric-input/dist/index.d.ts +27 -10
  27. package/dist/components/numeric-input/dist/index.js +132 -34
  28. package/dist/components/numeric-input/src/hooks/use-input-interactions.d.ts +3 -1
  29. package/dist/components/numeric-input/src/hooks/use-input-interactions.js +7 -3
  30. package/dist/components/numeric-input/src/hooks/use-numeric-input.js +15 -4
  31. package/dist/components/numeric-input/src/numeric-input.js +5 -4
  32. package/dist/components/numeric-input/src/utils/value-comparator.js +1 -5
  33. package/dist/components/panel/dist/index.d.ts +16 -16
  34. package/dist/components/picture-preview/dist/index.d.ts +5 -0
  35. package/dist/components/picture-preview/dist/index.js +287 -140
  36. package/dist/components/popover/dist/index.d.ts +5 -0
  37. package/dist/components/popover/dist/index.js +21 -2
  38. package/dist/components/radio/dist/index.d.ts +9 -1
  39. package/dist/components/radio/dist/index.js +50 -6
  40. package/dist/components/range/dist/index.d.ts +276 -20
  41. package/dist/components/range/dist/index.js +1030 -602
  42. package/dist/components/scroll-area/dist/index.d.ts +4 -27
  43. package/dist/components/scroll-area/dist/index.js +96 -123
  44. package/dist/components/separator/dist/index.d.ts +1 -8
  45. package/dist/components/splitter/dist/index.d.ts +1 -1
  46. package/dist/components/text-field/dist/index.d.ts +2 -3
  47. package/dist/components/text-field/dist/index.js +4 -19
  48. package/dist/components/textarea/dist/index.js +3 -1
  49. package/dist/components/toast/dist/index.d.ts +274 -0
  50. package/dist/components/tooltip/dist/index.d.ts +2 -0
  51. package/dist/components/tooltip/dist/index.js +23 -5
  52. package/dist/components/virtual-select/dist/index.d.ts +48 -0
  53. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- import React__default, { memo, useState, useEffect } from "react";
1
+ import React__default, { memo, useState, useEffect, useRef, useCallback } from "react";
2
2
  import { useStickToBottom } from "use-stick-to-bottom";
3
3
  import { codeToHtml } from "shiki";
4
4
  import { useEventCallback } from "usehooks-ts";
@@ -34,13 +34,34 @@ function useCodeBlock({
34
34
  if (!code || typeof code !== "string") {
35
35
  return;
36
36
  }
37
- try {
38
- if (typeof navigator !== "undefined" && navigator.clipboard) {
37
+ const onSuccess = () => {
38
+ setCopied(true);
39
+ setTimeout(() => setCopied(false), 2e3);
40
+ };
41
+ if (typeof navigator !== "undefined" && navigator.clipboard) {
42
+ try {
39
43
  await navigator.clipboard.writeText(code);
40
- setCopied(true);
41
- setTimeout(() => setCopied(false), 2e3);
44
+ onSuccess();
45
+ return;
46
+ } catch {
47
+ }
48
+ }
49
+ const textArea = document.createElement("textarea");
50
+ try {
51
+ textArea.value = code;
52
+ textArea.style.cssText = "position:fixed;top:0;left:0;width:2em;height:2em;padding:0;border:none;outline:none;box-shadow:none;background:transparent;";
53
+ document.body.appendChild(textArea);
54
+ textArea.focus();
55
+ textArea.select();
56
+ const successful = document.execCommand("copy");
57
+ if (successful) {
58
+ onSuccess();
59
+ }
60
+ } catch {
61
+ } finally {
62
+ if (textArea.parentNode) {
63
+ textArea.parentNode.removeChild(textArea);
42
64
  }
43
- } catch (error) {
44
65
  }
45
66
  });
46
67
  return {
@@ -56,12 +77,15 @@ function useScrollDetection({
56
77
  scrollRef,
57
78
  contentRef,
58
79
  isExpanded,
59
- codeExpanded,
60
- children
80
+ codeExpanded
61
81
  }) {
62
82
  const [needsScroll, setNeedsScroll] = useState(false);
63
- useEffect(() => {
64
- const checkScrollNeeded = () => {
83
+ const debounceRef = useRef(null);
84
+ const checkScrollNeeded = useCallback(() => {
85
+ if (debounceRef.current) {
86
+ clearTimeout(debounceRef.current);
87
+ }
88
+ debounceRef.current = setTimeout(() => {
65
89
  if (!scrollRef.current || !contentRef.current) {
66
90
  setNeedsScroll(false);
67
91
  return;
@@ -71,50 +95,30 @@ function useScrollDetection({
71
95
  const content = contentRef.current;
72
96
  const hasScroll = content.scrollHeight > viewport.clientHeight;
73
97
  setNeedsScroll(hasScroll);
74
- } catch (error) {
98
+ } catch {
75
99
  setNeedsScroll(false);
76
100
  }
77
- };
101
+ }, 50);
102
+ }, [scrollRef, contentRef]);
103
+ useEffect(() => {
78
104
  const timeoutId = setTimeout(checkScrollNeeded, 100);
79
105
  window.addEventListener("resize", checkScrollNeeded);
80
106
  let resizeObserver = null;
81
- if (typeof ResizeObserver !== "undefined") {
107
+ if (typeof ResizeObserver !== "undefined" && contentRef.current) {
82
108
  resizeObserver = new ResizeObserver(checkScrollNeeded);
83
- if (contentRef.current) {
84
- resizeObserver.observe(contentRef.current);
85
- }
109
+ resizeObserver.observe(contentRef.current);
86
110
  }
87
111
  return () => {
88
112
  clearTimeout(timeoutId);
113
+ if (debounceRef.current) {
114
+ clearTimeout(debounceRef.current);
115
+ }
89
116
  window.removeEventListener("resize", checkScrollNeeded);
90
117
  resizeObserver == null ? void 0 : resizeObserver.disconnect();
91
118
  };
92
- }, [scrollRef, contentRef, isExpanded, codeExpanded, children]);
119
+ }, [checkScrollNeeded, isExpanded, codeExpanded]);
93
120
  return needsScroll;
94
121
  }
95
- function useLineCount(children) {
96
- const [lineCount, setLineCount] = useState(0);
97
- useEffect(() => {
98
- try {
99
- const codeContent = React__default.Children.toArray(children).map((child) => {
100
- var _a;
101
- if (React__default.isValidElement(child) && ((_a = child.props) == null ? void 0 : _a.code) && typeof child.props.code === "string") {
102
- return child.props.code;
103
- }
104
- return "";
105
- }).join("");
106
- if (codeContent) {
107
- const lines = codeContent.split("\n").length;
108
- setLineCount(lines);
109
- } else {
110
- setLineCount(0);
111
- }
112
- } catch (error) {
113
- setLineCount(0);
114
- }
115
- }, [children]);
116
- return lineCount;
117
- }
118
122
  function useTheme() {
119
123
  const [theme, setTheme] = useState(() => {
120
124
  if (typeof window === "undefined") return "light";
@@ -176,34 +180,46 @@ var codeBlockCodeTv = tcv({
176
180
  base: "text-message-code w-fit min-w-full bg-transparent font-mono [&>pre]:!bg-transparent [&>pre]:px-4 [&>pre]:py-4"
177
181
  });
178
182
  var CodeBlockCode = memo(function CodeBlockCode2(props) {
179
- const { code, language = "tsx", className, variant: variantProp, codeBlock, ...rest } = props;
183
+ const { children, language = "tsx", className, variant: variantProp, codeBlock, ...rest } = props;
180
184
  const systemTheme = useTheme();
181
185
  const resolvedVariant = variantProp ?? ((codeBlock == null ? void 0 : codeBlock.variant) === "default" ? void 0 : codeBlock == null ? void 0 : codeBlock.variant);
182
186
  const theme = resolvedVariant ?? systemTheme;
183
187
  const [highlightedHtml, setHighlightedHtml] = useState(null);
184
188
  useEffect(() => {
189
+ let isMounted = true;
185
190
  async function highlight() {
186
- if (!code) {
187
- setHighlightedHtml("<pre><code></code></pre>");
191
+ if (!children) {
192
+ if (isMounted) setHighlightedHtml("<pre><code></code></pre>");
188
193
  return;
189
194
  }
190
195
  const resolvedLang = resolveLanguage(language);
196
+ const themeConfig = theme === "light" ? "github-light" : "github-dark";
191
197
  try {
192
- const html = await codeToHtml(code, {
198
+ const html = await codeToHtml(children, {
193
199
  lang: resolvedLang,
194
- theme: theme === "light" ? "github-light" : "github-dark"
200
+ theme: themeConfig
195
201
  });
196
- setHighlightedHtml(html);
202
+ if (isMounted) setHighlightedHtml(html);
197
203
  } catch {
198
- const html = await codeToHtml(code, {
199
- lang: "text",
200
- theme: theme === "light" ? "github-light" : "github-dark"
201
- });
202
- setHighlightedHtml(html);
204
+ try {
205
+ const html = await codeToHtml(children, {
206
+ lang: "text",
207
+ theme: themeConfig
208
+ });
209
+ if (isMounted) setHighlightedHtml(html);
210
+ } catch {
211
+ if (isMounted) {
212
+ const escaped = children.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
213
+ setHighlightedHtml(`<pre><code>${escaped}</code></pre>`);
214
+ }
215
+ }
203
216
  }
204
217
  }
205
218
  highlight();
206
- }, [code, language, theme]);
219
+ return () => {
220
+ isMounted = false;
221
+ };
222
+ }, [children, language, theme]);
207
223
  const classNames = codeBlockCodeTv({ className });
208
224
  return highlightedHtml ? /* @__PURE__ */ jsx(
209
225
  "div",
@@ -217,10 +233,29 @@ var CodeBlockCode = memo(function CodeBlockCode2(props) {
217
233
  {
218
234
  className: tcx("min-w-0", classNames),
219
235
  ...rest,
220
- children: /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: code }) })
236
+ children: /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children }) })
221
237
  }
222
238
  );
223
239
  });
240
+ function extractCodeFromChildren(children) {
241
+ if (!children) return "";
242
+ try {
243
+ return React__default.Children.toArray(children).map((child) => {
244
+ var _a, _b;
245
+ if (React__default.isValidElement(child)) {
246
+ if (((_a = child.props) == null ? void 0 : _a.code) && typeof child.props.code === "string") {
247
+ return child.props.code;
248
+ }
249
+ if (((_b = child.props) == null ? void 0 : _b.children) && typeof child.props.children === "string") {
250
+ return child.props.children;
251
+ }
252
+ }
253
+ return "";
254
+ }).filter(Boolean).join("");
255
+ } catch {
256
+ return "";
257
+ }
258
+ }
224
259
  var icons = {
225
260
  js: /* @__PURE__ */ jsxs(
226
261
  "svg",
@@ -908,9 +943,8 @@ var CodeBlockHeader = memo(function CodeBlockHeader2(props) {
908
943
  handleCopy,
909
944
  variant
910
945
  } = codeBlock;
911
- if (!handleExpand || !handleCopy) {
912
- return null;
913
- }
946
+ const canExpand = Boolean(handleExpand);
947
+ const canCopy = Boolean(handleCopy);
914
948
  const tv = codeBlockHeaderTv({ isExpanded, variant });
915
949
  let icon = null;
916
950
  try {
@@ -934,17 +968,17 @@ var CodeBlockHeader = memo(function CodeBlockHeader2(props) {
934
968
  children
935
969
  ] }),
936
970
  /* @__PURE__ */ jsxs("div", { className: tv.actions(), children: [
937
- isExpanded && /* @__PURE__ */ jsx(
971
+ isExpanded && canCopy && /* @__PURE__ */ jsx(
938
972
  IconButton,
939
973
  {
940
974
  className: tv.button(),
941
975
  variant: variant === "dark" ? "dark" : "ghost",
942
- onClick: () => handleCopy(),
976
+ onClick: () => handleCopy == null ? void 0 : handleCopy(),
943
977
  tooltip: { content: copyTooltipContent },
944
978
  children: copied ? /* @__PURE__ */ jsx(Check, { className: "text-success-foreground" }) : /* @__PURE__ */ jsx(ClipboardSmall, {})
945
979
  }
946
980
  ),
947
- expandable && /* @__PURE__ */ jsx(
981
+ expandable && canExpand && /* @__PURE__ */ jsx(
948
982
  IconButton,
949
983
  {
950
984
  className: tv.button(),
@@ -972,9 +1006,10 @@ var codeBlockFooterTv = tcv({
972
1006
  },
973
1007
  false: {
974
1008
  footer: [
975
- "bg-secondary-background/90 absolute inset-x-0 bottom-0 z-3",
1009
+ "bg-secondary-background/80 absolute inset-x-0 bottom-0 z-3",
976
1010
  "opacity-0 group-hover:opacity-100",
977
- "hover:bg-tertiary-background"
1011
+ "hover:bg-tertiary-background",
1012
+ "backdrop-blur-xs"
978
1013
  ]
979
1014
  }
980
1015
  }
@@ -988,7 +1023,7 @@ var CodeBlockFooter = memo(function CodeBlockFooter2(props) {
988
1023
  if (!codeBlock) return null;
989
1024
  const { isExpanded, codeExpanded, handleCodeExpand, lineCount, lineThreshold, needsScroll } = codeBlock;
990
1025
  const tv = codeBlockFooterTv({ codeExpanded });
991
- if (!(lineCount > lineThreshold || needsScroll || codeExpanded) || !isExpanded) {
1026
+ if (lineThreshold && !(lineCount > lineThreshold || needsScroll || codeExpanded) || !isExpanded) {
992
1027
  return null;
993
1028
  }
994
1029
  return /* @__PURE__ */ jsx(
@@ -1000,24 +1035,26 @@ var CodeBlockFooter = memo(function CodeBlockFooter2(props) {
1000
1035
  }
1001
1036
  );
1002
1037
  });
1038
+ var LINE_HEIGHT_PX = 16;
1039
+ var HEIGHT_PADDING_PX = 32 + 40;
1003
1040
  var codeBlockTv = tcv({
1004
1041
  slots: {
1005
- code: "overflow-hidden",
1042
+ code: "overflow-hidden min-h-0 flex-1",
1006
1043
  content: "flex w-fit flex-col overflow-clip p-[inherit]"
1007
1044
  }
1008
1045
  });
1009
- function CodeBlockContent(props) {
1010
- const { code, className, codeBlock, withScrollArea = true } = props;
1046
+ var CodeBlockContent = memo(function CodeBlockContent2(props) {
1047
+ const { className, codeBlock, withScrollArea = true, children } = props;
1011
1048
  if (!codeBlock) return null;
1012
1049
  const { language, isExpanded, codeExpanded, scrollRef, contentRef, lineCount, lineThreshold } = codeBlock;
1013
1050
  if (!isExpanded) {
1014
1051
  return null;
1015
1052
  }
1016
- if (typeof code !== "string") {
1053
+ if (typeof children !== "string") {
1017
1054
  return null;
1018
1055
  }
1019
1056
  const tv = codeBlockTv();
1020
- const shouldLimitHeight = lineCount > lineThreshold && !codeExpanded;
1057
+ const shouldLimitHeight = lineThreshold && lineCount > lineThreshold && !codeExpanded;
1021
1058
  return /* @__PURE__ */ jsx(Fragment, { children: withScrollArea ? /* @__PURE__ */ jsx(
1022
1059
  ScrollArea,
1023
1060
  {
@@ -1030,7 +1067,7 @@ function CodeBlockContent(props) {
1030
1067
  {
1031
1068
  ref: scrollRef,
1032
1069
  style: {
1033
- maxHeight: shouldLimitHeight ? `${lineThreshold * 14 + 32}px` : "none"
1070
+ maxHeight: shouldLimitHeight ? `${lineThreshold * LINE_HEIGHT_PX + HEIGHT_PADDING_PX}px` : "none"
1034
1071
  },
1035
1072
  children: /* @__PURE__ */ jsx(
1036
1073
  ScrollArea.Content,
@@ -1040,9 +1077,9 @@ function CodeBlockContent(props) {
1040
1077
  children: /* @__PURE__ */ jsx(
1041
1078
  CodeBlockCode,
1042
1079
  {
1043
- code,
1044
1080
  language,
1045
- codeBlock
1081
+ codeBlock,
1082
+ children
1046
1083
  }
1047
1084
  )
1048
1085
  }
@@ -1053,19 +1090,19 @@ function CodeBlockContent(props) {
1053
1090
  ) : /* @__PURE__ */ jsx("div", { className: tcx(tv.content(), className), children: /* @__PURE__ */ jsx(
1054
1091
  CodeBlockCode,
1055
1092
  {
1056
- code,
1057
1093
  language,
1058
- codeBlock
1094
+ codeBlock,
1095
+ children
1059
1096
  }
1060
1097
  ) }) });
1061
- }
1098
+ });
1062
1099
  var CodeBlockRoot = memo(function CodeBlock(props) {
1063
1100
  const {
1064
1101
  children,
1065
1102
  className,
1066
1103
  filename,
1067
1104
  language = "code",
1068
- lineThreshold = 20,
1105
+ lineThreshold,
1069
1106
  expandable = true,
1070
1107
  defaultExpanded = true,
1071
1108
  defaultCodeExpanded = false,
@@ -1077,7 +1114,6 @@ var CodeBlockRoot = memo(function CodeBlock(props) {
1077
1114
  resize: "smooth",
1078
1115
  initial: "smooth"
1079
1116
  });
1080
- const codeContentRef = React__default.useRef("");
1081
1117
  const {
1082
1118
  isExpanded,
1083
1119
  codeExpanded,
@@ -1092,34 +1128,25 @@ var CodeBlockRoot = memo(function CodeBlock(props) {
1092
1128
  onCodeExpandChange,
1093
1129
  scrollToBottom
1094
1130
  });
1131
+ const codeContent = React__default.useMemo(() => extractCodeFromChildren(children), [children]);
1132
+ const lineCount = React__default.useMemo(
1133
+ () => codeContent ? codeContent.split("\n").length : 0,
1134
+ [codeContent]
1135
+ );
1095
1136
  const handleCopy = React__default.useCallback(
1096
1137
  (code) => {
1097
- const codeToUse = code || codeContentRef.current;
1138
+ const codeToUse = code || codeContent;
1098
1139
  if (codeToUse) {
1099
1140
  originalHandleCopy(codeToUse);
1100
1141
  }
1101
1142
  },
1102
- [originalHandleCopy]
1143
+ [originalHandleCopy, codeContent]
1103
1144
  );
1104
- React__default.useEffect(() => {
1105
- try {
1106
- React__default.Children.forEach(children, (child) => {
1107
- if (React__default.isValidElement(child) && child.props) {
1108
- if (child.props.code && typeof child.props.code === "string") {
1109
- codeContentRef.current = child.props.code;
1110
- }
1111
- }
1112
- });
1113
- } catch {
1114
- }
1115
- }, [children]);
1116
- const lineCount = useLineCount(children);
1117
1145
  const needsScroll = useScrollDetection({
1118
1146
  scrollRef,
1119
1147
  contentRef,
1120
1148
  isExpanded,
1121
- codeExpanded,
1122
- children
1149
+ codeExpanded
1123
1150
  });
1124
1151
  const contextValue = React__default.useMemo(
1125
1152
  () => ({
@@ -1178,7 +1205,7 @@ var CodeBlockRoot = memo(function CodeBlock(props) {
1178
1205
  "div",
1179
1206
  {
1180
1207
  className: tcx(
1181
- "group/code-block relative overflow-hidden rounded-lg",
1208
+ "group/code-block relative flex flex-col overflow-hidden rounded-lg",
1182
1209
  variant === "default" && "bg-secondary-background",
1183
1210
  variant === "light" && "bg-gray-100",
1184
1211
  variant === "dark" && "bg-gray-700",
@@ -452,8 +452,37 @@ interface ColorAreaProps {
452
452
  }
453
453
  declare const ColorArea: react.MemoExoticComponent<react.ForwardRefExoticComponent<ColorAreaProps & react.RefAttributes<HTMLDivElement>>>;
454
454
 
455
+ interface ColorSliderThumbProps {
456
+ className?: string;
457
+ size?: number;
458
+ }
459
+ declare function ColorSliderThumb(props: ColorSliderThumbProps): react_jsx_runtime.JSX.Element;
460
+ declare namespace ColorSliderThumb {
461
+ var displayName: string;
462
+ }
463
+
464
+ interface ColorSliderTrackProps {
465
+ className?: string;
466
+ children?: React.ReactNode;
467
+ /**
468
+ * Height of the track in pixels.
469
+ * This prop is extracted by the parent ColorSlider and passed via context.
470
+ */
471
+ height?: number;
472
+ }
473
+ /**
474
+ * ColorSliderTrack - The track background of the color slider.
475
+ * Renders the gradient background based on slider type (hue, alpha, etc.)
476
+ * Can contain custom children for additional visual elements.
477
+ */
478
+ declare function ColorSliderTrack(props: ColorSliderTrackProps): react_jsx_runtime.JSX.Element;
479
+ declare namespace ColorSliderTrack {
480
+ var displayName: string;
481
+ }
482
+
455
483
  interface ColorSliderProps {
456
484
  backgroundStyle?: CSSProperties;
485
+ children?: React.ReactNode;
457
486
  className?: string;
458
487
  disabled?: boolean;
459
488
  hue?: number;
@@ -461,14 +490,18 @@ interface ColorSliderProps {
461
490
  onChangeEnd?: () => void;
462
491
  onChangeStart?: () => void;
463
492
  position: number;
464
- thumbSize?: number;
465
- trackSize?: {
466
- height?: number;
467
- width?: number;
468
- };
469
493
  type: PickerSliderType;
494
+ /**
495
+ * Width of the slider track in pixels.
496
+ * If not provided (undefined or false), the width will be auto-calculated from the container.
497
+ */
498
+ width?: number | boolean;
499
+ }
500
+ interface ColorSliderComponent extends React.MemoExoticComponent<React.ForwardRefExoticComponent<ColorSliderProps & React.RefAttributes<HTMLDivElement>>> {
501
+ Thumb: typeof ColorSliderThumb;
502
+ Track: typeof ColorSliderTrack;
470
503
  }
471
- declare const ColorSlider: react.MemoExoticComponent<react.ForwardRefExoticComponent<ColorSliderProps & react.RefAttributes<HTMLDivElement>>>;
504
+ declare const ColorSlider: ColorSliderComponent;
472
505
 
473
506
  interface ColorSwatchProps extends Omit<HTMLProps<HTMLDivElement>, "color"> {
474
507
  alpha?: number;
@@ -1,6 +1,6 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { Button } from "../../../button/dist/index.js";
3
- import { Range } from "../../../range/dist/index.js";
3
+ import { Range as Range2 } from "../../../range/dist/index.js";
4
4
  import React__default, { memo, useState, useRef, useMemo, useEffect, useCallback } from "react";
5
5
  import { useEventCallback } from "usehooks-ts";
6
6
  import { ColorImageToolbar } from "./color-image-toolbar.js";
@@ -209,7 +209,7 @@ const ColorImagePaint = memo(function ColorImagePaint2(props) {
209
209
  return /* @__PURE__ */ jsxs(React__default.Fragment, { children: [
210
210
  /* @__PURE__ */ jsx("span", { className: styles.adjustLabel(), children: (_a2 = features == null ? void 0 : features.labels) == null ? void 0 : _a2[filterName] }),
211
211
  /* @__PURE__ */ jsx(
212
- Range,
212
+ Range2,
213
213
  {
214
214
  min: -100,
215
215
  max: 100,
@@ -7,6 +7,12 @@ interface DropdownProps {
7
7
  * @default true
8
8
  */
9
9
  autoSelectFirstItem?: boolean;
10
+ /**
11
+ * Whether to avoid collisions by flipping or shifting the dropdown position.
12
+ * When false, the dropdown will strictly follow the placement direction.
13
+ * @default true
14
+ */
15
+ avoidCollisions?: boolean;
10
16
  children?: React.ReactNode;
11
17
  disabledNested?: boolean;
12
18
  focusManagerProps?: Partial<FloatingFocusManagerProps>;
@@ -13,6 +13,7 @@ var DropdownComponent = memo(function DropdownComponent2(props) {
13
13
  const {
14
14
  children,
15
15
  autoSelectFirstItem = true,
16
+ avoidCollisions = true,
16
17
  disabledNested = false,
17
18
  offset: offsetDistance = DEFAULT_OFFSET,
18
19
  placement = "bottom-start",
@@ -53,7 +54,7 @@ var DropdownComponent = memo(function DropdownComponent2(props) {
53
54
  }
54
55
  onOpenChange == null ? void 0 : onOpenChange(newOpen);
55
56
  });
56
- const { nodeId, item, isNested } = useMenuTree({
57
+ const { nodeId, item, isNested, tree } = useMenuTree({
57
58
  disabledNested,
58
59
  handleOpenChange,
59
60
  isControlledOpen
@@ -77,11 +78,14 @@ var DropdownComponent = memo(function DropdownComponent2(props) {
77
78
  });
78
79
  });
79
80
  const lastPositionRef = useRef(null);
80
- const middleware = useMemo(
81
- () => [
82
- offset({ mainAxis: isNested ? 10 : offsetDistance, alignmentAxis: isNested ? -4 : 0 }),
83
- flip(),
84
- shift(),
81
+ const middleware = useMemo(() => {
82
+ const baseMiddleware = [
83
+ offset({ mainAxis: isNested ? 10 : offsetDistance, alignmentAxis: isNested ? -4 : 0 })
84
+ ];
85
+ if (avoidCollisions) {
86
+ baseMiddleware.push(flip(), shift());
87
+ }
88
+ baseMiddleware.push(
85
89
  size({
86
90
  padding: 4,
87
91
  apply({ elements, availableHeight, rects }) {
@@ -104,9 +108,9 @@ var DropdownComponent = memo(function DropdownComponent2(props) {
104
108
  }
105
109
  }
106
110
  })
107
- ],
108
- [isNested, offsetDistance, matchTriggerWidth, scrollRef]
109
- );
111
+ );
112
+ return baseMiddleware;
113
+ }, [isNested, offsetDistance, matchTriggerWidth, scrollRef, avoidCollisions]);
110
114
  const { refs, floatingStyles, context, isPositioned } = useFloating({
111
115
  nodeId,
112
116
  open: isControlledOpen,
@@ -165,11 +169,17 @@ var DropdownComponent = memo(function DropdownComponent2(props) {
165
169
  bubbles: true,
166
170
  escapeKey: true
167
171
  });
172
+ const handleNavigate = useEventCallback((index) => {
173
+ setActiveIndex(index);
174
+ if (tree && index !== null) {
175
+ tree.events.emit("navigate", { nodeId, index });
176
+ }
177
+ });
168
178
  const listNavigation = useListNavigation(context, {
169
179
  listRef: elementsRef,
170
180
  activeIndex,
171
181
  nested: isNested,
172
- onNavigate: setActiveIndex,
182
+ onNavigate: handleNavigate,
173
183
  loop: true
174
184
  });
175
185
  const typeahead = useTypeahead(context, {
@@ -15,12 +15,24 @@ type VirtualItem = {
15
15
  emojis: EmojiData[];
16
16
  type: "emojis";
17
17
  };
18
+ interface CategoryNames {
19
+ activities: string;
20
+ animalsNature: string;
21
+ flags: string;
22
+ foodDrink: string;
23
+ frequentlyUsed: string;
24
+ objects: string;
25
+ smileysPeople: string;
26
+ symbols: string;
27
+ travelPlaces: string;
28
+ }
18
29
  interface UseEmojiDataProps {
30
+ categoryNames?: CategoryNames;
19
31
  columns: number;
20
32
  searchQuery: string;
21
33
  showFrequentlyUsed: boolean;
22
34
  }
23
- declare function useEmojiData({ searchQuery, columns, showFrequentlyUsed }: UseEmojiDataProps): {
35
+ declare function useEmojiData({ searchQuery, columns, showFrequentlyUsed, categoryNames, }: UseEmojiDataProps): {
24
36
  categorizedData: VirtualItem[];
25
37
  categoryIndexMap: Map<EmojiCategory, number>;
26
38
  searchResults: {
@@ -49,8 +61,25 @@ interface EmojiPickerProps {
49
61
  showCategories?: boolean;
50
62
  showFrequentlyUsed?: boolean;
51
63
  showSearch?: boolean;
64
+ showFooter?: boolean;
52
65
  value?: EmojiData | null;
53
66
  variant?: "default" | "dark" | "light";
67
+ i18n?: {
68
+ noEmojisFoundTitle?: string;
69
+ noEmojisFoundDescription?: string;
70
+ footerPickAnEmoji?: string;
71
+ categories?: {
72
+ frequentlyUsed: string;
73
+ smileysPeople: string;
74
+ animalsNature: string;
75
+ foodDrink: string;
76
+ travelPlaces: string;
77
+ activities: string;
78
+ objects: string;
79
+ symbols: string;
80
+ flags: string;
81
+ };
82
+ };
54
83
  }
55
84
  declare const EmojiPicker: React.NamedExoticComponent<EmojiPickerProps>;
56
85