@bagelink/vue 0.0.354 → 0.0.358
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/dist/components/Card.vue.d.ts +2 -2
- package/dist/components/form/inputs/RichText.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
- package/dist/components/layout/Tabs.vue.d.ts.map +1 -1
- package/dist/index.cjs +70 -46
- package/dist/index.mjs +71 -47
- package/dist/style.css +31 -27
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/BagelFormUtils.d.ts +16 -5
- package/dist/utils/BagelFormUtils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/form/inputs/RichText.vue +169 -158
- package/src/components/form/inputs/SelectInput.vue +47 -39
- package/src/components/layout/Tabs.vue +23 -4
- package/src/types/index.ts +12 -11
- package/src/utils/BagelFormUtils.ts +25 -11
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
<div v-if="editor">
|
|
3
|
+
<Btn
|
|
4
|
+
:flat="!editor.isActive(item.name, item.option)"
|
|
5
|
+
@click="item.command"
|
|
6
|
+
thin
|
|
7
|
+
v-for="item in config"
|
|
8
|
+
v-tooltip="item.name"
|
|
9
|
+
:key="item.name"
|
|
10
|
+
:icon="item.icon"
|
|
11
|
+
:disabled="item.disabled?.()" />
|
|
12
|
+
</div>
|
|
13
|
+
<editor-content :editor="editor" />
|
|
7
14
|
</template>
|
|
8
15
|
|
|
9
16
|
<script setup lang="ts">
|
|
@@ -18,144 +25,143 @@ let editor = $ref<Editor>();
|
|
|
18
25
|
const props = defineProps<{ modelValue: string }>();
|
|
19
26
|
|
|
20
27
|
const focus = () => {
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
if (!editor) throw new Error('editor is not defined');
|
|
29
|
+
return editor.chain().focus();
|
|
23
30
|
};
|
|
24
31
|
|
|
25
|
-
const config: {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
},
|
|
32
|
+
const config: {
|
|
33
|
+
name: string;
|
|
34
|
+
command: any;
|
|
35
|
+
icon: MaterialIcons;
|
|
36
|
+
option?: Record<string, any>;
|
|
37
|
+
disabled?: () => boolean;
|
|
38
|
+
}[] = [
|
|
39
|
+
{
|
|
40
|
+
name: 'bold',
|
|
41
|
+
command: () => focus()?.toggleBold().run(),
|
|
42
|
+
icon: 'format_bold',
|
|
43
|
+
disabled: () => !editor?.can().chain().focus().toggleBold().run(),
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'italic',
|
|
47
|
+
command: () => focus().toggleItalic().run(),
|
|
48
|
+
icon: 'format_italic',
|
|
49
|
+
disabled: () => !editor?.can().chain().focus().toggleItalic().run(),
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'strike',
|
|
53
|
+
command: () => focus().toggleStrike().run(),
|
|
54
|
+
icon: 'format_strikethrough',
|
|
55
|
+
disabled: () => !editor?.can().chain().focus().toggleStrike().run(),
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'code',
|
|
59
|
+
command: () => focus().toggleCode().run(),
|
|
60
|
+
icon: 'code',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'clearMarks',
|
|
64
|
+
command: () => focus().unsetAllMarks(),
|
|
65
|
+
icon: 'clear',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'clearNodes',
|
|
69
|
+
command: () => focus().clearNodes().run(),
|
|
70
|
+
icon: 'clear',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'paragraph',
|
|
74
|
+
command: () => focus().setParagraph().run(),
|
|
75
|
+
icon: 'format_paragraph',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'heading',
|
|
79
|
+
command: () => focus().toggleHeading({ level: 1 }).run(),
|
|
80
|
+
icon: 'format_h1',
|
|
81
|
+
option: { level: 1 },
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'heading',
|
|
85
|
+
command: () => focus().toggleHeading({ level: 2 }).run(),
|
|
86
|
+
icon: 'format_h2',
|
|
87
|
+
option: { level: 2 },
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: 'heading',
|
|
91
|
+
command: () => focus().toggleHeading({ level: 3 }).run(),
|
|
92
|
+
icon: 'format_h3',
|
|
93
|
+
option: { level: 3 },
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'heading',
|
|
97
|
+
command: () => focus().toggleHeading({ level: 4 }).run(),
|
|
98
|
+
icon: 'format_h4',
|
|
99
|
+
option: { level: 4 },
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'heading',
|
|
103
|
+
command: () => focus().toggleHeading({ level: 5 }).run(),
|
|
104
|
+
icon: 'format_h5',
|
|
105
|
+
option: { level: 5 },
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'heading',
|
|
109
|
+
command: () => focus().toggleHeading({ level: 6 }).run(),
|
|
110
|
+
icon: 'format_h6',
|
|
111
|
+
option: { level: 6 },
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'bulletList',
|
|
115
|
+
command: () => focus().toggleBulletList().run(),
|
|
116
|
+
icon: 'format_list_bulleted',
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'orderedList',
|
|
120
|
+
command: () => focus().toggleOrderedList().run(),
|
|
121
|
+
icon: 'format_list_numbered',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: 'codeBlock',
|
|
125
|
+
command: () => focus().toggleCodeBlock().run(),
|
|
126
|
+
icon: 'code',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: 'blockquote',
|
|
130
|
+
command: () => focus().toggleBlockquote().run(),
|
|
131
|
+
icon: 'format_quote',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: 'horizontalRule',
|
|
135
|
+
command: () => focus().setHorizontalRule().run(),
|
|
136
|
+
icon: 'horizontal_rule',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: 'hardBreak',
|
|
140
|
+
command: () => focus().setHardBreak().run(),
|
|
141
|
+
icon: 'keyboard_return',
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: 'undo',
|
|
145
|
+
command: () => focus().undo().run(),
|
|
146
|
+
icon: 'undo',
|
|
147
|
+
disabled: () => !editor?.can().chain().focus().undo().run(),
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: 'redo',
|
|
151
|
+
command: () => focus().redo().run(),
|
|
152
|
+
icon: 'redo',
|
|
153
|
+
disabled: () => !editor?.can().chain().focus().redo().run(),
|
|
154
|
+
},
|
|
149
155
|
];
|
|
150
156
|
|
|
151
157
|
const emit = defineEmits(['update:modelValue']);
|
|
152
158
|
|
|
153
159
|
onMounted(() => {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
editor = new Editor({
|
|
161
|
+
extensions: [StarterKit],
|
|
162
|
+
content: props.modelValue,
|
|
163
|
+
onUpdate: ({ editor }) => emit('update:modelValue', editor.getHTML()),
|
|
164
|
+
});
|
|
159
165
|
});
|
|
160
166
|
|
|
161
167
|
onBeforeUnmount(() => editor?.destroy());
|
|
@@ -163,13 +169,13 @@ onBeforeUnmount(() => editor?.destroy());
|
|
|
163
169
|
|
|
164
170
|
<style>
|
|
165
171
|
/* Basic editor styles */
|
|
166
|
-
.tiptap
|
|
167
|
-
|
|
172
|
+
.tiptap > * + * {
|
|
173
|
+
margin-top: 0.75em;
|
|
168
174
|
}
|
|
169
175
|
|
|
170
176
|
.tiptap ul,
|
|
171
177
|
.tiptap ol {
|
|
172
|
-
|
|
178
|
+
padding: 0 1rem;
|
|
173
179
|
}
|
|
174
180
|
|
|
175
181
|
.tiptap h1,
|
|
@@ -178,42 +184,47 @@ onBeforeUnmount(() => editor?.destroy());
|
|
|
178
184
|
.tiptap h4,
|
|
179
185
|
.tiptap h5,
|
|
180
186
|
.tiptap h6 {
|
|
181
|
-
|
|
187
|
+
line-height: 1.1;
|
|
182
188
|
}
|
|
183
189
|
|
|
184
190
|
.tiptap code {
|
|
185
|
-
|
|
186
|
-
|
|
191
|
+
background-color: rgba(97, 97, 97, 0.1);
|
|
192
|
+
color: #616161;
|
|
187
193
|
}
|
|
188
194
|
|
|
189
195
|
.tiptap pre {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
196
|
+
background: #0d0d0d;
|
|
197
|
+
color: #fff;
|
|
198
|
+
font-family: 'JetBrainsMono', monospace;
|
|
199
|
+
padding: 0.75rem 1rem;
|
|
200
|
+
border-radius: 0.5rem;
|
|
195
201
|
}
|
|
196
202
|
|
|
197
203
|
.tiptap pre code {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
204
|
+
color: inherit;
|
|
205
|
+
padding: 0;
|
|
206
|
+
background: none;
|
|
207
|
+
font-size: 0.8rem;
|
|
202
208
|
}
|
|
203
209
|
|
|
204
210
|
.tiptap img {
|
|
205
|
-
|
|
206
|
-
|
|
211
|
+
max-width: 100%;
|
|
212
|
+
height: auto;
|
|
207
213
|
}
|
|
208
214
|
|
|
209
215
|
.tiptap blockquote {
|
|
210
|
-
|
|
211
|
-
|
|
216
|
+
padding-left: 1rem;
|
|
217
|
+
border-left: 2px solid rgba(13, 13, 13, 0.1);
|
|
212
218
|
}
|
|
213
219
|
|
|
214
220
|
.tiptap hr {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
221
|
+
border: none;
|
|
222
|
+
border-top: 2px solid rgba(13, 13, 13, 0.1);
|
|
223
|
+
margin: 2rem 0;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.tiptap {
|
|
227
|
+
min-height: 500px;
|
|
228
|
+
background: var(--input-bg);
|
|
218
229
|
}
|
|
219
230
|
</style>
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
@hide="updateOpen(false)"
|
|
4
4
|
ref="dropdown"
|
|
5
5
|
placement="bottom-start"
|
|
6
|
-
class="bagel-input selectinput"
|
|
7
|
-
>
|
|
6
|
+
class="bagel-input selectinput">
|
|
8
7
|
<label>
|
|
9
8
|
{{ label }}
|
|
10
9
|
<button
|
|
@@ -12,44 +11,39 @@
|
|
|
12
11
|
:disabled="disabled"
|
|
13
12
|
type="button"
|
|
14
13
|
class="selectinput-btn"
|
|
15
|
-
:class="{isEmpty: selectedItems.length ===0}"
|
|
16
|
-
>
|
|
14
|
+
:class="{ isEmpty: selectedItems.length === 0 }">
|
|
17
15
|
<p>{{ selectedLabel }}</p>
|
|
18
16
|
<Icon v-bind="{ icon: open ? 'unfold_less' : 'unfold_more' }" />
|
|
19
17
|
</button>
|
|
20
18
|
<input
|
|
21
19
|
style="width: 0; height: 0; position: absolute; opacity: 0; z-index: -1"
|
|
22
20
|
v-if="required"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
@input="updateOpen(true)"
|
|
22
|
+
:value="selectedItems"
|
|
23
|
+
required />
|
|
26
24
|
</label>
|
|
27
25
|
<template #popper="{ hide }">
|
|
28
26
|
<Card
|
|
29
27
|
class="selectinput-options p-05"
|
|
30
|
-
:style="{ width: fullWidth ? '100%' : 'auto' }"
|
|
31
|
-
>
|
|
28
|
+
:style="{ width: fullWidth ? '100%' : 'auto' }">
|
|
32
29
|
<TextInput
|
|
33
30
|
v-if="searchable"
|
|
34
31
|
ref="searchInput"
|
|
35
32
|
dense
|
|
36
33
|
:placeholder="'Search'"
|
|
37
34
|
icon="search"
|
|
38
|
-
v-model="search"
|
|
39
|
-
/>
|
|
35
|
+
v-model="search" />
|
|
40
36
|
<div
|
|
41
37
|
class="selectinput-option hover gap-1"
|
|
42
38
|
v-for="(option, i) in filteredOptions"
|
|
43
39
|
:key="`${option}${i}`"
|
|
44
40
|
@click="select(option)"
|
|
45
|
-
:class="{ selected: isSelected(option) }"
|
|
46
|
-
>
|
|
41
|
+
:class="{ selected: isSelected(option) }">
|
|
47
42
|
<Icon v-if="isSelected(option)" icon="check" />
|
|
48
43
|
<Icon
|
|
49
44
|
class="opacity-3"
|
|
50
45
|
v-if="!isSelected(option)"
|
|
51
|
-
icon="fiber_manual_record"
|
|
52
|
-
/>
|
|
46
|
+
icon="fiber_manual_record" />
|
|
53
47
|
<span>
|
|
54
48
|
{{ getLabel(option) }}
|
|
55
49
|
</span>
|
|
@@ -99,7 +93,7 @@ function updateOpen(visible: boolean) {
|
|
|
99
93
|
else {
|
|
100
94
|
setTimeout(
|
|
101
95
|
() => (searchInput as any)?.$el?.querySelector('input')?.focus(),
|
|
102
|
-
100
|
|
96
|
+
100
|
|
103
97
|
);
|
|
104
98
|
}
|
|
105
99
|
}
|
|
@@ -130,18 +124,23 @@ const getValue = (option: Option) => {
|
|
|
130
124
|
return option.value;
|
|
131
125
|
};
|
|
132
126
|
|
|
133
|
-
const isSelected = (option: Option) =>
|
|
127
|
+
const isSelected = (option: Option) =>
|
|
128
|
+
!!selectedItems.find((item) => getValue(option) === getValue(item));
|
|
134
129
|
|
|
135
|
-
const filteredOptions = $computed(() =>
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
130
|
+
const filteredOptions = $computed(() =>
|
|
131
|
+
props.options.filter((option) => {
|
|
132
|
+
const searchTerm = new RegExp(search, 'gi');
|
|
133
|
+
return (
|
|
134
|
+
Boolean(option) &&
|
|
139
135
|
(getLabel(option).match(searchTerm) || getValue(option).match(searchTerm))
|
|
140
|
-
|
|
141
|
-
})
|
|
136
|
+
);
|
|
137
|
+
})
|
|
138
|
+
);
|
|
142
139
|
|
|
143
140
|
const select = (option: Option) => {
|
|
144
|
-
const existingIndex = selectedItems.findIndex(
|
|
141
|
+
const existingIndex = selectedItems.findIndex(
|
|
142
|
+
(item) => getValue(item) === getValue(option)
|
|
143
|
+
);
|
|
145
144
|
if (existingIndex > -1) selectedItems.splice(existingIndex, 1);
|
|
146
145
|
else if (props.multiselect) {
|
|
147
146
|
selectedItems.push(option);
|
|
@@ -163,7 +162,9 @@ function emitUpdate() {
|
|
|
163
162
|
}
|
|
164
163
|
|
|
165
164
|
function compareArrays(arr1: Option[], arr2: Option[]) {
|
|
166
|
-
const isSame = arr1.every((item: Option) =>
|
|
165
|
+
const isSame = arr1.every((item: Option) =>
|
|
166
|
+
arr2.map((a) => getValue(a)).includes(getValue(item))
|
|
167
|
+
);
|
|
167
168
|
return isSame;
|
|
168
169
|
}
|
|
169
170
|
|
|
@@ -172,25 +173,32 @@ watch(
|
|
|
172
173
|
(newVal: Option | Option[]) => {
|
|
173
174
|
if (!newVal) return;
|
|
174
175
|
if (!props.multiselect) {
|
|
175
|
-
if (!isSelected(newVal))
|
|
176
|
+
if (!isSelected(newVal))
|
|
177
|
+
selectedItems.splice(0, selectedItems.length, newVal);
|
|
176
178
|
} else {
|
|
177
179
|
const isSame = compareArrays([newVal].flat(), selectedItems);
|
|
178
|
-
if (!isSame)
|
|
180
|
+
if (!isSame)
|
|
181
|
+
selectedItems.splice(0, selectedItems.length, [newVal].flat());
|
|
179
182
|
}
|
|
180
183
|
},
|
|
181
|
-
{ immediate: true }
|
|
184
|
+
{ immediate: true }
|
|
182
185
|
);
|
|
183
186
|
|
|
184
|
-
watch(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
187
|
+
watch(
|
|
188
|
+
() => props.options,
|
|
189
|
+
() => {
|
|
190
|
+
const original = JSON.stringify(selectedItems);
|
|
191
|
+
[...selectedItems].forEach((option, i) => {
|
|
192
|
+
const exists = props.options.find(
|
|
193
|
+
(o) => getValue(o) === getValue(option)
|
|
194
|
+
);
|
|
195
|
+
if (!exists) selectedItems.splice(i, 1);
|
|
196
|
+
else selectedItems.splice(i, 1, exists);
|
|
197
|
+
});
|
|
198
|
+
const newSelection = JSON.stringify(selectedItems);
|
|
199
|
+
if (original !== newSelection) emitUpdate();
|
|
200
|
+
}
|
|
201
|
+
);
|
|
194
202
|
</script>
|
|
195
203
|
|
|
196
204
|
<style scoped>
|
|
@@ -218,7 +226,7 @@ watch(() => props.options, () => {
|
|
|
218
226
|
.selectinput-option:hover {
|
|
219
227
|
background: var(--bgl-gray-20);
|
|
220
228
|
}
|
|
221
|
-
.isEmpty p{
|
|
229
|
+
.isEmpty p {
|
|
222
230
|
opacity: 0.3;
|
|
223
231
|
}
|
|
224
232
|
</style>
|
|
@@ -1,19 +1,38 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<TabsNav :tabs="tabs" :group="group" class="mb-05" />
|
|
3
3
|
<div v-if="currentTab">
|
|
4
|
-
<
|
|
4
|
+
<template v-if="slots[currentTab]">
|
|
5
|
+
<slot :name="currentTab" />
|
|
6
|
+
</template>
|
|
7
|
+
<template v-else-if="currentTab">
|
|
8
|
+
<component :is="tabComponent" />
|
|
9
|
+
</template>
|
|
5
10
|
</div>
|
|
6
11
|
</template>
|
|
7
12
|
|
|
8
13
|
<script setup lang="ts">
|
|
9
14
|
import { TabsNav, type Tab } from '@bagelink/vue';
|
|
15
|
+
import { defineProps, useSlots, h, defineComponent } from 'vue';
|
|
10
16
|
import { useTabs } from './tabsManager';
|
|
11
17
|
|
|
12
|
-
defineProps<{
|
|
13
|
-
|
|
14
|
-
|
|
18
|
+
const props = defineProps<{
|
|
19
|
+
tabs: Tab[];
|
|
20
|
+
modelValue?: string;
|
|
15
21
|
}>();
|
|
16
22
|
|
|
23
|
+
const slots = useSlots();
|
|
17
24
|
const group = Math.random().toString(36).substring(7);
|
|
18
25
|
const { currentTab } = useTabs(group);
|
|
26
|
+
|
|
27
|
+
const tabValue = (tab: Tab) => (typeof tab === 'string' ? tab : tab.id);
|
|
28
|
+
|
|
29
|
+
const tabComponent = defineComponent({
|
|
30
|
+
render() {
|
|
31
|
+
const currentTabIndex = props.tabs.findIndex(
|
|
32
|
+
(tab) => tabValue(tab) === currentTab.value
|
|
33
|
+
);
|
|
34
|
+
const slotChildren = slots?.default?.()?.[1]?.children;
|
|
35
|
+
return h('div', slotChildren?.[currentTabIndex]);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
19
38
|
</script>
|
package/src/types/index.ts
CHANGED
|
@@ -13,17 +13,18 @@ export * from './BtnOptions';
|
|
|
13
13
|
export * from './BagelForm';
|
|
14
14
|
|
|
15
15
|
export type Tab = {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
label: string;
|
|
17
|
+
id: string;
|
|
18
|
+
icon?: MaterialIcons;
|
|
19
19
|
} | string
|
|
20
20
|
|
|
21
21
|
export type ThemeType = |
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
'light'
|
|
23
|
+
| 'white'
|
|
24
|
+
| 'red'
|
|
25
|
+
| 'gray'
|
|
26
|
+
| 'gray-light'
|
|
27
|
+
| 'black'
|
|
28
|
+
| 'green'
|
|
29
|
+
| 'primary'
|
|
30
|
+
| 'blue' // ! blue does nothing
|