diff --git a/dist/basecoat.css b/dist/basecoat.css
index 2197ee9..5915cc4 100644
--- a/dist/basecoat.css
+++ b/dist/basecoat.css
@@ -69,6 +69,8 @@
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
--shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25);
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
--animate-spin: spin 1s linear infinite;
--animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
@@ -531,10 +533,21 @@
--tw-translate-y: calc(calc(1/2 * 100%) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
+ .translate-y-0 {
+ --tw-translate-y: calc(var(--spacing) * 0);
+ translate: var(--tw-translate-x) var(--tw-translate-y);
+ }
.translate-y-0\.5 {
--tw-translate-y: calc(var(--spacing) * 0.5);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
+ .translate-y-2 {
+ --tw-translate-y: calc(var(--spacing) * 2);
+ translate: var(--tw-translate-x) var(--tw-translate-y);
+ }
+ .transform {
+ transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
+ }
.animate-pulse {
animation: var(--animate-pulse);
}
@@ -893,12 +906,18 @@
.underline-offset-4 {
text-underline-offset: 4px;
}
+ .opacity-0 {
+ opacity: 0%;
+ }
.opacity-50 {
opacity: 50%;
}
.opacity-60 {
opacity: 60%;
}
+ .opacity-100 {
+ opacity: 100%;
+ }
.shadow-none {
--tw-shadow: 0 0 #0000;
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
@@ -928,6 +947,11 @@
.filter {
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
}
+ .transition {
+ transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter;
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
+ }
.transition-\[margin-left\] {
transition-property: margin-left;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
@@ -957,10 +981,22 @@
--tw-duration: 200ms;
transition-duration: 200ms;
}
+ .duration-300 {
+ --tw-duration: 300ms;
+ transition-duration: 300ms;
+ }
+ .ease-in {
+ --tw-ease: var(--ease-in);
+ transition-timing-function: var(--ease-in);
+ }
.ease-in-out {
--tw-ease: var(--ease-in-out);
transition-timing-function: var(--ease-in-out);
}
+ .ease-out {
+ --tw-ease: var(--ease-out);
+ transition-timing-function: var(--ease-out);
+ }
.outline-none {
--tw-outline-style: none;
outline-style: none;
@@ -1378,32 +1414,6 @@
}
}
}
- .\[\&_a\:not\(\[class\]\)\]\:text-muted-foreground {
- & a:not([class]) {
- color: var(--color-muted-foreground);
- }
- }
- .\[\&_a\:not\(\[class\]\)\]\:no-underline {
- & a:not([class]) {
- text-decoration-line: none;
- }
- }
- .\[\&_a\:not\(\[class\]\)\]\:transition-colors {
- & a:not([class]) {
- transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
- transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
- transition-duration: var(--tw-duration, var(--default-transition-duration));
- }
- }
- .\[\&_a\:not\(\[class\]\)\]\:hover\:text-foreground {
- & a:not([class]) {
- &:hover {
- @media (hover: hover) {
- color: var(--color-foreground);
- }
- }
- }
- }
.\[\&_img\]\:size-8 {
& img {
width: calc(var(--spacing) * 8);
@@ -1537,6 +1547,33 @@
}
}
}
+ .\[\&\>\[role\=img\]\]\:size-4 {
+ &>[role=img] {
+ width: calc(var(--spacing) * 4);
+ height: calc(var(--spacing) * 4);
+ }
+ }
+ .\[\&\>\[role\=img\]\]\:shrink-0 {
+ &>[role=img] {
+ flex-shrink: 0;
+ }
+ }
+ .\[\&\>\[role\=img\]\>svg\]\:size-4 {
+ &>[role=img]>svg {
+ width: calc(var(--spacing) * 4);
+ height: calc(var(--spacing) * 4);
+ }
+ }
+ .\[\&\>\[role\=img\]\>svg\]\:w-full {
+ &>[role=img]>svg {
+ width: 100%;
+ }
+ }
+ .\[\&\>\[role\=img\]\>svg\]\:shrink-0 {
+ &>[role=img]>svg {
+ flex-shrink: 0;
+ }
+ }
.\[\&\>h2\]\:mt-16 {
&>h2 {
margin-top: calc(var(--spacing) * 16);
@@ -3946,6 +3983,31 @@
inherits: false;
initial-value: 0;
}
+@property --tw-rotate-x {
+ syntax: "*";
+ inherits: false;
+ initial-value: rotateX(0);
+}
+@property --tw-rotate-y {
+ syntax: "*";
+ inherits: false;
+ initial-value: rotateY(0);
+}
+@property --tw-rotate-z {
+ syntax: "*";
+ inherits: false;
+ initial-value: rotateZ(0);
+}
+@property --tw-skew-x {
+ syntax: "*";
+ inherits: false;
+ initial-value: skewX(0);
+}
+@property --tw-skew-y {
+ syntax: "*";
+ inherits: false;
+ initial-value: skewY(0);
+}
@property --tw-space-y-reverse {
syntax: "*";
inherits: false;
@@ -4160,6 +4222,11 @@
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-translate-z: 0;
+ --tw-rotate-x: rotateX(0);
+ --tw-rotate-y: rotateY(0);
+ --tw-rotate-z: rotateZ(0);
+ --tw-skew-x: skewX(0);
+ --tw-skew-y: skewY(0);
--tw-space-y-reverse: 0;
--tw-space-x-reverse: 0;
--tw-border-style: solid;
diff --git a/docs/_includes/components/dialog.njk b/docs/_includes/components/dialog.njk
index 21ce3c9..80dca78 100644
--- a/docs/_includes/components/dialog.njk
+++ b/docs/_includes/components/dialog.njk
@@ -15,7 +15,6 @@
@param open {boolean} [optional] [default=false] - Whether the dialog should be open initially.
@param close_button {boolean} [optional] [default=true] - Whether to include a close button.
@param close_on_overlay_click {boolean} [optional] [default=true] - Whether clicking the overlay closes the dialog.
- @param include_html {boolean} [optional] [default=true] - Whether to render the HTML structure.
@param include_script {boolean} [optional] [default=true] - Whether to include the Alpine.js component script.
@param register_on {array} [optional] [default=["alpine:init"]] - Alpine.js events to register the component on.
#}
@@ -34,7 +33,6 @@
open=false,
close_button=true,
close_on_overlay_click=true,
- include_html=true,
include_script=false,
register_on=["alpine:init"]
) %}
@@ -42,7 +40,6 @@
{% include "components/dialog-script.njk" %}
{% endif %}
-{% if include_html %}
-{% endif %}
{% endmacro %}
\ No newline at end of file
diff --git a/docs/_includes/components/dropdown-menu.njk b/docs/_includes/components/dropdown-menu.njk
index 4d06957..09b8e50 100644
--- a/docs/_includes/components/dropdown-menu.njk
+++ b/docs/_includes/components/dropdown-menu.njk
@@ -4,7 +4,6 @@
main_attrs={},
trigger_attrs={},
content_attrs={},
- include_html=true,
include_script=false,
register_on=["alpine:init"]
) %}
@@ -12,7 +11,6 @@
{% include "components/dropdown-menu-script.njk" %}
{% endif %}
-{% if include_html %}
-{% endif %}
-{% endmacro %}
+{% endmacro %}
\ No newline at end of file
diff --git a/docs/_includes/components/popover.njk b/docs/_includes/components/popover.njk
index 7266508..f8c7e3d 100644
--- a/docs/_includes/components/popover.njk
+++ b/docs/_includes/components/popover.njk
@@ -4,7 +4,6 @@
main_attrs=None,
trigger_attrs=None,
content_attrs=None,
- include_html=true,
include_script=false,
register_on=["alpine:init"]
) %}
@@ -12,7 +11,6 @@
{% include "components/popover-script.njk" %}
{% endif %}
-{% if include_html %}
-{% endif %}
{% endmacro %}
diff --git a/docs/_includes/components/select-script.njk b/docs/_includes/components/select-script.njk
index 7d06110..b031f61 100644
--- a/docs/_includes/components/select-script.njk
+++ b/docs/_includes/components/select-script.njk
@@ -23,7 +23,6 @@
const option = this.options.find(opt => opt.getAttribute('data-value') === initialValue);
this.selectOption(option, false);
this.focusedIndex = this.options.indexOf(option);
- this.focusOption();
} else {
this.selectOption(this.options[0], false);
}
diff --git a/docs/_includes/components/select.njk b/docs/_includes/components/select.njk
index f4ad2db..fa587e1 100644
--- a/docs/_includes/components/select.njk
+++ b/docs/_includes/components/select.njk
@@ -9,7 +9,6 @@
input_attrs={},
search_placeholder="Search entries...",
is_combobox=false,
- include_html=true,
include_script=false,
register_on=["alpine:init"]
) %}
@@ -17,7 +16,6 @@
{% include "components/select-script.njk" %}
{% endif %}
-{% if include_html %}
{% endif %}
-{% endif %}
{% endmacro %}
\ No newline at end of file
diff --git a/docs/_includes/components/tabs.njk b/docs/_includes/components/tabs.njk
index a947c00..8a0d43f 100644
--- a/docs/_includes/components/tabs.njk
+++ b/docs/_includes/components/tabs.njk
@@ -4,7 +4,6 @@
main_attrs=None,
tablist_attrs=None,
default_tab_index=1,
- include_html=true,
include_script=false,
register_on=["alpine:init"]
)
@@ -13,7 +12,6 @@
{% include "components/tabs-script.njk" %}
{% endif %}
-{% if include_html %}
-{% endif %}
{% endmacro %}
\ No newline at end of file
diff --git a/docs/_includes/components/toast-script.njk b/docs/_includes/components/toast-script.njk
index 18e893c..315dafa 100644
--- a/docs/_includes/components/toast-script.njk
+++ b/docs/_includes/components/toast-script.njk
@@ -4,13 +4,14 @@
const registerToastComponent = () => {
Alpine.store('toaster', { isPaused: false });
- Alpine.data('toast', (category = '', timeoutDuration = null) => ({
+ Alpine.data('toast', (config={}) => ({
+ config: config,
open: false,
timeoutDuration: null,
timeoutId: null,
init() {
- this.timeoutDuration = timeoutDuration || (category === 'error' ? 5000 : 3000);
+ this.timeoutDuration = config.duration || (config.category === 'error' ? 5000 : 3000);
this.timeoutId = setTimeout(() => { this.close() }, this.timeoutDuration);
this.open = true;
this.$watch('$store.toaster.isPaused', (isPaused) => {
@@ -37,12 +38,34 @@
this.$el.blur();
},
- $toast: {
+ $toastBindings: {
['@mouseenter']() { this.$store.toaster.isPaused = true },
['@mouseleave']() { this.$store.toaster.isPaused = false },
['@keydown.escape.prevent']() { this.close() },
+ [':aria-hidden']() { return !this.open }
},
}));
+
+ Alpine.magic('toast', (el) => (config, toasterId='toaster') => {
+ const toaster = document.getElementById(toasterId);
+ const template = document.getElementById('toast-template');
+
+ if (!toaster) {
+ console.error(`Toaster container with id #${targetId} not found.`);
+ return;
+ }
+ if (!template) {
+ console.error('Toast template with id #toast-template not found.');
+ return;
+ }
+
+ const clone = template.content.firstElementChild.cloneNode(true);
+
+ clone.setAttribute('x-data', `toast(${JSON.stringify(config)})`);
+ clone.removeAttribute('id');
+
+ toaster.appendChild(clone);
+ });
}
{% for event in (register_on or ["alpine:init"]) %}
diff --git a/docs/_includes/components/toast.njk b/docs/_includes/components/toast.njk
index 0419101..b9874be 100644
--- a/docs/_includes/components/toast.njk
+++ b/docs/_includes/components/toast.njk
@@ -3,7 +3,6 @@
toasts=[],
main_attrs=None,
is_fragment=false,
- include_html=true,
include_script=false,
register_on=["alpine:init"]
) %}
@@ -11,12 +10,11 @@
{% include "components/toast-script.njk" %}
{% endif %}
-{% if include_html %}
-{% set iconMapping = {
- 'error': 'circle-x',
- 'success': 'circle-check',
- 'info': 'info',
- 'warning': 'circle-alert'
+{% set icons = {
+ 'success': '
',
+ 'error': '
',
+ 'info': '
',
+ 'warning': '
'
} %}
{% if toast.category in ["error", "success", "info", "warning"] %}
- {% lucide iconMapping[toast.category], class="size-4 shrink-0" %}
+ {{ icons[toast.category] | safe }}
{% endif %}
- {% if toast.message is string %}
- {{ toast.message }}
- {% elif toast.message is mapping %}
- {% if toast.message.title %}
- {{ toast.message.title }}
- {% endif %}
- {% if toast.message.description %}
- {{ toast.message.description }}
- {% endif %}
+ {% if toast.title %}
+ {{ toast.title }}
+ {% endif %}
+ {% if toast.description %}
+ {{ toast.description }}
{% endif %}
- {% if toast.message.action or toast.message.cancel %}
+ {% if toast.action or toast.cancel %}
@@ -92,5 +85,76 @@
{% endfor %}
+
+{% if not is_fragment %}
+
+
+
+
+
+
+
+
+ {{ icons.success | safe }}
+
+
+ {{ icons.error | safe }}
+
+
+ {{ icons.info | safe }}
+
+
+ {{ icons.warning | safe }}
+
+
+
+
+
+
+
+
{% endif %}
{% endmacro %}
\ No newline at end of file
diff --git a/docs/_includes/partials/sidebar.njk b/docs/_includes/partials/sidebar.njk
index cc816db..5585216 100644
--- a/docs/_includes/partials/sidebar.njk
+++ b/docs/_includes/partials/sidebar.njk
@@ -31,7 +31,7 @@
Basecoat
diff --git a/docs/components/toast.njk b/docs/components/toast.njk
index 2fa55c0..555be81 100644
--- a/docs/components/toast.njk
+++ b/docs/components/toast.njk
@@ -5,10 +5,32 @@ description: A succinct message that is displayed temporarily.
---
{% from "macros/code_preview.njk" import code_preview %}
-{% set code %}