ux4g-components-web 1.4.0 → 1.5.0
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/README.md +76 -0
- package/dist/__tests__/css-bundle.integration.test.d.ts +11 -0
- package/dist/__tests__/css-bundle.integration.test.js +1102 -0
- package/dist/__tests__/css-bundle.phase10.property.test.d.ts +9 -0
- package/dist/__tests__/css-bundle.phase10.property.test.js +64 -0
- package/dist/__tests__/css-bundle.phase5.property.test.d.ts +9 -0
- package/dist/__tests__/css-bundle.phase5.property.test.js +126 -0
- package/dist/__tests__/css-bundle.phase6.property.test.d.ts +9 -0
- package/dist/__tests__/css-bundle.phase6.property.test.js +73 -0
- package/dist/__tests__/css-bundle.phase7.property.test.d.ts +9 -0
- package/dist/__tests__/css-bundle.phase7.property.test.js +76 -0
- package/dist/__tests__/css-bundle.phase8.property.test.d.ts +9 -0
- package/dist/__tests__/css-bundle.phase8.property.test.js +67 -0
- package/dist/__tests__/css-bundle.phase9.property.test.d.ts +9 -0
- package/dist/__tests__/css-bundle.phase9.property.test.js +93 -0
- package/dist/__tests__/css-bundle.property.test.d.ts +14 -0
- package/dist/__tests__/css-bundle.property.test.js +393 -0
- package/dist/__tests__/dom-generators.determinism.property.test.d.ts +1 -0
- package/dist/__tests__/dom-generators.determinism.property.test.js +71 -0
- package/dist/__tests__/dom-generators.id.property.test.d.ts +1 -0
- package/dist/__tests__/dom-generators.id.property.test.js +99 -0
- package/dist/__tests__/dom-generators.otp.property.test.d.ts +1 -0
- package/dist/__tests__/dom-generators.property.test.d.ts +1 -0
- package/dist/__tests__/dom-generators.property.test.js +205 -0
- package/dist/__tests__/dom-generators.states.property.test.d.ts +1 -0
- package/dist/__tests__/dom-generators.table.property.test.d.ts +1 -0
- package/dist/__tests__/dom-generators.tier1.property.test.d.ts +1 -0
- package/dist/__tests__/dom-generators.tier1.property.test.js +403 -0
- package/dist/__tests__/dom-generators.validation.property.test.d.ts +1 -0
- package/dist/__tests__/dom-generators.validation.property.test.js +327 -0
- package/dist/__tests__/megamenu.classbuilder.property.test.d.ts +1 -0
- package/dist/__tests__/megamenu.classbuilder.property.test.js +88 -0
- package/dist/__tests__/smoke.test.d.ts +1 -0
- package/dist/__tests__/smoke.test.js +65 -0
- package/dist/__tests__/types.phase10.property.test.d.ts +1 -0
- package/dist/__tests__/types.phase10.property.test.js +166 -0
- package/dist/__tests__/types.phase10.test.d.ts +1 -0
- package/dist/__tests__/types.phase10.test.js +76 -0
- package/dist/__tests__/types.phase3.property.test.d.ts +1 -0
- package/dist/__tests__/types.phase3.property.test.js +83 -0
- package/dist/__tests__/types.phase3.test.d.ts +1 -0
- package/dist/__tests__/types.phase3.test.js +76 -0
- package/dist/__tests__/types.phase4.property.test.d.ts +1 -0
- package/dist/__tests__/types.phase4.property.test.js +119 -0
- package/dist/__tests__/types.phase4.test.d.ts +1 -0
- package/dist/__tests__/types.phase4.test.js +70 -0
- package/dist/__tests__/types.phase5.property.test.d.ts +1 -0
- package/dist/__tests__/types.phase5.property.test.js +120 -0
- package/dist/__tests__/types.phase5.test.d.ts +1 -0
- package/dist/__tests__/types.phase5.test.js +64 -0
- package/dist/__tests__/types.phase6.property.test.d.ts +1 -0
- package/dist/__tests__/types.phase6.property.test.js +189 -0
- package/dist/__tests__/types.phase6.test.d.ts +1 -0
- package/dist/__tests__/types.phase6.test.js +121 -0
- package/dist/__tests__/types.phase7.property.test.d.ts +1 -0
- package/dist/__tests__/types.phase7.property.test.js +217 -0
- package/dist/__tests__/types.phase7.test.d.ts +1 -0
- package/dist/__tests__/types.phase7.test.js +106 -0
- package/dist/__tests__/types.phase8.property.test.d.ts +1 -0
- package/dist/__tests__/types.phase8.property.test.js +224 -0
- package/dist/__tests__/types.phase8.test.d.ts +1 -0
- package/dist/__tests__/types.phase8.test.js +114 -0
- package/dist/__tests__/types.phase9.property.test.d.ts +1 -0
- package/dist/__tests__/types.phase9.property.test.js +347 -0
- package/dist/__tests__/types.phase9.test.d.ts +1 -0
- package/dist/__tests__/types.phase9.test.js +226 -0
- package/dist/__tests__/types.restructure.property.test.d.ts +1 -0
- package/dist/__tests__/types.restructure.property.test.js +76 -0
- package/dist/__tests__/types.test.d.ts +1 -0
- package/dist/__tests__/types.test.js +175 -0
- package/dist/dom-generators/accordion.d.ts +23 -0
- package/dist/dom-generators/avatar.d.ts +19 -0
- package/dist/dom-generators/carousel.d.ts +20 -0
- package/dist/dom-generators/chip.d.ts +18 -0
- package/dist/dom-generators/combobox.d.ts +28 -0
- package/dist/dom-generators/date-picker.d.ts +19 -0
- package/dist/dom-generators/dom-generators/accordion.d.ts +21 -0
- package/dist/dom-generators/dom-generators/avatar.d.ts +17 -0
- package/dist/dom-generators/dom-generators/carousel.d.ts +19 -0
- package/dist/dom-generators/dom-generators/chip.d.ts +16 -0
- package/dist/dom-generators/dom-generators/combobox.d.ts +26 -0
- package/dist/dom-generators/dom-generators/date-picker.d.ts +18 -0
- package/dist/dom-generators/dom-generators/drawer.d.ts +17 -0
- package/dist/dom-generators/dom-generators/dropdown.d.ts +26 -0
- package/dist/dom-generators/dom-generators/file-upload.d.ts +20 -0
- package/dist/dom-generators/dom-generators/id-generator.d.ts +9 -0
- package/dist/dom-generators/dom-generators/index.d.ts +27 -0
- package/dist/dom-generators/dom-generators/modal.d.ts +19 -0
- package/dist/dom-generators/dom-generators/otp.d.ts +16 -0
- package/dist/dom-generators/dom-generators/popover.d.ts +17 -0
- package/dist/dom-generators/dom-generators/progress.d.ts +16 -0
- package/dist/dom-generators/dom-generators/search.d.ts +20 -0
- package/dist/dom-generators/dom-generators/stepper.d.ts +21 -0
- package/dist/dom-generators/dom-generators/table.d.ts +23 -0
- package/dist/dom-generators/dom-generators/tabs.d.ts +21 -0
- package/dist/dom-generators/dom-generators/time-picker.d.ts +18 -0
- package/dist/dom-generators/dom-generators/tooltip.d.ts +17 -0
- package/dist/dom-generators/dom-generators/types.d.ts +27 -0
- package/dist/dom-generators/dom-generators/validate.d.ts +20 -0
- package/dist/dom-generators/drawer.d.ts +19 -0
- package/dist/dom-generators/dropdown.d.ts +28 -0
- package/dist/dom-generators/file-upload.d.ts +22 -0
- package/dist/dom-generators/id-generator.d.ts +9 -0
- package/dist/dom-generators/index.bundled.d.ts +654 -0
- package/dist/dom-generators/index.cjs +2029 -0
- package/dist/dom-generators/index.d.ts +27 -0
- package/dist/dom-generators/index.mjs +2001 -0
- package/dist/dom-generators/modal.d.ts +21 -0
- package/dist/dom-generators/otp.d.ts +18 -0
- package/dist/dom-generators/popover.d.ts +19 -0
- package/dist/dom-generators/progress.d.ts +18 -0
- package/dist/dom-generators/search.d.ts +22 -0
- package/dist/dom-generators/stepper.d.ts +23 -0
- package/dist/dom-generators/table.d.ts +25 -0
- package/dist/dom-generators/tabs.d.ts +23 -0
- package/dist/dom-generators/time-picker.d.ts +19 -0
- package/dist/dom-generators/tooltip.d.ts +19 -0
- package/dist/dom-generators/types.d.ts +155 -0
- package/dist/dom-generators/validate.d.ts +20 -0
- package/dist/runtime/bootstrap.js +59 -0
- package/dist/runtime/index.js +55 -0
- package/dist/types.d.ts +155 -0
- package/dist/types.js +552 -0
- package/package.json +12 -2
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { buildPaginationClasses, buildTableClasses, buildPopoverClasses, buildTooltipClasses, buildTabClasses, buildIconButtonClasses, } from '../../src/types';
|
|
2
|
+
// ── buildPaginationClasses ────────────────────────────────────────────────────
|
|
3
|
+
// Requirements: 4.3
|
|
4
|
+
describe('buildPaginationClasses', () => {
|
|
5
|
+
it("variant='default' → base only", () => {
|
|
6
|
+
expect(buildPaginationClasses('default')).toBe('ux4g-pagination');
|
|
7
|
+
});
|
|
8
|
+
it("variant='dotted' → base + dotted", () => {
|
|
9
|
+
expect(buildPaginationClasses('dotted')).toBe('ux4g-pagination ux4g-pagination-dotted');
|
|
10
|
+
});
|
|
11
|
+
it("variant='dotted' paginationStyle='solid' → base + dotted + solid", () => {
|
|
12
|
+
expect(buildPaginationClasses('dotted', 'solid')).toBe('ux4g-pagination ux4g-pagination-dotted ux4g-pagination-solid');
|
|
13
|
+
});
|
|
14
|
+
it("variant='dotted' paginationStyle='translucent' → base + dotted + translucent", () => {
|
|
15
|
+
expect(buildPaginationClasses('dotted', 'translucent')).toBe('ux4g-pagination ux4g-pagination-dotted ux4g-pagination-translucent');
|
|
16
|
+
});
|
|
17
|
+
it("variant='default' paginationStyle='solid' → base only (paginationStyle ignored)", () => {
|
|
18
|
+
expect(buildPaginationClasses('default', 'solid')).toBe('ux4g-pagination');
|
|
19
|
+
});
|
|
20
|
+
it("variant='dotted' paginationStyle='solid' extra='my-pager' → base + dotted + solid + extra", () => {
|
|
21
|
+
expect(buildPaginationClasses('dotted', 'solid', 'my-pager')).toBe('ux4g-pagination ux4g-pagination-dotted ux4g-pagination-solid my-pager');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
// ── buildTableClasses ─────────────────────────────────────────────────────────
|
|
25
|
+
// Requirements: 4.7
|
|
26
|
+
describe('buildTableClasses', () => {
|
|
27
|
+
it("size='m' → base + size", () => {
|
|
28
|
+
expect(buildTableClasses('m')).toBe('ux4g-table ux4g-table-m');
|
|
29
|
+
});
|
|
30
|
+
it("size='s' divider='column' → base + size + column-dividers", () => {
|
|
31
|
+
expect(buildTableClasses('s', 'column')).toBe('ux4g-table ux4g-table-s ux4g-table-column-dividers');
|
|
32
|
+
});
|
|
33
|
+
it("size='lg' divider='none' zebra='rows' → base + size + no-row-dividers + zebra-rows", () => {
|
|
34
|
+
expect(buildTableClasses('lg', 'none', 'rows')).toBe('ux4g-table ux4g-table-lg ux4g-table-no-row-dividers ux4g-table-zebra-rows');
|
|
35
|
+
});
|
|
36
|
+
it("size='m' divider='row' zebra='none' interactive sortable headerBrand → no divider/zebra modifiers, interactive + sortable + header-brand", () => {
|
|
37
|
+
expect(buildTableClasses('m', 'row', 'none', true, true, false, true)).toBe('ux4g-table ux4g-table-m ux4g-table-interactive ux4g-table-sortable ux4g-table-header-brand');
|
|
38
|
+
});
|
|
39
|
+
it("size='m' divider='column' zebra='cols' all booleans true extra='my-table' → full class string", () => {
|
|
40
|
+
expect(buildTableClasses('m', 'column', 'cols', true, true, true, true, 'my-table')).toBe('ux4g-table ux4g-table-m ux4g-table-column-dividers ux4g-table-zebra-cols ux4g-table-interactive ux4g-table-sortable ux4g-table-resizable ux4g-table-header-brand my-table');
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
// ── buildPopoverClasses ───────────────────────────────────────────────────────
|
|
44
|
+
// Requirements: 4.9
|
|
45
|
+
describe('buildPopoverClasses', () => {
|
|
46
|
+
it("placement='bottom' → base + placement", () => {
|
|
47
|
+
expect(buildPopoverClasses('bottom')).toBe('ux4g-popover ux4g-popover-bottom');
|
|
48
|
+
});
|
|
49
|
+
it("placement='top-start' → base + placement", () => {
|
|
50
|
+
expect(buildPopoverClasses('top-start')).toBe('ux4g-popover ux4g-popover-top-start');
|
|
51
|
+
});
|
|
52
|
+
it("placement='right-end' show=true → base + placement + show", () => {
|
|
53
|
+
expect(buildPopoverClasses('right-end', true)).toBe('ux4g-popover ux4g-popover-right-end show');
|
|
54
|
+
});
|
|
55
|
+
it("placement='left' show=false → base + placement, no show", () => {
|
|
56
|
+
expect(buildPopoverClasses('left', false)).toBe('ux4g-popover ux4g-popover-left');
|
|
57
|
+
});
|
|
58
|
+
it("placement='bottom' show=true extra='my' → base + placement + show + extra", () => {
|
|
59
|
+
expect(buildPopoverClasses('bottom', true, 'my')).toBe('ux4g-popover ux4g-popover-bottom show my');
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
// ── buildTooltipClasses ───────────────────────────────────────────────────────
|
|
63
|
+
// Requirements: 4.12
|
|
64
|
+
describe('buildTooltipClasses', () => {
|
|
65
|
+
it("placement='top-center' size='s' → base + placement + size", () => {
|
|
66
|
+
expect(buildTooltipClasses('top-center', 's')).toBe('ux4g-tooltip ux4g-tooltip-top-center ux4g-tooltip-s');
|
|
67
|
+
});
|
|
68
|
+
it("placement='bottom-right' size='xs' → base + placement + size", () => {
|
|
69
|
+
expect(buildTooltipClasses('bottom-right', 'xs')).toBe('ux4g-tooltip ux4g-tooltip-bottom-right ux4g-tooltip-xs');
|
|
70
|
+
});
|
|
71
|
+
it("placement='left-center' size='s' extra='my-tip' → base + placement + size + extra", () => {
|
|
72
|
+
expect(buildTooltipClasses('left-center', 's', 'my-tip')).toBe('ux4g-tooltip ux4g-tooltip-left-center ux4g-tooltip-s my-tip');
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
// ── buildTabClasses ───────────────────────────────────────────────────────────
|
|
76
|
+
// Requirements: 4.15
|
|
77
|
+
describe('buildTabClasses', () => {
|
|
78
|
+
it("variant='underline' size='md' → base + variant + size", () => {
|
|
79
|
+
expect(buildTabClasses('underline', 'md')).toBe('ux4g-tab ux4g-tab-underline ux4g-tab-md');
|
|
80
|
+
});
|
|
81
|
+
it("variant='pill' size='lg' → base + variant + size", () => {
|
|
82
|
+
expect(buildTabClasses('pill', 'lg')).toBe('ux4g-tab ux4g-tab-pill ux4g-tab-lg');
|
|
83
|
+
});
|
|
84
|
+
it("variant='underline' size='sm' vertical=true → base + variant + size + vertical", () => {
|
|
85
|
+
expect(buildTabClasses('underline', 'sm', true)).toBe('ux4g-tab ux4g-tab-underline ux4g-tab-sm ux4g-tab-vertical');
|
|
86
|
+
});
|
|
87
|
+
it("variant='pill' size='md' vertical=false extra='my-tabs' → base + variant + size + extra, no vertical", () => {
|
|
88
|
+
expect(buildTabClasses('pill', 'md', false, 'my-tabs')).toBe('ux4g-tab ux4g-tab-pill ux4g-tab-md my-tabs');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
// ── buildIconButtonClasses ────────────────────────────────────────────────────
|
|
92
|
+
// Requirements: 4.18
|
|
93
|
+
describe('buildIconButtonClasses', () => {
|
|
94
|
+
it("variant='primary' size='md' → base + variant + size", () => {
|
|
95
|
+
expect(buildIconButtonClasses('primary', 'md')).toBe('ux4g-icon-btn ux4g-icon-btn-primary ux4g-icon-btn-md');
|
|
96
|
+
});
|
|
97
|
+
it("variant='outline-primary' size='sm' → base + variant + size", () => {
|
|
98
|
+
expect(buildIconButtonClasses('outline-primary', 'sm')).toBe('ux4g-icon-btn ux4g-icon-btn-outline-primary ux4g-icon-btn-sm');
|
|
99
|
+
});
|
|
100
|
+
it("variant='text-primary' size='lg' pill=true → base + variant + size + pill", () => {
|
|
101
|
+
expect(buildIconButtonClasses('text-primary', 'lg', true)).toBe('ux4g-icon-btn ux4g-icon-btn-text-primary ux4g-icon-btn-lg ux4g-icon-btn-pill');
|
|
102
|
+
});
|
|
103
|
+
it("variant='tonal-primary' size='xs' pill=false extra='my' → base + variant + size + extra, no pill", () => {
|
|
104
|
+
expect(buildIconButtonClasses('tonal-primary', 'xs', false, 'my')).toBe('ux4g-icon-btn ux4g-icon-btn-tonal-primary ux4g-icon-btn-xs my');
|
|
105
|
+
});
|
|
106
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Property-based tests for Phase 8 build functions
|
|
3
|
+
*
|
|
4
|
+
* Property 1: AccessibilityBar class string always contains ux4g-topbar as the sole base token
|
|
5
|
+
* Property 2: Accordion class string contains required tokens and correctly applies arrow position and variant modifiers
|
|
6
|
+
* Property 3: Stepper class string contains required tokens and correctly applies orientation, alignment, variant, and size modifiers
|
|
7
|
+
* Property 4: SliderField class string contains ux4g-slider-field and correctly toggles ux4g-slider-md for md size
|
|
8
|
+
* Property 5: Drawer class string always contains ux4g-drawer and a placement class, and correctly toggles ux4g-drawer-open
|
|
9
|
+
* Property 6: Extra param is always appended as a space-separated token and never duplicates existing tokens for all Phase 8 build functions
|
|
10
|
+
*/
|
|
11
|
+
import * as fc from 'fast-check';
|
|
12
|
+
import { buildAccessibilityBarClasses, buildAccordionClasses, buildStepperClasses, buildSliderFieldClasses, buildDrawerClasses, } from '../../src/types';
|
|
13
|
+
/**
|
|
14
|
+
* Property 1: AccessibilityBar class string always contains ux4g-topbar as the sole base token
|
|
15
|
+
* Tag: Feature: ux4g-phase8-components, Property 1
|
|
16
|
+
* Validates: Requirements 4.1
|
|
17
|
+
*/
|
|
18
|
+
describe('Property 1: AccessibilityBar class always returns ux4g-topbar with optional extra', () => {
|
|
19
|
+
it('Feature: ux4g-phase8-components, Property 1', () => {
|
|
20
|
+
fc.assert(fc.property(fc.option(fc.stringOf(fc.char().filter((c) => c !== ' '), { minLength: 1 })), (extra) => {
|
|
21
|
+
const result = extra !== null
|
|
22
|
+
? buildAccessibilityBarClasses(extra)
|
|
23
|
+
: buildAccessibilityBarClasses();
|
|
24
|
+
const tokens = result.split(' ');
|
|
25
|
+
// Always contains 'ux4g-topbar'
|
|
26
|
+
const hasBase = tokens.includes('ux4g-topbar');
|
|
27
|
+
// When extra is provided, result contains the extra token
|
|
28
|
+
const extraCorrect = extra !== null
|
|
29
|
+
? tokens.includes(extra)
|
|
30
|
+
: true;
|
|
31
|
+
// No duplicates
|
|
32
|
+
const noDuplicates = tokens.length === new Set(tokens).size;
|
|
33
|
+
return hasBase && extraCorrect && noDuplicates;
|
|
34
|
+
}), { numRuns: 100 });
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
/**
|
|
38
|
+
* Property 2: Accordion class string contains required tokens and correctly applies arrow position and variant modifiers
|
|
39
|
+
* Tag: Feature: ux4g-phase8-components, Property 2
|
|
40
|
+
* Validates: Requirements 4.2, 4.3, 4.4
|
|
41
|
+
*/
|
|
42
|
+
describe('Property 2: Accordion class correctly toggles arrow-left and bordered modifiers', () => {
|
|
43
|
+
it('Feature: ux4g-phase8-components, Property 2', () => {
|
|
44
|
+
fc.assert(fc.property(fc.constantFrom('right', 'left'), fc.constantFrom('default', 'bordered'), (arrowPosition, variant) => {
|
|
45
|
+
const result = buildAccordionClasses(arrowPosition, variant);
|
|
46
|
+
const tokens = result.split(' ');
|
|
47
|
+
// Always contains base class
|
|
48
|
+
const hasBase = tokens.includes('ux4g-accordion');
|
|
49
|
+
// Arrow position toggles correctly
|
|
50
|
+
const arrowCorrect = arrowPosition === 'left'
|
|
51
|
+
? tokens.includes('ux4g-accordion-arrow-left')
|
|
52
|
+
: !tokens.includes('ux4g-accordion-arrow-left');
|
|
53
|
+
// Variant toggles correctly
|
|
54
|
+
const variantCorrect = variant === 'bordered'
|
|
55
|
+
? tokens.includes('ux4g-accordion-bordered')
|
|
56
|
+
: !tokens.includes('ux4g-accordion-bordered');
|
|
57
|
+
// No duplicates
|
|
58
|
+
const noDuplicates = tokens.length === new Set(tokens).size;
|
|
59
|
+
return hasBase && arrowCorrect && variantCorrect && noDuplicates;
|
|
60
|
+
}), { numRuns: 100 });
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
/**
|
|
64
|
+
* Property 3: Stepper class string contains required tokens and correctly applies orientation, alignment, variant, and size modifiers
|
|
65
|
+
* Tag: Feature: ux4g-phase8-components, Property 3
|
|
66
|
+
* Validates: Requirements 4.5, 4.6, 4.7, 4.8, 4.9
|
|
67
|
+
*/
|
|
68
|
+
describe('Property 3: Stepper class correctly applies orientation, alignment, variant, and size modifiers', () => {
|
|
69
|
+
it('Feature: ux4g-phase8-components, Property 3', () => {
|
|
70
|
+
fc.assert(fc.property(fc.constantFrom('horizontal', 'vertical'), fc.constantFrom('default', 'center', 'left'), fc.constantFrom('default', 'bottom-line', 'mobile', 'progress'), fc.constantFrom('default', 's'), (orientation, alignment, variant, size) => {
|
|
71
|
+
const result = buildStepperClasses(orientation, alignment, variant, size);
|
|
72
|
+
const tokens = result.split(' ');
|
|
73
|
+
// Always contains base class
|
|
74
|
+
const hasBase = tokens.includes('ux4g-stepper');
|
|
75
|
+
// Orientation and alignment logic
|
|
76
|
+
let orientationCorrect;
|
|
77
|
+
if (orientation === 'vertical') {
|
|
78
|
+
// vertical: contains ux4g-stepper-vertical, does NOT contain horizontal/center/left (alignment ignored)
|
|
79
|
+
orientationCorrect =
|
|
80
|
+
tokens.includes('ux4g-stepper-vertical') &&
|
|
81
|
+
!tokens.includes('ux4g-stepper-horizontal') &&
|
|
82
|
+
!tokens.includes('ux4g-stepper-center') &&
|
|
83
|
+
!tokens.includes('ux4g-stepper-left');
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// horizontal
|
|
87
|
+
if (alignment === 'center') {
|
|
88
|
+
orientationCorrect =
|
|
89
|
+
tokens.includes('ux4g-stepper-horizontal') &&
|
|
90
|
+
tokens.includes('ux4g-stepper-center') &&
|
|
91
|
+
!tokens.includes('ux4g-stepper-vertical');
|
|
92
|
+
}
|
|
93
|
+
else if (alignment === 'left') {
|
|
94
|
+
orientationCorrect =
|
|
95
|
+
tokens.includes('ux4g-stepper-horizontal') &&
|
|
96
|
+
tokens.includes('ux4g-stepper-left') &&
|
|
97
|
+
!tokens.includes('ux4g-stepper-vertical');
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// alignment === 'default': no horizontal class added
|
|
101
|
+
orientationCorrect =
|
|
102
|
+
!tokens.includes('ux4g-stepper-horizontal') &&
|
|
103
|
+
!tokens.includes('ux4g-stepper-center') &&
|
|
104
|
+
!tokens.includes('ux4g-stepper-left') &&
|
|
105
|
+
!tokens.includes('ux4g-stepper-vertical');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Variant modifiers are mutually exclusive
|
|
109
|
+
let variantCorrect;
|
|
110
|
+
if (variant === 'bottom-line') {
|
|
111
|
+
variantCorrect =
|
|
112
|
+
tokens.includes('ux4g-stepper-bottom-line') &&
|
|
113
|
+
!tokens.includes('ux4g-stepper-mobile') &&
|
|
114
|
+
!tokens.includes('ux4g-stepper-progress');
|
|
115
|
+
}
|
|
116
|
+
else if (variant === 'mobile') {
|
|
117
|
+
variantCorrect =
|
|
118
|
+
tokens.includes('ux4g-stepper-mobile') &&
|
|
119
|
+
!tokens.includes('ux4g-stepper-bottom-line') &&
|
|
120
|
+
!tokens.includes('ux4g-stepper-progress');
|
|
121
|
+
}
|
|
122
|
+
else if (variant === 'progress') {
|
|
123
|
+
variantCorrect =
|
|
124
|
+
tokens.includes('ux4g-stepper-progress') &&
|
|
125
|
+
!tokens.includes('ux4g-stepper-bottom-line') &&
|
|
126
|
+
!tokens.includes('ux4g-stepper-mobile');
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
// variant === 'default': no variant modifier
|
|
130
|
+
variantCorrect =
|
|
131
|
+
!tokens.includes('ux4g-stepper-bottom-line') &&
|
|
132
|
+
!tokens.includes('ux4g-stepper-mobile') &&
|
|
133
|
+
!tokens.includes('ux4g-stepper-progress');
|
|
134
|
+
}
|
|
135
|
+
// Size toggles correctly
|
|
136
|
+
const sizeCorrect = size === 's'
|
|
137
|
+
? tokens.includes('ux4g-stepper-s')
|
|
138
|
+
: !tokens.includes('ux4g-stepper-s');
|
|
139
|
+
// No duplicates
|
|
140
|
+
const noDuplicates = tokens.length === new Set(tokens).size;
|
|
141
|
+
return hasBase && orientationCorrect && variantCorrect && sizeCorrect && noDuplicates;
|
|
142
|
+
}), { numRuns: 100 });
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
/**
|
|
146
|
+
* Property 4: SliderField class string contains ux4g-slider-field and correctly toggles ux4g-slider-md for md size
|
|
147
|
+
* Tag: Feature: ux4g-phase8-components, Property 4
|
|
148
|
+
* Validates: Requirements 4.10, 4.11
|
|
149
|
+
*/
|
|
150
|
+
describe('Property 4: SliderField class correctly toggles md size modifier', () => {
|
|
151
|
+
it('Feature: ux4g-phase8-components, Property 4', () => {
|
|
152
|
+
fc.assert(fc.property(fc.constantFrom('sm', 'md'), (size) => {
|
|
153
|
+
const result = buildSliderFieldClasses(size);
|
|
154
|
+
const tokens = result.split(' ');
|
|
155
|
+
// Always contains base class
|
|
156
|
+
const hasBase = tokens.includes('ux4g-slider-field');
|
|
157
|
+
// Size toggles correctly
|
|
158
|
+
const sizeCorrect = size === 'md'
|
|
159
|
+
? tokens.includes('ux4g-slider-md')
|
|
160
|
+
: !tokens.includes('ux4g-slider-md');
|
|
161
|
+
// No duplicates
|
|
162
|
+
const noDuplicates = tokens.length === new Set(tokens).size;
|
|
163
|
+
return hasBase && sizeCorrect && noDuplicates;
|
|
164
|
+
}), { numRuns: 100 });
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
/**
|
|
168
|
+
* Property 5: Drawer class string always contains ux4g-drawer and a placement class, and correctly toggles ux4g-drawer-open
|
|
169
|
+
* Tag: Feature: ux4g-phase8-components, Property 5
|
|
170
|
+
* Validates: Requirements 4.12, 4.13
|
|
171
|
+
*/
|
|
172
|
+
describe('Property 5: Drawer class always emits placement class and correctly toggles open', () => {
|
|
173
|
+
it('Feature: ux4g-phase8-components, Property 5', () => {
|
|
174
|
+
const allPlacements = ['right', 'left', 'top', 'bottom'];
|
|
175
|
+
fc.assert(fc.property(fc.constantFrom('right', 'left', 'top', 'bottom'), fc.boolean(), (placement, open) => {
|
|
176
|
+
const result = buildDrawerClasses(placement, open);
|
|
177
|
+
const tokens = result.split(' ');
|
|
178
|
+
// Always contains base class
|
|
179
|
+
const hasBase = tokens.includes('ux4g-drawer');
|
|
180
|
+
// Always contains the correct placement class
|
|
181
|
+
const hasPlacement = tokens.includes(`ux4g-drawer-${placement}`);
|
|
182
|
+
// Exactly one placement class is present (no other placement classes)
|
|
183
|
+
const otherPlacements = allPlacements.filter((p) => p !== placement);
|
|
184
|
+
const noOtherPlacements = otherPlacements.every((p) => !tokens.includes(`ux4g-drawer-${p}`));
|
|
185
|
+
// open toggles correctly
|
|
186
|
+
const openCorrect = open
|
|
187
|
+
? tokens.includes('ux4g-drawer-open')
|
|
188
|
+
: !tokens.includes('ux4g-drawer-open');
|
|
189
|
+
// No duplicates
|
|
190
|
+
const noDuplicates = tokens.length === new Set(tokens).size;
|
|
191
|
+
return hasBase && hasPlacement && noOtherPlacements && openCorrect && noDuplicates;
|
|
192
|
+
}), { numRuns: 100 });
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
/**
|
|
196
|
+
* Property 6: Extra param is always appended as a space-separated token and never duplicates existing tokens for all Phase 8 build functions
|
|
197
|
+
* Tag: Feature: ux4g-phase8-components, Property 6
|
|
198
|
+
* Validates: Requirements 4.1, 4.4, 4.9, 4.11, 4.13
|
|
199
|
+
*/
|
|
200
|
+
describe('Property 6: Extra param is always appended and never duplicated across all Phase 8 build functions', () => {
|
|
201
|
+
it('Feature: ux4g-phase8-components, Property 6', () => {
|
|
202
|
+
// Generator for a non-empty extra token with no spaces (valid CSS class name)
|
|
203
|
+
const extraArb = fc.stringOf(fc.char().filter((c) => c !== ' '), { minLength: 1 });
|
|
204
|
+
fc.assert(fc.property(extraArb, (extra) => {
|
|
205
|
+
const results = [
|
|
206
|
+
buildAccessibilityBarClasses(extra),
|
|
207
|
+
buildAccordionClasses('left', 'bordered', extra),
|
|
208
|
+
buildStepperClasses('horizontal', 'center', 'progress', 's', extra),
|
|
209
|
+
buildSliderFieldClasses('md', extra),
|
|
210
|
+
buildDrawerClasses('right', true, extra),
|
|
211
|
+
];
|
|
212
|
+
return results.every((result) => {
|
|
213
|
+
const tokens = result.split(' ');
|
|
214
|
+
// Extra token appears in result
|
|
215
|
+
const hasExtra = tokens.includes(extra);
|
|
216
|
+
// No duplicates
|
|
217
|
+
const noDuplicates = tokens.length === new Set(tokens).size;
|
|
218
|
+
// Extra token appears exactly once
|
|
219
|
+
const exactlyOnce = tokens.filter((t) => t === extra).length === 1;
|
|
220
|
+
return hasExtra && noDuplicates && exactlyOnce;
|
|
221
|
+
});
|
|
222
|
+
}), { numRuns: 100 });
|
|
223
|
+
});
|
|
224
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { buildAccessibilityBarClasses, buildAccordionClasses, buildStepperClasses, buildSliderFieldClasses, buildDrawerClasses, } from '../../src/types';
|
|
2
|
+
// ── buildAccessibilityBarClasses ──────────────────────────────────────────────
|
|
3
|
+
// Requirements: 4.1
|
|
4
|
+
describe('buildAccessibilityBarClasses', () => {
|
|
5
|
+
it('no args → ux4g-topbar', () => {
|
|
6
|
+
expect(buildAccessibilityBarClasses()).toBe('ux4g-topbar');
|
|
7
|
+
});
|
|
8
|
+
it("extra='my-topbar' → ux4g-topbar my-topbar", () => {
|
|
9
|
+
expect(buildAccessibilityBarClasses('my-topbar')).toBe('ux4g-topbar my-topbar');
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
// ── buildAccordionClasses ─────────────────────────────────────────────────────
|
|
13
|
+
// Requirements: 4.4
|
|
14
|
+
describe('buildAccordionClasses', () => {
|
|
15
|
+
it('no args → ux4g-accordion', () => {
|
|
16
|
+
expect(buildAccordionClasses()).toBe('ux4g-accordion');
|
|
17
|
+
});
|
|
18
|
+
it("arrowPosition='right' → ux4g-accordion ux4g-accordion-arrow-right", () => {
|
|
19
|
+
expect(buildAccordionClasses('right')).toBe('ux4g-accordion ux4g-accordion-arrow-right');
|
|
20
|
+
});
|
|
21
|
+
it("arrowPosition='left' → ux4g-accordion ux4g-accordion-arrow-left", () => {
|
|
22
|
+
expect(buildAccordionClasses('left')).toBe('ux4g-accordion ux4g-accordion-arrow-left');
|
|
23
|
+
});
|
|
24
|
+
it("arrowPosition='right' variant='bordered' → ux4g-accordion ux4g-accordion-arrow-right ux4g-accordion-bordered", () => {
|
|
25
|
+
expect(buildAccordionClasses('right', 'bordered')).toBe('ux4g-accordion ux4g-accordion-arrow-right ux4g-accordion-bordered');
|
|
26
|
+
});
|
|
27
|
+
it("arrowPosition='left' variant='bordered' → ux4g-accordion ux4g-accordion-arrow-left ux4g-accordion-bordered", () => {
|
|
28
|
+
expect(buildAccordionClasses('left', 'bordered')).toBe('ux4g-accordion ux4g-accordion-arrow-left ux4g-accordion-bordered');
|
|
29
|
+
});
|
|
30
|
+
it("arrowPosition='left' variant='bordered' extra='my-acc' → full class string", () => {
|
|
31
|
+
expect(buildAccordionClasses('left', 'bordered', 'my-acc')).toBe('ux4g-accordion ux4g-accordion-arrow-left ux4g-accordion-bordered my-acc');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
// ── buildStepperClasses ───────────────────────────────────────────────────────
|
|
35
|
+
// Requirements: 4.9
|
|
36
|
+
describe('buildStepperClasses', () => {
|
|
37
|
+
it('no args → ux4g-stepper', () => {
|
|
38
|
+
expect(buildStepperClasses()).toBe('ux4g-stepper');
|
|
39
|
+
});
|
|
40
|
+
it("orientation='horizontal' → ux4g-stepper (no modifier for default alignment)", () => {
|
|
41
|
+
expect(buildStepperClasses('horizontal')).toBe('ux4g-stepper');
|
|
42
|
+
});
|
|
43
|
+
it("orientation='horizontal' alignment='center' → ux4g-stepper ux4g-stepper-horizontal ux4g-stepper-center", () => {
|
|
44
|
+
expect(buildStepperClasses('horizontal', 'center')).toBe('ux4g-stepper ux4g-stepper-horizontal ux4g-stepper-center');
|
|
45
|
+
});
|
|
46
|
+
it("orientation='horizontal' alignment='left' → ux4g-stepper ux4g-stepper-horizontal ux4g-stepper-left", () => {
|
|
47
|
+
expect(buildStepperClasses('horizontal', 'left')).toBe('ux4g-stepper ux4g-stepper-horizontal ux4g-stepper-left');
|
|
48
|
+
});
|
|
49
|
+
it("orientation='vertical' → ux4g-stepper ux4g-stepper-vertical", () => {
|
|
50
|
+
expect(buildStepperClasses('vertical')).toBe('ux4g-stepper ux4g-stepper-vertical');
|
|
51
|
+
});
|
|
52
|
+
it("orientation='vertical' alignment='center' → ux4g-stepper ux4g-stepper-vertical (alignment ignored when vertical)", () => {
|
|
53
|
+
expect(buildStepperClasses('vertical', 'center')).toBe('ux4g-stepper ux4g-stepper-vertical');
|
|
54
|
+
});
|
|
55
|
+
it("orientation='vertical' alignment='left' → ux4g-stepper ux4g-stepper-vertical (alignment ignored when vertical)", () => {
|
|
56
|
+
expect(buildStepperClasses('vertical', 'left')).toBe('ux4g-stepper ux4g-stepper-vertical');
|
|
57
|
+
});
|
|
58
|
+
it("orientation='horizontal' alignment='default' variant='bottom-line' → ux4g-stepper ux4g-stepper-bottom-line", () => {
|
|
59
|
+
expect(buildStepperClasses('horizontal', 'default', 'bottom-line')).toBe('ux4g-stepper ux4g-stepper-bottom-line');
|
|
60
|
+
});
|
|
61
|
+
it("orientation='horizontal' alignment='default' variant='mobile' → ux4g-stepper ux4g-stepper-mobile", () => {
|
|
62
|
+
expect(buildStepperClasses('horizontal', 'default', 'mobile')).toBe('ux4g-stepper ux4g-stepper-mobile');
|
|
63
|
+
});
|
|
64
|
+
it("orientation='horizontal' alignment='default' variant='progress' → ux4g-stepper ux4g-stepper-progress", () => {
|
|
65
|
+
expect(buildStepperClasses('horizontal', 'default', 'progress')).toBe('ux4g-stepper ux4g-stepper-progress');
|
|
66
|
+
});
|
|
67
|
+
it("orientation='horizontal' alignment='default' variant='default' size='s' → ux4g-stepper ux4g-stepper-s", () => {
|
|
68
|
+
expect(buildStepperClasses('horizontal', 'default', 'default', 's')).toBe('ux4g-stepper ux4g-stepper-s');
|
|
69
|
+
});
|
|
70
|
+
it("orientation='horizontal' alignment='center' variant='progress' size='s' → full class string", () => {
|
|
71
|
+
expect(buildStepperClasses('horizontal', 'center', 'progress', 's')).toBe('ux4g-stepper ux4g-stepper-horizontal ux4g-stepper-center ux4g-stepper-progress ux4g-stepper-s');
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
// ── buildSliderFieldClasses ───────────────────────────────────────────────────
|
|
75
|
+
// Requirements: 4.11
|
|
76
|
+
describe('buildSliderFieldClasses', () => {
|
|
77
|
+
it('no args → ux4g-slider-field', () => {
|
|
78
|
+
expect(buildSliderFieldClasses()).toBe('ux4g-slider-field');
|
|
79
|
+
});
|
|
80
|
+
it("size='sm' → ux4g-slider-field (no size modifier)", () => {
|
|
81
|
+
expect(buildSliderFieldClasses('sm')).toBe('ux4g-slider-field');
|
|
82
|
+
});
|
|
83
|
+
it("size='md' → ux4g-slider-field ux4g-slider-md", () => {
|
|
84
|
+
expect(buildSliderFieldClasses('md')).toBe('ux4g-slider-field ux4g-slider-md');
|
|
85
|
+
});
|
|
86
|
+
it("size='md' extra='x' → ux4g-slider-field ux4g-slider-md x", () => {
|
|
87
|
+
expect(buildSliderFieldClasses('md', 'x')).toBe('ux4g-slider-field ux4g-slider-md x');
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
// ── buildDrawerClasses ────────────────────────────────────────────────────────
|
|
91
|
+
// Requirements: 4.13
|
|
92
|
+
describe('buildDrawerClasses', () => {
|
|
93
|
+
it("placement='right' → ux4g-drawer ux4g-drawer-right", () => {
|
|
94
|
+
expect(buildDrawerClasses('right')).toBe('ux4g-drawer ux4g-drawer-right');
|
|
95
|
+
});
|
|
96
|
+
it("placement='left' → ux4g-drawer ux4g-drawer-left", () => {
|
|
97
|
+
expect(buildDrawerClasses('left')).toBe('ux4g-drawer ux4g-drawer-left');
|
|
98
|
+
});
|
|
99
|
+
it("placement='top' → ux4g-drawer ux4g-drawer-top", () => {
|
|
100
|
+
expect(buildDrawerClasses('top')).toBe('ux4g-drawer ux4g-drawer-top');
|
|
101
|
+
});
|
|
102
|
+
it("placement='bottom' → ux4g-drawer ux4g-drawer-bottom", () => {
|
|
103
|
+
expect(buildDrawerClasses('bottom')).toBe('ux4g-drawer ux4g-drawer-bottom');
|
|
104
|
+
});
|
|
105
|
+
it("placement='right' open=true → ux4g-drawer ux4g-drawer-right ux4g-drawer-open", () => {
|
|
106
|
+
expect(buildDrawerClasses('right', true)).toBe('ux4g-drawer ux4g-drawer-right ux4g-drawer-open');
|
|
107
|
+
});
|
|
108
|
+
it("placement='left' open=false → ux4g-drawer ux4g-drawer-left (no open modifier)", () => {
|
|
109
|
+
expect(buildDrawerClasses('left', false)).toBe('ux4g-drawer ux4g-drawer-left');
|
|
110
|
+
});
|
|
111
|
+
it("placement='right' open=true extra='my' → ux4g-drawer ux4g-drawer-right ux4g-drawer-open my", () => {
|
|
112
|
+
expect(buildDrawerClasses('right', true, 'my')).toBe('ux4g-drawer ux4g-drawer-right ux4g-drawer-open my');
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|