mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 18:05:11 +03:00
fix: FormItemLayout width fix, <Sheet/> renamed with prop name reverted, started new form story (#21989)
* init * Fix some TS errors. Comment out a unspecified form field. --------- Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
This commit is contained in:
1 parent
1ea12bfed0
commit
204b4e04a3
8 files changed
+608
-135
No files matched your search
+9
-9
@@ -2,9 +2,9 @@ import type { PostgresPolicy } from '@supabase/postgres-meta'
|
||||
import clsx from 'clsx'
|
||||
import { PanelLeftClose, PanelRightClose, X } from 'lucide-react'
|
||||
import {
|
||||
SheetClose_Shadcn_,
|
||||
SheetHeader_Shadcn_,
|
||||
SheetTitle_Shadcn_,
|
||||
SheetClose,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
TooltipContent_Shadcn_,
|
||||
TooltipTrigger_Shadcn_,
|
||||
Tooltip_Shadcn_,
|
||||
@@ -21,14 +21,14 @@ export const AIPolicyHeader = ({
|
||||
setAssistantVisible: (v: boolean) => void
|
||||
}) => {
|
||||
return (
|
||||
<SheetHeader_Shadcn_
|
||||
<SheetHeader
|
||||
className={cn(
|
||||
selectedPolicy !== undefined ? 'pt-3 pb-0' : 'py-3',
|
||||
'flex flex-row justify-between items-center'
|
||||
)}
|
||||
>
|
||||
<div className="flex flex-row gap-3 items-center max-w-[75%]">
|
||||
<SheetClose_Shadcn_
|
||||
<SheetClose
|
||||
className={clsx(
|
||||
'text-muted hover:text ring-offset-background transition-opacity hover:opacity-100',
|
||||
'focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
|
||||
@@ -38,13 +38,13 @@ export const AIPolicyHeader = ({
|
||||
>
|
||||
<X className="h-3 w-3" />
|
||||
<span className="sr-only">Close</span>
|
||||
</SheetClose_Shadcn_>
|
||||
</SheetClose>
|
||||
<div className="h-[24px] w-[1px] bg-border-overlay" />
|
||||
<SheetTitle_Shadcn_ className="truncate">
|
||||
<SheetTitle className="truncate">
|
||||
{selectedPolicy !== undefined
|
||||
? `Update policy: ${selectedPolicy.name}`
|
||||
: 'Create a new Row Level Security policy'}
|
||||
</SheetTitle_Shadcn_>
|
||||
</SheetTitle>
|
||||
</div>
|
||||
<Tooltip_Shadcn_>
|
||||
<TooltipTrigger_Shadcn_ asChild>
|
||||
@@ -69,6 +69,6 @@ export const AIPolicyHeader = ({
|
||||
{assistantVisible ? 'Hide' : 'Show'} tools
|
||||
</TooltipContent_Shadcn_>
|
||||
</Tooltip_Shadcn_>
|
||||
</SheetHeader_Shadcn_>
|
||||
</SheetHeader>
|
||||
)
|
||||
}
|
||||
@@ -14,9 +14,9 @@ import {
|
||||
IconGrid,
|
||||
Modal,
|
||||
ScrollArea,
|
||||
SheetContent_Shadcn_,
|
||||
SheetFooter_Shadcn_,
|
||||
Sheet_Shadcn_,
|
||||
SheetContent,
|
||||
SheetFooter,
|
||||
Sheet,
|
||||
TabsContent_Shadcn_,
|
||||
TabsList_Shadcn_,
|
||||
TabsTrigger_Shadcn_,
|
||||
@@ -293,8 +293,8 @@ export const AIPolicyEditorPanel = memo(function ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<Sheet_Shadcn_ open={visible} onOpenChange={() => onClosingPanel()}>
|
||||
<SheetContent_Shadcn_
|
||||
<Sheet open={visible} onOpenChange={() => onClosingPanel()}>
|
||||
<SheetContent
|
||||
size={assistantVisible ? 'lg' : 'default'}
|
||||
className={cn(
|
||||
'bg-surface-200',
|
||||
@@ -402,7 +402,7 @@ export const AIPolicyEditorPanel = memo(function ({
|
||||
setOpen={setErrorPanelOpen}
|
||||
/>
|
||||
)}
|
||||
<SheetFooter_Shadcn_ className="flex items-center !justify-between px-5 py-4 w-full">
|
||||
<SheetFooter className="flex items-center !justify-between px-5 py-4 w-full">
|
||||
<Button type="text" onClick={toggleFeaturePreviewModal}>
|
||||
Toggle feature preview
|
||||
</Button>
|
||||
@@ -419,7 +419,7 @@ export const AIPolicyEditorPanel = memo(function ({
|
||||
Save policy
|
||||
</Button>
|
||||
</div>
|
||||
</SheetFooter_Shadcn_>
|
||||
</SheetFooter>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -512,8 +512,8 @@ export const AIPolicyEditorPanel = memo(function ({
|
||||
</p>
|
||||
</Modal.Content>
|
||||
</ConfirmationModal>
|
||||
</SheetContent_Shadcn_>
|
||||
</Sheet_Shadcn_>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
@@ -23,7 +23,11 @@ const InfoTooltip = forwardRef<
|
||||
>(({ ...props }, ref) => {
|
||||
return (
|
||||
<Tooltip_Shadcn_>
|
||||
<TooltipTrigger_Shadcn_ className="flex [&_svg]:data-[state=delayed-open]:fill-foreground-lighter [&_svg]:data-[state=instant-open]:fill-foreground-lighter">
|
||||
<TooltipTrigger_Shadcn_
|
||||
type="button"
|
||||
role="button"
|
||||
className="flex [&_svg]:data-[state=delayed-open]:fill-foreground-lighter [&_svg]:data-[state=instant-open]:fill-foreground-lighter"
|
||||
>
|
||||
<SVG strokeWidth={2} className="transition-colors fill-foreground-muted w-4 h-4" />
|
||||
</TooltipTrigger_Shadcn_>
|
||||
<TooltipContent_Shadcn_ {...props} />
|
||||
|
||||
@@ -0,0 +1,434 @@
|
||||
import { zodResolver } from '@hookform/resolvers/zod'
|
||||
import { Box, FileWarning } from 'lucide-react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import {
|
||||
Badge_Shadcn_,
|
||||
Button,
|
||||
Checkbox_Shadcn_,
|
||||
Form_Shadcn_,
|
||||
FormControl_Shadcn_,
|
||||
FormField_Shadcn_,
|
||||
RadioGroup_Shadcn_,
|
||||
RadioGroupItem_Shadcn_,
|
||||
Select_Shadcn_,
|
||||
SelectContent_Shadcn_,
|
||||
SelectItem_Shadcn_,
|
||||
SelectTrigger_Shadcn_,
|
||||
SelectValue_Shadcn_,
|
||||
Separator,
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetDescription,
|
||||
SheetFooter,
|
||||
SheetHeader,
|
||||
SheetSection,
|
||||
SheetTitle,
|
||||
SidePanel,
|
||||
Switch,
|
||||
} from 'ui'
|
||||
import { z } from 'zod'
|
||||
import { Input } from '../DataInputs/Input'
|
||||
import { InfoTooltip } from '../InfoTooltip/InfoTooltip'
|
||||
import { FormItemLayout } from './FormItemLayout/FormItemLayout'
|
||||
|
||||
const items = [
|
||||
{
|
||||
id: 'recents',
|
||||
label: 'Recents',
|
||||
},
|
||||
{
|
||||
id: 'home',
|
||||
label: 'Home',
|
||||
},
|
||||
{
|
||||
id: 'applications',
|
||||
label: 'Applications',
|
||||
},
|
||||
{
|
||||
id: 'desktop',
|
||||
label: 'Desktop',
|
||||
},
|
||||
{
|
||||
id: 'downloads',
|
||||
label: 'Downloads',
|
||||
},
|
||||
{
|
||||
id: 'documents',
|
||||
label: 'Documents',
|
||||
},
|
||||
] as const
|
||||
|
||||
export const Page = () => {
|
||||
const FormSchema = z.object({
|
||||
username: z.string().min(2, {
|
||||
message: 'Username must be at least 2 characters.',
|
||||
}),
|
||||
kevins_input: z.string().min(6, {
|
||||
message: 'Username must be at least 6 characters.',
|
||||
}),
|
||||
email: z
|
||||
.string({
|
||||
required_error: 'Please select an email to display.',
|
||||
})
|
||||
.email(),
|
||||
consistent_settings: z.boolean().default(false).optional(),
|
||||
switch_option: z.boolean().default(false).optional(),
|
||||
items: z.array(z.string()).refine((value) => value.some((item) => item), {
|
||||
message: 'You have to select at least one item.',
|
||||
}),
|
||||
type: z.enum(['all', 'mentions', 'none'], {
|
||||
required_error: 'You need to select a notification type.',
|
||||
}),
|
||||
})
|
||||
|
||||
const form = useForm<z.infer<typeof FormSchema>>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
defaultValues: {
|
||||
username: '',
|
||||
items: ['recents', 'home'],
|
||||
},
|
||||
})
|
||||
|
||||
function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||
console.log(data)
|
||||
}
|
||||
|
||||
const UserIcon = () => {
|
||||
return (
|
||||
<div>
|
||||
<img
|
||||
className="relative h-4 w-4 rounded-full"
|
||||
src="https://avatars.githubusercontent.com/u/8291514?v=4"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Sheet open={true}>
|
||||
<SheetContent side="right" className="overflow-auto" size="default">
|
||||
<SheetHeader>
|
||||
<SheetTitle>Create a function</SheetTitle>
|
||||
<SheetDescription>Create a function</SheetDescription>
|
||||
</SheetHeader>
|
||||
<Form_Shadcn_ {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<SheetSection>
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="username"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Function name"
|
||||
description="Name will also be used for the function name in postgres."
|
||||
layout="horizontal"
|
||||
labelOptional="Optional"
|
||||
afterLabel={
|
||||
<InfoTooltip side="right">You can also rename this later.</InfoTooltip>
|
||||
}
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Input placeholder="Name of function" {...field} />
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
</SheetSection>
|
||||
<Separator />
|
||||
|
||||
{/* <FormField
|
||||
control={form.control}
|
||||
name="language"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-col">
|
||||
<FormLabel>Language</FormLabel>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<FormControl>
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
className={cn(
|
||||
'w-[200px] justify-between',
|
||||
!field.value && 'text-muted-foreground'
|
||||
)}
|
||||
>
|
||||
{field.value
|
||||
? languages.find((language) => language.value === field.value)?.label
|
||||
: 'Select language'}
|
||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</FormControl>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-[200px] p-0">
|
||||
<Command>
|
||||
<CommandInput placeholder="Search language..." />
|
||||
<CommandEmpty>No language found.</CommandEmpty>
|
||||
<CommandGroup>
|
||||
{languages.map((language) => (
|
||||
<CommandItem
|
||||
value={language.label}
|
||||
key={language.value}
|
||||
onSelect={() => {
|
||||
form.setValue('language', language.value)
|
||||
}}
|
||||
>
|
||||
<Check
|
||||
className={cn(
|
||||
'mr-2 h-4 w-4',
|
||||
language.value === field.value ? 'opacity-100' : 'opacity-0'
|
||||
)}
|
||||
/>
|
||||
{language.label}
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<FormDescription>
|
||||
This is the language that will be used in the dashboard.
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/> */}
|
||||
<SheetSection>
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="switch_option"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
afterLabel="Switch"
|
||||
label="Use ./supabase directory for everything"
|
||||
description="This is an explanation."
|
||||
layout="flex"
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Switch
|
||||
placeholder="mildtomato"
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
</SheetSection>
|
||||
<Separator />
|
||||
<SheetSection>
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
label="Choose user"
|
||||
description="This is your public display name."
|
||||
layout="horizontal"
|
||||
>
|
||||
<Select_Shadcn_ onValueChange={field.onChange} defaultValue={field.value}>
|
||||
<FormControl_Shadcn_ className="w-full">
|
||||
<SelectTrigger_Shadcn_ className="w-full">
|
||||
<SelectValue_Shadcn_
|
||||
placeholder="Select a verified email"
|
||||
className="flex gap-2"
|
||||
/>
|
||||
</SelectTrigger_Shadcn_>
|
||||
</FormControl_Shadcn_>
|
||||
<SelectContent_Shadcn_>
|
||||
<SelectItem_Shadcn_ value="m@example.com">
|
||||
<div className="flex gap-2 items-center">
|
||||
<UserIcon />
|
||||
<span>m@example.com</span>
|
||||
</div>
|
||||
</SelectItem_Shadcn_>
|
||||
<SelectItem_Shadcn_ value="m@google.com" className="flex gap-2">
|
||||
<div className="flex gap-2 items-center">
|
||||
<UserIcon />
|
||||
UserIconm@google.com
|
||||
</div>
|
||||
</SelectItem_Shadcn_>
|
||||
<SelectItem_Shadcn_ value="m@support.com" className="flex gap-2">
|
||||
<div className="flex gap-2 items-center">
|
||||
<UserIcon />
|
||||
m@support.com
|
||||
</div>
|
||||
</SelectItem_Shadcn_>
|
||||
</SelectContent_Shadcn_>
|
||||
</Select_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
</SheetSection>
|
||||
|
||||
<Separator />
|
||||
|
||||
<SheetSection>
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="kevins_input"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
afterLabel="Kevins input"
|
||||
label="Kevins input"
|
||||
description="This is your public display name."
|
||||
layout="vertical"
|
||||
labelOptional="Optional"
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Input
|
||||
icon={<Box strokeWidth={1.5} size={16} />}
|
||||
placeholder="Needs to be 6 long"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
</SheetSection>
|
||||
|
||||
<Separator />
|
||||
|
||||
<SheetSection>
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="consistent_settings"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
afterLabel={
|
||||
<Badge_Shadcn_ variant={'destructive'} className="flex gap-1">
|
||||
<FileWarning size={14} strokeWidth={1.5} className="text-destructive-500" />
|
||||
Danger zone!
|
||||
</Badge_Shadcn_>
|
||||
}
|
||||
label="Use consistent settings"
|
||||
description="This is your public display name."
|
||||
layout="flex"
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Checkbox_Shadcn_ checked={field.value} onCheckedChange={field.onChange} />
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
</SheetSection>
|
||||
|
||||
<Separator />
|
||||
|
||||
<SheetSection>
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="items"
|
||||
render={() => (
|
||||
<FormItemLayout
|
||||
label="Sidebar"
|
||||
description="Select the items you want to display in the sidebar."
|
||||
layout="horizontal"
|
||||
afterLabel={<InfoTooltip side="right">Please give me info</InfoTooltip>}
|
||||
>
|
||||
{/* <div className="mb-4">
|
||||
<FormLabel className="text-base">Sidebar</FormLabel>
|
||||
<FormDescription>
|
||||
Select the items you want to display in the sidebar.
|
||||
</FormDescription>
|
||||
</div> */}
|
||||
{items.map((item) => (
|
||||
<FormField_Shadcn_
|
||||
key={item.id}
|
||||
control={form.control}
|
||||
name="items"
|
||||
render={({ field }) => {
|
||||
return (
|
||||
<FormItemLayout
|
||||
key={item.id}
|
||||
className="flex flex-row items-start space-x-3 space-y-0"
|
||||
label={item.label}
|
||||
layout="flex"
|
||||
hideMessage
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<Checkbox_Shadcn_
|
||||
checked={field.value?.includes(item.id)}
|
||||
onCheckedChange={(checked) => {
|
||||
return checked
|
||||
? field.onChange([...field.value, item.id])
|
||||
: field.onChange(
|
||||
field.value?.filter((value) => value !== item.id)
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{/* <FormMessage /> */}
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
</SheetSection>
|
||||
|
||||
<SheetSection>
|
||||
<FormField_Shadcn_
|
||||
control={form.control}
|
||||
name="type"
|
||||
render={({ field }) => (
|
||||
<FormItemLayout
|
||||
className="space-y-3"
|
||||
label="Notify me about..."
|
||||
description="I am descript"
|
||||
layout="horizontal"
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<RadioGroup_Shadcn_
|
||||
onValueChange={field.onChange}
|
||||
defaultValue={field.value}
|
||||
className="flex flex-col space-y-1"
|
||||
>
|
||||
<FormItemLayout
|
||||
className="flex items-center space-x-3 space-y-0"
|
||||
label="All new messages"
|
||||
layout="flex"
|
||||
hideMessage
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<RadioGroupItem_Shadcn_ value="all" />
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
<FormItemLayout
|
||||
className="flex items-center space-x-3 space-y-0"
|
||||
label="Direct messages and mentions"
|
||||
layout="flex"
|
||||
hideMessage
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<RadioGroupItem_Shadcn_ value="mentions" />
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
<FormItemLayout
|
||||
className="flex items-center space-x-3 space-y-0"
|
||||
label="Nothing"
|
||||
layout="flex"
|
||||
hideMessage
|
||||
>
|
||||
<FormControl_Shadcn_>
|
||||
<RadioGroupItem_Shadcn_ value="none" />
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
</RadioGroup_Shadcn_>
|
||||
</FormControl_Shadcn_>
|
||||
</FormItemLayout>
|
||||
)}
|
||||
/>
|
||||
</SheetSection>
|
||||
<SheetFooter>
|
||||
<Button type="default">Cancel</Button>
|
||||
<Button htmlType="submit">Submit</Button>
|
||||
</SheetFooter>
|
||||
</form>
|
||||
</Form_Shadcn_>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
)
|
||||
}
|
||||
@@ -41,7 +41,7 @@ const ContainerVariants = cva('grid gap-2', {
|
||||
false: '',
|
||||
},
|
||||
layout: {
|
||||
horizontal: 'flex flex-row gap-6 justify-between',
|
||||
horizontal: 'grid grid-cols-12',
|
||||
vertical: 'flex flex-col gap-3',
|
||||
flex: 'flex flex-row gap-3',
|
||||
},
|
||||
@@ -71,7 +71,7 @@ const LabelContainerVariants = cva('', {
|
||||
right: '',
|
||||
},
|
||||
layout: {
|
||||
horizontal: 'flex flex-col gap-2',
|
||||
horizontal: 'flex flex-col gap-2 col-span-4',
|
||||
vertical: 'flex flex-row gap-2 justify-between',
|
||||
flex: 'flex flex-col gap-0',
|
||||
},
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// import { within, userEvent, expect } from '@storybook/test'
|
||||
import { TooltipProvider_Shadcn_ } from 'ui'
|
||||
import { Page } from './FormLayout2'
|
||||
|
||||
export default {
|
||||
title: 'Form Examples/Side Panel Function Create',
|
||||
component: Page,
|
||||
parameters: {
|
||||
// More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
|
||||
layout: 'centered',
|
||||
},
|
||||
decorators: [
|
||||
(Story: any) => {
|
||||
return (
|
||||
<TooltipProvider_Shadcn_>
|
||||
<Story />
|
||||
</TooltipProvider_Shadcn_>
|
||||
)
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export const StateOne = {}
|
||||
|
||||
// More on interaction testing: https://storybook.js.org/docs/writing-tests/interaction-testing
|
||||
// export const LoggedIn = {
|
||||
// play: async ({ canvasElement }) => {
|
||||
// const canvas = within(canvasElement)
|
||||
// const loginButton = canvas.getByRole('button', { name: /Log in/i })
|
||||
// await expect(loginButton).toBeInTheDocument()
|
||||
// await userEvent.click(loginButton)
|
||||
// await expect(loginButton).not.toBeInTheDocument()
|
||||
|
||||
// const logoutButton = canvas.getByRole('button', { name: /Log out/i })
|
||||
// await expect(logoutButton).toBeInTheDocument()
|
||||
// },
|
||||
// }
|
||||
+1
-11
@@ -85,6 +85,7 @@ export * from './src/components/shadcn/ui/toaster'
|
||||
export { Badge as Badge_Shadcn_ } from './src/components/shadcn/ui/badge'
|
||||
|
||||
export * from './src/components/shadcn/ui/separator'
|
||||
export * from './src/components/shadcn/ui/sheet'
|
||||
|
||||
export {
|
||||
Command as Command_Shadcn_,
|
||||
@@ -171,17 +172,6 @@ export {
|
||||
CollapsibleContent as CollapsibleContent_Shadcn_,
|
||||
} from './src/components/shadcn/ui/collapsible'
|
||||
|
||||
export {
|
||||
Sheet as Sheet_Shadcn_,
|
||||
SheetTrigger as SheetTrigger_Shadcn_,
|
||||
SheetClose as SheetClose_Shadcn_,
|
||||
SheetContent as SheetContent_Shadcn_,
|
||||
SheetHeader as SheetHeader_Shadcn_,
|
||||
SheetFooter as SheetFooter_Shadcn_,
|
||||
SheetTitle as SheetTitle_Shadcn_,
|
||||
SheetDescription as SheetDescription_Shadcn_,
|
||||
} from './src/components/shadcn/ui/sheet'
|
||||
|
||||
export {
|
||||
Tabs as Tabs_Shadcn_,
|
||||
TabsContent as TabsContent_Shadcn_,
|
||||
|
||||
@@ -5,6 +5,7 @@ import { cva, type VariantProps } from 'class-variance-authority'
|
||||
import * as React from 'react'
|
||||
|
||||
import { cn } from '../../../lib/utils/cn'
|
||||
import { X } from 'lucide-react'
|
||||
|
||||
const Sheet = SheetPrimitive.Root
|
||||
|
||||
@@ -14,23 +15,23 @@ const SheetClose = SheetPrimitive.Close
|
||||
|
||||
const portalVariants = cva('fixed inset-0 z-40 flex', {
|
||||
variants: {
|
||||
position: {
|
||||
side: {
|
||||
top: 'items-start',
|
||||
bottom: 'items-end',
|
||||
left: 'justify-start',
|
||||
right: 'justify-end',
|
||||
},
|
||||
},
|
||||
defaultVariants: { position: 'right' },
|
||||
defaultVariants: { side: 'right' },
|
||||
})
|
||||
|
||||
interface SheetPortalProps
|
||||
extends SheetPrimitive.DialogPortalProps,
|
||||
VariantProps<typeof portalVariants> {}
|
||||
|
||||
const SheetPortal = ({ position, children, ...props }: SheetPortalProps) => (
|
||||
const SheetPortal = ({ side, children, ...props }: SheetPortalProps) => (
|
||||
<SheetPrimitive.Portal {...props}>
|
||||
<div className={portalVariants({ position })}>{children}</div>
|
||||
<div className={portalVariants({ side })}>{children}</div>
|
||||
</SheetPrimitive.Portal>
|
||||
)
|
||||
SheetPortal.displayName = SheetPrimitive.Portal.displayName
|
||||
@@ -41,7 +42,7 @@ const SheetOverlay = React.forwardRef<
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<SheetPrimitive.Overlay
|
||||
className={cn(
|
||||
'fixed inset-0 z-40 bg-background/80 backdrop-blur-sm transition-all duration-100 data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in',
|
||||
'fixed inset-0 z-40 bg-alternative/90 backdrop-blur-sm transition-all duration-100 data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -50,99 +51,96 @@ const SheetOverlay = React.forwardRef<
|
||||
))
|
||||
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
|
||||
|
||||
const sheetVariants = cva(
|
||||
'fixed z-40 scale-100 gap-4 bg-background p-6 opacity-100 shadow-lg border',
|
||||
{
|
||||
variants: {
|
||||
position: {
|
||||
top: 'animate-in slide-in-from-top w-full duration-300',
|
||||
bottom: 'animate-in slide-in-from-bottom w-full duration-300',
|
||||
left: 'animate-in slide-in-from-left h-full duration-300',
|
||||
right: 'animate-in slide-in-from-right h-full duration-300',
|
||||
},
|
||||
size: {
|
||||
content: '',
|
||||
default: '',
|
||||
sm: '',
|
||||
lg: '',
|
||||
xl: '',
|
||||
xxl: '',
|
||||
full: '',
|
||||
},
|
||||
const sheetVariants = cva('fixed z-40 scale-100 gap-4 bg-studio opacity-100 shadow-lg', {
|
||||
variants: {
|
||||
side: {
|
||||
top: 'animate-in slide-in-from-top w-full duration-300 border-b',
|
||||
bottom: 'animate-in slide-in-from-bottom w-full duration-300 border-t',
|
||||
left: 'animate-in slide-in-from-left h-full duration-300 border-r',
|
||||
right: 'animate-in slide-in-from-right h-full duration-300 border-l',
|
||||
},
|
||||
compoundVariants: [
|
||||
{
|
||||
position: ['top', 'bottom'],
|
||||
size: 'content',
|
||||
class: 'max-h-screen',
|
||||
},
|
||||
{
|
||||
position: ['top', 'bottom'],
|
||||
size: 'default',
|
||||
class: 'h-1/3',
|
||||
},
|
||||
{
|
||||
position: ['top', 'bottom'],
|
||||
size: 'sm',
|
||||
class: 'h-1/4',
|
||||
},
|
||||
{
|
||||
position: ['top', 'bottom'],
|
||||
size: 'lg',
|
||||
class: 'h-1/2',
|
||||
},
|
||||
{
|
||||
position: ['top', 'bottom'],
|
||||
size: 'xl',
|
||||
class: 'h-5/6',
|
||||
},
|
||||
{
|
||||
position: ['top', 'bottom'],
|
||||
size: 'full',
|
||||
class: 'h-screen',
|
||||
},
|
||||
{
|
||||
position: ['right', 'left'],
|
||||
size: 'content',
|
||||
class: 'max-w-screen',
|
||||
},
|
||||
{
|
||||
position: ['right', 'left'],
|
||||
size: 'default',
|
||||
class: 'w-1/3',
|
||||
},
|
||||
{
|
||||
position: ['right', 'left'],
|
||||
size: 'sm',
|
||||
class: 'w-1/4',
|
||||
},
|
||||
{
|
||||
position: ['right', 'left'],
|
||||
size: 'lg',
|
||||
class: 'w-1/2',
|
||||
},
|
||||
{
|
||||
position: ['right', 'left'],
|
||||
size: 'xl',
|
||||
class: 'w-4/6',
|
||||
},
|
||||
{
|
||||
position: ['right', 'left'],
|
||||
size: 'xxl',
|
||||
class: 'w-5/6',
|
||||
},
|
||||
{
|
||||
position: ['right', 'left'],
|
||||
size: 'full',
|
||||
class: 'w-screen',
|
||||
},
|
||||
],
|
||||
defaultVariants: {
|
||||
position: 'right',
|
||||
size: {
|
||||
content: '',
|
||||
default: '',
|
||||
sm: '',
|
||||
lg: '',
|
||||
xl: '',
|
||||
xxl: '',
|
||||
full: '',
|
||||
},
|
||||
},
|
||||
compoundVariants: [
|
||||
{
|
||||
side: ['top', 'bottom'],
|
||||
size: 'content',
|
||||
class: 'max-h-screen',
|
||||
},
|
||||
{
|
||||
side: ['top', 'bottom'],
|
||||
size: 'default',
|
||||
class: 'h-1/3',
|
||||
},
|
||||
}
|
||||
)
|
||||
{
|
||||
side: ['top', 'bottom'],
|
||||
size: 'sm',
|
||||
class: 'h-1/4',
|
||||
},
|
||||
{
|
||||
side: ['top', 'bottom'],
|
||||
size: 'lg',
|
||||
class: 'h-1/2',
|
||||
},
|
||||
{
|
||||
side: ['top', 'bottom'],
|
||||
size: 'xl',
|
||||
class: 'h-5/6',
|
||||
},
|
||||
{
|
||||
side: ['top', 'bottom'],
|
||||
size: 'full',
|
||||
class: 'h-screen',
|
||||
},
|
||||
{
|
||||
side: ['right', 'left'],
|
||||
size: 'content',
|
||||
class: 'max-w-screen',
|
||||
},
|
||||
{
|
||||
side: ['right', 'left'],
|
||||
size: 'default',
|
||||
class: 'w-1/3',
|
||||
},
|
||||
{
|
||||
side: ['right', 'left'],
|
||||
size: 'sm',
|
||||
class: 'w-1/4',
|
||||
},
|
||||
{
|
||||
side: ['right', 'left'],
|
||||
size: 'lg',
|
||||
class: 'w-1/2',
|
||||
},
|
||||
{
|
||||
side: ['right', 'left'],
|
||||
size: 'xl',
|
||||
class: 'w-4/6',
|
||||
},
|
||||
{
|
||||
side: ['right', 'left'],
|
||||
size: 'xxl',
|
||||
class: 'w-5/6',
|
||||
},
|
||||
{
|
||||
side: ['right', 'left'],
|
||||
size: 'full',
|
||||
class: 'w-screen',
|
||||
},
|
||||
],
|
||||
defaultVariants: {
|
||||
side: 'right',
|
||||
size: 'default',
|
||||
},
|
||||
})
|
||||
|
||||
export interface DialogContentProps
|
||||
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
|
||||
@@ -151,32 +149,41 @@ export interface DialogContentProps
|
||||
const SheetContent = React.forwardRef<
|
||||
React.ElementRef<typeof SheetPrimitive.Content>,
|
||||
DialogContentProps
|
||||
>(({ position, size, className, children, ...props }, ref) => (
|
||||
<SheetPortal position={position}>
|
||||
>(({ side, size, className, children, ...props }, ref) => (
|
||||
<SheetPortal side={side}>
|
||||
<SheetOverlay />
|
||||
<SheetPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(sheetVariants({ position, size }), className)}
|
||||
className={cn(sheetVariants({ side, size }), className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
{/* <SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
|
||||
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
|
||||
<X className="h-4 w-4" />
|
||||
<span className="sr-only">Close</span>
|
||||
</SheetPrimitive.Close> */}
|
||||
</SheetPrimitive.Close>
|
||||
</SheetPrimitive.Content>
|
||||
</SheetPortal>
|
||||
))
|
||||
SheetContent.displayName = SheetPrimitive.Content.displayName
|
||||
|
||||
const SheetHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div className={cn('px-5 py-4 text-center sm:text-left', className)} {...props} />
|
||||
<div className={cn('px-5 py-4 text-center sm:text-left border-b', className)} {...props} />
|
||||
)
|
||||
SheetHeader.displayName = 'SheetHeader'
|
||||
|
||||
const SheetSection = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div className={cn('px-content py-content', className)} {...props} />
|
||||
)
|
||||
SheetSection.displayName = 'SheetSection'
|
||||
|
||||
const SheetFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div
|
||||
className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)}
|
||||
className={cn(
|
||||
'px-5 py-3 border-t w-full',
|
||||
'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
@@ -211,8 +218,9 @@ export {
|
||||
SheetClose,
|
||||
SheetContent,
|
||||
SheetDescription,
|
||||
SheetFooter,
|
||||
SheetHeader,
|
||||
SheetSection,
|
||||
SheetFooter,
|
||||
SheetTitle,
|
||||
SheetTrigger,
|
||||
}
|
||||
Reference in new issue
Block a user