@bagelink/vue 0.0.988 → 0.0.996

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 (56) hide show
  1. package/dist/components/Btn.vue.d.ts.map +1 -1
  2. package/dist/components/Loading.vue.d.ts +16 -0
  3. package/dist/components/Loading.vue.d.ts.map +1 -0
  4. package/dist/components/form/BglField.vue.d.ts.map +1 -1
  5. package/dist/components/form/inputs/CodeEditor/Index.vue.d.ts +6 -55
  6. package/dist/components/form/inputs/CodeEditor/Index.vue.d.ts.map +1 -1
  7. package/dist/components/form/inputs/FileUpload.vue.d.ts.map +1 -1
  8. package/dist/components/form/inputs/RichText/components/Toolbar.vue.d.ts.map +1 -1
  9. package/dist/components/form/inputs/RichText/components/gridBox.vue.d.ts +3 -7
  10. package/dist/components/form/inputs/RichText/components/gridBox.vue.d.ts.map +1 -1
  11. package/dist/components/form/inputs/RichText/composables/useEditor.d.ts.map +1 -1
  12. package/dist/components/form/inputs/RichText/config.d.ts.map +1 -1
  13. package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
  14. package/dist/components/form/inputs/RichText/utils/formatting.d.ts +1 -0
  15. package/dist/components/form/inputs/RichText/utils/formatting.d.ts.map +1 -1
  16. package/dist/components/form/inputs/RichText/utils/media.d.ts +3 -3
  17. package/dist/components/form/inputs/RichText/utils/media.d.ts.map +1 -1
  18. package/dist/components/form/inputs/RichText/utils/selection.d.ts.map +1 -1
  19. package/dist/components/form/inputs/RichText/utils/table.d.ts +2 -1
  20. package/dist/components/form/inputs/RichText/utils/table.d.ts.map +1 -1
  21. package/dist/components/index.d.ts +1 -0
  22. package/dist/components/index.d.ts.map +1 -1
  23. package/dist/components/layout/TabsNav.vue.d.ts.map +1 -1
  24. package/dist/editor-a8DSbb6P.js +4 -0
  25. package/dist/editor-xBt_vIha.cjs +4 -0
  26. package/dist/index.cjs +10525 -48629
  27. package/dist/index.mjs +10526 -48630
  28. package/dist/style.css +818 -20219
  29. package/package.json +6 -33
  30. package/src/components/Btn.vue +110 -136
  31. package/src/components/Loading.vue +177 -0
  32. package/src/components/form/BglField.vue +2 -0
  33. package/src/components/form/inputs/CodeEditor/Index.vue +88 -395
  34. package/src/components/form/inputs/CodeEditor/format.ts +2 -2
  35. package/src/components/form/inputs/FileUpload.vue +2 -1
  36. package/src/components/form/inputs/RichText/components/Toolbar.vue +1 -1
  37. package/src/components/form/inputs/RichText/components/gridBox.vue +37 -8
  38. package/src/components/form/inputs/RichText/composables/useEditor.ts +27 -7
  39. package/src/components/form/inputs/RichText/config.ts +6 -2
  40. package/src/components/form/inputs/RichText/editor.css +14 -14
  41. package/src/components/form/inputs/RichText/index.vue +12 -10
  42. package/src/components/form/inputs/RichText/richTextTypes.d.ts +2 -0
  43. package/src/components/form/inputs/RichText/utils/formatting.ts +281 -34
  44. package/src/components/form/inputs/RichText/utils/media.ts +9 -6
  45. package/src/components/form/inputs/RichText/utils/selection.ts +6 -22
  46. package/src/components/form/inputs/RichText/utils/table.ts +60 -58
  47. package/src/components/index.ts +2 -2
  48. package/src/components/layout/TabsNav.vue +1 -0
  49. package/src/styles/theme.css +256 -256
  50. package/src/components/form/inputs/CodeEditor/themes/brown-papersq.png +0 -0
  51. package/src/components/form/inputs/CodeEditor/themes/pojoaque.jpg +0 -0
  52. package/src/components/form/inputs/CodeEditor/themes/themes-base16.css +0 -12809
  53. package/src/components/form/inputs/CodeEditor/themes/themes.css +0 -6740
  54. package/src/components/formkit/FileUploader.vue +0 -406
  55. package/src/components/formkit/MiscFields.vue +0 -74
  56. package/src/components/formkit/Toggle.vue +0 -149
