feature/responsive #22
@@ -1,7 +1,4 @@
|
||||
export {
|
||||
SetupFontMenu,
|
||||
TypographyMenu,
|
||||
} from './ui';
|
||||
export { TypographyMenu } from './ui';
|
||||
|
||||
export {
|
||||
type ControlId,
|
||||
@@ -20,6 +17,9 @@ export {
|
||||
MIN_FONT_SIZE,
|
||||
MIN_FONT_WEIGHT,
|
||||
MIN_LINE_HEIGHT,
|
||||
MULTIPLIER_L,
|
||||
MULTIPLIER_M,
|
||||
MULTIPLIER_S,
|
||||
} from './model';
|
||||
|
||||
export {
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
<!--
|
||||
Component: SetupFontMenu
|
||||
Contains controls for setting up font properties.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { ResponsiveManager } from '$shared/lib';
|
||||
import { ComboControl } from '$shared/ui';
|
||||
import { getContext } from 'svelte';
|
||||
import { controlManager } from '../model';
|
||||
const responsive = getContext<ResponsiveManager>('responsive');
|
||||
|
||||
$effect(() => {
|
||||
if (!responsive) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case responsive.isMobile:
|
||||
controlManager.multiplier = 0.5;
|
||||
break;
|
||||
case responsive.isTablet:
|
||||
controlManager.multiplier = 0.75;
|
||||
break;
|
||||
case responsive.isDesktop:
|
||||
controlManager.multiplier = 1;
|
||||
break;
|
||||
default:
|
||||
controlManager.multiplier = 1;
|
||||
break;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="sm:py-2 sm:px-10 flex flex-row items-center gap-2">
|
||||
<div class="flex flex-row gap-3">
|
||||
{#each controlManager.controls as control (control.id)}
|
||||
<ComboControl
|
||||
control={control.instance}
|
||||
increaseLabel={control.increaseLabel}
|
||||
decreaseLabel={control.decreaseLabel}
|
||||
controlLabel={control.controlLabel}
|
||||
reduced={responsive.isMobile}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,41 +1,121 @@
|
||||
<!--
|
||||
Component: TypographyMenu
|
||||
Provides a menu for selecting and configuring typography settings
|
||||
- On mobile the menu is displayed as a drawer
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { SetupFontMenu } from '$features/SetupFont';
|
||||
import type { ResponsiveManager } from '$shared/lib';
|
||||
import {
|
||||
Content as ItemContent,
|
||||
Root as ItemRoot,
|
||||
} from '$shared/shadcn/ui/item';
|
||||
|
||||
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
||||
import {
|
||||
ComboControl,
|
||||
ComboControlV2,
|
||||
Drawer,
|
||||
IconButton,
|
||||
} from '$shared/ui';
|
||||
import SlidersIcon from '@lucide/svelte/icons/sliders-vertical';
|
||||
import { getContext } from 'svelte';
|
||||
import { cubicOut } from 'svelte/easing';
|
||||
import { crossfade } from 'svelte/transition';
|
||||
import {
|
||||
MULTIPLIER_L,
|
||||
MULTIPLIER_M,
|
||||
MULTIPLIER_S,
|
||||
controlManager,
|
||||
} from '../model';
|
||||
|
||||
interface Props {
|
||||
class?: string;
|
||||
}
|
||||
|
||||
const { class: className }: Props = $props();
|
||||
const responsive = getContext<ResponsiveManager>('responsive');
|
||||
|
||||
const [send, receive] = crossfade({
|
||||
duration: 400,
|
||||
duration: 300,
|
||||
easing: cubicOut,
|
||||
fallback(node, params) {
|
||||
// If it can't find a pair, it falls back to a simple fade/slide
|
||||
return {
|
||||
duration: 400,
|
||||
duration: 300,
|
||||
css: t => `opacity: ${t}; transform: translateY(${(1 - t) * 10}px);`,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Sets the common font size multiplier based on the current responsive state.
|
||||
*/
|
||||
$effect(() => {
|
||||
if (!responsive) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case responsive.isMobile:
|
||||
controlManager.multiplier = MULTIPLIER_S;
|
||||
break;
|
||||
case responsive.isTablet:
|
||||
controlManager.multiplier = MULTIPLIER_M;
|
||||
break;
|
||||
case responsive.isDesktop:
|
||||
controlManager.multiplier = MULTIPLIER_L;
|
||||
break;
|
||||
default:
|
||||
controlManager.multiplier = MULTIPLIER_L;
|
||||
break;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="w-auto fixed bottom-4 sm:bottom-5 left-4 right-4 sm:left-1/2 sm:right-[unset] sm:-translate-x-1/2 sm:inset-x-0 max-screen z-10 flex justify-center"
|
||||
class={cn('w-auto max-screen z-10 flex justify-center', className)}
|
||||
in:receive={{ key: 'panel' }}
|
||||
out:send={{ key: 'panel' }}
|
||||
>
|
||||
{#if responsive.isMobile}
|
||||
<Drawer>
|
||||
{#snippet trigger({ onClick })}
|
||||
<IconButton onclick={onClick}>
|
||||
{#snippet icon({ className })}
|
||||
<SlidersIcon class={className} />
|
||||
{/snippet}
|
||||
</IconButton>
|
||||
{/snippet}
|
||||
{#snippet content()}
|
||||
<div class="flex flex-col gap-6 px-2 py-4">
|
||||
{#each controlManager.controls as control (control.id)}
|
||||
<ComboControlV2
|
||||
control={control.instance}
|
||||
orientation="horizontal"
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
{/snippet}
|
||||
</Drawer>
|
||||
{:else}
|
||||
<ItemRoot
|
||||
variant="outline"
|
||||
class="w-full sm:w-auto max-w-full sm:max-w-max p-2 sm:p-2.5 rounded-xl sm:rounded-2xl backdrop-blur-lg"
|
||||
>
|
||||
<ItemContent class="flex flex-row justify-center items-center max-w-full sm:max-w-max">
|
||||
<SetupFontMenu />
|
||||
<div class="sm:py-2 sm:px-10 flex flex-row items-center gap-2">
|
||||
<div class="flex flex-row gap-3">
|
||||
{#each controlManager.controls as control (control.id)}
|
||||
<ComboControl
|
||||
control={control.instance}
|
||||
increaseLabel={control.increaseLabel}
|
||||
decreaseLabel={control.decreaseLabel}
|
||||
controlLabel={control.controlLabel}
|
||||
reduced={responsive.isMobile}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</ItemContent>
|
||||
</ItemRoot>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
export { default as SetupFontMenu } from './SetupFontMenu.svelte';
|
||||
export { default as TypographyMenu } from './TypographyMenu.svelte';
|
||||
|
||||
@@ -102,6 +102,6 @@ function checkPosition() {
|
||||
</FontVirtualList>
|
||||
|
||||
{#if isAboveMiddle}
|
||||
<TypographyMenu />
|
||||
<TypographyMenu class="fixed bottom-4 sm:bottom-5 right-4 sm:left-1/2 sm:right-[unset] sm:-translate-x-1/2" />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user