fix(ui): let Page.SettingsActions sticky bar escape its wrapper (#825)
The bar was nested in an extra shrink-0 div together with the dock sentinel. A sticky element is constrained to its containing block, and that wrapper is only as tall as the bar plus a 1px sentinel, so the bar had roughly 1px of travel. It could never float over the page content and only ever appeared where it naturally sits, at the end of the page. Render the bar and the sentinel as siblings so the containing block is Page.Root and the bar has the full page to travel. Measured in headless Chrome at scrollY=600 in a 713px viewport: wrapped bar bottom was 2484 (off screen), sibling bar bottom is 713, pinned to the viewport. Also raise the bar from z-10 to z-50. The editor root is relative z-50, so it painted over the bar on any settings page with an editor, such as the course welcome email. Matching 50 rather than exceeding it wins the tie on DOM order while keeping body-portaled dialogs and sheets above the bar. ref is now bound to the sticky element rather than the removed wrapper. No dashboard caller binds ref today.
This commit is contained in:
@@ -45,33 +45,36 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={ref} class={cn('ui:shrink-0', className)} {...restProps}>
|
<div
|
||||||
<div data-slot="page-settings-actions" class="ui:sticky ui:bottom-0 ui:z-10 ui:pb-4">
|
bind:this={ref}
|
||||||
<div
|
data-slot="page-settings-actions"
|
||||||
class={cn(
|
class={cn('ui:sticky ui:bottom-0 ui:z-50 ui:pb-4 ui:shrink-0', className)}
|
||||||
'ui:flex ui:flex-col ui:gap-3 ui:sm:flex-row ui:sm:items-center ui:sm:justify-between',
|
{...restProps}
|
||||||
'ui:rounded-lg ui:border ui:border-border ui:bg-background ui:p-4 ui:transition-shadow',
|
>
|
||||||
!isDocked && 'ui:shadow-md',
|
<div
|
||||||
contentClassName
|
class={cn(
|
||||||
)}
|
'ui:flex ui:flex-col ui:gap-3 ui:sm:flex-row ui:sm:items-center ui:sm:justify-between',
|
||||||
>
|
'ui:rounded-lg ui:border ui:border-border ui:bg-background ui:p-4 ui:transition-shadow',
|
||||||
<p class="ui:text-sm ui:text-muted-foreground">{statusLabel}</p>
|
!isDocked && 'ui:shadow-md',
|
||||||
|
contentClassName
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<p class="ui:text-sm ui:text-muted-foreground">{statusLabel}</p>
|
||||||
|
|
||||||
<div class="ui:flex ui:shrink-0 ui:items-center ui:justify-end ui:gap-2">
|
<div class="ui:flex ui:shrink-0 ui:items-center ui:justify-end ui:gap-2">
|
||||||
<Button variant="ghost" type="button" disabled={actionsDisabled} onclick={onDiscard}>
|
<Button variant="ghost" type="button" disabled={actionsDisabled} onclick={onDiscard}>
|
||||||
{discardLabel}
|
{discardLabel}
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="button" {loading} disabled={actionsDisabled || disabled} onclick={onSave}>
|
<Button type="button" {loading} disabled={actionsDisabled || disabled} onclick={onSave}>
|
||||||
{saveLabel}
|
{saveLabel}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
|
||||||
bind:this={dockSentinel}
|
|
||||||
data-slot="page-settings-actions-sentinel"
|
|
||||||
class="ui:h-px ui:shrink-0"
|
|
||||||
aria-hidden="true"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={dockSentinel}
|
||||||
|
data-slot="page-settings-actions-sentinel"
|
||||||
|
class="ui:h-px ui:shrink-0"
|
||||||
|
aria-hidden="true"
|
||||||
|
></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user