@rebasepro/ui 0.17.3 → 0.18.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.
Files changed (127) hide show
  1. package/README.md +4 -0
  2. package/dist/components/MultiSelect.d.ts +10 -0
  3. package/dist/index.es.js +2 -1
  4. package/dist/index.es.js.map +1 -1
  5. package/package.json +32 -23
  6. package/src/components/Alert.tsx +0 -118
  7. package/src/components/Autocomplete.tsx +0 -93
  8. package/src/components/Avatar.tsx +0 -73
  9. package/src/components/Badge.tsx +0 -44
  10. package/src/components/BooleanSwitch.tsx +0 -116
  11. package/src/components/BooleanSwitchWithLabel.tsx +0 -120
  12. package/src/components/Button.tsx +0 -110
  13. package/src/components/Card.tsx +0 -43
  14. package/src/components/CenteredView.tsx +0 -35
  15. package/src/components/Checkbox.tsx +0 -129
  16. package/src/components/Chip.tsx +0 -131
  17. package/src/components/CircularProgress.tsx +0 -53
  18. package/src/components/CircularProgressCenter.tsx +0 -27
  19. package/src/components/Collapse.tsx +0 -66
  20. package/src/components/ColorPicker.tsx +0 -140
  21. package/src/components/Container.tsx +0 -51
  22. package/src/components/DateTimeField.tsx +0 -363
  23. package/src/components/DebouncedTextField.tsx +0 -76
  24. package/src/components/Dialog.tsx +0 -159
  25. package/src/components/DialogActions.tsx +0 -29
  26. package/src/components/DialogContent.tsx +0 -27
  27. package/src/components/DialogTitle.tsx +0 -41
  28. package/src/components/ErrorBoundary.tsx +0 -236
  29. package/src/components/ExpandablePanel.tsx +0 -130
  30. package/src/components/FileUpload.tsx +0 -103
  31. package/src/components/FilterChip.tsx +0 -89
  32. package/src/components/IconButton.tsx +0 -101
  33. package/src/components/InfoLabel.tsx +0 -23
  34. package/src/components/InputLabel.tsx +0 -40
  35. package/src/components/Label.tsx +0 -32
  36. package/src/components/LoadingButton.tsx +0 -32
  37. package/src/components/Markdown.tsx +0 -55
  38. package/src/components/Menu.tsx +0 -114
  39. package/src/components/Menubar.tsx +0 -355
  40. package/src/components/MultiSelect.tsx +0 -433
  41. package/src/components/Paper.tsx +0 -23
  42. package/src/components/Popover.tsx +0 -162
  43. package/src/components/RadioGroup.tsx +0 -74
  44. package/src/components/ResizablePanels.tsx +0 -189
  45. package/src/components/SearchBar.tsx +0 -136
  46. package/src/components/Select.tsx +0 -326
  47. package/src/components/Separator.tsx +0 -28
  48. package/src/components/Sheet.tsx +0 -135
  49. package/src/components/Skeleton.tsx +0 -54
  50. package/src/components/Slider.tsx +0 -110
  51. package/src/components/Table.tsx +0 -178
  52. package/src/components/Tabs.tsx +0 -185
  53. package/src/components/TextField.tsx +0 -270
  54. package/src/components/TextareaAutosize.tsx +0 -368
  55. package/src/components/ToggleButtonGroup.tsx +0 -69
  56. package/src/components/Tooltip.tsx +0 -153
  57. package/src/components/Typography.tsx +0 -132
  58. package/src/components/VirtualTable/VirtualTable.performance.test.tsx +0 -90
  59. package/src/components/VirtualTable/VirtualTable.tsx +0 -700
  60. package/src/components/VirtualTable/VirtualTableCell.tsx +0 -59
  61. package/src/components/VirtualTable/VirtualTableHeader.tsx +0 -327
  62. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +0 -250
  63. package/src/components/VirtualTable/VirtualTableProps.tsx +0 -339
  64. package/src/components/VirtualTable/VirtualTableRow.tsx +0 -51
  65. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +0 -44
  66. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +0 -89
  67. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +0 -71
  68. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +0 -107
  69. package/src/components/VirtualTable/fields/VirtualTableSwitch.tsx +0 -28
  70. package/src/components/VirtualTable/index.tsx +0 -10
  71. package/src/components/VirtualTable/selection/SelectionContext.tsx +0 -36
  72. package/src/components/VirtualTable/selection/SelectionStore.ts +0 -54
  73. package/src/components/VirtualTable/types.tsx +0 -47
  74. package/src/components/common/SelectInputLabel.tsx +0 -23
  75. package/src/components/index.tsx +0 -62
  76. package/src/hooks/PortalContainerContext.tsx +0 -50
  77. package/src/hooks/index.ts +0 -7
  78. package/src/hooks/useDebounceCallback.tsx +0 -21
  79. package/src/hooks/useDebounceValue.tsx +0 -20
  80. package/src/hooks/useDebouncedCallback.ts +0 -39
  81. package/src/hooks/useInjectStyles.tsx +0 -31
  82. package/src/hooks/useOutsideAlerter.tsx +0 -46
  83. package/src/icons/GitHubIcon.tsx +0 -21
  84. package/src/icons/HandleIcon.tsx +0 -23
  85. package/src/icons/Icon.tsx +0 -33
  86. package/src/icons/LucideIconByName.tsx +0 -117
  87. package/src/icons/cool_icon_keys.ts +0 -12
  88. package/src/icons/icon_keys.ts +0 -1936
  89. package/src/icons/index.ts +0 -179
  90. package/src/index.css +0 -169
  91. package/src/index.ts +0 -47
  92. package/src/scripts/fixIconSizes.cjs +0 -92
  93. package/src/scripts/fixIconSizesToConst.cjs +0 -106
  94. package/src/scripts/generateIconKeys.ts +0 -41
  95. package/src/scripts/generateIcons.ts +0 -4
  96. package/src/scripts/saveIconFiles.ts +0 -89
  97. package/src/styles.ts +0 -141
  98. package/src/theme.css +0 -168
  99. package/src/util/chip_colors.ts +0 -242
  100. package/src/util/cls.ts +0 -8
  101. package/src/util/debounce.ts +0 -28
  102. package/src/util/hash.ts +0 -11
  103. package/src/util/index.ts +0 -4
  104. package/src/util/key_to_icon_component.ts +0 -11
  105. package/src/util/lazy_chunk.ts +0 -101
  106. package/src/views/CardView.tsx +0 -281
  107. package/src/views/CollectionView/CollectionCardView.tsx +0 -265
  108. package/src/views/CollectionView/CollectionKanbanView.tsx +0 -246
  109. package/src/views/CollectionView/CollectionListView.tsx +0 -240
  110. package/src/views/CollectionView/CollectionTableView.tsx +0 -229
  111. package/src/views/CollectionView/CollectionView.tsx +0 -450
  112. package/src/views/CollectionView/CollectionViewToolbar.tsx +0 -242
  113. package/src/views/CollectionView/CollectionViewTypes.ts +0 -181
  114. package/src/views/CollectionView/DefaultCellRenderer.tsx +0 -404
  115. package/src/views/CollectionView/index.ts +0 -39
  116. package/src/views/CollectionView/resolveTitleProperty.ts +0 -52
  117. package/src/views/CollectionView/utils.ts +0 -14
  118. package/src/views/Kanban/Board.tsx +0 -384
  119. package/src/views/Kanban/BoardColumn.tsx +0 -138
  120. package/src/views/Kanban/BoardColumnTitle.tsx +0 -47
  121. package/src/views/Kanban/BoardSortableList.tsx +0 -182
  122. package/src/views/Kanban/board_types.ts +0 -80
  123. package/src/views/Kanban/index.tsx +0 -5
  124. package/src/views/Kanban/placement.ts +0 -62
  125. package/src/views/KanbanView.tsx +0 -32
  126. package/src/views/ListView.tsx +0 -296
  127. package/src/views/index.ts +0 -5
