Skip to content

Commit e0394dd

Browse files
rtibblesbotclaude
andcommitted
Align the associate editor with the design spec
Pair rows, cards, chips and pool boxes took colours, padding and copy that diverge from the issue's mockups. Measured against them: - pair rows: grey.v_50 with a fineLine border, cards on surface, 40px tall - chips: 12px each side, 8px before the delete control, tinted only in the distractor pool, where they sit on the surface rather than the tint - pair validation message: aligned to the row's left edge, not indented under the cards - correct-answer chip border: green.v_600, as the sibling editors use - section and button copy taken verbatim from the mockups Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 2c9fff3 commit e0394dd

2 files changed

Lines changed: 72 additions & 24 deletions

File tree

‎contentcuration/contentcuration/frontend/shared/views/QTIEditor/interactions/associate/AssociateInteractionEditor.vue‎

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@
230230
<li
231231
v-for="(choice, index) in state.distractors"
232232
:key="`${choice.id}-${index}`"
233-
:class="isDistractorOpen(index) ? 'distractor-editing' : 'chip'"
233+
:class="isDistractorOpen(index) ? 'distractor-editing' : ['chip', 'is-muted']"
234234
:style="cardStyle(choice.id)"
235235
>
236236
<ClickableRegion
@@ -530,7 +530,7 @@
530530
function poolChipStyle(id) {
531531
const isCorrect = props.showAnswers && pairedIds.value.has(id);
532532
return {
533-
borderColor: isCorrect ? palette.green.v_500 : tokens.fineLine,
533+
borderColor: isCorrect ? palette.green.v_600 : tokens.fineLine,
534534
backgroundColor: isCorrect ? palette.green.v_50 : null,
535535
};
536536
}
@@ -697,15 +697,19 @@
697697
display: grid;
698698
grid-template-areas:
699699
'label cards actions'
700-
'. message .';
700+
'message message message';
701701
grid-template-columns: auto 1fr auto;
702-
gap: 8px;
702+
703+
// Row gap is carried by the message itself: the message track is always
704+
// present, so a gap here would pad every row that has no message.
705+
column-gap: 8px;
703706
align-items: center;
704707
border-radius: 4px;
705708
706709
&.is-editable {
707710
padding: 8px;
708-
background-color: v-bind('$themePalette.grey.v_100');
711+
background-color: v-bind('$themePalette.grey.v_50');
712+
border: 1px solid v-bind('$themeTokens.fineLine');
709713
}
710714
711715
&.is-stacked {
@@ -714,6 +718,10 @@
714718
'cards cards'
715719
'message message';
716720
grid-template-columns: 1fr auto;
721+
722+
.pair-cards {
723+
margin-top: 8px;
724+
}
717725
}
718726
}
719727
@@ -736,9 +744,32 @@
736744
}
737745
}
738746
747+
// A pair card sits on the tinted row, so it carries the surface colour itself,
748+
// and is more compact than the prompt card: the text sits 8px from the border
749+
// rather than at the editor's default 24px inset.
739750
.pair-card {
740751
flex: 1;
741752
min-width: 0;
753+
background-color: v-bind('$themeTokens.surface');
754+
755+
.item-card-text {
756+
padding: 0;
757+
758+
&.is-closed {
759+
min-height: 40px;
760+
761+
// A closed card shows one line, so the editor's paragraph margins would
762+
// only make it taller than the 40px the design gives it.
763+
::v-deep .ProseMirror p {
764+
margin: 0;
765+
margin-block: 0;
766+
}
767+
}
768+
}
769+
770+
::v-deep .editor-content {
771+
padding: 8px;
772+
}
742773
}
743774
744775
.pair-actions {
@@ -749,6 +780,7 @@
749780
750781
.pair-message {
751782
grid-area: message;
783+
margin-top: 8px;
752784
}
753785
754786
.pool-box {
@@ -760,7 +792,7 @@
760792
border-radius: 4px;
761793
762794
&.is-shuffled {
763-
background-color: v-bind('$themePalette.grey.v_100');
795+
background-color: v-bind('$themePalette.grey.v_50');
764796
}
765797
}
766798
@@ -773,16 +805,31 @@
773805
list-style: none;
774806
}
775807
776-
// A chip is a compact pill, so it overrides the editor's own content padding.
808+
// A chip is a compact pill, so it drops the editor's own content padding and
809+
// paragraph margins and sets its own — 12px on each side, 8px before the
810+
// delete control.
777811
.chip {
778812
display: flex;
813+
gap: 8px;
779814
align-items: center;
780-
padding: 0 4px 0 12px;
815+
padding: 4px 12px;
816+
background-color: v-bind('$themeTokens.surface');
781817
border: 1px solid;
782818
border-radius: 4px;
783819
820+
// Chips in the distractor pool sit on the surface, so they are tinted to
821+
// stand out; chips in the shuffled pool sit on the tint, so they are not.
822+
&.is-muted {
823+
background-color: v-bind('$themePalette.grey.v_50');
824+
}
825+
784826
::v-deep .editor-content {
785-
padding: 8px 0;
827+
padding: 0;
828+
}
829+
830+
::v-deep .ProseMirror p {
831+
margin: 0;
832+
margin-block: 0;
786833
}
787834
}
788835

