@dust-tt/sparkle 0.2.288 → 0.2.289-rc-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 (57) hide show
  1. package/dist/cjs/index.js +59763 -59984
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/esm/components/Breadcrumbs.d.ts.map +1 -1
  4. package/dist/esm/components/Breadcrumbs.js +7 -4
  5. package/dist/esm/components/Breadcrumbs.js.map +1 -1
  6. package/dist/esm/components/Button.d.ts +1 -1
  7. package/dist/esm/components/Button.d.ts.map +1 -1
  8. package/dist/esm/components/Button.js +3 -3
  9. package/dist/esm/components/Button.js.map +1 -1
  10. package/dist/esm/components/DataTable.d.ts +3 -3
  11. package/dist/esm/components/DataTable.d.ts.map +1 -1
  12. package/dist/esm/components/DataTable.js +5 -4
  13. package/dist/esm/components/DataTable.js.map +1 -1
  14. package/dist/esm/components/IconButton.d.ts +3 -3
  15. package/dist/esm/components/IconButton.d.ts.map +1 -1
  16. package/dist/esm/components/IconButton.js +9 -12
  17. package/dist/esm/components/IconButton.js.map +1 -1
  18. package/dist/esm/components/NewDropdown.d.ts +1 -1
  19. package/dist/esm/components/NewDropdown.d.ts.map +1 -1
  20. package/dist/esm/components/index.d.ts +1 -1
  21. package/dist/esm/components/index.d.ts.map +1 -1
  22. package/dist/esm/components/index.js +0 -1
  23. package/dist/esm/components/index.js.map +1 -1
  24. package/dist/esm/stories/DataTable.stories.d.ts.map +1 -1
  25. package/dist/esm/stories/DataTable.stories.js +1 -1
  26. package/dist/esm/stories/DataTable.stories.js.map +1 -1
  27. package/dist/esm/stories/IconButton.stories.d.ts +11 -2
  28. package/dist/esm/stories/IconButton.stories.d.ts.map +1 -1
  29. package/dist/esm/stories/IconButton.stories.js +0 -3
  30. package/dist/esm/stories/IconButton.stories.js.map +1 -1
  31. package/dist/esm/stories/Item.stories.d.ts.map +1 -1
  32. package/dist/esm/stories/Item.stories.js +24 -18
  33. package/dist/esm/stories/Item.stories.js.map +1 -1
  34. package/dist/esm/stories/Tabs.stories.d.ts.map +1 -1
  35. package/dist/esm/stories/Tabs.stories.js.map +1 -1
  36. package/dist/sparkle.css +0 -106
  37. package/package.json +1 -1
  38. package/src/components/Breadcrumbs.tsx +26 -19
  39. package/src/components/Button.tsx +4 -4
  40. package/src/components/DataTable.tsx +22 -15
  41. package/src/components/IconButton.tsx +44 -46
  42. package/src/components/NewDropdown.tsx +1 -1
  43. package/src/components/index.ts +1 -1
  44. package/src/stories/DataTable.stories.tsx +6 -3
  45. package/src/stories/IconButton.stories.tsx +0 -3
  46. package/src/stories/Item.stories.tsx +70 -52
  47. package/src/stories/Tabs.stories.tsx +6 -1
  48. package/dist/esm/components/DropdownMenu.d.ts +0 -59
  49. package/dist/esm/components/DropdownMenu.d.ts.map +0 -1
  50. package/dist/esm/components/DropdownMenu.js +0 -214
  51. package/dist/esm/components/DropdownMenu.js.map +0 -1
  52. package/dist/esm/stories/DropdownMenu.stories.d.ts +0 -9
  53. package/dist/esm/stories/DropdownMenu.stories.d.ts.map +0 -1
  54. package/dist/esm/stories/DropdownMenu.stories.js +0 -223
  55. package/dist/esm/stories/DropdownMenu.stories.js.map +0 -1
  56. package/src/components/DropdownMenu.tsx +0 -521
  57. package/src/stories/DropdownMenu.stories.tsx +0 -518
