@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.
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 +8 -10
  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,159 +1,199 @@
1
1
  <template>
2
- <div class="dm-textarea">
3
- <label v-if="label" :for="inputId" class="dm-textarea__label">
4
- {{ label }}
5
- <span v-if="required" class="dm-textarea__required">*</span>
6
- </label>
2
+ <div class="datametria-textarea" :class="textareaClasses">
7
3
  <textarea
8
- :id="inputId"
9
- v-model="internalValue"
10
- class="dm-textarea__input"
11
- :class="{ 'dm-textarea__input--error': error }"
4
+ ref="textareaRef"
5
+ v-model="currentValue"
6
+ class="datametria-textarea__inner"
12
7
  :placeholder="placeholder"
13
8
  :disabled="disabled"
14
- :required="required"
15
- :rows="rows"
16
- :maxlength="maxLength"
17
- :aria-label="ariaLabel"
18
- :aria-describedby="error ? `${inputId}-error` : undefined"
19
- :aria-invalid="!!error"
9
+ :readonly="readonly"
10
+ :rows="computedRows"
11
+ :maxlength="maxlength"
20
12
  @input="handleInput"
13
+ @focus="handleFocus"
14
+ @blur="handleBlur"
21
15
  />
22
- <div v-if="maxLength || error" class="dm-textarea__footer">
23
- <p v-if="error" :id="`${inputId}-error`" class="dm-textarea__error">{{ error }}</p>
24
- <span v-if="maxLength" class="dm-textarea__counter">
25
- {{ internalValue?.length || 0 }}/{{ maxLength }}
26
- </span>
16
+ <div v-if="showWordLimit && maxlength" class="datametria-textarea__count">
17
+ {{ currentValue.length }} / {{ maxlength }}
27
18
  </div>
28
19
  </div>
29
20
  </template>
30
21
 
31
22
  <script setup lang="ts">
32
- import { ref, watch } from 'vue'
23
+ import { ref, computed, watch, nextTick, onMounted } from 'vue'
33
24
 
34
25
  interface Props {
35
26
  modelValue?: string
36
- label?: string
37
27
  placeholder?: string
38
28
  disabled?: boolean
39
- required?: boolean
40
- error?: string
29
+ readonly?: boolean
41
30
  rows?: number
42
- maxLength?: number
43
- ariaLabel?: string
31
+ maxlength?: number
32
+ showWordLimit?: boolean
33
+ autosize?: boolean | { minRows?: number; maxRows?: number }
44
34
  }
45
35
 
46
36
  const props = withDefaults(defineProps<Props>(), {
47
37
  modelValue: '',
38
+ placeholder: '',
48
39
  disabled: false,
49
- required: false,
50
- rows: 4
40
+ readonly: false,
41
+ rows: 3,
42
+ showWordLimit: false,
43
+ autosize: false
51
44
  })
52
45
 
53
46
  const emit = defineEmits<{
54
47
  'update:modelValue': [value: string]
48
+ input: [value: string]
49
+ focus: [event: FocusEvent]
50
+ blur: [event: FocusEvent]
55
51
  }>()
56
52
 
57
- const inputId = `dm-textarea-${Math.random().toString(36).substr(2, 9)}`
58
- const internalValue = ref(props.modelValue)
53
+ const textareaRef = ref<HTMLTextAreaElement>()
54
+ const currentValue = ref(props.modelValue)
55
+ const isFocused = ref(false)
59
56
 
