refactor: unify button style

Signed-off-by: Innei <i@innei.in>
This commit is contained in:
Innei 2024-08-19 13:59:24 +08:00
parent 6e1ee50536
commit 430ee81228
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
40 changed files with 186 additions and 374 deletions

View File

@ -12,6 +12,7 @@
// ["tw\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
["tw`([^`]*)`", "([^`]*)"]
],
// If you do not want to autofix some rules on save

View File

@ -5,7 +5,7 @@ import { useEffect, useRef } from "react"
import { isRouteErrorResponse, useRouteError } from "react-router-dom"
import { toast } from "sonner"
import { StyledButton } from "../ui/button"
import { Button } from "../ui/button"
import { PoweredByFooter } from "./PoweredByFooter"
export function ErrorElement() {
@ -68,7 +68,7 @@ export function ErrorElement() {
</p>
<div className="center gap-4">
<StyledButton
<Button
variant="outline"
onClick={() => {
clearLocalPersistStoreData()
@ -76,10 +76,10 @@ export function ErrorElement() {
}}
>
Reset Local Database
</StyledButton>
<StyledButton onClick={() => (window.location.href = "/")}>
</Button>
<Button onClick={() => (window.location.href = "/")}>
Reload
</StyledButton>
</Button>
</div>
<FallbackIssue message={message} stack={stack} />

View File

@ -5,7 +5,7 @@ import type { Location } from "react-router-dom"
import { useLocation, useNavigate } from "react-router-dom"
import { Logo } from "../icons/logo"
import { StyledButton } from "../ui/button"
import { Button } from "../ui/button"
import { PoweredByFooter } from "./PoweredByFooter"
class AccessNotFoundError extends Error {
@ -53,9 +53,9 @@ export const NotFound = () => {
</p>
<p>
<StyledButton onClick={() => navigate("/")}>
<Button onClick={() => navigate("/")}>
Back to Home
</StyledButton>
</Button>
</p>
</main>

View File

@ -9,7 +9,7 @@ import { useNavigate } from "react-router-dom"
import type { AppErrorFallbackProps } from "../common/AppErrorBoundary"
import { FeedIcon } from "../feed-icon"
import { StyledButton } from "../ui/button"
import { Button } from "../ui/button"
import { useModalStack } from "../ui/modal"
import { CustomSafeError, useResetErrorWhenRouteChange } from "./helper"
@ -40,7 +40,7 @@ export const FeedFoundCanBeFollowErrorFallback: FC<AppErrorFallbackProps> = ({
homepage.
</div>
<div className="center mt-12 gap-4">
<StyledButton
<Button
variant="outline"
onClick={() => {
navigate("/")
@ -50,9 +50,9 @@ export const FeedFoundCanBeFollowErrorFallback: FC<AppErrorFallbackProps> = ({
}}
>
Back
</StyledButton>
</Button>
<StyledButton
<Button
onClick={() => {
present({
title: "Add Feed",
@ -83,7 +83,7 @@ export const FeedFoundCanBeFollowErrorFallback: FC<AppErrorFallbackProps> = ({
variant="primary"
>
Follow
</StyledButton>
</Button>
</div>
</div>
</div>

View File

@ -3,7 +3,7 @@ import { useNavigate } from "react-router-dom"
import type { AppErrorFallbackProps } from "../common/AppErrorBoundary"
import { Logo } from "../icons/logo"
import { StyledButton } from "../ui/button"
import { Button } from "../ui/button"
import { CustomSafeError, useResetErrorWhenRouteChange } from "./helper"
export const FeedNotFoundErrorFallback: FC<AppErrorFallbackProps> = ({
@ -27,7 +27,7 @@ export const FeedNotFoundErrorFallback: FC<AppErrorFallbackProps> = ({
</p>
<div className="center mt-12 gap-4">
<StyledButton
<Button
variant="outline"
onClick={() => {
navigate("/")
@ -37,7 +37,7 @@ export const FeedNotFoundErrorFallback: FC<AppErrorFallbackProps> = ({
}}
>
Back
</StyledButton>
</Button>
</div>
</div>
</div>

View File

@ -4,7 +4,7 @@ import type { FC } from "react"
import type { AppErrorFallbackProps } from "../common/AppErrorBoundary"
import { FallbackIssue } from "../common/ErrorElement"
import { m } from "../common/Motion"
import { StyledButton } from "../ui/button"
import { Button } from "../ui/button"
import { useCurrentModal } from "../ui/modal"
import { parseError } from "./helper"
@ -36,15 +36,15 @@ export const ModalErrorFallback: FC<AppErrorFallbackProps> = (props) => {
</p>
<div className="center gap-4">
<StyledButton onClick={() => modal.dismiss()} variant="outline">
<Button onClick={() => modal.dismiss()} variant="outline">
Close Modal
</StyledButton>
<StyledButton
</Button>
<Button
onClick={() => window.location.reload()}
variant="outline"
>
Reload
</StyledButton>
</Button>
</div>
<FallbackIssue message={message!} stack={stack} />

View File

@ -3,7 +3,7 @@ import type { FC } from "react"
import type { AppErrorFallbackProps } from "../common/AppErrorBoundary"
import { FallbackIssue } from "../common/ErrorElement"
import { StyledButton } from "../ui/button"
import { Button } from "../ui/button"
import { parseError } from "./helper"
export const PageErrorFallback: FC<AppErrorFallbackProps> = (props) => {
@ -28,16 +28,16 @@ export const PageErrorFallback: FC<AppErrorFallbackProps> = (props) => {
</p>
<div className="center gap-4">
<StyledButton onClick={() => props.resetError()} variant="primary">
<Button onClick={() => props.resetError()} variant="primary">
Retry
</StyledButton>
</Button>
<StyledButton
<Button
onClick={() => window.location.reload()}
variant="outline"
>
Reload
</StyledButton>
</Button>
</div>
<FallbackIssue message={message!} stack={stack} />

View File

@ -1,4 +1,3 @@
import { Slot, Slottable } from "@radix-ui/react-slot"
import { stopPropagation } from "@renderer/lib/dom"
import { cn } from "@renderer/lib/utils"
import type { VariantProps } from "class-variance-authority"
@ -16,81 +15,37 @@ import {
TooltipPortal,
TooltipTrigger,
} from "../tooltip"
import { buttonVariants, styledButtonVariant } from "./variants"
import { styledButtonVariant } from "./variants"
export interface BaseButtonProps {
isLoading?: boolean
}
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants>,
BaseButtonProps {
asChild?: boolean
as?: keyof React.JSX.IntrinsicElements
}
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
(
{
className,
variant,
size,
asChild = false,
isLoading = false,
as = "button",
...props
},
ref,
) => {
const Comp = asChild ? Slot : (as as any)
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
disabled={props.disabled || isLoading}
>
{isLoading && (
<i className="i-mgc-loading-3-cute-re mr-2 animate-spin" />
)}
<Slottable>{props.children}</Slottable>
</Comp>
)
},
)
Button.displayName = "Button"
// BIZ buttons
interface ActionButtonProps {
onClick?: React.MouseEventHandler<HTMLButtonElement>
icon?: React.ReactNode | React.FC<ComponentType>
tooltip: React.ReactNode
tooltipSide?: "top" | "bottom"
active?: boolean
shortcut?: string
as?: keyof React.JSX.IntrinsicElements
asChild?: boolean
}
export const ActionButton = React.forwardRef<
HTMLButtonElement,
ComponentType<ActionButtonProps>
ComponentType<ActionButtonProps> & React.HTMLAttributes<HTMLButtonElement>
>(
(
{
icon,
onClick,
tooltip,
className,
tooltipSide,
children,
active,
shortcut,
as,
asChild,
...rest
},
ref,
) => {
@ -107,21 +62,19 @@ export const ActionButton = React.forwardRef<
)}
<Tooltip disableHoverableContent>
<TooltipTrigger asChild>
<Button
as={as}
asChild={asChild}
<button
ref={buttonRef}
// @see https://github.com/radix-ui/primitives/issues/2248#issuecomment-2147056904
onFocusCapture={stopPropagation}
className={cn(
"no-drag-region flex size-8 items-center text-xl",
"no-drag-region inline-flex size-8 items-center justify-center text-xl",
active && "bg-zinc-500/15 hover:bg-zinc-500/20",
"focus-visible:bg-zinc-500/30 focus-visible:!outline-none",
"rounded-md duration-200 hover:bg-theme-button-hover",
className,
)}
variant="ghost"
size="sm"
onClick={onClick}
type="button"
{...rest}
>
{typeof icon === "function" ?
React.createElement(icon, {
@ -130,7 +83,7 @@ export const ActionButton = React.forwardRef<
icon}
{children}
</Button>
</button>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent
@ -186,7 +139,7 @@ export const MotionButtonBase = React.forwardRef<
MotionButtonBase.displayName = "MotionButtonBase"
export const StyledButton = React.forwardRef<
export const Button = React.forwardRef<
HTMLButtonElement,
React.PropsWithChildren<
Omit<HTMLMotionProps<"button">, "children"> &

View File

@ -1,41 +1,15 @@
import { cn } from "@renderer/lib/utils"
import { cva } from "class-variance-authority"
export const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors disabled:pointer-events-none disabled:opacity-50",
{
variants: {
size: {
default: "h-10 px-4 py-2",
sm: "h-8 rounded-md px-4",
lg: "h-11 rounded-md px-8",
xl: "h-14 rounded-lg px-10",
icon: "size-10",
},
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-theme-background hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-theme-button-hover px-1.5",
link: "text-primary underline-offset-4 hover:underline",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
)
// Design
// @see https://x.com/uiuxadrian/status/1822947443186504176
export const styledButtonVariant = cva(
cn(
"inline-flex cursor-default select-none items-center justify-center gap-2 rounded-lg px-3 py-1.5 text-sm outline-offset-2 transition active:transition-none disabled:cursor-not-allowed",
"ring-theme-accent/20 duration-200 focus:border-theme-accent/80 focus:outline-none focus:ring-2 disabled:ring-0",
[
"inline-flex cursor-default select-none items-center justify-center gap-2 outline-offset-2 transition active:transition-none disabled:cursor-not-allowed",
"ring-theme-accent/20 duration-200 disabled:ring-0",
"align-middle",
),
],
{
compoundVariants: [
{
@ -56,6 +30,10 @@ export const styledButtonVariant = cva(
},
],
variants: {
size: {
default: "px-3 py-1.5 rounded-lg text-sm",
},
status: {
disabled: "cursor-not-allowed !ring-0",
},
@ -66,21 +44,29 @@ export const styledButtonVariant = cva(
"font-semibold",
"disabled:bg-theme-disabled disabled:dark:text-zinc-50",
"text-zinc-100 dark:text-zinc-200/90",
"focus:border-theme-accent/80 focus:outline-none focus:ring-2",
),
outline: cn(
"bg-theme-background font-semibold transition-colors duration-200",
"border border-border hover:bg-zinc-50/20 dark:bg-neutral-900/30",
"focus:border-theme-accent/80",
),
text: cn(
"font-semibold text-theme-accent",
"hover:contrast-[1.10] active:contrast-125",
"focus:text-theme-accent focus:outline-none",
),
ghost: cn(
"px-1.5 font-semibold",
"hover:bg-theme-button-hover",
),
},
},
defaultVariants: {
variant: "primary",
size: "default",
},
},
)

View File

@ -1,132 +0,0 @@
import { cn } from "@renderer/lib/utils"
import { Command as CommandPrimitive } from "cmdk"
import * as React from "react"
const Command = React.forwardRef<
React.ElementRef<typeof CommandPrimitive>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive>
>(({ className, ...props }, ref) => (
<CommandPrimitive
ref={ref}
className={cn(
"flex size-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
className,
)}
{...props}
/>
))
Command.displayName = CommandPrimitive.displayName
const CommandInput = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Input>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
>(({ className, ...props }, ref) => (
<div className="flex items-center border-b px-3" cmdk-input-wrapper="">
<i className="i-mingcute-search-2-line mr-2 size-4 shrink-0 opacity-50" />
<CommandPrimitive.Input
ref={ref}
className={cn(
"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
className,
)}
{...props}
/>
</div>
))
CommandInput.displayName = CommandPrimitive.Input.displayName
const CommandList = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.List>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
>(({ className, ...props }, ref) => (
<CommandPrimitive.List
ref={ref}
className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
{...props}
/>
))
CommandList.displayName = CommandPrimitive.List.displayName
const CommandEmpty = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Empty>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
>((props, ref) => (
<CommandPrimitive.Empty
ref={ref}
className="py-6 text-center text-sm"
{...props}
/>
))
CommandEmpty.displayName = CommandPrimitive.Empty.displayName
const CommandGroup = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Group>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
>(({ className, ...props }, ref) => (
<CommandPrimitive.Group
ref={ref}
className={cn(
"overflow-auto p-1 text-theme-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
className,
)}
{...props}
/>
))
CommandGroup.displayName = CommandPrimitive.Group.displayName
const CommandSeparator = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
>(({ className, ...props }, ref) => (
<CommandPrimitive.Separator
ref={ref}
className={cn("-mx-1 h-px bg-border", className)}
{...props}
/>
))
CommandSeparator.displayName = CommandPrimitive.Separator.displayName
const CommandItem = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
>(({ className, ...props }, ref) => (
<CommandPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground",
className,
)}
{...props}
/>
))
CommandItem.displayName = CommandPrimitive.Item.displayName
const CommandShortcut = ({
className,
...props
}: React.HTMLAttributes<HTMLSpanElement>) => (
<span
className={cn(
"ml-auto text-xs tracking-widest text-muted-foreground",
className,
)}
{...props}
/>
)
CommandShortcut.displayName = "CommandShortcut"
export {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
CommandShortcut,
}

View File

@ -23,7 +23,7 @@ const ContextMenuSubTrigger = React.forwardRef<
<ContextMenuPrimitive.SubTrigger
ref={ref}
className={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-theme-item-hover focus:text-accent-foreground data-[state=open]:bg-theme-item-hover data-[state=open]:text-accent-foreground",
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-theme-item-hover focus:text-theme-foreground data-[state=open]:bg-theme-item-hover data-[state=open]:text-theme-foreground",
inset && "pl-8",
"center gap-2",
className,
@ -80,7 +80,7 @@ const ContextMenuItem = React.forwardRef<
<ContextMenuPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-theme-item-hover focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-theme-item-hover focus:text-theme-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
"focus-within:outline-transparent data-[highlighted]:bg-theme-item-hover dark:data-[highlighted]:bg-neutral-800",
inset && "pl-8",
className,
@ -97,7 +97,7 @@ const ContextMenuCheckboxItem = React.forwardRef<
<ContextMenuPrimitive.CheckboxItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-theme-item-hover focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-theme-item-hover focus:text-theme-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
"focus-within:outline-transparent",
className,
)}

View File

@ -23,7 +23,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
<DropdownMenuPrimitive.SubTrigger
ref={ref}
className={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-theme-item-hover data-[state=open]:bg-theme-item-active",
inset && "pl-8",
className,
)}
@ -75,18 +75,28 @@ const DropdownMenuItem = React.forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
inset?: boolean
icon?: React.ReactNode
}
>(({ className, inset, ...props }, ref) => (
<DropdownMenuPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-theme-item-hover data-[disabled]:pointer-events-none data-[state=open]:bg-theme-item-active data-[disabled]:opacity-50",
inset && "pl-8",
"focus-within:!outline-transparent",
className,
)}
{...props}
/>
>
{props.icon && (
<span className="mr-1.5 inline-flex size-4 items-center justify-center">
{props.icon}
</span>
)}
{props.children}
{/* Justify Fill */}
{props.icon && <span className="ml-1.5 size-4" />}
</DropdownMenuPrimitive.Item>
))
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
@ -97,7 +107,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
<DropdownMenuPrimitive.CheckboxItem
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-theme-item-hover data-[disabled]:pointer-events-none data-[state=open]:bg-theme-item-active data-[disabled]:opacity-50",
className,
)}
checked={checked}

View File

@ -59,11 +59,11 @@ export const TextArea = forwardRef<
return (
<div
className={cn(
"group relative h-full border ring-0 ring-accent/20 duration-200 [--spotlight-color:oklch(var(--a)_/_0.12)]",
"group relative h-full border ring-0 ring-theme-accent/20 duration-200 [--spotlight-color:oklch(var(--a)_/_0.12)]",
roundedMap[rounded],
"border-transparent",
isFocus && "border-accent/80 ring-2",
isFocus && "border-theme-accent/80 ring-2",
"dark:text-zinc-200 dark:placeholder:text-zinc-500",
wrapperClassName,

View File

@ -119,7 +119,7 @@ const SelectItem = React.forwardRef<
<SelectPrimitive.Item
ref={ref}
className={cn(
"pointer-events-auto relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-theme-item-active focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
"pointer-events-auto relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-theme-item-active focus:text-theme-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
)}
{...props}

View File

@ -77,7 +77,7 @@ export const ProfileButton: FC<LoginProps> = memo((props) => {
return (
<DropdownMenu>
<DropdownMenuTrigger className="!outline-none focus-visible:bg-theme-item-hover">
<ActionButton as="div" tooltip="Profile">
<ActionButton tooltip="Profile">
<UserAvatar className="h-5 p-0 [&_*]:border-0" hideName />
</ActionButton>
</DropdownMenuTrigger>
@ -101,8 +101,8 @@ export const ProfileButton: FC<LoginProps> = memo((props) => {
onClick={() => {
presentUserProfile(user?.id)
}}
icon={<i className="i-mgc-user-3-cute-re" />}
>
<i className="i-mgc-user-3-cute-re mr-1.5" />
Profile
</DropdownMenuItem>
<DropdownMenuSeparator />
@ -113,21 +113,17 @@ export const ProfileButton: FC<LoginProps> = memo((props) => {
// and the page freezes after modal is turned off.
nextFrame(() => settingModalPresent("wallet"))
}}
icon={<i className="i-mgc-power-outline" />}
>
<i className="i-mgc-power-outline mr-1.5" />
Power
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
nextFrame(settingModalPresent)
}}
icon={<i className="i-mgc-settings-7-cute-re" />}
>
<i className="i-mgc-settings-7-cute-re mr-1.5" />
Preferences
{/* <div className="ml-auto flex gap-1">
<Kbd>Meta</Kbd>
<Kbd>,</Kbd>
</div> */}
</DropdownMenuItem>
<DropdownMenuSeparator />
{!window.electron && (
@ -136,15 +132,17 @@ export const ProfileButton: FC<LoginProps> = memo((props) => {
onClick={() => {
window.open(`${repository.url}/releases`)
}}
icon={<i className="i-mgc-download-2-cute-re" />}
>
<i className="i-mgc-download-2-cute-re mr-1.5" />
Download Desktop app
</DropdownMenuItem>
<DropdownMenuSeparator />
</>
)}
<DropdownMenuItem onClick={signOut}>
<i className="i-mgc-exit-cute-re mr-1.5" />
<DropdownMenuItem
onClick={signOut}
icon={<i className="i-mgc-exit-cute-re" />}
>
Log out
</DropdownMenuItem>
</DropdownMenuContent>

View File

@ -35,8 +35,7 @@ export const LoginModalContent = (props: LoginModalContentProps) => {
</div>
<div className="flex flex-col gap-4">
<Button
className="h-[48px] w-[320px] rounded-[8px] !bg-black font-sans text-base text-white hover:!bg-black/80"
size="lg"
className="h-[48px] w-[320px] rounded-[8px] !bg-black font-sans text-base text-white hover:!bg-black/80 focus:!border-black/80 focus:!ring-black/80"
onClick={() => {
loginHandler("github", runtime)
}}
@ -47,8 +46,7 @@ export const LoginModalContent = (props: LoginModalContentProps) => {
GitHub
</Button>
<Button
className="h-[48px] w-[320px] rounded-[8px] bg-blue-500 font-sans text-base text-white hover:bg-blue-500/90"
size="xl"
className="h-[48px] w-[320px] rounded-[8px] bg-blue-500 font-sans text-base text-white hover:bg-blue-500/90 focus:!border-blue-500/80 focus:!ring-blue-500/80"
onClick={() => {
loginHandler("google", runtime)
}}

View File

@ -1,6 +1,6 @@
import { FollowSummary } from "@renderer/components/feed-summary"
import { AutoResizeHeight } from "@renderer/components/ui/auto-resize-height"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { Card, CardHeader } from "@renderer/components/ui/card"
import {
CopyButton,
@ -141,7 +141,7 @@ export const FeedClaimModalContent: FC<{
</Tabs>
<div className="mt-3 flex justify-end">
<StyledButton
<Button
disabled={isSuccess}
isLoading={isPending}
onClick={() => claim()}
@ -151,7 +151,7 @@ export const FeedClaimModalContent: FC<{
<i className="i-mgc-check-circle-filled mr-2 bg-green-500" />
)}
Claim
</StyledButton>
</Button>
</div>
</div>
)

View File

@ -1,6 +1,6 @@
import { zodResolver } from "@hookform/resolvers/zod"
import { getSidebarActiveView } from "@renderer/atoms/sidebar"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { CopyButton } from "@renderer/components/ui/code-highlighter"
import { Form, FormItem, FormLabel } from "@renderer/components/ui/form"
import { Input } from "@renderer/components/ui/input"
@ -275,7 +275,7 @@ export const DiscoverFeedForm = ({
submitButtonClassName,
)}
>
<StyledButton type="submit">Preview</StyledButton>
<Button type="submit">Preview</Button>
</div>
</form>
</Form>

View File

@ -2,7 +2,7 @@ import { zodResolver } from "@hookform/resolvers/zod"
import { FollowSummary } from "@renderer/components/feed-summary"
import { Logo } from "@renderer/components/icons/logo"
import { Autocomplete } from "@renderer/components/ui/auto-completion"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { Card, CardHeader } from "@renderer/components/ui/card"
import {
Form,
@ -324,7 +324,7 @@ const FeedInnerForm = ({
<div className="flex flex-1 items-end justify-end gap-4">
{isSubscribed && (
<StyledButton
<Button
ref={buttonRef}
variant="text"
isLoading={deleteSubscription.isPending}
@ -337,15 +337,15 @@ const FeedInnerForm = ({
}}
>
Unfollow
</StyledButton>
</Button>
)}
<StyledButton
<Button
ref={buttonRef}
type="submit"
isLoading={followMutation.isPending}
>
{isSubscribed ? "Update" : "Follow"}
</StyledButton>
</Button>
</div>
</form>
</Form>

View File

@ -1,6 +1,6 @@
import { zodResolver } from "@hookform/resolvers/zod"
import { getSidebarActiveView } from "@renderer/atoms/sidebar"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import {
Card,
CardContent,
@ -131,13 +131,13 @@ export function DiscoverForm({ type }: { type: string }) {
)}
/>
<div className="center flex">
<StyledButton
<Button
disabled={!form.formState.isValid}
type="submit"
isLoading={mutation.isPending}
>
{info[type].showModal ? "Preview" : "Search"}
</StyledButton>
</Button>
</div>
</form>
</Form>
@ -164,7 +164,7 @@ export function DiscoverForm({ type }: { type: string }) {
{item.docs ? (
<CardFooter>
<a href={item.docs} target="_blank" rel="noreferrer">
<StyledButton>View Docs</StyledButton>
<Button>View Docs</Button>
</a>
</CardFooter>
) : (
@ -207,11 +207,11 @@ export function DiscoverForm({ type }: { type: string }) {
</CardContent>
<CardFooter>
{item.isSubscribed ? (
<StyledButton variant="outline" disabled>
<Button variant="outline" disabled>
Followed
</StyledButton>
</Button>
) : (
<StyledButton
<Button
onClick={() => {
present({
title: "Add Feed",
@ -230,7 +230,7 @@ export function DiscoverForm({ type }: { type: string }) {
}}
>
Follow
</StyledButton>
</Button>
)}
<div className="ml-6 text-zinc-500">
<span className="font-medium text-zinc-800 dark:text-zinc-200">

View File

@ -1,5 +1,5 @@
import { zodResolver } from "@hookform/resolvers/zod"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { Card, CardContent, CardHeader } from "@renderer/components/ui/card"
import {
Form,
@ -139,13 +139,13 @@ export function DiscoverImport() {
)}
/>
<div className="center flex">
<StyledButton
<Button
type="submit"
disabled={!form.formState.dirtyFields.file}
isLoading={mutation.isPending}
>
Import
</StyledButton>
</Button>
</div>
</form>
</Form>

View File

@ -2,7 +2,6 @@ import { PopoverPortal } from "@radix-ui/react-popover"
import {
ActionButton,
Button,
StyledButton,
} from "@renderer/components/ui/button"
import {
Popover,
@ -68,17 +67,17 @@ export const MarkAllReadButton = forwardRef<
</div>
<div className="space-x-4">
<PopoverClose>
<StyledButton variant="outline">Cancel</StyledButton>
<Button variant="outline">Cancel</Button>
</PopoverClose>
<StyledButton
<Button
onClick={() => {
handleMarkAllAsRead()
setMarkPopoverOpen(false)
}}
>
Confirm
</StyledButton>
</Button>
</div>
</PopoverContent>
</PopoverPortal>
@ -102,7 +101,7 @@ export const FlatMarkAllReadButton: FC<MarkAllButtonProps> = (props) => {
return (
<Button
variant="ghost"
className={cn("center relative flex h-auto gap-1 !py-1.5", className)}
className={cn("center relative flex h-auto gap-1", className)}
onMouseLeave={() => {
if (status === "confirm") {
setStatus("initial")

View File

@ -1,7 +1,7 @@
import { subscriptionActions } from "@renderer/store/subscription"
import { useMutation } from "@tanstack/react-query"
import { StyledButton } from "../../components/ui/button"
import { Button } from "../../components/ui/button"
import { useCurrentModal } from "../../components/ui/modal"
export function CategoryRemoveDialogContent({
@ -23,15 +23,15 @@ export function CategoryRemoveDialogContent({
</p>
<div className="flex items-center justify-end gap-3">
<StyledButton variant="outline" onClick={dismiss}>
<Button variant="outline" onClick={dismiss}>
Cancel
</StyledButton>
<StyledButton
</Button>
<Button
isLoading={deleteMutation.isPending}
onClick={() => deleteMutation.mutateAsync().then(() => dismiss())}
>
Continue
</StyledButton>
</Button>
</div>
</div>
)

View File

@ -1,5 +1,5 @@
import { zodResolver } from "@hookform/resolvers/zod"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import {
Form,
FormControl,
@ -78,9 +78,9 @@ export function CategoryRenameContent({
)}
/>
<div className="flex justify-end">
<StyledButton type="submit" isLoading={renameMutation.isPending}>
<Button type="submit" isLoading={renameMutation.isPending}>
Rename
</StyledButton>
</Button>
</div>
</form>
</Form>

View File

@ -7,7 +7,7 @@ import {
AvatarFallback,
AvatarImage,
} from "@renderer/components/ui/avatar"
import { ActionButton, StyledButton } from "@renderer/components/ui/button"
import { ActionButton, Button } from "@renderer/components/ui/button"
import { LoadingCircle } from "@renderer/components/ui/loading"
import { useCurrentModal, useModalStack } from "@renderer/components/ui/modal"
import { ScrollArea } from "@renderer/components/ui/scroll-area"
@ -328,7 +328,7 @@ const SubscriptionItem: FC<{
)}
</div>
<div className="absolute right-0 opacity-0 transition-opacity group-hover:opacity-100">
<StyledButton
<Button
onClick={(e) => {
e.stopPropagation()
e.preventDefault()
@ -361,7 +361,7 @@ const SubscriptionItem: FC<{
{APP_NAME}
</>
)}
</StyledButton>
</Button>
</div>
</a>
</div>

View File

@ -193,7 +193,6 @@ const DeleteTableCell = ({
<Button
variant="ghost"
className="w-full px-0"
size="sm"
disabled={disabled}
onClick={onClick}
>
@ -205,8 +204,8 @@ const DeleteTableCell = ({
const AddTableRow = ({ onClick }: { onClick?: () => void }) => (
<Button
variant="outline"
size="sm"
className="mt-1 w-full gap-1"
buttonClassName="py-1"
onClick={onClick}
>
<i className="i-mgc-add-cute-re" />
@ -297,8 +296,6 @@ export function ActionCard({
<div className="flex w-full items-center gap-2 pr-2">
<Button
variant="ghost"
size="sm"
className="ml-2"
onClick={() => {
onChange(null)
}}

View File

@ -1,4 +1,4 @@
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { Checkbox } from "@renderer/components/ui/checkbox"
import { Label } from "@renderer/components/ui/label"
import { Switch } from "@renderer/components/ui/switch"
@ -67,6 +67,6 @@ export const SettingActionItem = ({
}) => (
<div className={cn("relative mb-3 mt-4 flex items-center justify-between gap-4")}>
<div className="text-sm font-medium">{label}</div>
<StyledButton buttonClassName="text-xs absolute right-0" onClick={action}>{buttonText}</StyledButton>
<Button buttonClassName="text-xs absolute right-0" onClick={action}>{buttonText}</Button>
</div>
)

View File

@ -3,7 +3,7 @@ import {
setUISetting,
useUISettingSelector,
} from "@renderer/atoms/settings/ui"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { Input } from "@renderer/components/ui/input"
import { useModalStack } from "@renderer/components/ui/modal"
import {
@ -179,9 +179,9 @@ const usePresentCustomFontDialog = (
/>
<div className="flex justify-end">
<StyledButton type="submit">
<Button type="submit">
Save
</StyledButton>
</Button>
</div>
</form>

View File

@ -1,6 +1,7 @@
import { license, repository } from "@pkg"
import { Logo } from "@renderer/components/icons/logo"
import { Button, StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { styledButtonVariant } from "@renderer/components/ui/button/variants"
import { Divider } from "@renderer/components/ui/divider"
import { SocialMediaLinks } from "@renderer/constants/social"
import { getNewIssueUrl } from "@renderer/lib/issues"
@ -28,22 +29,22 @@ export const SettingAbout = () => (
</div>
<div className="shrink-0">
<StyledButton
<Button
variant="outline"
onClick={() => {
window.open(`${repository.url}/releases`, "_blank")
}}
>
Changelog
</StyledButton>
</Button>
</div>
</div>
<p className="mt-6 text-balance text-sm">
{APP_NAME}
{" "}
is and will always be a free and open-source project. It is licensed under
{" "}
is and will always be a free and open-source project. It is
licensed under
{license}
.
</p>
@ -60,7 +61,8 @@ export const SettingAbout = () => (
</a>
<i className="i-mgc-external-link-cute-re translate-y-px" />
{" "}
and cannot be redistributed.
and cannot
be redistributed.
</p>
<p className="mt-3 text-sm">
@ -68,8 +70,9 @@ export const SettingAbout = () => (
{" "}
(
{GIT_COMMIT_SHA.slice(0, 7).toUpperCase()}
) is in the early stages of development. If you have any feedback or suggestions, please feel
free to
) is in the early
stages of development. If you have any feedback or suggestions, please
feel free to
{" "}
<a
className="inline-flex cursor-pointer items-center gap-1 hover:underline"
@ -91,18 +94,18 @@ export const SettingAbout = () => (
</h2>
<div className="mt-2 flex flex-wrap gap-2">
{SocialMediaLinks.map((link) => (
<Button
asChild
<span
key={link.url}
variant="outline"
className="flex flex-1 cursor-pointer items-center gap-2"
className={styledButtonVariant({
variant: "outline",
className: "flex-1",
})}
>
<a href={link.url} target="_blank" rel="noreferrer">
<a href={link.url} className="center flex w-full gap-1" target="_blank" rel="noreferrer">
<i className={link.icon} />
{link.label}
</a>
</Button>
</span>
))}
</div>
</section>

View File

@ -1,5 +1,5 @@
import { TooltipTrigger } from "@radix-ui/react-tooltip"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { Tooltip, TooltipContent } from "@renderer/components/ui/tooltip"
import {
useClaimWalletDailyRewardMutation,
@ -42,7 +42,7 @@ export const ClaimDailyReward = () => {
return (
<Tooltip>
<TooltipTrigger>
<StyledButton
<Button
variant="primary"
isLoading={mutation.isPending}
onClick={() => mutation.mutate()}
@ -51,7 +51,7 @@ export const ClaimDailyReward = () => {
{canClaim ?
"Mint Daily Power" :
`Mint in ${hour}:${minute}`}
</StyledButton>
</Button>
</TooltipTrigger>
<TooltipContent>
{canClaim ?

View File

@ -1,4 +1,4 @@
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { useCreateWalletMutation } from "@renderer/queries/wallet"
export const CreateWallet = () => {
@ -17,13 +17,13 @@ export const CreateWallet = () => {
reward creators and also get rewarded for your content contributions.
</p>
<div className="mt-4 text-right">
<StyledButton
<Button
variant="primary"
isLoading={mutation.isPending}
onClick={() => mutation.mutate()}
>
Create Wallet
</StyledButton>
</Button>
</div>
</div>
)

View File

@ -1,5 +1,5 @@
import { useWhoami } from "@renderer/atoms/user"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { Divider } from "@renderer/components/ui/divider"
import { LoadingCircle } from "@renderer/components/ui/loading"
import { useCurrentModal } from "@renderer/components/ui/modal"
@ -64,12 +64,12 @@ export const TipModalContent: FC<{
You don't have a wallet yet. Please create a wallet to tip.
</p>
<div className="flex justify-end">
<StyledButton
<Button
variant="primary"
onClick={() => nextFrame(() => settingModalPresent("wallet"))}
>
Create For Free
</StyledButton>
</Button>
</div>
</div>
)
@ -92,12 +92,12 @@ export const TipModalContent: FC<{
</p>
<div className="flex justify-end">
<StyledButton
<Button
variant="primary"
onClick={() => dismiss()}
>
OK
</StyledButton>
</Button>
</div>
</div>
)
@ -116,7 +116,7 @@ export const TipModalContent: FC<{
<span className="text-xs text-theme-foreground/80">No one has claimed this feed yet. The received Power will be securely held in the blockchain contract until it is claimed.</span>
</p>
<div className="text-center">
<StyledButton variant="text" className="w-fit p-0" onClick={() => claimFeed()}>Claim this feed</StyledButton>
<Button variant="text" className="w-fit p-0" onClick={() => claimFeed()}>Claim this feed</Button>
</div>
</>
)}
@ -157,7 +157,7 @@ export const TipModalContent: FC<{
</div>
<div className="flex justify-end">
<StyledButton
<Button
disabled={tipMutation.isSuccess || tipMutation.isPending || wrongNumberRange}
isLoading={tipMutation.isPending}
onClick={() => {
@ -174,7 +174,7 @@ export const TipModalContent: FC<{
<i className="i-mgc-check-circle-filled mr-2 bg-green-500" />
)}
Tip Now
</StyledButton>
</Button>
</div>
</div>
)

View File

@ -1,6 +1,6 @@
import { FeedIcon } from "@renderer/components/feed-icon"
import { FollowIcon } from "@renderer/components/icons/follow"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { ListItemHoverOverlay } from "@renderer/components/ui/list-item-hover-overlay"
import { LoadingCircle } from "@renderer/components/ui/loading"
import { views } from "@renderer/constants"
@ -97,10 +97,10 @@ export function Component() {
{APP_NAME}
</div>
<a className="mb-8 cursor-default" href={`${DEEPLINK_SCHEME}add?id=${id}`}>
<StyledButton>
<Button>
<FollowIcon className="mr-1 size-3" />
{APP_NAME}
</StyledButton>
</Button>
</a>
<div
className={cn(

View File

@ -5,7 +5,7 @@ import {
AvatarFallback,
AvatarImage,
} from "@renderer/components/ui/avatar"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { LoadingCircle } from "@renderer/components/ui/loading"
import { useAuthQuery, useTitle } from "@renderer/hooks/common"
import { apiClient } from "@renderer/lib/api-fetch"
@ -100,10 +100,10 @@ export function Component() {
href={`${DEEPLINK_SCHEME}add?id=${subscription.feeds?.id}`}
onClick={stopPropagation}
>
<StyledButton>
<Button>
<FollowIcon className="mr-1 size-3" />
{APP_NAME}
</StyledButton>
</Button>
</a>
</a>
</div>

View File

@ -1,6 +1,6 @@
import { zodResolver } from "@hookform/resolvers/zod"
import { Logo } from "@renderer/components/icons/logo"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import {
Form,
FormControl,
@ -67,13 +67,13 @@ export function Component() {
)}
/>
<div className="center flex">
<StyledButton
<Button
type="submit"
disabled={!form.formState.isValid}
isLoading={invitationMutation.isPending}
>
Activate
</StyledButton>
</Button>
</div>
</form>
</Form>

View File

@ -49,8 +49,7 @@ function Login() {
) : (
<div className="flex flex-col gap-3">
<Button
className="!bg-black text-lg text-white"
size="xl"
className="h-[48px] w-[320px] rounded-[8px] !bg-black font-sans text-base text-white hover:!bg-black/80 focus:!border-black/80 focus:!ring-black/80"
onClick={() => {
loginHandler("github")
}}
@ -61,8 +60,7 @@ function Login() {
GitHub
</Button>
<Button
className="bg-blue-500 text-lg text-white hover:bg-blue-500/90"
size="xl"
className="h-[48px] w-[320px] rounded-[8px] bg-blue-500 font-sans text-base text-white hover:bg-blue-500/90 focus:!border-blue-500/80 focus:!ring-blue-500/80"
onClick={() => {
loginHandler("google")
}}

View File

@ -1,5 +1,5 @@
import { PoweredByFooter } from "@renderer/components/common/PoweredByFooter"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { UserAvatar } from "@renderer/components/user-button"
import { apiClient } from "@renderer/lib/api-fetch"
import { DEEPLINK_SCHEME } from "@shared/constants"
@ -46,22 +46,22 @@ export function Component() {
and safely close this page.
</h2>
<div className="center flex flex-col gap-4 sm:flex-row">
<StyledButton
<Button
variant="text"
className="h-14 px-10 text-base"
onClick={() => navigate("/")}
>
Continue in Browser
</StyledButton>
</Button>
<StyledButton
<Button
className="h-14 !rounded-full px-5 text-lg"
onClick={async () => window.open(await getCallbackUrl(), "_top")}
>
Open
{" "}
{APP_NAME}
</StyledButton>
</Button>
</div>
<div className="grow" />
<PoweredByFooter />

View File

@ -97,6 +97,7 @@ export function Component() {
<SearchCmdK />
<CmdNTrigger />
{ELECTRON && <CmdF />}
{isAuthFail && !user && (
<RootPortal>
<DeclarativeModal

View File

@ -1,4 +1,4 @@
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import { useAuthQuery } from "@renderer/hooks/common"
import { apiClient, getFetchErrorMessage } from "@renderer/lib/api-fetch"
import type { ActionsResponse } from "@renderer/models"
@ -114,7 +114,7 @@ export function Component() {
}}
/>
))}
<StyledButton
<Button
variant="outline"
className="center w-full gap-1"
onClick={() => {
@ -130,15 +130,15 @@ export function Component() {
>
<i className="i-mgc-add-cute-re" />
<span> New Rule</span>
</StyledButton>
</Button>
<div className="text-right">
<StyledButton
<Button
variant="primary"
isLoading={mutation.isPending}
onClick={() => mutation.mutate()}
>
Save
</StyledButton>
</Button>
</div>
</div>
</>

View File

@ -1,6 +1,6 @@
import { zodResolver } from "@hookform/resolvers/zod"
import { useWhoami } from "@renderer/atoms/user"
import { StyledButton } from "@renderer/components/ui/button"
import { Button } from "@renderer/components/ui/button"
import {
Form,
FormControl,
@ -109,7 +109,7 @@ export function Component() {
)}
/>
<div className="text-right">
<StyledButton type="submit">Submit</StyledButton>
<Button type="submit">Submit</Button>
</div>
</form>
</Form>