Merge branch 'main' into development

This commit is contained in:
Ronan Berder
2025-05-19 00:15:39 -07:00
79 changed files with 1173 additions and 460 deletions
+4 -7
View File
@@ -1,16 +1,13 @@
@import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Lora&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Fira+Code&display=swap");
@import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Inter&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Geist+Mono&display=swap");
@import "tailwindcss";
@import "../../src/css/basecoat.css";
@import "./custom.css";
@theme {
--font-sans: 'Inter';
--font-mono: 'JetBrains Mono';
--font-sans: 'Geist';
--font-mono: 'Geist Mono';
}
@import "./themes/claude.css";
+10
View File
@@ -0,0 +1,10 @@
export default {
title: "Basecoat",
description: "A components library built with Tailwind CSS that works with any web stack.",
keywords: ["components", "component library", "component system", "UI", "UI kit", "shadcn", "shadcn/ui", "Tailwind CSS", "Tailwind", "CSS", "HTML", "Jinja", "Nunjucks", "Alpine.js"],
author: {
name: "Ronan Berder",
x: "@hunvreus"
},
url: process.env.ELEVENTY_ENV === 'development' ? "http://localhost:8080" : "https://basecoatui.com"
};
-4
View File
@@ -1,4 +0,0 @@
{
"title": "Basecoat",
"description": "shadcn/ui for the rest of us"
}
+24 -6
View File
@@ -45,18 +45,36 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Title & Description -->
<title>{{ site.title + ": " + title if page.url === "/" else title + " - " + site.title }}</title>
<meta name="description" content="{{ description or site.description }}"/>
<meta name="title" content="{{ title }} | Basecoat">
<meta name="description" content="{{ description }}">
{% set meta_title = title ~ ' | ' ~ site.title if title else site.title %}
{% set meta_description = description or site.description %}
<title>{{ meta_title }}</title>
<meta name="description" content="{{ meta_description }}"/>
<meta name="title" content="{{ meta_title }}">
{% if site.keywords %}<meta name="keywords" content="{{ site.keywords | join(',') }}" />{% endif %}
<!-- Favicon -->
<link rel="icon" type="image/svg+xml" href="/assets/favicon.svg">
<link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png">
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website">
<meta property="og:url" content="{{ site.url }}{{ page.url }}">
<meta property="og:title" content="{{ meta_title }}">
<meta property="og:description" content="{{ meta_description }}">
<meta property="og:image" content="{{ site.url }}/assets/social-screenshot.png">
<meta property="og:site_name" content="{{ site.title }}">
<meta property="og:locale" content="en_US">
<meta property="og:author" content="{{ site.author.name }}">
<!-- X/Twitter -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:url" content="{{ site.url }}{{ page.url }}">
<meta name="twitter:title" content="{{ title if title else site.title }}">
<meta name="twitter:description" content="{{ meta_description }}">
<meta name="twitter:image" content="{{ site.url }}/assets/social-screenshot.png">
<meta name="twitter:creator" content="{{ site.author.x }}">
<!-- CSS -->
<link rel="preconnect" href="https://rsms.me/">
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
<link rel="stylesheet" href="/assets/styles.css">
<!-- JS -->
+1 -1
View File
@@ -9,7 +9,7 @@ layout: layouts/base.njk
{% include "partials/header.njk" %}
</header>
<div class="p-6 md:p-8 xl:p-12">
<div class="p-4 md:p-6 xl:p-12">
{{ content | safe }}
</div>
</main>
+1 -1
View File
@@ -5,7 +5,7 @@ layout: layouts/layout.njk
<main class="mx-auto relative flex w-full max-w-screen-lg gap-10">
<div class="mx-auto w-full max-w-screen-md">
<header class="space-y-2">
<h1 class="text-3xl font-semibold tracking-tight">{{ title }}</h1>
<h1 class="text-3xl font-bold tracking-tight">{{ title }}</h1>
<p class="text-muted-foreground">{{ description }}</p>
</header>
<article class="pb-12 mt-8 content">
+11 -1
View File
@@ -32,7 +32,6 @@
:aria-label="$store.darkMode.isDark ? 'Switch to light mode' : 'Switch to dark mode'"
:data-tooltip="$store.darkMode.isDark ? 'Light mode' : 'Dark mode'"
data-side="bottom"
data-align="end"
class="btn-icon-outline size-8"
x-init
@click="$store.darkMode.toggle()"
@@ -40,4 +39,15 @@
<span x-show="$store.darkMode.isDark">{% lucide "sun" %}</span>
<span x-show="!$store.darkMode.isDark">{% lucide "moon" %}</span>
</button>
<a
href="https://github.com/hunvreus/basecoat"
class="btn-icon size-8"
target="_blank"
rel="noopener noreferrer"
data-tooltip="GitHub repository"
data-side="bottom"
data-align="end"
>
{% lucide "github" %}
</a>
</div>
@@ -1,7 +1,7 @@
<section id="accordion" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Accordion</h2>
<a href="/components/accordion" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/accordion" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -3,7 +3,7 @@
<section id="alert-dialog" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Alert Dialog</h2>
<a href="/components/alert-dialog" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/alert-dialog" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="alert" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Alert</h2>
<a href="/components/alert" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/alert" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="avatar" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Avatar</h2>
<a href="/components/avatar" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/avatar" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="badge" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Badge</h2>
<a href="/components/badge" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/badge" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -3,7 +3,7 @@
<section id="breadcrumb" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Breadcrumb</h2>
<a href="/components/breadcrumb" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/breadcrumb" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="button" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Button</h2>
<a href="/components/button" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/button" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="card" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Card</h2>
<a href="/components/card" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/card" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="checkbox" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Checkbox</h2>
<a href="/components/checkbox" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/checkbox" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -3,7 +3,7 @@
<section id="combobox" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Combobox</h2>
<a href="/components/combobox" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/combobox" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -3,7 +3,7 @@
<section id="dialog" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Dialog</h2>
<a href="/components/dialog" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/dialog" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -3,7 +3,7 @@
<section id="dropdown-menu" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Dropdown Menu</h2>
<a href="/components/dropdown-menu" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/dropdown-menu" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -258,7 +258,8 @@
{% call dropdown_menu(
id="dropdown-checkboxes",
trigger=trigger,
trigger_attrs={"class": "btn-icon-ghost rounded-full size-8"}
trigger_attrs={"class": "btn-icon-ghost rounded-full size-8"},
content_attrs={"data-align": "end"}
) %}
{{ profile_menu | safe }}
{% endcall %}
@@ -1,7 +1,7 @@
<section id="input" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Input</h2>
<a href="/components/input" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/input" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="label" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Label</h2>
<a href="/components/label" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/label" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="pagination" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Pagination</h2>
<a href="/components/pagination" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/pagination" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -3,7 +3,7 @@
<section id="popover" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Popover</h2>
<a href="/components/popover" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/popover" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="radio-group" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Radio Group</h2>
<a href="/components/radio-group" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/radio-group" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -3,7 +3,7 @@
<section id="select" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Select</h2>
<a href="/components/select" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/select" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="skeleton" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Skeleton</h2>
<a href="/components/skeleton" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/skeleton" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -15,7 +15,7 @@
</div>
</div>
<div class="flex gap-4 w-full">
<div class="flex max-sm:flex-col gap-4 w-full">
<div class="card w-full @md:w-auto @md:min-w-sm">
<header>
<div class="bg-accent animate-pulse rounded-md h-4 w-2/3"></div>
@@ -1,7 +1,7 @@
<section id="slider" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Slider</h2>
<a href="/components/slider" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/slider" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="switch" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Switch</h2>
<a href="/components/switch" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/switch" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="table" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Table</h2>
<a href="/components/table" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/table" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -3,7 +3,7 @@
<section id="tabs" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Tabs</h2>
<a href="/components/tabs" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/tabs" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="textarea" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Textarea</h2>
<a href="/components/textarea" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/textarea" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="toast" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Toast</h2>
<a href="/components/toast" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/toast" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
@@ -1,7 +1,7 @@
<section id="tooltip" class="w-full rounded-lg border scroll-mt-14">
<header class="border-b px-4 py-3 flex items-center justify-between">
<h2 class="text-sm font-medium">Tooltip</h2>
<a href="/components/tooltip" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation">
<a href="/components/tooltip" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
{% lucide "book-open", { "class": "size-4" } %}
</a>
</header>
+19 -3
View File
@@ -13,7 +13,18 @@
{% call popover(
trigger=trigger,
trigger_attrs={"class": "btn-ghost p-2 h-12 w-full flex items-center justify-start"},
content_attrs={"data-side": "right", "data-align": "end", "class": "w-80"}
content_attrs={
"data-side": "right",
"data-align": "end",
"class": "w-80",
"x-init": "
if (window.innerWidth < 768) {
$el.setAttribute('data-side', 'top');
$el.setAttribute('data-align', 'start');
$el.classList.add('w-full');
}
"
}
) %}
<div class="grid gap-4 p-4">
<header class="grid gap-1.5">
@@ -51,7 +62,8 @@
"hx-boost": "true",
"hx-select": "#content",
"hx-target": "#content",
"hx-swap": "outerHTML"
"hx-swap": "outerHTML",
"@click": "if (window.innerWidth < 768) { open = false }"
} %}
{% set icon_home %}{% lucide "house" %}{% endset %}
@@ -65,7 +77,11 @@
{ label: "Introduction", url: "/introduction", icon: icon_info, attrs: link_attrs },
{ label: "Installation", url: "/installation", icon: icon_square_terminal, attrs: link_attrs },
{ label: "Kitchen sink", url: "/kitchen-sink", icon: icon_layout_dashboard, attrs: link_attrs },
{ label: "GitHub", url: "https://github.com/hunvreus/basecoat", icon: icon_github, attrs: { "target": "_blank" } }
{ label: "GitHub", url: "https://github.com/hunvreus/basecoat", icon: icon_github, attrs: {
"target": "_blank",
"@click": "if (window.innerWidth < 768) { open = false }"
}
}
]},
{ type: 'group', label: 'Components', items: [
{ label: "Accordion", url: "/components/accordion", attrs: link_attrs },
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+26 -17
View File
@@ -1,15 +1,12 @@
/*! tailwindcss v4.1.4 | MIT License | https://tailwindcss.com */
@import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Lora&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Fira+Code&display=swap");
@import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Inter&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Geist+Mono&display=swap");
@layer properties;
@layer theme, base, components, utilities;
@layer theme {
:root, :host {
--font-sans: 'Inter';
--font-mono: 'JetBrains Mono';
--font-sans: 'Geist';
--font-mono: 'Geist Mono';
--color-amber-50: oklch(98.7% 0.022 95.277);
--color-amber-100: oklch(96.2% 0.059 95.617);
--color-amber-900: oklch(41.4% 0.112 45.904);
@@ -56,7 +53,7 @@
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--tracking-tighter: -0.05em;
--font-weight-bold: 700;
--tracking-tight: -0.025em;
--tracking-normal: 0em;
--tracking-widest: 0.1em;
@@ -352,6 +349,9 @@
.mb-6 {
margin-bottom: calc(var(--spacing) * 6);
}
.mb-8 {
margin-bottom: calc(var(--spacing) * 8);
}
.mb-12 {
margin-bottom: calc(var(--spacing) * 12);
}
@@ -364,6 +364,9 @@
.block {
display: block;
}
.contents {
display: contents;
}
.flex {
display: flex;
}
@@ -772,9 +775,6 @@
.p-4 {
padding: calc(var(--spacing) * 4);
}
.p-6 {
padding: calc(var(--spacing) * 6);
}
.p-10 {
padding: calc(var(--spacing) * 10);
}
@@ -881,6 +881,10 @@
--tw-leading: var(--leading-tight);
line-height: var(--leading-tight);
}
.font-bold {
--tw-font-weight: var(--font-weight-bold);
font-weight: var(--font-weight-bold);
}
.font-medium {
--tw-font-weight: var(--font-weight-medium);
font-weight: var(--font-weight-medium);
@@ -897,10 +901,6 @@
--tw-tracking: var(--tracking-tight);
letter-spacing: var(--tracking-tight);
}
.tracking-tighter {
--tw-tracking: var(--tracking-tighter);
letter-spacing: var(--tracking-tighter);
}
.tracking-widest {
--tw-tracking: var(--tracking-widest);
letter-spacing: var(--tracking-widest);
@@ -1218,6 +1218,11 @@
background-color: var(--color-green-50);
}
}
.max-sm\:flex-col {
@media (width < 40rem) {
flex-direction: column;
}
}
.sm\:max-w-\[425px\] {
@media (width >= 40rem) {
max-width: 425px;
@@ -1261,9 +1266,9 @@
border-left-width: 1px;
}
}
.md\:p-8 {
.md\:p-6 {
@media (width >= 48rem) {
padding: calc(var(--spacing) * 8);
padding: calc(var(--spacing) * 6);
}
}
.md\:pl-8 {
@@ -3171,6 +3176,10 @@
background-size: 1rem;
background-position: center right 0.75rem;
background-repeat: no-repeat;
option, optgroup {
background-color: var(--color-popover);
color: var(--color-popover-foreground);
}
}
}
.sidebar {
+2 -2
View File
@@ -61,7 +61,7 @@ document.addEventListener('alpine:init', () => {
<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 gap-2 my-6">
<div class="flex flex-wrap gap-2 my-6">
<a class="badge-outline" href="/installation/#install-js">
Components with Javascript
{% lucide "arrow-right" %}
@@ -89,7 +89,7 @@ document.addEventListener('alpine:init', () => {
<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. If you use one of the macros, make sure to set <code>close_on_overlay_click</code> and <code>close_button</code> to <code>False</code> (or <code>false</code> for Nunjucks).</p>
</div>
<div class="flex gap-2 my-6">
<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" %}
+1 -1
View File
@@ -12,7 +12,7 @@ toc:
<div class="alert mb-6">
{% lucide "circle-alert" %}
<h2>There is no dedicated accordion component in Basecoat.</h2>
<h2>There is no dedicated avatar 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 %}
+1 -1
View File
@@ -75,7 +75,7 @@ document.addEventListener('alpine:init', () => {
<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 gap-2 my-6">
<div class="flex flex-wrap gap-2 my-6">
<a class="badge-outline" href="/installation/#install-js">
Components with Javascript
{% lucide "arrow-right" %}
+2 -2
View File
@@ -71,7 +71,7 @@ document.addEventListener('alpine:init', () => {
<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>
</div>
<div class="flex gap-2 my-6">
<div class="flex flex-wrap gap-2 my-6">
<a class="badge-outline" href="/installation/#install-js">
Components with Javascript
{% lucide "arrow-right" %}
@@ -99,7 +99,7 @@ document.addEventListener('alpine:init', () => {
<p>You can use the <code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-xs">select()</code> Nunjucks or Jinja macro for this component. If you use one of the macros, make sure to set <code>is_combobox</code> to <code>True</code> (or <code>true</code> for Nunjucks).</p>
</div>
<div class="flex gap-2 my-6">
<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" %}
+11 -2
View File
@@ -89,7 +89,7 @@ document.addEventListener('alpine:init', () => {
<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 gap-2 my-6">
<div class="flex flex-wrap gap-2 my-6">
<a class="badge-outline" href="/installation/#install-js">
Components with Javascript
{% lucide "arrow-right" %}
@@ -111,13 +111,22 @@ document.addEventListener('alpine:init', () => {
] %}
{{ 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 gap-2 my-6">
<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" %}
+2 -2
View File
@@ -114,7 +114,7 @@ document.addEventListener('alpine:init', () => {
<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 gap-2 my-6">
<div class="flex flex-wrap gap-2 my-6">
<a class="badge-outline" href="/installation/#install-js">
Components with Javascript
{% lucide "arrow-right" %}
@@ -142,7 +142,7 @@ document.addEventListener('alpine:init', () => {
<p>You can use the <code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-xs">dropdown_menu()</code> Nunjucks or Jinja macro for this component.</p>
</div>
<div class="flex gap-2 my-6">
<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" %}
+2 -2
View File
@@ -91,7 +91,7 @@ document.addEventListener('alpine:init', () => {
<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 gap-2 my-6">
<div class="flex flex-wrap gap-2 my-6">
<a class="badge-outline" href="/installation/#install-js">
Components with Javascript
{% lucide "arrow-right" %}
@@ -119,7 +119,7 @@ document.addEventListener('alpine:init', () => {
<p>You can use the <code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-xs">popover()</code> Nunjucks or Jinja macro for this component.</p>
</div>
<div class="flex gap-2 my-6">
<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" %}
+6 -2
View File
@@ -106,7 +106,7 @@ document.addEventListener('alpine:init', () => {
<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 gap-2 my-6">
<div class="flex flex-wrap gap-2 my-6">
<a class="badge-outline" href="/installation/#install-js">
Components with Javascript
{% lucide "arrow-right" %}
@@ -128,13 +128,17 @@ document.addEventListener('alpine:init', () => {
] %}
{{ tabs(id="select", tabsets=tabsets) }}
<section class="prose">
<p>The component will dispatch a <code>select:change</code> event when a value is selected, along with the value and label of the selected option in the <code>detail</code> object.</p>
</section>
<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">dropdown_menu()</code> Nunjucks or Jinja macro for this component.</p>
</div>
<div class="flex gap-2 my-6">
<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" %}
+2 -2
View File
@@ -43,7 +43,7 @@ toc:
<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 gap-2 my-6">
<div class="flex flex-wrap gap-2 my-6">
<a class="badge-outline" href="/installation/#install-js">
Components with Javascript
{% lucide "arrow-right" %}
@@ -112,7 +112,7 @@ document.addEventListener('alpine:init', () => {
<p>You can use the <code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-xs">sidebar()</code> Nunjucks or Jinja macro for this component.</p>
</div>
<div class="flex gap-2 my-6">
<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" %}
+2 -2
View File
@@ -109,7 +109,7 @@ document.addEventListener('alpine:init', () => {
<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 gap-2 my-6">
<div class="flex flex-wrap gap-2 my-6">
<a class="badge-outline" href="/installation/#install-js">
Components with Javascript
{% lucide "arrow-right" %}
@@ -137,7 +137,7 @@ document.addEventListener('alpine:init', () => {
<p>You can use the <code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-xs">tabs()</code> Nunjucks or Jinja macro for this component.</p>
</div>
<div class="flex gap-2 my-6">
<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" %}
+2 -2
View File
@@ -67,7 +67,7 @@ toc:
<p>You will also need to 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 gap-2 my-6">
<div class="flex flex-wrap gap-2 my-6">
<a class="badge-outline" href="/installation/#install-js">
Components with Javascript
{% lucide "arrow-right" %}
@@ -205,7 +205,7 @@ document.addEventListener('alpine:init', () => {
<p>You can use the <code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-xs">toaster()</code> and <code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-xs">toast()</code> Nunjucks or Jinja macros for this component.</p>
</div>
<div class="flex gap-2 my-6">
<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" %}
+3 -3
View File
@@ -7,7 +7,7 @@ layout: layouts/layout.njk
<div class="max-w-screen-lg mx-auto">
<header class="flex flex-col gap-4">
<div class="flex flex-col gap-2">
<h1 class="text-2xl font-semibold tracking-tighter sm:text-3xl md:text-4xl">All of the shadcn/ui magic, none of the React</h1>
<h1 class="text-2xl font-bold tracking-tight sm:text-3xl md:text-4xl">All of the shadcn/ui magic, none of the React</h1>
<p class="sm:text-lg text-muted-foreground">A components library built with Tailwind CSS that works with any web stack.</p>
</div>
<div class="flex w-full items-center justify-start gap-2 pt-2">
@@ -92,7 +92,7 @@ layout: layouts/layout.njk
<div class="font-medium">Strictly Necessary</div>
<div class="text-muted-foreground">These cookies are essential in order to use the website and use its features.</div>
</div>
<input type="checkbox" role="switch" class="input" />
<input type="checkbox" role="switch" class="input" checked />
</label>
<label class="flex items-center justify-between gap-2">
<div class="flex flex-col gap-0.5">
@@ -192,7 +192,7 @@ layout: layouts/layout.njk
</div>
<div class="grid gap-2 flex-1">
<label for="payment-method-cvv">CVV</label>
<input type="text" id="payment-method-cvv" placeholder="123" maxlength="3" class="w-full" />
<input type="text" id="payment-method-cvv" placeholder="123" maxlength="4" class="w-full" />
</div>
</div>
<button type="button" class="btn w-full">Continue</button>
+53 -14
View File
@@ -25,14 +25,10 @@ toc:
---
{% from "macros/code_block.njk" import code_block %}
{% from "tabs.njk" import tabs %}
<h2 id="install-css">Install the CSS</h2>
<div class="alert my-6">
{% lucide "circle-alert" %}
<h2>If you don't want to use npm, you can follow the <a href="#install-manual" class="underline underline-offset-4">manual installation instructions</a>.</h2>
</div>
<ol class="[&>h3]:step steps mb-12 md:ml-4 md:border-l md:pl-8">
<li class="step">
<h4 class="mb-4 scroll-m-20 font-semibold tracking-tight" id="install-css-tailwind"><a href="#install-css-tailwind">Add Tailwind CSS</a></h4>
@@ -46,8 +42,17 @@ toc:
<div class="prose">
<p>Add Basecoat to your Tailwind CSS file.</p>
</div>
{% set code %}npm install hunvreus/basecoat{% endset %}
{{ code_block(code, "bash") }}
{% set code_npm %}npm install basecoat-css{% endset %}
{% set code_pnpm %}pnpm add basecoat-css{% endset %}
{% set code_bun %}bun add basecoat-css{% endset %}
{% set code_yarn %}yarn add basecoat-css{% endset %}
{% set tabsets = [
{ tab: "npm", panel: code_block(code_npm, class="") },
{ tab: "pnpm", panel: code_block(code_pnpm, class="") },
{ tab: "bun", panel: code_block(code_bun, class="") },
{ tab: "yarn", panel: code_block(code_yarn, class="") }
] %}
{{ tabs(id="npm-install", tabsets=tabsets) }}
<div class="prose">
<p>Alternatively, you can directly <a href="https://github.com/hunvreus/basecoat/blob/main/src/css/basecoat.css" target="_blank">copy the <code>basecoat.css</code> file</a> into your project.</p>
</div>
@@ -55,7 +60,7 @@ toc:
<li class="step mt-8">
<h3 class="mb-4 scroll-m-20 font-semibold tracking-tight" id="install-css-import"><a href="#install-css-import">Import basecoat in your CSS</a></h3>
{% set code %}@import "tailwindcss";
@import "basecoat";{% endset %}
@import "basecoat-css";{% endset %}
{{ code_block(code, "css") }}
</li>
<li class="step mt-8">
@@ -95,10 +100,23 @@ toc:
<h2 id="install-cli"><a href="#install-cli">Use the CLI</a></h2>
<div class="prose">
<p>If you're using Nunjucks or Jinja, you can use the CLI to install the CSS and macros for any of the complex components(e.g. <a href="/components/dialog">Dialog</a>). It will copy the JS and `<code>.html.jinja</code> or <code>.njk</code> macros into your code.</p>
<p>For example, to add the Dialog component, run:</p>
{% set code %}npx basecoatui add dialog{% endset %}
{{ code_block(code, "bash") }}
<p>If you're using Nunjucks or Jinja, you can use the CLI to install the CSS and macros for any of the complex components(e.g. <a href="/components/dialog">Dialog</a>). It will copy the JS and <code>.html.jinja</code> or <code>.njk</code> macros into your code.</p>
<p>For example, to add the Dialog component, run one of the following commands:</p>
</div>
{% set code_npm_exec %}npx basecoat-cli add dialog{% endset %}
{% set code_pnpm_exec %}pnpm dlx basecoat-cli add dialog{% endset %}
{% set code_bun_exec %}bunx basecoat-cli add dialog{% endset %}
{% set code_yarn_exec %}yarn dlx basecoat-cli add dialog{% endset %}
{% set exec_tabsets = [
{ tab: "npm", panel: code_block(code_npm_exec, class="") },
{ tab: "pnpm", panel: code_block(code_pnpm_exec, class="") },
{ tab: "bun", panel: code_block(code_bun_exec, class="") },
{ tab: "yarn", panel: code_block(code_yarn_exec, class="") }
] %}
{{ tabs(id="cli-execution", tabsets=exec_tabsets, label="Execute CLI commands to add components:") }}
<div class="prose my-6">
<p>You will be asked to confirm the template engine and destination directory for the Javascript and macros.</p>
</div>
@@ -140,10 +158,31 @@ toc:
<li>
Import the theme in your CSS file:
{% set code %}@import "tailwindcss";
@import "basecoat";
@import "basecoat-css";
@import "theme.css";{% endset %}
{{ code_block(code, "css") }}
</li>
</ul>
<p><a href="https://ui.shadcn.com/docs/theming" target="_blank">Read more about theming on the shadcn/ui website.</a></p>
</div>
<div class="flex flex-wrap gap-2 my-6">
<a class="badge-outline" href="https://ui.shadcn.com/docs/theming" target="_blank">
About shadcn/ui theming
{% lucide "arrow-right" %}
</a>
</div>
<h2 id="install-customization"><a href="#install-manual">Customization</a></h2>
<div class="prose">
<p>You can override default styles using Tailwind:</p>
{% set code %}<button class="btn font-normal ">Click me</button>{% endset %}
{{ code_block(code, "html") }}
<p>You can also obviously extend and/or override the existing styles with your own Tailwind files:</p>
{% set code %}@import "tailwindcss";
@import "basecoat-css";
@import "theme.css";{% endset %}
{{ code_block(code, "css") }}
<p>You can also use use the <a href="#install-theming">theme variables</a> to customize many aspects of the components (colors, fonts, sizes, etc).</p>
<p><b>If you want to make more drastic changes</b>, I recommend <a href="https://github.com/hunvreus/basecoat/blob/main/src/css/basecoat.css" target="_blank">copying the <code>basecoat.css</code> file</a> into your project and making your changes there.</p>
</div>
+5 -5
View File
@@ -46,7 +46,7 @@ toc:
<p>There's also a CLI to help you scaffold components and get set up fast.</p>
<p><a href="/docs/installation">Check out the installation guide</a> to get started.</p>
<p><a href="/installation">Check out the installation guide</a> to get started.</p>
</div>
<h2 id="how-can-i-help"><a href="#how-can-i-help">How can I help?</a></h2>
@@ -55,9 +55,9 @@ toc:
<p>Basecoat is 100% open source and free.</p>
<ul>
<li><a href="https://github.com/basecoat-ui/basecoat">Star it on GitHub</a></li>
<li><a href="https://github.com/basecoat-ui/basecoat/issues">Report bugs or request features</a></li>
<li><a href="https://github.com/basecoat-ui/basecoat/pulls">Submit a pull request</a></li>
<li><a href="https://github.com/hunvreus/basecoat">Star it on GitHub</a></li>
<li><a href="https://github.com/hunvreus/basecoat/issues">Report bugs or request features</a></li>
<li><a href="https://github.com/hunvreus/basecoat/pulls">Submit a pull request</a></li>
<li><a href="https://github.com/sponsors/hunvreus">Sponsor the project</a></li>
</ul>
</div>
</div>
+13 -5
View File
@@ -1,5 +1,7 @@
---
layout: layouts/layout.njk
title: Kitchen Sink
description: A collection of all the components available in Basecoat.
---
{% set components = [
{ label: "Accordion", id: "accordion" },
@@ -31,11 +33,17 @@ layout: layouts/layout.njk
{ label: "Tooltip", id: "tooltip" }
] %}
<div class="flex gap-x-10">
<div class="grid gap-4 flex-1">
{% for component in components %}
{% include "partials/kitchen-sink/" ~ component.id ~ ".njk" %}
{% endfor %}
<div class="flex gap-x-10 justify-center">
<div>
<header class="space-y-2 mb-8">
<h1 class="text-3xl font-semibold tracking-tight">{{ title }}</h1>
<p class="text-muted-foreground">{{ description }}</p>
</header>
<div class="grid gap-4 flex-1">
{% for component in components %}
{% include "partials/kitchen-sink/" ~ component.id ~ ".njk" %}
{% endfor %}
</div>
</div>
<div class="hidden text-sm xl:block w-full max-w-[200px]">
{% from "macros/toc.njk" import toc_nav %}
+7
View File
@@ -0,0 +1,7 @@
---
permalink: /robots.txt
eleventyExcludeFromCollections: true
---
Sitemap: {{ site.url }}/sitemap.xml
User-agent: *
Disallow:
+15
View File
@@ -0,0 +1,15 @@
---
permalink: /sitemap.xml
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{% for page in collections.all %}
{% if not page.url.startsWith('/fragments/') %}
<url>
<loc>{{ site.url }}{{ page.url | url }}</loc>
<lastmod>{{ page.date.toISOString() }}</lastmod>
</url>
{% endif %}
{% endfor %}
</urlset>