wip: ui components
This commit is contained in:
parent
30be5bb82e
commit
4cf5175548
13 changed files with 1314 additions and 0 deletions
11
bootstrap/app/handlers/showcase.go
Normal file
11
bootstrap/app/handlers/showcase.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"AABBCCDD/app/views/showcase"
|
||||
|
||||
"github.com/anthdm/superkit/kit"
|
||||
)
|
||||
|
||||
func HandleShowcaseIndex(kit *kit.Kit) error {
|
||||
return kit.Render(showcase.Index())
|
||||
}
|
157
bootstrap/app/views/showcase/index.templ
Normal file
157
bootstrap/app/views/showcase/index.templ
Normal file
|
@ -0,0 +1,157 @@
|
|||
package showcase
|
||||
|
||||
import (
|
||||
"AABBCCDD/app/views/layouts"
|
||||
"AABBCCDD/ui/button"
|
||||
"AABBCCDD/ui/input"
|
||||
"AABBCCDD/ui/modal"
|
||||
"AABBCCDD/ui/card"
|
||||
"AABBCCDD/ui"
|
||||
"AABBCCDD/ui/table"
|
||||
)
|
||||
|
||||
templ Index() {
|
||||
@layouts.App() {
|
||||
<div class="flex flex-col gap-10 mt-10 py-8">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold">Buttons</h1>
|
||||
<div class="border-b pt-2 mb-6"></div>
|
||||
<div class="flex gap-4">
|
||||
<button { button.Primary()... }>primary</button>
|
||||
<button { button.Outline()... }>outline</button>
|
||||
<button { button.Secondary()... }>secondary</button>
|
||||
<button { button.Destructive()... }>destructive</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold">Forms</h1>
|
||||
<div class="border-b pt-2 mb-6"></div>
|
||||
<form class="flex flex-col gap-4 w-full max-w-xs">
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="text-sm">Email</label>
|
||||
<input name="email" type="email" placeholder="enter your email" { input.Input()... }/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="text-sm">First Name</label>
|
||||
<input name="firstName" type="text" placeholder="first name" { input.Input()... }/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="text-sm">Last Name</label>
|
||||
<input name="lastName" type="text" placeholder="last name" { input.Input()... }/>
|
||||
</div>
|
||||
<button type="button" { button.Primary(ui.Class("w-fit"))... }>submit</button>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold">Card</h1>
|
||||
<div class="border-b pt-2 mb-6"></div>
|
||||
@card.Card(ui.Class("max-w-md")) {
|
||||
@card.Header() {
|
||||
<h1 class="text-xl">User registration</h1>
|
||||
<h2 class="text-muted-foreground">Please register to get the latest updates</h2>
|
||||
}
|
||||
@card.Content() {
|
||||
<form class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-1">
|
||||
<label class="text-sm">Username</label>
|
||||
<input { input.Input()... }/>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<label class="text-sm">Email</label>
|
||||
<input { input.Input()... }/>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
@card.Footer() {
|
||||
<button { button.Primary()... }>Submit</button>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold">Table</h1>
|
||||
<div class="border-b pt-2 mb-6"></div>
|
||||
<div class="max-w-4xl">
|
||||
@table.Table() {
|
||||
@table.Header(ui.Class("text-left")) {
|
||||
<th { table.Th()... }>
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-id" type="checkbox" class="w-4 h-4 bg-transparent border-input rounded"/>
|
||||
</div>
|
||||
</th>
|
||||
<th { table.Th()... }>id</th>
|
||||
<th { table.Th()... }>email</th>
|
||||
<th { table.Th()... }>first name</th>
|
||||
<th { table.Th()... }>last name</th>
|
||||
<th { table.Th(ui.Class("text-right"))... }>action</th>
|
||||
}
|
||||
@table.Body() {
|
||||
<tr>
|
||||
<td { table.Td()... }>
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-id" type="checkbox" class="w-4 h-4 bg-transparent border-input rounded"/>
|
||||
</div>
|
||||
</td>
|
||||
<td { table.Td()... }>1</td>
|
||||
<td { table.Td()... }>foo@foo.com</td>
|
||||
<td { table.Td()... }>Anthony</td>
|
||||
<td { table.Td()... }>GG</td>
|
||||
<td { table.Td(ui.Class("text-right text-blue-500"))... }>view</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td { table.Td()... }>
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-id" type="checkbox" class="w-4 h-4 bg-transparent border-input rounded"/>
|
||||
</div>
|
||||
</td>
|
||||
<td { table.Td()... }>1</td>
|
||||
<td { table.Td()... }>foo@foo.com</td>
|
||||
<td { table.Td()... }>Anthony</td>
|
||||
<td { table.Td()... }>GG</td>
|
||||
<td { table.Td(ui.Class("text-right text-blue-500"))... }>view</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td { table.Td()... }>
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-id" type="checkbox" class="w-4 h-4 bg-transparent border-input rounded"/>
|
||||
</div>
|
||||
</td>
|
||||
<td { table.Td()... }>1</td>
|
||||
<td { table.Td()... }>foo@foo.com</td>
|
||||
<td { table.Td()... }>Anthony</td>
|
||||
<td { table.Td()... }>GG</td>
|
||||
<td { table.Td(ui.Class("text-right text-blue-500"))... }>view</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td { table.Td()... }>
|
||||
<div class="flex items-center">
|
||||
<input id="checkbox-id" type="checkbox" class="w-4 h-4 bg-transparent border-input rounded"/>
|
||||
</div>
|
||||
</td>
|
||||
<td { table.Td()... }>1</td>
|
||||
<td { table.Td()... }>foo@foo.com</td>
|
||||
<td { table.Td()... }>Anthony</td>
|
||||
<td { table.Td()... }>GG</td>
|
||||
<td { table.Td(ui.Class("text-right text-blue-500"))... }>view</td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold">Modal</h1>
|
||||
<div class="border-b pt-2 mb-6"></div>
|
||||
@modal.Modal() {
|
||||
@modal.Header() {
|
||||
the header
|
||||
}
|
||||
@modal.Content() {
|
||||
the content
|
||||
}
|
||||
@modal.Trigger() {
|
||||
<div class="text-white">trigger me</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
|
@ -629,23 +629,63 @@ body {
|
|||
position: fixed;
|
||||
}
|
||||
|
||||
.absolute {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.relative {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.inset-0 {
|
||||
inset: 0px;
|
||||
}
|
||||
|
||||
.left-0 {
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.right-0 {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.right-6 {
|
||||
right: 1.5rem;
|
||||
}
|
||||
|
||||
.top-0 {
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.top-6 {
|
||||
top: 1.5rem;
|
||||
}
|
||||
|
||||
.z-50 {
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.z-\[99\] {
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.mx-auto {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.mb-6 {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.ml-4 {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.mr-5 {
|
||||
margin-right: 1.25rem;
|
||||
}
|
||||
|
||||
.mt-10 {
|
||||
margin-top: 2.5rem;
|
||||
}
|
||||
|
@ -654,6 +694,14 @@ body {
|
|||
margin-top: 8rem;
|
||||
}
|
||||
|
||||
.mt-5 {
|
||||
margin-top: 1.25rem;
|
||||
}
|
||||
|
||||
.mt-8 {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
@ -666,14 +714,58 @@ body {
|
|||
display: inline-flex;
|
||||
}
|
||||
|
||||
.table {
|
||||
display: table;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.h-10 {
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.h-4 {
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.h-5 {
|
||||
height: 1.25rem;
|
||||
}
|
||||
|
||||
.h-8 {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.h-auto {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.h-full {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.h-screen {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.w-4 {
|
||||
width: 1rem;
|
||||
}
|
||||
|
||||
.w-5 {
|
||||
width: 1.25rem;
|
||||
}
|
||||
|
||||
.w-8 {
|
||||
width: 2rem;
|
||||
}
|
||||
|
||||
.w-auto {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.w-fit {
|
||||
width: -moz-fit-content;
|
||||
width: fit-content;
|
||||
|
@ -683,10 +775,22 @@ body {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.w-screen {
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.min-w-full {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.max-w-2xl {
|
||||
max-width: 42rem;
|
||||
}
|
||||
|
||||
.max-w-4xl {
|
||||
max-width: 56rem;
|
||||
}
|
||||
|
||||
.max-w-7xl {
|
||||
max-width: 80rem;
|
||||
}
|
||||
|
@ -699,6 +803,20 @@ body {
|
|||
max-width: 24rem;
|
||||
}
|
||||
|
||||
.max-w-xs {
|
||||
max-width: 20rem;
|
||||
}
|
||||
|
||||
.translate-y-0 {
|
||||
--tw-translate-y: 0px;
|
||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||
}
|
||||
|
||||
.translate-y-4 {
|
||||
--tw-translate-y: 1rem;
|
||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||
}
|
||||
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -755,6 +873,36 @@ body {
|
|||
gap: 2rem;
|
||||
}
|
||||
|
||||
.divide-y > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-divide-y-reverse: 0;
|
||||
border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
|
||||
border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
|
||||
}
|
||||
|
||||
.overflow-hidden {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.overflow-x-auto {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.whitespace-nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.rounded {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.rounded-full {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.rounded-lg {
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
.rounded-md {
|
||||
border-radius: calc(var(--radius) - 2px);
|
||||
}
|
||||
|
@ -772,20 +920,49 @@ body {
|
|||
border-color: hsl(var(--input) / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: hsl(var(--primary) / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-red-500 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(239 68 68 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.bg-black {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-card {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--card) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-destructive {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--destructive) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-primary {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--primary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-secondary {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--secondary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-transparent {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.bg-opacity-40 {
|
||||
--tw-bg-opacity: 0.4;
|
||||
}
|
||||
|
||||
.bg-gradient-to-r {
|
||||
background-image: linear-gradient(to right, var(--tw-gradient-stops));
|
||||
}
|
||||
|
@ -810,6 +987,10 @@ body {
|
|||
background-clip: text;
|
||||
}
|
||||
|
||||
.p-6 {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.px-3 {
|
||||
padding-left: 0.75rem;
|
||||
padding-right: 0.75rem;
|
||||
|
@ -820,16 +1001,31 @@ body {
|
|||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
.px-5 {
|
||||
padding-left: 1.25rem;
|
||||
padding-right: 1.25rem;
|
||||
}
|
||||
|
||||
.px-6 {
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
}
|
||||
|
||||
.px-7 {
|
||||
padding-left: 1.75rem;
|
||||
padding-right: 1.75rem;
|
||||
}
|
||||
|
||||
.px-8 {
|
||||
padding-left: 2rem;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
.py-1 {
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.py-12 {
|
||||
padding-top: 3rem;
|
||||
padding-bottom: 3rem;
|
||||
|
@ -845,10 +1041,45 @@ body {
|
|||
padding-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.py-4 {
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.py-6 {
|
||||
padding-top: 1.5rem;
|
||||
padding-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.py-8 {
|
||||
padding-top: 2rem;
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
.pb-2 {
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.pt-0 {
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
.pt-2 {
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
|
||||
.text-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.align-middle {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
@ -908,16 +1139,35 @@ body {
|
|||
letter-spacing: 0.025em;
|
||||
}
|
||||
|
||||
.text-blue-500 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(59 130 246 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-card-foreground {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--card-foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-foreground {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-foreground\/60 {
|
||||
color: hsl(var(--foreground) / 0.6);
|
||||
}
|
||||
|
||||
.text-muted-foreground {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--muted-foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--primary) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-primary-foreground {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--primary-foreground) / var(--tw-text-opacity));
|
||||
|
@ -932,16 +1182,33 @@ body {
|
|||
color: transparent;
|
||||
}
|
||||
|
||||
.text-white {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.underline {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
|
||||
.opacity-0 {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.opacity-100 {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.shadow-sm {
|
||||
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
.outline {
|
||||
outline-style: solid;
|
||||
}
|
||||
|
||||
.ring-offset-background {
|
||||
--tw-ring-offset-color: hsl(var(--background) / 1);
|
||||
}
|
||||
|
@ -956,12 +1223,51 @@ body {
|
|||
transition-duration: 200ms;
|
||||
}
|
||||
|
||||
.duration-300 {
|
||||
transition-duration: 300ms;
|
||||
}
|
||||
|
||||
.ease-in {
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
|
||||
}
|
||||
|
||||
.ease-out {
|
||||
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
/* fix for Alpine users. */
|
||||
|
||||
[x-cloak] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.file\:border-0::file-selector-button {
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.file\:bg-transparent::file-selector-button {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.file\:text-sm::file-selector-button {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
|
||||
.file\:font-medium::file-selector-button {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.placeholder\:text-muted-foreground::-moz-placeholder {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--muted-foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.placeholder\:text-muted-foreground::placeholder {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--muted-foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.placeholder\:text-neutral-500::-moz-placeholder {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(115 115 115 / var(--tw-text-opacity));
|
||||
|
@ -972,10 +1278,27 @@ body {
|
|||
color: rgb(115 115 115 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-destructive\/80:hover {
|
||||
background-color: hsl(var(--destructive) / 0.8);
|
||||
}
|
||||
|
||||
.hover\:bg-primary\/90:hover {
|
||||
background-color: hsl(var(--primary) / 0.9);
|
||||
}
|
||||
|
||||
.hover\:bg-secondary:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--secondary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-secondary\/80:hover {
|
||||
background-color: hsl(var(--secondary) / 0.8);
|
||||
}
|
||||
|
||||
.hover\:text-foreground\/80:hover {
|
||||
color: hsl(var(--foreground) / 0.8);
|
||||
}
|
||||
|
||||
.focus\:border-neutral-300:focus {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(212 212 212 / var(--tw-border-opacity));
|
||||
|
@ -997,6 +1320,22 @@ body {
|
|||
--tw-ring-color: hsl(var(--primary) / var(--tw-ring-opacity));
|
||||
}
|
||||
|
||||
.focus-visible\:outline-none:focus-visible {
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.focus-visible\:ring-1:focus-visible {
|
||||
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
||||
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||
}
|
||||
|
||||
.focus-visible\:ring-ring:focus-visible {
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: hsl(var(--ring) / var(--tw-ring-opacity));
|
||||
}
|
||||
|
||||
.disabled\:cursor-not-allowed:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
@ -1005,6 +1344,33 @@ body {
|
|||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.sm\:max-w-lg {
|
||||
max-width: 32rem;
|
||||
}
|
||||
|
||||
.sm\:translate-y-0 {
|
||||
--tw-translate-y: 0px;
|
||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||
}
|
||||
|
||||
.sm\:scale-100 {
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||
}
|
||||
|
||||
.sm\:scale-95 {
|
||||
--tw-scale-x: .95;
|
||||
--tw-scale-y: .95;
|
||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||
}
|
||||
|
||||
.sm\:rounded-lg {
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.lg\:mt-20 {
|
||||
margin-top: 5rem;
|
||||
|
|
20
go.sum
Normal file
20
go.sum
Normal file
|
@ -0,0 +1,20 @@
|
|||
github.com/a-h/templ v0.2.707 h1:T1Gkd2ugbRglZ9rYw/VBchWOSZVKmetDbBkm4YubM7U=
|
||||
github.com/a-h/templ v0.2.707/go.mod h1:5cqsugkq9IerRNucNsI4DEamdHPsoGMQy99DzydLhM8=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
||||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
||||
github.com/gorilla/sessions v1.3.0 h1:XYlkq7KcpOB2ZhHBPv5WpjMIxrQosiZanfoy1HLZFzg=
|
||||
github.com/gorilla/sessions v1.3.0/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
59
ui/button/button.go
Normal file
59
ui/button/button.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
package button
|
||||
|
||||
import (
|
||||
"AABBCCDD/ui"
|
||||
|
||||
"github.com/a-h/templ"
|
||||
)
|
||||
|
||||
const (
|
||||
buttonBaseClass = "inline-flex items-center justify-center px-4 py-2 font-medium text-sm tracking-wide transition-colors duration-200 rounded-md focus:ring focus:shadow-outline focus:outline-none"
|
||||
buttonVariantPrimary = "text-primary-foreground bg-primary focus:ring-primary hover:bg-primary/90"
|
||||
buttonVariantOutline = "text-primary border border-primary hover:bg-secondary focus:ring-primary"
|
||||
buttonVariantSecondary = "text-primary bg-secondary hover:bg-secondary/80"
|
||||
buttonVariantDestructive = "text-primary bg-destructive hover:bg-destructive/80"
|
||||
)
|
||||
|
||||
func New(opts ...func(*templ.Attributes)) templ.Attributes {
|
||||
return ui.CreateAttrs(buttonBaseClass, buttonVariantPrimary, opts...)
|
||||
}
|
||||
|
||||
func Outline(opts ...func(*templ.Attributes)) templ.Attributes {
|
||||
return appendVariant("outline", opts...)
|
||||
}
|
||||
|
||||
func Primary(opts ...func(*templ.Attributes)) templ.Attributes {
|
||||
return appendVariant("primary", opts...)
|
||||
}
|
||||
|
||||
func Secondary(opts ...func(*templ.Attributes)) templ.Attributes {
|
||||
return appendVariant("secondary", opts...)
|
||||
}
|
||||
|
||||
func Destructive(opts ...func(*templ.Attributes)) templ.Attributes {
|
||||
return appendVariant("destructive", opts...)
|
||||
}
|
||||
|
||||
func Variant(variant string) func(*templ.Attributes) {
|
||||
return func(attrs *templ.Attributes) {
|
||||
att := *attrs
|
||||
switch variant {
|
||||
case "primary":
|
||||
att["class"] = ui.Merge(buttonBaseClass, buttonVariantPrimary)
|
||||
case "outline":
|
||||
att["class"] = ui.Merge(buttonBaseClass, buttonVariantOutline)
|
||||
case "secondary":
|
||||
att["class"] = ui.Merge(buttonBaseClass, buttonVariantSecondary)
|
||||
case "destructive":
|
||||
att["class"] = ui.Merge(buttonBaseClass, buttonVariantDestructive)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func appendVariant(variant string, opts ...func(*templ.Attributes)) templ.Attributes {
|
||||
opt := []func(*templ.Attributes){
|
||||
Variant(variant),
|
||||
}
|
||||
opt = append(opt, opts...)
|
||||
return New(opt...)
|
||||
}
|
29
ui/card/card.templ
Normal file
29
ui/card/card.templ
Normal file
|
@ -0,0 +1,29 @@
|
|||
package card
|
||||
|
||||
import "AABBCCDD/ui"
|
||||
|
||||
const cardBaseClass = "rounded-lg border bg-card text-card-foreground shadow-sm"
|
||||
|
||||
templ Card(opts ...func(*templ.Attributes)) {
|
||||
<div { ui.CreateAttrs(cardBaseClass, "", opts...)... }>
|
||||
{ children... }
|
||||
</div>
|
||||
}
|
||||
|
||||
templ Header(opts ...func(*templ.Attributes)) {
|
||||
<div { ui.CreateAttrs("p-6", "", opts...)... }>
|
||||
{ children... }
|
||||
</div>
|
||||
}
|
||||
|
||||
templ Content(opts ...func(*templ.Attributes)) {
|
||||
<div { ui.CreateAttrs("p-6 pt-0", "", opts...)... }>
|
||||
{ children... }
|
||||
</div>
|
||||
}
|
||||
|
||||
templ Footer(opts ...func(*templ.Attributes)) {
|
||||
<div { ui.CreateAttrs("p-6 pt-0", "", opts...)... }>
|
||||
{ children... }
|
||||
</div>
|
||||
}
|
175
ui/card/card_templ.go
Normal file
175
ui/card/card_templ.go
Normal file
|
@ -0,0 +1,175 @@
|
|||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.707
|
||||
package card
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import "context"
|
||||
import "io"
|
||||
import "bytes"
|
||||
|
||||
import "AABBCCDD/ui"
|
||||
|
||||
const cardBaseClass = "rounded-lg border bg-card text-card-foreground shadow-sm"
|
||||
|
||||
func Card(opts ...func(*templ.Attributes)) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, ui.CreateAttrs(cardBaseClass, "", opts...))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func Header(opts ...func(*templ.Attributes)) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var2 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var2 == nil {
|
||||
templ_7745c5c3_Var2 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, ui.CreateAttrs("p-6", "", opts...))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var2.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func Content(opts ...func(*templ.Attributes)) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var3 == nil {
|
||||
templ_7745c5c3_Var3 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, ui.CreateAttrs("p-6 pt-0", "", opts...))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var3.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func Footer(opts ...func(*templ.Attributes)) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var4 == nil {
|
||||
templ_7745c5c3_Var4 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, ui.CreateAttrs("p-6 pt-0", "", opts...))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var4.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
13
ui/input/input.go
Normal file
13
ui/input/input.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package input
|
||||
|
||||
import (
|
||||
"github.com/a-h/templ"
|
||||
|
||||
"AABBCCDD/ui"
|
||||
)
|
||||
|
||||
const defaultInputClass = "flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
|
||||
|
||||
func Input(opts ...func(*templ.Attributes)) templ.Attributes {
|
||||
return ui.CreateAttrs(defaultInputClass, "", opts...)
|
||||
}
|
70
ui/modal/modal.templ
Normal file
70
ui/modal/modal.templ
Normal file
|
@ -0,0 +1,70 @@
|
|||
package modal
|
||||
|
||||
templ Modal() {
|
||||
<div
|
||||
x-data="{ modalOpen: false }"
|
||||
@keydown.escape.window="modalOpen = false"
|
||||
class="relative z-50 w-auto h-auto"
|
||||
>
|
||||
<div @click="modalOpen=true">
|
||||
foo
|
||||
</div>
|
||||
<template x-teleport="body">
|
||||
<div x-show="modalOpen" class="fixed top-0 left-0 z-[99] flex items-center justify-center w-screen h-screen" x-cloak>
|
||||
<div
|
||||
x-show="modalOpen"
|
||||
x-transition:enter="ease-out duration-300"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100"
|
||||
x-transition:leave="ease-in duration-300"
|
||||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
@click="modalOpen=false"
|
||||
class="absolute inset-0 w-full h-full bg-black bg-opacity-40"
|
||||
></div>
|
||||
<div
|
||||
x-show="modalOpen"
|
||||
x-trap.inert.noscroll="modalOpen"
|
||||
x-transition:enter="ease-out duration-300"
|
||||
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
|
||||
x-transition:leave="ease-in duration-200"
|
||||
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
||||
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
class="relative w-full py-6 px-7 sm:max-w-lg sm:rounded-lg"
|
||||
>
|
||||
{ children... }
|
||||
<div @click="modalOpen=true">
|
||||
foo
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ Header() {
|
||||
<div class="flex items-center justify-between pb-2">
|
||||
<h3 class="text-lg font-semibold">
|
||||
{ children... }
|
||||
</h3>
|
||||
<button @click="modalOpen=false" class="absolute top-0 right-0 flex items-center justify-center w-8 h-8 mt-5 mr-5 rounded-full">
|
||||
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ Content() {
|
||||
<div class="relative w-auto">
|
||||
{ children... }
|
||||
</div>
|
||||
}
|
||||
|
||||
templ Trigger() {
|
||||
<div @click="modalOpen=true">
|
||||
{ children... }
|
||||
</div>
|
||||
}
|
||||
|
||||
templ Footer() {
|
||||
}
|
159
ui/modal/modal_templ.go
Normal file
159
ui/modal/modal_templ.go
Normal file
|
@ -0,0 +1,159 @@
|
|||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.707
|
||||
package modal
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import "context"
|
||||
import "io"
|
||||
import "bytes"
|
||||
|
||||
func Modal() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div x-data=\"{ modalOpen: false }\" @keydown.escape.window=\"modalOpen = false\" class=\"relative z-50 w-auto h-auto\"><div @click=\"modalOpen=true\">foo</div><template x-teleport=\"body\"><div x-show=\"modalOpen\" class=\"fixed top-0 left-0 z-[99] flex items-center justify-center w-screen h-screen\" x-cloak><div x-show=\"modalOpen\" x-transition:enter=\"ease-out duration-300\" x-transition:enter-start=\"opacity-0\" x-transition:enter-end=\"opacity-100\" x-transition:leave=\"ease-in duration-300\" x-transition:leave-start=\"opacity-100\" x-transition:leave-end=\"opacity-0\" @click=\"modalOpen=false\" class=\"absolute inset-0 w-full h-full bg-black bg-opacity-40\"></div><div x-show=\"modalOpen\" x-trap.inert.noscroll=\"modalOpen\" x-transition:enter=\"ease-out duration-300\" x-transition:enter-start=\"opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95\" x-transition:enter-end=\"opacity-100 translate-y-0 sm:scale-100\" x-transition:leave=\"ease-in duration-200\" x-transition:leave-start=\"opacity-100 translate-y-0 sm:scale-100\" x-transition:leave-end=\"opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95\" class=\"relative w-full py-6 px-7 sm:max-w-lg sm:rounded-lg\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div @click=\"modalOpen=true\">foo</div></div></div></template></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func Header() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var2 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var2 == nil {
|
||||
templ_7745c5c3_Var2 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex items-center justify-between pb-2\"><h3 class=\"text-lg font-semibold\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var2.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h3><button @click=\"modalOpen=false\" class=\"absolute top-0 right-0 flex items-center justify-center w-8 h-8 mt-5 mr-5 rounded-full\"><svg class=\"w-5 h-5\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\"></path></svg></button></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func Content() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var3 == nil {
|
||||
templ_7745c5c3_Var3 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"relative w-auto\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var3.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func Trigger() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var4 == nil {
|
||||
templ_7745c5c3_Var4 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div @click=\"modalOpen=true\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var4.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func Footer() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var5 == nil {
|
||||
templ_7745c5c3_Var5 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
54
ui/table/table.templ
Normal file
54
ui/table/table.templ
Normal file
|
@ -0,0 +1,54 @@
|
|||
package table
|
||||
|
||||
import (
|
||||
"AABBCCDD/ui"
|
||||
)
|
||||
|
||||
templ Table() {
|
||||
<div class="flex flex-col border rounded-md">
|
||||
<div class="overflow-x-auto">
|
||||
<div class="inline-block min-w-full">
|
||||
<div class="overflow-hidden">
|
||||
<table class="min-w-full divide-y">
|
||||
{ children... }
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ Header(opts ...func(*templ.Attributes)) {
|
||||
<thead { ui.CreateAttrs("", "", opts...)... }>
|
||||
<tr>
|
||||
{ children... }
|
||||
</tr>
|
||||
</thead>
|
||||
}
|
||||
|
||||
templ Body(opts ...func(*templ.Attributes)) {
|
||||
<tbody { ui.CreateAttrs("divide-y", "", opts...)... }>
|
||||
{ children... }
|
||||
</tbody>
|
||||
}
|
||||
|
||||
templ Footer(opts ...func(*templ.Attributes)) {
|
||||
<tfoot>
|
||||
<tr>
|
||||
{ children... }
|
||||
</tr>
|
||||
</tfoot>
|
||||
}
|
||||
|
||||
const (
|
||||
thBaseClass = "px-5 py-3 text-xs font-medium uppercase"
|
||||
tdBaseClass = "px-5 py-4 text-sm whitespace-nowrap"
|
||||
)
|
||||
|
||||
func Td(opts ...func(*templ.Attributes)) templ.Attributes {
|
||||
return ui.CreateAttrs(tdBaseClass, "", opts...)
|
||||
}
|
||||
|
||||
func Th(opts ...func(*templ.Attributes)) templ.Attributes {
|
||||
return ui.CreateAttrs(thBaseClass, "", opts...)
|
||||
}
|
172
ui/table/table_templ.go
Normal file
172
ui/table/table_templ.go
Normal file
|
@ -0,0 +1,172 @@
|
|||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.707
|
||||
package table
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import "context"
|
||||
import "io"
|
||||
import "bytes"
|
||||
|
||||
import (
|
||||
"AABBCCDD/ui"
|
||||
)
|
||||
|
||||
func Table() templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex flex-col border rounded-md\"><div class=\"overflow-x-auto\"><div class=\"inline-block min-w-full\"><div class=\"overflow-hidden\"><table class=\"min-w-full divide-y\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</table></div></div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func Header(opts ...func(*templ.Attributes)) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var2 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var2 == nil {
|
||||
templ_7745c5c3_Var2 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<thead")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, ui.CreateAttrs("", "", opts...))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("><tr>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var2.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</tr></thead>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func Body(opts ...func(*templ.Attributes)) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var3 == nil {
|
||||
templ_7745c5c3_Var3 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<tbody")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, ui.CreateAttrs("divide-y", "", opts...))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var3.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</tbody>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func Footer(opts ...func(*templ.Attributes)) templ.Component {
|
||||
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var4 == nil {
|
||||
templ_7745c5c3_Var4 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<tfoot><tr>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var4.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</tr></tfoot>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
thBaseClass = "px-5 py-3 text-xs font-medium uppercase"
|
||||
tdBaseClass = "px-5 py-4 text-sm whitespace-nowrap"
|
||||
)
|
||||
|
||||
func Td(opts ...func(*templ.Attributes)) templ.Attributes {
|
||||
return ui.CreateAttrs(tdBaseClass, "", opts...)
|
||||
}
|
||||
|
||||
func Th(opts ...func(*templ.Attributes)) templ.Attributes {
|
||||
return ui.CreateAttrs(thBaseClass, "", opts...)
|
||||
}
|
29
ui/ui.go
Normal file
29
ui/ui.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/a-h/templ"
|
||||
)
|
||||
|
||||
func CreateAttrs(baseClass string, defaultClass string, opts ...func(*templ.Attributes)) templ.Attributes {
|
||||
attrs := templ.Attributes{
|
||||
"class": baseClass + " " + defaultClass,
|
||||
}
|
||||
for _, o := range opts {
|
||||
o(&attrs)
|
||||
}
|
||||
return attrs
|
||||
}
|
||||
|
||||
func Merge(a, b string) string {
|
||||
return fmt.Sprintf("%s %s", a, b)
|
||||
}
|
||||
|
||||
func Class(class string) func(*templ.Attributes) {
|
||||
return func(attrs *templ.Attributes) {
|
||||
attr := *attrs
|
||||
class := attr["class"].(string) + " " + class
|
||||
attr["class"] = class
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue