Download packages/tui/src/component/dialog-skill.tsx from SaylorTwift/opencode: direct link, hf CLI and curl.
- Browser
- Download file 2.13 kB
-
https://huggingface.co/SaylorTwift/opencode/resolve/main/packages/tui/src/component/dialog-skill.tsx
- Command line
-
hf download hf://SaylorTwift/opencode/packages/tui/src/component/dialog-skill.tsx
-
curl -L -o dialog-skill.tsx https://huggingface.co/SaylorTwift/opencode/resolve/main/packages/tui/src/component/dialog-skill.tsx
2.13 kB
| import { TextAttributes } from "@opentui/core" | |
| import { DialogSelect, type DialogSelectOption } from "../ui/dialog-select" | |
| import { createResource, createMemo, createSignal } from "solid-js" | |
| import { useDialog } from "../ui/dialog" | |
| import { useSDK } from "../context/sdk" | |
| import { useTheme } from "../context/theme" | |
| import { errorMessage } from "../util/error" | |
| export type DialogSkillProps = { | |
| onSelect: (skill: string) => void | |
| } | |
| export function DialogSkill(props: DialogSkillProps) { | |
| const dialog = useDialog() | |
| const sdk = useSDK() | |
| const { theme } = useTheme() | |
| dialog.setSize("large") | |
| const [loadError, setLoadError] = createSignal<unknown>() | |
| const [skills] = createResource(() => | |
| sdk.client.app | |
| .skills({}, { throwOnError: true }) | |
| .then((result) => result.data ?? []) | |
| // Catch so the rejected resource never reaches the memo below: reading | |
| // skills() in an errored state re-throws and tears down the dialog. | |
| .catch((error) => { | |
| setLoadError(error) | |
| return undefined | |
| }), | |
| ) | |
| const showError = createMemo(() => Boolean(loadError())) | |
| const options = createMemo<DialogSelectOption<string>[]>(() => { | |
| if (showError()) return [] | |
| const list = skills() ?? [] | |
| const maxWidth = Math.max(0, ...list.map((s) => s.name.length)) | |
| return list.map((skill) => ({ | |
| title: skill.name.padEnd(maxWidth), | |
| description: skill.description?.replace(/\s+/g, " ").trim(), | |
| value: skill.name, | |
| category: "Skills", | |
| onSelect: () => { | |
| props.onSelect(skill.name) | |
| dialog.clear() | |
| }, | |
| })) | |
| }) | |
| return ( | |
| <DialogSelect | |
| title="Skills" | |
| placeholder="Search skills…" | |
| options={options()} | |
| renderFilter={!showError()} | |
| locked={showError()} | |
| emptyView={ | |
| showError() ? ( | |
| <box paddingLeft={4} paddingRight={4}> | |
| <text fg={theme.error} attributes={TextAttributes.BOLD}> | |
| Could not load skills | |
| </text> | |
| <text fg={theme.textMuted}>{errorMessage(loadError())}</text> | |
| </box> | |
| ) : undefined | |
| } | |
| /> | |
| ) | |
| } | |