before sqlc

This commit is contained in:
Johannes Bülow 2025-06-03 15:44:56 +02:00
parent e9e6e34364
commit 8308398d0a
Signed by: jmb
GPG key ID: B56971CF7B8F83A6
114 changed files with 38000 additions and 134 deletions

View file

@ -1,5 +1,5 @@
{ {
"componentsDir": "server/web/components", "componentsDir": "server/web/templui/components",
"utilsDir": "server/web/utils", "utilsDir": "server/web/templui/utils",
"moduleName": "git.jmbit.de/jmb/scanfile" "moduleName": "git.jmbit.de/jmb/scanfile"
} }

View file

@ -2,43 +2,40 @@
all: deps build all: deps build
deps: deps: ## Install build dependencies
go mod tidy go mod tidy
go install github.com/a-h/templ/cmd/templ@latest go install github.com/a-h/templ/cmd/templ@latest
build: build: ## Build and compile
echo "Building..." echo "Building..."
tailwindcss -o server/web/assets/styles.css tailwindcss -o server/web/assets/styles.css
templ generate templ generate
go build -o main.out server/main.go go build -o main.out server/main.go
# Run the application run: ## Run the application
run:
go run main.go go run main.go
# Test the application test: ## Run test
test:
echo "Testing..." echo "Testing..."
go test ./tests/... -v go test ./tests/... -v
# Clean the binary clean: ## Delete build artifacts
clean:
echo "Cleaning..." echo "Cleaning..."
rm -f main.out rm -f main.out
rm -rf sessions/* rm -rf sessions/*
rm -rf storage/* rm -rf storage/*
dev: dev: ## Start templ-dev tailwind-dev and watch
make -j3 templ-dev tailwind-dev watch make -j3 templ-dev tailwind-dev watch
templ-dev: templ-dev: ## Watch & Live rebuild of templ
templ generate --watch --proxy="http://localhost:8080" --open-browser=false templ generate --watch --proxy="http://localhost:8080" --open-browser=false
tailwind-dev: tailwind-dev: ##Live rebuild of tailwind
tailwindcss -o server/web/assets/styles.css -i input.css --watch tailwindcss -o server/web/assets/styles.css -i input.css --watch
# Live Reload # Live Reload
watch: watch: ##Live reload with air
@if command -v air > /dev/null; then \ @if command -v air > /dev/null; then \
air; \ air; \
echo "Watching...";\ echo "Watching...";\
@ -54,4 +51,14 @@ watch:
fi; \ fi; \
fi fi
.PHONY: all build run test clean help: ## Display this Help.
@awk 'BEGIN { \
FS = ":.*##"; \
printf "\nUsage:\n make <target>\n" \
} \
/^[a-zA-Z_-]+:.*?##/ { \
printf " %-20s %s\n", $$1, $$2 \
} \
' $(MAKEFILE_LIST)
.PHONY: all build run test clean help

View file

@ -11,7 +11,10 @@ user = "scanfile"
port = 5432 port = 5432
password = "Sequel-Gutless-Epilogue1-Scorch-Nuclei" password = "Sequel-Gutless-Epilogue1-Scorch-Nuclei"
database = "scanfile" database = "scanfile"
debug = true
[store] [store]
path = "./storage/files/" path = "./storage/files/"
[processing]
executors = 5

6
go.mod
View file

@ -3,14 +3,17 @@ module git.jmbit.de/jmb/scanfile
go 1.24.1 go 1.24.1
require ( require (
github.com/Oudwins/tailwind-merge-go v0.2.1
github.com/a-h/templ v0.3.865 github.com/a-h/templ v0.3.865
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/gorilla/securecookie v1.1.2 github.com/gorilla/securecookie v1.1.2
github.com/gorilla/sessions v1.4.0 github.com/gorilla/sessions v1.4.0
github.com/h2non/filetype v1.1.3 github.com/h2non/filetype v1.1.3
github.com/jackc/pgx/v5 v5.7.5
github.com/joho/godotenv v1.5.1 github.com/joho/godotenv v1.5.1
github.com/lib/pq v1.10.9 github.com/lib/pq v1.10.9
github.com/spf13/viper v1.20.1 github.com/spf13/viper v1.20.1
golang.org/x/crypto v0.38.0
xorm.io/xorm v1.3.9 xorm.io/xorm v1.3.9
) )
@ -20,6 +23,8 @@ require (
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/goccy/go-json v0.10.5 // indirect github.com/goccy/go-json v0.10.5 // indirect
github.com/golang/snappy v1.0.0 // indirect github.com/golang/snappy v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/mattn/go-sqlite3 v1.14.27 // indirect github.com/mattn/go-sqlite3 v1.14.27 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@ -35,7 +40,6 @@ require (
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/sys v0.33.0 // indirect golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.25.0 // indirect golang.org/x/text v0.25.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
xorm.io/builder v0.3.13 // indirect xorm.io/builder v0.3.13 // indirect
) )

17
go.sum
View file

@ -2,6 +2,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
github.com/Oudwins/tailwind-merge-go v0.2.1 h1:jxRaEqGtwwwF48UuFIQ8g8XT7YSualNuGzCvQ89nPFE=
github.com/Oudwins/tailwind-merge-go v0.2.1/go.mod h1:kkZodgOPvZQ8f7SIrlWkG/w1g9JTbtnptnePIh3V72U=
github.com/a-h/templ v0.3.865 h1:nYn5EWm9EiXaDgWcMQaKiKvrydqgxDUtT1+4zU2C43A= github.com/a-h/templ v0.3.865 h1:nYn5EWm9EiXaDgWcMQaKiKvrydqgxDUtT1+4zU2C43A=
github.com/a-h/templ v0.3.865/go.mod h1:oLBbZVQ6//Q6zpvSMPTuBK0F3qOtBdFBcGRspcT+VNQ= github.com/a-h/templ v0.3.865/go.mod h1:oLBbZVQ6//Q6zpvSMPTuBK0F3qOtBdFBcGRspcT+VNQ=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -39,17 +41,22 @@ github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg=
github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs=
github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
@ -90,6 +97,7 @@ github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
@ -98,6 +106,8 @@ github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFd
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -123,6 +133,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=

View file

@ -42,6 +42,7 @@ func setDefaults() {
viper.SetDefault("db.user", "scanfile") viper.SetDefault("db.user", "scanfile")
viper.SetDefault("db.database", "scanfile") viper.SetDefault("db.database", "scanfile")
viper.SetDefault("db.password", "CHANGEME") viper.SetDefault("db.password", "CHANGEME")
viper.SetDefault("db.debug", false)
viper.SetDefault("store.path", "./storage/files/") viper.SetDefault("store.path", "./storage/files/")
} }

View file

@ -0,0 +1,59 @@
package database
import (
"encoding/hex"
"log/slog"
"github.com/google/uuid"
"golang.org/x/crypto/blake2b"
"git.jmbit.de/jmb/scanfile/server/internal/store"
)
// CreateFile() creates the filesystem object and the DB entry for a file
func CreateFile(name string, fileBytes []byte, size int64) (File, error) {
file := File{
Name: name,
Size: size,
}
bl2hash := blake2b.Sum256(fileBytes)
file.Blake2 = hex.EncodeToString(bl2hash[:])
fileExists, err := FileAlreadyExists(file.Blake2)
if err != nil {
slog.Error("Could not check if a duplicate exists", "error", err)
err = nil
}
if fileExists {
slog.Info("File seems to already exist")
sameFile, err := FileByBlake2(file.Blake2)
if err != nil {
slog.Error("Could not retrieve duplicate", "error", err)
err = nil
}
return sameFile, nil
}
//Using UUIDs instead of the file hash to make switching storage backends easier
fileUUID, err := uuid.NewRandom()
if err != nil {
slog.Error("could not save file,", "error", err)
return file, err
}
uuid, err := store.SaveFile(fileUUID.String(), fileBytes)
if err != nil {
return file, err
}
file.Uuid = uuid
file.MimeType, _ = store.GetFileType(file.Uuid)
err = file.Insert()
if err != nil {
return file, nil
}
return file, nil
}

View file

@ -8,6 +8,7 @@ import (
_ "github.com/lib/pq" _ "github.com/lib/pq"
"github.com/spf13/viper" "github.com/spf13/viper"
"xorm.io/xorm" "xorm.io/xorm"
"xorm.io/xorm/log"
"xorm.io/xorm/names" "xorm.io/xorm/names"
) )
@ -33,6 +34,10 @@ func Connect() (*xorm.Engine, error) {
if err != nil { if err != nil {
slog.Error("Error syncing DB schema", "error", err) slog.Error("Error syncing DB schema", "error", err)
} }
if viper.GetBool("db.debug") {
engi.SetLogLevel(log.LOG_DEBUG)
engi.ShowSQL(true)
}
engine = engi engine = engi
return engi, nil return engi, nil

View file

@ -1,7 +1,8 @@
package database package database
import ( import (
"mime/multipart" "fmt"
"log/slog"
"time" "time"
"git.jmbit.de/jmb/scanfile/server/internal/store" "git.jmbit.de/jmb/scanfile/server/internal/store"
@ -9,12 +10,13 @@ import (
type File struct { type File struct {
Id int64 Id int64
Uuid string //used for file blob storage etc. Blake2 string `xorm:"unique"`//Used for checking if the file already exists
Uuid string `xorm:"unique"`//used for file blob storage etc.
Name string //Name of the file Name string //Name of the file
Description string //Any text to add to it for context Description string //Any text to add to it for context
MimeType string MimeType string
Size int64 Size int64
CreatedAt time.Time `xorm:"create"` CreatedAt time.Time `xorm:"created"`
UpdatedAt time.Time `xorm:"updated"` UpdatedAt time.Time `xorm:"updated"`
} }
@ -24,28 +26,26 @@ func (f File) Insert() error {
return err return err
} }
// CreateFile() creates the filesystem object and the DB entry for a file // Deletes a File
func CreateFile(name string, fileData multipart.File, size int64) (File, error) { // TODO: Make atomic
file := File{ func (f File) Delete() error {
Name: name, err := store.DeleteFile(f.Uuid)
Size: size,
}
uuid, err := store.SaveFile(fileData)
if err != nil { if err != nil {
return file, err slog.Error("Could not delete File from disk", "file-uuid", f.Uuid, "file-name", f.Name)
return err
} }
file.Uuid = uuid slog.Info("Deleted File from disk", "uuid", f.Uuid)
_, err = engine.Delete(f)
file.MimeType, _ = store.GetFileType(file.Uuid)
err = file.Insert()
if err != nil { if err != nil {
return file, nil slog.Error("Could not delete File from DB", "file-uuid", f.Uuid, "file-name", f.Name)
return err
} }
slog.Info("Deleted File from DB", "file-uuid", f.Uuid)
return file, nil return nil
} }
func FileByID(id int64) (File, error) { func FileByID(id int64) (File, error) {
file := File{Id: id} file := File{Id: id}
success, err := engine.Get(&file) success, err := engine.Get(&file)
@ -63,3 +63,30 @@ func FileByUUID(uuid string) (File, error) {
} }
return file, nil return file, nil
} }
func FileByBlake2(hash string) (File, error) {
file := File{Blake2: hash}
success, err := engine.Get(&file)
slog.Info("Getting file for blake2 hash", "success", success, "hash", hash)
if err != nil {
return file, err
}
if success == false {
return file, fmt.Errorf("Record not found")
}
return file, nil
}
func FileAlreadyExists(blake2 string) (bool, error) {
file := new(File)
count, err := engine.Where("blake2 LIKE ?", blake2).Count(file)
if err != nil {
return false, err
}
if count > 0 {
return true, nil
} else {
return false, nil
}
}

View file

@ -0,0 +1,38 @@
package database
import (
"log/slog"
"time"
)
type ProcessingJob struct {
Id int64
FileID int64
FileUUID string
Created time.Time `xorm:"created"`
Started time.Time
Completed time.Time
Status string //Could be an enum, but who cares
Type string
}
func (j ProcessingJob) Update() error {
_, err := engine.Update(j)
if err != nil {
slog.Error("Error updating processing job", "error", err, "file-uuid", j.FileUUID, "job-id", j.Id, "job-type", j.Type)
}
return err
}
func NewProcessingJob(fileID int64, fileUUID string) (ProcessingJob, error) {
job := ProcessingJob{
FileID: fileID,
}
_, err := engine.InsertOne(job)
if err != nil {
slog.Error("Unable to create new processing job", "file-uuid", fileUUID)
return job, err
}
return job, nil
}

View file

@ -0,0 +1,23 @@
-- name: CreateFile :one
INSERT INTO files (
name, description, mimetype, size, blake2
) VALUES (
$1,$2,$3,$4,$5
)
ON CONFLICT DO NOTHING -- Handle this in application code
RETURNING *;
-- name: GetFileByUUID :one
SELECT *
FROM files
WHERE id = $1;
-- name: GetFileByBlake2 :one
SELECT *
FROM files
WHERE blake2 = $1;
-- name: UpdateFileDescription :exec
UPDATE files
SET description = $1
WHERE id = $2;

View file

@ -0,0 +1,17 @@
-- name: CreateProcessingJob :one
INSERT INTO processing_jobs (
file_id, job_type
) VALUES ($1,$2 )
RETURNING *;
-- name: StartProcessingJob :exec
UPDATE processing_jobs
SET started = NOW(),
status = "started"
WHERE id = $1;
-- name: FinishProcessingJob :exec
UPDATE processing_jobs
SET completed = NOW(),
status = "completed"
WHERE id = $1;

View file

@ -0,0 +1,21 @@
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
CREATE TABLE IF NOT EXISTS files (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
description TEXT,
mimetype TEXT NOT NULL,
size INTEGER NOT NULL,
blake2 BYTEA NOT NULL UNIQUE,
created TIMESTAMP DEFAULT NOW() NOT NULL,
updated TIMESTAMP DEFAULT NOW() NOT NULL
);
CREATE TABLE IF NOT EXISTS processing_jobs (
id SERIAL PRIMARY KEY,
file_id UUID REFERENCES files (id),
created TIMESTAMP DEFAULT NOW(),
started TIMESTAMP,
completed TIMESTAMP,
status TEXT,
job_type TEXT
);

View file

@ -0,0 +1,4 @@
package processing
func Submit()

View file

@ -0,0 +1,32 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
package sqlc
import (
"context"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
)
type DBTX interface {
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
QueryRow(context.Context, string, ...interface{}) pgx.Row
}
func New(db DBTX) *Queries {
return &Queries{db: db}
}
type Queries struct {
db DBTX
}
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
return &Queries{
db: tx,
}
}

View file

@ -0,0 +1,30 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
package sqlc
import (
"github.com/jackc/pgx/v5/pgtype"
)
type File struct {
ID pgtype.UUID
Name string
Description pgtype.Text
Mimetype string
Size int32
Blake2 []byte
Created pgtype.Timestamp
Updated pgtype.Timestamp
}
type ProcessingJob struct {
ID int32
FileID pgtype.UUID
Created pgtype.Timestamp
Started pgtype.Timestamp
Completed pgtype.Timestamp
Status pgtype.Text
JobType pgtype.Text
}

View file

@ -0,0 +1,112 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
// source: queries-files.sql
package sqlc
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const createFile = `-- name: CreateFile :one
INSERT INTO files (
name, description, mimetype, size, blake2
) VALUES (
$1,$2,$3,$4,$5
)
ON CONFLICT DO NOTHING -- Handle this in application code
RETURNING id, name, description, mimetype, size, blake2, created, updated
`
type CreateFileParams struct {
Name string
Description pgtype.Text
Mimetype string
Size int32
Blake2 []byte
}
func (q *Queries) CreateFile(ctx context.Context, arg CreateFileParams) (File, error) {
row := q.db.QueryRow(ctx, createFile,
arg.Name,
arg.Description,
arg.Mimetype,
arg.Size,
arg.Blake2,
)
var i File
err := row.Scan(
&i.ID,
&i.Name,
&i.Description,
&i.Mimetype,
&i.Size,
&i.Blake2,
&i.Created,
&i.Updated,
)
return i, err
}
const getFileByBlake2 = `-- name: GetFileByBlake2 :one
SELECT id, name, description, mimetype, size, blake2, created, updated
FROM files
WHERE blake2 = $1
`
func (q *Queries) GetFileByBlake2(ctx context.Context, blake2 []byte) (File, error) {
row := q.db.QueryRow(ctx, getFileByBlake2, blake2)
var i File
err := row.Scan(
&i.ID,
&i.Name,
&i.Description,
&i.Mimetype,
&i.Size,
&i.Blake2,
&i.Created,
&i.Updated,
)
return i, err
}
const getFileByUUID = `-- name: GetFileByUUID :one
SELECT id, name, description, mimetype, size, blake2, created, updated
FROM files
WHERE id = $1
`
func (q *Queries) GetFileByUUID(ctx context.Context, id pgtype.UUID) (File, error) {
row := q.db.QueryRow(ctx, getFileByUUID, id)
var i File
err := row.Scan(
&i.ID,
&i.Name,
&i.Description,
&i.Mimetype,
&i.Size,
&i.Blake2,
&i.Created,
&i.Updated,
)
return i, err
}
const updateFileDescription = `-- name: UpdateFileDescription :exec
UPDATE files
SET description = $1
WHERE id = $2
`
type UpdateFileDescriptionParams struct {
Description pgtype.Text
ID pgtype.UUID
}
func (q *Queries) UpdateFileDescription(ctx context.Context, arg UpdateFileDescriptionParams) error {
_, err := q.db.Exec(ctx, updateFileDescription, arg.Description, arg.ID)
return err
}

View file

@ -0,0 +1,63 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
// source: queries-processing_jobs.sql
package sqlc
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const createProcessingJob = `-- name: CreateProcessingJob :one
INSERT INTO processing_jobs (
file_id, job_type
) VALUES ($1,$2 )
RETURNING id, file_id, created, started, completed, status, job_type
`
type CreateProcessingJobParams struct {
FileID pgtype.UUID
JobType pgtype.Text
}
func (q *Queries) CreateProcessingJob(ctx context.Context, arg CreateProcessingJobParams) (ProcessingJob, error) {
row := q.db.QueryRow(ctx, createProcessingJob, arg.FileID, arg.JobType)
var i ProcessingJob
err := row.Scan(
&i.ID,
&i.FileID,
&i.Created,
&i.Started,
&i.Completed,
&i.Status,
&i.JobType,
)
return i, err
}
const finishProcessingJob = `-- name: FinishProcessingJob :exec
UPDATE processing_jobs
SET completed = NOW(),
status = "completed"
WHERE id = $1
`
func (q *Queries) FinishProcessingJob(ctx context.Context, id int32) error {
_, err := q.db.Exec(ctx, finishProcessingJob, id)
return err
}
const startProcessingJob = `-- name: StartProcessingJob :exec
UPDATE processing_jobs
SET started = NOW(),
status = "started"
WHERE id = $1
`
func (q *Queries) StartProcessingJob(ctx context.Context, id int32) error {
_, err := q.db.Exec(ctx, startProcessingJob, id)
return err
}

View file

@ -1,13 +1,10 @@
package store package store
import ( import (
"io"
"log/slog" "log/slog"
"mime/multipart"
"os" "os"
"path/filepath" "path/filepath"
"github.com/google/uuid"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -24,56 +21,54 @@ func SetupStore() {
slog.Info("Initialized File storage directory") slog.Info("Initialized File storage directory")
} }
func SaveFile(file multipart.File) (string, error) { func SaveFile(fileName string, fileBytes []byte) (string, error) {
path, err := filepath.Abs(viper.GetString("store.path")) path, err := filepath.Abs(viper.GetString("store.path"))
if err != nil { if err != nil {
slog.Error("could not save file,", "error", err) slog.Error("could not save file,", "error", err)
return "", err return "", err
} }
fileName, err := uuid.NewRandom()
osFile, err := os.Create(filepath.Join(path, fileName))
if err != nil { if err != nil {
slog.Error("could not save file,", "error", err) slog.Error("could not create file on disk,", "error", err)
return "", err return "", err
} }
osFile, err := os.Create(filepath.Join(path, fileName.String())) defer osFile.Close()
_, err = osFile.Write(fileBytes)
if err != nil { if err != nil {
slog.Error("could not write to file on disk,", "error", err) slog.Error("could not write file content,", "error", err)
return "", err
}
_, err = io.Copy(osFile, file)
if err != nil {
slog.Error("could not save file,", "error", err)
return "", err return "", err
} }
return fileName.String(), nil return fileName, nil
} }
func OpenFile(fileId string) (*os.File, error) { func OpenFile(fileName string) (*os.File, error) {
path, err := filepath.Abs(viper.GetString("store.path")) path, err := filepath.Abs(viper.GetString("store.path"))
if err != nil { if err != nil {
slog.Error("Storage directory not accessible", "error", err) slog.Error("Storage directory not accessible", "error", err)
return nil, err return nil, err
} }
file, err := os.Open(filepath.Join(path, fileId)) file, err := os.Open(filepath.Join(path, fileName))
return file, err return file, err
} }
func DeleteFile(fileId string) error { func DeleteFile(fileName string) error {
path, err := filepath.Abs(viper.GetString("store.path")) path, err := filepath.Abs(viper.GetString("store.path"))
if err != nil { if err != nil {
slog.Error("Storage directory not accessible", "error", err) slog.Error("Storage directory not accessible", "error", err)
return err return err
} }
return os.Remove(path) file := filepath.Join(path, fileName)
return os.Remove(file)
} }
func absPath(fileID string) (string, error) { func absPath(fileName string) (string, error) {
path, err := filepath.Abs(viper.GetString("store.path")) path, err := filepath.Abs(viper.GetString("store.path"))
if err != nil { if err != nil {
slog.Error("could not get full path for file,", "error", err) slog.Error("could not get full path for file,", "error", err)
return "", err return "", err
} }
return path, nil return filepath.Join(path, fileName), nil
} }

View file

@ -1,4 +1,4 @@
/*! tailwindcss v4.1.7 | MIT License | https://tailwindcss.com */ /*! tailwindcss v4.1.8 | MIT License | https://tailwindcss.com */
@layer properties; @layer properties;
@layer theme, base, components, utilities; @layer theme, base, components, utilities;
@layer theme { @layer theme {
@ -8,7 +8,6 @@
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
"Courier New", monospace; "Courier New", monospace;
--color-red-500: oklch(63.7% 0.237 25.331); --color-red-500: oklch(63.7% 0.237 25.331);
--color-amber-100: oklch(96.2% 0.059 95.617);
--color-yellow-400: oklch(85.2% 0.199 91.936); --color-yellow-400: oklch(85.2% 0.199 91.936);
--color-yellow-500: oklch(79.5% 0.184 86.047); --color-yellow-500: oklch(79.5% 0.184 86.047);
--color-green-500: oklch(72.3% 0.219 149.579); --color-green-500: oklch(72.3% 0.219 149.579);
@ -22,6 +21,7 @@
--color-black: #000; --color-black: #000;
--color-white: #fff; --color-white: #fff;
--spacing: 0.25rem; --spacing: 0.25rem;
--container-sm: 24rem;
--text-xs: 0.75rem; --text-xs: 0.75rem;
--text-xs--line-height: calc(1 / 0.75); --text-xs--line-height: calc(1 / 0.75);
--text-sm: 0.875rem; --text-sm: 0.875rem;
@ -39,8 +39,6 @@
--tracking-tight: -0.025em; --tracking-tight: -0.025em;
--tracking-widest: 0.1em; --tracking-widest: 0.1em;
--leading-relaxed: 1.625; --leading-relaxed: 1.625;
--radius-md: calc(var(--radius) - 2px);
--radius-2xl: 1rem;
--ease-in: cubic-bezier(0.4, 0, 1, 1); --ease-in: cubic-bezier(0.4, 0, 1, 1);
--ease-out: cubic-bezier(0, 0, 0.2, 1); --ease-out: cubic-bezier(0, 0, 0.2, 1);
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
@ -247,9 +245,6 @@
.top-0 { .top-0 {
top: calc(var(--spacing) * 0); top: calc(var(--spacing) * 0);
} }
.top-1 {
top: calc(var(--spacing) * 1);
}
.top-1\/2 { .top-1\/2 {
top: calc(1/2 * 100%); top: calc(1/2 * 100%);
} }
@ -271,9 +266,6 @@
.left-0 { .left-0 {
left: calc(var(--spacing) * 0); left: calc(var(--spacing) * 0);
} }
.left-1 {
left: calc(var(--spacing) * 1);
}
.left-1\/2 { .left-1\/2 {
left: calc(1/2 * 100%); left: calc(1/2 * 100%);
} }
@ -475,9 +467,6 @@
.w-0 { .w-0 {
width: calc(var(--spacing) * 0); width: calc(var(--spacing) * 0);
} }
.w-1 {
width: calc(var(--spacing) * 1);
}
.w-1\/2 { .w-1\/2 {
width: calc(1/2 * 100%); width: calc(1/2 * 100%);
} }
@ -487,9 +476,6 @@
.w-1\/4 { .w-1\/4 {
width: calc(1/4 * 100%); width: calc(1/4 * 100%);
} }
.w-2 {
width: calc(var(--spacing) * 2);
}
.w-2\.5 { .w-2\.5 {
width: calc(var(--spacing) * 2.5); width: calc(var(--spacing) * 2.5);
} }
@ -538,6 +524,9 @@
.w-full { .w-full {
width: 100%; width: 100%;
} }
.max-w-sm {
max-width: var(--container-sm);
}
.min-w-0 { .min-w-0 {
min-width: calc(var(--spacing) * 0); min-width: calc(var(--spacing) * 0);
} }
@ -550,12 +539,12 @@
.flex-1 { .flex-1 {
flex: 1; flex: 1;
} }
.flex-shrink {
flex-shrink: 1;
}
.flex-shrink-0 { .flex-shrink-0 {
flex-shrink: 0; flex-shrink: 0;
} }
.shrink {
flex-shrink: 1;
}
.shrink-0 { .shrink-0 {
flex-shrink: 0; flex-shrink: 0;
} }
@ -568,13 +557,6 @@
.caption-bottom { .caption-bottom {
caption-side: bottom; caption-side: bottom;
} }
.border-collapse {
border-collapse: collapse;
}
.-translate-x-1 {
--tw-translate-x: calc(var(--spacing) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.-translate-x-1\/2 { .-translate-x-1\/2 {
--tw-translate-x: calc(calc(1/2 * 100%) * -1); --tw-translate-x: calc(calc(1/2 * 100%) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y); translate: var(--tw-translate-x) var(--tw-translate-y);
@ -591,10 +573,6 @@
--tw-translate-x: 100%; --tw-translate-x: 100%;
translate: var(--tw-translate-x) var(--tw-translate-y); translate: var(--tw-translate-x) var(--tw-translate-y);
} }
.-translate-y-1 {
--tw-translate-y: calc(var(--spacing) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y);
}
.-translate-y-1\/2 { .-translate-y-1\/2 {
--tw-translate-y: calc(calc(1/2 * 100%) * -1); --tw-translate-y: calc(calc(1/2 * 100%) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y); translate: var(--tw-translate-x) var(--tw-translate-y);
@ -631,6 +609,9 @@
--tw-scale-z: 100%; --tw-scale-z: 100%;
scale: var(--tw-scale-x) var(--tw-scale-y); scale: var(--tw-scale-x) var(--tw-scale-y);
} }
.scale-3d {
scale: var(--tw-scale-x) var(--tw-scale-y) var(--tw-scale-z);
}
.rotate-45 { .rotate-45 {
rotate: 45deg; rotate: 45deg;
} }
@ -664,6 +645,15 @@
.appearance-none { .appearance-none {
appearance: none; appearance: none;
} }
.columns-2 {
columns: 2;
}
.columns-3 {
columns: 3;
}
.columns-4 {
columns: 4;
}
.grid-cols-7 { .grid-cols-7 {
grid-template-columns: repeat(7, minmax(0, 1fr)); grid-template-columns: repeat(7, minmax(0, 1fr));
} }
@ -703,12 +693,8 @@
.gap-2 { .gap-2 {
gap: calc(var(--spacing) * 2); gap: calc(var(--spacing) * 2);
} }
.space-y-1 { .gap-4 {
:where(& > :not(:last-child)) { gap: calc(var(--spacing) * 4);
--tw-space-y-reverse: 0;
margin-block-start: calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));
margin-block-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)));
}
} }
.space-y-1\.5 { .space-y-1\.5 {
:where(& > :not(:last-child)) { :where(& > :not(:last-child)) {
@ -803,9 +789,6 @@
.rounded { .rounded {
border-radius: 0.25rem; border-radius: 0.25rem;
} }
.rounded-2xl {
border-radius: var(--radius-2xl);
}
.rounded-full { .rounded-full {
border-radius: calc(infinity * 1px); border-radius: calc(infinity * 1px);
} }
@ -878,10 +861,6 @@
--tw-border-style: dotted; --tw-border-style: dotted;
border-style: dotted; border-style: dotted;
} }
.border-solid {
--tw-border-style: solid;
border-style: solid;
}
.border-border { .border-border {
border-color: var(--border); border-color: var(--border);
} }
@ -924,9 +903,6 @@
background-color: color-mix(in oklab, var(--background) 80%, transparent); background-color: color-mix(in oklab, var(--background) 80%, transparent);
} }
} }
.bg-black {
background-color: var(--color-black);
}
.bg-black\/20 { .bg-black\/20 {
background-color: color-mix(in srgb, #000 20%, transparent); background-color: color-mix(in srgb, #000 20%, transparent);
@supports (color: color-mix(in lab, red, red)) { @supports (color: color-mix(in lab, red, red)) {
@ -1029,9 +1005,6 @@
.px-5 { .px-5 {
padding-inline: calc(var(--spacing) * 5); padding-inline: calc(var(--spacing) * 5);
} }
.py-0 {
padding-block: calc(var(--spacing) * 0);
}
.py-0\.5 { .py-0\.5 {
padding-block: calc(var(--spacing) * 0.5); padding-block: calc(var(--spacing) * 0.5);
} }
@ -1144,9 +1117,6 @@
.text-background { .text-background {
color: var(--background); color: var(--background);
} }
.text-black {
color: var(--color-black);
}
.text-blue-500 { .text-blue-500 {
color: var(--color-blue-500); color: var(--color-blue-500);
} }
@ -1195,6 +1165,9 @@
.text-yellow-500 { .text-yellow-500 {
color: var(--color-yellow-500); color: var(--color-yellow-500);
} }
.italic {
font-style: italic;
}
.underline { .underline {
text-decoration-line: underline; text-decoration-line: underline;
} }
@ -1263,10 +1236,6 @@
-webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,); -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,); backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
} }
.backdrop-filter {
-webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
}
.transition { .transition {
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, visibility, content-visibility, overlay, pointer-events; transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, visibility, content-visibility, overlay, pointer-events;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));

View file

@ -11,7 +11,7 @@ templ Base(title string) {
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8"/> <meta charset="utf-8"/>
<title>{title}</title> <title>{title}</title>
<link rel="stylesheet" href="/assets/terminal.css"/> <link rel="stylesheet" href="/assets/styles.css"/>
</head> </head>
<body> <body>
<header> <header>

View file

@ -46,7 +46,7 @@ func Base(title string) templ.Component {
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</title><link rel=\"stylesheet\" href=\"/assets/terminal.css\"></head><body><header>") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</title><link rel=\"stylesheet\" href=\"/assets/styles.css\"></head><body><header>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }

View file

@ -10,7 +10,7 @@ import (
func FileViewWebHandler(w http.ResponseWriter, r *http.Request) { func FileViewWebHandler(w http.ResponseWriter, r *http.Request) {
file, err := database.FileByUUID(r.PathValue("uuid")) file, err := database.FileByUUID(r.PathValue("uuid"))
if err != nil { if err != nil {
slog.Error("Error getting File in FileViewWebHandler", "error", err, "id", r.PathValue("uuid")) slog.Error("Error getting File in FileViewWebHandler", "error", err, "file-uuid", r.PathValue("uuid"))
http.Error(w, err.Error(), http.StatusBadRequest) http.Error(w, err.Error(), http.StatusBadRequest)
} }
component := FileView(file) component := FileView(file)

View file

@ -1,7 +1,7 @@
package web package web
import ( import (
"fmt" "io"
"log/slog" "log/slog"
"net/http" "net/http"
@ -15,6 +15,7 @@ func IndexWebHandler(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
slog.Error("Error rendering in IndexWebHandler", "error", err) slog.Error("Error rendering in IndexWebHandler", "error", err)
http.Error(w, err.Error(), http.StatusBadRequest) http.Error(w, err.Error(), http.StatusBadRequest)
return
} }
} }
@ -32,12 +33,28 @@ func IndexUploadHandler(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
slog.Error("Error parsing form in IndexUploadHandler", "error", err) slog.Error("Error parsing form in IndexUploadHandler", "error", err)
http.Error(w, err.Error(), http.StatusBadRequest) http.Error(w, err.Error(), http.StatusBadRequest)
return
} }
file, err := database.CreateFile(fileHeader.Filename, fileData, fileHeader.Size) fileBytes, err := io.ReadAll(fileData)
if err != nil {
slog.Error("Error reading file in IndexUploadHandler", "error", err)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
fileSize := len(fileBytes)
file, err := database.CreateFile(fileHeader.Filename, fileBytes, int64(fileSize))
if err != nil { if err != nil {
slog.Error("Error saving file in IndexUploadHandler", "error", err) slog.Error("Error saving file in IndexUploadHandler", "error", err)
http.Error(w, err.Error(), http.StatusBadRequest) http.Error(w, err.Error(), http.StatusBadRequest)
return
} }
http.Redirect(w, r, fmt.Sprintf("/files/%s", file.Uuid), http.StatusSeeOther)
component := UploadSuccessCard(file)
err = component.Render(r.Context(), w)
if err != nil {
slog.Error("Error rendering in IndexUploadHandler", "error", err)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
} }

View file

@ -1,18 +1,78 @@
package web package web
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/card"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/input"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/form"
"git.jmbit.de/jmb/scanfile/server/internal/database"
"fmt"
)
templ Index() { templ Index() {
@Base("Scanfile") { @Base("Scanfile") {
<div class="w-full max-w-sm">
<div id="uploadForm"> @UploadCard()
<form id='form' hx-encoding='multipart/form-data' hx-post='/upload'>
<input type='file' name='file'>
<button class="button">
Upload
</button>
</form>
</div> </div>
} }
} }
templ UploadCard() {
@card.Card(card.Props{ID: "upload-card"}) {
@card.Header() {
@card.Title() {
Upload File
}
}
@card.Content() {
<form class="flex flex-col gap-4" hx-encoding='multipart/form-data' hx-post='/upload' hx-target="#upload-card">
@form.Item() {
<div class="w-full max-w-sm grid gap-2">
@form.Label(form.LabelProps{
For: "file",
}) {
File
}
@input.Input(input.Props{
ID: "file",
Name: "file",
Type: input.TypeFile,
})
</div>
}
@form.Item() {
@button.Button(button.Props{Type: button.TypeSubmit}) {
Submit
}
}
</form>
}
}
}
templ UploadSuccessCard(file database.File) {
@card.Card(card.Props{ID: "upload-card"}) {
@card.Header() {
@card.Title() {
Upload Successful
}
@card.Description() {
Name: { file.Name }
}
}
@card.Content() {
<div class="flex flex-col gap-4" hx-encoding='multipart/form-data' hx-post='/upload'>
<p> ID: { file.Uuid } </p>
<p> Size: { file.Size } Bytes</p>
@button.Button(button.Props{Type: button.TypeButton, Href: fmt.Sprintf("/files/%s", file.Uuid)}) {
Go to file
}
</div>
}
}
}

View file

@ -8,6 +8,15 @@ package web
import "github.com/a-h/templ" import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime" import templruntime "github.com/a-h/templ/runtime"
import (
"fmt"
"git.jmbit.de/jmb/scanfile/server/internal/database"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/card"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/form"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/input"
)
func Index() templ.Component { func Index() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
@ -41,7 +50,15 @@ func Index() templ.Component {
}() }()
} }
ctx = templ.InitializeContext(ctx) ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div id=\"uploadForm\"><form id=\"form\" hx-encoding=\"multipart/form-data\" hx-post=\"/upload\"><input type=\"file\" name=\"file\"> <button class=\"button\">Upload</button></form></div>") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"w-full max-w-sm\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = UploadCard().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</div>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
@ -55,4 +72,411 @@ func Index() templ.Component {
}) })
} }
func UploadCard() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var4 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "Upload File")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = card.Title().Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = card.Header().Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var7 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<form class=\"flex flex-col gap-4\" hx-encoding=\"multipart/form-data\" hx-post=\"/upload\" hx-target=\"#upload-card\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var8 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<div class=\"w-full max-w-sm grid gap-2\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var9 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "File")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = form.Label(form.LabelProps{
For: "file",
}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var9), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = input.Input(input.Props{
ID: "file",
Name: "file",
Type: input.TypeFile,
}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = form.Item().Render(templ.WithChildren(ctx, templ_7745c5c3_Var8), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var10 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var11 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "Submit")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = button.Button(button.Props{Type: button.TypeSubmit}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var11), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = form.Item().Render(templ.WithChildren(ctx, templ_7745c5c3_Var10), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</form>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = card.Content().Render(templ.WithChildren(ctx, templ_7745c5c3_Var7), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = card.Card(card.Props{ID: "upload-card"}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var4), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func UploadSuccessCard(file database.File) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var12 := templ.GetChildren(ctx)
if templ_7745c5c3_Var12 == nil {
templ_7745c5c3_Var12 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var13 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var14 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var15 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "Upload Successful")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = card.Title().Render(templ.WithChildren(ctx, templ_7745c5c3_Var15), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var16 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "Name: ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(file.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/index.templ`, Line: 62, Col: 27}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = card.Description().Render(templ.WithChildren(ctx, templ_7745c5c3_Var16), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = card.Header().Render(templ.WithChildren(ctx, templ_7745c5c3_Var14), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var18 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<div class=\"flex flex-col gap-4\" hx-encoding=\"multipart/form-data\" hx-post=\"/upload\"><p>ID: ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var19 string
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(file.Uuid)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/index.templ`, Line: 68, Col: 30}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</p><p>Size: ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var20 string
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(file.Size)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/index.templ`, Line: 69, Col: 30}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, " Bytes</p>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var21 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "Go to file")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = button.Button(button.Props{Type: button.TypeButton, Href: fmt.Sprintf("/files/%s", file.Uuid)}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var21), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = card.Content().Render(templ.WithChildren(ctx, templ_7745c5c3_Var18), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = card.Card(card.Props{ID: "upload-card"}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var13), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,126 @@
// templui component accordion - version: main installed by templui v0.71.0
package accordion
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
type ItemProps struct {
ID string
Class string
Attributes templ.Attributes
}
type TriggerProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ContentProps struct {
ID string
Class string
Attributes templ.Attributes
}
templ Accordion(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"divide-y rounded-md divide-border border",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
templ Item(props ...ItemProps) {
{{ var p ItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<details
if p.ID != "" {
id={ p.ID }
}
name="accordion"
class={
utils.TwMerge(
"group",
"open:[&>summary_svg]:rotate-180",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</details>
}
templ Trigger(props ...TriggerProps) {
{{ var p TriggerProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<summary
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex w-full items-center justify-between py-4 px-5",
"text-left font-medium cursor-pointer",
"transition-all hover:underline",
"list-none [&::-webkit-details-marker]:hidden",
p.Class,
),
}
{ p.Attributes... }
>
<div class="flex-1">
{ children... }
</div>
@icon.ChevronDown(icon.Props{
Size: 16,
Class: "transition-transform",
})
</summary>
}
templ Content(props ...ContentProps) {
{{ var p ContentProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"px-5 pb-4 pt-0",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}

View file

@ -0,0 +1,437 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component accordion - version: main installed by templui v0.71.0
package accordion
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
type ItemProps struct {
ID string
Class string
Attributes templ.Attributes
}
type TriggerProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ContentProps struct {
ID string
Class string
Attributes templ.Attributes
}
func Accordion(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"divide-y rounded-md divide-border border",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/accordion/accordion.templ`, Line: 40, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/accordion/accordion.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Item(props ...ItemProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p ItemProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var6 = []any{
utils.TwMerge(
"group",
"open:[&>summary_svg]:rotate-180",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<details")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/accordion/accordion.templ`, Line: 61, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " name=\"accordion\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/accordion/accordion.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var5.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</details>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Trigger(props ...TriggerProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
if templ_7745c5c3_Var9 == nil {
templ_7745c5c3_Var9 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p TriggerProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var10 = []any{
utils.TwMerge(
"flex w-full items-center justify-between py-4 px-5",
"text-left font-medium cursor-pointer",
"transition-all hover:underline",
"list-none [&::-webkit-details-marker]:hidden",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<summary")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/accordion/accordion.templ`, Line: 84, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var10).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/accordion/accordion.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "><div class=\"flex-1\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var9.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = icon.ChevronDown(icon.Props{
Size: 16,
Class: "transition-transform",
}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "</summary>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Content(props ...ContentProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var13 := templ.GetChildren(ctx)
if templ_7745c5c3_Var13 == nil {
templ_7745c5c3_Var13 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p ContentProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var14 = []any{
utils.TwMerge(
"px-5 pb-4 pt-0",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/accordion/accordion.templ`, Line: 114, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var14).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/accordion/accordion.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var13.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,107 @@
// templui component alert - version: main installed by templui v0.71.0
package alert
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Variant string
const (
VariantDefault Variant = "default"
VariantDestructive Variant = "destructive"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Variant Variant
}
type TitleProps struct {
ID string
Class string
Attributes templ.Attributes
}
type DescriptionProps struct {
ID string
Class string
Attributes templ.Attributes
}
templ Alert(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"relative w-full p-4",
"[&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4",
"[&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11",
"rounded-lg border",
variantClasses(p.Variant),
p.Class,
),
}
role="alert"
{ p.Attributes... }
>
{ children... }
</div>
}
templ Title(props ...TitleProps) {
{{ var p TitleProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<h5
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"mb-1 font-medium leading-none tracking-tight",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</h5>
}
templ Description(props ...DescriptionProps) {
{{ var p DescriptionProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"[&_p]:leading-relaxed text-sm",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
func variantClasses(variant Variant) string {
switch variant {
case VariantDestructive:
return "border-destructive text-destructive"
default:
return "border-border text-foreground"
}
}

View file

@ -0,0 +1,339 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component alert - version: main installed by templui v0.71.0
package alert
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Variant string
const (
VariantDefault Variant = "default"
VariantDestructive Variant = "destructive"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Variant Variant
}
type TitleProps struct {
ID string
Class string
Attributes templ.Attributes
}
type DescriptionProps struct {
ID string
Class string
Attributes templ.Attributes
}
func Alert(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"relative w-full p-4",
"[&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4",
"[&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11",
"rounded-lg border",
variantClasses(p.Variant),
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/alert/alert.templ`, Line: 39, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/alert/alert.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" role=\"alert\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Title(props ...TitleProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p TitleProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var6 = []any{
utils.TwMerge(
"mb-1 font-medium leading-none tracking-tight",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<h5")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/alert/alert.templ`, Line: 65, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/alert/alert.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var5.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</h5>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Description(props ...DescriptionProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
if templ_7745c5c3_Var9 == nil {
templ_7745c5c3_Var9 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p DescriptionProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var10 = []any{
utils.TwMerge(
"[&_p]:leading-relaxed text-sm",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/alert/alert.templ`, Line: 86, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var10).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/alert/alert.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var9.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func variantClasses(variant Variant) string {
switch variant {
case VariantDestructive:
return "border-destructive text-destructive"
default:
return "border-border text-foreground"
}
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,60 @@
// templui component aspectratio - version: main installed by templui v0.71.0
package aspectratio
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Ratio string
const (
RatioAuto Ratio = "auto"
RatioSquare Ratio = "square"
RatioVideo Ratio = "video"
RatioPortrait Ratio = "portrait"
RatioWide Ratio = "wide"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Ratio Ratio
}
templ AspectRatio(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"relative w-full",
ratioClass(p.Ratio),
p.Class,
),
}
{ p.Attributes... }
>
<div class="absolute inset-0">
{ children... }
</div>
</div>
}
func ratioClass(ratio Ratio) string {
switch ratio {
case RatioSquare:
return "aspect-square"
case RatioVideo:
return "aspect-video"
case RatioPortrait:
return "aspect-[3/4]"
case RatioWide:
return "aspect-[2/1]"
default:
return "aspect-square"
}
}

View file

@ -0,0 +1,143 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component aspectratio - version: main installed by templui v0.71.0
package aspectratio
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Ratio string
const (
RatioAuto Ratio = "auto"
RatioSquare Ratio = "square"
RatioVideo Ratio = "video"
RatioPortrait Ratio = "portrait"
RatioWide Ratio = "wide"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Ratio Ratio
}
func AspectRatio(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"relative w-full",
ratioClass(p.Ratio),
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/aspectratio/aspect_ratio.templ`, Line: 30, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/aspectratio/aspect_ratio.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "><div class=\"absolute inset-0\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func ratioClass(ratio Ratio) string {
switch ratio {
case RatioSquare:
return "aspect-square"
case RatioVideo:
return "aspect-video"
case RatioPortrait:
return "aspect-[3/4]"
case RatioWide:
return "aspect-[2/1]"
default:
return "aspect-square"
}
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,291 @@
// templui component avatar - version: main installed by templui v0.71.0
package avatar
import (
"fmt"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
"strings"
)
type Size string
type GroupSpacing string
const (
SizeSm Size = "sm"
SizeMd Size = "md"
SizeLg Size = "lg"
)
const (
GroupSpacingSm GroupSpacing = "sm"
GroupSpacingMd GroupSpacing = "medium"
GroupSpacingLg GroupSpacing = "large"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Size Size
InGroup bool
}
type ImageProps struct {
ID string
Class string
Attributes templ.Attributes
Alt string
Src string
}
type FallbackProps struct {
ID string
Class string
Attributes templ.Attributes
}
type GroupProps struct {
ID string
Class string
Attributes templ.Attributes
Spacing GroupSpacing
}
templ Avatar(props ...Props) {
@Script()
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
data-avatar
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"inline-flex items-center justify-center",
SizeClasses(p.Size),
"rounded-full bg-muted",
utils.If(p.InGroup, "ring-2 ring-background"),
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
templ Image(props ...ImageProps) {
{{ var p ImageProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<img
data-avatar-image
if p.ID != "" {
id={ p.ID }
}
if p.Src != "" {
src={ p.Src }
}
alt={ avatarAlt(p) }
class={
utils.TwMerge(
"w-full h-full",
"rounded-full object-cover",
p.Class,
),
}
{ p.Attributes... }
/>
}
templ Fallback(props ...FallbackProps) {
{{ var p FallbackProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
data-avatar-fallback
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"font-medium text-muted-foreground",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</span>
}
templ Group(props ...GroupProps) {
{{ var p GroupProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center -space-x-3",
groupSpacingClasses(p.Spacing),
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
templ GroupOverflow(count int, props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"inline-flex items-center justify-center",
SizeClasses(p.Size),
"rounded-full bg-muted ring-2 ring-background",
p.Class,
),
}
{ p.Attributes... }
>
<span class="text-xs font-medium">+{ fmt.Sprint(count) }</span>
</div>
}
func SizeClasses(size Size) string {
switch size {
case SizeSm:
return "w-8 h-8 text-xs"
case SizeLg:
return "w-16 h-16 text-xl"
default: // SizeMd
return "w-12 h-12 text-base"
}
}
func Initials(name string) string {
parts := strings.Fields(name)
initials := ""
for i, part := range parts {
if i > 1 {
break
}
if len(part) > 0 {
initials += string(part[0])
}
}
return strings.ToUpper(initials)
}
func groupSpacingClasses(spacing GroupSpacing) string {
switch spacing {
case GroupSpacingSm:
return "-space-x-1"
case GroupSpacingLg:
return "-space-x-4"
default: // GroupSpacingMd
return "-space-x-2"
}
}
func avatarAlt(p ImageProps) string {
if p.Alt != "" {
return p.Alt
}
if p.ID != "" {
return fmt.Sprintf("Avatar of %s", p.ID)
}
if p.Src != "" {
return "User avatar"
}
return ""
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<script defer nonce={ templ.GetNonce(ctx) }>
(function() { // IIFE
function initAvatar(avatar) {
const image = avatar.querySelector('[data-avatar-image]');
const fallback = avatar.querySelector('[data-avatar-fallback]');
if (image && fallback) {
image.style.display = 'none';
fallback.style.display = 'none';
const showFallback = () => {
image.style.display = 'none';
fallback.style.display = '';
};
const showImage = () => {
image.style.display = '';
fallback.style.display = 'none';
};
if (image.complete) {
image.naturalWidth > 0 && image.naturalHeight > 0 ? showImage() : showFallback();
} else {
image.addEventListener('load', showImage, { once: true });
image.addEventListener('error', showFallback, { once: true });
setTimeout(() => {
if (image.complete && !(image.naturalWidth > 0 && image.naturalHeight > 0)) {
showFallback();
}
}, 50);
}
} else if (fallback) {
fallback.style.display = '';
} else if (image) {
image.style.display = '';
}
}
function initAllComponents(root = document) {
if (root instanceof Element && root.matches('[data-avatar]')) {
initAvatar(root);
}
for (const avatar of root.querySelectorAll('[data-avatar]')) {
initAvatar(avatar);
}
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})(); // End of IIFE
</script>
}
}

View file

@ -0,0 +1,692 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component avatar - version: main installed by templui v0.71.0
package avatar
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"fmt"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
"strings"
)
type Size string
type GroupSpacing string
const (
SizeSm Size = "sm"
SizeMd Size = "md"
SizeLg Size = "lg"
)
const (
GroupSpacingSm GroupSpacing = "sm"
GroupSpacingMd GroupSpacing = "medium"
GroupSpacingLg GroupSpacing = "large"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Size Size
InGroup bool
}
type ImageProps struct {
ID string
Class string
Attributes templ.Attributes
Alt string
Src string
}
type FallbackProps struct {
ID string
Class string
Attributes templ.Attributes
}
type GroupProps struct {
ID string
Class string
Attributes templ.Attributes
Spacing GroupSpacing
}
func Avatar(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = Script().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"inline-flex items-center justify-center",
SizeClasses(p.Size),
"rounded-full bg-muted",
utils.If(p.InGroup, "ring-2 ring-background"),
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div data-avatar")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 63, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Image(props ...ImageProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p ImageProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var6 = []any{
utils.TwMerge(
"w-full h-full",
"rounded-full object-cover",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<img data-avatar-image")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 88, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Src != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " src=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(p.Src)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 91, Col: 14}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, " alt=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(avatarAlt(p))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 93, Col: 20}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Fallback(props ...FallbackProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var11 := templ.GetChildren(ctx)
if templ_7745c5c3_Var11 == nil {
templ_7745c5c3_Var11 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p FallbackProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var12 = []any{
utils.TwMerge(
"font-medium text-muted-foreground",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<span data-avatar-fallback")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 113, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var12).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var11.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Group(props ...GroupProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var15 := templ.GetChildren(ctx)
if templ_7745c5c3_Var15 == nil {
templ_7745c5c3_Var15 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p GroupProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var16 = []any{
utils.TwMerge(
"flex items-center -space-x-3",
groupSpacingClasses(p.Spacing),
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 134, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var16).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var15.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func GroupOverflow(count int, props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var19 := templ.GetChildren(ctx)
if templ_7745c5c3_Var19 == nil {
templ_7745c5c3_Var19 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var20 = []any{
utils.TwMerge(
"inline-flex items-center justify-center",
SizeClasses(p.Size),
"rounded-full bg-muted ring-2 ring-background",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var21 string
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 156, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var22 string
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var20).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "><span class=\"text-xs font-medium\">+")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var23 string
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprint(count))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 168, Col: 56}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "</span></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func SizeClasses(size Size) string {
switch size {
case SizeSm:
return "w-8 h-8 text-xs"
case SizeLg:
return "w-16 h-16 text-xl"
default: // SizeMd
return "w-12 h-12 text-base"
}
}
func Initials(name string) string {
parts := strings.Fields(name)
initials := ""
for i, part := range parts {
if i > 1 {
break
}
if len(part) > 0 {
initials += string(part[0])
}
}
return strings.ToUpper(initials)
}
func groupSpacingClasses(spacing GroupSpacing) string {
switch spacing {
case GroupSpacingSm:
return "-space-x-1"
case GroupSpacingLg:
return "-space-x-4"
default: // GroupSpacingMd
return "-space-x-2"
}
}
func avatarAlt(p ImageProps) string {
if p.Alt != "" {
return p.Alt
}
if p.ID != "" {
return fmt.Sprintf("Avatar of %s", p.ID)
}
if p.Src != "" {
return "User avatar"
}
return ""
}
var handle = templ.NewOnceHandle()
func Script() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var24 := templ.GetChildren(ctx)
if templ_7745c5c3_Var24 == nil {
templ_7745c5c3_Var24 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var25 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "<script defer nonce=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var26 string
templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(templ.GetNonce(ctx))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/avatar/avatar.templ`, Line: 228, Col: 43}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "\">\n\t\t\t(function() { // IIFE\n\t\t\t\tfunction initAvatar(avatar) {\n\t\t\t\t\tconst image = avatar.querySelector('[data-avatar-image]');\n\t\t\t\t\tconst fallback = avatar.querySelector('[data-avatar-fallback]');\n\n\t\t\t\t\tif (image && fallback) {\n\t\t\t\t\t\timage.style.display = 'none';\n\t\t\t\t\t\tfallback.style.display = 'none';\n\n\t\t\t\t\t\tconst showFallback = () => {\n\t\t\t\t\t\t\timage.style.display = 'none';\n\t\t\t\t\t\t\tfallback.style.display = '';\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst showImage = () => {\n\t\t\t\t\t\t\timage.style.display = '';\n\t\t\t\t\t\t\tfallback.style.display = 'none';\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tif (image.complete) {\n\t\t\t\t\t\t\timage.naturalWidth > 0 && image.naturalHeight > 0 ? showImage() : showFallback();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\timage.addEventListener('load', showImage, { once: true });\n\t\t\t\t\t\t\timage.addEventListener('error', showFallback, { once: true });\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\t\tif (image.complete && !(image.naturalWidth > 0 && image.naturalHeight > 0)) {\n\t\t\t\t\t\t\t\t\tshowFallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}, 50);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (fallback) {\n\t\t\t\t\t\tfallback.style.display = '';\n\t\t\t\t\t} else if (image) {\n\t\t\t\t\t\timage.style.display = '';\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfunction initAllComponents(root = document) {\n\t\t\t\t\tif (root instanceof Element && root.matches('[data-avatar]')) {\n\t\t\t\t\t\tinitAvatar(root);\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (const avatar of root.querySelectorAll('[data-avatar]')) {\n\t\t\t\t\t\tinitAvatar(avatar);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst handleHtmxSwap = (event) => {\n\t\t\t\t\tconst target = event.detail.target || event.detail.elt;\n\t\t\t\t\tif (target instanceof Element) {\n\t\t\t\t\t\trequestAnimationFrame(() => initAllComponents(target));\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tinitAllComponents();\n\t\t\t\tdocument.addEventListener('DOMContentLoaded', () => initAllComponents());\n\t\t\t\tdocument.body.addEventListener('htmx:afterSwap', handleHtmxSwap);\n\t\t\t\tdocument.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);\n\t\t\t})(); // End of IIFE\n\t\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = handle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var25), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,57 @@
// templui component badge - version: main installed by templui v0.71.0
package badge
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Variant string
const (
VariantDefault Variant = "default"
VariantSecondary Variant = "secondary"
VariantDestructive Variant = "destructive"
VariantOutline Variant = "outline"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Variant Variant
}
templ Badge(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"inline-flex items-center gap-2",
"rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors",
"focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2",
p.variantClasses(),
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
func (p Props) variantClasses() string {
switch p.Variant {
case VariantDestructive:
return "border-transparent bg-destructive text-destructive-foreground"
case VariantOutline:
return "text-foreground border-border"
case VariantSecondary:
return "border-transparent bg-secondary text-secondary-foreground"
default:
return "border-transparent bg-primary text-primary-foreground"
}
}

View file

@ -0,0 +1,142 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component badge - version: main installed by templui v0.71.0
package badge
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Variant string
const (
VariantDefault Variant = "default"
VariantSecondary Variant = "secondary"
VariantDestructive Variant = "destructive"
VariantOutline Variant = "outline"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Variant Variant
}
func Badge(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"inline-flex items-center gap-2",
"rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors",
"focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2",
p.variantClasses(),
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/badge/badge.templ`, Line: 29, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/badge/badge.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func (p Props) variantClasses() string {
switch p.Variant {
case VariantDestructive:
return "border-transparent bg-destructive text-destructive-foreground"
case VariantOutline:
return "text-foreground border-border"
case VariantSecondary:
return "border-transparent bg-secondary text-secondary-foreground"
default:
return "border-transparent bg-primary text-primary-foreground"
}
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,175 @@
// templui component breadcrumb - version: main installed by templui v0.71.0
package breadcrumb
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
type ListProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ItemProps struct {
ID string
Class string
Attributes templ.Attributes
Current bool
}
type LinkProps struct {
ID string
Class string
Attributes templ.Attributes
Href string
}
type SeparatorProps struct {
ID string
Class string
Attributes templ.Attributes
UseCustom bool
}
templ Breadcrumb(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<nav
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex",
p.Class,
),
}
aria-label="Breadcrumb"
{ p.Attributes... }
>
{ children... }
</nav>
}
templ List(props ...ListProps) {
{{ var p ListProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<ol
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center flex-wrap gap-1 text-sm",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</ol>
}
templ Item(props ...ItemProps) {
{{ var p ItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<li
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</li>
}
templ Link(props ...LinkProps) {
{{ var p LinkProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<a
if p.ID != "" {
id={ p.ID }
}
if p.Href != "" {
href={ templ.SafeURL(p.Href) }
}
class={
utils.TwMerge(
"text-muted-foreground hover:text-foreground hover:underline flex items-center gap-1.5 transition-colors",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</a>
}
templ Separator(props ...SeparatorProps) {
{{ var p SeparatorProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"mx-2 text-muted-foreground",
p.Class,
),
}
{ p.Attributes... }
>
if p.UseCustom {
{ children... }
} else {
@icon.ChevronRight(icon.Props{Size: 14, Class: "text-muted-foreground"})
}
</span>
}
templ Page(props ...ItemProps) {
{{ var p ItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"font-medium text-foreground flex items-center gap-1.5",
p.Class,
),
}
aria-current="page"
{ p.Attributes... }
>
{ children... }
</span>
}

View file

@ -0,0 +1,643 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component breadcrumb - version: main installed by templui v0.71.0
package breadcrumb
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
type ListProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ItemProps struct {
ID string
Class string
Attributes templ.Attributes
Current bool
}
type LinkProps struct {
ID string
Class string
Attributes templ.Attributes
Href string
}
type SeparatorProps struct {
ID string
Class string
Attributes templ.Attributes
UseCustom bool
}
func Breadcrumb(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"flex",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<nav")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 49, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" aria-label=\"Breadcrumb\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</nav>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func List(props ...ListProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p ListProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var6 = []any{
utils.TwMerge(
"flex items-center flex-wrap gap-1 text-sm",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<ol")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 71, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var5.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</ol>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Item(props ...ItemProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
if templ_7745c5c3_Var9 == nil {
templ_7745c5c3_Var9 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p ItemProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var10 = []any{
utils.TwMerge(
"flex items-center",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<li")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 92, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var10).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var9.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</li>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Link(props ...LinkProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var13 := templ.GetChildren(ctx)
if templ_7745c5c3_Var13 == nil {
templ_7745c5c3_Var13 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p LinkProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var14 = []any{
utils.TwMerge(
"text-muted-foreground hover:text-foreground hover:underline flex items-center gap-1.5 transition-colors",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "<a")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 113, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Href != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, " href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 templ.SafeURL = templ.SafeURL(p.Href)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var16)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var14).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var13.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "</a>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Separator(props ...SeparatorProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var18 := templ.GetChildren(ctx)
if templ_7745c5c3_Var18 == nil {
templ_7745c5c3_Var18 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p SeparatorProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var19 = []any{
utils.TwMerge(
"mx-2 text-muted-foreground",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var19...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "<span")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var20 string
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 137, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var21 string
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var19).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.UseCustom {
templ_7745c5c3_Err = templ_7745c5c3_Var18.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
templ_7745c5c3_Err = icon.ChevronRight(icon.Props{Size: 14, Class: "text-muted-foreground"}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Page(props ...ItemProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var22 := templ.GetChildren(ctx)
if templ_7745c5c3_Var22 == nil {
templ_7745c5c3_Var22 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p ItemProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var23 = []any{
utils.TwMerge(
"font-medium text-foreground flex items-center gap-1.5",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var23...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "<span")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var24 string
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 162, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var25 string
templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var23).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "\" aria-current=\"page\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var22.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,169 @@
// templui component button - version: main installed by templui v0.71.0
package button
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
"strings"
)
type Variant string
type Size string
type Type string
const (
VariantDefault Variant = "default"
VariantDestructive Variant = "destructive"
VariantOutline Variant = "outline"
VariantSecondary Variant = "secondary"
VariantGhost Variant = "ghost"
VariantLink Variant = "link"
)
const (
TypeButton Type = "button"
TypeReset Type = "reset"
TypeSubmit Type = "submit"
)
const (
SizeIcon Size = "icon"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Variant Variant
Size Size
FullWidth bool
Href string
Target string
Disabled bool
Type Type
HxGet string
HxPost string
HxPut string
HxDelete string
HxTrigger string
HxTarget string
HxSwap string
HxReplaceUrl string
}
templ Button(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.Type == "" {
{{ p.Type = TypeButton }}
}
if p.Href != "" && !p.Disabled {
<a
if p.ID != "" {
id={ p.ID }
}
href={ templ.SafeURL(p.Href) }
if p.Target != "" {
target={ p.Target }
}
class={
utils.TwMerge(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors",
"focus-visible:outline-hidden focus-visible:ring-2 focus:ring-ring focus-visible:ring-offset-2",
"cursor-pointer",
p.variantClasses(),
p.sizeClasses(),
p.modifierClasses(),
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</a>
} else {
<button
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors",
"focus-visible:outline-hidden focus-visible:ring-2 focus:ring-ring focus-visible:ring-offset-2",
"disabled:opacity-50 disabled:cursor-not-allowed",
"cursor-pointer",
p.variantClasses(),
p.sizeClasses(),
p.modifierClasses(),
p.Class,
),
}
if p.Type != "" {
type={ string(p.Type) }
}
disabled?={ p.Disabled }
if p.HxGet != "" {
hx-get={ p.HxGet }
}
if p.HxPost != "" {
hx-post={ p.HxPost }
}
if p.HxPut != "" {
hx-put={ p.HxPut }
}
if p.HxDelete != "" {
hx-delete={ p.HxDelete }
}
if p.HxTrigger != "" {
hx-trigger={ p.HxTrigger }
}
if p.HxTarget != "" {
hx-target={ p.HxTarget }
}
if p.HxSwap != "" {
hx-swap={ p.HxSwap }
}
if p.HxReplaceUrl != "" {
hx-replace-url={ p.HxReplaceUrl }
}
{ p.Attributes... }
>
{ children... }
</button>
}
}
func (b Props) variantClasses() string {
switch b.Variant {
case VariantDestructive:
return "bg-destructive text-destructive-foreground hover:bg-destructive/90"
case VariantOutline:
return "border border-input bg-background hover:bg-accent hover:text-accent-foreground"
case VariantSecondary:
return "bg-secondary text-secondary-foreground hover:bg-secondary/80"
case VariantGhost:
return "hover:bg-accent hover:text-accent-foreground"
case VariantLink:
return "text-primary underline-offset-4 hover:underline"
default:
return "bg-primary text-primary-foreground hover:bg-primary/90"
}
}
func (b Props) sizeClasses() string {
switch b.Size {
case SizeIcon:
return "h-10 w-10"
default:
return "h-10 px-4 py-2 rounded-md"
}
}
func (b Props) modifierClasses() string {
classes := []string{}
if b.FullWidth {
classes = append(classes, "w-full")
}
return strings.Join(classes, " ")
}

View file

@ -0,0 +1,483 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component button - version: main installed by templui v0.71.0
package button
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
"strings"
)
type Variant string
type Size string
type Type string
const (
VariantDefault Variant = "default"
VariantDestructive Variant = "destructive"
VariantOutline Variant = "outline"
VariantSecondary Variant = "secondary"
VariantGhost Variant = "ghost"
VariantLink Variant = "link"
)
const (
TypeButton Type = "button"
TypeReset Type = "reset"
TypeSubmit Type = "submit"
)
const (
SizeIcon Size = "icon"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Variant Variant
Size Size
FullWidth bool
Href string
Target string
Disabled bool
Type Type
HxGet string
HxPost string
HxPut string
HxDelete string
HxTrigger string
HxTarget string
HxSwap string
HxReplaceUrl string
}
func Button(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
if p.Type == "" {
p.Type = TypeButton
}
if p.Href != "" && !p.Disabled {
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors",
"focus-visible:outline-hidden focus-visible:ring-2 focus:ring-ring focus-visible:ring-offset-2",
"cursor-pointer",
p.variantClasses(),
p.sizeClasses(),
p.modifierClasses(),
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<a")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 64, Col: 13}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 templ.SafeURL = templ.SafeURL(p.Href)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var4)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Target != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " target=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(p.Target)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 68, Col: 21}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "</a>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
var templ_7745c5c3_Var7 = []any{
utils.TwMerge(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors",
"focus-visible:outline-hidden focus-visible:ring-2 focus:ring-ring focus-visible:ring-offset-2",
"disabled:opacity-50 disabled:cursor-not-allowed",
"cursor-pointer",
p.variantClasses(),
p.sizeClasses(),
p.modifierClasses(),
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<button")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 88, Col: 13}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var7).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Type != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, " type=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(string(p.Type))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 103, Col: 25}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Disabled {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, " disabled")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.HxGet != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " hx-get=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(p.HxGet)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 107, Col: 20}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.HxPost != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, " hx-post=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(p.HxPost)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 110, Col: 22}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.HxPut != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, " hx-put=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(p.HxPut)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 113, Col: 20}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.HxDelete != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, " hx-delete=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(p.HxDelete)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 116, Col: 26}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.HxTrigger != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, " hx-trigger=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(p.HxTrigger)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 119, Col: 28}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.HxTarget != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, " hx-target=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(p.HxTarget)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 122, Col: 26}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.HxSwap != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, " hx-swap=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(p.HxSwap)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 125, Col: 22}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.HxReplaceUrl != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, " hx-replace-url=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(p.HxReplaceUrl)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 128, Col: 35}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "</button>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
return nil
})
}
func (b Props) variantClasses() string {
switch b.Variant {
case VariantDestructive:
return "bg-destructive text-destructive-foreground hover:bg-destructive/90"
case VariantOutline:
return "border border-input bg-background hover:bg-accent hover:text-accent-foreground"
case VariantSecondary:
return "bg-secondary text-secondary-foreground hover:bg-secondary/80"
case VariantGhost:
return "hover:bg-accent hover:text-accent-foreground"
case VariantLink:
return "text-primary underline-offset-4 hover:underline"
default:
return "bg-primary text-primary-foreground hover:bg-primary/90"
}
}
func (b Props) sizeClasses() string {
switch b.Size {
case SizeIcon:
return "h-10 w-10"
default:
return "h-10 px-4 py-2 rounded-md"
}
}
func (b Props) modifierClasses() string {
classes := []string{}
if b.FullWidth {
classes = append(classes, "w-full")
}
return strings.Join(classes, " ")
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,303 @@
// templui component calendar - version: main installed by templui v0.71.0
package calendar
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
"strconv"
"time"
)
type LocaleTag string
var (
LocaleDefaultTag = LocaleTag("en-US")
LocaleTagChinese = LocaleTag("zh-CN")
LocaleTagFrench = LocaleTag("fr-FR")
LocaleTagGerman = LocaleTag("de-DE")
LocaleTagItalian = LocaleTag("it-IT")
LocaleTagJapanese = LocaleTag("ja-JP")
LocaleTagPortuguese = LocaleTag("pt-PT")
LocaleTagSpanish = LocaleTag("es-ES")
)
type Props struct {
ID string
Class string
LocaleTag LocaleTag
Value *time.Time
Name string
InitialMonth int // Optional: 0-11 (Default: current or from Value). Controls the initially displayed month view.
InitialYear int // Optional: (Default: current or from Value). Controls the initially displayed year view.
}
templ Calendar(props ...Props) {
@Script()
{{
var p Props
if len(props) > 0 {
p = props[0]
}
if p.ID == "" {
p.ID = utils.RandomID() + "-calendar"
}
if p.Name == "" {
// Should be provided by parent (e.g., DatePicker or in standalone usage)
p.Name = p.ID + "-value" // Fallback name
}
if p.LocaleTag == "" {
p.LocaleTag = LocaleDefaultTag
}
initialView := time.Now()
if p.Value != nil {
initialView = *p.Value
}
initialMonth := p.InitialMonth
initialYear := p.InitialYear
// Use year from initialView if InitialYear prop is invalid/unset (<= 0)
if initialYear <= 0 {
initialYear = initialView.Year()
}
// Use month from initialView if InitialMonth prop is invalid OR
// if InitialMonth is default 0 AND InitialYear was also defaulted (meaning neither was likely set explicitly)
if (initialMonth < 0 || initialMonth > 11) || (initialMonth == 0 && p.InitialYear <= 0) {
initialMonth = int(initialView.Month()) - 1 // time.Month is 1-12
}
initialSelectedISO := ""
if p.Value != nil {
initialSelectedISO = p.Value.Format("2006-01-02")
}
}}
<div class={ p.Class } id={ p.ID + "-wrapper" } data-calendar-wrapper="true">
<input
type="hidden"
name={ p.Name }
value={ initialSelectedISO }
id={ p.ID + "-hidden" }
data-calendar-hidden-input
/>
<div
id={ p.ID }
data-calendar-container="true"
data-locale-tag={ string(p.LocaleTag) }
data-initial-month={ strconv.Itoa(initialMonth) }
data-initial-year={ strconv.Itoa(initialYear) }
data-selected-date={ initialSelectedISO }
>
<!-- Calendar Header -->
<div class="flex items-center justify-between mb-4">
<span data-calendar-month-display class="text-sm font-medium"></span>
<div class="flex gap-1">
<button type="button" data-calendar-prev class="inline-flex items-center justify-center rounded-md text-sm font-medium h-7 w-7 hover:bg-accent hover:text-accent-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:opacity-50">
@icon.ChevronLeft()
</button>
<button type="button" data-calendar-next class="inline-flex items-center justify-center rounded-md text-sm font-medium h-7 w-7 hover:bg-accent hover:text-accent-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:opacity-50">
@icon.ChevronRight()
</button>
</div>
</div>
<!-- Weekday Headers -->
<div data-calendar-weekdays class="grid grid-cols-7 gap-1 mb-1 place-items-center"></div>
<!-- Calendar Day Grid -->
<div data-calendar-days class="grid grid-cols-7 gap-1 place-items-center"></div>
</div>
</div>
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<script defer nonce={ templ.GetNonce(ctx) }>
(function() {
function initCalendar(container) {
if (!container || container._calendarInitialized) return;
const monthDisplay = container.querySelector('[data-calendar-month-display]');
const weekdaysContainer = container.querySelector('[data-calendar-weekdays]');
const daysContainer = container.querySelector('[data-calendar-days]');
const prevButton = container.querySelector('[data-calendar-prev]');
const nextButton = container.querySelector('[data-calendar-next]');
const wrapper = container.closest('[data-calendar-wrapper]');
const hiddenInput = wrapper ? wrapper.querySelector('[data-calendar-hidden-input]') : null;
if (!monthDisplay || !weekdaysContainer || !daysContainer || !prevButton || !nextButton || !hiddenInput) {
console.error('Calendar init error: Missing required elements (or hidden input relative to wrapper).', container);
return;
}
const localeTag = container.dataset.localeTag || 'en-US';
let monthNames;
try {
monthNames = Array.from({ length: 12 }, (_, i) =>
new Intl.DateTimeFormat(localeTag, { month: 'long', timeZone: 'UTC' }).format(new Date(Date.UTC(2000, i, 1)))
);
} catch (e) {
console.error(`Calendar: Error generating month names via Intl (locale: "${localeTag}"). Falling back to English.`, e);
// Fallback to English names if Intl fails for any reason
monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
}
let dayNames = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']; // Default fallback
try {
// Use days 0-6 (Sun-Sat standard). Intl provides names in the locale's typical order.
dayNames = Array.from({ length: 7 }, (_, i) =>
new Intl.DateTimeFormat(localeTag, { weekday: 'short' }).format(new Date(Date.UTC(2000, 0, i)))
);
} catch (e) {
console.error('Error generating calendar day names via Intl:', e);
// Keep default dayNames on error
}
let currentMonth = parseInt(container.dataset.initialMonth);
let currentYear = parseInt(container.dataset.initialYear);
let selectedDate = null; // Stored as JS Date object (UTC midnight)
if (container.dataset.selectedDate) {
selectedDate = parseISODate(container.dataset.selectedDate);
}
function parseISODate(isoStr) {
if (!isoStr) return null;
try {
const parts = isoStr.split('-');
const year = parseInt(parts[0], 10);
const month = parseInt(parts[1], 10) - 1; // JS month is 0-indexed
const day = parseInt(parts[2], 10);
const date = new Date(Date.UTC(year, month, day));
if (!isNaN(date) && date.getUTCFullYear() === year && date.getUTCMonth() === month && date.getUTCDate() === day) {
return date;
}
} catch {}
return null;
}
function updateMonthDisplay() {
// Always use the fallback month name combined with the current year
// Ensure month index is within bounds (0-11)
const monthIndex = Math.max(0, Math.min(11, currentMonth));
const monthName = monthNames[monthIndex];
const displayString = `${monthName} ${currentYear}`;
monthDisplay.textContent = displayString;
}
function renderWeekdays() {
weekdaysContainer.innerHTML = '';
dayNames.forEach(day => {
const el = document.createElement('div');
el.className = 'text-center text-xs text-muted-foreground font-medium';
el.textContent = day;
weekdaysContainer.appendChild(el);
});
}
function renderCalendar() {
daysContainer.innerHTML = '';
const firstDayOfMonth = new Date(Date.UTC(currentYear, currentMonth, 1));
const firstDayUTCDay = firstDayOfMonth.getUTCDay(); // 0=Sun
let startOffset = firstDayUTCDay; // Simple Sunday start offset
// NOTE: A robust implementation might need to adjust offset based on locale's actual first day of week.
// Intl doesn't directly provide this easily yet. Keep Sunday start for simplicity.
const daysInMonth = new Date(Date.UTC(currentYear, currentMonth + 1, 0)).getUTCDate();
// Calculate 'today' based on the browser's local date for correct highlighting
const now = new Date();
const today = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate()));
for (let i = 0; i < startOffset; i++) {
const blank = document.createElement('div');
blank.className = 'h-8 w-8';
daysContainer.appendChild(blank);
}
for (let day = 1; day <= daysInMonth; day++) {
const button = document.createElement('button');
button.type = 'button';
button.className = 'inline-flex h-8 w-8 items-center justify-center rounded-md text-sm font-medium focus:outline-none focus:ring-1 focus:ring-ring';
button.textContent = day;
button.dataset.day = day;
const currentDate = new Date(Date.UTC(currentYear, currentMonth, day));
const isSelected = selectedDate && currentDate.getTime() === selectedDate.getTime();
const isToday = currentDate.getTime() === today.getTime();
if (isSelected) button.classList.add('bg-primary', 'text-primary-foreground', 'hover:bg-primary/90');
else if (isToday) button.classList.add('bg-accent', 'text-accent-foreground');
else button.classList.add('hover:bg-accent', 'hover:text-accent-foreground');
button.addEventListener('click', handleDayClick);
daysContainer.appendChild(button);
}
}
function handlePrevMonthClick() {
currentMonth--;
if (currentMonth < 0) { currentMonth = 11; currentYear--; }
updateMonthDisplay(); renderCalendar();
}
function handleNextMonthClick() {
currentMonth++;
if (currentMonth > 11) { currentMonth = 0; currentYear++; }
updateMonthDisplay(); renderCalendar();
}
function handleDayClick(event) {
const day = parseInt(event.target.dataset.day);
if (!day) return;
const newlySelectedDate = new Date(Date.UTC(currentYear, currentMonth, day));
selectedDate = newlySelectedDate;
const isoFormattedValue = newlySelectedDate.toISOString().split('T')[0];
hiddenInput.value = isoFormattedValue;
hiddenInput.dispatchEvent(new Event('change', { bubbles: true }));
container.dispatchEvent(new CustomEvent('calendar-date-selected', {
bubbles: true,
detail: { date: newlySelectedDate }
}));
renderCalendar();
}
// Initialization
prevButton.addEventListener('click', handlePrevMonthClick);
nextButton.addEventListener('click', handleNextMonthClick);
updateMonthDisplay();
renderWeekdays();
renderCalendar();
container._calendarInitialized = true;
}
function initAllComponents(root = document) {
if (root instanceof Element && root.matches('[data-calendar-container]')) {
initCalendar(root);
}
for (const calendar of root.querySelectorAll('[data-calendar-container]')) {
initCalendar(calendar);
}
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})();
</script>
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,305 @@
// templui component card - version: main installed by templui v0.71.0
package card
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/aspectratio"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type MediaPosition string
type MediaWidth string
const (
MediaPositionTop MediaPosition = "top"
MediaPositionBottom MediaPosition = "bottom"
MediaPositionLeft MediaPosition = "left"
MediaPositionRight MediaPosition = "right"
)
const (
MediaWidthAuto MediaWidth = "auto"
MediaWidthFull MediaWidth = "full"
MediaWidthHalf MediaWidth = "half"
MediaWidthThird MediaWidth = "third"
MediaWidthQuarter MediaWidth = "quarter"
MediaWidthTwoThirds MediaWidth = "two-thirds"
MediaWidthThreeQuarters MediaWidth = "three-quarters"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
type HeaderProps struct {
ID string
Class string
Attributes templ.Attributes
}
type TitleProps struct {
ID string
Class string
Attributes templ.Attributes
}
type DescriptionProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ContentProps struct {
ID string
Class string
Attributes templ.Attributes
}
type FooterProps struct {
ID string
Class string
Attributes templ.Attributes
}
type HorizontalProps struct {
ID string
Class string
Attributes templ.Attributes
}
type MediaProps struct {
ID string
Class string
Attributes templ.Attributes
Src string
Alt string
Position MediaPosition
Width MediaWidth
AspectRatio aspectratio.Ratio
}
templ Card(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"w-full rounded-lg border bg-card text-card-foreground shadow-xs",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
templ Header(props ...HeaderProps) {
{{ var p HeaderProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex flex-col space-y-1.5 p-6 pb-0",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
templ Title(props ...TitleProps) {
{{ var p TitleProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<h3
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"text-lg font-semibold leading-none tracking-tight",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</h3>
}
templ Description(props ...DescriptionProps) {
{{ var p DescriptionProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<p
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"text-sm text-muted-foreground",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</p>
}
templ Content(props ...ContentProps) {
{{ var p ContentProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"p-6",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
templ Footer(props ...FooterProps) {
{{ var p FooterProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center p-6 pt-0",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
templ Horizontal(props ...HorizontalProps) {
{{ var p HorizontalProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex overflow-hidden",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
templ Media(props ...MediaProps) {
{{ var p MediaProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"overflow-hidden",
mediaPositionClasses(p.Position, p.Width),
p.Class,
),
}
{ p.Attributes... }
>
@aspectratio.AspectRatio(aspectratio.Props{
ID: p.ID + "-aspect",
Ratio: p.AspectRatio,
Class: "h-full w-full",
}) {
<img
if p.Src != "" {
src={ p.Src }
}
if p.Alt != "" {
alt={ p.Alt }
}
class="h-full w-full object-cover"
/>
}
</div>
}
func mediaPositionClasses(position MediaPosition, width MediaWidth) string {
var positionClass string
switch position {
case MediaPositionTop:
return "w-full rounded-t-lg"
case MediaPositionBottom:
return "w-full rounded-b-lg"
case MediaPositionLeft:
positionClass = "shrink-0 rounded-l-lg"
case MediaPositionRight:
positionClass = "shrink-0 rounded-r-lg"
default:
positionClass = ""
}
if position == MediaPositionLeft || position == MediaPositionRight {
return positionClass + " " + widthClass(width)
}
return positionClass
}
func widthClass(width MediaWidth) string {
switch width {
case MediaWidthFull:
return "w-full"
case MediaWidthHalf:
return "w-1/2"
case MediaWidthThird:
return "w-1/3"
case MediaWidthQuarter:
return "w-1/4"
case MediaWidthTwoThirds:
return "w-2/3"
case MediaWidthThreeQuarters:
return "w-3/4"
default:
return "w-1/3"
}
}

View file

@ -0,0 +1,958 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component card - version: main installed by templui v0.71.0
package card
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/aspectratio"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type MediaPosition string
type MediaWidth string
const (
MediaPositionTop MediaPosition = "top"
MediaPositionBottom MediaPosition = "bottom"
MediaPositionLeft MediaPosition = "left"
MediaPositionRight MediaPosition = "right"
)
const (
MediaWidthAuto MediaWidth = "auto"
MediaWidthFull MediaWidth = "full"
MediaWidthHalf MediaWidth = "half"
MediaWidthThird MediaWidth = "third"
MediaWidthQuarter MediaWidth = "quarter"
MediaWidthTwoThirds MediaWidth = "two-thirds"
MediaWidthThreeQuarters MediaWidth = "three-quarters"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
type HeaderProps struct {
ID string
Class string
Attributes templ.Attributes
}
type TitleProps struct {
ID string
Class string
Attributes templ.Attributes
}
type DescriptionProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ContentProps struct {
ID string
Class string
Attributes templ.Attributes
}
type FooterProps struct {
ID string
Class string
Attributes templ.Attributes
}
type HorizontalProps struct {
ID string
Class string
Attributes templ.Attributes
}
type MediaProps struct {
ID string
Class string
Attributes templ.Attributes
Src string
Alt string
Position MediaPosition
Width MediaWidth
AspectRatio aspectratio.Ratio
}
func Card(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"w-full rounded-lg border bg-card text-card-foreground shadow-xs",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 89, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Header(props ...HeaderProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p HeaderProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var6 = []any{
utils.TwMerge(
"flex flex-col space-y-1.5 p-6 pb-0",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 110, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var5.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Title(props ...TitleProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
if templ_7745c5c3_Var9 == nil {
templ_7745c5c3_Var9 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p TitleProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var10 = []any{
utils.TwMerge(
"text-lg font-semibold leading-none tracking-tight",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<h3")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 131, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var10).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var9.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</h3>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Description(props ...DescriptionProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var13 := templ.GetChildren(ctx)
if templ_7745c5c3_Var13 == nil {
templ_7745c5c3_Var13 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p DescriptionProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var14 = []any{
utils.TwMerge(
"text-sm text-muted-foreground",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "<p")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 152, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var14).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var13.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "</p>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Content(props ...ContentProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var17 := templ.GetChildren(ctx)
if templ_7745c5c3_Var17 == nil {
templ_7745c5c3_Var17 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p ContentProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var18 = []any{
utils.TwMerge(
"p-6",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var18...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var19 string
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 173, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var20 string
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var18).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var17.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Footer(props ...FooterProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var21 := templ.GetChildren(ctx)
if templ_7745c5c3_Var21 == nil {
templ_7745c5c3_Var21 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p FooterProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var22 = []any{
utils.TwMerge(
"flex items-center p-6 pt-0",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var22...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var23 string
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 194, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var24 string
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var22).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var21.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Horizontal(props ...HorizontalProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var25 := templ.GetChildren(ctx)
if templ_7745c5c3_Var25 == nil {
templ_7745c5c3_Var25 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p HorizontalProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var26 = []any{
utils.TwMerge(
"flex overflow-hidden",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var26...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var27 string
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 215, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var28 string
templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var26).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var25.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Media(props ...MediaProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var29 := templ.GetChildren(ctx)
if templ_7745c5c3_Var29 == nil {
templ_7745c5c3_Var29 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p MediaProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var30 = []any{
utils.TwMerge(
"overflow-hidden",
mediaPositionClasses(p.Position, p.Width),
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var30...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var31 string
templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 236, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var32 string
templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var30).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var33 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "<img")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Src != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, " src=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var34 string
templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(p.Src)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 254, Col: 16}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Alt != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, " alt=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var35 string
templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinStringErrs(p.Alt)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/card/card.templ`, Line: 257, Col: 16}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, " class=\"h-full w-full object-cover\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = aspectratio.AspectRatio(aspectratio.Props{
ID: p.ID + "-aspect",
Ratio: p.AspectRatio,
Class: "h-full w-full",
}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var33), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func mediaPositionClasses(position MediaPosition, width MediaWidth) string {
var positionClass string
switch position {
case MediaPositionTop:
return "w-full rounded-t-lg"
case MediaPositionBottom:
return "w-full rounded-b-lg"
case MediaPositionLeft:
positionClass = "shrink-0 rounded-l-lg"
case MediaPositionRight:
positionClass = "shrink-0 rounded-r-lg"
default:
positionClass = ""
}
if position == MediaPositionLeft || position == MediaPositionRight {
return positionClass + " " + widthClass(width)
}
return positionClass
}
func widthClass(width MediaWidth) string {
switch width {
case MediaWidthFull:
return "w-full"
case MediaWidthHalf:
return "w-1/2"
case MediaWidthThird:
return "w-1/3"
case MediaWidthQuarter:
return "w-1/4"
case MediaWidthTwoThirds:
return "w-2/3"
case MediaWidthThreeQuarters:
return "w-3/4"
default:
return "w-1/3"
}
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,394 @@
// templui component carousel - version: main installed by templui v0.71.0
package carousel
import (
"fmt"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
"strconv"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Autoplay bool
Interval int
Loop bool
}
type ContentProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ItemProps struct {
ID string
Class string
Attributes templ.Attributes
}
type PreviousProps struct {
ID string
Class string
Attributes templ.Attributes
}
type NextProps struct {
ID string
Class string
Attributes templ.Attributes
}
type IndicatorsProps struct {
ID string
Class string
Attributes templ.Attributes
Count int
}
templ Carousel(props ...Props) {
@Script()
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"carousel-component relative overflow-hidden w-full",
p.Class,
),
}
data-autoplay={ strconv.FormatBool(p.Autoplay) }
data-interval={ fmt.Sprintf("%d", func() int {
if p.Interval == 0 {
return 5000
}
return p.Interval
}()) }
data-loop={ strconv.FormatBool(p.Loop) }
{ p.Attributes... }
>
{ children... }
</div>
}
templ Content(props ...ContentProps) {
{{ var p ContentProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"carousel-track flex h-full w-full transition-transform duration-500 ease-in-out",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
templ Item(props ...ItemProps) {
{{ var p ItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"carousel-item flex-shrink-0 w-full h-full relative",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
templ Previous(props ...PreviousProps) {
{{ var p PreviousProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<button
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"carousel-prev absolute left-2 top-1/2 transform -translate-y-1/2 p-2 rounded-full bg-black/20 text-white hover:bg-black/40 focus:outline-none",
p.Class,
),
}
aria-label="Previous slide"
type="button"
{ p.Attributes... }
>
@icon.ChevronLeft()
</button>
}
templ Next(props ...NextProps) {
{{ var p NextProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<button
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"carousel-next absolute right-2 top-1/2 transform -translate-y-1/2 p-2 rounded-full bg-black/20 text-white hover:bg-black/40 focus:outline-none",
p.Class,
),
}
aria-label="Next slide"
type="button"
{ p.Attributes... }
>
@icon.ChevronRight()
</button>
}
templ Indicators(props ...IndicatorsProps) {
{{ var p IndicatorsProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"absolute bottom-4 left-1/2 transform -translate-x-1/2 flex gap-2",
p.Class,
),
}
{ p.Attributes... }
>
for i := 0; i < p.Count; i++ {
<button
class={
utils.TwMerge(
"carousel-indicator w-3 h-3 rounded-full bg-white/50 hover:bg-white/80 focus:outline-none transition-colors",
utils.If(i == 0, "bg-white"),
),
}
aria-label={ fmt.Sprintf("Go to slide %d", i+1) }
type="button"
></button>
}
</div>
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<script defer nonce={ templ.GetNonce(ctx) }>
(function() { // IIFE
function initCarousel(carousel) {
const track = carousel.querySelector('.carousel-track');
const items = Array.from(track?.querySelectorAll('.carousel-item') || []);
if (items.length === 0) return;
const indicators = Array.from(carousel.querySelectorAll('.carousel-indicator'));
const prevBtn = carousel.querySelector('.carousel-prev');
const nextBtn = carousel.querySelector('.carousel-next');
const state = {
currentIndex: 0,
slideCount: items.length,
autoplay: carousel.dataset.autoplay === 'true',
interval: parseInt(carousel.dataset.interval || 5000),
loop: carousel.dataset.loop === 'true',
autoplayInterval: null,
isHovering: false,
touchStartX: 0
};
function updateTrackPosition() {
track.style.transform = `translateX(-${state.currentIndex * 100}%)`;
}
function updateIndicators() {
indicators.forEach((indicator, i) => {
if (i < state.slideCount) {
if (i === state.currentIndex) {
indicator.classList.add('bg-white');
indicator.classList.remove('bg-white/50');
} else {
indicator.classList.remove('bg-white');
indicator.classList.add('bg-white/50');
}
indicator.style.display = '';
} else {
indicator.style.display = 'none';
}
});
}
function updateButtons() {
if (prevBtn) {
prevBtn.disabled = !state.loop && state.currentIndex === 0;
prevBtn.classList.toggle('opacity-50', prevBtn.disabled);
prevBtn.classList.toggle('cursor-not-allowed', prevBtn.disabled);
}
if (nextBtn) {
nextBtn.disabled = !state.loop && state.currentIndex === state.slideCount - 1;
nextBtn.classList.toggle('opacity-50', nextBtn.disabled);
nextBtn.classList.toggle('cursor-not-allowed', nextBtn.disabled);
}
}
function startAutoplay() {
if (state.autoplayInterval) {
clearInterval(state.autoplayInterval);
}
if (state.autoplay) {
state.autoplayInterval = setInterval(() => {
if (!state.isHovering) {
goToNext();
}
}, state.interval);
}
}
function stopAutoplay() {
if (state.autoplayInterval) {
clearInterval(state.autoplayInterval);
state.autoplayInterval = null;
}
}
function goToNext() {
let nextIndex = state.currentIndex + 1;
if (nextIndex >= state.slideCount) {
if (state.loop) {
nextIndex = 0;
} else {
return;
}
}
goToSlide(nextIndex);
}
function goToPrev() {
let prevIndex = state.currentIndex - 1;
if (prevIndex < 0) {
if (state.loop) {
prevIndex = state.slideCount - 1;
} else {
return;
}
}
goToSlide(prevIndex);
}
function goToSlide(index) {
if (index < 0 || index >= state.slideCount) {
if (state.loop) {
index = (index + state.slideCount) % state.slideCount;
} else {
return;
}
}
if (index === state.currentIndex) return;
state.currentIndex = index;
updateTrackPosition();
updateIndicators();
updateButtons();
if (state.autoplay && !state.isHovering) {
stopAutoplay();
startAutoplay();
}
}
if (track) {
track.addEventListener('touchstart', (e) => {
state.touchStartX = e.touches[0].clientX;
}, { passive: true });
track.addEventListener('touchend', (e) => {
const touchEndX = e.changedTouches[0].clientX;
const diff = state.touchStartX - touchEndX;
const sensitivity = 50;
if (Math.abs(diff) > sensitivity) {
diff > 0 ? goToNext() : goToPrev();
}
}, { passive: true });
}
indicators.forEach((indicator, index) => {
if (index < state.slideCount) {
indicator.addEventListener('click', () => goToSlide(index));
}
});
if (prevBtn) prevBtn.addEventListener('click', goToPrev);
if (nextBtn) nextBtn.addEventListener('click', goToNext);
carousel.addEventListener('mouseenter', () => {
state.isHovering = true;
if (state.autoplay) stopAutoplay();
});
carousel.addEventListener('mouseleave', () => {
state.isHovering = false;
if (state.autoplay) startAutoplay();
});
updateTrackPosition();
updateIndicators();
updateButtons();
if (state.autoplay) startAutoplay();
}
function initAllComponents(root = document) {
if (root instanceof Element && root.matches('.carousel-component')) {
initCarousel(root);
}
for (const carousel of root.querySelectorAll('.carousel-component')) {
initCarousel(carousel);
}
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})(); // End of IIFE
</script>
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,330 @@
// templui component chart - version: main installed by templui v0.71.0
package chart
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Variant string
const (
VariantBar Variant = "bar"
VariantLine Variant = "line"
VariantPie Variant = "pie"
VariantDoughnut Variant = "doughnut"
VariantRadar Variant = "radar"
)
type Dataset struct {
Label string `json:"label"`
Data []float64 `json:"data"`
BorderWidth int `json:"borderWidth,omitempty"`
BorderColor interface{} `json:"borderColor,omitempty"`
BackgroundColor interface{} `json:"backgroundColor,omitempty"`
Tension float64 `json:"tension,omitempty"`
Fill bool `json:"fill,omitempty"`
Stepped bool `json:"stepped,omitempty"`
}
type Options struct {
Responsive bool `json:"responsive,omitempty"`
Legend bool `json:"legend,omitempty"`
}
type Data struct {
Labels []string `json:"labels"`
Datasets []Dataset `json:"datasets"`
}
type Config struct {
Type Variant `json:"type"`
Data Data `json:"data"`
Options Options `json:"options,omitempty"`
ShowLegend bool `json:"showLegend,omitempty"`
ShowXAxis bool `json:"showXAxis"`
ShowYAxis bool `json:"showYAxis"`
ShowXLabels bool `json:"showXLabels"`
ShowYLabels bool `json:"showYLabels"`
ShowXGrid bool `json:"showXGrid"`
ShowYGrid bool `json:"showYGrid"`
Horizontal bool `json:"horizontal"`
Stacked bool `json:"stacked"`
}
// Erweiterung des Props um ID und Attributes
type Props struct {
ID string
Variant Variant
Data Data
Options Options
ShowLegend bool
ShowXAxis bool
ShowYAxis bool
ShowXLabels bool
ShowYLabels bool
ShowXGrid bool
ShowYGrid bool
Horizontal bool
Stacked bool
Class string
Attributes templ.Attributes
}
templ Chart(props ...Props) {
@Script()
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.ID == "" {
{{ p.ID = "chart-" + utils.RandomID() }}
}
{{ canvasId := p.ID + "-canvas" }}
{{ dataId := p.ID + "-data" }}
<div
id={ p.ID }
class={
utils.TwMerge(
"chart-container relative",
p.Class),
}
{ p.Attributes... }
>
<canvas id={ canvasId } data-chart-id={ dataId }></canvas>
</div>
{{
chartConfig := Config{
Type: p.Variant,
Data: p.Data,
Options: p.Options,
ShowLegend: p.ShowLegend,
ShowXAxis: p.ShowXAxis,
ShowYAxis: p.ShowYAxis,
ShowXLabels: p.ShowXLabels,
ShowYLabels: p.ShowYLabels,
ShowXGrid: p.ShowXGrid,
ShowYGrid: p.ShowYGrid,
Horizontal: p.Horizontal,
Stacked: p.Stacked,
}
}}
@templ.JSONScript(dataId, chartConfig)
}
templ Script() {
<script defer nonce={ templ.GetNonce(ctx) } src="https://cdn.jsdelivr.net/npm/chart.js@4.4.8/dist/chart.umd.min.js"></script>
<script nonce={ templ.GetNonce(ctx) }>
window.chartInstances = window.chartInstances || {};
(function() { // IIFE
if (!window.chartScriptInitialized) {
function getThemeColors() {
const style = getComputedStyle(document.documentElement);
return {
foreground: style.getPropertyValue('--foreground').trim() || '#000',
background: style.getPropertyValue('--background').trim() || '#fff',
mutedForeground: style.getPropertyValue('--muted-foreground').trim() || '#666',
border: style.getPropertyValue('--border').trim() || '#ccc'
};
}
function initChart(canvas) {
if (!canvas || !canvas.id || !canvas.hasAttribute('data-chart-id')) return;
if (window.chartInstances[canvas.id]) {
cleanupChart(canvas);
}
const dataId = canvas.getAttribute('data-chart-id');
const dataElement = document.getElementById(dataId);
if (!dataElement) return;
try {
const chartConfig = JSON.parse(dataElement.textContent);
const colors = getThemeColors();
Chart.defaults.elements.point.radius = 0;
Chart.defaults.elements.point.hoverRadius = 5;
const isComplexChart = ["pie", "doughnut", "bar", "radar"].includes(chartConfig.type);
const legendOptions = {
display: chartConfig.showLegend || false,
labels: { color: colors.foreground }
};
const tooltipOptions = {
backgroundColor: colors.background,
bodyColor: colors.mutedForeground,
titleColor: colors.foreground,
borderColor: colors.border,
borderWidth: 1
};
const scalesOptions = chartConfig.type === "radar"
? {
r: {
grid: {
color: colors.border,
display: chartConfig.showYGrid !== false
},
ticks: {
color: colors.mutedForeground,
backdropColor: "transparent",
display: chartConfig.showYLabels !== false
},
angleLines: {
color: colors.border,
display: chartConfig.showXGrid !== false
},
pointLabels: {
color: colors.foreground,
font: { size: 12 }
},
border: {
display: chartConfig.showYAxis !== false,
color: colors.border
},
beginAtZero: true
}
}
: {
x: {
beginAtZero: true,
display: chartConfig.showXLabels !== false ||
chartConfig.showXGrid !== false ||
chartConfig.showXAxis !== false,
border: {
display: chartConfig.showXAxis !== false,
color: colors.border
},
ticks: {
display: chartConfig.showXLabels !== false,
color: colors.mutedForeground
},
grid: {
display: chartConfig.showXGrid !== false,
color: colors.border
},
stacked: chartConfig.stacked || false
},
y: {
offset: true,
beginAtZero: true,
display: chartConfig.showYLabels !== false ||
chartConfig.showYGrid !== false ||
chartConfig.showYAxis !== false,
border: {
display: chartConfig.showYAxis !== false,
color: colors.border
},
ticks: {
display: chartConfig.showYLabels !== false,
color: colors.mutedForeground
},
grid: {
display: chartConfig.showYGrid !== false,
color: colors.border
},
stacked: chartConfig.stacked || false
}
};
const finalChartConfig = {
...chartConfig,
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
intersect: isComplexChart ? true : false,
axis: "xy",
mode: isComplexChart ? "nearest" : "index"
},
indexAxis: chartConfig.horizontal ? "y" : "x",
plugins: {
legend: legendOptions,
tooltip: tooltipOptions
},
scales: scalesOptions
}
};
window.chartInstances[canvas.id] = new Chart(canvas, finalChartConfig);
} catch (e) {}
}
function cleanupChart(canvas) {
if (!canvas || !canvas.id || !window.chartInstances[canvas.id]) return;
try {
window.chartInstances[canvas.id].destroy();
} finally {
delete window.chartInstances[canvas.id];
}
}
function initAllComponents(root = document) {
if (typeof Chart === "undefined") return;
for (const canvas of root.querySelectorAll("canvas[data-chart-id]")) {
initChart(canvas);
}
}
function waitForChartAndInit() {
if (typeof Chart !== "undefined") {
initAllComponents();
} else {
setTimeout(waitForChartAndInit, 100);
}
}
document.addEventListener("DOMContentLoaded", waitForChartAndInit);
document.body.addEventListener("htmx:beforeSwap", (event) => {
const el = event.detail.target || event.detail.elt;;
if (el instanceof Element) {
for (const canvas of el.querySelectorAll("canvas[data-chart-id]")) {
cleanupChart(canvas);
}
if (el.matches("canvas[data-chart-id]")) {
cleanupChart(el);
}
}
});
document.body.addEventListener("htmx:afterSwap", (event) => {
const target = event.detail.target || event.detail.elt;;
if (target instanceof Element) {
function tryInit(attempt = 1) {
if (typeof Chart !== "undefined") {
initAllComponents(target);
} else if (attempt < 10) {
setTimeout(() => tryInit(attempt + 1), 100);
}
}
tryInit();
}
});
const observer = new MutationObserver(() => {
let timeout;
clearTimeout(timeout);
timeout = setTimeout(() => {
for (const canvas of document.querySelectorAll("canvas[data-chart-id]")) {
if (window.chartInstances[canvas.id]) {
cleanupChart(canvas);
initChart(canvas);
}
}
}, 50);
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ["class", "style"]
});
window.chartScriptInitialized = true;
}
})(); // End of IIFE
</script>
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,70 @@
// templui component checkbox - version: main installed by templui v0.71.0
package checkbox
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Name string
Value string
Disabled bool
Required bool
Checked bool
Icon templ.Component
}
templ Checkbox(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div class="relative flex items-center">
<input
checked?={ p.Checked }
disabled?={ p.Disabled }
required?={ p.Required }
if p.ID != "" {
id={ p.ID }
}
if p.Name != "" {
name={ p.Name }
}
if p.Value != "" {
value={ p.Value }
}
type="checkbox"
class={
utils.TwMerge(
"relative size-4 overflow-hidden peer",
"before:absolute before:inset-0 before:content['']",
"appearance-none rounded-sm border-2 border-primary bg-background",
"cursor-pointer transition-colors",
"checked:before:bg-primary",
"disabled:cursor-not-allowed disabled:opacity-50",
p.Class,
),
}
{ p.Attributes... }
/>
<div
class={
utils.TwMerge(
"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2",
"size-3 text-primary-foreground pointer-events-none opacity-0",
"peer-checked:opacity-100",
),
}
>
if p.Icon != nil {
@p.Icon
} else {
@icon.Check(icon.Props{Size: 12})
}
</div>
</div>
}

View file

@ -0,0 +1,225 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component checkbox - version: main installed by templui v0.71.0
package checkbox
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Name string
Value string
Disabled bool
Required bool
Checked bool
Icon templ.Component
}
func Checkbox(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"relative flex items-center\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"relative size-4 overflow-hidden peer",
"before:absolute before:inset-0 before:content['']",
"appearance-none rounded-sm border-2 border-primary bg-background",
"cursor-pointer transition-colors",
"checked:before:bg-primary",
"disabled:cursor-not-allowed disabled:opacity-50",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<input")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Checked {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, " checked")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Disabled {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " disabled")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Required {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, " required")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkbox/checkbox.templ`, Line: 32, Col: 13}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Name != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, " name=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(p.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkbox/checkbox.templ`, Line: 35, Col: 17}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Value != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(p.Value)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkbox/checkbox.templ`, Line: 38, Col: 19}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " type=\"checkbox\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkbox/checkbox.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 = []any{
utils.TwMerge(
"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2",
"size-3 text-primary-foreground pointer-events-none opacity-0",
"peer-checked:opacity-100",
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<div class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var7).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkbox/checkbox.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Icon != nil {
templ_7745c5c3_Err = p.Icon.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
templ_7745c5c3_Err = icon.Check(icon.Props{Size: 12}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,152 @@
// templui component checkboxcard - version: main installed by templui v0.71.0
package checkboxcard
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Props struct {
ID string
Class string
Attributes templ.Attributes
Checked bool
Disabled bool
Required bool
Name string
Value string
}
type HeaderProps struct {
ID string
Class string
Attributes templ.Attributes
}
type DescriptionProps struct {
ID string
Class string
Attributes templ.Attributes
}
type FooterProps struct {
ID string
Class string
Attributes templ.Attributes
}
templ CheckboxCard(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.ID == "" {
{{ p.ID = utils.RandomID() }}
}
{{ inputId := p.ID + "-input" }}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"relative",
utils.If(p.Disabled, "opacity-60"),
p.Class,
),
}
{ p.Attributes... }
>
<input
type="checkbox"
id={ inputId }
if p.Name != "" {
name={ p.Name }
}
if p.Value != "" {
value={ p.Value }
}
checked?={ p.Checked }
disabled?={ p.Disabled }
required?={ p.Required }
class="peer sr-only"
/>
<label
for={ inputId }
class={
utils.TwMerge(
"block w-full rounded-lg border overflow-hidden h-full",
"bg-card text-card-foreground p-4 flex flex-col",
"cursor-pointer",
"hover:border-primary/50",
"peer-checked:ring-1 peer-checked:ring-primary peer-checked:border-primary",
utils.If(p.Disabled, "cursor-not-allowed"),
"transition-all duration-200",
p.Class,
),
}
>
{ children... }
</label>
</div>
}
templ Header(props ...HeaderProps) {
{{ var p HeaderProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center justify-between mb-2",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
templ Description(props ...DescriptionProps) {
{{ var p DescriptionProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<p
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"text-sm text-muted-foreground",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</p>
}
templ Footer(props ...FooterProps) {
{{ var p FooterProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"mt-auto pt-4 w-full",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}

View file

@ -0,0 +1,548 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component checkboxcard - version: main installed by templui v0.71.0
package checkboxcard
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Props struct {
ID string
Class string
Attributes templ.Attributes
Checked bool
Disabled bool
Required bool
Name string
Value string
}
type HeaderProps struct {
ID string
Class string
Attributes templ.Attributes
}
type DescriptionProps struct {
ID string
Class string
Attributes templ.Attributes
}
type FooterProps struct {
ID string
Class string
Attributes templ.Attributes
}
func CheckboxCard(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
if p.ID == "" {
p.ID = utils.RandomID()
}
inputId := p.ID + "-input"
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"relative",
utils.If(p.Disabled, "opacity-60"),
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkboxcard/checkbox_card.templ`, Line: 46, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkboxcard/checkbox_card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "><input type=\"checkbox\" id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(inputId)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkboxcard/checkbox_card.templ`, Line: 59, Col: 15}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Name != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, " name=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(p.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkboxcard/checkbox_card.templ`, Line: 61, Col: 17}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Value != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(p.Value)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkboxcard/checkbox_card.templ`, Line: 64, Col: 19}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Checked {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " checked")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Disabled {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, " disabled")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Required {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, " required")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, " class=\"peer sr-only\"> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 = []any{
utils.TwMerge(
"block w-full rounded-lg border overflow-hidden h-full",
"bg-card text-card-foreground p-4 flex flex-col",
"cursor-pointer",
"hover:border-primary/50",
"peer-checked:ring-1 peer-checked:ring-primary peer-checked:border-primary",
utils.If(p.Disabled, "cursor-not-allowed"),
"transition-all duration-200",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<label for=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(inputId)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkboxcard/checkbox_card.templ`, Line: 72, Col: 16}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var8).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkboxcard/checkbox_card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "</label></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Header(props ...HeaderProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var11 := templ.GetChildren(ctx)
if templ_7745c5c3_Var11 == nil {
templ_7745c5c3_Var11 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p HeaderProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var12 = []any{
utils.TwMerge(
"flex items-center justify-between mb-2",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkboxcard/checkbox_card.templ`, Line: 98, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var12).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkboxcard/checkbox_card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var11.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Description(props ...DescriptionProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var15 := templ.GetChildren(ctx)
if templ_7745c5c3_Var15 == nil {
templ_7745c5c3_Var15 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p DescriptionProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var16 = []any{
utils.TwMerge(
"text-sm text-muted-foreground",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "<p")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkboxcard/checkbox_card.templ`, Line: 119, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var16).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkboxcard/checkbox_card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var15.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "</p>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Footer(props ...FooterProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var19 := templ.GetChildren(ctx)
if templ_7745c5c3_Var19 == nil {
templ_7745c5c3_Var19 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p FooterProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var20 = []any{
utils.TwMerge(
"mt-auto pt-4 w-full",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var21 string
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkboxcard/checkbox_card.templ`, Line: 140, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var22 string
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var20).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/checkboxcard/checkbox_card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var19.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,197 @@
// templui component code - version: main installed by templui v0.71.0
package code
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Size string
const (
SizeSm Size = "sm"
SizeLg Size = "lg"
SizeFull Size = "full"
)
type Props struct {
ID string
Class string
Attrs templ.Attributes
Language string
ShowCopyButton bool
Size Size
CodeClass string
}
templ Code(props ...Props) {
@Script()
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.ID == "" {
{{ p.ID = "code-" + utils.RandomID() }}
}
<div
id={ p.ID }
class={ utils.TwMerge("relative code-component", p.Class) }
data-code-component
{ p.Attrs... }
>
<pre class="overflow-hidden!">
<code
data-code-block
class={
utils.TwMerge(
"language-"+p.Language,
"overflow-y-auto! rounded-md block text-sm max-h-[501px]",
utils.If(p.Size == SizeSm, "max-h-[250px]"),
utils.If(p.Size == SizeLg, "max-h-[1000px]"),
utils.If(p.Size == SizeFull, "max-h-full"),
"hljs-target",
p.CodeClass,
),
}
>
{ children... }
</code>
</pre>
if p.ShowCopyButton {
<button
data-copy-button
type="button"
class="absolute top-2 right-2 hover:bg-gray-500 hover:bg-opacity-30 text-white p-2 rounded"
>
<span data-icon-check class="hidden">
@icon.Check(icon.Props{Size: 14})
</span>
<span data-icon-clipboard>
@icon.Clipboard(icon.Props{Size: 14})
</span>
</button>
}
</div>
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/pojoaque.min.css"/>
<script nonce={ templ.GetNonce(ctx) } src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script nonce={ templ.GetNonce(ctx) }>
(function() { // IIFE Start
function whenHljsReady(callback, attempt = 1) {
if (typeof hljs !== "undefined") {
callback();
} else if (attempt < 20) { // Retry for a few seconds
setTimeout(() => whenHljsReady(callback, attempt + 1), 100);
} else {
console.error("highlight.js (hljs) failed to load after several attempts.");
}
}
function fallbackCopyText(text, iconCheck, iconClipboard) {
const textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed';
textArea.style.top = '-9999px';
textArea.style.left = '-9999px';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
if (document.execCommand('copy')) {
iconCheck.style.display = 'inline';
iconClipboard.style.display = 'none';
setTimeout(() => {
iconCheck.style.display = 'none';
iconClipboard.style.display = 'inline';
}, 2000);
}
} catch (err) {
console.error('Fallback copy failed', err);
} finally {
document.body.removeChild(textArea);
}
}
function initCode(component) {
if (!component || component._codeInitialized) return; // Basic initialized check
const codeBlock = component.querySelector('[data-code-block]');
const copyButton = component.querySelector('[data-copy-button]');
const iconCheck = component.querySelector('[data-icon-check]');
const iconClipboard = component.querySelector('[data-icon-clipboard]');
// Highlight if hljs is available and not already highlighted
if (codeBlock && typeof hljs !== 'undefined') {
if (!codeBlock.classList.contains('hljs')) {
hljs.highlightElement(codeBlock);
}
}
// Setup copy button if elements exist
if (copyButton && codeBlock && iconCheck && iconClipboard) {
// Remove previous listener if any (important for re-initialization)
const oldListener = copyButton._copyListener;
if (oldListener) {
copyButton.removeEventListener('click', oldListener);
}
const newListener = () => {
const codeToCopy = codeBlock.textContent || '';
const showCopied = () => {
iconCheck.style.display = 'inline';
iconClipboard.style.display = 'none';
setTimeout(() => {
iconCheck.style.display = 'none';
iconClipboard.style.display = 'inline';
}, 2000);
};
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(codeToCopy)
.then(showCopied)
.catch(() => fallbackCopyText(codeToCopy, iconCheck, iconClipboard));
} else {
fallbackCopyText(codeToCopy, iconCheck, iconClipboard);
}
};
copyButton.addEventListener('click', newListener);
copyButton._copyListener = newListener; // Store listener for removal
}
component._codeInitialized = true; // Mark as initialized
}
function initAllComponents(root = document) {
if (root instanceof Element && root.matches('[data-code-component]')) {
initCode(root);
}
for (const component of root.querySelectorAll('[data-code-component]')) {
initCode(component);
}
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
whenHljsReady(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => {
whenHljsReady(() => initAllComponents());
});
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})(); // IIFE End
</script>
}
}

View file

@ -0,0 +1,256 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component code - version: main installed by templui v0.71.0
package code
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Size string
const (
SizeSm Size = "sm"
SizeLg Size = "lg"
SizeFull Size = "full"
)
type Props struct {
ID string
Class string
Attrs templ.Attributes
Language string
ShowCopyButton bool
Size Size
CodeClass string
}
func Code(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = Script().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var p Props
if len(props) > 0 {
p = props[0]
}
if p.ID == "" {
p.ID = "code-" + utils.RandomID()
}
var templ_7745c5c3_Var2 = []any{utils.TwMerge("relative code-component", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/code/code.templ`, Line: 37, Col: 11}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/code/code.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\" data-code-component")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attrs)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "><pre class=\"overflow-hidden!\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 = []any{
utils.TwMerge(
"language-"+p.Language,
"overflow-y-auto! rounded-md block text-sm max-h-[501px]",
utils.If(p.Size == SizeSm, "max-h-[250px]"),
utils.If(p.Size == SizeLg, "max-h-[1000px]"),
utils.If(p.Size == SizeFull, "max-h-full"),
"hljs-target",
p.CodeClass,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<code data-code-block class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var5).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/code/code.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</code></pre>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ShowCopyButton {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<button data-copy-button type=\"button\" class=\"absolute top-2 right-2 hover:bg-gray-500 hover:bg-opacity-30 text-white p-2 rounded\"><span data-icon-check class=\"hidden\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = icon.Check(icon.Props{Size: 14}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</span> <span data-icon-clipboard>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = icon.Clipboard(icon.Props{Size: 14}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</span></button>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var handle = templ.NewOnceHandle()
func Script() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var7 := templ.GetChildren(ctx)
if templ_7745c5c3_Var7 == nil {
templ_7745c5c3_Var7 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var8 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/pojoaque.min.css\"><script nonce=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(templ.GetNonce(ctx))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/code/code.templ`, Line: 82, Col: 37}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\" src=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js\"></script> <script nonce=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(templ.GetNonce(ctx))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/code/code.templ`, Line: 83, Col: 37}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\">\n\t\t\t(function() { // IIFE Start\n\t\t\t\tfunction whenHljsReady(callback, attempt = 1) {\n\t\t\t\t\tif (typeof hljs !== \"undefined\") {\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else if (attempt < 20) { // Retry for a few seconds\n\t\t\t\t\t\tsetTimeout(() => whenHljsReady(callback, attempt + 1), 100);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(\"highlight.js (hljs) failed to load after several attempts.\");\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfunction fallbackCopyText(text, iconCheck, iconClipboard) {\n\t\t\t\t\tconst textArea = document.createElement('textarea');\n\t\t\t\t\ttextArea.value = text;\n\t\t\t\t\ttextArea.style.position = 'fixed';\n\t\t\t\t\ttextArea.style.top = '-9999px';\n\t\t\t\t\ttextArea.style.left = '-9999px';\n\t\t\t\t\tdocument.body.appendChild(textArea);\n\t\t\t\t\ttextArea.focus();\n\t\t\t\t\ttextArea.select();\n\t\t\t\t\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (document.execCommand('copy')) {\n\t\t\t\t\t\t\ticonCheck.style.display = 'inline';\n\t\t\t\t\t\t\ticonClipboard.style.display = 'none';\n\t\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\t\ticonCheck.style.display = 'none';\n\t\t\t\t\t\t\t\ticonClipboard.style.display = 'inline';\n\t\t\t\t\t\t\t}, 2000);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.error('Fallback copy failed', err);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tdocument.body.removeChild(textArea);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfunction initCode(component) {\n\t\t\t\t\tif (!component || component._codeInitialized) return; // Basic initialized check\n\n\t\t\t\t\tconst codeBlock = component.querySelector('[data-code-block]');\n\t\t\t\t\tconst copyButton = component.querySelector('[data-copy-button]');\n\t\t\t\t\tconst iconCheck = component.querySelector('[data-icon-check]');\n\t\t\t\t\tconst iconClipboard = component.querySelector('[data-icon-clipboard]');\n\n\t\t\t\t\t// Highlight if hljs is available and not already highlighted\n\t\t\t\t\tif (codeBlock && typeof hljs !== 'undefined') {\n\t\t\t\t\t\tif (!codeBlock.classList.contains('hljs')) {\n\t\t\t\t\t\t\thljs.highlightElement(codeBlock);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Setup copy button if elements exist\n\t\t\t\t\tif (copyButton && codeBlock && iconCheck && iconClipboard) {\n\t\t\t\t\t\t// Remove previous listener if any (important for re-initialization)\n\t\t\t\t\t\tconst oldListener = copyButton._copyListener;\n\t\t\t\t\t\tif (oldListener) {\n\t\t\t\t\t\t\tcopyButton.removeEventListener('click', oldListener);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst newListener = () => {\n\t\t\t\t\t\t\tconst codeToCopy = codeBlock.textContent || '';\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tconst showCopied = () => {\n\t\t\t\t\t\t\t\ticonCheck.style.display = 'inline';\n\t\t\t\t\t\t\t\ticonClipboard.style.display = 'none';\n\t\t\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\t\t\ticonCheck.style.display = 'none';\n\t\t\t\t\t\t\t\t\ticonClipboard.style.display = 'inline';\n\t\t\t\t\t\t\t\t}, 2000);\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tif (navigator.clipboard && window.isSecureContext) {\n\t\t\t\t\t\t\t\tnavigator.clipboard.writeText(codeToCopy)\n\t\t\t\t\t\t\t\t\t.then(showCopied)\n\t\t\t\t\t\t\t\t\t.catch(() => fallbackCopyText(codeToCopy, iconCheck, iconClipboard));\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfallbackCopyText(codeToCopy, iconCheck, iconClipboard);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tcopyButton.addEventListener('click', newListener);\n\t\t\t\t\t\tcopyButton._copyListener = newListener; // Store listener for removal\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tcomponent._codeInitialized = true; // Mark as initialized\n\t\t\t\t}\n\n\t\t\t\tfunction initAllComponents(root = document) {\n\t\t\t\t\tif (root instanceof Element && root.matches('[data-code-component]')) {\n\t\t\t\t\t\tinitCode(root);\n\t\t\t\t\t}\n\t\t\t\t\tfor (const component of root.querySelectorAll('[data-code-component]')) {\n\t\t\t\t\t\tinitCode(component);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst handleHtmxSwap = (event) => {\n\t\t\t\t\tconst target = event.detail.target || event.detail.elt;\n\t\t\t\t\tif (target instanceof Element) {\n\t\t\t\t\t\twhenHljsReady(() => initAllComponents(target));\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tinitAllComponents();\n\t\t\t\tdocument.addEventListener('DOMContentLoaded', () => {\n\t\t\t\t\twhenHljsReady(() => initAllComponents());\n\t\t\t\t});\n\t\t\t\tdocument.body.addEventListener('htmx:afterSwap', handleHtmxSwap);\n\t\t\t\tdocument.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);\n\t\t\t})(); // IIFE End\n\t\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = handle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var8), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,319 @@
// templui component datepicker - version: main installed by templui v0.71.0
package datepicker
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/calendar"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/popover"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
"time"
)
type Format string
type LocaleTag string
const (
FormatLOCALE_SHORT Format = "locale-short" // Locale-specific short format (e.g., MM/DD/YY or DD.MM.YY)
FormatLOCALE_MEDIUM Format = "locale-medium" // Locale-specific medium format (e.g., Jan 5, 2024 or 5. Jan. 2024)
FormatLOCALE_LONG Format = "locale-long" // Locale-specific long format (e.g., January 5, 2024 or 5. Januar 2024)
FormatLOCALE_FULL Format = "locale-full" // Locale-specific full format (e.g., Monday, January 5, 2024 or Montag, 5. Januar 2024)
)
// Common Locale (BCP 47)
var (
LocaleDefaultTag = LocaleTag("en-US")
LocaleTagChinese = LocaleTag("zh-CN")
LocaleTagFrench = LocaleTag("fr-FR")
LocaleTagGerman = LocaleTag("de-DE")
LocaleTagItalian = LocaleTag("it-IT")
LocaleTagJapanese = LocaleTag("ja-JP")
LocaleTagPortuguese = LocaleTag("pt-PT")
LocaleTagSpanish = LocaleTag("es-ES")
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Value time.Time
Format Format // Controls the display format using Intl dateStyle options.
LocaleTag LocaleTag // BCP 47 Locale Tag (e.g., "en-US", "es-ES"). Determines language and regional format defaults.
Placeholder string
Disabled bool
Required bool
HasError bool
Name string
}
templ DatePicker(props ...Props) {
@Script()
{{
var p Props
if len(props) > 0 {
p = props[0]
}
if p.ID == "" {
p.ID = utils.RandomID()
}
if p.Name == "" {
p.Name = p.ID
}
if p.Placeholder == "" {
p.Placeholder = "Select a date"
}
if p.LocaleTag == "" {
p.LocaleTag = LocaleDefaultTag
}
if p.Format == "" {
p.Format = FormatLOCALE_MEDIUM
}
var contentID = p.ID + "-content"
var valuePtr *time.Time
if !p.Value.IsZero() {
valuePtr = &p.Value
}
}}
@popover.Popover() {
@popover.Trigger(popover.TriggerProps{For: contentID}) {
@button.Button(button.Props{
ID: p.ID,
Variant: button.VariantOutline,
Class: utils.TwMerge(
"w-full select-trigger flex items-center justify-between",
utils.If(p.HasError, "border-destructive ring-destructive"),
p.Class,
),
Disabled: p.Disabled,
Attributes: utils.MergeAttributes(p.Attributes, templ.Attributes{
"data-datepicker": "true",
"data-display-format": string(p.Format),
"data-locale-tag": string(p.LocaleTag),
"data-placeholder": p.Placeholder,
}),
}) {
if p.Placeholder != "" {
<span data-datepicker-display class={ "text-left grow text-muted-foreground" }>
{ p.Placeholder }
</span>
}
<span class="text-muted-foreground flex items-center ml-2">
@icon.Calendar(icon.Props{Size: 16})
</span>
}
}
@popover.Content(popover.ContentProps{
ID: contentID,
Placement: popover.PlacementBottomStart,
Class: "p-3",
}) {
@calendar.Calendar(calendar.Props{
ID: p.ID + "-calendar-instance", // Pass ID for calendar instance
Name: p.Name, // Pass Name for hidden input
LocaleTag: calendar.LocaleTag(p.LocaleTag), // Pass locale tag to calendar
Value: valuePtr, // Pass pointer to value
})
}
}
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<script defer nonce={ templ.GetNonce(ctx) }>
(function() { // IIFE Start
function parseISODate(isoString) {
if (!isoString || typeof isoString !== 'string') return null;
const parts = isoString.match(/^(\d{4})-(\d{2})-(\d{2})$/);
if (!parts) return null;
const year = parseInt(parts[1], 10);
const month = parseInt(parts[2], 10) - 1; // JS month is 0-indexed
const day = parseInt(parts[3], 10);
const date = new Date(Date.UTC(year, month, day));
if (date.getUTCFullYear() === year && date.getUTCMonth() === month && date.getUTCDate() === day) {
return date;
}
return null;
}
function formatDateWithIntl(date, format, localeTag) {
if (!date || isNaN(date.getTime())) return '';
// Always use UTC for formatting to avoid timezone shifts
let options = { timeZone: 'UTC' };
switch(format) {
case 'locale-short':
options.dateStyle = 'short';
break;
case 'locale-long':
options.dateStyle = 'long';
break;
case 'locale-full':
options.dateStyle = 'full';
break;
case 'locale-medium': // Default to medium
default:
options.dateStyle = 'medium';
break;
}
try {
// Explicitly pass the options object with timeZone: 'UTC'
return new Intl.DateTimeFormat(localeTag, options).format(date);
} catch (e) {
console.error(`Error formatting date with Intl (locale: ${localeTag}, format: ${format}, timezone: UTC):`, e);
// Fallback to locale default medium on error, still using UTC
try {
const fallbackOptions = { dateStyle: 'medium', timeZone: 'UTC' };
return new Intl.DateTimeFormat(localeTag, fallbackOptions).format(date);
} catch (fallbackError) {
console.error(`Error formatting date with fallback Intl (locale: ${localeTag}, timezone: UTC):`, fallbackError);
// Absolute fallback: Format the UTC date parts manually if Intl fails completely
const year = date.getUTCFullYear();
// getUTCMonth is 0-indexed, add 1 for display
const month = (date.getUTCMonth() + 1).toString().padStart(2, '0');
const day = date.getUTCDate().toString().padStart(2, '0');
return `${year}-${month}-${day}`; // Simple ISO format as absolute fallback
}
}
}
function initDatePicker(triggerButton) {
if (!triggerButton || triggerButton._datePickerInitialized) return;
const datePickerID = triggerButton.id;
const displaySpan = triggerButton.querySelector('[data-datepicker-display]');
const calendarInstanceId = datePickerID + '-calendar-instance';
const calendarInstance = document.getElementById(calendarInstanceId);
const calendarHiddenInputId = calendarInstanceId + '-hidden';
const calendarHiddenInput = document.getElementById(calendarHiddenInputId);
// Fallback to find calendar relatively
let calendar = calendarInstance;
let hiddenInput = calendarHiddenInput;
if (!calendarInstance || !calendarHiddenInput) {
const popoverContentId = triggerButton.getAttribute('aria-controls');
const popoverContent = popoverContentId ? document.getElementById(popoverContentId) : null;
if (popoverContent) {
if (!calendar) calendar = popoverContent.querySelector('[data-calendar-container]');
if (!hiddenInput) {
const wrapper = popoverContent.querySelector('[data-calendar-wrapper]');
hiddenInput = wrapper ? wrapper.querySelector('[data-calendar-hidden-input]') : null;
}
}
}
if (!displaySpan || !calendar || !hiddenInput) {
console.error("DatePicker init error: Missing required elements.", { datePickerID, displaySpan, calendar, hiddenInput });
return;
}
const displayFormat = triggerButton.dataset.displayFormat || 'locale-medium';
const localeTag = triggerButton.dataset.localeTag || 'en-US';
const placeholder = triggerButton.dataset.placeholder || 'Select a date';
const onCalendarSelect = (event) => {
if (!event.detail || !event.detail.date || !(event.detail.date instanceof Date)) return;
const selectedDate = event.detail.date;
const displayFormattedValue = formatDateWithIntl(selectedDate, displayFormat, localeTag);
displaySpan.textContent = displayFormattedValue;
displaySpan.classList.remove('text-muted-foreground');
// Find and click the popover trigger to close it
const popoverTrigger = triggerButton.closest('[data-popover]')?.querySelector('[data-popover-trigger]');
if (popoverTrigger instanceof HTMLElement) {
popoverTrigger.click();
} else {
triggerButton.click(); // Fallback: click the button itself (might not work if inside popover)
}
};
const updateDisplay = () => {
if (hiddenInput && hiddenInput.value) {
const initialDate = parseISODate(hiddenInput.value);
if (initialDate) {
const correctlyFormatted = formatDateWithIntl(initialDate, displayFormat, localeTag);
if (displaySpan.textContent.trim() !== correctlyFormatted) {
displaySpan.textContent = correctlyFormatted;
displaySpan.classList.remove('text-muted-foreground');
}
} else {
// Handle case where hidden input has invalid value
displaySpan.textContent = placeholder;
displaySpan.classList.add('text-muted-foreground');
}
} else {
// Ensure placeholder is shown if no value
displaySpan.textContent = placeholder;
displaySpan.classList.add('text-muted-foreground');
}
};
// Attach listener to the specific calendar instance
calendar.addEventListener('calendar-date-selected', onCalendarSelect);
updateDisplay(); // Initial display update
triggerButton._datePickerInitialized = true;
// Store cleanup function on the button itself
triggerButton._datePickerCleanup = () => {
if (calendar) {
calendar.removeEventListener('calendar-date-selected', onCalendarSelect);
}
};
}
function initAllComponents(root = document) {
if (root instanceof Element && root.matches('[data-datepicker="true"]')) {
initDatePicker(root);
}
root.querySelectorAll('[data-datepicker="true"]').forEach(triggerButton => {
initDatePicker(triggerButton);
});
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:beforeSwap', (event) => {
let target = event.detail.target || event.detail.elt;;
if (target instanceof Element) {
const cleanup = (button) => {
if (button.matches && button.matches('[data-datepicker="true"]')) {
if (button._datePickerCleanup) {
button._datePickerCleanup();
delete button._datePickerCleanup;
delete button._datePickerInitialized;
}
}
};
// Cleanup the target itself if it's a trigger button
if (target.matches && target.matches('[data-datepicker="true"]')) {
cleanup(target);
}
// Cleanup trigger buttons within the target
if (target.querySelectorAll) {
target.querySelectorAll('[data-datepicker="true"]').forEach(cleanup);
}
}
});
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})(); // End of IIFE
</script>
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,432 @@
// templui component drawer - version: main installed by templui v0.71.0
package drawer
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Position string
const (
PositionTop Position = "top"
PositionRight Position = "right"
PositionBottom Position = "bottom"
PositionLeft Position = "left"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Side Position
}
type TriggerProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ContentProps struct {
ID string
Class string
Attributes templ.Attributes
Position Position
}
type HeaderProps struct {
ID string
Class string
Attributes templ.Attributes
}
type FooterProps struct {
ID string
Class string
Attributes templ.Attributes
}
type TitleProps struct {
ID string
Class string
Attributes templ.Attributes
}
type DescriptionProps struct {
ID string
Class string
Attributes templ.Attributes
}
type CloseProps struct {
ID string
Class string
Attributes templ.Attributes
}
templ Drawer(props ...Props) {
@Script()
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.ID == "" {
{{ p.ID = utils.RandomID() }}
}
<div
id={ p.ID }
class={ utils.TwMerge("relative", p.Class) }
data-component="drawer"
data-drawer-id={ p.ID }
{ p.Attributes... }
>
{ children... }
</div>
}
templ Trigger(props ...TriggerProps) {
{{ var p TriggerProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("cursor-pointer", p.Class) }
data-drawer-trigger
{ p.Attributes... }
>
{ children... }
</div>
}
templ Content(props ...ContentProps) {
{{ var p ContentProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.ID == "" {
{{ p.ID = utils.RandomID() }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class="fixed inset-0 z-50 bg-background/80 backdrop-blur-xs templui-drawer-backdrop hidden"
data-drawer-backdrop
></div>
<div
id={ p.ID + "-content" }
class={
utils.TwMerge(
"fixed z-50 templui-drawer-content hidden",
p.Class,
utils.If(p.Position == PositionRight, "inset-y-0 right-0 w-3/4 md:w-1/2 lg:w-1/3"),
utils.If(p.Position == PositionLeft, "inset-y-0 left-0 w-3/4 md:w-1/2 lg:w-1/3"),
utils.If(p.Position == PositionTop, "inset-x-0 top-0 h-auto sm:h-1/2"),
utils.If(p.Position == PositionBottom, "inset-x-0 bottom-0 h-auto sm:h-1/2"),
),
}
data-drawer-content
data-drawer-position={ string(p.Position) }
{ p.Attributes... }
>
<div
class={
utils.TwMerge(
"h-full overflow-y-auto bg-background p-6 shadow-lg",
utils.If(p.Position == PositionRight, "border-l"),
utils.If(p.Position == PositionLeft, "border-r"),
utils.If(p.Position == PositionBottom, "border-t"),
utils.If(p.Position == PositionTop, "border-b"),
),
}
data-drawer-inner
>
{ children... }
</div>
</div>
}
templ Header(props ...HeaderProps) {
{{ var p HeaderProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("flex flex-col space-y-1.5 pb-4", p.Class) }
{ p.Attributes... }
>
{ children... }
</div>
}
templ Title(props ...TitleProps) {
{{ var p TitleProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<h2
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("text-lg font-semibold leading-none tracking-tight", p.Class) }
{ p.Attributes... }
>
{ children... }
</h2>
}
templ Description(props ...DescriptionProps) {
{{ var p DescriptionProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<p
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("text-sm text-muted-foreground", p.Class) }
{ p.Attributes... }
>
{ children... }
</p>
}
templ Footer(props ...FooterProps) {
{{ var p FooterProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 pt-4", p.Class) }
{ p.Attributes... }
>
{ children... }
</div>
}
templ Close(props ...CloseProps) {
{{ var p CloseProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<button
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background",
"transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent",
"hover:text-accent-foreground h-10 px-4 py-2",
p.Class,
),
}
data-drawer-close
{ p.Attributes... }
>
{ children... }
</button>
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<script nonce={ templ.GetNonce(ctx) }>
(function() { // IIFE
function initDrawer(drawer) {
// Get the drawer elements
const triggers = drawer.querySelectorAll('[data-drawer-trigger]');
const content = drawer.querySelector('[data-drawer-content]');
const backdrop = drawer.querySelector('[data-drawer-backdrop]');
const closeButtons = drawer.querySelectorAll('[data-drawer-close]');
const position = content?.getAttribute('data-drawer-position') || 'right';
if (!content || !backdrop) return;
// Set up animations based on position
const transitions = {
'left': {
enterFrom: 'opacity-0 -translate-x-full',
enterTo: 'opacity-100 translate-x-0',
leaveFrom: 'opacity-100 translate-x-0',
leaveTo: 'opacity-0 -translate-x-full'
},
'right': {
enterFrom: 'opacity-0 translate-x-full',
enterTo: 'opacity-100 translate-x-0',
leaveFrom: 'opacity-100 translate-x-0',
leaveTo: 'opacity-0 translate-x-full'
},
'top': {
enterFrom: 'opacity-0 -translate-y-full',
enterTo: 'opacity-100 translate-y-0',
leaveFrom: 'opacity-100 translate-y-0',
leaveTo: 'opacity-0 -translate-y-full'
},
'bottom': {
enterFrom: 'opacity-0 translate-y-full',
enterTo: 'opacity-100 translate-y-0',
leaveFrom: 'opacity-100 translate-y-0',
leaveTo: 'opacity-0 translate-y-full'
}
};
// Check if drawer is already initialized
if (drawer.dataset.drawerInitialized) {
return;
}
drawer.dataset.drawerInitialized = 'true';
// Initial styles
content.style.transform = position === 'left' ? 'translateX(-100%)' :
position === 'right' ? 'translateX(100%)' :
position === 'top' ? 'translateY(-100%)' :
'translateY(100%)';
content.style.opacity = '0';
backdrop.style.opacity = '0';
content.style.display = 'none'; // Ensure it starts hidden
backdrop.style.display = 'none'; // Ensure it starts hidden
// Function to open the drawer
function openDrawer() {
// Display elements
backdrop.style.display = 'block';
content.style.display = 'block';
// Trigger reflow
void content.offsetWidth;
// Apply transitions
backdrop.style.transition = 'opacity 300ms ease-out';
content.style.transition = 'opacity 300ms ease-out, transform 300ms ease-out';
// Animate in
backdrop.style.opacity = '1';
content.style.opacity = '1';
content.style.transform = 'translate(0)';
// Lock body scroll
document.body.style.overflow = 'hidden';
// Add event listeners for close actions
backdrop.addEventListener('click', closeDrawer);
document.addEventListener('keydown', handleEscKey);
document.addEventListener('click', handleClickAway);
}
// Function to close the drawer
function closeDrawer() {
// Remove event listeners before animation starts
backdrop.removeEventListener('click', closeDrawer);
document.removeEventListener('keydown', handleEscKey);
document.removeEventListener('click', handleClickAway);
// Apply transitions
backdrop.style.transition = 'opacity 300ms ease-in';
content.style.transition = 'opacity 300ms ease-in, transform 300ms ease-in';
// Animate out
backdrop.style.opacity = '0';
if (position === 'left') {
content.style.transform = 'translateX(-100%)';
} else if (position === 'right') {
content.style.transform = 'translateX(100%)';
} else if (position === 'top') {
content.style.transform = 'translateY(-100%)';
} else if (position === 'bottom') {
content.style.transform = 'translateY(100%)';
}
content.style.opacity = '0';
// Hide elements after animation
setTimeout(() => {
if (content.style.opacity === '0') { // Check if it wasn't reopened during the timeout
backdrop.style.display = 'none';
content.style.display = 'none';
}
// Unlock body scroll only if no other drawers are open
const anyDrawerOpen = document.querySelector('[data-component="drawer"] [data-drawer-backdrop][style*="display: block"]');
if (!anyDrawerOpen) {
document.body.style.overflow = '';
}
}, 300);
}
// Click away handler
function handleClickAway(e) {
// Check if the click is outside the content AND not on any trigger associated with THIS drawer
if (content.style.display === 'block' &&
!content.contains(e.target) &&
!Array.from(triggers).some(trigger => trigger.contains(e.target))) {
closeDrawer();
}
}
// ESC key handler
function handleEscKey(e) {
if (e.key === 'Escape' && content.style.display === 'block') {
closeDrawer();
}
}
// Set up trigger click listeners
triggers.forEach(trigger => {
trigger.removeEventListener('click', openDrawer); // Remove potential duplicates
trigger.addEventListener('click', openDrawer);
});
// Set up close button listeners
closeButtons.forEach(button => {
button.removeEventListener('click', closeDrawer); // Remove potential duplicates
button.addEventListener('click', closeDrawer);
});
// Stop propagation on the inner content click to prevent backdrop click handler
const inner = content.querySelector('[data-drawer-inner]');
if (inner) {
inner.removeEventListener('click', stopPropagationHandler); // Remove potential duplicates
inner.addEventListener('click', stopPropagationHandler);
}
}
function stopPropagationHandler(e) {
e.stopPropagation();
}
function initAllComponents(root = document) {
if (root instanceof Element && root.matches('[data-component="drawer"]')) {
initDrawer(root);
}
if (root && typeof root.querySelectorAll === 'function') {
const drawers = root.querySelectorAll('[data-component="drawer"]');
drawers.forEach(initDrawer);
}
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})(); // End of IIFE
</script>
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,421 @@
// templui component dropdown - version: main installed by templui v0.71.0
package dropdown
import (
"context"
"fmt"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/popover"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type contextKey string
var (
contentIDKey contextKey = "contentID"
subContentIDKey contextKey = "subContentID"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
type TriggerProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ContentProps struct {
ID string
Class string
Attributes templ.Attributes
Width string
MaxHeight string
Align string
Side string
}
type GroupProps struct {
ID string
Class string
Attributes templ.Attributes
}
type LabelProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ItemProps struct {
ID string
Class string
Attributes templ.Attributes
Disabled bool
Href string
Target string
}
type SeparatorProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ShortcutProps struct {
ID string
Class string
Attributes templ.Attributes
}
type SubProps struct {
ID string
Class string
Attributes templ.Attributes
}
type SubTriggerProps struct {
ID string
Class string
Attributes templ.Attributes
}
type SubContentProps struct {
ID string
Class string
Attributes templ.Attributes
}
type PortalProps struct {
ID string
Class string
Attributes templ.Attributes
}
templ Dropdown(props ...Props) {
@Script()
{{
var p Props
if len(props) > 0 {
p = props[0]
}
contentID := p.ID
if contentID == "" {
contentID = utils.RandomID()
}
ctx = context.WithValue(ctx, contentIDKey, contentID)
}}
@popover.Popover(popover.Props{
Class: p.Class,
}) {
{ children... }
}
}
templ Trigger(props ...TriggerProps) {
{{
var p TriggerProps
if len(props) > 0 {
p = props[0]
}
contentID, ok := ctx.Value(contentIDKey).(string)
if !ok {
contentID = "fallback-content-id"
}
}}
@popover.Trigger(popover.TriggerProps{
ID: p.ID,
For: contentID, TriggerType: popover.TriggerTypeClick,
}) {
<span
class={ utils.TwMerge("inline-block", p.Class) }
{ p.Attributes... }
>
{ children... }
</span>
}
}
templ Content(props ...ContentProps) {
{{ var p ContentProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
{{ contentID, ok := ctx.Value(contentIDKey).(string) }}
if !ok {
{{ contentID = "fallback-content-id" }} // Must match fallback in Trigger
}
{{
var maxHeight string = "300px"
if p.MaxHeight != "" {
maxHeight = p.MaxHeight
}
maxHeightClass := fmt.Sprintf("max-h-[%s]", maxHeight)
}}
@popover.Content(popover.ContentProps{
ID: contentID,
Placement: popover.PlacementBottomStart,
Offset: 4,
Class: utils.TwMerge(
"z-50 rounded-md bg-popover p-1 shadow-md focus:outline-none overflow-auto",
"border border-border",
"min-w-[8rem]",
maxHeightClass,
p.Width,
p.Class,
),
Attributes: p.Attributes,
}) {
{ children... }
}
}
templ Group(props ...GroupProps) {
{{ var p GroupProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("py-1", p.Class) }
role="group"
{ p.Attributes... }
>
{ children... }
</div>
}
templ Label(props ...LabelProps) {
{{ var p LabelProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("px-2 py-1.5 text-sm font-semibold", p.Class) }
{ p.Attributes... }
>
{ children... }
</div>
}
templ Item(props ...ItemProps) {
{{ var p ItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.ID == "" {
{{ p.ID = utils.RandomID() }}
}
if p.Href != "" {
<a
id={ p.ID }
if p.Href != "" {
href={ templ.SafeURL(p.Href) }
}
if p.Target != "" {
target={ p.Target }
}
class={
utils.TwMerge(
"flex text-left items-center px-2 py-1.5 text-sm rounded-sm",
utils.If(!p.Disabled, "focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default"),
utils.If(p.Disabled, "opacity-50 pointer-events-none"),
p.Class,
),
}
role="menuitem"
data-dropdown-item
{ p.Attributes... }
>
{ children... }
</a>
} else {
<button
id={ p.ID }
class={
utils.TwMerge(
"w-full text-left flex items-center justify-between px-2 py-1.5 text-sm rounded-sm",
utils.If(!p.Disabled, "focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default"),
utils.If(p.Disabled, "opacity-50 pointer-events-none"),
p.Class,
),
}
role="menuitem"
data-dropdown-item
disabled?={ p.Disabled }
{ p.Attributes... }
>
{ children... }
</button>
}
}
templ Separator(props ...SeparatorProps) {
{{ var p SeparatorProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("h-px my-1 -mx-1 bg-muted", p.Class) }
role="separator"
{ p.Attributes... }
></div>
}
templ Shortcut(props ...ShortcutProps) {
{{ var p ShortcutProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("ml-auto text-xs tracking-widest opacity-60", p.Class) }
{ p.Attributes... }
>
{ children... }
</span>
}
templ Sub(props ...SubProps) {
{{
var p SubProps
if len(props) > 0 {
p = props[0]
}
subContentID := p.ID
if subContentID == "" {
subContentID = utils.RandomID()
}
ctx = context.WithValue(ctx, subContentIDKey, subContentID)
}}
<div
if p.ID != "" {
id={ p.ID }
}
data-dropdown-submenu
class={ utils.TwMerge("relative", p.Class) }
{ p.Attributes... }
>
{ children... }
</div>
}
templ SubTrigger(props ...SubTriggerProps) {
{{
var p SubTriggerProps
if len(props) > 0 {
p = props[0]
}
subContentID, ok := ctx.Value(subContentIDKey).(string)
if !ok {
subContentID = "fallback-subcontent-id"
}
}}
@popover.Trigger(popover.TriggerProps{
ID: p.ID,
For: subContentID,
TriggerType: popover.TriggerTypeHover,
}) {
<button
type="button"
data-dropdown-submenu-trigger
class={
utils.TwMerge(
"w-full text-left flex items-center justify-between px-2 py-1.5 text-sm rounded-sm",
"focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default",
p.Class,
),
}
{ p.Attributes... }
>
<span>
{ children... }
</span>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 ml-auto">
<path d="M6.5 3L11.5 8L6.5 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>
</svg>
</button>
}
}
templ SubContent(props ...SubContentProps) {
{{
var p SubContentProps
if len(props) > 0 {
p = props[0]
}
subContentID, ok := ctx.Value(subContentIDKey).(string)
if !ok {
subContentID = "fallback-subcontent-id"
}
}}
@popover.Content(popover.ContentProps{
ID: subContentID,
Placement: popover.PlacementRightStart,
Offset: -4, // Adjust as needed
HoverDelay: 100, // ms
HoverOutDelay: 200, // ms
Class: utils.TwMerge(
"z-[9999] min-w-[8rem] rounded-md border bg-popover p-1 shadow-lg",
p.Class,
),
Attributes: p.Attributes,
}) {
{ children... }
}
}
var dropdownHandle = templ.NewOnceHandle()
templ Script() {
<script nonce={ templ.GetNonce(ctx) }>
(function() { // IIFE
function handleDropdownItemClick(event) {
const item = event.currentTarget;
const popoverContent = item.closest('[data-popover-id]');
if (popoverContent) {
const popoverId = popoverContent.dataset.popoverId;
if (window.closePopover) {
window.closePopover(popoverId, true);
} else {
console.warn("popover.Script's closePopover function not found.");
document.body.click(); // Fallback
}
}
}
function initAllComponents(root = document) {
// Select items with 'data-dropdown-item' but not 'data-dropdown-submenu-trigger'
const items = root.querySelectorAll('[data-dropdown-item]:not([data-dropdown-submenu-trigger])');
items.forEach(item => {
item.removeEventListener('click', handleDropdownItemClick);
item.addEventListener('click', handleDropdownItemClick);
});
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})(); // End of IIFE
</script>
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,137 @@
// templui component form - version: main installed by templui v0.71.0
package form
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/label"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type MessageVariant string
const (
MessageVariantError MessageVariant = "error"
MessageVariantInfo MessageVariant = "info"
)
type ItemProps struct {
ID string
Class string
Attributes templ.Attributes
}
type LabelProps struct {
ID string
Class string
Attributes templ.Attributes
For string
DisabledClass string
}
type DescriptionProps struct {
ID string
Class string
Attributes templ.Attributes
}
type MessageProps struct {
ID string
Class string
Attributes templ.Attributes
Variant MessageVariant
}
templ Item(props ...ItemProps) {
{{ var p ItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("space-y-2", p.Class) }
{ p.Attributes... }
>
{ children... }
</div>
}
templ ItemFlex(props ...ItemProps) {
{{ var p ItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("items-center flex space-x-2", p.Class) }
{ p.Attributes... }
>
{ children... }
</div>
}
templ Label(props ...LabelProps) {
{{ var p LabelProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
@label.Label(label.Props{
ID: p.ID,
Class: p.Class,
Attributes: p.Attributes,
For: p.For,
}) {
{ children... }
}
}
templ Description(props ...DescriptionProps) {
{{ var p DescriptionProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<p
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("text-sm text-muted-foreground", p.Class) }
{ p.Attributes... }
>
{ children... }
</p>
}
templ Message(props ...MessageProps) {
{{ var p MessageProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<p
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"text-[0.8rem] font-medium",
messageVariantClass(p.Variant),
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</p>
}
func messageVariantClass(variant MessageVariant) string {
switch variant {
case MessageVariantError:
return "text-red-500"
case MessageVariantInfo:
return "text-blue-500"
default:
return ""
}
}

View file

@ -0,0 +1,485 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component form - version: main installed by templui v0.71.0
package form
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/label"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type MessageVariant string
const (
MessageVariantError MessageVariant = "error"
MessageVariantInfo MessageVariant = "info"
)
type ItemProps struct {
ID string
Class string
Attributes templ.Attributes
}
type LabelProps struct {
ID string
Class string
Attributes templ.Attributes
For string
DisabledClass string
}
type DescriptionProps struct {
ID string
Class string
Attributes templ.Attributes
}
type MessageProps struct {
ID string
Class string
Attributes templ.Attributes
Variant MessageVariant
}
func Item(props ...ItemProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p ItemProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{utils.TwMerge("space-y-2", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/form/form.templ`, Line: 50, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/form/form.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func ItemFlex(props ...ItemProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p ItemProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var6 = []any{utils.TwMerge("items-center flex space-x-2", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/form/form.templ`, Line: 66, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/form/form.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var5.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Label(props ...LabelProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
if templ_7745c5c3_Var9 == nil {
templ_7745c5c3_Var9 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p LabelProps
if len(props) > 0 {
p = props[0]
}
templ_7745c5c3_Var10 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templ_7745c5c3_Var9.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = label.Label(label.Props{
ID: p.ID,
Class: p.Class,
Attributes: p.Attributes,
For: p.For,
}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var10), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Description(props ...DescriptionProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var11 := templ.GetChildren(ctx)
if templ_7745c5c3_Var11 == nil {
templ_7745c5c3_Var11 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p DescriptionProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var12 = []any{utils.TwMerge("text-sm text-muted-foreground", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<p")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/form/form.templ`, Line: 97, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var12).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/form/form.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var11.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</p>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Message(props ...MessageProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var15 := templ.GetChildren(ctx)
if templ_7745c5c3_Var15 == nil {
templ_7745c5c3_Var15 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p MessageProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var16 = []any{
utils.TwMerge(
"text-[0.8rem] font-medium",
messageVariantClass(p.Variant),
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "<p")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/form/form.templ`, Line: 113, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var16).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/form/form.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var15.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "</p>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func messageVariantClass(variant MessageVariant) string {
switch variant {
case MessageVariantError:
return "text-red-500"
case MessageVariantInfo:
return "text-blue-500"
default:
return ""
}
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,117 @@
// templui component icon - version: main installed by templui v0.71.0
package icon
import (
"context"
"fmt"
"io"
"sync"
"github.com/a-h/templ"
)
// iconContents caches the fully generated SVG strings for icons that have been used,
// keyed by a composite key of name and props to handle different stylings.
var (
iconContents = make(map[string]string)
iconMutex sync.RWMutex
)
// Props defines the properties that can be set for an icon.
type Props struct {
Size int
Color string
Fill string
Stroke string
StrokeWidth string // Stroke Width of Icon, Usage: "2.5"
Class string
}
// Icon returns a function that generates a templ.Component for the specified icon name.
func Icon(name string) func(...Props) templ.Component {
return func(props ...Props) templ.Component {
var p Props
if len(props) > 0 {
p = props[0]
}
// Create a unique key for the cache based on icon name and all relevant props.
// This ensures different stylings of the same icon are cached separately.
cacheKey := fmt.Sprintf("%s|s:%d|c:%s|f:%s|sk:%s|sw:%s|cl:%s",
name, p.Size, p.Color, p.Fill, p.Stroke, p.StrokeWidth, p.Class)
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
iconMutex.RLock()
svg, cached := iconContents[cacheKey]
iconMutex.RUnlock()
if cached {
_, err = w.Write([]byte(svg))
return err
}
// Not cached, generate it
// The actual generation now happens once and is cached.
generatedSvg, err := generateSVG(name, p) // p (Props) is passed to generateSVG
if err != nil {
// Provide more context in the error message
return fmt.Errorf("failed to generate svg for icon '%s' with props %+v: %w", name, p, err)
}
iconMutex.Lock()
iconContents[cacheKey] = generatedSvg
iconMutex.Unlock()
_, err = w.Write([]byte(generatedSvg))
return err
})
}
}
// generateSVG creates an SVG string for the specified icon with the given properties.
// This function is called when an icon-prop combination is not yet in the cache.
func generateSVG(name string, props Props) (string, error) {
// Get the raw, inner SVG content for the icon name from our internal data map.
content, err := getIconContent(name) // This now reads from internalSvgData
if err != nil {
return "", err // Error from getIconContent already includes icon name
}
size := props.Size
if size <= 0 {
size = 24 // Default size
}
fill := props.Fill
if fill == "" {
fill = "none" // Default fill
}
stroke := props.Stroke
if stroke == "" {
stroke = props.Color // Fallback to Color if Stroke is not set
}
if stroke == "" {
stroke = "currentColor" // Default stroke color
}
strokeWidth := props.StrokeWidth
if strokeWidth == "" {
strokeWidth = "2" // Default stroke width
}
// Construct the final SVG string.
// The data-lucide attribute helps identify these as Lucide icons if needed.
return fmt.Sprintf("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"%d\" height=\"%d\" viewBox=\"0 0 24 24\" fill=\"%s\" stroke=\"%s\" stroke-width=\"%s\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"%s\" data-lucide=\"icon\">%s</svg>",
size, size, fill, stroke, strokeWidth, props.Class, content), nil
}
// getIconContent retrieves the raw inner SVG content for a given icon name.
// It reads from the pre-generated internalSvgData map from icon_data.go.
func getIconContent(name string) (string, error) {
content, exists := internalSvgData[name]
if !exists {
return "", fmt.Errorf("icon '%s' not found in internalSvgData map", name)
}
return content, nil
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,165 @@
// templui component input - version: main installed by templui v0.71.0
package input
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Type string
const (
TypeText Type = "text"
TypePassword Type = "password"
TypeEmail Type = "email"
TypeNumber Type = "number"
TypeTel Type = "tel"
TypeURL Type = "url"
TypeSearch Type = "search"
TypeDate Type = "date"
TypeTime Type = "time"
TypeFile Type = "file"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Name string
Type Type
Placeholder string
Value string
Disabled bool
Readonly bool
Required bool
FileAccept string
HasError bool
NoTogglePassword bool
}
templ Input(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.Type == "" {
{{ p.Type = TypeText }}
}
if p.ID == "" {
{{ p.ID = utils.RandomID() }}
}
if p.Type == TypePassword && !p.NoTogglePassword {
@Script()
}
<div class="relative w-full">
<input
id={ p.ID }
type={ string(p.Type) }
if p.Name != "" {
name={ p.Name }
}
if p.Placeholder != "" {
placeholder={ p.Placeholder }
}
if p.Value != "" {
value={ p.Value }
}
if p.Type == TypeFile && p.FileAccept != "" {
accept={ p.FileAccept }
}
disabled?={ p.Disabled }
readonly?={ p.Readonly }
required?={ p.Required }
class={
utils.TwMerge(
"peer flex h-10 w-full px-3 py-2",
"rounded-md border border-input bg-background text-sm ring-offset-background",
"file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground",
"placeholder:text-muted-foreground",
"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"disabled:cursor-not-allowed disabled:opacity-50",
utils.If(p.HasError, "border-destructive ring-destructive"),
utils.If(p.Type == TypePassword && !p.NoTogglePassword, "pr-8"),
p.Class,
),
}
{ p.Attributes... }
/>
if p.Type == TypePassword && !p.NoTogglePassword {
@button.Button(button.Props{
Size: button.SizeIcon,
Variant: button.VariantGhost,
Class: "absolute right-0 top-1/2 -translate-y-1/2 opacity-50 cursor-pointer",
Attributes: templ.Attributes{"data-toggle-password": p.ID},
}) {
<span class="icon-open block">
@icon.Eye(icon.Props{
Size: 18,
})
</span>
<span class="icon-closed hidden">
@icon.EyeOff(icon.Props{
Size: 18,
})
</span>
}
}
</div>
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<script nonce={ templ.GetNonce(ctx) }>
(function() { // IIFE Start
function initPasswordToggle(button) {
if (button.hasAttribute('data-password-initialized')) {
return;
}
button.setAttribute('data-password-initialized', 'true');
button.addEventListener('click', function(event) {
const inputId = button.getAttribute('data-toggle-password');
const input = document.getElementById(inputId);
if (input) {
const iconOpen = button.querySelector('.icon-open');
const iconClosed = button.querySelector('.icon-closed');
if (input.type === 'password') {
input.type = 'text';
iconOpen.classList.add('hidden');
iconClosed.classList.remove('hidden');
} else {
input.type = 'password';
iconOpen.classList.remove('hidden');
iconClosed.classList.add('hidden');
}
}
});
}
function initAllComponents(root = document) {
const buttons = root.querySelectorAll('[data-toggle-password]:not([data-password-initialized])');
buttons.forEach(button => {
initPasswordToggle(button);
});
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})(); // IIFE End
</script>
}
}

View file

@ -0,0 +1,376 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component input - version: main installed by templui v0.71.0
package input
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Type string
const (
TypeText Type = "text"
TypePassword Type = "password"
TypeEmail Type = "email"
TypeNumber Type = "number"
TypeTel Type = "tel"
TypeURL Type = "url"
TypeSearch Type = "search"
TypeDate Type = "date"
TypeTime Type = "time"
TypeFile Type = "file"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Name string
Type Type
Placeholder string
Value string
Disabled bool
Readonly bool
Required bool
FileAccept string
HasError bool
NoTogglePassword bool
}
func Input(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
if p.Type == "" {
p.Type = TypeText
}
if p.ID == "" {
p.ID = utils.RandomID()
}
if p.Type == TypePassword && !p.NoTogglePassword {
templ_7745c5c3_Err = Script().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"relative w-full\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"peer flex h-10 w-full px-3 py-2",
"rounded-md border border-input bg-background text-sm ring-offset-background",
"file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground",
"placeholder:text-muted-foreground",
"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"disabled:cursor-not-allowed disabled:opacity-50",
utils.If(p.HasError, "border-destructive ring-destructive"),
utils.If(p.Type == TypePassword && !p.NoTogglePassword, "pr-8"),
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<input id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/input/input.templ`, Line: 57, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\" type=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(string(p.Type))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/input/input.templ`, Line: 58, Col: 24}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Name != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, " name=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(p.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/input/input.templ`, Line: 60, Col: 17}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Placeholder != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, " placeholder=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(p.Placeholder)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/input/input.templ`, Line: 63, Col: 31}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Value != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(p.Value)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/input/input.templ`, Line: 66, Col: 19}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Type == TypeFile && p.FileAccept != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " accept=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(p.FileAccept)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/input/input.templ`, Line: 69, Col: 25}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Disabled {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, " disabled")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Readonly {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, " readonly")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Required {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, " required")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/input/input.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Type == TypePassword && !p.NoTogglePassword {
templ_7745c5c3_Var10 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "<span class=\"icon-open block\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = icon.Eye(icon.Props{
Size: 18,
}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</span> <span class=\"icon-closed hidden\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = icon.EyeOff(icon.Props{
Size: 18,
}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = button.Button(button.Props{
Size: button.SizeIcon,
Variant: button.VariantGhost,
Class: "absolute right-0 top-1/2 -translate-y-1/2 opacity-50 cursor-pointer",
Attributes: templ.Attributes{"data-toggle-password": p.ID},
}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var10), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var handle = templ.NewOnceHandle()
func Script() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var11 := templ.GetChildren(ctx)
if templ_7745c5c3_Var11 == nil {
templ_7745c5c3_Var11 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var12 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<script nonce=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(templ.GetNonce(ctx))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/input/input.templ`, Line: 115, Col: 37}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "\">\n\t\t(function() { // IIFE Start\n function initPasswordToggle(button) {\n if (button.hasAttribute('data-password-initialized')) {\n return;\n }\n \n button.setAttribute('data-password-initialized', 'true');\n \n button.addEventListener('click', function(event) {\n const inputId = button.getAttribute('data-toggle-password');\n const input = document.getElementById(inputId);\n if (input) {\n const iconOpen = button.querySelector('.icon-open');\n const iconClosed = button.querySelector('.icon-closed');\n\n if (input.type === 'password') {\n input.type = 'text';\n iconOpen.classList.add('hidden');\n iconClosed.classList.remove('hidden');\n } else {\n input.type = 'password';\n iconOpen.classList.remove('hidden');\n iconClosed.classList.add('hidden');\n }\n }\n });\n }\n\n function initAllComponents(root = document) {\n const buttons = root.querySelectorAll('[data-toggle-password]:not([data-password-initialized])');\n buttons.forEach(button => {\n initPasswordToggle(button);\n });\n }\n\n const handleHtmxSwap = (event) => {\n const target = event.detail.target || event.detail.elt;\n if (target instanceof Element) {\n requestAnimationFrame(() => initAllComponents(target));\n }\n };\n\n\t\t\tinitAllComponents();\n document.addEventListener('DOMContentLoaded', () => initAllComponents());\n document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);\n document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);\n })(); // IIFE End\n </script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = handle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var12), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,388 @@
// templui component inputotp - version: main installed by templui v0.71.0
package inputotp
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
"strconv"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Value string
Required bool
Name string
HasError bool
}
type GroupProps struct {
ID string
Class string
Attributes templ.Attributes
}
type SlotProps struct {
ID string
Class string
Attributes templ.Attributes
Index int
Type string
Placeholder string
Disabled bool
}
type SeparatorProps struct {
ID string
Class string
Attributes templ.Attributes
}
templ InputOTP(props ...Props) {
@Script()
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID + "-container" }
}
if p.Value != "" {
data-value={ p.Value }
}
class={
utils.TwMerge(
"flex flex-row items-center gap-2 w-fit",
p.Class,
),
}
data-input-otp
{ p.Attributes... }
>
<input
type="hidden"
if p.ID != "" {
id={ p.ID }
}
if p.Name != "" {
name={ p.Name }
}
data-input-otp-value-target
required?={ p.Required }
/>
{ children... }
</div>
}
templ Group(props ...GroupProps) {
{{ var p GroupProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex gap-2",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</div>
}
templ Slot(props ...SlotProps) {
{{ var p SlotProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.Type == "" {
{{ p.Type = "text" }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class="relative"
{ p.Attributes... }
>
<input
type={ p.Type }
inputmode="numeric"
if p.Placeholder != "" {
placeholder={ p.Placeholder }
}
maxlength="1"
class={
utils.TwMerge(
"w-10 h-12 text-center",
"rounded-md border border-input bg-background text-sm",
"file:border-0 file:bg-transparent file:text-sm file:font-medium",
"placeholder:text-muted-foreground",
"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"disabled:cursor-not-allowed disabled:opacity-50",
p.Class,
),
}
disabled?={ p.Disabled }
data-input-index={ strconv.Itoa(p.Index) }
data-input-otp-slot
{ p.Attributes... }
/>
</div>
}
templ Separator(props ...SeparatorProps) {
{{ var p SeparatorProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"flex items-center text-muted-foreground text-xl",
p.Class,
),
}
{ p.Attributes... }
>
<span>-</span>
</div>
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<script nonce={ templ.GetNonce(ctx) }>
if (typeof window.inputOTPState === 'undefined') {
window.inputOTPState = new WeakMap();
}
(function() { // IIFE Start
// Prevent re-running the whole setup if already done
if (window.inputOTPSystemInitialized) return;
// --- Core Component Logic ---
function initInputOTP(container) {
// Prevent re-initialization if state already exists for this container
if (window.inputOTPState.has(container)) return;
// Basic elements
const hiddenInput = container.querySelector('[data-input-otp-value-target]');
const slots = Array.from(container.querySelectorAll('[data-input-otp-slot]'))
.sort((a, b) => parseInt(a.dataset.inputIndex) - parseInt(b.dataset.inputIndex));
if (!hiddenInput || slots.length === 0) return;
// Check for autofocus attribute and focus the first slot
if (container.hasAttribute('autofocus')) {
// Use requestAnimationFrame to ensure DOM is ready
requestAnimationFrame(() => {
const firstSlot = slots[0];
if (firstSlot) {
firstSlot.focus();
firstSlot.select();
}
});
}
// Core functionality helpers bound to this instance
const updateHiddenValue = () => {
hiddenInput.value = slots.map(slot => slot.value).join('');
};
const findFirstEmptySlotIndex = () => slots.findIndex(slot => !slot.value);
const focusSlot = (index) => {
if (index >= 0 && index < slots.length) {
slots[index].focus();
// Use setTimeout to ensure select happens after focus
setTimeout(() => slots[index].select(), 0);
}
};
// Event Handlers specific to this instance
const handleInput = (e) => {
const input = e.target;
const index = parseInt(input.dataset.inputIndex);
if (input.value === ' ') { input.value = ''; return; }
if (input.value.length > 1) input.value = input.value.slice(-1);
if (input.value && index < slots.length - 1) focusSlot(index + 1);
updateHiddenValue();
};
const handleKeydown = (e) => {
const input = e.target;
const index = parseInt(input.dataset.inputIndex);
if (e.key === 'Backspace') {
const currentValue = input.value;
if (index > 0) {
e.preventDefault();
if (currentValue) {
input.value = ''; updateHiddenValue(); focusSlot(index - 1);
} else {
slots[index - 1].value = ''; updateHiddenValue(); focusSlot(index - 1);
}
}
} else if (e.key === 'ArrowLeft' && index > 0) {
e.preventDefault(); focusSlot(index - 1);
} else if (e.key === 'ArrowRight' && index < slots.length - 1) {
e.preventDefault(); focusSlot(index + 1);
}
};
const handleFocus = (e) => {
const input = e.target;
const index = parseInt(input.dataset.inputIndex);
const firstEmptyIndex = findFirstEmptySlotIndex();
if (firstEmptyIndex !== -1 && index !== firstEmptyIndex) {
focusSlot(firstEmptyIndex);
return; // Prevent default focus/select on original target
}
// Use setTimeout to ensure select() happens after potential focus redirection
setTimeout(() => input.select(), 0);
};
const handlePaste = (e) => {
e.preventDefault();
const pastedData = (e.clipboardData || window.clipboardData).getData('text');
const pastedChars = pastedData.replace(/\s/g, '').split('');
let currentSlotIndex = 0; // Start pasting from the first slot
// Try to find focused slot to start paste from, fallback to 0
const focusedSlot = slots.find(slot => slot === document.activeElement);
if (focusedSlot) currentSlotIndex = parseInt(focusedSlot.dataset.inputIndex);
for (let i = 0; i < pastedChars.length && currentSlotIndex < slots.length; i++) {
slots[currentSlotIndex].value = pastedChars[i];
currentSlotIndex++;
}
updateHiddenValue();
// Focus after paste: either next available slot or last filled slot
let focusIndex = findFirstEmptySlotIndex();
if (focusIndex === -1) focusIndex = slots.length - 1;
else if (focusIndex > 0 && focusIndex > currentSlotIndex) focusIndex = currentSlotIndex; // Focus next slot after pasted content
focusSlot(Math.min(focusIndex, slots.length - 1));
};
// Add event listeners to slots
for (const slot of slots) {
slot.addEventListener('input', handleInput);
slot.addEventListener('keydown', handleKeydown);
slot.addEventListener('focus', handleFocus);
}
// Add paste listener to the container
container.addEventListener('paste', handlePaste);
// Handle label clicks to focus first slot
const targetId = hiddenInput.id;
if (targetId) {
for (const label of document.querySelectorAll(`label[for="${targetId}"]`)) {
// Check if listener already attached to avoid duplicates
if (!label.dataset.inputOtpListener) {
const labelClickListener = (e) => {
e.preventDefault();
if (slots.length > 0) focusSlot(0);
};
label.addEventListener('click', labelClickListener);
label.dataset.inputOtpListener = 'true'; // Mark as having listener
// Store handler for potential cleanup
label._inputOtpClickListener = labelClickListener;
}
}
}
// Initial value handling
if (container.dataset.value) {
const initialValue = container.dataset.value;
for (let i = 0; i < slots.length && i < initialValue.length; i++) {
slots[i].value = initialValue[i];
}
updateHiddenValue();
}
// Store state and handlers for potential cleanup
const state = { slots, hiddenInput, handleInput, handleKeydown, handleFocus, handlePaste };
window.inputOTPState.set(container, state);
}
// --- Cleanup ---
function cleanupInputOTP(container) {
const state = window.inputOTPState.get(container);
if (!state) return;
// Remove slot listeners
for (const slot of state.slots) {
slot.removeEventListener('input', state.handleInput);
slot.removeEventListener('keydown', state.handleKeydown);
slot.removeEventListener('focus', state.handleFocus);
}
// Remove container paste listener
container.removeEventListener('paste', state.handlePaste);
// Remove label listeners
const targetId = state.hiddenInput.id;
if (targetId) {
for (const label of document.querySelectorAll(`label[for="${targetId}"]`)) {
if (label._inputOtpClickListener) {
label.removeEventListener('click', label._inputOtpClickListener);
delete label._inputOtpClickListener;
delete label.dataset.inputOtpListener;
}
}
}
window.inputOTPState.delete(container);
}
function initAllComponents(root = document) {
if (root instanceof Element && root.matches('[data-input-otp]')) {
initInputOTP(root);
}
const containers = root.querySelectorAll('[data-input-otp]');
containers.forEach(initInputOTP);
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:beforeSwap', (event) => {
const target = event.detail.target || event.detail.elt;;
if (target instanceof Element) {
// Cleanup target itself if it's an OTP container
if (target.matches && target.matches('[data-input-otp]')) {
cleanupInputOTP(target);
}
// Cleanup descendants
if (target.querySelectorAll) {
for (const container of target.querySelectorAll('[data-input-otp]')) {
cleanupInputOTP(container);
}
}
}
});
initAllComponents();
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
window.inputOTPSystemInitialized = true;
})(); // End of IIFE
</script>
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,111 @@
// templui component label - version: main installed by templui v0.71.0
package label
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Props struct {
ID string
Class string
Attributes templ.Attributes
For string
Error string
}
templ Label(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<label
if p.ID != "" {
id={ p.ID }
}
if p.For != "" {
for={ p.For }
}
class={
utils.TwMerge(
"text-sm font-medium leading-none inline-block",
utils.If(len(p.Error) > 0, "text-destructive"),
p.Class,
),
}
data-disabled-style="opacity-50 cursor-not-allowed"
{ p.Attributes... }
>
{ children... }
</label>
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<script nonce={ templ.GetNonce(ctx) }>
(function() { // IIFE
function initLabel(label) {
if (!label.hasAttribute('for') || !label.hasAttribute('data-disabled-style')) {
return;
}
const forId = label.getAttribute('for');
const targetElement = forId ? document.getElementById(forId) : null;
const disabledStyle = label.getAttribute('data-disabled-style');
if (!disabledStyle) return;
const classes = disabledStyle.split(' ').filter(Boolean);
function updateStyle() {
if (targetElement && targetElement.disabled) {
label.classList.add(...classes);
} else {
label.classList.remove(...classes);
}
}
// Set up mutation observer to detect disabled state changes
if (targetElement) {
const observer = new MutationObserver(mutations => {
for (const mutation of mutations) {
if (mutation.type === 'attributes' && mutation.attributeName === 'disabled') {
updateStyle();
}
}
});
observer.observe(targetElement, {
attributes: true,
attributeFilter: ['disabled']
});
}
// Initial style update
updateStyle();
}
function initAllComponents(root = document) {
if (root instanceof Element && root.matches('label[for][data-disabled-style]')) {
initLabel(root);
}
for (const label of root.querySelectorAll('label[for][data-disabled-style]')) {
initLabel(label);
}
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})(); // End of IIFE
</script>
}
}

View file

@ -0,0 +1,200 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component label - version: main installed by templui v0.71.0
package label
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Props struct {
ID string
Class string
Attributes templ.Attributes
For string
Error string
}
func Label(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"text-sm font-medium leading-none inline-block",
utils.If(len(p.Error) > 0, "text-destructive"),
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<label")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/label/label.templ`, Line: 21, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.For != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " for=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(p.For)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/label/label.templ`, Line: 24, Col: 14}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/label/label.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\" data-disabled-style=\"opacity-50 cursor-not-allowed\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</label>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var handle = templ.NewOnceHandle()
func Script() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var6 := templ.GetChildren(ctx)
if templ_7745c5c3_Var6 == nil {
templ_7745c5c3_Var6 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var7 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<script nonce=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(templ.GetNonce(ctx))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/label/label.templ`, Line: 44, Col: 37}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\">\n\n\t\t\t(function() { // IIFE\n\t\t\t\tfunction initLabel(label) {\n\t\t\t\t\tif (!label.hasAttribute('for') || !label.hasAttribute('data-disabled-style')) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tconst forId = label.getAttribute('for');\n\t\t\t\t\tconst targetElement = forId ? document.getElementById(forId) : null;\n\t\t\t\t\tconst disabledStyle = label.getAttribute('data-disabled-style');\n\t\t\t\t\t\n\t\t\t\t\tif (!disabledStyle) return;\n\t\t\t\t\t\n\t\t\t\t\tconst classes = disabledStyle.split(' ').filter(Boolean);\n\t\t\t\t\t\n\t\t\t\t\tfunction updateStyle() {\n\t\t\t\t\t\tif (targetElement && targetElement.disabled) {\n\t\t\t\t\t\t\tlabel.classList.add(...classes);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlabel.classList.remove(...classes);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// Set up mutation observer to detect disabled state changes\n\t\t\t\t\tif (targetElement) {\n\t\t\t\t\t\tconst observer = new MutationObserver(mutations => {\n\t\t\t\t\t\t\tfor (const mutation of mutations) {\n\t\t\t\t\t\t\t\tif (mutation.type === 'attributes' && mutation.attributeName === 'disabled') {\n\t\t\t\t\t\t\t\t\tupdateStyle();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\t\n\t\t\t\t\t\tobserver.observe(targetElement, { \n\t\t\t\t\t\t\tattributes: true, \n\t\t\t\t\t\t\tattributeFilter: ['disabled'] \n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// Initial style update\n\t\t\t\t\tupdateStyle();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tfunction initAllComponents(root = document) {\n\t\t\t\t\tif (root instanceof Element && root.matches('label[for][data-disabled-style]')) {\n\t\t\t\t\t\tinitLabel(root);\n\t\t\t\t\t}\n\t\t\t\t\tfor (const label of root.querySelectorAll('label[for][data-disabled-style]')) {\n\t\t\t\t\t\tinitLabel(label);\n\t\t\t\t\t}\t\n\t\t\t\t}\n\n\t\t\t\tconst handleHtmxSwap = (event) => {\n\t\t\t\t\tconst target = event.detail.target || event.detail.elt;\n\t\t\t\t\tif (target instanceof Element) {\n\t\t\t\t\t\trequestAnimationFrame(() => initAllComponents(target));\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\tinitAllComponents();\n\t\t\t\tdocument.addEventListener('DOMContentLoaded', () => initAllComponents());\n\t\t\t\tdocument.body.addEventListener('htmx:afterSwap', handleHtmxSwap);\n\t\t\t\tdocument.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);\n\t\t\t})(); // End of IIFE\n\t\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = handle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var7), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,362 @@
// templui component modal - version: main installed by templui v0.71.0
package modal
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
"strconv"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
DisableClickAway bool
DisableESC bool
}
type TriggerProps struct {
ID string
Class string
Attributes templ.Attributes
Disabled bool
ModalID string // ID of the modal to trigger
}
type CloseProps struct {
ID string
Class string
Attributes templ.Attributes
ModalID string // ID of the modal to close (optional, defaults to closest modal)
}
type HeaderProps struct {
ID string
Class string
Attributes templ.Attributes
}
type BodyProps struct {
ID string
Class string
Attributes templ.Attributes
}
type FooterProps struct {
ID string
Class string
Attributes templ.Attributes
}
templ Modal(props ...Props) {
@Script()
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.ID == "" {
{{ p.ID = "modal-" + utils.RandomID() }}
}
<div
id={ p.ID }
data-modal
data-disable-click-away={ strconv.FormatBool(p.DisableClickAway) }
data-disable-esc={ strconv.FormatBool(p.DisableESC) }
class="modal-container fixed inset-0 z-50 flex items-center justify-center overflow-y-auto opacity-0 transition-opacity duration-300 ease-out hidden"
aria-labelledby={ p.ID + "-title" }
role="dialog"
aria-modal="true"
{ p.Attributes... }
>
<div data-modal-backdrop class="fixed inset-0 bg-background/70 bg-opacity-50" aria-hidden="true"></div>
<div
id={ p.ID + "-content" }
data-modal-content
class={
utils.TwMerge(
"modal-content relative bg-background rounded-lg border text-left overflow-hidden shadow-xl transform transition-all sm:my-8 w-full scale-95 opacity-0", // Base classes + transition start
"duration-300 ease-out", // Enter duration
p.Class,
),
}
>
{ children... }
</div>
</div>
}
templ Trigger(props ...TriggerProps) {
{{ var p TriggerProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
data-modal-trigger
if p.ModalID != "" {
data-modal-target-id={ p.ModalID }
}
class={
utils.TwMerge(
utils.IfElse(p.Disabled, "cursor-not-allowed opacity-50", "cursor-pointer"),
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</span>
}
templ Close(props ...CloseProps) {
{{ var p CloseProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
data-modal-close
if p.ModalID != "" {
data-modal-target-id={ p.ModalID }
}
class={ utils.TwMerge("cursor-pointer", p.Class) }
{ p.Attributes... }
>
{ children... }
</span>
}
templ Header(props ...HeaderProps) {
{{ var p HeaderProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("px-4 pt-5 pb-4 sm:p-6 sm:pb-4 text-lg leading-6 font-medium text-foreground", p.Class) }
{ p.Attributes... }
>
<h3 class="text-lg leading-6 font-medium text-foreground" id={ p.ID + "-title" }>
// Ensure title ID matches aria-labelledby
{ children... }
</h3>
</div>
}
templ Body(props ...BodyProps) {
{{ var p BodyProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("px-4 pt-5 pb-4 sm:p-6 sm:pb-4", p.Class) }
{ p.Attributes... }
>
{ children... }
</div>
}
templ Footer(props ...FooterProps) {
{{ var p FooterProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse", p.Class) }
{ p.Attributes... }
>
{ children... }
</div>
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<script nonce={ templ.GetNonce(ctx) }>
if (typeof window.modalState === 'undefined') {
window.modalState = {
openModalId: null
};
}
(function() { // IIFE
function closeModal(modal, immediate = false) {
if (!modal || modal.style.display === 'none') return;
const content = modal.querySelector('[data-modal-content]');
const modalId = modal.id;
// Apply leaving transitions
modal.classList.remove('opacity-100');
modal.classList.add('opacity-0');
if (content) {
content.classList.remove('scale-100', 'opacity-100');
content.classList.add('scale-95', 'opacity-0');
}
function hideModal() {
modal.style.display = 'none';
if (window.modalState.openModalId === modalId) {
window.modalState.openModalId = null;
document.body.style.overflow = '';
}
}
if (immediate) {
hideModal();
} else {
setTimeout(hideModal, 300);
}
}
function openModal(modal) {
if (!modal) return;
// Close any open modal first
if (window.modalState.openModalId) {
const openModal = document.getElementById(window.modalState.openModalId);
if (openModal && openModal !== modal) {
closeModal(openModal, true);
}
}
const content = modal.querySelector('[data-modal-content]');
// Display and prepare for animation
modal.style.display = 'flex';
// Store as currently open modal
window.modalState.openModalId = modal.id;
document.body.style.overflow = 'hidden';
// Force reflow before adding transition classes
void modal.offsetHeight;
// Start animations
modal.classList.remove('opacity-0');
modal.classList.add('opacity-100');
if (content) {
content.classList.remove('scale-95', 'opacity-0');
content.classList.add('scale-100', 'opacity-100');
// Focus first focusable element
setTimeout(() => {
const focusable = content.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
if (focusable) focusable.focus();
}, 50);
}
}
function closeModalById(modalId, immediate = false) {
const modal = document.getElementById(modalId);
if (modal) closeModal(modal, immediate);
}
function openModalById(modalId) {
const modal = document.getElementById(modalId);
if (modal) openModal(modal);
}
function handleClickAway(e) {
const openModalId = window.modalState.openModalId;
if (!openModalId) return;
const modal = document.getElementById(openModalId);
if (!modal || modal.getAttribute('data-disable-click-away') === 'true') return;
const content = modal.querySelector('[data-modal-content]');
const trigger = e.target.closest('[data-modal-trigger]');
if (content && !content.contains(e.target) &&
(!trigger || trigger.getAttribute('data-modal-target-id') !== openModalId)) {
closeModal(modal);
}
}
function handleEscKey(e) {
if (e.key !== 'Escape' || !window.modalState.openModalId) return;
const modal = document.getElementById(window.modalState.openModalId);
if (modal && modal.getAttribute('data-disable-esc') !== 'true') {
closeModal(modal);
}
}
function initTrigger(trigger) {
const targetId = trigger.getAttribute('data-modal-target-id');
if (!targetId) return;
trigger.addEventListener('click', () => {
if (!trigger.hasAttribute('disabled') &&
!trigger.classList.contains('opacity-50')) {
openModalById(targetId);
}
});
}
function initCloseButton(closeBtn) {
closeBtn.addEventListener('click', () => {
const targetId = closeBtn.getAttribute('data-modal-target-id');
if (targetId) {
closeModalById(targetId);
} else {
const modal = closeBtn.closest('[data-modal]');
if (modal && modal.id) {
closeModal(modal);
}
}
});
}
function initAllComponents(root = document) {
if (root instanceof Element && root.matches('[data-modal-trigger]')) {
initTrigger(root);
}
for (const trigger of root.querySelectorAll('[data-modal-trigger]')) {
initTrigger(trigger);
}
if (root instanceof Element && root.matches('[data-modal-close]')) {
initCloseButton(root);
}
for (const closeBtn of root.querySelectorAll('[data-modal-close]')) {
initCloseButton(closeBtn);
}
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
if (typeof window.modalEventsInitialized === 'undefined') {
document.addEventListener('click', handleClickAway);
document.addEventListener('keydown', handleEscKey);
window.modalEventsInitialized = true;
}
initAllComponents();
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})(); // End of IIFE
</script>
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,277 @@
// templui component pagination - version: main installed by templui v0.71.0
package pagination
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
type ContentProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ItemProps struct {
ID string
Class string
Attributes templ.Attributes
}
type LinkProps struct {
ID string
Class string
Attributes templ.Attributes
Href string
IsActive bool
Disabled bool
HxGet string
HxTarget string
HxSwap string
}
type PreviousProps struct {
ID string
Class string
Attributes templ.Attributes
Href string
Disabled bool
Label string
HxGet string
HxTarget string
HxSwap string
}
type NextProps struct {
ID string
Class string
Attributes templ.Attributes
Href string
Disabled bool
Label string
HxGet string
HxTarget string
HxSwap string
}
templ Pagination(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<nav
if p.ID != "" {
id={ p.ID }
}
role="navigation"
aria-label="pagination"
class={ utils.TwMerge("flex flex-wrap justify-center", p.Class) }
{ p.Attributes... }
>
{ children... }
</nav>
}
templ Content(props ...ContentProps) {
{{ var p ContentProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<ul
if p.ID != "" {
id={ p.ID }
}
class="flex flex-row items-center gap-1"
{ p.Attributes... }
>
{ children... }
</ul>
}
templ Item(props ...ItemProps) {
{{ var p ItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<li
if p.ID != "" {
id={ p.ID }
}
{ p.Attributes... }
>
{ children... }
</li>
}
templ Link(props ...LinkProps) {
{{ var p LinkProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.Disabled {
@button.Button(button.Props{
ID: p.ID,
Disabled: true,
Size: button.SizeIcon,
Variant: button.VariantGhost,
Class: p.Class,
Attributes: p.Attributes,
}) {
{ children... }
}
} else if p.HxGet != "" {
@button.Button(button.Props{
ID: p.ID,
HxGet: p.HxGet,
HxTarget: p.HxTarget,
HxSwap: p.HxSwap,
Size: button.SizeIcon,
Variant: button.Variant(buttonVariant(p.IsActive)),
Class: p.Class,
Attributes: p.Attributes,
}) {
{ children... }
}
} else {
@button.Button(button.Props{
ID: p.ID,
Href: p.Href,
Size: button.SizeIcon,
Variant: button.Variant(buttonVariant(p.IsActive)),
Class: p.Class,
Attributes: p.Attributes,
}) {
{ children... }
}
}
}
templ Previous(props ...PreviousProps) {
{{ var p PreviousProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
@button.Button(button.Props{
ID: p.ID,
Href: p.Href,
HxGet: p.HxGet,
HxTarget: p.HxTarget,
HxSwap: p.HxSwap,
Disabled: p.Disabled,
Variant: button.VariantGhost,
Class: utils.TwMerge("gap-1", p.Class),
Attributes: p.Attributes,
}) {
@icon.ChevronLeft(icon.Props{Size: 16})
if p.Label != "" {
<span>{ p.Label }</span>
}
}
}
templ Next(props ...NextProps) {
{{ var p NextProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
@button.Button(button.Props{
ID: p.ID,
Href: p.Href,
HxGet: p.HxGet,
HxTarget: p.HxTarget,
HxSwap: p.HxSwap,
Disabled: p.Disabled,
Variant: button.VariantGhost,
Class: utils.TwMerge("gap-1", p.Class),
Attributes: p.Attributes,
}) {
if p.Label != "" {
<span>{ p.Label }</span>
}
@icon.ChevronRight(icon.Props{Size: 16})
}
}
templ Ellipsis() {
@icon.Ellipsis(icon.Props{Size: 16})
}
func CreatePagination(currentPage, totalPages, maxVisible int) struct {
CurrentPage int
TotalPages int
Pages []int
HasPrevious bool
HasNext bool
} {
if currentPage < 1 {
currentPage = 1
}
if totalPages < 1 {
totalPages = 1
}
if currentPage > totalPages {
currentPage = totalPages
}
if maxVisible < 1 {
maxVisible = 5
}
start, end := calculateVisibleRange(currentPage, totalPages, maxVisible)
pages := make([]int, 0, end-start+1)
for i := start; i <= end; i++ {
pages = append(pages, i)
}
return struct {
CurrentPage int
TotalPages int
Pages []int
HasPrevious bool
HasNext bool
}{
CurrentPage: currentPage,
TotalPages: totalPages,
Pages: pages,
HasPrevious: currentPage > 1,
HasNext: currentPage < totalPages,
}
}
func calculateVisibleRange(currentPage, totalPages, maxVisible int) (int, int) {
if totalPages <= maxVisible {
return 1, totalPages
}
half := maxVisible / 2
start := currentPage - half
end := currentPage + half
if start < 1 {
end += (1 - start)
start = 1
}
if end > totalPages {
start -= (end - totalPages)
if start < 1 {
start = 1
}
end = totalPages
}
return start, end
}
func buttonVariant(isActive bool) button.Variant {
if isActive {
return button.VariantOutline
}
return button.VariantGhost
}

View file

@ -0,0 +1,695 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component pagination - version: main installed by templui v0.71.0
package pagination
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
type ContentProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ItemProps struct {
ID string
Class string
Attributes templ.Attributes
}
type LinkProps struct {
ID string
Class string
Attributes templ.Attributes
Href string
IsActive bool
Disabled bool
HxGet string
HxTarget string
HxSwap string
}
type PreviousProps struct {
ID string
Class string
Attributes templ.Attributes
Href string
Disabled bool
Label string
HxGet string
HxTarget string
HxSwap string
}
type NextProps struct {
ID string
Class string
Attributes templ.Attributes
Href string
Disabled bool
Label string
HxGet string
HxTarget string
HxSwap string
}
func Pagination(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{utils.TwMerge("flex flex-wrap justify-center", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<nav")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/pagination/pagination.templ`, Line: 71, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " role=\"navigation\" aria-label=\"pagination\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/pagination/pagination.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</nav>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Content(props ...ContentProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p ContentProps
if len(props) > 0 {
p = props[0]
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<ul")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/pagination/pagination.templ`, Line: 89, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " class=\"flex flex-row items-center gap-1\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var5.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</ul>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Item(props ...ItemProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var7 := templ.GetChildren(ctx)
if templ_7745c5c3_Var7 == nil {
templ_7745c5c3_Var7 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p ItemProps
if len(props) > 0 {
p = props[0]
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<li")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/pagination/pagination.templ`, Line: 105, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var7.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</li>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Link(props ...LinkProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
if templ_7745c5c3_Var9 == nil {
templ_7745c5c3_Var9 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p LinkProps
if len(props) > 0 {
p = props[0]
}
if p.Disabled {
templ_7745c5c3_Var10 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templ_7745c5c3_Var9.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = button.Button(button.Props{
ID: p.ID,
Disabled: true,
Size: button.SizeIcon,
Variant: button.VariantGhost,
Class: p.Class,
Attributes: p.Attributes,
}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var10), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else if p.HxGet != "" {
templ_7745c5c3_Var11 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templ_7745c5c3_Var9.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = button.Button(button.Props{
ID: p.ID,
HxGet: p.HxGet,
HxTarget: p.HxTarget,
HxSwap: p.HxSwap,
Size: button.SizeIcon,
Variant: button.Variant(buttonVariant(p.IsActive)),
Class: p.Class,
Attributes: p.Attributes,
}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var11), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
templ_7745c5c3_Var12 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templ_7745c5c3_Var9.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = button.Button(button.Props{
ID: p.ID,
Href: p.Href,
Size: button.SizeIcon,
Variant: button.Variant(buttonVariant(p.IsActive)),
Class: p.Class,
Attributes: p.Attributes,
}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var12), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
return nil
})
}
func Previous(props ...PreviousProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var13 := templ.GetChildren(ctx)
if templ_7745c5c3_Var13 == nil {
templ_7745c5c3_Var13 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p PreviousProps
if len(props) > 0 {
p = props[0]
}
templ_7745c5c3_Var14 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = icon.ChevronLeft(icon.Props{Size: 16}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Label != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "<span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(p.Label)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/pagination/pagination.templ`, Line: 174, Col: 18}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
return nil
})
templ_7745c5c3_Err = button.Button(button.Props{
ID: p.ID,
Href: p.Href,
HxGet: p.HxGet,
HxTarget: p.HxTarget,
HxSwap: p.HxSwap,
Disabled: p.Disabled,
Variant: button.VariantGhost,
Class: utils.TwMerge("gap-1", p.Class),
Attributes: p.Attributes,
}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var14), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Next(props ...NextProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var16 := templ.GetChildren(ctx)
if templ_7745c5c3_Var16 == nil {
templ_7745c5c3_Var16 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p NextProps
if len(props) > 0 {
p = props[0]
}
templ_7745c5c3_Var17 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
if p.Label != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "<span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(p.Label)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/pagination/pagination.templ`, Line: 196, Col: 18}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = icon.ChevronRight(icon.Props{Size: 16}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = button.Button(button.Props{
ID: p.ID,
Href: p.Href,
HxGet: p.HxGet,
HxTarget: p.HxTarget,
HxSwap: p.HxSwap,
Disabled: p.Disabled,
Variant: button.VariantGhost,
Class: utils.TwMerge("gap-1", p.Class),
Attributes: p.Attributes,
}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var17), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Ellipsis() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var19 := templ.GetChildren(ctx)
if templ_7745c5c3_Var19 == nil {
templ_7745c5c3_Var19 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = icon.Ellipsis(icon.Props{Size: 16}).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func CreatePagination(currentPage, totalPages, maxVisible int) struct {
CurrentPage int
TotalPages int
Pages []int
HasPrevious bool
HasNext bool
} {
if currentPage < 1 {
currentPage = 1
}
if totalPages < 1 {
totalPages = 1
}
if currentPage > totalPages {
currentPage = totalPages
}
if maxVisible < 1 {
maxVisible = 5
}
start, end := calculateVisibleRange(currentPage, totalPages, maxVisible)
pages := make([]int, 0, end-start+1)
for i := start; i <= end; i++ {
pages = append(pages, i)
}
return struct {
CurrentPage int
TotalPages int
Pages []int
HasPrevious bool
HasNext bool
}{
CurrentPage: currentPage,
TotalPages: totalPages,
Pages: pages,
HasPrevious: currentPage > 1,
HasNext: currentPage < totalPages,
}
}
func calculateVisibleRange(currentPage, totalPages, maxVisible int) (int, int) {
if totalPages <= maxVisible {
return 1, totalPages
}
half := maxVisible / 2
start := currentPage - half
end := currentPage + half
if start < 1 {
end += (1 - start)
start = 1
}
if end > totalPages {
start -= (end - totalPages)
if start < 1 {
start = 1
}
end = totalPages
}
return start, end
}
func buttonVariant(isActive bool) button.Variant {
if isActive {
return button.VariantOutline
}
return button.VariantGhost
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,865 @@
// templui component popover - version: main installed by templui v0.71.0
package popover
// https://cdn.jsdelivr.net/npm/@floating-ui/core@1.7.0
templ FloatingUICore() {
<script nonce={ templ.GetNonce(ctx) }>
!(function (t, e) {
"object" == typeof exports && "undefined" != typeof module
? e(exports)
: "function" == typeof define && define.amd
? define(["exports"], e)
: e(
((t =
"undefined" != typeof globalThis
? globalThis
: t || self).FloatingUICore = {})
);
})(this, function (t) {
"use strict";
const e = ["top", "right", "bottom", "left"],
n = ["start", "end"],
i = e.reduce((t, e) => t.concat(e, e + "-" + n[0], e + "-" + n[1]), []),
o = Math.min,
r = Math.max,
a = { left: "right", right: "left", bottom: "top", top: "bottom" },
l = { start: "end", end: "start" };
function s(t, e, n) {
return r(t, o(e, n));
}
function f(t, e) {
return "function" == typeof t ? t(e) : t;
}
function c(t) {
return t.split("-")[0];
}
function u(t) {
return t.split("-")[1];
}
function m(t) {
return "x" === t ? "y" : "x";
}
function d(t) {
return "y" === t ? "height" : "width";
}
function g(t) {
return ["top", "bottom"].includes(c(t)) ? "y" : "x";
}
function p(t) {
return m(g(t));
}
function h(t, e, n) {
void 0 === n && (n = !1);
const i = u(t),
o = p(t),
r = d(o);
let a =
"x" === o
? i === (n ? "end" : "start")
? "right"
: "left"
: "start" === i
? "bottom"
: "top";
return e.reference[r] > e.floating[r] && (a = w(a)), [a, w(a)];
}
function y(t) {
return t.replace(/start|end/g, (t) => l[t]);
}
function w(t) {
return t.replace(/left|right|bottom|top/g, (t) => a[t]);
}
function x(t) {
return "number" != typeof t
? (function (t) {
return { top: 0, right: 0, bottom: 0, left: 0, ...t };
})(t)
: { top: t, right: t, bottom: t, left: t };
}
function v(t) {
const { x: e, y: n, width: i, height: o } = t;
return {
width: i,
height: o,
top: n,
left: e,
right: e + i,
bottom: n + o,
x: e,
y: n,
};
}
function b(t, e, n) {
let { reference: i, floating: o } = t;
const r = g(e),
a = p(e),
l = d(a),
s = c(e),
f = "y" === r,
m = i.x + i.width / 2 - o.width / 2,
h = i.y + i.height / 2 - o.height / 2,
y = i[l] / 2 - o[l] / 2;
let w;
switch (s) {
case "top":
w = { x: m, y: i.y - o.height };
break;
case "bottom":
w = { x: m, y: i.y + i.height };
break;
case "right":
w = { x: i.x + i.width, y: h };
break;
case "left":
w = { x: i.x - o.width, y: h };
break;
default:
w = { x: i.x, y: i.y };
}
switch (u(e)) {
case "start":
w[a] -= y * (n && f ? -1 : 1);
break;
case "end":
w[a] += y * (n && f ? -1 : 1);
}
return w;
}
async function A(t, e) {
var n;
void 0 === e && (e = {});
const { x: i, y: o, platform: r, rects: a, elements: l, strategy: s } = t,
{
boundary: c = "clippingAncestors",
rootBoundary: u = "viewport",
elementContext: m = "floating",
altBoundary: d = !1,
padding: g = 0,
} = f(e, t),
p = x(g),
h = l[d ? ("floating" === m ? "reference" : "floating") : m],
y = v(
await r.getClippingRect({
element:
null ==
(n = await (null == r.isElement ? void 0 : r.isElement(h))) || n
? h
: h.contextElement ||
(await (null == r.getDocumentElement
? void 0
: r.getDocumentElement(l.floating))),
boundary: c,
rootBoundary: u,
strategy: s,
})
),
w =
"floating" === m
? { x: i, y: o, width: a.floating.width, height: a.floating.height }
: a.reference,
b = await (null == r.getOffsetParent
? void 0
: r.getOffsetParent(l.floating)),
A = ((await (null == r.isElement ? void 0 : r.isElement(b))) &&
(await (null == r.getScale ? void 0 : r.getScale(b)))) || {
x: 1,
y: 1,
},
R = v(
r.convertOffsetParentRelativeRectToViewportRelativeRect
? await r.convertOffsetParentRelativeRectToViewportRelativeRect({
elements: l,
rect: w,
offsetParent: b,
strategy: s,
})
: w
);
return {
top: (y.top - R.top + p.top) / A.y,
bottom: (R.bottom - y.bottom + p.bottom) / A.y,
left: (y.left - R.left + p.left) / A.x,
right: (R.right - y.right + p.right) / A.x,
};
}
function R(t, e) {
return {
top: t.top - e.height,
right: t.right - e.width,
bottom: t.bottom - e.height,
left: t.left - e.width,
};
}
function P(t) {
return e.some((e) => t[e] >= 0);
}
function D(t) {
const e = o(...t.map((t) => t.left)),
n = o(...t.map((t) => t.top));
return {
x: e,
y: n,
width: r(...t.map((t) => t.right)) - e,
height: r(...t.map((t) => t.bottom)) - n,
};
}
(t.arrow = (t) => ({
name: "arrow",
options: t,
async fn(e) {
const {
x: n,
y: i,
placement: r,
rects: a,
platform: l,
elements: c,
middlewareData: m,
} = e,
{ element: g, padding: h = 0 } = f(t, e) || {};
if (null == g) return {};
const y = x(h),
w = { x: n, y: i },
v = p(r),
b = d(v),
A = await l.getDimensions(g),
R = "y" === v,
P = R ? "top" : "left",
D = R ? "bottom" : "right",
T = R ? "clientHeight" : "clientWidth",
O = a.reference[b] + a.reference[v] - w[v] - a.floating[b],
E = w[v] - a.reference[v],
L = await (null == l.getOffsetParent ? void 0 : l.getOffsetParent(g));
let k = L ? L[T] : 0;
(k && (await (null == l.isElement ? void 0 : l.isElement(L)))) ||
(k = c.floating[T] || a.floating[b]);
const C = O / 2 - E / 2,
B = k / 2 - A[b] / 2 - 1,
H = o(y[P], B),
S = o(y[D], B),
F = H,
j = k - A[b] - S,
z = k / 2 - A[b] / 2 + C,
M = s(F, z, j),
V =
!m.arrow &&
null != u(r) &&
z !== M &&
a.reference[b] / 2 - (z < F ? H : S) - A[b] / 2 < 0,
W = V ? (z < F ? z - F : z - j) : 0;
return {
[v]: w[v] + W,
data: {
[v]: M,
centerOffset: z - M - W,
...(V && { alignmentOffset: W }),
},
reset: V,
};
},
})),
(t.autoPlacement = function (t) {
return (
void 0 === t && (t = {}),
{
name: "autoPlacement",
options: t,
async fn(e) {
var n, o, r;
const {
rects: a,
middlewareData: l,
placement: s,
platform: m,
elements: d,
} = e,
{
crossAxis: g = !1,
alignment: p,
allowedPlacements: w = i,
autoAlignment: x = !0,
...v
} = f(t, e),
b =
void 0 !== p || w === i
? (function (t, e, n) {
return (
t
? [
...n.filter((e) => u(e) === t),
...n.filter((e) => u(e) !== t),
]
: n.filter((t) => c(t) === t)
).filter((n) => !t || u(n) === t || (!!e && y(n) !== n));
})(p || null, x, w)
: w,
R = await A(e, v),
P = (null == (n = l.autoPlacement) ? void 0 : n.index) || 0,
D = b[P];
if (null == D) return {};
const T = h(
D,
a,
await (null == m.isRTL ? void 0 : m.isRTL(d.floating))
);
if (s !== D) return { reset: { placement: b[0] } };
const O = [R[c(D)], R[T[0]], R[T[1]]],
E = [
...((null == (o = l.autoPlacement) ? void 0 : o.overflows) ||
[]),
{ placement: D, overflows: O },
],
L = b[P + 1];
if (L)
return {
data: { index: P + 1, overflows: E },
reset: { placement: L },
};
const k = E.map((t) => {
const e = u(t.placement);
return [
t.placement,
e && g
? t.overflows.slice(0, 2).reduce((t, e) => t + e, 0)
: t.overflows[0],
t.overflows,
];
}).sort((t, e) => t[1] - e[1]),
C =
(null ==
(r = k.filter((t) =>
t[2].slice(0, u(t[0]) ? 2 : 3).every((t) => t <= 0)
)[0])
? void 0
: r[0]) || k[0][0];
return C !== s
? {
data: { index: P + 1, overflows: E },
reset: { placement: C },
}
: {};
},
}
);
}),
(t.computePosition = async (t, e, n) => {
const {
placement: i = "bottom",
strategy: o = "absolute",
middleware: r = [],
platform: a,
} = n,
l = r.filter(Boolean),
s = await (null == a.isRTL ? void 0 : a.isRTL(e));
let f = await a.getElementRects({
reference: t,
floating: e,
strategy: o,
}),
{ x: c, y: u } = b(f, i, s),
m = i,
d = {},
g = 0;
for (let n = 0; n < l.length; n++) {
const { name: r, fn: p } = l[n],
{
x: h,
y: y,
data: w,
reset: x,
} = await p({
x: c,
y: u,
initialPlacement: i,
placement: m,
strategy: o,
middlewareData: d,
rects: f,
platform: a,
elements: { reference: t, floating: e },
});
(c = null != h ? h : c),
(u = null != y ? y : u),
(d = { ...d, [r]: { ...d[r], ...w } }),
x &&
g <= 50 &&
(g++,
"object" == typeof x &&
(x.placement && (m = x.placement),
x.rects &&
(f =
!0 === x.rects
? await a.getElementRects({
reference: t,
floating: e,
strategy: o,
})
: x.rects),
({ x: c, y: u } = b(f, m, s))),
(n = -1));
}
return { x: c, y: u, placement: m, strategy: o, middlewareData: d };
}),
(t.detectOverflow = A),
(t.flip = function (t) {
return (
void 0 === t && (t = {}),
{
name: "flip",
options: t,
async fn(e) {
var n, i;
const {
placement: o,
middlewareData: r,
rects: a,
initialPlacement: l,
platform: s,
elements: m,
} = e,
{
mainAxis: d = !0,
crossAxis: p = !0,
fallbackPlacements: x,
fallbackStrategy: v = "bestFit",
fallbackAxisSideDirection: b = "none",
flipAlignment: R = !0,
...P
} = f(t, e);
if (null != (n = r.arrow) && n.alignmentOffset) return {};
const D = c(o),
T = g(l),
O = c(l) === l,
E = await (null == s.isRTL ? void 0 : s.isRTL(m.floating)),
L =
x ||
(O || !R
? [w(l)]
: (function (t) {
const e = w(t);
return [y(t), e, y(e)];
})(l)),
k = "none" !== b;
!x &&
k &&
L.push(
...(function (t, e, n, i) {
const o = u(t);
let r = (function (t, e, n) {
const i = ["left", "right"],
o = ["right", "left"],
r = ["top", "bottom"],
a = ["bottom", "top"];
switch (t) {
case "top":
case "bottom":
return n ? (e ? o : i) : e ? i : o;
case "left":
case "right":
return e ? r : a;
default:
return [];
}
})(c(t), "start" === n, i);
return (
o &&
((r = r.map((t) => t + "-" + o)),
e && (r = r.concat(r.map(y)))),
r
);
})(l, R, b, E)
);
const C = [l, ...L],
B = await A(e, P),
H = [];
let S = (null == (i = r.flip) ? void 0 : i.overflows) || [];
if ((d && H.push(B[D]), p)) {
const t = h(o, a, E);
H.push(B[t[0]], B[t[1]]);
}
if (
((S = [...S, { placement: o, overflows: H }]),
!H.every((t) => t <= 0))
) {
var F, j;
const t = ((null == (F = r.flip) ? void 0 : F.index) || 0) + 1,
e = C[t];
if (e) {
var z;
const n = "alignment" === p && T !== g(e),
i = (null == (z = S[0]) ? void 0 : z.overflows[0]) > 0;
if (!n || i)
return {
data: { index: t, overflows: S },
reset: { placement: e },
};
}
let n =
null ==
(j = S.filter((t) => t.overflows[0] <= 0).sort(
(t, e) => t.overflows[1] - e.overflows[1]
)[0])
? void 0
: j.placement;
if (!n)
switch (v) {
case "bestFit": {
var M;
const t =
null ==
(M = S.filter((t) => {
if (k) {
const e = g(t.placement);
return e === T || "y" === e;
}
return !0;
})
.map((t) => [
t.placement,
t.overflows
.filter((t) => t > 0)
.reduce((t, e) => t + e, 0),
])
.sort((t, e) => t[1] - e[1])[0])
? void 0
: M[0];
t && (n = t);
break;
}
case "initialPlacement":
n = l;
}
if (o !== n) return { reset: { placement: n } };
}
return {};
},
}
);
}),
(t.hide = function (t) {
return (
void 0 === t && (t = {}),
{
name: "hide",
options: t,
async fn(e) {
const { rects: n } = e,
{ strategy: i = "referenceHidden", ...o } = f(t, e);
switch (i) {
case "referenceHidden": {
const t = R(
await A(e, { ...o, elementContext: "reference" }),
n.reference
);
return {
data: { referenceHiddenOffsets: t, referenceHidden: P(t) },
};
}
case "escaped": {
const t = R(await A(e, { ...o, altBoundary: !0 }), n.floating);
return { data: { escapedOffsets: t, escaped: P(t) } };
}
default:
return {};
}
},
}
);
}),
(t.inline = function (t) {
return (
void 0 === t && (t = {}),
{
name: "inline",
options: t,
async fn(e) {
const {
placement: n,
elements: i,
rects: a,
platform: l,
strategy: s,
} = e,
{ padding: u = 2, x: m, y: d } = f(t, e),
p = Array.from(
(await (null == l.getClientRects
? void 0
: l.getClientRects(i.reference))) || []
),
h = (function (t) {
const e = t.slice().sort((t, e) => t.y - e.y),
n = [];
let i = null;
for (let t = 0; t < e.length; t++) {
const o = e[t];
!i || o.y - i.y > i.height / 2
? n.push([o])
: n[n.length - 1].push(o),
(i = o);
}
return n.map((t) => v(D(t)));
})(p),
y = v(D(p)),
w = x(u);
const b = await l.getElementRects({
reference: {
getBoundingClientRect: function () {
if (
2 === h.length &&
h[0].left > h[1].right &&
null != m &&
null != d
)
return (
h.find(
(t) =>
m > t.left - w.left &&
m < t.right + w.right &&
d > t.top - w.top &&
d < t.bottom + w.bottom
) || y
);
if (h.length >= 2) {
if ("y" === g(n)) {
const t = h[0],
e = h[h.length - 1],
i = "top" === c(n),
o = t.top,
r = e.bottom,
a = i ? t.left : e.left,
l = i ? t.right : e.right;
return {
top: o,
bottom: r,
left: a,
right: l,
width: l - a,
height: r - o,
x: a,
y: o,
};
}
const t = "left" === c(n),
e = r(...h.map((t) => t.right)),
i = o(...h.map((t) => t.left)),
a = h.filter((n) => (t ? n.left === i : n.right === e)),
l = a[0].top,
s = a[a.length - 1].bottom;
return {
top: l,
bottom: s,
left: i,
right: e,
width: e - i,
height: s - l,
x: i,
y: l,
};
}
return y;
},
},
floating: i.floating,
strategy: s,
});
return a.reference.x !== b.reference.x ||
a.reference.y !== b.reference.y ||
a.reference.width !== b.reference.width ||
a.reference.height !== b.reference.height
? { reset: { rects: b } }
: {};
},
}
);
}),
(t.limitShift = function (t) {
return (
void 0 === t && (t = {}),
{
options: t,
fn(e) {
const { x: n, y: i, placement: o, rects: r, middlewareData: a } = e,
{ offset: l = 0, mainAxis: s = !0, crossAxis: u = !0 } = f(t, e),
d = { x: n, y: i },
p = g(o),
h = m(p);
let y = d[h],
w = d[p];
const x = f(l, e),
v =
"number" == typeof x
? { mainAxis: x, crossAxis: 0 }
: { mainAxis: 0, crossAxis: 0, ...x };
if (s) {
const t = "y" === h ? "height" : "width",
e = r.reference[h] - r.floating[t] + v.mainAxis,
n = r.reference[h] + r.reference[t] - v.mainAxis;
y < e ? (y = e) : y > n && (y = n);
}
if (u) {
var b, A;
const t = "y" === h ? "width" : "height",
e = ["top", "left"].includes(c(o)),
n =
r.reference[p] -
r.floating[t] +
((e && (null == (b = a.offset) ? void 0 : b[p])) || 0) +
(e ? 0 : v.crossAxis),
i =
r.reference[p] +
r.reference[t] +
(e ? 0 : (null == (A = a.offset) ? void 0 : A[p]) || 0) -
(e ? v.crossAxis : 0);
w < n ? (w = n) : w > i && (w = i);
}
return { [h]: y, [p]: w };
},
}
);
}),
(t.offset = function (t) {
return (
void 0 === t && (t = 0),
{
name: "offset",
options: t,
async fn(e) {
var n, i;
const { x: o, y: r, placement: a, middlewareData: l } = e,
s = await (async function (t, e) {
const { placement: n, platform: i, elements: o } = t,
r = await (null == i.isRTL ? void 0 : i.isRTL(o.floating)),
a = c(n),
l = u(n),
s = "y" === g(n),
m = ["left", "top"].includes(a) ? -1 : 1,
d = r && s ? -1 : 1,
p = f(e, t);
let {
mainAxis: h,
crossAxis: y,
alignmentAxis: w,
} = "number" == typeof p
? { mainAxis: p, crossAxis: 0, alignmentAxis: null }
: {
mainAxis: p.mainAxis || 0,
crossAxis: p.crossAxis || 0,
alignmentAxis: p.alignmentAxis,
};
return (
l && "number" == typeof w && (y = "end" === l ? -1 * w : w),
s ? { x: y * d, y: h * m } : { x: h * m, y: y * d }
);
})(e, t);
return a === (null == (n = l.offset) ? void 0 : n.placement) &&
null != (i = l.arrow) &&
i.alignmentOffset
? {}
: { x: o + s.x, y: r + s.y, data: { ...s, placement: a } };
},
}
);
}),
(t.rectToClientRect = v),
(t.shift = function (t) {
return (
void 0 === t && (t = {}),
{
name: "shift",
options: t,
async fn(e) {
const { x: n, y: i, placement: o } = e,
{
mainAxis: r = !0,
crossAxis: a = !1,
limiter: l = {
fn: (t) => {
let { x: e, y: n } = t;
return { x: e, y: n };
},
},
...u
} = f(t, e),
d = { x: n, y: i },
p = await A(e, u),
h = g(c(o)),
y = m(h);
let w = d[y],
x = d[h];
if (r) {
const t = "y" === y ? "bottom" : "right";
w = s(w + p["y" === y ? "top" : "left"], w, w - p[t]);
}
if (a) {
const t = "y" === h ? "bottom" : "right";
x = s(x + p["y" === h ? "top" : "left"], x, x - p[t]);
}
const v = l.fn({ ...e, [y]: w, [h]: x });
return {
...v,
data: { x: v.x - n, y: v.y - i, enabled: { [y]: r, [h]: a } },
};
},
}
);
}),
(t.size = function (t) {
return (
void 0 === t && (t = {}),
{
name: "size",
options: t,
async fn(e) {
var n, i;
const { placement: a, rects: l, platform: s, elements: m } = e,
{ apply: d = () => {}, ...p } = f(t, e),
h = await A(e, p),
y = c(a),
w = u(a),
x = "y" === g(a),
{ width: v, height: b } = l.floating;
let R, P;
"top" === y || "bottom" === y
? ((R = y),
(P =
w ===
((await (null == s.isRTL ? void 0 : s.isRTL(m.floating)))
? "start"
: "end")
? "left"
: "right"))
: ((P = y), (R = "end" === w ? "top" : "bottom"));
const D = b - h.top - h.bottom,
T = v - h.left - h.right,
O = o(b - h[R], D),
E = o(v - h[P], T),
L = !e.middlewareData.shift;
let k = O,
C = E;
if (
(null != (n = e.middlewareData.shift) && n.enabled.x && (C = T),
null != (i = e.middlewareData.shift) && i.enabled.y && (k = D),
L && !w)
) {
const t = r(h.left, 0),
e = r(h.right, 0),
n = r(h.top, 0),
i = r(h.bottom, 0);
x
? (C =
v - 2 * (0 !== t || 0 !== e ? t + e : r(h.left, h.right)))
: (k =
b - 2 * (0 !== n || 0 !== i ? n + i : r(h.top, h.bottom)));
}
await d({ ...e, availableWidth: C, availableHeight: k });
const B = await s.getDimensions(m.floating);
return v !== B.width || b !== B.height
? { reset: { rects: !0 } }
: {};
},
}
);
});
});
</script>
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,606 @@
// templui component popover - version: main installed by templui v0.71.0
package popover
// https://cdn.jsdelivr.net/npm/@floating-ui/dom@1.7.0
templ FloatingUIDom() {
<script nonce={ templ.GetNonce(ctx) }>
!(function (t, e) {
"object" == typeof exports && "undefined" != typeof module
? e(exports, require("@floating-ui/core"))
: "function" == typeof define && define.amd
? define(["exports", "@floating-ui/core"], e)
: e(
((t =
"undefined" != typeof globalThis
? globalThis
: t || self).FloatingUIDOM = {}),
t.FloatingUICore
);
})(this, function (t, e) {
"use strict";
const n = Math.min,
o = Math.max,
i = Math.round,
r = Math.floor,
c = (t) => ({ x: t, y: t });
function l() {
return "undefined" != typeof window;
}
function s(t) {
return a(t) ? (t.nodeName || "").toLowerCase() : "#document";
}
function f(t) {
var e;
return (
(null == t || null == (e = t.ownerDocument) ? void 0 : e.defaultView) ||
window
);
}
function u(t) {
var e;
return null ==
(e = (a(t) ? t.ownerDocument : t.document) || window.document)
? void 0
: e.documentElement;
}
function a(t) {
return !!l() && (t instanceof Node || t instanceof f(t).Node);
}
function d(t) {
return !!l() && (t instanceof Element || t instanceof f(t).Element);
}
function h(t) {
return !!l() && (t instanceof HTMLElement || t instanceof f(t).HTMLElement);
}
function p(t) {
return (
!(!l() || "undefined" == typeof ShadowRoot) &&
(t instanceof ShadowRoot || t instanceof f(t).ShadowRoot)
);
}
function g(t) {
const { overflow: e, overflowX: n, overflowY: o, display: i } = b(t);
return (
/auto|scroll|overlay|hidden|clip/.test(e + o + n) &&
!["inline", "contents"].includes(i)
);
}
function m(t) {
return ["table", "td", "th"].includes(s(t));
}
function y(t) {
return [":popover-open", ":modal"].some((e) => {
try {
return t.matches(e);
} catch (t) {
return !1;
}
});
}
function w(t) {
const e = x(),
n = d(t) ? b(t) : t;
return (
["transform", "translate", "scale", "rotate", "perspective"].some(
(t) => !!n[t] && "none" !== n[t]
) ||
(!!n.containerType && "normal" !== n.containerType) ||
(!e && !!n.backdropFilter && "none" !== n.backdropFilter) ||
(!e && !!n.filter && "none" !== n.filter) ||
[
"transform",
"translate",
"scale",
"rotate",
"perspective",
"filter",
].some((t) => (n.willChange || "").includes(t)) ||
["paint", "layout", "strict", "content"].some((t) =>
(n.contain || "").includes(t)
)
);
}
function x() {
return (
!("undefined" == typeof CSS || !CSS.supports) &&
CSS.supports("-webkit-backdrop-filter", "none")
);
}
function v(t) {
return ["html", "body", "#document"].includes(s(t));
}
function b(t) {
return f(t).getComputedStyle(t);
}
function T(t) {
return d(t)
? { scrollLeft: t.scrollLeft, scrollTop: t.scrollTop }
: { scrollLeft: t.scrollX, scrollTop: t.scrollY };
}
function L(t) {
if ("html" === s(t)) return t;
const e = t.assignedSlot || t.parentNode || (p(t) && t.host) || u(t);
return p(e) ? e.host : e;
}
function R(t) {
const e = L(t);
return v(e)
? t.ownerDocument
? t.ownerDocument.body
: t.body
: h(e) && g(e)
? e
: R(e);
}
function C(t, e, n) {
var o;
void 0 === e && (e = []), void 0 === n && (n = !0);
const i = R(t),
r = i === (null == (o = t.ownerDocument) ? void 0 : o.body),
c = f(i);
if (r) {
const t = E(c);
return e.concat(
c,
c.visualViewport || [],
g(i) ? i : [],
t && n ? C(t) : []
);
}
return e.concat(i, C(i, [], n));
}
function E(t) {
return t.parent && Object.getPrototypeOf(t.parent) ? t.frameElement : null;
}
function S(t) {
const e = b(t);
let n = parseFloat(e.width) || 0,
o = parseFloat(e.height) || 0;
const r = h(t),
c = r ? t.offsetWidth : n,
l = r ? t.offsetHeight : o,
s = i(n) !== c || i(o) !== l;
return s && ((n = c), (o = l)), { width: n, height: o, $: s };
}
function F(t) {
return d(t) ? t : t.contextElement;
}
function O(t) {
const e = F(t);
if (!h(e)) return c(1);
const n = e.getBoundingClientRect(),
{ width: o, height: r, $: l } = S(e);
let s = (l ? i(n.width) : n.width) / o,
f = (l ? i(n.height) : n.height) / r;
return (
(s && Number.isFinite(s)) || (s = 1),
(f && Number.isFinite(f)) || (f = 1),
{ x: s, y: f }
);
}
const D = c(0);
function H(t) {
const e = f(t);
return x() && e.visualViewport
? { x: e.visualViewport.offsetLeft, y: e.visualViewport.offsetTop }
: D;
}
function P(t, n, o, i) {
void 0 === n && (n = !1), void 0 === o && (o = !1);
const r = t.getBoundingClientRect(),
l = F(t);
let s = c(1);
n && (i ? d(i) && (s = O(i)) : (s = O(t)));
const u = (function (t, e, n) {
return void 0 === e && (e = !1), !(!n || (e && n !== f(t))) && e;
})(l, o, i)
? H(l)
: c(0);
let a = (r.left + u.x) / s.x,
h = (r.top + u.y) / s.y,
p = r.width / s.x,
g = r.height / s.y;
if (l) {
const t = f(l),
e = i && d(i) ? f(i) : i;
let n = t,
o = E(n);
for (; o && i && e !== n; ) {
const t = O(o),
e = o.getBoundingClientRect(),
i = b(o),
r = e.left + (o.clientLeft + parseFloat(i.paddingLeft)) * t.x,
c = e.top + (o.clientTop + parseFloat(i.paddingTop)) * t.y;
(a *= t.x),
(h *= t.y),
(p *= t.x),
(g *= t.y),
(a += r),
(h += c),
(n = f(o)),
(o = E(n));
}
}
return e.rectToClientRect({ width: p, height: g, x: a, y: h });
}
function W(t, e) {
const n = T(t).scrollLeft;
return e ? e.left + n : P(u(t)).left + n;
}
function M(t, e, n) {
void 0 === n && (n = !1);
const o = t.getBoundingClientRect();
return {
x: o.left + e.scrollLeft - (n ? 0 : W(t, o)),
y: o.top + e.scrollTop,
};
}
function z(t, n, i) {
let r;
if ("viewport" === n)
r = (function (t, e) {
const n = f(t),
o = u(t),
i = n.visualViewport;
let r = o.clientWidth,
c = o.clientHeight,
l = 0,
s = 0;
if (i) {
(r = i.width), (c = i.height);
const t = x();
(!t || (t && "fixed" === e)) &&
((l = i.offsetLeft), (s = i.offsetTop));
}
return { width: r, height: c, x: l, y: s };
})(t, i);
else if ("document" === n)
r = (function (t) {
const e = u(t),
n = T(t),
i = t.ownerDocument.body,
r = o(e.scrollWidth, e.clientWidth, i.scrollWidth, i.clientWidth),
c = o(e.scrollHeight, e.clientHeight, i.scrollHeight, i.clientHeight);
let l = -n.scrollLeft + W(t);
const s = -n.scrollTop;
return (
"rtl" === b(i).direction &&
(l += o(e.clientWidth, i.clientWidth) - r),
{ width: r, height: c, x: l, y: s }
);
})(u(t));
else if (d(n))
r = (function (t, e) {
const n = P(t, !0, "fixed" === e),
o = n.top + t.clientTop,
i = n.left + t.clientLeft,
r = h(t) ? O(t) : c(1);
return {
width: t.clientWidth * r.x,
height: t.clientHeight * r.y,
x: i * r.x,
y: o * r.y,
};
})(n, i);
else {
const e = H(t);
r = { x: n.x - e.x, y: n.y - e.y, width: n.width, height: n.height };
}
return e.rectToClientRect(r);
}
function A(t, e) {
const n = L(t);
return (
!(n === e || !d(n) || v(n)) && ("fixed" === b(n).position || A(n, e))
);
}
function B(t, e, n) {
const o = h(e),
i = u(e),
r = "fixed" === n,
l = P(t, !0, r, e);
let f = { scrollLeft: 0, scrollTop: 0 };
const a = c(0);
function d() {
a.x = W(i);
}
if (o || (!o && !r))
if ((("body" !== s(e) || g(i)) && (f = T(e)), o)) {
const t = P(e, !0, r, e);
(a.x = t.x + e.clientLeft), (a.y = t.y + e.clientTop);
} else i && d();
r && !o && i && d();
const p = !i || o || r ? c(0) : M(i, f);
return {
x: l.left + f.scrollLeft - a.x - p.x,
y: l.top + f.scrollTop - a.y - p.y,
width: l.width,
height: l.height,
};
}
function V(t) {
return "static" === b(t).position;
}
function N(t, e) {
if (!h(t) || "fixed" === b(t).position) return null;
if (e) return e(t);
let n = t.offsetParent;
return u(t) === n && (n = n.ownerDocument.body), n;
}
function I(t, e) {
const n = f(t);
if (y(t)) return n;
if (!h(t)) {
let e = L(t);
for (; e && !v(e); ) {
if (d(e) && !V(e)) return e;
e = L(e);
}
return n;
}
let o = N(t, e);
for (; o && m(o) && V(o); ) o = N(o, e);
return o && v(o) && V(o) && !w(o)
? n
: o ||
(function (t) {
let e = L(t);
for (; h(e) && !v(e); ) {
if (w(e)) return e;
if (y(e)) return null;
e = L(e);
}
return null;
})(t) ||
n;
}
const k = {
convertOffsetParentRelativeRectToViewportRelativeRect: function (t) {
let { elements: e, rect: n, offsetParent: o, strategy: i } = t;
const r = "fixed" === i,
l = u(o),
f = !!e && y(e.floating);
if (o === l || (f && r)) return n;
let a = { scrollLeft: 0, scrollTop: 0 },
d = c(1);
const p = c(0),
m = h(o);
if (
(m || (!m && !r)) &&
(("body" !== s(o) || g(l)) && (a = T(o)), h(o))
) {
const t = P(o);
(d = O(o)), (p.x = t.x + o.clientLeft), (p.y = t.y + o.clientTop);
}
const w = !l || m || r ? c(0) : M(l, a, !0);
return {
width: n.width * d.x,
height: n.height * d.y,
x: n.x * d.x - a.scrollLeft * d.x + p.x + w.x,
y: n.y * d.y - a.scrollTop * d.y + p.y + w.y,
};
},
getDocumentElement: u,
getClippingRect: function (t) {
let { element: e, boundary: i, rootBoundary: r, strategy: c } = t;
const l = [
...("clippingAncestors" === i
? y(e)
? []
: (function (t, e) {
const n = e.get(t);
if (n) return n;
let o = C(t, [], !1).filter((t) => d(t) && "body" !== s(t)),
i = null;
const r = "fixed" === b(t).position;
let c = r ? L(t) : t;
for (; d(c) && !v(c); ) {
const e = b(c),
n = w(c);
n || "fixed" !== e.position || (i = null),
(
r
? !n && !i
: (!n &&
"static" === e.position &&
i &&
["absolute", "fixed"].includes(i.position)) ||
(g(c) && !n && A(t, c))
)
? (o = o.filter((t) => t !== c))
: (i = e),
(c = L(c));
}
return e.set(t, o), o;
})(e, this._c)
: [].concat(i)),
r,
],
f = l[0],
u = l.reduce((t, i) => {
const r = z(e, i, c);
return (
(t.top = o(r.top, t.top)),
(t.right = n(r.right, t.right)),
(t.bottom = n(r.bottom, t.bottom)),
(t.left = o(r.left, t.left)),
t
);
}, z(e, f, c));
return {
width: u.right - u.left,
height: u.bottom - u.top,
x: u.left,
y: u.top,
};
},
getOffsetParent: I,
getElementRects: async function (t) {
const e = this.getOffsetParent || I,
n = this.getDimensions,
o = await n(t.floating);
return {
reference: B(t.reference, await e(t.floating), t.strategy),
floating: { x: 0, y: 0, width: o.width, height: o.height },
};
},
getClientRects: function (t) {
return Array.from(t.getClientRects());
},
getDimensions: function (t) {
const { width: e, height: n } = S(t);
return { width: e, height: n };
},
getScale: O,
isElement: d,
isRTL: function (t) {
return "rtl" === b(t).direction;
},
};
function q(t, e) {
return (
t.x === e.x && t.y === e.y && t.width === e.width && t.height === e.height
);
}
const U = e.detectOverflow,
j = e.offset,
X = e.autoPlacement,
Y = e.shift,
$ = e.flip,
_ = e.size,
G = e.hide,
J = e.arrow,
K = e.inline,
Q = e.limitShift;
(t.arrow = J),
(t.autoPlacement = X),
(t.autoUpdate = function (t, e, i, c) {
void 0 === c && (c = {});
const {
ancestorScroll: l = !0,
ancestorResize: s = !0,
elementResize: f = "function" == typeof ResizeObserver,
layoutShift: a = "function" == typeof IntersectionObserver,
animationFrame: d = !1,
} = c,
h = F(t),
p = l || s ? [...(h ? C(h) : []), ...C(e)] : [];
p.forEach((t) => {
l && t.addEventListener("scroll", i, { passive: !0 }),
s && t.addEventListener("resize", i);
});
const g =
h && a
? (function (t, e) {
let i,
c = null;
const l = u(t);
function s() {
var t;
clearTimeout(i), null == (t = c) || t.disconnect(), (c = null);
}
return (
(function f(u, a) {
void 0 === u && (u = !1), void 0 === a && (a = 1), s();
const d = t.getBoundingClientRect(),
{ left: h, top: p, width: g, height: m } = d;
if ((u || e(), !g || !m)) return;
const y = {
rootMargin:
-r(p) +
"px " +
-r(l.clientWidth - (h + g)) +
"px " +
-r(l.clientHeight - (p + m)) +
"px " +
-r(h) +
"px",
threshold: o(0, n(1, a)) || 1,
};
let w = !0;
function x(e) {
const n = e[0].intersectionRatio;
if (n !== a) {
if (!w) return f();
n
? f(!1, n)
: (i = setTimeout(() => {
f(!1, 1e-7);
}, 1e3));
}
1 !== n || q(d, t.getBoundingClientRect()) || f(), (w = !1);
}
try {
c = new IntersectionObserver(x, {
...y,
root: l.ownerDocument,
});
} catch (t) {
c = new IntersectionObserver(x, y);
}
c.observe(t);
})(!0),
s
);
})(h, i)
: null;
let m,
y = -1,
w = null;
f &&
((w = new ResizeObserver((t) => {
let [n] = t;
n &&
n.target === h &&
w &&
(w.unobserve(e),
cancelAnimationFrame(y),
(y = requestAnimationFrame(() => {
var t;
null == (t = w) || t.observe(e);
}))),
i();
})),
h && !d && w.observe(h),
w.observe(e));
let x = d ? P(t) : null;
return (
d &&
(function e() {
const n = P(t);
x && !q(x, n) && i();
(x = n), (m = requestAnimationFrame(e));
})(),
i(),
() => {
var t;
p.forEach((t) => {
l && t.removeEventListener("scroll", i),
s && t.removeEventListener("resize", i);
}),
null == g || g(),
null == (t = w) || t.disconnect(),
(w = null),
d && cancelAnimationFrame(m);
}
);
}),
(t.computePosition = (t, n, o) => {
const i = new Map(),
r = { platform: k, ...o },
c = { ...r.platform, _c: i };
return e.computePosition(t, n, { ...r, platform: c });
}),
(t.detectOverflow = U),
(t.flip = $),
(t.getOverflowAncestors = C),
(t.hide = G),
(t.inline = K),
(t.limitShift = Q),
(t.offset = j),
(t.platform = k),
(t.shift = Y),
(t.size = _);
});
</script>
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,489 @@
// templui component popover - version: main installed by templui v0.71.0
package popover
import (
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
"strconv"
)
type Placement string
const (
PlacementTop Placement = "top"
PlacementTopStart Placement = "top-start"
PlacementTopEnd Placement = "top-end"
PlacementRight Placement = "right"
PlacementRightStart Placement = "right-start"
PlacementRightEnd Placement = "right-end"
PlacementBottom Placement = "bottom"
PlacementBottomStart Placement = "bottom-start"
PlacementBottomEnd Placement = "bottom-end"
PlacementLeft Placement = "left"
PlacementLeftStart Placement = "left-start"
PlacementLeftEnd Placement = "left-end"
)
type TriggerType string
const (
TriggerTypeHover TriggerType = "hover"
TriggerTypeClick TriggerType = "click"
)
type Props struct {
Class string
}
type TriggerProps struct {
ID string
For string
TriggerType TriggerType
}
type ContentProps struct {
ID string
Class string
Attributes templ.Attributes
Placement Placement
Offset int
DisableClickAway bool
DisableESC bool
ShowArrow bool
HoverDelay int
HoverOutDelay int
MatchWidth bool
}
templ Popover(props ...Props) {
@Script()
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div class={ p.Class }>
{ children... }
</div>
}
templ Trigger(props ...TriggerProps) {
{{ var p TriggerProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.TriggerType == "" {
{{ p.TriggerType = TriggerTypeClick }}
}
<span
if p.ID != "" {
id={ p.ID }
}
data-popover-trigger
data-popover-for={ p.For }
data-popover-type={ string(p.TriggerType) }
>
{ children... }
</span>
}
templ Content(props ...ContentProps) {
{{ var p ContentProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.Placement == "" {
{{ p.Placement = PlacementBottom }}
}
if p.Offset == 0 {
if p.ShowArrow {
{{ p.Offset = 8 }}
} else {
{{ p.Offset = 4 }}
}
}
<div
id={ p.ID }
data-popover-id={ p.ID }
data-popover-placement={ string(p.Placement) }
data-popover-offset={ strconv.Itoa(p.Offset) }
data-popover-disable-clickaway={ strconv.FormatBool(p.DisableClickAway) }
data-popover-disable-esc={ strconv.FormatBool(p.DisableESC) }
data-popover-show-arrow={ strconv.FormatBool(p.ShowArrow) }
data-popover-hover-delay={ strconv.Itoa(p.HoverDelay) }
data-popover-hover-out-delay={ strconv.Itoa(p.HoverOutDelay) }
if p.MatchWidth {
data-popover-match-width="true"
}
class={ utils.TwMerge(
"bg-background rounded-lg border text-sm shadow-lg pointer-events-auto absolute z-[9999] hidden top-0 left-0",
p.Class,
) }
{ p.Attributes... }
>
<div class="w-full overflow-hidden">
{ children... }
</div>
if p.ShowArrow {
<div data-popover-arrow class="absolute h-2.5 w-2.5 rotate-45 bg-background border"></div>
}
</div>
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
@FloatingUICore()
@FloatingUIDom()
<script nonce={ templ.GetNonce(ctx) }>
if (typeof window.popoverState === 'undefined') {
window.popoverState = new Map();
}
(function() { // IIFE Start
if (window.popoverSystemInitialized) return;
// --- Ensure Global Portal Container ---
let portalContainer = document.querySelector('[data-popover-portal-container]');
if (!portalContainer) {
portalContainer = document.createElement('div');
portalContainer.setAttribute('data-popover-portal-container', '');
portalContainer.className = 'fixed inset-0 z-[9999] pointer-events-none';
document.body.appendChild(portalContainer);
}
// --- End Ensure Global Portal Container ---
// --- Floating UI Check & Helper ---
let FloatingUIDOM = null;
function whenFloatingUiReady(callback, attempt = 1) {
if (window.FloatingUIDOM) {
FloatingUIDOM = window.FloatingUIDOM;
callback();
} else if (attempt < 40) {
setTimeout(() => whenFloatingUiReady(callback, attempt + 1), 50);
} else {
console.error("Floating UI DOM failed to load after several attempts.");
}
}
// --- Helper Functions ---
function findReferenceElement(triggerSpan) {
const children = triggerSpan.children;
if (children.length === 0) return triggerSpan;
let bestElement = triggerSpan;
let largestArea = 0;
for (const child of children) {
if (typeof child.getBoundingClientRect !== 'function') continue;
const rect = child.getBoundingClientRect();
const area = rect.width * rect.height;
if (area > largestArea) {
largestArea = area;
bestElement = child;
}
}
return bestElement;
}
function positionArrow(arrowElement, placement, arrowData, content) {
const { x: arrowX, y: arrowY } = arrowData;
const staticSide = { top: 'bottom', right: 'left', bottom: 'top', left: 'right' }[placement.split('-')[0]];
Object.assign(arrowElement.style, { left: arrowX != null ? `${arrowX}px` : '', top: arrowY != null ? `${arrowY}px` : '', right: '', bottom: '', [staticSide]: '-5px' });
const popoverStyle = window.getComputedStyle(content);
const popoverBorderColor = popoverStyle.borderColor;
arrowElement.style.backgroundColor = popoverStyle.backgroundColor;
arrowElement.style.borderTopColor = popoverBorderColor;
arrowElement.style.borderRightColor = popoverBorderColor;
arrowElement.style.borderBottomColor = popoverBorderColor;
arrowElement.style.borderLeftColor = popoverBorderColor;
switch (staticSide) {
case 'top': arrowElement.style.borderBottomColor = 'transparent'; arrowElement.style.borderRightColor = 'transparent'; break;
case 'bottom': arrowElement.style.borderTopColor = 'transparent'; arrowElement.style.borderLeftColor = 'transparent'; break;
case 'left': arrowElement.style.borderTopColor = 'transparent'; arrowElement.style.borderRightColor = 'transparent'; break;
case 'right': arrowElement.style.borderBottomColor = 'transparent'; arrowElement.style.borderLeftColor = 'transparent'; break;
}
}
function addAnimationStyles() {
if (document.getElementById('popover-animations')) return;
const style = document.createElement('style');
style.id = 'popover-animations';
style.textContent = `
@keyframes popover-in { 0% { opacity: 0; transform: scale(0.95); } 100% { opacity: 1; transform: scale(1); } }
@keyframes popover-out { 0% { opacity: 1; transform: scale(1); } 100% { opacity: 0; transform: scale(0.95); } }
[data-popover-id].popover-animate-in { animation: popover-in 0.15s cubic-bezier(0.16, 1, 0.3, 1); }
[data-popover-id].popover-animate-out { animation: popover-out 0.1s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
`;
document.head.appendChild(style);
}
// --- Core Popover Logic ---
function updatePosition(state) {
if (!FloatingUIDOM || !state || !state.trigger || !state.content) return;
const { computePosition, offset, flip, shift, arrow } = FloatingUIDOM;
const referenceElement = findReferenceElement(state.trigger);
const arrowElement = state.content.querySelector('[data-popover-arrow]');
const placement = state.content.dataset.popoverPlacement || 'bottom';
const offsetValue = parseInt(state.content.dataset.popoverOffset) || (arrowElement ? 8 : 4);
const shouldMatchWidth = state.content.dataset.popoverMatchWidth === 'true';
const middleware = [offset(offsetValue), flip({ padding: 10 }), shift({ padding: 10 })];
if (arrowElement) middleware.push(arrow({ element: arrowElement, padding: 5 }));
computePosition(referenceElement, state.content, { placement, middleware }).then(({ x, y, placement, middlewareData }) => {
Object.assign(state.content.style, { left: `${x}px`, top: `${y}px` });
if (shouldMatchWidth) {
const triggerWidth = referenceElement.offsetWidth;
state.content.style.setProperty('--popover-trigger-width', `${triggerWidth}px`);
}
if (arrowElement && middlewareData.arrow) {
positionArrow(arrowElement, placement, middlewareData.arrow, state.content);
}
});
}
function addGlobalListeners(popoverId, state) {
removeGlobalListeners(state); // Ensure no duplicates
if (state.content.dataset.popoverDisableClickaway !== 'true') {
const handler = (e) => {
// Close if click is outside trigger and content
if (!state.trigger.contains(e.target) && !state.content.contains(e.target)) {
closePopover(popoverId);
}
};
// Use setTimeout to avoid capturing the click that opened the popover
setTimeout(() => document.addEventListener('click', handler), 0);
state.eventListeners.clickAway = handler;
}
if (state.content.dataset.popoverDisableEsc !== 'true') {
const handler = (e) => { if (e.key === 'Escape') closePopover(popoverId); };
document.addEventListener('keydown', handler);
state.eventListeners.esc = handler;
}
}
function removeGlobalListeners(state) {
if (state.eventListeners.clickAway) document.removeEventListener('click', state.eventListeners.clickAway);
if (state.eventListeners.esc) document.removeEventListener('keydown', state.eventListeners.esc);
state.eventListeners = {}; // Clear stored handlers
}
function openPopover(popoverId, trigger) {
if (!FloatingUIDOM) return;
const { autoUpdate } = FloatingUIDOM;
const content = document.getElementById(popoverId);
if (!content) return;
let state = window.popoverState.get(popoverId);
if (!state) { // Should be created by initTrigger, but as a fallback
state = { trigger, content, isOpen: false, cleanup: null, hoverState: {}, eventListeners: {} };
window.popoverState.set(popoverId, state);
} else if (state.isOpen) return;
state.trigger = trigger; // Ensure trigger reference is current
state.content = content; // Ensure content reference is current
const portal = document.querySelector('[data-popover-portal-container]');
if (portal && content.parentNode !== portal) portal.appendChild(content);
content.style.display = 'block';
content.classList.remove('popover-animate-out');
content.classList.add('popover-animate-in');
// Initial position update before autoUpdate starts
updatePosition(state);
if (state.cleanup) state.cleanup();
state.cleanup = autoUpdate(findReferenceElement(trigger), content, () => updatePosition(state), { animationFrame: true }); // Use animationFrame for smoother updates
addGlobalListeners(popoverId, state);
state.isOpen = true;
}
function closePopover(popoverId, immediate = false) {
const state = window.popoverState.get(popoverId);
if (!state || !state.isOpen) return;
if (state.cleanup) { state.cleanup(); state.cleanup = null; }
removeGlobalListeners(state);
const content = state.content;
function hideContent() { content.style.display = 'none'; content.classList.remove('popover-animate-in', 'popover-animate-out'); }
if (immediate) hideContent();
else {
content.classList.remove('popover-animate-in');
content.classList.add('popover-animate-out');
setTimeout(hideContent, 150); // Match animation duration
}
state.isOpen = false;
}
// Expose closePopover globally
window.closePopover = closePopover;
// --- Trigger Initialization & Handling ---
function attachClickTrigger(trigger, popoverId) {
const handler = (e) => {
e.stopPropagation();
const state = window.popoverState.get(popoverId);
if (state?.isOpen) closePopover(popoverId);
else openPopover(popoverId, trigger);
};
trigger.addEventListener('click', handler);
trigger._popoverListener = handler;
}
function attachHoverTrigger(trigger, popoverId) {
const content = document.getElementById(popoverId);
if (!content) return;
let state = window.popoverState.get(popoverId);
if (!state) return; // State should exist from initTrigger
const hoverDelay = parseInt(content.dataset.popoverHoverDelay) || 100;
const hoverOutDelay = parseInt(content.dataset.popoverHoverOutDelay) || 200;
const handleTriggerEnter = () => { clearTimeout(state.hoverState.leaveTimeout); state.hoverState.enterTimeout = setTimeout(() => openPopover(popoverId, trigger), hoverDelay); };
const handleTriggerLeave = (e) => { clearTimeout(state.hoverState.enterTimeout); state.hoverState.leaveTimeout = setTimeout(() => { if (!content.contains(e.relatedTarget)) closePopover(popoverId); }, hoverOutDelay); };
const handleContentEnter = () => clearTimeout(state.hoverState.leaveTimeout);
const handleContentLeave = (e) => { state.hoverState.leaveTimeout = setTimeout(() => { if (!trigger.contains(e.relatedTarget)) closePopover(popoverId); }, hoverOutDelay); };
trigger.addEventListener('mouseenter', handleTriggerEnter);
trigger.addEventListener('mouseleave', handleTriggerLeave);
content.addEventListener('mouseenter', handleContentEnter);
content.addEventListener('mouseleave', handleContentLeave);
// Store handlers for cleanup
trigger._popoverHoverListeners = { handleTriggerEnter, handleTriggerLeave };
content._popoverHoverListeners = { handleContentEnter, handleContentLeave };
}
function initTrigger(trigger) {
const popoverId = trigger.dataset.popoverFor;
const content = document.getElementById(popoverId);
if (!popoverId || !content) return;
// Prevent re-attaching listeners to the same DOM element instance
if (trigger._popoverListenerAttached) return;
// Ensure state object exists
if (!window.popoverState.has(popoverId)) {
window.popoverState.set(popoverId, {
trigger, content, isOpen: false, cleanup: null,
hoverState: {}, eventListeners: {}
});
} else {
// Update refs in existing state if trigger persisted
const state = window.popoverState.get(popoverId);
state.trigger = trigger;
state.content = content;
// Ensure closed state after potential swap/cleanup
if (state.isOpen) closePopover(popoverId, true);
}
// Cleanup any stray listeners before attaching new ones
if (trigger._popoverListener) trigger.removeEventListener('click', trigger._popoverListener);
if (trigger._popoverHoverListeners) { trigger.removeEventListener('mouseenter', trigger._popoverHoverListeners.handleTriggerEnter); trigger.removeEventListener('mouseleave', trigger._popoverHoverListeners.handleTriggerLeave); }
if (content._popoverHoverListeners) { content.removeEventListener('mouseenter', content._popoverHoverListeners.handleContentEnter); content.removeEventListener('mouseleave', content._popoverHoverListeners.handleContentLeave); }
delete trigger._popoverListener;
delete trigger._popoverHoverListeners;
if (content) delete content._popoverHoverListeners;
// Attach the correct listener type
const triggerType = trigger.dataset.popoverType || 'click';
if (triggerType === 'click') {
attachClickTrigger(trigger, popoverId);
} else if (triggerType === 'hover') {
attachHoverTrigger(trigger, popoverId);
}
trigger._popoverListenerAttached = true;
}
// --- Cleanup ---
function cleanupPopovers(element) {
const cleanupTrigger = (trigger) => {
const popoverId = trigger.dataset.popoverFor;
if (popoverId) {
closePopover(popoverId, true); // Close popover, remove global listeners, stop Floating UI
}
// Remove listeners directly attached to the trigger
if (trigger._popoverListener) trigger.removeEventListener('click', trigger._popoverListener);
if (trigger._popoverHoverListeners) {
trigger.removeEventListener('mouseenter', trigger._popoverHoverListeners.handleTriggerEnter);
trigger.removeEventListener('mouseleave', trigger._popoverHoverListeners.handleTriggerLeave);
}
// Remove listeners attached to the content (for hover)
const content = document.getElementById(popoverId);
if (content && content._popoverHoverListeners) {
content.removeEventListener('mouseenter', content._popoverHoverListeners.handleContentEnter);
content.removeEventListener('mouseleave', content._popoverHoverListeners.handleContentLeave);
delete content._popoverHoverListeners;
}
// Clean up stored references and flags on the trigger
delete trigger._popoverListener;
delete trigger._popoverHoverListeners;
delete trigger._popoverListenerAttached;
// Optionally remove state - might be desired if the element is definitely gone
// window.popoverState.delete(popoverId);
};
// Cleanup element itself if it's a trigger
if (element.matches && element.matches('[data-popover-trigger]')) {
cleanupTrigger(element);
}
// Cleanup descendants
if (element.querySelectorAll) {
element.querySelectorAll('[data-popover-trigger]').forEach(cleanupTrigger);
}
}
function initAllComponents(root = document) {
if (!FloatingUIDOM) return; // Don't init if library isn't ready
if (root instanceof Element && root.matches('[data-popover-trigger]')) {
initTrigger(root);
}
if (root && typeof root.querySelectorAll === 'function') {
for (const trigger of root.querySelectorAll('[data-popover-trigger]')) {
initTrigger(trigger);
}
}
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
whenFloatingUiReady(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => {
whenFloatingUiReady(() => {
addAnimationStyles();
initAllComponents();
});
});
document.body.addEventListener('htmx:beforeSwap', (event) => {
const target = event.detail.target || event.detail.elt;;
if (target instanceof Element) {
cleanupPopovers(target);
}
});
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
window.popoverSystemInitialized = true;
})(); // IIFE End
</script>
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,190 @@
// templui component progress - version: main installed by templui v0.71.0
package progress
import (
"fmt"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Size string
type Variant string
const (
SizeSm Size = "sm"
SizeLg Size = "lg"
)
const (
VariantDefault Variant = "default"
VariantSuccess Variant = "success"
VariantDanger Variant = "danger"
VariantWarning Variant = "warning"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Max int
Value int
Label string
ShowValue bool
Size Size
Variant Variant
BarClass string
HxGet string
HxTrigger string
HxTarget string
HxSwap string
}
templ Progress(props ...Props) {
@Script()
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.ID == "" {
{{ p.ID = utils.RandomID() }}
}
<div
id={ p.ID }
class={ utils.TwMerge("w-full", p.Class) }
if p.HxGet != "" {
hx-get={ p.HxGet }
}
if p.HxTrigger != "" {
hx-trigger={ p.HxTrigger }
}
if p.HxTarget != "" {
hx-target={ p.HxTarget }
}
if p.HxSwap != "" {
hx-swap={ p.HxSwap }
}
aria-valuemin="0"
aria-valuemax={ fmt.Sprintf("%d", maxValue(p.Max)) }
aria-valuenow={ fmt.Sprintf("%d", p.Value) }
role="progressbar"
{ p.Attributes... }
>
if p.Label != "" || p.ShowValue {
<div class="flex justify-between items-center mb-1">
if p.Label != "" {
<span class="text-sm font-medium">{ p.Label }</span>
}
if p.ShowValue {
<span class="text-sm font-medium">
{ fmt.Sprintf("%d%%", percentage(p.Value, p)) }
</span>
}
</div>
}
<div class="w-full overflow-hidden rounded-full bg-secondary">
<div
data-progress-indicator
class={
utils.TwMerge(
"h-full rounded-full transition-all",
sizeClasses(p.Size),
variantClasses(p.Variant),
p.BarClass,
),
}
></div>
</div>
</div>
}
func maxValue(max int) int {
if max <= 0 {
return 100
}
return max
}
func percentage(value int, props Props) int {
max := maxValue(props.Max)
if value < 0 {
value = 0
}
if value > max {
value = max
}
return (value * 100) / max
}
func sizeClasses(size Size) string {
switch size {
case SizeSm:
return "h-1"
case SizeLg:
return "h-4"
default:
return "h-2.5"
}
}
func variantClasses(variant Variant) string {
switch variant {
case VariantSuccess:
return "bg-green-500"
case VariantDanger:
return "bg-destructive"
case VariantWarning:
return "bg-yellow-500"
default:
return "bg-primary"
}
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<script nonce={ templ.GetNonce(ctx) }>
(function() { // IIFE Start
function updateProgressWidth(progressBar) {
if (!progressBar) return;
const indicator = progressBar.querySelector('[data-progress-indicator]');
if (!indicator) return;
const value = parseFloat(progressBar.getAttribute('aria-valuenow') || '0');
let max = parseFloat(progressBar.getAttribute('aria-valuemax') || '100');
if (max <= 0) max = 100;
let percentage = 0;
if (max > 0) {
percentage = (Math.max(0, Math.min(value, max)) / max) * 100;
}
indicator.style.width = percentage + '%';
}
function initAllComponents(root = document) {
if (root instanceof Element && root.matches('[role="progressbar"]')) {
updateProgressWidth(root);
}
if (root && typeof root.querySelectorAll === 'function') {
for (const progressBar of root.querySelectorAll('[role="progressbar"]')) {
updateProgressWidth(progressBar);
}
}
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})(); // IIFE End
</script>
}
}

View file

@ -0,0 +1,420 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component progress - version: main installed by templui v0.71.0
package progress
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"fmt"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Size string
type Variant string
const (
SizeSm Size = "sm"
SizeLg Size = "lg"
)
const (
VariantDefault Variant = "default"
VariantSuccess Variant = "success"
VariantDanger Variant = "danger"
VariantWarning Variant = "warning"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Max int
Value int
Label string
ShowValue bool
Size Size
Variant Variant
BarClass string
HxGet string
HxTrigger string
HxTarget string
HxSwap string
}
func Progress(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = Script().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var p Props
if len(props) > 0 {
p = props[0]
}
if p.ID == "" {
p.ID = utils.RandomID()
}
var templ_7745c5c3_Var2 = []any{utils.TwMerge("w-full", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/progress/progress.templ`, Line: 51, Col: 11}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/progress/progress.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.HxGet != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " hx-get=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(p.HxGet)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/progress/progress.templ`, Line: 54, Col: 19}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.HxTrigger != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " hx-trigger=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(p.HxTrigger)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/progress/progress.templ`, Line: 57, Col: 27}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.HxTarget != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, " hx-target=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(p.HxTarget)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/progress/progress.templ`, Line: 60, Col: 25}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.HxSwap != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " hx-swap=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(p.HxSwap)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/progress/progress.templ`, Line: 63, Col: 21}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " aria-valuemin=\"0\" aria-valuemax=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", maxValue(p.Max)))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/progress/progress.templ`, Line: 66, Col: 52}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\" aria-valuenow=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", p.Value))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/progress/progress.templ`, Line: 67, Col: 44}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\" role=\"progressbar\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Label != "" || p.ShowValue {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<div class=\"flex justify-between items-center mb-1\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Label != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<span class=\"text-sm font-medium\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(p.Label)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/progress/progress.templ`, Line: 74, Col: 48}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</span> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.ShowValue {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "<span class=\"text-sm font-medium\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d%%", percentage(p.Value, p)))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/progress/progress.templ`, Line: 78, Col: 51}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "<div class=\"w-full overflow-hidden rounded-full bg-secondary\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 = []any{
utils.TwMerge(
"h-full rounded-full transition-all",
sizeClasses(p.Size),
variantClasses(p.Variant),
p.BarClass,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var13...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<div data-progress-indicator class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var13).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/progress/progress.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "\"></div></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func maxValue(max int) int {
if max <= 0 {
return 100
}
return max
}
func percentage(value int, props Props) int {
max := maxValue(props.Max)
if value < 0 {
value = 0
}
if value > max {
value = max
}
return (value * 100) / max
}
func sizeClasses(size Size) string {
switch size {
case SizeSm:
return "h-1"
case SizeLg:
return "h-4"
default:
return "h-2.5"
}
}
func variantClasses(variant Variant) string {
switch variant {
case VariantSuccess:
return "bg-green-500"
case VariantDanger:
return "bg-destructive"
case VariantWarning:
return "bg-yellow-500"
default:
return "bg-primary"
}
}
var handle = templ.NewOnceHandle()
func Script() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var15 := templ.GetChildren(ctx)
if templ_7745c5c3_Var15 == nil {
templ_7745c5c3_Var15 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var16 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<script nonce=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(templ.GetNonce(ctx))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/progress/progress.templ`, Line: 145, Col: 37}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "\">\n\t\t\t(function() { // IIFE Start\n\t\t\t\tfunction updateProgressWidth(progressBar) {\n\t\t\t\t\tif (!progressBar) return;\n\t\t\t\t\t\n\t\t\t\t\tconst indicator = progressBar.querySelector('[data-progress-indicator]');\n\t\t\t\t\tif (!indicator) return;\n\t\t\t\t\t\n\t\t\t\t\tconst value = parseFloat(progressBar.getAttribute('aria-valuenow') || '0');\n\t\t\t\t\tlet max = parseFloat(progressBar.getAttribute('aria-valuemax') || '100');\n\t\t\t\t\tif (max <= 0) max = 100;\n\t\t\t\t\t\n\t\t\t\t\tlet percentage = 0;\n\t\t\t\t\tif (max > 0) {\n\t\t\t\t\t\tpercentage = (Math.max(0, Math.min(value, max)) / max) * 100;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tindicator.style.width = percentage + '%';\n\t\t\t\t}\n\n\t\t\t\tfunction initAllComponents(root = document) {\n\t\t\t\t\tif (root instanceof Element && root.matches('[role=\"progressbar\"]')) {\n\t\t\t\t\t\tupdateProgressWidth(root);\n\t\t\t\t\t}\n\t\t\t\t\tif (root && typeof root.querySelectorAll === 'function') {\n\t\t\t\t\t\tfor (const progressBar of root.querySelectorAll('[role=\"progressbar\"]')) {\n\t\t\t\t\t\t\tupdateProgressWidth(progressBar);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst handleHtmxSwap = (event) => {\n\t\t\t\t\tconst target = event.detail.target || event.detail.elt;\n\t\t\t\t\tif (target instanceof Element) {\n\t\t\t\t\t\trequestAnimationFrame(() => initAllComponents(target));\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tinitAllComponents();\n\t\t\t\tdocument.addEventListener('DOMContentLoaded', () => initAllComponents());\n\t\t\t\tdocument.body.addEventListener('htmx:afterSwap', handleHtmxSwap);\n\t\t\t\tdocument.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);\n\t\t\t})(); // IIFE End\n\t\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = handle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var16), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,54 @@
// templui component radio - version: main installed by templui v0.71.0
package radio
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Props struct {
ID string
Class string
Attributes templ.Attributes
Name string
Value string
Disabled bool
Required bool
Checked bool
}
templ Radio(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<input
type="radio"
if p.ID != "" {
id={ p.ID }
}
if p.Name != "" {
name={ p.Name }
}
if p.Value != "" {
value={ p.Value }
}
checked?={ p.Checked }
disabled?={ p.Disabled }
required?={ p.Required }
class={
utils.TwMerge(
"relative h-4 w-4",
"before:absolute before:left-1/2 before:top-1/2",
"before:h-1.5 before:w-1.5 before:-translate-x-1/2 before:-translate-y-1/2",
"appearance-none rounded-full",
"border-2 border-primary",
"before:content[''] before:rounded-full before:bg-background",
"checked:border-primary checked:bg-primary",
"checked:before:visible",
"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
"focus-visible:ring-offset-2 focus-visible:ring-offset-background",
"disabled:cursor-not-allowed",
p.Class,
),
}
{ p.Attributes... }
/>
}

View file

@ -0,0 +1,179 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component radio - version: main installed by templui v0.71.0
package radio
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Props struct {
ID string
Class string
Attributes templ.Attributes
Name string
Value string
Disabled bool
Required bool
Checked bool
}
func Radio(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"relative h-4 w-4",
"before:absolute before:left-1/2 before:top-1/2",
"before:h-1.5 before:w-1.5 before:-translate-x-1/2 before:-translate-y-1/2",
"appearance-none rounded-full",
"border-2 border-primary",
"before:content[''] before:rounded-full before:bg-background",
"checked:border-primary checked:bg-primary",
"checked:before:visible",
"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
"focus-visible:ring-offset-2 focus-visible:ring-offset-background",
"disabled:cursor-not-allowed",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<input type=\"radio\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radio/radio.templ`, Line: 25, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Name != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " name=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(p.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radio/radio.templ`, Line: 28, Col: 16}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Value != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(p.Value)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radio/radio.templ`, Line: 31, Col: 18}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Checked {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, " checked")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Disabled {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " disabled")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Required {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " required")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radio/radio.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,135 @@
// templui component radiocard - version: main installed by templui v0.71.0
package radiocard
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Props struct {
ID string
Class string
Attributes templ.Attributes
Name string
Value string
Checked bool
Disabled bool
Required bool
}
type HeaderProps struct {
ID string
Class string
Attributes templ.Attributes
}
type DescriptionProps struct {
ID string
Class string
Attributes templ.Attributes
}
type FooterProps struct {
ID string
Class string
Attributes templ.Attributes
}
templ RadioCard(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.ID == "" {
{{ p.ID = utils.RandomID() }}
}
<div
id={ p.ID + "-container" }
class={
utils.TwMerge(
"relative",
utils.If(p.Disabled, "opacity-60"),
p.Class,
),
}
{ p.Attributes... }
>
<input
type="radio"
id={ p.ID }
if p.Name != "" {
name={ p.Name }
}
if p.Value != "" {
value={ p.Value }
}
checked?={ p.Checked }
disabled?={ p.Disabled }
required?={ p.Required }
class="peer sr-only"
/>
<label
for={ p.ID }
class={
utils.TwMerge(
"block w-full rounded-lg border overflow-hidden h-full",
"bg-card text-card-foreground p-4 flex flex-col",
"cursor-pointer",
"hover:border-primary/50",
"peer-checked:ring-1 peer-checked:ring-primary peer-checked:border-primary",
utils.If(p.Disabled, "cursor-not-allowed"),
"transition-all duration-200",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</label>
</div>
}
templ Header(props ...HeaderProps) {
{{ var p HeaderProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("flex items-center justify-between mb-2", p.Class) }
{ p.Attributes... }
>
{ children... }
</div>
}
templ Description(props ...DescriptionProps) {
{{ var p DescriptionProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<p
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("text-sm text-muted-foreground", p.Class) }
{ p.Attributes... }
>
{ children... }
</p>
}
templ Footer(props ...FooterProps) {
{{ var p FooterProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("mt-auto pt-4 w-full", p.Class) }
{ p.Attributes... }
>
{ children... }
</div>
}

View file

@ -0,0 +1,530 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component radiocard - version: main installed by templui v0.71.0
package radiocard
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Props struct {
ID string
Class string
Attributes templ.Attributes
Name string
Value string
Checked bool
Disabled bool
Required bool
}
type HeaderProps struct {
ID string
Class string
Attributes templ.Attributes
}
type DescriptionProps struct {
ID string
Class string
Attributes templ.Attributes
}
type FooterProps struct {
ID string
Class string
Attributes templ.Attributes
}
func RadioCard(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
if p.ID == "" {
p.ID = utils.RandomID()
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"relative",
utils.If(p.Disabled, "opacity-60"),
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID + "-container")
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radiocard/radio_card.templ`, Line: 44, Col: 26}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radiocard/radio_card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "><input type=\"radio\" id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radiocard/radio_card.templ`, Line: 56, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Name != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " name=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(p.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radiocard/radio_card.templ`, Line: 58, Col: 17}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Value != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, " value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(p.Value)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radiocard/radio_card.templ`, Line: 61, Col: 19}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Checked {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " checked")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Disabled {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " disabled")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Required {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " required")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, " class=\"peer sr-only\"> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 = []any{
utils.TwMerge(
"block w-full rounded-lg border overflow-hidden h-full",
"bg-card text-card-foreground p-4 flex flex-col",
"cursor-pointer",
"hover:border-primary/50",
"peer-checked:ring-1 peer-checked:ring-primary peer-checked:border-primary",
utils.If(p.Disabled, "cursor-not-allowed"),
"transition-all duration-200",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<label for=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radiocard/radio_card.templ`, Line: 69, Col: 13}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var8).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radiocard/radio_card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</label></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Header(props ...HeaderProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var11 := templ.GetChildren(ctx)
if templ_7745c5c3_Var11 == nil {
templ_7745c5c3_Var11 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p HeaderProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var12 = []any{utils.TwMerge("flex items-center justify-between mb-2", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radiocard/radio_card.templ`, Line: 96, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var12).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radiocard/radio_card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var11.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Description(props ...DescriptionProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var15 := templ.GetChildren(ctx)
if templ_7745c5c3_Var15 == nil {
templ_7745c5c3_Var15 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p DescriptionProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var16 = []any{utils.TwMerge("text-sm text-muted-foreground", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "<p")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radiocard/radio_card.templ`, Line: 112, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var16).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radiocard/radio_card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var15.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "</p>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Footer(props ...FooterProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var19 := templ.GetChildren(ctx)
if templ_7745c5c3_Var19 == nil {
templ_7745c5c3_Var19 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p FooterProps
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var20 = []any{utils.TwMerge("mt-auto pt-4 w-full", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var21 string
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radiocard/radio_card.templ`, Line: 128, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var22 string
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var20).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/radiocard/radio_card.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var19.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,426 @@
// templui component rating - version: main installed by templui v0.71.0
package rating
import (
"fmt"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
"strconv"
)
type Style string
const (
StyleStar Style = "star"
StyleHeart Style = "heart"
StyleEmoji Style = "emoji"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Value float64
ReadOnly bool
Precision float64
Name string
OnlyInteger bool
}
type GroupProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ItemProps struct {
ID string
Class string
Attributes templ.Attributes
Value int
Style Style
}
templ Rating(props ...Props) {
@Script()
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
{{ p.setDefaults() }}
<div
if p.ID != "" {
id={ p.ID }
}
data-rating-component
data-initial-value={ fmt.Sprintf("%.2f", p.Value) }
data-precision={ fmt.Sprintf("%.2f", p.Precision) }
data-readonly={ strconv.FormatBool(p.ReadOnly) }
if p.Name != "" {
data-name={ p.Name }
}
data-onlyinteger={ strconv.FormatBool(p.OnlyInteger) }
class={
utils.TwMerge(
"flex flex-col items-start gap-1",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
if p.Name != "" {
<input
type="hidden"
name={ p.Name }
value={ fmt.Sprintf("%.2f", p.Value) }
data-rating-input
/>
}
</div>
}
templ Group(props ...GroupProps) {
{{ var p GroupProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("flex flex-row items-center gap-1", p.Class) }
{ p.Attributes... }
>
{ children... }
</div>
}
templ Item(props ...ItemProps) {
{{ var p ItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
{{ p.setDefaults() }}
<div
if p.ID != "" {
id={ p.ID }
}
data-rating-item
data-rating-value={ strconv.Itoa(p.Value) }
class={
utils.TwMerge(
"relative",
colorClass(p.Style),
"transition-opacity",
"cursor-pointer", // Default cursor
p.Class,
),
}
{ p.Attributes... }
>
<div class="opacity-30">
@ratingIcon(p.Style, false, float64(p.Value))
</div>
<div
class="absolute inset-0 overflow-hidden w-0"
data-rating-item-foreground
>
@ratingIcon(p.Style, true, float64(p.Value))
</div>
</div>
}
func colorClass(style Style) string {
switch style {
case StyleHeart:
return "text-destructive"
case StyleEmoji:
return "text-yellow-500"
default:
return "text-yellow-400"
}
}
func ratingIcon(style Style, filled bool, value float64) templ.Component {
if style == StyleEmoji {
if filled {
switch {
case value <= 1:
return icon.Angry()
case value <= 2:
return icon.Frown()
case value <= 3:
return icon.Meh()
case value <= 4:
return icon.Smile()
default:
return icon.Laugh()
}
}
return icon.Meh()
}
iconProps := icon.Props{}
if filled {
iconProps.Fill = "currentColor"
}
switch style {
case StyleHeart:
return icon.Heart(iconProps)
default:
return icon.Star(iconProps)
}
}
func (p *ItemProps) setDefaults() {
if p.Style == "" {
p.Style = StyleStar
}
}
func (p *Props) setDefaults() {
if p.Precision <= 0 {
p.Precision = 1.0
}
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<script nonce={ templ.GetNonce(ctx) }>
if (typeof window.ratingState === 'undefined') {
window.ratingState = new WeakMap();
}
(function() { // IIFE
function initRating(ratingElement) {
if (!ratingElement) return;
const existingState = window.ratingState.get(ratingElement);
if (existingState) {
cleanupRating(ratingElement, existingState);
}
ratingElement.dataset.ratingInitialized = 'true';
const config = {
value: parseFloat(ratingElement.dataset.initialValue) || 0,
precision: parseFloat(ratingElement.dataset.precision) || 1,
readonly: ratingElement.dataset.readonly === 'true',
name: ratingElement.dataset.name || '',
onlyInteger: ratingElement.dataset.onlyinteger === 'true',
maxValue: 0
};
const hiddenInput = ratingElement.querySelector('[data-rating-input]');
let items = Array.from(ratingElement.querySelectorAll('[data-rating-item]'));
let currentValue = config.value;
let previewValue = 0;
const handlers = {
click: handleClick,
mouseover: handleMouseOver,
mouseleave: handleMouseLeave
};
function calculateMaxValue() {
let highestValue = 0;
for (const item of items) {
const value = parseInt(item.dataset.ratingValue, 10);
if (!isNaN(value) && value > highestValue) {
highestValue = value;
}
}
config.maxValue = Math.max(1, highestValue);
currentValue = Math.max(0, Math.min(config.maxValue, currentValue));
currentValue = Math.round(currentValue / config.precision) * config.precision;
updateHiddenInput();
}
function updateHiddenInput() {
if (hiddenInput) {
hiddenInput.value = currentValue.toFixed(2);
}
}
function updateItemStyles(displayValue) {
for (const item of items) {
const itemValue = parseInt(item.dataset.ratingValue, 10);
if (isNaN(itemValue)) continue;
const foreground = item.querySelector('[data-rating-item-foreground]');
if (!foreground) continue;
const valueToCompare = displayValue > 0 ? displayValue : currentValue;
const filled = itemValue <= Math.floor(valueToCompare);
const partial = !filled && (itemValue - 1 < valueToCompare && valueToCompare < itemValue);
const percentage = partial ? (valueToCompare - Math.floor(valueToCompare)) * 100 : 0;
foreground.style.width = filled ? '100%' : (partial ? `${percentage}%` : '0%');
}
}
function setValue(itemValue) {
if (config.readonly) return;
let newValue = itemValue;
if (config.onlyInteger) {
newValue = Math.round(newValue);
} else {
if (currentValue === newValue && newValue % 1 === 0) {
newValue = Math.max(0, newValue - config.precision);
} else {
newValue = Math.round(newValue / config.precision) * config.precision;
}
}
currentValue = Math.max(0, Math.min(config.maxValue, newValue));
previewValue = 0;
updateHiddenInput();
updateItemStyles(0);
ratingElement.dispatchEvent(new CustomEvent('rating-change', {
bubbles: true,
detail: {
name: config.name,
value: currentValue,
maxValue: config.maxValue
}
}));
if (hiddenInput) {
hiddenInput.dispatchEvent(new Event('input', { bubbles: true }));
hiddenInput.dispatchEvent(new Event('change', { bubbles: true }));
}
}
function handleMouseOver(event) {
if (config.readonly) return;
const item = event.target.closest('[data-rating-item]');
if (!item) return;
previewValue = parseInt(item.dataset.ratingValue, 10);
if (!isNaN(previewValue)) {
updateItemStyles(previewValue);
}
}
function handleMouseLeave() {
if (config.readonly) return;
previewValue = 0;
updateItemStyles(0);
}
function handleClick(event) {
if (config.readonly) return;
const item = event.target.closest('[data-rating-item]');
if (!item) return;
const itemValue = parseInt(item.dataset.ratingValue, 10);
if (!isNaN(itemValue)) {
setValue(itemValue);
}
}
calculateMaxValue();
updateItemStyles(0);
if (config.readonly) {
ratingElement.style.cursor = 'default';
for (const item of items) {
item.style.cursor = 'default';
}
} else {
ratingElement.addEventListener('click', handlers.click);
ratingElement.addEventListener('mouseover', handlers.mouseover);
ratingElement.addEventListener('mouseleave', handlers.mouseleave);
}
const observer = new MutationObserver(() => {
try {
const currentItemCount = ratingElement.querySelectorAll('[data-rating-item]').length;
if (currentItemCount !== items.length) {
items = Array.from(ratingElement.querySelectorAll('[data-rating-item]'));
calculateMaxValue();
updateItemStyles(previewValue > 0 ? previewValue : 0);
}
} catch (err) {
console.error('Error in rating MutationObserver:', err);
}
});
observer.observe(ratingElement, { childList: true, subtree: true });
const state = {
handlers,
observer,
items
};
window.ratingState.set(ratingElement, state);
}
function cleanupRating(ratingElement, state) {
if (!ratingElement || !state) return;
if (!ratingElement.dataset.readonly === 'true') {
ratingElement.removeEventListener('click', state.handlers.click);
ratingElement.removeEventListener('mouseover', state.handlers.mouseover);
ratingElement.removeEventListener('mouseleave', state.handlers.mouseleave);
}
if (state.observer) {
state.observer.disconnect();
}
window.ratingState.delete(ratingElement);
ratingElement.removeAttribute('data-rating-initialized');
}
function initAllComponents(root = document) {
if (root instanceof Element && root.matches('[data-rating-component]')) {
initRating(root); // initRating handles already initialized check internally
}
if (root && typeof root.querySelectorAll === 'function') {
root.querySelectorAll('[data-rating-component]').forEach(initRating);
}
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:beforeCleanup', event => {
const containerToRemove = event.detail.target || event.detail.elt;; // Use elt for beforeCleanup
if (containerToRemove instanceof Element) {
// Cleanup target itself
if (containerToRemove.matches && containerToRemove.matches('[data-rating-component][data-rating-initialized]')) {
const state = window.ratingState.get(containerToRemove);
if (state) cleanupRating(containerToRemove, state);
}
// Cleanup descendants
if (containerToRemove.querySelectorAll) {
for (const ratingEl of containerToRemove.querySelectorAll('[data-rating-component][data-rating-initialized]')) {
const state = window.ratingState.get(ratingEl);
if (state) cleanupRating(ratingEl, state);
}
}
}
});
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})(); // End of IIFE
</script>
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,419 @@
// templui component selectbox - version: main installed by templui v0.71.0
package selectbox
import (
"context"
"fmt"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
"git.jmbit.de/jmb/scanfile/server/web/templui/components/popover"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
"strconv"
)
type contextKey string
var contentIDKey contextKey = "contentID"
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
type TriggerProps struct {
ID string
Class string
Attributes templ.Attributes
Name string
Required bool
Disabled bool
HasError bool
}
type ValueProps struct {
ID string
Class string
Attributes templ.Attributes
Placeholder string
}
type ContentProps struct {
ID string
Class string
Attributes templ.Attributes
}
type GroupProps struct {
ID string
Class string
Attributes templ.Attributes
}
type LabelProps struct {
ID string
Class string
Attributes templ.Attributes
}
type ItemProps struct {
ID string
Class string
Attributes templ.Attributes
Value string
Selected bool
Disabled bool
}
templ SelectBox(props ...Props) {
@Script()
{{
var p Props
if len(props) > 0 {
p = props[0]
}
wrapperID := p.ID
if wrapperID == "" {
wrapperID = utils.RandomID()
}
contentID := fmt.Sprintf("%s-content", wrapperID)
ctx = context.WithValue(ctx, contentIDKey, contentID)
}}
<div
id={ wrapperID }
class={ utils.TwMerge("select-container w-full relative", p.Class) }
{ p.Attributes... }
>
@popover.Popover() {
{ children... }
}
</div>
}
templ Trigger(props ...TriggerProps) {
{{
var p TriggerProps
if len(props) > 0 {
p = props[0]
}
contentID, ok := ctx.Value(contentIDKey).(string)
if !ok {
contentID = "fallback-select-content-id"
}
}}
@popover.Trigger(popover.TriggerProps{
For: contentID,
TriggerType: popover.TriggerTypeClick,
}) {
@button.Button(button.Props{
ID: p.ID,
Type: "button",
Variant: button.VariantOutline,
Class: utils.TwMerge(
"w-full select-trigger flex items-center justify-between focus:ring-2 focus:ring-offset-2",
utils.If(p.HasError, "border-destructive ring-destructive"),
p.Class,
),
Disabled: p.Disabled,
Attributes: utils.MergeAttributes(
templ.Attributes{
"data-content-id": contentID,
"tabindex": "0",
"required": strconv.FormatBool(p.Required),
},
p.Attributes,
),
}) {
<input
type="hidden"
if p.Name != "" {
name={ p.Name }
}
required?={ p.Required }
/>
{ children... }
<span class="pointer-events-none ml-1">
@icon.ChevronDown(icon.Props{
Size: 16,
Class: "text-muted-foreground",
})
</span>
}
}
}
templ Value(props ...ValueProps) {
{{ var p ValueProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("block truncate select-value text-muted-foreground", p.Class) }
{ p.Attributes... }
>
if p.Placeholder != "" {
{ p.Placeholder }
}
{ children... }
</span>
}
templ Content(props ...ContentProps) {
{{
var p ContentProps
if len(props) > 0 {
p = props[0]
}
contentID, ok := ctx.Value(contentIDKey).(string)
if !ok {
contentID = "fallback-select-content-id"
}
}}
@popover.Content(popover.ContentProps{
ID: contentID,
Placement: popover.PlacementBottomStart,
Offset: 4,
MatchWidth: true,
Class: utils.TwMerge(
"p-1 select-content z-50 overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md",
"min-w-[var(--popover-trigger-width)] w-[var(--popover-trigger-width)]",
p.Class,
),
Attributes: utils.MergeAttributes(
templ.Attributes{
"role": "listbox",
"tabindex": "-1",
},
p.Attributes,
),
}) {
{ children... }
}
}
templ Group(props ...GroupProps) {
{{ var p GroupProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("p-1", p.Class) }
role="group"
{ p.Attributes... }
>
{ children... }
</div>
}
templ Label(props ...LabelProps) {
{{ var p LabelProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<span
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("px-2 py-1.5 text-sm font-medium", p.Class) }
{ p.Attributes... }
>
{ children... }
</span>
}
templ Item(props ...ItemProps) {
{{ var p ItemProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"select-item relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 px-2 text-sm font-light outline-none",
"hover:bg-accent hover:text-accent-foreground",
"focus:bg-accent focus:text-accent-foreground",
utils.If(p.Selected, "bg-accent text-accent-foreground"),
utils.If(p.Disabled, "pointer-events-none opacity-50"),
p.Class,
),
}
role="option"
data-value={ p.Value }
data-selected={ strconv.FormatBool(p.Selected) }
data-disabled={ strconv.FormatBool(p.Disabled) }
tabindex="0"
{ p.Attributes... }
>
<span class="truncate select-item-text">
{ children... }
</span>
<span
class={
utils.TwMerge(
"select-check absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
utils.IfElse(p.Selected, "opacity-100", "opacity-0"),
),
}
>
@icon.Check(icon.Props{Size: 16})
</span>
</div>
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<script defer nonce={ templ.GetNonce(ctx) }>
(function() { // IIFE
function initSelect(wrapper) {
if (!wrapper || wrapper.hasAttribute('data-initialized')) return;
wrapper.setAttribute('data-initialized', 'true');
const triggerButton = wrapper.querySelector('button.select-trigger');
if (!triggerButton) {
console.error("Select box: Trigger button (.select-trigger) not found in wrapper", wrapper);
return;
}
const contentID = triggerButton.dataset.contentId;
const content = contentID ? document.getElementById(contentID) : null;
const valueEl = triggerButton.querySelector('.select-value');
const hiddenInput = triggerButton.querySelector('input[type="hidden"]');
if (!content || !valueEl || !hiddenInput) {
console.error("Select box: Missing required elements for initialization.", { wrapper, contentID, contentExists: !!content, valueElExists: !!valueEl, hiddenInputExists: !!hiddenInput });
return;
}
// Initialize display value if an item is pre-selected
const selectedItem = content.querySelector('.select-item[data-selected="true"]');
if (selectedItem) {
const itemText = selectedItem.querySelector('.select-item-text');
if (itemText) {
valueEl.textContent = itemText.textContent;
valueEl.classList.remove('text-muted-foreground');
}
if (hiddenInput) {
hiddenInput.value = selectedItem.getAttribute('data-value') || '';
}
}
// Reset visual state of items
function resetItemStyles() {
content.querySelectorAll('.select-item').forEach(item => {
if (item.getAttribute('data-selected') === 'true') {
item.classList.add('bg-accent', 'text-accent-foreground');
item.classList.remove('bg-muted');
} else {
item.classList.remove('bg-accent', 'text-accent-foreground', 'bg-muted');
}
});
}
// Select an item
function selectItem(item) {
if (!item || item.getAttribute('data-disabled') === 'true') return;
const value = item.getAttribute('data-value');
const itemText = item.querySelector('.select-item-text');
// Reset all items in this content
content.querySelectorAll('.select-item').forEach(el => {
el.setAttribute('data-selected', 'false');
el.classList.remove('bg-accent', 'text-accent-foreground', 'bg-muted');
const check = el.querySelector('.select-check');
if (check) check.classList.replace('opacity-100', 'opacity-0');
});
// Mark new selection
item.setAttribute('data-selected', 'true');
item.classList.add('bg-accent', 'text-accent-foreground');
const check = item.querySelector('.select-check');
if (check) check.classList.replace('opacity-0', 'opacity-100');
// Update display value
if (valueEl && itemText) { // Check if valueEl exists
valueEl.textContent = itemText.textContent;
valueEl.classList.remove('text-muted-foreground');
}
// Update hidden input & trigger change event
if (hiddenInput && value !== null) { // Check if hiddenInput exists
hiddenInput.value = value;
hiddenInput.dispatchEvent(new Event('change', { bubbles: true }));
}
// Close the popover using the correct contentID
if (window.closePopover) {
window.closePopover(contentID, true);
} else {
console.warn("closePopover function not found");
}
}
// Event Listeners for Items (delegated from content for robustness)
content.addEventListener('click', (e) => {
const item = e.target.closest('.select-item');
if (item) selectItem(item);
});
content.addEventListener('keydown', (e) => {
const item = e.target.closest('.select-item');
if (item && (e.key === 'Enter' || e.key === ' ')) {
e.preventDefault();
selectItem(item);
}
// Add other keyboard navigation (Up/Down/Home/End) if desired
});
// Event: Mouse hover on items (delegated)
content.addEventListener('mouseover', e => {
const item = e.target.closest('.select-item');
if (!item || item.getAttribute('data-disabled') === 'true') return;
// Reset all others first
content.querySelectorAll('.select-item').forEach(el => {
el.classList.remove('bg-accent', 'text-accent-foreground', 'bg-muted');
});
// Apply hover style only if not selected
if (item.getAttribute('data-selected') !== 'true') {
item.classList.add('bg-accent', 'text-accent-foreground');
}
});
// Reset hover styles when mouse leaves the content area
content.addEventListener('mouseleave', resetItemStyles);
}
function initAllComponents(root = document) {
const containers = root.querySelectorAll('.select-container:not([data-initialized])');
if (root instanceof Element && root.matches('.select-container') && !root.hasAttribute('data-initialized')) {
initSelect(root);
} else {
containers.forEach(initSelect);
}
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})(); // End of IIFE
</script>
}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,97 @@
// templui component separator - version: main installed by templui v0.71.0
package separator
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Orientation string
type Decoration string
const (
OrientationHorizontal Orientation = "horizontal"
OrientationVertical Orientation = "vertical"
)
const (
DecorationDashed Decoration = "dashed"
DecorationDotted Decoration = "dotted"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Orientation Orientation
Decoration Decoration
}
templ Separator(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.Orientation == "" {
{{ p.Orientation = OrientationHorizontal }}
}
if p.Orientation == OrientationHorizontal {
<div
if p.ID != "" {
id={ p.ID }
}
role="separator"
aria-orientation="horizontal"
class={ utils.TwMerge("shrink-0 w-full", p.Class) }
{ p.Attributes... }
>
<div class="relative flex items-center w-full">
<span
class={
utils.TwMerge(
"absolute w-full border-t h-[1px]",
decorationClasses(p.Decoration),
),
}
aria-hidden="true"
></span>
<span class="relative mx-auto bg-background px-2 text-xs text-muted-foreground">
{ children... }
</span>
</div>
</div>
} else {
<div
if p.ID != "" {
id={ p.ID }
}
role="separator"
aria-orientation="vertical"
class={ utils.TwMerge("shrink-0 h-full", p.Class) }
{ p.Attributes... }
>
<div class="relative flex flex-col items-center h-full">
<span
class={
utils.TwMerge(
"absolute h-full border-l w-[1px]",
decorationClasses(p.Decoration),
),
}
aria-hidden="true"
></span>
<span class="relative my-auto bg-background py-2 text-xs text-muted-foreground">
{ children... }
</span>
</div>
</div>
}
}
func decorationClasses(decoration Decoration) string {
switch decoration {
case DecorationDashed:
return "border-dashed"
case DecorationDotted:
return "border-dotted"
default:
return ""
}
}

View file

@ -0,0 +1,258 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component separator - version: main installed by templui v0.71.0
package separator
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Orientation string
type Decoration string
const (
OrientationHorizontal Orientation = "horizontal"
OrientationVertical Orientation = "vertical"
)
const (
DecorationDashed Decoration = "dashed"
DecorationDotted Decoration = "dotted"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Orientation Orientation
Decoration Decoration
}
func Separator(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
if p.Orientation == "" {
p.Orientation = OrientationHorizontal
}
if p.Orientation == OrientationHorizontal {
var templ_7745c5c3_Var2 = []any{utils.TwMerge("shrink-0 w-full", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/separator/separator.templ`, Line: 38, Col: 13}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " role=\"separator\" aria-orientation=\"horizontal\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/separator/separator.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "><div class=\"relative flex items-center w-full\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 = []any{
utils.TwMerge(
"absolute w-full border-t h-[1px]",
decorationClasses(p.Decoration),
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "<span class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var5).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/separator/separator.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\" aria-hidden=\"true\"></span> <span class=\"relative mx-auto bg-background px-2 text-xs text-muted-foreground\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</span></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
var templ_7745c5c3_Var7 = []any{utils.TwMerge("shrink-0 h-full", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/separator/separator.templ`, Line: 63, Col: 13}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, " role=\"separator\" aria-orientation=\"vertical\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var7).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/separator/separator.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "><div class=\"relative flex flex-col items-center h-full\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 = []any{
utils.TwMerge(
"absolute h-full border-l w-[1px]",
decorationClasses(p.Decoration),
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<span class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var10).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/separator/separator.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\" aria-hidden=\"true\"></span> <span class=\"relative my-auto bg-background py-2 text-xs text-muted-foreground\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</span></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
return nil
})
}
func decorationClasses(decoration Decoration) string {
switch decoration {
case DecorationDashed:
return "border-dashed"
case DecorationDotted:
return "border-dotted"
default:
return ""
}
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,29 @@
// templui component skeleton - version: main installed by templui v0.71.0
package skeleton
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
templ Skeleton(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"animate-pulse rounded bg-muted",
p.Class,
),
}
{ p.Attributes... }
></div>
}

View file

@ -0,0 +1,108 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component skeleton - version: main installed by templui v0.71.0
package skeleton
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
func Skeleton(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"animate-pulse rounded bg-muted",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/skeleton/skeleton.templ`, Line: 19, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/skeleton/skeleton.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,168 @@
// templui component slider - version: main installed by templui v0.71.0
package slider
import (
"fmt"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
type InputProps struct {
ID string
Class string
Attributes templ.Attributes
Name string
Min int
Max int
Step int
Value int
Disabled bool
}
type ValueProps struct {
ID string
Class string
Attributes templ.Attributes
For string // Corresponds to the ID of the Slider Input
}
templ Slider(props ...Props) {
@Script()
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("w-full", p.Class) }
data-slider-wrapper
{ p.Attributes... }
>
{ children... }
</div>
}
templ Input(props ...InputProps) {
{{ var p InputProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.ID == "" {
{{ p.ID = utils.RandomID() }}
}
<input
type="range"
id={ p.ID }
data-slider-input
if p.Name != "" {
name={ p.Name }
}
if p.Value != 0 {
value={ fmt.Sprintf("%d", p.Value) }
}
if p.Min != 0 {
min={ fmt.Sprintf("%d", p.Min) }
}
if p.Max != 0 {
max={ fmt.Sprintf("%d", p.Max) }
}
if p.Step != 0 {
step={ fmt.Sprintf("%d", p.Step) }
}
class={
utils.TwMerge(
"w-full h-2 rounded-full bg-secondary appearance-none cursor-pointer",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-primary",
"[&::-webkit-slider-thumb]:hover:bg-primary/90",
"[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4 [&::-moz-range-thumb]:border-0",
"[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-primary",
"[&::-moz-range-thumb]:hover:bg-primary/90",
"disabled:opacity-50 disabled:cursor-not-allowed",
p.Class,
),
}
disabled?={ p.Disabled }
{ p.Attributes... }
/>
}
templ Value(props ...ValueProps) {
{{ var p ValueProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
if p.For == "" {
<span class="text-xs text-destructive">Error: SliderValue missing 'For' attribute.</span>
}
<span
if p.ID != "" {
id={ p.ID }
}
data-slider-value
data-slider-value-for={ p.For }
class={ utils.TwMerge("text-sm text-muted-foreground", p.Class) }
{ p.Attributes... }
>
<!-- Initial value will be set by JS -->
</span>
}
var handle = templ.NewOnceHandle()
templ Script() {
@handle.Once() {
<script defer nonce={ templ.GetNonce(ctx) }>
(function() { // IIFE
function initSlider(sliderInput) {
if (sliderInput.hasAttribute('data-initialized')) return;
sliderInput.setAttribute('data-initialized', 'true');
const sliderId = sliderInput.id;
if (!sliderId) return;
const valueElements = document.querySelectorAll(`[data-slider-value][data-slider-value-for="${sliderId}"]`);
function updateValues() {
valueElements.forEach(el => {
el.textContent = sliderInput.value;
});
}
updateValues();
sliderInput.addEventListener('input', updateValues);
}
function initAllComponents(root = document) {
if (root instanceof Element && root.matches('input[type="range"][data-slider-input]')) {
initSlider(root);
}
for (const slider of root.querySelectorAll('input[type="range"][data-slider-input]:not([data-initialized])')) {
initSlider(slider);
}
}
const handleHtmxSwap = (event) => {
const target = event.detail.target || event.detail.elt;
if (target instanceof Element) {
requestAnimationFrame(() => initAllComponents(target));
}
};
initAllComponents();
document.addEventListener('DOMContentLoaded', () => initAllComponents());
document.body.addEventListener('htmx:afterSwap', handleHtmxSwap);
document.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);
})(); // End of IIFE
</script>
}
}

View file

@ -0,0 +1,493 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component slider - version: main installed by templui v0.71.0
package slider
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"fmt"
"git.jmbit.de/jmb/scanfile/server/web/templui/utils"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
type InputProps struct {
ID string
Class string
Attributes templ.Attributes
Name string
Min int
Max int
Step int
Value int
Disabled bool
}
type ValueProps struct {
ID string
Class string
Attributes templ.Attributes
For string // Corresponds to the ID of the Slider Input
}
func Slider(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = Script().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{utils.TwMerge("w-full", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/slider/slider.templ`, Line: 42, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/slider/slider.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" data-slider-wrapper")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Input(props ...InputProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
if templ_7745c5c3_Var5 == nil {
templ_7745c5c3_Var5 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p InputProps
if len(props) > 0 {
p = props[0]
}
if p.ID == "" {
p.ID = utils.RandomID()
}
var templ_7745c5c3_Var6 = []any{
utils.TwMerge(
"w-full h-2 rounded-full bg-secondary appearance-none cursor-pointer",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-primary",
"[&::-webkit-slider-thumb]:hover:bg-primary/90",
"[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4 [&::-moz-range-thumb]:border-0",
"[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-primary",
"[&::-moz-range-thumb]:hover:bg-primary/90",
"disabled:opacity-50 disabled:cursor-not-allowed",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<input type=\"range\" id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/slider/slider.templ`, Line: 62, Col: 11}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\" data-slider-input")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Name != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " name=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(p.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/slider/slider.templ`, Line: 65, Col: 16}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Value != 0 {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " value=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", p.Value))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/slider/slider.templ`, Line: 68, Col: 37}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Min != 0 {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, " min=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", p.Min))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/slider/slider.templ`, Line: 71, Col: 33}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Max != 0 {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, " max=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", p.Max))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/slider/slider.templ`, Line: 74, Col: 33}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if p.Step != 0 {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " step=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", p.Step))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/slider/slider.templ`, Line: 77, Col: 35}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/slider/slider.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.Disabled {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, " disabled")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func Value(props ...ValueProps) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var14 := templ.GetChildren(ctx)
if templ_7745c5c3_Var14 == nil {
templ_7745c5c3_Var14 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p ValueProps
if len(props) > 0 {
p = props[0]
}
if p.For == "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "<span class=\"text-xs text-destructive\">Error: SliderValue missing 'For' attribute.</span> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
var templ_7745c5c3_Var15 = []any{utils.TwMerge("text-sm text-muted-foreground", p.Class)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var15...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<span")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/slider/slider.templ`, Line: 108, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, " data-slider-value data-slider-value-for=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(p.For)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/slider/slider.templ`, Line: 111, Col: 31}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var15).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/slider/slider.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "><!-- Initial value will be set by JS --></span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var handle = templ.NewOnceHandle()
func Script() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var19 := templ.GetChildren(ctx)
if templ_7745c5c3_Var19 == nil {
templ_7745c5c3_Var19 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Var20 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "<script defer nonce=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var21 string
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(templ.GetNonce(ctx))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/slider/slider.templ`, Line: 123, Col: 43}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "\">\n\t\t\t(function() { // IIFE\n\t\t\t\tfunction initSlider(sliderInput) {\n\t\t\t\t\tif (sliderInput.hasAttribute('data-initialized')) return;\n\t\t\t\t\t\n\t\t\t\t\tsliderInput.setAttribute('data-initialized', 'true');\n\n\t\t\t\t\tconst sliderId = sliderInput.id;\n\t\t\t\t\tif (!sliderId) return;\n\n\t\t\t\t\tconst valueElements = document.querySelectorAll(`[data-slider-value][data-slider-value-for=\"${sliderId}\"]`);\n\t\t\t\t\t\n\t\t\t\t\tfunction updateValues() {\n\t\t\t\t\t\tvalueElements.forEach(el => {\n\t\t\t\t\t\t\tel.textContent = sliderInput.value;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tupdateValues(); \n\t\t\t\t\tsliderInput.addEventListener('input', updateValues);\n\t\t\t\t}\n\n\t\t\t\tfunction initAllComponents(root = document) {\n\t\t\t\t\tif (root instanceof Element && root.matches('input[type=\"range\"][data-slider-input]')) {\n\t\t\t\t\t\tinitSlider(root);\n\t\t\t\t\t}\n\t\t\t\t\tfor (const slider of root.querySelectorAll('input[type=\"range\"][data-slider-input]:not([data-initialized])')) {\n\t\t\t\t\t\tinitSlider(slider);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst handleHtmxSwap = (event) => {\n\t\t\t\t\tconst target = event.detail.target || event.detail.elt;\n\t\t\t\t\tif (target instanceof Element) {\n\t\t\t\t\t\trequestAnimationFrame(() => initAllComponents(target));\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tinitAllComponents();\n\t\t\t\tdocument.addEventListener('DOMContentLoaded', () => initAllComponents());\n\t\t\t\tdocument.body.addEventListener('htmx:afterSwap', handleHtmxSwap);\n\t\t\t\tdocument.body.addEventListener('htmx:oobAfterSwap', handleHtmxSwap);\n\t\t\t})(); // End of IIFE\n\t\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = handle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var20), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,83 @@
// templui component spinner - version: main installed by templui v0.71.0
package spinner
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Size string
const (
SizeSm Size = "sm"
SizeMd Size = "md"
SizeLg Size = "lg"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Size Size
Color string
}
templ Spinner(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"inline-flex flex-col items-center justify-center",
p.Class,
),
}
aria-label="Loading"
role="status"
{ p.Attributes... }
>
<div
class={
utils.TwMerge(
"animate-spin rounded-full",
sizeClass(p.Size),
borderSizeClass(p.Size),
utils.IfElse(
p.Color == "",
"border-primary border-b-transparent",
"border-current border-b-transparent",
),
utils.IfElse(
p.Color != "",
p.Color,
"",
),
),
}
></div>
</div>
}
func sizeClass(size Size) string {
switch size {
case SizeSm:
return "w-6 h-6"
case SizeLg:
return "w-12 h-12"
default:
return "w-8 h-8"
}
}
func borderSizeClass(size Size) string {
switch size {
case SizeSm:
return "border-[3px]"
case SizeLg:
return "border-[5px]"
default:
return "border-4"
}
}

View file

@ -0,0 +1,178 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component spinner - version: main installed by templui v0.71.0
package spinner
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Size string
const (
SizeSm Size = "sm"
SizeMd Size = "md"
SizeLg Size = "lg"
)
type Props struct {
ID string
Class string
Attributes templ.Attributes
Size Size
Color string
}
func Spinner(props ...Props) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var p Props
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
"inline-flex flex-col items-center justify-center",
p.Class,
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if p.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " id=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.ID)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/spinner/spinner.templ`, Line: 29, Col: 12}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/spinner/spinner.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" aria-label=\"Loading\" role=\"status\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderAttributes(ctx, templ_7745c5c3_Buffer, p.Attributes)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, ">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 = []any{
utils.TwMerge(
"animate-spin rounded-full",
sizeClass(p.Size),
borderSizeClass(p.Size),
utils.IfElse(
p.Color == "",
"border-primary border-b-transparent",
"border-current border-b-transparent",
),
utils.IfElse(
p.Color != "",
p.Color,
"",
),
),
}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "<div class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var5).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/spinner/spinner.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\"></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func sizeClass(size Size) string {
switch size {
case SizeSm:
return "w-6 h-6"
case SizeLg:
return "w-12 h-12"
default:
return "w-8 h-8"
}
}
func borderSizeClass(size Size) string {
switch size {
case SizeSm:
return "border-[3px]"
case SizeLg:
return "border-[5px]"
default:
return "border-4"
}
}
var _ = templruntime.GeneratedTemplate

View file

@ -0,0 +1,201 @@
// templui component table - version: main installed by templui v0.71.0
package table
import "git.jmbit.de/jmb/scanfile/server/web/templui/utils"
type Props struct {
ID string
Class string
Attributes templ.Attributes
}
type HeaderProps struct {
ID string
Class string
Attributes templ.Attributes
}
type BodyProps struct {
ID string
Class string
Attributes templ.Attributes
}
type FooterProps struct {
ID string
Class string
Attributes templ.Attributes
}
type RowProps struct {
ID string
Class string
Attributes templ.Attributes
Selected bool
}
type HeadProps struct {
ID string
Class string
Attributes templ.Attributes
}
type CellProps struct {
ID string
Class string
Attributes templ.Attributes
}
type CaptionProps struct {
ID string
Class string
Attributes templ.Attributes
}
templ Table(props ...Props) {
{{ var p Props }}
if len(props) > 0 {
{{ p = props[0] }}
}
<div class="relative w-full overflow-auto">
<table
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("w-full caption-bottom text-sm", p.Class) }
{ p.Attributes... }
>
{ children... }
</table>
</div>
}
templ Header(props ...HeaderProps) {
{{ var p HeaderProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<thead
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("[&_tr]:border-b", p.Class) }
{ p.Attributes... }
>
{ children... }
</thead>
}
templ Body(props ...BodyProps) {
{{ var p BodyProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<tbody
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("[&_tr:last-child]:border-0", p.Class) }
{ p.Attributes... }
>
{ children... }
</tbody>
}
templ Footer(props ...FooterProps) {
{{ var p FooterProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<tfoot
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", p.Class) }
{ p.Attributes... }
>
{ children... }
</tfoot>
}
templ Row(props ...RowProps) {
{{ var p RowProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<tr
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"border-b transition-colors hover:bg-muted/50",
utils.If(p.Selected, "data-[state=selected]:bg-muted"),
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</tr>
}
templ Head(props ...HeadProps) {
{{ var p HeadProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<th
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"h-10 px-2 text-left align-middle font-medium text-muted-foreground",
"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</th>
}
templ Cell(props ...CellProps) {
{{ var p CellProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<td
if p.ID != "" {
id={ p.ID }
}
class={
utils.TwMerge(
"p-2 align-middle",
"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
p.Class,
),
}
{ p.Attributes... }
>
{ children... }
</td>
}
templ Caption(props ...CaptionProps) {
{{ var p CaptionProps }}
if len(props) > 0 {
{{ p = props[0] }}
}
<caption
if p.ID != "" {
id={ p.ID }
}
class={ utils.TwMerge("mt-4 text-sm text-muted-foreground", p.Class) }
{ p.Attributes... }
>
{ children... }
</caption>
}

Some files were not shown because too many files have changed in this diff Show more