fix: Resizing, card
This commit is contained in:
@@ -58,7 +58,9 @@
|
||||
"husky": "^8.0.3",
|
||||
"jsdom": "^25.0.1",
|
||||
"lint-staged": "^15.2.0",
|
||||
"lucide-svelte": "^0.477.0",
|
||||
"node-html-parser": "^6.1.5",
|
||||
"paneforge": "^1.0.0-next.4",
|
||||
"postcss": "^8.4.33",
|
||||
"postcss-load-config": "5.1.0",
|
||||
"prettier": "^3.1.0",
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
isOpen?: boolean;
|
||||
tabs?: Tab[];
|
||||
activeTabID?: string;
|
||||
title: string;
|
||||
title?: string;
|
||||
onselect?: (tab: Tab) => void;
|
||||
actions?: Snippet;
|
||||
children?: Snippet;
|
||||
@@ -35,11 +35,12 @@
|
||||
let isTabsShown = $derived(isOpen && tabs.length > 0);
|
||||
</script>
|
||||
|
||||
<div class="card m-2 flex flex-grow flex-col overflow-hidden rounded shadow-2xl">
|
||||
<div
|
||||
class="card flex h-fit {isOpen ? 'flex-grow' : ''} flex-col overflow-hidden rounded-2xl border-2">
|
||||
<div
|
||||
role="toolbar"
|
||||
tabindex="0"
|
||||
class="bg-primary p-2 {isTabsShown ? 'pb-0' : ''} flex-none cursor-pointer"
|
||||
class="bg-border p-2 {isTabsShown ? 'pb-0' : ''} flex-none cursor-pointer"
|
||||
onclick={toggleCardOpen}
|
||||
onkeypress={toggleCardOpen}>
|
||||
<div class="flex justify-between">
|
||||
@@ -50,7 +51,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{#if isOpen}
|
||||
<div class="card-body flex-grow overflow-auto p-0 text-base-content" transition:slide>
|
||||
<div class="card-body text-base-content flex-grow overflow-auto p-0" transition:slide>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
}: {
|
||||
isClosable?: boolean;
|
||||
tabs: Tab[];
|
||||
title: string;
|
||||
title?: string;
|
||||
isOpen?: boolean;
|
||||
activeTabID: string;
|
||||
onselect?: (tab: Tab) => void;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Pane } from "paneforge";
|
||||
import Handle from "./resizable-handle.svelte";
|
||||
import PaneGroup from "./resizable-pane-group.svelte";
|
||||
|
||||
export {
|
||||
PaneGroup,
|
||||
Pane,
|
||||
Handle,
|
||||
//
|
||||
PaneGroup as ResizablePaneGroup,
|
||||
Pane as ResizablePane,
|
||||
Handle as ResizableHandle,
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<script lang="ts">
|
||||
import GripVertical from "lucide-svelte/icons/grip-vertical";
|
||||
import * as ResizablePrimitive from "paneforge";
|
||||
import type { WithoutChildrenOrChild } from "bits-ui";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
withHandle = false,
|
||||
...restProps
|
||||
}: WithoutChildrenOrChild<ResizablePrimitive.PaneResizerProps> & {
|
||||
withHandle?: boolean;
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<ResizablePrimitive.PaneResizer
|
||||
bind:ref
|
||||
class={cn(
|
||||
"bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-offset-1 data-[direction=vertical]:h-px data-[direction=vertical]:w-full data-[direction=vertical]:after:left-0 data-[direction=vertical]:after:h-1 data-[direction=vertical]:after:w-full data-[direction=vertical]:after:-translate-y-1/2 data-[direction=vertical]:after:translate-x-0 [&[data-direction=vertical]>div]:rotate-90",
|
||||
className
|
||||
)}
|
||||
{...restProps}
|
||||
>
|
||||
{#if withHandle}
|
||||
<div class="bg-border z-10 flex h-4 w-3 items-center justify-center rounded-sm border">
|
||||
<GripVertical class="size-2.5" />
|
||||
</div>
|
||||
{/if}
|
||||
</ResizablePrimitive.PaneResizer>
|
||||
@@ -0,0 +1,22 @@
|
||||
<script lang="ts">
|
||||
import * as ResizablePrimitive from "paneforge";
|
||||
import { cn } from "$lib/utils.js";
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
class: className,
|
||||
direction,
|
||||
this: paneGroup = $bindable(),
|
||||
...restProps
|
||||
}: ResizablePrimitive.PaneGroupProps & {
|
||||
this?: ResizablePrimitive.PaneGroup;
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<ResizablePrimitive.PaneGroup
|
||||
bind:ref
|
||||
bind:this={paneGroup}
|
||||
{direction}
|
||||
class={cn("flex h-full w-full data-[direction=vertical]:flex-col", className)}
|
||||
{...restProps}
|
||||
/>
|
||||
+101
-113
@@ -6,6 +6,7 @@
|
||||
import History from '$lib/components/History/History.svelte';
|
||||
import Navbar from '$lib/components/Navbar.svelte';
|
||||
import Preset from '$lib/components/Preset.svelte';
|
||||
import * as Resizable from '$lib/components/ui/resizable/index.js';
|
||||
import View from '$lib/components/View.svelte';
|
||||
import type { DocumentationConfig, EditorMode, Tab, ValidatedState } from '$lib/types';
|
||||
import { env } from '$lib/util/env';
|
||||
@@ -115,130 +116,117 @@
|
||||
|
||||
onMount(async () => {
|
||||
await initHandler();
|
||||
const resizer = document.querySelector<HTMLElement>('#resizeHandler');
|
||||
const element = document.querySelector<HTMLElement>('#editorPane');
|
||||
if (!resizer || !element) {
|
||||
console.debug('Failed to find resize handler or editor pane', { resizer, element });
|
||||
return;
|
||||
}
|
||||
const resize = ({ pageX }: { pageX: number }) => {
|
||||
const newWidth = pageX - element.getBoundingClientRect().left;
|
||||
if (newWidth > 50) {
|
||||
element.style.width = `${newWidth}px`;
|
||||
}
|
||||
};
|
||||
|
||||
const stopResize = () => {
|
||||
window.removeEventListener('mousemove', resize);
|
||||
};
|
||||
resizer.addEventListener('mousedown', (event) => {
|
||||
event.preventDefault();
|
||||
window.addEventListener('mousemove', resize);
|
||||
window.addEventListener('mouseup', stopResize);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex h-full flex-col overflow-hidden">
|
||||
<Navbar />
|
||||
<div class="flex flex-1 overflow-hidden">
|
||||
<div class="hidden flex-col md:flex" id="editorPane" style="width: 40%">
|
||||
<Card onselect={tabSelectHandler} {tabs} isClosable={false} {activeTabID} title="Mermaid">
|
||||
{#snippet actions()}
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="form-control flex-row items-center">
|
||||
<label class="label cursor-pointer" for="autoSync">
|
||||
<span> Auto sync</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="toggle {$stateStore.autoSync ? 'btn-secondary' : 'toggle-primary'} ml-1"
|
||||
id="autoSync"
|
||||
bind:checked={$inputStateStore.autoSync} />
|
||||
</label>
|
||||
</div>
|
||||
<Resizable.PaneGroup direction="horizontal" class="p-2">
|
||||
<Resizable.Pane defaultSize={40}>
|
||||
<div class="hidden h-full flex-col gap-2 md:flex" id="editorPane">
|
||||
<Card onselect={tabSelectHandler} {tabs} isClosable={false} {activeTabID}>
|
||||
{#snippet actions()}
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="form-control flex-row items-center">
|
||||
<label class="label cursor-pointer" for="autoSync">
|
||||
<span> Auto sync</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="toggle {$stateStore.autoSync
|
||||
? 'btn-secondary'
|
||||
: 'toggle-primary'} ml-1"
|
||||
id="autoSync"
|
||||
bind:checked={$inputStateStore.autoSync} />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{#if !$stateStore.autoSync}
|
||||
<button
|
||||
class="btn btn-secondary btn-xs mr-1"
|
||||
title="Sync Diagram ({cmdKey} + Enter)"
|
||||
aria-label="Sync Diagram"
|
||||
data-cy="sync"
|
||||
onclick={syncDiagram}><i class="fas fa-sync"></i></button>
|
||||
{/if}
|
||||
{#if !$stateStore.autoSync}
|
||||
<button
|
||||
class="btn btn-secondary btn-xs mr-1"
|
||||
title="Sync Diagram ({cmdKey} + Enter)"
|
||||
aria-label="Sync Diagram"
|
||||
data-cy="sync"
|
||||
onclick={syncDiagram}><i class="fas fa-sync"></i></button>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
class="btn btn-secondary btn-xs"
|
||||
title="View documentation for {docKey.replace('Diagram', '')} diagram">
|
||||
<a target="_blank" href={docURL} data-cy="docs">
|
||||
<i class="fas fa-book mr-1"></i>Docs
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
{/snippet}
|
||||
<button
|
||||
class="btn btn-secondary btn-xs"
|
||||
title="View documentation for {docKey.replace('Diagram', '')} diagram">
|
||||
<a target="_blank" href={docURL} data-cy="docs">
|
||||
<i class="fas fa-book mr-1"></i>Docs
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
<Editor />
|
||||
</Card>
|
||||
<Editor />
|
||||
</Card>
|
||||
|
||||
<div class="-mt-2">
|
||||
<Preset />
|
||||
<History />
|
||||
<Actions />
|
||||
</div>
|
||||
</div>
|
||||
<div id="resizeHandler" class="hidden md:block"></div>
|
||||
<div class="flex flex-1 flex-col overflow-hidden">
|
||||
<Card title="Diagram" isClosable={false}>
|
||||
{#snippet actions()}
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<label
|
||||
class="label flex cursor-pointer gap-1 py-0"
|
||||
title="Rough mode is in beta. Features like clickable nodes, Pan & Zoom, will be disabled."
|
||||
for="rough">
|
||||
<span>Rough</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="toggle {$stateStore.rough ? 'btn-secondary' : 'toggle-primary'}"
|
||||
id="rough"
|
||||
bind:checked={$inputStateStore.rough} />
|
||||
</label>
|
||||
<label
|
||||
class="label flex cursor-pointer gap-1 py-0"
|
||||
title={$stateStore.rough ? 'Pan & Zoom is disabled in rough mode.' : ''}
|
||||
for="panZoom">
|
||||
<span>Pan & Zoom</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="toggle {$stateStore.panZoom ? 'btn-secondary' : 'toggle-primary'}"
|
||||
id="panZoom"
|
||||
disabled={$stateStore.rough}
|
||||
bind:checked={$inputStateStore.panZoom} />
|
||||
</label>
|
||||
<a
|
||||
href={`${base}/view#${$stateStore.serialized}`}
|
||||
target="_blank"
|
||||
class="btn btn-secondary btn-xs gap-1"
|
||||
title="View diagram in new page"
|
||||
><i class="fas fa-external-link-alt"></i>Full screen</a>
|
||||
{#if env.isEnabledMermaidChartLinks}
|
||||
<a
|
||||
href={`${MCBaseURL}/app/plugin/save?state=${$stateStore.serialized}`}
|
||||
target="_blank"
|
||||
class="btn btn-secondary btn-xs gap-1 bg-[#FF3570]"
|
||||
title="Save diagram in Mermaid Chart"
|
||||
><img src="./mermaidchart-logo.svg" class="h-5 w-5" alt="Mermaid chart logo" />Save
|
||||
to Mermaid Chart</a>
|
||||
{/if}
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
<div class="flex-1 overflow-auto">
|
||||
<View />
|
||||
<Preset />
|
||||
<History />
|
||||
<Actions />
|
||||
</div>
|
||||
</Card>
|
||||
<div class="mx-2 rounded p-2 shadow md:hidden">
|
||||
Code editing not supported on mobile. Please use a desktop browser.
|
||||
</div>
|
||||
</div>
|
||||
</Resizable.Pane>
|
||||
<Resizable.Handle class="mx-2" />
|
||||
<Resizable.Pane>
|
||||
<div class="flex h-full flex-1 flex-col overflow-hidden">
|
||||
<Card title="Diagram" isClosable={false}>
|
||||
{#snippet actions()}
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<label
|
||||
class="label flex cursor-pointer gap-1 py-0"
|
||||
title="Rough mode is in beta. Features like clickable nodes, Pan & Zoom, will be disabled."
|
||||
for="rough">
|
||||
<span>Rough</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="toggle {$stateStore.rough ? 'btn-secondary' : 'toggle-primary'}"
|
||||
id="rough"
|
||||
bind:checked={$inputStateStore.rough} />
|
||||
</label>
|
||||
<label
|
||||
class="label flex cursor-pointer gap-1 py-0"
|
||||
title={$stateStore.rough ? 'Pan & Zoom is disabled in rough mode.' : ''}
|
||||
for="panZoom">
|
||||
<span>Pan & Zoom</span>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="toggle {$stateStore.panZoom ? 'btn-secondary' : 'toggle-primary'}"
|
||||
id="panZoom"
|
||||
disabled={$stateStore.rough}
|
||||
bind:checked={$inputStateStore.panZoom} />
|
||||
</label>
|
||||
<a
|
||||
href={`${base}/view#${$stateStore.serialized}`}
|
||||
target="_blank"
|
||||
class="btn btn-secondary btn-xs gap-1"
|
||||
title="View diagram in new page"
|
||||
><i class="fas fa-external-link-alt"></i>Full screen</a>
|
||||
{#if env.isEnabledMermaidChartLinks}
|
||||
<a
|
||||
href={`${MCBaseURL}/app/plugin/save?state=${$stateStore.serialized}`}
|
||||
target="_blank"
|
||||
class="btn btn-secondary btn-xs gap-1 bg-[#FF3570]"
|
||||
title="Save diagram in Mermaid Chart"
|
||||
><img
|
||||
src="./mermaidchart-logo.svg"
|
||||
class="size-5"
|
||||
alt="Mermaid chart logo" />Save to Mermaid Chart</a>
|
||||
{/if}
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
<div class="flex-1 overflow-auto">
|
||||
<View />
|
||||
</div>
|
||||
</Card>
|
||||
<div class="mx-2 rounded p-2 shadow md:hidden">
|
||||
Code editing not supported on mobile. Please use a desktop browser.
|
||||
</div>
|
||||
</div>
|
||||
</Resizable.Pane>
|
||||
</Resizable.PaneGroup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -4459,6 +4459,11 @@ lru-cache@^6.0.0:
|
||||
dependencies:
|
||||
yallist "^4.0.0"
|
||||
|
||||
lucide-svelte@^0.477.0:
|
||||
version "0.477.0"
|
||||
resolved "https://registry.yarnpkg.com/lucide-svelte/-/lucide-svelte-0.477.0.tgz#85d80c9a7787b4b3ff8f5faed2f41182c8c4e303"
|
||||
integrity sha512-w/zj6/CXTtTizIeo8SuWGYu0u45CJ7cD2AtNzIObVHZrWXNgaIIX/2cI25wybjSmYHIi4pub2TLv/kNPKiB3ww==
|
||||
|
||||
lz-string@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941"
|
||||
@@ -4900,6 +4905,13 @@ pako@2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86"
|
||||
integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==
|
||||
|
||||
paneforge@^1.0.0-next.4:
|
||||
version "1.0.0-next.4"
|
||||
resolved "https://registry.yarnpkg.com/paneforge/-/paneforge-1.0.0-next.4.tgz#99887329c5cab35b83beac2700540a7b765a62cf"
|
||||
integrity sha512-xB7iqIx6sT+XDRx/Eps+lddN3X7zRy8RIqXXFimGuFF6d+3s4YoXrk8SdNwEK5U/mqwupeKX0BbSfy0z9W9feA==
|
||||
dependencies:
|
||||
svelte-toolbelt "^0.7.1"
|
||||
|
||||
parent-module@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
|
||||
|
||||
Reference in New Issue
Block a user