Skip to content

Commit 475f59e

Browse files
committed
resize content text inside exercise and completion status
1 parent 4db2d9e commit 475f59e

File tree

8 files changed

+101
-48
lines changed

8 files changed

+101
-48
lines changed

src/components/Answer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { colors } from '../theme';
1010
const StyledAnswerIndicator = styled.div<{ state: boolean }>`
1111
color: ${props => props.state ? colors.answer.correct : colors.answer.incorrect};
1212
text-transform: uppercase;
13-
font-size: 1.1rem;
13+
font-size: calc(1.1rem * var(--content-text-scale));
1414
font-weight: bold;
1515
`;
1616

src/components/Card.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ StepCardHeader.displayName = 'StepCardHeader';
145145
const StepCardQuestion = styled.div<{ unpadded?: boolean }>`
146146
.step-card-body {
147147
${mixins.stepCardPadding()}
148-
148+
overflow: auto;
149149
background: ${colors.card.body.background};
150150
151151
&.exercise-stimulus {

src/components/CompletionStatus.tsx

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1-
import styled from "styled-components";
1+
import styled, { createGlobalStyle } from "styled-components";
22
import { InnerStepCard } from "./Card";
33
import Button from "./Button";
44

5+
const GlobalStyle = createGlobalStyle`
6+
:root {
7+
--content-text-scale: 1;
8+
}
9+
`;
10+
511
export interface CompletionStatusProps {
612
numberOfQuestions: number;
713
numberCompleted: number;
@@ -10,8 +16,8 @@ export interface CompletionStatusProps {
1016

1117
const CompletionStatusCard = styled(InnerStepCard)`
1218
padding: 88px 72px;
13-
font-size: 1.8rem;
14-
line-height: 3rem;
19+
font-size: calc(1.8rem * var(--content-text-scale));
20+
line-height: calc(3rem * var(--content-text-scale));
1521
display: block;
1622
1723
button {
@@ -25,27 +31,28 @@ const CompletionStatusCard = styled(InnerStepCard)`
2531
`;
2632

2733
const CompletionHeader = styled.h2`
28-
font-size: 2.4rem;
34+
font-size: calc(2.4rem * var(--content-text-scale));
2935
margin: 0;
3036
`;
3137

32-
export const CompletionStatus = ({
38+
export const CompletionStatus = styled(({
3339
numberOfQuestions, numberCompleted, handleClick
3440
}: CompletionStatusProps) => {
35-
41+
3642
const allCompleted = numberOfQuestions === numberCompleted;
3743
const someCompleted = numberCompleted > 0;
3844
const buttonText = allCompleted ? 'Next' : (
3945
someCompleted ? 'Continue' : 'Start'
4046
);
4147

42-
return (
48+
return <>
49+
<GlobalStyle />
4350
<CompletionStatusCard>
4451
<CompletionHeader>{allCompleted ? 'You are done.' : (someCompleted ? 'Quiz is partially complete.' : 'No questions have been answered.')}</CompletionHeader>
4552
<p>{allCompleted ? 'Great job answering all the questions.' : (someCompleted ? `You've completed ${numberCompleted} of ${numberOfQuestions} questions.` : 'Begin working on the quiz.')}</p>
46-
<Button data-test-id={`${buttonText.split(' ')[0].toLowerCase()}-btn`} onClick={()=> handleClick()}>
53+
<Button data-test-id={`${buttonText.split(' ')[0].toLowerCase()}-btn`} onClick={() => handleClick()}>
4754
{buttonText}
4855
</Button>
4956
</CompletionStatusCard>
50-
)
51-
};
57+
</>
58+
})``;

src/components/Exercise.stories.tsx

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { useState } from 'react';
1+
import React, { useState } from 'react';
22
import { Exercise, ExerciseWithStepDataProps, ExerciseWithQuestionStatesProps } from './Exercise';
33
import { Answer } from '../types';
4+
import styled from 'styled-components';
45

56
const exerciseWithStepDataProps: ExerciseWithStepDataProps = {
67
exercise: {
@@ -131,6 +132,38 @@ const exerciseWithQuestionStatesProps = (): ExerciseWithQuestionStatesProps => {
131132
},
132133
}};
133134

135+
type TextResizerValue = -2 | -1 | 0 | 1 | 2 | 3;
136+
const textResizerScales = [0.75, 0.9, 1, 1.25, 1.5, 2];
137+
const textResizerValues: TextResizerValue[] = [-2, -1, 0, 1, 2, 3];
138+
const textResizerValueMap = new Map(textResizerValues.map((v, i) => [v, textResizerScales[i]]));
139+
140+
const ExerciseWrapper = styled.div<{ textSize: TextResizerValue }>`
141+
${(props: { textSize: TextResizerValue }) => `
142+
--content-text-scale: ${textResizerValueMap.get(props.textSize)};
143+
`}
144+
`;
145+
146+
const TextResizerProvider = ({ children }: { children: React.ReactNode }) => {
147+
const [index, setIndex] = useState(2);
148+
149+
const increase = () => setIndex(Math.min(index + 1, textResizerValues.length - 1));
150+
const decrease = () => setIndex(Math.max(index - 1, 0));
151+
152+
return (
153+
<ExerciseWrapper textSize={textResizerValues[index]}>
154+
<div style={{ marginBottom: '2rem', alignItems: 'center', placeContent: 'center', display: 'flex', gap: '1rem' }}>
155+
<h3>Text Size</h3>
156+
<button onClick={decrease}>- Decrease</button>
157+
<span style={{ display: 'inline-block', width: '3rem', textAlign: 'center' }}>
158+
<b>{textResizerScales[index]}</b>
159+
</span>
160+
<button onClick={increase}>+ Increase</button>
161+
</div>
162+
{children}
163+
</ExerciseWrapper>
164+
);
165+
};
166+
134167
export const Default = () => {
135168
const [selectedAnswerId, setSelectedAnswerId] = useState<number>(0);
136169
const [apiIsPending, setApiIsPending] = useState(false)
@@ -144,7 +177,8 @@ export const Default = () => {
144177
setSelectedAnswerId(a.id)
145178
}}
146179
onAnswerSave={() => setApiIsPending(true)}
147-
/>)
180+
/>
181+
)
148182
};
149183

