@pokle/basecoat 0.3.10-beta2.pokle

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/.eleventy.js +47 -0
  2. package/.gitattributes +1 -0
  3. package/.gitignore +12 -0
  4. package/AGENTS.md +112 -0
  5. package/CONTRIBUTING.md +15 -0
  6. package/LICENSE.md +21 -0
  7. package/README.md +29 -0
  8. package/ROADMAP.md +20 -0
  9. package/docs/css/custom.css +92 -0
  10. package/docs/css/highlight.css +151 -0
  11. package/docs/css/styles.css +8 -0
  12. package/docs/css/themes/claude.css +95 -0
  13. package/docs/css/themes/doom-64.css +95 -0
  14. package/docs/css/themes/supabase.css +100 -0
  15. package/docs/src/_data/site.js +10 -0
  16. package/docs/src/_includes/layouts/base.njk +112 -0
  17. package/docs/src/_includes/layouts/layout.njk +15 -0
  18. package/docs/src/_includes/layouts/page.njk +21 -0
  19. package/docs/src/_includes/macros/code_block.njk +23 -0
  20. package/docs/src/_includes/macros/code_preview.njk +26 -0
  21. package/docs/src/_includes/macros/toc.njk +20 -0
  22. package/docs/src/_includes/partials/header.njk +64 -0
  23. package/docs/src/_includes/partials/kitchen-sink/accordion.njk +89 -0
  24. package/docs/src/_includes/partials/kitchen-sink/alert-dialog.njk +26 -0
  25. package/docs/src/_includes/partials/kitchen-sink/alert.njk +72 -0
  26. package/docs/src/_includes/partials/kitchen-sink/avatar.njk +37 -0
  27. package/docs/src/_includes/partials/kitchen-sink/badge.njk +47 -0
  28. package/docs/src/_includes/partials/kitchen-sink/breadcrumb.njk +42 -0
  29. package/docs/src/_includes/partials/kitchen-sink/button.njk +101 -0
  30. package/docs/src/_includes/partials/kitchen-sink/card.njk +147 -0
  31. package/docs/src/_includes/partials/kitchen-sink/checkbox.njk +34 -0
  32. package/docs/src/_includes/partials/kitchen-sink/combobox.njk +83 -0
  33. package/docs/src/_includes/partials/kitchen-sink/dialog.njk +65 -0
  34. package/docs/src/_includes/partials/kitchen-sink/dropdown-menu.njk +294 -0
  35. package/docs/src/_includes/partials/kitchen-sink/form.njk +106 -0
  36. package/docs/src/_includes/partials/kitchen-sink/input.njk +27 -0
  37. package/docs/src/_includes/partials/kitchen-sink/label.njk +30 -0
  38. package/docs/src/_includes/partials/kitchen-sink/pagination.njk +34 -0
  39. package/docs/src/_includes/partials/kitchen-sink/popover.njk +43 -0
  40. package/docs/src/_includes/partials/kitchen-sink/radio-group.njk +33 -0
  41. package/docs/src/_includes/partials/kitchen-sink/select.njk +99 -0
  42. package/docs/src/_includes/partials/kitchen-sink/skeleton.njk +40 -0
  43. package/docs/src/_includes/partials/kitchen-sink/slider.njk +38 -0
  44. package/docs/src/_includes/partials/kitchen-sink/switch.njk +27 -0
  45. package/docs/src/_includes/partials/kitchen-sink/table.njk +74 -0
  46. package/docs/src/_includes/partials/kitchen-sink/tabs.njk +105 -0
  47. package/docs/src/_includes/partials/kitchen-sink/textarea.njk +27 -0
  48. package/docs/src/_includes/partials/kitchen-sink/toast.njk +25 -0
  49. package/docs/src/_includes/partials/kitchen-sink/tooltip.njk +24 -0
  50. package/docs/src/_includes/partials/sidebar.njk +139 -0
  51. package/docs/src/assets/apple-touch-icon.png +0 -0
  52. package/docs/src/assets/favicon.svg +12 -0
  53. package/docs/src/assets/images/avatar-1.png +0 -0
  54. package/docs/src/assets/images/avatar-2.png +0 -0
  55. package/docs/src/assets/images/avatar-3.png +0 -0
  56. package/docs/src/assets/images/screenshot.png +0 -0
  57. package/docs/src/assets/social-screenshot.png +0 -0
  58. package/docs/src/assets/social.png +0 -0
  59. package/docs/src/assets/styles.css +6309 -0
  60. package/docs/src/components/accordion.njk +75 -0
  61. package/docs/src/components/alert-dialog.njk +119 -0
  62. package/docs/src/components/alert.njk +108 -0
  63. package/docs/src/components/avatar.njk +40 -0
  64. package/docs/src/components/badge.njk +93 -0
  65. package/docs/src/components/breadcrumb.njk +71 -0
  66. package/docs/src/components/button-group.njk +290 -0
  67. package/docs/src/components/button.njk +141 -0
  68. package/docs/src/components/card.njk +156 -0
  69. package/docs/src/components/carousel.njk +102 -0
  70. package/docs/src/components/chart.njk +814 -0
  71. package/docs/src/components/checkbox.njk +101 -0
  72. package/docs/src/components/combobox.njk +293 -0
  73. package/docs/src/components/command.njk +288 -0
  74. package/docs/src/components/dialog.njk +177 -0
  75. package/docs/src/components/dropdown-menu.njk +403 -0
  76. package/docs/src/components/empty.njk +157 -0
  77. package/docs/src/components/field.njk +459 -0
  78. package/docs/src/components/form.njk +79 -0
  79. package/docs/src/components/input-group.njk +372 -0
  80. package/docs/src/components/input.njk +90 -0
  81. package/docs/src/components/item.njk +320 -0
  82. package/docs/src/components/kbd.njk +76 -0
  83. package/docs/src/components/label.njk +41 -0
  84. package/docs/src/components/pagination.njk +48 -0
  85. package/docs/src/components/popover.njk +174 -0
  86. package/docs/src/components/progress.njk +44 -0
  87. package/docs/src/components/radio-group.njk +48 -0
  88. package/docs/src/components/select.njk +457 -0
  89. package/docs/src/components/sidebar.njk +219 -0
  90. package/docs/src/components/skeleton.njk +51 -0
  91. package/docs/src/components/slider.njk +47 -0
  92. package/docs/src/components/spinner.njk +214 -0
  93. package/docs/src/components/switch.njk +54 -0
  94. package/docs/src/components/table.njk +87 -0
  95. package/docs/src/components/tabs.njk +232 -0
  96. package/docs/src/components/textarea.njk +90 -0
  97. package/docs/src/components/theme-switcher.njk +111 -0
  98. package/docs/src/components/toast.njk +279 -0
  99. package/docs/src/components/tooltip.njk +53 -0
  100. package/docs/src/fragments/toast/error.njk +6 -0
  101. package/docs/src/fragments/toast/info.njk +5 -0
  102. package/docs/src/fragments/toast/success.njk +7 -0
  103. package/docs/src/fragments/toast/warning.njk +5 -0
  104. package/docs/src/index.njk +336 -0
  105. package/docs/src/installation.njk +275 -0
  106. package/docs/src/introduction.njk +63 -0
  107. package/docs/src/kitchen-sink.njk +52 -0
  108. package/docs/src/llms.txt +506 -0
  109. package/docs/src/robots.njk +7 -0
  110. package/docs/src/sitemap.njk +15 -0
  111. package/docs/src/test.njk +39 -0
  112. package/package.json +51 -0
  113. package/packages/cli/README.md +55 -0
  114. package/packages/cli/index.js +193 -0
  115. package/packages/cli/package.json +44 -0
  116. package/packages/css/README.md +63 -0
  117. package/packages/css/package.json +63 -0
  118. package/scripts/build.js +170 -0
  119. package/src/css/basecoat.cdn.css +2 -0
  120. package/src/css/basecoat.css +1310 -0
  121. package/src/jinja/command.html.jinja +206 -0
  122. package/src/jinja/dialog.html.jinja +94 -0
  123. package/src/jinja/dropdown-menu.html.jinja +124 -0
  124. package/src/jinja/popover.html.jinja +48 -0
  125. package/src/jinja/select.html.jinja +196 -0
  126. package/src/jinja/sidebar.html.jinja +144 -0
  127. package/src/jinja/tabs.html.jinja +78 -0
  128. package/src/jinja/toast.html.jinja +117 -0
  129. package/src/js/basecoat.js +99 -0
  130. package/src/js/command.js +175 -0
  131. package/src/js/dropdown-menu.js +171 -0
  132. package/src/js/popover.js +73 -0
  133. package/src/js/select.js +432 -0
  134. package/src/js/sidebar.js +104 -0
  135. package/src/js/tabs.js +63 -0
  136. package/src/js/toast.js +181 -0
  137. package/src/nunjucks/command.njk +206 -0
  138. package/src/nunjucks/dialog.njk +92 -0
  139. package/src/nunjucks/dropdown-menu.njk +124 -0
  140. package/src/nunjucks/popover.njk +48 -0
  141. package/src/nunjucks/select.njk +196 -0
  142. package/src/nunjucks/sidebar.njk +144 -0
  143. package/src/nunjucks/tabs.njk +78 -0
  144. package/src/nunjucks/toast.njk +117 -0
  145. package/wrangler.jsonc +7 -0
