Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/UI/@Templates/@layout.latte
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
</style>

<script src="https://cdn.tailwindcss.com"></script>
<script defer src="https://unpkg.com/@alpinejs/collapse@3.9.0/dist/cdn.min.js"></script>
<script defer src="https://unpkg.com/alpinejs@3.9.0/dist/cdn.min.js"></script>
</head>
<body>
Expand Down
37 changes: 37 additions & 0 deletions app/UI/@Widgets/accordion.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{default $sections = 0}
{default $exclusive = true}
{default $defaultOpen = 0}

{if $exclusive}
<div x-data="{ active: {$defaultOpen} }">
{for $i = 1; $i <= $sections; $i++}
<div class="border-b border-gray-200">
<button @click="active = active === {$i} ? 0 : {$i}"
class="w-full flex justify-between items-center py-3 px-4 text-left font-medium hover:bg-gray-50 focus:outline-none cursor-pointer"
:class="active === {$i} ? 'text-blue-600' : 'text-gray-700'">
<span>{block "header-$i"}{/block}</span>
<span class="transform transition-transform duration-200" :class="active === {$i} ? 'rotate-180' : ''">&#9660;</span>
</button>
<div x-show="active === {$i}" x-collapse x-cloak class="px-4 pb-4 text-gray-600">
{block "content-$i"}{/block}
</div>
</div>
{/for}
</div>
{else}
<div x-data="{ {for $i = 1; $i <= $sections; $i++}s{$i}: {$i === $defaultOpen ? 'true' : 'false'}{if $i < $sections}, {/if}{/for} }">
{for $i = 1; $i <= $sections; $i++}
<div class="border-b border-gray-200">
<button @click="s{$i} = !s{$i}"
class="w-full flex justify-between items-center py-3 px-4 text-left font-medium hover:bg-gray-50 focus:outline-none cursor-pointer"
:class="s{$i} ? 'text-blue-600' : 'text-gray-700'">
<span>{block "header-$i"}{/block}</span>
<span class="transform transition-transform duration-200" :class="s{$i} ? 'rotate-180' : ''">&#9660;</span>
</button>
<div x-show="s{$i}" x-collapse x-cloak class="px-4 pb-4 text-gray-600">
{block "content-$i"}{/block}
</div>
</div>
{/for}
</div>
{/if}
26 changes: 26 additions & 0 deletions app/UI/@Widgets/alert.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{default $type = 'info'}
{default $dismissible = true}

{var $colors = [
info => 'bg-blue-50 border-blue-400 text-blue-800',
success => 'bg-green-50 border-green-400 text-green-800',
warning => 'bg-yellow-50 border-yellow-400 text-yellow-800',
error => 'bg-red-50 border-red-400 text-red-800',
]}

