@datametria/vue-components 2.2.0 → 2.3.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 (78) hide show
  1. package/README.md +25 -7
  2. package/dist/index.es.js +3378 -2148
  3. package/dist/index.umd.js +9 -9
  4. package/dist/src/components/DatametriaAutocomplete.vue.d.ts +14 -17
  5. package/dist/src/components/DatametriaBreadcrumb.vue.d.ts +39 -7
  6. package/dist/src/components/DatametriaCheckbox.vue.d.ts +35 -6
  7. package/dist/src/components/DatametriaCheckboxGroup.vue.d.ts +30 -0
  8. package/dist/src/components/DatametriaDataTable.vue.d.ts +64 -0
  9. package/dist/src/components/DatametriaDatePicker.vue.d.ts +15 -37
  10. package/dist/src/components/DatametriaDialog.vue.d.ts +71 -0
  11. package/dist/src/components/DatametriaEmpty.vue.d.ts +30 -0
  12. package/dist/src/components/DatametriaFloatingBar.vue.d.ts +2 -2
  13. package/dist/src/components/DatametriaForm.vue.d.ts +40 -0
  14. package/dist/src/components/DatametriaFormItem.vue.d.ts +28 -0
  15. package/dist/src/components/DatametriaGrid.vue.d.ts +1 -1
  16. package/dist/src/components/DatametriaInput.vue.d.ts +69 -10
  17. package/dist/src/components/DatametriaMenu.vue.d.ts +3 -3
  18. package/dist/src/components/DatametriaNavbar.vue.d.ts +2 -2
  19. package/dist/src/components/DatametriaPagination.vue.d.ts +29 -0
  20. package/dist/src/components/DatametriaPopconfirm.vue.d.ts +43 -0
  21. package/dist/src/components/DatametriaProgress.vue.d.ts +33 -8
  22. package/dist/src/components/DatametriaRadio.vue.d.ts +25 -6
  23. package/dist/src/components/DatametriaRadioGroup.vue.d.ts +29 -0
  24. package/dist/src/components/DatametriaResult.vue.d.ts +30 -0
  25. package/dist/src/components/DatametriaSelect.vue.d.ts +16 -11
  26. package/dist/src/components/DatametriaSidebar.vue.d.ts +3 -3
  27. package/dist/src/components/DatametriaSlider.vue.d.ts +3 -3
  28. package/dist/src/components/DatametriaSortableTable.vue.d.ts +1 -1
  29. package/dist/src/components/DatametriaSteps.vue.d.ts +45 -0
  30. package/dist/src/components/DatametriaSwitch.vue.d.ts +9 -4
  31. package/dist/src/components/DatametriaTabPane.vue.d.ts +28 -0
  32. package/dist/src/components/DatametriaTextarea.vue.d.ts +27 -8
  33. package/dist/src/components/DatametriaTimePicker.vue.d.ts +17 -25
  34. package/dist/src/components/DatametriaToast.vue.d.ts +1 -1
  35. package/dist/src/components/DatametriaTooltip.vue.d.ts +1 -1
  36. package/dist/src/components/DatametriaTree.vue.d.ts +31 -0
  37. package/dist/src/components/DatametriaTreeNode.vue.d.ts +17 -0
  38. package/dist/src/components/DatametriaUpload.vue.d.ts +64 -0
  39. package/dist/src/index.d.ts +14 -0
  40. package/dist/vue-components.css +1 -1
  41. package/package.json +4 -3
  42. package/src/components/DatametriaAutocomplete.vue +155 -260
  43. package/src/components/DatametriaBreadcrumb.vue +66 -80
  44. package/src/components/DatametriaCheckbox.vue +150 -37
  45. package/src/components/DatametriaCheckboxGroup.vue +43 -0
  46. package/src/components/DatametriaDataTable.vue +304 -0
  47. package/src/components/DatametriaDatePicker.vue +238 -614
  48. package/src/components/DatametriaDialog.vue +295 -0
  49. package/src/components/DatametriaDropdown.vue +352 -0
  50. package/src/components/DatametriaEmpty.vue +153 -0
  51. package/src/components/DatametriaForm.vue +160 -0
  52. package/src/components/DatametriaFormItem.vue +181 -0
  53. package/src/components/DatametriaInput.vue +226 -63
  54. package/src/components/DatametriaPagination.vue +373 -0
  55. package/src/components/DatametriaPopconfirm.vue +236 -0
  56. package/src/components/DatametriaProgress.vue +176 -63
  57. package/src/components/DatametriaRadio.vue +83 -72
  58. package/src/components/DatametriaRadioGroup.vue +42 -0
  59. package/src/components/DatametriaResult.vue +133 -0
  60. package/src/components/DatametriaSelect.vue +172 -67
  61. package/src/components/DatametriaSortableTable.vue +35 -4
  62. package/src/components/DatametriaSteps.vue +314 -0
  63. package/src/components/DatametriaSwitch.vue +86 -80
  64. package/src/components/DatametriaTabPane.vue +82 -0
  65. package/src/components/DatametriaTextarea.vue +140 -100
  66. package/src/components/DatametriaTimePicker.vue +231 -214
  67. package/src/components/DatametriaTree.vue +124 -0
  68. package/src/components/DatametriaTreeNode.vue +174 -0
  69. package/src/components/DatametriaUpload.vue +365 -0
  70. package/src/index.ts +25 -11
  71. package/src/components/__tests__/DatametriaAutocomplete.test.ts +0 -180
  72. package/src/components/__tests__/DatametriaBreadcrumb.test.ts +0 -75
  73. package/src/components/__tests__/DatametriaCheckbox.test.ts +0 -47
  74. package/src/components/__tests__/DatametriaDatePicker.test.ts +0 -234
  75. package/src/components/__tests__/DatametriaProgress.test.ts +0 -90
  76. package/src/components/__tests__/DatametriaRadio.test.ts +0 -77
  77. package/src/components/__tests__/DatametriaSwitch.test.ts +0 -64
  78. package/src/components/__tests__/DatametriaTextarea.test.ts +0 -66
