@@ -8,23 +8,23 @@ List component with custom item rendering, headers, and reactive data binding.
## Props
| Prop | Type | Default | Description |
| :--- | :--- | :--- | : --- |
| `items` | `Array \| Signal<Array>` | `[]` | Data array to display |
| `header` | `string \| VNode \| Signal` | `-` | Optional header content |
| `render` | `function(item, index)` | Required | Custom render function for each item |
| `keyFn` | `function(item, index)` | `(item, idx) => idx` | Unique key function for items |
| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) |
| Prop | Type | Default | Description |
| :------- | :-------------------------- | :------------------- | :--------------------------------------- --- |
| `items` | `Array \| Signal<Array>` | `[]` | Data array to display |
| `header` | `string \| VNode \| Signal` | `-` | Optional header content |
| `render` | `function(item, index)` | Required | Custom render function for each item |
| `keyFn` | `function(item, index)` | `(item, idx) => idx` | Unique key function for items |
| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) |
## Styling
List supports all **daisyUI List classes ** :
| Category | Keywords | Description |
| :--- | :--- | : --- |
| Base | `list` | Base list styling |
| Variant | `list-row` | Row styling for list items |
| Background | `bg-base-100` | Background color |
| Category | Keywords | Description |
| :--------- | :------------ | :---------------------- --- |
| Base | `list` | Base list styling |
| Variant | `list-row` | Row styling for list items |
| Background | `bg-base-100` | Background color |
> For further details, check the [daisyUI List Documentation](https://daisyui.com/components/list) – Full reference for CSS classes.
@@ -41,16 +41,17 @@ List supports all **daisyUI List classes**:
``` javascript
const BasicDemo = ( ) => {
const items = [ ' Apple' , ' Banana' , ' Orange' , ' Grape' , ' Mango' ] ;
const items = [ " Apple" , " Banana" , " Orange" , " Grape" , " Mango" ] ;
return List ( {
items : items ,
render : ( item ) => Div ( { class : 'p-3 hover:bg-base-200 transition-colors' } , [
Span ( { class : 'font-medium' } , item )
] )
render : ( item ) =>
Div ( { class : "p-3 hover:bg-base-200 transition-colors" } , [
Span ( { class : "font-medium" } , item ) ,
] ) ,
} ) ;
} ;
$mount ( BasicDemo , ' #demo-basic' ) ;
$mount ( BasicDemo , " #demo-basic" ) ;
```
### With Header
@@ -65,22 +66,31 @@ $mount(BasicDemo, '#demo-basic');
``` javascript
const HeaderDemo = ( ) => {
const users = [
{ name : ' John Doe' , email : ' john@example.com' , status : ' active' } ,
{ name : ' Jane Smith' , email : ' jane@example.com' , status : ' inactive' } ,
{ name : ' Bob Johnson' , email : ' bob@example.com' , status : ' active' }
{ name : " John Doe" , email : " john@example.com" , status : " active" } ,
{ name : " Jane Smith" , email : " jane@example.com" , status : " inactive" } ,
{ name : " Bob Johnson" , email : " bob@example.com" , status : " active" } ,
] ;
return List ( {
items : users ,
header : Div ( { class : 'p-3 bg-primary/10 font-bold border-b border-base-300' } , 'Active Users' ) ,
render : ( user ) => Div ( { class : ' p-3 border-b border-base-300 hover:bg -base-2 00' } , [
Div ( { class : 'font-medium' } , user . name ) ,
Div ( { class : 'text-sm opacity-70' } , user . email ) ,
Span ( { class : ` badge badge-sm ${ user . status === 'active' ? 'badge-success' : 'badge-ghost' } mt-1 ` } , user . status )
] )
header : Div (
{ class : " p-3 bg-primary/10 font-bold border-b border -base-3 00" } ,
"Active Users" ,
) ,
render : ( user ) =>
Div ( { class : "p-3 border-b border-base-300 hover:bg-base-200" } , [
Div ( { class : "font-medium" } , user . name ) ,
Div ( { class : "text-sm opacity-70" } , user . email ) ,
Span (
{
class : ` badge badge-sm ${ user . status === "active" ? "badge-success" : "badge-ghost" } mt-1 ` ,
} ,
user . status ,
) ,
] ) ,
} ) ;
} ;
$mount ( HeaderDemo , ' #demo-header' ) ;
$mount ( HeaderDemo , " #demo-header" ) ;
```
### With Icons
@@ -95,25 +105,36 @@ $mount(HeaderDemo, '#demo-header');
``` javascript
const IconsDemo = ( ) => {
const settings = [
{ icon : '🔊' , label : 'Sound' , description : 'Adjust volume and notifications' } ,
{ icon : '🌙' , label : 'Display' , description : 'Brightness and dark mode' } ,
{ icon : '🔒' , label : 'Privacy' , description : 'Security settings' } ,
{ icon : '🌐' , label : 'Network' , description : 'WiFi and connections' }
{
icon : "🔊" ,
label : "Sound" ,
description : "Adjust volume and notifications" ,
} ,
{ icon : "🌙" , label : "Display" , description : "Brightness and dark mode" } ,
{ icon : "🔒" , label : "Privacy" , description : "Security settings" } ,
{ icon : "🌐" , label : "Network" , description : "WiFi and connections" } ,
] ;
return List ( {
items : settings ,
render : ( item ) => Div ( { class : 'flex gap-3 p-3 hover:bg-base-200 transition-colors cursor-pointer' } , [
Div ( { class : 'text-2xl' } , item . icon ) ,
Div ( { class : 'flex-1' } , [
Div ( { class : 'font-medium' } , item . label ) ,
Div ( { class : 'text-sm opacity-60' } , item . description )
] ) ,
Span ( { class : 'opacity-40' } , '→' )
] )
render : ( item ) =>
Div (
{
class :
"flex gap-3 p-3 hover:bg-base-200 transition-colors cursor-pointer" ,
} ,
[
Div ( { class : "text-2xl" } , item . icon ) ,
Div ( { class : "flex-1" } , [
Div ( { class : "font-medium" } , item . label ) ,
Div ( { class : "text-sm opacity-60" } , item . description ) ,
] ) ,
Span ( { class : "opacity-40" } , "→" ) ,
] ,
) ,
} ) ;
} ;
$mount ( IconsDemo , ' #demo-icons' ) ;
$mount ( IconsDemo , " #demo-icons" ) ;
```
### With Badges
@@ -128,24 +149,52 @@ $mount(IconsDemo, '#demo-icons');
``` javascript
const BadgesDemo = ( ) => {
const notifications = [
{ id : 1 , message : 'New comment on your post' , time : '5 min ago' , unread : true } ,
{ id : 2 , message : 'Your order has been shipped' , time : '1 hour ago' , unread : true } ,
{ id : 3 , message : 'Wel come to the platform!' , time : '2 days ago' , unread : false } ,
{ id : 4 , message : 'Weekly digest available' , time : '3 days ago' , unread : false }
{
id : 1 ,
message : "New comm ent on your post" ,
time : "5 min ago" ,
unread : true ,
} ,
{
id : 2 ,
message : "Your order has been shipped" ,
time : "1 hour ago" ,
unread : true ,
} ,
{
id : 3 ,
message : "Welcome to the platform!" ,
time : "2 days ago" ,
unread : false ,
} ,
{
id : 4 ,
message : "Weekly digest available" ,
time : "3 days ago" ,
unread : false ,
} ,
] ;
return List ( {
items : notifications ,
render : ( item ) => Div ( { class : ` flex justify-between items-center p-3 border-b border-base-300 hover:bg-base-200 ${ item . unread ? 'bg-primary/5' : '' } ` } , [
Div ( { class : 'flex-1' } , [
Div ( { class : 'font-medium' } , item . message ) ,
Div ( { class : 'text-xs opacity-50' } , item . time )
] ) ,
item . unread ? Span ( { class : 'badge badge-primary badge-sm' } , 'New' ) : null
] )
render : ( item ) =>
Div (
{
class : ` flex justify-between items-center p-3 border-b border-base-300 hover:bg-base-200 ${ item . unread ? "bg-primary/5" : "" } ` ,
} ,
[
Div ( { class : "flex-1" } , [
Div ( { class : "font-medium" } , item . message ) ,
Div ( { class : "text-xs opacity-50" } , item . time ) ,
] ) ,
item . unread
? Span ( { class : "badge badge-primary badge-sm" } , "New" )
: null ,
] ,
) ,
} ) ;
} ;
$mount ( BadgesDemo , ' #demo-badges' ) ;
$mount ( BadgesDemo , " #demo-badges" ) ;
```
### Interactive List
@@ -161,38 +210,49 @@ $mount(BadgesDemo, '#demo-badges');
const InteractiveDemo = ( ) => {
const selected = $ ( null ) ;
const items = [
{ id : 1 , name : ' Project Alpha' , status : ' In Progress' } ,
{ id : 2 , name : ' Project Beta' , status : ' Planning' } ,
{ id : 3 , name : ' Project Gamma' , status : ' Completed' } ,
{ id : 4 , name : ' Project Delta' , status : ' Review' }
{ id : 1 , name : " Project Alpha" , status : " In Progress" } ,
{ id : 2 , name : " Project Beta" , status : " Planning" } ,
{ id : 3 , name : " Project Gamma" , status : " Completed" } ,
{ id : 4 , name : " Project Delta" , status : " Review" } ,
] ;
const statusColors = {
' In Progress' : ' badge-warning' ,
' Planning' : ' badge-info' ,
' Completed' : ' badge-success' ,
' Review' : ' badge-accent'
" In Progress" : " badge-warning" ,
Planning: " badge-info" ,
Completed: " badge-success" ,
Review: " badge-accent" ,
} ;
return Div ( { class : ' flex flex-col gap-4' } , [
return Div ( { class : " flex flex-col gap-4" } , [
List ( {
items : items ,
render : ( item ) => Div ( {
class : ` p-3 cursor-pointer transition-all hover:bg-base-200 ${ selected ( ) === item . id ? 'bg-primary/10 border-l-4 border-primary' : 'border-l-4 border-transparent' } ` ,
onclick : ( ) => selected ( item . id )
} , [
Div ( { class : 'flex justify-between items-center' } , [
Div ( { class : 'font-medium' } , item . name ) ,
Span ( { class : ` badge ${ statusColors [ item . status ] } ` } , item . status )
] )
] )
render : ( item ) =>
Div (
{
class : ` p-3 cursor-pointer transition-all hover:bg-base-200 ${ selected ( ) === item . id ? "bg-primary/10 border-l-4 border-primary" : "border-l-4 border-transparent" } ` ,
onclick : ( ) => selected ( item . id ) ,
} ,
[
Div ( { class : "flex justify-between items-center" } , [
Div ( { class : "font-medium" } , item . name ) ,
Span (
{ class : ` badge ${ statusColors [ item . status ] } ` } ,
item . status ,
) ,
] ) ,
] ,
) ,
} ) ,
( ) => selected ( )
? Div ( { class : 'alert alert-info' } , ` Selected: ${ items . find ( i => i . id === selected ( ) ) . name } ` )
: Div ( { class : 'alert alert-soft' } , 'Select a project to see details' )
( ) =>
selected ( )
? Div (
{ class : "alert alert-info" } ,
` Selected: ${ items . find ( ( i ) => i . id === selected ( ) ) . name } ` ,
)
: Div ( { class : "alert alert-soft" } , "Select a project to see details" ) ,
] ) ;
} ;
$mount ( InteractiveDemo , ' #demo-interactive' ) ;
$mount ( InteractiveDemo , " #demo-interactive" ) ;
```
### Reactive List (Todo App)
@@ -223,9 +283,7 @@ const ReactiveDemo = () => {
} ;
const toggleTodo = ( id ) => {
todos ( todos ( ) . map ( t =>
t . id === id ? { ... t , done : ! t . done } : t
) ) ;
todos ( todos ( ) . map ( t => t . id === id ? { ... t , done : ! t . done } : t ) ) ;
} ;
const deleteTodo = ( id ) => {
@@ -233,13 +291,12 @@ const ReactiveDemo = () => {
} ;
const pendingCount = ( ) => todos ( ) . filter ( t => ! t . done ) . length ;
$watch ( ( ) => console . log ( pendingCount ( ) ) ) ;
return Div ( { class : 'flex flex-col gap-4' } , [
Div ( { class : 'flex gap-2' } , [
Input ( {
placeholder : 'Add new task...' ,
value : newTodo ,
class : 'flex-1' ,
oninput : ( e ) => newTodo ( e . target . value ) ,
onkeypress : ( e ) => e . key === 'Enter' && addTodo ( )
} ) ,
@@ -247,24 +304,32 @@ const ReactiveDemo = () => {
] ) ,
List ( {
items : todos ,
render : ( todo ) => Div ( { class : ` flex items-center gap-3 p-2 border-b border-base-300 hover:bg-base-200 ${ todo . done ? 'opacity-60' : '' } ` } , [
Checkbox ( {
value : todo . done ,
onclick : ( ) => toggleTodo ( todo . id )
} ) ,
Span ( {
class : ` flex-1 ${ todo . done ? 'line-through' : '' } ` ,
onclick : ( ) => toggleTodo ( todo . id )
} , todo . text ) ,
Button ( {
class : 'btn btn-ghost btn-xs btn-circle' ,
onclick : ( ) => deleteTodo ( todo . id )
} , '✕' )
] )
render : ( item ) => {
// Esta función busca siempre el estado actual del item dentro del signal
const it = ( ) => todos ( ) . find ( t => t . id === item . id ) || item ;
return Div ( {
class : ( ) => ` flex items-center gap-3 p-2 border-b border-base-300 ${ it ( ) . done ? 'opacity-60' : '' } `
} , [
Checkbox ( {
value : ( ) => it ( ) . done ,
onclick : ( ) => toggleTodo ( item . id )
} ) ,
Span ( {
class : ( ) => ` flex-1 ${ it ( ) . done ? 'line-through' : '' } ` ,
onclick : ( ) => toggleTodo ( item . id )
} , ( ) => it ( ) . text ) ,
Button ( {
class : 'btn btn-ghost btn-xs btn-circle' ,
onclick : ( ) => deleteTodo ( item . id )
} , '✕' )
] ) ;
}
} ) ,
Div ( { class : 'text-sm opacity-70 mt-2' } , ( ) => ` ${ pendingCount ( ) } tasks remaining ` )
] ) ;
} ;
$mount ( ReactiveDemo , '#demo-reactive' ) ;
```
@@ -280,27 +345,45 @@ $mount(ReactiveDemo, '#demo-reactive');
``` javascript
const AvatarDemo = ( ) => {
const contacts = [
{ name : ' Alice Johnson' , role : ' Developer' , avatar : 'A' , online : true } ,
{ name : ' Bob Smith' , role : ' Designer' , avatar : 'B' , online : false } ,
{ name : ' Charlie Brown' , role : ' Manager' , avatar : 'C' , online : true } ,
{ name : ' Diana Prince' , role : ' QA Engineer' , avatar : 'D' , online : false }
{ name : " Alice Johnson" , role : " Developer" , avatar : "A" , online : true } ,
{ name : " Bob Smith" , role : " Designer" , avatar : "B" , online : false } ,
{ name : " Charlie Brown" , role : " Manager" , avatar : "C" , online : true } ,
{ name : " Diana Prince" , role : " QA Engineer" , avatar : "D" , online : false } ,
] ;
return List ( {
items : contacts ,
render : ( contact ) => Div ( { class : 'flex gap-3 p-3 hover:bg-base-200 transition-colors' } , [
Div ( { class : ` avatar ${ contact . online ? 'online' : 'offline' } ` , style : 'width: 48px' } , [
Div ( { class : 'rounded-full bg-primary text-primary-content flex items-center justify-center w-12 h-12 font-bold' } , contact . avatar )
render : ( contact ) =>
Div ( { class : "flex gap-3 p-3 hover:bg-base-200 transition-colors" } , [
Div (
{
class : ` avatar ${ contact . online ? "online" : "offline" } ` ,
style : "width: 48px" ,
} ,
[
Div (
{
class :
"rounded-full bg-primary text-primary-content flex items-center justify-center w-12 h-12 font-bold" ,
} ,
contact . avatar ,
) ,
] ,
) ,
Div ( { class : "flex-1" } , [
Div ( { class : "font-medium" } , contact . name ) ,
Div ( { class : "text-sm opacity-60" } , contact . role ) ,
] ) ,
Div (
{
class : ` badge badge-sm ${ contact . online ? "badge-success" : "badge-ghost" } ` ,
} ,
contact . online ? "Online" : "Offline" ,
) ,
] ) ,
Div ( { class : 'flex-1' } , [
Div ( { class : 'font-medium' } , contact . name ) ,
Div ( { class : 'text-sm opacity-60' } , contact . role )
] ) ,
Div ( { class : ` badge badge-sm ${ contact . online ? 'badge-success' : 'badge-ghost' } ` } , contact . online ? 'Online' : 'Offline' )
] )
} ) ;
} ;
$mount ( AvatarDemo , ' #demo-avatar' ) ;
$mount ( AvatarDemo , " #demo-avatar" ) ;
```
### All Variants
@@ -314,29 +397,29 @@ $mount(AvatarDemo, '#demo-avatar');
``` javascript
const VariantsDemo = ( ) => {
const items = [ ' Item 1' , ' Item 2' , ' Item 3' ] ;
return Div ( { class : ' flex flex-col gap-6' } , [
Div ( { class : ' text-sm font-bold' } , ' Default List' ) ,
const items = [ " Item 1" , " Item 2" , " Item 3" ] ;
return Div ( { class : " flex flex-col gap-6" } , [
Div ( { class : " text-sm font-bold" } , " Default List" ) ,
List ( {
items : items ,
render : ( item ) => Div ( { class : ' p-2' } , item )
render : ( item ) => Div ( { class : " p-2" } , item ) ,
} ) ,
Div ( { class : ' text-sm font-bold mt-2' } , ' With Shadow' ) ,
Div ( { class : " text-sm font-bold mt-2" } , " With Shadow" ) ,
List ( {
items : items ,
render : ( item ) => Div ( { class : ' p-2' } , item ) ,
class : ' shadow-lg'
render : ( item ) => Div ( { class : " p-2" } , item ) ,
class : " shadow-lg" ,
} ) ,
Div ( { class : ' text-sm font-bold mt-2' } , ' Rounded Corners' ) ,
Div ( { class : " text-sm font-bold mt-2" } , " Rounded Corners" ) ,
List ( {
items : items ,
render : ( item ) => Div ( { class : ' p-2' } , item ) ,
class : ' rounded-box overflow-hidden'
} )
render : ( item ) => Div ( { class : " p-2" } , item ) ,
class : " rounded-box overflow-hidden" ,
} ) ,
] ) ;
} ;
$mount ( VariantsDemo , ' #demo-variants' ) ;
```
$mount ( VariantsDemo , " #demo-variants" ) ;
```