From a162a438bb095cf5440c90f967094961946093b9 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Mon, 24 Apr 2023 14:49:05 +0100 Subject: [PATCH 01/23] feat(806): implement #400 container queries --- src/utils/__tests__/base.test.ts | 33 +++++++++++++++- src/utils/__tests__/is-valid-css-size.test.ts | 21 ++++++++++ src/utils/responsive-helpers.ts | 18 ++++++++- src/utils/style/base.ts | 39 +++++++++++++++++-- src/utils/style/getters.ts | 6 ++- src/utils/style/types.ts | 2 +- src/utils/style/utils.ts | 11 ++++++ 7 files changed, 121 insertions(+), 9 deletions(-) create mode 100644 src/utils/__tests__/is-valid-css-size.test.ts diff --git a/src/utils/__tests__/base.test.ts b/src/utils/__tests__/base.test.ts index 5d7b7ad669..0d5839465a 100644 --- a/src/utils/__tests__/base.test.ts +++ b/src/utils/__tests__/base.test.ts @@ -58,7 +58,38 @@ describe('getXFromTheme', () => { '@media screen and (min-width: 768px)': {width: '12px'}, }); }); - + test('getXFromTheme with CQ value', () => { + const result = getXFromTheme('sizing')('width', { + '300px': 'sizing010', + '500px': 'sizing020', + '800px': 'sizing030', + })({theme}); + expect(result).toEqual({ + '@container (min-width: 300px)': {width: '4px'}, + '@container (min-width: 500px)': {width: '8px'}, + '@container (min-width: 800px)': {width: '12px'}, + }); + }); + test('getXFromTheme with CQ & MQ value', () => { + const result = getXFromTheme('sizing')('width', { + xs: 'sizing010', + sm: 'sizing020', + '300px': 'sizing010', + '500px': 'sizing020', + '800px': 'sizing030', + })({theme}); + expect(result).toEqual({ + '@container (min-width: 300px)': {width: '4px'}, + '@container (min-width: 500px)': {width: '8px'}, + '@container (min-width: 800px)': {width: '12px'}, + '@media screen and (max-width: 479px)': { + width: '4px', + }, + '@media screen and (min-width: 480px)': { + width: '8px', + }, + }); + }); test('getXFromTheme with non MQ and callback', () => { const cb = (value: string) => ({padding: `${value} 0`, width: value}); const result = getXFromTheme('sizing')(cb, 'sizing050')({theme}); diff --git a/src/utils/__tests__/is-valid-css-size.test.ts b/src/utils/__tests__/is-valid-css-size.test.ts new file mode 100644 index 0000000000..7c7ab2825d --- /dev/null +++ b/src/utils/__tests__/is-valid-css-size.test.ts @@ -0,0 +1,21 @@ +import {isValidCSSSizeUnit} from '../style/utils'; + +describe('isValidCSSSizeUnit', () => { + it('should return true for valid CSS size units', () => { + expect(isValidCSSSizeUnit('12px')).toBe(true); + expect(isValidCSSSizeUnit('100%')).toBe(true); + expect(isValidCSSSizeUnit('10em')).toBe(true); + expect(isValidCSSSizeUnit('24pt')).toBe(true); + expect(isValidCSSSizeUnit('100cm')).toBe(true); + expect(isValidCSSSizeUnit('0.5rem')).toBe(true); + expect(isValidCSSSizeUnit('0.5vmin')).toBe(true); + }); + + it('should return false for invalid CSS size units', () => { + expect(isValidCSSSizeUnit('10')).toBe(false); + expect(isValidCSSSizeUnit('10pt ')).toBe(false); + expect(isValidCSSSizeUnit('abc')).toBe(false); + expect(isValidCSSSizeUnit('50deg')).toBe(false); + expect(isValidCSSSizeUnit('2px2em')).toBe(false); + }); +}); diff --git a/src/utils/responsive-helpers.ts b/src/utils/responsive-helpers.ts index 34a3361c78..04dfa5ae50 100644 --- a/src/utils/responsive-helpers.ts +++ b/src/utils/responsive-helpers.ts @@ -1,5 +1,6 @@ import {Breakpoints, BreakpointKeys, Theme} from '../theme'; import {hasOwnProperty} from './has-own-property'; +import {isValidCSSSizeUnit} from './style/utils'; interface ThemeProp { theme: Theme; @@ -50,4 +51,19 @@ export const isResponsive = ( ): prop is Record => !!prop && typeof prop === 'object' && - Object.keys(breakpoints).some(bp => prop && hasOwnProperty(prop, bp)); + (Object.keys(breakpoints).some(bp => prop && hasOwnProperty(prop, bp)) || + Object.keys(prop).some(p => isValidCSSSizeUnit(p))); + +export const getContainerQuery = ( + minWidth: string, + maxWidth?: string, +): string => { + const queries = []; + if (minWidth) { + queries.push(`(min-width: ${minWidth})`); + } + if (maxWidth) { + queries.push(`(max-width: ${maxWidth})`); + } + return `@container ${queries.join(' AND ')}`; +}; diff --git a/src/utils/style/base.ts b/src/utils/style/base.ts index fca9eb09df..19fd02bff8 100644 --- a/src/utils/style/base.ts +++ b/src/utils/style/base.ts @@ -1,6 +1,10 @@ import {Theme, BreakpointKeys} from '../../theme'; -import {isResponsive, getMediaQueryFromTheme} from '../responsive-helpers'; -import {filterObject} from '../filter-object'; +import { + isResponsive, + getMediaQueryFromTheme, + getContainerQuery, +} from '../responsive-helpers'; +import {filterObject, rejectObject} from '../filter-object'; import {getToken} from '../get-token'; import {ThemeProp} from '../style-types'; import {MQ} from './types'; @@ -76,7 +80,7 @@ export const getResponsiveValueFromTheme = ( ([a], [b]) => mq.indexOf(a as BreakpointKeys) - mq.indexOf(b as BreakpointKeys), ) as any; // eslint-disable-line @typescript-eslint/no-explicit-any - const cssObject = presetKeys + const cssMediaQueryObject = presetKeys .filter( // Exclude invalid breakpoints and theme section keys ([breakpointKey, presetKey]) => @@ -114,7 +118,34 @@ export const getResponsiveValueFromTheme = ( return acc; }, {} as Record); - return Object.entries(cssObject); + // get container queries + const containerKeys: [string, ThemeToken][] = Object.entries( + rejectObject(propKeys, mq), + ) as any; // eslint-disable-line @typescript-eslint/no-explicit-any + + const cssContainerQueryObject = containerKeys.reduce( + (acc, [minWidth, presetKey]) => { + let preset = '' as Record[ThemeToken]; + const MQtokens = + typeof presetKey === 'string' && (presetKey as string).split(' '); + if (themeKey === 'spacePresets' && isMQTokenArray(MQtokens)) { + preset = mapTokensArray(MQtokens); + } else { + preset = + section[presetKey] || + (canHaveNonThemeValue && + isValidUnit(themeKey, presetKey) && + presetKey); + } + + const mediaQuery = getContainerQuery(minWidth); + acc[mediaQuery] = preset; + return acc; + }, + {} as Record, + ); + + return Object.entries({...cssMediaQueryObject, ...cssContainerQueryObject}); } const noMQtokens = diff --git a/src/utils/style/getters.ts b/src/utils/style/getters.ts index 8eb1175374..37789322ca 100644 --- a/src/utils/style/getters.ts +++ b/src/utils/style/getters.ts @@ -353,7 +353,7 @@ export const handleResponsiveProp = ( ? commonMQKeys : ['xs', ...commonMQKeys]; - const cssObject = usedMQKeys.reduce((acc, mqKey, index) => { + const cssMediaQueryObject = usedMQKeys.reduce((acc, mqKey, index) => { const fromMqKey = mqKey; const toMqKey = usedMQKeys[index + 1] ? usedMQKeys[index + 1] : undefined; @@ -378,5 +378,7 @@ export const handleResponsiveProp = ( return acc; }, {} as Record) as CSSObject; - return cssObject; + const cssContentQueryObject = {}; + + return {...cssMediaQueryObject, ...cssContentQueryObject}; }; diff --git a/src/utils/style/types.ts b/src/utils/style/types.ts index 805acd1a61..d3608d078b 100644 --- a/src/utils/style/types.ts +++ b/src/utils/style/types.ts @@ -6,4 +6,4 @@ export type MQPartial = Partial<{ xl: T; }>; -export type MQ = T | MQPartial; +export type MQ = T | MQPartial | {[minWidth: string]: T}; diff --git a/src/utils/style/utils.ts b/src/utils/style/utils.ts index f88d275760..7bb2700758 100644 --- a/src/utils/style/utils.ts +++ b/src/utils/style/utils.ts @@ -32,6 +32,12 @@ export const CSSUnits = [ 'vmin', 'vmax', '%', + 'cqw', + 'cqh', + 'cqi', + 'cqb', + 'cqmin', + 'cqmax', ]; export const CSSColorNames = [ @@ -219,6 +225,11 @@ export const isValidUnit = (themeKey: string, value: any) => { ); }; +export const isValidCSSSizeUnit = (value: string) => { + const regex = new RegExp(`^\\d+(\\.\\d+)?(${CSSUnits.join('|')})$`); + return regex.test(value); +}; + export const isArrayLikeObject = (value: string | object) => typeof value === 'object' && '0' in value; From 1608c530f242bdeefa522df524fcda9721cbfd2e Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Thu, 27 Apr 2023 13:58:56 +0100 Subject: [PATCH 02/23] feat(806): define queries on rules object --- package.json | 4 +- .../__stories/card-composable.stories.tsx | 94 ++++++++++++++++ src/headline/types.ts | 4 +- src/utils/logical-properties.ts | 14 +-- src/utils/responsive-helpers.ts | 31 +++--- src/utils/style/base.ts | 37 +++---- src/utils/style/types.ts | 9 ++ yarn.lock | 100 +++++++++--------- 8 files changed, 192 insertions(+), 101 deletions(-) diff --git a/package.json b/package.json index 8800b248d7..f27a40ad79 100644 --- a/package.json +++ b/package.json @@ -89,8 +89,8 @@ "@docsearch/css": "^3.0.0", "@docsearch/react": "^3.0.0", "@emotion/jest": "^11.2.1", - "@emotion/react": "^11.1.5", - "@emotion/styled": "^11.10.4", + "@emotion/react": "11.10.5", + "@emotion/styled": "11.10.5", "@hookform/resolvers": "^2.5.0", "@mapbox/rehype-prism": "^0.3.1", "@mdx-js/loader": "^1.5.8", diff --git a/src/card-composable/__tests__/__stories/card-composable.stories.tsx b/src/card-composable/__tests__/__stories/card-composable.stories.tsx index cd582ec4f7..6d8310910a 100644 --- a/src/card-composable/__tests__/__stories/card-composable.stories.tsx +++ b/src/card-composable/__tests__/__stories/card-composable.stories.tsx @@ -1,6 +1,7 @@ /* eslint-disable no-script-url */ import React from 'react'; import {Story as StoryType} from '@storybook/react'; +import {styled} from '../../../utils'; import { CardComposable, CardActions, @@ -32,6 +33,15 @@ import {Tag} from '../../../tag'; import {VideoPlayer} from '../../../video-player'; import {DEFAULT_VIDEO_PLAYER_CONFIG} from '../../../video-player/__tests__/config'; +const QueryContainerSmall = styled.div` + container-type: inline-size; + width: 200px; +`; +const QueryContainerLarge = styled.div` + container-type: inline-size; + width: 400px; +`; + const H = ({overrides, ...props}: Omit) => ( ( ); StoryLogicalProps.storyName = 'Logical props'; +export const StoryContainerQueries = () => { + const CardWithQueries = () => ( + 300px)', + value: 'space060', + }, + ], + }, + paddingInline: { + rules: [ + { + rule: '@container (width < 300px)', + value: 'space010', + }, + { + rule: '@container (width > 300px)', + value: 'space060', + }, + ], + }, + }} + rowGap={areasGap} + > + + Flag + 300px)', + value: 'editorialHeadline050', + }, + ], + }, + }} + > + This headlines typographyPreset changes depending on its container + size + +

