/** @jsxImportSource @compiled/react */
// eslint-disable-next-line import/no-extraneous-dependencies
import { cssMap as cssMapLoose } from '@compiled/react';
import { render } from '@testing-library/react';
import { css, cssMap, XCSSProp, cx } from './__fixtures__/strict-api';
describe('createStrictAPI()', () => {
describe('css()', () => {
it('should type error when circumventing the excess property check', () => {
const stylesOne = css({
color: 'var(--ds-text)',
accentColor: 'red',
// @ts-expect-error — Type 'string' is not assignable to type 'undefined'.ts(2322)
bkgrnd: 'red',
'&:hover': {
color: 'var(--ds-text-hover)',
},
});
const stylesTwo = css({
color: 'var(--ds-text)',
accentColor: 'red',
'&:hover': {
color: 'var(--ds-text-hover)',
// @ts-expect-error — Type 'string' is not assignable to type 'undefined'.ts(2322)
bkgrnd: 'red',
},
});
const { getByTestId } = render(
);
expect(getByTestId('div')).toHaveCompiledCss('color', 'var(--ds-text)');
});
it('should constrain declared types for css() func', () => {
// @ts-expect-error — Type '"red"' is not assignable to type '"var(--ds-surface)" | "var(--ds-surface-sunken" | undefined'.ts(2322)
const styles = css({ background: 'red' });
const { getByTestId } = render();
expect(getByTestId('div')).toHaveCompiledCss('background-color', 'red');
});
it('should mark all properties as optional', () => {
const styles1 = css({});
const styles2 = css({ '&:hover': {} });
const { getByTestId } = render();
expect(getByTestId('div')).not.toHaveCompiledCss('color', 'red');
});
it('should constrain pseudos', () => {
const styles = css({
// @ts-expect-error — Type '"red"' is not assignable to type '"var(--ds-surface)" | "var(--ds-surface-sunken" | undefined'.ts(2322)
background: 'red',
'&:hover': {
// @ts-expect-error — Type '"red"' is not assignable to type '"var(--ds-surface)" | "var(--ds-surface-sunken" | undefined'.ts(2322)
background: 'red',
},
});
const { getByTestId } = render();
expect(getByTestId('div')).toHaveCompiledCss('background-color', 'red', { target: ':hover' });
});
it('should allow valid properties inside pseudos that are different to root', () => {
const styles = css({
background: 'var(--ds-surface)',
'&:hover': {
accentColor: 'red',
background: 'var(--ds-surface-hover)',
},
});
const { getByTestId } = render();
expect(getByTestId('div')).toHaveCompiledCss('background', 'var(--ds-surface-hover)', {
target: ':hover',
});
});
it('should allow valid properties', () => {
const styles = css({
background: 'var(--ds-surface)',
accentColor: 'red',
color: 'var(--ds-text)',
all: 'inherit',
'&:hover': { color: 'var(--ds-text-hover)' },
'&:invalid': { color: 'var(--ds-text)' },
});
const { getByTestId } = render();
expect(getByTestId('div')).toHaveCompiledCss('all', 'inherit');
});
it('should type error with css properties not in the style scope', () => {
// NOTE: These are split into mutliple `css()` calls to ensure the type errors are not hidden
// as only one will error at a time when combined into one query
const bgStyles = css({
fontWeight: 'bold', // just a valid property to ensure the `extends` keyword isn't working as intended
// @ts-expect-error - Object literal may only specify known properties, and 'bg' does not exist in type …
bg: 'red',
});
const colourStyles = css({
fontWeight: 'bold', // just a valid property to ensure the `extends` keyword isn't working as intended
// @ts-expect-error - Object literal may only specify known properties, and 'colour' does not exist in type …
colour: 'var(--ds-text)',
});
const hoverStyles = css({
fontWeight: 'bold', // just a valid property to ensure the `extends` keyword isn't working as intended
'&:hover': {
fontWeight: 'bold', // just a valid property to ensure the `extends` keyword isn't working as intended
// @ts-expect-error - Object literal may only specify known properties, and 'colour' does not exist in type …
colour: 'var(--ds-text-hover)',
},
});
const invalidPsuedoStyles = css({
fontWeight: 'bold', // just a valid property to ensure the `extends` keyword isn't working as intended
// @ts-expect-error - bject literal may only specify known properties, and ''&:invalid-pseudo'' does not exist in type …
'&:invalid-pseudo': {
color: 'var(--ds-text)',
},
});
const { getByTestId } = render(
);
expect(getByTestId('div')).toHaveCompiledCss('font-weight', 'bold');
expect(getByTestId('div')).toHaveCompiledCss('font-weight', 'bold', {
target: ':hover',
});
// These still get compiled to css, even if they're not valid
expect(getByTestId('div')).toHaveCompiledCss('bg', 'red');
expect(getByTestId('div')).toHaveCompiledCss('colour', 'var(--ds-text)');
expect(getByTestId('div')).toHaveCompiledCss('colour', 'var(--ds-text-hover)', {
target: ':hover',
});
});
});
describe('cssMap()', () => {
it('should allow valid properties', () => {
const styles = cssMap({
primary: {
background: 'var(--ds-surface)',
accentColor: 'red',
all: 'inherit',
'&:hover': { color: 'var(--ds-text-hover)' },
'&:invalid': { color: 'var(--ds-text)' },
},
});
const { getByTestId } = render();
expect(getByTestId('div')).toHaveCompiledCss('background', 'var(--ds-surface)');
});
it('should allow valid properties inside pseudos that are different to root', () => {
const styles = cssMap({
primary: {
background: 'var(--ds-surface)',
'&:hover': {
accentColor: 'red',
background: 'var(--ds-surface-hover)',
},
},
});
const { getByTestId } = render();
expect(getByTestId('div')).toHaveCompiledCss('background', 'var(--ds-surface-hover)', {
target: ':hover',
});
});
it('should type error invalid vales', () => {
const styles = cssMap({
primary: {
// @ts-expect-error — Type '{ val: string; }' is not assignable to type 'Readonly> & PseudosDeclarations & EnforceSchema<{ background: "var(--ds-surface)" | "var(--ds-surface-sunken"; }>'.
val: 'ok',
},
});
const { getByTestId } = render();
expect(getByTestId('div')).toHaveCompiledCss('val', 'ok');
});
it('should type error invalid values in pseudos', () => {
const styles = cssMap({
primary: {
// @ts-expect-error — Type '"red"' is not assignable to type '"var(--ds-surface)" | "var(--ds-surface-sunken" | undefined'.ts(2322)
background: 'red',
'&:hover': {
// @ts-expect-error — Type 'string' is not assignable to type 'never'.ts(2322)
val: 'ok',
},
},
});
const { getByTestId } = render();
expect(getByTestId('div')).toHaveCompiledCss('val', 'ok', { target: ':hover' });
});
it('should type error with css properties not in the style scope', () => {
// NOTE: These are split into mutliple `css()` calls to ensure the type errors are not hidden
// as only one will error at a time when combined into one query
const bgStyles = cssMap({
primary: {
fontWeight: 'bold', // just a valid property to ensure the `extends` keyword isn't working as intended
// @ts-expect-error - Object literal may only specify known properties, and 'bg' does not exist in type …
bg: 'red',
},
});
const colourStyles = cssMap({
primary: {
fontWeight: 'bold', // just a valid property to ensure the `extends` keyword isn't working as intended
// @ts-expect-error - Object literal may only specify known properties, and 'colour' does not exist in type …
colour: 'var(--ds-text)',
},
});
const hoverStyles = cssMap({
primary: {
fontWeight: 'bold', // just a valid property to ensure the `extends` keyword isn't working as intended
'&:hover': {
fontWeight: 'bold', // just a valid property to ensure the `extends` keyword isn't working as intended
// @ts-expect-error - Object literal may only specify known properties, and 'colour' does not exist in type …
colour: 'var(--ds-text-hover)',
},
},
});
const invalidPsuedoStyles = cssMap({
primary: {
fontWeight: 'bold', // just a valid property to ensure the `extends` keyword isn't working as intended
// @ts-expect-error - bject literal may only specify known properties, and ''&:invalid-pseudo'' does not exist in type …
'&:invalid-pseudo': {
color: 'var(--ds-text)',
},
},
});
const { getByTestId } = render(
);
expect(getByTestId('div')).toHaveCompiledCss('font-weight', 'bold');
expect(getByTestId('div')).toHaveCompiledCss('font-weight', 'bold', {
target: ':hover',
});
// These still get compiled to css, even if they're not valid
expect(getByTestId('div')).toHaveCompiledCss('bg', 'red');
expect(getByTestId('div')).toHaveCompiledCss('colour', 'var(--ds-text)');
expect(getByTestId('div')).toHaveCompiledCss('colour', 'var(--ds-text-hover)', {
target: ':hover',
});
});
});
describe('XCSSProp', () => {
it('should error with values not in the strict `CompiledStrictSchema`', () => {
function Button({
xcss,
testId,
}: {
testId: string;
xcss: ReturnType>;
}) {
return ;
}
// NOTE: For some reason the "background" property is being expanded to "string" instead of
// staying narrowed as "var(--ds-surface-hover)" meaning it breaks when used with the strict
// schema loaded XCSS prop. This is a bug and unexpected.
const stylesValidRoot = cssMapLoose({
primary: {
color: 'var(--ds-text)',
'&:hover': { color: 'var(--ds-text-hover)', background: 'var(--ds-surface-hover)' },
},
});
const stylesInvalidRoot = cssMapLoose({
primary: {
color: 'red',
'&:hover': { color: 'var(--ds-text-hover)', background: 'var(--ds-surface-hover)' },
},
});
const stylesInvalid = cssMap({
primary: {
// @ts-expect-error -- This is not valid in the CompiledStrictSchema
color: 'red',
'&:hover': { color: 'var(--ds-text-hover)', background: 'var(--ds-surface-hover)' },
},
});
const stylesValid = cssMap({
primary: {
color: 'var(--ds-text)',
'&:hover': { color: 'var(--ds-text-hover)', background: 'var(--ds-surface-hover)' },
},
});
const { getByTestId } = render(
<>
>
);
expect(getByTestId('button-invalid-root')).toHaveCompiledCss('color', 'red');
});
it('should allow valid values from cssMap', () => {
function Button({ xcss }: { xcss: ReturnType> }) {
return ;
}
const styles = cssMap({ bg: { background: 'var(--ds-surface)' } });
const { getByTestId } = render();
expect(getByTestId('button')).toHaveCompiledCss('background', 'var(--ds-surface)');
});
it('should disallow invalid values from cssMap', () => {
function Button({ xcss }: { xcss: ReturnType> }) {
return ;
}
const styles = cssMap({ bg: { accentColor: 'red' } });
const { getByTestId } = render(