@eggspot/ui 0.0.0
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/eslint.config.js +4 -0
- package/package.json +66 -0
- package/postcss.config.mjs +1 -0
- package/src/components/Button.machine.tsx +50 -0
- package/src/components/Button.tsx +249 -0
- package/src/components/Button.variants.tsx +186 -0
- package/src/components/ButtonGroup.tsx +56 -0
- package/src/components/Calendar.tsx +275 -0
- package/src/components/Calendar.utils.tsx +22 -0
- package/src/components/Checkbox.tsx +199 -0
- package/src/components/ConfirmDialog.tsx +183 -0
- package/src/components/DashboardLayout/DashboardLayout.tsx +348 -0
- package/src/components/DashboardLayout/SidebarNav.tsx +509 -0
- package/src/components/DashboardLayout/index.ts +33 -0
- package/src/components/DataTable/DataTable.tsx +557 -0
- package/src/components/DataTable/DataTableColumnHeader.tsx +122 -0
- package/src/components/DataTable/DataTableDisplaySettings.tsx +265 -0
- package/src/components/DataTable/DataTableFloatingBar.tsx +44 -0
- package/src/components/DataTable/DataTablePagination.tsx +168 -0
- package/src/components/DataTable/DataTableStates.tsx +69 -0
- package/src/components/DataTable/DataTableToolbarContainer.tsx +47 -0
- package/src/components/DataTable/hooks/use-data-table-settings.ts +101 -0
- package/src/components/DataTable/index.ts +7 -0
- package/src/components/DataTable/types/data-table.ts +97 -0
- package/src/components/DatePicker.tsx +213 -0
- package/src/components/DatePicker.utils.tsx +38 -0
- package/src/components/Datefield.tsx +109 -0
- package/src/components/Datefield.utils.ts +10 -0
- package/src/components/Dialog.tsx +167 -0
- package/src/components/Field.tsx +49 -0
- package/src/components/Filter/Filter.store.tsx +122 -0
- package/src/components/Filter/Filter.tsx +11 -0
- package/src/components/Filter/Filter.types.ts +107 -0
- package/src/components/Filter/FilterBar.tsx +38 -0
- package/src/components/Filter/FilterBuilder.tsx +158 -0
- package/src/components/Filter/FilterField/DateModeRowValue.tsx +250 -0
- package/src/components/Filter/FilterField/FilterAsyncSelect.tsx +191 -0
- package/src/components/Filter/FilterField/FilterDateMode.tsx +241 -0
- package/src/components/Filter/FilterField/FilterDateRange.tsx +169 -0
- package/src/components/Filter/FilterField/FilterSelect.tsx +208 -0
- package/src/components/Filter/FilterField/FilterSingleDate.tsx +277 -0
- package/src/components/Filter/FilterField/OptionItem.tsx +112 -0
- package/src/components/Filter/FilterField/index.ts +6 -0
- package/src/components/Filter/FilterRow.tsx +527 -0
- package/src/components/Filter/index.ts +17 -0
- package/src/components/Form.tsx +195 -0
- package/src/components/Heading.tsx +41 -0
- package/src/components/Input.tsx +221 -0
- package/src/components/InputOTP.tsx +78 -0
- package/src/components/Label.tsx +65 -0
- package/src/components/Layout.tsx +129 -0
- package/src/components/ListBox.tsx +97 -0
- package/src/components/Menu.tsx +152 -0
- package/src/components/NativeSelect.tsx +77 -0
- package/src/components/NumberInput.tsx +114 -0
- package/src/components/Popover.tsx +44 -0
- package/src/components/Provider.tsx +22 -0
- package/src/components/RadioGroup.tsx +191 -0
- package/src/components/Resizable.tsx +71 -0
- package/src/components/ScrollArea.tsx +57 -0
- package/src/components/Select.tsx +626 -0
- package/src/components/Select.utils.tsx +64 -0
- package/src/components/Separator.tsx +25 -0
- package/src/components/Sheet.tsx +147 -0
- package/src/components/Sonner.tsx +96 -0
- package/src/components/Spinner.tsx +30 -0
- package/src/components/Switch.tsx +51 -0
- package/src/components/Text.tsx +35 -0
- package/src/components/Tooltip.tsx +58 -0
- package/src/consts/config.ts +2 -0
- package/src/hooks/.gitkeep +0 -0
- package/src/lib/utils.ts +10 -0
- package/tsconfig.json +11 -0
- package/tsconfig.lint.json +8 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Label } from "@eggspot/ui/components/Label"
|
|
4
|
+
import { cn } from "@eggspot/ui/lib/utils"
|
|
5
|
+
import { useControllableState } from "@radix-ui/react-use-controllable-state"
|
|
6
|
+
import { cva, VariantProps } from "class-variance-authority"
|
|
7
|
+
import { Circle } from "lucide-react"
|
|
8
|
+
import {
|
|
9
|
+
Radio as AriaRadio,
|
|
10
|
+
RadioGroup as AriaRadioGroup,
|
|
11
|
+
RadioGroupProps as AriaRadioGroupProps,
|
|
12
|
+
RadioProps as AriaRadioProps,
|
|
13
|
+
composeRenderProps,
|
|
14
|
+
} from "react-aria-components"
|
|
15
|
+
|
|
16
|
+
function BaseRadioGroup({ className, ...props }: AriaRadioGroupProps) {
|
|
17
|
+
return (
|
|
18
|
+
<AriaRadioGroup
|
|
19
|
+
aria-label="radio"
|
|
20
|
+
className={composeRenderProps(className, (className, renderProps) =>
|
|
21
|
+
cn("group/radiogroup flex flex-col flex-wrap gap-2", className)
|
|
22
|
+
)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const radioVariants = cva(
|
|
29
|
+
[
|
|
30
|
+
"group/radio flex cursor-pointer items-center text-sm",
|
|
31
|
+
/* Disabled */
|
|
32
|
+
"data-[disabled]:cursor-not-allowed data-[disabled]:opacity-70",
|
|
33
|
+
/* Invalid */
|
|
34
|
+
"data-[invalid]:text-error-11",
|
|
35
|
+
],
|
|
36
|
+
{
|
|
37
|
+
variants: {
|
|
38
|
+
variant: {
|
|
39
|
+
default: ["group/default gap-x-2"],
|
|
40
|
+
card: [
|
|
41
|
+
"gap-x-3.5",
|
|
42
|
+
"border-gray-7 rounded-md border p-3.5 transition-all duration-200",
|
|
43
|
+
/* Selected */
|
|
44
|
+
"bg-gray-2 data-selected:border-accent-9 data-selected:bg-accent-2 data-selected:border-1",
|
|
45
|
+
/* Hovered */
|
|
46
|
+
"data-hovered:border-gray-8",
|
|
47
|
+
/* Focus Visible */
|
|
48
|
+
"ring-offset-2 data-focus-visible:ring-2 data-pressed:scale-[0.99]",
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
function Radio({
|
|
56
|
+
className,
|
|
57
|
+
children,
|
|
58
|
+
variant = "default",
|
|
59
|
+
...props
|
|
60
|
+
}: AriaRadioProps & VariantProps<typeof radioVariants>) {
|
|
61
|
+
return (
|
|
62
|
+
<AriaRadio className={radioVariants({ variant })} {...props}>
|
|
63
|
+
{composeRenderProps(children, (children, renderProps) => (
|
|
64
|
+
<>
|
|
65
|
+
<span
|
|
66
|
+
className={cn(
|
|
67
|
+
"transition-colors",
|
|
68
|
+
"bg-gray-2 text-accent-contrast ring-offset-gray-1 flex aspect-square size-4 items-center justify-center rounded-full border",
|
|
69
|
+
/* Focus */
|
|
70
|
+
"group-data-[focused]/radio:outline-none",
|
|
71
|
+
/* Focus Visible */
|
|
72
|
+
"group-data-[focus-visible]/default:ring-2 group-data-[focus-visible]/default:ring-offset-2",
|
|
73
|
+
/* Selected */
|
|
74
|
+
"group-data-[selected]/radio:bg-accent-9 group-data-[selected]/radio:border-accent-9",
|
|
75
|
+
/* Hovered */
|
|
76
|
+
"group-data-hovered/radio:border-gray-8",
|
|
77
|
+
/* Pressed */
|
|
78
|
+
"group-data-pressed/radio:scale-[0.95]",
|
|
79
|
+
/* Selected Dark */
|
|
80
|
+
"dark:group-data-[selected]/radio:border-none",
|
|
81
|
+
/* Disabled */
|
|
82
|
+
"group-data-[disabled]/radio:cursor-not-allowed group-data-[disabled]/radio:opacity-50"
|
|
83
|
+
)}
|
|
84
|
+
>
|
|
85
|
+
{renderProps.isSelected && (
|
|
86
|
+
<Circle
|
|
87
|
+
className={cn(
|
|
88
|
+
"animate-in fade-in-0 zoom-in-60 size-1.5 fill-current text-current"
|
|
89
|
+
)}
|
|
90
|
+
/>
|
|
91
|
+
)}
|
|
92
|
+
</span>
|
|
93
|
+
{children}
|
|
94
|
+
</>
|
|
95
|
+
))}
|
|
96
|
+
</AriaRadio>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
interface RadioOption {
|
|
101
|
+
value: string | number
|
|
102
|
+
label: string
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
interface RadioGroupProps<T extends RadioOption>
|
|
106
|
+
extends Omit<AriaRadioGroupProps, "value" | "onChange" | "defaultValue"> {
|
|
107
|
+
/** The label for the radio group. */
|
|
108
|
+
label?: string
|
|
109
|
+
|
|
110
|
+
/** The options for the radio group. */
|
|
111
|
+
options: Array<T>
|
|
112
|
+
|
|
113
|
+
/** The variant for the radio group. */
|
|
114
|
+
variant?: "default" | "card"
|
|
115
|
+
|
|
116
|
+
/** The class name for the radio group. */
|
|
117
|
+
className?: string
|
|
118
|
+
|
|
119
|
+
/** Whether to show an asterisk for the label. */
|
|
120
|
+
withAsterisk?: boolean
|
|
121
|
+
|
|
122
|
+
/** The tooltip for the radio group. */
|
|
123
|
+
tooltip?: React.ReactNode
|
|
124
|
+
|
|
125
|
+
/** Custom rendering function for each option in the radio group. */
|
|
126
|
+
renderOption?: (option: T) => React.ReactNode
|
|
127
|
+
|
|
128
|
+
/** If this prop is set, the radio group operates in a controlled manner and uses this value as its state. */
|
|
129
|
+
value?: T
|
|
130
|
+
|
|
131
|
+
/** If this prop is set, the radio group will call this function with the new value whenever the value changes. */
|
|
132
|
+
onChange?: (value: T | undefined) => void
|
|
133
|
+
|
|
134
|
+
/** Initial value used when the component is uncontrolled. */
|
|
135
|
+
defaultValue?: T
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function RadioGroup<T extends RadioOption>({
|
|
139
|
+
options,
|
|
140
|
+
renderOption,
|
|
141
|
+
variant = "default",
|
|
142
|
+
className,
|
|
143
|
+
label,
|
|
144
|
+
withAsterisk,
|
|
145
|
+
tooltip,
|
|
146
|
+
value: controlledValue,
|
|
147
|
+
onChange: controlledOnChange,
|
|
148
|
+
defaultValue,
|
|
149
|
+
...props
|
|
150
|
+
}: RadioGroupProps<T>) {
|
|
151
|
+
const [value, onChange] = useControllableState<T | undefined>({
|
|
152
|
+
prop: controlledValue,
|
|
153
|
+
defaultProp: defaultValue,
|
|
154
|
+
onChange: controlledOnChange,
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<BaseRadioGroup
|
|
159
|
+
value={JSON.stringify(value)}
|
|
160
|
+
onChange={(v) => onChange(JSON.parse(v))}
|
|
161
|
+
{...props}
|
|
162
|
+
>
|
|
163
|
+
{label && (
|
|
164
|
+
<Label withAsterisk={withAsterisk} tooltip={tooltip}>
|
|
165
|
+
{label}
|
|
166
|
+
</Label>
|
|
167
|
+
)}
|
|
168
|
+
<div
|
|
169
|
+
className={cn(
|
|
170
|
+
"grid",
|
|
171
|
+
variant === "card" && "gap-2.5",
|
|
172
|
+
variant === "default" && "gap-1.5",
|
|
173
|
+
className
|
|
174
|
+
)}
|
|
175
|
+
>
|
|
176
|
+
{options.map((option) => (
|
|
177
|
+
<Radio
|
|
178
|
+
key={option.value}
|
|
179
|
+
value={JSON.stringify(option)}
|
|
180
|
+
variant={variant}
|
|
181
|
+
>
|
|
182
|
+
{renderOption ? renderOption(option) : option.label}
|
|
183
|
+
</Radio>
|
|
184
|
+
))}
|
|
185
|
+
</div>
|
|
186
|
+
</BaseRadioGroup>
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export { BaseRadioGroup, Radio, RadioGroup }
|
|
191
|
+
export type { RadioGroupProps, RadioOption }
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cn } from "@eggspot/ui/lib/utils"
|
|
3
|
+
import { GripVerticalIcon } from "lucide-react"
|
|
4
|
+
import * as AriaResizable from "react-resizable-panels"
|
|
5
|
+
|
|
6
|
+
function ResizablePanelGroup({
|
|
7
|
+
className,
|
|
8
|
+
...props
|
|
9
|
+
}: React.ComponentProps<typeof AriaResizable.PanelGroup>) {
|
|
10
|
+
return (
|
|
11
|
+
<AriaResizable.PanelGroup
|
|
12
|
+
data-slot="resizable-panel-group"
|
|
13
|
+
className={cn(
|
|
14
|
+
"flex h-full w-full",
|
|
15
|
+
"data-[panel-group-direction=vertical]:flex-col",
|
|
16
|
+
className
|
|
17
|
+
)}
|
|
18
|
+
{...props}
|
|
19
|
+
/>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const ResizablePanel = React.forwardRef<
|
|
24
|
+
React.ComponentRef<typeof AriaResizable.Panel>,
|
|
25
|
+
React.ComponentProps<typeof AriaResizable.Panel>
|
|
26
|
+
>((props, ref) => {
|
|
27
|
+
return (
|
|
28
|
+
<AriaResizable.Panel ref={ref} data-slot="resizable-panel" {...props} />
|
|
29
|
+
)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
ResizablePanel.displayName = "ResizablePanel"
|
|
33
|
+
|
|
34
|
+
function ResizableHandle({
|
|
35
|
+
withHandle,
|
|
36
|
+
className,
|
|
37
|
+
...props
|
|
38
|
+
}: React.ComponentProps<typeof AriaResizable.PanelResizeHandle> & {
|
|
39
|
+
withHandle?: boolean
|
|
40
|
+
}) {
|
|
41
|
+
return (
|
|
42
|
+
<AriaResizable.PanelResizeHandle
|
|
43
|
+
data-slot="resizable-handle"
|
|
44
|
+
className={cn(
|
|
45
|
+
"relative flex items-center justify-center",
|
|
46
|
+
"data-[panel-group-direction=horizontal]:h-full data-[panel-group-direction=horizontal]:w-px data-[panel-group-direction=horizontal]:self-center",
|
|
47
|
+
"data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full",
|
|
48
|
+
"bg-gray-6",
|
|
49
|
+
// "cursor-grab! data-resize-handle-active:cursor-grabbing!",
|
|
50
|
+
"hover:bg-gray-7 data-resize-handle-active:bg-accent-9",
|
|
51
|
+
"transition-colors duration-150",
|
|
52
|
+
className
|
|
53
|
+
)}
|
|
54
|
+
{...props}
|
|
55
|
+
>
|
|
56
|
+
{withHandle && (
|
|
57
|
+
<div
|
|
58
|
+
className={cn(
|
|
59
|
+
"bg-gray-5 text-gray-11 pointer-events-none z-10 flex h-5 w-3 items-center justify-center rounded-full shadow-sm",
|
|
60
|
+
"opacity-0 transition-opacity group-hover:opacity-100",
|
|
61
|
+
"data-[panel-group-direction=vertical]:rotate-90"
|
|
62
|
+
)}
|
|
63
|
+
>
|
|
64
|
+
<GripVerticalIcon className="size-3" aria-hidden="true" />
|
|
65
|
+
</div>
|
|
66
|
+
)}
|
|
67
|
+
</AriaResizable.PanelResizeHandle>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { ResizableHandle, ResizablePanel, ResizablePanelGroup }
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { cn } from "@eggspot/ui/lib/utils"
|
|
5
|
+
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
|
|
6
|
+
|
|
7
|
+
function ScrollArea({
|
|
8
|
+
className,
|
|
9
|
+
children,
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
|
12
|
+
return (
|
|
13
|
+
<ScrollAreaPrimitive.Root
|
|
14
|
+
data-slot="scroll-area"
|
|
15
|
+
className={cn("relative", className)}
|
|
16
|
+
{...props}
|
|
17
|
+
>
|
|
18
|
+
<ScrollAreaPrimitive.Viewport
|
|
19
|
+
data-slot="scroll-area-viewport"
|
|
20
|
+
className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
|
|
21
|
+
>
|
|
22
|
+
{children}
|
|
23
|
+
</ScrollAreaPrimitive.Viewport>
|
|
24
|
+
<ScrollBar />
|
|
25
|
+
<ScrollAreaPrimitive.Corner />
|
|
26
|
+
</ScrollAreaPrimitive.Root>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function ScrollBar({
|
|
31
|
+
className,
|
|
32
|
+
orientation = "vertical",
|
|
33
|
+
...props
|
|
34
|
+
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
|
|
35
|
+
return (
|
|
36
|
+
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
|
37
|
+
data-slot="scroll-area-scrollbar"
|
|
38
|
+
orientation={orientation}
|
|
39
|
+
className={cn(
|
|
40
|
+
"flex touch-none p-px transition-colors select-none",
|
|
41
|
+
orientation === "vertical" &&
|
|
42
|
+
"h-full w-2.5 border-l border-l-transparent",
|
|
43
|
+
orientation === "horizontal" &&
|
|
44
|
+
"h-2.5 flex-col border-t border-t-transparent",
|
|
45
|
+
className
|
|
46
|
+
)}
|
|
47
|
+
{...props}
|
|
48
|
+
>
|
|
49
|
+
<ScrollAreaPrimitive.ScrollAreaThumb
|
|
50
|
+
data-slot="scroll-area-thumb"
|
|
51
|
+
className="bg-gray-11/20 relative flex-1 rounded-full"
|
|
52
|
+
/>
|
|
53
|
+
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { ScrollArea, ScrollBar }
|