@datametria/vue-components 2.3.1 → 2.4.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 (128) hide show
  1. package/README.md +625 -594
  2. package/dist/index.es.js +1962 -1887
  3. package/dist/index.umd.js +6 -6
  4. package/dist/src/components/DatametriaForm.vue.d.ts +1 -1
  5. package/dist/src/components/DatametriaInput.vue.d.ts +9 -1
  6. package/dist/src/components/DatametriaSelect.vue.d.ts +10 -1
  7. package/dist/vue-components.css +1 -1
  8. package/package.json +103 -102
  9. package/src/components/DatametriaAlert.vue +151 -133
  10. package/src/components/DatametriaAutocomplete.vue +250 -229
  11. package/src/components/DatametriaAvatar.vue +256 -238
  12. package/src/components/DatametriaBadge.vue +101 -96
  13. package/src/components/DatametriaBreadcrumb.vue +132 -128
  14. package/src/components/DatametriaButton.vue +191 -173
  15. package/src/components/DatametriaCard.vue +84 -66
  16. package/src/components/DatametriaCheckbox.vue +197 -193
  17. package/src/components/DatametriaCheckboxGroup.vue +56 -38
  18. package/src/components/DatametriaChip.vue +159 -141
  19. package/src/components/DatametriaContainer.vue +70 -52
  20. package/src/components/DatametriaDataTable.vue +318 -300
  21. package/src/components/DatametriaDatePicker.vue +396 -378
  22. package/src/components/DatametriaDialog.vue +297 -293
  23. package/src/components/DatametriaDivider.vue +105 -98
  24. package/src/components/DatametriaDropdown.vue +356 -350
  25. package/src/components/DatametriaEmpty.vue +155 -151
  26. package/src/components/DatametriaFileUpload.vue +413 -395
  27. package/src/components/DatametriaFloatingBar.vue +144 -126
  28. package/src/components/DatametriaForm.vue +174 -156
  29. package/src/components/DatametriaFormItem.vue +183 -179
  30. package/src/components/DatametriaGrid.vue +55 -37
  31. package/src/components/DatametriaInput.vue +314 -263
  32. package/src/components/DatametriaMenu.vue +618 -600
  33. package/src/components/DatametriaModal.vue +147 -129
  34. package/src/components/DatametriaNavbar.vue +277 -223
  35. package/src/components/DatametriaPagination.vue +375 -371
  36. package/src/components/DatametriaPasswordInput.vue +444 -426
  37. package/src/components/DatametriaPopconfirm.vue +240 -234
  38. package/src/components/DatametriaProgress.vue +228 -224
  39. package/src/components/DatametriaRadio.vue +151 -147
  40. package/src/components/DatametriaRadioGroup.vue +55 -37
  41. package/src/components/DatametriaResult.vue +135 -131
  42. package/src/components/DatametriaSelect.vue +311 -211
  43. package/src/components/DatametriaSidebar.vue +294 -222
  44. package/src/components/DatametriaSkeleton.vue +257 -234
  45. package/src/components/DatametriaSlider.vue +409 -391
  46. package/src/components/DatametriaSortableTable.vue +820 -802
  47. package/src/components/DatametriaSpinner.vue +114 -110
  48. package/src/components/DatametriaSteps.vue +318 -312
  49. package/src/components/DatametriaSwitch.vue +146 -142
  50. package/src/components/DatametriaTabPane.vue +94 -76
  51. package/src/components/DatametriaTable.vue +118 -100
  52. package/src/components/DatametriaTabs.vue +315 -297
  53. package/src/components/DatametriaTextarea.vue +213 -195
  54. package/src/components/DatametriaTimePicker.vue +317 -299
  55. package/src/components/DatametriaToast.vue +176 -176
  56. package/src/components/DatametriaTooltip.vue +421 -400
  57. package/src/components/DatametriaTree.vue +126 -122
  58. package/src/components/DatametriaTreeNode.vue +176 -172
  59. package/src/components/DatametriaUpload.vue +379 -361
  60. package/src/components/__tests__/DatametriaAlert.test.js +35 -35
  61. package/src/components/__tests__/DatametriaAlert.test.ts +190 -190
  62. package/src/components/__tests__/DatametriaAvatar.test.ts +151 -151
  63. package/src/components/__tests__/DatametriaBadge.test.js +29 -29
  64. package/src/components/__tests__/DatametriaBadge.test.ts +167 -167
  65. package/src/components/__tests__/DatametriaBreadcrumb.test.ts +187 -0
  66. package/src/components/__tests__/DatametriaButton.test.js +30 -30
  67. package/src/components/__tests__/DatametriaButton.test.ts +283 -283
  68. package/src/components/__tests__/DatametriaCard.test.ts +201 -201
  69. package/src/components/__tests__/DatametriaCheckbox.test.ts +204 -0
  70. package/src/components/__tests__/DatametriaChip.test.js +38 -38
  71. package/src/components/__tests__/DatametriaContainer.test.ts +52 -52
  72. package/src/components/__tests__/DatametriaDialog.test.ts +338 -0
  73. package/src/components/__tests__/DatametriaDivider.test.ts +54 -54
  74. package/src/components/__tests__/DatametriaDropdown.test.ts +357 -0
  75. package/src/components/__tests__/DatametriaEmpty.test.ts +261 -0
  76. package/src/components/__tests__/DatametriaFileUpload.test.ts +290 -290
  77. package/src/components/__tests__/DatametriaFloatingBar.test.ts +137 -137
  78. package/src/components/__tests__/DatametriaForm.test.ts +96 -0
  79. package/src/components/__tests__/DatametriaFormItem.test.ts +58 -0
  80. package/src/components/__tests__/DatametriaGrid.test.ts +31 -31
  81. package/src/components/__tests__/DatametriaInput.test.ts +72 -72
  82. package/src/components/__tests__/DatametriaMenu.test.ts +366 -366
  83. package/src/components/__tests__/DatametriaModal.test.ts +86 -86
  84. package/src/components/__tests__/DatametriaNavbar.test.js +48 -48
  85. package/src/components/__tests__/DatametriaNavbar.test.ts +203 -203
  86. package/src/components/__tests__/DatametriaPasswordInput.test.js +305 -305
  87. package/src/components/__tests__/DatametriaRadio.test.ts +195 -0
  88. package/src/components/__tests__/DatametriaSelect.test.ts +77 -77
  89. package/src/components/__tests__/DatametriaSidebar.test.ts +169 -169
  90. package/src/components/__tests__/DatametriaSlider.test.ts +261 -261
  91. package/src/components/__tests__/DatametriaSortableTable.test.js +168 -168
  92. package/src/components/__tests__/DatametriaSpinner.test.ts +156 -156
  93. package/src/components/__tests__/DatametriaSteps.test.ts +211 -0
  94. package/src/components/__tests__/DatametriaSwitch.test.ts +129 -0
  95. package/src/components/__tests__/DatametriaTabPane.test.ts +205 -0
  96. package/src/components/__tests__/DatametriaTable.test.ts +97 -97
  97. package/src/components/__tests__/DatametriaTabs.test.ts +232 -232
  98. package/src/components/__tests__/DatametriaToast.test.js +48 -48
  99. package/src/components/__tests__/DatametriaToast.test.ts +99 -99
  100. package/src/components/__tests__/DatametriaTree.test.ts +376 -0
  101. package/src/components/__tests__/index.test.ts +48 -0
  102. package/src/composables/useAccessibilityScale.ts +94 -94
  103. package/src/composables/useBreakpoints.ts +82 -82
  104. package/src/composables/useHapticFeedback.ts +439 -439
  105. package/src/composables/useRipple.ts +218 -218
  106. package/src/composables/useTheme.ts +5 -1
  107. package/src/index.ts +84 -84
  108. package/src/stories/Variants.stories.js +95 -95
  109. package/src/styles/design-tokens.css +623 -623
  110. package/src/theme/ThemeProvider.vue +96 -96
  111. package/src/theme/__tests__/ThemeProvider.test.ts +208 -208
  112. package/src/theme/__tests__/constants.test.ts +31 -31
  113. package/src/theme/__tests__/presets.test.ts +166 -166
  114. package/src/theme/__tests__/tokens.test.ts +155 -155
  115. package/src/theme/__tests__/types.test.ts +153 -153
  116. package/src/theme/__tests__/useTheme.test.ts +146 -146
  117. package/src/theme/constants.ts +14 -14
  118. package/src/theme/index.ts +12 -12
  119. package/src/theme/presets/datametria.ts +94 -94
  120. package/src/theme/presets/default.ts +94 -94
  121. package/src/theme/presets/index.ts +8 -8
  122. package/src/theme/tokens/colors.ts +28 -28
  123. package/src/theme/tokens/index.ts +47 -47
  124. package/src/theme/tokens/spacing.ts +21 -21
  125. package/src/theme/tokens/typography.ts +35 -35
  126. package/src/theme/types.ts +111 -111
  127. package/src/theme/useTheme.ts +28 -28
  128. package/src/types/index.ts +55 -55
