fix(tui): pin dialog select footer to bottom (#29878)
This commit is contained in:
@@ -354,7 +354,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
|
|||||||
const right = createMemo(() => visibleActions().filter((item) => item.side === "right"))
|
const right = createMemo(() => visibleActions().filter((item) => item.side === "right"))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<box gap={1} paddingBottom={1}>
|
<box gap={1} paddingBottom={1} flexGrow={1}>
|
||||||
<box paddingLeft={4} paddingRight={4}>
|
<box paddingLeft={4} paddingRight={4}>
|
||||||
<box flexDirection="row" justifyContent="space-between">
|
<box flexDirection="row" justifyContent="space-between">
|
||||||
<text fg={theme.text} attributes={TextAttributes.BOLD}>
|
<text fg={theme.text} attributes={TextAttributes.BOLD}>
|
||||||
@@ -391,106 +391,108 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
|
|||||||
</box>
|
</box>
|
||||||
</Show>
|
</Show>
|
||||||
</box>
|
</box>
|
||||||
<Show
|
<box flexGrow={1} flexShrink={1}>
|
||||||
when={grouped().length > 0}
|
<Show
|
||||||
fallback={
|
when={grouped().length > 0}
|
||||||
<box paddingLeft={4} paddingRight={4} paddingTop={1}>
|
fallback={
|
||||||
<text fg={theme.textMuted}>No results found</text>
|
<box paddingLeft={4} paddingRight={4} paddingTop={1}>
|
||||||
</box>
|
<text fg={theme.textMuted}>No results found</text>
|
||||||
}
|
</box>
|
||||||
>
|
}
|
||||||
<scrollbox
|
|
||||||
paddingLeft={1}
|
|
||||||
paddingRight={1}
|
|
||||||
scrollbarOptions={{ visible: false }}
|
|
||||||
scrollAcceleration={scrollAcceleration()}
|
|
||||||
ref={(r: ScrollBoxRenderable) => (scroll = r)}
|
|
||||||
maxHeight={height()}
|
|
||||||
>
|
>
|
||||||
<For each={grouped()}>
|
<scrollbox
|
||||||
{([category, options], index) => (
|
paddingLeft={1}
|
||||||
<>
|
paddingRight={1}
|
||||||
<Show when={category}>
|
scrollbarOptions={{ visible: false }}
|
||||||
<box paddingTop={index() > 0 ? 1 : 0} paddingLeft={3}>
|
scrollAcceleration={scrollAcceleration()}
|
||||||
<Show
|
ref={(r: ScrollBoxRenderable) => (scroll = r)}
|
||||||
when={options[0]?.categoryView}
|
maxHeight={height()}
|
||||||
fallback={
|
>
|
||||||
<text fg={theme.accent} attributes={TextAttributes.BOLD}>
|
<For each={grouped()}>
|
||||||
{category}
|
{([category, options], index) => (
|
||||||
</text>
|
<>
|
||||||
}
|
<Show when={category}>
|
||||||
>
|
<box paddingTop={index() > 0 ? 1 : 0} paddingLeft={3}>
|
||||||
{options[0]?.categoryView}
|
<Show
|
||||||
</Show>
|
when={options[0]?.categoryView}
|
||||||
</box>
|
fallback={
|
||||||
</Show>
|
<text fg={theme.accent} attributes={TextAttributes.BOLD}>
|
||||||
<For each={options}>
|
{category}
|
||||||
{(option) => {
|
</text>
|
||||||
const active = createMemo(() => isDeepEqual(option.value, selected()?.value))
|
}
|
||||||
const current = createMemo(() => isDeepEqual(option.value, props.current))
|
|
||||||
return (
|
|
||||||
<box
|
|
||||||
id={JSON.stringify(option.value)}
|
|
||||||
flexDirection="column"
|
|
||||||
position="relative"
|
|
||||||
onMouseMove={() => {
|
|
||||||
setStore("input", "mouse")
|
|
||||||
}}
|
|
||||||
onMouseUp={() => {
|
|
||||||
option.onSelect?.(dialog)
|
|
||||||
props.onSelect?.(option)
|
|
||||||
}}
|
|
||||||
onMouseOver={() => {
|
|
||||||
if (store.input !== "mouse") return
|
|
||||||
const index = flat().findIndex((x) => isDeepEqual(x.value, option.value))
|
|
||||||
if (index === -1) return
|
|
||||||
moveTo(index)
|
|
||||||
}}
|
|
||||||
onMouseDown={() => {
|
|
||||||
const index = flat().findIndex((x) => isDeepEqual(x.value, option.value))
|
|
||||||
if (index === -1) return
|
|
||||||
moveTo(index)
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
|
{options[0]?.categoryView}
|
||||||
|
</Show>
|
||||||
|
</box>
|
||||||
|
</Show>
|
||||||
|
<For each={options}>
|
||||||
|
{(option) => {
|
||||||
|
const active = createMemo(() => isDeepEqual(option.value, selected()?.value))
|
||||||
|
const current = createMemo(() => isDeepEqual(option.value, props.current))
|
||||||
|
return (
|
||||||
<box
|
<box
|
||||||
flexDirection="row"
|
id={JSON.stringify(option.value)}
|
||||||
paddingLeft={current() || option.gutter ? 1 : 3}
|
flexDirection="column"
|
||||||
paddingRight={3}
|
position="relative"
|
||||||
gap={1}
|
onMouseMove={() => {
|
||||||
backgroundColor={active() ? (option.bg ?? theme.primary) : RGBA.fromInts(0, 0, 0, 0)}
|
setStore("input", "mouse")
|
||||||
|
}}
|
||||||
|
onMouseUp={() => {
|
||||||
|
option.onSelect?.(dialog)
|
||||||
|
props.onSelect?.(option)
|
||||||
|
}}
|
||||||
|
onMouseOver={() => {
|
||||||
|
if (store.input !== "mouse") return
|
||||||
|
const index = flat().findIndex((x) => isDeepEqual(x.value, option.value))
|
||||||
|
if (index === -1) return
|
||||||
|
moveTo(index)
|
||||||
|
}}
|
||||||
|
onMouseDown={() => {
|
||||||
|
const index = flat().findIndex((x) => isDeepEqual(x.value, option.value))
|
||||||
|
if (index === -1) return
|
||||||
|
moveTo(index)
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Show when={!current() && option.margin}>
|
<box
|
||||||
<box position="absolute" left={1} flexShrink={0}>
|
flexDirection="row"
|
||||||
{option.margin}
|
paddingLeft={current() || option.gutter ? 1 : 3}
|
||||||
</box>
|
paddingRight={3}
|
||||||
</Show>
|
gap={1}
|
||||||
<Option
|
backgroundColor={active() ? (option.bg ?? theme.primary) : RGBA.fromInts(0, 0, 0, 0)}
|
||||||
title={option.title}
|
>
|
||||||
footer={flatten() ? (option.category ?? option.footer) : option.footer}
|
<Show when={!current() && option.margin}>
|
||||||
description={option.description !== category ? option.description : undefined}
|
<box position="absolute" left={1} flexShrink={0}>
|
||||||
active={active()}
|
{option.margin}
|
||||||
current={current()}
|
</box>
|
||||||
gutter={option.gutter}
|
</Show>
|
||||||
/>
|
<Option
|
||||||
|
title={option.title}
|
||||||
|
footer={flatten() ? (option.category ?? option.footer) : option.footer}
|
||||||
|
description={option.description !== category ? option.description : undefined}
|
||||||
|
active={active()}
|
||||||
|
current={current()}
|
||||||
|
gutter={option.gutter}
|
||||||
|
/>
|
||||||
|
</box>
|
||||||
|
<For each={option.details}>
|
||||||
|
{(detail) => (
|
||||||
|
<box paddingLeft={3} paddingRight={3}>
|
||||||
|
<text fg={theme.textMuted} wrapMode="none">
|
||||||
|
{Locale.truncateMiddle(detail, Math.max(1, Math.min(76, dimensions().width - 12)))}
|
||||||
|
</text>
|
||||||
|
</box>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
</box>
|
</box>
|
||||||
<For each={option.details}>
|
)
|
||||||
{(detail) => (
|
}}
|
||||||
<box paddingLeft={3} paddingRight={3}>
|
</For>
|
||||||
<text fg={theme.textMuted} wrapMode="none">
|
</>
|
||||||
{Locale.truncateMiddle(detail, Math.max(1, Math.min(76, dimensions().width - 12)))}
|
)}
|
||||||
</text>
|
</For>
|
||||||
</box>
|
</scrollbox>
|
||||||
)}
|
</Show>
|
||||||
</For>
|
</box>
|
||||||
</box>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</For>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</scrollbox>
|
|
||||||
</Show>
|
|
||||||
<Show when={visibleActions().length} fallback={<box flexShrink={0} />}>
|
<Show when={visibleActions().length} fallback={<box flexShrink={0} />}>
|
||||||
<box
|
<box
|
||||||
paddingRight={2}
|
paddingRight={2}
|
||||||
|
|||||||
Reference in New Issue
Block a user