Initial react-zen migration.
Some checks failed
Node.js CI / build (push) Has been cancelled

This commit is contained in:
Mike Cao 2026-01-19 21:09:22 -08:00
parent 30c45f888f
commit 3b4776b0e0
6 changed files with 2055 additions and 16 deletions

View file

@ -72,7 +72,7 @@
"@react-spring/web": "^10.0.3",
"@svgr/cli": "^8.1.0",
"@tanstack/react-query": "^5.90.17",
"@umami/react-zen": "^0.229.0",
"@umami/react-zen": "^0.231.0",
"@umami/redis-client": "^0.30.0",
"bcryptjs": "^3.0.2",
"chalk": "^5.6.2",

1927
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
import { Icon, Row, Text } from '@umami/react-zen';
import { IconLabel, Row } from '@umami/react-zen';
import { WebsiteShareForm } from '@/app/(main)/websites/[websiteId]/settings/WebsiteShareForm';
import { Favicon } from '@/components/common/Favicon';
import { LinkButton } from '@/components/common/LinkButton';
@ -30,12 +30,9 @@ export function WebsiteHeader({ showActions }: { showActions?: boolean }) {
{showActions && (
<Row alignItems="center" gap>
<ShareButton websiteId={website.id} shareId={website.shareId} />
<ShareButton websiteId={website?.id} shareId={website?.shareId} />
<LinkButton href={renderUrl(`/websites/${website.id}/settings`, false)}>
<Icon>
<Edit />
</Icon>
<Text>{formatMessage(labels.edit)}</Text>
<IconLabel icon={<Edit />}>{formatMessage(labels.edit)}</IconLabel>
</LinkButton>
</Row>
)}

View file

@ -1,3 +1,8 @@
:root {
--font-family: var(--font-inter), sans-serif;
--text-primary: oklch(68.5% 0.169 237.323);
}
html,
body {
font-family: var(--font-family), sans-serif;

View file

@ -23,7 +23,7 @@ export function PageHeader({
}) {
return (
<Grid
columns={{ xs: '1fr', md: '1fr 1fr' }}
columns={{ base: '1fr', md: '1fr 1fr' }}
paddingY="6"
marginBottom="6"
border={showBorder ? 'bottom' : undefined}
@ -38,10 +38,10 @@ export function PageHeader({
)}
{title && titleHref ? (
<LinkButton href={titleHref} variant="quiet">
<Heading size={{ xs: '2', md: '3', lg: '4' }}>{title}</Heading>
<Heading size={{ base: 'lg', md: '2xl', lg: '3xl' }}>{title}</Heading>
</LinkButton>
) : (
title && <Heading size={{ xs: '2', md: '3', lg: '4' }}>{title}</Heading>
title && <Heading size={{ base: 'lg', md: '2xl', lg: '3xl' }}>{title}</Heading>
)}
</Row>
{description && (

View file

@ -0,0 +1,122 @@
import {
Box,
Column,
type ColumnProps,
Focusable,
Icon,
Row,
type RowProps,
Text,
Tooltip,
TooltipTrigger,
} from '@umami/react-zen';
import classNames from 'classnames';
import { createContext, type ReactNode, useContext } from 'react';
export interface SidebarProps extends ColumnProps {
isCollapsed?: boolean;
muteItems?: boolean;
children?: ReactNode;
}
const SidebarContext = createContext(null as any);
export function Sidebar({ isCollapsed, muteItems, className, children, ...props }: SidebarProps) {
return (
<SidebarContext.Provider value={{ isCollapsed }}>
<Column
{...props}
border="right"
width={isCollapsed ? '64px' : '240px'}
backgroundColor="surface-base"
>
{children}
</Column>
</SidebarContext.Provider>
);
}
export function SidebarSection({
title,
className,
children,
...props
}: { title?: string; children: ReactNode } & ColumnProps) {
return (
<Column {...props} paddingY="2" className={className}>
{title && (
<Box paddingX="4" paddingY="2">
<Text size="xs" weight="semibold" transform="uppercase" color="muted">
{title}
</Text>
</Box>
)}
<Column>{children}</Column>
</Column>
);
}
export function SidebarHeader({
label,
icon,
className,
children,
...props
}: {
label: string;
icon?: ReactNode;
children?: ReactNode;
} & RowProps) {
return (
<Row {...props} paddingX="4" paddingY="3" gap="3" alignItems="center" className={className}>
{icon && <Icon size="sm">{icon}</Icon>}
{label && <Text weight="semibold">{label}</Text>}
{children}
</Row>
);
}
export interface SidebarItemProps extends RowProps {
isSelected?: boolean;
}
export function SidebarItem({
label,
icon,
isSelected,
className,
children,
...props
}: {
label?: string;
icon?: ReactNode;
} & SidebarItemProps) {
const { isCollapsed } = useContext(SidebarContext);
return (
<TooltipTrigger delay={0} closeDelay={0} isDisabled={!isCollapsed}>
<Focusable>
<Row
{...props}
paddingX={isCollapsed ? '0' : '4'}
paddingY="2"
gap="3"
alignItems="center"
justifyContent={isCollapsed ? 'center' : undefined}
borderRadius="md"
className={classNames(
'cursor-pointer',
'hover:bg-interactive',
isSelected && 'bg-interactive font-medium',
className,
)}
>
{icon && <Icon size="sm">{icon}</Icon>}
{label && !isCollapsed && <Text>{label}</Text>}
{children}
</Row>
</Focusable>
<Tooltip placement="right">{label}</Tooltip>
</TooltipTrigger>
);
}