From 364ee5443ff05b6c7ade64e87a03acf867f204a7 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Sun, 7 Jun 2020 23:23:43 +0300 Subject: [PATCH 001/133] export everything from vtl --- babel.config.js | 2 +- tests/test-utils/test-utils.js | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/babel.config.js b/babel.config.js index 28460893..c61b6267 100644 --- a/babel.config.js +++ b/babel.config.js @@ -6,7 +6,7 @@ module.exports = { ], env: { test: { - plugins: ['transform-es2015-modules-commonjs'] + // plugins: ['transform-es2015-modules-commonjs'] } } } diff --git a/tests/test-utils/test-utils.js b/tests/test-utils/test-utils.js index 563f9b0d..701e9b52 100644 --- a/tests/test-utils/test-utils.js +++ b/tests/test-utils/test-utils.js @@ -1,9 +1,9 @@ import '@testing-library/jest-dom/extend-expect' -import { render } from '@testing-library/vue' +import * as vtl from '@testing-library/vue' +import userEvent from '@testing-library/user-event' import icons from '@/packages/chakra-ui-core/src/lib/internal-icons' import theme from '@/packages/chakra-ui-core/src/lib/theme' - const defaultProviders = options => ({ $chakraTheme: () => theme, $chakraColorMode: () => 'light', @@ -11,11 +11,11 @@ const defaultProviders = options => ({ ...options }) -const customRender = (component, ...rest) => { +const render = (component, ...rest) => { const defaults = { provide: () => defaultProviders() } - const utils = render({ ...defaults, ...component }, ...rest) + const utils = vtl.render({ ...defaults, ...component }, ...rest) return { ...utils, asFragment: (innerHTML = utils.container.innerHTML) => { @@ -32,13 +32,14 @@ const customRender = (component, ...rest) => { } } -export function waitMs (ms = 0) { +function waitMs (ms = 0) { return new Promise(resolve => setTimeout(resolve, ms)) } -export { default as userEvent } from '@testing-library/user-event' -export { fireEvent } from '@testing-library/vue' +export * from '@testing-library/vue' export { - customRender as render, + render, + userEvent, + waitMs, defaultProviders } From b1dbd305dd0b8f7481f16f68892073234510d353 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Sun, 7 Jun 2020 23:24:40 +0300 Subject: [PATCH 002/133] test(aspect-ratio): add tests for padding bottom --- .../tests/CAspectRatioBox.test.js | 52 +++++++++++++++---- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/packages/chakra-ui-core/src/CAspectRatioBox/tests/CAspectRatioBox.test.js b/packages/chakra-ui-core/src/CAspectRatioBox/tests/CAspectRatioBox.test.js index 20da297d..90293fdc 100644 --- a/packages/chakra-ui-core/src/CAspectRatioBox/tests/CAspectRatioBox.test.js +++ b/packages/chakra-ui-core/src/CAspectRatioBox/tests/CAspectRatioBox.test.js @@ -1,6 +1,5 @@ import { CAspectRatioBox, CBox } from '../..' -import { render } from '@/tests/test-utils' - +import { render, screen } from '@/tests/test-utils' const renderComponent = (props) => { const inlineAttrs = (props && props.inlineAttrs) || '' const base = { @@ -15,17 +14,53 @@ const renderComponent = (props) => { return render(base) } +/** + * Not sure if we need jest-emotion + * + * Get styles from document.styleSheets + * @param {String} selector + */ +function getElementStyles (selector) { + selector = new RegExp(selector) + let styles = [] + let i; let j; let sel = selector + for (i = 0; i < document.styleSheets.length; ++i) { + for (j = 0; j < document.styleSheets[i].cssRules.length; ++j) { + if (sel.test(document.styleSheets[i].cssRules[j].selectorText)) { + // let selectorText = document.styleSheets[i].cssRules[j].selectorText + let cssText = document.styleSheets[i].cssRules[j].style.cssText + styles += cssText + } + } + } + return styles +} + it('should render correctly', () => { const inlineAttrs = ':ratio="1"' const { asFragment } = renderComponent({ inlineAttrs }) expect(asFragment()).toMatchSnapshot() + + const [, emotionClassName] = [...screen.getByTestId('aspectRatioBox').classList] + const pseudoStyles = getElementStyles(`.${emotionClassName}:before`) + + expect(pseudoStyles).toContain(` + padding-bottom: 100% + `.trim()) }) -it('should have correct styles', () => { - const inlineAttrs = ':ratio="2"' - const { getByTestId } = renderComponent({ inlineAttrs }) - const image = getByTestId('image') - const aspectRatioBox = getByTestId('aspectRatioBox') +it('should have correct styles', async () => { + const inlineAttrs = `:ratio="2"` + renderComponent({ inlineAttrs }) + const image = screen.getByTestId('image') + const aspectRatioBox = screen.getByTestId('aspectRatioBox') + + const [, emotionClassName] = [...aspectRatioBox.classList] + const pseudoStyles = getElementStyles(`.${emotionClassName}:before`) + + expect(pseudoStyles).toContain(` + padding-bottom: 50% + `.trim()) expect(aspectRatioBox).toHaveStyle(` max-width: 400px; @@ -40,7 +75,4 @@ it('should have correct styles', () => { top: 0px; left: 0px; `) - - // TODO: we can't test pseudo elements.. so better test styles? - // aspectRatioBox padding-bottom }) From 77eefca780a32729eb1d09d6e87ec5900b3f4183 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Sat, 13 Jun 2020 16:20:37 +0300 Subject: [PATCH 003/133] chore: fix lint errs --- .../src/CAspectRatioBox/tests/CAspectRatioBox.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/chakra-ui-core/src/CAspectRatioBox/tests/CAspectRatioBox.test.js b/packages/chakra-ui-core/src/CAspectRatioBox/tests/CAspectRatioBox.test.js index 90293fdc..e3935e26 100644 --- a/packages/chakra-ui-core/src/CAspectRatioBox/tests/CAspectRatioBox.test.js +++ b/packages/chakra-ui-core/src/CAspectRatioBox/tests/CAspectRatioBox.test.js @@ -23,12 +23,12 @@ const renderComponent = (props) => { function getElementStyles (selector) { selector = new RegExp(selector) let styles = [] - let i; let j; let sel = selector + let i; let j; const sel = selector for (i = 0; i < document.styleSheets.length; ++i) { for (j = 0; j < document.styleSheets[i].cssRules.length; ++j) { if (sel.test(document.styleSheets[i].cssRules[j].selectorText)) { // let selectorText = document.styleSheets[i].cssRules[j].selectorText - let cssText = document.styleSheets[i].cssRules[j].style.cssText + const cssText = document.styleSheets[i].cssRules[j].style.cssText styles += cssText } } @@ -49,8 +49,8 @@ it('should render correctly', () => { `.trim()) }) -it('should have correct styles', async () => { - const inlineAttrs = `:ratio="2"` +it('should have correct styles', () => { + const inlineAttrs = ':ratio="2"' renderComponent({ inlineAttrs }) const image = screen.getByTestId('image') const aspectRatioBox = screen.getByTestId('aspectRatioBox') From fe2ecd95de8116e8a36921afc115cb17b044071e Mon Sep 17 00:00:00 2001 From: codebender828 Date: Sun, 28 Jun 2020 20:26:52 +0800 Subject: [PATCH 004/133] perf: initial performance refactor --- packages/chakra-ui-core/src/CBox/CBox.js | 104 +++++++----------- .../chakra-ui-core/src/CBox/CBox.stories.js | 38 ++++++- packages/chakra-ui-core/src/CBox/index.js | 1 + .../src/CPseudoBox/CPseudoBox.js | 69 +++++++----- .../src/CPseudoBox/CPseudoBox.stories.js | 91 +++++++-------- .../chakra-ui-core/src/CPseudoBox/index.js | 1 + .../chakra-ui-core/src/CPseudoBox/utils.js | 21 ++-- .../src/config/props/props.config.js | 8 +- .../src/directives/chakra.directive.js | 41 ++++--- .../chakra-ui-core/src/utils/components.js | 81 ++++++++++++++ packages/chakra-ui-core/src/utils/index.js | 3 +- packages/chakra-ui-core/src/utils/object.js | 88 +++++++++++++-- .../chakra-ui-core/src/utils/styled-system.js | 60 ++++++++++ .../chakra-ui-core/src/utils/transform.js | 18 ++- packages/chakra-ui-docs/static/sw.js | 33 +++++- 15 files changed, 467 insertions(+), 190 deletions(-) diff --git a/packages/chakra-ui-core/src/CBox/CBox.js b/packages/chakra-ui-core/src/CBox/CBox.js index 85ff8380..554ef23f 100644 --- a/packages/chakra-ui-core/src/CBox/CBox.js +++ b/packages/chakra-ui-core/src/CBox/CBox.js @@ -9,67 +9,8 @@ */ import { css } from 'emotion' -import { background, border, color, borderRadius, flexbox, grid, layout, position, shadow, space, typography, compose } from 'styled-system' -import { baseProps, propsConfig } from '../config/props' -import { forwardProps } from '../utils' - -const baseEllipsis = { - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap' -} - -/** - * @description Truncates text if `truncate` is set to true. - * @param {Object} props Props - */ -const truncate = (props) => { - if (props.truncate) { - if (!props.lineClamp) { - return baseEllipsis - } - } -} - -/** - * @description Clamps text based on number of lines. - * @param {Object} props Props - */ -const clamp = (props) => { - if (props.lineClamp) { - return { - ...baseEllipsis, - '-webkit-box-orient': 'vertical', - '-webkit-line-clamp': `${props.lineClamp}` - } - } -} - -const decorate = (props) => { - if (props.textDecoration || props.textDecor) { - return { - 'text-decoration': `${props.textDecoration || props.textDecor}` - } - } -} - -export const systemProps = compose( - space, - layout, - color, - background, - border, - borderRadius, - grid, - position, - shadow, - decorate, - typography, - flexbox, - propsConfig, - truncate, - clamp -) +import { baseProps } from '../config/props' +import { forwardProps, createStyledAttrsMixin, systemProps } from '../utils' /** * CBox component @@ -95,15 +36,19 @@ const CBox = { computed: { theme () { return this.$chakraTheme() + }, + boxClassName () { + const { as, to, ...cleanedStyleProps } = forwardProps(this.$props) + const boxStylesObject = systemProps({ ...cleanedStyleProps, theme: this.theme }) + return css(boxStylesObject) } }, render (h) { - const { as, to, ...cleanedStyleProps } = forwardProps(this.$props) - const boxStylesObject = systemProps({ ...cleanedStyleProps, theme: this.theme }) - - return h(as, { - props: { to }, - class: css(boxStylesObject), + return h(this.as, { + props: { + to: this.to + }, + class: this.boxClassName, on: this.$listeners, attrs: { 'data-chakra-component': 'CBox' @@ -113,3 +58,28 @@ const CBox = { } export default CBox + +export const _CBox = { + name: 'CBox', + mixins: [createStyledAttrsMixin('CBox')], + props: { + as: { + type: [String, Object], + default: 'div' + }, + to: { + type: [String, Object], + default: '' + } + }, + render (h) { + return h(this.as, { + props: { + to: this.to + }, + class: this.className, + on: this.listeners$, + attrs: this.computedAttrs + }, this.$slots.default) + } +} diff --git a/packages/chakra-ui-core/src/CBox/CBox.stories.js b/packages/chakra-ui-core/src/CBox/CBox.stories.js index 4814cf2a..5fcdc2f2 100644 --- a/packages/chakra-ui-core/src/CBox/CBox.stories.js +++ b/packages/chakra-ui-core/src/CBox/CBox.stories.js @@ -1,5 +1,6 @@ import { storiesOf } from '@storybook/vue' -import { CBox } from '..' +import { _CBox } from './CBox.js' +import { CBox, CInput } from '..' storiesOf('UI | Box', module) .add('Box', () => ({ @@ -27,15 +28,44 @@ storiesOf('UI | Box', module) components: { CBox }, template: `
- - - + +
` })) + .add('_CBox Box', () => ({ + components: { CBox: _CBox, CInput }, + template: ` +
+
+
+
+ +
+
+ + {{ title }} + + + Another ignored box + +
+ `, + data () { + return { + title: 'Hello world' + } + }, + computed: { + color () { + return this.title.length > 4 ? 'red' : 'blue' + } + } + })) diff --git a/packages/chakra-ui-core/src/CBox/index.js b/packages/chakra-ui-core/src/CBox/index.js index 7eb01a36..02a022aa 100644 --- a/packages/chakra-ui-core/src/CBox/index.js +++ b/packages/chakra-ui-core/src/CBox/index.js @@ -1,2 +1,3 @@ import CBox from './CBox' export default CBox +export * from './CBox' diff --git a/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js b/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js index bc078095..d7ab00a9 100644 --- a/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js +++ b/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js @@ -9,26 +9,11 @@ import { css } from 'emotion' import __css from '@styled-system/css' -import { background, border, color, borderRadius, flexbox, grid, layout, position, shadow, space, typography, compose } from 'styled-system' import CBox from '../CBox' -import styleProps, { propsConfig } from '../config/props' +import styleProps from '../config/props' +import { systemProps, createStyledAttrsMixin } from '../utils' import { parsePseudoStyles } from './utils' -const systemProps = compose( - layout, - color, - space, - background, - border, - borderRadius, - grid, - position, - shadow, - typography, - flexbox, - propsConfig -) - /** * CPseudoBox component * @@ -52,19 +37,21 @@ const CPseudoBox = { computed: { theme () { return this.$chakraTheme() + }, + pseudoBoxClassName () { + const { as, to, ...cleanedStyleProps } = this.$props + const { pseudoStyles, baseStyles } = parsePseudoStyles(cleanedStyleProps) + const _baseStyles = systemProps({ ...baseStyles, theme: this.theme }) + const _pseudoStyles = __css(pseudoStyles)(this.theme) + return css({ ..._baseStyles, ..._pseudoStyles }) } }, render (h) { - const { as, to, ...cleanedStyleProps } = this.$props - const { pseudoStyles, baseProps } = parsePseudoStyles(cleanedStyleProps) - const baseStyles = systemProps({ ...baseProps, theme: this.theme }) - const _pseudoStyles = __css(pseudoStyles)(this.theme) - return h(CBox, { - class: css({ ...baseStyles, ..._pseudoStyles }), + class: this.pseudoBoxClassName, props: { - as, - to + as: this.as, + to: this.to }, attrs: { 'data-chakra-component': 'CPseudoBox' @@ -73,4 +60,36 @@ const CPseudoBox = { } } +/** + * CPseudoBox component + * + * The pseudobox component that accepts pseudo props + * + * @extends CBox + * @see Docs https://vue.chakra-ui.com/pseudobox + */ +export const _CPseudoBox = { + name: 'CPseudoBox', + mixins: [createStyledAttrsMixin('CPseudoBox', true)], + props: { + as: { + type: [String, Object], + default: () => 'div' + }, + to: [String, Object], + chakraId: String + }, + render (h) { + return h(CBox, { + props: { + as: this.as, + to: this.to + }, + class: this.className, + on: this.listeners$, + attrs: this.computedAttrs + }, this.$slots.default) + } +} + export default CPseudoBox diff --git a/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.stories.js b/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.stories.js index 376ee34c..c247f302 100644 --- a/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.stories.js +++ b/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.stories.js @@ -1,16 +1,17 @@ import { storiesOf } from '@storybook/vue' -import CBox from '../CBox' -import CPseudoBox from '../CPseudoBox' +// import CBox from '../CBox' +import { _CPseudoBox } from '../CPseudoBox' storiesOf('UI | PseudoBox', module) .add('PseudoBox | :hover', () => ({ - components: { CPseudoBox }, + components: { CPseudoBox: _CPseudoBox }, template: ` ` })) - .add('Pseudobox | :odd', () => ({ - components: { CBox, CPseudoBox }, - data () { - return { - boxes: [ - { - id: 1, - name: 'Box 1' - }, - { - id: 2, - name: 'Box 2' - }, - { - id: 3, - name: 'Box 3' - } - ] - } - }, - template: ` - - - {{ box.name }} - - - ` - })) + // .add('Pseudobox | :odd', () => ({ + // components: { CBox, CPseudoBox }, + // data () { + // return { + // boxes: [ + // { + // id: 1, + // name: 'Box 1' + // }, + // { + // id: 2, + // name: 'Box 2' + // }, + // { + // id: 3, + // name: 'Box 3' + // } + // ] + // } + // }, + // template: ` + // + // + // {{ box.name }} + // + // + // ` + // })) diff --git a/packages/chakra-ui-core/src/CPseudoBox/index.js b/packages/chakra-ui-core/src/CPseudoBox/index.js index 583e09f1..b3da1097 100644 --- a/packages/chakra-ui-core/src/CPseudoBox/index.js +++ b/packages/chakra-ui-core/src/CPseudoBox/index.js @@ -1,2 +1,3 @@ import CPseudoBox from './CPseudoBox' export default CPseudoBox +export * from './CPseudoBox' diff --git a/packages/chakra-ui-core/src/CPseudoBox/utils.js b/packages/chakra-ui-core/src/CPseudoBox/utils.js index 1fc902f0..3f336ca2 100644 --- a/packages/chakra-ui-core/src/CPseudoBox/utils.js +++ b/packages/chakra-ui-core/src/CPseudoBox/utils.js @@ -1,5 +1,5 @@ -import map from 'lodash-es/map' -import { forwardProps, filterBaseStyles, filterPseudo as getPseudoStyles, tx } from '../utils' +import { map } from 'lodash-es' +import { tx, splitProps, forwardProps } from '../utils' /** * PseudoBox pseudo selectors @@ -33,20 +33,19 @@ export const selectors = { /** * Filter undefined props and parse pseudo style props to generate css styles object - * @param {Object} props - Props - * @returns {Object} Parsed pseudo styles object + * @param {Object} props styles objects + * @returns {{ baseStyles: Object, pseudoStyles: Object }} */ export function parsePseudoStyles (props) { - const pseudoStyles = {} + const _pseudoStyles = {} const clean = forwardProps(props) - const pseudoProps = getPseudoStyles(clean) - const baseProps = filterBaseStyles(clean) - const result = map(pseudoProps, (value, prop) => ({ prop, value })) + const { baseStyles, pseudoStyles } = splitProps(clean) + const result = map(pseudoStyles, (value, prop) => ({ prop, value })) result.forEach((pair) => { if (selectors[pair.prop]) { - pseudoStyles[selectors[pair.prop]] = tx(pair.value) + _pseudoStyles[selectors[pair.prop]] = tx(pair.value) } }) - const mergedPseudoBoxStyles = { pseudoStyles, baseProps } - return mergedPseudoBoxStyles + + return { pseudoStyles: _pseudoStyles, baseStyles } } diff --git a/packages/chakra-ui-core/src/config/props/props.config.js b/packages/chakra-ui-core/src/config/props/props.config.js index 7ce714cd..4b5702f7 100644 --- a/packages/chakra-ui-core/src/config/props/props.config.js +++ b/packages/chakra-ui-core/src/config/props/props.config.js @@ -98,19 +98,19 @@ export const config = { scale: 'borders' }, bl: { - property: 'border-left', + property: 'borderLeft', scale: 'borders' }, bt: { - property: 'border-top', + property: 'borderTop', scale: 'borders' }, br: { - property: 'border-right', + property: 'borderRight', scale: 'borders' }, bb: { - property: 'border-bottom', + property: 'borderBottom', scale: 'borders' }, textDecoration: { diff --git a/packages/chakra-ui-core/src/directives/chakra.directive.js b/packages/chakra-ui-core/src/directives/chakra.directive.js index 78906ddc..dd6762f7 100644 --- a/packages/chakra-ui-core/src/directives/chakra.directive.js +++ b/packages/chakra-ui-core/src/directives/chakra.directive.js @@ -79,26 +79,33 @@ export function createServerDirective (theme) { /** Creates Client `v-chakra` Directive */ export function createClientDirective (theme) { - return { - bind (el, binding, vnode) { - const [className, pure] = createClassName(vnode.data.attrs, theme) - el.classList.add(className) - purifyAttrs(el, pure) + function applyClientStyles (el, binding, vnode) { + const [className, pure] = createClassName(vnode.data.attrs, theme) + el.classList.add(className) + purifyAttrs(el, pure) - if (binding.value) { - if (typeof binding.value === 'object') { - const [className, pure] = createClassName(binding.value, theme, true) - el.classList.add(className) - purifyAttrs(el, pure) - } + if (binding.value) { + if (typeof binding.value === 'object') { + const [className, pure] = createClassName(binding.value, theme, true) + el.classList.add(className) + purifyAttrs(el, pure) + } - if (typeof binding.value === 'function') { - const styles = binding.value(theme) - const [className, pure] = createClassName(styles, theme, true) - el.classList.add(className) - purifyAttrs(el, pure) - } + if (typeof binding.value === 'function') { + const styles = binding.value(theme) + const [className, pure] = createClassName(styles, theme, true) + el.classList.add(className) + purifyAttrs(el, pure) } } } + + return { + bind (el, binding, vnode) { + applyClientStyles(el, binding, vnode) + }, + update (el, binding, vnode) { + applyClientStyles(el, binding, vnode) + } + } } diff --git a/packages/chakra-ui-core/src/utils/components.js b/packages/chakra-ui-core/src/utils/components.js index 116a4223..7eddf21e 100644 --- a/packages/chakra-ui-core/src/utils/components.js +++ b/packages/chakra-ui-core/src/utils/components.js @@ -1,3 +1,84 @@ +import { css } from 'emotion' +import __css from '@styled-system/css' +import { hasOwn } from '../utils' +import { parsePseudoStyles } from '../CPseudoBox/utils' +import { systemProps } from './styled-system' +import { purifyStyleAttributes, filterChakraStyleProps } from './object' + export const isVueComponent = (value) => { return (!!value && !!value.$el) } + +/** + * Makes a cache watcher handler for data property. + * This utility helps prevent unnecessary re-renders + * for primitives with changes in the $parent $attrs + * and $listeners objects + * @param {String} property +*/ +export function createWatcher (property) { + return { + handler (newVal, oldVal) { + for (const key in oldVal) { + if (!hasOwn(newVal, key)) { + this.$delete(this.$data[property], key) + } + } + for (const key in newVal) { + this.$set(this.$data[property], key, newVal[key]) + } + }, + immediate: true + } +} + +/** + * Create mixin for style attributes + * @param {String} name Component name +*/ +export const createStyledAttrsMixin = (name, isPseudo) => ({ + inheritAttrs: false, + inject: ['$chakraTheme'], + data () { + return { + attrs$: {}, + listeners$: {} + } + }, + computed: { + theme () { + return this.$chakraTheme() + }, + /** Split style attributes and native attributes */ + splitProps () { + const styleProps = filterChakraStyleProps(this.$data.attrs$) + const attrs = purifyStyleAttributes(this.$data.attrs$, styleProps) + return { + styleProps, + attrs + } + }, + className () { + const { styleProps } = this.splitProps + if (isPseudo) { + const { pseudoStyles, baseStyles } = parsePseudoStyles(styleProps) + const _baseStyles = systemProps({ ...baseStyles, theme: this.theme }) + const _pseudoStyles = __css(pseudoStyles)(this.theme) + return css({ ..._baseStyles, ..._pseudoStyles }) + } + const boxStylesObject = systemProps({ ...styleProps, theme: this.theme }) + return css(boxStylesObject) + }, + /** Computed attributes object */ + computedAttrs () { + return { + ...this.splitProps.attrs, + 'data-chakra-component': name + } + } + }, + watch: { + $attrs: createWatcher('attrs$'), + $listeners: createWatcher('listeners$') + } +}) diff --git a/packages/chakra-ui-core/src/utils/index.js b/packages/chakra-ui-core/src/utils/index.js index 8690d6d0..54c94c34 100644 --- a/packages/chakra-ui-core/src/utils/index.js +++ b/packages/chakra-ui-core/src/utils/index.js @@ -1,6 +1,7 @@ export { default as Logger } from './logger' export { transformAlias as tx, valueToPercent } from './transform' -export { pickProperty as forwardProps, filterBaseStyles, filterPseudo, unwrapValues } from './object' +export { pickProperty as forwardProps } from './object' +export * from './object' export * from './color' export { parsePackIcons } from './icons' export * from './dom' diff --git a/packages/chakra-ui-core/src/utils/object.js b/packages/chakra-ui-core/src/utils/object.js index 8e12dc19..0e8480b8 100644 --- a/packages/chakra-ui-core/src/utils/object.js +++ b/packages/chakra-ui-core/src/utils/object.js @@ -1,5 +1,6 @@ -import { pickBy, mapValues } from 'lodash-es' -import startsWith from 'lodash-es/startsWith' +import { pickBy, startsWith } from 'lodash-es' +import { camelize, kebabify } from '../utils' +import styleProps from '../config/props' /** * Clears out all undefined properties from an object. @@ -7,7 +8,12 @@ import startsWith from 'lodash-es/startsWith' * @returns {Object} Sanitized object with defined values. */ export function pickProperty (props) { - const pure = pickBy(props, prop => prop !== undefined) + const pure = {} + for (const prop in props) { + if (props[prop] !== undefined) { + pure[prop] = props[prop] + } + } return pure } @@ -35,13 +41,25 @@ export function filterBaseStyles (props) { return pseudos } -/** - * Unwraps `value` getter values from ref property values in refs object. - * @param {Object} props - * @returns {Object} Unwrapped values object - */ -export function unwrapValues (props) { - return mapValues(props, 'value') +/** Filter attrs and return object of chakra props */ +export function filterChakraStyleProps (attrs) { + const pure = {} + for (const _prop in attrs) { + const prop = camelize(_prop) + if (styleProps[prop]) { + pure[prop] = attrs[_prop] + } + } + return pure +} + +/** Purify's Chakra Attributes from VNode object */ +export function purifyStyleAttributes (attrs = {}, props = {}) { + for (const attr in props) { + delete attrs[kebabify(attr)] + delete attrs[camelize(attr)] + } + return attrs } /** @@ -52,3 +70,53 @@ export function unwrapValues (props) { export function isNonNullObject (value) { return typeof value === 'object' && value !== null } + +/** + * Checks if object has a specific property. + * @param {Object} obj + * @param {String} prop + */ +export const hasOwn = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) + +/** + * Checks to see if objects in empty + * @param {Object} object + */ +export function isEmpty (object) { + for (const key in object) { + // Should iterate only once + if (hasOwn(object, key)) { + return false + } + return true + } +} + +/** + * Splits user styles into base and pseudo styles + * @param {Object} props styles objects + * @returns {{ baseStyles: Object, pseudoStyles: Object }} + */ +export function splitProps (props) { + const baseStyles = {} + const pseudoStyles = {} + + const styles = { + baseStyles, + pseudoStyles + } + + if (!props || isEmpty(props)) { + return styles + } + + for (const key in props) { + if (key.startsWith('_')) { + styles.pseudoStyles[key] = props[key] + } else { + styles.baseStyles[key] = props[key] + } + } + + return styles +} diff --git a/packages/chakra-ui-core/src/utils/styled-system.js b/packages/chakra-ui-core/src/utils/styled-system.js index 2e47e180..8e957374 100644 --- a/packages/chakra-ui-core/src/utils/styled-system.js +++ b/packages/chakra-ui-core/src/utils/styled-system.js @@ -1,3 +1,5 @@ +import { background, border, color, borderRadius, flexbox, grid, layout, position, shadow, space, typography, compose } from 'styled-system' +import { propsConfig } from '../config/props' /** * Existential getter function that can be used in any style declaration to get a value @@ -18,3 +20,61 @@ export const __get = (obj, key, def, p, undef) => { return obj === undef ? def : obj } + +const baseEllipsis = { + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap' +} + +/** + * @description Truncates text if `truncate` is set to true. + * @param {Object} props Props + */ +const truncate = (props) => { + if (props.truncate) { + if (!props.lineClamp) { + return baseEllipsis + } + } +} + +/** + * @description Clamps text based on number of lines. + * @param {Object} props Props + */ +const clamp = (props) => { + if (props.lineClamp) { + return { + ...baseEllipsis, + '-webkit-box-orient': 'vertical', + '-webkit-line-clamp': `${props.lineClamp}` + } + } +} + +const decorate = (props) => { + if (props.textDecoration || props.textDecor) { + return { + 'text-decoration': `${props.textDecoration || props.textDecor}` + } + } +} + +export const systemProps = compose( + space, + layout, + color, + background, + border, + borderRadius, + grid, + position, + shadow, + decorate, + typography, + flexbox, + propsConfig, + truncate, + clamp +) diff --git a/packages/chakra-ui-core/src/utils/transform.js b/packages/chakra-ui-core/src/utils/transform.js index d0db1465..3620f9a9 100644 --- a/packages/chakra-ui-core/src/utils/transform.js +++ b/packages/chakra-ui-core/src/utils/transform.js @@ -1,4 +1,5 @@ import { config } from '../config/props' +import { isEmpty } from './object' /** * @description Transforms the custom prop alias to a format that styled-system CSS supports @@ -8,18 +9,20 @@ import { config } from '../config/props' * @see chakra-ui PseudoBox tx_ method. */ function normalizeAlias (prop, propValue) { - const configKeys = Object.keys(config) const result = {} + const entry = config[prop] - if (configKeys.includes(prop)) { - const { properties, property } = config[prop] + if (entry) { + const { properties, property } = entry if (properties) { - properties.forEach(_cssProp => (result[_cssProp] = propValue)) + for (const _cssProp in properties) { + result[_cssProp] = propValue + } } if (property) { result[property] = propValue } - if (config[prop] === true) { + if (entry === true) { result[prop] = propValue } } else { @@ -35,6 +38,10 @@ function normalizeAlias (prop, propValue) { */ export const transformAlias = (props) => { let result = {} + if (!props || isEmpty(props)) { + return result + } + for (const prop in props) { if (typeof props[prop] === 'object') { result = { ...result, [prop]: transformAlias(props[prop]) } @@ -42,6 +49,7 @@ export const transformAlias = (props) => { result = { ...result, ...normalizeAlias(prop, props[prop]) } } } + return result } diff --git a/packages/chakra-ui-docs/static/sw.js b/packages/chakra-ui-docs/static/sw.js index ea698990..3f26afec 100644 --- a/packages/chakra-ui-docs/static/sw.js +++ b/packages/chakra-ui-docs/static/sw.js @@ -1 +1,32 @@ -// THIS FILE SHOULD NOT BE VERSION CONTROLLED +importScripts('https://cdn.jsdelivr.net/npm/workbox-cdn@4.3.1/workbox/workbox-sw.js') + +// -------------------------------------------------- +// Configure +// -------------------------------------------------- + +// Set workbox config +workbox.setConfig({ + "debug": false +}) + +// Start controlling any existing clients as soon as it activates +workbox.core.clientsClaim() + +// Skip over the SW waiting lifecycle stage +workbox.core.skipWaiting() + +workbox.precaching.cleanupOutdatedCaches() + +// -------------------------------------------------- +// Precaches +// -------------------------------------------------- + +// Precache assets + +// -------------------------------------------------- +// Runtime Caching +// -------------------------------------------------- + +// Register route handlers for runtimeCaching +workbox.routing.registerRoute(new RegExp('/_nuxt/'), new workbox.strategies.CacheFirst ({}), 'GET') +workbox.routing.registerRoute(new RegExp('/'), new workbox.strategies.NetworkFirst ({}), 'GET') From b92f3d1544fa284d6a73ea9e2b46b86111c0a106 Mon Sep 17 00:00:00 2001 From: codebender828 Date: Sun, 28 Jun 2020 20:56:22 +0800 Subject: [PATCH 005/133] chore: add more nodes to box storybook --- .gitignore | 3 ++- packages/chakra-ui-core/src/CBox/CBox.stories.js | 5 +---- packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js | 6 ++---- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index d7c5dce2..84fa0012 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,5 @@ packages/*/node_modules lerna-debug.log .now config/.env -packages/nuxt-chakra/.github \ No newline at end of file +packages/nuxt-chakra/.github +packages/chakra-ui-docs/static/sw.js \ No newline at end of file diff --git a/packages/chakra-ui-core/src/CBox/CBox.stories.js b/packages/chakra-ui-core/src/CBox/CBox.stories.js index 5fcdc2f2..6585730e 100644 --- a/packages/chakra-ui-core/src/CBox/CBox.stories.js +++ b/packages/chakra-ui-core/src/CBox/CBox.stories.js @@ -50,12 +50,9 @@ storiesOf('UI | Box', module)

- + {{ title }} - - Another ignored box - `, data () { diff --git a/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js b/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js index d7ab00a9..6d1a83fb 100644 --- a/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js +++ b/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js @@ -76,13 +76,11 @@ export const _CPseudoBox = { type: [String, Object], default: () => 'div' }, - to: [String, Object], - chakraId: String + to: [String, Object] }, render (h) { - return h(CBox, { + return h(this.as, { props: { - as: this.as, to: this.to }, class: this.className, From 8c438d0b319b3729492beaa564a8405b2891a7d0 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Wed, 1 Jul 2020 15:47:44 +0300 Subject: [PATCH 006/133] test(aspect-ratio): refactor and fix AspectRatio tests --- .../src/CAccordion/tests/CAccordion.test.js | 126 ++++++++---------- 1 file changed, 57 insertions(+), 69 deletions(-) diff --git a/packages/chakra-ui-core/src/CAccordion/tests/CAccordion.test.js b/packages/chakra-ui-core/src/CAccordion/tests/CAccordion.test.js index f6031289..d6fe79a5 100644 --- a/packages/chakra-ui-core/src/CAccordion/tests/CAccordion.test.js +++ b/packages/chakra-ui-core/src/CAccordion/tests/CAccordion.test.js @@ -1,5 +1,5 @@ import { CAccordion, CAccordionItem, CAccordionHeader, CAccordionPanel, CAccordionIcon } from '..' -import { render, userEvent, fireEvent } from '@/tests/test-utils' +import { render, userEvent, fireEvent, screen } from '@/tests/test-utils' const renderComponent = (props) => { const base = { @@ -10,9 +10,8 @@ const renderComponent = (props) => { } it('should render correctly', () => { - const { asFragment } = renderComponent( - { - template: ` + const { asFragment } = renderComponent({ + template: ` Section 1 title @@ -20,13 +19,12 @@ it('should render correctly', () => { ` - } - ) + }) expect(asFragment()).toMatchSnapshot() }) it('uncontrolled: It opens the accordion panel', () => { - const { getByTestId } = renderComponent({ + renderComponent({ template: ` @@ -35,14 +33,13 @@ it('uncontrolled: It opens the accordion panel', () => { ` - } - ) - const button = getByTestId('button') + }) + const button = screen.getByTestId('button') expect(button).toHaveAttribute('aria-expanded', 'true') }) -it('uncontrolled: toggles the accordion on click', () => { - const { getByText } = renderComponent({ +it('uncontrolled: toggles the accordion on click', async () => { + renderComponent({ template: ` @@ -52,19 +49,17 @@ it('uncontrolled: toggles the accordion on click', () => { ` }) - const trigger = getByText('Trigger') - - userEvent.click(trigger) - expect(trigger).toHaveAttribute('aria-expanded', 'true') + await userEvent.click(screen.getByText('Trigger')) + expect(screen.getByText('Trigger')).toHaveAttribute('aria-expanded', 'true') // you can't toggle an accordion without passing `allowToggle` - userEvent.click(trigger) - expect(trigger).toHaveAttribute('aria-expanded', 'true') + await userEvent.click(screen.getByText('Trigger')) + expect(screen.getByText('Trigger')).toHaveAttribute('aria-expanded', 'true') }) // test the only one accordion can be visible + is not togglable -it('only one accordion can be visible + is not togglable', () => { - const { getByText } = renderComponent({ +it('only one accordion can be visible + is not togglable', async () => { + renderComponent({ template: ` @@ -78,21 +73,19 @@ it('only one accordion can be visible + is not togglable', () => { ` }) - const firstAccordion = getByText('First section') - - userEvent.click(firstAccordion) - expect(firstAccordion).toHaveAttribute('aria-expanded', 'true') + await userEvent.click(screen.getByText('First section')) + expect(screen.getByText('First section')).toHaveAttribute('aria-expanded', 'true') - userEvent.click(firstAccordion) - expect(firstAccordion).toHaveAttribute('aria-expanded', 'true') + await userEvent.click(screen.getByText('First section')) + expect(screen.getByText('First section')).toHaveAttribute('aria-expanded', 'true') }) // test the only one accordion can be visible + is togglable -it('only one accordion can be visible + is togglable', () => { - const { getByText } = renderComponent({ +it('only one accordion can be visible + is togglable', async () => { + renderComponent({ template: ` - + First section Panel 1 @@ -102,21 +95,19 @@ it('only one accordion can be visible + is togglable', () => { ` }) - const firstAccordion = getByText('First section') - // TODO: Why its not working? - // fireEvent.click(firstAccordion) - // expect(firstAccordion).toHaveAttribute('aria-expanded', 'false') + await userEvent.click(screen.getByText('First section')) + expect(screen.getByText('First section')).not.toHaveAttribute('aria-expanded') // false or null? - userEvent.click(firstAccordion) - expect(firstAccordion).toHaveAttribute('aria-expanded', 'true') + await userEvent.click(screen.getByText('First section')) + expect(screen.getByText('First section')).toHaveAttribute('aria-expanded', 'true') }) // test that multiple accordions can be opened + is togglable -it('multiple accordions can be opened + is togglable', () => { - const { getByText } = renderComponent({ +it('multiple accordions can be opened + is togglable', async () => { + renderComponent({ template: ` - + First section Panel 1 @@ -128,19 +119,16 @@ it('multiple accordions can be opened + is togglable', () => { ` }) - const firstAccordion = getByText('First section') - const secondAccordion = getByText('Second section') - - userEvent.click(firstAccordion) - expect(firstAccordion).toHaveAttribute('aria-expanded', 'true') + expect(screen.getByText('First section')).toHaveAttribute('aria-expanded', 'true') + expect(screen.getByText('Second section')).toHaveAttribute('aria-expanded', 'true') - userEvent.click(secondAccordion) - expect(firstAccordion).toHaveAttribute('aria-expanded', 'true') + await userEvent.click(screen.getByText('First section')) + expect(screen.getByText('First section')).not.toHaveAttribute('aria-expanded') }) // it has the proper aria attributes it('has the proper aria attributes', () => { - const { getByText, getByTestId } = renderComponent({ + renderComponent({ template: ` @@ -149,16 +137,16 @@ it('has the proper aria attributes', () => { ` }) - const button = getByText('Section 1 title') - const panel = getByTestId('panel1') + const button = screen.getByText('Section 1 title') + const panel = screen.getByTestId('panel1') expect(button).toHaveAttribute('aria-controls') expect(button).toHaveAttribute('aria-expanded') expect(panel).toHaveAttribute('aria-labelledby') }) // test that tab moves focus to the next focusable element -it('tab moves focus to the next focusable element', () => { - const { getByText } = renderComponent({ +it('tab moves focus to the next focusable element', async () => { + renderComponent({ template: ` @@ -176,23 +164,23 @@ it('tab moves focus to the next focusable element', () => { ` }) - const first = getByText('First section') - const second = getByText('Second section') - const last = getByText('Last section') + const first = screen.getByText('First section') + const second = screen.getByText('Second section') + const last = screen.getByText('Last section') - userEvent.tab() + await userEvent.tab() expect(first).toHaveFocus() - userEvent.tab() + await userEvent.tab() expect(second).toHaveFocus() - userEvent.tab() + await userEvent.tab() expect(last).toHaveFocus() }) // test that aria-contols for button is same as id for panel it('aria-contols for button is same as id for panel', () => { - const { getByText, getByTestId } = renderComponent({ + renderComponent({ template: ` @@ -202,14 +190,14 @@ it('aria-contols for button is same as id for panel', () => { ` }) - const button = getByText('Section 1 title') - const panel = getByTestId('panel1') + const button = screen.getByText('Section 1 title') + const panel = screen.getByTestId('panel1') expect(button.getAttribute('aria-controls')).toEqual(panel.getAttribute('id')) }) // test that aria-expanded is true/false when accordion is open/closed it('aria-expanded is true/false when accordion is open/closed', () => { - const { getByText } = renderComponent({ + renderComponent({ template: ` @@ -223,13 +211,13 @@ it('aria-expanded is true/false when accordion is open/closed', () => { ` }) - const button = getByText('Section 1 title') + const button = screen.getByText('Section 1 title') expect(button).toHaveAttribute('aria-expanded', 'true') }) // test that panel has role=region and aria-labelledby it('panel has role=region and aria-labelledby', () => { - const { getByTestId } = renderComponent({ + renderComponent({ template: ` @@ -238,15 +226,15 @@ it('panel has role=region and aria-labelledby', () => { ` }) - const panel = getByTestId('panel1') + const panel = screen.getByTestId('panel1') expect(panel).toHaveAttribute('aria-labelledby') expect(panel).toHaveAttribute('role', 'region') }) // eslint-disable-next-line no-undef -xit('arrow up & down moves focus to next/previous accordion', () => { - const { getByText } = renderComponent({ +xit('arrow up & down moves focus to next/previous accordion', async () => { + renderComponent({ template: ` @@ -260,12 +248,12 @@ xit('arrow up & down moves focus to next/previous accordion', () => { ` }) - const first = getByText('Section 1 title') - const second = getByText('Section 2 title') + const first = screen.getByText('Section 1 title') + const second = screen.getByText('Section 2 title') - fireEvent.keyDown(first, { key: 'ArrowDown', keyCode: 40 }) + await fireEvent.keyDown(first, { key: 'ArrowDown', keyCode: 40 }) expect(second).toHaveFocus() - fireEvent.keyDown(second, { key: 'ArrowUp', keyCode: 38 }) + await fireEvent.keyDown(second, { key: 'ArrowUp', keyCode: 38 }) expect(first).toHaveFocus() }) From eb768bf687040ba1b2f2dd7162b68fa701978fd9 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Wed, 1 Jul 2020 15:54:25 +0300 Subject: [PATCH 007/133] test(alert): add tests for alert icons and refactor --- .../src/CAlert/tests/CAlert.test.js | 53 +++--- .../tests/__snapshots__/CAlert.test.js.snap | 178 ++---------------- 2 files changed, 46 insertions(+), 185 deletions(-) diff --git a/packages/chakra-ui-core/src/CAlert/tests/CAlert.test.js b/packages/chakra-ui-core/src/CAlert/tests/CAlert.test.js index 57306430..bfbeea3c 100644 --- a/packages/chakra-ui-core/src/CAlert/tests/CAlert.test.js +++ b/packages/chakra-ui-core/src/CAlert/tests/CAlert.test.js @@ -1,14 +1,12 @@ import { CAlert, CAlertIcon, CAlertTitle, CAlertDescription, CStack } from '../..' -import icons from '../../lib/internal-icons' -import { render, defaultProviders } from '@/tests/test-utils' +import { render, screen } from '@/tests/test-utils' const renderComponent = (props) => { const base = { components: { CAlert, CAlertTitle, CAlertDescription, CAlertIcon, CStack }, - provide: () => defaultProviders({ $chakraIcons: { add: icons.add } }), template: ` - + alert title alert description `, @@ -16,23 +14,12 @@ const renderComponent = (props) => { } return render(base) } + it('should render correctly', () => { const { asFragment } = renderComponent() expect(asFragment()).toMatchSnapshot() }) -it('should display title', () => { - const { getByText } = renderComponent() - - expect(getByText('alert title')).toBeInTheDocument() -}) - -it('should display description', () => { - const { getByText } = renderComponent() - - expect(getByText('alert description')).toBeInTheDocument() -}) - it('should override icon if set explicitly', () => { const { asFragment } = renderComponent({ template: ` @@ -44,17 +31,6 @@ it('should override icon if set explicitly', () => { expect(asFragment()).toMatchSnapshot() }) -it('should have role=alert', () => { - const { getByRole } = renderComponent({ - template: ` - - - ` - }) - - getByRole('alert') -}) - it('should render correct variant styles', () => { const { asFragment } = renderComponent({ template: ` @@ -81,3 +57,26 @@ it('should render correct variant styles', () => { expect(asFragment()).toMatchSnapshot() }) + +it('should display title', () => { + renderComponent() + + expect(screen.getByText('alert title')).toBeInTheDocument() +}) + +it('should display description', () => { + renderComponent() + + expect(screen.getByText('alert description')).toBeInTheDocument() +}) + +it('should have role=alert', () => { + renderComponent({ + template: ` + + + ` + }) + + screen.getByRole('alert') +}) diff --git a/packages/chakra-ui-core/src/CAlert/tests/__snapshots__/CAlert.test.js.snap b/packages/chakra-ui-core/src/CAlert/tests/__snapshots__/CAlert.test.js.snap index c631a8ae..1f3960a7 100644 --- a/packages/chakra-ui-core/src/CAlert/tests/__snapshots__/CAlert.test.js.snap +++ b/packages/chakra-ui-core/src/CAlert/tests/__snapshots__/CAlert.test.js.snap @@ -44,39 +44,11 @@ exports[`should render correct variant styles 1`] = ` viewBox="0 0 24 24" > - - - - - - - - - - - - - - - + Data uploaded to the server. Fire on! @@ -94,39 +66,11 @@ exports[`should render correct variant styles 1`] = ` viewBox="0 0 24 24" > - - - - - - - - - - - - - - - + Data uploaded to the server. Fire on! @@ -144,39 +88,11 @@ exports[`should render correct variant styles 1`] = ` viewBox="0 0 24 24" > - - - - - - - - - - - - - - - + Data uploaded to the server. Fire on! @@ -194,39 +110,11 @@ exports[`should render correct variant styles 1`] = ` viewBox="0 0 24 24" > - - - - - - - - - - - - - - - + Data uploaded to the server. Fire on! @@ -251,36 +139,10 @@ exports[`should render correctly 1`] = ` > - - - - - - - - - - - - - + From ea6011fc4ab57c0662b3e47e3c69267d9d2ceef4 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Wed, 1 Jul 2020 16:09:54 +0300 Subject: [PATCH 008/133] test(alert-dialog): refactor alert dialog tests --- .../CAlertDialog/tests/CAlertDialog.test.js | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/chakra-ui-core/src/CAlertDialog/tests/CAlertDialog.test.js b/packages/chakra-ui-core/src/CAlertDialog/tests/CAlertDialog.test.js index 26fed9ee..43ee113f 100644 --- a/packages/chakra-ui-core/src/CAlertDialog/tests/CAlertDialog.test.js +++ b/packages/chakra-ui-core/src/CAlertDialog/tests/CAlertDialog.test.js @@ -1,6 +1,5 @@ -import Vue from 'vue' import { CButton, CAlertDialog, CAlertDialogContent, CAlertDialogBody, CAlertDialogFooter, CAlertDialogOverlay, CAlertDialogHeader } from '../..' -import { render, userEvent, fireEvent, waitMs } from '@/tests/test-utils' +import { render, userEvent, fireEvent, wait, screen } from '@/tests/test-utils' import { useId } from '@/packages/chakra-ui-core/src/utils' // mocks @@ -49,18 +48,19 @@ it('should render correctly', async () => { const inlineAttrs = 'isOpen' const { asFragment } = renderComponent({ inlineAttrs }) - await Vue.nextTick() - - expect(asFragment(document.body.innerHTML)).toMatchSnapshot() + await wait(() => { + expect(asFragment(document.body.innerHTML)).toMatchSnapshot() + }) }) test('clicking the close button calls the onClose callback', async () => { const onClose = jest.fn() const inlineAttrs = 'isOpen :on-close="close"' - const { getByTestId } = renderComponent({ inlineAttrs, methods: { close: onClose } }) + renderComponent({ inlineAttrs, methods: { close: onClose } }) - await Vue.nextTick() - userEvent.click(getByTestId('close-btn')) + await wait(async () => { + await userEvent.click(screen.getByTestId('close-btn')) + }) expect(onClose).toHaveBeenCalled() }) @@ -68,12 +68,12 @@ test('clicking the close button calls the onClose callback', async () => { test('pressing "esc" calls the onClose callback', async () => { const onClose = jest.fn() const inlineAttrs = ':isOpen="isOpen" :on-close="close"' - const { getByTestId } = renderComponent({ inlineAttrs, data: () => ({ isOpen: true }), methods: { close: onClose } }) - - await Vue.nextTick() - const inputInside = getByTestId('inputInsideDrawer') + renderComponent({ inlineAttrs, data: () => ({ isOpen: true }), methods: { close: onClose } }) - fireEvent.keyDown(inputInside, { key: 'Escape' }) + await wait(async () => { + const inputInside = screen.getByTestId('inputInsideDrawer') + await fireEvent.keyDown(inputInside, { key: 'Escape' }) + }) expect(onClose).toHaveBeenCalled() }) @@ -81,12 +81,12 @@ test('pressing "esc" calls the onClose callback', async () => { test('clicking overlay calls the onClose callback', async () => { const onClose = jest.fn() const inlineAttrs = ':isOpen="isOpen" :on-close="close"' - const { getByTestId } = renderComponent({ inlineAttrs, data: () => ({ isOpen: true }), methods: { close: onClose } }) - - await Vue.nextTick() - const overlay = getByTestId('overlay') + renderComponent({ inlineAttrs, data: () => ({ isOpen: true }), methods: { close: onClose } }) - userEvent.click(overlay) + await wait(async () => { + const overlay = screen.getByTestId('overlay') + await userEvent.click(overlay) + }) expect(onClose).toHaveBeenCalled() }) @@ -96,11 +96,11 @@ it('should have proper aria', async () => { const inlineAttrs = 'isOpen' renderComponent({ inlineAttrs }) - await Vue.nextTick() - const dialog = document.querySelector('section') - await waitMs() + let dialog + await wait(() => { + dialog = screen.getByRole('alertdialog') + }) - expect(dialog).toHaveAttribute('role', 'alertdialog') expect(dialog).toHaveAttribute('aria-modal', 'true') expect(dialog).toHaveAttribute('aria-labelledby', 'alert-dialog-1-label') expect(dialog).toHaveAttribute('aria-describedby', 'alert-dialog-1-desc') From d1814b7d9c7763cdfd5f59eec3ef4ccf9a4e5119 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Wed, 1 Jul 2020 16:18:56 +0300 Subject: [PATCH 009/133] feat(test-utils): add getElementStyles to test utils --- .../tests/CAspectRatioBox.test.js | 26 ++------------ tests/test-utils/test-utils.js | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/packages/chakra-ui-core/src/CAspectRatioBox/tests/CAspectRatioBox.test.js b/packages/chakra-ui-core/src/CAspectRatioBox/tests/CAspectRatioBox.test.js index e3935e26..01cc167e 100644 --- a/packages/chakra-ui-core/src/CAspectRatioBox/tests/CAspectRatioBox.test.js +++ b/packages/chakra-ui-core/src/CAspectRatioBox/tests/CAspectRatioBox.test.js @@ -1,5 +1,5 @@ import { CAspectRatioBox, CBox } from '../..' -import { render, screen } from '@/tests/test-utils' +import { render, screen, getElementStyles } from '@/tests/test-utils' const renderComponent = (props) => { const inlineAttrs = (props && props.inlineAttrs) || '' const base = { @@ -14,28 +14,6 @@ const renderComponent = (props) => { return render(base) } -/** - * Not sure if we need jest-emotion - * - * Get styles from document.styleSheets - * @param {String} selector - */ -function getElementStyles (selector) { - selector = new RegExp(selector) - let styles = [] - let i; let j; const sel = selector - for (i = 0; i < document.styleSheets.length; ++i) { - for (j = 0; j < document.styleSheets[i].cssRules.length; ++j) { - if (sel.test(document.styleSheets[i].cssRules[j].selectorText)) { - // let selectorText = document.styleSheets[i].cssRules[j].selectorText - const cssText = document.styleSheets[i].cssRules[j].style.cssText - styles += cssText - } - } - } - return styles -} - it('should render correctly', () => { const inlineAttrs = ':ratio="1"' const { asFragment } = renderComponent({ inlineAttrs }) @@ -55,7 +33,7 @@ it('should have correct styles', () => { const image = screen.getByTestId('image') const aspectRatioBox = screen.getByTestId('aspectRatioBox') - const [, emotionClassName] = [...aspectRatioBox.classList] + const [, emotionClassName] = [...aspectRatioBox.classList] // second className has the pseudo styles const pseudoStyles = getElementStyles(`.${emotionClassName}:before`) expect(pseudoStyles).toContain(` diff --git a/tests/test-utils/test-utils.js b/tests/test-utils/test-utils.js index 701e9b52..e12b043f 100644 --- a/tests/test-utils/test-utils.js +++ b/tests/test-utils/test-utils.js @@ -32,10 +32,44 @@ const render = (component, ...rest) => { } } +/** + * Wait for given ms + * + * @param {number} duration + */ function waitMs (ms = 0) { return new Promise(resolve => setTimeout(resolve, ms)) } +/** + * Get styles from document.styleSheets + * + * @param {String} selector + * + * @example className usage + * getElementStyles('.anyClassName') + * + * @example Emotion Classname + * const [className1, className2] = [...screen.getByTestId('aspectRatioBox').classList] + * const styles = getElementStyles(`.${className1}`) + * const pseudoStyles = getElementStyles(`.${className2}:before`) + */ +export function getElementStyles (selector) { + selector = new RegExp(selector) + let styles = [] + let i; let j; const sel = selector + for (i = 0; i < document.styleSheets.length; ++i) { + for (j = 0; j < document.styleSheets[i].cssRules.length; ++j) { + if (sel.test(document.styleSheets[i].cssRules[j].selectorText)) { + // let selectorText = document.styleSheets[i].cssRules[j].selectorText + const cssText = document.styleSheets[i].cssRules[j].style.cssText + styles += cssText + } + } + } + return styles +} + export * from '@testing-library/vue' export { render, From 86c9f1b6cdd593de5af73585a138f33b763140ad Mon Sep 17 00:00:00 2001 From: codebender828 Date: Wed, 1 Jul 2020 21:35:50 +0800 Subject: [PATCH 010/133] refactor(button): use button attrs --- .../chakra-ui-core/src/CButton/CButton.js | 173 +++++++++++++----- .../src/CButton/CButton.stories.js | 15 +- .../src/CButton/utils/button.props.js | 18 +- .../src/CButton/utils/button.styles.js | 4 +- packages/chakra-ui-core/src/CIcon/CIcon.js | 87 +++++---- .../src/CIcon/utils/icon.props.js | 4 - .../src/CIconButton/CIconButton.js | 30 ++- .../chakra-ui-core/src/utils/components.js | 19 +- 8 files changed, 213 insertions(+), 137 deletions(-) diff --git a/packages/chakra-ui-core/src/CButton/CButton.js b/packages/chakra-ui-core/src/CButton/CButton.js index 438863a7..ec775707 100644 --- a/packages/chakra-ui-core/src/CButton/CButton.js +++ b/packages/chakra-ui-core/src/CButton/CButton.js @@ -11,11 +11,11 @@ * @see WAI-ARIA https://www.w3.org/TR/wai-aria-practices-1.2/#button */ -import styleProps from '../config/props' -import { forwardProps } from '../utils' +// import styleProps from '../config/props' +import { createStyledAttrsMixin } from '../utils' -import CBox from '../CBox' -import CPseudoBox from '../CPseudoBox' +import CBox, { _CBox } from '../CBox' +import { _CPseudoBox } from '../CPseudoBox' import CSpinner from '../CSpinner' import CIcon from '../CIcon' import createButtonStyles, { setIconSizes } from './utils/button.styles' @@ -30,42 +30,41 @@ import { buttonProps } from './utils/button.props' * @see Docs https://vue.chakra-ui.com/button */ const CButtonIcon = { - name: 'CButtonIcon', + mixins: [createStyledAttrsMixin('CButtonIcon', true)], props: { icon: { type: [String, Object] }, size: { type: [String, Number] - }, - ...styleProps + } }, render (h) { if (typeof this.icon === 'string') { return h(CIcon, { + class: this.className, props: { - focusable: false, - name: this.icon, - color: 'currentColor', - ...setIconSizes(this.$props), - ...forwardProps(this.$props) + name: this.icon }, attrs: { - 'data-chakra-component': 'CButtonIcon' + color: 'currentColor', + focusable: false, + ...setIconSizes(this.$props), + ...this.computedAttrs } }) } else { - return h(CBox, { + return h(_CBox, { + class: this.className, props: { - as: this.icon, - focusable: false, - color: 'currentColor', - ...setIconSizes(this.$props), - ...forwardProps(this.$props) + as: this.icon }, attrs: { + ...setIconSizes(this.$props), + color: 'currentColor', 'data-custom-icon': true, - 'data-chakra-component': 'CButtonIcon' + ...this.computedAttrs, + focusable: false } }) } @@ -82,43 +81,32 @@ const CButtonIcon = { */ const CButton = { name: 'CButton', + inheritAttrs: false, inject: ['$chakraTheme', '$chakraColorMode'], - props: { - ...buttonProps, - ...styleProps, - to: [String, Object] - }, + props: buttonProps, computed: { colorMode () { return this.$chakraColorMode() }, theme () { return this.$chakraTheme() + }, + buttonStyles () { + return createButtonStyles({ + color: this.variantColor, + variant: this.variant, + theme: this.theme, + ripple: this.ripple, + colorMode: this.colorMode, + size: this.size || 'md' + }) } }, render (h) { - const buttonStyles = createButtonStyles({ - color: this.variantColor, - variant: this.variant, - theme: this.theme, - ripple: this.ripple, - colorMode: this.colorMode, - size: this.size || 'md' - }) - - return h(CPseudoBox, { + return h(_CPseudoBox, { props: { as: this.as, - to: this.to, - outline: 'none', - cursor: 'pointer', - fontSize: 'md', - fontWeight: '700', - border: 'none', - rounded: 'md', - width: this.isFullWidth ? 'full' : undefined, - ...buttonStyles, - ...forwardProps(this.$props) + to: this.to }, attrs: { type: this.type, @@ -126,7 +114,16 @@ const CButton = { disabled: this.isDisabled || this.isLoading, 'aria-disabled': this.isDisabled || this.isLoading, dataActive: this.isActive ? 'true' : undefined, - 'data-chakra-component': 'CButton' + outline: 'none', + cursor: 'pointer', + fontSize: 'md', + fontWeight: '700', + border: 'none', + rounded: 'md', + width: this.isFullWidth ? 'full' : undefined, + 'data-chakra-component': 'CButton', + ...this.buttonStyles, + ...this.$attrs }, nativeOn: { click: $event => this.$emit('click', $event) @@ -134,6 +131,9 @@ const CButton = { }, [ this.leftIcon && h(CButtonIcon, { props: { + icon: this.leftIcon + }, + attrs: { mr: this.iconSpacing, mb: 'px', icon: this.leftIcon, @@ -152,15 +152,19 @@ const CButton = { }), this.isLoading ? this.loadingText || h(CBox, { props: { - as: 'span', + as: 'span' + }, + attrs: { opacity: 0 } }, this.$slots.default) : this.$slots.default, this.rightIcon && h(CButtonIcon, { props: { + icon: this.rightIcon + }, + attrs: { ml: this.iconSpacing, mb: 'px', - icon: this.rightIcon, size: '1em', opacity: this.isLoading ? 0 : 1 } @@ -170,3 +174,76 @@ const CButton = { } export default CButton + +export const _CButton = { + mixins: [createStyledAttrsMixin('CButton', true)], + props: buttonProps, + computed: { + colorMode () { + return this.$chakraColorMode() + }, + theme () { + return this.$chakraTheme() + }, + componentStyles () { + return createButtonStyles({ + color: this.variantColor, + variant: this.variant, + theme: this.theme, + ripple: this.ripple, + colorMode: this.colorMode, + size: this.size || 'md' + }) + } + }, + render (h) { + return h(this.as, { + class: this.className, + attrs: this.computedAttrs, + on: { + click: $event => this.$emit('click', $event) + } + }, [ + this.leftIcon && h(CButtonIcon, { + props: { + icon: this.leftIcon + }, + attrs: { + mr: this.iconSpacing, + mb: 'px', + icon: this.leftIcon, + size: '1em', + opacity: this.isLoading ? 0 : 1 + } + }), + this.isLoading && h(CSpinner, { + props: { + position: this.loadingText ? 'relative' : 'absolute', + color: 'currentColor', + mb: '-4px', + mr: this.loadingText ? this.iconSpacing : 0, + size: '1em' + } + }), + this.isLoading ? this.loadingText || h(_CBox, { + props: { + as: 'span' + }, + attrs: { + opacity: 0 + } + }, this.$slots.default) : this.$slots.default, + this.rightIcon && h(CButtonIcon, { + props: { + icon: this.rightIcon + }, + attrs: { + ml: this.iconSpacing, + mb: 'px', + size: '1em', + opacity: this.isLoading ? 0 : 1 + } + }) + ]) + } +} diff --git a/packages/chakra-ui-core/src/CButton/CButton.stories.js b/packages/chakra-ui-core/src/CButton/CButton.stories.js index 3b3b5cd2..138177de 100644 --- a/packages/chakra-ui-core/src/CButton/CButton.stories.js +++ b/packages/chakra-ui-core/src/CButton/CButton.stories.js @@ -1,8 +1,21 @@ import { action } from '@storybook/addon-actions' import { storiesOf } from '@storybook/vue' -import { CButton } from '..' +import { _CButton as CButton } from './CButton' storiesOf('UI | Button', module) + .add('New', () => ({ + components: { CButton }, + template: ` +
+ + New button +
+ `, + methods: { action: action('Button Clicked') }, + data: () => ({ + value: '' + }) + })) .add('Unstyled', () => ({ components: { CButton }, template: ` diff --git a/packages/chakra-ui-core/src/CButton/utils/button.props.js b/packages/chakra-ui-core/src/CButton/utils/button.props.js index a11c4830..9ca6e25e 100644 --- a/packages/chakra-ui-core/src/CButton/utils/button.props.js +++ b/packages/chakra-ui-core/src/CButton/utils/button.props.js @@ -3,16 +3,11 @@ export const buttonProps = { type: [String, Object], default: 'button' }, + to: [String, Object], type: { type: String, default: 'button' }, - cast: { - type: String, - default: 'primary', - validator: value => - value.match(/^(primary|secondary|success|warning|danger)$/) - }, variant: { type: String, default: 'solid', @@ -55,14 +50,5 @@ export const buttonProps = { rightIcon: { type: String, default: null - }, - rounded: { - type: Boolean, - default: false - }, - ripple: { - type: [String, Boolean], - default: true - }, - forwardRef: Object + } } diff --git a/packages/chakra-ui-core/src/CButton/utils/button.styles.js b/packages/chakra-ui-core/src/CButton/utils/button.styles.js index e72db857..307f6cc5 100644 --- a/packages/chakra-ui-core/src/CButton/utils/button.styles.js +++ b/packages/chakra-ui-core/src/CButton/utils/button.styles.js @@ -11,7 +11,9 @@ const baseStyles = { whiteSpace: 'nowrap', verticalAlign: 'middle', lineHeight: '1.2', - outline: 'none' + outline: 'none', + fontWeight: 'bold', + rounded: 'md' } const disabledProps = { diff --git a/packages/chakra-ui-core/src/CIcon/CIcon.js b/packages/chakra-ui-core/src/CIcon/CIcon.js index 9b432671..a41590ca 100644 --- a/packages/chakra-ui-core/src/CIcon/CIcon.js +++ b/packages/chakra-ui-core/src/CIcon/CIcon.js @@ -11,33 +11,29 @@ import { css } from 'emotion' import iconPaths from '../lib/internal-icons' -import { forwardProps } from '../utils' -import { baseProps } from '../config/props' -import CBox from '../CBox' +import { createStyledAttrsMixin } from '../utils' import { iconProps } from './utils/icon.props' const fallbackIcon = iconPaths['question-outline'] const Svg = { - name: 'IconSvg', - props: { - ...iconProps, - ...baseProps + mixins: [createStyledAttrsMixin('ChakraIconSvg')], + props: iconProps, + computed: { + svgClassName () { + return css` + flex-shrink: 0; + backface-visibility: hidden; + &:not(:root) { + overflow: hidden; + } + ` + } }, render (h) { - const className = css` - flex-shrink: 0; - backface-visibility: hidden; - &:not(:root) { - overflow: hidden; - } - ` - return h(CBox, { - props: { - as: 'svg', - ...forwardProps(this.$props) - }, - class: [className] + return h('svg', { + class: [this.svgClassName, this.className], + attrs: this.computedAttrs }, this.$slots.default) } } @@ -51,44 +47,43 @@ const Svg = { * @see Docs https://vue.chakra-ui.com/icon */ const CIcon = { - name: 'CIcon', - inject: ['$chakraTheme', '$chakraIcons'], - props: { - ...iconProps, - ...baseProps - }, - render (h) { - let icon - if (this.name) { - icon = this.$chakraIcons[this.name] - } else { - console.warn('[Chakra]: You need to provide the "name" or "use" prop to for the Icon component') - } + mixins: [createStyledAttrsMixin('CIcon')], + inject: ['$chakraIcons'], + computed: { + icon() { + let icon + if (this.name) { + icon = this.$chakraIcons[this.name] + } else { + console.warn('[Chakra]: You need to provide the "name" or "use" prop to for the Icon component') + } + if (!icon) { + icon = fallbackIcon + } - if (!icon) { - icon = fallbackIcon + return icon + }, + viewBox () { + return this.icon.viewBox || '0 0 24 24' } - - const viewBox = icon.viewBox || '0 0 24 24' - + }, + props: iconProps, + render (h) { return h(Svg, { - props: { - as: 'svg', + class: this.className, + attrs: { w: this.size, h: this.size, color: this.color, d: 'inline-block', verticalAlign: 'middle', - ...forwardProps(this.$props) - }, - attrs: { - viewBox, + viewBox: this.viewBox, role: 'presentation', focusable: false, - 'data-chakra-component': 'CIcon' + ...this.computedAttrs }, domProps: { - innerHTML: icon.path + innerHTML: this.icon.path } }) } diff --git a/packages/chakra-ui-core/src/CIcon/utils/icon.props.js b/packages/chakra-ui-core/src/CIcon/utils/icon.props.js index e7079d97..1273853d 100644 --- a/packages/chakra-ui-core/src/CIcon/utils/icon.props.js +++ b/packages/chakra-ui-core/src/CIcon/utils/icon.props.js @@ -15,9 +15,5 @@ export const iconProps = { size: { type: [String, Number, Array], default: '1em' - }, - color: { - type: [String, Array], - default: 'currentColor' } } diff --git a/packages/chakra-ui-core/src/CIconButton/CIconButton.js b/packages/chakra-ui-core/src/CIconButton/CIconButton.js index b0b01002..fbd4bbc1 100644 --- a/packages/chakra-ui-core/src/CIconButton/CIconButton.js +++ b/packages/chakra-ui-core/src/CIconButton/CIconButton.js @@ -10,8 +10,7 @@ * @see Source https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CIconButton/CIconButton.js */ -import styleProps from '../config/props' -import { forwardProps } from '../utils' +import { forwardProps, createStyledAttrsMixin } from '../utils' import { buttonProps } from '../CButton/utils/button.props' import CButton from '../CButton' @@ -42,8 +41,7 @@ const baseStyles = { * @see Docs https://vue.chakra-ui.com/iconbutton */ const CIconButton = { - name: 'CIconButton', - inject: ['$chakraTheme', '$chakraColorMode'], + mixins: [createStyledAttrsMixin('CIconButton', true)], props: { icon: { type: [String] @@ -55,20 +53,18 @@ const CIconButton = { type: [String], required: true }, - ...buttonProps, - ...styleProps + ...buttonProps }, render (h) { const { isFullWidth, leftIcon, rightIcon, loadingText, ...props } = this.$props return h(CButton, { - props: { + props: forwardProps(props), + class: this.className, + attrs: { p: 0, rounded: this.isRound ? 'full' : 'md', size: this.size, - ...forwardProps(props) - }, - attrs: { 'aria-label': this.ariaLabel, 'data-chakra-component': 'CIconButton' }, @@ -79,24 +75,24 @@ const CIconButton = { [typeof this.icon === 'string' ? h(CIcon, { props: { + name: this.icon + }, + attrs: { ...baseStyles, - name: this.icon, color: 'currentColor', mb: '2px', - size: '1em' - }, - attrs: { + size: '1em', focusable: false, 'aria-hidden': true } }) : h(CBox, { props: { - as: this.icon, - color: 'currentColor' + as: this.icon }, attrs: { - focusable: true + focusable: true, + color: 'currentColor' } })] ) diff --git a/packages/chakra-ui-core/src/utils/components.js b/packages/chakra-ui-core/src/utils/components.js index 7eddf21e..ff53f76d 100644 --- a/packages/chakra-ui-core/src/utils/components.js +++ b/packages/chakra-ui-core/src/utils/components.js @@ -37,8 +37,9 @@ export function createWatcher (property) { * @param {String} name Component name */ export const createStyledAttrsMixin = (name, isPseudo) => ({ + name, inheritAttrs: false, - inject: ['$chakraTheme'], + inject: ['$chakraTheme', '$chakraColorMode'], data () { return { attrs$: {}, @@ -46,13 +47,20 @@ export const createStyledAttrsMixin = (name, isPseudo) => ({ } }, computed: { + colorMode () { + return this.$chakraColorMode() + }, theme () { return this.$chakraTheme() }, /** Split style attributes and native attributes */ splitProps () { - const styleProps = filterChakraStyleProps(this.$data.attrs$) - const attrs = purifyStyleAttributes(this.$data.attrs$, styleProps) + const styles = { + ...this.componentStyles && this.componentStyles, + ...this.$data.attrs$ + } + const styleProps = filterChakraStyleProps(styles) + const attrs = purifyStyleAttributes(styles, styleProps) return { styleProps, attrs @@ -64,7 +72,10 @@ export const createStyledAttrsMixin = (name, isPseudo) => ({ const { pseudoStyles, baseStyles } = parsePseudoStyles(styleProps) const _baseStyles = systemProps({ ...baseStyles, theme: this.theme }) const _pseudoStyles = __css(pseudoStyles)(this.theme) - return css({ ..._baseStyles, ..._pseudoStyles }) + return css({ + ..._baseStyles, + ..._pseudoStyles + }) } const boxStylesObject = systemProps({ ...styleProps, theme: this.theme }) return css(boxStylesObject) From b8dfd81a3776849c3763773ddd88eace5fc8efef Mon Sep 17 00:00:00 2001 From: codebender828 Date: Wed, 1 Jul 2020 21:36:10 +0800 Subject: [PATCH 011/133] refactor(icon): use --- packages/chakra-ui-core/src/CIcon/CIcon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/chakra-ui-core/src/CIcon/CIcon.js b/packages/chakra-ui-core/src/CIcon/CIcon.js index a41590ca..889f6da4 100644 --- a/packages/chakra-ui-core/src/CIcon/CIcon.js +++ b/packages/chakra-ui-core/src/CIcon/CIcon.js @@ -50,7 +50,7 @@ const CIcon = { mixins: [createStyledAttrsMixin('CIcon')], inject: ['$chakraIcons'], computed: { - icon() { + icon () { let icon if (this.name) { icon = this.$chakraIcons[this.name] From d129a247b19adbf5d1d68a48d3d205426f6593ff Mon Sep 17 00:00:00 2001 From: codebender828 Date: Wed, 1 Jul 2020 21:46:00 +0800 Subject: [PATCH 012/133] refactor(spinner): use --- .../chakra-ui-core/src/CButton/CButton.js | 3 +-- .../chakra-ui-core/src/CSpinner/CSpinner.js | 20 ++++++++----------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/packages/chakra-ui-core/src/CButton/CButton.js b/packages/chakra-ui-core/src/CButton/CButton.js index ec775707..c81ae4e8 100644 --- a/packages/chakra-ui-core/src/CButton/CButton.js +++ b/packages/chakra-ui-core/src/CButton/CButton.js @@ -11,7 +11,6 @@ * @see WAI-ARIA https://www.w3.org/TR/wai-aria-practices-1.2/#button */ -// import styleProps from '../config/props' import { createStyledAttrsMixin } from '../utils' import CBox, { _CBox } from '../CBox' @@ -217,7 +216,7 @@ export const _CButton = { } }), this.isLoading && h(CSpinner, { - props: { + attrs: { position: this.loadingText ? 'relative' : 'absolute', color: 'currentColor', mb: '-4px', diff --git a/packages/chakra-ui-core/src/CSpinner/CSpinner.js b/packages/chakra-ui-core/src/CSpinner/CSpinner.js index 88a589b0..cca4e7a6 100644 --- a/packages/chakra-ui-core/src/CSpinner/CSpinner.js +++ b/packages/chakra-ui-core/src/CSpinner/CSpinner.js @@ -1,8 +1,7 @@ import { keyframes } from 'emotion' -import { baseProps } from '../config/props' -import { forwardProps } from '../utils' +import { createStyledAttrsMixin } from '../utils' -import CBox from '../CBox' +import { _CBox } from '../CBox' import CVisuallyHidden from '../CVisuallyHidden' const spin = keyframes` @@ -57,7 +56,7 @@ const setSizes = (props) => { * @see Docs https://vue.chakra-ui.com/spinner */ const CSpinner = { - name: 'CSpinner', + mixins: [createStyledAttrsMixin('CSpinner')], props: { size: { type: [String, Array], @@ -82,12 +81,12 @@ const CSpinner = { emptyColor: { type: [String, Array], default: 'transparent' - }, - ...baseProps + } }, render (h) { - return h(CBox, { - props: { + return h(_CBox, { + class: this.className, + attrs: { d: 'inline-block', borderWidth: this.thickness, borderColor: 'currentColor', @@ -98,10 +97,7 @@ const CSpinner = { borderLeftColor: this.emptyColor, animation: `${spin} ${this.speed} linear infinite`, ...setSizes(this.$props), - ...forwardProps(this.$props) - }, - attrs: { - 'data-chakra-component': 'CSpinner' + ...this.computedAttrs } }, this.label && h(CVisuallyHidden, {}, this.label)) } From f3d81a8e52a11bae55a942015056d153e1c2664a Mon Sep 17 00:00:00 2001 From: codebender828 Date: Wed, 1 Jul 2020 21:47:27 +0800 Subject: [PATCH 013/133] refactor(button): remove old inheritAttrs --- packages/chakra-ui-core/src/CButton/CButton.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/chakra-ui-core/src/CButton/CButton.js b/packages/chakra-ui-core/src/CButton/CButton.js index c81ae4e8..28bf4572 100644 --- a/packages/chakra-ui-core/src/CButton/CButton.js +++ b/packages/chakra-ui-core/src/CButton/CButton.js @@ -80,7 +80,6 @@ const CButtonIcon = { */ const CButton = { name: 'CButton', - inheritAttrs: false, inject: ['$chakraTheme', '$chakraColorMode'], props: buttonProps, computed: { From aaf1c15ce3cb4c3739150dae4d87aa6fa416f20d Mon Sep 17 00:00:00 2001 From: codebender828 Date: Wed, 1 Jul 2020 22:55:52 +0800 Subject: [PATCH 014/133] feat: refactored primitives and base components --- packages/chakra-ui-core/src/CBox/CBox.js | 46 +------- .../chakra-ui-core/src/CButton/CButton.js | 105 +----------------- .../src/CButton/CButton.stories.js | 2 +- .../src/CPseudoBox/CPseudoBox.js | 53 +-------- .../chakra-ui-core/src/CSpinner/CSpinner.js | 4 +- 5 files changed, 12 insertions(+), 198 deletions(-) diff --git a/packages/chakra-ui-core/src/CBox/CBox.js b/packages/chakra-ui-core/src/CBox/CBox.js index 554ef23f..cc9bcb54 100644 --- a/packages/chakra-ui-core/src/CBox/CBox.js +++ b/packages/chakra-ui-core/src/CBox/CBox.js @@ -8,9 +8,7 @@ * @see Source https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CBox/CBox.js */ -import { css } from 'emotion' -import { baseProps } from '../config/props' -import { forwardProps, createStyledAttrsMixin, systemProps } from '../utils' +import { createStyledAttrsMixin } from '../utils' /** * CBox component @@ -20,46 +18,6 @@ import { forwardProps, createStyledAttrsMixin, systemProps } from '../utils' * @see Docs https://vue.chakra-ui.com/box */ const CBox = { - name: 'CBox', - inject: ['$chakraTheme'], - props: { - as: { - type: [String, Object], - default: 'div' - }, - to: { - type: [String, Object], - default: '' - }, - ...baseProps - }, - computed: { - theme () { - return this.$chakraTheme() - }, - boxClassName () { - const { as, to, ...cleanedStyleProps } = forwardProps(this.$props) - const boxStylesObject = systemProps({ ...cleanedStyleProps, theme: this.theme }) - return css(boxStylesObject) - } - }, - render (h) { - return h(this.as, { - props: { - to: this.to - }, - class: this.boxClassName, - on: this.$listeners, - attrs: { - 'data-chakra-component': 'CBox' - } - }, this.$slots.default) - } -} - -export default CBox - -export const _CBox = { name: 'CBox', mixins: [createStyledAttrsMixin('CBox')], props: { @@ -83,3 +41,5 @@ export const _CBox = { }, this.$slots.default) } } + +export default CBox diff --git a/packages/chakra-ui-core/src/CButton/CButton.js b/packages/chakra-ui-core/src/CButton/CButton.js index 28bf4572..25acc8c4 100644 --- a/packages/chakra-ui-core/src/CButton/CButton.js +++ b/packages/chakra-ui-core/src/CButton/CButton.js @@ -13,8 +13,7 @@ import { createStyledAttrsMixin } from '../utils' -import CBox, { _CBox } from '../CBox' -import { _CPseudoBox } from '../CPseudoBox' +import CBox from '../CBox' import CSpinner from '../CSpinner' import CIcon from '../CIcon' import createButtonStyles, { setIconSizes } from './utils/button.styles' @@ -53,7 +52,7 @@ const CButtonIcon = { } }) } else { - return h(_CBox, { + return h(CBox, { class: this.className, props: { as: this.icon @@ -75,105 +74,9 @@ const CButtonIcon = { * * The Button component is an accessible rich component that does what a button does :) * - * @extends CPseudoBox * @see Docs https://vue.chakra-ui.com/button */ const CButton = { - name: 'CButton', - inject: ['$chakraTheme', '$chakraColorMode'], - props: buttonProps, - computed: { - colorMode () { - return this.$chakraColorMode() - }, - theme () { - return this.$chakraTheme() - }, - buttonStyles () { - return createButtonStyles({ - color: this.variantColor, - variant: this.variant, - theme: this.theme, - ripple: this.ripple, - colorMode: this.colorMode, - size: this.size || 'md' - }) - } - }, - render (h) { - return h(_CPseudoBox, { - props: { - as: this.as, - to: this.to - }, - attrs: { - type: this.type, - tabIndex: 0, - disabled: this.isDisabled || this.isLoading, - 'aria-disabled': this.isDisabled || this.isLoading, - dataActive: this.isActive ? 'true' : undefined, - outline: 'none', - cursor: 'pointer', - fontSize: 'md', - fontWeight: '700', - border: 'none', - rounded: 'md', - width: this.isFullWidth ? 'full' : undefined, - 'data-chakra-component': 'CButton', - ...this.buttonStyles, - ...this.$attrs - }, - nativeOn: { - click: $event => this.$emit('click', $event) - } - }, [ - this.leftIcon && h(CButtonIcon, { - props: { - icon: this.leftIcon - }, - attrs: { - mr: this.iconSpacing, - mb: 'px', - icon: this.leftIcon, - size: '1em', - opacity: this.isLoading ? 0 : 1 - } - }), - this.isLoading && h(CSpinner, { - props: { - position: this.loadingText ? 'relative' : 'absolute', - color: 'currentColor', - mb: '-4px', - mr: this.loadingText ? this.iconSpacing : 0, - size: '1em' - } - }), - this.isLoading ? this.loadingText || h(CBox, { - props: { - as: 'span' - }, - attrs: { - opacity: 0 - } - }, this.$slots.default) : this.$slots.default, - this.rightIcon && h(CButtonIcon, { - props: { - icon: this.rightIcon - }, - attrs: { - ml: this.iconSpacing, - mb: 'px', - size: '1em', - opacity: this.isLoading ? 0 : 1 - } - }) - ]) - } -} - -export default CButton - -export const _CButton = { mixins: [createStyledAttrsMixin('CButton', true)], props: buttonProps, computed: { @@ -223,7 +126,7 @@ export const _CButton = { size: '1em' } }), - this.isLoading ? this.loadingText || h(_CBox, { + this.isLoading ? this.loadingText || h(CBox, { props: { as: 'span' }, @@ -245,3 +148,5 @@ export const _CButton = { ]) } } + +export default CButton diff --git a/packages/chakra-ui-core/src/CButton/CButton.stories.js b/packages/chakra-ui-core/src/CButton/CButton.stories.js index 138177de..e92a551d 100644 --- a/packages/chakra-ui-core/src/CButton/CButton.stories.js +++ b/packages/chakra-ui-core/src/CButton/CButton.stories.js @@ -1,6 +1,6 @@ import { action } from '@storybook/addon-actions' import { storiesOf } from '@storybook/vue' -import { _CButton as CButton } from './CButton' +import { CButton } from '../' storiesOf('UI | Button', module) .add('New', () => ({ diff --git a/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js b/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js index 6d1a83fb..bd7cc1b9 100644 --- a/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js +++ b/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js @@ -7,12 +7,7 @@ * @see Source https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.js */ -import { css } from 'emotion' -import __css from '@styled-system/css' -import CBox from '../CBox' -import styleProps from '../config/props' -import { systemProps, createStyledAttrsMixin } from '../utils' -import { parsePseudoStyles } from './utils' +import { createStyledAttrsMixin } from '../utils' /** * CPseudoBox component @@ -23,52 +18,6 @@ import { parsePseudoStyles } from './utils' * @see Docs https://vue.chakra-ui.com/pseudobox */ const CPseudoBox = { - name: 'CPseudoBox', - inject: ['$chakraTheme'], - props: { - as: { - type: [String, Object], - default: () => 'div' - }, - to: [String, Object], - ...styleProps, - chakraId: String - }, - computed: { - theme () { - return this.$chakraTheme() - }, - pseudoBoxClassName () { - const { as, to, ...cleanedStyleProps } = this.$props - const { pseudoStyles, baseStyles } = parsePseudoStyles(cleanedStyleProps) - const _baseStyles = systemProps({ ...baseStyles, theme: this.theme }) - const _pseudoStyles = __css(pseudoStyles)(this.theme) - return css({ ..._baseStyles, ..._pseudoStyles }) - } - }, - render (h) { - return h(CBox, { - class: this.pseudoBoxClassName, - props: { - as: this.as, - to: this.to - }, - attrs: { - 'data-chakra-component': 'CPseudoBox' - } - }, this.$slots.default) - } -} - -/** - * CPseudoBox component - * - * The pseudobox component that accepts pseudo props - * - * @extends CBox - * @see Docs https://vue.chakra-ui.com/pseudobox - */ -export const _CPseudoBox = { name: 'CPseudoBox', mixins: [createStyledAttrsMixin('CPseudoBox', true)], props: { diff --git a/packages/chakra-ui-core/src/CSpinner/CSpinner.js b/packages/chakra-ui-core/src/CSpinner/CSpinner.js index cca4e7a6..51d23d55 100644 --- a/packages/chakra-ui-core/src/CSpinner/CSpinner.js +++ b/packages/chakra-ui-core/src/CSpinner/CSpinner.js @@ -1,7 +1,7 @@ import { keyframes } from 'emotion' import { createStyledAttrsMixin } from '../utils' -import { _CBox } from '../CBox' +import CBox from '../CBox' import CVisuallyHidden from '../CVisuallyHidden' const spin = keyframes` @@ -84,7 +84,7 @@ const CSpinner = { } }, render (h) { - return h(_CBox, { + return h(CBox, { class: this.className, attrs: { d: 'inline-block', From 960a2b07c470e06a0798f697112ef5efbe45d0dd Mon Sep 17 00:00:00 2001 From: codebender828 Date: Wed, 1 Jul 2020 23:39:13 +0800 Subject: [PATCH 015/133] feat: added playground to storybook for testing --- .storybook/config.js | 4 +- .../chakra-ui-core/src/CBox/CBox.stories.js | 29 +----- .../src/CPseudoBox/CPseudoBox.stories.js | 90 +++++++++---------- .../chakra-ui-core/src/CSpinner/CSpinner.js | 17 ++-- .../src/utils/playground.stories.js | 30 +++++++ .../chakra-ui-docs/components/CodeBlock.js | 5 +- 6 files changed, 91 insertions(+), 84 deletions(-) create mode 100644 packages/chakra-ui-core/src/utils/playground.stories.js diff --git a/.storybook/config.js b/.storybook/config.js index 8b085535..63c894d5 100644 --- a/.storybook/config.js +++ b/.storybook/config.js @@ -1,9 +1,9 @@ import { configure, addDecorator, addParameters } from '@storybook/vue'; import Vue from 'vue' +import VueLive from 'vue-live' import Chakra, { CThemeProvider, CColorModeProvider, CReset } from '../packages/chakra-ui-core/src' import Canvas from './components/Canvas.vue' import theme from '../packages/chakra-ui-core/src/lib/theme' -import icons from '../packages/chakra-ui-core/src/lib/internal-icons' import storyBookTheme from './theme' import { @@ -81,6 +81,8 @@ addDecorator(() => ({ components: { CThemeProvider, CColorModeProvider, CReset, Canvas } })); +// For playground +Vue.use(VueLive) function loadStories() { const req = require.context('../packages/chakra-ui-core/src', true, /\.stories\.(js|mdx)$/); diff --git a/packages/chakra-ui-core/src/CBox/CBox.stories.js b/packages/chakra-ui-core/src/CBox/CBox.stories.js index 6585730e..636d71c2 100644 --- a/packages/chakra-ui-core/src/CBox/CBox.stories.js +++ b/packages/chakra-ui-core/src/CBox/CBox.stories.js @@ -1,6 +1,5 @@ import { storiesOf } from '@storybook/vue' -import { _CBox } from './CBox.js' -import { CBox, CInput } from '..' +import { CBox } from '..' storiesOf('UI | Box', module) .add('Box', () => ({ @@ -40,29 +39,3 @@ storiesOf('UI | Box', module) ` })) - .add('_CBox Box', () => ({ - components: { CBox: _CBox, CInput }, - template: ` -
-
-
-
- -
-
- - {{ title }} - -
- `, - data () { - return { - title: 'Hello world' - } - }, - computed: { - color () { - return this.title.length > 4 ? 'red' : 'blue' - } - } - })) diff --git a/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.stories.js b/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.stories.js index c247f302..20af1985 100644 --- a/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.stories.js +++ b/packages/chakra-ui-core/src/CPseudoBox/CPseudoBox.stories.js @@ -1,10 +1,10 @@ import { storiesOf } from '@storybook/vue' -// import CBox from '../CBox' -import { _CPseudoBox } from '../CPseudoBox' +import CBox from '../CBox' +import CPseudoBox from '../CPseudoBox' storiesOf('UI | PseudoBox', module) .add('PseudoBox | :hover', () => ({ - components: { CPseudoBox: _CPseudoBox }, + components: { CPseudoBox }, template: ` ` })) - // .add('Pseudobox | :odd', () => ({ - // components: { CBox, CPseudoBox }, - // data () { - // return { - // boxes: [ - // { - // id: 1, - // name: 'Box 1' - // }, - // { - // id: 2, - // name: 'Box 2' - // }, - // { - // id: 3, - // name: 'Box 3' - // } - // ] - // } - // }, - // template: ` - // - // - // {{ box.name }} - // - // - // ` - // })) + .add('Pseudobox | :odd', () => ({ + components: { CBox, CPseudoBox }, + data () { + return { + boxes: [ + { + id: 1, + name: 'Box 1' + }, + { + id: 2, + name: 'Box 2' + }, + { + id: 3, + name: 'Box 3' + } + ] + } + }, + template: ` + + + {{ box.name }} + + + ` + })) diff --git a/packages/chakra-ui-core/src/CSpinner/CSpinner.js b/packages/chakra-ui-core/src/CSpinner/CSpinner.js index 51d23d55..90aed4ae 100644 --- a/packages/chakra-ui-core/src/CSpinner/CSpinner.js +++ b/packages/chakra-ui-core/src/CSpinner/CSpinner.js @@ -1,7 +1,6 @@ import { keyframes } from 'emotion' import { createStyledAttrsMixin } from '../utils' -import CBox from '../CBox' import CVisuallyHidden from '../CVisuallyHidden' const spin = keyframes` @@ -83,10 +82,9 @@ const CSpinner = { default: 'transparent' } }, - render (h) { - return h(CBox, { - class: this.className, - attrs: { + computed: { + componentStyles () { + return { d: 'inline-block', borderWidth: this.thickness, borderColor: 'currentColor', @@ -96,9 +94,14 @@ const CSpinner = { borderBottomColor: this.emptyColor, borderLeftColor: this.emptyColor, animation: `${spin} ${this.speed} linear infinite`, - ...setSizes(this.$props), - ...this.computedAttrs + ...setSizes(this.$props) } + } + }, + render (h) { + return h('div', { + class: this.className, + attrs: this.computedAttrs }, this.label && h(CVisuallyHidden, {}, this.label)) } } diff --git a/packages/chakra-ui-core/src/utils/playground.stories.js b/packages/chakra-ui-core/src/utils/playground.stories.js new file mode 100644 index 00000000..2d6937a4 --- /dev/null +++ b/packages/chakra-ui-core/src/utils/playground.stories.js @@ -0,0 +1,30 @@ +/*eslint import/namespace: [2, { allowComputed: true }]*/ +import { storiesOf } from '@storybook/vue' +import Vue from 'vue' +import CodeBlock from '../../../chakra-ui-docs/components/CodeBlock.js' +import * as ChakraComponents from '..' + +Object.keys(ChakraComponents).forEach((key) => { + if (typeof ChakraComponents[key] === 'object' && ChakraComponents[key].name) { + Vue.component(ChakraComponents[key].name, ChakraComponents[key]) + } +}) + +storiesOf('Playground', module) + .add('New', () => ({ + components: { CodeBlock: CodeBlock({ live: true, lang: 'vue', className: 'lang-vue' }) }, + template: ` + +

Chakra UI Vue Playground ⚡️

+ + {{ code }} + +
+ `, + data: () => ({ + code: ` +let value = "Hello Chakra" + +{{ value }}` + }) + })) diff --git a/packages/chakra-ui-docs/components/CodeBlock.js b/packages/chakra-ui-docs/components/CodeBlock.js index a29604d3..6ef97ba8 100644 --- a/packages/chakra-ui-docs/components/CodeBlock.js +++ b/packages/chakra-ui-docs/components/CodeBlock.js @@ -1,4 +1,3 @@ -import { CBox, CButton } from '@chakra-ui/vue' import 'prismjs' import PrismEditor from 'vue-prism-editor' import '../css/night-owl.css' @@ -62,7 +61,7 @@ const CodeBlock = props => ({ this.text = code if (!props.live) { - return h(CBox, { + return h('CBox', { props: { rounded: 'md', position: 'relative', @@ -77,7 +76,7 @@ const CodeBlock = props => ({ ...this.$props } }), - h(CButton, { + h('CButton', { props: { variantColor: 'vue', position: 'absolute', From 9ae294e48bd953bdb67261368e4c17d763bc3c8e Mon Sep 17 00:00:00 2001 From: codebender828 Date: Wed, 1 Jul 2020 23:39:28 +0800 Subject: [PATCH 016/133] feat: added playground to storybook for testing --- packages/chakra-ui-core/src/utils/playground.stories.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/chakra-ui-core/src/utils/playground.stories.js b/packages/chakra-ui-core/src/utils/playground.stories.js index 2d6937a4..05cdfbda 100644 --- a/packages/chakra-ui-core/src/utils/playground.stories.js +++ b/packages/chakra-ui-core/src/utils/playground.stories.js @@ -1,4 +1,4 @@ -/*eslint import/namespace: [2, { allowComputed: true }]*/ +/* eslint import/namespace: [2, { allowComputed: true }] */ import { storiesOf } from '@storybook/vue' import Vue from 'vue' import CodeBlock from '../../../chakra-ui-docs/components/CodeBlock.js' From 4d55aaa0ab31937e53002aed29d78e7598d7af9c Mon Sep 17 00:00:00 2001 From: codebender828 Date: Wed, 1 Jul 2020 23:51:13 +0800 Subject: [PATCH 017/133] refactor(flex): use mixin --- packages/chakra-ui-core/src/CFlex/CFlex.js | 33 +++++++++++----------- packages/chakra-ui-core/src/CText/CText.js | 26 ++++++++--------- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/packages/chakra-ui-core/src/CFlex/CFlex.js b/packages/chakra-ui-core/src/CFlex/CFlex.js index 968d54c3..0ad516e3 100644 --- a/packages/chakra-ui-core/src/CFlex/CFlex.js +++ b/packages/chakra-ui-core/src/CFlex/CFlex.js @@ -8,34 +8,31 @@ * @see Source https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CFlex/CFlex.js */ -import { baseProps } from '../config/props' -import { forwardProps } from '../utils' - -import CBox from '../CBox' +import { createStyledAttrsMixin } from '../utils' /** * CFlex component * * `CFlex` is `CBox` with display: flex and comes with helpful style shorthands. * - * @extends CBox * @see Docs https://vue.chakra-ui.com/flex */ const CFlex = { - name: 'CFlex', + mixins: [createStyledAttrsMixin('CFlex')], props: { - as: String, + as: { + type: String, + default: 'div' + }, align: [String, Array], justify: [String, Array], wrap: [String, Array], direction: [String, Array], - size: [String, Array], - ...baseProps + size: [String, Number, Array] }, - render (h) { - return h(CBox, { - props: { - as: this.as, + computed: { + componentStyles() { + return { display: 'flex', flexDirection: this.direction, alignItems: this.align, @@ -43,11 +40,13 @@ const CFlex = { flexWrap: this.wrap, h: this.size, w: this.size, - ...forwardProps(this.$props) - }, - attrs: { - 'data-chakra-component': 'CFlex' } + } + }, + render (h) { + return h(this.as, { + class: this.className, + attrs: this.computedAttrs }, this.$slots.default) } } diff --git a/packages/chakra-ui-core/src/CText/CText.js b/packages/chakra-ui-core/src/CText/CText.js index 2bab42a5..13244f36 100644 --- a/packages/chakra-ui-core/src/CText/CText.js +++ b/packages/chakra-ui-core/src/CText/CText.js @@ -7,9 +7,7 @@ * @see Source https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CText/CText.js */ -import CBox from '../CBox' -import { forwardProps } from '../utils' -import { baseProps } from '../config/props' +import { createStyledAttrsMixin } from '../utils' import { useTruncated } from './utils/text.utils' /** @@ -17,14 +15,11 @@ import { useTruncated } from './utils/text.utils' * * the text element component * - * @extends CBox * @see Docs https://vue.chakra-ui.com/text */ const CText = { - name: 'CText', - inject: ['$chakraTheme', '$chakraColorMode'], + mixins: [createStyledAttrsMixin('CText')], props: { - ...baseProps, as: { type: [String, Array], default: 'p' @@ -35,17 +30,18 @@ const CText = { default: 'body' } }, - render (h) { - return h(CBox, { - props: { - as: this.as, - ...forwardProps(this.$props), + computed: { + componentStyles() { + return { fontFamily: this.as === 'kbd' ? 'mono' : this.fontFamily, ...this.isTruncated && useTruncated() - }, - attrs: { - 'data-chakra-component': 'CText' } + } + }, + render (h) { + return h(this.as, { + class: this.className, + attrs: this.computedAttrs }, this.$slots.default) } } From 01dde0c103213cc6c3d124f8c6c7801b11ca8fb0 Mon Sep 17 00:00:00 2001 From: codebender828 Date: Wed, 1 Jul 2020 23:59:18 +0800 Subject: [PATCH 018/133] refactor(c-grid-&-c-simple-grid): use mixin --- packages/chakra-ui-core/src/CFlex/CFlex.js | 15 +++++----- packages/chakra-ui-core/src/CGrid/CGrid.js | 30 +++++++++---------- .../src/CSimpleGrid/CSimpleGrid.js | 17 +++++------ packages/chakra-ui-core/src/CText/CText.js | 2 +- 4 files changed, 31 insertions(+), 33 deletions(-) diff --git a/packages/chakra-ui-core/src/CFlex/CFlex.js b/packages/chakra-ui-core/src/CFlex/CFlex.js index 0ad516e3..377e34d8 100644 --- a/packages/chakra-ui-core/src/CFlex/CFlex.js +++ b/packages/chakra-ui-core/src/CFlex/CFlex.js @@ -9,6 +9,7 @@ */ import { createStyledAttrsMixin } from '../utils' +import { SNA } from '../config/props/props.types' /** * CFlex component @@ -24,14 +25,14 @@ const CFlex = { type: String, default: 'div' }, - align: [String, Array], - justify: [String, Array], - wrap: [String, Array], - direction: [String, Array], - size: [String, Number, Array] + align: SNA, + justify: SNA, + wrap: SNA, + direction: SNA, + size: SNA, }, computed: { - componentStyles() { + componentStyles () { return { display: 'flex', flexDirection: this.direction, @@ -39,7 +40,7 @@ const CFlex = { justifyContent: this.justify, flexWrap: this.wrap, h: this.size, - w: this.size, + w: this.size } } }, diff --git a/packages/chakra-ui-core/src/CGrid/CGrid.js b/packages/chakra-ui-core/src/CGrid/CGrid.js index c44faef2..218bf18a 100644 --- a/packages/chakra-ui-core/src/CGrid/CGrid.js +++ b/packages/chakra-ui-core/src/CGrid/CGrid.js @@ -9,12 +9,9 @@ * @see Source https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CGrid/CGrid.js */ -import { baseProps } from '../config/props' -import { forwardProps } from '../utils' +import { createStyledAttrsMixin } from '../utils' import { SNA } from '../config/props/props.types' -import CBox from '../CBox' - /** * CGrid component * @@ -24,9 +21,12 @@ import CBox from '../CBox' * @see Docs https://vue.chakra-ui.com/grid */ const CGrid = { - name: 'CGrid', + mixins: [createStyledAttrsMixin('CGrid')], props: { - ...baseProps, + as: { + type: String, + default: 'div' + }, gap: SNA, rowGap: SNA, columnGap: SNA, @@ -39,12 +39,10 @@ const CGrid = { area: SNA, column: SNA, row: SNA, - as: String }, - render (h) { - return h(CBox, { - props: { - as: this.as, + computed: { + componentStyles () { + return { d: 'grid', gridArea: this.area, gridTemplateAreas: this.templateAreas, @@ -58,11 +56,13 @@ const CGrid = { gridAutoRows: this.autoRows, gridTemplateRows: this.templateRows, gridTemplateColumns: this.templateColumns, - ...forwardProps(this.$props) - }, - attrs: { - 'data-chakra-component': 'CGrid' } + } + }, + render (h) { + return h(this.as, { + class: this.className, + attrs: this.computedAttrs }, this.$slots.default) } } diff --git a/packages/chakra-ui-core/src/CSimpleGrid/CSimpleGrid.js b/packages/chakra-ui-core/src/CSimpleGrid/CSimpleGrid.js index 2cc67e88..d68dffd2 100644 --- a/packages/chakra-ui-core/src/CSimpleGrid/CSimpleGrid.js +++ b/packages/chakra-ui-core/src/CSimpleGrid/CSimpleGrid.js @@ -8,48 +8,45 @@ * @see Source https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CSimpleGrid/CSimpleGrid.js */ -import { baseProps } from '../config/props' - import CGrid from '../CGrid' import { SNA } from '../config/props/props.types' import { countToColumns, widthToColumns } from './utils/grid.styles' +import { createStyledAttrsMixin } from '../utils' /** * CSimpleGrid component * * The simple grid component provides basic grid functionalities. * - * @extends CBox + * @extends CGrid * @see Docs https://vue.chakra-ui.com/select */ const CSimpleGrid = { - name: 'CSimpleGrid', + mixins: [createStyledAttrsMixin('CSimpleGrid')], props: { columns: SNA, spacingX: SNA, spacingY: SNA, spacing: SNA, - minChildWidth: SNA, - ...baseProps + minChildWidth: SNA }, computed: { templateColumns () { return this.minChildWidth ? widthToColumns(this.minChildWidth) : countToColumns(this.columns) - } + }, }, render (h) { return h(CGrid, { + class: this.className, props: { gap: this.spacing, columnGap: this.spacingX, rowGap: this.spacingY, templateColumns: this.templateColumns }, - attrs: { - 'data-chakra-component': 'CSimpleGrid' - } + attrs: this.computedAttrs }, this.$slots.default) } } diff --git a/packages/chakra-ui-core/src/CText/CText.js b/packages/chakra-ui-core/src/CText/CText.js index 13244f36..fec54e8e 100644 --- a/packages/chakra-ui-core/src/CText/CText.js +++ b/packages/chakra-ui-core/src/CText/CText.js @@ -31,7 +31,7 @@ const CText = { } }, computed: { - componentStyles() { + componentStyles () { return { fontFamily: this.as === 'kbd' ? 'mono' : this.fontFamily, ...this.isTruncated && useTruncated() From d8a0ca0b971c7e54d3fd588e8c51cb3e99ee2db0 Mon Sep 17 00:00:00 2001 From: codebender828 Date: Wed, 1 Jul 2020 23:59:28 +0800 Subject: [PATCH 019/133] refactor(c-grid-&-c-simple-grid): use mixin --- packages/chakra-ui-core/src/CFlex/CFlex.js | 2 +- packages/chakra-ui-core/src/CGrid/CGrid.js | 4 ++-- packages/chakra-ui-core/src/CSimpleGrid/CSimpleGrid.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/chakra-ui-core/src/CFlex/CFlex.js b/packages/chakra-ui-core/src/CFlex/CFlex.js index 377e34d8..943dc995 100644 --- a/packages/chakra-ui-core/src/CFlex/CFlex.js +++ b/packages/chakra-ui-core/src/CFlex/CFlex.js @@ -29,7 +29,7 @@ const CFlex = { justify: SNA, wrap: SNA, direction: SNA, - size: SNA, + size: SNA }, computed: { componentStyles () { diff --git a/packages/chakra-ui-core/src/CGrid/CGrid.js b/packages/chakra-ui-core/src/CGrid/CGrid.js index 218bf18a..3fb8f459 100644 --- a/packages/chakra-ui-core/src/CGrid/CGrid.js +++ b/packages/chakra-ui-core/src/CGrid/CGrid.js @@ -38,7 +38,7 @@ const CGrid = { templateAreas: SNA, area: SNA, column: SNA, - row: SNA, + row: SNA }, computed: { componentStyles () { @@ -55,7 +55,7 @@ const CGrid = { gridAutoFlow: this.autoFlow, gridAutoRows: this.autoRows, gridTemplateRows: this.templateRows, - gridTemplateColumns: this.templateColumns, + gridTemplateColumns: this.templateColumns } } }, diff --git a/packages/chakra-ui-core/src/CSimpleGrid/CSimpleGrid.js b/packages/chakra-ui-core/src/CSimpleGrid/CSimpleGrid.js index d68dffd2..8d5bda2b 100644 --- a/packages/chakra-ui-core/src/CSimpleGrid/CSimpleGrid.js +++ b/packages/chakra-ui-core/src/CSimpleGrid/CSimpleGrid.js @@ -10,8 +10,8 @@ import CGrid from '../CGrid' import { SNA } from '../config/props/props.types' -import { countToColumns, widthToColumns } from './utils/grid.styles' import { createStyledAttrsMixin } from '../utils' +import { countToColumns, widthToColumns } from './utils/grid.styles' /** * CSimpleGrid component @@ -35,7 +35,7 @@ const CSimpleGrid = { return this.minChildWidth ? widthToColumns(this.minChildWidth) : countToColumns(this.columns) - }, + } }, render (h) { return h(CGrid, { From fc29206bc395a04439ac949ba1252c52e6c71102 Mon Sep 17 00:00:00 2001 From: codebender828 Date: Thu, 2 Jul 2020 00:49:57 +0800 Subject: [PATCH 020/133] refactor(c-heading): use mixin --- packages/chakra-ui-core/src/CBadge/CBadge.js | 49 +++++++++---------- packages/chakra-ui-core/src/CCode/CCode.js | 35 +++++-------- .../chakra-ui-core/src/CCode/CCode.stories.js | 2 +- .../chakra-ui-core/src/CDivider/CDivider.js | 35 +++++++------ .../chakra-ui-core/src/CHeading/CHeading.js | 25 +++++----- .../src/CIconButton/CIconButton.js | 12 ++--- packages/chakra-ui-core/src/CImage/CImage.js | 27 +++++----- .../src/CImage/CImage.stories.js | 1 + .../src/utils/playground.stories.js | 6 +++ 9 files changed, 89 insertions(+), 103 deletions(-) diff --git a/packages/chakra-ui-core/src/CBadge/CBadge.js b/packages/chakra-ui-core/src/CBadge/CBadge.js index cae8be24..c7b87528 100644 --- a/packages/chakra-ui-core/src/CBadge/CBadge.js +++ b/packages/chakra-ui-core/src/CBadge/CBadge.js @@ -7,9 +7,7 @@ * @see Source https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CBadge/CBadge.js */ -import { forwardProps } from '../utils' -import { baseProps } from '../config/props' -import CBox from '../CBox' +import { createStyledAttrsMixin } from '../utils' import useBadgeStyles from './utils/badge.styles' /** @@ -17,12 +15,10 @@ import useBadgeStyles from './utils/badge.styles' * * Used to highlight an item's status for quick recognition. * - * @extends CBox * @see Docs https://vue.chakra-ui.com/badge */ const CBadge = { - name: 'CBadge', - inject: ['$chakraTheme', '$chakraColorMode'], + mixins: [createStyledAttrsMixin('CBadge')], props: { variant: { type: String, @@ -32,23 +28,22 @@ const CBadge = { type: String, default: 'gray' }, - ...baseProps - }, - computed: { - colorMode () { - return this.$chakraColorMode() + as: { + type: String, + default: 'div' } }, - render (h) { - const badgeStyleProps = useBadgeStyles({ - theme: this.$chakraTheme(), - colorMode: this.colorMode, - color: this.variantColor, - variant: this.variant - }) - - return h(CBox, { - props: { + computed: { + badgeStyles () { + return useBadgeStyles({ + theme: this.theme, + colorMode: this.colorMode, + color: this.variantColor, + variant: this.variant + }) + }, + componentStyles () { + return { d: 'inline-block', textTransform: 'uppercase', fontSize: 'xs', @@ -58,12 +53,14 @@ const CBadge = { fontWeight: 'bold', whiteSpace: 'nowrap', verticalAlign: 'middle', - ...badgeStyleProps, - ...forwardProps(this.$props) - }, - attrs: { - 'data-chakra-component': 'CBadge' + ...this.badgeStyles } + } + }, + render (h) { + return h(this.as, { + class: this.className, + attrs: this.computedAttrs }, this.$slots.default) } } diff --git a/packages/chakra-ui-core/src/CCode/CCode.js b/packages/chakra-ui-core/src/CCode/CCode.js index 0ba7b0be..eb36030b 100644 --- a/packages/chakra-ui-core/src/CCode/CCode.js +++ b/packages/chakra-ui-core/src/CCode/CCode.js @@ -8,10 +8,8 @@ */ import useBadgeStyle from '../CBadge/utils/badge.styles' -import { useVariantColorWarning, forwardProps } from '../utils' -import { baseProps } from '../config/props' +import { useVariantColorWarning, createStyledAttrsMixin } from '../utils' -import CBox from '../CBox' import { SNA } from '../config/props/props.types' /** @@ -23,10 +21,8 @@ import { SNA } from '../config/props/props.types' * @see Docs https://vue.chakra-ui.com/code */ const CCode = { - name: 'CCode', - inject: ['$chakraTheme', '$chakraColorMode'], + mixins: [createStyledAttrsMixin('CCode')], props: { - ...baseProps, variantColor: { type: String, default: 'gray' @@ -37,12 +33,6 @@ const CCode = { } }, computed: { - theme () { - return this.$chakraTheme() - }, - colorMode () { - return this.$chakraColorMode() - }, badgeStyle () { useVariantColorWarning(this.theme, 'CCode', this.variantColor) return useBadgeStyle({ @@ -51,23 +41,22 @@ const CCode = { colorMode: this.colorMode, theme: this.theme }) - } - }, - render (h) { - return h(CBox, { - props: { - as: 'code', + }, + componentStyles () { + return { display: 'inline-block', fontSize: 'sm', px: '0.2em', fontFamily: 'mono', rounded: 'sm', - ...this.badgeStyle, - ...forwardProps(this.$props) - }, - attrs: { - 'data-chakra-component': 'CCode' + ...this.badgeStyle } + } + }, + render (h) { + return h('code', { + class: this.className, + attrs: this.computedAttrs }, this.$slots.default) } } diff --git a/packages/chakra-ui-core/src/CCode/CCode.stories.js b/packages/chakra-ui-core/src/CCode/CCode.stories.js index 1b48ebc0..3e0ffc1e 100644 --- a/packages/chakra-ui-core/src/CCode/CCode.stories.js +++ b/packages/chakra-ui-core/src/CCode/CCode.stories.js @@ -18,7 +18,7 @@ storiesOf('UI | Code', module) console.log(welcome) - var chakra = 'awesome!' + var chakra = 'awesome!' npm install chakra diff --git a/packages/chakra-ui-core/src/CDivider/CDivider.js b/packages/chakra-ui-core/src/CDivider/CDivider.js index 358c611f..45561eee 100644 --- a/packages/chakra-ui-core/src/CDivider/CDivider.js +++ b/packages/chakra-ui-core/src/CDivider/CDivider.js @@ -8,9 +8,7 @@ * @see A11y https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CDivider/accessibility.md */ -import CBox from '../CBox' -import { baseProps } from '../config/props' -import { forwardProps } from '../utils' +import { createStyledAttrsMixin } from '../utils' /** * CDivider component @@ -18,36 +16,37 @@ import { forwardProps } from '../utils' * Creates a horizontal or vertical dividing rule between sibling * elements * - * @extends CBox * @see Docs https://vue.chakra-ui.com/divider */ const CDivider = { - name: 'CDivider', + mixins: [createStyledAttrsMixin('CDivider')], props: { - ...baseProps, orientation: { type: String, default: 'horizontal' } }, - render (h) { - const borderProps = - this.orientation === 'vertical' + computed: { + borderProps () { + return this.orientation === 'vertical' ? { borderLeft: '0.0625rem solid', height: 'auto', mx: 2 } : { borderBottom: '0.0625rem solid', width: 'auto', my: 2 } - - return h(CBox, { - props: { - ...borderProps, - as: 'hr', + }, + componentStyles () { + return { border: 0, + ...this.borderProps, opacity: 0.6, - borderColor: 'inherit', - ...forwardProps(this.$props) - }, + borderColor: 'inherit' + } + } + }, + render (h) { + return h('hr', { + class: this.className, attrs: { 'aria-orientation': this.orientation, - 'data-chakra-component': 'CDivider' + ...this.computedAttrs } }) } diff --git a/packages/chakra-ui-core/src/CHeading/CHeading.js b/packages/chakra-ui-core/src/CHeading/CHeading.js index c76daf71..17967b17 100644 --- a/packages/chakra-ui-core/src/CHeading/CHeading.js +++ b/packages/chakra-ui-core/src/CHeading/CHeading.js @@ -10,12 +10,9 @@ * @see Source https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CHeading/CHeading.js */ -import { baseProps } from '../config/props' -import { forwardProps } from '../utils' +import { createStyledAttrsMixin } from '../utils' import { useTruncated } from '../CText/utils/text.utils' -import CBox from '../CBox' - const sizes = { '2xl': ['4xl', null, '5xl'], xl: ['3xl', null, '4xl'], @@ -34,7 +31,7 @@ const sizes = { * @see Docs https://vue.chakra-ui.com/heading */ const CHeading = { - name: 'CHeading', + mixins: [createStyledAttrsMixin('CHeading')], props: { size: { type: [String, Array, Object], @@ -44,23 +41,23 @@ const CHeading = { type: String, default: 'h2' }, - ...baseProps, isTruncated: Boolean }, - render (h) { - return h(CBox, { - props: { - as: this.as, + computed: { + componentStyles () { + return { fontSize: sizes[this.size], lineHeight: 'shorter', fontWeight: 'bold', fontFamily: 'heading', - ...forwardProps(this.$props), ...this.isTruncated && useTruncated() - }, - attrs: { - 'data-chakra-component': 'CHeading' } + } + }, + render (h) { + return h(this.as, { + class: this.className, + attrs: this.computedAttrs }, this.$slots.default) } } diff --git a/packages/chakra-ui-core/src/CIconButton/CIconButton.js b/packages/chakra-ui-core/src/CIconButton/CIconButton.js index fbd4bbc1..8680c49d 100644 --- a/packages/chakra-ui-core/src/CIconButton/CIconButton.js +++ b/packages/chakra-ui-core/src/CIconButton/CIconButton.js @@ -10,7 +10,7 @@ * @see Source https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CIconButton/CIconButton.js */ -import { forwardProps, createStyledAttrsMixin } from '../utils' +import { forwardProps } from '../utils' import { buttonProps } from '../CButton/utils/button.props' import CButton from '../CButton' @@ -41,7 +41,7 @@ const baseStyles = { * @see Docs https://vue.chakra-ui.com/iconbutton */ const CIconButton = { - mixins: [createStyledAttrsMixin('CIconButton', true)], + name: 'CIconButton', props: { icon: { type: [String] @@ -60,13 +60,11 @@ const CIconButton = { return h(CButton, { props: forwardProps(props), - class: this.className, attrs: { - p: 0, - rounded: this.isRound ? 'full' : 'md', - size: this.size, 'aria-label': this.ariaLabel, - 'data-chakra-component': 'CIconButton' + rounded: this.isRound ? 'full' : 'md', + ...this.$attrs, + p: 0 }, on: { click: e => this.$emit('click', e) diff --git a/packages/chakra-ui-core/src/CImage/CImage.js b/packages/chakra-ui-core/src/CImage/CImage.js index 17c75186..cdb192d4 100644 --- a/packages/chakra-ui-core/src/CImage/CImage.js +++ b/packages/chakra-ui-core/src/CImage/CImage.js @@ -9,10 +9,8 @@ * @see Source https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CImage/CImage.js */ -import { baseProps } from '../config/props' -import CBox from '../CBox' import CNoSsr from '../CNoSsr' -import { forwardProps } from '../utils' +import { createStyledAttrsMixin } from '../utils' /** * CImage component @@ -23,9 +21,8 @@ import { forwardProps } from '../utils' * @see Docs https://vue.chakra-ui.com/image */ const CImage = { - name: 'CImage', + mixins: [createStyledAttrsMixin('CImage')], props: { - ...baseProps, src: String, fallbackSrc: String, ignoreFalback: Boolean, @@ -39,6 +36,14 @@ const CImage = { hasLoaded: false } }, + computed: { + componentStyles () { + return { + w: this.size, + h: this.size + } + } + }, created () { // Should only invoke window.Image in the browser. if (process.browser) { @@ -69,21 +74,15 @@ const CImage = { imageProps = { src: this.hasLoaded ? this.src : this.fallbackSrc } } return h(CNoSsr, [ - h(CBox, { - props: { - as: 'img', - w: this.size, - h: this.size, - ...forwardProps(this.$props) - }, + h('img', { + class: this.className, domProps: { width: this.htmlWidth, height: this.htmlHeight }, attrs: { ...imageProps, - ...this.$attrs, - 'data-chakra-component': 'CImage' + ...this.computedAttrs } }) ]) diff --git a/packages/chakra-ui-core/src/CImage/CImage.stories.js b/packages/chakra-ui-core/src/CImage/CImage.stories.js index 47d8a48e..139faffd 100644 --- a/packages/chakra-ui-core/src/CImage/CImage.stories.js +++ b/packages/chakra-ui-core/src/CImage/CImage.stories.js @@ -18,6 +18,7 @@ storiesOf('UI | Image', module) diff --git a/packages/chakra-ui-core/src/utils/playground.stories.js b/packages/chakra-ui-core/src/utils/playground.stories.js index 05cdfbda..c7347efe 100644 --- a/packages/chakra-ui-core/src/utils/playground.stories.js +++ b/packages/chakra-ui-core/src/utils/playground.stories.js @@ -8,6 +8,12 @@ Object.keys(ChakraComponents).forEach((key) => { if (typeof ChakraComponents[key] === 'object' && ChakraComponents[key].name) { Vue.component(ChakraComponents[key].name, ChakraComponents[key]) } + if (typeof ChakraComponents[key] === 'object' && ChakraComponents[key].mixins) { + const [mixin] = ChakraComponents[key].mixins + if (mixin.name) { + Vue.component(mixin.name, ChakraComponents[key]) + } + } }) storiesOf('Playground', module) From f51a37fcfa8b5a41d334d44bbb5f9f025ca7c497 Mon Sep 17 00:00:00 2001 From: codebender828 Date: Thu, 2 Jul 2020 01:46:59 +0800 Subject: [PATCH 021/133] chore(collapse): removed unused modules --- .../src/CAccordion/CAccordion.js | 99 ++++++++----------- .../src/CAccordion/CAccordion.stories.js | 1 - .../chakra-ui-core/src/CCollapse/CCollapse.js | 13 ++- 3 files changed, 51 insertions(+), 62 deletions(-) diff --git a/packages/chakra-ui-core/src/CAccordion/CAccordion.js b/packages/chakra-ui-core/src/CAccordion/CAccordion.js index 45b2f9b8..85dfa778 100644 --- a/packages/chakra-ui-core/src/CAccordion/CAccordion.js +++ b/packages/chakra-ui-core/src/CAccordion/CAccordion.js @@ -21,12 +21,9 @@ * @see WAI-ARIA https://www.w3.org/TR/wai-aria-practices-1.2/#accordion */ -import { baseProps } from '../config' -import { forwardProps, cloneVNodes, useId, isDef } from '../utils' -import styleProps from '../config/props' +import { forwardProps, cloneVNodes, useId, isDef, createStyledAttrsMixin } from '../utils' import { iconProps } from '../CIcon/utils/icon.props' -import CBox from '../CBox' import CPseudoBox from '../CPseudoBox' import CCollapse from '../CCollapse' import CIcon from '../CIcon' @@ -42,9 +39,8 @@ import CIcon from '../CIcon' */ const CAccordion = { - name: 'CAccordion', + mixins: [createStyledAttrsMixin('CAccordion')], props: { - ...baseProps, allowMultiple: Boolean, allowToggle: Boolean, index: { @@ -136,13 +132,9 @@ const CAccordion = { return clone }) - return h(CBox, { - props: { - ...forwardProps(this.$props) - }, - attrs: { - 'data-chakra-component': 'CAccordion' - } + return h('div', { + class: this.className, + attrs: this.computedAttrs }, clones) } } @@ -157,9 +149,8 @@ const CAccordion = { */ const CAccordionItem = { - name: 'CAccordionItem', + mixins: [createStyledAttrsMixin('CAccordionItem', true)], props: { - ...styleProps, isOpen: { type: Boolean, default: null @@ -168,10 +159,7 @@ const CAccordionItem = { type: Boolean, default: false }, - id: { - type: String, - default: useId() - }, + id: String, isDisabled: { type: Boolean, default: false @@ -208,11 +196,20 @@ const CAccordionItem = { this.isExpanded = value } }, + _id () { + return this.id || useId() + }, headerId () { - return `accordion-header-${this.id}` + return `accordion-header-${this._id}` }, panelId () { - return `accordion-panel-${this.id}` + return `accordion-panel-${this._id}` + }, + componentStyles () { + return { + borderTopWidth: '1px', + _last: { borderBottomWidth: '1px' } + } } }, methods: { @@ -225,14 +222,13 @@ const CAccordionItem = { }, render (h) { return h(CPseudoBox, { + class: this.className, props: { ...forwardProps(this.$props), borderTopWidth: '1px', _last: { borderBottomWidth: '1px' } }, - attrs: { - 'data-chakra-component': 'CAccordionItem' - } + attrs: this.computedAttrs }, [ this.$scopedSlots.default({ isExpanded: this._isExpanded, @@ -252,9 +248,8 @@ const CAccordionItem = { * @see Docs https://vue.chakra-ui.com/accordion */ const CAccordionHeader = { - name: 'CAccordionHeader', + mixins: [createStyledAttrsMixin('CAccordionHeader', true)], inject: ['$AccordionContext'], - props: styleProps, computed: { context () { return this.$AccordionContext() @@ -263,8 +258,7 @@ const CAccordionHeader = { render (h) { const { isExpanded, panelId, headerId, isDisabled, onToggle } = this.context return h(CPseudoBox, { - props: { - ...forwardProps(this.$props), + attrs: { as: 'button', display: 'flex', alignItems: 'center', @@ -275,9 +269,7 @@ const CAccordionHeader = { py: 2, _focus: { boxShadow: 'outline' }, _hover: { bg: 'blackAlpha.50' }, - _disabled: { opacity: '0.4', cursor: 'not-allowed' } - }, - attrs: { + _disabled: { opacity: '0.4', cursor: 'not-allowed' }, id: headerId, type: 'button', disabled: isDisabled, @@ -307,8 +299,8 @@ const CAccordionHeader = { */ const CAccordionPanel = { name: 'CAccordionPanel', + inheritAttrs: false, inject: ['$AccordionContext'], - props: baseProps, computed: { context () { return this.$AccordionContext() @@ -316,21 +308,17 @@ const CAccordionPanel = { }, render (h) { const { isExpanded, panelId, headerId } = this.context - return h(CCollapse, { - props: { - ...forwardProps(this.$props), - isOpen: isExpanded, + attrs: { pt: 2, px: 4, - pb: 5 - }, - attrs: { + pb: 5, + isOpen: isExpanded, id: panelId, - 'data-chakra-component': 'CAccordionPanel', 'aria-labelledby': headerId, 'aria-hidden': !isExpanded, - role: 'region' + role: 'region', + ...this.$attrs } }, this.$slots.default) } @@ -346,32 +334,31 @@ const CAccordionPanel = { * @see Docs https://vue.chakra-ui.com/accordion */ const CAccordionIcon = { - name: 'CAccordionIcon', + mixins: [createStyledAttrsMixin('CAccordionIcon')], inject: ['$AccordionContext'], - props: { - ...baseProps, - ...iconProps - }, + props: iconProps, computed: { context () { return this.$AccordionContext() + }, + componentStyles () { + const { isExpanded, isDisabled } = this.context + return { + opacity: isDisabled ? 0.4 : 1, + transform: isExpanded ? 'rotate(-180deg)' : null, + transition: 'transform 0.2s', + transformOrigin: 'center' + } } }, render (h) { - const { isExpanded, isDisabled } = this.context return h(CIcon, { + class: this.className, props: { - ...forwardProps(this.$props), size: this.size || '1.25em', - name: this.name || 'chevron-down', - opacity: isDisabled ? 0.4 : 1, - transform: isExpanded ? 'rotate(-180deg)' : null, - transition: 'transform 0.2s', - transformOrigin: 'center' + name: this.name || 'chevron-down' }, - attrs: { - 'data-chakra-component': 'CAccordionIcon' - } + attrs: this.computedAttrs }) } } diff --git a/packages/chakra-ui-core/src/CAccordion/CAccordion.stories.js b/packages/chakra-ui-core/src/CAccordion/CAccordion.stories.js index ca906410..1949c5bb 100644 --- a/packages/chakra-ui-core/src/CAccordion/CAccordion.stories.js +++ b/packages/chakra-ui-core/src/CAccordion/CAccordion.stories.js @@ -32,7 +32,6 @@ storiesOf('UI | Accordion', module) tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. -
` diff --git a/packages/chakra-ui-core/src/CCollapse/CCollapse.js b/packages/chakra-ui-core/src/CCollapse/CCollapse.js index f1b20b24..318fe0f7 100644 --- a/packages/chakra-ui-core/src/CCollapse/CCollapse.js +++ b/packages/chakra-ui-core/src/CCollapse/CCollapse.js @@ -10,7 +10,6 @@ */ import { CAnimateHeight } from '../CTransition' -import { forwardProps } from '../utils' import CBox from '../CBox' @@ -25,7 +24,7 @@ import CBox from '../CBox' */ const CCollapse = { name: 'CCollapse', - extends: CBox, + inheritAttrs: false, props: { isOpen: Boolean, duration: { @@ -45,7 +44,6 @@ const CCollapse = { }, render (h) { const children = this.$slots.default - return h(CAnimateHeight, { props: { isOpen: this.isOpen, @@ -60,13 +58,18 @@ const CCollapse = { enter: e => this.$emit('start', e), leave: e => this.$emit('finish', e) }, + style: { + overflow: 'hidden' + }, attrs: { 'data-chakra-component': 'CCollapse' } }, [h(CBox, { props: { - ...forwardProps(this.$props), - overflow: 'hidden' + as: this.as + }, + attrs: { + ...this.$attrs } }, children)]) } From 8f4a3cb33d9257a5f695cdcc7bc7d2d5a9a05a9a Mon Sep 17 00:00:00 2001 From: codebender828 Date: Thu, 2 Jul 2020 17:27:39 +0800 Subject: [PATCH 022/133] test((box): update box test --- jest.config.js | 3 +- package.json | 1 + .../src/CBox/tests/CBox.test.js | 16 ++++++---- .../tests/__snapshots__/CBox.test.js.snap | 29 +++++++++++++++---- .../chakra-ui-core/src/utils/components.js | 2 +- yarn.lock | 17 ++++++++++- 6 files changed, 54 insertions(+), 14 deletions(-) diff --git a/jest.config.js b/jest.config.js index e03e1bb7..d0aba066 100644 --- a/jest.config.js +++ b/jest.config.js @@ -20,7 +20,8 @@ module.exports = { breadstick: require.resolve('./tests/test-utils/module-mock.js') }, snapshotSerializers: [ - 'jest-serializer-vue' + 'jest-serializer-vue', + 'jest-emotion' ], testMatch: [ '**/**/*.test.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' diff --git a/package.json b/package.json index f5e69eea..8f3b44de 100644 --- a/package.json +++ b/package.json @@ -149,6 +149,7 @@ "eslint-plugin-nuxt": ">=0.4.2", "eslint-plugin-prettier": "^3.1.2", "jest": "^25.1.0", + "jest-emotion": "^10.0.32", "prettier": "^1.19.1", "rimraf": "^3.0.2", "rollup": "^1.31.1", diff --git a/packages/chakra-ui-core/src/CBox/tests/CBox.test.js b/packages/chakra-ui-core/src/CBox/tests/CBox.test.js index 61060dad..b3480477 100644 --- a/packages/chakra-ui-core/src/CBox/tests/CBox.test.js +++ b/packages/chakra-ui-core/src/CBox/tests/CBox.test.js @@ -1,5 +1,7 @@ +import serializer from 'jest-emotion' import CBox from '../' import { render } from '@/tests/test-utils' +expect.addSnapshotSerializer(serializer) const renderComponent = (props) => { const inlineAttrs = (props && props.inlineAttrs) || '' @@ -8,20 +10,21 @@ const renderComponent = (props) => { template: `Box Works`, ...props } + return render(base) } it('should render correctly', () => { const { asFragment } = renderComponent() - expect(asFragment()).toMatchSnapshot() }) it('should change the style', () => { const inlineAttrs = ` - d="flex" :w="['auto']" px="5" py="5" shadow="lg" - my="5" mb="5" rounded="sm" font-family="body" - background-color="blue.200" color="blue.700"` + d="flex" :w="['auto']" px="5" py="5" shadow="lg" + my="5" mb="5" rounded="sm" font-family="body" + background-color="blue.200" color="blue.700"` + const { asFragment, getByTestId } = renderComponent({ inlineAttrs }) const box = getByTestId('box') @@ -47,8 +50,9 @@ it.each` 'should display CBox with type as $as', ({ as }) => { const inlineAttrs = `as=${as}` - const { asFragment } = renderComponent({ inlineAttrs }) - + const { asFragment, getByTestId } = renderComponent({ inlineAttrs }) + const box = getByTestId('box') + expect(box.tagName.toLowerCase()).toEqual(as) expect(asFragment()).toMatchSnapshot() } ) diff --git a/packages/chakra-ui-core/src/CBox/tests/__snapshots__/CBox.test.js.snap b/packages/chakra-ui-core/src/CBox/tests/__snapshots__/CBox.test.js.snap index 1b73abef..4959a2ac 100644 --- a/packages/chakra-ui-core/src/CBox/tests/__snapshots__/CBox.test.js.snap +++ b/packages/chakra-ui-core/src/CBox/tests/__snapshots__/CBox.test.js.snap @@ -2,8 +2,27 @@ exports[`should change the style 1`] = ` -
@@ -15,7 +34,7 @@ exports[`should change the style 1`] = ` exports[`should display CBox with type as header 1`] = `
@@ -27,7 +46,7 @@ exports[`should display CBox with type as header 1`] = ` exports[`should display CBox with type as p 1`] = `

@@ -39,7 +58,7 @@ exports[`should display CBox with type as p 1`] = ` exports[`should render correctly 1`] = `

diff --git a/packages/chakra-ui-core/src/utils/components.js b/packages/chakra-ui-core/src/utils/components.js index ff53f76d..6f0997f7 100644 --- a/packages/chakra-ui-core/src/utils/components.js +++ b/packages/chakra-ui-core/src/utils/components.js @@ -84,7 +84,7 @@ export const createStyledAttrsMixin = (name, isPseudo) => ({ computedAttrs () { return { ...this.splitProps.attrs, - 'data-chakra-component': name + ...name && { 'data-chakra-component': name } } } }, diff --git a/yarn.lock b/yarn.lock index 90ec3879..f0e50b2d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4265,6 +4265,11 @@ jest-diff "25.1.0" pretty-format "25.1.0" +"@types/jest@^23.0.2": + version "23.3.14" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.14.tgz#37daaf78069e7948520474c87b80092ea912520a" + integrity sha512-Q5hTcfdudEL2yOmluA1zaSyPbzWPmJ3XfSWeP3RyoYvS9hnje1ZyagrZOuQ6+1nQC1Gw+7gap3pLNL3xL6UBug== + "@types/json-schema@^7.0.3": version "7.0.4" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" @@ -8824,7 +8829,7 @@ css.escape@^1.5.1: resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= -css@^2.0.0, css@^2.1.0, css@^2.2.4: +css@^2.0.0, css@^2.1.0, css@^2.2.1, css@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== @@ -13774,6 +13779,16 @@ jest-each@^25.5.0: jest-util "^25.5.0" pretty-format "^25.5.0" +jest-emotion@^10.0.32: + version "10.0.32" + resolved "https://registry.yarnpkg.com/jest-emotion/-/jest-emotion-10.0.32.tgz#8e36a871911f78841701224a95b7c535c65b70b6" + integrity sha512-hW3IwWc47qRuxnGsWFGY6uIMX8F4YBzq+Qci3LAYUCUqUBNP+1DU1L5Nudo9Ry0NHVFOqDnDeip1p2UR0kVMwA== + dependencies: + "@babel/runtime" "^7.5.5" + "@types/jest" "^23.0.2" + chalk "^2.4.1" + css "^2.2.1" + jest-environment-jsdom@^23.4.0: version "23.4.0" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz#056a7952b3fea513ac62a140a2c368c79d9e6023" From afaa8bc8f8eb06f057fc91bb40541047229da4da Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Thu, 2 Jul 2020 19:27:59 +0300 Subject: [PATCH 023/133] fix(avatar): render AvatarName if no src provided and fix all test cases --- jest.config.js | 3 +- .../chakra-ui-core/src/CAvatar/CAvatar.js | 5 +- .../src/CAvatar/tests/CAvatar.test.js | 77 ++++++++++++++----- .../tests/__snapshots__/CAvatar.test.js.snap | 61 +++++---------- 4 files changed, 79 insertions(+), 67 deletions(-) diff --git a/jest.config.js b/jest.config.js index e03e1bb7..d2c950c2 100644 --- a/jest.config.js +++ b/jest.config.js @@ -29,5 +29,6 @@ module.exports = { watchPlugins: [ 'jest-watch-typeahead/filename', 'jest-watch-typeahead/testname' - ] + ], + testEnvironmentOptions: { resources: 'usable' } } diff --git a/packages/chakra-ui-core/src/CAvatar/CAvatar.js b/packages/chakra-ui-core/src/CAvatar/CAvatar.js index d98d0574..73a2a274 100644 --- a/packages/chakra-ui-core/src/CAvatar/CAvatar.js +++ b/packages/chakra-ui-core/src/CAvatar/CAvatar.js @@ -201,7 +201,6 @@ const CAvatar = { if (!canUseDOM) { return } - const image = new window.Image() image.src = src @@ -210,7 +209,7 @@ const CAvatar = { this.$emit('load', event) } - image.onError = (event) => { + image.onerror = (event) => { this.hasLoaded = false this.$emit('error', event) } @@ -252,7 +251,7 @@ const CAvatar = { }) } - if (this.src && !this.hasLoaded) { + if (!this.src || (this.src && !this.hasLoaded)) { if (this.name) { return h(CAvatarName, { props: { diff --git a/packages/chakra-ui-core/src/CAvatar/tests/CAvatar.test.js b/packages/chakra-ui-core/src/CAvatar/tests/CAvatar.test.js index 79b87d60..c36e1fe0 100644 --- a/packages/chakra-ui-core/src/CAvatar/tests/CAvatar.test.js +++ b/packages/chakra-ui-core/src/CAvatar/tests/CAvatar.test.js @@ -1,45 +1,82 @@ import { CAvatar, CAvatarBadge } from '..' -import { render, fireEvent } from '@/tests/test-utils' +import { render, wait, waitMs, screen } from '@/tests/test-utils' +const LOAD_FAILURE_SRC = 'LOAD_FAILURE_SRC' +const LOAD_SUCCESS_SRC = 'LOAD_SUCCESS_SRC' + +beforeAll(() => { + process.browser = true // Mock process.browser for CAvatar created() +}) + +beforeAll(() => { + // Mock Img + // eslint-disable-next-line accessor-pairs + Object.defineProperty(global.Image.prototype, 'src', { + set (src) { + if (src === LOAD_FAILURE_SRC) { + setTimeout(() => this.onerror(new Error('mocked error'))) + } else if (src === LOAD_SUCCESS_SRC) { + setTimeout(() => this.onload()) + } + } + }) +}) const renderComponent = (props) => { const base = { components: { CAvatar, CAvatarBadge }, - template: '', + template: '', ...props } return render(base) } -it('should render correctly', () => { +it('should render correctly', async () => { const { asFragment } = renderComponent() + + await waitMs(1) // wait for img.onsuccess to be called. + expect(asFragment()).toMatchSnapshot() }) -it("should render default avatar if name is not provided and image didn't load", async () => { - const { container, asFragment } = renderComponent({ template: '' }) - const image = container.querySelector('img') +it('Avatar with AvatarBadge renders correctly', async () => { + const { asFragment } = renderComponent({ + template: ` + + + + ` + }) - if (image) { - await fireEvent.error(image) - } + await waitMs(1) // wait for img.onsuccess to be called. expect(asFragment()).toMatchSnapshot() }) -// TODO: change mounted logic in avatar -xit('should render image if loaded correctly', () => { - const { getByAltText } = renderComponent() +it('renders an image', async () => { + renderComponent({ template: '' }) - expect(getByAltText('Mesut Koca')).toBeInTheDocument() + await wait(() => { + expect(screen.getByAltText(/Mesut Koca/i)).toBeInTheDocument() + }) }) -// TODO: change mounted logic in avatar -xit("should render avatar name as fallback if image didn't loaded correctly", async () => { - const { getByAltText, queryByAltText, getByText } = renderComponent() - const image = getByAltText('Mesut Koca') +it('renders a name avatar if no src', async () => { + renderComponent({ template: '' }) + + await wait(() => { + expect(screen.getByLabelText(/Mesut Koca/i)).toBeInTheDocument() + expect(screen.getByText('MK')).toBeInTheDocument() + }) +}) - await fireEvent.error(image) +it('renders a name avatar if src fails', async () => { + renderComponent({ template: '' }) - expect(queryByAltText('Mesut Koca')).not.toBeInTheDocument() - expect(getByText('MK')).toBeInTheDocument() + await wait(() => { + expect(screen.queryByAltText(/Mesut Koca/i)).not.toBeInTheDocument() + expect(screen.getByText('MK')).toBeInTheDocument() + }) }) diff --git a/packages/chakra-ui-core/src/CAvatar/tests/__snapshots__/CAvatar.test.js.snap b/packages/chakra-ui-core/src/CAvatar/tests/__snapshots__/CAvatar.test.js.snap index bf5dae1f..35592779 100644 --- a/packages/chakra-ui-core/src/CAvatar/tests/__snapshots__/CAvatar.test.js.snap +++ b/packages/chakra-ui-core/src/CAvatar/tests/__snapshots__/CAvatar.test.js.snap @@ -1,63 +1,38 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should render correctly 1`] = ` +exports[`Avatar with AvatarBadge renders correctly 1`] = `
+ Mesut Koca
- MK -
+ class="css-mwkd9l" + data-chakra-component="CAvatarBadge" + />
`; -exports[`should render default avatar if name is not provided and image didn't load 1`] = ` +exports[`should render correctly 1`] = `
-
- - - - - - - - - - - - - - - - - - - - -
+ Mesut Koca
`; From b2b706df8bad2331d526413d2ee246d53ffd0546 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Thu, 2 Jul 2020 19:51:55 +0300 Subject: [PATCH 024/133] test(avatar-group): fix AvatarGroup tests --- .../CAvatarGroup/tests/CAvatarGroup.test.js | 34 ++++++++++++++++--- .../__snapshots__/CAvatarGroup.test.js.snap | 26 +++++++------- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/packages/chakra-ui-core/src/CAvatarGroup/tests/CAvatarGroup.test.js b/packages/chakra-ui-core/src/CAvatarGroup/tests/CAvatarGroup.test.js index 9cbed35f..b14d5d3f 100644 --- a/packages/chakra-ui-core/src/CAvatarGroup/tests/CAvatarGroup.test.js +++ b/packages/chakra-ui-core/src/CAvatarGroup/tests/CAvatarGroup.test.js @@ -1,5 +1,26 @@ import { CAvatar, CAvatarGroup } from '../..' -import { render } from '@/tests/test-utils' +import { render, waitMs } from '@/tests/test-utils' + +const LOAD_FAILURE_SRC = 'LOAD_FAILURE_SRC' +const LOAD_SUCCESS_SRC = 'LOAD_SUCCESS_SRC' + +beforeAll(() => { + process.browser = true // Mock process.browser for CAvatar created() +}) + +beforeAll(() => { + // Mock Img + // eslint-disable-next-line accessor-pairs + Object.defineProperty(global.Image.prototype, 'src', { + set (src) { + if (src === LOAD_FAILURE_SRC) { + setTimeout(() => this.onerror(new Error('mocked error'))) + } else if (src === LOAD_SUCCESS_SRC) { + setTimeout(() => this.onload()) + } + } + }) +}) const renderComponent = (props) => { const base = { @@ -11,15 +32,15 @@ const renderComponent = (props) => { `, ...props @@ -27,8 +48,11 @@ const renderComponent = (props) => { return render(base) } -it('should render correctly', () => { +it('should render correctly', async () => { const { asFragment } = renderComponent() + + await waitMs(1) + expect(asFragment()).toMatchSnapshot() }) diff --git a/packages/chakra-ui-core/src/CAvatarGroup/tests/__snapshots__/CAvatarGroup.test.js.snap b/packages/chakra-ui-core/src/CAvatarGroup/tests/__snapshots__/CAvatarGroup.test.js.snap index d539866a..f7fbaa6b 100644 --- a/packages/chakra-ui-core/src/CAvatarGroup/tests/__snapshots__/CAvatarGroup.test.js.snap +++ b/packages/chakra-ui-core/src/CAvatarGroup/tests/__snapshots__/CAvatarGroup.test.js.snap @@ -10,25 +10,23 @@ exports[`should render correctly 1`] = ` class="css-1jwki60" data-chakra-component="CAvatar" > -
- MK -
+ Mesut Koca
-
- EY -
+ Evan You
Date: Thu, 2 Jul 2020 19:57:04 +0300 Subject: [PATCH 025/133] test(bread-crumb): refactor Breadcrump tests --- .../src/CBreadcrumb/tests/CBreadcrumb.test.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/chakra-ui-core/src/CBreadcrumb/tests/CBreadcrumb.test.js b/packages/chakra-ui-core/src/CBreadcrumb/tests/CBreadcrumb.test.js index 4bbeaa0d..32bc26bd 100644 --- a/packages/chakra-ui-core/src/CBreadcrumb/tests/CBreadcrumb.test.js +++ b/packages/chakra-ui-core/src/CBreadcrumb/tests/CBreadcrumb.test.js @@ -1,5 +1,5 @@ import { CBreadcrumb, CBreadcrumbItem, CBreadcrumbLink, CBreadcrumbSeparator } from '..' -import { render } from '@/tests/test-utils' +import { render, screen } from '@/tests/test-utils' const renderComponent = (props) => { const base = { @@ -49,7 +49,7 @@ it('should display custom seperator ', () => { }) it('should have the proper aria-attributes', () => { - const { getByText, getAllByRole, getByLabelText } = renderComponent({ + renderComponent({ template: ` @@ -65,12 +65,12 @@ it('should have the proper aria-attributes', () => { }) // surrounding `nav` has aria-label="breadcrumb" - getByLabelText('breadcrumb', { selector: 'nav' }) + screen.getByLabelText('breadcrumb', { selector: 'nav' }) // `isCurrentPage` link has aria-current="page" - const currentPageLink = getByText('Contact') + const currentPageLink = screen.getByText('Contact') expect(currentPageLink).toHaveAttribute('aria-current', 'page') // separator receives presentation="role" - expect(getAllByRole('presentation')).toHaveLength(2) + expect(screen.getAllByRole('presentation')).toHaveLength(2) }) From 5e8f58e4ab13d21d7b186ae69d521be87ea6058a Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Thu, 2 Jul 2020 20:03:42 +0300 Subject: [PATCH 026/133] test(button): refactor button tests --- .../src/CButton/tests/CButton.test.js | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/packages/chakra-ui-core/src/CButton/tests/CButton.test.js b/packages/chakra-ui-core/src/CButton/tests/CButton.test.js index 2f976f9e..578394cd 100644 --- a/packages/chakra-ui-core/src/CButton/tests/CButton.test.js +++ b/packages/chakra-ui-core/src/CButton/tests/CButton.test.js @@ -1,5 +1,5 @@ import { CButton } from '../..' -import { render } from '@/tests/test-utils' +import { render, screen } from '@/tests/test-utils' const renderComponent = (props) => { const base = { @@ -17,26 +17,19 @@ it('should render correctly', () => { expect(asFragment()).toMatchSnapshot() }) -it('should display children', () => { - const { getByText } = renderComponent({ template: 'Works' }) - expect(getByText('Works')).toBeInTheDocument() -}) - it('should display button with left icon', () => { - const { container, asFragment } = renderComponent({ template: 'Email' }) - expect(container.querySelector('button > svg')).toBeInTheDocument() + const { asFragment } = renderComponent({ template: 'Email' }) expect(asFragment()).toMatchSnapshot() }) it('should display button with right icon', () => { - const { container, asFragment } = renderComponent({ template: 'Email' }) - expect(container.querySelector('button > svg')).toBeInTheDocument() + const { asFragment } = renderComponent({ template: 'Email' }) expect(asFragment()).toMatchSnapshot() }) it('should display spinner and hide text', () => { - const { getByTestId, container } = renderComponent({ template: 'CButton' }) - const button = getByTestId('btn') + const { container } = renderComponent({ template: 'CButton' }) + const button = screen.getByTestId('btn') expect(button).toHaveAttribute('disabled') expect(button).toHaveAttribute('aria-disabled', 'true') @@ -47,15 +40,15 @@ it('should display spinner and hide text', () => { }) it('should display spinner with text', () => { - const { getByText, container } = renderComponent({ template: 'Button' }) + const { container } = renderComponent({ template: 'Button' }) - expect(getByText('Submitting')).toBeInTheDocument() + expect(screen.getByText('Submitting')).toBeInTheDocument() const spinner = container.querySelector('[data-chakra-component=CSpinner]') expect(spinner).toBeInTheDocument() }) it('should display a disabled button', () => { - const { getByText } = renderComponent({ template: 'Button' }) + renderComponent({ template: 'Button' }) - expect(getByText('Button')).toHaveAttribute('disabled') + expect(screen.getByText('Button')).toHaveAttribute('disabled') }) From 83e9a99a9594b8db2cb3211af867ecf6a69a76f2 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Thu, 2 Jul 2020 20:41:57 +0300 Subject: [PATCH 027/133] chore: add .jsconfig for better code completion support in vscode --- jsconfig.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 jsconfig.json diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 00000000..29037a62 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "~/*": ["./*"], + "@/*": ["./*"], + "~~/*": ["./*"], + "@@/*": ["./*"] + } + }, + "exclude": ["node_modules", ".nuxt", "dist"] +} From 78099790e56253e2be0ff70b078cef641e62ce05 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Thu, 2 Jul 2020 21:26:33 +0300 Subject: [PATCH 028/133] chore: add eslint testing library plugin --- .eslintrc.js | 17 ++++++++++------- package.json | 1 + yarn.lock | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 66b25a11..d37cd07f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,15 +3,21 @@ module.exports = { env: { node: true }, - 'extends': [ + plugins: ['testing-library'], + extends: [ 'plugin:vue/essential', '@vue/standard', - '@nuxtjs' + '@nuxtjs', + 'plugin:testing-library/recommended', + 'plugin:testing-library/vue' ], rules: { 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', - 'curly': 'off' + curly: 'off', + 'testing-library/no-debug': 'error', + 'testing-library/prefer-screen-queries': 'error', + 'testing-library/await-fire-event': 'error' }, parserOptions: { parser: 'babel-eslint' @@ -23,10 +29,7 @@ module.exports = { }, overrides: [ { - files: [ - '**/__tests__/*.{j,t}s?(x)', - '**/tests/*.{j,t}s?(x)' - ], + files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/*.{j,t}s?(x)'], env: { jest: true } diff --git a/package.json b/package.json index 0bb0e3ac..d5455650 100644 --- a/package.json +++ b/package.json @@ -147,6 +147,7 @@ "eslint-loader": "^3.0.3", "eslint-plugin-nuxt": ">=0.4.2", "eslint-plugin-prettier": "^3.1.2", + "eslint-plugin-testing-library": "^3.3.1", "jest": "^25.1.0", "prettier": "^1.19.1", "rimraf": "^3.0.2", diff --git a/yarn.lock b/yarn.lock index d29f93c9..700d5a23 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4585,6 +4585,16 @@ dependencies: "@types/yargs-parser" "*" +"@typescript-eslint/experimental-utils@^2.29.0": + version "2.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz#d3524b644cdb40eebceca67f8cf3e4cc9c8f980f" + integrity sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/typescript-estree" "2.34.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + "@typescript-eslint/experimental-utils@^2.5.0": version "2.26.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.26.0.tgz#063390c404d9980767d76274df386c0aa675d91d" @@ -4608,6 +4618,19 @@ semver "^6.3.0" tsutils "^3.17.1" +"@typescript-eslint/typescript-estree@2.34.0": + version "2.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz#14aeb6353b39ef0732cc7f1b8285294937cf37d5" + integrity sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg== + dependencies: + debug "^4.1.1" + eslint-visitor-keys "^1.1.0" + glob "^7.1.6" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + "@vue/babel-helper-vue-jsx-merge-props@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz#048fe579958da408fb7a8b2a3ec050b50a661040" @@ -10128,6 +10151,13 @@ eslint-plugin-standard@^4.0.0, eslint-plugin-standard@^4.0.1: resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ== +eslint-plugin-testing-library@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-3.3.1.tgz#aab204bb19b634ee50a9da550649a51723ebb423" + integrity sha512-0Ubug+v9hJDb0OEHc6e2p5/7Q4xhaCZiYLc05hybja8Yd2t+2y1Q+UDwKz+JiDAHoPgE7y2B2G3jn+u9kqJTGw== + dependencies: + "@typescript-eslint/experimental-utils" "^2.29.0" + eslint-plugin-unicorn@^16.0.0: version "16.1.1" resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-16.1.1.tgz#012c598d71914ef30f5d386dd85110e59f2ef999" @@ -20064,6 +20094,11 @@ semver@^7.1.2, semver@^7.1.3: resolved "https://registry.yarnpkg.com/semver/-/semver-7.1.3.tgz#e4345ce73071c53f336445cfc19efb1c311df2a6" integrity sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA== +semver@^7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" From 8a3a5909fb67dabba4cd75137bb1e7a3b87e6c19 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Thu, 2 Jul 2020 21:27:59 +0300 Subject: [PATCH 029/133] test(button-group): remove unnecessary test in ButtonGroup --- .../src/CButtonGroup/tests/CButtonGroup.test.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/chakra-ui-core/src/CButtonGroup/tests/CButtonGroup.test.js b/packages/chakra-ui-core/src/CButtonGroup/tests/CButtonGroup.test.js index f87efd27..18468028 100644 --- a/packages/chakra-ui-core/src/CButtonGroup/tests/CButtonGroup.test.js +++ b/packages/chakra-ui-core/src/CButtonGroup/tests/CButtonGroup.test.js @@ -1,5 +1,5 @@ import { CButton, CButtonGroup } from '../..' -import { render } from '@/tests/test-utils' +import { render, screen } from '@/tests/test-utils' const renderComponent = (props) => { const base = { @@ -21,9 +21,3 @@ it('should render correctly', () => { const { asFragment } = renderComponent() expect(asFragment()).toMatchSnapshot() }) - -it('should display children', () => { - const { getByText } = renderComponent() - expect(getByText('Button1')).toBeInTheDocument() - expect(getByText('Button2')).toBeInTheDocument() -}) From 5bcc4d5c2e144ded41a5632066307db80f053ace Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Thu, 2 Jul 2020 21:34:03 +0300 Subject: [PATCH 030/133] test(avatar): remove unused attrs --- packages/chakra-ui-core/src/CAvatar/tests/CAvatar.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/chakra-ui-core/src/CAvatar/tests/CAvatar.test.js b/packages/chakra-ui-core/src/CAvatar/tests/CAvatar.test.js index c36e1fe0..0d801f5a 100644 --- a/packages/chakra-ui-core/src/CAvatar/tests/CAvatar.test.js +++ b/packages/chakra-ui-core/src/CAvatar/tests/CAvatar.test.js @@ -64,7 +64,7 @@ it('renders an image', async () => { }) it('renders a name avatar if no src', async () => { - renderComponent({ template: '' }) + renderComponent({ template: '' }) await wait(() => { expect(screen.getByLabelText(/Mesut Koca/i)).toBeInTheDocument() @@ -73,7 +73,7 @@ it('renders a name avatar if no src', async () => { }) it('renders a name avatar if src fails', async () => { - renderComponent({ template: '' }) + renderComponent({ template: '' }) await wait(() => { expect(screen.queryByAltText(/Mesut Koca/i)).not.toBeInTheDocument() From b57613b7ea6342a8d76e0a659bcca16074586aac Mon Sep 17 00:00:00 2001 From: codebender828 Date: Sat, 4 Jul 2020 07:22:04 +0800 Subject: [PATCH 031/133] test: update box and pseudobox snapshots --- .../src/CBox/tests/CBox.test.js | 1 - .../src/CPseudoBox/tests/CPseudoBox.test.js | 34 ++++++++------- .../__snapshots__/CPseudoBox.test.js.snap | 37 ++++++++++++---- tests/test-utils/test-utils.js | 43 +++++++++++++++++++ 4 files changed, 89 insertions(+), 26 deletions(-) diff --git a/packages/chakra-ui-core/src/CBox/tests/CBox.test.js b/packages/chakra-ui-core/src/CBox/tests/CBox.test.js index b3480477..3c80a9f3 100644 --- a/packages/chakra-ui-core/src/CBox/tests/CBox.test.js +++ b/packages/chakra-ui-core/src/CBox/tests/CBox.test.js @@ -10,7 +10,6 @@ const renderComponent = (props) => { template: `Box Works`, ...props } - return render(base) } diff --git a/packages/chakra-ui-core/src/CPseudoBox/tests/CPseudoBox.test.js b/packages/chakra-ui-core/src/CPseudoBox/tests/CPseudoBox.test.js index d3b74b19..35f324d4 100644 --- a/packages/chakra-ui-core/src/CPseudoBox/tests/CPseudoBox.test.js +++ b/packages/chakra-ui-core/src/CPseudoBox/tests/CPseudoBox.test.js @@ -1,11 +1,14 @@ +import serializer from 'jest-emotion' import CPseudoBox from '../' -import { render } from '@/tests/test-utils' +import { render, getTagName } from '@/tests/test-utils' + +expect.addSnapshotSerializer(serializer) const renderComponent = (props) => { const inlineAttrs = (props && props.inlineAttrs) || '' const base = { components: { CPseudoBox }, - template: `Box Works`, + template: `Box Works`, ...props } return render(base) @@ -13,7 +16,6 @@ const renderComponent = (props) => { it('should render correctly', () => { const { asFragment } = renderComponent() - expect(asFragment()).toMatchSnapshot() }) @@ -24,19 +26,19 @@ it('should change the style', () => { background-color="blue.200" color="blue.700"` const { asFragment, getByTestId } = renderComponent({ inlineAttrs }) - const box = getByTestId('box') + const pseudobox = getByTestId('pseudobox') expect(asFragment()).toMatchSnapshot() - expect(box).toHaveStyle('display: flex') - expect(box).toHaveStyle('width: auto') - expect(box).toHaveStyle('margin-bottom: 1.25rem') - expect(box).toHaveStyle('margin-top: 1.25rem') - expect(box).toHaveStyle('box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1),0 4px 6px -2px rgba(0,0,0,0.05);') - expect(box).toHaveStyle('padding: 1.25rem 1.25rem 1.25rem 1.25rem;') - expect(box).toHaveStyle('border-radius: 0.125rem;') - expect(box).toHaveStyle('font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";') - expect(box).toHaveStyle('color: rgb(0, 49, 130);') - expect(box).toHaveStyle('background-color: rgb(125, 177, 255);') + expect(pseudobox).toHaveStyle('display: flex') + expect(pseudobox).toHaveStyle('width: auto') + expect(pseudobox).toHaveStyle('margin-bottom: 1.25rem') + expect(pseudobox).toHaveStyle('margin-top: 1.25rem') + expect(pseudobox).toHaveStyle('box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1),0 4px 6px -2px rgba(0,0,0,0.05);') + expect(pseudobox).toHaveStyle('padding: 1.25rem 1.25rem 1.25rem 1.25rem;') + expect(pseudobox).toHaveStyle('border-radius: 0.125rem;') + expect(pseudobox).toHaveStyle('font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";') + expect(pseudobox).toHaveStyle('color: rgb(0, 49, 130);') + expect(pseudobox).toHaveStyle('background-color: rgb(125, 177, 255);') }) it.each` @@ -47,8 +49,8 @@ it.each` 'should display Box with type as $as', ({ as }) => { const inlineAttrs = `as=${as}` - const { asFragment } = renderComponent({ inlineAttrs }) - + const { asFragment, getByTestId } = renderComponent({ inlineAttrs }) + expect(getTagName(getByTestId('pseudobox'))).toEqual(as) expect(asFragment()).toMatchSnapshot() } ) diff --git a/packages/chakra-ui-core/src/CPseudoBox/tests/__snapshots__/CPseudoBox.test.js.snap b/packages/chakra-ui-core/src/CPseudoBox/tests/__snapshots__/CPseudoBox.test.js.snap index c4256ee1..16ed123d 100644 --- a/packages/chakra-ui-core/src/CPseudoBox/tests/__snapshots__/CPseudoBox.test.js.snap +++ b/packages/chakra-ui-core/src/CPseudoBox/tests/__snapshots__/CPseudoBox.test.js.snap @@ -2,10 +2,29 @@ exports[`should change the style 1`] = ` -
Box Works
@@ -15,9 +34,9 @@ exports[`should change the style 1`] = ` exports[`should display Box with type as header 1`] = `
Box Works
@@ -27,9 +46,9 @@ exports[`should display Box with type as header 1`] = ` exports[`should display Box with type as p 1`] = `

Box Works

@@ -39,9 +58,9 @@ exports[`should display Box with type as p 1`] = ` exports[`should render correctly 1`] = `
Box Works
diff --git a/tests/test-utils/test-utils.js b/tests/test-utils/test-utils.js index 563f9b0d..5a3332e9 100644 --- a/tests/test-utils/test-utils.js +++ b/tests/test-utils/test-utils.js @@ -32,10 +32,53 @@ const customRender = (component, ...rest) => { } } +/** + * Wait for given ms + * + * @param {number} duration + */ export function waitMs (ms = 0) { return new Promise(resolve => setTimeout(resolve, ms)) } +/** + * Get styles from document.styleSheets + * + * @param {String} selector + * + * @example className usage + * getElementStyles('.anyClassName') + * + * @example Emotion Classname + * const [className1, className2] = [...screen.getByTestId('aspectRatioBox').classList] + * const styles = getElementStyles(`.${className1}`) + * const pseudoStyles = getElementStyles(`.${className2}:before`) + */ +export function getElementStyles (selector) { + selector = new RegExp(selector) + let styles = [] + let i; let j; const sel = selector + for (i = 0; i < document.styleSheets.length; ++i) { + for (j = 0; j < document.styleSheets[i].cssRules.length; ++j) { + if (sel.test(document.styleSheets[i].cssRules[j].selectorText)) { + // let selectorText = document.styleSheets[i].cssRules[j].selectorText + const cssText = document.styleSheets[i].cssRules[j].style.cssText + styles += cssText + } + } + } + return styles +} + +/** + * Gets the tagname of an element + * @param {HTMLElement} node Element + */ +export const getTagName = (node) => { + if (!(node instanceof HTMLElement)) throw new Error('Expected HTMLElement as argument') + return node.tagName.toLowerCase() +} + export { default as userEvent } from '@testing-library/user-event' export { fireEvent } from '@testing-library/vue' export { From f154c9e5abcb70a5bcd4108a136fb64db5559cf9 Mon Sep 17 00:00:00 2001 From: codebender828 Date: Sat, 4 Jul 2020 09:15:12 +0800 Subject: [PATCH 032/133] test: updated tests for stack --- .../src/CButton/CButton.stories.js | 2 +- packages/chakra-ui-core/src/CStack/CStack.js | 84 +++--- .../src/CStack/tests/CStack.test.js | 68 +++++ .../tests/__snapshots__/CStack.test.js.snap | 253 ++++++++++++++++++ .../chakra-ui-core/src/utils/components.js | 4 + 5 files changed, 376 insertions(+), 35 deletions(-) create mode 100644 packages/chakra-ui-core/src/CStack/tests/CStack.test.js create mode 100644 packages/chakra-ui-core/src/CStack/tests/__snapshots__/CStack.test.js.snap diff --git a/packages/chakra-ui-core/src/CButton/CButton.stories.js b/packages/chakra-ui-core/src/CButton/CButton.stories.js index e92a551d..231c8561 100644 --- a/packages/chakra-ui-core/src/CButton/CButton.stories.js +++ b/packages/chakra-ui-core/src/CButton/CButton.stories.js @@ -7,7 +7,7 @@ storiesOf('UI | Button', module) components: { CButton }, template: `
- + New button
`, diff --git a/packages/chakra-ui-core/src/CStack/CStack.js b/packages/chakra-ui-core/src/CStack/CStack.js index 0714b2ec..1880270c 100644 --- a/packages/chakra-ui-core/src/CStack/CStack.js +++ b/packages/chakra-ui-core/src/CStack/CStack.js @@ -8,9 +8,8 @@ * @see Source https://github.com/chakra-ui/chakra-ui-vue/blob/master/packages/chakra-ui-core/src/CStack/CStack.js */ -import { baseProps } from '../config/props' import { StringArray, SNA } from '../config/props/props.types' -import { forwardProps, cloneVNode } from '../utils' +import { cloneVNode, createStyledAttrsMixin } from '../utils' import CFlex from '../CFlex' import CBox from '../CBox' @@ -24,7 +23,7 @@ import CBox from '../CBox' * @see Docs https://vue.chakra-ui.com/stack */ const CStack = { - name: 'CStack', + mixins: [createStyledAttrsMixin('CStack')], props: { direction: [String, Array], isInline: { @@ -44,54 +43,73 @@ const CStack = { shouldWrapChildren: { type: Boolean, default: false - }, - ...baseProps + } }, - render (h) { - const _isReversed = this.isReversed || (this.direction && this.direction.endsWith('reverse')) - const _isInline = this.isInline || (this.direction && this.direction.startsWith('row')) - let _direction + computed: { + _isInline () { + return this.isInline || (this.direction && this.direction.startsWith('row')) + }, + _isReversed () { + return this.isReversed || (this.direction && this.direction.endsWith('reverse')) + }, + _direction () { + let _direction - if (_isInline) { - _direction = 'row' - } + if (this._isInline) { + _direction = 'row' + } - if (_isReversed) { - _direction = this.isInline ? 'row-reverse' : 'column-reverse' - } + if (this._isReversed) { + _direction = this.isInline ? 'row-reverse' : 'column-reverse' + } - if (this.direction) { - _direction = this.direction - } + if (this.direction) { + _direction = this.direction + } - if (!_isInline && !_isReversed && !this.direction) { - _direction = 'column' - } + if (!this._isInline && !this._isReversed && !this.direction) { + _direction = 'column' + } + return _direction + } + }, + render (h) { const children = this.$slots.default.filter(e => e.tag) const stackables = children.map((node, index) => { const isLastChild = children.length === index + 1 - const spacingProps = _isInline - ? { [_isReversed ? 'ml' : 'mr']: isLastChild ? null : this.spacing } - : { [_isReversed ? 'mt' : 'mb']: isLastChild ? null : this.spacing } + const spacingProps = this._isInline + ? { [this._isReversed ? 'ml' : 'mr']: isLastChild ? null : this.spacing } + : { [this._isReversed ? 'mt' : 'mb']: isLastChild ? null : this.spacing } + const clone = cloneVNode(node, h) const { propsData } = clone.componentOptions + const { attrs } = clone.data - // If children nodes should wrap, we wrap them inside block with + // If children nodes should wrap, + // we wrap them inside block with // display set to inline block. if (this.shouldWrapChildren) { return h(CBox, { props: { + as: this.as, + to: this.to + }, + attrs: { d: 'inline-block', - ...spacingProps, - ...forwardProps(this.$props) + ...this.computedAttrs } }, [clone]) } - // Otherwise we simply set spacing props to current node. + // Otherwise we simply set spacing props + // to current node. clone.componentOptions.propsData = { - ...propsData, + ...propsData + } + + clone.data.attrs = { + ...attrs, ...spacingProps } @@ -100,14 +118,12 @@ const CStack = { return h(CFlex, { props: { + as: this.as, align: this.align, justify: this.justify, - direction: _direction, - ...forwardProps(this.$props) + direction: this._direction }, - attrs: { - 'data-chakra-component': 'CStack' - } + attrs: this.computedAttrs }, stackables) } } diff --git a/packages/chakra-ui-core/src/CStack/tests/CStack.test.js b/packages/chakra-ui-core/src/CStack/tests/CStack.test.js new file mode 100644 index 00000000..8d757146 --- /dev/null +++ b/packages/chakra-ui-core/src/CStack/tests/CStack.test.js @@ -0,0 +1,68 @@ +import serializer from 'jest-emotion' +import { CStack, CBox, CHeading, CText } from '../..' +import { render, getTagName } from '@/tests/test-utils' +expect.addSnapshotSerializer(serializer) + +const renderComponent = (props) => { + const inlineAttrs = (props && props.inlineAttrs) || '' + const base = { + components: { CStack, CBox, CHeading, CText }, + template: ` + + + Plan Money + The future can be even brighter but a goal without a plan is just a wish + + + Save Money + You deserve good things. With a whooping 10-15% interest rate per annum, grow your savings on your own terms with our completely automated process + + `, + ...props + } + return render(base) +} + +it('should render correctly', () => { + const { asFragment } = renderComponent() + expect(asFragment()).toMatchSnapshot() +}) + +it('should default to vertical stack', () => { + const { getByTestId } = renderComponent() + const stack = getByTestId('stack') + expect(stack).toHaveStyle('display: flex') + expect(stack).toHaveStyle('flex-direction: column') +}) + +it('should not space last child', () => { + const { getByTestId } = renderComponent() + const stack = getByTestId('stack') + expect(stack).not.toHaveStyle('margin-bottom: 0.5rem') +}) + +it('should should stack horizontally if isInline', () => { + const inlineAttrs = 'is-inline' + const { getByTestId } = renderComponent({ inlineAttrs }) + const stack = getByTestId('stack') + expect(stack).toHaveStyle('display: flex') + expect(stack).toHaveStyle('flex-direction: row') +}) + +// Cannot use `it.each` because it cannot accept +// component as interpolated variable + +it.each` + as + ${'section'} + ${'nav'}} +`( + 'should render CStack with element as $as', + ({ as }) => { + const inlineAttrs = `as="${as}"` + const { asFragment, getByTestId } = renderComponent({ inlineAttrs }) + const stack = getByTestId('stack') + expect(getTagName(stack)).toEqual(as) + expect(asFragment()).toMatchSnapshot() + } +) diff --git a/packages/chakra-ui-core/src/CStack/tests/__snapshots__/CStack.test.js.snap b/packages/chakra-ui-core/src/CStack/tests/__snapshots__/CStack.test.js.snap new file mode 100644 index 00000000..2a97bc5f --- /dev/null +++ b/packages/chakra-ui-core/src/CStack/tests/__snapshots__/CStack.test.js.snap @@ -0,0 +1,253 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render CStack with element as nav 1`] = ` + + .emotion-6 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; +} + +.emotion-2 { + padding: 1.25rem; + box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06); + border-width: 1px; + margin-bottom: 0.5rem; +} + +.emotion-0 { + font-size: 1.25rem; + line-height: 1.25; + font-weight: 700; + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; +} + +.emotion-1 { + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; + margin-top: 1rem; +} + +.emotion-5 { + padding: 1.25rem; + box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06); + border-width: 1px; +} + + + +`; + +exports[`should render CStack with element as section 1`] = ` + + .emotion-6 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; +} + +.emotion-2 { + padding: 1.25rem; + box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06); + border-width: 1px; + margin-bottom: 0.5rem; +} + +.emotion-0 { + font-size: 1.25rem; + line-height: 1.25; + font-weight: 700; + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; +} + +.emotion-1 { + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; + margin-top: 1rem; +} + +.emotion-5 { + padding: 1.25rem; + box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06); + border-width: 1px; +} + +
+
+

+ Plan Money +

+ +

+ The future can be even brighter but a goal without a plan is just a wish +

+
+
+

+ Save Money +

+ +

+ You deserve good things. With a whooping 10-15% interest rate per annum, grow your savings on your own terms with our completely automated process +

+
+
+
+`; + +exports[`should render correctly 1`] = ` + + .emotion-6 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; +} + +.emotion-2 { + padding: 1.25rem; + box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06); + border-width: 1px; + margin-bottom: 0.5rem; +} + +.emotion-0 { + font-size: 1.25rem; + line-height: 1.25; + font-weight: 700; + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; +} + +.emotion-1 { + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; + margin-top: 1rem; +} + +.emotion-5 { + padding: 1.25rem; + box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06); + border-width: 1px; +} + +
+
+

+ Plan Money +

+ +

+ The future can be even brighter but a goal without a plan is just a wish +

+
+
+

+ Save Money +

+ +

+ You deserve good things. With a whooping 10-15% interest rate per annum, grow your savings on your own terms with our completely automated process +

+
+
+
+`; diff --git a/packages/chakra-ui-core/src/utils/components.js b/packages/chakra-ui-core/src/utils/components.js index 6f0997f7..a31b7b45 100644 --- a/packages/chakra-ui-core/src/utils/components.js +++ b/packages/chakra-ui-core/src/utils/components.js @@ -46,6 +46,10 @@ export const createStyledAttrsMixin = (name, isPseudo) => ({ listeners$: {} } }, + props: { + as: [String, Object], + to: String + }, computed: { colorMode () { return this.$chakraColorMode() From 9712014af832e0daa0417dc248c493a36b10fa3b Mon Sep 17 00:00:00 2001 From: codebender828 Date: Sat, 4 Jul 2020 09:19:05 +0800 Subject: [PATCH 033/133] test(badge): update badge tests --- .../tests/__snapshots__/CBadge.test.js.snap | 92 +++++++++++++++++-- 1 file changed, 84 insertions(+), 8 deletions(-) diff --git a/packages/chakra-ui-core/src/CBadge/tests/__snapshots__/CBadge.test.js.snap b/packages/chakra-ui-core/src/CBadge/tests/__snapshots__/CBadge.test.js.snap index 146ebb25..5222de15 100644 --- a/packages/chakra-ui-core/src/CBadge/tests/__snapshots__/CBadge.test.js.snap +++ b/packages/chakra-ui-core/src/CBadge/tests/__snapshots__/CBadge.test.js.snap @@ -2,24 +2,85 @@ exports[`should apply variant styles corectly 1`] = ` -
Subtle
Solid
Outline @@ -30,8 +91,23 @@ exports[`should apply variant styles corectly 1`] = ` exports[`should render correctly 1`] = ` -
500 From bba1930a2d2550ec65797f13e97903afcdc33de3 Mon Sep 17 00:00:00 2001 From: codebender828 Date: Sat, 4 Jul 2020 12:43:38 +0800 Subject: [PATCH 034/133] refactor(iconbutton): change to functional component --- .../src/CBadge/tests/CBadge.test.js | 1 - .../chakra-ui-core/src/CButton/CButton.js | 10 +- .../tests/__snapshots__/CButton.test.js.snap | 269 +++++++++++++++++- .../src/CDivider/tests/CDivider.test.js | 11 +- .../tests/__snapshots__/CDivider.test.js.snap | 51 +++- .../src/CIconButton/CIconButton.js | 39 ++- .../src/CIconButton/CIconButton.stories.js | 10 +- .../src/CIconButton/tests/CIconButton.test.js | 21 +- .../__snapshots__/CIconButton.test.js.snap | 240 +++++++++++++++- .../chakra-ui-core/src/utils/components.js | 4 +- packages/chakra-ui-core/src/utils/vdom.js | 40 +++ 11 files changed, 653 insertions(+), 43 deletions(-) diff --git a/packages/chakra-ui-core/src/CBadge/tests/CBadge.test.js b/packages/chakra-ui-core/src/CBadge/tests/CBadge.test.js index eb1f01af..29194ed5 100644 --- a/packages/chakra-ui-core/src/CBadge/tests/CBadge.test.js +++ b/packages/chakra-ui-core/src/CBadge/tests/CBadge.test.js @@ -17,7 +17,6 @@ it('should render correctly', () => { it('should display children', () => { const { getByText } = renderComponent() - expect(getByText('500')).toBeInTheDocument() }) diff --git a/packages/chakra-ui-core/src/CButton/CButton.js b/packages/chakra-ui-core/src/CButton/CButton.js index 25acc8c4..dab36c6f 100644 --- a/packages/chakra-ui-core/src/CButton/CButton.js +++ b/packages/chakra-ui-core/src/CButton/CButton.js @@ -100,7 +100,15 @@ const CButton = { render (h) { return h(this.as, { class: this.className, - attrs: this.computedAttrs, + attrs: { + type: this.type, + tabIndex: 0, + disabled: this.isDisabled || this.isLoading, + 'aria-disabled': this.isDisabled || this.isLoading, + dataActive: this.isActive ? 'true' : undefined, + 'data-chakra-component': 'CButton', + ...this.computedAttrs + }, on: { click: $event => this.$emit('click', $event) } diff --git a/packages/chakra-ui-core/src/CButton/tests/__snapshots__/CButton.test.js.snap b/packages/chakra-ui-core/src/CButton/tests/__snapshots__/CButton.test.js.snap index a4e58c46..7b6712d8 100644 --- a/packages/chakra-ui-core/src/CButton/tests/__snapshots__/CButton.test.js.snap +++ b/packages/chakra-ui-core/src/CButton/tests/__snapshots__/CButton.test.js.snap @@ -2,15 +2,109 @@ exports[`should display button with left icon 1`] = ` - + +
+
+`; + exports[`should render correctly 1`] = ` -
From 7b3d85f8a8fcc7829d2e98f9cefa001c09dcae14 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Mon, 6 Jul 2020 23:23:14 +0300 Subject: [PATCH 059/133] test(checkbox-group): refactor CheckboxGroup tests --- .../tests/CCheckboxGroup.test.js | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/chakra-ui-core/src/CCheckboxGroup/tests/CCheckboxGroup.test.js b/packages/chakra-ui-core/src/CCheckboxGroup/tests/CCheckboxGroup.test.js index 522f3f16..71549b95 100644 --- a/packages/chakra-ui-core/src/CCheckboxGroup/tests/CCheckboxGroup.test.js +++ b/packages/chakra-ui-core/src/CCheckboxGroup/tests/CCheckboxGroup.test.js @@ -1,5 +1,5 @@ import { CBox, CCheckbox, CCheckboxGroup } from '../..' -import { render } from '@/tests/test-utils' +import { render, screen, wait } from '@/tests/test-utils' // mocks import { useId } from '@/packages/chakra-ui-core/src/utils' @@ -33,20 +33,18 @@ it('should render correctly', () => { }) it('should display children', () => { - const { getByText } = renderComponent() - expect(getByText('One')).toBeInTheDocument() - expect(getByText('Two')).toBeInTheDocument() - expect(getByText('Three')).toBeInTheDocument() + renderComponent() + expect(screen.getByText('One')).toBeInTheDocument() + expect(screen.getByText('Two')).toBeInTheDocument() + expect(screen.getByText('Three')).toBeInTheDocument() }) test('selectedValues prop works', () => { - const { getByTestId } = renderComponent() + renderComponent() - const one = getByTestId('one').querySelector('input') - const two = getByTestId('two').querySelector('input') - const three = getByTestId('three').querySelector('input') - - expect(one).not.toBeChecked() - expect(two).toBeChecked() - expect(three).not.toBeChecked() + wait(() => { + expect(screen.getByLabelText('One')).not.toBeChecked() + expect(screen.getByLabelText('Two')).toBeChecked() + expect(screen.getByLabelText('Three')).not.toBeChecked() + }) }) From d14721cddaa4af8b4b0886cb90b955e6f13d7357 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Mon, 6 Jul 2020 23:25:41 +0300 Subject: [PATCH 060/133] test(circular-progress): refactor circular progress --- .../tests/CCircularProgress.test.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/chakra-ui-core/src/CCircularProgress/tests/CCircularProgress.test.js b/packages/chakra-ui-core/src/CCircularProgress/tests/CCircularProgress.test.js index f8007f41..280c0c3c 100644 --- a/packages/chakra-ui-core/src/CCircularProgress/tests/CCircularProgress.test.js +++ b/packages/chakra-ui-core/src/CCircularProgress/tests/CCircularProgress.test.js @@ -1,5 +1,5 @@ import { CCircularProgress, CCircularProgressLabel } from '../..' -import { render } from '@/tests/test-utils' +import { render, screen } from '@/tests/test-utils' const renderComponent = (props) => { const base = { @@ -20,26 +20,26 @@ it('should render correctly', () => { }) it('should display a label', () => { - const { queryByText } = renderComponent({ + renderComponent({ template: ` 40% ` }) - expect(queryByText('40%')).toBeInTheDocument() + expect(screen.getByText('40%')).toBeInTheDocument() }) test('a11y - progress has a "role" set to "progressbar"', () => { - const { queryByRole } = renderComponent() + renderComponent() - expect(queryByRole('progressbar')).toBeInTheDocument() + expect(screen.queryByRole('progressbar')).toBeInTheDocument() }) test('a11y - progress has a "aria-valuenow" set to the percentage completion value', () => { - const { queryByTestId } = renderComponent() + renderComponent() - expect(queryByTestId('CircularProgress')).toHaveAttribute( + expect(screen.queryByTestId('CircularProgress')).toHaveAttribute( 'aria-valuenow', '40' ) From a77f8f3ba20293351c5ab994204e27d3544ea6e9 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Mon, 6 Jul 2020 23:31:29 +0300 Subject: [PATCH 061/133] test(close-button): refactor close button tests --- .../src/CCloseButton/tests/CloseButton.test.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/chakra-ui-core/src/CCloseButton/tests/CloseButton.test.js b/packages/chakra-ui-core/src/CCloseButton/tests/CloseButton.test.js index 836800b2..65961321 100644 --- a/packages/chakra-ui-core/src/CCloseButton/tests/CloseButton.test.js +++ b/packages/chakra-ui-core/src/CCloseButton/tests/CloseButton.test.js @@ -1,5 +1,5 @@ import CloseButton from '../' -import { render } from '@/tests/test-utils' +import { render, screen } from '@/tests/test-utils' const renderComponent = (props) => { const base = { @@ -14,18 +14,18 @@ it('should render correctly', () => { expect(asFragment()).toMatchSnapshot() }) it('should allow setting a custom aria-label for the button', () => { - const { container } = renderComponent({ template: '' }) + renderComponent({ template: '' }) - expect(container.querySelector('button')).toHaveAttribute( + expect(screen.getByLabelText('my aria label')).toHaveAttribute( 'aria-label', 'my aria label' ) }) test('a11y - should have aria-label set to "Close"', () => { - const { container } = renderComponent() + renderComponent() - expect(container.querySelector('button')).toHaveAttribute( + expect(screen.getByLabelText('Close')).toHaveAttribute( 'aria-label', 'Close' ) From 725f822a297711cfbe0cb35c62d6a302f8faa12f Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Mon, 6 Jul 2020 23:32:35 +0300 Subject: [PATCH 062/133] test(code): refactor to screen --- packages/chakra-ui-core/src/CCode/tests/CCode.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/chakra-ui-core/src/CCode/tests/CCode.test.js b/packages/chakra-ui-core/src/CCode/tests/CCode.test.js index d7151b2d..ffe67e55 100644 --- a/packages/chakra-ui-core/src/CCode/tests/CCode.test.js +++ b/packages/chakra-ui-core/src/CCode/tests/CCode.test.js @@ -1,5 +1,5 @@ import CCode from '..' -import { render } from '@/tests/test-utils' +import { render, screen } from '@/tests/test-utils' const renderComponent = (props) => { const base = { @@ -16,7 +16,7 @@ it('should render correctly', () => { }) it('should display children', () => { - const { getByText } = renderComponent() + renderComponent() - expect(getByText('content')).toBeInTheDocument() + expect(screen.getByText('content')).toBeInTheDocument() }) From 1af9a078aa8474a0911126bf58b3fb017c86b54c Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Mon, 6 Jul 2020 23:34:19 +0300 Subject: [PATCH 063/133] test(controlbox): refactor use screen --- .../src/CControlBox/tests/CControlBox.test.js | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/chakra-ui-core/src/CControlBox/tests/CControlBox.test.js b/packages/chakra-ui-core/src/CControlBox/tests/CControlBox.test.js index 9e375198..1fd25dc1 100644 --- a/packages/chakra-ui-core/src/CControlBox/tests/CControlBox.test.js +++ b/packages/chakra-ui-core/src/CControlBox/tests/CControlBox.test.js @@ -1,5 +1,5 @@ import { CVisuallyHidden, CControlBox, CBox } from '../..' -import { render, userEvent } from '@/tests/test-utils' +import { render, userEvent, screen } from '@/tests/test-utils' const renderComponent = (props) => { const inlineAttrs = (props && props.inlineAttrs) || '' @@ -43,9 +43,9 @@ it('should render correctly', () => { }) test('Uncontrolled radio - should be checked always', async () => { - const { getByTestId } = renderComponent({ type: 'radio' }) - const control = getByTestId('control') - const hiddenControl = getByTestId('hiddenControl') + renderComponent({ type: 'radio' }) + const control = screen.getByTestId('control') + const hiddenControl = screen.getByTestId('hiddenControl') // click the first time, it's checked await userEvent.click(control) @@ -57,9 +57,9 @@ test('Uncontrolled radio - should be checked always', async () => { }) test('Uncontrolled checkbox - should toggle', async () => { - const { getByTestId } = renderComponent({ type: 'checkbox' }) - const control = getByTestId('control') - const hiddenControl = getByTestId('hiddenControl') + renderComponent({ type: 'checkbox' }) + const control = screen.getByTestId('control') + const hiddenControl = screen.getByTestId('hiddenControl') // click the first time, it's checked await userEvent.click(control) @@ -72,9 +72,9 @@ test('Uncontrolled checkbox - should toggle', async () => { test('controlled checkbox - v-model works', async () => { const inlineAttrs = ':checked="checked"' - const { getByTestId } = renderComponent({ inlineAttrs, type: 'checkbox', data: () => ({ checked: true }) }) - const control = getByTestId('control') - const hiddenControl = getByTestId('hiddenControl') + renderComponent({ inlineAttrs, type: 'checkbox', data: () => ({ checked: true }) }) + const control = screen.getByTestId('control') + const hiddenControl = screen.getByTestId('hiddenControl') // click the first time, it's checked expect(hiddenControl).toBeChecked() @@ -86,9 +86,9 @@ test('controlled checkbox - v-model works', async () => { test('controlled radio - v-model works', async () => { const inlineAttrs = ':checked="checked"' - const { getByTestId } = renderComponent({ inlineAttrs, type: 'radio', data: () => ({ checked: true }) }) - const control = getByTestId('control') - const hiddenControl = getByTestId('hiddenControl') + renderComponent({ inlineAttrs, type: 'radio', data: () => ({ checked: true }) }) + const control = screen.getByTestId('control') + const hiddenControl = screen.getByTestId('hiddenControl') // click the first time, it's checked expect(hiddenControl).toBeChecked() From 3aa7a15add043850ee97aa9d9c1035bc1735875f Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Tue, 7 Jul 2020 00:07:17 +0300 Subject: [PATCH 064/133] test(drawer): refactor drawer tests --- .../src/CDrawer/tests/CDrawer.test.js | 72 ++++++++++--------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/packages/chakra-ui-core/src/CDrawer/tests/CDrawer.test.js b/packages/chakra-ui-core/src/CDrawer/tests/CDrawer.test.js index 01d397c8..0087ba68 100644 --- a/packages/chakra-ui-core/src/CDrawer/tests/CDrawer.test.js +++ b/packages/chakra-ui-core/src/CDrawer/tests/CDrawer.test.js @@ -1,6 +1,5 @@ -import Vue from 'vue' import { CInput, CButton, CDrawer, CDrawerBody, CDrawerFooter, CDrawerHeader, CDrawerOverlay, CDrawerContent, CDrawerCloseButton } from '../../' -import { render, userEvent, fireEvent, waitMs } from '@/tests/test-utils' +import { render, userEvent, fireEvent, waitMs, wait, screen } from '@/tests/test-utils' import { useId } from '@/packages/chakra-ui-core/src/utils' // mocks @@ -49,7 +48,7 @@ it('should render correctly', async () => { const inlineAttrs = 'isOpen' const { asFragment } = renderComponent({ inlineAttrs }) - await Vue.nextTick() + await waitMs() // render expect(asFragment(document.body.innerHTML)).toMatchSnapshot() }) @@ -57,10 +56,11 @@ it('should render correctly', async () => { test('clicking the close button calls the onClose callback', async () => { const onClose = jest.fn() const inlineAttrs = 'isOpen :on-close="close"' - const { getByTestId } = renderComponent({ inlineAttrs, methods: { close: onClose } }) + renderComponent({ inlineAttrs, methods: { close: onClose } }) - await Vue.nextTick() - userEvent.click(getByTestId('close-btn')) + await wait(() => { + userEvent.click(screen.getByTestId('close-btn')) + }) expect(onClose).toHaveBeenCalled() }) @@ -68,12 +68,12 @@ test('clicking the close button calls the onClose callback', async () => { test('pressing "esc" calls the onClose callback', async () => { const onClose = jest.fn() const inlineAttrs = ':isOpen="isOpen" :on-close="close"' - const { getByTestId } = renderComponent({ inlineAttrs, data: () => ({ isOpen: true }), methods: { close: onClose } }) + renderComponent({ inlineAttrs, data: () => ({ isOpen: true }), methods: { close: onClose } }) - await Vue.nextTick() - const inputInside = getByTestId('inputInsideDrawer') - - fireEvent.keyDown(inputInside, { key: 'Escape' }) + await wait(async () => { + const inputInside = screen.getByTestId('inputInsideDrawer') + await fireEvent.keyDown(inputInside, { key: 'Escape' }) + }) expect(onClose).toHaveBeenCalled() }) @@ -81,39 +81,41 @@ test('pressing "esc" calls the onClose callback', async () => { test('clicking overlay calls the onClose callback', async () => { const onClose = jest.fn() const inlineAttrs = ':isOpen="isOpen" :on-close="close"' - const { getByTestId } = renderComponent({ inlineAttrs, data: () => ({ isOpen: true }), methods: { close: onClose } }) - - await Vue.nextTick() - const overlay = getByTestId('overlay') + renderComponent({ inlineAttrs, data: () => ({ isOpen: true }), methods: { close: onClose } }) - userEvent.click(overlay) + await wait(async () => { + const overlay = screen.getByTestId('overlay') + await fireEvent.click(overlay) + }) expect(onClose).toHaveBeenCalled() }) test('focuses the initial focus ref when opened - initialFocusRef', async () => { const inlineAttrs = 'isOpen :on-close="close" :initialFocusRef="()=>$refs.inputInsideDrawer"' - const { getByTestId } = renderComponent({ inlineAttrs }) + renderComponent({ inlineAttrs }) - await Vue.nextTick() - const inputInside = getByTestId('inputInsideDrawer') + await waitMs() // render - await waitMs() - expect(inputInside).toHaveFocus() + await wait(() => { + expect(screen.getByTestId('inputInsideDrawer')).toHaveFocus() + }) }) test('returns focus when closed - finalFocusRef', async () => { const inlineAttrs = ':isOpen="isOpen" :on-close="close" :finalFocusRef="$refs.inputOutsideDrawer"' - const { getByTestId } = renderComponent({ inlineAttrs, data: () => ({ isOpen: true }) }) + renderComponent({ inlineAttrs, data: () => ({ isOpen: true }) }) + + await waitMs() // render - await Vue.nextTick() - const inputOutside = getByTestId('inputOutsideDrawer') - const closeButton = getByTestId('close-btn') + const inputOutside = screen.getByTestId('inputOutsideDrawer') + const closeButton = screen.getByTestId('close-btn') - await userEvent.click(closeButton) - await waitMs() + await fireEvent.click(closeButton) - expect(inputOutside).toHaveFocus() + await wait(() => { + expect(inputOutside).toHaveFocus() + }) }) it('should have proper aria', async () => { @@ -121,12 +123,12 @@ it('should have proper aria', async () => { const inlineAttrs = 'isOpen' renderComponent({ inlineAttrs }) - await Vue.nextTick() - const dialog = document.querySelector('section') - await waitMs() + await wait(() => { + const dialog = screen.getByRole('dialog') - expect(dialog).toHaveAttribute('role', 'dialog') - expect(dialog).toHaveAttribute('aria-modal', 'true') - expect(dialog).toHaveAttribute('aria-labelledby', 'drawer-1-header') - expect(dialog).toHaveAttribute('aria-describedby', 'drawer-1-body') + expect(dialog).toHaveAttribute('role', 'dialog') + expect(dialog).toHaveAttribute('aria-modal', 'true') + expect(dialog).toHaveAttribute('aria-labelledby', 'drawer-1-header') + expect(dialog).toHaveAttribute('aria-describedby', 'drawer-1-body') + }) }) From 470ec732f537316a6a93ea22deb769f2577b8fd0 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Tue, 7 Jul 2020 00:45:35 +0300 Subject: [PATCH 065/133] test(editable): refactor use screen --- .../src/CEditable/tests/CEditable.test.js | 57 ++++++++++--------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/packages/chakra-ui-core/src/CEditable/tests/CEditable.test.js b/packages/chakra-ui-core/src/CEditable/tests/CEditable.test.js index 0cd18dc7..550f653e 100644 --- a/packages/chakra-ui-core/src/CEditable/tests/CEditable.test.js +++ b/packages/chakra-ui-core/src/CEditable/tests/CEditable.test.js @@ -1,6 +1,6 @@ import { CEditable, CEditableInput, CEditablePreview } from '../..' import { useId } from '../../utils' -import { render, userEvent, fireEvent } from '@/tests/test-utils' +import { render, userEvent, fireEvent, screen } from '@/tests/test-utils' // mocks jest.mock('@/packages/chakra-ui-core/src/utils/generators.js') @@ -29,9 +29,9 @@ it('should render correctly', () => { it('should render correctly - input', async () => { useId.mockReturnValueOnce('1') const inlineAttrs = 'defaultValue="testing" ' - const { asFragment, getByTestId } = renderComponent({ inlineAttrs }) + const { asFragment } = renderComponent({ inlineAttrs }) - const preview = getByTestId('preview') + const preview = screen.getByTestId('preview') await userEvent.click(preview) expect(asFragment(document.body.innerHTML)).toMatchSnapshot() @@ -44,82 +44,87 @@ it('uncontrolled: handles callbacks correctly', async () => { const onEdit = jest.fn() const inlineAttrs = '@edit="onEdit" @change="onChange" @cancel="onCancel" @submit="onSubmit" defaultValue="Hello "' - const { getByTestId } = renderComponent({ inlineAttrs, methods: { onChange, onCancel, onSubmit, onEdit } }) + renderComponent({ inlineAttrs, methods: { onChange, onCancel, onSubmit, onEdit } }) - const preview = getByTestId('preview') + const preview = screen.getByTestId('preview') await userEvent.click(preview) - const input = getByTestId('input') + const input = screen.getByTestId('input') // calls `onEdit` when preview is focused - fireEvent.focus(preview) + await fireEvent.focus(preview) expect(onEdit).toHaveBeenCalled() // calls `onChange` with input on change - userEvent.type(input, 'World') + await userEvent.type(input, 'World') expect(onChange).toHaveBeenCalledWith('Hello World') // calls `onCancel` with previous value when "esc" pressed - fireEvent.keyDown(input, { key: 'Escape' }) + await fireEvent.keyDown(input, { key: 'Escape' }) expect(onCancel).toHaveBeenCalledWith('Hello ') // calls `onSubmit` with previous value when "enter" pressed after cancelling - fireEvent.keyDown(input, { key: 'Enter' }) + await fireEvent.keyDown(input, { key: 'Enter' }) expect(onSubmit).toHaveBeenCalledWith('Hello ') // TODO: ⚠️ we should make controlledInput for vue + // we didn't change the v-model but input.value changes // remove this line, previous input value stays and next 2 expect fails input.value = 'Hello ' // returns new value when submitting without cancelling - userEvent.type(input, 'World') - fireEvent.keyDown(input, { key: 'Enter' }) + await userEvent.type(input, 'World') + await fireEvent.keyDown(input, { key: 'Enter' }) expect(onSubmit).toHaveBeenCalledWith('Hello World') // cancelling now returns new value - fireEvent.keyDown(input, { key: 'Escape' }) + await fireEvent.keyDown(input, { key: 'Escape' }) expect(onCancel).toHaveBeenCalledWith('Hello ') }) it('controlled: handles callbacks correctly', async () => { + useId.mockReturnValueOnce('1') const onChange = jest.fn() const onCancel = jest.fn() const onSubmit = jest.fn() const onEdit = jest.fn() const inlineAttrs = '@edit="onEdit" @change="onChange" @cancel="onCancel" @submit="onSubmit" defaultValue="Hello "' - const { getByTestId } = renderComponent({ inlineAttrs, methods: { onChange, onCancel, onSubmit, onEdit } }) + renderComponent({ inlineAttrs, methods: { onChange, onCancel, onSubmit, onEdit } }) - const preview = getByTestId('preview') + const preview = screen.getByTestId('preview') - await userEvent.click(preview) - const input = getByTestId('input') + await fireEvent.touch(preview) + const input = screen.getByTestId('input') // calls `onEdit` when preview is focused - fireEvent.focus(preview) + await fireEvent.focus(preview) expect(onEdit).toHaveBeenCalled() // calls `onSubmit` with `value` - fireEvent.keyDown(input, { key: 'Enter' }) + await fireEvent.keyDown(input, { key: 'Enter' }) expect(onSubmit).toHaveBeenCalledWith('Hello ') // calls `onCancel` with `value` - fireEvent.keyDown(input, { key: 'Escape' }) + await fireEvent.keyDown(input, { key: 'Escape' }) expect(onSubmit).toHaveBeenCalledWith('Hello ') // calls `onChange` with new input on change - userEvent.type(input, 'World') + // await fireEvent.update(input, 'Hello World') // changes all value + await userEvent.type(input, 'World') // continues typing with previous value + + await fireEvent.keyDown(input, { key: 'Escape' }) expect(onChange).toHaveBeenCalledWith('Hello World') }) test('has the proper aria attributes', async () => { const inlineAttrs = 'defaultValue=""' - const { getByTestId } = renderComponent({ inlineAttrs }) + renderComponent({ inlineAttrs }) - const preview = getByTestId('preview') + const preview = screen.getByTestId('preview') await userEvent.click(preview) - const input = getByTestId('input') + const input = screen.getByTestId('input') // preview and input do not have aria-disabled when `CEditable` is not disabled expect(preview).not.toHaveAttribute('aria-disabled') @@ -128,9 +133,9 @@ test('has the proper aria attributes', async () => { test('has the proper aria attributes when disabled', () => { const inlineAttrs = 'isDisabled defaultValue=""' - const { getByTestId } = renderComponent({ inlineAttrs }) + renderComponent({ inlineAttrs }) - const preview = getByTestId('preview') + const preview = screen.getByTestId('preview') // preview does not have aria-disabled when `CEditable` is not disabled expect(preview).toHaveAttribute('aria-disabled', 'true') From 5edf979a452cf39e6a819904cacd07e784e53ce3 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Tue, 7 Jul 2020 00:46:34 +0300 Subject: [PATCH 066/133] test(flex): refactor use screen --- packages/chakra-ui-core/src/CFlex/tests/CFlex.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/chakra-ui-core/src/CFlex/tests/CFlex.test.js b/packages/chakra-ui-core/src/CFlex/tests/CFlex.test.js index 6dfb2495..e5abcb5b 100644 --- a/packages/chakra-ui-core/src/CFlex/tests/CFlex.test.js +++ b/packages/chakra-ui-core/src/CFlex/tests/CFlex.test.js @@ -1,5 +1,5 @@ import CFlex from '..' -import { render } from '@/tests/test-utils' +import { render, screen } from '@/tests/test-utils' const renderComponent = (props) => { const inlineAttrs = (props && props.inlineAttrs) || '' @@ -19,11 +19,11 @@ it('should render correctly', () => { it('should change styles', () => { const inlineAttrs = 'align="center" justify="center" direction="column"' - const { asFragment, getByTestId } = renderComponent({ inlineAttrs }) + const { asFragment } = renderComponent({ inlineAttrs }) expect(asFragment()).toMatchSnapshot() - const flex = getByTestId('flex') + const flex = screen.getByTestId('flex') expect(flex).toHaveStyle('display: flex') expect(flex).toHaveStyle('align-items: center') expect(flex).toHaveStyle('justify-content: center') From 70e9ae2c4760bde4ef0b77fc7af866507f19c788 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Tue, 7 Jul 2020 00:59:33 +0300 Subject: [PATCH 067/133] test(icon-button): refactor use screen --- .../src/CIconButton/tests/CIconButton.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/chakra-ui-core/src/CIconButton/tests/CIconButton.test.js b/packages/chakra-ui-core/src/CIconButton/tests/CIconButton.test.js index 53ea5187..ab963093 100644 --- a/packages/chakra-ui-core/src/CIconButton/tests/CIconButton.test.js +++ b/packages/chakra-ui-core/src/CIconButton/tests/CIconButton.test.js @@ -1,5 +1,5 @@ import CIconButton from '..' -import { render } from '@/tests/test-utils' +import { render, screen } from '@/tests/test-utils' const renderComponent = (props) => { const inlineAttrs = (props && props.inlineAttrs) || '' @@ -19,15 +19,15 @@ it('should render correctly', () => { it('should display spinner and hide the icon', () => { const inlineAttrs = 'isLoading' - const { container, getByTestId } = renderComponent({ inlineAttrs }) + const { container } = renderComponent({ inlineAttrs }) - const button = getByTestId('btn') + const button = screen.getByTestId('btn') expect(button).toHaveAttribute('disabled') expect(button).toHaveAttribute('aria-disabled', 'true') // TODO: find a way to easily grab the spinner element - // Maybe? expect(getByTestId('Spinner')).toBeInTheDocument() + // Maybe? expect(screen.getByTestId('Spinner')).toBeInTheDocument() expect(button).toHaveStyle('opacity: 0.4') expect(container.querySelector('button > div')).toBeInTheDocument() }) From 979bb01bfbef59eed68a27bdb1943c75fbe69c35 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Tue, 7 Jul 2020 01:03:39 +0300 Subject: [PATCH 068/133] test(image): add tests for Image component and fix onerror --- packages/chakra-ui-core/src/CImage/CImage.js | 2 +- .../src/CImage/tests/CImage.test.js | 47 +++++++++++++++++++ .../tests/__snapshots__/CImage.test.js.snap | 13 +++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 packages/chakra-ui-core/src/CImage/tests/CImage.test.js create mode 100644 packages/chakra-ui-core/src/CImage/tests/__snapshots__/CImage.test.js.snap diff --git a/packages/chakra-ui-core/src/CImage/CImage.js b/packages/chakra-ui-core/src/CImage/CImage.js index 17c75186..934ac10b 100644 --- a/packages/chakra-ui-core/src/CImage/CImage.js +++ b/packages/chakra-ui-core/src/CImage/CImage.js @@ -55,7 +55,7 @@ const CImage = { this.$emit('load', event) } - image.onError = (event) => { + image.onerror = (event) => { this.hasLoaded = false this.$emit('error', event) } diff --git a/packages/chakra-ui-core/src/CImage/tests/CImage.test.js b/packages/chakra-ui-core/src/CImage/tests/CImage.test.js new file mode 100644 index 00000000..3b6feaff --- /dev/null +++ b/packages/chakra-ui-core/src/CImage/tests/CImage.test.js @@ -0,0 +1,47 @@ +import { CImage } from '../..' +import { render, wait, waitMs, screen } from '@/tests/test-utils' +const LOAD_FAILURE_SRC = 'LOAD_FAILURE_SRC' +const LOAD_SUCCESS_SRC = 'LOAD_SUCCESS_SRC' + +beforeAll(() => { + process.browser = true // Mock process.browser for CAvatar created() +}) + +beforeAll(() => { + // Mock Img + // eslint-disable-next-line accessor-pairs + Object.defineProperty(global.Image.prototype, 'src', { + set (src) { + if (src === LOAD_FAILURE_SRC) { + setTimeout(() => this.onerror(new Error('mocked error'))) + } else if (src === LOAD_SUCCESS_SRC) { + setTimeout(() => this.onload()) + } + } + }) +}) + +const renderComponent = (props) => { + const base = { + components: { CImage }, + template: '', + ...props + } + return render(base) +} + +it('should render correctly', async () => { + const { asFragment } = renderComponent() + + await waitMs() // wait for img.onsuccess to be called. + + expect(asFragment()).toMatchSnapshot() +}) + +it('fallback src works', async () => { + renderComponent({ template: '' }) + + await wait(() => { + expect(screen.getByAltText(/Mesut Koca/i)).toHaveAttribute('src', 'LOAD_FALLBACK_SRC') + }) +}) diff --git a/packages/chakra-ui-core/src/CImage/tests/__snapshots__/CImage.test.js.snap b/packages/chakra-ui-core/src/CImage/tests/__snapshots__/CImage.test.js.snap new file mode 100644 index 00000000..23f8c25b --- /dev/null +++ b/packages/chakra-ui-core/src/CImage/tests/__snapshots__/CImage.test.js.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly 1`] = ` + + Mesut Koca + +`; From e988316e121ceae0c14052b728b298c4be4ec7b2 Mon Sep 17 00:00:00 2001 From: Mesut Koca Date: Tue, 7 Jul 2020 01:24:22 +0300 Subject: [PATCH 069/133] test(input): add tests for input component and fix readonly --- packages/chakra-ui-core/src/CInput/CInput.js | 2 +- .../src/CInput/tests/CInput.test.js | 40 +++++++++++++++++++ .../tests/__snapshots__/CInput.test.js.snap | 12 ++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 packages/chakra-ui-core/src/CInput/tests/CInput.test.js create mode 100644 packages/chakra-ui-core/src/CInput/tests/__snapshots__/CInput.test.js.snap diff --git a/packages/chakra-ui-core/src/CInput/CInput.js b/packages/chakra-ui-core/src/CInput/CInput.js index 24efb167..c1f27eab 100644 --- a/packages/chakra-ui-core/src/CInput/CInput.js +++ b/packages/chakra-ui-core/src/CInput/CInput.js @@ -90,7 +90,7 @@ const CInput = { }, attrs: { 'aria-readonly': this.isReadOnly, - 'read-only': this.formControl.isReadOnly, + readonly: this.formControl.isReadOnly, disabled: this.formControl.isDisabled, 'aria-disabled': this.formControl.isDisabled, 'aria-invalid': this.formControl.isInvalid, diff --git a/packages/chakra-ui-core/src/CInput/tests/CInput.test.js b/packages/chakra-ui-core/src/CInput/tests/CInput.test.js new file mode 100644 index 00000000..31295c19 --- /dev/null +++ b/packages/chakra-ui-core/src/CInput/tests/CInput.test.js @@ -0,0 +1,40 @@ +import { CInput } from '../..' +import { render, screen, userEvent } from '@/tests/test-utils' + +const renderComponent = (props) => { + const inlineAttrs = (props && props.inlineAttrs) || '' + const base = { + data: () => ({ text: 'hello' }), + components: { CInput }, + template: ``, + ...props + } + return render(base) +} + +test('should render correctly', () => { + const { asFragment } = renderComponent() + expect(asFragment()).toMatchSnapshot() +}) + +test('v-model works', () => { + renderComponent() + const input = screen.getByTestId('input') + + userEvent.type(input, ' world') + expect(input).toHaveValue('hello world') +}) + +test('readonly input renders correctly', () => { + renderComponent({ inlineAttrs: 'isReadOnly' }) + const input = screen.getByTestId('input') + + expect(input).toHaveAttribute('readonly') +}) + +test('disabled input renders correctly', () => { + renderComponent({ inlineAttrs: 'isDisabled' }) + const input = screen.getByTestId('input') + + expect(input).toHaveAttribute('disabled') +}) diff --git a/packages/chakra-ui-core/src/CInput/tests/__snapshots__/CInput.test.js.snap b/packages/chakra-ui-core/src/CInput/tests/__snapshots__/CInput.test.js.snap new file mode 100644 index 00000000..bd670d80 --- /dev/null +++ b/packages/chakra-ui-core/src/CInput/tests/__snapshots__/CInput.test.js.snap @@ -0,0 +1,12 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly 1`] = ` + + + +`; From 14d5acdfc849b429c3e93df9a80d4812e189a7b6 Mon Sep 17 00:00:00 2001 From: codebender828 Date: Tue, 7 Jul 2020 11:38:19 +0800 Subject: [PATCH 070/133] refactor(modal): refactor boss level component to a api --- .../src/CCloseButton/CCloseButton.js | 56 +-- .../CCloseButton/utils/closebutton.props.js | 19 + .../CCloseButton/utils/closebutton.styles.js | 33 ++ .../tests/__snapshots__/CCode.test.js.snap | 15 +- .../chakra-ui-core/src/CCollapse/CCollapse.js | 53 ++- .../src/CCollapse/CCollapse.stories.js | 13 +- packages/chakra-ui-core/src/CModal/CModal.js | 232 ++++++----- .../tests/__snapshots__/CModal.test.js.snap | 391 +++++++++++++++++- .../src/CModal/utils/modal.props.js | 4 +- 9 files changed, 613 insertions(+), 203 deletions(-) create mode 100644 packages/chakra-ui-core/src/CCloseButton/utils/closebutton.props.js create mode 100644 packages/chakra-ui-core/src/CCloseButton/utils/closebutton.styles.js diff --git a/packages/chakra-ui-core/src/CCloseButton/CCloseButton.js b/packages/chakra-ui-core/src/CCloseButton/CCloseButton.js index b13c8004..99d28bd2 100644 --- a/packages/chakra-ui-core/src/CCloseButton/CCloseButton.js +++ b/packages/chakra-ui-core/src/CCloseButton/CCloseButton.js @@ -15,40 +15,8 @@ import { extractListeners } from '../utils' import CIcon from '../CIcon' import CPseudoBox from '../CPseudoBox' - -const baseProps = { - display: 'inline-flex', - alignItems: 'center', - justifyContent: 'center', - rounded: 'md', - transition: 'all 0.2s', - flex: '0 0 auto', - _hover: { bg: 'blackAlpha.100' }, - _active: { bg: 'blackAlpha.200' }, - _disabled: { - cursor: 'not-allowed' - }, - _focus: { - boxShadow: 'outline' - }, - border: 'none', - bg: 'blackAlpha.50' -} - -const sizes = { - lg: { - button: '40px', - icon: '16px' - }, - md: { - button: '32px', - icon: '12px' - }, - sm: { - button: '24px', - icon: '10px' - } -} +import props from './utils/closebutton.props' +import { sizes, baseProps } from './utils/closebutton.styles' /** * CCloseButton component @@ -62,25 +30,7 @@ const CCloseButton = { name: 'CCloseButton', functional: true, inject: ['$chakraColorMode'], - props: { - size: { - type: String, - default: 'md', - validator: value => value.match(/^(sm|md|lg)$/) - }, - isDisabled: { - type: Boolean, - default: false - }, - color: { - type: String, - default: 'currentColor' - }, - ariaLabel: { - type: String, - default: 'Close' - } - }, + props, render (h, context) { const { props, data, injections, listeners, ...rest } = context diff --git a/packages/chakra-ui-core/src/CCloseButton/utils/closebutton.props.js b/packages/chakra-ui-core/src/CCloseButton/utils/closebutton.props.js new file mode 100644 index 00000000..0afa1ff8 --- /dev/null +++ b/packages/chakra-ui-core/src/CCloseButton/utils/closebutton.props.js @@ -0,0 +1,19 @@ +export default { + size: { + type: String, + default: 'md', + validator: value => value.match(/^(sm|md|lg)$/) + }, + isDisabled: { + type: Boolean, + default: false + }, + color: { + type: String, + default: 'currentColor' + }, + ariaLabel: { + type: String, + default: 'Close' + } +} diff --git a/packages/chakra-ui-core/src/CCloseButton/utils/closebutton.styles.js b/packages/chakra-ui-core/src/CCloseButton/utils/closebutton.styles.js new file mode 100644 index 00000000..eaaa9a58 --- /dev/null +++ b/packages/chakra-ui-core/src/CCloseButton/utils/closebutton.styles.js @@ -0,0 +1,33 @@ +export const baseProps = { + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + rounded: 'md', + transition: 'all 0.2s', + flex: '0 0 auto', + _hover: { bg: 'blackAlpha.100' }, + _active: { bg: 'blackAlpha.200' }, + _disabled: { + cursor: 'not-allowed' + }, + _focus: { + boxShadow: 'outline' + }, + border: 'none', + bg: 'blackAlpha.50' +} + +export const sizes = { + lg: { + button: '40px', + icon: '16px' + }, + md: { + button: '32px', + icon: '12px' + }, + sm: { + button: '24px', + icon: '10px' + } +} diff --git a/packages/chakra-ui-core/src/CCode/tests/__snapshots__/CCode.test.js.snap b/packages/chakra-ui-core/src/CCode/tests/__snapshots__/CCode.test.js.snap index 040ede46..ea8b89c9 100644 --- a/packages/chakra-ui-core/src/CCode/tests/__snapshots__/CCode.test.js.snap +++ b/packages/chakra-ui-core/src/CCode/tests/__snapshots__/CCode.test.js.snap @@ -2,8 +2,19 @@ exports[`should render correctly 1`] = ` - content diff --git a/packages/chakra-ui-core/src/CCollapse/CCollapse.js b/packages/chakra-ui-core/src/CCollapse/CCollapse.js index cd1f2105..789244d3 100644 --- a/packages/chakra-ui-core/src/CCollapse/CCollapse.js +++ b/packages/chakra-ui-core/src/CCollapse/CCollapse.js @@ -11,6 +11,7 @@ import { CAnimateHeight } from '../CTransition' import CBox from '../CBox' +import { extractListeners } from '../utils' /** * CCollapse component @@ -23,7 +24,7 @@ import CBox from '../CBox' */ const CCollapse = { name: 'Collapse', - inheritAttrs: false, + functional: true, props: { isOpen: Boolean, duration: { @@ -41,32 +42,48 @@ const CCollapse = { default: true } }, - render (h) { - const children = this.$slots.default + render (h, { slots, props, data, listeners, ...rest }) { + // Get children + const children = slots().default + + // Handle events + const nonNativeEvents = { + start: (e) => { + const emitStart = listeners.start + if (emitStart) { + emitStart('start', e) + } + }, + finish: (e) => { + const emitFinish = listeners.finish + if (emitFinish) { + emitFinish('finish', e) + } + } + } + const { native, nonNative } = extractListeners({ listeners }, nonNativeEvents) + return h(CAnimateHeight, { + ...rest, props: { - isOpen: this.isOpen, - duration: this.duration, - enterEasing: this.easing, - leaveEasing: this.easing, - initialHeight: this.startingHeight, - finalHeight: this.endingHeight, - animateOpacity: this.animateOpacity - }, - on: { - enter: e => this.$emit('start', e), - leave: e => this.$emit('finish', e) + isOpen: props.isOpen, + duration: props.duration, + enterEasing: props.easing, + leaveEasing: props.easing, + initialHeight: props.startingHeight, + finalHeight: props.endingHeight, + animateOpacity: props.animateOpacity }, + on: nonNative, + nativeOn: native, attrs: { 'data-chakra-component': 'CCollapse' } }, [h(CBox, { props: { - as: this.as + as: props.as }, - attrs: { - ...this.$attrs - } + attrs: data.attrs }, children)]) } } diff --git a/packages/chakra-ui-core/src/CCollapse/CCollapse.stories.js b/packages/chakra-ui-core/src/CCollapse/CCollapse.stories.js index 2323f0a5..a80f741b 100644 --- a/packages/chakra-ui-core/src/CCollapse/CCollapse.stories.js +++ b/packages/chakra-ui-core/src/CCollapse/CCollapse.stories.js @@ -6,8 +6,8 @@ storiesOf('UI | Collapse', module) components: { CButton, CCollapse, CBox }, template: `
- Collapse - + Collapse + Lorem ipsum dolor sit, amet consectetur adipisicing elit. Vitae officia rem mollitia molestias eveniet, reiciendis perspiciatis minima deleniti iure voluptates laborum vel accusamus enim officiis dolorum necessitatibus, animi perferendis reprehenderit! @@ -18,14 +18,19 @@ storiesOf('UI | Collapse', module) return { showCollapsed: true } + }, + methods: { + handleFinished (e) { + console.log('Collapse complete!', e) + } } })) .add('Changing the startingHeight', () => ({ components: { CButton, CCollapse, CBox }, template: `
- Collapse - + Collapse + Lorem ipsum dolor sit, amet consectetur adipisicing elit. Vitae officia rem mollitia molestias eveniet, reiciendis perspiciatis minima deleniti iure voluptates laborum vel accusamus enim officiis dolorum necessitatibus, animi perferendis reprehenderit! diff --git a/packages/chakra-ui-core/src/CModal/CModal.js b/packages/chakra-ui-core/src/CModal/CModal.js index 6ab341ab..4648aea9 100644 --- a/packages/chakra-ui-core/src/CModal/CModal.js +++ b/packages/chakra-ui-core/src/CModal/CModal.js @@ -13,15 +13,14 @@ import { hideOthers } from 'aria-hidden' import { FocusTrap } from 'focus-trap-vue' import isFunction from 'lodash-es/isFunction' -import { useId, canUseDOM, getElById, isVueComponent, getElement, getFocusables, cleanChildren, forwardProps, wrapEvent } from '../utils' -import { baseProps } from '../config' -import styleProps from '../config/props' +import { useId, canUseDOM, getElById, isVueComponent, getElement, getFocusables, cleanChildren, wrapEvent, createStyledAttrsMixin } from '../utils' import { CFade } from '../CTransition' import CPortal from '../CPortal' import CBox from '../CBox' -import CPseudoBox from '../CPseudoBox' -import CCloseButton from '../CCloseButton' +import CIcon from '../CIcon' +import closeButtonProps from '../CCloseButton/utils/closebutton.props' +import { sizes, baseProps } from '../CCloseButton/utils/closebutton.styles' import props from './utils/modal.props' /** @@ -228,10 +227,8 @@ const CModal = { deactivate: this.deactivateFocusLock } }, [ - h(CPseudoBox, { - props: { - position: 'relative' - }, + h('div', { + style: { position: 'relative' }, directives: [{ name: 'scroll-lock', value: this.isOpen && this.blockScrollOnMount @@ -267,13 +264,11 @@ const CModal = { */ const CModalOverlay = { name: 'CModalOverlay', - props: baseProps, - attrs: { - 'data-chakra-component': 'CModalOverlay' - }, - render (h) { + functional: true, + render (h, { data, ...rest }) { return h(CBox, { - props: { + ...rest, + attrs: { pos: 'fixed', bg: 'rgba(0,0,0,0.4)', left: '0', @@ -281,7 +276,8 @@ const CModalOverlay = { w: '100vw', h: '100vh', zIndex: 'overlay', - ...forwardProps(this.$props) + ...data.attrs, + 'data-chakra-component': 'CModalOverlay' } }) } @@ -296,11 +292,9 @@ const CModalOverlay = { * @see Docs https://vue.chakra-ui.com/modal */ const CModalContent = { - name: 'CModalContent', - inheritAttrs: false, - inject: ['$ModalContext', '$chakraColorMode'], + mixins: [createStyledAttrsMixin('CModalContent')], + inject: ['$ModalContext'], props: { - ...baseProps, noStyles: Boolean, zIndex: { type: String, @@ -325,14 +319,22 @@ const CModalContent = { } }, computed: { - colorMode () { - return this.$chakraColorMode() - }, context () { return this.$ModalContext() }, boxStyleProps () { return this.colorModeStyles[this.colorMode] + }, + componentStyles () { + return { + ...this.wrapperStyle, + pos: 'fixed', + left: '0', + top: '0', + w: '100%', + h: '100%', + zIndex: this.zIndex || 'modal' + } } }, created () { @@ -404,18 +406,10 @@ const CModalContent = { closeOnOverlayClick } = this.context - return h(CBox, { - props: { - ...forwardProps(this.$props), - ...this.wrapperStyle, - pos: 'fixed', - left: '0', - top: '0', - w: '100%', - h: '100%', - zIndex: this.zIndex || 'modal' - }, - nativeOn: { + return h(this.as || 'div', { + class: [this.className], + attrs: this.computedAttrs, + on: { click: (event) => { event.stopPropagation() if (closeOnOverlayClick) { @@ -430,15 +424,21 @@ const CModalContent = { onClose(event, 'pressedEscape') } } - } - }, - attrs: { - 'data-chakra-component': 'CModalContent' + }, + ...this.computedListeners } }, [ h(CBox, { props: { - as: 'section', + as: 'section' + }, + attrs: { + role: 'dialog', + 'aria-modal': 'true', + tabIndex: -1, + id: contentId, + ...(addAriaDescribedby && { 'aria-describedby': bodyId }), + ...(addAriaLabelledby && { 'aria-labelledby': headerId }), outline: 0, maxWidth: size, w: '100%', @@ -448,17 +448,7 @@ const CModalContent = { zIndex: this.zIndex, fontFamily: 'body', ...this.boxStyleProps, - ...this.contentStyle, - ...forwardProps(this.$props) - }, - attrs: { - role: 'dialog', - 'aria-modal': 'true', - tabIndex: -1, - id: contentId, - ...(addAriaDescribedby && { 'aria-describedby': bodyId }), - ...(addAriaLabelledby && { 'aria-labelledby': headerId }), - ...this.$attrs + ...this.contentStyle }, nativeOn: { click: wrapEvent(e => this.$emit('click', e), event => event.stopPropagation()) @@ -477,31 +467,31 @@ const CModalContent = { * @see Docs https://vue.chakra-ui.com/modal */ const CModalHeader = { - name: 'CModalHeader', + mixins: [createStyledAttrsMixin('CModalHeader')], inject: ['$ModalContext'], - props: baseProps, computed: { context () { return this.$ModalContext() - } - }, - render (h) { - const { headerId } = this.context - - return h(CBox, { - props: { - as: 'header', + }, + componentStyles () { + return { px: 6, py: 4, position: 'relative', fontSize: 'xl', - fontWeight: 'semibold', - ...forwardProps(this.$props) - }, + fontWeight: 'semibold' + } + } + }, + render (h) { + const { headerId } = this.context + return h('header', { + class: [this.className], attrs: { id: headerId, - 'data-chakra-component': 'CModalHeader' - } + ...this.computedAttrs + }, + on: this.computedListeners }, this.$slots.default) } } @@ -516,21 +506,20 @@ const CModalHeader = { */ const CModalFooter = { name: 'CModalFooter', - props: baseProps, - render (h) { + functional: true, + render (h, { slots, data }) { return h(CBox, { - props: { + ...data, + attrs: { as: 'footer', display: 'flex', px: 6, py: 4, justifyContent: 'flex-end', - ...forwardProps(this.$props) - }, - attrs: { + ...data.attrs, 'data-chakra-component': 'CModalFooter' } - }, this.$slots.default) + }, slots().default) } } @@ -543,34 +532,36 @@ const CModalFooter = { * @see Docs https://vue.chakra-ui.com/modal */ const CModalBody = { - name: 'CModalBody', - props: baseProps, + mixins: [createStyledAttrsMixin('CModalBody')], inject: ['$ModalContext'], computed: { context () { return this.$ModalContext() - } - }, - render (h) { - const { bodyId, scrollBehavior } = this.context - - let style = {} - if (scrollBehavior === 'inside') { - style = { overflowY: 'auto' } - } - - return h(CBox, { - props: { + }, + componentStyles () { + const { scrollBehavior } = this.context + let style = {} + if (scrollBehavior === 'inside') { + style = { overflowY: 'auto' } + } + return { px: 6, py: 2, flex: 1, - ...style, - ...forwardProps(this.$props) - }, + ...style + } + } + }, + render (h) { + const { bodyId } = this.context + return h(this.as || 'div', { + class: [this.className], attrs: { id: bodyId, + ...this.computedAttrs, 'data-chakra-component': 'CModalBody' - } + }, + on: this.computedListeners }, this.$slots.default) } } @@ -584,33 +575,68 @@ const CModalBody = { * @see Docs https://vue.chakra-ui.com/modal */ const CModalCloseButton = { - name: 'CModalCloseButton', - props: styleProps, + mixins: [createStyledAttrsMixin('CModalCloseButton', true)], inject: ['$ModalContext'], + props: closeButtonProps, computed: { context () { return this.$ModalContext() + }, + componentStyles () { + const colorMode = this.colorMode + + // Pseudo styles + const hoverColor = { light: 'blackAlpha.100', dark: 'whiteAlpha.100' } + const activeColor = { light: 'blackAlpha.200', dark: 'whiteAlpha.200' } + + // Size styles + const buttonSize = sizes[this.size] && sizes[this.size].button + + return { + outline: 'none', + h: buttonSize, + w: buttonSize, + disabled: this.isDisabled, + cursor: 'pointer', + _hover: { bg: hoverColor[colorMode] }, + _active: { bg: activeColor[colorMode] }, + position: 'absolute', + top: '8px', + right: '12px', + ...baseProps + } } }, render (h) { const { onClose } = this.context - return h(CCloseButton, { - props: { - position: 'absolute', - top: '8px', - right: '12px', - ...forwardProps(this.$props) - }, + const iconSize = sizes[this.size] && sizes[this.size].icon + + return h('button', { + class: [this.className], attrs: { - 'x-close-button': '', + ...this.computedAttrs, + 'aria-label': this.ariaLabel, + 'aria-disabled': this.isDisabled, 'data-chakra-component': 'CModalCloseButton' }, on: { + ...this.computedListeners, click: (e) => { wrapEvent(onClose, event => this.$emit('click', event))(e) - } + }, + ...this.computedListeners } - }) + }, [h(CIcon, { + props: { + color: props.color, + name: 'close', + size: iconSize + }, + attrs: { + focusable: false, + 'aria-hidden': true + } + })]) } } diff --git a/packages/chakra-ui-core/src/CModal/tests/__snapshots__/CModal.test.js.snap b/packages/chakra-ui-core/src/CModal/tests/__snapshots__/CModal.test.js.snap index e759290d..0248d469 100644 --- a/packages/chakra-ui-core/src/CModal/tests/__snapshots__/CModal.test.js.snap +++ b/packages/chakra-ui-core/src/CModal/tests/__snapshots__/CModal.test.js.snap @@ -2,17 +2,79 @@ exports[`should render correctly 1`] = ` -
+ .emotion-1 { + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-transition: all 250ms; + transition: all 250ms; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + position: relative; + white-space: nowrap; + vertical-align: middle; + line-height: 1.2; + outline: none; + font-weight: 700; + border-radius: 0.25rem; + height: 2.5rem; + min-width: 2.5rem; + font-size: 1rem; + padding-left: 1rem; + padding-right: 1rem; + background-color: #EDF2F7; +} + +.emotion-1:focus { + outline: none; + box-shadow: 0 0 0 3px rgba(66,153,225,0.6); +} + +.emotion-1:hover { + background-color: #E2E8F0; +} + +.emotion-1:active, +.emotion-1[data-active=true] { + background-color: #CBD5E0; +} + +.emotion-1:disabled, +.emotion-1:disabled:focus, +.emotion-1:disabled:hover, +.emotion-1[aria-disabled=true], +.emotion-1[aria-disabled=true]:focus, +.emotion-1[aria-disabled=true]:hover { + opacity: 0.4; + cursor: not-allowed; + box-shadow: none; +} + +
-
-
-
@@ -45,7 +249,7 @@ exports[`should render correctly 1`] = `
@@ -59,11 +263,11 @@ exports[`should render correctly 1`] = `
- .emotion-0 { - position: fixed; - background-color: rgba(0,0,0,0.4); - left: 0; - top: 0; - width: 100vw; - height: 100vh; - z-index: 1300; -} - -.emotion-12 { - position: fixed; - left: 0; - top: 0; - width: 100%; - height: 100%; - z-index: 1400; -} - -.emotion-11 { - outline: 0; - max-width: 28rem; - width: 100%; - position: fixed; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - z-index: 1400; - font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; - background-color: #fff; - box-shadow: 0 7px 14px 0 rgba(0,0,0,0.1),0 3px 6px 0 rgba(0,0,0,.07); - right: 0; - top: 0; - height: 100vh; -} - -.emotion-4 { - outline: none; - height: 32px; - width: 32px; - cursor: pointer; - position: fixed; - top: 8px; - right: 12px; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - border-radius: 0.25rem; - -webkit-transition: all 0.2s; - transition: all 0.2s; - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - border: 0; - background-color: rgba(0,0,0,0.04); - z-index: 1; -} - -.emotion-4:hover { - background-color: rgba(0,0,0,0.06); -} - -.emotion-4:active, -.emotion-4[data-active=true] { - background-color: rgba(0,0,0,0.08); -} - -.emotion-4:disabled, -.emotion-4:disabled:focus, -.emotion-4:disabled:hover, -.emotion-4[aria-disabled=true], -.emotion-4[aria-disabled=true]:focus, -.emotion-4[aria-disabled=true]:hover { - cursor: not-allowed; -} - -.emotion-4:focus { - box-shadow: 0 0 0 3px rgba(66,153,225,0.6); -} - -.emotion-1 { - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; -} - -.emotion-1:not(:root) { - overflow: hidden; -} - -.emotion-2 { - width: 12px; - height: 12px; - display: inline-block; - vertical-align: middle; -} - -.emotion-5 { - padding-left: 1.5rem; - padding-right: 1.5rem; - padding-top: 1rem; - padding-bottom: 1rem; - position: relative; - font-size: 1.25rem; - font-weight: 600; -} - -.emotion-7 { - padding-left: 1.5rem; - padding-right: 1.5rem; - padding-top: 0.5rem; - padding-bottom: 0.5rem; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; -} - -.emotion-10 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - padding-left: 1.5rem; - padding-right: 1.5rem; - padding-top: 1rem; - padding-bottom: 1rem; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-8 { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-transition: all 250ms; - transition: all 250ms; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - position: relative; - white-space: nowrap; - vertical-align: middle; - line-height: 1.2; - outline: none; - font-weight: 700; - border-radius: 0.25rem; - height: 2.5rem; - min-width: 2.5rem; - font-size: 1rem; - padding-left: 1rem; - padding-right: 1rem; - border: 1px solid; - border-color: #E2E8F0; - color: #A0AEC0; - background-color: transparent; - margin-right: 0.75rem; -} - -.emotion-8:focus { - outline: none; - box-shadow: 0 0 0 3px rgba(66,153,225,0.6); -} - -.emotion-8:hover { - background-color: #F7FAFC; -} - -.emotion-8:active, -.emotion-8[data-active=true] { - background-color: #EDF2F7; -} - -.emotion-8:disabled, -.emotion-8:disabled:focus, -.emotion-8:disabled:hover, -.emotion-8[aria-disabled=true], -.emotion-8[aria-disabled=true]:focus, -.emotion-8[aria-disabled=true]:hover { - opacity: 0.4; - cursor: not-allowed; - box-shadow: none; -} - -.emotion-9 { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-transition: all 250ms; - transition: all 250ms; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - position: relative; - white-space: nowrap; - vertical-align: middle; - line-height: 1.2; - outline: none; - font-weight: 700; - border-radius: 0.25rem; - height: 2.5rem; - min-width: 2.5rem; - font-size: 1rem; - padding-left: 1rem; - padding-right: 1rem; - background-color: #EDF2F7; -} - -.emotion-9 color { - 50: #def0ff; - 100: #afd0ff; - 200: #7db1ff; - 300: #4b91ff; - 400: #1a72ff; - 500: #0058e6; - 600: #0045b4; - 700: #003182; - 800: #001d51; - 900: #000a21; -} - -.emotion-9:focus { - outline: none; - box-shadow: 0 0 0 3px rgba(66,153,225,0.6); -} - -.emotion-9:hover { - background-color: #E2E8F0; -} - -.emotion-9:active, -.emotion-9[data-active=true] { - background-color: #CBD5E0; -} - -.emotion-9:disabled, -.emotion-9:disabled:focus, -.emotion-9:disabled:hover, -.emotion-9[aria-disabled=true], -.emotion-9[aria-disabled=true]:focus, -.emotion-9[aria-disabled=true]:hover { - opacity: 0.4; - cursor: not-allowed; - box-shadow: none; -} - -
- .emotion-0 { - position: fixed; - background-color: rgba(0,0,0,0.4); - left: 0; - top: 0; - width: 100vw; - height: 100vh; - z-index: 1300; -} - -.emotion-12 { - overflow-y: auto; - overflow-x: hidden; - position: fixed; - left: 0; - top: 0; - width: 100%; - height: 100%; - z-index: 1400; -} - -.emotion-11 { - outline: 0; - max-width: 28rem; - width: 100%; - position: relative; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - z-index: 1400; - font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; - background-color: #fff; - box-shadow: 0 7px 14px 0 rgba(0,0,0,0.1),0 3px 6px 0 rgba(0,0,0,.07); - top: 0; - margin-left: auto; - margin-right: auto; - margin-top: 3.75rem; - margin-bottom: 3.75rem; -} - -.emotion-4 { - outline: none; - height: 32px; - width: 32px; - cursor: pointer; - position: absolute; - top: 8px; - right: 12px; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - border-radius: 0.25rem; - -webkit-transition: all 0.2s; - transition: all 0.2s; - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - border: 0; - background-color: rgba(0,0,0,0.04); -} - -.emotion-4:hover { - background-color: rgba(0,0,0,0.06); -} - -.emotion-4:active, -.emotion-4[data-active=true] { - background-color: rgba(0,0,0,0.08); -} - -.emotion-4:disabled, -.emotion-4:disabled:focus, -.emotion-4:disabled:hover, -.emotion-4[aria-disabled=true], -.emotion-4[aria-disabled=true]:focus, -.emotion-4[aria-disabled=true]:hover { - cursor: not-allowed; -} - -.emotion-4:focus { - box-shadow: 0 0 0 3px rgba(66,153,225,0.6); -} - -.emotion-1 { - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; -} - -.emotion-1:not(:root) { - overflow: hidden; -} - -.emotion-2 { - width: 12px; - height: 12px; - display: inline-block; - vertical-align: middle; -} - -.emotion-5 { - padding-left: 1.5rem; - padding-right: 1.5rem; - padding-top: 1rem; - padding-bottom: 1rem; - position: relative; - font-size: 1.25rem; - font-weight: 600; -} - -.emotion-7 { - padding-left: 1.5rem; - padding-right: 1.5rem; - padding-top: 0.5rem; - padding-bottom: 0.5rem; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; -} - -.emotion-10 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - padding-left: 1.5rem; - padding-right: 1.5rem; - padding-top: 1rem; - padding-bottom: 1rem; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-8 { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-transition: all 250ms; - transition: all 250ms; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - position: relative; - white-space: nowrap; - vertical-align: middle; - line-height: 1.2; - outline: none; - font-weight: 700; - border-radius: 0.25rem; - height: 2.5rem; - min-width: 2.5rem; - font-size: 1rem; - padding-left: 1rem; - padding-right: 1rem; - border: 1px solid; - border-color: #E2E8F0; - color: #A0AEC0; - background-color: transparent; - margin-right: 0.75rem; -} - -.emotion-8:focus { - outline: none; - box-shadow: 0 0 0 3px rgba(66,153,225,0.6); -} - -.emotion-8:hover { - background-color: #F7FAFC; -} - -.emotion-8:active, -.emotion-8[data-active=true] { - background-color: #EDF2F7; -} - -.emotion-8:disabled, -.emotion-8:disabled:focus, -.emotion-8:disabled:hover, -.emotion-8[aria-disabled=true], -.emotion-8[aria-disabled=true]:focus, -.emotion-8[aria-disabled=true]:hover { - opacity: 0.4; - cursor: not-allowed; - box-shadow: none; -} - -.emotion-9 { - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-transition: all 250ms; - transition: all 250ms; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - position: relative; - white-space: nowrap; - vertical-align: middle; - line-height: 1.2; - outline: none; - font-weight: 700; - border-radius: 0.25rem; - height: 2.5rem; - min-width: 2.5rem; - font-size: 1rem; - padding-left: 1rem; - padding-right: 1rem; - background-color: #EDF2F7; -} - -.emotion-9 color { - 50: #def0ff; - 100: #afd0ff; - 200: #7db1ff; - 300: #4b91ff; - 400: #1a72ff; - 500: #0058e6; - 600: #0045b4; - 700: #003182; - 800: #001d51; - 900: #000a21; -} - -.emotion-9:focus { - outline: none; - box-shadow: 0 0 0 3px rgba(66,153,225,0.6); -} - -.emotion-9:hover { - background-color: #E2E8F0; -} - -.emotion-9:active, -.emotion-9[data-active=true] { - background-color: #CBD5E0; -} - -.emotion-9:disabled, -.emotion-9:disabled:focus, -.emotion-9:disabled:hover, -.emotion-9[aria-disabled=true], -.emotion-9[aria-disabled=true]:focus, -.emotion-9[aria-disabled=true]:hover { - opacity: 0.4; - cursor: not-allowed; - box-shadow: none; -} - -