diff --git a/dist/basecoat.css b/dist/basecoat.css index 77707a1..7873117 100644 --- a/dist/basecoat.css +++ b/dist/basecoat.css @@ -27,7 +27,6 @@ --color-black: #000; --color-white: #fff; --spacing: 0.25rem; - --breakpoint-sm: 40rem; --breakpoint-md: 48rem; --breakpoint-lg: 64rem; --container-xs: 20rem; @@ -465,6 +464,9 @@ .w-6 { width: calc(var(--spacing) * 6); } + .w-48 { + width: calc(var(--spacing) * 48); + } .w-72 { width: calc(var(--spacing) * 72); } @@ -480,6 +482,9 @@ .w-\[180px\] { width: 180px; } + .w-\[200px\] { + width: 200px; + } .w-\[var\(--sidebar-width\)\] { width: var(--sidebar-width); } @@ -2827,12 +2832,6 @@ border-bottom-style: var(--tw-border-style); border-bottom-width: 1px; padding-inline: calc(var(--spacing) * 3); - svg { - width: calc(var(--spacing) * 4); - height: calc(var(--spacing) * 4); - flex-shrink: 0; - opacity: 50%; - } input[role='combobox'] { display: flex; height: calc(var(--spacing) * 10); diff --git a/dist/basecoat.tailwind.css b/dist/basecoat.tailwind.css index 3d182a2..369c30a 100644 --- a/dist/basecoat.tailwind.css +++ b/dist/basecoat.tailwind.css @@ -652,19 +652,15 @@ [role='separator'] { @apply border-border -mx-1 my-1; } + /* Combobox */ > header { @apply flex h-9 items-center gap-2 border-b px-3 -mx-1 -mt-1 mb-1; - svg { - @apply size-4 shrink-0 opacity-50; - } input[role='combobox'] { @apply placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50; } } - - /* Combobox */ [role='listbox']:not(:has([data-value]:not([aria-hidden='true'])))::before { @apply flex items-center justify-center p-6 text-sm truncate; } diff --git a/docs/_includes/partials/kitchen-sink/combobox.njk b/docs/_includes/partials/kitchen-sink/combobox.njk index cb56a53..f1a04b5 100644 --- a/docs/_includes/partials/kitchen-sink/combobox.njk +++ b/docs/_includes/partials/kitchen-sink/combobox.njk @@ -5,63 +5,76 @@

Combobox

