@bagelink/vue 1.12.71 → 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/i18n/index.d.ts.map +1 -1
- package/dist/index.cjs +135 -135
- package/dist/index.mjs +16026 -15661
- 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 +44 -9
- package/src/components/form/inputs/Upload/upload.css +15 -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/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 +10 -10
- package/src/types/BagelForm.ts +11 -1
- package/src/utils/BagelFormUtils.ts +1 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { resolveI18n } from '@bagelink/vue'
|
|
3
3
|
import { computed, ref, watch } from 'vue'
|
|
4
|
+
import type { BagelInputShellProps } from './bagelInputShell'
|
|
4
5
|
|
|
5
|
-
export interface RangeInputProps {
|
|
6
|
+
export interface RangeInputProps extends BagelInputShellProps {
|
|
6
7
|
modelValue: number | [number, number]
|
|
7
8
|
min?: number
|
|
8
9
|
max?: number
|
|
@@ -14,6 +15,10 @@ export interface RangeInputProps {
|
|
|
14
15
|
rtl?: boolean
|
|
15
16
|
multiRange?: boolean
|
|
16
17
|
formatValue?: (value: number) => string
|
|
18
|
+
/** צבע הרקע של הפס (track) */
|
|
19
|
+
trackColor?: string
|
|
20
|
+
/** צבע הפס הפעיל והעיגול — ברירת מחדל: labelActiveColor או primary */
|
|
21
|
+
activeColor?: string
|
|
17
22
|
}
|
|
18
23
|
|
|
19
24
|
const props = defineProps<RangeInputProps>()
|
|
@@ -72,7 +77,15 @@ const displayTo = computed(() => formatValue(validTo.value))
|
|
|
72
77
|
</script>
|
|
73
78
|
|
|
74
79
|
<template>
|
|
75
|
-
<div
|
|
80
|
+
<div
|
|
81
|
+
:dir="rtl ? 'rtl' : 'ltr'"
|
|
82
|
+
:style="[
|
|
83
|
+
minWidth ? { minWidth } : {},
|
|
84
|
+
maxWidth ? { maxWidth } : {},
|
|
85
|
+
activeColor ? { '--bgl-range-thumb-color': activeColor } : {},
|
|
86
|
+
labelActiveColor ? { '--bgl-input-label-active-color': labelActiveColor } : {},
|
|
87
|
+
]"
|
|
88
|
+
>
|
|
76
89
|
<label v-if="props.label" class="label">{{ resolveI18n(props.label) }}</label>
|
|
77
90
|
<div class="range-slider relative w-100">
|
|
78
91
|
<input
|
|
@@ -101,10 +114,13 @@ const displayTo = computed(() => formatValue(validTo.value))
|
|
|
101
114
|
aria-label="Maximum value"
|
|
102
115
|
@input="(e) => handleInput(+(e.target as HTMLInputElement).value, false)"
|
|
103
116
|
>
|
|
104
|
-
<div
|
|
117
|
+
<div
|
|
118
|
+
class="track absolute pointer-events-none overflow-hidden round"
|
|
119
|
+
:style="trackColor ? { background: trackColor } : {}"
|
|
120
|
+
>
|
|
105
121
|
<div
|
|
106
|
-
class="active-range absolute h-100 pointer-events-none
|
|
107
|
-
:style="rangeStyle"
|
|
122
|
+
class="active-range absolute h-100 pointer-events-none"
|
|
123
|
+
:style="{ ...rangeStyle, background: activeColor || 'var(--bgl-input-label-active-color, var(--bgl-primary))' }"
|
|
108
124
|
/>
|
|
109
125
|
</div>
|
|
110
126
|
<p
|
|
@@ -190,13 +206,13 @@ input[type="range"]::-webkit-slider-thumb {
|
|
|
190
206
|
}
|
|
191
207
|
|
|
192
208
|
input[type="range"]::-webkit-slider-thumb:hover {
|
|
193
|
-
box-shadow: 0 0 0 calc(var(--bgl-range-thumb-size) / 2) var(--bgl-primary
|
|
209
|
+
box-shadow: 0 0 0 calc(var(--bgl-range-thumb-size) / 2) color-mix(in srgb, var(--bgl-input-label-active-color, var(--bgl-primary)) 18%, transparent);
|
|
194
210
|
filter: brightness(90%);
|
|
195
211
|
}
|
|
196
212
|
|
|
197
213
|
input[type="range"]:focus::-webkit-slider-thumb {
|
|
198
214
|
outline: none;
|
|
199
|
-
box-shadow: 0 0 0 calc(var(--bgl-range-thumb-size) / 2.2) var(--bgl-primary
|
|
215
|
+
box-shadow: 0 0 0 calc(var(--bgl-range-thumb-size) / 2.2) color-mix(in srgb, var(--bgl-input-label-active-color, var(--bgl-primary)) 18%, transparent);
|
|
200
216
|
}
|
|
201
217
|
|
|
202
218
|
input[type="range"]:active::-webkit-slider-thumb {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<!-- eslint-disable vue/multi-word-component-names -->
|
|
1
2
|
<script setup lang="ts">
|
|
2
3
|
import type { ToolbarConfig } from './richTextTypes'
|
|
3
4
|
import { CodeEditor, copyText, Btn, Modal, BglVideo, Icon, Card, ColorInput, pathKeyToURL } from '@bagelink/vue'
|
|
@@ -11,6 +12,8 @@ import EditorToolbar from './components/EditorToolbar.vue'
|
|
|
11
12
|
import { useCommands } from './composables/useCommands'
|
|
12
13
|
import { useEditor } from './composables/useEditor'
|
|
13
14
|
import { useEditorKeyboard } from './composables/useEditorKeyboard'
|
|
15
|
+
import type { BagelInputShellProps } from '../bagelInputShell'
|
|
16
|
+
import { useBagelInputShell } from '../bagelInputShell'
|
|
14
17
|
|
|
15
18
|
// Disable automatic inheritance of non-prop attributes
|
|
16
19
|
defineOptions({
|
|
@@ -44,10 +47,13 @@ const props = defineProps<{
|
|
|
44
47
|
textColor?: string
|
|
45
48
|
// Font size
|
|
46
49
|
fontSize?: number | string
|
|
47
|
-
}>()
|
|
50
|
+
} & BagelInputShellProps>()
|
|
48
51
|
|
|
49
52
|
const emit = defineEmits(['update:modelValue'])
|
|
50
53
|
|
|
54
|
+
const { shellClass, shellStyle } = useBagelInputShell(props)
|
|
55
|
+
const hasEditorValue = computed(() => Boolean(props.modelValue?.trim()))
|
|
56
|
+
|
|
51
57
|
const attrs = useAttrs()
|
|
52
58
|
|
|
53
59
|
const iframe = ref<HTMLIFrameElement>()
|
|
@@ -415,20 +421,20 @@ function showInlineToolbarForSelection() {
|
|
|
415
421
|
|
|
416
422
|
const selection = doc.getSelection()
|
|
417
423
|
if (!selection || selection.rangeCount === 0) {
|
|
418
|
-
|
|
424
|
+
closeInlineToolbar()
|
|
419
425
|
return
|
|
420
426
|
}
|
|
421
427
|
|
|
422
428
|
const range = selection.getRangeAt(0)
|
|
423
429
|
if (range.collapsed) {
|
|
424
|
-
|
|
430
|
+
closeInlineToolbar()
|
|
425
431
|
return
|
|
426
432
|
}
|
|
427
433
|
|
|
428
434
|
// Get the selected text
|
|
429
435
|
const selectedText = selection.toString().trim()
|
|
430
436
|
if (!selectedText) {
|
|
431
|
-
|
|
437
|
+
closeInlineToolbar()
|
|
432
438
|
return
|
|
433
439
|
}
|
|
434
440
|
|
|
@@ -461,7 +467,7 @@ function showInlineToolbarForSelection() {
|
|
|
461
467
|
}
|
|
462
468
|
|
|
463
469
|
// Function to hide inline toolbar
|
|
464
|
-
function
|
|
470
|
+
function closeInlineToolbar() {
|
|
465
471
|
showInlineToolbar.value = false
|
|
466
472
|
inlineToolbarSelection.value = null
|
|
467
473
|
}
|
|
@@ -495,7 +501,7 @@ function runInlineAction(actionName: string) {
|
|
|
495
501
|
if (!newRange.collapsed) {
|
|
496
502
|
; (inlineToolbarSelection.value as any)._storedRange = newRange.cloneRange()
|
|
497
503
|
} else {
|
|
498
|
-
|
|
504
|
+
closeInlineToolbar()
|
|
499
505
|
}
|
|
500
506
|
}
|
|
501
507
|
}, 50)
|
|
@@ -2103,7 +2109,7 @@ onUnmounted(() => {
|
|
|
2103
2109
|
function setupTableEditButtons(doc: Document) {
|
|
2104
2110
|
// Simple function to add edit buttons to all tables
|
|
2105
2111
|
function addEditButtonsToTables() {
|
|
2106
|
-
const tables = doc.querySelectorAll('table:not([data-edit-button-added])')
|
|
2112
|
+
const tables = doc.querySelectorAll('table:not([data-edit-button-added])')
|
|
2107
2113
|
|
|
2108
2114
|
tables.forEach((table, index) => {
|
|
2109
2115
|
// Create edit button as a span element instead of button
|
|
@@ -2418,8 +2424,8 @@ function setupAutoWrapping(doc: Document) {
|
|
|
2418
2424
|
const textAfterCursor = range.startContainer.textContent?.substring(range.startOffset) || ''
|
|
2419
2425
|
|
|
2420
2426
|
// Debug logging to understand the issue
|
|
2421
|
-
|
|
2422
|
-
}
|
|
2427
|
+
|
|
2428
|
+
if (props.debug) { /* reserved for future debug output */ }
|
|
2423
2429
|
|
|
2424
2430
|
// Create new paragraph with proper direction
|
|
2425
2431
|
const newParagraph = doc.createElement('p')
|
|
@@ -2937,7 +2943,7 @@ async function initEditor() {
|
|
|
2937
2943
|
setTimeout(() => {
|
|
2938
2944
|
const selection = doc.getSelection()
|
|
2939
2945
|
if (!selection || selection.rangeCount === 0 || selection.getRangeAt(0).collapsed) {
|
|
2940
|
-
|
|
2946
|
+
closeInlineToolbar()
|
|
2941
2947
|
}
|
|
2942
2948
|
}, 10)
|
|
2943
2949
|
})
|
|
@@ -2948,7 +2954,7 @@ async function initEditor() {
|
|
|
2948
2954
|
setTimeout(() => {
|
|
2949
2955
|
const selection = doc.getSelection()
|
|
2950
2956
|
if (!selection || selection.rangeCount === 0 || selection.getRangeAt(0).collapsed) {
|
|
2951
|
-
|
|
2957
|
+
closeInlineToolbar()
|
|
2952
2958
|
}
|
|
2953
2959
|
}, 10)
|
|
2954
2960
|
}
|
|
@@ -3190,7 +3196,10 @@ const imgTransform = computed({
|
|
|
3190
3196
|
</script>
|
|
3191
3197
|
|
|
3192
3198
|
<template>
|
|
3193
|
-
<div
|
|
3199
|
+
<div
|
|
3200
|
+
class="bagel-input" :class="[shellClass, { 'has-value': hasEditorValue }]" :style="shellStyle"
|
|
3201
|
+
v-bind="attrs"
|
|
3202
|
+
>
|
|
3194
3203
|
<label v-if="label">{{ label }}</label>
|
|
3195
3204
|
|
|
3196
3205
|
<div
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { Option } from '@bagelink/vue'
|
|
3
3
|
import { Btn, Icon, resolveI18n } from '@bagelink/vue'
|
|
4
|
+
import { computed } from 'vue'
|
|
4
5
|
import { getOptionIcon, getOptionLabel, getOptionValue } from '../../../utils/options'
|
|
6
|
+
import type { BagelInputShellProps } from './bagelInputShell'
|
|
7
|
+
import { useBagelInputShell } from './bagelInputShell'
|
|
5
8
|
|
|
6
9
|
const props = withDefaults(
|
|
7
10
|
defineProps<{
|
|
@@ -10,12 +13,24 @@ const props = withDefaults(
|
|
|
10
13
|
required?: boolean
|
|
11
14
|
error?: string
|
|
12
15
|
thin?: boolean
|
|
13
|
-
outline?: boolean
|
|
14
16
|
multiselect?: boolean
|
|
15
|
-
}>(),
|
|
17
|
+
} & BagelInputShellProps>(),
|
|
16
18
|
{ multiselect: false },
|
|
17
19
|
)
|
|
18
20
|
|
|
21
|
+
const { shellClass, shellStyle } = useBagelInputShell(() => ({
|
|
22
|
+
frame: props.frame,
|
|
23
|
+
outline: props.outline,
|
|
24
|
+
minWidth: props.minWidth,
|
|
25
|
+
maxWidth: props.maxWidth,
|
|
26
|
+
labelColor: props.labelColor,
|
|
27
|
+
labelActiveColor: props.labelActiveColor,
|
|
28
|
+
}))
|
|
29
|
+
const hasValue = computed(() => {
|
|
30
|
+
const v = selected.value
|
|
31
|
+
return Array.isArray(v) ? v.length > 0 : v != null && v !== ''
|
|
32
|
+
})
|
|
33
|
+
|
|
19
34
|
const selected = defineModel<string | number | (string | number)[] | null>('modelValue', { default: null })
|
|
20
35
|
|
|
21
36
|
function toggleOption(val: string | number) {
|
|
@@ -34,15 +49,28 @@ function isSelected(val: string | number) {
|
|
|
34
49
|
</script>
|
|
35
50
|
|
|
36
51
|
<template>
|
|
37
|
-
<div
|
|
52
|
+
<div
|
|
53
|
+
class="bagel-input SelectBtn" :class="[shellClass, { 'has-value': hasValue }]" :style="shellStyle"
|
|
54
|
+
>
|
|
38
55
|
<label v-if="label || required" class="pb-025">
|
|
39
56
|
{{ resolveI18n(label) }}<span v-if="required"> *</span>
|
|
40
57
|
</label>
|
|
41
58
|
<div class="flex flex-wrap gap-05">
|
|
42
59
|
<Btn
|
|
43
|
-
v-for="option in options" :key="String(getOptionValue(option))" :thin="thin"
|
|
44
|
-
type="button"
|
|
45
|
-
:
|
|
60
|
+
v-for="option in options" :key="String(getOptionValue(option))" :thin="thin"
|
|
61
|
+
type="button"
|
|
62
|
+
:class="isSelected(getOptionValue(option)!) ? 'color-white' : 'bg-transparent'"
|
|
63
|
+
:style="isSelected(getOptionValue(option)!)
|
|
64
|
+
? {
|
|
65
|
+
backgroundColor: 'var(--bgl-input-label-active-color, var(--bgl-primary))',
|
|
66
|
+
borderColor: 'var(--bgl-input-label-active-color, var(--bgl-primary))',
|
|
67
|
+
color: 'white',
|
|
68
|
+
}
|
|
69
|
+
: {
|
|
70
|
+
color: 'var(--bgl-input-label-active-color, var(--bgl-border-color))',
|
|
71
|
+
borderColor: 'var(--bgl-input-label-active-color, var(--bgl-border-color))',
|
|
72
|
+
}"
|
|
73
|
+
class="border px-075 radius-2"
|
|
46
74
|
@click="toggleOption(getOptionValue(option)!)"
|
|
47
75
|
>
|
|
48
76
|
<Icon v-if="getOptionIcon(option)" :icon="getOptionIcon(option)!" weight="300" />
|
|
@@ -5,6 +5,8 @@ import { Btn, Card, Skeleton, Dropdown, Icon, TextInput, useSearch, useI18n, res
|
|
|
5
5
|
import { computed, onMounted, ref, watch } from 'vue'
|
|
6
6
|
import { getOptionIcon, getOptionLabel, getOptionValue } from '../../../utils/options'
|
|
7
7
|
import 'floating-vue/style.css'
|
|
8
|
+
import type { BagelInputShellProps } from './bagelInputShell'
|
|
9
|
+
import { useBagelInputShell } from './bagelInputShell'
|
|
8
10
|
|
|
9
11
|
const props = withDefaults(defineProps<PropTypes>(), {
|
|
10
12
|
placement: 'bottom-start',
|
|
@@ -14,12 +16,14 @@ const emit = defineEmits(['update:modelValue'])
|
|
|
14
16
|
|
|
15
17
|
const { $t } = useI18n()
|
|
16
18
|
|
|
19
|
+
const { shellClass, shellStyle } = useBagelInputShell(props)
|
|
20
|
+
|
|
17
21
|
type OptionsSource = Option[] | ((query: string) => Promise<Option[]>)
|
|
18
22
|
const isAsyncSource = (src: OptionsSource): src is (q: string) => Promise<Option[]> => typeof src === 'function'
|
|
19
23
|
|
|
20
24
|
type Primitive = string | number | boolean
|
|
21
25
|
|
|
22
|
-
interface PropTypes {
|
|
26
|
+
interface PropTypes extends BagelInputShellProps {
|
|
23
27
|
options: OptionsSource
|
|
24
28
|
placeholder?: string
|
|
25
29
|
disabled?: boolean
|
|
@@ -39,7 +43,6 @@ interface PropTypes {
|
|
|
39
43
|
error?: string
|
|
40
44
|
underlined?: boolean
|
|
41
45
|
size?: 'xs' | 's' | 'm' | 'l' | 'xl'
|
|
42
|
-
outline?: boolean
|
|
43
46
|
border?: boolean
|
|
44
47
|
thin?: boolean
|
|
45
48
|
round?: boolean
|
|
@@ -50,10 +53,9 @@ const triggerBtn = ref<HTMLButtonElement | undefined>()
|
|
|
50
53
|
|
|
51
54
|
const selectedItems = ref<Option[]>([])
|
|
52
55
|
|
|
53
|
-
const getLabel = (option: Option) => getOptionLabel(option)
|
|
54
56
|
const getValue = (option?: Option): Primitive | undefined => getOptionValue(option) as Primitive | undefined
|
|
55
57
|
|
|
56
|
-
const selectedItemCount = computed(() => selectedItems.value.length
|
|
58
|
+
const selectedItemCount = computed(() => selectedItems.value.length)
|
|
57
59
|
const searchTerm = ref<string>('')
|
|
58
60
|
|
|
59
61
|
const dropdown = ref<InstanceType<typeof Dropdown> | undefined>()
|
|
@@ -77,11 +79,11 @@ const selectedLabel = computed((): string => {
|
|
|
77
79
|
if (selectedItemCount.value > 4) {
|
|
78
80
|
const str = selectedItems.value
|
|
79
81
|
.slice(0, 4)
|
|
80
|
-
.map(item =>
|
|
82
|
+
.map(item => getOptionLabel(item))
|
|
81
83
|
.join(', ')
|
|
82
84
|
return `${str}... +${selectedItemCount.value - 4}`
|
|
83
85
|
}
|
|
84
|
-
return selectedItems.value.map(item =>
|
|
86
|
+
return selectedItems.value.map(item => getOptionLabel(item)).join(', ')
|
|
85
87
|
})
|
|
86
88
|
|
|
87
89
|
const searchPlaceholder = computed(() => props.searchPlaceholder ?? selectedLabel.value ?? $t('select.search'))
|
|
@@ -172,7 +174,6 @@ function emitUpdate() {
|
|
|
172
174
|
if (props.multiselect) {
|
|
173
175
|
emit('update:modelValue', selectedItems.value.map(getValue).filter(v => v != null))
|
|
174
176
|
} else {
|
|
175
|
-
// selectedItems.value.splice(1, selectedItemCount.value - 1);
|
|
176
177
|
const [item] = selectedItems.value
|
|
177
178
|
emit('update:modelValue', getValue(item))
|
|
178
179
|
}
|
|
@@ -230,9 +231,6 @@ watch(
|
|
|
230
231
|
if (exists === undefined) { selectedItems.value.splice(i, 1) }
|
|
231
232
|
else { selectedItems.value.splice(i, 1, exists) }
|
|
232
233
|
})
|
|
233
|
-
// const original = JSON.stringify(props.options.map(getValue));
|
|
234
|
-
// const newSelection = JSON.stringify(selectedItems.value.map(getValue));
|
|
235
|
-
// if (original !== newSelection) emitUpdate();
|
|
236
234
|
},
|
|
237
235
|
{ deep: true, immediate: true },
|
|
238
236
|
)
|
|
@@ -277,7 +275,8 @@ onMounted(() => {
|
|
|
277
275
|
<template>
|
|
278
276
|
<Dropdown
|
|
279
277
|
ref="dropdown" v-model:shown="open" :placement="placement" class="bagel-input selectinput"
|
|
280
|
-
:class="{ 'has-error': !!error, underlined, open, 'has-value': selectedItemCount > 0 }"
|
|
278
|
+
:class="[shellClass, { 'has-error': !!error, underlined, open, 'has-value': selectedItemCount > 0 }]"
|
|
279
|
+
:style="shellStyle" no-auto-focus
|
|
281
280
|
@click.stop
|
|
282
281
|
>
|
|
283
282
|
<template #trigger>
|
|
@@ -296,7 +295,7 @@ onMounted(() => {
|
|
|
296
295
|
@keydown.down.prevent="navigate('down')" @keydown.up.prevent="navigate('up')"
|
|
297
296
|
>
|
|
298
297
|
<Icon v-if="icon" :icon="icon" />
|
|
299
|
-
<p v-if="!hideLabel">
|
|
298
|
+
<p v-if="!hideLabel" :class="{ 'me-auto ms-05': icon }">
|
|
300
299
|
{{ selectedItemCount > 0 ? selectedLabel : (underlined ? '' : (resolveI18n(placeholder)
|
|
301
300
|
|| 'Select...')) }}
|
|
302
301
|
</p>
|
|
@@ -339,9 +338,9 @@ onMounted(() => {
|
|
|
339
338
|
</template>
|
|
340
339
|
<div class="flex gap-05">
|
|
341
340
|
<Icon v-if="getOptionIcon(option)" :icon="getOptionIcon(option)!" :size="1" />
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
341
|
+
<span class="block">
|
|
342
|
+
{{ getOptionLabel(option) }}
|
|
343
|
+
</span>
|
|
345
344
|
</div>
|
|
346
345
|
</div>
|
|
347
346
|
<p v-if="results.length === 0" class="selectinput-option opacity-3 pointer-events-none">
|
|
@@ -377,7 +376,6 @@ onMounted(() => {
|
|
|
377
376
|
|
|
378
377
|
.selectinput-options.multiselect .selectinput-option {
|
|
379
378
|
grid-template-columns: 10px 1fr;
|
|
380
|
-
|
|
381
379
|
}
|
|
382
380
|
|
|
383
381
|
.selectinput-options {
|
|
@@ -410,7 +408,7 @@ onMounted(() => {
|
|
|
410
408
|
}
|
|
411
409
|
|
|
412
410
|
.selected {
|
|
413
|
-
color: var(--bgl-primary);
|
|
411
|
+
color: var(--bgl-input-label-active-color, var(--bgl-primary));
|
|
414
412
|
background: var(--bgl-selected);
|
|
415
413
|
}
|
|
416
414
|
</style>
|
|
@@ -448,10 +446,6 @@ onMounted(() => {
|
|
|
448
446
|
.selectinput-btn.selectinput-btn--round { border-radius: 999px; }
|
|
449
447
|
.selectinput-btn.selectinput-btn--thin { height: calc(var(--input-height) * 0.75); padding: 0 0.5rem; }
|
|
450
448
|
|
|
451
|
-
.selectinput .bagel-input.mb-0 input {
|
|
452
|
-
/* background: transparent !important; */
|
|
453
|
-
}
|
|
454
|
-
|
|
455
449
|
.selectinput-btn:disabled {
|
|
456
450
|
color: var(--input-disabled-color);
|
|
457
451
|
background-color: transparent;
|
|
@@ -464,11 +458,11 @@ onMounted(() => {
|
|
|
464
458
|
|
|
465
459
|
.selectinput.has-error .selectinput-btn {
|
|
466
460
|
border-color: var(--bgl-red, #dc3545) !important;
|
|
467
|
-
|
|
468
|
-
|
|
461
|
+
outline: 1px solid var(--bgl-red, #dc3545) !important;
|
|
462
|
+
}
|
|
469
463
|
|
|
470
|
-
|
|
471
|
-
|
|
464
|
+
.selectinput.underlined.has-error .selectinput-btn {
|
|
465
|
+
border-color: var(--bgl-red, #dc3545) !important;
|
|
472
466
|
}
|
|
473
467
|
|
|
474
468
|
/* Underlined mode styling */
|
|
@@ -4,6 +4,8 @@ import { Btn } from '@bagelink/vue'
|
|
|
4
4
|
import { useEventListener, useResizeObserver } from '@vueuse/core'
|
|
5
5
|
import SignaturePad from 'signature_pad'
|
|
6
6
|
import { computed, onMounted, ref, watch } from 'vue'
|
|
7
|
+
import type { BagelInputShellProps } from './bagelInputShell'
|
|
8
|
+
import { useBagelInputShell } from './bagelInputShell'
|
|
7
9
|
|
|
8
10
|
export interface WaterMark {
|
|
9
11
|
text: string
|
|
@@ -33,10 +35,14 @@ const props = withDefaults(defineProps<{
|
|
|
33
35
|
required?: boolean
|
|
34
36
|
label?: string
|
|
35
37
|
helptext?: string
|
|
36
|
-
|
|
38
|
+
penColor?: string
|
|
39
|
+
backgroundColor?: string
|
|
40
|
+
} & BagelInputShellProps>(), {
|
|
37
41
|
clearable: true,
|
|
38
42
|
})
|
|
39
43
|
|
|
44
|
+
const { shellClass, shellStyle } = useBagelInputShell(props)
|
|
45
|
+
|
|
40
46
|
const sigData = defineModel()
|
|
41
47
|
const fileData = defineModel<File>('file')
|
|
42
48
|
|
|
@@ -108,10 +114,15 @@ function undo() {
|
|
|
108
114
|
|
|
109
115
|
const defaultOptions = ref<SignaturePadOptions>({
|
|
110
116
|
penColor: 'rgb(0, 0, 0)',
|
|
111
|
-
backgroundColor: '
|
|
117
|
+
backgroundColor: 'rgba(0,0,0,0)',
|
|
112
118
|
})
|
|
113
119
|
|
|
114
|
-
const signatureOptions = computed(() => ({
|
|
120
|
+
const signatureOptions = computed(() => ({
|
|
121
|
+
...defaultOptions.value,
|
|
122
|
+
...(props.penColor ? { penColor: props.penColor } : {}),
|
|
123
|
+
...(props.backgroundColor ? { backgroundColor: props.backgroundColor } : {}),
|
|
124
|
+
...props.sigOption,
|
|
125
|
+
}))
|
|
115
126
|
|
|
116
127
|
watch(
|
|
117
128
|
() => props.disabled,
|
|
@@ -121,6 +132,14 @@ watch(
|
|
|
121
132
|
},
|
|
122
133
|
)
|
|
123
134
|
|
|
135
|
+
watch(signatureOptions, (opts) => {
|
|
136
|
+
if (!sig.value) { return }
|
|
137
|
+
sig.value.penColor = opts.penColor ?? 'rgb(0,0,0)'
|
|
138
|
+
if (opts.backgroundColor) {
|
|
139
|
+
sig.value.backgroundColor = opts.backgroundColor
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
|
|
124
143
|
function addWaterMark(data: WaterMark) {
|
|
125
144
|
if (!(Object.prototype.toString.call(data) === '[object Object]')) {
|
|
126
145
|
throw new Error(`Expected Object, got ${typeof data}.`)
|
|
@@ -216,11 +235,11 @@ defineExpose({
|
|
|
216
235
|
|
|
217
236
|
<template>
|
|
218
237
|
<div
|
|
219
|
-
class="bgl_input signature-pad relative"
|
|
220
|
-
:class="{ '
|
|
221
|
-
@touchmove.prevent
|
|
238
|
+
class="bagel-input bgl_input signature-pad relative"
|
|
239
|
+
:class="[shellClass, { 'has-value': !_isEmpty }]" :style="shellStyle"
|
|
240
|
+
tabindex="-1" @touchmove.prevent
|
|
222
241
|
>
|
|
223
|
-
<label v-if="label" class="label">{{ label }}</label>
|
|
242
|
+
<label v-if="label" class="label-text">{{ label }}</label>
|
|
224
243
|
<p v-if="helptext" class="helptext">{{ helptext }}</p>
|
|
225
244
|
<Btn
|
|
226
245
|
v-if="clearable && !disabled"
|
|
@@ -234,6 +253,7 @@ defineExpose({
|
|
|
234
253
|
ref="vCanvas"
|
|
235
254
|
class="canvas"
|
|
236
255
|
:disabled
|
|
256
|
+
:style="backgroundColor ? { background: backgroundColor } : {}"
|
|
237
257
|
/>
|
|
238
258
|
<input
|
|
239
259
|
placeholder="required"
|
|
@@ -257,22 +277,27 @@ defineExpose({
|
|
|
257
277
|
}
|
|
258
278
|
|
|
259
279
|
.bgl_input.signature-pad {
|
|
260
|
-
background:
|
|
280
|
+
background: transparent;
|
|
261
281
|
border: none;
|
|
262
282
|
border-radius: var(--input-border-radius);
|
|
263
283
|
}
|
|
264
284
|
|
|
265
|
-
.bgl_input.signature-pad
|
|
285
|
+
.bgl_input.signature-pad .canvas {
|
|
286
|
+
background: var(--input-bg);
|
|
287
|
+
border-radius: var(--input-border-radius);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.bgl_input.signature-pad > .label-text {
|
|
266
291
|
display: block;
|
|
267
|
-
font-size:
|
|
268
|
-
|
|
292
|
+
font-size: var(--label-font-size);
|
|
293
|
+
margin-bottom: 0.25rem;
|
|
269
294
|
}
|
|
270
295
|
|
|
271
296
|
.bgl_input.signature-pad > .helptext {
|
|
272
|
-
font-size:
|
|
273
|
-
|
|
274
|
-
margin: 0;
|
|
297
|
+
font-size: var(--label-font-size);
|
|
298
|
+
margin: 0 0 0.25rem 0;
|
|
275
299
|
line-height: 1.4;
|
|
300
|
+
opacity: 0.7;
|
|
276
301
|
}
|
|
277
302
|
|
|
278
303
|
.bgl_input.signature-pad .canvas[disabled] {
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import { Btn, Icon, formatString } from '@bagelink/vue'
|
|
3
3
|
import { onMounted, ref } from 'vue'
|
|
4
4
|
import { VueDraggableNext } from 'vue-draggable-next'
|
|
5
|
+
import type { BagelInputShellProps } from './bagelInputShell'
|
|
6
|
+
import { useBagelInputShell } from './bagelInputShell'
|
|
5
7
|
|
|
6
8
|
const props = withDefaults(
|
|
7
9
|
defineProps<{
|
|
@@ -10,7 +12,7 @@ const props = withDefaults(
|
|
|
10
12
|
fieldname: string
|
|
11
13
|
bagelApp?: any
|
|
12
14
|
modelValue: any
|
|
13
|
-
}>(),
|
|
15
|
+
} & BagelInputShellProps>(),
|
|
14
16
|
{
|
|
15
17
|
description: '',
|
|
16
18
|
bagelApp: undefined,
|
|
@@ -63,6 +65,8 @@ function ended() {
|
|
|
63
65
|
})
|
|
64
66
|
emits('update:modelValue', listRef.value)
|
|
65
67
|
}
|
|
68
|
+
const { shellClass, shellStyle } = useBagelInputShell(props)
|
|
69
|
+
|
|
66
70
|
onMounted(() => {
|
|
67
71
|
bagel = props.bagelApp || api
|
|
68
72
|
})
|
|
@@ -73,7 +77,7 @@ onMounted(() => {
|
|
|
73
77
|
class="table-field-wrap"
|
|
74
78
|
:title="description"
|
|
75
79
|
>
|
|
76
|
-
<div class="bagel-input">
|
|
80
|
+
<div class="bagel-input" :class="shellClass" :style="shellStyle">
|
|
77
81
|
<label>
|
|
78
82
|
{{ fieldMeta?.label }}
|
|
79
83
|
</label>
|
|
@@ -4,6 +4,8 @@ import type { CountryCode } from 'libphonenumber-js'
|
|
|
4
4
|
import { Dropdown, Flag, Icon, TextInput, allCountries, ipapi, useI18n, resolveI18n } from '@bagelink/vue'
|
|
5
5
|
import { parsePhoneNumberFromString } from 'libphonenumber-js'
|
|
6
6
|
import { computed, onMounted, ref, watch } from 'vue'
|
|
7
|
+
import type { BagelInputShellProps } from './bagelInputShell'
|
|
8
|
+
import { useBagelInputShell } from './bagelInputShell'
|
|
7
9
|
|
|
8
10
|
const props = defineProps<{
|
|
9
11
|
id?: string
|
|
@@ -16,7 +18,9 @@ const props = defineProps<{
|
|
|
16
18
|
disabled?: boolean
|
|
17
19
|
underlined?: boolean
|
|
18
20
|
error?: string
|
|
19
|
-
}>()
|
|
21
|
+
} & BagelInputShellProps>()
|
|
22
|
+
|
|
23
|
+
const { shellClass, shellStyle } = useBagelInputShell(props)
|
|
20
24
|
|
|
21
25
|
const emit = defineEmits(['update:modelValue', 'blur', 'focus', 'keydown', 'input', 'paste'])
|
|
22
26
|
|
|
@@ -230,7 +234,10 @@ onMounted(initializeCountry)
|
|
|
230
234
|
</script>
|
|
231
235
|
|
|
232
236
|
<template>
|
|
233
|
-
<div
|
|
237
|
+
<div
|
|
238
|
+
class="bagel-input text-input" :class="[shellClass, { 'invalid': !isValid, 'has-error': !!error, underlined, 'has-value': hasValue }]"
|
|
239
|
+
:style="shellStyle"
|
|
240
|
+
>
|
|
234
241
|
<label>
|
|
235
242
|
<span v-if="label || (underlined && placeholder)" class="label-text">{{ resolveI18n(label) || resolveI18n(placeholder) }}<span v-if="required"> *</span></span>
|
|
236
243
|
<div
|
|
@@ -302,14 +309,49 @@ onMounted(initializeCountry)
|
|
|
302
309
|
box-shadow: inset 0 0 10px #00000012;
|
|
303
310
|
}
|
|
304
311
|
|
|
312
|
+
/* In frame mode, remove the solid background from .tel-input wrapper */
|
|
313
|
+
.bagel-input.frame .tel-input {
|
|
314
|
+
background: transparent !important;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/* frame variant: outline on the tel-input wrapper */
|
|
318
|
+
.bagel-input.frame .tel-input {
|
|
319
|
+
outline: 1.5px solid var(--border-color);
|
|
320
|
+
outline-offset: -1px;
|
|
321
|
+
transition: outline-color 0.2s ease, box-shadow 0.2s ease;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.bagel-input.frame .tel-input:focus-within {
|
|
325
|
+
outline-color: var(--bgl-input-label-active-color, var(--bgl-primary)) !important;
|
|
326
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--bgl-input-label-active-color, var(--bgl-primary)) 12%, transparent) !important;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/* bgl-outline variant: outline on the tel-input wrapper */
|
|
330
|
+
.bagel-input.bgl-outline .tel-input {
|
|
331
|
+
outline: 1.5px solid var(--border-color);
|
|
332
|
+
outline-offset: -1px;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/* Prevent the global frame/outline rules from hitting the inner inputs */
|
|
336
|
+
.bagel-input.frame .tel-input input,
|
|
337
|
+
.bagel-input.bgl-outline .tel-input input,
|
|
338
|
+
.bagel-input.frame .tel-input input:focus,
|
|
339
|
+
.bagel-input.frame .tel-input input:focus-visible {
|
|
340
|
+
outline: none !important;
|
|
341
|
+
box-shadow: none !important;
|
|
342
|
+
background: transparent;
|
|
343
|
+
}
|
|
344
|
+
|
|
305
345
|
.tel-input input {
|
|
306
346
|
background: transparent;
|
|
307
347
|
text-align: left;
|
|
308
348
|
flex: 1;
|
|
309
349
|
}
|
|
310
350
|
|
|
351
|
+
.tel-input input:focus,
|
|
311
352
|
.tel-input input:focus-visible {
|
|
312
|
-
|
|
353
|
+
outline: none !important;
|
|
354
|
+
box-shadow: none !important;
|
|
313
355
|
}
|
|
314
356
|
|
|
315
357
|
.country-code-display {
|
|
@@ -342,6 +384,12 @@ onMounted(initializeCountry)
|
|
|
342
384
|
margin-left: 4px;
|
|
343
385
|
}
|
|
344
386
|
|
|
387
|
+
.national-number-input:focus,
|
|
388
|
+
.national-number-input:focus-visible {
|
|
389
|
+
outline: none !important;
|
|
390
|
+
box-shadow: none !important;
|
|
391
|
+
}
|
|
392
|
+
|
|
345
393
|
.country-changed {
|
|
346
394
|
animation: highlight-country 1.5s ease-in-out;
|
|
347
395
|
}
|
|
@@ -391,7 +439,7 @@ onMounted(initializeCountry)
|
|
|
391
439
|
|
|
392
440
|
/* When focused in underlined mode, make label primary color */
|
|
393
441
|
.bagel-input.underlined:focus-within .label-text {
|
|
394
|
-
color: var(--bgl-primary);
|
|
442
|
+
color: var(--bgl-input-label-active-color, var(--bgl-primary));
|
|
395
443
|
opacity: 1;
|
|
396
444
|
}
|
|
397
445
|
|