150184
export const DeprecatedStepData = () => <Exercise {...exerciseWithStepDataProps} />;
@@ -173,7 +207,7 @@ export const CompleteWithFeedback = () => {
173207
}
174208
};
175209

176-
return <Exercise {...props} />;
210+
return <TextResizerProvider><Exercise {...props} /></TextResizerProvider>;
177211
};
178212

179213
export const IncorrectWithFeedbackAndSolution = () => {
@@ -197,7 +231,7 @@ export const IncorrectWithFeedbackAndSolution = () => {
197231
apiIsPending: false
198232
}
199233
};
200-
return <Exercise {...props} />;
234+
return <TextResizerProvider><Exercise {...props} /></TextResizerProvider>;
201235
};
202236

203237
export const IncorrectWithFeedbackAndSolutionWrappingText = () => {
@@ -223,7 +257,7 @@ export const IncorrectWithFeedbackAndSolutionWrappingText = () => {
223257
};
224258
props.exercise.questions[0].answers[0].content_html = 'A very long correct answer to observe line wrapping at mobile sizes';
225259
props.exercise.questions[0].answers[1].content_html = 'A very long incorrect answer to observe line wrapping at mobile sizes';
226-
return <Exercise {...props} />;
260+
return <TextResizerProvider><Exercise {...props} /></TextResizerProvider>;
227261
};
228262

229263
export const MultiPartHalfComplete = () => {
@@ -325,7 +359,7 @@ export const MultiPartHalfComplete = () => {
325359
}
326360
};
327361

328-
return <Exercise {...props} />;
362+
return <TextResizerProvider><Exercise {...props} /></TextResizerProvider>;
329363
};
330364

331365
export const Icons = () => {
@@ -340,22 +374,24 @@ export const Icons = () => {
340374
}
341375
};
342376

343-
return <Exercise
344-
{...exerciseWithQuestionStatesProps()}
345-
exerciseIcons={{
346-
topic: {
347-
url: 'https://openstax.org',
348-
location
349-
},
350-
errata: {
351-
url: 'https://openstax.org',
352-
location
353-
},
354-
info: {
355-
location
356-
},
357-
}}
358-
/>;
377+
return <TextResizerProvider>
378+
<Exercise
379+
{...exerciseWithQuestionStatesProps()}
380+
exerciseIcons={{
381+
topic: {
382+
url: 'https://openstax.org',
383+
location
384+
},
385+
errata: {
386+
url: 'https://openstax.org',
387+
location
388+
},
389+
info: {
390+
location
391+
},
392+
}}
393+
/>
394+
</TextResizerProvider>;
359395
};
360396

361397
export const MathJax = () => {
@@ -506,7 +542,7 @@ bitterness. The discriminant <span data-math="b^2 - 4ac"></span> could perhaps a
506542
};
507543

508544
return (
509-
<>
545+
<TextResizerProvider>
510546
<Exercise {...props1}
511547
onAnswerChange={(a: Omit<Answer, 'id'> & { id: number, question_id: number }) => {
512548
setSelectedAnswerId(a.id)
@@ -516,6 +552,6 @@ bitterness. The discriminant <span data-math="b^2 - 4ac"></span> could perhaps a
516552
}}
517553
/>
518554
<Exercise {...props2} />
519-
</>
555+
</TextResizerProvider>
520556
);
521557
};

