summaryrefslogtreecommitdiffhomepage
path: root/cloud/web/src/ui/dialog-select.tsx
diff options
context:
space:
mode:
authorFrank <[email protected]>2025-08-29 23:32:17 -0400
committerFrank <[email protected]>2025-08-29 23:32:17 -0400
commit37f284f9a97d3354143d64fc76c2eb9f7d9ccf9e (patch)
tree053db9abcb2178c71b22ebeadd07f920750ef5d2 /cloud/web/src/ui/dialog-select.tsx
parent0178eab29bda2f1b37a29543cd313ede48ad3977 (diff)
downloadopencode-37f284f9a97d3354143d64fc76c2eb9f7d9ccf9e.tar.gz
opencode-37f284f9a97d3354143d64fc76c2eb9f7d9ccf9e.zip
wip: cloud
Diffstat (limited to 'cloud/web/src/ui/dialog-select.tsx')
-rw-r--r--cloud/web/src/ui/dialog-select.tsx124
1 files changed, 0 insertions, 124 deletions
diff --git a/cloud/web/src/ui/dialog-select.tsx b/cloud/web/src/ui/dialog-select.tsx
deleted file mode 100644
index 087b94411..000000000
--- a/cloud/web/src/ui/dialog-select.tsx
+++ /dev/null
@@ -1,124 +0,0 @@
-import style from "./dialog-select.module.css"
-import { z } from "zod"
-import { createMemo, createSignal, For, JSX, onMount } from "solid-js"
-import { createList } from "solid-list"
-import { createDialog } from "./context-dialog"
-
-export const DialogSelect = createDialog({
- size: "md",
- schema: z.object({
- title: z.string(),
- placeholder: z.string(),
- onSelect: z
- .function(z.tuple([z.any()]))
- .returns(z.void())
- .optional(),
- options: z.array(
- z.object({
- display: z.string(),
- value: z.any().optional(),
- onSelect: z.function().returns(z.void()).optional(),
- prefix: z.custom<JSX.Element>().optional(),
- }),
- ),
- }),
- render: (ctx) => {
- let input: HTMLInputElement
- onMount(() => {
- input.focus()
- input.value = ""
- })
-
- const [filter, setFilter] = createSignal("")
- const filtered = createMemo(() =>
- ctx.input.options?.filter((i) =>
- i.display.toLowerCase().includes(filter().toLowerCase()),
- ),
- )
- const list = createList({
- loop: true,
- initialActive: 0,
- items: () => filtered().map((_, i) => i),
- handleTab: false,
- })
-
- const handleSelection = (index: number) => {
- const option = ctx.input.options[index]
-
- // If the option has its own onSelect handler, use it
- if (option.onSelect) {
- option.onSelect()
- }
- // Otherwise, if there's a global onSelect handler, call it with the option's value
- else if (ctx.input.onSelect) {
- ctx.input.onSelect(
- option.value !== undefined ? option.value : option.display,
- )
- }
- }
-
- return (
- <>
- <div data-slot="header">
- <label
- data-size="md"
- data-slot="title"
- data-component="label"
- for={`dialog-select-${ctx.input.title}`}
- >
- {ctx.input.title}
- </label>
- </div>
- <div data-slot="main">
- <input
- data-size="lg"
- data-component="input"
- value={filter()}
- onInput={(e) => {
- setFilter(e.target.value)
- list.setActive(0)
- }}
- onKeyDown={(e) => {
- if (e.key === "Enter") {
- const selected = list.active()
- if (selected === null) return
- handleSelection(selected)
- return
- }
- if (e.key === "Escape") {
- setFilter("")
- return
- }
- list.onKeyDown(e)
- }}
- id={`dialog-select-${ctx.input.title}`}
- ref={(r) => (input = r)}
- data-slot="input"
- placeholder={ctx.input.placeholder}
- />
- </div>
- <div data-slot="options" class={style.options}>
- <For
- each={filtered()}
- fallback={
- <div data-slot="option" data-empty>
- No results
- </div>
- }
- >
- {(option, index) => (
- <div
- onClick={() => handleSelection(index())}
- data-slot="option"
- data-active={list.active() === index() ? true : undefined}
- >
- {option.prefix && <div data-slot="prefix">{option.prefix}</div>}
- <div data-slot="title">{option.display}</div>
- </div>
- )}
- </For>
- </div>
- </>
- )
- },
-})