@indielayer/ui 1.14.4 → 1.15.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.
- package/docs/pages/component/avatar/usage.vue +1 -1
- package/docs/pages/component/input/usage.vue +22 -8
- package/docs/pages/component/table/selectable.vue +1 -1
- package/docs/pages/component/table/virtual.vue +2 -1
- package/docs/pages/component/tag/usage.vue +1 -1
- package/docs/pages/component/textarea/usage.vue +22 -8
- package/lib/components/avatar/Avatar.vue2.js +20 -19
- package/lib/components/avatar/theme/Avatar.base.theme.js +9 -12
- package/lib/components/datepicker/Datepicker.vue.js +4 -4
- package/lib/components/drawer/Drawer.vue.js +66 -60
- package/lib/components/input/Input.vue.d.ts +8 -0
- package/lib/components/input/Input.vue.js +84 -69
- package/lib/components/inputFooter/InputFooter.vue.d.ts +13 -2
- package/lib/components/inputFooter/InputFooter.vue.js +35 -19
- package/lib/components/inputFooter/theme/InputFooter.base.theme.js +3 -1
- package/lib/components/inputFooter/theme/InputFooter.carbon.theme.js +3 -1
- package/lib/components/menu/MenuItem.vue.js +2 -2
- package/lib/components/menu/MenuItem.vue2.js +1 -0
- package/lib/components/popover/Popover.vue.d.ts +1 -1
- package/lib/components/select/Select.vue.d.ts +38 -10
- package/lib/components/select/Select.vue.js +210 -200
- package/lib/components/table/Table.vue.d.ts +55 -19
- package/lib/components/table/Table.vue.js +256 -214
- package/lib/components/table/TableCell.vue.d.ts +9 -0
- package/lib/components/table/TableCell.vue.js +45 -21
- package/lib/components/table/TableHeader.vue.js +14 -14
- package/lib/components/table/theme/TableCell.base.theme.js +3 -3
- package/lib/components/tag/Tag.vue.d.ts +3 -0
- package/lib/components/tag/Tag.vue.js +37 -35
- package/lib/components/textarea/Textarea.vue.d.ts +19 -3
- package/lib/components/textarea/Textarea.vue.js +98 -76
- package/lib/components/textarea/theme/Textarea.base.theme.js +2 -1
- package/lib/components/textarea/theme/Textarea.carbon.theme.js +2 -1
- package/lib/components/upload/Upload.vue.js +91 -86
- package/lib/index.js +1 -1
- package/lib/index.umd.js +4 -4
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/components/avatar/Avatar.vue +2 -2
- package/src/components/avatar/theme/Avatar.base.theme.ts +0 -5
- package/src/components/datepicker/Datepicker.vue +7 -2
- package/src/components/drawer/Drawer.vue +13 -2
- package/src/components/input/Input.vue +27 -2
- package/src/components/inputFooter/InputFooter.vue +35 -3
- package/src/components/inputFooter/theme/InputFooter.base.theme.ts +2 -0
- package/src/components/inputFooter/theme/InputFooter.carbon.theme.ts +2 -0
- package/src/components/menu/MenuItem.vue +1 -0
- package/src/components/select/Select.vue +21 -8
- package/src/components/table/Table.vue +170 -48
- package/src/components/table/TableCell.vue +23 -0
- package/src/components/table/TableHeader.vue +2 -2
- package/src/components/table/theme/TableCell.base.theme.ts +20 -11
- package/src/components/tag/Tag.vue +8 -3
- package/src/components/textarea/Textarea.vue +63 -30
- package/src/components/textarea/theme/Textarea.base.theme.ts +2 -0
- package/src/components/textarea/theme/Textarea.carbon.theme.ts +2 -0
- package/src/components/upload/Upload.vue +12 -2
- package/src/version.ts +1 -1
|
@@ -16,6 +16,9 @@ const tableCellProps = {
|
|
|
16
16
|
default: 'middle',
|
|
17
17
|
validator: (value: string) => validators.verticalAlign.includes(value as any),
|
|
18
18
|
},
|
|
19
|
+
to: [String, Object],
|
|
20
|
+
href: String,
|
|
21
|
+
target: String as PropType<'_blank' | '_self' | '_parent' | '_top'>,
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
export type TableCellTextAlign = typeof validators.textAlign[number]
|
|
@@ -44,6 +47,26 @@ const { styles, classes, className } = useTheme('TableCell', {}, props)
|
|
|
44
47
|
|
|
45
48
|
<template>
|
|
46
49
|
<td
|
|
50
|
+
v-if="to || href"
|
|
51
|
+
class="relative"
|
|
52
|
+
:class="className"
|
|
53
|
+
:style="[{ width: computedWidth, minWidth: computedWidth, maxWidth: computedWidth }]"
|
|
54
|
+
>
|
|
55
|
+
<component
|
|
56
|
+
:is="to ? 'router-link' : 'a'"
|
|
57
|
+
v-bind="href ? { href } : {}"
|
|
58
|
+
:target="target"
|
|
59
|
+
:to="to"
|
|
60
|
+
:style="styles"
|
|
61
|
+
:class="classes.wrapper"
|
|
62
|
+
>
|
|
63
|
+
<div :class="[truncate ? 'truncate' : '']">
|
|
64
|
+
<slot></slot>
|
|
65
|
+
</div>
|
|
66
|
+
</component>
|
|
67
|
+
</td>
|
|
68
|
+
<td
|
|
69
|
+
v-else
|
|
47
70
|
:style="[styles, { width: computedWidth, minWidth: computedWidth, maxWidth: computedWidth }]"
|
|
48
71
|
:class="[
|
|
49
72
|
'relative',
|
|
@@ -52,8 +52,8 @@ const { styles, classes, className } = useTheme('TableHeader', {}, props)
|
|
|
52
52
|
:class="[
|
|
53
53
|
classes.sortIcon,
|
|
54
54
|
textAlign === 'right' ? '-mr-4 -translate-x-4' : '-ml-4 translate-x-4',
|
|
55
|
-
[sort && [1, -1].includes(sort) ? '' : '
|
|
56
|
-
[sort !== -1 && sort !== 1 ? 'text-secondary-400 dark:text-secondary-500' : 'text-primary-
|
|
55
|
+
[sort && [1, -1].includes(sort) ? '' : 'group-hover/th:text-secondary-500 dark:group-hover/th:text-secondary-400'],
|
|
56
|
+
[sort !== -1 && sort !== 1 ? 'text-secondary-400 dark:text-secondary-500' : 'text-primary-500 dark:text-primary-400']
|
|
57
57
|
]"
|
|
58
58
|
width="24"
|
|
59
59
|
height="24"
|
|
@@ -7,17 +7,26 @@ const theme: TableCellTheme = {
|
|
|
7
7
|
|
|
8
8
|
c.push(props.dense ? 'h-9 py-0.5' : 'h-11 py-1')
|
|
9
9
|
|
|
10
|
-
if (props.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
else
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
if (props.to || props.href) {
|
|
11
|
+
c.push('flex items-center')
|
|
12
|
+
|
|
13
|
+
if (props.textAlign === 'left') c.push('justify-start')
|
|
14
|
+
else if (props.textAlign === 'center') c.push('justify-center')
|
|
15
|
+
else if (props.textAlign === 'right') c.push('justify-end')
|
|
16
|
+
else if (props.textAlign === 'justify') c.push('justify-center')
|
|
17
|
+
} else {
|
|
18
|
+
if (props.textAlign === 'left') c.push('text-left')
|
|
19
|
+
else if (props.textAlign === 'center') c.push('text-center')
|
|
20
|
+
else if (props.textAlign === 'right') c.push('text-right')
|
|
21
|
+
else if (props.textAlign === 'justify') c.push('text-justify')
|
|
22
|
+
|
|
23
|
+
if (props.verticalAlign === 'baseline') c.push('align-baseline')
|
|
24
|
+
else if (props.verticalAlign === 'bottom') c.push('align-bottom')
|
|
25
|
+
else if (props.verticalAlign === 'middle') c.push('align-middle')
|
|
26
|
+
else if (props.verticalAlign === 'text-bottom') c.push('align-text-bottom')
|
|
27
|
+
else if (props.verticalAlign === 'text-top') c.push('align-text-top')
|
|
28
|
+
else if (props.verticalAlign === 'top') c.push('align-top')
|
|
29
|
+
}
|
|
21
30
|
|
|
22
31
|
if (props.truncate) c.push('truncate')
|
|
23
32
|
|
|
@@ -11,6 +11,7 @@ const tagProps = {
|
|
|
11
11
|
outlined: Boolean,
|
|
12
12
|
filled: Boolean,
|
|
13
13
|
disabled: Boolean,
|
|
14
|
+
to: [String, Object],
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
export type TagProps = ExtractPublicPropTypes<typeof tagProps>
|
|
@@ -27,7 +28,7 @@ export default {
|
|
|
27
28
|
</script>
|
|
28
29
|
|
|
29
30
|
<script setup lang="ts">
|
|
30
|
-
import { computed, type ExtractPublicPropTypes } from 'vue'
|
|
31
|
+
import { computed, useAttrs, type ExtractPublicPropTypes } from 'vue'
|
|
31
32
|
import { useColors } from '../../composables/useColors'
|
|
32
33
|
import { useCommon } from '../../composables/useCommon'
|
|
33
34
|
import { useTheme, type ThemeComponent } from '../../composables/useTheme'
|
|
@@ -48,12 +49,16 @@ const closeIconSize = computed(() => {
|
|
|
48
49
|
return 'sm'
|
|
49
50
|
})
|
|
50
51
|
|
|
52
|
+
const attrs = useAttrs()
|
|
53
|
+
const htmlTag = computed(() => (attrs.href ? 'a' : props.to ? 'router-link' : props.tag))
|
|
54
|
+
|
|
51
55
|
const { styles, classes, className } = useTheme('Tag', {}, props)
|
|
52
56
|
</script>
|
|
53
57
|
|
|
54
58
|
<template>
|
|
55
59
|
<component
|
|
56
|
-
:is="
|
|
60
|
+
:is="htmlTag"
|
|
61
|
+
:to="to"
|
|
57
62
|
class="text-[color:var(--x-tag-text)] dark:text-[color:var(--x-tag-dark-text)] border relative"
|
|
58
63
|
:style="styles"
|
|
59
64
|
:class="
|
|
@@ -84,7 +89,7 @@ const { styles, classes, className } = useTheme('Tag', {}, props)
|
|
|
84
89
|
:icon="closeIcon"
|
|
85
90
|
class="cursor-pointer transition-colors duration-150"
|
|
86
91
|
:class="[disabled ? 'text-secondary-400' : 'hover:text-secondary-500']"
|
|
87
|
-
@click="(e: Event) => !disabled && $emit('remove', e)"
|
|
92
|
+
@click.prevent="(e: Event) => !disabled && $emit('remove', e)"
|
|
88
93
|
/>
|
|
89
94
|
</div>
|
|
90
95
|
</span>
|
|
@@ -20,11 +20,13 @@ const textareaProps = {
|
|
|
20
20
|
preventEnter: Boolean,
|
|
21
21
|
block: Boolean,
|
|
22
22
|
resizable: Boolean,
|
|
23
|
+
showCounter: Boolean,
|
|
24
|
+
clearable: Boolean,
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
export type TextareaProps = ExtractPublicPropTypes<typeof textareaProps>
|
|
26
28
|
|
|
27
|
-
type InternalClasses = 'wrapper' | 'input'
|
|
29
|
+
type InternalClasses = 'wrapper' | 'input' | 'icon'
|
|
28
30
|
type InternalExtraData = { errorInternal: Ref<boolean>; }
|
|
29
31
|
|
|
30
32
|
export interface TextareaTheme extends ThemeComponent<TextareaProps, InternalClasses, InternalExtraData> {}
|
|
@@ -49,6 +51,8 @@ import { useInteractive } from '../../composables/useInteractive'
|
|
|
49
51
|
|
|
50
52
|
import XLabel from '../label/Label.vue'
|
|
51
53
|
import XInputFooter from '../inputFooter/InputFooter.vue'
|
|
54
|
+
import XIcon from '../icon/Icon.vue'
|
|
55
|
+
import { closeIcon } from '../../common/icons'
|
|
52
56
|
|
|
53
57
|
const props = defineProps(textareaProps)
|
|
54
58
|
|
|
@@ -107,6 +111,14 @@ const {
|
|
|
107
111
|
setError,
|
|
108
112
|
} = useInputtable(props, { focus, emit })
|
|
109
113
|
|
|
114
|
+
const currentLength = computed(() => {
|
|
115
|
+
const value = props.modelValue
|
|
116
|
+
|
|
117
|
+
return value ? String(value).length : 0
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
const showClearIcon = computed(() => props.clearable && props.modelValue !== '')
|
|
121
|
+
|
|
110
122
|
const { styles, classes, className } = useTheme('Textarea', {}, props, { errorInternal })
|
|
111
123
|
|
|
112
124
|
defineExpose({ focus, blur, reset, validate, setError })
|
|
@@ -126,34 +138,55 @@ defineExpose({ focus, blur, reset, validate, setError })
|
|
|
126
138
|
]"
|
|
127
139
|
:tooltip="tooltip"
|
|
128
140
|
>
|
|
129
|
-
<
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
141
|
+
<div class="relative">
|
|
142
|
+
<slot name="prefix"></slot>
|
|
143
|
+
<textarea
|
|
144
|
+
:id="id"
|
|
145
|
+
ref="elRef"
|
|
146
|
+
class=""
|
|
147
|
+
:style="style"
|
|
148
|
+
:class="[
|
|
149
|
+
classes.input,
|
|
150
|
+
errorInternal
|
|
151
|
+
? 'border-error-500 dark:border-error-400 focus:outline-error-500'
|
|
152
|
+
: 'focus:outline-[color:var(--x-textarea-border)]',
|
|
153
|
+
]"
|
|
154
|
+
:disabled="disabled"
|
|
155
|
+
:max="max"
|
|
156
|
+
:maxlength="maxlength"
|
|
157
|
+
:min="min"
|
|
158
|
+
:dir="dir"
|
|
159
|
+
:rows="rows"
|
|
160
|
+
:minlength="minlength"
|
|
161
|
+
:name="name"
|
|
162
|
+
:placeholder="placeholder"
|
|
163
|
+
:readonly="readonly"
|
|
164
|
+
:value="typeof modelValue !== 'undefined' ? String(modelValue) : ''"
|
|
165
|
+
v-bind="dataAttrs"
|
|
166
|
+
v-on="inputListeners"
|
|
167
|
+
@keydown.enter="onEnter"
|
|
168
|
+
@input="onInput"
|
|
169
|
+
></textarea>
|
|
170
|
+
|
|
171
|
+
<slot name="suffix">
|
|
172
|
+
<x-icon
|
|
173
|
+
v-if="showClearIcon"
|
|
174
|
+
:size="size"
|
|
175
|
+
:icon="closeIcon"
|
|
176
|
+
class="right-2 cursor-pointer"
|
|
177
|
+
:class="classes.icon"
|
|
178
|
+
@click="reset()"
|
|
179
|
+
/>
|
|
180
|
+
</slot>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
<x-input-footer
|
|
184
|
+
v-if="!hideFooterInternal"
|
|
185
|
+
:error="errorInternal"
|
|
186
|
+
:helper="helper"
|
|
187
|
+
:character-count="currentLength"
|
|
188
|
+
:max-characters="maxlength"
|
|
189
|
+
:show-counter="showCounter"
|
|
190
|
+
/>
|
|
158
191
|
</x-label>
|
|
159
192
|
</template>
|
|
@@ -52,7 +52,7 @@ export default {
|
|
|
52
52
|
</script>
|
|
53
53
|
|
|
54
54
|
<script setup lang="ts">
|
|
55
|
-
import { computed, ref, watch, type ExtractPublicPropTypes, type PropType } from 'vue'
|
|
55
|
+
import { computed, onBeforeUnmount, ref, watch, type ExtractPublicPropTypes, type PropType } from 'vue'
|
|
56
56
|
import { useDropZone } from '@vueuse/core'
|
|
57
57
|
import { useCommon } from '../../composables/useCommon'
|
|
58
58
|
import { useInteractive } from '../../composables/useInteractive'
|
|
@@ -187,10 +187,20 @@ function isImage(file: File) {
|
|
|
187
187
|
return file.type.startsWith('image') || imageExtensions.some((ext) => file.name.endsWith(ext))
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
+
const blobUrls: string[] = []
|
|
191
|
+
|
|
190
192
|
function getImagePreview(file: File) {
|
|
191
|
-
|
|
193
|
+
const url = URL.createObjectURL(file)
|
|
194
|
+
|
|
195
|
+
blobUrls.push(url)
|
|
196
|
+
|
|
197
|
+
return url
|
|
192
198
|
}
|
|
193
199
|
|
|
200
|
+
onBeforeUnmount(() => {
|
|
201
|
+
blobUrls.forEach((url) => URL.revokeObjectURL(url))
|
|
202
|
+
})
|
|
203
|
+
|
|
194
204
|
function calculateFileSize(size: number) {
|
|
195
205
|
if (size < 1024) return `${size} B`
|
|
196
206
|
if (size < 1024 * 1024) return `${(size / 1024).toFixed(2)} KB`
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '1.
|
|
1
|
+
export default '1.15.0'
|