Complete 1 fase docs components
This commit is contained in:
688
docs/components/fab.md
Normal file
688
docs/components/fab.md
Normal file
@@ -0,0 +1,688 @@
|
||||
# Fab
|
||||
|
||||
Floating Action Button (FAB) component for primary actions with expandable menu options. Each example uses a container with `position: relative` and explicit height to position the FAB correctly.
|
||||
|
||||
## Tag
|
||||
|
||||
`Fab`
|
||||
|
||||
## Props
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| :----------- | :-------------------------------------- | :--------------- | :----------------------------------------------- |
|
||||
| `icon` | `string \| VNode \| Signal` | `-` | Main FAB icon |
|
||||
| `label` | `string \| VNode \| Signal` | `-` | Text label for main button |
|
||||
| `actions` | `Array<Action> \| Signal<Array>` | `[]` | Array of action buttons that expand from FAB |
|
||||
| `position` | `string` | `'bottom-6 right-6'` | CSS position classes (e.g., 'bottom-6 left-6') |
|
||||
| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) |
|
||||
|
||||
### Action Structure
|
||||
|
||||
| Property | Type | Description |
|
||||
| :---------- | :--------------------------- | :----------------------------------------------- |
|
||||
| `label` | `string \| VNode` | Label text shown next to action button |
|
||||
| `icon` | `string \| VNode` | Icon for the action button |
|
||||
| `onclick` | `function` | Click handler |
|
||||
| `class` | `string` | Additional CSS classes for the action button |
|
||||
|
||||
## Live Examples
|
||||
|
||||
### Basic FAB
|
||||
|
||||
<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-basic" class="bg-base-100 p-6 rounded-xl border border-base-300 min-h-[300px] relative"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
const BasicDemo = () => {
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Fab({
|
||||
icon: '➕',
|
||||
actions: [
|
||||
{ icon: '📝', label: 'New Note', onclick: () => Toast('Create note', 'alert-info', 2000) },
|
||||
{ icon: '📷', label: 'Take Photo', onclick: () => Toast('Open camera', 'alert-info', 2000) },
|
||||
{ icon: '📎', label: 'Attach File', onclick: () => Toast('Attach file', 'alert-info', 2000) }
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(BasicDemo, '#demo-basic');
|
||||
```
|
||||
|
||||
### With Label
|
||||
|
||||
<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-label" class="bg-base-100 p-6 rounded-xl border border-base-300 min-h-[300px] relative"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
const LabelDemo = () => {
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Fab({
|
||||
label: 'Create',
|
||||
icon: '✨',
|
||||
actions: [
|
||||
{ icon: '📝', label: 'Document', onclick: () => Toast('New document', 'alert-success', 2000) },
|
||||
{ icon: '🎨', label: 'Design', onclick: () => Toast('New design', 'alert-success', 2000) },
|
||||
{ icon: '📊', label: 'Spreadsheet', onclick: () => Toast('New spreadsheet', 'alert-success', 2000) }
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(LabelDemo, '#demo-label');
|
||||
```
|
||||
|
||||
### Different Positions
|
||||
|
||||
<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-positions" class="bg-base-100 p-6 rounded-xl border border-base-300 min-h-[500px] relative"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
const PositionsDemo = () => {
|
||||
const position = $('bottom-6 right-6');
|
||||
|
||||
return Div({ class: 'relative h-[500px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Div({ class: 'absolute top-4 left-4 z-20 bg-base-200 p-2 rounded-lg shadow' }, [
|
||||
Select({
|
||||
value: position,
|
||||
options: [
|
||||
{ value: 'bottom-6 right-6', label: 'Bottom Right' },
|
||||
{ value: 'bottom-6 left-6', label: 'Bottom Left' },
|
||||
{ value: 'top-6 right-6', label: 'Top Right' },
|
||||
{ value: 'top-6 left-6', label: 'Top Left' }
|
||||
],
|
||||
onchange: (e) => position(e.target.value)
|
||||
})
|
||||
]),
|
||||
Div({ class: 'absolute inset-0 flex items-center justify-center text-sm opacity-50 pointer-events-none' }, [
|
||||
'FAB position changes relative to this container'
|
||||
]),
|
||||
Fab({
|
||||
position: () => position(),
|
||||
icon: '🧭',
|
||||
actions: [
|
||||
{ icon: '⬅️', label: 'Bottom Left', onclick: () => position('bottom-6 left-6') },
|
||||
{ icon: '➡️', label: 'Bottom Right', onclick: () => position('bottom-6 right-6') },
|
||||
{ icon: '⬆️', label: 'Top Right', onclick: () => position('top-6 right-6') },
|
||||
{ icon: '⬇️', label: 'Top Left', onclick: () => position('top-6 left-6') }
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(PositionsDemo, '#demo-positions');
|
||||
```
|
||||
|
||||
### Color Variants
|
||||
|
||||
<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-colors" class="bg-base-100 p-6 rounded-xl border border-base-300 min-h-[300px] relative"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
const ColorsDemo = () => {
|
||||
const variant = $('primary');
|
||||
|
||||
const variants = {
|
||||
primary: { class: 'btn-primary', icon: '🔵' },
|
||||
secondary: { class: 'btn-secondary', icon: '🟣' },
|
||||
accent: { class: 'btn-accent', icon: '🔴' },
|
||||
info: { class: 'btn-info', icon: '🔷' },
|
||||
success: { class: 'btn-success', icon: '🟢' },
|
||||
warning: { class: 'btn-warning', icon: '🟡' },
|
||||
error: { class: 'btn-error', icon: '🔴' }
|
||||
};
|
||||
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Div({ class: 'absolute top-4 left-4 z-20 bg-base-200 p-2 rounded-lg shadow' }, [
|
||||
Select({
|
||||
value: variant,
|
||||
options: Object.keys(variants).map(v => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) })),
|
||||
onchange: (e) => variant(e.target.value)
|
||||
})
|
||||
]),
|
||||
Fab({
|
||||
class: variants[variant()].class,
|
||||
icon: variants[variant()].icon,
|
||||
actions: [
|
||||
{ icon: '📝', label: 'Action 1', onclick: () => Toast('Action 1', 'alert-info', 2000) },
|
||||
{ icon: '🎨', label: 'Action 2', onclick: () => Toast('Action 2', 'alert-info', 2000) },
|
||||
{ icon: '⚙️', label: 'Action 3', onclick: () => Toast('Action 3', 'alert-info', 2000) }
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(ColorsDemo, '#demo-colors');
|
||||
```
|
||||
|
||||
### Reactive Actions
|
||||
|
||||
<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-reactive" class="bg-base-100 p-6 rounded-xl border border-base-300 min-h-[300px] relative"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
const ReactiveActions = () => {
|
||||
const count = $(0);
|
||||
|
||||
const actions = () => [
|
||||
{
|
||||
icon: '🔢',
|
||||
label: `Count: ${count()}`,
|
||||
onclick: () => {}
|
||||
},
|
||||
{
|
||||
icon: '➕',
|
||||
label: 'Increment',
|
||||
onclick: () => count(count() + 1)
|
||||
},
|
||||
{
|
||||
icon: '➖',
|
||||
label: 'Decrement',
|
||||
onclick: () => count(count() - 1)
|
||||
},
|
||||
{
|
||||
icon: '🔄',
|
||||
label: 'Reset',
|
||||
onclick: () => count(0)
|
||||
}
|
||||
];
|
||||
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Fab({
|
||||
icon: () => count() > 0 ? `🔢 ${count()}` : '🎛️',
|
||||
actions: actions
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(ReactiveActions, '#demo-reactive');
|
||||
```
|
||||
|
||||
### Document Actions
|
||||
|
||||
<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-document" class="bg-base-100 p-6 rounded-xl border border-base-300 min-h-[300px] relative"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
const DocumentActions = () => {
|
||||
const saved = $(false);
|
||||
|
||||
const handleSave = () => {
|
||||
saved(true);
|
||||
Toast('Document saved!', 'alert-success', 2000);
|
||||
setTimeout(() => saved(false), 3000);
|
||||
};
|
||||
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Div({ class: 'absolute inset-0 flex flex-col items-center justify-center' }, [
|
||||
Div({ class: 'text-6xl mb-4' }, '📄'),
|
||||
Div({ class: 'text-sm opacity-70' }, 'Untitled Document'),
|
||||
() => saved() ? Div({ class: 'mt-4' }, Alert({ type: 'success', message: '✓ Saved successfully' })) : null
|
||||
]),
|
||||
Fab({
|
||||
icon: '✏️',
|
||||
actions: [
|
||||
{ icon: '💾', label: 'Save', onclick: handleSave },
|
||||
{ icon: '📋', label: 'Copy', onclick: () => Toast('Copied!', 'alert-info', 2000) },
|
||||
{ icon: '✂️', label: 'Cut', onclick: () => Toast('Cut!', 'alert-info', 2000) },
|
||||
{ icon: '📎', label: 'Share', onclick: () => Toast('Share dialog', 'alert-info', 2000) }
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(DocumentActions, '#demo-document');
|
||||
```
|
||||
|
||||
### Messaging FAB
|
||||
|
||||
<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-messaging" class="bg-base-100 p-6 rounded-xl border border-base-300 min-h-[300px] relative"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
const MessagingFAB = () => {
|
||||
const unread = $(3);
|
||||
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Div({ class: 'absolute inset-0 flex flex-col items-center justify-center' }, [
|
||||
Div({ class: 'text-6xl mb-4' }, '💬'),
|
||||
Div({ class: 'text-sm opacity-70' }, 'Messages'),
|
||||
() => unread() > 0 ? Div({ class: 'badge badge-error mt-2' }, `${unread()} unread`) : null
|
||||
]),
|
||||
Fab({
|
||||
icon: () => `💬${unread() > 0 ? ` ${unread()}` : ''}`,
|
||||
class: 'btn-primary',
|
||||
actions: [
|
||||
{
|
||||
icon: '👤',
|
||||
label: 'New Message',
|
||||
onclick: () => Toast('Start new conversation', 'alert-info', 2000)
|
||||
},
|
||||
{
|
||||
icon: '👥',
|
||||
label: 'Group Chat',
|
||||
onclick: () => Toast('Create group', 'alert-info', 2000)
|
||||
},
|
||||
{
|
||||
icon: '📞',
|
||||
label: 'Voice Call',
|
||||
onclick: () => Toast('Start call', 'alert-info', 2000)
|
||||
},
|
||||
{
|
||||
icon: '📹',
|
||||
label: 'Video Call',
|
||||
onclick: () => Toast('Start video call', 'alert-info', 2000)
|
||||
},
|
||||
{
|
||||
icon: '🔔',
|
||||
label: () => `Mark as read (${unread()})`,
|
||||
onclick: () => {
|
||||
unread(0);
|
||||
Toast('All messages read', 'alert-success', 2000);
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(MessagingFAB, '#demo-messaging');
|
||||
```
|
||||
|
||||
### Flower Style FAB
|
||||
|
||||
<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-flower" class="bg-base-100 p-6 rounded-xl border border-base-300 min-h-[300px] relative"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
const FlowerDemo = () => {
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Div({ class: 'absolute inset-0 flex items-center justify-center text-sm opacity-50' }, [
|
||||
'Flower style FAB (quarter circle arrangement)'
|
||||
]),
|
||||
Fab({
|
||||
icon: '🌸',
|
||||
class: 'fab-flower',
|
||||
actions: [
|
||||
{ icon: '📷', label: 'Camera', onclick: () => Toast('Camera', 'alert-info', 2000) },
|
||||
{ icon: '🎨', label: 'Gallery', onclick: () => Toast('Gallery', 'alert-info', 2000) },
|
||||
{ icon: '🎤', label: 'Voice', onclick: () => Toast('Voice', 'alert-info', 2000) },
|
||||
{ icon: '📍', label: 'Location', onclick: () => Toast('Location', 'alert-info', 2000) }
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(FlowerDemo, '#demo-flower');
|
||||
```
|
||||
|
||||
### All Variants
|
||||
|
||||
<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-variants" class="bg-base-100 p-6 rounded-xl border border-base-300 min-h-[400px] relative"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
const VariantsDemo = () => {
|
||||
const actions = [
|
||||
{ icon: '⭐', label: 'Favorite', onclick: () => Toast('Favorited', 'alert-info', 2000) },
|
||||
{ icon: '🔔', label: 'Remind', onclick: () => Toast('Reminder set', 'alert-info', 2000) },
|
||||
{ icon: '📅', label: 'Schedule', onclick: () => Toast('Scheduled', 'alert-info', 2000) }
|
||||
];
|
||||
|
||||
return Div({ class: 'relative h-[400px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Div({ class: 'grid grid-cols-2 gap-4 p-4 h-full' }, [
|
||||
Div({ class: 'relative border rounded-lg bg-base-200' }, [
|
||||
Span({ class: 'absolute top-2 left-2 text-xs opacity-50' }, 'Primary'),
|
||||
Fab({ icon: '🔵', class: 'btn-primary', actions, position: 'bottom-6 left-6' })
|
||||
]),
|
||||
Div({ class: 'relative border rounded-lg bg-base-200' }, [
|
||||
Span({ class: 'absolute top-2 left-2 text-xs opacity-50' }, 'Secondary'),
|
||||
Fab({ icon: '🟣', class: 'btn-secondary', actions, position: 'bottom-6 right-6' })
|
||||
]),
|
||||
Div({ class: 'relative border rounded-lg bg-base-200' }, [
|
||||
Span({ class: 'absolute top-2 left-2 text-xs opacity-50' }, 'Accent'),
|
||||
Fab({ icon: '🔴', class: 'btn-accent', actions, position: 'top-6 left-6' })
|
||||
]),
|
||||
Div({ class: 'relative border rounded-lg bg-base-200' }, [
|
||||
Span({ class: 'absolute top-2 left-2 text-xs opacity-50' }, 'Success'),
|
||||
Fab({ icon: '🟢', class: 'btn-success', actions, position: 'top-6 right-6' })
|
||||
])
|
||||
])
|
||||
]);
|
||||
};
|
||||
$mount(VariantsDemo, '#demo-variants');
|
||||
```
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
const initFabExamples = () => {
|
||||
|
||||
// 1. Basic FAB
|
||||
const basicTarget = document.querySelector('#demo-basic');
|
||||
if (basicTarget && !basicTarget.hasChildNodes()) {
|
||||
const BasicDemo = () => {
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Fab({
|
||||
icon: '➕',
|
||||
actions: [
|
||||
{ icon: '📝', label: 'New Note', onclick: () => Toast('Create note', 'alert-info', 2000) },
|
||||
{ icon: '📷', label: 'Take Photo', onclick: () => Toast('Open camera', 'alert-info', 2000) },
|
||||
{ icon: '📎', label: 'Attach File', onclick: () => Toast('Attach file', 'alert-info', 2000) }
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(BasicDemo, basicTarget);
|
||||
}
|
||||
|
||||
// 2. With Label
|
||||
const labelTarget = document.querySelector('#demo-label');
|
||||
if (labelTarget && !labelTarget.hasChildNodes()) {
|
||||
const LabelDemo = () => {
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Fab({
|
||||
label: 'Create',
|
||||
icon: '✨',
|
||||
actions: [
|
||||
{ icon: '📝', label: 'Document', onclick: () => Toast('New document', 'alert-success', 2000) },
|
||||
{ icon: '🎨', label: 'Design', onclick: () => Toast('New design', 'alert-success', 2000) },
|
||||
{ icon: '📊', label: 'Spreadsheet', onclick: () => Toast('New spreadsheet', 'alert-success', 2000) }
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(LabelDemo, labelTarget);
|
||||
}
|
||||
|
||||
// 3. Different Positions
|
||||
const positionsTarget = document.querySelector('#demo-positions');
|
||||
if (positionsTarget && !positionsTarget.hasChildNodes()) {
|
||||
const PositionsDemo = () => {
|
||||
const position = $('bottom-6 right-6');
|
||||
|
||||
return Div({ class: 'relative h-[500px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Div({ class: 'absolute top-4 left-4 z-20 bg-base-200 p-2 rounded-lg shadow' }, [
|
||||
Select({
|
||||
value: position,
|
||||
options: [
|
||||
{ value: 'bottom-6 right-6', label: 'Bottom Right' },
|
||||
{ value: 'bottom-6 left-6', label: 'Bottom Left' },
|
||||
{ value: 'top-6 right-6', label: 'Top Right' },
|
||||
{ value: 'top-6 left-6', label: 'Top Left' }
|
||||
],
|
||||
onchange: (e) => position(e.target.value)
|
||||
})
|
||||
]),
|
||||
Div({ class: 'absolute inset-0 flex items-center justify-center text-sm opacity-50 pointer-events-none' }, [
|
||||
'FAB position changes relative to this container'
|
||||
]),
|
||||
Fab({
|
||||
position: () => position(),
|
||||
icon: '🧭',
|
||||
actions: [
|
||||
{ icon: '⬅️', label: 'Bottom Left', onclick: () => position('bottom-6 left-6') },
|
||||
{ icon: '➡️', label: 'Bottom Right', onclick: () => position('bottom-6 right-6') },
|
||||
{ icon: '⬆️', label: 'Top Right', onclick: () => position('top-6 right-6') },
|
||||
{ icon: '⬇️', label: 'Top Left', onclick: () => position('top-6 left-6') }
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(PositionsDemo, positionsTarget);
|
||||
}
|
||||
|
||||
// 4. Color Variants
|
||||
const colorsTarget = document.querySelector('#demo-colors');
|
||||
if (colorsTarget && !colorsTarget.hasChildNodes()) {
|
||||
const ColorsDemo = () => {
|
||||
const variant = $('primary');
|
||||
|
||||
const variants = {
|
||||
primary: { class: 'btn-primary', icon: '🔵' },
|
||||
secondary: { class: 'btn-secondary', icon: '🟣' },
|
||||
accent: { class: 'btn-accent', icon: '🔴' },
|
||||
info: { class: 'btn-info', icon: '🔷' },
|
||||
success: { class: 'btn-success', icon: '🟢' },
|
||||
warning: { class: 'btn-warning', icon: '🟡' },
|
||||
error: { class: 'btn-error', icon: '🔴' }
|
||||
};
|
||||
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Div({ class: 'absolute top-4 left-4 z-20 bg-base-200 p-2 rounded-lg shadow' }, [
|
||||
Select({
|
||||
value: variant,
|
||||
options: Object.keys(variants).map(v => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) })),
|
||||
onchange: (e) => variant(e.target.value)
|
||||
})
|
||||
]),
|
||||
Fab({
|
||||
class: variants[variant()].class,
|
||||
icon: variants[variant()].icon,
|
||||
actions: [
|
||||
{ icon: '📝', label: 'Action 1', onclick: () => Toast('Action 1', 'alert-info', 2000) },
|
||||
{ icon: '🎨', label: 'Action 2', onclick: () => Toast('Action 2', 'alert-info', 2000) },
|
||||
{ icon: '⚙️', label: 'Action 3', onclick: () => Toast('Action 3', 'alert-info', 2000) }
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(ColorsDemo, colorsTarget);
|
||||
}
|
||||
|
||||
// 5. Reactive Actions
|
||||
const reactiveTarget = document.querySelector('#demo-reactive');
|
||||
if (reactiveTarget && !reactiveTarget.hasChildNodes()) {
|
||||
const ReactiveActions = () => {
|
||||
const count = $(0);
|
||||
|
||||
const actions = () => [
|
||||
{
|
||||
icon: '🔢',
|
||||
label: `Count: ${count()}`,
|
||||
onclick: () => {}
|
||||
},
|
||||
{
|
||||
icon: '➕',
|
||||
label: 'Increment',
|
||||
onclick: () => count(count() + 1)
|
||||
},
|
||||
{
|
||||
icon: '➖',
|
||||
label: 'Decrement',
|
||||
onclick: () => count(count() - 1)
|
||||
},
|
||||
{
|
||||
icon: '🔄',
|
||||
label: 'Reset',
|
||||
onclick: () => count(0)
|
||||
}
|
||||
];
|
||||
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Fab({
|
||||
icon: () => count() > 0 ? `🔢 ${count()}` : '🎛️',
|
||||
actions: actions
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(ReactiveActions, reactiveTarget);
|
||||
}
|
||||
|
||||
// 6. Document Actions
|
||||
const documentTarget = document.querySelector('#demo-document');
|
||||
if (documentTarget && !documentTarget.hasChildNodes()) {
|
||||
const DocumentActions = () => {
|
||||
const saved = $(false);
|
||||
|
||||
const handleSave = () => {
|
||||
saved(true);
|
||||
Toast('Document saved!', 'alert-success', 2000);
|
||||
setTimeout(() => saved(false), 3000);
|
||||
};
|
||||
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Div({ class: 'absolute inset-0 flex flex-col items-center justify-center' }, [
|
||||
Div({ class: 'text-6xl mb-4' }, '📄'),
|
||||
Div({ class: 'text-sm opacity-70' }, 'Untitled Document'),
|
||||
() => saved() ? Div({ class: 'mt-4' }, Alert({ type: 'success', message: '✓ Saved successfully' })) : null
|
||||
]),
|
||||
Fab({
|
||||
icon: '✏️',
|
||||
actions: [
|
||||
{ icon: '💾', label: 'Save', onclick: handleSave },
|
||||
{ icon: '📋', label: 'Copy', onclick: () => Toast('Copied!', 'alert-info', 2000) },
|
||||
{ icon: '✂️', label: 'Cut', onclick: () => Toast('Cut!', 'alert-info', 2000) },
|
||||
{ icon: '📎', label: 'Share', onclick: () => Toast('Share dialog', 'alert-info', 2000) }
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(DocumentActions, documentTarget);
|
||||
}
|
||||
|
||||
// 7. Messaging FAB
|
||||
const messagingTarget = document.querySelector('#demo-messaging');
|
||||
if (messagingTarget && !messagingTarget.hasChildNodes()) {
|
||||
const MessagingFAB = () => {
|
||||
const unread = $(3);
|
||||
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Div({ class: 'absolute inset-0 flex flex-col items-center justify-center' }, [
|
||||
Div({ class: 'text-6xl mb-4' }, '💬'),
|
||||
Div({ class: 'text-sm opacity-70' }, 'Messages'),
|
||||
() => unread() > 0 ? Div({ class: 'badge badge-error mt-2' }, `${unread()} unread`) : null
|
||||
]),
|
||||
Fab({
|
||||
icon: () => `💬${unread() > 0 ? ` ${unread()}` : ''}`,
|
||||
class: 'btn-primary',
|
||||
actions: [
|
||||
{
|
||||
icon: '👤',
|
||||
label: 'New Message',
|
||||
onclick: () => Toast('Start new conversation', 'alert-info', 2000)
|
||||
},
|
||||
{
|
||||
icon: '👥',
|
||||
label: 'Group Chat',
|
||||
onclick: () => Toast('Create group', 'alert-info', 2000)
|
||||
},
|
||||
{
|
||||
icon: '📞',
|
||||
label: 'Voice Call',
|
||||
onclick: () => Toast('Start call', 'alert-info', 2000)
|
||||
},
|
||||
{
|
||||
icon: '📹',
|
||||
label: 'Video Call',
|
||||
onclick: () => Toast('Start video call', 'alert-info', 2000)
|
||||
},
|
||||
{
|
||||
icon: '🔔',
|
||||
label: () => `Mark as read (${unread()})`,
|
||||
onclick: () => {
|
||||
unread(0);
|
||||
Toast('All messages read', 'alert-success', 2000);
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(MessagingFAB, messagingTarget);
|
||||
}
|
||||
|
||||
// 8. Flower Style FAB
|
||||
const flowerTarget = document.querySelector('#demo-flower');
|
||||
if (flowerTarget && !flowerTarget.hasChildNodes()) {
|
||||
const FlowerDemo = () => {
|
||||
return Div({ class: 'relative h-[300px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Div({ class: 'absolute inset-0 flex items-center justify-center text-sm opacity-50' }, [
|
||||
'Flower style FAB (quarter circle arrangement)'
|
||||
]),
|
||||
Fab({
|
||||
icon: '🌸',
|
||||
class: 'fab-flower',
|
||||
actions: [
|
||||
{ icon: '📷', label: 'Camera', onclick: () => Toast('Camera', 'alert-info', 2000) },
|
||||
{ icon: '🎨', label: 'Gallery', onclick: () => Toast('Gallery', 'alert-info', 2000) },
|
||||
{ icon: '🎤', label: 'Voice', onclick: () => Toast('Voice', 'alert-info', 2000) },
|
||||
{ icon: '📍', label: 'Location', onclick: () => Toast('Location', 'alert-info', 2000) }
|
||||
]
|
||||
})
|
||||
]);
|
||||
};
|
||||
$mount(FlowerDemo, flowerTarget);
|
||||
}
|
||||
|
||||
// 9. All Variants
|
||||
const variantsTarget = document.querySelector('#demo-variants');
|
||||
if (variantsTarget && !variantsTarget.hasChildNodes()) {
|
||||
const VariantsDemo = () => {
|
||||
const actions = [
|
||||
{ icon: '⭐', label: 'Favorite', onclick: () => Toast('Favorited', 'alert-info', 2000) },
|
||||
{ icon: '🔔', label: 'Remind', onclick: () => Toast('Reminder set', 'alert-info', 2000) },
|
||||
{ icon: '📅', label: 'Schedule', onclick: () => Toast('Scheduled', 'alert-info', 2000) }
|
||||
];
|
||||
|
||||
return Div({ class: 'relative h-[400px] w-full bg-base-100 rounded-lg overflow-hidden' }, [
|
||||
Div({ class: 'grid grid-cols-2 gap-4 p-4 h-full' }, [
|
||||
Div({ class: 'relative border rounded-lg bg-base-200' }, [
|
||||
Span({ class: 'absolute top-2 left-2 text-xs opacity-50' }, 'Primary'),
|
||||
Fab({ icon: '🔵', class: 'btn-primary', actions, position: 'bottom-6 left-6' })
|
||||
]),
|
||||
Div({ class: 'relative border rounded-lg bg-base-200' }, [
|
||||
Span({ class: 'absolute top-2 left-2 text-xs opacity-50' }, 'Secondary'),
|
||||
Fab({ icon: '🟣', class: 'btn-secondary', actions, position: 'bottom-6 right-6' })
|
||||
]),
|
||||
Div({ class: 'relative border rounded-lg bg-base-200' }, [
|
||||
Span({ class: 'absolute top-2 left-2 text-xs opacity-50' }, 'Accent'),
|
||||
Fab({ icon: '🔴', class: 'btn-accent', actions, position: 'top-6 left-6' })
|
||||
]),
|
||||
Div({ class: 'relative border rounded-lg bg-base-200' }, [
|
||||
Span({ class: 'absolute top-2 left-2 text-xs opacity-50' }, 'Success'),
|
||||
Fab({ icon: '🟢', class: 'btn-success', actions, position: 'top-6 right-6' })
|
||||
])
|
||||
])
|
||||
]);
|
||||
};
|
||||
$mount(VariantsDemo, variantsTarget);
|
||||
}
|
||||
};
|
||||
|
||||
initFabExamples();
|
||||
|
||||
if (window.$docsify) {
|
||||
window.$docsify.plugins = [].concat(window.$docsify.plugins || [], (hook) => {
|
||||
hook.doneEach(initFabExamples);
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
Reference in New Issue
Block a user