Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 145 additions & 37 deletions apps/storybook/stories/Grid.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ export const BasicWithBoxes: Story = {

/**
* Magazine-style 12-column grid - Editorial Artsy Portfolio
* Fully responsive: stacked on mobile, 2-column on tablet, 12-column on desktop
*/
export const MagazineLayout: Story = {
args: {
Expand All @@ -338,9 +339,20 @@ export const MagazineLayout: Story = {
gap: 0,
},
render: (args) => (
<Grid {...args} css={{ bg: "white", p: "32 16" }}>
<Grid
{...args}
css={{
bg: "white",
p: { base: "16 4", md: "24 8", lg: "32 16" },
overflowX: "hidden",
}}
>
{/* Hero Image - Breathe */}
<GridItem colSpan={8} colStart={3}>
<GridItem
css={{
gridColumn: { base: "1 / -1", md: "2 / -2", lg: "3 / 11" },
}}
>
<Image
src="https://a.storyblok.com/f/281211/5000x2400/609e58d1fb/outlet-store_slideshow-1.jpg/m/2000x1125/smart/filters:quality(75)"
alt="Outlet Store Hero"
Expand All @@ -349,8 +361,17 @@ export const MagazineLayout: Story = {
</GridItem>

{/* Title - Generous spacing */}
<GridItem colSpan={6} colStart={4}>
<Box css={{ mt: "40", mb: "40" }}>
<GridItem
css={{
gridColumn: { base: "1 / -1", md: "2 / -2", lg: "4 / 10" },
}}
>
<Box
css={{
mt: { base: "8", md: "16", lg: "40" },
mb: { base: "8", md: "16", lg: "40" },
}}
>
<Box
css={{
fontSize: "xs",
Expand All @@ -363,16 +384,24 @@ export const MagazineLayout: Story = {
</Box>
<Headline
level={2}
css={{ fontSize: "3rem", lineHeight: 1.1, fontWeight: 700 }}
css={{
fontSize: { base: "2rem", md: "2.5rem", lg: "3rem" },
lineHeight: 1.1,
fontWeight: 700,
}}
>
⋆.˚ ᡣ𐭩 Creative Direction
</Headline>
</Box>
</GridItem>

{/* Large Portrait Left */}
<GridItem colSpan={5} colStart={2}>
<Box css={{ mt: "20" }}>
<GridItem
css={{
gridColumn: { base: "1 / -1", md: "1 / 7", lg: "2 / 7" },
}}
>
<Box css={{ mt: { base: "0", md: "8", lg: "20" } }}>
<Image
src="https://a.storyblok.com/f/281211/1500x2000/e04c56fe25/2024_10_11_klosterkirche_nordshausen_time_this_wild_beast_in_the_jungle_0225.jpg/m/2000x1125/smart/filters:quality(75)"
alt="Portrait"
Expand All @@ -382,8 +411,12 @@ export const MagazineLayout: Story = {
</GridItem>

{/* Small Square Top Right */}
<GridItem colSpan={3} colStart={9}>
<Box css={{ mt: "48" }}>
<GridItem
css={{
gridColumn: { base: "1 / -1", md: "7 / -1", lg: "9 / 12" },
}}
>
<Box css={{ mt: { base: "8", md: "16", lg: "48" } }}>
<Image
src="https://a.storyblok.com/f/281211/5000x2400/7de0835b62/outlet-store_slideshow-2.jpg/m/2000x1125/smart/filters:quality(75)"
alt="Outlet Store Detail"
Expand All @@ -393,8 +426,17 @@ export const MagazineLayout: Story = {
</GridItem>

{/* Text Block Float */}
<GridItem colSpan={3} colStart={9}>
<Box css={{ mt: "20", pr: "8" }}>
<GridItem
css={{
gridColumn: { base: "1 / -1", md: "7 / -1", lg: "9 / 12" },
}}
>
<Box
css={{
mt: { base: "4", md: "8", lg: "20" },
pr: { base: "0", lg: "8" },
}}
>
<Paragraph css={{ fontSize: "sm", lineHeight: 2, opacity: 0.7 }}>
🎀 ୧ꔛꗃ˖ Embracing the space between elements creates rhythm and
allows each piece to breathe ・゚⋆
Expand All @@ -403,8 +445,17 @@ export const MagazineLayout: Story = {
</GridItem>

{/* Wide Image Center */}
<GridItem colSpan={10} colStart={2}>
<Box css={{ mt: "64", mb: "64" }}>
<GridItem
css={{
gridColumn: { base: "1 / -1", md: "1 / -1", lg: "2 / 12" },
}}
>
<Box
css={{
mt: { base: "12", md: "24", lg: "64" },
mb: { base: "12", md: "24", lg: "64" },
}}
>
<Image
src="https://a.storyblok.com/f/281211/5000x2400/92dcf912ab/outlet-store_slideshow-3.jpg/m/2000x1125/smart/filters:quality(75)"
alt="Outlet Store Wide"
Expand All @@ -414,12 +465,16 @@ export const MagazineLayout: Story = {
</GridItem>

{/* Quote - Minimal */}
<GridItem colSpan={6} colStart={4}>
<Box css={{ mb: "56" }}>
<GridItem
css={{
gridColumn: { base: "1 / -1", md: "2 / -2", lg: "4 / 10" },
}}
>
<Box css={{ mb: { base: "12", md: "24", lg: "56" } }}>
<Headline
level={3}
css={{
fontSize: "2rem",
fontSize: { base: "1.5rem", md: "1.75rem", lg: "2rem" },
lineHeight: 1.3,
fontWeight: 600,
textAlign: "center",
Expand All @@ -431,16 +486,24 @@ export const MagazineLayout: Story = {
</GridItem>

{/* Two Images Offset */}
<GridItem colSpan={4} colStart={2}>
<GridItem
css={{
gridColumn: { base: "1 / -1", md: "1 / 7", lg: "2 / 6" },
}}
>
<Image
src="https://a.storyblok.com/f/281211/2000x1500/bff231d512/2024_10_11_klosterkirche_nordshausen_time_this_wild_beast_in_the_jungle_0215.jpg/m/2000x1125/smart/filters:quality(75)"
alt="Left"
aspectRatio="4/5"
/>
</GridItem>

<GridItem colSpan={4} colStart={8}>
<Box css={{ mt: "32" }}>
<GridItem
css={{
gridColumn: { base: "1 / -1", md: "7 / -1", lg: "8 / 12" },
}}
>
<Box css={{ mt: { base: "8", md: "0", lg: "32" } }}>
<Image
src="https://a.storyblok.com/f/281211/5120x2880/a1811c6510/video-still-1.png/m/2000x1125/smart/filters:quality(75)"
alt="Right"
Expand All @@ -449,20 +512,44 @@ export const MagazineLayout: Story = {
</Box>
</GridItem>

{/* Small Detail Right */}
<GridItem colSpan={3} colStart={9}>
<Box css={{ mt: "48" }}>
<Image
src="https://a.storyblok.com/f/281211/5120x2880/89c84d7bcc/video-still-2.png/m/2000x1125/smart/filters:quality(75)"
alt="Small detail"
aspectRatio="4/3"
/>
{/* Small Detail Right - Full Bleed */}
<GridItem
css={{
gridColumn: { base: "1 / -1", md: "7 / -1", lg: "10 / 13" },
}}
>
<Box
css={{
mt: { base: "8", md: "12", lg: "48" },
position: "relative",
}}
>
<Box
css={{
position: { base: "relative", lg: "relative" },
left: { base: "0", lg: "50%" },
right: { base: "0", lg: "50%" },
marginLeft: { base: "0", lg: "-50vw" },
marginRight: { base: "0", lg: "-50vw" },
width: { base: "100%", lg: "100vw" },
}}
>
<Image
src="https://a.storyblok.com/f/281211/5120x2880/89c84d7bcc/video-still-2.png/m/2000x1125/smart/filters:quality(75)"
alt="Small detail"
aspectRatio="4/3"
/>
</Box>
</Box>
</GridItem>

{/* Closing Image Full Bleed */}
<GridItem colSpan={12}>
<Box css={{ mt: "80" }}>
<GridItem
css={{
gridColumn: { base: "1 / -1", md: "1 / -1", lg: "1 / -1" },
}}
>
<Box css={{ mt: { base: "12", md: "24", lg: "80" } }}>
<Image
src="https://a.storyblok.com/f/281211/5120x2880/075de8f14e/video-still-3.png/m/2000x1125/smart/filters:quality(75)"
alt="Closing"
Expand All @@ -472,8 +559,18 @@ export const MagazineLayout: Story = {
</GridItem>

{/* Footer Details */}
<GridItem colSpan={8} colStart={3}>
<Box css={{ mt: "40", mb: "20", textAlign: "center" }}>
<GridItem
css={{
gridColumn: { base: "1 / -1", md: "2 / -2", lg: "3 / 11" },
}}
>
<Box
css={{
mt: { base: "8", md: "16", lg: "40" },
mb: { base: "8", md: "12", lg: "20" },
textAlign: "center",
}}
>
<Box
css={{
fontSize: "xs",
Expand All @@ -491,12 +588,23 @@ export const MagazineLayout: Story = {
</GridItem>

{/* Wide Image - Bottom */}
<GridItem colSpan={9} colStart={2} css={{ mt: "24", mb: "16" }}>
<Image
src="https://a.storyblok.com/f/281211/5120x2880/a1811c6510/video-still-1.png/m/2000x1125/smart/filters:quality(75)"
alt="Wide Shot"
aspectRatio="21/9"
/>
<GridItem
css={{
gridColumn: { base: "1 / -1", md: "1 / -1", lg: "2 / 11" },
}}
>
<Box
css={{
mt: { base: "8", md: "12", lg: "24" },
mb: { base: "8", md: "12", lg: "16" },
}}
>
<Image
src="https://a.storyblok.com/f/281211/5120x2880/a1811c6510/video-still-1.png/m/2000x1125/smart/filters:quality(75)"
alt="Wide Shot"
aspectRatio="21/9"
/>
</Box>
</GridItem>
</Grid>
),
Expand Down
46 changes: 37 additions & 9 deletions packages/storyblok-richtext/src/richtext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,26 +114,36 @@ function MarkCode(children: ReactNode) {
*/
function NodeHeading(children: ReactNode, props: any) {
const level = props.level as 1 | 2 | 3;
const textAlign = props.textAlign;
return (
<Headline level={level} marginTop="6" marginBottom="3">
<Headline level={level} marginTop="6" marginBottom="3" css={{ textAlign }}>
{children}
</Headline>
);
}

/**
* Custom resolver for paragraphs
* Accepts maxWidth from context for dynamic prose width
* Filters out empty paragraphs to avoid unnecessary spacing
* Accepts maxWidth from context and textAlign from node attributes
* Spacing is controlled via CSS on the parent container
*/
function NodeParagraph(
children: ReactNode,
_props: any,
context?: { maxWidth?: string | boolean },
props: any,
context?: {
maxWidth?: string | boolean;
},
) {
const maxWidth = context?.maxWidth ?? true;
const textAlign = props.textAlign as
| "left"
| "center"
| "right"
| "justify"
| undefined;

return (
<Paragraph maxWidth={maxWidth} spacing>
<Paragraph maxWidth={maxWidth} align={textAlign}>
{children}
</Paragraph>
);
Expand Down Expand Up @@ -164,7 +174,11 @@ function NodeImage(_children: ReactNode, props: any) {
* Custom resolver for unordered lists
*/
function NodeUL(children: ReactNode) {
return <UnorderedList>{children}</UnorderedList>;
return (
<UnorderedList listStyle="disc" spacing="2">
{children}
</UnorderedList>
);
}

/**
Expand Down Expand Up @@ -252,7 +266,9 @@ function DefaultBlokResolver(_name: string, _props: any) {
*/
export function renderStoryblokRichText(
data: ISbRichtext,
options?: { maxWidth?: string | boolean },
options?: {
maxWidth?: string | boolean;
},
) {
if (!data) {
return null;
Expand Down Expand Up @@ -308,5 +324,17 @@ export function StoryblokRichText({

const content = renderStoryblokRichText(data, { maxWidth });

return <Box {...props}>{content}</Box>;
return (
<Box
css={{
/* Add spacing between consecutive paragraphs */
"& > p + p": {
mt: "4",
},
}}
{...props}
>
{content}
</Box>
);
}
Loading
Loading