mirror of
https://github.com/axzilla/templui.git
synced 2025-02-21 01:52:52 +00:00
commit
7b325e90db
@ -1,95 +0,0 @@
|
||||
# Goilerplate Commit & Release Cheatsheet
|
||||
|
||||
## Commit Message Format
|
||||
|
||||
`<type>`: `<description>`
|
||||
|
||||
## Types
|
||||
|
||||
- `feat`: New feature or component
|
||||
- `fix`: Bug fix
|
||||
- `docs`: Documentation changes
|
||||
- `style`: Changes that do not affect the meaning of the code (white-space, formatting, etc)
|
||||
- `refactor`: Code change that neither fixes a bug nor adds a feature
|
||||
- `perf`: Code change that improves performance
|
||||
- `test`: Adding missing tests or correcting existing tests
|
||||
- `chore`: Changes to the build process or auxiliary tools and libraries
|
||||
|
||||
## Examples
|
||||
|
||||
- `feat: add Button component`
|
||||
- `fix: correct Card component padding on mobile`
|
||||
- `refactor: simplify Modal component logic`
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
Add `!` after the type for breaking changes:
|
||||
|
||||
- `feat!: redesign Form component API`
|
||||
|
||||
## Versioning Strategy (0.x.y)
|
||||
|
||||
- 0: Remains 0 until the first stable version (1.0.0)
|
||||
- x: For major changes or feature sets (e.g., 20)
|
||||
- y: For minor changes, bugfixes, and incremental updates
|
||||
|
||||
## Version Increments
|
||||
|
||||
- Increase second number (x) for:
|
||||
- New major features
|
||||
- Significant API or functionality changes
|
||||
- Increase third number (y) for:
|
||||
- Bugfixes
|
||||
- Small feature additions
|
||||
- Documentation changes
|
||||
- Performance optimizations
|
||||
- Other minor changes
|
||||
|
||||
## Release Process
|
||||
|
||||
1. Commit changes:
|
||||
|
||||
```
|
||||
git add .
|
||||
git commit -m "feat: implement XYZ feature"
|
||||
```
|
||||
|
||||
2. Tag and push version:
|
||||
|
||||
```
|
||||
git tag -a v0.20.2 -m "Release v0.20.2"
|
||||
git push origin main --tags
|
||||
```
|
||||
|
||||
3. Create GitHub Release:
|
||||
- Go to GitHub > Releases > "Draft a new release"
|
||||
- Select the created tag
|
||||
- Title: "Release v0.20.2"
|
||||
- Description: Brief summary of main changes
|
||||
- Publish the release
|
||||
|
||||
## Go Module Usage
|
||||
|
||||
- Install latest version:
|
||||
```
|
||||
go get github.com/axzilla/goilerplate@latest
|
||||
```
|
||||
- Install specific version:
|
||||
```
|
||||
go get github.com/axzilla/goilerplate@v0.20.2
|
||||
```
|
||||
- Install development version:
|
||||
```
|
||||
go get github.com/axzilla/goilerplate@main
|
||||
```
|
||||
|
||||
Remind users to run `go mod tidy` after changes.
|
||||
|
||||
## Transition to 1.0.0
|
||||
|
||||
Switch to 1.0.0 when the project:
|
||||
|
||||
- Has a stable API
|
||||
- Is sufficiently tested
|
||||
- Is ready for production environments
|
||||
- Offers a solid feature base
|
@ -6,45 +6,46 @@
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 240 10% 3.9%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 240 10% 3.9%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 240 10% 3.9%;
|
||||
--primary: 240 5.9% 10%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
--secondary: 240 4.8% 95.9%;
|
||||
--secondary-foreground: 240 5.9% 10%;
|
||||
--muted: 240 4.8% 95.9%;
|
||||
--muted-foreground: 240 3.8% 46.1%;
|
||||
--accent: 240 4.8% 95.9%;
|
||||
--accent-foreground: 240 5.9% 10%;
|
||||
--destructive: 0 72.22% 50.59%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 240 10% 3.9%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 240 10% 3.9%;
|
||||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
--ring: 240 5.9% 10%;
|
||||
--primary: 346.8 77.2% 49.8%;
|
||||
--primary-foreground: 355.7 100% 97.3%;
|
||||
--secondary: 240 4.8% 95.9%;
|
||||
--secondary-foreground: 240 5.9% 10%;
|
||||
--accent: 240 4.8% 95.9%;
|
||||
--accent-foreground: 240 5.9% 10%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--ring: 346.8 77.2% 49.8%;
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
.dark {
|
||||
--background: 240 10% 3.9%;
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 240 10% 3.9%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
--popover: 240 10% 3.9%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
--primary: 0 0% 98%;
|
||||
--primary-foreground: 240 5.9% 10%;
|
||||
--secondary: 240 3.7% 15.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--muted: 240 3.7% 15.9%;
|
||||
--background: 20 14.3% 4.1%;
|
||||
--foreground: 0 0% 95%;
|
||||
--muted: 0 0% 15%;
|
||||
--muted-foreground: 240 5% 64.9%;
|
||||
--accent: 240 3.7% 15.9%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--popover: 0 0% 9%;
|
||||
--popover-foreground: 0 0% 95%;
|
||||
--card: 24 9.8% 10%;
|
||||
--card-foreground: 0 0% 95%;
|
||||
--border: 240 3.7% 15.9%;
|
||||
--input: 240 3.7% 15.9%;
|
||||
--ring: 240 4.9% 83.9%;
|
||||
--primary: 346.8 77.2% 49.8%;
|
||||
--primary-foreground: 355.7 100% 97.3%;
|
||||
--secondary: 240 3.7% 15.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--accent: 12 6.5% 15.1%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 85.7% 97.3%;
|
||||
--ring: 346.8 77.2% 49.8%;
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
}
|
||||
@layer base {
|
||||
|
@ -449,46 +449,47 @@ video {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 240 10% 3.9%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 240 10% 3.9%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 240 10% 3.9%;
|
||||
--primary: 240 5.9% 10%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
--secondary: 240 4.8% 95.9%;
|
||||
--secondary-foreground: 240 5.9% 10%;
|
||||
--muted: 240 4.8% 95.9%;
|
||||
--muted-foreground: 240 3.8% 46.1%;
|
||||
--accent: 240 4.8% 95.9%;
|
||||
--accent-foreground: 240 5.9% 10%;
|
||||
--destructive: 0 72.22% 50.59%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 240 10% 3.9%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 240 10% 3.9%;
|
||||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
--ring: 240 5.9% 10%;
|
||||
--primary: 346.8 77.2% 49.8%;
|
||||
--primary-foreground: 355.7 100% 97.3%;
|
||||
--secondary: 240 4.8% 95.9%;
|
||||
--secondary-foreground: 240 5.9% 10%;
|
||||
--accent: 240 4.8% 95.9%;
|
||||
--accent-foreground: 240 5.9% 10%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--ring: 346.8 77.2% 49.8%;
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 240 10% 3.9%;
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 240 10% 3.9%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
--popover: 240 10% 3.9%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
--primary: 0 0% 98%;
|
||||
--primary-foreground: 240 5.9% 10%;
|
||||
--secondary: 240 3.7% 15.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--muted: 240 3.7% 15.9%;
|
||||
--background: 20 14.3% 4.1%;
|
||||
--foreground: 0 0% 95%;
|
||||
--muted: 0 0% 15%;
|
||||
--muted-foreground: 240 5% 64.9%;
|
||||
--accent: 240 3.7% 15.9%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--popover: 0 0% 9%;
|
||||
--popover-foreground: 0 0% 95%;
|
||||
--card: 24 9.8% 10%;
|
||||
--card-foreground: 0 0% 95%;
|
||||
--border: 240 3.7% 15.9%;
|
||||
--input: 240 3.7% 15.9%;
|
||||
--ring: 240 4.9% 83.9%;
|
||||
--primary: 346.8 77.2% 49.8%;
|
||||
--primary-foreground: 355.7 100% 97.3%;
|
||||
--secondary: 240 3.7% 15.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--accent: 12 6.5% 15.1%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 85.7% 97.3%;
|
||||
--ring: 346.8 77.2% 49.8%;
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
* {
|
||||
@ -628,6 +629,30 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.pointer-events-none {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.visible {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.static {
|
||||
position: static;
|
||||
}
|
||||
@ -674,6 +699,10 @@ body {
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.left-1\/2 {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.left-full {
|
||||
left: 100%;
|
||||
}
|
||||
@ -686,6 +715,10 @@ body {
|
||||
right: 0.5rem;
|
||||
}
|
||||
|
||||
.right-3 {
|
||||
right: 0.75rem;
|
||||
}
|
||||
|
||||
.right-4 {
|
||||
right: 1rem;
|
||||
}
|
||||
@ -694,10 +727,18 @@ body {
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.top-1\/2 {
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.top-2 {
|
||||
top: 0.5rem;
|
||||
}
|
||||
|
||||
.top-3 {
|
||||
top: 0.75rem;
|
||||
}
|
||||
|
||||
.top-full {
|
||||
top: 100%;
|
||||
}
|
||||
@ -819,6 +860,16 @@ body {
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
.size-3 {
|
||||
width: 0.75rem;
|
||||
height: 0.75rem;
|
||||
}
|
||||
|
||||
.size-4 {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.h-1\/2 {
|
||||
height: 50%;
|
||||
}
|
||||
@ -839,6 +890,10 @@ body {
|
||||
height: 4rem;
|
||||
}
|
||||
|
||||
.h-2 {
|
||||
height: 0.5rem;
|
||||
}
|
||||
|
||||
.h-24 {
|
||||
height: 6rem;
|
||||
}
|
||||
@ -887,6 +942,10 @@ body {
|
||||
max-height: 24rem;
|
||||
}
|
||||
|
||||
.min-h-\[80px\] {
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
.min-h-screen {
|
||||
min-height: 100vh;
|
||||
}
|
||||
@ -955,6 +1014,10 @@ body {
|
||||
max-width: 80rem;
|
||||
}
|
||||
|
||||
.max-w-lg {
|
||||
max-width: 32rem;
|
||||
}
|
||||
|
||||
.max-w-md {
|
||||
max-width: 28rem;
|
||||
}
|
||||
@ -987,11 +1050,20 @@ body {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.-translate-x-1 {
|
||||
--tw-translate-x: -0.25rem;
|
||||
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-x-1\/2 {
|
||||
--tw-translate-x: -50%;
|
||||
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-x-1\/4 {
|
||||
--tw-translate-x: -25%;
|
||||
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));
|
||||
@ -1002,6 +1074,11 @@ body {
|
||||
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-1\/2 {
|
||||
--tw-translate-y: -50%;
|
||||
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-full {
|
||||
--tw-translate-y: -100%;
|
||||
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));
|
||||
@ -1012,16 +1089,6 @@ body {
|
||||
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-x-0\.5 {
|
||||
--tw-translate-x: 0.125rem;
|
||||
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-x-\[18px\] {
|
||||
--tw-translate-x: 18px;
|
||||
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-x-full {
|
||||
--tw-translate-x: 100%;
|
||||
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));
|
||||
@ -1042,11 +1109,6 @@ body {
|
||||
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-px {
|
||||
--tw-translate-y: 1px;
|
||||
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));
|
||||
}
|
||||
|
||||
.scale-100 {
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
@ -1077,6 +1139,10 @@ body {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.resize {
|
||||
resize: both;
|
||||
}
|
||||
|
||||
.list-decimal {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
@ -1196,10 +1262,10 @@ body {
|
||||
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
|
||||
}
|
||||
|
||||
.space-y-6 > :not([hidden]) ~ :not([hidden]) {
|
||||
.space-y-8 > :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));
|
||||
margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse)));
|
||||
margin-bottom: calc(2rem * var(--tw-space-y-reverse));
|
||||
}
|
||||
|
||||
.divide-y > :not([hidden]) ~ :not([hidden]) {
|
||||
@ -1281,11 +1347,6 @@ body {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.border-blue-500 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(59 130 246 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-border {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: hsl(var(--border) / var(--tw-border-opacity));
|
||||
@ -1358,11 +1419,6 @@ body {
|
||||
background-color: hsl(var(--muted) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-muted-foreground {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--muted-foreground) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-muted\/50 {
|
||||
background-color: hsl(var(--muted) / 0.5);
|
||||
}
|
||||
@ -1475,11 +1531,6 @@ body {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
.py-0\.5 {
|
||||
padding-top: 0.125rem;
|
||||
padding-bottom: 0.125rem;
|
||||
}
|
||||
|
||||
.py-1 {
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
@ -1735,10 +1786,6 @@ body {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.opacity-50 {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.opacity-80 {
|
||||
opacity: 0.8;
|
||||
}
|
||||
@ -1755,12 +1802,6 @@ body {
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
.shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
.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);
|
||||
@ -1796,6 +1837,11 @@ body {
|
||||
--tw-ring-offset-color: hsl(var(--background) / 1);
|
||||
}
|
||||
|
||||
.blur {
|
||||
--tw-blur: blur(8px);
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||
}
|
||||
|
||||
.filter {
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||
}
|
||||
@ -1900,6 +1946,107 @@ body {
|
||||
color: hsl(var(--muted-foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.before\:absolute::before {
|
||||
content: var(--tw-content);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.before\:inset-0::before {
|
||||
content: var(--tw-content);
|
||||
inset: 0px;
|
||||
}
|
||||
|
||||
.before\:left-1\/2::before {
|
||||
content: var(--tw-content);
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.before\:top-1\/2::before {
|
||||
content: var(--tw-content);
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.before\:h-1\.5::before {
|
||||
content: var(--tw-content);
|
||||
height: 0.375rem;
|
||||
}
|
||||
|
||||
.before\:w-1\.5::before {
|
||||
content: var(--tw-content);
|
||||
width: 0.375rem;
|
||||
}
|
||||
|
||||
.before\:-translate-x-1\/2::before {
|
||||
content: var(--tw-content);
|
||||
--tw-translate-x: -50%;
|
||||
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));
|
||||
}
|
||||
|
||||
.before\:-translate-y-1\/2::before {
|
||||
content: var(--tw-content);
|
||||
--tw-translate-y: -50%;
|
||||
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));
|
||||
}
|
||||
|
||||
.before\:rounded-full::before {
|
||||
content: var(--tw-content);
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.before\:bg-background::before {
|
||||
content: var(--tw-content);
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--background) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.after\:absolute::after {
|
||||
content: var(--tw-content);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.after\:left-0\.5::after {
|
||||
content: var(--tw-content);
|
||||
left: 0.125rem;
|
||||
}
|
||||
|
||||
.after\:top-0\.5::after {
|
||||
content: var(--tw-content);
|
||||
top: 0.125rem;
|
||||
}
|
||||
|
||||
.after\:h-5::after {
|
||||
content: var(--tw-content);
|
||||
height: 1.25rem;
|
||||
}
|
||||
|
||||
.after\:w-5::after {
|
||||
content: var(--tw-content);
|
||||
width: 1.25rem;
|
||||
}
|
||||
|
||||
.after\:rounded-full::after {
|
||||
content: var(--tw-content);
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.after\:bg-muted-foreground::after {
|
||||
content: var(--tw-content);
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--muted-foreground) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.after\:transition-all::after {
|
||||
content: var(--tw-content);
|
||||
transition-property: all;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.after\:content-\[\'\'\]::after {
|
||||
--tw-content: '';
|
||||
content: var(--tw-content);
|
||||
}
|
||||
|
||||
.checked\:border-primary:checked {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: hsl(var(--primary) / var(--tw-border-opacity));
|
||||
@ -1910,6 +2057,17 @@ body {
|
||||
background-color: hsl(var(--primary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.checked\:before\:visible:checked::before {
|
||||
content: var(--tw-content);
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.checked\:before\:bg-primary:checked::before {
|
||||
content: var(--tw-content);
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--primary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-accent:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--accent) / var(--tw-bg-opacity));
|
||||
@ -1993,6 +2151,22 @@ body {
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.focus\:outline:focus {
|
||||
outline-style: solid;
|
||||
}
|
||||
|
||||
.focus\:outline-2:focus {
|
||||
outline-width: 2px;
|
||||
}
|
||||
|
||||
.focus\:outline-offset-2:focus {
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.focus\:outline-ring:focus {
|
||||
outline-color: hsl(var(--ring) / 1);
|
||||
}
|
||||
|
||||
.focus\:ring-2:focus {
|
||||
--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);
|
||||
@ -2008,6 +2182,19 @@ body {
|
||||
--tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity));
|
||||
}
|
||||
|
||||
.focus\:ring-ring:focus {
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: hsl(var(--ring) / var(--tw-ring-opacity));
|
||||
}
|
||||
|
||||
.focus\:ring-offset-2:focus {
|
||||
--tw-ring-offset-width: 2px;
|
||||
}
|
||||
|
||||
.checked\:focus\:outline-primary:focus:checked {
|
||||
outline-color: hsl(var(--primary) / 1);
|
||||
}
|
||||
|
||||
.focus-visible\:outline-none:focus-visible {
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 2px;
|
||||
@ -2034,6 +2221,14 @@ body {
|
||||
--tw-ring-offset-width: 2px;
|
||||
}
|
||||
|
||||
.focus-visible\:ring-offset-background:focus-visible {
|
||||
--tw-ring-offset-color: hsl(var(--background) / 1);
|
||||
}
|
||||
|
||||
.active\:outline-offset-0:active {
|
||||
outline-offset: 0px;
|
||||
}
|
||||
|
||||
.disabled\:pointer-events-none:disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
@ -2064,24 +2259,30 @@ body {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.peer:checked ~ .peer-checked\:visible {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.peer:checked ~ .peer-checked\:bg-primary {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--primary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.peer:focus-visible ~ .peer-focus-visible\:ring-2 {
|
||||
--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);
|
||||
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||
.peer:checked ~ .peer-checked\:text-foreground {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.peer:focus-visible ~ .peer-focus-visible\:ring-ring {
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: hsl(var(--ring) / var(--tw-ring-opacity));
|
||||
.peer:checked ~ .peer-checked\:after\:translate-x-\[16px\]::after {
|
||||
content: var(--tw-content);
|
||||
--tw-translate-x: 16px;
|
||||
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));
|
||||
}
|
||||
|
||||
.peer:focus-visible ~ .peer-focus-visible\:ring-offset-2 {
|
||||
--tw-ring-offset-width: 2px;
|
||||
.peer:checked ~ .peer-checked\:after\:bg-secondary::after {
|
||||
content: var(--tw-content);
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--secondary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.peer:disabled ~ .peer-disabled\:cursor-not-allowed {
|
||||
@ -2273,6 +2474,70 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.\[\&\:\:-moz-range-thumb\]\:h-4::-moz-range-thumb {
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.\[\&\:\:-moz-range-thumb\]\:w-4::-moz-range-thumb {
|
||||
width: 1rem;
|
||||
}
|
||||
|
||||
.\[\&\:\:-moz-range-thumb\]\:rounded-full::-moz-range-thumb {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.\[\&\:\:-moz-range-thumb\]\:border-0::-moz-range-thumb {
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.\[\&\:\:-moz-range-thumb\]\:bg-primary::-moz-range-thumb {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--primary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.\[\&\:\:-moz-range-thumb\]\:hover\:bg-primary\/90:hover::-moz-range-thumb {
|
||||
background-color: hsl(var(--primary) / 0.9);
|
||||
}
|
||||
|
||||
.\[\&\:\:-webkit-slider-thumb\]\:h-4::-webkit-slider-thumb {
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.\[\&\:\:-webkit-slider-thumb\]\:w-4::-webkit-slider-thumb {
|
||||
width: 1rem;
|
||||
}
|
||||
|
||||
.\[\&\:\:-webkit-slider-thumb\]\:appearance-none::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.\[\&\:\:-webkit-slider-thumb\]\:rounded-full::-webkit-slider-thumb {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.\[\&\:\:-webkit-slider-thumb\]\:bg-primary::-webkit-slider-thumb {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--primary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.\[\&\:\:-webkit-slider-thumb\]\:hover\:bg-primary\/90:hover::-webkit-slider-thumb {
|
||||
background-color: hsl(var(--primary) / 0.9);
|
||||
}
|
||||
|
||||
.\[\&\:has\(input\:checked\)\]\:text-foreground:has(input:checked) {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.\[\&\:has\(input\:disabled\)\]\:cursor-not-allowed:has(input:disabled) {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.\[\&\:has\(input\:disabled\)\]\:opacity-50:has(input:disabled) {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.\[\&\:has\(svg\)\]\:pl-11:has(svg) {
|
||||
padding-left: 2.75rem;
|
||||
}
|
||||
|
@ -35,8 +35,11 @@ func main() {
|
||||
mux.Handle("GET /docs/components/input", templ.Handler(pages.Input()))
|
||||
mux.Handle("GET /docs/components/modal", templ.Handler(pages.Modal()))
|
||||
mux.Handle("GET /docs/components/radio-group", templ.Handler(pages.RadioGroup()))
|
||||
mux.Handle("GET /docs/components/select", templ.Handler(pages.Select()))
|
||||
mux.Handle("GET /docs/components/sheet", templ.Handler(pages.Sheet()))
|
||||
mux.Handle("GET /docs/components/slider", templ.Handler(pages.Slider()))
|
||||
mux.Handle("GET /docs/components/tabs", templ.Handler(pages.Tabs()))
|
||||
mux.Handle("GET /docs/components/textarea", templ.Handler(pages.Textarea()))
|
||||
mux.Handle("GET /docs/components/toggle", templ.Handler(pages.Toggle()))
|
||||
|
||||
fmt.Println("Server is running on http://localhost:8090")
|
||||
|
@ -81,14 +81,26 @@ var Sections = []Section{
|
||||
Text: "Radio Group",
|
||||
Href: "/docs/components/radio-group",
|
||||
},
|
||||
{
|
||||
Text: "Select",
|
||||
Href: "/docs/components/select",
|
||||
},
|
||||
{
|
||||
Text: "Sheet",
|
||||
Href: "/docs/components/sheet",
|
||||
},
|
||||
{
|
||||
Text: "Slider",
|
||||
Href: "/docs/components/slider",
|
||||
},
|
||||
{
|
||||
Text: "Tabs",
|
||||
Href: "/docs/components/tabs",
|
||||
},
|
||||
{
|
||||
Text: "Textarea",
|
||||
Href: "/docs/components/textarea",
|
||||
},
|
||||
{
|
||||
Text: "Toggle",
|
||||
Href: "/docs/components/toggle",
|
||||
|
@ -60,7 +60,6 @@ templ BaseLayout() {
|
||||
class="h-full flex flex-col transition-colors duration-200"
|
||||
:class="{'bg-white text-black': appTheme === 'light', 'text-white': appTheme === 'dark'}"
|
||||
>
|
||||
<div class="page-loader">Loading...</div>
|
||||
<div class="flex flex-col min-h-screen">
|
||||
{ children... }
|
||||
</div>
|
||||
|
41
internals/ui/pages/select.templ
Normal file
41
internals/ui/pages/select.templ
Normal file
@ -0,0 +1,41 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"github.com/axzilla/goilerplate/internals/ui/layouts"
|
||||
"github.com/axzilla/goilerplate/internals/ui/showcase"
|
||||
"github.com/axzilla/goilerplate/pkg/components"
|
||||
)
|
||||
|
||||
templ Select() {
|
||||
@layouts.DocsLayout() {
|
||||
<div>
|
||||
<div class="mb-16">
|
||||
<h1 class="text-3xl font-bold mb-2">Select</h1>
|
||||
<p class="mb-4 text-muted-foreground">
|
||||
A dropdown menu for selecting a single value from a list of options.
|
||||
</p>
|
||||
</div>
|
||||
@components.Tabs(components.TabsProps{
|
||||
Tabs: []components.Tab{
|
||||
{
|
||||
ID: "preview",
|
||||
Title: "Preview",
|
||||
Content: showcase.SelectShowcase(),
|
||||
},
|
||||
{
|
||||
ID: "code",
|
||||
Title: "Code",
|
||||
Content: CodeSnippetFromEmbedded("select.templ", "go", showcase.TemplFiles),
|
||||
},
|
||||
{
|
||||
ID: "component",
|
||||
Title: "Component",
|
||||
Content: CodeSnippetFromEmbedded("select.templ", "go", components.TemplFiles),
|
||||
},
|
||||
},
|
||||
TabsContainerClass: "md:w-1/2",
|
||||
ContentContainerClass: "w-full",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
}
|
39
internals/ui/pages/slider.templ
Normal file
39
internals/ui/pages/slider.templ
Normal file
@ -0,0 +1,39 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"github.com/axzilla/goilerplate/internals/ui/layouts"
|
||||
"github.com/axzilla/goilerplate/internals/ui/showcase"
|
||||
"github.com/axzilla/goilerplate/pkg/components"
|
||||
)
|
||||
|
||||
templ Slider() {
|
||||
@layouts.DocsLayout() {
|
||||
<div>
|
||||
<div class="mb-16">
|
||||
<h1 class="text-3xl font-bold mb-2">Slider</h1>
|
||||
<p class="mb-4 text-muted-foreground">An input where the user selects a value from within a given range.</p>
|
||||
</div>
|
||||
@components.Tabs(components.TabsProps{
|
||||
Tabs: []components.Tab{
|
||||
{
|
||||
ID: "preview",
|
||||
Title: "Preview",
|
||||
Content: showcase.SliderShowcase(),
|
||||
},
|
||||
{
|
||||
ID: "code",
|
||||
Title: "Code",
|
||||
Content: CodeSnippetFromEmbedded("slider.templ", "go", showcase.TemplFiles),
|
||||
},
|
||||
{
|
||||
ID: "component",
|
||||
Title: "Component",
|
||||
Content: CodeSnippetFromEmbedded("slider.templ", "go", components.TemplFiles),
|
||||
},
|
||||
},
|
||||
TabsContainerClass: "md:w-1/2",
|
||||
ContentContainerClass: "w-full",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
}
|
39
internals/ui/pages/textarea.templ
Normal file
39
internals/ui/pages/textarea.templ
Normal file
@ -0,0 +1,39 @@
|
||||
package pages
|
||||
|
||||
import (
|
||||
"github.com/axzilla/goilerplate/internals/ui/layouts"
|
||||
"github.com/axzilla/goilerplate/internals/ui/showcase"
|
||||
"github.com/axzilla/goilerplate/pkg/components"
|
||||
)
|
||||
|
||||
templ Textarea() {
|
||||
@layouts.DocsLayout() {
|
||||
<div>
|
||||
<div class="mb-16">
|
||||
<h1 class="text-3xl font-bold mb-2">Textarea</h1>
|
||||
<p class="mb-4 text-muted-foreground">A multi-line text input field that allows users to enter longer text content.</p>
|
||||
</div>
|
||||
@components.Tabs(components.TabsProps{
|
||||
Tabs: []components.Tab{
|
||||
{
|
||||
ID: "preview",
|
||||
Title: "Preview",
|
||||
Content: showcase.TextareaShowcase(),
|
||||
},
|
||||
{
|
||||
ID: "code",
|
||||
Title: "Code",
|
||||
Content: CodeSnippetFromEmbedded("textarea.templ", "go", showcase.TemplFiles),
|
||||
},
|
||||
{
|
||||
ID: "component",
|
||||
Title: "Component",
|
||||
Content: CodeSnippetFromEmbedded("textarea.templ", "go", components.TemplFiles),
|
||||
},
|
||||
},
|
||||
TabsContainerClass: "md:w-1/2",
|
||||
ContentContainerClass: "w-full",
|
||||
})
|
||||
</div>
|
||||
}
|
||||
}
|
@ -1,5 +1,3 @@
|
||||
// internals/ui/pages/theme_customizer.templ
|
||||
|
||||
package pages
|
||||
|
||||
import (
|
||||
@ -70,7 +68,7 @@ templ ThemePreview() {
|
||||
@components.Input(components.InputProps{
|
||||
ID: "username",
|
||||
Name: "username",
|
||||
Type: components.Text,
|
||||
Type: components.InputTypeText,
|
||||
Placeholder: "Enter your username",
|
||||
})
|
||||
</div>
|
||||
@ -79,7 +77,7 @@ templ ThemePreview() {
|
||||
@components.Input(components.InputProps{
|
||||
ID: "email",
|
||||
Name: "email",
|
||||
Type: components.Email,
|
||||
Type: components.InputTypeEmail,
|
||||
Placeholder: "Enter your email",
|
||||
})
|
||||
</div>
|
||||
@ -88,7 +86,7 @@ templ ThemePreview() {
|
||||
@components.Input(components.InputProps{
|
||||
ID: "password",
|
||||
Name: "password",
|
||||
Type: components.Password,
|
||||
Type: components.InputTypePassword,
|
||||
Placeholder: "Enter your password",
|
||||
})
|
||||
</div>
|
||||
@ -103,28 +101,26 @@ templ ThemePreview() {
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="text-sm font-medium">Preferred Contact Method</label>
|
||||
@components.RadioGroup(components.RadioGroupProps{DefaultValue: "email", Name: "contact-method"}) {
|
||||
<div class="space-y-2">
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "email",
|
||||
ID: "contact-email",
|
||||
Name: "contact-method",
|
||||
Label: templ.Raw("Email"),
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "phone",
|
||||
ID: "contact-phone",
|
||||
Name: "contact-method",
|
||||
Label: templ.Raw("Phone"),
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "mail",
|
||||
ID: "contact-mail",
|
||||
Name: "contact-method",
|
||||
Label: templ.Raw("Physical Mail"),
|
||||
Disabled: "true",
|
||||
})
|
||||
</div>
|
||||
@components.RadioGroup(components.RadioGroupProps{Name: "contact-method"}) {
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "email",
|
||||
ID: "contact-email",
|
||||
Name: "contact-method",
|
||||
Label: templ.Raw("Email"),
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "phone",
|
||||
ID: "contact-phone",
|
||||
Name: "contact-method",
|
||||
Label: templ.Raw("Phone"),
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "mail",
|
||||
ID: "contact-mail",
|
||||
Name: "contact-method",
|
||||
Label: templ.Raw("Physical Mail"),
|
||||
Attributes: templ.Attributes{"disabled": "true"},
|
||||
})
|
||||
}
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
@ -141,7 +137,7 @@ templ ThemePreview() {
|
||||
ID: "notifications",
|
||||
Name: "notifications",
|
||||
LabelRight: "Enable notifications",
|
||||
Checked: "true",
|
||||
Attributes: templ.Attributes{"checked": "true"},
|
||||
})
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
@ -149,7 +145,7 @@ templ ThemePreview() {
|
||||
ID: "beta",
|
||||
Name: "beta",
|
||||
LabelRight: "Join beta program",
|
||||
Disabled: "true",
|
||||
Attributes: templ.Attributes{"disabled": "true"},
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,32 +17,31 @@ templ CheckboxShowcase() {
|
||||
<div class="mb-8">
|
||||
<h2 class="font-semibold mb-2">Checked Checkbox</h2>
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
ID: "checked-checkbox",
|
||||
Name: "newsletter",
|
||||
Value: "subscribe",
|
||||
Label: "Receive newsletter",
|
||||
Checked: "true",
|
||||
ID: "checked-checkbox",
|
||||
Name: "newsletter",
|
||||
Value: "subscribe",
|
||||
Label: "Receive newsletter",
|
||||
Attributes: templ.Attributes{"checked": "true"},
|
||||
})
|
||||
</div>
|
||||
<div class="mb-8">
|
||||
<h2 class="font-semibold mb-2">Disabled Checkbox</h2>
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
ID: "disabled-checkbox",
|
||||
Name: "disabled",
|
||||
Value: "disabled",
|
||||
Label: "Disabled option",
|
||||
Disabled: "true",
|
||||
ID: "disabled-checkbox",
|
||||
Name: "disabled",
|
||||
Value: "disabled",
|
||||
Label: "Disabled option",
|
||||
Attributes: templ.Attributes{"disabled": "true"},
|
||||
})
|
||||
</div>
|
||||
<div class="mb-8">
|
||||
<h2 class="font-semibold mb-2">Disabled Checked Checkbox</h2>
|
||||
@components.Checkbox(components.CheckboxProps{
|
||||
ID: "disabled-checked-checkbox",
|
||||
Name: "disabled-checked",
|
||||
Value: "disabled-checked",
|
||||
Label: "Disabled checked option",
|
||||
Checked: "true",
|
||||
Disabled: "true",
|
||||
ID: "disabled-checked-checkbox",
|
||||
Name: "disabled-checked",
|
||||
Value: "disabled-checked",
|
||||
Label: "Disabled checked option",
|
||||
Attributes: templ.Attributes{"checked": "true", "disabled": "true"},
|
||||
})
|
||||
</div>
|
||||
<div class="mb-8">
|
||||
|
@ -7,9 +7,15 @@ templ InputShowcase() {
|
||||
<div>
|
||||
<div class="mb-8">
|
||||
<h2 class="font-semibold mb-2">Default</h2>
|
||||
@components.Input(components.InputProps{
|
||||
Type: "email",
|
||||
})
|
||||
</div>
|
||||
<div class="mb-8">
|
||||
<h2 class="font-semibold mb-2">With Placeholder</h2>
|
||||
@components.Input(components.InputProps{
|
||||
Type: "email",
|
||||
Placeholder: "Email",
|
||||
Placeholder: "e.g. john@doe.com",
|
||||
})
|
||||
</div>
|
||||
<div class="mb-8">
|
||||
@ -23,54 +29,45 @@ templ InputShowcase() {
|
||||
<div class="mb-8">
|
||||
<h2 class="font-semibold mb-2">Disabled</h2>
|
||||
@components.Input(components.InputProps{
|
||||
Type: "email",
|
||||
Placeholder: "Email",
|
||||
Disabled: "true",
|
||||
Type: "email",
|
||||
Attributes: templ.Attributes{"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",
|
||||
ID: "email",
|
||||
Type: "email",
|
||||
Label: "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>
|
||||
<h2 class="font-semibold mb-2">With Description</h2>
|
||||
@components.Input(components.InputProps{
|
||||
ID: "email",
|
||||
Type: "email",
|
||||
Description: "This is your accounts email address.",
|
||||
})
|
||||
</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",
|
||||
})
|
||||
<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>
|
||||
<h2 class="font-semibold mb-2">With Error</h2>
|
||||
@components.Input(components.InputProps{
|
||||
ID: "username",
|
||||
Error: "Username must be more then 2 characters",
|
||||
})
|
||||
</div>
|
||||
<div class="mb-8">
|
||||
<h2 class="font-semibold mb-2">Advanced</h2>
|
||||
@components.Input(components.InputProps{
|
||||
ID: "username",
|
||||
Label: "Username",
|
||||
Placeholder: "e.g. john123",
|
||||
Description: "This is your public display name.",
|
||||
Value: "",
|
||||
Error: "Username must be more then 2 characters",
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,35 +1,30 @@
|
||||
package showcase
|
||||
|
||||
import (
|
||||
"github.com/axzilla/goilerplate/pkg/components"
|
||||
)
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ RadioGroupShowcase() {
|
||||
<div class="flex justify-center items-center border rounded-md py-16 px-4">
|
||||
<div>
|
||||
@components.RadioGroup(components.RadioGroupProps{DefaultValue: "comfortable", Name: "view-mode"}) {
|
||||
<div class="space-y-2">
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "default",
|
||||
ID: "r1",
|
||||
Name: "view-mode",
|
||||
Label: templ.Raw("Default"),
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "comfortable",
|
||||
ID: "r2",
|
||||
Name: "view-mode",
|
||||
Disabled: "true",
|
||||
Label: templ.Raw("Comfortable"),
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "compact",
|
||||
ID: "r3",
|
||||
Name: "view-mode",
|
||||
Label: templ.Raw("Compact"),
|
||||
})
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@components.RadioGroup(components.RadioGroupProps{}) {
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "default",
|
||||
ID: "r1",
|
||||
Name: "view-mode",
|
||||
Label: templ.Raw("Default"),
|
||||
Attributes: templ.Attributes{"checked": true},
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "comfortable",
|
||||
ID: "r2",
|
||||
Name: "view-mode",
|
||||
Label: templ.Raw("Disabled"),
|
||||
Attributes: templ.Attributes{"disabled": true},
|
||||
})
|
||||
@components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
Value: "compact",
|
||||
ID: "r3",
|
||||
Name: "view-mode",
|
||||
Label: templ.Raw("Compact"),
|
||||
})
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
66
internals/ui/showcase/select.templ
Normal file
66
internals/ui/showcase/select.templ
Normal file
@ -0,0 +1,66 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
var xxx = "banana"
|
||||
|
||||
templ SelectShowcase() {
|
||||
<div class="flex justify-center items-center border rounded-md py-16 px-4">
|
||||
<div class="w-full max-w-xs space-y-8">
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">Default Select</h2>
|
||||
@components.Select(components.SelectProps{
|
||||
ID: "fruit",
|
||||
Name: "fruit",
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Apple", Value: "apple"},
|
||||
{Label: "Banana", Value: "banana"},
|
||||
{Label: "Orange", Value: "orange"},
|
||||
{Label: "Mango", Value: "mango"},
|
||||
},
|
||||
})
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">With Placeholder</h2>
|
||||
@components.Select(components.SelectProps{
|
||||
ID: "fruit",
|
||||
Name: "fruit",
|
||||
Placeholder: "Select a fruit",
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Apple", Value: "apple"},
|
||||
{Label: "Banana", Value: "banana"},
|
||||
{Label: "Orange", Value: "orange"},
|
||||
{Label: "Mango", Value: "mango"},
|
||||
},
|
||||
})
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">Selected Value</h2>
|
||||
@components.Select(components.SelectProps{
|
||||
ID: "selected",
|
||||
Name: "selected",
|
||||
Placeholder: "Select a fruit",
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Apple", Value: "apple"},
|
||||
{Label: "Banana", Value: "banana"},
|
||||
{Label: "Orange", Value: "orange", Attributes: templ.Attributes{"selected": true}},
|
||||
{Label: "Mango", Value: "mango"},
|
||||
},
|
||||
})
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">Disabled Select</h2>
|
||||
@components.Select(components.SelectProps{
|
||||
ID: "disabled",
|
||||
Name: "disabled",
|
||||
Placeholder: "Select is disabled",
|
||||
Attributes: templ.Attributes{":disabled": "true"},
|
||||
Options: []components.SelectOption{
|
||||
{Label: "Option 1", Value: "1"},
|
||||
{Label: "Option 2", Value: "2"},
|
||||
},
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
79
internals/ui/showcase/slider.templ
Normal file
79
internals/ui/showcase/slider.templ
Normal file
@ -0,0 +1,79 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ SliderShowcase() {
|
||||
<div class="flex justify-center items-center border rounded-md py-16 px-4">
|
||||
<div class="space-y-8 w-full max-w-lg">
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">Default Slider</h2>
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "default",
|
||||
Name: "default",
|
||||
Label: "Volume",
|
||||
Value: 50,
|
||||
Min: 0,
|
||||
Max: 100,
|
||||
Step: 1,
|
||||
ShowValue: true,
|
||||
})
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">With Label</h2>
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "with-label",
|
||||
Name: "with-label",
|
||||
Label: "Volume",
|
||||
Value: 75,
|
||||
Min: 0,
|
||||
Max: 100,
|
||||
Step: 1,
|
||||
ShowValue: true,
|
||||
ValueFormat: "%",
|
||||
})
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">Temperature Range</h2>
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "temperature",
|
||||
Name: "temperature",
|
||||
Label: "Temperature",
|
||||
Value: 23,
|
||||
Min: -20,
|
||||
Max: 40,
|
||||
Step: 1,
|
||||
ShowValue: true,
|
||||
ValueFormat: "°C",
|
||||
})
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">Steps</h2>
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "steps",
|
||||
Name: "steps",
|
||||
Label: "Zoom Level",
|
||||
Value: 100,
|
||||
Min: 0,
|
||||
Max: 200,
|
||||
Step: 25,
|
||||
ShowValue: true,
|
||||
ValueFormat: "%",
|
||||
})
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">Disabled</h2>
|
||||
@components.Slider(components.SliderProps{
|
||||
ID: "disabled",
|
||||
Name: "disabled",
|
||||
Label: "Disabled Slider",
|
||||
Value: 20,
|
||||
Min: -20,
|
||||
Max: 200,
|
||||
Step: 20,
|
||||
Disabled: true,
|
||||
ShowValue: true,
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
@ -38,7 +38,7 @@ templ AccountTab() {
|
||||
<div class="space-y-1">
|
||||
<label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="name">Name</label>
|
||||
@components.Input(components.InputProps{
|
||||
Type: components.Text,
|
||||
Type: components.InputTypeText,
|
||||
Placeholder: "Name",
|
||||
ID: "name",
|
||||
Value: "John Doe",
|
||||
@ -47,7 +47,7 @@ templ AccountTab() {
|
||||
<div class="space-y-1">
|
||||
<label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for="username">Username</label>
|
||||
@components.Input(components.InputProps{
|
||||
Type: components.Text,
|
||||
Type: components.InputTypeText,
|
||||
Placeholder: "Username",
|
||||
ID: "username",
|
||||
Value: "@johndoe",
|
||||
@ -78,7 +78,7 @@ templ PasswordTab() {
|
||||
Current Password
|
||||
</label>
|
||||
@components.Input(components.InputProps{
|
||||
Type: components.Password,
|
||||
Type: components.InputTypePassword,
|
||||
Placeholder: "Current Password",
|
||||
ID: "current_password",
|
||||
})
|
||||
@ -88,7 +88,7 @@ templ PasswordTab() {
|
||||
New Password
|
||||
</label>
|
||||
@components.Input(components.InputProps{
|
||||
Type: components.Password,
|
||||
Type: components.InputTypePassword,
|
||||
Placeholder: "New Password",
|
||||
ID: "new_password",
|
||||
})
|
||||
|
71
internals/ui/showcase/textarea.templ
Normal file
71
internals/ui/showcase/textarea.templ
Normal file
@ -0,0 +1,71 @@
|
||||
package showcase
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/components"
|
||||
|
||||
templ TextareaShowcase() {
|
||||
<div class="flex justify-center items-center border rounded-md py-16 px-4">
|
||||
<div class="space-y-8 w-full max-w-lg">
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">Default Textarea (3 rows)</h2>
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "default",
|
||||
Name: "default",
|
||||
Placeholder: "Type your message here.",
|
||||
})
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">Tall Textarea (6 rows)</h2>
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "tall",
|
||||
Name: "tall",
|
||||
Placeholder: "Type your message here.",
|
||||
Rows: 6,
|
||||
})
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">With Label & Description</h2>
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "with-label",
|
||||
Name: "with-label",
|
||||
Label: "Your Message",
|
||||
Description: "Write a detailed description of your request.",
|
||||
Placeholder: "Type your message here.",
|
||||
Rows: 4,
|
||||
})
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">With Error</h2>
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "with-error",
|
||||
Name: "with-error",
|
||||
Label: "Your Message",
|
||||
Error: "Message is required",
|
||||
Placeholder: "Type your message here.",
|
||||
})
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">Auto-resize</h2>
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "auto-resize",
|
||||
Name: "auto-resize",
|
||||
Label: "Auto-resizing Textarea",
|
||||
Description: "This textarea will grow as you type.",
|
||||
Placeholder: "Start typing to see the magic...",
|
||||
Rows: 3,
|
||||
AutoResize: true,
|
||||
})
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">Disabled</h2>
|
||||
@components.Textarea(components.TextareaProps{
|
||||
ID: "disabled",
|
||||
Name: "disabled",
|
||||
Label: "Disabled Textarea",
|
||||
Value: "This textarea is disabled",
|
||||
Rows: 3,
|
||||
Attributes: templ.Attributes{"disabled": "true"},
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
@ -29,25 +29,24 @@ templ ToggleShowcase() {
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold mb-4">States</h2>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex flex-col gap-2" x-data="{'xxx': ''}">
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "toggle-checked",
|
||||
Name: "toggle-checked",
|
||||
LabelRight: "Checked Toggle",
|
||||
Checked: "1+1==2",
|
||||
Attributes: templ.Attributes{"x-bind:checked": "true"},
|
||||
})
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "toggle-disabled",
|
||||
Name: "toggle-disabled",
|
||||
LabelRight: "Disabled Toggle",
|
||||
Disabled: "true",
|
||||
Attributes: templ.Attributes{"disabled": "true"},
|
||||
})
|
||||
@components.Toggle(components.ToggleProps{
|
||||
ID: "toggle-disabled-checked",
|
||||
Name: "toggle-disabled-checked",
|
||||
LabelRight: "Disabled Checked Toggle",
|
||||
Disabled: "true",
|
||||
Checked: "true",
|
||||
Attributes: templ.Attributes{"checked": "true", "disabled": true},
|
||||
})
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,61 +5,37 @@ import (
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
|
||||
// AccordionItem represents a single item in the Accordion component.
|
||||
type AccordionItem struct {
|
||||
// ID is the unique identifier for the accordion item.
|
||||
// It is used to manage the open/closed state of the item.
|
||||
// ID is the unique identifier for managing accordion item state
|
||||
ID string
|
||||
|
||||
// Trigger is the content of the accordion item's header/trigger.
|
||||
// This is typically text, but can be any templ.Component.
|
||||
// Trigger is the content shown in the header/trigger area
|
||||
// Can be any templ.Component (typically text)
|
||||
Trigger templ.Component
|
||||
|
||||
// Content is the expandable content of the accordion item.
|
||||
// This can be any templ.Component.
|
||||
// Content is the expandable content section
|
||||
// Can be any templ.Component
|
||||
Content templ.Component
|
||||
}
|
||||
|
||||
// AccordionProps defines the properties for the Accordion component.
|
||||
type AccordionProps struct {
|
||||
// Items is a slice of AccordionItem structs representing each item in the accordion.
|
||||
// Items contains the accordion sections
|
||||
Items []AccordionItem
|
||||
|
||||
// Class specifies additional CSS classes to apply to the accordion container.
|
||||
// Default: "" (empty string)
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the accordion container element.
|
||||
// Default: nil
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Accordion renders an accordion component based on the provided props.
|
||||
// It uses Alpine.js for interactivity and state management.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Accordion(components.AccordionProps{
|
||||
// Items: []components.AccordionItem{
|
||||
// {
|
||||
// ID: "item-1",
|
||||
// Trigger: templ.Raw("Is it accessible?"),
|
||||
// Content: templ.Raw("Yes. It adheres to the WAI-ARIA design pattern."),
|
||||
// },
|
||||
// {
|
||||
// ID: "item-2",
|
||||
// Trigger: templ.Raw("Is it styled?"),
|
||||
// Content: templ.Raw("Yes. It comes with default styles that match the other components' aesthetic."),
|
||||
// },
|
||||
// },
|
||||
// Class: "w-full sm:max-w-[70%]",
|
||||
// Attributes: templ.Attributes{"data-testid": "my-accordion"},
|
||||
// })
|
||||
// Accordion renders a collapsible content section component with expand/collapse functionality.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/accordion
|
||||
//
|
||||
// Props:
|
||||
// - Items: A slice of AccordionItem structs, each representing an item in the accordion.
|
||||
// - Class: Additional CSS classes to apply to the accordion container. Default: "" (empty string)
|
||||
// - Attributes: Additional HTML attributes to apply to the accordion container element. Default: nil
|
||||
// - Items: Array of accordion sections with ID, trigger and content
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes (e.g. data-testid)
|
||||
templ Accordion(props AccordionProps) {
|
||||
<div
|
||||
x-data="{
|
||||
|
@ -13,61 +13,37 @@ import (
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
|
||||
// AccordionItem represents a single item in the Accordion component.
|
||||
type AccordionItem struct {
|
||||
// ID is the unique identifier for the accordion item.
|
||||
// It is used to manage the open/closed state of the item.
|
||||
// ID is the unique identifier for managing accordion item state
|
||||
ID string
|
||||
|
||||
// Trigger is the content of the accordion item's header/trigger.
|
||||
// This is typically text, but can be any templ.Component.
|
||||
// Trigger is the content shown in the header/trigger area
|
||||
// Can be any templ.Component (typically text)
|
||||
Trigger templ.Component
|
||||
|
||||
// Content is the expandable content of the accordion item.
|
||||
// This can be any templ.Component.
|
||||
// Content is the expandable content section
|
||||
// Can be any templ.Component
|
||||
Content templ.Component
|
||||
}
|
||||
|
||||
// AccordionProps defines the properties for the Accordion component.
|
||||
type AccordionProps struct {
|
||||
// Items is a slice of AccordionItem structs representing each item in the accordion.
|
||||
// Items contains the accordion sections
|
||||
Items []AccordionItem
|
||||
|
||||
// Class specifies additional CSS classes to apply to the accordion container.
|
||||
// Default: "" (empty string)
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the accordion container element.
|
||||
// Default: nil
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Accordion renders an accordion component based on the provided props.
|
||||
// It uses Alpine.js for interactivity and state management.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Accordion(components.AccordionProps{
|
||||
// Items: []components.AccordionItem{
|
||||
// {
|
||||
// ID: "item-1",
|
||||
// Trigger: templ.Raw("Is it accessible?"),
|
||||
// Content: templ.Raw("Yes. It adheres to the WAI-ARIA design pattern."),
|
||||
// },
|
||||
// {
|
||||
// ID: "item-2",
|
||||
// Trigger: templ.Raw("Is it styled?"),
|
||||
// Content: templ.Raw("Yes. It comes with default styles that match the other components' aesthetic."),
|
||||
// },
|
||||
// },
|
||||
// Class: "w-full sm:max-w-[70%]",
|
||||
// Attributes: templ.Attributes{"data-testid": "my-accordion"},
|
||||
// })
|
||||
// Accordion renders a collapsible content section component with expand/collapse functionality.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/accordion
|
||||
//
|
||||
// Props:
|
||||
// - Items: A slice of AccordionItem structs, each representing an item in the accordion.
|
||||
// - Class: Additional CSS classes to apply to the accordion container. Default: "" (empty string)
|
||||
// - Attributes: Additional HTML attributes to apply to the accordion container element. Default: nil
|
||||
// - Items: Array of accordion sections with ID, trigger and content
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes (e.g. data-testid)
|
||||
func Accordion(props AccordionProps) templ.Component {
|
||||
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
|
||||
@ -127,7 +103,7 @@ func Accordion(props AccordionProps) templ.Component {
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs("toggleItem('" + item.ID + "')")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/accordion.templ`, Line: 79, Col: 46}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/accordion.templ`, Line: 55, Col: 46}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -140,7 +116,7 @@ func Accordion(props AccordionProps) templ.Component {
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs("activeItem === '" + item.ID + "'")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/accordion.templ`, Line: 81, Col: 57}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/accordion.templ`, Line: 57, Col: 57}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -165,7 +141,7 @@ func Accordion(props AccordionProps) templ.Component {
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs("activeItem === '" + item.ID + "'")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/accordion.templ`, Line: 88, Col: 48}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/accordion.templ`, Line: 64, Col: 48}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
@ -2,26 +2,26 @@ package components
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// AlertVariant represents the visual style of the alert.
|
||||
// AlertVariant defines the available alert styles
|
||||
type AlertVariant string
|
||||
|
||||
// Constants for alert variants.
|
||||
const (
|
||||
DefaultAlert AlertVariant = "default"
|
||||
// DefaultAlert shows standard informational styling
|
||||
DefaultAlert AlertVariant = "default"
|
||||
|
||||
// DestructiveAlert shows error/warning styling
|
||||
DestructiveAlert AlertVariant = "destructive"
|
||||
)
|
||||
|
||||
// AlertProps defines the properties for the Alert component.
|
||||
type AlertProps struct {
|
||||
// Variant determines the visual style of the alert.
|
||||
// Default: DefaultAlert
|
||||
// Variant controls the alert styling (default or destructive)
|
||||
Variant AlertVariant
|
||||
// Class specifies additional CSS classes to apply to the alert.
|
||||
// Default: "" (empty string)
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
}
|
||||
|
||||
// getAlertVariantClasses returns the CSS classes for the given alert variant.
|
||||
// getAlertVariantClasses maps variants to their CSS classes
|
||||
func getAlertVariantClasses(variant AlertVariant) string {
|
||||
switch variant {
|
||||
case DestructiveAlert:
|
||||
@ -31,21 +31,12 @@ func getAlertVariantClasses(variant AlertVariant) string {
|
||||
}
|
||||
}
|
||||
|
||||
// Alert renders an alert component based on the provided props and children.
|
||||
// It can be customized with two visual styles: Default and Destructive.
|
||||
// All content, including icons, should be passed in as children.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Alert(components.AlertProps{Variant: components.DestructiveAlert}) {
|
||||
// @components.ExclamationTriangleIcon()
|
||||
// @components.AlertTitle{"Error"}
|
||||
// @components.AlertDescription{"Your session has expired. Please log in again."}
|
||||
// }
|
||||
// Alert renders a notification box component for messages, warnings and errors.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/alert
|
||||
//
|
||||
// Props:
|
||||
// - Variant: The visual style of the alert (DefaultAlert or DestructiveAlert). Default: DefaultAlert
|
||||
// - Class: Additional CSS classes to apply to the alert. Default: "" (empty string)
|
||||
// - Variant: Visual style (DefaultAlert or DestructiveAlert)
|
||||
// - Class: Additional CSS classes
|
||||
templ Alert(props AlertProps) {
|
||||
<div
|
||||
class={
|
||||
|
@ -10,26 +10,26 @@ import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// AlertVariant represents the visual style of the alert.
|
||||
// AlertVariant defines the available alert styles
|
||||
type AlertVariant string
|
||||
|
||||
// Constants for alert variants.
|
||||
const (
|
||||
DefaultAlert AlertVariant = "default"
|
||||
// DefaultAlert shows standard informational styling
|
||||
DefaultAlert AlertVariant = "default"
|
||||
|
||||
// DestructiveAlert shows error/warning styling
|
||||
DestructiveAlert AlertVariant = "destructive"
|
||||
)
|
||||
|
||||
// AlertProps defines the properties for the Alert component.
|
||||
type AlertProps struct {
|
||||
// Variant determines the visual style of the alert.
|
||||
// Default: DefaultAlert
|
||||
// Variant controls the alert styling (default or destructive)
|
||||
Variant AlertVariant
|
||||
// Class specifies additional CSS classes to apply to the alert.
|
||||
// Default: "" (empty string)
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
}
|
||||
|
||||
// getAlertVariantClasses returns the CSS classes for the given alert variant.
|
||||
// getAlertVariantClasses maps variants to their CSS classes
|
||||
func getAlertVariantClasses(variant AlertVariant) string {
|
||||
switch variant {
|
||||
case DestructiveAlert:
|
||||
@ -39,21 +39,12 @@ func getAlertVariantClasses(variant AlertVariant) string {
|
||||
}
|
||||
}
|
||||
|
||||
// Alert renders an alert component based on the provided props and children.
|
||||
// It can be customized with two visual styles: Default and Destructive.
|
||||
// All content, including icons, should be passed in as children.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Alert(components.AlertProps{Variant: components.DestructiveAlert}) {
|
||||
// @components.ExclamationTriangleIcon()
|
||||
// @components.AlertTitle{"Error"}
|
||||
// @components.AlertDescription{"Your session has expired. Please log in again."}
|
||||
// }
|
||||
// Alert renders a notification box component for messages, warnings and errors.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/alert
|
||||
//
|
||||
// Props:
|
||||
// - Variant: The visual style of the alert (DefaultAlert or DestructiveAlert). Default: DefaultAlert
|
||||
// - Class: Additional CSS classes to apply to the alert. Default: "" (empty string)
|
||||
// - Variant: Visual style (DefaultAlert or DestructiveAlert)
|
||||
// - Class: Additional CSS classes
|
||||
func Alert(props AlertProps) templ.Component {
|
||||
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
|
||||
|
@ -6,36 +6,39 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// AvatarSize represents the size of the avatar.
|
||||
// AvatarSize defines the available avatar dimensions
|
||||
type AvatarSize string
|
||||
|
||||
const (
|
||||
AvatarSizeSmall AvatarSize = "small"
|
||||
// AvatarSizeSmall renders a small avatar (32x32px)
|
||||
AvatarSizeSmall AvatarSize = "small"
|
||||
|
||||
// AvatarSizeMedium renders a medium avatar (48x48px)
|
||||
AvatarSizeMedium AvatarSize = "medium"
|
||||
AvatarSizeLarge AvatarSize = "large"
|
||||
|
||||
// AvatarSizeLarge renders a large avatar (64x64px)
|
||||
AvatarSizeLarge AvatarSize = "large"
|
||||
)
|
||||
|
||||
// AvatarProps defines the properties for the Avatar component.
|
||||
type AvatarProps struct {
|
||||
// ImageSrc is the URL of the avatar image.
|
||||
// If empty, initials will be used.
|
||||
// ImageSrc is the URL for the avatar image
|
||||
// If empty, initials will be shown instead
|
||||
ImageSrc string
|
||||
|
||||
// Name is used to generate initials if ImageSrc is empty.
|
||||
// Name is used to generate initials when no image is provided
|
||||
Name string
|
||||
|
||||
// Size determines the size of the avatar.
|
||||
// Default: AvatarSizeMedium
|
||||
// Size controls the avatar dimensions (small, medium, large)
|
||||
Size AvatarSize
|
||||
|
||||
// Class specifies additional CSS classes to apply to the avatar.
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the avatar element.
|
||||
// Attributes for additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// getInitials generates initials from the given name.
|
||||
// AvatarInitials generates a 1-2 character initial from the given name
|
||||
func AvatarInitials(name string) string {
|
||||
parts := strings.Fields(name)
|
||||
initials := ""
|
||||
@ -50,7 +53,7 @@ func AvatarInitials(name string) string {
|
||||
return strings.ToUpper(initials)
|
||||
}
|
||||
|
||||
// getSizeClasses returns the CSS classes for the given avatar size.
|
||||
// AvatarSizeClasses maps sizes to their corresponding CSS classes
|
||||
func AvatarSizeClasses(size AvatarSize) string {
|
||||
switch size {
|
||||
case AvatarSizeSmall:
|
||||
@ -62,24 +65,15 @@ func AvatarSizeClasses(size AvatarSize) string {
|
||||
}
|
||||
}
|
||||
|
||||
// Avatar renders an avatar component based on the provided props.
|
||||
// It displays an image if ImageSrc is provided, otherwise it shows initials.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Avatar(components.AvatarProps{
|
||||
// ImageSrc: "https://example.com/avatar.jpg",
|
||||
// Name: "John Doe",
|
||||
// Size: components.AvatarSizeMedium,
|
||||
// Class: "border-2 border-blue-500",
|
||||
// })
|
||||
// Avatar renders a circular image or initials for user representation.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/avatar
|
||||
//
|
||||
// Props:
|
||||
// - ImageSrc: The URL of the avatar image. Default: "" (empty string)
|
||||
// - Name: The name used to generate initials if ImageSrc is empty. Default: "" (empty string)
|
||||
// - Size: The size of the avatar (AvatarSizeSmall, AvatarSizeMedium, AvatarSizeLarge). Default: AvatarSizeMedium
|
||||
// - Class: Additional CSS classes to apply to the avatar. Default: "" (empty string)
|
||||
// - Attributes: Additional HTML attributes to apply to the avatar element. Default: nil
|
||||
// - ImageSrc: URL for the avatar image
|
||||
// - Name: Text to generate initials from when no image is provided
|
||||
// - Size: Avatar dimensions (small, medium, large)
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
templ Avatar(props AvatarProps) {
|
||||
<div
|
||||
class={
|
||||
|
@ -14,36 +14,39 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// AvatarSize represents the size of the avatar.
|
||||
// AvatarSize defines the available avatar dimensions
|
||||
type AvatarSize string
|
||||
|
||||
const (
|
||||
AvatarSizeSmall AvatarSize = "small"
|
||||
// AvatarSizeSmall renders a small avatar (32x32px)
|
||||
AvatarSizeSmall AvatarSize = "small"
|
||||
|
||||
// AvatarSizeMedium renders a medium avatar (48x48px)
|
||||
AvatarSizeMedium AvatarSize = "medium"
|
||||
AvatarSizeLarge AvatarSize = "large"
|
||||
|
||||
// AvatarSizeLarge renders a large avatar (64x64px)
|
||||
AvatarSizeLarge AvatarSize = "large"
|
||||
)
|
||||
|
||||
// AvatarProps defines the properties for the Avatar component.
|
||||
type AvatarProps struct {
|
||||
// ImageSrc is the URL of the avatar image.
|
||||
// If empty, initials will be used.
|
||||
// ImageSrc is the URL for the avatar image
|
||||
// If empty, initials will be shown instead
|
||||
ImageSrc string
|
||||
|
||||
// Name is used to generate initials if ImageSrc is empty.
|
||||
// Name is used to generate initials when no image is provided
|
||||
Name string
|
||||
|
||||
// Size determines the size of the avatar.
|
||||
// Default: AvatarSizeMedium
|
||||
// Size controls the avatar dimensions (small, medium, large)
|
||||
Size AvatarSize
|
||||
|
||||
// Class specifies additional CSS classes to apply to the avatar.
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the avatar element.
|
||||
// Attributes for additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// getInitials generates initials from the given name.
|
||||
// AvatarInitials generates a 1-2 character initial from the given name
|
||||
func AvatarInitials(name string) string {
|
||||
parts := strings.Fields(name)
|
||||
initials := ""
|
||||
@ -58,7 +61,7 @@ func AvatarInitials(name string) string {
|
||||
return strings.ToUpper(initials)
|
||||
}
|
||||
|
||||
// getSizeClasses returns the CSS classes for the given avatar size.
|
||||
// AvatarSizeClasses maps sizes to their corresponding CSS classes
|
||||
func AvatarSizeClasses(size AvatarSize) string {
|
||||
switch size {
|
||||
case AvatarSizeSmall:
|
||||
@ -70,24 +73,15 @@ func AvatarSizeClasses(size AvatarSize) string {
|
||||
}
|
||||
}
|
||||
|
||||
// Avatar renders an avatar component based on the provided props.
|
||||
// It displays an image if ImageSrc is provided, otherwise it shows initials.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Avatar(components.AvatarProps{
|
||||
// ImageSrc: "https://example.com/avatar.jpg",
|
||||
// Name: "John Doe",
|
||||
// Size: components.AvatarSizeMedium,
|
||||
// Class: "border-2 border-blue-500",
|
||||
// })
|
||||
// Avatar renders a circular image or initials for user representation.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/avatar
|
||||
//
|
||||
// Props:
|
||||
// - ImageSrc: The URL of the avatar image. Default: "" (empty string)
|
||||
// - Name: The name used to generate initials if ImageSrc is empty. Default: "" (empty string)
|
||||
// - Size: The size of the avatar (AvatarSizeSmall, AvatarSizeMedium, AvatarSizeLarge). Default: AvatarSizeMedium
|
||||
// - Class: Additional CSS classes to apply to the avatar. Default: "" (empty string)
|
||||
// - Attributes: Additional HTML attributes to apply to the avatar element. Default: nil
|
||||
// - ImageSrc: URL for the avatar image
|
||||
// - Name: Text to generate initials from when no image is provided
|
||||
// - Size: Avatar dimensions (small, medium, large)
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
func Avatar(props AvatarProps) templ.Component {
|
||||
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
|
||||
@ -153,7 +147,7 @@ func Avatar(props AvatarProps) templ.Component {
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.ImageSrc)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/avatar.templ`, Line: 96, Col: 24}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/avatar.templ`, Line: 90, Col: 24}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -166,7 +160,7 @@ func Avatar(props AvatarProps) templ.Component {
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s's avatar", props.Name))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/avatar.templ`, Line: 97, Col: 48}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/avatar.templ`, Line: 91, Col: 48}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -184,7 +178,7 @@ func Avatar(props AvatarProps) templ.Component {
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(AvatarInitials(props.Name))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/avatar.templ`, Line: 102, Col: 32}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/avatar.templ`, Line: 96, Col: 32}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
@ -5,80 +5,67 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ButtonVariant represents the visual style of the button.
|
||||
// ButtonVariant defines the available button styles
|
||||
type ButtonVariant string
|
||||
|
||||
// ButtonSize represents the size of the button.
|
||||
// ButtonSize defines the available button dimensions
|
||||
type ButtonSize string
|
||||
|
||||
// Constants for button variants and sizes.
|
||||
const (
|
||||
Default ButtonVariant = "default"
|
||||
Destructive ButtonVariant = "destructive"
|
||||
Outline ButtonVariant = "outline"
|
||||
Secondary ButtonVariant = "secondary"
|
||||
Ghost ButtonVariant = "ghost"
|
||||
Link ButtonVariant = "link"
|
||||
// Button style variants
|
||||
Default ButtonVariant = "default" // Primary action button
|
||||
Destructive ButtonVariant = "destructive" // Dangerous/warning action
|
||||
Outline ButtonVariant = "outline" // Bordered button
|
||||
Secondary ButtonVariant = "secondary" // Less prominent action
|
||||
Ghost ButtonVariant = "ghost" // Minimal styling
|
||||
Link ButtonVariant = "link" // Appears as a text link
|
||||
|
||||
Md ButtonSize = "md"
|
||||
Sm ButtonSize = "sm"
|
||||
Lg ButtonSize = "lg"
|
||||
ButtonIcon ButtonSize = "icon"
|
||||
// Button sizes
|
||||
Md ButtonSize = "md" // Standard size
|
||||
Sm ButtonSize = "sm" // Compact size
|
||||
Lg ButtonSize = "lg" // Large size
|
||||
ButtonIcon ButtonSize = "icon" // Square icon button
|
||||
)
|
||||
|
||||
// Button defines the properties for the Button component.
|
||||
type ButtonProps struct {
|
||||
// Class specifies additional CSS classes to apply to the button.
|
||||
// Default: "" (empty string)
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Text is the content of the button.
|
||||
// Default: "" (empty string)
|
||||
// Text contains the button label
|
||||
Text string
|
||||
|
||||
// Variant determines the visual style of the button.
|
||||
// Default: Default
|
||||
// Variant controls the button styling
|
||||
Variant ButtonVariant
|
||||
|
||||
// Size sets the size of the button.
|
||||
// Default: Md
|
||||
// Size controls button dimensions
|
||||
Size ButtonSize
|
||||
|
||||
// FullWidth determines whether the button should take up the full width of its container.
|
||||
// Default: false
|
||||
// FullWidth makes button expand to container width
|
||||
FullWidth bool
|
||||
|
||||
// Href, if provided, renders the button as an anchor tag with this URL.
|
||||
// Default: "" (empty string)
|
||||
// Href turns the button into a link
|
||||
Href string
|
||||
|
||||
// Target specifies the target attribute for the anchor tag (only used when Href is provided).
|
||||
// Default: "" (empty string)
|
||||
// Target controls link opening behavior
|
||||
Target string
|
||||
|
||||
// Disabled can be either a bool or a string.
|
||||
// If bool (Go), it directly controls the disabled state.
|
||||
// If string, it's treated as a JavaScript expression for dynamic disabling.
|
||||
// Disabled controls interactive state (bool or JS expression)
|
||||
Disabled any
|
||||
|
||||
// Type specifies the type of the button. Default: "button"
|
||||
// Default: "" (empty string)
|
||||
// Type sets the button type attribute
|
||||
Type string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the button or anchor element.
|
||||
// Default: nil
|
||||
// Attributes for additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
|
||||
// IconLeft specifies an icon component to be displayed on the left side of the button text.
|
||||
// Default: nil
|
||||
// IconLeft displays an icon before text
|
||||
IconLeft templ.Component
|
||||
|
||||
// IconRight specifies an icon component to be displayed on the right side of the button text.
|
||||
// Default: nil
|
||||
// IconRight displays an icon after text
|
||||
IconRight templ.Component
|
||||
}
|
||||
|
||||
// Variant als Methode
|
||||
// variantClasses maps variants to their CSS classes
|
||||
func (b ButtonProps) variantClasses() string {
|
||||
switch b.Variant {
|
||||
case Destructive:
|
||||
@ -96,7 +83,7 @@ func (b ButtonProps) variantClasses() string {
|
||||
}
|
||||
}
|
||||
|
||||
// Size als Methode
|
||||
// sizeClasses maps sizes to their CSS classes
|
||||
func (b ButtonProps) sizeClasses() string {
|
||||
switch b.Size {
|
||||
case Sm:
|
||||
@ -110,6 +97,7 @@ func (b ButtonProps) sizeClasses() string {
|
||||
}
|
||||
}
|
||||
|
||||
// modifierClasses generates additional utility classes
|
||||
func (b ButtonProps) modifierClasses() string {
|
||||
classes := []string{}
|
||||
if b.FullWidth {
|
||||
@ -118,37 +106,22 @@ func (b ButtonProps) modifierClasses() string {
|
||||
return strings.Join(classes, " ")
|
||||
}
|
||||
|
||||
// Button renders a button or anchor component based on the provided props.
|
||||
// It can be customized with various visual styles, sizes, and behaviors.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Button(components.ButtonProps{
|
||||
// Text: "Click me",
|
||||
// Variant: components.Primary,
|
||||
// Size: components.Md,
|
||||
// FullWidth: false,
|
||||
// IconLeft: components.Icon(components.IconProps{Name: "user"}),
|
||||
// IconRight: components.Icon(components.IconProps{Name: "arrow-right"}),
|
||||
// Attributes: templ.Attributes{
|
||||
// "aria-label": "Click this button",
|
||||
// "data-testid": "main-button",
|
||||
// },
|
||||
// })
|
||||
// Button renders an interactive button or link component with consistent styling.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/button
|
||||
//
|
||||
// Props:
|
||||
// - Class: Additional CSS classes to apply to the button. Default: "" (empty string)
|
||||
// - Text: The text content of the button. Default: "" (empty string)
|
||||
// - Variant: The visual style of the button (e.g., Default, Destructive, Outline). Default: Default
|
||||
// - Size: The size of the button (Md, Sm, Lg, Icon). Default: Md
|
||||
// - FullWidth: Whether the button should take up the full width of its container. Default: false
|
||||
// - Href: If provided, renders the button as an anchor tag with this URL. Default: "" (empty string)
|
||||
// - Target: The target attribute for the anchor tag (only used when Href is provided). Default: "" (empty string)
|
||||
// - Disabled: Can be either a bool or a string. If bool (Go), it directly controls the disabled state. If string, it's treated as a JavaScript expression for dynamic disabling. Default: nil
|
||||
// - Type: The type of the button. Default: "button"
|
||||
// - Attributes: Additional HTML attributes to apply to the button or anchor element. Default: nil
|
||||
// - IconLeft: An icon component to be displayed on the left side of the button text. Default: nil
|
||||
// - IconRight: An icon component to be displayed on the right side of the button text. Default: nil
|
||||
// - Class: Additional CSS classes
|
||||
// - Text: Button label text
|
||||
// - Variant: Visual style (default, destructive, outline, etc)
|
||||
// - Size: Button dimensions (sm, md, lg, icon)
|
||||
// - FullWidth: Expand to fill container
|
||||
// - Href: Optional URL for link buttons
|
||||
// - Target: Link target attribute
|
||||
// - Disabled: Interactivity state
|
||||
// - Type: Button type attribute
|
||||
// - Attributes: Additional HTML attributes
|
||||
// - IconLeft: Icon component before text
|
||||
// - IconRight: Icon component after text
|
||||
templ Button(props ButtonProps) {
|
||||
if props.Href != "" {
|
||||
<a
|
||||
@ -209,7 +182,7 @@ templ Button(props ButtonProps) {
|
||||
}
|
||||
}
|
||||
|
||||
// renderButtonContent renders the content of the button, including icons and text
|
||||
// renderButtonContent arranges button text and icons
|
||||
templ renderButtonContent(props ButtonProps) {
|
||||
<span class="flex gap-2 items-center">
|
||||
if props.IconLeft != nil {
|
||||
|
@ -13,80 +13,67 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ButtonVariant represents the visual style of the button.
|
||||
// ButtonVariant defines the available button styles
|
||||
type ButtonVariant string
|
||||
|
||||
// ButtonSize represents the size of the button.
|
||||
// ButtonSize defines the available button dimensions
|
||||
type ButtonSize string
|
||||
|
||||
// Constants for button variants and sizes.
|
||||
const (
|
||||
Default ButtonVariant = "default"
|
||||
Destructive ButtonVariant = "destructive"
|
||||
Outline ButtonVariant = "outline"
|
||||
Secondary ButtonVariant = "secondary"
|
||||
Ghost ButtonVariant = "ghost"
|
||||
Link ButtonVariant = "link"
|
||||
// Button style variants
|
||||
Default ButtonVariant = "default" // Primary action button
|
||||
Destructive ButtonVariant = "destructive" // Dangerous/warning action
|
||||
Outline ButtonVariant = "outline" // Bordered button
|
||||
Secondary ButtonVariant = "secondary" // Less prominent action
|
||||
Ghost ButtonVariant = "ghost" // Minimal styling
|
||||
Link ButtonVariant = "link" // Appears as a text link
|
||||
|
||||
Md ButtonSize = "md"
|
||||
Sm ButtonSize = "sm"
|
||||
Lg ButtonSize = "lg"
|
||||
ButtonIcon ButtonSize = "icon"
|
||||
// Button sizes
|
||||
Md ButtonSize = "md" // Standard size
|
||||
Sm ButtonSize = "sm" // Compact size
|
||||
Lg ButtonSize = "lg" // Large size
|
||||
ButtonIcon ButtonSize = "icon" // Square icon button
|
||||
)
|
||||
|
||||
// Button defines the properties for the Button component.
|
||||
type ButtonProps struct {
|
||||
// Class specifies additional CSS classes to apply to the button.
|
||||
// Default: "" (empty string)
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Text is the content of the button.
|
||||
// Default: "" (empty string)
|
||||
// Text contains the button label
|
||||
Text string
|
||||
|
||||
// Variant determines the visual style of the button.
|
||||
// Default: Default
|
||||
// Variant controls the button styling
|
||||
Variant ButtonVariant
|
||||
|
||||
// Size sets the size of the button.
|
||||
// Default: Md
|
||||
// Size controls button dimensions
|
||||
Size ButtonSize
|
||||
|
||||
// FullWidth determines whether the button should take up the full width of its container.
|
||||
// Default: false
|
||||
// FullWidth makes button expand to container width
|
||||
FullWidth bool
|
||||
|
||||
// Href, if provided, renders the button as an anchor tag with this URL.
|
||||
// Default: "" (empty string)
|
||||
// Href turns the button into a link
|
||||
Href string
|
||||
|
||||
// Target specifies the target attribute for the anchor tag (only used when Href is provided).
|
||||
// Default: "" (empty string)
|
||||
// Target controls link opening behavior
|
||||
Target string
|
||||
|
||||
// Disabled can be either a bool or a string.
|
||||
// If bool (Go), it directly controls the disabled state.
|
||||
// If string, it's treated as a JavaScript expression for dynamic disabling.
|
||||
// Disabled controls interactive state (bool or JS expression)
|
||||
Disabled any
|
||||
|
||||
// Type specifies the type of the button. Default: "button"
|
||||
// Default: "" (empty string)
|
||||
// Type sets the button type attribute
|
||||
Type string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the button or anchor element.
|
||||
// Default: nil
|
||||
// Attributes for additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
|
||||
// IconLeft specifies an icon component to be displayed on the left side of the button text.
|
||||
// Default: nil
|
||||
// IconLeft displays an icon before text
|
||||
IconLeft templ.Component
|
||||
|
||||
// IconRight specifies an icon component to be displayed on the right side of the button text.
|
||||
// Default: nil
|
||||
// IconRight displays an icon after text
|
||||
IconRight templ.Component
|
||||
}
|
||||
|
||||
// Variant als Methode
|
||||
// variantClasses maps variants to their CSS classes
|
||||
func (b ButtonProps) variantClasses() string {
|
||||
switch b.Variant {
|
||||
case Destructive:
|
||||
@ -104,7 +91,7 @@ func (b ButtonProps) variantClasses() string {
|
||||
}
|
||||
}
|
||||
|
||||
// Size als Methode
|
||||
// sizeClasses maps sizes to their CSS classes
|
||||
func (b ButtonProps) sizeClasses() string {
|
||||
switch b.Size {
|
||||
case Sm:
|
||||
@ -118,6 +105,7 @@ func (b ButtonProps) sizeClasses() string {
|
||||
}
|
||||
}
|
||||
|
||||
// modifierClasses generates additional utility classes
|
||||
func (b ButtonProps) modifierClasses() string {
|
||||
classes := []string{}
|
||||
if b.FullWidth {
|
||||
@ -126,37 +114,22 @@ func (b ButtonProps) modifierClasses() string {
|
||||
return strings.Join(classes, " ")
|
||||
}
|
||||
|
||||
// Button renders a button or anchor component based on the provided props.
|
||||
// It can be customized with various visual styles, sizes, and behaviors.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Button(components.ButtonProps{
|
||||
// Text: "Click me",
|
||||
// Variant: components.Primary,
|
||||
// Size: components.Md,
|
||||
// FullWidth: false,
|
||||
// IconLeft: components.Icon(components.IconProps{Name: "user"}),
|
||||
// IconRight: components.Icon(components.IconProps{Name: "arrow-right"}),
|
||||
// Attributes: templ.Attributes{
|
||||
// "aria-label": "Click this button",
|
||||
// "data-testid": "main-button",
|
||||
// },
|
||||
// })
|
||||
// Button renders an interactive button or link component with consistent styling.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/button
|
||||
//
|
||||
// Props:
|
||||
// - Class: Additional CSS classes to apply to the button. Default: "" (empty string)
|
||||
// - Text: The text content of the button. Default: "" (empty string)
|
||||
// - Variant: The visual style of the button (e.g., Default, Destructive, Outline). Default: Default
|
||||
// - Size: The size of the button (Md, Sm, Lg, Icon). Default: Md
|
||||
// - FullWidth: Whether the button should take up the full width of its container. Default: false
|
||||
// - Href: If provided, renders the button as an anchor tag with this URL. Default: "" (empty string)
|
||||
// - Target: The target attribute for the anchor tag (only used when Href is provided). Default: "" (empty string)
|
||||
// - Disabled: Can be either a bool or a string. If bool (Go), it directly controls the disabled state. If string, it's treated as a JavaScript expression for dynamic disabling. Default: nil
|
||||
// - Type: The type of the button. Default: "button"
|
||||
// - Attributes: Additional HTML attributes to apply to the button or anchor element. Default: nil
|
||||
// - IconLeft: An icon component to be displayed on the left side of the button text. Default: nil
|
||||
// - IconRight: An icon component to be displayed on the right side of the button text. Default: nil
|
||||
// - Class: Additional CSS classes
|
||||
// - Text: Button label text
|
||||
// - Variant: Visual style (default, destructive, outline, etc)
|
||||
// - Size: Button dimensions (sm, md, lg, icon)
|
||||
// - FullWidth: Expand to fill container
|
||||
// - Href: Optional URL for link buttons
|
||||
// - Target: Link target attribute
|
||||
// - Disabled: Interactivity state
|
||||
// - Type: Button type attribute
|
||||
// - Attributes: Additional HTML attributes
|
||||
// - IconLeft: Icon component before text
|
||||
// - IconRight: Icon component after text
|
||||
func Button(props ButtonProps) templ.Component {
|
||||
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
|
||||
@ -209,7 +182,7 @@ func Button(props ButtonProps) templ.Component {
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.Target)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/button.templ`, Line: 156, Col: 24}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/button.templ`, Line: 129, Col: 24}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -247,7 +220,7 @@ func Button(props ButtonProps) templ.Component {
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(disabledStr)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/button.templ`, Line: 172, Col: 33}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/button.templ`, Line: 145, Col: 33}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -320,7 +293,7 @@ func Button(props ButtonProps) templ.Component {
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(props.Type)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/button.templ`, Line: 194, Col: 21}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/button.templ`, Line: 167, Col: 21}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -348,7 +321,7 @@ func Button(props ButtonProps) templ.Component {
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(disabledStr)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/button.templ`, Line: 201, Col: 28}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/button.templ`, Line: 174, Col: 28}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -385,7 +358,7 @@ func Button(props ButtonProps) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// renderButtonContent renders the content of the button, including icons and text
|
||||
// renderButtonContent arranges button text and icons
|
||||
func renderButtonContent(props ButtonProps) templ.Component {
|
||||
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
|
||||
@ -420,7 +393,7 @@ func renderButtonContent(props ButtonProps) templ.Component {
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(props.Text)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/button.templ`, Line: 218, Col: 14}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/button.templ`, Line: 191, Col: 14}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
@ -2,32 +2,20 @@ package components
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// CardProps defines the properties for the Card component.
|
||||
type CardProps struct {
|
||||
// Class specifies additional CSS classes to apply to the card.
|
||||
// Default: "" (empty string)
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the card element.
|
||||
// Default: nil
|
||||
// Attributes for additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Card renders a card component based on the provided props.
|
||||
// It can be customized with additional classes and attributes.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Card(components.CardProps{
|
||||
// Class: "custom-card",
|
||||
// Attributes: templ.Attributes{"data-testid": "my-card"},
|
||||
// }) {
|
||||
// // Card content goes here
|
||||
// }
|
||||
// Card renders a container component with consistent styling and structure.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/card
|
||||
//
|
||||
// Props:
|
||||
// - Class: Additional CSS classes to apply to the card. Default: "" (empty string)
|
||||
// - Attributes: Additional HTML attributes to apply to the card element. Default: nil
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
templ Card(props CardProps) {
|
||||
<div
|
||||
class={ utils.TwMerge("rounded-lg border bg-card text-card-foreground shadow-sm", props.Class) }
|
||||
@ -37,66 +25,40 @@ templ Card(props CardProps) {
|
||||
</div>
|
||||
}
|
||||
|
||||
// CardHeader renders the header section of a card.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.CardHeader() {
|
||||
// @components.CardTitle() { Card Title }
|
||||
// @components.CardDescription() { Card description goes here }
|
||||
// }
|
||||
// CardHeader renders the top section of the card
|
||||
// Typically contains title and description
|
||||
templ CardHeader() {
|
||||
<div class="flex flex-col space-y-1.5 p-6">
|
||||
{ children... }
|
||||
</div>
|
||||
}
|
||||
|
||||
// CardTitle renders the title of a card.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.CardTitle() {
|
||||
// My Card Title
|
||||
// }
|
||||
// CardTitle renders the card's main heading
|
||||
// Uses h3 with consistent styling
|
||||
templ CardTitle() {
|
||||
<h3 class="font-semibold leading-none tracking-tight">
|
||||
{ children... }
|
||||
</h3>
|
||||
}
|
||||
|
||||
// CardDescription renders the description of a card.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.CardDescription() {
|
||||
// This is a detailed description of the card's content.
|
||||
// }
|
||||
// CardDescription renders secondary text below the title
|
||||
// Uses muted styling for visual hierarchy
|
||||
templ CardDescription() {
|
||||
<p class="text-sm text-muted-foreground">
|
||||
{ children... }
|
||||
</p>
|
||||
}
|
||||
|
||||
// CardContent renders the main content section of a card.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.CardContent() {
|
||||
// // Main card content goes here
|
||||
// }
|
||||
// CardContent renders the main card body section
|
||||
// Contains the primary content area
|
||||
templ CardContent() {
|
||||
<div class="p-6 pt-0">
|
||||
{ children... }
|
||||
</div>
|
||||
}
|
||||
|
||||
// CardFooter renders the footer section of a card.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.CardFooter() {
|
||||
// @components.Button(components.ButtonProps{Text: "Submit"})
|
||||
// }
|
||||
// CardFooter renders the bottom section of the card
|
||||
// Typically contains actions or summary information
|
||||
templ CardFooter() {
|
||||
<div class="flex items-center p-6 pt-0">
|
||||
{ children... }
|
||||
|
@ -10,32 +10,20 @@ import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// CardProps defines the properties for the Card component.
|
||||
type CardProps struct {
|
||||
// Class specifies additional CSS classes to apply to the card.
|
||||
// Default: "" (empty string)
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the card element.
|
||||
// Default: nil
|
||||
// Attributes for additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Card renders a card component based on the provided props.
|
||||
// It can be customized with additional classes and attributes.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Card(components.CardProps{
|
||||
// Class: "custom-card",
|
||||
// Attributes: templ.Attributes{"data-testid": "my-card"},
|
||||
// }) {
|
||||
// // Card content goes here
|
||||
// }
|
||||
// Card renders a container component with consistent styling and structure.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/card
|
||||
//
|
||||
// Props:
|
||||
// - Class: Additional CSS classes to apply to the card. Default: "" (empty string)
|
||||
// - Attributes: Additional HTML attributes to apply to the card element. Default: nil
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
func Card(props CardProps) templ.Component {
|
||||
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
|
||||
@ -99,14 +87,8 @@ func Card(props CardProps) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// CardHeader renders the header section of a card.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.CardHeader() {
|
||||
// @components.CardTitle() { Card Title }
|
||||
// @components.CardDescription() { Card description goes here }
|
||||
// }
|
||||
// CardHeader renders the top section of the card
|
||||
// Typically contains title and description
|
||||
func CardHeader() templ.Component {
|
||||
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
|
||||
@ -144,13 +126,8 @@ func CardHeader() templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// CardTitle renders the title of a card.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.CardTitle() {
|
||||
// My Card Title
|
||||
// }
|
||||
// CardTitle renders the card's main heading
|
||||
// Uses h3 with consistent styling
|
||||
func CardTitle() templ.Component {
|
||||
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
|
||||
@ -188,13 +165,8 @@ func CardTitle() templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// CardDescription renders the description of a card.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.CardDescription() {
|
||||
// This is a detailed description of the card's content.
|
||||
// }
|
||||
// CardDescription renders secondary text below the title
|
||||
// Uses muted styling for visual hierarchy
|
||||
func CardDescription() templ.Component {
|
||||
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
|
||||
@ -232,13 +204,8 @@ func CardDescription() templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// CardContent renders the main content section of a card.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.CardContent() {
|
||||
// // Main card content goes here
|
||||
// }
|
||||
// CardContent renders the main card body section
|
||||
// Contains the primary content area
|
||||
func CardContent() templ.Component {
|
||||
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
|
||||
@ -276,13 +243,8 @@ func CardContent() templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// CardFooter renders the footer section of a card.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.CardFooter() {
|
||||
// @components.Button(components.ButtonProps{Text: "Submit"})
|
||||
// }
|
||||
// CardFooter renders the bottom section of the card
|
||||
// Typically contains actions or summary information
|
||||
func CardFooter() templ.Component {
|
||||
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
|
||||
|
@ -5,99 +5,74 @@ import (
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
|
||||
// CheckboxProps defines the properties for the Checkbox component.
|
||||
type CheckboxProps struct {
|
||||
// ID is the unique identifier for the checkbox input.
|
||||
// ID uniquely identifies the checkbox input
|
||||
ID string
|
||||
|
||||
// Name is the name attribute for the checkbox input.
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Value is the value attribute for the checkbox input.
|
||||
// Value sets the checkbox value
|
||||
Value string
|
||||
|
||||
// Label is the text label associated with the checkbox.
|
||||
// If empty, no label will be rendered.
|
||||
// Label displays text next to checkbox
|
||||
// Empty string hides the label
|
||||
Label string
|
||||
|
||||
// Checked is a JavaScript expression for the checked state
|
||||
// Example: "true", "isSubscribed", "5+5===10"
|
||||
Checked string
|
||||
|
||||
// Disabled is a JavaScript expression for the disabled state
|
||||
// Example: "true", "isLoading", "!isEnabled"
|
||||
Disabled string
|
||||
|
||||
// Class specifies additional CSS classes for the container
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Checkbox renders a customizable checkbox component with an associated label.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Checkbox(components.CheckboxProps{
|
||||
// ID: "terms",
|
||||
// Name: "accept_terms",
|
||||
// Value: "accepted",
|
||||
// Label: "I accept the terms and conditions",
|
||||
// Checked: "true",
|
||||
// Disabled: "isSubmitting",
|
||||
// Class: "mt-4",
|
||||
// Attributes: templ.Attributes{"data-testid": "terms-checkbox"},
|
||||
// })
|
||||
// Checkbox renders a styled checkbox input with optional label.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/checkbox
|
||||
//
|
||||
// Props:
|
||||
// - ID: The unique identifier for the checkbox input. Required.
|
||||
// - Name: The name attribute for the checkbox input. Required.
|
||||
// - Value: The value attribute for the checkbox input. Required.
|
||||
// - Label: The text label associated with the checkbox. Optional.
|
||||
// - Checked: Determines the checked state. Can be a bool or a string for dynamic binding. Optional.
|
||||
// - Disabled: Determines the disabled state. Can be a bool or a string for dynamic binding. Optional.
|
||||
// - Class: Additional CSS classes to apply to the checkbox container. Optional.
|
||||
// - Attributes: Additional HTML attributes to apply to the checkbox input element. Optional.
|
||||
// - ID: Unique identifier for the input
|
||||
// - Name: Form field name
|
||||
// - Value: Checkbox value
|
||||
// - Label: Optional text label
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
templ Checkbox(props CheckboxProps) {
|
||||
<div x-data="{ checked: false }" class={ utils.TwMerge("flex items-center space-x-2", props.Class) }>
|
||||
<div class="relative">
|
||||
<label
|
||||
for={ props.ID }
|
||||
class={ utils.TwMerge(
|
||||
"flex cursor-pointer items-center gap-2 text-sm font-medium",
|
||||
"text-muted-foreground [&:has(input:checked)]:text-foreground",
|
||||
"[&:has(input:disabled)]:opacity-50 [&:has(input:disabled)]:cursor-not-allowed",
|
||||
props.Class,
|
||||
) }
|
||||
>
|
||||
<div class="relative flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
value={ props.Value }
|
||||
x-ref="checkbox"
|
||||
x-model="checked"
|
||||
if props.Checked != "" {
|
||||
x-init={ "checked = " + props.Checked }
|
||||
}
|
||||
if props.Disabled != "" {
|
||||
:disabled={ props.Disabled }
|
||||
}
|
||||
class="absolute w-full h-full opacity-0 z-10 cursor-pointer peer"
|
||||
type="checkbox"
|
||||
class="before:content[''] peer relative size-4 cursor-pointer appearance-none overflow-hidden
|
||||
rounded-sm border border-2 border-primary
|
||||
bg-background before:absolute before:inset-0
|
||||
checked:before:bg-primary
|
||||
focus:outline focus:outline-2 focus:outline-offset-2
|
||||
focus:outline-ring checked:focus:outline-primary
|
||||
active:outline-offset-0
|
||||
disabled:cursor-not-allowed
|
||||
transition-colors"
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
<div
|
||||
class="h-4 w-4 rounded-sm border border-primary ring-offset-background
|
||||
peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2
|
||||
peer-disabled:cursor-not-allowed peer-disabled:opacity-50
|
||||
flex items-center justify-center
|
||||
bg-background peer-checked:bg-primary transition-colors"
|
||||
class="pointer-events-none invisible absolute left-1/2 top-1/2 size-3
|
||||
-translate-x-1/2 -translate-y-1/2 text-primary-foreground
|
||||
peer-checked:visible"
|
||||
>
|
||||
<div x-show="checked" class="text-primary-foreground">
|
||||
@icons.Check(icons.IconProps{Size: "12"})
|
||||
</div>
|
||||
@icons.Check(icons.IconProps{Size: "12"})
|
||||
</div>
|
||||
</div>
|
||||
if props.Label != "" {
|
||||
<label
|
||||
for={ props.ID }
|
||||
class="text-sm font-medium leading-none cursor-pointer select-none"
|
||||
:class="{ 'text-muted-foreground': !checked, 'text-foreground': checked }"
|
||||
>
|
||||
{ props.Label }
|
||||
</label>
|
||||
<span>{ props.Label }</span>
|
||||
}
|
||||
</div>
|
||||
</label>
|
||||
}
|
||||
|
@ -13,60 +13,37 @@ import (
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
|
||||
// CheckboxProps defines the properties for the Checkbox component.
|
||||
type CheckboxProps struct {
|
||||
// ID is the unique identifier for the checkbox input.
|
||||
// ID uniquely identifies the checkbox input
|
||||
ID string
|
||||
|
||||
// Name is the name attribute for the checkbox input.
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Value is the value attribute for the checkbox input.
|
||||
// Value sets the checkbox value
|
||||
Value string
|
||||
|
||||
// Label is the text label associated with the checkbox.
|
||||
// If empty, no label will be rendered.
|
||||
// Label displays text next to checkbox
|
||||
// Empty string hides the label
|
||||
Label string
|
||||
|
||||
// Checked is a JavaScript expression for the checked state
|
||||
// Example: "true", "isSubscribed", "5+5===10"
|
||||
Checked string
|
||||
|
||||
// Disabled is a JavaScript expression for the disabled state
|
||||
// Example: "true", "isLoading", "!isEnabled"
|
||||
Disabled string
|
||||
|
||||
// Class specifies additional CSS classes for the container
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Checkbox renders a customizable checkbox component with an associated label.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Checkbox(components.CheckboxProps{
|
||||
// ID: "terms",
|
||||
// Name: "accept_terms",
|
||||
// Value: "accepted",
|
||||
// Label: "I accept the terms and conditions",
|
||||
// Checked: "true",
|
||||
// Disabled: "isSubmitting",
|
||||
// Class: "mt-4",
|
||||
// Attributes: templ.Attributes{"data-testid": "terms-checkbox"},
|
||||
// })
|
||||
// Checkbox renders a styled checkbox input with optional label.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/checkbox
|
||||
//
|
||||
// Props:
|
||||
// - ID: The unique identifier for the checkbox input. Required.
|
||||
// - Name: The name attribute for the checkbox input. Required.
|
||||
// - Value: The value attribute for the checkbox input. Required.
|
||||
// - Label: The text label associated with the checkbox. Optional.
|
||||
// - Checked: Determines the checked state. Can be a bool or a string for dynamic binding. Optional.
|
||||
// - Disabled: Determines the disabled state. Can be a bool or a string for dynamic binding. Optional.
|
||||
// - Class: Additional CSS classes to apply to the checkbox container. Optional.
|
||||
// - Attributes: Additional HTML attributes to apply to the checkbox input element. Optional.
|
||||
// - ID: Unique identifier for the input
|
||||
// - Name: Form field name
|
||||
// - Value: Checkbox value
|
||||
// - Label: Optional text label
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
func Checkbox(props CheckboxProps) templ.Component {
|
||||
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
|
||||
@ -88,47 +65,65 @@ func Checkbox(props CheckboxProps) templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var2 = []any{utils.TwMerge("flex items-center space-x-2", props.Class)}
|
||||
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
|
||||
"flex cursor-pointer items-center gap-2 text-sm font-medium",
|
||||
"text-muted-foreground [&:has(input:checked)]:text-foreground",
|
||||
"[&:has(input:disabled)]:opacity-50 [&:has(input:disabled)]:cursor-not-allowed",
|
||||
props.Class,
|
||||
)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div x-data=\"{ checked: false }\" class=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label for=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 1, Col: 0}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 41, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><div class=\"relative\"><input type=\"checkbox\" id=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 67, Col: 17}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><div class=\"relative flex items-center\"><input id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 51, Col: 17}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" name=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 68, Col: 21}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 52, Col: 21}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -136,58 +131,16 @@ func Checkbox(props CheckboxProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 69, Col: 23}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 53, Col: 23}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-ref=\"checkbox\" x-model=\"checked\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Checked != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" x-init=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs("checked = " + props.Checked)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 73, Col: 42}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
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 props.Disabled != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" :disabled=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.Disabled)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 76, Col: 31}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
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_Buffer.WriteString(" class=\"absolute w-full h-full opacity-0 z-10 cursor-pointer peer\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" type=\"checkbox\" class=\"before:content[''] peer relative size-4 cursor-pointer appearance-none overflow-hidden \n rounded-sm border border-2 border-primary\n bg-background before:absolute before:inset-0 \n checked:before:bg-primary\n focus:outline focus:outline-2 focus:outline-offset-2 \n focus:outline-ring checked:focus:outline-primary \n active:outline-offset-0 \n disabled:cursor-not-allowed\n transition-colors\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -195,7 +148,7 @@ func Checkbox(props CheckboxProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("><div class=\"h-4 w-4 rounded-sm border border-primary ring-offset-background \n peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2 \n peer-disabled:cursor-not-allowed peer-disabled:opacity-50\n flex items-center justify-center\n bg-background peer-checked:bg-primary transition-colors\"><div x-show=\"checked\" class=\"text-primary-foreground\">")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("><div class=\"pointer-events-none invisible absolute left-1/2 top-1/2 size-3 \n -translate-x-1/2 -translate-y-1/2 text-primary-foreground \n peer-checked:visible\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -203,43 +156,30 @@ func Checkbox(props CheckboxProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div></div>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Label != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label for=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 95, Col: 18}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 75, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"text-sm font-medium leading-none cursor-pointer select-none\" :class=\"{ 'text-muted-foreground': !checked, 'text-foreground': checked }\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(props.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/checkbox.templ`, Line: 99, Col: 17}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
@ -5,49 +5,43 @@ import (
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
|
||||
// DatepickerProps defines the properties for the Datepicker component.
|
||||
type DatepickerProps struct {
|
||||
// ID is the unique identifier for the datepicker input.
|
||||
// ID uniquely identifies the datepicker input
|
||||
ID string
|
||||
|
||||
// Name is the name attribute for the datepicker input.
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Placeholder is the placeholder text for the datepicker input.
|
||||
// Placeholder shows helper text when empty
|
||||
Placeholder string
|
||||
|
||||
// Format specifies the date format to use. Options: "M d, Y", "MM-DD-YYYY", "DD-MM-YYYY", "YYYY-MM-DD", "D d M, Y"
|
||||
// Default: "M d, Y"
|
||||
// Format controls date string presentation
|
||||
// Supported formats:
|
||||
// - "M d, Y" (Jan 1, 2024)
|
||||
// - "MM-DD-YYYY" (01-01-2024)
|
||||
// - "DD-MM-YYYY" (01-01-2024)
|
||||
// - "YYYY-MM-DD" (2024-01-01)
|
||||
// - "D d M, Y" (Mon 1 Jan, 2024)
|
||||
Format string
|
||||
|
||||
// Class specifies additional CSS classes to apply to the datepicker container.
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the datepicker input element.
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Datepicker renders an enhanced datepicker component with an input field and a calendar view.
|
||||
// It uses Alpine.js for interactivity and provides various formatting options and improved navigation.
|
||||
// This version supports dark mode using Tailwind CSS variables.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Datepicker(components.DatepickerProps{
|
||||
// ID: "my-datepicker",
|
||||
// Name: "selected-date",
|
||||
// Placeholder: "Select a date",
|
||||
// Format: "YYYY-MM-DD",
|
||||
// Class: "w-full",
|
||||
// })
|
||||
// Datepicker renders a calendar input component with popup date selection.
|
||||
// Uses Alpine.js for interactions and supports dark mode via Tailwind.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/datepicker
|
||||
//
|
||||
// Props:
|
||||
// - ID: The unique identifier for the datepicker input. Default: "" (empty string)
|
||||
// - Name: The name attribute for the datepicker input. Default: "" (empty string)
|
||||
// - Placeholder: The placeholder text for the datepicker input. Default: "" (empty string)
|
||||
// - Format: The date format to use. Default: "M d, Y"
|
||||
// - Class: Additional CSS classes to apply to the datepicker container. Default: "" (empty string)
|
||||
// - Attributes: Additional HTML attributes to apply to the datepicker input element. Default: nil
|
||||
// - ID: Unique identifier for the input
|
||||
// - Name: Form field name
|
||||
// - Placeholder: Helper text when empty
|
||||
// - Format: Date display format
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
templ Datepicker(props DatepickerProps) {
|
||||
<div
|
||||
data-date-format={ props.Format }
|
||||
@ -174,7 +168,7 @@ templ Datepicker(props DatepickerProps) {
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
placeholder={ props.Placeholder }
|
||||
x-model="datePickerValue"
|
||||
x-modelable="datePickerValue"
|
||||
@click="toggleDatePicker()"
|
||||
x-on:keydown.escape="datePickerOpen = false"
|
||||
x-ref="datePickerInput"
|
||||
|
@ -13,49 +13,43 @@ import (
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
|
||||
// DatepickerProps defines the properties for the Datepicker component.
|
||||
type DatepickerProps struct {
|
||||
// ID is the unique identifier for the datepicker input.
|
||||
// ID uniquely identifies the datepicker input
|
||||
ID string
|
||||
|
||||
// Name is the name attribute for the datepicker input.
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Placeholder is the placeholder text for the datepicker input.
|
||||
// Placeholder shows helper text when empty
|
||||
Placeholder string
|
||||
|
||||
// Format specifies the date format to use. Options: "M d, Y", "MM-DD-YYYY", "DD-MM-YYYY", "YYYY-MM-DD", "D d M, Y"
|
||||
// Default: "M d, Y"
|
||||
// Format controls date string presentation
|
||||
// Supported formats:
|
||||
// - "M d, Y" (Jan 1, 2024)
|
||||
// - "MM-DD-YYYY" (01-01-2024)
|
||||
// - "DD-MM-YYYY" (01-01-2024)
|
||||
// - "YYYY-MM-DD" (2024-01-01)
|
||||
// - "D d M, Y" (Mon 1 Jan, 2024)
|
||||
Format string
|
||||
|
||||
// Class specifies additional CSS classes to apply to the datepicker container.
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the datepicker input element.
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Datepicker renders an enhanced datepicker component with an input field and a calendar view.
|
||||
// It uses Alpine.js for interactivity and provides various formatting options and improved navigation.
|
||||
// This version supports dark mode using Tailwind CSS variables.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Datepicker(components.DatepickerProps{
|
||||
// ID: "my-datepicker",
|
||||
// Name: "selected-date",
|
||||
// Placeholder: "Select a date",
|
||||
// Format: "YYYY-MM-DD",
|
||||
// Class: "w-full",
|
||||
// })
|
||||
// Datepicker renders a calendar input component with popup date selection.
|
||||
// Uses Alpine.js for interactions and supports dark mode via Tailwind.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/datepicker
|
||||
//
|
||||
// Props:
|
||||
// - ID: The unique identifier for the datepicker input. Default: "" (empty string)
|
||||
// - Name: The name attribute for the datepicker input. Default: "" (empty string)
|
||||
// - Placeholder: The placeholder text for the datepicker input. Default: "" (empty string)
|
||||
// - Format: The date format to use. Default: "M d, Y"
|
||||
// - Class: Additional CSS classes to apply to the datepicker container. Default: "" (empty string)
|
||||
// - Attributes: Additional HTML attributes to apply to the datepicker input element. Default: nil
|
||||
// - ID: Unique identifier for the input
|
||||
// - Name: Form field name
|
||||
// - Placeholder: Helper text when empty
|
||||
// - Format: Date display format
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
func Datepicker(props DatepickerProps) templ.Component {
|
||||
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
|
||||
@ -89,7 +83,7 @@ func Datepicker(props DatepickerProps) templ.Component {
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.Format)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 53, Col: 33}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 47, Col: 33}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -115,7 +109,7 @@ func Datepicker(props DatepickerProps) templ.Component {
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 174, Col: 17}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 168, Col: 17}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -128,7 +122,7 @@ func Datepicker(props DatepickerProps) templ.Component {
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 175, Col: 21}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 169, Col: 21}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -141,13 +135,13 @@ func Datepicker(props DatepickerProps) templ.Component {
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.Placeholder)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 176, Col: 35}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/datepicker.templ`, Line: 170, Col: 35}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-model=\"datePickerValue\" @click=\"toggleDatePicker()\" x-on:keydown.escape=\"datePickerOpen = false\" x-ref=\"datePickerInput\" 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\" readonly")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-modelable=\"datePickerValue\" @click=\"toggleDatePicker()\" x-on:keydown.escape=\"datePickerOpen = false\" x-ref=\"datePickerInput\" 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\" readonly")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
@ -7,29 +7,50 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// DropdownMenuItem represents an item in the dropdown menu
|
||||
type DropdownMenuItem struct {
|
||||
Label string // The text to display for the menu item
|
||||
Value string // The value associated with the menu item (for non-link items)
|
||||
Href string // The URL to navigate to if the item is a link
|
||||
Target string // The target attribute for link items (e.g., "_blank" for new tab)
|
||||
IconLeft templ.Component // An optional icon component to display on the left side of the item
|
||||
IconRight templ.Component // An optional icon component to display on the right side of the item
|
||||
SubItems []DropdownMenuItem // A slice of DropdownMenuItems for nested submenus
|
||||
Disabled bool // Whether the item is disabled or not
|
||||
// Attributes allows passing additional HTML attributes to the accordion container element.
|
||||
// Default: nil
|
||||
// Label displays text for the menu item
|
||||
Label string
|
||||
|
||||
// Value for non-link menu items
|
||||
Value string
|
||||
|
||||
// Href makes item a navigation link
|
||||
Href string
|
||||
|
||||
// Target controls link opening behavior
|
||||
Target string
|
||||
|
||||
// IconLeft displays icon before label
|
||||
IconLeft templ.Component
|
||||
|
||||
// IconRight displays icon after label
|
||||
IconRight templ.Component
|
||||
|
||||
// SubItems creates nested submenu
|
||||
SubItems []DropdownMenuItem
|
||||
|
||||
// Disabled controls interactive state
|
||||
Disabled bool
|
||||
|
||||
// Attributes for additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// DropdownMenuProps defines the properties for the DropdownMenu component
|
||||
type DropdownMenuProps struct {
|
||||
Items []DropdownMenuItem // The list of items to display in the dropdown menu
|
||||
Trigger templ.Component // An optional custom trigger component (default is a button if not provided)
|
||||
Class string // Additional CSS classes to apply to the root element
|
||||
Position string // The preferred position of the dropdown ("left", "right", "top", or "bottom")
|
||||
// Items defines the menu structure
|
||||
Items []DropdownMenuItem
|
||||
|
||||
// Trigger overrides default button trigger
|
||||
Trigger templ.Component
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Position sets preferred menu placement (left, right, top, bottom)
|
||||
Position string
|
||||
}
|
||||
|
||||
// ModifierClasses generates state-based CSS classes
|
||||
func (d DropdownMenuItem) ModifierClasses() string {
|
||||
classes := []string{}
|
||||
if d.Disabled {
|
||||
@ -40,8 +61,8 @@ func (d DropdownMenuItem) ModifierClasses() string {
|
||||
return strings.Join(classes, " ")
|
||||
}
|
||||
|
||||
// renderMenuItem is a helper function to render a single menu item
|
||||
// It handles rendering of regular items, links, and submenus recursively
|
||||
// renderMenuItem handles recursive menu item rendering
|
||||
// Supports regular items, links, and nested submenus up to 3 levels
|
||||
templ renderMenuItem(item DropdownMenuItem, index int, depth int) {
|
||||
if len(item.SubItems) > 0 {
|
||||
<div class="relative group">
|
||||
@ -134,41 +155,21 @@ templ renderMenuItem(item DropdownMenuItem, index int, depth int) {
|
||||
}
|
||||
}
|
||||
|
||||
// DropdownMenu renders an enhanced dropdown menu component
|
||||
// It can be customized with various styles, positions, and behaviors.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.DropdownMenu(components.DropdownMenuProps{
|
||||
// Trigger: components.Button(components.ButtonProps{
|
||||
// Text: "Open Menu",
|
||||
// IconRight: components.Icon(components.IconProps{Name: "chevron-down"}),
|
||||
// }),
|
||||
// Position: "bottom",
|
||||
// Items: []components.DropdownMenuItem{
|
||||
// {Label: "Option 1", Value: "opt1"},
|
||||
// {Label: "Option 2", Value: "opt2", IconLeft: components.Icon(components.IconProps{Name: "settings"})},
|
||||
// {Label: "Submenu", SubItems: []components.DropdownMenuItem{
|
||||
// {Label: "Sub Option 1", Value: "sub1"},
|
||||
// {Label: "Sub Option 2", Value: "sub2"},
|
||||
// }},
|
||||
// },
|
||||
// })
|
||||
// DropdownMenu renders a customizable popup menu with positioning and nesting support.
|
||||
// Uses Alpine.js for interactions and supports keyboard navigation.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/dropdown-menu
|
||||
//
|
||||
// Props:
|
||||
// - Items: Slice of DropdownMenuItem, defining the content of the dropdown
|
||||
// - Trigger: Custom component to trigger the dropdown (optional, default is a basic button)
|
||||
// - Class: Additional CSS classes to apply to the root element
|
||||
// - Position: Preferred position of the dropdown ("left", "right", "top", or "bottom")
|
||||
// - Attributes: Additional HTML attributes to apply to the accordion container element. Default: nil
|
||||
// - Items: Menu structure and content
|
||||
// - Trigger: Custom trigger element (optional)
|
||||
// - Class: Additional CSS classes
|
||||
// - Position: Preferred placement
|
||||
//
|
||||
// Features:
|
||||
// - Supports nested submenus up to 3 levels deep
|
||||
// - Automatically adjusts position based on available space
|
||||
// - Supports custom icons for menu items
|
||||
// - Handles disabled states for menu items
|
||||
// - Uses Tailwind CSS for styling, including dark mode support
|
||||
// - Implements keyboard navigation and ARIA attributes for accessibility
|
||||
// - Nested submenus (up to 3 levels)
|
||||
// - Automatic position adjustment
|
||||
// - Keyboard navigation
|
||||
// - ARIA support
|
||||
templ DropdownMenu(props DropdownMenuProps) {
|
||||
<div
|
||||
x-data="{
|
||||
|
@ -15,29 +15,50 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// DropdownMenuItem represents an item in the dropdown menu
|
||||
type DropdownMenuItem struct {
|
||||
Label string // The text to display for the menu item
|
||||
Value string // The value associated with the menu item (for non-link items)
|
||||
Href string // The URL to navigate to if the item is a link
|
||||
Target string // The target attribute for link items (e.g., "_blank" for new tab)
|
||||
IconLeft templ.Component // An optional icon component to display on the left side of the item
|
||||
IconRight templ.Component // An optional icon component to display on the right side of the item
|
||||
SubItems []DropdownMenuItem // A slice of DropdownMenuItems for nested submenus
|
||||
Disabled bool // Whether the item is disabled or not
|
||||
// Attributes allows passing additional HTML attributes to the accordion container element.
|
||||
// Default: nil
|
||||
// Label displays text for the menu item
|
||||
Label string
|
||||
|
||||
// Value for non-link menu items
|
||||
Value string
|
||||
|
||||
// Href makes item a navigation link
|
||||
Href string
|
||||
|
||||
// Target controls link opening behavior
|
||||
Target string
|
||||
|
||||
// IconLeft displays icon before label
|
||||
IconLeft templ.Component
|
||||
|
||||
// IconRight displays icon after label
|
||||
IconRight templ.Component
|
||||
|
||||
// SubItems creates nested submenu
|
||||
SubItems []DropdownMenuItem
|
||||
|
||||
// Disabled controls interactive state
|
||||
Disabled bool
|
||||
|
||||
// Attributes for additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// DropdownMenuProps defines the properties for the DropdownMenu component
|
||||
type DropdownMenuProps struct {
|
||||
Items []DropdownMenuItem // The list of items to display in the dropdown menu
|
||||
Trigger templ.Component // An optional custom trigger component (default is a button if not provided)
|
||||
Class string // Additional CSS classes to apply to the root element
|
||||
Position string // The preferred position of the dropdown ("left", "right", "top", or "bottom")
|
||||
// Items defines the menu structure
|
||||
Items []DropdownMenuItem
|
||||
|
||||
// Trigger overrides default button trigger
|
||||
Trigger templ.Component
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Position sets preferred menu placement (left, right, top, bottom)
|
||||
Position string
|
||||
}
|
||||
|
||||
// ModifierClasses generates state-based CSS classes
|
||||
func (d DropdownMenuItem) ModifierClasses() string {
|
||||
classes := []string{}
|
||||
if d.Disabled {
|
||||
@ -48,8 +69,8 @@ func (d DropdownMenuItem) ModifierClasses() string {
|
||||
return strings.Join(classes, " ")
|
||||
}
|
||||
|
||||
// renderMenuItem is a helper function to render a single menu item
|
||||
// It handles rendering of regular items, links, and submenus recursively
|
||||
// renderMenuItem handles recursive menu item rendering
|
||||
// Supports regular items, links, and nested submenus up to 3 levels
|
||||
func renderMenuItem(item DropdownMenuItem, index int, depth int) templ.Component {
|
||||
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
|
||||
@ -106,7 +127,7 @@ func renderMenuItem(item DropdownMenuItem, index int, depth int) templ.Component
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("menu-item-%d", index))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 57, Col: 43}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 78, Col: 43}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -139,7 +160,7 @@ func renderMenuItem(item DropdownMenuItem, index int, depth int) templ.Component
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(item.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 67, Col: 17}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 88, Col: 17}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -210,7 +231,7 @@ func renderMenuItem(item DropdownMenuItem, index int, depth int) templ.Component
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(item.Target)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 88, Col: 23}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 109, Col: 23}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -236,7 +257,7 @@ func renderMenuItem(item DropdownMenuItem, index int, depth int) templ.Component
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("menu-item-%d", index))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 96, Col: 42}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 117, Col: 42}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -263,7 +284,7 @@ func renderMenuItem(item DropdownMenuItem, index int, depth int) templ.Component
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(item.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 103, Col: 16}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 124, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -321,7 +342,7 @@ func renderMenuItem(item DropdownMenuItem, index int, depth int) templ.Component
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("menu-item-%d", index))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 120, Col: 42}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 141, Col: 42}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -354,7 +375,7 @@ func renderMenuItem(item DropdownMenuItem, index int, depth int) templ.Component
|
||||
var templ_7745c5c3_Var15 string
|
||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(item.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 128, Col: 16}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 149, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -379,41 +400,21 @@ func renderMenuItem(item DropdownMenuItem, index int, depth int) templ.Component
|
||||
})
|
||||
}
|
||||
|
||||
// DropdownMenu renders an enhanced dropdown menu component
|
||||
// It can be customized with various styles, positions, and behaviors.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.DropdownMenu(components.DropdownMenuProps{
|
||||
// Trigger: components.Button(components.ButtonProps{
|
||||
// Text: "Open Menu",
|
||||
// IconRight: components.Icon(components.IconProps{Name: "chevron-down"}),
|
||||
// }),
|
||||
// Position: "bottom",
|
||||
// Items: []components.DropdownMenuItem{
|
||||
// {Label: "Option 1", Value: "opt1"},
|
||||
// {Label: "Option 2", Value: "opt2", IconLeft: components.Icon(components.IconProps{Name: "settings"})},
|
||||
// {Label: "Submenu", SubItems: []components.DropdownMenuItem{
|
||||
// {Label: "Sub Option 1", Value: "sub1"},
|
||||
// {Label: "Sub Option 2", Value: "sub2"},
|
||||
// }},
|
||||
// },
|
||||
// })
|
||||
// DropdownMenu renders a customizable popup menu with positioning and nesting support.
|
||||
// Uses Alpine.js for interactions and supports keyboard navigation.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/dropdown-menu
|
||||
//
|
||||
// Props:
|
||||
// - Items: Slice of DropdownMenuItem, defining the content of the dropdown
|
||||
// - Trigger: Custom component to trigger the dropdown (optional, default is a basic button)
|
||||
// - Class: Additional CSS classes to apply to the root element
|
||||
// - Position: Preferred position of the dropdown ("left", "right", "top", or "bottom")
|
||||
// - Attributes: Additional HTML attributes to apply to the accordion container element. Default: nil
|
||||
// - Items: Menu structure and content
|
||||
// - Trigger: Custom trigger element (optional)
|
||||
// - Class: Additional CSS classes
|
||||
// - Position: Preferred placement
|
||||
//
|
||||
// Features:
|
||||
// - Supports nested submenus up to 3 levels deep
|
||||
// - Automatically adjusts position based on available space
|
||||
// - Supports custom icons for menu items
|
||||
// - Handles disabled states for menu items
|
||||
// - Uses Tailwind CSS for styling, including dark mode support
|
||||
// - Implements keyboard navigation and ARIA attributes for accessibility
|
||||
// - Nested submenus (up to 3 levels)
|
||||
// - Automatic position adjustment
|
||||
// - Keyboard navigation
|
||||
// - ARIA support
|
||||
func DropdownMenu(props DropdownMenuProps) templ.Component {
|
||||
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
|
||||
@ -460,7 +461,7 @@ func DropdownMenu(props DropdownMenuProps) templ.Component {
|
||||
var templ_7745c5c3_Var19 string
|
||||
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(props.Position)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 199, Col: 32}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/dropdown_menu.templ`, Line: 200, Col: 32}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
@ -2,116 +2,113 @@ package components
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// InputType represents the type of the input field.
|
||||
// InputType defines the available input field types
|
||||
type InputType string
|
||||
|
||||
// Constants for input types.
|
||||
const (
|
||||
Text InputType = "text"
|
||||
Password InputType = "password"
|
||||
Email InputType = "email"
|
||||
Number InputType = "number"
|
||||
Tel InputType = "tel"
|
||||
URL InputType = "url"
|
||||
Search InputType = "search"
|
||||
Date InputType = "date"
|
||||
Time InputType = "time"
|
||||
File InputType = "file"
|
||||
// Standard text inputs
|
||||
InputTypeText InputType = "text"
|
||||
InputTypePassword InputType = "password"
|
||||
InputTypeEmail InputType = "email"
|
||||
InputTypeNumber InputType = "number"
|
||||
InputTypeTel InputType = "tel"
|
||||
InputTypeURL InputType = "url"
|
||||
InputTypeSearch InputType = "search"
|
||||
|
||||
// Date and time inputs
|
||||
InputTypeDate InputType = "date"
|
||||
InputTypeTime InputType = "time"
|
||||
|
||||
// File upload input
|
||||
InputTypeFile InputType = "file"
|
||||
)
|
||||
|
||||
// InputProps defines the properties for the Input component.
|
||||
type InputProps struct {
|
||||
// Type specifies the type of the input field.
|
||||
// Default: Text
|
||||
// Type sets the input field behavior
|
||||
Type InputType
|
||||
|
||||
// Placeholder is the placeholder text for the input field.
|
||||
// Default: "" (empty string)
|
||||
// Placeholder shows helper text when empty
|
||||
Placeholder string
|
||||
|
||||
// Value is the current value of the input field.
|
||||
// Default: "" (empty string)
|
||||
// Value sets the current input content
|
||||
Value string
|
||||
|
||||
// Name is the name attribute of the input field.
|
||||
// Default: "" (empty string)
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// ID is the unique identifier for the input field.
|
||||
// Default: "" (empty string)
|
||||
// ID uniquely identifies the input
|
||||
ID string
|
||||
|
||||
// Class specifies additional CSS classes to apply to the input field.
|
||||
// Default: "" (empty string)
|
||||
// Label displays text above input
|
||||
Label string
|
||||
|
||||
// Description shows helper text below input
|
||||
Description string
|
||||
|
||||
// Error displays validation message
|
||||
Error string
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Disabled can be either a bool or a string.
|
||||
// If bool (Go), it directly controls the disabled state.
|
||||
// If string, it's treated as a JavaScript expression for dynamic disabling.
|
||||
// Default: nil
|
||||
Disabled any
|
||||
|
||||
// FileAccept specifies which file types are accepted (only for file type).
|
||||
// Default: "" (empty string)
|
||||
// FileAccept limits allowed file types
|
||||
// Only used when Type is InputTypeFile
|
||||
FileAccept string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the input element.
|
||||
// Default: nil
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Input renders an input component based on the provided props.
|
||||
// It can be customized with various types, sizes, and behaviors.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Input(components.InputProps{
|
||||
// Type: components.Email,
|
||||
// Placeholder: "Enter your email",
|
||||
// ID: "email-input",
|
||||
// Class: "custom-input",
|
||||
// Attributes: templ.Attributes{
|
||||
// "aria-label": "Email input",
|
||||
// "data-testid": "email-input",
|
||||
// },
|
||||
// })
|
||||
// Input renders a form input field with optional label and validation.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/input
|
||||
//
|
||||
// Props:
|
||||
// - Type: The type of the input field (e.g., Text, Email, Password). Default: Text
|
||||
// - Placeholder: The placeholder text for the input field. Default: "" (empty string)
|
||||
// - Value: The current value of the input field. Default: "" (empty string)
|
||||
// - Name: The name attribute of the input field. Default: "" (empty string)
|
||||
// - ID: The unique identifier for the input field. Default: "" (empty string)
|
||||
// - Class: Additional CSS classes to apply to the input field. Default: "" (empty string)
|
||||
// - Disabled: Can be either a bool or a string. If bool (Go), it directly controls the disabled state. If string, it's treated as a JavaScript expression for dynamic disabling. Default: nil
|
||||
// - FileAccept: Specifies which file types are accepted (only for file type). Default: "" (empty string)
|
||||
// - Attributes: Additional HTML attributes to apply to the input element. Default: nil
|
||||
// - Type: Input field behavior type
|
||||
// - Placeholder: Helper text when empty
|
||||
// - Value: Current input value
|
||||
// - Name: Form field name
|
||||
// - ID: Unique identifier
|
||||
// - Label: Text label
|
||||
// - Description: Helper text
|
||||
// - Error: Validation message
|
||||
// - Class: Additional CSS classes
|
||||
// - FileAccept: Allowed file types
|
||||
// - Attributes: Additional HTML attributes
|
||||
templ Input(props InputProps) {
|
||||
<input
|
||||
type={ string(props.Type) }
|
||||
placeholder={ props.Placeholder }
|
||||
value={ props.Value }
|
||||
name={ props.Name }
|
||||
id={ props.ID }
|
||||
class={
|
||||
utils.TwMerge("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),
|
||||
<span class="space-y-2">
|
||||
if props.Label != "" {
|
||||
<label
|
||||
for={ props.ID }
|
||||
class={ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
templ.KV("text-destructive", len(props.Error)>0) }
|
||||
>
|
||||
{ props.Label }
|
||||
</label>
|
||||
}
|
||||
if props.Disabled != nil {
|
||||
if disabledBool, ok := props.Disabled.(bool); ok && disabledBool {
|
||||
disabled="true"
|
||||
<input
|
||||
type={ string(props.Type) }
|
||||
placeholder={ props.Placeholder }
|
||||
name={ props.Name }
|
||||
value={ props.Value }
|
||||
id={ props.ID }
|
||||
class={
|
||||
utils.TwMerge("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 disabledStr, ok := props.Disabled.(string); ok {
|
||||
:disabled={ disabledStr }
|
||||
if props.Type == InputTypeFile {
|
||||
accept={ props.FileAccept }
|
||||
}
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
if props.Description != "" {
|
||||
<p class="text-sm text-muted-foreground m-0">{ props.Description }</p>
|
||||
}
|
||||
if props.Type == File {
|
||||
accept={ props.FileAccept }
|
||||
if props.Error != "" {
|
||||
<p class="text-sm font-medium text-destructive">{ props.Error }</p>
|
||||
}
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
</span>
|
||||
}
|
||||
|
@ -10,90 +10,78 @@ import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// InputType represents the type of the input field.
|
||||
// InputType defines the available input field types
|
||||
type InputType string
|
||||
|
||||
// Constants for input types.
|
||||
const (
|
||||
Text InputType = "text"
|
||||
Password InputType = "password"
|
||||
Email InputType = "email"
|
||||
Number InputType = "number"
|
||||
Tel InputType = "tel"
|
||||
URL InputType = "url"
|
||||
Search InputType = "search"
|
||||
Date InputType = "date"
|
||||
Time InputType = "time"
|
||||
File InputType = "file"
|
||||
// Standard text inputs
|
||||
InputTypeText InputType = "text"
|
||||
InputTypePassword InputType = "password"
|
||||
InputTypeEmail InputType = "email"
|
||||
InputTypeNumber InputType = "number"
|
||||
InputTypeTel InputType = "tel"
|
||||
InputTypeURL InputType = "url"
|
||||
InputTypeSearch InputType = "search"
|
||||
|
||||
// Date and time inputs
|
||||
InputTypeDate InputType = "date"
|
||||
InputTypeTime InputType = "time"
|
||||
|
||||
// File upload input
|
||||
InputTypeFile InputType = "file"
|
||||
)
|
||||
|
||||
// InputProps defines the properties for the Input component.
|
||||
type InputProps struct {
|
||||
// Type specifies the type of the input field.
|
||||
// Default: Text
|
||||
// Type sets the input field behavior
|
||||
Type InputType
|
||||
|
||||
// Placeholder is the placeholder text for the input field.
|
||||
// Default: "" (empty string)
|
||||
// Placeholder shows helper text when empty
|
||||
Placeholder string
|
||||
|
||||
// Value is the current value of the input field.
|
||||
// Default: "" (empty string)
|
||||
// Value sets the current input content
|
||||
Value string
|
||||
|
||||
// Name is the name attribute of the input field.
|
||||
// Default: "" (empty string)
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// ID is the unique identifier for the input field.
|
||||
// Default: "" (empty string)
|
||||
// ID uniquely identifies the input
|
||||
ID string
|
||||
|
||||
// Class specifies additional CSS classes to apply to the input field.
|
||||
// Default: "" (empty string)
|
||||
// Label displays text above input
|
||||
Label string
|
||||
|
||||
// Description shows helper text below input
|
||||
Description string
|
||||
|
||||
// Error displays validation message
|
||||
Error string
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Disabled can be either a bool or a string.
|
||||
// If bool (Go), it directly controls the disabled state.
|
||||
// If string, it's treated as a JavaScript expression for dynamic disabling.
|
||||
// Default: nil
|
||||
Disabled any
|
||||
|
||||
// FileAccept specifies which file types are accepted (only for file type).
|
||||
// Default: "" (empty string)
|
||||
// FileAccept limits allowed file types
|
||||
// Only used when Type is InputTypeFile
|
||||
FileAccept string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the input element.
|
||||
// Default: nil
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Input renders an input component based on the provided props.
|
||||
// It can be customized with various types, sizes, and behaviors.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Input(components.InputProps{
|
||||
// Type: components.Email,
|
||||
// Placeholder: "Enter your email",
|
||||
// ID: "email-input",
|
||||
// Class: "custom-input",
|
||||
// Attributes: templ.Attributes{
|
||||
// "aria-label": "Email input",
|
||||
// "data-testid": "email-input",
|
||||
// },
|
||||
// })
|
||||
// Input renders a form input field with optional label and validation.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/input
|
||||
//
|
||||
// Props:
|
||||
// - Type: The type of the input field (e.g., Text, Email, Password). Default: Text
|
||||
// - Placeholder: The placeholder text for the input field. Default: "" (empty string)
|
||||
// - Value: The current value of the input field. Default: "" (empty string)
|
||||
// - Name: The name attribute of the input field. Default: "" (empty string)
|
||||
// - ID: The unique identifier for the input field. Default: "" (empty string)
|
||||
// - Class: Additional CSS classes to apply to the input field. Default: "" (empty string)
|
||||
// - Disabled: Can be either a bool or a string. If bool (Go), it directly controls the disabled state. If string, it's treated as a JavaScript expression for dynamic disabling. Default: nil
|
||||
// - FileAccept: Specifies which file types are accepted (only for file type). Default: "" (empty string)
|
||||
// - Attributes: Additional HTML attributes to apply to the input element. Default: nil
|
||||
// - Type: Input field behavior type
|
||||
// - Placeholder: Helper text when empty
|
||||
// - Value: Current input value
|
||||
// - Name: Form field name
|
||||
// - ID: Unique identifier
|
||||
// - Label: Text label
|
||||
// - Description: Helper text
|
||||
// - Error: Validation message
|
||||
// - Class: Additional CSS classes
|
||||
// - FileAccept: Allowed file types
|
||||
// - Attributes: Additional HTML attributes
|
||||
func Input(props InputProps) templ.Component {
|
||||
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
|
||||
@ -115,7 +103,62 @@ func Input(props InputProps) templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var2 = []any{
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"space-y-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Label != "" {
|
||||
var templ_7745c5c3_Var2 = []any{"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
templ.KV("text-destructive", len(props.Error) > 0)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label for=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 81, Col: 18}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
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
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 85, Col: 17}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
var templ_7745c5c3_Var6 = []any{
|
||||
utils.TwMerge("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",
|
||||
@ -123,7 +166,7 @@ func Input(props InputProps) templ.Component {
|
||||
"file:text-foreground dark:file:text-foreground",
|
||||
props.Class),
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -131,12 +174,12 @@ func Input(props InputProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(string(props.Type))
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(string(props.Type))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 91, Col: 27}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 89, Col: 28}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -144,25 +187,12 @@ func Input(props InputProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.Placeholder)
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.Placeholder)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 92, Col: 33}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 90, Col: 34}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 93, Col: 21}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -170,12 +200,25 @@ func Input(props InputProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 94, Col: 19}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 91, Col: 20}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 92, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -183,12 +226,12 @@ func Input(props InputProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 95, Col: 15}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 93, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -196,12 +239,12 @@ func Input(props InputProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -209,44 +252,17 @@ func Input(props InputProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Disabled != nil {
|
||||
if disabledBool, ok := props.Disabled.(bool); ok && disabledBool {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" disabled=\"true\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
if disabledStr, ok := props.Disabled.(string); ok {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" :disabled=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(disabledStr)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 109, Col: 27}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
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 props.Type == File {
|
||||
if props.Type == InputTypeFile {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" accept=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(props.FileAccept)
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(props.FileAccept)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 113, Col: 28}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 103, Col: 29}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -259,7 +275,49 @@ func Input(props InputProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(">")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Description != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"text-sm text-muted-foreground m-0\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(props.Description)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 108, Col: 67}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
if props.Error != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"text-sm font-medium text-destructive\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var15 string
|
||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(props.Error)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/input.templ`, Line: 111, Col: 64}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
@ -2,51 +2,21 @@ package components
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// ModalProps defines the properties for the Modal component.
|
||||
type ModalProps struct {
|
||||
// ID is a unique identifier for the modal.
|
||||
// It's used to control opening and closing.
|
||||
// This should be unique across your application.
|
||||
// ID uniquely identifies the modal for open/close control
|
||||
ID string
|
||||
|
||||
// Class specifies additional CSS classes to apply to the modal container.
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
}
|
||||
|
||||
// Modal renders a modal dialog component.
|
||||
// It uses Alpine.js for state management and animations.
|
||||
// Modal renders a popup dialog window with customizable content.
|
||||
// Uses Alpine.js for interactions and animations.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/modal
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.ModalTrigger("default-modal") {
|
||||
// @components.Button(components.ButtonProps{Text: "Open Modal"})
|
||||
// }
|
||||
//
|
||||
// @components.Modal(components.ModalProps{ID: "default-modal", Class: "max-w-md"}) {
|
||||
// @components.ModalHeader() {
|
||||
// Are you absolutely sure?
|
||||
// }
|
||||
// @components.ModalBody() {
|
||||
// This action cannot be undone. This will permanently delete your account and remove your data from our servers.
|
||||
// }
|
||||
// @components.ModalFooter() {
|
||||
// <div class="flex gap-2">
|
||||
// @components.ModalClose("default-modal") {
|
||||
// @components.Button(components.ButtonProps{
|
||||
// Text: "Cancel",
|
||||
// })
|
||||
// }
|
||||
// @components.ModalClose("default-modal") {
|
||||
// @components.Button(components.ButtonProps{
|
||||
// Text: "Continue",
|
||||
// Variant: components.Secondary,
|
||||
// })
|
||||
// }
|
||||
// </div>
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// The Modal component should be used in conjunction with ModalTrigger to open it.
|
||||
// Props:
|
||||
// - ID: Unique identifier for control
|
||||
// - Class: Additional CSS classes
|
||||
templ Modal(props ModalProps) {
|
||||
<div
|
||||
x-data="{ open: false }"
|
||||
@ -79,15 +49,8 @@ templ Modal(props ModalProps) {
|
||||
</div>
|
||||
}
|
||||
|
||||
// ModalTrigger renders an element that opens the modal when clicked.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.ModalTrigger("example-modal") {
|
||||
// @components.Button(components.ButtonProps{Text: "Open Modal"})
|
||||
// }
|
||||
//
|
||||
// The 'id' parameter should match the ID of the Modal you want to open.
|
||||
// ModalTrigger creates clickable elements that open a modal
|
||||
// ID parameter must match the target modal's ID
|
||||
templ ModalTrigger(id string) {
|
||||
<span
|
||||
data-modal-id={ id }
|
||||
@ -97,18 +60,8 @@ templ ModalTrigger(id string) {
|
||||
</span>
|
||||
}
|
||||
|
||||
// ModalClose renders an element that closes the modal when clicked.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.ModalClose("example-modal") {
|
||||
// @components.Button(components.ButtonProps{
|
||||
// Text: "Close",
|
||||
// Variant: components.Secondary,
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// The 'id' parameter should match the ID of the Modal you want to close.
|
||||
// ModalClose creates clickable elements that close a modal
|
||||
// ID parameter must match the target modal's ID
|
||||
templ ModalClose(id string) {
|
||||
<span
|
||||
data-modal-id={ id }
|
||||
@ -118,14 +71,7 @@ templ ModalClose(id string) {
|
||||
</span>
|
||||
}
|
||||
|
||||
// ModalHeader renders the header section of the modal.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.ModalHeader() {
|
||||
// Modal Title
|
||||
// @components.ModalClose("example-modal")
|
||||
// }
|
||||
// ModalHeader renders the modal title section
|
||||
templ ModalHeader() {
|
||||
<div class="px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||
<h3 class="text-lg leading-6 font-medium text-foreground" id="modal-title">
|
||||
@ -134,31 +80,14 @@ templ ModalHeader() {
|
||||
</div>
|
||||
}
|
||||
|
||||
// ModalBody renders the main content area of the modal.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.ModalBody() {
|
||||
// <p>This is the modal content.</p>
|
||||
// }
|
||||
/// ModalBody renders the main modal content area
|
||||
templ ModalBody() {
|
||||
<div class="px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
|
||||
{ children... }
|
||||
</div>
|
||||
}
|
||||
|
||||
// ModalFooter renders the footer section of the modal, typically containing action buttons.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.ModalFooter() {
|
||||
// @components.ModalClose("example-modal") {
|
||||
// @components.Button(components.ButtonProps{
|
||||
// Text: "Close",
|
||||
// Variant: components.Secondary,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// ModalFooter renders the modal action buttons section
|
||||
templ ModalFooter() {
|
||||
<div class="px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
|
||||
{ children... }
|
||||
|
@ -10,51 +10,21 @@ import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// ModalProps defines the properties for the Modal component.
|
||||
type ModalProps struct {
|
||||
// ID is a unique identifier for the modal.
|
||||
// It's used to control opening and closing.
|
||||
// This should be unique across your application.
|
||||
// ID uniquely identifies the modal for open/close control
|
||||
ID string
|
||||
|
||||
// Class specifies additional CSS classes to apply to the modal container.
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
}
|
||||
|
||||
// Modal renders a modal dialog component.
|
||||
// It uses Alpine.js for state management and animations.
|
||||
// Modal renders a popup dialog window with customizable content.
|
||||
// Uses Alpine.js for interactions and animations.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/modal
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.ModalTrigger("default-modal") {
|
||||
// @components.Button(components.ButtonProps{Text: "Open Modal"})
|
||||
// }
|
||||
//
|
||||
// @components.Modal(components.ModalProps{ID: "default-modal", Class: "max-w-md"}) {
|
||||
// @components.ModalHeader() {
|
||||
// Are you absolutely sure?
|
||||
// }
|
||||
// @components.ModalBody() {
|
||||
// This action cannot be undone. This will permanently delete your account and remove your data from our servers.
|
||||
// }
|
||||
// @components.ModalFooter() {
|
||||
// <div class="flex gap-2">
|
||||
// @components.ModalClose("default-modal") {
|
||||
// @components.Button(components.ButtonProps{
|
||||
// Text: "Cancel",
|
||||
// })
|
||||
// }
|
||||
// @components.ModalClose("default-modal") {
|
||||
// @components.Button(components.ButtonProps{
|
||||
// Text: "Continue",
|
||||
// Variant: components.Secondary,
|
||||
// })
|
||||
// }
|
||||
// </div>
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// The Modal component should be used in conjunction with ModalTrigger to open it.
|
||||
// Props:
|
||||
// - ID: Unique identifier for control
|
||||
// - Class: Additional CSS classes
|
||||
func Modal(props ModalProps) templ.Component {
|
||||
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
|
||||
@ -83,7 +53,7 @@ func Modal(props ModalProps) templ.Component {
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/modal.templ`, Line: 55, Col: 26}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/modal.templ`, Line: 25, Col: 26}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -131,15 +101,8 @@ func Modal(props ModalProps) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// ModalTrigger renders an element that opens the modal when clicked.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.ModalTrigger("example-modal") {
|
||||
// @components.Button(components.ButtonProps{Text: "Open Modal"})
|
||||
// }
|
||||
//
|
||||
// The 'id' parameter should match the ID of the Modal you want to open.
|
||||
// ModalTrigger creates clickable elements that open a modal
|
||||
// ID parameter must match the target modal's ID
|
||||
func ModalTrigger(id string) templ.Component {
|
||||
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
|
||||
@ -168,7 +131,7 @@ func ModalTrigger(id string) templ.Component {
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(id)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/modal.templ`, Line: 93, Col: 20}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/modal.templ`, Line: 56, Col: 20}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -190,18 +153,8 @@ func ModalTrigger(id string) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// ModalClose renders an element that closes the modal when clicked.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.ModalClose("example-modal") {
|
||||
// @components.Button(components.ButtonProps{
|
||||
// Text: "Close",
|
||||
// Variant: components.Secondary,
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// The 'id' parameter should match the ID of the Modal you want to close.
|
||||
// ModalClose creates clickable elements that close a modal
|
||||
// ID parameter must match the target modal's ID
|
||||
func ModalClose(id string) templ.Component {
|
||||
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
|
||||
@ -230,7 +183,7 @@ func ModalClose(id string) templ.Component {
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(id)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/modal.templ`, Line: 114, Col: 20}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/modal.templ`, Line: 67, Col: 20}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -252,14 +205,7 @@ func ModalClose(id string) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// ModalHeader renders the header section of the modal.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.ModalHeader() {
|
||||
// Modal Title
|
||||
// @components.ModalClose("example-modal")
|
||||
// }
|
||||
// ModalHeader renders the modal title section
|
||||
func ModalHeader() templ.Component {
|
||||
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
|
||||
@ -297,13 +243,7 @@ func ModalHeader() templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// ModalBody renders the main content area of the modal.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.ModalBody() {
|
||||
// <p>This is the modal content.</p>
|
||||
// }
|
||||
// / ModalBody renders the main modal content area
|
||||
func ModalBody() templ.Component {
|
||||
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
|
||||
@ -341,18 +281,7 @@ func ModalBody() templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// ModalFooter renders the footer section of the modal, typically containing action buttons.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.ModalFooter() {
|
||||
// @components.ModalClose("example-modal") {
|
||||
// @components.Button(components.ButtonProps{
|
||||
// Text: "Close",
|
||||
// Variant: components.Secondary,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// ModalFooter renders the modal action buttons section
|
||||
func ModalFooter() templ.Component {
|
||||
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
|
||||
|
@ -1,77 +1,48 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// RadioGroupProps defines the properties for the RadioGroup component.
|
||||
type RadioGroupProps struct {
|
||||
// DefaultValue is the initial selected value for the radio group.
|
||||
DefaultValue string
|
||||
|
||||
// Name is the name attribute for the radio group, used to group radio buttons.
|
||||
// Name groups related radio buttons
|
||||
Name string
|
||||
|
||||
// Required indicates whether the radio group is a required field.
|
||||
Required bool
|
||||
|
||||
// Class specifies additional CSS classes to apply to the radio group container.
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the radio group container.
|
||||
// Attributes for additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// RadioGroupItemProps defines the properties for the RadioGroupItem component.
|
||||
type RadioGroupItemProps struct {
|
||||
// Value is the value attribute for the radio button.
|
||||
// Value sets the radio button value
|
||||
Value string
|
||||
|
||||
// Name is the name attribute for the radio button, should match the RadioGroup's name.
|
||||
// Name matches parent RadioGroup name
|
||||
Name string
|
||||
|
||||
// ID is the unique identifier for the radio button, used for labeling.
|
||||
// ID uniquely identifies the radio button
|
||||
ID string
|
||||
|
||||
// Disabled is a string representing an Alpine.js expression for the disabled state.
|
||||
// It can be a boolean value ("true" or "false") or a more complex condition.
|
||||
// Examples:
|
||||
// - "true" for always disabled
|
||||
// - "false" for never disabled
|
||||
// - "someVariable" to bind to an Alpine.js data property
|
||||
// - "someCondition === true" for a dynamic condition
|
||||
Disabled string
|
||||
// Label displays text next to radio button
|
||||
Label templ.Component
|
||||
|
||||
// Class specifies additional CSS classes to apply to the radio button container.
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the radio button.
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
|
||||
// Label is a templ.Component that represents the label for the radio button.
|
||||
// If not provided, the Value will be used as the label text.
|
||||
Label templ.Component
|
||||
}
|
||||
|
||||
// RadioGroup renders a group of radio buttons.
|
||||
// It uses Alpine.js for managing the selected state.
|
||||
// RadioGroup renders a set of mutually exclusive radio button options.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/radio-group
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.RadioGroup(components.RadioGroupProps{
|
||||
// DefaultValue: "option1",
|
||||
// Name: "myRadioGroup",
|
||||
// Required: true,
|
||||
// Class: "my-custom-class",
|
||||
// }) {
|
||||
// // RadioGroupItem components go here
|
||||
// }
|
||||
// Props:
|
||||
// - Name: Groups related radio buttons
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
templ RadioGroup(props RadioGroupProps) {
|
||||
<div
|
||||
role="radiogroup"
|
||||
aria-required={ fmt.Sprintf("%t", props.Required) }
|
||||
x-data={ fmt.Sprintf(`{ selectedValue: '%s' }`, props.DefaultValue) }
|
||||
class={ utils.TwMerge("space-y-2", props.Class) }
|
||||
{ props.Attributes... }
|
||||
>
|
||||
@ -79,71 +50,47 @@ templ RadioGroup(props RadioGroupProps) {
|
||||
</div>
|
||||
}
|
||||
|
||||
// RadioGroupItem renders a single radio button with an integrated label.
|
||||
// It uses Alpine.js for managing the disabled state and selected value.
|
||||
// RadioGroupItem renders an individual radio button with label.
|
||||
// Must be used within a RadioGroup component.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
// Value: "option1",
|
||||
// Name: "myRadioGroup",
|
||||
// ID: "option1",
|
||||
// Disabled: "someCondition === true", // Alpine.js expression
|
||||
// Label: templ.Raw("Option 1"),
|
||||
// })
|
||||
// Props:
|
||||
// - Value: Radio button value
|
||||
// - Name: Matches parent group name
|
||||
// - ID: Unique identifier
|
||||
// - Label: Button label
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
templ RadioGroupItem(props RadioGroupItemProps) {
|
||||
<style>
|
||||
/* Custom styles for radio buttons */
|
||||
input[type="radio"] {
|
||||
position: relative;
|
||||
}
|
||||
input[type="radio"]:checked::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background-color: hsl(var(--background));
|
||||
}
|
||||
input[type="radio"]:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px hsl(var(--ring) / 50%);
|
||||
}
|
||||
</style>
|
||||
<div
|
||||
class={ utils.TwMerge("flex items-center space-x-2", props.Class) }
|
||||
x-data={ fmt.Sprintf(`{ isDisabled: %s }`, props.Disabled) }
|
||||
<label
|
||||
for={ props.ID }
|
||||
class={ utils.TwMerge(
|
||||
"flex items-center gap-2 cursor-pointer text-sm font-medium",
|
||||
"text-muted-foreground [&:has(input:checked)]:text-foreground",
|
||||
"[&:has(input:disabled)]:cursor-not-allowed [&:has(input:disabled)]:opacity-50",
|
||||
props.Class,
|
||||
) }
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
value={ props.Value }
|
||||
:disabled="isDisabled"
|
||||
x-model="selectedValue"
|
||||
class={
|
||||
"h-4 w-4 translate-y-px appearance-none rounded-full border bg-background checked:border-primary checked:bg-primary",
|
||||
"disabled:opacity-50 disabled:cursor-not-allowed",
|
||||
}
|
||||
style="
|
||||
border-color: hsl(var(--input));
|
||||
transition: all 0.2s ease-in-out;
|
||||
"
|
||||
class="before:content[''] relative h-4 w-4 appearance-none rounded-full
|
||||
border border-2 border-primary
|
||||
checked:border-primary checked:bg-primary
|
||||
before:absolute before:left-1/2 before:top-1/2
|
||||
before:h-1.5 before:w-1.5 before:-translate-x-1/2 before:-translate-y-1/2
|
||||
before:rounded-full before:bg-background
|
||||
checked:before:visible
|
||||
focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring
|
||||
focus-visible:ring-offset-2 focus-visible:ring-offset-background
|
||||
disabled:cursor-not-allowed"
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
<label
|
||||
for={ props.ID }
|
||||
class={ "text-sm font-medium leading-none text-foreground" }
|
||||
:class="{ 'opacity-50 cursor-not-allowed': isDisabled }"
|
||||
>
|
||||
if props.Label != nil {
|
||||
@props.Label
|
||||
} else {
|
||||
{ props.Value }
|
||||
}
|
||||
</label>
|
||||
</div>
|
||||
if props.Label != nil {
|
||||
@props.Label
|
||||
} else {
|
||||
<span>{ props.Value }</span>
|
||||
}
|
||||
</label>
|
||||
}
|
||||
|
@ -8,73 +8,46 @@ package components
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
import "github.com/axzilla/goilerplate/pkg/utils"
|
||||
|
||||
// RadioGroupProps defines the properties for the RadioGroup component.
|
||||
type RadioGroupProps struct {
|
||||
// DefaultValue is the initial selected value for the radio group.
|
||||
DefaultValue string
|
||||
|
||||
// Name is the name attribute for the radio group, used to group radio buttons.
|
||||
// Name groups related radio buttons
|
||||
Name string
|
||||
|
||||
// Required indicates whether the radio group is a required field.
|
||||
Required bool
|
||||
|
||||
// Class specifies additional CSS classes to apply to the radio group container.
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the radio group container.
|
||||
// Attributes for additional HTML attributes
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// RadioGroupItemProps defines the properties for the RadioGroupItem component.
|
||||
type RadioGroupItemProps struct {
|
||||
// Value is the value attribute for the radio button.
|
||||
// Value sets the radio button value
|
||||
Value string
|
||||
|
||||
// Name is the name attribute for the radio button, should match the RadioGroup's name.
|
||||
// Name matches parent RadioGroup name
|
||||
Name string
|
||||
|
||||
// ID is the unique identifier for the radio button, used for labeling.
|
||||
// ID uniquely identifies the radio button
|
||||
ID string
|
||||
|
||||
// Disabled is a string representing an Alpine.js expression for the disabled state.
|
||||
// It can be a boolean value ("true" or "false") or a more complex condition.
|
||||
// Examples:
|
||||
// - "true" for always disabled
|
||||
// - "false" for never disabled
|
||||
// - "someVariable" to bind to an Alpine.js data property
|
||||
// - "someCondition === true" for a dynamic condition
|
||||
Disabled string
|
||||
// Label displays text next to radio button
|
||||
Label templ.Component
|
||||
|
||||
// Class specifies additional CSS classes to apply to the radio button container.
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes to the radio button.
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
|
||||
// Label is a templ.Component that represents the label for the radio button.
|
||||
// If not provided, the Value will be used as the label text.
|
||||
Label templ.Component
|
||||
}
|
||||
|
||||
// RadioGroup renders a group of radio buttons.
|
||||
// It uses Alpine.js for managing the selected state.
|
||||
// RadioGroup renders a set of mutually exclusive radio button options.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/radio-group
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.RadioGroup(components.RadioGroupProps{
|
||||
// DefaultValue: "option1",
|
||||
// Name: "myRadioGroup",
|
||||
// Required: true,
|
||||
// Class: "my-custom-class",
|
||||
// }) {
|
||||
// // RadioGroupItem components go here
|
||||
// }
|
||||
// Props:
|
||||
// - Name: Groups related radio buttons
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
func RadioGroup(props RadioGroupProps) templ.Component {
|
||||
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
|
||||
@ -101,42 +74,16 @@ func RadioGroup(props RadioGroupProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div role=\"radiogroup\" aria-required=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div role=\"radiogroup\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%t", props.Required))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 73, Col: 51}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-data=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(`{ selectedValue: '%s' }`, props.DefaultValue))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 74, Col: 69}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -164,18 +111,16 @@ func RadioGroup(props RadioGroupProps) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// RadioGroupItem renders a single radio button with an integrated label.
|
||||
// It uses Alpine.js for managing the disabled state and selected value.
|
||||
// RadioGroupItem renders an individual radio button with label.
|
||||
// Must be used within a RadioGroup component.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.RadioGroupItem(components.RadioGroupItemProps{
|
||||
// Value: "option1",
|
||||
// Name: "myRadioGroup",
|
||||
// ID: "option1",
|
||||
// Disabled: "someCondition === true", // Alpine.js expression
|
||||
// Label: templ.Raw("Option 1"),
|
||||
// })
|
||||
// Props:
|
||||
// - Value: Radio button value
|
||||
// - Name: Matches parent group name
|
||||
// - ID: Unique identifier
|
||||
// - Label: Button label
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
func RadioGroupItem(props RadioGroupItemProps) templ.Component {
|
||||
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
|
||||
@ -192,81 +137,70 @@ func RadioGroupItem(props RadioGroupItemProps) templ.Component {
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var6 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var6 == nil {
|
||||
templ_7745c5c3_Var6 = templ.NopComponent
|
||||
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("<style>\n\t\t/* Custom styles for radio buttons */\n\t\tinput[type=\"radio\"] {\n\t\t\tposition: relative;\n\t\t}\n\t\tinput[type=\"radio\"]:checked::before {\n\t\t\tcontent: '';\n\t\t\tposition: absolute;\n\t\t\ttop: 50%;\n\t\t\tleft: 50%;\n\t\t\ttransform: translate(-50%, -50%);\n\t\t\twidth: 8px;\n\t\t\theight: 8px;\n\t\t\tborder-radius: 50%;\n\t\t\tbackground-color: hsl(var(--background));\n\t\t}\n\t\tinput[type=\"radio\"]:focus {\n\t\t\toutline: none;\n\t\t\tbox-shadow: 0 0 0 2px hsl(var(--ring) / 50%);\n\t\t}\n\t</style>")
|
||||
var templ_7745c5c3_Var5 = []any{utils.TwMerge(
|
||||
"flex items-center gap-2 cursor-pointer text-sm font-medium",
|
||||
"text-muted-foreground [&:has(input:checked)]:text-foreground",
|
||||
"[&:has(input:disabled)]:cursor-not-allowed [&:has(input:disabled)]:opacity-50",
|
||||
props.Class,
|
||||
)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 = []any{utils.TwMerge("flex items-center space-x-2", props.Class)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label for=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"")
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 65, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var5).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><input type=\"radio\" id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var7).String())
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 1, Col: 0}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 75, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-data=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(`{ isDisabled: %s }`, props.Disabled))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 118, Col: 60}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
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
|
||||
}
|
||||
var templ_7745c5c3_Var10 = []any{
|
||||
"h-4 w-4 translate-y-px appearance-none rounded-full border bg-background checked:border-primary checked:bg-primary",
|
||||
"disabled:opacity-50 disabled:cursor-not-allowed",
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<input type=\"radio\" id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 122, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" name=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 123, Col: 20}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 76, Col: 20}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -274,29 +208,16 @@ func RadioGroupItem(props RadioGroupItemProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 124, Col: 22}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 77, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" :disabled=\"isDisabled\" x-model=\"selectedValue\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var10).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" style=\"\n\t\t\t\tborder-color: hsl(var(--input));\n\t\t\t\ttransition: all 0.2s ease-in-out;\n\t\t\t\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"before:content[''] relative h-4 w-4 appearance-none rounded-full \n border border-2 border-primary \n checked:border-primary checked:bg-primary\n before:absolute before:left-1/2 before:top-1/2 \n before:h-1.5 before:w-1.5 before:-translate-x-1/2 before:-translate-y-1/2 \n before:rounded-full before:bg-background\n checked:before:visible\n focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring \n focus-visible:ring-offset-2 focus-visible:ring-offset-background\n disabled:cursor-not-allowed\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -308,58 +229,31 @@ func RadioGroupItem(props RadioGroupItemProps) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var15 = []any{"text-sm font-medium leading-none text-foreground"}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var15...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label for=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var16 string
|
||||
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 138, Col: 17}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var17 string
|
||||
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var15).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" :class=\"{ 'opacity-50 cursor-not-allowed': isDisabled }\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Label != nil {
|
||||
templ_7745c5c3_Err = props.Label.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
var templ_7745c5c3_Var18 string
|
||||
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 145, Col: 17}
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/radio_group.templ`, Line: 93, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label></div>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
81
pkg/components/select.templ
Normal file
81
pkg/components/select.templ
Normal file
@ -0,0 +1,81 @@
|
||||
// pkg/components/select.templ
|
||||
|
||||
package components
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/icons"
|
||||
|
||||
type SelectProps struct {
|
||||
// ID uniquely identifies the select input
|
||||
ID string
|
||||
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Placeholder shows text when no option selected
|
||||
Placeholder string
|
||||
|
||||
// Options defines available choices
|
||||
Options []SelectOption
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
type SelectOption struct {
|
||||
// Label displays text in dropdown
|
||||
Label string
|
||||
|
||||
// Value sets the option's form value
|
||||
Value string
|
||||
|
||||
// Attributes for disabled state or other HTML attributes
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Select renders a dropdown menu component with keyboard navigation.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/select
|
||||
//
|
||||
// Props:
|
||||
// - ID: Unique identifier
|
||||
// - Name: Form field name
|
||||
// - Placeholder: Default text
|
||||
// - Options: Available choices
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
//
|
||||
// Features:
|
||||
// - Keyboard navigation
|
||||
// - Disabled state support
|
||||
// - Alpine.js integration
|
||||
// - Custom styling via Tailwind
|
||||
templ Select(props SelectProps) {
|
||||
<div class="relative">
|
||||
<select
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
class="peer h-10 w-full appearance-none rounded-md border border-input bg-background px-3 py-2 text-sm
|
||||
ring-offset-background placeholder:text-muted-foreground
|
||||
focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2
|
||||
disabled:cursor-not-allowed disabled:opacity-50"
|
||||
{ props.Attributes... }
|
||||
>
|
||||
if props.Placeholder != "" {
|
||||
<option value="" disabled selected hidden>{ props.Placeholder }</option>
|
||||
}
|
||||
for _, option := range props.Options {
|
||||
<option
|
||||
value={ option.Value }
|
||||
{ option.Attributes... }
|
||||
>
|
||||
{ option.Label }
|
||||
</option>
|
||||
}
|
||||
</select>
|
||||
<div class="absolute right-3 top-3 pointer-events-none peer-disabled:opacity-50">
|
||||
@icons.ChevronDown(icons.IconProps{Size: "16", Class: "text-muted-foreground"})
|
||||
</div>
|
||||
</div>
|
||||
}
|
196
pkg/components/select_templ.go
Normal file
196
pkg/components/select_templ.go
Normal file
@ -0,0 +1,196 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.778
|
||||
// pkg/components/select.templ
|
||||
|
||||
package components
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/axzilla/goilerplate/pkg/icons"
|
||||
|
||||
type SelectProps struct {
|
||||
// ID uniquely identifies the select input
|
||||
ID string
|
||||
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Placeholder shows text when no option selected
|
||||
Placeholder string
|
||||
|
||||
// Options defines available choices
|
||||
Options []SelectOption
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
type SelectOption struct {
|
||||
// Label displays text in dropdown
|
||||
Label string
|
||||
|
||||
// Value sets the option's form value
|
||||
Value string
|
||||
|
||||
// Attributes for disabled state or other HTML attributes
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Select renders a dropdown menu component with keyboard navigation.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/select
|
||||
//
|
||||
// Props:
|
||||
// - ID: Unique identifier
|
||||
// - Name: Form field name
|
||||
// - Placeholder: Default text
|
||||
// - Options: Available choices
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
//
|
||||
// Features:
|
||||
// - Keyboard navigation
|
||||
// - Disabled state support
|
||||
// - Alpine.js integration
|
||||
// - Custom styling via Tailwind
|
||||
func Select(props SelectProps) templ.Component {
|
||||
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
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
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=\"relative\"><select id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 57, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" name=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 58, Col: 20}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"peer h-10 w-full appearance-none rounded-md border border-input bg-background px-3 py-2 text-sm \n ring-offset-background placeholder:text-muted-foreground\n focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\n disabled:cursor-not-allowed disabled:opacity-50\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, props.Attributes)
|
||||
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 props.Placeholder != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<option value=\"\" disabled selected hidden>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.Placeholder)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 66, Col: 65}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</option> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
for _, option := range props.Options {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<option value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(option.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 70, Col: 25}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
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.RenderAttributes(ctx, templ_7745c5c3_Buffer, option.Attributes)
|
||||
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
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(option.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/select.templ`, Line: 73, Col: 19}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</option>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</select><div class=\"absolute right-3 top-3 pointer-events-none peer-disabled:opacity-50\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = icons.ChevronDown(icons.IconProps{Size: "16", Class: "text-muted-foreground"}).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
@ -1,38 +1,29 @@
|
||||
package components
|
||||
|
||||
// SheetSide represents the side from which the sheet will appear.
|
||||
// SheetSide defines the slide-in direction
|
||||
type SheetSide string
|
||||
|
||||
// Constants for sheet sides.
|
||||
const (
|
||||
Top SheetSide = "top"
|
||||
Right SheetSide = "right"
|
||||
Bottom SheetSide = "bottom"
|
||||
Left SheetSide = "left"
|
||||
// Sheet appearance directions
|
||||
Top SheetSide = "top" // Slides down from top
|
||||
Right SheetSide = "right" // Slides in from right
|
||||
Bottom SheetSide = "bottom" // Slides up from bottom
|
||||
Left SheetSide = "left" // Slides in from left
|
||||
)
|
||||
|
||||
// SheetProps defines the properties for the Sheet component.
|
||||
type SheetProps struct {
|
||||
// Title is the heading text for the sheet.
|
||||
// Default: "" (empty string)
|
||||
// Title displays in sheet header
|
||||
Title string
|
||||
|
||||
// Description is the subheading or description text for the sheet.
|
||||
// Default: "" (empty string)
|
||||
// Description shows below title
|
||||
Description string
|
||||
|
||||
// Side determines from which side the sheet will appear.
|
||||
// Default: Right
|
||||
// Side controls slide-in direction
|
||||
Side SheetSide
|
||||
}
|
||||
|
||||
// SheetRoot renders the root component for the Sheet, setting up the Alpine.js data and event handlers.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.SheetRoot() {
|
||||
// // Sheet trigger and content go here
|
||||
// }
|
||||
// SheetRoot initializes Alpine.js state and event handlers
|
||||
// Must wrap Sheet components and triggers
|
||||
templ SheetRoot() {
|
||||
<div
|
||||
x-data="{
|
||||
@ -52,22 +43,20 @@ templ SheetRoot() {
|
||||
</div>
|
||||
}
|
||||
|
||||
// Sheet renders the main sheet component with backdrop and content.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Sheet(components.SheetProps{
|
||||
// Title: "Sheet Title",
|
||||
// Description: "Sheet description goes here",
|
||||
// Side: components.Right,
|
||||
// }) {
|
||||
// // Sheet content goes here
|
||||
// }
|
||||
// Sheet renders a slide-in panel with backdrop.
|
||||
// Uses Alpine.js for animations and state management.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/sheet
|
||||
//
|
||||
// Props:
|
||||
// - Title: The heading text for the sheet. Default: "" (empty string)
|
||||
// - Description: The subheading or description text for the sheet. Default: "" (empty string)
|
||||
// - Side: Determines from which side the sheet will appear. Default: Right
|
||||
// - Title: Header text
|
||||
// - Description: Subheading text
|
||||
// - Side: Slide-in direction
|
||||
//
|
||||
// Features:
|
||||
// - Responsive sizing
|
||||
// - Animated transitions
|
||||
// - Backdrop blur
|
||||
// - ESC key closing
|
||||
templ Sheet(props SheetProps) {
|
||||
<!-- Backdrop -->
|
||||
<div
|
||||
@ -136,17 +125,8 @@ templ Sheet(props SheetProps) {
|
||||
</div>
|
||||
}
|
||||
|
||||
// SheetTrigger renders a trigger element that opens the sheet when clicked.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.SheetTrigger("Open Sheet", components.Right) {
|
||||
// <button>Open Sheet</button>
|
||||
// }
|
||||
//
|
||||
// Props:
|
||||
// - text: The text content of the trigger (unused in the current implementation)
|
||||
// - side: The side from which the sheet should appear
|
||||
// SheetTrigger creates elements that open the sheet
|
||||
// Must be used within SheetRoot
|
||||
templ SheetTrigger(text string, side SheetSide) {
|
||||
<span
|
||||
@click={ "open('" + string(side) + "')" }
|
||||
@ -155,14 +135,8 @@ templ SheetTrigger(text string, side SheetSide) {
|
||||
</span>
|
||||
}
|
||||
|
||||
// SheetClose renders a button that closes the sheet when clicked.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.SheetClose("Close")
|
||||
//
|
||||
// Props:
|
||||
// - text: The text content of the close button
|
||||
// SheetClose creates a button that closes the sheet
|
||||
// Must be used within Sheet
|
||||
templ SheetClose(text string) {
|
||||
<button
|
||||
@click="close()"
|
||||
|
@ -8,39 +8,30 @@ package components
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
// SheetSide represents the side from which the sheet will appear.
|
||||
// SheetSide defines the slide-in direction
|
||||
type SheetSide string
|
||||
|
||||
// Constants for sheet sides.
|
||||
const (
|
||||
Top SheetSide = "top"
|
||||
Right SheetSide = "right"
|
||||
Bottom SheetSide = "bottom"
|
||||
Left SheetSide = "left"
|
||||
// Sheet appearance directions
|
||||
Top SheetSide = "top" // Slides down from top
|
||||
Right SheetSide = "right" // Slides in from right
|
||||
Bottom SheetSide = "bottom" // Slides up from bottom
|
||||
Left SheetSide = "left" // Slides in from left
|
||||
)
|
||||
|
||||
// SheetProps defines the properties for the Sheet component.
|
||||
type SheetProps struct {
|
||||
// Title is the heading text for the sheet.
|
||||
// Default: "" (empty string)
|
||||
// Title displays in sheet header
|
||||
Title string
|
||||
|
||||
// Description is the subheading or description text for the sheet.
|
||||
// Default: "" (empty string)
|
||||
// Description shows below title
|
||||
Description string
|
||||
|
||||
// Side determines from which side the sheet will appear.
|
||||
// Default: Right
|
||||
// Side controls slide-in direction
|
||||
Side SheetSide
|
||||
}
|
||||
|
||||
// SheetRoot renders the root component for the Sheet, setting up the Alpine.js data and event handlers.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.SheetRoot() {
|
||||
// // Sheet trigger and content go here
|
||||
// }
|
||||
// SheetRoot initializes Alpine.js state and event handlers
|
||||
// Must wrap Sheet components and triggers
|
||||
func SheetRoot() templ.Component {
|
||||
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
|
||||
@ -78,22 +69,20 @@ func SheetRoot() templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// Sheet renders the main sheet component with backdrop and content.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Sheet(components.SheetProps{
|
||||
// Title: "Sheet Title",
|
||||
// Description: "Sheet description goes here",
|
||||
// Side: components.Right,
|
||||
// }) {
|
||||
// // Sheet content goes here
|
||||
// }
|
||||
// Sheet renders a slide-in panel with backdrop.
|
||||
// Uses Alpine.js for animations and state management.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/sheet
|
||||
//
|
||||
// Props:
|
||||
// - Title: The heading text for the sheet. Default: "" (empty string)
|
||||
// - Description: The subheading or description text for the sheet. Default: "" (empty string)
|
||||
// - Side: Determines from which side the sheet will appear. Default: Right
|
||||
// - Title: Header text
|
||||
// - Description: Subheading text
|
||||
// - Side: Slide-in direction
|
||||
//
|
||||
// Features:
|
||||
// - Responsive sizing
|
||||
// - Animated transitions
|
||||
// - Backdrop blur
|
||||
// - ESC key closing
|
||||
func Sheet(props SheetProps) templ.Component {
|
||||
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
|
||||
@ -176,7 +165,7 @@ func Sheet(props SheetProps) templ.Component {
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Title)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/sheet.templ`, Line: 129, Col: 51}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/sheet.templ`, Line: 118, Col: 51}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -189,7 +178,7 @@ func Sheet(props SheetProps) templ.Component {
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.Description)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/sheet.templ`, Line: 130, Col: 64}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/sheet.templ`, Line: 119, Col: 64}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -211,17 +200,8 @@ func Sheet(props SheetProps) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// SheetTrigger renders a trigger element that opens the sheet when clicked.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.SheetTrigger("Open Sheet", components.Right) {
|
||||
// <button>Open Sheet</button>
|
||||
// }
|
||||
//
|
||||
// Props:
|
||||
// - text: The text content of the trigger (unused in the current implementation)
|
||||
// - side: The side from which the sheet should appear
|
||||
// SheetTrigger creates elements that open the sheet
|
||||
// Must be used within SheetRoot
|
||||
func SheetTrigger(text string, side SheetSide) templ.Component {
|
||||
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
|
||||
@ -250,7 +230,7 @@ func SheetTrigger(text string, side SheetSide) templ.Component {
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs("open('" + string(side) + "')")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/sheet.templ`, Line: 152, Col: 41}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/sheet.templ`, Line: 132, Col: 41}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -272,14 +252,8 @@ func SheetTrigger(text string, side SheetSide) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
// SheetClose renders a button that closes the sheet when clicked.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.SheetClose("Close")
|
||||
//
|
||||
// Props:
|
||||
// - text: The text content of the close button
|
||||
// SheetClose creates a button that closes the sheet
|
||||
// Must be used within Sheet
|
||||
func SheetClose(text string) templ.Component {
|
||||
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
|
||||
@ -329,7 +303,7 @@ func SheetClose(text string) templ.Component {
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(text)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/sheet.templ`, Line: 174, Col: 8}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/sheet.templ`, Line: 148, Col: 8}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
109
pkg/components/slider.templ
Normal file
109
pkg/components/slider.templ
Normal file
@ -0,0 +1,109 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
|
||||
type SliderProps struct {
|
||||
// ID is the unique identifier for the slider
|
||||
ID string
|
||||
|
||||
// Name is the name attribute for the slider
|
||||
Name string
|
||||
|
||||
// Min sets the minimum value (default: 0)
|
||||
Min int
|
||||
|
||||
// Max sets the maximum value (default: 100)
|
||||
Max int
|
||||
|
||||
// Step defines the increment between values (default: 1)
|
||||
Step int
|
||||
|
||||
// Value sets the initial value
|
||||
Value int
|
||||
|
||||
// Label displays a label above the slider
|
||||
Label string
|
||||
|
||||
// ShowValue toggles the value display
|
||||
ShowValue bool
|
||||
|
||||
// ValueFormat adds a suffix to the value (e.g. "%", "°C")
|
||||
ValueFormat string
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Disabled makes the slider non-interactive
|
||||
Disabled bool
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Slider renders a range input component with support for labels, value display and external binding.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/slider
|
||||
//
|
||||
// Props:
|
||||
// - ID: Unique identifier for the slider
|
||||
// - Name: Input name attribute
|
||||
// - Min: Minimum value (default: 0)
|
||||
// - Max: Maximum value (default: 100)
|
||||
// - Step: Value increment (default: 1)
|
||||
// - Value: Initial value
|
||||
// - Label: Optional label text
|
||||
// - ShowValue: Show current value
|
||||
// - ValueFormat: Optional format suffix (e.g. "%", "°C")
|
||||
// - Class: Additional CSS classes
|
||||
// - Disabled: Disables the slider
|
||||
// - Attributes: Additional HTML attributes (e.g. x-model for binding)
|
||||
templ Slider(props SliderProps) {
|
||||
<div
|
||||
class="space-y-2"
|
||||
x-data={ fmt.Sprintf("{ value: %d }", props.Value) }
|
||||
>
|
||||
if props.Label != "" || props.ShowValue {
|
||||
<div class="flex justify-between items-center">
|
||||
if props.Label != "" {
|
||||
<label for={ props.ID } class="text-sm font-medium">
|
||||
{ props.Label }
|
||||
</label>
|
||||
}
|
||||
if props.ShowValue {
|
||||
<p class="text-sm text-muted-foreground">
|
||||
<span x-text="value"></span>
|
||||
if props.ValueFormat != "" {
|
||||
{ " " + props.ValueFormat }
|
||||
}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<input
|
||||
@input="value = $event.target.value"
|
||||
type="range"
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
value={ fmt.Sprintf("%d", props.Value) }
|
||||
min={ fmt.Sprintf("%d", props.Min) }
|
||||
max={ fmt.Sprintf("%d", props.Max) }
|
||||
step={ fmt.Sprintf("%d", props.Step) }
|
||||
class={ utils.TwMerge(
|
||||
"w-full h-2 rounded-full bg-secondary appearance-none cursor-pointer",
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
"[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
|
||||
"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-primary",
|
||||
"[&::-webkit-slider-thumb]:hover:bg-primary/90",
|
||||
"[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4 [&::-moz-range-thumb]:border-0",
|
||||
"[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-primary",
|
||||
"[&::-moz-range-thumb]:hover:bg-primary/90",
|
||||
"disabled:opacity-50 disabled:cursor-not-allowed",
|
||||
props.Class,
|
||||
) }
|
||||
disabled?={ props.Disabled }
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
</div>
|
||||
}
|
300
pkg/components/slider_templ.go
Normal file
300
pkg/components/slider_templ.go
Normal file
@ -0,0 +1,300 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.778
|
||||
package components
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
)
|
||||
|
||||
type SliderProps struct {
|
||||
// ID is the unique identifier for the slider
|
||||
ID string
|
||||
|
||||
// Name is the name attribute for the slider
|
||||
Name string
|
||||
|
||||
// Min sets the minimum value (default: 0)
|
||||
Min int
|
||||
|
||||
// Max sets the maximum value (default: 100)
|
||||
Max int
|
||||
|
||||
// Step defines the increment between values (default: 1)
|
||||
Step int
|
||||
|
||||
// Value sets the initial value
|
||||
Value int
|
||||
|
||||
// Label displays a label above the slider
|
||||
Label string
|
||||
|
||||
// ShowValue toggles the value display
|
||||
ShowValue bool
|
||||
|
||||
// ValueFormat adds a suffix to the value (e.g. "%", "°C")
|
||||
ValueFormat string
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Disabled makes the slider non-interactive
|
||||
Disabled bool
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Slider renders a range input component with support for labels, value display and external binding.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/slider
|
||||
//
|
||||
// Props:
|
||||
// - ID: Unique identifier for the slider
|
||||
// - Name: Input name attribute
|
||||
// - Min: Minimum value (default: 0)
|
||||
// - Max: Maximum value (default: 100)
|
||||
// - Step: Value increment (default: 1)
|
||||
// - Value: Initial value
|
||||
// - Label: Optional label text
|
||||
// - ShowValue: Show current value
|
||||
// - ValueFormat: Optional format suffix (e.g. "%", "°C")
|
||||
// - Class: Additional CSS classes
|
||||
// - Disabled: Disables the slider
|
||||
// - Attributes: Additional HTML attributes (e.g. x-model for binding)
|
||||
func Slider(props SliderProps) templ.Component {
|
||||
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
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
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=\"space-y-2\" x-data=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("{ value: %d }", props.Value))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/slider.templ`, Line: 65, Col: 52}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
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 props.Label != "" || props.ShowValue {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"flex justify-between items-center\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Label != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label for=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/slider.templ`, Line: 70, Col: 26}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"text-sm font-medium\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/slider.templ`, Line: 71, Col: 19}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
if props.ShowValue {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"text-sm text-muted-foreground\"><span x-text=\"value\"></span> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.ValueFormat != "" {
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(" " + props.ValueFormat)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/slider.templ`, Line: 78, Col: 32}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>")
|
||||
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
|
||||
}
|
||||
}
|
||||
var templ_7745c5c3_Var6 = []any{utils.TwMerge(
|
||||
"w-full h-2 rounded-full bg-secondary appearance-none cursor-pointer",
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
"[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
|
||||
"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-primary",
|
||||
"[&::-webkit-slider-thumb]:hover:bg-primary/90",
|
||||
"[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4 [&::-moz-range-thumb]:border-0",
|
||||
"[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-primary",
|
||||
"[&::-moz-range-thumb]:hover:bg-primary/90",
|
||||
"disabled:opacity-50 disabled:cursor-not-allowed",
|
||||
props.Class,
|
||||
)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<input @input=\"value = $event.target.value\" type=\"range\" id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/slider.templ`, Line: 87, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" name=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/slider.templ`, Line: 88, Col: 20}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", props.Value))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/slider.templ`, Line: 89, Col: 41}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" min=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", props.Min))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/slider.templ`, Line: 90, Col: 37}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" max=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", props.Max))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/slider.templ`, Line: 91, Col: 37}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" step=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", props.Step))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/slider.templ`, Line: 92, Col: 39}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/slider.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
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 props.Disabled {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" disabled")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, props.Attributes)
|
||||
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
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
@ -1,49 +1,41 @@
|
||||
package components
|
||||
|
||||
// Tab represents a single tab in the Tabs component.
|
||||
type Tab struct {
|
||||
// ID is the unique identifier for the tab.
|
||||
// ID uniquely identifies the tab
|
||||
ID string
|
||||
|
||||
// Title is the text displayed on the tab button.
|
||||
// Title displays in tab button
|
||||
Title string
|
||||
|
||||
// Content is the templ.Component to be rendered when the tab is active.
|
||||
// Content renders when tab is active
|
||||
Content templ.Component
|
||||
}
|
||||
|
||||
// TabsProps defines the properties for the Tabs component.
|
||||
type TabsProps struct {
|
||||
// Tabs is an array of Tab structs representing each tab in the component.
|
||||
// Tabs defines the tabs structure and content
|
||||
Tabs []Tab
|
||||
|
||||
// TabsContainerClass specifies additional CSS classes for the tabs container.
|
||||
// Default: "" (empty string)
|
||||
// TabsContainerClass adds classes to tabs header
|
||||
TabsContainerClass string
|
||||
|
||||
// ContentContainerClass specifies additional CSS classes for the content container.
|
||||
// Default: "" (empty string)
|
||||
// ContentContainerClass adds classes to content area
|
||||
ContentContainerClass string
|
||||
}
|
||||
|
||||
// Tabs renders a tabbed interface component based on the provided props.
|
||||
// It uses Alpine.js for interactivity and state management.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Tabs(components.TabsProps{
|
||||
// Tabs: []components.Tab{
|
||||
// {ID: "1", Title: "Tab 1", Content: Tab1Content()},
|
||||
// {ID: "2", Title: "Tab 2", Content: Tab2Content()},
|
||||
// },
|
||||
// TabsContainerClass: "w-full max-w-md",
|
||||
// ContentContainerClass: "mt-4",
|
||||
// })
|
||||
// Tabs renders a tabbed interface with animated transitions.
|
||||
// Uses Alpine.js for state management and interactions.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/tabs
|
||||
//
|
||||
// Props:
|
||||
// - Tabs: An array of Tab structs, each representing a tab in the interface.
|
||||
// - TabsContainerClass: Additional CSS classes for the tabs container. Default: "" (empty string)
|
||||
// - ContentContainerClass: Additional CSS classes for the content container. Default: "" (empty string)
|
||||
// - Tabs: Tab definitions and content
|
||||
// - TabsContainerClass: Additional classes for header
|
||||
// - ContentContainerClass: Additional classes for content
|
||||
//
|
||||
// Features:
|
||||
// - Animated tab switching
|
||||
// - Keyboard navigation
|
||||
// - Responsive layout
|
||||
// - ARIA support
|
||||
templ Tabs(props TabsProps) {
|
||||
<div
|
||||
x-data="{
|
||||
|
@ -8,50 +8,42 @@ package components
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
// Tab represents a single tab in the Tabs component.
|
||||
type Tab struct {
|
||||
// ID is the unique identifier for the tab.
|
||||
// ID uniquely identifies the tab
|
||||
ID string
|
||||
|
||||
// Title is the text displayed on the tab button.
|
||||
// Title displays in tab button
|
||||
Title string
|
||||
|
||||
// Content is the templ.Component to be rendered when the tab is active.
|
||||
// Content renders when tab is active
|
||||
Content templ.Component
|
||||
}
|
||||
|
||||
// TabsProps defines the properties for the Tabs component.
|
||||
type TabsProps struct {
|
||||
// Tabs is an array of Tab structs representing each tab in the component.
|
||||
// Tabs defines the tabs structure and content
|
||||
Tabs []Tab
|
||||
|
||||
// TabsContainerClass specifies additional CSS classes for the tabs container.
|
||||
// Default: "" (empty string)
|
||||
// TabsContainerClass adds classes to tabs header
|
||||
TabsContainerClass string
|
||||
|
||||
// ContentContainerClass specifies additional CSS classes for the content container.
|
||||
// Default: "" (empty string)
|
||||
// ContentContainerClass adds classes to content area
|
||||
ContentContainerClass string
|
||||
}
|
||||
|
||||
// Tabs renders a tabbed interface component based on the provided props.
|
||||
// It uses Alpine.js for interactivity and state management.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// @components.Tabs(components.TabsProps{
|
||||
// Tabs: []components.Tab{
|
||||
// {ID: "1", Title: "Tab 1", Content: Tab1Content()},
|
||||
// {ID: "2", Title: "Tab 2", Content: Tab2Content()},
|
||||
// },
|
||||
// TabsContainerClass: "w-full max-w-md",
|
||||
// ContentContainerClass: "mt-4",
|
||||
// })
|
||||
// Tabs renders a tabbed interface with animated transitions.
|
||||
// Uses Alpine.js for state management and interactions.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/tabs
|
||||
//
|
||||
// Props:
|
||||
// - Tabs: An array of Tab structs, each representing a tab in the interface.
|
||||
// - TabsContainerClass: Additional CSS classes for the tabs container. Default: "" (empty string)
|
||||
// - ContentContainerClass: Additional CSS classes for the content container. Default: "" (empty string)
|
||||
// - Tabs: Tab definitions and content
|
||||
// - TabsContainerClass: Additional classes for header
|
||||
// - ContentContainerClass: Additional classes for content
|
||||
//
|
||||
// Features:
|
||||
// - Animated tab switching
|
||||
// - Keyboard navigation
|
||||
// - Responsive layout
|
||||
// - ARIA support
|
||||
func Tabs(props TabsProps) templ.Component {
|
||||
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
|
||||
@ -109,7 +101,7 @@ func Tabs(props TabsProps) templ.Component {
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(tab.Title)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/tabs.templ`, Line: 84, Col: 16}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/tabs.templ`, Line: 76, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
99
pkg/components/textarea.templ
Normal file
99
pkg/components/textarea.templ
Normal file
@ -0,0 +1,99 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type TextareaProps struct {
|
||||
// ID uniquely identifies the textarea
|
||||
ID string
|
||||
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Value sets initial content
|
||||
Value string
|
||||
|
||||
// Placeholder shows when empty
|
||||
Placeholder string
|
||||
|
||||
// Label displays text above textarea
|
||||
Label string
|
||||
|
||||
// Description shows helper text below
|
||||
Description string
|
||||
|
||||
// Error displays validation message
|
||||
Error string
|
||||
|
||||
// Rows sets visible text lines height
|
||||
Rows int
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// AutoResize enables dynamic height adjustment
|
||||
AutoResize bool
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Textarea renders a multi-line text input with optional validation.
|
||||
// Uses Alpine.js for autoresize functionality when enabled.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/textarea
|
||||
//
|
||||
// Props:
|
||||
// - ID: Unique identifier
|
||||
// - Name: Form field name
|
||||
// - Value: Initial content
|
||||
// - Placeholder: Helper text when empty
|
||||
// - Label: Text label
|
||||
// - Description: Helper text
|
||||
// - Error: Validation message
|
||||
// - Rows: Initial height in lines
|
||||
// - Class: Additional CSS classes
|
||||
// - AutoResize: Enable dynamic sizing
|
||||
// - Attributes: Additional HTML attributes
|
||||
templ Textarea(props TextareaProps) {
|
||||
<div class="space-y-2">
|
||||
if props.Label != "" {
|
||||
<label
|
||||
for={ props.ID }
|
||||
class={ "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
templ.KV("text-destructive", len(props.Error) > 0) }
|
||||
>
|
||||
{ props.Label }
|
||||
</label>
|
||||
}
|
||||
<textarea
|
||||
id={ props.ID }
|
||||
name={ props.Name }
|
||||
value={ props.Value }
|
||||
placeholder={ props.Placeholder }
|
||||
if props.Rows != 0 {
|
||||
rows={ strconv.Itoa(props.Rows) }
|
||||
}
|
||||
class={ utils.TwMerge(
|
||||
"flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background",
|
||||
"min-h-[80px] 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",
|
||||
props.Class,
|
||||
) }
|
||||
if props.AutoResize {
|
||||
x-data="{ resize() { $el.style.height = '80px'; $el.style.height = $el.scrollHeight + 'px' } }"
|
||||
x-init="resize()"
|
||||
@input="resize()"
|
||||
}
|
||||
{ props.Attributes... }
|
||||
></textarea>
|
||||
if props.Description != "" {
|
||||
<p class="text-sm text-muted-foreground">{ props.Description }</p>
|
||||
}
|
||||
if props.Error != "" {
|
||||
<p class="text-sm font-medium text-destructive">{ props.Error }</p>
|
||||
}
|
||||
</div>
|
||||
}
|
306
pkg/components/textarea_templ.go
Normal file
306
pkg/components/textarea_templ.go
Normal file
@ -0,0 +1,306 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.778
|
||||
package components
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"github.com/axzilla/goilerplate/pkg/utils"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type TextareaProps struct {
|
||||
// ID uniquely identifies the textarea
|
||||
ID string
|
||||
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Value sets initial content
|
||||
Value string
|
||||
|
||||
// Placeholder shows when empty
|
||||
Placeholder string
|
||||
|
||||
// Label displays text above textarea
|
||||
Label string
|
||||
|
||||
// Description shows helper text below
|
||||
Description string
|
||||
|
||||
// Error displays validation message
|
||||
Error string
|
||||
|
||||
// Rows sets visible text lines height
|
||||
Rows int
|
||||
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// AutoResize enables dynamic height adjustment
|
||||
AutoResize bool
|
||||
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Textarea renders a multi-line text input with optional validation.
|
||||
// Uses Alpine.js for autoresize functionality when enabled.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/textarea
|
||||
//
|
||||
// Props:
|
||||
// - ID: Unique identifier
|
||||
// - Name: Form field name
|
||||
// - Value: Initial content
|
||||
// - Placeholder: Helper text when empty
|
||||
// - Label: Text label
|
||||
// - Description: Helper text
|
||||
// - Error: Validation message
|
||||
// - Rows: Initial height in lines
|
||||
// - Class: Additional CSS classes
|
||||
// - AutoResize: Enable dynamic sizing
|
||||
// - Attributes: Additional HTML attributes
|
||||
func Textarea(props TextareaProps) templ.Component {
|
||||
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
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
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=\"space-y-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Label != "" {
|
||||
var templ_7745c5c3_Var2 = []any{"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
templ.KV("text-destructive", len(props.Error) > 0)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label for=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 63, Col: 18}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
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
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Label)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 67, Col: 17}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
var templ_7745c5c3_Var6 = []any{utils.TwMerge(
|
||||
"flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background",
|
||||
"min-h-[80px] 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",
|
||||
props.Class,
|
||||
)}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<textarea id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 71, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" name=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 72, Col: 20}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(props.Value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 73, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" placeholder=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(props.Placeholder)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 74, Col: 34}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
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 props.Rows != 0 {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" rows=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(props.Rows))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 76, Col: 35}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
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_Buffer.WriteString(" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
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 props.AutoResize {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" x-data=\"{ resize() { $el.style.height = '80px'; $el.style.height = $el.scrollHeight + 'px' } }\" x-init=\"resize()\" @input=\"resize()\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, props.Attributes)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("></textarea> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Description != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"text-sm text-muted-foreground\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(props.Description)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 93, Col: 63}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
if props.Error != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"text-sm font-medium text-destructive\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 string
|
||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(props.Error)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/textarea.templ`, Line: 96, Col: 64}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</p>")
|
||||
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
|
||||
}
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
@ -1,134 +1,71 @@
|
||||
package components
|
||||
|
||||
// ToggleSize represents the size of the toggle
|
||||
// / ToggleSize defines the available toggle dimensions
|
||||
type ToggleSize string
|
||||
|
||||
// ToggleLabelPlacement represents where the label should be placed
|
||||
// ToggleLabelPlacement defines label position options
|
||||
type ToggleLabelPlacement string
|
||||
|
||||
// ToggleProps defines the properties for the Toggle component
|
||||
type ToggleProps struct {
|
||||
// ID is the unique identifier for the toggle input
|
||||
// ID uniquely identifies the toggle
|
||||
ID string
|
||||
|
||||
// Name is the name attribute for the toggle input
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Label is the text label for the toggle
|
||||
// LabelLeft displays text before toggle
|
||||
LabelLeft string
|
||||
|
||||
// Label is the text label for the toggle
|
||||
// LabelRight displays text after toggle
|
||||
LabelRight string
|
||||
|
||||
// It's treated as an Alpine.js expression for dynamic checking.
|
||||
// Example bool: Checked: "true"
|
||||
// Example string: Checked: "darkMode"
|
||||
Checked string
|
||||
|
||||
// It's treated as an Alpine.js expression for dynamic checking.
|
||||
// Example bool: Disabled: "true"
|
||||
// Example string: Disabled: "isLoading"
|
||||
Disabled string
|
||||
|
||||
// Class specifies additional CSS classes
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Toggle renders a toggle switch component based on the provided props.
|
||||
// It can be customized with different label placements, and supports
|
||||
// both static and dynamic states through Alpine.js integration.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// // Basic toggle with label
|
||||
// @components.Toggle(components.ToggleProps{
|
||||
// ID: "dark-mode",
|
||||
// Name: "darkMode",
|
||||
// LabelLeft: "Dark Mode",
|
||||
// })
|
||||
//
|
||||
// // Toggle with Alpine.js binding
|
||||
// @components.Toggle(components.ToggleProps{
|
||||
// ID: "notifications",
|
||||
// Name: "notifications",
|
||||
// LabelLeft: "Enable Notifications",
|
||||
// Checked: "notificationsEnabled",
|
||||
// Disabled: "isLoading",
|
||||
// })
|
||||
//
|
||||
// // Toggle with custom size and label placement
|
||||
// @components.Toggle(components.ToggleProps{
|
||||
// ID: "alerts",
|
||||
// Name: "alerts",
|
||||
// LabelLeft: "Alerts",
|
||||
// })
|
||||
// Toggle renders a switch control for boolean values.
|
||||
// Uses Alpine.js for state management and animations.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/toggle
|
||||
//
|
||||
// Props:
|
||||
// - ID: The unique identifier for the toggle input. Required.
|
||||
// - Name: The name attribute for the toggle input. Required.
|
||||
// - LabelLeft: The text label for the toggle. Optional.
|
||||
// - LabelRight: The text label for the toggle. Optional.
|
||||
// - Checked: Controls the checked state. Can be bool or string for Alpine.js binding. Optional.
|
||||
// - Disabled: Controls the disabled state. Can be bool or string for Alpine.js binding. Optional.
|
||||
// - Class: Additional CSS classes. Optional.
|
||||
// - Attributes: Additional HTML attributes. Optional.
|
||||
// - ID: Unique identifier
|
||||
// - Name: Form field name
|
||||
// - LabelLeft: Text before toggle
|
||||
// - LabelRight: Text after toggle
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
//
|
||||
// Features:
|
||||
// - Animated switching
|
||||
// - Keyboard navigation
|
||||
// - Label placement options
|
||||
// - ARIA support
|
||||
templ Toggle(props ToggleProps) {
|
||||
<div x-data="{ checked: false }" class="flex items-center gap-2">
|
||||
<label for={ props.ID } class="inline-flex cursor-pointer items-center gap-2">
|
||||
<input
|
||||
id={ props.ID }
|
||||
type="checkbox"
|
||||
name={ props.Name }
|
||||
class="hidden"
|
||||
if props.Checked != "" {
|
||||
x-init={ "checked = " + props.Checked }
|
||||
}
|
||||
if props.Disabled != "" {
|
||||
:disabled={ props.Disabled }
|
||||
}
|
||||
x-model="checked"
|
||||
class="peer sr-only"
|
||||
role="switch"
|
||||
{ props.Attributes... }
|
||||
/>
|
||||
if props.LabelLeft != "" {
|
||||
<label
|
||||
@click="$refs.switchButton.click(); $refs.switchButton.focus()"
|
||||
:id="$id('switch')"
|
||||
:class="{ 'text-foreground': checked, 'text-muted-foreground': !checked, 'opacity-50 cursor-not-allowed': disabled }"
|
||||
class="text-sm select-none"
|
||||
x-cloak
|
||||
>
|
||||
<span class="text-sm select-none text-muted-foreground peer-checked:text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-50">
|
||||
{ props.LabelLeft }
|
||||
</label>
|
||||
</span>
|
||||
}
|
||||
// FIX: Browser console bug: Alpine Expression Error: Unexpected token '}' -> on :disabled attribute -> But it works
|
||||
<button
|
||||
x-ref="switchButton"
|
||||
type="button"
|
||||
@click="checked = !checked"
|
||||
class={
|
||||
"relative inline-flex h-6 py-0.5 focus:outline-none rounded-full w-10",
|
||||
"disabled:opacity-50 disabled:cursor-not-allowed",
|
||||
}
|
||||
:class="checked ? 'bg-primary' : 'bg-neutral-200'"
|
||||
:disabled={ props.Disabled }
|
||||
x-cloak
|
||||
>
|
||||
<span
|
||||
:class="checked ? 'translate-x-[18px] bg-secondary' : 'translate-x-0.5 bg-muted-foreground'"
|
||||
class="w-5 h-5 duration-200 ease-in-out rounded-full shadow-md"
|
||||
></span>
|
||||
</button>
|
||||
<div
|
||||
class="relative h-6 w-10 rounded-full bg-neutral-200 after:h-5 after:w-5 peer-checked:after:translate-x-[16px] after:absolute after:left-0.5 after:top-0.5 after:rounded-full after:bg-muted-foreground after:transition-all after:content-[''] peer-checked:bg-primary peer-checked:after:bg-secondary peer-disabled:opacity-50 peer-disabled:cursor-not-allowed"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
if props.LabelRight != "" {
|
||||
<label
|
||||
@click="$refs.switchButton.click(); $refs.switchButton.focus()"
|
||||
:id="$id('switch')"
|
||||
:class="{ 'text-foreground': checked, 'text-muted-foreground': !checked, 'opacity-50 cursor-not-allowed': disabled }"
|
||||
class="text-sm select-none"
|
||||
x-cloak
|
||||
>
|
||||
<span class="text-sm select-none text-muted-foreground peer-checked:text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-50">
|
||||
{ props.LabelRight }
|
||||
</label>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</label>
|
||||
}
|
||||
|
@ -8,81 +8,49 @@ package components
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
// ToggleSize represents the size of the toggle
|
||||
// / ToggleSize defines the available toggle dimensions
|
||||
type ToggleSize string
|
||||
|
||||
// ToggleLabelPlacement represents where the label should be placed
|
||||
// ToggleLabelPlacement defines label position options
|
||||
type ToggleLabelPlacement string
|
||||
|
||||
// ToggleProps defines the properties for the Toggle component
|
||||
type ToggleProps struct {
|
||||
// ID is the unique identifier for the toggle input
|
||||
// ID uniquely identifies the toggle
|
||||
ID string
|
||||
|
||||
// Name is the name attribute for the toggle input
|
||||
// Name sets the form field name
|
||||
Name string
|
||||
|
||||
// Label is the text label for the toggle
|
||||
// LabelLeft displays text before toggle
|
||||
LabelLeft string
|
||||
|
||||
// Label is the text label for the toggle
|
||||
// LabelRight displays text after toggle
|
||||
LabelRight string
|
||||
|
||||
// It's treated as an Alpine.js expression for dynamic checking.
|
||||
// Example bool: Checked: "true"
|
||||
// Example string: Checked: "darkMode"
|
||||
Checked string
|
||||
|
||||
// It's treated as an Alpine.js expression for dynamic checking.
|
||||
// Example bool: Disabled: "true"
|
||||
// Example string: Disabled: "isLoading"
|
||||
Disabled string
|
||||
|
||||
// Class specifies additional CSS classes
|
||||
// Class adds custom CSS classes
|
||||
Class string
|
||||
|
||||
// Attributes allows passing additional HTML attributes
|
||||
// Attributes for additional HTML attributes and Alpine.js bindings
|
||||
Attributes templ.Attributes
|
||||
}
|
||||
|
||||
// Toggle renders a toggle switch component based on the provided props.
|
||||
// It can be customized with different label placements, and supports
|
||||
// both static and dynamic states through Alpine.js integration.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// // Basic toggle with label
|
||||
// @components.Toggle(components.ToggleProps{
|
||||
// ID: "dark-mode",
|
||||
// Name: "darkMode",
|
||||
// LabelLeft: "Dark Mode",
|
||||
// })
|
||||
//
|
||||
// // Toggle with Alpine.js binding
|
||||
// @components.Toggle(components.ToggleProps{
|
||||
// ID: "notifications",
|
||||
// Name: "notifications",
|
||||
// LabelLeft: "Enable Notifications",
|
||||
// Checked: "notificationsEnabled",
|
||||
// Disabled: "isLoading",
|
||||
// })
|
||||
//
|
||||
// // Toggle with custom size and label placement
|
||||
// @components.Toggle(components.ToggleProps{
|
||||
// ID: "alerts",
|
||||
// Name: "alerts",
|
||||
// LabelLeft: "Alerts",
|
||||
// })
|
||||
// Toggle renders a switch control for boolean values.
|
||||
// Uses Alpine.js for state management and animations.
|
||||
// For detailed examples and usage guides, visit https://goilerplate.com/docs/components/toggle
|
||||
//
|
||||
// Props:
|
||||
// - ID: The unique identifier for the toggle input. Required.
|
||||
// - Name: The name attribute for the toggle input. Required.
|
||||
// - LabelLeft: The text label for the toggle. Optional.
|
||||
// - LabelRight: The text label for the toggle. Optional.
|
||||
// - Checked: Controls the checked state. Can be bool or string for Alpine.js binding. Optional.
|
||||
// - Disabled: Controls the disabled state. Can be bool or string for Alpine.js binding. Optional.
|
||||
// - Class: Additional CSS classes. Optional.
|
||||
// - Attributes: Additional HTML attributes. Optional.
|
||||
// - ID: Unique identifier
|
||||
// - Name: Form field name
|
||||
// - LabelLeft: Text before toggle
|
||||
// - LabelRight: Text after toggle
|
||||
// - Class: Additional CSS classes
|
||||
// - Attributes: Additional HTML attributes
|
||||
//
|
||||
// Features:
|
||||
// - Animated switching
|
||||
// - Keyboard navigation
|
||||
// - Label placement options
|
||||
// - ARIA support
|
||||
func Toggle(props ToggleProps) templ.Component {
|
||||
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
|
||||
@ -104,155 +72,100 @@ func Toggle(props ToggleProps) templ.Component {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div x-data=\"{ checked: false }\" class=\"flex items-center gap-2\"><input id=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label for=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toggle.templ`, Line: 81, Col: 16}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toggle.templ`, Line: 47, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"inline-flex cursor-pointer items-center gap-2\"><input id=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.ID)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toggle.templ`, Line: 49, Col: 16}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" type=\"checkbox\" name=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(props.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toggle.templ`, Line: 83, Col: 20}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toggle.templ`, Line: 51, Col: 20}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"hidden\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"peer sr-only\" role=\"switch\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Checked != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" x-init=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs("checked = " + props.Checked)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toggle.templ`, Line: 86, Col: 41}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
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.RenderAttributes(ctx, templ_7745c5c3_Buffer, props.Attributes)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.Disabled != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" :disabled=\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.LabelLeft != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"text-sm select-none text-muted-foreground peer-checked:text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-50\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.Disabled)
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(props.LabelLeft)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toggle.templ`, Line: 89, Col: 30}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toggle.templ`, Line: 58, Col: 21}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" x-model=\"checked\"> ")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"relative h-6 w-10 rounded-full bg-neutral-200 after:h-5 after:w-5 peer-checked:after:translate-x-[16px] after:absolute after:left-0.5 after:top-0.5 after:rounded-full after:bg-muted-foreground after:transition-all after:content-[''] peer-checked:bg-primary peer-checked:after:bg-secondary peer-disabled:opacity-50 peer-disabled:cursor-not-allowed\" aria-hidden=\"true\"></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.LabelLeft != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label @click=\"$refs.switchButton.click(); $refs.switchButton.focus()\" :id=\"$id('switch')\" :class=\"{ 'text-foreground': checked, 'text-muted-foreground': !checked, 'opacity-50 cursor-not-allowed': disabled }\" class=\"text-sm select-none\" x-cloak>")
|
||||
if props.LabelRight != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"text-sm select-none text-muted-foreground peer-checked:text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-50\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.LabelLeft)
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(props.LabelRight)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toggle.templ`, Line: 101, Col: 21}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toggle.templ`, Line: 67, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
var templ_7745c5c3_Var7 = []any{
|
||||
"relative inline-flex h-6 py-0.5 focus:outline-none rounded-full w-10",
|
||||
"disabled:opacity-50 disabled:cursor-not-allowed",
|
||||
}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<button x-ref=\"switchButton\" type=\"button\" @click=\"checked = !checked\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var7).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toggle.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" :class=\"checked ? 'bg-primary' : 'bg-neutral-200'\" :disabled=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(props.Disabled)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toggle.templ`, Line: 114, Col: 29}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" x-cloak><span :class=\"checked ? 'translate-x-[18px] bg-secondary' : 'translate-x-0.5 bg-muted-foreground'\" class=\"w-5 h-5 duration-200 ease-in-out rounded-full shadow-md\"></span></button> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if props.LabelRight != "" {
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<label @click=\"$refs.switchButton.click(); $refs.switchButton.focus()\" :id=\"$id('switch')\" :class=\"{ 'text-foreground': checked, 'text-muted-foreground': !checked, 'opacity-50 cursor-not-allowed': disabled }\" class=\"text-sm select-none\" x-cloak>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(props.LabelRight)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg/components/toggle.templ`, Line: 130, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</label>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
@ -449,46 +449,47 @@ video {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 240 10% 3.9%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 240 10% 3.9%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 240 10% 3.9%;
|
||||
--primary: 240 5.9% 10%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
--secondary: 240 4.8% 95.9%;
|
||||
--secondary-foreground: 240 5.9% 10%;
|
||||
--muted: 240 4.8% 95.9%;
|
||||
--muted-foreground: 240 3.8% 46.1%;
|
||||
--accent: 240 4.8% 95.9%;
|
||||
--accent-foreground: 240 5.9% 10%;
|
||||
--destructive: 0 72.22% 50.59%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 240 10% 3.9%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 240 10% 3.9%;
|
||||
--border: 240 5.9% 90%;
|
||||
--input: 240 5.9% 90%;
|
||||
--ring: 240 5.9% 10%;
|
||||
--primary: 346.8 77.2% 49.8%;
|
||||
--primary-foreground: 355.7 100% 97.3%;
|
||||
--secondary: 240 4.8% 95.9%;
|
||||
--secondary-foreground: 240 5.9% 10%;
|
||||
--accent: 240 4.8% 95.9%;
|
||||
--accent-foreground: 240 5.9% 10%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--ring: 346.8 77.2% 49.8%;
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 240 10% 3.9%;
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 240 10% 3.9%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
--popover: 240 10% 3.9%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
--primary: 0 0% 98%;
|
||||
--primary-foreground: 240 5.9% 10%;
|
||||
--secondary: 240 3.7% 15.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--muted: 240 3.7% 15.9%;
|
||||
--background: 20 14.3% 4.1%;
|
||||
--foreground: 0 0% 95%;
|
||||
--muted: 0 0% 15%;
|
||||
--muted-foreground: 240 5% 64.9%;
|
||||
--accent: 240 3.7% 15.9%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--popover: 0 0% 9%;
|
||||
--popover-foreground: 0 0% 95%;
|
||||
--card: 24 9.8% 10%;
|
||||
--card-foreground: 0 0% 95%;
|
||||
--border: 240 3.7% 15.9%;
|
||||
--input: 240 3.7% 15.9%;
|
||||
--ring: 240 4.9% 83.9%;
|
||||
--primary: 346.8 77.2% 49.8%;
|
||||
--primary-foreground: 355.7 100% 97.3%;
|
||||
--secondary: 240 3.7% 15.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--accent: 12 6.5% 15.1%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 85.7% 97.3%;
|
||||
--ring: 346.8 77.2% 49.8%;
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
* {
|
||||
@ -628,8 +629,28 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.static {
|
||||
position: static;
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.pointer-events-none {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.visible {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.fixed {
|
||||
@ -670,6 +691,10 @@ body {
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.left-1\/2 {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.left-full {
|
||||
left: 100%;
|
||||
}
|
||||
@ -678,10 +703,22 @@ body {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.right-3 {
|
||||
right: 0.75rem;
|
||||
}
|
||||
|
||||
.top-0 {
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.top-1\/2 {
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.top-3 {
|
||||
top: 0.75rem;
|
||||
}
|
||||
|
||||
.top-full {
|
||||
top: 100%;
|
||||
}
|
||||
@ -698,6 +735,10 @@ body {
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.m-0 {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.mx-auto {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
@ -775,6 +816,16 @@ body {
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
.size-3 {
|
||||
width: 0.75rem;
|
||||
height: 0.75rem;
|
||||
}
|
||||
|
||||
.size-4 {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.h-1\/2 {
|
||||
height: 50%;
|
||||
}
|
||||
@ -795,6 +846,10 @@ body {
|
||||
height: 4rem;
|
||||
}
|
||||
|
||||
.h-2 {
|
||||
height: 0.5rem;
|
||||
}
|
||||
|
||||
.h-4 {
|
||||
height: 1rem;
|
||||
}
|
||||
@ -827,6 +882,10 @@ body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.min-h-\[80px\] {
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
.w-1\/3 {
|
||||
width: 33.333333%;
|
||||
}
|
||||
@ -851,10 +910,6 @@ body {
|
||||
width: 1rem;
|
||||
}
|
||||
|
||||
.w-5 {
|
||||
width: 1.25rem;
|
||||
}
|
||||
|
||||
.w-56 {
|
||||
width: 14rem;
|
||||
}
|
||||
@ -875,10 +930,6 @@ body {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.max-w-md {
|
||||
max-width: 28rem;
|
||||
}
|
||||
|
||||
.flex-1 {
|
||||
flex: 1 1 0%;
|
||||
}
|
||||
@ -887,11 +938,21 @@ body {
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
.-translate-x-1\/2 {
|
||||
--tw-translate-x: -50%;
|
||||
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-x-full {
|
||||
--tw-translate-x: -100%;
|
||||
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-1\/2 {
|
||||
--tw-translate-y: -50%;
|
||||
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-full {
|
||||
--tw-translate-y: -100%;
|
||||
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));
|
||||
@ -902,16 +963,6 @@ body {
|
||||
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-x-0\.5 {
|
||||
--tw-translate-x: 0.125rem;
|
||||
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-x-\[18px\] {
|
||||
--tw-translate-x: 18px;
|
||||
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-x-full {
|
||||
--tw-translate-x: 100%;
|
||||
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));
|
||||
@ -927,11 +978,6 @@ body {
|
||||
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-px {
|
||||
--tw-translate-y: 1px;
|
||||
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));
|
||||
}
|
||||
|
||||
.scale-100 {
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
@ -962,6 +1008,10 @@ body {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.resize {
|
||||
resize: both;
|
||||
}
|
||||
|
||||
.appearance-none {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
@ -1106,11 +1156,6 @@ body {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.border-blue-500 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(59 130 246 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-border {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: hsl(var(--border) / var(--tw-border-opacity));
|
||||
@ -1174,11 +1219,6 @@ body {
|
||||
background-color: hsl(var(--muted) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-muted-foreground {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--muted-foreground) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-muted\/50 {
|
||||
background-color: hsl(var(--muted) / 0.5);
|
||||
}
|
||||
@ -1262,11 +1302,6 @@ body {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
.py-0\.5 {
|
||||
padding-top: 0.125rem;
|
||||
padding-bottom: 0.125rem;
|
||||
}
|
||||
|
||||
.py-1 {
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.25rem;
|
||||
@ -1459,10 +1494,6 @@ body {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.opacity-50 {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.opacity-80 {
|
||||
opacity: 0.8;
|
||||
}
|
||||
@ -1479,12 +1510,6 @@ body {
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
.shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
.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);
|
||||
@ -1520,6 +1545,11 @@ body {
|
||||
--tw-ring-offset-color: hsl(var(--background) / 1);
|
||||
}
|
||||
|
||||
.blur {
|
||||
--tw-blur: blur(8px);
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||
}
|
||||
|
||||
.filter {
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||
}
|
||||
@ -1624,6 +1654,107 @@ body {
|
||||
color: hsl(var(--muted-foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.before\:absolute::before {
|
||||
content: var(--tw-content);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.before\:inset-0::before {
|
||||
content: var(--tw-content);
|
||||
inset: 0px;
|
||||
}
|
||||
|
||||
.before\:left-1\/2::before {
|
||||
content: var(--tw-content);
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.before\:top-1\/2::before {
|
||||
content: var(--tw-content);
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.before\:h-1\.5::before {
|
||||
content: var(--tw-content);
|
||||
height: 0.375rem;
|
||||
}
|
||||
|
||||
.before\:w-1\.5::before {
|
||||
content: var(--tw-content);
|
||||
width: 0.375rem;
|
||||
}
|
||||
|
||||
.before\:-translate-x-1\/2::before {
|
||||
content: var(--tw-content);
|
||||
--tw-translate-x: -50%;
|
||||
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));
|
||||
}
|
||||
|
||||
.before\:-translate-y-1\/2::before {
|
||||
content: var(--tw-content);
|
||||
--tw-translate-y: -50%;
|
||||
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));
|
||||
}
|
||||
|
||||
.before\:rounded-full::before {
|
||||
content: var(--tw-content);
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.before\:bg-background::before {
|
||||
content: var(--tw-content);
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--background) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.after\:absolute::after {
|
||||
content: var(--tw-content);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.after\:left-0\.5::after {
|
||||
content: var(--tw-content);
|
||||
left: 0.125rem;
|
||||
}
|
||||
|
||||
.after\:top-0\.5::after {
|
||||
content: var(--tw-content);
|
||||
top: 0.125rem;
|
||||
}
|
||||
|
||||
.after\:h-5::after {
|
||||
content: var(--tw-content);
|
||||
height: 1.25rem;
|
||||
}
|
||||
|
||||
.after\:w-5::after {
|
||||
content: var(--tw-content);
|
||||
width: 1.25rem;
|
||||
}
|
||||
|
||||
.after\:rounded-full::after {
|
||||
content: var(--tw-content);
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.after\:bg-muted-foreground::after {
|
||||
content: var(--tw-content);
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--muted-foreground) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.after\:transition-all::after {
|
||||
content: var(--tw-content);
|
||||
transition-property: all;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.after\:content-\[\'\'\]::after {
|
||||
--tw-content: '';
|
||||
content: var(--tw-content);
|
||||
}
|
||||
|
||||
.checked\:border-primary:checked {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: hsl(var(--primary) / var(--tw-border-opacity));
|
||||
@ -1634,6 +1765,17 @@ body {
|
||||
background-color: hsl(var(--primary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.checked\:before\:visible:checked::before {
|
||||
content: var(--tw-content);
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.checked\:before\:bg-primary:checked::before {
|
||||
content: var(--tw-content);
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--primary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-accent:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--accent) / var(--tw-bg-opacity));
|
||||
@ -1698,6 +1840,22 @@ body {
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.focus\:outline:focus {
|
||||
outline-style: solid;
|
||||
}
|
||||
|
||||
.focus\:outline-2:focus {
|
||||
outline-width: 2px;
|
||||
}
|
||||
|
||||
.focus\:outline-offset-2:focus {
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.focus\:outline-ring:focus {
|
||||
outline-color: hsl(var(--ring) / 1);
|
||||
}
|
||||
|
||||
.focus\:ring-2:focus {
|
||||
--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);
|
||||
@ -1713,6 +1871,19 @@ body {
|
||||
--tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity));
|
||||
}
|
||||
|
||||
.focus\:ring-ring:focus {
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: hsl(var(--ring) / var(--tw-ring-opacity));
|
||||
}
|
||||
|
||||
.focus\:ring-offset-2:focus {
|
||||
--tw-ring-offset-width: 2px;
|
||||
}
|
||||
|
||||
.checked\:focus\:outline-primary:focus:checked {
|
||||
outline-color: hsl(var(--primary) / 1);
|
||||
}
|
||||
|
||||
.focus-visible\:outline-none:focus-visible {
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 2px;
|
||||
@ -1733,6 +1904,14 @@ body {
|
||||
--tw-ring-offset-width: 2px;
|
||||
}
|
||||
|
||||
.focus-visible\:ring-offset-background:focus-visible {
|
||||
--tw-ring-offset-color: hsl(var(--background) / 1);
|
||||
}
|
||||
|
||||
.active\:outline-offset-0:active {
|
||||
outline-offset: 0px;
|
||||
}
|
||||
|
||||
.disabled\:pointer-events-none:disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
@ -1763,24 +1942,30 @@ body {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.peer:checked ~ .peer-checked\:visible {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.peer:checked ~ .peer-checked\:bg-primary {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--primary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.peer:focus-visible ~ .peer-focus-visible\:ring-2 {
|
||||
--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);
|
||||
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
||||
.peer:checked ~ .peer-checked\:text-foreground {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.peer:focus-visible ~ .peer-focus-visible\:ring-ring {
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: hsl(var(--ring) / var(--tw-ring-opacity));
|
||||
.peer:checked ~ .peer-checked\:after\:translate-x-\[16px\]::after {
|
||||
content: var(--tw-content);
|
||||
--tw-translate-x: 16px;
|
||||
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));
|
||||
}
|
||||
|
||||
.peer:focus-visible ~ .peer-focus-visible\:ring-offset-2 {
|
||||
--tw-ring-offset-width: 2px;
|
||||
.peer:checked ~ .peer-checked\:after\:bg-secondary::after {
|
||||
content: var(--tw-content);
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--secondary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.peer:disabled ~ .peer-disabled\:cursor-not-allowed {
|
||||
@ -1791,6 +1976,10 @@ body {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.peer:disabled ~ .peer-disabled\:opacity-70 {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.dark\:text-gray-200:is(.dark *) {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(229 231 235 / var(--tw-text-opacity));
|
||||
@ -1820,10 +2009,6 @@ body {
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.sm\:max-w-\[70\%\] {
|
||||
max-width: 70%;
|
||||
}
|
||||
|
||||
.sm\:flex-row-reverse {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
@ -1871,6 +2056,70 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
.\[\&\:\:-moz-range-thumb\]\:h-4::-moz-range-thumb {
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.\[\&\:\:-moz-range-thumb\]\:w-4::-moz-range-thumb {
|
||||
width: 1rem;
|
||||
}
|
||||
|
||||
.\[\&\:\:-moz-range-thumb\]\:rounded-full::-moz-range-thumb {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.\[\&\:\:-moz-range-thumb\]\:border-0::-moz-range-thumb {
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.\[\&\:\:-moz-range-thumb\]\:bg-primary::-moz-range-thumb {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--primary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.\[\&\:\:-moz-range-thumb\]\:hover\:bg-primary\/90:hover::-moz-range-thumb {
|
||||
background-color: hsl(var(--primary) / 0.9);
|
||||
}
|
||||
|
||||
.\[\&\:\:-webkit-slider-thumb\]\:h-4::-webkit-slider-thumb {
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.\[\&\:\:-webkit-slider-thumb\]\:w-4::-webkit-slider-thumb {
|
||||
width: 1rem;
|
||||
}
|
||||
|
||||
.\[\&\:\:-webkit-slider-thumb\]\:appearance-none::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.\[\&\:\:-webkit-slider-thumb\]\:rounded-full::-webkit-slider-thumb {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.\[\&\:\:-webkit-slider-thumb\]\:bg-primary::-webkit-slider-thumb {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: hsl(var(--primary) / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.\[\&\:\:-webkit-slider-thumb\]\:hover\:bg-primary\/90:hover::-webkit-slider-thumb {
|
||||
background-color: hsl(var(--primary) / 0.9);
|
||||
}
|
||||
|
||||
.\[\&\:has\(input\:checked\)\]\:text-foreground:has(input:checked) {
|
||||
--tw-text-opacity: 1;
|
||||
color: hsl(var(--foreground) / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.\[\&\:has\(input\:disabled\)\]\:cursor-not-allowed:has(input:disabled) {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.\[\&\:has\(input\:disabled\)\]\:opacity-50:has(input:disabled) {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.\[\&\:has\(svg\)\]\:pl-11:has(svg) {
|
||||
padding-left: 2.75rem;
|
||||
}
|
||||
|
9950
repopack-output.txt
Normal file
9950
repopack-output.txt
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user