Skip to content

Commit

Permalink
Container and Section
Browse files Browse the repository at this point in the history
  • Loading branch information
gbalint committed May 29, 2024
1 parent e314079 commit eff89a5
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 97 deletions.
2 changes: 1 addition & 1 deletion app/components/Layout.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React from 'react';
import {Await} from '@remix-run/react';
import {Suspense} from 'react';
import {Aside} from '~/components/Aside';
Expand Down
135 changes: 47 additions & 88 deletions app/routes/products.$handle/sections/reviews.jsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import {
Container,
Flex,
Section,
MultiColumn,
Spacer,
} from '@h2/new/Layout'
import { Heading, Span, Strong, Text } from '@h2/new/Text'
import { Button } from '@h2/new/Button'
import { cva, cx } from '@h2/new/utils'
import { Placeholder } from 'utopia-api'
import * as React from 'react'
import { Star } from '/app/components/Star'
import {Container, Flex, Section, MultiColumn, Spacer} from '@h2/new/Layout';
import {Heading, Span, Strong, Text} from '@h2/new/Text';
import {Button} from '@h2/new/Button';
import {cva, cx} from '@h2/new/utils';
import {Placeholder} from 'utopia-api';
import * as React from 'react';
import {Star} from '/app/components/Star';

const reviews = [
{
Expand Down Expand Up @@ -49,36 +43,34 @@ const reviews = [
'The perfect blend of functionality and fashion. I take it to work, on weekend getaways, and even to the gym. It’s a must-have for any builder!',
customer: 'Sarah M.',
},
]
];

export default function Reviews({ data = reviews }) {
export default function Reviews({data = reviews}) {
return (
<Section>
<Container as='header' className='py-56 -mb-[26rem]'>
<Flex direction='down' gap={8}>
<Heading size='6xl'>
Don’t take our word for it
</Heading>
<Flex direction='down' gap={6}>
<Text size='2xl' weight='medium'>
<Container as="header" paddingY="l" marginBottom>
<Flex direction="down" gap={8}>
<Heading size="6xl">Don’t take our word for it</Heading>
<Flex direction="down" gap={6}>
<Text size="2xl" weight="medium">
<Star />
4.8
<Span transparent>&mdash; 385 Reviews</Span>
</Text>
<Button color='accent'>View all reviews</Button>
<Button color="accent">View all reviews</Button>
</Flex>
</Flex>
</Container>
<Container className='pb-16'>
<Container paddingBottom={'s'}>
<MultiColumn columns={2} gap maxWidth>
<Spacer height={144} />
{data.map((review) => {
return <Review key={review.id} data={review} />
return <Review key={review.id} data={review} />;
})}
</MultiColumn>
</Container>
</Section>
)
);
}

const review = cva({
Expand All @@ -93,107 +85,74 @@ const review = cva({
defaultVariants: {
background: 'white',
},
})
});

export function Review({ data, className, ...props }) {
const { id, quote, customer } = data
export function Review({data, className, ...props}) {
const {id, quote, customer} = data;

// hack so we have a background from data.id
const moduloId = (parseInt(id) - 1) % 6
const moduloId = (parseInt(id) - 1) % 6;
const background =
props.background ??
(moduloId === 1
? 'black'
: moduloId === 5
? 'accent'
: 'white')
(moduloId === 1 ? 'black' : moduloId === 5 ? 'accent' : 'white');

const classes = cx(
review({ ...props, background }),
className,
)
const { firstSentence, remainingText } =
splitTextIntoSentences(quote)
const classes = cx(review({...props, background}), className);
const {firstSentence, remainingText} = splitTextIntoSentences(quote);

console.log(background)
console.log(background);
return (
<div className='relative inline-block'>
<Flex
px={7}
py={6}
direction='down'
gap={5}
className={classes}
>
<span
className={`${
background === 'black' && 'text-accent'
}`}
>
<div className="relative inline-block">
<Flex px={7} py={6} direction="down" gap={5} className={classes}>
<span className={`${background === 'black' && 'text-accent'}`}>
{background === 'black' && (
<span className='absolute top-0 left-0 w-6 bg-white aspect-square' />
<span className="absolute top-0 left-0 w-6 bg-white aspect-square" />
)}
<IconQuote />
</span>
<Text>
<Strong
color={
background === 'black' ? 'white' : 'text'
}
>
<Strong color={background === 'black' ? 'white' : 'text'}>
{firstSentence}
</Strong>{' '}
<Span
color={
background === 'black' ? 'white' : 'black'
}
className='opacity-70'
color={background === 'black' ? 'white' : 'black'}
className="opacity-70"
>
{remainingText}
</Span>
</Text>
<Text
weight='medium'
className={
background === 'black' && 'text-accent'
}
weight="medium"
className={background === 'black' && 'text-accent'}
>
&mdash;{customer}
</Text>
</Flex>
</div>
)
);
}

