@saasmakers/ui 0.1.59 → 0.1.60
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.
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { BaseTag } from '../../types/bases'
|
|
3
|
+
import { NuxtLinkLocale } from '#components'
|
|
4
|
+
import { getIcon } from '../../composables/useIcons'
|
|
5
|
+
|
|
6
|
+
const props = withDefaults(defineProps<BaseTag>(), {
|
|
7
|
+
active: false,
|
|
8
|
+
avatar: '',
|
|
9
|
+
circle: '',
|
|
10
|
+
clickable: true,
|
|
11
|
+
color: 'black',
|
|
12
|
+
draggable: false,
|
|
13
|
+
editable: false,
|
|
14
|
+
icon: undefined,
|
|
15
|
+
iconSize: undefined,
|
|
16
|
+
id: undefined,
|
|
17
|
+
isCreation: false,
|
|
18
|
+
light: true,
|
|
19
|
+
removable: false,
|
|
20
|
+
rounded: false,
|
|
21
|
+
size: 'base',
|
|
22
|
+
text: '',
|
|
23
|
+
to: undefined,
|
|
24
|
+
truncate: false,
|
|
25
|
+
uppercase: true,
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const emit = defineEmits<{
|
|
29
|
+
click: [event: MouseEvent, id?: number | string]
|
|
30
|
+
close: [event: MouseEvent, id?: number | string]
|
|
31
|
+
inputBlur: [event: FocusEvent, name: string, id?: number | string]
|
|
32
|
+
inputSubmit: [event: KeyboardEvent, name: string, id?: number | string]
|
|
33
|
+
remove: [event: MouseEvent, id?: number | string]
|
|
34
|
+
}>()
|
|
35
|
+
|
|
36
|
+
const hovered = ref(false)
|
|
37
|
+
|
|
38
|
+
const form = reactive({ name: '' })
|
|
39
|
+
|
|
40
|
+
onBeforeMount(() => {
|
|
41
|
+
if (!props.isCreation) {
|
|
42
|
+
initializeFormForExistingTag()
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
function initializeFormForExistingTag() {
|
|
47
|
+
form.name = String(props.text)?.substring(1)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function onClick(event: MouseEvent) {
|
|
51
|
+
if (!props.removable) {
|
|
52
|
+
emit('click', event, props.id)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function onInputBlur(event: FocusEvent) {
|
|
57
|
+
emit('inputBlur', event, form.name.trim(), props.id)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function onInputSubmit(event: KeyboardEvent) {
|
|
61
|
+
emit('inputSubmit', event, form.name.trim(), props.id)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function onMouseEnter() {
|
|
65
|
+
hovered.value = true
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function onMouseLeave() {
|
|
69
|
+
hovered.value = false
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function onRemove(event: MouseEvent) {
|
|
73
|
+
emit('remove', event, props.id)
|
|
74
|
+
}
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<template>
|
|
78
|
+
<span
|
|
79
|
+
class="flex select-none"
|
|
80
|
+
@click.stop="onClick"
|
|
81
|
+
@mouseenter="onMouseEnter"
|
|
82
|
+
@mouseleave="onMouseLeave"
|
|
83
|
+
>
|
|
84
|
+
<component
|
|
85
|
+
:is="to ? NuxtLinkLocale : 'span'"
|
|
86
|
+
class="inline-flex items-center border font-medium"
|
|
87
|
+
:class="{
|
|
88
|
+
'cursor-pointer': clickable,
|
|
89
|
+
'rounded-md': !rounded,
|
|
90
|
+
'rounded-full': rounded,
|
|
91
|
+
'uppercase': uppercase,
|
|
92
|
+
|
|
93
|
+
'border-gray-200 dark:border-gray-800 bg-gray-200 dark:bg-gray-800 text-gray-800 dark:text-gray-200': (color === 'black' && light && !active) || removable,
|
|
94
|
+
'border-gray-900 dark:border-gray-100 bg-gray-900 dark:bg-gray-100 text-white dark:text-black': color === 'black' && (!light || active),
|
|
95
|
+
'border-gray-700 dark:border-gray-300 bg-gray-100 dark:bg-gray-900 text-gray-700 dark:text-gray-300': color === 'gray' && light && !active,
|
|
96
|
+
'border-gray-800 dark:border-gray-200 bg-gray-800 dark:bg-gray-200 text-white dark:text-black': color === 'gray' && (!light || active),
|
|
97
|
+
'border-green-700 dark:border-green-300 bg-green-100 dark:bg-green-900 text-green-700 dark:text-green-300': color === 'green' && light && !active,
|
|
98
|
+
'border-green-800 dark:border-green-200 bg-green-800 dark:bg-green-200 text-white dark:text-black': color === 'green' && (!light || active),
|
|
99
|
+
'border-indigo-700 dark:border-indigo-300 bg-indigo-100 dark:bg-indigo-900 text-indigo-700 dark:text-indigo-300': color === 'indigo' && light && !active,
|
|
100
|
+
'border-indigo-800 dark:border-indigo-200 bg-indigo-800 dark:bg-indigo-200 text-white dark:text-black': color === 'indigo' && (!light || active),
|
|
101
|
+
'border-orange-700 dark:border-orange-300 bg-white dark:bg-gray-900 text-orange-700 dark:text-orange-300': color === 'orange' && light && !active,
|
|
102
|
+
'border-orange-800 dark:border-orange-200 bg-orange-800 dark:bg-orange-200 text-white dark:text-black': color === 'orange' && (!light || active),
|
|
103
|
+
'border-red-700 dark:border-red-300 bg-white dark:bg-gray-900 text-red-700 dark:text-red-300': color === 'red' && light && !active,
|
|
104
|
+
'border-red-800 dark:border-red-200 bg-red-800 dark:bg-red-200 text-white dark:text-black': color === 'red' && (!light || active),
|
|
105
|
+
'border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 text-gray-800 dark:text-gray-200': color === 'white' && light && !active,
|
|
106
|
+
'border-white dark:border-gray-900 text-white dark:text-black': color === 'white' && (!light || active),
|
|
107
|
+
'border-dashed border-gray-400 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-800 dark:text-gray-200': color === 'white' && light && !active,
|
|
108
|
+
|
|
109
|
+
'py-1.5 px-2.5 text-2xs': size === 'sm',
|
|
110
|
+
'py-2 px-3 text-xs': size === 'base',
|
|
111
|
+
}"
|
|
112
|
+
:to="to"
|
|
113
|
+
>
|
|
114
|
+
<BaseIcon
|
|
115
|
+
v-if="draggable"
|
|
116
|
+
class="js-drag-handle mr-2 cursor-move"
|
|
117
|
+
clickable
|
|
118
|
+
color="gray"
|
|
119
|
+
:icon="getIcon('drag')"
|
|
120
|
+
/>
|
|
121
|
+
|
|
122
|
+
<span
|
|
123
|
+
v-if="avatar || circle || icon"
|
|
124
|
+
class="mr-1 flex items-center text-center"
|
|
125
|
+
:class="{
|
|
126
|
+
'h-2.5 w-2.5': size === 'sm' || iconSize === 2.5,
|
|
127
|
+
'h-3 w-3': size === 'base' || iconSize === 3,
|
|
128
|
+
'h-3.5 w-3.5': iconSize === 3.5,
|
|
129
|
+
'h-4 w-4': iconSize === 4,
|
|
130
|
+
}"
|
|
131
|
+
>
|
|
132
|
+
<BaseAvatar
|
|
133
|
+
v-if="avatar"
|
|
134
|
+
class="h-full w-full"
|
|
135
|
+
rounded="sm"
|
|
136
|
+
:shadow="false"
|
|
137
|
+
:src="avatar"
|
|
138
|
+
/>
|
|
139
|
+
|
|
140
|
+
<BaseIcon
|
|
141
|
+
v-else-if="icon"
|
|
142
|
+
class="h-full w-full"
|
|
143
|
+
:icon="icon"
|
|
144
|
+
/>
|
|
145
|
+
</span>
|
|
146
|
+
|
|
147
|
+
<span
|
|
148
|
+
v-if="$slots.left"
|
|
149
|
+
class="mr-1"
|
|
150
|
+
>
|
|
151
|
+
<slot name="left" />
|
|
152
|
+
</span>
|
|
153
|
+
|
|
154
|
+
<BaseText
|
|
155
|
+
v-if="!editable"
|
|
156
|
+
class="whitespace-nowrap outline-none"
|
|
157
|
+
:class="{ truncate }"
|
|
158
|
+
:text="text"
|
|
159
|
+
/>
|
|
160
|
+
|
|
161
|
+
<FieldInput
|
|
162
|
+
v-else
|
|
163
|
+
v-model="form.name"
|
|
164
|
+
border="none"
|
|
165
|
+
class="w-16"
|
|
166
|
+
size="sm"
|
|
167
|
+
@blur="onInputBlur"
|
|
168
|
+
@submit="onInputSubmit"
|
|
169
|
+
/>
|
|
170
|
+
|
|
171
|
+
<BaseIcon
|
|
172
|
+
v-if="removable"
|
|
173
|
+
class="ml-1.5 text-red-700 dark:text-red-300 hover:text-black dark:hover:text-white"
|
|
174
|
+
:icon="getIcon('closeCircle')"
|
|
175
|
+
@click.prevent.stop="onRemove"
|
|
176
|
+
/>
|
|
177
|
+
</component>
|
|
178
|
+
</span>
|
|
179
|
+
</template>
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { BaseTags } from '../../types/bases'
|
|
3
|
+
|
|
4
|
+
const props = withDefaults(defineProps<BaseTags>(), {
|
|
5
|
+
active: false,
|
|
6
|
+
clickable: true,
|
|
7
|
+
draggable: false,
|
|
8
|
+
editable: false,
|
|
9
|
+
hasBack: false,
|
|
10
|
+
hasCreation: false,
|
|
11
|
+
maxTags: Number.POSITIVE_INFINITY,
|
|
12
|
+
removable: false,
|
|
13
|
+
selectable: false,
|
|
14
|
+
selectableUnique: false,
|
|
15
|
+
size: 'base',
|
|
16
|
+
tags: () => [],
|
|
17
|
+
value: () => [],
|
|
18
|
+
wrap: false,
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const emit = defineEmits<{
|
|
22
|
+
'attach': [event: MouseEvent, tagId?: number | string]
|
|
23
|
+
'back': [event: MouseEvent]
|
|
24
|
+
'click': [event: MouseEvent]
|
|
25
|
+
'create': [event: MouseEvent, name: string]
|
|
26
|
+
'detach': [event: MouseEvent, tagId?: number | string]
|
|
27
|
+
'remove': [event: MouseEvent, tagId?: number | string]
|
|
28
|
+
'update': [event: MouseEvent, name: string, tagId?: number | string]
|
|
29
|
+
'update:modelValue': [value: (number | string)[]]
|
|
30
|
+
}>()
|
|
31
|
+
|
|
32
|
+
const keyForTagCreation = ref(Date.now())
|
|
33
|
+
const keyForTagUpdate = ref(Date.now())
|
|
34
|
+
const root = ref<HTMLDivElement>()
|
|
35
|
+
const showingAllTags = ref(false)
|
|
36
|
+
const showingTagCreationField = ref(false)
|
|
37
|
+
|
|
38
|
+
const { t } = useI18n()
|
|
39
|
+
|
|
40
|
+
const sortedTags = computed({
|
|
41
|
+
get() {
|
|
42
|
+
return props.tags
|
|
43
|
+
.slice()
|
|
44
|
+
.filter((_tag, tagIndex) => tagIndex < props.maxTags || showingAllTags.value)
|
|
45
|
+
.sort((tagA, tagB) => (tagA.order! < tagB.order! ? -1 : 0))
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
set(tags) {
|
|
49
|
+
const suiteForTags = tags
|
|
50
|
+
.map((tag, order) => ({
|
|
51
|
+
id: tag.id,
|
|
52
|
+
order,
|
|
53
|
+
}))
|
|
54
|
+
.map(tag => ({
|
|
55
|
+
id: tag.id,
|
|
56
|
+
order: tag.order,
|
|
57
|
+
}))
|
|
58
|
+
|
|
59
|
+
return suiteForTags
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
function onCreateTag(event: MouseEvent, name: string) {
|
|
64
|
+
showingTagCreationField.value = false
|
|
65
|
+
keyForTagCreation.value = Date.now()
|
|
66
|
+
|
|
67
|
+
emit('create', event, name)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function onGoBack(event: MouseEvent) {
|
|
71
|
+
emit('back', event)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function onShowTagField() {
|
|
75
|
+
if (!showingTagCreationField.value) {
|
|
76
|
+
showingTagCreationField.value = true
|
|
77
|
+
|
|
78
|
+
// Focus contenteditable
|
|
79
|
+
nextTick(() => {
|
|
80
|
+
const element = root.value?.querySelector<HTMLInputElement>('input[type="text"]')
|
|
81
|
+
|
|
82
|
+
element?.focus()
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function onShowAllTags() {
|
|
88
|
+
showingAllTags.value = true
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function onTagClick(event: MouseEvent, tagId?: number | string) {
|
|
92
|
+
if (props.selectable && tagId) {
|
|
93
|
+
let value = [...props.value]
|
|
94
|
+
|
|
95
|
+
if (value.includes(tagId)) {
|
|
96
|
+
value.splice(value.indexOf(tagId), 1)
|
|
97
|
+
emit('detach', event, tagId)
|
|
98
|
+
}
|
|
99
|
+
else if (props.selectableUnique) {
|
|
100
|
+
value = [tagId]
|
|
101
|
+
emit('attach', event, tagId)
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
value.push(tagId)
|
|
105
|
+
emit('attach', event, tagId)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
emit('update:modelValue', value)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function onUpdateTag(event: MouseEvent, name: string, tagId?: number | string) {
|
|
113
|
+
if (name) {
|
|
114
|
+
emit('update', event, name, tagId)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
else {
|
|
118
|
+
keyForTagUpdate.value = Date.now()
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function onRemoveTag(event: MouseEvent, tagId?: number | string) {
|
|
123
|
+
emit('remove', event, tagId)
|
|
124
|
+
}
|
|
125
|
+
</script>
|
|
126
|
+
|
|
127
|
+
<template>
|
|
128
|
+
<div
|
|
129
|
+
ref="root"
|
|
130
|
+
class="flex items-center"
|
|
131
|
+
:class="{
|
|
132
|
+
'flex-wrap': wrap,
|
|
133
|
+
'w-full overflow-x-auto': !wrap,
|
|
134
|
+
|
|
135
|
+
'-mt-0.75 -ml-0.75': size === 'sm',
|
|
136
|
+
'-mt-1 -ml-1': size === 'base',
|
|
137
|
+
}"
|
|
138
|
+
>
|
|
139
|
+
<BaseTag
|
|
140
|
+
v-if="hasBack"
|
|
141
|
+
key="BaseTagToGoBack"
|
|
142
|
+
:class="{
|
|
143
|
+
'm-0.75': size === 'sm',
|
|
144
|
+
'm-1': size === 'base',
|
|
145
|
+
}"
|
|
146
|
+
color="indigo"
|
|
147
|
+
:icon="getIcon('back')"
|
|
148
|
+
:size="size"
|
|
149
|
+
:text="t('globals.cancel')"
|
|
150
|
+
@click="onGoBack"
|
|
151
|
+
/>
|
|
152
|
+
|
|
153
|
+
<BaseTag
|
|
154
|
+
v-if="hasCreation"
|
|
155
|
+
:key="keyForTagCreation"
|
|
156
|
+
:class="{
|
|
157
|
+
'm-0.75': size === 'sm',
|
|
158
|
+
'm-1': size === 'base',
|
|
159
|
+
}"
|
|
160
|
+
color="indigo"
|
|
161
|
+
:editable="showingTagCreationField"
|
|
162
|
+
:icon="showingTagCreationField ? getIcon('tags') : getIcon('plus')"
|
|
163
|
+
is-creation
|
|
164
|
+
:light="false"
|
|
165
|
+
:size="size"
|
|
166
|
+
:text="showingTagCreationField ? '' : t('newTag')"
|
|
167
|
+
@click="onShowTagField"
|
|
168
|
+
@input:blur="onCreateTag"
|
|
169
|
+
@input:submit="onCreateTag"
|
|
170
|
+
/>
|
|
171
|
+
|
|
172
|
+
<div class="flex items-center">
|
|
173
|
+
<span
|
|
174
|
+
v-for="(tag, tagIndex) in sortedTags"
|
|
175
|
+
:key="tag.id ? `${tag.id}_${tag.order}_${keyForTagUpdate}` : tagIndex"
|
|
176
|
+
class="flex flex-wrap items-center"
|
|
177
|
+
:class="{
|
|
178
|
+
'm-0.75': size === 'sm',
|
|
179
|
+
'm-1': size === 'base',
|
|
180
|
+
}"
|
|
181
|
+
>
|
|
182
|
+
<template v-if="tag">
|
|
183
|
+
<BaseTag
|
|
184
|
+
:id="tag.id || tagIndex"
|
|
185
|
+
:key="`${tag.id}_${tagIndex}`"
|
|
186
|
+
:active="tag.id && value.includes(tag.id) || tag.active"
|
|
187
|
+
:avatar="tag.avatar"
|
|
188
|
+
:circle="tag.circle"
|
|
189
|
+
:clickable="clickable"
|
|
190
|
+
:color="tag.color"
|
|
191
|
+
:draggable="draggable"
|
|
192
|
+
:editable="editable"
|
|
193
|
+
:icon="tag.icon"
|
|
194
|
+
:icon-size="tag.iconSize"
|
|
195
|
+
:light="tag.light"
|
|
196
|
+
:removable="removable"
|
|
197
|
+
:size="size"
|
|
198
|
+
:text="tag.text"
|
|
199
|
+
:to="tag.to"
|
|
200
|
+
@click="onTagClick"
|
|
201
|
+
@input:blur="onUpdateTag"
|
|
202
|
+
@input:submit="onUpdateTag"
|
|
203
|
+
@remove="onRemoveTag"
|
|
204
|
+
/>
|
|
205
|
+
</template>
|
|
206
|
+
</span>
|
|
207
|
+
</div>
|
|
208
|
+
|
|
209
|
+
<BaseTag
|
|
210
|
+
v-if="tags.length > maxTags && !showingAllTags"
|
|
211
|
+
key="showMore"
|
|
212
|
+
:class="{
|
|
213
|
+
'm-0.75': size === 'sm',
|
|
214
|
+
'm-1': size === 'base',
|
|
215
|
+
}"
|
|
216
|
+
:size="size"
|
|
217
|
+
:text="t('showMore', { value: tags.length - maxTags })"
|
|
218
|
+
@click="onShowAllTags"
|
|
219
|
+
/>
|
|
220
|
+
</div>
|
|
221
|
+
</template>
|
|
222
|
+
|
|
223
|
+
<i18n lang="json">
|
|
224
|
+
{
|
|
225
|
+
"en": {
|
|
226
|
+
"newTag": "New tag",
|
|
227
|
+
"showMore": "& {value} other | & {value} others"
|
|
228
|
+
},
|
|
229
|
+
"fr": {
|
|
230
|
+
"newTag": "Nouveau tag",
|
|
231
|
+
"showMore": "& {value} autre | & {value} autres"
|
|
232
|
+
},
|
|
233
|
+
"ja": {
|
|
234
|
+
"newTag": "新しいタグ",
|
|
235
|
+
"showMore": "& {value} その他 | & {value} その他"
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
</i18n>
|
|
@@ -12,12 +12,16 @@ const icons = {
|
|
|
12
12
|
arrowDown: 'solar:alt-arrow-down-bold',
|
|
13
13
|
arrowRight: 'solar:alt-arrow-right-bold',
|
|
14
14
|
arrowUp: 'solar:alt-arrow-up-bold',
|
|
15
|
+
back: 'hugeicons:arrow-turn-backward',
|
|
15
16
|
checkCircle: 'hugeicons:checkmark-circle-02',
|
|
16
17
|
close: 'hugeicons:cancel-01',
|
|
17
18
|
closeCircle: 'hugeicons:cancel-circle',
|
|
18
19
|
default: 'hugeicons:help-circle',
|
|
20
|
+
drag: 'mdi:drag-horizontal-variant',
|
|
19
21
|
exclamationCircle: 'hugeicons:alert-circle',
|
|
20
22
|
infoCircle: 'hugeicons:information-circle',
|
|
23
|
+
plus: 'hugeicons:add-01',
|
|
24
|
+
tags: 'hugeicons:tags',
|
|
21
25
|
} as const
|
|
22
26
|
|
|
23
27
|
export function getIcon(attribute: keyof typeof icons) {
|
package/app/types/bases.d.ts
CHANGED
|
@@ -262,6 +262,48 @@ export interface BaseSpinner {
|
|
|
262
262
|
uppercase?: boolean
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
+
export interface BaseTag {
|
|
266
|
+
active?: boolean
|
|
267
|
+
avatar?: string
|
|
268
|
+
circle?: string
|
|
269
|
+
clickable?: boolean
|
|
270
|
+
color?: BaseColor
|
|
271
|
+
draggable?: boolean
|
|
272
|
+
editable?: boolean
|
|
273
|
+
icon?: BaseIconValue
|
|
274
|
+
iconSize?: number
|
|
275
|
+
id?: number
|
|
276
|
+
isCreation?: boolean
|
|
277
|
+
light?: boolean
|
|
278
|
+
order?: number
|
|
279
|
+
removable?: boolean
|
|
280
|
+
rounded?: boolean
|
|
281
|
+
size?: BaseTagSize
|
|
282
|
+
text: BaseTextText
|
|
283
|
+
to?: RouteLocationNamedI18n
|
|
284
|
+
truncate?: boolean
|
|
285
|
+
uppercase?: boolean
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export type BaseTagSize = 'base' | 'sm'
|
|
289
|
+
|
|
290
|
+
export interface BaseTags {
|
|
291
|
+
active?: boolean
|
|
292
|
+
clickable?: boolean
|
|
293
|
+
draggable?: boolean
|
|
294
|
+
editable?: boolean
|
|
295
|
+
hasBack?: boolean
|
|
296
|
+
hasCreation?: boolean
|
|
297
|
+
maxTags?: number
|
|
298
|
+
removable?: boolean
|
|
299
|
+
selectable?: boolean
|
|
300
|
+
selectableUnique?: boolean
|
|
301
|
+
size?: BaseTagSize
|
|
302
|
+
tags: BaseTag[]
|
|
303
|
+
value?: (number | string)[]
|
|
304
|
+
wrap?: boolean
|
|
305
|
+
}
|
|
306
|
+
|
|
265
307
|
export interface BaseText {
|
|
266
308
|
background?: BaseTextBackground
|
|
267
309
|
bold?: boolean
|