@meta-1/design 0.0.159

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 (99) hide show
  1. package/README.md +412 -0
  2. package/package.json +138 -0
  3. package/src/assets/icons/empty.svg +1 -0
  4. package/src/assets/icons/spin.svg +1 -0
  5. package/src/assets/locales/en-us.ts +74 -0
  6. package/src/assets/locales/zh-cn.ts +74 -0
  7. package/src/assets/locales/zh-tw.ts +74 -0
  8. package/src/assets/style/theme.css +173 -0
  9. package/src/components/icons/Empty.tsx +18 -0
  10. package/src/components/icons/Spin.tsx +16 -0
  11. package/src/components/icons/index.ts +2 -0
  12. package/src/components/ui/alert-dialog.tsx +111 -0
  13. package/src/components/ui/alert.tsx +49 -0
  14. package/src/components/ui/avatar.tsx +32 -0
  15. package/src/components/ui/badge.tsx +36 -0
  16. package/src/components/ui/breadcrumb.tsx +92 -0
  17. package/src/components/ui/button.tsx +52 -0
  18. package/src/components/ui/calendar.tsx +56 -0
  19. package/src/components/ui/card.tsx +56 -0
  20. package/src/components/ui/checkbox.tsx +28 -0
  21. package/src/components/ui/command.tsx +137 -0
  22. package/src/components/ui/dialog.tsx +127 -0
  23. package/src/components/ui/dropdown-menu.tsx +217 -0
  24. package/src/components/ui/form.tsx +138 -0
  25. package/src/components/ui/hover-card.tsx +36 -0
  26. package/src/components/ui/input-otp.tsx +66 -0
  27. package/src/components/ui/input.tsx +21 -0
  28. package/src/components/ui/label.tsx +21 -0
  29. package/src/components/ui/navigation-menu.tsx +142 -0
  30. package/src/components/ui/pagination.tsx +118 -0
  31. package/src/components/ui/popover.tsx +40 -0
  32. package/src/components/ui/progress.tsx +22 -0
  33. package/src/components/ui/radio-group.tsx +31 -0
  34. package/src/components/ui/resizable.tsx +46 -0
  35. package/src/components/ui/scroll-area.tsx +46 -0
  36. package/src/components/ui/select.tsx +158 -0
  37. package/src/components/ui/separator.tsx +26 -0
  38. package/src/components/ui/sheet.tsx +101 -0
  39. package/src/components/ui/skeleton.tsx +7 -0
  40. package/src/components/ui/sonner.tsx +23 -0
  41. package/src/components/ui/switch.tsx +26 -0
  42. package/src/components/ui/table.tsx +73 -0
  43. package/src/components/ui/tabs.tsx +40 -0
  44. package/src/components/ui/textarea.tsx +18 -0
  45. package/src/components/ui/tooltip.tsx +46 -0
  46. package/src/components/uix/action/index.tsx +37 -0
  47. package/src/components/uix/alert/index.tsx +43 -0
  48. package/src/components/uix/alert-dialog/index.tsx +109 -0
  49. package/src/components/uix/avatar/index.tsx +25 -0
  50. package/src/components/uix/breadcrumbs/index.tsx +38 -0
  51. package/src/components/uix/broadcast-channel-context/index.tsx +28 -0
  52. package/src/components/uix/button/index.tsx +29 -0
  53. package/src/components/uix/card/index.tsx +32 -0
  54. package/src/components/uix/checkbox/index.tsx +79 -0
  55. package/src/components/uix/checkbox-group/index.tsx +60 -0
  56. package/src/components/uix/combo-select/index.tsx +364 -0
  57. package/src/components/uix/config-provider/index.tsx +31 -0
  58. package/src/components/uix/data-table/index.tsx +491 -0
  59. package/src/components/uix/data-table/style.css +40 -0
  60. package/src/components/uix/date-picker/index.tsx +88 -0
  61. package/src/components/uix/date-range-picker/index.tsx +71 -0
  62. package/src/components/uix/dialog/index.tsx +70 -0
  63. package/src/components/uix/divider/index.tsx +23 -0
  64. package/src/components/uix/dropdown/index.tsx +117 -0
  65. package/src/components/uix/empty/index.tsx +29 -0
  66. package/src/components/uix/filters/index.tsx +105 -0
  67. package/src/components/uix/form/index.tsx +274 -0
  68. package/src/components/uix/image/index.tsx +13 -0
  69. package/src/components/uix/loading/index.tsx +24 -0
  70. package/src/components/uix/message/index.tsx +21 -0
  71. package/src/components/uix/pagination/index.tsx +180 -0
  72. package/src/components/uix/radio-group/index.tsx +35 -0
  73. package/src/components/uix/result/index.tsx +45 -0
  74. package/src/components/uix/select/index.tsx +93 -0
  75. package/src/components/uix/space/index.tsx +24 -0
  76. package/src/components/uix/spin/index.tsx +12 -0
  77. package/src/components/uix/steps/index.tsx +67 -0
  78. package/src/components/uix/switch/index.tsx +33 -0
  79. package/src/components/uix/tooltip/index.tsx +29 -0
  80. package/src/components/uix/tree/index.tsx +39 -0
  81. package/src/components/uix/tree/style.css +75 -0
  82. package/src/components/uix/tree-select/index.tsx +137 -0
  83. package/src/components/uix/tree-table/action.tsx +24 -0
  84. package/src/components/uix/tree-table/config.ts +2 -0
  85. package/src/components/uix/tree-table/index.tsx +86 -0
  86. package/src/components/uix/tree-table/utils.tsx +63 -0
  87. package/src/components/uix/uploader/index.tsx +237 -0
  88. package/src/components/uix/uploader/type.ts +20 -0
  89. package/src/components/uix/uploader/utils.ts +41 -0
  90. package/src/components/uix/value-formatter/index.tsx +59 -0
  91. package/src/hooks/index.ts +2 -0
  92. package/src/hooks/resize.ts +29 -0
  93. package/src/hooks/use.outside.ts +30 -0
  94. package/src/index.ts +159 -0
  95. package/src/lib/formatters.ts +13 -0
  96. package/src/lib/index.ts +4 -0
  97. package/src/lib/is.ts +6 -0
  98. package/src/lib/react-dom.ts +98 -0
  99. package/src/lib/utils.ts +39 -0