@@ -1,440 +1,133 @@
1
1
  <script setup lang="ts">
2
- import type { Directive } from 'vue'
3
- import { Btn, Dropdown, copyText } from '@bagelink/vue'
4
- import hljs from 'highlight.js'
5
- import { defineEmits, defineProps, nextTick, onMounted, watch } from 'vue'
6
- import { type CodeTheme, type Language, codeLanguages } from './CodeTypes'
7
- import { formatCode } from './format'
8
- import './themes/themes-base16.css'
9
- import './themes/themes.css'
10
-
11
- const {
12
- showLineNumbers = false,
13
- modelValue = '',
14
- theme = 'github-dark',
15
- tabSpaces = 2,
16
- wrap = true,
17
- readOnly = false,
18
- autofocus = false,
19
- header = true,
20
- width = '400px',
21
- height = '600px',
22
- maxWidth,
23
- minWidth,
24
- maxHeight,
25
- minHeight,
26
- borderRadius = '12px',
27
- languages = ['javascript'],
28
- displayLanguage = true,
29
- copyCode = true,
30
- fontSize = '17px',
31
- padding = '20px'
32
- } = defineProps<{
33
- showLineNumbers?: boolean
2
+ import hljsVuePlugin from '@highlightjs/vue-plugin'
3
+ import { nextTick, watch } from 'vue'
4
+ import 'highlight.js/lib/common'
5
+ import 'highlight.js/styles/atom-one-dark.css'
6
+
7
+ const { readonly = false, language, modelValue = '' } = defineProps<{
8
+ language?: string
9
+ readonly?: boolean
34
10
  modelValue?: string
35
- theme?: CodeTheme
36
- tabSpaces?: number
37
- wrap?: boolean
38
- readOnly?: boolean
39
- autofocus?: boolean
40
- header?: boolean
41
- width?: string
42
- height?: string
43
- maxWidth?: string
44
- minWidth?: string
45
- maxHeight?: string
46
- minHeight?: string
47
- borderRadius?: string
48
- languages?: Language[]
49
- displayLanguage?: boolean
50
- copyCode?: boolean
51
- fontSize?: string
52
- padding?: string
53
11
  }>()
54
12
 
55
- const emit = defineEmits(['update:modelValue', 'lang', 'content', 'textarea', 'search'])
56
-
57
- let scrollBarWidth = $ref(0)
58
- let scrollBarHeight = $ref(0)
59
- let top = $ref(0)
60
- let left = $ref(0)
61
- let currentLanguage = $ref(languages[0])
62
- let content = $ref(formatCode(modelValue, currentLanguage))
63
- let cursorPosition = $ref(0)
64
- let insertTab = $ref(false)
65
- let lineNum = $ref(0)
66
- let lineNumsWidth = $ref(0)
67
- let scrolling = $ref(false)
68
- let textareaHeight = $ref(0)
69
- const langListHeight = $ref('200px') // Define langListHeight with a default value
70
-
71
- const textarea = $ref<HTMLTextAreaElement>()
72
- const code = $ref<HTMLElement>()
73
- const lineNums = $ref<HTMLElement>()
74
-
75
- const languageClass = $computed(() => `hljs language-${currentLanguage}`)
76
- const languageTitle = $computed(() => codeLanguages[currentLanguage as Language])
77
- const tabWidth = $computed(() => ' '.repeat(tabSpaces))
78
- const scroll = $computed(() => height !== 'auto')
79
-
80
- const showLineNums = $computed(() => showLineNumbers || wrap)
13
+ let code = $ref('')
81
14
 
82
- const autoClosePairs = {
83
- '(': ')',
84
- '[': ']',
85
- '{': '}',
86
- '"': '"',
87
- '\'': '\'',
88
- '`': '`'
89
- }
90
-
91
- function updateValue(e: Event) {
92
- const target = e.target as HTMLTextAreaElement
93
- const char = target.value[target.selectionStart - 1]
94
-
95
- if (char && autoClosePairs[char as keyof typeof autoClosePairs]) {
96
- const closingChar = autoClosePairs[char as keyof typeof autoClosePairs]
97
- const cursorPos = target.selectionStart
98
- target.value = target.value.slice(0, cursorPos) + closingChar + target.value.slice(cursorPos)
99
- target.selectionStart = cursorPos
100
- target.selectionEnd = cursorPos
101
- }
102
- const cursorPos = target.selectionStart
103
- content = target.value
104
- emit('update:modelValue', content)
15
+ function tabKeyDown(event: KeyboardEvent) {
16
+ const target = event.target as HTMLTextAreaElement
17
+ const start = target.selectionStart
18
+ const end = target.selectionEnd
19
+ const tab = ' '
20
+ code = code.slice(0, start) + tab + code.slice(end)
105
21
  nextTick(() => {
106
- target.setSelectionRange(cursorPos, cursorPos)
22
+ target.selectionStart = target.selectionEnd = start + 2
107
23
  })
108
24
  }
109
25
 
110
- function changeLang(lang: Language) {
111
- currentLanguage = lang
112
- emit('lang', lang)
113
- }
26
+ const textarea = $ref<HTMLInputElement>()
27
+ let height = $ref('300px')
114
28
 
115
- function tab() {
116
- if (document.execCommand('insertText')) {
117
- document.execCommand('insertText', false, tabWidth)
118
- } else {
119
- const cursorPos = textarea?.selectionStart ?? 0
120
- content
121
- = content.substring(0, cursorPos) + tabWidth + content.substring(cursorPos)
122
- cursorPosition = cursorPos + tabWidth.length
123
- insertTab = true
124
- }
29
+ function setHeight() {
30
+ if (!textarea) return
31
+ const { scrollHeight } = textarea
32
+ height = `${scrollHeight}px`
125
33
  }
126
34
 
127
- function calcScrollDistance(e: Event) {
128
- const target = e.target as HTMLTextAreaElement
129
- code?.setAttribute('scrolling', 'true')
130
- scrolling = true
131
- top = -target.scrollTop
132
- left = -target.scrollLeft
133
- }
134
-
135
- function resizer() {
136
- const textareaResizer = new ResizeObserver((entries) => {
137
- const target = entries[0].target as HTMLElement
138
- scrollBarWidth = target.offsetWidth - target.clientWidth
139
- scrollBarHeight = target.offsetHeight - target.clientHeight
140
- textareaHeight = target.offsetHeight
141
- })
142
- if (textarea) {
143
- textareaResizer.observe(textarea)
144
- }
145
-
146
- const lineNumsResizer = new ResizeObserver((entries) => {
147
- lineNumsWidth = (entries[0].target as HTMLElement).offsetWidth
148
- })
149
- if (lineNums) {
150
- lineNumsResizer.observe(lineNums)
151
- }
152
- }
153
-
154
- function getLineNum() {
155
- const str = textarea!.value
156
- let lineNumCount = 0
157
- let position = str.indexOf('\n')
158
- while (position !== -1) {
159
- lineNumCount++
160
- position = str.indexOf('\n', position + 1)
161
- }
162
- const firstChild = lineNums!.firstChild as HTMLElement
163
- const singleLineHeight = firstChild!.offsetHeight
164
- const heightNum = Math.floor(textareaHeight / singleLineHeight) - 1
165
- lineNum = height === 'auto' ? lineNumCount : Math.max(lineNumCount, heightNum)
166
- }
167
-
168
- watch(() => modelValue, (newVal) => {
169
- if (newVal !== undefined) {
170
- content = newVal
171
- }
172
- })
173
-
174
- onMounted(() => {
175
- emit('lang', languages[0])
176
- emit('content', content)
177
- emit('textarea', textarea)
178
- resizer()
179
- })
180
-
181
- watch(() => insertTab, (newVal) => {
182
- if (newVal) {
183
- textarea!.setSelectionRange(cursorPosition, cursorPosition)
184
- insertTab = false
185
- }
186
- })
187
-
188
- watch(() => showLineNumbers, (newVal) => {
189
- if (newVal) {
190
- if (scrolling) scrolling = false
191
- else getLineNum()
192
- }
193
- })
194
-
195
- const highlight: Directive = {
196
- mounted(el, binding) {
197
- el.textContent = binding
198
- hljs.highlightElement(el)
199
- },
200
- updated(el, binding) {
201
- if (el.getAttribute('data-scrolling') === 'true') {
202
- el.setAttribute('data-scrolling', 'false')
203
- } else {
204
- el.textContent = binding
205
- hljs.highlightElement(el)
206
- }
207
- },
208
- }
209
-
210
- defineExpose({ highlight })
35
+ const Highlightjs = hljsVuePlugin.component
36
+ watch(() => code, setHeight, { immediate: true })
37
+ watch(() => modelValue, (value) => {
38
+ if (value !== code) code = value
39
+ }, { immediate: true })
211
40
  </script>
212
41
 
213
42
  <template>
214
- <div
215
- :theme="theme" class="code-editor" :class="{
216
- 'hide-header': !header,
217
- 'scroll': scroll,
218
- 'read-only': readOnly,
219
- 'wrap': wrap,
220
- }" :style="{
221
- width,
222
- height,
223
- maxWidth,
224
- minWidth,
225
- maxHeight,
226
- minHeight,
227
- }"
228
- >
229
- <div class="hljs" :style="{ borderRadius }">
230
- <div
231
- v-if="header" class="p-025 flex space-between" :class="{ border: showLineNums }"
232
- :style="{ borderRadius: `${borderRadius} ${borderRadius} 0 0` }"
233
- >
234
- <Dropdown v-if="displayLanguage" :value="languageTitle" flat thin :disabled="languages.length <= 1">
235
- <ul class="lang-list hljs" :style="{ height: langListHeight }">
236
- <li v-for="(lang, index) in languages" :key="index" @click="changeLang(lang)">
237
- {{ codeLanguages[lang] }}
238
- </li>
239
- </ul>
240
- </Dropdown>
241
- <Btn v-if="copyCode" v-tooltip.left="'Copy'" class="color-white" flat thin icon="content_copy" @click="copyText(content)" />
242
- </div>
243
- <div class="code-area" :style="{ borderRadius: header ? `0 0 ${borderRadius} ${borderRadius}` : borderRadius }">
43
+ <div class="code-editor-wrap ltr radius-1">
44
+ <div class="relative block h-100" :style="{ height }">
45
+ <div class="numbers absolute inset-0 py-1 px-05 txt16 line-height-15 overflow-hidden z-1 w50px txt-start opacity-3 color-gray">
244
46
  <div
245
- v-if="showLineNums" ref="lineNums" class="line-nums hljs" :style="{
246
- fontSize,
247
- paddingTop: header ? '10px' : padding,
248
- paddingBottom: padding,
249
- top: `${top}px`,
250
- }"
47
+ v-for="(_, index) in code.split('\n')"
48
+ :key="index"
49
+ class="number txt-end"
251
50
  >
252
- <div>1</div>
253
- <div v-for="num in lineNum" :key="num">
254
- {{ num + 1 }}
255
- </div>
256
- <div>&nbsp;</div>
51
+ {{ index + 1 }}
257
52
  </div>
258
- <textarea
259
- ref="textarea" title="textarea" :readOnly="readOnly" :style="{
260
- fontSize,
261
- padding: !header ? padding : lineNums ? `10px ${padding} ${padding}` : `0 ${padding} ${padding}`,
262
- marginLeft: showLineNums ? `${lineNumsWidth}px` : '0',
263
- width: showLineNums ? `calc(100% - ${lineNumsWidth}px)` : '100%',
264
- }" :autofocus="autofocus" spellcheck="false" :value="content"
265
- @keydown.tab.prevent.stop="tab" @scroll="calcScrollDistance" @input="updateValue"
266
- />
267
- <pre
268
- :style="{
269
- paddingRight: `${scrollBarWidth}px`,
270
- paddingBottom: `${scrollBarHeight}px`,
271
- marginLeft: showLineNums ? `${lineNumsWidth}px` : '0',
272
- width: showLineNums ? `calc(100% - ${lineNumsWidth}px)` : '100%',
273
- }"
274
- >
275
- <code
276
- ref="code"
277
- :innerHTML="hljs.highlight(content, { language: currentLanguage }).value"
278
- :class="languageClass"
279
- :style="{
280
- top: `${top}px`,
281
- left: `${left}px`,
282
- fontSize,
283
- padding: !header ? padding : lineNums ? `10px ${padding} ${padding}` : `0 ${padding} ${padding}`,
284
- }"
285
- />
286
- </pre>
287
53
  </div>
