@codemation/next-host 0.0.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 +25 -0
- package/app/(shell)/credentials/page.tsx +5 -0
- package/app/(shell)/dashboard/page.tsx +14 -0
- package/app/(shell)/layout.tsx +11 -0
- package/app/(shell)/page.tsx +5 -0
- package/app/(shell)/users/page.tsx +5 -0
- package/app/(shell)/workflows/[workflowId]/page.tsx +19 -0
- package/app/(shell)/workflows/page.tsx +5 -0
- package/app/api/[[...path]]/route.ts +40 -0
- package/app/api/auth/[...nextauth]/route.ts +3 -0
- package/app/globals.css +997 -0
- package/app/invite/[token]/page.tsx +10 -0
- package/app/layout.tsx +65 -0
- package/app/login/layout.tsx +25 -0
- package/app/login/page.tsx +22 -0
- package/components.json +21 -0
- package/docs/FORMS.md +46 -0
- package/docs/TAILWIND_SHADCN_MIGRATION.md +89 -0
- package/eslint.config.mjs +56 -0
- package/middleware.ts +29 -0
- package/next-env.d.ts +6 -0
- package/next.config.ts +34 -0
- package/package.json +76 -0
- package/postcss.config.mjs +7 -0
- package/public/canvas-icons/builtin/openai.svg +5 -0
- package/src/api/CodemationApiClient.ts +107 -0
- package/src/api/CodemationApiHttpError.ts +17 -0
- package/src/auth/CodemationNextAuthConfigResolver.ts +14 -0
- package/src/auth/CodemationNextAuthOAuthProviderDescriptorMapper.ts +30 -0
- package/src/auth/CodemationNextAuthOAuthProviderSnapshotResolver.ts +17 -0
- package/src/auth/CodemationNextAuthProviderCatalog.ts +107 -0
- package/src/auth/codemationEdgeAuth.ts +25 -0
- package/src/auth/codemationNextAuth.ts +32 -0
- package/src/components/Codemation.tsx +6 -0
- package/src/components/CodemationDataTable.tsx +37 -0
- package/src/components/CodemationDialog.tsx +137 -0
- package/src/components/CodemationFormattedDateTime.tsx +46 -0
- package/src/components/GoogleColorGIcon.tsx +39 -0
- package/src/components/OauthProviderIcon.tsx +33 -0
- package/src/components/PasswordStrengthMeter.tsx +59 -0
- package/src/components/forms/index.ts +28 -0
- package/src/components/json/JsonMonacoEditor.tsx +75 -0
- package/src/components/oauthProviderIconData.ts +17 -0
- package/src/components/ui/alert.tsx +56 -0
- package/src/components/ui/badge.tsx +40 -0
- package/src/components/ui/button.tsx +64 -0
- package/src/components/ui/card.tsx +70 -0
- package/src/components/ui/collapsible.tsx +26 -0
- package/src/components/ui/dialog.tsx +137 -0
- package/src/components/ui/dropdown-menu.tsx +238 -0
- package/src/components/ui/form.tsx +147 -0
- package/src/components/ui/input.tsx +19 -0
- package/src/components/ui/label.tsx +26 -0
- package/src/components/ui/scroll-area.tsx +47 -0
- package/src/components/ui/select.tsx +169 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/switch.tsx +28 -0
- package/src/components/ui/table.tsx +72 -0
- package/src/components/ui/tabs.tsx +76 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/components/ui/toggle.tsx +41 -0
- package/src/features/credentials/components/CredentialConfirmDialog.tsx +58 -0
- package/src/features/credentials/components/CredentialDialog.tsx +252 -0
- package/src/features/credentials/components/CredentialDialogFeedback.tsx +36 -0
- package/src/features/credentials/components/CredentialDialogFieldRows.tsx +257 -0
- package/src/features/credentials/components/CredentialDialogFormSections.tsx +230 -0
- package/src/features/credentials/components/CredentialEnvFieldStatusRow.tsx +64 -0
- package/src/features/credentials/components/CredentialFieldCopyButton.tsx +48 -0
- package/src/features/credentials/components/CredentialsScreenHealthBadge.tsx +21 -0
- package/src/features/credentials/components/CredentialsScreenInstancesTable.tsx +108 -0
- package/src/features/credentials/components/CredentialsScreenTestFailureAlert.tsx +33 -0
- package/src/features/credentials/hooks/useCredentialCreateDialog.ts +33 -0
- package/src/features/credentials/hooks/useCredentialDialogSession.ts +616 -0
- package/src/features/credentials/hooks/useCredentialsScreen.ts +213 -0
- package/src/features/credentials/lib/credentialFieldHelpers.ts +35 -0
- package/src/features/credentials/lib/credentialFormTypes.ts +1 -0
- package/src/features/credentials/lib/credentialInstanceTestPayloadParser.ts +10 -0
- package/src/features/credentials/screens/CredentialsScreen.tsx +187 -0
- package/src/features/invite/screens/InviteAcceptScreen.tsx +190 -0
- package/src/features/users/components/UsersInviteDialog.tsx +121 -0
- package/src/features/users/components/UsersRegenerateDialog.tsx +81 -0
- package/src/features/users/components/UsersScreenUserStatusBadge.tsx +19 -0
- package/src/features/users/schemas/usersInviteFormSchema.ts +7 -0
- package/src/features/users/screens/UsersScreen.tsx +240 -0
- package/src/features/workflows/components/WorkflowListFolderSection.tsx +91 -0
- package/src/features/workflows/components/WorkflowListItemCard.tsx +67 -0
- package/src/features/workflows/components/WorkflowListRoot.tsx +39 -0
- package/src/features/workflows/components/WorkflowsListTree.tsx +28 -0
- package/src/features/workflows/components/canvas/CanvasNodeChromeTooltip.tsx +96 -0
- package/src/features/workflows/components/canvas/CanvasNodeIconSlot.tsx +25 -0
- package/src/features/workflows/components/canvas/VisibleNodeStatusResolver.tsx +84 -0
- package/src/features/workflows/components/canvas/WorkflowCanvas.tsx +248 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNode.tsx +182 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeAccents.tsx +73 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeAgentBottomSourceHandles.tsx +43 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeAgentLabels.tsx +47 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeCard.tsx +202 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeHandles.tsx +77 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeLabelBelow.tsx +51 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeMainGlyph.tsx +64 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasCodemationNodeToolbar.tsx +95 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasLoadingPlaceholder.tsx +69 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasNodeIcon.tsx +102 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasSimpleIconGlyph.tsx +21 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasStraightCountEdge.tsx +33 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasStructureSignature.tsx +7 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasSymmetricForkEdge.tsx +32 -0
- package/src/features/workflows/components/canvas/WorkflowCanvasToolbarIconButton.tsx +95 -0
- package/src/features/workflows/components/canvas/lib/WorkflowCanvasBuiltinIconRegistry.ts +26 -0
- package/src/features/workflows/components/canvas/lib/WorkflowCanvasEdgeCountResolver.ts +51 -0
- package/src/features/workflows/components/canvas/lib/WorkflowCanvasEdgeStyleResolver.ts +35 -0
- package/src/features/workflows/components/canvas/lib/WorkflowCanvasLabelLayoutEstimator.ts +42 -0
- package/src/features/workflows/components/canvas/lib/WorkflowCanvasOverlapResolver.ts +78 -0
- package/src/features/workflows/components/canvas/lib/WorkflowCanvasPortOrderResolver.ts +25 -0
- package/src/features/workflows/components/canvas/lib/WorkflowCanvasRoundedOrthogonalPathPlanner.ts +56 -0
- package/src/features/workflows/components/canvas/lib/WorkflowCanvasSiIconRegistry.ts +18 -0
- package/src/features/workflows/components/canvas/lib/WorkflowCanvasSymmetricForkPathPlanner.ts +43 -0
- package/src/features/workflows/components/canvas/lib/layoutWorkflow.ts +315 -0
- package/src/features/workflows/components/canvas/lib/workflowCanvasEdgeGeometry.ts +3 -0
- package/src/features/workflows/components/canvas/lib/workflowCanvasEmbeddedStyles.ts +62 -0
- package/src/features/workflows/components/canvas/lib/workflowCanvasFlowTypes.ts +10 -0
- package/src/features/workflows/components/canvas/lib/workflowCanvasNodeData.ts +41 -0
- package/src/features/workflows/components/canvas/lib/workflowCanvasNodeGeometry.ts +99 -0
- package/src/features/workflows/components/canvas/workflowCanvasNodeChrome.tsx +46 -0
- package/src/features/workflows/components/realtime/RealtimeContext.tsx +14 -0
- package/src/features/workflows/components/realtime/WorkflowRealtimeProvider.tsx +15 -0
- package/src/features/workflows/components/workflowDetail/NodeCredentialBindingRow.tsx +209 -0
- package/src/features/workflows/components/workflowDetail/NodeCredentialBindingsSection.tsx +227 -0
- package/src/features/workflows/components/workflowDetail/NodePropertiesConfigSection.tsx +51 -0
- package/src/features/workflows/components/workflowDetail/NodePropertiesPanelHeader.tsx +50 -0
- package/src/features/workflows/components/workflowDetail/NodePropertiesSlidePanel.tsx +134 -0
- package/src/features/workflows/components/workflowDetail/WorkflowActivationErrorDialog.tsx +71 -0
- package/src/features/workflows/components/workflowDetail/WorkflowActivationHeaderControl.tsx +64 -0
- package/src/features/workflows/components/workflowDetail/WorkflowDetailIcons.tsx +52 -0
- package/src/features/workflows/components/workflowDetail/WorkflowExecutionInspector.tsx +110 -0
- package/src/features/workflows/components/workflowDetail/WorkflowExecutionInspectorDetailBody.tsx +213 -0
- package/src/features/workflows/components/workflowDetail/WorkflowExecutionInspectorPanes.tsx +239 -0
- package/src/features/workflows/components/workflowDetail/WorkflowExecutionInspectorSidebarResizer.tsx +31 -0
- package/src/features/workflows/components/workflowDetail/WorkflowExecutionInspectorTreePanel.tsx +133 -0
- package/src/features/workflows/components/workflowDetail/WorkflowInspectorAttachmentGroupingPresenter.tsx +31 -0
- package/src/features/workflows/components/workflowDetail/WorkflowInspectorAttachmentList.tsx +118 -0
- package/src/features/workflows/components/workflowDetail/WorkflowInspectorBinaryView.tsx +15 -0
- package/src/features/workflows/components/workflowDetail/WorkflowInspectorErrorView.tsx +107 -0
- package/src/features/workflows/components/workflowDetail/WorkflowInspectorJsonView.tsx +114 -0
- package/src/features/workflows/components/workflowDetail/WorkflowInspectorPrettyTreePresenter.tsx +132 -0
- package/src/features/workflows/components/workflowDetail/WorkflowInspectorPrettyTreeViewRenderer.tsx +147 -0
- package/src/features/workflows/components/workflowDetail/WorkflowInspectorPrettyView.tsx +65 -0
- package/src/features/workflows/components/workflowDetail/WorkflowInspectorViews.tsx +5 -0
- package/src/features/workflows/components/workflowDetail/WorkflowJsonEditorBinaryAttachmentRow.tsx +74 -0
- package/src/features/workflows/components/workflowDetail/WorkflowJsonEditorBinaryUploadRow.tsx +69 -0
- package/src/features/workflows/components/workflowDetail/WorkflowJsonEditorDialog.tsx +254 -0
- package/src/features/workflows/components/workflowDetail/WorkflowRunsList.tsx +89 -0
- package/src/features/workflows/components/workflowDetail/WorkflowRunsSidebar.tsx +50 -0
- package/src/features/workflows/hooks/canvas/useWorkflowCanvasVisibleNodeStatuses.ts +14 -0
- package/src/features/workflows/hooks/realtime/realtime.tsx +271 -0
- package/src/features/workflows/hooks/realtime/runQueryPolling.ts +34 -0
- package/src/features/workflows/hooks/realtime/useWorkflowRealtimeInfrastructure.ts +541 -0
- package/src/features/workflows/hooks/realtime/useWorkflowRealtimeShowDisconnectedBadge.ts +9 -0
- package/src/features/workflows/hooks/workflowDetail/useWorkflowDetailController.tsx +1300 -0
- package/src/features/workflows/lib/realtime/realtimeApi.ts +78 -0
- package/src/features/workflows/lib/realtime/realtimeClientBridge.ts +52 -0
- package/src/features/workflows/lib/realtime/realtimeDomainTypes.ts +191 -0
- package/src/features/workflows/lib/realtime/realtimeQueryKeys.ts +15 -0
- package/src/features/workflows/lib/realtime/realtimeRunMutations.ts +167 -0
- package/src/features/workflows/lib/realtime/workflowTypes.ts +5 -0
- package/src/features/workflows/lib/workflowDetail/PersistedWorkflowSnapshotMapper.ts +205 -0
- package/src/features/workflows/lib/workflowDetail/WorkflowActivationHttpErrorFormat.ts +32 -0
- package/src/features/workflows/lib/workflowDetail/WorkflowDetailPresenter.ts +1017 -0
- package/src/features/workflows/lib/workflowDetail/WorkflowDetailUrlCodec.ts +70 -0
- package/src/features/workflows/lib/workflowDetail/workflowDetailTypes.ts +152 -0
- package/src/features/workflows/lib/workflowDetailTreeStyles.ts +65 -0
- package/src/features/workflows/screens/WorkflowDetailScreen.tsx +236 -0
- package/src/features/workflows/screens/WorkflowDetailScreenInspectorPanel.tsx +55 -0
- package/src/features/workflows/screens/WorkflowsList.tsx +35 -0
- package/src/features/workflows/screens/WorkflowsScreen.tsx +31 -0
- package/src/index.ts +1 -0
- package/src/lib/utils.ts +6 -0
- package/src/middleware/CodemationNextHostMiddlewarePathRules.ts +31 -0
- package/src/providers/CodemationSessionProvider.tsx +23 -0
- package/src/providers/Providers.tsx +36 -0
- package/src/providers/RealtimeBoundary.tsx +17 -0
- package/src/providers/WhitelabelProvider.tsx +22 -0
- package/src/server/CodemationAuthPrismaClient.ts +21 -0
- package/src/server/CodemationNextHost.ts +379 -0
- package/src/shell/AppLayout.tsx +141 -0
- package/src/shell/AppLayoutNavItems.tsx +129 -0
- package/src/shell/AppLayoutPageHeader.tsx +79 -0
- package/src/shell/AppLayoutSidebarBrand.tsx +33 -0
- package/src/shell/AppMainContent.tsx +17 -0
- package/src/shell/AppShellHeaderActions.tsx +12 -0
- package/src/shell/AppShellHeaderActionsAuthenticated.tsx +51 -0
- package/src/shell/CodemationNextClientShell.tsx +17 -0
- package/src/shell/CredentialsSignInRedirectResolver.ts +21 -0
- package/src/shell/LoginPageClient.tsx +231 -0
- package/src/shell/WorkflowDetailChromeContext.tsx +42 -0
- package/src/shell/WorkflowFolderTreeBuilder.ts +62 -0
- package/src/shell/WorkflowFolderUi.ts +42 -0
- package/src/shell/WorkflowSidebarNavFolder.tsx +112 -0
- package/src/shell/WorkflowSidebarNavTree.tsx +68 -0
- package/src/shell/appLayoutPageTitle.ts +16 -0
- package/src/shell/appLayoutSidebarIcons.tsx +108 -0
- package/src/whitelabel/CodemationWhitelabelSnapshot.ts +4 -0
- package/src/whitelabel/CodemationWhitelabelSnapshotFactory.ts +18 -0
- package/tsconfig.json +40 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +34 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import {
|
|
5
|
+
Controller,
|
|
6
|
+
type ControllerProps,
|
|
7
|
+
type FieldPath,
|
|
8
|
+
type FieldValues,
|
|
9
|
+
FormProvider,
|
|
10
|
+
useFormContext,
|
|
11
|
+
} from "react-hook-form";
|
|
12
|
+
import { Slot } from "radix-ui";
|
|
13
|
+
|
|
14
|
+
import { Label } from "@/components/ui/label";
|
|
15
|
+
import { cn } from "@/lib/utils";
|
|
16
|
+
|
|
17
|
+
const Form = FormProvider;
|
|
18
|
+
|
|
19
|
+
type FormFieldContextValue<
|
|
20
|
+
TFieldValues extends FieldValues = FieldValues,
|
|
21
|
+
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
|
|
22
|
+
> = {
|
|
23
|
+
name: TName;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const FormFieldContext = React.createContext<FormFieldContextValue | null>(null);
|
|
27
|
+
|
|
28
|
+
const FormField = <
|
|
29
|
+
TFieldValues extends FieldValues = FieldValues,
|
|
30
|
+
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
|
|
31
|
+
>({
|
|
32
|
+
...props
|
|
33
|
+
}: ControllerProps<TFieldValues, TName>) => {
|
|
34
|
+
return (
|
|
35
|
+
<FormFieldContext.Provider value={{ name: props.name }}>
|
|
36
|
+
<Controller {...props} />
|
|
37
|
+
</FormFieldContext.Provider>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
type FormItemContextValue = {
|
|
42
|
+
id: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const FormItemContext = React.createContext<FormItemContextValue | null>(null);
|
|
46
|
+
|
|
47
|
+
const useFormField = () => {
|
|
48
|
+
const fieldContext = React.useContext(FormFieldContext);
|
|
49
|
+
const itemContext = React.useContext(FormItemContext);
|
|
50
|
+
const { getFieldState, formState } = useFormContext();
|
|
51
|
+
|
|
52
|
+
if (!fieldContext) {
|
|
53
|
+
throw new Error("useFormField must be used within <FormField>");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!itemContext) {
|
|
57
|
+
throw new Error("useFormField must be used within <FormItem>");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const fieldState = getFieldState(fieldContext.name, formState);
|
|
61
|
+
const { id } = itemContext;
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
id,
|
|
65
|
+
name: fieldContext.name,
|
|
66
|
+
formItemId: `${id}-form-item`,
|
|
67
|
+
formDescriptionId: `${id}-form-item-description`,
|
|
68
|
+
formMessageId: `${id}-form-item-message`,
|
|
69
|
+
...fieldState,
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
74
|
+
({ className, ...props }, ref) => {
|
|
75
|
+
const id = React.useId();
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<FormItemContext.Provider value={{ id }}>
|
|
79
|
+
<div ref={ref} className={cn("space-y-2", className)} {...props} />
|
|
80
|
+
</FormItemContext.Provider>
|
|
81
|
+
);
|
|
82
|
+
},
|
|
83
|
+
);
|
|
84
|
+
FormItem.displayName = "FormItem";
|
|
85
|
+
|
|
86
|
+
const FormLabel = React.forwardRef<React.ComponentRef<typeof Label>, React.ComponentPropsWithoutRef<typeof Label>>(
|
|
87
|
+
({ className, ...props }, ref) => {
|
|
88
|
+
const { error, formItemId } = useFormField();
|
|
89
|
+
|
|
90
|
+
return <Label ref={ref} className={cn(error && "text-destructive", className)} htmlFor={formItemId} {...props} />;
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
FormLabel.displayName = "FormLabel";
|
|
94
|
+
|
|
95
|
+
const FormControl = React.forwardRef<
|
|
96
|
+
React.ComponentRef<typeof Slot.Root>,
|
|
97
|
+
React.ComponentPropsWithoutRef<typeof Slot.Root>
|
|
98
|
+
>(({ ...props }, ref) => {
|
|
99
|
+
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<Slot.Root
|
|
103
|
+
ref={ref}
|
|
104
|
+
id={formItemId}
|
|
105
|
+
aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}
|
|
106
|
+
aria-invalid={!!error}
|
|
107
|
+
{...props}
|
|
108
|
+
/>
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
FormControl.displayName = "FormControl";
|
|
112
|
+
|
|
113
|
+
const FormDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
|
|
114
|
+
({ className, ...props }, ref) => {
|
|
115
|
+
const { formDescriptionId } = useFormField();
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<p ref={ref} id={formDescriptionId} className={cn("text-[0.8rem] text-muted-foreground", className)} {...props} />
|
|
119
|
+
);
|
|
120
|
+
},
|
|
121
|
+
);
|
|
122
|
+
FormDescription.displayName = "FormDescription";
|
|
123
|
+
|
|
124
|
+
const FormMessage = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
|
|
125
|
+
({ className, children, ...props }, ref) => {
|
|
126
|
+
const { error, formMessageId } = useFormField();
|
|
127
|
+
const body = error ? String(error.message) : children;
|
|
128
|
+
|
|
129
|
+
if (!body) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<p
|
|
135
|
+
ref={ref}
|
|
136
|
+
id={formMessageId}
|
|
137
|
+
className={cn("text-[0.8rem] font-medium text-destructive", className)}
|
|
138
|
+
{...props}
|
|
139
|
+
>
|
|
140
|
+
{body}
|
|
141
|
+
</p>
|
|
142
|
+
);
|
|
143
|
+
},
|
|
144
|
+
);
|
|
145
|
+
FormMessage.displayName = "FormMessage";
|
|
146
|
+
|
|
147
|
+
export { useFormField, Form, FormItem, FormLabel, FormControl, FormDescription, FormMessage, FormField };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
|
|
5
|
+
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
|
6
|
+
return (
|
|
7
|
+
<input
|
|
8
|
+
type={type}
|
|
9
|
+
data-slot="input"
|
|
10
|
+
className={cn(
|
|
11
|
+
"h-8 w-full min-w-0 rounded-md border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
|
12
|
+
className,
|
|
13
|
+
)}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { Input };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Label as LabelPrimitive } from "radix-ui";
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
|
|
8
|
+
const Label = React.forwardRef<
|
|
9
|
+
React.ComponentRef<typeof LabelPrimitive.Root>,
|
|
10
|
+
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
|
|
11
|
+
>(({ className, ...props }, ref) => {
|
|
12
|
+
return (
|
|
13
|
+
<LabelPrimitive.Root
|
|
14
|
+
ref={ref}
|
|
15
|
+
data-slot="label"
|
|
16
|
+
className={cn(
|
|
17
|
+
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
18
|
+
className,
|
|
19
|
+
)}
|
|
20
|
+
{...props}
|
|
21
|
+
/>
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
Label.displayName = "Label";
|
|
25
|
+
|
|
26
|
+
export { Label };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { ScrollArea as ScrollAreaPrimitive } from "radix-ui";
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
|
|
8
|
+
function ScrollArea({ className, children, ...props }: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
|
9
|
+
return (
|
|
10
|
+
<ScrollAreaPrimitive.Root data-slot="scroll-area" className={cn("relative", className)} {...props}>
|
|
11
|
+
<ScrollAreaPrimitive.Viewport
|
|
12
|
+
data-slot="scroll-area-viewport"
|
|
13
|
+
className="size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1"
|
|
14
|
+
>
|
|
15
|
+
{children}
|
|
16
|
+
</ScrollAreaPrimitive.Viewport>
|
|
17
|
+
<ScrollBar />
|
|
18
|
+
<ScrollAreaPrimitive.Corner />
|
|
19
|
+
</ScrollAreaPrimitive.Root>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function ScrollBar({
|
|
24
|
+
className,
|
|
25
|
+
orientation = "vertical",
|
|
26
|
+
...props
|
|
27
|
+
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
|
|
28
|
+
return (
|
|
29
|
+
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
|
30
|
+
data-slot="scroll-area-scrollbar"
|
|
31
|
+
data-orientation={orientation}
|
|
32
|
+
orientation={orientation}
|
|
33
|
+
className={cn(
|
|
34
|
+
"flex touch-none p-px transition-colors select-none data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-l data-vertical:border-l-transparent",
|
|
35
|
+
className,
|
|
36
|
+
)}
|
|
37
|
+
{...props}
|
|
38
|
+
>
|
|
39
|
+
<ScrollAreaPrimitive.ScrollAreaThumb
|
|
40
|
+
data-slot="scroll-area-thumb"
|
|
41
|
+
className="relative flex-1 rounded-full bg-border"
|
|
42
|
+
/>
|
|
43
|
+
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { ScrollArea, ScrollBar };
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Select as SelectPrimitive } from "radix-ui";
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react";
|
|
8
|
+
|
|
9
|
+
function Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {
|
|
10
|
+
return <SelectPrimitive.Root data-slot="select" {...props} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function SelectGroup({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {
|
|
14
|
+
return <SelectPrimitive.Group data-slot="select-group" className={cn("scroll-my-1 p-1", className)} {...props} />;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {
|
|
18
|
+
return <SelectPrimitive.Value data-slot="select-value" {...props} />;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function SelectTrigger({
|
|
22
|
+
className,
|
|
23
|
+
size = "default",
|
|
24
|
+
children,
|
|
25
|
+
...props
|
|
26
|
+
}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
|
|
27
|
+
size?: "sm" | "default";
|
|
28
|
+
}) {
|
|
29
|
+
return (
|
|
30
|
+
<SelectPrimitive.Trigger
|
|
31
|
+
data-slot="select-trigger"
|
|
32
|
+
data-size={size}
|
|
33
|
+
className={cn(
|
|
34
|
+
"flex w-fit items-center justify-between gap-1.5 rounded-md border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap shadow-sm transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-sm *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
35
|
+
className,
|
|
36
|
+
)}
|
|
37
|
+
{...props}
|
|
38
|
+
>
|
|
39
|
+
{children}
|
|
40
|
+
<SelectPrimitive.Icon asChild>
|
|
41
|
+
<ChevronDownIcon className="pointer-events-none size-4 text-muted-foreground" />
|
|
42
|
+
</SelectPrimitive.Icon>
|
|
43
|
+
</SelectPrimitive.Trigger>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function SelectContent({
|
|
48
|
+
className,
|
|
49
|
+
children,
|
|
50
|
+
position = "item-aligned",
|
|
51
|
+
align = "center",
|
|
52
|
+
...props
|
|
53
|
+
}: React.ComponentProps<typeof SelectPrimitive.Content>) {
|
|
54
|
+
return (
|
|
55
|
+
<SelectPrimitive.Portal>
|
|
56
|
+
<SelectPrimitive.Content
|
|
57
|
+
data-slot="select-content"
|
|
58
|
+
data-align-trigger={position === "item-aligned"}
|
|
59
|
+
className={cn(
|
|
60
|
+
"relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none 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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
61
|
+
position === "popper" &&
|
|
62
|
+
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
63
|
+
className,
|
|
64
|
+
)}
|
|
65
|
+
position={position}
|
|
66
|
+
align={align}
|
|
67
|
+
{...props}
|
|
68
|
+
>
|
|
69
|
+
<SelectScrollUpButton />
|
|
70
|
+
<SelectPrimitive.Viewport
|
|
71
|
+
data-position={position}
|
|
72
|
+
className={cn(
|
|
73
|
+
"data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)",
|
|
74
|
+
position === "popper" && "",
|
|
75
|
+
)}
|
|
76
|
+
>
|
|
77
|
+
{children}
|
|
78
|
+
</SelectPrimitive.Viewport>
|
|
79
|
+
<SelectScrollDownButton />
|
|
80
|
+
</SelectPrimitive.Content>
|
|
81
|
+
</SelectPrimitive.Portal>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {
|
|
86
|
+
return (
|
|
87
|
+
<SelectPrimitive.Label
|
|
88
|
+
data-slot="select-label"
|
|
89
|
+
className={cn("px-1.5 py-1 text-xs text-muted-foreground", className)}
|
|
90
|
+
{...props}
|
|
91
|
+
/>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function SelectItem({ className, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Item>) {
|
|
96
|
+
return (
|
|
97
|
+
<SelectPrimitive.Item
|
|
98
|
+
data-slot="select-item"
|
|
99
|
+
className={cn(
|
|
100
|
+
"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
101
|
+
className,
|
|
102
|
+
)}
|
|
103
|
+
{...props}
|
|
104
|
+
>
|
|
105
|
+
<span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center">
|
|
106
|
+
<SelectPrimitive.ItemIndicator>
|
|
107
|
+
<CheckIcon className="pointer-events-none" />
|
|
108
|
+
</SelectPrimitive.ItemIndicator>
|
|
109
|
+
</span>
|
|
110
|
+
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
|
111
|
+
</SelectPrimitive.Item>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function SelectSeparator({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Separator>) {
|
|
116
|
+
return (
|
|
117
|
+
<SelectPrimitive.Separator
|
|
118
|
+
data-slot="select-separator"
|
|
119
|
+
className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
|
|
120
|
+
{...props}
|
|
121
|
+
/>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function SelectScrollUpButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
|
|
126
|
+
return (
|
|
127
|
+
<SelectPrimitive.ScrollUpButton
|
|
128
|
+
data-slot="select-scroll-up-button"
|
|
129
|
+
className={cn(
|
|
130
|
+
"z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
131
|
+
className,
|
|
132
|
+
)}
|
|
133
|
+
{...props}
|
|
134
|
+
>
|
|
135
|
+
<ChevronUpIcon />
|
|
136
|
+
</SelectPrimitive.ScrollUpButton>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function SelectScrollDownButton({
|
|
141
|
+
className,
|
|
142
|
+
...props
|
|
143
|
+
}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
|
|
144
|
+
return (
|
|
145
|
+
<SelectPrimitive.ScrollDownButton
|
|
146
|
+
data-slot="select-scroll-down-button"
|
|
147
|
+
className={cn(
|
|
148
|
+
"z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
149
|
+
className,
|
|
150
|
+
)}
|
|
151
|
+
{...props}
|
|
152
|
+
>
|
|
153
|
+
<ChevronDownIcon />
|
|
154
|
+
</SelectPrimitive.ScrollDownButton>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export {
|
|
159
|
+
Select,
|
|
160
|
+
SelectContent,
|
|
161
|
+
SelectGroup,
|
|
162
|
+
SelectItem,
|
|
163
|
+
SelectLabel,
|
|
164
|
+
SelectScrollDownButton,
|
|
165
|
+
SelectScrollUpButton,
|
|
166
|
+
SelectSeparator,
|
|
167
|
+
SelectTrigger,
|
|
168
|
+
SelectValue,
|
|
169
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Separator as SeparatorPrimitive } from "radix-ui";
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
|
|
8
|
+
function Separator({
|
|
9
|
+
className,
|
|
10
|
+
orientation = "horizontal",
|
|
11
|
+
decorative = true,
|
|
12
|
+
...props
|
|
13
|
+
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
|
|
14
|
+
return (
|
|
15
|
+
<SeparatorPrimitive.Root
|
|
16
|
+
data-slot="separator"
|
|
17
|
+
decorative={decorative}
|
|
18
|
+
orientation={orientation}
|
|
19
|
+
className={cn(
|
|
20
|
+
"shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
|
|
21
|
+
className,
|
|
22
|
+
)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { Separator };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Switch as SwitchPrimitive } from "radix-ui";
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
|
|
8
|
+
function Switch({ className, ...props }: React.ComponentProps<typeof SwitchPrimitive.Root>) {
|
|
9
|
+
return (
|
|
10
|
+
<SwitchPrimitive.Root
|
|
11
|
+
data-slot="switch"
|
|
12
|
+
className={cn(
|
|
13
|
+
"peer inline-flex h-[1.15rem] w-8 shrink-0 cursor-pointer items-center rounded-full border border-transparent shadow-xs transition-colors outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input dark:data-[state=unchecked]:bg-input/80",
|
|
14
|
+
className,
|
|
15
|
+
)}
|
|
16
|
+
{...props}
|
|
17
|
+
>
|
|
18
|
+
<SwitchPrimitive.Thumb
|
|
19
|
+
data-slot="switch-thumb"
|
|
20
|
+
className={cn(
|
|
21
|
+
"pointer-events-none block size-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0",
|
|
22
|
+
)}
|
|
23
|
+
/>
|
|
24
|
+
</SwitchPrimitive.Root>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { Switch };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
import { cn } from "@/lib/utils";
|
|
6
|
+
|
|
7
|
+
function Table({ className, ...props }: React.ComponentProps<"table">) {
|
|
8
|
+
return (
|
|
9
|
+
<div data-slot="table-container" className="relative w-full overflow-x-auto">
|
|
10
|
+
<table data-slot="table" className={cn("w-full caption-bottom text-sm", className)} {...props} />
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
|
|
16
|
+
return <thead data-slot="table-header" className={cn("[&_tr]:border-b", className)} {...props} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
|
|
20
|
+
return <tbody data-slot="table-body" className={cn("[&_tr:last-child]:border-0", className)} {...props} />;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
|
|
24
|
+
return (
|
|
25
|
+
<tfoot
|
|
26
|
+
data-slot="table-footer"
|
|
27
|
+
className={cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className)}
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
|
|
34
|
+
return (
|
|
35
|
+
<tr
|
|
36
|
+
data-slot="table-row"
|
|
37
|
+
className={cn("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", className)}
|
|
38
|
+
{...props}
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function TableHead({ className, ...props }: React.ComponentProps<"th">) {
|
|
44
|
+
return (
|
|
45
|
+
<th
|
|
46
|
+
data-slot="table-head"
|
|
47
|
+
className={cn(
|
|
48
|
+
"h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
|
|
49
|
+
className,
|
|
50
|
+
)}
|
|
51
|
+
{...props}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function TableCell({ className, ...props }: React.ComponentProps<"td">) {
|
|
57
|
+
return (
|
|
58
|
+
<td
|
|
59
|
+
data-slot="table-cell"
|
|
60
|
+
className={cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className)}
|
|
61
|
+
{...props}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function TableCaption({ className, ...props }: React.ComponentProps<"caption">) {
|
|
67
|
+
return (
|
|
68
|
+
<caption data-slot="table-caption" className={cn("mt-4 text-sm text-muted-foreground", className)} {...props} />
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
5
|
+
import { Tabs as TabsPrimitive } from "radix-ui";
|
|
6
|
+
|
|
7
|
+
import { cn } from "@/lib/utils";
|
|
8
|
+
|
|
9
|
+
function Tabs({ className, orientation = "horizontal", ...props }: React.ComponentProps<typeof TabsPrimitive.Root>) {
|
|
10
|
+
return (
|
|
11
|
+
<TabsPrimitive.Root
|
|
12
|
+
data-slot="tabs"
|
|
13
|
+
data-orientation={orientation}
|
|
14
|
+
className={cn("group/tabs flex gap-2 data-horizontal:flex-col", className)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const tabsListVariants = cva(
|
|
21
|
+
"group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none",
|
|
22
|
+
{
|
|
23
|
+
variants: {
|
|
24
|
+
variant: {
|
|
25
|
+
default: "bg-muted",
|
|
26
|
+
line: "gap-1 bg-transparent",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
defaultVariants: {
|
|
30
|
+
variant: "default",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
function TabsList({
|
|
36
|
+
className,
|
|
37
|
+
variant = "default",
|
|
38
|
+
...props
|
|
39
|
+
}: React.ComponentProps<typeof TabsPrimitive.List> & VariantProps<typeof tabsListVariants>) {
|
|
40
|
+
return (
|
|
41
|
+
<TabsPrimitive.List
|
|
42
|
+
data-slot="tabs-list"
|
|
43
|
+
data-variant={variant}
|
|
44
|
+
className={cn(tabsListVariants({ variant }), className)}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
|
|
51
|
+
return (
|
|
52
|
+
<TabsPrimitive.Trigger
|
|
53
|
+
data-slot="tabs-trigger"
|
|
54
|
+
className={cn(
|
|
55
|
+
"relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
56
|
+
"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent",
|
|
57
|
+
"data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground",
|
|
58
|
+
"after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
|
|
59
|
+
className,
|
|
60
|
+
)}
|
|
61
|
+
{...props}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Content>) {
|
|
67
|
+
return (
|
|
68
|
+
<TabsPrimitive.Content
|
|
69
|
+
data-slot="tabs-content"
|
|
70
|
+
className={cn("flex-1 text-sm outline-none", className)}
|
|
71
|
+
{...props}
|
|
72
|
+
/>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils";
|
|
4
|
+
|
|
5
|
+
function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
|
|
6
|
+
return (
|
|
7
|
+
<textarea
|
|
8
|
+
data-slot="textarea"
|
|
9
|
+
className={cn(
|
|
10
|
+
"flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
|
11
|
+
className,
|
|
12
|
+
)}
|
|
13
|
+
{...props}
|
|
14
|
+
/>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { Textarea };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
5
|
+
import { Toggle as TogglePrimitive } from "radix-ui";
|
|
6
|
+
|
|
7
|
+
import { cn } from "@/lib/utils";
|
|
8
|
+
|
|
9
|
+
const toggleVariants = cva(
|
|
10
|
+
"inline-flex shrink-0 items-center justify-center gap-2 rounded-md border border-transparent bg-transparent text-sm font-medium whitespace-nowrap transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-primary data-[state=on]:text-primary-foreground data-[state=on]:hover:bg-primary/90 dark:data-[state=on]:bg-primary dark:data-[state=on]:hover:bg-primary/90 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
11
|
+
{
|
|
12
|
+
variants: {
|
|
13
|
+
variant: {
|
|
14
|
+
default: "bg-transparent",
|
|
15
|
+
outline:
|
|
16
|
+
"border border-border bg-transparent shadow-sm hover:bg-muted hover:text-foreground data-[state=on]:border-primary data-[state=on]:text-primary-foreground",
|
|
17
|
+
},
|
|
18
|
+
size: {
|
|
19
|
+
default: "h-8 min-w-8 px-2",
|
|
20
|
+
sm: "h-7 min-w-[2.75rem] rounded-full px-2 text-xs",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
variant: "default",
|
|
25
|
+
size: "default",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
function Toggle({
|
|
31
|
+
className,
|
|
32
|
+
variant,
|
|
33
|
+
size,
|
|
34
|
+
...props
|
|
35
|
+
}: React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>) {
|
|
36
|
+
return (
|
|
37
|
+
<TogglePrimitive.Root data-slot="toggle" className={cn(toggleVariants({ variant, size, className }))} {...props} />
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { Toggle, toggleVariants };
|