@@ -1,102 +1,265 @@
1
1
  <template>
2
- <div class="datametria-input">
3
- <label v-if="label" :for="inputId" class="datametria-input__label">
4
- {{ label }}
5
- <span v-if="required" class="datametria-input__required">*</span>
6
- </label>
7
-
8
- <input
9
- :id="inputId"
10
- :value="modelValue"
11
- :placeholder="placeholder"
12
- :disabled="disabled"
13
- :required="required"
14
- :class="inputClasses"
15
- @input="$emit('update:modelValue', ($event.target as HTMLInputElement).value)"
16
- />
17
-
18
- <p v-if="errorMessage" class="datametria-input__error">
19
- {{ errorMessage }}
20
- </p>
2
+ <div class="datametria-input" :class="inputWrapperClasses">
3
+ <div v-if="$slots.prepend" class="datametria-input__prepend">
4
+ <slot name="prepend" />
5
+ </div>
6
+
7
+ <div class="datametria-input__inner">
8
+ <span v-if="$slots.prefix || prefixIcon" class="datametria-input__prefix">
9
+ <slot name="prefix">
10
+ <span v-if="prefixIcon">{{ prefixIcon }}</span>
11
+ </slot>
12
+ </span>
13
+
14
+ <input
15
+ ref="inputRef"
16
+ v-model="inputValue"
17
+ :type="type"
18
+ :placeholder="placeholder"
19
+ :disabled="disabled"
20
+ :readonly="readonly"
21
+ :maxlength="maxlength"
22
+ :class="inputClasses"
23
+ @input="handleInput"
24
+ @change="handleChange"
25
+ @focus="handleFocus"
26
+ @blur="handleBlur"
27
+ />
28
+
29
+ <span v-if="showClear || $slots.suffix || suffixIcon" class="datametria-input__suffix">
30
+ <button
31
+ v-if="showClear"
32
+ class="datametria-input__clear"
33
+ @click="handleClear"
34
+ type="button"
35
+ >
36
+ ×
37
+ </button>
38
+ <slot name="suffix">
39
+ <span v-if="suffixIcon">{{ suffixIcon }}</span>
40
+ </slot>
41
+ </span>
42
+ </div>
43
+
44
+ <div v-if="$slots.append" class="datametria-input__append">
45
+ <slot name="append" />
46
+ </div>
21
47
  </div>
22
48
  </template>
23
49
 
24
50
  <script setup lang="ts">
25
- import { computed } from 'vue'
51
+ import { ref, computed, watch } from 'vue'
52
+
53
+ /**
54
+ * DatametriaInput - Input de texto com validação e slots
55
+ *
56
+ * @component
57
+ * @example
58
+ * <DatametriaInput v-model="value" placeholder="Digite algo" />
59
+ */
26
60
 
