diff --git a/packages/dnb-design-system-portal/src/docs/uilib/about-the-lib/releases/eufemia/v10-info.md b/packages/dnb-design-system-portal/src/docs/uilib/about-the-lib/releases/eufemia/v10-info.md index 695ebff026b..6c98fa55e96 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/about-the-lib/releases/eufemia/v10-info.md +++ b/packages/dnb-design-system-portal/src/docs/uilib/about-the-lib/releases/eufemia/v10-info.md @@ -30,6 +30,30 @@ v10 of @dnb/eufemia contains _breaking changes_. As a migration process, you can 1. Find `use_navigation` and remove it or replace it with `mode="strict"` or `mode="loose"`. 1. URL support has been removed – so props like `active_url`, `url`, `url_future`, and `url_passed` are not supported anymore. You have to handle it by yourself from inside your application. Here is [an example](/uilib/components/step-indicator/#stepindicator-with-a-router). +### Breakpoints + +Some [breakpoints](https://eufemia.dnb.no/uilib/usage/layout/media-queries) sizes have changed: + +- **xx-large:** `1280` is now `1440` – and `80em` is now `90em` +- **x-large:** `1152` is now `1280` – and `72em` is now `80em` +- **large:** `960` is now `1152` – and `60em` is now `72em` +- **medium:** `800` is now `960` – and `50em` is now `60em` + +1. Find `$layout-x-large` and replace with `$layout-large` +1. Find `$layout-xx-large` and replace with `$layout-x-large` +1. Find `--layout-x-large` and replace with `--layout-large` +1. Find `--layout-xx-large` and replace with `--layout-x-large` + +**NB:** Import and use the Eufemia breakpoints directly in your code: + +```scss +// breakpoints.scss +@import '@dnb/eufemia/style/core/utilities'; +$layout-small: map-get($breakpoints, 'small'); +$layout-medium: map-get($breakpoints, 'medium'); +$layout-large: map-get($breakpoints, 'large'); +``` + ### Table 1. Ensure all table sub elements have a CSS Class: diff --git a/packages/dnb-design-system-portal/src/docs/uilib/usage/layout/media-queries.md b/packages/dnb-design-system-portal/src/docs/uilib/usage/layout/media-queries.md index ed45994d418..07aec2cb8e8 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/usage/layout/media-queries.md +++ b/packages/dnb-design-system-portal/src/docs/uilib/usage/layout/media-queries.md @@ -17,15 +17,14 @@ In order to make it as declarative and easy to handle media queries from JavaScr UX designers are using a 12 column system during their design processes. -| Pixel | Type | Rem | Custom Property | Comments | -| ----- | ---------- | -------- | ------------------- | ----------- | -| 640 | `small` | **40em** | `--layout-small` | Mobile | -| 800 | `medium` | **50em** | `--layout-medium` | | -| 960 | `large` | **60em** | `--layout-large` | DNB default | -| 1152 | `x-large` | **72em** | `--layout-x-large` | | -| 1280 | `xx-large` | **80em** | `--layout-xx-large` | | +| Pixel | Type | Rem | Custom Property | Comments | +| ----- | -------- | -------- | ----------------- | ---------- | +| 640 | `small` | **40em** | `--layout-small` | 4 columns | +| 960 | `medium` | **60em** | `--layout-medium` | 6 columns | +| 1152 | `large` | **72em** | `--layout-large` | 12 columns | - + + ## MediaQuery component and React Hooks @@ -41,7 +40,7 @@ By using `matchMedia` we only render when the requested media query actually cha ### CSS similarity -It uses the same query API as CSS uses. You are able to provide your query also raw, by using e.g. `query="(min-width: 50em)"`. But your custom queries will quickly grow and mess up your application code unnecessarily. +It uses the same query API as CSS uses. You are able to provide your query also raw, by using e.g. `query="(min-width: 60em)"`. But your custom queries will quickly grow and mess up your application code unnecessarily. ### Properties @@ -141,12 +140,12 @@ You have plenty of possibilities to mix and match: matches small and medium screens and during SSR - - matches all between small and x-large screens or all print media + + matches all between small and large screens or all print media - - matches screens to a max of 80em + + matches screens to a max of 60em @@ -206,7 +205,17 @@ import { defaultBreakpoints } from '@dnb/eufemia/shared/MediaQueryUtils' You can re-use the SASS mixins from Eufemia: ```scss -@import '@dnb/eufemia/style/core/utilities.scss'; +// breakpoints.scss +@import '@dnb/eufemia/style/core/utilities'; +$layout-small: map-get($breakpoints, 'small'); +$layout-medium: map-get($breakpoints, 'medium'); +$layout-large: map-get($breakpoints, 'large'); +``` + +or like this: + +```scss +@import '@dnb/eufemia/style/core/utilities'; @include allBelow(large) { /* Your CSS */ @@ -221,19 +230,13 @@ You can re-use the SASS mixins from Eufemia: ```css @media screen and (max-width: 40em) { - /* small (mobile) */ -} -@media screen and (max-width: 50em) { - /* medium */ + /* small */ } @media screen and (max-width: 60em) { - /* large (default) */ -} -@media screen and (min-width: 60em) and (max-width: 72em) { - /* x-large */ + /* medium */ } -@media screen and (min-width: 70em) and (max-width: 80em) { - /* xx-large */ +@media screen and (max-width: 72em) { + /* large */ } ``` @@ -249,7 +252,7 @@ import MatchMediaMock from 'jest-matchmedia-mock' const matchMedia = new MatchMediaMock() it('your test', () => { - matchMedia.useMediaQuery('(min-width: 50em) and (max-width: 60em)') + matchMedia.useMediaQuery('(min-width: 40em) and (max-width: 60em)') ... }) ``` diff --git a/packages/dnb-design-system-portal/src/shared/menu/SearchBar.module.scss b/packages/dnb-design-system-portal/src/shared/menu/SearchBar.module.scss index f7f4a0cc63f..4301b835032 100644 --- a/packages/dnb-design-system-portal/src/shared/menu/SearchBar.module.scss +++ b/packages/dnb-design-system-portal/src/shared/menu/SearchBar.module.scss @@ -1,7 +1,9 @@ +@import '@dnb/eufemia/src/style/core/utilities.scss'; + .autocompleteStyle { :global { margin-right: 1rem; - @media (max-width: 40em) { + @include allBelow(small) { margin-right: 0.5rem; } @@ -9,7 +11,7 @@ &, input { width: 40vw; - @media (max-width: 40em) { + @include allBelow(small) { width: 50vw; } } diff --git a/packages/dnb-eufemia/src/components/accordion/style/dnb-accordion.scss b/packages/dnb-eufemia/src/components/accordion/style/dnb-accordion.scss index 9fdc5980556..884412fccf1 100644 --- a/packages/dnb-eufemia/src/components/accordion/style/dnb-accordion.scss +++ b/packages/dnb-eufemia/src/components/accordion/style/dnb-accordion.scss @@ -147,7 +147,7 @@ position: static; max-width: 60rem; - @media screen and (min-width: 40em) { + @include allAbove(small) { &__header { width: 40%; // 40% / 60% } @@ -173,7 +173,7 @@ // } } &-group--single-container & > &__header &__header__icon { - @media screen and (min-width: 40em) { + @include allAbove(small) { transform: rotate(-90deg); } } @@ -183,7 +183,7 @@ &__children { max-width: 60rem; - @media screen and (min-width: 40em) { + @include allAbove(small) { position: relative; display: flex; flex-direction: column; diff --git a/packages/dnb-eufemia/src/components/breadcrumb/__tests__/Breadcrumb.test.tsx b/packages/dnb-eufemia/src/components/breadcrumb/__tests__/Breadcrumb.test.tsx index 2e58cca121c..ba44fe1ab29 100644 --- a/packages/dnb-eufemia/src/components/breadcrumb/__tests__/Breadcrumb.test.tsx +++ b/packages/dnb-eufemia/src/components/breadcrumb/__tests__/Breadcrumb.test.tsx @@ -159,7 +159,7 @@ describe('Breadcrumb', () => { }) it('variant collapse opens the collapsed content on click', () => { - matchMedia.useMediaQuery('(max-width: 50em)') + matchMedia.useMediaQuery('(max-width: 60em)') render( { - matchMedia.useMediaQuery('(min-width: 50em)') + matchMedia.useMediaQuery('(min-width: 60em)') document.body.innerHTML = `
` }) function simulateSmallScreen() { - matchMedia.useMediaQuery('(min-width: 0) and (max-width: 50em)') + matchMedia.useMediaQuery('(min-width: 0) and (max-width: 60em)') } const stepIndicatorListData = [ diff --git a/packages/dnb-eufemia/src/components/toggle-button/style/dnb-toggle-button.scss b/packages/dnb-eufemia/src/components/toggle-button/style/dnb-toggle-button.scss index db59f5cef97..1661bd509b7 100644 --- a/packages/dnb-eufemia/src/components/toggle-button/style/dnb-toggle-button.scss +++ b/packages/dnb-eufemia/src/components/toggle-button/style/dnb-toggle-button.scss @@ -187,7 +187,7 @@ } // default spacing for a single toggle button - @media screen and (min-width: 40em) { + @include allAbove(small) { .dnb-form-label + & { transform: translateY(-0.5rem); } diff --git a/packages/dnb-eufemia/src/fragments/drawer-list/style/dnb-drawer-list.scss b/packages/dnb-eufemia/src/fragments/drawer-list/style/dnb-drawer-list.scss index a8430d249db..52bfe626719 100644 --- a/packages/dnb-eufemia/src/fragments/drawer-list/style/dnb-drawer-list.scss +++ b/packages/dnb-eufemia/src/fragments/drawer-list/style/dnb-drawer-list.scss @@ -404,7 +404,7 @@ align-items: center; } } - @media screen and (min-width: 40em) { + @include allAbove(small) { &--action-menu#{&}--is-popup#{&}--left &__list { left: 0; } diff --git a/packages/dnb-eufemia/src/shared/MediaQueryUtils.ts b/packages/dnb-eufemia/src/shared/MediaQueryUtils.ts index cefef089fc1..3295615d298 100644 --- a/packages/dnb-eufemia/src/shared/MediaQueryUtils.ts +++ b/packages/dnb-eufemia/src/shared/MediaQueryUtils.ts @@ -13,10 +13,10 @@ export type MediaQueryBreakpoints = Partial< export const defaultBreakpoints: MediaQueryBreakpoints = { small: '40em', - medium: '50em', - large: '60em', - 'x-large': '72em', - 'xx-large': '80em', + medium: '60em', + large: '72em', + 'x-large': '80em', + 'xx-large': '90em', } export type MediaQueryCondition = diff --git a/packages/dnb-eufemia/src/shared/__tests__/MediaQuery.test.tsx b/packages/dnb-eufemia/src/shared/__tests__/MediaQuery.test.tsx index abbec607d50..c4e94978be9 100644 --- a/packages/dnb-eufemia/src/shared/__tests__/MediaQuery.test.tsx +++ b/packages/dnb-eufemia/src/shared/__tests__/MediaQuery.test.tsx @@ -40,7 +40,7 @@ describe('MediaQuery', () => { }) it('should match for query with medium width', () => { - matchMedia.useMediaQuery('(min-width: 50em) and (max-width: 60em)') + matchMedia.useMediaQuery('(min-width: 60em) and (max-width: 72em)') const Comp = mount( @@ -52,7 +52,7 @@ describe('MediaQuery', () => { it('should match for query when different breakpoints are given', () => { matchMedia.useMediaQuery( - '(min-width: 40em) and (max-width: 72em), (min-width: 0) and (max-width: 30rem), (max-width: 80em)' + '(min-width: 40em) and (max-width: 80em), (min-width: 0) and (max-width: 30rem), (max-width: 90em)' ) const Comp = mount( @@ -145,7 +145,7 @@ describe('MediaQuery', () => { it('should match for query with medium and large width', () => { matchMedia.useMediaQuery( - '(min-width: 50em) and (max-width: 60em), (min-width: 60em) and (max-width: 72em)' + '(min-width: 60em) and (max-width: 72em), (min-width: 72em) and (max-width: 80em)' ) const Comp = mount( @@ -163,7 +163,7 @@ describe('MediaQuery', () => { it('should handle media query changes', () => { matchMedia.useMediaQuery( - 'not screen and (min-width: 0) and (max-width: 60em)' + 'not screen and (min-width: 0) and (max-width: 72em)' ) const Playground = () => { diff --git a/packages/dnb-eufemia/src/shared/__tests__/MediaQueryUtils.test.tsx b/packages/dnb-eufemia/src/shared/__tests__/MediaQueryUtils.test.tsx index 5a8ed316517..eea5765cbaf 100644 --- a/packages/dnb-eufemia/src/shared/__tests__/MediaQueryUtils.test.tsx +++ b/packages/dnb-eufemia/src/shared/__tests__/MediaQueryUtils.test.tsx @@ -20,7 +20,7 @@ describe('onMediaQueryChange', () => { matchMedia.useMediaQuery('(min-width: 40em)') expect(callback).toHaveBeenCalledTimes(1) - matchMedia.useMediaQuery('(min-width: 50em)') + matchMedia.useMediaQuery('(min-width: 60em)') expect(callback).toHaveBeenCalledTimes(1) matchMedia.useMediaQuery('(min-width: 40em)') @@ -54,7 +54,7 @@ describe('onMediaQueryChange', () => { }) ) - matchMedia.useMediaQuery('(min-width: 60em)') + matchMedia.useMediaQuery('(min-width: 72em)') expect(callback).toHaveBeenCalledTimes(2) expect(callback).toHaveBeenCalledWith( true, @@ -127,7 +127,7 @@ describe('buildQuery', () => { maxWidth: 'large', }, }) - ).toBe('(min-width: 40em) and (max-width: 60em)') + ).toBe('(min-width: 40em) and (max-width: 72em)') }) it('should return query string by given but shorten breakpoint type', () => { @@ -138,7 +138,7 @@ describe('buildQuery', () => { max: 'large', }, }) - ).toBe('(min-width: 40em) and (max-width: 60em)') + ).toBe('(min-width: 40em) and (max-width: 72em)') }) it('should return reversed query string by given but shorten breakpoint type', () => { @@ -150,7 +150,7 @@ describe('buildQuery', () => { max: 'large', }, }) - ).toBe('not all and (min-width: 40em) and (max-width: 60em)') + ).toBe('not all and (min-width: 40em) and (max-width: 72em)') }) it('should return reversed query string by given but shorten breakpoint type', () => { @@ -162,7 +162,7 @@ describe('buildQuery', () => { max: 'large', }, }) - ).toBe('not all and (min-width: 40em) and (max-width: 60em)') + ).toBe('not all and (min-width: 40em) and (max-width: 72em)') }) it('should return not change the min value to zero if only a small min property was given', () => { @@ -188,10 +188,10 @@ describe('buildQuery', () => { buildQuery({ when: { min: 10, - max: '60em', + max: '72em', }, }) - ).toBe('(min-width: 10em) and (max-width: 60em)') + ).toBe('(min-width: 10em) and (max-width: 72em)') }) it('should return not reversed query string by providing reversed twice', () => { @@ -204,7 +204,7 @@ describe('buildQuery', () => { max: 'large', }, }) - ).toBe('all and (min-width: 40em) and (max-width: 60em)') + ).toBe('all and (min-width: 40em) and (max-width: 72em)') }) it('should return reversed query string', () => { @@ -216,7 +216,7 @@ describe('buildQuery', () => { max: 'large', }, }) - ).toBe('not all and (min-width: 40em) and (max-width: 60em)') + ).toBe('not all and (min-width: 40em) and (max-width: 72em)') }) it('should return query string based on types given as an array', () => { @@ -224,7 +224,7 @@ describe('buildQuery', () => { buildQuery({ when: [{ max: 'small' }, { min: 'large', max: 'x-large' }], }) - ).toBe('(max-width: 40em), (min-width: 60em) and (max-width: 72em)') + ).toBe('(max-width: 40em), (min-width: 72em) and (max-width: 80em)') }) it('should return query string based on types given as a string', () => { @@ -232,7 +232,7 @@ describe('buildQuery', () => { buildQuery({ when: [{ max: 'small' }, { min: 'x-large', max: 'xx-large' }], }) - ).toBe('(max-width: 40em), (min-width: 72em) and (max-width: 80em)') + ).toBe('(max-width: 40em), (min-width: 80em) and (max-width: 90em)') }) it('should return comma seperated query string for multiple media queries', () => { @@ -321,7 +321,7 @@ describe('convertToMediaQuery', () => { minWidth: 'small', maxWidth: 'large', }) - ).toBe('(min-width: 40em) and (max-width: 60em)') + ).toBe('(min-width: 40em) and (max-width: 72em)') }) it('should return query string by given but shorten breakpoint type', () => { @@ -330,7 +330,7 @@ describe('convertToMediaQuery', () => { min: 'small', max: 'large', }) - ).toBe('(min-width: 40em) and (max-width: 60em)') + ).toBe('(min-width: 40em) and (max-width: 72em)') }) it('should return reversed query string by given but shorten breakpoint type', () => { @@ -340,7 +340,7 @@ describe('convertToMediaQuery', () => { min: 'small', max: 'large', }) - ).toBe('not all and (min-width: 40em) and (max-width: 60em)') + ).toBe('not all and (min-width: 40em) and (max-width: 72em)') }) it('should add em unit to dimension features', () => { diff --git a/packages/dnb-eufemia/src/shared/__tests__/useMedia.test.tsx b/packages/dnb-eufemia/src/shared/__tests__/useMedia.test.tsx index 59aec5850a2..efaafb4441c 100644 --- a/packages/dnb-eufemia/src/shared/__tests__/useMedia.test.tsx +++ b/packages/dnb-eufemia/src/shared/__tests__/useMedia.test.tsx @@ -22,8 +22,8 @@ describe('useMedia', () => { const ABOVE = '100em' const SMALL = '39em' // 40em - const MEDIUM = '49em' // 50em - const LARGE = '59em' // 60em + const MEDIUM = '59em' // 60em + const LARGE = '79em' // 80em beforeEach(() => { jest.spyOn(window, 'matchMedia').mockImplementation(matchMedia) @@ -423,8 +423,8 @@ describe('useMedia', () => { setMedia({ width: ABOVE }) const SMALL = '39em' // 40em - const MEDIUM = '59em' // 60em - const LARGE = '71em' // 72em + const MEDIUM = '71em' // 72em + const LARGE = '79em' // 80em const wrapper = (props) => ( { value={{ breakpoints: { small: '40em', - medium: '60em', - large: '72em', + medium: '72em', + large: '80em', }, }} /> @@ -514,7 +514,7 @@ describe('useMedia', () => { describe('using jest-matchmedia-mock mocker', () => { const SMALL = '40em' - const MEDIUM = '50em' + const MEDIUM = '60em' const matchMedia = mockMediaQuery() const matchMediaMock = window.matchMedia // set in mockMediaQuery diff --git a/packages/dnb-eufemia/src/shared/__tests__/useMediaQuery.test.tsx b/packages/dnb-eufemia/src/shared/__tests__/useMediaQuery.test.tsx index a4f894b6555..100d4c7694e 100644 --- a/packages/dnb-eufemia/src/shared/__tests__/useMediaQuery.test.tsx +++ b/packages/dnb-eufemia/src/shared/__tests__/useMediaQuery.test.tsx @@ -46,7 +46,7 @@ describe('useMediaQuery', () => { }) it('should have valid strings inside render', () => { - matchMedia.useMediaQuery('(min-width: 50em) and (max-width: 60em)') + matchMedia.useMediaQuery('(min-width: 60em) and (max-width: 72em)') const { rerender } = render( @@ -87,7 +87,7 @@ describe('useMediaQuery', () => { }) it('should have valid strings inside render', () => { - matchMedia.useMediaQuery('(min-width: 0) and (max-width: 72em)') + matchMedia.useMediaQuery('(min-width: 0) and (max-width: 80em)') render( @@ -100,7 +100,7 @@ describe('useMediaQuery', () => { it('should handle media query changes', () => { matchMedia.useMediaQuery( - 'not screen and (min-width: 40em) and (max-width: 60em)' + 'not screen and (min-width: 40em) and (max-width: 72em)' ) const match1Handler = jest.fn() @@ -162,7 +162,7 @@ describe('useMediaQuery', () => { .spyOn(window, 'matchMedia') .mockImplementationOnce(jest.fn(window.matchMedia)) - matchMedia.useMediaQuery('(min-width: 0) and (max-width: 72em)') + matchMedia.useMediaQuery('(min-width: 0) and (max-width: 80em)') const when = { min: '0', max: 'x-large' } diff --git a/packages/dnb-eufemia/src/style/core/properties.scss b/packages/dnb-eufemia/src/style/core/properties.scss index eb69eeb2104..78a3ce700b8 100644 --- a/packages/dnb-eufemia/src/style/core/properties.scss +++ b/packages/dnb-eufemia/src/style/core/properties.scss @@ -93,11 +93,10 @@ // Layout --layout-small: 40em; // 640 - --layout-medium: 50em; // 800 - --layout-large: 60em; // 960 - --layout-x-large: 72em; // 1152 - --layout-xx-large: 80em; // 1280 - --layout-xxx-large: 90em; // 1440 + --layout-medium: 60em; // 960 + --layout-large: 72em; // 1152 + --layout-x-large: 80em; // 1280 (not documented yet) + --layout-xx-large: 90em; // 1440 (not documented yet) // Shadow --shadow-default: 0 8px 16px rgba(51, 51, 51, 0.08); diff --git a/packages/dnb-eufemia/src/style/core/utilities.scss b/packages/dnb-eufemia/src/style/core/utilities.scss index a1bf977adc4..d39429b5059 100644 --- a/packages/dnb-eufemia/src/style/core/utilities.scss +++ b/packages/dnb-eufemia/src/style/core/utilities.scss @@ -261,10 +261,10 @@ $focusRingColor: var(--color-emerald-green); $breakpoints: ( 'small': 40em, - 'medium': 50em, - 'large': 60em, - 'x-large': 72em, - 'xx-large': 80em, + 'medium': 60em, + 'large': 72em, + 'x-large': 80em /* not documented yet */, + 'xx-large': 90em /* not documented yet */, ); // Example usage: diff --git a/packages/dnb-eufemia/src/style/properties.js b/packages/dnb-eufemia/src/style/properties.js index 27b6e95b9df..276595bd1b0 100644 --- a/packages/dnb-eufemia/src/style/properties.js +++ b/packages/dnb-eufemia/src/style/properties.js @@ -69,11 +69,10 @@ export default { '--spacing-x-large': '3rem', '--spacing-xx-large': '3.5rem', '--layout-small': '40em', - '--layout-medium': '50em', - '--layout-large': '60em', - '--layout-x-large': '72em', - '--layout-xx-large': '80em', - '--layout-xxx-large': '90em', + '--layout-medium': '60em', + '--layout-large': '72em', + '--layout-x-large': '80em', + '--layout-xx-large': '90em', '--shadow-default': '0 8px 16px rgba(51, 51, 51, 0.08)', '--shadow-default-x': '0', '--shadow-default-y': '8px',