1
0
mirror of https://github.com/axzilla/templui.git synced 2025-02-22 01:33:15 +00:00

refactor: clean up unused CSS classes and improve toast handler structure

This commit is contained in:
axzilla 2024-12-12 15:18:42 +07:00
parent 0bc679826c
commit b8612c352c
8 changed files with 272 additions and 348 deletions

View File

@ -788,10 +788,6 @@ body {
margin-left: 0.75rem; margin-left: 0.75rem;
} }
.ml-4 {
margin-left: 1rem;
}
.ml-auto { .ml-auto {
margin-left: auto; margin-left: auto;
} }
@ -1443,11 +1439,6 @@ body {
background-color: hsl(var(--destructive) / var(--tw-bg-opacity, 1)); background-color: hsl(var(--destructive) / var(--tw-bg-opacity, 1));
} }
.bg-gray-50 {
--tw-bg-opacity: 1;
background-color: rgb(249 250 251 / var(--tw-bg-opacity, 1));
}
.bg-gray-700 { .bg-gray-700 {
--tw-bg-opacity: 1; --tw-bg-opacity: 1;
background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1)); background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1));

View File

@ -13,21 +13,13 @@ import (
"github.com/axzilla/templui/pkg/components" "github.com/axzilla/templui/pkg/components"
) )
func HandleToastDemo(w http.ResponseWriter, r *http.Request) { func toastDemoHandler(w http.ResponseWriter, r *http.Request) {
duration, err := strconv.Atoi(r.FormValue("duration")) duration, err := strconv.Atoi(r.FormValue("duration"))
if err != nil { if err != nil {
duration = 0 duration = 0
} }
fmt.Println("duration", duration)
fmt.Println("r.FormValue(\"message\")", r.FormValue("message"))
fmt.Println("r.FormValue(\"type\")", r.FormValue("type"))
fmt.Println("r.FormValue(\"position\")", r.FormValue("position"))
fmt.Println("r.FormValue(\"theme\")", r.FormValue("theme"))
fmt.Println("r.FormValue(\"size\")", r.FormValue("size"))
fmt.Println("r.FormValue(\"dismissible\")", r.FormValue("dismissible"))
fmt.Println("r.FormValue(\"icon\")", r.FormValue("icon"))
cfg := components.ToastProps{ toastProps := components.ToastProps{
Message: r.FormValue("message"), Message: r.FormValue("message"),
Type: r.FormValue("type"), Type: r.FormValue("type"),
Position: r.FormValue("position"), Position: r.FormValue("position"),
@ -37,38 +29,7 @@ func HandleToastDemo(w http.ResponseWriter, r *http.Request) {
Icon: r.FormValue("icon") == "on", Icon: r.FormValue("icon") == "on",
} }
components.Toast(cfg).Render(r.Context(), w) components.Toast(toastProps).Render(r.Context(), w)
return
}
func HandleCreateUser(w http.ResponseWriter, r *http.Request) {
email := r.FormValue("email")
// Validierung
if email == "" {
// Error Toast
components.Toast(components.ToastProps{
Message: "Email ist erforderlich",
Type: "error",
Position: "top-left",
Duration: 1000,
Dismissible: true,
Size: "md",
Icon: true,
}).Render(r.Context(), w)
return
}
// Erfolg Toast
components.Toast(components.ToastProps{
Message: "Benutzer erstellt",
Type: "success",
Position: "bottom-right",
Duration: 3000,
Dismissible: false,
Size: "sm",
Icon: true,
}).Render(r.Context(), w)
} }
func main() { func main() {
@ -108,8 +69,7 @@ func main() {
mux.Handle("GET /docs/components/toast", templ.Handler(pages.Toast())) mux.Handle("GET /docs/components/toast", templ.Handler(pages.Toast()))
mux.Handle("GET /docs/components/toggle", templ.Handler(pages.Toggle())) mux.Handle("GET /docs/components/toggle", templ.Handler(pages.Toggle()))
// Showcase API // Showcase API
mux.Handle("POST /users", http.HandlerFunc(HandleCreateUser)) mux.Handle("POST /docs/toast/demo", http.HandlerFunc(toastDemoHandler))
mux.Handle("POST /docs/toast/demo", http.HandlerFunc(HandleToastDemo))
fmt.Println("Server is running on http://localhost:8090") fmt.Println("Server is running on http://localhost:8090")
http.ListenAndServe(":8090", wrappedMux) http.ListenAndServe(":8090", wrappedMux)

View File

@ -33,7 +33,6 @@ templ ExampleWrapper(p ExampleWrapperProps) {
</div> </div>
} }
// generateTabs erstellt die Tabs basierend auf den Props
func generateTabs(p ExampleWrapperProps) []components.Tab { func generateTabs(p ExampleWrapperProps) []components.Tab {
tabs := []components.Tab{ tabs := []components.Tab{
{ {
@ -50,7 +49,6 @@ func generateTabs(p ExampleWrapperProps) []components.Tab {
}, },
} }
// Füge Component Tab nur hinzu wenn gewünscht
if p.ComponentCodeFile != "" { if p.ComponentCodeFile != "" {
tabs = append(tabs, components.Tab{ tabs = append(tabs, components.Tab{
ID: "component", ID: "component",

View File

@ -1,27 +1,90 @@
package pages package pages
import ( import (
"fmt"
"github.com/axzilla/templui/internals/ui/layouts" "github.com/axzilla/templui/internals/ui/layouts"
"github.com/axzilla/templui/internals/ui/modules" "github.com/axzilla/templui/internals/ui/modules"
"github.com/axzilla/templui/internals/ui/showcase" "github.com/axzilla/templui/internals/ui/showcase"
"github.com/axzilla/templui/pkg/components"
) )
templ Toast() { templ Toast() {
@layouts.DocsLayout() { @layouts.DocsLayout() {
@modules.PageWrapper(modules.PageWrapperProps{ @modules.PageWrapper(modules.PageWrapperProps{
Name: "Toast", Name: "Toast",
Description: templ.Raw("Flexible Toast component for notifications and feedback."), Description: templ.Raw("Flexible toast component for notifications and feedback."),
}) { }) {
// @modules.ExampleWrapper(modules.ExampleWrapperProps{
// ShowcaseFile: showcase.Toast(),
// PreviewCodeFile: "toast.templ",
// ComponentCodeFile: "toast.templ",
// })
@modules.ExampleWrapper(modules.ExampleWrapperProps{ @modules.ExampleWrapper(modules.ExampleWrapperProps{
ShowcaseFile: showcase.ToastAdvanced(), ShowcaseFile: showcase.Toast(),
PreviewCodeFile: "toast_advancded.templ", PreviewCodeFile: "toast.templ",
ComponentCodeFile: "toast.templ", ComponentCodeFile: "toast.templ",
}) })
@UsageExamples()
} }
} }
} }
templ UsageExamples() {
@components.Tabs(components.TabsProps{
Tabs: []components.Tab{
{
ID: "with-htmx",
Title: "With HTMX",
Content: withHtmx(),
},
{
ID: "full-page-form",
Title: "Full Page Form",
Content: fullPageForm(),
},
},
TabsContainerClass: "w-full",
ContentContainerClass: "w-full",
})
}
var withHtmxCode = fmt.Sprintf(`// Template
%s UserForm() {
<form hx-post="/save" hx-target="#toast">
<input name="email" />
</form>
<div id="toast"></div>
}
// Handler
func Save(w http.ResponseWriter, r *http.Request) {
if err != nil {
components.Toast(components.ToastProps{
Message: err.Error(),
Type: "error",
}).Render(r.Context(), w)
}
}`, "templ")
templ withHtmx() {
@modules.CodeSnippet(withHtmxCode, "go")
}
var fullPageFormCode = fmt.Sprintf(`// Template
%s UserForm(error string) {
if error != "" {
@components.Toast(components.ToastProps{
Message: error,
Type: "error",
})
}
<form method="POST">
<input name="email"/>
</form>
}
// Handler
func Save(w http.ResponseWriter, r *http.Request) {
if err != nil {
UserForm(err.Error()).Render(r.Context(), w)
}
}`, "templ")
templ fullPageForm() {
@modules.CodeSnippet(string(fullPageFormCode), "go")
}

View File

@ -1,25 +1,104 @@
package showcase package showcase
import "github.com/axzilla/templui/pkg/components"
templ Toast() { templ Toast() {
<div class="flex flex-wrap gap-2"> <div class="w-full max-w-4xl mx-auto p-8">
<div> <section class="mb-12">
<form @components.Card(components.CardProps{}) {
hx-post="/users" @components.CardContent() {
hx-target="#toast-container" <form
class="space-y-4" class="flex flex-col gap-2"
> hx-post="/docs/toast/demo"
<div> hx-trigger="submit"
<label for="email">Email</label> hx-target="#toast-container"
<input >
type="email" // Message
name="email" @components.FormItem(components.FormItemProps{}) {
id="email" @components.Label(components.LabelProps{Text: "Message"})
class="w-full rounded-lg border" @components.Input(components.InputProps{
/> Value: "Test Notification",
</div> Name: "message",
<button type="submit">Speichern</button> })
</form> }
<div id="toast-container"></div> // Type
</div> @components.FormItem(components.FormItemProps{}) {
@components.Label(components.LabelProps{Text: "Type"})
@components.Select(components.SelectProps{
Name: "type",
Options: []components.SelectOption{
{Value: "default", Label: "Default"},
{Value: "success", Label: "Success"},
{Value: "error", Label: "Error"},
{Value: "warning", Label: "Warning"},
{Value: "info", Label: "Info"},
},
})
}
// Position
@components.FormItem(components.FormItemProps{}) {
@components.Label(components.LabelProps{Text: "Position"})
@components.Select(components.SelectProps{
Name: "position",
Options: []components.SelectOption{
{Value: "top-right", Label: "Top Right"},
{Value: "top-left", Label: "Top Left"},
{Value: "top-center", Label: "Top Center"},
{Value: "bottom-right", Label: "Bottom Right", Selected: true},
{Value: "bottom-left", Label: "Bottom Left"},
{Value: "bottom-center", Label: "Bottom Center"},
},
})
}
// Duration
@components.FormItem(components.FormItemProps{}) {
@components.Label(components.LabelProps{Text: "Duration (ms)"})
@components.Input(components.InputProps{
Type: "number",
Name: "duration",
Value: "3000",
})
}
// Size
@components.FormItem(components.FormItemProps{}) {
@components.Label(components.LabelProps{Text: "Size"})
@components.Select(components.SelectProps{
Name: "size",
Options: []components.SelectOption{
{Value: "sm", Label: "Small"},
{Value: "md", Label: "Medium"},
{Value: "lg", Label: "Large"},
},
})
}
// Options
@components.FormItem(components.FormItemProps{}) {
@components.Label(components.LabelProps{Text: "Options"})
@components.FormItemFlex(components.FormItemProps{}) {
@components.Toggle(components.ToggleProps{
Name: "dismissible",
Checked: true,
})
@components.Label(components.LabelProps{Text: "Dismissible"})
}
@components.FormItemFlex(components.FormItemProps{}) {
@components.Toggle(components.ToggleProps{
Name: "icon",
Checked: true,
})
@components.Label(components.LabelProps{Text: "Show Icon"})
}
}
// Submit
@components.Button(components.ButtonProps{
Text: "Show Toast",
Type: "submit",
Class: "w-full",
})
</form>
}
}
</section>
<div id="toast-container"></div>
</div> </div>
} }

View File

@ -1,139 +0,0 @@
package showcase
import "github.com/axzilla/templui/pkg/components"
templ ToastAdvanced() {
<div class="max-w-4xl mx-auto p-8">
<section class="mb-12">
@components.Card(components.CardProps{}) {
@components.CardContent() {
<form
class="flex flex-col gap-2"
hx-post="/docs/toast/demo"
hx-trigger="change, submit"
hx-target="#toast-containerx"
>
// Message
@components.FormItem(components.FormItemProps{}) {
@components.Label(components.LabelProps{Text: "Message"})
@components.Input(components.InputProps{
Value: "Test Notification",
Name: "message",
})
}
// Type
@components.FormItem(components.FormItemProps{}) {
@components.Label(components.LabelProps{Text: "Type"})
@components.Select(components.SelectProps{
Name: "type",
Options: []components.SelectOption{
{Value: "default", Label: "Default"},
{Value: "success", Label: "Success"},
{Value: "error", Label: "Error"},
{Value: "warning", Label: "Warning"},
{Value: "info", Label: "Info"},
},
})
}
// Position
@components.FormItem(components.FormItemProps{}) {
@components.Label(components.LabelProps{Text: "Position"})
@components.Select(components.SelectProps{
Name: "position",
Options: []components.SelectOption{
{Value: "top-right", Label: "Top Right"},
{Value: "top-left", Label: "Top Left"},
{Value: "top-center", Label: "Top Center"},
{Value: "bottom-right", Label: "Bottom Right"},
{Value: "bottom-left", Label: "Bottom Left"},
{Value: "bottom-center", Label: "Bottom Center"},
},
})
}
// Duration
@components.FormItem(components.FormItemProps{}) {
@components.Label(components.LabelProps{Text: "Duration (ms)"})
@components.Input(components.InputProps{
Type: "number",
Name: "duration",
Value: "3000",
})
}
// Size
@components.FormItem(components.FormItemProps{}) {
@components.Label(components.LabelProps{Text: "Size"})
@components.Select(components.SelectProps{
Name: "size",
Options: []components.SelectOption{
{Value: "sm", Label: "Small"},
{Value: "md", Label: "Medium"},
{Value: "lg", Label: "Large"},
},
})
}
// Options
@components.FormItem(components.FormItemProps{}) {
@components.Label(components.LabelProps{Text: "Options"})
@components.FormItemFlex(components.FormItemProps{}) {
@components.Toggle(components.ToggleProps{
Name: "dismissible",
Checked: true,
})
@components.Label(components.LabelProps{Text: "Dismissible"})
}
@components.FormItemFlex(components.FormItemProps{}) {
@components.Toggle(components.ToggleProps{
Name: "icon",
Checked: true,
})
@components.Label(components.LabelProps{Text: "Show Icon"})
}
}
@components.Button(components.ButtonProps{
Text: "Show Toast",
Type: "submit",
Class: "w-full",
})
</form>
}
}
</section>
<div id="toast-containerx"></div>
// Code Examples
<section>
<h2 class="text-xl font-semibold mb-4">Usage Examples</h2>
<div class="space-y-4">
<div class="p-4 bg-gray-50 rounded-lg">
<h3 class="font-medium mb-2">Basic Usage</h3>
<pre class="text-sm">
{ `// In your handler
components.Toast(types.ToastConfig{
Message: "Nachricht",
Type: "success",
Position: "top-right",
Duration: 3000,
}).Render(ctx, w)` }
</pre>
</div>
<div class="p-4 bg-gray-50 rounded-lg">
<h3 class="font-medium mb-2">With HTMX</h3>
<pre class="text-sm">
{ `// Template
<form hx-post="/save" hx-target="#toast-container">
...
</form>
<div id="toast-container"></div>
// Handler
if err != nil {
return components.Toast(types.ToastConfig{
Message: err.Error(),
Type: "error",
}).Render(ctx, w)
}` }
</pre>
</div>
</div>
</section>
</div>
}

View File

@ -6,26 +6,26 @@ import (
) )
type ToastProps struct { type ToastProps struct {
Message string // Die Nachricht Message string // Message to display
Type string // success, error, warning, info, default Type string // Type of the toast (default, success, error, warning, info)
Position string // top-right, top-left, top-center, bottom-right, bottom-left, bottom-center Position string // Position of the toast (top-right, top-left, top-center, bottom-right, bottom-left, bottom-center)
Duration int // Millisekunden, 0 = permanent Duration int // Duration in milliseconds
Dismissible bool // Kann manuell geschlossen werden Dismissible bool // Show dismiss button
Size string // sm, md, lg Size string // Size of the toast (sm, md, lg)
Icon bool // Icon anzeigen/verstecken Icon bool // Show icon
HTML string // Custom HTML Content
} }
templ Toast(cfg ToastProps) { // Flexible toast component for notifications and feedback.
templ Toast(props ToastProps) {
<div <div
x-data={ `{ x-data={ `{
show: true, show: true,
message: '` + cfg.Message + `', message: '` + props.Message + `',
type: '` + cfg.Type + `', type: '` + props.Type + `',
position: '` + cfg.Position + `', position: '` + props.Position + `',
duration: ` + fmt.Sprint(cfg.Duration) + `, duration: ` + fmt.Sprint(props.Duration) + `,
dismissible: ` + fmt.Sprint(cfg.Dismissible) + `, dismissible: ` + fmt.Sprint(props.Dismissible) + `,
size: '` + cfg.Size + `' size: '` + props.Size + `'
}` } }` }
x-init="if(duration > 0) setTimeout(() => show = false, duration)" x-init="if(duration > 0) setTimeout(() => show = false, duration)"
x-show="show" x-show="show"
@ -36,7 +36,7 @@ templ Toast(cfg ToastProps) {
x-transition:leave-start="opacity-100 translate-y-0" x-transition:leave-start="opacity-100 translate-y-0"
x-transition:leave-end="opacity-0 translate-y-4" x-transition:leave-end="opacity-0 translate-y-4"
@click="if(dismissible) show = false" @click="if(dismissible) show = false"
class="fixed pointer-events-auto" class="z-50 fixed pointer-events-auto"
:class="{ :class="{
// Position // Position
'top-4 right-4': position === 'top-right', 'top-4 right-4': position === 'top-right',
@ -51,43 +51,34 @@ templ Toast(cfg ToastProps) {
'w-[30rem]': size === 'lg' 'w-[30rem]': size === 'lg'
}" }"
> >
if cfg.HTML != "" { <div
<div class="bg-primary-foreground rounded-lg shadow-sm border p-4 flex items-center justify-center"
x-html="message" >
class="rounded-lg shadow-lg" if props.Icon {
></div> if props.Type == "success" {
} else { @icons.CircleCheck(icons.IconProps{Size: "18", Class: "text-green-500 mr-3"})
// Default Toast
<div
class="bg-primary-foreground rounded-lg shadow-sm border p-4 flex items-center justify-center"
>
if cfg.Icon {
// Icons für verschiedene Types
if cfg.Type == "success" {
@icons.CircleCheck(icons.IconProps{Size: "18", Class: "text-green-500 mr-3"})
}
if cfg.Type == "error" {
@icons.CircleX(icons.IconProps{Size: "18", Class: "text-red-500 mr-3"})
}
if cfg.Type == "warning" {
@icons.TriangleAlert(icons.IconProps{Size: "18", Class: "text-yellow-500 mr-3"})
}
if cfg.Type == "info" {
@icons.Info(icons.IconProps{Size: "18", Class: "text-blue-500 mr-3"})
}
} }
<div class="flex-1" x-text="message"></div> if props.Type == "error" {
if cfg.Dismissible { @icons.CircleX(icons.IconProps{Size: "18", Class: "text-red-500 mr-3"})
<button
@click.stop="show = false"
>
@icons.X(icons.IconProps{
Size: "18",
Class: "ml-4 flex-shrink-0 opacity-75 hover:opacity-100",
})
</button>
} }
</div> if props.Type == "warning" {
} @icons.TriangleAlert(icons.IconProps{Size: "18", Class: "text-yellow-500 mr-3"})
}
if props.Type == "info" {
@icons.Info(icons.IconProps{Size: "18", Class: "text-blue-500 mr-3"})
}
}
<div class="flex-1" x-text="message"></div>
if props.Dismissible {
<button
@click.stop="show = false"
>
@icons.X(icons.IconProps{
Size: "18",
Class: "opacity-75 hover:opacity-100",
})
</button>
}
</div>
</div> </div>
} }

View File

@ -14,17 +14,17 @@ import (
) )
type ToastProps struct { type ToastProps struct {
Message string // Die Nachricht Message string // Message to display
Type string // success, error, warning, info, default Type string // Type of the toast (default, success, error, warning, info)
Position string // top-right, top-left, top-center, bottom-right, bottom-left, bottom-center Position string // Position of the toast (top-right, top-left, top-center, bottom-right, bottom-left, bottom-center)
Duration int // Millisekunden, 0 = permanent Duration int // Duration in milliseconds
Dismissible bool // Kann manuell geschlossen werden Dismissible bool // Show dismiss button
Size string // sm, md, lg Size string // Size of the toast (sm, md, lg)
Icon bool // Icon anzeigen/verstecken Icon bool // Show icon
HTML string // Custom HTML Content
} }
func Toast(cfg ToastProps) templ.Component { // Flexible toast component for notifications and feedback.
func Toast(props ToastProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@ -52,12 +52,12 @@ func Toast(cfg ToastProps) templ.Component {
var templ_7745c5c3_Var2 string var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(`{ templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(`{
show: true, show: true,
message: '` + cfg.Message + `', message: '` + props.Message + `',
type: '` + cfg.Type + `', type: '` + props.Type + `',
position: '` + cfg.Position + `', position: '` + props.Position + `',
duration: ` + fmt.Sprint(cfg.Duration) + `, duration: ` + fmt.Sprint(props.Duration) + `,
dismissible: ` + fmt.Sprint(cfg.Dismissible) + `, dismissible: ` + fmt.Sprint(props.Dismissible) + `,
size: '` + cfg.Size + `' size: '` + props.Size + `'
}`) }`)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toast.templ`, Line: 29, Col: 10} return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toast.templ`, Line: 29, Col: 10}
@ -66,89 +66,70 @@ func Toast(cfg ToastProps) templ.Component {
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-init=\"if(duration &gt; 0) setTimeout(() =&gt; show = false, duration)\" x-show=\"show\" x-transition:enter=\"transition ease-out duration-300\" x-transition:enter-start=\"opacity-0 translate-y-4\" x-transition:enter-end=\"opacity-100 translate-y-0\" x-transition:leave=\"transition ease-in duration-200\" x-transition:leave-start=\"opacity-100 translate-y-0\" x-transition:leave-end=\"opacity-0 translate-y-4\" @click=\"if(dismissible) show = false\" class=\"fixed pointer-events-auto\" :class=\"{\n // Position\n &#39;top-4 right-4&#39;: position === &#39;top-right&#39;,\n &#39;top-4 left-4&#39;: position === &#39;top-left&#39;,\n &#39;top-4 left-1/2 -translate-x-1/2&#39;: position === &#39;top-center&#39;,\n &#39;bottom-4 right-4&#39;: position === &#39;bottom-right&#39;,\n &#39;bottom-4 left-4&#39;: position === &#39;bottom-left&#39;,\n &#39;bottom-4 left-1/2 -translate-x-1/2&#39;: position === &#39;bottom-center&#39;,\n // Size\n &#39;w-72&#39;: size === &#39;sm&#39;,\n &#39;w-96&#39;: size === &#39;md&#39;,\n &#39;w-[30rem]&#39;: size === &#39;lg&#39;\n }\">") _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-init=\"if(duration &gt; 0) setTimeout(() =&gt; show = false, duration)\" x-show=\"show\" x-transition:enter=\"transition ease-out duration-300\" x-transition:enter-start=\"opacity-0 translate-y-4\" x-transition:enter-end=\"opacity-100 translate-y-0\" x-transition:leave=\"transition ease-in duration-200\" x-transition:leave-start=\"opacity-100 translate-y-0\" x-transition:leave-end=\"opacity-0 translate-y-4\" @click=\"if(dismissible) show = false\" class=\"z-50 fixed pointer-events-auto\" :class=\"{\n // Position\n &#39;top-4 right-4&#39;: position === &#39;top-right&#39;,\n &#39;top-4 left-4&#39;: position === &#39;top-left&#39;,\n &#39;top-4 left-1/2 -translate-x-1/2&#39;: position === &#39;top-center&#39;,\n &#39;bottom-4 right-4&#39;: position === &#39;bottom-right&#39;,\n &#39;bottom-4 left-4&#39;: position === &#39;bottom-left&#39;,\n &#39;bottom-4 left-1/2 -translate-x-1/2&#39;: position === &#39;bottom-center&#39;,\n // Size\n &#39;w-72&#39;: size === &#39;sm&#39;,\n &#39;w-96&#39;: size === &#39;md&#39;,\n &#39;w-[30rem]&#39;: size === &#39;lg&#39;\n }\"><div class=\"bg-primary-foreground rounded-lg shadow-sm border p-4 flex items-center justify-center\">")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
if cfg.HTML != "" { if props.Icon {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div x-html=\"message\" class=\"rounded-lg shadow-lg\"></div>") if props.Type == "success" {
templ_7745c5c3_Err = icons.CircleCheck(icons.IconProps{Size: "18", Class: "text-green-500 mr-3"}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
} else { if props.Type == "error" {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <div class=\"bg-primary-foreground rounded-lg shadow-sm border p-4 flex items-center justify-center\">") templ_7745c5c3_Err = icons.CircleX(icons.IconProps{Size: "18", Class: "text-red-500 mr-3"}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
if cfg.Icon { if props.Type == "warning" {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") templ_7745c5c3_Err = icons.TriangleAlert(icons.IconProps{Size: "18", Class: "text-yellow-500 mr-3"}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
if cfg.Type == "success" {
templ_7745c5c3_Err = icons.CircleCheck(icons.IconProps{Size: "18", Class: "text-green-500 mr-3"}).Render(ctx, templ_7745c5c3_Buffer)
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
}
if cfg.Type == "error" {
templ_7745c5c3_Err = icons.CircleX(icons.IconProps{Size: "18", Class: "text-red-500 mr-3"}).Render(ctx, templ_7745c5c3_Buffer)
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
}
if cfg.Type == "warning" {
templ_7745c5c3_Err = icons.TriangleAlert(icons.IconProps{Size: "18", Class: "text-yellow-500 mr-3"}).Render(ctx, templ_7745c5c3_Buffer)
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
}
if cfg.Type == "info" {
templ_7745c5c3_Err = icons.Info(icons.IconProps{Size: "18", Class: "text-blue-500 mr-3"}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex-1\" x-text=\"message\"></div>") _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
if cfg.Dismissible { if props.Type == "info" {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<button @click.stop=\"show = false\">") templ_7745c5c3_Err = icons.Info(icons.IconProps{Size: "18", Class: "text-blue-500 mr-3"}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = icons.X(icons.IconProps{
Size: "18",
Class: "ml-4 flex-shrink-0 opacity-75 hover:opacity-100",
}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</button>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>") }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex-1\" x-text=\"message\"></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if props.Dismissible {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<button @click.stop=\"show = false\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = icons.X(icons.IconProps{
Size: "18",
Class: "opacity-75 hover:opacity-100",
}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</button>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
} }
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>") _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }