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.
Files changed (124) hide show
  1. package/README.md +76 -0
  2. package/dist/__tests__/css-bundle.integration.test.d.ts +11 -0
  3. package/dist/__tests__/css-bundle.integration.test.js +1102 -0
  4. package/dist/__tests__/css-bundle.phase10.property.test.d.ts +9 -0
  5. package/dist/__tests__/css-bundle.phase10.property.test.js +64 -0
  6. package/dist/__tests__/css-bundle.phase5.property.test.d.ts +9 -0
  7. package/dist/__tests__/css-bundle.phase5.property.test.js +126 -0
  8. package/dist/__tests__/css-bundle.phase6.property.test.d.ts +9 -0
  9. package/dist/__tests__/css-bundle.phase6.property.test.js +73 -0
  10. package/dist/__tests__/css-bundle.phase7.property.test.d.ts +9 -0
  11. package/dist/__tests__/css-bundle.phase7.property.test.js +76 -0
  12. package/dist/__tests__/css-bundle.phase8.property.test.d.ts +9 -0
  13. package/dist/__tests__/css-bundle.phase8.property.test.js +67 -0
  14. package/dist/__tests__/css-bundle.phase9.property.test.d.ts +9 -0
  15. package/dist/__tests__/css-bundle.phase9.property.test.js +93 -0
  16. package/dist/__tests__/css-bundle.property.test.d.ts +14 -0
  17. package/dist/__tests__/css-bundle.property.test.js +393 -0
  18. package/dist/__tests__/dom-generators.determinism.property.test.d.ts +1 -0
  19. package/dist/__tests__/dom-generators.determinism.property.test.js +71 -0
  20. package/dist/__tests__/dom-generators.id.property.test.d.ts +1 -0
  21. package/dist/__tests__/dom-generators.id.property.test.js +99 -0
  22. package/dist/__tests__/dom-generators.otp.property.test.d.ts +1 -0
  23. package/dist/__tests__/dom-generators.property.test.d.ts +1 -0
  24. package/dist/__tests__/dom-generators.property.test.js +205 -0
  25. package/dist/__tests__/dom-generators.states.property.test.d.ts +1 -0
  26. package/dist/__tests__/dom-generators.table.property.test.d.ts +1 -0
  27. package/dist/__tests__/dom-generators.tier1.property.test.d.ts +1 -0
  28. package/dist/__tests__/dom-generators.tier1.property.test.js +403 -0
  29. package/dist/__tests__/dom-generators.validation.property.test.d.ts +1 -0
  30. package/dist/__tests__/dom-generators.validation.property.test.js +327 -0
  31. package/dist/__tests__/megamenu.classbuilder.property.test.d.ts +1 -0
  32. package/dist/__tests__/megamenu.classbuilder.property.test.js +88 -0
  33. package/dist/__tests__/smoke.test.d.ts +1 -0
  34. package/dist/__tests__/smoke.test.js +65 -0
  35. package/dist/__tests__/types.phase10.property.test.d.ts +1 -0
  36. package/dist/__tests__/types.phase10.property.test.js +166 -0
  37. package/dist/__tests__/types.phase10.test.d.ts +1 -0
  38. package/dist/__tests__/types.phase10.test.js +76 -0
  39. package/dist/__tests__/types.phase3.property.test.d.ts +1 -0
  40. package/dist/__tests__/types.phase3.property.test.js +83 -0
  41. package/dist/__tests__/types.phase3.test.d.ts +1 -0
  42. package/dist/__tests__/types.phase3.test.js +76 -0
  43. package/dist/__tests__/types.phase4.property.test.d.ts +1 -0
  44. package/dist/__tests__/types.phase4.property.test.js +119 -0
  45. package/dist/__tests__/types.phase4.test.d.ts +1 -0
  46. package/dist/__tests__/types.phase4.test.js +70 -0
  47. package/dist/__tests__/types.phase5.property.test.d.ts +1 -0
  48. package/dist/__tests__/types.phase5.property.test.js +120 -0
  49. package/dist/__tests__/types.phase5.test.d.ts +1 -0
  50. package/dist/__tests__/types.phase5.test.js +64 -0
  51. package/dist/__tests__/types.phase6.property.test.d.ts +1 -0
  52. package/dist/__tests__/types.phase6.property.test.js +189 -0
  53. package/dist/__tests__/types.phase6.test.d.ts +1 -0
  54. package/dist/__tests__/types.phase6.test.js +121 -0
  55. package/dist/__tests__/types.phase7.property.test.d.ts +1 -0
  56. package/dist/__tests__/types.phase7.property.test.js +217 -0
  57. package/dist/__tests__/types.phase7.test.d.ts +1 -0
  58. package/dist/__tests__/types.phase7.test.js +106 -0
  59. package/dist/__tests__/types.phase8.property.test.d.ts +1 -0
  60. package/dist/__tests__/types.phase8.property.test.js +224 -0
  61. package/dist/__tests__/types.phase8.test.d.ts +1 -0
  62. package/dist/__tests__/types.phase8.test.js +114 -0
  63. package/dist/__tests__/types.phase9.property.test.d.ts +1 -0
  64. package/dist/__tests__/types.phase9.property.test.js +347 -0
  65. package/dist/__tests__/types.phase9.test.d.ts +1 -0
  66. package/dist/__tests__/types.phase9.test.js +226 -0
  67. package/dist/__tests__/types.restructure.property.test.d.ts +1 -0
  68. package/dist/__tests__/types.restructure.property.test.js +76 -0
  69. package/dist/__tests__/types.test.d.ts +1 -0
  70. package/dist/__tests__/types.test.js +175 -0
  71. package/dist/dom-generators/accordion.d.ts +23 -0
  72. package/dist/dom-generators/avatar.d.ts +19 -0
  73. package/dist/dom-generators/carousel.d.ts +20 -0
  74. package/dist/dom-generators/chip.d.ts +18 -0
  75. package/dist/dom-generators/combobox.d.ts +28 -0
  76. package/dist/dom-generators/date-picker.d.ts +19 -0
  77. package/dist/dom-generators/dom-generators/accordion.d.ts +21 -0
  78. package/dist/dom-generators/dom-generators/avatar.d.ts +17 -0
  79. package/dist/dom-generators/dom-generators/carousel.d.ts +19 -0
  80. package/dist/dom-generators/dom-generators/chip.d.ts +16 -0
  81. package/dist/dom-generators/dom-generators/combobox.d.ts +26 -0
  82. package/dist/dom-generators/dom-generators/date-picker.d.ts +18 -0
  83. package/dist/dom-generators/dom-generators/drawer.d.ts +17 -0
  84. package/dist/dom-generators/dom-generators/dropdown.d.ts +26 -0
  85. package/dist/dom-generators/dom-generators/file-upload.d.ts +20 -0
  86. package/dist/dom-generators/dom-generators/id-generator.d.ts +9 -0
  87. package/dist/dom-generators/dom-generators/index.d.ts +27 -0
  88. package/dist/dom-generators/dom-generators/modal.d.ts +19 -0
  89. package/dist/dom-generators/dom-generators/otp.d.ts +16 -0
  90. package/dist/dom-generators/dom-generators/popover.d.ts +17 -0
  91. package/dist/dom-generators/dom-generators/progress.d.ts +16 -0
  92. package/dist/dom-generators/dom-generators/search.d.ts +20 -0
  93. package/dist/dom-generators/dom-generators/stepper.d.ts +21 -0
  94. package/dist/dom-generators/dom-generators/table.d.ts +23 -0
  95. package/dist/dom-generators/dom-generators/tabs.d.ts +21 -0
  96. package/dist/dom-generators/dom-generators/time-picker.d.ts +18 -0
  97. package/dist/dom-generators/dom-generators/tooltip.d.ts +17 -0
  98. package/dist/dom-generators/dom-generators/types.d.ts +27 -0
  99. package/dist/dom-generators/dom-generators/validate.d.ts +20 -0
  100. package/dist/dom-generators/drawer.d.ts +19 -0
  101. package/dist/dom-generators/dropdown.d.ts +28 -0
  102. package/dist/dom-generators/file-upload.d.ts +22 -0
  103. package/dist/dom-generators/id-generator.d.ts +9 -0
  104. package/dist/dom-generators/index.bundled.d.ts +654 -0
  105. package/dist/dom-generators/index.cjs +2029 -0
  106. package/dist/dom-generators/index.d.ts +27 -0
  107. package/dist/dom-generators/index.mjs +2001 -0
  108. package/dist/dom-generators/modal.d.ts +21 -0
  109. package/dist/dom-generators/otp.d.ts +18 -0
  110. package/dist/dom-generators/popover.d.ts +19 -0
  111. package/dist/dom-generators/progress.d.ts +18 -0
  112. package/dist/dom-generators/search.d.ts +22 -0
  113. package/dist/dom-generators/stepper.d.ts +23 -0
  114. package/dist/dom-generators/table.d.ts +25 -0
  115. package/dist/dom-generators/tabs.d.ts +23 -0
  116. package/dist/dom-generators/time-picker.d.ts +19 -0
  117. package/dist/dom-generators/tooltip.d.ts +19 -0
  118. package/dist/dom-generators/types.d.ts +155 -0
  119. package/dist/dom-generators/validate.d.ts +20 -0
  120. package/dist/runtime/bootstrap.js +59 -0
  121. package/dist/runtime/index.js +55 -0
  122. package/dist/types.d.ts +155 -0
  123. package/dist/types.js +552 -0
  124. 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 {};