@opencode/ui 2.0.7 → 2.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/feedback/toast/description.d.ts +4 -0
- package/dist/feedback/toast/toast.d.ts +2 -0
- package/dist/i18n/en.d.ts +2 -0
- package/package.json +1 -1
- package/src/components/scroll-view.tsx +11 -7
- package/src/feedback/toast/description.ts +9 -0
- package/src/feedback/toast/toast.css +9 -0
- package/src/feedback/toast/toast.tsx +20 -2
- package/src/i18n/en.ts +2 -0
|
@@ -31,6 +31,8 @@ export declare const toaster: {
|
|
|
31
31
|
}) => JSX.Element, options?: {
|
|
32
32
|
duration?: number;
|
|
33
33
|
persistent?: boolean;
|
|
34
|
+
/** Reactive value the toast's height depends on; sonner re-measures when it changes. */
|
|
35
|
+
resize?: () => unknown;
|
|
34
36
|
}): number;
|
|
35
37
|
dismiss(toastId?: number): string | number | undefined;
|
|
36
38
|
};
|
package/dist/i18n/en.d.ts
CHANGED
|
@@ -133,6 +133,8 @@ declare const source: {
|
|
|
133
133
|
"ui.promptInput.dropFiles.pdf": string;
|
|
134
134
|
"ui.promptInput.dropFiles.imagePdf": string;
|
|
135
135
|
"ui.promptInput.removeAttachment": string;
|
|
136
|
+
"ui.promptInput.cancelUpload": string;
|
|
137
|
+
"ui.promptInput.uploading": string;
|
|
136
138
|
"ui.promptInput.label": string;
|
|
137
139
|
"ui.promptInput.placeholder.shell": string;
|
|
138
140
|
"ui.promptInput.placeholder.normal": string;
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createEffect, mergeProps, onCleanup, onMount, Show, splitProps, type ComponentProps } from "solid-js"
|
|
1
|
+
import { createEffect, mergeProps, on, onCleanup, onMount, Show, splitProps, type ComponentProps } from "solid-js"
|
|
2
2
|
import { Portal } from "solid-js/web"
|
|
3
3
|
import { createResizeObserver } from "@solid-primitives/resize-observer"
|
|
4
4
|
import { createStore } from "solid-js/store"
|
|
@@ -236,18 +236,22 @@ export function ScrollView(props: ScrollViewProps) {
|
|
|
236
236
|
local.viewportRef(viewportRef)
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
+
// The observer reports every target once when it starts observing (including a thumb mount that
|
|
240
|
+
// appears later), after layout. Measuring here as well would force a synchronous layout per
|
|
241
|
+
// ScrollView while the page is still rendering.
|
|
239
242
|
createResizeObserver(
|
|
240
243
|
() => [viewportRef, viewportRef.firstElementChild, thumbMount()].filter(Boolean) as HTMLElement[],
|
|
241
244
|
updateThumb,
|
|
242
245
|
)
|
|
243
|
-
|
|
244
|
-
updateThumb()
|
|
245
246
|
})
|
|
246
247
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
248
|
+
// Inputs that change the thumb without resizing anything: re-measure on change, but leave the
|
|
249
|
+
// first measurement to the observer.
|
|
250
|
+
createEffect(
|
|
251
|
+
on([() => local.verticalScrollAdjustment, vertical, horizontal, thumbMount], () => updateThumb(), {
|
|
252
|
+
defer: true,
|
|
253
|
+
}),
|
|
254
|
+
)
|
|
251
255
|
|
|
252
256
|
createEffect(() => {
|
|
253
257
|
if (!horizontal() || !viewportRef) return
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// A toast shows a few lines; the rest of a long description would only be retained (in the dedupe
|
|
2
|
+
// key, the active-toast registry and the toaster's store) for as long as the toast lives. Server
|
|
3
|
+
// errors have carried a whole data URL here.
|
|
4
|
+
export const toastDescriptionLimit = 2000
|
|
5
|
+
|
|
6
|
+
export function boundToastDescription<T extends { description?: string }>(options: T): T {
|
|
7
|
+
if (!options.description || options.description.length <= toastDescriptionLimit) return options
|
|
8
|
+
return { ...options, description: `${options.description.slice(0, toastDescriptionLimit)}…` }
|
|
9
|
+
}
|
|
@@ -79,6 +79,15 @@
|
|
|
79
79
|
grid-column: 2;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
/* Custom toasts render no close button, so their content takes the whole width. */
|
|
83
|
+
&:not(:has(> [data-close-button])) > [data-content] {
|
|
84
|
+
grid-column: 1 / -1;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
[data-description]:empty {
|
|
88
|
+
display: none;
|
|
89
|
+
}
|
|
90
|
+
|
|
82
91
|
> [data-close-button] {
|
|
83
92
|
grid-column: 2;
|
|
84
93
|
grid-row: 1;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Toaster, toast, type ToasterProps } from "solid-sonner"
|
|
2
|
+
import { boundToastDescription } from "./description"
|
|
2
3
|
import { isRTL } from "@kobalte/core/i18n"
|
|
3
4
|
import type { ComponentProps, JSX } from "solid-js"
|
|
4
5
|
import { createContext, onCleanup, onMount, splitProps, useContext } from "solid-js"
|
|
@@ -140,13 +141,30 @@ export const Toast = Object.assign(ToastRoot, {
|
|
|
140
141
|
let toastV2Id = 0
|
|
141
142
|
|
|
142
143
|
export const toaster = {
|
|
143
|
-
show(
|
|
144
|
+
show(
|
|
145
|
+
render: (props: { toastId: number }) => JSX.Element,
|
|
146
|
+
options?: {
|
|
147
|
+
duration?: number
|
|
148
|
+
persistent?: boolean
|
|
149
|
+
/** Reactive value the toast's height depends on; sonner re-measures when it changes. */
|
|
150
|
+
resize?: () => unknown
|
|
151
|
+
},
|
|
152
|
+
) {
|
|
144
153
|
const toastId = --toastV2Id
|
|
145
154
|
toast.custom((id) => render({ toastId: Number(id) }), {
|
|
146
155
|
id: toastId,
|
|
147
156
|
className: "toast-v2",
|
|
148
157
|
duration: options?.persistent ? Number.POSITIVE_INFINITY : options?.duration,
|
|
149
158
|
unstyled: true,
|
|
159
|
+
// Sonner only re-measures on title/description changes, so a function-valued description is
|
|
160
|
+
// the hook for a custom toast whose height depends on reactive state. It renders nothing;
|
|
161
|
+
// toast.css collapses the empty description element.
|
|
162
|
+
description: options?.resize
|
|
163
|
+
? (): JSX.Element => {
|
|
164
|
+
options.resize?.()
|
|
165
|
+
return undefined
|
|
166
|
+
}
|
|
167
|
+
: undefined,
|
|
150
168
|
})
|
|
151
169
|
return toastId
|
|
152
170
|
},
|
|
@@ -188,7 +206,7 @@ const activeToastByKey = new Map<string, ActiveToast>()
|
|
|
188
206
|
const activeToastById = new Map<number, ActiveToast>()
|
|
189
207
|
|
|
190
208
|
export function showToast(options: ToastOptions | string) {
|
|
191
|
-
const opts
|
|
209
|
+
const opts = boundToastDescription(typeof options === "string" ? { description: options } : options)
|
|
192
210
|
const key = JSON.stringify({
|
|
193
211
|
title: opts.title,
|
|
194
212
|
description: opts.description,
|
package/src/i18n/en.ts
CHANGED
|
@@ -147,6 +147,8 @@ const source = {
|
|
|
147
147
|
"ui.promptInput.dropFiles.pdf": "Drop PDFs or files to add",
|
|
148
148
|
"ui.promptInput.dropFiles.imagePdf": "Drop images, PDFs, or files to add",
|
|
149
149
|
"ui.promptInput.removeAttachment": "Remove attachment",
|
|
150
|
+
"ui.promptInput.cancelUpload": "Cancel upload",
|
|
151
|
+
"ui.promptInput.uploading": "{{percent}}%",
|
|
150
152
|
"ui.promptInput.label": "Prompt",
|
|
151
153
|
"ui.promptInput.placeholder.shell": "Enter shell command…",
|
|
152
154
|
"ui.promptInput.placeholder.normal": "Ask anything, {{slash}} for commands, {{at}} for context…",
|