Skip to content

Commit 56b338e

Browse files
OpenStaxClaudeRoyEJohnson
authored andcommitted
Phase 4.3: Migrate remaining study guides components to plain CSS
Migrate Filters.tsx and StudyGuides.tsx from styled-components to plain CSS following the hybrid approach documented in PLAIN_CSS_MIGRATION_GUIDE.md. Changes: - Filters.tsx: Migrated StyledColorFilter and RightButtonsWrapper to CSS classes - Created Filters.css with study-guides-color-filter and study-guides-right-buttons classes - Removed styled-components, replaced with className props - StudyGuides.tsx: Migrated nested component styling to CSS descendant selectors - Created StudyGuides.css targeting HighlightsChapterWrapper, HighlightSection, HighlightWrapper - Used :has() selectors to target styled-components by their data-testid attributes - Bound theme.color.neutral.darkest as CSS variable for print styles - Preserved mobile breakpoint and print styles Note: StudyGuidesPopUp.tsx and StudyGuidesToasts.tsx do not require migration as they only use shared components with no study-guides-specific styling. Related to CORE-1830 Snaps/lint css
1 parent 46979c4 commit 56b338e

6 files changed

Lines changed: 208 additions & 215 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* Study Guides Filters Styling */
2+
3+
.study-guides-color-filter {
4+
min-width: 29rem;
5+
}
6+
7+
.study-guides-right-buttons {
8+
margin-left: auto;
9+
display: flex;
10+
align-items: center;
11+
overflow: visible;
12+
}

src/app/content/studyGuides/components/Filters.tsx

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { HighlightColorEnum } from '@openstax/highlighter/dist/api';
22
import flow from 'lodash/fp/flow';
33
import React from 'react';
44
import { connect, useSelector } from 'react-redux';
5-
import styled from 'styled-components/macro';
65
import { loggedOut } from '../../../auth/selectors';
76
import { useServices } from '../../../context/Services';
87
import { AppState, Dispatch } from '../../../types';
@@ -18,6 +17,7 @@ import { printStudyGuides } from '../actions';
1817
import { highlightStyles } from '../constants';
1918
import * as selectors from '../selectors';
2019
import { updateQueryFromFilterChange } from '../utils';
20+
import './Filters.css';
2121

2222
// converting color to a label is based on "i18n:studyguides:popup:filters:remove:color" from messages.json
2323
const createColorDataAnalyticsLabel = (color: HighlightColorEnum): string => {
@@ -48,23 +48,12 @@ const ConnectedChapterFilter = connect(
4848
})
4949
)(ChapterFilter);
5050

51-
const StyledColorFilter = styled(ColorFilter)`
52-
min-width: 29rem;
53-
`;
54-
55-
const RightButtonsWrapper = styled.div`
56-
margin-left: auto;
57-
display: flex;
58-
align-items: center;
59-
overflow: visible;
60-
`;
61-
6251
const ConnectedColorFilter = connect(
6352
(state: AppState) => ({
6453
colorFiltersWithContent: selectors.highlightColorFiltersWithContent(state),
6554
selectedColorFilters: selectors.summaryColorFilters(state),
6655
})
67-
)(StyledColorFilter);
56+
)(ColorFilter);
6857

