diff --git a/.drone.yml b/.drone.yml index 1a4b8015b76..7f22aebb759 100644 --- a/.drone.yml +++ b/.drone.yml @@ -10,7 +10,7 @@ steps: - name: setup image: tujoworker/docker-node-puppeteer commands: - - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.13.0 + - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.16.0 - export PATH="$HOME/.yarn/bin:$PATH" - name: dependencies audit diff --git a/CHANGELOG.md b/CHANGELOG.md index 4853f6e1e2d..9e6224677d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,14 @@ -## May, 27. 2019 +## June, 5. 2019 + +- New corner radius (border-radius) on `Dropdown` and `DatePicker`: 4px (0.25rem) + +## June, 3. 2019 - New component in the `dnb-ui-lib`: [Textarea](/uilib/components/textarea). Got also a wider corner radius by `16px (1rem)`. ## May, 27. 2019 -- New component in the `dnb-ui-lib`: [Checkbox](/uilib/components/checkbox) and [Radio](/uilib/components/radio) button +- New components in the `dnb-ui-lib`: [Checkbox](/uilib/components/checkbox) and [Radio](/uilib/components/radio) button ## May, 19. 2019 diff --git a/package.json b/package.json index 5fb84a905db..513d6175f7b 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "test-ci-screenshots": "yarn workspace dnb-ui-lib test-ci-screenshots" }, "devDependencies": { - "husky": "^1.3.1" + "husky": "^2.3.0" }, "release": { "analyzeCommits": "simple-commit-message" diff --git a/packages/dnb-design-system-portal/gatsby-config.js b/packages/dnb-design-system-portal/gatsby-config.js index a16e95ce9d1..67d51d12356 100644 --- a/packages/dnb-design-system-portal/gatsby-config.js +++ b/packages/dnb-design-system-portal/gatsby-config.js @@ -53,8 +53,8 @@ module.exports = { { resolve: 'gatsby-remark-images', options: { - maxWidth: 1024, - showCaptions: true + maxWidth: 1024 + // showCaptions: true // sizeByPixelDensity: true // linkImagesToOriginal: true // wrapperStyle: {} diff --git a/packages/dnb-design-system-portal/gatsby-node.js b/packages/dnb-design-system-portal/gatsby-node.js index a04d6a2a51c..1ed6f6d1b1a 100644 --- a/packages/dnb-design-system-portal/gatsby-node.js +++ b/packages/dnb-design-system-portal/gatsby-node.js @@ -93,7 +93,7 @@ exports.onCreateNode = ({ node, getNode, actions }) => { createNodeField({ name: 'slug', node, - value: `/${slug}` + value: slug }) createNodeField({ diff --git a/packages/dnb-design-system-portal/package.json b/packages/dnb-design-system-portal/package.json index 4ab473748a6..63058f57b4f 100644 --- a/packages/dnb-design-system-portal/package.json +++ b/packages/dnb-design-system-portal/package.json @@ -65,12 +65,12 @@ "ci-info": "^2.0.0", "classnames": "^2.2.6", "clean-html": "^1.5.0", - "color": "^3.1.1", + "color": "^3.1.2", "cross-env": "^5.2.0", "del": "^4.1.1", "emotion": "^10.0.9", - "enzyme": "^3.9.0", - "enzyme-adapter-react-16": "^1.13.2", + "enzyme": "^3.10.0", + "enzyme-adapter-react-16": "^1.14.0", "enzyme-to-json": "^3.3.5", "eslint": "^5.16.0", "eslint-plugin-import": "^2.17.3", @@ -78,7 +78,7 @@ "eslint-plugin-react": "^7.13.0", "front-matter": "^3.0.2", "fs-extra": "^8.0.1", - "gatsby": "^2.7.1", + "gatsby": "^2.8.2", "gatsby-link": "^2.1.1", "gatsby-mdx": "^0.6.3", "gatsby-plugin-catch-links": "^2.0.15", @@ -88,9 +88,9 @@ "gatsby-plugin-postcss": "^2.0.7", "gatsby-plugin-react-helmet": "^3.0.12", "gatsby-plugin-sass": "^2.0.11", - "gatsby-plugin-sharp": "^2.1.1", - "gatsby-remark-images": "^3.0.13", - "gatsby-source-filesystem": "^2.0.37", + "gatsby-plugin-sharp": "^2.1.3", + "gatsby-remark-images": "^3.0.14", + "gatsby-source-filesystem": "^2.0.38", "gh-pages": "^2.0.1", "github-slugger": "^1.2.1", "jest": "^24.8.0", @@ -114,7 +114,7 @@ "react-markdown": "^4.0.8", "stylelint": "^10.0.1", "stylelint-config-styled-components": "^0.1.1", - "stylelint-processor-styled-components": "^1.7.0" + "stylelint-processor-styled-components": "^1.8.0" }, "buildVersion": "[LOCAL BUILD]" } 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 index a003db220e7..e11157c913e 100644 --- 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 @@ -2,12 +2,14 @@ draft: true --- -| Properties | Description | -| --------------- | ------------------------------------------------------------------------------------------------------- | -| `checked` | _(optional)_ determine whether the checkbox is checked or not. Default will be `false`. | -| `default_state` | _(optional)_ boolean value. The state of the checkbox. Defaults to `false`. Set to `true` if otherwise. | -| `title` | _(optional)_ the `title` of the input - describing it a bit further for accessibility reasons. | -| `label` | _(optional)_ use either the `label` property or provide custom one. | -| `status` | _(optional)_ uses the `form-status` component to show failure messages. | -| `id` | _(optional)_ the `id` of the input. Default will be a random id. | -| `disabled` | _(optional)_ to disable/enable the checkbox. | +| Properties | Description | +| ---------------- | -------------------------------------------------------------------------------------------------------------- | +| `checked` | _(optional)_ determine whether the checkbox is checked or not. Default will be `false`. | +| `default_state` | _(optional)_ boolean value. The state of the checkbox. Defaults to `false`. Set to `true` if otherwise. | +| `title` | _(optional)_ the `title` of the input - describing it a bit further for accessibility reasons. | +| `label` | _(optional)_ use either the `label` property or provide custom one. | +| `label_position` | _(optional)_ defines the position of the `label`. Use either `left` or `right`. Defaults to `right`. | +| `id` | _(optional)_ the `id` of the input. Default will be a random id. | +| `disabled` | _(optional)_ to disable/enable the checkbox. | +| `status` | _(optional)_ text with a status message. The style defaults to an error message. | +| `status_state` | _(optional)_ defines the state of the status. Currently are two statuses `[error, info]`. Defaults to `error`. | diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/date-picker/Examples.js b/packages/dnb-design-system-portal/src/pages/uilib/components/date-picker/Examples.js index b7a52472899..483b46a2b2d 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/components/date-picker/Examples.js +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/date-picker/Examples.js @@ -5,22 +5,16 @@ import React, { PureComponent, Fragment } from 'react' import ComponentBox from '../../../../shared/tags/ComponentBox' -import DatePickerRange from 'dnb-ui-lib/src/components/date-picker/DatePickerRange' +import styled from '@emotion/styled' class Example extends PureComponent { render() { const IS_TEST = typeof window !== 'undefined' && window.IS_TEST + if (IS_TEST) { + return + } return ( - - {/* @jsx */ ` - - `} - {/* @jsx */ ` {/* @jsx */ ` {/* @jsx */ ` - { - console.log('on_change', date) - }} - on_show={({ date }) => { - console.log('on_show', date) - }} -/> - `} - - - {/* @jsx */ ` `} + + {/* @jsx */ ` + + `} + + + {/* @jsx */ ` + + `} + + + {/* @jsx */ ` + + `} + -
-
- -
-

- Example styling of range calendar (also used for screenshot - tests) -

