diff --git a/package.json b/package.json
index bf38cc6014..2975e65669 100644
--- a/package.json
+++ b/package.json
@@ -101,7 +101,7 @@
"@docsearch/css": "^3.0.0",
"@docsearch/react": "^3.0.0",
"@emotion/jest": "^11.2.1",
- "@emotion/react": "^11.1.5",
+ "@emotion/react": "^11.10.4",
"@emotion/styled": "^11.10.4",
"@hookform/resolvers": "^2.5.0",
"@mapbox/rehype-prism": "^0.3.1",
@@ -292,8 +292,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/__tests__/__snapshots__/package.test.ts.snap b/src/__tests__/__snapshots__/package.test.ts.snap
index 4697cf56a1..3baa1cebf8 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",
diff --git a/src/block/__tests__/__snapshots__/block.test.tsx.snap b/src/block/__tests__/__snapshots__/block.test.tsx.snap
index 3ab1dba818..13da59d02d 100644
--- a/src/block/__tests__/__snapshots__/block.test.tsx.snap
+++ b/src/block/__tests__/__snapshots__/block.test.tsx.snap
@@ -8,6 +8,19 @@ 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`] = `
(
);
StoryBreakpoint.storyName = 'Breakpoint';
+export const StoryContainerQueries = () => {
+ 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 = () => (
{
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/block/block.tsx b/src/block/block.tsx
index 03a639a304..221563eef6 100644
--- a/src/block/block.tsx
+++ b/src/block/block.tsx
@@ -6,12 +6,15 @@ import {
MQ,
getSpacingFromTheme,
getStylePresetFromTheme,
+ ContainerQueryProps,
} from '../utils/style';
import {getTransitionPresetFromTheme} from '../utils/style/transition-preset';
+import {containerProps} from '../utils/container-properties';
export interface BlockProps
extends React.HTMLAttributes,
- LogicalProps {
+ LogicalProps,
+ ContainerQueryProps {
as?: keyof JSX.IntrinsicElements;
stylePreset?: MQ;
transitionPreset?: TransitionToken | TransitionToken[];
@@ -32,6 +35,7 @@ const StyledDiv = styled.div`
${({spaceStack}) =>
spaceStack && getSpacingFromTheme(spaceStack, undefined, 'marginBottom')}
${logicalProps()}
+ ${containerProps()}
${({transitionPreset}) =>
transitionPreset && getTransitionPresetFromTheme(transitionPreset)};
`;
diff --git a/src/card-composable/__tests__/card-composable.stories.tsx b/src/card-composable/__tests__/card-composable.stories.tsx
index cc9e83bfd2..22e05412b0 100644
--- a/src/card-composable/__tests__/card-composable.stories.tsx
+++ b/src/card-composable/__tests__/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,
@@ -38,6 +39,15 @@ import {
stylePresets as stylePresetsTheSun,
} from './the-sun-cards';
+const QueryContainerSmall = styled.div`
+ container-type: inline-size;
+ width: 300px;
+`;
+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: 'space020',
+ },
+ {
+ rule: '@container (width > 300px)',
+ value: 'space060',
+ },
+ ],
+ },
+ }}
+ rowGap={areasGap}
+ containerType="inline-size"
+ >
+
+ Flag
+ 300px)',
+ value: 'editorialHeadline040',
+ },
+ ],
+ },
+ }}
+ >
+ This headline's typographyPreset changes depending on its
+ container size
+
+
+
+
+
+
+ Tag
+
+
+
+ );
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+StoryContainerQueries.storyName = 'Container Queries';
+
export const StoryOverrides = () => (
@@ -779,7 +874,6 @@ export const StoryOverrides = () => (
);
StoryOverrides.storyName = 'Styling overrides';
-// https://www.linkedin.com/search/results/content/?keywords=design&origin=FACETED_SEARCH&postedBy=%5B%22first%22%2C%22following%22%5D&sid=xxV&sortBy=%22relevance%22
export const ComplexStory = () => (
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..b57020d7a4 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;
+ display: grid;
+ container-type: inline-size;
+ container-name: test-container;
+}
+
+
+
+`;
+
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/__tests__/stories/grid-layout.stories.tsx b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx
index 5bf58a815f..95fcc18196 100644
--- a/src/grid-layout/__tests__/stories/grid-layout.stories.tsx
+++ b/src/grid-layout/__tests__/stories/grid-layout.stories.tsx
@@ -9,6 +9,8 @@ import {Label} from '../../..';
import {
StorybookHeading,
StorybookSubHeading,
+ StorybookCase,
+ StorybookPage,
} from '../../../test/storybook-comps';
const BigRedBlock = styled(Block)`
@@ -163,6 +165,56 @@ export const StoryResponsiveExample = () => (
);
StoryResponsiveExample.storyName = 'responsive';
+export const StoryContainerQueryExample = () => {
+ const QueryGridLayout = () => (
+ 200px)',
+ value: '1fr',
+ },
+ ],
+ }}
+ columns={{
+ rules: [
+ {
+ rule: '@container (width <= 200px)',
+ value: '1fr',
+ },
+ {
+ rule: '@container (width > 200px)',
+ value: '1fr 1fr',
+ },
+ ],
+ }}
+ >
+ 1
+ 2
+
+ );
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+StoryContainerQueryExample.storyName = 'Container Queries';
+
export const StoryMinMaxRepeat = () => {
const boxes = Array.from(Array(20)).map((_, i) => {i} box);
return (
diff --git a/src/grid-layout/styled.ts b/src/grid-layout/styled.ts
index 4f0e1613e1..ba7b2b2d6d 100644
--- a/src/grid-layout/styled.ts
+++ b/src/grid-layout/styled.ts
@@ -2,6 +2,7 @@ import {Theme} from '../theme';
import {logicalProps} from '../utils/logical-properties';
import {getResponsiveSize, handleResponsiveProp, styled} from '../utils/style';
import {GridLayoutProps} from './types';
+import {containerProps} from '../utils/container-properties';
const GRID_DEFAULT_PROPS = {
rowGap: undefined,
@@ -121,4 +122,5 @@ export const StyledGridLayout = styled.div`
${getResponsiveSize('minHeight', 'gridLayout', '', 'minHeight')};
${getResponsiveSize('maxHeight', 'gridLayout', '', 'maxHeight')};
${logicalProps('gridLayout')}
+ ${containerProps()}
`;
diff --git a/src/grid-layout/types.ts b/src/grid-layout/types.ts
index e2db2035f0..e86f5c9cf6 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';
@@ -19,29 +19,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;
+export type GridLayoutProps = ContainerQueryProps & {
+ 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'>;
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));
}
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/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/text-block/__tests__/text-block.stories.tsx b/src/text-block/__tests__/text-block.stories.tsx
index 05cb85be53..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}}'},
@@ -71,6 +79,58 @@ export const StoryTextBlockLogicalProps = () => (
);
StoryTextBlockLogicalProps.storyName = 'Logical props';
+export const StoryTextBlockContainerQueries = () => {
+ const QueryTextBlock = () => (
+ 300px)',
+ value: 'editorialParagraph030',
+ },
+ ],
+ }}
+ stylePreset="inkContrast"
+ >
+ {BODY}
+
+ );
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+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/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;
diff --git a/src/utils/__tests__/base.test.ts b/src/utils/__tests__/base.test.ts
index 5d7b7ad669..68575d5e54 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,
@@ -58,7 +61,38 @@ describe('getXFromTheme', () => {
'@media screen and (min-width: 768px)': {width: '12px'},
});
});
-
+ test('getXFromTheme with Container Query value', () => {
+ const result = getXFromTheme('sizing')('width', {
+ rules: [{rule: '@container (min-width: 300px)', value: '4px'}],
+ })({theme});
+ expect(result).toEqual({
+ '@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',
+ sm: 'sizing020',
+ rules: [{rule: '@container (min-width: 300px)', value: '4px'}],
+ })({theme});
+ expect(result).toEqual({
+ '@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', () => {
const cb = (value: string) => ({padding: `${value} 0`, width: value});
const result = getXFromTheme('sizing')(cb, 'sizing050')({theme});
diff --git a/src/utils/__tests__/container-properties.test.ts b/src/utils/__tests__/container-properties.test.ts
new file mode 100644
index 0000000000..3fff50d29b
--- /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 undefined 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/__tests__/responsive-props.test.ts b/src/utils/__tests__/responsive-props.test.ts
index a32939303d..500defc5a3 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,27 @@ describe('handleResponsiveProp', () => {
});
});
+ it('using CQ rules value', () => {
+ const props = {
+ display: {
+ 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)': {
+ display: 'inline',
+ },
+ '@container (width >= 200px)': {
+ display: 'block',
+ },
+ });
+ });
+
it('does not have XS value', () => {
const props = {
display: {sm: 'inline', md: 'block'},
diff --git a/src/utils/container-properties.ts b/src/utils/container-properties.ts
new file mode 100644
index 0000000000..aa1515e4b0
--- /dev/null
+++ b/src/utils/container-properties.ts
@@ -0,0 +1,6 @@
+import {ContainerQueryProps, CSSObject} from './style';
+
+export const containerProps = () => (props: ContainerQueryProps) => {
+ const {containerType, containerName} = props || {};
+ return {containerType, containerName} as CSSObject;
+};
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/responsive-helpers.ts b/src/utils/responsive-helpers.ts
index 34a3361c78..195126039c 100644
--- a/src/utils/responsive-helpers.ts
+++ b/src/utils/responsive-helpers.ts
@@ -47,7 +47,8 @@ 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(breakpoints).some(bp => prop && hasOwnProperty(prop, bp)) ||
+ hasOwnProperty(prop, 'rules'));
diff --git a/src/utils/style/base.ts b/src/utils/style/base.ts
index fca9eb09df..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 {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;
@@ -76,7 +76,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 +114,27 @@ export const getResponsiveValueFromTheme = (
return acc;
}, {} as Record);
- return Object.entries(cssObject);
+ const containerKeys = (propKeys.rules || []) as CSSQuery[];
+
+ const cssContainerQueryObject =
+ containerKeys &&
+ containerKeys.reduce((acc, query) => {
+ const {rule, value} = query;
+ let preset = '' as Record[ThemeToken];
+ const MQtokens =
+ typeof value === 'string' && (value as string).split(' ');
+ if (themeKey === 'spacePresets' && isMQTokenArray(MQtokens)) {
+ preset = mapTokensArray(MQtokens);
+ } else {
+ preset =
+ section[value] ||
+ (canHaveNonThemeValue && isValidUnit(themeKey, value) && value);
+ }
+ acc[rule] = preset;
+ return acc;
+ }, {} as Record);
+
+ return Object.entries({...cssMediaQueryObject, ...cssContainerQueryObject});
}
const noMQtokens =
@@ -142,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,
diff --git a/src/utils/style/getters.ts b/src/utils/style/getters.ts
index 3f110b381c..ad4d4ad59c 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,
@@ -15,7 +15,7 @@ import {textCrop} from '../text-crop';
import {getFontMetrics} from './helpers/getter-helper';
export const getTypographyPresetFromTheme = (
- defaultToken?: MQ,
+ defaultToken?: ResponsiveValue,
customProp?: Exclude,
options?: {withCrop: boolean},
) => (props: Props) => {
@@ -201,7 +201,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
@@ -210,7 +209,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[];
@@ -243,6 +242,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,
@@ -308,30 +308,66 @@ export const handleResponsiveProp = (
? commonMQKeys
: ['xs', ...commonMQKeys];
- const cssObject = 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 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 [string, CSSQueryRules][];
+
+ const cssContainerQueryObject: Record<
+ CSSQuery['rule'],
+ string | CSSObject
+ > = usedValues.reduce(
+ (acc: Record['rule'], string | CSSObject>, prop) => {
+ const values = {} as {[Key in keyof T]: T[Key]};
+ 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);
+ });
}
- /* istanbul ignore next */
- return valAcc;
- }, {}) as {[Key in keyof T]: T[Key]};
- acc[mediaQuery] = propHandler(values, props, fromMqKey);
- return acc;
- }, {} as Record) as CSSObject;
+ return acc;
+ },
+ {},
+ );
- return cssObject;
+ return {...cssMediaQueryObject, ...cssContainerQueryObject};
};
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) => {
diff --git a/src/utils/style/types.ts b/src/utils/style/types.ts
index 805acd1a61..5ca7617637 100644
--- a/src/utils/style/types.ts
+++ b/src/utils/style/types.ts
@@ -7,3 +7,34 @@ 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;
+};
+
+export type CSSQueryRules = {
+ rules?: CSSQuery[];
+};
+
+export type ContainerQueryProps = {
+ containerType?:
+ | `normal`
+ | `inline-size`
+ | `size`
+ | `inherit`
+ | `initial`
+ | `unset`
+ | `revert`
+ | `revert-layer`;
+ containerName?: string;
+};
diff --git a/src/utils/style/utils.ts b/src/utils/style/utils.ts
index f88d275760..df869f3835 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 = [
diff --git a/yarn.lock b/yarn.lock
index b31f08d32b..eee6a654d3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1308,13 +1308,6 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
-"@babel/plugin-syntax-jsx@^7.17.12", "@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"
@@ -2750,23 +2750,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.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/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/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.0.13"
+ stylis "4.2.0"
"@emotion/babel-utils@^0.6.4":
version "0.6.10"
@@ -2780,16 +2779,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.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.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.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"
@@ -2804,10 +2803,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"
@@ -2816,13 +2815,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"
@@ -2849,17 +2855,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.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/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.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.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":
@@ -2872,33 +2884,33 @@
"@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.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.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.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.4":
- version "11.10.4"
- resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.4.tgz#e93f84a4d54003c2acbde178c3f97b421fce1cd4"
- integrity sha512-pRl4R8Ez3UXvOPfc2bzIoV8u9P97UedgHS4FPX594ntwEuAMA114wlaHvOK24HB48uqfXiGlYIZYCxVJ1R1ttQ==
+ 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.0"
- "@emotion/is-prop-valid" "^1.2.0"
- "@emotion/serialize" "^1.1.0"
- "@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"
@@ -2920,30 +2932,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.0.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/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.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.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"
@@ -21336,10 +21348,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.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"