@@ -1,201 +1,201 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { mount } from '@vue/test-utils'
3
- import DatametriaCard from '../DatametriaCard.vue'
4
-
5
- describe('DatametriaCard', () => {
6
- describe('Rendering', () => {
7
- it('renders correctly with default props', () => {
8
- const wrapper = mount(DatametriaCard)
9
- expect(wrapper.find('.datametria-card').exists()).toBe(true)
10
- expect(wrapper.find('.datametria-card__content').exists()).toBe(true)
11
- })
12
-
13
- it('renders title when provided', () => {
14
- const wrapper = mount(DatametriaCard, {
15
- props: { title: 'Test Card' }
16
- })
17
- expect(wrapper.find('.datametria-card__header').exists()).toBe(true)
18
- expect(wrapper.find('.datametria-card__title').text()).toBe('Test Card')
19
- })
20
-
21
- it('renders default slot content', () => {
22
- const wrapper = mount(DatametriaCard, {
23
- slots: {
24
- default: '<p>Card content</p>'
25
- }
26
- })
27
- expect(wrapper.find('.datametria-card__content').html()).toContain('Card content')
28
- })
29
-
30
- it('renders header slot when provided', () => {
31
- const wrapper = mount(DatametriaCard, {
32
- slots: {
33
- header: '<div class="custom-header">Custom Header</div>'
34
- }
35
- })
36
- expect(wrapper.find('.datametria-card__header').exists()).toBe(true)
37
- expect(wrapper.find('.custom-header').text()).toBe('Custom Header')
38
- })
39
-
40
- it('renders footer slot when provided', () => {
41
- const wrapper = mount(DatametriaCard, {
42
- slots: {
43
- footer: '<div class="custom-footer">Footer</div>'
44
- }
45
- })
46
- expect(wrapper.find('.datametria-card__footer').exists()).toBe(true)
47
- expect(wrapper.find('.custom-footer').text()).toBe('Footer')
48
- })
49
-
50
- it('does not render header when no title or header slot', () => {
51
- const wrapper = mount(DatametriaCard)
52
- expect(wrapper.find('.datametria-card__header').exists()).toBe(false)
53
- })
54
-
55
- it('does not render footer when no footer slot', () => {
56
- const wrapper = mount(DatametriaCard)
57
- expect(wrapper.find('.datametria-card__footer').exists()).toBe(false)
58
- })
59
- })
60
-
61
- describe('Padding', () => {
62
- it('applies padding by default', () => {
63
- const wrapper = mount(DatametriaCard)
64
- expect(wrapper.find('.datametria-card--no-padding').exists()).toBe(false)
65
- })
66
-
67
- it('removes padding when padding prop is false', () => {
68
- const wrapper = mount(DatametriaCard, {
69
- props: { padding: false }
70
- })
71
- expect(wrapper.find('.datametria-card--no-padding').exists()).toBe(true)
72
- })
73
-
74
- it('applies padding when padding prop is true', () => {
75
- const wrapper = mount(DatametriaCard, {
76
- props: { padding: true }
77
- })
78
- expect(wrapper.find('.datametria-card--no-padding').exists()).toBe(false)
79
- })
80
- })
81
-
82
- describe('CSS Variables', () => {
83
- it('uses CSS variables for background color', () => {
84
- const wrapper = mount(DatametriaCard)
85
- const card = wrapper.find('.datametria-card')
86
- const styles = card.element.style.cssText || window.getComputedStyle(card.element).cssText
87
-
88
- // Component should use CSS variables in its styles
89
- expect(wrapper.html()).toContain('datametria-card')
90
- })
91
-
92
- it('uses CSS variables for border radius', () => {
93
- const wrapper = mount(DatametriaCard)
94
- expect(wrapper.find('.datametria-card').exists()).toBe(true)
95
- })
96
-
97
- it('uses CSS variables for shadows', () => {
98
- const wrapper = mount(DatametriaCard)
99
- expect(wrapper.find('.datametria-card').exists()).toBe(true)
100
- })
101
-
102
- it('uses CSS variables for spacing', () => {
103
- const wrapper = mount(DatametriaCard, {
104
- props: { title: 'Test' }
105
- })
106
- expect(wrapper.find('.datametria-card__header').exists()).toBe(true)
107
- })
108
-
109
- it('uses CSS variables for typography', () => {
110
- const wrapper = mount(DatametriaCard, {
111
- props: { title: 'Test' }
112
- })
113
- expect(wrapper.find('.datametria-card__title').exists()).toBe(true)
114
- })
115
-
116
- it('uses CSS variables for border colors', () => {
117
- const wrapper = mount(DatametriaCard, {
118
- props: { title: 'Test' },
119
- slots: { footer: '<div>Footer</div>' }
120
- })
121
- expect(wrapper.find('.datametria-card__header').exists()).toBe(true)
122
- expect(wrapper.find('.datametria-card__footer').exists()).toBe(true)
123
- })
124
- })
125
-
126
- describe('Complex Scenarios', () => {
127
- it('renders complete card with all sections', () => {
128
- const wrapper = mount(DatametriaCard, {
129
- props: { title: 'Complete Card' },
130
- slots: {
131
- default: '<p>Main content</p>',
132
- footer: '<button>Action</button>'
133
- }
134
- })
135
-
136
- expect(wrapper.find('.datametria-card__header').exists()).toBe(true)
137
- expect(wrapper.find('.datametria-card__content').exists()).toBe(true)
138
- expect(wrapper.find('.datametria-card__footer').exists()).toBe(true)
139
- expect(wrapper.find('.datametria-card__title').text()).toBe('Complete Card')
140
- expect(wrapper.html()).toContain('Main content')
141
- expect(wrapper.html()).toContain('Action')
142
- })
143
-
144
- it('renders card with custom header and footer', () => {
145
- const wrapper = mount(DatametriaCard, {
146
- slots: {
147
- header: '<div class="custom">Custom Header</div>',
148
- default: '<p>Content</p>',
149
- footer: '<div class="custom">Custom Footer</div>'
150
- }
151
- })
152
-
153
- expect(wrapper.findAll('.custom')).toHaveLength(2)
154
- expect(wrapper.html()).toContain('Custom Header')
155
- expect(wrapper.html()).toContain('Custom Footer')
156
- })
157
-
158
- it('renders card without padding and with all sections', () => {
159
- const wrapper = mount(DatametriaCard, {
160
- props: {
161
- title: 'No Padding Card',
162
- padding: false
163
- },
164
- slots: {
165
- default: '<table>Table content</table>',
166
- footer: '<div>Footer</div>'
167
- }
168
- })
169
-
170
- expect(wrapper.find('.datametria-card--no-padding').exists()).toBe(true)
171
- expect(wrapper.html()).toContain('Table content')
172
- })
173
- })
174
-
175
- describe('Backward Compatibility', () => {
176
- it('works without ThemeProvider', () => {
177
- const wrapper = mount(DatametriaCard, {
178
- props: { title: 'Test' },
179
- slots: {
180
- default: '<p>Content</p>',
181
- footer: '<div>Footer</div>'
182
- }
183
- })
184
-
185
- expect(wrapper.find('.datametria-card').exists()).toBe(true)
186
- expect(wrapper.find('.datametria-card__header').exists()).toBe(true)
187
- expect(wrapper.find('.datametria-card__content').exists()).toBe(true)
188
- expect(wrapper.find('.datametria-card__footer').exists()).toBe(true)
189
- })
190
-
191
- it('maintains original visual appearance', () => {
192
- const wrapper = mount(DatametriaCard, {
193
- props: { title: 'Original Style' }
194
- })
195
-
196
- const card = wrapper.find('.datametria-card')
197
- expect(card.exists()).toBe(true)
198
- expect(wrapper.find('.datametria-card__title').text()).toBe('Original Style')
199
- })
200
- })
201
- })
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import DatametriaCard from '../DatametriaCard.vue'
4
+
5
+ describe('DatametriaCard', () => {
6
+ describe('Rendering', () => {
7
+ it('renders correctly with default props', () => {
8
+ const wrapper = mount(DatametriaCard)
9
+ expect(wrapper.find('.datametria-card').exists()).toBe(true)
10
+ expect(wrapper.find('.datametria-card__content').exists()).toBe(true)
11
+ })
12
+
13
+ it('renders title when provided', () => {
14
+ const wrapper = mount(DatametriaCard, {
15
+ props: { title: 'Test Card' }
16
+ })
17
+ expect(wrapper.find('.datametria-card__header').exists()).toBe(true)
18
+ expect(wrapper.find('.datametria-card__title').text()).toBe('Test Card')
19
+ })
20
+
21
+ it('renders default slot content', () => {
22
+ const wrapper = mount(DatametriaCard, {
23
+ slots: {
24
+ default: '<p>Card content</p>'
25
+ }
26
+ })
27
+ expect(wrapper.find('.datametria-card__content').html()).toContain('Card content')
28
+ })
29
+
30
+ it('renders header slot when provided', () => {
31
+ const wrapper = mount(DatametriaCard, {
32
+ slots: {
33
+ header: '<div class="custom-header">Custom Header</div>'
34
+ }
35
+ })
36
+ expect(wrapper.find('.datametria-card__header').exists()).toBe(true)
37
+ expect(wrapper.find('.custom-header').text()).toBe('Custom Header')
38
+ })
39
+
40
+ it('renders footer slot when provided', () => {
41
+ const wrapper = mount(DatametriaCard, {
42
+ slots: {
43
+ footer: '<div class="custom-footer">Footer</div>'
44
+ }
45
+ })
46
+ expect(wrapper.find('.datametria-card__footer').exists()).toBe(true)
47
+ expect(wrapper.find('.custom-footer').text()).toBe('Footer')
48
+ })
49
+
50
+ it('does not render header when no title or header slot', () => {
51
+ const wrapper = mount(DatametriaCard)
52
+ expect(wrapper.find('.datametria-card__header').exists()).toBe(false)
53
+ })
54
+
55
+ it('does not render footer when no footer slot', () => {
56
+ const wrapper = mount(DatametriaCard)
57
+ expect(wrapper.find('.datametria-card__footer').exists()).toBe(false)
58
+ })
59
+ })
60
+
61
+ describe('Padding', () => {
62
+ it('applies padding by default', () => {
63
+ const wrapper = mount(DatametriaCard)
64
+ expect(wrapper.find('.datametria-card--no-padding').exists()).toBe(false)
65
+ })
66
+
67
+ it('removes padding when padding prop is false', () => {
68
+ const wrapper = mount(DatametriaCard, {
69
+ props: { padding: false }
70
+ })
71
+ expect(wrapper.find('.datametria-card--no-padding').exists()).toBe(true)
72
+ })
73
+
74
+ it('applies padding when padding prop is true', () => {
75
+ const wrapper = mount(DatametriaCard, {
76
+ props: { padding: true }
77
+ })
78
+ expect(wrapper.find('.datametria-card--no-padding').exists()).toBe(false)
79
+ })
80
+ })
81
+
82
+ describe('CSS Variables', () => {
83
+ it('uses CSS variables for background color', () => {
84
+ const wrapper = mount(DatametriaCard)
85
+ const card = wrapper.find('.datametria-card')
86
+ const styles = card.element.style.cssText || window.getComputedStyle(card.element).cssText
87
+
88
+ // Component should use CSS variables in its styles
89
+ expect(wrapper.html()).toContain('datametria-card')
90
+ })
91
+
92
+ it('uses CSS variables for border radius', () => {
93
+ const wrapper = mount(DatametriaCard)
94
+ expect(wrapper.find('.datametria-card').exists()).toBe(true)
95
+ })
96
+
97
+ it('uses CSS variables for shadows', () => {
98
+ const wrapper = mount(DatametriaCard)
99
+ expect(wrapper.find('.datametria-card').exists()).toBe(true)
100
+ })
101
+
102
+ it('uses CSS variables for spacing', () => {
103
+ const wrapper = mount(DatametriaCard, {
104
+ props: { title: 'Test' }
105
+ })
106
+ expect(wrapper.find('.datametria-card__header').exists()).toBe(true)
107
+ })
108
+
109
+ it('uses CSS variables for typography', () => {
110
+ const wrapper = mount(DatametriaCard, {
111
+ props: { title: 'Test' }
112
+ })
113
+ expect(wrapper.find('.datametria-card__title').exists()).toBe(true)
114
+ })
115
+
116
+ it('uses CSS variables for border colors', () => {
117
+ const wrapper = mount(DatametriaCard, {
118
+ props: { title: 'Test' },
119
+ slots: { footer: '<div>Footer</div>' }
120
+ })
121
+ expect(wrapper.find('.datametria-card__header').exists()).toBe(true)
122
+ expect(wrapper.find('.datametria-card__footer').exists()).toBe(true)
123
+ })
124
+ })
125
+
126
+ describe('Complex Scenarios', () => {
127
+ it('renders complete card with all sections', () => {
128
+ const wrapper = mount(DatametriaCard, {
129
+ props: { title: 'Complete Card' },
130
+ slots: {
131
+ default: '<p>Main content</p>',
132
+ footer: '<button>Action</button>'
133
+ }
134
+ })
135
+
136
+ expect(wrapper.find('.datametria-card__header').exists()).toBe(true)
137
+ expect(wrapper.find('.datametria-card__content').exists()).toBe(true)
138
+ expect(wrapper.find('.datametria-card__footer').exists()).toBe(true)
139
+ expect(wrapper.find('.datametria-card__title').text()).toBe('Complete Card')
140
+ expect(wrapper.html()).toContain('Main content')
141
+ expect(wrapper.html()).toContain('Action')
142
+ })
143
+
144
+ it('renders card with custom header and footer', () => {
145
+ const wrapper = mount(DatametriaCard, {
146
+ slots: {
147
+ header: '<div class="custom">Custom Header</div>',
148
+ default: '<p>Content</p>',
149
+ footer: '<div class="custom">Custom Footer</div>'
150
+ }
151
+ })
152
+
153
+ expect(wrapper.findAll('.custom')).toHaveLength(2)
154
+ expect(wrapper.html()).toContain('Custom Header')
155
+ expect(wrapper.html()).toContain('Custom Footer')
156
+ })
157
+
158
+ it('renders card without padding and with all sections', () => {
159
+ const wrapper = mount(DatametriaCard, {
160
+ props: {
161
+ title: 'No Padding Card',
162
+ padding: false
163
+ },
164
+ slots: {
165
+ default: '<table>Table content</table>',
166
+ footer: '<div>Footer</div>'
167
+ }
168
+ })
169
+
170
+ expect(wrapper.find('.datametria-card--no-padding').exists()).toBe(true)
171
+ expect(wrapper.html()).toContain('Table content')
172
+ })
173
+ })
174
+
175
+ describe('Backward Compatibility', () => {
176
+ it('works without ThemeProvider', () => {
177
+ const wrapper = mount(DatametriaCard, {
178
+ props: { title: 'Test' },
179
+ slots: {
180
+ default: '<p>Content</p>',
181
+ footer: '<div>Footer</div>'
182
+ }
183
+ })
184
+
185
+ expect(wrapper.find('.datametria-card').exists()).toBe(true)
186
+ expect(wrapper.find('.datametria-card__header').exists()).toBe(true)
187
+ expect(wrapper.find('.datametria-card__content').exists()).toBe(true)
188
+ expect(wrapper.find('.datametria-card__footer').exists()).toBe(true)
189
+ })
190
+
191
+ it('maintains original visual appearance', () => {
192
+ const wrapper = mount(DatametriaCard, {
193
+ props: { title: 'Original Style' }
194
+ })
195
+
196
+ const card = wrapper.find('.datametria-card')
197
+ expect(card.exists()).toBe(true)
198
+ expect(wrapper.find('.datametria-card__title').text()).toBe('Original Style')
199
+ })
200
+ })
201
+ })
@@ -0,0 +1,204 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import DatametriaCheckbox from '../DatametriaCheckbox.vue'
4
+ import DatametriaCheckboxGroup from '../DatametriaCheckboxGroup.vue'
5
+
6
+ describe('DatametriaCheckbox', () => {
7
+ it('renders correctly', () => {
8
+ const wrapper = mount(DatametriaCheckbox, {
9
+ props: { label: 'Test Checkbox' }
10
+ })
11
+ expect(wrapper.find('.datametria-checkbox').exists()).toBe(true)
12
+ expect(wrapper.text()).toContain('Test Checkbox')
13
+ })
14
+
15
+ it('renders with slot content', () => {
16
+ const wrapper = mount(DatametriaCheckbox, {
17
+ slots: { default: 'Slot Content' }
18
+ })
19
+ expect(wrapper.text()).toContain('Slot Content')
20
+ })
21
+
22
+ it('handles v-model correctly', async () => {
23
+ const wrapper = mount(DatametriaCheckbox, {
24
+ props: {
25
+ modelValue: false,
26
+ 'onUpdate:modelValue': (value: boolean) => wrapper.setProps({ modelValue: value })
27
+ }
28
+ })
29
+
30
+ const input = wrapper.find('input[type="checkbox"]')
31
+ await input.setValue(true)
32
+
33
+ expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([true])
34
+ expect(wrapper.emitted('change')?.[0]).toEqual([true])
35
+ })
36
+
37
+ it('applies checked class when checked', async () => {
38
+ const wrapper = mount(DatametriaCheckbox, {
39
+ props: { modelValue: true }
40
+ })
41
+ expect(wrapper.find('.datametria-checkbox').classes()).toContain('is-checked')
42
+ })
43
+
44
+ it('handles disabled state', async () => {
45
+ const wrapper = mount(DatametriaCheckbox, {
46
+ props: { disabled: true }
47
+ })
48
+
49
+ expect(wrapper.find('.datametria-checkbox').classes()).toContain('is-disabled')
50
+ expect(wrapper.find('input').attributes('disabled')).toBeDefined()
51
+
52
+ const input = wrapper.find('input')
53
+ await input.trigger('change')
54
+ expect(wrapper.emitted('update:modelValue')).toBeUndefined()
55
+ })
56
+
57
+ it('handles indeterminate state', async () => {
58
+ const wrapper = mount(DatametriaCheckbox, {
59
+ props: { indeterminate: true }
60
+ })
61
+
62
+ expect(wrapper.find('.datametria-checkbox').classes()).toContain('is-indeterminate')
63
+
64
+ await wrapper.vm.$nextTick()
65
+ const input = wrapper.find('input').element as HTMLInputElement
66
+ expect(input.indeterminate).toBe(true)
67
+ })
68
+
69
+ it('supports custom true/false values', async () => {
70
+ const wrapper = mount(DatametriaCheckbox, {
71
+ props: {
72
+ modelValue: 'yes',
73
+ trueValue: 'yes',
74
+ falseValue: 'no',
75
+ 'onUpdate:modelValue': (value: string) => wrapper.setProps({ modelValue: value })
76
+ }
77
+ })
78
+
79
+ expect(wrapper.find('.datametria-checkbox').classes()).toContain('is-checked')
80
+
81
+ const input = wrapper.find('input')
82
+ await input.setValue(false)
83
+ expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['no'])
84
+ })
85
+
86
+ it('exposes inputRef', () => {
87
+ const wrapper = mount(DatametriaCheckbox)
88
+ expect(wrapper.vm.inputRef).toBeDefined()
89
+ })
90
+
91
+ it('works within checkbox group', async () => {
92
+ const wrapper = mount(DatametriaCheckboxGroup, {
93
+ props: {
94
+ modelValue: ['option1'],
95
+ 'onUpdate:modelValue': (value: string[]) => wrapper.setProps({ modelValue: value })
96
+ },
97
+ slots: {
98
+ default: `
99
+ <DatametriaCheckbox modelValue="option1" label="Option 1" />
100
+ <DatametriaCheckbox modelValue="option2" label="Option 2" />
101
+ `
102
+ },
103
+ global: {
104
+ components: { DatametriaCheckbox }
105
+ }
106
+ })
107
+
108
+ const checkboxes = wrapper.findAllComponents(DatametriaCheckbox)
109
+ expect(checkboxes).toHaveLength(2)
110
+ expect(checkboxes[0].classes()).toContain('is-checked')
111
+ expect(checkboxes[1].classes()).not.toContain('is-checked')
112
+ })
113
+
114
+ it('updates group value when checkbox is toggled', async () => {
115
+ const wrapper = mount(DatametriaCheckboxGroup, {
116
+ props: {
117
+ modelValue: [],
118
+ 'onUpdate:modelValue': (value: string[]) => wrapper.setProps({ modelValue: value })
119
+ },
120
+ slots: {
121
+ default: `
122
+ <DatametriaCheckbox modelValue="option1" label="Option 1" />
123
+ `
124
+ },
125
+ global: {
126
+ components: { DatametriaCheckbox }
127
+ }
128
+ })
129
+
130
+ const checkbox = wrapper.findComponent(DatametriaCheckbox)
131
+ const input = checkbox.find('input')
132
+ await input.setValue(true)
133
+
134
+ expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([['option1']])
135
+ })
136
+
137
+ it('removes value from group when unchecked', async () => {
138
+ const wrapper = mount(DatametriaCheckboxGroup, {
139
+ props: {
140
+ modelValue: ['option1', 'option2'],
141
+ 'onUpdate:modelValue': (value: string[]) => wrapper.setProps({ modelValue: value })
142
+ },
143
+ slots: {
144
+ default: `
145
+ <DatametriaCheckbox modelValue="option1" label="Option 1" />
146
+ `
147
+ },
148
+ global: {
149
+ components: { DatametriaCheckbox }
150
+ }
151
+ })
152
+
153
+ const checkbox = wrapper.findComponent(DatametriaCheckbox)
154
+ const input = checkbox.find('input')
155
+ await input.setValue(false)
156
+
157
+ expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([['option2']])
158
+ })
159
+
160
+ it('emits change event', async () => {
161
+ const wrapper = mount(DatametriaCheckbox, {
162
+ props: { modelValue: false }
163
+ })
164
+
165
+ const input = wrapper.find('input')
166
+ await input.setValue(true)
167
+
168
+ expect(wrapper.emitted('change')).toBeTruthy()
169
+ expect(wrapper.emitted('change')?.[0]).toEqual([true])
170
+ })
171
+
172
+ it('updates indeterminate property reactively', async () => {
173
+ const wrapper = mount(DatametriaCheckbox, {
174
+ props: { indeterminate: false }
175
+ })
176
+
177
+ const input = wrapper.find('input').element as HTMLInputElement
178
+ expect(input.indeterminate).toBe(false)
179
+
180
+ await wrapper.setProps({ indeterminate: true })
181
+ await wrapper.vm.$nextTick()
182
+ expect(input.indeterminate).toBe(true)
183
+ })
184
+
185
+ it('renders without label when not provided', () => {
186
+ const wrapper = mount(DatametriaCheckbox)
187
+ expect(wrapper.find('.datametria-checkbox__label').exists()).toBe(false)
188
+ })
189
+
190
+ it('applies correct classes for all states', async () => {
191
+ const wrapper = mount(DatametriaCheckbox, {
192
+ props: {
193
+ modelValue: true,
194
+ disabled: true,
195
+ indeterminate: true
196
+ }
197
+ })
198
+
199
+ const checkbox = wrapper.find('.datametria-checkbox')
200
+ expect(checkbox.classes()).toContain('is-checked')
201
+ expect(checkbox.classes()).toContain('is-disabled')
202
+ expect(checkbox.classes()).toContain('is-indeterminate')
203
+ })
204
+ })