import { MULTI_SUBMIT_LABEL, type MultiSelectViewProps } from "../../view/components/multi-select-view.js"; import type { OptionListViewProps } from "../../view/components/option-list-view.js"; import type { PreviewPaneProps } from "../../view/components/preview/preview-pane.js"; import type { SubmitPickerProps } from "../../view/components/submit-picker.js"; import type { TabBarProps } from "../../view/components/tab-bar.js"; import type { DialogProps } from "../../view/dialog-builder.js"; import { displayLabel } from "../i18n-bridge.js"; import type { GlobalSelector, PerTabSelector } from "./contract.js"; import { selectConfirmedIndicator } from "./derivations.js"; export const selectMultiSelectProps: PerTabSelector = (state, ctx) => { const question = ctx.questions[ctx.i]; if (!question) { return { rows: [], other: { active: false, inputMode: false, inputBuffer: ctx.inputBuffer, inputCursorOffset: ctx.inputCursorOffset, }, nextActive: false, nextLabel: displayLabel("next"), }; } const focused = ctx.activeView === "options"; const rows: { checked: boolean; active: boolean }[] = []; for (let i = 0; i < question.options.length; i++) { rows.push({ checked: state.multiSelectChecked.has(i), active: focused && i === state.optionIndex, }); } const otherActive = focused && state.optionIndex === question.options.length; const nextActive = focused && state.optionIndex === question.options.length + 1; const isLastQuestion = ctx.i === ctx.questions.length - 1; const nextLabel = isLastQuestion ? MULTI_SUBMIT_LABEL : displayLabel("next"); return { rows, other: { active: otherActive, inputMode: state.inputMode, inputBuffer: ctx.inputBuffer, inputCursorOffset: ctx.inputCursorOffset, }, nextActive, nextLabel, }; }; export const selectOptionListProps: PerTabSelector = (state, ctx) => { const items = ctx.itemsByTab[ctx.i] ?? []; const focused = ctx.activeView === "options"; const confirmed = selectConfirmedIndicator(ctx.questions, state.currentTab, state.answers, items); return { selectedIndex: state.optionIndex, focused, inputBuffer: ctx.inputBuffer, inputCursorOffset: ctx.inputCursorOffset, ...(confirmed ? { confirmed } : {}), }; }; export const selectSubmitPickerProps: GlobalSelector = (state, ctx) => { const focused = ctx.activeView === "submit"; return { rows: [ { active: focused && state.submitChoiceIndex === 0 }, { active: focused && state.submitChoiceIndex === 1 }, ], }; }; export const selectPreviewPaneProps: PerTabSelector = (state, ctx) => ({ notesVisible: state.notesVisible, selectedIndex: state.optionIndex, focused: ctx.activeView === "options", inputMode: state.inputMode, }); export const selectTabBarProps: GlobalSelector = (state, ctx) => { const tabs = ctx.questions.map((q, i) => ({ label: q.header && q.header.length > 0 ? q.header : `Q${i + 1}`, answered: state.answers.has(i), active: i === state.currentTab, })); return { tabs, submit: { active: state.currentTab === ctx.questions.length, allAnswered: state.answers.size === ctx.questions.length && ctx.questions.length > 0, }, }; }; export const selectDialogProps: GlobalSelector = (state, ctx) => ({ state, activePreviewPane: ctx.activePreviewPane, });