@meistrari/tela-build 1.57.3 → 1.57.4
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/components/tela/code-block/code-block.vue +25 -17
- package/components/tela/code-block/highlighter.ts +79 -0
- package/components/tela/code-block/tela-theme.ts +3 -1
- package/components/tela/icon/custom.vue +28 -17
- package/components/tela/input/input.mdx +1 -8
- package/components/tela/input/input.vue +1 -4
- package/components/tela/input-otp/input-otp.mdx +2 -1
- package/components/tela/skeleton/skeleton.mdx +3 -1
- package/nuxt.config.ts +18 -1
- package/package.json +1 -1
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import type { HTMLAttributes } from 'vue'
|
|
3
3
|
|
|
4
4
|
import type { BuiltinLanguage } from 'shiki'
|
|
5
|
-
import { codeToHtml } from 'shiki'
|
|
6
5
|
|
|
6
|
+
import { highlightCode } from './highlighter'
|
|
7
7
|
import { TelaTheme } from './tela-theme'
|
|
8
8
|
|
|
9
9
|
const props = withDefaults(defineProps<{
|
|
@@ -33,24 +33,32 @@ const theme = computed(() => TelaTheme(props.background ?? 'transparent'))
|
|
|
33
33
|
const lineCount = computed(() => props.code?.split('\n').length || 1)
|
|
34
34
|
const isSingleLine = computed(() => lineCount.value === 1)
|
|
35
35
|
|
|
36
|
-
watchEffect(() => {
|
|
37
|
-
if (props.code
|
|
38
|
-
isLoading.value = true
|
|
39
|
-
codeToHtml(props.code, {
|
|
40
|
-
lang: props.language,
|
|
41
|
-
theme: theme.value,
|
|
42
|
-
})
|
|
43
|
-
.then((html) => {
|
|
44
|
-
highlighted.value = html
|
|
45
|
-
isLoading.value = false
|
|
46
|
-
})
|
|
47
|
-
.catch(() => {
|
|
48
|
-
isLoading.value = false
|
|
49
|
-
})
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
36
|
+
watchEffect((onCleanup) => {
|
|
37
|
+
if (!props.code || !props.language) {
|
|
52
38
|
isLoading.value = false
|
|
39
|
+
return
|
|
53
40
|
}
|
|
41
|
+
|
|
42
|
+
let stale = false
|
|
43
|
+
|
|
44
|
+
onCleanup(() => {
|
|
45
|
+
stale = true
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
isLoading.value = true
|
|
49
|
+
|
|
50
|
+
highlightCode(props.code, props.language, theme.value)
|
|
51
|
+
.then((html) => {
|
|
52
|
+
if (stale)
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
highlighted.value = html
|
|
56
|
+
isLoading.value = false
|
|
57
|
+
})
|
|
58
|
+
.catch(() => {
|
|
59
|
+
if (!stale)
|
|
60
|
+
isLoading.value = false
|
|
61
|
+
})
|
|
54
62
|
})
|
|
55
63
|
</script>
|
|
56
64
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { HighlighterCore, LanguageInput, ThemeRegistrationAny } from 'shiki/core'
|
|
2
|
+
import { createHighlighterCore } from 'shiki/core'
|
|
3
|
+
import { createJavaScriptRegexEngine } from 'shiki/engine/javascript'
|
|
4
|
+
import { bundledLanguages } from 'shiki/langs'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Shiki loaded through the fine-grained core API instead of the `shiki` bundle
|
|
8
|
+
* entry. The bundle entry pulls in the Oniguruma engine, whose WASM is
|
|
9
|
+
* base64-inlined into the JS chunk (~640KB parsed on first import) even when a
|
|
10
|
+
* page never renders a code block. The JavaScript regex engine covers every
|
|
11
|
+
* grammar we ship and costs nothing up front.
|
|
12
|
+
*
|
|
13
|
+
* Every bundled language stays available: `bundledLanguages` is a map of
|
|
14
|
+
* dynamic imports, so a grammar is only fetched when a code block asks for it.
|
|
15
|
+
* Grammars and themes are registered once and shared across every
|
|
16
|
+
* TelaCodeBlock instance, so a page with twenty code blocks loads each grammar
|
|
17
|
+
* a single time.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** Names shiki treats as plain text — no grammar to load. */
|
|
21
|
+
const plainLanguages = new Set(['text', 'plaintext', 'txt', 'plain', 'ansi'])
|
|
22
|
+
|
|
23
|
+
let highlighterPromise: Promise<HighlighterCore> | undefined
|
|
24
|
+
|
|
25
|
+
const themeLoads = new Map<string, Promise<void>>()
|
|
26
|
+
const languageLoads = new Map<string, Promise<void>>()
|
|
27
|
+
|
|
28
|
+
async function getHighlighter() {
|
|
29
|
+
highlighterPromise ??= createHighlighterCore({
|
|
30
|
+
themes: [],
|
|
31
|
+
langs: [],
|
|
32
|
+
// `forgiving` downgrades the few Oniguruma-only patterns to a no-match
|
|
33
|
+
// instead of throwing, so an exotic grammar degrades to partial
|
|
34
|
+
// highlighting rather than failing the whole block
|
|
35
|
+
engine: createJavaScriptRegexEngine({ forgiving: true }),
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
return await highlighterPromise
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function loadTheme(highlighter: HighlighterCore, theme: ThemeRegistrationAny) {
|
|
42
|
+
const name = theme.name ?? 'default'
|
|
43
|
+
|
|
44
|
+
let pending = themeLoads.get(name)
|
|
45
|
+
|
|
46
|
+
if (!pending) {
|
|
47
|
+
pending = highlighter.loadTheme(theme).then(() => undefined)
|
|
48
|
+
themeLoads.set(name, pending)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return await pending
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function loadLanguage(highlighter: HighlighterCore, language: string) {
|
|
55
|
+
let pending = languageLoads.get(language)
|
|
56
|
+
|
|
57
|
+
if (!pending) {
|
|
58
|
+
const grammar = bundledLanguages[language as keyof typeof bundledLanguages] as LanguageInput
|
|
59
|
+
|
|
60
|
+
pending = highlighter.loadLanguage(grammar).then(() => undefined)
|
|
61
|
+
languageLoads.set(language, pending)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return await pending
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export async function highlightCode(code: string, language: string, theme: ThemeRegistrationAny) {
|
|
68
|
+
const highlighter = await getHighlighter()
|
|
69
|
+
|
|
70
|
+
// an unknown language renders as plain text rather than throwing
|
|
71
|
+
const resolved = !plainLanguages.has(language) && Object.hasOwn(bundledLanguages, language) ? language : 'text'
|
|
72
|
+
|
|
73
|
+
await Promise.all([
|
|
74
|
+
loadTheme(highlighter, theme),
|
|
75
|
+
resolved === 'text' ? undefined : loadLanguage(highlighter, resolved),
|
|
76
|
+
])
|
|
77
|
+
|
|
78
|
+
return highlighter.codeToHtml(code, { lang: resolved, theme: theme.name ?? 'default' })
|
|
79
|
+
}
|
|
@@ -2,7 +2,9 @@ import type { RawTheme } from 'shiki'
|
|
|
2
2
|
|
|
3
3
|
export function TelaTheme(background = '#FAFAFB') {
|
|
4
4
|
return ({
|
|
5
|
-
|
|
5
|
+
// the background is baked into the theme, so it has to be part of the
|
|
6
|
+
// name — the highlighter registers and caches themes by name
|
|
7
|
+
name: `tela-light-${background}`,
|
|
6
8
|
colors: {
|
|
7
9
|
'editor.background': background,
|
|
8
10
|
},
|
|
@@ -14,6 +14,16 @@ const props = withDefaults(defineProps<{
|
|
|
14
14
|
isAnimated: true,
|
|
15
15
|
})
|
|
16
16
|
|
|
17
|
+
const isMotionReady = ref(false)
|
|
18
|
+
|
|
19
|
+
onMounted(() => {
|
|
20
|
+
requestAnimationFrame(() => {
|
|
21
|
+
isMotionReady.value = true
|
|
22
|
+
})
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
const isMotionActive = computed(() => props.isAnimated && isMotionReady.value)
|
|
26
|
+
|
|
17
27
|
const colorValue = computed(() => {
|
|
18
28
|
if (props.color.startsWith('#')) {
|
|
19
29
|
return props.color
|
|
@@ -38,7 +48,7 @@ const colorValue = computed(() => {
|
|
|
38
48
|
<svg :width="size" :height="size" viewBox="0 0 12 12" fill="none" :style="{ color: colorValue }" xmlns="http://www.w3.org/2000/svg">
|
|
39
49
|
<template v-if="name === 'circle'">
|
|
40
50
|
<component
|
|
41
|
-
:is="
|
|
51
|
+
:is="isMotionActive ? Motion : 'path'"
|
|
42
52
|
as="path"
|
|
43
53
|
d="M12 6C12 9.31371 9.31371 12 6 12C2.68629 12 0 9.31371 0 6C0 2.68629 2.68629 0 6 0C9.31371 0 12 2.68629 12 6ZM1.2 6C1.2 8.65097 3.34903 10.8 6 10.8C8.65097 10.8 10.8 8.65097 10.8 6C10.8 3.34903 8.65097 1.2 6 1.2C3.34903 1.2 1.2 3.34903 1.2 6Z"
|
|
44
54
|
fill="currentColor"
|
|
@@ -59,7 +69,7 @@ const colorValue = computed(() => {
|
|
|
59
69
|
|
|
60
70
|
<template v-if="name === 'queued'">
|
|
61
71
|
<component
|
|
62
|
-
:is="
|
|
72
|
+
:is="isMotionActive ? Motion : 'path'"
|
|
63
73
|
as="path"
|
|
64
74
|
d="M12 6C12 9.31371 9.31371 12 6 12C2.68629 12 0 9.31371 0 6C0 2.68629 2.68629 0 6 0C9.31371 0 12 2.68629 12 6ZM1.2 6C1.2 8.65097 3.34903 10.8 6 10.8C8.65097 10.8 10.8 8.65097 10.8 6C10.8 3.34903 8.65097 1.2 6 1.2C3.34903 1.2 1.2 3.34903 1.2 6Z"
|
|
65
75
|
fill="currentColor"
|
|
@@ -68,7 +78,7 @@ const colorValue = computed(() => {
|
|
|
68
78
|
:transition="{ duration: 0.8, ease: [0.4, 0, 0.2, 1] }"
|
|
69
79
|
/>
|
|
70
80
|
<component
|
|
71
|
-
:is="
|
|
81
|
+
:is="isMotionActive ? Motion : 'rect'"
|
|
72
82
|
as="rect"
|
|
73
83
|
x="3.5"
|
|
74
84
|
y="6.5"
|
|
@@ -81,7 +91,7 @@ const colorValue = computed(() => {
|
|
|
81
91
|
:transition="{ duration: 0.8, ease: 'easeOut', delay: 0.17, repeat: Infinity, repeatDelay: 1 }"
|
|
82
92
|
/>
|
|
83
93
|
<component
|
|
84
|
-
:is="
|
|
94
|
+
:is="isMotionActive ? Motion : 'rect'"
|
|
85
95
|
as="rect"
|
|
86
96
|
x="4"
|
|
87
97
|
y="4.5"
|
|
@@ -94,7 +104,7 @@ const colorValue = computed(() => {
|
|
|
94
104
|
:transition="{ duration: 0.8, ease: 'easeOut', delay: 0.12, repeat: Infinity, repeatDelay: 1 }"
|
|
95
105
|
/>
|
|
96
106
|
<component
|
|
97
|
-
:is="
|
|
107
|
+
:is="isMotionActive ? Motion : 'rect'"
|
|
98
108
|
as="rect"
|
|
99
109
|
x="4.5"
|
|
100
110
|
y="3"
|
|
@@ -124,7 +134,8 @@ const colorValue = computed(() => {
|
|
|
124
134
|
</template>
|
|
125
135
|
|
|
126
136
|
<template v-if="name === 'circle-notch'">
|
|
127
|
-
<
|
|
137
|
+
<component
|
|
138
|
+
:is="isMotionActive ? Motion : 'path'"
|
|
128
139
|
as="path"
|
|
129
140
|
d="M11.4 6C11.7314 6 12.0031 5.73069 11.97 5.40098C11.858 4.28448 11.4345 3.21734 10.7422 2.32414C9.92681 1.27227 8.78487 0.521339 7.49603 0.189501C6.20719 -0.142337 4.84459 -0.0362459 3.62264 0.491083C2.40069 1.01841 1.38875 1.93705 0.746034 3.10244C0.103318 4.26784 -0.133688 5.61385 0.0723077 6.92869C0.278303 8.24353 0.915607 9.45256 1.88394 10.3656C2.85228 11.2786 4.09668 11.8437 5.42136 11.972C6.5462 12.081 7.67471 11.8698 8.67877 11.3688C8.97528 11.2209 9.05806 10.8474 8.88125 10.5671C8.70444 10.2868 8.3351 10.2068 8.03498 10.3473C7.25926 10.7104 6.39684 10.8609 5.53709 10.7776C4.47735 10.6749 3.48182 10.2228 2.70715 9.49244C1.93249 8.76205 1.42264 7.79482 1.25785 6.74295C1.09305 5.69108 1.28265 4.61427 1.79683 3.68195C2.311 2.74964 3.12055 2.01473 4.09811 1.59287C5.07567 1.171 6.16575 1.08613 7.19682 1.3516C8.2279 1.61707 9.14145 2.21782 9.79373 3.05932C10.3229 3.74201 10.6558 4.55173 10.7626 5.40155C10.8039 5.73033 11.0686 6 11.4 6Z"
|
|
130
141
|
fill="currentColor"
|
|
@@ -136,7 +147,7 @@ const colorValue = computed(() => {
|
|
|
136
147
|
|
|
137
148
|
<template v-if="name === 'circle-minus'">
|
|
138
149
|
<component
|
|
139
|
-
:is="
|
|
150
|
+
:is="isMotionActive ? Motion : 'path'"
|
|
140
151
|
as="path"
|
|
141
152
|
d="M12 6C12 9.31371 9.31371 12 6 12C2.68629 12 0 9.31371 0 6C0 2.68629 2.68629 0 6 0C9.31371 0 12 2.68629 12 6ZM1.2 6C1.2 8.65097 3.34903 10.8 6 10.8C8.65097 10.8 10.8 8.65097 10.8 6C10.8 3.34903 8.65097 1.2 6 1.2C3.34903 1.2 1.2 3.34903 1.2 6Z"
|
|
142
153
|
fill="currentColor"
|
|
@@ -145,7 +156,7 @@ const colorValue = computed(() => {
|
|
|
145
156
|
:transition="{ duration: 2.2, ease: 'easeOut', repeat: Infinity }"
|
|
146
157
|
/>
|
|
147
158
|
<component
|
|
148
|
-
:is="
|
|
159
|
+
:is="isMotionActive ? Motion : 'rect'"
|
|
149
160
|
as="rect"
|
|
150
161
|
x="3.5"
|
|
151
162
|
y="5"
|
|
@@ -161,7 +172,7 @@ const colorValue = computed(() => {
|
|
|
161
172
|
|
|
162
173
|
<template v-if="name === 'check'">
|
|
163
174
|
<component
|
|
164
|
-
:is="
|
|
175
|
+
:is="isMotionActive ? Motion : 'g'"
|
|
165
176
|
as="g"
|
|
166
177
|
:initial="{ opacity: 0.4 }"
|
|
167
178
|
:animate="{ opacity: 1 }"
|
|
@@ -173,7 +184,7 @@ const colorValue = computed(() => {
|
|
|
173
184
|
fill="currentColor"
|
|
174
185
|
/>
|
|
175
186
|
<component
|
|
176
|
-
:is="
|
|
187
|
+
:is="isMotionActive ? Motion : 'path'"
|
|
177
188
|
as="path"
|
|
178
189
|
d="M3.5 6 L5.5 8 L8.5 4"
|
|
179
190
|
stroke="currentColor"
|
|
@@ -184,7 +195,7 @@ const colorValue = computed(() => {
|
|
|
184
195
|
tabindex="-1"
|
|
185
196
|
:initial="{ pathLength: 0 }"
|
|
186
197
|
:animate="{ pathLength: 1 }"
|
|
187
|
-
:style="{ rotate:
|
|
198
|
+
:style="{ rotate: isMotionActive ? 4 : undefined, scale: 0.85, transformOrigin: '6px 6px', transformBox: 'view-box' }"
|
|
188
199
|
:transition="{ duration: 0.3, ease: [0.645, 0.045, 0.355, 1] }"
|
|
189
200
|
/>
|
|
190
201
|
</component>
|
|
@@ -219,14 +230,14 @@ const colorValue = computed(() => {
|
|
|
219
230
|
|
|
220
231
|
<template v-if="name === 'warning'">
|
|
221
232
|
<component
|
|
222
|
-
:is="
|
|
233
|
+
:is="isMotionActive ? Motion : 'g'"
|
|
223
234
|
as="g"
|
|
224
235
|
tabindex="-1"
|
|
225
236
|
:animate="{ opacity: [0.5, 1, 0.5] }"
|
|
226
237
|
:transition="{ duration: 1.4, ease: 'easeOut', repeat: Infinity }"
|
|
227
238
|
>
|
|
228
239
|
<component
|
|
229
|
-
:is="
|
|
240
|
+
:is="isMotionActive ? Motion : 'path'"
|
|
230
241
|
as="path"
|
|
231
242
|
d="M11.4 6C11.7314 6 12.0031 5.73069 11.97 5.40098C11.858 4.28448 11.4345 3.21734 10.7422 2.32414C9.92681 1.27227 8.78487 0.521339 7.49603 0.189501C6.20719 -0.142337 4.84459 -0.0362459 3.62264 0.491083C2.40069 1.01841 1.38875 1.93705 0.746034 3.10244C0.103318 4.26784 -0.133688 5.61385 0.0723077 6.92869C0.278303 8.24353 0.915607 9.45256 1.88394 10.3656C2.85228 11.2786 4.09668 11.8437 5.42136 11.972C6.5462 12.081 7.67471 11.8698 8.67877 11.3688C8.97528 11.2209 9.05806 10.8474 8.88125 10.5671C8.70444 10.2868 8.3351 10.2068 8.03498 10.3473C7.25926 10.7104 6.39684 10.8609 5.53709 10.7776C4.47735 10.6749 3.48182 10.2228 2.70715 9.49244C1.93249 8.76205 1.42264 7.79482 1.25785 6.74295C1.09305 5.69108 1.28265 4.61427 1.79683 3.68195C2.311 2.74964 3.12055 2.01473 4.09811 1.59287C5.07567 1.171 6.16575 1.08613 7.19682 1.3516C8.2279 1.61707 9.14145 2.21782 9.79373 3.05932C10.3229 3.74201 10.6558 4.55173 10.7626 5.40155C10.8039 5.73033 11.0686 6 11.4 6Z"
|
|
232
243
|
fill="currentColor"
|
|
@@ -235,7 +246,7 @@ const colorValue = computed(() => {
|
|
|
235
246
|
:transition="{ duration: 0.7, ease: 'easeOut', repeat: Infinity, repeatDelay: 0.1 }"
|
|
236
247
|
/>
|
|
237
248
|
<component
|
|
238
|
-
:is="
|
|
249
|
+
:is="isMotionActive ? Motion : 'rect'"
|
|
239
250
|
as="rect"
|
|
240
251
|
x="5.25"
|
|
241
252
|
y="3"
|
|
@@ -259,7 +270,7 @@ const colorValue = computed(() => {
|
|
|
259
270
|
|
|
260
271
|
<template v-if="name === 'check-dashed'">
|
|
261
272
|
<component
|
|
262
|
-
:is="
|
|
273
|
+
:is="isMotionActive ? Motion : 'g'" as="g" clip-path="url(#clip0_5125_104)" tabindex="-1" :initial="{ opacity: 0.4 }" :animate="{ opacity: 1 }" :transition="{ duration: 0.3, ease: [0.645, 0.045, 0.355, 1] }"
|
|
263
274
|
>
|
|
264
275
|
<path d="M12 6C12 9.31371 9.31371 12 6 12C2.68629 12 0 9.31371 0 6C0 2.68629 2.68629 0 6 0C9.31371 0 12 2.68629 12 6ZM1.2 6C1.2 8.65097 3.34903 10.8 6 10.8C8.65097 10.8 10.8 8.65097 10.8 6C10.8 3.34903 8.65097 1.2 6 1.2C3.34903 1.2 1.2 3.34903 1.2 6Z" fill="currentColor" />
|
|
265
276
|
<rect x="5.25" width="1.5" height="12" fill="#F0FDF6" />
|
|
@@ -267,7 +278,7 @@ const colorValue = computed(() => {
|
|
|
267
278
|
<rect x="10.773" y="9.71228" width="1.5" height="12" transform="rotate(135 10.773 9.71228)" fill="#F0FDF6" />
|
|
268
279
|
<rect x="2.28769" y="10.7729" width="1.5" height="12" transform="rotate(-135 2.28769 10.7729)" fill="#F0FDF6" />
|
|
269
280
|
<component
|
|
270
|
-
:is="
|
|
281
|
+
:is="isMotionActive ? Motion : 'path'"
|
|
271
282
|
as="path"
|
|
272
283
|
d="M3.5 6 L5.5 8 L8.5 4"
|
|
273
284
|
stroke="currentColor"
|
|
@@ -307,7 +318,7 @@ const colorValue = computed(() => {
|
|
|
307
318
|
<template v-if="name === 'arrow-down'">
|
|
308
319
|
<path d="M12 6C12 9.31371 9.31371 12 6 12C2.68629 12 0 9.31371 0 6C0 2.68629 2.68629 0 6 0C9.31371 0 12 2.68629 12 6ZM1.2 6C1.2 8.65097 3.34903 10.8 6 10.8C8.65097 10.8 10.8 8.65097 10.8 6C10.8 3.34903 8.65097 1.2 6 1.2C3.34903 1.2 1.2 3.34903 1.2 6Z" fill="#A3A3A3" />
|
|
309
320
|
<component
|
|
310
|
-
:is="
|
|
321
|
+
:is="isMotionActive ? Motion : 'path'"
|
|
311
322
|
as="path"
|
|
312
323
|
d="M6 4V8M6 8L7.75 6.53682M6 8L4.25 6.53682"
|
|
313
324
|
stroke="currentColor"
|
|
@@ -59,7 +59,6 @@ const value = ref('')
|
|
|
59
59
|
<template>
|
|
60
60
|
<TelaInput
|
|
61
61
|
v-model="value"
|
|
62
|
-
label="Username"
|
|
63
62
|
placeholder="Enter your username"
|
|
64
63
|
/>
|
|
65
64
|
</template>
|
|
@@ -70,7 +69,6 @@ const value = ref('')
|
|
|
70
69
|
```vue
|
|
71
70
|
<TelaInput
|
|
72
71
|
v-model="value"
|
|
73
|
-
label="Email"
|
|
74
72
|
placeholder="you@example.com"
|
|
75
73
|
show-clear-button
|
|
76
74
|
/>
|
|
@@ -92,7 +90,6 @@ const value = ref('')
|
|
|
92
90
|
```vue
|
|
93
91
|
<TelaInput
|
|
94
92
|
v-model="email"
|
|
95
|
-
label="Email"
|
|
96
93
|
placeholder="you@example.com"
|
|
97
94
|
error="Please enter a valid email address"
|
|
98
95
|
/>
|
|
@@ -102,10 +99,9 @@ const value = ref('')
|
|
|
102
99
|
|
|
103
100
|
```vue
|
|
104
101
|
<TelaInput
|
|
105
|
-
label="Disabled Input"
|
|
106
102
|
placeholder="Cannot edit"
|
|
107
|
-
disabled
|
|
108
103
|
model-value="Read only value"
|
|
104
|
+
disabled
|
|
109
105
|
/>
|
|
110
106
|
```
|
|
111
107
|
|
|
@@ -113,7 +109,6 @@ const value = ref('')
|
|
|
113
109
|
<TelaInput
|
|
114
110
|
v-model="message"
|
|
115
111
|
type="textarea"
|
|
116
|
-
label="Message"
|
|
117
112
|
placeholder="Enter your message..."
|
|
118
113
|
/>
|
|
119
114
|
```
|
|
@@ -123,7 +118,6 @@ const value = ref('')
|
|
|
123
118
|
```vue
|
|
124
119
|
<TelaInput
|
|
125
120
|
v-model="value"
|
|
126
|
-
label="Custom Input"
|
|
127
121
|
label-class="text-blue-600 font-bold"
|
|
128
122
|
input-class="border-blue-400"
|
|
129
123
|
/>
|
|
@@ -134,7 +128,6 @@ const value = ref('')
|
|
|
134
128
|
```vue
|
|
135
129
|
<TelaInput
|
|
136
130
|
v-model="bio"
|
|
137
|
-
label="Bio"
|
|
138
131
|
placeholder="Tell us about yourself"
|
|
139
132
|
:maxlength="100"
|
|
140
133
|
/>
|
|
@@ -150,10 +150,7 @@ defineExpose({
|
|
|
150
150
|
<label
|
|
151
151
|
v-if="label"
|
|
152
152
|
:for="id"
|
|
153
|
-
text
|
|
154
|
-
body-12-semibold
|
|
155
|
-
flex
|
|
156
|
-
align-center
|
|
153
|
+
body-12-semibold text-tertiary flex align-center
|
|
157
154
|
:class="[disabled && 'cursor-not-allowed', props.labelClass]"
|
|
158
155
|
>
|
|
159
156
|
<slot name="label-leading" />
|
|
@@ -39,7 +39,8 @@ One-time passcode input. Renders a row of single-character slots that share one
|
|
|
39
39
|
const code = ref('')
|
|
40
40
|
|
|
41
41
|
function onComplete(value: string) {
|
|
42
|
-
|
|
42
|
+
// fires once every slot is filled — verify the code here
|
|
43
|
+
console.log(value)
|
|
43
44
|
}
|
|
44
45
|
</script>
|
|
45
46
|
|
|
@@ -102,7 +102,9 @@ const isLoading = ref(true)
|
|
|
102
102
|
const data = ref(null)
|
|
103
103
|
|
|
104
104
|
onMounted(async () => {
|
|
105
|
-
|
|
105
|
+
// swap this for your own request
|
|
106
|
+
data.value = await new Promise(resolve =>
|
|
107
|
+
setTimeout(() => resolve({ title: 'Loaded', content: 'Content is ready.' }), 1200))
|
|
106
108
|
isLoading.value = false
|
|
107
109
|
})
|
|
108
110
|
</script>
|
package/nuxt.config.ts
CHANGED
|
@@ -99,8 +99,25 @@ export default defineNuxtConfig({
|
|
|
99
99
|
},
|
|
100
100
|
},
|
|
101
101
|
optimizeDeps: {
|
|
102
|
+
// Components here are pulled in by auto-imports from lazily-imported
|
|
103
|
+
// pages, so esbuild's dependency scanner never sees them from the app
|
|
104
|
+
// entry. Left undeclared, the first page that renders one of these
|
|
105
|
+
// components makes Vite discover the dep mid-session, re-optimize, and
|
|
106
|
+
// hard-reload the browser. Prebundling them up front keeps dev stable.
|
|
102
107
|
include: [
|
|
103
|
-
'
|
|
108
|
+
'@number-flow/vue',
|
|
109
|
+
'clsx',
|
|
110
|
+
'date-fns',
|
|
111
|
+
'radix-vue',
|
|
112
|
+
'reka-ui',
|
|
113
|
+
'shiki/core',
|
|
114
|
+
'shiki/engine/javascript',
|
|
115
|
+
'tailwind-merge',
|
|
116
|
+
'vue-i18n',
|
|
117
|
+
'vue-input-otp',
|
|
118
|
+
],
|
|
119
|
+
exclude: [
|
|
120
|
+
'shiki/langs',
|
|
104
121
|
],
|
|
105
122
|
},
|
|
106
123
|
},
|