Skip to content

Commit 3013b59

Browse files
committed
chore: update dependencies and enhance UI components
- Add `oxfmt` dependency to `package.json` for improved formatting capabilities. - Update styles in `index.css` to implement a new dark color scheme. - Refactor button and card components for better structure and styling consistency. - Simplify dialog component structure and improve accessibility features. - Enhance input component styling for better user experience. - Update development runner script to resolve local turbo executable path.
1 parent ccf0e92 commit 3013b59

11 files changed

Lines changed: 268 additions & 398 deletions

File tree

apps/desktop/resources/icon.icns

-1.5 MB
Binary file not shown.

apps/desktop/resources/icon.ico

-180 Bytes
Binary file not shown.

apps/desktop/resources/icon.png

-120 KB
Loading

apps/web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"effect": "catalog:",
4040
"lexical": "^0.41.0",
4141
"lucide-react": "^0.564.0",
42+
"oxfmt": "^0.42.0",
4243
"react": "^19.0.0",
4344
"react-dom": "^19.0.0",
4445
"react-markdown": "^10.1.0",
Lines changed: 44 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,66 @@
1-
"use client";
2-
3-
import { mergeProps } from "@base-ui/react/merge-props";
4-
import { useRender } from "@base-ui/react/use-render";
51
import { cva, type VariantProps } from "class-variance-authority";
6-
import type * as React from "react";
2+
import * as React from "react";
73

84
import { cn } from "~/lib/utils";
95

106
const buttonVariants = cva(
11-
"[&_svg]:-mx-0.5 relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-lg border font-medium text-base outline-none transition-shadow before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-lg)-1px)] pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 sm:text-sm [&_svg:not([class*='opacity-'])]:opacity-80 [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
7+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-xl text-sm font-medium transition-all duration-200 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 outline-none focus-visible:ring-2 focus-visible:ring-ring/80 focus-visible:ring-offset-2 focus-visible:ring-offset-background active:scale-[0.99]",
128
{
13-
defaultVariants: {
14-
size: "default",
15-
variant: "default",
16-
},
179
variants: {
18-
size: {
19-
default: "h-9 px-[calc(--spacing(3)-1px)] sm:h-8",
20-
icon: "size-9 sm:size-8",
21-
"icon-lg": "size-10 sm:size-9",
22-
"icon-sm": "size-8 sm:size-7",
23-
"icon-xl":
24-
"size-11 sm:size-10 [&_svg:not([class*='size-'])]:size-5 sm:[&_svg:not([class*='size-'])]:size-4.5",
25-
"icon-xs":
26-
"size-7 rounded-md before:rounded-[calc(var(--radius-md)-1px)] sm:size-6 not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-4 sm:not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-3.5",
27-
lg: "h-10 px-[calc(--spacing(3.5)-1px)] sm:h-9",
28-
sm: "h-8 gap-1.5 px-[calc(--spacing(2.5)-1px)] sm:h-7",
29-
xl: "h-11 px-[calc(--spacing(4)-1px)] text-lg sm:h-10 sm:text-base [&_svg:not([class*='size-'])]:size-5 sm:[&_svg:not([class*='size-'])]:size-4.5",
30-
xs: "h-7 gap-1 rounded-md px-[calc(--spacing(2)-1px)] text-sm before:rounded-[calc(var(--radius-md)-1px)] sm:h-6 sm:text-xs [&_svg:not([class*='size-'])]:size-4 sm:[&_svg:not([class*='size-'])]:size-3.5",
31-
},
3210
variant: {
3311
default:
34-
"not-disabled:inset-shadow-[0_1px_--theme(--color-white/16%)] border-primary bg-primary text-primary-foreground shadow-primary/24 shadow-xs [:active,[data-pressed]]:inset-shadow-[0_1px_--theme(--color-black/8%)] [:disabled,:active,[data-pressed]]:shadow-none [:hover,[data-pressed]]:bg-primary/90",
12+
"bg-linear-to-b from-primary to-[hsl(223_82%_62%)] text-primary-foreground shadow-[0_18px_45px_-20px_hsl(var(--primary)/0.85)] hover:brightness-110 hover:shadow-[0_22px_55px_-22px_hsl(var(--primary)/0.95)]",
3513
destructive:
36-
"not-disabled:inset-shadow-[0_1px_--theme(--color-white/16%)] border-destructive bg-destructive text-white shadow-destructive/24 shadow-xs [:active,[data-pressed]]:inset-shadow-[0_1px_--theme(--color-black/8%)] [:disabled,:active,[data-pressed]]:shadow-none [:hover,[data-pressed]]:bg-destructive/90",
37-
"destructive-outline":
38-
"border-input bg-popover not-dark:bg-clip-padding text-destructive-foreground shadow-xs/5 not-disabled:not-active:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] dark:bg-input/32 dark:not-disabled:before:shadow-[0_-1px_--theme(--color-white/2%)] dark:not-disabled:not-active:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/6%)] [:disabled,:active,[data-pressed]]:shadow-none [:hover,[data-pressed]]:border-destructive/32 [:hover,[data-pressed]]:bg-destructive/4",
39-
ghost:
40-
"border-transparent text-foreground data-pressed:bg-accent [:hover,[data-pressed]]:bg-accent",
41-
link: "border-transparent underline-offset-4 [:hover,[data-pressed]]:underline",
14+
"bg-linear-to-b from-destructive to-[hsl(352_72%_52%)] text-destructive-foreground shadow-[0_18px_45px_-20px_hsl(var(--destructive)/0.7)] hover:brightness-105 hover:shadow-[0_22px_55px_-22px_hsl(var(--destructive)/0.8)]",
4215
outline:
43-
"border-input bg-popover not-dark:bg-clip-padding text-foreground shadow-xs/5 not-disabled:not-active:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] dark:bg-input/32 dark:not-disabled:before:shadow-[0_-1px_--theme(--color-white/2%)] dark:not-disabled:not-active:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/6%)] [:disabled,:active,[data-pressed]]:shadow-none [:hover,[data-pressed]]:bg-accent/50 dark:[:hover,[data-pressed]]:bg-input/64",
16+
"border border-border/80 bg-card/70 text-foreground shadow-[inset_0_1px_0_hsl(0_0%_100%/0.04)] hover:border-primary/30 hover:bg-accent/80 hover:text-foreground",
4417
secondary:
45-
"border-transparent bg-secondary text-secondary-foreground [:active,[data-pressed]]:bg-secondary/80 [:hover,[data-pressed]]:bg-secondary/90",
18+
"bg-accent/85 text-accent-foreground shadow-[inset_0_1px_0_hsl(0_0%_100%/0.04)] hover:bg-accent",
19+
ghost: "text-muted-foreground hover:bg-accent/75 hover:text-foreground",
20+
link: "text-primary underline-offset-4 hover:underline",
21+
},
22+
size: {
23+
default: "h-9 px-4 py-2",
24+
sm: "h-8 rounded-lg px-3 text-xs",
25+
lg: "h-10 rounded-xl px-6",
26+
icon: "size-9 rounded-xl",
27+
"icon-xs": "size-7 rounded-lg",
4628
},
4729
},
30+
defaultVariants: {
31+
variant: "default",
32+
size: "default",
33+
},
4834
},
4935
);
5036

