Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Clark Lin
vue-utility
Commits
1a530b08
Commit
1a530b08
authored
Jul 28, 2025
by
Clark Lin
Browse files
Optimized TextToMermaid. Migrated partial vuetified elements to TextToMarkdown.
parent
ca404669
Changes
2
Show whitespace changes
Inline
Side-by-side
src/components/TextToMarkdown.vue
View file @
1a530b08
<
template
>
<div
class=
"text-to-markdown"
>
<h1
class=
"page-title"
>
Text to Markdown Converter
</h1>
<div
class=
"converter-container"
>
<v-container
fluid
class=
"text-to-markdown"
>
<v-row>
<v-col
cols=
"12"
>
<h1
class=
"text-h4 text-center font-weight-bold mx-3 my-3"
>
Text to Markdown Converter
</h1>
</v-col>
</v-row>
<v-divider
:thickness=
"1"
color=
"white"
class=
"border-opacity-100"
></v-divider>
<v-row
class=
"mx-3 my-3"
>
<!-- Input Section -->
<div
class=
"input-section"
>
<h3>
Input Text
</h3>
<textarea
<v-col
cols=
"12"
md=
"4"
class=
"pa-3"
>
<v-card
elevation=
"2"
class=
"input-card"
>
<v-card-title
class=
"card-title"
>
Input Text
</v-card-title>
<v-card-text>
<v-textarea
v-model=
"inputText"
@
input=
"handleInput"
placeholder=
"Enter your text here to convert to Markdown preview..."
class=
"text-input
"
variant=
"outlined
"
rows=
"10"
></textarea>
class=
"text-input"
></v-textarea>
<div
class=
"button-group"
>
<button
@
click=
"convertNow"
class=
"convert-btn"
:disabled=
"isProcessing"
>
{{
isProcessing
?
'
Converting...
'
:
'
Convert Now
'
}}
</button>
<button
@
click=
"clearAll"
class=
"clear-btn"
>
Clear All
</button>
<v-btn
@
click=
"convertNow"
:loading=
"isProcessing"
color=
"primary"
class=
"convert-btn"
>
Convert Now
</v-btn>
<v-btn
@
click=
"clearAll"
variant=
"outlined"
color=
"secondary"
>
Clear All
</v-btn>
</div>
<!-- Status Indicator -->
<div
class=
"status"
:class=
"currentState"
>
<span
v-if=
"currentState === 'typing'"
>
Typing...
</span>
<span
v-else-if=
"currentState === 'processing'"
>
Converting...
</span>
<span
v-else-if=
"currentState === 'ready'"
>
Ready
</span>
<span
v-else-if=
"currentState === 'error'"
>
Error occurred
</span>
</div>
</div>
<v-alert
:type=
"alertType"
:icon=
"alertIcon"
variant=
"tonal"
density=
"compact"
class=
"my-2"
>
{{
statusText
}}
</v-alert>
</v-card-text>
</v-card>
</v-col>
<!-- Output Section -->
<
div
class=
"output-section
"
>
<
v-col
cols=
"12"
md=
"8"
class=
"pa-3
"
>
<h3>
Markdown Preview
</h3>
<!-- Preview Section -->
...
...
@@ -75,6 +95,21 @@
</div>
</div>
<!-- Generated Markdown Section -->
<div
class=
"code-section"
>
<div
class=
"diagram-header"
>
<h4>
Generated Markdown:
</h4>
<div
class=
"diagram-controls"
>
<button
@
click=
"copyToClipboard"
class=
"copy-btn"
:disabled=
"!markdownCode"
>
{{
copyButtonText
}}
</button>
</div>
</div>
<div
class=
"code-container"
>
<pre><code>
{{
markdownCode
||
'
Your generated markdown will appear here...
'
}}
</code></pre>
</div>
</div>
<!-- Fullscreen Modal -->
<div
v-if=
"isFullscreen"
class=
"fullscreen-modal"
@
click=
"closeFullscreen"
>
<div
class=
"modal-content"
@
click.stop
>
...
...
@@ -137,9 +172,9 @@
</div>
<!-- Generated Markdown Section -->
</
div
>
</
div
>
</
div
>
</
v-col
>
</
v-row
>
</
v-container
>
</
template
>
<
script
setup
>
...
...
@@ -163,6 +198,9 @@ const isDragging = ref(false)
const
dragStart
=
ref
({
x
:
0
,
y
:
0
})
const
dragOffset
=
ref
({
x
:
0
,
y
:
0
})
// Copy button state
const
copyButtonText
=
ref
(
'
Copy to Clipboard
'
)
let
debounceTimeout
=
null
// Debounced conversion logic
...
...
@@ -246,6 +284,36 @@ const clearAll = () => {
currentState
.
value
=
'
ready
'
}
const
alertType
=
computed
(()
=>
{
switch
(
currentState
.
value
)
{
case
'
error
'
:
return
'
error
'
case
'
processing
'
:
return
'
info
'
case
'
ready
'
:
return
'
success
'
case
'
typing
'
:
return
'
warning
'
default
:
return
'
info
'
}
})
const
alertIcon
=
computed
(()
=>
{
switch
(
currentState
.
value
)
{
case
'
error
'
:
return
'
mdi-alert-circle
'
case
'
processing
'
:
return
'
mdi-progress-clock
'
case
'
ready
'
:
return
'
mdi-check-circle
'
case
'
typing
'
:
return
'
mdi-pencil
'
default
:
return
'
mdi-information
'
}
})
const
statusText
=
computed
(()
=>
{
switch
(
currentState
.
value
)
{
case
'
typing
'
:
return
'
Typing...
'
case
'
processing
'
:
return
'
Converting...
'
case
'
ready
'
:
return
'
Ready
'
case
'
error
'
:
return
'
Error occurred
'
default
:
return
'
Ready
'
}
})
// Rendered Markdown (computed for v-html)
const
renderedMarkdown
=
computed
(()
=>
{
return
markdownCode
.
value
?
marked
.
parse
(
markdownCode
.
value
)
:
''
...
...
@@ -349,6 +417,25 @@ const downloadPreview = async () => {
}
}
// Copy to clipboard function
const
copyToClipboard
=
async
()
=>
{
if
(
!
markdownCode
.
value
)
return
try
{
await
navigator
.
clipboard
.
writeText
(
markdownCode
.
value
)
copyButtonText
.
value
=
'
Copied!
'
setTimeout
(()
=>
{
copyButtonText
.
value
=
'
Copy to Clipboard
'
},
2000
)
}
catch
(
err
)
{
console
.
error
(
'
Failed to copy:
'
,
err
)
copyButtonText
.
value
=
'
Copy Failed
'
setTimeout
(()
=>
{
copyButtonText
.
value
=
'
Copy to Clipboard
'
},
2000
)
}
}
// Mount/unmount
onMounted
(()
=>
{
document
.
addEventListener
(
'
keydown
'
,
handleKeydown
)
...
...
@@ -360,13 +447,10 @@ onUnmounted(() => {
<
style
scoped
>
.text-to-markdown
{
/* max-width: 2400px; */
display
:
grid
;
grid-template-rows
:
1
fr
;
background
:
linear-gradient
(
135deg
,
#667eea
0%
,
#764ba2
100%
);
margin
:
10px
;
padding
:
0
;
font-family
:
'Segoe UI'
,
Tahoma
,
Geneva
,
Verdana
,
sans-serif
;
height
:
100%
;
}
.converter-container
{
display
:
grid
;
...
...
@@ -430,11 +514,38 @@ onUnmounted(() => {
.status
{
margin-top
:
10px
;
font-size
:
14px
;
padding
:
8px
12px
;
border-radius
:
4px
;
font-weight
:
500
;
display
:
inline-block
;
min-width
:
100px
;
text-align
:
center
;
}
.status.typing
{
background-color
:
#e2f0ff
;
color
:
#007bff
;
border
:
1px
solid
#b8daff
;
}
.status.typing
{
color
:
#888
;
}
.status.processing
{
color
:
#007bff
;
}
.status.ready
{
color
:
#28a745
;
}
.status.error
{
color
:
#dc3545
;
}
.status.processing
{
background-color
:
#fff3cd
;
color
:
#856404
;
border
:
1px
solid
#ffeaa7
;
}
.status.ready
{
background-color
:
#d4edda
;
color
:
#155724
;
border
:
1px
solid
#c3e6cb
;
}
.status.error
{
background-color
:
#f8d7da
;
color
:
#721c24
;
border
:
1px
solid
#f5c6cb
;
}
/* Diagram Section (now first) */
.diagram-section
{
background
:
#f8f9fa
;
...
...
@@ -1143,18 +1254,6 @@ onUnmounted(() => {
gap: 80px;
}
} */
.page-title
{
font-size
:
2.4rem
;
/* Larger, more prominent */
font-weight
:
700
;
/* Bold */
letter-spacing
:
1px
;
text-align
:
center
;
line-height
:
1.2
;
/* Optional: add a subtle shadow for depth */
text-shadow
:
0
2px
8px
rgba
(
76
,
110
,
245
,
0.08
);
/* Optional: add a divider line below */
border-bottom
:
1px
solid
black
;
padding-bottom
:
12px
;
}
/* Markdown content styles */
.markdown-preview
,
...
...
src/components/TextToMermaid.vue
View file @
1a530b08
...
...
@@ -10,47 +10,41 @@
<v-divider
:thickness=
"1"
color=
"white"
class=
"border-opacity-100"
></v-divider>
<!--
<div
class=
"converter-container"
>
-->
<v-row
class=
"mx-3 my-3"
>
<v-col
cols=
"12"
md=
"4"
class=
"pa-3"
>
<!-- Input Section -->
<div
class=
"input-section"
>
<v-col
cols=
"12"
md=
"4"
class=
"pa-3"
>
<!--
<div
class=
"input-section"
>
-->
<v-card
elevation=
"2"
class=
"input-card"
>
<!--
<h3>
Input Text
</h3>
-->
<v-card-title
class=
"text-h6 pa-0"
>
Input Text
</v-card-title>
<v-card-title
class=
"card-title"
>
Input Text
</v-card-title>
<v-card-text>
<v-textarea
v-model=
"inputText"
@
input=
"handleInput"
placeholder=
"Enter your text here to convert to Mermaid diagram..."
class=
"text-input"
variant=
"outlined"
rows=
"10"
></v-textarea>
<div
class=
"button-group"
>
<!--
<button
@
click=
"convertNow"
class=
"convert-btn"
:disabled=
"isProcessing"
>
{{
isProcessing
?
'
Converting...
'
:
'
Convert Now
'
}}
</button>
-->
<v-btn
@
click=
"convertNow"
:loading=
"isProcessing"
:disabled=
"isProcessing"
color=
"primary"
variant=
"flat"
>
class=
"convert-btn"
>
Convert Now
</v-btn>
<!--
<button
@
click=
"clearAll"
class=
"clear-btn"
>
Clear All
</button>
-->
<v-btn
@
click=
"clearAll"
variant=
"outlined"
color=
"secondary"
variant=
"outlined"
>
>
Clear All
</v-btn>
</div>
<!-- Status Indicator -->
<!--
<div
class=
"status"
:class=
"currentState"
>
<span
v-if=
"currentState === 'typing'"
>
Typing...
</span>
<span
v-else-if=
"currentState === 'processing'"
>
Converting...
</span>
<span
v-else-if=
"currentState === 'ready'"
>
Ready
</span>
<span
v-else-if=
"currentState === 'error'"
>
Error occurred
</span>
</div>
-->
<v-alert
:type=
"alertType"
:icon=
"alertIcon"
variant=
"tonal"
...
...
@@ -58,18 +52,18 @@
class=
"my-2"
>
{{
statusText
}}
</v-alert>
</div>
</v-card-text>
</v-card>
</v-col>
<v-col
cols=
"12"
md=
"8"
class=
"pa-3"
>
<!-- Output Section -->
<div
class=
"output-section"
>
<div
elevation=
"2"
class=
"output-section"
>
<!--
<h3>
Mermaid Diagram
</h3>
-->
<v-card-title
class=
"text-h6 pa-0"
>
Mermaid Diagram
</v-card-title>
<v-card-title
class=
"text-h6 pa-0
ma-2
"
>
Mermaid Diagram
</v-card-title>
<!-- Diagram Section -->
<v-card
class=
"diagram-section mb-4"
>
<v-card-text
class=
"pa-0"
>
<v-card-text>
<div
class=
"diagram-header"
>
<!--
<h4>
Visual Diagram:
</h4>
-->
<v-card-subtitle
class=
"text-subtitle-1 pa-0"
>
Visual Diagram:
</v-card-subtitle>
...
...
@@ -125,7 +119,6 @@
</div>
</div>
</v-card-text>
</v-card>
<!-- Fullscreen Modal -->
<div
v-if=
"isFullscreen"
class=
"fullscreen-modal"
@
click=
"closeFullscreen"
>
...
...
@@ -663,15 +656,10 @@
gap: 40px;
margin: 40px;
} */
.input-section
,
.output-section
{
background
:
#f8f9fa
;
padding
:
20px
;
border-radius
:
8px
;
border
:
1px
solid
#e9ecef
;
}
.output-section
{
/*
background: #f8f9fa;
*/
padding
:
20px
;
background
:
#f8f9fa
;
/*
padding: 20px;
*/
border-radius
:
8px
;
border
:
1px
solid
#e9ecef
;
max-width
:
100%
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment