feat: Proper theme support
This commit is contained in:
@@ -147,39 +147,51 @@
|
||||
<div class="flex flex-wrap gap-2 m-2">
|
||||
{#if isClipboardAvailable()}
|
||||
<button class="action-btn w-full" on:click={onCopyClipboard}
|
||||
><i class="far fa-copy" /> Copy Image to clipboard
|
||||
><i class="far fa-copy mr-2" /> Copy Image to clipboard
|
||||
</button>
|
||||
{/if}
|
||||
<button class="action-btn flex-auto" on:click={onDownloadPNG}>
|
||||
<i class="fas fa-download" /> PNG
|
||||
<i class="fas fa-download mr-2" /> PNG
|
||||
</button>
|
||||
<button class="action-btn flex-auto" on:click={onDownloadSVG}>
|
||||
<i class="fas fa-download" /> SVG
|
||||
<i class="fas fa-download mr-2" /> SVG
|
||||
</button>
|
||||
<button class="action-btn flex-auto">
|
||||
<a target="_blank" href={iUrl}><i class="fas fa-external-link-alt" /> PNG</a>
|
||||
<a target="_blank" href={iUrl}><i class="fas fa-external-link-alt mr-2" /> PNG</a>
|
||||
</button>
|
||||
<button class="action-btn flex-auto">
|
||||
<a target="_blank" href={svgUrl}><i class="fas fa-external-link-alt" /> SVG</a>
|
||||
<a target="_blank" href={svgUrl}><i class="fas fa-external-link-alt mr-2" /> SVG</a>
|
||||
</button>
|
||||
|
||||
<div class="flex gap-2 items-center">
|
||||
PNG size
|
||||
<input type="radio" value="auto" id="autosize" bind:group={imagemodeselected} />
|
||||
<label for="autosize">Auto</label>
|
||||
<input type="radio" value="width" id="width-active" bind:group={imagemodeselected} />
|
||||
<label for="width">Width</label>
|
||||
<input type="radio" value="height" id="height-active" bind:group={imagemodeselected} />
|
||||
<label for="height">Height</label>
|
||||
<label for="autosize">
|
||||
<input type="radio" value="auto" id="autosize" bind:group={imagemodeselected} /> Auto
|
||||
</label>
|
||||
|
||||
<label for="width">
|
||||
<input type="radio" value="width" id="width" bind:group={imagemodeselected} /> Width
|
||||
</label>
|
||||
|
||||
<label for="height">
|
||||
<input type="radio" value="height" id="height" bind:group={imagemodeselected} /> Height
|
||||
</label>
|
||||
|
||||
{#if imagemodeselected !== 'auto'}
|
||||
<input id="height" type="number" min="3" max="10000" bind:value={userimagesize} />
|
||||
<input
|
||||
id="height"
|
||||
class="input"
|
||||
type="number"
|
||||
min="3"
|
||||
max="10000"
|
||||
bind:value={userimagesize} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="w-full flex gap-2 items-center">
|
||||
<input class="input" id="markdown" type="text" value={mdCode} on:click={onCopyMarkdown} />
|
||||
<label for="markdown">
|
||||
<button class="btn btn-primary btn-sm flex-auto" on:click={onCopyMarkdown}>
|
||||
<button class="btn btn-primary btn-md flex-auto" on:click={onCopyMarkdown}>
|
||||
Copy Markdown
|
||||
</button>
|
||||
</label>
|
||||
@@ -193,7 +205,7 @@
|
||||
bind:value={gistURL}
|
||||
placeholder="Enter Gist URL" />
|
||||
<label for="gist">
|
||||
<button class="btn btn-primary btn-sm flex-auto" on:click={loadGist}> Load Gist </button>
|
||||
<button class="btn btn-primary btn-md flex-auto" on:click={loadGist}> Load Gist </button>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,21 +7,22 @@
|
||||
export let tabs: Tab[] = [];
|
||||
export let title: string;
|
||||
$: isOpen = isCloseable ? isOpen : true;
|
||||
$: isTabsShown = isOpen && tabs.length > 0;
|
||||
</script>
|
||||
|
||||
<div class="card rounded overflow-hidden m-2 flex-grow flex flex-col shadow-2xl">
|
||||
<div
|
||||
class="bg-primary p-2 {tabs.length > 0 ? 'pb-0' : ''} flex-none cursor-pointer"
|
||||
class="bg-primary p-2 {isTabsShown ? 'pb-0' : ''} flex-none cursor-pointer"
|
||||
on:click={() => (isOpen = !isOpen)}>
|
||||
<div class="flex justify-between">
|
||||
<Tabs on:select {tabs} bind:isOpen {title} {isCloseable} />
|
||||
<div class="flex gap-x-4 items-center">
|
||||
<div class="flex gap-x-4 items-center {isTabsShown ? '-mt-2' : ''}">
|
||||
<slot name="actions" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{#if isOpen}
|
||||
<div class="card-body p-0 flex-grow overflow-auto" transition:slide>
|
||||
<div class="card-body p-0 flex-grow overflow-auto text-base-content" transition:slide>
|
||||
<slot />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<ul class="tabs" transition:fade>
|
||||
{#each tabs as tab}
|
||||
<div
|
||||
class="tab tab-lifted {activeTabID === tab.id ? 'tab-active' : ''}"
|
||||
class="tab tab-lifted text-primary-content {activeTabID === tab.id ? 'tab-active' : ''}"
|
||||
on:click|stopPropagation={() => toggleTabs(tab)}>
|
||||
<i class="mr-1 {tab.icon}" />
|
||||
{tab.title}
|
||||
|
||||
@@ -90,13 +90,13 @@
|
||||
<div slot="actions">
|
||||
<button
|
||||
id="saveHistory"
|
||||
class="btn btn-xs btn-success"
|
||||
class="btn btn-xs btn-success w-12"
|
||||
on:click|stopPropagation={() => saveHistory()}
|
||||
title="Save current state"><i class="far fa-save" /></button>
|
||||
{#if $historyModeStore !== 'loader'}
|
||||
<button
|
||||
id="clearHistory"
|
||||
class="btn btn-xs btn-error"
|
||||
class="btn btn-xs btn-error w-12"
|
||||
on:click|stopPropagation={() => clearHistory()}
|
||||
title="Delete all saved states"><i class="fas fa-trash-alt" /></button>
|
||||
{/if}
|
||||
@@ -107,7 +107,7 @@
|
||||
<li class="rounded p-2 shadow flex-col">
|
||||
<div class="flex">
|
||||
<div class="flex-1">
|
||||
<div class="flex flex-col">
|
||||
<div class="flex flex-col text-base-content">
|
||||
{#if url}
|
||||
<a
|
||||
href={url}
|
||||
|
||||
@@ -1,47 +1,59 @@
|
||||
<script>
|
||||
import { toggleDarkTheme } from '$lib/util/state';
|
||||
|
||||
import { setTheme, themeStore } from '$lib/util/theme';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
const themes = [
|
||||
'light',
|
||||
'dark',
|
||||
'cupcake',
|
||||
'bumblebee',
|
||||
'emerald',
|
||||
'corporate',
|
||||
'synthwave',
|
||||
'retro',
|
||||
'cyberpunk',
|
||||
'valentine',
|
||||
'halloween',
|
||||
'garden',
|
||||
'forest',
|
||||
'aqua',
|
||||
'lofi',
|
||||
'pastel',
|
||||
'fantasy',
|
||||
'wireframe',
|
||||
'black',
|
||||
'luxury',
|
||||
'dracula'
|
||||
'🌝 light',
|
||||
'🌚 dark',
|
||||
'🧁 cupcake',
|
||||
'🐝 bumblebee',
|
||||
'✳️ emerald',
|
||||
'🏢 corporate',
|
||||
'🌃 synthwave',
|
||||
'👴 retro',
|
||||
'🤖 cyberpunk',
|
||||
'🌸 valentine',
|
||||
'🎃 halloween',
|
||||
'🌷 garden',
|
||||
'🌲 forest',
|
||||
'🐟 aqua',
|
||||
'👓 lofi',
|
||||
'🖍 pastel',
|
||||
'🧚♀️ fantasy',
|
||||
'📝 wireframe',
|
||||
'🏴 black',
|
||||
'💎 luxury',
|
||||
'🧛♂️ dracula'
|
||||
];
|
||||
|
||||
let selectedTheme = $themeStore.theme;
|
||||
onMount(() => {
|
||||
themeStore.subscribe(({ theme, isDark }) => {
|
||||
document.getElementsByTagName('html')[0].setAttribute('data-theme', theme);
|
||||
toggleDarkTheme(isDark);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<select
|
||||
class="select select-bordered"
|
||||
bind:value={selectedTheme}
|
||||
on:change={() => setTheme(selectedTheme)}>
|
||||
{#each themes as theme}
|
||||
<option value={theme}>{theme}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<div class="hidden lg:block dropdown">
|
||||
<div tabindex="0" class="btn btn-ghost ">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
class="inline-block w-6 h-6 stroke-current md:mr-2"
|
||||
><path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01" /></svg>
|
||||
<span class="hidden md:inline"> Change Theme </span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 1792 1792"
|
||||
class="inline-block w-4 h-4 ml-1 fill-current"
|
||||
><path
|
||||
d="M1395 736q0 13-10 23l-466 466q-10 10-23 10t-23-10l-466-466q-10-10-10-23t10-23l50-50q10-10 23-10t23 10l393 393 393-393q10-10 23-10t23 10l50 50q10 10 10 23z" /></svg>
|
||||
</div>
|
||||
<div
|
||||
class="mt-14 overflow-y-auto shadow-2xl top-px dropdown-content h-96 w-52 bg-base-200 text-base-content">
|
||||
<ul tabindex="0" class="p-4 menu compact">
|
||||
{#each themes as theme}
|
||||
<li class={theme.includes($themeStore.theme) ? 'bordered' : ''}>
|
||||
<a on:click={() => setTheme(theme)}>{theme}</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -99,7 +99,7 @@ export const toggleDarkTheme = (dark: boolean): void => {
|
||||
config.theme = dark ? 'dark' : 'default';
|
||||
}
|
||||
|
||||
return { ...state, mermaid: JSON.stringify(config), updateEditor: true };
|
||||
return { ...state, mermaid: JSON.stringify(config, null, 2), updateEditor: true };
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { writable } from 'svelte/store';
|
||||
import { persist, localStorage } from '@macfja/svelte-persistent-store';
|
||||
import { toggleDarkTheme } from './state';
|
||||
|
||||
export const themeStore = persist(
|
||||
writable({
|
||||
isDark: false,
|
||||
theme: 'light'
|
||||
theme: ''
|
||||
}),
|
||||
localStorage(),
|
||||
'themeStore'
|
||||
@@ -14,6 +13,9 @@ export const themeStore = persist(
|
||||
const darkThemes = ['dark', 'synthwave', 'halloween', 'forest', 'luxury', 'black', 'dracula'];
|
||||
|
||||
export const setTheme = (theme: string): void => {
|
||||
if (theme.includes(' ')) {
|
||||
theme = theme.split(' ')[1].trim();
|
||||
}
|
||||
const isDark = darkThemes.includes(theme);
|
||||
console.log('Setting theme', theme);
|
||||
themeStore.set({ theme, isDark });
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
import { base } from '$app/paths';
|
||||
import { onMount } from 'svelte';
|
||||
import { loadingStateStore } from '$lib/util/loading';
|
||||
import { themeStore } from '$lib/util/theme';
|
||||
import { setTheme, themeStore } from '$lib/util/theme';
|
||||
import { toggleDarkTheme } from '$lib/util/state';
|
||||
|
||||
// This can be removed once https://github.com/sveltejs/kit/issues/1612 is fixed.
|
||||
// Then move it into src and vite will bundle it automatically.
|
||||
@@ -20,10 +21,23 @@
|
||||
console.log('Service worker registration failed, error:', error);
|
||||
});
|
||||
}
|
||||
|
||||
const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
|
||||
if (isDarkMode && $themeStore.theme === '') {
|
||||
setTheme('dark');
|
||||
}
|
||||
|
||||
themeStore.subscribe(({ theme, isDark }) => {
|
||||
if (theme) {
|
||||
document.getElementsByTagName('html')[0].setAttribute('data-theme', theme);
|
||||
toggleDarkTheme(isDark);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<main class="h-screen text-primary-content" data-theme={$themeStore}>
|
||||
<main class="h-screen text-primary-content">
|
||||
<slot />
|
||||
</main>
|
||||
|
||||
|
||||
+20
-17
@@ -126,22 +126,25 @@
|
||||
<div class="hidden md:flex flex-col" id="editorPane" style="width: 40%">
|
||||
<Card on:select={tabSelectHandler} {tabs} isCloseable={false} title="Mermaid">
|
||||
<div slot="actions">
|
||||
{#if !$codeStore.autoSync}
|
||||
<button
|
||||
class="btn btn-primary btn-xs"
|
||||
title="Sync Diagram"
|
||||
data-cy="sync"
|
||||
on:click={syncDiagram}><i class="fas fa-sync" /></button>
|
||||
{/if}
|
||||
<div class="form-control">
|
||||
<label class="cursor-pointer label" for="autoSync">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="toggle toggle-primary toggle-sm"
|
||||
id="autoSync"
|
||||
bind:checked={$codeStore.autoSync} />
|
||||
<span> Auto sync</span>
|
||||
</label>
|
||||
<div class="flex flex-row items-center">
|
||||
{#if !$codeStore.autoSync}
|
||||
<button
|
||||
class="btn btn-secondary btn-xs"
|
||||
title="Sync Diagram"
|
||||
data-cy="sync"
|
||||
on:click={syncDiagram}><i class="fas fa-sync" /></button>
|
||||
{/if}
|
||||
|
||||
<div class="form-control">
|
||||
<label class="cursor-pointer label" for="autoSync">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="toggle toggle-primary"
|
||||
id="autoSync"
|
||||
bind:checked={$codeStore.autoSync} />
|
||||
<span> Auto sync</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -161,7 +164,7 @@
|
||||
slot="actions"
|
||||
class="btn btn-primary btn-xs shadow-lg"
|
||||
title="View diagram in new page"
|
||||
on:click|stopPropagation={() => viewDiagram()}><i class="far fa-eye" /> View</button>
|
||||
on:click|stopPropagation={() => viewDiagram()}><i class="far fa-eye mr-2" /> View</button>
|
||||
|
||||
<div class="flex-1 overflow-auto">
|
||||
<View />
|
||||
|
||||
Reference in New Issue
Block a user