feat: markdown (#345)

This commit is contained in:
Jason Rasmussen
2025-10-28 14:24:59 -04:00
committed by GitHub
parent 0533548064
commit 9f43d0d480
317 changed files with 4186 additions and 5454 deletions
+3 -3
View File
@@ -29,16 +29,16 @@ jobs:
uses: immich-app/devtools/actions/use-mise@697a75e2c3186d3c037c2c159855cf2d566542ba # use-mise-action-0.0.1
- name: Run npm install
run: npm ci
run: pnpm -r install
- name: Run build
run: npm run build
run: pnpm build
- name: Upload build output
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: build-output
path: build
path: packages/ui/build
retention-days: 1
deploy:
+3 -3
View File
@@ -23,10 +23,10 @@ jobs:
uses: immich-app/devtools/actions/use-mise@697a75e2c3186d3c037c2c159855cf2d566542ba # use-mise-action-0.0.1
- name: Install
run: npm ci
run: pnpm -r install
- name: Build
run: npm run build
run: pnpm build
- name: Publish
run: npm publish
run: pnpm -r publish --no-git-checks
+3 -3
View File
@@ -21,14 +21,14 @@ jobs:
uses: immich-app/devtools/actions/use-mise@697a75e2c3186d3c037c2c159855cf2d566542ba # use-mise-action-0.0.1
- name: Run npm install
run: npm ci
run: pnpm -r install
- name: Run linter
run: npm run lint
run: pnpm -r lint
if: ${{ !cancelled() }}
- name: Run formatter
run: npm run format
run: pnpm -r format
if: ${{ !cancelled() }}
- name: Run check
+3 -3
View File
@@ -4,9 +4,9 @@ node_modules
# Output
.output
.vercel
/.svelte-kit
/build
/dist
.svelte-kit/
build/
dist/
# OS
.DS_Store
+2
View File
@@ -3,4 +3,6 @@ package-lock.json
pnpm-lock.yaml
yarn.lock
src/lib/assets
dist/
CHANGELOG.md
.svelte-kit/
+2 -1
View File
@@ -1,3 +1,4 @@
{
".": "0.39.2"
"package/ui": "0.39.2",
"package/svelte-markdown-preprocess": "0.0.0"
}
+1 -1
View File
@@ -30,6 +30,6 @@ export default ts.config(
},
},
{
ignores: ['build/', '.svelte-kit/', 'dist/'],
ignores: ['packages/**/build/', 'packages/**/.svelte-kit/', 'packages/**/dist/'],
},
);
+1
View File
@@ -1,3 +1,4 @@
[tools]
npm = "11.6.2"
node = "22.20"
pnpm = "10.19.0"
-5195
View File
File diff suppressed because it is too large Load Diff
+33 -72
View File
@@ -1,85 +1,46 @@
{
"name": "@immich/ui",
"version": "0.39.2",
"license": "GNU Affero General Public License version 3",
"name": "immich-monorepo",
"version": "0.0.1",
"description": "monorepo for immich and friends",
"private": true,
"type": "module",
"packageManager": "pnpm@10.19.0",
"engines": {
"pnpm": ">=10.0.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/immich-app/ui.git"
},
"scripts": {
"create": "node scripts/create.js",
"start": "npm run start:dev",
"start:dev": "vite dev",
"watch": "vite build --watch",
"build": "vite build && npm run package",
"preview": "vite preview",
"package": "npm run sync && svelte-package && publint",
"check": "npm run sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "npm run sync && svelte-check --tsconfig ./tsconfig.json --watch",
"build": "pnpm -r --filter=./packages/* build",
"lint": "eslint . --max-warnings 0",
"lint:fix": "npm run lint -- --fix",
"lint:fix": "pnpm lint -- --fix",
"format": "prettier --check .",
"format:fix": "prettier --write .",
"test": "vitest",
"sync": "svelte-kit sync"
},
"files": [
"dist",
"!dist/**/*.test.*",
"!dist/**/*.spec.*"
],
"sideEffects": [
"**/*.css"
],
"svelte": "./dist/index.js",
"types": "./dist/index.d.ts",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"svelte": "./dist/index.js"
},
"./theme/default.css": "./dist/theme/default.css"
},
"peerDependencies": {
"svelte": "^5.0.0"
"check": "pnpm --filter @immich/svelte-markdown-preprocess build && pnpm -r check",
"test": "pnpm -r --filter=./packages/* test",
"changeset:version": "changeset version && pnpm -r generate:version && git add --all",
"changeset:publish": "changeset publish",
"bench": "node --allow-natives-syntax ./benchmarking/run.js",
"bench:compare": "node --allow-natives-syntax ./benchmarking/compare/index.js",
"bench:debug": "node --allow-natives-syntax --inspect-brk ./benchmarking/run.js"
},
"devDependencies": {
"@sveltejs/adapter-static": "^3.0.6",
"@sveltejs/kit": "^2.13.0",
"@sveltejs/package": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^6.0.0",
"@tailwindcss/postcss": "^4.1.7",
"@tailwindcss/vite": "^4.1.7",
"@types/eslint": "^9.6.0",
"@types/luxon": "^3.7.1",
"autoprefixer": "^10.4.20",
"eslint": "^9.7.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-svelte": "^3.9.3",
"globals": "^16.0.0",
"prettier": "^3.3.2",
"prettier-plugin-svelte": "^3.2.6",
"prettier-plugin-tailwindcss": "^0.7.0",
"publint": "^0.3.0",
"svelte": "^5.37.0",
"svelte-check": "^4.0.0",
"tailwindcss": "^4.1.7",
"typescript": "^5.0.0",
"typescript-eslint": "^8.34.1",
"vite": "^7.0.0",
"vitest": "^3.0.0"
},
"dependencies": {
"svelte-highlight": "^7.8.4",
"@mdi/js": "^7.4.47",
"bits-ui": "^2.9.8",
"luxon": "^3.7.2",
"simple-icons": "^15.14.0",
"tailwind-merge": "^3.0.0",
"tailwind-variants": "^3.0.0"
},
"volta": {
"node": "22.20.0"
"@eslint/js": "^9.38.0",
"@sveltejs/eslint-config": "^8.3.4",
"@types/eslint": "^9.6.1",
"acorn": "latest",
"eslint": "^9.38.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-svelte": "^3.12.5",
"globals": "^16.4.0",
"prettier": "^3.6.2",
"prettier-plugin-svelte": "^3.4.0",
"prettier-plugin-tailwindcss": "^0.7.1",
"svelte": "^5.42.3",
"typescript": "^5.9.3",
"typescript-eslint": "^8.46.2",
"vitest": "^3.2.4"
}
}
@@ -0,0 +1,2 @@
src/
tsconfig.json
@@ -0,0 +1,5 @@
# Changelog
## 0.0.0 (2025-10-27)
Initial commit
@@ -0,0 +1,43 @@
{
"name": "@immich/svelte-markdown-preprocess",
"version": "0.0.0",
"license": "GNU Affero General Public License version 3",
"repository": {
"type": "git",
"url": "git+https://github.com/immich-app/ui.git",
"directory": "packages/svelte-markdown-preprocess"
},
"scripts": {
"start": "npm run start:dev",
"build": "tsc --project ./tsconfig.json",
"check": "tsc --project ./tsconfig.json --noEmit",
"check:watch": "tsc --project ./tsconfig.json --noEmit --watch",
"lint": "eslint . --max-warnings 0",
"lint:fix": "npm run lint -- --fix",
"format": "prettier --check .",
"format:fix": "prettier --write ."
},
"files": [
"dist",
"!dist/**/*.test.*",
"!dist/**/*.spec.*"
],
"types": "./dist/index.d.ts",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
},
"peerDependencies": {
"svelte": "^5.0.0"
},
"devDependencies": {
"front-matter": "^4.0.2",
"marked": "^16.4.1"
},
"volta": {
"node": "22.20.0"
}
}
@@ -0,0 +1,61 @@
import fm from 'front-matter';
import type { PreprocessorGroup } from 'svelte/compiler';
import { md } from './markdown.js';
import { SvelteFile } from './svelte-file.js';
type Layouts = Record<string, string>;
type Options = { layouts?: Layouts };
const resolveLayout = (layout?: string, layouts?: Layouts) => {
if (layout && layouts) {
return layouts[layout];
}
};
const SCRIPT_BODY_REGEX = /<script.*>(?<body>(.|\n)*?)<\/script>/;
const parse = (content: string) => {
let scriptBody = '';
const match = SCRIPT_BODY_REGEX.exec(content);
const bodyGroup = match?.groups?.body;
if (bodyGroup) {
scriptBody = bodyGroup.trim();
content = content.substring(match.index + match[0].length).trim();
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
const { attributes, body } = fm(content);
return { attributes, body, scriptBody };
};
export const svelteMarkdownPreprocess = (options: Options): PreprocessorGroup => {
const { layouts } = options || {};
return {
name: 'immich-markdown',
async markup({ content, filename }) {
if (!filename?.endsWith('.md')) {
return;
}
const { attributes, body, scriptBody } = parse(content);
const file = new SvelteFile();
file.addScript(`import { Markdown } from '@immich/ui';`);
const layout = resolveLayout(attributes.layout, layouts);
if (layout) {
file.addScript(`import Layout from '${layout}';`);
file.addTag(`<Layout>`, '</Layout>');
}
file.addScript(scriptBody);
file.addTemplate(await md.parse(body));
return { code: file.export() };
},
};
};
@@ -0,0 +1,78 @@
import { Marked } from 'marked';
export const md = new Marked().use({
tokenizer: {
code(src) {
if (src.startsWith(' ')) {
return false;
}
},
},
renderer: {
heading({ tokens, depth }) {
const text = this.parser.parseInline(tokens);
let id = text
.toLowerCase()
.replace(/<[^>]*>/g, '')
.replace(/[^a-z1-9 ]/g, '')
.replace(/\s+/g, '-');
if (id.endsWith('-')) {
id = id.slice(0, -1);
}
switch (depth) {
case 1:
case 2:
case 3:
case 4:
case 5:
case 6: {
return `<Markdown.Heading id="${id}" level={${depth}}>${text}</Markdown.Heading>\n`;
}
}
return `<Markdown.Paragraph>${text}</Markdown.Paragraph>\n`;
},
list({ items, ordered, start }) {
const startAttribute = start && start !== 1 ? ` start={${start}}` : '';
let output = '';
output += `<Markdown.List ordered={${ordered}}${startAttribute}>\n`;
for (const item of items) {
const content = this.parser.parse(item.tokens);
const attributes = [item.task && 'task', item.checked && 'checked'].filter(Boolean);
output += ` <Markdown.ListItem ${attributes.join(' ')}>${content}</Markdown.ListItem>`;
}
output += `</Markdown.List>\n`;
return output;
},
blockquote({ tokens }) {
const children = this.parser.parse(tokens);
return `<Markdown.BlockQuote>${children}</Markdown.BlockQuote>\n`;
},
paragraph({ tokens }) {
const children = this.parser.parseInline(tokens);
return `<Markdown.Paragraph>${children}</Markdown.Paragraph>\n`;
},
code({ text, lang }) {
return `<Markdown.Code lang="${lang}" code={\`${text}\`} multiline />\n`;
},
codespan({ text }) {
return `<Markdown.Code code={\`${text}\`} />\n`;
},
hr() {
return `<Markdown.LineBreak />\n`;
},
link({ href, title, text }) {
return `<Markdown.Link href="${href}" title="${title ?? ''}">${text}</Markdown.Link>\n`;
},
},
});
@@ -0,0 +1,42 @@
export class SvelteFile {
private scripts: string[] = [];
private lines: string[] = [];
private closingTags: string[] = [];
addScript(line: string) {
if (line) {
this.scripts.push(line);
}
return this;
}
addTemplate(line: string) {
this.lines.push(line);
return this;
}
addTag(tag: string, closingTag: string) {
this.lines.push(tag);
this.closingTags.push(closingTag);
}
export() {
const lines: string[] = [];
lines.push(`<script lang="ts">`);
for (const line of this.scripts) {
lines.push(' ' + line);
}
lines.push('</script>');
for (const line of this.lines) {
lines.push(line);
}
for (const line of this.closingTags.toReversed()) {
lines.push(line);
}
return lines.join('\n');
}
}
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"declaration": true,
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": false,
"strict": true,
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "./dist"
}
}
+65 -46
View File
@@ -24,9 +24,10 @@
<!-- Release notes generated using configuration in .github/release.yml at main -->
## What's Changed
### 🌟 Enhancements
* feat(toast): default titles by @jrasm91 in https://github.com/immich-app/ui/pull/336
### 🌟 Enhancements
- feat(toast): default titles by @jrasm91 in https://github.com/immich-app/ui/pull/336
**Full Changelog**: https://github.com/immich-app/ui/compare/v0.38.0...v0.39.0
@@ -35,11 +36,14 @@
<!-- Release notes generated using configuration in .github/release.yml at main -->
## What's Changed
### 🚀 Features
* feat: toast by @jrasm91 in https://github.com/immich-app/ui/pull/331
### 🐛 Bug fixes
* fix: close button color by @jrasm91 in https://github.com/immich-app/ui/pull/335
### 🚀 Features
- feat: toast by @jrasm91 in https://github.com/immich-app/ui/pull/331
### 🐛 Bug fixes
- fix: close button color by @jrasm91 in https://github.com/immich-app/ui/pull/335
**Full Changelog**: https://github.com/immich-app/ui/compare/v0.37.1...v0.38.0
@@ -48,9 +52,10 @@
<!-- Release notes generated using configuration in .github/release.yml at main -->
## What's Changed
### 🐛 Bug fixes
* fix: map empty string to undefined in number inputs by @jrasm91 in https://github.com/immich-app/ui/pull/330
### 🐛 Bug fixes
- fix: map empty string to undefined in number inputs by @jrasm91 in https://github.com/immich-app/ui/pull/330
**Full Changelog**: https://github.com/immich-app/ui/compare/v0.37.0...v0.37.1
@@ -59,12 +64,15 @@
<!-- Release notes generated using configuration in .github/release.yml at main -->
## What's Changed
### 🚀 Features
* feat: number input by @jrasm91 in https://github.com/immich-app/ui/pull/323
### 🌟 Enhancements
* feat: auto-expire announcements by @jrasm91 in https://github.com/immich-app/ui/pull/322
* chore: tweak announcement banner background by @alextran1502 in https://github.com/immich-app/ui/pull/324
### 🚀 Features
- feat: number input by @jrasm91 in https://github.com/immich-app/ui/pull/323
### 🌟 Enhancements
- feat: auto-expire announcements by @jrasm91 in https://github.com/immich-app/ui/pull/322
- chore: tweak announcement banner background by @alextran1502 in https://github.com/immich-app/ui/pull/324
**Full Changelog**: https://github.com/immich-app/ui/compare/v0.36.4...v0.37.0
@@ -73,9 +81,10 @@
<!-- Release notes generated using configuration in .github/release.yml at main -->
## What's Changed
### 🐛 Bug fixes
* fix: npm version by @jrasm91 in https://github.com/immich-app/ui/pull/318
### 🐛 Bug fixes
- fix: npm version by @jrasm91 in https://github.com/immich-app/ui/pull/318
**Full Changelog**: https://github.com/immich-app/ui/compare/v0.36.3...v0.36.4
@@ -84,9 +93,10 @@
<!-- Release notes generated using configuration in .github/release.yml at main -->
## What's Changed
### 🐛 Bug fixes
* fix: publish workflow by @jrasm91 in https://github.com/immich-app/ui/pull/316
### 🐛 Bug fixes
- fix: publish workflow by @jrasm91 in https://github.com/immich-app/ui/pull/316
**Full Changelog**: https://github.com/immich-app/ui/compare/v0.36.2...v0.36.3
@@ -94,8 +104,6 @@
<!-- Release notes generated using configuration in .github/release.yml at main -->
**Full Changelog**: https://github.com/immich-app/ui/compare/v0.36.1...v0.36.2
## 0.36.1 (2025-10-16)
@@ -103,11 +111,14 @@
<!-- Release notes generated using configuration in .github/release.yml at main -->
## What's Changed
### 🌟 Enhancements
* chore: npm trusted publisher by @jrasm91 in https://github.com/immich-app/ui/pull/312
- chore: npm trusted publisher by @jrasm91 in https://github.com/immich-app/ui/pull/312
## New Contributors
* @sacrosanctic made their first contribution in https://github.com/immich-app/ui/pull/311
- @sacrosanctic made their first contribution in https://github.com/immich-app/ui/pull/311
**Full Changelog**: https://github.com/immich-app/ui/compare/v0.36.0...v0.36.1
@@ -116,15 +127,20 @@
<!-- Release notes generated using configuration in .github/release.yml at main -->
## What's Changed
### 🚀 Features
* feat: announcement bar by @jrasm91 in https://github.com/immich-app/ui/pull/306
### 🌟 Enhancements
* chore: footer style tweak by @alextran1502 in https://github.com/immich-app/ui/pull/304
* fix: simpler footer by @jrasm91 in https://github.com/immich-app/ui/pull/309
### 🐛 Bug fixes
* fix: z-index by @jrasm91 in https://github.com/immich-app/ui/pull/307
* fix: site-footer by @jrasm91 in https://github.com/immich-app/ui/pull/308
### 🚀 Features
- feat: announcement bar by @jrasm91 in https://github.com/immich-app/ui/pull/306
### 🌟 Enhancements
- chore: footer style tweak by @alextran1502 in https://github.com/immich-app/ui/pull/304
- fix: simpler footer by @jrasm91 in https://github.com/immich-app/ui/pull/309
### 🐛 Bug fixes
- fix: z-index by @jrasm91 in https://github.com/immich-app/ui/pull/307
- fix: site-footer by @jrasm91 in https://github.com/immich-app/ui/pull/308
**Full Changelog**: https://github.com/immich-app/ui/compare/v0.35.0...v0.36.0
@@ -133,9 +149,10 @@
<!-- Release notes generated using configuration in .github/release.yml at main -->
## What's Changed
### 🚀 Features
* feat: expose openCount on ModalManager by @midzelis in https://github.com/immich-app/ui/pull/301
### 🚀 Features
- feat: expose openCount on ModalManager by @midzelis in https://github.com/immich-app/ui/pull/301
**Full Changelog**: https://github.com/immich-app/ui/compare/v0.34.2...v0.35.0
@@ -144,9 +161,10 @@
<!-- Release notes generated using configuration in .github/release.yml at main -->
## What's Changed
### 🐛 Bug fixes
* fix: move svelte-hightlight from dev to actual dependency by @midzelis in https://github.com/immich-app/ui/pull/299
### 🐛 Bug fixes
- fix: move svelte-hightlight from dev to actual dependency by @midzelis in https://github.com/immich-app/ui/pull/299
**Full Changelog**: https://github.com/immich-app/ui/compare/v0.34.1...v0.34.2
@@ -154,9 +172,9 @@
<!-- Release notes generated using configuration in .github/release.yml at main -->
## New Contributors
* @midzelis made their first contribution in https://github.com/immich-app/ui/pull/297
- @midzelis made their first contribution in https://github.com/immich-app/ui/pull/297
**Full Changelog**: https://github.com/immich-app/ui/compare/v0.34.0...v0.34.1
@@ -165,25 +183,26 @@
<!-- Release notes generated using configuration in .github/release.yml at main -->
## What's Changed
### 🌟 Enhancements
* feat: site metadata article by @jrasm91 in https://github.com/immich-app/ui/pull/296
### 🐛 Bug fixes
* fix: site metadata by @jrasm91 in https://github.com/immich-app/ui/pull/295
### 🌟 Enhancements
- feat: site metadata article by @jrasm91 in https://github.com/immich-app/ui/pull/296
### 🐛 Bug fixes
- fix: site metadata by @jrasm91 in https://github.com/immich-app/ui/pull/295
**Full Changelog**: https://github.com/immich-app/ui/compare/v0.33.0...v0.34.0
## [0.33.0](https://github.com/immich-app/ui/compare/v0.32.0...v0.33.0) (2025-09-30)
### Features
* default release type ([#291](https://github.com/immich-app/ui/issues/291)) ([52d8d7e](https://github.com/immich-app/ui/commit/52d8d7e24e092ba44ed4557204dcbfe8fe6175c0))
* prerender ([#288](https://github.com/immich-app/ui/issues/288)) ([cc85216](https://github.com/immich-app/ui/commit/cc8521625dad0eb2c07204f8730f4d4dad477abb))
* release tag name ([9bac06b](https://github.com/immich-app/ui/commit/9bac06b4fb5e238c09a9a42f3ee5bd7511c03b5f))
- default release type ([#291](https://github.com/immich-app/ui/issues/291)) ([52d8d7e](https://github.com/immich-app/ui/commit/52d8d7e24e092ba44ed4557204dcbfe8fe6175c0))
- prerender ([#288](https://github.com/immich-app/ui/issues/288)) ([cc85216](https://github.com/immich-app/ui/commit/cc8521625dad0eb2c07204f8730f4d4dad477abb))
- release tag name ([9bac06b](https://github.com/immich-app/ui/commit/9bac06b4fb5e238c09a9a42f3ee5bd7511c03b5f))
### Bug Fixes
* release tag name ([#292](https://github.com/immich-app/ui/issues/292)) ([9bac06b](https://github.com/immich-app/ui/commit/9bac06b4fb5e238c09a9a42f3ee5bd7511c03b5f))
* set bootstrap-sha for release-please ([#286](https://github.com/immich-app/ui/issues/286)) ([8536088](https://github.com/immich-app/ui/commit/8536088e8bae2f1ceb5daa86f9bf6d436371ac7c))
- release tag name ([#292](https://github.com/immich-app/ui/issues/292)) ([9bac06b](https://github.com/immich-app/ui/commit/9bac06b4fb5e238c09a9a42f3ee5bd7511c03b5f))
- set bootstrap-sha for release-please ([#286](https://github.com/immich-app/ui/issues/286)) ([8536088](https://github.com/immich-app/ui/commit/8536088e8bae2f1ceb5daa86f9bf6d436371ac7c))
+75
View File
@@ -0,0 +1,75 @@
{
"name": "@immich/ui",
"version": "0.39.2",
"license": "GNU Affero General Public License version 3",
"repository": {
"type": "git",
"url": "git+https://github.com/immich-app/ui.git",
"directory": "packages/ui"
},
"scripts": {
"create": "node scripts/create.js",
"start": "npm run start:dev",
"start:dev": "vite dev",
"watch": "vite build --watch",
"build": "vite build && pnpm package",
"preview": "vite preview",
"package": "npm run sync && svelte-package && publint",
"check": "npm run sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "npm run sync && svelte-check --tsconfig ./tsconfig.json --watch",
"test": "vitest",
"sync": "svelte-kit sync"
},
"files": [
"dist",
"!dist/**/*.test.*",
"!dist/**/*.spec.*"
],
"sideEffects": [
"**/*.css"
],
"svelte": "./dist/index.js",
"types": "./dist/index.d.ts",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"svelte": "./dist/index.js"
},
"./theme/default.css": "./dist/theme/default.css"
},
"peerDependencies": {
"svelte": "^5.0.0"
},
"devDependencies": {
"@sveltejs/adapter-static": "^3.0.6",
"@sveltejs/kit": "^2.13.0",
"@sveltejs/package": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^6.0.0",
"@tailwindcss/postcss": "^4.1.7",
"@tailwindcss/vite": "^4.1.7",
"@types/luxon": "^3.7.1",
"autoprefixer": "^10.4.20",
"globals": "^16.0.0",
"publint": "^0.3.0",
"svelte": "^5.37.0",
"svelte-check": "^4.0.0",
"tailwindcss": "^4.1.7",
"typescript": "^5.0.0",
"vite": "^7.0.0",
"vitest": "^3.0.0"
},
"dependencies": {
"@immich/svelte-markdown-preprocess": "workspace:^",
"@mdi/js": "^7.4.47",
"bits-ui": "^2.9.8",
"luxon": "^3.7.2",
"simple-icons": "^15.14.0",
"svelte-highlight": "^7.8.4",
"tailwind-merge": "^3.0.0",
"tailwind-variants": "^3.0.0"
},
"volta": {
"node": "22.20.0"
}
}
View File
@@ -32,6 +32,7 @@ import {
mdiImage,
mdiImageOutline,
mdiKeyboardVariant,
mdiLanguageMarkdownOutline,
mdiLink,
mdiListBox,
mdiListBoxOutline,
@@ -128,8 +129,9 @@ export const componentGroups = [
title: 'Miscellaneous',
components: [
{ name: 'Avatar', icon: mdiAccountCircleOutline, activeIcon: mdiAccountCircle },
{ name: 'Logo', icon: mdiImageOutline, activeIcon: mdiImage },
{ name: 'CommandPalette', icon: mdiMenu, activeIcon: mdiMenu },
{ name: 'Logo', icon: mdiImageOutline, activeIcon: mdiImage },
{ name: 'Markdown', icon: mdiLanguageMarkdownOutline, activeIcon: mdiLanguageMarkdownOutline },
{ name: 'SupporterBadge', icon: mdiPartyPopper },
{ name: 'ThemeSwitcher', icon: mdiThemeLightDark },
],

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

@@ -0,0 +1,12 @@
<script lang="ts">
import Text from '$lib/components/Text/Text.svelte';
import type { Snippet } from 'svelte';
type Props = {
children: Snippet;
};
const { children }: Props = $props();
</script>
<Text {children} class="border-muted border-s-4 ps-4" variant="italic" />
@@ -0,0 +1,41 @@
<script lang="ts">
import Code from '$lib/components/Code/Code.svelte';
import CodeBlock from '$lib/components/CodeBlock/CodeBlock.svelte';
import * as languages from 'svelte-highlight/languages';
type Props = {
code: string;
multiline?: boolean;
lang?: string;
};
const { code, lang, multiline }: Props = $props();
const getLanguage = (lang: string | undefined) => {
switch (lang) {
case 'js': {
lang = 'javascript';
break;
}
case 'ts': {
lang = 'typescript';
break;
}
}
if (lang) {
return languages[lang as keyof typeof languages];
}
};
let language = $derived(getLanguage(lang) ?? languages.plaintext);
</script>
{#if multiline}
<div class="mt-2 mb-2">
<CodeBlock {code} {language} />
</div>
{:else}
<Code>{code}</Code>
{/if}
@@ -0,0 +1,45 @@
<script lang="ts">
import Heading from '$lib/components/Heading/Heading.svelte';
import type { HeadingTag, Size } from '$lib/types.js';
import type { Snippet } from 'svelte';
type Props = {
id?: string;
level?: number;
children: Snippet;
};
const { children, id, level }: Props = $props();
const getSizeAndTag = (level?: number): { size: Size; tag: HeadingTag } => {
switch (level) {
case 1: {
return { size: 'giant', tag: 'h1' };
}
case 2: {
return { size: 'large', tag: 'h2' };
}
case 3: {
return { size: 'medium', tag: 'h3' };
}
case 4: {
return { size: 'small', tag: 'h4' };
}
case 5: {
return { size: 'tiny', tag: 'h5' };
}
case 6: {
return { size: 'tiny', tag: 'h6' };
}
default: {
return { size: 'tiny', tag: 'p' };
}
}
};
let { size, tag } = $derived(getSizeAndTag(level));
</script>
<Heading {size} {tag} class="mt-4" {id}>
{@render children()}
</Heading>
@@ -0,0 +1,11 @@
<script lang="ts">
import { cleanClass } from '$lib/utilities/internal.js';
type Props = {
class?: string;
};
const { class: className }: Props = $props();
</script>
<hr class={cleanClass('my-6 border-t', className)} />
@@ -0,0 +1,14 @@
<script lang="ts">
import Link from '$lib/components/Link/Link.svelte';
import type { Snippet } from 'svelte';
type Props = {
href: string;
title?: string;
children?: Snippet;
};
const { href, title, children }: Props = $props();
</script>
<Link {href} {title} {children} />
@@ -0,0 +1,21 @@
<script lang="ts">
import type { Snippet } from 'svelte';
type Props = {
ordered?: boolean;
children: Snippet;
};
const { children, ordered }: Props = $props();
const styles = 'list-outside ps-6 w-full flex flex-col gap-1';
</script>
{#if ordered}
<ol class="list-decimal {styles}">
{@render children?.()}
</ol>
{:else}
<ul class="list-disc {styles}">
{@render children?.()}
</ul>
{/if}
@@ -0,0 +1,19 @@
<script lang="ts">
import Checkbox from '$lib/components/Checkbox/Checkbox.svelte';
import type { Snippet } from 'svelte';
type Props = {
checked?: boolean;
task?: boolean;
children: Snippet;
};
const { children, checked, task }: Props = $props();
</script>
<li class:list-none={task}>
{#if task}
<Checkbox {checked} readonly size="tiny" color="secondary" />
{/if}
{@render children?.()}
</li>
@@ -0,0 +1,14 @@
<script lang="ts">
import { Text } from '@immich/ui';
import type { Snippet } from 'svelte';
type Props = {
children: Snippet;
};
const { children }: Props = $props();
</script>
<Text class="mb-1">
{@render children()}
</Text>
@@ -0,0 +1,19 @@
import BlockQuote from './BlockQuote.svelte';
import Code from './Code.svelte';
import Heading from './Heading.svelte';
import LineBreak from './LineBreak.svelte';
import Link from './Link.svelte';
import List from './List.svelte';
import ListItem from './ListItem.svelte';
import Paragraph from './Paragraph.svelte';
export const Markdown = {
Link,
BlockQuote,
Code,
Heading,
LineBreak,
ListItem,
List,
Paragraph,
};

Some files were not shown because too many files have changed in this diff Show More