diff --git a/packages/docusaurus-playground/src/pages/index.mdx b/packages/docusaurus-playground/src/pages/index.mdx index 2d51c88a..02bc30db 100644 --- a/packages/docusaurus-playground/src/pages/index.mdx +++ b/packages/docusaurus-playground/src/pages/index.mdx @@ -180,102 +180,64 @@ import * as challengesData from '/generated/challenges.json' - - - Read more - - } - > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + & { actions?: React.ReactNode + leftLabel?: string + rightLabel?: string + spacingButtons?: boolean } export const Grid: { Item: typeof GridItem } & React.FC = ({ actions, + leftLabel = '', + rightLabel = '', + spacingButtons = false, children, ...props }) => { @@ -40,12 +46,41 @@ export const Grid: { Item: typeof GridItem } & React.FC = ({
{actions} -
+
- + + {leftLabel.length ? ( + + {leftLabel} + + ) : null} - + + {rightLabel.length ? ( + + {rightLabel} + + ) : null} @@ -64,6 +99,7 @@ type GridBreakpointProps = { cols?: number wrap?: boolean gap?: string | number + scrollButtons?: boolean } const GridRoot = styled.div<{ @@ -79,6 +115,24 @@ const GridRoot = styled.div<{ display: flex; flex-direction: row; gap: 0 1rem; + margin-left: auto; + } + + .mdx-grid__scroll--spacing-buttons { + width: 100%; + + > div { + justify-content: space-between; + width: 100%; + } + + > div > button:not(:last-child) { + border-right: 1px solid rgb(var(--lsd-border-primary)) !important; + } + } + + .mdx-grid__scroll-button { + display: flex; } .mdx-grid__content { @@ -95,7 +149,7 @@ const GridRoot = styled.div<{ gap: 1rem; & > * { - margin-bottom: 2rem; + margin-bottom: 3rem; } } @@ -148,9 +202,38 @@ const GridRoot = styled.div<{ scroll-snap-type: x mandatory; } `} + + ${bp.scrollButtons === false && + css` + .mdx-grid__scroll { + display: none; + } + `} `) })} + ${(props) => + lsdUtils.responsive( + props.theme as any, + 'md', + 'up', + )(css` + .mdx-grid__scroll-button--with-label { + width: auto; + min-width: 83px; + padding: 5px 11px 5px 9px; + gap: 12px; + + &:first-of-type { + justify-content: flex-start; + } + + &:last-of-type { + justify-content: flex-start; + } + } + `)} + ${(props) => lsdUtils.responsive( props.theme as any, @@ -158,7 +241,17 @@ const GridRoot = styled.div<{ 'down', )(css` .mdx-grid__scroll { - display: none !important; + & > div { + justify-content: flex-end; + + > button:not(:last-child) { + border-right: none !important; + } + } + } + + .mdx-grid__scroll-button-label { + display: none; } `)} ` diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/Roadmap/Roadmap.tsx b/packages/logos-docusaurus-theme/src/client/components/mdx/Roadmap/Roadmap.tsx index 9f5b4d12..95921f7c 100644 --- a/packages/logos-docusaurus-theme/src/client/components/mdx/Roadmap/Roadmap.tsx +++ b/packages/logos-docusaurus-theme/src/client/components/mdx/Roadmap/Roadmap.tsx @@ -11,28 +11,67 @@ export type RoadmapProps = Omit< > & { title: React.ReactNode description?: React.ReactNode - alignment?: 'top' | 'bottom' timeline?: Partial[] } export const Roadmap: React.FC = ({ title, description, - alignment = 'bottom', timeline = [], className, children, ...props }) => { + const currentYear = new Date().getFullYear() + + const handleBorderStyle = (item, index, array) => { + if (index === array.length - 1) { + return 'none' + } + + const currentYear = item.period[0] + const nextYear = array[index + 1].period[0] + + if (currentYear === nextYear) { + return 'solid' + } + + return 'dashed' + } + const getCurrentQuarter = () => { + const month = new Date().getMonth() + return 'Q' + Math.ceil((month + 1) / 3) + } + + const handlePeriodStyle = (period: TimelineItemProps['period']) => { + const currentYear = new Date().getFullYear() + const currentQuarter = getCurrentQuarter() + + let year, additional + + if (Array.isArray(period)) { + ;[year, additional] = period + } else { + year = period + } + + if (year < currentYear) { + return 'filled' + } else if (year > currentYear) { + return 'transparent' + } else { + if (!additional || additional === '+') { + return 'filled' + } + if (additional <= currentQuarter) { + return 'filled' + } + return 'transparent' + } + } + return ( -
+
{title} @@ -47,17 +86,20 @@ export const Roadmap: React.FC = ({ {timeline.length > 0 && ( {timeline.map((item, index) => ( diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/TimelineItem/TimelineItem.scss b/packages/logos-docusaurus-theme/src/client/components/mdx/TimelineItem/TimelineItem.scss index a323a79f..1dbc631e 100644 --- a/packages/logos-docusaurus-theme/src/client/components/mdx/TimelineItem/TimelineItem.scss +++ b/packages/logos-docusaurus-theme/src/client/components/mdx/TimelineItem/TimelineItem.scss @@ -3,7 +3,8 @@ .mdx-timeline-item { width: 236px; - height: 100%; + min-height: 306px; + justify-content: space-between; gap: 1rem; flex: 0 0 auto; display: flex; @@ -45,8 +46,18 @@ padding: 3px 12px; display: inline-block; border-radius: 10rem; +} + +.mdx-timeline-item__period--filled { color: rgb(var(--lsd-text-secondary)) !important; background-color: rgb(var(--lsd-surface-secondary)); + border: 1px solid rgb(var(--lsd-border-secondary)); +} + +.mdx-timeline-item__period--transparent { + color: rgb(var(--lsd-text-primary)) !important; + background-color: rgb(var(--lsd-surface-primary)); + border: 1px solid rgb(var(--lsd-border-primary)); } .mdx-timeline-item__item:last-child { @@ -55,12 +66,8 @@ } } -.mdx-timeline-item--top-aligned { -} - -.mdx-timeline-item--bottom-aligned { - min-height: 308px; - justify-content: space-between; +.mdx-timeline-item__description { + margin-top: auto; } @include utils.responsive('lg', 'down') { diff --git a/packages/logos-docusaurus-theme/src/client/components/mdx/TimelineItem/TimelineItem.tsx b/packages/logos-docusaurus-theme/src/client/components/mdx/TimelineItem/TimelineItem.tsx index 76d8ddda..c19f8af7 100644 --- a/packages/logos-docusaurus-theme/src/client/components/mdx/TimelineItem/TimelineItem.tsx +++ b/packages/logos-docusaurus-theme/src/client/components/mdx/TimelineItem/TimelineItem.tsx @@ -9,14 +9,32 @@ export type TimelineItemProps = Omit< > & { /** The index or label of the timeline item. */ index: React.ReactNode - /** The alignment of the timeline item, either 'top' or 'bottom'. (Optional, default: 'top') */ - alignment?: 'top' | 'bottom' /** The period or time frame associated with the timeline item. e.g., `2023 Q3` */ - period: React.ReactNode + period: [number, 'Q1' | 'Q2' | 'Q3' | 'Q4' | '+'] | number /** The description or content of the timeline item. */ description: React.ReactNode /** The border style for the timeline item */ borderStyle?: 'solid' | 'dashed' | 'none' + /** The period style for the timeline item */ + periodStyle?: 'transparent' | 'filled' +} + +const formatPeriod = (input: TimelineItemProps['period']) => { + if (Array.isArray(input) && input.length > 0) { + let result = input[0].toString() + + if (input.length > 1) { + if (input[1] === '+') { + result += '+' + } else { + result += ' ' + input[1] + } + } + + return result + } else { + return '' + } } /** @@ -65,12 +83,13 @@ export type TimelineItemProps = Omit< * * ``` */ + export const TimelineItem: React.FC = ({ index, period, description, - alignment = 'top', borderStyle, + periodStyle, className, children, ...props @@ -80,7 +99,6 @@ export const TimelineItem: React.FC = ({ className={clsx( className, 'mdx-timeline-item', - `mdx-timeline-item--${alignment}-aligned`, borderStyle === 'dashed' && 'mdx-timeline-item--border-dashed', )} {...props} @@ -93,9 +111,12 @@ export const TimelineItem: React.FC = ({ - {period} + {formatPeriod(period)}