feat: Proper theme support

This commit is contained in:
Sidharth Vinod
2021-08-19 00:19:22 +05:30
parent ffe260893d
commit 19a6190b56
10 changed files with 4881 additions and 4978 deletions
+26 -14
View File
@@ -147,39 +147,51 @@
<div class="flex flex-wrap gap-2 m-2"> <div class="flex flex-wrap gap-2 m-2">
{#if isClipboardAvailable()} {#if isClipboardAvailable()}
<button class="action-btn w-full" on:click={onCopyClipboard} <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> </button>
{/if} {/if}
<button class="action-btn flex-auto" on:click={onDownloadPNG}> <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>
<button class="action-btn flex-auto" on:click={onDownloadSVG}> <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>
<button class="action-btn flex-auto"> <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>
<button class="action-btn flex-auto"> <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> </button>
<div class="flex gap-2 items-center"> <div class="flex gap-2 items-center">
PNG size PNG size
<input type="radio" value="auto" id="autosize" bind:group={imagemodeselected} /> <label for="autosize">
<label for="autosize">Auto</label> <input type="radio" value="auto" id="autosize" bind:group={imagemodeselected} /> Auto
<input type="radio" value="width" id="width-active" bind:group={imagemodeselected} /> </label>
<label for="width">Width</label>
<input type="radio" value="height" id="height-active" bind:group={imagemodeselected} /> <label for="width">
<label for="height">Height</label> <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'} {#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} {/if}
</div> </div>
<div class="w-full flex gap-2 items-center"> <div class="w-full flex gap-2 items-center">
<input class="input" id="markdown" type="text" value={mdCode} on:click={onCopyMarkdown} /> <input class="input" id="markdown" type="text" value={mdCode} on:click={onCopyMarkdown} />
<label for="markdown"> <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 Copy Markdown
</button> </button>
</label> </label>
@@ -193,7 +205,7 @@
bind:value={gistURL} bind:value={gistURL}
placeholder="Enter Gist URL" /> placeholder="Enter Gist URL" />
<label for="gist"> <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> </label>
</div> </div>
</div> </div>
+4 -3
View File
@@ -7,21 +7,22 @@
export let tabs: Tab[] = []; export let tabs: Tab[] = [];
export let title: string; export let title: string;
$: isOpen = isCloseable ? isOpen : true; $: isOpen = isCloseable ? isOpen : true;
$: isTabsShown = isOpen && tabs.length > 0;
</script> </script>
<div class="card rounded overflow-hidden m-2 flex-grow flex flex-col shadow-2xl"> <div class="card rounded overflow-hidden m-2 flex-grow flex flex-col shadow-2xl">
<div <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)}> on:click={() => (isOpen = !isOpen)}>
<div class="flex justify-between"> <div class="flex justify-between">
<Tabs on:select {tabs} bind:isOpen {title} {isCloseable} /> <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" /> <slot name="actions" />
</div> </div>
</div> </div>
</div> </div>
{#if isOpen} {#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 /> <slot />
</div> </div>
{/if} {/if}
+1 -1
View File
@@ -26,7 +26,7 @@
<ul class="tabs" transition:fade> <ul class="tabs" transition:fade>
{#each tabs as tab} {#each tabs as tab}
<div <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)}> on:click|stopPropagation={() => toggleTabs(tab)}>
<i class="mr-1 {tab.icon}" /> <i class="mr-1 {tab.icon}" />
{tab.title} {tab.title}
+3 -3
View File
@@ -90,13 +90,13 @@
<div slot="actions"> <div slot="actions">
<button <button
id="saveHistory" id="saveHistory"
class="btn btn-xs btn-success" class="btn btn-xs btn-success w-12"
on:click|stopPropagation={() => saveHistory()} on:click|stopPropagation={() => saveHistory()}
title="Save current state"><i class="far fa-save" /></button> title="Save current state"><i class="far fa-save" /></button>
{#if $historyModeStore !== 'loader'} {#if $historyModeStore !== 'loader'}
<button <button
id="clearHistory" id="clearHistory"
class="btn btn-xs btn-error" class="btn btn-xs btn-error w-12"
on:click|stopPropagation={() => clearHistory()} on:click|stopPropagation={() => clearHistory()}
title="Delete all saved states"><i class="fas fa-trash-alt" /></button> title="Delete all saved states"><i class="fas fa-trash-alt" /></button>
{/if} {/if}
@@ -107,7 +107,7 @@
<li class="rounded p-2 shadow flex-col"> <li class="rounded p-2 shadow flex-col">
<div class="flex"> <div class="flex">
<div class="flex-1"> <div class="flex-1">
<div class="flex flex-col"> <div class="flex flex-col text-base-content">
{#if url} {#if url}
<a <a
href={url} href={url}
+52 -40
View File
@@ -1,47 +1,59 @@
<script> <script>
import { toggleDarkTheme } from '$lib/util/state';
import { setTheme, themeStore } from '$lib/util/theme'; import { setTheme, themeStore } from '$lib/util/theme';
import { onMount } from 'svelte';
const themes = [ const themes = [
'light', '🌝 light',
'dark', '🌚 dark',
'cupcake', '🧁 cupcake',
'bumblebee', '🐝 bumblebee',
'emerald', '✳️ emerald',
'corporate', '🏢 corporate',
'synthwave', '🌃 synthwave',
'retro', '👴 retro',
'cyberpunk', '🤖 cyberpunk',
'valentine', '🌸 valentine',
'halloween', '🎃 halloween',
'garden', '🌷 garden',
'forest', '🌲 forest',
'aqua', '🐟 aqua',
'lofi', '👓 lofi',
'pastel', '🖍 pastel',
'fantasy', '🧚‍♀️ fantasy',
'wireframe', '📝 wireframe',
'black', '🏴 black',
'luxury', '💎 luxury',
'dracula' '🧛‍♂️ dracula'
]; ];
let selectedTheme = $themeStore.theme;
onMount(() => {
themeStore.subscribe(({ theme, isDark }) => {
document.getElementsByTagName('html')[0].setAttribute('data-theme', theme);
toggleDarkTheme(isDark);
});
});
</script> </script>
<select <div class="hidden lg:block dropdown">
class="select select-bordered" <div tabindex="0" class="btn btn-ghost ">
bind:value={selectedTheme} <svg
on:change={() => setTheme(selectedTheme)}> xmlns="http://www.w3.org/2000/svg"
{#each themes as theme} fill="none"
<option value={theme}>{theme}</option> viewBox="0 0 24 24"
{/each} class="inline-block w-6 h-6 stroke-current md:mr-2"
</select> ><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>
+1 -1
View File
@@ -99,7 +99,7 @@ export const toggleDarkTheme = (dark: boolean): void => {
config.theme = dark ? 'dark' : 'default'; config.theme = dark ? 'dark' : 'default';
} }
return { ...state, mermaid: JSON.stringify(config), updateEditor: true }; return { ...state, mermaid: JSON.stringify(config, null, 2), updateEditor: true };
}); });
}; };
+4 -2
View File
@@ -1,11 +1,10 @@
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import { persist, localStorage } from '@macfja/svelte-persistent-store'; import { persist, localStorage } from '@macfja/svelte-persistent-store';
import { toggleDarkTheme } from './state';
export const themeStore = persist( export const themeStore = persist(
writable({ writable({
isDark: false, isDark: false,
theme: 'light' theme: ''
}), }),
localStorage(), localStorage(),
'themeStore' 'themeStore'
@@ -14,6 +13,9 @@ export const themeStore = persist(
const darkThemes = ['dark', 'synthwave', 'halloween', 'forest', 'luxury', 'black', 'dracula']; const darkThemes = ['dark', 'synthwave', 'halloween', 'forest', 'luxury', 'black', 'dracula'];
export const setTheme = (theme: string): void => { export const setTheme = (theme: string): void => {
if (theme.includes(' ')) {
theme = theme.split(' ')[1].trim();
}
const isDark = darkThemes.includes(theme); const isDark = darkThemes.includes(theme);
console.log('Setting theme', theme); console.log('Setting theme', theme);
themeStore.set({ theme, isDark }); themeStore.set({ theme, isDark });
+16 -2
View File
@@ -3,7 +3,8 @@
import { base } from '$app/paths'; import { base } from '$app/paths';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { loadingStateStore } from '$lib/util/loading'; 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. // 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. // Then move it into src and vite will bundle it automatically.
@@ -20,10 +21,23 @@
console.log('Service worker registration failed, error:', error); 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> </script>
<main class="h-screen text-primary-content" data-theme={$themeStore}> <main class="h-screen text-primary-content">
<slot /> <slot />
</main> </main>
+20 -17
View File
@@ -126,22 +126,25 @@
<div class="hidden md:flex flex-col" id="editorPane" style="width: 40%"> <div class="hidden md:flex flex-col" id="editorPane" style="width: 40%">
<Card on:select={tabSelectHandler} {tabs} isCloseable={false} title="Mermaid"> <Card on:select={tabSelectHandler} {tabs} isCloseable={false} title="Mermaid">
<div slot="actions"> <div slot="actions">
{#if !$codeStore.autoSync} <div class="flex flex-row items-center">
<button {#if !$codeStore.autoSync}
class="btn btn-primary btn-xs" <button
title="Sync Diagram" class="btn btn-secondary btn-xs"
data-cy="sync" title="Sync Diagram"
on:click={syncDiagram}><i class="fas fa-sync" /></button> data-cy="sync"
{/if} on:click={syncDiagram}><i class="fas fa-sync" /></button>
<div class="form-control"> {/if}
<label class="cursor-pointer label" for="autoSync">
<input <div class="form-control">
type="checkbox" <label class="cursor-pointer label" for="autoSync">
class="toggle toggle-primary toggle-sm" <input
id="autoSync" type="checkbox"
bind:checked={$codeStore.autoSync} /> class="toggle toggle-primary"
<span> Auto sync</span> id="autoSync"
</label> bind:checked={$codeStore.autoSync} />
<span> Auto sync</span>
</label>
</div>
</div> </div>
</div> </div>
@@ -161,7 +164,7 @@
slot="actions" slot="actions"
class="btn btn-primary btn-xs shadow-lg" class="btn btn-primary btn-xs shadow-lg"
title="View diagram in new page" 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"> <div class="flex-1 overflow-auto">
<View /> <View />
+4754 -4895
View File
File diff suppressed because it is too large Load Diff