@bagelink/vue 1.15.202 → 1.15.205
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/AddressSearch.vue.d.ts.map +1 -1
- package/dist/components/Swiper.vue.d.ts +2 -2
- package/dist/components/calendar/CalendarPopover.vue.d.ts.map +1 -1
- package/dist/components/charts/BarChart.vue.d.ts.map +1 -1
- package/dist/components/charts/ChartTooltip.vue.d.ts.map +1 -1
- package/dist/components/charts/Donut.vue.d.ts.map +1 -1
- package/dist/components/charts/Funnel.vue.d.ts.map +1 -1
- package/dist/components/charts/Gauge.vue.d.ts.map +1 -1
- package/dist/components/charts/LineChart.vue.d.ts.map +1 -1
- package/dist/components/charts/MapChart.vue.d.ts +25 -0
- package/dist/components/charts/MapChart.vue.d.ts.map +1 -0
- package/dist/components/charts/RadialBars.vue.d.ts.map +1 -1
- package/dist/components/charts/RankBars.vue.d.ts.map +1 -1
- package/dist/components/charts/StatCard.vue.d.ts.map +1 -1
- package/dist/components/charts/core/arc.d.ts +6 -0
- package/dist/components/charts/core/arc.d.ts.map +1 -0
- package/dist/components/charts/core/useChartTip.d.ts +13 -0
- package/dist/components/charts/core/useChartTip.d.ts.map +1 -0
- package/dist/components/charts/core/world-paths.d.ts +13 -0
- package/dist/components/charts/core/world-paths.d.ts.map +1 -0
- package/dist/components/charts/index.d.ts +2 -0
- package/dist/components/charts/index.d.ts.map +1 -1
- package/dist/components/charts/mapTypes.d.ts +7 -0
- package/dist/components/charts/mapTypes.d.ts.map +1 -0
- package/dist/components/dataTable/DataTable.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/DateInput.vue.d.ts +3 -0
- package/dist/components/form/inputs/DateInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/NumberInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/index.d.ts +0 -1
- package/dist/components/form/inputs/index.d.ts.map +1 -1
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/form-flow/FormFlowPlayer.vue.d.ts +18 -0
- package/dist/form-flow/FormFlowPlayer.vue.d.ts.map +1 -1
- package/dist/form-flow/structure.d.ts +12 -0
- package/dist/form-flow/structure.d.ts.map +1 -1
- package/dist/index.cjs +177 -154
- package/dist/index.mjs +37661 -43116
- package/dist/style.css +1 -2
- package/package.json +1 -1
- package/src/components/charts/BarChart.vue +15 -15
- package/src/components/charts/ChartTooltip.vue +7 -6
- package/src/components/charts/Donut.vue +25 -40
- package/src/components/charts/Funnel.vue +10 -12
- package/src/components/charts/Gauge.vue +4 -2
- package/src/components/charts/LineChart.vue +15 -17
- package/src/components/charts/MapChart.vue +198 -0
- package/src/components/charts/RadialBars.vue +3 -1
- package/src/components/charts/RankBars.vue +2 -0
- package/src/components/charts/Sparkline.vue +1 -1
- package/src/components/charts/StatCard.vue +2 -0
- package/src/components/charts/core/arc.ts +53 -0
- package/src/components/charts/core/useChartTip.ts +35 -0
- package/src/components/charts/core/world-paths.ts +351 -0
- package/src/components/charts/index.ts +3 -0
- package/src/components/charts/mapTypes.ts +6 -0
- package/src/components/dataTable/useTableVirtualization.ts +5 -5
- package/src/components/form/inputs/DateInput.vue +9 -1
- package/src/components/form/inputs/NumberInput.vue +17 -6
- package/src/components/form/inputs/index.ts +0 -1
- package/src/components/index.ts +2 -2
- package/src/form-flow/FormFlowPlayer.vue +49 -0
- package/src/form-flow/structure.ts +12 -0
- package/dist/components/dataTable/useTableVirtualization.d.ts +0 -25
- package/dist/components/dataTable/useTableVirtualization.d.ts.map +0 -1
- package/dist/components/form/inputs/JSONInput.vue.d.ts +0 -21
- package/dist/components/form/inputs/JSONInput.vue.d.ts.map +0 -1
- package/src/components/form/inputs/JSONInput.vue +0 -60
|
@@ -4,9 +4,12 @@ export { default as BarChart } from './BarChart.vue'
|
|
|
4
4
|
export { default as Donut } from './Donut.vue'
|
|
5
5
|
export { default as Funnel } from './Funnel.vue'
|
|
6
6
|
export { default as Gauge } from './Gauge.vue'
|
|
7
|
+
export { default as MapChart } from './MapChart.vue'
|
|
7
8
|
export { default as RadialBars } from './RadialBars.vue'
|
|
8
9
|
export { default as RankBars } from './RankBars.vue'
|
|
9
10
|
export { default as StatCard } from './StatCard.vue'
|
|
10
11
|
|
|
12
|
+
export type { MapDatum } from './mapTypes'
|
|
13
|
+
|
|
11
14
|
export type { RawPoint, RawSeries, NormalizeOptions } from './core/data'
|
|
12
15
|
export type { ValueFormat } from './core/format'
|
|
@@ -11,9 +11,10 @@ export function useTableVirtualization<T>(options: TableVirtualizationOptions<T>
|
|
|
11
11
|
return [{ __isHeader: true } as any, ...originalData]
|
|
12
12
|
})
|
|
13
13
|
|
|
14
|
-
//
|
|
14
|
+
// `as any`: packages/vue nests vue@3.5.40 while @vueuse/core is typed against
|
|
15
|
+
// workspace vue@3.5.35 — RefSymbol identities diverge under root tsc.
|
|
15
16
|
const { list, containerProps, wrapperProps, scrollTo } = useVirtualList(
|
|
16
|
-
dataWithHeader,
|
|
17
|
+
dataWithHeader as any,
|
|
17
18
|
{
|
|
18
19
|
itemHeight: options.itemHeight,
|
|
19
20
|
overscan: 10,
|
|
@@ -28,11 +29,10 @@ export function useTableVirtualization<T>(options: TableVirtualizationOptions<T>
|
|
|
28
29
|
async function registerLastItemObserver() {
|
|
29
30
|
await until(() => lastItemEl.value).toBeTruthy()
|
|
30
31
|
|
|
31
|
-
useIntersectionObserver(lastItemEl, ([entry]) => {
|
|
32
|
-
// Check if options.data.value exists and has length
|
|
32
|
+
useIntersectionObserver(lastItemEl as any, ([entry]) => {
|
|
33
33
|
const dataLength = toValue(options.data).length || 0
|
|
34
34
|
|
|
35
|
-
if (entry
|
|
35
|
+
if (entry?.isIntersecting && dataLength > 0) {
|
|
36
36
|
options.onLastItemVisible?.()
|
|
37
37
|
}
|
|
38
38
|
})
|
|
@@ -36,6 +36,8 @@ export interface DateInputProps extends BagelInputShellProps {
|
|
|
36
36
|
center?: boolean
|
|
37
37
|
error?: string
|
|
38
38
|
underlined?: boolean
|
|
39
|
+
/** When true, input is not editable (same as `edit-mode="false"`). */
|
|
40
|
+
disabled?: boolean
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
const props = withDefaults(
|
|
@@ -43,6 +45,7 @@ const props = withDefaults(
|
|
|
43
45
|
{
|
|
44
46
|
enableTime: false,
|
|
45
47
|
editMode: true,
|
|
48
|
+
disabled: false,
|
|
46
49
|
small: false,
|
|
47
50
|
range: false,
|
|
48
51
|
mode: () => ({ mode: 'day' }),
|
|
@@ -51,6 +54,8 @@ const props = withDefaults(
|
|
|
51
54
|
},
|
|
52
55
|
)
|
|
53
56
|
|
|
57
|
+
const isEditable = computed(() => props.editMode && !props.disabled)
|
|
58
|
+
|
|
54
59
|
const { $t } = useI18n()
|
|
55
60
|
|
|
56
61
|
const { shellClass, shellStyle } = useBagelInputShell(props)
|
|
@@ -112,6 +117,9 @@ function normalizeDate(date: Date): string {
|
|
|
112
117
|
function coerceDateOnlyValue(val: string | Date | DateRangeValue | undefined): string | Date | DateRangeValue | undefined {
|
|
113
118
|
if (props.enableTime || props.range || val == null) return val
|
|
114
119
|
if (typeof val === 'string' && val.includes('T')) {
|
|
120
|
+
// Prefer the calendar day from the string — avoids TZ shifting midnight UTC/local.
|
|
121
|
+
const day = /^(\d{4}-\d{2}-\d{2})/.exec(val)?.[1]
|
|
122
|
+
if (day) return day
|
|
115
123
|
const d = new Date(val)
|
|
116
124
|
if (!Number.isNaN(d.getTime())) return local.date(d)
|
|
117
125
|
}
|
|
@@ -312,7 +320,7 @@ onMounted(() => {
|
|
|
312
320
|
<TextInput
|
|
313
321
|
v-model="inputValue" iconStart="calendar"
|
|
314
322
|
:placeholder="underlined ? ' ' : (resolveI18n(placeholder) || defaultPlaceholder)"
|
|
315
|
-
:required="underlined ? false : required" :disabled="!
|
|
323
|
+
:required="underlined ? false : required" :disabled="!isEditable"
|
|
316
324
|
:error="!isValid ? $t('date.invalidFormat') : error" :class="{ 'txt-center': center }"
|
|
317
325
|
:underlined="underlined" :frame="frame" :outline="outline" :min-width="minWidth"
|
|
318
326
|
:max-width="maxWidth" :label-color="labelColor" :label-active-color="labelActiveColor"
|
|
@@ -146,12 +146,23 @@ watch(() => numberValue.value, () => {
|
|
|
146
146
|
})
|
|
147
147
|
|
|
148
148
|
watch(() => modelValue, (newVal) => {
|
|
149
|
-
if (newVal
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
149
|
+
if (newVal === undefined || newVal === null || newVal === '') {
|
|
150
|
+
numberValue.value = undefined
|
|
151
|
+
formattedValue.value = ''
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
if (typeof newVal === 'string' && (newVal === '-' || newVal.endsWith('.'))) {
|
|
155
|
+
formattedValue.value = newVal
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
const parsed = Number.parseFloat(`${newVal}`)
|
|
159
|
+
if (Number.isNaN(parsed)) {
|
|
160
|
+
numberValue.value = undefined
|
|
161
|
+
formattedValue.value = ''
|
|
162
|
+
return
|
|
163
|
+
}
|
|
164
|
+
if (parsed !== numberValue.value) {
|
|
165
|
+
numberValue.value = parsed
|
|
155
166
|
}
|
|
156
167
|
}, { immediate: true })
|
|
157
168
|
|
|
@@ -7,7 +7,6 @@ export { default as ColorInput } from './ColorInput.vue'
|
|
|
7
7
|
export { default as DateInput } from './DateInput.vue'
|
|
8
8
|
export { default as DatePicker } from './DatePicker.vue'
|
|
9
9
|
export { default as EmailInput } from './EmailInput.vue'
|
|
10
|
-
export { default as JSONInput } from './JSONInput.vue'
|
|
11
10
|
export { default as MarkdownEditor } from './MarkdownEditor.vue'
|
|
12
11
|
export { default as NumberInput } from './NumberInput.vue'
|
|
13
12
|
export { default as OTP } from './OTP.vue'
|
package/src/components/index.ts
CHANGED
|
@@ -3,8 +3,8 @@ export { default as AccordionItem } from './AccordionItem.vue'
|
|
|
3
3
|
export { default as AddressSearch } from './AddressSearch.vue'
|
|
4
4
|
export { default as AddToCalendar } from './AddToCalendar.vue'
|
|
5
5
|
export { default as Alert } from './Alert.vue'
|
|
6
|
-
export { BarChart, Donut, Funnel, Gauge, LineChart, RadialBars, RankBars, Sparkline, StatCard } from './charts'
|
|
7
|
-
export type { NormalizeOptions, RawPoint, RawSeries, ValueFormat } from './charts'
|
|
6
|
+
export { BarChart, Donut, Funnel, Gauge, LineChart, MapChart, RadialBars, RankBars, Sparkline, StatCard } from './charts'
|
|
7
|
+
export type { MapDatum, NormalizeOptions, RawPoint, RawSeries, ValueFormat } from './charts'
|
|
8
8
|
export { default as Avatar } from './Avatar.vue'
|
|
9
9
|
export { default as Badge } from './Badge.vue'
|
|
10
10
|
/** @deprecated Renamed to Badge. Pill is an alias that will be removed in a future version. */
|
|
@@ -37,6 +37,18 @@ export interface Props {
|
|
|
37
37
|
autoAdvance?: boolean
|
|
38
38
|
/** Delay (ms) before an auto-advance fires, letting the choice paint. */
|
|
39
39
|
autoAdvanceDelay?: number
|
|
40
|
+
/**
|
|
41
|
+
* Push each step's `enterEvent` / `submitEvent` payload to `window.dataLayer`
|
|
42
|
+
* (GTM). Default true. Set false to suppress (e.g. SSR or when the host wants
|
|
43
|
+
* to handle analytics itself via the `dataLayer` event).
|
|
44
|
+
*/
|
|
45
|
+
dataLayer?: boolean
|
|
46
|
+
/**
|
|
47
|
+
* Perform `redirectUrl` navigation on submit. Default true. Set false to let
|
|
48
|
+
* the host own navigation (it can read the URL from the `complete` event or
|
|
49
|
+
* the `redirect` event).
|
|
50
|
+
*/
|
|
51
|
+
redirect?: boolean
|
|
40
52
|
/** Optional async submit handler; awaited before `complete` is emitted. */
|
|
41
53
|
onComplete?: (data: Record<string, any>) => Promise<void> | void
|
|
42
54
|
}
|
|
@@ -45,6 +57,8 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
45
57
|
animated: true,
|
|
46
58
|
autoAdvance: true,
|
|
47
59
|
autoAdvanceDelay: 200,
|
|
60
|
+
dataLayer: true,
|
|
61
|
+
redirect: true,
|
|
48
62
|
})
|
|
49
63
|
|
|
50
64
|
const emit = defineEmits<{
|
|
@@ -52,6 +66,10 @@ const emit = defineEmits<{
|
|
|
52
66
|
'stepChange': [stepKey: string]
|
|
53
67
|
/** Best-effort 0–100 progress along the current path; recomputes on change. */
|
|
54
68
|
'progress': [value: number]
|
|
69
|
+
/** A dataLayer payload was pushed. `phase` = which step hook fired it. */
|
|
70
|
+
'dataLayer': [payload: Record<string, any>, phase: 'enter' | 'submit']
|
|
71
|
+
/** The form is about to redirect to `url` (fired even if `redirect` is off). */
|
|
72
|
+
'redirect': [url: string]
|
|
55
73
|
'complete': [data: Record<string, any>]
|
|
56
74
|
}>()
|
|
57
75
|
|
|
@@ -90,6 +108,26 @@ watch(currentKey, (key) => {
|
|
|
90
108
|
|
|
91
109
|
const currentStep = computed(() => stepByKey(props.structure, currentKey.value ?? null))
|
|
92
110
|
|
|
111
|
+
// ─── dataLayer (GTM) ─────────────────────────────────────────────────────────
|
|
112
|
+
// Push a step's analytics payload to window.dataLayer and notify the host. The
|
|
113
|
+
// server stores these payloads verbatim; the client decides when to fire them:
|
|
114
|
+
// `enterEvent` on step entry, `submitEvent` on submit-from-a-terminal-step.
|
|
115
|
+
function pushDataLayer(payload: Record<string, any> | null | undefined, phase: 'enter' | 'submit') {
|
|
116
|
+
if (!payload || typeof payload !== 'object') return
|
|
117
|
+
emit('dataLayer', payload, phase)
|
|
118
|
+
if (!props.dataLayer || typeof window === 'undefined') return
|
|
119
|
+
const w = window as unknown as { dataLayer?: Record<string, any>[] }
|
|
120
|
+
w.dataLayer = w.dataLayer || []
|
|
121
|
+
w.dataLayer.push({ ...payload })
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Fire the current step's `enterEvent` whenever we land on it (including the
|
|
125
|
+
// first step). `immediate` covers the entry step; the key guard avoids
|
|
126
|
+
// re-firing when the same step object recomputes.
|
|
127
|
+
watch(currentKey, (key, prev) => {
|
|
128
|
+
if (key && key !== prev) pushDataLayer(stepByKey(props.structure, key)?.enterEvent, 'enter')
|
|
129
|
+
}, { immediate: true })
|
|
130
|
+
|
|
93
131
|
// Convert the current step's stored JSON Schema into a renderable schema.
|
|
94
132
|
const currentSchema = computed(() => {
|
|
95
133
|
const step = currentStep.value
|
|
@@ -124,9 +162,20 @@ async function onPrimary() {
|
|
|
124
162
|
|
|
125
163
|
if (isTerminal.value) {
|
|
126
164
|
submitting.value = true
|
|
165
|
+
const step = currentStep.value
|
|
127
166
|
try {
|
|
128
167
|
await props.onComplete?.({ ...formData.value })
|
|
168
|
+
// Fire this terminal step's submit analytics before completing.
|
|
169
|
+
pushDataLayer(step?.submitEvent, 'submit')
|
|
129
170
|
emit('complete', { ...formData.value })
|
|
171
|
+
// Redirect last: leaves the page after analytics + host handling.
|
|
172
|
+
const url = step?.redirectUrl?.trim()
|
|
173
|
+
if (url) {
|
|
174
|
+
emit('redirect', url)
|
|
175
|
+
if (props.redirect && typeof window !== 'undefined') {
|
|
176
|
+
window.location.assign(url)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
130
179
|
}
|
|
131
180
|
finally {
|
|
132
181
|
submitting.value = false
|
|
@@ -26,6 +26,18 @@ export interface FormStep {
|
|
|
26
26
|
* default: a single required radio/select field. `false` force-disables.
|
|
27
27
|
*/
|
|
28
28
|
autoAdvance?: boolean
|
|
29
|
+
/**
|
|
30
|
+
* Where to send the browser after the form is submitted *from this step*
|
|
31
|
+
* (final step or an early-termination leaf). Empty => no redirect.
|
|
32
|
+
*/
|
|
33
|
+
redirectUrl?: string | null
|
|
34
|
+
/** dataLayer payload pushed when the user *enters* this step. */
|
|
35
|
+
enterEvent?: Record<string, any> | null
|
|
36
|
+
/**
|
|
37
|
+
* dataLayer payload pushed when the form is *submitted* from this step
|
|
38
|
+
* (i.e. this step is terminal), before the redirect.
|
|
39
|
+
*/
|
|
40
|
+
submitEvent?: Record<string, any> | null
|
|
29
41
|
/** Canvas position (designer-only; ignored by the server). */
|
|
30
42
|
x?: number
|
|
31
43
|
y?: number
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { TableVirtualizationOptions } from '../../types/TableSchema';
|
|
2
|
-
export declare function useTableVirtualization<T>(options: TableVirtualizationOptions<T>): {
|
|
3
|
-
list: import('vue').ComputedRef<import('@vueuse/core').UseVirtualListItem<any>[]>;
|
|
4
|
-
containerProps: {
|
|
5
|
-
ref: import('vue').Ref<HTMLElement | null>;
|
|
6
|
-
onScroll: () => void;
|
|
7
|
-
style: import('vue').StyleValue;
|
|
8
|
-
};
|
|
9
|
-
wrapperProps: import('vue').ComputedRef<{
|
|
10
|
-
style: {
|
|
11
|
-
width: string;
|
|
12
|
-
height: string;
|
|
13
|
-
marginTop: string;
|
|
14
|
-
} | {
|
|
15
|
-
width: string;
|
|
16
|
-
height: string;
|
|
17
|
-
marginLeft: string;
|
|
18
|
-
display: string;
|
|
19
|
-
};
|
|
20
|
-
}>;
|
|
21
|
-
scrollTo: (index: number) => void;
|
|
22
|
-
lastItemEl: import('vue').Ref<HTMLTableRowElement | null, HTMLTableRowElement | null>;
|
|
23
|
-
registerLastItemObserver: () => Promise<void>;
|
|
24
|
-
};
|
|
25
|
-
//# sourceMappingURL=useTableVirtualization.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useTableVirtualization.d.ts","sourceRoot":"","sources":["../../../src/components/dataTable/useTableVirtualization.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAA;AAIzE,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,OAAO,EAAE,0BAA0B,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;EA4C/E"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { BagelInputShellProps } from './bagelInputShell';
|
|
2
|
-
type __VLS_Props = {
|
|
3
|
-
description?: string;
|
|
4
|
-
label?: string;
|
|
5
|
-
modelValue: any;
|
|
6
|
-
placeholder?: string;
|
|
7
|
-
editMode?: boolean;
|
|
8
|
-
small?: boolean;
|
|
9
|
-
} & BagelInputShellProps;
|
|
10
|
-
declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
11
|
-
"update:modelValue": (...args: any[]) => void;
|
|
12
|
-
}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
13
|
-
"onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
|
|
14
|
-
}>, {
|
|
15
|
-
label: string;
|
|
16
|
-
description: string;
|
|
17
|
-
placeholder: string;
|
|
18
|
-
editMode: boolean;
|
|
19
|
-
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
|
|
20
|
-
export default _default;
|
|
21
|
-
//# sourceMappingURL=JSONInput.vue.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"JSONInput.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/form/inputs/JSONInput.vue"],"names":[],"mappings":"AAiEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAG7D,KAAK,WAAW,GAAG;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,GAAG,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;CACf,GAAG,oBAAoB,CAAC;;;;;;WALhB,MAAM;iBADA,MAAM;iBAGN,MAAM;cACT,OAAO;;AAkGpB,wBASG"}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
// const props =
|
|
3
|
-
import { computed } from 'vue'
|
|
4
|
-
import { resolveI18n } from '@bagelink/vue'
|
|
5
|
-
import type { BagelInputShellProps } from './bagelInputShell'
|
|
6
|
-
import { useBagelInputShell } from './bagelInputShell'
|
|
7
|
-
|
|
8
|
-
const props = withDefaults(
|
|
9
|
-
defineProps<{
|
|
10
|
-
description?: string
|
|
11
|
-
label?: string
|
|
12
|
-
modelValue: any
|
|
13
|
-
placeholder?: string
|
|
14
|
-
editMode?: boolean
|
|
15
|
-
small?: boolean
|
|
16
|
-
} & BagelInputShellProps>(),
|
|
17
|
-
{
|
|
18
|
-
description: '',
|
|
19
|
-
editMode: true,
|
|
20
|
-
placeholder: '',
|
|
21
|
-
label: '',
|
|
22
|
-
},
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
const { shellClass, shellStyle } = useBagelInputShell(props)
|
|
26
|
-
const hasValue = computed(() => props.modelValue != null && String(props.modelValue).length > 0)
|
|
27
|
-
|
|
28
|
-
const emits = defineEmits(['update:modelValue'])
|
|
29
|
-
function handleInput(e: Event) {
|
|
30
|
-
const el = e.target as HTMLInputElement
|
|
31
|
-
emits('update:modelValue', el.value)
|
|
32
|
-
}
|
|
33
|
-
</script>
|
|
34
|
-
|
|
35
|
-
<template>
|
|
36
|
-
<div
|
|
37
|
-
class="bagel-input" :title="description"
|
|
38
|
-
:class="[shellClass, { small, 'has-value': hasValue }]" :style="shellStyle"
|
|
39
|
-
>
|
|
40
|
-
<label v-if="label">
|
|
41
|
-
<LangText :input="label" />
|
|
42
|
-
</label>
|
|
43
|
-
<textarea
|
|
44
|
-
:value="modelValue" :class="{ 'no-edit': !editMode }" :placeholder="resolveI18n(placeholder)"
|
|
45
|
-
@input="handleInput"
|
|
46
|
-
/>
|
|
47
|
-
</div>
|
|
48
|
-
</template>
|
|
49
|
-
|
|
50
|
-
<style scoped>
|
|
51
|
-
|
|
52
|
-
.bagel-input textarea {
|
|
53
|
-
font-family: monospace;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
[dir='rtl'] .bagel-input textarea {
|
|
57
|
-
direction: ltr;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
</style>
|