+ + + + + Tag + + + + ); + return ( + + + + + + + + + + + + + ); +}; +StoryContainerQueries.storyName = 'Container Queries'; + export const StoryOverrides = () => ( diff --git a/src/headline/types.ts b/src/headline/types.ts index 5f6a798a6b..333320c6b8 100644 --- a/src/headline/types.ts +++ b/src/headline/types.ts @@ -1,8 +1,8 @@ -import {MQ} from '../utils/style'; +import {MQ, CQ} from '../utils/style'; import {LogicalProps} from '../utils/logical-properties'; export interface HeadlineOverrides extends LogicalProps { - typographyPreset?: MQ; + typographyPreset?: MQ & CQ; // < --- I don't like doing this, we could probably just allow it on MQ 🤔 kicker?: { stylePreset?: MQ; spaceInline?: MQ; diff --git a/src/utils/logical-properties.ts b/src/utils/logical-properties.ts index e8bcbadea6..dea504b5fd 100644 --- a/src/utils/logical-properties.ts +++ b/src/utils/logical-properties.ts @@ -1,4 +1,4 @@ -import {CSSObject, getTypographyPreset, getXFromTheme, MQ} from './style'; +import {CSSObject, getTypographyPreset, getXFromTheme, MQ, CQ} from './style'; import {ThemeProp} from './style-types'; import {deepMerge} from './deep-merge'; import {get} from './get'; @@ -14,12 +14,12 @@ export interface LogicalMarginProps { } export interface LogicalPaddingProps { - paddingInlineStart?: MQ; - paddingInlineEnd?: MQ; - paddingInline?: MQ; - paddingBlockStart?: MQ; - paddingBlockEnd?: MQ; - paddingBlock?: MQ; + paddingInlineStart?: MQ & CQ; + paddingInlineEnd?: MQ & CQ; + paddingInline?: MQ & CQ; + paddingBlockStart?: MQ; + paddingBlockEnd?: MQ & CQ; + paddingBlock?: MQ & CQ; } export interface LogicalProps extends LogicalMarginProps, LogicalPaddingProps {} diff --git a/src/utils/responsive-helpers.ts b/src/utils/responsive-helpers.ts index 04dfa5ae50..7839eba525 100644 --- a/src/utils/responsive-helpers.ts +++ b/src/utils/responsive-helpers.ts @@ -1,6 +1,5 @@ import {Breakpoints, BreakpointKeys, Theme} from '../theme'; import {hasOwnProperty} from './has-own-property'; -import {isValidCSSSizeUnit} from './style/utils'; interface ThemeProp { theme: Theme; @@ -48,22 +47,22 @@ export const getMediaQueryFromTheme = ( export const isResponsive = ( prop: unknown, breakpoints: Breakpoints, -): prop is Record => +): prop is Record => !!prop && typeof prop === 'object' && (Object.keys(breakpoints).some(bp => prop && hasOwnProperty(prop, bp)) || - Object.keys(prop).some(p => isValidCSSSizeUnit(p))); + hasOwnProperty(prop, 'rules')); -export const getContainerQuery = ( - minWidth: string, - maxWidth?: string, -): string => { - const queries = []; - if (minWidth) { - queries.push(`(min-width: ${minWidth})`); - } - if (maxWidth) { - queries.push(`(max-width: ${maxWidth})`); - } - return `@container ${queries.join(' AND ')}`; -}; +// export const getContainerQuery = ( +// minWidth?: string, +// maxWidth?: string, +// ): string => { +// const queries = []; +// if (minWidth) { +// queries.push(`(min-width: ${minWidth})`); +// } +// if (maxWidth) { +// queries.push(`(max-width: ${maxWidth})`); +// } +// return `@container ${queries.join(' AND ')}`; +// }; diff --git a/src/utils/style/base.ts b/src/utils/style/base.ts index 19fd02bff8..a3109a5103 100644 --- a/src/utils/style/base.ts +++ b/src/utils/style/base.ts @@ -1,13 +1,9 @@ import {Theme, BreakpointKeys} from '../../theme'; -import { - isResponsive, - getMediaQueryFromTheme, - getContainerQuery, -} from '../responsive-helpers'; -import {filterObject, rejectObject} from '../filter-object'; +import {isResponsive, getMediaQueryFromTheme} from '../responsive-helpers'; +import {filterObject} from '../filter-object'; import {getToken} from '../get-token'; import {ThemeProp} from '../style-types'; -import {MQ} from './types'; +import {CSSQuery, MQ} from './types'; import {isNonThemeValueAllowed, isValidUnit} from './utils'; import {CSSObject} from './emotion'; @@ -118,32 +114,25 @@ export const getResponsiveValueFromTheme = ( return acc; }, {} as Record); - // get container queries - const containerKeys: [string, ThemeToken][] = Object.entries( - rejectObject(propKeys, mq), - ) as any; // eslint-disable-line @typescript-eslint/no-explicit-any + const containerKeys = (propKeys.rules || []) as CSSQuery[]; - const cssContainerQueryObject = containerKeys.reduce( - (acc, [minWidth, presetKey]) => { + const cssContainerQueryObject = + containerKeys && + containerKeys.reduce((acc, query) => { + const {rule, value} = query; let preset = '' as Record[ThemeToken]; const MQtokens = - typeof presetKey === 'string' && (presetKey as string).split(' '); + typeof value === 'string' && (value as string).split(' '); if (themeKey === 'spacePresets' && isMQTokenArray(MQtokens)) { preset = mapTokensArray(MQtokens); } else { preset = - section[presetKey] || - (canHaveNonThemeValue && - isValidUnit(themeKey, presetKey) && - presetKey); + section[value] || + (canHaveNonThemeValue && isValidUnit(themeKey, value) && value); } - - const mediaQuery = getContainerQuery(minWidth); - acc[mediaQuery] = preset; + acc[rule] = preset; return acc; - }, - {} as Record, - ); + }, {} as Record); return Object.entries({...cssMediaQueryObject, ...cssContainerQueryObject}); } diff --git a/src/utils/style/types.ts b/src/utils/style/types.ts index d3608d078b..680cdff078 100644 --- a/src/utils/style/types.ts +++ b/src/utils/style/types.ts @@ -7,3 +7,12 @@ export type MQPartial = Partial<{ }>; export type MQ = T | MQPartial | {[minWidth: string]: T}; + +export type CSSQuery = { + rule: `@media ${string}` | `@container ${string}`; + value: string; +}; + +export type CQ = { + rules?: CSSQuery[]; +}; diff --git a/yarn.lock b/yarn.lock index 9705ff3920..6b7946e3a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -928,7 +928,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-jsx@^7.17.12", "@babel/plugin-syntax-jsx@^7.7.2": +"@babel/plugin-syntax-jsx@^7.7.2": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== @@ -1897,23 +1897,22 @@ "@babel/runtime" "^7.12.13" "@emotion-icons/emotion-icon" "4.0.0" -"@emotion/babel-plugin@^11.10.0": - version "11.10.2" - resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz#879db80ba622b3f6076917a1e6f648b1c7d008c7" - integrity sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA== +"@emotion/babel-plugin@^11.10.5": + version "11.10.6" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz#a68ee4b019d661d6f37dec4b8903255766925ead" + integrity sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ== dependencies: "@babel/helper-module-imports" "^7.16.7" - "@babel/plugin-syntax-jsx" "^7.17.12" "@babel/runtime" "^7.18.3" "@emotion/hash" "^0.9.0" "@emotion/memoize" "^0.8.0" - "@emotion/serialize" "^1.1.0" + "@emotion/serialize" "^1.1.1" babel-plugin-macros "^3.1.0" convert-source-map "^1.5.0" escape-string-regexp "^4.0.0" find-root "^1.1.0" source-map "^0.5.7" - stylis "4.0.13" + stylis "4.1.3" "@emotion/babel-utils@^0.6.4": version "0.6.10" @@ -1927,16 +1926,16 @@ find-root "^1.1.0" source-map "^0.7.2" -"@emotion/cache@^11.6.0": - version "11.6.0" - resolved "https://registry.npmjs.org/@emotion/cache/-/cache-11.6.0.tgz" - integrity sha512-ElbsWY1KMwEowkv42vGo0UPuLgtPYfIs9BxxVrmvsaJVvktknsHYYlx5NQ5g6zLDcOTyamlDc7FkRg2TAcQDKQ== +"@emotion/cache@^11.10.5": + version "11.10.7" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.7.tgz#2e3b12d3c7c74db0a020ae79eefc52a1b03a6908" + integrity sha512-VLl1/2D6LOjH57Y8Vem1RoZ9haWF4jesHDGiHtKozDQuBIkJm2gimVo0I02sWCuzZtVACeixTVB4jeE8qvCBoQ== dependencies: - "@emotion/memoize" "^0.7.4" - "@emotion/sheet" "^1.1.0" - "@emotion/utils" "^1.0.0" - "@emotion/weak-memoize" "^0.2.5" - stylis "^4.0.10" + "@emotion/memoize" "^0.8.0" + "@emotion/sheet" "^1.2.1" + "@emotion/utils" "^1.2.0" + "@emotion/weak-memoize" "^0.3.0" + stylis "4.1.3" "@emotion/css-prettifier@^1.0.0": version "1.0.0" @@ -1996,17 +1995,18 @@ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f" integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== -"@emotion/react@^11.1.5": - version "11.6.0" - resolved "https://registry.npmjs.org/@emotion/react/-/react-11.6.0.tgz" - integrity sha512-23MnRZFBN9+D1lHXC5pD6z4X9yhPxxtHr6f+iTGz6Fv6Rda0GdefPrsHL7otsEf+//7uqCdT5QtHeRxHCERzuw== +"@emotion/react@11.10.5": + version "11.10.5" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.5.tgz#95fff612a5de1efa9c0d535384d3cfa115fe175d" + integrity sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A== dependencies: - "@babel/runtime" "^7.13.10" - "@emotion/cache" "^11.6.0" - "@emotion/serialize" "^1.0.2" - "@emotion/sheet" "^1.1.0" - "@emotion/utils" "^1.0.0" - "@emotion/weak-memoize" "^0.2.5" + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.10.5" + "@emotion/cache" "^11.10.5" + "@emotion/serialize" "^1.1.1" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" + "@emotion/utils" "^1.2.0" + "@emotion/weak-memoize" "^0.3.0" hoist-non-react-statics "^3.3.1" "@emotion/serialize@^0.9.1": @@ -2019,10 +2019,10 @@ "@emotion/unitless" "^0.6.7" "@emotion/utils" "^0.8.2" -"@emotion/serialize@^1.0.2", "@emotion/serialize@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.0.tgz#b1f97b1011b09346a40e9796c37a3397b4ea8ea8" - integrity sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA== +"@emotion/serialize@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.1.tgz#0595701b1902feded8a96d293b26be3f5c1a5cf0" + integrity sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA== dependencies: "@emotion/hash" "^0.9.0" "@emotion/memoize" "^0.8.0" @@ -2030,20 +2030,20 @@ "@emotion/utils" "^1.2.0" csstype "^3.0.2" -"@emotion/sheet@^1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz" - integrity sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g== +"@emotion/sheet@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.1.tgz#0767e0305230e894897cadb6c8df2c51e61a6c2c" + integrity sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA== -"@emotion/styled@^11.10.4": - version "11.10.4" - resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.4.tgz#e93f84a4d54003c2acbde178c3f97b421fce1cd4" - integrity sha512-pRl4R8Ez3UXvOPfc2bzIoV8u9P97UedgHS4FPX594ntwEuAMA114wlaHvOK24HB48uqfXiGlYIZYCxVJ1R1ttQ== +"@emotion/styled@11.10.5": + version "11.10.5" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.5.tgz#1fe7bf941b0909802cb826457e362444e7e96a79" + integrity sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw== dependencies: "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.10.0" + "@emotion/babel-plugin" "^11.10.5" "@emotion/is-prop-valid" "^1.2.0" - "@emotion/serialize" "^1.1.0" + "@emotion/serialize" "^1.1.1" "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" "@emotion/utils" "^1.2.0" @@ -2082,15 +2082,15 @@ resolved "https://registry.npmjs.org/@emotion/utils/-/utils-0.8.2.tgz" integrity sha512-rLu3wcBWH4P5q1CGoSSH/i9hrXs7SlbRLkoq9IGuoPYNGQvDJ3pt/wmOM+XgYjIDRMVIdkUWt0RsfzF50JfnCw== -"@emotion/utils@^1.0.0", "@emotion/utils@^1.2.0": +"@emotion/utils@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.0.tgz#9716eaccbc6b5ded2ea5a90d65562609aab0f561" integrity sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw== -"@emotion/weak-memoize@^0.2.5": - version "0.2.5" - resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz" - integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== +"@emotion/weak-memoize@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb" + integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg== "@eslint/eslintrc@^1.0.4": version "1.0.4" @@ -18142,10 +18142,10 @@ stylis-rule-sheet@^0.0.10: resolved "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz" integrity sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw== -stylis@4.0.13: - version "4.0.13" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.13.tgz#f5db332e376d13cc84ecfe5dace9a2a51d954c91" - integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag== +stylis@4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.3.tgz#fd2fbe79f5fed17c55269e16ed8da14c84d069f7" + integrity sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA== stylis@^3.5.0: version "3.5.4" From 98504daa89eb5ee8964e4cadc1df5aa8dbb02820 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Thu, 27 Apr 2023 15:44:57 +0100 Subject: [PATCH 03/23] feat(806): extend MQ to allow CQ rules --- .../__stories/card-composable.stories.tsx | 3 +++ src/headline/types.ts | 4 ++-- src/utils/logical-properties.ts | 14 +++++++------- src/utils/style/types.ts | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/card-composable/__tests__/__stories/card-composable.stories.tsx b/src/card-composable/__tests__/__stories/card-composable.stories.tsx index 6d8310910a..63b9bbfa20 100644 --- a/src/card-composable/__tests__/__stories/card-composable.stories.tsx +++ b/src/card-composable/__tests__/__stories/card-composable.stories.tsx @@ -789,6 +789,9 @@ export const StoryContainerQueries = () => { + + + ); }; diff --git a/src/headline/types.ts b/src/headline/types.ts index 333320c6b8..5f6a798a6b 100644 --- a/src/headline/types.ts +++ b/src/headline/types.ts @@ -1,8 +1,8 @@ -import {MQ, CQ} from '../utils/style'; +import {MQ} from '../utils/style'; import {LogicalProps} from '../utils/logical-properties'; export interface HeadlineOverrides extends LogicalProps { - typographyPreset?: MQ & CQ; // < --- I don't like doing this, we could probably just allow it on MQ 🤔 + typographyPreset?: MQ; kicker?: { stylePreset?: MQ; spaceInline?: MQ; diff --git a/src/utils/logical-properties.ts b/src/utils/logical-properties.ts index dea504b5fd..e8bcbadea6 100644 --- a/src/utils/logical-properties.ts +++ b/src/utils/logical-properties.ts @@ -1,4 +1,4 @@ -import {CSSObject, getTypographyPreset, getXFromTheme, MQ, CQ} from './style'; +import {CSSObject, getTypographyPreset, getXFromTheme, MQ} from './style'; import {ThemeProp} from './style-types'; import {deepMerge} from './deep-merge'; import {get} from './get'; @@ -14,12 +14,12 @@ export interface LogicalMarginProps { } export interface LogicalPaddingProps { - paddingInlineStart?: MQ & CQ; - paddingInlineEnd?: MQ & CQ; - paddingInline?: MQ & CQ; - paddingBlockStart?: MQ; - paddingBlockEnd?: MQ & CQ; - paddingBlock?: MQ & CQ; + paddingInlineStart?: MQ; + paddingInlineEnd?: MQ; + paddingInline?: MQ; + paddingBlockStart?: MQ; + paddingBlockEnd?: MQ; + paddingBlock?: MQ; } export interface LogicalProps extends LogicalMarginProps, LogicalPaddingProps {} diff --git a/src/utils/style/types.ts b/src/utils/style/types.ts index 680cdff078..78c4c01370 100644 --- a/src/utils/style/types.ts +++ b/src/utils/style/types.ts @@ -6,7 +6,7 @@ export type MQPartial = Partial<{ xl: T; }>; -export type MQ = T | MQPartial | {[minWidth: string]: T}; +export type MQ = (T | MQPartial) & CQ; export type CSSQuery = { rule: `@media ${string}` | `@container ${string}`; From 53d1307e62c407e08e7cc41426555a40c2768091 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Tue, 2 May 2023 13:26:06 +0100 Subject: [PATCH 04/23] feat(806): wip --- src/block/block.tsx | 6 +- .../__stories/card-composable.stories.tsx | 22 +++--- src/card-composable/styled.tsx | 2 + src/grid-layout/types.ts | 46 ++++++------ src/headline/types.ts | 10 +-- .../__tests__/text-block.stories.tsx | 71 +++++++++++++++++++ src/text-block/types.ts | 6 +- src/utils/logical-properties.ts | 31 ++++---- src/utils/style/base.ts | 2 +- src/utils/style/types.ts | 17 +++-- 10 files changed, 151 insertions(+), 62 deletions(-) diff --git a/src/block/block.tsx b/src/block/block.tsx index 03a639a304..5d3c26d8bb 100644 --- a/src/block/block.tsx +++ b/src/block/block.tsx @@ -6,12 +6,14 @@ import { MQ, getSpacingFromTheme, getStylePresetFromTheme, + ContainerQueryProps, } from '../utils/style'; import {getTransitionPresetFromTheme} from '../utils/style/transition-preset'; export interface BlockProps extends React.HTMLAttributes, - LogicalProps { + LogicalProps, + ContainerQueryProps { as?: keyof JSX.IntrinsicElements; stylePreset?: MQ; transitionPreset?: TransitionToken | TransitionToken[]; @@ -26,6 +28,8 @@ export interface BlockProps } const StyledDiv = styled.div` + ${({containerType}) => containerType && `container-type: ${containerType}`} + ${({containerName}) => containerName && `container-name: ${containerName}`} ${({stylePreset}) => stylePreset && getStylePresetFromTheme(stylePreset)} ${({spaceInline}) => spaceInline && getSpacingFromTheme(spaceInline, undefined, 'marginRight')} diff --git a/src/card-composable/__tests__/__stories/card-composable.stories.tsx b/src/card-composable/__tests__/__stories/card-composable.stories.tsx index 63b9bbfa20..9795cec9da 100644 --- a/src/card-composable/__tests__/__stories/card-composable.stories.tsx +++ b/src/card-composable/__tests__/__stories/card-composable.stories.tsx @@ -35,7 +35,7 @@ import {DEFAULT_VIDEO_PLAYER_CONFIG} from '../../../video-player/__tests__/confi const QueryContainerSmall = styled.div` container-type: inline-size; - width: 200px; + width: 300px; `; const QueryContainerLarge = styled.div` container-type: inline-size; @@ -718,8 +718,8 @@ export const StoryContainerQueries = () => { paddingBlock: { rules: [ { - rule: '@container (width < 300px)', - value: 'space010', + rule: '@container (width <= 300px)', + value: 'space020', }, { rule: '@container (width > 300px)', @@ -730,8 +730,8 @@ export const StoryContainerQueries = () => { paddingInline: { rules: [ { - rule: '@container (width < 300px)', - value: 'space010', + rule: '@container (width <= 300px)', + value: 'space020', }, { rule: '@container (width > 300px)', @@ -741,6 +741,7 @@ export const StoryContainerQueries = () => { }, }} rowGap={areasGap} + containerType="inline-size" > Flag @@ -749,19 +750,19 @@ export const StoryContainerQueries = () => { typographyPreset: { rules: [ { - rule: '@container (width < 300px)', + rule: '@container (width <= 300px)', value: 'editorialHeadline020', }, { rule: '@container (width > 300px)', - value: 'editorialHeadline050', + value: 'editorialHeadline040', }, ], }, }} > - This headlines typographyPreset changes depending on its container - size + This headline's typographyPreset changes depending on its + container size

@@ -789,9 +790,6 @@ export const StoryContainerQueries = () => { - - - ); }; diff --git a/src/card-composable/styled.tsx b/src/card-composable/styled.tsx index 3721418512..aabd4ab12f 100644 --- a/src/card-composable/styled.tsx +++ b/src/card-composable/styled.tsx @@ -12,6 +12,8 @@ const StyledGrid = styled(GridLayout)` ${getStylePreset('', '')}; ${getTransitionPreset('', '')}; ${({areaName}) => areaName && `grid-area: ${areaName};`} + ${({containerName}) => containerName && `container-name: ${containerName};`} + ${({containerType}) => containerType && `container-type: ${containerType};`} `; export const StyledCard = styled(StyledGrid)` diff --git a/src/grid-layout/types.ts b/src/grid-layout/types.ts index e2db2035f0..a0d1c603c9 100644 --- a/src/grid-layout/types.ts +++ b/src/grid-layout/types.ts @@ -1,5 +1,5 @@ import React from 'react'; -import {MQ} from '../utils/style'; +import {ContainerQueryProps, MQ, ResponsiveValue} from '../utils/style'; import {BlockProps} from '../block'; import {LogicalProps} from '../utils/logical-properties'; @@ -11,7 +11,8 @@ export type GridLayoutItemProps = BlockProps & { alignSelf?: MQ; column?: MQ; row?: MQ; -} & React.HTMLAttributes; +} & ContainerQueryProps & + React.HTMLAttributes; export type AreasMap = { [componentName: string]: React.FC; @@ -20,28 +21,29 @@ export type AreasMap = { export type GridLayoutRenderProps = (areas: AreasMap) => React.ReactNode; export type GridLayoutProps = { - rowGap?: MQ; - columnGap?: MQ; - rows?: MQ; - columns?: MQ; - justifyContent?: MQ; - alignContent?: MQ; - justifyItems?: MQ; - alignItems?: MQ; - areas?: MQ; - inline?: MQ; - autoColumns?: MQ; - autoRows?: MQ; - autoFlow?: MQ; + rowGap?: ResponsiveValue; + columnGap?: ResponsiveValue; + rows?: ResponsiveValue; + columns?: ResponsiveValue; + justifyContent?: ResponsiveValue; + alignContent?: ResponsiveValue; + justifyItems?: ResponsiveValue; + alignItems?: ResponsiveValue; + areas?: ResponsiveValue; + inline?: ResponsiveValue; + autoColumns?: ResponsiveValue; + autoRows?: ResponsiveValue; + autoFlow?: ResponsiveValue; children?: React.ReactNode | GridLayoutRenderProps; // eslint-disable-next-line @typescript-eslint/no-explicit-any as?: React.ElementType; overrides?: { - width?: MQ; - minWidth?: MQ; - maxWidth?: MQ; - height?: MQ; - minHeight?: MQ; - maxHeight?: MQ; + width?: ResponsiveValue; + minWidth?: ResponsiveValue; + maxWidth?: ResponsiveValue; + height?: ResponsiveValue; + minHeight?: ResponsiveValue; + maxHeight?: ResponsiveValue; } & LogicalProps; -} & Omit, 'children'>; +} & ContainerQueryProps & + Omit, 'children'>; diff --git a/src/headline/types.ts b/src/headline/types.ts index 5f6a798a6b..c7cd98630e 100644 --- a/src/headline/types.ts +++ b/src/headline/types.ts @@ -1,14 +1,14 @@ -import {MQ} from '../utils/style'; +import {ResponsiveValue} from '../utils/style'; import {LogicalProps} from '../utils/logical-properties'; export interface HeadlineOverrides extends LogicalProps { - typographyPreset?: MQ; + typographyPreset?: ResponsiveValue; kicker?: { - stylePreset?: MQ; - spaceInline?: MQ; + stylePreset?: ResponsiveValue; + spaceInline?: ResponsiveValue; }; heading?: { - stylePreset?: MQ; + stylePreset?: ResponsiveValue; }; } diff --git a/src/text-block/__tests__/text-block.stories.tsx b/src/text-block/__tests__/text-block.stories.tsx index 05cb85be53..7e02a7bce9 100644 --- a/src/text-block/__tests__/text-block.stories.tsx +++ b/src/text-block/__tests__/text-block.stories.tsx @@ -71,6 +71,77 @@ export const StoryTextBlockLogicalProps = () => ( ); StoryTextBlockLogicalProps.storyName = 'Logical props'; +export const StoryTextBlockContainerQueries = () => { + const QueryContainerSmall = styled.div` + container-type: inline-size; + width: 300px; + border: 1px dashed; + ${getColorCssFromTheme('borderColor', 'blue060')} + `; + const QueryContainerLarge = styled.div` + container-type: inline-size; + width: 600px; + border: 1px dashed; + ${getColorCssFromTheme('borderColor', 'blue060')} + `; + + return ( + + + + 300px)', + value: 'editorialParagraph030', + }, + ], + }} + stylePreset="inkContrast" + marginBlock="space040" + paddingBlock="space040" + marginInline="space040" + paddingInline="space040" + > + {BODY} + + + + + + 300px)', + value: 'editorialParagraph030', + }, + ], + }} + stylePreset="inkContrast" + marginBlock="space040" + paddingBlock="space040" + marginInline="space040" + paddingInline="space040" + > + {BODY} + + + + + ); +}; +StoryTextBlockContainerQueries.storyName = 'Container Queries'; + export const StoryTextBlockStylingOverrides = () => ( diff --git a/src/text-block/types.ts b/src/text-block/types.ts index a7fcc34afa..0e9c8d5b43 100644 --- a/src/text-block/types.ts +++ b/src/text-block/types.ts @@ -1,12 +1,12 @@ import React from 'react'; import {LogicalProps} from '../utils/logical-properties'; -import {MQ} from '../utils/style'; +import {ResponsiveValue} from '../utils/style'; export interface TextBlockProps extends React.HTMLAttributes, LogicalProps { - typographyPreset?: MQ; - stylePreset?: MQ; + typographyPreset?: ResponsiveValue; + stylePreset?: ResponsiveValue; noCrop?: boolean; as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'div' | 'span'; } diff --git a/src/utils/logical-properties.ts b/src/utils/logical-properties.ts index e8bcbadea6..ea482fa758 100644 --- a/src/utils/logical-properties.ts +++ b/src/utils/logical-properties.ts @@ -1,25 +1,30 @@ -import {CSSObject, getTypographyPreset, getXFromTheme, MQ} from './style'; +import { + CSSObject, + getTypographyPreset, + getXFromTheme, + ResponsiveValue, +} from './style'; import {ThemeProp} from './style-types'; import {deepMerge} from './deep-merge'; import {get} from './get'; import {filterObject, rejectObject} from './filter-object'; export interface LogicalMarginProps { - marginInlineStart?: MQ; - marginInlineEnd?: MQ; - marginInline?: MQ; - marginBlockStart?: MQ; - marginBlockEnd?: MQ; - marginBlock?: MQ; + marginInlineStart?: ResponsiveValue; + marginInlineEnd?: ResponsiveValue; + marginInline?: ResponsiveValue; + marginBlockStart?: ResponsiveValue; + marginBlockEnd?: ResponsiveValue; + marginBlock?: ResponsiveValue; } export interface LogicalPaddingProps { - paddingInlineStart?: MQ; - paddingInlineEnd?: MQ; - paddingInline?: MQ; - paddingBlockStart?: MQ; - paddingBlockEnd?: MQ; - paddingBlock?: MQ; + paddingInlineStart?: ResponsiveValue; + paddingInlineEnd?: ResponsiveValue; + paddingInline?: ResponsiveValue; + paddingBlockStart?: ResponsiveValue; + paddingBlockEnd?: ResponsiveValue; + paddingBlock?: ResponsiveValue; } export interface LogicalProps extends LogicalMarginProps, LogicalPaddingProps {} diff --git a/src/utils/style/base.ts b/src/utils/style/base.ts index a3109a5103..b01b06ab7e 100644 --- a/src/utils/style/base.ts +++ b/src/utils/style/base.ts @@ -114,7 +114,7 @@ export const getResponsiveValueFromTheme = ( return acc; }, {} as Record); - const containerKeys = (propKeys.rules || []) as CSSQuery[]; + const containerKeys = (propKeys.rules || []) as CSSQuery[]; const cssContainerQueryObject = containerKeys && diff --git a/src/utils/style/types.ts b/src/utils/style/types.ts index 78c4c01370..3f7134cc71 100644 --- a/src/utils/style/types.ts +++ b/src/utils/style/types.ts @@ -6,13 +6,20 @@ export type MQPartial = Partial<{ xl: T; }>; -export type MQ = (T | MQPartial) & CQ; +export type MQ = T | MQPartial; -export type CSSQuery = { +export type ResponsiveValue = MQ | CSSQueryRules; + +export type CSSQuery = { rule: `@media ${string}` | `@container ${string}`; - value: string; + value: T; +}; + +export type CSSQueryRules = { + rules?: CSSQuery[]; }; -export type CQ = { - rules?: CSSQuery[]; +export type ContainerQueryProps = { + containerType?: 'normal' | 'inline-size' | 'size'; + containerName?: string; }; From 1478cea3682fb3764aba628a55ae106c1d4e430a Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Tue, 2 May 2023 15:23:15 +0100 Subject: [PATCH 05/23] feat(806): update tests --- src/utils/__tests__/base.test.ts | 14 +++----------- src/utils/style/base.ts | 6 +++--- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/utils/__tests__/base.test.ts b/src/utils/__tests__/base.test.ts index 0d5839465a..9431e499d8 100644 --- a/src/utils/__tests__/base.test.ts +++ b/src/utils/__tests__/base.test.ts @@ -58,30 +58,22 @@ describe('getXFromTheme', () => { '@media screen and (min-width: 768px)': {width: '12px'}, }); }); - test('getXFromTheme with CQ value', () => { + test('getXFromTheme with Container Query value', () => { const result = getXFromTheme('sizing')('width', { - '300px': 'sizing010', - '500px': 'sizing020', - '800px': 'sizing030', + rules: [{rule: '@container (min-width: 300px)', value: '4px'}], })({theme}); expect(result).toEqual({ '@container (min-width: 300px)': {width: '4px'}, - '@container (min-width: 500px)': {width: '8px'}, - '@container (min-width: 800px)': {width: '12px'}, }); }); test('getXFromTheme with CQ & MQ value', () => { const result = getXFromTheme('sizing')('width', { xs: 'sizing010', sm: 'sizing020', - '300px': 'sizing010', - '500px': 'sizing020', - '800px': 'sizing030', + rules: [{rule: '@container (min-width: 300px)', value: '4px'}], })({theme}); expect(result).toEqual({ '@container (min-width: 300px)': {width: '4px'}, - '@container (min-width: 500px)': {width: '8px'}, - '@container (min-width: 800px)': {width: '12px'}, '@media screen and (max-width: 479px)': { width: '4px', }, diff --git a/src/utils/style/base.ts b/src/utils/style/base.ts index b01b06ab7e..c4bdf49581 100644 --- a/src/utils/style/base.ts +++ b/src/utils/style/base.ts @@ -3,7 +3,7 @@ import {isResponsive, getMediaQueryFromTheme} from '../responsive-helpers'; import {filterObject} from '../filter-object'; import {getToken} from '../get-token'; import {ThemeProp} from '../style-types'; -import {CSSQuery, MQ} from './types'; +import {CSSQuery, MQ, ResponsiveValue} from './types'; import {isNonThemeValueAllowed, isValidUnit} from './utils'; import {CSSObject} from './emotion'; @@ -51,7 +51,7 @@ export const getValueFromTheme = ( export const getResponsiveValueFromTheme = ( themeKey: keyof Theme, ) => ( - defaultToken?: MQ, + defaultToken?: ResponsiveValue, customProp?: Exclude, ) => ({theme, ...props}: Props) => { const section = theme[themeKey] as Record; @@ -162,7 +162,7 @@ export const getXFromTheme = (themeKey: keyof Theme) => < Props extends ThemeProp >( cssProperty: string | FromThemeCallback, - defaultToken: MQ, + defaultToken: ResponsiveValue, ) => (props: Props) => { const value = getResponsiveValueFromTheme(themeKey)(defaultToken)( props, From 2341ccc76f17463d98630cbbf8854009a8c7e3f6 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Wed, 3 May 2023 13:14:34 +0100 Subject: [PATCH 06/23] feat(806): handle responsive props container rules --- .../__tests__/stories/grid-layout.stories.tsx | 58 ++++++++++++++++ src/utils/__tests__/base.test.ts | 2 +- src/utils/__tests__/responsive-props.test.ts | 17 ++++- src/utils/style/getters.ts | 66 ++++++++++++------- 4 files changed, 117 insertions(+), 26 deletions(-) diff --git a/src/grid-layout/__tests__/stories/grid-layout.stories.tsx b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx index 5bf58a815f..36bc3d9104 100644 --- a/src/grid-layout/__tests__/stories/grid-layout.stories.tsx +++ b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx @@ -17,6 +17,12 @@ const BigRedBlock = styled(Block)` background: red; `; +const QueryContainerLarge = styled(Block)` + width: 200px; + container-type: inline-size; + container-name: grid-container; +`; + export const StoryResponsiveExample = () => ( <> Responsive grid with mixed sizing @@ -163,6 +169,58 @@ export const StoryResponsiveExample = () => ( ); StoryResponsiveExample.storyName = 'responsive'; +export const StoryContainerQueryExample = () => ( + <> + Responsive grid with mixed sizing + + 200px)', + value: '1fr 1fr 1fr 1fr', + }, + ], + }} + columns={{ + rules: [ + { + rule: '@container grid-container (width <= 200px)', + value: '1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr', + }, + { + rule: '@container grid-container (width > 200px)', + value: '1fr 1fr', + }, + ], + }} + > + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + + + +); +StoryContainerQueryExample.storyName = 'Container Queries'; + export const StoryMinMaxRepeat = () => { const boxes = Array.from(Array(20)).map((_, i) => {i} box); return ( diff --git a/src/utils/__tests__/base.test.ts b/src/utils/__tests__/base.test.ts index 9431e499d8..25e6c4afb3 100644 --- a/src/utils/__tests__/base.test.ts +++ b/src/utils/__tests__/base.test.ts @@ -73,13 +73,13 @@ describe('getXFromTheme', () => { rules: [{rule: '@container (min-width: 300px)', value: '4px'}], })({theme}); expect(result).toEqual({ - '@container (min-width: 300px)': {width: '4px'}, '@media screen and (max-width: 479px)': { width: '4px', }, '@media screen and (min-width: 480px)': { width: '8px', }, + '@container (min-width: 300px)': {width: '4px'}, }); }); test('getXFromTheme with non MQ and callback', () => { diff --git a/src/utils/__tests__/responsive-props.test.ts b/src/utils/__tests__/responsive-props.test.ts index a32939303d..33a7f92f28 100644 --- a/src/utils/__tests__/responsive-props.test.ts +++ b/src/utils/__tests__/responsive-props.test.ts @@ -2,7 +2,7 @@ import {handleResponsiveProp} from '../style/getters'; import {createTheme} from '../../theme'; describe('handleResponsiveProp', () => { - type DisplayObj = {display: string}; + type DisplayObj = {display: string | undefined}; const theme: any = createTheme({}); const handler = ({display}: DisplayObj) => ({display}); @@ -49,6 +49,21 @@ describe('handleResponsiveProp', () => { }); }); + it.only('using CQ rules value', () => { + const props = { + display: { + rules: [{rule: '@container (width > 200px)', value: 'inline'}], + }, + theme, + }; + const result = handleResponsiveProp({display: undefined}, handler)(props); + expect(result).toEqual({ + '@container (width > 200px)': { + display: 'inline', + }, + }); + }); + it('does not have XS value', () => { const props = { display: {sm: 'inline', md: 'block'}, diff --git a/src/utils/style/getters.ts b/src/utils/style/getters.ts index 37789322ca..d9ed10c24a 100644 --- a/src/utils/style/getters.ts +++ b/src/utils/style/getters.ts @@ -246,7 +246,6 @@ export const handleResponsiveProp = ( ) => string | CSSObject, ) => (props: Props): string | CSSObject => { const {breakpoints} = props.theme; - const propNames = Object.keys(propObject); // get only props that we will use @@ -288,6 +287,7 @@ export const handleResponsiveProp = ( .flatMap( (propValue: MQ) => Object.keys(propValue) as BreakpointKeys[], ) + .filter((item: BreakpointKeys | 'rules') => item !== 'rules') .filter( (item: BreakpointKeys, index: number, ar: BreakpointKeys[]) => ar.indexOf(item) === index, @@ -353,32 +353,50 @@ export const handleResponsiveProp = ( ? commonMQKeys : ['xs', ...commonMQKeys]; - const cssMediaQueryObject = usedMQKeys.reduce((acc, mqKey, index) => { - const fromMqKey = mqKey; - const toMqKey = usedMQKeys[index + 1] ? usedMQKeys[index + 1] : undefined; + let cssMediaQueryObject = {}; + if (commonMQKeys.length > 0) { + cssMediaQueryObject = usedMQKeys.reduce((acc, mqKey, index) => { + const fromMqKey = mqKey; + const toMqKey = usedMQKeys[index + 1] ? usedMQKeys[index + 1] : undefined; - const mediaQuery = getMediaQueryFromTheme(fromMqKey, toMqKey)(props); - const values = propNames.reduce((valAcc, propName) => { - // TS needs checking if prop is part of the object otherwise throw error - /* istanbul ignore else */ - if (hasOwnProperty(filledPropValues, propName)) { - const mqValue = filledPropValues[propName as keyof T]; + const mediaQuery = getMediaQueryFromTheme(fromMqKey, toMqKey)(props); + const values = propNames.reduce((valAcc, propName) => { + // TS needs checking if prop is part of the object otherwise throw error /* istanbul ignore else */ - if (hasOwnProperty(mqValue, fromMqKey)) { - return { - ...valAcc, - [propName]: mqValue[fromMqKey], - }; + if (hasOwnProperty(filledPropValues, propName)) { + const mqValue = filledPropValues[propName as keyof T]; + /* istanbul ignore else */ + if (hasOwnProperty(mqValue, fromMqKey)) { + return { + ...valAcc, + [propName]: mqValue[fromMqKey], + }; + } } + /* istanbul ignore next */ + return valAcc; + }, {}) as {[Key in keyof T]: T[Key]}; + acc[mediaQuery] = propHandler(values, props, fromMqKey); + return acc; + }, {} as Record) as CSSObject; + } + /* + If they've defined container queries using the 'rules' +*/ + + const cssContainerQueryObject = Object.values(usedProps).reduce( + (acc, prop, index) => { + const values: Record = {}; + if (prop.rules) { + prop.rules.forEach(rule => { + values[`${Object.keys(usedProps)[index]}`] = rule.value; + acc[rule.rule] = propHandler(values, props, undefined); + }); } - /* istanbul ignore next */ - return valAcc; - }, {}) as {[Key in keyof T]: T[Key]}; - acc[mediaQuery] = propHandler(values, props, fromMqKey); - return acc; - }, {} as Record) as CSSObject; - - const cssContentQueryObject = {}; + return acc; + }, + ({} as Record) as CSSObject, + ); - return {...cssMediaQueryObject, ...cssContentQueryObject}; + return {...cssMediaQueryObject, ...cssContainerQueryObject}; }; From 4d78efea87289ddfeab9fc22b09ec20c77069c51 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Thu, 4 May 2023 13:29:50 +0100 Subject: [PATCH 07/23] feat(806): typescript fixes --- .../__tests__/stories/grid-layout.stories.tsx | 2 + src/utils/style/getters.ts | 42 ++++++++++++++----- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/grid-layout/__tests__/stories/grid-layout.stories.tsx b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx index 36bc3d9104..13dc0d1e22 100644 --- a/src/grid-layout/__tests__/stories/grid-layout.stories.tsx +++ b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx @@ -187,6 +187,8 @@ export const StoryContainerQueryExample = () => ( ], }} columns={{ + xs: '1fr', + md: '2fr', rules: [ { rule: '@container grid-container (width <= 200px)', diff --git a/src/utils/style/getters.ts b/src/utils/style/getters.ts index d9ed10c24a..28b91f9d0b 100644 --- a/src/utils/style/getters.ts +++ b/src/utils/style/getters.ts @@ -3,7 +3,7 @@ import {getFontSizing} from '../font-sizing'; import {BreakpointKeys, TypographyPreset} from '../../theme'; import {isFontConfigObject} from '../guards'; import {ThemeProp} from '../style-types'; -import {MQ, MQPartial} from './types'; +import {CSSQuery, CSSQueryRules, MQ, MQPartial, ResponsiveValue} from './types'; import { getResponsiveValueFromTheme, getValueFromTheme, @@ -254,7 +254,7 @@ export const handleResponsiveProp = ( return {...acc, [propName]: props[propName]}; } return acc; - }, {}) as {[Key in keyof T]: MQ}; + }, {}) as {[Key in keyof T]: ResponsiveValue}; const propsValues = Object.values(usedProps) as MQ[]; @@ -354,7 +354,7 @@ export const handleResponsiveProp = ( : ['xs', ...commonMQKeys]; let cssMediaQueryObject = {}; - if (commonMQKeys.length > 0) { + if (usedMQKeys.length > 0) { cssMediaQueryObject = usedMQKeys.reduce((acc, mqKey, index) => { const fromMqKey = mqKey; const toMqKey = usedMQKeys[index + 1] ? usedMQKeys[index + 1] : undefined; @@ -380,22 +380,44 @@ export const handleResponsiveProp = ( return acc; }, {} as Record) as CSSObject; } + /* If they've defined container queries using the 'rules' -*/ - - const cssContainerQueryObject = Object.values(usedProps).reduce( - (acc, prop, index) => { - const values: Record = {}; + */ + + // let containerRules = Object.entries(usedProps).filter(entry => typeof entry[1] === 'object' && hasOwnProperty(entry[1], 'rules')); + + const usedValues = Object.entries(usedProps).filter(usedProp => { + const propValue = usedProp[1]; + return ( + propValue && + typeof propValue === 'object' && + hasOwnProperty(propValue, 'rules') && + Array.isArray(propValue.rules) && + propValue.rules.length > 0 + ); + }) as CSSQueryRules[]; + + const cssContainerQueryObject: Record< + CSSQuery['rule'], + string | CSSObject + > = usedValues.reduce( + ( + acc: Record['rule'], string | CSSObject>, + prop, + index: number, + ) => { + const values = {} as {[Key in keyof T]: T[Key]}; if (prop.rules) { prop.rules.forEach(rule => { - values[`${Object.keys(usedProps)[index]}`] = rule.value; + const key = `${Object.keys(usedValues)[index]}` as keyof T; + values[key] = rule.value; acc[rule.rule] = propHandler(values, props, undefined); }); } return acc; }, - ({} as Record) as CSSObject, + {}, ); return {...cssMediaQueryObject, ...cssContainerQueryObject}; From 8f1d77e24040234109c3bf55f510691a991030bd Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Fri, 5 May 2023 09:50:32 +0100 Subject: [PATCH 08/23] feat(806): fix types update test --- src/utils/__tests__/responsive-props.test.ts | 12 +++++++++--- src/utils/style/getters.ts | 18 ++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/utils/__tests__/responsive-props.test.ts b/src/utils/__tests__/responsive-props.test.ts index 33a7f92f28..500defc5a3 100644 --- a/src/utils/__tests__/responsive-props.test.ts +++ b/src/utils/__tests__/responsive-props.test.ts @@ -49,18 +49,24 @@ describe('handleResponsiveProp', () => { }); }); - it.only('using CQ rules value', () => { + it('using CQ rules value', () => { const props = { display: { - rules: [{rule: '@container (width > 200px)', value: 'inline'}], + rules: [ + {rule: '@container (width < 200px)', value: 'inline'}, + {rule: '@container (width >= 200px)', value: 'block'}, + ], }, theme, }; const result = handleResponsiveProp({display: undefined}, handler)(props); expect(result).toEqual({ - '@container (width > 200px)': { + '@container (width < 200px)': { display: 'inline', }, + '@container (width >= 200px)': { + display: 'block', + }, }); }); diff --git a/src/utils/style/getters.ts b/src/utils/style/getters.ts index 28b91f9d0b..b3c8a5b146 100644 --- a/src/utils/style/getters.ts +++ b/src/utils/style/getters.ts @@ -354,7 +354,7 @@ export const handleResponsiveProp = ( : ['xs', ...commonMQKeys]; let cssMediaQueryObject = {}; - if (usedMQKeys.length > 0) { + if (commonMQKeys.length > 0) { cssMediaQueryObject = usedMQKeys.reduce((acc, mqKey, index) => { const fromMqKey = mqKey; const toMqKey = usedMQKeys[index + 1] ? usedMQKeys[index + 1] : undefined; @@ -385,8 +385,6 @@ export const handleResponsiveProp = ( If they've defined container queries using the 'rules' */ - // let containerRules = Object.entries(usedProps).filter(entry => typeof entry[1] === 'object' && hasOwnProperty(entry[1], 'rules')); - const usedValues = Object.entries(usedProps).filter(usedProp => { const propValue = usedProp[1]; return ( @@ -396,21 +394,17 @@ export const handleResponsiveProp = ( Array.isArray(propValue.rules) && propValue.rules.length > 0 ); - }) as CSSQueryRules[]; + }) as [string, CSSQueryRules][]; const cssContainerQueryObject: Record< CSSQuery['rule'], string | CSSObject > = usedValues.reduce( - ( - acc: Record['rule'], string | CSSObject>, - prop, - index: number, - ) => { + (acc: Record['rule'], string | CSSObject>, prop) => { const values = {} as {[Key in keyof T]: T[Key]}; - if (prop.rules) { - prop.rules.forEach(rule => { - const key = `${Object.keys(usedValues)[index]}` as keyof T; + if (prop[1].rules) { + prop[1].rules.forEach(rule => { + const key = `${prop[0]}` as keyof T; values[key] = rule.value; acc[rule.rule] = propHandler(values, props, undefined); }); From d16da5a62367cbb67b6335a6d098ba2dea841699 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Fri, 5 May 2023 09:57:25 +0100 Subject: [PATCH 09/23] fix(806): fix emotion package versions --- package.json | 4 ++-- yarn.lock | 50 +++++++++++++++++++++++++------------------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index f27a40ad79..e9a95cba5a 100644 --- a/package.json +++ b/package.json @@ -89,8 +89,8 @@ "@docsearch/css": "^3.0.0", "@docsearch/react": "^3.0.0", "@emotion/jest": "^11.2.1", - "@emotion/react": "11.10.5", - "@emotion/styled": "11.10.5", + "@emotion/react": "^11.10.5", + "@emotion/styled": "^11.10.5", "@hookform/resolvers": "^2.5.0", "@mapbox/rehype-prism": "^0.3.1", "@mdx-js/loader": "^1.5.8", diff --git a/yarn.lock b/yarn.lock index 6b7946e3a4..fc088d10eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1897,10 +1897,10 @@ "@babel/runtime" "^7.12.13" "@emotion-icons/emotion-icon" "4.0.0" -"@emotion/babel-plugin@^11.10.5": - version "11.10.6" - resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz#a68ee4b019d661d6f37dec4b8903255766925ead" - integrity sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ== +"@emotion/babel-plugin@^11.10.8": + version "11.10.8" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.8.tgz#bae325c902937665d00684038fd5294223ef9e1d" + integrity sha512-gxNky50AJL3AlkbjvTARiwAqei6/tNUxDZPSKd+3jqWVM3AmdVTTdpjHorR/an/M0VJqdsuq5oGcFH+rjtyujQ== dependencies: "@babel/helper-module-imports" "^7.16.7" "@babel/runtime" "^7.18.3" @@ -1912,7 +1912,7 @@ escape-string-regexp "^4.0.0" find-root "^1.1.0" source-map "^0.5.7" - stylis "4.1.3" + stylis "4.1.4" "@emotion/babel-utils@^0.6.4": version "0.6.10" @@ -1926,16 +1926,16 @@ find-root "^1.1.0" source-map "^0.7.2" -"@emotion/cache@^11.10.5": - version "11.10.7" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.7.tgz#2e3b12d3c7c74db0a020ae79eefc52a1b03a6908" - integrity sha512-VLl1/2D6LOjH57Y8Vem1RoZ9haWF4jesHDGiHtKozDQuBIkJm2gimVo0I02sWCuzZtVACeixTVB4jeE8qvCBoQ== +"@emotion/cache@^11.10.8": + version "11.10.8" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.8.tgz#3b39b4761bea0ae2f4f07f0a425eec8b6977c03e" + integrity sha512-5fyqGHi51LU95o7qQ/vD1jyvC4uCY5GcBT+UgP4LHdpO9jPDlXqhrRr9/wCKmfoAvh5G/F7aOh4MwQa+8uEqhA== dependencies: "@emotion/memoize" "^0.8.0" "@emotion/sheet" "^1.2.1" "@emotion/utils" "^1.2.0" "@emotion/weak-memoize" "^0.3.0" - stylis "4.1.3" + stylis "4.1.4" "@emotion/css-prettifier@^1.0.0": version "1.0.0" @@ -1995,14 +1995,14 @@ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f" integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== -"@emotion/react@11.10.5": - version "11.10.5" - resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.5.tgz#95fff612a5de1efa9c0d535384d3cfa115fe175d" - integrity sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A== +"@emotion/react@^11.10.5": + version "11.10.8" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.8.tgz#02e274ecb45e03ab9d7a8eb9f0f0c064613eaf7b" + integrity sha512-ZfGfiABtJ1P1OXqOBsW08EgCDp5fK6C5I8hUJauc/VcJBGSzqAirMnFslhFWnZJ/w5HxPI36XbvMV0l4KZHl+w== dependencies: "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.10.5" - "@emotion/cache" "^11.10.5" + "@emotion/babel-plugin" "^11.10.8" + "@emotion/cache" "^11.10.8" "@emotion/serialize" "^1.1.1" "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" "@emotion/utils" "^1.2.0" @@ -2035,13 +2035,13 @@ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.1.tgz#0767e0305230e894897cadb6c8df2c51e61a6c2c" integrity sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA== -"@emotion/styled@11.10.5": - version "11.10.5" - resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.5.tgz#1fe7bf941b0909802cb826457e362444e7e96a79" - integrity sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw== +"@emotion/styled@^11.10.5": + version "11.10.8" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.8.tgz#a3fd68efd90bd7e8a06b82b95adec643d386fa69" + integrity sha512-gow0lF4Uw/QEdX2REMhI8v6wLOabPKJ+4HKNF0xdJ2DJdznN6fxaXpQOx6sNkyBhSUL558Rmcu1Lq/MYlVo4vw== dependencies: "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.10.5" + "@emotion/babel-plugin" "^11.10.8" "@emotion/is-prop-valid" "^1.2.0" "@emotion/serialize" "^1.1.1" "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" @@ -18142,10 +18142,10 @@ stylis-rule-sheet@^0.0.10: resolved "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz" integrity sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw== -stylis@4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.3.tgz#fd2fbe79f5fed17c55269e16ed8da14c84d069f7" - integrity sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA== +stylis@4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.4.tgz#9cb60e7153d8ac6d02d773552bf51c7a0344535b" + integrity sha512-USf5pszRYwuE6hg9by0OkKChkQYEXfkeTtm0xKw+jqQhwyjCVLdYyMBK7R+n7dhzsblAWJnGxju4vxq5eH20GQ== stylis@^3.5.0: version "3.5.4" From 754c35ce929250af82857da8dfebac823c88d619 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Fri, 5 May 2023 10:41:31 +0100 Subject: [PATCH 10/23] feat(806): fix type for getAreasList --- src/grid-layout/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/grid-layout/utils.ts b/src/grid-layout/utils.ts index eb53e801c3..d06c4b92da 100644 --- a/src/grid-layout/utils.ts +++ b/src/grid-layout/utils.ts @@ -1,4 +1,4 @@ -import {MQ} from '../utils/style'; +import {ResponsiveValue} from '../utils/style'; import {uniq} from '../utils/uniq'; export const capitalize = (s: string) => @@ -15,7 +15,7 @@ export const extractAreas = (areaString: string) => export const filterInvalidAreas = (areaName: string): boolean => areaName !== '.' && Boolean(areaName); -export const getAreasList = (areas: MQ): string[] => { +export const getAreasList = (areas: ResponsiveValue): string[] => { if (typeof areas === 'string') { return uniq(extractAreas(areas)); } From c1ede9eecca9df7303531a7d0aa35eff1ababf8b Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Fri, 5 May 2023 11:26:37 +0100 Subject: [PATCH 11/23] feat(806): change types for get typography from theme --- src/utils/style/getters.ts | 2 +- src/utils/style/style-preset.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/style/getters.ts b/src/utils/style/getters.ts index b3c8a5b146..560e4120b8 100644 --- a/src/utils/style/getters.ts +++ b/src/utils/style/getters.ts @@ -15,7 +15,7 @@ import {FontConfig} from '../../theme/foundations/fonts'; import {textCrop} from '../text-crop'; export const getTypographyPresetFromTheme = ( - defaultToken?: MQ, + defaultToken?: ResponsiveValue, customProp?: Exclude, options?: {withCrop: boolean}, ) => (props: Props) => { diff --git a/src/utils/style/style-preset.ts b/src/utils/style/style-preset.ts index a514d7ed99..51f7d27d7e 100644 --- a/src/utils/style/style-preset.ts +++ b/src/utils/style/style-preset.ts @@ -9,7 +9,7 @@ import {filterObject, rejectObject} from '../filter-object'; import {ThemeProp} from '../style-types'; import {getDefaultedValue, getResponsiveValueFromTheme} from './base'; import {CSSObject} from './emotion'; -import {MQ} from './types'; +import {ResponsiveValue} from './types'; export interface GetStylePresetFromThemeOptions { nestedCssSelector?: string; @@ -241,7 +241,7 @@ const getStylePresetValueFromTheme = ( ); export const getStylePresetFromTheme = ( - defaultToken?: MQ, + defaultToken?: ResponsiveValue, customProp?: Exclude, options?: GetStylePresetFromThemeOptions, ) => (props: Props) => { From e2f5585218813812686c2399755596c888c992b0 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Fri, 5 May 2023 14:21:41 +0100 Subject: [PATCH 12/23] feat(806): update examples, add block story --- src/block/__tests__/block.stories.tsx | 65 ++++++++++- .../__stories/card-composable.stories.tsx | 4 +- .../__tests__/stories/grid-layout.stories.tsx | 109 +++++++++--------- .../__tests__/text-block.stories.tsx | 68 ++++------- 4 files changed, 146 insertions(+), 100 deletions(-) diff --git a/src/block/__tests__/block.stories.tsx b/src/block/__tests__/block.stories.tsx index 59bfee25fc..4038cff6fe 100644 --- a/src/block/__tests__/block.stories.tsx +++ b/src/block/__tests__/block.stories.tsx @@ -6,7 +6,7 @@ import {ThemeProvider, CreateThemeArgs} from '../../theme'; import {Visible} from '../../grid/visibility'; import {createCustomThemeWithBaseThemeSwitch} from '../../test/theme-select-object'; import {TextBlock} from '../../text-block'; -import {MQ} from '../../utils'; +import {MQ, styled, getColorCssFromTheme} from '../../utils'; // The style presets are added for easier visualization of the spacings around the Block component const blockCustomThemeObject: CreateThemeArgs = { @@ -124,6 +124,69 @@ export const StoryBreakpoint = () => ( ); StoryBreakpoint.storyName = 'Breakpoint'; +export const StoryContainerQueries = () => { + const QueryContainerSmall = styled.div` + container-type: inline-size; + width: 300px; + border: 1px dashed; + ${getColorCssFromTheme('borderColor', 'blue060')} + `; + const QueryContainerLarge = styled.div` + container-type: inline-size; + width: 600px; + border: 1px dashed; + ${getColorCssFromTheme('borderColor', 'blue060')} + `; + + const QueryBlock = () => ( + 300px)', + value: 'space040', + }, + ], + }} + paddingBlock={{ + rules: [ + { + rule: '@container (width <= 300px)', + value: 'space010', + }, + { + rule: '@container (width > 300px)', + value: 'space040', + }, + ], + }} + > + This block changes padding depending on its container size + + ); + + return ( + + + + + + + + + + + + + ); +}; +StoryContainerQueries.storyName = 'Container Queries'; + export const StoryTransitions = () => ( { ); return ( - + - + diff --git a/src/grid-layout/__tests__/stories/grid-layout.stories.tsx b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx index 13dc0d1e22..342dc0cf7a 100644 --- a/src/grid-layout/__tests__/stories/grid-layout.stories.tsx +++ b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx @@ -9,6 +9,7 @@ import {Label} from '../../..'; import { StorybookHeading, StorybookSubHeading, + StorybookCase, } from '../../../test/storybook-comps'; const BigRedBlock = styled(Block)` @@ -17,12 +18,18 @@ const BigRedBlock = styled(Block)` background: red; `; -const QueryContainerLarge = styled(Block)` +const QueryContainerSmall = styled(Block)` width: 200px; container-type: inline-size; container-name: grid-container; `; +const QueryContainerLarge = styled(Block)` + width: 400px; + container-type: inline-size; + container-name: grid-container; +`; + export const StoryResponsiveExample = () => ( <> Responsive grid with mixed sizing @@ -169,58 +176,54 @@ export const StoryResponsiveExample = () => ( ); StoryResponsiveExample.storyName = 'responsive'; -export const StoryContainerQueryExample = () => ( - <> - Responsive grid with mixed sizing - - 200px)', - value: '1fr 1fr 1fr 1fr', - }, - ], - }} - columns={{ - xs: '1fr', - md: '2fr', - rules: [ - { - rule: '@container grid-container (width <= 200px)', - value: '1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr', - }, - { - rule: '@container grid-container (width > 200px)', - value: '1fr 1fr', - }, - ], - }} - > - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - - - -); +export const StoryContainerQueryExample = () => { + const QueryGridLayout = () => ( + 200px)', + value: '1fr', + }, + ], + }} + columns={{ + rules: [ + { + rule: '@container grid-container (width <= 200px)', + value: '1fr 1fr', + }, + { + rule: '@container grid-container (width > 200px)', + value: '1fr', + }, + ], + }} + > + 1 + 2 + + ); + + return ( + <> + + + + + + + + + + + + ); +}; StoryContainerQueryExample.storyName = 'Container Queries'; export const StoryMinMaxRepeat = () => { diff --git a/src/text-block/__tests__/text-block.stories.tsx b/src/text-block/__tests__/text-block.stories.tsx index 7e02a7bce9..5699f3cb08 100644 --- a/src/text-block/__tests__/text-block.stories.tsx +++ b/src/text-block/__tests__/text-block.stories.tsx @@ -85,56 +85,36 @@ export const StoryTextBlockContainerQueries = () => { ${getColorCssFromTheme('borderColor', 'blue060')} `; + const QueryTextBlock = () => ( + 300px)', + value: 'editorialParagraph030', + }, + ], + }} + stylePreset="inkContrast" + > + {BODY} + + ); + return ( - + - 300px)', - value: 'editorialParagraph030', - }, - ], - }} - stylePreset="inkContrast" - marginBlock="space040" - paddingBlock="space040" - marginInline="space040" - paddingInline="space040" - > - {BODY} - + - + - 300px)', - value: 'editorialParagraph030', - }, - ], - }} - stylePreset="inkContrast" - marginBlock="space040" - paddingBlock="space040" - marginInline="space040" - paddingInline="space040" - > - {BODY} - + From 2a3befde95ff0a828350a510cf81303684ab3ea6 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Fri, 5 May 2023 15:42:36 +0100 Subject: [PATCH 13/23] feat(806): update snapshots --- .../__snapshots__/newskitprovider.test.tsx.snap | 10 ---------- .../__snapshots__/theme-provider.test.tsx.snap | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/src/newskit-provider/__tests__/__snapshots__/newskitprovider.test.tsx.snap b/src/newskit-provider/__tests__/__snapshots__/newskitprovider.test.tsx.snap index 1760dc8bfe..171f832f55 100644 --- a/src/newskit-provider/__tests__/__snapshots__/newskitprovider.test.tsx.snap +++ b/src/newskit-provider/__tests__/__snapshots__/newskitprovider.test.tsx.snap @@ -149,15 +149,10 @@ exports[`NewsKitProvider renders (slowly) with css variables and theme cache mis --borderRadiusCircle: 50%; --borderRadiusPill: 20rem; --borderRadiusDefault: 8px; - -webkit---borderRadiusRounded010: 4px; --borderRadiusRounded010: 4px; - -webkit---borderRadiusRounded020: 8px; --borderRadiusRounded020: 8px; - -webkit---borderRadiusRounded030: 12px; --borderRadiusRounded030: 12px; - -webkit---borderRadiusRounded040: 16px; --borderRadiusRounded040: 16px; - -webkit---borderRadiusRounded050: 24px; --borderRadiusRounded050: 24px; --color-blue010: #ECF1FF; --color-blue020: #D5E0FC; @@ -639,15 +634,10 @@ exports[`NewsKitProvider renders (slowly) with css variables and theme cache mis --borderRadiusCircle: 50%; --borderRadiusPill: 20rem; --borderRadiusDefault: 8px; - -webkit---borderRadiusRounded010: 4px; --borderRadiusRounded010: 4px; - -webkit---borderRadiusRounded020: 8px; --borderRadiusRounded020: 8px; - -webkit---borderRadiusRounded030: 12px; --borderRadiusRounded030: 12px; - -webkit---borderRadiusRounded040: 16px; --borderRadiusRounded040: 16px; - -webkit---borderRadiusRounded050: 24px; --borderRadiusRounded050: 24px; --color-blue010: #ECF1FF; --color-blue020: #D5E0FC; diff --git a/src/theme/__tests__/__snapshots__/theme-provider.test.tsx.snap b/src/theme/__tests__/__snapshots__/theme-provider.test.tsx.snap index 7d3f2a136d..a39634d65a 100644 --- a/src/theme/__tests__/__snapshots__/theme-provider.test.tsx.snap +++ b/src/theme/__tests__/__snapshots__/theme-provider.test.tsx.snap @@ -12,15 +12,10 @@ exports[`ThemeProvider renders as css variables 1`] = ` --borderRadiusCircle: 50%; --borderRadiusPill: 20rem; --borderRadiusDefault: 8px; - -webkit---borderRadiusRounded010: 4px; --borderRadiusRounded010: 4px; - -webkit---borderRadiusRounded020: 8px; --borderRadiusRounded020: 8px; - -webkit---borderRadiusRounded030: 12px; --borderRadiusRounded030: 12px; - -webkit---borderRadiusRounded040: 16px; --borderRadiusRounded040: 16px; - -webkit---borderRadiusRounded050: 24px; --borderRadiusRounded050: 24px; --color-blue010: #ECF1FF; --color-blue020: #D5E0FC; @@ -371,15 +366,10 @@ exports[`ThemeProvider renders as css variables in nested providers 1`] = ` --borderRadiusCircle: 50%; --borderRadiusPill: 20rem; --borderRadiusDefault: 8px; - -webkit---borderRadiusRounded010: 4px; --borderRadiusRounded010: 4px; - -webkit---borderRadiusRounded020: 8px; --borderRadiusRounded020: 8px; - -webkit---borderRadiusRounded030: 12px; --borderRadiusRounded030: 12px; - -webkit---borderRadiusRounded040: 16px; --borderRadiusRounded040: 16px; - -webkit---borderRadiusRounded050: 24px; --borderRadiusRounded050: 24px; --color-blue010: #ECF1FF; --color-blue020: #D5E0FC; From 71aecebde03c194fa21e2a58d80a474bcc573e3c Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Fri, 5 May 2023 16:24:48 +0100 Subject: [PATCH 14/23] feat(806): address comments --- src/block/__tests__/block.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/block/__tests__/block.stories.tsx b/src/block/__tests__/block.stories.tsx index 4038cff6fe..c1626224ce 100644 --- a/src/block/__tests__/block.stories.tsx +++ b/src/block/__tests__/block.stories.tsx @@ -140,7 +140,7 @@ export const StoryContainerQueries = () => { const QueryBlock = () => ( Date: Tue, 9 May 2023 11:53:05 +0100 Subject: [PATCH 15/23] feat(806): test coverage --- .../__snapshots__/block.test.tsx.snap | 12 ++++++++ src/block/__tests__/block.test.tsx | 10 +++++++ src/card-composable/styled.tsx | 2 -- .../__snapshots__/grid-layout.test.tsx.snap | 16 +++++++++++ .../__tests__/grid-layout.test.tsx | 10 +++++++ src/grid-layout/styled.ts | 4 +++ src/utils/__tests__/base.test.ts | 28 +++++++++++++++++-- 7 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/block/__tests__/__snapshots__/block.test.tsx.snap b/src/block/__tests__/__snapshots__/block.test.tsx.snap index 3ab1dba818..7e8e7da4c7 100644 --- a/src/block/__tests__/__snapshots__/block.test.tsx.snap +++ b/src/block/__tests__/__snapshots__/block.test.tsx.snap @@ -8,6 +8,18 @@ exports[`Block with no props renders an unstyled div 1`] = ` `; +exports[`Block with props renders GridLayout with container name and type 1`] = ` + + .emotion-0 { + container-type:inline-size container-name: test-container; +} + +

