@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,153 +1,242 @@
1
- <template>
2
- <label
3
- class="datametria-radio"
4
- :class="{
5
- 'is-checked': isChecked,
6
- 'is-disabled': disabled
7
- }"
8
- >
9
- <span class="datametria-radio__input">
10
- <input
11
- ref="inputRef"
12
- type="radio"
13
- :checked="isChecked"
14
- :disabled="disabled"
15
- :value="modelValue"
16
- @change="handleChange"
17
- />
18
- <span class="datametria-radio__inner"></span>
19
- </span>
20
- <span v-if="label || $slots.default" class="datametria-radio__label">
21
- <slot>{{ label }}</slot>
22
- </span>
23
- </label>
24
- </template>
25
-
26
- <script setup lang="ts">
27
- import { ref, computed, inject } from 'vue'
28
-
29
- interface Props {
30
- modelValue?: string | number | boolean
31
- label?: string
32
- disabled?: boolean
33
- }
34
-
35
- const props = withDefaults(defineProps<Props>(), {
36
- disabled: false
37
- })
38
-
39
- const emit = defineEmits<{
40
- 'update:modelValue': [value: string | number | boolean]
41
- change: [value: string | number | boolean]
42
- }>()
43
-
44
- const inputRef = ref<HTMLInputElement>()
45
- const radioGroup = inject<any>('radioGroup', null)
46
-
47
- const isChecked = computed(() => {
48
- if (radioGroup) {
49
- return radioGroup.modelValue.value === props.modelValue
50
- }
51
- return false
52
- })
53
-
54
- const handleChange = () => {
55
- if (props.disabled) return
56
-
57
- if (radioGroup) {
58
- radioGroup.updateValue(props.modelValue)
59
- }
60
-
61
- emit('update:modelValue', props.modelValue!)
62
- emit('change', props.modelValue!)
63
- }
64
-
65
- defineExpose({
66
- inputRef
67
- })
68
- </script>
69
-
70
- <style scoped>
71
- .datametria-radio {
72
- display: inline-flex;
73
- align-items: center;
74
- cursor: pointer;
75
- user-select: none;
76
- font-size: var(--dm-font-size-base, 14px);
77
- color: var(--dm-text-primary, #333);
78
- }
79
-
80
- .datametria-radio.is-disabled {
81
- cursor: not-allowed;
82
- opacity: 0.5;
83
- }
84
-
85
- .datametria-radio__input {
86
- position: relative;
87
- display: inline-block;
88
- width: 16px;
89
- height: 16px;
90
- }
91
-
92
- .datametria-radio__input input {
93
- position: absolute;
94
- opacity: 0;
95
- width: 100%;
96
- height: 100%;
97
- cursor: pointer;
98
- z-index: 1;
99
- }
100
-
101
- .datametria-radio__input input:disabled {
102
- cursor: not-allowed;
103
- }
104
-
105
- .datametria-radio__inner {
106
- position: absolute;
107
- top: 0;
108
- left: 0;
109
- width: 16px;
110
- height: 16px;
111
- border: 1px solid var(--dm-border-color, #dcdfe6);
112
- border-radius: 50%;
113
- background-color: var(--dm-bg-color, #fff);
114
- transition: all 0.2s;
115
- }
116
-
117
- .datametria-radio.is-checked .datametria-radio__inner {
118
- border-color: var(--dm-primary, #0072ce);
119
- }
120
-
121
- .datametria-radio.is-checked .datametria-radio__inner::after {
122
- content: '';
123
- position: absolute;
124
- top: 50%;
125
- left: 50%;
126
- width: 8px;
127
- height: 8px;
128
- border-radius: 50%;
129
- background-color: var(--dm-primary, #0072ce);
130
- transform: translate(-50%, -50%);
131
- }
132
-
133
- .datametria-radio__label {
134
- margin-left: 8px;
135
- line-height: 1;
136
- }
137
-
138
- /* Dark mode */
139
- @media (prefers-color-scheme: dark) {
140
- .datametria-radio {
141
- color: var(--dm-text-primary-dark, #e0e0e0);
1
+ <template>
2
+ <label
3
+ class="datametria-radio"
4
+ :class="radioClasses"
5
+ >
6
+ <span class="datametria-radio__input">
7
+ <input
8
+ :id="radioId"
9
+ ref="inputRef"
10
+ type="radio"
11
+ :checked="isChecked"
12
+ :disabled="disabled"
13
+ :value="modelValue"
14
+ :aria-label="label"
15
+ :aria-checked="isChecked"
16
+ :aria-disabled="disabled"
17
+ @change="handleChange"
18
+ />
19
+ <span class="datametria-radio__inner"></span>
20
+ </span>
21
+ <span v-if="label || $slots.default" class="datametria-radio__label">
22
+ <slot>{{ label }}</slot>
23
+ </span>
24
+ </label>
25
+ </template>
26
+
27
+ <script setup lang="ts">
28
+ import { ref, computed, inject } from 'vue'
29
+ import { useAnalytics } from '@/composables/useAnalytics'
30
+
31
+ interface Props {
32
+ modelValue?: string | number | boolean
33
+ label?: string
34
+ disabled?: boolean
35
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
36
+ }
37
+
38
+ const props = withDefaults(defineProps<Props>(), {
39
+ disabled: false,
40
+ size: 'md'
41
+ })
42
+
43
+ const emit = defineEmits<{
44
+ 'update:modelValue': [value: string | number | boolean]
45
+ change: [value: string | number | boolean]
46
+ }>()
47
+
48
+ const { trackEvent } = useAnalytics()
49
+ const inputRef = ref<HTMLInputElement>()
50
+ const radioGroup = inject<any>('radioGroup', null)
51
+ const radioId = `datametria-radio-${Math.random().toString(36).substr(2, 9)}`
52
+
53
+ const isChecked = computed(() => {
54
+ if (radioGroup) {
55
+ return radioGroup.modelValue.value === props.modelValue
56
+ }
57
+ return false
58
+ })
59
+
60
+ const radioClasses = computed(() => ({
61
+ 'is-checked': isChecked.value,
62
+ 'is-disabled': props.disabled,
63
+ [`datametria-radio--${props.size}`]: true
64
+ }))
65
+
66
+ const handleChange = () => {
67
+ if (props.disabled) return
68
+
69
+ if (radioGroup) {
70
+ radioGroup.updateValue(props.modelValue)
142
71
  }
72
+
73
+ emit('update:modelValue', props.modelValue!)
74
+ emit('change', props.modelValue!)
75
+
76
+ trackEvent('radio_change', {
77
+ component: 'DatametriaRadio',
78
+ value: props.modelValue,
79
+ size: props.size
80
+ })
81
+ }
82
+
83
+ defineExpose({
84
+ inputRef
85
+ })
86
+ </script>
87
+
88
+ <style scoped>
89
+ .datametria-radio {
90
+ display: inline-flex;
91
+ align-items: center;
92
+ cursor: pointer;
93
+ user-select: none;
94
+ font-size: 14px;
95
+ color: var(--color-text-primary, #1f2937);
96
+ touch-action: manipulation;
97
+ -webkit-tap-highlight-color: transparent;
98
+ }
99
+
100
+ .datametria-radio.is-disabled {
101
+ cursor: not-allowed;
102
+ opacity: 0.6;
103
+ }
104
+
105
+ .datametria-radio__input {
106
+ position: relative;
107
+ display: inline-block;
108
+ min-width: 44px;
109
+ min-height: 44px;
110
+ display: flex;
111
+ align-items: center;
112
+ justify-content: center;
113
+ }
114
+
115
+ .datametria-radio__input input {
116
+ position: absolute;
117
+ opacity: 0;
118
+ width: 100%;
119
+ height: 100%;
120
+ cursor: pointer;
121
+ z-index: 1;
122
+ }
123
+
124
+ .datametria-radio__input input:disabled {
125
+ cursor: not-allowed;
126
+ }
127
+
128
+ .datametria-radio__input input:focus-visible + .datametria-radio__inner {
129
+ outline: none;
130
+ box-shadow: 0 0 0 3px var(--color-primary-alpha, rgba(59, 130, 246, 0.1));
131
+ }
132
+
133
+ .datametria-radio__inner {
134
+ position: relative;
135
+ width: 16px;
136
+ height: 16px;
137
+ border: 1px solid var(--color-border, #d1d5db);
138
+ border-radius: 50%;
139
+ background-color: var(--color-background, #fff);
140
+ transition: all 0.2s;
141
+ }
143
142
 
144
- [data-theme="dark"] .datametria-radio {
145
- color: var(--dm-text-primary-dark, #e0e0e0);
146
- }
147
-
148
- .datametria-radio__inner {
149
- border-color: var(--dm-border-color-dark, #4a4a4a);
150
- background-color: var(--dm-bg-color-dark, #1e1e1e);
151
- }
152
- }
153
- </style>
143
+ .datametria-radio.is-checked .datametria-radio__inner {
144
+ border-color: var(--color-primary, #3b82f6);
145
+ }
146
+
147
+ .datametria-radio.is-checked .datametria-radio__inner::after {
148
+ content: '';
149
+ position: absolute;
150
+ top: 50%;
151
+ left: 50%;
152
+ width: 8px;
153
+ height: 8px;
154
+ border-radius: 50%;
155
+ background-color: var(--color-primary, #3b82f6);
156
+ transform: translate(-50%, -50%);
157
+ }
158
+
159
+ .datametria-radio__label {
160
+ margin-left: 8px;
161
+ line-height: 1.5;
162
+ }
163
+
164
+ /* Tamanhos */
165
+ .datametria-radio--xs .datametria-radio__inner {
166
+ width: 12px;
167
+ height: 12px;
168
+ }
169
+
170
+ .datametria-radio--xs.is-checked .datametria-radio__inner::after {
171
+ width: 6px;
172
+ height: 6px;
173
+ }
174
+
175
+ .datametria-radio--xs .datametria-radio__label {
176
+ font-size: 11px;
177
+ }
178
+
179
+ .datametria-radio--sm .datametria-radio__inner {
180
+ width: 14px;
181
+ height: 14px;
182
+ }
183
+
184
+ .datametria-radio--sm.is-checked .datametria-radio__inner::after {
185
+ width: 7px;
186
+ height: 7px;
187
+ }
188
+
189
+ .datametria-radio--sm .datametria-radio__label {
190
+ font-size: 12px;
191
+ }
192
+
193
+ .datametria-radio--md .datametria-radio__inner {
194
+ width: 16px;
195
+ height: 16px;
196
+ }
197
+
198
+ .datametria-radio--md.is-checked .datametria-radio__inner::after {
199
+ width: 8px;
200
+ height: 8px;
201
+ }
202
+
203
+ .datametria-radio--md .datametria-radio__label {
204
+ font-size: 14px;
205
+ }
206
+
207
+ .datametria-radio--lg .datametria-radio__inner {
208
+ width: 18px;
209
+ height: 18px;
210
+ }
211
+
212
+ .datametria-radio--lg.is-checked .datametria-radio__inner::after {
213
+ width: 9px;
214
+ height: 9px;
215
+ }
216
+
217
+ .datametria-radio--lg .datametria-radio__label {
218
+ font-size: 16px;
219
+ }
220
+
221
+ .datametria-radio--xl .datametria-radio__inner {
222
+ width: 20px;
223
+ height: 20px;
224
+ }
225
+
226
+ .datametria-radio--xl.is-checked .datametria-radio__inner::after {
227
+ width: 10px;
228
+ height: 10px;
229
+ }
230
+
231
+ .datametria-radio--xl .datametria-radio__label {
232
+ font-size: 18px;
233
+ }
234
+
235
+ /* Responsividade mobile */
236
+ @media (max-width: 640px) {
237
+ .datametria-radio__input {
238
+ min-width: 48px;
239
+ min-height: 48px;
240
+ }
241
+ }
242
+ </style>
@@ -1,19 +1,47 @@
1
1
  <template>
2
- <div class="datametria-radio-group" role="radiogroup">
3
- <slot></slot>
2
+ <div
3
+ class="datametria-radio-group"
4
+ :class="groupClasses"
5
+ role="radiogroup"
6
+ :aria-label="label"
7
+ :aria-disabled="disabled"
8
+ >
9
+ <label v-if="label" class="datametria-radio-group__label">
10
+ {{ label }}
11
+ <span v-if="required" class="datametria-radio-group__required">*</span>
12
+ </label>
13
+ <div class="datametria-radio-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-radio-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 | boolean
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
- disabled: false
42
+ disabled: false,
43
+ required: false,
44
+ size: 'md'
17
45
  })
18
46
 
19
47
  const emit = defineEmits<{
@@ -21,9 +49,24 @@ const emit = defineEmits<{
21
49
  change: [value: string | number | boolean]
22
50
  }>()
23
51
 
52
+ const { trackEvent } = useAnalytics()
53
+ const groupId = `datametria-radio-group-${Math.random().toString(36).substr(2, 9)}`
54
+
55
+ const groupClasses = computed(() => ({
56
+ 'is-disabled': props.disabled,
57
+ 'is-error': !!props.errorMessage,
58
+ [`datametria-radio-group--${props.size}`]: true
59
+ }))
60
+
24
61
  const updateValue = (value: string | number | boolean) => {
25
62
  emit('update:modelValue', value)
26
63
  emit('change', value)
64
+
65
+ trackEvent('radio_group_change', {
66
+ component: 'DatametriaRadioGroup',
67
+ value,
68
+ size: props.size
69
+ })
27
70
  }
28
71
 
29
72
  provide('radioGroup', {
@@ -35,8 +78,86 @@ provide('radioGroup', {
35
78
 
36
79
  <style scoped>
37
80
  .datametria-radio-group {
81
+ display: inline-flex;
82
+ flex-direction: column;
83
+ width: 100%;
84
+ }
85
+
86
+ .datametria-radio-group__label {
87
+ display: block;
88
+ margin-bottom: 8px;
89
+ font-size: 14px;
90
+ font-weight: 500;
91
+ color: var(--color-text-primary, #1f2937);
92
+ }
93
+
94
+ .datametria-radio-group__required {
95
+ color: var(--color-error, #ef4444);
96
+ margin-left: 2px;
97
+ }
98
+
99
+ .datametria-radio-group__content {
38
100
  display: inline-flex;
39
101
  flex-wrap: wrap;
40
102
  gap: 12px;
41
103
  }
104
+
105
+ .datametria-radio-group__error {
106
+ margin-top: 4px;
107
+ font-size: 12px;
108
+ color: var(--color-error, #ef4444);
109
+ }
110
+
111
+ .datametria-radio-group.is-disabled {
112
+ opacity: 0.6;
113
+ cursor: not-allowed;
114
+ }
115
+
116
+ /* Tamanhos */
117
+ .datametria-radio-group--xs .datametria-radio-group__content {
118
+ gap: 8px;
119
+ }
120
+
121
+ .datametria-radio-group--xs .datametria-radio-group__label {
122
+ font-size: 11px;
123
+ }
124
+
125
+ .datametria-radio-group--sm .datametria-radio-group__content {
126
+ gap: 10px;
127
+ }
128
+
129
+ .datametria-radio-group--sm .datametria-radio-group__label {
130
+ font-size: 12px;
131
+ }
132
+
133
+ .datametria-radio-group--md .datametria-radio-group__content {
134
+ gap: 12px;
135
+ }
136
+
137
+ .datametria-radio-group--md .datametria-radio-group__label {
138
+ font-size: 14px;
139
+ }
140
+
141
+ .datametria-radio-group--lg .datametria-radio-group__content {
142
+ gap: 14px;
143
+ }
144
+
145
+ .datametria-radio-group--lg .datametria-radio-group__label {
146
+ font-size: 16px;
147
+ }
148
+
149
+ .datametria-radio-group--xl .datametria-radio-group__content {
150
+ gap: 16px;
151
+ }
152
+
153
+ .datametria-radio-group--xl .datametria-radio-group__label {
154
+ font-size: 18px;
155
+ }
156
+
157
+ /* Responsividade mobile */
158
+ @media (max-width: 640px) {
159
+ .datametria-radio-group__content {
160
+ gap: 16px;
161
+ }
162
+ }
42
163
  </style>