51-
interface ButtonProps extends useRender.ComponentProps<"button"> {
52-
variant?: VariantProps<typeof buttonVariants>["variant"];
53-
size?: VariantProps<typeof buttonVariants>["size"];
54-
}
55-
56-
function Button({ className, variant, size, render, ...props }: ButtonProps) {
57-
const typeValue: React.ButtonHTMLAttributes<HTMLButtonElement>["type"] = render
58-
? undefined
59-
: "button";
37+
function Button({
38+
className,
39+
variant,
40+
size,
41+
asChild = false,
42+
...props
43+
}: React.ComponentProps<"button"> &
44+
VariantProps<typeof buttonVariants> & {
45+
asChild?: boolean;
46+
}) {
47+
const Comp = asChild ? (React.Fragment as never) : "button";
6048

61-
const defaultProps = {
62-
className: cn(buttonVariants({ className, size, variant })),
63-
"data-slot": "button",
64-
type: typeValue,
65-
};
49+
if (asChild) {
50+
const child = React.Children.only(props.children) as React.ReactElement;
51+
return React.cloneElement(child, {
52+
...props,
53+
className: cn(buttonVariants({ variant, size, className }), child.props.className),
54+
});
55+
}
6656

67-
return useRender({
68-
defaultTagName: "button",
69-
props: mergeProps<"button">(defaultProps, props),
70-
render,
71-
});
57+
return (
58+
<Comp
59+
data-slot="button"
60+
className={cn(buttonVariants({ variant, size, className }))}
61+
{...props}
62+
/>
63+
);
7264
}
7365

7466
export { Button, buttonVariants };
Lines changed: 55 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -1,196 +1,72 @@
1-
"use client";
2-
3-
import { mergeProps } from "@base-ui/react/merge-props";
4-
import { useRender } from "@base-ui/react/use-render";
1+
import * as React from "react";
52

63
import { cn } from "~/lib/utils";
74

8-
function Card({ className, render, ...props }: useRender.ComponentProps<"div">) {
9-
const defaultProps = {
10-
className: cn(
11-
"relative flex flex-col rounded-2xl border bg-card not-dark:bg-clip-padding text-card-foreground shadow-xs/5 before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-2xl)-1px)] before:shadow-[0_1px_--theme(--color-black/4%)] dark:before:shadow-[0_-1px_--theme(--color-white/6%)]",
12-
className,
13-
),
14-
"data-slot": "card",
15-
};
16-
17-
return useRender({
18-
defaultTagName: "div",
19-
props: mergeProps<"div">(defaultProps, props),
20-
render,
21-
});
22-
}
23-
24-
function CardFrame({ className, render, ...props }: useRender.ComponentProps<"div">) {
25-
const defaultProps = {
26-
className: cn(
27-
"[--clip-top:-1rem] [--clip-bottom:-1rem] *:data-[slot=card]:first:[--clip-top:1px] *:data-[slot=card]:last:[--clip-bottom:1px] flex flex-col relative rounded-2xl border bg-card before:bg-muted/72 not-dark:bg-clip-padding text-card-foreground shadow-xs/5 before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-2xl)-1px)] before:shadow-[0_1px_--theme(--color-black/4%)] dark:before:shadow-[0_-1px_--theme(--color-white/6%)] *:data-[slot=card]:-m-px *:not-last:data-[slot=card]:rounded-b-xl *:not-last:data-[slot=card]:before:rounded-b-[calc(var(--radius-xl)-1px)] *:not-first:data-[slot=card]:rounded-t-xl *:not-first:data-[slot=card]:before:rounded-t-[calc(var(--radius-xl)-1px)] *:data-[slot=card]:[clip-path:inset(var(--clip-top)_1px_var(--clip-bottom)_1px_round_calc(var(--radius-2xl)-1px))] *:data-[slot=card]:shadow-none *:data-[slot=card]:before:hidden *:data-[slot=card]:bg-clip-padding",
28-
className,
29-
),
30-
"data-slot": "card-frame",
31-
};
32-
33-
return useRender({
34-
defaultTagName: "div",
35-
props: mergeProps<"div">(defaultProps, props),
36-
render,
37-
});
5+
function Card({ className, ...props }: React.ComponentProps<"div">) {
6+
return (
7+
<div
8+
data-slot="card"
9+
className={cn(
10+
"rounded-2xl border border-border/75 bg-card/82 text-card-foreground shadow-[0_24px_80px_-36px_hsl(220_70%_3%/0.95)] backdrop-blur-xl",
11+
className,
12+
)}
13+
{...props}
14+
/>
15+
);
3816
}
3917

40-
function CardFrameHeader({ className, render, ...props }: useRender.ComponentProps<"div">) {
41-
const defaultProps = {
42-
className: cn("relative flex flex-col px-6 py-4", className),
43-
"data-slot": "card-frame-header",
44-
};
45-
46-
return useRender({
47-
defaultTagName: "div",
48-
props: mergeProps<"div">(defaultProps, props),
49-
render,
50-
});
18+
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
19+
return (
20+
<div
21+
data-slot="card-header"
22+
className={cn("flex flex-col gap-1.5 p-6", className)}
23+
{...props}
24+
/>
25+
);
5126
}
5227

53-
function CardFrameTitle({ className, render, ...props }: useRender.ComponentProps<"div">) {
54-
const defaultProps = {
55-
className: cn("font-semibold text-sm", className),
56-
"data-slot": "card-frame-title",
57-
};
58-
59-
return useRender({
60-
defaultTagName: "div",
61-
props: mergeProps<"div">(defaultProps, props),
62-
render,
63-
});
28+
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
29+
return (
30+
<div
31+
data-slot="card-title"
32+
className={cn("leading-none font-semibold tracking-tight", className)}
33+
{...props}
34+
/>
35+
);
6436
}
6537

66-
function CardFrameDescription({ className, render, ...props }: useRender.ComponentProps<"div">) {
67-
const defaultProps = {
68-
className: cn("text-muted-foreground text-sm", className),
69-
"data-slot": "card-frame-description",
70-
};
71-
72-
return useRender({
73-
defaultTagName: "div",
74-
props: mergeProps<"div">(defaultProps, props),
75-
render,
76-
});
38+
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
39+
return (
40+
<div
41+
data-slot="card-description"
42+
className={cn("text-sm text-muted-foreground", className)}
43+
{...props}
44+
/>
45+
);
7746
}
7847

79-
function CardFrameFooter({ className, render, ...props }: useRender.ComponentProps<"div">) {
80-
const defaultProps = {
81-
className: cn("px-6 py-4", className),
82-
"data-slot": "card-frame-footer",
83-
};
84-
85-
return useRender({
86-
defaultTagName: "div",
87-
props: mergeProps<"div">(defaultProps, props),
88-
render,
89-
});
48+
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
49+
return (
50+
<div
51+
data-slot="card-action"
52+
className={cn("col-start-2 row-span-2 row-start-1 self-start justify-self-end", className)}
53+
{...props}
54+
/>
55+
);
9056
}
9157

92-
function CardHeader({ className, render, ...props }: useRender.ComponentProps<"div">) {
93-
const defaultProps = {
94-
className: cn(
95-
"grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 p-6 in-[[data-slot=card]:has(>[data-slot=card-panel])]:pb-4 has-data-[slot=card-action]:grid-cols-[1fr_auto]",
96-
className,
97-
),
98-
"data-slot": "card-header",
99-
};
100-
101-
return useRender({
102-
defaultTagName: "div",
103-
props: mergeProps<"div">(defaultProps, props),
104-
render,
105-
});
58+
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
59+
return <div data-slot="card-content" className={cn("px-6 pb-6", className)} {...props} />;
10660
}
10761

108-
function CardTitle({ className, render, ...props }: useRender.ComponentProps<"div">) {
109-
const defaultProps = {
110-
className: cn("font-semibold text-lg leading-none", className),
111-
"data-slot": "card-title",
112-
};
113-
114-
return useRender({
115-
defaultTagName: "div",
116-
props: mergeProps<"div">(defaultProps, props),
117-
render,
118-
});
119-
}
120-
121-
function CardDescription({ className, render, ...props }: useRender.ComponentProps<"div">) {
122-
const defaultProps = {
123-
className: cn("text-muted-foreground text-sm", className),
124-
"data-slot": "card-description",
125-
};
126-
127-
return useRender({
128-
defaultTagName: "div",
129-
props: mergeProps<"div">(defaultProps, props),
130-
render,
131-
});
132-
}
133-
134-
function CardAction({ className, render, ...props }: useRender.ComponentProps<"div">) {
135-
const defaultProps = {
136-
className: cn(
137-
"col-start-2 row-span-2 row-start-1 self-start justify-self-end inline-flex",
138-
className,
139-
),
140-
"data-slot": "card-action",
141-
};
142-
143-
return useRender({
144-
defaultTagName: "div",
145-
props: mergeProps<"div">(defaultProps, props),
146-
render,
147-
});
148-
}
149-
150-
function CardPanel({ className, render, ...props }: useRender.ComponentProps<"div">) {
151-
const defaultProps = {
152-
className: cn(
153-
"flex-1 p-6 in-[[data-slot=card]:has(>[data-slot=card-header]:not(.border-b))]:pt-0 in-[[data-slot=card]:has(>[data-slot=card-footer]:not(.border-t))]:pb-0",
154-
className,
155-
),
156-
"data-slot": "card-panel",
157-
};
158-
159-
return useRender({
160-
defaultTagName: "div",
161-
props: mergeProps<"div">(defaultProps, props),
162-
render,
163-
});
164-
}
165-
166-
function CardFooter({ className, render, ...props }: useRender.ComponentProps<"div">) {
167-
const defaultProps = {
168-
className: cn(
169-
"flex items-center p-6 in-[[data-slot=card]:has(>[data-slot=card-panel])]:pt-4",
170-
className,
171-
),
172-
"data-slot": "card-footer",
173-
};
174-
175-
return useRender({
176-
defaultTagName: "div",
177-
props: mergeProps<"div">(defaultProps, props),
178-
render,
179-
});
62+
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
63+
return (
64+
<div
65+
data-slot="card-footer"
66+
className={cn("flex items-center px-6 pb-6", className)}
67+
{...props}
68+
/>
69+
);
18070
}
18171

182-
export {
183-
Card,
184-
CardFrame,
185-
CardFrameHeader,
186-
CardFrameTitle,
187-
CardFrameDescription,
188-
CardFrameFooter,
189-
CardAction,
190-
CardDescription,
191-
CardFooter,
192-
CardHeader,
193-
CardPanel,
194-
CardPanel as CardContent,
195-
CardTitle,
196-
};
72+
export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };

0 commit comments

Comments
 (0)