function splitTextIntoSentences(text) {
const regex = /([.!?]\s+)(?=[A-Z"'\s])/
const regex = /([.!?]\s+)(?=[A-Z"'\s])/;

const splitIndex = text.search(regex)
const splitIndex = text.search(regex);

if (splitIndex === -1) {
return { firstSentence: text, remainingText: '' }
return {firstSentence: text, remainingText: ''};
}

const endIndex =
splitIndex +
text.slice(splitIndex).match(regex)[0].length
const endIndex = splitIndex + text.slice(splitIndex).match(regex)[0].length;

const firstSentence = text.substring(0, endIndex)
const remainingText = text.substring(endIndex).trim()
const firstSentence = text.substring(0, endIndex);
const remainingText = text.substring(endIndex).trim();

return { firstSentence, remainingText }
return {firstSentence, remainingText};
}

const IconQuote = () => (
<svg
xmlns='http://www.w3.org/2000/svg'
width='42'
height='26'
fill='none'
>
<svg xmlns="http://www.w3.org/2000/svg" width="42" height="26" fill="none">
<path
fill='currentColor'
d='m29 12.5-.2-.2c0-.2-.6-.6-1.4-1.3-.4-.4-.8-1-1-1.8C26 8.4 26 7.7 26 7c0-2 .6-3.4 1.9-4.5A8.7 8.7 0 0 1 33.5 1c5 0 7.6 2 7.6 6 0 1.7-.7 3.2-2 4.5a5.5 5.5 0 0 1-4.4 1.5c-1.8 0-2.7.1-2.7.7 0 .2.3.5.9.8A6 6 0 0 1 35 19c0 2-.7 3.4-2 4.5a7 7 0 0 1-5 1.7l-3.3-.1-1.9-.8c-1-.5-1.7-1.2-2.3-2.2a6 6 0 0 1-.8-3c0-1.6.6-3 1.8-4.1a6.5 6.5 0 0 1 4.6-1.8h1.3c1 0 1.4-.2 1.4-.7Zm-19.4 0-.1-.2L8 11c-.5-.4-.8-1-1-1.8-.3-.8-.5-1.5-.5-2.2 0-2 .7-3.4 2-4.5A8.7 8.7 0 0 1 14.2 1c5 0 7.6 2 7.6 6 0 1.7-.7 3.2-2 4.5a5.5 5.5 0 0 1-4.4 1.5c-1.8 0-2.7.1-2.7.7 0 .2.3.5.9.8.6.5 1 1.1 1.4 2 .4.8.6 1.7.6 2.7 0 1.8-.6 3.3-1.8 4.4a7 7 0 0 1-5 1.7l-3.3-.1c-.8-.2-1.4-.5-2-.8-.9-.5-1.6-1.2-2.2-2.2a6 6 0 0 1-.8-3c0-1.6.6-3 1.8-4.1a6.5 6.5 0 0 1 4.6-1.8h1.3c1 0 1.4-.2 1.4-.7Z'
fill="currentColor"
d="m29 12.5-.2-.2c0-.2-.6-.6-1.4-1.3-.4-.4-.8-1-1-1.8C26 8.4 26 7.7 26 7c0-2 .6-3.4 1.9-4.5A8.7 8.7 0 0 1 33.5 1c5 0 7.6 2 7.6 6 0 1.7-.7 3.2-2 4.5a5.5 5.5 0 0 1-4.4 1.5c-1.8 0-2.7.1-2.7.7 0 .2.3.5.9.8A6 6 0 0 1 35 19c0 2-.7 3.4-2 4.5a7 7 0 0 1-5 1.7l-3.3-.1-1.9-.8c-1-.5-1.7-1.2-2.3-2.2a6 6 0 0 1-.8-3c0-1.6.6-3 1.8-4.1a6.5 6.5 0 0 1 4.6-1.8h1.3c1 0 1.4-.2 1.4-.7Zm-19.4 0-.1-.2L8 11c-.5-.4-.8-1-1-1.8-.3-.8-.5-1.5-.5-2.2 0-2 .7-3.4 2-4.5A8.7 8.7 0 0 1 14.2 1c5 0 7.6 2 7.6 6 0 1.7-.7 3.2-2 4.5a5.5 5.5 0 0 1-4.4 1.5c-1.8 0-2.7.1-2.7.7 0 .2.3.5.9.8.6.5 1 1.1 1.4 2 .4.8.6 1.7.6 2.7 0 1.8-.6 3.3-1.8 4.4a7 7 0 0 1-5 1.7l-3.3-.1c-.8-.2-1.4-.5-2-.8-.9-.5-1.6-1.2-2.2-2.2a6 6 0 0 1-.8-3c0-1.6.6-3 1.8-4.1a6.5 6.5 0 0 1 4.6-1.8h1.3c1 0 1.4-.2 1.4-.7Z"
/>
</svg>
)
);
95 changes: 87 additions & 8 deletions utopia/layout.utopia.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import * as Utopia from 'utopia-api';
import {Background, Flex, MultiColumn, Spacer, Section} from '@h2/new/Layout';
import {
Background,
Flex,
MultiColumn,
Spacer,
Section,
Container,
} from '@h2/new/Layout';

export const BooleanSegmentControl = Utopia.radioControl([
{
Expand Down Expand Up @@ -174,8 +181,8 @@ const annotations = {
component: MultiColumn,
properties: {
columns: Utopia.sliderControl(1, 4, 1),
gap: BooleanSegmentControl,
maxWidth: BooleanSegmentControl,
gap: Utopia.checkboxControl(),
maxWidth: Utopia.checkboxControl(),
},
focus: 'never',
inspector: 'hidden',
Expand Down Expand Up @@ -228,12 +235,84 @@ const annotations = {
},
focus: 'never',
inspector: 'hidden',
children: 'not-supported',
variants: {
label: 'Spacer',
imports: "import { Spacer } from '@h2/new/Layout'",
code: `<Spacer height={144} />`,
variants: [
{
label: 'Section',
imports: "import { Section } from '@h2/new/Layout'",
code: `<Section />`,
},
{
label: 'Section (padded)',
imports: "import { Section } from '@h2/new/Layout'",
code: `<Section padded />`,
},
],
icon: 'dashedframe',
},
Container: {
component: Container,
properties: {
fluid: BooleanSegmentControl,
paddingY: Utopia.radioControl([
{
label: 's',
value: 's',
},
{
label: 'm',
value: 'm',
},
{
label: 'l',
value: 'l',
},
]),
paddingBottom: Utopia.radioControl([
{
label: 's',
value: 's',
},
{
label: 'm',
value: 'm',
},
{
label: 'l',
value: 'l',
},
]),
marginBottom: BooleanSegmentControl,
},
focus: 'never',
inspector: 'hidden',
variants: [
{
label: 'Container with placeholder',
imports: `import { Container } from '@h2/new/Layout'
import { Placeholder } from 'utopia-api'`,
code: `<Container>
<Placeholder />
</Container>`,
},
{
label: 'Container (Review Title)',
imports: `import { Container } from '@h2/new/Layout'
import { Placeholder } from 'utopia-api'`,
code: `<Container as='header' paddingY='l' marginBottom>
<Placeholder />
<Placeholder />
</Container>`,
},
{
label: 'Container (Review Content)',
imports: `import { Container } from '@h2/new/Layout'
import { Placeholder } from 'utopia-api'`,
code: `<Container paddingBottom='s' >
<Placeholder />
<Placeholder />
</Container>`,
},
],
icon: 'dashedframe',
},
};
Expand Down

0 comments on commit eff89a5

Please sign in to comment.