From b3727deef2397dc935196ccd842623d09f697712 Mon Sep 17 00:00:00 2001 From: OpenStaxClaude Date: Mon, 13 Jul 2026 23:10:32 +0000 Subject: [PATCH 1/9] Migrate AssignedTopBar component from styled-components to plain CSS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaced styled-components with plain CSS using CSS variables - Created AssignedTopBar.css with responsive breakpoints - Converted StyledTopBarWrapper to use TopBarWrapper with className - Converted StyledSectionTitle to plain h2 element with className - Used CSS variables for dynamic theme values (colors, heights) - Followed migration patterns from PLAIN_CSS_MIGRATION_LEARNINGS.md - All component logic remains unchanged 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- src/app/content/components/AssignedTopBar.css | 33 ++++++++++++ src/app/content/components/AssignedTopBar.tsx | 50 +++++++------------ 2 files changed, 50 insertions(+), 33 deletions(-) create mode 100644 src/app/content/components/AssignedTopBar.css diff --git a/src/app/content/components/AssignedTopBar.css b/src/app/content/components/AssignedTopBar.css new file mode 100644 index 0000000000..579112fd74 --- /dev/null +++ b/src/app/content/components/AssignedTopBar.css @@ -0,0 +1,33 @@ +/* AssignedTopBar styles */ + +.assigned-topbar-wrapper { + box-shadow: 0 0.2rem 0.2rem 0 rgba(0, 0, 0, 0.14); + top: 0; + background-color: var(--assigned-topbar-bg-color, #f1f1f1); + color: var(--assigned-topbar-text-color, #424242); + display: flex; + height: var(--assigned-topbar-height-desktop, 5rem); +} + +/* Mobile medium breakpoint: max-width: 50em (800px) */ +@media screen and (max-width: 50em) { + .assigned-topbar-wrapper { + height: var(--assigned-topbar-height-mobile, 5.3rem); + } +} + +.assigned-topbar-section-title { + font-size: 1.8rem; + line-height: 2.1rem; + letter-spacing: 0.03px; + margin-left: 1.6rem; +} + +/* Mobile breakpoint: max-width: 75em (1200px) */ +@media screen and (max-width: 75em) { + .assigned-topbar-section-title { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} diff --git a/src/app/content/components/AssignedTopBar.tsx b/src/app/content/components/AssignedTopBar.tsx index fcbab66e05..db90351a2c 100644 --- a/src/app/content/components/AssignedTopBar.tsx +++ b/src/app/content/components/AssignedTopBar.tsx @@ -1,44 +1,17 @@ import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import styled, { css } from 'styled-components'; +import classNames from 'classnames'; import { MessageEvent } from '@openstax/types/lib.dom'; import theme from '../../theme'; import { setTextSize } from '../actions'; import * as selectContent from '../selectors'; import { LinkedArchiveTreeSection } from '../types'; -import { shadow, TopBarWrapper } from './Topbar/styled'; +import { TopBarWrapper } from './Topbar/styled'; import { TextResizer } from './Topbar/TextResizer'; import { topbarDesktopHeight, topbarMobileHeight } from './constants'; import { TextResizerValue, textResizerValues } from '../constants'; import { useLaunchToken } from '../launchToken'; - -const StyledTopBarWrapper = styled(TopBarWrapper)` - ${shadow} - - && { - top: 0; - } - - background-color: ${theme.color.neutral.base}; - color: ${theme.color.text.default}; - display: flex; - height: ${topbarDesktopHeight}rem; - ${theme.breakpoints.mobileMedium(css` - height: ${topbarMobileHeight}rem; - `)} -`; - -const StyledSectionTitle = styled.h2` - font-size: 1.8rem; - line-height: 2.1rem; - letter-spacing: 0.03px; - margin-left: 1.6rem; - ${theme.breakpoints.mobile(css` - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - `)} -`; +import './AssignedTopBar.css'; const useTextResizeIntegration = (handleChange: (value: TextResizerValue) => void) => { const launchToken = useLaunchToken(); @@ -86,8 +59,19 @@ export const AssignedTopBar = (props: { } return ( - - + +

- + ); }; From caabc1694c4540bc34bbf8abc99e5f9284619542 Mon Sep 17 00:00:00 2001 From: OpenStaxClaude Date: Mon, 13 Jul 2026 23:11:20 +0000 Subject: [PATCH 2/9] Migrate BuyBook component from styled-components to plain CSS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit migrates the BuyBook component following the simplified plain CSS migration approach documented in PLAIN_CSS_MIGRATION_LEARNINGS.md. Changes: - Created BuyBook.css with plain CSS styles - Updated BuyBook.tsx to use className instead of styled-components - Used CSS variables for dynamic values (max-width and color) - Applied disablePrintClass for print hiding behavior - Followed established patterns from other migrated components The component maintains identical functionality and styling while removing the styled-components dependency. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- src/app/content/components/BuyBook.css | 28 ++++++++++++ src/app/content/components/BuyBook.tsx | 63 ++++++++++---------------- 2 files changed, 53 insertions(+), 38 deletions(-) create mode 100644 src/app/content/components/BuyBook.css diff --git a/src/app/content/components/BuyBook.css b/src/app/content/components/BuyBook.css new file mode 100644 index 0000000000..9cafac1868 --- /dev/null +++ b/src/app/content/components/BuyBook.css @@ -0,0 +1,28 @@ +/* BuyBook component styles - Plain CSS version */ + +.buy-book-alignment { + width: 100%; + display: flex; + flex-direction: column; + margin: 0 auto; + max-width: var(--buy-book-max-width, 82.5rem); /* contentTextWidth */ + overflow: visible; +} + +.buy-book-link { + /* textRegularSize equivalent */ + font-size: 1.6rem; + line-height: 2.5rem; + + /* Additional link styles */ + font-size: 1.6rem; + display: flex; + align-items: center; + justify-content: center; + text-decoration: none; + height: 5rem; + width: 19rem; + color: var(--buy-book-color, #d4450c); /* theme.color.primary.orange.base */ + border: solid 0.1rem; + font-weight: 700; +} diff --git a/src/app/content/components/BuyBook.tsx b/src/app/content/components/BuyBook.tsx index 1ae0f6e740..eba1802529 100644 --- a/src/app/content/components/BuyBook.tsx +++ b/src/app/content/components/BuyBook.tsx @@ -1,36 +1,12 @@ +import classNames from 'classnames'; import React from 'react'; import { FormattedMessage } from 'react-intl'; -import styled from 'styled-components/macro'; -import { textRegularSize } from '../../components/Typography'; import theme from '../../theme'; import { contentTextWidth } from './constants'; -import { disablePrint } from './utils/disablePrint'; +import { disablePrintClass } from './utils/disablePrint'; import { setUtmCampaign } from '../utils/urlUtils'; import { Book, BookWithOSWebData } from '../types'; - -const BuyBookAlignment = styled.div` - width: 100%; - display: flex; - flex-direction: column; - margin: 0 auto; - max-width: ${contentTextWidth}rem; - overflow: visible; - ${disablePrint} -`; - -const BuyBookLink = styled.a` - ${textRegularSize}; - font-size: 1.6rem; - display: flex; - align-items: center; - justify-content: center; - text-decoration: none; - height: 5rem; - width: 19rem; - color: ${theme.color.primary.orange.base}; - border: solid 0.1rem; - font-weight: 700; -`; +import './BuyBook.css'; const BuyBook = ({book}: {book: Book}) => { const bookWithOSwebData = book as BookWithOSWebData; @@ -38,18 +14,29 @@ const BuyBook = ({book}: {book: Book}) => { if (!bookWithOSwebData.amazon_link) { return null; } - return - - - {(msg) => msg} - - - ; + + + {(msg) => msg} + + + + ); }; export default BuyBook; From f12f9f796b687a87c4dd9371678a14007510b006 Mon Sep 17 00:00:00 2001 From: OpenStaxClaude Date: Mon, 13 Jul 2026 23:12:27 +0000 Subject: [PATCH 3/9] Migrate Attribution component from styled-components to plain CSS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Convert class component to functional component with hooks - Replace connect() HOC with useSelector hook - Create Attribution.css with all component styles - Use CSS variables for dynamic values (theme colors, widths) - Replace styled Summary/Details with plain HTML elements - Implement htmlMessage pattern inline (Content and CodeRunnerNote components) - Maintain all existing functionality: - Auto-scroll on toggle - Close on page navigation - Special attribution for python books - Support for special book IDs - Export named Attribution component for testing - Use classNames package for className composition - Follow patterns from PLAIN_CSS_MIGRATION_LEARNINGS.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- src/app/content/components/Attribution.css | 145 ++++++++++ src/app/content/components/Attribution.tsx | 302 +++++++++++---------- 2 files changed, 298 insertions(+), 149 deletions(-) create mode 100644 src/app/content/components/Attribution.css diff --git a/src/app/content/components/Attribution.css b/src/app/content/components/Attribution.css new file mode 100644 index 0000000000..14ecbed419 --- /dev/null +++ b/src/app/content/components/Attribution.css @@ -0,0 +1,145 @@ +/** + * Attribution Component Styles + * + * Styles for the attribution details section that appears at the bottom of each page. + * Uses CSS variables bound from theme.ts and constants. + */ + +/* Details container */ +.attribution-details { + /* Typography - matches bodyCopyRegularStyle */ + color: var(--attribution-text-color, #424242); + font-size: 1.6rem; + line-height: 2.5rem; + + /* Box styling */ + box-shadow: 0 -1rem 1rem -1rem rgba(0, 0, 0, 0.1); + margin: 3rem 0 0 0; + min-height: 6rem; + + /* Padding - matches wrapperPadding from Layout */ + padding-left: 4rem; + padding-right: 4rem; + padding-top: 1.8rem; +} + +/* Mobile breakpoint - 75em = 1200px (theme.breakpoints.mobile) */ +@media screen and (max-width: 75em) { + .attribution-details { + min-height: 4rem; + padding-left: 1.5rem; + padding-right: 1.5rem; + padding-top: 0.8rem; + } +} + +/* Print media - hide attribution */ +@media print { + .attribution-details { + display: none; + } +} + +/* Summary styles */ +.attribution-summary { + /* Content text width constraint - from contentTextStyle */ + max-width: var(--content-text-width, 80rem); + margin: 0 auto; + + font-weight: 500; + list-style: none; + + /* Spacing */ + margin-bottom: 1.8rem; + + /* Text styling - bodyCopyRegularStyle + decoratedLinkStyle */ + color: var(--attribution-text-color, #424242); + font-size: 1.6rem; + line-height: 2.5rem; +} + +/* Mobile summary spacing */ +@media screen and (max-width: 75em) { + .attribution-summary { + margin-bottom: 0.8rem; + } +} + +/* Remove default summary styling */ +.attribution-summary::before { + display: none; +} + +.attribution-summary::-moz-list-bullet { + list-style-type: none; +} + +.attribution-summary::-webkit-details-marker { + display: none; +} + +/* Summary is clickable */ +.attribution-summary { + cursor: pointer; + color: var(--link-color, #027EB5); + text-decoration: none; +} + +.attribution-summary:hover, +.attribution-summary:focus { + text-decoration: underline; + color: var(--link-hover, #0064A0); +} + +/* Icon styles */ +.attribution-summary-icon { + margin-left: -0.3rem; + height: 1.7rem; + width: 1.7rem; +} + +/* Icon visibility based on open state */ +.attribution-details[open] .attribution-expand-icon { + display: none; +} + +.attribution-details:not([open]) .attribution-collapse-icon { + display: none; +} + +/* Content container */ +.attribution-content { + /* Content text width constraint */ + max-width: var(--content-text-width, 80rem); + margin: 0 auto; +} + +/* Full page width in print */ +@media screen { + .attribution-content { + max-width: var(--content-text-width, 80rem); + margin: 0 auto; + } +} + +/* Content blockquote styling */ +.attribution-content blockquote { + margin-left: 0; +} + +/* List item styling */ +.attribution-details li { + margin-bottom: 1rem; + overflow: visible; +} + +/* Link styling within attribution content */ +.attribution-content a { + color: var(--link-color, #027EB5); + cursor: pointer; + text-decoration: underline; +} + +.attribution-content a:hover { + color: var(--link-hover, #0064A0); +} diff --git a/src/app/content/components/Attribution.tsx b/src/app/content/components/Attribution.tsx index ea25fe165e..e1613ac1e4 100644 --- a/src/app/content/components/Attribution.tsx +++ b/src/app/content/components/Attribution.tsx @@ -1,11 +1,8 @@ import { HTMLDetailsElement } from '@openstax/types/lib.dom'; -import React, { Component } from 'react'; +import React, { useEffect, useRef } from 'react'; import { useIntl } from 'react-intl'; -import { connect } from 'react-redux'; -import styled, { css } from 'styled-components/macro'; -import { CollapseIcon, Details, ExpandIcon, Summary } from '../../components/Details.legacy'; -import { htmlMessage } from '../../components/htmlMessage'; -import { bodyCopyRegularStyle, decoratedLinkStyle, textRegularLineHeight } from '../../components/Typography'; +import { useSelector } from 'react-redux'; +import classNames from 'classnames'; import { scrollTo } from '../../domUtils'; import theme from '../../theme'; import { AppState } from '../../types'; @@ -15,180 +12,187 @@ import * as select from '../selectors'; import { Book, BookWithOSWebData, Page } from '../types'; import { findDefaultBookPage, getBookPageUrlAndParams } from '../utils'; import { splitTitleParts } from '../utils/archiveTreeUtils'; -import { contentTextStyle } from './Page/PageContent.legacy'; import { bookIdsWithSpecialAttributionText, compensateForUTC, getAuthors, getPublishDate } from './utils/attributionValues'; -import { disablePrint } from './utils/disablePrint'; -import { wrapperPadding } from './Wrapper'; +import { ExpandIcon, CollapseIcon } from '../../components/Details'; +import { linkColor, linkHover } from '../../components/Typography/Links.constants'; +import { contentTextWidth } from './constants'; +import './Attribution.css'; -const detailsMarginTop = 3; +export const detailsMarginTop = 3; const desktopSpacing = 1.8; const mobileSpacing = 0.8; +export const textRegularLineHeight = 2.5; export const desktopAttributionHeight = detailsMarginTop + textRegularLineHeight + desktopSpacing * 2; export const mobileAttributionHeight = detailsMarginTop + textRegularLineHeight + mobileSpacing * 2; -const summaryIconStyle = css` - margin-left: -0.3rem; -`; +interface AttributionSummaryProps extends React.HTMLAttributes {} -const SummaryClosedIcon = styled((props) => )` - ${summaryIconStyle} -`; -const SummaryOpenIcon = styled((props) => )` - ${summaryIconStyle} -`; - -const AttributionSummary = styled((props) => { +function AttributionSummary({ className, style, ...props }: AttributionSummaryProps) { const message = useIntl().formatMessage({id: 'i18n:attribution:toggle'}); - return - - - {message} - ; -})` - ${contentTextStyle} - font-weight: 500; - list-style: none; - - &, - span { - ${bodyCopyRegularStyle} - ${decoratedLinkStyle} - } -`; - -const Content = styled.div` - ${contentTextStyle} - - blockquote { - margin-left: 0; - } -`; - -const AttributionDetails = styled(Details)` - ${bodyCopyRegularStyle} - box-shadow: 0 -1rem 1rem -1rem rgba(0, 0, 0, 0.1); - margin: ${detailsMarginTop}rem 0 0 0; - min-height: 6rem; - ${wrapperPadding} - padding-top: ${desktopSpacing}rem; - - > ${AttributionSummary} { - margin-bottom: ${desktopSpacing}rem; - } - - ${theme.breakpoints.mobile(css` - min-height: 4rem; - padding-top: ${mobileSpacing}rem; - - > ${Summary} { - margin-bottom: ${mobileSpacing}rem; - } - `)} + return ( + + + + {message} + + ); +} - li { - margin-bottom: 1rem; - overflow: visible; - } +interface ContentProps extends React.HTMLAttributes { + values?: Record; +} - ${disablePrint} -`; +function Content({ values, className, style, ...props }: ContentProps) { + const html = useIntl().formatMessage({id: 'i18n:attribution:text'}, values, {ignoreTag: true}); + + return ( +
+ ); +} -const AttributionContent = htmlMessage('i18n:attribution:text', Content); -const CodeRunnerNote = htmlMessage('i18n:attribution:code-runner', Content); +function CodeRunnerNote({ className, style, ...props }: React.HTMLAttributes) { + const html = useIntl().formatMessage({id: 'i18n:attribution:code-runner'}, undefined, {ignoreTag: true}); + + return ( +
+ ); +} -interface Props { +interface AttributionProps { book: Book | undefined; page: Page | undefined; } -class Attribution extends Component { - public container = React.createRef(); - private toggleHandler: undefined | (() => void); +function getAttributionValues(book: BookWithOSWebData, page: Page) { + const introPage = findDefaultBookPage(book); + const bookWithoutExplicitVersions = { + ...book, + loadOptions: {booksConfig: book.loadOptions.booksConfig}, + }; + + const [, introTitlePart] = splitTitleParts(introPage.title); + const [, currentTitlePart] = splitTitleParts(page.title); + const introPageTitle = `${introTitlePart} - ${book.title} | OpenStax`; + const introPageUrl = getBookPageUrlAndParams(bookWithoutExplicitVersions, introPage).url; + const currentPageUrl = getBookPageUrlAndParams(bookWithoutExplicitVersions, page).url; + const currentPageTitle = `${currentTitlePart} - ${book.title} | OpenStax`; + + assertNotNull(book.publish_date, `BUG: Could not find publication date`); + const bookPublishDate = getPublishDate(book); + const bookLatestRevision = new Date(book.revised); + + compensateForUTC(bookLatestRevision); + + const authorsToDisplay = getAuthors(book); + + return { + bookAuthors: authorsToDisplay.map(({value: {name}}) => name).join(', '), + bookLatestRevision, + bookLicenseName: book.license.name, + bookLicenseUrl: book.license.url, + bookLicenseVersion: book.license.version, + bookPublishDate, + bookTitle: book.title, + copyrightHolder: 'OpenStax', + currentPath: currentPageUrl, + currentPageTitle, + introPageTitle, + introPageUrl, + originalMaterialLink: null, + ...bookIdsWithSpecialAttributionText[book.id] || {}, + }; +} - public componentDidMount() { - const container = this.container.current; +export function Attribution({ book, page }: AttributionProps) { + const containerRef = useRef(null); + const previousPageRef = useRef(page); + + useEffect(() => { + const container = containerRef.current; if (!container) { return; } - this.toggleHandler = () => container.getAttribute('open') !== null && scrollTo(container); - container.addEventListener('toggle', this.toggleHandler); - } + const toggleHandler = () => { + if (container.getAttribute('open') !== null) { + scrollTo(container); + } + }; - public componentWillUnmount() { - if (!this.container.current || !this.toggleHandler) { - return; - } - this.container.current.removeEventListener('toggle', this.toggleHandler); - } + container.addEventListener('toggle', toggleHandler); + + return () => { + container.removeEventListener('toggle', toggleHandler); + }; + }, []); - public componentDidUpdate(prevProps: Props) { - if (this.container.current && prevProps.page && prevProps.page !== this.props.page) { - this.container.current.removeAttribute('open'); + useEffect(() => { + if (containerRef.current && previousPageRef.current && previousPageRef.current !== page) { + containerRef.current.removeAttribute('open'); } - } + previousPageRef.current = page; + }, [page]); - public render() { - const {book, page} = this.props; + if (!hasOSWebData(book) || !page) { + return null; + } - return hasOSWebData(book) && !!page && - - { - book.slug.includes('python') && - } - ; - } + + {book.slug.includes('python') && ( + + + + )} + + ); +} - private getValues = (book: BookWithOSWebData, page: Page) => { - const introPage = findDefaultBookPage(book); - const bookWithoutExplicitVersions = { - ...book, - loadOptions: {booksConfig: book.loadOptions.booksConfig}, - }; +export default function AttributionConnected() { + const { book, page } = useSelector((state: AppState) => select.bookAndPage(state)); - const [, introTitlePart] = splitTitleParts(introPage.title); - const [, currentTitlePart] = splitTitleParts(page.title); - const introPageTitle = `${introTitlePart} - ${book.title} | OpenStax`; - const introPageUrl = getBookPageUrlAndParams(bookWithoutExplicitVersions, introPage).url; - const currentPageUrl = getBookPageUrlAndParams(bookWithoutExplicitVersions, page).url; - const currentPageTitle = `${currentTitlePart} - ${book.title} | OpenStax`; - - assertNotNull(book.publish_date, `BUG: Could not find publication date`); - const bookPublishDate = getPublishDate(book); - const bookLatestRevision = new Date(book.revised); - - compensateForUTC(bookLatestRevision); - - const authorsToDisplay = getAuthors(book); - - return { - bookAuthors: authorsToDisplay.map(({value: {name}}) => name).join(', '), - bookLatestRevision, - bookLicenseName: book.license.name, - bookLicenseUrl: book.license.url, - bookLicenseVersion: book.license.version, - bookPublishDate, - bookTitle: book.title, - copyrightHolder: 'OpenStax', - currentPath: currentPageUrl, - currentPageTitle, - introPageTitle, - introPageUrl, - originalMaterialLink: null, - ...bookIdsWithSpecialAttributionText[book.id] || {}, - }; - }; + return ; } - -export default connect( - (state: AppState) => ({ - ...select.bookAndPage(state), - }) -)(Attribution); From 206607d48f63c6f501371a30c443b2c71549e0e1 Mon Sep 17 00:00:00 2001 From: OpenStaxClaude Date: Mon, 13 Jul 2026 23:13:58 +0000 Subject: [PATCH 4/9] Migrate Assigned.tsx from styled-components to plain CSS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace styled-components imports with classNames - Convert StyledButton, ToastOverride, and PlatformWrapper to plain React components - Create Assigned.css with corresponding styles - Use CSS variables for dynamic values (contentTextWidth, topbarDesktopHeight, assignedMobileTop) - Convert theme.breakpoints.mobile() to @media query with correct breakpoint (75em) - Maintain all existing functionality and component behavior 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- src/app/content/components/Assigned.css | 32 +++++++++++ src/app/content/components/Assigned.tsx | 76 +++++++++++++++++-------- 2 files changed, 83 insertions(+), 25 deletions(-) create mode 100644 src/app/content/components/Assigned.css diff --git a/src/app/content/components/Assigned.css b/src/app/content/components/Assigned.css new file mode 100644 index 0000000000..4f6b88d4bd --- /dev/null +++ b/src/app/content/components/Assigned.css @@ -0,0 +1,32 @@ +/* Assigned component styling */ + +/* StyledButton - full width button with max-width constraint */ +.assigned-styled-button { + width: 100%; + max-width: var(--content-text-width); + margin: 0 auto; +} + +/* ToastOverride - override layout for Toast component */ +.assigned-toast-override { + top: var(--topbar-desktop-height); + left: 0; + max-width: 100%; +} + +/* Mobile breakpoint for ToastOverride + * IMPORTANT: This breakpoint is derived from theme.breakpoints.mobile() + * which corresponds to max-width: 75em (1200px) + * If theme breakpoints change, this must be updated accordingly. + * The conversion formula is: rems * 10 / 16 = ems (because 1rem = 10px, 1em = 16px in media queries) + */ +@media screen and (max-width: 75em) { + .assigned-toast-override { + top: var(--assigned-mobile-top); + } +} + +/* PlatformWrapper - hide elements with matching data-platform-hidden attribute */ +.platform-wrapper[data-platform="assignable"] [data-platform-hidden="assignable"] { + display: none; +} diff --git a/src/app/content/components/Assigned.tsx b/src/app/content/components/Assigned.tsx index 88c0880c2d..7f8e17b091 100644 --- a/src/app/content/components/Assigned.tsx +++ b/src/app/content/components/Assigned.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; import { useSelector } from 'react-redux'; -import styled, { css } from 'styled-components/macro'; +import classNames from 'classnames'; import AccessibilityButtonsWrapper from '../../components/AccessibilityButtonsWrapper'; import Button from '../../components/Button'; import { useServices } from '../../context/Services'; @@ -21,37 +21,63 @@ import { contentTextWidth } from './constants'; import Page from './Page'; import { PrevNextBar } from './PrevNextBar'; import { getMobileSearchFailureTop } from './Page/PageToasts'; -import theme from '../../theme'; import PageToasts from './Page/PageToasts'; import { topbarDesktopHeight, bookBannerMobileMiniHeight, } from './constants'; +import './Assigned.css'; -const StyledButton = styled(Button)` - width: 100%; - max-width: ${contentTextWidth}rem; - margin: 0 auto; -`; - -// Override layout for Toast -const assignedMobileTop = (props: { mobileToolbarOpen: boolean }) => +// Helper to compute mobile toast top position +const getAssignedMobileTop = (props: { mobileToolbarOpen: boolean }) => getMobileSearchFailureTop(props) - bookBannerMobileMiniHeight; -const ToastOverride = styled(PageToasts)` - top: ${topbarDesktopHeight}rem; - left: 0; - max-width: 100%; - ${theme.breakpoints.mobile(css` - top: ${assignedMobileTop}rem; - `)} -`; - -// tslint:disable-next-line: variable-name -const PlatformWrapper = styled.div<{ platform: string }>` - [data-platform-hidden="${props => props.platform}"] { - display: none; - } -`; + +// StyledButton component - renders Button with assigned-styled-button class +function StyledButton({ className, style, ...props }: React.ComponentProps) { + return ( +
diff --git a/src/app/content/components/Assigned.tsx b/src/app/content/components/Assigned.tsx index 7f8e17b091..2f411725dc 100644 --- a/src/app/content/components/Assigned.tsx +++ b/src/app/content/components/Assigned.tsx @@ -12,6 +12,7 @@ import * as selectNavigation from '../../navigation/selectors'; import { assertString } from '../../utils/assertions'; import { loadPage } from '../hooks/locationChange/resolveContent'; import * as selectContent from '../selectors'; +import { mobileToolbarOpen as mobileToolBarOpenSelector } from '../search/selectors'; import { ArchiveTreeSection, LinkedArchiveTreeSection } from '../types'; import { findTreePages, getPrevNext, nodeMatcher } from '../utils/archiveTreeUtils'; import { stripIdVersion } from '../utils/idUtils'; @@ -47,11 +48,12 @@ function StyledButton({ className, style, ...props }: React.ComponentProps) { +function ToastOverride({ className, style, ...props }: React.ComponentProps) { + const mobileToolbarOpen = useSelector(mobileToolBarOpenSelector); + return ( {} +type AttributionSummaryProps = React.HTMLAttributes; function AttributionSummary({ className, style, ...props }: AttributionSummaryProps) { const message = useIntl().formatMessage({id: 'i18n:attribution:toggle'}); diff --git a/src/app/content/components/BuyBook.tsx b/src/app/content/components/BuyBook.tsx index eba1802529..fc35751fb9 100644 --- a/src/app/content/components/BuyBook.tsx +++ b/src/app/content/components/BuyBook.tsx @@ -24,7 +24,7 @@ const BuyBook = ({book}: {book: Book}) => { div { +.c1 > div { padding: 2rem 2.4rem; outline: none; color: #424242; @@ -35,55 +35,20 @@ exports[`AssignedTopBar renders 1`] = ` justify-content: flex-end; } -.c0 { - box-shadow: 0 0.2rem 0.2rem 0 rgba(0,0,0,0.14); - background-color: #fff; - color: #424242; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - height: 5rem; -} - -.c0.c0 { - top: 0; -} - -.c1 { - font-size: 1.8rem; - line-height: 2.1rem; - -webkit-letter-spacing: 0.03px; - -moz-letter-spacing: 0.03px; - -ms-letter-spacing: 0.03px; - letter-spacing: 0.03px; - margin-left: 1.6rem; -} - @media screen and (max-width:75em) { - .c3 > div { + .c1 > div { padding: 1rem 1.6rem; } } -@media screen and (max-width:50em) { - .c0 { - height: 5.3rem; - } -} - -@media screen and (max-width:75em) { - .c1 { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } -} -