54
+ <Highlightjs
55
+ class="highlighted-code absolute inset-0"
56
+ :autodetect="!language"
57
+ :code="code"
58
+ :wrap="true"
59
+ :language="language"
60
+ />
61
+ <textarea
62
+ v-if="!readonly"
63
+ ref="textarea"
64
+ v-model="code"
65
+ :spellcheck="false"
66
+ class="code-editor absolute inset-0 overflow-hidden bg-transparent line-height-15 border-none m-0"
67
+ placeholder="Write your code here"
68
+ aria-label="Code Editor"
69
+ data-gramm="false"
70
+ @input="$emit('update:modelValue', code)"
71
+ @keydown.tab.prevent="tabKeyDown"
72
+ />
288
73
  </div>
289
74
  </div>
290
75
  </template>
291
76
 
292
77
  <style>
293
- .code-editor {
294
- position: relative;
78
+ .code-editor-wrap{
79
+ background: #282c34;
80
+ overflow: scroll;
81
+ display: grid;
82
+ max-height: 300px;
295
83
  }
296
84
 
297
- .code-editor>div {
298
- width: 100%;
299
- height: 100%;
85
+ .numbers {
86
+ font-family: monospace;
87
+ border-inline-end: 1px solid var(--bgl-gray);
300
88
  }
301
-
302
- .code-editor .code-area {
303
- position: relative;
304
- z-index: 0;
305
- text-align: left;
306
- overflow: hidden;
89
+ .number{
90
+ scale: 0.9;
307
91
  }
308
-
309
- /* Common styles for text elements */
310
- .code-editor .code-area>textarea,
311
- .code-editor .code-area>pre>code,
312
- .code-editor .line-nums>div {
313
- font-family: Consolas, Monaco, monospace;
314
- line-height: 1.5;
92
+ /* Highlight.js styles */
93
+ .highlighted-code {
94
+ white-space: pre-wrap;
95
+ word-wrap: break-word;
96
+ overflow: hidden;
97
+ margin: 0;
98
+ padding: 0;
315
99
  }
316
100
 
317
- .code-editor .code-area>textarea:focus-within {
318
- background: rgba(255, 255, 255, 0.05);
101
+ .highlighted-code code {
102
+ padding-left: 70px !important;
103
+ overflow: hidden !important;
319
104
  }
320
105
 
321
- /* Textarea styles */
322
- .code-editor .code-area>textarea {
323
- position: absolute;
324
- z-index: 1;
325
- inset: 0;
326
- box-sizing: border-box;
327
- caret-color: rgb(127, 127, 127);
106
+ /* Textarea aligned with Highlight.js */
107
+ .code-editor {
108
+ font-family: monospace;
328
109
  color: transparent;
329
- white-space: pre;
330
- word-wrap: normal;
331
- border: 0;
332
- width: 100%;
333
- height: 100%;
334
- background: none;
335
110
  resize: none;
336
- outline: none;
337
- }
338
-
339
- /* Pre and code styles */
340
- .code-editor .code-area>pre {
341
- box-sizing: border-box;
342
- position: relative;
343
- margin: 0;
344
- font-size: 0;
345
- }
346
-
347
- .code-editor .code-area>pre>code {
348
- display: block;
349
- position: relative;
350
- overflow-x: visible !important;
351
- background: none;
352
- margin: 0;
353
- box-sizing: border-box;
354
- }
355
-
356
- /* Wrap styles */
357
- .code-editor.wrap .code-area>textarea,
358
- .code-editor.wrap .code-area>pre>code {
359
111
  white-space: pre-wrap;
360
112
  word-wrap: break-word;
361
- word-break: break-all;
362
- }
113
+ caret-color: var(--bgl-white);
114
+ font-size: 16px;
115
+ padding: 1rem;
116
+ padding-left: 70px !important;
363
117
 
364
- /* Scroll styles */
365
- .code-editor.scroll .code-area {
366
- height: calc(100% - 34px);
367
118
  }
368
119
 
369
- .code-editor.hide-header.scroll .code-area {
370
- height: 100%;
120
+ .code-editor::-moz-selection {
121
+ background: #2466bc30;
122
+ color: inherit;
371
123
  }
372
124
 
373
- .code-editor.scroll .code-area>textarea {
374
- overflow: auto;
125
+ .code-editor::selection {
126
+ background: #2466bc30;
127
+ color: inherit;
375
128
  }
376
129
 
377
- /* Language list styles */
378
- .code-editor .list {
379
- user-select: none;
380
- height: 100%;
381
- font-family: sans-serif;
382
- }
383
-
384
- .code-editor .list>.lang-list {
385
- border-radius: 5px;
386
- padding: 0;
387
- margin: 0;
388
- list-style: none;
389
- font-size: 13px;
390
- overflow: auto;
391
- }
392
-
393
- .code-editor .list>.lang-list>li {
394
- padding: 0 12px;
395
- line-height: 30px;
396
- white-space: nowrap;
397
- overflow: hidden;
398
- text-overflow: ellipsis;
399
- transition: background 0.16s ease;
400
- }
401
-
402
- .code-editor .list>.lang-list>li:first-child {
403
- padding-top: 5px;
404
- }
405
-
406
- .code-editor .list>.lang-list>li:last-child {
407
- padding-bottom: 5px;
408
- }
409
-
410
- .code-editor .list>.lang-list>li:hover {
411
- background: rgba(160, 160, 160, 0.4);
412
- }
413
-
414
- /* Line numbers */
415
- .code-editor .line-nums {
416
- min-width: 36px;
417
- position: absolute;
418
- left: 0;
419
- padding: 0 8px;
420
- text-align: right;
421
- opacity: 0.3;
422
- }
423
-
424
- .code-editor .line-nums::after {
425
- content: "";
426
- position: absolute;
427
- inset: 0;
428
- border-right: 1px solid currentColor;
429
- opacity: 0.5;
430
- }
431
-
432
- .code-editor .header.border::after {
433
- content: "";
434
- position: absolute;
435
- inset: auto 0 0;
436
- height: 1px;
437
- background: currentColor;
438
- opacity: 0.15;
130
+ .code-editor:focus {
131
+ outline: none;
439
132
  }
440
133
  </style>
@@ -68,8 +68,8 @@ const format = {
68
68
  continue
69
69
  }
70
70
  if (
71
- (char === ')' && nextChar === '{') ||
72
- (char === ')' && nextChar === ' ')
71
+ (char === ')' && nextChar === '{')
72
+ || (char === ')' && nextChar === ' ')
73
73
  ) {
74
74
  formatted += `${char}\n${tab.repeat(level)}`
75
75
  continue
@@ -405,7 +405,7 @@ function drop(e: DragEvent) {
405
405
  class="single-image-item-preview"
406
406
  :class="{ 'bgl_fill-image': fill }"
407
407
  >
408
- <div class="position-start m-05 flex opacity-7 z-99">
408
+ <div class="position-start m-05 flex opacity-7 z-99 gap-025">
409
409
  <Btn
410
410
  v-tooltip="'Delete'"
411
411
  color="gray"
@@ -588,6 +588,7 @@ function drop(e: DragEvent) {
588
588
  height: calc(100% - 2rem);
589
589
  object-fit: cover;
590
590
  background: var(--bgl-gray-light);
591
+ width: 90%;
591
592
  }
592
593
  .single-image-item-preview:hover::after {
593
594
  content: 'zoom_in';
@@ -32,7 +32,7 @@ function runAction(name: ToolbarConfigOption, value?: string) {
32
32
  </template>
33
33
  </Dropdown>
34
34
  <Btn
35
- v-if="action.name !== 'separator'" v-tooltip="action.label" :icon="action.icon" thin flat
35
+ v-else-if="action.name !== 'separator'" v-tooltip="action.label" :icon="action.icon" thin flat
36
36
  :aria-label="action.name" :class="[action.class, { active: selectedStyles.has(action.name) }]"
37
37
  @click="runAction(action.name)"
38
38
  />
@@ -1,22 +1,51 @@
1
1
  <script setup lang="ts">
2
- defineProps<{ gridSize: number }>()
3
2
  const emit = defineEmits(['select'])
4
- const hoveredRow = $ref(-1)
5
- const hoveredCol = $ref(-1)
3
+ const fb = 1
4
+ const base = 5
5
+ const hoveredRow = $ref(fb)
6
+ const hoveredCol = $ref(fb)
7
+
8
+ const rowSize = $computed(() => {
9
+ const enlarge = Math.min(hoveredRow + 1, 20)
10
+ return hoveredRow > (base - 1) ? enlarge : base
11
+ })
12
+ const colSize = $computed(() => {
13
+ const enlarge = Math.min(hoveredCol + 1, 20)
14
+ return hoveredCol > (base - 1) ? enlarge : base
15
+ })
6
16
  </script>
7
17
 
8
18
  <template>
9
19
  <div class="grid grid-wrap p-05">
10
20
  <div
11
- v-for="row in gridSize" :key="`row-${row}`" class="flex" @mouseout="hoveredRow = -1; hoveredCol = -1"
12
- @focusout="hoveredRow = -1; hoveredCol = -1"
21
+ v-for="row in rowSize" :key="`row-${row}`" class="flex" @mouseout="hoveredRow = fb; hoveredCol = fb"
22
+ @focusout="hoveredRow = fb; hoveredCol = fb"
13
23
  >
14
24
  <div
15
- v-for="col in 6" :key="`col-${col}`" role="button" tabindex="0" aria-label="Insert Table"
16
- :style="{ width: '20px', height: '20px' }" class="border flex pointer"
17
- :class="{ 'bg-gray-80': hoveredRow >= row && hoveredCol >= col }"
25
+ v-for="col in colSize" :key="`col-${col}`" role="button" tabindex="0" aria-label="Insert Table"
26
+ :style="{ width: '20px', height: '20px' }" class="flex pointer gap-025 tableBoxSelect"
27
+ :class="{ borderSelect: hoveredRow >= row && hoveredCol >= col }"
18
28
  @mousemove="hoveredRow = row; hoveredCol = col" @click="emit('select', `${row}x${col}`)"
19
29
  />
20
30
  </div>
31
+ <p class="txt-center txt-12 color-gray">
32
+ {{ hoveredRow }}x{{ hoveredCol }}
33
+ </p>
21
34
  </div>
22
35
  </template>
36
+
37
+ <style scoped>
38
+ .tableBoxSelect::after {
39
+ content: '';
40
+ display: block;
41
+ width: calc(100% - 4px);
42
+ height: calc(100% - 4px);
43
+ border: 1px solid var(--bgl-gray);
44
+ background: var(--bgl-gray-light);
45
+
46
+ }
47
+ .borderSelect::after {
48
+ border-color: var(--bgl-primary-tint);
49
+ background: var(--bgl-primary-light);
50
+ }
51
+ </style>