@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.
- package/README.md +4 -0
- package/dist/components/MultiSelect.d.ts +10 -0
- package/dist/index.es.js +2 -1
- package/dist/index.es.js.map +1 -1
- package/package.json +32 -23
- package/src/components/Alert.tsx +0 -118
- package/src/components/Autocomplete.tsx +0 -93
- package/src/components/Avatar.tsx +0 -73
- package/src/components/Badge.tsx +0 -44
- package/src/components/BooleanSwitch.tsx +0 -116
- package/src/components/BooleanSwitchWithLabel.tsx +0 -120
- package/src/components/Button.tsx +0 -110
- package/src/components/Card.tsx +0 -43
- package/src/components/CenteredView.tsx +0 -35
- package/src/components/Checkbox.tsx +0 -129
- package/src/components/Chip.tsx +0 -131
- package/src/components/CircularProgress.tsx +0 -53
- package/src/components/CircularProgressCenter.tsx +0 -27
- package/src/components/Collapse.tsx +0 -66
- package/src/components/ColorPicker.tsx +0 -140
- package/src/components/Container.tsx +0 -51
- package/src/components/DateTimeField.tsx +0 -363
- package/src/components/DebouncedTextField.tsx +0 -76
- package/src/components/Dialog.tsx +0 -159
- package/src/components/DialogActions.tsx +0 -29
- package/src/components/DialogContent.tsx +0 -27
- package/src/components/DialogTitle.tsx +0 -41
- package/src/components/ErrorBoundary.tsx +0 -236
- package/src/components/ExpandablePanel.tsx +0 -130
- package/src/components/FileUpload.tsx +0 -103
- package/src/components/FilterChip.tsx +0 -89
- package/src/components/IconButton.tsx +0 -101
- package/src/components/InfoLabel.tsx +0 -23
- package/src/components/InputLabel.tsx +0 -40
- package/src/components/Label.tsx +0 -32
- package/src/components/LoadingButton.tsx +0 -32
- package/src/components/Markdown.tsx +0 -55
- package/src/components/Menu.tsx +0 -114
- package/src/components/Menubar.tsx +0 -355
- package/src/components/MultiSelect.tsx +0 -433
- package/src/components/Paper.tsx +0 -23
- package/src/components/Popover.tsx +0 -162
- package/src/components/RadioGroup.tsx +0 -74
- package/src/components/ResizablePanels.tsx +0 -189
- package/src/components/SearchBar.tsx +0 -136
- package/src/components/Select.tsx +0 -326
- package/src/components/Separator.tsx +0 -28
- package/src/components/Sheet.tsx +0 -135
- package/src/components/Skeleton.tsx +0 -54
- package/src/components/Slider.tsx +0 -110
- package/src/components/Table.tsx +0 -178
- package/src/components/Tabs.tsx +0 -185
- package/src/components/TextField.tsx +0 -270
- package/src/components/TextareaAutosize.tsx +0 -368
- package/src/components/ToggleButtonGroup.tsx +0 -69
- package/src/components/Tooltip.tsx +0 -153
- package/src/components/Typography.tsx +0 -132
- package/src/components/VirtualTable/VirtualTable.performance.test.tsx +0 -90
- package/src/components/VirtualTable/VirtualTable.tsx +0 -700
- package/src/components/VirtualTable/VirtualTableCell.tsx +0 -59
- package/src/components/VirtualTable/VirtualTableHeader.tsx +0 -327
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +0 -250
- package/src/components/VirtualTable/VirtualTableProps.tsx +0 -339
- package/src/components/VirtualTable/VirtualTableRow.tsx +0 -51
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +0 -44
- package/src/components/VirtualTable/fields/VirtualTableInput.tsx +0 -89
- package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +0 -71
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +0 -107
- package/src/components/VirtualTable/fields/VirtualTableSwitch.tsx +0 -28
- package/src/components/VirtualTable/index.tsx +0 -10
- package/src/components/VirtualTable/selection/SelectionContext.tsx +0 -36
- package/src/components/VirtualTable/selection/SelectionStore.ts +0 -54
- package/src/components/VirtualTable/types.tsx +0 -47
- package/src/components/common/SelectInputLabel.tsx +0 -23
- package/src/components/index.tsx +0 -62
- package/src/hooks/PortalContainerContext.tsx +0 -50
- package/src/hooks/index.ts +0 -7
- package/src/hooks/useDebounceCallback.tsx +0 -21
- package/src/hooks/useDebounceValue.tsx +0 -20
- package/src/hooks/useDebouncedCallback.ts +0 -39
- package/src/hooks/useInjectStyles.tsx +0 -31
- package/src/hooks/useOutsideAlerter.tsx +0 -46
- package/src/icons/GitHubIcon.tsx +0 -21
- package/src/icons/HandleIcon.tsx +0 -23
- package/src/icons/Icon.tsx +0 -33
- package/src/icons/LucideIconByName.tsx +0 -117
- package/src/icons/cool_icon_keys.ts +0 -12
- package/src/icons/icon_keys.ts +0 -1936
- package/src/icons/index.ts +0 -179
- package/src/index.css +0 -169
- package/src/index.ts +0 -47
- package/src/scripts/fixIconSizes.cjs +0 -92
- package/src/scripts/fixIconSizesToConst.cjs +0 -106
- package/src/scripts/generateIconKeys.ts +0 -41
- package/src/scripts/generateIcons.ts +0 -4
- package/src/scripts/saveIconFiles.ts +0 -89
- package/src/styles.ts +0 -141
- package/src/theme.css +0 -168
- package/src/util/chip_colors.ts +0 -242
- package/src/util/cls.ts +0 -8
- package/src/util/debounce.ts +0 -28
- package/src/util/hash.ts +0 -11
- package/src/util/index.ts +0 -4
- package/src/util/key_to_icon_component.ts +0 -11
- package/src/util/lazy_chunk.ts +0 -101
- package/src/views/CardView.tsx +0 -281
- package/src/views/CollectionView/CollectionCardView.tsx +0 -265
- package/src/views/CollectionView/CollectionKanbanView.tsx +0 -246
- package/src/views/CollectionView/CollectionListView.tsx +0 -240
- package/src/views/CollectionView/CollectionTableView.tsx +0 -229
- package/src/views/CollectionView/CollectionView.tsx +0 -450
- package/src/views/CollectionView/CollectionViewToolbar.tsx +0 -242
- package/src/views/CollectionView/CollectionViewTypes.ts +0 -181
- package/src/views/CollectionView/DefaultCellRenderer.tsx +0 -404
- package/src/views/CollectionView/index.ts +0 -39
- package/src/views/CollectionView/resolveTitleProperty.ts +0 -52
- package/src/views/CollectionView/utils.ts +0 -14
- package/src/views/Kanban/Board.tsx +0 -384
- package/src/views/Kanban/BoardColumn.tsx +0 -138
- package/src/views/Kanban/BoardColumnTitle.tsx +0 -47
- package/src/views/Kanban/BoardSortableList.tsx +0 -182
- package/src/views/Kanban/board_types.ts +0 -80
- package/src/views/Kanban/index.tsx +0 -5
- package/src/views/Kanban/placement.ts +0 -62
- package/src/views/KanbanView.tsx +0 -32
- package/src/views/ListView.tsx +0 -296
- package/src/views/index.ts +0 -5
package/src/components/Sheet.tsx
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React, { useEffect, useState } from "react";
|
|
3
|
-
import { cls } from "../util";
|
|
4
|
-
import { defaultBorderMixin } from "../styles";
|
|
5
|
-
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
6
|
-
import { usePortalContainer, PortalContainerProvider } from "../hooks/PortalContainerContext";
|
|
7
|
-
|
|
8
|
-
interface SheetProps {
|
|
9
|
-
children: React.ReactNode;
|
|
10
|
-
open: boolean;
|
|
11
|
-
title?: string;
|
|
12
|
-
modal?: boolean;
|
|
13
|
-
includeBackgroundOverlay?: boolean;
|
|
14
|
-
side?: "top" | "bottom" | "left" | "right";
|
|
15
|
-
darkBackground?: boolean;
|
|
16
|
-
transparent?: boolean;
|
|
17
|
-
onOpenChange?: (open: boolean) => void;
|
|
18
|
-
onPointerDownOutside?: (e: Event) => void;
|
|
19
|
-
onInteractOutside?: (e: Event) => void;
|
|
20
|
-
className?: string;
|
|
21
|
-
style?: React.CSSProperties;
|
|
22
|
-
overlayClassName?: string;
|
|
23
|
-
overlayZIndex?: string;
|
|
24
|
-
overlayStyle?: React.CSSProperties;
|
|
25
|
-
portalContainer?: HTMLElement | null;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const Sheet: React.FC<SheetProps> = ({
|
|
29
|
-
children,
|
|
30
|
-
side = "right",
|
|
31
|
-
title,
|
|
32
|
-
modal = true,
|
|
33
|
-
includeBackgroundOverlay = true,
|
|
34
|
-
open,
|
|
35
|
-
onOpenChange,
|
|
36
|
-
onPointerDownOutside,
|
|
37
|
-
onInteractOutside,
|
|
38
|
-
transparent,
|
|
39
|
-
className,
|
|
40
|
-
style,
|
|
41
|
-
overlayClassName,
|
|
42
|
-
overlayZIndex = "z-50",
|
|
43
|
-
overlayStyle,
|
|
44
|
-
portalContainer,
|
|
45
|
-
...props
|
|
46
|
-
}) => {
|
|
47
|
-
const [displayed, setDisplayed] = useState(false);
|
|
48
|
-
const [contentEl, setContentEl] = useState<HTMLDivElement | null>(null);
|
|
49
|
-
|
|
50
|
-
// Get the portal container from context
|
|
51
|
-
const contextContainer = usePortalContainer();
|
|
52
|
-
|
|
53
|
-
// Prioritize manual prop, fallback to context container
|
|
54
|
-
const finalContainer = (portalContainer ?? contextContainer ?? undefined) as HTMLElement | undefined;
|
|
55
|
-
|
|
56
|
-
useEffect(() => {
|
|
57
|
-
const raf = requestAnimationFrame(() => {
|
|
58
|
-
setDisplayed(open);
|
|
59
|
-
});
|
|
60
|
-
return () => cancelAnimationFrame(raf);
|
|
61
|
-
}, [open]);
|
|
62
|
-
|
|
63
|
-
const transformValue: Record<string, string> = {
|
|
64
|
-
top: "-translate-y-full",
|
|
65
|
-
bottom: "translate-y-full",
|
|
66
|
-
left: "-translate-x-full",
|
|
67
|
-
right: "translate-x-full"
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const borderClass: Record<string, string> = {
|
|
71
|
-
top: "border-b",
|
|
72
|
-
bottom: "border-t",
|
|
73
|
-
left: "border-r",
|
|
74
|
-
right: "border-l"
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
return (
|
|
78
|
-
<DialogPrimitive.Root open={displayed || open}
|
|
79
|
-
modal={modal}
|
|
80
|
-
onOpenChange={onOpenChange}>
|
|
81
|
-
<DialogPrimitive.Portal container={finalContainer}>
|
|
82
|
-
{includeBackgroundOverlay && <DialogPrimitive.Overlay
|
|
83
|
-
className={cls(
|
|
84
|
-
"outline-none",
|
|
85
|
-
"fixed inset-0 bg-white/80 dark:bg-surface-900/80",
|
|
86
|
-
"backdrop-blur-sm transition-all duration-100 data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in",
|
|
87
|
-
overlayZIndex,
|
|
88
|
-
overlayClassName
|
|
89
|
-
)}
|
|
90
|
-
style={overlayStyle}
|
|
91
|
-
/>}
|
|
92
|
-
<DialogPrimitive.Content
|
|
93
|
-
{...props}
|
|
94
|
-
ref={setContentEl}
|
|
95
|
-
onOpenAutoFocus={(event) => event.preventDefault()}
|
|
96
|
-
onPointerDownOutside={onPointerDownOutside}
|
|
97
|
-
onInteractOutside={onInteractOutside}
|
|
98
|
-
className={cls(
|
|
99
|
-
"outline-none",
|
|
100
|
-
borderClass[side],
|
|
101
|
-
defaultBorderMixin,
|
|
102
|
-
// No `will-change: transform` / `transform-gpu` here, however
|
|
103
|
-
// tempting the layer hint is on a panel this size. Either one
|
|
104
|
-
// makes this element a *containing block* for its
|
|
105
|
-
// `position: fixed` descendants, and everything portaled into
|
|
106
|
-
// the panel below — a Select dropdown, above all — is fixed and
|
|
107
|
-
// positioned in viewport coordinates. Inside a containing block
|
|
108
|
-
// those coordinates are resolved against the panel instead, so
|
|
109
|
-
// every popup was displaced by the panel's own offset and a
|
|
110
|
-
// right-hand Select opened its list off the edge of the screen:
|
|
111
|
-
// the dropdown was open, just nowhere anyone could see it.
|
|
112
|
-
"text-surface-accent-900 dark:text-white",
|
|
113
|
-
"fixed transform z-50 transition-[transform,opacity] ease-in-out",
|
|
114
|
-
!displayed ? "duration-150" : "duration-100",
|
|
115
|
-
"outline-none focus:outline-none focus-visible:outline-none focus-visible:ring-0 focus:ring-0",
|
|
116
|
-
transparent ? "" : "shadow-md bg-white dark:bg-surface-900",
|
|
117
|
-
side === "top" || side === "bottom" ? "w-full" : "h-full",
|
|
118
|
-
side === "left" || side === "top" ? "left-0 top-0" : "right-0 bottom-0",
|
|
119
|
-
displayed && open ? "opacity-100" : "opacity-50",
|
|
120
|
-
!displayed || !open ? transformValue[side] : "",
|
|
121
|
-
className
|
|
122
|
-
)}
|
|
123
|
-
style={style}
|
|
124
|
-
>
|
|
125
|
-
<DialogPrimitive.Title className="sr-only outline-none focus:outline-none focus-visible:outline-none focus-visible:ring-0 focus:ring-0">
|
|
126
|
-
{title ?? "Sheet"}
|
|
127
|
-
</DialogPrimitive.Title>
|
|
128
|
-
<PortalContainerProvider container={contentEl}>
|
|
129
|
-
{children}
|
|
130
|
-
</PortalContainerProvider>
|
|
131
|
-
</DialogPrimitive.Content>
|
|
132
|
-
</DialogPrimitive.Portal>
|
|
133
|
-
</DialogPrimitive.Root>
|
|
134
|
-
);
|
|
135
|
-
};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { cls } from "../util";
|
|
3
|
-
import { useInjectStyles } from "../hooks";
|
|
4
|
-
|
|
5
|
-
export type SkeletonProps = {
|
|
6
|
-
width?: number;
|
|
7
|
-
height?: number;
|
|
8
|
-
className?: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const styles = `
|
|
12
|
-
@keyframes shimmer {
|
|
13
|
-
0% {
|
|
14
|
-
transform: translateX(-150%);
|
|
15
|
-
}
|
|
16
|
-
100% {
|
|
17
|
-
transform: translateX(150%);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
`;
|
|
21
|
-
|
|
22
|
-
export function Skeleton({
|
|
23
|
-
width,
|
|
24
|
-
height,
|
|
25
|
-
className
|
|
26
|
-
}: SkeletonProps) {
|
|
27
|
-
|
|
28
|
-
useInjectStyles("Skeleton", styles);
|
|
29
|
-
|
|
30
|
-
return <span
|
|
31
|
-
style={{
|
|
32
|
-
width: width === undefined ? undefined : `${width}px`,
|
|
33
|
-
height: height === undefined ? undefined : `${height}px`
|
|
34
|
-
}}
|
|
35
|
-
className={
|
|
36
|
-
cls(
|
|
37
|
-
"block relative overflow-hidden",
|
|
38
|
-
"bg-surface-accent-50 dark:bg-surface-accent-800 rounded-md",
|
|
39
|
-
"max-w-full max-h-full",
|
|
40
|
-
// The defaults are classes, not inline styles, so that a caller can
|
|
41
|
-
// override them: an inline style beats every utility, which is why
|
|
42
|
-
// `<Skeleton className="w-full h-full"/>` inside a 40px thumbnail
|
|
43
|
-
// box used to render a 12px bar. The `width`/`height` props still
|
|
44
|
-
// win over any class, since those do land inline.
|
|
45
|
-
width === undefined ? "w-full" : undefined,
|
|
46
|
-
height === undefined ? "h-3" : undefined,
|
|
47
|
-
className)
|
|
48
|
-
}>
|
|
49
|
-
<span
|
|
50
|
-
className="absolute inset-0 bg-gradient-to-r from-transparent via-white/50 dark:via-white/8 to-transparent"
|
|
51
|
-
style={{ animation: "shimmer 1.8s ease-in-out infinite" }}
|
|
52
|
-
/>
|
|
53
|
-
</span>;
|
|
54
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { cls } from "../util";
|
|
4
|
-
import * as SliderPrimitive from "@radix-ui/react-slider";
|
|
5
|
-
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
6
|
-
|
|
7
|
-
export interface SliderProps {
|
|
8
|
-
className?: string;
|
|
9
|
-
name?: string;
|
|
10
|
-
disabled?: boolean;
|
|
11
|
-
orientation?: React.AriaAttributes["aria-orientation"];
|
|
12
|
-
dir?: "ltr" | "rtl";
|
|
13
|
-
min?: number;
|
|
14
|
-
max?: number;
|
|
15
|
-
step?: number;
|
|
16
|
-
minStepsBetweenThumbs?: number;
|
|
17
|
-
value?: number[];
|
|
18
|
-
defaultValue?: number[];
|
|
19
|
-
onValueChange?: (value: number[]) => void;
|
|
20
|
-
onValueCommit?: (value: number[]) => void;
|
|
21
|
-
inverted?: boolean;
|
|
22
|
-
form?: string;
|
|
23
|
-
size?: "small" | "regular";
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function SliderThumb(props: {
|
|
27
|
-
props: Omit<React.PropsWithoutRef<SliderProps>, "size" | "className">,
|
|
28
|
-
index: number,
|
|
29
|
-
hovered: boolean,
|
|
30
|
-
classes: string
|
|
31
|
-
}) {
|
|
32
|
-
return <TooltipPrimitive.Root open={props.hovered}>
|
|
33
|
-
<TooltipPrimitive.Trigger asChild>
|
|
34
|
-
<SliderPrimitive.Thumb
|
|
35
|
-
className={cls({
|
|
36
|
-
"border-primary bg-primary outline-none": !props.props.disabled,
|
|
37
|
-
"border-surface-accent-300 bg-surface-accent-300 dark:border-surface-700 dark:bg-surface-700": props.props.disabled
|
|
38
|
-
},
|
|
39
|
-
props.classes,
|
|
40
|
-
"focus-visible:ring-4 focus-visible:ring-primary focus-visible:ring-opacity-50 focus-visible:ring-primary/50",
|
|
41
|
-
"hover:ring-4 hover:ring-primary hover:ring-opacity-25 hover:ring-primary/25",
|
|
42
|
-
"block rounded-full transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50")}
|
|
43
|
-
|
|
44
|
-
/>
|
|
45
|
-
</TooltipPrimitive.Trigger>
|
|
46
|
-
<TooltipPrimitive.Content side="top"
|
|
47
|
-
sideOffset={5}
|
|
48
|
-
className={cls(
|
|
49
|
-
"TooltipContent",
|
|
50
|
-
"max-w-lg leading-relaxed",
|
|
51
|
-
"z-50 rounded-md px-3 py-2 text-xs leading-none bg-surface-accent-700 dark:bg-surface-accent-800 bg-opacity-90 bg-surface-accent-700/90 dark:bg-surface-accent-800/90 font-medium text-surface-accent-50 shadow-2xl select-none duration-400 ease-in transform opacity-100"
|
|
52
|
-
)}>
|
|
53
|
-
{props.props.value?.[props.index]}
|
|
54
|
-
</TooltipPrimitive.Content>
|
|
55
|
-
</TooltipPrimitive.Root>;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const Slider = React.forwardRef<
|
|
59
|
-
React.ElementRef<typeof SliderPrimitive.Root>,
|
|
60
|
-
SliderProps
|
|
61
|
-
>(({
|
|
62
|
-
className,
|
|
63
|
-
size = "regular",
|
|
64
|
-
...props
|
|
65
|
-
}, ref) => {
|
|
66
|
-
const [hovered, setHovered] = React.useState(false);
|
|
67
|
-
|
|
68
|
-
const thumbSizeClasses =
|
|
69
|
-
size === "small"
|
|
70
|
-
? "h-4 w-4" // Smaller size for the thumb
|
|
71
|
-
: "h-6 w-6"; // Default size
|
|
72
|
-
|
|
73
|
-
return (
|
|
74
|
-
<TooltipPrimitive.Provider delayDuration={200}>
|
|
75
|
-
<SliderPrimitive.Root
|
|
76
|
-
ref={ref}
|
|
77
|
-
onMouseEnter={() => setHovered(true)}
|
|
78
|
-
onMouseLeave={() => setHovered(false)}
|
|
79
|
-
className={cls(
|
|
80
|
-
"relative flex w-full touch-none select-none items-center",
|
|
81
|
-
className
|
|
82
|
-
)}
|
|
83
|
-
{...props}
|
|
84
|
-
>
|
|
85
|
-
<SliderPrimitive.Track
|
|
86
|
-
style={{ height: size === "small" ? 4 : 8 }}
|
|
87
|
-
className={"relative w-full grow overflow-hidden rounded-full bg-surface-accent-300 bg-opacity-40 bg-surface-accent-300/40 dark:bg-surface-700 dark:bg-opacity-40 dark:bg-surface-700/40"}>
|
|
88
|
-
|
|
89
|
-
<SliderPrimitive.Range
|
|
90
|
-
className={cls("absolute h-full", {
|
|
91
|
-
"bg-primary": !props.disabled,
|
|
92
|
-
"bg-surface-accent-300 dark:bg-surface-700": props.disabled
|
|
93
|
-
})}
|
|
94
|
-
/>
|
|
95
|
-
</SliderPrimitive.Track>
|
|
96
|
-
|
|
97
|
-
{(props.value ?? [0]).map((_, index) => <SliderThumb
|
|
98
|
-
key={index}
|
|
99
|
-
index={index}
|
|
100
|
-
props={props}
|
|
101
|
-
hovered={hovered}
|
|
102
|
-
classes={thumbSizeClasses}/>)}
|
|
103
|
-
</SliderPrimitive.Root>
|
|
104
|
-
</TooltipPrimitive.Provider>
|
|
105
|
-
);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
Slider.displayName = "Slider";
|
|
109
|
-
|
|
110
|
-
export { Slider };
|
package/src/components/Table.tsx
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
"use client";
|
|
3
|
-
|
|
4
|
-
import { TagIcon } from "lucide-react";
|
|
5
|
-
import React, { useRef } from "react";
|
|
6
|
-
import { defaultBorderMixin } from "../styles";
|
|
7
|
-
import { cls } from "../util";
|
|
8
|
-
|
|
9
|
-
export type TableProps = {
|
|
10
|
-
children: React.ReactNode;
|
|
11
|
-
className?: string;
|
|
12
|
-
style?: React.CSSProperties;
|
|
13
|
-
} & React.TableHTMLAttributes<HTMLTableElement>;
|
|
14
|
-
|
|
15
|
-
export const Table = React.memo(({
|
|
16
|
-
children,
|
|
17
|
-
className,
|
|
18
|
-
style,
|
|
19
|
-
...rest
|
|
20
|
-
}: TableProps) => (
|
|
21
|
-
<table
|
|
22
|
-
className={cls("text-left text-text-primary dark:text-text-primary-dark rounded-lg overflow-x-auto", className)}
|
|
23
|
-
style={style}
|
|
24
|
-
{...rest}
|
|
25
|
-
>
|
|
26
|
-
{children}
|
|
27
|
-
</table>
|
|
28
|
-
));
|
|
29
|
-
|
|
30
|
-
export type TableBodyProps = {
|
|
31
|
-
children?: React.ReactNode;
|
|
32
|
-
className?: string;
|
|
33
|
-
} & React.HTMLAttributes<HTMLTableSectionElement>;
|
|
34
|
-
|
|
35
|
-
export const TableBody = React.memo(({
|
|
36
|
-
children,
|
|
37
|
-
className,
|
|
38
|
-
...rest
|
|
39
|
-
}: TableBodyProps) => (
|
|
40
|
-
<tbody
|
|
41
|
-
className={cls("bg-white dark:bg-surface-900 text-sm divide-y divide-surface-100 dark:divide-surface-700 dark:divide-opacity-70 dark:divide-surface-700/70", className)}
|
|
42
|
-
{...rest}
|
|
43
|
-
>
|
|
44
|
-
{children}
|
|
45
|
-
</tbody>
|
|
46
|
-
));
|
|
47
|
-
|
|
48
|
-
export type TableHeaderProps = {
|
|
49
|
-
children?: React.ReactNode;
|
|
50
|
-
className?: string;
|
|
51
|
-
} & React.HTMLAttributes<HTMLTableSectionElement>;
|
|
52
|
-
|
|
53
|
-
export const TableHeader = React.memo(({
|
|
54
|
-
children,
|
|
55
|
-
className,
|
|
56
|
-
...rest
|
|
57
|
-
}: TableHeaderProps) => (
|
|
58
|
-
<thead {...rest}>
|
|
59
|
-
<tr
|
|
60
|
-
className={cls(
|
|
61
|
-
defaultBorderMixin,
|
|
62
|
-
"text-sm font-medium text-surface-700 dark:text-surface-accent-300",
|
|
63
|
-
"bg-surface-accent-50 border-b dark:bg-surface-800",
|
|
64
|
-
className
|
|
65
|
-
)}
|
|
66
|
-
>
|
|
67
|
-
{children}
|
|
68
|
-
</tr>
|
|
69
|
-
</thead>
|
|
70
|
-
));
|
|
71
|
-
|
|
72
|
-
export type TableRowProps = {
|
|
73
|
-
children?: React.ReactNode;
|
|
74
|
-
className?: string;
|
|
75
|
-
onClick?: React.MouseEventHandler<any>;
|
|
76
|
-
style?: React.CSSProperties;
|
|
77
|
-
} & React.HTMLAttributes<HTMLTableRowElement>;
|
|
78
|
-
|
|
79
|
-
export const TableRow = React.memo(({
|
|
80
|
-
children,
|
|
81
|
-
className,
|
|
82
|
-
onClick,
|
|
83
|
-
style,
|
|
84
|
-
...rest
|
|
85
|
-
}: TableRowProps) => (
|
|
86
|
-
<tr
|
|
87
|
-
onClick={onClick}
|
|
88
|
-
style={style}
|
|
89
|
-
className={cls(
|
|
90
|
-
"bg-white dark:bg-surface-900",
|
|
91
|
-
onClick ? "transition-colors duration-150 hover:bg-primary/5 cursor-pointer" : "",
|
|
92
|
-
className
|
|
93
|
-
)}
|
|
94
|
-
{...rest}
|
|
95
|
-
>
|
|
96
|
-
{children}
|
|
97
|
-
</tr>
|
|
98
|
-
));
|
|
99
|
-
|
|
100
|
-
export type TableCellProps = {
|
|
101
|
-
children?: React.ReactNode;
|
|
102
|
-
header?: boolean;
|
|
103
|
-
scope?: string;
|
|
104
|
-
className?: string;
|
|
105
|
-
style?: React.CSSProperties;
|
|
106
|
-
align?: "left" | "center" | "right";
|
|
107
|
-
colspan?: number;
|
|
108
|
-
} & React.HTMLAttributes<HTMLTableCellElement>;
|
|
109
|
-
|
|
110
|
-
export const TableCell = React.memo(({
|
|
111
|
-
children,
|
|
112
|
-
header = false,
|
|
113
|
-
scope = "",
|
|
114
|
-
align,
|
|
115
|
-
className,
|
|
116
|
-
style,
|
|
117
|
-
colspan,
|
|
118
|
-
...rest
|
|
119
|
-
}: TableCellProps) => {
|
|
120
|
-
const ref = useRef<HTMLTableCellElement>(null);
|
|
121
|
-
const TagIcon = header || getParentName(ref.current) === "TableHeader" ? "th" : "td";
|
|
122
|
-
return (
|
|
123
|
-
<TagIcon
|
|
124
|
-
scope={scope}
|
|
125
|
-
colSpan={colspan}
|
|
126
|
-
ref={ref}
|
|
127
|
-
style={style}
|
|
128
|
-
className={cls(
|
|
129
|
-
"px-4 py-3 text-clip ",
|
|
130
|
-
align === "center" ? "text-center" : (align === "right" ? "text-right" : "text-left"),
|
|
131
|
-
className
|
|
132
|
-
)}
|
|
133
|
-
{...rest}
|
|
134
|
-
>
|
|
135
|
-
{children}
|
|
136
|
-
</TagIcon>
|
|
137
|
-
);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
interface ReactFiber {
|
|
141
|
-
return: ReactFiber;
|
|
142
|
-
type: string | Function;
|
|
143
|
-
elementType?: {
|
|
144
|
-
name?: string;
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// This is highly experimental and might break in the future
|
|
149
|
-
function getParentName(element: HTMLElement | null): string | undefined {
|
|
150
|
-
if (element) {
|
|
151
|
-
const key = Object.keys(element).find((key) => {
|
|
152
|
-
return (
|
|
153
|
-
key.startsWith("__reactFiber$") ||
|
|
154
|
-
key.startsWith("__reactInternalInstance$")
|
|
155
|
-
);
|
|
156
|
-
});
|
|
157
|
-
if (key) {
|
|
158
|
-
const domFiber = (element as unknown as Record<string, ReactFiber>)[key];
|
|
159
|
-
const getComponentFiber = (fiber: ReactFiber): ReactFiber => {
|
|
160
|
-
let parentFiber = fiber.return;
|
|
161
|
-
while (parentFiber && typeof parentFiber.type === "string") {
|
|
162
|
-
parentFiber = parentFiber.return;
|
|
163
|
-
}
|
|
164
|
-
return parentFiber;
|
|
165
|
-
};
|
|
166
|
-
let fiber = getComponentFiber(domFiber);
|
|
167
|
-
fiber = getComponentFiber(fiber);
|
|
168
|
-
return fiber?.elementType?.name;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return undefined;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
Table.displayName = "Table";
|
|
175
|
-
TableBody.displayName = "TableBody";
|
|
176
|
-
TableHeader.displayName = "TableHeader";
|
|
177
|
-
TableRow.displayName = "TableRow";
|
|
178
|
-
TableCell.displayName = "TableCell";
|
package/src/components/Tabs.tsx
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import React, { createContext, useContext, useRef, useState, useEffect, useMemo } from "react";
|
|
3
|
-
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
4
|
-
import { cls } from "../util";
|
|
5
|
-
import { defaultBorderMixin } from "../styles";
|
|
6
|
-
|
|
7
|
-
export type TabVariant = "standard" | "boxy" | "pill";
|
|
8
|
-
|
|
9
|
-
const TabsContext = createContext<{ variant: TabVariant }>({ variant: "standard" });
|
|
10
|
-
import { IconButton } from "./IconButton";
|
|
11
|
-
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
|
|
12
|
-
import { iconSize } from "../icons/Icon";
|
|
13
|
-
|
|
14
|
-
export type TabsProps = {
|
|
15
|
-
value: string,
|
|
16
|
-
children: React.ReactNode,
|
|
17
|
-
innerClassName?: string,
|
|
18
|
-
className?: string,
|
|
19
|
-
variant?: TabVariant,
|
|
20
|
-
onValueChange: (value: string) => void
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export function Tabs({
|
|
24
|
-
value,
|
|
25
|
-
onValueChange,
|
|
26
|
-
className,
|
|
27
|
-
innerClassName,
|
|
28
|
-
variant = "standard",
|
|
29
|
-
children
|
|
30
|
-
}: TabsProps) {
|
|
31
|
-
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
|
32
|
-
const [showLeftScroll, setShowLeftScroll] = useState(false);
|
|
33
|
-
const [showRightScroll, setShowRightScroll] = useState(false);
|
|
34
|
-
const [isScrollable, setIsScrollable] = useState(false);
|
|
35
|
-
|
|
36
|
-
const checkScroll = () => {
|
|
37
|
-
if (scrollContainerRef.current) {
|
|
38
|
-
const { scrollLeft, scrollWidth, clientWidth } = scrollContainerRef.current;
|
|
39
|
-
setShowLeftScroll(scrollLeft > 0);
|
|
40
|
-
setShowRightScroll(Math.ceil(scrollLeft + clientWidth) < scrollWidth);
|
|
41
|
-
setIsScrollable(scrollWidth > clientWidth);
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
checkScroll();
|
|
47
|
-
window.addEventListener("resize", checkScroll);
|
|
48
|
-
|
|
49
|
-
let observer: ResizeObserver;
|
|
50
|
-
if (scrollContainerRef.current) {
|
|
51
|
-
observer = new ResizeObserver(checkScroll);
|
|
52
|
-
observer.observe(scrollContainerRef.current);
|
|
53
|
-
if (scrollContainerRef.current.firstElementChild) {
|
|
54
|
-
observer.observe(scrollContainerRef.current.firstElementChild);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return () => {
|
|
59
|
-
window.removeEventListener("resize", checkScroll);
|
|
60
|
-
observer?.disconnect();
|
|
61
|
-
};
|
|
62
|
-
}, [children]);
|
|
63
|
-
|
|
64
|
-
const scroll = (direction: "left" | "right") => {
|
|
65
|
-
if (scrollContainerRef.current) {
|
|
66
|
-
const container = scrollContainerRef.current;
|
|
67
|
-
const scrollAmount = Math.max(container.clientWidth / 2, 200);
|
|
68
|
-
const targetScroll = container.scrollLeft + (direction === "left" ? -scrollAmount : scrollAmount);
|
|
69
|
-
|
|
70
|
-
container.scrollTo({
|
|
71
|
-
left: targetScroll,
|
|
72
|
-
behavior: "smooth"
|
|
73
|
-
});
|
|
74
|
-
// checkScroll will be called by onScroll event
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const contextValue = useMemo(() => ({ variant }), [variant]);
|
|
79
|
-
|
|
80
|
-
return <TabsContext.Provider value={contextValue}>
|
|
81
|
-
<TabsPrimitive.Root
|
|
82
|
-
value={value}
|
|
83
|
-
onValueChange={onValueChange}
|
|
84
|
-
className={cls("relative flex flex-row items-center min-w-0 w-full", className)}
|
|
85
|
-
>
|
|
86
|
-
{isScrollable && (
|
|
87
|
-
<button
|
|
88
|
-
type="button"
|
|
89
|
-
disabled={!showLeftScroll}
|
|
90
|
-
aria-label="Scroll tabs left"
|
|
91
|
-
onClick={() => scroll("left")}
|
|
92
|
-
className={cls(
|
|
93
|
-
"absolute left-0 top-1/2 -translate-y-1/2 z-10 flex items-center justify-center rounded-md transition-all h-8 w-6",
|
|
94
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-surface-400",
|
|
95
|
-
!showLeftScroll ? "pointer-events-none opacity-0" : "text-surface-600 dark:text-surface-400 hover:bg-surface-accent-200 dark:hover:bg-surface-accent-800",
|
|
96
|
-
"bg-surface-50 dark:bg-surface-900 border shadow-sm", defaultBorderMixin
|
|
97
|
-
)}
|
|
98
|
-
>
|
|
99
|
-
<ChevronLeftIcon size={iconSize.smallest}/>
|
|
100
|
-
</button>
|
|
101
|
-
)}
|
|
102
|
-
<div
|
|
103
|
-
ref={scrollContainerRef}
|
|
104
|
-
className="flex-1 overflow-x-auto no-scrollbar min-w-0"
|
|
105
|
-
onScroll={checkScroll}
|
|
106
|
-
style={{ scrollbarWidth: "none",
|
|
107
|
-
msOverflowStyle: "none" }}
|
|
108
|
-
>
|
|
109
|
-
<TabsPrimitive.List className={cls(
|
|
110
|
-
variant === "standard" && "inline-flex h-9 items-center justify-start rounded-md bg-surface-50 p-1 text-surface-600 dark:bg-surface-900 dark:text-surface-400 gap-2 border",
|
|
111
|
-
variant === "standard" && defaultBorderMixin,
|
|
112
|
-
variant === "boxy" && "flex items-center h-full",
|
|
113
|
-
variant === "pill" && "flex items-center gap-0.5",
|
|
114
|
-
innerClassName)
|
|
115
|
-
}>
|
|
116
|
-
{children}
|
|
117
|
-
</TabsPrimitive.List>
|
|
118
|
-
</div>
|
|
119
|
-
{isScrollable && (
|
|
120
|
-
<button
|
|
121
|
-
type="button"
|
|
122
|
-
disabled={!showRightScroll}
|
|
123
|
-
aria-label="Scroll tabs right"
|
|
124
|
-
onClick={() => scroll("right")}
|
|
125
|
-
className={cls(
|
|
126
|
-
"absolute right-0 top-1/2 -translate-y-1/2 z-10 flex items-center justify-center rounded-md transition-all h-8 w-6",
|
|
127
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-surface-400",
|
|
128
|
-
!showRightScroll ? "pointer-events-none opacity-0" : "text-surface-600 dark:text-surface-400 hover:bg-surface-accent-200 dark:hover:bg-surface-accent-800",
|
|
129
|
-
"bg-surface-50 dark:bg-surface-900 border shadow-sm", defaultBorderMixin
|
|
130
|
-
)}
|
|
131
|
-
>
|
|
132
|
-
<ChevronRightIcon size={iconSize.smallest}/>
|
|
133
|
-
</button>
|
|
134
|
-
)}
|
|
135
|
-
</TabsPrimitive.Root>
|
|
136
|
-
</TabsContext.Provider>;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export type TabProps = {
|
|
140
|
-
value: string,
|
|
141
|
-
className?: string,
|
|
142
|
-
innerClassName?: string,
|
|
143
|
-
children: React.ReactNode,
|
|
144
|
-
disabled?: boolean
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
export function Tab({
|
|
148
|
-
value,
|
|
149
|
-
className,
|
|
150
|
-
innerClassName,
|
|
151
|
-
children,
|
|
152
|
-
disabled
|
|
153
|
-
}: TabProps) {
|
|
154
|
-
const { variant } = useContext(TabsContext);
|
|
155
|
-
|
|
156
|
-
return (
|
|
157
|
-
<TabsPrimitive.Trigger
|
|
158
|
-
value={value}
|
|
159
|
-
disabled={disabled}
|
|
160
|
-
className={cls(
|
|
161
|
-
"inline-flex items-center justify-center whitespace-nowrap text-sm font-medium ring-offset-white transition-all",
|
|
162
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-surface-400 focus-visible:ring-offset-2",
|
|
163
|
-
"disabled:pointer-events-none disabled:opacity-50",
|
|
164
|
-
variant === "standard" && "rounded-md px-3 py-1 data-[state=active]:bg-white data-[state=active]:text-surface-900 data-[state=active]:shadow-sm dark:data-[state=active]:bg-surface-900 dark:data-[state=active]:text-surface-50",
|
|
165
|
-
variant === "boxy" && cls(
|
|
166
|
-
"flex-shrink-0 flex items-center gap-1.5 px-3.5 h-9 border-r border-surface-200 dark:border-surface-800 cursor-pointer text-xs font-medium transition-colors group relative box-border overflow-hidden",
|
|
167
|
-
"border-b-2 border-b-transparent",
|
|
168
|
-
"data-[state=active]:bg-surface-50 dark:data-[state=active]:bg-surface-900",
|
|
169
|
-
"data-[state=active]:text-text-primary dark:data-[state=active]:text-text-primary-dark",
|
|
170
|
-
"data-[state=active]:border-b-primary",
|
|
171
|
-
"text-text-secondary dark:text-text-secondary-dark hover:bg-surface-100 dark:hover:bg-surface-800"
|
|
172
|
-
),
|
|
173
|
-
variant === "pill" && cls(
|
|
174
|
-
"px-2 py-0.5 rounded-md text-[10px] font-medium transition-colors",
|
|
175
|
-
"data-[state=active]:bg-primary/10 data-[state=active]:text-primary dark:data-[state=active]:bg-primary/20 dark:data-[state=active]:text-primary",
|
|
176
|
-
"text-text-disabled dark:text-text-disabled-dark hover:text-text-secondary dark:hover:text-text-secondary-dark"
|
|
177
|
-
),
|
|
178
|
-
className,
|
|
179
|
-
variant === "standard" && innerClassName
|
|
180
|
-
)}
|
|
181
|
-
>
|
|
182
|
-
{children}
|
|
183
|
-
</TabsPrimitive.Trigger>
|
|
184
|
-
);
|
|
185
|
-
}
|