@bagelink/vue 0.0.218 → 0.0.223
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/Avatar.vue.d.ts +20 -0
- package/dist/components/Avatar.vue.d.ts.map +1 -0
- package/dist/components/Card.vue.d.ts +27 -0
- package/dist/components/Card.vue.d.ts.map +1 -0
- package/dist/components/ModalBglForm.vue.d.ts +50 -31
- package/dist/components/ModalBglForm.vue.d.ts.map +1 -1
- package/dist/components/NavBar.vue.d.ts +16 -12
- package/dist/components/NavBar.vue.d.ts.map +1 -1
- package/dist/components/form/BglField.vue.d.ts +12 -19
- package/dist/components/form/BglField.vue.d.ts.map +1 -1
- package/dist/components/form/BglForm.vue.d.ts.map +1 -1
- package/dist/components/form/index.d.ts +0 -3
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/form/inputs/CheckInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/DateInput.vue.d.ts +36 -38
- package/dist/components/form/inputs/DateInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/TableField.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/index.d.ts +0 -2
- package/dist/components/form/inputs/index.d.ts.map +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/index.cjs +13318 -13575
- package/dist/index.mjs +13319 -13576
- package/dist/plugins/modal.d.ts.map +1 -1
- package/dist/style.css +132 -123
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/package.json +9 -10
- package/src/components/Avatar.vue +47 -0
- package/src/components/Card.vue +13 -0
- package/src/components/ContactArray.vue +10 -39
- package/src/components/ModalBglForm.vue +13 -25
- package/src/components/NavBar.vue +25 -9
- package/src/components/PersonPreview.vue +1 -1
- package/src/components/RTXEditor.vue +69 -69
- package/src/components/form/BglField.vue +13 -10
- package/src/components/form/BglForm.vue +3 -9
- package/src/components/form/index.ts +0 -3
- package/src/components/form/inputs/CheckInput.vue +20 -18
- package/src/components/form/inputs/DateInput.vue +14 -23
- package/src/components/form/inputs/TableField.vue +1 -5
- package/src/components/form/inputs/index.ts +0 -2
- package/src/components/index.ts +2 -0
- package/src/plugins/modal.ts +0 -1
- package/src/styles/inputs.css +2 -2
- package/src/styles/layout.css +1 -1
- package/src/styles/theme.css +7 -6
- package/src/types/index.ts +1 -0
- package/src/utils/index.ts +4 -1
- package/src/components/form/ItemRef.vue +0 -44
- package/src/components/form/MaterialIcon.vue +0 -19
- package/src/components/form/PlainInputField.vue +0 -79
- package/src/components/form/inputs/DynamicLinkField.vue +0 -137
- package/src/components/form/inputs/EmailInput.vue +0 -58
package/dist/types/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export type { MaterialIcons } from './materialIcons';
|
|
|
2
2
|
export type { BankDetailsInterface, NewPerson, Person } from './Person';
|
|
3
3
|
export type { Tables, TableToTypeMapping } from '@bagelink/sdk';
|
|
4
4
|
export type { StorageFile } from './file';
|
|
5
|
+
export type { NavLink } from '../components/NavBar.vue';
|
|
5
6
|
export * from './BtnOptions';
|
|
6
7
|
export * from './BagelForm';
|
|
7
8
|
export type ThemeType = 'light' | 'red' | 'gray' | 'gray-light' | 'black' | 'green' | 'primary' | 'blue';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACxE,YAAY,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAChE,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACxE,YAAY,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAChE,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,YAAY,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAExD,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAE5B,MAAM,MAAM,SAAS,GACpB,OAAO,GACL,KAAK,GACL,MAAM,GACN,YAAY,GACZ,OAAO,GACP,OAAO,GACP,SAAS,GACT,MAAM,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,eAAO,MAAM,QAAQ,OAAQ,MAAM,IAAI,yBAGtC,CAAC;AAEF,eAAO,MAAM,UAAU,QAAS,MAAM,WAG3B,CAAC;AAEZ,eAAO,MAAM,QAAQ,SACd,MAAM,cAED,MAAM,KAAK,IAAI,+BAI1B,CAAC;AAEF,eAAO,MAAM,UAAU,eAGtB,CAAC;AAEF,eAAO,MAAM,QAAQ,cAAe,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,eAAO,MAAM,QAAQ,OAAQ,MAAM,IAAI,yBAGtC,CAAC;AAEF,eAAO,MAAM,UAAU,QAAS,MAAM,WAG3B,CAAC;AAEZ,eAAO,MAAM,QAAQ,SACd,MAAM,cAED,MAAM,KAAK,IAAI,+BAI1B,CAAC;AAEF,eAAO,MAAM,UAAU,eAGtB,CAAC;AAEF,eAAO,MAAM,QAAQ,cAAe,MAAM,EAAE,WAG3C,CAAC;AAEF,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,QAIrE;AAED,wBAAgB,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,OAO1F;AAED,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bagelink/vue",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.223",
|
|
5
5
|
"description": "Bagel core sdk packages",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Neveh Allon",
|
|
@@ -50,19 +50,15 @@
|
|
|
50
50
|
"./tsconfig.json",
|
|
51
51
|
"./vite.config.ts"
|
|
52
52
|
],
|
|
53
|
-
"dependencies": {},
|
|
54
53
|
"devDependencies": {
|
|
55
|
-
"vue": "^
|
|
56
|
-
"
|
|
54
|
+
"@vue-macros/reactivity-transform": "^0.4.1",
|
|
55
|
+
"vue": "^3.4.3"
|
|
57
56
|
},
|
|
58
57
|
"peerDependencies": {
|
|
59
58
|
"@bagelink/sdk": "*",
|
|
60
|
-
"vue-router": "*",
|
|
61
|
-
"vue": "*",
|
|
62
|
-
"vue3-charts": "^1.1.33",
|
|
63
|
-
"@formkit/vue": "^1.3.0",
|
|
64
59
|
"@formkit/core": "1.3.0",
|
|
65
|
-
"vue
|
|
60
|
+
"@formkit/vue": "^1.3.0",
|
|
61
|
+
"@vuepic/vue-datepicker": "^7.4.0",
|
|
66
62
|
"prosemirror-commands": "^1.5.2",
|
|
67
63
|
"prosemirror-history": "^1.3.2",
|
|
68
64
|
"prosemirror-keymap": "^1.2.2",
|
|
@@ -70,7 +66,10 @@
|
|
|
70
66
|
"prosemirror-schema-basic": "^1.2.2",
|
|
71
67
|
"prosemirror-state": "^1.4.3",
|
|
72
68
|
"prosemirror-view": "^1.32.4",
|
|
73
|
-
"
|
|
69
|
+
"vue": "*",
|
|
70
|
+
"vue-draggable-next": "^2.2.1",
|
|
71
|
+
"vue-router": "*",
|
|
72
|
+
"vue3-charts": "^1.1.33"
|
|
74
73
|
},
|
|
75
74
|
"peerDependenciesMeta": {
|
|
76
75
|
"@vuepic/vue-datepicker": {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="avatar">
|
|
3
|
+
<img
|
|
4
|
+
v-if="src"
|
|
5
|
+
:src="src"
|
|
6
|
+
:alt="name"
|
|
7
|
+
>
|
|
8
|
+
<p v-else>
|
|
9
|
+
{{ fallback || initials(name || '') }}
|
|
10
|
+
</p>
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script setup lang="ts">
|
|
15
|
+
import { initials } from '@bagelink/vue';
|
|
16
|
+
|
|
17
|
+
defineProps<{
|
|
18
|
+
fallback?: string;
|
|
19
|
+
src?: string;
|
|
20
|
+
name?: string;
|
|
21
|
+
}>();
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<style scoped>
|
|
25
|
+
.avatar{
|
|
26
|
+
border-radius: 100%;
|
|
27
|
+
width: 50px;
|
|
28
|
+
height: 50px;
|
|
29
|
+
background-color: var(--bgl-primary-tint);
|
|
30
|
+
overflow: hidden;
|
|
31
|
+
text-align: center;
|
|
32
|
+
padding: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.avatar p {
|
|
36
|
+
font-size: 1.5rem;
|
|
37
|
+
line-height: 50px;
|
|
38
|
+
margin: 0;
|
|
39
|
+
font-weight: 200;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.avatar img{
|
|
43
|
+
width: 100%;
|
|
44
|
+
height: 100%;
|
|
45
|
+
object-fit: cover;
|
|
46
|
+
}
|
|
47
|
+
</style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="bagel-input mt-2">
|
|
3
|
-
{{
|
|
3
|
+
{{ label }}
|
|
4
4
|
<div class="mb-2 mt-1">
|
|
5
5
|
<div
|
|
6
6
|
class="bglform-contact"
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
v-model="contact.email"
|
|
12
12
|
:placeholder="placeholders.email"
|
|
13
13
|
type="email"
|
|
14
|
-
v-if="
|
|
14
|
+
v-if="id === 'email'"
|
|
15
15
|
>
|
|
16
16
|
<input
|
|
17
17
|
v-model="contact.phone"
|
|
18
18
|
:placeholder="placeholders.phone"
|
|
19
19
|
type="tel"
|
|
20
|
-
v-if="
|
|
20
|
+
v-if="id === 'phone'"
|
|
21
21
|
>
|
|
22
22
|
<input
|
|
23
23
|
v-if="contact.email || contact.phone"
|
|
@@ -28,15 +28,11 @@
|
|
|
28
28
|
<div class="bglform-contact-opt">
|
|
29
29
|
<!-- <input v-model="contact.primary" id="primary" type="checkbox" > -->
|
|
30
30
|
<CheckInput
|
|
31
|
-
|
|
32
|
-
id: 'primary',
|
|
33
|
-
inputType: 'CheckInput',
|
|
34
|
-
label: 'primary',
|
|
35
|
-
}"
|
|
31
|
+
label = "Primary"
|
|
36
32
|
v-model="contact.primary"
|
|
37
33
|
/>
|
|
38
34
|
<MaterialIcon
|
|
39
|
-
@click="
|
|
35
|
+
@click="val.splice(i, 1)"
|
|
40
36
|
icon="delete"
|
|
41
37
|
class="btn-float"
|
|
42
38
|
/>
|
|
@@ -55,20 +51,16 @@
|
|
|
55
51
|
</template>
|
|
56
52
|
|
|
57
53
|
<script setup lang="ts">
|
|
58
|
-
import {
|
|
59
|
-
import type { BagelField } from '@bagelink/vue';
|
|
60
|
-
import MaterialIcon from './MaterialIcon.vue';
|
|
61
|
-
import Btn from './Btn.vue';
|
|
62
|
-
import CheckInput from './form/inputs/CheckInput.vue';
|
|
54
|
+
import { MaterialIcon, Btn, CheckInput } from '.';
|
|
63
55
|
|
|
64
|
-
|
|
56
|
+
withDefaults(
|
|
65
57
|
defineProps<{
|
|
66
|
-
|
|
58
|
+
label?: string;
|
|
67
59
|
modelValue: any;
|
|
68
60
|
editMode?: boolean;
|
|
69
61
|
small?: boolean;
|
|
62
|
+
id: string;
|
|
70
63
|
placeholders: {
|
|
71
|
-
|
|
72
64
|
email: string
|
|
73
65
|
phone: string
|
|
74
66
|
label: string
|
|
@@ -80,28 +72,7 @@ const props = withDefaults(
|
|
|
80
72
|
},
|
|
81
73
|
);
|
|
82
74
|
|
|
83
|
-
const val =
|
|
84
|
-
|
|
85
|
-
const del = (i: number) => {
|
|
86
|
-
val.value.splice(i, 1);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const emit = defineEmits(['update:modelValue']);
|
|
90
|
-
|
|
91
|
-
watch(
|
|
92
|
-
() => props.modelValue,
|
|
93
|
-
() => {
|
|
94
|
-
val.value = [...props.modelValue];
|
|
95
|
-
},
|
|
96
|
-
{ immediate: true },
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
watch(
|
|
100
|
-
() => val,
|
|
101
|
-
() => {
|
|
102
|
-
emit('update:modelValue', val.value);
|
|
103
|
-
},
|
|
104
|
-
);
|
|
75
|
+
const val = defineModel<any[]>('modelValue', { default: [] });
|
|
105
76
|
</script>
|
|
106
77
|
<!--
|
|
107
78
|
<style>
|
|
@@ -23,8 +23,7 @@
|
|
|
23
23
|
</header>
|
|
24
24
|
<BagelForm
|
|
25
25
|
:onDelete="onDelete ? runDelete : undefined"
|
|
26
|
-
|
|
27
|
-
@update:modelValue="handleEmit"
|
|
26
|
+
v-model="formData"
|
|
28
27
|
@submit="runSubmit"
|
|
29
28
|
:schema="computedFormSchema"
|
|
30
29
|
/>
|
|
@@ -33,7 +32,7 @@
|
|
|
33
32
|
</template>
|
|
34
33
|
|
|
35
34
|
<script lang="ts" setup>
|
|
36
|
-
import { onMounted, onUnmounted } from 'vue';
|
|
35
|
+
import { onMounted, onUnmounted, watch } from 'vue';
|
|
37
36
|
import {
|
|
38
37
|
Btn, BtnOptions, useEscape, BagelForm, type BglFormSchemaT,
|
|
39
38
|
} from '@bagelink/vue';
|
|
@@ -45,7 +44,6 @@ const props = defineProps<{
|
|
|
45
44
|
dismissable?: boolean;
|
|
46
45
|
actions?: BtnOptions[];
|
|
47
46
|
schema: BglFormSchemaT | (() => BglFormSchemaT);
|
|
48
|
-
modelValue?: Record<string, any>;
|
|
49
47
|
// eslint-disable-next-line no-unused-vars
|
|
50
48
|
onSubmit?: ((formData: any) => Promise<void>);
|
|
51
49
|
// eslint-disable-next-line no-unused-vars
|
|
@@ -61,10 +59,9 @@ const computedFormSchema = $computed(() => {
|
|
|
61
59
|
|
|
62
60
|
let isActive = $ref<boolean>(false);
|
|
63
61
|
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
};
|
|
62
|
+
const formData = defineModel<Record<string, any>>('modelValue', { default: {} });
|
|
63
|
+
|
|
64
|
+
const emit = defineEmits(['update:isModalVisible']);
|
|
68
65
|
|
|
69
66
|
const closeModal = () => {
|
|
70
67
|
isActive = false;
|
|
@@ -73,9 +70,11 @@ const closeModal = () => {
|
|
|
73
70
|
}, 200);
|
|
74
71
|
};
|
|
75
72
|
|
|
76
|
-
|
|
73
|
+
watch(formData.value, (v) => { console.log(v); });
|
|
74
|
+
|
|
75
|
+
const runSubmit = async () => {
|
|
77
76
|
try {
|
|
78
|
-
await props.onSubmit?.(formData);
|
|
77
|
+
await props.onSubmit?.(formData.value);
|
|
79
78
|
closeModal();
|
|
80
79
|
} catch (err) {
|
|
81
80
|
console.error(err);
|
|
@@ -83,28 +82,17 @@ const runSubmit = async (formData: any) => {
|
|
|
83
82
|
};
|
|
84
83
|
|
|
85
84
|
const runDelete = () => {
|
|
86
|
-
props.onDelete?.(
|
|
85
|
+
props.onDelete?.(formData.value?.id);
|
|
87
86
|
closeModal();
|
|
88
87
|
};
|
|
89
88
|
|
|
90
89
|
const escapeKeyClose = (e: KeyboardEvent) => props?.dismissable && useEscape(e, () => closeModal());
|
|
91
90
|
|
|
92
91
|
onMounted(() => {
|
|
93
|
-
setTimeout(() =>
|
|
94
|
-
|
|
95
|
-
}, 1);
|
|
96
|
-
|
|
97
|
-
document.addEventListener(
|
|
98
|
-
'keydown',
|
|
99
|
-
escapeKeyClose,
|
|
100
|
-
);
|
|
101
|
-
});
|
|
102
|
-
onUnmounted(() => {
|
|
103
|
-
document.removeEventListener(
|
|
104
|
-
'keydown',
|
|
105
|
-
escapeKeyClose,
|
|
106
|
-
);
|
|
92
|
+
setTimeout(() => isActive = true, 1);
|
|
93
|
+
document.addEventListener('keydown', escapeKeyClose);
|
|
107
94
|
});
|
|
95
|
+
onUnmounted(() => document.removeEventListener('keydown', escapeKeyClose));
|
|
108
96
|
</script>
|
|
109
97
|
|
|
110
98
|
<style scoped>
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<div class="nav-scroll">
|
|
19
19
|
<div class="nav-links-wrapper">
|
|
20
20
|
<RouterLink
|
|
21
|
-
v-for="link in links
|
|
21
|
+
v-for="link in links"
|
|
22
22
|
class="nav-button"
|
|
23
23
|
:to="link.to"
|
|
24
24
|
:key="link.label"
|
|
@@ -27,13 +27,26 @@
|
|
|
27
27
|
{{ link.materialIcon }}
|
|
28
28
|
</div>
|
|
29
29
|
<div class="tooltip">
|
|
30
|
-
{{ link.
|
|
30
|
+
{{ link.label }}
|
|
31
31
|
</div>
|
|
32
32
|
</RouterLink>
|
|
33
33
|
</div>
|
|
34
34
|
</div>
|
|
35
35
|
|
|
36
36
|
<div class="bot-buttons-wrapper">
|
|
37
|
+
<RouterLink
|
|
38
|
+
v-for="link in footerLinks"
|
|
39
|
+
class="nav-button"
|
|
40
|
+
:to="link.to"
|
|
41
|
+
:key="link.label"
|
|
42
|
+
>
|
|
43
|
+
<div class="icon-font">
|
|
44
|
+
{{ link.materialIcon }}
|
|
45
|
+
</div>
|
|
46
|
+
<div class="tooltip">
|
|
47
|
+
{{ link.label }}
|
|
48
|
+
</div>
|
|
49
|
+
</RouterLink>
|
|
37
50
|
<slot name="floor" />
|
|
38
51
|
</div>
|
|
39
52
|
</div>
|
|
@@ -41,19 +54,20 @@
|
|
|
41
54
|
</template>
|
|
42
55
|
|
|
43
56
|
<script lang="ts" setup>
|
|
44
|
-
// import LangText from "../translation/LangText.vue"s
|
|
45
57
|
import type { MaterialIcons } from '@bagelink/vue';
|
|
46
58
|
|
|
47
59
|
const isOpen = $ref(true);
|
|
60
|
+
export type NavLink = {
|
|
61
|
+
label: string;
|
|
62
|
+
to: string;
|
|
63
|
+
materialIcon: MaterialIcons;
|
|
64
|
+
localized?: string;
|
|
65
|
+
}
|
|
48
66
|
|
|
49
67
|
withDefaults(
|
|
50
68
|
defineProps<{
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
to: string;
|
|
54
|
-
materialIcon: MaterialIcons;
|
|
55
|
-
localized?: string;
|
|
56
|
-
}[];
|
|
69
|
+
footerLinks: NavLink[];
|
|
70
|
+
links:NavLink[];
|
|
57
71
|
homeIcon?: MaterialIcons;
|
|
58
72
|
homeLabel?: string;
|
|
59
73
|
homeTo?: string;
|
|
@@ -62,6 +76,8 @@ withDefaults(
|
|
|
62
76
|
homeIcon: 'home',
|
|
63
77
|
homeLabel: 'Home',
|
|
64
78
|
homeTo: '/',
|
|
79
|
+
links: () => [],
|
|
80
|
+
footerLinks: () => [],
|
|
65
81
|
},
|
|
66
82
|
);
|
|
67
83
|
</script>
|
|
@@ -107,7 +107,7 @@ const showEditForm = () => {
|
|
|
107
107
|
.person-card {
|
|
108
108
|
border: 1.1px solid var(--border-color);
|
|
109
109
|
/* background: var(--input-bg); */
|
|
110
|
-
|
|
110
|
+
border-radius: var(--card-border-radius);
|
|
111
111
|
padding: 1rem;
|
|
112
112
|
margin-bottom: 0.5rem;
|
|
113
113
|
font-size: 1rem;
|
|
@@ -1,105 +1,105 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
<!-- :class="{ editable: editable }" -->
|
|
3
|
+
<div
|
|
4
|
+
@click="focusEditor"
|
|
5
|
+
:id="`canvas-${elementId}`"
|
|
6
|
+
@keydown.meta.enter="$emit('keydown.meta.enter')"
|
|
7
|
+
/>
|
|
8
8
|
</template>
|
|
9
9
|
|
|
10
10
|
<script setup lang="ts">
|
|
11
|
-
import { ref, onMounted, watch } from
|
|
12
|
-
import { DOMParser, DOMSerializer } from
|
|
13
|
-
import { EditorState } from
|
|
14
|
-
import { EditorView } from
|
|
15
|
-
import { keymap } from
|
|
16
|
-
import { baseKeymap } from
|
|
17
|
-
import { undo, redo, history } from
|
|
18
|
-
import { schema } from
|
|
11
|
+
import { ref, onMounted, watch } from 'vue';
|
|
12
|
+
import { DOMParser, DOMSerializer } from 'prosemirror-model';
|
|
13
|
+
import { EditorState } from 'prosemirror-state';
|
|
14
|
+
import { EditorView } from 'prosemirror-view';
|
|
15
|
+
import { keymap } from 'prosemirror-keymap';
|
|
16
|
+
import { baseKeymap } from 'prosemirror-commands';
|
|
17
|
+
import { undo, redo, history } from 'prosemirror-history';
|
|
18
|
+
import { schema } from 'prosemirror-schema-basic';
|
|
19
19
|
|
|
20
20
|
const props = withDefaults(
|
|
21
|
-
|
|
21
|
+
defineProps<{
|
|
22
22
|
elementId?: string;
|
|
23
23
|
modelValue: string;
|
|
24
24
|
}>(),
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
{
|
|
26
|
+
elementId: Math.random().toString(36).substr(2, 9),
|
|
27
|
+
modelValue: '',
|
|
28
|
+
},
|
|
29
29
|
);
|
|
30
30
|
|
|
31
|
-
const emit = defineEmits([
|
|
31
|
+
const emit = defineEmits(['update:modelValue', 'keydown.meta.enter']);
|
|
32
32
|
|
|
33
33
|
const html = ref<string>(props.modelValue);
|
|
34
34
|
let view: EditorView;
|
|
35
35
|
|
|
36
36
|
const createEditorStateFromHTML = (htmlContent: string) => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
37
|
+
let content = { type: 'doc', content: [] };
|
|
38
|
+
try {
|
|
39
|
+
const dom = document.createElement('div');
|
|
40
|
+
dom.innerHTML = htmlContent || '';
|
|
41
|
+
content = DOMParser.fromSchema(schema)
|
|
42
|
+
.parse(dom, { preserveWhitespace: true })
|
|
43
|
+
.toJSON();
|
|
44
|
+
} catch (err) {
|
|
45
|
+
content = { type: 'doc', content: [] };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const state = EditorState.create({
|
|
49
|
+
doc: DOMParser.fromSchema(schema).schema.nodeFromJSON(content),
|
|
50
|
+
plugins: [
|
|
51
|
+
history(),
|
|
52
|
+
keymap({ 'Mod-z': undo, 'Mod-y': redo }),
|
|
53
|
+
keymap(baseKeymap),
|
|
54
|
+
],
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return state;
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
function handleChange(newState: any) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
const dom = document.createElement('div');
|
|
62
|
+
const node = DOMSerializer.fromSchema(schema).serializeFragment(newState);
|
|
63
|
+
dom.appendChild(node);
|
|
64
|
+
html.value = dom?.innerHTML || '';
|
|
65
|
+
emit('update:modelValue', html.value);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
const createEditorView = (state: EditorState) => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
69
|
+
const editorDiv = document.getElementById(`canvas-${props.elementId}`);
|
|
70
|
+
view = new EditorView(editorDiv, {
|
|
71
|
+
state,
|
|
72
|
+
// editable: () => props.editable,
|
|
73
|
+
dispatchTransaction(transaction) {
|
|
74
|
+
const newState = view.state.apply(transaction);
|
|
75
|
+
handleChange(newState.doc);
|
|
76
|
+
view.updateState(newState);
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
view.setProps({
|
|
80
|
+
// editable: () => props.editable,
|
|
81
|
+
});
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
function loadContent() {
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
const state = createEditorStateFromHTML(props.modelValue);
|
|
86
|
+
createEditorView(state);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
watch(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
90
|
+
() => props.modelValue,
|
|
91
|
+
(val: string) => {
|
|
92
|
+
if (val === html.value) return;
|
|
93
|
+
const el = document.getElementById(`canvas-${props.elementId}`);
|
|
94
|
+
if (el) el.innerHTML = '';
|
|
95
|
+
loadContent();
|
|
96
|
+
},
|
|
97
97
|
);
|
|
98
98
|
|
|
99
99
|
onMounted(loadContent);
|
|
100
100
|
|
|
101
101
|
function focusEditor() {
|
|
102
|
-
|
|
102
|
+
view.focus();
|
|
103
103
|
}
|
|
104
104
|
</script>
|
|
105
105
|
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<component
|
|
3
3
|
:required="field.required"
|
|
4
|
-
v-bind="bindAttrs(field?.attrs||{},
|
|
4
|
+
v-bind="bindAttrs(field?.attrs||{}, field.id?data[field.id]:'', data)"
|
|
5
5
|
v-if="vIf"
|
|
6
6
|
:is="field.$el || 'div'"
|
|
7
7
|
:label="field.label"
|
|
8
8
|
:id="field.id"
|
|
9
9
|
:placeholder="field.placeholder || field.label"
|
|
10
|
-
:modelValue="
|
|
11
|
-
@update:modelValue="($event:any)=>
|
|
10
|
+
:modelValue="field.id?data[field.id]:''"
|
|
11
|
+
@update:modelValue="($event:any)=>updateField($event, field?.id)"
|
|
12
12
|
>
|
|
13
13
|
<BglField
|
|
14
|
-
|
|
15
|
-
@update:modelValue="($event:any)=>emits('update:modelValue', $event)"
|
|
14
|
+
v-model="data"
|
|
16
15
|
v-for="(child,ii) in field.children" :key="child.id||ii"
|
|
17
16
|
:field="child"
|
|
18
17
|
/>
|
|
@@ -23,17 +22,21 @@
|
|
|
23
22
|
import { type Field, bindAttrs } from '@bagelink/vue';
|
|
24
23
|
|
|
25
24
|
const props = defineProps<{
|
|
26
|
-
modelValue: Record<string, any>;
|
|
27
25
|
field: Field
|
|
28
26
|
}>();
|
|
29
27
|
|
|
28
|
+
const data = defineModel<Record<string, any>>('modelValue', { default: {} });
|
|
29
|
+
|
|
30
|
+
function updateField(val: any, fieldID?: string) {
|
|
31
|
+
if (!fieldID || !data.value) return;
|
|
32
|
+
data.value[fieldID] = val;
|
|
33
|
+
}
|
|
34
|
+
|
|
30
35
|
const vIf = $computed(() => {
|
|
31
36
|
if (props.field['v-if'] === undefined) return true;
|
|
32
37
|
if (typeof props.field['v-if'] === 'boolean') return props.field['v-if'];
|
|
33
|
-
if (typeof props.field['v-if'] === 'string') return !!
|
|
34
|
-
if (typeof props.field['v-if'] === 'function') return props.field['v-if']!(
|
|
38
|
+
if (typeof props.field['v-if'] === 'string') return !!data.value[props.field['v-if']];
|
|
39
|
+
if (typeof props.field['v-if'] === 'function') return props.field['v-if']!(data.value[props.field.id || ''], data.value);
|
|
35
40
|
return true;
|
|
36
41
|
});
|
|
37
|
-
|
|
38
|
-
const emits = defineEmits(['update:modelValue']);
|
|
39
42
|
</script>
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<form ref="form" @submit.prevent="runSubmit">
|
|
3
3
|
<BglField
|
|
4
|
-
v-for="(field, i) in schema" :key="field.id || `${i }p`" :field="field"
|
|
5
|
-
@update:modelValue="($event)=>updateModelValue($event, field?.id || '')"
|
|
4
|
+
v-for="(field, i) in schema" :key="field.id || `${i }p`" :field="field" v-model="data"
|
|
6
5
|
/>
|
|
7
6
|
<Btn
|
|
8
7
|
class="del-top" v-if="data?.id && onDelete" @click="runDelete" value="Delete" flat icon="delete"
|
|
@@ -33,19 +32,14 @@ const form = $ref<HTMLFormElement>();
|
|
|
33
32
|
|
|
34
33
|
const validateForm = () => form?.reportValidity?.();
|
|
35
34
|
|
|
36
|
-
const updateModelValue = (val: any, fieldID: string) => {
|
|
37
|
-
if (!fieldID || !data.value) return;
|
|
38
|
-
data.value[fieldID] = val;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
35
|
defineExpose({ validateForm });
|
|
42
36
|
|
|
43
|
-
const clearForm = () => Object.assign(data, {});
|
|
37
|
+
const clearForm = () => Object.assign(data.value, {});
|
|
44
38
|
const emits = defineEmits(['submit']);
|
|
45
39
|
|
|
46
40
|
const runSubmit = () => {
|
|
47
41
|
validateForm();
|
|
48
|
-
emits('submit', data);
|
|
42
|
+
emits('submit', data.value);
|
|
49
43
|
clearForm();
|
|
50
44
|
};
|
|
51
45
|
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
export { default as ItemRef } from './ItemRef.vue';
|
|
2
|
-
export { default as MaterialIcon } from './MaterialIcon.vue';
|
|
3
|
-
export { default as PlainInputField } from './PlainInputField.vue';
|
|
4
1
|
export { default as BglForm } from './BglForm.vue';
|
|
5
2
|
export { default as BagelForm } from './BglForm.vue';
|
|
6
3
|
export { default as BglField } from './BglField.vue';
|