mirror of
https://github.com/hunvreus/basecoat.git
synced 2026-11-13 13:48:28 +00:00
Starting work on documentation
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Accordion
|
||||
description: A vertically stacked set of interactive headings that each reveal a section of content.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
---
|
||||
|
||||
<div class="alert mb-6">
|
||||
{% lucide "circle-alert" %}
|
||||
<h2>There is no dedicated accordion component in Basecoat.</h2>
|
||||
</div>
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% set code %}<section
|
||||
x-init
|
||||
@click="
|
||||
const clickedSummary = $event.target.closest('summary');
|
||||
if (!clickedSummary) return;
|
||||
const clickedDetails = clickedSummary.closest('details');
|
||||
if (!clickedDetails) return;
|
||||
$el.querySelectorAll('details').forEach(detailsEl => {
|
||||
if (detailsEl !== clickedDetails) {
|
||||
detailsEl.removeAttribute('open');
|
||||
}
|
||||
});
|
||||
"
|
||||
>
|
||||
<details class="group border-b last:border-b-0 ">
|
||||
<summary class="w-full focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] transition-all outline-none rounded-md">
|
||||
<h2 class="flex flex-1 items-start justify-between gap-4 py-4 text-left text-sm font-medium hover:underline ">
|
||||
Is it accessible?
|
||||
{% lucide "chevron-down", { "class": "text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200 group-open:rotate-180" } %}
|
||||
</h2>
|
||||
</summary>
|
||||
<section class="pb-4">
|
||||
<p class="text-sm">Yes. It adheres to the WAI-ARIA design pattern.</p>
|
||||
</section>
|
||||
</details>
|
||||
<details class="group border-b last:border-b-0">
|
||||
<summary class="w-full focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] transition-all outline-none rounded-md">
|
||||
<h2 class="flex flex-1 items-start justify-between gap-4 py-4 text-left text-sm font-medium hover:underline ">
|
||||
Is it styled?
|
||||
{% lucide "chevron-down", { "class": "text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200 group-open:rotate-180" } %}
|
||||
</h2>
|
||||
</summary>
|
||||
<section class="pb-4">
|
||||
<p class="text-sm">Yes. It comes with default styles that matches the other components' aesthetic.</p>
|
||||
</section>
|
||||
</details>
|
||||
<details class="group border-b last:border-b-0">
|
||||
<summary class="w-full focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] transition-all outline-none rounded-md">
|
||||
<h2 class="flex flex-1 items-start justify-between gap-4 py-4 text-left text-sm font-medium hover:underline ">
|
||||
Is it animated?
|
||||
{% lucide "chevron-down", { "class": "text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200 group-open:rotate-180" } %}
|
||||
</h2>
|
||||
</summary>
|
||||
<section>
|
||||
<p class="text-sm whitespace-pre-wrap">Yes. It's animated by default, but you can disable it if you prefer.</p>
|
||||
</section>
|
||||
</details>
|
||||
</section>
|
||||
{% endset %}
|
||||
{{ code_preview("accordion", code | prettyHtml, "w-full max-w-md") }}
|
||||
|
||||
<h2 id="usage"><a href="#usage">Usage</a></h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>Basecoat animates <code><details></code> elements by default. The example above shows how to use Alpine.js, Tailwind and <code><details></code> elements to implement a simple accordion.</p>
|
||||
</section>
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Alert Dialog
|
||||
description: A modal dialog that interrupts the user with important content and expects a response.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
children:
|
||||
- label: Default
|
||||
id: usage-default
|
||||
- label: Jinja or Nunjucks
|
||||
id: usage-jinja
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% from "components/dialog.njk" import dialog %}
|
||||
|
||||
<div class="alert mb-6">
|
||||
{% lucide "info" %}
|
||||
<h2>The Alert Dialog component uses the <a href="/components/dialog" class="font-medium underline underline-offset-4">Dialog</a> component.</h2>
|
||||
</div>
|
||||
|
||||
{% set code %}{% set footer %}
|
||||
<button class="btn-outline" @click="open = false">Cancel</button>
|
||||
<button class="btn-primary" @click="open = false">Continue</button>
|
||||
{% endset %}
|
||||
{{ dialog(
|
||||
id="demo-alert-dialog",
|
||||
title="Are you absolutely sure?",
|
||||
description="This action cannot be undone. This will permanently delete your account and remove your data from our servers.",
|
||||
trigger="Open Alert Dialog",
|
||||
trigger_attrs={"class": "btn-outline"},
|
||||
footer=footer,
|
||||
close_button=false,
|
||||
close_on_overlay_click=false
|
||||
) }}{% endset %}
|
||||
{{ code_preview("alert-dialog", code | prettyHtml) }}
|
||||
|
||||
<h2 id="usage"><a href="#usage">Usage</a></h2>
|
||||
|
||||
<h3 id="usage-default"><a href="#usage-default">Default</a></h3>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>The Alert Dialog component uses the same Alpine.js code as the <a href="/components/dialog" class="font-medium underline underline-offset-4">Dialog</a> component with one small difference: we set <code>initialCloseOnOverlayClick</code> to <code>false</code> to prevent the dialog from closing when the overlay is clicked.</p>
|
||||
</section>
|
||||
|
||||
{{ code_block(code | prettyHtml) }}
|
||||
|
||||
<h3 id="usage-jinja"><a href="#usage-jinja">Jinja or Nunjucks</a></h3>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>If you use Jinja (or Nunjucks), you can use the Dialog macro directly, making sure to set <code>close_on_overlay_click</code> to <code>False</code> (or <code>false</code> for Nunjucks).</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/jinja-and-nunjucks">Read more about using Basecoat with Jinja or Nunjucks</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/components/dialog">Read more about the Dialog component</a>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{% set raw_code %}{% raw %}{% set footer %}
|
||||
<button class="btn-outline" @click="open = false">Cancel</button>
|
||||
<button class="btn-primary" @click="open = false">Continue</button>
|
||||
{% endset %}
|
||||
{{ dialog(
|
||||
id="demo-alert-dialog",
|
||||
title="Are you absolutely sure?",
|
||||
description="This action cannot be undone. This will permanently delete your account and remove your data from our servers.",
|
||||
trigger="Open Alert Dialog",
|
||||
trigger_attrs={"class": "btn-outline"},
|
||||
footer=footer,
|
||||
close_button=False,
|
||||
close_on_overlay_click=False
|
||||
) }}{% endraw %}
|
||||
{% endset%}
|
||||
{{ code_block(raw_code, "jinja") }}
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Alert
|
||||
description: Displays a callout for user attention.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
- label: Examples
|
||||
id: examples
|
||||
children:
|
||||
- label: Destructive
|
||||
id: example-destructive
|
||||
- label: No description
|
||||
id: example-no-description
|
||||
- label: No icon
|
||||
id: example-no-icon
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
{% set code %}<div class="alert">
|
||||
{% lucide "circle-check" %}
|
||||
<h2>Success! Your changes have been saved</h2>
|
||||
<section>This is an alert with icon, title and description.</section>
|
||||
</div>{% endset %}
|
||||
{{ code_preview("alert", code) }}
|
||||
|
||||
<h2 id="usage">Usage</h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>You can use one of the two classes: <code>alert</code> or <code>alert-dialog</code> with any of the following children:</p>
|
||||
<ul>
|
||||
<li>A SVG icon,</li>
|
||||
<li>A <code><h2></code> for the title.</li>
|
||||
<li>A <code><section></code> for the description.</li>
|
||||
</ul>
|
||||
<p><a href="/kitchen-sink#alert">See the kitchen sink for more examples.</a></p>
|
||||
</section>
|
||||
|
||||
{{ code_block(code) }}
|
||||
|
||||
<h2 id="examples"><a href="#examples">Examples</a></h2>
|
||||
|
||||
<h3 id="example-destructive"><a href="#example-destructive">Destructive</a></h3>
|
||||
|
||||
{% set code %}<div class="alert-destructive">
|
||||
{% lucide "circle-alert" %}
|
||||
<h2>Something went wrong!</h2>
|
||||
<section>Your session has expired. Please log in again.</section>
|
||||
</div>{% endset %}
|
||||
{{ code_preview("alert-destructive", code) }}
|
||||
|
||||
<h3 id="example-no-description"><a href="#example-no-description">No description</a></h3>
|
||||
|
||||
{% set code %}
|
||||
<div class="alert">
|
||||
{% lucide "shield-alert" %}
|
||||
<h2>This is a very long alert title that demonstrates how the component handles extended text content and potentially wraps across multiple lines</h2>
|
||||
</div>{% endset %}
|
||||
{{ code_preview("alert-no-description", code) }}
|
||||
|
||||
<h3 id="example-no-icon"><a href="#example-no-icon">No icon</a></h3>
|
||||
|
||||
{% set code %}<div class="alert">
|
||||
<h2>Success! Your changes have been saved</h2>
|
||||
<section>This is an alert with icon, title and description.</section>
|
||||
</div>{% endset %}
|
||||
{{ code_preview("alert-no-icon", code) }}
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Avatar
|
||||
description: An image element with a fallback for representing the user.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
<div class="alert mb-6">
|
||||
{% lucide "circle-alert" %}
|
||||
<h2>There is no dedicated accordion component in Basecoat.</h2>
|
||||
</div>
|
||||
|
||||
{% set code %}<img class="size-8 shrink-0 object-cover rounded-full" alt="@hunvreus" src="https://github.com/hunvreus.png">{% endset %}
|
||||
{{ code_preview("avatar", code, "max-w-md") }}
|
||||
|
||||
<h2 id="usage"><a href="#usage">Usage</a></h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>Avatars are fairly simple to implement with Tailwind. The example above shows how to implement one with Tailwind and an <code><img></code> element. <a href="/kitchen-sink#avatar">You can find more examples in the kitchen sink</a>.</p>
|
||||
</section>
|
||||
|
||||
{{ code_block(code) }}
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Badge
|
||||
description: Displays a badge or a component that looks like a badge.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
- label: Examples
|
||||
id: examples
|
||||
children:
|
||||
- label: Primary
|
||||
id: example-primary
|
||||
- label: Secondary
|
||||
id: example-secondary
|
||||
- label: Destructive
|
||||
id: example-destructive
|
||||
- label: Outline
|
||||
id: example-outline
|
||||
- label: With icon
|
||||
id: example-with-icon
|
||||
- label: Link
|
||||
id: example-link
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
{% set code %}<span class="badge">Badge</span>{% endset %}
|
||||
{{ code_preview("badge", code) }}
|
||||
|
||||
<h2 id="usage"><a href="#usage">Usage</a></h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>Simply use one of the badge classes: <code>badge</code>, <code>badge-primary</code>, <code>badge-secondary</code>, <code>badge-destructive</code> or <code>badge-outline</code>. <a href="/kitchen-sink#badge">You can find more examples in the kitchen sink</a>.</p>
|
||||
</section>
|
||||
|
||||
{{ code_block(code) }}
|
||||
|
||||
<h2 id="examples"><a href="#examples">Examples</a></h2>
|
||||
|
||||
<h3 id="example-primary"><a href="#example-primary">Primary</a></h3>
|
||||
|
||||
{% set code %}<span class="badge">Primary</span>{% endset %}
|
||||
{{ code_preview("badge-primary", code) }}
|
||||
|
||||
<h3 id="example-secondary"><a href="#example-secondary">Secondary</a></h3>
|
||||
|
||||
{% set code %}<span class="badge-secondary">Secondary</span>{% endset %}
|
||||
{{ code_preview("badge-secondary", code) }}
|
||||
|
||||
<h3 id="example-destructive"><a href="#example-destructive">Destructive</a></h3>
|
||||
|
||||
{% set code %}<span class="badge-destructive">Destructive</span>{% endset %}
|
||||
{{ code_preview("badge-destructive", code) }}
|
||||
|
||||
<h3 id="example-outline"><a href="#example-outline">Outline</a></h3>
|
||||
|
||||
{% set code %}<span class="badge-outline">Outline</span>{% endset %}
|
||||
{{ code_preview("badge-outline", code) }}
|
||||
|
||||
<h3 id="example-with-icon"><a href="#example-with-icon">With icon</a></h3>
|
||||
|
||||
{% set code %}<span class="badge-destructive">
|
||||
{% lucide "circle-alert" %}
|
||||
With icon
|
||||
</span>{% endset %}
|
||||
{{ code_preview("badge-with-icon", code) }}
|
||||
|
||||
<h3 id="example-link"><a href="#example-link">Link</a></h3>
|
||||
|
||||
{% set code %}<a href="#" class="badge-outline">
|
||||
Link
|
||||
{% lucide "arrow-right" %}
|
||||
</a>{% endset %}
|
||||
{{ code_preview("badge-link", code) }}
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Breadcrumb
|
||||
description: Displays the path to the current resource using a hierarchy of links.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
---
|
||||
|
||||
<div class="alert mb-6">
|
||||
{% lucide "circle-alert" %}
|
||||
<h2>There is no dedicated breadcrumb component in Basecoat.</h2>
|
||||
</div>
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "components/dropdown-menu.njk" import dropdown_menu %}
|
||||
{% set code %}<ol class="text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5">
|
||||
<li class="inline-flex items-center gap-1.5">
|
||||
<a href="#" class="hover:text-foreground transition-colors">Home</a>
|
||||
</li>
|
||||
<li>{% lucide "chevron-right", { "class": "size-3.5" } %}</li>
|
||||
<li class="inline-flex items-center gap-1.5">
|
||||
{% set trigger %}
|
||||
{% lucide "ellipsis" %}
|
||||
{% endset %}
|
||||
{% call dropdown_menu(
|
||||
id="demo-breadcrumb-menu",
|
||||
trigger=trigger,
|
||||
trigger_attrs={"class": "flex size-9 items-center justify-center h-4 w-4 hover:text-foreground cursor-pointer"}
|
||||
) %}
|
||||
<nav role="menu">
|
||||
<button type="button" role="menuitem">Documentation</button>
|
||||
<button type="button" role="menuitem">Themes</button>
|
||||
<button type="button" role="menuitem">GitHub</button>
|
||||
</nav>
|
||||
{% endcall %}
|
||||
</li>
|
||||
<li>{% lucide "chevron-right", { "class": "size-3.5" } %}</li>
|
||||
<li class="inline-flex items-center gap-1.5">
|
||||
<a href="#" class="hover:text-foreground transition-colors">Components</a>
|
||||
</li>
|
||||
<li>{% lucide "chevron-right", { "class": "size-3.5" } %}</li>
|
||||
<li class="inline-flex items-center gap-1.5">
|
||||
<span class="text-foreground font-normal">Breadcrumb</span>
|
||||
</li>
|
||||
</ol>{% endset %}
|
||||
{{ code_preview("dropdown-menu", code | prettyHtml) }}
|
||||
|
||||
<h2 id="usage"><a href="#usage">Usage</a></h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>The example below shows how to implement it with Tailwind and the <a href="/components/dropdown-menu" class="font-medium underline underline-offset-4">Dropdown Menu</a> component.</p>
|
||||
</section>
|
||||
@@ -0,0 +1,141 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Button
|
||||
description: Displays a button or a component that looks like a button.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
- label: Examples
|
||||
id: examples
|
||||
children:
|
||||
- label: Primary
|
||||
id: example-primary
|
||||
- label: Secondary
|
||||
id: example-secondary
|
||||
- label: Destructive
|
||||
id: example-destructive
|
||||
- label: Outline
|
||||
id: example-outline
|
||||
- label: Ghost
|
||||
id: example-ghost
|
||||
- label: Link
|
||||
id: example-link
|
||||
- label: Icon
|
||||
id: example-icon
|
||||
- label: With Icon
|
||||
id: example-with-icon
|
||||
- label: Loading
|
||||
id: example-loading
|
||||
- label: Large
|
||||
id: example-large
|
||||
- label: Small
|
||||
id: example-small
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
{% set code %}<button class="btn">Button</button>{% endset %}
|
||||
{{ code_preview("button", code) }}
|
||||
|
||||
<h2 id="usage">Usage</h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>You can use one of the <code>btn</code> classes to style any element as a button:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<b>Variants</b>:
|
||||
<ul>
|
||||
<li><code>btn</code> or <code>btn-primary</code> for primary
|
||||
buttons,</li>
|
||||
<li><code>btn-secondary</code> for secondary buttons.</li>
|
||||
<li><code>btn-destructive</code> for destructive buttons.</li>
|
||||
<li><code>btn-outline</code> for outline buttons.</li>
|
||||
<li><code>btn-ghost</code> for ghost buttons.</li>
|
||||
<li><code>btn-link</code> for link buttons.</li>
|
||||
<li><code>btn-icon</code> for icon buttons. This can be combined with other variants, for example <code>btn-icon-destructive</code>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>Sizes</b>:
|
||||
<ul>
|
||||
<li><code>btn-sm</code> for small buttons.</li>
|
||||
<li><code>btn-lg</code> for large buttons.</li>
|
||||
<li>You can combine sizes with any variant, for example <code>btn-lg-destructive</code> or <code>btn-sm-icon-outline</code>.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{{ code_block(code) }}
|
||||
|
||||
<h2 id="examples"><a href="#examples">Examples</a></h2>
|
||||
|
||||
<h3 id="example-primary"><a href="#example-primary">Primary</a></h3>
|
||||
|
||||
{% set code %}<button class="btn">Primary</button>{% endset %}
|
||||
{{ code_preview("button-primary", code) }}
|
||||
|
||||
<h3 id="example-secondary"><a href="#example-secondary">Secondary</a></h3>
|
||||
|
||||
{% set code %}<button class="btn-secondary">Button</button>{% endset %}
|
||||
{{ code_preview("button-secondary", code) }}
|
||||
|
||||
<h3 id="example-destructive"><a href="#example-destructive">Destructive</a></h3>
|
||||
|
||||
{% set code %}<button class="btn-destructive">Destructive</button>{% endset %}
|
||||
{{ code_preview("button-destructive", code) }}
|
||||
|
||||
<h3 id="example-outline"><a href="#example-outline">Outline</a></h3>
|
||||
|
||||
{% set code %}<button class="btn-outline">Outline</button>{% endset %}
|
||||
{{ code_preview("button-outline", code) }}
|
||||
|
||||
<h3 id="example-ghost"><a href="#example-ghost">Ghost</a></h3>
|
||||
|
||||
{% set code %}<button class="btn-ghost">Ghost</button>{% endset %}
|
||||
{{ code_preview("button-ghost", code) }}
|
||||
|
||||
<h3 id="example-link"><a href="#example-link">Link</a></h3>
|
||||
|
||||
{% set code %}<button class="btn-link">Link</button>{% endset %}
|
||||
{{ code_preview("button-link", code) }}
|
||||
|
||||
<h3 id="example-icon"><a href="#example-icon">Icon</a></h3>
|
||||
|
||||
{% set code %}<button class="btn-icon-outline">
|
||||
{% lucide "chevron-right" %}
|
||||
</button>{% endset %}
|
||||
{{ code_preview("button-icon", code) }}
|
||||
|
||||
<h3 id="example-with-icon"><a href="#example-with-icon">With Icon</a></h3>
|
||||
|
||||
{% set code %}<button class="btn">
|
||||
{% lucide "send" %}
|
||||
Send email
|
||||
</button>{% endset %}
|
||||
{{ code_preview("button-with-icon", code) }}
|
||||
|
||||
<h3 id="example-loading"><a href="#example-loading">Loading</a></h3>
|
||||
|
||||
{% set code %}<button class="btn-outline" disabled>
|
||||
{% lucide "loader", { "class": "animate-spin" } %}
|
||||
Loading
|
||||
</button>{% endset %}
|
||||
{{ code_preview("button-loading", code) }}
|
||||
|
||||
<h3 id="example-large"><a href="#example-large">Large</a></h3>
|
||||
|
||||
{% set code %}<button class="btn-lg">
|
||||
{% lucide "shopping-cart" %}
|
||||
Buy
|
||||
</button>{% endset %}
|
||||
{{ code_preview("button-large", code) }}
|
||||
|
||||
<h3 id="example-small"><a href="#example-small">Small</a></h3>
|
||||
|
||||
{% set code %}<button class="btn-sm-icon-destructive">
|
||||
{% lucide "trash" %}
|
||||
</button>{% endset %}
|
||||
{{ code_preview("button-small", code) }}
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Card
|
||||
description: Displays a card with header, content, and footer.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
- label: Examples
|
||||
id: examples
|
||||
children:
|
||||
- label: With content and footer
|
||||
id: example-with-content-and-footer
|
||||
- label: With image
|
||||
id: example-with-image
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
{% set code %}<div class="card w-full">
|
||||
<header>
|
||||
<h2>Login to your account</h2>
|
||||
<p>Enter your details below to login to your account</p>
|
||||
</header>
|
||||
<section>
|
||||
<form class="form grid gap-6">
|
||||
<div class="grid gap-2">
|
||||
<label for="demo-card-form-email">Email</label>
|
||||
<input type="email" id="demo-card-form-email">
|
||||
</div>
|
||||
<div class="grid gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<label for="demo-card-form-password">Password</label>
|
||||
<a href="#" class="ml-auto inline-block text-sm underline-offset-4 hover:underline">Forgot your password?</a>
|
||||
</div>
|
||||
<input type="password" id="demo-card-form-password">
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
<footer class="flex flex-col items-center gap-2">
|
||||
<button type="button" class="btn w-full">Login</button>
|
||||
<button type="button" class="btn-outline w-full">Login with Google</button>
|
||||
<p class="mt-4 text-center text-sm">Don't have an account? <a href="#" class="underline-offset-4 hover:underline">Sign up</a></p>
|
||||
</footer>
|
||||
</div>{% endset %}
|
||||
{{ code_preview("card", code, "w-full max-w-sm") }}
|
||||
|
||||
<h2 id="usage">Usage</h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>Simply add the <code>card</code> class to any element and then define any of the children elements:</p>
|
||||
<ul>
|
||||
<li>A <code><header></code> for the card header, which can contain a <code><h2></code> for the title and a <code><p></code> for the description.</li>
|
||||
<li>A <code><section></code> for the card content.</li>
|
||||
<li>A <code><footer></code> for the card footer.</li>
|
||||
</ul>
|
||||
<p><a href="/kitchen-sink#alert">See the kitchen sink for more examples.</a></p>
|
||||
</section>
|
||||
|
||||
{% set code %}<div class="card">
|
||||
<header>
|
||||
<h2>Card Title</h2>
|
||||
<p>Card Description</p>
|
||||
</header>
|
||||
<section>
|
||||
<p>Card Content</p>
|
||||
</section>
|
||||
<footer>
|
||||
<p>Card Footer</p>
|
||||
</footer>
|
||||
</div>{% endset %}
|
||||
{{ code_block(code) }}
|
||||
|
||||
<h2 id="examples"><a href="#examples">Examples</a></h2>
|
||||
|
||||
<h3 id="example-with-content-and-footer"><a href="#example-with-content-and-footer">With content and footer</a></h3>
|
||||
|
||||
{% set code %}<div class="card">
|
||||
<header>
|
||||
<h2>Meeting Notes</h2>
|
||||
<p>Transcript from the meeting with the client.</p>
|
||||
</header>
|
||||
<section class="text-sm">
|
||||
<p>Client requested dashboard redesign with focus on mobile responsiveness.</p>
|
||||
<ol class="mt-4 flex list-decimal flex-col gap-2 pl-6">
|
||||
<li>New analytics widgets for daily/weekly metrics</li>
|
||||
<li>Simplified navigation menu</li>
|
||||
<li>Dark mode support</li>
|
||||
<li>Timeline: 6 weeks</li>
|
||||
<li>Follow-up meeting scheduled for next Tuesday</li>
|
||||
</ol>
|
||||
</section>
|
||||
<footer class="flex items-center">
|
||||
<div class="flex -space-x-2 [&_img]:ring-card [&_img]:ring-2 [&_img]:grayscale [&_img]:size-8 [&_img]:shrink-0 [&_img]:object-cover [&_img]:rounded-full">
|
||||
<img alt="@hunvreus" src="https://github.com/hunvreus.png">
|
||||
<img alt="@shadcn" src="https://github.com/shadcn.png">
|
||||
<img alt="@adamwathan" src="https://github.com/adamwathan.png">
|
||||
</div>
|
||||
</footer>
|
||||
</div>{% endset %}
|
||||
{{ code_preview("card-with-content-and-footer", code) }}
|
||||
|
||||
<h3 id="example-with-image"><a href="#example-with-image">With image</a></h3>
|
||||
|
||||
{% set code %}<div class="card">
|
||||
<header>
|
||||
<h2>Is this an image?</h2>
|
||||
<p>This is a card with an image.</p>
|
||||
</header>
|
||||
<section class="px-0">
|
||||
<img
|
||||
alt="Photo by Drew Beamer"
|
||||
loading="lazy"
|
||||
width="500"
|
||||
height="500"
|
||||
class="aspect-video object-cover" style="color:transparent"
|
||||
srcset="
|
||||
https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&dpr=2&q=80&w=640&q=75 1x,
|
||||
https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&dpr=2&q=80&w=1080&q=75 2x
|
||||
"
|
||||
src="https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&dpr=2&q=80&w=1080&q=75"
|
||||
/>
|
||||
</section>
|
||||
<footer class="flex items-center gap-2">
|
||||
<span class="badge-outline">
|
||||
{% lucide "bed" %}
|
||||
1
|
||||
</span>
|
||||
<span class="badge-outline">
|
||||
{% lucide "bath" %}
|
||||
2
|
||||
</span>
|
||||
<span class="badge-outline">
|
||||
{% lucide "land-plot" %}
|
||||
350m²
|
||||
</span>
|
||||
<span class="ml-auto font-medium tabular-nums">
|
||||
$135,000
|
||||
</span>
|
||||
</footer>
|
||||
</div>{% endset %}
|
||||
{{ code_preview("card-with-image", code) }}
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Checkbox
|
||||
description: A control that allows the user to toggle between checked and not checked.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
- label: Examples
|
||||
id: examples
|
||||
children:
|
||||
- label: Disabled
|
||||
id: example-disabled
|
||||
- label: With text
|
||||
id: example-with-text
|
||||
- label: Form
|
||||
id: example-form
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
{% set code %}<label class="label gap-3">
|
||||
<input type="checkbox" class="input">
|
||||
Accept terms and conditions
|
||||
</label>{% endset %}
|
||||
{{ code_preview("checkbox", code) }}
|
||||
|
||||
<h2 id="usage">Usage</h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>Simply add the <code>input</code> class to your <code><input type="radio"></code> elements or have a parent with the <code>form</code> class (<a href="/components/form">read more about form</a>). You can also set the <code>aria-invalid</code> attribute to <code>true</code> to make the input invalid.</p>
|
||||
</section>
|
||||
|
||||
{{ code_block(code) }}
|
||||
|
||||
<h2 id="examples"><a href="#examples">Examples</a></h2>
|
||||
|
||||
<h3 id="example-disabled"><a href="#example-disabled">Disabled</a></h3>
|
||||
|
||||
{% set code %}<label class="label gap-3">
|
||||
<input type="checkbox" class="input" disabled>
|
||||
Accept terms and conditions
|
||||
</label>{% endset %}
|
||||
{{ code_preview("checkbox-disabled", code) }}
|
||||
|
||||
<h3 id="example-with-text"><a href="#example-with-text">With text</a></h3>
|
||||
|
||||
{% set code %}<div class="flex items-start gap-3">
|
||||
<input type="checkbox" id="checkbox-with-text" class="input">
|
||||
<div class="grid gap-2">
|
||||
<label for="checkbox-with-text" class="label">Accept terms and conditions</label>
|
||||
<p class="text-muted-foreground text-sm">By clicking this checkbox, you agree to the terms and conditions.</p>
|
||||
</div>
|
||||
</div>{% endset %}
|
||||
{{ code_preview("checkbox-with-text", code) }}
|
||||
|
||||
<h3 id="example-form"><a href="#example-form">Form</a></h3>
|
||||
|
||||
{% set code %}<form class="form flex flex-row items-start gap-3 rounded-md border p-4 shadow-xs">
|
||||
<input type="checkbox" id="checkbox-form-1">
|
||||
<div class="flex flex-col gap-1">
|
||||
<label for="checkbox-form-1" class="leading-snug">Use different settings for my mobile devices</label>
|
||||
<p class="text-muted-foreground text-sm leading-snug">You can manage your mobile notifications in the mobile settings page.</p>
|
||||
</div>
|
||||
</form>{% endset %}
|
||||
{{ code_preview("input-form", code) }}
|
||||
|
||||
{% set code %}<form class="form flex flex-col gap-4">
|
||||
<header>
|
||||
<label for="demo-form-checkboxes" class="text-base leading-normal">Sidebar</label>
|
||||
<p class="text-muted-foreground text-sm">Select the items you want to display in the sidebar.</p>
|
||||
</header>
|
||||
<fieldset id="demo-form-checkboxes" class="flex flex-col gap-2">
|
||||
<label class="font-normal leading-tight">
|
||||
<input type="checkbox" name="demo-form-checkboxes" value="1" checked>
|
||||
Recents
|
||||
</label>
|
||||
<label class="font-normal leading-tight">
|
||||
<input type="checkbox" name="demo-form-checkboxes" value="2" checked>
|
||||
Home
|
||||
</label>
|
||||
<label class="font-normal leading-tight">
|
||||
<input type="checkbox" name="demo-form-checkboxes" value="3">
|
||||
Applications
|
||||
</label>
|
||||
<label class="font-normal leading-tight">
|
||||
<input type="checkbox" name="demo-form-checkboxes" value="4">
|
||||
Desktop
|
||||
</label>
|
||||
<label class="font-normal leading-tight">
|
||||
<input type="checkbox" name="demo-form-checkboxes" value="5">
|
||||
Download
|
||||
</label>
|
||||
<label class="font-normal leading-tight">
|
||||
<input type="checkbox" name="demo-form-checkboxes" value="6">
|
||||
Documents
|
||||
</label>
|
||||
</fieldset>
|
||||
</form>{% endset %}
|
||||
{{ code_preview("input-form", code) }}
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Dialog
|
||||
description: A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
|
||||
---
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% from "components/dialog.njk" import dialog %}
|
||||
{% set code %}{% set footer %}
|
||||
<button class="btn-outline" @click="open = false">Cancel</button>
|
||||
<button class="btn-primary" @click="open = false">Continue</button>
|
||||
{% endset %}
|
||||
{{ dialog(
|
||||
id="alert-dialog-demo",
|
||||
title="Are you absolutely sure?",
|
||||
description="This action cannot be undone. This will permanently delete your account and remove your data from our servers.",
|
||||
trigger="Open dialog",
|
||||
trigger_attrs={"class": "btn-outline"},
|
||||
footer=footer,
|
||||
close_button=false,
|
||||
close_on_overlay_click=false
|
||||
) }}{% endset %}
|
||||
{{ code_block("alert-dialog", code | prettyHtml) }}
|
||||
|
||||
<h2>Usage</h2>
|
||||
|
||||
<p>The Alert Dialog component uses the same syntax as the <a href="/components/dialog" class="font-medium underline underline-offset-4">Dialog</a> component with one difference in the JS.</p>
|
||||
@@ -0,0 +1,145 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Dropdown Menu
|
||||
description: Displays a menu to the user — such as a set of actions or functions — triggered by a button.
|
||||
---
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% from "components/dropdown-menu.njk" import dropdown_menu %}
|
||||
{% set code %}{% call dropdown_menu(
|
||||
id="dropdown-menu",
|
||||
trigger="Open Menu",
|
||||
trigger_attrs={"class": "btn-outline"},
|
||||
content_attrs={"class": "min-w-56"}
|
||||
) %}
|
||||
<div role="group" aria-labelledby="account-options">
|
||||
<span id="account-options" role="heading">Account Options</span>
|
||||
<button type="button" role="menuitem">
|
||||
Profile
|
||||
<span class="text-muted-foreground ml-auto text-xs tracking-widest">⇧⌘P</span>
|
||||
</button>
|
||||
<button type="button" role="menuitem">
|
||||
Billing
|
||||
<span class="text-muted-foreground ml-auto text-xs tracking-widest">⌘B</span>
|
||||
</button>
|
||||
<button type="button" role="menuitem">
|
||||
Settings
|
||||
<span class="text-muted-foreground ml-auto text-xs tracking-widest">⌘S</span>
|
||||
</button>
|
||||
<button type="button" role="menuitem">
|
||||
Keyboard shortcuts
|
||||
<span class="text-muted-foreground ml-auto text-xs tracking-widest">⌘K</span>
|
||||
</button>
|
||||
</div>
|
||||
<hr role="separator">
|
||||
<button type="button" role="menuitem">GitHub</button>
|
||||
<button type="button" role="menuitem">Support</button>
|
||||
<button type="button" role="menuitem" disabled>API</button>
|
||||
<hr role="separator">
|
||||
<button type="button" role="menuitem">
|
||||
Logout
|
||||
<span class="text-muted-foreground ml-auto text-xs tracking-widest">⇧⌘P</span>
|
||||
</button>{% endcall %}{% endset %}
|
||||
{{ code_block("dropdown-menu", code | prettyHtml) }}
|
||||
|
||||
|
||||
<h2 id="usage">Usage</h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>You can use one of the <code class="">btn</code> classes to style any element as a button:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<b>Variants</b>: <code>btn</code> or <code>btn-primary</code> for primary
|
||||
buttons, then <code>btn-secondary</code>, <code>btn-destructive</code>, <code>btn-outline</code>,
|
||||
<code>btn-ghost</code>, <code>btn-link</code>. You can also use <code>btn-icon</code> to
|
||||
style an icon as a button, along with all of its variants (e.g. <code>btn-icon-destructive</code>).
|
||||
</li>
|
||||
<li>
|
||||
<b>Sizes</b>: <code>btn-sm</code> for small and <code>btn-lg</code> for large.
|
||||
You can combine this with other attributes, for example <code>btn-lg-destructive</code>
|
||||
or <code>btn-icon-sm-secondary</code>.
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<h2>Examples</h2>
|
||||
|
||||
<h3>Primary</h3>
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% set code %}<button class="btn">Primary</button>{% endset %}
|
||||
{{ code_block("accordion", code | prettyHtml) }}
|
||||
|
||||
<h3>Secondary</h3>
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% set code %}<button class="btn-secondary">Button</button>{% endset %}
|
||||
{{ code_block("accordion", code | prettyHtml) }}
|
||||
|
||||
<h3>Destructive</h3>
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% set code %}<button class="btn-destructive">Destructive</button>{% endset %}
|
||||
{{ code_block("accordion", code | prettyHtml) }}
|
||||
|
||||
<h3>Outline</h3>
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% set code %}<button class="btn-outline">Outline</button>{% endset %}
|
||||
{{ code_block("accordion", code | prettyHtml) }}
|
||||
|
||||
<h3>Ghost</h3>
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% set code %}<button class="btn-ghost">Ghost</button>{% endset %}
|
||||
{{ code_block("accordion", code | prettyHtml) }}
|
||||
|
||||
<h3>Link</h3>
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% set code %}<button class="btn-link">Link</button>{% endset %}
|
||||
{{ code_block("accordion", code | prettyHtml) }}
|
||||
|
||||
<h3>Icon</h3>
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% set code %}<button class="btn-icon-outline">
|
||||
{% lucide "chevron-right" %}
|
||||
</button>{% endset %}
|
||||
{{ code_block("accordion", code | prettyHtml) }}
|
||||
|
||||
<h3>With Icon</h3>
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% set code %}<button class="btn">
|
||||
{% lucide "send" %}
|
||||
Send email
|
||||
</button>{% endset %}
|
||||
{{ code_block("accordion", code | prettyHtml) }}
|
||||
|
||||
<h3>Loading</h3>
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% set code %}<button class="btn" disabled>
|
||||
{% lucide "loader", { "class": "animate-spin" } %}
|
||||
Loading
|
||||
</button>{% endset %}
|
||||
{{ code_block("accordion", code) }}
|
||||
|
||||
<h3>Large</h3>
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% set code %}<button class="btn-lg">
|
||||
{% lucide "shopping-cart" %}
|
||||
Buy
|
||||
</button>{% endset %}
|
||||
{{ code_block("accordion", code) }}
|
||||
|
||||
<h3>Small</h3>
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% set code %}<button class="btn-icon-sm-destructive">
|
||||
{% lucide "trash" %}
|
||||
</button>{% endset %}
|
||||
{{ code_block("accordion", code) }}
|
||||
@@ -0,0 +1,92 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Input
|
||||
description: Displays a form input field or a component that looks like an input field.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
- label: Examples
|
||||
id: examples
|
||||
children:
|
||||
- label: Default
|
||||
id: example-default
|
||||
- label: Invalid
|
||||
id: example-invalid
|
||||
- label: Disabled
|
||||
id: example-disabled
|
||||
- label: With label
|
||||
id: example-with-label
|
||||
- label: With text
|
||||
id: example-with-text
|
||||
- label: With button
|
||||
id: example-with-button
|
||||
- label: Form
|
||||
id: example-form
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
{% set code %}<input class="input" type="email" placeholder="Email">{% endset %}
|
||||
{{ code_preview("input", code) }}
|
||||
|
||||
<h2 id="usage">Usage</h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>Simply add the <code>input</code> class to your <code><input></code> element or have a parent with the <code>form</code> class (<a href="/components/form">read more about form</a>). You can also set the <code>aria-invalid</code> attribute to <code>true</code> to make the input invalid.</p>
|
||||
</section>
|
||||
|
||||
{{ code_block(code) }}
|
||||
|
||||
<h2 id="examples"><a href="#examples">Examples</a></h2>
|
||||
|
||||
<h3 id="example-default"><a href="#example-default">Default</a></h3>
|
||||
|
||||
{{ code_preview("input-default", code) }}
|
||||
|
||||
<h3 id="example-invalid"><a href="#example-invalid">Invalid</a></h3>
|
||||
|
||||
{% set code %}<input class="input" type="email" placeholder="Email" aria-invalid="true">{% endset %}
|
||||
{{ code_preview("input-invalid", code) }}
|
||||
|
||||
<h3 id="example-disabled"><a href="#example-disabled">Disabled</a></h3>
|
||||
|
||||
{% set code %}<input class="input" type="email" placeholder="Email" disabled>{% endset %}
|
||||
{{ code_preview("input-disabled", code) }}
|
||||
|
||||
<h3 id="example-with-label"><a href="#example-with-label">With label</a></h3>
|
||||
|
||||
{% set code %}<div class="grid gap-3">
|
||||
<label for="input-with-label" class="label">Label</label>
|
||||
<input class="input" id="input-with-label" type="email" placeholder="Email">
|
||||
</div>{% endset %}
|
||||
{{ code_preview("input-with-label", code) }}
|
||||
|
||||
<h3 id="example-with-text"><a href="#example-with-text">With text</a></h3>
|
||||
|
||||
{% set code %}<div class="grid gap-3">
|
||||
<label for="input-with-text" class="label">Label</label>
|
||||
<input class="input" id="input-with-text" type="email" placeholder="Email">
|
||||
<p class="text-muted-foreground text-sm">Fill in your email address.</p>
|
||||
</div>{% endset %}
|
||||
{{ code_preview("input-with-text", code) }}
|
||||
|
||||
<h3 id="example-with-button"><a href="#example-with-button">With button</a></h3>
|
||||
|
||||
{% set code %}<div class="flex items-center space-x-2">
|
||||
<input class="input" type="email" placeholder="Email">
|
||||
<button type="submit" class="btn">Submit</button>
|
||||
</div>{% endset %}
|
||||
{{ code_preview("textarea-form", code) }}
|
||||
|
||||
<h3 id="example-form"><a href="#example-form">Form</a></h3>
|
||||
|
||||
{% set code %}<form class="form space-y-6 w-full">
|
||||
<div class="grid gap-3">
|
||||
<label for="input-form" class="label">Username</label>
|
||||
<input class="input" id="input-form" type="text" placeholder="hunvreus">
|
||||
<p class="text-muted-foreground text-sm">This is your public display name.</p>
|
||||
</div>
|
||||
<button type="submit" class="btn">Submit</button>
|
||||
</form>{% endset %}
|
||||
{{ code_preview("input-form", code, "w-full max-w-sm") }}
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Label
|
||||
description: Renders an accessible label associated with controls.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
{% set code %}<label class="label gap-3">
|
||||
<input type="checkbox" class="input">
|
||||
Accept terms and conditions
|
||||
</label>{% endset %}
|
||||
{{ code_preview("label", code) }}
|
||||
|
||||
<h2 id="usage">Usage</h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>Simply add the <code>label</code> class to your <code><label></code> element or have a parent with the <code>form</code> class (<a href="/components/form">read more about form</a>). Labels will be styled accordingly if a peer or child element is disabled.</p>
|
||||
</section>
|
||||
|
||||
{% set code %}<label class="label" for="email">Your email address</label>{% endset %}
|
||||
{{ code_block(code) }}
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Pagination
|
||||
description: Pagination with page navigation, next and previous links.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
<div class="alert mb-6">
|
||||
{% lucide "circle-alert" %}
|
||||
<h2>There is no dedicated pagination component in Basecoat.</h2>
|
||||
</div>
|
||||
|
||||
{% set code %}<nav role="navigation" aria-label="pagination" class="mx-auto flex w-full justify-center">
|
||||
<ul class="flex flex-row items-center gap-1">
|
||||
<li>
|
||||
<a href="#" class="btn-ghost">{% lucide "chevron-left" %} Previous</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="btn-icon-ghost">1</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="btn-icon-outline">2</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="btn-icon-ghost">3</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="size-9 flex items-center justify-center">{% lucide "ellipsis", { "class": "size-4 shrink-0" } %}</div>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="btn-ghost">Next {% lucide "chevron-right" %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>{% endset %}
|
||||
{{ code_preview("pagination", code, "max-w-md") }}
|
||||
|
||||
<h2 id="usage"><a href="#usage">Usage</a></h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>A pagination is fairly simple to implement with Tailwind using the Basecoat button classes:</p>
|
||||
</section>
|
||||
|
||||
{{ code_block(code) }}
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Popover
|
||||
description: Displays rich content in a portal, triggered by a button.
|
||||
---
|
||||
|
||||
<div class="alert mb-6">
|
||||
{% lucide "info" %}
|
||||
<h2>There is no dedicated avatar component in Basecoat.</h2>
|
||||
<section>
|
||||
<p>Simply use regular Tailwind classes. <a href="/kitchen-sink#avatar" class="underline hover:text-foreground transition-all">You can find more examples of avatars in the kitchen sink.</a></p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% set code %}<img class="size-8 shrink-0 object-cover rounded-full" alt="@hunvreus" src="https://github.com/hunvreus.png">{% endset %}
|
||||
{{ code_block("accordion", code, "max-w-md") }}
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Radio Group
|
||||
description: A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
- label: Examples
|
||||
id: examples
|
||||
children:
|
||||
- label: Form
|
||||
id: example-form
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
{% set code %}<fieldset class="grid gap-3">
|
||||
<label class="label"><input type="radio" name="radio-group" value="default" class="input">Default</label>
|
||||
<label class="label"><input type="radio" name="radio-group" value="comfortable" class="input" checked>Comfortable</label>
|
||||
<label class="label"><input type="radio" name="radio-group" value="compact" class="input">Compact</label>
|
||||
</fieldset>{% endset %}
|
||||
{{ code_preview("radio-group", code) }}
|
||||
|
||||
<h2 id="usage">Usage</h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>Simply add the <code>input</code> class to your <code><input type="radio"></code> elements or have a parent with the <code>form</code> class (<a href="/components/form">read more about form</a>). You can also set the <code>aria-invalid</code> attribute to <code>true</code> to make the input invalid.</p>
|
||||
</section>
|
||||
|
||||
{{ code_block(code) }}
|
||||
|
||||
<h2 id="examples"><a href="#examples">Examples</a></h2>
|
||||
|
||||
<h3 id="example-form"><a href="#example-form">Form</a></h3>
|
||||
|
||||
{% set code %}<form class="form space-y-6 w-full">
|
||||
<div class="flex flex-col gap-3">
|
||||
<label for="demo-form-radio">Notify me about...</label>
|
||||
<fieldset id="demo-form-radio" class="grid gap-3">
|
||||
<label class="font-normal"><input type="radio" name="demo-form-radio" value="1">All new messages</label>
|
||||
<label class="font-normal"><input type="radio" name="demo-form-radio" value="2">Direct messages and mentions</label>
|
||||
<label class="font-normal"><input type="radio" name="demo-form-radio" value="3" >Nothing</label>
|
||||
</fieldset>
|
||||
</div>
|
||||
<button type="submit" class="btn">Submit</button>
|
||||
</form>{% endset %}
|
||||
{{ code_preview("radio-group-form", code, "w-full max-w-sm") }}
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Select
|
||||
description: isplays a list of options for the user to pick from—triggered by a button.
|
||||
---
|
||||
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
{% set code %}<button class="btn-outline" hx-trigger="click" hx-get="/fragments/toast/success" hx-target="#toast-htmx">
|
||||
Success
|
||||
</button>
|
||||
<div id="toast-htmx"></div>{% endset %}
|
||||
{{ code_block("accordion", code, "max-w-md") }}
|
||||
|
||||
<h2>Usage</h2>
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Slider
|
||||
description: An input where the user selects a value from within a given range.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
{% set code %}<input
|
||||
type="range"
|
||||
class="input w-full"
|
||||
min="0"
|
||||
max="100"
|
||||
value="50"
|
||||
x-data="{
|
||||
updatePercent(el) {
|
||||
const min = parseFloat(el.min || 0);
|
||||
const max = parseFloat(el.max || 100);
|
||||
const value = parseFloat(el.value);
|
||||
const percent = (max === min) ? 0 : ((value - min) / (max - min)) * 100;
|
||||
el.style.setProperty('--slider-value', `${percent}%`);
|
||||
}
|
||||
}"
|
||||
x-init="updatePercent($el)"
|
||||
@input="updatePercent($el)"
|
||||
>{% endset %}
|
||||
{{ code_preview("slider", code, "w-full max-w-sm") }}
|
||||
|
||||
<h2 id="usage"><a href="#usage">Usage</a></h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>You can style an <code><input type="range"></code> element by either adding the <code>input</code> class or having a parent with the <code>form</code> class (<a href="/components/form">read more about form</a>). However, the range input also requries some Javacript code to be able to paint the left side of the slider.</p>
|
||||
</section>
|
||||
|
||||
{{ code_block(code) }}
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Switch
|
||||
description: A control that allows the user to toggle between checked and not checked.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
- label: Examples
|
||||
id: examples
|
||||
children:
|
||||
- label: Form
|
||||
id: example-form
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
{% set code %}<label class="label">
|
||||
<input type="checkbox" name="switch" role="switch" class="input">
|
||||
Airplane Mode
|
||||
</label>{% endset %}
|
||||
{{ code_preview("switch", code) }}
|
||||
|
||||
<h2 id="usage"><a href="#usage">Usage</a></h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>You can style a <code><input type="checkbox"></code> element as a switch by adding a <code>role="switch"</code> attribute, and adding the <code>input</code> class or having a parent with the <code>form</code> class (<a href="/components/form">read more about form</a>).</p>
|
||||
</section>
|
||||
|
||||
{% set code %}<input type="checkbox" role="switch" class="input">{% endset %}
|
||||
{{ code_block(code) }}
|
||||
|
||||
<h2 id="examples"><a href="#examples">Examples</a></h2>
|
||||
|
||||
<h3 id="example-form"><a href="#example-form">Form</a></h3>
|
||||
|
||||
{% set code %}<form class="form grid gap-4">
|
||||
<h3 class="text-lg font-medium">Email Notifications</h3>
|
||||
<div class="gap-2 flex flex-row items-start justify-between rounded-lg border p-4 shadow-xs">
|
||||
<div class="flex flex-col gap-0.5">
|
||||
<label for="demo-form-switch" class="leading-normal">Marketing emails</label>
|
||||
<p class="text-muted-foreground text-sm">Receive emails about new products, features, and more.</p>
|
||||
</div>
|
||||
<input type="checkbox" id="demo-form-switch" role="switch">
|
||||
</div>
|
||||
<div class="gap-2 flex flex-row items-start justify-between rounded-lg border p-4 shadow-xs">
|
||||
<div class="flex flex-col gap-0.5 opacity-60">
|
||||
<label for="demo-form-switch-disabled" class="leading-normal">Marketing emails</label>
|
||||
<p class="text-muted-foreground text-sm">Receive emails about new products, features, and more.</p>
|
||||
</div>
|
||||
<input type="checkbox" id="demo-form-switch-disabled" role="switch" disabled>
|
||||
</div>
|
||||
</form>{% endset %}
|
||||
{{ code_preview("switch-form", code, "w-full") }}
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Table
|
||||
description: A responsive table component.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
{% set code %}<table class="table">
|
||||
<caption>A list of your recent invoices.</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Invoice</th>
|
||||
<th>Status</th>
|
||||
<th>Method</th>
|
||||
<th>Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="font-medium">INV001</td>
|
||||
<td>Paid</td>
|
||||
<td>Credit Card</td>
|
||||
<td class="text-right">$250.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">INV002</td>
|
||||
<td>Pending</td>
|
||||
<td>PayPal</td>
|
||||
<td class="text-right">$150.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">INV003</td>
|
||||
<td>Unpaid</td>
|
||||
<td>Bank Transfer</td>
|
||||
<td class="text-right">$350.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">INV004</td>
|
||||
<td>Paid</td>
|
||||
<td>Paypal</td>
|
||||
<td class="text-right">$450.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">INV005</td>
|
||||
<td>Paid</td>
|
||||
<td>Credit Card</td>
|
||||
<td class="text-right">$550.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">INV006</td>
|
||||
<td>Pending</td>
|
||||
<td>Bank Transfer</td>
|
||||
<td class="text-right">$200.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-medium">INV007</td>
|
||||
<td>Unpaid</td>
|
||||
<td>Credit Card</td>
|
||||
<td class="text-right">$300.00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="3">Total</td>
|
||||
<td class="text-right">$2,500.00</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>{% endset %}
|
||||
{{ code_preview("table", code, "w-full") }}
|
||||
|
||||
<h2 id="usage"><a href="#usage">Usage</a></h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>Simply add the <code>table</code> class to your table element.</p>
|
||||
</section>
|
||||
|
||||
{% set code %}<table class="table">
|
||||
<!-- Content of your table -->
|
||||
</table>{% endset %}
|
||||
{{ code_block(code) }}
|
||||
@@ -0,0 +1,92 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Teaxtarea
|
||||
description: Displays a form textarea or a component that looks like a textarea.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
- label: Examples
|
||||
id: examples
|
||||
children:
|
||||
- label: Default
|
||||
id: example-default
|
||||
- label: Invalid
|
||||
id: example-invalid
|
||||
- label: Disabled
|
||||
id: example-disabled
|
||||
- label: With label
|
||||
id: example-with-label
|
||||
- label: With text
|
||||
id: example-with-text
|
||||
- label: With button
|
||||
id: example-with-button
|
||||
- label: Form
|
||||
id: example-form
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
{% set code %}<textarea class="textarea" placeholder="Type your message here"></textarea>{% endset %}
|
||||
{{ code_preview("button", code, "w-full") }}
|
||||
|
||||
<h2 id="usage">Usage</h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>Simply add the <code>textarea</code> class to your <code><textarea></code> element or have a parent with the <code>form</code> class (<a href="/components/form">read more about form</a>). You can also set the <code>aria-invalid</code> attribute to <code>true</code> to make the textarea invalid.</p>
|
||||
</section>
|
||||
|
||||
{{ code_block(code) }}
|
||||
|
||||
<h2 id="examples"><a href="#examples">Examples</a></h2>
|
||||
|
||||
<h3 id="example-default"><a href="#example-default">Default</a></h3>
|
||||
|
||||
{{ code_preview("textarea-default", code, "w-full") }}
|
||||
|
||||
<h3 id="example-invalid"><a href="#example-invalid">Invalid</a></h3>
|
||||
|
||||
{% set code %}<textarea class="textarea" placeholder="Type your message here" aria-invalid="true"></textarea>{% endset %}
|
||||
{{ code_preview("textarea-invalid", code, "w-full") }}
|
||||
|
||||
<h3 id="example-disabled"><a href="#example-disabled">Disabled</a></h3>
|
||||
|
||||
{% set code %}<textarea class="textarea" placeholder="Type your message here" disabled></textarea>{% endset %}
|
||||
{{ code_preview("textarea-disabled", code, "w-full") }}
|
||||
|
||||
<h3 id="example-with-label"><a href="#example-with-label">With label</a></h3>
|
||||
|
||||
{% set code %}<div class="grid gap-3">
|
||||
<label for="textarea-with-label" class="label">Label</label>
|
||||
<textarea id="textarea-with-label" class="textarea" placeholder="Type your message here"></textarea>
|
||||
</div>{% endset %}
|
||||
{{ code_preview("textarea-with-label", code, "w-full") }}
|
||||
|
||||
<h3 id="example-with-text"><a href="#example-with-text">With text</a></h3>
|
||||
|
||||
{% set code %}<div class="grid gap-3">
|
||||
<label for="textarea-with-label" class="label">Label</label>
|
||||
<textarea id="textarea-with-label" class="textarea" placeholder="Type your message here"></textarea>
|
||||
<p class="text-muted-foreground text-sm">Type your message and press enter to send.</p>
|
||||
</div>{% endset %}
|
||||
{{ code_preview("textarea-with-text", code, "w-full") }}
|
||||
|
||||
<h3 id="example-with-button"><a href="#example-with-button">With button</a></h3>
|
||||
|
||||
{% set code %}<div class="grid gap-3">
|
||||
<textarea id="textarea-with-label" class="textarea" placeholder="Type your message here"></textarea>
|
||||
<button type="submit" class="btn">Submit</button>
|
||||
</div>{% endset %}
|
||||
{{ code_preview("textarea-form", code, "w-full") }}
|
||||
|
||||
<h3 id="example-form"><a href="#example-form">Form</a></h3>
|
||||
|
||||
{% set code %}<form class="form space-y-6">
|
||||
<div class="grid gap-3">
|
||||
<label for="textarea-form" class="label">Bio</label>
|
||||
<textarea id="textarea-form" placeholder="Tell us a bit about yourself"></textarea>
|
||||
<p class="text-muted-foreground text-sm">You can @mention other users and organizations.</p>
|
||||
</div>
|
||||
<button type="submit" class="btn">Submit</button>
|
||||
</form>{% endset %}
|
||||
{{ code_preview("textarea-form", code, "w-full max-w-sm") }}
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Toast
|
||||
description: A succinct message that is displayed temporarily.
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% set code %}<button class="btn-outline" hx-trigger="click" hx-get="/fragments/toast/success" hx-target="#toast-htmx">
|
||||
Success
|
||||
</button>
|
||||
<div id="toast-htmx"></div>{% endset %}
|
||||
{{ code_preview("accordion", code, "max-w-md") }}
|
||||
|
||||
<h2>Usage</h2>
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
layout: layouts/component.njk
|
||||
title: Tooltip
|
||||
description: A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.
|
||||
toc:
|
||||
- label: Usage
|
||||
id: usage
|
||||
- label: Examples
|
||||
id: examples
|
||||
children:
|
||||
- label: Default
|
||||
id: example-default
|
||||
- label: Right
|
||||
id: example-right
|
||||
- label: Bottom + Start
|
||||
id: example-bottom-start
|
||||
---
|
||||
|
||||
{% from "macros/code_preview.njk" import code_preview %}
|
||||
{% from "macros/code_block.njk" import code_block %}
|
||||
|
||||
{% set code %}<button class="btn-outline" data-tooltip="Add to library">Hover</button>{% endset %}
|
||||
{{ code_preview("button", code) }}
|
||||
|
||||
<h2 id="usage">Usage</h2>
|
||||
|
||||
<section class="prose my-6">
|
||||
<p>On any element, set the value of the <code>data-tooltip</code> attribute to the text you want to display in the tooltip. Additionally, you can set:</p>
|
||||
<ul>
|
||||
<li><code>data-side</code> attribute to <code>top</code>, <code>bottom</code>, <code>left</code>, or <code>right</code> to change the side of the tooltip.</li>
|
||||
<li><code>data-align</code> attribute to <code>start</code>, <code>center</code>, or <code>end</code> to change the alignment of the tooltip.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{% set code %}<button class="btn-outline" data-tooltip="Tooltip text" data-side="bottom" data-align="center">Bottom left</button>{% endset %}
|
||||
{{ code_block(code) }}
|
||||
|
||||
<h2 id="examples"><a href="#examples">Examples</a></h2>
|
||||
|
||||
<h3 id="example-default"><a href="#example-default">Default</a></h3>
|
||||
|
||||
{% set code %}<button class="btn-outline" data-tooltip="Default tooltip">Default</button>{% endset %}
|
||||
{{ code_preview("button", code) }}
|
||||
|
||||
<h3 id="example-right"><a href="#example-right">Right</a></h3>
|
||||
|
||||
{% set code %}<button class="btn-outline" data-tooltip="Right side tooltip" data-side="right">Right</button>{% endset %}
|
||||
{{ code_preview("button", code) }}
|
||||
|
||||
<h3 id="example-bottom-start"><a href="#example-bottom-start">Bottom + Start</a></h3>
|
||||
|
||||
{% set code %}<button class="btn-outline" data-tooltip="Bottom side and start aligned tooltip" data-side="bottom" data-align="start">Bottom + Start</button>{% endset %}
|
||||
{{ code_preview("button", code) }}
|
||||
Reference in New Issue
Block a user