|
@@ -115,11 +115,12 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
|
|
|
setStore("selected", currentIndex)
|
|
setStore("selected", currentIndex)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- scroll.scrollTo(0)
|
|
|
|
|
|
|
+ scroll?.scrollTo(0)
|
|
|
}),
|
|
}),
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
function move(direction: number) {
|
|
function move(direction: number) {
|
|
|
|
|
+ if (flat().length === 0) return
|
|
|
let next = store.selected + direction
|
|
let next = store.selected + direction
|
|
|
if (next < 0) next = flat().length - 1
|
|
if (next < 0) next = flat().length - 1
|
|
|
if (next >= flat().length) next = 0
|
|
if (next >= flat().length) next = 0
|
|
@@ -129,6 +130,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
|
|
|
function moveTo(next: number) {
|
|
function moveTo(next: number) {
|
|
|
setStore("selected", next)
|
|
setStore("selected", next)
|
|
|
props.onMove?.(selected()!)
|
|
props.onMove?.(selected()!)
|
|
|
|
|
+ if (!scroll) return
|
|
|
const target = scroll.getChildren().find((child) => {
|
|
const target = scroll.getChildren().find((child) => {
|
|
|
return child.id === JSON.stringify(selected()?.value)
|
|
return child.id === JSON.stringify(selected()?.value)
|
|
|
})
|
|
})
|
|
@@ -172,7 +174,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- let scroll: ScrollBoxRenderable
|
|
|
|
|
|
|
+ let scroll: ScrollBoxRenderable | undefined
|
|
|
const ref: DialogSelectRef<T> = {
|
|
const ref: DialogSelectRef<T> = {
|
|
|
get filter() {
|
|
get filter() {
|
|
|
return store.filter
|
|
return store.filter
|
|
@@ -213,61 +215,70 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
|
|
|
/>
|
|
/>
|
|
|
</box>
|
|
</box>
|
|
|
</box>
|
|
</box>
|
|
|
- <scrollbox
|
|
|
|
|
- paddingLeft={1}
|
|
|
|
|
- paddingRight={1}
|
|
|
|
|
- scrollbarOptions={{ visible: false }}
|
|
|
|
|
- ref={(r: ScrollBoxRenderable) => (scroll = r)}
|
|
|
|
|
- maxHeight={height()}
|
|
|
|
|
|
|
+ <Show
|
|
|
|
|
+ when={grouped().length > 0}
|
|
|
|
|
+ fallback={
|
|
|
|
|
+ <box paddingLeft={4} paddingRight={4} paddingTop={1}>
|
|
|
|
|
+ <text fg={theme.textMuted}>No results found</text>
|
|
|
|
|
+ </box>
|
|
|
|
|
+ }
|
|
|
>
|
|
>
|
|
|
- <For each={grouped()}>
|
|
|
|
|
- {([category, options], index) => (
|
|
|
|
|
- <>
|
|
|
|
|
- <Show when={category}>
|
|
|
|
|
- <box paddingTop={index() > 0 ? 1 : 0} paddingLeft={3}>
|
|
|
|
|
- <text fg={theme.accent} attributes={TextAttributes.BOLD}>
|
|
|
|
|
- {category}
|
|
|
|
|
- </text>
|
|
|
|
|
- </box>
|
|
|
|
|
- </Show>
|
|
|
|
|
- <For each={options}>
|
|
|
|
|
- {(option) => {
|
|
|
|
|
- const active = createMemo(() => isDeepEqual(option.value, selected()?.value))
|
|
|
|
|
- const current = createMemo(() => isDeepEqual(option.value, props.current))
|
|
|
|
|
- return (
|
|
|
|
|
- <box
|
|
|
|
|
- id={JSON.stringify(option.value)}
|
|
|
|
|
- flexDirection="row"
|
|
|
|
|
- onMouseUp={() => {
|
|
|
|
|
- option.onSelect?.(dialog)
|
|
|
|
|
- props.onSelect?.(option)
|
|
|
|
|
- }}
|
|
|
|
|
- onMouseOver={() => {
|
|
|
|
|
- const index = filtered().findIndex((x) => isDeepEqual(x.value, option.value))
|
|
|
|
|
- if (index === -1) return
|
|
|
|
|
- moveTo(index)
|
|
|
|
|
- }}
|
|
|
|
|
- backgroundColor={active() ? (option.bg ?? theme.primary) : RGBA.fromInts(0, 0, 0, 0)}
|
|
|
|
|
- paddingLeft={current() || option.gutter ? 1 : 3}
|
|
|
|
|
- paddingRight={3}
|
|
|
|
|
- gap={1}
|
|
|
|
|
- >
|
|
|
|
|
- <Option
|
|
|
|
|
- title={option.title}
|
|
|
|
|
- footer={option.footer}
|
|
|
|
|
- description={option.description !== category ? option.description : undefined}
|
|
|
|
|
- active={active()}
|
|
|
|
|
- current={current()}
|
|
|
|
|
- gutter={option.gutter}
|
|
|
|
|
- />
|
|
|
|
|
- </box>
|
|
|
|
|
- )
|
|
|
|
|
- }}
|
|
|
|
|
- </For>
|
|
|
|
|
- </>
|
|
|
|
|
- )}
|
|
|
|
|
- </For>
|
|
|
|
|
- </scrollbox>
|
|
|
|
|
|
|
+ <scrollbox
|
|
|
|
|
+ paddingLeft={1}
|
|
|
|
|
+ paddingRight={1}
|
|
|
|
|
+ scrollbarOptions={{ visible: false }}
|
|
|
|
|
+ ref={(r: ScrollBoxRenderable) => (scroll = r)}
|
|
|
|
|
+ maxHeight={height()}
|
|
|
|
|
+ >
|
|
|
|
|
+ <For each={grouped()}>
|
|
|
|
|
+ {([category, options], index) => (
|
|
|
|
|
+ <>
|
|
|
|
|
+ <Show when={category}>
|
|
|
|
|
+ <box paddingTop={index() > 0 ? 1 : 0} paddingLeft={3}>
|
|
|
|
|
+ <text fg={theme.accent} attributes={TextAttributes.BOLD}>
|
|
|
|
|
+ {category}
|
|
|
|
|
+ </text>
|
|
|
|
|
+ </box>
|
|
|
|
|
+ </Show>
|
|
|
|
|
+ <For each={options}>
|
|
|
|
|
+ {(option) => {
|
|
|
|
|
+ const active = createMemo(() => isDeepEqual(option.value, selected()?.value))
|
|
|
|
|
+ const current = createMemo(() => isDeepEqual(option.value, props.current))
|
|
|
|
|
+ return (
|
|
|
|
|
+ <box
|
|
|
|
|
+ id={JSON.stringify(option.value)}
|
|
|
|
|
+ flexDirection="row"
|
|
|
|
|
+ onMouseUp={() => {
|
|
|
|
|
+ option.onSelect?.(dialog)
|
|
|
|
|
+ props.onSelect?.(option)
|
|
|
|
|
+ }}
|
|
|
|
|
+ onMouseOver={() => {
|
|
|
|
|
+ const index = filtered().findIndex((x) => isDeepEqual(x.value, option.value))
|
|
|
|
|
+ if (index === -1) return
|
|
|
|
|
+ moveTo(index)
|
|
|
|
|
+ }}
|
|
|
|
|
+ backgroundColor={active() ? (option.bg ?? theme.primary) : RGBA.fromInts(0, 0, 0, 0)}
|
|
|
|
|
+ paddingLeft={current() || option.gutter ? 1 : 3}
|
|
|
|
|
+ paddingRight={3}
|
|
|
|
|
+ gap={1}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Option
|
|
|
|
|
+ title={option.title}
|
|
|
|
|
+ footer={option.footer}
|
|
|
|
|
+ description={option.description !== category ? option.description : undefined}
|
|
|
|
|
+ active={active()}
|
|
|
|
|
+ current={current()}
|
|
|
|
|
+ gutter={option.gutter}
|
|
|
|
|
+ />
|
|
|
|
|
+ </box>
|
|
|
|
|
+ )
|
|
|
|
|
+ }}
|
|
|
|
|
+ </For>
|
|
|
|
|
+ </>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </For>
|
|
|
|
|
+ </scrollbox>
|
|
|
|
|
+ </Show>
|
|
|
<Show when={keybinds().length} fallback={<box flexShrink={0} />}>
|
|
<Show when={keybinds().length} fallback={<box flexShrink={0} />}>
|
|
|
<box paddingRight={2} paddingLeft={4} flexDirection="row" gap={2} flexShrink={0} paddingTop={1}>
|
|
<box paddingRight={2} paddingLeft={4} flexDirection="row" gap={2} flexShrink={0} paddingTop={1}>
|
|
|
<For each={keybinds()}>
|
|
<For each={keybinds()}>
|