@datametria/vue-components 2.4.1 → 2.4.2

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 (35) hide show
  1. package/README.md +57 -5
  2. package/dist/index.es.js +5812 -2837
  3. package/dist/index.umd.js +670 -10
  4. package/dist/src/components/DatametriaCheckbox.vue.d.ts +2 -0
  5. package/dist/src/components/DatametriaCheckboxGroup.vue.d.ts +6 -0
  6. package/dist/src/components/DatametriaFileUpload.vue.d.ts +5 -0
  7. package/dist/src/components/DatametriaFloatingBar.vue.d.ts +1 -1
  8. package/dist/src/components/DatametriaInput.vue.d.ts +2 -22
  9. package/dist/src/components/DatametriaNavbar.vue.d.ts +1 -1
  10. package/dist/src/components/DatametriaPasswordInput.vue.d.ts +2 -0
  11. package/dist/src/components/DatametriaRadio.vue.d.ts +2 -0
  12. package/dist/src/components/DatametriaRadioGroup.vue.d.ts +6 -0
  13. package/dist/src/components/DatametriaSelect.vue.d.ts +2 -3
  14. package/dist/src/components/DatametriaSidebar.vue.d.ts +1 -1
  15. package/dist/src/components/DatametriaSwitch.vue.d.ts +8 -1
  16. package/dist/src/components/DatametriaTabs.vue.d.ts +2 -2
  17. package/dist/src/components/DatametriaTextarea.vue.d.ts +6 -0
  18. package/dist/src/composables/useAnalytics.d.ts +8 -0
  19. package/dist/src/types/analytics.d.ts +50 -0
  20. package/dist/vue-components.css +1 -1
  21. package/package.json +3 -2
  22. package/src/components/DatametriaButton.vue +196 -195
  23. package/src/components/DatametriaCheckbox.vue +289 -197
  24. package/src/components/DatametriaCheckboxGroup.vue +124 -3
  25. package/src/components/DatametriaFileUpload.vue +493 -414
  26. package/src/components/DatametriaInput.vue +342 -316
  27. package/src/components/DatametriaPasswordInput.vue +433 -446
  28. package/src/components/DatametriaRadio.vue +240 -151
  29. package/src/components/DatametriaRadioGroup.vue +124 -3
  30. package/src/components/DatametriaSelect.vue +409 -313
  31. package/src/components/DatametriaSwitch.vue +319 -146
  32. package/src/components/DatametriaTabs.vue +2 -2
  33. package/src/components/DatametriaTextarea.vue +285 -213
  34. package/src/composables/useAnalytics.ts +70 -0
  35. package/src/types/analytics.ts +59 -0