6958
const ConnectedFilterList = connect(
7059
(state: AppState) => ({
@@ -126,6 +115,7 @@ export default () => {
126115
controlsId='guide-filter-color'
127116
>
128117
<ConnectedColorFilter
118+
className="study-guides-color-filter"
129119
id='guide-filter-color'
130120
disabled={userLoggedOut}
131121
styles={highlightStyles}
@@ -134,9 +124,9 @@ export default () => {
134124
updateQueryFromFilterChange(dispatch, state, { colors: change })}
135125
/>
136126
</FilterDropdown>
137-
<RightButtonsWrapper>
127+
<div className="study-guides-right-buttons">
138128
<ConnectedPrintButton studyGuidesButton />
139-
</RightButtonsWrapper>
129+
</div>
140130
</FiltersTopBar>
141131
{!userLoggedOut && <ConnectedFilterList
142132
className="filters-list"
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/* Study Guides Main Component Styling */
2+
3+
/*
4+
* Note: This component styles nested components from SectionHighlights.tsx
5+
* (HighlightsChapterWrapper, HighlightSection, HighlightWrapper) which are
6+
* styled-components. We target them using descendant selectors based on
7+
* their structure and test-ids.
8+
*/
9+
10+
.study-guides-wrapper {
11+
display: contents;
12+
}
13+
14+
/*
15+
* Mobile styles for HighlightsChapterWrapper
16+
* Target: div containing h2[data-testid="chapter-title"]
17+
*/
18+
@media screen and (max-width: 75em) {
19+
.study-guides-wrapper > div:has(h2[data-testid="chapter-title"]) {
20+
max-width: 90%;
21+
white-space: nowrap;
22+
overflow: hidden;
23+
text-overflow: ellipsis;
24+
}
25+
}
26+
27+
/*
28+
* Mobile styles for HighlightSection
29+
* Target: h3 elements with data-testid="section-title"
30+
*/
31+
@media screen and (max-width: 75em) {
32+
.study-guides-wrapper h3[data-testid="section-title"] {
33+
padding-left: 2rem;
34+
}
35+
}
36+
37+
/* Print styles */
38+
@media print {
39+
/*
40+
* HighlightsChapterWrapper padding
41+
* Target: div containing h2[data-testid="chapter-title"]
42+
*/
43+
.study-guides-wrapper > div:has(h2[data-testid="chapter-title"]) {
44+
padding-left: 0;
45+
}
46+
47+
/*
48+
* HighlightWrapper margin
49+
* Target: divs that don't contain chapter titles (i.e., highlight wrappers)
50+
*/
51+
.study-guides-wrapper > div:not(:has(h2[data-testid="chapter-title"])) {
52+
margin-left: 0;
53+
}
54+
55+
/*
56+
* HighlightsChapterWrapper + HighlightWrapper margin
57+
* Target: div following chapter wrapper
58+
*/
59+
.study-guides-wrapper > div:has(h2[data-testid="chapter-title"]) + div {
60+
margin-top: 0;
61+
}
62+
63+
/*
64+
* HighlightSection background
65+
* Target: h3 elements with data-testid="section-title"
66+
* Uses CSS variable bound from theme in component
67+
*/
68+
.study-guides-wrapper h3[data-testid="section-title"] {
69+
background: var(--section-bg);
70+
}
71+
}

src/app/content/studyGuides/components/StudyGuides.tsx

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,27 @@ import { HTMLElement } from '@openstax/types/lib.dom';
22
import React from 'react';
33
import { FormattedMessage } from 'react-intl';
44
import { useSelector } from 'react-redux';
5-
import styled from 'styled-components/macro';
65
import { typesetMath } from '../../../../helpers/mathjax';
76
import htmlMessage from '../../../components/htmlMessage';
87
import Loader from '../../../components/Loader';
98
import { useServices } from '../../../context/Services';
109
import theme from '../../../theme';
1110
import { assertWindow } from '../../../utils';
12-
import SectionHighlights, {
13-
HighlightsChapterWrapper,
14-
HighlightSection,
15-
HighlightWrapper,
16-
} from '../../components/SectionHighlights';
11+
import SectionHighlights from '../../components/SectionHighlights';
1712
import allImagesLoaded from '../../components/utils/allImagesLoaded';
1813
import { GeneralCenterText } from '../../highlights/components/HighlightStyles';
1914
import HighlightsWrapper from '../../styles/HighlightsWrapper';
2015
import LoaderWrapper from '../../styles/LoaderWrapper';
2116
import * as selectors from '../selectors';
2217
import StudyGuidesListElement from './StudyGuidesListElement';
18+
import './StudyGuides.css';
2319

2420
export const NoStudyGuidesTip = htmlMessage(
2521
'i18n:studyguides:popup:no-highlights-tip',
2622
(props) => <span {...props} />
2723
);
2824

29-
const StudyGuides = ({ className }: { className: string }) => {
25+
const StudyGuides = () => {
3026
const orderedStudyGuides = useSelector(selectors.orderedSummaryStudyGuides);
3127
const isLoading = useSelector(selectors.summaryIsLoading);
3228
const container = React.useRef<HTMLElement>(null);
@@ -40,7 +36,12 @@ const StudyGuides = ({ className }: { className: string }) => {
4036
// eslint-disable-next-line react-hooks/exhaustive-deps
4137
}, [orderedStudyGuides]);
4238

43-
return <div className={className}>
39+
return <div
40+
className="study-guides-wrapper"
41+
style={{
42+
'--section-bg': theme.color.neutral.darkest,
43+
} as React.CSSProperties}
44+
>
4445
{isLoading ? <LoaderWrapper><Loader large /></LoaderWrapper> : null}
4546
{(!isLoading && orderedStudyGuides && orderedStudyGuides.length === 0) ?
4647
<HighlightsWrapper ref={container}>
@@ -68,39 +69,4 @@ const StudyGuides = ({ className }: { className: string }) => {
6869
</div>;
6970
};
7071

71-
export default styled(StudyGuides)`
72-
${HighlightsChapterWrapper} {
73-
${theme.breakpoints.mobile`
74-
max-width: 90%;
75-
white-space: nowrap;
76-
overflow: hidden;
77-
text-overflow: ellipsis;
78-
`}
79-
}
80-
81-
${HighlightSection} {
82-
${theme.breakpoints.mobile`
83-
padding-left: 2rem;
84-
`}
85-
}
86-
87-
@media print {
88-
${HighlightsChapterWrapper} {
89-
padding-left: 0;
90-
91-
& + ${HighlightWrapper} {
92-
margin-top: 0;
93-
}
94-
}
95-
96-
${HighlightWrapper} {
97-
margin-left: 0;
98-
}
99-
100-
${HighlightSection} {
101-
background: ${theme.color.neutral.darkest};
102-
}
103-
}
104-
105-
display: contents;
106-
`;
72+
export default StudyGuides;

0 commit comments

Comments
 (0)