mirror of
https://github.com/System-End/scraps.git
synced 2026-04-19 19:45:14 +00:00
add in markdown
This commit is contained in:
parent
62a983f00d
commit
ad001bd9ad
7 changed files with 152 additions and 5 deletions
|
|
@ -7,6 +7,7 @@
|
|||
"dependencies": {
|
||||
"@lucide/svelte": "^0.563.1",
|
||||
"better-auth": "^1.4.18",
|
||||
"marked": "^17.0.3",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/compat": "^2.0.2",
|
||||
|
|
@ -463,6 +464,8 @@
|
|||
|
||||
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
||||
|
||||
"marked": ["marked@17.0.3", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-jt1v2ObpyOKR8p4XaUJVk3YWRJ5n+i4+rjQopxvV32rSndTJXvIzuUdWWIy/1pFQMkQmvTXawzDNqOH/CUmx6A=="],
|
||||
|
||||
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
||||
|
||||
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
"type": "module",
|
||||
"dependencies": {
|
||||
"@lucide/svelte": "^0.563.1",
|
||||
"better-auth": "^1.4.18"
|
||||
"better-auth": "^1.4.18",
|
||||
"marked": "^17.0.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
139
frontend/src/lib/components/Markdown.svelte
Normal file
139
frontend/src/lib/components/Markdown.svelte
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
<script lang="ts">
|
||||
import { Marked } from 'marked';
|
||||
|
||||
interface Props {
|
||||
content: string;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
let { content, class: className = '' }: Props = $props();
|
||||
|
||||
const marked = new Marked({
|
||||
breaks: true,
|
||||
gfm: true
|
||||
});
|
||||
|
||||
const renderer = {
|
||||
link({ text }: { href: string; text: string }) {
|
||||
return text;
|
||||
},
|
||||
image() {
|
||||
return '';
|
||||
},
|
||||
html() {
|
||||
return '';
|
||||
},
|
||||
checkbox() {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
marked.use({ renderer });
|
||||
|
||||
function render(text: string): string {
|
||||
const result = marked.parse(text);
|
||||
if (typeof result !== 'string') return text;
|
||||
return result;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="markdown {className}">
|
||||
{@html render(content)}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.markdown :global(h1) {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.markdown :global(h2) {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.markdown :global(h3) {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.markdown :global(h4) {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.markdown :global(h5),
|
||||
.markdown :global(h6) {
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.markdown :global(p) {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.markdown :global(p:last-child) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.markdown :global(strong) {
|
||||
font-weight: 700;
|
||||
}
|
||||
.markdown :global(em) {
|
||||
font-style: italic;
|
||||
}
|
||||
.markdown :global(del) {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
.markdown :global(code) {
|
||||
font-family: monospace;
|
||||
background-color: #f3f4f6;
|
||||
padding: 0.125rem 0.25rem;
|
||||
border-radius: 0.25rem;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
.markdown :global(pre) {
|
||||
background-color: #f3f4f6;
|
||||
padding: 0.75rem;
|
||||
border-radius: 0.5rem;
|
||||
overflow-x: auto;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.markdown :global(pre code) {
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
.markdown :global(blockquote) {
|
||||
border-left: 3px solid #d1d5db;
|
||||
padding-left: 0.75rem;
|
||||
color: #6b7280;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.markdown :global(ul) {
|
||||
list-style-type: disc;
|
||||
padding-left: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.markdown :global(ol) {
|
||||
list-style-type: decimal;
|
||||
padding-left: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.markdown :global(li) {
|
||||
margin-bottom: 0.125rem;
|
||||
}
|
||||
.markdown :global(hr) {
|
||||
border: none;
|
||||
border-top: 1px solid #d1d5db;
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
.markdown :global(a) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
.markdown :global(img) {
|
||||
display: none;
|
||||
}
|
||||
.markdown :global(table) {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
Lock
|
||||
} from '@lucide/svelte';
|
||||
import ProjectPlaceholder from '$lib/components/ProjectPlaceholder.svelte';
|
||||
import Markdown from '$lib/components/Markdown.svelte';
|
||||
import { getUser } from '$lib/auth-client';
|
||||
import { API_URL } from '$lib/config';
|
||||
import { formatHours } from '$lib/utils';
|
||||
|
|
@ -410,7 +411,7 @@
|
|||
{statusTag.label}
|
||||
</span>
|
||||
</div>
|
||||
<p class="mb-4 text-gray-600">{project.description}</p>
|
||||
<Markdown content={project.description} class="mb-4 text-gray-600" />
|
||||
{#if project.updateDescription}
|
||||
<div class="mb-4 rounded-lg border-2 border-dashed border-gray-400 bg-gray-50 p-4">
|
||||
<p class="mb-1 flex items-center gap-1.5 text-sm font-bold text-gray-600">
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
Lock
|
||||
} from '@lucide/svelte';
|
||||
import ProjectPlaceholder from '$lib/components/ProjectPlaceholder.svelte';
|
||||
import Markdown from '$lib/components/Markdown.svelte';
|
||||
import { getUser } from '$lib/auth-client';
|
||||
import { API_URL } from '$lib/config';
|
||||
import { formatHours } from '$lib/utils';
|
||||
|
|
@ -289,7 +290,7 @@
|
|||
pending approval
|
||||
</span>
|
||||
</div>
|
||||
<p class="mb-4 text-gray-600">{project.description}</p>
|
||||
<Markdown content={project.description} class="mb-4 text-gray-600" />
|
||||
{#if project.updateDescription}
|
||||
<div class="mb-4 rounded-lg border-2 border-dashed border-gray-400 bg-gray-50 p-4">
|
||||
<p class="mb-1 flex items-center gap-1.5 text-sm font-bold text-gray-600">
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
import { API_URL } from '$lib/config';
|
||||
import { formatHours } from '$lib/utils';
|
||||
import ProjectPlaceholder from '$lib/components/ProjectPlaceholder.svelte';
|
||||
import Markdown from '$lib/components/Markdown.svelte';
|
||||
import { tutorialActiveStore } from '$lib/stores';
|
||||
import { t } from '$lib/i18n';
|
||||
|
||||
|
|
@ -305,7 +306,7 @@
|
|||
</div>
|
||||
|
||||
{#if project.description}
|
||||
<p class="mb-4 text-lg text-gray-700">{project.description}</p>
|
||||
<Markdown content={project.description} class="mb-4 text-lg text-gray-700" />
|
||||
{:else}
|
||||
<p class="mb-4 text-lg text-gray-400 italic">{$t.project.noDescriptionYet}</p>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
import { formatHours } from '$lib/utils';
|
||||
import { getUser } from '$lib/auth-client';
|
||||
import ProjectPlaceholder from '$lib/components/ProjectPlaceholder.svelte';
|
||||
import Markdown from '$lib/components/Markdown.svelte';
|
||||
import { t } from '$lib/i18n';
|
||||
|
||||
let { data } = $props();
|
||||
|
|
@ -134,7 +135,7 @@
|
|||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
<p class="mb-4 text-gray-600">{project.description}</p>
|
||||
<Markdown content={project.description} class="mb-4 text-gray-600" />
|
||||
{#if project.updateDescription}
|
||||
<div class="mb-4 rounded-lg border-2 border-dashed border-gray-400 bg-gray-50 p-4">
|
||||
<p class="mb-1 flex items-center gap-1.5 text-sm font-bold text-gray-600">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue