@compiled/react 0.16.10 → 0.17.1

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.
Files changed (63) hide show
  1. package/dist/browser/create-strict-api/index.d.ts +19 -22
  2. package/dist/browser/create-strict-api/index.js +6 -4
  3. package/dist/browser/create-strict-api/index.js.map +1 -1
  4. package/dist/browser/create-strict-api/types.d.ts +28 -0
  5. package/dist/browser/create-strict-api/types.js +2 -0
  6. package/dist/browser/create-strict-api/types.js.map +1 -0
  7. package/dist/browser/css/index.d.ts +2 -0
  8. package/dist/browser/css/index.js.map +1 -1
  9. package/dist/browser/css-map/index.d.ts +15 -2
  10. package/dist/browser/css-map/index.js.map +1 -1
  11. package/dist/browser/index.d.ts +3 -2
  12. package/dist/browser/index.js +1 -1
  13. package/dist/browser/index.js.map +1 -1
  14. package/dist/browser/types.d.ts +4 -2
  15. package/dist/browser/xcss-prop/index.d.ts +17 -14
  16. package/dist/browser/xcss-prop/index.js.map +1 -1
  17. package/dist/cjs/create-strict-api/index.d.ts +19 -22
  18. package/dist/cjs/create-strict-api/index.js +6 -4
  19. package/dist/cjs/create-strict-api/index.js.map +1 -1
  20. package/dist/cjs/create-strict-api/types.d.ts +28 -0
  21. package/dist/cjs/create-strict-api/types.js +3 -0
  22. package/dist/cjs/create-strict-api/types.js.map +1 -0
  23. package/dist/cjs/css/index.d.ts +2 -0
  24. package/dist/cjs/css/index.js.map +1 -1
  25. package/dist/cjs/css-map/index.d.ts +15 -2
  26. package/dist/cjs/css-map/index.js.map +1 -1
  27. package/dist/cjs/index.d.ts +3 -2
  28. package/dist/cjs/index.js.map +1 -1
  29. package/dist/cjs/types.d.ts +4 -2
  30. package/dist/cjs/xcss-prop/index.d.ts +17 -14
  31. package/dist/cjs/xcss-prop/index.js.map +1 -1
  32. package/dist/esm/create-strict-api/index.d.ts +19 -22
  33. package/dist/esm/create-strict-api/index.js +6 -4
  34. package/dist/esm/create-strict-api/index.js.map +1 -1
  35. package/dist/esm/create-strict-api/types.d.ts +28 -0
  36. package/dist/esm/create-strict-api/types.js +2 -0
  37. package/dist/esm/create-strict-api/types.js.map +1 -0
  38. package/dist/esm/css/index.d.ts +2 -0
  39. package/dist/esm/css/index.js.map +1 -1
  40. package/dist/esm/css-map/index.d.ts +15 -2
  41. package/dist/esm/css-map/index.js.map +1 -1
  42. package/dist/esm/index.d.ts +3 -2
  43. package/dist/esm/index.js +1 -1
  44. package/dist/esm/index.js.map +1 -1
  45. package/dist/esm/types.d.ts +4 -2
  46. package/dist/esm/xcss-prop/index.d.ts +17 -14
  47. package/dist/esm/xcss-prop/index.js.map +1 -1
  48. package/package.json +1 -1
  49. package/src/create-strict-api/__tests__/__fixtures__/strict-api-recursive.ts +6 -6
  50. package/src/create-strict-api/__tests__/__fixtures__/strict-api.ts +14 -3
  51. package/src/create-strict-api/__tests__/css-func.test.tsx +49 -0
  52. package/src/create-strict-api/__tests__/generics.test.tsx +26 -5
  53. package/src/create-strict-api/__tests__/index.test.tsx +198 -32
  54. package/src/create-strict-api/index.ts +41 -34
  55. package/src/create-strict-api/types.ts +69 -0
  56. package/src/css/index.ts +2 -0
  57. package/src/css-map/index.ts +20 -2
  58. package/src/index.ts +16 -2
  59. package/src/types.ts +14 -10
  60. package/src/xcss-prop/__tests__/media-query-strict.test.tsx +179 -0
  61. package/src/xcss-prop/__tests__/media-query.test.tsx +53 -0
  62. package/src/xcss-prop/__tests__/xcss-prop.test.tsx +3 -34
  63. package/src/xcss-prop/index.ts +47 -28
