mirror of
https://github.com/axzilla/templui.git
synced 2025-02-21 20:33:00 +00:00
feat: add input component wip
This commit is contained in:
parent
fa59e4f47b
commit
683e34fb62
@ -628,6 +628,10 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.pointer-events-none {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.static {
|
||||
position: static;
|
||||
}
|
||||
@ -702,6 +706,14 @@ body {
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.m-32 {
|
||||
margin: 8rem;
|
||||
}
|
||||
|
||||
.m-0 {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.mx-auto {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
@ -767,6 +779,10 @@ body {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
@ -791,6 +807,10 @@ body {
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.h-5 {
|
||||
height: 1.25rem;
|
||||
}
|
||||
|
||||
.h-6 {
|
||||
height: 1.5rem;
|
||||
}
|
||||
@ -839,6 +859,10 @@ body {
|
||||
width: 1rem;
|
||||
}
|
||||
|
||||
.w-5 {
|
||||
width: 1.25rem;
|
||||
}
|
||||
|
||||
.w-6 {
|
||||
width: 1.5rem;
|
||||
}
|
||||
@ -855,6 +879,10 @@ body {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.w-1\/2 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.max-w-3xl {
|
||||
max-width: 48rem;
|
||||
}
|
||||
@ -863,10 +891,22 @@ body {
|
||||
max-width: 80rem;
|
||||
}
|
||||
|
||||
.max-w-sm {
|
||||
max-width: 24rem;
|
||||
}
|
||||
|
||||
.max-w-xs {
|
||||
max-width: 20rem;
|
||||
}
|
||||
|
||||
.max-w-xl {
|
||||
max-width: 36rem;
|
||||
}
|
||||
|
||||
.max-w-lg {
|
||||
max-width: 32rem;
|
||||
}
|
||||
|
||||
.flex-1 {
|
||||
flex: 1 1 0%;
|
||||
}
|
||||
@ -953,6 +993,10 @@ body {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.gap-1\.5 {
|
||||
gap: 0.375rem;
|
||||
}
|
||||
|
||||
.gap-2 {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
@ -997,6 +1041,12 @@ body {
|
||||
margin-bottom: calc(2rem * var(--tw-space-y-reverse));
|
||||
}
|
||||
|
||||
.space-y-6 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-y-reverse: 0;
|
||||
margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
|
||||
margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
|
||||
}
|
||||
|
||||
.overflow-auto {
|
||||
overflow: auto;
|
||||
}
|
||||
@ -1102,6 +1152,10 @@ body {
|
||||
background-color: hsl(var(--secondary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-transparent {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.bg-white {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
||||
@ -1222,10 +1276,26 @@ body {
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
.pl-10 {
|
||||
padding-left: 2.5rem;
|
||||
}
|
||||
|
||||
.pl-3 {
|
||||
padding-left: 0.75rem;
|
||||
}
|
||||
|
||||
.pl-6 {
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
.pr-10 {
|
||||
padding-right: 2.5rem;
|
||||
}
|
||||
|
||||
.pr-3 {
|
||||
padding-right: 0.75rem;
|
||||
}
|
||||
|
||||
.pt-0 {
|
||||
padding-top: 0px;
|
||||
}
|
||||
@ -1274,6 +1344,10 @@ body {
|
||||
line-height: 1rem;
|
||||
}
|
||||
|
||||
.text-\[0\.8rem\] {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
@ -1312,6 +1386,11 @@ body {
|
||||
color: hsl(var(--card-foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-destructive {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--destructive) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-destructive-foreground {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--destructive-foreground) / var(--tw-text-opacity));
|
||||
@ -1456,6 +1535,56 @@ body {
|
||||
mask-image: linear-gradient(180deg,white,rgba(255,255,255,0));
|
||||
}
|
||||
|
||||
.file\:mr-4::file-selector-button {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.file\:rounded-md::file-selector-button {
|
||||
border-radius: calc(var(--radius) - 2px);
|
||||
}
|
||||
|
||||
.file\:border-0::file-selector-button {
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.file\:bg-transparent::file-selector-button {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.file\:bg-secondary::file-selector-button {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--secondary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.file\:px-4::file-selector-button {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
.file\:py-2::file-selector-button {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.file\:text-sm::file-selector-button {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
|
||||
.file\:font-medium::file-selector-button {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.file\:text-secondary-foreground::file-selector-button {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--secondary-foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.file\:text-foreground::file-selector-button {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.placeholder\:text-muted-foreground::-moz-placeholder {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--muted-foreground) / var(--tw-text-opacity));
|
||||
@ -1522,6 +1651,10 @@ body {
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
.hover\:file\:bg-secondary\/80::file-selector-button:hover {
|
||||
background-color: hsl(var(--secondary) / 0.8);
|
||||
}
|
||||
|
||||
.focus\:border-ring:focus {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: hsl(var(--ring) / var(--tw-border-opacity));
|
||||
@ -1561,6 +1694,12 @@ body {
|
||||
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-2: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(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
||||
@ -1640,6 +1779,11 @@ body {
|
||||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:file\:text-foreground:is(.dark *)::file-selector-button {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.dark\:hover\:bg-gray-700:hover:is(.dark *) {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(55 65 81 / var(--tw-bg-opacity));
|
||||
|
@ -25,6 +25,7 @@ func main() {
|
||||
mux.Handle("GET /docs/components/sheet", templ.Handler(pages.Sheet()))
|
||||
mux.Handle("GET /docs/components/tabs", templ.Handler(pages.Tabs()))
|
||||
mux.Handle("GET /docs/components/card", templ.Handler(pages.Card()))
|
||||
mux.Handle("GET /docs/components/input", templ.Handler(pages.Input()))
|
||||
|
||||
fmt.Println("Server is running on http://localhost:8090")
|
||||
http.ListenAndServe(":8090", mux)
|
||||
|
@ -37,6 +37,10 @@ var Sections = []Section{
|
||||
Text: "Card",
|
||||
Href: "/docs/components/card",
|
||||
},
|
||||
{
|
||||
Text: "Input",
|
||||
Href: "/docs/components/input",
|
||||
},
|
||||
{
|
||||
Text: "Sheet",
|
||||
Href: "/docs/components/sheet",
|
||||
|
43
internals/ui/components/input.templ
Normal file
43
internals/ui/components/input.templ
Normal file
@ -0,0 +1,43 @@
|
||||
package components
|
||||
|
||||
type InputProps struct {
|
||||
Type string
|
||||
Placeholder string
|
||||
Value string
|
||||
Name string
|
||||
ID string
|
||||
Class string
|
||||
Disabled any
|
||||
ReadOnly bool
|
||||
Required bool
|
||||
FileAccept string
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
templ Input(props InputProps) {
|
||||
<input
|
||||
type={ props.Type }
|
||||
placeholder={ props.Placeholder }
|
||||
value={ props.Value }
|
||||
name={ props.Name }
|
||||
id={ props.ID }
|
||||
class={ "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background",
|
||||
"file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground",
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
"disabled:cursor-not-allowed disabled:opacity-50", "file:text-foreground dark:file:text-foreground", props.Class }
|
||||
if props.Disabled != nil {
|
||||
if disabledBool, ok := props.Disabled.(bool); ok && disabledBool {
|
||||
disabled="true"
|
||||
}
|
||||
if disabledStr, ok := props.Disabled.(string); ok {
|
||||
:disabled={ disabledStr }
|
||||
}
|
||||
}
|
||||
readonly?={ props.ReadOnly }
|
||||
required?={ props.Required }
|
||||
if props.Type == "file" {
|
||||
accept={ props.FileAccept }
|
||||
}
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
}
|
36
internals/ui/pages/input.templ
Normal file
36
internals/ui/pages/input.templ
Normal file
@ -0,0 +1,36 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"github.com/axzilla/goilerplate/internals/ui/components"
|
||||
"github.com/axzilla/goilerplate/internals/ui/layouts"
|
||||
"github.com/axzilla/goilerplate/internals/ui/showcase"
|
||||
)
|
||||
|
||||
templ Input() {
|
||||
@layouts.DocsLayout() {
|
||||
<div class="mb-16">
|
||||
<h1 class="text-3xl font-bold mb-2">Input</h1>
|
||||
<p class="mb-4 text-muted-foreground">Displays a form input field or a component that looks like an input field.</p>
|
||||
</div>
|
||||
@components.Tabs(components.TabsProps{
|
||||
Tabs: []components.Tab{
|
||||
{
|
||||
ID: "preview",
|
||||
Title: "Preview",
|
||||
Content: showcase.InputShowcase(),
|
||||
},
|
||||
{
|
||||
ID: "code",
|
||||
Title: "Code",
|
||||
Content: CodeSnippetFromEmbedded("input.templ", "go", showcase.TemplFiles),
|
||||
},
|
||||
{
|
||||
ID: "component",
|
||||
Title: "Component",
|
||||
Content: CodeSnippetFromEmbedded("input.templ", "go", components.TemplFiles),
|
||||
},
|
||||
},
|
||||
TabsContainerClass: "md:w-1/2",
|
||||
})
|
||||
}
|
||||
}
|
78
internals/ui/showcase/input.templ
Normal file
78
internals/ui/showcase/input.templ
Normal file
@ -0,0 +1,78 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/internals/ui/components"
|
||||
|
||||
templ InputShowcase() {
|
||||
<div class="flex justify-center items-center border rounded-md py-16 px-4">
|
||||
<div>
|
||||
<div class="mb-8">
|
||||
<h2 class="font-semibold mb-2">Default</h2>
|
||||
@components.Input(components.InputProps{
|
||||
Type: "email",
|
||||
Placeholder: "Email",
|
||||
})
|
||||
</div>
|
||||
<div class="mb-8">
|
||||
<h2 class="font-semibold mb-2">File</h2>
|
||||
<div class="grid w-full max-w-sm items-center gap-1.5">
|
||||
@components.Input(components.InputProps{
|
||||
Type: "file",
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-8">
|
||||
<h2 class="font-semibold mb-2">Disabled</h2>
|
||||
@components.Input(components.InputProps{
|
||||
Type: "email",
|
||||
Placeholder: "Email",
|
||||
Disabled: "true",
|
||||
})
|
||||
</div>
|
||||
<div class="mb-8">
|
||||
<h2 class="font-semibold mb-2">With Label</h2>
|
||||
<div class="grid w-full max-w-sm items-center gap-1.5">
|
||||
<label for="email" class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
|
||||
Email
|
||||
</label>
|
||||
@components.Input(components.InputProps{
|
||||
ID: "email",
|
||||
Type: "email",
|
||||
Placeholder: "Email",
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-8">
|
||||
<h2 class="font-semibold mb-2">With Button</h2>
|
||||
<div class="flex w-full max-w-sm items-center space-x-2">
|
||||
@components.Input(components.InputProps{
|
||||
Type: "email",
|
||||
Placeholder: "Email",
|
||||
})
|
||||
@components.Button(components.ButtonProps{
|
||||
Type: "submit",
|
||||
Text: "Subscribe",
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-8">
|
||||
<h2 class="font-semibold mb-2">Form</h2>
|
||||
<form class="w-full max-w-sm space-y-6">
|
||||
<div class="space-y-2">
|
||||
<label for="username" class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
|
||||
Username
|
||||
</label>
|
||||
@components.Input(components.InputProps{
|
||||
ID: "username",
|
||||
Type: "text",
|
||||
})
|
||||
<p class="text-sm text-muted-foreground m-0">This is your public display name.</p>
|
||||
</div>
|
||||
@components.Button(components.ButtonProps{
|
||||
Type: "submit",
|
||||
Text: "Submit",
|
||||
})
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user