@@ -1,433 +0,0 @@
1
-
2
- "use client";
3
- import { CheckIcon, ChevronDownIcon, XIcon } from "lucide-react";
4
- import { iconSize } from "../icons/Icon";
5
- import * as PopoverPrimitive from "@radix-ui/react-popover";
6
- import * as React from "react";
7
- import { ChangeEvent, Children, useEffect, useState } from "react";
8
- import { Command as CommandPrimitive } from "cmdk";
9
- import { cls } from "../util";
10
-
11
- import { Separator } from "./Separator";
12
- import { Chip } from "./Chip";
13
- import { SelectInputLabel } from "./common/SelectInputLabel";
14
- import {
15
- defaultBorderMixin,
16
- fieldBackgroundDisabledMixin,
17
- fieldBackgroundHoverMixin,
18
- fieldBackgroundInvisibleMixin,
19
- fieldBackgroundMixin,
20
- focusedDisabled
21
- } from "../styles";
22
- import { useInjectStyles } from "../hooks";
23
- import { usePortalContainer } from "../hooks/PortalContainerContext";
24
-
25
- export type MultiSelectValue = string | number | boolean;
26
-
27
- // Make the context properly generic
28
- interface MultiSelectContextProps<T extends MultiSelectValue = string> {
29
- fieldValue?: T[];
30
- onItemClick: (v: T) => void;
31
- }
32
-
33
- // Create a proper generic context
34
- export const MultiSelectContext = React.createContext<MultiSelectContextProps<MultiSelectValue>>(null! as MultiSelectContextProps<MultiSelectValue>);
35
-
36
- /**
37
- * Props for MultiSelect component
38
- */
39
- interface MultiSelectProps<T extends MultiSelectValue = string> {
40
- modalPopover?: boolean;
41
- className?: string;
42
- open?: boolean,
43
- name?: string,
44
- id?: string,
45
- onOpenChange?: (open: boolean) => void,
46
- value?: T[],
47
- inputClassName?: string,
48
- onChange?: React.EventHandler<ChangeEvent<HTMLSelectElement>>,
49
- onValueChange?: (updatedValue: T[]) => void,
50
- placeholder?: React.ReactNode,
51
- size?: "smallest" | "small" | "medium" | "large",
52
- useChips?: boolean,
53
- label?: React.ReactNode | string,
54
- disabled?: boolean,
55
- error?: boolean,
56
- position?: "item-aligned" | "popper",
57
- endAdornment?: React.ReactNode,
58
- multiple?: boolean,
59
- includeSelectAll?: boolean,
60
- includeClear?: boolean,
61
- inputRef?: React.Ref<HTMLButtonElement>,
62
- padding?: boolean,
63
- invisible?: boolean,
64
- children: React.ReactNode;
65
- renderValues?: (values: T[]) => React.ReactNode;
66
- portalContainer?: HTMLElement | null;
67
- }
68
-
69
- // Use generic type for the forwarded ref
70
- export const MultiSelect = React.forwardRef<
71
- HTMLButtonElement,
72
- MultiSelectProps
73
- >(
74
- (
75
- {
76
- value,
77
- size = "large",
78
- label,
79
- error,
80
- onValueChange,
81
- invisible,
82
- disabled,
83
- placeholder,
84
- modalPopover = true,
85
- includeClear = true,
86
- includeSelectAll = true,
87
- useChips = true,
88
- className,
89
- inputClassName,
90
- inputRef,
91
- children,
92
- renderValues,
93
- open,
94
- onOpenChange,
95
- portalContainer
96
- },
97
- ref
98
- ) => {
99
- const [isMounted, setIsMounted] = useState(false);
100
- const [isPopoverOpen, setIsPopoverOpen] = useState(open ?? false);
101
- const [selectedValues, setSelectedValues] = useState<string[]>(value ?? []);
102
-
103
- // Get the portal container from context
104
- const contextContainer = usePortalContainer();
105
-
106
- // Prioritize manual prop, fallback to context container
107
- const finalContainer = (portalContainer ?? contextContainer ?? undefined) as HTMLElement | undefined;
108
-
109
- useEffect(() => {
110
- setIsMounted(true);
111
- }, []);
112
-
113
- const onPopoverOpenChange = (open: boolean) => {
114
- setIsPopoverOpen(open);
115
- onOpenChange?.(open);
116
- }
117
-
118
- useEffect(() => {
119
- setIsPopoverOpen(open ?? false);
120
- }, [open]);
121
-
122
- const allValues = React.useMemo(() => children
123
- ?
124
- Children.map(children, (child) => {
125
- if (React.isValidElement<MultiSelectItemProps>(child)) {
126
- return child.props.value;
127
- }
128
- return null;
129
- })?.filter(Boolean) ?? []
130
- : [], [children]);
131
-
132
- const optionsMap = React.useMemo(() => {
133
- const map = new Map<string, React.ReactNode>();
134
- Children.forEach(children, (child) => {
135
- if (React.isValidElement<MultiSelectItemProps>(child)) {
136
- map.set(String(child.props.value), child.props.children);
137
- }
138
- });
139
- return map;
140
- }, [children]);
141
-
142
- React.useEffect(() => {
143
- setSelectedValues(value ?? []);
144
- }, [value]);
145
-
146
- const updateValues = React.useCallback((values: string[]) => {
147
- setSelectedValues(values);
148
- onValueChange?.(values);
149
- }, [onValueChange]);
150
-
151
- const onItemClick = React.useCallback((newValue: MultiSelectValue) => {
152
- let newSelectedValues: string[];
153
- if (selectedValues.some(v => String(v) === String(newValue))) {
154
- newSelectedValues = selectedValues.filter(v => String(v) !== String(newValue));
155
- } else {
156
- newSelectedValues = [...selectedValues, String(newValue)];
157
- }
158
- updateValues(newSelectedValues);
159
- }, [selectedValues, updateValues]);
160
-
161
- const handleInputKeyDown = (
162
- event: React.KeyboardEvent<HTMLInputElement>
163
- ) => {
164
- if (event.key === "Enter") {
165
- onPopoverOpenChange(true);
166
- } else if (event.key === "Backspace" && !event.currentTarget.value) {
167
- const newSelectedValues = [...selectedValues];
168
- newSelectedValues.pop();
169
- updateValues(newSelectedValues);
170
- }
171
- };
172
-
173
- const toggleOption = (value: string) => {
174
- const newSelectedValues = selectedValues.some(v => String(v) === String(value))
175
- ? selectedValues.filter(v => String(v) !== String(value))
176
- : [...selectedValues, value];
177
- updateValues(newSelectedValues);
178
- };
179
-
180
- const handleClear = () => {
181
- updateValues([]);
182
- };
183
-
184
- const handleTogglePopover = () => {
185
- onPopoverOpenChange(!isPopoverOpen);
186
- };
187
-
188
- const toggleAll = () => {
189
- if (selectedValues.length === allValues.length) {
190
- handleClear();
191
- } else {
192
- updateValues(allValues);
193
- }
194
- onPopoverOpenChange(false);
195
- };
196
-
197
- // Scoped to this popover. Unscoped, it reached every other cmdk list on
198
- // the page — the relation and user selectors set their own height on
199
- // the list and got a second, competing scroll container inside it.
200
- useInjectStyles("MultiSelect", `
201
- [data-multi-select-content] [cmdk-group] {
202
- max-height: 45vh;
203
- overflow-y: auto;
204
- } `)
205
-
206
- const contextValue = React.useMemo(() => ({
207
- fieldValue: selectedValues,
208
- onItemClick
209
- }), [selectedValues, onItemClick]);
210
-
211
- return (
212
- <MultiSelectContext.Provider value={contextValue}>
213
-
214
- {typeof label === "string" ? <SelectInputLabel error={error}>{label}</SelectInputLabel> : label}
215
-
216
- <PopoverPrimitive.Root
217
- open={isMounted && isPopoverOpen}
218
- onOpenChange={onPopoverOpenChange}
219
- modal={modalPopover}
220
- >
221
- <PopoverPrimitive.Trigger asChild>
222
- <button
223
- ref={inputRef ?? ref}
224
- onClick={handleTogglePopover}
225
- className={cls(
226
- {
227
- "min-h-[28px]": size === "smallest",
228
- "min-h-[32px]": size === "small",
229
- "min-h-[40px]": size === "medium",
230
- "min-h-[48px]": size === "large"
231
- },
232
- {
233
- // Kept tight so the min-height above governs:
234
- // py-2 plus a medium Chip overflowed it and made
235
- // smallest/small render at the same height.
236
- "py-0": size === "smallest",
237
- "py-0.5": size === "small",
238
- "py-1": size === "medium" || size === "large"
239
- },
240
- {
241
- "px-2": size === "small" || size === "smallest",
242
- "px-4": size === "medium" || size === "large"
243
- },
244
- "select-none rounded-lg text-sm",
245
- "focus:ring-0 focus-visible:ring-0 outline-none focus:outline-none focus-visible:outline-none",
246
- invisible ? fieldBackgroundInvisibleMixin : fieldBackgroundMixin,
247
- disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
248
- "relative flex items-center",
249
- className,
250
- inputClassName
251
- )}
252
- >
253
- {selectedValues.length > 0 ? (
254
- <div className="flex justify-between items-center w-full">
255
- <div className="flex flex-wrap items-center gap-1.5 text-start">
256
- {renderValues && renderValues(selectedValues)}
257
- {!renderValues && selectedValues.map((value) => {
258
-
259
- const optionChildren = optionsMap.get(String(value));
260
- if (!useChips) {
261
- return optionChildren;
262
- }
263
- return (
264
- <Chip
265
- size={size === "smallest" || size === "small" ? "smallest" : "small"}
266
- key={String(value)}
267
- className={cls("flex flex-row items-center p-1")}
268
- >
269
- {optionChildren}
270
- <XIcon
271
- size={iconSize.smallest}
272
- onClick={(event) => {
273
- event.stopPropagation();
274
- toggleOption(value);
275
- }}
276
- />
277
- </Chip>
278
- );
279
- })}
280
- </div>
281
- <div className="flex items-center justify-between">
282
- {includeClear && <XIcon
283
- className={"ml-4"}
284
- size={iconSize.small}
285
- onClick={(event) => {
286
- event.stopPropagation();
287
- handleClear();
288
- }}
289
- />}
290
- <div className={cls("px-2 h-full flex items-center")}>
291
- <ChevronDownIcon size={size === "large" ? iconSize.medium : iconSize.small}
292
- className={cls("transition", isPopoverOpen ? "rotate-180" : "")}/>
293
- </div>
294
- </div>
295
- </div>
296
- ) : (
297
- <div className="flex items-center justify-between w-full mx-auto">
298
- <span className="text-sm">
299
- {placeholder}
300
- </span>
301
- <div className={cls("px-2 h-full flex items-center")}>
302
- <ChevronDownIcon size={size === "large" ? iconSize.medium : iconSize.small}
303
- className={cls("transition", isPopoverOpen ? "rotate-180" : "")}/>
304
- </div>
305
- </div>
306
- )}
307
- </button>
308
- </PopoverPrimitive.Trigger>
309
- <PopoverPrimitive.Portal container={finalContainer}>
310
- <PopoverPrimitive.Content
311
- data-multi-select-content
312
- className={cls("z-50 overflow-hidden border bg-white dark:bg-surface-800 rounded-lg w-[400px]", defaultBorderMixin)}
313
- align="start"
314
- sideOffset={8}
315
- onEscapeKeyDown={() => onPopoverOpenChange(false)}
316
- >
317
- <CommandPrimitive>
318
- <div className={"flex flex-row items-center"}>
319
- <CommandPrimitive.Input
320
- className={cls(focusedDisabled, "bg-transparent outline-none flex-1 h-full w-full m-4 flex-grow text-surface-accent-900 dark:text-white")}
321
- placeholder="Search..."
322
- onKeyDown={handleInputKeyDown}
323
- />
324
- {selectedValues.length > 0 && (
325
- <div
326
- onClick={handleClear}
327
- className="text-sm justify-center cursor-pointer py-3 px-4 text-text-secondary dark:text-text-secondary-dark">
328
- Clear
329
- </div>
330
- )}
331
- </div>
332
- <Separator orientation={"horizontal"} className={"my-0"}/>
333
- <CommandPrimitive.List>
334
- <CommandPrimitive.Empty className={"px-4 py-2 text-sm text-text-secondary dark:text-text-secondary-dark"}>
335
- No results found.
336
- </CommandPrimitive.Empty>
337
- <CommandPrimitive.Group>
338
- {includeSelectAll && <CommandPrimitive.Item
339
- key="all"
340
- onSelect={toggleAll}
341
- className={
342
- cls(
343
- "flex flex-row items-center gap-1.5",
344
- "cursor-pointer",
345
- "m-1",
346
- "ring-offset-transparent",
347
- "p-1 rounded-md aria-[selected=true]:outline-none aria-[selected=true]:ring-2 aria-[selected=true]:ring-primary aria-[selected=true]:ring-opacity-75 aria-[selected=true]:ring-primary/75 aria-[selected=true]:ring-offset-2",
348
- "aria-[selected=true]:bg-surface-accent-100 aria-[selected=true]:dark:bg-surface-accent-900",
349
- "cursor-pointer p-2 rounded-md aria-[selected=true]:bg-surface-accent-100 aria-[selected=true]:dark:bg-surface-accent-900"
350
- )
351
- }
352
- >
353
- <InnerCheckBox checked={selectedValues.length === allValues.length}/>
354
- <span className={"text-sm text-text-secondary dark:text-text-secondary-dark"}>(Select All)</span>
355
- </CommandPrimitive.Item>}
356
- {children}
357
- </CommandPrimitive.Group>
358
- </CommandPrimitive.List>
359
- </CommandPrimitive>
360
- </PopoverPrimitive.Content>
361
- </PopoverPrimitive.Portal>
362
- </PopoverPrimitive.Root>
363
- </MultiSelectContext.Provider>
364
- );
365
- }
366
- );
367
-
368
- MultiSelect.displayName = "MultiSelect";
369
-
370
- export interface MultiSelectItemProps<T extends MultiSelectValue = string> {
371
- value: T;
372
- children?: React.ReactNode,
373
- className?: string;
374
- }
375
-
376
- export const MultiSelectItem = React.memo(function MultiSelectItem<T extends MultiSelectValue = string>({
377
- children,
378
- value,
379
- className
380
- }: MultiSelectItemProps<T>) {
381
- const context = React.useContext(MultiSelectContext);
382
- if (!context) throw new Error("MultiSelectItem must be used inside a MultiSelect");
383
- const {
384
- fieldValue,
385
- onItemClick
386
- } = context;
387
-
388
- const isSelected = (fieldValue ?? []).some(v => String(v) === String(value));
389
-
390
- return <CommandPrimitive.Item
391
- onMouseDown={(e) => {
392
- e.preventDefault();
393
- e.stopPropagation();
394
- }}
395
- onSelect={(_) => {
396
- onItemClick(value);
397
- }}
398
- className={cls(
399
- "flex flex-row items-center gap-1.5",
400
- isSelected ? "bg-surface-accent-200 dark:bg-surface-accent-950" : "",
401
- "cursor-pointer",
402
- "m-1",
403
- "ring-offset-transparent",
404
- "p-1 rounded-md aria-[selected=true]:outline-none aria-[selected=true]:ring-2 aria-[selected=true]:ring-primary aria-[selected=true]:ring-opacity-75 aria-[selected=true]:ring-primary/75 aria-[selected=true]:ring-offset-2",
405
- "aria-[selected=true]:bg-surface-accent-100 aria-[selected=true]:dark:bg-surface-accent-900",
406
- "cursor-pointer p-2 rounded-md aria-[selected=true]:bg-surface-accent-100 aria-[selected=true]:dark:bg-surface-accent-900",
407
- "text-surface-accent-700 dark:text-surface-accent-300",
408
- className
409
- )}
410
- >
411
- <InnerCheckBox checked={isSelected}/>
412
- {children}
413
- </CommandPrimitive.Item>;
414
- });
415
-
416
- const InnerCheckBox = React.memo(function InnerCheckBox({ checked }: { checked: boolean }) {
417
- return <div className={cls(
418
- "p-2",
419
- "w-8 h-8",
420
- "inline-flex items-center justify-center text-sm font-medium focus:outline-none transition-colors ease-in-out duration-150"
421
- )}>
422
- <div
423
- className={cls(
424
- "border-2 relative transition-colors ease-in-out duration-150",
425
- "w-4 h-4 rounded-sm flex items-center justify-center",
426
- (checked ? "bg-primary" : "bg-white dark:bg-surface-accent-900"),
427
- (checked) ? "text-surface-accent-100 dark:text-surface-accent-900" : "",
428
- (checked ? "border-transparent" : "border-surface-accent-800 dark:border-surface-accent-200")
429
- )}>
430
- {checked && <CheckIcon size={iconSize.smallest} className={"absolute"}/>}
431
- </div>
432
- </div>
433
- });
@@ -1,23 +0,0 @@
1
- import React from "react";
2
-
3
- import { paperMixin } from "../styles";
4
- import { cls } from "../util";
5
-
6
- export function Paper({
7
- children,
8
- style,
9
- className
10
- }: {
11
- children: React.ReactNode;
12
- style?: React.CSSProperties;
13
- className?: string;
14
-
15
- }) {
16
- return (
17
- <div
18
- className={cls(paperMixin, className)}
19
- style={style}>
20
- {children}
21
- </div>
22
- )
23
- }
@@ -1,162 +0,0 @@
1
- "use client";
2
- import React from "react";
3
- import * as PopoverPrimitive from "@radix-ui/react-popover";
4
-
5
- import { paperMixin } from "../styles";
6
- import { cls } from "../util";
7
- import { useInjectStyles } from "../hooks";
8
- import { usePortalContainer } from "../hooks/PortalContainerContext";
9
-
10
- export type PopoverSide = "top" | "right" | "bottom" | "left";
11
- export type PopoverAlign = "start" | "center" | "end";
12
-
13
- export interface PopoverProps {
14
- trigger: React.ReactNode;
15
- children: React.ReactNode;
16
- open?: boolean;
17
- onOpenChange?: (open: boolean) => void;
18
- side?: PopoverSide;
19
- sideOffset?: number;
20
- align?: PopoverAlign;
21
- alignOffset?: number;
22
- arrowPadding?: number;
23
- sticky?: "partial" | "always";
24
- hideWhenDetached?: boolean;
25
- avoidCollisions?: boolean;
26
- enabled?: boolean;
27
- modal?: boolean;
28
- className?: string;
29
- portalContainer?: HTMLElement | null;
30
- onMouseEnter?: React.MouseEventHandler<HTMLDivElement>;
31
- onMouseLeave?: React.MouseEventHandler<HTMLDivElement>;
32
- }
33
-
34
- export function Popover({
35
- trigger,
36
- children,
37
- open,
38
- onOpenChange,
39
- side,
40
- sideOffset = 5,
41
- align,
42
- alignOffset,
43
- arrowPadding,
44
- sticky,
45
- hideWhenDetached,
46
- avoidCollisions,
47
- enabled = true,
48
- modal = false,
49
- portalContainer,
50
- className,
51
- onMouseEnter,
52
- onMouseLeave
53
- }: PopoverProps) {
54
-
55
- useInjectStyles("Popover", popoverStyles);
56
-
57
- // Get the portal container from context
58
- const contextContainer = usePortalContainer();
59
-
60
- // Prioritize manual prop, fallback to context container
61
- const finalContainer = (portalContainer ?? contextContainer ?? undefined) as HTMLElement | undefined;
62
-
63
- if (!enabled)
64
- return <>{trigger}</>;
65
-
66
- return <PopoverPrimitive.Root open={open}
67
- onOpenChange={onOpenChange}
68
- modal={modal}>
69
-
70
- <PopoverPrimitive.Trigger asChild>
71
- {trigger}
72
- </PopoverPrimitive.Trigger>
73
-
74
- <PopoverPrimitive.Portal container={finalContainer}>
75
- <PopoverPrimitive.Content
76
- // `z-50`, the floating layer — see the note in `Menu`. Below it
77
- // a popover opened from inside a dialog or a side panel is
78
- // painted under the thing that owns its trigger.
79
- className={cls(paperMixin,
80
- "PopoverContent z-50", className)}
81
- side={side}
82
- sideOffset={sideOffset}
83
- align={align}
84
- alignOffset={alignOffset}
85
- arrowPadding={arrowPadding}
86
- sticky={sticky}
87
- hideWhenDetached={hideWhenDetached}
88
- avoidCollisions={avoidCollisions}
89
- onMouseEnter={onMouseEnter}
90
- onMouseLeave={onMouseLeave}>
91
-
92
- {children}
93
- <PopoverPrimitive.Arrow className="fill-white dark:fill-surface-900"/>
94
- </PopoverPrimitive.Content>
95
- </PopoverPrimitive.Portal>
96
- </PopoverPrimitive.Root>;
97
- }
98
-
99
- const popoverStyles = `
100
- /* ... (styles remain unchanged) ... */
101
- .PopoverContent {
102
- animation-duration: 400ms;
103
- animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
104
- will-change: transform, opacity;
105
- }
106
- .PopoverContent[data-state='open'][data-side='top'] {
107
- animation-name: slideDownAndFade;
108
- }
109
- .PopoverContent[data-state='open'][data-side='right'] {
110
- animation-name: slideLeftAndFade;
111
- }
112
- .PopoverContent[data-state='open'][data-side='bottom'] {
113
- animation-name: slideUpAndFade;
114
- }
115
- .PopoverContent[data-state='open'][data-side='left'] {
116
- animation-name: slideRightAndFade;
117
- }
118
-
119
- @keyframes slideUpAndFade {
120
- from {
121
- opacity: 0;
122
- transform: translateY(2px);
123
- }
124
- to {
125
- opacity: 1;
126
- transform: translateY(0);
127
- }
128
- }
129
-
130
- @keyframes slideRightAndFade {
131
- from {
132
- opacity: 0;
133
- transform: translateX(-2px);
134
- }
135
- to {
136
- opacity: 1;
137
- transform: translateX(0);
138
- }
139
- }
140
-
141
- @keyframes slideDownAndFade {
142
- from {
143
- opacity: 0;
144
- transform: translateY(-2px);
145
- }
146
- to {
147
- opacity: 1;
148
- transform: translateY(0);
149
- }
150
- }
151
-
152
- @keyframes slideLeftAndFade {
153
- from {
154
- opacity: 0;
155
- transform: translateX(2px);
156
- }
157
- to {
158
- opacity: 1;
159
- transform: translateX(0);
160
- }
161
- }
162
- `;
@@ -1,74 +0,0 @@
1
- "use client";
2
- import * as React from "react"
3
- import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"
4
- import { cls } from "../util";
5
-
6
- export interface RadioGroupProps {
7
- id?: string;
8
- children: React.ReactNode;
9
- name?: string
10
- required?: boolean;
11
- disabled?: boolean;
12
- /**
13
- * Whether keyboard navigation should loop around
14
- * @defaultValue false
15
- */
16
- loop?: boolean;
17
- defaultValue?: string;
18
- value?: string;
19
-
20
- onValueChange?(value: string): void;
21
-
22
- className?: string;
23
- }
24
-
25
- const RadioGroup = React.forwardRef<
26
- React.ElementRef<typeof RadioGroupPrimitive.Root>,
27
- RadioGroupProps
28
- >(({
29
- className,
30
- ...props
31
- }, ref) => {
32
- return (
33
- <RadioGroupPrimitive.Root
34
- className={cls("grid gap-2", className)}
35
- {...props}
36
- ref={ref}
37
- />
38
- )
39
- })
40
- RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
41
-
42
- export interface RadioGroupItemProps {
43
- id?: string;
44
- value: string;
45
- checked?: boolean;
46
- required?: boolean;
47
- className?: string;
48
- disabled?: boolean;
49
- }
50
- const RadioGroupItem = React.forwardRef<
51
- React.ElementRef<typeof RadioGroupPrimitive.Item>,
52
- RadioGroupItemProps
53
- >(({
54
- className,
55
- ...props
56
- }, ref) => {
57
- return (
58
- <RadioGroupPrimitive.Item
59
- ref={ref}
60
- className={cls(
61
- "aspect-square h-4 w-4 rounded-full border border-primary text-primary focus:outline-hidden focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
62
- className
63
- )}
64
- {...props}
65
- >
66
- <RadioGroupPrimitive.Indicator className="flex items-center justify-center">
67
- <div className="h-2.5 w-2.5 fill-current text-current bg-primary rounded-full"/>
68
- </RadioGroupPrimitive.Indicator>
69
- </RadioGroupPrimitive.Item>
70
- )
71
- })
72
- RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
73
-
74
- export { RadioGroup, RadioGroupItem }