@compiled/react 0.16.10 → 0.17.0
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.
- package/dist/browser/create-strict-api/index.d.ts +19 -22
- package/dist/browser/create-strict-api/index.js +6 -4
- package/dist/browser/create-strict-api/index.js.map +1 -1
- package/dist/browser/create-strict-api/types.d.ts +28 -0
- package/dist/browser/create-strict-api/types.js +2 -0
- package/dist/browser/create-strict-api/types.js.map +1 -0
- package/dist/browser/css/index.d.ts +2 -0
- package/dist/browser/css/index.js.map +1 -1
- package/dist/browser/css-map/index.d.ts +15 -2
- package/dist/browser/css-map/index.js.map +1 -1
- package/dist/browser/types.d.ts +4 -2
- package/dist/browser/xcss-prop/index.d.ts +17 -14
- package/dist/browser/xcss-prop/index.js.map +1 -1
- package/dist/cjs/create-strict-api/index.d.ts +19 -22
- package/dist/cjs/create-strict-api/index.js +6 -4
- package/dist/cjs/create-strict-api/index.js.map +1 -1
- package/dist/cjs/create-strict-api/types.d.ts +28 -0
- package/dist/cjs/create-strict-api/types.js +3 -0
- package/dist/cjs/create-strict-api/types.js.map +1 -0
- package/dist/cjs/css/index.d.ts +2 -0
- package/dist/cjs/css/index.js.map +1 -1
- package/dist/cjs/css-map/index.d.ts +15 -2
- package/dist/cjs/css-map/index.js.map +1 -1
- package/dist/cjs/types.d.ts +4 -2
- package/dist/cjs/xcss-prop/index.d.ts +17 -14
- package/dist/cjs/xcss-prop/index.js.map +1 -1
- package/dist/esm/create-strict-api/index.d.ts +19 -22
- package/dist/esm/create-strict-api/index.js +6 -4
- package/dist/esm/create-strict-api/index.js.map +1 -1
- package/dist/esm/create-strict-api/types.d.ts +28 -0
- package/dist/esm/create-strict-api/types.js +2 -0
- package/dist/esm/create-strict-api/types.js.map +1 -0
- package/dist/esm/css/index.d.ts +2 -0
- package/dist/esm/css/index.js.map +1 -1
- package/dist/esm/css-map/index.d.ts +15 -2
- package/dist/esm/css-map/index.js.map +1 -1
- package/dist/esm/types.d.ts +4 -2
- package/dist/esm/xcss-prop/index.d.ts +17 -14
- package/dist/esm/xcss-prop/index.js.map +1 -1
- package/package.json +1 -1
- package/src/create-strict-api/__tests__/__fixtures__/strict-api-recursive.ts +6 -6
- package/src/create-strict-api/__tests__/__fixtures__/strict-api.ts +14 -3
- package/src/create-strict-api/__tests__/css-func.test.tsx +49 -0
- package/src/create-strict-api/__tests__/generics.test.tsx +26 -5
- package/src/create-strict-api/__tests__/index.test.tsx +198 -32
- package/src/create-strict-api/index.ts +41 -34
- package/src/create-strict-api/types.ts +69 -0
- package/src/css/index.ts +2 -0
- package/src/css-map/index.ts +20 -2
- package/src/types.ts +14 -10
- package/src/xcss-prop/__tests__/media-query-strict.test.tsx +179 -0
- package/src/xcss-prop/__tests__/media-query.test.tsx +53 -0
- package/src/xcss-prop/__tests__/xcss-prop.test.tsx +3 -34
- package/src/xcss-prop/index.ts +47 -28
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
import type * as CSS from 'csstype';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ApplySchemaValue } from '../create-strict-api/types';
|
|
3
|
+
import type { CSSPseudos, CSSPseudoClasses, CSSProperties, StrictCSSProperties } from '../types';
|
|
3
4
|
type MarkAsRequired<T, K extends keyof T> = T & {
|
|
4
5
|
[P in K]-?: T[P];
|
|
5
6
|
};
|
|
6
|
-
type
|
|
7
|
-
[Q in keyof
|
|
7
|
+
type XCSSValue<TStyleDecl extends keyof CSSProperties, TSchema, TPseudoKey extends CSSPseudoClasses | ''> = {
|
|
8
|
+
[Q in keyof StrictCSSProperties]: Q extends TStyleDecl ? ApplySchemaValue<TSchema, Q, TPseudoKey> : never;
|
|
8
9
|
};
|
|
9
|
-
type
|
|
10
|
+
type XCSSPseudo<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TRequiredProperties extends {
|
|
10
11
|
requiredProperties: TAllowedProperties;
|
|
11
12
|
}, TSchema> = {
|
|
12
|
-
[Q in CSSPseudos]?: Q extends TAllowedPseudos ? MarkAsRequired<
|
|
13
|
+
[Q in CSSPseudos]?: Q extends TAllowedPseudos ? MarkAsRequired<XCSSValue<TAllowedProperties, TSchema, Q extends CSSPseudoClasses ? Q : ''>, TRequiredProperties['requiredProperties']> : never;
|
|
14
|
+
};
|
|
15
|
+
type XCSSMediaQuery<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TAllowedMediaQueries extends string, TSchema> = {
|
|
16
|
+
[Q in `@media ${TAllowedMediaQueries}`]?: XCSSValue<TAllowedProperties, TSchema, ''> | XCSSPseudo<TAllowedProperties, TAllowedPseudos, never, TSchema>;
|
|
13
17
|
};
|
|
14
18
|
/**
|
|
15
19
|
* These APIs we don't want to allow to be passed through the `xcss` prop but we also
|
|
16
20
|
* must declare them so the (lack-of a) excess property check doesn't bite us and allow
|
|
17
21
|
* unexpected values through.
|
|
18
22
|
*/
|
|
19
|
-
type BlockedRules = {
|
|
23
|
+
type BlockedRules<TMode extends 'loose' | 'strict'> = {
|
|
24
|
+
'@media [loose]'?: TMode extends 'loose' ? any : never;
|
|
20
25
|
selectors?: never;
|
|
21
26
|
} & {
|
|
22
27
|
[Q in CSS.AtRules]?: never;
|
|
@@ -30,7 +35,7 @@ type CompiledPropertyDeclarationReference = {
|
|
|
30
35
|
* take Compiled generated styles and not some arbitrary object.
|
|
31
36
|
*/
|
|
32
37
|
export type CompiledStyles<TObject> = {
|
|
33
|
-
[Q in keyof TObject]: TObject[Q] extends Record<string, unknown> ? CompiledStyles<TObject[Q]> : CompiledPropertyDeclarationReference;
|
|
38
|
+
[Q in keyof TObject]: TObject[Q] extends Record<string, unknown> ? CompiledStyles<TObject[Q]> : CompiledPropertyDeclarationReference & TObject[Q];
|
|
34
39
|
};
|
|
35
40
|
/**
|
|
36
41
|
* Please think twice before using this type, you're better off declaring explicitly
|
|
@@ -84,7 +89,7 @@ export type XCSSAllPseudos = CSSPseudos;
|
|
|
84
89
|
* xcss?: XCSSProp<XCSSAllProperties, '&:hover'>;
|
|
85
90
|
*
|
|
86
91
|
* // The xcss prop is required as well as the color property. No pseudos are required.
|
|
87
|
-
* xcss: XCSSProp<XCSSAllProperties, '&:hover', { requiredProperties: 'color'
|
|
92
|
+
* xcss: XCSSProp<XCSSAllProperties, '&:hover', { requiredProperties: 'color' }>;
|
|
88
93
|
* }
|
|
89
94
|
*
|
|
90
95
|
* function MyComponent({ xcss }: MyComponentProps) {
|
|
@@ -106,14 +111,12 @@ export type XCSSAllPseudos = CSSPseudos;
|
|
|
106
111
|
*
|
|
107
112
|
* To concatenate and conditonally apply styles use the {@link cssMap} {@link cx} functions.
|
|
108
113
|
*/
|
|
109
|
-
export type XCSSProp<TAllowedProperties extends keyof
|
|
114
|
+
export type XCSSProp<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TRequiredProperties extends {
|
|
110
115
|
requiredProperties: TAllowedProperties;
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
export type Internal$XCSSProp<TAllowedProperties extends keyof CSSProperties, TAllowedPseudos extends CSSPseudos, TSchema, TRequiredProperties extends {
|
|
116
|
+
} = never> = Internal$XCSSProp<TAllowedProperties, TAllowedPseudos, string, object, TRequiredProperties, 'loose'>;
|
|
117
|
+
export type Internal$XCSSProp<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TAllowedMediaQueries extends string, TSchema, TRequiredProperties extends {
|
|
114
118
|
requiredProperties: TAllowedProperties;
|
|
115
|
-
|
|
116
|
-
}> = (MarkAsRequired<XCSSItem<TAllowedProperties, TSchema>, TRequiredProperties['requiredProperties']> & MarkAsRequired<XCSSPseudos<TAllowedProperties, TAllowedPseudos, TRequiredProperties, TSchema>, TRequiredProperties['requiredPseudos']> & BlockedRules) | false | null | undefined;
|
|
119
|
+
}, TMode extends 'loose' | 'strict'> = (MarkAsRequired<XCSSValue<TAllowedProperties, TSchema, ''>, TRequiredProperties['requiredProperties']> & XCSSPseudo<TAllowedProperties, TAllowedPseudos, TRequiredProperties, TSchema> & XCSSMediaQuery<TAllowedProperties, TAllowedPseudos, TAllowedMediaQueries, TSchema> & BlockedRules<TMode>) | false | null | undefined;
|
|
117
120
|
/**
|
|
118
121
|
* ## CX
|
|
119
122
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/xcss-prop/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/xcss-prop/index.ts"],"names":[],"mappings":";;;AAGA,wCAAgC;AAsLhC;;;;;;;;;;;;;;;GAeG;AACI,MAAM,EAAE,GAAG,CAChB,GAAG,MAAe,EACD,EAAE;IACnB,2EAA2E;IAC3E,sDAAsD;IACtD,MAAM,YAAY,GAAG,MAA6B,CAAC;IAEnD,+EAA+E;IAC/E,kFAAkF;IAClF,OAAO,IAAA,YAAE,EAAC,YAAY,CAAoB,CAAC;AAC7C,CAAC,CAAC;AAVW,QAAA,EAAE,MAUb"}
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import type { StrictCSSProperties, CSSPseudos } from '../types';
|
|
1
|
+
import type { StrictCSSProperties, CSSPseudos, CSSProps } from '../types';
|
|
2
2
|
import { type CompiledStyles, cx, type Internal$XCSSProp } from '../xcss-prop';
|
|
3
|
-
type
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
};
|
|
9
|
-
type CSSStyles<TSchema extends CompiledSchema> = StrictCSSProperties & PseudosDeclarations & EnforceSchema<TSchema>;
|
|
10
|
-
type CSSMapStyles<TSchema extends CompiledSchema> = Record<string, CSSStyles<TSchema>>;
|
|
11
|
-
interface CompiledAPI<TSchema extends CompiledSchema> {
|
|
3
|
+
import type { AllowedStyles, ApplySchema, ApplySchemaMap, CompiledSchemaShape } from './types';
|
|
4
|
+
export interface StrictOptions {
|
|
5
|
+
media: string;
|
|
6
|
+
}
|
|
7
|
+
export interface CompiledAPI<TSchema extends CompiledSchemaShape, TAllowedMediaQueries extends string> {
|
|
12
8
|
/**
|
|
13
9
|
* ## CSS
|
|
14
10
|
*
|
|
15
11
|
* Creates styles that are statically typed and useable with other Compiled APIs.
|
|
16
12
|
* For further details [read the documentation](https://compiledcssinjs.com/docs/api-css).
|
|
17
13
|
*
|
|
14
|
+
* This API does not currently work with XCSS prop.
|
|
15
|
+
*
|
|
18
16
|
* @example
|
|
19
17
|
* ```
|
|
20
18
|
* const redText = css({
|
|
@@ -24,7 +22,7 @@ interface CompiledAPI<TSchema extends CompiledSchema> {
|
|
|
24
22
|
* <div css={redText} />
|
|
25
23
|
* ```
|
|
26
24
|
*/
|
|
27
|
-
css(styles:
|
|
25
|
+
css<TStyles extends ApplySchema<TStyles, TSchema>>(styles: AllowedStyles<TAllowedMediaQueries> & TStyles): CSSProps<unknown>;
|
|
28
26
|
/**
|
|
29
27
|
* ## CSS Map
|
|
30
28
|
*
|
|
@@ -41,7 +39,7 @@ interface CompiledAPI<TSchema extends CompiledSchema> {
|
|
|
41
39
|
* <div css={styles.solid} />
|
|
42
40
|
* ```
|
|
43
41
|
*/
|
|
44
|
-
cssMap<TStylesMap extends
|
|
42
|
+
cssMap<TObject extends Record<string, AllowedStyles<TAllowedMediaQueries>>, TStylesMap extends ApplySchemaMap<TObject, TSchema>>(styles: Record<string, AllowedStyles<TAllowedMediaQueries>> & TStylesMap): {
|
|
45
43
|
readonly [P in keyof TStylesMap]: CompiledStyles<TStylesMap[P]>;
|
|
46
44
|
};
|
|
47
45
|
/**
|
|
@@ -99,7 +97,7 @@ interface CompiledAPI<TSchema extends CompiledSchema> {
|
|
|
99
97
|
* typeof XCSSProp<
|
|
100
98
|
* XCSSAllProperties,
|
|
101
99
|
* '&:hover',
|
|
102
|
-
* { requiredProperties: 'color'
|
|
100
|
+
* { requiredProperties: 'color' }
|
|
103
101
|
* >
|
|
104
102
|
* >;
|
|
105
103
|
* }
|
|
@@ -124,10 +122,8 @@ interface CompiledAPI<TSchema extends CompiledSchema> {
|
|
|
124
122
|
*/
|
|
125
123
|
XCSSProp<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TRequiredProperties extends {
|
|
126
124
|
requiredProperties: TAllowedProperties;
|
|
127
|
-
|
|
128
|
-
} = never>(): Internal$XCSSProp<TAllowedProperties, TAllowedPseudos, TSchema, TRequiredProperties>;
|
|
125
|
+
} = never>(): Internal$XCSSProp<TAllowedProperties, TAllowedPseudos, TAllowedMediaQueries, TSchema, TRequiredProperties, 'strict'>;
|
|
129
126
|
}
|
|
130
|
-
type CompiledSchema = StrictCSSProperties & PseudosDeclarations;
|
|
131
127
|
/**
|
|
132
128
|
* ## Create Strict API
|
|
133
129
|
*
|
|
@@ -142,17 +138,19 @@ type CompiledSchema = StrictCSSProperties & PseudosDeclarations;
|
|
|
142
138
|
*
|
|
143
139
|
* To set up:
|
|
144
140
|
*
|
|
145
|
-
* 1. Declare the API in a module (either local or in a package)
|
|
141
|
+
* 1. Declare the API in a module (either local or in a package), optionally declaring accepted media queries.
|
|
146
142
|
*
|
|
147
143
|
* @example
|
|
148
144
|
* ```tsx
|
|
149
145
|
* // ./foo.ts
|
|
150
|
-
*
|
|
146
|
+
* interface Schema {
|
|
151
147
|
* color: 'var(--ds-text)',
|
|
152
148
|
* '&:hover': { color: 'var(--ds-text-hover)' }
|
|
153
|
-
* }
|
|
149
|
+
* }
|
|
150
|
+
*
|
|
151
|
+
* const { css, cssMap, XCSSProp, cx } = createStrictAPI<Schema, { media: '(min-width: 30rem)' }>();
|
|
154
152
|
*
|
|
155
|
-
* export { css };
|
|
153
|
+
* export { css, cssMap, XCSSProp, cx };
|
|
156
154
|
* ```
|
|
157
155
|
*
|
|
158
156
|
* 2. Configure Compiled to pick up this module:
|
|
@@ -176,5 +174,4 @@ type CompiledSchema = StrictCSSProperties & PseudosDeclarations;
|
|
|
176
174
|
* <div css={styles} />
|
|
177
175
|
* ```
|
|
178
176
|
*/
|
|
179
|
-
export declare function createStrictAPI<TSchema extends
|
|
180
|
-
export {};
|
|
177
|
+
export declare function createStrictAPI<TSchema extends CompiledSchemaShape, TCreateStrictAPIOptions extends StrictOptions = never>(): CompiledAPI<TSchema, TCreateStrictAPIOptions['media']>;
|
|
@@ -14,17 +14,19 @@ import { cx } from '../xcss-prop';
|
|
|
14
14
|
*
|
|
15
15
|
* To set up:
|
|
16
16
|
*
|
|
17
|
-
* 1. Declare the API in a module (either local or in a package)
|
|
17
|
+
* 1. Declare the API in a module (either local or in a package), optionally declaring accepted media queries.
|
|
18
18
|
*
|
|
19
19
|
* @example
|
|
20
20
|
* ```tsx
|
|
21
21
|
* // ./foo.ts
|
|
22
|
-
*
|
|
22
|
+
* interface Schema {
|
|
23
23
|
* color: 'var(--ds-text)',
|
|
24
24
|
* '&:hover': { color: 'var(--ds-text-hover)' }
|
|
25
|
-
* }
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* const { css, cssMap, XCSSProp, cx } = createStrictAPI<Schema, { media: '(min-width: 30rem)' }>();
|
|
26
28
|
*
|
|
27
|
-
* export { css };
|
|
29
|
+
* export { css, cssMap, XCSSProp, cx };
|
|
28
30
|
* ```
|
|
29
31
|
*
|
|
30
32
|
* 2. Configure Compiled to pick up this module:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/create-strict-api/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAuB,EAAE,EAA0B,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/create-strict-api/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAuB,EAAE,EAA0B,MAAM,cAAc,CAAC;AAyJ/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,MAAM,UAAU,eAAe;IAI7B,OAAO;QACL,GAAG;YACD,MAAM,sBAAsB,EAAE,CAAC;QACjC,CAAC;QACD,MAAM;YACJ,MAAM,sBAAsB,EAAE,CAAC;QACjC,CAAC;QACD,EAAE;QACF,QAAQ;YACN,MAAM,sBAAsB,EAAE,CAAC;QACjC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { StrictCSSProperties, CSSPseudoClasses, CSSPseudoElements, CSSPseudos } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* This is the shape of the generic object that `createStrictAPI()` takes.
|
|
4
|
+
* It's deliberately a subset of `AllowedStyles` and does not take at rules
|
|
5
|
+
* and pseudo elements.
|
|
6
|
+
*/
|
|
7
|
+
export type CompiledSchemaShape = StrictCSSProperties & {
|
|
8
|
+
[Q in CSSPseudoClasses]?: StrictCSSProperties;
|
|
9
|
+
};
|
|
10
|
+
export type PseudosDeclarations = {
|
|
11
|
+
[Q in CSSPseudos]?: StrictCSSProperties;
|
|
12
|
+
};
|
|
13
|
+
export type MediaQueries<TMediaQuery extends string> = {
|
|
14
|
+
[Q in `@media ${TMediaQuery}`]?: StrictCSSProperties & PseudosDeclarations;
|
|
15
|
+
};
|
|
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];
|
|
18
|
+
/**
|
|
19
|
+
* Recursively maps over object properties to resolve them to either a {@link TSchema}
|
|
20
|
+
* value if present, else fallback to its value from {@link StrictCSSProperties}. If
|
|
21
|
+
* the property isn't a known property its value will be resolved to `never`.
|
|
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;
|
|
25
|
+
};
|
|
26
|
+
export type ApplySchemaMap<TStylesMap, TSchema> = {
|
|
27
|
+
[P in keyof TStylesMap]: ApplySchema<TStylesMap[P], TSchema>;
|
|
28
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/create-strict-api/types.ts"],"names":[],"mappings":""}
|
package/dist/esm/css/index.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ import type { CSSProps, CssObject, CssFunction } from '../types';
|
|
|
5
5
|
* Create styles that are statically typed and useable with other Compiled APIs.
|
|
6
6
|
* For further details [read the documentation](https://compiledcssinjs.com/docs/api-css).
|
|
7
7
|
*
|
|
8
|
+
* This API does not currently work with XCSS prop.
|
|
9
|
+
*
|
|
8
10
|
* ### Style with objects
|
|
9
11
|
*
|
|
10
12
|
* @example
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/css/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAGlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/css/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAGlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAyClD,MAAM,CAAC,OAAO,UAAU,GAAG,CACzB,OAA6D,EAC7D,GAAG,eAA8B;IAEjC,MAAM,gBAAgB,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -77,6 +77,19 @@ type ExtendedSelectors = {
|
|
|
77
77
|
*/
|
|
78
78
|
selectors?: ExtendedSelector;
|
|
79
79
|
};
|
|
80
|
+
type LooseMediaQueries = Record<`@media ${string}`, CSSProperties & AllPseudos>;
|
|
81
|
+
/**
|
|
82
|
+
* We remap media query keys to `"@media"` so it's blocked inside the strict APIs.
|
|
83
|
+
* This is done as it's currently impossible to ensure type safety end-to-end — when
|
|
84
|
+
* passing in unknown media queries from the loose API into the strict API you end up
|
|
85
|
+
* being also able to pass any styles you want, which makes the whole point of the strict
|
|
86
|
+
* API meaningless.
|
|
87
|
+
*
|
|
88
|
+
* Sorry folks!
|
|
89
|
+
*/
|
|
90
|
+
type RemapMedia<TStyles> = {
|
|
91
|
+
[Q in keyof TStyles as Q extends `@media ${string}` ? '@media [loose]' : Q]: TStyles[Q];
|
|
92
|
+
};
|
|
80
93
|
/**
|
|
81
94
|
* ## CSS Map
|
|
82
95
|
*
|
|
@@ -93,7 +106,7 @@ type ExtendedSelectors = {
|
|
|
93
106
|
* <div css={styles.solid} />
|
|
94
107
|
* ```
|
|
95
108
|
*/
|
|
96
|
-
export default function cssMap<TStyles extends Record<string, CSSProperties & WhitelistedSelector & ExtendedSelectors>>(_styles: TStyles): {
|
|
97
|
-
readonly [P in keyof TStyles]: CompiledStyles<TStyles[P]
|
|
109
|
+
export default function cssMap<TStyles extends Record<string, CSSProperties & WhitelistedSelector & ExtendedSelectors & LooseMediaQueries>>(_styles: TStyles): {
|
|
110
|
+
readonly [P in keyof TStyles]: CompiledStyles<RemapMedia<TStyles[P]>>;
|
|
98
111
|
};
|
|
99
112
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/css-map/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/css-map/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAiGlD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAM5B,OAAgB;IAIhB,MAAM,gBAAgB,EAAE,CAAC;AAC3B,CAAC"}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -18,14 +18,16 @@ export type CssObject<TProps> = Readonly<{
|
|
|
18
18
|
[key: string]: CssFunction<TProps>;
|
|
19
19
|
}>;
|
|
20
20
|
export type CssFunction<TProps = unknown> = CssType<TProps> | BasicTemplateInterpolations | null | boolean | undefined;
|
|
21
|
-
export type
|
|
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 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;
|
|
22
24
|
/**
|
|
23
25
|
* The XCSSProp must be given all known available properties even
|
|
24
26
|
* if it takes a subset of them. This ensures the (lack-of an)
|
|
25
27
|
* excess property check doesn't enable makers to circumvent the
|
|
26
28
|
* system and pass in values they shouldn't.
|
|
27
29
|
*/
|
|
28
|
-
export type CSSProperties = Readonly<CSS.Properties<string | number>>;
|
|
30
|
+
export type CSSProperties = Readonly<CSS.Properties<(string & object) | number>>;
|
|
29
31
|
/**
|
|
30
32
|
* A stricter subset of the {@link CSSProperties} type that excludes
|
|
31
33
|
* vendor and obsolete properties.
|
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
import type * as CSS from 'csstype';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ApplySchemaValue } from '../create-strict-api/types';
|
|
3
|
+
import type { CSSPseudos, CSSPseudoClasses, CSSProperties, StrictCSSProperties } from '../types';
|
|
3
4
|
type MarkAsRequired<T, K extends keyof T> = T & {
|
|
4
5
|
[P in K]-?: T[P];
|
|
5
6
|
};
|
|
6
|
-
type
|
|
7
|
-
[Q in keyof
|
|
7
|
+
type XCSSValue<TStyleDecl extends keyof CSSProperties, TSchema, TPseudoKey extends CSSPseudoClasses | ''> = {
|
|
8
|
+
[Q in keyof StrictCSSProperties]: Q extends TStyleDecl ? ApplySchemaValue<TSchema, Q, TPseudoKey> : never;
|
|
8
9
|
};
|
|
9
|
-
type
|
|
10
|
+
type XCSSPseudo<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TRequiredProperties extends {
|
|
10
11
|
requiredProperties: TAllowedProperties;
|
|
11
12
|
}, TSchema> = {
|
|
12
|
-
[Q in CSSPseudos]?: Q extends TAllowedPseudos ? MarkAsRequired<
|
|
13
|
+
[Q in CSSPseudos]?: Q extends TAllowedPseudos ? MarkAsRequired<XCSSValue<TAllowedProperties, TSchema, Q extends CSSPseudoClasses ? Q : ''>, TRequiredProperties['requiredProperties']> : never;
|
|
14
|
+
};
|
|
15
|
+
type XCSSMediaQuery<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TAllowedMediaQueries extends string, TSchema> = {
|
|
16
|
+
[Q in `@media ${TAllowedMediaQueries}`]?: XCSSValue<TAllowedProperties, TSchema, ''> | XCSSPseudo<TAllowedProperties, TAllowedPseudos, never, TSchema>;
|
|
13
17
|
};
|
|
14
18
|
/**
|
|
15
19
|
* These APIs we don't want to allow to be passed through the `xcss` prop but we also
|
|
16
20
|
* must declare them so the (lack-of a) excess property check doesn't bite us and allow
|
|
17
21
|
* unexpected values through.
|
|
18
22
|
*/
|
|
19
|
-
type BlockedRules = {
|
|
23
|
+
type BlockedRules<TMode extends 'loose' | 'strict'> = {
|
|
24
|
+
'@media [loose]'?: TMode extends 'loose' ? any : never;
|
|
20
25
|
selectors?: never;
|
|
21
26
|
} & {
|
|
22
27
|
[Q in CSS.AtRules]?: never;
|
|
@@ -30,7 +35,7 @@ type CompiledPropertyDeclarationReference = {
|
|
|
30
35
|
* take Compiled generated styles and not some arbitrary object.
|
|
31
36
|
*/
|
|
32
37
|
export type CompiledStyles<TObject> = {
|
|
33
|
-
[Q in keyof TObject]: TObject[Q] extends Record<string, unknown> ? CompiledStyles<TObject[Q]> : CompiledPropertyDeclarationReference;
|
|
38
|
+
[Q in keyof TObject]: TObject[Q] extends Record<string, unknown> ? CompiledStyles<TObject[Q]> : CompiledPropertyDeclarationReference & TObject[Q];
|
|
34
39
|
};
|
|
35
40
|
/**
|
|
36
41
|
* Please think twice before using this type, you're better off declaring explicitly
|
|
@@ -84,7 +89,7 @@ export type XCSSAllPseudos = CSSPseudos;
|
|
|
84
89
|
* xcss?: XCSSProp<XCSSAllProperties, '&:hover'>;
|
|
85
90
|
*
|
|
86
91
|
* // The xcss prop is required as well as the color property. No pseudos are required.
|
|
87
|
-
* xcss: XCSSProp<XCSSAllProperties, '&:hover', { requiredProperties: 'color'
|
|
92
|
+
* xcss: XCSSProp<XCSSAllProperties, '&:hover', { requiredProperties: 'color' }>;
|
|
88
93
|
* }
|
|
89
94
|
*
|
|
90
95
|
* function MyComponent({ xcss }: MyComponentProps) {
|
|
@@ -106,14 +111,12 @@ export type XCSSAllPseudos = CSSPseudos;
|
|
|
106
111
|
*
|
|
107
112
|
* To concatenate and conditonally apply styles use the {@link cssMap} {@link cx} functions.
|
|
108
113
|
*/
|
|
109
|
-
export type XCSSProp<TAllowedProperties extends keyof
|
|
114
|
+
export type XCSSProp<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TRequiredProperties extends {
|
|
110
115
|
requiredProperties: TAllowedProperties;
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
export type Internal$XCSSProp<TAllowedProperties extends keyof CSSProperties, TAllowedPseudos extends CSSPseudos, TSchema, TRequiredProperties extends {
|
|
116
|
+
} = never> = Internal$XCSSProp<TAllowedProperties, TAllowedPseudos, string, object, TRequiredProperties, 'loose'>;
|
|
117
|
+
export type Internal$XCSSProp<TAllowedProperties extends keyof StrictCSSProperties, TAllowedPseudos extends CSSPseudos, TAllowedMediaQueries extends string, TSchema, TRequiredProperties extends {
|
|
114
118
|
requiredProperties: TAllowedProperties;
|
|
115
|
-
|
|
116
|
-
}> = (MarkAsRequired<XCSSItem<TAllowedProperties, TSchema>, TRequiredProperties['requiredProperties']> & MarkAsRequired<XCSSPseudos<TAllowedProperties, TAllowedPseudos, TRequiredProperties, TSchema>, TRequiredProperties['requiredPseudos']> & BlockedRules) | false | null | undefined;
|
|
119
|
+
}, TMode extends 'loose' | 'strict'> = (MarkAsRequired<XCSSValue<TAllowedProperties, TSchema, ''>, TRequiredProperties['requiredProperties']> & XCSSPseudo<TAllowedProperties, TAllowedPseudos, TRequiredProperties, TSchema> & XCSSMediaQuery<TAllowedProperties, TAllowedPseudos, TAllowedMediaQueries, TSchema> & BlockedRules<TMode>) | false | null | undefined;
|
|
117
120
|
/**
|
|
118
121
|
* ## CX
|
|
119
122
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/xcss-prop/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/xcss-prop/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAsLhC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG,CAChB,GAAG,MAAe,EACD,EAAE;IACnB,2EAA2E;IAC3E,sDAAsD;IACtD,MAAM,YAAY,GAAG,MAA6B,CAAC;IAEnD,+EAA+E;IAC/E,kFAAkF;IAClF,OAAO,EAAE,CAAC,YAAY,CAAoB,CAAC;AAC7C,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -6,29 +6,29 @@ type ColorPressed = 'var(--ds-text-pressed)';
|
|
|
6
6
|
type Background = 'var(--ds-bold)' | 'var(--ds-success)';
|
|
7
7
|
type BackgroundHovered = 'var(--ds-bold-hovered)' | 'var(--ds-success-hovered)';
|
|
8
8
|
type BackgroundPressed = 'var(--ds-bold-pressed)' | 'var(--ds-success-pressed)';
|
|
9
|
+
type Space = 'var(--ds-space-050)' | 'var(--ds-space-0)';
|
|
9
10
|
|
|
10
11
|
interface Properties {
|
|
11
12
|
color: Color;
|
|
12
13
|
backgroundColor: Background;
|
|
14
|
+
padding: Space;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
interface HoveredProperties
|
|
17
|
+
interface HoveredProperties {
|
|
16
18
|
color: ColorHovered;
|
|
17
19
|
backgroundColor: BackgroundHovered;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
interface PressedProperties
|
|
22
|
+
interface PressedProperties {
|
|
21
23
|
color: ColorPressed;
|
|
22
24
|
backgroundColor: BackgroundPressed;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
interface
|
|
27
|
+
interface CSSPropertiesSchema extends Properties {
|
|
26
28
|
'&:hover': HoveredProperties;
|
|
27
29
|
'&:active': PressedProperties;
|
|
28
|
-
'&::before': Properties;
|
|
29
|
-
'&::after': Properties;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
const { css,
|
|
32
|
+
const { css, cssMap, cx, XCSSProp } = createStrictAPI<CSSPropertiesSchema>();
|
|
33
33
|
|
|
34
34
|
export { css, XCSSProp, cssMap, cx };
|
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import { createStrictAPI } from '../../index';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
interface CSSPropertiesSchema {
|
|
4
4
|
'&:hover': {
|
|
5
5
|
color: 'var(--ds-text-hover)';
|
|
6
6
|
background: 'var(--ds-surface-hover)' | 'var(--ds-surface-sunken-hover)';
|
|
7
7
|
};
|
|
8
|
-
color: 'var(--ds-text)';
|
|
8
|
+
color: 'var(--ds-text)' | 'var(--ds-text-bold)';
|
|
9
9
|
background: 'var(--ds-surface)' | 'var(--ds-surface-sunken)';
|
|
10
10
|
bkgrnd: 'red' | 'green';
|
|
11
|
-
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type MediaQuery =
|
|
14
|
+
| '(min-width: 30rem)'
|
|
15
|
+
| '(min-width: 48rem)'
|
|
16
|
+
| '(min-width: 64rem)'
|
|
17
|
+
| '(min-width: 90rem)'
|
|
18
|
+
| '(min-width: 110rem)'
|
|
19
|
+
| '(prefers-color-scheme: dark)'
|
|
20
|
+
| '(prefers-color-scheme: light)';
|
|
21
|
+
|
|
22
|
+
const { css, XCSSProp, cssMap, cx } = createStrictAPI<CSSPropertiesSchema, { media: MediaQuery }>();
|
|
12
23
|
|
|
13
24
|
export { css, XCSSProp, cssMap, cx };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** @jsxImportSource @compiled/react */
|
|
2
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
3
|
+
import { css } from '@compiled/react';
|
|
4
|
+
import type { XCSSProp } from '@fixture/strict-api-test';
|
|
5
|
+
import { css as strictCSS } from '@fixture/strict-api-test';
|
|
6
|
+
import { render } from '@testing-library/react';
|
|
7
|
+
|
|
8
|
+
function Button({
|
|
9
|
+
xcss,
|
|
10
|
+
testId,
|
|
11
|
+
}: {
|
|
12
|
+
testId: string;
|
|
13
|
+
xcss: ReturnType<typeof XCSSProp<'backgroundColor', '&:hover'>>;
|
|
14
|
+
}) {
|
|
15
|
+
return <button data-testid={testId} className={xcss} />;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe('css func from strict api', () => {
|
|
19
|
+
it('should type error when passing css func result into xcss prop', () => {
|
|
20
|
+
const strictStyles = strictCSS({
|
|
21
|
+
backgroundColor: 'var(--ds-surface)',
|
|
22
|
+
});
|
|
23
|
+
const looseStyles = css({
|
|
24
|
+
backgroundColor: 'red',
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const { getByTestId } = render(
|
|
28
|
+
<>
|
|
29
|
+
<Button
|
|
30
|
+
testId="button-1"
|
|
31
|
+
// @ts-expect-error — CSS func currently doesn't work with XCSS prop so should type error
|
|
32
|
+
xcss={strictStyles}
|
|
33
|
+
/>
|
|
34
|
+
<Button
|
|
35
|
+
testId="button-2"
|
|
36
|
+
// @ts-expect-error — CSS func currently doesn't work with XCSS prop so should type error
|
|
37
|
+
xcss={looseStyles}
|
|
38
|
+
/>
|
|
39
|
+
<div data-testid="div-1" css={[strictStyles, looseStyles]} />
|
|
40
|
+
<div data-testid="div-2" css={[looseStyles, strictStyles]} />
|
|
41
|
+
</>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
expect(getByTestId('button-1').className).toEqual('');
|
|
45
|
+
expect(getByTestId('button-2').className).toEqual('');
|
|
46
|
+
expect(getByTestId('div-1')).toHaveCompiledCss('background-color', 'red');
|
|
47
|
+
expect(getByTestId('div-2')).toHaveCompiledCss('background-color', 'var(--ds-surface)');
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -99,7 +99,7 @@ describe('createStrictAPI()', () => {
|
|
|
99
99
|
const styles = cssMap({
|
|
100
100
|
primary: {
|
|
101
101
|
// @ts-expect-error — Type '""' is not assignable to type ...
|
|
102
|
-
color: '
|
|
102
|
+
color: '',
|
|
103
103
|
// @ts-expect-error — Type '""' is not assignable to type ...
|
|
104
104
|
backgroundColor: '',
|
|
105
105
|
'&:hover': {
|
|
@@ -155,15 +155,15 @@ describe('createStrictAPI()', () => {
|
|
|
155
155
|
backgroundColor: '',
|
|
156
156
|
'&:hover': {
|
|
157
157
|
// @ts-expect-error — Type '""' is not assignable to type ...
|
|
158
|
-
color: '',
|
|
158
|
+
color: 'var(--ds-text)',
|
|
159
159
|
// @ts-expect-error — Type '""' is not assignable to type ...
|
|
160
|
-
backgroundColor: '',
|
|
160
|
+
backgroundColor: 'var(--ds-success)',
|
|
161
161
|
},
|
|
162
162
|
'&:active': {
|
|
163
163
|
// @ts-expect-error — Type '""' is not assignable to type ...
|
|
164
|
-
color: '',
|
|
164
|
+
color: 'var(--ds-text)',
|
|
165
165
|
// @ts-expect-error — Type '""' is not assignable to type ...
|
|
166
|
-
backgroundColor: '',
|
|
166
|
+
backgroundColor: 'var(--ds-success)',
|
|
167
167
|
},
|
|
168
168
|
'&::before': {
|
|
169
169
|
// @ts-expect-error — Type '""' is not assignable to type ...
|
|
@@ -188,21 +188,31 @@ describe('createStrictAPI()', () => {
|
|
|
188
188
|
describe('type success', () => {
|
|
189
189
|
it('should pass type check for css()', () => {
|
|
190
190
|
const styles = css({
|
|
191
|
+
// @ts-expect-error — should be a value from the schema
|
|
192
|
+
padding: '10px',
|
|
191
193
|
color: 'var(--ds-text)',
|
|
192
194
|
backgroundColor: 'var(--ds-bold)',
|
|
193
195
|
'&:hover': {
|
|
196
|
+
// @ts-expect-error — should be a value from the schema
|
|
197
|
+
padding: '10px',
|
|
194
198
|
color: 'var(--ds-text-hovered)',
|
|
195
199
|
backgroundColor: 'var(--ds-bold-hovered)',
|
|
196
200
|
},
|
|
197
201
|
'&:active': {
|
|
202
|
+
// @ts-expect-error — should be a value from the schema
|
|
203
|
+
padding: '10px',
|
|
198
204
|
color: 'var(--ds-text-pressed)',
|
|
199
205
|
backgroundColor: 'var(--ds-bold-pressed)',
|
|
200
206
|
},
|
|
201
207
|
'&::before': {
|
|
208
|
+
// @ts-expect-error — should be a value from the schema
|
|
209
|
+
padding: '10px',
|
|
202
210
|
color: 'var(--ds-text)',
|
|
203
211
|
backgroundColor: 'var(--ds-bold)',
|
|
204
212
|
},
|
|
205
213
|
'&::after': {
|
|
214
|
+
// @ts-expect-error — should be a value from the schema
|
|
215
|
+
padding: '10px',
|
|
206
216
|
color: 'var(--ds-text)',
|
|
207
217
|
backgroundColor: 'var(--ds-bold)',
|
|
208
218
|
},
|
|
@@ -218,19 +228,30 @@ describe('createStrictAPI()', () => {
|
|
|
218
228
|
primary: {
|
|
219
229
|
color: 'var(--ds-text)',
|
|
220
230
|
backgroundColor: 'var(--ds-bold)',
|
|
231
|
+
// @ts-expect-error — should be a value from the schema
|
|
232
|
+
padding: '10px',
|
|
221
233
|
'&:hover': {
|
|
234
|
+
accentColor: 'red',
|
|
235
|
+
// @ts-expect-error — should be a value from the schema
|
|
236
|
+
padding: '10px',
|
|
222
237
|
color: 'var(--ds-text-hovered)',
|
|
223
238
|
backgroundColor: 'var(--ds-bold-hovered)',
|
|
224
239
|
},
|
|
225
240
|
'&:active': {
|
|
241
|
+
// @ts-expect-error — should be a value from the schema
|
|
242
|
+
padding: '10px',
|
|
226
243
|
color: 'var(--ds-text-pressed)',
|
|
227
244
|
backgroundColor: 'var(--ds-bold-pressed)',
|
|
228
245
|
},
|
|
229
246
|
'&::before': {
|
|
247
|
+
// @ts-expect-error — should be a value from the schema
|
|
248
|
+
padding: '10px',
|
|
230
249
|
color: 'var(--ds-text)',
|
|
231
250
|
backgroundColor: 'var(--ds-bold)',
|
|
232
251
|
},
|
|
233
252
|
'&::after': {
|
|
253
|
+
// @ts-expect-error — should be a value from the schema
|
|
254
|
+
padding: '10px',
|
|
234
255
|
color: 'var(--ds-text)',
|
|
235
256
|
backgroundColor: 'var(--ds-bold)',
|
|
236
257
|
},
|