@compiled/react 0.16.2 → 0.16.4
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/class-names/index.d.ts +1 -1
- package/dist/browser/create-strict-api/index.d.ts +181 -0
- package/dist/browser/create-strict-api/index.js +65 -0
- package/dist/browser/create-strict-api/index.js.map +1 -0
- package/dist/browser/css/index.d.ts +1 -1
- package/dist/browser/css-map/index.d.ts +3 -5
- package/dist/browser/css-map/index.js +3 -5
- package/dist/browser/css-map/index.js.map +1 -1
- package/dist/browser/index.d.ts +1 -0
- package/dist/browser/index.js +1 -0
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/types.d.ts +7 -2
- package/dist/browser/utils/error.d.ts +1 -0
- package/dist/browser/utils/error.js +19 -0
- package/dist/browser/utils/error.js.map +1 -1
- package/dist/browser/xcss-prop/index.d.ts +14 -10
- package/dist/browser/xcss-prop/index.js +1 -1
- package/dist/browser/xcss-prop/index.js.map +1 -1
- package/dist/cjs/class-names/index.d.ts +1 -1
- package/dist/cjs/create-strict-api/index.d.ts +181 -0
- package/dist/cjs/create-strict-api/index.js +69 -0
- package/dist/cjs/create-strict-api/index.js.map +1 -0
- package/dist/cjs/css/index.d.ts +1 -1
- package/dist/cjs/css-map/index.d.ts +3 -5
- package/dist/cjs/css-map/index.js +3 -5
- package/dist/cjs/css-map/index.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types.d.ts +7 -2
- package/dist/cjs/utils/error.d.ts +1 -0
- package/dist/cjs/utils/error.js +21 -1
- package/dist/cjs/utils/error.js.map +1 -1
- package/dist/cjs/xcss-prop/index.d.ts +14 -10
- package/dist/cjs/xcss-prop/index.js +1 -1
- package/dist/cjs/xcss-prop/index.js.map +1 -1
- package/dist/esm/class-names/index.d.ts +1 -1
- package/dist/esm/create-strict-api/index.d.ts +181 -0
- package/dist/esm/create-strict-api/index.js +65 -0
- package/dist/esm/create-strict-api/index.js.map +1 -0
- package/dist/esm/css/index.d.ts +1 -1
- package/dist/esm/css-map/index.d.ts +3 -5
- package/dist/esm/css-map/index.js +3 -5
- package/dist/esm/css-map/index.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types.d.ts +7 -2
- package/dist/esm/utils/error.d.ts +1 -0
- package/dist/esm/utils/error.js +19 -0
- package/dist/esm/utils/error.js.map +1 -1
- package/dist/esm/xcss-prop/index.d.ts +14 -10
- package/dist/esm/xcss-prop/index.js +1 -1
- package/dist/esm/xcss-prop/index.js.map +1 -1
- package/package.json +2 -1
- package/src/class-names/index.ts +1 -1
- package/src/create-strict-api/__tests__/__fixtures__/strict-api.ts +13 -0
- package/src/create-strict-api/__tests__/index.test.tsx +312 -0
- package/src/create-strict-api/__tests__/package.test.tsx +21 -0
- package/src/create-strict-api/index.ts +223 -0
- package/src/css/index.ts +1 -1
- package/src/css-map/index.ts +3 -5
- package/src/index.ts +1 -0
- package/src/types.ts +8 -2
- package/src/utils/error.ts +20 -0
- package/src/xcss-prop/index.ts +33 -10
package/dist/esm/types.d.ts
CHANGED
|
@@ -20,9 +20,14 @@ export type CssObject<TProps> = Readonly<{
|
|
|
20
20
|
export type CssFunction<TProps = unknown> = CssType<TProps> | BasicTemplateInterpolations | null | boolean | undefined;
|
|
21
21
|
export type CSSPseudos = '&::after' | '&::backdrop' | '&::before' | '&::cue' | '&::cue-region' | '&::first-letter' | '&::first-line' | '&::grammar-error' | '&::marker' | '&::placeholder' | '&::selection' | '&::spelling-error' | '&::target-text' | '&::view-transition' | '&: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';
|
|
22
22
|
/**
|
|
23
|
-
* The
|
|
24
|
-
* if it takes a subset of them. This
|
|
23
|
+
* The XCSSProp must be given all known available properties even
|
|
24
|
+
* if it takes a subset of them. This ensures the (lack-of an)
|
|
25
25
|
* excess property check doesn't enable makers to circumvent the
|
|
26
26
|
* system and pass in values they shouldn't.
|
|
27
27
|
*/
|
|
28
28
|
export type CSSProperties = Readonly<CSS.Properties<string | number>>;
|
|
29
|
+
/**
|
|
30
|
+
* A stricter subset of the {@link CSSProperties} type that excludes
|
|
31
|
+
* vendor and obsolete properties.
|
|
32
|
+
*/
|
|
33
|
+
export type StrictCSSProperties = Readonly<CSS.StandardProperties & CSS.SvgProperties>;
|
package/dist/esm/utils/error.js
CHANGED
|
@@ -17,4 +17,23 @@ export const createSetupError = () => {
|
|
|
17
17
|
Good luck!
|
|
18
18
|
`);
|
|
19
19
|
};
|
|
20
|
+
export const createStrictSetupError = () => {
|
|
21
|
+
return new Error(`
|
|
22
|
+
██████╗ ██████╗ ███╗ ███╗██████╗ ██╗██╗ ███████╗██████╗
|
|
23
|
+
██╔════╝██╔═══██╗████╗ ████║██╔══██╗██║██║ ██╔════╝██╔══██╗
|
|
24
|
+
██║ ██║ ██║██╔████╔██║██████╔╝██║██║ █████╗ ██║ ██║
|
|
25
|
+
██║ ██║ ██║██║╚██╔╝██║██╔═══╝ ██║██║ ██╔══╝ ██║ ██║
|
|
26
|
+
╚██████╗╚██████╔╝██║ ╚═╝ ██║██║ ██║███████╗███████╗██████╔╝
|
|
27
|
+
╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═════╝
|
|
28
|
+
|
|
29
|
+
@compiled/react
|
|
30
|
+
|
|
31
|
+
Code was executed when it shouldn't have. To resolve make sure to:
|
|
32
|
+
|
|
33
|
+
1. Set up Compiled.
|
|
34
|
+
2. Configure importSources in your Compiled config to point to the module that exports the output of createStrictAPI().
|
|
35
|
+
|
|
36
|
+
For more information visit https://compiledcssinjs.com/docs/installation and follow the instructions.
|
|
37
|
+
`);
|
|
38
|
+
};
|
|
20
39
|
//# sourceMappingURL=error.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/utils/error.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAU,EAAE;IAC1C,OAAO,IAAI,KAAK,CAAC;;;;;;;;;;;;;;;;CAgBlB,CAAC,CAAC;AACH,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/utils/error.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAU,EAAE;IAC1C,OAAO,IAAI,KAAK,CAAC;;;;;;;;;;;;;;;;CAgBlB,CAAC,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAU,EAAE;IAChD,OAAO,IAAI,KAAK,CAAC;;;;;;;;;;;;;;;;CAgBlB,CAAC,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import type * as CSS from 'csstype';
|
|
2
2
|
import type { CSSPseudos, CSSProperties } from '../types';
|
|
3
|
-
type
|
|
4
|
-
[
|
|
3
|
+
type MarkAsRequired<T, K extends keyof T> = T & {
|
|
4
|
+
[P in K]-?: T[P];
|
|
5
|
+
};
|
|
6
|
+
type XCSSItem<TStyleDecl extends keyof CSSProperties, TCompiledTypedProperty> = {
|
|
7
|
+
[Q in keyof CSSProperties]: Q extends TStyleDecl ? CompiledPropertyDeclarationReference | (Q extends keyof TCompiledTypedProperty ? TCompiledTypedProperty[Q] : CSSProperties[Q]) : never;
|
|
5
8
|
};
|
|
6
9
|
type XCSSPseudos<TAllowedProperties extends keyof CSSProperties, TAllowedPseudos extends CSSPseudos, TRequiredProperties extends {
|
|
7
10
|
requiredProperties: TAllowedProperties;
|
|
8
|
-
}> = {
|
|
9
|
-
[Q in CSSPseudos]?: Q extends TAllowedPseudos ? MarkAsRequired<XCSSItem<TAllowedProperties>, TRequiredProperties['requiredProperties']> : never;
|
|
11
|
+
}, TCompiledTypedPseudo> = {
|
|
12
|
+
[Q in CSSPseudos]?: Q extends TAllowedPseudos ? MarkAsRequired<XCSSItem<TAllowedProperties, Q extends keyof TCompiledTypedPseudo ? TCompiledTypedPseudo[Q] : object>, TRequiredProperties['requiredProperties']> : never;
|
|
10
13
|
};
|
|
11
14
|
/**
|
|
12
15
|
* These APIs we don't want to allow to be passed through the `xcss` prop but we also
|
|
@@ -47,7 +50,7 @@ export type XCSSAllProperties = keyof CSSProperties;
|
|
|
47
50
|
*/
|
|
48
51
|
export type XCSSAllPseudos = CSSPseudos;
|
|
49
52
|
/**
|
|
50
|
-
* ##
|
|
53
|
+
* ## XCSSProp
|
|
51
54
|
*
|
|
52
55
|
* Declare styles your component takes with all other styles marked as violations
|
|
53
56
|
* by the TypeScript compiler. There are two primary use cases for xcss prop:
|
|
@@ -106,12 +109,13 @@ export type XCSSAllPseudos = CSSPseudos;
|
|
|
106
109
|
export type XCSSProp<TAllowedProperties extends keyof CSSProperties, TAllowedPseudos extends CSSPseudos, TRequiredProperties extends {
|
|
107
110
|
requiredProperties: TAllowedProperties;
|
|
108
111
|
requiredPseudos: TAllowedPseudos;
|
|
109
|
-
} = never> =
|
|
110
|
-
type
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
} = never> = Internal$XCSSProp<TAllowedProperties, TAllowedPseudos, object, object, TRequiredProperties>;
|
|
113
|
+
export type Internal$XCSSProp<TAllowedProperties extends keyof CSSProperties, TAllowedPseudos extends CSSPseudos, TCompiledTypedProperty, TCompiledTypedPseudo, TRequiredProperties extends {
|
|
114
|
+
requiredProperties: TAllowedProperties;
|
|
115
|
+
requiredPseudos: TAllowedPseudos;
|
|
116
|
+
}> = (MarkAsRequired<XCSSItem<TAllowedProperties, TCompiledTypedProperty>, TRequiredProperties['requiredProperties']> & MarkAsRequired<XCSSPseudos<TAllowedProperties, TAllowedPseudos, TRequiredProperties, TCompiledTypedPseudo>, TRequiredProperties['requiredPseudos']> & BlockedRules) | false | null | undefined;
|
|
113
117
|
/**
|
|
114
|
-
* ##
|
|
118
|
+
* ## CX
|
|
115
119
|
*
|
|
116
120
|
* Use in conjunction with the {@link XCSSProp} to concatenate and conditionally apply
|
|
117
121
|
* declared styles. Can only be used with the `cssMap()` and {@link XCSSProp} APIs.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/xcss-prop/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/xcss-prop/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAwKhC;;;;;;;;;;;;;;;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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@compiled/react",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.4",
|
|
4
4
|
"description": "A familiar and performant compile time CSS-in-JS library for React.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"compiled",
|
|
@@ -76,6 +76,7 @@
|
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"@compiled/benchmark": "^1.1.0",
|
|
79
|
+
"@fixture/strict-api-test": "*",
|
|
79
80
|
"@testing-library/react": "^12.1.5",
|
|
80
81
|
"@types/jsdom": "^16.2.15",
|
|
81
82
|
"@types/react-dom": "^17.0.22",
|
package/src/class-names/index.ts
CHANGED
|
@@ -19,7 +19,7 @@ export interface ClassNamesProps<TProps> {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* ## Class
|
|
22
|
+
* ## Class Names
|
|
23
23
|
*
|
|
24
24
|
* Use a component where styles are not necessarily used on a JSX element.
|
|
25
25
|
* For further details [read the documentation](https://compiledcssinjs.com/docs/api-class-names).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createStrictAPI } from '@compiled/react';
|
|
2
|
+
|
|
3
|
+
const { css, XCSSProp, cssMap, cx } = createStrictAPI<{
|
|
4
|
+
'&:hover': {
|
|
5
|
+
color: 'var(--ds-text-hover)';
|
|
6
|
+
background: 'var(--ds-surface-hover)' | 'var(--ds-surface-sunken-hover)';
|
|
7
|
+
};
|
|
8
|
+
color: 'var(--ds-text)';
|
|
9
|
+
background: 'var(--ds-surface)' | 'var(--ds-surface-sunken)';
|
|
10
|
+
bkgrnd: 'red' | 'green';
|
|
11
|
+
}>();
|
|
12
|
+
|
|
13
|
+
export { css, XCSSProp, cssMap, cx };
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/** @jsxImportSource @compiled/react */
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
|
|
4
|
+
import { css, cssMap, XCSSProp } from './__fixtures__/strict-api';
|
|
5
|
+
|
|
6
|
+
describe('createStrictAPI()', () => {
|
|
7
|
+
describe('css()', () => {
|
|
8
|
+
it('should type error when circumventing the excess property check', () => {
|
|
9
|
+
const styles = css({
|
|
10
|
+
color: 'var(--ds-text)',
|
|
11
|
+
accentColor: 'red',
|
|
12
|
+
// @ts-expect-error — Type 'string' is not assignable to type 'undefined'.ts(2322)
|
|
13
|
+
bkgrnd: 'red',
|
|
14
|
+
'&:hover': {
|
|
15
|
+
color: 'var(--ds-text-hover)',
|
|
16
|
+
// @ts-expect-error — Type 'string' is not assignable to type 'undefined'.ts(2322)
|
|
17
|
+
bkgrnd: 'red',
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const { getByTestId } = render(<div css={styles} data-testid="div" />);
|
|
22
|
+
|
|
23
|
+
expect(getByTestId('div')).toHaveCompiledCss('color', 'var(--ds-text)');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should constrain declared types for css() func', () => {
|
|
27
|
+
// @ts-expect-error — Type '"red"' is not assignable to type '"var(--ds-surface)" | "var(--ds-surface-sunken" | undefined'.ts(2322)
|
|
28
|
+
const styles = css({ background: 'red' });
|
|
29
|
+
|
|
30
|
+
const { getByTestId } = render(<div css={styles} data-testid="div" />);
|
|
31
|
+
|
|
32
|
+
expect(getByTestId('div')).toHaveCompiledCss('background-color', 'red');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should mark all properties as optional', () => {
|
|
36
|
+
const styles1 = css({});
|
|
37
|
+
const styles2 = css({ '&:hover': {} });
|
|
38
|
+
|
|
39
|
+
const { getByTestId } = render(<div css={[styles1, styles2]} data-testid="div" />);
|
|
40
|
+
|
|
41
|
+
expect(getByTestId('div')).not.toHaveCompiledCss('color', 'red');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should constrain pseudos', () => {
|
|
45
|
+
const styles = css({
|
|
46
|
+
// @ts-expect-error — Type '"red"' is not assignable to type '"var(--ds-surface)" | "var(--ds-surface-sunken" | undefined'.ts(2322)
|
|
47
|
+
background: 'red',
|
|
48
|
+
'&:hover': {
|
|
49
|
+
// @ts-expect-error — Type '"red"' is not assignable to type '"var(--ds-surface)" | "var(--ds-surface-sunken" | undefined'.ts(2322)
|
|
50
|
+
background: 'red',
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const { getByTestId } = render(<div css={styles} data-testid="div" />);
|
|
55
|
+
|
|
56
|
+
expect(getByTestId('div')).toHaveCompiledCss('background-color', 'red', { target: ':hover' });
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should allow valid properties inside pseudos that are different to root', () => {
|
|
60
|
+
const styles = css({
|
|
61
|
+
background: 'var(--ds-surface)',
|
|
62
|
+
'&:hover': {
|
|
63
|
+
accentColor: 'red',
|
|
64
|
+
background: 'var(--ds-surface-hover)',
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const { getByTestId } = render(<div css={styles} data-testid="div" />);
|
|
69
|
+
|
|
70
|
+
expect(getByTestId('div')).toHaveCompiledCss('background', 'var(--ds-surface-hover)', {
|
|
71
|
+
target: ':hover',
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should allow valid properties', () => {
|
|
76
|
+
const styles = css({
|
|
77
|
+
background: 'var(--ds-surface)',
|
|
78
|
+
accentColor: 'red',
|
|
79
|
+
color: 'var(--ds-text)',
|
|
80
|
+
all: 'inherit',
|
|
81
|
+
'&:hover': { color: 'var(--ds-text-hover)' },
|
|
82
|
+
'&:invalid': { color: 'orange' },
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const { getByTestId } = render(<div css={styles} data-testid="div" />);
|
|
86
|
+
|
|
87
|
+
expect(getByTestId('div')).toHaveCompiledCss('all', 'inherit');
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe('cssMap()', () => {
|
|
92
|
+
it('should allow valid properties', () => {
|
|
93
|
+
const styles = cssMap({
|
|
94
|
+
primary: {
|
|
95
|
+
background: 'var(--ds-surface)',
|
|
96
|
+
accentColor: 'red',
|
|
97
|
+
all: 'inherit',
|
|
98
|
+
'&:hover': { color: 'var(--ds-text-hover)' },
|
|
99
|
+
'&:invalid': { color: 'orange' },
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const { getByTestId } = render(<div css={styles.primary} data-testid="div" />);
|
|
104
|
+
|
|
105
|
+
expect(getByTestId('div')).toHaveCompiledCss('background', 'var(--ds-surface)');
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should allow valid properties inside pseudos that are different to root', () => {
|
|
109
|
+
const styles = cssMap({
|
|
110
|
+
primary: {
|
|
111
|
+
background: 'var(--ds-surface)',
|
|
112
|
+
'&:hover': {
|
|
113
|
+
accentColor: 'red',
|
|
114
|
+
background: 'var(--ds-surface-hover)',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const { getByTestId } = render(<div css={styles.primary} data-testid="div" />);
|
|
120
|
+
|
|
121
|
+
expect(getByTestId('div')).toHaveCompiledCss('background', 'var(--ds-surface-hover)', {
|
|
122
|
+
target: ':hover',
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should type error invalid vales', () => {
|
|
127
|
+
const styles = cssMap({
|
|
128
|
+
primary: {
|
|
129
|
+
// @ts-expect-error — Type '{ val: string; }' is not assignable to type 'Readonly<Properties<string | number, string & {}>> & PseudosDeclarations & EnforceSchema<{ background: "var(--ds-surface)" | "var(--ds-surface-sunken"; }>'.
|
|
130
|
+
val: 'ok',
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const { getByTestId } = render(<div css={styles.primary} data-testid="div" />);
|
|
135
|
+
|
|
136
|
+
expect(getByTestId('div')).toHaveCompiledCss('val', 'ok');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('should type error invalid values in pseudos', () => {
|
|
140
|
+
const styles = cssMap({
|
|
141
|
+
primary: {
|
|
142
|
+
// @ts-expect-error — Type '"red"' is not assignable to type '"var(--ds-surface)" | "var(--ds-surface-sunken" | undefined'.ts(2322)
|
|
143
|
+
background: 'red',
|
|
144
|
+
'&:hover': {
|
|
145
|
+
// @ts-expect-error — Type 'string' is not assignable to type 'never'.ts(2322)
|
|
146
|
+
val: 'ok',
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const { getByTestId } = render(<div css={styles.primary} data-testid="div" />);
|
|
152
|
+
|
|
153
|
+
expect(getByTestId('div')).toHaveCompiledCss('val', 'ok', { target: ':hover' });
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
describe('XCSSProp', () => {
|
|
158
|
+
it('should allow valid values', () => {
|
|
159
|
+
function Button({ xcss }: { xcss: ReturnType<typeof XCSSProp<'background', never>> }) {
|
|
160
|
+
return <button data-testid="button" className={xcss} />;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const { getByTestId } = render(<Button xcss={{ background: 'var(--ds-surface)' }} />);
|
|
164
|
+
|
|
165
|
+
expect(getByTestId('button')).toHaveCompiledCss('background', 'var(--ds-surface)');
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should type error for invalid known values', () => {
|
|
169
|
+
function Button({ xcss }: { xcss: ReturnType<typeof XCSSProp<'background', never>> }) {
|
|
170
|
+
return <button data-testid="button" className={xcss} />;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const { getByTestId } = render(
|
|
174
|
+
<Button
|
|
175
|
+
xcss={{
|
|
176
|
+
// @ts-expect-error — Type '"red"' is not assignable to type '"var(--ds-surface)" | "var(--ds-surface-sunken" | CompiledPropertyDeclarationReference | undefined'.ts(2322)
|
|
177
|
+
background: 'red',
|
|
178
|
+
// @ts-expect-error — Type '{ background: string; }' is not assignable to type 'undefined'.ts(2322)
|
|
179
|
+
'&::after': {
|
|
180
|
+
background: 'red',
|
|
181
|
+
},
|
|
182
|
+
}}
|
|
183
|
+
/>
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
expect(getByTestId('button')).toHaveCompiledCss('background-color', 'red');
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('should type error for invalid unknown values', () => {
|
|
190
|
+
function Button({ xcss }: { xcss: ReturnType<typeof XCSSProp<'background', never>> }) {
|
|
191
|
+
return <button data-testid="button" className={xcss} />;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const { getByTestId } = render(
|
|
195
|
+
<Button
|
|
196
|
+
xcss={{
|
|
197
|
+
// @ts-expect-error — Type '{ asd: number; }' is not assignable to type 'Internal$XCSSProp<"background", never, { background: "var(--ds-surface)" | "var(--ds-surface-sunken"; }, PickObjects<{ background: "var(--ds-surface)" | "var(--ds-surface-sunken"; }>, never>'.
|
|
198
|
+
asd: 0,
|
|
199
|
+
}}
|
|
200
|
+
/>
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
expect(getByTestId('button')).toHaveCompiledCss('asd', '0');
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('should type error for unsupported known pseudos', () => {
|
|
207
|
+
function Button({ xcss }: { xcss: ReturnType<typeof XCSSProp<'background', never>> }) {
|
|
208
|
+
return <button data-testid="button" className={xcss} />;
|
|
209
|
+
}
|
|
210
|
+
const { getByTestId } = render(
|
|
211
|
+
<Button
|
|
212
|
+
xcss={{
|
|
213
|
+
// @ts-expect-error — Object literal may only specify known properties, and '':hover'' does not exist in type
|
|
214
|
+
':hover': {
|
|
215
|
+
color: 'red',
|
|
216
|
+
},
|
|
217
|
+
}}
|
|
218
|
+
/>
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
expect(getByTestId('button')).toHaveCompiledCss('color', 'red', { target: ':hover' });
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('should type error for unsupported unknown pseudos', () => {
|
|
225
|
+
function Button({ xcss }: { xcss: ReturnType<typeof XCSSProp<'background', never>> }) {
|
|
226
|
+
return <button data-testid="button" className={xcss} />;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const { getByTestId } = render(
|
|
230
|
+
<Button
|
|
231
|
+
xcss={{
|
|
232
|
+
// @ts-expect-error — Object literal may only specify known properties, and '':hover'' does not exist in type
|
|
233
|
+
':asd': {
|
|
234
|
+
color: 'red',
|
|
235
|
+
},
|
|
236
|
+
}}
|
|
237
|
+
/>
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
expect(getByTestId('button')).toHaveCompiledCss('color', 'red', { target: ':asd' });
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('should type error for invalid known values in pseudos', () => {
|
|
244
|
+
function Button({ xcss }: { xcss: ReturnType<typeof XCSSProp<'color', '&:hover'>> }) {
|
|
245
|
+
return <button data-testid="button" className={xcss} />;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const { getByTestId } = render(
|
|
249
|
+
<Button
|
|
250
|
+
xcss={{
|
|
251
|
+
'&:hover': {
|
|
252
|
+
// @ts-expect-error — Type '"red"' is not assignable to type 'CompiledPropertyDeclarationReference | "var(--ds-text)" | undefined'.ts(2322)
|
|
253
|
+
color: 'red',
|
|
254
|
+
},
|
|
255
|
+
}}
|
|
256
|
+
/>
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
expect(getByTestId('button')).toHaveCompiledCss('color', 'red', { target: ':hover' });
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it('should type error for invalid unknown values in pseudos', () => {
|
|
263
|
+
function Button({ xcss }: { xcss: ReturnType<typeof XCSSProp<'color', '&:hover'>> }) {
|
|
264
|
+
return <button data-testid="button" className={xcss} />;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const { getByTestId } = render(
|
|
268
|
+
<Button
|
|
269
|
+
xcss={{
|
|
270
|
+
'&:hover': {
|
|
271
|
+
// @ts-expect-error — Type '{ asd: string; }' is not assignable to type 'MarkAsRequired<XCSSItem<"color", { color: "var(--ds-text)"; }>, never>'.
|
|
272
|
+
asd: 'red',
|
|
273
|
+
},
|
|
274
|
+
}}
|
|
275
|
+
/>
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
expect(getByTestId('button')).toHaveCompiledCss('asd', 'red', { target: ':hover' });
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
it('should enforce required properties', () => {
|
|
282
|
+
function Button({
|
|
283
|
+
xcss,
|
|
284
|
+
}: {
|
|
285
|
+
xcss: ReturnType<
|
|
286
|
+
typeof XCSSProp<
|
|
287
|
+
'background',
|
|
288
|
+
never,
|
|
289
|
+
{ requiredProperties: 'background'; requiredPseudos: never }
|
|
290
|
+
>
|
|
291
|
+
>;
|
|
292
|
+
}) {
|
|
293
|
+
return <button data-testid="button" className={xcss} />;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const { getByTestId } = render(
|
|
297
|
+
<Button
|
|
298
|
+
// @ts-expect-error — Type '{}' is not assignable to type 'Internal$XCSSProp<"background", never, EnforceSchema<{ background: "var(--ds-surface)" | "var(--ds-surface-sunken"; }>, object, { requiredProperties: "background"; requiredPseudos: never; }>'.ts(2322)
|
|
299
|
+
xcss={{}}
|
|
300
|
+
/>
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
expect(getByTestId('button')).not.toHaveCompiledCss('color', 'red');
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it('should throw when calling XCSSProp directly', () => {
|
|
308
|
+
expect(() => {
|
|
309
|
+
XCSSProp();
|
|
310
|
+
}).toThrow();
|
|
311
|
+
});
|
|
312
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** @jsxImportSource @compiled/react */
|
|
2
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
3
|
+
import { css } from '@fixture/strict-api-test';
|
|
4
|
+
import { render } from '@testing-library/react';
|
|
5
|
+
|
|
6
|
+
describe('createStrictAPI()', () => {
|
|
7
|
+
describe('css()', () => {
|
|
8
|
+
it('should type error when circumventing the excess property check', () => {
|
|
9
|
+
const styles = css({
|
|
10
|
+
color: 'var(--ds-text)',
|
|
11
|
+
'&:hover': {
|
|
12
|
+
color: 'var(--ds-text-hover)',
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const { getByTestId } = render(<div css={styles} data-testid="div" />);
|
|
17
|
+
|
|
18
|
+
expect(getByTestId('div')).toHaveCompiledCss('color', 'var(--ds-text)');
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
});
|