Fix floating layer wiring in acel poppers

main
dev 6 months ago
parent c17c0fbf75
commit e192a2f815

@ -1,7 +1,7 @@
<script lang="ts">
import type { Snippet } from "svelte";
import { boxWith, type WritableBox } from "../../utilities/index";
import { FloatingAnchorState } from "../../utilities/floating/use-floating-layer.svelte";
import { FloatingAnchorState } from "./use-floating-layer.svelte.ts";
import type { Measurable } from "../../utilities/floating/types";
let {
@ -29,3 +29,4 @@
</script>
{@render children?.()}

@ -1,6 +1,6 @@
<script lang="ts">
import type { Snippet } from "svelte";
import { FloatingRootState } from "../../utilities/floating/use-floating-layer.svelte";
import { FloatingRootState } from "./use-floating-layer.svelte.ts";
let { children, tooltip = false }: { children?: Snippet; tooltip?: boolean } = $props();
@ -8,3 +8,4 @@
</script>
{@render children?.()}

@ -0,0 +1,430 @@
import {
type Middleware,
type Placement,
arrow,
autoUpdate,
flip,
hide,
limitShift,
offset,
shift,
size,
} from "@floating-ui/dom";
import {
attachRef,
cssToStyleObj,
getWindow,
styleToString,
type ReadableBoxedValues,
type ReadableBox,
type Box,
simpleBox,
boxFrom,
} from "../../utilities";
import { Context, ElementSize, watch } from "runed";
import type { Arrayable, WithRefOpts } from "../../utilities";
import { isNotNull } from "../../utilities";
import { useId } from "../../utilities";
import { useFloating } from "../../utilities";
import type { Measurable, UseFloatingReturn } from "../../utilities";
import type { Direction, StyleProperties } from "../../utilities";
export const SIDE_OPTIONS = ["top", "right", "bottom", "left"] as const;
export const ALIGN_OPTIONS = ["start", "center", "end"] as const;
const OPPOSITE_SIDE: Record<Side, Side> = {
top: "bottom",
right: "left",
bottom: "top",
left: "right",
};
const FloatingRootContext = new Context<FloatingRootState>("Floating.Root");
const FloatingContentContext = new Context<FloatingContentState>("Floating.Content");
const FloatingTooltipRootContext = new Context<FloatingRootState>("Floating.Root");
export type Side = (typeof SIDE_OPTIONS)[number];
export type Align = (typeof ALIGN_OPTIONS)[number];
export type Boundary = Element | null;
export class FloatingRootState {
static create(tooltip = false) {
return tooltip
? FloatingTooltipRootContext.set(new FloatingRootState())
: FloatingRootContext.set(new FloatingRootState());
}
anchorNode = simpleBox<Measurable | HTMLElement | null>(null);
customAnchorNode = simpleBox<Measurable | HTMLElement | null | string>(null);
triggerNode: ReadableBox<Measurable | HTMLElement | null> = simpleBox(null);
constructor() {
$effect(() => {
if (this.customAnchorNode.current) {
if (typeof this.customAnchorNode.current === "string") {
this.anchorNode.current = document.querySelector(this.customAnchorNode.current);
} else {
this.anchorNode.current = this.customAnchorNode.current;
}
} else {
this.anchorNode.current = this.triggerNode.current;
}
});
}
}
export interface FloatingContentStateOpts
extends ReadableBoxedValues<{
id: string;
wrapperId: string;
side: Side;
sideOffset: number;
align: Align;
alignOffset: number;
arrowPadding: number;
avoidCollisions: boolean;
collisionBoundary: Arrayable<Boundary>;
collisionPadding: number | Partial<Record<Side, number>>;
sticky: "partial" | "always";
hideWhenDetached: boolean;
updatePositionStrategy: "optimized" | "always";
strategy: "fixed" | "absolute";
onPlaced: () => void;
dir: Direction;
style: StyleProperties | null | undefined | string;
enabled: boolean;
customAnchor: string | HTMLElement | null | Measurable;
}> {}
export class FloatingContentState {
static create(opts: FloatingContentStateOpts, tooltip = false) {
return tooltip
? FloatingContentContext.set(
new FloatingContentState(opts, FloatingTooltipRootContext.get())
)
: FloatingContentContext.set(new FloatingContentState(opts, FloatingRootContext.get()));
}
readonly opts: FloatingContentStateOpts;
readonly root: FloatingRootState;
// nodes
contentRef = simpleBox<HTMLElement | null>(null);
wrapperRef = simpleBox<HTMLElement | null>(null);
arrowRef = simpleBox<HTMLElement | null>(null);
readonly contentAttachment = attachRef(this.contentRef);
readonly wrapperAttachment = attachRef(this.wrapperRef);
readonly arrowAttachment = attachRef(this.arrowRef);
// ids
arrowId: Box<string> = simpleBox(useId());
#transformedStyle = $derived.by(() => {
if (typeof this.opts.style === "string") return cssToStyleObj(this.opts.style);
if (!this.opts.style) return {};
});
#updatePositionStrategy =
undefined as unknown as FloatingContentStateOpts["updatePositionStrategy"];
#arrowSize = new ElementSize(() => this.arrowRef.current ?? undefined);
#arrowWidth = $derived(this.#arrowSize?.width ?? 0);
#arrowHeight = $derived(this.#arrowSize?.height ?? 0);
#desiredPlacement = $derived.by(
() =>
(this.opts.side?.current +
(this.opts.align.current !== "center"
? `-${this.opts.align.current}`
: "")) as Placement
);
#boundary = $derived.by(() =>
Array.isArray(this.opts.collisionBoundary.current)
? this.opts.collisionBoundary.current
: [this.opts.collisionBoundary.current]
);
hasExplicitBoundaries = $derived(this.#boundary.length > 0);
detectOverflowOptions = $derived.by(() => ({
padding: this.opts.collisionPadding.current,
boundary: this.#boundary.filter(isNotNull),
altBoundary: this.hasExplicitBoundaries,
}));
#availableWidth = $state<number | undefined>(undefined);
#availableHeight = $state<number | undefined>(undefined);
#anchorWidth = $state<number | undefined>(undefined);
#anchorHeight = $state<number | undefined>(undefined);
middleware: Middleware[] = $derived.by(
() =>
[
offset({
mainAxis: this.opts.sideOffset.current + this.#arrowHeight,
alignmentAxis: this.opts.alignOffset.current,
}),
this.opts.avoidCollisions.current &&
shift({
mainAxis: true,
crossAxis: false,
limiter: this.opts.sticky.current === "partial" ? limitShift() : undefined,
...this.detectOverflowOptions,
}),
this.opts.avoidCollisions.current && flip({ ...this.detectOverflowOptions }),
size({
...this.detectOverflowOptions,
apply: ({ rects, availableWidth, availableHeight }) => {
const { width: anchorWidth, height: anchorHeight } = rects.reference;
this.#availableWidth = availableWidth;
this.#availableHeight = availableHeight;
this.#anchorWidth = anchorWidth;
this.#anchorHeight = anchorHeight;
},
}),
this.arrowRef.current &&
arrow({
element: this.arrowRef.current,
padding: this.opts.arrowPadding.current,
}),
transformOrigin({ arrowWidth: this.#arrowWidth, arrowHeight: this.#arrowHeight }),
this.opts.hideWhenDetached.current &&
hide({ strategy: "referenceHidden", ...this.detectOverflowOptions }),
].filter(Boolean) as Middleware[]
);
floating: UseFloatingReturn;
placedSide = $derived.by(() => getSideFromPlacement(this.floating.placement));
placedAlign = $derived.by(() => getAlignFromPlacement(this.floating.placement));
arrowX = $derived.by(() => this.floating.middlewareData.arrow?.x ?? 0);
arrowY = $derived.by(() => this.floating.middlewareData.arrow?.y ?? 0);
cannotCenterArrow = $derived.by(() => this.floating.middlewareData.arrow?.centerOffset !== 0);
contentZIndex = $state<string>();
arrowBaseSide = $derived(OPPOSITE_SIDE[this.placedSide]);
wrapperProps = $derived.by(
() =>
({
id: this.opts.wrapperId.current,
"data-bits-floating-content-wrapper": "",
style: {
...this.floating.floatingStyles,
// keep off page when measuring
transform: this.floating.isPositioned
? this.floating.floatingStyles.transform
: "translate(0, -200%)",
minWidth: "max-content",
zIndex: this.contentZIndex,
"--bits-floating-transform-origin": `${this.floating.middlewareData.transformOrigin?.x} ${this.floating.middlewareData.transformOrigin?.y}`,
"--bits-floating-available-width": `${this.#availableWidth}px`,
"--bits-floating-available-height": `${this.#availableHeight}px`,
"--bits-floating-anchor-width": `${this.#anchorWidth}px`,
"--bits-floating-anchor-height": `${this.#anchorHeight}px`,
// hide the content if using the hide middleware and should be hidden
...(this.floating.middlewareData.hide?.referenceHidden && {
visibility: "hidden",
"pointer-events": "none",
}),
...this.#transformedStyle,
},
// Floating UI calculates logical alignment based the `dir` attribute
dir: this.opts.dir.current,
...this.wrapperAttachment,
}) as const
);
props = $derived.by(
() =>
({
"data-side": this.placedSide,
"data-align": this.placedAlign,
style: styleToString({
...this.#transformedStyle,
}),
...this.contentAttachment,
}) as const
);
arrowStyle = $derived({
position: "absolute",
left: this.arrowX ? `${this.arrowX}px` : undefined,
top: this.arrowY ? `${this.arrowY}px` : undefined,
[this.arrowBaseSide]: 0,
"transform-origin": {
top: "",
right: "0 0",
bottom: "center 0",
left: "100% 0",
}[this.placedSide],
transform: {
top: "translateY(100%)",
right: "translateY(50%) rotate(90deg) translateX(-50%)",
bottom: "rotate(180deg)",
left: "translateY(50%) rotate(-90deg) translateX(50%)",
}[this.placedSide],
visibility: this.cannotCenterArrow ? "hidden" : undefined,
});
constructor(opts: FloatingContentStateOpts, root: FloatingRootState) {
this.opts = opts;
this.root = root;
this.#updatePositionStrategy = opts.updatePositionStrategy;
if (opts.customAnchor) {
this.root.customAnchorNode.current = opts.customAnchor.current;
}
watch(
() => opts.customAnchor.current,
(customAnchor) => {
this.root.customAnchorNode.current = customAnchor;
}
);
this.floating = useFloating({
strategy: () => this.opts.strategy.current,
placement: () => this.#desiredPlacement,
middleware: () => this.middleware,
reference: this.root.anchorNode,
whileElementsMounted: (...args) => {
const cleanup = autoUpdate(...args, {
animationFrame: this.#updatePositionStrategy?.current === "always",
});
return cleanup;
},
open: () => this.opts.enabled.current,
sideOffset: () => this.opts.sideOffset.current,
alignOffset: () => this.opts.alignOffset.current,
});
$effect(() => {
if (!this.floating.isPositioned) return;
this.opts.onPlaced?.current();
});
watch(
() => this.contentRef.current,
(contentNode) => {
if (!contentNode || !this.opts.enabled.current) return;
const win = getWindow(contentNode);
const rafId = win.requestAnimationFrame(() => {
// avoid applying stale values when refs change quickly
if (this.contentRef.current !== contentNode || !this.opts.enabled.current) return;
const zIndex = win.getComputedStyle(contentNode).zIndex;
if (zIndex !== this.contentZIndex) {
this.contentZIndex = zIndex;
}
});
return () => {
win.cancelAnimationFrame(rafId);
};
}
);
$effect(() => {
this.floating.floating.current = this.wrapperRef.current;
});
}
}
interface FloatingArrowStateOpts extends WithRefOpts {}
export class FloatingArrowState {
static create(opts: FloatingArrowStateOpts) {
return new FloatingArrowState(opts, FloatingContentContext.get());
}
readonly opts: FloatingArrowStateOpts;
readonly content: FloatingContentState;
constructor(opts: FloatingArrowStateOpts, content: FloatingContentState) {
this.opts = opts;
this.content = content;
}
readonly props = $derived.by(
() =>
({
id: this.opts.id.current,
style: this.content.arrowStyle,
"data-side": this.content.placedSide,
...this.content.arrowAttachment,
}) as const
);
}
interface FloatingAnchorStateOpts
extends ReadableBoxedValues<{
id: string;
virtualEl?: Measurable | null;
ref: Measurable | HTMLElement | null;
}> {}
export class FloatingAnchorState {
static create(opts: FloatingAnchorStateOpts, tooltip = false) {
return tooltip
? new FloatingAnchorState(opts, FloatingTooltipRootContext.get())
: new FloatingAnchorState(opts, FloatingRootContext.get());
}
readonly opts: FloatingAnchorStateOpts;
readonly root: FloatingRootState;
constructor(opts: FloatingAnchorStateOpts, root: FloatingRootState) {
this.opts = opts;
this.root = root;
if (opts.virtualEl && opts.virtualEl.current) {
root.triggerNode = boxFrom(opts.virtualEl.current);
} else {
root.triggerNode = opts.ref;
}
}
}
//
// HELPERS
//
function transformOrigin(options: { arrowWidth: number; arrowHeight: number }): Middleware {
return {
name: "transformOrigin",
options,
fn(data) {
const { placement, rects, middlewareData } = data;
const cannotCenterArrow = middlewareData.arrow?.centerOffset !== 0;
const isArrowHidden = cannotCenterArrow;
const arrowWidth = isArrowHidden ? 0 : options.arrowWidth;
const arrowHeight = isArrowHidden ? 0 : options.arrowHeight;
const [placedSide, placedAlign] = getSideAndAlignFromPlacement(placement);
const noArrowAlign = { start: "0%", center: "50%", end: "100%" }[placedAlign];
const arrowXCenter = (middlewareData.arrow?.x ?? 0) + arrowWidth / 2;
const arrowYCenter = (middlewareData.arrow?.y ?? 0) + arrowHeight / 2;
let x = "";
let y = "";
if (placedSide === "bottom") {
x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
y = `${-arrowHeight}px`;
} else if (placedSide === "top") {
x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
y = `${rects.floating.height + arrowHeight}px`;
} else if (placedSide === "right") {
x = `${-arrowHeight}px`;
y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
} else if (placedSide === "left") {
x = `${rects.floating.width + arrowHeight}px`;
y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
}
return { data: { x, y } };
},
};
}
function getSideAndAlignFromPlacement(placement: Placement) {
const [side, align = "center"] = placement.split("-");
return [side as Side, align as Align] as const;
}
export function getSideFromPlacement(placement: Placement) {
return getSideAndAlignFromPlacement(placement)[0];
}
export function getAlignFromPlacement(placement: Placement) {
return getSideAndAlignFromPlacement(placement)[1];
}

@ -84,6 +84,7 @@
{collisionPadding}
{style}
{id}
ref={contentState.opts.ref}
open={contentState.parentMenu.opts.open.current}
onInteractOutside={handleInteractOutside}
onEscapeKeydown={handleEscapeKeydown}
@ -107,3 +108,4 @@
{/if}
{/snippet}
</PopperLayer>

@ -3,7 +3,7 @@
import type { ContextMenuTriggerProps } from "../types";
import { ContextMenuTriggerState } from "../../menu/menu.svelte";
import { useId } from "../../utilities/use-id";
import FloatingLayerAnchor from "../../comn/floating-layer/floating-layer-anchor.svelte";
import FloatingLayerAnchor from "../../comn/floating-layer/components/floating-layer-anchor.svelte";
let {
id = useId(),
@ -45,3 +45,4 @@
</div>
{/if}
</FloatingLayerAnchor>

@ -1,7 +1,7 @@
<script lang="ts">
import { boxWith } from "../../utilities/index";
import type { ContextMenuRootProps } from "../types";
import FloatingLayer from "../../comn/floating-layer/floating-layer.svelte";
import FloatingLayer from "../../comn/floating-layer/components/floating-layer.svelte";
import { noop } from "../../utilities/noop";
import { MenuMenuState, MenuRootState } from "../../menu/menu.svelte";
@ -40,3 +40,4 @@
<FloatingLayer>
{@render children?.()}
</FloatingLayer>

@ -0,0 +1,233 @@
<script lang="ts">
import { watch } from "runed";
import type { DateValue } from "$lib/glob/lib";
import {
boxWith,
mergeProps,
noop,
useId,
} from "../../utilities/index";
import { DateRangePickerRootState } from "../date-range-picker.svelte.ts";
import type { DateRangePickerRootProps } from "../types.ts";
import { PopoverRootState } from "../../popover/popover.svelte.ts";
import { DateRangeFieldRootState } from "../../date-range-field/date-range-field.svelte.ts";
import FloatingLayer from "../../comn/floating-layer/components/floating-layer.svelte";
import { type DateRange, getDefaultDate } from "$lib/glob/lib";
import { resolveLocaleProp } from "../../comn/config/prop-resolvers.ts";
let {
open = $bindable(false),
onOpenChange = noop,
onOpenChangeComplete = noop,
value = $bindable(),
id = useId(),
ref = $bindable(null),
onValueChange = noop,
placeholder = $bindable(),
onPlaceholderChange = noop,
isDateUnavailable = () => false,
onInvalid = noop,
minValue,
maxValue,
disabled = false,
readonly = false,
granularity,
readonlySegments = [],
hourCycle,
locale,
hideTimeZone = false,
required = false,
calendarLabel = "Event",
disableDaysOutsideMonth = true,
preventDeselect = false,
pagedNavigation = false,
weekStartsOn,
weekdayFormat = "narrow",
isDateDisabled = () => false,
fixedWeeks = false,
numberOfMonths = 1,
closeOnRangeSelect = true,
onStartValueChange = noop,
onEndValueChange = noop,
validate = noop,
errorMessageId,
minDays,
maxDays,
excludeDisabled = false,
child,
children,
monthFormat = "long",
yearFormat = "numeric",
...restProps
}: DateRangePickerRootProps = $props();
let startValue = $state<DateValue | undefined>(value?.start);
let endValue = $state<DateValue | undefined>(value?.end);
function handleDefaultValue() {
if (value !== undefined) return;
value = { start: undefined, end: undefined };
}
// SSR
handleDefaultValue();
/**
* Covers an edge case where when a spread props object is reassigned,
* the props are reset to their default values, which would make value
* undefined which causes errors to be thrown.
*/
watch.pre(
() => value,
() => {
handleDefaultValue();
}
);
const defaultPlaceholder = getDefaultDate({
granularity,
defaultValue: value?.start,
minValue,
maxValue,
});
function handleDefaultPlaceholder() {
if (placeholder !== undefined) return;
placeholder = defaultPlaceholder;
}
// SSR
handleDefaultPlaceholder();
/**
* Covers an edge case where when a spread props object is reassigned,
* the props are reset to their default values, which would make placeholder
* undefined which causes errors to be thrown.
*/
watch.pre(
() => placeholder,
() => {
handleDefaultPlaceholder();
}
);
function onRangeSelect() {
if (closeOnRangeSelect) {
open = false;
}
}
const pickerRootState = DateRangePickerRootState.create({
open: boxWith(
() => open,
(v) => {
open = v;
onOpenChange(v);
}
),
value: boxWith(
() => value as DateRange,
(v) => {
value = v;
onValueChange(v);
}
),
placeholder: boxWith(
() => placeholder as DateValue,
(v) => {
placeholder = v;
onPlaceholderChange(v as DateValue);
}
),
isDateUnavailable: boxWith(() => isDateUnavailable),
minValue: boxWith(() => minValue),
maxValue: boxWith(() => maxValue),
minDays: boxWith(() => minDays),
maxDays: boxWith(() => maxDays),
disabled: boxWith(() => disabled),
readonly: boxWith(() => readonly),
granularity: boxWith(() => granularity),
readonlySegments: boxWith(() => readonlySegments),
hourCycle: boxWith(() => hourCycle),
locale: resolveLocaleProp(() => locale),
hideTimeZone: boxWith(() => hideTimeZone),
required: boxWith(() => required),
calendarLabel: boxWith(() => calendarLabel),
disableDaysOutsideMonth: boxWith(() => disableDaysOutsideMonth),
preventDeselect: boxWith(() => preventDeselect),
pagedNavigation: boxWith(() => pagedNavigation),
weekStartsOn: boxWith(() => weekStartsOn),
weekdayFormat: boxWith(() => weekdayFormat),
isDateDisabled: boxWith(() => isDateDisabled),
fixedWeeks: boxWith(() => fixedWeeks),
numberOfMonths: boxWith(() => numberOfMonths),
excludeDisabled: boxWith(() => excludeDisabled),
onRangeSelect: boxWith(() => onRangeSelect),
startValue: boxWith(
() => startValue,
(v) => {
startValue = v;
onStartValueChange(v);
}
),
endValue: boxWith(
() => endValue,
(v) => {
endValue = v;
onEndValueChange(v);
}
),
monthFormat: boxWith(() => monthFormat),
yearFormat: boxWith(() => yearFormat),
defaultPlaceholder,
});
PopoverRootState.create({
open: pickerRootState.opts.open,
onOpenChangeComplete: boxWith(() => onOpenChangeComplete),
});
const fieldRootState = DateRangeFieldRootState.create({
value: pickerRootState.opts.value,
disabled: pickerRootState.opts.disabled,
readonly: pickerRootState.opts.readonly,
readonlySegments: pickerRootState.opts.readonlySegments,
validate: boxWith(() => validate),
minValue: pickerRootState.opts.minValue,
maxValue: pickerRootState.opts.maxValue,
granularity: pickerRootState.opts.granularity,
hideTimeZone: pickerRootState.opts.hideTimeZone,
hourCycle: pickerRootState.opts.hourCycle,
locale: pickerRootState.opts.locale,
required: pickerRootState.opts.required,
placeholder: pickerRootState.opts.placeholder,
id: boxWith(() => id),
ref: boxWith(
() => ref,
(v) => (ref = v)
),
startValue: pickerRootState.opts.startValue,
endValue: pickerRootState.opts.endValue,
onInvalid: boxWith(() => onInvalid),
errorMessageId: boxWith(() => errorMessageId),
});
const mergedProps = $derived(mergeProps(restProps, fieldRootState.props));
</script>
<FloatingLayer>
{#if child}
{@render child({ props: mergedProps })}
{:else}
<div {...mergedProps}>
{@render children?.()}
</div>
{/if}
</FloatingLayer>

@ -76,6 +76,7 @@
{collisionPadding}
{style}
{id}
ref={contentState.opts.ref}
open={contentState.parentMenu.opts.open.current}
onInteractOutside={handleInteractOutside}
onEscapeKeydown={handleEscapeKeydown}
@ -99,3 +100,4 @@
{/if}
{/snippet}
</PopperLayer>

@ -74,6 +74,7 @@
{collisionPadding}
{style}
{id}
ref={contentState.opts.ref}
open={contentState.parentMenu.opts.open.current}
onInteractOutside={handleInteractOutside}
onEscapeKeydown={handleEscapeKeydown}
@ -97,3 +98,4 @@
{/if}
{/snippet}
</PopperLayer>

@ -78,6 +78,7 @@
{...mergedProps}
{side}
{id}
ref={subContentState.opts.ref}
open={subContentState.parentMenu.opts.open.current}
onInteractOutside={handleInteractOutside}
onEscapeKeydown={handleEscapeKeydown}
@ -101,3 +102,4 @@
{/if}
{/snippet}
</PopperLayer>

@ -2,7 +2,7 @@
import { boxWith, mergeProps } from "../../utilities/index";
import type { MenuSubTriggerProps } from "../types";
import { MenuSubTriggerState } from "../menu.svelte";
import FloatingLayerAnchor from "../../comn/floating-layer/floating-layer-anchor.svelte";
import FloatingLayerAnchor from "../../comn/floating-layer/components/floating-layer-anchor.svelte";
import { noop } from "../../utilities/noop";
import { createId } from "../../utilities/create-id";
@ -42,3 +42,4 @@
</div>
{/if}
</FloatingLayerAnchor>

@ -2,7 +2,7 @@
import { boxWith } from "../../utilities/index";
import type { MenuSubProps } from "../types";
import { MenuSubmenuState } from "../menu.svelte";
import FloatingLayer from "../../comn/floating-layer/floating-layer.svelte";
import FloatingLayer from "../../comn/floating-layer/components/floating-layer.svelte";
import { noop } from "../../utilities/noop";
let {
@ -27,3 +27,4 @@
<FloatingLayer>
{@render children?.()}
</FloatingLayer>

@ -3,7 +3,7 @@
import type { MenuTriggerProps } from "../types";
import { DropdownMenuTriggerState } from "../menu.svelte";
import { createId } from "../../utilities/create-id";
import FloatingLayerAnchor from "../../comn/floating-layer/floating-layer-anchor.svelte";
import FloatingLayerAnchor from "../../comn/floating-layer/components/floating-layer-anchor.svelte";
const uid = $props.id();
@ -38,3 +38,4 @@
</button>
{/if}
</FloatingLayerAnchor>

@ -3,7 +3,7 @@
import type { MenuRootProps } from "../types";
import { MenuMenuState, MenuRootState } from "../menu.svelte";
import { noop } from "../../utilities/noop";
import FloatingLayer from "../../comn/floating-layer/floating-layer.svelte";
import FloatingLayer from "../../comn/floating-layer/components/floating-layer.svelte";
let {
open = $bindable(false),
@ -43,3 +43,4 @@
<FloatingLayer>
{@render children?.()}
</FloatingLayer>

@ -10,7 +10,7 @@ import type {
AcelPrimitiveDivAttributes,
} from "../utilities/attributes";
import type { Direction } from "../utilities/index";
import type { Side, Align, Boundary } from "../utilities/floating/use-floating-layer.svelte";
import type { Side, Align, Boundary } from "../comn/floating-layer/use-floating-layer.svelte.ts";
import type { Arrayable } from "../utilities/types";
import type { StyleProperties } from "../utilities/index";
@ -216,3 +216,4 @@ export type MenuRadioItemPropsWithoutHTML = MenuItemPropsWithoutHTML<MenuRadioIt
export type MenuRadioItemProps = MenuRadioItemPropsWithoutHTML &
Without<AcelPrimitiveDivAttributes, MenuRadioItemPropsWithoutHTML>;

@ -3,7 +3,7 @@
import type { MenubarTriggerProps } from "../types";
import { MenubarTriggerState } from "../menubar.svelte";
import { useId } from "../../utilities/use-id";
import FloatingLayerAnchor from "../../comn/floating-layer/floating-layer-anchor.svelte";
import FloatingLayerAnchor from "../../comn/floating-layer/components/floating-layer-anchor.svelte";
import { DropdownMenuTriggerState } from "../../menu/menu.svelte";
let {
@ -43,3 +43,4 @@
</button>
{/if}
</FloatingLayerAnchor>

@ -61,6 +61,7 @@
{customAnchor}
onEscapeKeydown={contentState.onEscapeKeydown}
onInteractOutside={contentState.onInteractOutside}
ref={contentState.opts.ref}
open={contentState.root.opts.open.current}
shouldRender={forceMount || contentState.shouldRender}
>
@ -82,3 +83,4 @@
{/if}
{/snippet}
</PopperLayer>

@ -3,7 +3,7 @@
import type { PopoverTriggerProps } from "../types";
import { PopoverTriggerState } from "../popover.svelte";
import { createId } from "../../utilities/create-id";
import FloatingLayerAnchor from "../../comn/floating-layer/floating-layer-anchor.svelte";
import FloatingLayerAnchor from "../../comn/floating-layer/components/floating-layer-anchor.svelte";
const uid = $props.id();
@ -44,3 +44,4 @@
</button>
{/if}
</FloatingLayerAnchor>

@ -2,7 +2,7 @@
import { boxWith } from "../../utilities/index";
import type { PopoverRootProps } from "../types";
import { PopoverRootState } from "../popover.svelte";
import FloatingLayer from "../../comn/floating-layer/floating-layer.svelte";
import FloatingLayer from "../../comn/floating-layer/components/floating-layer.svelte";
import { noop } from "../../utilities/noop";
let {
@ -27,3 +27,4 @@
<FloatingLayer>
{@render children?.()}
</FloatingLayer>

@ -1,7 +1,7 @@
import type { WithChild, WithChildren, Without, OnChangeFn } from "../utilities/types";
import type { AcelPrimitiveDivAttributes, AcelPrimitiveButtonAttributes } from "../utilities/attributes";
import type { StyleProperties } from "../utilities/index";
import type { Side, Align, Boundary } from "../utilities/floating/use-floating-layer.svelte";
import type { Side, Align, Boundary } from "../comn/floating-layer/use-floating-layer.svelte.ts";
import type { Arrayable } from "../utilities/types";
import type { Measurable } from "../utilities/floating/types";
@ -65,3 +65,9 @@ export type PopoverCloseProps = PopoverClosePropsWithoutHTML &
export type PopoverOverlayPropsWithoutHTML = WithChild<{ forceMount?: boolean }, { open: boolean }>;
export type PopoverOverlayProps = PopoverOverlayPropsWithoutHTML &
Without<AcelPrimitiveDivAttributes, PopoverOverlayPropsWithoutHTML>;
export type {
ArrowPropsWithoutHTML as PopoverArrowPropsWithoutHTML,
ArrowProps as PopoverArrowProps,
} from "../comn/arrow/types";

@ -63,6 +63,7 @@
customAnchor={customAnchor ?? contentState.root.triggerNode}
onEscapeKeydown={contentState.onEscapeKeydown}
onInteractOutside={contentState.onInteractOutside}
ref={contentState.opts.ref}
open={contentState.root.opts.open.current}
tooltip={true}
shouldRender={forceMount || contentState.shouldRender}
@ -86,3 +87,4 @@
{/if}
{/snippet}
</PopperLayer>

@ -6,7 +6,7 @@
import { boxWith } from "../../utilities/index";
import type { TooltipRootProps } from "../types";
import { TooltipRootState } from "../tooltip.svelte";
import FloatingLayer from "../../comn/floating-layer/floating-layer.svelte";
import FloatingLayer from "../../comn/floating-layer/components/floating-layer.svelte";
import { noop } from "../../utilities/noop";
let {
@ -54,3 +54,4 @@
payload: rootState.activePayload as [T] extends [never] ? null : T | null,
})}
</FloatingLayer>

@ -3,7 +3,7 @@ import type { WithChild, WithChildNoChildrenSnippetProps, WithChildren, Without,
import type { AcelPrimitiveDivAttributes, AcelPrimitiveButtonAttributes } from "../utilities/attributes";
import type { TooltipTether as TooltipTetherImpl } from "./tooltip.svelte";
import type { StyleProperties } from "../utilities/index";
import type { Side, Align, Boundary } from "../utilities/floating/use-floating-layer.svelte";
import type { Side, Align, Boundary } from "../comn/floating-layer/use-floating-layer.svelte.ts";
import type { Arrayable } from "../utilities/types";
export type TooltipTether<Payload = never> = TooltipTetherImpl<Payload>;
@ -84,3 +84,4 @@ export type TooltipTriggerPropsWithoutHTML<Payload = never> = WithChild<{
export type TooltipTriggerProps<Payload = never> = TooltipTriggerPropsWithoutHTML<Payload> &
Without<AcelPrimitiveButtonAttributes, TooltipTriggerPropsWithoutHTML<Payload>>;

@ -104,7 +104,7 @@ export { CustomEventDispatcher } from "./events/event-dispatcher.ts";
// floating/
export * from "./floating/floating-utils.svelte.ts";
export * from "./floating/use-floating-layer.svelte.ts";
export { useFloating } from "./floating/use-floating.svelte.ts";
export type { UseFloatingOptions, UseFloatingReturn, Measurable } from "./floating/types.ts";
export { GraceArea } from "./floating/grace-area.svelte.ts";
@ -128,3 +128,4 @@ export { PresenceManager } from "./presence/presence-manager.svelte.ts";
// typeahead/
export { DataTypeahead } from "./typeahead/data-typeahead.svelte.ts";
export { DOMTypeahead } from "./typeahead/dom-typeahead.svelte.ts";

Loading…
Cancel
Save

Powered by TurnKey Linux.