Tabs Con pestañas cerrables

This commit is contained in:
2026-04-13 16:21:42 +02:00
parent 0697b4b4b7
commit 3c3938b354
12 changed files with 362 additions and 140 deletions

View File

@@ -275,7 +275,7 @@ const CartDrawer = () => {
Button({
class: 'btn btn-ghost btn-circle btn-sm',
onclick: () => isOpen(false)
}, '✕')
}, Span('✕'))
])
]),
Div({ class: 'flex-1 overflow-y-auto p-4' }, cart().length === 0
@@ -290,12 +290,12 @@ const CartDrawer = () => {
Button({
class: 'btn btn-xs btn-circle',
onclick: () => updateQuantity(item.id, -1)
}, '-'),
}, Span('-')),
Span({ class: 'w-8 text-center' }, item.quantity),
Button({
class: 'btn btn-xs btn-circle',
onclick: () => updateQuantity(item.id, 1)
}, '+')
}, Span('+'))
]),
Span({ class: 'font-bold w-16 text-right' }, `$${item.price * item.quantity}`)
])
@@ -313,7 +313,7 @@ const CartDrawer = () => {
Toast('Checkout initiated!', 'alert-success', 2000);
},
disabled: () => cart().length === 0
}, 'Checkout')
}, Span('Checkout'))
])
]),
content: Div({ class: 'p-4' }, [
@@ -322,7 +322,7 @@ const CartDrawer = () => {
Button({
class: 'btn btn-primary',
onclick: () => isOpen(true)
}, () => `🛒 Cart (${cart().length})`)
}, Span({ class: 'flex items-center gap-2' }, [Span('🛒'), Span(`Cart (${cart().length})`)]))
]),
Div({ class: 'mt-4 grid grid-cols-2 gap-4' }, [
Button({
@@ -331,7 +331,7 @@ const CartDrawer = () => {
cart([...cart(), { id: Date.now(), name: 'New Product', price: 39, quantity: 1 }]);
Toast('Added to cart!', 'alert-success', 1500);
}
}, ['📦', 'Add to Cart'])
}, Span({ class: 'flex flex-col items-center gap-1' }, [Span('📦'), Span('Add to Cart')]))
])
])
});

View File

@@ -416,4 +416,40 @@ const VariantsDemo = () => {
]);
};
Mount(VariantsDemo, '#demo-variants');
```
### Closable Tabs
<div class="card bg-base-200 border border-base-300 shadow-sm my-6"> <div class="card-body"> <h3 class="card-title text-sm uppercase opacity-50 mb-4">Live Demo</h3> <div id="demo-closable" class="bg-base-100 p-6 rounded-xl border border-base-300"></div> </div> </div>
```javascript
let nextTabId = 4;
const ClosableTabsDemo = () => {
const tabs = $([
{ label: 'Tab 1', content: Div('Content 1') }, // ❌ quita active: true
{ label: 'Tab 2', content: Div('Content 2'), closable: true },
{ label: 'Tab 3', content: Div('Content 3'), closable: true }
]);
// Opcional: si quieres que la primera pestaña esté activa al inicio,
// puedes hacerlo mediante una señal externa o simplemente confiar en que
// activeIndex empieza en 0 (que es el comportamiento por defecto).
const addTab = () => {
const newId = nextTabId++;
tabs([...tabs(), {
label: `Tab ${newId}`,
content: Div(`Content ${newId}`),
closable: true
}]);
};
return Div({ class: 'flex flex-col gap-4' }, [
Button({ class: 'btn btn-sm btn-outline mb-2', onclick: addTab }, 'Add Tab'),
Tabs({ items: tabs })
]);
};
Mount(ClosableTabsDemo, '#demo-closable');
```