Skip to content

Commit

Permalink
[Theme setup] Initial setup and Accordion example (#436)
Browse files Browse the repository at this point in the history
* initial setup

* convert Acoordion,add  theme suport to stories

* complete accordion example

* shouldShowForEnvironment refactor

* commit snapshot size

* v13.0.0-alpha.1

* Replace swap button with addon-toolbars to fix visual regression

Co-authored-by: Michael Altamirano <michaeljaltamirano@gmail.com>
  • Loading branch information
daigof and michaeljaltamirano authored Oct 27, 2020
1 parent c2bd07f commit 6fb4f55
Show file tree
Hide file tree
Showing 17 changed files with 921 additions and 691 deletions.
1,302 changes: 651 additions & 651 deletions .size-snapshot.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
'@storybook/addon-knobs',
'@storybook/addon-a11y',
'@storybook/addon-actions',
'@storybook/addon-toolbars',
'@storybook/addon-viewport',
'@storybook/addon-storysource',
{
Expand Down
40 changes: 39 additions & 1 deletion .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React from 'react';
import { addDecorator, addParameters } from '@storybook/react';
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
import addons from '@storybook/addons';
import addons, { StoryContext, StoryGetter } from '@storybook/addons';
import { Global, css } from '@emotion/core';
import { ThemeProvider } from 'emotion-theming';
import Theme from './theme';
import {
resetStyles,
brandStyles,
} from '../src/utils/injectGlobalStyles/style';
import { primaryTheme, secondaryTheme } from '../src/constants/themes';
import { ThemeType } from '../src/constants/themes/types';
import { BREAKPOINTS } from '../src/constants';

const InjectGlobalStyles = (storyFn) => (
Expand Down Expand Up @@ -110,3 +113,38 @@ addParameters({
});

addons.setConfig(ADDONS_CONFIG);

export const globalTypes = {
theme: {
name: 'Theme',
description: 'Global theme for components',
defaultValue: primaryTheme.__type,
toolbar: {
icon: 'switchalt',
items: [
{ value: primaryTheme.__type, title: 'Primary Theme' },
{
value: secondaryTheme.__type,
title: 'Secondary Theme',
},
],
},
},
};

const withThemeProvider = (Story: StoryGetter, context: StoryContext) => {
const getTheme = (): ThemeType => {
const {
globals: { theme },
} = context;

return theme === primaryTheme.__type ? primaryTheme : secondaryTheme;
};

return (
<ThemeProvider theme={getTheme()}>
<Story {...context} />
</ThemeProvider>
);
};
export const decorators = [withThemeProvider];
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "radiance-ui",
"version": "12.3.1",
"version": "13.0.0-alpha.1",
"description": "Curology's React based component library",
"main": "dist/bundle.js",
"module": "dist/bundle-es/index.js",
Expand Down Expand Up @@ -73,6 +73,7 @@
"@storybook/addon-knobs": "^6.0.26",
"@storybook/addon-links": "^6.0.26",
"@storybook/addon-storysource": "^6.0.26",
"@storybook/addon-toolbars": "6.0.26",
"@storybook/addon-viewport": "^6.0.26",
"@storybook/core": "^6.0.26",
"@storybook/react": "^6.0.26",
Expand Down Expand Up @@ -134,6 +135,7 @@
"@emotion/core": "10.0.35",
"@emotion/styled": "10.0.27",
"@react-aria/focus": "^3.0.2",
"emotion-theming": "10.0.27",
"focus-visible": "^5.1.0",
"lodash.round": "^4.0.4",
"lodash.throttle": "^4.1.1",
Expand All @@ -149,6 +151,7 @@
"peerDependencies": {
"@emotion/core": "10.0.35",
"@emotion/styled": "10.0.27",
"emotion-theming": "10.0.27",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
Expand Down
60 changes: 60 additions & 0 deletions src/constants/colors/primary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import PropTypes from 'prop-types';

import COLORS from '.';

const PRIMARY_COLORS = {
// brand colors
primary: COLORS.purple100,
primaryTint1: COLORS.purple85,
primaryTint2: COLORS.purple70,
primaryTint3: COLORS.purple30,
secondary: COLORS.lavender100,
tertiary: COLORS.purple4,

// general colors
success: COLORS.statusGreen,
successBackground: COLORS.statusGreenBackground,
successBorder: COLORS.statusGreenBorder,
info: COLORS.statusPurple,
infoBackground: COLORS.statusPurpleBackground,
infoBorder: COLORS.statusPurpleBorder,
error: COLORS.statusRed,
errorBackground: COLORS.statusRedBackground,
errorBorder: COLORS.statusRedBorder,
default: COLORS.purple70,
defaultBackground: COLORS.purple10,
defaultBorder: COLORS.purple15,
accent: COLORS.red,
disabled: COLORS.purple10,
failure: COLORS.red,
hover: COLORS.purple4,
warning: COLORS.yellowLight,

// ui colors
background: COLORS.purple4,
backgroundDark: COLORS.purple4,
border: COLORS.purple10,
divider: COLORS.purple10,

// form colors
radioBorder: COLORS.purple30,
radioBorderSelected: COLORS.lavender100,

// typography
textMuted: COLORS.purple70,
textGhost: COLORS.purple30,
textDisabled: COLORS.purple30,

// overlay
overlay: 'rgba(45, 45, 48, 0.7)',
overlaySolid: 'rgba(45, 45, 48, 1)',

black: COLORS.black,
white: COLORS.white,
};

export const PRIMARY_COLORS_PROP_TYPES = PropTypes.oneOf(
Object.values(PRIMARY_COLORS),
);

export default PRIMARY_COLORS;
60 changes: 60 additions & 0 deletions src/constants/colors/secondary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import PropTypes from 'prop-types';

import COLORS from '.';

const SECONDARY_COLORS = {
// brand colors
primary: '#4c0000',
primaryTint1: '#b20000',
primaryTint2: null,
primaryTint3: '#ff0000',
secondary: '#ff8000',
tertiary: null,

// general colors
success: null,
successBackground: null,
successBorder: null,
info: null,
infoBackground: null,
infoBorder: null,
error: null,
errorBackground: null,
errorBorder: null,
default: null,
defaultBackground: null,
defaultBorder: null,
accent: null,
disabled: null,
failure: null,
hover: null,
warning: null,

// ui colors
background: null,
backgroundDark: null,
border: null,
divider: null,

// form colors
radioBorder: null,
radioBorderSelected: null,

// typography
textMuted: null,
textGhost: null,
textDisabled: null,

// overlay
overlay: null,
overlaySolid: null,

black: COLORS.black,
white: COLORS.white,
};

export const SECONDARY_COLORS_PROP_TYPES = PropTypes.oneOf(
Object.values(SECONDARY_COLORS),
);

export default SECONDARY_COLORS;
10 changes: 10 additions & 0 deletions src/constants/colors/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import PRIMARY_COLORS from './primary';
import SECONDARY_COLORS from './secondary';

describe('theme colors', () => {
it('primary and secondary colors have the same number of properties', () => {
expect(Object.keys(PRIMARY_COLORS).length).toEqual(
Object.keys(SECONDARY_COLORS).length,
);
});
});
2 changes: 2 additions & 0 deletions src/constants/themes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as primaryTheme } from './primary';
export { default as secondaryTheme } from './secondary';
9 changes: 9 additions & 0 deletions src/constants/themes/primary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import PRIMARY_COLORS from '../colors/primary';

const primaryTheme = {
__type: 'primary',
BOX_SHADOW: {},
COLORS: PRIMARY_COLORS,
} as const;

export default primaryTheme;
9 changes: 9 additions & 0 deletions src/constants/themes/secondary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import SECONDARY_COLORS from '../colors/secondary';

const secondaryTheme = {
__type: 'secondary',
BOX_SHADOW: {},
COLORS: SECONDARY_COLORS,
} as const;

export default secondaryTheme;
13 changes: 13 additions & 0 deletions src/constants/themes/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { primaryTheme, secondaryTheme } from '.';

type BoxShadow =
| typeof primaryTheme['BOX_SHADOW']
| typeof secondaryTheme['BOX_SHADOW'];

type Colors = typeof primaryTheme['COLORS'] | typeof secondaryTheme['COLORS'];

export type ThemeType = {
__type: 'primary' | 'secondary';
BOX_SHADOW: BoxShadow;
COLORS: Colors;
};
6 changes: 4 additions & 2 deletions src/shared-components/accordion/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import PropTypes from 'prop-types';
import React, { useEffect, useState, useRef } from 'react';
import ChevronIcon from 'src/svgs/icons/chevron-icon.svg';
import { COLORS } from 'src/constants';
import { useTheme } from 'emotion-theming';

import { ThemeType } from '../../constants/themes/types';
import Thumbnails from './thumbnails';
import {
AccordionBox,
Expand Down Expand Up @@ -50,6 +51,7 @@ export const Accordion = ({
rightAlignArrow = false,
title,
}: AccordionProps) => {
const theme = useTheme<ThemeType>();
const [contentHeight, setContentHeight] = useState('0px');

const contentRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -94,7 +96,7 @@ export const Accordion = ({
rotate={isOpen ? 90 : 0}
width={16}
height={16}
fill={COLORS.primary}
fill={theme.COLORS.primary}
/>
</ArrowWrapper>
</TitleWrapper>
Expand Down
30 changes: 16 additions & 14 deletions src/shared-components/accordion/style.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import styled from '@emotion/styled';
import { css } from '@emotion/core';
import {
ANIMATION,
BREAKPOINTS,
BOX_SHADOWS,
COLORS,
SPACER,
ANIMATION, BREAKPOINTS, BOX_SHADOWS, SPACER,
} from 'src/constants';
import { ThemeType } from 'src/constants/themes/types';

export const Content = styled.div`
padding: ${SPACER.medium};
Expand All @@ -19,33 +16,35 @@ export const ExpansionWrapper = styled.div<{ contentHeight: string }>`
transition: max-height ${ANIMATION.defaultTiming} ease-in-out;
`;

const getBorderStyle = (isOpen: boolean) => css`
border: 1px solid ${COLORS.border};
const getBorderStyle = (theme: ThemeType, isOpen: boolean) => css`
border: 1px solid ${theme.COLORS.border};
${ExpansionWrapper} {
${isOpen && `border-top: 1px solid ${COLORS.border};`};
${isOpen && `border-top: 1px solid ${theme.COLORS.border}`};
}
`;

export const AccordionBox = styled.div<{
noBorder: boolean;
isOpen: boolean;
disabled: boolean;
theme?: ThemeType;
}>`
${({ noBorder, isOpen }) => (!noBorder ? getBorderStyle(isOpen) : '')};
${({ noBorder, isOpen, theme }) =>
!noBorder ? getBorderStyle(theme, isOpen) : ''};
width: 100%;
&:not(:last-child) {
border-bottom: none;
}
${({ disabled }) =>
${({ disabled, theme }) =>
disabled
? `
opacity: 0.4;
background-color: ${COLORS.disabled};
border-color: ${COLORS.purple30};
background-color: ${theme.COLORS.disabled};
border-color: ${theme.COLORS.primaryTint3};
`
: ''};
`;
Expand Down Expand Up @@ -96,9 +95,12 @@ export const Truncate = styled.div`
* borderRadius must match borderRadius passed to main <Accordion />
* component if opting out of default values.
*/
export const Container = styled.div<{ borderRadius?: string }>`
export const Container = styled.div<{
borderRadius?: string;
theme?: ThemeType;
}>`
box-shadow: ${BOX_SHADOWS.clickable};
background-color: ${COLORS.white};
background-color: ${({ theme }) => theme.COLORS.white};
max-width: ${BREAKPOINTS.md}px;
${({ borderRadius = '4px' }) => `
Expand Down
Loading

0 comments on commit 6fb4f55

Please sign in to comment.