@@ -83,6 +83,21 @@ type ExtendedSelectors = {
83
83
  selectors?: ExtendedSelector;
84
84
  };
85
85
 
86
+ type LooseMediaQueries = Record<`@media ${string}`, CSSProperties & AllPseudos>;
87
+
88
+ /**
89
+ * We remap media query keys to `"@media"` so it's blocked inside the strict APIs.
90
+ * This is done as it's currently impossible to ensure type safety end-to-end — when
91
+ * passing in unknown media queries from the loose API into the strict API you end up
92
+ * being also able to pass any styles you want, which makes the whole point of the strict
93
+ * API meaningless.
94
+ *
95
+ * Sorry folks!
96
+ */
97
+ type RemapMedia<TStyles> = {
98
+ [Q in keyof TStyles as Q extends `@media ${string}` ? '@media [loose]' : Q]: TStyles[Q];
99
+ };
100
+
86
101
  /**
87
102
  * ## CSS Map
88
103
  *
@@ -100,11 +115,14 @@ type ExtendedSelectors = {
100
115
  * ```
101
116
  */
102
117
  export default function cssMap<
103
- TStyles extends Record<string, CSSProperties & WhitelistedSelector & ExtendedSelectors>
118
+ TStyles extends Record<
119
+ string,
120
+ CSSProperties & WhitelistedSelector & ExtendedSelectors & LooseMediaQueries
121
+ >
104
122
  >(
105
123
  _styles: TStyles
106
124
  ): {
107
- readonly [P in keyof TStyles]: CompiledStyles<TStyles[P]>;
125
+ readonly [P in keyof TStyles]: CompiledStyles<RemapMedia<TStyles[P]>>;
108
126
  } {
109
127
  throw createSetupError();
110
128
  }
package/src/index.ts CHANGED
@@ -4,10 +4,17 @@ import type { CompiledJSX } from './jsx/jsx-local-namespace';
4
4
 
5
5
  export { ClassNames } from './class-names';
6
6
  export { createStrictAPI } from './create-strict-api';
7
+ export type {
8
+ PseudosDeclarations,
9
+ MediaQueries,
10
+ AllowedStyles,
11
+ ApplySchema,
12
+ ApplySchemaMap,
13
+ } from './create-strict-api/types';
7
14
  export { default as css } from './css';
8
15
  export { default as cssMap } from './css-map';
9
16
  export { keyframes } from './keyframes';
