feat(TypographyMenu): add bindable "open" prop to close popover from outside
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
Component: TypographyMenu
|
Component: TypographyMenu
|
||||||
Floating controls bar for typography settings.
|
Floating controls bar for typography settings.
|
||||||
Warm surface, sharp corners, Settings icon header, dividers between units.
|
|
||||||
Mobile: popover with slider controls anchored to settings button.
|
Mobile: popover with slider controls anchored to settings button.
|
||||||
Desktop: inline bar with combo controls.
|
Desktop: inline bar with combo controls.
|
||||||
-->
|
-->
|
||||||
@@ -37,14 +36,17 @@ interface Props {
|
|||||||
* @default false
|
* @default false
|
||||||
*/
|
*/
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
|
/**
|
||||||
|
* Bindable popover open state
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
open?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { class: className, hidden = false }: Props = $props();
|
let { class: className, hidden = false, open = $bindable(false) }: Props = $props();
|
||||||
|
|
||||||
const responsive = getContext<ResponsiveManager>('responsive');
|
const responsive = getContext<ResponsiveManager>('responsive');
|
||||||
|
|
||||||
let isOpen = $state(false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the common font size multiplier based on the current responsive state.
|
* Sets the common font size multiplier based on the current responsive state.
|
||||||
*/
|
*/
|
||||||
@@ -70,7 +72,7 @@ $effect(() => {
|
|||||||
|
|
||||||
{#if !hidden}
|
{#if !hidden}
|
||||||
{#if responsive.isMobileOrTablet}
|
{#if responsive.isMobileOrTablet}
|
||||||
<Popover.Root bind:open={isOpen}>
|
<Popover.Root bind:open>
|
||||||
<Popover.Trigger>
|
<Popover.Trigger>
|
||||||
{#snippet child({ props })}
|
{#snippet child({ props })}
|
||||||
<Button class={className} variant="primary" {...props}>
|
<Button class={className} variant="primary" {...props}>
|
||||||
@@ -84,7 +86,7 @@ $effect(() => {
|
|||||||
<Popover.Portal>
|
<Popover.Portal>
|
||||||
<Popover.Content
|
<Popover.Content
|
||||||
side="top"
|
side="top"
|
||||||
align="start"
|
align="end"
|
||||||
sideOffset={8}
|
sideOffset={8}
|
||||||
class={clsx(
|
class={clsx(
|
||||||
'z-50 w-72',
|
'z-50 w-72',
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ const responsive = getContext<ResponsiveManager>('responsive');
|
|||||||
const isMobile = $derived(responsive?.isMobile ?? false);
|
const isMobile = $derived(responsive?.isMobile ?? false);
|
||||||
|
|
||||||
let isDragging = $state(false);
|
let isDragging = $state(false);
|
||||||
|
let isTypographyMenuOpen = $state(false);
|
||||||
|
|
||||||
// New high-performance layout engine
|
// New high-performance layout engine
|
||||||
const comparisonEngine = new CharacterComparisonEngine();
|
const comparisonEngine = new CharacterComparisonEngine();
|
||||||
@@ -76,6 +77,8 @@ function handleMove(e: PointerEvent) {
|
|||||||
|
|
||||||
function startDragging(e: PointerEvent) {
|
function startDragging(e: PointerEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
// Close typography menu popover
|
||||||
|
isTypographyMenuOpen = false;
|
||||||
isDragging = true;
|
isDragging = true;
|
||||||
handleMove(e);
|
handleMove(e);
|
||||||
}
|
}
|
||||||
@@ -222,7 +225,7 @@ const scaleClass = $derived(
|
|||||||
class="
|
class="
|
||||||
relative w-full max-w-6xl h-full
|
relative w-full max-w-6xl h-full
|
||||||
flex flex-col justify-center
|
flex flex-col justify-center
|
||||||
select-none touch-none cursor-ew-resize
|
select-none touch-none outline-none cursor-ew-resize
|
||||||
py-8 px-4 sm:py-12 sm:px-8 md:py-16 md:px-12 lg:py-20 lg:px-24
|
py-8 px-4 sm:py-12 sm:px-8 md:py-16 md:px-12 lg:py-20 lg:px-24
|
||||||
"
|
"
|
||||||
in:fade={{ duration: 300, delay: 300 }}
|
in:fade={{ duration: 300, delay: 300 }}
|
||||||
@@ -253,6 +256,7 @@ const scaleClass = $derived(
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<TypographyMenu
|
<TypographyMenu
|
||||||
|
bind:open={isTypographyMenuOpen}
|
||||||
class={clsx(
|
class={clsx(
|
||||||
'absolute z-50',
|
'absolute z-50',
|
||||||
responsive.isMobileOrTablet
|
responsive.isMobileOrTablet
|
||||||
|
|||||||
Reference in New Issue
Block a user