@wix/design-system
Version:
@wix/design-system
113 lines • 5.51 kB
JavaScript
import { defineClassNames, createClassNames } from './defineClassNames';
const classes = defineClassNames('input', {
slots: ['wrapper', 'input'],
variants: {
size: ['tiny', 'small', 'medium', 'large'],
border: ['standard', 'round', 'bottomLine', 'none'],
},
states: ['focus', 'disabled', 'noLeftBorderRadius'],
});
describe('defineClassNames', () => {
describe('block', () => {
it('namespaces the block name', () => {
expect(classes.block).toBe('wds-input');
});
it('root() with no props is just the block', () => {
expect(classes.root()).toBe('wds-input');
});
it('works with no config at all', () => {
expect(defineClassNames('button').root()).toBe('wds-button');
});
});
describe('variants', () => {
it('renders an active variant as block--name-value', () => {
expect(classes.root({ size: 'medium' })).toBe('wds-input wds-input--size-medium');
});
it('omits unset variants', () => {
expect(classes.root({ border: 'round' })).toBe('wds-input wds-input--border-round');
});
it('omits values not in the declared set', () => {
expect(classes.root({ size: 'huge' })).toBe('wds-input');
});
it('omits false/null variant values', () => {
expect(classes.root({ size: false, border: null })).toBe('wds-input');
});
});
describe('states', () => {
it('renders a truthy state as block--name', () => {
expect(classes.root({ disabled: true })).toBe('wds-input wds-input--disabled');
});
it('omits falsy/unset states', () => {
expect(classes.root({ disabled: false, focus: null })).toBe('wds-input');
});
it('kebab-cases camelCase state names', () => {
expect(classes.root({ noLeftBorderRadius: true })).toBe('wds-input wds-input--no-left-border-radius');
});
});
describe('deterministic ordering', () => {
it('orders by config declaration, not prop order', () => {
const fromProps = classes.root({ border: 'round', size: 'tiny' });
expect(fromProps).toBe('wds-input wds-input--size-tiny wds-input--border-round');
});
it('always emits block, then variants, then states, then extras', () => {
expect(classes.root({ disabled: true, size: 'large', border: 'none' }, 'extra-1', 'extra-2')).toBe('wds-input wds-input--size-large wds-input--border-none wds-input--disabled extra-1 extra-2');
});
it('produces identical output regardless of prop key order', () => {
expect(classes.root({ size: 'small', disabled: true })).toBe(classes.root({ disabled: true, size: 'small' }));
});
});
describe('extra class names', () => {
it('appends extra classes to root', () => {
expect(classes.root({}, 'custom')).toBe('wds-input custom');
});
it('filters out falsy extras', () => {
expect(classes.root({}, false, null, undefined, 'kept')).toBe('wds-input kept');
});
});
describe('element / slot', () => {
it('renders a slot as block__name', () => {
expect(classes.element('wrapper')).toBe('wds-input__wrapper');
});
it('appends and filters extra classes on a slot', () => {
expect(classes.element('input', false, 'mask')).toBe('wds-input__input mask');
});
it('slot() returns the same as element() without extras', () => {
expect(classes.slot('wrapper')).toBe(classes.element('wrapper'));
});
});
describe('single-modifier accessors', () => {
it('variant() builds block--name-value', () => {
expect(classes.variant('size', 'tiny')).toBe('wds-input--size-tiny');
});
it('state() builds block--name', () => {
expect(classes.state('focus')).toBe('wds-input--focus');
});
});
});
describe('createClassNames with a versioned namespace', () => {
const versioned = createClassNames('input', {
slots: ['wrapper'],
variants: { size: ['tiny', 'medium'] },
states: ['disabled'],
}, 'wds_1_283_0');
it('root() emits the stable block then the versioned block', () => {
expect(versioned.root()).toBe('wds-input wds_1_283_0-input');
});
it('root() emits both forms of the block and each active modifier', () => {
expect(versioned.root({ size: 'medium', disabled: true })).toBe('wds-input wds-input--size-medium wds-input--disabled ' +
'wds_1_283_0-input wds_1_283_0-input--size-medium wds_1_283_0-input--disabled');
});
it('element() emits the stable slot then the versioned slot', () => {
expect(versioned.element('wrapper')).toBe('wds-input__wrapper wds_1_283_0-input__wrapper');
});
it('does not version consumer-passed classes', () => {
expect(versioned.root({}, 'custom')).toBe('wds-input wds_1_283_0-input custom');
expect(versioned.element('wrapper', 'custom')).toBe('wds-input__wrapper wds_1_283_0-input__wrapper custom');
});
it('emits only the stable form when the versioned namespace is empty', () => {
const stable = createClassNames('input', { slots: ['wrapper'] }, '');
expect(stable.root()).toBe('wds-input');
expect(stable.element('wrapper')).toBe('wds-input__wrapper');
});
});
//# sourceMappingURL=defineClassNames.spec.js.map