@@ -1,521 +0,0 @@
1
- import { Menu, Transition } from "@headlessui/react";
2
- import React, {
3
- ComponentType,
4
- forwardRef,
5
- Fragment,
6
- JSXElementConstructor,
7
- MouseEvent,
8
- MutableRefObject,
9
- ReactElement,
10
- useContext,
11
- useEffect,
12
- useRef,
13
- useState,
14
- } from "react";
15
-
16
- import {
17
- ChevronDownIcon,
18
- ChevronRightIcon,
19
- ChevronUpDownIcon,
20
- } from "@sparkle/icons/solid";
21
- import { classNames } from "@sparkle/lib/utils";
22
-
23
- import { Icon } from "./Icon";
24
- import { Item as StandardItem, LinkProps } from "./Item";
25
- import { Tooltip } from "./Tooltip";
26
-
27
- const ButtonRefContext =
28
- React.createContext<MutableRefObject<HTMLButtonElement | null> | null>(null);
29
-
30
- const labelClasses = {
31
- base: "s-text-element-900 s-inline-flex s-transition-colors s-ease-out s-duration-400 s-box-border s-gap-x-2 s-select-none",
32
- hover: "group-hover/dm:s-text-action-500",
33
- active: "active:s-text-action-700",
34
- dark: {
35
- base: "dark:s-text-element-900-dark",
36
- hover: "dark:group-hover/dm:s-text-action-400",
37
- active: "dark:active:s-text-action-600",
38
- disabled: "dark:s-element-500-dark",
39
- },
40
- disabled: "s-opacity-50",
41
- };
42
-
43
- const labelSizeClasses = {
44
- sm: "s-text-sm",
45
- md: "s-text-base",
46
- };
47
-
48
- const iconClasses = {
49
- base: "s-text-element-700 s-transition-colors s-ease-out s-duration-400",
50
- hover: "group-hover/dm:s-text-action-500",
51
- active: "active:s-text-action-700",
52
- disabled: "s-opacity-50",
53
- dark: {
54
- base: "dark:s-text-element-700-dark",
55
- hover: "dark:group-hover/dm:s-text-action-500-dark",
56
- active: "dark:active:s-text-action-600",
57
- },
58
- };
59
-
60
- const chevronClasses = {
61
- base: "s-text-element-600 s-mt-0.5",
62
- hover: "group-hover/dm:s-text-action-400",
63
- disabled: "s-element-500",
64
- dark: {
65
- base: "dark:s-text-element-600-dark",
66
- hover: "dark:group-hover/dm:s-text-action-500-dark",
67
- disabled: "dark:s-element-500-dark",
68
- },
69
- };
70
-
71
- export interface DropdownMenuProps {
72
- className?: string;
73
- children:
74
- | React.ReactNode
75
- | (({
76
- close,
77
- }: {
78
- close: () => void;
79
- }) => ReactElement<unknown, string | JSXElementConstructor<unknown>>);
80
- }
81
-
82
- export function DropdownMenu({ children, className = "" }: DropdownMenuProps) {
83
- const buttonRef = useRef(null);
84
- return (
85
- <ButtonRefContext.Provider value={buttonRef}>
86
- <Menu
87
- as="div"
88
- className={classNames(className, "s-relative s-inline-block")}
89
- >
90
- {children}
91
- </Menu>
92
- </ButtonRefContext.Provider>
93
- );
94
- }
95
-
96
- export interface DropdownButtonProps {
97
- label?: string;
98
- type?: "menu" | "submenu" | "select";
99
- size?: "sm" | "md";
100
- tooltip?: string;
101
- tooltipPosition?: React.ComponentProps<typeof Tooltip>["side"];
102
- icon?: ComponentType;
103
- className?: string;
104
- disabled?: boolean;
105
- children?: React.ReactNode;
106
- ref?: React.Ref<HTMLButtonElement>;
107
- onClick?: () => void;
108
- }
109
-
110
- DropdownMenu.Button = forwardRef<HTMLButtonElement, DropdownButtonProps>(
111
- function DropdownMenuButton(
112
- {
113
- label,
114
- type = "menu",
115
- size = "sm",
116
- tooltip,
117
- icon,
118
- children,
119
- tooltipPosition = "top",
120
- className = "",
121
- disabled = false,
122
- onClick,
123
- },
124
- forwardedRef
125
- ) {
126
- const contextRef = useContext(ButtonRefContext);
127
-
128
- const finalLabelClasses = classNames(
129
- labelClasses.base,
130
- labelSizeClasses[size],
131
- labelClasses.dark.base,
132
- !disabled ? labelClasses.active : "",
133
- !disabled ? labelClasses.dark.active : "",
134
- !disabled ? labelClasses.hover : "",
135
- !disabled ? labelClasses.dark.hover : "",
136
- disabled ? labelClasses.disabled : ""
137
- );
138
-
139
- const finalIconClasses = classNames(
140
- iconClasses.base,
141
- iconClasses.dark.base,
142
- !disabled ? iconClasses.hover : "",
143
- !disabled ? iconClasses.dark.hover : "",
144
- disabled ? iconClasses.disabled : ""
145
- );
146
-
147
- const finalChevronClasses = classNames(
148
- chevronClasses.base,
149
- !disabled ? chevronClasses.hover : "",
150
- chevronClasses.dark.base,
151
- !disabled ? chevronClasses.dark.hover : "",
152
- disabled ? chevronClasses.disabled : ""
153
- );
154
-
155
- const aggregatedRef = (value: HTMLButtonElement) => {
156
- if (contextRef) {
157
- contextRef.current = value;
158
- }
159
- if (typeof forwardedRef === "function") {
160
- forwardedRef(value);
161
- } else if (forwardedRef) {
162
- forwardedRef.current = value;
163
- }
164
- };
165
-
166
- if (children) {
167
- return (
168
- <Menu.Button
169
- as="div"
170
- disabled={disabled}
171
- ref={aggregatedRef}
172
- className={classNames(
173
- disabled ? "s-cursor-default" : "s-cursor-pointer",
174
- className,
175
- "s-group/dm s-flex s-justify-items-center s-text-sm s-font-medium focus:s-outline-none focus:s-ring-0",
176
- label ? "s-gap-1.5" : "s-gap-0"
177
- )}
178
- onClick={(e) => e.stopPropagation()}
179
- >
180
- {tooltip ? (
181
- <Tooltip
182
- trigger={children}
183
- label={tooltip}
184
- side={tooltipPosition}
185
- />
186
- ) : (
187
- children
188
- )}
189
- </Menu.Button>
190
- );
191
- }
192
-
193
- const chevronIcon =
194
- type === "select"
195
- ? ChevronUpDownIcon
196
- : type === "submenu"
197
- ? ChevronRightIcon
198
- : ChevronDownIcon;
199
-
200
- return (
201
- <>
202
- {tooltip ? (
203
- <Tooltip
204
- trigger={
205
- <Menu.Button
206
- disabled={disabled}
207
- ref={aggregatedRef}
208
- className={classNames(
209
- disabled ? "s-cursor-default" : "s-cursor-pointer",
210
- className,
211
- "s-group/dm s-flex s-justify-items-center s-text-sm s-font-medium focus:s-outline-none focus:s-ring-0",
212
- label
213
- ? size === "md"
214
- ? "s-gap-2"
215
- : "s-gap-1.5"
216
- : "s-gap-0.5"
217
- )}
218
- onClick={(e) => {
219
- e.stopPropagation();
220
- if (onClick) {
221
- onClick();
222
- }
223
- }}
224
- >
225
- <Icon visual={icon} size={size} className={finalIconClasses} />
226
- <Icon
227
- visual={chevronIcon}
228
- size={size === "sm" ? "xs" : "sm"}
229
- className={finalChevronClasses}
230
- />
231
- </Menu.Button>
232
- }
233
- tooltipTriggerAsChild
234
- label={tooltip}
235
- side={tooltipPosition}
236
- />
237
- ) : (
238
- <Menu.Button
239
- disabled={disabled}
240
- ref={aggregatedRef}
241
- className={classNames(
242
- disabled ? "s-cursor-default" : "s-cursor-pointer",
243
- className,
244
- "s-group/dm s-flex s-justify-items-center s-text-sm s-font-medium focus:s-outline-none focus:s-ring-0",
245
- label ? (size === "md" ? "s-gap-2" : "s-gap-1.5") : "s-gap-0.5",
246
- type === "submenu" ? "s-opacity-50" : ""
247
- )}
248
- onClick={(e) => {
249
- e.stopPropagation();
250
- if (onClick) {
251
- onClick();
252
- }
253
- }}
254
- >
255
- <Icon visual={icon} size={size} className={finalIconClasses} />
256
- <span
257
- className={classNames(
258
- finalLabelClasses,
259
- type === "submenu" ? "s-w-full" : ""
260
- )}
261
- >
262
- {label}
263
- </span>
264
- <Icon
265
- visual={chevronIcon}
266
- size={size === "sm" ? "xs" : "sm"}
267
- className={finalChevronClasses}
268
- />
269
- </Menu.Button>
270
- )}
271
- </>
272
- );
273
- }
274
- );
275
-
276
- export interface DropdownItemProps {
277
- children?: React.ReactNode;
278
- description?: string;
279
- disabled?: boolean;
280
- hasChildren?: boolean;
281
- icon?: ComponentType;
282
- label: string;
283
- link?: LinkProps;
284
- onClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
285
- selected?: boolean;
286
- variant?: "default" | "warning";
287
- visual?: string | React.ReactNode;
288
- }
289
-
290
- DropdownMenu.Item = function ({
291
- variant = "default",
292
- label,
293
- description,
294
- link,
295
- disabled,
296
- visual,
297
- icon,
298
- onClick,
299
- hasChildren,
300
- children,
301
- selected = false,
302
- }: DropdownItemProps) {
303
- return (
304
- // need to use as="div" -- otherwise we get a "forwardRef" error in the console
305
- <Menu.Item disabled={disabled} as="div">
306
- {hasChildren ? (
307
- <DropdownMenu className="s-w-full s-gap-x-2 s-py-2">
308
- <DropdownMenu.Button
309
- className="s-w-full"
310
- disabled={disabled}
311
- label={label}
312
- type="submenu"
313
- />
314
- {children}
315
- </DropdownMenu>
316
- ) : (
317
- <StandardItem.Dropdown
318
- className="s-w-full"
319
- description={description}
320
- disabled={disabled}
321
- link={link}
322
- icon={icon}
323
- label={label}
324
- onClick={onClick}
325
- selected={selected}
326
- style={variant}
327
- visual={visual}
328
- />
329
- )}
330
- </Menu.Item>
331
- );
332
- };
333
-
334
- interface DropdownSectionHeaderProps {
335
- label: string;
336
- }
337
-
338
- DropdownMenu.SectionHeader = function ({ label }: DropdownSectionHeaderProps) {
339
- return (
340
- // need to use as="div" -- otherwise we get a "forwardRef" error in the console
341
- <Menu.Item as="div">
342
- <div
343
- className={classNames(
344
- "s-w-full",
345
- "s-text-element-600 dark:s-text-element-600-dark",
346
- "s-pb-3 s-pt-4 s-text-xs s-font-medium s-uppercase"
347
- )}
348
- >
349
- {label}
350
- </div>
351
- </Menu.Item>
352
- );
353
- };
354
-
355
- type ItemsVariantType = "default" | "no-padding";
356
-
357
- const classNamesForVariant = (
358
- variant: ItemsVariantType,
359
- hasDropdownItem: boolean
360
- ) => {
361
- switch (variant) {
362
- case "no-padding":
363
- return "";
364
-
365
- case "default":
366
- return `s-px-5 ${hasDropdownItem ? "s-py-1.5" : "s-py-4"}`;
367
- }
368
- };
369
-
370
- interface DropdownItemsProps {
371
- origin?: "topLeft" | "topRight" | "bottomLeft" | "bottomRight" | "auto";
372
- width?: number;
373
- marginLeft?: number;
374
- children: React.ReactNode;
375
- topBar?: React.ReactNode;
376
- bottomBar?: React.ReactNode;
377
- onKeyDown?: (e: React.KeyboardEvent) => void;
378
- overflow?: "visible" | "auto";
379
- variant?: ItemsVariantType;
380
- }
381
-
382
- DropdownMenu.Items = function ({
383
- origin = "auto",
384
- width = 160,
385
- marginLeft,
386
- children,
387
- topBar,
388
- bottomBar,
389
- onKeyDown,
390
- overflow = "auto",
391
- variant = "default",
392
- }: DropdownItemsProps) {
393
- const buttonRef = useContext(ButtonRefContext);
394
- const [buttonHeight, setButtonHeight] = useState(0);
395
-
396
- if (origin === "auto") {
397
- origin = findOriginFromButton(buttonRef);
398
- }
399
- useEffect(() => {
400
- if (buttonRef && buttonRef.current) {
401
- setButtonHeight(buttonRef.current.offsetHeight);
402
- }
403
- }, []);
404
-
405
- // Check if any child is a Dropdown.Item
406
- const hasDropdownItem = React.Children.toArray(children).some(
407
- (child) =>
408
- React.isValidElement(child) &&
409
- (child.type === DropdownMenu.Item || child.props?.hasChildren)
410
- );
411
-
412
- const getOriginClass = (origin: string) => {
413
- switch (origin) {
414
- case "topLeft":
415
- return `s-origin-top-left s-left-0`;
416
- case "topRight":
417
- return `s-origin-top-right s-right-0`;
418
- case "bottomLeft":
419
- return "s-origin-bottom-left s-left-0 s-bottom-6";
420
- case "bottomRight":
421
- return "s-origin-bottom-right s-right-0 s-bottom-6";
422
- default:
423
- return "s-origin-top-right";
424
- }
425
- };
426
-
427
- const getOriginTransClass = (origin: string) => {
428
- switch (origin) {
429
- case "topLeft":
430
- return "s-transform s-opacity-0 s-scale-95 -s-translate-y-5";
431
- case "topRight":
432
- return "s-transform s-opacity-0 s-scale-95 -s-translate-y-5";
433
- case "bottomLeft":
434
- return "s-transform s-opacity-0 s-scale-95 s-translate-y-5";
435
- case "bottomRight":
436
- return "s-transform s-opacity-0 s-scale-95 s-translate-y-5";
437
- default:
438
- return "s-origin-top-right";
439
- }
440
- };
441
-
442
- const getOverflowClass = (overflow: string) => {
443
- switch (overflow) {
444
- case "visible":
445
- return "s-overflow-visible";
446
- case "auto":
447
- return "s-max-h-[344px] s-overflow-auto";
448
- default:
449
- return "s-max-h-[344px] s-overflow-auto";
450
- }
451
- };
452
-
453
- const styleInsert = (origin: string, marginLeft?: number) => {
454
- const style: { width: string; top?: string; left?: string } = {
455
- width: `${width}px`,
456
- };
457
-
458
- if (marginLeft) {
459
- style["left"] = `${marginLeft}px`;
460
- }
461
-
462
- if (origin === "topLeft" || origin === "topRight") {
463
- style["top"] = `${buttonHeight + 8}px`;
464
- }
465
-
466
- return style;
467
- };
468
-
469
- return (
470
- <Transition
471
- as={Fragment}
472
- enter="s-transition s-ease-out s-duration-200"
473
- enterFrom={getOriginTransClass(origin)}
474
- enterTo="s-transform s-opacity-100 s-scale-100 s-translate-y-0"
475
- leave="s-transition s-ease-in s-duration-75"
476
- leaveFrom="s-transform s-opacity-100 s-scale-100 s-translate-y-0"
477
- leaveTo={getOriginTransClass(origin)}
478
- >
479
- <Menu.Items
480
- onKeyDown={onKeyDown}
481
- className={classNames(
482
- "s-absolute s-z-10",
483
- getOriginClass(origin),
484
- "s-rounded-xl s-border s-border-structure-100 s-bg-structure-0 s-shadow-lg focus:s-outline-none dark:s-border-structure-100-dark dark:s-bg-structure-0-dark"
485
- )}
486
- onClick={(e) => e.stopPropagation()}
487
- style={styleInsert(origin, marginLeft)}
488
- >
489
- {topBar}
490
- <div
491
- className={classNames(
492
- classNamesForVariant(variant, hasDropdownItem),
493
- getOverflowClass(overflow)
494
- )}
495
- >
496
- <StandardItem.List>{children}</StandardItem.List>
497
- </div>
498
- {bottomBar}
499
- </Menu.Items>
500
- </Transition>
501
- );
502
- };
503
-
504
- function findOriginFromButton(
505
- buttonRef: MutableRefObject<HTMLButtonElement | null> | null
506
- ) {
507
- if (!buttonRef) {
508
- return "topRight";
509
- }
510
- const buttonRect = buttonRef.current?.getBoundingClientRect();
511
- if (!buttonRect) {
512
- return "topRight";
513
- }
514
- const windowHeight = window.innerHeight;
515
- // Top half of screen
516
- if (buttonRect.top < windowHeight / 2) {
517
- return buttonRect.left < window.innerWidth / 2 ? "topLeft" : "topRight";
518
- }
519
- // Bottom half of screen
520
- return buttonRect.left < window.innerWidth / 2 ? "bottomLeft" : "bottomRight";
521
- }