You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
1.3 KiB
50 lines
1.3 KiB
|
5 months ago
|
<script lang="ts">
|
||
|
|
/**
|
||
|
|
* Eidos `<Float>` — pulls its child to the start or end of the text
|
||
|
|
* flow so adjacent inline content wraps around it. Composes through
|
||
|
|
* `<Box>` and writes a `--float-side` / `--float-gap` pair that the
|
||
|
|
* recipe consumes via `float: inline-{start | end}` + a logical
|
||
|
|
* margin against the text. Typical uses: inline images, pull-quotes,
|
||
|
|
* drop caps.
|
||
|
|
*
|
||
|
|
* <p>
|
||
|
|
* <Float side="start" maxWidth={120}>
|
||
|
|
* <img src="…" alt="…" />
|
||
|
|
* </Float>
|
||
|
|
* Long paragraph that wraps around the float…
|
||
|
|
* </p>
|
||
|
|
*/
|
||
|
|
import { ActiveEidos } from '$uix/eidos';
|
||
|
|
import Box from '../box/box.svelte';
|
||
|
|
import { composeStyle, formatLayoutSpace, pushStyleVar } from '../_layout/shared';
|
||
|
|
import type { FloatProps } from './types';
|
||
|
|
|
||
|
|
let {
|
||
|
|
side = 'start',
|
||
|
|
gap = 3,
|
||
|
|
style,
|
||
|
|
class: className,
|
||
|
|
children,
|
||
|
|
...restProps
|
||
|
|
}: FloatProps = $props();
|
||
|
|
|
||
|
|
const eidos = ActiveEidos.require();
|
||
|
|
|
||
|
|
const resolvedSide = $derived(eidos.resolve(side) ?? 'start');
|
||
|
|
const resolvedStyle = $derived.by(() => {
|
||
|
|
const decls: string[] = [];
|
||
|
|
pushStyleVar(decls, '--float-gap', formatLayoutSpace(eidos.resolve(gap)));
|
||
|
|
return composeStyle(decls, style);
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<Box
|
||
|
|
{...restProps}
|
||
|
|
class={className}
|
||
|
|
style={resolvedStyle}
|
||
|
|
data-float=""
|
||
|
|
data-side={resolvedSide}
|
||
|
|
>
|
||
|
|
{@render children?.()}
|
||
|
|
</Box>
|