@datametria/vue-components 1.2.0 → 2.0.1
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 +548 -657
- package/dist/index.es.js +2353 -1364
- package/dist/index.umd.js +10 -10
- package/dist/vue-components.css +1 -1
- package/package.json +102 -98
- package/src/components/DatametriaAlert.vue +137 -137
- package/src/components/DatametriaAutocomplete.vue +184 -138
- package/src/components/DatametriaAvatar.vue +177 -33
- package/src/components/DatametriaBadge.vue +98 -98
- package/src/components/DatametriaBreadcrumb.vue +21 -21
- package/src/components/DatametriaButton.vue +177 -165
- package/src/components/DatametriaCard.vue +12 -12
- package/src/components/DatametriaCheckbox.vue +8 -8
- package/src/components/DatametriaChip.vue +145 -149
- package/src/components/DatametriaContainer.vue +4 -4
- package/src/components/DatametriaDatePicker.vue +686 -68
- package/src/components/DatametriaDivider.vue +13 -13
- package/src/components/DatametriaFileUpload.vue +272 -140
- package/src/components/DatametriaGrid.vue +3 -3
- package/src/components/DatametriaInput.vue +15 -15
- package/src/components/DatametriaMenu.vue +604 -619
- package/src/components/DatametriaModal.vue +16 -16
- package/src/components/DatametriaNavbar.vue +230 -252
- package/src/components/DatametriaPasswordInput.vue +430 -0
- package/src/components/DatametriaProgress.vue +18 -18
- package/src/components/DatametriaRadio.vue +20 -20
- package/src/components/DatametriaSelect.vue +15 -15
- package/src/components/DatametriaSkeleton.vue +243 -239
- package/src/components/DatametriaSlider.vue +395 -407
- package/src/components/DatametriaSortableTable.vue +585 -0
- package/src/components/DatametriaSpinner.vue +7 -7
- package/src/components/DatametriaSwitch.vue +16 -16
- package/src/components/DatametriaTable.vue +14 -14
- package/src/components/DatametriaTextarea.vue +28 -28
- package/src/components/DatametriaTimePicker.vue +285 -285
- package/src/components/DatametriaToast.vue +176 -176
- package/src/components/DatametriaTooltip.vue +408 -408
- package/src/components/__tests__/DatametriaAlert.test.js +35 -35
- package/src/components/__tests__/DatametriaAlert.test.ts +190 -0
- package/src/components/__tests__/DatametriaAutocomplete.test.ts +180 -0
- package/src/components/__tests__/DatametriaAvatar.test.ts +152 -0
- package/src/components/__tests__/DatametriaBadge.test.js +29 -29
- package/src/components/__tests__/DatametriaBadge.test.ts +167 -0
- package/src/components/__tests__/DatametriaBreadcrumb.test.ts +75 -0
- package/src/components/__tests__/DatametriaButton.test.js +30 -30
- package/src/components/__tests__/DatametriaButton.test.ts +283 -0
- package/src/components/__tests__/DatametriaCard.test.ts +201 -0
- package/src/components/__tests__/DatametriaCheckbox.test.ts +47 -0
- package/src/components/__tests__/DatametriaChip.test.js +38 -38
- package/src/components/__tests__/DatametriaContainer.test.ts +52 -0
- package/src/components/__tests__/DatametriaDatePicker.test.ts +234 -0
- package/src/components/__tests__/DatametriaDivider.test.ts +54 -0
- package/src/components/__tests__/DatametriaFileUpload.test.ts +291 -0
- package/src/components/__tests__/DatametriaGrid.test.ts +31 -0
- package/src/components/__tests__/DatametriaInput.test.ts +72 -0
- package/src/components/__tests__/DatametriaMenu.test.ts +366 -0
- package/src/components/__tests__/DatametriaModal.test.ts +86 -0
- package/src/components/__tests__/DatametriaNavbar.test.js +48 -48
- package/src/components/__tests__/DatametriaNavbar.test.ts +203 -0
- package/src/components/__tests__/DatametriaPasswordInput.test.js +305 -0
- package/src/components/__tests__/DatametriaProgress.test.ts +90 -0
- package/src/components/__tests__/DatametriaRadio.test.ts +77 -0
- package/src/components/__tests__/DatametriaSelect.test.ts +77 -0
- package/src/components/__tests__/DatametriaSlider.test.ts +261 -0
- package/src/components/__tests__/DatametriaSortableTable.test.js +168 -0
- package/src/components/__tests__/DatametriaSpinner.test.ts +156 -0
- package/src/components/__tests__/DatametriaSwitch.test.ts +64 -0
- package/src/components/__tests__/DatametriaTable.test.ts +97 -0
- package/src/components/__tests__/DatametriaTextarea.test.ts +66 -0
- package/src/components/__tests__/DatametriaToast.test.js +48 -48
- package/src/components/__tests__/DatametriaToast.test.ts +99 -0
- package/src/composables/useAccessibilityScale.ts +94 -94
- package/src/composables/useBreakpoints.ts +82 -82
- package/src/composables/useHapticFeedback.ts +439 -439
- package/src/composables/useRipple.ts +218 -218
- package/src/index.ts +68 -61
- package/src/stories/Variants.stories.js +95 -95
- package/src/styles/design-tokens.css +623 -623
- package/src/theme/ThemeProvider.vue +96 -0
- package/src/theme/__tests__/ThemeProvider.test.ts +208 -0
- package/src/theme/__tests__/constants.test.ts +31 -0
- package/src/theme/__tests__/presets.test.ts +166 -0
- package/src/theme/__tests__/tokens.test.ts +155 -0
- package/src/theme/__tests__/types.test.ts +153 -0
- package/src/theme/__tests__/useTheme.test.ts +146 -0
- package/src/theme/constants.ts +14 -0
- package/src/theme/index.ts +12 -0
- package/src/theme/presets/datametria.ts +94 -0
- package/src/theme/presets/default.ts +94 -0
- package/src/theme/presets/index.ts +8 -0
- package/src/theme/tokens/colors.ts +28 -0
- package/src/theme/tokens/index.ts +47 -0
- package/src/theme/tokens/spacing.ts +21 -0
- package/src/theme/tokens/typography.ts +35 -0
- package/src/theme/types.ts +111 -0
- package/src/theme/useTheme.ts +28 -0
- package/src/types/index.ts +19 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import DatametriaFileUpload from '../DatametriaFileUpload.vue'
|
|
4
|
+
import { datametriaTheme } from '../../theme/presets'
|
|
5
|
+
import { THEME_INJECTION_KEY } from '../../theme/constants'
|
|
6
|
+
|
|
7
|
+
const createWrapper = (props = {}, themeProps = {}) => {
|
|
8
|
+
return mount(DatametriaFileUpload, {
|
|
9
|
+
props,
|
|
10
|
+
global: {
|
|
11
|
+
plugins: [{
|
|
12
|
+
install(app) {
|
|
13
|
+
app.provide(THEME_INJECTION_KEY, datametriaTheme)
|
|
14
|
+
}
|
|
15
|
+
}]
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Mock File API
|
|
21
|
+
const createMockFile = (name: string, size: number, type: string) => {
|
|
22
|
+
const file = new File([''], name, { type })
|
|
23
|
+
Object.defineProperty(file, 'size', { value: size })
|
|
24
|
+
return file
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
describe('DatametriaFileUpload', () => {
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
vi.clearAllMocks()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('renders correctly', () => {
|
|
33
|
+
const wrapper = createWrapper()
|
|
34
|
+
expect(wrapper.find('.dm-file-upload').exists()).toBe(true)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('applies theme colors correctly', () => {
|
|
38
|
+
const wrapper = createWrapper()
|
|
39
|
+
expect(wrapper.find('.dm-file-upload').exists()).toBe(true)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('displays upload area', () => {
|
|
43
|
+
const wrapper = createWrapper()
|
|
44
|
+
expect(wrapper.find('.dm-file-upload__area').exists()).toBe(true)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('shows upload text and icon', () => {
|
|
48
|
+
const wrapper = createWrapper()
|
|
49
|
+
expect(wrapper.find('.dm-file-upload__icon').exists()).toBe(true)
|
|
50
|
+
expect(wrapper.find('.dm-file-upload__text').exists()).toBe(true)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('handles file selection via input', async () => {
|
|
54
|
+
const wrapper = createWrapper()
|
|
55
|
+
const input = wrapper.find('.dm-file-upload__input')
|
|
56
|
+
const file = createMockFile('test.txt', 1024, 'text/plain')
|
|
57
|
+
|
|
58
|
+
Object.defineProperty(input.element, 'files', {
|
|
59
|
+
value: [file],
|
|
60
|
+
writable: false
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
await input.trigger('change')
|
|
64
|
+
|
|
65
|
+
const fileUpload = wrapper.findComponent(DatametriaFileUpload)
|
|
66
|
+
expect(fileUpload.emitted('update:modelValue')).toBeTruthy()
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('handles drag and drop', async () => {
|
|
70
|
+
const wrapper = createWrapper()
|
|
71
|
+
const dropArea = wrapper.find('.dm-file-upload__area')
|
|
72
|
+
const file = createMockFile('test.txt', 1024, 'text/plain')
|
|
73
|
+
|
|
74
|
+
const mockDataTransfer = {
|
|
75
|
+
files: [file]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
await dropArea.trigger('drop', {
|
|
79
|
+
dataTransfer: mockDataTransfer
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
const fileUpload = wrapper.findComponent(DatametriaFileUpload)
|
|
83
|
+
expect(fileUpload.emitted('update:modelValue')).toBeTruthy()
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('shows drag over state', async () => {
|
|
87
|
+
const wrapper = createWrapper()
|
|
88
|
+
const dropArea = wrapper.find('.dm-file-upload__area')
|
|
89
|
+
|
|
90
|
+
await dropArea.trigger('dragenter')
|
|
91
|
+
await wrapper.vm.$nextTick()
|
|
92
|
+
expect(wrapper.find('.dm-file-upload__area--dragover').exists()).toBe(true)
|
|
93
|
+
|
|
94
|
+
await dropArea.trigger('dragleave', {
|
|
95
|
+
relatedTarget: document.body
|
|
96
|
+
})
|
|
97
|
+
await wrapper.vm.$nextTick()
|
|
98
|
+
expect(wrapper.find('.dm-file-upload__area--dragover').exists()).toBe(false)
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('supports multiple file selection', async () => {
|
|
102
|
+
const wrapper = createWrapper({ multiple: true })
|
|
103
|
+
const input = wrapper.find('.dm-file-upload__input')
|
|
104
|
+
|
|
105
|
+
expect(input.attributes('multiple')).toBeDefined()
|
|
106
|
+
|
|
107
|
+
const files = [
|
|
108
|
+
createMockFile('test1.txt', 1024, 'text/plain'),
|
|
109
|
+
createMockFile('test2.txt', 2048, 'text/plain')
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
Object.defineProperty(input.element, 'files', {
|
|
113
|
+
value: files,
|
|
114
|
+
writable: false
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
await input.trigger('change')
|
|
118
|
+
|
|
119
|
+
const fileUpload = wrapper.findComponent(DatametriaFileUpload)
|
|
120
|
+
expect(fileUpload.emitted('update:modelValue')).toBeTruthy()
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it('validates file types', async () => {
|
|
124
|
+
const wrapper = createWrapper({ accept: '.txt,.pdf' })
|
|
125
|
+
const input = wrapper.find('.dm-file-upload__input')
|
|
126
|
+
|
|
127
|
+
expect(input.attributes('accept')).toBe('.txt,.pdf')
|
|
128
|
+
|
|
129
|
+
const invalidFile = createMockFile('test.jpg', 1024, 'image/jpeg')
|
|
130
|
+
Object.defineProperty(input.element, 'files', {
|
|
131
|
+
value: [invalidFile],
|
|
132
|
+
writable: false
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
await input.trigger('change')
|
|
136
|
+
await wrapper.vm.$nextTick()
|
|
137
|
+
|
|
138
|
+
expect(wrapper.text()).toContain('Invalid file type')
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
it('validates file size', async () => {
|
|
142
|
+
const wrapper = createWrapper({ maxSize: 1024 }) // 1KB
|
|
143
|
+
const input = wrapper.find('.dm-file-upload__input')
|
|
144
|
+
|
|
145
|
+
const largeFile = createMockFile('large.txt', 2048, 'text/plain') // 2KB
|
|
146
|
+
Object.defineProperty(input.element, 'files', {
|
|
147
|
+
value: [largeFile],
|
|
148
|
+
writable: false
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
await input.trigger('change')
|
|
152
|
+
await wrapper.vm.$nextTick()
|
|
153
|
+
|
|
154
|
+
expect(wrapper.text()).toContain('too large')
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
it('validates maximum number of files', async () => {
|
|
158
|
+
const wrapper = createWrapper({ multiple: true, maxFiles: 2 })
|
|
159
|
+
const input = wrapper.find('.dm-file-upload__input')
|
|
160
|
+
|
|
161
|
+
const files = [
|
|
162
|
+
createMockFile('test1.txt', 1024, 'text/plain'),
|
|
163
|
+
createMockFile('test2.txt', 1024, 'text/plain'),
|
|
164
|
+
createMockFile('test3.txt', 1024, 'text/plain')
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
Object.defineProperty(input.element, 'files', {
|
|
168
|
+
value: files,
|
|
169
|
+
writable: false
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
await input.trigger('change')
|
|
173
|
+
await wrapper.vm.$nextTick()
|
|
174
|
+
|
|
175
|
+
expect(wrapper.text()).toContain('Maximum 2 files')
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
it('shows file list when files are selected', async () => {
|
|
179
|
+
const wrapper = createWrapper({ multiple: true })
|
|
180
|
+
const input = wrapper.find('.dm-file-upload__input')
|
|
181
|
+
|
|
182
|
+
const files = [
|
|
183
|
+
createMockFile('test1.txt', 1024, 'text/plain'),
|
|
184
|
+
createMockFile('test2.txt', 2048, 'text/plain')
|
|
185
|
+
]
|
|
186
|
+
|
|
187
|
+
Object.defineProperty(input.element, 'files', {
|
|
188
|
+
value: files,
|
|
189
|
+
writable: false
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
await input.trigger('change')
|
|
193
|
+
|
|
194
|
+
expect(wrapper.find('.dm-file-upload__files').exists()).toBe(true)
|
|
195
|
+
expect(wrapper.findAll('.dm-file-upload__file')).toHaveLength(2)
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
it('allows file removal', async () => {
|
|
199
|
+
const wrapper = createWrapper({ multiple: true })
|
|
200
|
+
const input = wrapper.find('.dm-file-upload__input')
|
|
201
|
+
|
|
202
|
+
const files = [
|
|
203
|
+
createMockFile('test1.txt', 1024, 'text/plain'),
|
|
204
|
+
createMockFile('test2.txt', 2048, 'text/plain')
|
|
205
|
+
]
|
|
206
|
+
|
|
207
|
+
Object.defineProperty(input.element, 'files', {
|
|
208
|
+
value: files,
|
|
209
|
+
writable: false
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
await input.trigger('change')
|
|
213
|
+
|
|
214
|
+
const removeButton = wrapper.find('.dm-file-upload__remove')
|
|
215
|
+
await removeButton.trigger('click')
|
|
216
|
+
|
|
217
|
+
const fileUpload = wrapper.findComponent(DatametriaFileUpload)
|
|
218
|
+
expect(fileUpload.emitted('update:modelValue')).toBeTruthy()
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
it('supports disabled state', () => {
|
|
222
|
+
const wrapper = createWrapper({ disabled: true })
|
|
223
|
+
const input = wrapper.find('.dm-file-upload__input')
|
|
224
|
+
|
|
225
|
+
expect(input.attributes('disabled')).toBeDefined()
|
|
226
|
+
expect(wrapper.find('.dm-file-upload--disabled').exists()).toBe(true)
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
it('shows loading state during upload', () => {
|
|
230
|
+
const wrapper = createWrapper({ loading: true })
|
|
231
|
+
expect(wrapper.find('.dm-file-upload--loading').exists()).toBe(true)
|
|
232
|
+
expect(wrapper.find('.dm-file-upload__spinner').exists()).toBe(true)
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
it('shows upload progress', () => {
|
|
236
|
+
const wrapper = createWrapper({ progress: 50 })
|
|
237
|
+
const progressBar = wrapper.find('.dm-file-upload__progress-bar')
|
|
238
|
+
|
|
239
|
+
expect(progressBar.exists()).toBe(true)
|
|
240
|
+
expect(progressBar.attributes('style')).toContain('width: 50%')
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
it('supports custom upload text', () => {
|
|
244
|
+
const customText = 'Drop your files here'
|
|
245
|
+
const wrapper = createWrapper({ uploadText: customText })
|
|
246
|
+
|
|
247
|
+
expect(wrapper.find('.dm-file-upload__text').text()).toContain(customText)
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
it('supports custom error messages', () => {
|
|
251
|
+
const errorMessage = 'Upload failed'
|
|
252
|
+
const wrapper = createWrapper({ error: errorMessage })
|
|
253
|
+
|
|
254
|
+
expect(wrapper.find('.dm-file-upload__error').text()).toBe(errorMessage)
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
it('emits file-added event', async () => {
|
|
258
|
+
const wrapper = createWrapper()
|
|
259
|
+
const input = wrapper.find('.dm-file-upload__input')
|
|
260
|
+
const file = createMockFile('test.txt', 1024, 'text/plain')
|
|
261
|
+
|
|
262
|
+
Object.defineProperty(input.element, 'files', {
|
|
263
|
+
value: [file],
|
|
264
|
+
writable: false
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
await input.trigger('change')
|
|
268
|
+
|
|
269
|
+
const fileUpload = wrapper.findComponent(DatametriaFileUpload)
|
|
270
|
+
expect(fileUpload.emitted('file-added')).toBeTruthy()
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
it('emits file-removed event', async () => {
|
|
274
|
+
const wrapper = createWrapper({ multiple: true })
|
|
275
|
+
const input = wrapper.find('.dm-file-upload__input')
|
|
276
|
+
|
|
277
|
+
const files = [createMockFile('test.txt', 1024, 'text/plain')]
|
|
278
|
+
Object.defineProperty(input.element, 'files', {
|
|
279
|
+
value: files,
|
|
280
|
+
writable: false
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
await input.trigger('change')
|
|
284
|
+
|
|
285
|
+
const removeButton = wrapper.find('.dm-file-upload__remove')
|
|
286
|
+
await removeButton.trigger('click')
|
|
287
|
+
|
|
288
|
+
const fileUpload = wrapper.findComponent(DatametriaFileUpload)
|
|
289
|
+
expect(fileUpload.emitted('file-removed')).toBeTruthy()
|
|
290
|
+
})
|
|
291
|
+
})
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import DatametriaGrid from '../DatametriaGrid.vue'
|
|
4
|
+
|
|
5
|
+
describe('DatametriaGrid', () => {
|
|
6
|
+
it('renders correctly', () => {
|
|
7
|
+
const wrapper = mount(DatametriaGrid)
|
|
8
|
+
expect(wrapper.find('.dm-grid').exists()).toBe(true)
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('applies custom cols', () => {
|
|
12
|
+
const wrapper = mount(DatametriaGrid, {
|
|
13
|
+
props: { cols: 6 }
|
|
14
|
+
})
|
|
15
|
+
expect(wrapper.find('.dm-grid').attributes('style')).toContain('--dm-grid-cols: 6')
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it('applies custom gap', () => {
|
|
19
|
+
const wrapper = mount(DatametriaGrid, {
|
|
20
|
+
props: { gap: '2rem' }
|
|
21
|
+
})
|
|
22
|
+
expect(wrapper.find('.dm-grid').attributes('style')).toContain('--dm-grid-gap: 2rem')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('renders slot content', () => {
|
|
26
|
+
const wrapper = mount(DatametriaGrid, {
|
|
27
|
+
slots: { default: '<div>Grid Item</div>' }
|
|
28
|
+
})
|
|
29
|
+
expect(wrapper.html()).toContain('Grid Item')
|
|
30
|
+
})
|
|
31
|
+
})
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import DatametriaInput from '../DatametriaInput.vue'
|
|
4
|
+
|
|
5
|
+
describe('DatametriaInput', () => {
|
|
6
|
+
it('renders correctly', () => {
|
|
7
|
+
const wrapper = mount(DatametriaInput)
|
|
8
|
+
expect(wrapper.find('.datametria-input').exists()).toBe(true)
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('renders label when provided', () => {
|
|
12
|
+
const wrapper = mount(DatametriaInput, {
|
|
13
|
+
props: { label: 'Test Label' }
|
|
14
|
+
})
|
|
15
|
+
expect(wrapper.find('.datametria-input__label').text()).toContain('Test Label')
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it('shows required asterisk when required', () => {
|
|
19
|
+
const wrapper = mount(DatametriaInput, {
|
|
20
|
+
props: { label: 'Test', required: true }
|
|
21
|
+
})
|
|
22
|
+
expect(wrapper.find('.datametria-input__required').exists()).toBe(true)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('binds modelValue correctly', () => {
|
|
26
|
+
const wrapper = mount(DatametriaInput, {
|
|
27
|
+
props: { modelValue: 'test value' }
|
|
28
|
+
})
|
|
29
|
+
expect((wrapper.find('input').element as HTMLInputElement).value).toBe('test value')
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('emits update:modelValue on input', async () => {
|
|
33
|
+
const wrapper = mount(DatametriaInput)
|
|
34
|
+
const input = wrapper.find('input')
|
|
35
|
+
await input.setValue('new value')
|
|
36
|
+
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['new value'])
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('applies disabled state', () => {
|
|
40
|
+
const wrapper = mount(DatametriaInput, {
|
|
41
|
+
props: { disabled: true }
|
|
42
|
+
})
|
|
43
|
+
expect(wrapper.find('input').attributes('disabled')).toBeDefined()
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('shows error message when provided', () => {
|
|
47
|
+
const wrapper = mount(DatametriaInput, {
|
|
48
|
+
props: { errorMessage: 'Error text' }
|
|
49
|
+
})
|
|
50
|
+
expect(wrapper.find('.datametria-input__error').text()).toBe('Error text')
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('applies error class when error exists', () => {
|
|
54
|
+
const wrapper = mount(DatametriaInput, {
|
|
55
|
+
props: { errorMessage: 'Error' }
|
|
56
|
+
})
|
|
57
|
+
expect(wrapper.find('.datametria-input__field--error').exists()).toBe(true)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('applies placeholder', () => {
|
|
61
|
+
const wrapper = mount(DatametriaInput, {
|
|
62
|
+
props: { placeholder: 'Enter text' }
|
|
63
|
+
})
|
|
64
|
+
expect(wrapper.find('input').attributes('placeholder')).toBe('Enter text')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('uses CSS variables with fallbacks', () => {
|
|
68
|
+
const wrapper = mount(DatametriaInput)
|
|
69
|
+
const styles = wrapper.find('.datametria-input').attributes('style')
|
|
70
|
+
expect(wrapper.html()).toContain('datametria-input')
|
|
71
|
+
})
|
|
72
|
+
})
|