@variantjs/core
Version:
VariantJS common functions and utilities
794 lines (698 loc) • 18.2 kB
text/typescript
import { parseVariantWithClassesList } from '../index';
import { ObjectWithClassesList, WithVariantPropsAndClassesList } from '../types';
describe('parse variants with classes list function', () => {
it('returns the same object if no variants passed', () => {
const props = {
class: 'text-red-500',
type: 'number',
};
expect(parseVariantWithClassesList(props, [])).toEqual(props);
});
it('returns the variant props if a variant is added', () => {
const props = {
class: 'text-red-500',
type: 'number',
variants: {
alt: {
class: 'text-blue-500',
type: 'text',
},
},
variant: 'alt',
};
expect(parseVariantWithClassesList(props, [])).toEqual(props.variants.alt);
});
it('returns the default configuration', () => {
const props = {};
const globalConfiguration = {};
const defaultConfiguration = {
type: 'text',
fixedClasses: {
wrapper: 'border p-3',
},
classes: {
wrapper: 'text-red-500',
},
};
expect(
parseVariantWithClassesList(props, ['wrapper'], globalConfiguration, defaultConfiguration),
).toEqual({
type: 'text',
classesList: {
wrapper: 'text-red-500 border p-3',
},
});
});
it('returns the global configuration', () => {
const props = {};
const globalConfiguration = {
type: 'text',
fixedClasses: {
wrapper: 'border p-3',
},
classes: {
wrapper: 'text-red-500',
},
};
const defaultConfiguration = {
type: 'button',
fixedClasses: {
wrapper: 'p-2',
},
classes: {
wrapper: 'text-blue-500',
},
};
expect(
parseVariantWithClassesList(props, ['wrapper'], globalConfiguration, defaultConfiguration),
).toEqual({
type: 'text',
classesList: {
wrapper: 'text-red-500 border p-3',
},
});
});
it('returns the prop configuration from the variant', () => {
const props = {
variant: 'error',
variants: {
error: {
type: 'button',
fixedClasses: {
wrapper: 'p-2',
},
classes: {
wrapper: 'text-blue-500',
},
},
},
};
const globalConfiguration = {
type: 'text',
fixedClasses: {
wrapper: 'border p-3',
},
classes: {
wrapper: 'text-red-500',
},
};
const defaultConfiguration = {
variants: {
error: {
type: 'submit',
fixedClasses: {
wrapper: 'p-3',
},
classes: {
wrapper: 'text-red-500',
},
},
},
};
expect(
parseVariantWithClassesList(props, ['wrapper'], globalConfiguration, defaultConfiguration),
).toEqual({
type: 'button',
classesList: {
wrapper: 'text-blue-500 p-2',
},
});
});
it('returns the global configuration from the variant', () => {
const props = {
variant: 'error',
};
const globalConfiguration = {
type: 'text',
fixedClasses: {
wrapper: 'border p-3',
},
classes: {
wrapper: 'text-red-500',
},
variants: {
error: {
type: 'button',
fixedClasses: {
wrapper: 'p-2',
},
classes: {
wrapper: 'text-blue-500',
},
},
},
};
const defaultConfiguration = {
variants: {
error: {
type: 'submit',
fixedClasses: {
wrapper: 'p-3',
},
classes: {
wrapper: 'text-red-500',
},
},
},
};
expect(
parseVariantWithClassesList(props, ['wrapper'], globalConfiguration, defaultConfiguration),
).toEqual({
type: 'button',
classesList: {
wrapper: 'text-blue-500 p-2',
},
});
});
it('returns the default configuration from the variant', () => {
const props = {
variant: 'error',
};
const globalConfiguration = {
type: 'text',
fixedClasses: {
wrapper: 'border p-3',
},
classes: {
wrapper: 'text-red-500',
},
};
const defaultConfiguration = {
variants: {
error: {
type: 'button',
fixedClasses: {
wrapper: 'p-2',
},
classes: {
wrapper: 'text-blue-500',
},
},
},
};
expect(
parseVariantWithClassesList(props, ['wrapper'], globalConfiguration, defaultConfiguration),
).toEqual({
type: 'button',
classesList: {
wrapper: 'text-blue-500 p-2',
},
});
});
it('merge the variant props with the default props', () => {
const props = {
class: 'text-red-500',
type: 'number',
placeholder: 'Hello world',
variants: {
alt: {
class: 'text-blue-500',
type: 'text',
},
},
variant: 'alt',
};
expect(parseVariantWithClassesList(props, [])).toEqual({
...props.variants.alt,
...{
placeholder: props.placeholder,
},
});
});
it('use the props over the configuration', () => {
const props = {
class: 'text-red-500',
type: 'number',
placeholder: 'Hello world',
};
const configuration = {
class: 'text-blue-500',
};
expect(parseVariantWithClassesList(props, [], configuration)).toEqual(props);
});
it('uses the props over the configuration for classes list', () => {
const props = {
classes: {
wrapper: 'p-3',
body: 'text-gray-500',
},
};
const configuration = {
classes: {
wrapper: 'p-4',
body: 'text-red-500',
},
};
expect(parseVariantWithClassesList(props, ['wrapper', 'body'], configuration)).toEqual({
classesList: props.classes,
});
});
it('overrides only the props defined from the configuration', () => {
const props = {
classes: {
wrapper: 'p-3',
},
};
const configuration = {
classes: {
wrapper: 'p-4',
body: 'text-red-500',
},
};
expect(parseVariantWithClassesList(props, ['wrapper', 'body'], configuration)).toEqual({
classesList: {
body: 'text-red-500',
wrapper: 'p-3',
},
});
});
it('accepts undefined values', () => {
const props = {
classes: {
wrapper: undefined,
body: 'text-gray-500',
},
};
const configuration = {
classes: {
wrapper: 'p-4',
body: 'text-red-500',
},
};
expect(parseVariantWithClassesList(props, ['wrapper', 'body'], {}, configuration)).toEqual({
classesList: {
wrapper: undefined,
body: 'text-gray-500',
},
});
});
it('pass `undefined` in the classes props clear any value', () => {
const props = {
classes: undefined,
};
const configuration = {
classes: {
wrapper: 'p-3',
body: 'text-gray-500',
},
};
expect(parseVariantWithClassesList(props, ['wrapper', 'body'], configuration)).toEqual({
wrapper: undefined,
body: undefined,
});
});
it('pass `undefined` in the fixedClasses props clear any value', () => {
const props = {
fixedClasses: undefined,
};
const configuration = {
fixedClasses: {
wrapper: 'p-3',
body: 'text-gray-500',
},
};
expect(parseVariantWithClassesList(props, ['wrapper', 'body'], configuration)).toEqual({
wrapper: undefined,
body: undefined,
});
});
it('pass `undefined` in the variant classes props clear any value', () => {
const props = {
variants: {
empty: {
classes: undefined,
},
},
variant: 'empty',
};
const configuration = {
classes: {
wrapper: 'p-3',
body: 'text-gray-500',
},
};
expect(parseVariantWithClassesList(props, ['wrapper', 'body'], configuration)).toEqual({
wrapper: undefined,
body: undefined,
});
});
it('pass `undefined` in the variant fixedClasses props clear any value', () => {
const props = {
variants: {
empty: {
fixedClasses: undefined,
},
},
variant: 'empty',
};
const configuration = {
fixedClasses: {
wrapper: 'p-3',
body: 'text-gray-500',
},
};
expect(parseVariantWithClassesList(props, ['wrapper', 'body'], configuration)).toEqual({
wrapper: undefined,
body: undefined,
});
});
it('considers not defined values from the configuration variant', () => {
const props = {
variant: 'error',
};
const configuration = {
variants: {
error: {
fixedClasses: {
wrapper: 'p-3',
},
classes: {
wrapper: 'border',
},
},
},
};
const defaultConfiguration = {
};
expect(parseVariantWithClassesList(props, ['wrapper', 'body'], configuration, defaultConfiguration)).toEqual({
classesList: {
wrapper: 'border p-3',
},
});
});
it('considers not defined values from the defaultConfiguration variant', () => {
const props = {
variant: 'error',
};
const configuration = {
};
const defaultConfiguration = {
variants: {
error: {
fixedClasses: {
wrapper: 'p-3',
},
classes: {
wrapper: 'border',
},
},
},
};
expect(parseVariantWithClassesList(props, ['wrapper', 'body'], configuration, defaultConfiguration)).toEqual({
classesList: {
wrapper: 'border p-3',
},
});
});
it('use the variant from the configuration', () => {
const props = {
variant: 'alt',
};
const configuration = {
class: 'text-blue-500',
variants: {
alt: {
class: 'text-blue-500',
type: 'text',
},
},
};
expect(parseVariantWithClassesList(props, [], configuration)).toEqual(
configuration.variants.alt,
);
});
it('use the configuration if no props sent', () => {
const props = {};
const configuration = {
class: 'text-blue-500',
type: 'text',
};
expect(parseVariantWithClassesList(props, [], configuration)).toEqual(configuration);
});
it('merges className and fixedClasses', () => {
const props = {
class: 'text-red-500',
classes: {
wrapper: ['border-red-500'],
},
fixedClasses: {
wrapper: { 'border-2': true },
},
};
const config = parseVariantWithClassesList(props, ['wrapper']);
expect(config).toEqual({
class: 'text-red-500',
classesList: {
wrapper: 'border-red-500 border-2',
},
});
});
it('merges fixedClasses and variant classes', () => {
type ClassesKeys = 'wrapper' | 'inputWrapper' | 'label' | 'input';
const props: WithVariantPropsAndClassesList<ObjectWithClassesList, ClassesKeys> = {
class: 'text-red-500',
classes: {
wrapper: ['border-red-500'],
},
fixedClasses: {
wrapper: { 'border-2': true },
},
variants: {
alt: {
classes: {
wrapper: 'border-blue-500',
},
},
},
variant: 'alt',
};
expect(parseVariantWithClassesList(props, ['wrapper'])).toEqual({
class: 'text-red-500',
classesList: {
wrapper: 'border-blue-500 border-2',
},
});
});
it('uses the classes from the configuration', () => {
const props = {
variant: 'error',
};
const configuration = {
classes: {
wrapper: 'text-black',
},
variants: {
error: {
classes: {
wrapper: 'text-red-500',
},
},
},
};
expect(parseVariantWithClassesList(props, ['wrapper'], configuration)).toEqual({
classesList: {
wrapper: 'text-red-500',
},
});
});
it('handles undefined classes for a variant', () => {
const props = {
variant: 'error',
};
expect(parseVariantWithClassesList(props, ['wrapper'])).toEqual({});
});
it('merges only the attributes that are defined from the variant', () => {
type ClassesKeys = 'wrapper' | 'inputWrapper' | 'label' | 'input';
const props: WithVariantPropsAndClassesList<ObjectWithClassesList, ClassesKeys> = {
classes: {
wrapper: 'flex items-center space-x-2',
inputWrapper: 'inline-flex',
label: 'uppercase text-gray-500',
input: '',
},
variants: {
error: {
classes: {
label: 'uppercase text-red-500',
input: 'shadow',
},
},
},
variant: 'error',
};
expect(
parseVariantWithClassesList(props, ['wrapper', 'inputWrapper', 'label', 'input']),
).toEqual({
classesList: {
wrapper: 'flex items-center space-x-2',
inputWrapper: 'inline-flex',
label: 'uppercase text-red-500',
input: 'shadow',
},
});
});
it('merges only the attributes that are defined from the variant and keep the fixed classes', () => {
type ClassesKeys = 'wrapper' | 'inputWrapper' | 'label' | 'input';
const props: WithVariantPropsAndClassesList<ObjectWithClassesList, ClassesKeys> = {
fixedClasses: {
wrapper: 'flex items-center',
inputWrapper: 'inline-flex',
label: 'semibold',
input: '',
},
classes: {
wrapper: 'space-x-2',
inputWrapper: '',
label: 'uppercase text-gray-500',
input: '',
},
variants: {
error: {
classes: {
label: 'uppercase text-red-500',
input: 'shadow',
},
},
},
variant: 'error',
};
expect(
parseVariantWithClassesList(props, ['wrapper', 'inputWrapper', 'label', 'input']),
).toEqual({
classesList: {
wrapper: 'space-x-2 flex items-center',
inputWrapper: 'inline-flex',
label: 'uppercase text-red-500 semibold',
input: 'shadow',
},
});
});
it('merges the only the new attributes to the global configuration', () => {
type ClassesKeys = 'wrapper' | 'inputWrapper' | 'label' | 'input';
const props: WithVariantPropsAndClassesList<ObjectWithClassesList, ClassesKeys> = {
classes: {
input: 'border-1',
},
};
const globalConfiguration: WithVariantPropsAndClassesList<ObjectWithClassesList, ClassesKeys> = {
classes: {
wrapper: 'flex items-center space-x-2',
inputWrapper: 'inline-flex',
label: 'uppercase text-gray-500',
input: '',
},
};
expect(
parseVariantWithClassesList(
props,
['wrapper', 'inputWrapper', 'label', 'input'],
globalConfiguration,
),
).toEqual({
classesList: {
wrapper: 'flex items-center space-x-2',
inputWrapper: 'inline-flex',
label: 'uppercase text-gray-500',
input: 'border-1',
},
});
});
it('it merges the new attributes from the default configuration', () => {
type ClassesKeys = 'wrapper' | 'inputWrapper' | 'label' | 'input';
const globalConfiguration: WithVariantPropsAndClassesList<ObjectWithClassesList, ClassesKeys> = {
classes: {
input: 'border-1',
},
};
const defaultConfiguration = {
classes: {
wrapper: 'flex items-center space-x-2',
inputWrapper: 'inline-flex',
label: 'uppercase text-gray-500',
input: '',
},
};
expect(
parseVariantWithClassesList(
{},
['wrapper', 'inputWrapper', 'label', 'input'],
globalConfiguration,
defaultConfiguration,
),
).toEqual({
classesList: {
wrapper: 'flex items-center space-x-2',
inputWrapper: 'inline-flex',
label: 'uppercase text-gray-500',
input: 'border-1',
},
});
});
it('it merges the props with the the default configuration', () => {
type ClassesKeys = 'wrapper' | 'inputWrapper' | 'label' | 'input';
const props: WithVariantPropsAndClassesList<ObjectWithClassesList, ClassesKeys> = {
classes: {
input: 'border-1',
},
};
const defaultConfiguration = {
classes: {
wrapper: 'flex items-center space-x-2',
inputWrapper: 'inline-flex',
label: 'uppercase text-gray-500',
input: '',
},
};
expect(
parseVariantWithClassesList(
props,
['wrapper', 'inputWrapper', 'label', 'input'],
{},
defaultConfiguration,
),
).toEqual({
classesList: {
wrapper: 'flex items-center space-x-2',
inputWrapper: 'inline-flex',
label: 'uppercase text-gray-500',
input: 'border-1',
},
});
});
it('it merges the global configuration, the props, and the default configuration', () => {
type ClassesKeys = 'wrapper' | 'inputWrapper' | 'label' | 'input';
const props: WithVariantPropsAndClassesList<ObjectWithClassesList, ClassesKeys> = {
classes: {
wrapper: 'flex items-center space-x-2',
},
};
const globalConfiguration = {
classes: {
input: 'border-1',
},
};
const defaultConfiguration = {
classes: {
wrapper: 'p-3',
inputWrapper: 'inline-flex',
label: 'uppercase text-gray-500',
input: '',
},
};
expect(
parseVariantWithClassesList(
props,
['wrapper', 'inputWrapper', 'label', 'input'],
globalConfiguration,
defaultConfiguration,
),
).toEqual({
classesList: {
wrapper: 'flex items-center space-x-2',
inputWrapper: 'inline-flex',
label: 'uppercase text-gray-500',
input: 'border-1',
},
});
});
});