Files
basecoat/docs/src/components/dialog.njk
T
2025-05-07 21:49:31 +08:00

206 lines
12 KiB
Plaintext

---
layout: layouts/page.njk
title: Dialog
description: A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
toc:
- label: Usage
id: usage
children:
- label: HTML + Javascript
id: usage-default
- label: Jinja and Nunjucks
id: usage-macro
- label: Examples
id: examples
children:
- label: Scrollable content
id: example-scrollable-content
---
{% from "macros/code_block.njk" import code_block %}
{% from "macros/code_preview.njk" import code_preview %}
{% from "dialog.njk" import dialog %}
{% set code_html %}
{% set footer %}
<button class="btn-outline" @click="open = false">Cancel</button>
<button class="btn" @click="open = false">Save changes</button>
{% endset %}
{% call dialog(
id="demo-dialog-edit-profile",
title="Edit profile",
description="Make changes to your profile here. Click save when you're done.",
main_attrs={"x-ref": "myDialog"},
trigger="Edit Profile",
trigger_attrs={"class": "btn-outline"},
content_attrs={"class": "w-full sm:max-w-[425px] max-h-[612px]"},
footer=footer,
register_on=["alpine:init", "htmx:afterSwap"]
) %}
<form class="form grid gap-4">
<div class="grid gap-3">
<label for="demo-dialog-edit-profile-name">Name</label>
<input type="text" value="Pedro Duarte" id="demo-dialog-edit-profile-name" x-ref="focusOnOpen" />
</div>
<div class="grid gap-3">
<label for="demo-dialog-edit-profile-username">Username</label>
<input type="text" value="@peduarte" id="demo-dialog-edit-profile-username" />
</div>
</form>
{% endcall %}
{% endset %}
{% set code_script %}
<script>
{% fetchCode "src/js/dialog.js" %}
document.addEventListener('alpine:init', () => {
window.basecoat.registerDialog(Alpine);
});
</script>
{% endset %}
{{ code_preview("dialog", code_script | prettyHtml ~ code_html | prettyHtml) }}
<h2 id="usage"><a href="#usage">Usage</a></h2>
<h3 id="usage-default"><a href="#usage-default">HTML + Javascript</a></h3>
<div class="alert my-6">
{% lucide "circle-alert" %}
<h2>This component requires Javascript.</h2>
</div>
<section class="prose">
<p>The component is structured as such:</p>
<ul>
<li>A <code>&lt;div class="dialog"&gt;</code> which wraps around the entire component and holds it state (e.g. open/close).</li>
<li>A <code>&lt;button&gt;</code> that acts as the trigger to open or close the popover.</li>
<li>A <code>&lt;div role="dialog"&gt;</code> that holds the dialog itself. It also acts as the backdrop for the dialog.</li>
<li>Inside of it, we have:
<ul>
<li>A <code>&lt;header&gt;</code> that contains the title (<code>&lt;h2&gt;</code>) and description (<code>&lt;p&gt;</code>) of the dialog.</li>
<li>A <code>&lt;section&gt;</code> for the content.</li>
<li>A <code>&lt;footer&gt;</code> that usually contains actions.</li>
<li>A close <code>&lt;button&gt;</code>.</li>
</ul>
</li>
</ul>
<p>You can include the Javascript code provided below, load it as an individual file or use the CLI. Some Alpine.js properties are also required on certain elements (e.g. <code class="text-xs">x-bind</code>, <code class="text-xs">x-data</code>, <code class="text-xs">@click</code>).</p>
</section>
<div class="flex flex-wrap gap-2 my-6">
<a class="badge-outline" href="/installation/#install-js">
Components with Javascript
{% lucide "arrow-right" %}
</a>
<a class="badge-outline" href="/installation/#install-cli">
Use the CLI
{% lucide "arrow-right" %}
</a>
<a class="badge-outline" href="https://github.com/hunvreus/basecoat/blob/main/src/js/dialog.js" target="_blank">
Individual JS file (dialog.js)
{% lucide "arrow-right" %}
</a>
</div>
{% from "tabs.njk" import tabs %}
{% set tabsets = [
{ tab: "HTML", panel: code_block(code_html | prettyHtml, class="") },
{ tab: "Javascipt (Alpine.js)", panel: code_block(code_script | prettyHtml, class="") }
] %}
{{ tabs(id="combobox", tabsets=tabsets) }}
<section class="prose">
<p>The component will dispatch <code>dialog:opened</code> and <code>dialog:closed</code> events when the dialog is opened or closed. You can also dispatch <code>dialog:open</code> and <code>dialog:close</code> events to open or close the dialog programmatically. You will need the element to have an <code>id</code> to be able to target it (e.g. <code>&lt;div id="my-dialog" class="dialog"&gt;</code>):</p>
</section>
{% set code_dispatch %}<button type="button" x-init @click="$dispatch('dialog:open', { id: 'my-dialog' })">
Open #my-dialog
</button>{% endset %}
{{ code_block(code_dispatch | prettyHtml, "html") }}
<h3 id="usage-macro"><a href="#usage-macro">Jinja and Nunjucks</a></h3>
<div class="prose">
<p>You can use the <code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-xs">dialog()</code> Nunjucks or Jinja macro for this component.</p>
</div>
<div class="flex flex-wrap gap-2 my-6">
<a class="badge-outline" href="/installation/#install-macros" target="_blank">
Use Nunjucks or Jinja macros
{% lucide "arrow-right" %}
</a>
<a class="badge-outline" href="https://github.com/hunvreus/basecoat/blob/main/src/jinja/dialog.html.jinja" target="_blank">
Jinja macro
{% lucide "arrow-right" %}
</a>
<a class="badge-outline" href="https://github.com/hunvreus/basecoat/blob/main/src/nunjucks/dialog.njk" target="_blank">
Nunjucks macro
{% lucide "arrow-right" %}
</a>
</div>
{% set raw_code %}{% raw %}{% set footer %}
<button class="btn-outline" @click="open = false">Cancel</button>
<button class="btn" @click="open = false">Save changes</button>
{% endset %}
{% call dialog(
id="demo-dialog-edit-profile",
title="Edit profile",
description="Make changes to your profile here. Click save when you're done.",
main_attrs={"x-ref": "myDialog"},
trigger="Edit Profile",
trigger_attrs={"class": "btn-outline"},
content_attrs={"class": "w-full sm:max-w-[425px] max-h-[612px]"},
footer=footer,
register_on=["alpine:init", "htmx:afterSwap"]
) %}
<form class="form grid gap-4">
<div class="grid gap-3">
<label for="demo-dialog-edit-profile-name">Name</label>
<input type="text" value="Pedro Duarte" id="demo-dialog-edit-profile-name" />
</div>
<div class="grid gap-3">
<label for="demo-dialog-edit-profile-username">Username</label>
<input type="text" value="@peduarte" id="demo-dialog-edit-profile-username" />
</div>
</form>
{% endcall %}{% endraw %}{% endset%}
{{ code_block(raw_code, "jinja") }}
<h2 id="examples"><a href="#examples">Examples</a></h2>
<h3 id="example-scrollable-content"><a href="#example-scrollable-content">Scrollable content</a></h3>
{% set code %}
{% set footer %}
<button class="btn-outline" @click="open = false">Close</button>
{% endset %}
{% call dialog(
id="dialog-example",
title="Scrollable Content",
description="This is a dialog with scrollable content.",
main_attrs={"x-ref": "myDialog"},
trigger="Scrollable Content",
trigger_attrs={"class": "btn-outline"},
content_attrs={"class": "w-full sm:max-w-[425px] max-h-[612px]"},
content_body_attrs={"class": "overflow-y-auto scrollbar"},
footer=footer,
register_on=["alpine:init", "htmx:afterSwap"]
) %}
<div class="space-y-4 text-sm">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
{% endcall %}
{% endset %}
{{ code_preview("dialog-scrollable-content", code | prettyHtml) }}