Phase 4.2: Study Guides UI Migration to Plain CSS#2936
Phase 4.2: Study Guides UI Migration to Plain CSS#2936OpenStaxClaude wants to merge 17 commits intomainfrom
Conversation
Start CSS migration for practice questions by migrating ProgressBarItem component from styled-components to plain CSS with hybrid approach. - Created ProgressBarItem.css with plain CSS styles - Converted styled-components to className-based styling - Bind CSS variables from theme for dynamic values - Use classNames library for conditional classes Related to CORE-1703 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Convert QuestionNavigation index from styled-components to plain CSS - Create index.css with wrapper styles and media queries - Remove Button.tsx styled wrapper (no longer needed) - Update SkipAndSubmitButtons to import Button directly from components - Preserve all existing functionality and props - Child components (ShowAnswerButton, NextButton, FinishButton) already use plain Button component 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Migrated the following components from styled-components to plain CSS: - ProgressBar container component (src/app/content/practiceQuestions/components/ProgressBar/index.tsx) - Question component (src/app/content/practiceQuestions/components/Question.tsx) Changes: - Created index.css for ProgressBar container with responsive margin styles - Created Question.css with styles for question wrapper, content, and answers - Updated ProgressBar/index.tsx to use className instead of styled-components - Updated Question.tsx to use CSS classes and CSS variables for theming - Bound CSS variables from theme values for dynamic theming (padding, colors) - Exported QuestionWrapper, QuestionContent, and AnswersWrapper for backward compatibility with tests - Preserved all existing props and functionality Follows the hybrid approach from PLAIN_CSS_MIGRATION_GUIDE.md where theme remains in JavaScript and components bind CSS variables as needed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Migrated IntroScreen.tsx to use plain CSS with IntroScreen.css - Migrated NextSectionMessage.tsx to use plain CSS with NextSectionMessage.css - Migrated FinalScreen.tsx to use plain CSS with FinalScreen.css - Migrated EmptyScreen.tsx to use plain CSS with EmptyScreen.css - Migrated ShowPracticeQuestions.tsx to use plain CSS with ShowPracticeQuestions.css - Migrated Filters.tsx wrapper component to use plain CSS with Filters.css All components now use plain CSS with CSS variables for theming, following the hybrid approach from PLAIN_CSS_MIGRATION_GUIDE.md. Removed styled-components dependencies and converted Typography mixins (textRegularStyle, textRegularSize) to plain CSS equivalents. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove duplicate outline property (line 30-31) - Reorder selectors to fix specificity warnings - Group all hover states together at the end for proper specificity Resolves all 8 stylelint errors: - no-descending-specificity (7 errors) - declaration-block-no-duplicate-properties (1 error) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Question.tsx: - Replace 'any' types with proper TypeScript types - Add QuestionContentProps interface for QuestionContent component - Use React.HTMLAttributes for QuestionWrapper and AnswersWrapper ShowPracticeQuestions.tsx: - Export SectionTitle (alias for MaybeSectionTitle) for backward compatibility - Export QuestionsWrapper and QuestionsHeader for test compatibility - All exports maintain proper TypeScript typing Resolves all TypeScript compilation errors and eslint warnings: - 3 @typescript-eslint/no-explicit-any warnings fixed - 3 TS2614 module export errors fixed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The tests were failing because they were looking for component types (QuestionWrapper, AnswersWrapper, QuestionsWrapper, QuestionsHeader) but the code was using inline JSX elements (<form>, <div>, <h3>). Changes: - Updated Question.tsx to use QuestionWrapper and AnswersWrapper components - Updated QuestionWrapper to be a forwardRef component to support ref prop - Updated ShowPracticeQuestions.tsx to use QuestionsWrapper and QuestionsHeader - Moved wrapper component exports before they are used in the file This fixes all 3 failing test cases: - ShowPracticeQuestions › renders Intro screen - Question › renders all components - Question › renders properly with selected and submitted answer 🤖 Generated with [Claude Code](https://claude.com/claude-code) Update ShowPracticeQuestions.tsx Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fix 5 issues identified by Copilot code review: 1. **Filters.css**: Increased selector specificity to override styled-components - Changed `.practice-questions-chapter-filters` to `.practice-questions-chapter-filters.practice-questions-chapter-filters` - Ensures padding reset always wins over styled-components injection 2. **Question.tsx**: Preserve className prop in wrapper components - Updated QuestionWrapper and AnswersWrapper to merge incoming className with component class - Maintains backward compatibility and composability for tests 3. **ShowPracticeQuestions.css**: Increased specificity for body styles - Changed `.show-practice-questions-body` to `.show-practice-questions-body.show-practice-questions-body` - Ensures overrides win against PopupBody styled-component 4. **ShowPracticeQuestions.css**: Corrected section title typography - Fixed font-size from 2.4rem/3rem to 1.8rem/2.5rem (desktop) - Fixed mobile font-size from unspecified to 1.6rem/2rem - Now matches h4Style from Typography/Headings.legacy.ts as intended 5. **ShowPracticeQuestions.tsx**: Preserve className in wrapper components - Updated QuestionsWrapper and QuestionsHeader to merge className props - Maintains backward compatibility for test usage All changes maintain existing functionality while improving CSS specificity and component composability. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Remove unused classname handling
Migrate initial study guides components from styled-components to plain CSS: ✅ StudyGuidesListElement - Created StudyGuidesListElement.css with responsive and print styles - Bind dynamic highlight border color as CSS variable - Convert mobile breakpoints to standard media queries - Preserve accessibility with hidden-but-accessible class ✅ StudyGuidesCTA - Created StudyGuidesCTA.css for all CTA banner components - Migrate 8 styled components (wrapper, buttons, info, arrows) - Bind theme colors (deep green, text colors) as CSS variables - Preserve print styles (CTA hidden in print) - Deleted styles.tsx file Migration follows the hybrid approach from PLAIN_CSS_MIGRATION_GUIDE.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Migrate ShowStudyGuides.tsx from styled-components to plain CSS: ✅ ShowStudyGuides (StudyGuidesBody) - Created ShowStudyGuides.css with study-guides-specific styling - Replaced styled(PopupBody) with direct PopupBody usage + className - Bind theme background color as CSS variable (--study-guides-bg) - Convert mobile breakpoint to standard media query (max-width: 75em) - Preserve print styles (white background, FiltersList padding) - Export PopupBody as StudyGuidesBody for test compatibility Migration follows the hybrid approach from PLAIN_CSS_MIGRATION_GUIDE.md Related: CORE-1704 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
b2f74c6 to
51f1614
Compare
RoyEJohnson
left a comment
There was a problem hiding this comment.
Can you figure out which is the right color spec, and why two were put in?
Also look at the other errors; if the "important" is needed, we can put a disabling comment in.
src/app/content/studyGuides/components/StudyGuidesListElement.css
36:3 ⚠ Unexpected duplicate "color" declaration-block-no-duplicate-properties
66:38 ✖ Unexpected unknown pseudo-class selector ":global" selector-pseudo-class-no-unknown
src/app/content/studyGuides/components/StudyGuidesCTA/StudyGuidesCTA.css
28:20 ⚠ Unexpected !important declaration-no-important
- Remove duplicate color property in StudyGuidesListElement.css (kept theme.color.text.black as it overrides text.default) - Replace :global() pseudo-class with standard descendant selector (not using CSS Modules, so :global is not supported) - Add stylelint disable comment for !important in print styles (needed to override other display styles in print media) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
@RoyEJohnson I've fixed all the CSS linting errors: Fixed Issues1. Duplicate
|
RoyEJohnson
left a comment
There was a problem hiding this comment.
I think the test needs to be updated to look for the right thing rather than a Styled.STudyGuidesCTAWrapper.
src/app/content/studyGuides/components/StudyGuidesCTA/index.spec.tsx:8:25 - error TS2307: Cannot find module './styles' or its corresponding type declarations.
8 import * as Styled from './styles';
The StudyGuidesCTA component was migrated from styled-components to plain CSS, so the ./styles module no longer exists. Updated the test to query by className 'study-guides-cta-wrapper' instead of the removed Styled.StudyGuidesCTAWrapper component. Resolves TypeScript error: Cannot find module './styles' 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
@RoyEJohnson Fixed the test import error! IssueThe test was importing from import * as Styled from './styles';And then using: expect(() => component.root.findByType(Styled.StudyGuidesCTAWrapper)).toThrow();FixRemoved the styled-components import and updated the test to query by className instead: expect(() => component.root.findByProps({ className: 'study-guides-cta-wrapper' })).toThrow();This matches the migration pattern where The TypeScript compilation error should now be resolved. |
Summary
This PR migrates study guides components from styled-components to plain CSS, following the hybrid approach from
PLAIN_CSS_MIGRATION_GUIDE.md. This is Phase 4.2 of the CSS migration work and builds on top of Phase 4.1 (PR #2932).Progress
✅ Completed:
🚧 In Progress / Remaining:
Migration Approach
theme.tsin JavaScript for type safety and dynamic theme accesstheme.breakpoints.mobileto standard media queries (@media screen and (max-width: 75em))Key Features
Related
PLAIN_CSS_MIGRATION_GUIDE.mdTest Plan
See comprehensive testing guide in the Jira ticket description. Key areas:
🤖 Generated with Claude Code