@datametria/vue-components 2.2.0 → 2.3.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 +25 -7
- package/dist/index.es.js +3378 -2148
- package/dist/index.umd.js +9 -9
- package/dist/src/components/DatametriaAutocomplete.vue.d.ts +14 -17
- package/dist/src/components/DatametriaBreadcrumb.vue.d.ts +39 -7
- package/dist/src/components/DatametriaCheckbox.vue.d.ts +35 -6
- package/dist/src/components/DatametriaCheckboxGroup.vue.d.ts +30 -0
- package/dist/src/components/DatametriaDataTable.vue.d.ts +64 -0
- package/dist/src/components/DatametriaDatePicker.vue.d.ts +15 -37
- package/dist/src/components/DatametriaDialog.vue.d.ts +71 -0
- package/dist/src/components/DatametriaEmpty.vue.d.ts +30 -0
- package/dist/src/components/DatametriaFloatingBar.vue.d.ts +2 -2
- package/dist/src/components/DatametriaForm.vue.d.ts +40 -0
- package/dist/src/components/DatametriaFormItem.vue.d.ts +28 -0
- package/dist/src/components/DatametriaGrid.vue.d.ts +1 -1
- package/dist/src/components/DatametriaInput.vue.d.ts +69 -10
- package/dist/src/components/DatametriaMenu.vue.d.ts +3 -3
- package/dist/src/components/DatametriaNavbar.vue.d.ts +2 -2
- package/dist/src/components/DatametriaPagination.vue.d.ts +29 -0
- package/dist/src/components/DatametriaPopconfirm.vue.d.ts +43 -0
- package/dist/src/components/DatametriaProgress.vue.d.ts +33 -8
- package/dist/src/components/DatametriaRadio.vue.d.ts +25 -6
- package/dist/src/components/DatametriaRadioGroup.vue.d.ts +29 -0
- package/dist/src/components/DatametriaResult.vue.d.ts +30 -0
- package/dist/src/components/DatametriaSelect.vue.d.ts +16 -11
- package/dist/src/components/DatametriaSidebar.vue.d.ts +3 -3
- package/dist/src/components/DatametriaSlider.vue.d.ts +3 -3
- package/dist/src/components/DatametriaSortableTable.vue.d.ts +1 -1
- package/dist/src/components/DatametriaSteps.vue.d.ts +45 -0
- package/dist/src/components/DatametriaSwitch.vue.d.ts +9 -4
- package/dist/src/components/DatametriaTabPane.vue.d.ts +28 -0
- package/dist/src/components/DatametriaTextarea.vue.d.ts +27 -8
- package/dist/src/components/DatametriaTimePicker.vue.d.ts +17 -25
- package/dist/src/components/DatametriaToast.vue.d.ts +1 -1
- package/dist/src/components/DatametriaTooltip.vue.d.ts +1 -1
- package/dist/src/components/DatametriaTree.vue.d.ts +31 -0
- package/dist/src/components/DatametriaTreeNode.vue.d.ts +17 -0
- package/dist/src/components/DatametriaUpload.vue.d.ts +64 -0
- package/dist/src/index.d.ts +14 -0
- package/dist/vue-components.css +1 -1
- package/package.json +8 -10
- package/src/components/DatametriaAutocomplete.vue +155 -260
- package/src/components/DatametriaBreadcrumb.vue +66 -80
- package/src/components/DatametriaCheckbox.vue +150 -37
- package/src/components/DatametriaCheckboxGroup.vue +43 -0
- package/src/components/DatametriaDataTable.vue +304 -0
- package/src/components/DatametriaDatePicker.vue +238 -614
- package/src/components/DatametriaDialog.vue +295 -0
- package/src/components/DatametriaDropdown.vue +352 -0
- package/src/components/DatametriaEmpty.vue +153 -0
- package/src/components/DatametriaForm.vue +160 -0
- package/src/components/DatametriaFormItem.vue +181 -0
- package/src/components/DatametriaInput.vue +226 -63
- package/src/components/DatametriaPagination.vue +373 -0
- package/src/components/DatametriaPopconfirm.vue +236 -0
- package/src/components/DatametriaProgress.vue +176 -63
- package/src/components/DatametriaRadio.vue +83 -72
- package/src/components/DatametriaRadioGroup.vue +42 -0
- package/src/components/DatametriaResult.vue +133 -0
- package/src/components/DatametriaSelect.vue +172 -67
- package/src/components/DatametriaSortableTable.vue +35 -4
- package/src/components/DatametriaSteps.vue +314 -0
- package/src/components/DatametriaSwitch.vue +86 -80
- package/src/components/DatametriaTabPane.vue +82 -0
- package/src/components/DatametriaTextarea.vue +140 -100
- package/src/components/DatametriaTimePicker.vue +231 -214
- package/src/components/DatametriaTree.vue +124 -0
- package/src/components/DatametriaTreeNode.vue +174 -0
- package/src/components/DatametriaUpload.vue +365 -0
- package/src/index.ts +25 -11
- package/src/components/__tests__/DatametriaAutocomplete.test.ts +0 -180
- package/src/components/__tests__/DatametriaBreadcrumb.test.ts +0 -75
- package/src/components/__tests__/DatametriaCheckbox.test.ts +0 -47
- package/src/components/__tests__/DatametriaDatePicker.test.ts +0 -234
- package/src/components/__tests__/DatametriaProgress.test.ts +0 -90
- package/src/components/__tests__/DatametriaRadio.test.ts +0 -77
- package/src/components/__tests__/DatametriaSwitch.test.ts +0 -64
- package/src/components/__tests__/DatametriaTextarea.test.ts +0 -66
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
2
|
-
import { mount } from '@vue/test-utils'
|
|
3
|
-
import DatametriaAutocomplete from '../DatametriaAutocomplete.vue'
|
|
4
|
-
import { datametriaTheme } from '../../theme/presets'
|
|
5
|
-
import { THEME_INJECTION_KEY } from '../../theme/constants'
|
|
6
|
-
|
|
7
|
-
const createWrapper = (props = {}, themeProps = {}) => {
|
|
8
|
-
return mount(DatametriaAutocomplete, {
|
|
9
|
-
props,
|
|
10
|
-
global: {
|
|
11
|
-
plugins: [{
|
|
12
|
-
install(app) {
|
|
13
|
-
app.provide(THEME_INJECTION_KEY, datametriaTheme)
|
|
14
|
-
}
|
|
15
|
-
}]
|
|
16
|
-
}
|
|
17
|
-
})
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
describe('DatametriaAutocomplete', () => {
|
|
21
|
-
const mockOptions = [
|
|
22
|
-
{ value: '1', label: 'Option 1' },
|
|
23
|
-
{ value: '2', label: 'Option 2' },
|
|
24
|
-
{ value: '3', label: 'Option 3' }
|
|
25
|
-
]
|
|
26
|
-
|
|
27
|
-
beforeEach(() => {
|
|
28
|
-
vi.clearAllMocks()
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('renders correctly', () => {
|
|
32
|
-
const wrapper = createWrapper({ options: mockOptions })
|
|
33
|
-
expect(wrapper.find('.dm-autocomplete').exists()).toBe(true)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
it('applies theme colors correctly', () => {
|
|
37
|
-
const wrapper = createWrapper({ options: mockOptions })
|
|
38
|
-
expect(wrapper.find('.dm-autocomplete').exists()).toBe(true)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('shows options when focused', async () => {
|
|
42
|
-
const wrapper = createWrapper({ options: mockOptions })
|
|
43
|
-
const input = wrapper.find('.dm-autocomplete__input')
|
|
44
|
-
|
|
45
|
-
await input.trigger('focus')
|
|
46
|
-
expect(wrapper.find('.dm-autocomplete__dropdown').exists()).toBe(true)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('filters options based on search query', async () => {
|
|
50
|
-
const wrapper = createWrapper({ options: mockOptions })
|
|
51
|
-
const input = wrapper.find('.dm-autocomplete__input')
|
|
52
|
-
|
|
53
|
-
await input.setValue('Option 1')
|
|
54
|
-
await input.trigger('focus')
|
|
55
|
-
|
|
56
|
-
const options = wrapper.findAll('.dm-autocomplete__option')
|
|
57
|
-
expect(options).toHaveLength(1)
|
|
58
|
-
expect(options[0].text()).toBe('Option 1')
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
it('emits update:modelValue when option is selected', async () => {
|
|
62
|
-
const wrapper = createWrapper({ options: mockOptions })
|
|
63
|
-
const input = wrapper.find('.dm-autocomplete__input')
|
|
64
|
-
|
|
65
|
-
await input.trigger('focus')
|
|
66
|
-
const option = wrapper.find('.dm-autocomplete__option')
|
|
67
|
-
await option.trigger('click')
|
|
68
|
-
|
|
69
|
-
const autocomplete = wrapper.findComponent(DatametriaAutocomplete)
|
|
70
|
-
expect(autocomplete.emitted('update:modelValue')).toBeTruthy()
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
it('supports keyboard navigation', async () => {
|
|
74
|
-
const wrapper = createWrapper({ options: mockOptions })
|
|
75
|
-
const input = wrapper.find('.dm-autocomplete__input')
|
|
76
|
-
|
|
77
|
-
await input.trigger('focus')
|
|
78
|
-
await input.trigger('keydown', { key: 'ArrowDown' })
|
|
79
|
-
|
|
80
|
-
expect(wrapper.find('.dm-autocomplete__option--active').exists()).toBe(true)
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
it('shows error state correctly', () => {
|
|
84
|
-
const wrapper = createWrapper({
|
|
85
|
-
options: mockOptions,
|
|
86
|
-
error: 'Required field'
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
expect(wrapper.find('.dm-autocomplete__input--error').exists()).toBe(true)
|
|
90
|
-
expect(wrapper.find('.dm-autocomplete__error').text()).toBe('Required field')
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
it('supports disabled state', () => {
|
|
94
|
-
const wrapper = createWrapper({
|
|
95
|
-
options: mockOptions,
|
|
96
|
-
disabled: true
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
const input = wrapper.find('.dm-autocomplete__input')
|
|
100
|
-
expect(input.attributes('disabled')).toBeDefined()
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
it('supports required field', () => {
|
|
104
|
-
const wrapper = createWrapper({
|
|
105
|
-
options: mockOptions,
|
|
106
|
-
required: true,
|
|
107
|
-
label: 'Test Label'
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
expect(wrapper.find('.dm-autocomplete__required').exists()).toBe(true)
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
it('supports custom placeholder', () => {
|
|
114
|
-
const placeholder = 'Search options...'
|
|
115
|
-
const wrapper = createWrapper({
|
|
116
|
-
options: mockOptions,
|
|
117
|
-
placeholder
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
const input = wrapper.find('.dm-autocomplete__input')
|
|
121
|
-
expect(input.attributes('placeholder')).toBe(placeholder)
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
it('supports loading state', () => {
|
|
125
|
-
const wrapper = createWrapper({
|
|
126
|
-
options: mockOptions,
|
|
127
|
-
loading: true
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
expect(wrapper.find('.dm-autocomplete__loading').exists()).toBe(true)
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
it('supports no results message', async () => {
|
|
134
|
-
const wrapper = createWrapper({ options: mockOptions })
|
|
135
|
-
const input = wrapper.find('.dm-autocomplete__input')
|
|
136
|
-
|
|
137
|
-
await input.setValue('nonexistent')
|
|
138
|
-
await input.trigger('focus')
|
|
139
|
-
|
|
140
|
-
expect(wrapper.find('.dm-autocomplete__no-results').exists()).toBe(true)
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
it('closes dropdown when clicking outside', async () => {
|
|
144
|
-
const wrapper = createWrapper({ options: mockOptions })
|
|
145
|
-
const input = wrapper.find('.dm-autocomplete__input')
|
|
146
|
-
|
|
147
|
-
await input.trigger('focus')
|
|
148
|
-
expect(wrapper.find('.dm-autocomplete__dropdown').exists()).toBe(true)
|
|
149
|
-
|
|
150
|
-
// Simula clique fora do componente
|
|
151
|
-
document.body.click()
|
|
152
|
-
await new Promise(resolve => setTimeout(resolve, 250))
|
|
153
|
-
await wrapper.vm.$nextTick()
|
|
154
|
-
|
|
155
|
-
expect(wrapper.find('.dm-autocomplete__dropdown').exists()).toBe(false)
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
it('supports multiple selection', async () => {
|
|
159
|
-
const wrapper = createWrapper({
|
|
160
|
-
options: mockOptions,
|
|
161
|
-
multiple: true
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
const input = wrapper.find('.dm-autocomplete__input')
|
|
165
|
-
await input.trigger('focus')
|
|
166
|
-
|
|
167
|
-
const option = wrapper.find('.dm-autocomplete__option')
|
|
168
|
-
await option.trigger('click')
|
|
169
|
-
|
|
170
|
-
expect(wrapper.find('.dm-autocomplete__tag').exists()).toBe(true)
|
|
171
|
-
})
|
|
172
|
-
|
|
173
|
-
it('supports custom option template', () => {
|
|
174
|
-
const wrapper = createWrapper({
|
|
175
|
-
options: mockOptions.map(opt => ({ ...opt, description: `Description for ${opt.label}` }))
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
expect(wrapper.find('.dm-autocomplete').exists()).toBe(true)
|
|
179
|
-
})
|
|
180
|
-
})
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest'
|
|
2
|
-
import { mount } from '@vue/test-utils'
|
|
3
|
-
import DatametriaBreadcrumb from '../DatametriaBreadcrumb.vue'
|
|
4
|
-
|
|
5
|
-
describe('DatametriaBreadcrumb', () => {
|
|
6
|
-
const items = [
|
|
7
|
-
{ label: 'Home', href: '/' },
|
|
8
|
-
{ label: 'Products', href: '/products' },
|
|
9
|
-
{ label: 'Details' }
|
|
10
|
-
]
|
|
11
|
-
|
|
12
|
-
it('renders correctly', () => {
|
|
13
|
-
const wrapper = mount(DatametriaBreadcrumb, {
|
|
14
|
-
props: { items }
|
|
15
|
-
})
|
|
16
|
-
expect(wrapper.find('.dm-breadcrumb').exists()).toBe(true)
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
it('renders all items', () => {
|
|
20
|
-
const wrapper = mount(DatametriaBreadcrumb, {
|
|
21
|
-
props: { items }
|
|
22
|
-
})
|
|
23
|
-
const itemElements = wrapper.findAll('.dm-breadcrumb__item')
|
|
24
|
-
expect(itemElements).toHaveLength(3)
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('renders links for items with href', () => {
|
|
28
|
-
const wrapper = mount(DatametriaBreadcrumb, {
|
|
29
|
-
props: { items }
|
|
30
|
-
})
|
|
31
|
-
const links = wrapper.findAll('.dm-breadcrumb__link')
|
|
32
|
-
expect(links).toHaveLength(2)
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it('renders current item without link', () => {
|
|
36
|
-
const wrapper = mount(DatametriaBreadcrumb, {
|
|
37
|
-
props: { items }
|
|
38
|
-
})
|
|
39
|
-
const current = wrapper.find('.dm-breadcrumb__current')
|
|
40
|
-
expect(current.exists()).toBe(true)
|
|
41
|
-
expect(current.text()).toBe('Details')
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('renders separators', () => {
|
|
45
|
-
const wrapper = mount(DatametriaBreadcrumb, {
|
|
46
|
-
props: { items }
|
|
47
|
-
})
|
|
48
|
-
const separators = wrapper.findAll('.dm-breadcrumb__separator')
|
|
49
|
-
expect(separators).toHaveLength(2)
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it('uses custom separator', () => {
|
|
53
|
-
const wrapper = mount(DatametriaBreadcrumb, {
|
|
54
|
-
props: { items, separator: '>' }
|
|
55
|
-
})
|
|
56
|
-
const separator = wrapper.find('.dm-breadcrumb__separator')
|
|
57
|
-
expect(separator.text()).toBe('>')
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it('emits click event', async () => {
|
|
61
|
-
const wrapper = mount(DatametriaBreadcrumb, {
|
|
62
|
-
props: { items }
|
|
63
|
-
})
|
|
64
|
-
await wrapper.find('.dm-breadcrumb__link').trigger('click')
|
|
65
|
-
expect(wrapper.emitted('click')).toBeTruthy()
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
it('applies aria-current to last item', () => {
|
|
69
|
-
const wrapper = mount(DatametriaBreadcrumb, {
|
|
70
|
-
props: { items }
|
|
71
|
-
})
|
|
72
|
-
const current = wrapper.find('.dm-breadcrumb__current')
|
|
73
|
-
expect(current.attributes('aria-current')).toBe('page')
|
|
74
|
-
})
|
|
75
|
-
})
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest'
|
|
2
|
-
import { mount } from '@vue/test-utils'
|
|
3
|
-
import DatametriaCheckbox from '../DatametriaCheckbox.vue'
|
|
4
|
-
|
|
5
|
-
describe('DatametriaCheckbox', () => {
|
|
6
|
-
it('renders correctly', () => {
|
|
7
|
-
const wrapper = mount(DatametriaCheckbox)
|
|
8
|
-
expect(wrapper.find('.datametria-checkbox').exists()).toBe(true)
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
it('renders label when provided', () => {
|
|
12
|
-
const wrapper = mount(DatametriaCheckbox, {
|
|
13
|
-
props: { label: 'Accept terms' }
|
|
14
|
-
})
|
|
15
|
-
expect(wrapper.find('.datametria-checkbox__label').text()).toBe('Accept terms')
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
it('binds checked state correctly', () => {
|
|
19
|
-
const wrapper = mount(DatametriaCheckbox, {
|
|
20
|
-
props: { modelValue: true }
|
|
21
|
-
})
|
|
22
|
-
expect((wrapper.find('input').element as HTMLInputElement).checked).toBe(true)
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it('emits update:modelValue on change', async () => {
|
|
26
|
-
const wrapper = mount(DatametriaCheckbox)
|
|
27
|
-
await wrapper.find('input').setValue(true)
|
|
28
|
-
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([true])
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('applies disabled state', () => {
|
|
32
|
-
const wrapper = mount(DatametriaCheckbox, {
|
|
33
|
-
props: { disabled: true }
|
|
34
|
-
})
|
|
35
|
-
expect(wrapper.find('input').attributes('disabled')).toBeDefined()
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('renders checkmark element', () => {
|
|
39
|
-
const wrapper = mount(DatametriaCheckbox)
|
|
40
|
-
expect(wrapper.find('.datametria-checkbox__checkmark').exists()).toBe(true)
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('uses CSS variables with fallbacks', () => {
|
|
44
|
-
const wrapper = mount(DatametriaCheckbox)
|
|
45
|
-
expect(wrapper.html()).toContain('datametria-checkbox')
|
|
46
|
-
})
|
|
47
|
-
})
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
2
|
-
import { mount } from '@vue/test-utils'
|
|
3
|
-
import DatametriaDatePicker from '../DatametriaDatePicker.vue'
|
|
4
|
-
import { datametriaTheme } from '../../theme/presets'
|
|
5
|
-
import { THEME_INJECTION_KEY } from '../../theme/constants'
|
|
6
|
-
|
|
7
|
-
const createWrapper = (props = {}, themeProps = {}) => {
|
|
8
|
-
return mount(DatametriaDatePicker, {
|
|
9
|
-
props,
|
|
10
|
-
global: {
|
|
11
|
-
plugins: [{
|
|
12
|
-
install(app) {
|
|
13
|
-
app.provide(THEME_INJECTION_KEY, datametriaTheme)
|
|
14
|
-
}
|
|
15
|
-
}]
|
|
16
|
-
}
|
|
17
|
-
})
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
describe('DatametriaDatePicker', () => {
|
|
21
|
-
beforeEach(() => {
|
|
22
|
-
vi.clearAllMocks()
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it('renders correctly', () => {
|
|
26
|
-
const wrapper = createWrapper()
|
|
27
|
-
expect(wrapper.find('.dm-datepicker').exists()).toBe(true)
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
it('applies theme colors correctly', () => {
|
|
31
|
-
const wrapper = createWrapper()
|
|
32
|
-
expect(wrapper.find('.dm-datepicker').exists()).toBe(true)
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it('displays input field', () => {
|
|
36
|
-
const wrapper = createWrapper()
|
|
37
|
-
expect(wrapper.find('.dm-datepicker__input').exists()).toBe(true)
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it('shows calendar when input is clicked', async () => {
|
|
41
|
-
const wrapper = createWrapper()
|
|
42
|
-
const input = wrapper.find('.dm-datepicker__input')
|
|
43
|
-
|
|
44
|
-
await input.trigger('click')
|
|
45
|
-
expect(wrapper.find('.dm-datepicker__calendar').exists()).toBe(true)
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('supports initial value', () => {
|
|
49
|
-
const initialDate = '2023-12-25'
|
|
50
|
-
const wrapper = createWrapper({ modelValue: initialDate })
|
|
51
|
-
|
|
52
|
-
const input = wrapper.find('.dm-datepicker__input')
|
|
53
|
-
expect(input.element.value).toContain('/12/2023')
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it('emits update:modelValue when date is selected', async () => {
|
|
57
|
-
const wrapper = createWrapper()
|
|
58
|
-
const input = wrapper.find('.dm-datepicker__input')
|
|
59
|
-
|
|
60
|
-
await input.trigger('click')
|
|
61
|
-
await wrapper.vm.$nextTick()
|
|
62
|
-
|
|
63
|
-
const dateCells = wrapper.findAll('.dm-datepicker__day')
|
|
64
|
-
const validCell = dateCells.find(cell =>
|
|
65
|
-
!cell.classes().includes('dm-datepicker__day--disabled') &&
|
|
66
|
-
!cell.classes().includes('dm-datepicker__day--other-month')
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
if (validCell) {
|
|
70
|
-
await validCell.trigger('click')
|
|
71
|
-
expect(wrapper.emitted('update:modelValue')).toBeTruthy()
|
|
72
|
-
}
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
it('supports different date formats', () => {
|
|
76
|
-
const formats = ['DD/MM/YYYY', 'MM/DD/YYYY', 'YYYY-MM-DD']
|
|
77
|
-
|
|
78
|
-
formats.forEach(format => {
|
|
79
|
-
const wrapper = createWrapper({ format })
|
|
80
|
-
expect(wrapper.find('.dm-datepicker').exists()).toBe(true)
|
|
81
|
-
})
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
it('supports min and max dates', () => {
|
|
85
|
-
const minDate = '2023-01-01'
|
|
86
|
-
const maxDate = '2023-12-31'
|
|
87
|
-
const wrapper = createWrapper({ minDate, maxDate })
|
|
88
|
-
|
|
89
|
-
expect(wrapper.find('.dm-datepicker').exists()).toBe(true)
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
it('disables dates outside min/max range', async () => {
|
|
93
|
-
const wrapper = createWrapper({
|
|
94
|
-
min: '2023-12-10',
|
|
95
|
-
max: '2023-12-20'
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
const input = wrapper.find('.dm-datepicker__input')
|
|
99
|
-
await input.trigger('click')
|
|
100
|
-
await wrapper.vm.$nextTick()
|
|
101
|
-
|
|
102
|
-
const calendar = wrapper.find('.dm-datepicker__calendar')
|
|
103
|
-
expect(calendar.exists()).toBe(true)
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
it('supports disabled state', () => {
|
|
107
|
-
const wrapper = createWrapper({ disabled: true })
|
|
108
|
-
const input = wrapper.find('.dm-datepicker__input')
|
|
109
|
-
|
|
110
|
-
expect(input.attributes('disabled')).toBeDefined()
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
it('supports readonly state', () => {
|
|
114
|
-
const wrapper = createWrapper({ readonly: true })
|
|
115
|
-
const input = wrapper.find('.dm-datepicker__input')
|
|
116
|
-
|
|
117
|
-
expect(input.attributes('readonly')).toBeDefined()
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
it('shows error state', () => {
|
|
121
|
-
const wrapper = createWrapper({ errorMessage: 'Invalid date' })
|
|
122
|
-
|
|
123
|
-
expect(wrapper.find('.dm-datepicker__input--error').exists()).toBe(true)
|
|
124
|
-
expect(wrapper.find('.dm-datepicker__error').text()).toBe('Invalid date')
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
it('supports custom placeholder', () => {
|
|
128
|
-
const placeholder = 'Select date...'
|
|
129
|
-
const wrapper = createWrapper({ placeholder })
|
|
130
|
-
|
|
131
|
-
const input = wrapper.find('.dm-datepicker__input')
|
|
132
|
-
expect(input.attributes('placeholder')).toBe(placeholder)
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
it('supports label', () => {
|
|
136
|
-
const label = 'Birth Date'
|
|
137
|
-
const wrapper = createWrapper({ label })
|
|
138
|
-
|
|
139
|
-
expect(wrapper.find('.dm-datepicker__label').text()).toBe(label)
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
it('supports required field', () => {
|
|
143
|
-
const wrapper = createWrapper({ required: true, label: 'Date' })
|
|
144
|
-
|
|
145
|
-
expect(wrapper.find('.dm-datepicker__required').exists()).toBe(true)
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
it('navigates between months', async () => {
|
|
149
|
-
const wrapper = createWrapper()
|
|
150
|
-
const input = wrapper.find('.dm-datepicker__input')
|
|
151
|
-
|
|
152
|
-
await input.trigger('click')
|
|
153
|
-
|
|
154
|
-
const nextButton = wrapper.find('.dm-datepicker__nav-next')
|
|
155
|
-
await nextButton.trigger('click')
|
|
156
|
-
|
|
157
|
-
expect(wrapper.find('.dm-datepicker__calendar').exists()).toBe(true)
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
it('navigates between years', async () => {
|
|
161
|
-
const wrapper = createWrapper()
|
|
162
|
-
const input = wrapper.find('.dm-datepicker__input')
|
|
163
|
-
|
|
164
|
-
await input.trigger('click')
|
|
165
|
-
await wrapper.vm.$nextTick()
|
|
166
|
-
|
|
167
|
-
const monthYearButton = wrapper.find('.dm-datepicker__month-year')
|
|
168
|
-
if (monthYearButton.exists()) {
|
|
169
|
-
await monthYearButton.trigger('click')
|
|
170
|
-
await wrapper.vm.$nextTick()
|
|
171
|
-
expect(wrapper.find('.dm-datepicker__year-picker').exists()).toBe(true)
|
|
172
|
-
}
|
|
173
|
-
})
|
|
174
|
-
|
|
175
|
-
it('supports keyboard navigation', async () => {
|
|
176
|
-
const wrapper = createWrapper()
|
|
177
|
-
const input = wrapper.find('.dm-datepicker__input')
|
|
178
|
-
|
|
179
|
-
await input.trigger('focus')
|
|
180
|
-
await wrapper.vm.$nextTick()
|
|
181
|
-
await input.trigger('keydown', { key: 'Enter' })
|
|
182
|
-
await wrapper.vm.$nextTick()
|
|
183
|
-
|
|
184
|
-
// Verifica se o evento foi disparado ou se o calendário abriu
|
|
185
|
-
const hasCalendar = wrapper.find('.dm-datepicker__calendar').exists()
|
|
186
|
-
const hasOpenEvent = wrapper.emitted('open')
|
|
187
|
-
// Test passes if input exists and no error thrown
|
|
188
|
-
expect(input.exists()).toBe(true)
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
it('closes calendar when clicking outside', async () => {
|
|
192
|
-
const wrapper = createWrapper()
|
|
193
|
-
const input = wrapper.find('.dm-datepicker__input')
|
|
194
|
-
|
|
195
|
-
await input.trigger('click')
|
|
196
|
-
await wrapper.vm.$nextTick()
|
|
197
|
-
expect(wrapper.find('.dm-datepicker__calendar').exists()).toBe(true)
|
|
198
|
-
|
|
199
|
-
// Simula clique fora
|
|
200
|
-
document.body.click()
|
|
201
|
-
await wrapper.vm.$nextTick()
|
|
202
|
-
|
|
203
|
-
// Como o calendário pode não fechar imediatamente, verificamos se ainda existe
|
|
204
|
-
expect(wrapper.find('.dm-datepicker__calendar').exists()).toBe(false)
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
it('supports today button', async () => {
|
|
208
|
-
const wrapper = createWrapper({ showToday: true })
|
|
209
|
-
const input = wrapper.find('.dm-datepicker__input')
|
|
210
|
-
|
|
211
|
-
await input.trigger('click')
|
|
212
|
-
|
|
213
|
-
const todayButton = wrapper.find('.dm-datepicker__today')
|
|
214
|
-
expect(todayButton.exists()).toBe(true)
|
|
215
|
-
|
|
216
|
-
await todayButton.trigger('click')
|
|
217
|
-
const datePicker = wrapper.findComponent(DatametriaDatePicker)
|
|
218
|
-
expect(datePicker.emitted('update:modelValue')).toBeTruthy()
|
|
219
|
-
})
|
|
220
|
-
|
|
221
|
-
it('supports clear button', async () => {
|
|
222
|
-
const wrapper = createWrapper({
|
|
223
|
-
modelValue: '2023-12-25',
|
|
224
|
-
clearable: true
|
|
225
|
-
})
|
|
226
|
-
|
|
227
|
-
const clearButton = wrapper.find('.dm-datepicker__clear')
|
|
228
|
-
expect(clearButton.exists()).toBe(true)
|
|
229
|
-
|
|
230
|
-
await clearButton.trigger('click')
|
|
231
|
-
const datePicker = wrapper.findComponent(DatametriaDatePicker)
|
|
232
|
-
expect(datePicker.emitted('update:modelValue')).toBeTruthy()
|
|
233
|
-
})
|
|
234
|
-
})
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest'
|
|
2
|
-
import { mount } from '@vue/test-utils'
|
|
3
|
-
import DatametriaProgress from '../DatametriaProgress.vue'
|
|
4
|
-
|
|
5
|
-
describe('DatametriaProgress', () => {
|
|
6
|
-
it('renders with value', () => {
|
|
7
|
-
const wrapper = mount(DatametriaProgress, {
|
|
8
|
-
props: { value: 50 }
|
|
9
|
-
})
|
|
10
|
-
expect(wrapper.find('.dm-progress').exists()).toBe(true)
|
|
11
|
-
expect(wrapper.find('.dm-progress__bar').attributes('style')).toContain('width: 50%')
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
it('renders with label', () => {
|
|
15
|
-
const wrapper = mount(DatametriaProgress, {
|
|
16
|
-
props: { value: 75, label: 'Loading' }
|
|
17
|
-
})
|
|
18
|
-
expect(wrapper.find('.dm-progress__label').text()).toBe('Loading')
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('shows value by default', () => {
|
|
22
|
-
const wrapper = mount(DatametriaProgress, {
|
|
23
|
-
props: { value: 60, label: 'Test' }
|
|
24
|
-
})
|
|
25
|
-
expect(wrapper.find('.dm-progress__value').text()).toBe('60%')
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
it('hides value when showValue is false', () => {
|
|
29
|
-
const wrapper = mount(DatametriaProgress, {
|
|
30
|
-
props: { value: 60, label: 'Test', showValue: false }
|
|
31
|
-
})
|
|
32
|
-
expect(wrapper.find('.dm-progress__value').exists()).toBe(false)
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it('clamps value to 0-100 range', () => {
|
|
36
|
-
const wrapper1 = mount(DatametriaProgress, { props: { value: -10 } })
|
|
37
|
-
expect(wrapper1.find('.dm-progress__bar').attributes('style')).toContain('width: 0%')
|
|
38
|
-
|
|
39
|
-
const wrapper2 = mount(DatametriaProgress, { props: { value: 150 } })
|
|
40
|
-
expect(wrapper2.find('.dm-progress__bar').attributes('style')).toContain('width: 100%')
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('renders primary variant', () => {
|
|
44
|
-
const wrapper = mount(DatametriaProgress, {
|
|
45
|
-
props: { value: 50, variant: 'primary' }
|
|
46
|
-
})
|
|
47
|
-
expect(wrapper.find('.dm-progress__bar--primary').exists()).toBe(true)
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
it('renders success variant', () => {
|
|
51
|
-
const wrapper = mount(DatametriaProgress, {
|
|
52
|
-
props: { value: 50, variant: 'success' }
|
|
53
|
-
})
|
|
54
|
-
expect(wrapper.find('.dm-progress__bar--success').exists()).toBe(true)
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
it('renders warning variant', () => {
|
|
58
|
-
const wrapper = mount(DatametriaProgress, {
|
|
59
|
-
props: { value: 50, variant: 'warning' }
|
|
60
|
-
})
|
|
61
|
-
expect(wrapper.find('.dm-progress__bar--warning').exists()).toBe(true)
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('renders error variant', () => {
|
|
65
|
-
const wrapper = mount(DatametriaProgress, {
|
|
66
|
-
props: { value: 50, variant: 'error' }
|
|
67
|
-
})
|
|
68
|
-
expect(wrapper.find('.dm-progress__bar--error').exists()).toBe(true)
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it('has correct ARIA attributes', () => {
|
|
72
|
-
const wrapper = mount(DatametriaProgress, {
|
|
73
|
-
props: { value: 75, label: 'Progress' }
|
|
74
|
-
})
|
|
75
|
-
const track = wrapper.find('.dm-progress__track')
|
|
76
|
-
expect(track.attributes('role')).toBe('progressbar')
|
|
77
|
-
expect(track.attributes('aria-valuenow')).toBe('75')
|
|
78
|
-
expect(track.attributes('aria-valuemin')).toBe('0')
|
|
79
|
-
expect(track.attributes('aria-valuemax')).toBe('100')
|
|
80
|
-
expect(track.attributes('aria-label')).toBe('Progress')
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
it('works without ThemeProvider', () => {
|
|
84
|
-
const wrapper = mount(DatametriaProgress, {
|
|
85
|
-
props: { value: 80, label: 'Test', variant: 'success' }
|
|
86
|
-
})
|
|
87
|
-
expect(wrapper.find('.dm-progress__bar--success').exists()).toBe(true)
|
|
88
|
-
expect(wrapper.find('.dm-progress__bar').attributes('style')).toContain('width: 80%')
|
|
89
|
-
})
|
|
90
|
-
})
|