@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
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { useDropzone } from "react-dropzone";
|
|
4
|
-
import { fieldBackgroundHoverMixin, fieldBackgroundMixin } from "../styles";
|
|
5
|
-
import { cls } from "../util";
|
|
6
|
-
import { Typography } from "./Typography";
|
|
7
|
-
|
|
8
|
-
export interface FileUploadError {
|
|
9
|
-
message: string;
|
|
10
|
-
code: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export type OnFileUploadRejected = (fileRejections: {
|
|
14
|
-
file: File;
|
|
15
|
-
errors: readonly FileUploadError[];
|
|
16
|
-
}[], event: object) => void;
|
|
17
|
-
|
|
18
|
-
export type OnFilesUploadAdded = (files: File[]) => void;
|
|
19
|
-
|
|
20
|
-
export type FileUploadProps = {
|
|
21
|
-
// e.g. accept={{ "*/image": [] }}
|
|
22
|
-
accept?: Record<string, string[]>,
|
|
23
|
-
onFilesAdded: OnFilesUploadAdded,
|
|
24
|
-
onFilesRejected?: OnFileUploadRejected,
|
|
25
|
-
maxSize?: number,
|
|
26
|
-
disabled?: boolean;
|
|
27
|
-
maxFiles?: number;
|
|
28
|
-
title?: React.ReactNode;
|
|
29
|
-
uploadDescription?: React.ReactNode;
|
|
30
|
-
preventDropOnDocument?: boolean;
|
|
31
|
-
size?: "small" | "medium" | "large";
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export function FileUpload({
|
|
35
|
-
accept,
|
|
36
|
-
onFilesAdded,
|
|
37
|
-
onFilesRejected,
|
|
38
|
-
maxSize,
|
|
39
|
-
disabled,
|
|
40
|
-
maxFiles,
|
|
41
|
-
title,
|
|
42
|
-
uploadDescription,
|
|
43
|
-
children,
|
|
44
|
-
preventDropOnDocument = true,
|
|
45
|
-
size
|
|
46
|
-
}: React.PropsWithChildren<FileUploadProps>) {
|
|
47
|
-
|
|
48
|
-
const {
|
|
49
|
-
getRootProps,
|
|
50
|
-
getInputProps,
|
|
51
|
-
isDragActive,
|
|
52
|
-
isDragAccept,
|
|
53
|
-
isDragReject
|
|
54
|
-
} = useDropzone({
|
|
55
|
-
accept,
|
|
56
|
-
noDragEventsBubbling: true,
|
|
57
|
-
maxSize,
|
|
58
|
-
onDrop: onFilesAdded,
|
|
59
|
-
onDropRejected: onFilesRejected,
|
|
60
|
-
disabled,
|
|
61
|
-
maxFiles,
|
|
62
|
-
preventDropOnDocument
|
|
63
|
-
}
|
|
64
|
-
);
|
|
65
|
-
return <div
|
|
66
|
-
{...getRootProps()}
|
|
67
|
-
role="button"
|
|
68
|
-
aria-label={typeof title === "string" ? title : (typeof uploadDescription === "string" ? uploadDescription : "Upload file")}
|
|
69
|
-
aria-disabled={disabled || undefined}
|
|
70
|
-
className={cls(
|
|
71
|
-
fieldBackgroundMixin,
|
|
72
|
-
"flex gap-2",
|
|
73
|
-
"p-4 box-border relative items-center border-2 border-solid border-transparent outline-hidden rounded-lg duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid",
|
|
74
|
-
{
|
|
75
|
-
"h-44": size === "large",
|
|
76
|
-
"h-28": size === "medium",
|
|
77
|
-
"h-16": size === "small",
|
|
78
|
-
"cursor-pointer": !disabled,
|
|
79
|
-
[fieldBackgroundHoverMixin]: !isDragActive,
|
|
80
|
-
"transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-red-500": isDragReject,
|
|
81
|
-
"transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-green-500": isDragAccept
|
|
82
|
-
})}>
|
|
83
|
-
|
|
84
|
-
<Typography variant={"caption"} color={"secondary"} className={"absolute top-2 left-3.5 cursor-inherit"}>
|
|
85
|
-
{title}
|
|
86
|
-
</Typography>
|
|
87
|
-
|
|
88
|
-
<input
|
|
89
|
-
{...getInputProps()}/>
|
|
90
|
-
|
|
91
|
-
{children}
|
|
92
|
-
|
|
93
|
-
<div
|
|
94
|
-
className="grow h-28 box-border flex flex-col items-center justify-center text-center">
|
|
95
|
-
<Typography align={"center"}
|
|
96
|
-
variant={"label"}
|
|
97
|
-
className={"flex flex-row gap-2 justify-center"}>
|
|
98
|
-
{uploadDescription}
|
|
99
|
-
</Typography>
|
|
100
|
-
</div>
|
|
101
|
-
|
|
102
|
-
</div>
|
|
103
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { cls } from "../util";
|
|
3
|
-
|
|
4
|
-
export interface FilterChipProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
|
|
5
|
-
/**
|
|
6
|
-
* The text label displayed on the chip.
|
|
7
|
-
*/
|
|
8
|
-
children: React.ReactNode;
|
|
9
|
-
/**
|
|
10
|
-
* Whether the chip is currently in an active/selected state.
|
|
11
|
-
*/
|
|
12
|
-
active?: boolean;
|
|
13
|
-
/**
|
|
14
|
-
* Optional icon rendered before the label.
|
|
15
|
-
*/
|
|
16
|
-
icon?: React.ReactNode;
|
|
17
|
-
/**
|
|
18
|
-
* Size variant.
|
|
19
|
-
* @default "medium"
|
|
20
|
-
*/
|
|
21
|
-
size?: "small" | "medium";
|
|
22
|
-
/**
|
|
23
|
-
* Whether the chip is disabled.
|
|
24
|
-
*/
|
|
25
|
-
disabled?: boolean;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const sizeClasses = {
|
|
29
|
-
small: "px-2 py-0.5 text-xs",
|
|
30
|
-
medium: "px-2.5 py-1 text-xs"
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* A toggle chip used for filter presets and similar multi-select controls.
|
|
35
|
-
*
|
|
36
|
-
* Uses an inset box-shadow for the active ring instead of `border` so the
|
|
37
|
-
* chip size stays stable across states and the ring cannot be clipped by
|
|
38
|
-
* parent `overflow-hidden` containers.
|
|
39
|
-
*
|
|
40
|
-
* @group Interactive components
|
|
41
|
-
*/
|
|
42
|
-
export const FilterChip = React.forwardRef<HTMLButtonElement, FilterChipProps>(function FilterChip({
|
|
43
|
-
children,
|
|
44
|
-
active = false,
|
|
45
|
-
onClick,
|
|
46
|
-
icon,
|
|
47
|
-
size = "medium",
|
|
48
|
-
className,
|
|
49
|
-
disabled = false,
|
|
50
|
-
...rest
|
|
51
|
-
}: FilterChipProps, ref) {
|
|
52
|
-
return (
|
|
53
|
-
<button
|
|
54
|
-
ref={ref}
|
|
55
|
-
type="button"
|
|
56
|
-
onClick={onClick}
|
|
57
|
-
disabled={disabled}
|
|
58
|
-
className={cls(
|
|
59
|
-
"inline-flex items-center gap-1 rounded-full",
|
|
60
|
-
"font-medium whitespace-nowrap select-none shrink-0",
|
|
61
|
-
"transition-colors duration-150",
|
|
62
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50",
|
|
63
|
-
sizeClasses[size],
|
|
64
|
-
!disabled && "cursor-pointer",
|
|
65
|
-
// Hover is one step along the same ramp the chip already sits
|
|
66
|
-
// on, the way every other hoverable surface here moves. It used
|
|
67
|
-
// to be `hover:bg-primary/5` for the inactive chip, which
|
|
68
|
-
// *replaces* the resting fill with a tint fainter than it — so
|
|
69
|
-
// pointing at a chip made its background vanish. The active chip
|
|
70
|
-
// had no hover state at all.
|
|
71
|
-
active
|
|
72
|
-
? cls(
|
|
73
|
-
"bg-primary/12 text-primary dark:bg-primary/20 dark:text-primary shadow-[inset_0_0_0_1.5px_var(--color-primary)]",
|
|
74
|
-
!disabled && "hover:bg-primary/20 dark:hover:bg-primary/30"
|
|
75
|
-
)
|
|
76
|
-
: cls(
|
|
77
|
-
"bg-surface-accent-100 text-text-secondary dark:bg-surface-accent-800 dark:text-text-secondary-dark",
|
|
78
|
-
!disabled && "hover:bg-surface-accent-200 dark:hover:bg-surface-accent-700"
|
|
79
|
-
),
|
|
80
|
-
disabled && "opacity-50 cursor-not-allowed",
|
|
81
|
-
className
|
|
82
|
-
)}
|
|
83
|
-
{...rest}
|
|
84
|
-
>
|
|
85
|
-
{icon}
|
|
86
|
-
{children}
|
|
87
|
-
</button>
|
|
88
|
-
);
|
|
89
|
-
});
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { cls } from "../util";
|
|
4
|
-
|
|
5
|
-
export type IconButtonProps<C extends React.ElementType> =
|
|
6
|
-
Omit<(C extends "button" ? React.ButtonHTMLAttributes<HTMLButtonElement> : React.ComponentProps<C>), "onClick">
|
|
7
|
-
& {
|
|
8
|
-
size?: "medium" | "small" | "smallest" | "large";
|
|
9
|
-
variant?: "ghost" | "filled",
|
|
10
|
-
shape?: "circular" | "square",
|
|
11
|
-
disabled?: boolean;
|
|
12
|
-
toggled?: boolean;
|
|
13
|
-
component?: C;
|
|
14
|
-
onClick?: React.MouseEventHandler<any>;
|
|
15
|
-
"aria-label"?: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const buttonClasses = "hover:bg-surface-accent-200 hover:bg-opacity-75 hover:bg-surface-accent-200/75 dark:hover:bg-surface-accent-800 hover:scale-[1.04] active:scale-95 transition-transform";
|
|
19
|
-
// `[&>svg]:shrink-0` is load-bearing: without it flex compresses the icon to
|
|
20
|
-
// whatever width is left after padding, so an 18px icon in a 28px button
|
|
21
|
-
// rendered 12x18 — visibly squashed rather than merely small.
|
|
22
|
-
const baseClasses = "inline-flex items-center justify-center text-sm font-medium focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 transition-colors ease-in-out duration-150 [&>svg]:shrink-0";
|
|
23
|
-
const colorClasses = "text-surface-accent-500 visited:text-surface-accent-500 dark:text-surface-accent-300 dark:visited:text-surface-accent-300";
|
|
24
|
-
// Padding stays a flat p-2 (as it always was). Callers pass their own icon
|
|
25
|
-
// sizes, so tightening it here shrinks the content box under an icon that was
|
|
26
|
-
// sized for the old one and makes the icon overflow. `shrink-0` above is what
|
|
27
|
-
// actually fixes the squashing — the icon keeps its own dimensions and simply
|
|
28
|
-
// eats into the padding.
|
|
29
|
-
const sizeClasses = {
|
|
30
|
-
medium: "w-10 !h-10 min-w-10 min-h-10 p-2",
|
|
31
|
-
small: "w-8 !h-8 min-w-8 min-h-8 p-2",
|
|
32
|
-
smallest: "w-7 !h-7 min-w-7 min-h-7 p-2",
|
|
33
|
-
large: "w-12 !h-12 min-w-12 min-h-12 p-2"
|
|
34
|
-
}
|
|
35
|
-
const shapeClasses = {
|
|
36
|
-
circular: "rounded-full",
|
|
37
|
-
square: "rounded-md"
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** Icon size used when the caller doesn't set one on the child. */
|
|
41
|
-
const defaultIconSize = {
|
|
42
|
-
smallest: 16,
|
|
43
|
-
small: 18,
|
|
44
|
-
medium: 20,
|
|
45
|
-
large: 24
|
|
46
|
-
} as const;
|
|
47
|
-
|
|
48
|
-
const IconButtonInner = <C extends React.ElementType = "button">({
|
|
49
|
-
children,
|
|
50
|
-
className,
|
|
51
|
-
size = "medium",
|
|
52
|
-
variant = "ghost",
|
|
53
|
-
shape = "circular",
|
|
54
|
-
disabled,
|
|
55
|
-
toggled,
|
|
56
|
-
component,
|
|
57
|
-
...props
|
|
58
|
-
}: IconButtonProps<C>, ref: React.ForwardedRef<HTMLButtonElement>) => {
|
|
59
|
-
|
|
60
|
-
const bgClasses = variant === "ghost" ? "bg-transparent" : "bg-surface-accent-200 bg-opacity-50 bg-surface-accent-200/50 dark:bg-surface-900 dark:bg-opacity-50 dark:bg-surface-900/50";
|
|
61
|
-
const Component: React.ElementType<any> = component || "button";
|
|
62
|
-
const isNativeButton = Component === "button";
|
|
63
|
-
|
|
64
|
-
// Give the icon a size that matches the button when the caller didn't pick
|
|
65
|
-
// one. Without this a bare <IconButton size="smallest"><PencilIcon/></…>
|
|
66
|
-
// renders lucide's 24px default inside a 28px button, so icon size ended up
|
|
67
|
-
// depending on whether each call site happened to pass one — which is what
|
|
68
|
-
// made a row of icon buttons look randomly sized. An explicit `size` on the
|
|
69
|
-
// child always wins.
|
|
70
|
-
const sizedChildren = React.Children.map(children, (child) => {
|
|
71
|
-
if (!React.isValidElement(child)) return child;
|
|
72
|
-
if ((child.props as { size?: unknown }).size !== undefined) return child;
|
|
73
|
-
return React.cloneElement(child as React.ReactElement<{ size?: number }>,
|
|
74
|
-
{ size: defaultIconSize[size] });
|
|
75
|
-
});
|
|
76
|
-
return (
|
|
77
|
-
<Component
|
|
78
|
-
type={isNativeButton ? "button" : undefined}
|
|
79
|
-
role={isNativeButton ? undefined : "button"}
|
|
80
|
-
ref={ref}
|
|
81
|
-
aria-disabled={disabled || undefined}
|
|
82
|
-
tabIndex={disabled ? -1 : undefined}
|
|
83
|
-
{...props}
|
|
84
|
-
className={cls(
|
|
85
|
-
disabled ? "opacity-50 pointer-events-none" : "cursor-pointer",
|
|
86
|
-
toggled ? "outline outline-2 outline-primary" : "",
|
|
87
|
-
"text-inherit dark:text-inherit",
|
|
88
|
-
colorClasses,
|
|
89
|
-
bgClasses,
|
|
90
|
-
baseClasses,
|
|
91
|
-
buttonClasses,
|
|
92
|
-
shapeClasses[shape],
|
|
93
|
-
sizeClasses[size],
|
|
94
|
-
className
|
|
95
|
-
)}>
|
|
96
|
-
{sizedChildren}
|
|
97
|
-
</Component>
|
|
98
|
-
);
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
export const IconButton = React.forwardRef(IconButtonInner as React.ForwardRefRenderFunction<HTMLButtonElement, IconButtonProps<any>>) as React.ComponentType<IconButtonProps<any>>;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { cls } from "../util";
|
|
3
|
-
|
|
4
|
-
const colorClasses = {
|
|
5
|
-
info: "bg-blue-500/8 dark:bg-blue-500/12 text-blue-800 dark:text-blue-200 border border-blue-500/20 dark:border-blue-500/25",
|
|
6
|
-
warn: "bg-amber-500/8 dark:bg-amber-500/12 text-amber-800 dark:text-amber-200 border border-amber-500/20 dark:border-amber-500/25"
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function InfoLabel({
|
|
10
|
-
children,
|
|
11
|
-
mode = "info"
|
|
12
|
-
}: {
|
|
13
|
-
children: React.ReactNode,
|
|
14
|
-
mode?: "info" | "warn"
|
|
15
|
-
}) {
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<div
|
|
19
|
-
className={cls("my-3 py-2 px-4 rounded-lg text-sm font-medium leading-snug", colorClasses[mode])}>
|
|
20
|
-
{children}
|
|
21
|
-
</div>
|
|
22
|
-
)
|
|
23
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { cls } from "../util";
|
|
4
|
-
import { defaultBorderMixin } from "../styles";
|
|
5
|
-
|
|
6
|
-
export type InputLabelProps = {
|
|
7
|
-
children?: React.ReactNode;
|
|
8
|
-
className?: string;
|
|
9
|
-
shrink?: boolean;
|
|
10
|
-
} & React.LabelHTMLAttributes<HTMLLabelElement>;
|
|
11
|
-
|
|
12
|
-
const defaultClasses = {
|
|
13
|
-
root: "origin-left transition-transform block whitespace-nowrap overflow-hidden text-ellipsis max-w-full",
|
|
14
|
-
shrink: "transform translate-y-[2px] scale-75 translate-x-[12px]",
|
|
15
|
-
expanded: "translate-x-[16px] top-0 transform translate-y-[16px] scale-100"
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export const InputLabel = React.forwardRef<HTMLLabelElement, InputLabelProps>(function InputLabel(inProps, ref) {
|
|
19
|
-
const {
|
|
20
|
-
shrink,
|
|
21
|
-
className,
|
|
22
|
-
...other
|
|
23
|
-
} = inProps;
|
|
24
|
-
|
|
25
|
-
const computedClassName = cls(defaultClasses.root,
|
|
26
|
-
{
|
|
27
|
-
[defaultClasses.shrink]: shrink,
|
|
28
|
-
[defaultClasses.expanded]: !shrink
|
|
29
|
-
}, className);
|
|
30
|
-
|
|
31
|
-
return (
|
|
32
|
-
<label
|
|
33
|
-
className={cls("text-sm font-medium peer-disabled:cursor-not-allowed",
|
|
34
|
-
defaultBorderMixin, computedClassName)}
|
|
35
|
-
data-shrink={shrink}
|
|
36
|
-
ref={ref}
|
|
37
|
-
{...other}
|
|
38
|
-
/>
|
|
39
|
-
);
|
|
40
|
-
});
|
package/src/components/Label.tsx
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import * as React from "react"
|
|
3
|
-
import * as LabelPrimitive from "@radix-ui/react-label"
|
|
4
|
-
import { cls } from "../util";
|
|
5
|
-
import { defaultBorderMixin } from "../styles";
|
|
6
|
-
|
|
7
|
-
type LabelProps = React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & {
|
|
8
|
-
border?: boolean,
|
|
9
|
-
onClick?: React.MouseEventHandler<HTMLLabelElement>
|
|
10
|
-
};
|
|
11
|
-
const Label = React.forwardRef<
|
|
12
|
-
React.ElementRef<typeof LabelPrimitive.Root>,
|
|
13
|
-
LabelProps
|
|
14
|
-
>(({
|
|
15
|
-
className,
|
|
16
|
-
border,
|
|
17
|
-
onClick,
|
|
18
|
-
...props
|
|
19
|
-
}, ref) => (
|
|
20
|
-
<LabelPrimitive.Root
|
|
21
|
-
ref={ref}
|
|
22
|
-
onClick={onClick}
|
|
23
|
-
className={cls("text-sm font-medium peer-disabled:cursor-not-allowed",
|
|
24
|
-
border && "border border-surface-300 dark:border-surface-700 rounded-md px-3 py-1.5",
|
|
25
|
-
onClick && "hover:cursor-pointer hover:bg-surface-200 dark:hover:bg-surface-800",
|
|
26
|
-
defaultBorderMixin, className)}
|
|
27
|
-
{...props}
|
|
28
|
-
/>
|
|
29
|
-
))
|
|
30
|
-
Label.displayName = LabelPrimitive.Root.displayName
|
|
31
|
-
|
|
32
|
-
export { Label }
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { Button, ButtonProps } from "./Button";
|
|
3
|
-
import { CircularProgress } from "./CircularProgress";
|
|
4
|
-
|
|
5
|
-
export type LoadingButtonProps<P extends React.ElementType> = ButtonProps<P> & {
|
|
6
|
-
startIcon?: React.ReactNode;
|
|
7
|
-
loading?: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function LoadingButton<P extends React.ElementType = "button">({
|
|
11
|
-
children,
|
|
12
|
-
loading,
|
|
13
|
-
disabled,
|
|
14
|
-
onClick,
|
|
15
|
-
startIcon,
|
|
16
|
-
...props
|
|
17
|
-
}: LoadingButtonProps<P>) {
|
|
18
|
-
return (
|
|
19
|
-
<Button
|
|
20
|
-
disabled={loading || disabled}
|
|
21
|
-
onClick={onClick}
|
|
22
|
-
component={props.component as React.ElementType}
|
|
23
|
-
{...props}
|
|
24
|
-
>
|
|
25
|
-
{loading && (
|
|
26
|
-
<CircularProgress size={"smallest"}/>
|
|
27
|
-
)}
|
|
28
|
-
{!loading && startIcon}
|
|
29
|
-
{children}
|
|
30
|
-
</Button>
|
|
31
|
-
);
|
|
32
|
-
};
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React, { useMemo } from "react";
|
|
3
|
-
import { deepEqual as equal } from "fast-equals"
|
|
4
|
-
|
|
5
|
-
import MarkdownIt from "markdown-it";
|
|
6
|
-
import { cls } from "../util";
|
|
7
|
-
|
|
8
|
-
export interface MarkdownProps {
|
|
9
|
-
source: string,
|
|
10
|
-
size?: "small" | "medium" | "large" | "xl" | "2xl";
|
|
11
|
-
className?: string
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const proseClasses = {
|
|
15
|
-
small: "prose prose-sm typography-body2",
|
|
16
|
-
medium: "prose typography-body1",
|
|
17
|
-
large: "prose prose-lg",
|
|
18
|
-
xl: "prose prose-xl",
|
|
19
|
-
"2xl": "prose prose-2xl"
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Tailwind typography-plugin weight overrides.
|
|
24
|
-
* The plugin defaults to very heavy weights (h1: 800, h2: 700, h3/h4: 600,
|
|
25
|
-
* strong: 600, code: 600) which clash with the Rebase design-system that uses
|
|
26
|
-
* font-light (300) / font-normal (400) for headings.
|
|
27
|
-
* We reset them here so rendered markdown matches the rest of the UI.
|
|
28
|
-
*/
|
|
29
|
-
const proseWeightOverrides = [
|
|
30
|
-
"prose-headings:font-normal",
|
|
31
|
-
"prose-strong:font-semibold",
|
|
32
|
-
"prose-code:font-normal",
|
|
33
|
-
"prose-blockquote:font-normal",
|
|
34
|
-
"prose-a:font-normal"
|
|
35
|
-
].join(" ");
|
|
36
|
-
|
|
37
|
-
const md = new MarkdownIt({ html: false });
|
|
38
|
-
/**
|
|
39
|
-
* @group Preview components
|
|
40
|
-
*/
|
|
41
|
-
export const Markdown = React.memo<MarkdownProps>(function Markdown({
|
|
42
|
-
source,
|
|
43
|
-
className,
|
|
44
|
-
size = "medium"
|
|
45
|
-
}: MarkdownProps) {
|
|
46
|
-
const html = useMemo(() => {
|
|
47
|
-
return md.render(typeof source === "string" ? source : "");
|
|
48
|
-
}, [source]);
|
|
49
|
-
|
|
50
|
-
return <div
|
|
51
|
-
className={cls(proseClasses[size], "dark:prose-invert prose-headings:font-title", proseWeightOverrides, className)}
|
|
52
|
-
dangerouslySetInnerHTML={{ __html: html }}
|
|
53
|
-
/>;
|
|
54
|
-
}
|
|
55
|
-
, equal) as React.FunctionComponent<MarkdownProps>;
|
package/src/components/Menu.tsx
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
|
4
|
-
import { focusedDisabled, paperMixin } from "../styles";
|
|
5
|
-
import { cls } from "../util";
|
|
6
|
-
import { usePortalContainer } from "../hooks/PortalContainerContext";
|
|
7
|
-
|
|
8
|
-
export type MenuProps = {
|
|
9
|
-
children: React.ReactNode;
|
|
10
|
-
trigger: React.ReactNode;
|
|
11
|
-
|
|
12
|
-
open?: boolean;
|
|
13
|
-
defaultOpen?: boolean;
|
|
14
|
-
onOpenChange?(open: boolean): void;
|
|
15
|
-
|
|
16
|
-
portalContainer?: HTMLElement | null;
|
|
17
|
-
side?: "top" | "right" | "bottom" | "left";
|
|
18
|
-
align?: "start" | "center" | "end";
|
|
19
|
-
|
|
20
|
-
sideOffset?: number;
|
|
21
|
-
className?: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const Menu = React.forwardRef<
|
|
25
|
-
React.ElementRef<typeof DropdownMenu.Trigger>,
|
|
26
|
-
MenuProps
|
|
27
|
-
>(({
|
|
28
|
-
children,
|
|
29
|
-
trigger,
|
|
30
|
-
open,
|
|
31
|
-
defaultOpen,
|
|
32
|
-
side,
|
|
33
|
-
align,
|
|
34
|
-
onOpenChange,
|
|
35
|
-
portalContainer,
|
|
36
|
-
sideOffset = 4,
|
|
37
|
-
className
|
|
38
|
-
}, ref) => {
|
|
39
|
-
// Get the portal container from context
|
|
40
|
-
const contextContainer = usePortalContainer();
|
|
41
|
-
|
|
42
|
-
// Prioritize manual prop, fallback to context container
|
|
43
|
-
const finalContainer = (portalContainer ?? contextContainer ?? undefined) as HTMLElement | undefined;
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<DropdownMenu.Root
|
|
47
|
-
open={open}
|
|
48
|
-
defaultOpen={defaultOpen}
|
|
49
|
-
onOpenChange={onOpenChange}>
|
|
50
|
-
<DropdownMenu.Trigger
|
|
51
|
-
ref={ref}
|
|
52
|
-
asChild>
|
|
53
|
-
{trigger}
|
|
54
|
-
</DropdownMenu.Trigger>
|
|
55
|
-
<DropdownMenu.Portal container={finalContainer}>
|
|
56
|
-
<DropdownMenu.Content
|
|
57
|
-
side={side}
|
|
58
|
-
sideOffset={sideOffset}
|
|
59
|
-
align={align}
|
|
60
|
-
// `z-50` is the floating layer — the tier `Dialog`, `Sheet`,
|
|
61
|
-
// `Select` and `Tooltip` all sit on. Radix copies this value
|
|
62
|
-
// onto the popper wrapper it portals next to them, so at any
|
|
63
|
-
// lower value the menu opens *behind* the dialog or sheet it
|
|
64
|
-
// was opened from: visible in the DOM, painted under the
|
|
65
|
-
// overlay, and unclickable. Peers on this tier stack by mount
|
|
66
|
-
// order, which is what puts a menu above the dialog holding
|
|
67
|
-
// its trigger, and a dialog that menu opens above them both.
|
|
68
|
-
className={cls(paperMixin, focusedDisabled, "py-2 z-50", className)}>
|
|
69
|
-
{children}
|
|
70
|
-
</DropdownMenu.Content>
|
|
71
|
-
</DropdownMenu.Portal>
|
|
72
|
-
</DropdownMenu.Root>
|
|
73
|
-
);
|
|
74
|
-
})
|
|
75
|
-
Menu.displayName = "Menu"
|
|
76
|
-
|
|
77
|
-
export { Menu }
|
|
78
|
-
|
|
79
|
-
export type MenuItemProps = {
|
|
80
|
-
children: React.ReactNode;
|
|
81
|
-
dense?: boolean;
|
|
82
|
-
disabled?: boolean;
|
|
83
|
-
onClick?: (event: React.MouseEvent) => void;
|
|
84
|
-
className?: string;
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
export const MenuItem = React.memo(({
|
|
88
|
-
children,
|
|
89
|
-
dense = false, // Default value is false if not provided
|
|
90
|
-
disabled = false,
|
|
91
|
-
onClick,
|
|
92
|
-
className
|
|
93
|
-
}: MenuItemProps) => {
|
|
94
|
-
// Dynamically adjusting the class based on the "dense" prop
|
|
95
|
-
const classNames = cls(
|
|
96
|
-
onClick && !disabled && "cursor-pointer",
|
|
97
|
-
disabled && "opacity-50 cursor-not-allowed",
|
|
98
|
-
"rounded-md text-sm font-medium text-surface-accent-700 dark:text-surface-accent-300 flex items-center gap-4 transition-colors duration-150",
|
|
99
|
-
!disabled && "hover:bg-surface-accent-100 dark:hover:bg-surface-accent-900",
|
|
100
|
-
dense ? "px-4 py-1.5" : "px-4 py-2",
|
|
101
|
-
className
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
return (
|
|
105
|
-
<DropdownMenu.Item
|
|
106
|
-
className={classNames}
|
|
107
|
-
disabled={disabled}
|
|
108
|
-
onClick={disabled ? undefined : onClick}>
|
|
109
|
-
{children}
|
|
110
|
-
</DropdownMenu.Item>
|
|
111
|
-
);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
MenuItem.displayName = "MenuItem";
|