separate editor FAB and panel for cleaner animation
All checks were successful
deploy / deploy (push) Successful in 1m32s
All checks were successful
deploy / deploy (push) Successful in 1m32s
Split the editor sheet into two distinct elements: - .editor-fab: floating action button, always a pill in the corner - .editor-panel: sliding panel that animates in/out independently This enables proper CSS keyframe animations (slide-up/down on mobile, slide-in/out on desktop) with a closing class for exit transitions. Simplified the JS hook to only handle close behaviour. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1066,77 +1066,61 @@ defmodule BerrypodWeb.ShopComponents.Layout do
|
||||
|
||||
def editor_sheet(assigns) do
|
||||
~H"""
|
||||
<%!-- Floating action button: always visible when panel is closed --%>
|
||||
<button
|
||||
:if={@editor_sheet_state == :collapsed}
|
||||
type="button"
|
||||
phx-click={if @editing, do: "editor_set_sheet_state", else: "editor_toggle_editing"}
|
||||
phx-value-state={if @editing, do: "open", else: nil}
|
||||
class="editor-fab"
|
||||
aria-label={if @editing, do: "Show editor", else: "Edit page"}
|
||||
>
|
||||
<.edit_pencil_svg />
|
||||
<span>{if @editing, do: "Show editor", else: "Edit page"}</span>
|
||||
<span :if={@editing && @editor_dirty} class="editor-fab-dirty" aria-label="Unsaved changes" />
|
||||
</button>
|
||||
|
||||
<%!-- Editor panel: slides in/out --%>
|
||||
<aside
|
||||
id="editor-sheet"
|
||||
class="editor-sheet"
|
||||
id="editor-panel"
|
||||
class="editor-panel"
|
||||
role="region"
|
||||
aria-label="Page editor"
|
||||
aria-expanded={to_string(@editor_sheet_state != :collapsed)}
|
||||
aria-hidden={to_string(@editor_sheet_state == :collapsed)}
|
||||
data-state={@editor_sheet_state}
|
||||
data-editing={to_string(@editing)}
|
||||
phx-hook="EditorSheet"
|
||||
>
|
||||
<%!-- Header: content varies by state and editing mode --%>
|
||||
<div class="editor-sheet-header">
|
||||
<%= if @editor_sheet_state == :collapsed and not @editing do %>
|
||||
<%!-- Not editing, collapsed: show Edit button to enter edit mode --%>
|
||||
<button
|
||||
type="button"
|
||||
phx-click="editor_toggle_editing"
|
||||
class="editor-sheet-edit-btn"
|
||||
>
|
||||
<.edit_pencil_svg />
|
||||
<span>Edit page</span>
|
||||
</button>
|
||||
<% end %>
|
||||
<%= if @editor_sheet_state == :collapsed and @editing do %>
|
||||
<%!-- Editing but collapsed: show button to expand sheet (for previewing) --%>
|
||||
<button
|
||||
type="button"
|
||||
phx-click="editor_set_sheet_state"
|
||||
phx-value-state="open"
|
||||
class="editor-sheet-edit-btn"
|
||||
>
|
||||
<.edit_pencil_svg />
|
||||
<span>Show editor</span>
|
||||
</button>
|
||||
<span :if={@editor_dirty} class="editor-sheet-dirty" aria-live="polite">
|
||||
<span class="editor-sheet-dirty-dot" aria-hidden="true" />
|
||||
<div class="editor-panel-header">
|
||||
<div class="editor-panel-header-left">
|
||||
<span class="editor-panel-title">Page editor</span>
|
||||
<span :if={@editor_dirty} class="editor-panel-dirty" aria-live="polite">
|
||||
<span class="editor-panel-dirty-dot" aria-hidden="true" />
|
||||
<span>Unsaved</span>
|
||||
</span>
|
||||
<% end %>
|
||||
<%= if @editor_sheet_state != :collapsed do %>
|
||||
<div class="editor-sheet-header-left">
|
||||
<span class="editor-sheet-title">Page editor</span>
|
||||
<span :if={@editor_dirty} class="editor-sheet-dirty" aria-live="polite">
|
||||
<span class="editor-sheet-dirty-dot" aria-hidden="true" />
|
||||
<span>Unsaved</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="editor-sheet-header-actions">
|
||||
<button
|
||||
:if={@editor_save_status == :saved}
|
||||
type="button"
|
||||
class="admin-btn admin-btn-sm admin-btn-ghost"
|
||||
disabled
|
||||
>
|
||||
Saved ✓
|
||||
</button>
|
||||
<button
|
||||
:if={@editor_save_status != :saved}
|
||||
type="button"
|
||||
phx-click="editor_save"
|
||||
class={["admin-btn admin-btn-sm", @editor_dirty && "admin-btn-primary"]}
|
||||
disabled={!@editor_dirty}
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="editor-panel-header-actions">
|
||||
<button
|
||||
:if={@editor_save_status == :saved}
|
||||
type="button"
|
||||
class="admin-btn admin-btn-sm admin-btn-ghost"
|
||||
disabled
|
||||
>
|
||||
Saved ✓
|
||||
</button>
|
||||
<button
|
||||
:if={@editor_save_status != :saved}
|
||||
type="button"
|
||||
phx-click="editor_save"
|
||||
class={["admin-btn admin-btn-sm", @editor_dirty && "admin-btn-primary"]}
|
||||
disabled={!@editor_dirty}
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%!-- Content area (hidden when collapsed) --%>
|
||||
<div class="editor-sheet-content">
|
||||
<div class="editor-panel-content">
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
Reference in New Issue
Block a user