├── .github
└── workflows
│ └── go.yml
├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── cmd
└── storybook.go
├── css.go
├── go.mod
├── go.sum
├── icons
├── icons.templ
└── icons_templ.go
├── include.templ
├── include_templ.go
├── primitives
├── dialog
│ ├── close.templ
│ ├── close_templ.go
│ ├── content.templ
│ ├── content_templ.go
│ ├── description.templ
│ ├── description_templ.go
│ ├── dialog.go
│ ├── overlay.templ
│ ├── overlay_templ.go
│ ├── root.templ
│ ├── root_templ.go
│ ├── title.templ
│ ├── title_templ.go
│ ├── trigger.templ
│ └── trigger_templ.go
├── portal
│ ├── root.templ
│ └── root_templ.go
├── props.go
└── utils.go
├── static
└── css
│ ├── input.css
│ └── output.css
├── tailwind.config.js
├── tailwindcss-animate.js
└── ui
├── accordion.templ
├── accordion_templ.go
├── alert.templ
├── alert_templ.go
├── aspect-ratio
├── generated_optaliase.go
├── root.templ
└── root_templ.go
├── avatar.templ
├── avatar_templ.go
├── badge.templ
├── badge_templ.go
├── breadcrumb.templ
├── breadcrumb_templ.go
├── button.templ
├── button
├── root.templ
└── root_templ.go
├── button_templ.go
├── card.templ
├── card_templ.go
├── checkbox.templ
├── checkbox_templ.go
├── collapsible.templ
├── collapsible_templ.go
├── dialog.templ
├── dialog
├── close.go
├── content.templ
├── content_templ.go
├── description.templ
├── description_templ.go
├── footer.templ
├── footer_templ.go
├── header.templ
├── header_templ.go
├── overlay.templ
├── overlay_templ.go
├── root.go
├── title.templ
├── title_templ.go
└── trigger.go
├── dialog_templ.go
├── dropdown-menu.templ
├── dropdown-menu_templ.go
├── field.templ
├── field_templ.go
├── input.templ
├── input_templ.go
├── label.templ
├── label_templ.go
├── optalias_generator.go
├── progress
├── generated_optaliase.go
├── root.templ
└── root_templ.go
├── props.go
├── separator.templ
├── separator_templ.go
├── skeleton.templ
├── skeleton_templ.go
├── switch.templ
├── switch_templ.go
├── table.templ
├── table_templ.go
├── tabs.templ
├── tabs_templ.go
├── textarea.templ
├── textarea_templ.go
├── toggle.templ
├── toggle_templ.go
└── utils.go
/.github/workflows/go.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build a golang project
2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
3 |
4 | name: Go
5 |
6 | on:
7 | push:
8 | branches: [ "main" ]
9 | pull_request:
10 | branches: [ "main" ]
11 |
12 | jobs:
13 |
14 | build:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - uses: actions/checkout@v4
18 |
19 | - name: Set up Go
20 | uses: actions/setup-go@v4
21 | with:
22 | go-version: '1.23.2'
23 |
24 | - name: Build
25 | run: go build -v ./...
26 |
27 | - name: Test
28 | run: go test -v ./...
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # If you prefer the allow list template instead of the deny list, see community template:
2 | # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
3 | #
4 | # Binaries for programs and plugins
5 | *.exe
6 | *.exe~
7 | *.dll
8 | *.so
9 | *.dylib
10 |
11 | # Test binary, built with `go test -c`
12 | *.test
13 |
14 | # Output of the go coverage tool, specifically when used with LiteIDE
15 | *.out
16 |
17 | # Dependency directories (remove the comment below to include it)
18 | # vendor/
19 |
20 | # Go workspace file
21 | go.work
22 | go.work.sum
23 |
24 | # env file
25 | .env
26 |
27 | *storybook.log
28 |
29 | storybook-server/
30 |
31 | tailwindcss
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Rotem Horesh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | gen:
2 | templ generate
3 | ./tailwindcss -i ./static/css/input.css -o ./static/css/output.css --minify
4 | go generate ./...
5 |
6 | sb:
7 | go run ./cmd/storybook.go
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Shadcn/ui port for Go + Templ + Alpine.js + Tailwind CSS
2 |
3 | [](https://pkg.go.dev/github.com/rotemhoresh/shadcn-templ)
4 | [](https://opensource.org/licenses/MIT)
5 | [](https://goreportcard.com/report/github.com/rotemhoresh/shadcn-templ)
6 |
7 | ### Note
8 |
9 | **The codebase is going through a change in structure, so it's currently a bit messy**
10 |
11 | This is a work in proccess.
12 |
13 | - Not all the components from shadcn/ui are implemented.
14 | - There are refinements needed for some of the components - alpine.js naming, unfinished accessibility, improvements I want to make, etc.
15 | - Some components might contain behavior that existed for previous needs (I detached the developement of this from another project). Hopefully will be fixed in the future.
16 |
17 | ## Overview
18 |
19 | A [shadcn/ui](https://ui.shadcn.com/) port using [Go](https://go.dev/), [Templ](https://templ.guide/), [Alpine.js](https://alpinejs.dev/) and [Tailwind CSS](https://tailwindcss.com/).
20 |
21 | ### Components
22 |
23 | [issue](https://github.com/rotemhoresh/shadcn-templ/issues/1#issue-2570468143).
24 |
25 | ### Roadmap
26 |
27 | - Adding all the components from shadcn/ui
28 | - Making sure the components are of good quality: Accessibility, Correct functionality, Style, etc.
29 | - Creating a CLI to have a flow similar to shadcn's.
30 |
31 | ### Usage
32 |
33 | You have to include the [Head](https://github.com/rotemhoresh/shadcn-templ/blob/main/include.templ#L4) component in your `head` tag (it includes the neccessery scripts - Alpine.js and a theme script).
34 | You have to serve the [CSS](https://github.com/rotemhoresh/shadcn-templ/blob/main/css.go#L10) var and link to it in your `head` tag.
35 |
36 | Example:
37 |
38 | ```go
39 | router.HandleFunc("GET /static/css/styles.css", func(w http.ResponseWriter, r *http.Request) {
40 | w.Header().Set("Content-Type", "text/css")
41 | w.Write(shadcntempl.CSS)
42 | })
43 | ```
44 |
45 | ```templ
46 | templ Layout() {
47 |
48 |
49 |
50 | // ...
51 | @shadcntempl.Head()
52 |
83 | p.CoreProps // Class and Attrs
84 | }
85 | ```
86 |
87 | For example, the `button.Root`'s props:
88 |
89 | ```go
90 | type RootProps struct {
91 | Type Type // default: [TypeButton]
92 | Variant Variant // default: [VariantDefault]
93 | Size Size // default: [SizeDefault]
94 | p.CoreProps
95 | }
96 | ```
97 |
98 | The components are written with constant referencing to the shadcn/ui source code and the underlying radix components.
99 |
100 | ## Contributing
101 |
102 | Contributions are welcome for both new components and improvements for existing ones.
103 |
104 | Make sure to read the README and go over the codebase to understand the design choices and overall coding style as well as getting familiar with shadcn/ui.
105 |
106 | ### License
107 |
108 | MIT
109 |
--------------------------------------------------------------------------------
/cmd/storybook.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "log"
6 | "net/url"
7 |
8 | "github.com/a-h/templ/storybook"
9 | "github.com/rotemhoresh/shadcn-templ/ui/button"
10 | )
11 |
12 | func main() {
13 | s := storybook.New(storybook.WithHeader(`
14 |
15 |
16 | `))
17 | s.AddComponent("button", button.Root, storybook.Arg{
18 | Name: "content",
19 | Value: "val",
20 | Control: "con",
21 | Get: func(q url.Values) interface{} {
22 | return q.Get("content")
23 | },
24 | })
25 |
26 | // if err := s.Build(context.Background()); err != nil {
27 | // log.Fatalln(err)
28 | // }
29 |
30 | if err := s.ListenAndServeWithContext(context.Background()); err != nil {
31 | log.Fatalln(err)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/css.go:
--------------------------------------------------------------------------------
1 | package shadcntempl
2 |
3 | import _ "embed"
4 |
5 | // The compiled CSS used in this module.
6 | //
7 | // You need to include a path that serves this in your head tag.
8 | //
9 | //go:embed static/css/output.css
10 | var CSS []byte
11 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/rotemhoresh/shadcn-templ
2 |
3 | go 1.23.2
4 |
5 | require (
6 | github.com/Oudwins/tailwind-merge-go v0.2.0
7 | github.com/a-h/templ v0.2.778
8 | )
9 |
10 | require (
11 | github.com/a-h/pathvars v0.0.14 // indirect
12 | github.com/rs/cors v1.11.0 // indirect
13 | go.uber.org/multierr v1.11.0 // indirect
14 | go.uber.org/zap v1.27.0 // indirect
15 | golang.org/x/mod v0.20.0 // indirect
16 | )
17 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/Oudwins/tailwind-merge-go v0.2.0 h1:rtVHgYmLwwae4P+K6//ceRuUdyz3Bny6fo4664fOEmo=
2 | github.com/Oudwins/tailwind-merge-go v0.2.0/go.mod h1:kkZodgOPvZQ8f7SIrlWkG/w1g9JTbtnptnePIh3V72U=
3 | github.com/a-h/pathvars v0.0.14 h1:5/C0U5zuUtvAfVQCR5vow4E4MIRU7QIOLz8z26EeeQw=
4 | github.com/a-h/pathvars v0.0.14/go.mod h1:7rLTtvDVyKneR/N65hC0lh2sZ2KRyAmWFaOvv00uxb0=
5 | github.com/a-h/templ v0.2.778 h1:VzhOuvWECrwOec4790lcLlZpP4Iptt5Q4K9aFxQmtaM=
6 | github.com/a-h/templ v0.2.778/go.mod h1:lq48JXoUvuQrU0VThrK31yFwdRjTCnIE5bcPCM9IP1w=
7 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
8 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
10 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
11 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
12 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
13 | github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
14 | github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
15 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
16 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
17 | go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
18 | go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
19 | go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
20 | go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
21 | go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
22 | go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
23 | golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
24 | golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
25 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
26 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
27 |
--------------------------------------------------------------------------------
/icons/icons.templ:
--------------------------------------------------------------------------------
1 | package icons
2 |
3 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
4 |
5 | type Props struct {
6 | Class string
7 | Attrs templ.Attributes
8 | }
9 |
10 | templ CircleAlert(props Props) {
11 |
12 | }
13 |
14 | templ CircleCheck(props Props) {
15 |
16 | }
17 |
18 | templ Check(props Props) {
19 |
20 | }
21 |
22 | templ Info(props Props) {
23 |
24 | }
25 |
26 | templ CircleX(props Props) {
27 |
28 | }
29 |
30 | templ Megaphone(props Props) {
31 |
32 | }
33 |
34 | templ ChevronRight(props Props) {
35 |
36 | }
37 |
38 | templ LogIn(props Props) {
39 |
40 | }
41 |
42 | templ Film(props Props) {
43 |
44 | }
45 |
46 | templ Sun(props Props) {
47 |
48 | }
49 |
50 | templ Moon(props Props) {
51 |
52 | }
53 |
54 | templ SunMoon(props Props) {
55 |
56 | }
57 |
58 | templ ChevronDown(props Props) {
59 |
60 | }
61 |
62 | templ ChevronUp(props Props) {
63 |
64 | }
65 |
66 | templ X(props Props) {
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/include.templ:
--------------------------------------------------------------------------------
1 | package shadcntempl
2 |
3 | // Tags to include in the head of your page.
4 | templ Head() {
5 | // Alpine.js
6 |
7 |
8 |
9 | // Dark mode
10 |
17 | }
18 |
--------------------------------------------------------------------------------
/include_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package shadcntempl
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | // Tags to include in the head of your page.
12 | func Head() templ.Component {
13 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
14 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
15 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
16 | return templ_7745c5c3_CtxErr
17 | }
18 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
19 | if !templ_7745c5c3_IsBuffer {
20 | defer func() {
21 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
22 | if templ_7745c5c3_Err == nil {
23 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
24 | }
25 | }()
26 | }
27 | ctx = templ.InitializeContext(ctx)
28 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
29 | if templ_7745c5c3_Var1 == nil {
30 | templ_7745c5c3_Var1 = templ.NopComponent
31 | }
32 | ctx = templ.ClearChildren(ctx)
33 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
34 | if templ_7745c5c3_Err != nil {
35 | return templ_7745c5c3_Err
36 | }
37 | return templ_7745c5c3_Err
38 | })
39 | }
40 |
41 | var _ = templruntime.GeneratedTemplate
42 |
--------------------------------------------------------------------------------
/primitives/dialog/close.templ:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import "fmt"
4 |
5 | // There is no element for dialog close, just add these attributes to your component.
6 | var Close = templ.Attributes{
7 | "x-on:click": fmt.Sprintf("%s = false", control),
8 | }
9 |
--------------------------------------------------------------------------------
/primitives/dialog/close_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package dialog
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import "fmt"
12 |
13 | // There is no element for dialog close, just add these attributes to your component.
14 | var Close = templ.Attributes{
15 | "x-on:click": fmt.Sprintf("%s = false", control),
16 | }
17 |
18 | var _ = templruntime.GeneratedTemplate
19 |
--------------------------------------------------------------------------------
/primitives/dialog/content.templ:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import (
4 | "fmt"
5 | p "github.com/rotemhoresh/shadcn-templ/primitives"
6 | )
7 |
8 | const contentName = "content"
9 |
10 | type ContentProps struct {
11 | p.CoreProps
12 | }
13 |
14 | templ Content(props ContentProps) {
15 |
30 | { children... }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/primitives/dialog/content_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package dialog
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "fmt"
13 | p "github.com/rotemhoresh/shadcn-templ/primitives"
14 | )
15 |
16 | const contentName = "content"
17 |
18 | type ContentProps struct {
19 | p.CoreProps
20 | }
21 |
22 | func Content(props ContentProps) templ.Component {
23 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
24 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
25 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
26 | return templ_7745c5c3_CtxErr
27 | }
28 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
29 | if !templ_7745c5c3_IsBuffer {
30 | defer func() {
31 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
32 | if templ_7745c5c3_Err == nil {
33 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
34 | }
35 | }()
36 | }
37 | ctx = templ.InitializeContext(ctx)
38 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
39 | if templ_7745c5c3_Var1 == nil {
40 | templ_7745c5c3_Var1 = templ.NopComponent
41 | }
42 | ctx = templ.ClearChildren(ctx)
43 | var templ_7745c5c3_Var2 = []any{props.Class}
44 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
45 | if templ_7745c5c3_Err != nil {
46 | return templ_7745c5c3_Err
47 | }
48 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
174 | if templ_7745c5c3_Err != nil {
175 | return templ_7745c5c3_Err
176 | }
177 | templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
178 | if templ_7745c5c3_Err != nil {
179 | return templ_7745c5c3_Err
180 | }
181 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
182 | if templ_7745c5c3_Err != nil {
183 | return templ_7745c5c3_Err
184 | }
185 | return templ_7745c5c3_Err
186 | })
187 | }
188 |
189 | var _ = templruntime.GeneratedTemplate
190 |
--------------------------------------------------------------------------------
/primitives/dialog/description.templ:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import p "github.com/rotemhoresh/shadcn-templ/primitives"
4 |
5 | const descriptionName = "description"
6 |
7 | type DescriptionProps struct {
8 | p.CoreProps
9 | }
10 |
11 | templ Description(props DescriptionProps) {
12 |
17 | { children... }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/primitives/dialog/description_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package dialog
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import p "github.com/rotemhoresh/shadcn-templ/primitives"
12 |
13 | const descriptionName = "description"
14 |
15 | type DescriptionProps struct {
16 | p.CoreProps
17 | }
18 |
19 | func Description(props DescriptionProps) templ.Component {
20 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
21 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
22 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
23 | return templ_7745c5c3_CtxErr
24 | }
25 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
26 | if !templ_7745c5c3_IsBuffer {
27 | defer func() {
28 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
29 | if templ_7745c5c3_Err == nil {
30 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
31 | }
32 | }()
33 | }
34 | ctx = templ.InitializeContext(ctx)
35 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
36 | if templ_7745c5c3_Var1 == nil {
37 | templ_7745c5c3_Var1 = templ.NopComponent
38 | }
39 | ctx = templ.ClearChildren(ctx)
40 | var templ_7745c5c3_Var2 = []any{props.Class}
41 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
42 | if templ_7745c5c3_Err != nil {
43 | return templ_7745c5c3_Err
44 | }
45 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
80 | if templ_7745c5c3_Err != nil {
81 | return templ_7745c5c3_Err
82 | }
83 | templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
84 | if templ_7745c5c3_Err != nil {
85 | return templ_7745c5c3_Err
86 | }
87 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
88 | if templ_7745c5c3_Err != nil {
89 | return templ_7745c5c3_Err
90 | }
91 | return templ_7745c5c3_Err
92 | })
93 | }
94 |
95 | var _ = templruntime.GeneratedTemplate
96 |
--------------------------------------------------------------------------------
/primitives/dialog/dialog.go:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import (
4 | "fmt"
5 |
6 | p "github.com/rotemhoresh/shadcn-templ/primitives"
7 | )
8 |
9 | const scopeName = "dialog"
10 |
11 | var control = p.Prop("open")
12 |
13 | func getState(c string) string {
14 | return fmt.Sprintf("%s ? 'open' : 'closed'", c)
15 | }
16 |
--------------------------------------------------------------------------------
/primitives/dialog/overlay.templ:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import p "github.com/rotemhoresh/shadcn-templ/primitives"
4 |
5 | type OverlayProps struct {
6 | p.CoreProps
7 | }
8 |
9 | templ Overlay(props OverlayProps) {
10 |
18 | { children... }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/primitives/dialog/overlay_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package dialog
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import p "github.com/rotemhoresh/shadcn-templ/primitives"
12 |
13 | type OverlayProps struct {
14 | p.CoreProps
15 | }
16 |
17 | func Overlay(props OverlayProps) templ.Component {
18 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
19 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
20 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
21 | return templ_7745c5c3_CtxErr
22 | }
23 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
24 | if !templ_7745c5c3_IsBuffer {
25 | defer func() {
26 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
27 | if templ_7745c5c3_Err == nil {
28 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
29 | }
30 | }()
31 | }
32 | ctx = templ.InitializeContext(ctx)
33 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
34 | if templ_7745c5c3_Var1 == nil {
35 | templ_7745c5c3_Var1 = templ.NopComponent
36 | }
37 | ctx = templ.ClearChildren(ctx)
38 | var templ_7745c5c3_Var2 = []any{props.Class}
39 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
40 | if templ_7745c5c3_Err != nil {
41 | return templ_7745c5c3_Err
42 | }
43 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
91 | if templ_7745c5c3_Err != nil {
92 | return templ_7745c5c3_Err
93 | }
94 | templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
95 | if templ_7745c5c3_Err != nil {
96 | return templ_7745c5c3_Err
97 | }
98 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
99 | if templ_7745c5c3_Err != nil {
100 | return templ_7745c5c3_Err
101 | }
102 | return templ_7745c5c3_Err
103 | })
104 | }
105 |
106 | var _ = templruntime.GeneratedTemplate
107 |
--------------------------------------------------------------------------------
/primitives/dialog/root.templ:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import (
4 | "fmt"
5 | twmerge "github.com/Oudwins/tailwind-merge-go"
6 | p "github.com/rotemhoresh/shadcn-templ/primitives"
7 | )
8 |
9 | // TODO: support controlled dialog state
10 | // TODO: add a modal prop
11 |
12 | type RootProps struct {
13 | p.CoreProps
14 | }
15 |
16 | templ Root(props RootProps) {
17 |
25 | { children... }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/primitives/dialog/root_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package dialog
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "fmt"
13 | twmerge "github.com/Oudwins/tailwind-merge-go"
14 | p "github.com/rotemhoresh/shadcn-templ/primitives"
15 | )
16 |
17 | // TODO: support controlled dialog state
18 | // TODO: add a modal prop
19 |
20 | type RootProps struct {
21 | p.CoreProps
22 | }
23 |
24 | func Root(props RootProps) templ.Component {
25 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
26 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
27 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
28 | return templ_7745c5c3_CtxErr
29 | }
30 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
31 | if !templ_7745c5c3_IsBuffer {
32 | defer func() {
33 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
34 | if templ_7745c5c3_Err == nil {
35 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
36 | }
37 | }()
38 | }
39 | ctx = templ.InitializeContext(ctx)
40 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
41 | if templ_7745c5c3_Var1 == nil {
42 | templ_7745c5c3_Var1 = templ.NopComponent
43 | }
44 | ctx = templ.ClearChildren(ctx)
45 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(props.Class)}
46 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
47 | if templ_7745c5c3_Err != nil {
48 | return templ_7745c5c3_Err
49 | }
50 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
100 | if templ_7745c5c3_Err != nil {
101 | return templ_7745c5c3_Err
102 | }
103 | templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
104 | if templ_7745c5c3_Err != nil {
105 | return templ_7745c5c3_Err
106 | }
107 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
108 | if templ_7745c5c3_Err != nil {
109 | return templ_7745c5c3_Err
110 | }
111 | return templ_7745c5c3_Err
112 | })
113 | }
114 |
115 | var _ = templruntime.GeneratedTemplate
116 |
--------------------------------------------------------------------------------
/primitives/dialog/title.templ:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import p "github.com/rotemhoresh/shadcn-templ/primitives"
4 |
5 | const titleName = "title"
6 |
7 | type TitleProps struct {
8 | p.CoreProps
9 | }
10 |
11 | templ Title(props TitleProps) {
12 |
17 | { children... }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/primitives/dialog/title_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package dialog
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import p "github.com/rotemhoresh/shadcn-templ/primitives"
12 |
13 | const titleName = "title"
14 |
15 | type TitleProps struct {
16 | p.CoreProps
17 | }
18 |
19 | func Title(props TitleProps) templ.Component {
20 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
21 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
22 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
23 | return templ_7745c5c3_CtxErr
24 | }
25 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
26 | if !templ_7745c5c3_IsBuffer {
27 | defer func() {
28 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
29 | if templ_7745c5c3_Err == nil {
30 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
31 | }
32 | }()
33 | }
34 | ctx = templ.InitializeContext(ctx)
35 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
36 | if templ_7745c5c3_Var1 == nil {
37 | templ_7745c5c3_Var1 = templ.NopComponent
38 | }
39 | ctx = templ.ClearChildren(ctx)
40 | var templ_7745c5c3_Var2 = []any{props.Class}
41 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
42 | if templ_7745c5c3_Err != nil {
43 | return templ_7745c5c3_Err
44 | }
45 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
80 | if templ_7745c5c3_Err != nil {
81 | return templ_7745c5c3_Err
82 | }
83 | templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
84 | if templ_7745c5c3_Err != nil {
85 | return templ_7745c5c3_Err
86 | }
87 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
88 | if templ_7745c5c3_Err != nil {
89 | return templ_7745c5c3_Err
90 | }
91 | return templ_7745c5c3_Err
92 | })
93 | }
94 |
95 | var _ = templruntime.GeneratedTemplate
96 |
--------------------------------------------------------------------------------
/primitives/dialog/trigger.templ:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import (
4 | "fmt"
5 | p "github.com/rotemhoresh/shadcn-templ/primitives"
6 | )
7 |
8 | // There is no element for dialog trigger, just add these attributes to your component.
9 | var Trigger = templ.Attributes{
10 | "aria-haspopup": "dialog",
11 | ":aria-expanded": control,
12 | ":aria-controls": p.Id(scopeName, contentName),
13 | ":data-state": getState(control),
14 | "x-on:click": fmt.Sprintf("%s = true", control),
15 | }
16 |
--------------------------------------------------------------------------------
/primitives/dialog/trigger_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package dialog
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "fmt"
13 | p "github.com/rotemhoresh/shadcn-templ/primitives"
14 | )
15 |
16 | // There is no element for dialog trigger, just add these attributes to your component.
17 | var Trigger = templ.Attributes{
18 | "aria-haspopup": "dialog",
19 | ":aria-expanded": control,
20 | ":aria-controls": p.Id(scopeName, contentName),
21 | ":data-state": getState(control),
22 | "x-on:click": fmt.Sprintf("%s = true", control),
23 | }
24 |
25 | var _ = templruntime.GeneratedTemplate
26 |
--------------------------------------------------------------------------------
/primitives/portal/root.templ:
--------------------------------------------------------------------------------
1 | package portal
2 |
3 | const DefaultSelector = "body"
4 |
5 | type RootProps struct {
6 | Selector string
7 | Attrs templ.Attributes
8 | }
9 |
10 | func Root(props RootProps) templ.Component {
11 | if props.Selector == "" {
12 | props.Selector = DefaultSelector
13 | }
14 | return root(props)
15 | }
16 |
17 | templ root(props RootProps) {
18 |
22 | { children... }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/primitives/portal/root_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package portal
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | const DefaultSelector = "body"
12 |
13 | type RootProps struct {
14 | Selector string
15 | Attrs templ.Attributes
16 | }
17 |
18 | func Root(props RootProps) templ.Component {
19 | if props.Selector == "" {
20 | props.Selector = DefaultSelector
21 | }
22 | return root(props)
23 | }
24 |
25 | func root(props RootProps) templ.Component {
26 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
27 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
28 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
29 | return templ_7745c5c3_CtxErr
30 | }
31 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
32 | if !templ_7745c5c3_IsBuffer {
33 | defer func() {
34 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
35 | if templ_7745c5c3_Err == nil {
36 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
37 | }
38 | }()
39 | }
40 | ctx = templ.InitializeContext(ctx)
41 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
42 | if templ_7745c5c3_Var1 == nil {
43 | templ_7745c5c3_Var1 = templ.NopComponent
44 | }
45 | ctx = templ.ClearChildren(ctx)
46 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
68 | if templ_7745c5c3_Err != nil {
69 | return templ_7745c5c3_Err
70 | }
71 | templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
72 | if templ_7745c5c3_Err != nil {
73 | return templ_7745c5c3_Err
74 | }
75 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
76 | if templ_7745c5c3_Err != nil {
77 | return templ_7745c5c3_Err
78 | }
79 | return templ_7745c5c3_Err
80 | })
81 | }
82 |
83 | var _ = templruntime.GeneratedTemplate
84 |
--------------------------------------------------------------------------------
/primitives/props.go:
--------------------------------------------------------------------------------
1 | package primitives
2 |
3 | import "github.com/a-h/templ"
4 |
5 | //
6 | // type Option[T CorePropsInter] func(T)
7 | //
8 | // // Sets the class
9 | // func WithClass[T CorePropsInter](c string) Option[T] {
10 | // return func(p T) {
11 | // p.SetClass(c)
12 | // }
13 | // }
14 | //
15 | // // Sets the attributes
16 | // func WithAttrs[T CorePropsInter](a templ.Attributes) Option[T] {
17 | // return func(p T) {
18 | // p.SetAttrs(a)
19 | // }
20 | // }
21 | //
22 | // // Adds an attribute
23 | // func WithAttr[T CorePropsInter](k string, v any) Option[T] {
24 | // return func(p T) {
25 | // p.SetAttr(k, v)
26 | // }
27 | // }
28 |
29 | type CoreProps struct {
30 | Class string
31 | Attrs templ.Attributes
32 | }
33 |
34 | func (p *CoreProps) AddAttr(k string, v any) {
35 | if p.Attrs == nil {
36 | p.Attrs = templ.Attributes{}
37 | }
38 | if k != "" && v != nil {
39 | p.Attrs[k] = v
40 | }
41 | }
42 |
43 | //
44 | // // assert interface implementation
45 | // var _ CorePropsInter = (*CoreProps)(nil)
46 | //
47 | // type CorePropsInter interface {
48 | // SetClass(string)
49 | // SetAttrs(templ.Attributes)
50 | // SetAttr(string, any)
51 | // Class() string
52 | // Attrs() templ.Attributes
53 | // }
54 | //
55 | // func (p *CoreProps) SetClass(c string) {
56 | // p.class = c
57 | // }
58 | //
59 | // func (p *CoreProps) SetAttrs(a templ.Attributes) {
60 | // p.attrs = a
61 | // }
62 | //
63 | // func (p *CoreProps) SetAttr(k string, v any) {
64 | // p.attrs[k] = v
65 | // }
66 | //
67 | // func (p *CoreProps) Class() string {
68 | // return p.class
69 | // }
70 | //
71 | // func (p *CoreProps) Attrs() templ.Attributes {
72 | // return p.attrs
73 | // }
74 |
--------------------------------------------------------------------------------
/primitives/utils.go:
--------------------------------------------------------------------------------
1 | package primitives
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 |
7 | "github.com/a-h/templ"
8 | )
9 |
10 | const (
11 | propPrefix = "shadcntempl"
12 | )
13 |
14 | // Id returns a string to be used with alpine's `:id` directive.
15 | //
16 | // example:
17 | //
18 | //
19 | // // :id="`${$id('label')}:header`"
20 | func Id(scope, postfix string) string {
21 | return fmt.Sprintf("`${$id('%s')}:%s`", scope, postfix)
22 | }
23 |
24 | // Scope returns a string to define an alpine id scope using the `x-id` directive.
25 | func Scope(name string) string {
26 | return fmt.Sprintf("['%s']", name)
27 | }
28 |
29 | type Data map[string]string
30 |
31 | func (d Data) String() string {
32 | var b strings.Builder
33 | b.WriteString("{ ")
34 | for k, v := range d {
35 | if k != "" && v != "" {
36 | b.WriteString(fmt.Sprintf("%s: %s, ", k, v))
37 | }
38 | }
39 | b.WriteString("}")
40 | return b.String()
41 | }
42 |
43 | // Data builds a `x-data` directive from a map.
44 | //
45 | // example:
46 | //
47 | // Data({{ "state", "'open'" }})
48 | // // "{ state: 'open', }"
49 | // func Data(kvs XData) string {
50 | // var b strings.Builder
51 | // b.WriteString("{ ")
52 | // for k, v := range kvs {
53 | // if k != "" && v != "" {
54 | // b.WriteString(fmt.Sprintf("%s: %s, ", k, v))
55 | // }
56 | // }
57 | // b.WriteString("}")
58 | // return b.String()
59 | // }
60 |
61 | // Prop formats a string to be a shadcn-templ prop.
62 | //
63 | // example:
64 | //
65 | // x-data={ Data({{ Prop("open"), "false" }}) }
66 | // // x-data="{ shadcntempl_open: false, }"
67 | func Prop(p string) string {
68 | return fmt.Sprintf("%s_%s", propPrefix, p)
69 | }
70 |
71 | // ExtractClass takes the class attribute, returns it, and DELETES it.
72 | // If no class is defined, returns an empty string.
73 | func ExtractClass(attrs templ.Attributes) any {
74 | if class, ok := attrs["class"]; ok {
75 | delete(attrs, "class")
76 | return class
77 | }
78 | return ""
79 | }
80 |
--------------------------------------------------------------------------------
/static/css/input.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | @layer base {
6 | :root {
7 | --background: 0 0% 100%;
8 | --foreground: 240 10% 3.9%;
9 | --card: 0 0% 100%;
10 | --card-foreground: 240 10% 3.9%;
11 | --popover: 0 0% 100%;
12 | --popover-foreground: 240 10% 3.9%;
13 | --primary: 240 5.9% 10%;
14 | --primary-foreground: 0 0% 98%;
15 | --secondary: 240 4.8% 95.9%;
16 | --secondary-foreground: 240 5.9% 10%;
17 | --muted: 240 4.8% 95.9%;
18 | --muted-foreground: 240 3.8% 46.1%;
19 | --accent: 240 4.8% 95.9%;
20 | --accent-foreground: 240 5.9% 10%;
21 | --destructive: 0 72.22% 50.59%;
22 | --destructive-foreground: 0 0% 98%;
23 | --border: 240 5.9% 90%;
24 | --input: 240 5.9% 90%;
25 | --ring: 240 5.9% 10%;
26 | --radius: 0.5rem;
27 | }
28 | .dark {
29 | --background: 240 10% 3.9%;
30 | --foreground: 0 0% 98%;
31 | --card: 240 10% 3.9%;
32 | --card-foreground: 0 0% 98%;
33 | --popover: 240 10% 3.9%;
34 | --popover-foreground: 0 0% 98%;
35 | --primary: 0 0% 98%;
36 | --primary-foreground: 240 5.9% 10%;
37 | --secondary: 240 3.7% 15.9%;
38 | --secondary-foreground: 0 0% 98%;
39 | --muted: 240 3.7% 15.9%;
40 | --muted-foreground: 240 5% 64.9%;
41 | --accent: 240 3.7% 15.9%;
42 | --accent-foreground: 0 0% 98%;
43 | --destructive: 0 62.8% 30.6%;
44 | --destructive-foreground: 0 0% 98%;
45 | --border: 240 3.7% 15.9%;
46 | --input: 240 3.7% 15.9%;
47 | --ring: 240 4.9% 83.9%;
48 | }
49 | }
50 |
51 | @layer base {
52 | * {
53 | @apply border-border;
54 | }
55 | body {
56 | @apply bg-background text-foreground;
57 | font-feature-settings: "rlig" 1, "calt" 1;
58 | }
59 | }
60 |
61 | /* for Alpine.js */
62 | [x-cloak] {
63 | display: none !important;
64 | }
65 |
66 | [aria-hidden="true"],
67 | [aria-hidden="true"] * {
68 | pointer-events: none;
69 | }
70 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | import { fontFamily } from "tailwindcss/defaultTheme";
2 |
3 | /** @type {import('tailwindcss').Config} */
4 | module.exports = {
5 | darkMode: ["selector"],
6 | content: [ "./**/*.html", "./**/*.templ", "./**/*.go", ],
7 | theme: {
8 | container: {
9 | center: true,
10 | padding: "2rem",
11 | screens: {
12 | "2xl": "1400px",
13 | },
14 | },
15 | extend: {
16 | colors: {
17 | border: "hsl(var(--border))",
18 | input: "hsl(var(--input))",
19 | ring: "hsl(var(--ring))",
20 | background: "hsl(var(--background))",
21 | foreground: "hsl(var(--foreground))",
22 | primary: {
23 | DEFAULT: "hsl(var(--primary))",
24 | foreground: "hsl(var(--primary-foreground))",
25 | },
26 | secondary: {
27 | DEFAULT: "hsl(var(--secondary))",
28 | foreground: "hsl(var(--secondary-foreground))",
29 | },
30 | destructive: {
31 | DEFAULT: "hsl(var(--destructive))",
32 | foreground: "hsl(var(--destructive-foreground))",
33 | },
34 | muted: {
35 | DEFAULT: "hsl(var(--muted))",
36 | foreground: "hsl(var(--muted-foreground))",
37 | },
38 | accent: {
39 | DEFAULT: "hsl(var(--accent))",
40 | foreground: "hsl(var(--accent-foreground))",
41 | },
42 | popover: {
43 | DEFAULT: "hsl(var(--popover))",
44 | foreground: "hsl(var(--popover-foreground))",
45 | },
46 | card: {
47 | DEFAULT: "hsl(var(--card))",
48 | foreground: "hsl(var(--card-foreground))",
49 | },
50 | },
51 | borderRadius: {
52 | lg: `var(--radius)`,
53 | md: `calc(var(--radius) - 2px)`,
54 | sm: "calc(var(--radius) - 4px)",
55 | },
56 | fontFamily: {
57 | sans: ["Inter", ...fontFamily.sans],
58 | },
59 | },
60 | },
61 | plugins: [
62 | require("./tailwindcss-animate"),
63 | ],
64 | }
65 |
66 |
--------------------------------------------------------------------------------
/tailwindcss-animate.js:
--------------------------------------------------------------------------------
1 | /*
2 | * tailwindcss-animate source.
3 | *
4 | * https://github.com/jamiebuilds/tailwindcss-animate/blob/main/index.js
5 | */
6 |
7 | const plugin = require("tailwindcss/plugin")
8 |
9 | function filterDefault(values) {
10 | return Object.fromEntries(
11 | Object.entries(values).filter(([key]) => key !== "DEFAULT"),
12 | )
13 | }
14 |
15 | module.exports = plugin(
16 | ({ addUtilities, matchUtilities, theme }) => {
17 | addUtilities({
18 | "@keyframes enter": theme("keyframes.enter"),
19 | "@keyframes exit": theme("keyframes.exit"),
20 | ".animate-in": {
21 | animationName: "enter",
22 | animationDuration: theme("animationDuration.DEFAULT"),
23 | "--tw-enter-opacity": "initial",
24 | "--tw-enter-scale": "initial",
25 | "--tw-enter-rotate": "initial",
26 | "--tw-enter-translate-x": "initial",
27 | "--tw-enter-translate-y": "initial",
28 | },
29 | ".animate-out": {
30 | animationName: "exit",
31 | animationDuration: theme("animationDuration.DEFAULT"),
32 | "--tw-exit-opacity": "initial",
33 | "--tw-exit-scale": "initial",
34 | "--tw-exit-rotate": "initial",
35 | "--tw-exit-translate-x": "initial",
36 | "--tw-exit-translate-y": "initial",
37 | },
38 | })
39 |
40 | matchUtilities(
41 | {
42 | "fade-in": (value) => ({ "--tw-enter-opacity": value }),
43 | "fade-out": (value) => ({ "--tw-exit-opacity": value }),
44 | },
45 | { values: theme("animationOpacity") },
46 | )
47 |
48 | matchUtilities(
49 | {
50 | "zoom-in": (value) => ({ "--tw-enter-scale": value }),
51 | "zoom-out": (value) => ({ "--tw-exit-scale": value }),
52 | },
53 | { values: theme("animationScale") },
54 | )
55 |
56 | matchUtilities(
57 | {
58 | "spin-in": (value) => ({ "--tw-enter-rotate": value }),
59 | "spin-out": (value) => ({ "--tw-exit-rotate": value }),
60 | },
61 | { values: theme("animationRotate") },
62 | )
63 |
64 | matchUtilities(
65 | {
66 | "slide-in-from-top": (value) => ({
67 | "--tw-enter-translate-y": `-${value}`,
68 | }),
69 | "slide-in-from-bottom": (value) => ({
70 | "--tw-enter-translate-y": value,
71 | }),
72 | "slide-in-from-left": (value) => ({
73 | "--tw-enter-translate-x": `-${value}`,
74 | }),
75 | "slide-in-from-right": (value) => ({
76 | "--tw-enter-translate-x": value,
77 | }),
78 | "slide-out-to-top": (value) => ({
79 | "--tw-exit-translate-y": `-${value}`,
80 | }),
81 | "slide-out-to-bottom": (value) => ({
82 | "--tw-exit-translate-y": value,
83 | }),
84 | "slide-out-to-left": (value) => ({
85 | "--tw-exit-translate-x": `-${value}`,
86 | }),
87 | "slide-out-to-right": (value) => ({
88 | "--tw-exit-translate-x": value,
89 | }),
90 | },
91 | { values: theme("animationTranslate") },
92 | )
93 |
94 | matchUtilities(
95 | { duration: (value) => ({ animationDuration: value }) },
96 | { values: filterDefault(theme("animationDuration")) },
97 | )
98 |
99 | matchUtilities(
100 | { delay: (value) => ({ animationDelay: value }) },
101 | { values: theme("animationDelay") },
102 | )
103 |
104 | matchUtilities(
105 | { ease: (value) => ({ animationTimingFunction: value }) },
106 | { values: filterDefault(theme("animationTimingFunction")) },
107 | )
108 |
109 | addUtilities({
110 | ".running": { animationPlayState: "running" },
111 | ".paused": { animationPlayState: "paused" },
112 | })
113 |
114 | matchUtilities(
115 | { "fill-mode": (value) => ({ animationFillMode: value }) },
116 | { values: theme("animationFillMode") },
117 | )
118 |
119 | matchUtilities(
120 | { direction: (value) => ({ animationDirection: value }) },
121 | { values: theme("animationDirection") },
122 | )
123 |
124 | matchUtilities(
125 | { repeat: (value) => ({ animationIterationCount: value }) },
126 | { values: theme("animationRepeat") },
127 | )
128 | },
129 | {
130 | theme: {
131 | extend: {
132 | animationDelay: ({ theme }) => ({
133 | ...theme("transitionDelay"),
134 | }),
135 | animationDuration: ({ theme }) => ({
136 | 0: "0ms",
137 | ...theme("transitionDuration"),
138 | }),
139 | animationTimingFunction: ({ theme }) => ({
140 | ...theme("transitionTimingFunction"),
141 | }),
142 | animationFillMode: {
143 | none: "none",
144 | forwards: "forwards",
145 | backwards: "backwards",
146 | both: "both",
147 | },
148 | animationDirection: {
149 | normal: "normal",
150 | reverse: "reverse",
151 | alternate: "alternate",
152 | "alternate-reverse": "alternate-reverse",
153 | },
154 | animationOpacity: ({ theme }) => ({
155 | DEFAULT: 0,
156 | ...theme("opacity"),
157 | }),
158 | animationTranslate: ({ theme }) => ({
159 | DEFAULT: "100%",
160 | ...theme("translate"),
161 | }),
162 | animationScale: ({ theme }) => ({
163 | DEFAULT: 0,
164 | ...theme("scale"),
165 | }),
166 | animationRotate: ({ theme }) => ({
167 | DEFAULT: "30deg",
168 | ...theme("rotate"),
169 | }),
170 | animationRepeat: {
171 | 0: "0",
172 | 1: "1",
173 | infinite: "infinite",
174 | },
175 | keyframes: {
176 | enter: {
177 | from: {
178 | opacity: "var(--tw-enter-opacity, 1)",
179 | transform:
180 | "translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0))",
181 | },
182 | },
183 | exit: {
184 | to: {
185 | opacity: "var(--tw-exit-opacity, 1)",
186 | transform:
187 | "translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0))",
188 | },
189 | },
190 | },
191 | },
192 | },
193 | },
194 | )
195 |
--------------------------------------------------------------------------------
/ui/accordion.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import (
4 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
5 | "github.com/rotemhoresh/shadcn-templ/icons"
6 | )
7 |
8 | const (
9 | accordionBaseClass = "w-full"
10 | accordionItemBaseClass = "border-b"
11 | accordionTriggerBaseClass = "flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline"
12 | accordionContentBaseClass = "overflow-hidden text-sm"
13 | )
14 |
15 | templ Accordion(classes string, attrs templ.Attributes) {
16 |
21 | { children... }
22 |
23 | }
24 |
25 | templ AccordionItem(classes string, attrs templ.Attributes) {
26 |
31 | { children... }
32 |
33 | }
34 |
35 | templ AccordionTrigger(classes string, attrs templ.Attributes) {
36 |
37 |
48 |
49 | }
50 |
51 | templ AccorionContent(classes string, attrs templ.Attributes) {
52 |
59 |
62 | { children... }
63 |
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/ui/alert.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import (
4 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
5 | "github.com/rotemhoresh/shadcn-templ/icons"
6 | )
7 |
8 | const (
9 | alertBaseClass = "[&>svg]:text-foreground relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg~*]:pl-7"
10 | alertTitleBaseClass = "mb-1 font-medium leading-none tracking-tight"
11 | alertDescriptionBaseClass = "text-sm [&_p]:leading-relaxed"
12 | )
13 |
14 | type AlertVariant int
15 |
16 | const (
17 | AlertVariantDefault AlertVariant = iota
18 | AlertVariantDestructive
19 | )
20 |
21 | func (v AlertVariant) Class() string {
22 | switch v {
23 | case AlertVariantDestructive:
24 | return "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive"
25 | default:
26 | return "bg-background text-foreground"
27 | }
28 | }
29 |
30 | func (v AlertVariant) Icon() templ.Component {
31 | switch v {
32 | case AlertVariantDestructive:
33 | return icons.CircleX(icons.Props{
34 | Class: "h-4 w-4",
35 | })
36 | default:
37 | return icons.CircleCheck(icons.Props{
38 | Class: "h-4 w-4",
39 | })
40 | }
41 | }
42 |
43 | templ Alert(variant AlertVariant, classes string, attrs templ.Attributes) {
44 |
49 | @variant.Icon()
50 | { children... }
51 |
52 | }
53 |
54 | templ AlertTitle(classes string, attrs templ.Attributes) {
55 |
59 | { children... }
60 |
61 | }
62 |
63 | templ AlertDescription(classes string, attrs templ.Attributes) {
64 |
68 | { children... }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/ui/aspect-ratio/generated_optaliase.go:
--------------------------------------------------------------------------------
1 | // Code generated by "optaliase_generator.go -type=RootProps"; DO NOT EDIT.
2 |
3 | package aspectratio
4 |
5 | import "github.com/rotemhoresh/shadcn-templ/ui"
6 |
7 | var (
8 | WithClass = ui.WithClass[*RootProps]
9 | WithAttrs = ui.WithAttrs[*RootProps]
10 | WithAttr = ui.WithAttr[*RootProps]
11 | )
12 |
--------------------------------------------------------------------------------
/ui/aspect-ratio/root.templ:
--------------------------------------------------------------------------------
1 | package aspectratio
2 |
3 | import (
4 | "fmt"
5 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
6 | "github.com/rotemhoresh/shadcn-templ/ui"
7 | )
8 |
9 | type RootProps struct {
10 | ratio float32
11 | ui.CoreProps
12 | }
13 |
14 | type RootOption = ui.Option[*RootProps]
15 |
16 | // note that `16/9` will result in `1`. you need to convert one of the numbers to float, e.g., `16.0/9.0`.
17 | func WithRatio(r float32) RootOption {
18 | return func(p *RootProps) {
19 | p.ratio = r
20 | }
21 | }
22 |
23 | //go:generate go run ../optalias_generator.go -type=RootProps
24 |
25 | func Root(opts ...RootOption) templ.Component {
26 | p := &RootProps{
27 | ratio: 1 / 1,
28 | CoreProps: ui.DefaultCoreProps,
29 | }
30 | for _, opt := range opts {
31 | opt(p)
32 | }
33 | return root(p)
34 | }
35 |
36 | css rootStyle() {
37 | position: absolute;
38 | top: 0;
39 | right: 0;
40 | bottom: 0;
41 | left: 0;
42 | }
43 |
44 | css rootWrapperStyle(r float32) {
45 | position: relative;
46 | width: 100%;
47 | padding-bottom: { fmt.Sprintf("%.2f%%", 100/r) };
48 | }
49 |
50 | templ root(props *RootProps) {
51 |
54 |
58 | { children... }
59 |
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/ui/aspect-ratio/root_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package aspectratio
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "fmt"
13 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
14 | "github.com/rotemhoresh/shadcn-templ/ui"
15 | )
16 |
17 | type RootProps struct {
18 | ratio float32
19 | ui.CoreProps
20 | }
21 |
22 | type RootOption = ui.Option[*RootProps]
23 |
24 | // note that `16/9` will result in `1`. you need to convert one of the numbers to float, e.g., `16.0/9.0`.
25 | func WithRatio(r float32) RootOption {
26 | return func(p *RootProps) {
27 | p.ratio = r
28 | }
29 | }
30 |
31 | //go:generate go run ../optalias_generator.go -type=RootProps
32 |
33 | func Root(opts ...RootOption) templ.Component {
34 | p := &RootProps{
35 | ratio: 1 / 1,
36 | CoreProps: ui.DefaultCoreProps,
37 | }
38 | for _, opt := range opts {
39 | opt(p)
40 | }
41 | return root(p)
42 | }
43 |
44 | func rootStyle() templ.CSSClass {
45 | templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
46 | templ_7745c5c3_CSSBuilder.WriteString(`position:absolute;`)
47 | templ_7745c5c3_CSSBuilder.WriteString(`top:0;`)
48 | templ_7745c5c3_CSSBuilder.WriteString(`right:0;`)
49 | templ_7745c5c3_CSSBuilder.WriteString(`bottom:0;`)
50 | templ_7745c5c3_CSSBuilder.WriteString(`left:0;`)
51 | templ_7745c5c3_CSSID := templ.CSSID(`rootStyle`, templ_7745c5c3_CSSBuilder.String())
52 | return templ.ComponentCSSClass{
53 | ID: templ_7745c5c3_CSSID,
54 | Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
55 | }
56 | }
57 |
58 | func rootWrapperStyle(r float32) templ.CSSClass {
59 | templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
60 | templ_7745c5c3_CSSBuilder.WriteString(`position:relative;`)
61 | templ_7745c5c3_CSSBuilder.WriteString(`width:100%;`)
62 | templ_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`padding-bottom`, fmt.Sprintf("%.2f%%", 100/r))))
63 | templ_7745c5c3_CSSID := templ.CSSID(`rootWrapperStyle`, templ_7745c5c3_CSSBuilder.String())
64 | return templ.ComponentCSSClass{
65 | ID: templ_7745c5c3_CSSID,
66 | Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
67 | }
68 | }
69 |
70 | func root(props *RootProps) templ.Component {
71 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
72 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
73 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
74 | return templ_7745c5c3_CtxErr
75 | }
76 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
77 | if !templ_7745c5c3_IsBuffer {
78 | defer func() {
79 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
80 | if templ_7745c5c3_Err == nil {
81 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
82 | }
83 | }()
84 | }
85 | ctx = templ.InitializeContext(ctx)
86 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
87 | if templ_7745c5c3_Var1 == nil {
88 | templ_7745c5c3_Var1 = templ.NopComponent
89 | }
90 | ctx = templ.ClearChildren(ctx)
91 | var templ_7745c5c3_Var2 = []any{rootWrapperStyle(props.ratio)}
92 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
93 | if templ_7745c5c3_Err != nil {
94 | return templ_7745c5c3_Err
95 | }
96 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
110 | if templ_7745c5c3_Err != nil {
111 | return templ_7745c5c3_Err
112 | }
113 | var templ_7745c5c3_Var4 = []any{rootStyle(), twmerge.Merge(props.Class())}
114 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
115 | if templ_7745c5c3_Err != nil {
116 | return templ_7745c5c3_Err
117 | }
118 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
140 | if templ_7745c5c3_Err != nil {
141 | return templ_7745c5c3_Err
142 | }
143 | templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
144 | if templ_7745c5c3_Err != nil {
145 | return templ_7745c5c3_Err
146 | }
147 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
148 | if templ_7745c5c3_Err != nil {
149 | return templ_7745c5c3_Err
150 | }
151 | return templ_7745c5c3_Err
152 | })
153 | }
154 |
155 | var _ = templruntime.GeneratedTemplate
156 |
--------------------------------------------------------------------------------
/ui/avatar.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import (
4 | "fmt"
5 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
6 | )
7 |
8 | const (
9 | avatarBaseClass = "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full"
10 | avatarImageBaseClass = "aspect-square h-full w-full"
11 | avatarFallbackBaseClass = "flex h-full w-full items-center justify-center rounded-full bg-muted"
12 | )
13 |
14 | templ Avatar(classes string, attrs templ.Attributes) {
15 |
20 | { children... }
21 |
22 | }
23 |
24 | templ AvatarImage(src, alt, classes string, attrs templ.Attributes) {
25 |
status = 'loaded';
35 | this.image.onerror = () => status = 'error';
36 | this.image.src = '%s';
37 | }
38 | }`, src) }
39 | src={ src }
40 | alt={ alt }
41 | class={ twmerge.Merge(avatarBaseClass, classes) }
42 | { attrs... }
43 | x-cloak
44 | x-show="status === 'loaded'"
45 | />
46 | }
47 |
48 | templ AvatarFallback(classes string, attrs templ.Attributes) {
49 |
55 | { children... }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/ui/badge.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
4 |
5 | const (
6 | BadgeBaseClass = "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
7 | )
8 |
9 | type BadgeVariant int
10 |
11 | const (
12 | BadgeVariantDefault = iota
13 | BadgeVariantSecondary
14 | BadgeVariantDestructive
15 | BadgeVariantOutline
16 | )
17 |
18 | func (v BadgeVariant) Class() string {
19 | switch v {
20 | case BadgeVariantSecondary:
21 | return "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80"
22 | case BadgeVariantDestructive:
23 | return "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80"
24 | case BadgeVariantOutline:
25 | return "text-foreground"
26 | default:
27 | return "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80"
28 | }
29 | }
30 |
31 | templ Badge(variant BadgeVariant, classes string, attrs templ.Attributes) {
32 |
36 | { children... }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/ui/badge_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package ui
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
12 |
13 | const (
14 | BadgeBaseClass = "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
15 | )
16 |
17 | type BadgeVariant int
18 |
19 | const (
20 | BadgeVariantDefault = iota
21 | BadgeVariantSecondary
22 | BadgeVariantDestructive
23 | BadgeVariantOutline
24 | )
25 |
26 | func (v BadgeVariant) Class() string {
27 | switch v {
28 | case BadgeVariantSecondary:
29 | return "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80"
30 | case BadgeVariantDestructive:
31 | return "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80"
32 | case BadgeVariantOutline:
33 | return "text-foreground"
34 | default:
35 | return "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80"
36 | }
37 | }
38 |
39 | func Badge(variant BadgeVariant, classes string, attrs templ.Attributes) templ.Component {
40 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
41 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
42 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
43 | return templ_7745c5c3_CtxErr
44 | }
45 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
46 | if !templ_7745c5c3_IsBuffer {
47 | defer func() {
48 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
49 | if templ_7745c5c3_Err == nil {
50 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
51 | }
52 | }()
53 | }
54 | ctx = templ.InitializeContext(ctx)
55 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
56 | if templ_7745c5c3_Var1 == nil {
57 | templ_7745c5c3_Var1 = templ.NopComponent
58 | }
59 | ctx = templ.ClearChildren(ctx)
60 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(BadgeBaseClass, variant.Class(), classes)}
61 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
62 | if templ_7745c5c3_Err != nil {
63 | return templ_7745c5c3_Err
64 | }
65 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
87 | if templ_7745c5c3_Err != nil {
88 | return templ_7745c5c3_Err
89 | }
90 | templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
91 | if templ_7745c5c3_Err != nil {
92 | return templ_7745c5c3_Err
93 | }
94 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
95 | if templ_7745c5c3_Err != nil {
96 | return templ_7745c5c3_Err
97 | }
98 | return templ_7745c5c3_Err
99 | })
100 | }
101 |
102 | var _ = templruntime.GeneratedTemplate
103 |
--------------------------------------------------------------------------------
/ui/breadcrumb.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import (
4 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
5 | "github.com/rotemhoresh/shadcn-templ/icons"
6 | )
7 |
8 | const (
9 | breadcrumbListBaseClass = "flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5"
10 | breadcrumbItemBaseClass = "inline-flex items-center gap-1.5"
11 | breadcrumbSeparatorBaseClass = "[&>svg]:size-3.5"
12 | breadcrumbLinkBaseClass = "transition-colors hover:text-foreground"
13 | )
14 |
15 | templ Breadcrumb(classes string, attrs templ.Attributes) {
16 |
23 | }
24 |
25 | templ BreadcrumbList(classes string, attrs templ.Attributes) {
26 |
30 | { children... }
31 |
32 | }
33 |
34 | templ BreadcrumbItem(classes string, attrs templ.Attributes) {
35 |
39 | { children... }
40 |
41 | }
42 |
43 | templ BreadcrumbSeparator(classes string, attrs templ.Attributes) {
44 |
50 | @icons.ChevronRight(icons.Props{
51 | Class: "h-4 w-4",
52 | })
53 |
54 | }
55 |
56 | templ BreadcrumbLink(href templ.SafeURL, classes string, attrs templ.Attributes) {
57 |
62 | { children... }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/ui/button.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
4 |
5 | const buttonBaseClass = "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
6 |
7 | type ButtonType int
8 |
9 | const (
10 | ButtonTypeButton ButtonType = iota
11 | ButtonTypeSubmit
12 | ButtonTypeReset
13 | )
14 |
15 | func (t ButtonType) String() string {
16 | switch t {
17 | case ButtonTypeSubmit:
18 | return "submit"
19 | case ButtonTypeReset:
20 | return "reset"
21 | default:
22 | return "button"
23 | }
24 | }
25 |
26 | type ButtonVariant int
27 |
28 | const (
29 | ButtonVariantDefault ButtonVariant = iota
30 | ButtonVariantDestructive
31 | ButtonVariantSecondary
32 | ButtonVariantOutline
33 | ButtonVariantGhost
34 | ButtonVariantLink
35 | )
36 |
37 | func (v ButtonVariant) Class() string {
38 | switch v {
39 | case ButtonVariantDestructive:
40 | return "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90"
41 | case ButtonVariantSecondary:
42 | return "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80"
43 | case ButtonVariantOutline:
44 | return "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground"
45 | case ButtonVariantGhost:
46 | return "hover:bg-accent hover:text-accent-foreground"
47 | case ButtonVariantLink:
48 | return "text-primary underline-offset-4 hover:underline"
49 | default:
50 | return "bg-primary text-primary-foreground shadow hover:bg-primary/90"
51 | }
52 | }
53 |
54 | type ButtonSize int
55 |
56 | const (
57 | ButtonSizeDefault ButtonSize = iota
58 | ButtonSizeSmall
59 | ButtonSizeLarge
60 | ButtonSizeIcon
61 | )
62 |
63 | func (s ButtonSize) Class() string {
64 | switch s {
65 | case ButtonSizeSmall:
66 | return "h-8 rounded-md px-3 text-xs"
67 | case ButtonSizeLarge:
68 | return "h-10 rounded-md px-8"
69 | case ButtonSizeIcon:
70 | return "h-9 w-9"
71 | default:
72 | return "h-9 px-4 py-2"
73 | }
74 | }
75 |
76 | templ Button(buttonType ButtonType, variant ButtonVariant, size ButtonSize, classes string, attrs templ.Attributes) {
77 |
84 | }
85 |
--------------------------------------------------------------------------------
/ui/button/root.templ:
--------------------------------------------------------------------------------
1 | package button
2 |
3 | import (
4 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
5 | p "github.com/rotemhoresh/shadcn-templ/primitives"
6 | )
7 |
8 | const baseClass = "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
9 |
10 | type Type int
11 |
12 | const (
13 | TypeButton Type = iota
14 | TypeSubmit
15 | TypeReset
16 | )
17 |
18 | func (t Type) String() string {
19 | switch t {
20 | case TypeSubmit:
21 | return "submit"
22 | case TypeReset:
23 | return "reset"
24 | default:
25 | return "button"
26 | }
27 | }
28 |
29 | type Variant int
30 |
31 | const (
32 | VariantDefault Variant = iota
33 | VariantDestructive
34 | VariantSecondary
35 | VariantOutline
36 | VariantGhost
37 | VariantLink
38 | )
39 |
40 | func (v Variant) Class() string {
41 | switch v {
42 | case VariantDestructive:
43 | return "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90"
44 | case VariantSecondary:
45 | return "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80"
46 | case VariantOutline:
47 | return "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground"
48 | case VariantGhost:
49 | return "hover:bg-accent hover:text-accent-foreground"
50 | case VariantLink:
51 | return "text-primary underline-offset-4 hover:underline"
52 | default:
53 | return "bg-primary text-primary-foreground shadow hover:bg-primary/90"
54 | }
55 | }
56 |
57 | type Size int
58 |
59 | const (
60 | SizeDefault Size = iota
61 | SizeSmall
62 | SizeLarge
63 | SizeIcon
64 | )
65 |
66 | func (s Size) Class() string {
67 | switch s {
68 | case SizeSmall:
69 | return "h-8 rounded-md px-3 text-xs"
70 | case SizeLarge:
71 | return "h-10 rounded-md px-8"
72 | case SizeIcon:
73 | return "h-9 w-9"
74 | default:
75 | return "h-9 px-4 py-2"
76 | }
77 | }
78 |
79 | type RootProps struct {
80 | Type Type // default: [TypeButton]
81 | Variant Variant // default: [VariantDefault]
82 | Size Size // default: [SizeDefault]
83 | p.CoreProps
84 | }
85 |
86 | var props = RootProps{}
87 |
88 | templ Root(content string /* props RootProps */) {
89 |
97 | }
98 |
--------------------------------------------------------------------------------
/ui/button/root_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package button
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
13 | p "github.com/rotemhoresh/shadcn-templ/primitives"
14 | )
15 |
16 | const baseClass = "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
17 |
18 | type Type int
19 |
20 | const (
21 | TypeButton Type = iota
22 | TypeSubmit
23 | TypeReset
24 | )
25 |
26 | func (t Type) String() string {
27 | switch t {
28 | case TypeSubmit:
29 | return "submit"
30 | case TypeReset:
31 | return "reset"
32 | default:
33 | return "button"
34 | }
35 | }
36 |
37 | type Variant int
38 |
39 | const (
40 | VariantDefault Variant = iota
41 | VariantDestructive
42 | VariantSecondary
43 | VariantOutline
44 | VariantGhost
45 | VariantLink
46 | )
47 |
48 | func (v Variant) Class() string {
49 | switch v {
50 | case VariantDestructive:
51 | return "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90"
52 | case VariantSecondary:
53 | return "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80"
54 | case VariantOutline:
55 | return "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground"
56 | case VariantGhost:
57 | return "hover:bg-accent hover:text-accent-foreground"
58 | case VariantLink:
59 | return "text-primary underline-offset-4 hover:underline"
60 | default:
61 | return "bg-primary text-primary-foreground shadow hover:bg-primary/90"
62 | }
63 | }
64 |
65 | type Size int
66 |
67 | const (
68 | SizeDefault Size = iota
69 | SizeSmall
70 | SizeLarge
71 | SizeIcon
72 | )
73 |
74 | func (s Size) Class() string {
75 | switch s {
76 | case SizeSmall:
77 | return "h-8 rounded-md px-3 text-xs"
78 | case SizeLarge:
79 | return "h-10 rounded-md px-8"
80 | case SizeIcon:
81 | return "h-9 w-9"
82 | default:
83 | return "h-9 px-4 py-2"
84 | }
85 | }
86 |
87 | type RootProps struct {
88 | Type Type // default: [TypeButton]
89 | Variant Variant // default: [VariantDefault]
90 | Size Size // default: [SizeDefault]
91 | p.CoreProps
92 | }
93 |
94 | var props = RootProps{}
95 |
96 | func Root( /* props RootProps */ ) templ.Component {
97 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
98 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
99 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
100 | return templ_7745c5c3_CtxErr
101 | }
102 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
103 | if !templ_7745c5c3_IsBuffer {
104 | defer func() {
105 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
106 | if templ_7745c5c3_Err == nil {
107 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
108 | }
109 | }()
110 | }
111 | ctx = templ.InitializeContext(ctx)
112 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
113 | if templ_7745c5c3_Var1 == nil {
114 | templ_7745c5c3_Var1 = templ.NopComponent
115 | }
116 | ctx = templ.ClearChildren(ctx)
117 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(baseClass, props.Variant.Class(), props.Size.Class(), props.Class)}
118 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
119 | if templ_7745c5c3_Err != nil {
120 | return templ_7745c5c3_Err
121 | }
122 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
165 | if templ_7745c5c3_Err != nil {
166 | return templ_7745c5c3_Err
167 | }
168 | return templ_7745c5c3_Err
169 | })
170 | }
171 |
172 | var _ = templruntime.GeneratedTemplate
173 |
--------------------------------------------------------------------------------
/ui/button_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package ui
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
12 |
13 | const buttonBaseClass = "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
14 |
15 | type ButtonType int
16 |
17 | const (
18 | ButtonTypeButton ButtonType = iota
19 | ButtonTypeSubmit
20 | ButtonTypeReset
21 | )
22 |
23 | func (t ButtonType) String() string {
24 | switch t {
25 | case ButtonTypeSubmit:
26 | return "submit"
27 | case ButtonTypeReset:
28 | return "reset"
29 | default:
30 | return "button"
31 | }
32 | }
33 |
34 | type ButtonVariant int
35 |
36 | const (
37 | ButtonVariantDefault ButtonVariant = iota
38 | ButtonVariantDestructive
39 | ButtonVariantSecondary
40 | ButtonVariantOutline
41 | ButtonVariantGhost
42 | ButtonVariantLink
43 | )
44 |
45 | func (v ButtonVariant) Class() string {
46 | switch v {
47 | case ButtonVariantDestructive:
48 | return "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90"
49 | case ButtonVariantSecondary:
50 | return "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80"
51 | case ButtonVariantOutline:
52 | return "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground"
53 | case ButtonVariantGhost:
54 | return "hover:bg-accent hover:text-accent-foreground"
55 | case ButtonVariantLink:
56 | return "text-primary underline-offset-4 hover:underline"
57 | default:
58 | return "bg-primary text-primary-foreground shadow hover:bg-primary/90"
59 | }
60 | }
61 |
62 | type ButtonSize int
63 |
64 | const (
65 | ButtonSizeDefault ButtonSize = iota
66 | ButtonSizeSmall
67 | ButtonSizeLarge
68 | ButtonSizeIcon
69 | )
70 |
71 | func (s ButtonSize) Class() string {
72 | switch s {
73 | case ButtonSizeSmall:
74 | return "h-8 rounded-md px-3 text-xs"
75 | case ButtonSizeLarge:
76 | return "h-10 rounded-md px-8"
77 | case ButtonSizeIcon:
78 | return "h-9 w-9"
79 | default:
80 | return "h-9 px-4 py-2"
81 | }
82 | }
83 |
84 | func Button(buttonType ButtonType, variant ButtonVariant, size ButtonSize, classes string, attrs templ.Attributes) templ.Component {
85 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
86 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
87 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
88 | return templ_7745c5c3_CtxErr
89 | }
90 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
91 | if !templ_7745c5c3_IsBuffer {
92 | defer func() {
93 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
94 | if templ_7745c5c3_Err == nil {
95 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
96 | }
97 | }()
98 | }
99 | ctx = templ.InitializeContext(ctx)
100 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
101 | if templ_7745c5c3_Var1 == nil {
102 | templ_7745c5c3_Var1 = templ.NopComponent
103 | }
104 | ctx = templ.ClearChildren(ctx)
105 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(buttonBaseClass, variant.Class(), size.Class(), classes)}
106 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
107 | if templ_7745c5c3_Err != nil {
108 | return templ_7745c5c3_Err
109 | }
110 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
153 | if templ_7745c5c3_Err != nil {
154 | return templ_7745c5c3_Err
155 | }
156 | return templ_7745c5c3_Err
157 | })
158 | }
159 |
160 | var _ = templruntime.GeneratedTemplate
161 |
--------------------------------------------------------------------------------
/ui/card.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import "github.com/Oudwins/tailwind-merge-go"
4 |
5 | const (
6 | cardBaseClass = "rounded-xl border bg-card text-card-foreground shadow"
7 | cardHeaderBaseClass = "flex flex-col space-y-1.5 p-6"
8 | cardTitleBaseClass = "font-semibold leading-none tracking-tight"
9 | cardDescriptionBaseClass = "text-sm text-muted-foreground"
10 | cardContentBaseClass = "p-6 pt-0"
11 | cardFooterBaseClass = "flex items-center p-6 pt-0"
12 | )
13 |
14 | templ Card(classes string, attrs templ.Attributes) {
15 |
19 | { children... }
20 |
21 | }
22 |
23 | templ CardHeader(classes string, attrs templ.Attributes) {
24 |
28 | { children... }
29 |
30 | }
31 |
32 | templ CardTitle(classes string, attrs templ.Attributes) {
33 |
37 | { children... }
38 |
39 | }
40 |
41 | templ CardDescription(classes string, attrs templ.Attributes) {
42 |
46 | { children... }
47 |
48 | }
49 |
50 | templ CardContent(classes string, attrs templ.Attributes) {
51 |
55 | { children... }
56 |
57 | }
58 |
59 | templ CardFooter(classes string, attrs templ.Attributes) {
60 |
64 | { children... }
65 |
66 | }
--------------------------------------------------------------------------------
/ui/checkbox.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import (
4 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
5 | "github.com/rotemhoresh/shadcn-templ/icons"
6 | )
7 |
8 | const (
9 | checkboxBaseClass = "peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground"
10 | )
11 |
12 | // `attrs` will go to the inner input
13 | templ Checkbox(name, classes string, attrs templ.Attributes) {
14 |
54 | }
55 |
--------------------------------------------------------------------------------
/ui/checkbox_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package ui
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
13 | "github.com/rotemhoresh/shadcn-templ/icons"
14 | )
15 |
16 | const (
17 | checkboxBaseClass = "peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground"
18 | )
19 |
20 | // `attrs` will go to the inner input
21 | func Checkbox(name, classes string, attrs templ.Attributes) templ.Component {
22 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
23 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
24 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
25 | return templ_7745c5c3_CtxErr
26 | }
27 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
28 | if !templ_7745c5c3_IsBuffer {
29 | defer func() {
30 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
31 | if templ_7745c5c3_Err == nil {
32 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
33 | }
34 | }()
35 | }
36 | ctx = templ.InitializeContext(ctx)
37 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
38 | if templ_7745c5c3_Var1 == nil {
39 | templ_7745c5c3_Var1 = templ.NopComponent
40 | }
41 | ctx = templ.ClearChildren(ctx)
42 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(checkboxBaseClass, classes)}
43 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
44 | if templ_7745c5c3_Err != nil {
45 | return templ_7745c5c3_Err
46 | }
47 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
122 | if templ_7745c5c3_Err != nil {
123 | return templ_7745c5c3_Err
124 | }
125 | return templ_7745c5c3_Err
126 | })
127 | }
128 |
129 | var _ = templruntime.GeneratedTemplate
130 |
--------------------------------------------------------------------------------
/ui/collapsible.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import (
4 | "fmt"
5 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
6 | )
7 |
8 | templ Collapsible(defaultOpen bool, classes string, attrs templ.Attributes) {
9 |
16 | { children... }
17 |
18 | }
19 |
20 | // There is no element for collapsible trigger, just add these attributes to your component.
21 | var CollapsibleTriggerAttrs = templ.Attributes{
22 | "x-data": true,
23 | "x-on:click": "shadcntempl_open = ! shadcntempl_open",
24 | ":aria-expanded": "shadcntempl_open",
25 | ":data-state": "shadcntempl_open ? 'open' : 'closed'",
26 | ":data-disabled": "shadcntempl_disabled",
27 | }
28 |
29 | templ CollapsibleContent(classes string, attrs templ.Attributes) {
30 |
38 | { children... }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/ui/collapsible_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package ui
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "fmt"
13 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
14 | )
15 |
16 | func Collapsible(defaultOpen bool, classes string, attrs templ.Attributes) templ.Component {
17 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
18 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
19 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
20 | return templ_7745c5c3_CtxErr
21 | }
22 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
23 | if !templ_7745c5c3_IsBuffer {
24 | defer func() {
25 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
26 | if templ_7745c5c3_Err == nil {
27 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
28 | }
29 | }()
30 | }
31 | ctx = templ.InitializeContext(ctx)
32 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
33 | if templ_7745c5c3_Var1 == nil {
34 | templ_7745c5c3_Var1 = templ.NopComponent
35 | }
36 | ctx = templ.ClearChildren(ctx)
37 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(classes)}
38 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
39 | if templ_7745c5c3_Err != nil {
40 | return templ_7745c5c3_Err
41 | }
42 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
77 | if templ_7745c5c3_Err != nil {
78 | return templ_7745c5c3_Err
79 | }
80 | templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
81 | if templ_7745c5c3_Err != nil {
82 | return templ_7745c5c3_Err
83 | }
84 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
85 | if templ_7745c5c3_Err != nil {
86 | return templ_7745c5c3_Err
87 | }
88 | return templ_7745c5c3_Err
89 | })
90 | }
91 |
92 | // There is no element for collapsible trigger, just add these attributes to your component.
93 | var CollapsibleTriggerAttrs = templ.Attributes{
94 | "x-data": true,
95 | "x-on:click": "shadcntempl_open = ! shadcntempl_open",
96 | ":aria-expanded": "shadcntempl_open",
97 | ":data-state": "shadcntempl_open ? 'open' : 'closed'",
98 | ":data-disabled": "shadcntempl_disabled",
99 | }
100 |
101 | func CollapsibleContent(classes string, attrs templ.Attributes) templ.Component {
102 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
103 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
104 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
105 | return templ_7745c5c3_CtxErr
106 | }
107 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
108 | if !templ_7745c5c3_IsBuffer {
109 | defer func() {
110 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
111 | if templ_7745c5c3_Err == nil {
112 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
113 | }
114 | }()
115 | }
116 | ctx = templ.InitializeContext(ctx)
117 | templ_7745c5c3_Var5 := templ.GetChildren(ctx)
118 | if templ_7745c5c3_Var5 == nil {
119 | templ_7745c5c3_Var5 = templ.NopComponent
120 | }
121 | ctx = templ.ClearChildren(ctx)
122 | var templ_7745c5c3_Var6 = []any{twmerge.Merge(classes)}
123 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
124 | if templ_7745c5c3_Err != nil {
125 | return templ_7745c5c3_Err
126 | }
127 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
149 | if templ_7745c5c3_Err != nil {
150 | return templ_7745c5c3_Err
151 | }
152 | templ_7745c5c3_Err = templ_7745c5c3_Var5.Render(ctx, templ_7745c5c3_Buffer)
153 | if templ_7745c5c3_Err != nil {
154 | return templ_7745c5c3_Err
155 | }
156 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
157 | if templ_7745c5c3_Err != nil {
158 | return templ_7745c5c3_Err
159 | }
160 | return templ_7745c5c3_Err
161 | })
162 | }
163 |
164 | var _ = templruntime.GeneratedTemplate
165 |
--------------------------------------------------------------------------------
/ui/dialog.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import (
4 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
5 | "github.com/rotemhoresh/shadcn-templ/icons"
6 | )
7 |
8 | const (
9 | dialogContentBaseClass = "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg fill-mode-forwards"
10 | dialogCloseBaseClass = "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none"
11 | dialogOverlayBaseClass = "fixed inset-0 z-50 bg-black/80 fill-mode-forwards"
12 | dialogHeaderBaseClass = "flex flex-col space-y-1.5 text-center sm:text-left"
13 | dialogFooterBaseClass = "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2"
14 | dialogTitleBaseClass = "text-lg font-semibold leading-none tracking-tight"
15 | dialogDescriptionBaseClass = "text-sm text-muted-foreground"
16 | )
17 |
18 | templ Dialog(classes string, attrs templ.Attributes) {
19 |
24 | { children... }
25 |
26 | }
27 |
28 | // There is no element for dialog trigger, just add these attributes to your component.
29 | var DialogTriggerAttrs = templ.Attributes{
30 | "aria-haspopup": "dialog",
31 | ":aria-expanded": "shadcntempl_open",
32 | "x-data": true,
33 | "x-on:click": "shadcntempl_open = true",
34 | }
35 |
36 | templ DialogContent(classes string, attrs templ.Attributes) {
37 |
45 |
58 | { children... }
59 |
69 |
70 | }
71 |
72 | // If you want to add a custom close, add this attributes to your component
73 | var DialogCloseAttrs = templ.Attributes{
74 | "x-on:click": "shadcntempl_open = false",
75 | }
76 |
77 | templ DialogHeader(classes string, attrs templ.Attributes) {
78 |
82 | { children... }
83 |
84 | }
85 |
86 | templ DialogFooter(classes string, attrs templ.Attributes) {
87 |
91 | { children... }
92 |
93 | }
94 |
95 | templ DialogTitle(classes string, attrs templ.Attributes) {
96 |
100 | { children... }
101 |
102 | }
103 |
104 | templ DialogDescription(classes string, attrs templ.Attributes) {
105 |
109 | { children... }
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/ui/dialog/close.go:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import "github.com/rotemhoresh/shadcn-templ/primitives/dialog"
4 |
5 | var Close = dialog.Close
6 |
--------------------------------------------------------------------------------
/ui/dialog/content.templ:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import (
4 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
5 | "github.com/rotemhoresh/shadcn-templ/icons"
6 | "github.com/rotemhoresh/shadcn-templ/primitives/dialog"
7 | "github.com/rotemhoresh/shadcn-templ/primitives/portal"
8 | )
9 |
10 | const (
11 | contentClass = "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg fill-mode-forwards"
12 | closeClass = "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none"
13 | )
14 |
15 | type ContentProps = dialog.ContentProps
16 |
17 | func Content(props ContentProps) templ.Component {
18 | props.Class = twmerge.Merge(contentClass, props.Class)
19 | props.AddAttr("x-transition:enter", "animate-in fade-in-0 zoom-in-95 slide-in-from-top-[48%] slide-in-from-left-1/2")
20 | props.AddAttr("x-transition:leave", "animate-out fade-out-0 zoom-out-95 slide-out-to-top-[48%] slide-out-to-left-1/2")
21 | return content(props)
22 | }
23 |
24 | templ content(props ContentProps) {
25 | @portal.Root(portal.RootProps{}) {
26 | @Overlay(OverlayProps{})
27 | }
28 | @portal.Root(portal.RootProps{}) {
29 | @dialog.Content(props) {
30 | { children... }
31 |
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/ui/dialog/content_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package dialog
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
13 | "github.com/rotemhoresh/shadcn-templ/icons"
14 | "github.com/rotemhoresh/shadcn-templ/primitives/dialog"
15 | "github.com/rotemhoresh/shadcn-templ/primitives/portal"
16 | )
17 |
18 | const (
19 | contentClass = "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg fill-mode-forwards"
20 | closeClass = "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none"
21 | )
22 |
23 | type ContentProps = dialog.ContentProps
24 |
25 | func Content(props ContentProps) templ.Component {
26 | props.Class = twmerge.Merge(contentClass, props.Class)
27 | props.AddAttr("x-transition:enter", "animate-in fade-in-0 zoom-in-95 slide-in-from-top-[48%] slide-in-from-left-1/2")
28 | props.AddAttr("x-transition:leave", "animate-out fade-out-0 zoom-out-95 slide-out-to-top-[48%] slide-out-to-left-1/2")
29 | return content(props)
30 | }
31 |
32 | func content(props ContentProps) templ.Component {
33 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
34 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
35 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
36 | return templ_7745c5c3_CtxErr
37 | }
38 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
39 | if !templ_7745c5c3_IsBuffer {
40 | defer func() {
41 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
42 | if templ_7745c5c3_Err == nil {
43 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
44 | }
45 | }()
46 | }
47 | ctx = templ.InitializeContext(ctx)
48 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
49 | if templ_7745c5c3_Var1 == nil {
50 | templ_7745c5c3_Var1 = templ.NopComponent
51 | }
52 | ctx = templ.ClearChildren(ctx)
53 | templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
54 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
55 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
56 | if !templ_7745c5c3_IsBuffer {
57 | defer func() {
58 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
59 | if templ_7745c5c3_Err == nil {
60 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
61 | }
62 | }()
63 | }
64 | ctx = templ.InitializeContext(ctx)
65 | templ_7745c5c3_Err = Overlay(OverlayProps{}).Render(ctx, templ_7745c5c3_Buffer)
66 | if templ_7745c5c3_Err != nil {
67 | return templ_7745c5c3_Err
68 | }
69 | return templ_7745c5c3_Err
70 | })
71 | templ_7745c5c3_Err = portal.Root(portal.RootProps{}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
72 | if templ_7745c5c3_Err != nil {
73 | return templ_7745c5c3_Err
74 | }
75 | templ_7745c5c3_Var3 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
76 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
77 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
78 | if !templ_7745c5c3_IsBuffer {
79 | defer func() {
80 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
81 | if templ_7745c5c3_Err == nil {
82 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
83 | }
84 | }()
85 | }
86 | ctx = templ.InitializeContext(ctx)
87 | templ_7745c5c3_Var4 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
88 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
89 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
90 | if !templ_7745c5c3_IsBuffer {
91 | defer func() {
92 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
93 | if templ_7745c5c3_Err == nil {
94 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
95 | }
96 | }()
97 | }
98 | ctx = templ.InitializeContext(ctx)
99 | templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
100 | if templ_7745c5c3_Err != nil {
101 | return templ_7745c5c3_Err
102 | }
103 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
104 | if templ_7745c5c3_Err != nil {
105 | return templ_7745c5c3_Err
106 | }
107 | var templ_7745c5c3_Var5 = []any{closeClass}
108 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
109 | if templ_7745c5c3_Err != nil {
110 | return templ_7745c5c3_Err
111 | }
112 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
144 | if templ_7745c5c3_Err != nil {
145 | return templ_7745c5c3_Err
146 | }
147 | return templ_7745c5c3_Err
148 | })
149 | templ_7745c5c3_Err = dialog.Content(props).Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer)
150 | if templ_7745c5c3_Err != nil {
151 | return templ_7745c5c3_Err
152 | }
153 | return templ_7745c5c3_Err
154 | })
155 | templ_7745c5c3_Err = portal.Root(portal.RootProps{}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
156 | if templ_7745c5c3_Err != nil {
157 | return templ_7745c5c3_Err
158 | }
159 | return templ_7745c5c3_Err
160 | })
161 | }
162 |
163 | var _ = templruntime.GeneratedTemplate
164 |
--------------------------------------------------------------------------------
/ui/dialog/description.templ:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import (
4 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
5 | "github.com/rotemhoresh/shadcn-templ/primitives/dialog"
6 | )
7 |
8 | const descriptionClass = "text-sm text-muted-foreground"
9 |
10 | type DescriptionProps = dialog.DescriptionProps
11 |
12 | func Description(props DescriptionProps) templ.Component {
13 | props.Class = twmerge.Merge(descriptionClass, props.Class)
14 | return dialog.Description(props)
15 | }
16 |
--------------------------------------------------------------------------------
/ui/dialog/description_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package dialog
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
13 | "github.com/rotemhoresh/shadcn-templ/primitives/dialog"
14 | )
15 |
16 | const descriptionClass = "text-sm text-muted-foreground"
17 |
18 | type DescriptionProps = dialog.DescriptionProps
19 |
20 | func Description(props DescriptionProps) templ.Component {
21 | props.Class = twmerge.Merge(descriptionClass, props.Class)
22 | return dialog.Description(props)
23 | }
24 |
25 | var _ = templruntime.GeneratedTemplate
26 |
--------------------------------------------------------------------------------
/ui/dialog/footer.templ:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import (
4 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
5 | p "github.com/rotemhoresh/shadcn-templ/primitives"
6 | )
7 |
8 | const footerClass = "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2"
9 |
10 | type FooterProps struct {
11 | p.CoreProps
12 | }
13 |
14 | templ Footer(props FooterProps) {
15 |
19 | { children... }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/ui/dialog/footer_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package dialog
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
13 | p "github.com/rotemhoresh/shadcn-templ/primitives"
14 | )
15 |
16 | const footerClass = "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2"
17 |
18 | type FooterProps struct {
19 | p.CoreProps
20 | }
21 |
22 | func Footer(props FooterProps) templ.Component {
23 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
24 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
25 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
26 | return templ_7745c5c3_CtxErr
27 | }
28 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
29 | if !templ_7745c5c3_IsBuffer {
30 | defer func() {
31 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
32 | if templ_7745c5c3_Err == nil {
33 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
34 | }
35 | }()
36 | }
37 | ctx = templ.InitializeContext(ctx)
38 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
39 | if templ_7745c5c3_Var1 == nil {
40 | templ_7745c5c3_Var1 = templ.NopComponent
41 | }
42 | ctx = templ.ClearChildren(ctx)
43 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(footerClass, props.Class)}
44 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
45 | if templ_7745c5c3_Err != nil {
46 | return templ_7745c5c3_Err
47 | }
48 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
70 | if templ_7745c5c3_Err != nil {
71 | return templ_7745c5c3_Err
72 | }
73 | templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
74 | if templ_7745c5c3_Err != nil {
75 | return templ_7745c5c3_Err
76 | }
77 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
78 | if templ_7745c5c3_Err != nil {
79 | return templ_7745c5c3_Err
80 | }
81 | return templ_7745c5c3_Err
82 | })
83 | }
84 |
85 | var _ = templruntime.GeneratedTemplate
86 |
--------------------------------------------------------------------------------
/ui/dialog/header.templ:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import (
4 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
5 | p "github.com/rotemhoresh/shadcn-templ/primitives"
6 | )
7 |
8 | const headerClass = "flex flex-col space-y-1.5 text-center sm:text-left"
9 |
10 | type HeaderProps struct {
11 | p.CoreProps
12 | }
13 |
14 | templ Header(props HeaderProps) {
15 |
19 | { children... }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/ui/dialog/header_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package dialog
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
13 | p "github.com/rotemhoresh/shadcn-templ/primitives"
14 | )
15 |
16 | const headerClass = "flex flex-col space-y-1.5 text-center sm:text-left"
17 |
18 | type HeaderProps struct {
19 | p.CoreProps
20 | }
21 |
22 | func Header(props HeaderProps) templ.Component {
23 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
24 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
25 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
26 | return templ_7745c5c3_CtxErr
27 | }
28 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
29 | if !templ_7745c5c3_IsBuffer {
30 | defer func() {
31 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
32 | if templ_7745c5c3_Err == nil {
33 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
34 | }
35 | }()
36 | }
37 | ctx = templ.InitializeContext(ctx)
38 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
39 | if templ_7745c5c3_Var1 == nil {
40 | templ_7745c5c3_Var1 = templ.NopComponent
41 | }
42 | ctx = templ.ClearChildren(ctx)
43 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(headerClass, props.Class)}
44 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
45 | if templ_7745c5c3_Err != nil {
46 | return templ_7745c5c3_Err
47 | }
48 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
70 | if templ_7745c5c3_Err != nil {
71 | return templ_7745c5c3_Err
72 | }
73 | templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
74 | if templ_7745c5c3_Err != nil {
75 | return templ_7745c5c3_Err
76 | }
77 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
78 | if templ_7745c5c3_Err != nil {
79 | return templ_7745c5c3_Err
80 | }
81 | return templ_7745c5c3_Err
82 | })
83 | }
84 |
85 | var _ = templruntime.GeneratedTemplate
86 |
--------------------------------------------------------------------------------
/ui/dialog/overlay.templ:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import (
4 | twmerge "github.com/Oudwins/tailwind-merge-go"
5 | "github.com/rotemhoresh/shadcn-templ/primitives/dialog"
6 | )
7 |
8 | const overlayClass = "fixed inset-0 z-50 bg-black/80 fill-mode-forwards"
9 |
10 | type OverlayProps = dialog.OverlayProps
11 |
12 | func Overlay(props OverlayProps) templ.Component {
13 | props.Class = twmerge.Merge(overlayClass, props.Class)
14 | props.AddAttr("x-transition:enter", "animate-in fade-in-0")
15 | props.AddAttr("x-transition:leave", "animate-out fade-out-0")
16 | return dialog.Overlay(props)
17 | }
18 |
--------------------------------------------------------------------------------
/ui/dialog/overlay_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package dialog
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | twmerge "github.com/Oudwins/tailwind-merge-go"
13 | "github.com/rotemhoresh/shadcn-templ/primitives/dialog"
14 | )
15 |
16 | const overlayClass = "fixed inset-0 z-50 bg-black/80 fill-mode-forwards"
17 |
18 | type OverlayProps = dialog.OverlayProps
19 |
20 | func Overlay(props OverlayProps) templ.Component {
21 | props.Class = twmerge.Merge(overlayClass, props.Class)
22 | props.AddAttr("x-transition:enter", "animate-in fade-in-0")
23 | props.AddAttr("x-transition:leave", "animate-out fade-out-0")
24 | return dialog.Overlay(props)
25 | }
26 |
27 | var _ = templruntime.GeneratedTemplate
28 |
--------------------------------------------------------------------------------
/ui/dialog/root.go:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import "github.com/rotemhoresh/shadcn-templ/primitives/dialog"
4 |
5 | type RootProps = dialog.RootProps
6 |
7 | var Root = dialog.Root
8 |
--------------------------------------------------------------------------------
/ui/dialog/title.templ:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import (
4 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
5 | "github.com/rotemhoresh/shadcn-templ/primitives/dialog"
6 | )
7 |
8 | const titleClass = "text-lg font-semibold leading-none tracking-tight"
9 |
10 | type TitleProps = dialog.TitleProps
11 |
12 | func Title(props TitleProps) templ.Component {
13 | props.Class = twmerge.Merge(titleClass, props.Class)
14 | return dialog.Title(props)
15 | }
16 |
--------------------------------------------------------------------------------
/ui/dialog/title_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package dialog
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
13 | "github.com/rotemhoresh/shadcn-templ/primitives/dialog"
14 | )
15 |
16 | const titleClass = "text-lg font-semibold leading-none tracking-tight"
17 |
18 | type TitleProps = dialog.TitleProps
19 |
20 | func Title(props TitleProps) templ.Component {
21 | props.Class = twmerge.Merge(titleClass, props.Class)
22 | return dialog.Title(props)
23 | }
24 |
25 | var _ = templruntime.GeneratedTemplate
26 |
--------------------------------------------------------------------------------
/ui/dialog/trigger.go:
--------------------------------------------------------------------------------
1 | package dialog
2 |
3 | import "github.com/rotemhoresh/shadcn-templ/primitives/dialog"
4 |
5 | var Trigger = dialog.Trigger
6 |
--------------------------------------------------------------------------------
/ui/dropdown-menu.templ:
--------------------------------------------------------------------------------
1 | package ui;
2 |
3 | import twmerge "github.com/Oudwins/tailwind-merge-go"
4 |
5 | // TODO: add side alignment options
6 |
7 | type DropdownMenuAlign int
8 |
9 | func (a DropdownMenuAlign) Class() string {
10 | switch a {
11 | case DropdownMenuAlignLeft:
12 | return "left-0"
13 | case DropdownMenuAlignRight:
14 | return "right-0"
15 | default:
16 | return "left-1/2 -translate-x-1/2"
17 | }
18 | }
19 |
20 | const (
21 | DropdownMenuAlignCenter DropdownMenuAlign = iota
22 | DropdownMenuAlignLeft
23 | DropdownMenuAlignRight
24 | )
25 |
26 | const (
27 | dropdownMenuContentBaseClass = "absolute botton-full mt-2 z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none"
28 | dropdownMenuItemBaseClass = "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground"
29 | dropdownMenuSeparatorBaseClass = "-mx-1 my-1 h-px bg-muted"
30 | dropdownMenuShortcutBaseClass = "ml-auto text-xs tracking-widest opacity-60"
31 | dropdownMenuLabelBaseClass = "px-2 py-1.5 text-sm font-semibold"
32 | )
33 |
34 | templ DropdownMenu(classes string, attrs templ.Attributes) {
35 |
41 | { children... }
42 |
43 | }
44 |
45 | // There is no element for dropdown menu trigger, just add these attributes to your component.
46 | var DropdownMenuTriggerAttrs = templ.Attributes{
47 | "x-on:mousedown": "open = true",
48 | "aria-haspopup": "menu",
49 | ":aria-expanded": "open",
50 | "x-data": true,
51 | "x-on:keydown.enter.prevent": "open = true",
52 | "x-on:keydown.space.prevent": "open = true",
53 | "x-on:keydown.down.prevent": "open = true",
54 | }
55 |
56 | templ DropdownMenuContent(align DropdownMenuAlign, classes string, attrs templ.Attributes) {
57 |
69 | { children... }
70 |
71 | }
72 |
73 | templ DropdownMenuItem(classes string, attrs templ.Attributes) {
74 |
82 | { children... }
83 |
84 | }
85 |
86 | templ DropdownMenuSeparator(classes string, attrs templ.Attributes) {
87 |
91 | }
92 |
93 | templ DropdownMenuShortcut(classes string, attrs templ.Attributes) {
94 |
98 | { children... }
99 |
100 | }
101 |
102 | templ DropdownMenuLabel(classes string, attrs templ.Attributes) {
103 |
107 | { children... }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/ui/field.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
4 |
5 | const (
6 | fieldDescriptionBaseClass = "text-[0.8rem] text-muted-foreground"
7 | fieldErrorBaseClass = "text-[0.8rem] font-medium text-destructive"
8 | fieldBaseClass = "space-y-2"
9 | )
10 |
11 | templ FieldDescription(classes string, attrs templ.Attributes) {
12 |
16 | { children... }
17 |
18 | }
19 |
20 | // `id` is for [hx-swap-oob], if not needed, set it to an empty string (i.e., "")
21 | //
22 | // [hx-swap-oob]: https://htmx.org/attributes/hx-swap-oob
23 | templ FieldError(id, classes string, attrs templ.Attributes) {
24 |
33 | { children... }
34 |
35 | }
36 |
37 | templ Field(classes string, attrs templ.Attributes) {
38 |
42 | { children... }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/ui/field_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package ui
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
12 |
13 | const (
14 | fieldDescriptionBaseClass = "text-[0.8rem] text-muted-foreground"
15 | fieldErrorBaseClass = "text-[0.8rem] font-medium text-destructive"
16 | fieldBaseClass = "space-y-2"
17 | )
18 |
19 | func FieldDescription(classes string, attrs templ.Attributes) templ.Component {
20 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
21 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
22 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
23 | return templ_7745c5c3_CtxErr
24 | }
25 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
26 | if !templ_7745c5c3_IsBuffer {
27 | defer func() {
28 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
29 | if templ_7745c5c3_Err == nil {
30 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
31 | }
32 | }()
33 | }
34 | ctx = templ.InitializeContext(ctx)
35 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
36 | if templ_7745c5c3_Var1 == nil {
37 | templ_7745c5c3_Var1 = templ.NopComponent
38 | }
39 | ctx = templ.ClearChildren(ctx)
40 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(fieldDescriptionBaseClass, classes)}
41 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
42 | if templ_7745c5c3_Err != nil {
43 | return templ_7745c5c3_Err
44 | }
45 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
67 | if templ_7745c5c3_Err != nil {
68 | return templ_7745c5c3_Err
69 | }
70 | templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
71 | if templ_7745c5c3_Err != nil {
72 | return templ_7745c5c3_Err
73 | }
74 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
75 | if templ_7745c5c3_Err != nil {
76 | return templ_7745c5c3_Err
77 | }
78 | return templ_7745c5c3_Err
79 | })
80 | }
81 |
82 | // `id` is for [hx-swap-oob], if not needed, set it to an empty string (i.e., "")
83 | //
84 | // [hx-swap-oob]: https://htmx.org/attributes/hx-swap-oob
85 | func FieldError(id, classes string, attrs templ.Attributes) templ.Component {
86 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
87 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
88 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
89 | return templ_7745c5c3_CtxErr
90 | }
91 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
92 | if !templ_7745c5c3_IsBuffer {
93 | defer func() {
94 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
95 | if templ_7745c5c3_Err == nil {
96 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
97 | }
98 | }()
99 | }
100 | ctx = templ.InitializeContext(ctx)
101 | templ_7745c5c3_Var4 := templ.GetChildren(ctx)
102 | if templ_7745c5c3_Var4 == nil {
103 | templ_7745c5c3_Var4 = templ.NopComponent
104 | }
105 | ctx = templ.ClearChildren(ctx)
106 | var templ_7745c5c3_Var5 = []any{twmerge.Merge(fieldErrorBaseClass, classes)}
107 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
108 | if templ_7745c5c3_Err != nil {
109 | return templ_7745c5c3_Err
110 | }
111 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
152 | if templ_7745c5c3_Err != nil {
153 | return templ_7745c5c3_Err
154 | }
155 | templ_7745c5c3_Err = templ_7745c5c3_Var4.Render(ctx, templ_7745c5c3_Buffer)
156 | if templ_7745c5c3_Err != nil {
157 | return templ_7745c5c3_Err
158 | }
159 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
160 | if templ_7745c5c3_Err != nil {
161 | return templ_7745c5c3_Err
162 | }
163 | return templ_7745c5c3_Err
164 | })
165 | }
166 |
167 | func Field(classes string, attrs templ.Attributes) templ.Component {
168 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
169 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
170 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
171 | return templ_7745c5c3_CtxErr
172 | }
173 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
174 | if !templ_7745c5c3_IsBuffer {
175 | defer func() {
176 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
177 | if templ_7745c5c3_Err == nil {
178 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
179 | }
180 | }()
181 | }
182 | ctx = templ.InitializeContext(ctx)
183 | templ_7745c5c3_Var8 := templ.GetChildren(ctx)
184 | if templ_7745c5c3_Var8 == nil {
185 | templ_7745c5c3_Var8 = templ.NopComponent
186 | }
187 | ctx = templ.ClearChildren(ctx)
188 | var templ_7745c5c3_Var9 = []any{twmerge.Merge(fieldBaseClass, classes)}
189 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
190 | if templ_7745c5c3_Err != nil {
191 | return templ_7745c5c3_Err
192 | }
193 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
215 | if templ_7745c5c3_Err != nil {
216 | return templ_7745c5c3_Err
217 | }
218 | templ_7745c5c3_Err = templ_7745c5c3_Var8.Render(ctx, templ_7745c5c3_Buffer)
219 | if templ_7745c5c3_Err != nil {
220 | return templ_7745c5c3_Err
221 | }
222 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
223 | if templ_7745c5c3_Err != nil {
224 | return templ_7745c5c3_Err
225 | }
226 | return templ_7745c5c3_Err
227 | })
228 | }
229 |
230 | var _ = templruntime.GeneratedTemplate
231 |
--------------------------------------------------------------------------------
/ui/input.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
4 |
5 | const (
6 | inputBaseClass = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
7 | )
8 |
9 | type InputType int
10 |
11 | const (
12 | InputTypeText InputType = iota
13 | InputTypeEmail
14 | InputTypePassword
15 | InputTypeSearch
16 | InputTypeUrl
17 | InputTypeTel
18 | InputTypeDate
19 | InputTypeDatetimeLocal
20 | InputTypeNumber
21 | InputTypeButton
22 | InputTypeFile
23 | InputTypeHidden
24 | InputTypeImage
25 | InputTypeMonth
26 | InputTypeWeek
27 | InputTypeCheckbox
28 | InputTypeColor
29 | InputTypeRadio
30 | InputTypeRange
31 | InputTypeReset
32 | InputTypeSubmit
33 | InputTypeTime
34 | )
35 |
36 | func (t InputType) String() string {
37 | switch t {
38 | case InputTypeEmail:
39 | return "email"
40 | case InputTypePassword:
41 | return "password"
42 | case InputTypeSearch:
43 | return "search"
44 | case InputTypeUrl:
45 | return "url"
46 | case InputTypeTel:
47 | return "tel"
48 | case InputTypeDate:
49 | return "date"
50 | case InputTypeDatetimeLocal:
51 | return "datetime-local"
52 | case InputTypeNumber:
53 | return "number"
54 | case InputTypeButton:
55 | return "button"
56 | case InputTypeFile:
57 | return "file"
58 | case InputTypeHidden:
59 | return "hidden"
60 | case InputTypeImage:
61 | return "image"
62 | case InputTypeMonth:
63 | return "month"
64 | case InputTypeWeek:
65 | return "week"
66 | case InputTypeCheckbox:
67 | return "checkbox"
68 | case InputTypeColor:
69 | return "color"
70 | case InputTypeRadio:
71 | return "radio"
72 | case InputTypeRange:
73 | return "range"
74 | case InputTypeReset:
75 | return "reset"
76 | case InputTypeSubmit:
77 | return "submit"
78 | case InputTypeTime:
79 | return "time"
80 | default:
81 | return "text"
82 | }
83 | }
84 |
85 | templ Input(name string, inputType InputType, classes string, attrs templ.Attributes) {
86 |
92 | }
93 |
--------------------------------------------------------------------------------
/ui/input_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package ui
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
12 |
13 | const (
14 | inputBaseClass = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
15 | )
16 |
17 | type InputType int
18 |
19 | const (
20 | InputTypeText InputType = iota
21 | InputTypeEmail
22 | InputTypePassword
23 | InputTypeSearch
24 | InputTypeUrl
25 | InputTypeTel
26 | InputTypeDate
27 | InputTypeDatetimeLocal
28 | InputTypeNumber
29 | InputTypeButton
30 | InputTypeFile
31 | InputTypeHidden
32 | InputTypeImage
33 | InputTypeMonth
34 | InputTypeWeek
35 | InputTypeCheckbox
36 | InputTypeColor
37 | InputTypeRadio
38 | InputTypeRange
39 | InputTypeReset
40 | InputTypeSubmit
41 | InputTypeTime
42 | )
43 |
44 | func (t InputType) String() string {
45 | switch t {
46 | case InputTypeEmail:
47 | return "email"
48 | case InputTypePassword:
49 | return "password"
50 | case InputTypeSearch:
51 | return "search"
52 | case InputTypeUrl:
53 | return "url"
54 | case InputTypeTel:
55 | return "tel"
56 | case InputTypeDate:
57 | return "date"
58 | case InputTypeDatetimeLocal:
59 | return "datetime-local"
60 | case InputTypeNumber:
61 | return "number"
62 | case InputTypeButton:
63 | return "button"
64 | case InputTypeFile:
65 | return "file"
66 | case InputTypeHidden:
67 | return "hidden"
68 | case InputTypeImage:
69 | return "image"
70 | case InputTypeMonth:
71 | return "month"
72 | case InputTypeWeek:
73 | return "week"
74 | case InputTypeCheckbox:
75 | return "checkbox"
76 | case InputTypeColor:
77 | return "color"
78 | case InputTypeRadio:
79 | return "radio"
80 | case InputTypeRange:
81 | return "range"
82 | case InputTypeReset:
83 | return "reset"
84 | case InputTypeSubmit:
85 | return "submit"
86 | case InputTypeTime:
87 | return "time"
88 | default:
89 | return "text"
90 | }
91 | }
92 |
93 | func Input(name string, inputType InputType, classes string, attrs templ.Attributes) templ.Component {
94 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
95 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
96 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
97 | return templ_7745c5c3_CtxErr
98 | }
99 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
100 | if !templ_7745c5c3_IsBuffer {
101 | defer func() {
102 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
103 | if templ_7745c5c3_Err == nil {
104 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
105 | }
106 | }()
107 | }
108 | ctx = templ.InitializeContext(ctx)
109 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
110 | if templ_7745c5c3_Var1 == nil {
111 | templ_7745c5c3_Var1 = templ.NopComponent
112 | }
113 | ctx = templ.ClearChildren(ctx)
114 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(inputBaseClass, classes)}
115 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
116 | if templ_7745c5c3_Err != nil {
117 | return templ_7745c5c3_Err
118 | }
119 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
167 | if templ_7745c5c3_Err != nil {
168 | return templ_7745c5c3_Err
169 | }
170 | return templ_7745c5c3_Err
171 | })
172 | }
173 |
174 | var _ = templruntime.GeneratedTemplate
175 |
--------------------------------------------------------------------------------
/ui/label.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
4 |
5 | const (
6 | labelBaseClass = "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
7 | )
8 |
9 | templ Label(classes string, attrs templ.Attributes) {
10 |
16 | }
17 |
--------------------------------------------------------------------------------
/ui/label_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package ui
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
12 |
13 | const (
14 | labelBaseClass = "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
15 | )
16 |
17 | func Label(classes string, attrs templ.Attributes) templ.Component {
18 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
19 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
20 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
21 | return templ_7745c5c3_CtxErr
22 | }
23 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
24 | if !templ_7745c5c3_IsBuffer {
25 | defer func() {
26 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
27 | if templ_7745c5c3_Err == nil {
28 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
29 | }
30 | }()
31 | }
32 | ctx = templ.InitializeContext(ctx)
33 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
34 | if templ_7745c5c3_Var1 == nil {
35 | templ_7745c5c3_Var1 = templ.NopComponent
36 | }
37 | ctx = templ.ClearChildren(ctx)
38 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(labelBaseClass, "[div:has(>div.font-medium:not(:empty))>&]:text-destructive", classes)}
39 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
40 | if templ_7745c5c3_Err != nil {
41 | return templ_7745c5c3_Err
42 | }
43 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
73 | if templ_7745c5c3_Err != nil {
74 | return templ_7745c5c3_Err
75 | }
76 | return templ_7745c5c3_Err
77 | })
78 | }
79 |
80 | var _ = templruntime.GeneratedTemplate
81 |
--------------------------------------------------------------------------------
/ui/optalias_generator.go:
--------------------------------------------------------------------------------
1 | //go:build ignore
2 | // +build ignore
3 |
4 | package main
5 |
6 | import (
7 | "flag"
8 | "fmt"
9 | "go/ast"
10 | "go/parser"
11 | "go/token"
12 | "os"
13 | "os/exec"
14 | "path/filepath"
15 | "strings"
16 | )
17 |
18 | const filePath = "../props.go"
19 |
20 | func main() {
21 | var typeFlag string
22 | flag.StringVar(&typeFlag, "type", "", "type name to set aliases with as type param")
23 | flag.Parse()
24 |
25 | if typeFlag == "" || filePath == "" {
26 | panic("Both type and path parameters must be provided")
27 | }
28 |
29 | fset := token.NewFileSet()
30 | node, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments)
31 | if err != nil {
32 | panic(err)
33 | }
34 |
35 | packageName := node.Name.Name
36 |
37 | var functions []string
38 |
39 | for _, decl := range node.Decls {
40 | if fn, ok := decl.(*ast.FuncDecl); ok {
41 | // Check if the function return type is of the desired type
42 | if fn.Type.Results != nil && len(fn.Type.Results.List) > 0 {
43 | returnType := fn.Type.Results.List[0].Type
44 | if isMatchingType(returnType) {
45 | functions = append(functions, fn.Name.Name)
46 | }
47 | }
48 | }
49 | }
50 |
51 | cwd, err := os.Getwd()
52 | if err != nil {
53 | panic(err)
54 | }
55 | outputFilePath := filepath.Join(cwd, "generated_optaliase.go")
56 | f, err := os.Create(outputFilePath)
57 | if err != nil {
58 | panic(err)
59 | }
60 |
61 | var b strings.Builder
62 | mustWrite(&b, "// Code generated by \"optaliase_generator.go %s\"; DO NOT EDIT.\n", strings.Join(os.Args[1:], " "))
63 | mustWrite(&b, "\n")
64 | mustWrite(&b, "package %s", currPackageName())
65 | mustWrite(&b, "\n")
66 | mustWrite(&b, "var (\n")
67 | for _, function := range functions {
68 | mustWrite(&b, " %s = %s.%s[*%s]\n", function, packageName, function, typeFlag)
69 | }
70 | mustWrite(&b, ")")
71 |
72 | if _, err = f.WriteString(b.String()); err != nil {
73 | panic(err)
74 | }
75 |
76 | if err = f.Close(); err != nil {
77 | panic(err)
78 | }
79 |
80 | runGoImports(outputFilePath)
81 | }
82 |
83 | // panics at any error
84 | func runGoImports(filePath string) {
85 | cmd := exec.Command("goimports", "-w", filePath) // -w flag writes the result back to the file
86 | if err := cmd.Run(); err != nil {
87 | panic(err)
88 | }
89 | }
90 |
91 | func mustWrite(b *strings.Builder, f string, a ...any) {
92 | if _, err := b.WriteString(fmt.Sprintf(f, a...)); err != nil {
93 | panic(err)
94 | }
95 | }
96 |
97 | // checks if the type is `*Option`
98 | func isMatchingType(typ ast.Expr) bool {
99 | // Handle pointer types
100 | if indexExpr, ok := typ.(*ast.IndexExpr); ok {
101 | if ident, ok := indexExpr.X.(*ast.Ident); ok {
102 | if ident.Name == "Option" {
103 | return true
104 | }
105 | }
106 | }
107 | return false
108 | }
109 |
110 | // will panic at any error
111 | func currPackageName() string {
112 | currentDir, err := os.Getwd()
113 | if err != nil {
114 | panic(err)
115 | }
116 |
117 | goFiles, err := filepath.Glob(filepath.Join(currentDir, "*.go"))
118 | if err != nil || len(goFiles) == 0 {
119 | panic(err)
120 | }
121 |
122 | var firstGoFile string
123 | for _, goFile := range goFiles {
124 | if filepath.Base(goFile) != "generated_optaliase.go" {
125 | firstGoFile = goFile
126 | break
127 | }
128 | }
129 | if firstGoFile == "" {
130 | panic("no files found in cwd")
131 | }
132 |
133 | fset := token.NewFileSet()
134 | node, err := parser.ParseFile(fset, firstGoFile, nil, parser.PackageClauseOnly)
135 | if err != nil {
136 | panic(err)
137 | }
138 |
139 | return node.Name.Name
140 | }
141 |
--------------------------------------------------------------------------------
/ui/progress/generated_optaliase.go:
--------------------------------------------------------------------------------
1 | // Code generated by "optaliase_generator.go -type=RootProps"; DO NOT EDIT.
2 |
3 | package progress
4 |
5 | import "github.com/rotemhoresh/shadcn-templ/ui"
6 |
7 | var (
8 | WithClass = ui.WithClass[*RootProps]
9 | WithAttrs = ui.WithAttrs[*RootProps]
10 | WithAttr = ui.WithAttr[*RootProps]
11 | )
12 |
--------------------------------------------------------------------------------
/ui/progress/root.templ:
--------------------------------------------------------------------------------
1 | package progress
2 |
3 | import (
4 | "fmt"
5 | twmerge "github.com/Oudwins/tailwind-merge-go"
6 | "github.com/rotemhoresh/shadcn-templ/ui"
7 | )
8 |
9 | const (
10 | baseClass = "relative h-2 w-full overflow-hidden rounded-full bg-primary/20"
11 | indicatorBaseClass = "h-full w-full flex-1 bg-primary transition-all"
12 | )
13 |
14 | const maxVal uint = 100
15 |
16 | type RootProps struct {
17 | control string
18 | value uint
19 | ui.CoreProps
20 | }
21 |
22 | type RootOption = ui.Option[*RootProps]
23 |
24 | // provide a controling variable created using `x-data` on a parent component
25 | func WithControl(c string) RootOption {
26 | return func(p *RootProps) {
27 | p.control = c
28 | }
29 | }
30 |
31 | // if a control is provided, `value` will be ignored.
32 | //
33 | // default value - 0
34 | func WithValue(v uint) RootOption {
35 | return func(p *RootProps) {
36 | p.value = v
37 | }
38 | }
39 |
40 | //go:generate go run ../optalias_generator.go -type=RootProps
41 |
42 | func Root(opts ...RootOption) templ.Component {
43 | p := &RootProps{
44 | CoreProps: ui.DefaultCoreProps,
45 | }
46 | for _, opt := range opts {
47 | opt(p)
48 | }
49 | return root(p)
50 | }
51 |
52 | css uncontrolledIndicatorStyle(v uint) {
53 | transform: { fmt.Sprintf("translateX(%d)", -1 * (100 - int(v))) };
54 | }
55 |
56 | templ root(props *RootProps) {
57 |
98 | }
99 |
--------------------------------------------------------------------------------
/ui/props.go:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import "github.com/a-h/templ"
4 |
5 | type Option[T CorePropsInter] func(T)
6 |
7 | // Sets the class
8 | func WithClass[T CorePropsInter](c string) Option[T] {
9 | return func(p T) {
10 | p.SetClass(c)
11 | }
12 | }
13 |
14 | // Sets the attributes
15 | func WithAttrs[T CorePropsInter](a templ.Attributes) Option[T] {
16 | return func(p T) {
17 | p.SetAttrs(a)
18 | }
19 | }
20 |
21 | // Adds an attribute
22 | func WithAttr[T CorePropsInter](k string, v any) Option[T] {
23 | return func(p T) {
24 | p.SetAttr(k, v)
25 | }
26 | }
27 |
28 | type CoreProps struct {
29 | class string
30 | attrs templ.Attributes
31 | }
32 |
33 | var DefaultCoreProps = CoreProps{
34 | class: "",
35 | attrs: templ.Attributes{},
36 | }
37 |
38 | var _ CorePropsInter = (*CoreProps)(nil)
39 |
40 | type CorePropsInter interface {
41 | SetClass(string)
42 | SetAttrs(templ.Attributes)
43 | SetAttr(string, any)
44 | Class() string
45 | Attrs() templ.Attributes
46 | }
47 |
48 | func (p *CoreProps) SetClass(c string) {
49 | p.class = c
50 | }
51 |
52 | func (p *CoreProps) SetAttrs(a templ.Attributes) {
53 | p.attrs = a
54 | }
55 |
56 | func (p *CoreProps) SetAttr(k string, v any) {
57 | p.attrs[k] = v
58 | }
59 |
60 | func (p *CoreProps) Class() string {
61 | return p.class
62 | }
63 |
64 | func (p *CoreProps) Attrs() templ.Attributes {
65 | return p.attrs
66 | }
67 |
--------------------------------------------------------------------------------
/ui/separator.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
4 |
5 | const (
6 | separatorBaseClass = "shrink-0 bg-border"
7 | )
8 |
9 | type SeparatorOrientation int
10 |
11 | func (o SeparatorOrientation) String() string {
12 | switch o {
13 | case SeparatorOrientationVertical:
14 | return "vertical"
15 | default:
16 | return "horizontal"
17 | }
18 | }
19 |
20 | func (o SeparatorOrientation) Class() string {
21 | switch o {
22 | case SeparatorOrientationVertical:
23 | return "h-full w-[1px]"
24 | default:
25 | return "h-[1px] w-full"
26 | }
27 | }
28 |
29 | const (
30 | SeparatorOrientationVertical SeparatorOrientation = iota
31 | SeparatorOrientationHorizontal
32 | )
33 |
34 | templ Separator(orientation SeparatorOrientation, decorative bool, classes string, attrs templ.Attributes) {
35 |
44 | }
45 |
--------------------------------------------------------------------------------
/ui/separator_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package ui
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
12 |
13 | const (
14 | separatorBaseClass = "shrink-0 bg-border"
15 | )
16 |
17 | type SeparatorOrientation int
18 |
19 | func (o SeparatorOrientation) String() string {
20 | switch o {
21 | case SeparatorOrientationVertical:
22 | return "vertical"
23 | default:
24 | return "horizontal"
25 | }
26 | }
27 |
28 | func (o SeparatorOrientation) Class() string {
29 | switch o {
30 | case SeparatorOrientationVertical:
31 | return "h-full w-[1px]"
32 | default:
33 | return "h-[1px] w-full"
34 | }
35 | }
36 |
37 | const (
38 | SeparatorOrientationVertical SeparatorOrientation = iota
39 | SeparatorOrientationHorizontal
40 | )
41 |
42 | func Separator(orientation SeparatorOrientation, decorative bool, classes string, attrs templ.Attributes) templ.Component {
43 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
44 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
45 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
46 | return templ_7745c5c3_CtxErr
47 | }
48 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
49 | if !templ_7745c5c3_IsBuffer {
50 | defer func() {
51 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
52 | if templ_7745c5c3_Err == nil {
53 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
54 | }
55 | }()
56 | }
57 | ctx = templ.InitializeContext(ctx)
58 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
59 | if templ_7745c5c3_Var1 == nil {
60 | templ_7745c5c3_Var1 = templ.NopComponent
61 | }
62 | ctx = templ.ClearChildren(ctx)
63 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(separatorBaseClass, orientation.Class(), classes)}
64 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
65 | if templ_7745c5c3_Err != nil {
66 | return templ_7745c5c3_Err
67 | }
68 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
110 | if templ_7745c5c3_Err != nil {
111 | return templ_7745c5c3_Err
112 | }
113 | return templ_7745c5c3_Err
114 | })
115 | }
116 |
117 | var _ = templruntime.GeneratedTemplate
118 |
--------------------------------------------------------------------------------
/ui/skeleton.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import "github.com/Oudwins/tailwind-merge-go"
4 |
5 | const (
6 | skeletonBaseClass = "animate-pulse rounded-md bg-primary/10"
7 | )
8 |
9 | templ Skeleton(classes string, attrs templ.Attributes) {
10 |
14 | }
15 |
--------------------------------------------------------------------------------
/ui/skeleton_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package ui
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import "github.com/Oudwins/tailwind-merge-go"
12 |
13 | const (
14 | skeletonBaseClass = "animate-pulse rounded-md bg-primary/10"
15 | )
16 |
17 | func Skeleton(classes string, attrs templ.Attributes) templ.Component {
18 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
19 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
20 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
21 | return templ_7745c5c3_CtxErr
22 | }
23 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
24 | if !templ_7745c5c3_IsBuffer {
25 | defer func() {
26 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
27 | if templ_7745c5c3_Err == nil {
28 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
29 | }
30 | }()
31 | }
32 | ctx = templ.InitializeContext(ctx)
33 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
34 | if templ_7745c5c3_Var1 == nil {
35 | templ_7745c5c3_Var1 = templ.NopComponent
36 | }
37 | ctx = templ.ClearChildren(ctx)
38 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(skeletonBaseClass, classes)}
39 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
40 | if templ_7745c5c3_Err != nil {
41 | return templ_7745c5c3_Err
42 | }
43 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
65 | if templ_7745c5c3_Err != nil {
66 | return templ_7745c5c3_Err
67 | }
68 | return templ_7745c5c3_Err
69 | })
70 | }
71 |
72 | var _ = templruntime.GeneratedTemplate
73 |
--------------------------------------------------------------------------------
/ui/switch.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import (
4 | "fmt"
5 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
6 | )
7 |
8 | const (
9 | switchBaseClass = "peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors 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 disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input"
10 | switchThumbBaseClass = "pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
11 | )
12 |
13 | // `attrs` will go to the inner input
14 | templ Switch(name string, defaultChecked, required bool, classes string, attrs templ.Attributes) {
15 |
48 | }
49 |
50 | templ switchThumb(disabled bool) {
51 |
59 | }
60 |
--------------------------------------------------------------------------------
/ui/switch_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package ui
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "fmt"
13 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
14 | )
15 |
16 | const (
17 | switchBaseClass = "peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors 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 disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input"
18 | switchThumbBaseClass = "pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
19 | )
20 |
21 | // `attrs` will go to the inner input
22 | func Switch(name string, defaultChecked, required bool, classes string, attrs templ.Attributes) templ.Component {
23 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
24 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
25 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
26 | return templ_7745c5c3_CtxErr
27 | }
28 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
29 | if !templ_7745c5c3_IsBuffer {
30 | defer func() {
31 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
32 | if templ_7745c5c3_Err == nil {
33 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
34 | }
35 | }()
36 | }
37 | ctx = templ.InitializeContext(ctx)
38 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
39 | if templ_7745c5c3_Var1 == nil {
40 | templ_7745c5c3_Var1 = templ.NopComponent
41 | }
42 | ctx = templ.ClearChildren(ctx)
43 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(switchBaseClass, classes)}
44 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
45 | if templ_7745c5c3_Err != nil {
46 | return templ_7745c5c3_Err
47 | }
48 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
143 | if templ_7745c5c3_Err != nil {
144 | return templ_7745c5c3_Err
145 | }
146 | return templ_7745c5c3_Err
147 | })
148 | }
149 |
150 | func switchThumb(disabled bool) templ.Component {
151 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
152 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
153 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
154 | return templ_7745c5c3_CtxErr
155 | }
156 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
157 | if !templ_7745c5c3_IsBuffer {
158 | defer func() {
159 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
160 | if templ_7745c5c3_Err == nil {
161 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
162 | }
163 | }()
164 | }
165 | ctx = templ.InitializeContext(ctx)
166 | templ_7745c5c3_Var7 := templ.GetChildren(ctx)
167 | if templ_7745c5c3_Var7 == nil {
168 | templ_7745c5c3_Var7 = templ.NopComponent
169 | }
170 | ctx = templ.ClearChildren(ctx)
171 | var templ_7745c5c3_Var8 = []any{switchThumbBaseClass}
172 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
173 | if templ_7745c5c3_Err != nil {
174 | return templ_7745c5c3_Err
175 | }
176 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
200 | if templ_7745c5c3_Err != nil {
201 | return templ_7745c5c3_Err
202 | }
203 | return templ_7745c5c3_Err
204 | })
205 | }
206 |
207 | var _ = templruntime.GeneratedTemplate
208 |
--------------------------------------------------------------------------------
/ui/table.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
4 |
5 | const (
6 | tableBaseClass = "w-full caption-bottom text-sm"
7 | tableHeaderBaseClass = "[&_tr]:border-b"
8 | tableBodyBaseClass = "[&_tr:last-child]:border-0"
9 | tableFooterBaseClass = "border-t bg-muted/50 font-medium [&>tr]:last:border-b-0"
10 | tableRowBaseClass = "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted"
11 | tableHeadBaseClass = "h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]"
12 | tableCellBaseClass = "p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]"
13 | tableCaptionBaseClass = "mt-4 text-sm text-muted-foreground"
14 | )
15 |
16 | templ Table(classes string, attrs templ.Attributes) {
17 |
18 |
22 | { children... }
23 |
24 |
25 | }
26 |
27 | templ TableHeader(classes string, attrs templ.Attributes) {
28 |
32 | { children... }
33 |
34 | }
35 |
36 | templ TableBody(classes string, attrs templ.Attributes) {
37 |
41 | { children... }
42 |
43 | }
44 |
45 | templ TableFooter(classes string, attrs templ.Attributes) {
46 |
50 | { children... }
51 |
52 | }
53 |
54 | templ TableRow(classes string, attrs templ.Attributes) {
55 |
59 | { children... }
60 |
61 | }
62 |
63 | templ TableHead(classes string, attrs templ.Attributes) {
64 |
68 | { children... }
69 | |
70 | }
71 |
72 | templ TableCell(classes string, attrs templ.Attributes) {
73 |
77 | { children... }
78 | |
79 | }
80 |
81 | templ TableCaption(classes string, attrs templ.Attributes) {
82 |
86 | { children... }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/ui/tabs.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import (
4 | "fmt"
5 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
6 | )
7 |
8 | const (
9 | tabsListBaseClass = "inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground"
10 | tabsTriggerBaseClass = "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow"
11 | tabsContentBaseClass = "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
12 | )
13 |
14 | templ Tabs(defaultValue, classes string, attrs templ.Attributes) {
15 |
20 | { children... }
21 |
22 | }
23 |
24 | templ TabsList(classes string, attrs templ.Attributes) {
25 |
29 | { children... }
30 |
31 | }
32 |
33 | templ TabsTrigger(value, classes string, attrs templ.Attributes) {
34 |
48 | }
49 |
50 | templ TabsContent(value, classes string, attrs templ.Attributes) {
51 |
59 | { children... }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/ui/textarea.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
4 |
5 | const (
6 | textareaBaseClass = "flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
7 | )
8 |
9 | templ Textarea(name, classes string, attrs templ.Attributes) {
10 |
14 | }
15 |
--------------------------------------------------------------------------------
/ui/textarea_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package ui
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
12 |
13 | const (
14 | textareaBaseClass = "flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
15 | )
16 |
17 | func Textarea(name, classes string, attrs templ.Attributes) templ.Component {
18 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
19 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
20 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
21 | return templ_7745c5c3_CtxErr
22 | }
23 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
24 | if !templ_7745c5c3_IsBuffer {
25 | defer func() {
26 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
27 | if templ_7745c5c3_Err == nil {
28 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
29 | }
30 | }()
31 | }
32 | ctx = templ.InitializeContext(ctx)
33 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
34 | if templ_7745c5c3_Var1 == nil {
35 | templ_7745c5c3_Var1 = templ.NopComponent
36 | }
37 | ctx = templ.ClearChildren(ctx)
38 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(textareaBaseClass, classes)}
39 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
40 | if templ_7745c5c3_Err != nil {
41 | return templ_7745c5c3_Err
42 | }
43 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
65 | if templ_7745c5c3_Err != nil {
66 | return templ_7745c5c3_Err
67 | }
68 | return templ_7745c5c3_Err
69 | })
70 | }
71 |
72 | var _ = templruntime.GeneratedTemplate
73 |
--------------------------------------------------------------------------------
/ui/toggle.templ:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import (
4 | "fmt"
5 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
6 | )
7 |
8 | const (
9 | toggleBaseClass = "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground"
10 | )
11 |
12 | type ToggleVariant int
13 |
14 | func (v ToggleVariant) Class() string {
15 | switch v {
16 | case ToggleVariantSecondary:
17 | return "border border-input bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground"
18 | default:
19 | return "bg-transparent"
20 | }
21 | }
22 |
23 | const (
24 | ToggleVariantDefault ToggleVariant = iota
25 | ToggleVariantSecondary
26 | )
27 |
28 | type ToggleSize int
29 |
30 | func (s ToggleSize) Class() string {
31 | switch s {
32 | case ToggleSizeSmall:
33 | return "h-8 px-2"
34 | case ToggleSizeLarge:
35 | return "h-10 px-3"
36 | default:
37 | return "h-9 px-3"
38 | }
39 | }
40 |
41 | const (
42 | ToggleSizeDefault ToggleSize = iota
43 | ToggleSizeSmall
44 | ToggleSizeLarge
45 | )
46 |
47 | templ Toggle(variant ToggleVariant, size ToggleSize, alpinePressed, classes string, attrs templ.Attributes) {
48 |
62 | }
63 |
--------------------------------------------------------------------------------
/ui/toggle_templ.go:
--------------------------------------------------------------------------------
1 | // Code generated by templ - DO NOT EDIT.
2 |
3 | // templ: version: v0.2.778
4 | package ui
5 |
6 | //lint:file-ignore SA4006 This context is only used if a nested component is present.
7 |
8 | import "github.com/a-h/templ"
9 | import templruntime "github.com/a-h/templ/runtime"
10 |
11 | import (
12 | "fmt"
13 | "github.com/Oudwins/tailwind-merge-go/pkg/twmerge"
14 | )
15 |
16 | const (
17 | toggleBaseClass = "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground"
18 | )
19 |
20 | type ToggleVariant int
21 |
22 | func (v ToggleVariant) Class() string {
23 | switch v {
24 | case ToggleVariantSecondary:
25 | return "border border-input bg-transparent shadow-sm hover:bg-accent hover:text-accent-foreground"
26 | default:
27 | return "bg-transparent"
28 | }
29 | }
30 |
31 | const (
32 | ToggleVariantDefault ToggleVariant = iota
33 | ToggleVariantSecondary
34 | )
35 |
36 | type ToggleSize int
37 |
38 | func (s ToggleSize) Class() string {
39 | switch s {
40 | case ToggleSizeSmall:
41 | return "h-8 px-2"
42 | case ToggleSizeLarge:
43 | return "h-10 px-3"
44 | default:
45 | return "h-9 px-3"
46 | }
47 | }
48 |
49 | const (
50 | ToggleSizeDefault ToggleSize = iota
51 | ToggleSizeSmall
52 | ToggleSizeLarge
53 | )
54 |
55 | func Toggle(variant ToggleVariant, size ToggleSize, alpinePressed, classes string, attrs templ.Attributes) templ.Component {
56 | return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
57 | templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
58 | if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
59 | return templ_7745c5c3_CtxErr
60 | }
61 | templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
62 | if !templ_7745c5c3_IsBuffer {
63 | defer func() {
64 | templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
65 | if templ_7745c5c3_Err == nil {
66 | templ_7745c5c3_Err = templ_7745c5c3_BufErr
67 | }
68 | }()
69 | }
70 | ctx = templ.InitializeContext(ctx)
71 | templ_7745c5c3_Var1 := templ.GetChildren(ctx)
72 | if templ_7745c5c3_Var1 == nil {
73 | templ_7745c5c3_Var1 = templ.NopComponent
74 | }
75 | ctx = templ.ClearChildren(ctx)
76 | var templ_7745c5c3_Var2 = []any{twmerge.Merge(toggleBaseClass, variant.Class(), size.Class(), classes)}
77 | templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
78 | if templ_7745c5c3_Err != nil {
79 | return templ_7745c5c3_Err
80 | }
81 | _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("")
160 | if templ_7745c5c3_Err != nil {
161 | return templ_7745c5c3_Err
162 | }
163 | return templ_7745c5c3_Err
164 | })
165 | }
166 |
167 | var _ = templruntime.GeneratedTemplate
168 |
--------------------------------------------------------------------------------
/ui/utils.go:
--------------------------------------------------------------------------------
1 | package ui
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/a-h/templ"
7 | )
8 |
9 | // boolAttr checks if an attribute exists and has a true value - `true` (bool) or `"true"` (string).
10 | func boolAttr(attr string, attrs templ.Attributes) bool {
11 | if v, ok := attrs[attr]; ok {
12 | if boolV, ok := v.(bool); ok && boolV {
13 | return true
14 | } else if stringV, ok := v.(string); ok && stringV == "true" {
15 | return true
16 | }
17 | }
18 | return false
19 | }
20 |
21 | func fmtBool(v bool) string {
22 | return fmt.Sprintf("%t", v)
23 | }
24 |
--------------------------------------------------------------------------------