Skip to content

Commit ae8417a

Browse files
feat(client): add action row with interactive editor toggle to lectures (freeCodeCamp#62928)
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
1 parent 3893532 commit ae8417a

File tree

15 files changed

+287
-171
lines changed

15 files changed

+287
-171
lines changed

client/i18n/locales/english/translations.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,8 @@
523523
"instructions": "Instructions",
524524
"notes": "Notes",
525525
"preview": "Preview",
526-
"editor": "Editor"
526+
"editor": "Editor",
527+
"interactive-editor": "Interactive Editor"
527528
},
528529
"editor-alerts": {
529530
"tab-trapped": "Pressing tab will now insert the tab character",
@@ -952,7 +953,8 @@
952953
"editor-a11y-on-macos": "{{editorName}} editor content. Accessibility mode set to 'on'. Press Command+E to disable or press Option+F1 for more options.",
953954
"editor-a11y-on-non-macos": "{{editorName}} editor content. Accessibility mode set to 'on'. Press Ctrl+E to disable or press Alt+F1 for more options.",
954955
"terminal-output": "Terminal output",
955-
"not-available": "Not available"
956+
"not-available": "Not available",
957+
"interactive-editor-desc": "Turn static code examples into interactive editors. This allows you to edit and run the code directly on the page."
956958
},
957959
"flash": {
958960
"no-email-in-userinfo": "We could not retrieve an email from your chosen provider. Please try another provider or use the 'Continue with Email' option.",

client/src/components/Flash/flash.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ div.flash-message {
1010
padding-bottom: 3px;
1111
position: fixed;
1212
width: 100%;
13-
z-index: 150;
13+
z-index: var(--z-index-flash);
1414
}

client/src/components/Header/components/universal-nav.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
position: absolute;
7474
right: 0;
7575
width: 100%;
76+
z-index: var(--z-index-site-header);
7677
}
7778

7879
@media (min-width: 980px) {

client/src/components/layouts/global.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@ hr {
139139
min-height: 0;
140140
}
141141

142+
.default-layout:has(.breadcrumbs-demo) #learn-app-wrapper {
143+
padding-top: var(--breadcrumbs-height);
144+
}
145+
146+
.default-layout:has(.action-row) #learn-app-wrapper {
147+
padding-top: calc(var(--breadcrumbs-height) + var(--action-row-height));
148+
}
149+
142150
h1 {
143151
color: var(--secondary-color);
144152
font-weight: 700;

client/src/components/layouts/variables.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
--header-sub-element-size: 45px;
3838
--header-height: 38px;
3939
--breadcrumbs-height: 44px;
40+
--action-row-height: 64px;
41+
--z-index-breadcrumbs: 100;
42+
--z-index-flash: 150;
4043
--z-index-site-header: 200;
4144
}
4245

