@bagelink/vue 1.12.67 → 1.12.74
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/Dropdown.vue.d.ts.map +1 -1
- package/dist/components/FilterQuery.types.d.ts +19 -0
- package/dist/components/FilterQuery.types.d.ts.map +1 -0
- package/dist/components/FilterQuery.vue.d.ts.map +1 -1
- package/dist/components/analytics/PieChart.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/ArrayInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/CheckInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/CodeEditor/Index.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/ColorInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/DateInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/EmailInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/JSONInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/MarkdownEditor.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/NumberInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/OTP.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/PasswordInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RadioGroup.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RangeInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectBtn.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/SignaturePad.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/TableField.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/TelInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/TextInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/ToggleInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/Upload/UploadInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/bagelInputShell.d.ts +21 -0
- package/dist/components/form/inputs/bagelInputShell.d.ts.map +1 -0
- package/dist/components/form/inputs/index.d.ts.map +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/layout/AppSidebar.vue.d.ts.map +1 -1
- package/dist/dialog/Dialog.vue.d.ts.map +1 -1
- package/dist/dialog/useDialog.d.ts.map +1 -1
- package/dist/form-flow/FormFlow.vue.d.ts.map +1 -1
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/index.cjs +135 -135
- package/dist/index.mjs +14829 -14450
- package/dist/style.css +1 -1
- package/dist/types/BagelForm.d.ts.map +1 -1
- package/dist/utils/BagelFormUtils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/Dropdown.vue +2 -1
- package/src/components/FilterQuery.types.ts +21 -0
- package/src/components/FilterQuery.vue +112 -15
- package/src/components/form/inputs/ArrayInput.vue +10 -2
- package/src/components/form/inputs/CheckInput.vue +28 -9
- package/src/components/form/inputs/CodeEditor/Index.vue +15 -2
- package/src/components/form/inputs/ColorInput.vue +77 -9
- package/src/components/form/inputs/DateInput.vue +10 -3
- package/src/components/form/inputs/EmailInput.vue +90 -54
- package/src/components/form/inputs/JSONInput.vue +12 -4
- package/src/components/form/inputs/MarkdownEditor.vue +12 -4
- package/src/components/form/inputs/NumberInput.vue +154 -89
- package/src/components/form/inputs/OTP.vue +46 -7
- package/src/components/form/inputs/PasswordInput.vue +32 -21
- package/src/components/form/inputs/RadioGroup.vue +18 -7
- package/src/components/form/inputs/RangeInput.vue +23 -7
- package/src/components/form/inputs/RichText/index.vue +21 -12
- package/src/components/form/inputs/SelectBtn.vue +34 -6
- package/src/components/form/inputs/SelectInput.vue +19 -25
- package/src/components/form/inputs/SignaturePad.vue +39 -14
- package/src/components/form/inputs/TableField.vue +6 -2
- package/src/components/form/inputs/TelInput.vue +52 -4
- package/src/components/form/inputs/TextInput.vue +23 -31
- package/src/components/form/inputs/ToggleInput.vue +27 -4
- package/src/components/form/inputs/Upload/UploadInput.vue +47 -11
- package/src/components/form/inputs/Upload/upload.css +23 -0
- package/src/components/form/inputs/bagelInputShell.ts +43 -0
- package/src/components/form/inputs/index.ts +1 -0
- package/src/components/index.ts +1 -0
- package/src/dialog/Dialog.vue +12 -1
- package/src/dialog/useDialog.ts +2 -1
- package/src/form-flow/FormFlow.vue +3 -1
- package/src/i18n/locales/en.json +4 -1
- package/src/i18n/locales/es.json +4 -1
- package/src/i18n/locales/fr.json +4 -1
- package/src/i18n/locales/he.json +4 -1
- package/src/i18n/locales/it.json +4 -1
- package/src/i18n/locales/ru.json +4 -1
- package/src/styles/input-variants.css +12 -13
- package/src/styles/inputs.css +134 -15
- package/src/styles/text.css +534 -528
- package/src/types/BagelForm.ts +13 -1
- package/src/utils/BagelFormUtils.ts +1 -0
|
@@ -5,8 +5,10 @@ import { onClickOutside } from '@vueuse/core'
|
|
|
5
5
|
import { ref, computed, onMounted, watch } from 'vue'
|
|
6
6
|
import { WEEK_START_DAY } from '../../../utils/calendar/time'
|
|
7
7
|
import DatePicker from './DatePicker.vue'
|
|
8
|
+
import type { BagelInputShellProps } from './bagelInputShell'
|
|
9
|
+
import { useBagelInputShell } from './bagelInputShell'
|
|
8
10
|
|
|
9
|
-
export interface DateInputProps {
|
|
11
|
+
export interface DateInputProps extends BagelInputShellProps {
|
|
10
12
|
required?: boolean
|
|
11
13
|
label?: string
|
|
12
14
|
placeholder?: string
|
|
@@ -43,6 +45,8 @@ const props = withDefaults(
|
|
|
43
45
|
|
|
44
46
|
const { $t } = useI18n()
|
|
45
47
|
|
|
48
|
+
const { shellClass, shellStyle } = useBagelInputShell(props)
|
|
49
|
+
|
|
46
50
|
const selectedDate = defineModel<string | Date>()
|
|
47
51
|
const inputValue = ref('')
|
|
48
52
|
const isValid = ref(true)
|
|
@@ -193,7 +197,8 @@ onMounted(() => {
|
|
|
193
197
|
<template>
|
|
194
198
|
<div
|
|
195
199
|
class="bagel-input"
|
|
196
|
-
:class="{ small, 'has-error': !!error || !isValid, underlined, 'has-value': hasValue, 'open': isOpen }"
|
|
200
|
+
:class="[shellClass, { small, 'has-error': !!error || !isValid, underlined, 'has-value': hasValue, 'open': isOpen }]"
|
|
201
|
+
:style="shellStyle"
|
|
197
202
|
>
|
|
198
203
|
<label>
|
|
199
204
|
<span v-if="label || (underlined && placeholder)" class="label-text">{{ resolveI18n(label || placeholder)
|
|
@@ -206,7 +211,9 @@ onMounted(() => {
|
|
|
206
211
|
:placeholder="underlined ? ' ' : (resolveI18n(placeholder) || (enableTime ? 'DD.MM.YY HH:mm' : 'DD.MM.YY'))"
|
|
207
212
|
:required="underlined ? false : required" :disabled="!editMode"
|
|
208
213
|
:error="!isValid ? $t('date.invalidFormat') : error" :class="{ 'txt-center': center }"
|
|
209
|
-
:underlined="underlined"
|
|
214
|
+
:underlined="underlined" :frame="frame" :outline="outline" :min-width="minWidth"
|
|
215
|
+
:max-width="maxWidth" :label-color="labelColor" :label-active-color="labelActiveColor"
|
|
216
|
+
class="date-input m-0" @input="handleInput" @focus="handleFocus"
|
|
210
217
|
@blur="handleBlur" @click.stop @keydown="handleKeydown" @iconClick="handleIconClick"
|
|
211
218
|
/>
|
|
212
219
|
</div>
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { IconType, ValidateInputBaseT } from '@bagelink/vue'
|
|
3
3
|
import { Icon, useDebounceFn, useI18n, resolveI18n } from '@bagelink/vue'
|
|
4
|
-
import { computed, onMounted, ref, watch
|
|
4
|
+
import { computed, onMounted, ref, watch } from 'vue'
|
|
5
5
|
import { EMAIL_REGEX } from '../../../utils/constants'
|
|
6
|
+
import type { BagelInputShellProps } from './bagelInputShell'
|
|
7
|
+
import { useBagelInputShell } from './bagelInputShell'
|
|
6
8
|
|
|
7
9
|
const props = withDefaults(
|
|
8
10
|
defineProps<EmailInputProps>(),
|
|
@@ -11,15 +13,18 @@ const props = withDefaults(
|
|
|
11
13
|
autocorrect: true,
|
|
12
14
|
serverValidate: false,
|
|
13
15
|
preventFakeEmails: false,
|
|
16
|
+
formatValidation: false,
|
|
14
17
|
pattern: '[a-z0-9._%+\\-]+@[a-z0-9.\\-]+\\.[a-z]{2,}',
|
|
15
18
|
},
|
|
16
19
|
)
|
|
17
20
|
|
|
18
21
|
const emit = defineEmits(['update:modelValue', 'debounce'])
|
|
19
22
|
|
|
23
|
+
const { shellClass, shellStyle } = useBagelInputShell(props)
|
|
24
|
+
|
|
20
25
|
const { $t } = useI18n()
|
|
21
26
|
|
|
22
|
-
export interface EmailInputProps extends ValidateInputBaseT {
|
|
27
|
+
export interface EmailInputProps extends ValidateInputBaseT, BagelInputShellProps {
|
|
23
28
|
id?: string
|
|
24
29
|
title?: string
|
|
25
30
|
helptext?: string
|
|
@@ -37,7 +42,7 @@ export interface EmailInputProps extends ValidateInputBaseT {
|
|
|
37
42
|
nativeInputAttrs?: { [key: string]: any }
|
|
38
43
|
icon?: IconType
|
|
39
44
|
iconStart?: IconType
|
|
40
|
-
autocomplete?:
|
|
45
|
+
autocomplete?: string
|
|
41
46
|
autofocus?: boolean
|
|
42
47
|
error?: string
|
|
43
48
|
onFocusout?: (e: FocusEvent) => void
|
|
@@ -46,6 +51,7 @@ export interface EmailInputProps extends ValidateInputBaseT {
|
|
|
46
51
|
autocorrect?: boolean
|
|
47
52
|
serverValidate?: boolean
|
|
48
53
|
preventFakeEmails?: boolean
|
|
54
|
+
formatValidation?: boolean
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
// Common email providers for autocorrection
|
|
@@ -100,7 +106,6 @@ const inputVal = ref<string>('')
|
|
|
100
106
|
const suggestedCorrection = ref<string | null>(null)
|
|
101
107
|
const validationMessage = ref('')
|
|
102
108
|
const isValidating = ref(false)
|
|
103
|
-
const isValidEmail = ref(true)
|
|
104
109
|
const validatedEmails = new Map<string, boolean>()
|
|
105
110
|
|
|
106
111
|
const input = ref<HTMLInputElement>()
|
|
@@ -120,7 +125,7 @@ function validateEmail(value: string) {
|
|
|
120
125
|
if (domain) {
|
|
121
126
|
const domainLower = domain.toLowerCase()
|
|
122
127
|
if (FAKE_EMAIL_DOMAINS.includes(domainLower)) {
|
|
123
|
-
return '
|
|
128
|
+
return $t('email.disposableEmail')
|
|
124
129
|
}
|
|
125
130
|
}
|
|
126
131
|
}
|
|
@@ -151,9 +156,11 @@ function validateInput() {
|
|
|
151
156
|
async function validateEmailWithServer(email: string) {
|
|
152
157
|
if (!props.serverValidate || !email || !EMAIL_REGEX.test(email)) { return }
|
|
153
158
|
|
|
154
|
-
// If we've already validated this email, use cached result
|
|
155
159
|
if (validatedEmails.has(email)) {
|
|
156
|
-
|
|
160
|
+
if (!validatedEmails.get(email)) {
|
|
161
|
+
validationMessage.value = $t('email.invalidDomain')
|
|
162
|
+
input.value?.setCustomValidity(validationMessage.value)
|
|
163
|
+
}
|
|
157
164
|
return
|
|
158
165
|
}
|
|
159
166
|
|
|
@@ -172,7 +179,6 @@ async function validateEmailWithServer(email: string) {
|
|
|
172
179
|
const result = await response.json()
|
|
173
180
|
const isValid = result.status === 'valid' || result.has_mx === true
|
|
174
181
|
|
|
175
|
-
isValidEmail.value = isValid
|
|
176
182
|
validatedEmails.set(email, isValid)
|
|
177
183
|
|
|
178
184
|
if (!isValid) {
|
|
@@ -271,10 +277,6 @@ const debouncedServerValidate = useDebounceFn(() => validateEmailWithServer(inpu
|
|
|
271
277
|
function updateInputVal() {
|
|
272
278
|
if (props.disabled) { return }
|
|
273
279
|
|
|
274
|
-
// Remove typo checking while typing - only do this on focusout now
|
|
275
|
-
// checkForTypos(inputVal.value)
|
|
276
|
-
|
|
277
|
-
// Clear any previous suggestions
|
|
278
280
|
suggestedCorrection.value = null
|
|
279
281
|
|
|
280
282
|
validateInput()
|
|
@@ -289,7 +291,6 @@ function updateInputVal() {
|
|
|
289
291
|
}
|
|
290
292
|
|
|
291
293
|
function handleFocusout(e: FocusEvent) {
|
|
292
|
-
// Check for typos when the user leaves the field
|
|
293
294
|
checkForTypos(inputVal.value)
|
|
294
295
|
|
|
295
296
|
// Immediately validate on blur
|
|
@@ -305,25 +306,23 @@ watch(
|
|
|
305
306
|
(newVal) => {
|
|
306
307
|
if (newVal !== inputVal.value) {
|
|
307
308
|
inputVal.value = newVal || ''
|
|
308
|
-
nextTick(() => { validateInput() })
|
|
309
309
|
}
|
|
310
310
|
},
|
|
311
311
|
{ immediate: true },
|
|
312
312
|
)
|
|
313
313
|
|
|
314
|
-
watch(
|
|
315
|
-
() => inputVal.value,
|
|
316
|
-
() => { validateInput() },
|
|
317
|
-
{ immediate: true }
|
|
318
|
-
)
|
|
314
|
+
watch(() => inputVal.value, () => { validateInput() }, { immediate: true })
|
|
319
315
|
|
|
320
316
|
const hasFocus = () => document.activeElement === input.value
|
|
321
317
|
const focus = () => input.value?.focus()
|
|
322
318
|
defineExpose({ focus, hasFocus })
|
|
323
319
|
|
|
324
|
-
const hasValue = computed(() =>
|
|
325
|
-
|
|
326
|
-
|
|
320
|
+
const hasValue = computed(() => inputVal.value.length > 0)
|
|
321
|
+
|
|
322
|
+
const formatValidationClass = computed(() => {
|
|
323
|
+
if (!props.formatValidation) return null
|
|
324
|
+
if (!hasValue.value) return 'format-empty'
|
|
325
|
+
return EMAIL_REGEX.test(inputVal.value) ? 'format-valid' : 'format-invalid'
|
|
327
326
|
})
|
|
328
327
|
|
|
329
328
|
onMounted(() => {
|
|
@@ -334,16 +333,20 @@ onMounted(() => {
|
|
|
334
333
|
|
|
335
334
|
<template>
|
|
336
335
|
<div
|
|
337
|
-
class="bagel-input text-input" :class="
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
336
|
+
class="bagel-input text-input" :class="[
|
|
337
|
+
shellClass,
|
|
338
|
+
formatValidationClass,
|
|
339
|
+
{
|
|
340
|
+
small,
|
|
341
|
+
shrink,
|
|
342
|
+
underlined,
|
|
343
|
+
'textInputIconWrap': icon,
|
|
344
|
+
'txtInputIconStart': iconStart,
|
|
345
|
+
'is-validating': isValidating,
|
|
346
|
+
'has-error': !!error,
|
|
347
|
+
'has-value': hasValue,
|
|
348
|
+
},
|
|
349
|
+
]" :style="shellStyle" :title="title"
|
|
347
350
|
>
|
|
348
351
|
<label :for="id">
|
|
349
352
|
<span v-if="label || (underlined && placeholder)" class="label-text">{{ resolveI18n(label) || resolveI18n(placeholder) }}<span v-if="required"> *</span></span>
|
|
@@ -353,9 +356,9 @@ onMounted(() => {
|
|
|
353
356
|
v-if="suggestedCorrection" class="pointer nowrap inline-block ms-auto color-red txt-10px p-0"
|
|
354
357
|
@click.prevent="applyCorrection"
|
|
355
358
|
>
|
|
356
|
-
|
|
359
|
+
{{ $t('email.didYouMean', { suggestion: suggestedCorrection }) }}
|
|
357
360
|
</span>
|
|
358
|
-
<span v-if="isValidating" class="validating">
|
|
361
|
+
<span v-if="isValidating" class="validating">{{ $t('email.validating') }}</span>
|
|
359
362
|
</div>
|
|
360
363
|
<input
|
|
361
364
|
:id ref="input" v-model="inputVal" v-pattern:lower class="ltr" :name :title autocomplete="email"
|
|
@@ -381,29 +384,61 @@ onMounted(() => {
|
|
|
381
384
|
.bagel-input label {
|
|
382
385
|
font-size: var(--label-font-size);
|
|
383
386
|
}
|
|
384
|
-
</style>
|
|
385
387
|
|
|
386
|
-
|
|
387
|
-
.bagel-input
|
|
388
|
-
|
|
389
|
-
|
|
388
|
+
.bagel-input.format-invalid,
|
|
389
|
+
.bagel-input.format-valid,
|
|
390
|
+
.bagel-input.format-empty {
|
|
391
|
+
position: relative;
|
|
390
392
|
}
|
|
391
393
|
|
|
392
|
-
.bagel-input.
|
|
393
|
-
|
|
394
|
+
.bagel-input.format-invalid::after {
|
|
395
|
+
content: '';
|
|
396
|
+
position: absolute;
|
|
397
|
+
width: 7px;
|
|
398
|
+
height: 7px;
|
|
399
|
+
border-radius: 50%;
|
|
400
|
+
background: var(--bgl-orange);
|
|
401
|
+
right: 0.6rem;
|
|
402
|
+
bottom: calc(var(--input-height) / 2 - 3.5px);
|
|
403
|
+
pointer-events: none;
|
|
394
404
|
}
|
|
395
405
|
|
|
396
|
-
.
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
406
|
+
.bagel-input.format-invalid.textInputIconWrap::after,
|
|
407
|
+
.bagel-input.format-valid.textInputIconWrap::after,
|
|
408
|
+
.bagel-input.format-empty.textInputIconWrap::after {
|
|
409
|
+
right: calc(var(--input-height) / 3 + 1.8rem);
|
|
400
410
|
}
|
|
401
411
|
|
|
402
|
-
.
|
|
403
|
-
|
|
404
|
-
|
|
412
|
+
.bagel-input.format-empty::after {
|
|
413
|
+
content: '';
|
|
414
|
+
position: absolute;
|
|
415
|
+
width: 7px;
|
|
416
|
+
height: 7px;
|
|
417
|
+
border-radius: 50%;
|
|
418
|
+
background: var(--bgl-gray, #aaa);
|
|
419
|
+
right: 0.6rem;
|
|
420
|
+
bottom: calc(var(--input-height) / 2 - 3.5px);
|
|
421
|
+
pointer-events: none;
|
|
405
422
|
}
|
|
406
423
|
|
|
424
|
+
.bagel-input.format-valid {
|
|
425
|
+
position: relative;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.bagel-input.format-valid::after {
|
|
429
|
+
content: '';
|
|
430
|
+
position: absolute;
|
|
431
|
+
width: 7px;
|
|
432
|
+
height: 7px;
|
|
433
|
+
border-radius: 50%;
|
|
434
|
+
background: var(--bgl-green);
|
|
435
|
+
right: 0.6rem;
|
|
436
|
+
bottom: calc(var(--input-height) / 2 - 3.5px);
|
|
437
|
+
pointer-events: none;
|
|
438
|
+
}
|
|
439
|
+
</style>
|
|
440
|
+
|
|
441
|
+
<style scoped>
|
|
407
442
|
.bagel-input.small {
|
|
408
443
|
margin-bottom: 0;
|
|
409
444
|
height: 30px;
|
|
@@ -423,29 +458,30 @@ onMounted(() => {
|
|
|
423
458
|
font-size: var(--label-font-size);
|
|
424
459
|
}
|
|
425
460
|
|
|
461
|
+
/* email input is always LTR — use physical properties so icons stay in the correct
|
|
462
|
+
visual position regardless of the document's text direction */
|
|
426
463
|
.textInputIconWrap .bgl_icon-font {
|
|
427
464
|
color: var(--input-color);
|
|
428
465
|
position: absolute;
|
|
429
|
-
|
|
466
|
+
right: calc(var(--input-height) / 3 - 0.25rem);
|
|
430
467
|
margin-top: calc(var(--input-height) / 2 + 0.1rem);
|
|
431
468
|
line-height: 0;
|
|
432
469
|
}
|
|
433
470
|
|
|
434
471
|
.textInputIconWrap input {
|
|
435
|
-
padding-
|
|
472
|
+
padding-right: calc(var(--input-height) / 3 + 1.5rem);
|
|
436
473
|
}
|
|
437
474
|
|
|
438
475
|
.txtInputIconStart .iconStart {
|
|
439
476
|
color: var(--input-color);
|
|
440
477
|
position: absolute;
|
|
441
|
-
|
|
478
|
+
left: calc(var(--input-height) / 3 - 0.25rem);
|
|
442
479
|
margin-top: calc(var(--input-height) / 2);
|
|
443
480
|
line-height: 0;
|
|
444
481
|
}
|
|
445
482
|
|
|
446
|
-
.txtInputIconStart input
|
|
447
|
-
|
|
448
|
-
padding-inline-start: calc(var(--input-height) / 3 + 1.5rem);
|
|
483
|
+
.txtInputIconStart input {
|
|
484
|
+
padding-left: calc(var(--input-height) / 3 + 1.5rem);
|
|
449
485
|
}
|
|
450
486
|
|
|
451
487
|
.bagel-input.small textarea {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
// const props =
|
|
3
|
+
import { computed } from 'vue'
|
|
3
4
|
import { resolveI18n } from '@bagelink/vue'
|
|
5
|
+
import type { BagelInputShellProps } from './bagelInputShell'
|
|
6
|
+
import { useBagelInputShell } from './bagelInputShell'
|
|
4
7
|
|
|
5
|
-
withDefaults(
|
|
8
|
+
const props = withDefaults(
|
|
6
9
|
defineProps<{
|
|
7
10
|
description?: string
|
|
8
11
|
label?: string
|
|
@@ -10,7 +13,7 @@ withDefaults(
|
|
|
10
13
|
placeholder?: string
|
|
11
14
|
editMode?: boolean
|
|
12
15
|
small?: boolean
|
|
13
|
-
}>(),
|
|
16
|
+
} & BagelInputShellProps>(),
|
|
14
17
|
{
|
|
15
18
|
description: '',
|
|
16
19
|
editMode: true,
|
|
@@ -18,7 +21,9 @@ withDefaults(
|
|
|
18
21
|
label: '',
|
|
19
22
|
},
|
|
20
23
|
)
|
|
21
|
-
|
|
24
|
+
|
|
25
|
+
const { shellClass, shellStyle } = useBagelInputShell(props)
|
|
26
|
+
const hasValue = computed(() => props.modelValue != null && String(props.modelValue).length > 0)
|
|
22
27
|
|
|
23
28
|
const emits = defineEmits(['update:modelValue'])
|
|
24
29
|
function handleInput(e: Event) {
|
|
@@ -28,7 +33,10 @@ function handleInput(e: Event) {
|
|
|
28
33
|
</script>
|
|
29
34
|
|
|
30
35
|
<template>
|
|
31
|
-
<div
|
|
36
|
+
<div
|
|
37
|
+
class="bagel-input" :title="description"
|
|
38
|
+
:class="[shellClass, { small, 'has-value': hasValue }]" :style="shellStyle"
|
|
39
|
+
>
|
|
32
40
|
<label v-if="label">
|
|
33
41
|
<LangText :input="label" />
|
|
34
42
|
</label>
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import { Btn, TextInput } from '@bagelink/vue'
|
|
3
3
|
import { computed, nextTick, ref } from 'vue'
|
|
4
|
+
import type { BagelInputShellProps } from './bagelInputShell'
|
|
5
|
+
import { useBagelInputShell } from './bagelInputShell'
|
|
4
6
|
|
|
5
|
-
interface Props {
|
|
7
|
+
interface Props extends BagelInputShellProps {
|
|
6
8
|
maxLength?: number
|
|
7
9
|
placeholder?: string
|
|
8
10
|
label?: string
|
|
@@ -10,7 +12,13 @@ interface Props {
|
|
|
10
12
|
showFormatting?: boolean
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
const
|
|
15
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
16
|
+
placeholder: 'Enter Text',
|
|
17
|
+
label: 'Body',
|
|
18
|
+
showFormatting: true,
|
|
19
|
+
})
|
|
20
|
+
const { maxLength, placeholder, label, showFormatting, rtl } = props
|
|
21
|
+
const { shellClass, shellStyle } = useBagelInputShell(props)
|
|
14
22
|
|
|
15
23
|
const text = defineModel<string>('modelValue', { default: '' })
|
|
16
24
|
|
|
@@ -85,7 +93,7 @@ defineExpose({ html })
|
|
|
85
93
|
|
|
86
94
|
<template>
|
|
87
95
|
<div class="markdown-editor">
|
|
88
|
-
<div class="bagel-input mb-0">
|
|
96
|
+
<div class="bagel-input mb-0" :class="[shellClass, { 'has-value': charCount > 0 }]" :style="shellStyle">
|
|
89
97
|
<div v-if="maxLength" class="txt10 opacity-6 -mb-1 w100p txt-end">
|
|
90
98
|
{{ charCount }} / {{ maxLength }}
|
|
91
99
|
</div>
|
|
@@ -102,7 +110,7 @@ defineExpose({ html })
|
|
|
102
110
|
/>
|
|
103
111
|
</div>
|
|
104
112
|
|
|
105
|
-
<div v-if="showFormatting" class="flex justify-content-end -mt-025 -mb-05">
|
|
113
|
+
<div v-if="showFormatting" class="flex justify-content-end -mt-025 -mb-05 ltr">
|
|
106
114
|
<Btn thin icon-size="0.9" flat icon="format_bold" @click="insertToBody('bold')" />
|
|
107
115
|
<Btn thin icon-size="0.9" flat icon="format_italic" @click="insertToBody('italic')" />
|
|
108
116
|
<Btn thin icon-size="0.9" flat icon="format_underlined" @click="insertToBody('underline')" />
|