27
61
  interface Props {
28
- modelValue?: string | number
29
- label?: string
62
+ /** Valor do input */
63
+ modelValue: string | number
64
+ /** Tipo do input */
65
+ type?: 'text' | 'password' | 'email' | 'number' | 'tel' | 'url'
66
+ /** Placeholder */
30
67
  placeholder?: string
31
- errorMessage?: string
68
+ /** Input desabilitado */
32
69
  disabled?: boolean
33
- required?: boolean
70
+ /** Input somente leitura */
71
+ readonly?: boolean
72
+ /** Botão de limpar */
73
+ clearable?: boolean
74
+ /** Comprimento máximo */
75
+ maxlength?: number
76
+ /** Ícone prefixo */
77
+ prefixIcon?: string
78
+ /** Ícone sufixo */
79
+ suffixIcon?: string
80
+ /** Tamanho */
81
+ size?: 'small' | 'default' | 'large'
34
82
  }
35
83
 
36
84
  const props = withDefaults(defineProps<Props>(), {
37
- modelValue: '',
85
+ type: 'text',
86
+ placeholder: '',
38
87
  disabled: false,
39
- required: false
88
+ readonly: false,
89
+ clearable: false,
90
+ size: 'default'
40
91
  })
41
92
 
42
- defineEmits<{
43
- 'update:modelValue': [value: string]
93
+ const emit = defineEmits<{
94
+ 'update:modelValue': [value: string | number]
95
+ 'input': [value: string | number]
96
+ 'change': [value: string | number]
97
+ 'focus': [event: FocusEvent]
98
+ 'blur': [event: FocusEvent]
99
+ 'clear': []
44
100
  }>()
45
101
 
46
- const inputId = computed(() => `input-${Math.random().toString(36).substr(2, 9)}`)
102
+ const inputRef = ref<HTMLInputElement>()
103
+ const isFocused = ref(false)
47
104
 
48
- const inputClasses = computed(() => [
49
- 'datametria-input__field',
50
- {
51
- 'datametria-input__field--error': props.errorMessage,
52
- 'datametria-input__field--disabled': props.disabled
53
- }
54
- ])
105
+ const inputValue = computed({
106
+ get: () => props.modelValue,
107
+ set: (value) => emit('update:modelValue', value)
108
+ })
109
+
110
+ const showClear = computed(() => {
111
+ return props.clearable && !props.disabled && !props.readonly && inputValue.value
112
+ })
113
+
114
+ const inputWrapperClasses = computed(() => ({
115
+ 'datametria-input--disabled': props.disabled,
116
+ 'datametria-input--focused': isFocused.value,
117
+ [`datametria-input--${props.size}`]: props.size !== 'default'
118
+ }))
119
+
120
+ const inputClasses = computed(() => 'datametria-input__field')
121
+
122
+ const handleInput = (event: Event) => {
123
+ const target = event.target as HTMLInputElement
124
+ emit('input', target.value)
125
+ }
126
+
127
+ const handleChange = (event: Event) => {
128
+ const target = event.target as HTMLInputElement
129
+ emit('change', target.value)
130
+ }
131
+
132
+ const handleFocus = (event: FocusEvent) => {
133
+ isFocused.value = true
134
+ emit('focus', event)
135
+ }
136
+
137
+ const handleBlur = (event: FocusEvent) => {
138
+ isFocused.value = false
139
+ emit('blur', event)
140
+ }
141
+
142
+ const handleClear = () => {
143
+ emit('update:modelValue', '')
144
+ emit('clear')
145
+ inputRef.value?.focus()
146
+ }
147
+
148
+ defineExpose({
149
+ focus: () => inputRef.value?.focus(),
150
+ blur: () => inputRef.value?.blur()
151
+ })
55
152
  </script>
56
153
 
57
154
  <style scoped>
58
155
  .datametria-input {
59
- display: flex;
60
- flex-direction: column;
61
- gap: var(--dm-spacing-2, 0.5rem);
156
+ display: inline-flex;
157
+ width: 100%;
158
+ font-size: 14px;
62
159
  }
63
160
 
64
- .datametria-input__label {
65
- font-size: var(--dm-font-size-sm, 0.875rem);
66
- font-weight: var(--dm-font-weight-medium, 500);
67
- color: var(--dm-neutral-700, #374151);
161
+ .datametria-input__inner {
162
+ position: relative;
163
+ display: inline-flex;
164
+ align-items: center;
165
+ width: 100%;
166
+ background: var(--color-background, #ffffff);
167
+ border: 1px solid var(--color-border, #d1d5db);
168
+ border-radius: 6px;
169
+ transition: all 0.2s;
68
170
  }
69
171
 
70
- .datametria-input__required {
71
- color: var(--dm-error, #ef4444);
172
+ .datametria-input__inner:hover {
173
+ border-color: var(--color-primary, #3b82f6);
72
174
  }
73
175
 
74
- .datametria-input__field {
75
- padding: var(--dm-spacing-3, 0.75rem);
76
- border: 1px solid var(--dm-neutral-300, #d1d5db);
77
- border-radius: var(--dm-radius-md, 0.375rem);
78
- font-size: var(--dm-font-size-base, 1rem);
79
- transition: all 0.2s;
176
+ .datametria-input--focused .datametria-input__inner {
177
+ border-color: var(--color-primary, #3b82f6);
178
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
80
179
  }
81
180
 
82
- .datametria-input__field:focus {
83
- outline: none;
84
- border-color: var(--dm-primary, #0072CE);
85
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--dm-primary, #0072CE) 10%, transparent);
181
+ .datametria-input--disabled .datametria-input__inner {
182
+ background: var(--color-background-disabled, #f3f4f6);
183
+ cursor: not-allowed;
184
+ opacity: 0.6;
86
185
  }
87
186
 
88
- .datametria-input__field--error {
89
- border-color: var(--dm-error, #ef4444);
187
+ .datametria-input__field {
188
+ flex: 1;
189
+ width: 100%;
190
+ padding: 8px 12px;
191
+ border: none;
192
+ outline: none;
193
+ background: transparent;
194
+ color: var(--color-text-primary, #1f2937);
195
+ font-size: inherit;
90
196
  }
91
197
 
92
- .datametria-input__field--disabled {
93
- background: var(--dm-neutral-100, #f3f4f6);
198
+ .datametria-input__field:disabled {
94
199
  cursor: not-allowed;
95
200
  }
96
201
 
97
- .datametria-input__error {
98
- font-size: var(--dm-font-size-sm, 0.875rem);
99
- color: var(--dm-error, #ef4444);
100
- margin: 0;
202
+ .datametria-input__prefix,
203
+ .datametria-input__suffix {
204
+ display: inline-flex;
205
+ align-items: center;
206
+ padding: 0 8px;
207
+ color: var(--color-text-secondary, #6b7280);
208
+ }
209
+
210
+ .datametria-input__clear {
211
+ background: none;
212
+ border: none;
213
+ font-size: 18px;
214
+ line-height: 1;
215
+ color: var(--color-text-secondary, #6b7280);
216
+ cursor: pointer;
217
+ padding: 0 4px;
218
+ transition: color 0.2s;
219
+ }
220
+
221
+ .datametria-input__clear:hover {
222
+ color: var(--color-text-primary, #1f2937);
223
+ }
224
+
225
+ .datametria-input__prepend,
226
+ .datametria-input__append {
227
+ display: inline-flex;
228
+ align-items: center;
229
+ padding: 0 12px;
230
+ background: var(--color-background-secondary, #f9fafb);
231
+ border: 1px solid var(--color-border, #d1d5db);
232
+ white-space: nowrap;
233
+ }
234
+
235
+ .datametria-input__prepend {
236
+ border-right: none;
237
+ border-radius: 6px 0 0 6px;
238
+ }
239
+
240
+ .datametria-input__append {
241
+ border-left: none;
242
+ border-radius: 0 6px 6px 0;
243
+ }
244
+
245
+ .datametria-input--small .datametria-input__field {
246
+ padding: 4px 8px;
247
+ font-size: 12px;
248
+ }
249
+
250
+ .datametria-input--large .datametria-input__field {
251
+ padding: 12px 16px;
252
+ font-size: 16px;
253
+ }
254
+
255
+ @media (prefers-color-scheme: dark) {
256
+ .datametria-input__inner {
257
+ background: var(--color-background, #1f2937);
258
+ border-color: var(--color-border, #374151);
259
+ }
260
+
261
+ .datametria-input__field {
262
+ color: var(--color-text-primary, #f9fafb);
263
+ }
101
264
  }
102
265
  </style>
@@ -0,0 +1,373 @@
1
+ <template>
2
+ <div class="datametria-pagination" :class="classes">
3
+ <template v-for="item in layoutItems" :key="item">
4
+ <!-- Total -->
5
+ <span v-if="item === 'total'" class="datametria-pagination__total">
6
+ Total: {{ total }}
7
+ </span>
8
+
9
+ <!-- Sizes -->
10
+ <select
11
+ v-if="item === 'sizes'"
12
+ v-model="currentPageSize"
13
+ class="datametria-pagination__sizes"
14
+ :disabled="disabled"
15
+ @change="handleSizeChange"
16
+ >
17
+ <option v-for="size in pageSizes" :key="size" :value="size">
18
+ {{ size }} / página
19
+ </option>
20
+ </select>
21
+
22
+ <!-- Prev -->
23
+ <button
24
+ v-if="item === 'prev'"
25
+ class="datametria-pagination__btn"
26
+ :disabled="currentPage === 1 || disabled"
27
+ @click="handlePrev"
28
+ >
29
+ <span class="datametria-pagination__icon">‹</span>
30
+ </button>
31
+
32
+ <!-- Pager -->
33
+ <ul v-if="item === 'pager'" class="datametria-pagination__pager">
34
+ <li
35
+ v-for="page in pagerList"
36
+ :key="page"
37
+ class="datametria-pagination__number"
38
+ :class="{
39
+ 'is-active': page === currentPage,
40
+ 'is-disabled': disabled
41
+ }"
42
+ @click="handlePageClick(page)"
43
+ >
44
+ {{ page === '...' ? '•••' : page }}
45
+ </li>
46
+ </ul>
47
+
48
+ <!-- Next -->
49
+ <button
50
+ v-if="item === 'next'"
51
+ class="datametria-pagination__btn"
52
+ :disabled="currentPage === totalPages || disabled"
53
+ @click="handleNext"
54
+ >
55
+ <span class="datametria-pagination__icon">›</span>
56
+ </button>
57
+
58
+ <!-- Jumper -->
59
+ <span v-if="item === 'jumper'" class="datametria-pagination__jumper">
60
+ Ir para
61
+ <input
62
+ v-model.number="jumpPage"
63
+ type="number"
64
+ min="1"
65
+ :max="totalPages"
66
+ :disabled="disabled"
67
+ @keyup.enter="handleJump"
68
+ />
69
+ </span>
70
+ </template>
71
+ </div>
72
+ </template>
73
+
74
+ <script setup lang="ts">
75
+ import { ref, computed, watch } from 'vue'
76
+
77
+ interface Props {
78
+ modelValue?: number
79
+ total?: number
80
+ pageSize?: number
81
+ pageSizes?: number[]
82
+ layout?: string
83
+ pagerCount?: number
84
+ disabled?: boolean
85
+ small?: boolean
86
+ }
87
+
88
+ const props = withDefaults(defineProps<Props>(), {
89
+ modelValue: 1,
90
+ total: 0,
91
+ pageSize: 10,
92
+ pageSizes: () => [10, 20, 30, 50, 100],
93
+ layout: 'prev, pager, next',
94
+ pagerCount: 7,
95
+ disabled: false,
96
+ small: false
97
+ })
98
+
99
+ const emit = defineEmits<{
100
+ 'update:modelValue': [value: number]
101
+ 'size-change': [size: number]
102
+ 'current-change': [page: number]
103
+ }>()
104
+
105
+ const currentPage = ref(props.modelValue)
106
+ const currentPageSize = ref(props.pageSize)
107
+ const jumpPage = ref<number | ''>('')
108
+
109
+ const totalPages = computed(() => Math.ceil(props.total / currentPageSize.value) || 1)
110
+
111
+ const layoutItems = computed(() => {
112
+ return props.layout.split(',').map(item => item.trim())
113
+ })
114
+
115
+ const pagerList = computed(() => {
116
+ const pages: (number | string)[] = []
117
+ const count = props.pagerCount
118
+ const half = Math.floor(count / 2)
119
+
120
+ if (totalPages.value <= count) {
121
+ for (let i = 1; i <= totalPages.value; i++) {
122
+ pages.push(i)
123
+ }
124
+ } else {
125
+ if (currentPage.value <= half + 1) {
126
+ for (let i = 1; i <= count - 2; i++) {
127
+ pages.push(i)
128
+ }
129
+ pages.push('...')
130
+ pages.push(totalPages.value)
131
+ } else if (currentPage.value >= totalPages.value - half) {
132
+ pages.push(1)
133
+ pages.push('...')
134
+ for (let i = totalPages.value - count + 3; i <= totalPages.value; i++) {
135
+ pages.push(i)
136
+ }
137
+ } else {
138
+ pages.push(1)
139
+ pages.push('...')
140
+ for (let i = currentPage.value - half + 2; i <= currentPage.value + half - 2; i++) {
141
+ pages.push(i)
142
+ }
143
+ pages.push('...')
144
+ pages.push(totalPages.value)
145
+ }
146
+ }
147
+
148
+ return pages
149
+ })
150
+
151
+ const classes = computed(() => ({
152
+ 'is-small': props.small,
153
+ 'is-disabled': props.disabled
154
+ }))
155
+
156
+ watch(() => props.modelValue, (val) => {
157
+ currentPage.value = val
158
+ })
159
+
160
+ watch(() => props.pageSize, (val) => {
161
+ currentPageSize.value = val
162
+ })
163
+
164
+ const handlePrev = () => {
165
+ if (currentPage.value > 1) {
166
+ changePage(currentPage.value - 1)
167
+ }
168
+ }
169
+
170
+ const handleNext = () => {
171
+ if (currentPage.value < totalPages.value) {
172
+ changePage(currentPage.value + 1)
173
+ }
174
+ }
175
+
176
+ const handlePageClick = (page: number | string) => {
177
+ if (page === '...' || props.disabled) return
178
+ changePage(page as number)
179
+ }
180
+
181
+ const handleSizeChange = () => {
182
+ const newPage = Math.min(currentPage.value, Math.ceil(props.total / currentPageSize.value))
183
+ changePage(newPage)
184
+ emit('size-change', currentPageSize.value)
185
+ }
186
+
187
+ const handleJump = () => {
188
+ if (jumpPage.value && jumpPage.value >= 1 && jumpPage.value <= totalPages.value) {
189
+ changePage(jumpPage.value)
190
+ jumpPage.value = ''
191
+ }
192
+ }
193
+
194
+ const changePage = (page: number) => {
195
+ if (page === currentPage.value) return
196
+ currentPage.value = page
197
+ emit('update:modelValue', page)
198
+ emit('current-change', page)
199
+ }
200
+ </script>
201
+
202
+ <style scoped>
203
+ .datametria-pagination {
204
+ display: flex;
205
+ align-items: center;
206
+ gap: 8px;
207
+ font-size: 14px;
208
+ color: var(--datametria-text-primary, #303133);
209
+ }
210
+
211
+ .datametria-pagination.is-small {
212
+ font-size: 12px;
213
+ }
214
+
215
+ .datametria-pagination.is-disabled {
216
+ opacity: 0.5;
217
+ pointer-events: none;
218
+ }
219
+
220
+ .datametria-pagination__total {
221
+ color: var(--datametria-text-secondary, #606266);
222
+ }
223
+
224
+ .datametria-pagination__sizes {
225
+ width: 120px;
226
+ height: 32px;
227
+ padding: 0 8px;
228
+ border: 1px solid var(--datametria-border-color, #dcdfe6);
229
+ border-radius: 4px;
230
+ background: var(--datametria-bg-color, #ffffff);
231
+ color: var(--datametria-text-primary, #303133);
232
+ font-size: 14px;
233
+ cursor: pointer;
234
+ transition: all 0.2s;
235
+ }
236
+
237
+ .datametria-pagination__sizes:hover:not(:disabled) {
238
+ border-color: var(--datametria-primary-color, #0072ce);
239
+ }
240
+
241
+ .datametria-pagination__sizes:focus {
242
+ outline: none;
243
+ border-color: var(--datametria-primary-color, #0072ce);
244
+ }
245
+
246
+ .datametria-pagination__sizes:disabled {
247
+ cursor: not-allowed;
248
+ opacity: 0.5;
249
+ }
250
+
251
+ .datametria-pagination__btn {
252
+ min-width: 32px;
253
+ height: 32px;
254
+ padding: 0 8px;
255
+ border: 1px solid var(--datametria-border-color, #dcdfe6);
256
+ border-radius: 4px;
257
+ background: var(--datametria-bg-color, #ffffff);
258
+ color: var(--datametria-text-primary, #303133);
259
+ cursor: pointer;
260
+ transition: all 0.2s;
261
+ }
262
+
263
+ .datametria-pagination__btn:hover:not(:disabled) {
264
+ color: var(--datametria-primary-color, #0072ce);
265
+ border-color: var(--datametria-primary-color, #0072ce);
266
+ }
267
+
268
+ .datametria-pagination__btn:disabled {
269
+ cursor: not-allowed;
270
+ opacity: 0.5;
271
+ }
272
+
273
+ .datametria-pagination__icon {
274
+ font-size: 18px;
275
+ font-weight: bold;
276
+ }
277
+
278
+ .datametria-pagination__pager {
279
+ display: flex;
280
+ gap: 4px;
281
+ margin: 0;
282
+ padding: 0;
283
+ list-style: none;
284
+ }
285
+
286
+ .datametria-pagination__number {
287
+ min-width: 32px;
288
+ height: 32px;
289
+ padding: 0 8px;
290
+ display: flex;
291
+ align-items: center;
292
+ justify-content: center;
293
+ border: 1px solid var(--datametria-border-color, #dcdfe6);
294
+ border-radius: 4px;
295
+ background: var(--datametria-bg-color, #ffffff);
296
+ cursor: pointer;
297
+ transition: all 0.2s;
298
+ }
299
+
300
+ .datametria-pagination__number:hover:not(.is-active):not(.is-disabled) {
301
+ color: var(--datametria-primary-color, #0072ce);
302
+ border-color: var(--datametria-primary-color, #0072ce);
303
+ }
304
+
305
+ .datametria-pagination__number.is-active {
306
+ color: #ffffff;
307
+ background: var(--datametria-primary-color, #0072ce);
308
+ border-color: var(--datametria-primary-color, #0072ce);
309
+ }
310
+
311
+ .datametria-pagination__number.is-disabled {
312
+ cursor: not-allowed;
313
+ opacity: 0.5;
314
+ }
315
+
316
+ .datametria-pagination__jumper {
317
+ display: flex;
318
+ align-items: center;
319
+ gap: 8px;
320
+ color: var(--datametria-text-secondary, #606266);
321
+ }
322
+
323
+ .datametria-pagination__jumper input {
324
+ width: 60px;
325
+ height: 32px;
326
+ padding: 0 8px;
327
+ border: 1px solid var(--datametria-border-color, #dcdfe6);
328
+ border-radius: 4px;
329
+ text-align: center;
330
+ font-size: 14px;
331
+ }
332
+
333
+ .datametria-pagination__jumper input:focus {
334
+ outline: none;
335
+ border-color: var(--datametria-primary-color, #0072ce);
336
+ }
337
+
338
+ .datametria-pagination__jumper input:disabled {
339
+ cursor: not-allowed;
340
+ opacity: 0.5;
341
+ }
342
+
343
+ /* Dark mode */
344
+ @media (prefers-color-scheme: dark) {
345
+ .datametria-pagination {
346
+ color: var(--datametria-text-primary, #e5eaf3);
347
+ }
348
+
349
+ .datametria-pagination__total,
350
+ .datametria-pagination__jumper {
351
+ color: var(--datametria-text-secondary, #a3a6ad);
352
+ }
353
+
354
+ .datametria-pagination__btn,
355
+ .datametria-pagination__number {
356
+ border-color: var(--datametria-border-color, #4c4d4f);
357
+ background: var(--datametria-bg-color, #1d1e1f);
358
+ color: var(--datametria-text-primary, #e5eaf3);
359
+ }
360
+
361
+ .datametria-pagination__jumper input {
362
+ border-color: var(--datametria-border-color, #4c4d4f);
363
+ background: var(--datametria-bg-color, #1d1e1f);
364
+ color: var(--datametria-text-primary, #e5eaf3);
365
+ }
366
+
367
+ .datametria-pagination__sizes {
368
+ border-color: var(--datametria-border-color, #4c4d4f);
369
+ background: var(--datametria-bg-color, #1d1e1f);
370
+ color: var(--datametria-text-primary, #e5eaf3);
371
+ }
372
+ }
373
+ </style>