@@ -0,0 +1,138 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import type * as LabelPrimitive from "@radix-ui/react-label";
5
+ import { Slot } from "@radix-ui/react-slot";
6
+ import {
7
+ Controller,
8
+ type ControllerProps,
9
+ type FieldPath,
10
+ type FieldValues,
11
+ FormProvider,
12
+ useFormContext,
13
+ useFormState,
14
+ } from "react-hook-form";
15
+
16
+ import { Label } from "@meta-1/design/components/ui/label";
17
+ import { cn } from "@meta-1/design/lib/utils";
18
+
19
+ const Form = FormProvider;
20
+
21
+ type FormFieldContextValue<
22
+ TFieldValues extends FieldValues = FieldValues,
23
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
24
+ > = {
25
+ name: TName;
26
+ };
27
+
28
+ const FormFieldContext = React.createContext<FormFieldContextValue>({} as FormFieldContextValue);
29
+
30
+ const FormField = <
31
+ TFieldValues extends FieldValues = FieldValues,
32
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
33
+ >({
34
+ ...props
35
+ }: ControllerProps<TFieldValues, TName>) => {
36
+ return (
37
+ <FormFieldContext.Provider value={{ name: props.name }}>
38
+ <Controller {...props} />
39
+ </FormFieldContext.Provider>
40
+ );
41
+ };
42
+
43
+ const useFormField = () => {
44
+ const fieldContext = React.useContext(FormFieldContext);
45
+ const itemContext = React.useContext(FormItemContext);
46
+ const { getFieldState } = useFormContext();
47
+ const formState = useFormState({ name: fieldContext.name });
48
+ const fieldState = getFieldState(fieldContext.name, formState);
49
+
50
+ if (!fieldContext) {
51
+ throw new Error("useFormField should be used within <FormField>");
52
+ }
53
+
54
+ const { id } = itemContext;
55
+
56
+ return {
57
+ id,
58
+ name: fieldContext.name,
59
+ formItemId: `${id}-form-item`,
60
+ formDescriptionId: `${id}-form-item-description`,
61
+ formMessageId: `${id}-form-item-message`,
62
+ ...fieldState,
63
+ };
64
+ };
65
+
66
+ type FormItemContextValue = {
67
+ id: string;
68
+ };
69
+
70
+ const FormItemContext = React.createContext<FormItemContextValue>({} as FormItemContextValue);
71
+
72
+ function FormItem({ className, ...props }: React.ComponentProps<"div">) {
73
+ const id = React.useId();
74
+
75
+ return (
76
+ <FormItemContext.Provider value={{ id }}>
77
+ <div className={cn("grid gap-2", className)} data-slot="form-item" {...props} />
78
+ </FormItemContext.Provider>
79
+ );
80
+ }
81
+
82
+ function FormLabel({ className, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) {
83
+ const { error, formItemId } = useFormField();
84
+
85
+ return (
86
+ <Label
87
+ className={cn("data-[error=true]:text-destructive", className)}
88
+ data-error={!!error}
89
+ data-slot="form-label"
90
+ htmlFor={formItemId}
91
+ {...props}
92
+ />
93
+ );
94
+ }
95
+
96
+ function FormControl({ ...props }: React.ComponentProps<typeof Slot>) {
97
+ const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
98
+
99
+ return (
100
+ <Slot
101
+ aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}
102
+ aria-invalid={!!error}
103
+ data-slot="form-control"
104
+ id={formItemId}
105
+ {...props}
106
+ />
107
+ );
108
+ }
109
+
110
+ function FormDescription({ className, ...props }: React.ComponentProps<"p">) {
111
+ const { formDescriptionId } = useFormField();
112
+
113
+ return (
114
+ <p
115
+ className={cn("text-muted-foreground text-sm", className)}
116
+ data-slot="form-description"
117
+ id={formDescriptionId}
118
+ {...props}
119
+ />
120
+ );
121
+ }
122
+
123
+ function FormMessage({ className, ...props }: React.ComponentProps<"p">) {
124
+ const { error, formMessageId } = useFormField();
125
+ const body = error ? String(error?.message ?? "") : props.children;
126
+
127
+ if (!body) {
128
+ return null;
129
+ }
130
+
131
+ return (
132
+ <p className={cn("text-destructive text-sm", className)} data-slot="form-message" id={formMessageId} {...props}>
133
+ {body}
134
+ </p>
135
+ );
136
+ }
137
+
138
+ export { useFormField, Form, FormItem, FormLabel, FormControl, FormDescription, FormMessage, FormField };
@@ -0,0 +1,36 @@
1
+ import type * as React from "react";
2
+ import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
3
+
4
+ import { cn } from "@meta-1/design/lib/utils";
5
+
6
+ function HoverCard({ ...props }: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
7
+ return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />;
8
+ }
9
+
10
+ function HoverCardTrigger({ ...props }: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
11
+ return <HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />;
12
+ }
13
+
14
+ function HoverCardContent({
15
+ className,
16
+ align = "center",
17
+ sideOffset = 4,
18
+ ...props
19
+ }: React.ComponentProps<typeof HoverCardPrimitive.Content>) {
20
+ return (
21
+ <HoverCardPrimitive.Portal data-slot="hover-card-portal">
22
+ <HoverCardPrimitive.Content
23
+ align={align}
24
+ className={cn(
25
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-hidden data-[state=closed]:animate-out data-[state=open]:animate-in",
26
+ className,
27
+ )}
28
+ data-slot="hover-card-content"
29
+ sideOffset={sideOffset}
30
+ {...props}
31
+ />
32
+ </HoverCardPrimitive.Portal>
33
+ );
34
+ }
35
+
36
+ export { HoverCard, HoverCardTrigger, HoverCardContent };
@@ -0,0 +1,66 @@
1
+ import * as React from "react";
2
+ import { OTPInput, OTPInputContext } from "input-otp";
3
+ import { MinusIcon } from "lucide-react";
4
+
5
+ import { cn } from "@meta-1/design/lib/utils";
6
+
7
+ function InputOTP({
8
+ className,
9
+ containerClassName,
10
+ ...props
11
+ }: React.ComponentProps<typeof OTPInput> & {
12
+ containerClassName?: string;
13
+ }) {
14
+ return (
15
+ <OTPInput
16
+ className={cn("disabled:cursor-not-allowed", className)}
17
+ containerClassName={cn("flex items-center gap-2 has-disabled:opacity-50", containerClassName)}
18
+ data-slot="input-otp"
19
+ {...props}
20
+ />
21
+ );
22
+ }
23
+
24
+ function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">) {
25
+ return <div className={cn("flex items-center", className)} data-slot="input-otp-group" {...props} />;
26
+ }
27
+
28
+ function InputOTPSlot({
29
+ index,
30
+ className,
31
+ ...props
32
+ }: React.ComponentProps<"div"> & {
33
+ index: number;
34
+ }) {
35
+ const inputOTPContext = React.useContext(OTPInputContext);
36
+ const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {};
37
+
38
+ return (
39
+ <div
40
+ className={cn(
41
+ "relative flex h-9 w-9 items-center justify-center border-input border-y border-r text-sm shadow-xs outline-none transition-all first:rounded-l-md first:border-l last:rounded-r-md aria-invalid:border-destructive data-[active=true]:z-10 data-[active=true]:border-ring data-[active=true]:ring-[3px] data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:border-destructive data-[active=true]:aria-invalid:ring-destructive/20 dark:bg-input/30 dark:data-[active=true]:aria-invalid:ring-destructive/40",
42
+ className,
43
+ )}
44
+ data-active={isActive}
45
+ data-slot="input-otp-slot"
46
+ {...props}
47
+ >
48
+ {char}
49
+ {hasFakeCaret && (
50
+ <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
51
+ <div className="h-4 w-px animate-caret-blink bg-foreground duration-1000" />
52
+ </div>
53
+ )}
54
+ </div>
55
+ );
56
+ }
57
+
58
+ function InputOTPSeparator({ ...props }: React.ComponentProps<"div">) {
59
+ return (
60
+ <div data-slot="input-otp-separator" role="separator" {...props}>
61
+ <MinusIcon />
62
+ </div>
63
+ );
64
+ }
65
+
66
+ export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };
@@ -0,0 +1,21 @@
1
+ import type * as React from "react";
2
+
3
+ import { cn } from "@meta-1/design/lib/utils";
4
+
5
+ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6
+ return (
7
+ <input
8
+ className={cn(
9
+ "flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs outline-none transition-[color,box-shadow] selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:font-medium file:text-foreground file:text-sm placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30",
10
+ "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
11
+ "aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",
12
+ className,
13
+ )}
14
+ data-slot="input"
15
+ type={type}
16
+ {...props}
17
+ />
18
+ );
19
+ }
20
+
21
+ export { Input };
@@ -0,0 +1,21 @@
1
+ "use client";
2
+
3
+ import type * as React from "react";
4
+ import * as LabelPrimitive from "@radix-ui/react-label";
5
+
6
+ import { cn } from "@meta-1/design/lib/utils";
7
+
8
+ function Label({ className, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) {
9
+ return (
10
+ <LabelPrimitive.Root
11
+ className={cn(
12
+ "flex select-none items-center gap-2 font-medium text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-50 group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50",
13
+ className,
14
+ )}
15
+ data-slot="label"
16
+ {...props}
17
+ />
18
+ );
19
+ }
20
+
21
+ export { Label };
@@ -0,0 +1,142 @@
1
+ import type * as React from "react";
2
+ import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
3
+ import { cva } from "class-variance-authority";
4
+ import { ChevronDownIcon } from "lucide-react";
5
+
6
+ import { cn } from "@meta-1/design/lib/utils";
7
+
8
+ function NavigationMenu({
9
+ className,
10
+ children,
11
+ viewport = true,
12
+ ...props
13
+ }: React.ComponentProps<typeof NavigationMenuPrimitive.Root> & {
14
+ viewport?: boolean;
15
+ }) {
16
+ return (
17
+ <NavigationMenuPrimitive.Root
18
+ className={cn("group/navigation-menu relative flex max-w-max flex-1 items-center justify-center", className)}
19
+ data-slot="navigation-menu"
20
+ data-viewport={viewport}
21
+ {...props}
22
+ >
23
+ {children}
24
+ {viewport && <NavigationMenuViewport />}
25
+ </NavigationMenuPrimitive.Root>
26
+ );
27
+ }
28
+
29
+ function NavigationMenuList({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.List>) {
30
+ return (
31
+ <NavigationMenuPrimitive.List
32
+ className={cn("group flex flex-1 list-none items-center justify-center gap-1", className)}
33
+ data-slot="navigation-menu-list"
34
+ {...props}
35
+ />
36
+ );
37
+ }
38
+
39
+ function NavigationMenuItem({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Item>) {
40
+ return (
41
+ <NavigationMenuPrimitive.Item className={cn("relative", className)} data-slot="navigation-menu-item" {...props} />
42
+ );
43
+ }
44
+
45
+ const navigationMenuTriggerStyle = cva(
46
+ "group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 font-medium text-sm outline-none transition-[color,box-shadow] hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus-visible:outline-1 focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-[state=open]:bg-accent/50 data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:hover:bg-accent",
47
+ );
48
+
49
+ function NavigationMenuTrigger({
50
+ className,
51
+ children,
52
+ ...props
53
+ }: React.ComponentProps<typeof NavigationMenuPrimitive.Trigger>) {
54
+ return (
55
+ <NavigationMenuPrimitive.Trigger
56
+ className={cn(navigationMenuTriggerStyle(), "group", className)}
57
+ data-slot="navigation-menu-trigger"
58
+ {...props}
59
+ >
60
+ {children}{" "}
61
+ <ChevronDownIcon
62
+ aria-hidden="true"
63
+ className="relative top-[1px] ml-1 size-3 transition duration-300 group-data-[state=open]:rotate-180"
64
+ />
65
+ </NavigationMenuPrimitive.Trigger>
66
+ );
67
+ }
68
+
69
+ function NavigationMenuContent({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Content>) {
70
+ return (
71
+ <NavigationMenuPrimitive.Content
72
+ className={cn(
73
+ "data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 top-0 left-0 w-full p-2 pr-2.5 data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out md:absolute md:w-auto",
74
+ "group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 **:data-[slot=navigation-menu-link]:focus:outline-none **:data-[slot=navigation-menu-link]:focus:ring-0 group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in",
75
+ className,
76
+ )}
77
+ data-slot="navigation-menu-content"
78
+ {...props}
79
+ />
80
+ );
81
+ }
82
+
83
+ function NavigationMenuViewport({
84
+ className,
85
+ ...props
86
+ }: React.ComponentProps<typeof NavigationMenuPrimitive.Viewport>) {
87
+ return (
88
+ <div className={cn("absolute top-full left-0 isolate z-50 flex justify-center")}>
89
+ <NavigationMenuPrimitive.Viewport
90
+ className={cn(
91
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full origin-top-center overflow-hidden rounded-md border bg-popover text-popover-foreground shadow data-[state=closed]:animate-out data-[state=open]:animate-in md:w-[var(--radix-navigation-menu-viewport-width)]",
92
+ className,
93
+ )}
94
+ data-slot="navigation-menu-viewport"
95
+ {...props}
96
+ />
97
+ </div>
98
+ );
99
+ }
100
+
101
+ function NavigationMenuLink({ className, ...props }: React.ComponentProps<typeof NavigationMenuPrimitive.Link>) {
102
+ return (
103
+ <NavigationMenuPrimitive.Link
104
+ className={cn(
105
+ "flex flex-col gap-1 rounded-sm p-2 text-sm outline-none transition-all hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus-visible:outline-1 focus-visible:ring-[3px] focus-visible:ring-ring/50 data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground data-[active=true]:focus:bg-accent data-[active=true]:hover:bg-accent [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",
106
+ className,
107
+ )}
108
+ data-slot="navigation-menu-link"
109
+ {...props}
110
+ />
111
+ );
112
+ }
113
+
114
+ function NavigationMenuIndicator({
115
+ className,
116
+ ...props
117
+ }: React.ComponentProps<typeof NavigationMenuPrimitive.Indicator>) {
118
+ return (
119
+ <NavigationMenuPrimitive.Indicator
120
+ className={cn(
121
+ "data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=hidden]:animate-out data-[state=visible]:animate-in",
122
+ className,
123
+ )}
124
+ data-slot="navigation-menu-indicator"
125
+ {...props}
126
+ >
127
+ <div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
128
+ </NavigationMenuPrimitive.Indicator>
129
+ );
130
+ }
131
+
132
+ export {
133
+ NavigationMenu,
134
+ NavigationMenuList,
135
+ NavigationMenuItem,
136
+ NavigationMenuContent,
137
+ NavigationMenuTrigger,
138
+ NavigationMenuLink,
139
+ NavigationMenuIndicator,
140
+ NavigationMenuViewport,
141
+ navigationMenuTriggerStyle,
142
+ };
@@ -0,0 +1,118 @@
1
+ import * as React from "react"
2
+ import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"
3
+
4
+ import { cn } from "@meta-1/design/lib/utils"
5
+ import { ButtonProps } from "@meta-1/design/components/uix/button"
6
+ import { buttonVariants } from "@meta-1/design/components/ui/button"
7
+
8
+ const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
9
+ <nav
10
+ role="navigation"
11
+ aria-label="pagination"
12
+ className={cn("mx-auto flex w-full justify-center", className)}
13
+ {...props}
14
+ />
15
+ )
16
+ Pagination.displayName = "Pagination"
17
+
18
+ const PaginationContent = React.forwardRef<
19
+ HTMLUListElement,
20
+ React.ComponentProps<"ul">
21
+ >(({ className, ...props }, ref) => (
22
+ <ul
23
+ ref={ref}
24
+ className={cn("flex flex-row items-center gap-1", className)}
25
+ {...props}
26
+ />
27
+ ))
28
+ PaginationContent.displayName = "PaginationContent"
29
+
30
+ const PaginationItem = React.forwardRef<
31
+ HTMLLIElement,
32
+ React.ComponentProps<"li">
33
+ >(({ className, ...props }, ref) => (
34
+ <li ref={ref} className={cn("", className)} {...props} />
35
+ ))
36
+ PaginationItem.displayName = "PaginationItem"
37
+
38
+ type PaginationLinkProps = {
39
+ isActive?: boolean
40
+ } & Pick<ButtonProps, "size"> &
41
+ React.ComponentProps<"a">
42
+
43
+ const PaginationLink = ({
44
+ className,
45
+ isActive,
46
+ size = "icon",
47
+ ...props
48
+ }: PaginationLinkProps) => (
49
+ <a
50
+ aria-current={isActive ? "page" : undefined}
51
+ className={cn(
52
+ buttonVariants({
53
+ variant: isActive ? "outline" : "ghost",
54
+ size,
55
+ }),
56
+ className
57
+ )}
58
+ {...props}
59
+ />
60
+ )
61
+ PaginationLink.displayName = "PaginationLink"
62
+
63
+ const PaginationPrevious = ({
64
+ className,
65
+ ...props
66
+ }: React.ComponentProps<typeof PaginationLink>) => (
67
+ <PaginationLink
68
+ aria-label="Go to previous page"
69
+ size="default"
70
+ className={cn("gap-1 pl-2.5", className)}
71
+ {...props}
72
+ >
73
+ <ChevronLeft className="h-4 w-4" />
74
+ <span>Previous</span>
75
+ </PaginationLink>
76
+ )
77
+ PaginationPrevious.displayName = "PaginationPrevious"
78
+
79
+ const PaginationNext = ({
80
+ className,
81
+ ...props
82
+ }: React.ComponentProps<typeof PaginationLink>) => (
83
+ <PaginationLink
84
+ aria-label="Go to next page"
85
+ size="default"
86
+ className={cn("gap-1 pr-2.5", className)}
87
+ {...props}
88
+ >
89
+ <span>Next</span>
90
+ <ChevronRight className="h-4 w-4" />
91
+ </PaginationLink>
92
+ )
93
+ PaginationNext.displayName = "PaginationNext"
94
+
95
+ const PaginationEllipsis = ({
96
+ className,
97
+ ...props
98
+ }: React.ComponentProps<"span">) => (
99
+ <span
100
+ aria-hidden
101
+ className={cn("flex h-9 w-9 items-center justify-center", className)}
102
+ {...props}
103
+ >
104
+ <MoreHorizontal className="h-4 w-4" />
105
+ <span className="sr-only">More pages</span>
106
+ </span>
107
+ )
108
+ PaginationEllipsis.displayName = "PaginationEllipsis"
109
+
110
+ export {
111
+ Pagination,
112
+ PaginationContent,
113
+ PaginationEllipsis,
114
+ PaginationItem,
115
+ PaginationLink,
116
+ PaginationNext,
117
+ PaginationPrevious,
118
+ }
@@ -0,0 +1,40 @@
1
+ import type * as React from "react";
2
+ import * as PopoverPrimitive from "@radix-ui/react-popover";
3
+
4
+ import { cn } from "@meta-1/design/lib/utils";
5
+
6
+ function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>) {
7
+ return <PopoverPrimitive.Root data-slot="popover" {...props} />;
8
+ }
9
+
10
+ function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
11
+ return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />;
12
+ }
13
+
14
+ function PopoverContent({
15
+ className,
16
+ align = "center",
17
+ sideOffset = 4,
18
+ ...props
19
+ }: React.ComponentProps<typeof PopoverPrimitive.Content>) {
20
+ return (
21
+ <PopoverPrimitive.Portal>
22
+ <PopoverPrimitive.Content
23
+ align={align}
24
+ className={cn(
25
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-hidden data-[state=closed]:animate-out data-[state=open]:animate-in",
26
+ className,
27
+ )}
28
+ data-slot="popover-content"
29
+ sideOffset={sideOffset}
30
+ {...props}
31
+ />
32
+ </PopoverPrimitive.Portal>
33
+ );
34
+ }
35
+
36
+ function PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {
37
+ return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />;
38
+ }
39
+
40
+ export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
@@ -0,0 +1,22 @@
1
+ import type * as React from "react";
2
+ import * as ProgressPrimitive from "@radix-ui/react-progress";
3
+
4
+ import { cn } from "@meta-1/design/lib/utils";
5
+
6
+ function Progress({ className, value, ...props }: React.ComponentProps<typeof ProgressPrimitive.Root>) {
7
+ return (
8
+ <ProgressPrimitive.Root
9
+ className={cn("relative h-2 w-full overflow-hidden rounded-full bg-primary/20", className)}
10
+ data-slot="progress"
11
+ {...props}
12
+ >
13
+ <ProgressPrimitive.Indicator
14
+ className="h-full w-full flex-1 bg-primary transition-all"
15
+ data-slot="progress-indicator"
16
+ style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
17
+ />
18
+ </ProgressPrimitive.Root>
19
+ );
20
+ }
21
+
22
+ export { Progress };
@@ -0,0 +1,31 @@
1
+ import type * as React from "react";
2
+ import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
3
+ import { CircleIcon } from "lucide-react";
4
+
5
+ import { cn } from "@meta-1/design/lib/utils";
6
+
7
+ function RadioGroup({ className, ...props }: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {
8
+ return <RadioGroupPrimitive.Root className={cn("grid gap-3", className)} data-slot="radio-group" {...props} />;
9
+ }
10
+
11
+ function RadioGroupItem({ className, ...props }: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {
12
+ return (
13
+ <RadioGroupPrimitive.Item
14
+ className={cn(
15
+ "aspect-square size-4 shrink-0 rounded-full border border-input text-primary shadow-xs outline-none transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:bg-input/30 dark:aria-invalid:ring-destructive/40",
16
+ className,
17
+ )}
18
+ data-slot="radio-group-item"
19
+ {...props}
20
+ >
21
+ <RadioGroupPrimitive.Indicator
22
+ className="relative flex items-center justify-center"
23
+ data-slot="radio-group-indicator"
24
+ >
25
+ <CircleIcon className="-translate-x-1/2 -translate-y-1/2 absolute top-1/2 left-1/2 size-2 fill-primary" />
26
+ </RadioGroupPrimitive.Indicator>
27
+ </RadioGroupPrimitive.Item>
28
+ );
29
+ }
30
+
31
+ export { RadioGroup, RadioGroupItem };