client/src/redux/prop-types.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,12 @@ type ParagraphNodule = {
182182

183183
type InteractiveEditorNodule = {
184184
type: 'interactiveEditor';
185-
data: { ext: Ext; name: string; contents: string }[];
185+
data: {
186+
ext: Ext;
187+
name: string;
188+
contents: string;
189+
contentsHtml: string;
190+
}[];
186191
};
187192

188193
export type ChallengeNode = {

client/src/templates/Challenges/classic/action-row.tsx

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import store from 'store';
66
import { DailyCodingChallengeLanguages } from '../../../redux/prop-types';
77
import EditorTabs from './editor-tabs';
88

9-
interface ActionRowProps {
9+
interface ClassicLayoutProps {
1010
dailyCodingChallengeLanguage: DailyCodingChallengeLanguages;
1111
hasNotes: boolean;
1212
hasPreview: boolean;
@@ -21,24 +21,58 @@ interface ActionRowProps {
2121
showPreviewPane: boolean;
2222
showPreviewPortal: boolean;
2323
togglePane: (pane: string) => void;
24+
hasInteractiveEditor?: never;
2425
}
2526

26-
const ActionRow = ({
27-
hasPreview,
28-
hasNotes,
29-
togglePane,
30-
showNotes,
31-
showPreviewPane,
32-
showPreviewPortal,
33-
showConsole,
34-
showInstructions,
35-
areInstructionsDisplayable,
36-
isDailyCodingChallenge,
37-
dailyCodingChallengeLanguage,
38-
setDailyCodingChallengeLanguage
39-
}: ActionRowProps): JSX.Element => {
27+
interface InteractiveEditorProps {
28+
hasInteractiveEditor: true;
29+
showInteractiveEditor: boolean;
30+
toggleInteractiveEditor: () => void;
31+
}
32+
33+
type ActionRowProps = ClassicLayoutProps | InteractiveEditorProps;
34+
35+
const ActionRow = (props: ActionRowProps): JSX.Element => {
4036
const { t } = useTranslation();
4137

38+
if (props.hasInteractiveEditor) {
39+
const { toggleInteractiveEditor, showInteractiveEditor } = props;
40+
41+
return (
42+
<div className='action-row'>
43+
<div className='tabs-row'>
44+
<div className='tabs-row-right'>
45+
<button
46+
aria-expanded={!!showInteractiveEditor}
47+
aria-describedby='interactive-editor-desc'
48+
onClick={toggleInteractiveEditor}
49+
>
50+
{t('learn.editor-tabs.interactive-editor')}
51+
</button>
52+
<span id='interactive-editor-desc' className='sr-only'>
53+
{t('aria.interactive-editor-desc')}
54+
</span>
55+
</div>
56+
</div>
57+
</div>
58+
);
59+
}
60+
61+
const {
62+
togglePane,
63+
hasPreview,
64+
hasNotes,
65+
areInstructionsDisplayable,
66+
showConsole,
67+
showNotes,
68+
showInstructions,
69+
showPreviewPane,
70+
showPreviewPortal,
71+
isDailyCodingChallenge,
72+
dailyCodingChallengeLanguage,
73+
setDailyCodingChallengeLanguage
74+
} = props;
75+
4276
// sets screen reader text for the two preview buttons
4377
function getPreviewBtnsSrText() {
4478
// no preview open

client/src/templates/Challenges/classic/classic.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,15 @@
1818
}
1919

2020
.action-row {
21+
height: var(--action-row-height);
22+
position: fixed;
23+
top: calc(var(--header-height) + var(--breadcrumbs-height));
24+
left: 0;
25+
right: 0;
26+
z-index: 100;
2127
padding: 10px;
2228
border-bottom: 1px solid var(--quaternary-background);
29+
background-color: var(--secondary-background);
2330
}
2431

2532
.monaco-editor-tabs button[aria-expanded='true'],
@@ -79,6 +86,7 @@
7986
width: 30%;
8087
display: flex;
8188
justify-content: flex-end;
89+
margin-inline-start: auto;
8290
}
8391

8492
.monaco-editor-tabs button + button {

client/src/templates/Challenges/classic/editor.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,16 @@ textarea.inputarea {
3232
}
3333

3434
.breadcrumbs-demo {
35+
position: fixed;
36+
top: var(--header-height);
37+
left: 0;
38+
right: 0;
39+
z-index: var(--z-index-breadcrumbs);
3540
font-size: 16px;
3641
margin: 0;
3742
padding: 10px;
3843
height: var(--breadcrumbs-height);
44+
background: var(--secondary-background);
3945
}
4046

4147
@media screen and (max-height: 300px) {

client/src/templates/Challenges/components/interactive-editor.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
}
2424

2525
.sp-preview-actions .sp-button:hover {
26-
background-color: var(--gray-10);
26+
background-color: var(--gray-10) !important;
2727
color: var(--gray-90) !important;
28-
border-color: var(--gray-90);
28+
border-color: var(--gray-90) !important;
2929
}

0 commit comments

Comments
 (0)