60
- watch(() => props.modelValue, (newValue) => {
61
- internalValue.value = newValue
57
+ const textareaClasses = computed(() => ({
58
+ 'datametria-textarea--disabled': props.disabled,
59
+ 'datametria-textarea--focused': isFocused.value
60
+ }))
61
+
62
+ const computedRows = computed(() => {
63
+ if (props.autosize) return undefined
64
+ return props.rows
62
65
  })
63
66
 
64
- const handleInput = () => {
65
- emit('update:modelValue', internalValue.value || '')
67
+ const handleInput = (event: Event) => {
68
+ const target = event.target as HTMLTextAreaElement
69
+ currentValue.value = target.value
70
+ emit('update:modelValue', target.value)
71
+ emit('input', target.value)
72
+
73
+ if (props.autosize) {
74
+ nextTick(() => resizeTextarea())
75
+ }
66
76
  }
67
- </script>
68
77
 
69
- <style scoped>
70
- .dm-textarea {
71
- display: flex;
72
- flex-direction: column;
73
- gap: var(--dm-spacing-2, 0.5rem);
78
+ const handleFocus = (event: FocusEvent) => {
79
+ isFocused.value = true
80
+ emit('focus', event)
74
81
  }
75
82
 
76
- .dm-textarea__label {
77
- color: var(--dm-neutral-900, #111827);
78
- font-size: var(--dm-font-size-sm, 0.875rem);
79
- font-weight: var(--dm-font-weight-medium, 500);
83
+ const handleBlur = (event: FocusEvent) => {
84
+ isFocused.value = false
85
+ emit('blur', event)
80
86
  }
81
87
 
82
- .dm-textarea__required {
83
- color: var(--dm-error, #ef4444);
84
- }
88
+ const resizeTextarea = () => {
89
+ if (!textareaRef.value || !props.autosize) return
85
90
 
86
- .dm-textarea__input {
87
- width: 100%;
88
- padding: var(--dm-spacing-3, 0.75rem);
89
- border: 1px solid var(--dm-neutral-300, #d1d5db);
90
- border-radius: var(--dm-radius-md, 0.375rem);
91
- font-size: var(--dm-font-size-base, 1rem);
92
- color: var(--dm-neutral-900, #111827);
93
- background: white;
94
- transition: all 0.2s;
95
- resize: vertical;
96
- font-family: inherit;
97
- line-height: 1.5;
98
- }
91
+ const textarea = textareaRef.value
92
+ textarea.style.height = 'auto'
93
+
94
+ let minHeight = 0
95
+ let maxHeight = Infinity
99
96
 
100
- .dm-textarea__input::placeholder {
101
- color: var(--dm-neutral-400, #9ca3af);
102
- }
97
+ if (typeof props.autosize === 'object') {
98
+ if (props.autosize.minRows) {
99
+ const lineHeight = parseInt(getComputedStyle(textarea).lineHeight)
100
+ minHeight = props.autosize.minRows * lineHeight
101
+ }
102
+ if (props.autosize.maxRows) {
103
+ const lineHeight = parseInt(getComputedStyle(textarea).lineHeight)
104
+ maxHeight = props.autosize.maxRows * lineHeight
105
+ }
106
+ }
103
107
 
104
- .dm-textarea__input:hover:not(:disabled) {
105
- border-color: var(--dm-neutral-400, #9ca3af);
108
+ const scrollHeight = textarea.scrollHeight
109
+ const height = Math.max(minHeight, Math.min(maxHeight, scrollHeight))
110
+ textarea.style.height = `${height}px`
106
111
  }
107
112
 
108
- .dm-textarea__input:focus {
109
- outline: 2px solid var(--dm-primary, #0072CE);
110
- outline-offset: 0;
111
- border-color: var(--dm-primary, #0072CE);
113
+ watch(() => props.modelValue, (newValue) => {
114
+ if (newValue !== currentValue.value) {
115
+ currentValue.value = newValue
116
+ if (props.autosize) {
117
+ nextTick(() => resizeTextarea())
118
+ }
119
+ }
120
+ })
121
+
122
+ onMounted(() => {
123
+ if (props.autosize) {
124
+ nextTick(() => resizeTextarea())
125
+ }
126
+ })
127
+
128
+ defineExpose({
129
+ focus: () => textareaRef.value?.focus(),
130
+ blur: () => textareaRef.value?.blur()
131
+ })
132
+ </script>
133
+
134
+ <style scoped>
135
+ .datametria-textarea {
136
+ position: relative;
137
+ display: inline-block;
138
+ width: 100%;
139
+ vertical-align: bottom;
140
+ font-size: 14px;
112
141
  }
113
142
 
114
- .dm-textarea__input:disabled {
115
- background: var(--dm-neutral-100, #f3f4f6);
116
- cursor: not-allowed;
117
- opacity: 0.6;
143
+ .datametria-textarea__inner {
144
+ display: block;
145
+ resize: vertical;
146
+ padding: 8px 12px;
147
+ line-height: 1.5;
148
+ box-sizing: border-box;
149
+ width: 100%;
150
+ font-size: inherit;
151
+ font-family: inherit;
152
+ color: var(--datametria-text-color, #303133);
153
+ background-color: var(--datametria-bg-color, #ffffff);
154
+ border: 1px solid var(--datametria-border-color, #dcdfe6);
155
+ border-radius: 4px;
156
+ transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
118
157
  }
119
158
 
120
- .dm-textarea__input--error {
121
- border-color: var(--dm-error, #ef4444);
159
+ .datametria-textarea__inner:hover {
160
+ border-color: var(--datametria-border-color-hover, #c0c4cc);
122
161
  }
123
162
 
124
- .dm-textarea__input--error:focus {
125
- outline-color: var(--dm-error, #ef4444);
163
+ .datametria-textarea__inner:focus {
164
+ outline: none;
165
+ border-color: var(--datametria-primary-color, #0072ce);
126
166
  }
127
167
 
128
- .dm-textarea__footer {
129
- display: flex;
130
- justify-content: space-between;
131
- align-items: center;
132
- gap: var(--dm-spacing-2, 0.5rem);
168
+ .datametria-textarea__inner::placeholder {
169
+ color: var(--datametria-placeholder-color, #a8abb2);
133
170
  }
134
171
 
135
- .dm-textarea__error {
136
- color: var(--dm-error, #ef4444);
137
- font-size: var(--dm-font-size-sm, 0.875rem);
138
- margin: 0;
139
- flex: 1;
172
+ .datametria-textarea__inner:disabled {
173
+ background-color: var(--datametria-disabled-bg-color, #f5f7fa);
174
+ border-color: var(--datametria-disabled-border-color, #e4e7ed);
175
+ color: var(--datametria-disabled-text-color, #c0c4cc);
176
+ cursor: not-allowed;
140
177
  }
141
178
 
142
- .dm-textarea__counter {
143
- color: var(--dm-neutral-500, #6b7280);
144
- font-size: var(--dm-font-size-sm, 0.875rem);
145
- white-space: nowrap;
179
+ .datametria-textarea--disabled .datametria-textarea__inner {
180
+ background-color: var(--datametria-disabled-bg-color, #f5f7fa);
181
+ border-color: var(--datametria-disabled-border-color, #e4e7ed);
182
+ color: var(--datametria-disabled-text-color, #c0c4cc);
183
+ cursor: not-allowed;
146
184
  }
147
185
 
148
- @media (prefers-color-scheme: dark) {
149
- .dm-textarea__input {
150
- background: var(--dm-neutral-800, #1f2937);
151
- border-color: var(--dm-neutral-600, #4b5563);
152
- color: white;
153
- }
186
+ .datametria-textarea__count {
187
+ position: absolute;
188
+ bottom: 8px;
189
+ right: 12px;
190
+ font-size: 12px;
191
+ color: var(--datametria-info-color, #909399);
192
+ background-color: var(--datametria-bg-color, #ffffff);
193
+ padding: 0 4px;
194
+ }
154
195
 
155
- .dm-textarea__input:disabled {
156
- background: var(--dm-neutral-900, #111827);
157
- }
196
+ .datametria-textarea--focused .datametria-textarea__inner {
197
+ border-color: var(--datametria-primary-color, #0072ce);
158
198
  }
159
199
  </style>