‎contentcuration/contentcuration/frontend/shared/views/QTIEditor/qtiEditorStrings.js‎

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,24 +109,25 @@ export const qtiEditorStrings = createTranslator('QTIEditorStrings', {
109109
context: 'Description for the associate question type in the info modal',
110110
},
111111
correctPairsLabel: {
112-
message: 'Correct pairs',
112+
message: 'Matching pairs',
113113
context: 'Section header above the list of correctly associated pairs',
114114
},
115115
correctPairsDescription: {
116-
message: 'Learners will see all options shuffled together',
117-
context: 'Subtitle under the correct pairs header',
116+
message:
117+
'Learners match responses from a shuffled set to each prompt. Include distractors to increase difficulty.',
118+
context: 'Subtitle under the matching pairs header',
118119
},
119120
distractorsLabel: {
120-
message: 'Additional options',
121-
context: 'Section header above the options that belong to no correct pair',
121+
message: 'Distractors (optional)',
122+
context: 'Section header above the choices that belong to no correct pair',
122123
},
123124
distractorsDescription: {
124-
message: 'Options that are not part of any correct pair',
125-
context: 'Subtitle under the additional options header',
125+
message: "Extra items shown in the response pool that don't match any prompt",
126+
context: 'Subtitle under the distractors header',
126127
},
127128
responsePoolLabel: {
128-
message: 'Options (shuffled)',
129-
context: 'Header above the shuffled pool of options learners will pick from',
129+
message: 'Response pool (shuffled)',
130+
context: 'Header above the shuffled pool of choices learners will pick from',
130131
},
131132
correctAnswersLabel: {
132133
message: 'Answers',
@@ -145,20 +146,20 @@ export const qtiEditorStrings = createTranslator('QTIEditorStrings', {
145146
context: 'Accessible label for the delete icon button next to a pair row',
146147
},
147148
addDistractorBtn: {
148-
message: 'Add option',
149-
context: 'Button that appends a new additional option',
149+
message: 'Add distractor',
150+
context: 'Button that appends a new distractor',
150151
},
151152
deleteDistractorBtn: {
152-
message: 'Delete option {number}',
153-
context: 'Accessible label for the delete icon button on an additional option',
153+
message: 'Delete distractor {number}',
154+
context: 'Accessible label for the delete icon button on a distractor',
154155
},
155156
editPairItemLabel: {
156157
message: 'Edit pair {number}, item {position}',
157158
context: 'Accessible label for the clickable region to edit one item of a pair',
158159
},
159160
editDistractorLabel: {
160-
message: 'Edit option {number}',
161-
context: 'Accessible label for the clickable region to edit an additional option',
161+
message: 'Edit distractor {number}',
162+
context: 'Accessible label for the clickable region to edit a distractor',
162163
},
163164
errorTooFewPairs: {
164165
message: '1 or more valid pairs are required',

0 commit comments

Comments
 (0)