{% load i18n brickwork_icons %} {% comment %} Slide-over / side panel (04-interfaces section 4b, 0.14.0, brickwork#55). Consumed by EXTENDING, exactly like _modal.html: a consumer's slide-over partial opens with {% extends "brickwork/components/_slide_over.html" %} and fills the named blocks. Reuses the modal's a11y machinery (dialog semantics, focus trap, dismissal contract) but is edge-anchored instead of centred, so it can sit BESIDE page content rather than over it. DUAL CONSUMPTION, one partial, two documented render paths (BR-BW-HTMX-001, mirroring the modal): 1. htmx path (needs the #bw-slide-over-root container shell/base.html ships from 0.14.0): the trigger is a real anchor carrying hx-get hx-target="#bw-slide-over-root" hx-swap="innerHTML"; the view returns the consumer's slide-over partial and on insertion bwSlideOver opens it as an edge overlay. 2. no-JS floor: the SAME anchor's href is a full-page route; the view (branching on request.htmx) renders the SAME consumer partial inside a full page. With no JavaScript this markup is simply an in-flow, visible panel on that page: the slide-over is then a page, which is the floor. Nothing here is display:none at rest; the scrim and fixed overlay positioning apply only under the JS-set bw-slide-over--open state, so the floor never hides content behind JavaScript. DEDICATED root, not #bw-modal-root (0.14.0 build decision): a modal and a slide-over must be able to coexist open (e.g. a split-shell detail screen where a slide-over sits beside content while a confirm modal opens over it), and #bw-modal-root's own CSS and bwModal's htmx-path auto-open detection are both keyed to that one container. Reusing it would either block that coexistence or force bwModal and bwSlideOver to disambiguate inside a shared root; a second stable root is simpler and matches the one-container-per-overlay-family shape shell/base.html already uses for the modal and toast regions. Named blocks (semver-public, BR-BW-TPL-001): title: present SINCE 3.4.0, the concise successor to the deprecated slide_over_title block below (ADR-077 SS4). Defaults to rendering {{ title }} inside the chrome-owned heading (heading-sm type role). body: present SINCE 3.4.0, the concise successor to the deprecated slide_over_body block below (ADR-077 SS4). The panel content. A form inside it follows BR-BW-HTMX-003 unchanged (hx-target="this" hx-swap="outerHTML", 422 re-render with inline errors); a failed request NEVER closes the panel (CBH-026 applied here). On success the view closes it server-side: respond 204 (or with OOB toast content) plus HX-Trigger: {"bw:slide-over:close": {"id": ""}}; bwSlideOver listens for bw:slide-over:close at the window. footer: present SINCE 3.4.0, the concise successor to the deprecated slide_over_footer block below (ADR-077 SS4). Empty renders nothing; the filler owns the wrapper element (write ), matching _modal.html's footer convention. Sticky header/footer with a scrolling body. slide_over_title, slide_over_body, slide_over_footer: present since before 3.4.0 (unchanged back to at least 3.2.1). DEPRECATED, removed at 4.0 (ADR-077 SS4, BR-BW-TPL-001/BR-BW-VER-001). Kept as additional empty extension points for backwards compatibility: a shipped block name cannot be renamed silently. Both a concise block and its deprecated counterpart render when both are filled; a caller migrating to the concise name fills title/body/footer only. A block name this file does not define is SILENTLY DISCARDED by Django: no error, no warning, DEBUG=True does not catch it. A consumer pinned below 3.4.0 who reads title/body/footer from a newer checkout gets a structurally valid, entirely empty panel that still passes template loading; check this header against your pinned version before relying on a name. body and footer stay markup-only by design (icvoss/django-brickwork#398 sweep): body is the panel content, commonly a form wired to BR-BW-HTMX-003, and footer's filler owns its own