-
+
) } } export default Example + +const ScreenshotTests = () => { + return ( + + + {/* @jsx */ ` + { + console.log('on_change', date) + }} + on_show={({ date }) => { + console.log('on_show', date) + }} +/> + `} + + + {/* @jsx */ ` + + `} + + + {/* @jsx */ ` + + `} + + + {/* @jsx */ ` + + `} + + + ) +} + +const Wrapper = styled.div` + [data-dnb-test='date-picker-calendar'] .dnb-date-picker__container { + display: block; + position: relative; + top: 0; + } + [data-dnb-test='date-picker-calendar'] .dnb-date-picker { + margin-left: 1rem; + } +` diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/date-picker/date-picker-properties.md b/packages/dnb-design-system-portal/src/pages/uilib/components/date-picker/date-picker-properties.md index deed7472419..08767dde564 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/components/date-picker/date-picker-properties.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/date-picker/date-picker-properties.md @@ -14,7 +14,7 @@ draft: true | `end_month` | _(optional)_ to display what month should be shows in the second calendar by default. Defaults to the `date` respective `start_date`. | | `min_date` | _(optional)_ to limit a date range to a minimum `start_date`. Defaults to null. `start_date`. | | `max_date` | _(optional)_ to limit a date range to a maximum `end_date`. Defaults to null. `start_date`. | -| `return_format` | _(optional)_ Defines how the returned date, as a string, should be formatted as. Defualts to `YYYY-MM-DD`. | +| `return_format` | _(optional)_ Defines how the returned date, as a string, should be formatted as. Defaults to `YYYY-MM-DD`. | | `range` | _(optional)_ if the date picker should support a range of two dates (starting and ending date). Defaults to `false`. | | `show_input` | _(optional)_ if the input fields with the mask should be visible. Defaults to `false`. | | `mask_order` | _(optional)_ to define the order of the masked placeholder input fields. Defaults to `dd/mm/yyyy` | @@ -29,3 +29,5 @@ draft: true | `first_day` | _(optional)_ to define the first day of the week. Defaults to `monday`. | | `locale` | _(optional)_ to define the locale used in the calendar. Needs to be an `date-fns` locale object, like `import nbLocale from 'date-fns/locale/nb'`. Defaults to `nb`. | | `label` | _(optional)_ a prepending label in sync with the date input field. | +| `status` | _(optional)_ text with a status message. The style defaults to an error message. | +| `status_state` | _(optional)_ defines the state of the status. Currently are two statuses `[error, info]`. Defaults to `error`. | diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/dropdown/dropdown-properties.md b/packages/dnb-design-system-portal/src/pages/uilib/components/dropdown/dropdown-properties.md index 59970cf5225..182887413a7 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/components/dropdown/dropdown-properties.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/dropdown/dropdown-properties.md @@ -15,7 +15,9 @@ import { Data } from 'Pages/uilib/components/dropdown/Examples' | `scrollable` | _(optional)_ defines if the options list should be scrollable (the `max-height` is set by default to `50vh`). Defaults to `true`. | | `no_scroll_animation` | _(optional)_ to disable scrolling animation. Defaults to `false`. | | `no_animation` | _(optional)_ to disable appear/disappear (show/hide) animation. Defaults to `false`. | -| `max_height` | _(optional)_ defines if the height (in `rem`) of the options list. Defualts to null, as this is set automatically by default. | +| `max_height` | _(optional)_ defines if the height (in `rem`) of the options list. Defaults to null, as this is set automatically by default. | +| `status` | _(optional)_ text with a status message. The style defaults to an error message. | +| `status_state` | _(optional)_ defines the state of the status. Currently are two statuses `[error, info]`. Defaults to `error`. | ## Data structure diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/progress-indicator/Examples.js b/packages/dnb-design-system-portal/src/pages/uilib/components/progress-indicator/Examples.js index 3803feae491..b86b3591bc3 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/components/progress-indicator/Examples.js +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/progress-indicator/Examples.js @@ -50,14 +50,15 @@ class Example extends PureComponent { `} {/* @jsx */ ` () => { + const random = (min, max) => (Math.floor( Math.random () * (max - min + 1)) + min) const [visible, setVisibe] = useState(true) useEffect(() => { - const timer = setInterval(() => setVisibe(!visible), 2400) + const timer = setInterval(() => setVisibe(!visible), random(2400, 4200)) return () => clearTimeout(timer) }) return ( diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/radio/radio-properties.md b/packages/dnb-design-system-portal/src/pages/uilib/components/radio/radio-properties.md index aef6d1372b4..acc0c738825 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/components/radio/radio-properties.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/radio/radio-properties.md @@ -12,9 +12,11 @@ draft: true | `group` | _(optional)_ use a unique group identifier to define the Radio buttons who belongs together. | | `label` | _(optional)_ use either the `label` property or provide custom one. | | `label_position` | _(optional)_ defines the position of the `label`. Use either `left` or `right`. Defaults to `right`. | -| `status` | _(optional)_ uses the `form-status` component to show failure messages. | | `id` | _(optional)_ the `id` of the input. Default will be a random id. | | `disabled` | _(optional)_ to disable/enable the radio. | +| `status` | _(optional)_ text with a status message. The style defaults to an error message. | +| `status_state` | _(optional)_ defines the state of the status. Currently are two statuses `[error, info]`. Defaults to `error`. | +| | | ## Radio group diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/switch/switch-properties.md b/packages/dnb-design-system-portal/src/pages/uilib/components/switch/switch-properties.md index 2dfb73e0fee..1de620abf02 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/components/switch/switch-properties.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/switch/switch-properties.md @@ -2,12 +2,13 @@ draft: true --- -| Properties | Description | -| --------------- | ----------------------------------------------------------------------------------------------------- | -| `checked` | _(optional)_ determine whether the switch is checked or not. Default will be `false`. | -| `default_state` | _(optional)_ boolean value. The state of the switch. Defaults to `false`. Set to `true` if otherwise. | -| `title` | _(mandatory)_ the `title` of the input - describing it a bit further for accessibility reasons. | -| `label` | _(optional)_ use either the `label` property or provide custom one. | -| `status` | _(optional)_ uses the `form-status` component to show failure messages. | -| `id` | _(optional)_ the `id` of the input. Default will be a random id. | -| `disabled` | _(optional)_ to disable/enable the switch. | +| Properties | Description | +| --------------- | -------------------------------------------------------------------------------------------------------------- | +| `checked` | _(optional)_ determine whether the switch is checked or not. Default will be `false`. | +| `default_state` | _(optional)_ boolean value. The state of the switch. Defaults to `false`. Set to `true` if otherwise. | +| `title` | _(mandatory)_ the `title` of the input - describing it a bit further for accessibility reasons. | +| `label` | _(optional)_ use either the `label` property or provide custom one. | +| `id` | _(optional)_ the `id` of the input. Default will be a random id. | +| `disabled` | _(optional)_ to disable/enable the switch. | +| `status` | _(optional)_ text with a status message. The style defaults to an error message. | +| `status_state` | _(optional)_ defines the state of the status. Currently are two statuses `[error, info]`. Defaults to `error`. | diff --git a/packages/dnb-design-system-portal/src/pages/uilib/elements/tables.md b/packages/dnb-design-system-portal/src/pages/uilib/elements/tables.md index 1b3d0f1b55e..881c3e6957b 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/elements/tables.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/elements/tables.md @@ -75,6 +75,43 @@ The following table has a default style. But in future, there will be several pa `} +### Classes + +There are a couple helper classes to style tables: + +- `.dnb-table__th` Table Header +- `.dnb-table__td` Table Data +- `.dnb-table__tr` Table Row +- `.dnb-table__tr--even` Use this on a `tr` +- `.dnb-table__tr--odd` Use this on a `tr` +- `.dnb-table--no-wrap` Use this on a `th` +- `.dnb-table--active` Use this on a `th` +- `.dnb-table--sortable` Use this on a `th` +- `.dnb-table--reversed` Use this on a `th` +- `.dnb-table--tabular` Use this on the `table` root + + +{` + + + + + + + + + + + + + + +
+ .dnb-table__th +
.dnb-table__td .dnb-table__tr--even
.dnb-table__td .dnb-table__tr--odd
+`} +
+ ### Tabular Numbers Set [Tabular Lining](/uilib/typography/numbers) on tables by using this CSS class: `.dnb-table--tabular` diff --git a/packages/dnb-design-system-portal/src/pages/uilib/getting-started.md b/packages/dnb-design-system-portal/src/pages/uilib/getting-started.md index 622e98d3919..11a93e53ef4 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/getting-started.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/getting-started.md @@ -22,9 +22,9 @@ Do you want to... ## So, how do I get started? -You can [**follower this intro**](/uilib/intro), guiding You through all the elementary elements of Eufemia. Or continue reading all the articles in [the usage section](/uilib/usage/). +You can follow a [**Quick Intro**](/uilib/intro), guiding You through all the elementary elements of Eufemia. Or continue reading all the articles in [the usage section](/uilib/usage/). -
+
diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/01-about-design-systems.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/01-about-design-systems.md index cec8acccfa3..506b6006175 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/01-about-design-systems.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/01-about-design-systems.md @@ -19,6 +19,6 @@ What is a Design System good for? --- -[Next - Common Design Patterns](/uilib/intro/02-common-patterns?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/02-common-patterns.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/02-common-patterns.md index 79c47e68ae2..792ff3d7154 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/02-common-patterns.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/02-common-patterns.md @@ -22,6 +22,6 @@ Both UX designers and frontend web developers will have a huge benefit of **"tal --- -[Next - UX handover](/uilib/intro/03-ux-handover?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/03-ux-handover.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/03-ux-handover.md index c43ddc2fb56..a42b8a304b4 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/03-ux-handover.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/03-ux-handover.md @@ -10,17 +10,38 @@ order: 3 UX Designers at DNB are using Figma. Figma files can be shared and viewed online. -To get the details and properties about the layout, styles and the used components, you can inspect the file. +To get the details and properties about the layout, styles and the used components, you can inspect the file both for colors, typography, spacing and component usage. -1. First, select and area by one click. -2. Second, hover on the next by areas to se the distance. +## Spacing -Remember, everything should be in the **8px grid/spacing** (0.5rem) - even it the designer sometimes are one or two pixels of, you now know what it should be. +Remember, everything should be in the **8px grid** (0.5rem) spacing - even it the designer sometimes are one or two pixels of, you now know what it should be. -![Figma UX handover](./assets/ux-handover.png) +1. Select an area by a single _click_. +2. _Hover_ on the next areas to se the spacing between them. ---- +![What spacing is used](./assets/ux-handover-spacing.png) + +## Components + +1. Select a component by a single _click_. +2. Have a look at the _Pages_ pane on the left side. + +![What component is used](./assets/ux-handover-component.png) + +## Typography + +1. Select a text by a single _click_. +2. Have a look at the _Properties_ pane on the right side. + +![What typography is used](./assets/ux-handover-typography.png) + +## Color + +1. Select an area by a single _click_. +2. Have a look at the _Properties_ pane on the right side. Only use the color name as the reference. Do not copy HEX codes. + +![What color is uses](./assets/ux-handover-color.png) -[Next - Eufemia for Developers](/uilib/intro/04-eufemia-for-developers?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/04-eufemia-for-developers.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/04-eufemia-for-developers.md index bbaa505edbc..4e8ad0002c9 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/04-eufemia-for-developers.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/04-eufemia-for-developers.md @@ -23,6 +23,6 @@ What Eufemia offers for Developers? NPM Package including: --- -[Next - CSS Packages](/uilib/intro/05-css-packages?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/05-css-packages.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/05-css-packages.md index b891f9459e8..cb7047ebc0a 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/05-css-packages.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/05-css-packages.md @@ -29,6 +29,6 @@ On [legacy code projects](!/uilib/usage/customisation/styling#how-to-deal-with-e --- -[Next - Typography](/uilib/intro/06-typography?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/06-typography.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/06-typography.md index 61f8df9e2e8..dbe67c65649 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/06-typography.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/06-typography.md @@ -15,7 +15,9 @@ Every typography HTML element, like headings and paragraphs, have a defined `hei You don't need to define the `font-family` ever, but rather use CSS Custom Properties for `font-weight`. ```css -font-weight: var(--font-weight-demi); +.selector { + font-weight: var(--font-weight-demi); +} ``` The default [font-weight](!/uilib/typography/font-weights) is currently **Book**, alongside _Demi_ and _Medium_. @@ -26,6 +28,6 @@ Read [more about Typography](!/uilib/typography) --- -[Next - Color usage](/uilib/intro/07-color-usage?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/07-color-usage.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/07-color-usage.md index 5fda560242f..25647c76654 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/07-color-usage.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/07-color-usage.md @@ -35,6 +35,6 @@ See the [Color Table](!/uilib/usage/customisation/colors#colors-table). --- -[Next - Icons](/uilib/intro/08-icons?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/08-icons.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/08-icons.md index 05f04f15d48..246e2ae044a 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/08-icons.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/08-icons.md @@ -19,6 +19,6 @@ It is recommended to use the [Icon Component](!/uilib/components/icon) to displa --- -[Next - Components, Elements and Patterns](/uilib/intro/09-layout?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/09-layout.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/09-layout.md index 27a3a49c6ac..112addadece 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/09-layout.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/09-layout.md @@ -14,10 +14,16 @@ To get a good user experience and a professional looking result, perfect layouti - Use `rem` units for layouts and spacing. - Use **CSS Flexbox** or **CSS Grid** as layout systems. +## Spacing + +Remember, everything should be in the **8px grid** (0.5rem) spacing - even it the designer sometimes are one or two pixels of, you now know what it should be. + +![UX layout spacing](../usage/assets/ux-layout-spacing.png) + You may have a [look at the layout docs](!/uilib/usage/layout) --- -[Next - Components, Elements and Patterns](/uilib/intro/10-components-elements-patterns?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/10-components-elements-patterns.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/10-components-elements-patterns.md index aa9a83a43bd..b0ac9dd8e9d 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/10-components-elements-patterns.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/10-components-elements-patterns.md @@ -4,16 +4,34 @@ draft: true order: 10 --- +import { Button } from 'dnb-ui-lib/src' + # Components, Elements and Patterns -- [Components](!/uilib/components) are custom made **user interaction elements** with an internal state, your application can interact with. -- [Elements](!/uilib/elements) are basicity ready to use styled HTML elements. -- [Patterns](!/uilib/patterns) are larger components, less strictly defined, but with a more flexible outcome. +## [Components](!/uilib/components) + +Components are custom made **user interaction elements** with an internal state, your application can interact with. + +
+
+ +## [Elements](!/uilib/elements) + +Elements are basicity ready to use styled HTML elements. + + + +## [Patterns](!/uilib/patterns) + +Patterns are larger components, less strictly defined, but with a more flexible outcome. --- -[Next - Usage of Components and Patterns](/uilib/intro/11-usage-of-components-elements?fullscreen) +
diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/11-usage-of-components-elements.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/11-usage-of-components-elements.md index d2a15905a10..8c887bbbf5d 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/11-usage-of-components-elements.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/11-usage-of-components-elements.md @@ -52,6 +52,6 @@ Read more about using elements as [React JSX](!/uilib/elements#react-jsx) --- -[Next - Quality and Tests](/uilib/intro/12-quality-and-tests?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/12-quality-and-tests.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/12-quality-and-tests.md index f78a5a9ecb6..dcb8d49fff3 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/12-quality-and-tests.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/12-quality-and-tests.md @@ -18,6 +18,6 @@ Read [more about tests](!/uilib/usage/best-practices/for-testing). --- -[Next - Accessibility](/uilib/intro/13-accessibility?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/13-accessibility.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/13-accessibility.md index c2326c5d2f3..a9952cd84a1 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/13-accessibility.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/13-accessibility.md @@ -10,8 +10,52 @@ order: 12 **This is important!** You as a developer has the responsibility to implement and [use best practices](!/uilib/usage/accessibility) to make applications accessible for every end user. +## ARIA Examples + +Example usage of `role`, `aria-label`, `aria-labelledby` and `aria-hidden`. + +```html + + + + +
Dynamic content alert message
+ +image alt + +
+ image alt +
Description Name ...
+
+``` + +## Semantic Elements + +Example usage of HTML5 `landmarks`. + +```html + +
Header
+ +
+

Section

+ ... +
+
+

Article

+ ... +
+
+

Article

+ ... +
+ +
Footer
+ +``` + --- -[Next - Helper Classes](/uilib/intro/14-helper-classes?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/14-helper-classes.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/14-helper-classes.md index 82529b1b499..0c63b8e410b 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/14-helper-classes.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/14-helper-classes.md @@ -26,6 +26,6 @@ As a place for commonly used **global CSS classes**, Eufemia has the term [Helpe --- -[Summary](/uilib/intro/15-summary?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/15-summary.md b/packages/dnb-design-system-portal/src/pages/uilib/intro/15-summary.md index df14f235219..1fa589b4d1e 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/intro/15-summary.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/intro/15-summary.md @@ -12,6 +12,6 @@ The UX Team behind the **Eufemia Design System** would love to hear [your meanin --- -[Back to start](/uilib/intro/01-about-design-systems?fullscreen) + diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/assets/ux-handover-color.png b/packages/dnb-design-system-portal/src/pages/uilib/intro/assets/ux-handover-color.png new file mode 100644 index 00000000000..2d7d515d5c6 Binary files /dev/null and b/packages/dnb-design-system-portal/src/pages/uilib/intro/assets/ux-handover-color.png differ diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/assets/ux-handover-component.png b/packages/dnb-design-system-portal/src/pages/uilib/intro/assets/ux-handover-component.png new file mode 100644 index 00000000000..1ffdc5293c2 Binary files /dev/null and b/packages/dnb-design-system-portal/src/pages/uilib/intro/assets/ux-handover-component.png differ diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/assets/ux-handover-spacing.png b/packages/dnb-design-system-portal/src/pages/uilib/intro/assets/ux-handover-spacing.png new file mode 100644 index 00000000000..d21b6f40bd2 Binary files /dev/null and b/packages/dnb-design-system-portal/src/pages/uilib/intro/assets/ux-handover-spacing.png differ diff --git a/packages/dnb-design-system-portal/src/pages/uilib/intro/assets/ux-handover-typography.png b/packages/dnb-design-system-portal/src/pages/uilib/intro/assets/ux-handover-typography.png new file mode 100644 index 00000000000..dd0706980de Binary files /dev/null and b/packages/dnb-design-system-portal/src/pages/uilib/intro/assets/ux-handover-typography.png differ diff --git a/packages/dnb-design-system-portal/src/pages/uilib/usage/accessibility.md b/packages/dnb-design-system-portal/src/pages/uilib/usage/accessibility.md index 24f7a711680..cb265e9f439 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/usage/accessibility.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/usage/accessibility.md @@ -16,7 +16,7 @@ Make sure your applications are [**universally designed**](https://uu.difi.no) a - define the tab navigation and [focus management](/uilib/usage/accessibility/focus#managing-the-focus-state) properly - have a [Skip Link](/uilib/usage/accessibility/focus#skip-link) in place - properly use the `for="#id"` attribute on [labels](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label#Attributes) -- make good use of `area-label` and `aria-hidden`, e.g. of [decorative content](/uilib/usage/accessibility/icons#decorative-icons) +- make good use of `aria-label` and `aria-hidden`, e.g. of [decorative content](/uilib/usage/accessibility/icons#decorative-icons) - have `aria-live` in place for dynamic content - hide "hidden" content with `display: none;`, HTML `hidden` attribute or remove the markup entirely (like React States) - allow zooming in web pages. Example: diff --git a/packages/dnb-design-system-portal/src/pages/uilib/usage/assets/ux-layout-spacing.png b/packages/dnb-design-system-portal/src/pages/uilib/usage/assets/ux-layout-spacing.png new file mode 100644 index 00000000000..fc9adcd4055 Binary files /dev/null and b/packages/dnb-design-system-portal/src/pages/uilib/usage/assets/ux-layout-spacing.png differ diff --git a/packages/dnb-design-system-portal/src/pages/uilib/usage/customisation/styling/legacy-styling.js b/packages/dnb-design-system-portal/src/pages/uilib/usage/customisation/styling/legacy-styling.js index f014783f1d9..b3fc2a1ea5f 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/usage/customisation/styling/legacy-styling.js +++ b/packages/dnb-design-system-portal/src/pages/uilib/usage/customisation/styling/legacy-styling.js @@ -71,7 +71,7 @@ const LegacyCodeStyling = () => ( {'
'}

- I'm a {`

`} in an Article, and have the defualt + I'm a {`

`} in an Article, and have the default spacing!

diff --git a/packages/dnb-design-system-portal/src/pages/uilib/usage/layout.md b/packages/dnb-design-system-portal/src/pages/uilib/usage/layout.md index e301a5a3afc..e4e298529ac 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/usage/layout.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/usage/layout.md @@ -10,7 +10,9 @@ To not overcomplicate the Eufemia - and limit the creativity and possibilities, ## Spacing -Eufemia has a [Spatial System](/quickguide-designer/spatial-system) with a grid of **8px**. This is simply a guide grid which helps with making design decisions about the sizes of components, elements, margins, paddings etc. +Eufemia has a [Spatial System](/quickguide-designer/spatial-system) with a grid of **8px** (0.5rem). This is simply a guide grid which helps with making design decisions about the sizes of components, elements, margins, paddings etc. + +![UX layout spacing](./assets/ux-layout-spacing.png) ### Responsiveness diff --git a/packages/dnb-design-system-portal/src/shared/menu/MainMenu.js b/packages/dnb-design-system-portal/src/shared/menu/MainMenu.js index 08b5c054ec2..77a7b4295ab 100644 --- a/packages/dnb-design-system-portal/src/shared/menu/MainMenu.js +++ b/packages/dnb-design-system-portal/src/shared/menu/MainMenu.js @@ -186,6 +186,7 @@ export default class MainMenu extends PureComponent { static defaultProps = { enableOverlay: false } + static contextType = MainMenuContext constructor(props) { super(props) setPageFocusElement('.close-button', 'mainmenu') @@ -196,7 +197,6 @@ export default class MainMenu extends PureComponent { } } componentWillUnmount() { - this.closeMenuHandler = null if (typeof document !== 'undefined') { document.removeEventListener('keydown', this.onKeyDownHandler) } @@ -204,112 +204,103 @@ export default class MainMenu extends PureComponent { onKeyDownHandler = e => { switch (keycode(e)) { case 'esc': - if (this.closeMenuHandler) { - this.closeMenuHandler() + if (this.context.isOpen) { + this.context.closeMenu() } break } } + render() { + const { closeMenu, isOpen, isClosing, isActive } = this.context const { enableOverlay } = this.props return ( - - {({ closeMenu, isOpen, isClosing, isActive }) => { - this.closeMenuHandler = isOpen ? closeMenu : null - return ( - (isActive || !enableOverlay) && ( - + { + <> + + {isOpen && !isClosing && } + {(enableOverlay && ( + + {isOpen && !isClosing && ( +

@@ -318,7 +320,15 @@ export default class DatePickerCalendar extends PureComponent { } } -const PrevButton = ({ nr, minDate, month, prevBtn, onPrev, locale }) => { +const PrevButton = ({ + nr, + minDate, + month, + prevBtn, + onPrev, + locale, + onKeyDown +}) => { if (!prevBtn) { return <> } @@ -335,6 +345,7 @@ const PrevButton = ({ nr, minDate, month, prevBtn, onPrev, locale }) => { aria-label={title} title={title} onClick={onClick} + onKeyDown={onKeyDown} /> ) } @@ -344,13 +355,23 @@ PrevButton.propTypes = { month: PropTypes.object.isRequired, locale: PropTypes.object.isRequired, prevBtn: PropTypes.bool.isRequired, - onPrev: PropTypes.func.isRequired + onPrev: PropTypes.func.isRequired, + onKeyDown: PropTypes.func } PrevButton.defaultProps = { - minDate: null + minDate: null, + onKeyDown: null } -const NextButton = ({ nr, maxDate, month, nextBtn, onNext, locale }) => { +const NextButton = ({ + nr, + maxDate, + month, + nextBtn, + onNext, + locale, + onKeyDown +}) => { if (!nextBtn) { return <> } @@ -368,6 +389,7 @@ const NextButton = ({ nr, maxDate, month, nextBtn, onNext, locale }) => { aria-label={title} title={title} onClick={onClick} + onKeyDown={onKeyDown} /> ) ) @@ -378,10 +400,12 @@ NextButton.propTypes = { month: PropTypes.object.isRequired, locale: PropTypes.object.isRequired, nextBtn: PropTypes.bool.isRequired, - onNext: PropTypes.func.isRequired + onNext: PropTypes.func.isRequired, + onKeyDown: PropTypes.func } NextButton.defaultProps = { - maxDate: null + maxDate: null, + onKeyDown: null } const onSelectRange = ({ diff --git a/packages/dnb-ui-lib/src/components/date-picker/DatePickerInput.js b/packages/dnb-ui-lib/src/components/date-picker/DatePickerInput.js index 2f7cc1b426b..1be72b4472b 100644 --- a/packages/dnb-ui-lib/src/components/date-picker/DatePickerInput.js +++ b/packages/dnb-ui-lib/src/components/date-picker/DatePickerInput.js @@ -30,7 +30,11 @@ export const propTypes = { minDate: PropTypes.instanceOf(Date), maxDate: PropTypes.instanceOf(Date), range: PropTypes.bool, + status: PropTypes.string, + status_state: PropTypes.string, + status_animation: PropTypes.string, disabled: PropTypes.bool, + opened: PropTypes.bool, showInput: PropTypes.bool, onChange: PropTypes.func, onSubmit: PropTypes.func, @@ -44,9 +48,13 @@ export const defaultProps = { maskPlaceholder: 'dd/mm/åååå', separatorRexExp: /[-/ ]/g, range: null, + status: null, + status_state: 'error', + status_animation: null, minDate: null, maxDate: null, disabled: null, + opened: false, showInput: null, onChange: null, onSubmit: null, @@ -489,6 +497,10 @@ export default class DatePickerInput extends PureComponent { onSubmitButtonFocus /* eslint-disable-line */, showInput /* eslint-disable-line */, disabled, + opened, + status, + status_state, + status_animation, ...rest } = this.props @@ -500,9 +512,12 @@ export default class DatePickerInput extends PureComponent { return ( ({ ...view, - month: DatePickerRange.getMonth(i, props), + month: DatePickerRange.getMonth(i, state), nr: i })) } - static getMonth(viewCount, props) { - if ((props.startMonth || props.startDate) && viewCount === 0) { - return props.startMonth || props.startDate + static getMonth(viewCount, state) { + if ((state.startMonth || state.startDate) && viewCount === 0) { + return state.startMonth || state.startDate } - if ((props.endMonth || props.endDate) && viewCount === 1) { - return props.endMonth || props.endDate + if ((state.endMonth || state.endDate) && viewCount === 1) { + return state.endMonth || state.endDate } - return addMonths(DatePickerRange.getFallbackMonth(props), viewCount) + return addMonths(DatePickerRange.getFallbackMonth(state), viewCount) } - static getFallbackMonth(props) { - return props.month || props.startMonth || props.startDate || new Date() + static getFallbackMonth(state) { + return state.startMonth || state.startDate || new Date() } - callOnChange() { + callOnChange(opts = {}) { const { startDate, endDate, views } = this.state this.props.onChange && this.props.onChange( @@ -141,7 +154,7 @@ export default class DatePickerRange extends PureComponent { endDate, views }, - { hidePicker: false, callOnlyOnChangeHandler: false } + { hidePicker: false, callOnlyOnChangeHandler: false, ...opts } ) } @@ -157,15 +170,21 @@ export default class DatePickerRange extends PureComponent { startDate, endDate }) - this.callOnChange() + this.callOnChange({ hidePicker: true }) }) } onNext = ({ nr }) => { const views = this.state.views.map(c => { - return this.props.link || c.nr === nr - ? { ...c, month: addMonths(c.month, 1) } - : c + if (c.nr === nr) { + const month = addMonths(c.month, 1) + this.setState({ + [`${nr === 0 ? 'start' : 'end'}Month`]: month, + _listenForPropChanges: false + }) + return this.props.link || { ...c, month } + } + return this.props.link || c }) this.setState({ views, _listenForPropChanges: false }, () => { this.callOnNav() @@ -174,9 +193,15 @@ export default class DatePickerRange extends PureComponent { onPrev = ({ nr }) => { const views = this.state.views.map(c => { - return this.props.link || c.nr === nr - ? { ...c, month: subMonths(c.month, 1) } - : c + if (c.nr === nr) { + const month = subMonths(c.month, 1) + this.setState({ + [`${nr === 0 ? 'start' : 'end'}Month`]: month, + _listenForPropChanges: false + }) + return this.props.link || { ...c, month } + } + return this.props.link || c }) this.setState({ views, _listenForPropChanges: false }, () => { this.callOnNav() @@ -197,6 +222,8 @@ export default class DatePickerRange extends PureComponent { case 'down': event.preventDefault() break + default: + return } let type = nr === 0 ? 'start' : 'end' @@ -221,22 +248,58 @@ export default class DatePickerRange extends PureComponent { newDate = addWeeks(newDate, 1) break } - } - - if (!newDate) { + } else { + // use the date picker month, if provided newDate = - nr === 0 - ? this.props.month || this.props.startMonth || new Date() - : this.props.endMonth || addMonths(new Date(), 1) + this.state[`${type}Month`] || + (this.props.range && nr === 1 + ? addMonths(new Date(), 1) + : new Date()) } if (newDate !== this.state[`${type}Date`]) { - const state = { - [`${type}Date`]: newDate, - _listenForPropChanges: false + const state = { _listenForPropChanges: false } + + const currentMonth = this.state[`${type}Month`] + + if ( + // in case we dont have a start/end date, then we use the current month date + (currentMonth && !this.state[`${type}Date`]) || + // if we have a larger gap between the new date and the curent month in the calendar + (currentMonth && + Math.abs(differenceInMonths(newDate, currentMonth)) > 1) + ) { + if (!this.props.range) { + newDate = currentMonth + } else { + newDate = + nr === 0 + ? setDate(currentMonth, 1) + : lastDayOfMonth(currentMonth) + } + // if (nr === 1) { + // newDate = addMonths(newDate, 1) + // } + // only to make sure we navigate the calendar to the new date + } else if ( + currentMonth && + !isSameMonth(this.state[`${type}Date`], currentMonth) + ) { + state[`${type}Month`] = newDate } - if (!this.props.range || (nr === 0 && !this.state.endDate)) { - state.endDate = addMonths(newDate, 1) + + state[`${type}Date`] = newDate + + // set fallbacks + if (!this.props.range) { + state.endDate = newDate + } else { + if (!this.state.startDate) { + state.startDate = newDate + } + if (!this.state.endDate) { + state.endDate = newDate + } } // make sure we stay on the same month @@ -249,9 +312,15 @@ export default class DatePickerRange extends PureComponent { } } + // make sure we also navigate the view if (this.props.sync) { - state.views = DatePickerRange.getViews({ ...this.props, ...state }) + state.views = this.state.views + state.views[nr] = DatePickerRange.getViews( + { ...this.state, ...state }, + this.props.range + )[nr] } + this.setState(state) setTimeout(() => { this.callOnChange() diff --git a/packages/dnb-ui-lib/src/components/date-picker/__tests__/DatePicker.screenshot.test.js b/packages/dnb-ui-lib/src/components/date-picker/__tests__/DatePicker.screenshot.test.js index 132d53dabb3..05cc9e395e5 100644 --- a/packages/dnb-ui-lib/src/components/date-picker/__tests__/DatePicker.screenshot.test.js +++ b/packages/dnb-ui-lib/src/components/date-picker/__tests__/DatePicker.screenshot.test.js @@ -26,4 +26,18 @@ describe('DatePicker screenshot', () => { }) expect(screenshot).toMatchImageSnapshot() }) + it('have to match the date-picker trigger button', async () => { + const screenshot = await testPageScreenshot({ + selector: + '[data-dnb-test="date-picker-trigger-default"] .dnb-date-picker' + }) + expect(screenshot).toMatchImageSnapshot() + }) + it('have to match the date-picker trigger button in error state', async () => { + const screenshot = await testPageScreenshot({ + selector: + '[data-dnb-test="date-picker-trigger-error"] .dnb-date-picker' + }) + expect(screenshot).toMatchImageSnapshot() + }) }) diff --git a/packages/dnb-ui-lib/src/components/date-picker/__tests__/DatePicker.test.js b/packages/dnb-ui-lib/src/components/date-picker/__tests__/DatePicker.test.js index 69a9d020f6b..a8e76ffbf0f 100644 --- a/packages/dnb-ui-lib/src/components/date-picker/__tests__/DatePicker.test.js +++ b/packages/dnb-ui-lib/src/components/date-picker/__tests__/DatePicker.test.js @@ -96,7 +96,7 @@ describe('DatePicker component', () => { it('has a reacting start date input with valid value', () => { const elem = Comp.find('input.dnb-date-picker__input--day').at(0) - // by defualt we have the start day + // by default we have the start day expect(elem.instance().value).toBe('01') // listen to changes @@ -137,7 +137,7 @@ describe('DatePicker component', () => { it('has a reacting end date input with valid value', () => { const elem = Comp.find('input.dnb-date-picker__input--day').at(1) - // by defualt we have the start day + // by default we have the start day expect(elem.instance().value).toBe('15') // listen to changes diff --git a/packages/dnb-ui-lib/src/components/date-picker/__tests__/__snapshots__/DatePicker.test.js.snap b/packages/dnb-ui-lib/src/components/date-picker/__tests__/__snapshots__/DatePicker.test.js.snap index c4356a25f75..3c5535de8e6 100644 --- a/packages/dnb-ui-lib/src/components/date-picker/__tests__/__snapshots__/DatePicker.test.js.snap +++ b/packages/dnb-ui-lib/src/components/date-picker/__tests__/__snapshots__/DatePicker.test.js.snap @@ -69,7 +69,7 @@ exports[`DatePicker component have to match snapshot 1`] = ` sync={true} > -1) { state.progress = props.progress @@ -87,20 +87,8 @@ export default class ProgressIndicator extends PureComponent { return state } - constructor(props) { - super(props) - - // this._id = - // props.id || `dnb-progress-indicator-${Math.round(Math.random() * 999)}` // cause we need an id anyway - - this.state = { - _listenForPropChanges: true, - visible: Boolean(props.visible), - complete: false, - progress: props.progress - } - - this.firstDelay = 300 // wait for the rest time + 200 start delay + state = { + _listenForPropChanges: true } componentWillUnmount() { @@ -108,31 +96,17 @@ export default class ProgressIndicator extends PureComponent { clearTimeout(this.fadeOutTimeout) } - callOnCompleteHandler() { - if (typeof this.props.on_complete === 'function') { - this.fadeOutTimeout = setTimeout(() => { - dispatchCustomElementEvent(this, 'on_complete') - }, 600) // wait for CSS fade out, defined in "progress-indicator-fade-out" - } - } - - delayVisibility() { - if (this.state.complete) { - return - } - - const duration = 1e3 // the duration, defined in CSS - const difference = new Date().getTime() - this.state.startTime - const ceil = Math.ceil(difference / duration) * duration - const timeToWait = ceil - difference - - this.fadeOutTimeout = setTimeout(() => { - this.firstDelay = 0 + callOnCompleteHandler = () => { + this.completeTimeout = setTimeout(() => { this.setState({ complete: true }) - this.callOnCompleteHandler() - }, timeToWait + this.firstDelay) + if (typeof this.props.on_complete === 'function') { + this.fadeOutTimeout = setTimeout(() => { + dispatchCustomElementEvent(this, 'on_complete') + }, 600) // wait for CSS fade out, defined in "progress-indicator-fade-out" + } + }, 200) } render() { @@ -140,8 +114,10 @@ export default class ProgressIndicator extends PureComponent { type, size, no_animation, + on_complete, progress: _progress, //eslint-disable-line visible: _visible, //eslint-disable-line + complete: _complete, //eslint-disable-line ...props } = this.props @@ -157,20 +133,13 @@ export default class ProgressIndicator extends PureComponent { validateDOMAttributes(this.props, params) - const isComplete = - visible === false || - (hasProgressIndicator && parseFloat(progress) >= 100) - if (isComplete) { - this.delayVisibility() - } - return (
@@ -178,7 +147,10 @@ export default class ProgressIndicator extends PureComponent { )}
diff --git a/packages/dnb-ui-lib/src/components/progress-indicator/ProgressIndicatorCircular.js b/packages/dnb-ui-lib/src/components/progress-indicator/ProgressIndicatorCircular.js index 7c08bae19a1..e7035260008 100644 --- a/packages/dnb-ui-lib/src/components/progress-indicator/ProgressIndicatorCircular.js +++ b/packages/dnb-ui-lib/src/components/progress-indicator/ProgressIndicatorCircular.js @@ -10,26 +10,155 @@ import { validateDOMAttributes } from '../../shared/component-helper' export const propTypes = { size: PropTypes.string, + visible: PropTypes.bool, complete: PropTypes.bool, progress: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - maxOffset: PropTypes.number + maxOffset: PropTypes.number, + onComplete: PropTypes.func, + callOnCompleteHandler: PropTypes.func } export const defaultProps = { size: null, + visible: true, complete: false, progress: null, - maxOffset: 88 + maxOffset: 88, + onComplete: null, + callOnCompleteHandler: null } export default class ProgressIndicatorCircular extends PureComponent { static propTypes = propTypes static defaultProps = defaultProps + static getDerivedStateFromProps(props, state) { + state.progress = parseFloat(props.progress) + state.visible = props.visible + state.complete = props.complete + return state + } + constructor(props) { + super(props) + this.useAnimationFrame = typeof props.onComplete === 'function' + this._refDark = React.createRef() + this._refLight = React.createRef() + this.state = { animate: false } + } + componentDidMount() { + if (this.useAnimationFrame) { + this.startAnimationFirstTime() + } + } + componentWillUnmount() { + this.stopAnimation() + } + stopAnimation() { + this.setState({ animate: false }) + if (this.startupTimeout) { + clearTimeout(this.startupTimeout) + } + } + startAnimationFirstTime() { + this.setState({ animate: false }) + this.startupTimeout = setTimeout(() => this.startAnimation(), 300) + } + startAnimation() { + this.setState({ animate: true }, () => { + if (this._refDark.current) { + this.animate( + this._refDark.current, + true, + this.props.callOnCompleteHandler + ) + } + if (this._refLight.current) { + this.animate(this._refLight.current, false) + } + }) + } + animate(element, animateOnStart = true, callback = null) { + const min = 1 + const max = 88 + let start = 0, + ms = 0, + prog = max, + setProg = animateOnStart, + animate = true, + completeCalled = false, + stopNextRound = false + + const step = timestamp => { + if (!start) { + start = timestamp + } + + // milliseconds + ms = timestamp - start + + if (animate) { + if (!this.state.visible && prog < 5) { + prog = min + } + if (setProg) { + element.style['stroke-dashoffset'] = prog + } else if (!animateOnStart) { + element.style['stroke-dashoffset'] = max + } + } + + // if complete + if (stopNextRound) { + animate = false + if (!completeCalled) { + completeCalled = true + if (animateOnStart && typeof callback === 'function') { + callback() + } + } else if (this.state.visible && ms % 1e3 > 950) { + // this.startAnimationFirstTime() // will not start completely from scratch + stopNextRound = false + } + } else { + // make sure we stop next round + stopNextRound = !this.state.visible && prog === min + animate = true + completeCalled = false + } + + // sice we have 1sec as duration, and we want always a max of 1000ms + prog = Math.round(max - (max / 1e3) * (ms % 1e3)) + + // calc if we want to animate + setProg = animateOnStart + ? Math.ceil(ms / 1e3) % 2 === 1 || ms === 0 + : Math.ceil(ms / 1e3) % 2 === 0 && ms !== 0 + + if (this.state.animate) { + window.requestAnimationFrame(step) + } + } + if (typeof window !== 'undefined' && window.requestAnimationFrame) { + window.requestAnimationFrame(step) + } + } render() { - const { size, complete, maxOffset, progress } = this.props + const { + size, + maxOffset, + progress: _progress, // eslint-disable-line + visible, // eslint-disable-line + complete, // eslint-disable-line + onComplete, // eslint-disable-line + callOnCompleteHandler, // eslint-disable-line + + ...rest + } = this.props + + const { progress } = this.state + const strokeDashoffset = maxOffset - (maxOffset / 100) * progress const hasProgressIndicator = parseFloat(progress) > -1 - const params = {} + const params = { ...rest } if (hasProgressIndicator) { params['title'] = `${progress}%` params['aria-label'] = `${progress}%` @@ -61,17 +190,22 @@ export default class ProgressIndicatorCircular extends PureComponent { className={classnames( 'dnb-progress-indicator__circular__line', 'dark', - hasProgressIndicator || complete ? 'paused' : null + 'dark', + hasProgressIndicator || this.useAnimationFrame + ? 'paused' + : null )} style={hasProgressIndicator ? { strokeDashoffset } : {}} + ref={this._refDark} /> {!hasProgressIndicator && ( )} @@ -79,12 +213,13 @@ export default class ProgressIndicatorCircular extends PureComponent { } } -const Circle = ({ className, ...rest }) => { +const Circle = React.forwardRef(({ className, ...rest }, ref) => { return ( { /> ) -} +}) Circle.propTypes = { className: PropTypes.string.isRequired } diff --git a/packages/dnb-ui-lib/src/components/progress-indicator/__tests__/__snapshots__/ProgressIndicator.test.js.snap b/packages/dnb-ui-lib/src/components/progress-indicator/__tests__/__snapshots__/ProgressIndicator.test.js.snap index d7efebef106..c388d246b91 100644 --- a/packages/dnb-ui-lib/src/components/progress-indicator/__tests__/__snapshots__/ProgressIndicator.test.js.snap +++ b/packages/dnb-ui-lib/src/components/progress-indicator/__tests__/__snapshots__/ProgressIndicator.test.js.snap @@ -26,17 +26,20 @@ exports[`Circular ProgressIndicator component have to match snapshot 1`] = ` className="dnb-progress-indicator dnb-progress-indicator--visible" >
- - - + - +
@@ -184,6 +187,7 @@ exports[`ProgressIndicator scss have to match snapshot 1`] = ` * */ :root { + --progress-indicator-timing: cubic-bezier(0.5, 0, 0.5, 0.99); --progress-indicator-circular-circle: 88; --progress-indicator-circular-circle-offset--min: 88; --progress-indicator-circular-circle-offset--max: 1; } @@ -202,7 +206,7 @@ exports[`ProgressIndicator scss have to match snapshot 1`] = ` .dnb-progress-indicator__circular__line { animation-duration: 2s; animation-delay: 200ms; - animation-timing-function: cubic-bezier(0.5, 0, 0.5, 0.99); + animation-timing-function: var(--progress-indicator-timing); animation-iteration-count: infinite; } .dnb-progress-indicator__circular__line.background { stroke-dashoffset: var(--progress-indicator-circular-circle-offset--max); } @@ -217,7 +221,7 @@ exports[`ProgressIndicator scss have to match snapshot 1`] = ` .dnb-progress-indicator__circular__line.paused { animation-play-state: paused; } .dnb-progress-indicator__circular--has-progress-indicator .dnb-progress-indicator__circular__line.dark { - transition: stroke-dashoffset 600ms cubic-bezier(0.5, 0, 0.5, 0.99); } + transition: stroke-dashoffset 600ms var(--progress-indicator-timing); } .dnb-progress-indicator__circular__circle { stroke-linecap: round; } .dnb-progress-indicator__circular__line.light .dnb-progress-indicator__circular__circle { diff --git a/packages/dnb-ui-lib/src/components/progress-indicator/style/_progress-indicator.scss b/packages/dnb-ui-lib/src/components/progress-indicator/style/_progress-indicator.scss index b67b5bf483b..a2dc403defa 100644 --- a/packages/dnb-ui-lib/src/components/progress-indicator/style/_progress-indicator.scss +++ b/packages/dnb-ui-lib/src/components/progress-indicator/style/_progress-indicator.scss @@ -4,6 +4,7 @@ */ :root { + --progress-indicator-timing: cubic-bezier(0.5, 0, 0.5, 0.99); --progress-indicator-circular-circle: 88; --progress-indicator-circular-circle-offset--min: 88; --progress-indicator-circular-circle-offset--max: 1; @@ -32,7 +33,7 @@ &__line { animation-duration: 2s; animation-delay: 200ms; - animation-timing-function: cubic-bezier(0.5, 0, 0.5, 0.99); + animation-timing-function: var(--progress-indicator-timing); animation-iteration-count: infinite; } @@ -62,7 +63,7 @@ } // for static progress-indicator animation &--has-progress-indicator &__line.dark { - transition: stroke-dashoffset 600ms cubic-bezier(0.5, 0, 0.5, 0.99); + transition: stroke-dashoffset 600ms var(--progress-indicator-timing); } &__circle { diff --git a/packages/dnb-ui-lib/src/components/radio/Radio.js b/packages/dnb-ui-lib/src/components/radio/Radio.js index c20a2a8217b..821cbddd461 100644 --- a/packages/dnb-ui-lib/src/components/radio/Radio.js +++ b/packages/dnb-ui-lib/src/components/radio/Radio.js @@ -287,15 +287,6 @@ export default class Radio extends Component { inputParams['aria-readonly'] = inputParams.readOnly = true } - const StatusComp = showStatus && ( - - ) - // also used for code markup simulation validateDOMAttributes(this.props, inputParams) @@ -338,10 +329,16 @@ export default class Radio extends Component { - {label_position === 'left' && StatusComp} + {showStatus && ( + + )}
- {label_position === 'right' && StatusComp} ) } diff --git a/packages/dnb-ui-lib/src/components/radio/__tests__/__snapshots__/Radio.test.js.snap b/packages/dnb-ui-lib/src/components/radio/__tests__/__snapshots__/Radio.test.js.snap index 72ce0b3d34b..13b734f65d1 100644 --- a/packages/dnb-ui-lib/src/components/radio/__tests__/__snapshots__/Radio.test.js.snap +++ b/packages/dnb-ui-lib/src/components/radio/__tests__/__snapshots__/Radio.test.js.snap @@ -326,6 +326,10 @@ exports[`Radio scss have to match default theme snapshot 1`] = ` * When is ON * aka when the radio is :checked */ + /* + * When radio is OFF + * aka when the radio is not :checked + */ /* * On disabled * @@ -352,6 +356,11 @@ exports[`Radio scss have to match default theme snapshot 1`] = ` */ /* stylelint-disable */ /* stylelint-enable */ } + .dnb-radio__input { + opacity: 0; } + .dnb-radio__dot { + background-color: var(--color-sea-green-alt); + transition: opacity 200ms ease-out, transform 200ms ease-out; } .dnb-radio__input:not(:checked) ~ .dnb-radio__button { background-color: var(--color-white); border-color: var(--color-sea-green-alt); } @@ -359,7 +368,11 @@ exports[`Radio scss have to match default theme snapshot 1`] = ` background-color: var(--color-white); border-color: var(--color-sea-green-alt); } .dnb-radio__input:checked ~ .dnb-radio__dot { - background-color: var(--color-sea-green-alt); } + opacity: 1; + transform: scale(1); } + .dnb-radio__input:not(:checked) ~ .dnb-radio__dot { + opacity: 0; + transform: scale(0.8); } .dnb-radio__input[disabled] ~ .dnb-radio__button { border-color: var(--color-mint-green-50); } .dnb-radio__input[disabled]:checked ~ .dnb-radio__button { @@ -474,8 +487,7 @@ exports[`Radio scss have to match snapshot 1`] = ` vertical-align: baseline; cursor: pointer; color: inherit; - width: auto; - white-space: nowrap; } + width: auto; } .dnb-form-label--vertical { margin-right: 0; margin-top: 0; } @@ -663,32 +675,39 @@ exports[`Radio scss have to match snapshot 1`] = ` border: 0; } .dnb-radio__input:not([disabled]) { cursor: pointer; } - .dnb-radio > .dnb-form-status { - margin-top: 0.125rem; } - .dnb-radio--label-position-left { - display: inline-flex; } - .dnb-radio--label-position-left .dnb-radio { - order: 2; } - .dnb-radio--label-position-left label { - order: 1; } - .dnb-radio--label-position-left .dnb-form-label { - margin-right: 0.5rem; - margin-left: 1rem; } - .dnb-radio-group--layout-direction-column .dnb-radio--label-position-left { - display: flex; - margin-bottom: 0.5rem; } - .dnb-radio--label-position-right { - display: inline-flex; } - .dnb-radio--label-position-right .dnb-radio { - order: 1; } - .dnb-radio--label-position-right label { - order: 2; } - .dnb-radio--label-position-right .dnb-form-label { - margin-right: 1rem; - margin-left: 0.5rem; } - .dnb-radio-group--layout-direction-column .dnb-radio--label-position-right { - display: flex; + .dnb-radio--label-position-left, .dnb-radio--label-position-right { + display: inline-flex; + flex-direction: row; + align-items: flex-start; + flex-wrap: wrap; } + .dnb-radio--label-position-left .dnb-form-label, .dnb-radio--label-position-right .dnb-form-label { + flex: 1 1 33%; } + .dnb-radio--label-position-left .dnb-form-status, .dnb-radio--label-position-right .dnb-form-status { + order: 3; + flex: 1 1 1; + margin-top: 0.125rem; margin-bottom: 0.5rem; } + .dnb-radio--label-position-left .dnb-radio { + order: 2; } + .dnb-radio--label-position-left label { + order: 1; } + .dnb-radio--label-position-left .dnb-form-label { + flex: 0 1 auto; + margin-right: 0.5rem; + margin-left: 1rem; } + .dnb-radio-group--layout-direction-column .dnb-radio--label-position-left { + display: flex; + margin-bottom: 0.5rem; } + .dnb-radio--label-position-right .dnb-radio { + order: 1; } + .dnb-radio--label-position-right label { + order: 2; } + .dnb-radio--label-position-right .dnb-form-label { + margin-right: 1rem; + margin-left: 0.5rem; } + .dnb-radio-group--layout-direction-column .dnb-radio--label-position-right { + display: flex; + margin-bottom: 0.5rem; } .dnb-radio--label-position-left:first-of-type .dnb-form-label { margin-left: 0; } :not(.dnb-radio-group) > .dnb-form-label ~ .dnb-radio--label-position-left, diff --git a/packages/dnb-ui-lib/src/components/radio/__tests__/__snapshots__/radio-screenshot-test-js-radio-checked-screenshot-have-to-match-radio-group-with-form-status-1-013b7.snap.png b/packages/dnb-ui-lib/src/components/radio/__tests__/__snapshots__/radio-screenshot-test-js-radio-checked-screenshot-have-to-match-radio-group-with-form-status-1-013b7.snap.png index 30b12078de6..f4381398b39 100644 Binary files a/packages/dnb-ui-lib/src/components/radio/__tests__/__snapshots__/radio-screenshot-test-js-radio-checked-screenshot-have-to-match-radio-group-with-form-status-1-013b7.snap.png and b/packages/dnb-ui-lib/src/components/radio/__tests__/__snapshots__/radio-screenshot-test-js-radio-checked-screenshot-have-to-match-radio-group-with-form-status-1-013b7.snap.png differ diff --git a/packages/dnb-ui-lib/src/components/radio/style/_radio.scss b/packages/dnb-ui-lib/src/components/radio/style/_radio.scss index ca7493293f8..81208552da7 100644 --- a/packages/dnb-ui-lib/src/components/radio/style/_radio.scss +++ b/packages/dnb-ui-lib/src/components/radio/style/_radio.scss @@ -89,12 +89,25 @@ cursor: pointer; } - > .dnb-form-status { - margin-top: 0.125rem; + &--label-position-left, + &--label-position-right { + display: inline-flex; + flex-direction: row; + align-items: flex-start; + flex-wrap: wrap; + + .dnb-form-label { + flex: 1 1 33%; + } + .dnb-form-status { + order: 3; + flex: 1 1 1; + margin-top: 0.125rem; + margin-bottom: 0.5rem; + } } &--label-position-left { - display: inline-flex; .dnb-radio { order: 2; } @@ -102,6 +115,7 @@ order: 1; } .dnb-form-label { + flex: 0 1 auto; margin-right: 0.5rem; margin-left: 1rem; } @@ -112,7 +126,6 @@ } &--label-position-right { - display: inline-flex; .dnb-radio { order: 1; } diff --git a/packages/dnb-ui-lib/src/components/radio/style/themes/dnb-radio-theme-ui.scss b/packages/dnb-ui-lib/src/components/radio/style/themes/dnb-radio-theme-ui.scss index 531fe1926b0..cf03ddbdabb 100644 --- a/packages/dnb-ui-lib/src/components/radio/style/themes/dnb-radio-theme-ui.scss +++ b/packages/dnb-ui-lib/src/components/radio/style/themes/dnb-radio-theme-ui.scss @@ -6,6 +6,14 @@ @import '../../../../style/themes/imports.scss'; .dnb-radio { + &__input { + opacity: 0; + } + &__dot { + background-color: var(--color-sea-green-alt); + transition: opacity 200ms ease-out, transform 200ms ease-out; + } + /* * When is OFF * aka when the radio is not :checked @@ -24,7 +32,17 @@ border-color: var(--color-sea-green-alt); } &__input:checked ~ &__dot { - background-color: var(--color-sea-green-alt); + opacity: 1; + transform: scale(1); + } + + /* + * When radio is OFF + * aka when the radio is not :checked + */ + &__input:not(:checked) ~ &__dot { + opacity: 0; + transform: scale(0.8); } /* diff --git a/packages/dnb-ui-lib/src/components/switch/__tests__/__snapshots__/Switch.test.js.snap b/packages/dnb-ui-lib/src/components/switch/__tests__/__snapshots__/Switch.test.js.snap index 664a48ab958..98b63db11ef 100644 --- a/packages/dnb-ui-lib/src/components/switch/__tests__/__snapshots__/Switch.test.js.snap +++ b/packages/dnb-ui-lib/src/components/switch/__tests__/__snapshots__/Switch.test.js.snap @@ -302,8 +302,7 @@ exports[`Switch scss have to match snapshot 1`] = ` vertical-align: baseline; cursor: pointer; color: inherit; - width: auto; - white-space: nowrap; } + width: auto; } .dnb-form-label--vertical { margin-right: 0; margin-top: 0; } diff --git a/packages/dnb-ui-lib/src/components/textarea/__tests__/__snapshots__/Textarea.test.js.snap b/packages/dnb-ui-lib/src/components/textarea/__tests__/__snapshots__/Textarea.test.js.snap index 055294f2405..19c519606f1 100644 --- a/packages/dnb-ui-lib/src/components/textarea/__tests__/__snapshots__/Textarea.test.js.snap +++ b/packages/dnb-ui-lib/src/components/textarea/__tests__/__snapshots__/Textarea.test.js.snap @@ -272,8 +272,7 @@ exports[`Textarea scss have to match snapshot 1`] = ` vertical-align: baseline; cursor: pointer; color: inherit; - width: auto; - white-space: nowrap; } + width: auto; } .dnb-form-label--vertical { margin-right: 0; margin-top: 0; } diff --git a/packages/dnb-ui-lib/src/style/core/helper-classes/__tests__/HelperClasses.screenshot.test.js b/packages/dnb-ui-lib/src/style/core/helper-classes/__tests__/HelperClasses.screenshot.test.js index b1bc74b0e8a..64780fd6867 100644 --- a/packages/dnb-ui-lib/src/style/core/helper-classes/__tests__/HelperClasses.screenshot.test.js +++ b/packages/dnb-ui-lib/src/style/core/helper-classes/__tests__/HelperClasses.screenshot.test.js @@ -10,7 +10,7 @@ import { describe('Helper Classes screenshot', () => { setupPageScreenshot({ url: '/uilib/helper-classes' }) - it('have to match defualt "Section"', async () => { + it('have to match default "Section"', async () => { const screenshot = await testPageScreenshot({ selector: '[data-dnb-test="helper-classes-section"]' }) diff --git a/packages/dnb-ui-lib/src/style/core/helper-classes/__tests__/__snapshots__/helper-classes-screenshot-test-js-helper-classes-screenshot-have-to-match-defualt-section-1-5a21c.snap.png b/packages/dnb-ui-lib/src/style/core/helper-classes/__tests__/__snapshots__/helper-classes-screenshot-test-js-helper-classes-screenshot-have-to-match-default-section-1-71f8c.snap.png similarity index 100% rename from packages/dnb-ui-lib/src/style/core/helper-classes/__tests__/__snapshots__/helper-classes-screenshot-test-js-helper-classes-screenshot-have-to-match-defualt-section-1-5a21c.snap.png rename to packages/dnb-ui-lib/src/style/core/helper-classes/__tests__/__snapshots__/helper-classes-screenshot-test-js-helper-classes-screenshot-have-to-match-default-section-1-71f8c.snap.png diff --git a/packages/dnb-ui-lib/src/style/elements/__tests__/Blockquote.screenshot.test.js b/packages/dnb-ui-lib/src/style/elements/__tests__/Blockquote.screenshot.test.js index 4c3fc4a13fe..f346854d4b8 100644 --- a/packages/dnb-ui-lib/src/style/elements/__tests__/Blockquote.screenshot.test.js +++ b/packages/dnb-ui-lib/src/style/elements/__tests__/Blockquote.screenshot.test.js @@ -10,7 +10,7 @@ import { describe('Blockquote screenshot', () => { setupPageScreenshot({ url: '/uilib/elements/blockquote' }) - it('have to match defualt "blockquote"', async () => { + it('have to match default "blockquote"', async () => { const screenshot = await testPageScreenshot({ selector: '[data-dnb-test="blockquote-default"]' }) diff --git a/packages/dnb-ui-lib/src/style/elements/__tests__/__snapshots__/blockquote-screenshot-test-js-blockquote-screenshot-have-to-match-defualt-blockquote-1-a99a0.snap.png b/packages/dnb-ui-lib/src/style/elements/__tests__/__snapshots__/blockquote-screenshot-test-js-blockquote-screenshot-have-to-match-default-blockquote-1-a48bf.snap.png similarity index 100% rename from packages/dnb-ui-lib/src/style/elements/__tests__/__snapshots__/blockquote-screenshot-test-js-blockquote-screenshot-have-to-match-defualt-blockquote-1-a99a0.snap.png rename to packages/dnb-ui-lib/src/style/elements/__tests__/__snapshots__/blockquote-screenshot-test-js-blockquote-screenshot-have-to-match-default-blockquote-1-a48bf.snap.png diff --git a/packages/dnb-ui-lib/src/style/elements/table.scss b/packages/dnb-ui-lib/src/style/elements/table.scss index 248afb2e561..75d0fd874bd 100644 --- a/packages/dnb-ui-lib/src/style/elements/table.scss +++ b/packages/dnb-ui-lib/src/style/elements/table.scss @@ -17,7 +17,9 @@ border-collapse: collapse; & th, - & td { + & td, + & .dnb-table__th, + & .dnb-table__td { // to make sure we have the ability to have a border where ever we want border-bottom: 1px solid transparent; @@ -28,7 +30,8 @@ word-break: keep-all; text-align: left; } - & th { + & th, + & .dnb-table__th { padding: 3rem 1rem 0.5rem; font-weight: var(--font-weight-medium); @@ -37,12 +40,14 @@ background-color: var(--color-mint-green-50); border-bottom: 1px solid var(--color-mint-green); } - &--tabular td { + &--tabular td, + &--tabular .dnb-table__th { @include numberFeature(tabular-nums, lnum); } // sortable - & th#{&}--sortable { + & th#{&}--sortable, + & .dnb-table__th#{&}--sortable { color: var(--color-emerald-green); .dnb-icon { @@ -105,7 +110,8 @@ } } } - & th#{&}--active { + & th#{&}--active, + & .dnb-table__th#{&}--active { a, .dnb-anchor, .dnb-button, @@ -121,7 +127,8 @@ } } } - & th#{&}--reversed { + & th#{&}--reversed, + & .dnb-table__td#{&}--reversed { a, .dnb-anchor, .dnb-button, @@ -132,21 +139,28 @@ } } - & th#{&}--no-wrap { + & th#{&}--no-wrap, + & .dnb-table__th#{&}--no-wrap { white-space: nowrap; } - & td { + & td, + & .dnb-table__td { padding: 1rem; padding-top: 1.25rem; padding-bottom: 1.1875rem; } - & tr { + & tr, + & .dnb-table__tr, + & .dnb-table__tr--odd { background-color: var(--color-white); } - & tr:nth-of-type(2n) { + & tr:not(.dnb-table__tr--odd):nth-of-type(2n), + & .dnb-table__tr:not(.dnb-table__tr--odd):nth-of-type(2n), + & .dnb-table__tr--even { background-color: var(--color-mint-green-12); } - & tr:last-of-type td { + & tr:last-of-type td, + & .dnb-table__tr:last-of-type .dnb-table__td { // to get the perfect height of pixles, to this: padding-bottom: calc(1.1875rem - 1px); border-bottom: 1px solid var(--color-mint-green-50); diff --git a/packages/dnb-ui-lib/stories/components/Button.js b/packages/dnb-ui-lib/stories/components/Button.js new file mode 100644 index 00000000000..b22773e8779 --- /dev/null +++ b/packages/dnb-ui-lib/stories/components/Button.js @@ -0,0 +1,45 @@ +/** + * dnb-ui-lib Component Story + * + */ + +import React /* , { useState, useEffect } */ from 'react' +import { Wrapper, Box } from '../helpers' +// import styled from '@emotion/styled' + +import { Button } from '../../src/components' + +export default [ + 'Buttons', + () => ( + + +