diff --git a/.vscode/settings.json b/.vscode/settings.json
index 2c49d5ade..39bca79df 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -12,6 +12,7 @@
// ["tw\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
["tw`([^`]*)`", "([^`]*)"]
+
],
// If you do not want to autofix some rules on save
diff --git a/src/renderer/src/components/common/ErrorElement.tsx b/src/renderer/src/components/common/ErrorElement.tsx
index 1c9eda009..cbda58ace 100644
--- a/src/renderer/src/components/common/ErrorElement.tsx
+++ b/src/renderer/src/components/common/ErrorElement.tsx
@@ -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() {
- {
clearLocalPersistStoreData()
@@ -76,10 +76,10 @@ export function ErrorElement() {
}}
>
Reset Local Database
-
- (window.location.href = "/")}>
+
+
+
diff --git a/src/renderer/src/components/common/NotFound.tsx b/src/renderer/src/components/common/NotFound.tsx
index f436b4f52..0802d1139 100644
--- a/src/renderer/src/components/common/NotFound.tsx
+++ b/src/renderer/src/components/common/NotFound.tsx
@@ -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 = () => {
- navigate("/")}>
+
+
diff --git a/src/renderer/src/components/errors/FeedFoundCanBeFollowErrorFallback.tsx b/src/renderer/src/components/errors/FeedFoundCanBeFollowErrorFallback.tsx
index e8a328cce..9f10fec3e 100644
--- a/src/renderer/src/components/errors/FeedFoundCanBeFollowErrorFallback.tsx
+++ b/src/renderer/src/components/errors/FeedFoundCanBeFollowErrorFallback.tsx
@@ -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 = ({
homepage.
-
{
navigate("/")
@@ -50,9 +50,9 @@ export const FeedFoundCanBeFollowErrorFallback: FC = ({
}}
>
Back
-
+
-
{
present({
title: "Add Feed",
@@ -83,7 +83,7 @@ export const FeedFoundCanBeFollowErrorFallback: FC = ({
variant="primary"
>
Follow
-
+
diff --git a/src/renderer/src/components/errors/FeedNotFound.tsx b/src/renderer/src/components/errors/FeedNotFound.tsx
index 522cd7cf3..1d96cbc18 100644
--- a/src/renderer/src/components/errors/FeedNotFound.tsx
+++ b/src/renderer/src/components/errors/FeedNotFound.tsx
@@ -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 = ({
@@ -27,7 +27,7 @@ export const FeedNotFoundErrorFallback: FC = ({
-
{
navigate("/")
@@ -37,7 +37,7 @@ export const FeedNotFoundErrorFallback: FC = ({
}}
>
Back
-
+
diff --git a/src/renderer/src/components/errors/ModalError.tsx b/src/renderer/src/components/errors/ModalError.tsx
index f1b7c5c0c..2aa44d38e 100644
--- a/src/renderer/src/components/errors/ModalError.tsx
+++ b/src/renderer/src/components/errors/ModalError.tsx
@@ -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 = (props) => {
- modal.dismiss()} variant="outline">
+
-
+
+
diff --git a/src/renderer/src/components/errors/PageError.tsx b/src/renderer/src/components/errors/PageError.tsx
index d0f55da0e..e749845d6 100644
--- a/src/renderer/src/components/errors/PageError.tsx
+++ b/src/renderer/src/components/errors/PageError.tsx
@@ -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 = (props) => {
@@ -28,16 +28,16 @@ export const PageErrorFallback: FC = (props) => {
- props.resetError()} variant="primary">
+
+
- window.location.reload()}
variant="outline"
>
Reload
-
+
diff --git a/src/renderer/src/components/ui/button/index.tsx b/src/renderer/src/components/ui/button/index.tsx
index 50f1639ee..34143cab6 100644
--- a/src/renderer/src/components/ui/button/index.tsx
+++ b/src/renderer/src/components/ui/button/index.tsx
@@ -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,
- VariantProps,
- BaseButtonProps {
- asChild?: boolean
-
- as?: keyof React.JSX.IntrinsicElements
-}
-
-export const Button = React.forwardRef(
- (
- {
- className,
- variant,
- size,
- asChild = false,
- isLoading = false,
- as = "button",
- ...props
- },
- ref,
- ) => {
- const Comp = asChild ? Slot : (as as any)
-
- return (
-
- {isLoading && (
-
- )}
- {props.children}
-
- )
- },
-)
-Button.displayName = "Button"
// BIZ buttons
interface ActionButtonProps {
- onClick?: React.MouseEventHandler
icon?: React.ReactNode | React.FC
tooltip: React.ReactNode
tooltipSide?: "top" | "bottom"
active?: boolean
shortcut?: string
- as?: keyof React.JSX.IntrinsicElements
- asChild?: boolean
}
export const ActionButton = React.forwardRef<
HTMLButtonElement,
- ComponentType
+ ComponentType & React.HTMLAttributes
>(
(
{
icon,
- onClick,
+
tooltip,
className,
tooltipSide,
children,
active,
shortcut,
- as,
- asChild,
+ ...rest
},
ref,
) => {
@@ -107,21 +62,19 @@ export const ActionButton = React.forwardRef<
)}
-
+
, "children"> &
diff --git a/src/renderer/src/components/ui/button/variants.tsx b/src/renderer/src/components/ui/button/variants.tsx
index 42811a0bd..d1f5a94a8 100644
--- a/src/renderer/src/components/ui/button/variants.tsx
+++ b/src/renderer/src/components/ui/button/variants.tsx
@@ -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",
},
},
)
diff --git a/src/renderer/src/components/ui/command.tsx b/src/renderer/src/components/ui/command.tsx
deleted file mode 100644
index be8287c6d..000000000
--- a/src/renderer/src/components/ui/command.tsx
+++ /dev/null
@@ -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,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-Command.displayName = CommandPrimitive.displayName
-
-const CommandInput = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-
-
-
-))
-
-CommandInput.displayName = CommandPrimitive.Input.displayName
-
-const CommandList = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-
-CommandList.displayName = CommandPrimitive.List.displayName
-
-const CommandEmpty = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->((props, ref) => (
-
-))
-
-CommandEmpty.displayName = CommandPrimitive.Empty.displayName
-
-const CommandGroup = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-
-CommandGroup.displayName = CommandPrimitive.Group.displayName
-
-const CommandSeparator = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-CommandSeparator.displayName = CommandPrimitive.Separator.displayName
-
-const CommandItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-
-CommandItem.displayName = CommandPrimitive.Item.displayName
-
-const CommandShortcut = ({
- className,
- ...props
-}: React.HTMLAttributes) => (
-
-)
-CommandShortcut.displayName = "CommandShortcut"
-
-export {
- Command,
- CommandEmpty,
- CommandGroup,
- CommandInput,
- CommandItem,
- CommandList,
- CommandSeparator,
- CommandShortcut,
-}
diff --git a/src/renderer/src/components/ui/context-menu/context-menu.tsx b/src/renderer/src/components/ui/context-menu/context-menu.tsx
index 01887b42a..1a7f5a204 100644
--- a/src/renderer/src/components/ui/context-menu/context-menu.tsx
+++ b/src/renderer/src/components/ui/context-menu/context-menu.tsx
@@ -23,7 +23,7 @@ const ContextMenuSubTrigger = React.forwardRef<
,
React.ComponentPropsWithoutRef & {
inset?: boolean
+ icon?: React.ReactNode
}
>(({ className, inset, ...props }, ref) => (
+ >
+ {props.icon && (
+
+ {props.icon}
+
+ )}
+ {props.children}
+ {/* Justify Fill */}
+ {props.icon && }
+
))
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
@@ -97,7 +107,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
= memo((props) => {
return (
-
+
@@ -101,8 +101,8 @@ export const ProfileButton: FC = memo((props) => {
onClick={() => {
presentUserProfile(user?.id)
}}
+ icon={}
>
-
Profile
@@ -113,21 +113,17 @@ export const ProfileButton: FC = memo((props) => {
// and the page freezes after modal is turned off.
nextFrame(() => settingModalPresent("wallet"))
}}
+ icon={}
>
-
Power
{
nextFrame(settingModalPresent)
}}
+ icon={}
>
-
Preferences
- {/*
- Meta
- ,
-
*/}
{!window.electron && (
@@ -136,15 +132,17 @@ export const ProfileButton: FC = memo((props) => {
onClick={() => {
window.open(`${repository.url}/releases`)
}}
+ icon={}
>
-
Download Desktop app
>
)}
-
-
+ }
+ >
Log out
diff --git a/src/renderer/src/modules/auth/LoginModalContent.tsx b/src/renderer/src/modules/auth/LoginModalContent.tsx
index 9fa819e80..752c77ac2 100644
--- a/src/renderer/src/modules/auth/LoginModalContent.tsx
+++ b/src/renderer/src/modules/auth/LoginModalContent.tsx
@@ -35,8 +35,7 @@ export const LoginModalContent = (props: LoginModalContentProps) => {
)
diff --git a/src/renderer/src/modules/discover/DiscoverFeedForm.tsx b/src/renderer/src/modules/discover/DiscoverFeedForm.tsx
index a9aa4caa1..a4638a8bc 100644
--- a/src/renderer/src/modules/discover/DiscoverFeedForm.tsx
+++ b/src/renderer/src/modules/discover/DiscoverFeedForm.tsx
@@ -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,
)}
>
- Preview
+
diff --git a/src/renderer/src/modules/discover/feed-form.tsx b/src/renderer/src/modules/discover/feed-form.tsx
index aaaff1e48..1623eba47 100644
--- a/src/renderer/src/modules/discover/feed-form.tsx
+++ b/src/renderer/src/modules/discover/feed-form.tsx
@@ -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 = ({
{isSubscribed && (
-
Unfollow
-
+
)}
-
{isSubscribed ? "Update" : "Follow"}
-
+
diff --git a/src/renderer/src/modules/discover/form.tsx b/src/renderer/src/modules/discover/form.tsx
index a8b38cdd9..b5f5ae3d1 100644
--- a/src/renderer/src/modules/discover/form.tsx
+++ b/src/renderer/src/modules/discover/form.tsx
@@ -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 }) {
)}
/>
-
{info[type].showModal ? "Preview" : "Search"}
-
+
@@ -164,7 +164,7 @@ export function DiscoverForm({ type }: { type: string }) {
{item.docs ? (
- View Docs
+
) : (
@@ -207,11 +207,11 @@ export function DiscoverForm({ type }: { type: string }) {
{item.isSubscribed ? (
-
+
+
) : (
- {
present({
title: "Add Feed",
@@ -230,7 +230,7 @@ export function DiscoverForm({ type }: { type: string }) {
}}
>
Follow
-
+
)}
diff --git a/src/renderer/src/modules/discover/import.tsx b/src/renderer/src/modules/discover/import.tsx
index 71f2e3170..cadd30162 100644
--- a/src/renderer/src/modules/discover/import.tsx
+++ b/src/renderer/src/modules/discover/import.tsx
@@ -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() {
)}
/>
-
Import
-
+
diff --git a/src/renderer/src/modules/entry-column/components/mark-all-button.tsx b/src/renderer/src/modules/entry-column/components/mark-all-button.tsx
index b6104d8b7..45cb30108 100644
--- a/src/renderer/src/modules/entry-column/components/mark-all-button.tsx
+++ b/src/renderer/src/modules/entry-column/components/mark-all-button.tsx
@@ -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<
- Cancel
+
-
{
handleMarkAllAsRead()
setMarkPopoverOpen(false)
}}
>
Confirm
-
+
@@ -102,7 +101,7 @@ export const FlatMarkAllReadButton: FC = (props) => {
return (