@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.
Files changed (74) hide show
  1. package/eslint.config.js +4 -0
  2. package/package.json +66 -0
  3. package/postcss.config.mjs +1 -0
  4. package/src/components/Button.machine.tsx +50 -0
  5. package/src/components/Button.tsx +249 -0
  6. package/src/components/Button.variants.tsx +186 -0
  7. package/src/components/ButtonGroup.tsx +56 -0
  8. package/src/components/Calendar.tsx +275 -0
  9. package/src/components/Calendar.utils.tsx +22 -0
  10. package/src/components/Checkbox.tsx +199 -0
  11. package/src/components/ConfirmDialog.tsx +183 -0
  12. package/src/components/DashboardLayout/DashboardLayout.tsx +348 -0
  13. package/src/components/DashboardLayout/SidebarNav.tsx +509 -0
  14. package/src/components/DashboardLayout/index.ts +33 -0
  15. package/src/components/DataTable/DataTable.tsx +557 -0
  16. package/src/components/DataTable/DataTableColumnHeader.tsx +122 -0
  17. package/src/components/DataTable/DataTableDisplaySettings.tsx +265 -0
  18. package/src/components/DataTable/DataTableFloatingBar.tsx +44 -0
  19. package/src/components/DataTable/DataTablePagination.tsx +168 -0
  20. package/src/components/DataTable/DataTableStates.tsx +69 -0
  21. package/src/components/DataTable/DataTableToolbarContainer.tsx +47 -0
  22. package/src/components/DataTable/hooks/use-data-table-settings.ts +101 -0
  23. package/src/components/DataTable/index.ts +7 -0
  24. package/src/components/DataTable/types/data-table.ts +97 -0
  25. package/src/components/DatePicker.tsx +213 -0
  26. package/src/components/DatePicker.utils.tsx +38 -0
  27. package/src/components/Datefield.tsx +109 -0
  28. package/src/components/Datefield.utils.ts +10 -0
  29. package/src/components/Dialog.tsx +167 -0
  30. package/src/components/Field.tsx +49 -0
  31. package/src/components/Filter/Filter.store.tsx +122 -0
  32. package/src/components/Filter/Filter.tsx +11 -0
  33. package/src/components/Filter/Filter.types.ts +107 -0
  34. package/src/components/Filter/FilterBar.tsx +38 -0
  35. package/src/components/Filter/FilterBuilder.tsx +158 -0
  36. package/src/components/Filter/FilterField/DateModeRowValue.tsx +250 -0
  37. package/src/components/Filter/FilterField/FilterAsyncSelect.tsx +191 -0
  38. package/src/components/Filter/FilterField/FilterDateMode.tsx +241 -0
  39. package/src/components/Filter/FilterField/FilterDateRange.tsx +169 -0
  40. package/src/components/Filter/FilterField/FilterSelect.tsx +208 -0
  41. package/src/components/Filter/FilterField/FilterSingleDate.tsx +277 -0
  42. package/src/components/Filter/FilterField/OptionItem.tsx +112 -0
  43. package/src/components/Filter/FilterField/index.ts +6 -0
  44. package/src/components/Filter/FilterRow.tsx +527 -0
  45. package/src/components/Filter/index.ts +17 -0
  46. package/src/components/Form.tsx +195 -0
  47. package/src/components/Heading.tsx +41 -0
  48. package/src/components/Input.tsx +221 -0
  49. package/src/components/InputOTP.tsx +78 -0
  50. package/src/components/Label.tsx +65 -0
  51. package/src/components/Layout.tsx +129 -0
  52. package/src/components/ListBox.tsx +97 -0
  53. package/src/components/Menu.tsx +152 -0
  54. package/src/components/NativeSelect.tsx +77 -0
  55. package/src/components/NumberInput.tsx +114 -0
  56. package/src/components/Popover.tsx +44 -0
  57. package/src/components/Provider.tsx +22 -0
  58. package/src/components/RadioGroup.tsx +191 -0
  59. package/src/components/Resizable.tsx +71 -0
  60. package/src/components/ScrollArea.tsx +57 -0
  61. package/src/components/Select.tsx +626 -0
  62. package/src/components/Select.utils.tsx +64 -0
  63. package/src/components/Separator.tsx +25 -0
  64. package/src/components/Sheet.tsx +147 -0
  65. package/src/components/Sonner.tsx +96 -0
  66. package/src/components/Spinner.tsx +30 -0
  67. package/src/components/Switch.tsx +51 -0
  68. package/src/components/Text.tsx +35 -0
  69. package/src/components/Tooltip.tsx +58 -0
  70. package/src/consts/config.ts +2 -0
  71. package/src/hooks/.gitkeep +0 -0
  72. package/src/lib/utils.ts +10 -0
  73. package/tsconfig.json +11 -0
  74. package/tsconfig.lint.json +8 -0
