feat: add daisyUI
This commit is contained in:
@@ -50,6 +50,7 @@
|
||||
"@analytics/google-analytics": "^0.5.3",
|
||||
"@macfja/svelte-persistent-store": "^1.1.1",
|
||||
"analytics": "^0.7.13",
|
||||
"daisyui": "^1.11.1",
|
||||
"js-base64": "^3.6.1",
|
||||
"mermaid": "^8.11.4",
|
||||
"moment": "^2.29.1",
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/*
|
||||
.nav-btn {
|
||||
@apply lg:p-2 py-3 px-0 block border-b-2 border-transparent hover:border-white;
|
||||
}
|
||||
@@ -15,4 +15,4 @@
|
||||
|
||||
.input {
|
||||
@apply flex-1 border-indigo-400 border-solid border-2 rounded;
|
||||
}
|
||||
} */
|
||||
|
||||
@@ -9,17 +9,17 @@
|
||||
$: isOpen = isCloseable ? isOpen : true;
|
||||
</script>
|
||||
|
||||
<div class="bg-white rounded overflow-hidden shadow m-2 flex-grow flex flex-col">
|
||||
<div class="bg-indigo-400 border-gray-400 p-2 flex-none" on:click={() => (isOpen = !isOpen)}>
|
||||
<div class="card rounded overflow-hidden m-2 flex-grow flex flex-col shadow-2xl">
|
||||
<div class="bg-primary p-2 pb-0 flex-none" 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 text-white">
|
||||
<div class="flex gap-x-4 items-center">
|
||||
<slot name="actions" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{#if isOpen}
|
||||
<div class="flex-grow overflow-auto" transition:slide>
|
||||
<div class="card-body p-0 flex-grow overflow-auto" transition:slide>
|
||||
<slot />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -17,25 +17,20 @@
|
||||
</script>
|
||||
|
||||
<div class="flex cursor-default">
|
||||
<span class="text-white mr-2 font-semibold" on:click|stopPropagation={() => (isOpen = !isOpen)}>
|
||||
<span class="mr-2 font-semibold" on:click|stopPropagation={() => (isOpen = !isOpen)}>
|
||||
{#if isCloseable}
|
||||
<i class="fas fa-chevron-right icon" class:isOpen />
|
||||
{/if}
|
||||
{title}</span>
|
||||
{#if isOpen && tabs}
|
||||
<ul class="flex flex-wrap flex-row" transition:fade>
|
||||
<ul class="tabs" transition:fade>
|
||||
{#each tabs as tab}
|
||||
<li class="mr-2 last:mr-0 w-28 h-6 flex-auto text-center">
|
||||
<div
|
||||
class="text cursor-pointer font-semibold min-w-16 w-auto px-2 py-1 -mb-4 rounded-t block leading-normal {activeTabID ===
|
||||
tab.id
|
||||
? 'text-indigo-500 bg-white border-white'
|
||||
: 'text-white bg-indigo-500 border-indigo-500 hover:bg-indigo-600'}"
|
||||
on:click|stopPropagation={() => toggleTabs(tab)}>
|
||||
<i class={tab.icon} />
|
||||
{tab.title}
|
||||
</div>
|
||||
</li>
|
||||
<div
|
||||
class="tab tab-lifted {activeTabID === tab.id ? 'tab-active' : ''}"
|
||||
on:click|stopPropagation={() => toggleTabs(tab)}>
|
||||
<i class="mr-1 {tab.icon}" />
|
||||
{tab.title}
|
||||
</div>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
|
||||
@@ -90,13 +90,13 @@
|
||||
<div slot="actions">
|
||||
<button
|
||||
id="saveHistory"
|
||||
class="btn"
|
||||
class="btn btn-xs btn-success"
|
||||
on:click|stopPropagation={() => saveHistory()}
|
||||
title="Save current state"><i class="far fa-save" /></button>
|
||||
{#if $historyModeStore !== 'loader'}
|
||||
<button
|
||||
id="clearHistory"
|
||||
class="btn text-red-400"
|
||||
class="btn btn-xs btn-error"
|
||||
on:click|stopPropagation={() => clearHistory()}
|
||||
title="Delete all saved states"><i class="fas fa-trash-alt" /></button>
|
||||
{/if}
|
||||
@@ -121,20 +121,18 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2 content-center">
|
||||
<button
|
||||
class="rounded px-2 w-24 bg-green-200 hover:bg-green-300"
|
||||
on:click={() => restoreHistory(state)}><i class="fas fa-undo" /> Restore</button>
|
||||
<button class="btn btn-success" on:click={() => restoreHistory(state)}
|
||||
><i class="fas fa-undo mr-1" /> Restore</button>
|
||||
{#if type !== 'loader'}
|
||||
<button
|
||||
class="rounded px-2 w-24 bg-red-200 hover:bg-red-300"
|
||||
on:click={() => clearHistory(time)}><i class="fas fa-trash-alt" /> Delete</button>
|
||||
<button class="btn btn-error" on:click={() => clearHistory(time)}
|
||||
><i class="fas fa-trash-alt mr-1" /> Delete</button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{/each}
|
||||
{:else}
|
||||
<div class="m-2 text-gray-600">
|
||||
<div class="m-2">
|
||||
No items in History<br />
|
||||
Click the Save button to save current state and restore it later.<br />
|
||||
Timeline will automatically be saved every minute.
|
||||
|
||||
@@ -37,11 +37,12 @@
|
||||
];
|
||||
</script>
|
||||
|
||||
<header class="p-2 bg-indigo-400 text-white font-bold flex flex-wrap items-center">
|
||||
<div class="flex-1 flex justify-between items-center">
|
||||
<a href="/">Mermaid<span class="text-xs font-thin">v{version}</span> Live Editor</a>
|
||||
<div class="navbar mb-2 shadow-lg bg-primary text-neutral-content">
|
||||
<div class="flex-1 px-2 mx-2">
|
||||
<span class="text-lg font-bold">
|
||||
<a href="/">Mermaid<span class="text-xs font-thin">v{version}</span> Live Editor</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<label for="menu-toggle" class="pointer-cursor lg:hidden block"
|
||||
><svg
|
||||
class="fill-current "
|
||||
@@ -54,27 +55,25 @@
|
||||
<input class="hidden" type="checkbox" id="menu-toggle" />
|
||||
|
||||
<div class="hidden lg:flex lg:items-center lg:w-auto w-full" id="menu">
|
||||
<nav>
|
||||
<ul class="lg:flex items-center justify-between text-base pt-4 lg:pt-0">
|
||||
{#each links as { title, href, icon }}
|
||||
<li>
|
||||
<a class="nav-btn" target="_blank" {href}>
|
||||
{#if icon}
|
||||
<i class={icon} />
|
||||
{/if}
|
||||
{title}</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</nav>
|
||||
<ul class="lg:flex items-center justify-between text-base pt-4 lg:pt-0">
|
||||
{#each links as { title, href, icon }}
|
||||
<li>
|
||||
<a class="btn btn-ghost " target="_blank" {href}>
|
||||
{#if icon}
|
||||
<i class={icon} />
|
||||
{/if}
|
||||
{title}</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#menu-toggle:checked + #menu {
|
||||
display: block;
|
||||
}
|
||||
header {
|
||||
.navbar {
|
||||
z-index: 10000;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<script>
|
||||
import { themeStore } from '$lib/util/state';
|
||||
|
||||
const themes = [
|
||||
'light',
|
||||
'dark',
|
||||
'cupcake',
|
||||
'bumblebee',
|
||||
'emerald',
|
||||
'corporate',
|
||||
'synthwave',
|
||||
'retro',
|
||||
'cyberpunk',
|
||||
'valentine',
|
||||
'halloween',
|
||||
'garden',
|
||||
'forest',
|
||||
'aqua',
|
||||
'lofi',
|
||||
'pastel',
|
||||
'fantasy',
|
||||
'wireframe',
|
||||
'black',
|
||||
'luxury',
|
||||
'dracula'
|
||||
];
|
||||
</script>
|
||||
|
||||
<select class="select select-bordered w-full max-w-xs" bind:value={$themeStore}>
|
||||
{#each themes as theme}
|
||||
<option value={theme}>{theme}</option>
|
||||
{/each}
|
||||
</select>
|
||||
@@ -2,7 +2,7 @@ import { writable, get, derived } from 'svelte/store';
|
||||
import { toBase64, fromBase64 } from 'js-base64';
|
||||
import { persist, localStorage } from '@macfja/svelte-persistent-store';
|
||||
import type { State } from '$lib/types';
|
||||
import { saveStatistcs } from './stats';
|
||||
import { saveStatistics } from './stats';
|
||||
|
||||
export const defaultState: State = {
|
||||
code: `graph TD
|
||||
@@ -24,6 +24,7 @@ export const defaultState: State = {
|
||||
updateDiagram: true
|
||||
};
|
||||
|
||||
export const themeStore = persist(writable(''), localStorage(), 'themeStore');
|
||||
export const codeStore = persist(writable(defaultState), localStorage(), 'codeStore');
|
||||
export const base64State = derived([codeStore], ([code], set) => {
|
||||
set(toBase64(JSON.stringify(code), true));
|
||||
@@ -33,7 +34,7 @@ export const loadState = (data: string): void => {
|
||||
let state: State;
|
||||
try {
|
||||
const stateStr = fromBase64(data);
|
||||
console.log(`Tring to load state: ${stateStr}`);
|
||||
console.log(`Trying to load state: ${stateStr}`);
|
||||
state = JSON.parse(stateStr);
|
||||
const mermaidConfig =
|
||||
typeof state.mermaid === 'string' ? JSON.parse(state.mermaid) : state.mermaid;
|
||||
@@ -66,12 +67,12 @@ export const updateCodeStore = (newState: State): void => {
|
||||
|
||||
let prompted = false;
|
||||
export const updateCode = (code: string, updateEditor: boolean, updateDiagram = false): void => {
|
||||
saveStatistcs(code);
|
||||
saveStatistics(code);
|
||||
const lines = (code.match(/\n/g) || '').length + 1;
|
||||
|
||||
if (lines > 50 && !prompted && get(codeStore).autoSync) {
|
||||
const turnOff = confirm(
|
||||
'Long diagram deteced. Turn off Auto Sync? Click the sync logo to manually sync.'
|
||||
'Long diagram detected. Turn off Auto Sync? Click the sync logo to manually sync.'
|
||||
);
|
||||
prompted = true;
|
||||
if (turnOff) {
|
||||
|
||||
@@ -34,10 +34,10 @@ const detectType = (text: string): string => {
|
||||
|
||||
// manual debounce
|
||||
let timeout;
|
||||
export const saveStatistcs = (graph: string): void => {
|
||||
export const saveStatistics = (graph: string): void => {
|
||||
if (analytics) {
|
||||
clearTimeout(timeout);
|
||||
// Only save statistcs after a 5 sec delay
|
||||
// Only save statistics after a 5 sec delay
|
||||
timeout = setTimeout(function () {
|
||||
const graphType = detectType(graph);
|
||||
console.debug('ga:', 'send', 'event', 'render', graphType);
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
import { base } from '$app/paths';
|
||||
import { onMount } from 'svelte';
|
||||
import { loadingStateStore } from '$lib/util/loading';
|
||||
import { themeStore } from '$lib/util/state';
|
||||
import Theme from '$lib/components/theme.svelte';
|
||||
|
||||
// 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.
|
||||
onMount(() => {
|
||||
@@ -21,7 +24,8 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<main class="h-screen">
|
||||
<main class="h-screen" data-theme={$themeStore}>
|
||||
<Theme />
|
||||
<slot />
|
||||
</main>
|
||||
|
||||
|
||||
+13
-9
@@ -120,7 +120,7 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="h-full flex flex-col overflow-hidden bg-gray-100">
|
||||
<div class="h-full flex flex-col overflow-hidden">
|
||||
<Navbar />
|
||||
<div class="flex-1 flex overflow-hidden">
|
||||
<div class="hidden md:flex flex-col" id="editorPane" style="width: 40%">
|
||||
@@ -128,17 +128,21 @@
|
||||
<div slot="actions">
|
||||
{#if !$codeStore.autoSync}
|
||||
<button
|
||||
class="bg-indigo-500 hover:bg-indigo-700 rounded px-4 mx-2"
|
||||
class="btn btn-primary btn-xs"
|
||||
title="Sync Diagram"
|
||||
data-cy="sync"
|
||||
on:click={syncDiagram}><i class="fas fa-sync" /></button>
|
||||
{/if}
|
||||
<label
|
||||
for="autoSync"
|
||||
style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">
|
||||
<input type="checkbox" id="autoSync" bind:checked={$codeStore.autoSync} />
|
||||
Auto sync
|
||||
</label>
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<Editor on:update={updateHandler} {language} bind:text {errorMarkers} />
|
||||
@@ -155,7 +159,7 @@
|
||||
<Card title="Diagram" isCloseable={false}>
|
||||
<button
|
||||
slot="actions"
|
||||
class="btn"
|
||||
class="btn btn-primary btn-xs"
|
||||
title="View diagram in new page"
|
||||
on:click|stopPropagation={() => viewDiagram()}><i class="far fa-eye" /> View</button>
|
||||
|
||||
|
||||
+4
-15
@@ -1,21 +1,10 @@
|
||||
const { tailwindExtractor } = require('tailwindcss/lib/lib/purgeUnusedStyles');
|
||||
|
||||
module.exports = {
|
||||
mode: 'aot',
|
||||
purge: {
|
||||
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||
options: {
|
||||
defaultExtractor: (content) => [
|
||||
// If this stops working, please open an issue at https://github.com/svelte-add/tailwindcss/issues rather than bothering Tailwind Labs about it
|
||||
...tailwindExtractor(content),
|
||||
// Match Svelte class: directives (https://github.com/tailwindlabs/tailwindcss/discussions/1731)
|
||||
...[...content.matchAll(/(?:class:)*([\w\d-/:%.]+)/gm)].map(
|
||||
([_match, group, ..._rest]) => group
|
||||
)
|
||||
]
|
||||
},
|
||||
safelist: [/^svelte-[\d\w]+$/]
|
||||
},
|
||||
mode: 'jit',
|
||||
darkMode: 'media',
|
||||
plugins: [require('daisyui')],
|
||||
purge: ['./src/**/*.{html,js,svelte,ts}'],
|
||||
theme: {
|
||||
extend: {}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user