From 3ac41ec4a07ba6050704d5d753cfbd8969760abf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Berg=C3=A9?= Date: Thu, 24 Jan 2019 13:59:10 +0100 Subject: [PATCH] feat: simplify API & fixes theme bugs BREAKING CHANGE: remove uiAs prop & uiAs helper --- docs/advanced/CustomComponent.mdx | 15 +- examples/basics/src/emotion/index.js | 6 +- .../basics/src/styled-components/index.js | 6 +- packages/shared/core/Alert.js | 4 +- packages/shared/core/Breakpoint.js | 6 +- packages/shared/core/Button.js | 6 +- packages/shared/core/Checkbox.js | 30 ++-- packages/shared/core/ControlFeedback.js | 4 +- packages/shared/core/FormCheck.js | 5 +- packages/shared/core/FormCheckLabel.js | 2 +- packages/shared/core/FormGroup.js | 2 +- packages/shared/core/Input.js | 30 ++-- packages/shared/core/Modal.js | 4 +- packages/shared/core/ModalBody.js | 2 +- packages/shared/core/ModalCloseButton.js | 2 +- packages/shared/core/ModalContent.js | 6 +- packages/shared/core/ModalDialog.js | 2 +- packages/shared/core/ModalFooter.js | 2 +- packages/shared/core/ModalHeader.js | 2 +- packages/shared/core/Radio.js | 4 +- packages/shared/core/Row.js | 11 +- packages/shared/core/Select.js | 42 ++--- packages/shared/core/Switch.js | 2 +- packages/shared/core/Textarea.js | 5 +- packages/shared/core/Typography.js | 4 +- packages/shared/core/theme.js | 145 +++++++++--------- packages/shared/core/utils/createComponent.js | 38 ++--- packages/shared/core/utils/system.js | 3 +- 28 files changed, 186 insertions(+), 204 deletions(-) diff --git a/docs/advanced/CustomComponent.mdx b/docs/advanced/CustomComponent.mdx index b39e596d2..bb4a3e937 100644 --- a/docs/advanced/CustomComponent.mdx +++ b/docs/advanced/CustomComponent.mdx @@ -4,7 +4,7 @@ menu: Advanced --- import { Playground } from 'docz' -import { Button, Alert, uiAs } from '@smooth-ui/core-sc' +import { Button, Alert } from '@smooth-ui/core-sc' # Custom component @@ -12,28 +12,27 @@ Sometimes you may want to use a component but the resulting HTML tag is not the You can do it using two approaches. -## Use "uiAs" property +## Use "as" property -Every components accepts a `uiAs` property, it defines the base component used in each component. +Every components accepts a `as` property, it defines the base component used in each component. An example of an `Alert` that uses `span` as a component. - + A span alert -## Use "uiAs" helper +## Use "withComponent" helper -`uiAs` creates a new component with a predefined base component. +`withComponent` creates a new component with a predefined base component. An example of `Button` that will use `a` instead of `button`. {() => { - // import { uiAs } from '@smooth-ui/core-sc' - const LinkButton = uiAs(Button, 'a') + const LinkButton = Button.withComponent('a') return A button as a link }} diff --git a/examples/basics/src/emotion/index.js b/examples/basics/src/emotion/index.js index 8ac581d8b..362ff87a8 100644 --- a/examples/basics/src/emotion/index.js +++ b/examples/basics/src/emotion/index.js @@ -8,7 +8,7 @@ const BlackButton = styled(Button)` color: black; ` -const DivButton = uiAs(Button, 'div') +const DivButton = Button.withComponent('div') const App = () => ( <> @@ -17,10 +17,10 @@ const App = () => (
- {`uiAs(Button, 'div')`} + {`Button.withComponent('div')`}
- +
{`styled(Button)\`color: black\``} diff --git a/examples/basics/src/styled-components/index.js b/examples/basics/src/styled-components/index.js index d63aa457f..77641c468 100644 --- a/examples/basics/src/styled-components/index.js +++ b/examples/basics/src/styled-components/index.js @@ -6,7 +6,7 @@ const BlackButton = styled(Button)` color: black; ` -const DivButton = uiAs(Button, 'div') +const DivButton = Button.withComponent('div') const App = () => ( <> @@ -15,10 +15,10 @@ const App = () => (
- {`uiAs(Button, 'div')`} + {`Button.withComponent('div')`}
- +
{`styled(Button)\`color: black\``} diff --git a/packages/shared/core/Alert.js b/packages/shared/core/Alert.js index 2f6591b82..b277b1528 100644 --- a/packages/shared/core/Alert.js +++ b/packages/shared/core/Alert.js @@ -6,13 +6,13 @@ import createComponent from './utils/createComponent' const Alert = createComponent(() => ({ name: 'alert', omitProps: ['variant'], - style: css` + style: p => css` position: relative; padding: ${th('alertPaddingY')} ${th('alertPaddingX')}; margin-bottom: ${th('alertMarginBottom')}; border: 1px solid transparent; border-radius: ${th('borderRadius')}; - ${p => p.variant && mixin('alertVariant', p.variant)(p)}; + ${p.variant && mixin('alertVariant', p.variant)(p)}; `, propTypes: { children: PropTypes.node, diff --git a/packages/shared/core/Breakpoint.js b/packages/shared/core/Breakpoint.js index e7684d9b7..21f97da5b 100644 --- a/packages/shared/core/Breakpoint.js +++ b/packages/shared/core/Breakpoint.js @@ -6,10 +6,10 @@ import createComponent from './utils/createComponent' const Breakpoint = createComponent(() => ({ name: 'breakpoint', omitProps: ['up', 'down'], - style: css` + style: p => css` display: none; - ${p => p.up && up(p.up, 'display: block;')}; - ${p => p.down && down(p.down, 'display: block;')}; + ${p.up && up(p.up, 'display: block;')}; + ${p.down && down(p.down, 'display: block;')}; `, propTypes: { children: PropTypes.node, diff --git a/packages/shared/core/Button.js b/packages/shared/core/Button.js index cbf65fe98..cb33ec109 100644 --- a/packages/shared/core/Button.js +++ b/packages/shared/core/Button.js @@ -28,7 +28,7 @@ const Button = createComponent(() => ({ name: 'button', defaultComponent: 'button', omitProps: ['size', 'variant'], - style: css` + style: p => css` display: inline-block; padding: ${th('btnPaddingY')} ${th('btnPaddingX')}; z-index: ${th('zIndexControl')}; @@ -47,8 +47,8 @@ const Button = createComponent(() => ({ opacity: ${th('btnDisabledOpacity')}; } - ${p => p.size && sizeStyle[p.size]}; - ${p => p.variant && mixin('btnVariant', p.variant)(p)}; + ${p.size && sizeStyle[p.size]}; + ${p.variant && mixin('btnVariant', p.variant)(p)}; `, propTypes: { children: PropTypes.node, diff --git a/packages/shared/core/Checkbox.js b/packages/shared/core/Checkbox.js index 9a4cce96d..10e852262 100644 --- a/packages/shared/core/Checkbox.js +++ b/packages/shared/core/Checkbox.js @@ -78,22 +78,24 @@ const invalidStyle = css` } ` -const controlStyle = css` +const getValidStyle = valid => { + switch (valid) { + case true: + return validStyle + case false: + return invalidStyle + default: + return null + } +} + +const controlStyle = p => css` input:focus + .sui-checkbox-content { border-color: ${th('controlFocusBorderColor')}; box-shadow: ${mixin('controlFocusBoxShadow', 'primary')}; } - ${p => { - switch (p.valid) { - case true: - return validStyle - case false: - return invalidStyle - default: - return null - } - }}; + ${getValidStyle(p)}; ` const containerSystem = compose( @@ -137,7 +139,7 @@ const Checkbox = createComponent(() => ({ )} ), - style: css` + style: p => css` display: inline-flex; align-items: center; justify-content: center; @@ -185,8 +187,8 @@ const Checkbox = createComponent(() => ({ background-color: ${th('inputDisabledBgColor')}; } - ${p => sizeStyle[p.size]}; - ${p => p.control && controlStyle}; + ${sizeStyle[p.size]}; + ${p.control && controlStyle(p)}; ${containerSystem.props}; diff --git a/packages/shared/core/ControlFeedback.js b/packages/shared/core/ControlFeedback.js index 265a4698a..5e43d701a 100644 --- a/packages/shared/core/ControlFeedback.js +++ b/packages/shared/core/ControlFeedback.js @@ -6,11 +6,11 @@ import createComponent from './utils/createComponent' const ControlFeedback = createComponent(() => ({ name: 'control-feedback', omitProps: ['valid'], - style: css` + style: p => css` width: 100%; margin-top: 0.25rem; font-size: 80%; - color: ${p => (p.valid ? th('success')(p) : th('danger')(p))}; + color: ${p.valid ? th('success')(p) : th('danger')(p)}; `, propTypes: { children: PropTypes.node, diff --git a/packages/shared/core/FormCheck.js b/packages/shared/core/FormCheck.js index 945016f13..118f47d81 100644 --- a/packages/shared/core/FormCheck.js +++ b/packages/shared/core/FormCheck.js @@ -5,12 +5,11 @@ import createComponent from './utils/createComponent' const FormCheck = createComponent(() => ({ name: 'form-check', omitProps: ['inline'], - style: css` + style: p => css` display: flex; align-items: center; - ${p => - p.inline && + ${p.inline && css` display: inline-flex; margin-right: 0.75rem; diff --git a/packages/shared/core/FormCheckLabel.js b/packages/shared/core/FormCheckLabel.js index fd0625b35..b557b77bf 100644 --- a/packages/shared/core/FormCheckLabel.js +++ b/packages/shared/core/FormCheckLabel.js @@ -6,7 +6,7 @@ import createComponent from './utils/createComponent' const FormCheckLabel = createComponent(() => ({ name: 'form-check-label', defaultComponent: 'label', - style: css` + style: () => css` padding-left: 0.25rem; [class*='disabled'] ~ & { diff --git a/packages/shared/core/FormGroup.js b/packages/shared/core/FormGroup.js index 89ce6090b..4a1a17548 100644 --- a/packages/shared/core/FormGroup.js +++ b/packages/shared/core/FormGroup.js @@ -4,7 +4,7 @@ import createComponent from './utils/createComponent' const FormGroup = createComponent(() => ({ name: 'form-group', - style: css` + style: () => css` margin-bottom: 1rem; `, propTypes: { diff --git a/packages/shared/core/Input.js b/packages/shared/core/Input.js index cc11e65be..8bec24d14 100644 --- a/packages/shared/core/Input.js +++ b/packages/shared/core/Input.js @@ -39,7 +39,18 @@ const invalidStyle = css` } ` -const controlStyle = css` +const getValidStyle = valid => { + switch (valid) { + case true: + return validStyle + case false: + return invalidStyle + default: + return null + } +} + +const controlStyle = p => css` display: block; width: 100%; @@ -48,23 +59,14 @@ const controlStyle = css` box-shadow: ${mixin('controlFocusBoxShadow', 'primary')}; } - ${p => { - switch (p.valid) { - case true: - return validStyle - case false: - return invalidStyle - default: - return null - } - }}; + ${getValidStyle(p.valid)}; ` const Input = createComponent(() => ({ name: 'input', defaultComponent: 'input', omitProps: ['control', 'size', 'valid'], - style: css` + style: p => css` display: inline-block; border-width: ${th('inputBorderWidth')}; border-color: ${th('inputBorderColor')}; @@ -91,8 +93,8 @@ const Input = createComponent(() => ({ color: ${th('inputDisabledText')}; } - ${p => p.size && sizeStyle[p.size]}; - ${p => p.control && controlStyle}; + ${p.size && sizeStyle[p.size]}; + ${p.control && controlStyle(p)}; `, propTypes: { control: PropTypes.bool, diff --git a/packages/shared/core/Modal.js b/packages/shared/core/Modal.js index 6eac54f67..5061f0271 100644 --- a/packages/shared/core/Modal.js +++ b/packages/shared/core/Modal.js @@ -2,7 +2,7 @@ import React from 'react' import PropTypes from 'prop-types' import FocusLock from 'react-focus-lock' -import { RemoveScroll } from 'react-remove-scroll'; +import { RemoveScroll } from 'react-remove-scroll' import { css, withTheme } from './styled-engine' import { th, mixin } from './utils/system' import Transition from './Transition' @@ -132,7 +132,7 @@ const ModalComponentWithTheme = withTheme(ModalComponent) const Modal = createComponent(() => ({ name: 'modal', InnerComponent: ModalComponentWithTheme, - style: css` + style: () => css` position: fixed; top: 0; right: 0; diff --git a/packages/shared/core/ModalBody.js b/packages/shared/core/ModalBody.js index 3d8110643..cfc75ae92 100644 --- a/packages/shared/core/ModalBody.js +++ b/packages/shared/core/ModalBody.js @@ -5,7 +5,7 @@ import createComponent from './utils/createComponent' const ModalBody = createComponent(() => ({ name: 'modal-body', - style: css` + style: () => css` position: relative; /* Enable "flex-grow: 1" so that the body take up as much space as possible */ /* when should there be a fixed height on ModalDialog. */ diff --git a/packages/shared/core/ModalCloseButton.js b/packages/shared/core/ModalCloseButton.js index adde84e21..741a84160 100644 --- a/packages/shared/core/ModalCloseButton.js +++ b/packages/shared/core/ModalCloseButton.js @@ -26,7 +26,7 @@ const ModalCloseButton = createComponent(() => ({ )} ), - style: css` + style: () => css` position: absolute; cursor: pointer; top: 0.2rem; diff --git a/packages/shared/core/ModalContent.js b/packages/shared/core/ModalContent.js index c30b7f0e0..fe5fd79fc 100644 --- a/packages/shared/core/ModalContent.js +++ b/packages/shared/core/ModalContent.js @@ -26,7 +26,7 @@ const ModalContent = createComponent(() => ({ )} ), - style: css` + style: () => css` position: relative; display: flex; flex-direction: column; @@ -39,14 +39,14 @@ const ModalContent = createComponent(() => ({ border: ${th('modalContentBorderWidth')} solid ${th('modalContentBorderColor')}; border-radius: ${th('modalContentBorderRadius')}; - box-shadow: ${th('modalContentBoxShadowXs')}; + ${th('modalContentBoxShadowXs')}; /* Remove focus outline from opened modal */ outline: 0; ${up( 'sm', css` - box-shadow: ${th('modalContentBoxShadowSmUp')}; + ${th('modalContentBoxShadowSmUp')}; `, )}; `, diff --git a/packages/shared/core/ModalDialog.js b/packages/shared/core/ModalDialog.js index 3a7ca4532..5a408be79 100644 --- a/packages/shared/core/ModalDialog.js +++ b/packages/shared/core/ModalDialog.js @@ -10,7 +10,7 @@ const ModalDialog = createComponent(() => ({ render: ({ Component, ...props }) => ( ), - style: css` + style: () => css` position: relative; width: auto; margin: ${th('modalDialogMargin')}; diff --git a/packages/shared/core/ModalFooter.js b/packages/shared/core/ModalFooter.js index 178fdb642..72919d5ee 100644 --- a/packages/shared/core/ModalFooter.js +++ b/packages/shared/core/ModalFooter.js @@ -5,7 +5,7 @@ import createComponent from './utils/createComponent' const ModalFooter = createComponent(() => ({ name: 'modal-footer', - style: css` + style: () => css` display: flex; align-items: center; justify-content: flex-end; diff --git a/packages/shared/core/ModalHeader.js b/packages/shared/core/ModalHeader.js index 1a62ca2c7..6749c4146 100644 --- a/packages/shared/core/ModalHeader.js +++ b/packages/shared/core/ModalHeader.js @@ -5,7 +5,7 @@ import createComponent from './utils/createComponent' const ModalHeader = createComponent(() => ({ name: 'modal-header', - style: css` + style: () => css` display: flex; align-items: flex-start; justify-content: space-between; diff --git a/packages/shared/core/Radio.js b/packages/shared/core/Radio.js index 4034b7883..323be4052 100644 --- a/packages/shared/core/Radio.js +++ b/packages/shared/core/Radio.js @@ -86,7 +86,7 @@ const ModalHeader = createComponent(() => ({ )} ), - style: css` + style: p => css` display: inline-flex; align-items: center; justify-content: center; @@ -131,7 +131,7 @@ const ModalHeader = createComponent(() => ({ transform: scale(0); } - ${p => p.size && sizeStyle[p.size]}; + ${p.size && sizeStyle[p.size]}; ${containerSystem.props}; diff --git a/packages/shared/core/Row.js b/packages/shared/core/Row.js index 70bb9788f..819885208 100644 --- a/packages/shared/core/Row.js +++ b/packages/shared/core/Row.js @@ -1,4 +1,3 @@ -import React from 'react' import PropTypes from 'prop-types' import { css } from './styled-engine' import { px, prop } from './utils/system' @@ -6,15 +5,7 @@ import createComponent from './utils/createComponent' const Row = createComponent(() => ({ name: 'row', - injectTheme: true, - render: ({ - Component, - gutter, - className, - justifyContent, - theme, - ...props - }) => , + omitProps: ['gutter'], style: p => { const gutter = px(prop('gutter', 'gridGutter')(p)) return css` diff --git a/packages/shared/core/Select.js b/packages/shared/core/Select.js index bed219edc..197cfeb2a 100644 --- a/packages/shared/core/Select.js +++ b/packages/shared/core/Select.js @@ -15,12 +15,12 @@ const renderOption = option => { } const sizeStyle = { - sm: css` + sm: p => css` select { padding: ${th('inputPaddingYSm')} ${th('inputPaddingXSm')}; font-size: ${th('fontSizeSm')}; border-radius: ${th('borderRadiusSm')}; - ${p => p.arrow && !p.multiple && 'padding-right: 1.225rem;'}; + ${p.arrow && !p.multiple && 'padding-right: 1.225rem;'}; } .sui-select-arrow { @@ -28,11 +28,11 @@ const sizeStyle = { width: 0.525rem; } `, - md: css` + md: p => css` select { padding: ${th('inputPaddingY')} ${th('inputPaddingX')}; font-size: ${th('fontSizeBase')}; - ${p => p.arrow && !p.multiple && 'padding-right: 1.6rem;'}; + ${p.arrow && !p.multiple && 'padding-right: 1.6rem;'}; border-radius: ${th('borderRadius')}; } @@ -41,12 +41,12 @@ const sizeStyle = { width: 0.6rem; } `, - lg: css` + lg: p => css` select { padding: ${th('inputPaddingYLg')} ${th('inputPaddingXLg')}; font-size: ${th('fontSizeLg')}; border-radius: ${th('borderRadiusLg')}; - ${p => p.arrow && !p.multiple && 'padding-right: 2rem;'}; + ${p.arrow && !p.multiple && 'padding-right: 2rem;'}; } .sui-select-arrow { @@ -78,7 +78,18 @@ const invalidStyle = css` } ` -const controlStyle = css` +const getValidStyle = valid => { + switch (valid) { + case true: + return validStyle + case false: + return invalidStyle + default: + return null + } +} + +const controlStyle = p => css` display: block; width: 100%; @@ -92,16 +103,7 @@ const controlStyle = css` } } - ${p => { - switch (p.valid) { - case true: - return validStyle - case false: - return invalidStyle - default: - return null - } - }}; + ${getValidStyle(p.valid)}; ` const Select = createComponent(() => ({ @@ -148,7 +150,7 @@ const Select = createComponent(() => ({ ) }, - style: css` + style: p => css` display: inline-block; position: relative; @@ -183,8 +185,8 @@ const Select = createComponent(() => ({ pointer-events: none; } - ${p => p.size && sizeStyle[p.size]}; - ${p => p.control && controlStyle}; + ${p.size && sizeStyle[p.size](p)}; + ${p.control && controlStyle(p)}; `, propTypes: { arrow: PropTypes.bool, diff --git a/packages/shared/core/Switch.js b/packages/shared/core/Switch.js index 9430b65e8..74f2e9424 100644 --- a/packages/shared/core/Switch.js +++ b/packages/shared/core/Switch.js @@ -38,7 +38,7 @@ const Switch = createComponent(() => ({ )} ), - style: css` + style: () => css` display: inline-block; position: relative; width: 50px; diff --git a/packages/shared/core/Textarea.js b/packages/shared/core/Textarea.js index 94c1ecc2f..a8ea93b8f 100644 --- a/packages/shared/core/Textarea.js +++ b/packages/shared/core/Textarea.js @@ -1,6 +1,7 @@ -import { uiAs } from './utils/system' import Input from './Input' -const Textarea = uiAs(Input, 'textarea') +const Textarea = Input.withComponent('textarea') + +Textarea.propTypes = Input.propTypes export default Textarea diff --git a/packages/shared/core/Typography.js b/packages/shared/core/Typography.js index a2f79cf83..478399011 100644 --- a/packages/shared/core/Typography.js +++ b/packages/shared/core/Typography.js @@ -84,8 +84,8 @@ const Typography = createComponent(() => ({ const Component = BaseComponent || variantTags[variant] || 'span' return }, - style: css` - ${p => p.variant && variantStyle[p.variant]}; + style: p => css` + ${p.variant && variantStyle[p.variant]}; `, propTypes: { children: PropTypes.node, diff --git a/packages/shared/core/theme.js b/packages/shared/core/theme.js index 0ec16dbc7..117b4e1f4 100644 --- a/packages/shared/core/theme.js +++ b/packages/shared/core/theme.js @@ -44,17 +44,17 @@ export const green = '#28a745' export const teal = '#20c997' export const cyan = '#17a2b8' -export const primary = th('brick') -export const secondary = th('gray600') -export const success = th('green') -export const info = th('cyan') -export const warning = th('yellow') -export const danger = th('red') -export const light = th('gray100') -export const dark = th('gray800') - -export const primaryLight = th('primary', c => lighten(0.3, c)) -export const secondaryLight = th('secondary', c => lighten(0.3, c)) +export const primary = p => th('brick')(p) +export const secondary = p => th('gray600')(p) +export const success = p => th('green')(p) +export const info = p => th('cyan')(p) +export const warning = p => th('yellow')(p) +export const danger = p => th('red')(p) +export const light = p => th('gray100')(p) +export const dark = p => th('gray800')(p) + +export const primaryLight = p => th('primary', c => lighten(0.3, c))(p) +export const secondaryLight = p => th('secondary', c => lighten(0.3, c))(p) export const yikTextDark = '#111' export const yikTextLight = '#fff' @@ -109,7 +109,7 @@ export const colors = [ 'primaryLight', 'secondaryLight', ].reduce((obj, v) => { - obj[v] = th(v) + obj[v] = p => th(v)(p) return obj }, {}) @@ -127,12 +127,10 @@ export const borderWidth = '1px' // Fonts export const fontSizeBase = '1rem' -export const fontSizeSm = th('fontSizeBase', fontSize => - modularScale(-1, fontSize), -) -export const fontSizeLg = th('fontSizeBase', fontSize => - modularScale(1, fontSize), -) +export const fontSizeSm = p => + th('fontSizeBase', fontSize => modularScale(-1, fontSize))(p) +export const fontSizeLg = p => + th('fontSizeBase', fontSize => modularScale(1, fontSize))(p) export const fontWeightLight = 300 export const fontWeightNormal = 400 @@ -146,62 +144,61 @@ export const lineHeightLg = 1.5 export const inputBtnPaddingY = '.375rem' export const inputBtnPaddingX = '.75rem' -export const inputBtnLineHeight = th('lineHeightBase') +export const inputBtnLineHeight = p => th('lineHeightBase')(p) export const inputBtnPaddingYSm = '.25rem' export const inputBtnPaddingXSm = '.5rem' -export const inputBtnLineHeightSm = th('lineHeightSm') +export const inputBtnLineHeightSm = p => th('lineHeightSm')(p) export const inputBtnPaddingYLg = '.5rem' export const inputBtnPaddingXLg = '1rem' -export const inputBtnLineHeightLg = th('lineHeightLg') +export const inputBtnLineHeightLg = p => th('lineHeightLg')(p) -export const inputBtnBorderWidth = th('borderWidth') +export const inputBtnBorderWidth = p => th('borderWidth')(p) // Buttons -export const btnPaddingY = th('inputBtnPaddingY') -export const btnPaddingX = th('inputBtnPaddingX') -export const btnLineHeight = th('inputBtnLineHeight') +export const btnPaddingY = p => th('inputBtnPaddingY')(p) +export const btnPaddingX = p => th('inputBtnPaddingX')(p) +export const btnLineHeight = p => th('inputBtnLineHeight')(p) -export const btnPaddingYSm = th('inputBtnPaddingYSm') -export const btnPaddingXSm = th('inputBtnPaddingXSm') -export const btnLineHeightSm = th('inputBtnLineHeightSm') +export const btnPaddingYSm = p => th('inputBtnPaddingYSm')(p) +export const btnPaddingXSm = p => th('inputBtnPaddingXSm')(p) +export const btnLineHeightSm = p => th('inputBtnLineHeightSm')(p) -export const btnPaddingYLg = th('inputBtnPaddingYLg') -export const btnPaddingXLg = th('inputBtnPaddingXLg') -export const btnLineHeightLg = th('inputBtnLineHeightLg') +export const btnPaddingYLg = p => th('inputBtnPaddingYLg')(p) +export const btnPaddingXLg = p => th('inputBtnPaddingXLg')(p) +export const btnLineHeightLg = p => th('inputBtnLineHeightLg')(p) export const btnBorderWidth = 0 export const btnDisabledOpacity = 0.8 // Inputs -export const inputPaddingY = th('inputBtnPaddingY') -export const inputPaddingX = th('inputBtnPaddingX') -export const inputLineHeight = th('inputBtnLineHeight') +export const inputPaddingY = p => th('inputBtnPaddingY')(p) +export const inputPaddingX = p => th('inputBtnPaddingX')(p) +export const inputLineHeight = p => th('inputBtnLineHeight')(p) -export const inputPaddingYSm = th('inputBtnPaddingYSm') -export const inputPaddingXSm = th('inputBtnPaddingXSm') -export const inputLineHeightSm = th('inputBtnLineHeightSm') +export const inputPaddingYSm = p => th('inputBtnPaddingYSm')(p) +export const inputPaddingXSm = p => th('inputBtnPaddingXSm')(p) +export const inputLineHeightSm = p => th('inputBtnLineHeightSm')(p) -export const inputPaddingYLg = th('inputBtnPaddingYLg') -export const inputPaddingXLg = th('inputBtnPaddingXLg') -export const inputLineHeightLg = th('inputBtnLineHeightLg') +export const inputPaddingYLg = p => th('inputBtnPaddingYLg')(p) +export const inputPaddingXLg = p => th('inputBtnPaddingXLg')(p) +export const inputLineHeightLg = p => th('inputBtnLineHeightLg')(p) -export const inputBorderWidth = th('inputBtnBorderWidth') -export const inputBorderColor = th('gray300') -export const inputBgColor = th('white') -export const inputDisabledBgColor = th('gray100') -export const inputDisabledText = th('gray600') -export const inputPlaceholderText = th('gray600') -export const inputTextColor = th('gray900') +export const inputBorderWidth = p => th('inputBtnBorderWidth')(p) +export const inputBorderColor = p => th('gray300')(p) +export const inputBgColor = p => th('white')(p) +export const inputDisabledBgColor = p => th('gray100')(p) +export const inputDisabledText = p => th('gray600')(p) +export const inputPlaceholderText = p => th('gray600')(p) +export const inputTextColor = p => th('gray900')(p) // Controls -export const controlFocusBorderColor = th('primary', color => - lighten(0.25, color), -) +export const controlFocusBorderColor = p => + th('primary', color => lighten(0.25, color))(p) export const controlFocusBoxShadow = p => color => `0 0 0 0.2rem ${th(color, c => transparentize(0.75, c))(p)}` @@ -279,10 +276,11 @@ const safeTransitionProperties = [ 'opacity', ] -export const transitionBase = mixin( - 'transition', - safeTransitionProperties.map(prop => `${prop} .2s ease-in-out`).join(','), -) +export const transitionBase = p => + mixin( + 'transition', + safeTransitionProperties.map(prop => `${prop} .2s ease-in-out`).join(','), + )(p) // Breakpoints @@ -296,7 +294,7 @@ export const colorInterval = 0.08 // Headings export const headingsMarginBottom = '.5rem' -export const headingsFontFamily = th('fontFamily') +export const headingsFontFamily = p => th('fontFamily')(p) export const headingsFontWeight = 500 export const headingsLineHeight = 1.2 export const headingsColor = 'inherit' @@ -318,7 +316,7 @@ export const display2Weight = 300 export const display3Weight = 300 export const display4Weight = 300 -export const displayLineHeight = th('headingsLineHeight') +export const displayLineHeight = p => th('headingsLineHeight')(p) // Modals @@ -330,23 +328,24 @@ export const modalTransitionDuration = 300 // ms export const modalDialogMargin = '0.5rem' export const modalDialogMarginYSmUp = '1.75rem' -export const modalContentBg = th('white') -export const modalContentBorderWidth = th('borderWidth') -export const modalContentBorderColor = th('black', color => - transparentize(0.8, color), -) -export const modalContentBorderRadius = th('borderRadiusLg') -export const modalContentBoxShadowXs = css`0 .25rem .5rem ${th('black', color => - transparentize(0.8, color), -)}` -export const modalContentBoxShadowSmUp = css`0 .5rem 1rem ${th('black', color => - transparentize(0.8, color), -)}` - -export const modalHeaderBorderColor = th('gray200') -export const modalFooterBorderColor = th('modalHeaderBorderColor') -export const modalHeaderBorderWidth = th('modalContentBorderWidth') -export const modalFooterBorderWidth = th('modalHeaderBorderWidth') +export const modalContentBg = p => th('white')(p) +export const modalContentBorderWidth = p => th('borderWidth')(p) +export const modalContentBorderColor = p => + th('black', color => transparentize(0.8, color))(p) +export const modalContentBorderRadius = p => th('borderRadiusLg')(p) +export const modalContentBoxShadowXs = css` + box-shadow: 0 0.25rem 0.5rem + ${p => th('black', color => transparentize(0.8, color))(p)}; +` +export const modalContentBoxShadowSmUp = css` + box-shadow: 0 0.5rem 1rem + ${p => th('black', color => transparentize(0.8, color))(p)}; +` + +export const modalHeaderBorderColor = p => th('gray200')(p) +export const modalFooterBorderColor = p => th('modalHeaderBorderColor')(p) +export const modalHeaderBorderWidth = p => th('modalContentBorderWidth')(p) +export const modalFooterBorderWidth = p => th('modalHeaderBorderWidth')(p) // Mixins export const base = () => () => css` diff --git a/packages/shared/core/utils/createComponent.js b/packages/shared/core/utils/createComponent.js index 165f33b8f..dda02ef53 100644 --- a/packages/shared/core/utils/createComponent.js +++ b/packages/shared/core/utils/createComponent.js @@ -2,9 +2,9 @@ import React from 'react' import PropTypes from 'prop-types' import { system as fullSystem } from '@smooth-ui/system' -import { styled, withTheme } from '../styled-engine' -import * as theme from '../theme' +import { styled } from '../styled-engine' import { omit } from './misc' +import { gth } from './system' function createComponent(getConfig) { const { @@ -16,33 +16,26 @@ function createComponent(getConfig) { render = ({ Component, ...props }) => , defaultComponent = 'div', system = fullSystem, - applySystem = system => props => ({ '&&': system.props(props) }), - injectTheme, + applySystem = system => props => { + const theme = gth(props) + return { '&&': system.props({ ...props, theme }) } + }, InnerComponent: InnerComponentFromConfig, } = getConfig() const omittedProps = [ 'theme', - '__scTheme', ...(system ? system.meta.props : {}), ...omitProps, ] const baseClassName = `sui-${name}` - let InnerComponent = + const InnerComponent = InnerComponentFromConfig || class Component extends React.Component { render() { - const { - className, - uiAs, - theme, - __scTheme, - forwardedRef, - ...props - } = this.props - - const Component = uiAs || defaultComponent + const { className, as, forwardedRef, ...props } = this.props + const Component = as || defaultComponent const renderProps = { ref: forwardedRef, @@ -53,15 +46,10 @@ function createComponent(getConfig) { ...omit(props, omittedProps), } - if (injectTheme) { - renderProps.theme = theme || __scTheme - } - return render(renderProps) } } - InnerComponent = injectTheme ? withTheme(InnerComponent) : InnerComponent InnerComponent.displayName = `sui-${name}` function forwardRef(props, ref) { @@ -72,11 +60,10 @@ function createComponent(getConfig) { const RefComponent = React.forwardRef(forwardRef) RefComponent.displayName = InnerComponent.displayName - // eslint-disable-next-line no-underscore-dangle - RefComponent.__smoothUIComponent = true - const StyledComponent = styled(RefComponent)` - ${style}; + ${typeof style === 'function' + ? p => style({ ...defaultProps, ...p }) + : style}; ${applySystem && applySystem(system)}; ` @@ -96,7 +83,6 @@ function createComponent(getConfig) { } StyledComponent.defaultProps = { - __scTheme: theme, ...defaultProps, } diff --git a/packages/shared/core/utils/system.js b/packages/shared/core/utils/system.js index 416dfbfe6..2bbcfc9c8 100644 --- a/packages/shared/core/utils/system.js +++ b/packages/shared/core/utils/system.js @@ -1,11 +1,12 @@ import PropTypes from 'prop-types' import { styled } from '../styled-engine' +import * as theme from '../theme' import { is, num, get, cascade } from './misc' export const gth = p => { if (!p) return null if (p.theme && p.theme.__smoothUI) return p.theme - return p.__scTheme + return theme } export const lazyTh = name => props => cascade(p => get(gth(p), name), props)