Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
}
}
],
"tailwindStylesheet": "./src/routes/layout.css"
"tailwindStylesheet": "./src/app.css"
}
40 changes: 25 additions & 15 deletions src/routes/[page]/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<script>
import { setContext } from 'svelte';
import { page } from '$app/stores';
import { Svedit, KeyMapper, Command, define_keymap } from 'svedit';
import { create_session } from '../create_session.js';
let { data } = $props();
let session = $derived(create_session(data.doc));

let app_el;
let svedit_ref;
let app_el = $state();
let svedit_ref = $state();
let editable = $state(true);

function focus_canvas() {
Expand Down Expand Up @@ -78,19 +79,28 @@
<title>Editable Website v2</title>
</svelte:head>

<div class="demo-wrapper" bind:this={app_el}>
<!-- <Toolbar {session} {focus_canvas} bind:editable /> -->
<Svedit {session} bind:editable bind:this={svedit_ref} path={[session.doc.document_id]} />

{#if editable}
<div class="flex-column mx-auto my-10 w-full max-w-5xl gap-y-2">
<p>Selection:</p>
<pre class="debug-info p-4">{JSON.stringify(session.selection || {}, null, ' ')}</pre>
<p>Nodes:</p>
<pre class="debug-info p-4">{JSON.stringify(session.to_json(), null, ' ')}</pre>
</div>
{/if}
</div>
<!--
BUG: When navigating from / with preloading on the Svedit component ends up
with a stale session, breaking editing.
See https://github.com/michael/editable-website/issues/40
-->

<!-- Workaround for #40: Note that page.url.pathname from $app/state does not work -->
{#key $page.url.pathname}
<div class="demo-wrapper" bind:this={app_el}>
<!-- <Toolbar {session} {focus_canvas} bind:editable /> -->
<Svedit {session} bind:editable bind:this={svedit_ref} path={[session.doc.document_id]} />

{#if editable}
<div class="flex-column mx-auto my-10 w-full max-w-5xl gap-y-2">
<p>Selection:</p>
<pre class="debug-info p-4">{JSON.stringify(session.selection || {}, null, ' ')}</pre>
<p>Nodes:</p>
<pre class="debug-info p-4">{JSON.stringify(session.to_json(), null, ' ')}</pre>
</div>
{/if}
</div>
{/key}

<style>
.debug-info {
Expand Down
186 changes: 103 additions & 83 deletions src/routes/components/Feature.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
let is_selected = $derived(is_image_selected());

const TITLE_PLACEHOLDER = 'MODULUS MATRIX - 85 Social housing in Cornellà Cornellà 2021';
const DESCRIPTION_PLACEHOLDER = 'Para los 10.000 m2 de superficie edificada del nuevo edificio ubicado en Cornellà de Llobregat (Barcelona), que consta de 85 viviendas sociales distribuidas en 5 alturas, se han utilizado un total de 8.300 m2 de madera KM0 procedente del País Vasco.
El diseño de una matriz de habitaciones comunicantes, que elimina pasillos para garantizar el máximo aprovechamiento en planta, y el uso de la madera en favor de las posibilidades de industrialización del edificio, la mejora de la calidad de la construcción y la notable reducción de los plazos de ejecución y las emisiones de C02, son los ejes de este nuevo edificio de viviendas.';
const DESCRIPTION_PLACEHOLDER =
'Para los 10.000 m2 de superficie edificada del nuevo edificio ubicado en Cornellà de Llobregat (Barcelona), que consta de 85 viviendas sociales distribuidas en 5 alturas, se han utilizado un total de 8.300 m2 de madera KM0 procedente del País Vasco.
El diseño de una matriz de habitaciones comunicantes, que elimina pasillos para garantizar el máximo aprovechamiento en planta, y el uso de la madera en favor de las posibilidades de industrialización del edificio, la mejora de la calidad de la construcción y la notable reducción de los plazos de ejecución y las emisiones de C02, son los ejes de este nuevo edificio de viviendas.';

function is_image_selected() {
const path_of_selection = svedit?.session?.selection?.path?.join('.');
Expand All @@ -21,121 +22,140 @@

<!-- Primitives -->
{#snippet image(aspect_ratio)}
<CustomProperty class="ew-image-property" path={[...path, 'image']}>
<div
contenteditable="false"
style:aspect-ratio={aspect_ratio}
class="ew-image-wrapper h-full w-full overflow-hidden select-none"
class:ew-bg-checkerboard={is_selected || !image_node.src}
>
<Image path={[...path, 'image']} />
</div>
</CustomProperty>
<CustomProperty class="ew-image-property" path={[...path, 'image']}>
<div
contenteditable="false"
style:aspect-ratio={aspect_ratio}
class="ew-image-wrapper h-full w-full overflow-hidden select-none"
class:ew-bg-checkerboard={is_selected || !image_node.src}
>
<Image path={[...path, 'image']} />
</div>
</CustomProperty>
{/snippet}

{#snippet big_title()}
<AnnotatedTextProperty tag="h1" class="text-4xl font-bold" path={[...path, 'title']} placeholder={TITLE_PLACEHOLDER} />
<AnnotatedTextProperty
tag="h1"
class="text-4xl text-balance"
path={[...path, 'title']}
placeholder={TITLE_PLACEHOLDER}
/>
{/snippet}

{#snippet small_title()}
<AnnotatedTextProperty tag="h1" class="text-xl uppercase" path={[...path, 'title']} placeholder={TITLE_PLACEHOLDER} />
<AnnotatedTextProperty
tag="h1"
class="text-xl text-balance uppercase"
path={[...path, 'title']}
placeholder={TITLE_PLACEHOLDER}
/>
{/snippet}

{#snippet description()}
<AnnotatedTextProperty tag="p" class="text-gray-600" path={[...path, 'description']} placeholder={DESCRIPTION_PLACEHOLDER} />
<AnnotatedTextProperty
tag="p"
class="text-gray-600"
path={[...path, 'description']}
placeholder={DESCRIPTION_PLACEHOLDER}
/>
{/snippet}

<!-- Layouts -->
{#snippet layout_1()}
<div class="mx-auto max-w-7xl grid grid-cols-2">
<div class="flex flex-col p-15">
{@render big_title()}
<div class="flex-1"></div>
{@render description()}
</div>
<div class="p-15">
{@render image(3/4)}
</div>
</div>
<!-- Limiter -->
<div class="mx-auto max-w-7xl xl:px-8">
<div class="grid grid-cols-1 md:grid-cols-2 xl:border-r xl:border-l">
<div class="flex flex-col p-5 sm:p-8 md:p-11 lg:p-14">
<div class="max-md:pt-6">{@render big_title()}</div>
<div class="flex-1" contenteditable="false"></div>
<div class="max-md:pt-16 max-md:pb-6 max-md:pl-16">
{@render description()}
</div>
</div>
<!-- Separator line, only visible on mobile -->
<!-- <div class="ml-5 sm:ml-8 border-t md:hidden" contenteditable="false"></div> -->
<div class="p-5 sm:p-8 md:border-l md:p-11 lg:p-14">
{@render image(3 / 4)}
</div>
</div>
</div>
{/snippet}

<!-- Like layout 1 but flipped horizontally -->
{#snippet layout_2()}
<div class="mx-auto max-w-7xl grid grid-cols-2">
<div class="p-15">
{@render image(3/4)}
</div>
<div class="flex flex-col p-15">
{@render big_title()}
<div class="flex-1"></div>
{@render description()}
</div>
</div>
<!-- Limiter -->
<div class="mx-auto max-w-7xl xl:px-8">
<div class="grid grid-cols-2 xl:border-r xl:border-l">
<div class="border-r p-15">
{@render image(3 / 4)}
</div>
<div class="flex flex-col p-15">
{@render big_title()}
<div class="flex-1" contenteditable="false"></div>
{@render description()}
</div>
</div>
</div>
{/snippet}

<!-- Like layout 1 but image stretches to edges -->
{#snippet layout_3()}
<div class="mx-auto max-w-7xl grid grid-cols-2">
<div>
{@render image(3/4)}
</div>
<div class="flex flex-col p-15">
{@render big_title()}
<div class="flex-1"></div>
{@render description()}
</div>
</div>
<div class="mx-auto grid max-w-7xl grid-cols-2">
<div>
{@render image(3 / 4)}
</div>
<div class="flex flex-col p-15">
{@render big_title()}
<div class="flex-1" contenteditable="false"></div>
{@render description()}
</div>
</div>
{/snippet}

<!-- Like layout 2 but, but image stretches to edges -->
{#snippet layout_4()}
<div class="mx-auto max-w-7xl grid grid-cols-2">
<div class="flex flex-col p-15">
{@render big_title()}
<div class="flex-1"></div>
{@render description()}
</div>
<div>
{@render image(3/4)}
</div>
</div>
<div class="mx-auto grid max-w-7xl grid-cols-2">
<div class="flex flex-col p-15">
{@render big_title()}
<div class="flex-1" contenteditable="false"></div>
{@render description()}
</div>
<div>
{@render image(3 / 4)}
</div>
</div>
{/snippet}

<!-- Like layout 1 but title (small) + description aligned at top -->
{#snippet layout_5()}
<div class="mx-auto max-w-7xl grid grid-cols-2">
<div class="flex flex-col p-15">
<div class="flex-1"></div>
{@render small_title()}
<div class="pt-4">{@render description()}</div>
</div>
<div class="p-15">
{@render image(3/4)}
</div>
</div>
<div class="mx-auto grid max-w-7xl grid-cols-2">
<div class="flex flex-col p-15">
<div class="flex-1" contenteditable="false"></div>
{@render small_title()}
<div class="pt-4">{@render description()}</div>
</div>
<div class="p-15">
{@render image(3 / 4)}
</div>
</div>
{/snippet}

<!-- Like layout 2 but title (small) + description aligned at bottom -->
{#snippet layout_6()}
<div class="mx-auto max-w-7xl grid grid-cols-2">
<div class="p-15">
{@render image(3/4)}
</div>
<div class="flex flex-col p-15">
{@render small_title()}
<div class="pt-4">{@render description()}</div>
<div class="flex-1"></div>
</div>
</div>
<div class="mx-auto grid max-w-7xl grid-cols-2">
<div class="p-15">
{@render image(3 / 4)}
</div>
<div class="flex flex-col p-15">
{@render small_title()}
<div class="pt-4">{@render description()}</div>
<div class="flex-1" contenteditable="false"></div>
</div>
</div>
{/snippet}

<Node class="ew-feature" {path}>
{@const layouts = [
layout_1,
layout_2,
layout_3,
layout_4,
layout_5,
layout_6]}
{@render layouts[node.layout - 1]()}
<Node class="ew-feature border-t" {path}>
{@const layouts = [layout_1, layout_2, layout_3, layout_4, layout_5, layout_6]}
{@render layouts[node.layout - 1]()}
</Node>
60 changes: 60 additions & 0 deletions src/routes/components/Heading.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<script>
import { getContext } from 'svelte';
import { Node, AnnotatedTextProperty } from 'svedit';

const svedit = getContext('svedit');
let { path } = $props();
let node = $derived(svedit.session.get(path));
let layout = $derived(node.layout || 1);
let tag = $derived(get_tag(layout));
let text_style = $derived(get_text_style(layout));
let placeholder = $derived(get_placeholder(layout));

function get_tag(layout) {
switch (layout) {
case 1:
return 'h1';
case 2:
return 'h2';
case 3:
return 'h3';
default:
return 'h2';
}
}

function get_text_style(layout) {
switch (layout) {
case 1:
return 'text-4xl pt-20 pb-4 text-balance';
case 2:
return 'text-3xl pt-10 pb-4 text-balance';
case 3:
return 'text-2xl pt-6 pb-4 text-balance';
default:
return 'text-3xl text-balance';
}
}

function get_placeholder(layout) {
switch (layout) {
case 1:
return 'Heading 1';
case 2:
return 'Heading 2';
case 3:
return 'Heading 3';
default:
return 'Heading';
}
}
</script>

<Node {path}>
<AnnotatedTextProperty
{tag}
class={text_style}
path={[...path, 'content']}
{placeholder}
/>
</Node>
2 changes: 1 addition & 1 deletion src/routes/components/Nav.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<Node {path}>
<div class="">
<div class="nav mx-auto w-full max-w-5xl py-6 pb-12">
<div class="nav mx-auto w-full max-w-7xl py-6 pb-12">
<NodeArrayProperty class="nav-items flex flex-wrap" path={[...path, 'nav_items']} />
</div>
</div>
Expand Down
17 changes: 17 additions & 0 deletions src/routes/components/Paragraph.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script>
import { getContext } from 'svelte';
import { Node, AnnotatedTextProperty } from 'svedit';

const svedit = getContext('svedit');
let { path } = $props();
let node = $derived(svedit.session.get(path));
</script>

<Node {path}>
<AnnotatedTextProperty
tag="p"
class="py-4"
path={[...path, 'content']}
placeholder="Paragraph"
/>
</Node>
Loading