@@ -0,0 +1,147 @@
1
+ "use client"
2
+
3
+ import React from "react"
4
+ import { Button } from "@eggspot/ui/components/Button"
5
+ import { cn } from "@eggspot/ui/lib/utils"
6
+ import { X } from "lucide-react"
7
+ import {
8
+ Dialog as AriaDialog,
9
+ DialogProps as AriaDialogProps,
10
+ DialogTrigger as AriaDialogTrigger,
11
+ Heading as AriaHeading,
12
+ HeadingProps as AriaHeadingProps,
13
+ Modal as AriaModal,
14
+ ModalOverlay as AriaModalOverlay,
15
+ ModalOverlayProps as AriaModalOverlayProps,
16
+ composeRenderProps,
17
+ } from "react-aria-components"
18
+
19
+ const Sheet = AriaDialog
20
+
21
+ const SheetTrigger = AriaDialogTrigger
22
+
23
+ const SheetOverlay = ({
24
+ className,
25
+ isDismissable = true,
26
+ ...props
27
+ }: AriaModalOverlayProps) => (
28
+ <AriaModalOverlay
29
+ isDismissable={isDismissable}
30
+ className={composeRenderProps(className, (className) =>
31
+ cn(
32
+ "fixed inset-0 z-50 bg-black/50 duration-300",
33
+ /* Exiting */
34
+ "data-[exiting]:animate-out data-[exiting]:fade-out-0",
35
+ /* Entering */
36
+ "data-[entering]:animate-in data-[entering]:fade-in-0",
37
+ className
38
+ )
39
+ )}
40
+ {...props}
41
+ />
42
+ )
43
+
44
+ interface SheetContentProps
45
+ extends Omit<React.ComponentProps<typeof AriaModal>, "children"> {
46
+ children?: AriaDialogProps["children"]
47
+ role?: AriaDialogProps["role"]
48
+ closeButton?: boolean
49
+ side?: "top" | "right" | "bottom" | "left"
50
+ }
51
+
52
+ const SheetContent = ({
53
+ className,
54
+ children,
55
+ role,
56
+ closeButton = true,
57
+ side = "right",
58
+ ...props
59
+ }: SheetContentProps) => (
60
+ <SheetOverlay>
61
+ <AriaModal
62
+ className={composeRenderProps(className, (className) =>
63
+ cn(
64
+ "bg-gray-1 data-[entering]:animate-in data-[exiting]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition duration-300 ease-in-out",
65
+ side === "right" &&
66
+ "data-[exiting]:slide-out-to-right data-[entering]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
67
+ side === "left" &&
68
+ "data-[exiting]:slide-out-to-left data-[entering]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
69
+ side === "top" &&
70
+ "data-[exiting]:slide-out-to-top data-[entering]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
71
+ side === "bottom" &&
72
+ "data-[exiting]:slide-out-to-bottom data-[entering]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
73
+ className
74
+ )
75
+ )}
76
+ {...props}
77
+ >
78
+ <AriaDialog
79
+ role={role}
80
+ className={cn("grid h-full gap-4", "h-full outline-none")}
81
+ >
82
+ {composeRenderProps(children, (children, renderProps) => (
83
+ <>
84
+ {children}
85
+ {closeButton && (
86
+ <Button
87
+ onClick={renderProps.close}
88
+ mode="icon"
89
+ variant="ghost"
90
+ tooltip="Close"
91
+ tooltipDelay={2000}
92
+ className="absolute top-2.5 right-2.5"
93
+ >
94
+ <X className="text-gray-11 size-4!" />
95
+ <span className="sr-only">Close</span>
96
+ </Button>
97
+ )}
98
+ </>
99
+ ))}
100
+ </AriaDialog>
101
+ </AriaModal>
102
+ </SheetOverlay>
103
+ )
104
+
105
+ const SheetHeader = ({
106
+ className,
107
+ ...props
108
+ }: React.HTMLAttributes<HTMLDivElement>) => (
109
+ <div className={cn("flex flex-col gap-1.5 p-4", className)} {...props} />
110
+ )
111
+
112
+ const SheetFooter = ({
113
+ className,
114
+ ...props
115
+ }: React.HTMLAttributes<HTMLDivElement>) => (
116
+ <div
117
+ className={cn("mt-auto flex flex-col gap-2 p-4", className)}
118
+ {...props}
119
+ />
120
+ )
121
+
122
+ const SheetTitle = ({ className, ...props }: AriaHeadingProps) => (
123
+ <AriaHeading
124
+ slot="title"
125
+ className={cn("text-gray-11 font-semibold", className)}
126
+ {...props}
127
+ />
128
+ )
129
+
130
+ const SheetDescription = ({
131
+ className,
132
+ ...props
133
+ }: React.HTMLAttributes<HTMLParagraphElement>) => (
134
+ <p className={cn("text-gray-11 text-sm", className)} {...props} />
135
+ )
136
+
137
+ export {
138
+ Sheet,
139
+ SheetContent,
140
+ SheetDescription,
141
+ SheetFooter,
142
+ SheetHeader,
143
+ SheetOverlay,
144
+ SheetTitle,
145
+ SheetTrigger,
146
+ }
147
+ export type { SheetContentProps }
@@ -0,0 +1,96 @@
1
+ "use client"
2
+
3
+ import { Button } from "@eggspot/ui/components/Button"
4
+ import {
5
+ AlertTriangleIcon,
6
+ CircleCheckIcon,
7
+ CircleXIcon,
8
+ InfoIcon,
9
+ XIcon,
10
+ } from "lucide-react"
11
+ import { toast as sonnerToast, Toaster, ToastT } from "sonner"
12
+
13
+ interface ToastProps {
14
+ id: string | number
15
+ title: string
16
+ description?: React.ReactNode
17
+ variant?: "success" | "error" | "info" | "warning" | "neutral"
18
+ }
19
+
20
+ /** A fully custom toast that still maintains the animations and interactions. */
21
+ function Toast(props: ToastProps) {
22
+ const { title, description, id, variant = "neutral" } = props
23
+
24
+ return (
25
+ <div className="group bg-gray-2 text-gray-12 relative flex min-h-[64px] w-full items-center gap-3 rounded-xl border px-4 py-2.5 pr-7 shadow-lg md:w-[364px]">
26
+ <ToastIcon variant={variant} />
27
+ <div className="flex flex-1 items-center">
28
+ <div className="w-full">
29
+ <p className="text-gray-12 text-sm font-semibold">{title}</p>
30
+ {description && (
31
+ <div className="text-gray-11 mt-0.5 text-sm">{description}</div>
32
+ )}
33
+ </div>
34
+ </div>
35
+ <Button
36
+ size="sm"
37
+ mode="icon"
38
+ variant="ghost"
39
+ onClick={() => sonnerToast.dismiss(id)}
40
+ className="absolute top-1.5 right-1.5 opacity-0 transition-opacity group-hover:opacity-100"
41
+ >
42
+ <XIcon className="text-gray-11 h-4 w-4" />
43
+ </Button>
44
+ </div>
45
+ )
46
+ }
47
+
48
+ function ToastIcon({ variant }: { variant: ToastProps["variant"] }) {
49
+ if (variant === "neutral") {
50
+ return null
51
+ }
52
+
53
+ return (
54
+ <>
55
+ {variant === "success" && (
56
+ <CircleCheckIcon className="text-success-9 size-5" />
57
+ )}
58
+ {variant === "error" && <CircleXIcon className="text-error-9 size-5" />}
59
+ {variant === "info" && <InfoIcon className="text-info-9 size-5" />}
60
+ {variant === "warning" && (
61
+ <AlertTriangleIcon className="text-warning-9 size-5" />
62
+ )}
63
+ </>
64
+ )
65
+ }
66
+
67
+ function createToast(variant: ToastProps["variant"]) {
68
+ return (
69
+ props: Omit<ToastProps, "id" | "variant">,
70
+ options: Pick<ToastT, "position" | "duration"> = {}
71
+ ) => {
72
+ return sonnerToast.custom(
73
+ (id) => <Toast id={id} variant={variant} {...props} />,
74
+ {
75
+ position: "bottom-right",
76
+ ...options,
77
+ }
78
+ )
79
+ }
80
+ }
81
+
82
+ const success = createToast("success")
83
+ const error = createToast("error")
84
+ const info = createToast("info")
85
+ const warning = createToast("warning")
86
+ const neutral = createToast("neutral")
87
+
88
+ const toast = {
89
+ success,
90
+ error,
91
+ info,
92
+ warning,
93
+ neutral,
94
+ }
95
+
96
+ export { toast, Toaster }
@@ -0,0 +1,30 @@
1
+ import { cn } from "@eggspot/ui/lib/utils"
2
+
3
+ function Spinner({ className, ...props }: React.ComponentProps<"svg">) {
4
+ return (
5
+ <svg
6
+ xmlns="http://www.w3.org/2000/svg"
7
+ fill="none"
8
+ aria-hidden="true"
9
+ className={cn("size-5 animate-spin", className)}
10
+ viewBox="0 0 24 24"
11
+ {...props}
12
+ >
13
+ <circle
14
+ cx="12"
15
+ cy="12"
16
+ r="10"
17
+ stroke="currentColor"
18
+ strokeWidth="4"
19
+ className="opacity-25"
20
+ ></circle>
21
+ <path
22
+ fill="currentColor"
23
+ d="M4 12a8 8 0 0 1 8-8V0C5.373 0 0 5.373 0 12zm2 5.291A7.96 7.96 0 0 1 4 12H0c0 3.042 1.135 5.824 3 7.938z"
24
+ className="opacity-75"
25
+ ></path>
26
+ </svg>
27
+ )
28
+ }
29
+
30
+ export { Spinner }
@@ -0,0 +1,51 @@
1
+ "use client"
2
+
3
+ import { cn } from "@eggspot/ui/lib/utils"
4
+ import {
5
+ Switch as AriaSwitch,
6
+ SwitchProps as AriaSwitchProps,
7
+ composeRenderProps,
8
+ } from "react-aria-components"
9
+
10
+ const Switch = ({ children, className, ...props }: AriaSwitchProps) => (
11
+ <AriaSwitch
12
+ className={composeRenderProps(className, (className) =>
13
+ cn(
14
+ "group inline-flex items-center gap-2 text-sm leading-none font-medium data-[disabled]:cursor-not-allowed data-[disabled]:opacity-70",
15
+ className
16
+ )
17
+ )}
18
+ {...props}
19
+ >
20
+ {composeRenderProps(children, (children) => (
21
+ <>
22
+ <div
23
+ className={cn(
24
+ "peer border-gray-7 inline-flex h-5.5 w-11 shrink-0 cursor-pointer items-center rounded-full border transition-colors",
25
+ /* Focus Visible */
26
+ "group-data-[focus-visible]:ring-ring group-data-[focus-visible]:ring-offset-gray-1 group-data-[focus-visible]:ring-2 group-data-[focus-visible]:ring-offset-2 group-data-[focus-visible]:outline-none",
27
+ /* Disabled */
28
+ "group-data-disabled:cursor-not-allowed group-data-disabled:opacity-50",
29
+ /* Selected */
30
+ "bg-gray-3 group-data-selected:bg-accent-9 group-data-selected:border-accent-9",
31
+ /* Readonly */
32
+ "group-data-readonly:cursor-default",
33
+ /* Resets */
34
+ "focus-visible:outline-none"
35
+ )}
36
+ >
37
+ <div
38
+ className={cn(
39
+ "bg-gray-9 pointer-events-none block size-4 rounded-full shadow-lg ring-0 transition-transform",
40
+ /* Selected */
41
+ "group-data-selected:bg-accent-contrast translate-x-[3px] group-data-selected:translate-x-[24px]"
42
+ )}
43
+ />
44
+ </div>
45
+ {children}
46
+ </>
47
+ ))}
48
+ </AriaSwitch>
49
+ )
50
+
51
+ export { Switch }
@@ -0,0 +1,35 @@
1
+ import { cn } from "@eggspot/ui/lib/utils"
2
+ import { cva, VariantProps } from "class-variance-authority"
3
+ import { Slot } from "radix-ui"
4
+
5
+ const textVariants = cva("", {
6
+ variants: {
7
+ variant: {
8
+ body1: "text-base",
9
+ body2: "text-sm",
10
+ caption: "text-xs",
11
+ overline: "text-gray-11 text-xs",
12
+ },
13
+ },
14
+ defaultVariants: {
15
+ variant: "body1",
16
+ },
17
+ })
18
+ interface TextProps
19
+ extends React.ComponentProps<"p">,
20
+ VariantProps<typeof textVariants> {
21
+ asChild?: boolean
22
+ }
23
+
24
+ export function Text({
25
+ className,
26
+ asChild = false,
27
+ variant,
28
+ ...props
29
+ }: TextProps) {
30
+ const Comp = asChild ? Slot.Root : "p"
31
+
32
+ return (
33
+ <Comp className={cn(textVariants({ variant, className }))} {...props} />
34
+ )
35
+ }
@@ -0,0 +1,58 @@
1
+ "use client"
2
+
3
+ import React from "react"
4
+ import { cva } from "class-variance-authority"
5
+ import {
6
+ Tooltip as AriaTooltip,
7
+ TooltipProps as AriaTooltipProps,
8
+ TooltipTrigger as AriaTooltipTrigger,
9
+ composeRenderProps,
10
+ OverlayArrow,
11
+ } from "react-aria-components"
12
+
13
+ export const TooltipTrigger = AriaTooltipTrigger
14
+
15
+ export interface TooltipProps extends Omit<AriaTooltipProps, "children"> {
16
+ children: React.ReactNode
17
+ }
18
+
19
+ const styles = cva(
20
+ [
21
+ "bg-gray-2 max-w-lg",
22
+ "group rounded-md border px-2 py-1 text-sm drop-shadow-lg will-change-transform",
23
+ ],
24
+ {
25
+ variants: {
26
+ isEntering: {
27
+ true: 'animate-in fade-in data-[placement="bottom"]:slide-in-from-top-20 data-[placement="top"]:slide-in-from-bottom-20 data-[placement="left"]:slide-in-from-right-20 data-[placement="right"]:slide-in-from-left-20 duration-200 ease-out',
28
+ },
29
+ isExiting: {
30
+ true: 'animate-out fade-out data-[placement="bottom"]:slide-out-to-top-20 data-[placement="top"]:slide-out-to-bottom-20 data-[placement="left"]:slide-out-to-right-20 data-[placement="right"]:slide-out-to-left-20 duration-150 ease-in',
31
+ },
32
+ },
33
+ }
34
+ )
35
+
36
+ export function Tooltip({ children, ...props }: TooltipProps) {
37
+ return (
38
+ <AriaTooltip
39
+ {...props}
40
+ offset={10}
41
+ className={composeRenderProps(props.className, (className, renderProps) =>
42
+ styles({ ...renderProps, className })
43
+ )}
44
+ >
45
+ <OverlayArrow>
46
+ <svg
47
+ width={8}
48
+ height={8}
49
+ viewBox="0 0 8 8"
50
+ className='fill-gray-2 stroke-gray-6 group-data-[placement="bottom"]:rotate-180 group-data-[placement="left"]:-rotate-90 group-data-[placement="right"]:rotate-90'
51
+ >
52
+ <path d="M0 0 L4 4 L8 0" />
53
+ </svg>
54
+ </OverlayArrow>
55
+ {children}
56
+ </AriaTooltip>
57
+ )
58
+ }
@@ -0,0 +1,2 @@
1
+ export const MIN_YEAR = 1970
2
+ export const MAX_YEAR_FROM_NOW = 20
File without changes
@@ -0,0 +1,10 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
7
+
8
+ export function formatCount(num: number, max = 9): string {
9
+ return num > max ? `${max}+` : num.toString()
10
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "@workspace/typescript-config/react-library.json",
3
+ "compilerOptions": {
4
+ "baseUrl": ".",
5
+ "paths": {
6
+ "@eggspot/ui/*": ["./src/*"]
7
+ }
8
+ },
9
+ "include": ["."],
10
+ "exclude": ["node_modules", "dist"]
11
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "@workspace/typescript-config/react-library.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist"
5
+ },
6
+ "include": ["src", "turbo"],
7
+ "exclude": ["node_modules", "dist"]
8
+ }