mirror of
https://github.com/hunvreus/basecoat.git
synced 2026-11-14 14:08:18 +00:00
179 lines
6.7 KiB
Plaintext
179 lines
6.7 KiB
Plaintext
---
|
|
layout: layouts/component.njk
|
|
title: Combobox
|
|
description: Autocomplete input and command palette with a list of suggestions.
|
|
toc:
|
|
- label: Usage
|
|
id: usage
|
|
children:
|
|
- label: HTML + Javascript
|
|
id: usage-default
|
|
- label: Jinja or Nunjucks
|
|
id: usage-jinja
|
|
- label: Examples
|
|
id: examples
|
|
children:
|
|
- label: Scrollable
|
|
id: example-scrollable
|
|
- label: Top side
|
|
id: example-top
|
|
---
|
|
|
|
{% from "macros/code_preview.njk" import code_preview %}
|
|
{% from "macros/code_block.njk" import code_block %}
|
|
{% from "components/select.njk" import select %}
|
|
|
|
{% set options_frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"] %}
|
|
{% set code_html %}
|
|
{% call select(
|
|
trigger_attrs={"class": "w-[200px]"},
|
|
listbox_attrs={"data-empty": "No framework found."},
|
|
is_combobox=true,
|
|
search_placeholder="Search framework...",
|
|
register_on=["alpine:init", "htmx:afterSwap"]
|
|
) %}
|
|
{% for framework in options_frameworks %}
|
|
<div role="option" data-value="{{ framework }}">{{ framework }}</div>
|
|
{% endfor %}
|
|
{% endcall %}
|
|
{% endset %}
|
|
|
|
{% set code_script %}
|
|
{% include "components/select-script.njk" %}
|
|
{% endset %}
|
|
|
|
{{ code_preview("combobox", 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>
|
|
<section>
|
|
<p>You will need to include the Javascript (Alpine.js) code provided below before the HTML code for this component. As with all interactive components, you will need to add some Alpine.js properties to 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>
|
|
|
|
<section class="prose my-6">
|
|
<p>Combobox uses the same Alpine.js code and markup as the <a href="/components/select">Select</a> component, the only difference being the search box at the top of the listbox.</p>
|
|
<p>You can set up a few additional options on the <code><div data-popover></code> element:</p>
|
|
<ul>
|
|
<li><code>data-side</code> can be set to <code>top</code>, <code>bottom</code>, <code>left</code>, or <code>right</code> to change the side of the popover.</li>
|
|
<li><code>data-align</code> can be set to <code>start</code>, <code>center</code>, or <code>end</code> to change the alignment of the popover.</li>
|
|
<li><code>data-empty</code> to set up the message when the search is empty.</li>
|
|
</ul>
|
|
</section>
|
|
|
|
{% from "components/tabs.njk" import tabs %}
|
|
{% set tabsets = [
|
|
{ tab: "HTML", panel: code_block(code_html | prettyHtml) },
|
|
{ tab: "Javascipt (Alpine.js)", panel: code_block(code_script | prettyHtml) }
|
|
] %}
|
|
{{ tabs(id="combobox", tabsets=tabsets) }}
|
|
|
|
<h3 id="usage-jinja"><a href="#usage-jinja">Jinja or Nunjucks</a></h3>
|
|
|
|
<section class="prose my-6">
|
|
<p class="my-6 prose">If you use Jinja (or Nunjucks), you can use the <code>select()</code> macro directly, making sure to set <code>is_combobox</code> to <code>True</code> (or <code>true</code> for Nunjucks). <a href="/installation#jinja-and-nunjucks">Read more about using Basecoat with Jinja and Nunjucks</a>.</p>
|
|
</section>
|
|
|
|
{% set raw_code %}{% raw %}{% call select(
|
|
listbox_attrs={"data-empty": "No framework found."},
|
|
is_combobox=true
|
|
) %}
|
|
<div role="option" data-value="nextjs">Next.js</div>
|
|
<div role="option" data-value="sveltekit">SvelteKit</div>
|
|
<div role="option" data-value="nuxtjs">Nuxt.js</div>
|
|
<div role="option" data-value="remix">Remix</div>
|
|
<div role="option" data-value="astro">Astro</div>
|
|
{% endcall %}{% endraw %}{% endset %}
|
|
{{ code_block(raw_code, "jinja") }}
|
|
|
|
<h2 id="examples"><a href="#examples">Examples</a></h2>
|
|
|
|
<h3 id="example-scrollable"><a href="#example-scrollable">Scrollable</a></h3>
|
|
|
|
{% set options_timezones = [
|
|
{
|
|
label: "Americas",
|
|
timezones: [
|
|
{ value: "America/New_York", label: "(GMT-5) New York" },
|
|
{ value: "America/Los_Angeles", label: "(GMT-8) Los Angeles" },
|
|
{ value: "America/Chicago", label: "(GMT-6) Chicago" },
|
|
{ value: "America/Toronto", label: "(GMT-5) Toronto" },
|
|
{ value: "America/Vancouver", label: "(GMT-8) Vancouver" },
|
|
{ value: "America/Sao_Paulo", label: "(GMT-3) São Paulo" }
|
|
]
|
|
},
|
|
{
|
|
label: "Europe",
|
|
timezones: [
|
|
{ value: "Europe/London", label: "(GMT+0) London" },
|
|
{ value: "Europe/Paris", label: "(GMT+1) Paris" },
|
|
{ value: "Europe/Berlin", label: "(GMT+1) Berlin" },
|
|
{ value: "Europe/Rome", label: "(GMT+1) Rome" },
|
|
{ value: "Europe/Madrid", label: "(GMT+1) Madrid" },
|
|
{ value: "Europe/Amsterdam", label: "(GMT+1) Amsterdam" }
|
|
]
|
|
},
|
|
{
|
|
label: "Asia/Pacific",
|
|
timezones: [
|
|
{ value: "Asia/Tokyo", label: "(GMT+9) Tokyo" },
|
|
{ value: "Asia/Shanghai", label: "(GMT+8) Shanghai" },
|
|
{ value: "Asia/Singapore", label: "(GMT+8) Singapore" },
|
|
{ value: "Asia/Dubai", label: "(GMT+4) Dubai" },
|
|
{ value: "Australia/Sydney", label: "(GMT+11) Sydney" },
|
|
{ value: "Asia/Seoul", label: "(GMT+9) Seoul" }
|
|
]
|
|
}
|
|
] %}
|
|
{% set code %}
|
|
{% call select(
|
|
trigger_attrs={"class": "w-[200px]"},
|
|
content_attrs={"class": "w-72"},
|
|
listbox_attrs={"data-empty": "No timezone found."},
|
|
is_combobox=true,
|
|
search_placeholder="Search timezone...",
|
|
register_on=["alpine:init", "htmx:afterSwap"]
|
|
) %}
|
|
<div class="max-h-64 overflow-y-auto scrollbar">
|
|
{% for group in options_timezones %}
|
|
<div role="group" aria-labelledby="demo-combobox-timezones-group-{{ loop.index0 }}">
|
|
<span id="demo-combobox-timezones-group-{{ loop.index0 }}" role="heading">{{ group.label }}</span>
|
|
{% for timezone in group.timezones %}
|
|
<div role="option" data-value="{{ timezone.value}}">
|
|
{{ timezone.label }}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
<hr role="separator">
|
|
<div role="option">
|
|
{% lucide "circle-plus" %}
|
|
Create timezone
|
|
</div>
|
|
{% endcall %}
|
|
{% endset %}
|
|
{{ code_preview("combobox-with-groups", code | prettyHtml) }}
|
|
|
|
<h3 id="example-top"><a href="#example-top">Top side</a></h3>
|
|
|
|
{% set options_frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"] %}
|
|
{% set code %}
|
|
{% call select(
|
|
trigger_attrs={"class": "w-[200px]"},
|
|
listbox_attrs={"data-empty": "No framework found."},
|
|
is_combobox=true,
|
|
search_placeholder="Search framework...",
|
|
register_on=["alpine:init", "htmx:afterSwap"],
|
|
content_attrs={"data-side": "top"}
|
|
) %}
|
|
{% for framework in options_frameworks %}
|
|
<div role="option" data-value="{{ framework }}">{{ framework }}</div>
|
|
{% endfor %}
|
|
{% endcall %}{% endset %}
|
|
{{ code_preview("combobox", code | prettyHtml) }} |