@@ -1,199 +1,291 @@
1
- <template>
2
- <label
3
- class="datametria-checkbox"
4
- :class="{
5
- 'is-checked': isChecked,
6
- 'is-disabled': disabled,
7
- 'is-indeterminate': indeterminate
8
- }"
9
- >
10
- <span class="datametria-checkbox__input">
11
- <input
12
- ref="inputRef"
13
- type="checkbox"
14
- :checked="isChecked"
15
- :disabled="disabled"
16
- :indeterminate="indeterminate"
17
- @change="handleChange"
18
- />
19
- <span class="datametria-checkbox__inner"></span>
20
- </span>
21
- <span v-if="label || $slots.default" class="datametria-checkbox__label">
22
- <slot>{{ label }}</slot>
23
- </span>
24
- </label>
25
- </template>
26
-
27
- <script setup lang="ts">
28
- import { ref, computed, watch, inject } from 'vue'
29
-
30
- interface Props {
31
- modelValue?: boolean | string | number
32
- label?: string
33
- disabled?: boolean
34
- indeterminate?: boolean
35
- trueValue?: boolean | string | number
36
- falseValue?: boolean | string | number
37
- }
38
-
39
- const props = withDefaults(defineProps<Props>(), {
40
- modelValue: false,
41
- disabled: false,
42
- indeterminate: false,
43
- trueValue: true,
44
- falseValue: false
45
- })
46
-
47
- const emit = defineEmits<{
48
- 'update:modelValue': [value: boolean | string | number | (string | number)[]]
49
- change: [value: boolean | string | number | (string | number)[]]
50
- }>()
51
-
52
- const inputRef = ref<HTMLInputElement>()
53
- const checkboxGroup = inject<any>('checkboxGroup', null)
54
-
55
- const isChecked = computed(() => {
56
- if (checkboxGroup) {
57
- return checkboxGroup.modelValue.value.includes(props.modelValue)
58
- }
59
- return props.modelValue === props.trueValue
60
- })
61
-
62
- const handleChange = (e: Event) => {
63
- if (props.disabled) return
64
-
65
- const target = e.target as HTMLInputElement
66
- const checked = target.checked
67
-
68
- if (checkboxGroup) {
69
- const value = [...checkboxGroup.modelValue.value]
70
- if (checked) {
71
- value.push(props.modelValue)
72
- } else {
73
- const index = value.indexOf(props.modelValue)
74
- if (index > -1) value.splice(index, 1)
75
- }
76
- checkboxGroup.updateValue(value)
77
- emit('update:modelValue', value)
78
- emit('change', value)
79
- } else {
80
- const newValue = checked ? props.trueValue : props.falseValue
81
- emit('update:modelValue', newValue)
82
- emit('change', newValue)
83
- }
84
- }
85
-
86
- watch(() => props.indeterminate, (val) => {
87
- if (inputRef.value) {
88
- inputRef.value.indeterminate = val
89
- }
90
- }, { immediate: true })
91
-
92
- defineExpose({
93
- inputRef
94
- })
95
- </script>
96
-
97
- <style scoped>
98
- .datametria-checkbox {
99
- display: inline-flex;
100
- align-items: center;
101
- cursor: pointer;
102
- user-select: none;
103
- font-size: var(--dm-font-size-base, 14px);
104
- color: var(--dm-text-primary, #333);
105
- }
106
-
107
- .datametria-checkbox.is-disabled {
108
- cursor: not-allowed;
109
- opacity: 0.5;
110
- }
111
-
112
- .datametria-checkbox__input {
113
- position: relative;
114
- display: inline-block;
115
- width: 16px;
116
- height: 16px;
117
- }
118
-
119
- .datametria-checkbox__input input {
120
- position: absolute;
121
- opacity: 0;
122
- width: 100%;
123
- height: 100%;
124
- cursor: pointer;
125
- z-index: 1;
126
- }
127
-
128
- .datametria-checkbox__input input:disabled {
129
- cursor: not-allowed;
130
- }
131
-
132
- .datametria-checkbox__inner {
133
- position: absolute;
134
- top: 0;
135
- left: 0;
136
- width: 16px;
137
- height: 16px;
138
- border: 1px solid var(--dm-border-color, #dcdfe6);
139
- border-radius: var(--dm-border-radius-small, 2px);
140
- background-color: var(--dm-bg-color, #fff);
141
- transition: all 0.2s;
142
- }
143
-
144
- .datametria-checkbox.is-checked .datametria-checkbox__inner {
145
- background-color: var(--dm-primary, #0072ce);
146
- border-color: var(--dm-primary, #0072ce);
147
- }
148
-
149
- .datametria-checkbox.is-checked .datametria-checkbox__inner::after {
150
- content: '';
151
- position: absolute;
152
- top: 2px;
153
- left: 5px;
154
- width: 4px;
155
- height: 8px;
156
- border: 2px solid #fff;
157
- border-top: 0;
158
- border-left: 0;
159
- transform: rotate(45deg);
160
- }
161
-
162
- .datametria-checkbox.is-indeterminate .datametria-checkbox__inner {
163
- background-color: var(--dm-primary, #0072ce);
164
- border-color: var(--dm-primary, #0072ce);
165
- }
166
-
167
- .datametria-checkbox.is-indeterminate .datametria-checkbox__inner::after {
168
- content: '';
169
- position: absolute;
170
- top: 6px;
171
- left: 3px;
172
- width: 8px;
173
- height: 2px;
174
- background-color: #fff;
175
- transform: none;
176
- border: none;
177
- }
178
-
179
- .datametria-checkbox__label {
180
- margin-left: 8px;
181
- line-height: 1;
182
- }
183
-
184
- /* Dark mode */
185
- @media (prefers-color-scheme: dark) {
186
- .datametria-checkbox {
187
- color: var(--dm-text-primary-dark, #e0e0e0);
1
+ <template>
2
+ <label
3
+ class="datametria-checkbox"
4
+ :class="checkboxClasses"
5
+ >
6
+ <span class="datametria-checkbox__input">
7
+ <input
8
+ :id="checkboxId"
9
+ ref="inputRef"
10
+ type="checkbox"
11
+ :checked="isChecked"
12
+ :disabled="disabled"
13
+ :indeterminate="indeterminate"
14
+ :aria-label="label"
15
+ :aria-checked="indeterminate ? 'mixed' : isChecked"
16
+ :aria-disabled="disabled"
17
+ @change="handleChange"
18
+ />
19
+ <span class="datametria-checkbox__inner"></span>
20
+ </span>
21
+ <span v-if="label || $slots.default" class="datametria-checkbox__label">
22
+ <slot>{{ label }}</slot>
23
+ </span>
24
+ </label>
25
+ </template>
26
+
27
+ <script setup lang="ts">
28
+ import { ref, computed, watch, inject } from 'vue'
29
+ import { useAnalytics } from '@/composables/useAnalytics'
30
+
31
+ interface Props {
32
+ modelValue?: boolean | string | number
33
+ label?: string
34
+ disabled?: boolean
35
+ indeterminate?: boolean
36
+ trueValue?: boolean | string | number
37
+ falseValue?: boolean | string | number
38
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
39
+ }
40
+
41
+ const props = withDefaults(defineProps<Props>(), {
42
+ modelValue: false,
43
+ disabled: false,
44
+ indeterminate: false,
45
+ trueValue: true,
46
+ falseValue: false,
47
+ size: 'md'
48
+ })
49
+
50
+ const emit = defineEmits<{
51
+ 'update:modelValue': [value: boolean | string | number | (string | number)[]]
52
+ change: [value: boolean | string | number | (string | number)[]]
53
+ }>()
54
+
55
+ const { trackEvent } = useAnalytics()
56
+ const inputRef = ref<HTMLInputElement>()
57
+ const checkboxGroup = inject<any>('checkboxGroup', null)
58
+ const checkboxId = `datametria-checkbox-${Math.random().toString(36).substr(2, 9)}`
59
+
60
+ const isChecked = computed(() => {
61
+ if (checkboxGroup) {
62
+ return checkboxGroup.modelValue.value.includes(props.modelValue)
63
+ }
64
+ return props.modelValue === props.trueValue
65
+ })
66
+
67
+ const checkboxClasses = computed(() => ({
68
+ 'is-checked': isChecked.value,
69
+ 'is-disabled': props.disabled,
70
+ 'is-indeterminate': props.indeterminate,
71
+ [`datametria-checkbox--${props.size}`]: true
72
+ }))
73
+
74
+ const handleChange = (e: Event) => {
75
+ if (props.disabled) return
76
+
77
+ const target = e.target as HTMLInputElement
78
+ const checked = target.checked
79
+
80
+ if (checkboxGroup) {
81
+ const value = [...checkboxGroup.modelValue.value]
82
+ if (checked) {
83
+ value.push(props.modelValue)
84
+ } else {
85
+ const index = value.indexOf(props.modelValue)
86
+ if (index > -1) value.splice(index, 1)
87
+ }
88
+ checkboxGroup.updateValue(value)
89
+ emit('update:modelValue', value)
90
+ emit('change', value)
91
+ } else {
92
+ const newValue = checked ? props.trueValue : props.falseValue
93
+ emit('update:modelValue', newValue)
94
+ emit('change', newValue)
188
95
  }
189
96
 
190
- [data-theme="dark"] .datametria-checkbox {
191
- color: var(--dm-text-primary-dark, #e0e0e0);
192
- }
193
-
194
- .datametria-checkbox__inner {
195
- border-color: var(--dm-border-color-dark, #4a4a4a);
196
- background-color: var(--dm-bg-color-dark, #1e1e1e);
197
- }
198
- }
199
- </style>
97
+ trackEvent('checkbox_change', {
98
+ component: 'DatametriaCheckbox',
99
+ checked,
100
+ size: props.size
101
+ })
102
+ }
103
+
104
+ watch(() => props.indeterminate, (val) => {
105
+ if (inputRef.value) {
106
+ inputRef.value.indeterminate = val
107
+ }
108
+ }, { immediate: true })
109
+
110
+ defineExpose({
111
+ inputRef
112
+ })
113
+ </script>
114
+
115
+ <style scoped>
116
+ .datametria-checkbox {
117
+ display: inline-flex;
118
+ align-items: center;
119
+ cursor: pointer;
120
+ user-select: none;
121
+ font-size: 14px;
122
+ color: var(--color-text-primary, #1f2937);
123
+ touch-action: manipulation;
124
+ -webkit-tap-highlight-color: transparent;
125
+ }
126
+
127
+ .datametria-checkbox.is-disabled {
128
+ cursor: not-allowed;
129
+ opacity: 0.6;
130
+ }
131
+
132
+ .datametria-checkbox__input {
133
+ position: relative;
134
+ display: inline-block;
135
+ min-width: 44px;
136
+ min-height: 44px;
137
+ display: flex;
138
+ align-items: center;
139
+ justify-content: center;
140
+ }
141
+
142
+ .datametria-checkbox__input input {
143
+ position: absolute;
144
+ opacity: 0;
145
+ width: 100%;
146
+ height: 100%;
147
+ cursor: pointer;
148
+ z-index: 1;
149
+ }
150
+
151
+ .datametria-checkbox__input input:disabled {
152
+ cursor: not-allowed;
153
+ }
154
+
155
+ .datametria-checkbox__input input:focus-visible + .datametria-checkbox__inner {
156
+ outline: none;
157
+ box-shadow: 0 0 0 3px var(--color-primary-alpha, rgba(59, 130, 246, 0.1));
158
+ }
159
+
160
+ .datametria-checkbox__inner {
161
+ position: relative;
162
+ width: 16px;
163
+ height: 16px;
164
+ border: 1px solid var(--color-border, #d1d5db);
165
+ border-radius: 2px;
166
+ background-color: var(--color-background, #fff);
167
+ transition: all 0.2s;
168
+ }
169
+
170
+ .datametria-checkbox.is-checked .datametria-checkbox__inner {
171
+ background-color: var(--color-primary, #3b82f6);
172
+ border-color: var(--color-primary, #3b82f6);
173
+ }
174
+
175
+ .datametria-checkbox.is-checked .datametria-checkbox__inner::after {
176
+ content: '';
177
+ position: absolute;
178
+ top: 2px;
179
+ left: 5px;
180
+ width: 4px;
181
+ height: 8px;
182
+ border: 2px solid #fff;
183
+ border-top: 0;
184
+ border-left: 0;
185
+ transform: rotate(45deg);
186
+ }
187
+
188
+ .datametria-checkbox.is-indeterminate .datametria-checkbox__inner {
189
+ background-color: var(--color-primary, #3b82f6);
190
+ border-color: var(--color-primary, #3b82f6);
191
+ }
192
+
193
+ .datametria-checkbox.is-indeterminate .datametria-checkbox__inner::after {
194
+ content: '';
195
+ position: absolute;
196
+ top: 6px;
197
+ left: 3px;
198
+ width: 8px;
199
+ height: 2px;
200
+ background-color: #fff;
201
+ transform: none;
202
+ border: none;
203
+ }
204
+
205
+ .datametria-checkbox__label {
206
+ margin-left: 8px;
207
+ line-height: 1.5;
208
+ }
209
+
210
+ /* Tamanhos */
211
+ .datametria-checkbox--xs .datametria-checkbox__inner {
212
+ width: 12px;
213
+ height: 12px;
214
+ }
215
+
216
+ .datametria-checkbox--xs.is-checked .datametria-checkbox__inner::after {
217
+ top: 1px;
218
+ left: 3px;
219
+ width: 3px;
220
+ height: 6px;
221
+ }
222
+
223
+ .datametria-checkbox--xs .datametria-checkbox__label {
224
+ font-size: 11px;
225
+ }
226
+
227
+ .datametria-checkbox--sm .datametria-checkbox__inner {
228
+ width: 14px;
229
+ height: 14px;
230
+ }
231
+
232
+ .datametria-checkbox--sm.is-checked .datametria-checkbox__inner::after {
233
+ top: 1px;
234
+ left: 4px;
235
+ width: 3px;
236
+ height: 7px;
237
+ }
238
+
239
+ .datametria-checkbox--sm .datametria-checkbox__label {
240
+ font-size: 12px;
241
+ }
242
+
243
+ .datametria-checkbox--md .datametria-checkbox__inner {
244
+ width: 16px;
245
+ height: 16px;
246
+ }
247
+
248
+ .datametria-checkbox--md .datametria-checkbox__label {
249
+ font-size: 14px;
250
+ }
251
+
252
+ .datametria-checkbox--lg .datametria-checkbox__inner {
253
+ width: 18px;
254
+ height: 18px;
255
+ }
256
+
257
+ .datametria-checkbox--lg.is-checked .datametria-checkbox__inner::after {
258
+ top: 2px;
259
+ left: 6px;
260
+ width: 5px;
261
+ height: 9px;
262
+ }
263
+
264
+ .datametria-checkbox--lg .datametria-checkbox__label {
265
+ font-size: 16px;
266
+ }
267
+
268
+ .datametria-checkbox--xl .datametria-checkbox__inner {
269
+ width: 20px;
270
+ height: 20px;
271
+ }
272
+
273
+ .datametria-checkbox--xl.is-checked .datametria-checkbox__inner::after {
274
+ top: 3px;
275
+ left: 7px;
276
+ width: 5px;
277
+ height: 10px;
278
+ }
279
+
280
+ .datametria-checkbox--xl .datametria-checkbox__label {
281
+ font-size: 18px;
282
+ }
283
+
284
+ /* Responsividade mobile */
285
+ @media (max-width: 640px) {
286
+ .datametria-checkbox__input {
287
+ min-width: 48px;
288
+ min-height: 48px;
289
+ }
290
+ }
291
+ </style>
@@ -1,20 +1,48 @@
1
1
  <template>
2
- <div class="datametria-checkbox-group" role="group">
3
- <slot></slot>
2
+ <div
3
+ class="datametria-checkbox-group"
4
+ :class="groupClasses"
5
+ role="group"
6
+ :aria-label="label"
7
+ :aria-disabled="disabled"
8
+ >
9
+ <label v-if="label" class="datametria-checkbox-group__label">
10
+ {{ label }}
11
+ <span v-if="required" class="datametria-checkbox-group__required">*</span>
12
+ </label>
13
+ <div class="datametria-checkbox-group__content">
14
+ <slot></slot>
15
+ </div>
16
+ <div
17
+ v-if="errorMessage"
18
+ :id="`${groupId}-error`"
19
+ role="alert"
20
+ aria-live="polite"
21
+ class="datametria-checkbox-group__error"
22
+ >
23
+ {{ errorMessage }}
24
+ </div>
4
25
  </div>
5
26
  </template>
6
27
 
7
28
  <script setup lang="ts">
8
29
  import { provide, computed } from 'vue'
30
+ import { useAnalytics } from '@/composables/useAnalytics'
9
31
 
10
32
  interface Props {
11
33
  modelValue?: (string | number)[]
12
34
  disabled?: boolean
35
+ label?: string
36
+ required?: boolean
37
+ errorMessage?: string
38
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
13
39
  }
14
40
 
15
41
  const props = withDefaults(defineProps<Props>(), {
16
42
  modelValue: () => [],
17
- disabled: false
43
+ disabled: false,
44
+ required: false,
45
+ size: 'md'
18
46
  })
19
47
 
20
48
  const emit = defineEmits<{
@@ -22,9 +50,24 @@ const emit = defineEmits<{
22
50
  change: [value: (string | number)[]]
23
51
  }>()
24
52
 
53
+ const { trackEvent } = useAnalytics()
54
+ const groupId = `datametria-checkbox-group-${Math.random().toString(36).substr(2, 9)}`
55
+
56
+ const groupClasses = computed(() => ({
57
+ 'is-disabled': props.disabled,
58
+ 'is-error': !!props.errorMessage,
59
+ [`datametria-checkbox-group--${props.size}`]: true
60
+ }))
61
+
25
62
  const updateValue = (value: (string | number)[]) => {
26
63
  emit('update:modelValue', value)
27
64
  emit('change', value)
65
+
66
+ trackEvent('checkbox_group_change', {
67
+ component: 'DatametriaCheckboxGroup',
68
+ selectedCount: value.length,
69
+ size: props.size
70
+ })
28
71
  }
29
72
 
30
73
  provide('checkboxGroup', {
@@ -36,8 +79,86 @@ provide('checkboxGroup', {
36
79
 
37
80
  <style scoped>
38
81
  .datametria-checkbox-group {
82
+ display: inline-flex;
83
+ flex-direction: column;
84
+ width: 100%;
85
+ }
86
+
87
+ .datametria-checkbox-group__label {
88
+ display: block;
89
+ margin-bottom: 8px;
90
+ font-size: 14px;
91
+ font-weight: 500;
92
+ color: var(--color-text-primary, #1f2937);
93
+ }
94
+
95
+ .datametria-checkbox-group__required {
96
+ color: var(--color-error, #ef4444);
97
+ margin-left: 2px;
98
+ }
99
+
100
+ .datametria-checkbox-group__content {
39
101
  display: inline-flex;
40
102
  flex-wrap: wrap;
41
103
  gap: 12px;
42
104
  }
105
+
106
+ .datametria-checkbox-group__error {
107
+ margin-top: 4px;
108
+ font-size: 12px;
109
+ color: var(--color-error, #ef4444);
110
+ }
111
+
112
+ .datametria-checkbox-group.is-disabled {
113
+ opacity: 0.6;
114
+ cursor: not-allowed;
115
+ }
116
+
117
+ /* Tamanhos */
118
+ .datametria-checkbox-group--xs .datametria-checkbox-group__content {
119
+ gap: 8px;
120
+ }
121
+
122
+ .datametria-checkbox-group--xs .datametria-checkbox-group__label {
123
+ font-size: 11px;
124
+ }
125
+
126
+ .datametria-checkbox-group--sm .datametria-checkbox-group__content {
127
+ gap: 10px;
128
+ }
129
+
130
+ .datametria-checkbox-group--sm .datametria-checkbox-group__label {
131
+ font-size: 12px;
132
+ }
133
+
134
+ .datametria-checkbox-group--md .datametria-checkbox-group__content {
135
+ gap: 12px;
136
+ }
137
+
138
+ .datametria-checkbox-group--md .datametria-checkbox-group__label {
139
+ font-size: 14px;
140
+ }
141
+
142
+ .datametria-checkbox-group--lg .datametria-checkbox-group__content {
143
+ gap: 14px;
144
+ }
145
+
146
+ .datametria-checkbox-group--lg .datametria-checkbox-group__label {
147
+ font-size: 16px;
148
+ }
149
+
150
+ .datametria-checkbox-group--xl .datametria-checkbox-group__content {
151
+ gap: 16px;
152
+ }
153
+
154
+ .datametria-checkbox-group--xl .datametria-checkbox-group__label {
155
+ font-size: 18px;
156
+ }
157
+
158
+ /* Responsividade mobile */
159
+ @media (max-width: 640px) {
160
+ .datametria-checkbox-group__content {
161
+ gap: 16px;
162
+ }
163
+ }
43
164
  </style>