diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox.md b/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox.md new file mode 100644 index 00000000000..32ddfbf5fef --- /dev/null +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox.md @@ -0,0 +1,25 @@ +--- +title: 'Checkbox' +draft: false +order: 2 +--- + +import Tabs from 'Tags/Tabs' + +import CheckboxInfo from 'Pages/uilib/components/checkbox/checkbox-info' +import CheckboxProperties from 'Pages/uilib/components/checkbox/checkbox-properties' +import CheckboxEvents from 'Pages/uilib/components/checkbox/checkbox-events' + +# Checkbox + + + + + + + + + + + + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox/Examples.js b/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox/Examples.js new file mode 100644 index 00000000000..35b4a2c2c7f --- /dev/null +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox/Examples.js @@ -0,0 +1,113 @@ +/** + * UI lib Component Example + * + */ + +import React, { PureComponent, Fragment } from 'react' +import ComponentBox from '../../../../shared/tags/ComponentBox' + +class Example extends PureComponent { + onChangeHandler = state => { + console.log('onChangeHandler', state) + } + + render() { + const { onChangeHandler: onChange } = this + return ( + + + {/* @jsx */ ` + + `} + + + {/* @jsx */ ` + console.log(checked)} +/> + `} + + + {/* @jsx */ ` +

+ +