10
- export { styled } from './styled';
17
+ export { styled, StyledProps } from './styled';
11
18
  export type {
12
19
  CSSProperties,
13
20
  CSSProps,
@@ -16,7 +23,14 @@ export type {
16
23
  CssType,
17
24
  StrictCSSProperties,
18
25
  } from './types';
19
- export { type XCSSAllProperties, type XCSSAllPseudos, type XCSSProp, cx } from './xcss-prop';
26
+ export {
27
+ type XCSSAllProperties,
28
+ type XCSSAllPseudos,
29
+ type XCSSProp,
30
+ type CompiledStyles,
31
+ type Internal$XCSSProp,
32
+ cx,
33
+ } from './xcss-prop';
20
34
 
21
35
  // Pass through the (classic) jsx runtime.
22
36
  // Compiled currently doesn't define its own and uses this purely to enable a local jsx namespace.
package/src/types.ts CHANGED
@@ -35,14 +35,7 @@ export type CssFunction<TProps = unknown> =
35
35
  | boolean // Something like `false && styles`
36
36
  | undefined; // Something like `undefined && styles`
37
37
 
38
- /*
39
- * This list of pseudo-classes and pseudo-elements are from csstype
40
- * but with & added to the front. Compiled supports both &-ful
41
- * and &-less forms and both will target the current element
42
- * (`&:hover` <==> `:hover`), however we force the use of the
43
- * &-ful form for consistency with the nested spec for new APIs.
44
- */
45
- export type CSSPseudos =
38
+ export type CSSPseudoElements =
46
39
  | '&::after'
47
40
  | '&::backdrop'
48
41
  | '&::before'
@@ -56,7 +49,9 @@ export type CSSPseudos =
56
49
  | '&::selection'
57
50
  | '&::spelling-error'
58
51
  | '&::target-text'
59
- | '&::view-transition'
52
+ | '&::view-transition';
53
+
54
+ export type CSSPseudoClasses =
60
55
  | '&:active'
61
56
  | '&:autofill'
62
57
  | '&:blank'
@@ -94,13 +89,22 @@ export type CSSPseudos =
94
89
  | '&:valid'
95
90
  | '&:visited';
96
91
 
92
+ /*
93
+ * This list of pseudo-classes and pseudo-elements are from csstype
94
+ * but with & added to the front. Compiled supports both &-ful
95
+ * and &-less forms and both will target the current element
96
+ * (`&:hover` <==> `:hover`), however we force the use of the
97
+ * &-ful form for consistency with the nested spec for new APIs.
98
+ */
99
+ export type CSSPseudos = CSSPseudoElements | CSSPseudoClasses;
100
+
97
101
  /**
98
102
  * The XCSSProp must be given all known available properties even
99
103
  * if it takes a subset of them. This ensures the (lack-of an)
100
104
  * excess property check doesn't enable makers to circumvent the
101
105
  * system and pass in values they shouldn't.
102
106
  */
103
- export type CSSProperties = Readonly<CSS.Properties<string | number>>;
107
+ export type CSSProperties = Readonly<CSS.Properties<(string & object) | number>>;
104
108
 
105
109
  /**
106
110
  * A stricter subset of the {@link CSSProperties} type that excludes
@@ -0,0 +1,179 @@
1
+ /** @jsxImportSource @compiled/react */
2
+ // eslint-disable-next-line import/no-extraneous-dependencies
3
+ import { cssMap as cssMapLoose } from '@compiled/react';
4
+ import { render } from '@testing-library/react';
5
+
6
+ import { cssMap } from '../../create-strict-api/__tests__/__fixtures__/strict-api';
7
+ import type { XCSSProp } from '../../create-strict-api/__tests__/__fixtures__/strict-api';
8
+ import type { XCSSAllProperties, XCSSAllPseudos } from '../index';
9
+
10
+ function CSSPropComponent({
11
+ testId,
12
+ xcss,
13
+ }: {
14
+ testId?: string;
15
+ xcss: ReturnType<typeof XCSSProp<XCSSAllProperties, XCSSAllPseudos>>;
16
+ }) {
17
+ return (
18
+ <div data-testid={testId} className={xcss}>
19
+ foo
20
+ </div>
21
+ );
22
+ }
23
+
24
+ const styles = cssMap({
25
+ invalidMediaObject: {
26
+ // @ts-expect-error — @media at rule object is not allowed in strict cssMap
27
+ '@media': {
28
+ screen: { color: 'red' },
29
+ },
30
+ },
31
+ invalidMediaQuery: {
32
+ // @ts-expect-error — this specific @media is not in our allowed types
33
+ '@media (min-width: 100px)': {
34
+ color: 'red',
35
+ },
36
+ },
37
+ valid: {
38
+ '@media (min-width: 110rem)': {
39
+ // @ts-expect-error — color should be a value from the strict schema
40
+ color: 'red',
41
+ },
42
+ },
43
+ });
44
+
45
+ const looseStyles = cssMapLoose({
46
+ invalidMediaObject: {
47
+ '@media': {
48
+ screen: { color: 'var(--ds-text)' },
49
+ },
50
+ },
51
+ invalidMediaQuery: {
52
+ '@media (min-width: 100px)': {
53
+ color: 'red',
54
+ },
55
+ },
56
+ validMediaQueryInvalidProperty: {
57
+ '@media (min-width: 110rem)': {
58
+ color: 'red',
59
+ },
60
+ },
61
+ valid: {
62
+ '@media (min-width: 110rem)': {
63
+ color: 'var(--ds-text)',
64
+ },
65
+ },
66
+ });
67
+
68
+ describe('xcss prop', () => {
69
+ it('should block all usage of loose media queries in strict api as it is unsafe', () => {
70
+ const { getByText } = render(
71
+ <CSSPropComponent
72
+ // @ts-expect-error — Block all media queries in strict xcss prop
73
+ xcss={looseStyles.valid}
74
+ />
75
+ );
76
+
77
+ expect(getByText('foo')).toHaveCompiledCss('color', 'var(--ds-text)', {
78
+ media: '(min-width: 110rem)',
79
+ });
80
+ });
81
+
82
+ it('should type error invalid media queries from loose api', () => {
83
+ const { getByTestId } = render(
84
+ <>
85
+ <CSSPropComponent
86
+ // @ts-expect-error — Types of property '"@media"' are incompatible.
87
+ xcss={looseStyles.invalidMediaObject}
88
+ />
89
+ <CSSPropComponent testId="foobar" xcss={styles.invalidMediaObject} />
90
+ </>
91
+ );
92
+
93
+ expect(getByTestId('foobar')).toHaveCompiledCss('color', 'red', { media: 'screen' });
94
+ });
95
+
96
+ it('should allow valid media queries in inline xcss prop', () => {
97
+ const { getByText } = render(
98
+ <CSSPropComponent
99
+ xcss={{
100
+ '@media (min-width: 110rem)': {
101
+ color: 'var(--ds-text)',
102
+ },
103
+ }}
104
+ />
105
+ );
106
+
107
+ expect(getByText('foo')).toHaveCompiledCss('color', 'var(--ds-text)', {
108
+ media: '(min-width: 110rem)',
109
+ });
110
+ });
111
+
112
+ it('should allow valid media queries in inline xcss prop', () => {
113
+ const { getByText } = render(
114
+ <CSSPropComponent
115
+ xcss={{
116
+ '@media (min-width: 110rem)': {
117
+ // @ts-expect-error — color should be a value from the strict schema
118
+ color: 'red',
119
+ },
120
+ }}
121
+ />
122
+ );
123
+
124
+ expect(getByText('foo')).toHaveCompiledCss('color', 'red', { media: '(min-width: 110rem)' });
125
+ });
126
+
127
+ it('should allow valid psuedo through inline xcss prop', () => {
128
+ const { getByText } = render(
129
+ <CSSPropComponent
130
+ xcss={{ '@media (min-width: 30rem)': { '&:hover': { color: 'var(--ds-text-hover)' } } }}
131
+ />
132
+ );
133
+
134
+ expect(getByText('foo')).toHaveCompiledCss('color', 'var(--ds-text-hover)', {
135
+ media: '(min-width: 30rem)',
136
+ target: ':hover',
137
+ });
138
+ });
139
+
140
+ it('should type error for unexpected media query', () => {
141
+ const { getByTestId } = render(
142
+ <>
143
+ <CSSPropComponent
144
+ // NOTE: This doesn't currently error as the output isn't the generic value
145
+ // when the cssMap call has type supressions. While not ideal this is acceptable
146
+ // for now. Hopefully we can fix this in the future.
147
+ xcss={styles.invalidMediaQuery}
148
+ />
149
+ <CSSPropComponent
150
+ // @ts-expect-error — Passing loose media queries to XCSS prop is not supported.
151
+ xcss={looseStyles.invalidMediaQuery}
152
+ />
153
+ <CSSPropComponent
154
+ // @ts-expect-error — Passing loose media queries to XCSS prop is not supported.
155
+ xcss={looseStyles.validMediaQueryInvalidProperty}
156
+ />
157
+ <CSSPropComponent
158
+ testId="foobar"
159
+ xcss={{
160
+ // @ts-expect-error — Types of property '"@media"' are incompatible.
161
+ '@media (min-width: 100px)': {
162
+ color: 'var(--ds-text)',
163
+ },
164
+ }}
165
+ />
166
+ </>
167
+ );
168
+
169
+ expect(getByTestId('foobar')).toHaveCompiledCss('color', 'var(--ds-text)', {
170
+ media: '(min-width: 100px)',
171
+ });
172
+ });
173
+
174
+ it('should type check top level media query styles from cssMap', () => {
175
+ const { getByText } = render(<CSSPropComponent xcss={styles.valid} />);
176
+
177
+ expect(getByText('foo')).toHaveCompiledCss('color', 'red', { media: '(min-width: 110rem)' });
178
+ });
179
+ });
@@ -0,0 +1,53 @@
1
+ /** @jsxImportSource @compiled/react */
2
+ // eslint-disable-next-line import/no-extraneous-dependencies
3
+ import { cssMap } from '@compiled/react';
4
+ import { render } from '@testing-library/react';
5
+
6
+ import type { XCSSProp, XCSSAllProperties, XCSSAllPseudos } from '../index';
7
+
8
+ function CSSPropComponent({ xcss }: { xcss: XCSSProp<XCSSAllProperties, XCSSAllPseudos> }) {
9
+ return <div className={xcss}>foo</div>;
10
+ }
11
+
12
+ const styles = cssMap({
13
+ invalid: {
14
+ '@media': { screen: { color: 'red' } },
15
+ },
16
+ valid: { '@media screen': { color: 'red' } },
17
+ });
18
+
19
+ describe('xcss prop', () => {
20
+ it('should allow valid media queries in inline xcss prop', () => {
21
+ const { getByText } = render(<CSSPropComponent xcss={{ '@media screen': { color: 'red' } }} />);
22
+
23
+ expect(getByText('foo')).toHaveCompiledCss('color', 'red', { media: 'screen' });
24
+ });
25
+
26
+ it('should allow valid psuedo through inline xcss prop', () => {
27
+ const { getByText } = render(
28
+ <CSSPropComponent xcss={{ '@media screen': { '&:hover': { color: 'green' } } }} />
29
+ );
30
+
31
+ expect(getByText('foo')).toHaveCompiledCss('color', 'green', {
32
+ media: 'screen',
33
+ target: ':hover',
34
+ });
35
+ });
36
+
37
+ it('should type error for disallowed nested media query object from cssMap', () => {
38
+ const { getByText } = render(
39
+ <CSSPropComponent
40
+ // @ts-expect-error — @media object is not allowed in xcss prop
41
+ xcss={styles.invalid}
42
+ />
43
+ );
44
+
45
+ expect(getByText('foo')).toHaveCompiledCss('color', 'red', { media: 'screen' });
46
+ });
47
+
48
+ it('should type check top level media query styles from cssMap', () => {
49
+ const { getByText } = render(<CSSPropComponent xcss={styles.valid} />);
50
+
51
+ expect(getByText('foo')).toHaveCompiledCss('color', 'red', { media: 'screen' });
52
+ });
53
+ });
@@ -177,7 +177,7 @@ describe('xcss prop', () => {
177
177
  ).toBeObject();
178
178
  });
