@bagelink/vue 1.5.13 โ 1.5.17
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/RouterWrapper.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/TextInput.vue.d.ts.map +1 -1
- package/dist/index.cjs +65 -55
- package/dist/index.mjs +33946 -143
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/RouterWrapper.vue +3 -3
- package/src/components/form/inputs/RichText/index.vue +167 -8
- package/src/components/form/inputs/TextInput.vue +15 -42
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import Loading from './Loading.vue'
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
5
|
<template>
|
|
6
6
|
<RouterView v-slot="{ Component, route }">
|
|
7
7
|
<slot v-if="!Component">
|
|
8
|
-
<div class="w-100p h-
|
|
9
|
-
<
|
|
8
|
+
<div class="w-100p h-100vh flex justify-content-center">
|
|
9
|
+
<Loading />
|
|
10
10
|
</div>
|
|
11
11
|
</slot>
|
|
12
12
|
<transition v-else :duration="300" name="slide-fade" mode="out-in" appear>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { ToolbarConfig } from './richTextTypes'
|
|
3
3
|
import { CodeEditor, copyText, Btn, Modal, BglVideo, Icon, Card, ColorInput } from '@bagelink/vue'
|
|
4
|
-
import { watch, onUnmounted, onBeforeUnmount, ref, computed, useAttrs } from 'vue'
|
|
4
|
+
import { watch, onUnmounted, onBeforeUnmount, onMounted, ref, computed, useAttrs } from 'vue'
|
|
5
5
|
import CheckInput from '../CheckInput.vue'
|
|
6
6
|
import NumberInput from '../NumberInput.vue'
|
|
7
7
|
import SelectInput from '../SelectInput.vue'
|
|
@@ -52,6 +52,102 @@ const editor = useEditor()
|
|
|
52
52
|
const isInitializing = ref(false)
|
|
53
53
|
const hasInitialized = ref(false)
|
|
54
54
|
const commands = useCommands(editor.state, editor.state.debug)
|
|
55
|
+
|
|
56
|
+
// Reactive theme colors with forced reactivity
|
|
57
|
+
const forceUpdate = ref(0)
|
|
58
|
+
const currentInputColor = computed(() => {
|
|
59
|
+
// Force reactivity by using forceUpdate
|
|
60
|
+
void forceUpdate.value
|
|
61
|
+
|
|
62
|
+
if (typeof document !== 'undefined') {
|
|
63
|
+
const computedStyle = getComputedStyle(document.documentElement)
|
|
64
|
+
const color = computedStyle.getPropertyValue('--input-color').trim()
|
|
65
|
+
console.log('๐จ currentInputColor computed:', color, 'forceUpdate:', forceUpdate.value)
|
|
66
|
+
return color || '#000'
|
|
67
|
+
}
|
|
68
|
+
return '#000'
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
const currentTextColor = computed(() => {
|
|
72
|
+
const inputColor = currentInputColor.value
|
|
73
|
+
const textColor = props.textColor || (inputColor && inputColor.length > 0 && inputColor !== '#000' ? inputColor : 'inherit')
|
|
74
|
+
console.log('๐จ currentTextColor computed:', textColor, 'from inputColor:', inputColor)
|
|
75
|
+
return textColor
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
// Set up theme observation with MutationObserver
|
|
79
|
+
let themeObserver: MutationObserver | null = null
|
|
80
|
+
|
|
81
|
+
onMounted(() => {
|
|
82
|
+
if (typeof document !== 'undefined') {
|
|
83
|
+
themeObserver = new MutationObserver((mutations) => {
|
|
84
|
+
let shouldUpdate = false
|
|
85
|
+
mutations.forEach((mutation) => {
|
|
86
|
+
if (mutation.type === 'attributes') {
|
|
87
|
+
const { attributeName } = mutation
|
|
88
|
+
if (attributeName === 'data-theme'
|
|
89
|
+
|| attributeName === 'class'
|
|
90
|
+
|| attributeName === 'style') {
|
|
91
|
+
shouldUpdate = true
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
if (shouldUpdate) {
|
|
97
|
+
console.log('๐ Theme change detected, forcing update')
|
|
98
|
+
forceUpdate.value++
|
|
99
|
+
|
|
100
|
+
// Also directly update iframe if initialized
|
|
101
|
+
if (hasInitialized.value) {
|
|
102
|
+
setTimeout(() => {
|
|
103
|
+
updateIframeColors()
|
|
104
|
+
}, 50)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
// Watch for attribute changes on document element
|
|
110
|
+
themeObserver.observe(document.documentElement, {
|
|
111
|
+
attributes: true,
|
|
112
|
+
attributeFilter: ['data-theme', 'class', 'style']
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
// Also watch body for theme class changes
|
|
116
|
+
if (document.body) {
|
|
117
|
+
themeObserver.observe(document.body, {
|
|
118
|
+
attributes: true,
|
|
119
|
+
attributeFilter: ['class', 'data-theme']
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
onBeforeUnmount(() => {
|
|
126
|
+
themeObserver?.disconnect()
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
// Global testing functions
|
|
130
|
+
if (typeof window !== 'undefined') {
|
|
131
|
+
(window as any).testRichTextTheme = () => {
|
|
132
|
+
console.log('๐งช Testing RichText theme:', {
|
|
133
|
+
currentInputColor: currentInputColor.value,
|
|
134
|
+
currentTextColor: currentTextColor.value,
|
|
135
|
+
hasInitialized: hasInitialized.value,
|
|
136
|
+
hasIframe: !!iframe.value,
|
|
137
|
+
cssVar: getComputedStyle(document.documentElement).getPropertyValue('--input-color')
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
if (hasInitialized.value) {
|
|
141
|
+
updateIframeColors()
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
(window as any).forceRichTextUpdate = () => {
|
|
146
|
+
console.log('๐ Forcing RichText update')
|
|
147
|
+
forceUpdate.value++
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
55
151
|
// Computed properties for UI control
|
|
56
152
|
const shouldShowToolbar = computed(() => {
|
|
57
153
|
if (props.hideToolbar) return false
|
|
@@ -2509,16 +2605,11 @@ async function initEditor() {
|
|
|
2509
2605
|
isInitializing.value = true
|
|
2510
2606
|
|
|
2511
2607
|
try {
|
|
2512
|
-
// Get the --input-color CSS variable from the parent page
|
|
2513
|
-
const computedStyle = getComputedStyle(document.documentElement)
|
|
2514
|
-
const inputColor = computedStyle.getPropertyValue('--input-color').trim()
|
|
2515
|
-
const defaultTextColor = inputColor || 'inherit'
|
|
2516
|
-
|
|
2517
2608
|
// Use basic embedded styles for better compatibility
|
|
2518
2609
|
// We copy CSS variables to the iframe so it can use them
|
|
2519
2610
|
const editorStylesContent = `
|
|
2520
2611
|
:root {
|
|
2521
|
-
--input-color: ${
|
|
2612
|
+
--input-color: ${currentInputColor.value || '#000'};
|
|
2522
2613
|
}
|
|
2523
2614
|
body {
|
|
2524
2615
|
margin: 0;
|
|
@@ -2526,11 +2617,16 @@ async function initEditor() {
|
|
|
2526
2617
|
min-height: 200px;
|
|
2527
2618
|
font-family: sans-serif !important;
|
|
2528
2619
|
line-height: 1.5;
|
|
2529
|
-
color: ${
|
|
2620
|
+
color: ${currentTextColor.value};
|
|
2530
2621
|
background: transparent;
|
|
2531
2622
|
max-width: 1060px;
|
|
2532
2623
|
margin: 0 auto;
|
|
2533
2624
|
}
|
|
2625
|
+
|
|
2626
|
+
/* Ensure all text elements inherit the theme color */
|
|
2627
|
+
p, h1, h2, h3, h4, h5, h6, div, span, li, td, th {
|
|
2628
|
+
color: inherit !important;
|
|
2629
|
+
}
|
|
2534
2630
|
table {
|
|
2535
2631
|
border-collapse: collapse;
|
|
2536
2632
|
margin-bottom: 1rem;
|
|
@@ -2823,6 +2919,11 @@ async function initEditor() {
|
|
|
2823
2919
|
}
|
|
2824
2920
|
|
|
2825
2921
|
hasInitialized.value = true
|
|
2922
|
+
|
|
2923
|
+
// Update colors after initialization
|
|
2924
|
+
setTimeout(() => {
|
|
2925
|
+
updateIframeColors()
|
|
2926
|
+
}, 100)
|
|
2826
2927
|
} catch (error) {
|
|
2827
2928
|
// Keep only this error log for debugging critical issues
|
|
2828
2929
|
console.error('Error during editor initialization:', error)
|
|
@@ -2831,6 +2932,64 @@ async function initEditor() {
|
|
|
2831
2932
|
}
|
|
2832
2933
|
}
|
|
2833
2934
|
|
|
2935
|
+
// Function to update CSS colors in the iframe
|
|
2936
|
+
function updateIframeColors() {
|
|
2937
|
+
console.log('๐ฏ updateIframeColors called', {
|
|
2938
|
+
hasIframe: !!iframe.value,
|
|
2939
|
+
hasContentDocument: !!iframe.value?.contentDocument,
|
|
2940
|
+
hasInitialized: hasInitialized.value
|
|
2941
|
+
})
|
|
2942
|
+
|
|
2943
|
+
if (!iframe.value?.contentDocument || iframe.value.contentDocument === null) {
|
|
2944
|
+
console.warn('โ No iframe or contentDocument')
|
|
2945
|
+
return
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2948
|
+
const doc = iframe.value.contentDocument
|
|
2949
|
+
let styleElement = doc.getElementById('editor-theme-styles') as HTMLStyleElement
|
|
2950
|
+
|
|
2951
|
+
if (!styleElement) {
|
|
2952
|
+
styleElement = doc.createElement('style')
|
|
2953
|
+
styleElement.id = 'editor-theme-styles'
|
|
2954
|
+
doc.head.appendChild(styleElement)
|
|
2955
|
+
console.log('โ
Created new style element')
|
|
2956
|
+
}
|
|
2957
|
+
|
|
2958
|
+
const css = `
|
|
2959
|
+
:root {
|
|
2960
|
+
--input-color: ${currentInputColor.value || '#000'};
|
|
2961
|
+
}
|
|
2962
|
+
body {
|
|
2963
|
+
color: ${currentTextColor.value} !important;
|
|
2964
|
+
}
|
|
2965
|
+
|
|
2966
|
+
/* Ensure all text elements inherit the color */
|
|
2967
|
+
p, h1, h2, h3, h4, h5, h6, div, span, li, td, th {
|
|
2968
|
+
color: inherit !important;
|
|
2969
|
+
}
|
|
2970
|
+
`
|
|
2971
|
+
|
|
2972
|
+
styleElement.textContent = css
|
|
2973
|
+
console.log('๐จ Updated iframe colors:', {
|
|
2974
|
+
inputColor: currentInputColor.value,
|
|
2975
|
+
textColor: currentTextColor.value,
|
|
2976
|
+
css: css.trim()
|
|
2977
|
+
})
|
|
2978
|
+
}
|
|
2979
|
+
|
|
2980
|
+
// Watch for theme changes and update iframe colors
|
|
2981
|
+
watch([currentInputColor, currentTextColor], (newValues, oldValues) => {
|
|
2982
|
+
console.log('๐ Colors changed:', {
|
|
2983
|
+
newValues,
|
|
2984
|
+
oldValues,
|
|
2985
|
+
hasInitialized: hasInitialized.value
|
|
2986
|
+
})
|
|
2987
|
+
|
|
2988
|
+
if (hasInitialized.value) {
|
|
2989
|
+
updateIframeColors()
|
|
2990
|
+
}
|
|
2991
|
+
}, { flush: 'post' })
|
|
2992
|
+
|
|
2834
2993
|
// Reset initialization state when content changes significantly
|
|
2835
2994
|
watch(() => props.modelValue, (newValue, oldValue) => {
|
|
2836
2995
|
if (newValue !== editor.state.content) {
|
|
@@ -72,7 +72,7 @@ function autoResizeTextarea() {
|
|
|
72
72
|
|
|
73
73
|
const textarea = input as HTMLTextAreaElement
|
|
74
74
|
textarea.style.height = 'auto'
|
|
75
|
-
textarea.style.height =
|
|
75
|
+
textarea.style.height = `${textarea.scrollHeight + 1}px`
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
function updateInputVal() {
|
|
@@ -81,17 +81,17 @@ function updateInputVal() {
|
|
|
81
81
|
debouncedEmit()
|
|
82
82
|
|
|
83
83
|
if (props.autoheight) {
|
|
84
|
-
nextTick(() => autoResizeTextarea())
|
|
84
|
+
nextTick(() => { autoResizeTextarea() })
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
watch(
|
|
89
89
|
() => props.modelValue,
|
|
90
|
-
newVal => {
|
|
90
|
+
(newVal) => {
|
|
91
91
|
if (newVal !== inputVal) {
|
|
92
92
|
inputVal = newVal
|
|
93
93
|
if (props.autoheight) {
|
|
94
|
-
nextTick(() => autoResizeTextarea())
|
|
94
|
+
nextTick(() => { autoResizeTextarea() })
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
},
|
|
@@ -119,55 +119,27 @@ onMounted(async () => {
|
|
|
119
119
|
|
|
120
120
|
<template>
|
|
121
121
|
<div
|
|
122
|
-
class="bagel-input text-input"
|
|
123
|
-
:class="{
|
|
122
|
+
class="bagel-input text-input" :class="{
|
|
124
123
|
dense,
|
|
125
124
|
small,
|
|
126
125
|
shrink,
|
|
127
126
|
code,
|
|
128
127
|
textInputIconWrap: icon,
|
|
129
128
|
txtInputIconStart: iconStart,
|
|
130
|
-
}"
|
|
131
|
-
:title="title"
|
|
129
|
+
}" :title="title"
|
|
132
130
|
>
|
|
133
131
|
<label :for="id">
|
|
134
132
|
{{ label }} <span v-if="required && label">*</span>
|
|
135
133
|
|
|
136
134
|
<input
|
|
137
|
-
v-if="!multiline && !autoheight && !code && inputRows < 2"
|
|
138
|
-
:
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
:name
|
|
142
|
-
:title
|
|
143
|
-
:autocomplete
|
|
144
|
-
:type
|
|
145
|
-
:rows="1"
|
|
146
|
-
:placeholder="placeholder || label"
|
|
147
|
-
:disabled
|
|
148
|
-
:required
|
|
149
|
-
:pattern
|
|
150
|
-
v-bind="nativeInputAttrs"
|
|
151
|
-
@focusout="onFocusout"
|
|
152
|
-
@focus="onFocus"
|
|
153
|
-
@input="updateInputVal"
|
|
154
|
-
/>
|
|
135
|
+
v-if="!multiline && !autoheight && !code && inputRows < 2" :id ref="input" v-model.trim="inputVal"
|
|
136
|
+
:name :title :autocomplete :type :rows="1" :placeholder="placeholder || label" :disabled :required
|
|
137
|
+
:pattern v-bind="nativeInputAttrs" @focusout="onFocusout" @focus="onFocus" @input="updateInputVal"
|
|
138
|
+
>
|
|
155
139
|
<textarea
|
|
156
|
-
v-else
|
|
157
|
-
:
|
|
158
|
-
|
|
159
|
-
v-model="inputVal"
|
|
160
|
-
:name
|
|
161
|
-
:title
|
|
162
|
-
:type
|
|
163
|
-
:rows="inputRows"
|
|
164
|
-
:placeholder="placeholder || label"
|
|
165
|
-
:disabled
|
|
166
|
-
:required
|
|
167
|
-
:pattern
|
|
168
|
-
v-bind="nativeInputAttrs"
|
|
169
|
-
@input="updateInputVal"
|
|
170
|
-
@focusout="onFocusout"
|
|
140
|
+
v-else :id ref="input" v-model="inputVal" :name :title :type :rows="inputRows"
|
|
141
|
+
:placeholder="placeholder || label" :disabled :required :pattern v-bind="nativeInputAttrs"
|
|
142
|
+
@input="updateInputVal" @focusout="onFocusout"
|
|
171
143
|
/>
|
|
172
144
|
<p v-if="helptext" class="opacity-7 light">{{ helptext }}</p>
|
|
173
145
|
<Icon v-if="iconStart" class="iconStart" :icon="iconStart" />
|
|
@@ -236,7 +208,8 @@ onMounted(async () => {
|
|
|
236
208
|
line-height: 0;
|
|
237
209
|
}
|
|
238
210
|
|
|
239
|
-
.textInputIconWrap input
|
|
211
|
+
.textInputIconWrap input,
|
|
212
|
+
.textInputIconWrap textarea {
|
|
240
213
|
padding-inline-end: calc(var(--input-height) / 3 + 1.5rem);
|
|
241
214
|
}
|
|
242
215
|
|