From 301414d5b8a3005be4f6afcca0b9368c361ff7b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Connor=20B=C3=A4r?= Date: Mon, 4 May 2020 14:26:27 +0200 Subject: [PATCH 1/4] feat(configs): improve Jest config for TypeScript (#580) * test(configs): fix Jest config for TypeScript feature/typescript-jest feature/typescript-jest * docs: update test command feature/typescript-jest --- .npmignore | 2 + README.md | 2 +- docs/introduction/contributing.story.mdx | 2 +- jest.config.js | 19 ++++-- jest.setup.js | 51 +++++---------- package.json | 6 +- scripts/static-styles/config.js | 21 ++++--- .../types/global.d.ts | 19 ++---- src/util/test-utils.tsx | 63 +++++++++++++++++++ tsconfig.json | 3 +- yarn.lock | 31 ++++++--- 11 files changed, 142 insertions(+), 77 deletions(-) create mode 100644 .npmignore rename jest.fileTransformer.js => src/types/global.d.ts (63%) create mode 100644 src/util/test-utils.tsx diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000000..cbb7650234 --- /dev/null +++ b/.npmignore @@ -0,0 +1,2 @@ +**/*.story.* +**/*.spec.* diff --git a/README.md b/README.md index 67f18be5d8..cd5a2deccc 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ yarn lint:fix ## Testing ``` -yarn test:watch +yarn test ``` ```javascript diff --git a/docs/introduction/contributing.story.mdx b/docs/introduction/contributing.story.mdx index dd80c18ff2..a79d1e96ba 100644 --- a/docs/introduction/contributing.story.mdx +++ b/docs/introduction/contributing.story.mdx @@ -79,7 +79,7 @@ yarn storybook We use [Jest](https://jestjs.io/) and [react-testing-library](https://github.com/testing-library/react-testing-library) to unit test our components. Since most components are purely visual, we rely a lot on snapshot tests. Business logic should be tested with more specific assertions. To start unit tests in watch mode, run: ```bash -yarn test:watch +yarn test ``` As for linting and formatting, you can configure your editor to automatically lint and format your code on save. For this purpose, we're using [Prettier](https://prettier.io/) and [ESLint](https://eslint.org/). If you need to do it manually, you can run: diff --git a/jest.config.js b/jest.config.js index 12dbec56e7..b304b556c9 100644 --- a/jest.config.js +++ b/jest.config.js @@ -34,9 +34,20 @@ module.exports = { 'react-syntax-highlighter/dist/cjs/$1' }, transform: { - '^.+\\.jsx?$': 'babel-jest', - '^.+\\.svg$': '/jest.fileTransformer.js', - '^.+\\.mdx?$': '/jest.mdxTransformer.js' + '^.+\\.(js|jsx)$': 'babel-jest', + '^.+\\.(ts|tsx)$': 'ts-jest', + '^.+\\.(md|mdx)$': '/jest.mdxTransformer.js' }, - setupFilesAfterEnv: ['/jest.setup.js'] + setupFilesAfterEnv: ['/jest.setup.js'], + globals: { + STORYBOOK: false, + __DEV__: false, + __PRODUCTION__: false, + __TEST__: true, + 'ts-jest': { + tsConfig: { + jsx: 'react' + } + } + } }; diff --git a/jest.setup.js b/jest.setup.js index a65a505a42..34870ce6ca 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -14,50 +14,31 @@ */ import React from 'react'; -import { renderToStaticMarkup } from 'react-dom/server'; import '@testing-library/jest-dom/extend-expect'; import { createSerializer } from 'jest-emotion'; -import { axe, toHaveNoViolations } from 'jest-axe'; -import { render, fireEvent, wait, act } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import { ThemeProvider } from 'emotion-theming'; -import { light } from '@sumup/design-tokens'; +import { toHaveNoViolations } from 'jest-axe'; +import { fireEvent } from '@testing-library/react'; -import ComponentsContext, { - defaultComponents -} from './src/components/ComponentsContext'; - -// eslint-disable-next-line react/prop-types -const WithProviders = ({ children }) => ( - - {children} - -); - -const renderWithProviders = renderFn => (component, ...rest) => - renderFn({component}, rest); +import { + create, + render, + renderToHtml, + renderHook, + act, + actHook, + userEvent, + wait, + axe +} from './src/util/test-utils'; global.axe = axe; global.act = act; global.wait = wait; global.fireEvent = fireEvent; global.userEvent = userEvent; -global.render = (component, options) => - render(component, { wrapper: WithProviders, ...options }); -global.renderToHtml = renderWithProviders(renderToStaticMarkup); -global.create = (...args) => { - const { container } = global.render(...args); - return container.children.length > 1 - ? container.children - : container.firstChild; -}; - -// This is defined by webpack in storybook builds using the DefinePlugin plugin. -global.STORYBOOK = false; - -global.__DEV__ = false; -global.__PRODUCTION__ = false; -global.__TEST__ = true; +global.render = render; +global.renderToHtml = renderToHtml; +global.create = create; // react-popper relies on document.createRange if (global.document) { diff --git a/package.json b/package.json index d734195796..01a54e403b 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,7 @@ "lint:fix": "yarn lint --fix", "lint:watch": "onchange \"src/**/*\" -- yarn lint", "lint:ci": "yarn lint --format junit -o __reports__/eslint-results.xml", - "test": "jest --silent", - "test:watch": "yarn test --watch", + "test": "jest --watch", "test:output": "mkdir -p __reports__ && jest --json --outputFile=__reports__/jest-results.json", "test:ci": "yarn test:output --ci --coverage --runInBand", "check:security": "audit-ci --critical", @@ -103,9 +102,10 @@ "@testing-library/dom": "^6.5.0", "@testing-library/jest-dom": "^4.1.0", "@testing-library/react": "^9.1.4", - "@testing-library/react-hooks": "^2.0.1", + "@testing-library/react-hooks": "^3.2.1", "@testing-library/user-event": "^7.0.1", "@types/jest": "^25.2.1", + "@types/jest-axe": "^3.2.2", "@types/lodash": "^4.14.149", "@types/react": "^16.9.32", "@types/react-dom": "^16.9.6", diff --git a/scripts/static-styles/config.js b/scripts/static-styles/config.js index c5d5b5a558..a6d6292539 100644 --- a/scripts/static-styles/config.js +++ b/scripts/static-styles/config.js @@ -107,14 +107,19 @@ function getRequiredProps(props) { } export function getComponentInfo(component, propOverrides = {}) { - // eslint-disable-next-line no-underscore-dangle - const { displayName, props } = component.__docgenInfo; - return { - component, - name: kebabCase(displayName), - props: getProps(props, propOverrides), - requiredProps: getRequiredProps(props) - }; + try { + // eslint-disable-next-line no-underscore-dangle + const { displayName, props } = component.__docgenInfo; + return { + component, + name: kebabCase(displayName), + props: getProps(props, propOverrides), + requiredProps: getRequiredProps(props) + }; + } catch (error) { + console.error(component); + throw error; + } } export default { diff --git a/jest.fileTransformer.js b/src/types/global.d.ts similarity index 63% rename from jest.fileTransformer.js rename to src/types/global.d.ts index 4e29e0c59d..1c007eaa79 100644 --- a/jest.fileTransformer.js +++ b/src/types/global.d.ts @@ -1,5 +1,5 @@ /** - * Copyright 2019, SumUp Ltd. + * Copyright 2020, SumUp Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,16 +13,7 @@ * limitations under the License. */ -const { basename } = require('path'); - -module.exports = { - process(src, filename) { - const name = basename(filename); - return ` - const React = require('react') - module.exports = { - ReactComponent: props => React.createElement('div', props, '${name}') - } - `; - } -}; +declare module '*.mdx' { + const MDXComponent: (props: any) => JSX.Element; + export default MDXComponent; +} diff --git a/src/util/test-utils.tsx b/src/util/test-utils.tsx new file mode 100644 index 0000000000..9bc6a48d20 --- /dev/null +++ b/src/util/test-utils.tsx @@ -0,0 +1,63 @@ +/** + * Copyright 2020, SumUp Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { FunctionComponent } from 'react'; +import { renderToStaticMarkup } from 'react-dom/server'; +import '@testing-library/jest-dom/extend-expect'; +import { axe } from 'jest-axe'; +import { render as renderTest, wait, act } from '@testing-library/react'; +import { renderHook, act as actHook } from '@testing-library/react-hooks'; +import userEvent from '@testing-library/user-event'; +import { ThemeProvider } from 'emotion-theming'; +import { light } from '@sumup/design-tokens'; + +import ComponentsContext, { + defaultComponents +} from '../components/ComponentsContext'; + +export type RenderFn = (component: React.ReactElement, ...rest: any) => any; + +const WithProviders: FunctionComponent = ({ children }) => ( + + {children} + +); + +const renderWithProviders = (renderer: RenderFn): RenderFn => ( + component, + ...rest +): RenderFn => renderer({component}, rest); + +const render: RenderFn = (component, options) => + renderTest(component, { wrapper: WithProviders, ...options }); +const renderToHtml: RenderFn = renderWithProviders(renderToStaticMarkup); +const create: RenderFn = (...args) => { + const { container } = render(...args); + return container.children.length > 1 + ? container.children + : container.firstChild; +}; + +export { + create, + render, + renderToHtml, + renderHook, + act, + actHook, + userEvent, + wait, + axe +}; diff --git a/tsconfig.json b/tsconfig.json index 9ab6bf600c..81175fb3b7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,12 +23,11 @@ { "name": "typescript-styled-plugin", "lint": { - "validProperties": "label" + "validProperties": ["label"] } } ] }, "include": ["src/**/*"], - "exclude": ["**/*.spec.*", "**/*.story.*"], "typeRoots": ["./node_modules/@types", "./src/types/"] } diff --git a/yarn.lock b/yarn.lock index 0588f6b9a6..2f05e9b7a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2533,13 +2533,13 @@ pretty-format "^24.0.0" redent "^3.0.0" -"@testing-library/react-hooks@^2.0.1": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-2.0.3.tgz#305a6c76facb5fa1d185792b9eb11b1ca1b63fb7" - integrity sha512-adm+7b1gcysGka8VuYq/ObBrIBJTT9QmCEIqPpuxozWFfVDgxSbzBGc44ia/WYLGVt2dqFIOc6/DmAmu/pa0gQ== +"@testing-library/react-hooks@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-3.2.1.tgz#19b6caa048ef15faa69d439c469033873ea01294" + integrity sha512-1OB6Ksvlk6BCJA1xpj8/WWz0XVd1qRcgqdaFAq+xeC6l61Ucj0P6QpA5u+Db/x9gU4DCX8ziR5b66Mlfg0M2RA== dependencies: "@babel/runtime" "^7.5.4" - "@types/testing-library__react-hooks" "^2.0.0" + "@types/testing-library__react-hooks" "^3.0.0" "@testing-library/react@^9.1.4": version "9.4.0" @@ -2692,6 +2692,14 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" +"@types/jest-axe@^3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@types/jest-axe/-/jest-axe-3.2.2.tgz#9f66189683b91be02ba20e5defac42824f332f38" + integrity sha512-xVscGbS3nDay2GRG2TwF6xx92BbwU46gGanoelAfrweTng8OKU9pmX8AByuz5i8lWQ+y6B9PvkbtAJNDjsdSJQ== + dependencies: + "@types/jest" "*" + axe-core "^3.0.3" + "@types/jest-specific-snapshot@^0.5.3": version "0.5.4" resolved "https://registry.yarnpkg.com/@types/jest-specific-snapshot/-/jest-specific-snapshot-0.5.4.tgz#997364c39a59ddeff0ee790a19415e79dd061d1e" @@ -2867,10 +2875,10 @@ dependencies: pretty-format "^24.3.0" -"@types/testing-library__react-hooks@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/testing-library__react-hooks/-/testing-library__react-hooks-2.0.0.tgz#7b289d64945517ae8ba9cbcb0c5b282432aaeffa" - integrity sha512-YUVqXGCChJKEJ4aAnMXqPCq0NfPAFVsJeGIb2y/iiMjxwyu+45+vR+AHOwjJHHKEHeC0ZhOGrZ5gSEmaJe4tyQ== +"@types/testing-library__react-hooks@^3.0.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@types/testing-library__react-hooks/-/testing-library__react-hooks-3.2.0.tgz#52f3a109bef06080e3b1e3ae7ea1c014ce859897" + integrity sha512-dE8iMTuR5lzB+MqnxlzORlXzXyCL0EKfzH0w/lau20OpkHD37EaWjZDz0iNG8b71iEtxT4XKGmSKAGVEqk46mw== dependencies: "@types/react" "*" "@types/react-test-renderer" "*" @@ -3754,6 +3762,11 @@ axe-core@3.4.1, axe-core@^3.3.2: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-3.4.1.tgz#e42623918bb85b5ef674633852cb9029db0309c5" integrity sha512-+EhIdwR0hF6aeMx46gFDUy6qyCfsL0DmBrV3Z+LxYbsOd8e1zBaPHa3f9Rbjsz2dEwSBkLw6TwML/CAIIAqRpw== +axe-core@^3.0.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-3.5.3.tgz#5b7c0ee7c5197d546bd3a07c3ef701896f5773e9" + integrity sha512-HZpLE7xu05+8AbpqXITGdxp1Xwk8ysAXrg7MiKRY27py3DAyEJpoJQo1727pWF3F+O79V3r+cTWhOzfB49P89w== + axios@0.19.0: version "0.19.0" resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" From 3fa5edf66de4d24fea23dbebd509e387c83b606b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Connor=20B=C3=A4r?= Date: Fri, 1 May 2020 00:24:20 +0200 Subject: [PATCH 2/4] refactor(components): migrate Text to TypeScript feature/typescript-text --- scripts/static-styles/config.js | 7 +- src/__snapshots__/storyshots.spec.js.snap | 625 +++++++++--------- .../__snapshots__/Blockquote.spec.js.snap | 34 +- .../components/PlainButton/PlainButton.js | 4 +- .../__snapshots__/Carousel.spec.js.snap | 296 ++++----- .../Status/__snapshots__/Status.spec.js.snap | 8 +- src/components/Text/Text.js | 153 ----- .../Text/{Text.spec.js => Text.spec.tsx} | 6 +- .../Text/{Text.story.js => Text.story.tsx} | 10 +- src/components/Text/Text.tsx | 121 ++++ .../{Text.spec.js.snap => Text.spec.tsx.snap} | 20 +- src/components/Text/{index.js => index.ts} | 4 +- .../Toggle/__snapshots__/Toggle.spec.js.snap | 72 +- src/styles/styled.ts | 23 + 14 files changed, 692 insertions(+), 691 deletions(-) delete mode 100644 src/components/Text/Text.js rename src/components/Text/{Text.spec.js => Text.spec.tsx} (92%) rename src/components/Text/{Text.story.js => Text.story.tsx} (88%) create mode 100644 src/components/Text/Text.tsx rename src/components/Text/__snapshots__/{Text.spec.js.snap => Text.spec.tsx.snap} (91%) rename src/components/Text/{index.js => index.ts} (90%) create mode 100644 src/styles/styled.ts diff --git a/scripts/static-styles/config.js b/scripts/static-styles/config.js index a6d6292539..cf89f2a4f4 100644 --- a/scripts/static-styles/config.js +++ b/scripts/static-styles/config.js @@ -20,7 +20,6 @@ import { light } from '@sumup/design-tokens'; import { Badge, Blockquote, - Button, ButtonGroup, Card, Checkbox, @@ -42,8 +41,7 @@ import { styleConstants } from '../../src'; -const { colorNames, sizes } = styleConstants; -const { KILO, MEGA, GIGA } = sizes; +const { colorNames } = styleConstants; const element = props =>
; @@ -133,7 +131,8 @@ export default { circle: PropTypes.bool } }, - getComponentInfo(Button, { size: [KILO, MEGA, GIGA] }), + // TODO: Make React DocGen work with TypeScript + // getComponentInfo(Button, { size: [KILO, MEGA, GIGA] }), getComponentInfo(Blockquote, { size: [Blockquote.KILO, Blockquote.MEGA, Blockquote.GIGA] }), diff --git a/src/__snapshots__/storyshots.spec.js.snap b/src/__snapshots__/storyshots.spec.js.snap index 7fbc33b540..66d4b8108f 100644 --- a/src/__snapshots__/storyshots.spec.js.snap +++ b/src/__snapshots__/storyshots.spec.js.snap @@ -237,25 +237,27 @@ HTMLCollection [ `; exports[`Storyshots Components/Blockquote Base 1`] = ` -.circuit-1 { +.circuit-0 { font-weight: 400; margin-bottom: 16px; - font-size: 13px; - line-height: 20px; + font-size: 16px; + line-height: 24px; font-style: italic; padding-left: 12px; border-left: 2px solid #3388FF; + padding-left: 16px; + border-left: 3px solid #3388FF; } @media (min-width:480px) { - .circuit-1 { - font-size: 13px; - line-height: 20px; + .circuit-0 { + font-size: 16px; + line-height: 24px; } }
Lorem ipsum dolor amet echo park activated charcoal banjo deep @@ -268,29 +270,31 @@ tbh adaptogen green juice lo-fi kombucha. exports[`Storyshots Components/Blockquote Size 1`] = ` HTMLCollection [ - .circuit-1 { + .circuit-0 { font-weight: 400; margin-bottom: 16px; - font-size: 13px; - line-height: 20px; + font-size: 16px; + line-height: 24px; font-style: italic; padding-left: 12px; border-left: 2px solid #3388FF; + padding-left: 16px; + border-left: 3px solid #3388FF; } @media (min-width:480px) { - .circuit-1 { - font-size: 13px; - line-height: 20px; + .circuit-0 { + font-size: 16px; + line-height: 24px; } }
Kilo - The ability to accept credit card payments that are EMV-compliant is essentially an insurance policy against fraud and an impressively economical one at that.
, - .circuit-1 { + .circuit-0 { font-weight: 400; margin-bottom: 16px; font-size: 16px; @@ -298,21 +302,23 @@ HTMLCollection [ font-style: italic; padding-left: 12px; border-left: 2px solid #3388FF; + padding-left: 16px; + border-left: 3px solid #3388FF; } @media (min-width:480px) { - .circuit-1 { + .circuit-0 { font-size: 16px; line-height: 24px; } }
Mega - The ability to accept credit card payments that are EMV-compliant is essentially an insurance policy against fraud and an impressively economical one at that.
, - .circuit-1 { + .circuit-0 { font-weight: 400; margin-bottom: 16px; font-size: 16px; @@ -325,14 +331,14 @@ HTMLCollection [ } @media (min-width:480px) { - .circuit-1 { - font-size: 18px; - line-height: 28px; + .circuit-0 { + font-size: 16px; + line-height: 24px; } }
Giga - The ability to accept credit card payments that are EMV-compliant is essentially an insurance policy against fraud and an impressively economical one at that.
, @@ -4574,7 +4580,7 @@ HTMLCollection [ exports[`Storyshots Components/Card With Footer 1`] = ` HTMLCollection [ - .circuit-2 { + .circuit-1 { background-color: #FAFBFC; border-color: #D8DDE1; border-radius: 4px; @@ -4600,36 +4606,36 @@ HTMLCollection [ color: #5C656F; } -.circuit-2:active { +.circuit-1:active { background-color: #D8DDE1; border-color: #9DA7B1; box-shadow: inset 0 4px 8px 0 rgba(12,15,20,0.3); } -.circuit-2:focus { +.circuit-1:focus { border-color: #9DA7B1; border-width: 2px; outline: 0; padding: calc(8px - 1px) calc(24px - 1px); } -.circuit-2:hover { +.circuit-1:hover { background-color: #D8DDE1; } -.circuit-2:hover, -.circuit-2:active { +.circuit-1:hover, +.circuit-1:active { border-color: #9DA7B1; border-width: 1px; padding: calc(8px - 0px) calc(24px - 0px); } -.circuit-2[href] { +.circuit-1[href] { display: inline-block; } -.circuit-2:disabled, -.circuit-2[disabled] { +.circuit-1:disabled, +.circuit-1[disabled] { opacity: 0.4; pointer-events: none; -webkit-user-selectable: none; @@ -4638,48 +4644,48 @@ HTMLCollection [ user-selectable: none; } -.circuit-2:active { +.circuit-1:active { background-color: transparent; border-color: #212933; border-width: 0; box-shadow: none; } -.circuit-2:focus { +.circuit-1:focus { border-color: #212933; border-width: 2px; box-shadow: none; padding: calc(8px - 2px) calc(24px - 2px); } -.circuit-2:hover { +.circuit-1:hover { background-color: transparent; border-width: 0; border-color: #212933; } -.circuit-2:active, -.circuit-2:hover, -.circuit-2:hover:focus, -.circuit-2:active:focus { +.circuit-1:active, +.circuit-1:hover, +.circuit-1:hover:focus, +.circuit-1:active:focus { padding: calc(8px - 0px) calc(24px - 0px); } -.circuit-2:active, -.circuit-2:hover, -.circuit-2:focus { +.circuit-1:active, +.circuit-1:hover, +.circuit-1:focus { color: #212933; } -.circuit-2:active:focus, -.circuit-2:hover:focus { +.circuit-1:active:focus, +.circuit-1:hover:focus { border-color: #212933; border-width: 2px; box-shadow: none; padding: calc(8px - 2px) calc(24px - 2px); } -.circuit-4 { +.circuit-3 { background-color: #FAFBFC; border-color: #D8DDE1; border-radius: 4px; @@ -4700,36 +4706,36 @@ HTMLCollection [ padding: calc(8px - 0px) calc(24px - 0px); } -.circuit-4:active { +.circuit-3:active { background-color: #D8DDE1; border-color: #9DA7B1; box-shadow: inset 0 4px 8px 0 rgba(12,15,20,0.3); } -.circuit-4:focus { +.circuit-3:focus { border-color: #9DA7B1; border-width: 2px; outline: 0; padding: calc(8px - 1px) calc(24px - 1px); } -.circuit-4:hover { +.circuit-3:hover { background-color: #D8DDE1; } -.circuit-4:hover, -.circuit-4:active { +.circuit-3:hover, +.circuit-3:active { border-color: #9DA7B1; border-width: 1px; padding: calc(8px - 0px) calc(24px - 0px); } -.circuit-4[href] { +.circuit-3[href] { display: inline-block; } -.circuit-4:disabled, -.circuit-4[disabled] { +.circuit-3:disabled, +.circuit-3[disabled] { opacity: 0.4; pointer-events: none; -webkit-user-selectable: none; @@ -4738,7 +4744,7 @@ HTMLCollection [ user-selectable: none; } -.circuit-6 { +.circuit-5 { list-style-type: none; width: 100%; -webkit-box-pack: end; @@ -4747,16 +4753,16 @@ HTMLCollection [ justify-content: flex-end; } -.circuit-6 > li:not(:last-of-type) { +.circuit-5 > li:not(:last-of-type) { margin-bottom: 16px; } -.circuit-6 > li > * { +.circuit-5 > li > * { width: 100%; } @media (min-width:480px) { - .circuit-6 { + .circuit-5 { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; @@ -4766,13 +4772,13 @@ HTMLCollection [ flex-wrap: nowrap; } - .circuit-6 > li:not(:last-of-type) { + .circuit-5 > li:not(:last-of-type) { margin-bottom: 0; margin-right: 16px; } } -.circuit-10 { +.circuit-9 { background-color: #FFFFFF; border-radius: 4px; display: -webkit-box; @@ -4810,14 +4816,14 @@ HTMLCollection [ } } -.circuit-8 { +.circuit-7 { display: block; width: 100%; margin-top: 24px; } @media (min-width:480px) { - .circuit-8 { + .circuit-7 { -webkit-align-items: center; -webkit-box-align: center; -ms-flex-align: center; @@ -4831,7 +4837,7 @@ HTMLCollection [ } @media (min-width:480px) { - .circuit-8 { + .circuit-7 { -webkit-box-pack: end; -webkit-justify-content: flex-end; -ms-flex-pack: end; @@ -4840,30 +4846,30 @@ HTMLCollection [ }

This is some text showing in my card

  • @@ -4871,7 +4877,7 @@ HTMLCollection [
, - .circuit-2 { + .circuit-1 { background-color: #FAFBFC; border-color: #D8DDE1; border-radius: 4px; @@ -4897,36 +4903,36 @@ HTMLCollection [ color: #5C656F; } -.circuit-2:active { +.circuit-1:active { background-color: #D8DDE1; border-color: #9DA7B1; box-shadow: inset 0 4px 8px 0 rgba(12,15,20,0.3); } -.circuit-2:focus { +.circuit-1:focus { border-color: #9DA7B1; border-width: 2px; outline: 0; padding: calc(8px - 1px) calc(24px - 1px); } -.circuit-2:hover { +.circuit-1:hover { background-color: #D8DDE1; } -.circuit-2:hover, -.circuit-2:active { +.circuit-1:hover, +.circuit-1:active { border-color: #9DA7B1; border-width: 1px; padding: calc(8px - 0px) calc(24px - 0px); } -.circuit-2[href] { +.circuit-1[href] { display: inline-block; } -.circuit-2:disabled, -.circuit-2[disabled] { +.circuit-1:disabled, +.circuit-1[disabled] { opacity: 0.4; pointer-events: none; -webkit-user-selectable: none; @@ -4935,48 +4941,48 @@ HTMLCollection [ user-selectable: none; } -.circuit-2:active { +.circuit-1:active { background-color: transparent; border-color: #212933; border-width: 0; box-shadow: none; } -.circuit-2:focus { +.circuit-1:focus { border-color: #212933; border-width: 2px; box-shadow: none; padding: calc(8px - 2px) calc(24px - 2px); } -.circuit-2:hover { +.circuit-1:hover { background-color: transparent; border-width: 0; border-color: #212933; } -.circuit-2:active, -.circuit-2:hover, -.circuit-2:hover:focus, -.circuit-2:active:focus { +.circuit-1:active, +.circuit-1:hover, +.circuit-1:hover:focus, +.circuit-1:active:focus { padding: calc(8px - 0px) calc(24px - 0px); } -.circuit-2:active, -.circuit-2:hover, -.circuit-2:focus { +.circuit-1:active, +.circuit-1:hover, +.circuit-1:focus { color: #212933; } -.circuit-2:active:focus, -.circuit-2:hover:focus { +.circuit-1:active:focus, +.circuit-1:hover:focus { border-color: #212933; border-width: 2px; box-shadow: none; padding: calc(8px - 2px) calc(24px - 2px); } -.circuit-4 { +.circuit-3 { background-color: #FAFBFC; border-color: #D8DDE1; border-radius: 4px; @@ -4997,36 +5003,36 @@ HTMLCollection [ padding: calc(8px - 0px) calc(24px - 0px); } -.circuit-4:active { +.circuit-3:active { background-color: #D8DDE1; border-color: #9DA7B1; box-shadow: inset 0 4px 8px 0 rgba(12,15,20,0.3); } -.circuit-4:focus { +.circuit-3:focus { border-color: #9DA7B1; border-width: 2px; outline: 0; padding: calc(8px - 1px) calc(24px - 1px); } -.circuit-4:hover { +.circuit-3:hover { background-color: #D8DDE1; } -.circuit-4:hover, -.circuit-4:active { +.circuit-3:hover, +.circuit-3:active { border-color: #9DA7B1; border-width: 1px; padding: calc(8px - 0px) calc(24px - 0px); } -.circuit-4[href] { +.circuit-3[href] { display: inline-block; } -.circuit-4:disabled, -.circuit-4[disabled] { +.circuit-3:disabled, +.circuit-3[disabled] { opacity: 0.4; pointer-events: none; -webkit-user-selectable: none; @@ -5035,7 +5041,7 @@ HTMLCollection [ user-selectable: none; } -.circuit-10 { +.circuit-9 { background-color: #FFFFFF; border-radius: 4px; display: -webkit-box; @@ -5073,14 +5079,14 @@ HTMLCollection [ } } -.circuit-8 { +.circuit-7 { display: block; width: 100%; margin-top: 24px; } @media (min-width:480px) { - .circuit-8 { + .circuit-7 { -webkit-align-items: center; -webkit-box-align: center; -ms-flex-align: center; @@ -5093,7 +5099,7 @@ HTMLCollection [ } } -.circuit-6 { +.circuit-5 { list-style-type: none; width: 100%; -webkit-box-pack: start; @@ -5102,16 +5108,16 @@ HTMLCollection [ justify-content: flex-start; } -.circuit-6 > li:not(:last-of-type) { +.circuit-5 > li:not(:last-of-type) { margin-bottom: 16px; } -.circuit-6 > li > * { +.circuit-5 > li > * { width: 100%; } @media (min-width:480px) { - .circuit-6 { + .circuit-5 { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; @@ -5121,37 +5127,37 @@ HTMLCollection [ flex-wrap: nowrap; } - .circuit-6 > li:not(:last-of-type) { + .circuit-5 > li:not(:last-of-type) { margin-bottom: 0; margin-right: 16px; } }

This is some text showing in my card