@choice-ui/react 1.4.7 → 1.4.9

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,7 +1,7 @@
1
1
  import { Kbd } from "../../kbd/dist/index.js";
2
2
  import { useMergeRefs, useDelayGroup, useTransitionStyles, FloatingPortal, offset, flip, shift, arrow, useFloating, autoUpdate, useHover, useFocus, useDismiss, useRole, useInteractions } from "@floating-ui/react";
3
3
  import { FloatingDelayGroup } from "@floating-ui/react";
4
- import { forwardRef, createContext, useMemo, useState, useRef, useContext } from "react";
4
+ import React, { forwardRef, createContext, useMemo, useState, useRef, useContext } from "react";
5
5
  import { jsxs, jsx } from "react/jsx-runtime";
6
6
  import { Slot } from "../../slot/dist/index.js";
7
7
  import { tcv, tcx } from "../../../shared/utils/tcx/tcx.js";
@@ -183,7 +183,7 @@ var TooltipContent = forwardRef(
183
183
  var TooltipTrigger = forwardRef(
184
184
  function TooltipTrigger2({ children, ...props }, propRef) {
185
185
  const state = useTooltipState();
186
- const childrenRef = children == null ? void 0 : children.ref;
186
+ const childrenRef = React.isValidElement(children) ? children.props.ref : void 0;
187
187
  const ref = useMergeRefs([state.refs.setReference, propRef, childrenRef]);
188
188
  return /* @__PURE__ */ jsx(
189
189
  Slot,
@@ -1,2 +1,2 @@
1
- import { HTMLProps } from 'react';
2
- export declare const TooltipTrigger: import('react').ForwardRefExoticComponent<Omit<HTMLProps<HTMLElement>, "ref"> & import('react').RefAttributes<HTMLElement>>;
1
+ import { default as React } from 'react';
2
+ export declare const TooltipTrigger: React.ForwardRefExoticComponent<Omit<React.HTMLProps<HTMLElement>, "ref"> & React.RefAttributes<HTMLElement>>;
@@ -1,12 +1,12 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { Slot } from "../../../slot/dist/index.js";
3
3
  import { useMergeRefs } from "@floating-ui/react";
4
- import { forwardRef } from "react";
4
+ import React, { forwardRef } from "react";
5
5
  import { useTooltipState } from "../context/tooltip-context.js";
6
6
  const TooltipTrigger = forwardRef(
7
7
  function TooltipTrigger2({ children, ...props }, propRef) {
8
8
  const state = useTooltipState();
9
- const childrenRef = children == null ? void 0 : children.ref;
9
+ const childrenRef = React.isValidElement(children) ? children.props.ref : void 0;
10
10
  const ref = useMergeRefs([state.refs.setReference, propRef, childrenRef]);
11
11
  return /* @__PURE__ */ jsx(
12
12
  Slot,
@@ -1,11 +1,11 @@
1
1
  import { ReactNode } from 'react';
2
- import { AlertDialogProps } from '../components/alert-dialog';
2
+ import { AlertDialogProviderProps } from '../components/alert-dialog/src/context';
3
3
  export interface ChoiceUiProviderProps {
4
4
  children: ReactNode;
5
5
  /**
6
6
  * AlertDialog configuration
7
7
  */
8
- alertDialog?: Omit<AlertDialogProps, "children">;
8
+ alertDialog?: Omit<AlertDialogProviderProps, "children">;
9
9
  /**
10
10
  * Tooltip delay configuration
11
11
  * @default { open: 400, close: 200 }
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { FloatingDelayGroup } from "@floating-ui/react";
3
- import { AlertDialogProvider } from "../components/alert-dialog/dist/index.js";
3
+ import { AlertDialogProvider } from "../components/alert-dialog/src/context/alert-dialog-provider.js";
4
4
  const DEFAULT_TOOLTIP_DELAY = {
5
5
  open: 400,
6
6
  close: 200
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@choice-ui/react",
3
- "version": "1.4.7",
3
+ "version": "1.4.9",
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",
@@ -1,497 +0,0 @@
1
- import { Button } from "../../button/dist/index.js";
2
- import { Modal } from "../../modal/dist/index.js";
3
- import { useFloating, FloatingFocusManager, FloatingPortal, FloatingOverlay } from "@floating-ui/react";
4
- import { memo, createContext, useReducer, useCallback, useEffect, useMemo, useContext } from "react";
5
- import { useEventCallback } from "usehooks-ts";
6
- import { jsxs, jsx, Fragment } from "react/jsx-runtime";
7
- import { tcv, tcx } from "../../../shared/utils/tcx/tcx.js";
8
- var AlertDialogContext = createContext(null);
9
- var useAlertDialogContext = () => {
10
- const context = useContext(AlertDialogContext);
11
- if (!context) {
12
- throw new Error("useAlertDialogContext must be used within an AlertDialogProvider");
13
- }
14
- return context;
15
- };
16
- var alertDialogTv = tcv({
17
- slots: {
18
- overlay: ["fixed inset-0 grid place-items-center z-alert"],
19
- container: "max-w-none",
20
- content: "flex flex-col gap-4 px-4 py-2",
21
- header: "border-b-transparent",
22
- footer: "flex items-center justify-end gap-2 border-t-transparent"
23
- },
24
- variants: {
25
- variant: {
26
- default: {},
27
- danger: {
28
- container: "border-danger-boundary"
29
- },
30
- success: {
31
- container: "border-success-boundary"
32
- },
33
- warning: {
34
- container: "border-warning-boundary"
35
- }
36
- },
37
- size: {
38
- small: {
39
- container: "w-60"
40
- },
41
- default: {
42
- container: "w-80"
43
- },
44
- large: {
45
- container: "w-120"
46
- }
47
- }
48
- },
49
- defaultVariants: {
50
- variant: "default"
51
- }
52
- });
53
- var DEFAULT_CONFIRM_TEXT = "Confirm";
54
- var DEFAULT_CANCEL_TEXT = "Cancel";
55
- var DEFAULT_ALERT_TEXT = "OK";
56
- var DEFAULT_CONFIRM_VARIANT = "primary";
57
- var DEFAULT_CANCEL_VARIANT = "secondary";
58
- var initialState = {
59
- isOpen: false,
60
- type: null,
61
- config: null,
62
- resolve: null,
63
- queue: []
64
- };
65
- var alertDialogReducer = (state, action) => {
66
- switch (action.type) {
67
- case "SHOW": {
68
- const { dialogType, config, resolve } = action.payload;
69
- if (state.isOpen) {
70
- return {
71
- ...state,
72
- queue: [...state.queue, { type: dialogType, config, resolve }]
73
- };
74
- }
75
- return {
76
- ...state,
77
- isOpen: true,
78
- type: dialogType,
79
- config,
80
- resolve
81
- };
82
- }
83
- case "HIDE": {
84
- const { value } = action.payload;
85
- if (state.resolve) {
86
- state.resolve(value);
87
- }
88
- if (state.queue.length > 0) {
89
- const next = state.queue[0];
90
- return {
91
- ...state,
92
- type: next.type,
93
- config: next.config,
94
- resolve: next.resolve,
95
- queue: state.queue.slice(1)
96
- };
97
- }
98
- return {
99
- ...state,
100
- isOpen: false,
101
- type: null,
102
- config: null,
103
- resolve: null
104
- };
105
- }
106
- case "NEXT": {
107
- if (state.queue.length > 0) {
108
- const next = state.queue[0];
109
- return {
110
- ...state,
111
- type: next.type,
112
- config: next.config,
113
- resolve: next.resolve,
114
- queue: state.queue.slice(1)
115
- };
116
- }
117
- return {
118
- ...state,
119
- isOpen: false,
120
- type: null,
121
- config: null,
122
- resolve: null
123
- };
124
- }
125
- case "CLEAR_QUEUE": {
126
- return {
127
- ...state,
128
- isOpen: false,
129
- type: null,
130
- config: null,
131
- resolve: null,
132
- queue: []
133
- };
134
- }
135
- default:
136
- return state;
137
- }
138
- };
139
- var normalizeConfirmConfig = (config) => {
140
- if (typeof config === "string") {
141
- return {
142
- description: config,
143
- confirmText: DEFAULT_CONFIRM_TEXT,
144
- cancelText: DEFAULT_CANCEL_TEXT,
145
- confirmVariant: DEFAULT_CONFIRM_VARIANT,
146
- cancelVariant: DEFAULT_CANCEL_VARIANT
147
- };
148
- }
149
- return {
150
- confirmText: DEFAULT_CONFIRM_TEXT,
151
- cancelText: DEFAULT_CANCEL_TEXT,
152
- confirmVariant: DEFAULT_CONFIRM_VARIANT,
153
- cancelVariant: DEFAULT_CANCEL_VARIANT,
154
- ...config
155
- };
156
- };
157
- var normalizeAlertConfig = (config) => {
158
- if (typeof config === "string") {
159
- return {
160
- description: config,
161
- confirmText: DEFAULT_ALERT_TEXT,
162
- confirmVariant: DEFAULT_CONFIRM_VARIANT
163
- };
164
- }
165
- return {
166
- confirmText: DEFAULT_ALERT_TEXT,
167
- confirmVariant: DEFAULT_CONFIRM_VARIANT,
168
- ...config
169
- };
170
- };
171
- var getButtonsForDialog = (type, config) => {
172
- if (type === "confirm") {
173
- const confirmConfig = config;
174
- return [
175
- {
176
- text: confirmConfig.cancelText || DEFAULT_CANCEL_TEXT,
177
- value: "cancel",
178
- variant: confirmConfig.cancelVariant || DEFAULT_CANCEL_VARIANT
179
- },
180
- {
181
- text: confirmConfig.confirmText || DEFAULT_CONFIRM_TEXT,
182
- value: "confirm",
183
- variant: confirmConfig.confirmVariant || DEFAULT_CONFIRM_VARIANT,
184
- autoFocus: true
185
- }
186
- ];
187
- }
188
- if (type === "alert") {
189
- const alertConfig = config;
190
- return [
191
- {
192
- text: alertConfig.confirmText || DEFAULT_ALERT_TEXT,
193
- value: "confirm",
194
- variant: alertConfig.confirmVariant || DEFAULT_CONFIRM_VARIANT,
195
- autoFocus: true
196
- }
197
- ];
198
- }
199
- return [];
200
- };
201
- var processButtonResult = (type, buttonValue) => {
202
- if (type === "confirm") {
203
- return buttonValue === "confirm";
204
- }
205
- if (type === "alert") {
206
- return void 0;
207
- }
208
- return buttonValue;
209
- };
210
- var getDialogTitle = (type, config) => {
211
- if (config.title) {
212
- return config.title;
213
- }
214
- switch (type) {
215
- case "confirm":
216
- return "Confirm";
217
- case "alert":
218
- return "Alert";
219
- default:
220
- return "";
221
- }
222
- };
223
- var shouldShowCloseButton = (type, config) => {
224
- if (config.showCloseButton !== void 0) {
225
- return config.showCloseButton;
226
- }
227
- return type === "confirm";
228
- };
229
- var PORTAL_ROOT_ID = "floating-alert-root";
230
- var AlertDialog = memo(function AlertDialog2(props) {
231
- const { className, outsidePress, overlay = false, portalId = PORTAL_ROOT_ID, root } = props;
232
- const { state, _handleAction } = useAlertDialogContext();
233
- const { isOpen, type, config } = state;
234
- const { refs, context } = useFloating({
235
- open: isOpen,
236
- onOpenChange: (open) => {
237
- if (!open) {
238
- _handleAction({ type: "HIDE", payload: { value: false } });
239
- }
240
- }
241
- });
242
- useEffect(() => {
243
- if (!isOpen || !config) {
244
- return;
245
- }
246
- const handleKeyDown = (event) => {
247
- if (event.key === "Escape") {
248
- const shouldClose = config.closeOnEscape !== false;
249
- if (shouldClose) {
250
- event.stopImmediatePropagation();
251
- event.preventDefault();
252
- _handleAction({ type: "HIDE", payload: { value: false } });
253
- }
254
- }
255
- if (event.key === "Enter") {
256
- if (type === "alert") {
257
- event.preventDefault();
258
- _handleAction({ type: "HIDE", payload: { value: void 0 } });
259
- } else if (type === "confirm") {
260
- event.preventDefault();
261
- _handleAction({ type: "HIDE", payload: { value: true } });
262
- }
263
- }
264
- };
265
- window.addEventListener("keydown", handleKeyDown, { capture: true });
266
- return () => window.removeEventListener("keydown", handleKeyDown, { capture: true });
267
- }, [isOpen, config, type, _handleAction]);
268
- const handleOverlayClick = useEventCallback((event) => {
269
- if (!config) return;
270
- let shouldClose = false;
271
- if (outsidePress !== void 0) {
272
- shouldClose = outsidePress;
273
- } else {
274
- shouldClose = config.closeOnOverlayClick !== false;
275
- }
276
- if (shouldClose) {
277
- if (event.target === event.currentTarget) {
278
- _handleAction({ type: "HIDE", payload: { value: false } });
279
- }
280
- }
281
- });
282
- const handleButtonClick = useEventCallback((buttonValue) => {
283
- if (!type) return;
284
- const result = processButtonResult(type, buttonValue);
285
- _handleAction({ type: "HIDE", payload: { value: result } });
286
- });
287
- const handleCloseClick = useEventCallback(() => {
288
- _handleAction({ type: "HIDE", payload: { value: false } });
289
- });
290
- const buttons = useMemo(() => {
291
- if (!type || !config) return [];
292
- if (type === "custom") {
293
- return config.buttons;
294
- }
295
- return getButtonsForDialog(type, config);
296
- }, [type, config]);
297
- const title = useMemo(() => {
298
- if (!type || !config) return "";
299
- return getDialogTitle(type, config);
300
- }, [type, config]);
301
- const showCloseButton = useMemo(() => {
302
- if (!type || !config) return false;
303
- return shouldShowCloseButton(type, config);
304
- }, [type, config]);
305
- const tv = useMemo(() => {
306
- const variant = (config == null ? void 0 : config.variant) || "default";
307
- const size = (config == null ? void 0 : config.size) || "default";
308
- return alertDialogTv({ variant, size });
309
- }, [config == null ? void 0 : config.variant, config == null ? void 0 : config.size]);
310
- const shouldRenderContent = isOpen && config;
311
- const handleBackdropClose = useEventCallback(() => {
312
- if (!config) return;
313
- let shouldClose = false;
314
- if (outsidePress !== void 0) {
315
- shouldClose = outsidePress;
316
- } else {
317
- shouldClose = config.closeOnOverlayClick !== false;
318
- }
319
- if (shouldClose) {
320
- _handleAction({ type: "HIDE", payload: { value: false } });
321
- }
322
- });
323
- const dialogContent = shouldRenderContent && /* @__PURE__ */ jsx(
324
- FloatingFocusManager,
325
- {
326
- context,
327
- modal: true,
328
- children: /* @__PURE__ */ jsxs(
329
- Modal,
330
- {
331
- ref: refs.setFloating,
332
- className: tcx(tv.container(), className),
333
- role: "alertdialog",
334
- "aria-modal": "true",
335
- "aria-labelledby": title ? "alert-dialog-title" : void 0,
336
- "aria-describedby": "alert-dialog-description",
337
- onClick: (e) => e.stopPropagation(),
338
- children: [
339
- (title || showCloseButton) && /* @__PURE__ */ jsx(
340
- Modal.Header,
341
- {
342
- className: tv.header(),
343
- title,
344
- onClose: showCloseButton ? handleCloseClick : void 0,
345
- id: "alert-dialog-title"
346
- }
347
- ),
348
- /* @__PURE__ */ jsx(
349
- Modal.Content,
350
- {
351
- id: "alert-dialog-description",
352
- className: tv.content(),
353
- children: config.content || config.description
354
- }
355
- ),
356
- buttons.length > 0 && /* @__PURE__ */ jsx(Modal.Footer, { className: tv.footer(), children: buttons.map((button) => /* @__PURE__ */ jsx(
357
- Button,
358
- {
359
- variant: button.variant || "primary",
360
- disabled: button.disabled,
361
- onClick: () => handleButtonClick(button.value),
362
- autoFocus: button.autoFocus,
363
- children: button.text
364
- },
365
- button.value
366
- )) })
367
- ]
368
- }
369
- )
370
- }
371
- );
372
- return /* @__PURE__ */ jsx(
373
- FloatingPortal,
374
- {
375
- id: portalId,
376
- root,
377
- children: overlay ? /* @__PURE__ */ jsxs(Fragment, { children: [
378
- /* @__PURE__ */ jsx(
379
- Modal.Backdrop,
380
- {
381
- isOpen,
382
- onClose: handleBackdropClose,
383
- duration: 200
384
- }
385
- ),
386
- dialogContent && /* @__PURE__ */ jsx(
387
- FloatingOverlay,
388
- {
389
- className: tcx(tv.overlay()),
390
- lockScroll: true,
391
- onClick: handleOverlayClick,
392
- children: dialogContent
393
- }
394
- )
395
- ] }) : dialogContent && /* @__PURE__ */ jsx(
396
- FloatingOverlay,
397
- {
398
- className: tcx(tv.overlay()),
399
- onClick: handleOverlayClick,
400
- children: dialogContent
401
- }
402
- )
403
- }
404
- );
405
- });
406
- AlertDialog.displayName = "AlertDialog";
407
- var useAlertDialogProvider = () => {
408
- const [state, dispatch] = useReducer(alertDialogReducer, initialState);
409
- const handleAction = useCallback((action) => {
410
- dispatch(action);
411
- }, []);
412
- const confirm = useCallback(
413
- (config) => {
414
- return new Promise((resolve) => {
415
- const normalizedConfig = normalizeConfirmConfig(config);
416
- handleAction({
417
- type: "SHOW",
418
- payload: {
419
- dialogType: "confirm",
420
- config: normalizedConfig,
421
- resolve
422
- }
423
- });
424
- });
425
- },
426
- [handleAction]
427
- );
428
- const alert = useCallback(
429
- (config) => {
430
- return new Promise((resolve) => {
431
- const normalizedConfig = normalizeAlertConfig(config);
432
- handleAction({
433
- type: "SHOW",
434
- payload: {
435
- dialogType: "alert",
436
- config: normalizedConfig,
437
- resolve
438
- }
439
- });
440
- });
441
- },
442
- [handleAction]
443
- );
444
- const show = useCallback(
445
- (config) => {
446
- return new Promise((resolve) => {
447
- handleAction({
448
- type: "SHOW",
449
- payload: {
450
- dialogType: "custom",
451
- config,
452
- resolve
453
- }
454
- });
455
- });
456
- },
457
- [handleAction]
458
- );
459
- const closeAll = useCallback(() => {
460
- handleAction({ type: "CLEAR_QUEUE" });
461
- }, [handleAction]);
462
- return {
463
- state,
464
- confirm,
465
- alert,
466
- show,
467
- closeAll,
468
- _handleAction: handleAction
469
- };
470
- };
471
- var AlertDialogProvider = memo(function AlertDialogProvider2({
472
- children,
473
- className,
474
- overlay = false,
475
- outsidePress,
476
- portalId
477
- }) {
478
- const alertDialogContext = useAlertDialogProvider();
479
- return /* @__PURE__ */ jsxs(AlertDialogContext.Provider, { value: alertDialogContext, children: [
480
- children,
481
- /* @__PURE__ */ jsx(
482
- AlertDialog,
483
- {
484
- className,
485
- overlay,
486
- outsidePress,
487
- portalId
488
- }
489
- )
490
- ] });
491
- });
492
- AlertDialogProvider.displayName = "AlertDialogProvider";
493
- export {
494
- AlertDialog,
495
- AlertDialogProvider,
496
- useAlertDialogProvider
497
- };