(props: {
api: TuiPluginApi
layout: Layout
mode: () => Layout
pendingPreview: () => boolean
pinned: () => boolean
})
| 182 | } |
| 183 | |
| 184 | function WhichKeyPanel(props: { |
| 185 | api: TuiPluginApi |
| 186 | layout: Layout |
| 187 | mode: () => Layout |
| 188 | pendingPreview: () => boolean |
| 189 | pinned: () => boolean |
| 190 | }) { |
| 191 | const dimensions = useTerminalDimensions() |
| 192 | const [offset, setOffset] = createSignal(0) |
| 193 | const [activeGroup, setActiveGroup] = createSignal<string | undefined>() |
| 194 | const pending = useKeymapSelector((keymap) => keymap.getPendingSequence()) |
| 195 | const active = useKeymapSelector((keymap) => keymap.getActiveKeys({ includeMetadata: true })) |
| 196 | const pendingActive = createMemo(() => pending().length > 0 && active().length > 0) |
| 197 | const pendingAutoVisible = createMemo(() => props.mode() === "overlay" && props.pendingPreview() && pendingActive()) |
| 198 | const visible = createMemo(() => props.pinned() || pendingAutoVisible()) |
| 199 | const pendingMode = createMemo(() => visible() && pendingActive()) |
| 200 | const left = 0 |
| 201 | const width = createMemo(() => Math.max(1, dimensions().width)) |
| 202 | const panelHeight = createMemo(() => |
| 203 | Math.max(MIN_PANEL_HEIGHT, Math.min(MAX_PANEL_HEIGHT, Math.floor(dimensions().height * PANEL_HEIGHT_RATIO))), |
| 204 | ) |
| 205 | const contentWidth = createMemo(() => Math.max(1, width() - 2)) |
| 206 | const columns = createMemo(() => |
| 207 | Math.max(1, Math.min(3, Math.floor((contentWidth() + COLUMN_GAP) / (MAX_COLUMN_WIDTH + COLUMN_GAP)) || 1)), |
| 208 | ) |
| 209 | const entries = createMemo(() => active().map((item) => activeKeyEntry(props.api, item))) |
| 210 | const groups = createMemo(() => grouped(entries())) |
| 211 | const tabsVisible = createMemo(() => !pendingMode() && groups().length > 0) |
| 212 | const headerVisible = createMemo(() => tabsVisible() || pendingMode()) |
| 213 | const footerVisible = createMemo(() => !pendingMode()) |
| 214 | const rows = createMemo(() => |
| 215 | Math.max( |
| 216 | 1, |
| 217 | panelHeight() - |
| 218 | PANEL_TOP_PADDING - |
| 219 | (headerVisible() ? 1 : 0) - |
| 220 | (tabsVisible() ? TAB_CONTENT_GAP : 0) - |
| 221 | (footerVisible() ? FOOTER_MARGIN + FOOTER_HEIGHT : 0), |
| 222 | ), |
| 223 | ) |
| 224 | const pageSize = createMemo(() => rows() * columns()) |
| 225 | const currentGroup = createMemo(() => { |
| 226 | const group = activeGroup() |
| 227 | return groups().find((item) => item.label === group) ?? groups()[0] |
| 228 | }) |
| 229 | const activeEntries = createMemo(() => currentGroup()?.entries ?? []) |
| 230 | const items = createMemo<Item[]>(() => { |
| 231 | if (!pendingMode()) return activeEntries() |
| 232 | return groups().flatMap((group) => [{ type: "group", label: group.label } satisfies GroupHeader, ...group.entries]) |
| 233 | }) |
| 234 | const maxOffset = createMemo(() => Math.max(0, items().length - pageSize())) |
| 235 | const shown = createMemo(() => { |
| 236 | const columnsItems: Item[][] = [] |
| 237 | let index = offset() |
| 238 | for (let column = 0; column < columns() && index < items().length; column++) { |
| 239 | const list: Item[] = [] |
| 240 | while (list.length < rows() && index < items().length) { |
| 241 | list.push(items()[index]!) |
nothing calls this directly
no test coverage detected