<div x-data="{ visible: true }" x-show="visible"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
class="flex items-start border-l-4 p-4 rounded-md {$colors[$type] ?? $colors['info']}"
role="alert">
<div n:ifset="#icon" class="flex-shrink-0 mr-3">
{include #icon}
</div>
<div class="flex-1">
{include #content}
</div>
<button n:if="$dismissible" @click="visible = false" class="flex-shrink-0 ml-3 focus:outline-none cursor-pointer opacity-70 hover:opacity-100">
&#10005;
</button>
</div>
26 changes: 26 additions & 0 deletions app/UI/@Widgets/badge.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{default $type = 'default'}
{default $rounded = true}
{default $removable = false}
{default $dot = false}

{var $colors = [
default => 'bg-gray-100 text-gray-800',
primary => 'bg-blue-100 text-blue-800',
success => 'bg-green-100 text-green-800',
warning => 'bg-yellow-100 text-yellow-800',
danger => 'bg-red-100 text-red-800',
]}
{var $dotColors = [
default => 'bg-gray-500',
primary => 'bg-blue-500',
success => 'bg-green-500',
warning => 'bg-yellow-500',
danger => 'bg-red-500',
]}

<span x-data="{ visible: true }" x-show="visible"
class="inline-flex items-center px-2.5 py-0.5 text-xs font-medium {$colors[$type] ?? $colors['default']} {$rounded ? 'rounded-full' : 'rounded'}">
<span n:if="$dot" class="w-1.5 h-1.5 rounded-full mr-1.5 {$dotColors[$type] ?? $dotColors['default']}"></span>
{include #content}
<button n:if="$removable" @click="visible = false" class="ml-1 focus:outline-none hover:opacity-70 cursor-pointer">&#10005;</button>
</span>
26 changes: 26 additions & 0 deletions app/UI/@Widgets/card.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{default $hoverable = false}
{default $bordered = true}
{default $shadow = 'md'}

{var $shadows = [
none => '',
sm => 'shadow-sm',
md => 'shadow-md',
lg => 'shadow-lg',
]}

<div x-data="{}"
class="bg-white rounded-lg overflow-hidden {$bordered ? 'border border-gray-200' : ''} {$shadows[$shadow] ?? $shadows['md']} {$hoverable ? 'transition-shadow duration-200 hover:shadow-xl' : ''}">
<div n:ifset="#image" class="w-full">
{include #image}
</div>
<div n:ifset="#header" class="px-4 py-3 border-b border-gray-100 font-semibold text-gray-800">
{include #header}
</div>
<div class="px-4 py-4">
{include #content}
</div>
<div n:ifset="#footer" class="px-4 py-3 border-t border-gray-100 text-sm text-gray-500">
{include #footer}
</div>
</div>
52 changes: 52 additions & 0 deletions app/UI/@Widgets/drawer.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{default $side = 'right'}
{default $width = 'md'}

{var $widths = [
sm => 'w-64',
md => 'w-80',
lg => 'w-96',
xl => 'w-1/3',
]}
{var $slideStart = $side === 'left' ? '-translate-x-full' : 'translate-x-full'}

<div x-data="{ open: false }" @keydown.escape="open = false">
<div @click="open = true" class="cursor-pointer">
{include #trigger}
</div>

{* Backdrop *}
<div x-show="open" x-cloak
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
@click="open = false"
class="fixed inset-0 z-40 bg-black bg-opacity-50">
</div>

{* Drawer panel *}
<div x-show="open" x-cloak
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 {$slideStart}"
x-transition:enter-end="opacity-100 translate-x-0"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100 translate-x-0"
x-transition:leave-end="opacity-0 {$slideStart}"
class="fixed inset-y-0 {$side === 'left' ? 'left-0' : 'right-0'} z-50 {$widths[$width] ?? $widths['md']} bg-white shadow-xl flex flex-col">

<div n:ifset="#header" class="flex items-center justify-between px-4 py-3 border-b border-gray-200">
<div class="font-semibold text-lg">{include #header}</div>
<button @click="open = false" class="text-gray-400 hover:text-gray-600 focus:outline-none cursor-pointer">&#10005;</button>
</div>

<div class="flex-1 overflow-y-auto px-4 py-4">
{include #content}
</div>

<div n:ifset="#footer" class="px-4 py-3 border-t border-gray-200">
{include #footer}
</div>
</div>
</div>
37 changes: 37 additions & 0 deletions app/UI/@Widgets/popover.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{default $position = 'bottom'}
{default $width = 'md'}

{var $positionStyles = [
top => 'bottom-full left-1/2 -translate-x-1/2 mb-2',
bottom => 'top-full left-1/2 -translate-x-1/2 mt-2',
left => 'right-full top-1/2 -translate-y-1/2 mr-2',
right => 'left-full top-1/2 -translate-y-1/2 ml-2',
]}
{var $widths = [
sm => 'w-48',
md => 'w-64',
lg => 'w-80',
]}

<div x-data="{ open: false }" @keydown.escape="open = false" class="relative inline-block">
<div @click="open = !open" class="cursor-pointer">
{include #trigger}
</div>

<div x-show="open" x-cloak
@click.away="open = false"
x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0 scale-95"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-95"
class="absolute z-50 {$positionStyles[$position] ?? $positionStyles['bottom']} {$widths[$width] ?? $widths['md']} bg-white border border-gray-200 rounded-lg shadow-lg">
<div n:ifset="#title" class="px-4 py-2 border-b border-gray-100 font-semibold text-sm text-gray-700">
{include #title}
</div>
<div class="px-4 py-3 text-sm text-gray-600">
{include #content}
</div>
</div>
</div>
29 changes: 29 additions & 0 deletions app/UI/@Widgets/progress.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{default $value = 0}
{default $max = 100}
{default $type = 'primary'}
{default $showLabel = true}
{default $height = 'md'}

{var $barColors = [
primary => 'bg-blue-500',
success => 'bg-green-500',
warning => 'bg-yellow-500',
danger => 'bg-red-500',
]}
{var $heights = [
sm => 'h-1.5',
md => 'h-4',
lg => 'h-6',
]}

<div x-data="{ value: {$value}, max: {$max} }">
<div n:ifset="#label" class="flex justify-between mb-1 text-sm font-medium text-gray-700">
{include #label}
</div>
<div class="w-full bg-gray-200 rounded-full overflow-hidden {$heights[$height] ?? $heights['md']}">
<div class="{$barColors[$type] ?? $barColors['primary']} {$heights[$height] ?? $heights['md']} rounded-full transition-all duration-500 ease-out flex items-center justify-center"
:style="'width: ' + Math.min(100, Math.round(value / max * 100)) + '%'">
<span n:if="$showLabel && $height !== 'sm'" class="text-xs font-bold text-white" x-text="Math.min(100, Math.round(value / max * 100)) + '%'"></span>
</div>
</div>
</div>
29 changes: 29 additions & 0 deletions app/UI/@Widgets/stepper.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{default $steps = 0}
{default $current = 1}
{default $clickable = false}

<div x-data="{ current: {$current} }">
<div class="flex items-center">
{for $i = 1; $i <= $steps; $i++}
{* Step circle and label *}
<div class="flex flex-col items-center {$clickable ? 'cursor-pointer' : ''}"
{if $clickable}@click="current = {$i}"{/if}>
<div :class="current > {$i} ? 'bg-green-500 text-white' : current === {$i} ? 'bg-blue-500 text-white ring-4 ring-blue-200' : 'bg-gray-200 text-gray-500'"
class="w-8 h-8 rounded-full flex items-center justify-center text-sm font-bold transition-all duration-300">
<span x-show="current <= {$i}">{$i}</span>
<span x-show="current > {$i}" x-cloak>&#10003;</span>
</div>
<span class="mt-1 text-xs font-medium"
:class="current === {$i} ? 'text-blue-600' : 'text-gray-500'">
{block "step-$i"}{/block}
</span>
</div>
{* Connecting line *}
{if $i < $steps}
<div class="flex-1 h-0.5 mx-2 transition-colors duration-300"
:class="current > {$i} ? 'bg-green-500' : 'bg-gray-200'">
</div>
{/if}
{/for}
</div>
</div>
22 changes: 22 additions & 0 deletions app/UI/@Widgets/switch.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{default $checked = false}
{default $label = ''}
{default $name = ''}
{default $disabled = false}

<div x-data="{ on: {$checked ? 'true' : 'false'} }" class="flex items-center space-x-3">
<button type="button"
@click="{if !$disabled}on = !on{/if}"
:class="on ? 'bg-blue-500' : 'bg-gray-300'"
class="relative inline-flex h-6 w-11 items-center rounded-full transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-blue-300 {$disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}"
role="switch"
:aria-checked="on">
<span :class="on ? 'translate-x-6' : 'translate-x-1'"
class="inline-block h-4 w-4 transform rounded-full bg-white shadow transition-transform duration-200"></span>
</button>
<input n:if="$name" type="checkbox" :checked="on" name="{$name}" class="hidden">
<div>
<span n:ifset="#label" class="text-sm font-medium text-gray-700">{include #label}</span>
<span n:if="$label && !isset($__defined['label'])" class="text-sm font-medium text-gray-700">{$label}</span>
<p n:ifset="#description" class="text-xs text-gray-500">{include #description}</p>
</div>
</div>
35 changes: 35 additions & 0 deletions app/UI/@Widgets/toast.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{default $position = 'bottom-right'}
{default $duration = 3000}
{default $type = 'info'}

{var $positionClasses = [
'top-right' => 'top-4 right-4',
'top-left' => 'top-4 left-4',
'bottom-right' => 'bottom-4 right-4',
'bottom-left' => 'bottom-4 left-4',
]}
{var $colors = [
info => 'bg-blue-600 text-white',
success => 'bg-green-600 text-white',
warning => 'bg-yellow-500 text-white',
error => 'bg-red-600 text-white',
]}

<div x-data="{ visible: true }"
x-init="{if $duration > 0}setTimeout(() => visible = false, {$duration}){/if}"
x-show="visible"
x-cloak
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 translate-y-2"
x-transition:enter-end="opacity-100 translate-y-0"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0 translate-y-2"
class="fixed z-50 {$positionClasses[$position] ?? $positionClasses['bottom-right']} {$colors[$type] ?? $colors['info']} rounded-lg shadow-lg px-4 py-3 flex items-center space-x-3 max-w-sm">
<div class="flex-1">
{include #content}
</div>
<button @click="visible = false" class="flex-shrink-0 focus:outline-none opacity-70 hover:opacity-100 cursor-pointer">
&#10005;
</button>
</div>
10 changes: 10 additions & 0 deletions app/UI/Home/Templates/@codes/accordion1.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{embed "~accordion", sections: 3, exclusive: true, defaultOpen: 1}
{block header-1}What is Nette Framework?{/block}
{block content-1}Nette is a popular PHP framework for web development. It provides a robust set of tools for building modern, secure web applications.{/block}

{block header-2}What is Alpine.js?{/block}
{block content-2}Alpine.js is a lightweight JavaScript framework for composing behavior directly in your markup. It offers reactive and declarative nature of big frameworks at a much lower cost.{/block}

{block header-3}What is TailwindCSS?{/block}
{block content-3}TailwindCSS is a utility-first CSS framework that provides low-level utility classes to build custom designs without leaving your HTML.{/block}
{/embed}
23 changes: 23 additions & 0 deletions app/UI/Home/Templates/@codes/alert1.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{embed "~alert", type: 'success'}
{block content}
Your changes have been saved successfully.
{/block}
{/embed}

{embed "~alert", type: 'error'}
{block content}
Something went wrong. Please try again.
{/block}
{/embed}

{embed "~alert", type: 'warning', dismissible: false}
{block content}
Your trial expires in 3 days.
{/block}
{/embed}

{embed "~alert", type: 'info'}
{block content}
A new version is available.
{/block}
{/embed}
21 changes: 21 additions & 0 deletions app/UI/Home/Templates/@codes/badge1.latte
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<div class="flex flex-wrap gap-2">
{embed "~badge", type: 'success', dot: true}
{block content}Active{/block}
{/embed}

{embed "~badge", type: 'warning'}
{block content}Pending{/block}
{/embed}

{embed "~badge", type: 'danger', removable: true}
{block content}Urgent{/block}
{/embed}

{embed "~badge", type: 'primary'}
{block content}New{/block}
{/embed}

{embed "~badge", type: 'default', rounded: false}
{block content}Archived{/block}
{/embed}
</div>
Loading
Loading