src/components/Exercise.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import scrollToElement from 'scroll-to-element';
3-
import styled, { css } from 'styled-components';
3+
import styled, { createGlobalStyle, css } from 'styled-components';
44
import { Answer, ExerciseData, ID, QuestionState, StepBase, StepWithData } from '../../src/types';
55
import { InnerStepCard, OuterStepCard, TaskStepCard, TaskStepCardProps } from './Card';
66
import { Content } from './Content';
@@ -12,8 +12,14 @@ import { ExerciseHeaderIcons } from './ExerciseHeaderIcons';
1212
import { TypesetMathContext } from '../hooks/useTypesetMath';
1313

1414
const StyledTaskStepCard = styled(TaskStepCard)`
15-
font-size: 1.8rem;
16-
line-height: 2.8rem;
15+
font-size: calc(1.8rem * var(--content-text-scale));
16+
line-height: calc(2.8rem * var(--content-text-scale));
17+
`;
18+
19+
const GlobalStyle = createGlobalStyle`
20+
:root {
21+
--content-text-scale: 1;
22+
}
1723
`;
1824

1925
const ToolbarWrapper = styled.div<{
@@ -151,9 +157,9 @@ export interface ExerciseWithQuestionStatesProps extends ExerciseBaseProps {
151157
onAnswerChange: (answer: Omit<Answer, 'id'> & { id: number, question_id: number }) => void;
152158
}
153159

154-
export const Exercise = ({
160+
export const Exercise = styled(({
155161
numberOfQuestions, questionNumber, step, exercise, show_all_feedback, scrollToQuestion, exerciseIcons, ...props
156-
}: ExerciseWithStepDataProps | ExerciseWithQuestionStatesProps) => {
162+
}: { className?: string } & (ExerciseWithStepDataProps | ExerciseWithQuestionStatesProps)) => {
157163
const legacyStepRender = 'feedback_html' in step;
158164
const questionsRef = React.useRef<Array<HTMLDivElement>>([]);
159165
const container = React.useRef<HTMLDivElement>(null);
@@ -175,6 +181,7 @@ export const Exercise = ({
175181
const mobileToolbarEnabled = Object.values(exerciseIcons || {}).some(({ location }) => location?.toolbar?.mobile);
176182

177183
return <TypesetMathContext.Provider value={typesetExercise}>
184+
<GlobalStyle />
178185
<TaskStepCardWithToolbar
179186
step={step}
180187
questionNumber={questionNumber}
@@ -184,6 +191,7 @@ export const Exercise = ({
184191
desktopToolbarEnabled={desktopToolbarEnabled}
185192
mobileToolbarEnabled={mobileToolbarEnabled}
186193
{...(exerciseIcons ? { exerciseIcons: exerciseIcons } : null)}
194+
className={props.className}
187195
>
188196
<div ref={container}>
189197
<Preamble exercise={exercise} />
@@ -217,4 +225,5 @@ export const Exercise = ({
217225
</div>
218226
</TaskStepCardWithToolbar>
219227
</TypesetMathContext.Provider>;
220-
};
228+
})`
229+
`;

src/components/Question.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const StyledQuestion = styled.div`
1313
1414
&.openstax-question {
1515
border-top: 1px solid ${colors.palette.pale};
16-
font-size: 1.8rem;
16+
font-size: calc(1.8rem * var(--content-text-scale));
1717
1818
.detailed-solution {
1919
margin-bottom: 1rem;
@@ -42,8 +42,8 @@ const StyledQuestion = styled.div`
4242
4343
.answers-table {
4444
margin-bottom: 20px;
45-
font-size: 1.6rem;
46-
line-height: 2rem;
45+
font-size: calc(1.6rem * var(--content-text-scale));
46+
line-height: calc(2rem * var(--content-text-scale));
4747
}
4848
4949
.instructions {

src/components/StepCardFooter.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ export const StepCardFooter = styled.div`
66
display: flex;
77
flex-wrap: wrap;
88
justify-content: space-between;
9-
font-size: 1.4rem;
10-
line-height: 2rem;
9+
font-size: calc(1.4rem * var(--content-text-scale));
10+
line-height: calc(2rem * var(--content-text-scale));
1111
background: ${colors.card.body.background};
12+
overflow: auto;
1213
1314
> * {
1415
flex-grow: 1;

src/theme.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ export const mixins = {
208208
margin: calc(${layouts.popover.arrow.height} - 14px) 0 ${layouts.answer.horizontalSpacing} 8px;
209209
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.1);
210210
color: ${colors.palette.neutralThin};
211-
font-size: 1.4rem;
211+
font-size: calc(1.4rem * var(--content-text-scale));
212212
213213
.arrow {
214214
position: absolute;

0 commit comments

Comments
 (0)