@bagelink/vue 1.2.77 → 1.2.81

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.
Files changed (30) hide show
  1. package/bin/experimentalGenTypedRoutes.ts +13 -2
  2. package/dist/components/AddressSearch.vue.d.ts.map +1 -1
  3. package/dist/components/Carousel2.vue.d.ts +89 -0
  4. package/dist/components/Carousel2.vue.d.ts.map +1 -0
  5. package/dist/components/Dropdown.vue.d.ts.map +1 -1
  6. package/dist/components/Slider.vue.d.ts +4 -3
  7. package/dist/components/Slider.vue.d.ts.map +1 -1
  8. package/dist/components/calendar/views/CalendarPopover.vue.d.ts +2 -2
  9. package/dist/components/calendar/views/CalendarPopover.vue.d.ts.map +1 -1
  10. package/dist/components/form/BagelForm.vue.d.ts +1 -0
  11. package/dist/components/form/BagelForm.vue.d.ts.map +1 -1
  12. package/dist/components/form/BglMultiStepForm.vue.d.ts +7 -4
  13. package/dist/components/form/BglMultiStepForm.vue.d.ts.map +1 -1
  14. package/dist/components/form/inputs/CodeEditor/Index.vue.d.ts +14 -6
  15. package/dist/components/form/inputs/CodeEditor/Index.vue.d.ts.map +1 -1
  16. package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
  17. package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
  18. package/dist/index.cjs +173 -143
  19. package/dist/index.mjs +173 -143
  20. package/dist/style.css +206 -176
  21. package/dist/utils/index.d.ts.map +1 -1
  22. package/package.json +1 -1
  23. package/src/components/Slider.vue +13 -11
  24. package/src/components/form/BagelForm.vue +2 -1
  25. package/src/components/form/BglMultiStepForm.vue +47 -32
  26. package/src/components/form/inputs/CodeEditor/Index.vue +160 -98
  27. package/src/components/form/inputs/RichText/index.vue +12 -11
  28. package/src/utils/index.ts +38 -13
  29. package/dist/types/timeago.d.ts +0 -23
  30. package/dist/types/timeago.d.ts.map +0 -1
@@ -7,7 +7,7 @@ type AutoplayMode = 'disabled' | 'standard' | 'linear'
7
7
  type AutoplayValue = boolean | AutoplayMode
8
8
 