+ +`; + exports[`Block with props renders as span 1`] = ` { const fragment = renderToFragmentWithTheme(Block, props); expect(fragment).toMatchSnapshot(); }); + + test('renders GridLayout with container name and type', () => { + const props: BlockProps = { + containerName: 'test-container', + containerType: 'inline-size', + }; + + const fragment = renderToFragmentWithTheme(Block, props); + expect(fragment).toMatchSnapshot(); + }); }); }); diff --git a/src/card-composable/styled.tsx b/src/card-composable/styled.tsx index aabd4ab12f..3721418512 100644 --- a/src/card-composable/styled.tsx +++ b/src/card-composable/styled.tsx @@ -12,8 +12,6 @@ const StyledGrid = styled(GridLayout)` ${getStylePreset('', '')}; ${getTransitionPreset('', '')}; ${({areaName}) => areaName && `grid-area: ${areaName};`} - ${({containerName}) => containerName && `container-name: ${containerName};`} - ${({containerType}) => containerType && `container-type: ${containerType};`} `; export const StyledCard = styled(StyledGrid)` diff --git a/src/grid-layout/__tests__/__snapshots__/grid-layout.test.tsx.snap b/src/grid-layout/__tests__/__snapshots__/grid-layout.test.tsx.snap index d9335d5681..c0b4ca9102 100644 --- a/src/grid-layout/__tests__/__snapshots__/grid-layout.test.tsx.snap +++ b/src/grid-layout/__tests__/__snapshots__/grid-layout.test.tsx.snap @@ -205,6 +205,22 @@ exports[`GridLayout renders GridLayout with colum/row prop 1`] = ` `; +exports[`GridLayout renders GridLayout with container name and type 1`] = ` + + .emotion-0 { + margin: 0; + padding: 0; + container-type:inline-size; + container-name:test-container; + display: grid; +} + +
+ +`; + exports[`GridLayout renders GridLayout with different areas for different breakpoints 1`] = ` .emotion-0 { diff --git a/src/grid-layout/__tests__/grid-layout.test.tsx b/src/grid-layout/__tests__/grid-layout.test.tsx index 7182c161cc..7540c485ad 100644 --- a/src/grid-layout/__tests__/grid-layout.test.tsx +++ b/src/grid-layout/__tests__/grid-layout.test.tsx @@ -64,6 +64,16 @@ describe('GridLayout', () => { expect(fragment).toMatchSnapshot(); }); + test('renders GridLayout with container name and type', () => { + const props: GridLayoutProps = { + containerName: 'test-container', + containerType: 'inline-size', + }; + + const fragment = renderToFragmentWithTheme(GridLayout, props); + expect(fragment).toMatchSnapshot(); + }); + test('renders GridLayout with different areas for different breakpoints', () => { const props: GridLayoutProps = { areas: { diff --git a/src/grid-layout/styled.ts b/src/grid-layout/styled.ts index 4f0e1613e1..8772b0f682 100644 --- a/src/grid-layout/styled.ts +++ b/src/grid-layout/styled.ts @@ -29,6 +29,10 @@ export const StyledGridLayout = styled.div` margin: 0; padding: 0; + /* container query props */ + ${({containerType}) => containerType && `container-type: ${containerType}`}; + ${({containerName}) => containerName && `container-name: ${containerName}`}; + ${handleResponsiveProp({inline: GRID_DEFAULT_PROPS.inline}, ({inline}) => ({ display: inline ? 'inline-grid' : 'grid', }))} diff --git a/src/utils/__tests__/base.test.ts b/src/utils/__tests__/base.test.ts index 25e6c4afb3..32247e35ad 100644 --- a/src/utils/__tests__/base.test.ts +++ b/src/utils/__tests__/base.test.ts @@ -1,6 +1,9 @@ import {createTheme, compileTheme} from '../../theme'; -import {getSizingCssFromTheme} from '../style/getters'; -import {getXFromTheme} from '../style/base'; +import { + getSizingCssFromTheme, + getTypographyPresetFromTheme, +} from '../style/getters'; +import {getXFromTheme, getDefaultedValue} from '../style/base'; import { getResponsiveSize, getResponsiveSpace, @@ -40,6 +43,19 @@ describe('getXFromTheme', () => { }), ); + test('should not use overridePath when it is false', () => { + const presetType = 'typographyPreset'; + const defaultPath = 'md'; + const overridePath = false; + const expectedValue = '16px'; + const props = {theme: theme}; + const result = getDefaultedValue(getTypographyPresetFromTheme, presetType)( + defaultPath, + overridePath, + )(props); + expect(result).toEqual(expectedValue); + }); + test('getXFromTheme with non MQ value', () => { const result = getXFromTheme('sizing')('width', 'sizing050')({theme}); expect(result).toEqual({width: '24px'}); @@ -66,6 +82,14 @@ describe('getXFromTheme', () => { '@container (min-width: 300px)': {width: '4px'}, }); }); + test('getXFromTheme – spacePreset with Container Query value', () => { + const result = getXFromTheme('spacePresets')('padding', { + rules: [{rule: '@container (min-width: 300px)', value: 'space010'}], + })({theme}); + expect(result).toEqual({ + '@container (min-width: 300px)': {padding: '4px'}, + }); + }); test('getXFromTheme with CQ & MQ value', () => { const result = getXFromTheme('sizing')('width', { xs: 'sizing010', From 44b882f2bd583cfd2f80169eafe8386ed49e615e Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Wed, 10 May 2023 13:22:52 +0100 Subject: [PATCH 16/23] feat(806): move container props to own function --- .../__snapshots__/block.test.tsx.snap | 3 ++- src/block/__tests__/block.stories.tsx | 26 +++++++++++++++---- src/block/block.tsx | 4 +-- .../__snapshots__/grid-layout.test.tsx.snap | 4 +-- src/grid-layout/styled.ts | 6 ++--- src/utils/container-properties.ts | 6 +++++ src/utils/style/types.ts | 7 +++++ 7 files changed, 42 insertions(+), 14 deletions(-) create mode 100644 src/utils/container-properties.ts diff --git a/src/block/__tests__/__snapshots__/block.test.tsx.snap b/src/block/__tests__/__snapshots__/block.test.tsx.snap index 7e8e7da4c7..13da59d02d 100644 --- a/src/block/__tests__/__snapshots__/block.test.tsx.snap +++ b/src/block/__tests__/__snapshots__/block.test.tsx.snap @@ -11,7 +11,8 @@ exports[`Block with no props renders an unstyled div 1`] = ` exports[`Block with props renders GridLayout with container name and type 1`] = ` .emotion-0 { - container-type:inline-size container-name: test-container; + container-type: inline-size; + container-name: test-container; }
{ ${getColorCssFromTheme('borderColor', 'blue060')} `; const QueryContainerLarge = styled.div` - container-type: inline-size; width: 600px; border: 1px dashed; ${getColorCssFromTheme('borderColor', 'blue060')} @@ -173,14 +179,24 @@ export const StoryContainerQueries = () => { return ( - + - + - + - + ); diff --git a/src/block/block.tsx b/src/block/block.tsx index 5d3c26d8bb..221563eef6 100644 --- a/src/block/block.tsx +++ b/src/block/block.tsx @@ -9,6 +9,7 @@ import { ContainerQueryProps, } from '../utils/style'; import {getTransitionPresetFromTheme} from '../utils/style/transition-preset'; +import {containerProps} from '../utils/container-properties'; export interface BlockProps extends React.HTMLAttributes, @@ -28,14 +29,13 @@ export interface BlockProps } const StyledDiv = styled.div` - ${({containerType}) => containerType && `container-type: ${containerType}`} - ${({containerName}) => containerName && `container-name: ${containerName}`} ${({stylePreset}) => stylePreset && getStylePresetFromTheme(stylePreset)} ${({spaceInline}) => spaceInline && getSpacingFromTheme(spaceInline, undefined, 'marginRight')} ${({spaceStack}) => spaceStack && getSpacingFromTheme(spaceStack, undefined, 'marginBottom')} ${logicalProps()} + ${containerProps()} ${({transitionPreset}) => transitionPreset && getTransitionPresetFromTheme(transitionPreset)}; `; diff --git a/src/grid-layout/__tests__/__snapshots__/grid-layout.test.tsx.snap b/src/grid-layout/__tests__/__snapshots__/grid-layout.test.tsx.snap index c0b4ca9102..b57020d7a4 100644 --- a/src/grid-layout/__tests__/__snapshots__/grid-layout.test.tsx.snap +++ b/src/grid-layout/__tests__/__snapshots__/grid-layout.test.tsx.snap @@ -210,9 +210,9 @@ exports[`GridLayout renders GridLayout with container name and type 1`] = ` .emotion-0 { margin: 0; padding: 0; - container-type:inline-size; - container-name:test-container; display: grid; + container-type: inline-size; + container-name: test-container; }
` margin: 0; padding: 0; - /* container query props */ - ${({containerType}) => containerType && `container-type: ${containerType}`}; - ${({containerName}) => containerName && `container-name: ${containerName}`}; - ${handleResponsiveProp({inline: GRID_DEFAULT_PROPS.inline}, ({inline}) => ({ display: inline ? 'inline-grid' : 'grid', }))} @@ -125,4 +122,5 @@ export const StyledGridLayout = styled.div` ${getResponsiveSize('minHeight', 'gridLayout', '', 'minHeight')}; ${getResponsiveSize('maxHeight', 'gridLayout', '', 'maxHeight')}; ${logicalProps('gridLayout')} + ${containerProps()} `; diff --git a/src/utils/container-properties.ts b/src/utils/container-properties.ts new file mode 100644 index 0000000000..db2f8ca06f --- /dev/null +++ b/src/utils/container-properties.ts @@ -0,0 +1,6 @@ +import {ContainerQueryProps} from './style'; + +export const containerProps = () => (props: ContainerQueryProps) => { + const {containerType, containerName} = props; + return {containerType, containerName}; +}; diff --git a/src/utils/style/types.ts b/src/utils/style/types.ts index 3f7134cc71..f5703da283 100644 --- a/src/utils/style/types.ts +++ b/src/utils/style/types.ts @@ -8,8 +8,15 @@ export type MQPartial = Partial<{ export type MQ = T | MQPartial; +/* +Allows you define values at set breakpoints, or define custom media & container queries with the "rules" object +*/ export type ResponsiveValue = MQ | CSSQueryRules; +/* + @param rule - The media or container query definition + @param value - CSS value or token +*/ export type CSSQuery = { rule: `@media ${string}` | `@container ${string}`; value: T; From 4a1fcd61beaf2b3876af620c3cfa0fb86f681356 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Wed, 10 May 2023 14:02:05 +0100 Subject: [PATCH 17/23] feat(806): address comments --- src/block/__tests__/block.stories.tsx | 28 ++++------- src/block/__tests__/block.test.tsx | 6 ++- src/block/block.tsx | 4 +- .../__tests__/grid-layout.test.tsx | 8 +-- .../__tests__/stories/grid-layout.stories.tsx | 35 +++++++------ src/grid-layout/types.ts | 6 +-- .../__tests__/text-block.stories.tsx | 49 +++++++++++-------- src/utils/container-properties.ts | 10 ++-- 8 files changed, 80 insertions(+), 66 deletions(-) diff --git a/src/block/__tests__/block.stories.tsx b/src/block/__tests__/block.stories.tsx index de687f936d..37a591ac03 100644 --- a/src/block/__tests__/block.stories.tsx +++ b/src/block/__tests__/block.stories.tsx @@ -132,18 +132,6 @@ export const StoryBreakpoint = () => ( StoryBreakpoint.storyName = 'Breakpoint'; export const StoryContainerQueries = () => { - const QueryContainerSmall = styled.div` - container-type: inline-size; - width: 300px; - border: 1px dashed; - ${getColorCssFromTheme('borderColor', 'blue060')} - `; - const QueryContainerLarge = styled.div` - width: 600px; - border: 1px dashed; - ${getColorCssFromTheme('borderColor', 'blue060')} - `; - const QueryBlock = () => ( { return ( - + - + diff --git a/src/block/__tests__/block.test.tsx b/src/block/__tests__/block.test.tsx index 5100a49fa9..e13ad81490 100644 --- a/src/block/__tests__/block.test.tsx +++ b/src/block/__tests__/block.test.tsx @@ -102,8 +102,10 @@ describe('Block', () => { test('renders GridLayout with container name and type', () => { const props: BlockProps = { - containerName: 'test-container', - containerType: 'inline-size', + overrides: { + containerName: 'test-container', + containerType: 'inline-size', + }, }; const fragment = renderToFragmentWithTheme(Block, props); diff --git a/src/block/block.tsx b/src/block/block.tsx index 221563eef6..9d9730f656 100644 --- a/src/block/block.tsx +++ b/src/block/block.tsx @@ -13,8 +13,7 @@ import {containerProps} from '../utils/container-properties'; export interface BlockProps extends React.HTMLAttributes, - LogicalProps, - ContainerQueryProps { + LogicalProps { as?: keyof JSX.IntrinsicElements; stylePreset?: MQ; transitionPreset?: TransitionToken | TransitionToken[]; @@ -26,6 +25,7 @@ export interface BlockProps * @deprecated This property is deprecated and will be removed in the next major release. Use `marginBlockEnd` instead. */ spaceStack?: MQ; + overrides?: ContainerQueryProps; } const StyledDiv = styled.div` diff --git a/src/grid-layout/__tests__/grid-layout.test.tsx b/src/grid-layout/__tests__/grid-layout.test.tsx index 7540c485ad..0bf3fc592c 100644 --- a/src/grid-layout/__tests__/grid-layout.test.tsx +++ b/src/grid-layout/__tests__/grid-layout.test.tsx @@ -55,7 +55,7 @@ describe('GridLayout', () => { const props: GridLayoutProps = { areas: ` "A A" - "B C" + "B C" "D E"`, children: areasChildren, }; @@ -66,8 +66,10 @@ describe('GridLayout', () => { test('renders GridLayout with container name and type', () => { const props: GridLayoutProps = { - containerName: 'test-container', - containerType: 'inline-size', + overrides: { + containerName: 'test-container', + containerType: 'inline-size', + }, }; const fragment = renderToFragmentWithTheme(GridLayout, props); diff --git a/src/grid-layout/__tests__/stories/grid-layout.stories.tsx b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx index 342dc0cf7a..aed4c2c87b 100644 --- a/src/grid-layout/__tests__/stories/grid-layout.stories.tsx +++ b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx @@ -10,6 +10,7 @@ import { StorybookHeading, StorybookSubHeading, StorybookCase, + StorybookPage, } from '../../../test/storybook-comps'; const BigRedBlock = styled(Block)` @@ -182,11 +183,11 @@ export const StoryContainerQueryExample = () => { rows={{ rules: [ { - rule: '@container grid-container (width <= 200px)', + rule: '@container (width <= 200px)', value: '1fr 1fr', }, { - rule: '@container grid-container (width > 200px)', + rule: '@container (width > 200px)', value: '1fr', }, ], @@ -194,12 +195,12 @@ export const StoryContainerQueryExample = () => { columns={{ rules: [ { - rule: '@container grid-container (width <= 200px)', - value: '1fr 1fr', + rule: '@container (width <= 200px)', + value: '1fr', }, { - rule: '@container grid-container (width > 200px)', - value: '1fr', + rule: '@container (width > 200px)', + value: '1fr 1fr', }, ], }} @@ -210,18 +211,24 @@ export const StoryContainerQueryExample = () => { ); return ( - <> - - + + + - + - - + + - + - + ); }; StoryContainerQueryExample.storyName = 'Container Queries'; diff --git a/src/grid-layout/types.ts b/src/grid-layout/types.ts index a0d1c603c9..57fca31ebc 100644 --- a/src/grid-layout/types.ts +++ b/src/grid-layout/types.ts @@ -44,6 +44,6 @@ export type GridLayoutProps = { height?: ResponsiveValue; minHeight?: ResponsiveValue; maxHeight?: ResponsiveValue; - } & LogicalProps; -} & ContainerQueryProps & - Omit, 'children'>; + } & LogicalProps & + ContainerQueryProps; +} & Omit, 'children'>; diff --git a/src/text-block/__tests__/text-block.stories.tsx b/src/text-block/__tests__/text-block.stories.tsx index 5699f3cb08..2b137e1bca 100644 --- a/src/text-block/__tests__/text-block.stories.tsx +++ b/src/text-block/__tests__/text-block.stories.tsx @@ -5,12 +5,20 @@ import {ThemeProvider, CreateThemeArgs} from '../../theme'; import {StorybookCase, StorybookPage} from '../../test/storybook-comps'; import {getColorCssFromTheme, styled} from '../../utils'; import {createCustomThemeWithBaseThemeSwitch} from '../../test/theme-select-object'; +import {Block} from '../../block'; const textBlockCustomThemeObject: CreateThemeArgs = { name: 'textblock-custom-theme', overrides: { stylePresets: { textBlockCustom: {base: {color: '{{colors.inkBrand010}}'}}, + blockContainerQueryWrapper: { + base: { + borderStyle: 'dashed', + borderWidth: '{{borders.borderWidth010}}', + borderColor: '{{colors.blue060}}', + }, + }, }, typographyPresets: { textBlockCustom: {fontFamily: '{{fonts.fontFamily020.fontFamily}}'}, @@ -72,19 +80,6 @@ export const StoryTextBlockLogicalProps = () => ( StoryTextBlockLogicalProps.storyName = 'Logical props'; export const StoryTextBlockContainerQueries = () => { - const QueryContainerSmall = styled.div` - container-type: inline-size; - width: 300px; - border: 1px dashed; - ${getColorCssFromTheme('borderColor', 'blue060')} - `; - const QueryContainerLarge = styled.div` - container-type: inline-size; - width: 600px; - border: 1px dashed; - ${getColorCssFromTheme('borderColor', 'blue060')} - `; - const QueryTextBlock = () => ( { ); return ( - - - + + + - + - - + + - + ); diff --git a/src/utils/container-properties.ts b/src/utils/container-properties.ts index db2f8ca06f..3c040388d4 100644 --- a/src/utils/container-properties.ts +++ b/src/utils/container-properties.ts @@ -1,6 +1,8 @@ -import {ContainerQueryProps} from './style'; +import {ContainerQueryProps, CSSObject} from './style'; -export const containerProps = () => (props: ContainerQueryProps) => { - const {containerType, containerName} = props; - return {containerType, containerName}; +export const containerProps = () => (props: { + overrides?: ContainerQueryProps; +}) => { + const {containerType, containerName} = props.overrides || {}; + return {containerType, containerName} as CSSObject; }; From db0ddfed61bd7aca702fcdd7b752334a0d503ecf Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Wed, 10 May 2023 14:03:58 +0100 Subject: [PATCH 18/23] feat(806): remove a test --- src/utils/__tests__/base.test.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/utils/__tests__/base.test.ts b/src/utils/__tests__/base.test.ts index 32247e35ad..68575d5e54 100644 --- a/src/utils/__tests__/base.test.ts +++ b/src/utils/__tests__/base.test.ts @@ -43,19 +43,6 @@ describe('getXFromTheme', () => { }), ); - test('should not use overridePath when it is false', () => { - const presetType = 'typographyPreset'; - const defaultPath = 'md'; - const overridePath = false; - const expectedValue = '16px'; - const props = {theme: theme}; - const result = getDefaultedValue(getTypographyPresetFromTheme, presetType)( - defaultPath, - overridePath, - )(props); - expect(result).toEqual(expectedValue); - }); - test('getXFromTheme with non MQ value', () => { const result = getXFromTheme('sizing')('width', 'sizing050')({theme}); expect(result).toEqual({width: '24px'}); From f316a467511b66a0ec0d39749a6872a9f2225ccf Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Fri, 12 May 2023 17:10:07 +0100 Subject: [PATCH 19/23] feat(806): remove unused code --- .../__tests__/stories/grid-layout.stories.tsx | 12 ----------- src/grid-layout/types.ts | 3 +-- src/utils/__tests__/is-valid-css-size.test.ts | 21 ------------------- src/utils/responsive-helpers.ts | 14 ------------- src/utils/style/utils.ts | 5 ----- 5 files changed, 1 insertion(+), 54 deletions(-) delete mode 100644 src/utils/__tests__/is-valid-css-size.test.ts diff --git a/src/grid-layout/__tests__/stories/grid-layout.stories.tsx b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx index aed4c2c87b..b12abe3550 100644 --- a/src/grid-layout/__tests__/stories/grid-layout.stories.tsx +++ b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx @@ -19,18 +19,6 @@ const BigRedBlock = styled(Block)` background: red; `; -const QueryContainerSmall = styled(Block)` - width: 200px; - container-type: inline-size; - container-name: grid-container; -`; - -const QueryContainerLarge = styled(Block)` - width: 400px; - container-type: inline-size; - container-name: grid-container; -`; - export const StoryResponsiveExample = () => ( <> Responsive grid with mixed sizing diff --git a/src/grid-layout/types.ts b/src/grid-layout/types.ts index 57fca31ebc..6c5355c058 100644 --- a/src/grid-layout/types.ts +++ b/src/grid-layout/types.ts @@ -11,8 +11,7 @@ export type GridLayoutItemProps = BlockProps & { alignSelf?: MQ; column?: MQ; row?: MQ; -} & ContainerQueryProps & - React.HTMLAttributes; +} & React.HTMLAttributes; export type AreasMap = { [componentName: string]: React.FC; diff --git a/src/utils/__tests__/is-valid-css-size.test.ts b/src/utils/__tests__/is-valid-css-size.test.ts deleted file mode 100644 index 7c7ab2825d..0000000000 --- a/src/utils/__tests__/is-valid-css-size.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {isValidCSSSizeUnit} from '../style/utils'; - -describe('isValidCSSSizeUnit', () => { - it('should return true for valid CSS size units', () => { - expect(isValidCSSSizeUnit('12px')).toBe(true); - expect(isValidCSSSizeUnit('100%')).toBe(true); - expect(isValidCSSSizeUnit('10em')).toBe(true); - expect(isValidCSSSizeUnit('24pt')).toBe(true); - expect(isValidCSSSizeUnit('100cm')).toBe(true); - expect(isValidCSSSizeUnit('0.5rem')).toBe(true); - expect(isValidCSSSizeUnit('0.5vmin')).toBe(true); - }); - - it('should return false for invalid CSS size units', () => { - expect(isValidCSSSizeUnit('10')).toBe(false); - expect(isValidCSSSizeUnit('10pt ')).toBe(false); - expect(isValidCSSSizeUnit('abc')).toBe(false); - expect(isValidCSSSizeUnit('50deg')).toBe(false); - expect(isValidCSSSizeUnit('2px2em')).toBe(false); - }); -}); diff --git a/src/utils/responsive-helpers.ts b/src/utils/responsive-helpers.ts index 7839eba525..195126039c 100644 --- a/src/utils/responsive-helpers.ts +++ b/src/utils/responsive-helpers.ts @@ -52,17 +52,3 @@ export const isResponsive = ( typeof prop === 'object' && (Object.keys(breakpoints).some(bp => prop && hasOwnProperty(prop, bp)) || hasOwnProperty(prop, 'rules')); - -// export const getContainerQuery = ( -// minWidth?: string, -// maxWidth?: string, -// ): string => { -// const queries = []; -// if (minWidth) { -// queries.push(`(min-width: ${minWidth})`); -// } -// if (maxWidth) { -// queries.push(`(max-width: ${maxWidth})`); -// } -// return `@container ${queries.join(' AND ')}`; -// }; diff --git a/src/utils/style/utils.ts b/src/utils/style/utils.ts index 7bb2700758..df869f3835 100644 --- a/src/utils/style/utils.ts +++ b/src/utils/style/utils.ts @@ -225,11 +225,6 @@ export const isValidUnit = (themeKey: string, value: any) => { ); }; -export const isValidCSSSizeUnit = (value: string) => { - const regex = new RegExp(`^\\d+(\\.\\d+)?(${CSSUnits.join('|')})$`); - return regex.test(value); -}; - export const isArrayLikeObject = (value: string | object) => typeof value === 'object' && '0' in value; From 80110a6f71d367d7690465fb425ca58461b0dc24 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Tue, 16 May 2023 10:04:31 +0100 Subject: [PATCH 20/23] feat(806): move props out of overrides --- src/block/__tests__/block.stories.tsx | 12 ++++-------- src/block/__tests__/block.test.tsx | 6 ++---- src/block/block.tsx | 4 ++-- src/grid-layout/__tests__/grid-layout.test.tsx | 6 ++---- .../__tests__/stories/grid-layout.stories.tsx | 10 ++-------- src/grid-layout/types.ts | 5 ++--- src/utils/container-properties.ts | 6 ++---- 7 files changed, 16 insertions(+), 33 deletions(-) diff --git a/src/block/__tests__/block.stories.tsx b/src/block/__tests__/block.stories.tsx index 37a591ac03..90c61a27de 100644 --- a/src/block/__tests__/block.stories.tsx +++ b/src/block/__tests__/block.stories.tsx @@ -168,10 +168,8 @@ export const StoryContainerQueries = () => { @@ -180,10 +178,8 @@ export const StoryContainerQueries = () => { diff --git a/src/block/__tests__/block.test.tsx b/src/block/__tests__/block.test.tsx index e13ad81490..5100a49fa9 100644 --- a/src/block/__tests__/block.test.tsx +++ b/src/block/__tests__/block.test.tsx @@ -102,10 +102,8 @@ describe('Block', () => { test('renders GridLayout with container name and type', () => { const props: BlockProps = { - overrides: { - containerName: 'test-container', - containerType: 'inline-size', - }, + containerName: 'test-container', + containerType: 'inline-size', }; const fragment = renderToFragmentWithTheme(Block, props); diff --git a/src/block/block.tsx b/src/block/block.tsx index 9d9730f656..221563eef6 100644 --- a/src/block/block.tsx +++ b/src/block/block.tsx @@ -13,7 +13,8 @@ import {containerProps} from '../utils/container-properties'; export interface BlockProps extends React.HTMLAttributes, - LogicalProps { + LogicalProps, + ContainerQueryProps { as?: keyof JSX.IntrinsicElements; stylePreset?: MQ; transitionPreset?: TransitionToken | TransitionToken[]; @@ -25,7 +26,6 @@ export interface BlockProps * @deprecated This property is deprecated and will be removed in the next major release. Use `marginBlockEnd` instead. */ spaceStack?: MQ; - overrides?: ContainerQueryProps; } const StyledDiv = styled.div` diff --git a/src/grid-layout/__tests__/grid-layout.test.tsx b/src/grid-layout/__tests__/grid-layout.test.tsx index 0bf3fc592c..8c504b27cd 100644 --- a/src/grid-layout/__tests__/grid-layout.test.tsx +++ b/src/grid-layout/__tests__/grid-layout.test.tsx @@ -66,10 +66,8 @@ describe('GridLayout', () => { test('renders GridLayout with container name and type', () => { const props: GridLayoutProps = { - overrides: { - containerName: 'test-container', - containerType: 'inline-size', - }, + containerName: 'test-container', + containerType: 'inline-size', }; const fragment = renderToFragmentWithTheme(GridLayout, props); diff --git a/src/grid-layout/__tests__/stories/grid-layout.stories.tsx b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx index b12abe3550..95fcc18196 100644 --- a/src/grid-layout/__tests__/stories/grid-layout.stories.tsx +++ b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx @@ -201,18 +201,12 @@ export const StoryContainerQueryExample = () => { return ( - + - + diff --git a/src/grid-layout/types.ts b/src/grid-layout/types.ts index 6c5355c058..e86f5c9cf6 100644 --- a/src/grid-layout/types.ts +++ b/src/grid-layout/types.ts @@ -19,7 +19,7 @@ export type AreasMap = { export type GridLayoutRenderProps = (areas: AreasMap) => React.ReactNode; -export type GridLayoutProps = { +export type GridLayoutProps = ContainerQueryProps & { rowGap?: ResponsiveValue; columnGap?: ResponsiveValue; rows?: ResponsiveValue; @@ -43,6 +43,5 @@ export type GridLayoutProps = { height?: ResponsiveValue; minHeight?: ResponsiveValue; maxHeight?: ResponsiveValue; - } & LogicalProps & - ContainerQueryProps; + } & LogicalProps; } & Omit, 'children'>; diff --git a/src/utils/container-properties.ts b/src/utils/container-properties.ts index 3c040388d4..aa1515e4b0 100644 --- a/src/utils/container-properties.ts +++ b/src/utils/container-properties.ts @@ -1,8 +1,6 @@ import {ContainerQueryProps, CSSObject} from './style'; -export const containerProps = () => (props: { - overrides?: ContainerQueryProps; -}) => { - const {containerType, containerName} = props.overrides || {}; +export const containerProps = () => (props: ContainerQueryProps) => { + const {containerType, containerName} = props || {}; return {containerType, containerName} as CSSObject; }; From ba253fcbb2fad19e6989abe22ed3f54add167ac7 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Fri, 19 May 2023 10:10:15 +0100 Subject: [PATCH 21/23] feat(806): test coverage, peer deps versions --- package.json | 8 +- .../__tests__/grid-layout.test.tsx | 2 +- .../__tests__/container-properties.test.ts | 35 ++++ src/utils/style/types.ts | 10 +- yarn.lock | 182 ++++++++++-------- 5 files changed, 146 insertions(+), 91 deletions(-) create mode 100644 src/utils/__tests__/container-properties.test.ts diff --git a/package.json b/package.json index d610bbd55d..c780331001 100644 --- a/package.json +++ b/package.json @@ -101,8 +101,8 @@ "@docsearch/css": "^3.0.0", "@docsearch/react": "^3.0.0", "@emotion/jest": "^11.2.1", - "@emotion/react": "^11.10.5", - "@emotion/styled": "^11.10.5", + "@emotion/react": "^11.10.4", + "@emotion/styled": "^11.10.4", "@hookform/resolvers": "^2.5.0", "@mapbox/rehype-prism": "^0.3.1", "@mdx-js/loader": "^1.5.8", @@ -280,8 +280,8 @@ "kind-of": "^6.0.3" }, "peerDependencies": { - "@emotion/react": ">= 11.1.5 <= 11.9.3", - "@emotion/styled": ">= 11.1.5 <= 11.9.3", + "@emotion/react": ">= 11.10.4 <= 12", + "@emotion/styled": ">= 11.10.4 <= 12", "react": ">= 16.8.0 <= 18", "react-dom": ">= 16.8.0 <= 18", "react-is": ">= 16.8.0 <= 18" diff --git a/src/grid-layout/__tests__/grid-layout.test.tsx b/src/grid-layout/__tests__/grid-layout.test.tsx index 8c504b27cd..7540c485ad 100644 --- a/src/grid-layout/__tests__/grid-layout.test.tsx +++ b/src/grid-layout/__tests__/grid-layout.test.tsx @@ -55,7 +55,7 @@ describe('GridLayout', () => { const props: GridLayoutProps = { areas: ` "A A" - "B C" + "B C" "D E"`, children: areasChildren, }; diff --git a/src/utils/__tests__/container-properties.test.ts b/src/utils/__tests__/container-properties.test.ts new file mode 100644 index 0000000000..db4c94152b --- /dev/null +++ b/src/utils/__tests__/container-properties.test.ts @@ -0,0 +1,35 @@ +import {containerProps} from '../container-properties'; // Import the module you want to test +import {ContainerQueryProps} from '../style'; + +describe('containerProps', () => { + test('returns a CSSObject with containerType and containerName', () => { + const props: ContainerQueryProps = { + containerType: 'inline-size', + containerName: 'containerName', + }; + const result = containerProps()(props); + expect(result).toEqual({ + containerType: 'inline-size', + containerName: 'containerName', + }); + }); + + test('returns an empty CSSObject when props is an empty object', () => { + const props = {}; + const result = containerProps()(props); + const expected = {}; + + expect(result).toEqual(expected); + }); + test('should return default values when props is undefined', () => { + const props = undefined; + + // @ts-ignore next-line + const result = containerProps()(props); + console.log(result); + expect(result).toEqual({ + containerType: undefined, + containerName: undefined, + }); + }); +}); diff --git a/src/utils/style/types.ts b/src/utils/style/types.ts index f5703da283..5ca7617637 100644 --- a/src/utils/style/types.ts +++ b/src/utils/style/types.ts @@ -27,6 +27,14 @@ export type CSSQueryRules = { }; export type ContainerQueryProps = { - containerType?: 'normal' | 'inline-size' | 'size'; + containerType?: + | `normal` + | `inline-size` + | `size` + | `inherit` + | `initial` + | `unset` + | `revert` + | `revert-layer`; containerName?: string; }; diff --git a/yarn.lock b/yarn.lock index e2de25f39a..056de4ecba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1308,13 +1308,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-jsx@^7.7.2": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" - integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-jsx@^7.18.6", "@babel/plugin-syntax-jsx@^7.21.4": version "7.21.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz#f264ed7bf40ffc9ec239edabc17a50c4f5b6fea2" @@ -1322,6 +1315,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.20.2" +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" @@ -2738,22 +2738,22 @@ "@babel/runtime" "^7.12.13" "@emotion-icons/emotion-icon" "4.0.0" -"@emotion/babel-plugin@^11.10.8": - version "11.10.8" - resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.8.tgz#bae325c902937665d00684038fd5294223ef9e1d" - integrity sha512-gxNky50AJL3AlkbjvTARiwAqei6/tNUxDZPSKd+3jqWVM3AmdVTTdpjHorR/an/M0VJqdsuq5oGcFH+rjtyujQ== +"@emotion/babel-plugin@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" + integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== dependencies: "@babel/helper-module-imports" "^7.16.7" "@babel/runtime" "^7.18.3" - "@emotion/hash" "^0.9.0" - "@emotion/memoize" "^0.8.0" - "@emotion/serialize" "^1.1.1" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/serialize" "^1.1.2" babel-plugin-macros "^3.1.0" convert-source-map "^1.5.0" escape-string-regexp "^4.0.0" find-root "^1.1.0" source-map "^0.5.7" - stylis "4.1.4" + stylis "4.2.0" "@emotion/babel-utils@^0.6.4": version "0.6.10" @@ -2767,16 +2767,16 @@ find-root "^1.1.0" source-map "^0.7.2" -"@emotion/cache@^11.10.8": - version "11.10.8" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.8.tgz#3b39b4761bea0ae2f4f07f0a425eec8b6977c03e" - integrity sha512-5fyqGHi51LU95o7qQ/vD1jyvC4uCY5GcBT+UgP4LHdpO9jPDlXqhrRr9/wCKmfoAvh5G/F7aOh4MwQa+8uEqhA== +"@emotion/cache@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff" + integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== dependencies: - "@emotion/memoize" "^0.8.0" - "@emotion/sheet" "^1.2.1" - "@emotion/utils" "^1.2.0" - "@emotion/weak-memoize" "^0.3.0" - stylis "4.1.4" + "@emotion/memoize" "^0.8.1" + "@emotion/sheet" "^1.2.2" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + stylis "4.2.0" "@emotion/css-prettifier@^1.0.0": version "1.0.0" @@ -2791,10 +2791,10 @@ resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.6.6.tgz" integrity sha512-ojhgxzUHZ7am3D2jHkMzPpsBAiB005GF5YU4ea+8DNPybMk01JJUM9V9YRlF/GE95tcOm8DxQvWA2jq19bGalQ== -"@emotion/hash@^0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.0.tgz#c5153d50401ee3c027a57a177bc269b16d889cb7" - integrity sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ== +"@emotion/hash@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" + integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== "@emotion/is-prop-valid@^1.0.0": version "1.1.1" @@ -2803,13 +2803,20 @@ dependencies: "@emotion/memoize" "^0.7.4" -"@emotion/is-prop-valid@^1.1.0", "@emotion/is-prop-valid@^1.2.0": +"@emotion/is-prop-valid@^1.1.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz#7f2d35c97891669f7e276eb71c83376a5dc44c83" integrity sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg== dependencies: "@emotion/memoize" "^0.8.0" +"@emotion/is-prop-valid@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" + integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/jest@^11.2.1": version "11.6.0" resolved "https://registry.npmjs.org/@emotion/jest/-/jest-11.6.0.tgz" @@ -2836,18 +2843,23 @@ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f" integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== -"@emotion/react@^11.10.5": - version "11.10.8" - resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.8.tgz#02e274ecb45e03ab9d7a8eb9f0f0c064613eaf7b" - integrity sha512-ZfGfiABtJ1P1OXqOBsW08EgCDp5fK6C5I8hUJauc/VcJBGSzqAirMnFslhFWnZJ/w5HxPI36XbvMV0l4KZHl+w== +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + +"@emotion/react@^11.10.4": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.0.tgz#408196b7ef8729d8ad08fc061b03b046d1460e02" + integrity sha512-ZSK3ZJsNkwfjT3JpDAWJZlrGD81Z3ytNDsxw1LKq1o+xkmO5pnWfr6gmCC8gHEFf3nSSX/09YrG67jybNPxSUw== dependencies: "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.10.8" - "@emotion/cache" "^11.10.8" - "@emotion/serialize" "^1.1.1" - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" - "@emotion/utils" "^1.2.0" - "@emotion/weak-memoize" "^0.3.0" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/cache" "^11.11.0" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" hoist-non-react-statics "^3.3.1" "@emotion/serialize@^0.9.1": @@ -2860,33 +2872,33 @@ "@emotion/unitless" "^0.6.7" "@emotion/utils" "^0.8.2" -"@emotion/serialize@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.1.tgz#0595701b1902feded8a96d293b26be3f5c1a5cf0" - integrity sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA== +"@emotion/serialize@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.2.tgz#017a6e4c9b8a803bd576ff3d52a0ea6fa5a62b51" + integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA== dependencies: - "@emotion/hash" "^0.9.0" - "@emotion/memoize" "^0.8.0" - "@emotion/unitless" "^0.8.0" - "@emotion/utils" "^1.2.0" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/unitless" "^0.8.1" + "@emotion/utils" "^1.2.1" csstype "^3.0.2" -"@emotion/sheet@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.1.tgz#0767e0305230e894897cadb6c8df2c51e61a6c2c" - integrity sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA== +"@emotion/sheet@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" + integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== -"@emotion/styled@^11.10.5": - version "11.10.8" - resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.8.tgz#a3fd68efd90bd7e8a06b82b95adec643d386fa69" - integrity sha512-gow0lF4Uw/QEdX2REMhI8v6wLOabPKJ+4HKNF0xdJ2DJdznN6fxaXpQOx6sNkyBhSUL558Rmcu1Lq/MYlVo4vw== +"@emotion/styled@^11.10.4": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346" + integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== dependencies: "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.10.8" - "@emotion/is-prop-valid" "^1.2.0" - "@emotion/serialize" "^1.1.1" - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" - "@emotion/utils" "^1.2.0" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/is-prop-valid" "^1.2.1" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" "@emotion/stylis@^0.7.0": version "0.7.1" @@ -2908,30 +2920,30 @@ resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== -"@emotion/unitless@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.0.tgz#a4a36e9cbdc6903737cd20d38033241e1b8833db" - integrity sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw== +"@emotion/unitless@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" + integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== -"@emotion/use-insertion-effect-with-fallbacks@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz#ffadaec35dbb7885bd54de3fa267ab2f860294df" - integrity sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A== +"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963" + integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== "@emotion/utils@^0.8.2": version "0.8.2" resolved "https://registry.npmjs.org/@emotion/utils/-/utils-0.8.2.tgz" integrity sha512-rLu3wcBWH4P5q1CGoSSH/i9hrXs7SlbRLkoq9IGuoPYNGQvDJ3pt/wmOM+XgYjIDRMVIdkUWt0RsfzF50JfnCw== -"@emotion/utils@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.0.tgz#9716eaccbc6b5ded2ea5a90d65562609aab0f561" - integrity sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw== +"@emotion/utils@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4" + integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== -"@emotion/weak-memoize@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb" - integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg== +"@emotion/weak-memoize@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" + integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== "@esbuild/android-arm64@0.16.3": version "0.16.3" @@ -3696,16 +3708,16 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" -"@newskit-themes/the-sun@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@newskit-themes/the-sun/-/the-sun-0.1.0.tgz#bd3f12d80fefe22eb2d75ffa75ff1630964deccb" - integrity sha512-oWXJ3gd+qKl+7tP8kxKEgPRm/EzHZAR5Hp2XGLUf0OxLfLXACUbKtbW6diOaToUrUD1xqfol1wJQh8VpR533QA== - "@newskit-themes/newskit-website@1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@newskit-themes/newskit-website/-/newskit-website-1.0.2.tgz#010214a9d05f89e78a6651aefee4136985119b72" integrity sha512-DQHBfVmCeOjJc0A9aXYVdQmnpBUdXSseSYJ7yATiO4snFFqjsVQlLhHsEThkmUrO0ArDmMelPtQAGket8XLXdw== +"@newskit-themes/the-sun@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@newskit-themes/the-sun/-/the-sun-0.1.0.tgz#bd3f12d80fefe22eb2d75ffa75ff1630964deccb" + integrity sha512-oWXJ3gd+qKl+7tP8kxKEgPRm/EzHZAR5Hp2XGLUf0OxLfLXACUbKtbW6diOaToUrUD1xqfol1wJQh8VpR533QA== + "@next/env@13.1.0": version "13.1.0" resolved "https://registry.yarnpkg.com/@next/env/-/env-13.1.0.tgz#fdb4d4711c6bd544dd80f0afd9846af2699b8c1c" @@ -21210,10 +21222,10 @@ stylis-rule-sheet@^0.0.10: resolved "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz" integrity sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw== -stylis@4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.4.tgz#9cb60e7153d8ac6d02d773552bf51c7a0344535b" - integrity sha512-USf5pszRYwuE6hg9by0OkKChkQYEXfkeTtm0xKw+jqQhwyjCVLdYyMBK7R+n7dhzsblAWJnGxju4vxq5eH20GQ== +stylis@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== stylis@^3.5.0: version "3.5.4" From 5c0e7b7b9541c2b9b63ff392f49d07d36fd56f46 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Fri, 19 May 2023 10:14:28 +0100 Subject: [PATCH 22/23] feat(806): container props tests --- src/utils/__tests__/container-properties.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/__tests__/container-properties.test.ts b/src/utils/__tests__/container-properties.test.ts index db4c94152b..3fff50d29b 100644 --- a/src/utils/__tests__/container-properties.test.ts +++ b/src/utils/__tests__/container-properties.test.ts @@ -21,7 +21,7 @@ describe('containerProps', () => { expect(result).toEqual(expected); }); - test('should return default values when props is undefined', () => { + test('should return undefined values when props is undefined', () => { const props = undefined; // @ts-ignore next-line From 48cb5c5483ecec9f727a33b4befa4d12d71d9519 Mon Sep 17 00:00:00 2001 From: Luke Finch Date: Fri, 19 May 2023 10:53:44 +0100 Subject: [PATCH 23/23] feat(806): update package json snapshot --- src/__tests__/__snapshots__/package.test.ts.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/__tests__/__snapshots__/package.test.ts.snap b/src/__tests__/__snapshots__/package.test.ts.snap index cf224350f7..7bdd5a23a6 100644 --- a/src/__tests__/__snapshots__/package.test.ts.snap +++ b/src/__tests__/__snapshots__/package.test.ts.snap @@ -31,8 +31,8 @@ Object { "module": "esm/index.js", "name": "newskit", "peerDependencies": Object { - "@emotion/react": ">= 11.1.5 <= 11.9.3", - "@emotion/styled": ">= 11.1.5 <= 11.9.3", + "@emotion/react": ">= 11.10.4 <= 12", + "@emotion/styled": ">= 11.10.4 <= 12", "react": ">= 16.8.0 <= 18", "react-dom": ">= 16.8.0 <= 18", "react-is": ">= 16.8.0 <= 18",