Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(md-enhance): add flowchart back
- Loading branch information
1 parent
da60f1d
commit d870212
Showing
14 changed files
with
352 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { | ||
computed, | ||
defineComponent, | ||
h, | ||
onBeforeUnmount, | ||
onMounted, | ||
ref, | ||
} from "vue"; | ||
import debounce from "lodash.debounce"; | ||
import presets from "../flowchart-preset"; | ||
|
||
import type * as Flowchart from "flowchart.js"; | ||
import type { PropType, VNode } from "vue"; | ||
|
||
import "../styles/flowchart.scss"; | ||
|
||
declare const MARKDOWN_ENHANCE_DELAY: number; | ||
|
||
export default defineComponent({ | ||
name: "FlowChart", | ||
|
||
props: { | ||
id: { type: String, required: true }, | ||
preset: { | ||
type: String as PropType<"ant" | "vue">, | ||
default: "vue", | ||
}, | ||
}, | ||
|
||
setup(props) { | ||
let svg: Flowchart.Instance; | ||
let resize: () => void; | ||
const element = ref<HTMLDivElement | null>(null); | ||
|
||
const loading = ref(true); | ||
const scale = ref(1); | ||
|
||
const preset = computed<Record<string, unknown>>(() => { | ||
const preset = presets[props.preset]; | ||
|
||
if (!preset) { | ||
console.warn(`[md-enhance:flowchart] Unknown preset: ${props.preset}`); | ||
|
||
return presets.vue; | ||
} | ||
|
||
return preset; | ||
}); | ||
|
||
const getScale = (width: number): number => | ||
width < 419 ? 0.8 : width > 1280 ? 1 : 0.9; | ||
|
||
onMounted(() => { | ||
element.value?.setAttribute("id", props.id); | ||
|
||
void Promise.all([ | ||
import(/* webpackChunkName: "flowchart" */ "flowchart.js"), | ||
// delay | ||
new Promise((resolve) => setTimeout(resolve, MARKDOWN_ENHANCE_DELAY)), | ||
]).then(([flowchart]) => { | ||
const { parse } = flowchart; | ||
|
||
svg = parse(decodeURIComponent(element.value?.dataset.code || "")); | ||
|
||
// update scale | ||
scale.value = getScale(window.innerWidth); | ||
|
||
loading.value = false; | ||
|
||
// draw svg to #id | ||
svg.drawSVG(props.id, { ...preset.value, scale: scale.value }); | ||
|
||
resize = debounce(() => { | ||
const newScale = getScale(window.innerWidth); | ||
|
||
if (scale.value !== newScale) { | ||
scale.value = newScale; | ||
|
||
svg.drawSVG(props.id, { ...preset.value, scale: newScale }); | ||
} | ||
}, 100); | ||
|
||
window.addEventListener("resize", resize); | ||
}); | ||
}); | ||
|
||
onBeforeUnmount(() => { | ||
window.removeEventListener("resize", resize); | ||
}); | ||
|
||
return (): VNode => | ||
h("div", { | ||
ref: element, | ||
class: [ | ||
"flowchart-wrapper", | ||
{ | ||
loading: loading.value, | ||
innerHTML: loading.value | ||
? '<svg xmlns="http://www.w3.org/2000/svg" class="loading-icon" style="background:0 0;display:block;shape-rendering:auto" width="200" height="200" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><circle cx="50" cy="50" r="0" fill="none" stroke="currentColor" stroke-width="2"><animate attributeName="r" repeatCount="indefinite" dur="1s" values="0;40" keyTimes="0;1" keySplines="0 0.2 0.8 1" calcMode="spline" begin="0s"/><animate attributeName="opacity" repeatCount="indefinite" dur="1s" values="1;0" keyTimes="0;1" keySplines="0.2 0 0.8 1" calcMode="spline" begin="0s"/></circle><circle cx="50" cy="50" r="0" fill="none" stroke="currentColor" stroke-width="2"><animate attributeName="r" repeatCount="indefinite" dur="1s" values="0;40" keyTimes="0;1" keySplines="0 0.2 0.8 1" calcMode="spline" begin="-0.3333333333333333s"/><animate attributeName="opacity" repeatCount="indefinite" dur="1s" values="1;0" keyTimes="0;1" keySplines="0.2 0 0.8 1" calcMode="spline" begin="-0.3333333333333333s"/></circle><circle cx="50" cy="50" r="0" fill="none" stroke="currentColor" stroke-width="2"><animate attributeName="r" repeatCount="indefinite" dur="1s" values="0;40" keyTimes="0;1" keySplines="0 0.2 0.8 1" calcMode="spline" begin="-0.6666666666666666s"/><animate attributeName="opacity" repeatCount="indefinite" dur="1s" values="1;0" keyTimes="0;1" keySplines="0.2 0 0.8 1" calcMode="spline" begin="-0.6666666666666666s"/></circle></svg>' | ||
: "", | ||
}, | ||
], | ||
}); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import base from "./base"; | ||
|
||
export default { | ||
...base, | ||
...{ | ||
// style symbol types | ||
symbols: { | ||
start: { | ||
class: "start-element", | ||
"font-color": "#fff", | ||
fill: "#595959", | ||
"line-width": "0px", | ||
}, | ||
end: { | ||
class: "end-element", | ||
"font-color": "#fff", | ||
fill: "#595959", | ||
"line-width": "0px", | ||
}, | ||
operation: { | ||
class: "operation-element", | ||
"font-color": "#fff", | ||
fill: "#1890ff", | ||
"line-width": "0px", | ||
}, | ||
inputoutput: { | ||
class: "inputoutput-element", | ||
"font-color": "#fff", | ||
fill: "#1890ff", | ||
"line-width": "0px", | ||
}, | ||
subroutine: { | ||
class: "subroutine-element", | ||
"font-color": "#fff", | ||
fill: "#FF485E", | ||
"element-color": "#fff", | ||
"line-color": "red", | ||
}, | ||
condition: { | ||
class: "condition-element", | ||
"font-color": "#fff", | ||
fill: "#FF485E", | ||
"line-width": "0px", | ||
}, | ||
parallel: { | ||
class: "parallel-element", | ||
"font-color": "#fff", | ||
fill: "#1890ff", | ||
"line-width": "0px", | ||
}, | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
export default { | ||
// eslint-disable-next-line id-length | ||
x: 0, | ||
// eslint-disable-next-line id-length | ||
y: 0, | ||
"line-width": 2, | ||
"line-length": 40, | ||
"text-margin": 8, | ||
"font-size": 14, | ||
"font-color": "#8DA1AC", | ||
"line-color": "#8DA1AC", | ||
"element-color": "black", | ||
fill: "white", | ||
"yes-text": "Yes", | ||
"no-text": "No", | ||
"arrow-end": "block", | ||
scale: 1, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import ant from "./ant"; | ||
import vue from "./vue"; | ||
|
||
export default { | ||
ant, | ||
vue, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import base from "./base"; | ||
|
||
export default { | ||
...base, | ||
...{ | ||
// style symbol types | ||
symbols: { | ||
start: { | ||
class: "start-element", | ||
"font-color": "#fff", | ||
fill: "#2F495F", | ||
"line-width": "0px", | ||
}, | ||
end: { | ||
class: "end-element", | ||
"font-color": "#fff", | ||
fill: "#2F495F", | ||
"line-width": "0px", | ||
}, | ||
operation: { | ||
class: "operation-element", | ||
"font-color": "#fff", | ||
fill: "#00BC7D", | ||
"line-width": "0px", | ||
}, | ||
inputoutput: { | ||
class: "inputoutput-element", | ||
"font-color": "#fff", | ||
fill: "#EB4D5D", | ||
"line-width": "0px", | ||
}, | ||
subroutine: { | ||
class: "subroutine-element", | ||
"font-color": "#fff", | ||
fill: "#937AC4", | ||
"element-color": "#fff", | ||
"line-color": "red", | ||
}, | ||
condition: { | ||
class: "condition-element", | ||
"font-color": "#fff", | ||
fill: "#FFB500", | ||
"line-width": "0px", | ||
}, | ||
parallel: { | ||
class: "parallel-element", | ||
"font-color": "#fff", | ||
fill: "#2F495F", | ||
"line-width": "0px", | ||
}, | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
@use "@hope/config"; | ||
|
||
.flowchart-wrapper { | ||
padding: 0.6em 0.4em; | ||
transition: all 1s; | ||
text-align: center; | ||
overflow-x: scroll; | ||
|
||
&.loading { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
background: var(--grey15); | ||
} | ||
|
||
@media (max-width: config.$mobile) { | ||
margin: 0 -1.5rem; | ||
padding: 0.6em 0; | ||
} | ||
|
||
svg.loading-icon { | ||
width: 4em; | ||
height: 4em; | ||
margin: 2.5em auto; | ||
color: var(--c-brand); | ||
} | ||
} | ||
|
||
.operation-element, | ||
.parallel-element { | ||
rx: 5px; | ||
ry: 5px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* eslint-disable max-statements */ | ||
import { hash } from "@vuepress/utils"; | ||
import type Token from "markdown-it/lib/token"; | ||
|
||
import type MarkdownIt from "markdown-it"; | ||
|
||
const flowchartRender = (tokens: Token[], idx: number): string => { | ||
const token = tokens[idx]; | ||
const key = `flowchart-${hash(idx)}`; | ||
const { content, info } = token; | ||
|
||
return `<FlowChart id="${key}" data-code="${encodeURIComponent( | ||
content | ||
)}" preset="${info.trim().split(":")[1] || "vue"}"></FlowChart>`; | ||
}; | ||
|
||
export const flowchart = (md: MarkdownIt): void => { | ||
// Handle ```flow and ```flowchart blocks | ||
const fence = md.renderer.rules.fence; | ||
|
||
md.renderer.rules.fence = (...args): string => { | ||
const [tokens, idx] = args; | ||
const { info } = tokens[idx]; | ||
const realInfo = info.trim().split(":")[0]; | ||
|
||
if (realInfo === "flow" || realInfo === "flowchart") | ||
return flowchartRender(tokens, idx); | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
return fence!(...args); | ||
}; | ||
|
||
md.renderer.rules.flowchart = flowchartRender; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.