+ `} +
+ +
+ ) + } +} + +class StateDemo extends PureComponent { + render() { + return typeof window !== 'undefined' && window.IS_TEST ? ( + + {/* @jsx */ ` + +`} + + ) : ( + + {/* @jsx */ ` +() => { + const [checkboxIsEnabled, setState] = useState(false) + useEffect(() => { + const timer = setInterval(() => setState(!checkboxIsEnabled), 1e3) + return () => clearTimeout(timer) + }) + return (<> + + {}} + disabled + /> + ) +} + `} + + ) + } +} + +export { Example } +export default () => diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox/checkbox-events.md b/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox/checkbox-events.md new file mode 100644 index 00000000000..5e104b84797 --- /dev/null +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox/checkbox-events.md @@ -0,0 +1,8 @@ +--- +draft: true +--- + +| Events | Description | +| ----------------- | --------------------------------------------------------------------------- | +| `on_change` | _(optional)_ will be called on state changes made by the user. | +| `on_state_update` | _(optional)_ will be called once the parameter `checked` changes its value. | diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox/checkbox-info.md b/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox/checkbox-info.md new file mode 100644 index 00000000000..ee29f4cc095 --- /dev/null +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox/checkbox-info.md @@ -0,0 +1,14 @@ +--- +draft: true +--- + +import Examples from 'Pages/uilib/components/checkbox/Examples' + +## Description + +The `Checkbox` component is shown as a square box that is ticked (checked) when activated. +Checkboxes are used to let a user select one or more options of a limited number of choices. + +## Demos + + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox/checkbox-properties.md b/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox/checkbox-properties.md new file mode 100644 index 00000000000..2dcf467840d --- /dev/null +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/checkbox/checkbox-properties.md @@ -0,0 +1,13 @@ +--- +draft: true +--- + +| Properties | Description | +| --------------- | ------------------------------------------------------------------------------------------------------- | +| `title` | _(mandatory)_ the `title` of the input - describing it a bit further for accessibility reasons. | +| `label` | _(optional)_ use either the internal `label` or provide one manually. | +| `status` | _(optional)_ uses the `form-status` component to show failure messages. | +| `id` | _(optional)_ the `id` of the input. Default will be a random id. | +| `default_state` | _(optional)_ boolean value. The state of the checkbox. Defaults to `false`. Set to `true` if otherwise. | +| `checked` | _(optional)_ determine whether the checkbox is checked or not. Default will be `false`. | +| `disabled` | _(optional)_ to disable/enable the checkbox. | diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/switch/switch-info.md b/packages/dnb-design-system-portal/src/pages/uilib/components/switch/switch-info.md index c41b4f8043c..2541415f398 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/components/switch/switch-info.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/switch/switch-info.md @@ -11,6 +11,8 @@ _Also known as a toggle switch or a toggle._ The `Switch` component (toggle) is a digital on/off switch. Toggle switches are best used for changing the state of system functionalities and preferences. "Toggles may replace two radio buttons or a single checkbox to allow users to choose between two opposing states." - [Source][1] +May may also check out the [Checkbox](/uilib/components/checkbox) component. + ## How it **should** work "Toggle switches should take immediate effect and should not require the user to click Save or Submit to apply the new state. As always, we should strive to match the system to the real world." - [Source][1] diff --git a/packages/dnb-design-system-portal/src/pages/uilib/elements/other.md b/packages/dnb-design-system-portal/src/pages/uilib/elements/other.md index ab45c12a3c0..5fcba2a7ee1 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/elements/other.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/elements/other.md @@ -8,6 +8,4 @@ import CodeBlock from 'Tags/CodeBlock' Several commonly used HTML Elements are not included in the `dnb-ui-lib`. This decision is made by the DNB UX Team and relies on a principle to make UX design as good as possible, consistent and more thoughtful towards a broader customer target. -- For the `select` element, use e.g. [**Dropdown**](/uilib/components/dropdown) or [**Accordion**](/uilib/components/accordion) component. - -- For `checkbox` or `radio` inputs, use e.g. [**Toggle Button**](/uilib/components/button) or [**Switch**](/uilib/components/switch) component. +- For the `select` element, use the [**Dropdown**](/uilib/components/dropdown) component. diff --git a/packages/dnb-ui-lib/src/components/Checkbox.js b/packages/dnb-ui-lib/src/components/Checkbox.js new file mode 100644 index 00000000000..b6633ecef74 --- /dev/null +++ b/packages/dnb-ui-lib/src/components/Checkbox.js @@ -0,0 +1,14 @@ +/** + * ATTENTION: This file is auto generated by using "prepareTemplates". + * Do not change the content! + * + */ + +/** + * Library Index checkbox to autogenerate all the components and patterns + * Used by "prepareCheckboxs" + */ + +import Checkbox from './checkbox/Checkbox' +export * from './checkbox/Checkbox' +export default Checkbox diff --git a/packages/dnb-ui-lib/src/components/checkbox/Checkbox.js b/packages/dnb-ui-lib/src/components/checkbox/Checkbox.js new file mode 100644 index 00000000000..4ba7c896428 --- /dev/null +++ b/packages/dnb-ui-lib/src/components/checkbox/Checkbox.js @@ -0,0 +1,270 @@ +/** + * Web Checkbox Component + * + */ + +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import classnames from 'classnames' +import keycode from 'keycode' +import { + registerElement, + validateDOMAttributes, + dispatchCustomElementEvent +} from '../../shared/component-helper' +import FormLabel from '../form-label/FormLabel' +import FormStatus from '../form-status/FormStatus' + +const renderProps = { + on_change: null, + on_state_update: null +} + +export const propTypes = { + label: PropTypes.string, + title: PropTypes.string, + default_state: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), + checked: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), + disabled: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), + id: PropTypes.string, + status: PropTypes.string, + status_state: PropTypes.string, + status_animation: PropTypes.string, + value: PropTypes.string, + attributes: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), + readOnly: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), + class: PropTypes.string, + + /// React props + className: PropTypes.string, + children: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), + + // Web Component props + custom_element: PropTypes.object, + custom_method: PropTypes.func, + on_change: PropTypes.func, + on_state_update: PropTypes.func +} + +export const defaultProps = { + label: null, + title: null, + default_state: null, + checked: 'default', //we have to send this as a string + disabled: false, + id: null, + status: null, + status_state: 'error', + status_animation: null, + value: null, + attributes: null, + readOnly: false, + class: null, + + // React props + className: null, + children: null, + + // Web Component props + custom_element: null, + custom_method: null, + ...renderProps +} + +/** + * The checkbox component is our enhancement of the classic radio button. It acts like a checkbox. Example: On/off, yes/no. + */ +export default class Checkbox extends Component { + static tagName = 'dnb-checkbox' + static propTypes = propTypes + static defaultProps = defaultProps + static renderProps = renderProps + + static enableWebComponent() { + registerElement(Checkbox.tagName, Checkbox, defaultProps) + } + + static parseChecked = state => /true|on/.test(String(state)) + + static getDerivedStateFromProps(props, state) { + if (state._listenForPropChanges) { + if (state.hasDefaultState) { + state.checked = Checkbox.parseChecked(props.default_state) + state.hasDefaultState = false + } else if (props.checked !== 'default') { + state.checked = Checkbox.parseChecked(props.checked) + } + } + state._listenForPropChanges = true + + return state + } + + constructor(props) { + super(props) + this._refInput = React.createRef() + this._id = + props.id || `dnb-checkbox-${Math.round(Math.random() * 999)}` // cause we need an id anyway + this.state = { + _listenForPropChanges: true, + hasDefaultState: props.default_state !== null, + checked: Checkbox.parseChecked(props.default_state || props.checked) + } + this.helperParams = { onMouseDown: e => e.preventDefault() } + } + + shouldComponentUpdate(nextProps, nextState) { + if ( + Checkbox.parseChecked(this.props.checked) !== + Checkbox.parseChecked(nextProps.checked) + ) { + const { checked } = nextState + dispatchCustomElementEvent(this, 'on_state_update', { checked }) + } + return true + } + + onKeyDownHandler = event => { + switch (keycode(event)) { + case 'enter': + this.onChangeHandler(event) + break + } + } + + onChangeHandler = event => { + if (String(this.props.readOnly) === 'true') { + return event.preventDefault() + } + const checked = !this.state.checked + this.setState({ checked, _listenForPropChanges: false }) + dispatchCustomElementEvent(this, 'on_change', { checked, event }) + } + + onMouseOutHandler = () => { + // this way we keep the new state after the user changed the state, without getting the error state back vissually + if (this.props.status && this.props.status_state === 'error') { + return + } + if (this._refInput.current) { + this._refInput.current.blur() + } + } + + render() { + const { + value, + status, + status_state, + status_animation, + label, + title, + disabled, + readOnly, + className, + class: _className, + + id: _id, // eslint-disable-line + default_state: _default_state, // eslint-disable-line + checked: _checked, // eslint-disable-line + attributes, // eslint-disable-line + children, // eslint-disable-line + on_change, // eslint-disable-line + on_state_update, // eslint-disable-line + custom_method, // eslint-disable-line + custom_element, // eslint-disable-line + + ...rest + } = this.props + + const { checked } = this.state + + const id = this._id + const showStatus = status && status !== 'error' + + const classes = classnames( + 'dnb-checkbox', + showStatus && 'dnb-checkbox__form-status', + status && `dnb-checkbox__status--${status_state}`, + className, + _className + ) + + const inputParams = { + disabled, + checked, + onMouseOut: this.onMouseOutHandler, // for resetting the button to the default state + ...rest + } + + if (showStatus) { + inputParams['aria-describedby'] = id + '-status' + } + if (label) { + inputParams['aria-labelledby'] = id + '-label' + } + if (readOnly) { + inputParams['aria-readonly'] = inputParams.readOnly = true + } + + // also used for code markup simulation + validateDOMAttributes(this.props, inputParams) + + return ( + <> + {label && ( + + )} + + + + + + + + + {showStatus && ( + + )} + + + ) + } +} + +const CheckGfx = props => ( + + + +) diff --git a/packages/dnb-ui-lib/src/components/checkbox/__tests__/Checkbox.screenshot.test.js b/packages/dnb-ui-lib/src/components/checkbox/__tests__/Checkbox.screenshot.test.js new file mode 100644 index 00000000000..5e7f2f85205 --- /dev/null +++ b/packages/dnb-ui-lib/src/components/checkbox/__tests__/Checkbox.screenshot.test.js @@ -0,0 +1,79 @@ +/** + * Screenshot Test + * This file will not run on "test:staged" because we dont require any related files + */ + +import { + testPageScreenshot, + setupPageScreenshot +} from '../../../core/jest/jestSetupScreenshots' + +describe('Checkbox unchecked screenshot', () => { + setupPageScreenshot({ url: '/uilib/components/checkbox' }) + it('have to match checkbox in unchecked state', async () => { + const screenshot = await testPageScreenshot({ + selector: '[data-dnb-test="checkbox-default"] .dnb-checkbox' + }) + expect(screenshot).toMatchImageSnapshot() + }) + it('have to match checkbox in unchecked state with focus', async () => { + const screenshot = await testPageScreenshot({ + selector: '[data-dnb-test="checkbox-default"] .dnb-checkbox', + simulateSelector: + '[data-dnb-test="checkbox-default"] .dnb-checkbox__input', + simulate: 'focus' + }) + expect(screenshot).toMatchImageSnapshot() + }) + it('have to match checkbox in unchecked state with hover', async () => { + const screenshot = await testPageScreenshot({ + selector: '[data-dnb-test="checkbox-default"] .dnb-checkbox', + simulateSelector: + '[data-dnb-test="checkbox-default"] .dnb-checkbox__input', + simulate: 'hover' + }) + expect(screenshot).toMatchImageSnapshot() + }) +}) + +// NB: Because of focus simulation and screenshotElement.press('Tab') +// we have to run the two focus simulations in a seperate run each +describe('Checkbox checked screenshot', () => { + setupPageScreenshot({ url: '/uilib/components/checkbox' }) + it('have to match checkbox in checked state', async () => { + const screenshot = await testPageScreenshot({ + selector: '[data-dnb-test="checkbox-checked"] .dnb-checkbox' + }) + expect(screenshot).toMatchImageSnapshot() + }) + it('have to match checkbox in checked state with focus', async () => { + const screenshot = await testPageScreenshot({ + selector: '[data-dnb-test="checkbox-checked"] .dnb-checkbox', + simulateSelector: + '[data-dnb-test="checkbox-checked"] .dnb-checkbox__input', + simulate: 'focus' + }) + expect(screenshot).toMatchImageSnapshot() + }) + it('have to match checkbox in checked state with hover', async () => { + const screenshot = await testPageScreenshot({ + selector: '[data-dnb-test="checkbox-checked"] .dnb-checkbox', + simulateSelector: + '[data-dnb-test="checkbox-checked"] .dnb-checkbox__input', + simulate: 'hover' + }) + expect(screenshot).toMatchImageSnapshot() + }) + it('have to match disabled checkbox', async () => { + const screenshot = await testPageScreenshot({ + selector: '[data-dnb-test="checkbox-disabled"] .dnb-checkbox' + }) + expect(screenshot).toMatchImageSnapshot() + }) + it('have to match checkbox in error state', async () => { + const screenshot = await testPageScreenshot({ + selector: '[data-dnb-test="checkbox-error"] .dnb-checkbox' + }) + expect(screenshot).toMatchImageSnapshot() + }) +}) diff --git a/packages/dnb-ui-lib/src/components/checkbox/__tests__/Checkbox.test.js b/packages/dnb-ui-lib/src/components/checkbox/__tests__/Checkbox.test.js new file mode 100644 index 00000000000..19d2b668c12 --- /dev/null +++ b/packages/dnb-ui-lib/src/components/checkbox/__tests__/Checkbox.test.js @@ -0,0 +1,84 @@ +/** + * Component Test + * + */ + +import React from 'react' +import { + mount, + fakeProps, + axeComponent, + toJson, + loadScss +} from '../../../core/jest/jestSetup' +import Component from '../Checkbox' + +// just to make sure we re-run the test in watch mode due to changes in theese files +import _checkbox from '../style/_checkbox.scss' // eslint-disable-line +import dnb_checkbox from '../style/dnb-checkbox.scss' // eslint-disable-line +import dnb_checkbox_theme_ui from '../style/themes/dnb-checkbox-theme-ui.scss' // eslint-disable-line + +const props = fakeProps(require.resolve('../Checkbox'), { + optional: true +}) +props.status = null +props.readOnly = false + +describe('Checkbox component', () => { + // then test the state management + const Comp = mount() + + // mount compare the snapshot + it('have to match snapshot', () => { + expect(toJson(Comp)).toMatchSnapshot() + }) + + it('has correct state after "change" trigger', () => { + // default checked value has to be false + expect(Comp.state().checked).toBe(false) + + Comp.find('input').simulate('change') // we could send inn the event data structure like this: , { target: { checked: true } } + expect(Comp.state().checked).toBe(true) + + Comp.find('input').simulate('change') + expect(Comp.state().checked).toBe(false) + + // also check if getDerivedStateFromProps sets the state as expected + Comp.setProps({ checked: true }) + expect(Comp.state().checked).toBe(true) + + const value = 'new value' + Comp.setProps({ value }) + expect(Comp.find('input').props().value).toBe(value) + }) + + it('has a disabled attribute, once we set disabled to true', () => { + const Comp = mount() + Comp.setProps({ + disabled: true + }) + expect( + Comp.find('input') + .instance() + .hasAttribute('disabled') + ).toBe(true) + }) + + it('should validate with ARIA rules', async () => { + const Comp = mount() + expect(await axeComponent(Comp)).toHaveNoViolations() + }) +}) + +describe('Checkbox scss', () => { + it('have to match snapshot', () => { + const scss = loadScss(require.resolve('../style/dnb-checkbox.scss')) + expect(scss).toMatchSnapshot() + }) + it('have to match default theme snapshot', () => { + const scss = loadScss( + require.resolve('../style/themes/dnb-checkbox-theme-ui.scss') + ) + expect(scss).toMatchSnapshot() + }) +}) diff --git a/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/Checkbox.test.js.snap b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/Checkbox.test.js.snap new file mode 100644 index 00000000000..8889c579470 --- /dev/null +++ b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/Checkbox.test.js.snap @@ -0,0 +1,475 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Checkbox component have to match snapshot 1`] = ` + + + + + + + + + + + + + + + + + + +`; + +exports[`Checkbox scss have to match default theme snapshot 1`] = ` +"/* +* Checkbox theme +* +*/ +/** + * This file is only used to make themes independent + * so that they can get imported individually, without the core styles + * + */ +/* + * Utilities + */ +.dnb-checkbox { + /* + * When checkboxed OFF + * aka when the checkbox is not :checked + */ + /* + * When checkboxed ON + * aka when the checkbox is :checked + */ + /* + * On disabled + * + */ + /* + * On hover + * + */ + /* + * On active + * + */ + /* stylelint-disable */ + /* stylelint-enable */ + /* + * On focus + * + */ + /* stylelint-disable */ + /* stylelint-enable */ + /* + * On error state + * + */ } + .dnb-checkbox__input:not(:checked) ~ .dnb-checkbox__button { + background-color: var(--color-white); + border-color: var(--color-sea-green-alt); } + .dnb-checkbox__input:checked ~ .dnb-checkbox__button { + background-color: var(--color-sea-green-alt); } + .dnb-checkbox__input[disabled] ~ .dnb-checkbox__button { + border-color: var(--color-mint-green-50); } + .dnb-checkbox__input[disabled]:checked ~ .dnb-checkbox__button { + border-color: transparent; + background-color: var(--color-sea-green-alt-30); } + .dnb-checkbox__input:not([disabled]):not(:focus):hover ~ .dnb-checkbox__button { + background-color: var(--color-mint-green-50); } + .dnb-checkbox__input:not([disabled]):not(:focus):checked:hover ~ .dnb-checkbox__button { + border-color: transparent; } + .dnb-checkbox__input:not([disabled]):not(:focus):hover ~ .dnb-checkbox__gfx { + color: var(--color-sea-green-alt); } + .dnb-checkbox__input:not([disabled]):active ~ .dnb-checkbox__button { + background-color: var(--color-mint-green-50); + border-color: transparent; } + .dnb-checkbox__input:not([disabled]):active ~ .dnb-checkbox__gfx { + color: var(--color-white); } + html[data-whatinput='keyboard'] .dnb-checkbox__input:not([disabled]):focus ~ .dnb-checkbox__button { + border: none; + background-color: var(--color-mint-green-50); } + html[data-whatinput='keyboard'] .dnb-checkbox__input:not([disabled]):focus ~ .dnb-checkbox__gfx { + color: var(--color-sea-green-alt); } + .dnb-checkbox__input:not([disabled]):focus ~ .dnb-checkbox__button .dnb-checkbox__focus, + .dnb-checkbox__input:not([disabled]):active ~ .dnb-checkbox__button .dnb-checkbox__focus { + display: block; } + .dnb-checkbox__input:not([disabled]):not(:checked):focus ~ .dnb-checkbox__button, + .dnb-checkbox__input:not([disabled]):not(:checked):active ~ .dnb-checkbox__button { + background-color: var(--color-mint-green-50); } + .dnb-checkbox__status--error .dnb-checkbox__input:not([disabled]):not(:focus):not(:active) ~ .dnb-checkbox__button { + border: none; } + .dnb-checkbox__status--error .dnb-checkbox__input:not([disabled]):not(:focus):not(:active) ~ .dnb-checkbox__button .dnb-checkbox__focus { + display: block; + box-shadow: 0 0 0 0.125rem var(--color-cherry-red); + border-color: transparent; } + .dnb-checkbox__status--error .dnb-checkbox__input:not([disabled]):not(:focus):hover ~ .dnb-checkbox__button { + border-color: var(--color-cherry-red); + background-color: var(--color-cherry-red-80); } + .dnb-checkbox__status--error .dnb-checkbox__input:not([disabled]):not(:focus):not(:active):not(:hover) ~ .dnb-checkbox__button { + border-color: var(--color-cherry-red-80); } + .dnb-checkbox__status--error .dnb-checkbox__input:not([disabled]):not(:focus):not(:active):not(:hover):checked ~ .dnb-checkbox__button { + background-color: var(--color-cherry-red); } + .dnb-checkbox__status--error .dnb-checkbox__input:not([disabled]):not(:focus):hover ~ .dnb-checkbox__gfx { + color: var(--color-cherry-red); } + .dnb-checkbox__status--error .dnb-checkbox__input:not([disabled]):not(:focus):not(:active):not(:hover) ~ .dnb-checkbox__gfx { + color: var(--color-cherry-red-80); } + .dnb-checkbox > .dnb-form-status { + transform: translateY(0.1875rem); } +" +`; + +exports[`Checkbox scss have to match snapshot 1`] = ` +"/* +* DNB Checkbox +* +*/ +/** + * This file is only used to make components independent + * so that they can get imported individually, without the core styles + * + */ +/* + * Utilities + */ +/* + * Scopes + * + */ +/* + * Document Reset + * + */ +/* +* DNB FormLabel +* +*/ +.dnb-form-label { + font-family: var(--font-family-default); + font-weight: var(--font-weight-default); + font-size: 1rem; + font-style: normal; + line-height: 1.5rem; + color: var(--color-black-80, #333); + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + font-variant-numeric: lining-nums; + font-feature-settings: \\"lnum\\"; + /** + * 1. Remove repeating backgrounds in all browsers (opinionated). + * 2. Add border box sizing in all browsers (opinionated). + */ + /** + * 1. Add text decoration inheritance in all browsers (opinionated). + * 2. Add vertical alignment inheritance in all browsers (opinionated). + */ + margin: 0; + padding: 0; } + .dnb-form-label *, + .dnb-form-label ::before, + .dnb-form-label ::after { + background-repeat: no-repeat; + /* 1 */ + box-sizing: border-box; + /* 2 */ } + .dnb-form-label ::before, + .dnb-form-label ::after { + text-decoration: inherit; + /* 1 */ + vertical-align: inherit; + /* 2 */ } + +/* + * FormLabel component + * + */ +.dnb-form-label { + user-select: none; + margin-right: 1rem; + display: inline-block; + vertical-align: baseline; + cursor: pointer; + color: inherit; + width: auto; + white-space: nowrap; } + .dnb-form-label--vertical { + margin-right: 0; + margin-top: 0; } + .dnb-form-label[for]:not([disabled]):hover { + color: var(--color-sea-green); } + .dnb-form-label[disabled] { + cursor: not-allowed; } + +/* +* DNB FormStatus +* +*/ +.dnb-form-status { + font-family: var(--font-family-default); + font-weight: var(--font-weight-default); + font-size: 1rem; + font-style: normal; + line-height: 1.5rem; + color: var(--color-black-80, #333); + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + font-variant-numeric: lining-nums; + font-feature-settings: \\"lnum\\"; + /** + * 1. Remove repeating backgrounds in all browsers (opinionated). + * 2. Add border box sizing in all browsers (opinionated). + */ + /** + * 1. Add text decoration inheritance in all browsers (opinionated). + * 2. Add vertical alignment inheritance in all browsers (opinionated). + */ + margin: 0; + padding: 0; } + .dnb-form-status *, + .dnb-form-status ::before, + .dnb-form-status ::after { + background-repeat: no-repeat; + /* 1 */ + box-sizing: border-box; + /* 2 */ } + .dnb-form-status ::before, + .dnb-form-status ::after { + text-decoration: inherit; + /* 1 */ + vertical-align: inherit; + /* 2 */ } + +/* + * FormStatus component + * + */ +.dnb-form-status { + width: auto; + display: flex; + justify-content: flex-start; + align-items: center; + min-height: var(--input-height); + border-radius: var(--input-border-radius); + line-height: 0.5rem; } + .dnb-form-status--text { + padding: calc(0.5rem / 2) 1rem; + cursor: text; + color: var(--color-emerald-green); + line-height: 1.5rem; } + .dnb-icon + .dnb-form-status--text { + padding-left: 0.5rem; } + .dnb-form-status > .dnb-icon { + display: flex; + justify-content: center; + align-items: center; + width: 1.5em; + height: 1.5em; + margin-left: 0.5rem; + color: inherit; + font-size: 1rem; + border-radius: 50%; + border: 1px solid; + border-color: currentColor; } + .dnb-form-status[hidden] { + display: none; } + .dnb-form-status--fade-in { + height: 0; + opacity: 0; + animation: fade-in 600ms ease-out 1 200ms forwards; } + +@keyframes fade-in { + from { + opacity: 0; + height: 0; } + to { + opacity: 1; + height: var(--input-height); } } + +.dnb-checkbox { + font-family: var(--font-family-default); + font-weight: var(--font-weight-default); + font-size: 1rem; + font-style: normal; + line-height: 1.5rem; + color: var(--color-black-80, #333); + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + font-variant-numeric: lining-nums; + font-feature-settings: \\"lnum\\"; + /** + * 1. Remove repeating backgrounds in all browsers (opinionated). + * 2. Add border box sizing in all browsers (opinionated). + */ + /** + * 1. Add text decoration inheritance in all browsers (opinionated). + * 2. Add vertical alignment inheritance in all browsers (opinionated). + */ + margin: 0; + padding: 0; } + .dnb-checkbox *, + .dnb-checkbox ::before, + .dnb-checkbox ::after { + background-repeat: no-repeat; + /* 1 */ + box-sizing: border-box; + /* 2 */ } + .dnb-checkbox ::before, + .dnb-checkbox ::after { + text-decoration: inherit; + /* 1 */ + vertical-align: inherit; + /* 2 */ } + +/* +* Checkbox component +* +*/ +:root { + --checkbox-height: 1.5rem; + --checkbox-width: 1.5rem; + --checkbox-border-width: 0.125rem; } + +.dnb-checkbox { + user-select: none; + display: inline-flex; + flex-direction: column; + align-items: flex-start; + vertical-align: middle; + width: auto; + margin: 0; + padding: 0; + color: var(--color-white); + /* + * When checkbox is OFF + * aka when the checkbox is not :checked + */ + /* + * When checkbox is ON + * aka when the checkbox is :checked + */ } + .dnb-checkbox__shell { + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: var(--checkbox-height); + height: var(--checkbox-height); + transform: translateY(-0.0625rem); } + label + .dnb-checkbox[class*='__form-status'] { + vertical-align: top; } + .dnb-checkbox__focus, .dnb-checkbox__button, .dnb-checkbox__gfx { + position: absolute; + z-index: 4; + border-radius: 0.25rem; } + .dnb-checkbox__button { + border: var(--checkbox-border-width) solid transparent; } + .dnb-checkbox__focus { + display: none; + outline: none; } + html[data-whatinput='keyboard'] .dnb-checkbox__focus { + box-shadow: 0 0 0 0.125rem var(--color-emerald-green); + border-color: transparent; } + .dnb-checkbox__focus, .dnb-checkbox__button { + width: calc(var(--checkbox-width) - 0.25rem); + height: calc(var(--checkbox-height) - 0.25rem); } + .dnb-checkbox__gfx { + position: absolute; + width: var(--checkbox-height); + height: var(--checkbox-height); + transition: opacity 200ms ease-out, transform 200ms ease-out; + fill: currentColor; + shape-rendering: geometricPrecision; } + .dnb-checkbox__input:not(:checked) ~ .dnb-checkbox__gfx { + opacity: 0; + transform: scale(0.8); } + .dnb-checkbox__input:checked ~ .dnb-checkbox__gfx { + opacity: 1; + transform: scale(1); } + .dnb-checkbox__input { + opacity: 0; + position: absolute; + top: 0; + left: 0; + z-index: 5; + width: var(--checkbox-width); + height: var(--checkbox-height); + margin: 0; + padding: 0; + border: 0; } + .dnb-checkbox__input:not([disabled]) { + cursor: pointer; } + .dnb-checkbox > .dnb-form-status { + margin-top: 0.125rem; } +" +`; diff --git a/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-checkbox-in-checked-state-1-cd57d.snap.png b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-checkbox-in-checked-state-1-cd57d.snap.png new file mode 100644 index 00000000000..cae74d9e643 Binary files /dev/null and b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-checkbox-in-checked-state-1-cd57d.snap.png differ diff --git a/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-checkbox-in-checked-state-with-focus-1-68369.snap.png b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-checkbox-in-checked-state-with-focus-1-68369.snap.png new file mode 100644 index 00000000000..ea6a7083eff Binary files /dev/null and b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-checkbox-in-checked-state-with-focus-1-68369.snap.png differ diff --git a/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-checkbox-in-checked-state-with-hover-1-7fa0a.snap.png b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-checkbox-in-checked-state-with-hover-1-7fa0a.snap.png new file mode 100644 index 00000000000..8f5a76781ec Binary files /dev/null and b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-checkbox-in-checked-state-with-hover-1-7fa0a.snap.png differ diff --git a/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-checkbox-in-error-state-1-e6684.snap.png b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-checkbox-in-error-state-1-e6684.snap.png new file mode 100644 index 00000000000..3a6ad5d0b41 Binary files /dev/null and b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-checkbox-in-error-state-1-e6684.snap.png differ diff --git a/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-disabled-checkbox-1-b6ffd.snap.png b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-disabled-checkbox-1-b6ffd.snap.png new file mode 100644 index 00000000000..f9f52389683 Binary files /dev/null and b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-checked-screenshot-have-to-match-disabled-checkbox-1-b6ffd.snap.png differ diff --git a/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-unchecked-screenshot-have-to-match-checkbox-in-unchecked-state-1-24f56.snap.png b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-unchecked-screenshot-have-to-match-checkbox-in-unchecked-state-1-24f56.snap.png new file mode 100644 index 00000000000..ea25867655f Binary files /dev/null and b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-unchecked-screenshot-have-to-match-checkbox-in-unchecked-state-1-24f56.snap.png differ diff --git a/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-unchecked-screenshot-have-to-match-checkbox-in-unchecked-state-with-focus-1-294d3.snap.png b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-unchecked-screenshot-have-to-match-checkbox-in-unchecked-state-with-focus-1-294d3.snap.png new file mode 100644 index 00000000000..782b36688f0 Binary files /dev/null and b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-unchecked-screenshot-have-to-match-checkbox-in-unchecked-state-with-focus-1-294d3.snap.png differ diff --git a/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-unchecked-screenshot-have-to-match-checkbox-in-unchecked-state-with-hover-1-b3d7b.snap.png b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-unchecked-screenshot-have-to-match-checkbox-in-unchecked-state-with-hover-1-b3d7b.snap.png new file mode 100644 index 00000000000..f1c92d8f974 Binary files /dev/null and b/packages/dnb-ui-lib/src/components/checkbox/__tests__/__snapshots__/checkbox-screenshot-test-js-checkbox-unchecked-screenshot-have-to-match-checkbox-in-unchecked-state-with-hover-1-b3d7b.snap.png differ diff --git a/packages/dnb-ui-lib/src/components/checkbox/index.js b/packages/dnb-ui-lib/src/components/checkbox/index.js new file mode 100644 index 00000000000..ec92ac79f76 --- /dev/null +++ b/packages/dnb-ui-lib/src/components/checkbox/index.js @@ -0,0 +1,8 @@ +/** + * Component Entry + * + */ + +import Checkbox from './Checkbox' +export default Checkbox +export * from './Checkbox' diff --git a/packages/dnb-ui-lib/src/components/checkbox/style.js b/packages/dnb-ui-lib/src/components/checkbox/style.js new file mode 100644 index 00000000000..0c4abe21fbe --- /dev/null +++ b/packages/dnb-ui-lib/src/components/checkbox/style.js @@ -0,0 +1,6 @@ +/** + * Web Style Import + * + */ + +import './style/dnb-checkbox.scss' diff --git a/packages/dnb-ui-lib/src/components/checkbox/style/_checkbox.scss b/packages/dnb-ui-lib/src/components/checkbox/style/_checkbox.scss new file mode 100644 index 00000000000..69331cf1a04 --- /dev/null +++ b/packages/dnb-ui-lib/src/components/checkbox/style/_checkbox.scss @@ -0,0 +1,118 @@ +/* +* Checkbox component +* +*/ + +:root { + --checkbox-height: 1.5rem; + --checkbox-width: 1.5rem; + --checkbox-border-width: 0.125rem; +} + +.dnb-checkbox { + user-select: none; + + display: inline-flex; + flex-direction: column; + align-items: flex-start; + vertical-align: middle; + + width: auto; + + margin: 0; + padding: 0; + + color: var(--color-white); + + &__shell { + position: relative; + + display: flex; + align-items: center; + justify-content: center; + + width: var(--checkbox-height); + height: var(--checkbox-height); + + // vertical alignment + transform: translateY( + -0.0625rem + ); // ajust the shell to the inherited line-height for 1px + } + label + &[class*='__form-status'] { + vertical-align: top; + } + + &__focus, + &__button, + &__gfx { + position: absolute; + z-index: 4; + + border-radius: 0.25rem; + } + &__button { + border: var(--checkbox-border-width) solid transparent; + } + &__focus { + display: none; + @include fakeFocus(); + } + &__focus, + &__button { + width: calc(var(--checkbox-width) - 0.25rem); + height: calc(var(--checkbox-height) - 0.25rem); + } + &__gfx { + position: absolute; + width: var(--checkbox-height); + height: var(--checkbox-height); + + transition: opacity 200ms ease-out, transform 200ms ease-out; + fill: currentColor; + shape-rendering: geometricPrecision; + } + + /* + * When checkbox is OFF + * aka when the checkbox is not :checked + */ + &__input:not(:checked) ~ &__gfx { + opacity: 0; + transform: scale(0.8); + } + + /* + * When checkbox is ON + * aka when the checkbox is :checked + */ + &__input:checked ~ &__gfx { + opacity: 1; + transform: scale(1); + } + + &__input { + opacity: 0; + + position: absolute; + top: 0; + left: 0; + z-index: 5; + + width: var(--checkbox-width); + height: var(--checkbox-height); + + margin: 0; + padding: 0; + + border: 0; + } + + &__input:not([disabled]) { + cursor: pointer; + } + + > .dnb-form-status { + margin-top: 0.125rem; + } +} diff --git a/packages/dnb-ui-lib/src/components/checkbox/style/dnb-checkbox.scss b/packages/dnb-ui-lib/src/components/checkbox/style/dnb-checkbox.scss new file mode 100644 index 00000000000..da6105549ea --- /dev/null +++ b/packages/dnb-ui-lib/src/components/checkbox/style/dnb-checkbox.scss @@ -0,0 +1,14 @@ +/* +* DNB Checkbox +* +*/ + +@import '../../../style/components/imports.scss'; +@import '../../form-label/style/dnb-form-label.scss'; +@import '../../form-status/style/dnb-form-status.scss'; + +.dnb-checkbox { + @include componentReset(); +} + +@import './_checkbox.scss'; diff --git a/packages/dnb-ui-lib/src/components/checkbox/style/index.js b/packages/dnb-ui-lib/src/components/checkbox/style/index.js new file mode 100644 index 00000000000..45a1aaa4913 --- /dev/null +++ b/packages/dnb-ui-lib/src/components/checkbox/style/index.js @@ -0,0 +1,6 @@ +/** + * Web Style Import + * + */ + +import './dnb-checkbox.scss' diff --git a/packages/dnb-ui-lib/src/components/checkbox/style/themes/dnb-checkbox-theme-ui.scss b/packages/dnb-ui-lib/src/components/checkbox/style/themes/dnb-checkbox-theme-ui.scss new file mode 100644 index 00000000000..2dad6ffc9da --- /dev/null +++ b/packages/dnb-ui-lib/src/components/checkbox/style/themes/dnb-checkbox-theme-ui.scss @@ -0,0 +1,138 @@ +/* +* Checkbox theme +* +*/ + +@import '../../../../style/themes/imports.scss'; + +.dnb-checkbox { + /* + * When checkboxed OFF + * aka when the checkbox is not :checked + */ + &__input:not(:checked) ~ &__button { + background-color: var(--color-white); + border-color: var(--color-sea-green-alt); + } + + /* + * When checkboxed ON + * aka when the checkbox is :checked + */ + &__input:checked ~ &__button { + background-color: var(--color-sea-green-alt); + } + + /* + * On disabled + * + */ + &__input[disabled] ~ &__button { + border-color: var(--color-mint-green-50); + } + &__input[disabled]:checked ~ &__button { + border-color: transparent; + background-color: var(--color-sea-green-alt-30); + } + + /* + * On hover + * + */ + &__input:not([disabled]):not(:focus):hover ~ &__button { + background-color: var(--color-mint-green-50); + } + &__input:not([disabled]):not(:focus):checked:hover ~ &__button { + border-color: transparent; + } + &__input:not([disabled]):not(:focus):hover ~ &__gfx { + color: var(--color-sea-green-alt); + } + + /* + * On active + * + */ + /* stylelint-disable */ + &__input:not([disabled]):active ~ &__button { + background-color: var(--color-mint-green-50); + border-color: transparent; + } + &__input:not([disabled]):active ~ &__gfx { + color: var(--color-white); + } + /* stylelint-enable */ + + /* + * On focus + * + */ + /* stylelint-disable */ + &__input:not([disabled]):focus ~ &__button { + html[data-whatinput='keyboard'] & { + border: none; + background-color: var(--color-mint-green-50); + } + } + &__input:not([disabled]):focus ~ &__gfx { + html[data-whatinput='keyboard'] & { + color: var(--color-sea-green-alt); + } + } + &__input:not([disabled]):focus ~ &__button &__focus, + &__input:not([disabled]):active ~ &__button &__focus { + display: block; + } + &__input:not([disabled]):not(:checked):focus ~ &__button, + &__input:not([disabled]):not(:checked):active ~ &__button { + background-color: var(--color-mint-green-50); + } + /* stylelint-enable */ + + /* + * On error state + * + */ + // change button color + // fake border outside + &__status--error + &__input:not([disabled]):not(:focus):not(:active) + ~ &__button { + border: none; + } + &__status--error + &__input:not([disabled]):not(:focus):not(:active) + ~ &__button + &__focus { + display: block; + @include fakeBorder(var(--color-cherry-red), $focusRingWidth); + } + &__status--error &__input:not([disabled]):not(:focus):hover ~ &__button { + border-color: var(--color-cherry-red); + background-color: var(--color-cherry-red-80); + } + &__status--error + &__input:not([disabled]):not(:focus):not(:active):not(:hover) + ~ &__button { + border-color: var(--color-cherry-red-80); + } + &__status--error + &__input:not([disabled]):not(:focus):not(:active):not(:hover):checked + ~ &__button { + background-color: var(--color-cherry-red); + } + // check gfx color + &__status--error &__input:not([disabled]):not(:focus):hover ~ &__gfx { + color: var(--color-cherry-red); + } + &__status--error + &__input:not([disabled]):not(:focus):not(:active):not(:hover) + ~ &__gfx { + color: var(--color-cherry-red-80); + } + + // ajust the form-status to the inner border for 3px + > .dnb-form-status { + transform: translateY(0.1875rem); + } +} diff --git a/packages/dnb-ui-lib/src/components/checkbox/style/themes/ui.js b/packages/dnb-ui-lib/src/components/checkbox/style/themes/ui.js new file mode 100644 index 00000000000..7d92253a873 --- /dev/null +++ b/packages/dnb-ui-lib/src/components/checkbox/style/themes/ui.js @@ -0,0 +1,6 @@ +/** + * Imports the default theme + * + */ + +import './dnb-checkbox-theme-ui.scss' diff --git a/packages/dnb-ui-lib/src/components/checkbox/web-component.js b/packages/dnb-ui-lib/src/components/checkbox/web-component.js new file mode 100644 index 00000000000..68737cc2ae4 --- /dev/null +++ b/packages/dnb-ui-lib/src/components/checkbox/web-component.js @@ -0,0 +1,9 @@ +/** + * This file is used to enable Web Components + * + */ + +export * from './index' +import { enableWebComponents } from '../index' + +enableWebComponents() diff --git a/packages/dnb-ui-lib/src/components/index.js b/packages/dnb-ui-lib/src/components/index.js index db2433e4c78..4595f72f8b4 100644 --- a/packages/dnb-ui-lib/src/components/index.js +++ b/packages/dnb-ui-lib/src/components/index.js @@ -11,6 +11,7 @@ // import all the aviable components import Button from './button/Button' +import Checkbox from './checkbox/Checkbox' import DatePicker from './date-picker/DatePicker' import Dropdown from './dropdown/Dropdown' import FormLabel from './form-label/FormLabel' @@ -32,6 +33,7 @@ import Tabs from './tabs/Tabs' // define / export all the aviable components export { Button, + Checkbox, DatePicker, Dropdown, FormLabel, diff --git a/packages/dnb-ui-lib/src/components/lib.js b/packages/dnb-ui-lib/src/components/lib.js index 360119f5651..9e08ddac1b5 100644 --- a/packages/dnb-ui-lib/src/components/lib.js +++ b/packages/dnb-ui-lib/src/components/lib.js @@ -13,6 +13,7 @@ import { registerElement } from '../shared/component-helper' // import all the aviable components import Button from './button/Button' +import Checkbox from './checkbox/Checkbox' import DatePicker from './date-picker/DatePicker' import Dropdown from './dropdown/Dropdown' import FormLabel from './form-label/FormLabel' @@ -34,6 +35,7 @@ import Tabs from './tabs/Tabs' // define / export all the aviable components export { Button, + Checkbox, DatePicker, Dropdown, FormLabel, @@ -56,6 +58,7 @@ export { export const getComponents = () => { return { Button, + Checkbox, DatePicker, Dropdown, FormLabel, diff --git a/packages/dnb-ui-lib/src/components/switch/__tests__/Switch.screenshot.test.js b/packages/dnb-ui-lib/src/components/switch/__tests__/Switch.screenshot.test.js index 3c8d33344bb..61513a7603d 100644 --- a/packages/dnb-ui-lib/src/components/switch/__tests__/Switch.screenshot.test.js +++ b/packages/dnb-ui-lib/src/components/switch/__tests__/Switch.screenshot.test.js @@ -70,4 +70,10 @@ describe('Switch checked screenshot', () => { }) expect(screenshot).toMatchImageSnapshot() }) + it('have to match switch in error state', async () => { + const screenshot = await testPageScreenshot({ + selector: '[data-dnb-test="switch-error"] .dnb-switch' + }) + expect(screenshot).toMatchImageSnapshot() + }) }) diff --git a/packages/dnb-ui-lib/src/components/switch/__tests__/__snapshots__/switch-screenshot-test-js-switch-checked-screenshot-have-to-match-switch-in-error-state-1-83a9c.snap.png b/packages/dnb-ui-lib/src/components/switch/__tests__/__snapshots__/switch-screenshot-test-js-switch-checked-screenshot-have-to-match-switch-in-error-state-1-83a9c.snap.png new file mode 100644 index 00000000000..ded66bb439f Binary files /dev/null and b/packages/dnb-ui-lib/src/components/switch/__tests__/__snapshots__/switch-screenshot-test-js-switch-checked-screenshot-have-to-match-switch-in-error-state-1-83a9c.snap.png differ diff --git a/packages/dnb-ui-lib/src/index.js b/packages/dnb-ui-lib/src/index.js index ed45e4b4bc4..cd10e712fd7 100644 --- a/packages/dnb-ui-lib/src/index.js +++ b/packages/dnb-ui-lib/src/index.js @@ -11,6 +11,7 @@ // import all the aviable components and patterns import Button from './components/button/Button' +import Checkbox from './components/checkbox/Checkbox' import DatePicker from './components/date-picker/DatePicker' import Dropdown from './components/dropdown/Dropdown' import FormLabel from './components/form-label/FormLabel' @@ -52,6 +53,7 @@ import Ul from './elements/Ul' // define / export all the aviable components export { Button, + Checkbox, DatePicker, Dropdown, FormLabel, diff --git a/packages/dnb-ui-lib/src/style/dnb-ui-components.scss b/packages/dnb-ui-lib/src/style/dnb-ui-components.scss index 3630765b274..d51175976f1 100644 --- a/packages/dnb-ui-lib/src/style/dnb-ui-components.scss +++ b/packages/dnb-ui-lib/src/style/dnb-ui-components.scss @@ -6,6 +6,7 @@ @import './core/utilities.scss'; @import '../components/button/style/_button.scss'; +@import '../components/checkbox/style/_checkbox.scss'; @import '../components/date-picker/style/_date-picker.scss'; @import '../components/dropdown/style/_dropdown.scss'; @import '../components/form-label/style/_form-label.scss'; diff --git a/packages/dnb-ui-lib/src/style/themes/theme-ui/dnb-theme-ui.scss b/packages/dnb-ui-lib/src/style/themes/theme-ui/dnb-theme-ui.scss index 9a4421d30e0..5999ff69a8c 100644 --- a/packages/dnb-ui-lib/src/style/themes/theme-ui/dnb-theme-ui.scss +++ b/packages/dnb-ui-lib/src/style/themes/theme-ui/dnb-theme-ui.scss @@ -25,6 +25,7 @@ */ @import '../../../components/button/style/themes/dnb-button-theme-ui.scss'; +@import '../../../components/checkbox/style/themes/dnb-checkbox-theme-ui.scss'; @import '../../../components/date-picker/style/themes/dnb-date-picker-theme-ui.scss'; @import '../../../components/dropdown/style/themes/dnb-dropdown-theme-ui.scss'; @import '../../../components/form-label/style/themes/dnb-form-label-theme-ui.scss'; diff --git a/packages/dnb-ui-lib/stories/componentsStories.js b/packages/dnb-ui-lib/stories/componentsStories.js index cecaa8ffafc..5fd0c01d558 100644 --- a/packages/dnb-ui-lib/stories/componentsStories.js +++ b/packages/dnb-ui-lib/stories/componentsStories.js @@ -19,6 +19,7 @@ import { FormLabel, Dropdown, Switch, + Checkbox, Logo, StepIndicator, ProgressIndicator, @@ -778,6 +779,58 @@ stories.push([ ) ]) +stories.push([ + 'Checkbox', + () => ( + + + +

+ Text: Unchecked: + +

+
+ + { + console.log('on_change', checked) + }} + /> + + + { + console.log('on_change', checked) + }} + /> + + + + + + + + + + + + + +
+
+ ) +]) const exampleTabsContent = { first: () =>

First

,