this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: archive keyboard runner controls

+33 -24
-2
components/public-form-runner.test.tsx
··· 126 126 submit: "Submit", 127 127 progressRestored: "Progress restored", 128 128 savedProgressDiscarded: "Saved progress discarded", 129 - chooseOne: "Choose one option.", 130 - selectAll: "Select all that apply.", 131 129 defaultTextTitle: "Take a breath before the next step.", 132 130 openCalendar: "Open calendar", 133 131 },
+6 -18
components/public-form-runner.tsx
··· 823 823 ) : null} 824 824 825 825 <div className="mt-6 space-y-3"> 826 - {currentBlock.type === "SINGLE_CHOICE" ? ( 827 - <p className="text-sm font-medium text-[var(--muted)]"> 828 - {t("publicRunner.chooseOne")} 829 - </p> 830 - ) : null} 831 - 832 - {currentBlock.type === "MULTIPLE_CHOICE" ? ( 833 - <p className="text-sm font-medium text-[var(--muted)]"> 834 - {t("publicRunner.selectAll")} 835 - </p> 836 - ) : null} 837 - 838 826 {currentBlock.type === "SHORT_TEXT" ? ( 839 827 <Input 840 828 ref={setActiveInputNode} ··· 961 949 : null} 962 950 963 951 {currentBlock.type === "SINGLE_CHOICE" ? ( 964 - <div className="grid gap-3"> 952 + <div className="inline-grid min-w-[33%] max-w-full gap-3 px-2 max-md:min-w-full"> 965 953 {(currentBlock.config as ChoiceBlockConfig).options.map( 966 954 (option, index) => { 967 955 const selected = ··· 976 964 aria-pressed={selected} 977 965 aria-keyshortcuts={shortcut ?? undefined} 978 966 className={cn( 979 - "flex items-center justify-between gap-3 rounded-[16px] border px-4 py-3 text-left transition", 967 + "flex w-full max-w-full items-center justify-between gap-3 rounded-[16px] border px-4 py-3 text-left transition", 980 968 selected 981 969 ? "border-[var(--accent)] bg-[var(--accent-soft)] text-[var(--ink)] shadow-[var(--shadow-accent)]" 982 970 : "border-[color:var(--line)] bg-[var(--surface-strong)] text-[var(--ink)] hover:bg-[var(--surface)]", ··· 1008 996 ) : null} 1009 997 1010 998 {currentBlock.type === "MULTIPLE_CHOICE" ? ( 1011 - <div className="grid gap-3"> 999 + <div className="inline-grid min-w-[33%] max-w-full gap-3 px-2 max-md:min-w-full"> 1012 1000 {(currentBlock.config as ChoiceBlockConfig).options.map( 1013 1001 (option, index) => { 1014 1002 const rawValues = answers[currentBlock.id]; ··· 1028 1016 aria-pressed={selected} 1029 1017 aria-keyshortcuts={shortcut ?? undefined} 1030 1018 className={cn( 1031 - "flex items-center justify-between gap-3 rounded-[16px] border px-4 py-3 text-left transition", 1019 + "flex w-full max-w-full items-center justify-between gap-3 rounded-[16px] border px-4 py-3 text-left transition", 1032 1020 selected 1033 1021 ? "border-[var(--accent)] bg-[var(--accent-soft)] text-[var(--ink)] shadow-[var(--shadow-accent)]" 1034 1022 : "border-[color:var(--line)] bg-[var(--surface-strong)] text-[var(--ink)] hover:bg-[var(--surface)]", ··· 1065 1053 ) : null} 1066 1054 1067 1055 {currentBlock.type === "AGREEMENT" ? ( 1068 - <div className="grid gap-3"> 1056 + <div className="inline-grid min-w-[33%] max-w-full gap-3 px-2 max-md:min-w-full"> 1069 1057 {(() => { 1070 1058 const selected = 1071 1059 answers[currentBlock.id] === ··· 1084 1072 aria-pressed={selected} 1085 1073 aria-keyshortcuts="1" 1086 1074 className={cn( 1087 - "flex items-center justify-between gap-3 rounded-[16px] border px-4 py-3 text-left transition", 1075 + "flex w-full max-w-full items-center justify-between gap-3 rounded-[16px] border px-4 py-3 text-left transition", 1088 1076 selected 1089 1077 ? "border-[var(--accent)] bg-[var(--accent-soft)] text-[var(--ink)] shadow-[var(--shadow-accent)]" 1090 1078 : "border-[color:var(--line)] bg-[var(--surface-strong)] text-[var(--ink)] hover:bg-[var(--surface)]",
-2
locales/en.yml
··· 305 305 context: Context 306 306 defaultTextTitle: Take a breath before the next step. 307 307 required: Required 308 - chooseOne: Choose one option. 309 - selectAll: Select all that apply. 310 308 answerRequired: Please answer before continuing. 311 309 singleChoiceRequired: Choose one option before continuing. 312 310 multiChoiceRequired: Choose at least one option before continuing.
-2
locales/ru.yml
··· 305 305 context: Контекст 306 306 defaultTextTitle: Сделайте паузу перед следующим шагом. 307 307 required: Обязательно 308 - chooseOne: Выберите один вариант. 309 - selectAll: Выберите все подходящие варианты. 310 308 answerRequired: Пожалуйста, ответьте перед продолжением. 311 309 singleChoiceRequired: Выберите один вариант перед продолжением. 312 310 multiChoiceRequired: Выберите хотя бы один вариант перед продолжением.
openspec/changes/add-keyboard-form-runner-controls/.openspec.yaml openspec/changes/archive/2026-04-17-add-keyboard-form-runner-controls/.openspec.yaml
openspec/changes/add-keyboard-form-runner-controls/design.md openspec/changes/archive/2026-04-17-add-keyboard-form-runner-controls/design.md
openspec/changes/add-keyboard-form-runner-controls/proposal.md openspec/changes/archive/2026-04-17-add-keyboard-form-runner-controls/proposal.md
openspec/changes/add-keyboard-form-runner-controls/specs/anonymous-form-runner/spec.md openspec/changes/archive/2026-04-17-add-keyboard-form-runner-controls/specs/anonymous-form-runner/spec.md
openspec/changes/add-keyboard-form-runner-controls/tasks.md openspec/changes/archive/2026-04-17-add-keyboard-form-runner-controls/tasks.md
+27
openspec/specs/anonymous-form-runner/spec.md
··· 30 30 - **WHEN** a respondent advances past a step on a form that disables back navigation 31 31 - **THEN** the system does not provide runner navigation that returns them to an earlier visited step 32 32 33 + ### Requirement: Runner supports keyboard-first response entry 34 + The system SHALL support keyboard-first answering for the active step in the public form runner. For single-choice, multiple-choice, and agreement questions, the system SHALL map visible options in display order to digit shortcuts using `1` through `9` and `0` for the tenth visible option when present, and SHALL show respondents that those shortcuts are available. The shortcut affordances for those choice-style actions SHALL remain visible on mobile layouts as well as larger screens. For questions with a primary typed input, the system SHALL focus that input when the step becomes active. Pressing Enter on the active step SHALL advance to the next question or submit on the last step when validation succeeds, and SHALL NOT also toggle or change a choice answer. 35 + 36 + #### Scenario: Respondent selects a single-choice option with a number key 37 + - **WHEN** a respondent is on a single-choice question and presses the digit key for a visible option 38 + - **THEN** the system selects that option as the current answer for the question 39 + 40 + #### Scenario: Respondent toggles a multiple-choice option with a number key 41 + - **WHEN** a respondent is on a multiple-choice question and presses the digit key for a visible option that is already selected 42 + - **THEN** the system removes that option from the current answer for the question 43 + 44 + #### Scenario: Respondent sees that keyboard shortcuts are available 45 + - **WHEN** a respondent views a choice-based question in the public runner 46 + - **THEN** the system shows visible shortcut affordances or helper text indicating which number keys can be used for the available options 47 + 48 + #### Scenario: Respondent sees shortcut hints on mobile 49 + - **WHEN** a respondent views a choice-based question on a mobile layout 50 + - **THEN** the system still shows the shortcut affordances for the available actions instead of hiding them at that viewport size 51 + 52 + #### Scenario: Respondent lands on a text-input question 53 + - **WHEN** a respondent advances to a short text, long text, number, link, or date question 54 + - **THEN** the system focuses the primary input control for that question by default 55 + 56 + #### Scenario: Respondent presses Enter on a choice question 57 + - **WHEN** a respondent presses Enter on an active choice question after making a valid selection 58 + - **THEN** the system advances to the next step or submits on the last step without changing the current choice selection as a side effect 59 + 33 60 ### Requirement: Restored public runner sessions honor the form's back-navigation mode 34 61 The system SHALL restore saved public-runner progress only when the saved route remains valid for the current form, and resumed interaction SHALL honor the form's currently configured back-navigation mode. 35 62