179
179
 
180
- it('should type error when passing in at rules to xcss prop', () => {
180
+ it('should type error when passing in @media property to xcss prop', () => {
181
181
  function CSSPropComponent({ xcss }: { xcss: XCSSProp<'color', '&:hover'> }) {
182
182
  return <div className={xcss}>foo</div>;
183
183
  }
@@ -228,11 +228,7 @@ describe('xcss prop', () => {
228
228
  function CSSPropComponent({
229
229
  xcss,
230
230
  }: {
231
- xcss: XCSSProp<
232
- 'color' | 'backgroundColor',
233
- '&:hover',
234
- { requiredProperties: 'color'; requiredPseudos: never }
235
- >;
231
+ xcss: XCSSProp<'color' | 'backgroundColor', '&:hover', { requiredProperties: 'color' }>;
236
232
  }) {
237
233
  return <div className={xcss}>foo</div>;
238
234
  }
@@ -249,11 +245,7 @@ describe('xcss prop', () => {
249
245
  function CSSPropComponent({
250
246
  xcss,
251
247
  }: {
252
- xcss: XCSSProp<
253
- 'color' | 'backgroundColor',
254
- '&:hover',
255
- { requiredProperties: 'color'; requiredPseudos: never }
256
- >;
248
+ xcss: XCSSProp<'color' | 'backgroundColor', '&:hover', { requiredProperties: 'color' }>;
257
249
  }) {
258
250
  return <div className={xcss}>foo</div>;
259
251
  }
@@ -268,27 +260,4 @@ describe('xcss prop', () => {
268
260
  />
269
261
  ).toBeObject();
270
262
  });
271
-
272
- it('should mark a xcss prop pseudo as required', () => {
273
- function CSSPropComponent({
274
- xcss,
275
- }: {
276
- xcss: XCSSProp<
277
- 'color' | 'backgroundColor',
278
- '&:hover',
279
- { requiredProperties: never; requiredPseudos: '&:hover' }
280
- >;
281
- }) {
282
- return <div className={xcss}>foo</div>;
283
- }
284
-
285
- expectTypeOf(
286
- <CSSPropComponent
287
- // @ts-expect-error — Property '"&:hover"' is missing in type '{ color: string; }' but required in type '{ "&:hover": MarkAsRequired<XCSSItem<"backgroundColor" | "color">, never>; }'.
288
- xcss={{
289
- color: 'red',
290
- }}
291
- />
292
- ).toBeObject();
293
- });
294
263
  });
@@ -1,44 +1,58 @@
1
1
  import type * as CSS from 'csstype';
2
2
 
3
+ import type { ApplySchemaValue } from '../create-strict-api/types';
3
4
  import { ac } from '../runtime';
4
- import type { CSSPseudos, CSSProperties, StrictCSSProperties } from '../types';
5
+ import type { CSSPseudos, CSSPseudoClasses, CSSProperties, StrictCSSProperties } from '../types';
5
6
 
6
7
  type MarkAsRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
7
8
 
8
- type XCSSItem<TStyleDecl extends keyof CSSProperties, TSchema> = {
9
- [Q in keyof CSSProperties]: Q extends TStyleDecl
10
- ?
11
- | CompiledPropertyDeclarationReference
12
- | (Q extends keyof TSchema ? TSchema[Q] : CSSProperties[Q])
9
+ type XCSSValue<
10
+ TStyleDecl extends keyof CSSProperties,
11
+ TSchema,
12
+ TPseudoKey extends CSSPseudoClasses | ''
13
+ > = {
14
+ [Q in keyof StrictCSSProperties]: Q extends TStyleDecl
15
+ ? ApplySchemaValue<TSchema, Q, TPseudoKey>
13
16
  : never;
14
17
  };
15
18
 
16
- type XCSSPseudos<
17
- TAllowedProperties extends keyof CSSProperties,
19
+ type XCSSPseudo<
20
+ TAllowedProperties extends keyof StrictCSSProperties,
18
21
  TAllowedPseudos extends CSSPseudos,
19
22
  TRequiredProperties extends { requiredProperties: TAllowedProperties },
20
23
  TSchema
21
24
  > = {
22
25
  [Q in CSSPseudos]?: Q extends TAllowedPseudos
23
26
  ? MarkAsRequired<
24
- XCSSItem<TAllowedProperties, Q extends keyof TSchema ? TSchema[Q] : object>,
27
+ XCSSValue<TAllowedProperties, TSchema, Q extends CSSPseudoClasses ? Q : ''>,
25
28
  TRequiredProperties['requiredProperties']
26
29
  >
27
30
  : never;
28
31
  };
29
32
 
33
+ type XCSSMediaQuery<
34
+ TAllowedProperties extends keyof StrictCSSProperties,
35
+ TAllowedPseudos extends CSSPseudos,
36
+ TAllowedMediaQueries extends string,
37
+ TSchema
38
+ > = {
39
+ [Q in `@media ${TAllowedMediaQueries}`]?:
40
+ | XCSSValue<TAllowedProperties, TSchema, ''>
41
+ | XCSSPseudo<TAllowedProperties, TAllowedPseudos, never, TSchema>;
42
+ };
43
+
30
44
  /**
31
45
  * These APIs we don't want to allow to be passed through the `xcss` prop but we also
32
46
  * must declare them so the (lack-of a) excess property check doesn't bite us and allow
33
47
  * unexpected values through.
34
48
  */
35
- type BlockedRules = {
49
+ type BlockedRules<TMode extends 'loose' | 'strict'> = {
50
+ // To ensure styles that aren't allowed through XCSS prop strict APIs we block any
51
+ // loose media queries from being passed through as we can't ensure they're correct.
52
+ '@media [loose]'?: TMode extends 'loose' ? any : never;
36
53
  selectors?: never;
37
54
  } & {
38
- /**
39
- * We currently block all at rules from xcss prop.
40
- * This needs us to decide on what the final API is across Compiled to be able to set.
41
- */
55
+ // We also block all type level at rule "objects" that are present on cssMap.
42
56
  [Q in CSS.AtRules]?: never;
43
57
  };
44
58
 
@@ -54,7 +68,7 @@ type CompiledPropertyDeclarationReference = {
54
68
  export type CompiledStyles<TObject> = {
55
69
  [Q in keyof TObject]: TObject[Q] extends Record<string, unknown>
56
70
  ? CompiledStyles<TObject[Q]>
57
- : CompiledPropertyDeclarationReference;
71
+ : CompiledPropertyDeclarationReference & TObject[Q];
58
72
  };
59
73
 
60
74
  /**
@@ -111,7 +125,7 @@ export type XCSSAllPseudos = CSSPseudos;
111
125
  * xcss?: XCSSProp<XCSSAllProperties, '&:hover'>;
112
126
  *
113
127
  * // The xcss prop is required as well as the color property. No pseudos are required.
114
- * xcss: XCSSProp<XCSSAllProperties, '&:hover', { requiredProperties: 'color', requiredPseudos: never }>;
128
+ * xcss: XCSSProp<XCSSAllProperties, '&:hover', { requiredProperties: 'color' }>;
115
129
  * }
116
130
  *
117
131
  * function MyComponent({ xcss }: MyComponentProps) {
@@ -134,32 +148,37 @@ export type XCSSAllPseudos = CSSPseudos;
134
148
  * To concatenate and conditonally apply styles use the {@link cssMap} {@link cx} functions.
135
149
  */
136
150
  export type XCSSProp<
137
- TAllowedProperties extends keyof CSSProperties,
151
+ TAllowedProperties extends keyof StrictCSSProperties,
138
152
  TAllowedPseudos extends CSSPseudos,
139
153
  TRequiredProperties extends {
140
154
  requiredProperties: TAllowedProperties;
141
- requiredPseudos: TAllowedPseudos;
142
155
  } = never
143
- > = Internal$XCSSProp<TAllowedProperties, TAllowedPseudos, object, TRequiredProperties>;
156
+ > = Internal$XCSSProp<
157
+ TAllowedProperties,
158
+ TAllowedPseudos,
159
+ string,
160
+ object,
161
+ TRequiredProperties,
162
+ 'loose'
163
+ >;
144
164
 
145
165
  export type Internal$XCSSProp<
146
- TAllowedProperties extends keyof CSSProperties,
166
+ TAllowedProperties extends keyof StrictCSSProperties,
147
167
  TAllowedPseudos extends CSSPseudos,
168
+ TAllowedMediaQueries extends string,
148
169
  TSchema,
149
170
  TRequiredProperties extends {
150
171
  requiredProperties: TAllowedProperties;
151
- requiredPseudos: TAllowedPseudos;
152
- }
172
+ },
173
+ TMode extends 'loose' | 'strict'
153
174
  > =
154
175
  | (MarkAsRequired<
155
- XCSSItem<TAllowedProperties, TSchema>,
176
+ XCSSValue<TAllowedProperties, TSchema, ''>,
156
177
  TRequiredProperties['requiredProperties']
157
178
  > &
158
- MarkAsRequired<
159
- XCSSPseudos<TAllowedProperties, TAllowedPseudos, TRequiredProperties, TSchema>,
160
- TRequiredProperties['requiredPseudos']
161
- > &
162
- BlockedRules)
179
+ XCSSPseudo<TAllowedProperties, TAllowedPseudos, TRequiredProperties, TSchema> &
180
+ XCSSMediaQuery<TAllowedProperties, TAllowedPseudos, TAllowedMediaQueries, TSchema> &
181
+ BlockedRules<TMode>)
163
182
  | false
164
183
  | null
165
184
  | undefined;