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.
77 lines
2.5 KiB
77 lines
2.5 KiB
<script lang="ts">
|
|
import { ActiveEidos } from '$uix/eidos';
|
|
import { composeInlineStyle } from '$uix/eidos/lib/style';
|
|
import PopoverContent from '../popover/popover-content.svelte';
|
|
import { getDateRangePickerVisualContext } from './context.svelte';
|
|
import type { DateRangePickerContentProps } from './types';
|
|
|
|
let {
|
|
size,
|
|
align = 'end',
|
|
sideOffset = 6,
|
|
collisionPadding = 12,
|
|
width,
|
|
minWidth,
|
|
maxWidth,
|
|
style,
|
|
children: bodyContent,
|
|
...rest
|
|
}: DateRangePickerContentProps = $props();
|
|
|
|
const eidos = ActiveEidos.require();
|
|
const visual = getDateRangePickerVisualContext();
|
|
const resolvedSize = $derived(eidos.resolve(size ?? visual?.getSize() ?? 'md', 'md'));
|
|
// Popover doesn't have an `xs` chrome variant — clamp to `sm` so the
|
|
// popover surface stays consistent while the calendar inside still
|
|
// renders at xs via [data-date-range-picker][data-size='xs'].
|
|
const popoverSize = $derived(resolvedSize === 'xs' ? 'sm' : resolvedSize);
|
|
|
|
function serializeLength(value: string | number | undefined): string | undefined {
|
|
if (value === undefined) return undefined;
|
|
if (typeof value === 'number') return Number.isFinite(value) ? `${value}px` : undefined;
|
|
const trimmed = value.trim();
|
|
return trimmed || undefined;
|
|
}
|
|
|
|
function dimensionVar(name: string, value: string | number | undefined): string | undefined {
|
|
const serialized = serializeLength(value);
|
|
return serialized ? `${name}: ${serialized};` : undefined;
|
|
}
|
|
|
|
function resolveLength(value: typeof width, fallback: string): string | number | undefined {
|
|
const resolved = eidos.resolve(value);
|
|
if (typeof resolved === 'string' || typeof resolved === 'number') return resolved;
|
|
if (typeof value === 'string' || typeof value === 'number') return value;
|
|
return fallback;
|
|
}
|
|
|
|
const dimensionsStyle = $derived(
|
|
[
|
|
dimensionVar('--_popover-content-width-override', resolveLength(width, 'max-content')),
|
|
dimensionVar('--_popover-content-min-width-override', resolveLength(minWidth, 'max-content')),
|
|
dimensionVar(
|
|
'--_popover-content-max-width-override',
|
|
resolveLength(maxWidth, 'calc(100vw - var(--space-4))')
|
|
)
|
|
]
|
|
.filter(Boolean)
|
|
.join(' ')
|
|
);
|
|
|
|
const composedStyle = $derived(composeInlineStyle(style, dimensionsStyle));
|
|
</script>
|
|
|
|
<PopoverContent
|
|
{...rest}
|
|
{align}
|
|
{sideOffset}
|
|
{collisionPadding}
|
|
size={popoverSize}
|
|
data-picker-size={resolvedSize}
|
|
style={composedStyle}
|
|
>
|
|
{#snippet children(snippetProps)}
|
|
{@render bodyContent?.(snippetProps)}
|
|
{/snippet}
|
|
</PopoverContent>
|