@compiled/react 0.18.4 → 0.18.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,11 @@
1
- import type { StrictCSSProperties, CSSPseudoClasses, CSSPseudoElements, CSSPseudos } from '../types';
1
+ import type { StrictCSSProperties, CSSPseudoElements, CSSPseudos, AllCSSPseudoClasses } from '../types';
2
2
  /**
3
3
  * This is the shape of the generic object that `createStrictAPI()` takes.
4
4
  * It's deliberately a subset of `AllowedStyles` and does not take at rules
5
5
  * and pseudo elements.
6
6
  */
7
7
  export type CompiledSchemaShape = StrictCSSProperties & {
8
- [Q in CSSPseudoClasses]?: StrictCSSProperties;
8
+ [Q in AllCSSPseudoClasses]?: StrictCSSProperties;
9
9
  };
10
10
  export type PseudosDeclarations = {
11
11
  [Q in CSSPseudos]?: StrictCSSProperties;
@@ -14,14 +14,14 @@ export type MediaQueries<TMediaQuery extends string> = {
14
14
  [Q in `@media ${TMediaQuery}`]?: StrictCSSProperties & PseudosDeclarations;
15
15
  };
16
16
  export type AllowedStyles<TMediaQuery extends string> = StrictCSSProperties & PseudosDeclarations & MediaQueries<TMediaQuery>;
17
- export type ApplySchemaValue<TSchema, TKey extends keyof StrictCSSProperties, TPseudoKey extends CSSPseudoClasses | ''> = TKey extends keyof TSchema ? TPseudoKey extends keyof TSchema ? TKey extends keyof TSchema[TPseudoKey] ? TSchema[TPseudoKey][TKey] : TSchema[TKey] : TSchema[TKey] : StrictCSSProperties[TKey];
17
+ export type ApplySchemaValue<TSchema, TKey extends keyof StrictCSSProperties, TPseudoKey extends AllCSSPseudoClasses | ''> = TKey extends keyof TSchema ? TPseudoKey extends keyof TSchema ? TKey extends keyof TSchema[TPseudoKey] ? TSchema[TPseudoKey][TKey] : TSchema[TKey] : TSchema[TKey] : StrictCSSProperties[TKey];
18
18
  /**
19
19
  * Recursively maps over object properties to resolve them to either a {@link TSchema}
20
20
  * value if present, else fallback to its value from {@link StrictCSSProperties}. If
21
21
  * the property isn't a known property its value will be resolved to `never`.
22
22
  */
23
- export type ApplySchema<TObject, TSchema, TPseudoKey extends CSSPseudoClasses | '' = ''> = {
24
- [TKey in keyof TObject]?: TKey extends keyof StrictCSSProperties ? ApplySchemaValue<TSchema, TKey, TPseudoKey> : TKey extends CSSPseudoClasses ? ApplySchema<TObject[TKey], TSchema, TKey> : TKey extends `@${string}` | CSSPseudoElements ? ApplySchema<TObject[TKey], TSchema> : never;
23
+ export type ApplySchema<TObject, TSchema, TPseudoKey extends AllCSSPseudoClasses | '' = ''> = {
24
+ [TKey in keyof TObject]?: TKey extends keyof StrictCSSProperties ? ApplySchemaValue<TSchema, TKey, TPseudoKey> : TKey extends AllCSSPseudoClasses ? ApplySchema<TObject[TKey], TSchema, TKey> : TKey extends `@${string}` | CSSPseudoElements ? ApplySchema<TObject[TKey], TSchema> : never;
25
25
  };
26
26
  export type ApplySchemaMap<TStylesMap, TSchema> = {
27
27
  [P in keyof TStylesMap]: ApplySchema<TStylesMap[P], TSchema>;
@@ -19,8 +19,10 @@ export type CssObject<TProps> = Readonly<{
19
19
  }>;
20
20
  export type CssFunction<TProps = unknown> = CssType<TProps> | BasicTemplateInterpolations | null | boolean | undefined;
21
21
  export type CSSPseudoElements = '&::after' | '&::backdrop' | '&::before' | '&::cue' | '&::cue-region' | '&::first-letter' | '&::first-line' | '&::grammar-error' | '&::marker' | '&::placeholder' | '&::selection' | '&::spelling-error' | '&::target-text' | '&::view-transition';
22
+ export type FlattenedChainedCSSPseudosClasses = '&:visited:active' | '&:visited:hover' | '&:active:visited' | '&:hover::before' | '&:hover::after' | '&:focus-visible::before' | '&:focus-visible::after' | '&:focus:not(:focus-visible)';
22
23
  export type CSSPseudoClasses = '&:active' | '&:autofill' | '&:blank' | '&:checked' | '&:default' | '&:defined' | '&:disabled' | '&:empty' | '&:enabled' | '&:first' | '&:focus' | '&:focus-visible' | '&:focus-within' | '&:fullscreen' | '&:hover' | '&:in-range' | '&:indeterminate' | '&:invalid' | '&:left' | '&:link' | '&:local-link' | '&:optional' | '&:out-of-range' | '&:paused' | '&:picture-in-picture' | '&:placeholder-shown' | '&:playing' | '&:read-only' | '&:read-write' | '&:required' | '&:right' | '&:target' | '&:user-invalid' | '&:user-valid' | '&:valid' | '&:visited';
23
- export type CSSPseudos = CSSPseudoElements | CSSPseudoClasses;
24
+ export type AllCSSPseudoClasses = CSSPseudoClasses | FlattenedChainedCSSPseudosClasses;
25
+ export type CSSPseudos = CSSPseudoElements | AllCSSPseudoClasses;
24
26
  /**
25
27
  * The XCSSProp must be given all known available properties even
26
28
  * if it takes a subset of them. This ensures the (lack-of an)
@@ -1,16 +1,16 @@
1
1
  import type * as CSS from 'csstype';
2
2
  import type { ApplySchemaValue } from '../create-strict-api/types';
3
- import type { CSSPseudos, CSSPseudoClasses, CSSProperties, StrictCSSProperties } from '../types';
3
+ import type { CSSPseudos, CSSProperties, StrictCSSProperties, AllCSSPseudoClasses } from '../types';
4
4
  type MarkAsRequired<T, K extends keyof T> = T & {
5
5
  [P in K]-?: T[P];
6
6
  };
7
- type XCSSValue<TStyleDecl extends keyof CSSProperties, TSchema, TPseudoKey extends CSSPseudoClasses | ''> = {
7
+ type XCSSValue<TStyleDecl extends keyof CSSProperties, TSchema, TPseudoKey extends AllCSSPseudoClasses | ''> = {
8
8
  [Q in keyof StrictCSSProperties]: Q extends TStyleDecl ? ApplySchemaValue<TSchema, Q, TPseudoKey> : never;
9
9
  };
10
10
  type XCSSPseudo<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TRequiredProperties extends {
11
11
  requiredProperties: TAllowedProperties;
12
12
  }, TSchema> = {
13
- [Q in CSSPseudos]?: Q extends TAllowedPseudos ? MarkAsRequired<XCSSValue<TAllowedProperties, TSchema, Q extends CSSPseudoClasses ? Q : ''>, TRequiredProperties['requiredProperties']> : never;
13
+ [Q in CSSPseudos]?: Q extends TAllowedPseudos ? MarkAsRequired<XCSSValue<TAllowedProperties, TSchema, Q extends AllCSSPseudoClasses ? Q : ''>, TRequiredProperties['requiredProperties']> : never;
14
14
  };
15
15
  type XCSSMediaQuery<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TAllowedMediaQueries extends string, TSchema> = {
16
16
  [Q in `@media ${TAllowedMediaQueries}`]?: XCSSValue<TAllowedProperties, TSchema, ''> | XCSSPseudo<TAllowedProperties, TAllowedPseudos, never, TSchema>;
@@ -1,11 +1,11 @@
1
- import type { StrictCSSProperties, CSSPseudoClasses, CSSPseudoElements, CSSPseudos } from '../types';
1
+ import type { StrictCSSProperties, CSSPseudoElements, CSSPseudos, AllCSSPseudoClasses } from '../types';
2
2
  /**
3
3
  * This is the shape of the generic object that `createStrictAPI()` takes.
4
4
  * It's deliberately a subset of `AllowedStyles` and does not take at rules
5
5
  * and pseudo elements.
6
6
  */
7
7
  export type CompiledSchemaShape = StrictCSSProperties & {
8
- [Q in CSSPseudoClasses]?: StrictCSSProperties;
8
+ [Q in AllCSSPseudoClasses]?: StrictCSSProperties;
9
9
  };
10
10
  export type PseudosDeclarations = {
11
11
  [Q in CSSPseudos]?: StrictCSSProperties;
@@ -14,14 +14,14 @@ export type MediaQueries<TMediaQuery extends string> = {
14
14
  [Q in `@media ${TMediaQuery}`]?: StrictCSSProperties & PseudosDeclarations;
15
15
  };
16
16
  export type AllowedStyles<TMediaQuery extends string> = StrictCSSProperties & PseudosDeclarations & MediaQueries<TMediaQuery>;
17
- export type ApplySchemaValue<TSchema, TKey extends keyof StrictCSSProperties, TPseudoKey extends CSSPseudoClasses | ''> = TKey extends keyof TSchema ? TPseudoKey extends keyof TSchema ? TKey extends keyof TSchema[TPseudoKey] ? TSchema[TPseudoKey][TKey] : TSchema[TKey] : TSchema[TKey] : StrictCSSProperties[TKey];
17
+ export type ApplySchemaValue<TSchema, TKey extends keyof StrictCSSProperties, TPseudoKey extends AllCSSPseudoClasses | ''> = TKey extends keyof TSchema ? TPseudoKey extends keyof TSchema ? TKey extends keyof TSchema[TPseudoKey] ? TSchema[TPseudoKey][TKey] : TSchema[TKey] : TSchema[TKey] : StrictCSSProperties[TKey];
18
18
  /**
19
19
  * Recursively maps over object properties to resolve them to either a {@link TSchema}
20
20
  * value if present, else fallback to its value from {@link StrictCSSProperties}. If
21
21
  * the property isn't a known property its value will be resolved to `never`.
22
22
  */
23
- export type ApplySchema<TObject, TSchema, TPseudoKey extends CSSPseudoClasses | '' = ''> = {
24
- [TKey in keyof TObject]?: TKey extends keyof StrictCSSProperties ? ApplySchemaValue<TSchema, TKey, TPseudoKey> : TKey extends CSSPseudoClasses ? ApplySchema<TObject[TKey], TSchema, TKey> : TKey extends `@${string}` | CSSPseudoElements ? ApplySchema<TObject[TKey], TSchema> : never;
23
+ export type ApplySchema<TObject, TSchema, TPseudoKey extends AllCSSPseudoClasses | '' = ''> = {
24
+ [TKey in keyof TObject]?: TKey extends keyof StrictCSSProperties ? ApplySchemaValue<TSchema, TKey, TPseudoKey> : TKey extends AllCSSPseudoClasses ? ApplySchema<TObject[TKey], TSchema, TKey> : TKey extends `@${string}` | CSSPseudoElements ? ApplySchema<TObject[TKey], TSchema> : never;
25
25
  };
26
26
  export type ApplySchemaMap<TStylesMap, TSchema> = {
27
27
  [P in keyof TStylesMap]: ApplySchema<TStylesMap[P], TSchema>;
@@ -19,8 +19,10 @@ export type CssObject<TProps> = Readonly<{
19
19
  }>;
20
20
  export type CssFunction<TProps = unknown> = CssType<TProps> | BasicTemplateInterpolations | null | boolean | undefined;
21
21
  export type CSSPseudoElements = '&::after' | '&::backdrop' | '&::before' | '&::cue' | '&::cue-region' | '&::first-letter' | '&::first-line' | '&::grammar-error' | '&::marker' | '&::placeholder' | '&::selection' | '&::spelling-error' | '&::target-text' | '&::view-transition';
22
+ export type FlattenedChainedCSSPseudosClasses = '&:visited:active' | '&:visited:hover' | '&:active:visited' | '&:hover::before' | '&:hover::after' | '&:focus-visible::before' | '&:focus-visible::after' | '&:focus:not(:focus-visible)';
22
23
  export type CSSPseudoClasses = '&:active' | '&:autofill' | '&:blank' | '&:checked' | '&:default' | '&:defined' | '&:disabled' | '&:empty' | '&:enabled' | '&:first' | '&:focus' | '&:focus-visible' | '&:focus-within' | '&:fullscreen' | '&:hover' | '&:in-range' | '&:indeterminate' | '&:invalid' | '&:left' | '&:link' | '&:local-link' | '&:optional' | '&:out-of-range' | '&:paused' | '&:picture-in-picture' | '&:placeholder-shown' | '&:playing' | '&:read-only' | '&:read-write' | '&:required' | '&:right' | '&:target' | '&:user-invalid' | '&:user-valid' | '&:valid' | '&:visited';
23
- export type CSSPseudos = CSSPseudoElements | CSSPseudoClasses;
24
+ export type AllCSSPseudoClasses = CSSPseudoClasses | FlattenedChainedCSSPseudosClasses;
25
+ export type CSSPseudos = CSSPseudoElements | AllCSSPseudoClasses;
24
26
  /**
25
27
  * The XCSSProp must be given all known available properties even
26
28
  * if it takes a subset of them. This ensures the (lack-of an)
@@ -1,16 +1,16 @@
1
1
  import type * as CSS from 'csstype';
2
2
  import type { ApplySchemaValue } from '../create-strict-api/types';
3
- import type { CSSPseudos, CSSPseudoClasses, CSSProperties, StrictCSSProperties } from '../types';
3
+ import type { CSSPseudos, CSSProperties, StrictCSSProperties, AllCSSPseudoClasses } from '../types';
4
4
  type MarkAsRequired<T, K extends keyof T> = T & {
5
5
  [P in K]-?: T[P];
6
6
  };
7
- type XCSSValue<TStyleDecl extends keyof CSSProperties, TSchema, TPseudoKey extends CSSPseudoClasses | ''> = {
7
+ type XCSSValue<TStyleDecl extends keyof CSSProperties, TSchema, TPseudoKey extends AllCSSPseudoClasses | ''> = {
8
8
  [Q in keyof StrictCSSProperties]: Q extends TStyleDecl ? ApplySchemaValue<TSchema, Q, TPseudoKey> : never;
9
9
  };
10
10
  type XCSSPseudo<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TRequiredProperties extends {
11
11
  requiredProperties: TAllowedProperties;
12
12
  }, TSchema> = {
13
- [Q in CSSPseudos]?: Q extends TAllowedPseudos ? MarkAsRequired<XCSSValue<TAllowedProperties, TSchema, Q extends CSSPseudoClasses ? Q : ''>, TRequiredProperties['requiredProperties']> : never;
13
+ [Q in CSSPseudos]?: Q extends TAllowedPseudos ? MarkAsRequired<XCSSValue<TAllowedProperties, TSchema, Q extends AllCSSPseudoClasses ? Q : ''>, TRequiredProperties['requiredProperties']> : never;
14
14
  };
15
15
  type XCSSMediaQuery<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TAllowedMediaQueries extends string, TSchema> = {
16
16
  [Q in `@media ${TAllowedMediaQueries}`]?: XCSSValue<TAllowedProperties, TSchema, ''> | XCSSPseudo<TAllowedProperties, TAllowedPseudos, never, TSchema>;
@@ -1,11 +1,11 @@
1
- import type { StrictCSSProperties, CSSPseudoClasses, CSSPseudoElements, CSSPseudos } from '../types';
1
+ import type { StrictCSSProperties, CSSPseudoElements, CSSPseudos, AllCSSPseudoClasses } from '../types';
2
2
  /**
3
3
  * This is the shape of the generic object that `createStrictAPI()` takes.
4
4
  * It's deliberately a subset of `AllowedStyles` and does not take at rules
5
5
  * and pseudo elements.
6
6
  */
7
7
  export type CompiledSchemaShape = StrictCSSProperties & {
8
- [Q in CSSPseudoClasses]?: StrictCSSProperties;
8
+ [Q in AllCSSPseudoClasses]?: StrictCSSProperties;
9
9
  };
10
10
  export type PseudosDeclarations = {
11
11
  [Q in CSSPseudos]?: StrictCSSProperties;
@@ -14,14 +14,14 @@ export type MediaQueries<TMediaQuery extends string> = {
14
14
  [Q in `@media ${TMediaQuery}`]?: StrictCSSProperties & PseudosDeclarations;
15
15
  };
16
16
  export type AllowedStyles<TMediaQuery extends string> = StrictCSSProperties & PseudosDeclarations & MediaQueries<TMediaQuery>;
17
- export type ApplySchemaValue<TSchema, TKey extends keyof StrictCSSProperties, TPseudoKey extends CSSPseudoClasses | ''> = TKey extends keyof TSchema ? TPseudoKey extends keyof TSchema ? TKey extends keyof TSchema[TPseudoKey] ? TSchema[TPseudoKey][TKey] : TSchema[TKey] : TSchema[TKey] : StrictCSSProperties[TKey];
17
+ export type ApplySchemaValue<TSchema, TKey extends keyof StrictCSSProperties, TPseudoKey extends AllCSSPseudoClasses | ''> = TKey extends keyof TSchema ? TPseudoKey extends keyof TSchema ? TKey extends keyof TSchema[TPseudoKey] ? TSchema[TPseudoKey][TKey] : TSchema[TKey] : TSchema[TKey] : StrictCSSProperties[TKey];
18
18
  /**
19
19
  * Recursively maps over object properties to resolve them to either a {@link TSchema}
20
20
  * value if present, else fallback to its value from {@link StrictCSSProperties}. If
21
21
  * the property isn't a known property its value will be resolved to `never`.
22
22
  */
23
- export type ApplySchema<TObject, TSchema, TPseudoKey extends CSSPseudoClasses | '' = ''> = {
24
- [TKey in keyof TObject]?: TKey extends keyof StrictCSSProperties ? ApplySchemaValue<TSchema, TKey, TPseudoKey> : TKey extends CSSPseudoClasses ? ApplySchema<TObject[TKey], TSchema, TKey> : TKey extends `@${string}` | CSSPseudoElements ? ApplySchema<TObject[TKey], TSchema> : never;
23
+ export type ApplySchema<TObject, TSchema, TPseudoKey extends AllCSSPseudoClasses | '' = ''> = {
24
+ [TKey in keyof TObject]?: TKey extends keyof StrictCSSProperties ? ApplySchemaValue<TSchema, TKey, TPseudoKey> : TKey extends AllCSSPseudoClasses ? ApplySchema<TObject[TKey], TSchema, TKey> : TKey extends `@${string}` | CSSPseudoElements ? ApplySchema<TObject[TKey], TSchema> : never;
25
25
  };
26
26
  export type ApplySchemaMap<TStylesMap, TSchema> = {
27
27
  [P in keyof TStylesMap]: ApplySchema<TStylesMap[P], TSchema>;
@@ -19,8 +19,10 @@ export type CssObject<TProps> = Readonly<{
19
19
  }>;
20
20
  export type CssFunction<TProps = unknown> = CssType<TProps> | BasicTemplateInterpolations | null | boolean | undefined;
21
21
  export type CSSPseudoElements = '&::after' | '&::backdrop' | '&::before' | '&::cue' | '&::cue-region' | '&::first-letter' | '&::first-line' | '&::grammar-error' | '&::marker' | '&::placeholder' | '&::selection' | '&::spelling-error' | '&::target-text' | '&::view-transition';
22
+ export type FlattenedChainedCSSPseudosClasses = '&:visited:active' | '&:visited:hover' | '&:active:visited' | '&:hover::before' | '&:hover::after' | '&:focus-visible::before' | '&:focus-visible::after' | '&:focus:not(:focus-visible)';
22
23
  export type CSSPseudoClasses = '&:active' | '&:autofill' | '&:blank' | '&:checked' | '&:default' | '&:defined' | '&:disabled' | '&:empty' | '&:enabled' | '&:first' | '&:focus' | '&:focus-visible' | '&:focus-within' | '&:fullscreen' | '&:hover' | '&:in-range' | '&:indeterminate' | '&:invalid' | '&:left' | '&:link' | '&:local-link' | '&:optional' | '&:out-of-range' | '&:paused' | '&:picture-in-picture' | '&:placeholder-shown' | '&:playing' | '&:read-only' | '&:read-write' | '&:required' | '&:right' | '&:target' | '&:user-invalid' | '&:user-valid' | '&:valid' | '&:visited';
23
- export type CSSPseudos = CSSPseudoElements | CSSPseudoClasses;
24
+ export type AllCSSPseudoClasses = CSSPseudoClasses | FlattenedChainedCSSPseudosClasses;
25
+ export type CSSPseudos = CSSPseudoElements | AllCSSPseudoClasses;
24
26
  /**
25
27
  * The XCSSProp must be given all known available properties even
26
28
  * if it takes a subset of them. This ensures the (lack-of an)
@@ -1,16 +1,16 @@
1
1
  import type * as CSS from 'csstype';
2
2
  import type { ApplySchemaValue } from '../create-strict-api/types';
3
- import type { CSSPseudos, CSSPseudoClasses, CSSProperties, StrictCSSProperties } from '../types';
3
+ import type { CSSPseudos, CSSProperties, StrictCSSProperties, AllCSSPseudoClasses } from '../types';
4
4
  type MarkAsRequired<T, K extends keyof T> = T & {
5
5
  [P in K]-?: T[P];
6
6
  };
7
- type XCSSValue<TStyleDecl extends keyof CSSProperties, TSchema, TPseudoKey extends CSSPseudoClasses | ''> = {
7
+ type XCSSValue<TStyleDecl extends keyof CSSProperties, TSchema, TPseudoKey extends AllCSSPseudoClasses | ''> = {
8
8
  [Q in keyof StrictCSSProperties]: Q extends TStyleDecl ? ApplySchemaValue<TSchema, Q, TPseudoKey> : never;
9
9
  };
10
10
  type XCSSPseudo<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TRequiredProperties extends {
11
11
  requiredProperties: TAllowedProperties;
12
12
  }, TSchema> = {
13
- [Q in CSSPseudos]?: Q extends TAllowedPseudos ? MarkAsRequired<XCSSValue<TAllowedProperties, TSchema, Q extends CSSPseudoClasses ? Q : ''>, TRequiredProperties['requiredProperties']> : never;
13
+ [Q in CSSPseudos]?: Q extends TAllowedPseudos ? MarkAsRequired<XCSSValue<TAllowedProperties, TSchema, Q extends AllCSSPseudoClasses ? Q : ''>, TRequiredProperties['requiredProperties']> : never;
14
14
  };
15
15
  type XCSSMediaQuery<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TAllowedMediaQueries extends string, TSchema> = {
16
16
  [Q in `@media ${TAllowedMediaQueries}`]?: XCSSValue<TAllowedProperties, TSchema, ''> | XCSSPseudo<TAllowedProperties, TAllowedPseudos, never, TSchema>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@compiled/react",
3
- "version": "0.18.4",
3
+ "version": "0.18.5",
4
4
  "description": "A familiar and performant compile time CSS-in-JS library for React.",
5
5
  "keywords": [
6
6
  "compiled",
@@ -94,13 +94,14 @@ describe('browser', () => {
94
94
  render(<StyledLink href="https://atlassian.design">Atlassian Design System</StyledLink>);
95
95
 
96
96
  expect(document.head.innerHTML.split('</style>').join('</style>\n')).toMatchInlineSnapshot(`
97
- "<style nonce="k0Mp1lEd">._1e0c1txw{display:flex}._1wyb12am{font-size:50px}._syaz1cnh{color:purple}._v0vw1x77:focus-visible, ._ysv71x77:link{color:white}</style>
98
- <style nonce="k0Mp1lEd">._ysv75scu:link{color:red}</style>
97
+ "<style nonce="k0Mp1lEd">._1e0c1txw{display:flex}._1wyb12am{font-size:50px}._syaz1cnh{color:purple}</style>
98
+ <style nonce="k0Mp1lEd">._ysv75scu:link{color:red}._ysv71x77:link{color:white}</style>
99
99
  <style nonce="k0Mp1lEd">._105332ev:visited{color:pink}</style>
100
100
  <style nonce="k0Mp1lEd">._f8pjbf54:focus{color:green}</style>
101
+ <style nonce="k0Mp1lEd">._v0vw1x77:focus-visible{color:white}</style>
101
102
  <style nonce="k0Mp1lEd">._30l31gy6:hover{color:yellow}</style>
102
103
  <style nonce="k0Mp1lEd">._9h8h13q2:active{color:blue}</style>
103
- <style nonce="k0Mp1lEd">@media (max-width:800px){._1o8z1gy6:focus{color:yellow}._jbabtwqo:focus-visible, ._6146twqo:hover{color:grey}._1cld11x8:active{color:black}}@supports (display:grid){._1df61gy6:focus{color:yellow}._7okp11x8:active{color:black}}</style>
104
+ <style nonce="k0Mp1lEd">@media (max-width:800px){._1o8z1gy6:focus{color:yellow}._jbabtwqo:focus-visible{color:grey}._6146twqo:hover{color:grey}._1cld11x8:active{color:black}}@supports (display:grid){._1df61gy6:focus{color:yellow}._7okp11x8:active{color:black}}</style>
104
105
  "
105
106
  `);
106
107
  });
@@ -24,9 +24,15 @@ interface PressedProperties {
24
24
  backgroundColor: BackgroundPressed;
25
25
  }
26
26
 
27
+ interface ChainedProperties {
28
+ color: ColorPressed;
29
+ backgroundColor: BackgroundPressed;
30
+ }
31
+
27
32
  interface CSSPropertiesSchema extends Properties {
28
33
  '&:hover': HoveredProperties;
29
34
  '&:active': PressedProperties;
35
+ '&:hover::after': ChainedProperties;
30
36
  }
31
37
 
32
38
  const { css, cssMap, cx, XCSSProp } = createStrictAPI<CSSPropertiesSchema>();
@@ -9,6 +9,7 @@ describe('createStrictAPI()', () => {
9
9
  const styles = css({
10
10
  '&:hover': {},
11
11
  '&:active': {},
12
+ '&:hover::after': {},
12
13
  '&::before': {},
13
14
  '&::after': {},
14
15
  });
@@ -23,6 +24,7 @@ describe('createStrictAPI()', () => {
23
24
  nested: {
24
25
  '&:hover': {},
25
26
  '&:active': {},
27
+ '&:hover::after': {},
26
28
  '&::before': {},
27
29
  '&::after': {},
28
30
  },
@@ -40,7 +42,7 @@ describe('createStrictAPI()', () => {
40
42
  xcss: ReturnType<
41
43
  typeof XCSSProp<
42
44
  'backgroundColor' | 'color',
43
- '&:hover' | '&:active' | '&::before' | '&::after'
45
+ '&:hover' | '&:active' | '&::before' | '&::after' | '&:hover::after'
44
46
  >
45
47
  >;
46
48
  }) {
@@ -49,7 +51,13 @@ describe('createStrictAPI()', () => {
49
51
 
50
52
  const { getByTestId } = render(
51
53
  <Component
52
- xcss={{ '&:hover': {}, '&:active': {}, '&::before': {}, '&::after': {} }}
54
+ xcss={{
55
+ '&:hover': {},
56
+ '&:active': {},
57
+ '&::before': {},
58
+ '&::after': {},
59
+ '&:hover::after': {},
60
+ }}
53
61
  data-testid="div"
54
62
  />
55
63
  );
@@ -76,6 +84,12 @@ describe('createStrictAPI()', () => {
76
84
  // @ts-expect-error — Type '""' is not assignable to type ...
77
85
  backgroundColor: '',
78
86
  },
87
+ '&:hover::after': {
88
+ // @ts-expect-error — Type '""' is not assignable to type ...
89
+ color: '',
90
+ // @ts-expect-error — Type '""' is not assignable to type ...
91
+ backgroundColor: '',
92
+ },
79
93
  '&::before': {
80
94
  // @ts-expect-error — Type '""' is not assignable to type ...
81
95
  color: '',
@@ -114,6 +128,12 @@ describe('createStrictAPI()', () => {
114
128
  // @ts-expect-error — Type '""' is not assignable to type ...
115
129
  backgroundColor: '',
116
130
  },
131
+ '&:hover::after': {
132
+ // @ts-expect-error — Type '""' is not assignable to type ...
133
+ color: '',
134
+ // @ts-expect-error — Type '""' is not assignable to type ...
135
+ backgroundColor: '',
136
+ },
117
137
  '&::before': {
118
138
  // @ts-expect-error — Type '""' is not assignable to type ...
119
139
  color: '',
@@ -139,7 +159,7 @@ describe('createStrictAPI()', () => {
139
159
  xcss: ReturnType<
140
160
  typeof XCSSProp<
141
161
  'backgroundColor' | 'color',
142
- '&:hover' | '&:active' | '&::before' | '&::after'
162
+ '&:hover' | '&:active' | '&::before' | '&::after' | '&:hover::after'
143
163
  >
144
164
  >;
145
165
  }) {
@@ -165,6 +185,12 @@ describe('createStrictAPI()', () => {
165
185
  // @ts-expect-error — Type '""' is not assignable to type ...
166
186
  backgroundColor: 'var(--ds-success)',
167
187
  },
188
+ '&:hover::after': {
189
+ // @ts-expect-error — Type '""' is not assignable to type ...
190
+ color: 'var(--ds-text)',
191
+ // @ts-expect-error — Type '""' is not assignable to type ...
192
+ backgroundColor: 'var(--ds-success)',
193
+ },
168
194
  '&::before': {
169
195
  // @ts-expect-error — Type '""' is not assignable to type ...
170
196
  color: '',
@@ -198,6 +224,12 @@ describe('createStrictAPI()', () => {
198
224
  color: 'var(--ds-text-hovered)',
199
225
  backgroundColor: 'var(--ds-bold-hovered)',
200
226
  },
227
+ '&:hover::after': {
228
+ // @ts-expect-error — should be a value from the schema
229
+ padding: '10px',
230
+ color: 'var(--ds-text-pressed)',
231
+ backgroundColor: 'var(--ds-bold-pressed)',
232
+ },
201
233
  '&:active': {
202
234
  // @ts-expect-error — should be a value from the schema
203
235
  padding: '10px',
@@ -243,6 +275,12 @@ describe('createStrictAPI()', () => {
243
275
  color: 'var(--ds-text-pressed)',
244
276
  backgroundColor: 'var(--ds-bold-pressed)',
245
277
  },
278
+ '&:hover::after': {
279
+ // @ts-expect-error — should be a value from the schema
280
+ padding: '10px',
281
+ color: 'var(--ds-text-pressed)',
282
+ backgroundColor: 'var(--ds-bold-pressed)',
283
+ },
246
284
  '&::before': {
247
285
  // @ts-expect-error — should be a value from the schema
248
286
  padding: '10px',
@@ -270,7 +308,7 @@ describe('createStrictAPI()', () => {
270
308
  xcss: ReturnType<
271
309
  typeof XCSSProp<
272
310
  'backgroundColor' | 'color',
273
- '&:hover' | '&:active' | '&::before' | '&::after'
311
+ '&:hover' | '&:active' | '&::before' | '&::after' | '&:hover::after'
274
312
  >
275
313
  >;
276
314
  }) {
@@ -290,6 +328,10 @@ describe('createStrictAPI()', () => {
290
328
  color: 'var(--ds-text-pressed)',
291
329
  backgroundColor: 'var(--ds-bold-pressed)',
292
330
  },
331
+ '&:hover::after': {
332
+ color: 'var(--ds-text-pressed)',
333
+ backgroundColor: 'var(--ds-bold-pressed)',
334
+ },
293
335
  '&::before': {
294
336
  color: 'var(--ds-text)',
295
337
  backgroundColor: 'var(--ds-bold)',
@@ -1,8 +1,8 @@
1
1
  import type {
2
2
  StrictCSSProperties,
3
- CSSPseudoClasses,
4
3
  CSSPseudoElements,
5
4
  CSSPseudos,
5
+ AllCSSPseudoClasses,
6
6
  } from '../types';
7
7
 
8
8
  /**
@@ -11,7 +11,7 @@ import type {
11
11
  * and pseudo elements.
12
12
  */
13
13
  export type CompiledSchemaShape = StrictCSSProperties & {
14
- [Q in CSSPseudoClasses]?: StrictCSSProperties;
14
+ [Q in AllCSSPseudoClasses]?: StrictCSSProperties;
15
15
  };
16
16
 
17
17
  export type PseudosDeclarations = { [Q in CSSPseudos]?: StrictCSSProperties };
@@ -27,7 +27,7 @@ export type AllowedStyles<TMediaQuery extends string> = StrictCSSProperties &
27
27
  export type ApplySchemaValue<
28
28
  TSchema,
29
29
  TKey extends keyof StrictCSSProperties,
30
- TPseudoKey extends CSSPseudoClasses | ''
30
+ TPseudoKey extends AllCSSPseudoClasses | ''
31
31
  > = TKey extends keyof TSchema
32
32
  ? // TKey is a valid property on the schema
33
33
  TPseudoKey extends keyof TSchema
@@ -46,11 +46,11 @@ export type ApplySchemaValue<
46
46
  * value if present, else fallback to its value from {@link StrictCSSProperties}. If
47
47
  * the property isn't a known property its value will be resolved to `never`.
48
48
  */
49
- export type ApplySchema<TObject, TSchema, TPseudoKey extends CSSPseudoClasses | '' = ''> = {
49
+ export type ApplySchema<TObject, TSchema, TPseudoKey extends AllCSSPseudoClasses | '' = ''> = {
50
50
  [TKey in keyof TObject]?: TKey extends keyof StrictCSSProperties
51
51
  ? // TKey is a valid CSS property, try to resolve its value.
52
52
  ApplySchemaValue<TSchema, TKey, TPseudoKey>
53
- : TKey extends CSSPseudoClasses
53
+ : TKey extends AllCSSPseudoClasses
54
54
  ? // TKey is a valid pseudo class, recursively resolve its child properties
55
55
  // while passing down the parent pseudo key to resolve any specific schema types.
56
56
  ApplySchema<TObject[TKey], TSchema, TKey>
package/src/types.ts CHANGED
@@ -51,6 +51,16 @@ export type CSSPseudoElements =
51
51
  | '&::target-text'
52
52
  | '&::view-transition';
53
53
 
54
+ export type FlattenedChainedCSSPseudosClasses =
55
+ | '&:visited:active'
56
+ | '&:visited:hover'
57
+ | '&:active:visited'
58
+ | '&:hover::before'
59
+ | '&:hover::after'
60
+ | '&:focus-visible::before'
61
+ | '&:focus-visible::after'
62
+ | '&:focus:not(:focus-visible)';
63
+
54
64
  export type CSSPseudoClasses =
55
65
  | '&:active'
56
66
  | '&:autofill'
@@ -89,14 +99,16 @@ export type CSSPseudoClasses =
89
99
  | '&:valid'
90
100
  | '&:visited';
91
101
 
102
+ export type AllCSSPseudoClasses = CSSPseudoClasses | FlattenedChainedCSSPseudosClasses;
103
+
92
104
  /*
93
- * This list of pseudo-classes and pseudo-elements are from csstype
105
+ * This list of pseudo-classes, chained pseudo-classes, and pseudo-elements are from csstype
94
106
  * but with & added to the front. Compiled supports both &-ful
95
107
  * and &-less forms and both will target the current element
96
108
  * (`&:hover` <==> `:hover`), however we force the use of the
97
109
  * &-ful form for consistency with the nested spec for new APIs.
98
110
  */
99
- export type CSSPseudos = CSSPseudoElements | CSSPseudoClasses;
111
+ export type CSSPseudos = CSSPseudoElements | AllCSSPseudoClasses;
100
112
 
101
113
  /**
102
114
  * The XCSSProp must be given all known available properties even
@@ -260,4 +260,35 @@ describe('xcss prop', () => {
260
260
  />
261
261
  ).toBeObject();
262
262
  });
263
+
264
+ it('should allow chained pseudo elements', () => {
265
+ function CSSPropComponent({ xcss }: { xcss: XCSSProp<XCSSAllProperties, '&:hover::after'> }) {
266
+ return <div className={xcss}>foo</div>;
267
+ }
268
+
269
+ const styles = cssMap({
270
+ redColor: { color: 'red', '&:hover::after': { backgroundColor: 'green' } },
271
+ });
272
+
273
+ const { getByText } = render(<CSSPropComponent xcss={styles.redColor} />);
274
+
275
+ expect(getByText('foo')).toHaveCompiledCss('color', 'red');
276
+ });
277
+
278
+ it('should type error when given a chained pseudo element and none are allowed', () => {
279
+ function CSSPropComponent({ xcss }: { xcss: XCSSProp<XCSSAllProperties, '&:hover'> }) {
280
+ return <div className={xcss}>foo</div>;
281
+ }
282
+
283
+ const styles = cssMap({
284
+ redColor: { color: 'red', '&:hover::after': { backgroundColor: 'green' } },
285
+ });
286
+
287
+ expectTypeOf(
288
+ <CSSPropComponent
289
+ // @ts-expect-error — Types of property '"&:hover::after"' are incompatible.
290
+ xcss={styles.redColor}
291
+ />
292
+ ).toBeObject();
293
+ });
263
294
  });
@@ -2,14 +2,14 @@ import type * as CSS from 'csstype';
2
2
 
3
3
  import type { ApplySchemaValue } from '../create-strict-api/types';
4
4
  import { ax } from '../runtime';
5
- import type { CSSPseudos, CSSPseudoClasses, CSSProperties, StrictCSSProperties } from '../types';
5
+ import type { CSSPseudos, CSSProperties, StrictCSSProperties, AllCSSPseudoClasses } from '../types';
6
6
 
7
7
  type MarkAsRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
8
8
 
9
9
  type XCSSValue<
10
10
  TStyleDecl extends keyof CSSProperties,
11
11
  TSchema,
12
- TPseudoKey extends CSSPseudoClasses | ''
12
+ TPseudoKey extends AllCSSPseudoClasses | ''
13
13
  > = {
14
14
  [Q in keyof StrictCSSProperties]: Q extends TStyleDecl
15
15
  ? ApplySchemaValue<TSchema, Q, TPseudoKey>
@@ -24,7 +24,7 @@ type XCSSPseudo<
24
24
  > = {
25
25
  [Q in CSSPseudos]?: Q extends TAllowedPseudos
26
26
  ? MarkAsRequired<
27
- XCSSValue<TAllowedProperties, TSchema, Q extends CSSPseudoClasses ? Q : ''>,
27
+ XCSSValue<TAllowedProperties, TSchema, Q extends AllCSSPseudoClasses ? Q : ''>,
28
28
  TRequiredProperties['requiredProperties']
29
29
  >
30
30
  : never;