@@ -0,0 +1,72 @@
1
+ <section id="alert" class="w-full rounded-lg border scroll-mt-14">
2
+ <header class="border-b px-4 py-3 flex items-center justify-between">
3
+ <h2 class="text-sm font-medium">Alert</h2>
4
+ <a href="/components/alert" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
5
+ {% lucide "book-open", { "class": "size-4" } %}
6
+ </a>
7
+ </header>
8
+ <div class="p-4">
9
+ <div class="grid max-w-xl items-start gap-4">
10
+ <div class="alert">
11
+ {% lucide "circle-check" %}
12
+ <h2>Success! Your changes have been saved</h2>
13
+ <section>This is an alert with icon, title and description.</section>
14
+ </div>
15
+
16
+ <div class="alert">
17
+ {% lucide "bookmark-check" %}
18
+ <section>This is an alert with icon, description and no title.</section>
19
+ </div>
20
+
21
+ <div class="alert">
22
+ <section>This one has a description only. No title. No icon.</section>
23
+ </div>
24
+
25
+ <div class="alert">
26
+ {% lucide "popcorn" %}
27
+ <h2>Let's try one with icon and title.</h2>
28
+ </div>
29
+
30
+ <div class="alert">
31
+ {% lucide "shield-alert" %}
32
+ <h2>This is a very long alert title that demonstrates how the component handles extended text content and potentially wraps across multiple lines</h2>
33
+ </div>
34
+
35
+ <div class="alert">
36
+ {% lucide "gift" %}
37
+ <section>This is a very long alert description that demonstrates how the component handles extended text content and potentially wraps across multiple lines</section>
38
+ </div>
39
+
40
+ <div class="alert">
41
+ {% lucide "circle-alert" %}
42
+ <h2>This is an extremely long alert title that spans multiple lines to demonstrate how the component handles very lengthy headings while maintaining readability and proper text wrapping behavior</h2>
43
+ <section>This is an equally long description that contains detailed information about the alert. It shows how the component can accommodate extensive content while preserving proper spacing, alignment, and readability across different screen sizes and viewport widths. This helps ensure the user experience remains consistent regardless of the content length.</section>
44
+ </div>
45
+
46
+ <div class="alert-destructive">
47
+ {% lucide "circle-alert" %}
48
+ <h2>Something went wrong!</h2>
49
+ <section>Your session has expired. Please log in again.</section>
50
+ </div>
51
+
52
+ <div class="alert-destructive">
53
+ {% lucide "circle-alert" %}
54
+ <h2>Something went wrong!</h2>
55
+ <section>
56
+ <p>Please verify your billing information and try again.</p>
57
+ <ul>
58
+ <li>Check your card details</li>
59
+ <li>Ensure sufficient funds</li>
60
+ <li>Verify billing address</li>
61
+ </ul>
62
+ </section>
63
+ </div>
64
+
65
+ <div class="alert border-amber-50 bg-amber-50 text-amber-900 dark:border-amber-950 dark:bg-amber-950 dark:text-amber-100">
66
+ {% lucide "circle-check" %}
67
+ <h2>Plot Twist: This Alert is Actually Amber!</h2>
68
+ <section>This one has custom colors for light and dark mode.</section>
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </section>
@@ -0,0 +1,37 @@
1
+ <section id="avatar" class="w-full rounded-lg border scroll-mt-14">
2
+ <header class="border-b px-4 py-3 flex items-center justify-between">
3
+ <h2 class="text-sm font-medium">Avatar</h2>
4
+ <a href="/components/avatar" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
5
+ {% lucide "book-open", { "class": "size-4" } %}
6
+ </a>
7
+ </header>
8
+ <div class="p-4">
9
+ <div class="flex flex-row flex-wrap items-center gap-4">
10
+ <img class="size-8 shrink-0 object-cover rounded-full" alt="@hunvreus" src="https://github.com/hunvreus.png">
11
+
12
+ <span class="size-8 shrink-0 bg-muted flex items-center justify-center rounded-full">CN</span>
13
+
14
+ <img class="size-12 shrink-0 object-cover rounded-full" alt="@hunvreus" src="https://github.com/hunvreus.png">
15
+
16
+ <img class="size-8 shrink-0 object-cover rounded-lg" alt="@hunvreus" src="https://github.com/hunvreus.png">
17
+
18
+ <div class="flex -space-x-2 [&_img]:ring-background [&_img]:ring-2 [&_img]:grayscale [&_img]:size-8 [&_img]:shrink-0 [&_img]:object-cover [&_img]:rounded-full">
19
+ <img alt="@hunvreus" src="https://github.com/hunvreus.png">
20
+ <img alt="@shadcn" src="https://github.com/shadcn.png">
21
+ <img alt="@adamwathan" src="https://github.com/adamwathan.png">
22
+ </div>
23
+
24
+ <div class="flex -space-x-2 [&_img]:ring-background [&_img]:ring-2 [&_img]:grayscale [&_img]:size-12 [&_img]:shrink-0 [&_img]:object-cover [&_img]:rounded-full">
25
+ <img alt="@hunvreus" src="https://github.com/hunvreus.png">
26
+ <img alt="@shadcn" src="https://github.com/shadcn.png">
27
+ <img alt="@adamwathan" src="https://github.com/adamwathan.png">
28
+ </div>
29
+
30
+ <div class="flex -space-x-2 hover:space-x-1 [&_img]:ring-background [&_img]:size-12 [&_img]:shrink-0 [&_img]:object-cover [&_img]:rounded-full [&_img]:ring-2 [&_img]:grayscale [&_img]:transition-all [&_img]:ease-in-out [&_img]:duration-300">
31
+ <img alt="@hunvreus" src="https://github.com/hunvreus.png">
32
+ <img alt="@shadcn" src="https://github.com/shadcn.png">
33
+ <img alt="@adamwathan" src="https://github.com/adamwathan.png">
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </section>
@@ -0,0 +1,47 @@
1
+ <section id="badge" class="w-full rounded-lg border scroll-mt-14">
2
+ <header class="border-b px-4 py-3 flex items-center justify-between">
3
+ <h2 class="text-sm font-medium">Badge</h2>
4
+ <a href="/components/badge" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
5
+ {% lucide "book-open", { "class": "size-4" } %}
6
+ </a>
7
+ </header>
8
+ <div class="p-4">
9
+ <div class="flex flex-col gap-2">
10
+ <div class="flex flex-wrap items-center gap-2 md:flex-row">
11
+ <span class="badge">Primary</span>
12
+ <span class="badge-secondary">Secondary</span>
13
+ <span class="badge-outline">Outline</span>
14
+ <span class="badge-destructive">Destructive</span>
15
+ <span class="badge-outline">
16
+ {% lucide "check" %}
17
+ Badge
18
+ </span>
19
+ <span class="badge-destructive">
20
+ {% lucide "circle-alert" %}
21
+ Alert
22
+ </span>
23
+ <span class="badge rounded-full min-w-5 px-1">8</span>
24
+ <span class="badge-destructive rounded-full min-w-5 px-1">99</span>
25
+ <span class="badge-outline rounded-full min-w-5 px-1 font-mono tabular-nums">20+</span>
26
+ </div>
27
+ <div class="flex flex-wrap items-center gap-2 md:flex-row">
28
+ <a href="#" class="badge">
29
+ Link
30
+ {% lucide "arrow-right" %}
31
+ </a>
32
+ <a href="#" class="badge-secondary">
33
+ Link
34
+ {% lucide "arrow-right" %}
35
+ </a>
36
+ <a href="#" class="badge-destructive">
37
+ Link
38
+ {% lucide "arrow-right" %}
39
+ </a>
40
+ <a href="#" class="badge-outline">
41
+ Link
42
+ {% lucide "arrow-right" %}
43
+ </a>
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </section>
@@ -0,0 +1,42 @@
1
+ {% from "dropdown-menu.njk" import dropdown_menu %}
2
+
3
+ <section id="breadcrumb" class="w-full rounded-lg border scroll-mt-14">
4
+ <header class="border-b px-4 py-3 flex items-center justify-between">
5
+ <h2 class="text-sm font-medium">Breadcrumb</h2>
6
+ <a href="/components/breadcrumb" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
7
+ {% lucide "book-open", { "class": "size-4" } %}
8
+ </a>
9
+ </header>
10
+ <div class="p-4">
11
+ <ol class="text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5">
12
+ <li class="inline-flex items-center gap-1.5">
13
+ <a href="#" class="hover:text-foreground transition-colors">Home</a>
14
+ </li>
15
+ <li>{% lucide "chevron-right", { "class": "size-3.5" } %}</li>
16
+ <li class="inline-flex items-center gap-1.5">
17
+ {% set trigger %}
18
+ {% lucide "ellipsis" %}
19
+ {% endset %}
20
+ {{ dropdown_menu(
21
+ id="demo-breadcrumb-menu",
22
+ trigger=trigger,
23
+ trigger_attrs={"class": "flex size-9 items-center justify-center h-4 w-4 hover:text-foreground cursor-pointer"},
24
+ popover_attrs={"class": "p-1"},
25
+ items=[
26
+ { label: "Documentation" },
27
+ { label: "Themes" },
28
+ { label: "GitHub" }
29
+ ]
30
+ ) }}
31
+ </li>
32
+ <li>{% lucide "chevron-right", { "class": "size-3.5" } %}</li>
33
+ <li class="inline-flex items-center gap-1.5">
34
+ <a href="#" class="hover:text-foreground transition-colors">Components</a>
35
+ </li>
36
+ <li>{% lucide "chevron-right", { "class": "size-3.5" } %}</li>
37
+ <li class="inline-flex items-center gap-1.5">
38
+ <span class="text-foreground font-normal">Breadcrumb</span>
39
+ </li>
40
+ </ol>
41
+ </div>
42
+ </section>
@@ -0,0 +1,101 @@
1
+ <section id="button" class="w-full rounded-lg border scroll-mt-14">
2
+ <header class="border-b px-4 py-3 flex items-center justify-between">
3
+ <h2 class="text-sm font-medium">Button</h2>
4
+ <a href="/components/button" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
5
+ {% lucide "book-open", { "class": "size-4" } %}
6
+ </a>
7
+ </header>
8
+ <div class="p-4">
9
+ <div class="flex flex-col gap-6">
10
+ <div class="flex flex-wrap items-center gap-2 md:flex-row">
11
+ <button class="btn-primary">Primary</button>
12
+ <button class="btn-outline">Outline</button>
13
+ <button class="btn-ghost">Ghost</button>
14
+ <button class="btn-destructive">
15
+ {% lucide "send" %}
16
+ Danger
17
+ </button>
18
+ <button class="btn-secondary">Secondary</button>
19
+ <button class="btn-link">Link</button>
20
+ <button class="btn-outline">
21
+ {% lucide "send" %}
22
+ Send
23
+ </button>
24
+ <button class="btn-outline">
25
+ Learn more
26
+ {% lucide "arrow-right" %}
27
+ </button>
28
+ <button class="btn-outline" disabled>
29
+ {% lucide "loader", { "class": "animate-spin" } %}
30
+ Loading
31
+ </button>
32
+ </div>
33
+
34
+ <div class="flex flex-wrap items-center gap-2 md:flex-row">
35
+ <button class="btn-sm-primary">Primary</button>
36
+ <button class="btn-sm-outline">Outline</button>
37
+ <button class="btn-sm-ghost">Ghost</button>
38
+ <button class="btn-sm-destructive">Danger</button>
39
+ <button class="btn-sm-secondary">Secondary</button>
40
+ <button class="btn-sm-link">Link</button>
41
+ <button class="btn-sm-outline">
42
+ {% lucide "send" %}
43
+ Send
44
+ </button>
45
+ <button class="btn-sm-outline">
46
+ Learn more
47
+ {% lucide "arrow-right" %}
48
+ </button>
49
+ <button class="btn-sm-outline" disabled>
50
+ {% lucide "loader", { "class": "animate-spin" } %}
51
+ Loading
52
+ </button>
53
+ </div>
54
+
55
+ <div class="flex flex-wrap items-center gap-2 md:flex-row">
56
+ <button class="btn-lg-primary">Primary</button>
57
+ <button class="btn-lg-outline">Outline</button>
58
+ <button class="btn-lg-ghost">Ghost</button>
59
+ <button class="btn-lg-destructive">
60
+ {% lucide "send" %}
61
+ Danger
62
+ </button>
63
+ <button class="btn-lg-secondary">Secondary</button>
64
+ <button class="btn-lg-link">Link</button>
65
+ <button class="btn-lg-outline">
66
+ {% lucide "send" %}
67
+ Send
68
+ </button>
69
+ <button class="btn-lg-outline">
70
+ Learn more
71
+ {% lucide "arrow-right" %}
72
+ </button>
73
+ <button class="btn-lg-outline" disabled>
74
+ {% lucide "loader", { "class": "animate-spin" } %}
75
+ Loading
76
+ </button>
77
+ </div>
78
+
79
+ <div class="flex flex-wrap items-center gap-2 md:flex-row">
80
+ <button class="btn-icon-primary">
81
+ {% lucide "download" %}
82
+ </button>
83
+ <button class="btn-icon-secondary">
84
+ {% lucide "upload" %}
85
+ </button>
86
+ <button class="btn-icon-outline">
87
+ {% lucide "arrow-right" %}
88
+ </button>
89
+ <button class="btn-icon-ghost">
90
+ {% lucide "ellipsis" %}
91
+ </button>
92
+ <button class="btn-icon-destructive">
93
+ {% lucide "trash-2" %}
94
+ </button>
95
+ <button class="btn-icon-outline" disabled>
96
+ {% lucide "loader", { "class": "animate-spin" } %}
97
+ </button>
98
+ </div>
99
+ </div>
100
+ </div>
101
+ </section>
@@ -0,0 +1,147 @@
1
+ <section id="card" class="w-full rounded-lg border scroll-mt-14">
2
+ <header class="border-b px-4 py-3 flex items-center justify-between">
3
+ <h2 class="text-sm font-medium">Card</h2>
4
+ <a href="/components/card" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
5
+ {% lucide "book-open", { "class": "size-4" } %}
6
+ </a>
7
+ </header>
8
+ <div class="p-4">
9
+ <div class="flex flex-col items-start gap-4">
10
+ <div class="card w-full max-w-sm">
11
+ <header>
12
+ <h2>Login to your account</h2>
13
+ <p>Enter your details below to login to your account</p>
14
+ </header>
15
+ <section>
16
+ <form class="form grid gap-6">
17
+ <div class="grid gap-2">
18
+ <label for="demo-card-form-email">Email</label>
19
+ <input type="email" id="demo-card-form-email">
20
+ </div>
21
+ <div class="grid gap-2">
22
+ <div class="flex items-center gap-2">
23
+ <label for="demo-card-form-password">Password</label>
24
+ <a href="#" class="ml-auto inline-block text-sm underline-offset-4 hover:underline">Forgot your password?</a>
25
+ </div>
26
+ <input type="password" id="demo-card-form-password">
27
+ </div>
28
+ </form>
29
+ </section>
30
+ <footer class="flex flex-col items-center gap-2">
31
+ <button type="button" class="btn w-full">Login</button>
32
+ <button type="button" class="btn-outline w-full">Login with Google</button>
33
+ <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>
34
+ </footer>
35
+ </div>
36
+
37
+ <div class="card">
38
+ <header>
39
+ <h2>Meeting Notes</h2>
40
+ <p>Transcript from the meeting with the client.</p>
41
+ </header>
42
+ <section class="text-sm">
43
+ <p>Client requested dashboard redesign with focus on mobile responsiveness.</p>
44
+ <ol class="mt-4 flex list-decimal flex-col gap-2 pl-6">
45
+ <li>New analytics widgets for daily/weekly metrics</li>
46
+ <li>Simplified navigation menu</li>
47
+ <li>Dark mode support</li>
48
+ <li>Timeline: 6 weeks</li>
49
+ <li>Follow-up meeting scheduled for next Tuesday</li>
50
+ </ol>
51
+ </section>
52
+ <footer class="flex items-center">
53
+ <div class="flex -space-x-2 [&_img]:ring-background [&_img]:ring-2 [&_img]:grayscale [&_img]:size-8 [&_img]:shrink-0 [&_img]:object-cover [&_img]:rounded-full">
54
+ <img alt="@hunvreus" src="https://github.com/hunvreus.png">
55
+ <img alt="@shadcn" src="https://github.com/shadcn.png">
56
+ <img alt="@adamwathan" src="https://github.com/adamwathan.png">
57
+ </div>
58
+ </footer>
59
+ </div>
60
+
61
+ <div class="card">
62
+ <header>
63
+ <h2>Is this an image?</h2>
64
+ <p>This is a card with an image.</p>
65
+ </header>
66
+ <section class="px-0">
67
+ <img
68
+ alt="Photo by Drew Beamer"
69
+ loading="lazy"
70
+ width="500"
71
+ height="500"
72
+ class="aspect-video object-cover" style="color:transparent"
73
+ srcset="
74
+ https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&dpr=2&q=80&w=640&q=75 1x,
75
+ https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&dpr=2&q=80&w=1080&q=75 2x
76
+ "
77
+ src="https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&dpr=2&q=80&w=1080&q=75"
78
+ />
79
+ </section>
80
+ <footer class="flex items-center gap-2">
81
+ <span class="badge-outline">
82
+ {% lucide "bed" %}
83
+ 1
84
+ </span>
85
+ <span class="badge-outline">
86
+ {% lucide "bath" %}
87
+ 2
88
+ </span>
89
+ <span class="badge-outline">
90
+ {% lucide "land-plot" %}
91
+ 350m²
92
+ </span>
93
+ <span class="ml-auto font-medium tabular-nums">
94
+ $135,000
95
+ </span>
96
+ </footer>
97
+ </div>
98
+
99
+ <div class="flex w-full flex-wrap items-start gap-8 md:*:[.card]:basis-1/4">
100
+ <div class="card">
101
+ <section>Content Only</section>
102
+ </div>
103
+
104
+ <div class="card">
105
+ <header>
106
+ <h2>Header Only</h2>
107
+ <p>This is a card with a header and a description.</p>
108
+ </header>
109
+ </div>
110
+
111
+ <div class="card">
112
+ <header>
113
+ <h2>Header and Content</h2>
114
+ <p>This is a card with a header and a content.</p>
115
+ </header>
116
+ <section>Content only.</section>
117
+ </div>
118
+
119
+ <div class="card">
120
+ <footer>Footer Only</footer>
121
+ </div>
122
+
123
+ <div class="card">
124
+ <header>
125
+ <h2>Header + Footer</h2>
126
+ <p>This is a card with a header and a footer.</p>
127
+ </header>
128
+ <footer>Footer</footer>
129
+ </div>
130
+
131
+ <div class="card">
132
+ <section>Content</section>
133
+ <footer>Footer</footer>
134
+ </div>
135
+
136
+ <div class="card">
137
+ <header>
138
+ <h2>Header + Content + Footer</h2>
139
+ <p>This is a card with a header, content and footer.</p>
140
+ </header>
141
+ <section>Content</section>
142
+ <footer>Footer</footer>
143
+ </div>
144
+ </div>
145
+ </div>
146
+ </div>
147
+ </section>
@@ -0,0 +1,34 @@
1
+ <section id="checkbox" class="w-full rounded-lg border scroll-mt-14">
2
+ <header class="border-b px-4 py-3 flex items-center justify-between">
3
+ <h2 class="text-sm font-medium">Checkbox</h2>
4
+ <a href="/components/checkbox" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
5
+ {% lucide "book-open", { "class": "size-4" } %}
6
+ </a>
7
+ </header>
8
+ <div class="p-4">
9
+ <div class="flex flex-col gap-6 max-w-lg">
10
+ <label class="label gap-3">
11
+ <input type="checkbox" class="input">
12
+ Accept terms and conditions
13
+ </label>
14
+ <div class="flex items-start gap-3">
15
+ <input type="checkbox" id="demo-checkbox-label-and-description" class="input">
16
+ <div class="grid gap-2">
17
+ <label for="demo-checkbox-label-and-description" class="label">Accept terms and conditions</label>
18
+ <p class="text-muted-foreground text-sm">By clicking this checkbox, you agree to the terms and conditions.</p>
19
+ </div>
20
+ </div>
21
+ <label class="label gap-3">
22
+ <input type="checkbox" class="input" disabled>
23
+ Enable notifications
24
+ </label>
25
+ <label class="flex items-start gap-3 border p-3 hover:bg-accent/50 rounded-lg has-[input[type='checkbox']:checked]:border-blue-600 has-[input[type='checkbox']:checked]:bg-blue-50 dark:has-[input[type='checkbox']:checked]:border-blue-900 dark:has-[input[type='checkbox']:checked]:bg-blue-950">
26
+ <input type="checkbox" class="input checked:bg-blue-600 checked:border-blue-600 dark:checked:bg-blue-700 dark:checked:border-blue-700 checked:after:bg-white" checked>
27
+ <div class="grid gap-2">
28
+ <h2 class="text-sm leading-none font-medium">Enable notifications</h2>
29
+ <p class="text-muted-foreground text-sm">You can enable or disable notifications at any time.</p>
30
+ </div>
31
+ </label>
32
+ </div>
33
+ </div>
34
+ </section>
@@ -0,0 +1,83 @@
1
+ {% from "select.njk" import select %}
2
+
3
+ <section id="combobox" class="w-full rounded-lg border scroll-mt-14">
4
+ <header class="border-b px-4 py-3 flex items-center justify-between">
5
+ <h2 class="text-sm font-medium">Combobox</h2>
6
+ <a href="/components/combobox" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
7
+ {% lucide "book-open", { "class": "size-4" } %}
8
+ </a>
9
+ </header>
10
+ <div class="p-4">
11
+ <div class="flex flex-wrap items-start gap-4">
12
+ {% set options_frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"] %}
13
+ {% call select(
14
+ popover_attrs={"class": "w-48"},
15
+ listbox_attrs={"data-empty": "No framework found."},
16
+ is_combobox=true
17
+ ) %}
18
+ {% for framework in options_frameworks %}
19
+ <div role="option" data-value="{{ framework }}">{{ framework }}</div>
20
+ {% endfor %}
21
+ {% endcall %}
22
+
23
+ {% set options_timezones = [
24
+ {
25
+ label: "Americas",
26
+ timezones: [
27
+ { value: "America/New_York", label: "(GMT-5) New York" },
28
+ { value: "America/Los_Angeles", label: "(GMT-8) Los Angeles" },
29
+ { value: "America/Chicago", label: "(GMT-6) Chicago" },
30
+ { value: "America/Toronto", label: "(GMT-5) Toronto" },
31
+ { value: "America/Vancouver", label: "(GMT-8) Vancouver" },
32
+ { value: "America/Sao_Paulo", label: "(GMT-3) São Paulo" }
33
+ ]
34
+ },
35
+ {
36
+ label: "Europe",
37
+ timezones: [
38
+ { value: "Europe/London", label: "(GMT+0) London" },
39
+ { value: "Europe/Paris", label: "(GMT+1) Paris" },
40
+ { value: "Europe/Berlin", label: "(GMT+1) Berlin" },
41
+ { value: "Europe/Rome", label: "(GMT+1) Rome" },
42
+ { value: "Europe/Madrid", label: "(GMT+1) Madrid" },
43
+ { value: "Europe/Amsterdam", label: "(GMT+1) Amsterdam" }
44
+ ]
45
+ },
46
+ {
47
+ label: "Asia/Pacific",
48
+ timezones: [
49
+ { value: "Asia/Tokyo", label: "(GMT+9) Tokyo" },
50
+ { value: "Asia/Shanghai", label: "(GMT+8) Shanghai" },
51
+ { value: "Asia/Singapore", label: "(GMT+8) Singapore" },
52
+ { value: "Asia/Dubai", label: "(GMT+4) Dubai" },
53
+ { value: "Australia/Sydney", label: "(GMT+11) Sydney" },
54
+ { value: "Asia/Seoul", label: "(GMT+9) Seoul" }
55
+ ]
56
+ }
57
+ ] %}
58
+ {% call select(
59
+ popover_attrs={"class": "w-72"},
60
+ listbox_attrs={"data-empty": "No timezone found."},
61
+ is_combobox=true
62
+ ) %}
63
+ <div class="max-h-64 overflow-y-auto scrollbar">
64
+ {% for group in options_timezones %}
65
+ <div role="group" aria-labelledby="demo-combobox-timezones-group-{{ loop.index0 }}">
66
+ <span id="demo-combobox-timezones-group-{{ loop.index0 }}" role="heading">{{ group.label }}</span>
67
+ {% for timezone in group.timezones %}
68
+ <div role="option" data-value="{{ timezone.value}}">
69
+ {{ timezone.label }}
70
+ </div>
71
+ {% endfor %}
72
+ </div>
73
+ {% endfor %}
74
+ </div>
75
+ <hr role="separator">
76
+ <div role="option">
77
+ {% lucide "circle-plus" %}
78
+ Create timezone
79
+ </div>
80
+ {% endcall %}
81
+ </div>
82
+ </div>
83
+ </section>
@@ -0,0 +1,65 @@
1
+ {% from "dialog.njk" import dialog %}
2
+
3
+ <section id="dialog" class="w-full rounded-lg border scroll-mt-14">
4
+ <header class="border-b px-4 py-3 flex items-center justify-between">
5
+ <h2 class="text-sm font-medium">Dialog</h2>
6
+ <a href="/components/dialog" class="text-muted-foreground hover:text-foreground" data-tooltip="See documentation" data-side="left">
7
+ {% lucide "book-open", { "class": "size-4" } %}
8
+ </a>
9
+ </header>
10
+ <div class="p-4">
11
+ <div class="flex flex-wrap items-center gap-4">
12
+ {% set footer %}
13
+ <button class="btn-outline" onclick="document.getElementById('demo-dialog-edit-profile').close()">Cancel</button>
14
+ <button class="btn" onclick="document.getElementById('demo-dialog-edit-profile').close()">Save changes</button>
15
+ {% endset %}
16
+ {% call dialog(
17
+ id="demo-dialog-edit-profile",
18
+ title="Edit profile",
19
+ description="Make changes to your profile here. Click save when you're done.",
20
+ trigger="Edit Profile",
21
+ trigger_attrs={"class": "btn-outline"},
22
+ dialog_attrs={"class": "w-full sm:max-w-[425px] max-h-[612px]"},
23
+ footer=footer
24
+ ) %}
25
+ <form class="form grid gap-4">
26
+ <div class="grid gap-3">
27
+ <label for="demo-dialog-edit-profile-name">Name</label>
28
+ <input type="text" value="Pedro Duarte" id="demo-dialog-edit-profile-name" />
29
+ </div>
30
+ <div class="grid gap-3">
31
+ <label for="demo-dialog-edit-profile-username">Username</label>
32
+ <input type="text" value="@peduarte" id="demo-dialog-edit-profile-username" />
33
+ </div>
34
+ </form>
35
+ {% endcall %}
36
+
37
+ {% set footer %}
38
+ <button class="btn-outline" onclick="this.closest('dialog').close()">Close</button>
39
+ {% endset %}
40
+ {% call dialog(
41
+ id="dialog-example",
42
+ title="Scrollable Content",
43
+ description="This is a dialog with scrollable content.",
44
+ trigger="Scrollable Content",
45
+ trigger_attrs={"class": "btn-outline"},
46
+ dialog_attrs={"class": "w-full sm:max-w-[425px] max-h-[612px]"},
47
+ body_attrs={"class": "overflow-y-auto scrollbar"},
48
+ footer=footer
49
+ ) %}
50
+ <div class="space-y-4 text-sm">
51
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
52
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
53
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
54
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
55
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
56
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
57
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
58
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
59
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
60
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
61
+ </div>
62
+ {% endcall %}
63
+ </div>
64
+ </div>
65
+ </section>