9
9
  interface CarouselOptions {
10
- duration?: number
10
+ speed?: number
11
11
  easing?: Easing
12
12
  perPage?: number | { [key: number]: number }
13
13
  startIndex?: number
@@ -22,6 +22,7 @@ interface CarouselOptions {
22
22
  pauseOnHover?: boolean
23
23
  dots?: boolean
24
24
  slideWidth?: number
25
+ slideGap?: number
25
26
  onInit?: () => void
26
27
  onChange?: () => void
27
28
  }
@@ -35,7 +36,7 @@ interface DragState {
35
36
  }
36
37
 
37
38
  const props = withDefaults(defineProps<CarouselOptions>(), {
38
- duration: 200,
39
+ speed: 350,
39
40
  easing: 'ease-out',
40
41
  startIndex: 0,
41
42
  draggable: true,
@@ -44,11 +45,11 @@ const props = withDefaults(defineProps<CarouselOptions>(), {
44
45
  loop: true,
45
46
  rtl: false,
46
47
  autoplay: 'disabled',
47
- autoplayInterval: 3000,
48
- autoplaySpeed: 50,
48
+ autoplayInterval: 5000,
49
49
  pauseOnHover: true,
50
50
  dots: false,
51
51
  slideWidth: 300,
52
+ slideGap: 1
52
53
  })
53
54
 
54
55
  const emit = defineEmits<{
@@ -118,7 +119,7 @@ const config = computed<ComputedConfig>(() => {
118
119
  const calculatedPerPage = perPage.value
119
120
 
120
121
  return {
121
- duration: props.duration,
122
+ speed: props.speed,
122
123
  easing: props.easing,
123
124
  perPage: calculatedPerPage,
124
125
  startIndex: props.startIndex,
@@ -129,10 +130,11 @@ const config = computed<ComputedConfig>(() => {
129
130
  rtl: props.rtl,
130
131
  autoplay: autoplayMode,
131
132
  autoplayInterval: props.autoplayInterval,
132
- autoplaySpeed: props.autoplaySpeed,
133
+ autoplaySpeed: props.speed / 4,
133
134
  pauseOnHover: props.pauseOnHover,
134
135
  dots: props.dots,
135
136
  slideWidth: props.slideWidth,
137
+ slideGap: props.slideGap,
136
138
  onInit: () => { emit('init') },
137
139
  onChange: () => { emit('change') }
138
140
  }
@@ -343,7 +345,7 @@ function buildSliderFrameItem(elm: Element): HTMLElement {
343
345
  const elementContainer = document.createElement('div')
344
346
  elementContainer.style.cssFloat = config.value.rtl ? 'right' : 'left'
345
347
  elementContainer.style.float = config.value.rtl ? 'right' : 'left'
346
-
348
+ elementContainer.style.padding = config.value.slideGap ? `${config.value.slideGap / 2}rem` : '0'
347
349
  const percentage = config.value.loop
348
350
  ? 100 / (innerElements.value.length + (perPage.value * 2))
349
351
  : 100 / innerElements.value.length
@@ -474,8 +476,8 @@ function disableTransition(): void {
474
476
 
475
477
  function enableTransition(): void {
476
478
  if (sliderFrame.value) {
477
- sliderFrame.value.style.webkitTransition = `all ${config.value.duration}ms ${config.value.easing}`
478
- sliderFrame.value.style.transition = `all ${config.value.duration}ms ${config.value.easing}`
479
+ sliderFrame.value.style.webkitTransition = `all ${config.value.speed}ms ${config.value.easing}`
480
+ sliderFrame.value.style.transition = `all ${config.value.speed}ms ${config.value.easing}`
479
481
  }
480
482
  }
481
483
 
@@ -996,7 +998,7 @@ defineExpose({
996
998
  width: 12px;
997
999
  height: 12px;
998
1000
  border-radius: 50px;
999
- background-color: #ccc;
1001
+ background-color: var(--bgl-gray-light);
1000
1002
  border: none;
1001
1003
  padding: 0;
1002
1004
  cursor: pointer;
@@ -1004,7 +1006,7 @@ defineExpose({
1004
1006
  }
1005
1007
 
1006
1008
  .carousel-dot.active {
1007
- background-color: #333;
1009
+ background-color: var(--bgl-primary);
1008
1010
  width: 26px;
1009
1011
  }
1010
1012
  </style>
@@ -111,6 +111,7 @@ function updateFormData(fieldId: string, value: any) {
111
111
 
112
112
  // Form validation
113
113
  const validateForm = () => form.value?.reportValidity() ?? false
114
+ const checkValidity = () => form.value?.checkValidity() ?? false
114
115
  const formError = ref<Error>()
115
116
  // Form submission
116
117
  async function handleSubmit() {
@@ -156,7 +157,7 @@ function handleSlotInputChange(event: Event) {
156
157
  }
157
158
  }
158
159
 
159
- defineExpose({ form, isDirty, validateForm, resolveSchema, refreshSchema })
160
+ defineExpose({ form, isDirty, validateForm, resolveSchema, refreshSchema, checkValidity })
160
161
  </script>
161
162
 
162
163
  <template>
@@ -2,8 +2,8 @@
2
2
  import type { BglFormSchemaFnT } from '@bagelink/vue'
3
3
 
4
4
  import type { ComponentExposed, ComponentProps } from 'vue-component-type-helpers'
5
- import { BagelForm, Btn, useBglSchema } from '@bagelink/vue'
6
- import { ref, watch, computed } from 'vue'
5
+ import { BagelForm, Btn, useBglSchema, sleep } from '@bagelink/vue'
6
+ import { ref, watch, computed, nextTick } from 'vue'
7
7
 
8
8
  const props = withDefaults(
9
9
  defineProps<{
@@ -13,7 +13,7 @@ const props = withDefaults(
13
13
  'schema' | `${string}modelValue` | `ref${string}` | `onVnode${string}` | 'onSubmit'
14
14
  )
15
15
  >
16
- schema: BglFormSchemaFnT<T>
16
+ schema?: BglFormSchemaFnT<T>
17
17
  showProgress?: boolean
18
18
  rtl?: boolean
19
19
  stepLabels?: string[]
@@ -119,9 +119,6 @@ const currentStepSchema = computed(() => {
119
119
  return [computedSchema.value[actualIndex]]
120
120
  })
121
121
 
122
- const isStepping = ref(false)
123
- let isSteppingTO: NodeJS.Timeout
124
-
125
122
  // Tracks which way we're sliding (left or right)
126
123
  const slideDirection = ref(props.rtl ? 'right' : 'left')
127
124
 
@@ -138,9 +135,7 @@ watch(
138
135
  }
139
136
 
140
137
  previousStep.value = oldStep
141
- clearTimeout(isSteppingTO)
142
- isStepping.value = true
143
- isSteppingTO = setTimeout(() => (isStepping.value = false), 200)
138
+ // We don't need isStepping flag anymore
144
139
  emits('stepChange', {
145
140
  newStep,
146
141
  oldStep,
@@ -150,19 +145,32 @@ watch(
150
145
  }
151
146
  )
152
147
 
153
- const canDoNext = computed(() => currentStep.value < numberOfSteps.value - 1)
148
+ const isLastStep = computed(() => currentStep.value === numberOfSteps.value - 1)
154
149
 
155
150
  const isStepValidated = computed(() => (stepIndex: number) => validatedSteps.value.includes(stepIndex))
156
151
 
152
+ // Add a computed property to check if current step is valid
153
+ const isStepValid = ref(false)
154
+
155
+ async function checkCurrentStepValidity() {
156
+ await nextTick()
157
+ if (!props.validateOnSteps) isStepValid.value = true
158
+ else isStepValid.value = formRef.value?.checkValidity() ?? false
159
+ }
160
+
157
161
  function prevStep() {
158
162
  if (currentStep.value > 0) currentStep.value--
159
163
  }
160
164
 
161
165
  const formContainer = ref<HTMLElement>()
162
166
 
163
- function nextStep() {
167
+ async function nextStep() {
168
+ // Always use reportValidity when attempting to move to next step
169
+ // This will show validation errors to the user
164
170
  if (props.validateOnSteps && reportValidity() === false) return
165
- if (canDoNext.value) currentStep.value++
171
+ if (!isLastStep.value) currentStep.value++
172
+ await sleep(400)
173
+ checkCurrentStepValidity()
166
174
  }
167
175
 
168
176
  function goToStep(stepIndex: number) {
@@ -173,6 +181,7 @@ function goToStep(stepIndex: number) {
173
181
  }
174
182
 
175
183
  // For forward navigation to non-validated steps, validate current step first if needed
184
+ // This will show validation errors to the user
176
185
  if (props.validateOnSteps && reportValidity() === false) {
177
186
  return false
178
187
  }
@@ -187,6 +196,7 @@ function goToStep(stepIndex: number) {
187
196
  }
188
197
 
189
198
  function handleSubmit() {
199
+ // Show validation errors to the user when submitting
190
200
  if (reportValidity() === false) return
191
201
  emits('submit', formData.value)
192
202
  }
@@ -194,15 +204,11 @@ function handleSubmit() {
194
204
  function reset() {
195
205
  validatedSteps.value = []
196
206
  currentStep.value = 0
197
- // Clear form if BagelForm supports it
198
- // if (formRef.value && typeof formRef.value.clearForm === 'function') {
199
- // formRef.value.clearForm()
200
- // }
201
207
  }
202
208
 
203
209
  // Re-evaluate filtered steps when formData changes
204
210
  watch(() => formData.value, () => {
205
- // If current step index is now invalid after filtering, reset to first valid step
211
+ checkCurrentStepValidity()
206
212
  if (currentStep.value >= numberOfSteps.value && numberOfSteps.value > 0) {
207
213
  currentStep.value = 0
208
214
  }
@@ -211,11 +217,13 @@ watch(() => formData.value, () => {
211
217
  defineExpose({
212
218
  submit: handleSubmit,
213
219
  validateForm: reportValidity,
220
+ checkValidity: formRef.value?.checkValidity,
214
221
  isDirty: computed(() => formRef.value?.isDirty),
215
222
  reset,
216
223
  goToStep,
217
224
  currentStep: computed(() => currentStep.value),
218
225
  totalSteps: computed(() => numberOfSteps.value),
226
+ isStepValid,
219
227
  nextStep,
220
228
  prevStep,
221
229
  })
@@ -260,7 +268,7 @@ defineExpose({
260
268
  :name="slideDirection === 'right' ? 'slide-right' : 'slide-left'"
261
269
  mode="out-in"
262
270
  >
263
- <div v-if="!isStepping" :key="currentStep" ref="formContainer" class="bgl-form-container">
271
+ <div :key="currentStep" ref="formContainer" class="bgl-form-container">
264
272
  <BagelForm
265
273
  ref="formRef"
266
274
  v-model="formData"
@@ -286,11 +294,17 @@ defineExpose({
286
294
  submit: handleSubmit,
287
295
  currentStep,
288
296
  totalSteps: numberOfSteps,
289
- canDoNext,
297
+ isLastStep,
298
+ isStepValid,
290
299
  }"
291
300
  >
292
- <Btn v-if="currentStep !== 0" color="gray" icon="arrow_back" click="prevStep" />
293
- <Btn v-if="canDoNext" icon="arrow_forward" @click="nextStep" />
301
+ <Btn v-if="currentStep !== 0" color="gray" icon="arrow_back" @click="prevStep" />
302
+ <Btn
303
+ v-if="!isLastStep"
304
+ icon="arrow_forward"
305
+ :disabled="props.validateOnSteps && !isStepValid"
306
+ @click="nextStep"
307
+ />
294
308
  <Btn v-else value="Submit" @click="handleSubmit" />
295
309
  </slot>
296
310
  </div>
@@ -305,12 +319,10 @@ defineExpose({
305
319
  gap: 1rem;
306
320
  width: 100%;
307
321
  /* Default transition duration */
308
- --transition-duration: 200ms;
322
+ --transition-duration: 300ms;
309
323
  --move-distance: 35%;
310
- --ease-in: ease-in-out;
311
- --ease-out: ease-in-out;
312
- /* --ease-in: cubic-bezier(0.42, 0, 0.58, 1); */
313
- /* --ease-out: cubic-bezier(0.5, 0, 0.75, 0); */
324
+ --ease-in: cubic-bezier(0.42, 0, 0.58, 1);
325
+ --ease-out: cubic-bezier(0.42, 0, 0.58, 1);
314
326
  }
315
327
 
316
328
  .bgl-steps-indicator {
@@ -398,16 +410,18 @@ defineExpose({
398
410
  justify-content: center;
399
411
  gap: 1rem;
400
412
  grid-area: unset !important;
401
-
413
+ margin-top: 2rem;
402
414
  }
403
415
 
404
416
  /* Slide Left Animation (going forward) */
405
417
  .slide-left-enter-active {
406
- transition: opacity, transform calc(var(--transition-duration) * 1.2) var(--ease-in);
418
+ transition: opacity var(--transition-duration) var(--ease-in),
419
+ transform var(--transition-duration) var(--ease-in);
407
420
  }
408
421
 
409
422
  .slide-left-leave-active {
410
- transition: opacity, transform var(--transition-duration) var(--ease-out);
423
+ transition: opacity var(--transition-duration) var(--ease-out),
424
+ transform var(--transition-duration) var(--ease-out);
411
425
  }
412
426
 
413
427
  .slide-left-enter-from {
@@ -422,12 +436,13 @@ defineExpose({
422
436
 
423
437
  /* Slide Right Animation (going back) */
424
438
  .slide-right-enter-active {
425
- transition: all calc(var(--transition-duration) * 1.2) var(--ease-in);
439
+ transition: opacity var(--transition-duration) var(--ease-in),
440
+ transform var(--transition-duration) var(--ease-in);
426
441
  }
427
442
 
428
443
  .slide-right-leave-active {
429
- transition: all var(--transition-duration) var(--ease-out);
430
- transition-property: opacity, transform;
444
+ transition: opacity var(--transition-duration) var(--ease-out),
445
+ transform var(--transition-duration) var(--ease-out);
431
446
  }
432
447
 
433
448
  .slide-right-enter-from {
@@ -7,10 +7,9 @@ declare global {
7
7
  }
8
8
  }
9
9
  import { appendStyle, appendScript } from '@bagelink/vue'
10
- import { nextTick, onMounted, watch } from 'vue'
10
+ import { onMounted, ref, computed, watch } from 'vue'
11
11
 
12
- // Props
13
- const { language, readonly = false, modelValue = '', autodetect, ignoreIllegals = true, label, height = '300px' } = defineProps<{
12
+ interface CodeEditorProps {
14
13
  language?: Language
15
14
  readonly?: boolean
16
15
  modelValue?: string
@@ -18,39 +17,50 @@ const { language, readonly = false, modelValue = '', autodetect, ignoreIllegals
18
17
  ignoreIllegals?: boolean
19
18
  label?: string
20
19
  height?: string
21
- }>()
20
+ }
21
+ // Props with default values
22
+ const props = withDefaults(defineProps<CodeEditorProps>(), {
23
+ language: 'html',
24
+ readonly: false,
25
+ modelValue: '',
26
+ autodetect: true,
27
+ ignoreIllegals: true,
28
+ label: '',
29
+ height: '240px'
30
+ })
22
31
 
23
32
  const emit = defineEmits(['update:modelValue'])
33
+ // State
34
+ const code = ref(props.modelValue || '')
35
+ const editorRef = ref<HTMLDivElement>()
36
+ const loaded = ref(false)
37
+ const hljs = ref<HilightJS | null>(null)
38
+ // Computed
39
+ const maxHeight = computed(() => {
40
+ const h = props.height ?? '240px'
41
+ return h.match(/^\d+$/) ? `${h}px` : h
42
+ })
24
43
 
25
- let hljs = $ref<HilightJS | null>(null)
44
+ const formattedCode = computed(() => {
45
+ if (!hljs.value) return escapeHtml(code.value)
26
46
 
27
- let elHeight = $ref(height)
28
- // State and refs
29
- let code = $ref('')
30
- const textarea = $ref<HTMLTextAreaElement>()
31
- let loaded = $ref(false)
47
+ try {
48
+ const lang = props.language || ''
32
49
 
33
- // Computed properties
34
- const cannotDetectLanguage = $computed(() => {
35
- const lang = language || ''
36
- return !(autodetect ?? !lang) && !hljs?.getLanguage(lang)
37
- })
50
+ if (lang && !props.autodetect && !hljs.value.getLanguage(lang)) {
51
+ console.warn(`The language "${lang}" is not available.`)
52
+ return escapeHtml(code.value)
53
+ }
38
54
 
39
- const className = $computed(() => {
40
- if (cannotDetectLanguage) return ''
41
- return `hljs ${language || ''}`
42
- })
55
+ const result = props.autodetect
56
+ ? hljs.value.highlightAuto(code.value)
57
+ : hljs.value.highlight(code.value, { language: lang, ignoreIllegals: props.ignoreIllegals })
43
58
 
44
- const highlightedCode = $computed(() => {
45
- if (cannotDetectLanguage) {
46
- console.warn(`The language "${language}" you specified could not be found.`)
47
- return escapeHtml(code)
59
+ return result.value || escapeHtml(code.value)
60
+ } catch (error) {
61
+ console.error('Highlighting error:', error)
62
+ return escapeHtml(code.value)
48
63
  }
49
- const lang = language || ''
50
- const result = autodetect
51
- ? hljs?.highlightAuto(code)
52
- : hljs?.highlight(code, { language: lang, ignoreIllegals })
53
- return result?.value || ''
54
64
  })
55
65
 
56
66
  // Methods
@@ -67,113 +77,165 @@ function escapeHtml(unsafe: string) {
67
77
  })
68
78
  }
69
79
 
80
+ function handleInput(e: Event) {
81
+ const target = e.target as HTMLTextAreaElement
82
+ code.value = target.value
83
+ emit('update:modelValue', code.value)
84
+ }
85
+
70
86
  function handleTab(event: KeyboardEvent) {
87
+ if (event.key !== 'Tab') return
88
+
89
+ event.preventDefault()
71
90
  const target = event.target as HTMLTextAreaElement
72
91
  const start = target.selectionStart
73
- const tab = ' '
74
- code = code.slice(0, start) + tab + code.slice(start)
75
- nextTick(() => {
76
- target.selectionStart = target.selectionEnd = start + tab.length
77
- })
78
- }
92
+ const end = target.selectionEnd
79
93
 
80
- function adjustHeight() {
81
- if (textarea?.scrollHeight && textarea.scrollHeight > Number.parseInt(elHeight)) {
82
- elHeight = `${textarea.scrollHeight}px`
83
- }
94
+ // Add tab or indent selected text
95
+ const newValue = `${code.value.substring(0, start)} ${code.value.substring(end)}`
96
+ code.value = newValue
97
+ emit('update:modelValue', code.value)
98
+
99
+ // Move cursor position after the inserted tab
100
+ setTimeout(() => {
101
+ target.selectionStart = target.selectionEnd = start + 2
102
+ }, 0)
84
103
  }
85
104
 
86
105
  // Lifecycle
87
106
  onMounted(async () => {
88
- // Append scripts and styles for Highlight.js
89
- await appendScript('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/highlight.min.js', { id: 'hljs-cdn' })
90
- await appendStyle('https://cdn.jsdelivr.net/npm/highlight.js/styles/atom-one-dark.min.css')
91
-
92
- // Initialize hljs
93
- if (window.hljs) {
94
- hljs = window.hljs as HilightJS
95
- loaded = true
96
- } else {
97
- console.error('Highlight.js failed to load.')
107
+ try {
108
+ // Load highlight.js
109
+ await appendScript('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/highlight.min.js', { id: 'hljs-cdn' })
110
+ await appendStyle('https://cdn.jsdelivr.net/npm/highlight.js/styles/atom-one-dark.min.css')
111
+
112
+ if (window.hljs) {
113
+ hljs.value = window.hljs
114
+ loaded.value = true
115
+ } else {
116
+ console.error('Failed to load highlight.js')
117
+ }
118
+ } catch (error) {
119
+ console.error('Error loading highlight.js:', error)
98
120
  }
99
121
  })
100
122
 
101
- watch(() => modelValue, (newVal) => {
102
- adjustHeight()
103
- if (newVal !== code) {
104
- code = newVal
123
+ // Watch for external modelValue changes
124
+ watch(() => props.modelValue, (newVal) => {
125
+ if (newVal !== undefined && newVal !== code.value) {
126
+ code.value = newVal
105
127
  }
106
128
  }, { immediate: true })
107
129
  </script>
108
130
 
109
131
  <template>
110
- <div class="mb-05">
111
- <label v-if="label" class="label txt-start">{{ label }}</label>
112
- <div v-if="loaded" class="code-editor-wrap grid rounded p-1 overflow hm-300px ltr txt-start relative h-100p">
113
- <div class="relative block h-100" :style="{ height: `calc(${elHeight} - 2rem)` }">
114
- <pre class=" overflow-hidden absolute inset-0 p-0 m-0 h-100 codeText">
115
- <code class="absolute inset-0" :class="className" v-html="highlightedCode" />
116
- </pre>
132
+ <div class="code-editor-container ltr" :style="{ maxHeight }">
133
+ <label v-if="label" class="label">{{ label }}</label>
134
+ <div
135
+ v-if="loaded"
136
+ ref="editorRef"
137
+ class="code-editor-grandpa"
138
+ >
139
+ <div class="editor-content-papa relative">
140
+ <pre class="code-display" wrap><code v-html="formattedCode" /></pre>
117
141
  <textarea
118
142
  v-if="!readonly"
119
- ref="textarea"
120
- v-model="code"
121
- class="code-editor absolute inset-0 bg-transparent overflow-hidden h-100 p-0 m-0 codeText border-none txt-start"
143
+ :value="code"
144
+ class="code-input"
122
145
  spellcheck="false"
123
- placeholder="Write your code here"
124
- aria-label="Code Editor"
125
- data-gramm="false"
126
- @keydown.tab.prevent="handleTab"
127
- @input="emit('update:modelValue', code)"
146
+ autocomplete="off"
147
+ autocorrect="off"
148
+ autocapitalize="off"
149
+ @input="handleInput"
150
+ @keydown="handleTab"
128
151
  />
129
152
  </div>
130
153
  </div>
131
154
  </div>
132
155
  </template>
133
156
 
134
- <style>
135
- pre code.hljs{
136
- padding: 0 !important;
137
- inset: 0 !important;
138
- position: absolute;
157
+ <style scoped>
158
+ .code-editor-container {
159
+ margin-bottom: 0.5rem;
160
+ height: 100%;
139
161
  }
140
- </style>
141
162
 
142
- <style scoped>
143
- .codeText{
144
- font-family: monospace;
145
- white-space: pre-wrap;
146
- word-wrap: break-word;
147
- caret-color: var(--bgl-white);
148
- color: var(--bgl-white);
163
+ .label {
164
+ display: block;
165
+ text-align: left;
166
+ margin-bottom: 0.25rem;
149
167
  }
150
- .code-editor-wrap {
151
- background: #282c34;
152
- height: max-content;
168
+
169
+ .code-editor-grandpa {
170
+ background: #22252A;
171
+ border-radius: 0.25rem;
172
+ width: 100%;
173
+ height: 100%;
174
+ overflow: auto;
175
+ padding: 1ch;
176
+ padding-inline-start: 2ch;
153
177
  }
154
- .code-editor-wrap:focus-within, .code-editor-wrap:focus-visible, .code-editor-wrap:focus {
155
- box-shadow: inset 0 0 10px #00000021;
156
- outline: solid 1px var(--border-color);
157
- /* outline: -webkit-focus-ring-color auto 1px; */
158
178
 
179
+ .code-editor-grandpa:focus-within {
180
+ outline: solid 1px var(--border-color, #4f575f);
181
+ box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.13);
159
182
  }
160
183
 
161
- .code-editor-wrap:focus-within:has(textarea:focus) + .label,
162
- .label:has(+ .code-editor-wrap:focus-within) {
163
- color: var(--bgl-primary) !important;
184
+ .editor-content-papa {
185
+ position: relative;
186
+ width: 100%;
187
+ padding-bottom: calc(100% - 5lh);
188
+ }
189
+ .code-display,
190
+ .code-input {
191
+ inset: 0;
192
+ margin: 0;
193
+ padding: 0;
194
+ width: 100%;
195
+ height: 100%;
196
+ overflow: auto;
197
+ font-family: monospace;
198
+ font-size: 1em;
199
+ line-height: 1.5;
200
+ tab-size: 2;
201
+ word-break: keep-all;
202
+ text-align: left;
164
203
  }
165
204
 
166
- .code-editor {
167
- color: transparent;
168
- resize: none;
205
+ .code-display {
206
+ position: relative;
207
+ color: #fff;
208
+ pointer-events: none;
209
+ z-index: 1;
169
210
  }
170
211
 
171
- .code-editor::selection {
172
- background: #2466bc30;
173
- color: inherit;
212
+ .code-display code {
213
+ display: block;
214
+ background: transparent !important;
215
+ padding: 0 !important;
174
216
  }
175
217
 
176
- .code-editor:focus {
177
- outline: none;
218
+ .code-input {
219
+ position: absolute;
220
+ background: transparent;
221
+ color: transparent;
222
+ caret-color: #fff;
223
+ border: none;
224
+ resize: none;
225
+ outline: none;
226
+ z-index: 2;
227
+ }
228
+
229
+ .code-input::selection {
230
+ background-color: rgba(36, 102, 188, 0.3);
231
+ color: transparent;
232
+ }
233
+ </style>
234
+
235
+ <style>
236
+ /* Global styles */
237
+ pre code.hljs {
238
+ padding: 0 !important;
239
+ background: transparent !important;
178
240
  }
179
241
  </style>