- {% 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" } - ] - } - ] %} - {% call select( - content_attrs={"class": "w-72"}, - listbox_attrs={"data-empty": "No timezone found."}, - is_combobox=true - ) %} -
- {% for group in options_timezones %} -
- {{ group.label }} - {% for timezone in group.timezones %} -
- {{ timezone.label }} -
- {% endfor %} -
+
+ {% set options_frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"] %} + {% call select( + content_attrs={"class": "w-48"}, + listbox_attrs={"data-empty": "No framework found."}, + is_combobox=true + ) %} + {% for framework in options_frameworks %} +
{{ framework }}
{% endfor %} -
-
-
- {% lucide "circle-plus" %} - Create timezone -
- {% endcall %} + {% endcall %} + + {% 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" } + ] + } + ] %} + {% call select( + content_attrs={"class": "w-72"}, + listbox_attrs={"data-empty": "No timezone found."}, + is_combobox=true + ) %} +
+ {% for group in options_timezones %} +
+ {{ group.label }} + {% for timezone in group.timezones %} +
+ {{ timezone.label }} +
+ {% endfor %} +
+ {% endfor %} +
+
+
+ {% lucide "circle-plus" %} + Create timezone +
+ {% endcall %} +
\ No newline at end of file diff --git a/docs/components/accordion.njk b/docs/components/accordion.njk index 33c7327..4092dd4 100644 --- a/docs/components/accordion.njk +++ b/docs/components/accordion.njk @@ -7,12 +7,14 @@ toc: id: usage --- +{% from "macros/code_preview.njk" import code_preview %} +{% from "macros/code_block.njk" import code_block %} +
{% lucide "circle-alert" %}

There is no dedicated accordion component in Basecoat.

-{% from "macros/code_preview.njk" import code_preview %} {% set code %}
Usage
-

Basecoat animates <details> elements by default. The example above shows how to use Alpine.js, Tailwind and <details> elements to implement a simple accordion.

-
\ No newline at end of file +

Basecoat animates <details> elements by default. Using Alpine.js to handle the open/close state and Tailwind to style the the <details> elements, you can get an accordion component:

+
+ +{{ code_block(code) }} \ No newline at end of file diff --git a/docs/components/alert-dialog.njk b/docs/components/alert-dialog.njk index d87809f..88afc5d 100644 --- a/docs/components/alert-dialog.njk +++ b/docs/components/alert-dialog.njk @@ -50,7 +50,7 @@ toc:

Jinja or Nunjucks

-

If you use Jinja (or Nunjucks), you can use the Dialog macro directly, making sure to set close_on_overlay_click to False (or false for Nunjucks).

+

If you use Jinja (or Nunjucks), you can use the dialog() macro directly, making sure to set close_on_overlay_click to False (or false for Nunjucks).

+ +{{ code_block(code | prettyHtml) }} \ No newline at end of file diff --git a/docs/components/combobox.njk b/docs/components/combobox.njk new file mode 100644 index 0000000..bfd7c19 --- /dev/null +++ b/docs/components/combobox.njk @@ -0,0 +1,138 @@ +--- +layout: layouts/component.njk +title: Combobox +description: Autocomplete input and command palette with a list of suggestions. +toc: + - label: Usage + id: usage + children: + - label: Default + id: usage-default + - label: Jinja or Nunjucks + id: usage-jinja + - label: Examples + id: examples + children: + - label: With groups + id: example-with-groups +--- + +{% 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 %} +{% call select( + trigger_attrs={"class": "w-[200px]"}, + listbox_attrs={"data-empty": "No framework found."}, + is_combobox=true +) %} + {% for framework in options_frameworks %} +
{{ framework }}
+ {% endfor %} +{% endcall %}{% endset %} +{{ code_preview("combobox", code | prettyHtml) }} + +

Usage

+ +

Default

+ +
+

The Combobox component uses the same Alpine.js code as the Select component, and almost identical markup, the only difference being the search box.

+
+ +{{ code_block(code | prettyHtml) }} + +

Jinja or Nunjucks

+ +
+

If you use Jinja (or Nunjucks), you can use the select() macro directly, making sure to set is_combobox to True (or true for Nunjucks).

+ +
+ +{% set raw_code %}{% raw %}{% call select( + listbox_attrs={"data-empty": "No framework found."}, + is_combobox=true +) %} +
Next.js
+
SvelteKit
+
Nuxt.js
+
Remix
+
Astro
+{% endcall %}{% endraw %}{% endset %} +{{ code_block(raw_code, "jinja") }} + +

Examples

+ +

With groups

+ +{% 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 +) %} +
+ {% for group in options_timezones %} +
+ {{ group.label }} + {% for timezone in group.timezones %} +
+ {{ timezone.label }} +
+ {% endfor %} +
+ {% endfor %} +
+
+
+ {% lucide "circle-plus" %} + Create timezone +
+{% endcall %} +{% endset %} +{{ code_preview("combobox-with-groups", code | prettyHtml) }} diff --git a/docs/components/popover.njk b/docs/components/popover.njk index 038d0f6..0cdfd66 100644 --- a/docs/components/popover.njk +++ b/docs/components/popover.njk @@ -2,16 +2,108 @@ layout: layouts/component.njk title: Popover description: Displays rich content in a portal, triggered by a button. +toc: + - label: Usage + id: usage + children: + - label: Default + id: usage-default + - label: Jinja or Nunjucks + id: usage-jinja --- -
- {% lucide "info" %} -

There is no dedicated avatar component in Basecoat.

-
-

Simply use regular Tailwind classes. You can find more examples of avatars in the kitchen sink.

-
-
- +{% from "macros/code_preview.njk" import code_preview %} {% from "macros/code_block.njk" import code_block %} -{% set code %}@hunvreus{% endset %} -{{ code_block("accordion", code, "max-w-md") }} \ No newline at end of file +{% from "components/popover.njk" import popover %} + +{% set code %} +{% call popover( + id="demo-popover", + trigger="Open popover", + trigger_attrs={"class": "btn-outline"}, + content_attrs={"class": "w-80 p-4"} +) %} +
+
+

Dimensions

+

Set the dimensions for the layer.

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+{% endcall %} +{% endset %} +{{ code_preview("popover", code | prettyHtml ) }} + +

Usage

+ +

Default

+ +
+

If you need to do more than what <select> allows (e.g. HTML options), you can use the code below which uses the Popover component. Make sure to include the hidden input with the name you want to use for that field.

+
+ +{{ code_block(code | prettyHtml) }} + +

Jinja or Nunjucks

+ +
+

If you use Jinja (or Nunjucks), you can use the popover() macro directly.

+ +
+ +{% set raw_code %}{% raw %}{% call popover( + id="demo-popover", + trigger="Open popover", + trigger_attrs={"class": "btn-outline"}, + content_attrs={"class": "w-80 p-4"} +) %} +
+
+

Dimensions

+

Set the dimensions for the layer.

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+{% endcall %}{% endraw %}{% endset %} +{{ code_block(raw_code, "jinja") }} \ No newline at end of file diff --git a/docs/components/select.njk b/docs/components/select.njk index cc5118e..67801f9 100644 --- a/docs/components/select.njk +++ b/docs/components/select.njk @@ -1,14 +1,141 @@ --- layout: layouts/component.njk title: Select -description: isplays a list of options for the user to pick from—triggered by a button. +description: Displays a list of options for the user to pick from—triggered by a button. +toc: + - label: Usage + id: usage + children: + - label: Default + id: usage-default + - label: Jinja or Nunjucks + id: usage-jinja + - label: Examples + id: examples + children: + - label: Scrollable + id: example-scrollable + - label: Disabled + id: example-disabled + - label: With icon + id: example-with-icon --- +{% from "macros/code_preview.njk" import code_preview %} {% from "macros/code_block.njk" import code_block %} -{% set code %} -
{% endset %} -{{ code_block("accordion", code, "max-w-md") }} +{% from "components/select.njk" import select %} -

Usage

+{% set code_native %}{% endset %} +{{ code_preview("select-native", code_native) }} + +{% set code_alpine %} +{% call select(name="select-js", trigger_attrs={"class": "w-[180px]"}) %} +
+ Fruits +
Apple
+
Banana
+
Blueberry
+
Grapes
+
Pineapple
+
+{% endcall %} +{% endset %} +{{ code_preview("select-alpine", code_alpine | prettyHtml) }} + +

Usage

+ +

Pure HTML

+ +
+

If you use a <select> element, just add the select class to it or have a parent with the form class (read more about form).

+
+ +{{ code_block(code_native) }} + +

With Javascript

+ +
+

If you need to do more than what <select> allows (e.g. HTML options), you can use the code below which uses the Popover component. Make sure to include the hidden input with the name you want to use for that field.

+
+ +{{ code_block(code_alpine | prettyHtml) }} + +

Jinja or Nunjucks

+ +
+

If you use Jinja (or Nunjucks), you can use the select() macro directly.

+ +
+ +{% set raw_code %}{% raw %}{% call select(name="select-js") %} +
+ Fruits +
Apple
+
Banana
+
Blueberry
+
Grapes
+
Pineapple
+
+{% endcall %}{% endraw %}{% endset %} +{{ code_block(raw_code, "jinja") }} + +

Examples

+ +

Scrollable

+ +{% set code %} +{% call select( + listbox_attrs={"class": "scrollbar overflow-y-auto max-h-64"} +) %} +{% for i in range(0, 99) %} +
Item {{ i }}
+{% endfor %} +{% endcall %} +{% endset %} + +{{ code_preview("select-scrollable", code | prettyHtml) }} + +

Disabled

+ +{% set code %} +{% call select(trigger_attrs={"disabled": "disabled"}) %} +
Disabled
+{% endcall %} +{% endset %} + +{{ code_preview("select-disabled", code | prettyHtml) }} + +

With icon

+ +{% set code %} +{% call select(trigger_attrs={'class': 'w-[180px]'}) %} +
+ {% lucide "chart-bar", {"class": "text-muted-foreground"} %} + Bar +
+
+ {% lucide "chart-line", {"class": "text-muted-foreground"} %} + Line +
+
+ {% lucide "chart-pie", {"class": "text-muted-foreground"} %} + Pie +
+{% endcall %} +{% endset %} + +{{ code_preview("select-scrollable", code | prettyHtml) }} \ No newline at end of file