Skip to content

Commit

Permalink
Disp 140/button (#467)
Browse files Browse the repository at this point in the history
* feat(storybook): add experimental themes for rider and driver

* feat(button): add styling

* feat(button): add pressed and focus states

* fix(text): fix typography

* feat(experimental): use rems in spaces

---------

Co-authored-by: Lena Rashkovan <lena.rashkovan@free-now.com>
  • Loading branch information
alatielle and Lena Rashkovan committed Sep 13, 2024
1 parent 6d1cdb3 commit a6afc67
Show file tree
Hide file tree
Showing 11 changed files with 3,519 additions and 74 deletions.
7 changes: 6 additions & 1 deletion .storybook/preview-head.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css?family=Open+Sans:200,300,400,400i,600,600i,700,800" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Roboto+Flex:400,500,600,700" rel="stylesheet" />
<link
href="https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wdth,wght@8..144,50..100,400..700"
rel="stylesheet"
/>
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />

Expand Down
25 changes: 14 additions & 11 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,23 @@ import { LightTheme, DarkTheme } from '../src/docs/storybook-theme/FreenowTheme'

const THEMES = {
classic: ClassicColors,
modern: ModernColors
modern: ModernColors,
'experimental (rider)': createGlobalStyle({
accent: ExperimentalColors.red['50'],
onAccent: ExperimentalColors.neutral['100'],
accentDark: ExperimentalColors.red['60']
}),
'experimental (driver)': createGlobalStyle({
accent: ExperimentalColors.red['30'],
onAccent: ExperimentalColors.neutral['99'],
accentDark: ExperimentalColors.red['90'],
onAccentDark: ExperimentalColors.neutral['10']
})
} as const;

export const withTheme = (Story, context) => {
const { theme } = context.globals;
const Theme =
theme === 'experimental'
? createGlobalStyle({
accent: ExperimentalColors.red['50'],
onAccent: ExperimentalColors.neutral['100'],
accentDark: ExperimentalColors.red['60'],
onAccentDark: ExperimentalColors.neutral['10']
})
: THEMES[theme];
const Theme = THEMES[theme];
return (
<>
<Theme />
Expand Down Expand Up @@ -146,7 +149,7 @@ export const preview: Preview = {
toolbar: {
title: 'Theme',
icon: 'paintbrush',
items: ['modern', 'classic', 'experimental'],
items: ['modern', 'classic', 'experimental (rider)', 'experimental (driver)'],
dynamicTitle: true
}
}
Expand Down
3,340 changes: 3,336 additions & 4 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@
"@types/react-select": "^4.0.18",
"@types/styled-system": "^5.1.9",
"date-fns": "^2.11.1",
"react-aria": "^3.34.3",
"react-aria-components": "^1.3.3",
"react-popper": "^2.3.0",
"react-transition-group": "^4.3.0",
"styled-system": "^5.1.5",
Expand Down
111 changes: 84 additions & 27 deletions src/components/experimental/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,98 @@
import React, { ReactElement } from 'react';
import styled, { ThemeProvider } from 'styled-components';
import { Button as BaseButton } from '../../Button/Button';
import { theme as experimentalTheme } from '../../../essentials/experimental/theme';
import { getSemanticValue, getSemanticHslValue } from '../../../essentials/experimental/cssVariables';
import styled from 'styled-components';
import { variant } from 'styled-system';
import { Button as BaseButton, ButtonProps as BaseButtonProps } from 'react-aria-components';
import { getSemanticValue } from '../../../essentials/experimental/cssVariables';
import { get } from '../../../utils/experimental/themeGet';
import { Text } from '../Text/Text';
import { textStyles } from '../Text/Text';

const ButtonStyled = styled(BaseButton)<{ secondary: boolean }>`
type Emphasis = 'primary' | 'secondary';

interface ButtonProps extends BaseButtonProps {
/**
* Define style of the button component, defaults to primary
*/
emphasis?: Emphasis;
}

const emphasisStyles = variant<Record<string, unknown>, Emphasis>({
prop: '$emphasis',
variants: {
primary: {
color: getSemanticValue('on-accent'),
background: getSemanticValue('accent'),

'&::before': {
background: getSemanticValue('on-accent')
},

'&[data-disabled]::before': {
opacity: 0.38
}
},
secondary: {
color: getSemanticValue('on-surface'),
background: getSemanticValue('surface-variant'),

'&::before': {
background: getSemanticValue('on-surface')
},

'&[data-disabled]': {
opacity: 0.38
},

'&[data-disabled]::before': {
opacity: 0.06
}
}
}
});

const ButtonStyled = styled(BaseButton)<{ $emphasis: Emphasis }>`
position: relative;
display: inline-flex;
align-items: center;
gap: ${get('space.2')};
border: none;
outline: none;
border-radius: ${get('radii.4')};
padding: ${experimentalTheme.space[4]}rem ${experimentalTheme.space[6]}rem;
height: unset;
padding: ${get('space.4')} ${get('space.6')};
background-color: ${getSemanticValue('accent')};
cursor: pointer;
&:hover {
background-color: hsla(${getSemanticHslValue('accent')}, 0.84);
&::before {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
content: '';
border-radius: inherit;
opacity: 0;
transition: opacity ease 200ms;
}
${props =>
props.secondary &&
`
color: hsl(0, 6%, 11%); /* var(--sys-color-on-surface, #1E1A1A) */
background-color: hsl(0, 6%, 94%); /* var(--sys-color-surface-container, #F1EFEF) */
&:hover {
color: hsl(0, 6%, 11%); /* var(--sys-color-on-surface, #1E1A1A) */
background-color: hsl(0, 2%, 81%); /* var(--sys-color-on-surface, #1E1A1A) * opacity 0.16 */
}
`}
&[data-hovered]::before {
opacity: 0.16;
}
&[data-focused]::before,
&[data-pressed]::before {
opacity: 0.24;
}
${textStyles.variants.label1}
${emphasisStyles};
`;

function Button({ secondary, children }: { secondary: boolean; children: React.ReactNode }): ReactElement {
function Button({ children, emphasis = 'primary', ...restProps }: ButtonProps): ReactElement {
return (
<ThemeProvider theme={experimentalTheme}>
<ButtonStyled secondary={secondary}>
<Text variant="label1">{children}</Text>
</ButtonStyled>
</ThemeProvider>
<ButtonStyled $emphasis={emphasis} {...restProps}>
{children}
</ButtonStyled>
);
}

Expand Down
39 changes: 38 additions & 1 deletion src/components/experimental/Button/docs/Button.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import { StoryObj, Meta } from '@storybook/react';
import React from 'react';
import { Button } from '../Button';
import { TrashIcon } from '../../../../icons';

const meta: Meta = {
title: 'Experimental/Components/Button',
component: Button,
parameters: {
layout: 'centered'
},
args: {
children: 'Book now'
},
argTypes: {
children: {
description: 'Button text'
},
secondary: {
emphasis: {
control: 'radio',
options: ['primary', 'secondary']
},
isDisabled: {
control: 'boolean'
},
ref: {
Expand All @@ -37,3 +46,31 @@ export default meta;
type Story = StoryObj<typeof Button>;

export const Default: Story = {};

export const Secondary: Story = {
args: {
emphasis: 'secondary'
}
};

export const Disabled: Story = {
args: {
isDisabled: true
}
};

export const Focused: Story = {
args: {
autoFocus: true
}
};

export const WithIcon: Story = {
args: {
children: (
<>
<TrashIcon size={20} /> Remove
</>
)
}
};
2 changes: 1 addition & 1 deletion src/components/experimental/Chip/Chip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const Container = styled.div.attrs({ theme })<{ isActive: boolean }>`
cursor: pointer;
border-radius: ${get('radii.3')};
padding: ${get('space.2')}rem ${get('space.3')}rem;
padding: ${get('space.2')} ${get('space.3')};
color: ${
props =>
Expand Down
17 changes: 8 additions & 9 deletions src/components/experimental/Input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ const TextInput = styled.input.attrs(() => ({
font-weight: ${theme.fontWeights.medium};
line-height: ${theme.lineHeights[1]};
padding-top: ${theme.space[6]}rem;
padding-bottom: ${theme.space[2]}rem;
padding-top: ${theme.space[6]};
padding-bottom: ${theme.space[2]};
display: block;
width: 100%;
Expand All @@ -24,7 +24,7 @@ const TextInput = styled.input.attrs(() => ({
const Label = styled.label<{ $shouldDisplace: boolean; $shouldLabelAnimate?: boolean }>`
position: absolute;
top: 50%;
left: ${theme.space[4]}rem;
left: ${theme.space[4]};
font-size: ${theme.fontSizes[1]};
line-height: ${theme.lineHeights[0]};
Expand All @@ -36,7 +36,7 @@ const Label = styled.label<{ $shouldDisplace: boolean; $shouldLabelAnimate?: boo
${props =>
props.$shouldDisplace &&
`
top: ${theme.space[1]}rem;
top: ${theme.space[1]};
font-size: ${theme.fontSizes[0]};
transform: translate3d(1px, 0 ,0);
color: hsla(347, 41%, 50%, 1); // var(--sys-color-interactive, #B44B61);
Expand All @@ -54,8 +54,8 @@ const Wrapper = styled.div`
border-color: hsla(0, 6%, 82%, 1); // var(--sys-color-divider, #D4CECE);
border-radius: ${theme.radii[4]};
padding-left: ${theme.space[4]}rem;
padding-right: ${theme.space[4]}rem;
padding-left: ${theme.space[4]};
padding-right: ${theme.space[4]};
display: flex;
align-items: end;
Expand All @@ -67,9 +67,8 @@ const Wrapper = styled.div`
}
&:focus-within {
outline-color: hsla(347, 41%, 50%, 1); // var(--sys-color-interactive, #B44B61);
outline-style: solid;
outline-width: 0.125rem;
// var(--sys-color-interactive, #B44B61);
outline: hsla(347, 41%, 50%, 1) solid 0.125rem;
outline-offset: -0.125rem;
}
`;
Expand Down
21 changes: 16 additions & 5 deletions src/components/experimental/Text/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,54 +24,65 @@ interface TextProps
variant?: ResponsiveValue<'display' | 'headline' | 'title1' | 'title2' | 'body1' | 'body2' | 'label1' | 'label2'>;
}

const variantStyles = variant({
export const textStyles = {
variants: {
display: {
fontFamily: theme.fonts.normal,
fontSize: theme.fontSizes[4],
fontWeight: theme.fontWeights.bold,
lineHeight: theme.lineHeights[4]
lineHeight: theme.lineHeights[4],
fontStretch: '50%'
},
headline: {
fontFamily: theme.fonts.normal,
fontSize: theme.fontSizes[3],
fontWeight: theme.fontWeights.bold,
lineHeight: theme.lineHeights[3]
lineHeight: theme.lineHeights[3],
fontStretch: '50%'
},
title1: {
fontFamily: theme.fonts.normal,
fontSize: theme.fontSizes[2],
fontWeight: theme.fontWeights.semibold,
lineHeight: theme.lineHeights[2]
},
title2: {
fontFamily: theme.fonts.normal,
fontSize: theme.fontSizes[1],
fontWeight: theme.fontWeights.medium,
lineHeight: theme.lineHeights[1]
},
body1: {
fontFamily: theme.fonts.normal,
fontSize: theme.fontSizes[1],
fontWeight: theme.fontWeights.normal,
lineHeight: theme.lineHeights[1]
},
body2: {
fontFamily: theme.fonts.normal,
fontSize: theme.fontSizes[0],
fontWeight: theme.fontWeights.normal,
lineHeight: theme.lineHeights[0]
},
label1: {
fontFamily: theme.fonts.normal,
fontSize: theme.fontSizes[1],
fontWeight: theme.fontWeights.medium,
lineHeight: theme.lineHeights[1]
},
label2: {
fontFamily: theme.fonts.normal,
fontSize: theme.fontSizes[0],
fontWeight: theme.fontWeights.normal,
lineHeight: theme.lineHeights[0]
}
}
});
};

const variantStyles = variant(textStyles);

const Text = styled.span.attrs({ theme })<TextProps>`
color: inherit;
font-family: ${get('fonts.normal')};
margin: 0;
${compose(margin, variantStyles, fontFamily, textAlign)}
Expand Down
Loading

0 comments on commit a6afc67

Please sign in to comment.