Files
Danny White 476d4a5851 refactor(ui): drop redundant Button variant="default" props (#50161)
## What kind of change does this PR introduce?

Mechanical cleanup on top of the Button default-variant change (#50160).

## What is the current behavior?

Many callsites still pass `variant="default"` even though that is now
the component default.

## What is the new behavior?

Removes redundant static `variant="default"` from legacy `Button` and
`ButtonTooltip` callsites. Keeps explicit defaults where they document
the API:

- `button-default.tsx` and `button-sizes.tsx` demos
- `DocsButton`, which pins neutral styling at the wrapper boundary

## To test

Studio:

- [Auth → Rate
Limits](https://studio-staging-2s957kwc4-supabase.vercel.app/dashboard/project/_/auth/rate-limits):
dirty the form so Cancel appears; Cancel stays neutral, Save stays green
- [Project Settings → API
Keys](https://studio-staging-2s957kwc4-supabase.vercel.app/dashboard/project/_/settings/api-keys):
`DocsButton` in the header actions stays neutral

Design system:

- [Design system →
Button](https://design-system-git-dnywh-dc924ac1-supabase.vercel.app/design-system/docs/components/button):
`button-default` / `button-sizes` still show explicit default styling;
Primary (green) is restricted to the Primary section (and `asChild`)

WWW:

- [www → Brand
assets](https://zone-www-dot-com-git-dnywh-dc924ac1-supabase.vercel.app/brand-assets):
Download logo kit / Download button kit stay neutral
2026-09-11 17:05:26 +10:00

184 lines
6.0 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { zodResolver } from '@hookform/resolvers/zod'
import { useParams } from 'common'
import { Eye, EyeOff } from 'lucide-react'
import { useEffect, useState } from 'react'
import { SubmitHandler, useForm } from 'react-hook-form'
import { useLatest } from 'react-use'
import { toast } from 'sonner'
import {
Button,
Form,
FormControl,
FormField,
Input,
Sheet,
SheetContent,
SheetFooter,
SheetHeader,
SheetSection,
SheetTitle,
Textarea,
} from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import z from 'zod'
import { DiscardChangesConfirmationDialog } from '@/components/ui-patterns/Dialogs/DiscardChangesConfirmationDialog'
import { useSecretsCreateMutation } from '@/data/secrets/secrets-create-mutation'
import { ProjectSecret } from '@/data/secrets/secrets-query'
import { useConfirmOnClose } from '@/hooks/ui/useConfirmOnClose'
const FORM_ID = 'edit-secret-sidepanel'
const FormSchema = z.object({
name: z.string().min(1, 'Please provide a name for your secret'),
value: z.string().min(1, 'Please provide a value for your secret'),
})
type FormSchemaType = z.infer<typeof FormSchema>
interface EditSecretSheetProps {
secret?: ProjectSecret
visible: boolean
onClose: () => void
}
export function EditSecretSheet({ secret, visible, onClose }: EditSecretSheetProps) {
const { ref: projectRef } = useParams()
const secretName = useLatest(secret?.name)
const [showSecretValue, setShowSecretValue] = useState(false)
const form = useForm<FormSchemaType>({
resolver: zodResolver(FormSchema),
})
const isValid = form.formState.isValid
const isDirty = form.formState.isDirty
const { mutate: updateSecret, isPending: isUpdating } = useSecretsCreateMutation({
onSuccess: (_, variables) => {
toast.success(`Successfully updated secret "${variables.secrets[0].name}"`)
onClose()
},
})
const onSubmit: SubmitHandler<FormSchemaType> = async ({ name, value }) => {
updateSecret({
projectRef,
secrets: [{ name, value }],
})
}
const { confirmOnClose, handleOpenChange, modalProps } = useConfirmOnClose({
checkIsDirty: () => isDirty,
onClose,
})
useEffect(() => {
if (visible) {
form.reset({ name: secretName.current ?? '', value: '' })
}
}, [form, secretName, visible])
return (
<Sheet open={visible} onOpenChange={handleOpenChange}>
<SheetContent size="default" className={'min-w-screen! lg:min-w-[600px]! flex flex-col'}>
<SheetHeader className="py-3 flex flex-row gap-3 items-center">
<SheetTitle>Edit secret</SheetTitle>
</SheetHeader>
<SheetSection className="h-full">
<Form {...form}>
<form
id={FORM_ID}
className="flex flex-col gap-y-4"
onSubmit={form.handleSubmit(onSubmit)}
>
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItemLayout label="Name" layout="horizontal">
<FormControl>
<Input
{...field}
readOnly
className="text-foreground-light! cursor-not-allowed"
/>
</FormControl>
</FormItemLayout>
)}
/>
<FormField
control={form.control}
name="value"
render={({ field }) => (
<FormItemLayout
label="Value"
layout="horizontal"
description="Secrets can’t be retrieved once saved. Enter a new value to overwrite the existing value."
>
<FormControl>
<div className="relative">
<Textarea
{...field}
rows={1}
ref={(el) => {
field.ref(el)
if (el) {
el.style.height = 'auto'
el.style.height = Math.max(40, el.scrollHeight) + 'px'
}
}}
placeholder="my-secret-value"
data-1p-ignore
data-lpignore="true"
data-form-type="other"
data-bwignore
className="min-h-0 resize-none"
style={
{
WebkitTextSecurity: showSecretValue ? undefined : 'disc',
} as React.CSSProperties
}
onChange={(e) => {
field.onChange(e)
e.currentTarget.style.height = 'auto'
e.currentTarget.style.height =
Math.max(40, e.currentTarget.scrollHeight) + 'px'
}}
/>
<Button
variant="text"
className="absolute right-1 top-1 px-1"
icon={showSecretValue ? <EyeOff /> : <Eye />}
onClick={() => setShowSecretValue(!showSecretValue)}
/>
</div>
</FormControl>
</FormItemLayout>
)}
/>
</form>
</Form>
</SheetSection>
<SheetFooter>
<Button disabled={isUpdating} onClick={confirmOnClose}>
Cancel
</Button>
<Button
variant="primary"
form={FORM_ID}
type="submit"
disabled={!isValid}
loading={isUpdating}
>
Save
</Button>
</SheetFooter>
</SheetContent>
<DiscardChangesConfirmationDialog {...modalProps} />
</Sheet>
)
}