summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/components
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-12-11 11:28:34 -0600
committerAdam <[email protected]>2025-12-11 13:42:47 -0600
commite845eedbc325b05a19679bc439a57cc0fbf23aa3 (patch)
treef2bd6686664870ef11aba12a9946356d9df149c4 /packages/ui/src/components
parent4ae7e1b19c3915e3e9b1a39195d54c4721836b03 (diff)
downloadopencode-e845eedbc325b05a19679bc439a57cc0fbf23aa3.tar.gz
opencode-e845eedbc325b05a19679bc439a57cc0fbf23aa3.zip
wip(desktop): progress
Diffstat (limited to 'packages/ui/src/components')
-rw-r--r--packages/ui/src/components/list.css6
-rw-r--r--packages/ui/src/components/toast.css28
-rw-r--r--packages/ui/src/components/toast.tsx42
3 files changed, 59 insertions, 17 deletions
diff --git a/packages/ui/src/components/list.css b/packages/ui/src/components/list.css
index 38dcb773b..783b0ef4a 100644
--- a/packages/ui/src/components/list.css
+++ b/packages/ui/src/components/list.css
@@ -98,17 +98,13 @@
display: block;
}
[data-slot="list-item-extra-icon"] {
+ display: block !important;
color: var(--icon-strong-base) !important;
}
}
&:active {
background: var(--surface-raised-base-active);
}
- &:hover {
- [data-slot="list-item-extra-icon"] {
- color: var(--icon-strong-base) !important;
- }
- }
}
}
}
diff --git a/packages/ui/src/components/toast.css b/packages/ui/src/components/toast.css
index 2c55a4b06..3389f477a 100644
--- a/packages/ui/src/components/toast.css
+++ b/packages/ui/src/components/toast.css
@@ -120,6 +120,34 @@
margin: 0;
}
+ [data-slot="toast-actions"] {
+ display: flex;
+ gap: 16px;
+ margin-top: 8px;
+ }
+
+ [data-slot="toast-action"] {
+ background: none;
+ border: none;
+ padding: 0;
+ cursor: pointer;
+
+ color: rgba(253, 252, 252, 0.94);
+ font-family: var(--font-family-sans);
+ font-size: var(--font-size-base);
+ font-weight: var(--font-weight-medium);
+ line-height: var(--line-height-large);
+ letter-spacing: var(--letter-spacing-normal);
+
+ &:hover {
+ text-decoration: underline;
+ }
+
+ &:last-child {
+ color: rgba(253, 249, 249, 0.5);
+ }
+ }
+
[data-slot="toast-close-button"] {
flex-shrink: 0;
}
diff --git a/packages/ui/src/components/toast.tsx b/packages/ui/src/components/toast.tsx
index b6c9f8b08..5869f8a6b 100644
--- a/packages/ui/src/components/toast.tsx
+++ b/packages/ui/src/components/toast.tsx
@@ -57,6 +57,10 @@ function ToastDescription(props: ToastDescriptionProps & ComponentProps<"div">)
return <Kobalte.Description data-slot="toast-description" {...props} />
}
+function ToastActions(props: ComponentProps<"div">) {
+ return <div data-slot="toast-actions" {...props} />
+}
+
function ToastCloseButton(props: ToastCloseButtonProps & ComponentProps<"button">) {
return <Kobalte.CloseButton data-slot="toast-close-button" as={IconButton} icon="close" variant="ghost" {...props} />
}
@@ -75,6 +79,7 @@ export const Toast = Object.assign(ToastRoot, {
Content: ToastContent,
Title: ToastTitle,
Description: ToastDescription,
+ Actions: ToastActions,
CloseButton: ToastCloseButton,
ProgressTrack: ToastProgressTrack,
ProgressFill: ToastProgressFill,
@@ -84,31 +89,44 @@ export { toaster }
export type ToastVariant = "default" | "success" | "error" | "loading"
+export interface ToastAction {
+ label: string
+ onClick: () => void
+}
+
export interface ToastOptions {
title?: string
description?: string
icon?: IconProps["name"]
variant?: ToastVariant
duration?: number
+ actions?: ToastAction[]
}
export function showToast(options: ToastOptions | string) {
const opts = typeof options === "string" ? { description: options } : options
return toaster.show((props) => (
<Toast toastId={props.toastId} duration={opts.duration} data-variant={opts.variant ?? "default"}>
- <div data-slot="toast-inner">
- <Show when={opts.icon}>
- <Toast.Icon name={opts.icon!} />
+ <Show when={opts.icon}>
+ <Toast.Icon name={opts.icon!} />
+ </Show>
+ <Toast.Content>
+ <Show when={opts.title}>
+ <Toast.Title>{opts.title}</Toast.Title>
+ </Show>
+ <Show when={opts.description}>
+ <Toast.Description>{opts.description}</Toast.Description>
</Show>
- <Toast.Content>
- <Show when={opts.title}>
- <Toast.Title>{opts.title}</Toast.Title>
- </Show>
- <Show when={opts.description}>
- <Toast.Description>{opts.description}</Toast.Description>
- </Show>
- </Toast.Content>
- </div>
+ <Show when={opts.actions?.length}>
+ <Toast.Actions>
+ {opts.actions!.map((action) => (
+ <button data-slot="toast-action" onClick={action.onClick}>
+ {action.label}
+ </button>
+ ))}
+ </Toast.Actions>
+ </Show>
+ </Toast.Content>
<Toast.CloseButton />
</Toast>
))