feat: a little more useable on mobile
This commit is contained in:
parent
b7fe539cf0
commit
5488352514
3 changed files with 68 additions and 37 deletions
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
@theme {
|
||||
--radius: 2px;
|
||||
--radius-lg: 4px;
|
||||
--radius-full: 9999px;
|
||||
}
|
||||
|
||||
:root {
|
||||
--bg: #fafafa;
|
||||
--bg-card: #ffffff;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { Sun, Moon, Share2, Check, Trash2 } from 'lucide-svelte';
|
||||
import { Sun, Moon, Share2, Check, Trash2, Plus } from 'lucide-svelte';
|
||||
import { theme } from '$lib/theme.svelte';
|
||||
import { roster } from '$lib/state.svelte';
|
||||
import { presets } from '$lib/presets';
|
||||
|
|
@ -40,23 +40,30 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<header class="flex items-center gap-2 px-4 py-3 border-b shrink-0" style="border-color: var(--border); background: var(--bg-card);">
|
||||
<header class="border-b shrink-0" style="border-color: var(--border); background: var(--bg-card);">
|
||||
<div class="flex items-center gap-2 px-4 py-3 max-w-7xl mx-auto w-full">
|
||||
<h1 class="font-bold whitespace-nowrap">Aurora Records</h1>
|
||||
|
||||
{#if roster.characters.length > 0}
|
||||
<CharacterSwitcher />
|
||||
{/if}
|
||||
|
||||
<button onclick={share} class="flex items-center justify-center w-[30px] h-[30px] rounded border hover:opacity-80" style="border-color: var(--border);" title="Share character">
|
||||
<button onclick={createCharacter} class="flex items-center justify-center w-[30px] h-[30px] rounded border hover:opacity-80" style="border-color: var(--border);" title="New character">
|
||||
<Plus size={14} />
|
||||
</button>
|
||||
|
||||
{#if roster.characters.length > 0}
|
||||
<button onclick={() => { confirmDelete = true; }} class="flex items-center justify-center w-[30px] h-[30px] rounded border hover:opacity-80" style="border-color: var(--border);" title="Delete character">
|
||||
<Trash2 size={14} />
|
||||
</button>
|
||||
|
||||
<button onclick={share} class="flex items-center justify-center h-[30px] rounded border hover:opacity-80 {shared ? 'gap-1 px-2' : 'w-[30px]'}" style="border-color: var(--border);" title="Share character">
|
||||
{#if shared}
|
||||
<Check size={14} />
|
||||
<Check size={14} /> <span class="text-sm hidden sm:inline">Copied share link</span>
|
||||
{:else}
|
||||
<Share2 size={14} />
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<button onclick={() => { confirmDelete = true; }} class="flex items-center justify-center w-[30px] h-[30px] rounded border hover:opacity-80" style="border-color: var(--border);" title="Delete character">
|
||||
<Trash2 size={14} />
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<div class="ml-auto flex items-center gap-2">
|
||||
|
|
@ -64,14 +71,6 @@
|
|||
{#if roster.saveStatus === 'saving'}Saving...{:else if roster.saveStatus === 'saved'}Saved{/if}
|
||||
</span>
|
||||
|
||||
<button
|
||||
onclick={createCharacter}
|
||||
class="px-3 h-[30px] rounded text-sm border hover:opacity-80"
|
||||
style="border-color: var(--border);"
|
||||
>
|
||||
New Character
|
||||
</button>
|
||||
|
||||
<button onclick={() => theme.toggle()} class="flex items-center justify-center w-[30px] h-[30px] rounded hover:opacity-80" title="Toggle theme">
|
||||
{#if theme.dark}
|
||||
<Sun size={18} />
|
||||
|
|
@ -80,6 +79,7 @@
|
|||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{#if confirmDelete && roster.active}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { Eye, PenLine } from 'lucide-svelte';
|
||||
import Header from '$lib/components/Header.svelte';
|
||||
import SchemaForm from '$lib/components/SchemaForm.svelte';
|
||||
import OutputPanel from '$lib/components/OutputPanel.svelte';
|
||||
|
|
@ -9,7 +8,7 @@
|
|||
import { presets } from '$lib/presets';
|
||||
|
||||
let importData = $state<string | null>(null);
|
||||
let mobileView = $state<'form' | 'preview'>('form');
|
||||
let mobileView = $state<'edit' | 'preview' | 'split'>('split');
|
||||
|
||||
onMount(() => {
|
||||
const hash = window.location.hash.slice(1);
|
||||
|
|
@ -22,6 +21,8 @@
|
|||
importData = null;
|
||||
history.replaceState(null, '', window.location.pathname);
|
||||
}
|
||||
|
||||
const modes = ['edit', 'preview', 'split'] as const;
|
||||
</script>
|
||||
|
||||
<div class="h-dvh flex flex-col overflow-hidden">
|
||||
|
|
@ -33,29 +34,53 @@
|
|||
</div>
|
||||
{:else if roster.active}
|
||||
{@const char = roster.active}
|
||||
<main class="flex-1 grid grid-cols-1 lg:grid-cols-[1fr_1fr] overflow-hidden relative">
|
||||
<div class="overflow-y-auto p-4 {mobileView === 'preview' ? 'hidden lg:block' : ''}">
|
||||
<div class="max-w-xl mx-auto">
|
||||
|
||||
<div class="flex items-center justify-center gap-0 py-1 shrink-0 border-b md:hidden" style="border-color: var(--border); background: var(--bg-card);">
|
||||
{#each modes as mode}
|
||||
<button
|
||||
onclick={() => { mobileView = mode; }}
|
||||
class="px-3 py-0.5 text-sm capitalize"
|
||||
style={mobileView === mode
|
||||
? 'color: var(--text); font-weight: 500;'
|
||||
: 'color: var(--text-muted);'}
|
||||
>
|
||||
{mode}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<!-- Desktop: always side-by-side -->
|
||||
<main class="flex-1 hidden md:grid md:grid-cols-[1fr_1fr] overflow-hidden max-w-7xl mx-auto w-full">
|
||||
<div class="overflow-y-auto p-4">
|
||||
<SchemaForm character={char} />
|
||||
</div>
|
||||
<div class="p-4 min-h-0 flex flex-col">
|
||||
<OutputPanel character={char} />
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Mobile: view mode toggle -->
|
||||
<main class="flex-1 flex flex-col overflow-hidden md:hidden">
|
||||
{#if mobileView === 'edit'}
|
||||
<div class="flex-1 overflow-y-auto p-4">
|
||||
<div class="md:max-w-xl md:mx-auto">
|
||||
<SchemaForm character={char} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4 min-h-0 flex flex-col {mobileView === 'form' ? 'hidden lg:flex' : ''}">
|
||||
{:else if mobileView === 'preview'}
|
||||
<div class="flex-1 p-4 min-h-0 flex flex-col">
|
||||
<OutputPanel character={char} />
|
||||
</div>
|
||||
|
||||
<div class="fixed bottom-4 right-4 lg:hidden z-10">
|
||||
<button
|
||||
onclick={() => { mobileView = mobileView === 'form' ? 'preview' : 'form'; }}
|
||||
class="flex items-center gap-2 px-3 py-2 rounded-full shadow-lg text-sm"
|
||||
style="background: var(--bg-card); border: 1px solid var(--border); color: var(--text);"
|
||||
>
|
||||
{#if mobileView === 'form'}
|
||||
<Eye size={16} /> Preview
|
||||
{:else}
|
||||
<PenLine size={16} /> Edit
|
||||
{/if}
|
||||
</button>
|
||||
<div class="flex-1 overflow-y-auto p-4">
|
||||
<div class="md:max-w-xl md:mx-auto">
|
||||
<SchemaForm character={char} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-[50%] shrink-0 p-4 min-h-0 flex flex-col border-t" style="border-color: var(--border);">
|
||||
<OutputPanel character={char} />
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
{:else}
|
||||
<main class="flex-1 flex flex-col items-center justify-center gap-4">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue