init docker compose
This commit is contained in:
parent
81633cda04
commit
99bdb78780
95 changed files with 438 additions and 5068 deletions
1
.env
Normal file
1
.env
Normal file
|
|
@ -0,0 +1 @@
|
|||
NPM_TOKEN=88097a2fbf83ef025397b96fba63e4c7b1dac6cc
|
||||
34
.github/workflows/ci.yml
vendored
34
.github/workflows/ci.yml
vendored
|
|
@ -1,34 +0,0 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
# cancel in-progress runs on new commits to same PR (gitub.event.number)
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
jobs:
|
||||
Check:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version-file: .tool-versions
|
||||
run_install: true
|
||||
- run: bun run --filter "./packages/*" check
|
||||
|
||||
Tests:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version-file: .tool-versions
|
||||
run_install: true
|
||||
- run: bun run --filter "./packages/*" test
|
||||
28
.github/workflows/deploy.yml
vendored
28
.github/workflows/deploy.yml
vendored
|
|
@ -1,28 +0,0 @@
|
|||
name: Deployment
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
jobs:
|
||||
theia-storybook:
|
||||
name: Deploy ${{ env.GITHUB_REPOSITORY }}
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.GITHUB_SERVER_URL }}
|
||||
username: ${{ env.GITHUB_REPOSITORY_OWNER }}
|
||||
password: ${{ secrets.NPM_TOKEN }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: true
|
||||
context: packages/theia
|
||||
file: packages/theia/Dockerfile.storybook
|
||||
tags: git.palko.ca/${{ env.GITHUB_REPOSITORY }}-theia-storybook:latest
|
||||
175
.gitignore
vendored
175
.gitignore
vendored
|
|
@ -1,175 +0,0 @@
|
|||
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||
|
||||
# Logs
|
||||
|
||||
logs
|
||||
_.log
|
||||
npm-debug.log_
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Caches
|
||||
|
||||
.cache
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# Runtime data
|
||||
|
||||
pids
|
||||
_.pid
|
||||
_.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
|
||||
.temp
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# IntelliJ based IDEs
|
||||
.idea
|
||||
|
||||
# Finder (MacOS) folder config
|
||||
.DS_Store
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
# Package Managers
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
yarn.lock
|
||||
*.md
|
||||
|
||||
21
.prettierrc
21
.prettierrc
|
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"useTabs": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"printWidth": 100,
|
||||
"endOfLine": "lf",
|
||||
"arrowParens": "always",
|
||||
"jsxSingleQuote": false,
|
||||
"semi": true,
|
||||
"quoteProps": "as-needed",
|
||||
"tabWidth": 4,
|
||||
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.svelte",
|
||||
"options": {
|
||||
"parser": "svelte"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
bun 1.2.4
|
||||
12
README.md
12
README.md
|
|
@ -1,13 +1,17 @@
|
|||
# Atlas
|
||||
|
||||
This repository publishes common packages for both backend and frontend usage.
|
||||
This repository contains the deployment definitions for the full Pantheon suite of services.
|
||||
|
||||
## Setup
|
||||
|
||||
To install dependencies:
|
||||
Login to docker:
|
||||
|
||||
```bash
|
||||
bun install
|
||||
docker login git.palko.ca
|
||||
```
|
||||
|
||||
This project was created using `bun init` in bun v1.2.0. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
|
||||
Start docker compose:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
4
config/nginx/.gitignore
vendored
Normal file
4
config/nginx/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
keys
|
||||
log
|
||||
|
||||
nginx/dhparams.pem
|
||||
1
config/nginx/.migrations
Executable file
1
config/nginx/.migrations
Executable file
|
|
@ -0,0 +1 @@
|
|||
01-nginx-site-confs-default
|
||||
95
config/nginx/nginx/nginx.conf
Executable file
95
config/nginx/nginx/nginx.conf
Executable file
|
|
@ -0,0 +1,95 @@
|
|||
## Version 2024/12/17 - Changelog: https://github.com/linuxserver/docker-baseimage-alpine-nginx/commits/master/root/defaults/nginx/nginx.conf.sample
|
||||
|
||||
### Based on alpine defaults
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.conf?h=3.21-stable
|
||||
|
||||
user abc;
|
||||
|
||||
# Set number of worker processes automatically based on number of CPU cores.
|
||||
include /config/nginx/worker_processes.conf;
|
||||
|
||||
# Enables the use of JIT for regular expressions to speed-up their processing.
|
||||
pcre_jit on;
|
||||
|
||||
# Configures default error logger.
|
||||
error_log /config/log/nginx/error.log;
|
||||
|
||||
# Includes files with directives to load dynamic modules.
|
||||
include /etc/nginx/modules/*.conf;
|
||||
|
||||
# Include files with config snippets into the root context.
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
|
||||
events {
|
||||
# The maximum number of simultaneous connections that can be opened by
|
||||
# a worker process.
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
# Includes mapping of file name extensions to MIME types of responses
|
||||
# and defines the default type.
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Name servers used to resolve names of upstream servers into addresses.
|
||||
# It's also needed when using tcpsocket and udpsocket in Lua modules.
|
||||
#resolver 1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001;
|
||||
include /config/nginx/resolver.conf;
|
||||
|
||||
# Don't tell nginx version to the clients. Default is 'on'.
|
||||
server_tokens off;
|
||||
|
||||
# Specifies the maximum accepted body size of a client request, as
|
||||
# indicated by the request header Content-Length. If the stated content
|
||||
# length is greater than this size, then the client receives the HTTP
|
||||
# error code 413. Set to 0 to disable. Default is '1m'.
|
||||
client_max_body_size 0;
|
||||
|
||||
# Sendfile copies data between one FD and other from within the kernel,
|
||||
# which is more efficient than read() + write(). Default is off.
|
||||
sendfile on;
|
||||
|
||||
# Causes nginx to attempt to send its HTTP response head in one packet,
|
||||
# instead of using partial frames. Default is 'off'.
|
||||
tcp_nopush on;
|
||||
|
||||
# all ssl related config moved to ssl.conf
|
||||
# included in server blocks where listen 443 is defined
|
||||
|
||||
# Enable gzipping of responses.
|
||||
#gzip on;
|
||||
|
||||
# Set the Vary HTTP header as defined in the RFC 2616. Default is 'off'.
|
||||
gzip_vary on;
|
||||
|
||||
# Helper variable for proxying websockets.
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
# Enable http2 by default for all servers
|
||||
http2 on;
|
||||
|
||||
# Sets the path, format, and configuration for a buffered log write.
|
||||
access_log /config/log/nginx/access.log;
|
||||
|
||||
client_body_temp_path /tmp/nginx 1 2;
|
||||
proxy_temp_path /tmp/nginx-proxy;
|
||||
fastcgi_temp_path /tmp/nginx-fastcgi;
|
||||
uwsgi_temp_path /tmp/nginx-uwsgi;
|
||||
scgi_temp_path /tmp/nginx-scgi;
|
||||
|
||||
proxy_cache_path /tmp/nginx-proxy-cache keys_zone=lsio-proxy:10m;
|
||||
fastcgi_cache_path /tmp/nginx-fcgi-cache keys_zone=lsio-fcgi:10m;
|
||||
scgi_cache_path /tmp/nginx-scgi-cache keys_zone=lsio-scgi:10m;
|
||||
uwsgi_cache_path /tmp/nginx-uwsgi-cache keys_zone=lsio-uwsgi:10m;
|
||||
|
||||
# Includes virtual hosts configs.
|
||||
include /etc/nginx/http.d/*.conf;
|
||||
include /config/nginx/site-confs/*.conf;
|
||||
}
|
||||
|
||||
daemon off;
|
||||
pid /run/nginx.pid;
|
||||
95
config/nginx/nginx/nginx.conf.sample
Normal file
95
config/nginx/nginx/nginx.conf.sample
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
## Version 2024/12/17 - Changelog: https://github.com/linuxserver/docker-baseimage-alpine-nginx/commits/master/root/defaults/nginx/nginx.conf.sample
|
||||
|
||||
### Based on alpine defaults
|
||||
# https://git.alpinelinux.org/aports/tree/main/nginx/nginx.conf?h=3.21-stable
|
||||
|
||||
user abc;
|
||||
|
||||
# Set number of worker processes automatically based on number of CPU cores.
|
||||
include /config/nginx/worker_processes.conf;
|
||||
|
||||
# Enables the use of JIT for regular expressions to speed-up their processing.
|
||||
pcre_jit on;
|
||||
|
||||
# Configures default error logger.
|
||||
error_log /config/log/nginx/error.log;
|
||||
|
||||
# Includes files with directives to load dynamic modules.
|
||||
include /etc/nginx/modules/*.conf;
|
||||
|
||||
# Include files with config snippets into the root context.
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
|
||||
events {
|
||||
# The maximum number of simultaneous connections that can be opened by
|
||||
# a worker process.
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
# Includes mapping of file name extensions to MIME types of responses
|
||||
# and defines the default type.
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Name servers used to resolve names of upstream servers into addresses.
|
||||
# It's also needed when using tcpsocket and udpsocket in Lua modules.
|
||||
#resolver 1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001;
|
||||
include /config/nginx/resolver.conf;
|
||||
|
||||
# Don't tell nginx version to the clients. Default is 'on'.
|
||||
server_tokens off;
|
||||
|
||||
# Specifies the maximum accepted body size of a client request, as
|
||||
# indicated by the request header Content-Length. If the stated content
|
||||
# length is greater than this size, then the client receives the HTTP
|
||||
# error code 413. Set to 0 to disable. Default is '1m'.
|
||||
client_max_body_size 0;
|
||||
|
||||
# Sendfile copies data between one FD and other from within the kernel,
|
||||
# which is more efficient than read() + write(). Default is off.
|
||||
sendfile on;
|
||||
|
||||
# Causes nginx to attempt to send its HTTP response head in one packet,
|
||||
# instead of using partial frames. Default is 'off'.
|
||||
tcp_nopush on;
|
||||
|
||||
# all ssl related config moved to ssl.conf
|
||||
# included in server blocks where listen 443 is defined
|
||||
|
||||
# Enable gzipping of responses.
|
||||
#gzip on;
|
||||
|
||||
# Set the Vary HTTP header as defined in the RFC 2616. Default is 'off'.
|
||||
gzip_vary on;
|
||||
|
||||
# Helper variable for proxying websockets.
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
||||
# Enable http2 by default for all servers
|
||||
http2 on;
|
||||
|
||||
# Sets the path, format, and configuration for a buffered log write.
|
||||
access_log /config/log/nginx/access.log;
|
||||
|
||||
client_body_temp_path /tmp/nginx 1 2;
|
||||
proxy_temp_path /tmp/nginx-proxy;
|
||||
fastcgi_temp_path /tmp/nginx-fastcgi;
|
||||
uwsgi_temp_path /tmp/nginx-uwsgi;
|
||||
scgi_temp_path /tmp/nginx-scgi;
|
||||
|
||||
proxy_cache_path /tmp/nginx-proxy-cache keys_zone=lsio-proxy:10m;
|
||||
fastcgi_cache_path /tmp/nginx-fcgi-cache keys_zone=lsio-fcgi:10m;
|
||||
scgi_cache_path /tmp/nginx-scgi-cache keys_zone=lsio-scgi:10m;
|
||||
uwsgi_cache_path /tmp/nginx-uwsgi-cache keys_zone=lsio-uwsgi:10m;
|
||||
|
||||
# Includes virtual hosts configs.
|
||||
include /etc/nginx/http.d/*.conf;
|
||||
include /config/nginx/site-confs/*.conf;
|
||||
}
|
||||
|
||||
daemon off;
|
||||
pid /run/nginx.pid;
|
||||
20
config/nginx/nginx/proxy-confs/theia-storybook.conf
Normal file
20
config/nginx/nginx/proxy-confs/theia-storybook.conf
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name theia.*;
|
||||
|
||||
include /config/nginx/ssl.conf;
|
||||
|
||||
client_max_body_size 0;
|
||||
|
||||
location / {
|
||||
include /config/nginx/proxy.conf;
|
||||
include /config/nginx/resolver.conf;
|
||||
set $upstream_app theia;
|
||||
set $upstream_port 80;
|
||||
set $upstream_proto http;
|
||||
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
|
||||
|
||||
}
|
||||
}
|
||||
3
config/nginx/nginx/resolver.conf
Executable file
3
config/nginx/nginx/resolver.conf
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
# This file is auto-generated only on first start, based on the container's /etc/resolv.conf file. Feel free to modify it as you wish.
|
||||
|
||||
resolver 127.0.0.11 valid=30s;
|
||||
44
config/nginx/nginx/site-confs/default.conf
Executable file
44
config/nginx/nginx/site-confs/default.conf
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
## Version 2024/07/16 - Changelog: https://github.com/linuxserver/docker-baseimage-alpine-nginx/commits/master/root/defaults/nginx/site-confs/default.conf.sample
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
listen 443 ssl default_server;
|
||||
listen [::]:443 ssl default_server;
|
||||
|
||||
server_name pantheon.ca;
|
||||
|
||||
include /config/nginx/ssl.conf;
|
||||
|
||||
set $root /app/www/public;
|
||||
if (!-d /app/www/public) {
|
||||
set $root /config/www;
|
||||
}
|
||||
root $root;
|
||||
index index.html index.htm index.php;
|
||||
|
||||
location / {
|
||||
# enable for basic auth
|
||||
#auth_basic "Restricted";
|
||||
#auth_basic_user_file /config/nginx/.htpasswd;
|
||||
|
||||
try_files $uri $uri/ /index.html /index.htm /index.php$is_args$args;
|
||||
}
|
||||
|
||||
location ~ ^(.+\.php)(.*)$ {
|
||||
# enable the next two lines for http auth
|
||||
#auth_basic "Restricted";
|
||||
#auth_basic_user_file /config/nginx/.htpasswd;
|
||||
|
||||
fastcgi_split_path_info ^(.+\.php)(.*)$;
|
||||
if (!-f $document_root$fastcgi_script_name) { return 404; }
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_index index.php;
|
||||
include /etc/nginx/fastcgi_params;
|
||||
}
|
||||
|
||||
# deny access to .htaccess/.htpasswd files
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
44
config/nginx/nginx/site-confs/default.conf.sample
Normal file
44
config/nginx/nginx/site-confs/default.conf.sample
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
## Version 2024/07/16 - Changelog: https://github.com/linuxserver/docker-baseimage-alpine-nginx/commits/master/root/defaults/nginx/site-confs/default.conf.sample
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
listen 443 ssl default_server;
|
||||
listen [::]:443 ssl default_server;
|
||||
|
||||
server_name _;
|
||||
|
||||
include /config/nginx/ssl.conf;
|
||||
|
||||
set $root /app/www/public;
|
||||
if (!-d /app/www/public) {
|
||||
set $root /config/www;
|
||||
}
|
||||
root $root;
|
||||
index index.html index.htm index.php;
|
||||
|
||||
location / {
|
||||
# enable for basic auth
|
||||
#auth_basic "Restricted";
|
||||
#auth_basic_user_file /config/nginx/.htpasswd;
|
||||
|
||||
try_files $uri $uri/ /index.html /index.htm /index.php$is_args$args;
|
||||
}
|
||||
|
||||
location ~ ^(.+\.php)(.*)$ {
|
||||
# enable the next two lines for http auth
|
||||
#auth_basic "Restricted";
|
||||
#auth_basic_user_file /config/nginx/.htpasswd;
|
||||
|
||||
fastcgi_split_path_info ^(.+\.php)(.*)$;
|
||||
if (!-f $document_root$fastcgi_script_name) { return 404; }
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_index index.php;
|
||||
include /etc/nginx/fastcgi_params;
|
||||
}
|
||||
|
||||
# deny access to .htaccess/.htpasswd files
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
32
config/nginx/nginx/ssl.conf
Executable file
32
config/nginx/nginx/ssl.conf
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
## Version 2024/12/06 - Changelog: https://github.com/linuxserver/docker-baseimage-alpine-nginx/commits/master/root/defaults/nginx/ssl.conf.sample
|
||||
|
||||
### Mozilla Recommendations
|
||||
# generated 2024-12-06, Mozilla Guideline v5.7, nginx 1.26.2, OpenSSL 3.3.2, intermediate config, no OCSP
|
||||
# https://ssl-config.mozilla.org/#server=nginx&version=1.26.2&config=intermediate&openssl=3.3.2&ocsp=false&guideline=5.7
|
||||
|
||||
ssl_certificate /config/keys/cert.crt;
|
||||
ssl_certificate_key /config/keys/cert.key;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
|
||||
ssl_session_tickets off;
|
||||
|
||||
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
|
||||
ssl_dhparam /config/nginx/dhparams.pem;
|
||||
|
||||
# intermediate configuration
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
|
||||
#add_header Strict-Transport-Security "max-age=63072000" always;
|
||||
|
||||
# Optional additional headers
|
||||
#add_header Cache-Control "no-transform" always;
|
||||
#add_header Content-Security-Policy "upgrade-insecure-requests; frame-ancestors 'self'" always;
|
||||
#add_header Permissions-Policy "interest-cohort=()" always;
|
||||
#add_header Referrer-Policy "same-origin" always;
|
||||
#add_header X-Content-Type-Options "nosniff" always;
|
||||
#add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
#add_header X-UA-Compatible "IE=Edge" always;
|
||||
#add_header X-XSS-Protection "1; mode=block" always;
|
||||
32
config/nginx/nginx/ssl.conf.sample
Normal file
32
config/nginx/nginx/ssl.conf.sample
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
## Version 2024/12/06 - Changelog: https://github.com/linuxserver/docker-baseimage-alpine-nginx/commits/master/root/defaults/nginx/ssl.conf.sample
|
||||
|
||||
### Mozilla Recommendations
|
||||
# generated 2024-12-06, Mozilla Guideline v5.7, nginx 1.26.2, OpenSSL 3.3.2, intermediate config, no OCSP
|
||||
# https://ssl-config.mozilla.org/#server=nginx&version=1.26.2&config=intermediate&openssl=3.3.2&ocsp=false&guideline=5.7
|
||||
|
||||
ssl_certificate /config/keys/cert.crt;
|
||||
ssl_certificate_key /config/keys/cert.key;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
|
||||
ssl_session_tickets off;
|
||||
|
||||
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
|
||||
ssl_dhparam /config/nginx/dhparams.pem;
|
||||
|
||||
# intermediate configuration
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
|
||||
#add_header Strict-Transport-Security "max-age=63072000" always;
|
||||
|
||||
# Optional additional headers
|
||||
#add_header Cache-Control "no-transform" always;
|
||||
#add_header Content-Security-Policy "upgrade-insecure-requests; frame-ancestors 'self'" always;
|
||||
#add_header Permissions-Policy "interest-cohort=()" always;
|
||||
#add_header Referrer-Policy "same-origin" always;
|
||||
#add_header X-Content-Type-Options "nosniff" always;
|
||||
#add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
#add_header X-UA-Compatible "IE=Edge" always;
|
||||
#add_header X-XSS-Protection "1; mode=block" always;
|
||||
3
config/nginx/nginx/worker_processes.conf
Executable file
3
config/nginx/nginx/worker_processes.conf
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
# This file is auto-generated only on first start, based on the cpu cores detected. Feel free to change it to any other number or to auto to let nginx handle it automatically.
|
||||
|
||||
worker_processes 12;
|
||||
3
config/nginx/php/php-local.ini
Executable file
3
config/nginx/php/php-local.ini
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
; Edit this file to override php.ini directives
|
||||
|
||||
date.timezone = UTC
|
||||
5
config/nginx/php/www2.conf
Executable file
5
config/nginx/php/www2.conf
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
; Edit this file to override www.conf and php-fpm.conf directives and restart the container
|
||||
|
||||
; Pool name
|
||||
[www]
|
||||
|
||||
34
config/nginx/www/index.html
Executable file
34
config/nginx/www/index.html
Executable file
|
|
@ -0,0 +1,34 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Welcome to our server</title>
|
||||
<style>
|
||||
body{
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
}
|
||||
.message{
|
||||
width:330px;
|
||||
padding:20px 40px;
|
||||
margin:0 auto;
|
||||
background-color:#f9f9f9;
|
||||
border:1px solid #ddd;
|
||||
}
|
||||
center{
|
||||
margin:40px 0;
|
||||
}
|
||||
h1{
|
||||
font-size: 18px;
|
||||
line-height: 26px;
|
||||
}
|
||||
p{
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="message">
|
||||
<h1>Welcome to our server</h1>
|
||||
<p>The website is currently being setup under this address.</p>
|
||||
<p>For help and support, please contact: <a href="me@example.com">me@example.com</a></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
14
docker-compose.yml
Normal file
14
docker-compose.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
name: Pantheon
|
||||
|
||||
services:
|
||||
nginx:
|
||||
image: lscr.io/linuxserver/nginx:latest
|
||||
env_file: .env
|
||||
volumes:
|
||||
- ./config/nginx:/config
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
restart: unless-stopped
|
||||
theia-storybook:
|
||||
image: git.palko.ca/pantheon/theia-storybook:latest
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
import prettier from 'eslint-config-prettier';
|
||||
import js from '@eslint/js';
|
||||
import { includeIgnoreFile } from '@eslint/compat';
|
||||
import svelte from 'eslint-plugin-svelte';
|
||||
import globals from 'globals';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import ts from 'typescript-eslint';
|
||||
const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));
|
||||
|
||||
export default ts.config(
|
||||
includeIgnoreFile(gitignorePath),
|
||||
js.configs.recommended,
|
||||
...ts.configs.recommended,
|
||||
...svelte.configs['flat/recommended'],
|
||||
prettier,
|
||||
...svelte.configs['flat/prettier'],
|
||||
{
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.node,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.svelte'],
|
||||
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
parser: ts.parser,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
argsIgnorePattern: '^_',
|
||||
varsIgnorePattern: '^_',
|
||||
caughtErrorsIgnorePattern: '^_',
|
||||
},
|
||||
],
|
||||
'no-restricted-syntax': [
|
||||
'error',
|
||||
{
|
||||
selector:
|
||||
'CallExpression:matches([callee.object.object.name="prisma"], [callee.object.object.name="prismaTransactionClient"], [callee.object.object.name="transactionClient"]):matches([callee.property.name="findFirst"], [callee.property.name="findMany"], [callee.property.name="updateMany"], [callee.property.name="deleteMany"], [callee.property.name="count"], [callee.property.name="aggregate"], [callee.property.name="groupBy"]):not(:has(ObjectExpression > Property[key.name="where"] > ObjectExpression > Property[key.name="tenantId"]))',
|
||||
message:
|
||||
'Please filter on the current tenant when using findFirst, findMany, updateMany, deleteMany, count, aggregate or groupBy.',
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
);
|
||||
25
package.json
25
package.json
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"name": "atlas-monorepo",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"workspaces": [],
|
||||
"scripts": {
|
||||
"format": "prettier --write .",
|
||||
"lint": "prettier --check . && eslint .",
|
||||
"prepare": "husky"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/compat": "^1.2.3",
|
||||
"@types/bun": "latest",
|
||||
"eslint": "^9.7.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-svelte": "^2.36.0",
|
||||
"globals": "^15.0.0",
|
||||
"husky": "^9.1.7",
|
||||
"lint-staged": "^15.3.0",
|
||||
"prettier": "^3.3.2",
|
||||
"prettier-plugin-svelte": "^3.2.6",
|
||||
"prettier-plugin-tailwindcss": "^0.6.5"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
FROM oven/bun:1.2-alpine AS build
|
||||
|
||||
WORKDIR /opt/build
|
||||
|
||||
COPY . .
|
||||
RUN bun install --frozen-lockfile \
|
||||
&& bunx svelte-kit sync \
|
||||
&& bun run build-storybook
|
||||
|
||||
FROM nginx:alpine3.21
|
||||
|
||||
COPY --from=build --chown=1000:1000 /opt/build/storybook-static /usr/share/nginx/html
|
||||
186
packages/theia/.gitignore
vendored
186
packages/theia/.gitignore
vendored
|
|
@ -1,186 +0,0 @@
|
|||
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||
|
||||
# Storybook
|
||||
storybook-static
|
||||
|
||||
# Output
|
||||
.output
|
||||
.vercel
|
||||
.netlify
|
||||
.wrangler
|
||||
/.svelte-kit
|
||||
/build
|
||||
|
||||
# Logs
|
||||
|
||||
logs
|
||||
_.log
|
||||
npm-debug.log_
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Caches
|
||||
|
||||
.cache
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# Runtime data
|
||||
|
||||
pids
|
||||
_.pid
|
||||
_.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
|
||||
.temp
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# IntelliJ based IDEs
|
||||
.idea
|
||||
|
||||
# Finder (MacOS) folder config
|
||||
.DS_Store
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
/** @type { import('@storybook/sveltekit').StorybookConfig } */
|
||||
const config = {
|
||||
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|ts|svelte)'],
|
||||
addons: [
|
||||
'@chromatic-com/storybook',
|
||||
'@storybook/addon-essentials',
|
||||
'@storybook/addon-interactions',
|
||||
'@storybook/addon-styling-webpack',
|
||||
'@storybook/addon-svelte-csf',
|
||||
'@storybook/addon-themes',
|
||||
],
|
||||
framework: {
|
||||
name: '@storybook/sveltekit',
|
||||
options: {},
|
||||
},
|
||||
};
|
||||
export default config;
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
@import 'tailwindcss';
|
||||
@plugin "daisyui";
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
import { withThemeByDataAttribute } from '@storybook/addon-themes';
|
||||
import './preview.css';
|
||||
|
||||
/** @type { import('@storybook/svelte').Preview } */
|
||||
const preview = {
|
||||
tags: ['autodocs'],
|
||||
parameters: {
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/i,
|
||||
},
|
||||
},
|
||||
},
|
||||
decorators: [
|
||||
withThemeByDataAttribute({
|
||||
themes: {
|
||||
light: 'light',
|
||||
dark: 'dark',
|
||||
night: 'night',
|
||||
},
|
||||
defaultTheme: 'dark',
|
||||
attributeName: 'data-theme',
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
export default preview;
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
FROM oven/bun:1.2-alpine AS build
|
||||
|
||||
WORKDIR /opt/build
|
||||
|
||||
COPY . .
|
||||
RUN bun install --frozen-lockfile \
|
||||
&& bun run build-storybook
|
||||
|
||||
FROM nginx:alpine3.21
|
||||
|
||||
COPY --from=build --chown=1000:1000 /opt/build/storybook-static /usr/share/nginx/html
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
# Theia
|
||||
|
||||
Common Svelte components
|
||||
|
||||
To run:
|
||||
|
||||
```bash
|
||||
bun storybook
|
||||
```
|
||||
|
||||
This project was created using `bun init` in bun v1.2.0. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,86 +0,0 @@
|
|||
{
|
||||
"name": "@atlas/theia",
|
||||
"type": "module",
|
||||
"version": "1.0.5-alpha",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"svelte": "./dist/index.js"
|
||||
},
|
||||
"./components": {
|
||||
"types": "./dist/components/index.d.ts",
|
||||
"svelte": "./dist/components/index.js"
|
||||
},
|
||||
"./types": {
|
||||
"types": "./dist/types/index.d.ts",
|
||||
"import": "./dist/types/index.js"
|
||||
}
|
||||
},
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"!dist/**/*.spec.*",
|
||||
"!dist/**/*.test.*",
|
||||
"!dist/**/*.stories.*",
|
||||
"dist"
|
||||
],
|
||||
"keywords": [
|
||||
"svelte",
|
||||
"UI",
|
||||
"daisyui",
|
||||
"component",
|
||||
"library"
|
||||
],
|
||||
"scripts": {
|
||||
"build-storybook": "storybook build",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"test:unit": "vitest",
|
||||
"test": "bun run test:unit -- --run && bun run test:e2e",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"test:e2e": "playwright test",
|
||||
"package": "svelte-kit sync && svelte-package",
|
||||
"prepublishOnly": "bun package"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@chromatic-com/storybook": "^3.2.2",
|
||||
"@playwright/test": "^1.45.3",
|
||||
"@storybook/addon-essentials": "^8.5.0",
|
||||
"@storybook/addon-interactions": "^8.5.0",
|
||||
"@storybook/addon-styling-webpack": "^1.0.1",
|
||||
"@storybook/addon-svelte-csf": "^5.0.0-next.13",
|
||||
"@storybook/addon-themes": "^8.5.0",
|
||||
"@storybook/blocks": "^8.5.0",
|
||||
"@storybook/svelte": "^8.5.0",
|
||||
"@storybook/sveltekit": "^8.5.0",
|
||||
"@storybook/test": "^8.5.0",
|
||||
"@sveltejs/adapter-auto": "^3.0.0",
|
||||
"@sveltejs/kit": "^2.15.3",
|
||||
"@sveltejs/package": "^2.3.9",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||
"@tailwindcss/postcss": "^4.0.15",
|
||||
"@types/bun": "^1.1.15",
|
||||
"eslint": "^9.7.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-svelte": "^2.36.0",
|
||||
"lucide-svelte": "^0.483.0",
|
||||
"prettier": "^3.3.2",
|
||||
"prettier-plugin-svelte": "^3.2.6",
|
||||
"prettier-plugin-tailwindcss": "^0.6.11",
|
||||
"storybook": "^8.5.0",
|
||||
"svelte-check": "^4.0.0",
|
||||
"tailwindcss": "^4.0.15",
|
||||
"typescript": "^5.8.2",
|
||||
"typescript-eslint": "^8.0.0",
|
||||
"vite": "^6.0.7",
|
||||
"vitest": "^2.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1",
|
||||
"tailwind-merge": "^2.5.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"daisyui": "^5.0.6",
|
||||
"svelte": "^5.0.0"
|
||||
},
|
||||
"svelte": "./dist/index.js"
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
export default {
|
||||
plugins: {
|
||||
'@tailwindcss/postcss': {},
|
||||
},
|
||||
};
|
||||
13
packages/theia/src/app.d.ts
vendored
13
packages/theia/src/app.d.ts
vendored
|
|
@ -1,13 +0,0 @@
|
|||
// See https://kit.svelte.dev/docs/types#app
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface PageState {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div>%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import { fn } from '@storybook/test';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
import Button from './Button.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Actions/Button',
|
||||
component: Button,
|
||||
args: {
|
||||
onclick: fn(),
|
||||
},
|
||||
argTypes: {
|
||||
active: { control: 'boolean' },
|
||||
block: { control: 'boolean' },
|
||||
color: {
|
||||
control: 'select',
|
||||
options: [
|
||||
undefined,
|
||||
'neutral',
|
||||
'primary',
|
||||
'secondary',
|
||||
'accent',
|
||||
'ghost',
|
||||
'info',
|
||||
'success',
|
||||
'warning',
|
||||
'error',
|
||||
],
|
||||
},
|
||||
disabled: { control: 'boolean' },
|
||||
full: { control: 'boolean' },
|
||||
shape: {
|
||||
control: 'select',
|
||||
options: ['square', 'circle'],
|
||||
},
|
||||
size: {
|
||||
control: 'select',
|
||||
options: ['xs', 'sm', 'md', 'lg'],
|
||||
defaultValue: 'md',
|
||||
},
|
||||
style: {
|
||||
control: 'select',
|
||||
options: [undefined, 'outline', 'dash', 'soft', 'ghost', 'link'],
|
||||
},
|
||||
wide: { control: 'boolean' },
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template({ children: _, ...props }: Partial<ComponentProps<typeof Button>>)}
|
||||
<Button {...props}>Button</Button>
|
||||
{/snippet}
|
||||
|
||||
<Story name="Default" args={{}} children={template} />
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
<script lang="ts" module>
|
||||
export type ButtonShape = 'square' | 'circle';
|
||||
export type ButtonStyle = 'outline' | 'dash' | 'soft' | 'ghost' | 'link';
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import type { DaisyColor, DaisySize } from '$lib/types';
|
||||
import clsx from 'clsx';
|
||||
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
type Props = {
|
||||
active?: boolean;
|
||||
block?: boolean;
|
||||
color?: DaisyColor;
|
||||
full?: boolean;
|
||||
shape?: ButtonShape;
|
||||
size?: DaisySize;
|
||||
style?: ButtonStyle;
|
||||
wide?: boolean;
|
||||
} & SvelteHTMLElements['button'];
|
||||
|
||||
let {
|
||||
active = false,
|
||||
block = false,
|
||||
children,
|
||||
class: className,
|
||||
color,
|
||||
full = false,
|
||||
shape,
|
||||
size,
|
||||
style,
|
||||
wide = false,
|
||||
...props
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<button
|
||||
{...props}
|
||||
class={twMerge('btn', clsx(className))}
|
||||
class:btn-active={active}
|
||||
class:btn-block={block}
|
||||
class:btn-neutral={color === 'neutral'}
|
||||
class:btn-primary={color === 'primary'}
|
||||
class:btn-secondary={color === 'secondary'}
|
||||
class:btn-accent={color === 'accent'}
|
||||
class:btn-info={color === 'info'}
|
||||
class:btn-success={color === 'success'}
|
||||
class:btn-warning={color === 'warning'}
|
||||
class:btn-error={color === 'error'}
|
||||
class:btn-disabled={props.disabled}
|
||||
class:w-full={full}
|
||||
class:btn-circle={shape === 'circle'}
|
||||
class:btn-square={shape === 'square'}
|
||||
class:btn-xs={size === 'xs'}
|
||||
class:btn-sm={size === 'sm'}
|
||||
class:btn-md={size === 'md'}
|
||||
class:btn-lg={size === 'lg'}
|
||||
class:btn-xl={size === 'xl'}
|
||||
class:btn-outline={style === 'outline'}
|
||||
class:btn-dash={style === 'dash'}
|
||||
class:btn-soft={style === 'soft'}
|
||||
class:btn-ghost={style === 'ghost'}
|
||||
class:btn-link={style === 'link'}
|
||||
class:btn-wide={wide}
|
||||
>
|
||||
{@render children?.()}
|
||||
</button>
|
||||
|
||||
<style></style>
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
<script lang="ts" module>
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import Dropdown from './Dropdown.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Actions/Dropdown',
|
||||
component: Dropdown,
|
||||
argTypes: {
|
||||
hover: {
|
||||
control: 'boolean',
|
||||
},
|
||||
open: {
|
||||
control: 'boolean',
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<Story name="Dropdown Menu">
|
||||
<Dropdown>
|
||||
{#snippet title()}
|
||||
Click me!
|
||||
{/snippet}
|
||||
<ul class={'menu bg-base-200 rounded-box w-56'}>
|
||||
<li><a>Item 1</a></li>
|
||||
<li><a>Item 2</a></li>
|
||||
<li><a>Item 3</a></li>
|
||||
</ul>
|
||||
</Dropdown>
|
||||
</Story>
|
||||
|
||||
<Story name="Dropdown Card">
|
||||
<Dropdown>
|
||||
{#snippet title()}
|
||||
Click me!
|
||||
{/snippet}
|
||||
<div class="card card-sm bg-base-100 z-1 w-64 shadow-md">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">You needed more info?</h2>
|
||||
<p>This is a card. You can use any element as a dropdown.</p>
|
||||
</div>
|
||||
</div>
|
||||
</Dropdown>
|
||||
</Story>
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
<script lang="ts" module>
|
||||
export type DropdownAlignment = {
|
||||
vertical?: 'top' | 'bottom';
|
||||
horizontal?: 'left' | 'right';
|
||||
content?: 'start' | 'center' | 'end';
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
type Props = {
|
||||
alignment?: DropdownAlignment;
|
||||
children: Snippet;
|
||||
hover?: boolean;
|
||||
open?: boolean;
|
||||
title: Snippet;
|
||||
};
|
||||
|
||||
let { alignment, children, hover, open, title }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="dropdown"
|
||||
class:dropdown-start={alignment?.content === 'start'}
|
||||
class:dropdown-center={alignment?.content === 'center'}
|
||||
class:dropdown-end={alignment?.content === 'end'}
|
||||
class:dropdown-top={alignment?.vertical === 'top'}
|
||||
class:dropdown-bottom={alignment?.vertical === 'bottom'}
|
||||
class:dropdown-left={alignment?.horizontal === 'left'}
|
||||
class:dropdown-right={alignment?.horizontal === 'right'}
|
||||
class:dropdown-hover={hover}
|
||||
class:dropdown-open={open}
|
||||
>
|
||||
<div tabindex="0" role="button" class="btn m-1">{@render title()}</div>
|
||||
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
||||
<div tabindex="0" class="dropdown-content z-0">
|
||||
{@render children?.()}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
import Button from './Button.svelte';
|
||||
import Modal from './Modal.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Actions/Modal',
|
||||
component: Modal,
|
||||
argTypes: {
|
||||
open: {
|
||||
control: 'boolean',
|
||||
defaultValue: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let dialog: HTMLDialogElement | undefined = $state(undefined);
|
||||
</script>
|
||||
|
||||
{#snippet template({ children: _, ...props }: Partial<ComponentProps<typeof Modal>>)}
|
||||
<Button onclick={() => dialog?.showModal()}>Open</Button>
|
||||
<Modal {...props} backdrop bind:dialog>
|
||||
<h3 class="text-lg font-bold">Hello!</h3>
|
||||
<p class="py-4">Press ESC key or click the button below to close</p>
|
||||
{#snippet actions()}
|
||||
<Button onclick={() => dialog?.close()}>Close</Button>
|
||||
{/snippet}
|
||||
</Modal>
|
||||
{/snippet}
|
||||
|
||||
<Story name="Default" children={template} />
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<script lang="ts">
|
||||
import clsx from 'clsx';
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
type Props = SvelteHTMLElements['dialog'] & {
|
||||
actions?: Snippet;
|
||||
backdrop?: boolean;
|
||||
dialog?: HTMLDialogElement;
|
||||
};
|
||||
|
||||
let {
|
||||
actions,
|
||||
backdrop,
|
||||
dialog = $bindable(),
|
||||
children,
|
||||
class: className,
|
||||
...props
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<dialog {...props} class={twMerge('modal', clsx(className))} bind:this={dialog}>
|
||||
<div class="modal-box">
|
||||
{@render children?.()}
|
||||
{#if actions}
|
||||
<div class="modal-action">
|
||||
{@render actions()}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if backdrop}
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button>close</button>
|
||||
</form>
|
||||
{/if}
|
||||
</dialog>
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import { type ComponentProps } from 'svelte';
|
||||
import Swap from './Swap.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Actions/Swap',
|
||||
component: Swap,
|
||||
argTypes: {
|
||||
style: {
|
||||
control: 'radio',
|
||||
options: [undefined, 'flip', 'rotate'],
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template(props: Partial<ComponentProps<typeof Swap>>)}
|
||||
<Swap {...props}>
|
||||
{#snippet on()}
|
||||
ON
|
||||
{/snippet}
|
||||
{#snippet off()}
|
||||
OFF
|
||||
{/snippet}
|
||||
</Swap>
|
||||
{/snippet}
|
||||
|
||||
<Story name="Default" children={template} />
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<script lang="ts" module>
|
||||
export type SwapStyle = 'flip' | 'rotate';
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
type Props = {
|
||||
active?: boolean;
|
||||
indeterminate?: Snippet;
|
||||
on: Snippet;
|
||||
off: Snippet;
|
||||
style?: SwapStyle;
|
||||
};
|
||||
|
||||
let { active, indeterminate, on, off, style }: Props = $props();
|
||||
</script>
|
||||
|
||||
<label
|
||||
class="swap"
|
||||
class:swap-active={active}
|
||||
class:swap-flip={style === 'flip'}
|
||||
class:swap-rotate={style === 'rotate'}
|
||||
>
|
||||
<input type="checkbox" />
|
||||
{#if indeterminate}
|
||||
{@render indeterminate()}
|
||||
{/if}
|
||||
<div class="swap-on fill-current">{@render on()}</div>
|
||||
<div class="swap-off fill-current">{@render off()}</div>
|
||||
</label>
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
export { default as Button } from './Button.svelte';
|
||||
export { default as Dropdown } from './Dropdown.svelte';
|
||||
export { default as Modal } from './Modal.svelte';
|
||||
export { default as Swap } from './Swap.svelte';
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
<script lang="ts" module>
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import Accordion from './Accordion.svelte';
|
||||
import { type ComponentProps } from 'svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Data Display/Accordion',
|
||||
component: Accordion,
|
||||
argTypes: {
|
||||
close: {
|
||||
control: 'boolean',
|
||||
defaultValue: false,
|
||||
},
|
||||
open: {
|
||||
control: 'boolean',
|
||||
defaultValue: false,
|
||||
},
|
||||
style: {
|
||||
control: 'radio',
|
||||
options: [undefined, 'arrow', 'plus'],
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template(props: Partial<ComponentProps<typeof Accordion>>)}
|
||||
<div class="flex flex-col gap-2">
|
||||
<Accordion name={props.name!} style={props.style} initialOpen>
|
||||
{#snippet title()}
|
||||
Option 1
|
||||
{/snippet}
|
||||
{#snippet content()}
|
||||
Description here!
|
||||
{/snippet}
|
||||
</Accordion>
|
||||
<Accordion name={props.name!} style={props.style}>
|
||||
{#snippet title()}
|
||||
Option 2
|
||||
{/snippet}
|
||||
{#snippet content()}
|
||||
Description here!
|
||||
{/snippet}
|
||||
</Accordion>
|
||||
<Accordion name={props.name!} style={props.style}>
|
||||
{#snippet title()}
|
||||
Option 3
|
||||
{/snippet}
|
||||
{#snippet content()}
|
||||
Description here!
|
||||
{/snippet}
|
||||
</Accordion>
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
<Story name="Default" children={template} args={{ name: 'accordion-story' }} />
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
<script lang="ts" module>
|
||||
export type AccordionStyle = 'arrow' | 'plus';
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
type Props = {
|
||||
close?: boolean;
|
||||
content?: Snippet;
|
||||
initialOpen?: boolean;
|
||||
name: string;
|
||||
open?: boolean;
|
||||
style?: AccordionStyle;
|
||||
title?: Snippet;
|
||||
};
|
||||
|
||||
let { close, content, initialOpen, name, open, style, title }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="bg-base-100 border-base-300 collapse border"
|
||||
class:collapse-arrow={style === 'arrow'}
|
||||
class:collapse-close={close}
|
||||
class:collapse-open={open}
|
||||
class:collapse-plus={style === 'plus'}
|
||||
>
|
||||
<input type="radio" {name} checked={initialOpen} />
|
||||
{#if title}
|
||||
<div class="collapse-title font-semibold">{@render title()}</div>
|
||||
{/if}
|
||||
{#if content}
|
||||
<div class="collapse-content text-sm">{@render content()}</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import { type ComponentProps } from 'svelte';
|
||||
import Avatar from './Avatar.svelte';
|
||||
import AvatarGroups from './AvatarGroup.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Data display/Avatar',
|
||||
component: Avatar,
|
||||
argTypes: {
|
||||
img: {
|
||||
control: 'text',
|
||||
},
|
||||
placeholder: {
|
||||
control: 'text',
|
||||
defaultValue: 'DP',
|
||||
},
|
||||
presence: {
|
||||
control: 'radio',
|
||||
options: [undefined, 'online', 'offline'],
|
||||
},
|
||||
ring: {
|
||||
control: 'radio',
|
||||
options: [
|
||||
undefined,
|
||||
'neutral',
|
||||
'primary',
|
||||
'secondary',
|
||||
'accent',
|
||||
'info',
|
||||
'success',
|
||||
'warning',
|
||||
'error',
|
||||
],
|
||||
},
|
||||
shape: {
|
||||
control: 'radio',
|
||||
options: ['square', 'circle'],
|
||||
defaultValue: 'circle',
|
||||
},
|
||||
size: {
|
||||
control: 'radio',
|
||||
options: ['xs', 'sm', 'md', 'lg', 'xl'],
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template(props: Partial<ComponentProps<typeof Avatar>>)}
|
||||
<Avatar {...props} placeholder={props.placeholder || 'PC'} />
|
||||
{/snippet}
|
||||
|
||||
<Story
|
||||
name="Default"
|
||||
args={{
|
||||
img: 'https://img.daisyui.com/images/stock/photo-1534528741775-53994a69daeb.webp',
|
||||
}}
|
||||
children={template}
|
||||
/>
|
||||
|
||||
<Story name="Placeholder" args={{ placeholder: 'BP' }} children={template} />
|
||||
|
||||
<Story name="Sizes">
|
||||
{@render template({
|
||||
size: 'xs',
|
||||
placeholder: 'XS',
|
||||
})}
|
||||
{@render template({
|
||||
size: 'sm',
|
||||
placeholder: 'SM',
|
||||
})}
|
||||
{@render template({
|
||||
size: 'md',
|
||||
placeholder: 'MD',
|
||||
})}
|
||||
{@render template({
|
||||
size: 'lg',
|
||||
placeholder: 'LG',
|
||||
})}
|
||||
{@render template({
|
||||
size: 'xl',
|
||||
placeholder: 'XL',
|
||||
})}
|
||||
</Story>
|
||||
|
||||
<Story name="Avatar Group">
|
||||
<AvatarGroups>
|
||||
{@render template({ placeholder: 'BP' })}
|
||||
{@render template({ placeholder: 'MS' })}
|
||||
{@render template({ placeholder: 'DM' })}
|
||||
</AvatarGroups>
|
||||
</Story>
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
<script lang="ts" module>
|
||||
export type AvatarShape = 'circle' | 'square';
|
||||
export type AvatarPresence = 'offline' | 'online';
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import type { DaisyColor, DaisySize } from '$lib/types';
|
||||
import clsx from 'clsx';
|
||||
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
type Props = {
|
||||
img?: string;
|
||||
placeholder: string;
|
||||
presence?: AvatarPresence;
|
||||
ring?: DaisyColor;
|
||||
shape?: AvatarShape;
|
||||
size?: DaisySize;
|
||||
} & Omit<SvelteHTMLElements['div'], 'children'>;
|
||||
|
||||
let {
|
||||
class: className,
|
||||
img,
|
||||
placeholder,
|
||||
presence,
|
||||
ring,
|
||||
shape = 'circle',
|
||||
size = 'md',
|
||||
...props
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
{...props}
|
||||
class={twMerge('avatar', clsx(className))}
|
||||
class:avatar-online={presence === 'online'}
|
||||
class:avatar-offline={presence === 'offline'}
|
||||
class:avatar-placeholder={placeholder}
|
||||
>
|
||||
<div
|
||||
class={twMerge(
|
||||
'rounded-xl',
|
||||
clsx({
|
||||
'rounded-xl': shape === 'square',
|
||||
'rounded-full': shape === 'circle',
|
||||
'w-12': size === 'xs',
|
||||
'w-16': size === 'sm',
|
||||
'w-20': size === 'md',
|
||||
'w-24': size === 'lg',
|
||||
'w-32': size === 'xl',
|
||||
'avatar-ring ring-offset-base-100 ring ring-offset-2': !!ring,
|
||||
})
|
||||
)}
|
||||
class:bg-neutral={placeholder}
|
||||
class:ring-neutral={ring === 'neutral'}
|
||||
class:ring-primary={ring === 'primary'}
|
||||
class:ring-secondary={ring === 'secondary'}
|
||||
class:ring-accent={ring === 'accent'}
|
||||
class:ring-info={ring === 'info'}
|
||||
class:ring-success={ring === 'success'}
|
||||
class:ring-warning={ring === 'warning'}
|
||||
class:ring-error={ring === 'error'}
|
||||
>
|
||||
{#if img}
|
||||
<img src={img} alt={placeholder} />
|
||||
{:else}
|
||||
<span
|
||||
class:text-5xl={size === 'xl'}
|
||||
class:text-3xl={size === 'lg'}
|
||||
class:text-2xl={size === 'md'}
|
||||
class:text-xs={size === 'xs'}>{placeholder}</span
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
type Props = {
|
||||
children?: Snippet;
|
||||
};
|
||||
|
||||
let { children }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class="avatar-group -space-x-6">
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
<script lang="ts" module>
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import { type ComponentProps } from 'svelte';
|
||||
import Badge from './Badge.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Data Display/Badge',
|
||||
component: Badge,
|
||||
argTypes: {
|
||||
color: {
|
||||
control: 'radio',
|
||||
options: [
|
||||
undefined,
|
||||
'primary',
|
||||
'secondary',
|
||||
'accent',
|
||||
'neutral',
|
||||
'info',
|
||||
'success',
|
||||
'warning',
|
||||
'error',
|
||||
],
|
||||
},
|
||||
size: {
|
||||
control: 'radio',
|
||||
options: ['xs', 'sm', 'md', 'lg', 'xl'],
|
||||
},
|
||||
style: {
|
||||
control: 'radio',
|
||||
options: [undefined, 'outline', 'dash', 'soft', 'ghost'],
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template(props: Partial<ComponentProps<typeof Badge>>)}
|
||||
<Badge {...props}>Badge</Badge>
|
||||
{/snippet}
|
||||
|
||||
<Story name="Default" children={template} />
|
||||
|
||||
<Story name="Sizes">
|
||||
<Badge size="xs">x-small</Badge>
|
||||
<Badge size="sm">small</Badge>
|
||||
<Badge size="md">medium</Badge>
|
||||
<Badge size="lg">large</Badge>
|
||||
<Badge size="xl">x-large</Badge>
|
||||
</Story>
|
||||
|
||||
<Story name="Colors">
|
||||
<Badge color="primary">Primary</Badge>
|
||||
<Badge color="secondary">Secondary</Badge>
|
||||
<Badge color="accent">Accent</Badge>
|
||||
<Badge color="neutral">Neutral</Badge>
|
||||
<Badge color="info">Info</Badge>
|
||||
<Badge color="success">Success</Badge>
|
||||
<Badge color="warning">Warning</Badge>
|
||||
<Badge color="error">Error</Badge>
|
||||
</Story>
|
||||
|
||||
<Story name="Outline">
|
||||
<Badge style="outline" color="primary">Primary</Badge>
|
||||
<Badge style="outline" color="secondary">Secondary</Badge>
|
||||
<Badge style="outline" color="accent">Accent</Badge>
|
||||
<Badge style="outline" color="neutral">Neutral</Badge>
|
||||
<Badge style="outline" color="info">Info</Badge>
|
||||
<Badge style="outline" color="success">Success</Badge>
|
||||
<Badge style="outline" color="warning">Warning</Badge>
|
||||
<Badge style="outline" color="error">Error</Badge>
|
||||
</Story>
|
||||
|
||||
<Story name="Dash">
|
||||
<Badge style="dash" color="primary">Primary</Badge>
|
||||
<Badge style="dash" color="secondary">Secondary</Badge>
|
||||
<Badge style="dash" color="accent">Accent</Badge>
|
||||
<Badge style="dash" color="neutral">Neutral</Badge>
|
||||
<Badge style="dash" color="info">Info</Badge>
|
||||
<Badge style="dash" color="success">Success</Badge>
|
||||
<Badge style="dash" color="warning">Warning</Badge>
|
||||
<Badge style="dash" color="error">Error</Badge>
|
||||
</Story>
|
||||
|
||||
<Story name="Soft">
|
||||
<Badge style="soft" color="primary">Primary</Badge>
|
||||
<Badge style="soft" color="secondary">Secondary</Badge>
|
||||
<Badge style="soft" color="accent">Accent</Badge>
|
||||
<Badge style="soft" color="neutral">Neutral</Badge>
|
||||
<Badge style="soft" color="info">Info</Badge>
|
||||
<Badge style="soft" color="success">Success</Badge>
|
||||
<Badge style="soft" color="warning">Warning</Badge>
|
||||
<Badge style="soft" color="error">Error</Badge>
|
||||
</Story>
|
||||
|
||||
<Story name="Ghost">
|
||||
<Badge style="ghost">Ghost</Badge>
|
||||
</Story>
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
<script lang="ts" module>
|
||||
export type BadgeStyle = 'outline' | 'dash' | 'soft' | 'ghost';
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import type { DaisyColor, DaisySize } from '$lib/types';
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
type Props = {
|
||||
children: Snippet;
|
||||
color?: DaisyColor;
|
||||
size?: DaisySize;
|
||||
style?: BadgeStyle;
|
||||
};
|
||||
|
||||
let { children, color, size, style }: Props = $props();
|
||||
</script>
|
||||
|
||||
<span
|
||||
class="badge"
|
||||
class:badge-primary={color === 'primary'}
|
||||
class:badge-secondary={color === 'secondary'}
|
||||
class:badge-accent={color === 'accent'}
|
||||
class:badge-neutral={color === 'neutral'}
|
||||
class:badge-info={color === 'info'}
|
||||
class:badge-success={color === 'success'}
|
||||
class:badge-warning={color === 'warning'}
|
||||
class:badge-error={color === 'error'}
|
||||
class:badge-xs={size === 'xs'}
|
||||
class:badge-sm={size === 'sm'}
|
||||
class:badge-md={size === 'md'}
|
||||
class:badge-lg={size === 'lg'}
|
||||
class:badge-xl={size === 'xl'}
|
||||
class:badge-outline={style === 'outline'}
|
||||
class:badge-dash={style === 'dash'}
|
||||
class:badge-soft={style === 'soft'}
|
||||
class:badge-ghost={style === 'ghost'}
|
||||
>
|
||||
{@render children?.()}
|
||||
</span>
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
export { default as Accordion } from './Accordion.svelte';
|
||||
export { default as Avatar } from './Avatar.svelte';
|
||||
export { default as AvatarGroup } from './AvatarGroup.svelte';
|
||||
export { default as Badge } from './Badge.svelte';
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import { User } from 'lucide-svelte';
|
||||
import InputField from './InputField.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Data Input/Input Field',
|
||||
component: InputField,
|
||||
argTypes: {
|
||||
block: {
|
||||
control: 'boolean',
|
||||
},
|
||||
color: {
|
||||
control: 'select',
|
||||
options: ['primary', 'secondary', 'accent', 'info', 'success', 'warning', 'error'],
|
||||
},
|
||||
disabled: {
|
||||
control: 'boolean',
|
||||
},
|
||||
start: { control: 'text' },
|
||||
end: { control: 'text' },
|
||||
placeholder: { control: 'text' },
|
||||
size: {
|
||||
control: 'select',
|
||||
options: ['xs', 'sm', 'md', 'lg', 'xl'],
|
||||
},
|
||||
style: {
|
||||
control: 'radio',
|
||||
options: [undefined, 'ghost'],
|
||||
},
|
||||
type: {
|
||||
control: 'select',
|
||||
options: ['email', 'password', 'search', 'tel', 'text', 'url'],
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<Story name="Default" args={{ name: 'text' }} />
|
||||
|
||||
<Story name="Labels">
|
||||
<div class="flex flex-col gap-2">
|
||||
<InputField name="text" start="Label" />
|
||||
<InputField name="text">
|
||||
{#snippet start()}
|
||||
<User />
|
||||
{/snippet}
|
||||
</InputField>
|
||||
<InputField name="text">
|
||||
{#snippet end()}
|
||||
<User />
|
||||
{/snippet}
|
||||
</InputField>
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="Colors">
|
||||
<div class="flex flex-col gap-2">
|
||||
<InputField name="text" color="primary" placeholder="Primary" />
|
||||
<InputField name="text" color="secondary" placeholder="Secondary" />
|
||||
<InputField name="text" color="accent" placeholder="Accent" />
|
||||
<InputField name="text" color="neutral" placeholder="Neutral" />
|
||||
<InputField name="text" color="info" placeholder="Info" />
|
||||
<InputField name="text" color="success" placeholder="Success" />
|
||||
<InputField name="text" color="warning" placeholder="Warning" />
|
||||
<InputField name="text" color="error" placeholder="Error" />
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="Sizes">
|
||||
<div class="flex flex-col gap-2">
|
||||
<InputField name="text" size="xs" placeholder="XS" />
|
||||
<InputField name="text" size="sm" placeholder="SM" />
|
||||
<InputField name="text" size="md" placeholder="MD" />
|
||||
<InputField name="text" size="lg" placeholder="LG" />
|
||||
<InputField name="text" size="xl" placeholder="XL" />
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="Disabled" args={{ name: 'text', placeholder: 'Disabled', disabled: true }} />
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
<script lang="ts" module>
|
||||
export type InputFieldStyle = 'ghost';
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import type { DaisyColor, DaisySize } from '$lib/types';
|
||||
import clsx from 'clsx';
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { HTMLInputTypeAttribute, SvelteHTMLElements } from 'svelte/elements';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
type Props = {
|
||||
block?: boolean;
|
||||
color?: DaisyColor;
|
||||
error?: string | Snippet;
|
||||
fade?: boolean;
|
||||
start?: string | Snippet;
|
||||
end?: string | Snippet;
|
||||
label?: string | Snippet;
|
||||
size?: DaisySize;
|
||||
style?: InputFieldStyle;
|
||||
type?: Extract<
|
||||
HTMLInputTypeAttribute,
|
||||
'email' | 'password' | 'search' | 'tel' | 'text' | 'url'
|
||||
>;
|
||||
} & Omit<SvelteHTMLElements['input'], 'type' | 'size'>;
|
||||
|
||||
let {
|
||||
block,
|
||||
class: className,
|
||||
color,
|
||||
start,
|
||||
end,
|
||||
size = 'md',
|
||||
style,
|
||||
...props
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="input flex items-center gap-2 transition-[width] delay-150 duration-300 ease-in-out"
|
||||
class:w-full={block}
|
||||
class:input-primary={color === 'primary'}
|
||||
class:input-secondary={color === 'secondary'}
|
||||
class:input-accent={color === 'accent'}
|
||||
class:input-neutral={color === 'neutral'}
|
||||
class:input-info={color === 'info'}
|
||||
class:input-success={color === 'success'}
|
||||
class:input-warning={color === 'warning'}
|
||||
class:input-error={color === 'error'}
|
||||
class:input-ghost={style === 'ghost'}
|
||||
class:input-xs={size === 'xs'}
|
||||
class:input-sm={size === 'sm'}
|
||||
class:input-md={size === 'md'}
|
||||
class:input-lg={size === 'lg'}
|
||||
class:input-xl={size === 'xl'}
|
||||
>
|
||||
{#if typeof start === 'string'}
|
||||
{start}
|
||||
{:else}
|
||||
{@render start?.()}
|
||||
{/if}
|
||||
<input {...props} class={twMerge('grow', clsx(className))} />
|
||||
{#if typeof end === 'string'}
|
||||
{end}
|
||||
{:else}
|
||||
{@render end?.()}
|
||||
{/if}
|
||||
</div>
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import Textarea from './Textarea.svelte';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Data Input/Textarea',
|
||||
component: Textarea,
|
||||
argTypes: {
|
||||
bordered: {
|
||||
control: 'boolean',
|
||||
},
|
||||
color: {
|
||||
control: 'select',
|
||||
options: [
|
||||
'default',
|
||||
'ghost',
|
||||
'primary',
|
||||
'secondary',
|
||||
'accent',
|
||||
'info',
|
||||
'success',
|
||||
'warning',
|
||||
'error',
|
||||
],
|
||||
},
|
||||
disabled: {
|
||||
control: 'boolean',
|
||||
},
|
||||
error: {
|
||||
control: 'text',
|
||||
},
|
||||
label: {
|
||||
control: 'text',
|
||||
},
|
||||
placeholder: {
|
||||
control: 'text',
|
||||
},
|
||||
size: {
|
||||
control: 'select',
|
||||
options: ['xs', 'sm', 'md', 'lg', 'xl'],
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template(props: ComponentProps<typeof Textarea>)}
|
||||
<Textarea {...props} />
|
||||
{/snippet}
|
||||
|
||||
<Story name="Default" args={{ label: 'Label' }} children={template} />
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { DaisyColor, DaisySize } from '$lib/types';
|
||||
import clsx from 'clsx';
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
type Props = {
|
||||
bordered?: boolean;
|
||||
color?: Omit<DaisyColor, 'neutral'>;
|
||||
error?: string | Snippet;
|
||||
label?: string | Snippet;
|
||||
resizable?: boolean | 'yes' | 'no' | 'x' | 'y';
|
||||
size?: DaisySize;
|
||||
} & SvelteHTMLElements['textarea'];
|
||||
let {
|
||||
bordered,
|
||||
class: className,
|
||||
color,
|
||||
error,
|
||||
label,
|
||||
resizable,
|
||||
size,
|
||||
...props
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<label class="form-control w-full">
|
||||
<div class="label">
|
||||
<span
|
||||
class="label-text flex items-center gap-2"
|
||||
class:text-primary={color === 'primary'}
|
||||
class:text-secondary={color === 'secondary'}
|
||||
class:text-accent={color === 'accent'}
|
||||
class:text-info={color === 'info'}
|
||||
class:text-success={color === 'success'}
|
||||
class:text-warning={color === 'warning'}
|
||||
class:text-error={color === 'error' || error}
|
||||
>
|
||||
{#if typeof label === 'string'}
|
||||
{label}
|
||||
{:else if label}
|
||||
{@render label()}
|
||||
{/if}
|
||||
</span>
|
||||
<span class="label-text-alt text-error font-semibold">
|
||||
{#if typeof error === 'string'}
|
||||
{error}
|
||||
{:else if error}
|
||||
{@render error()}
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
<textarea
|
||||
{...props}
|
||||
class={twMerge('textarea', clsx(className))}
|
||||
class:textarea-bordered={bordered}
|
||||
class:textarea-xs={size === 'xs'}
|
||||
class:textarea-sm={size === 'sm'}
|
||||
class:textarea-md={size === 'md'}
|
||||
class:textarea-lg={size === 'lg'}
|
||||
class:textarea-xl={size === 'xl'}
|
||||
class:textarea-ghost={color === 'ghost'}
|
||||
class:textarea-primary={color === 'primary'}
|
||||
class:textarea-secondary={color === 'secondary'}
|
||||
class:textarea-accent={color === 'accent'}
|
||||
class:textarea-info={color === 'info'}
|
||||
class:textarea-success={color === 'success'}
|
||||
class:textarea-warning={color === 'warning'}
|
||||
class:textarea-error={color === 'error' || error}
|
||||
class:resize={resizable === true || resizable === 'yes'}
|
||||
class:resize-x={resizable === 'x'}
|
||||
class:resize-y={resizable === 'y'}
|
||||
class:resize-none={resizable === false || resizable === 'no'}
|
||||
></textarea>
|
||||
</label>
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
export { default as Textarea } from './Textarea.svelte';
|
||||
export { default as TextInput } from './TextInput.svelte';
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import { Info } from 'lucide-svelte';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
import Alert from './Alert.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Feedback/Alert',
|
||||
component: Alert,
|
||||
argTypes: {
|
||||
status: { control: 'select', options: ['info', 'success', 'warning', 'error'] },
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template(props: ComponentProps<typeof Alert>)}
|
||||
<Alert {...props}>
|
||||
{#snippet icon()}
|
||||
<Info />
|
||||
{/snippet}
|
||||
<span>Hello world!</span>
|
||||
</Alert>
|
||||
{/snippet}
|
||||
|
||||
<Story name="Default" args={{}} children={template} />
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { DaisyColor } from '$lib/types';
|
||||
import clsx from 'clsx';
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
type Props = {
|
||||
children?: Snippet;
|
||||
icon?: Snippet;
|
||||
status?: Extract<DaisyColor, 'info' | 'success' | 'warning' | 'error'>;
|
||||
} & SvelteHTMLElements['div'];
|
||||
|
||||
let { children, class: className, icon, status: color, ...props }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
{...props}
|
||||
role="alert"
|
||||
class={twMerge('alert', clsx(className))}
|
||||
class:alert-info={color === 'info'}
|
||||
class:alert-success={color === 'success'}
|
||||
class:alert-warning={color === 'warning'}
|
||||
class:alert-error={color === 'error'}
|
||||
>
|
||||
{@render icon?.()}
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import Loader from './Loader.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Feedback/Loader',
|
||||
component: Loader,
|
||||
});
|
||||
</script>
|
||||
|
||||
<Story name="Default" args={{}} />
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
<script lang="ts"></script>
|
||||
|
||||
<span class="loader"></span>
|
||||
|
||||
<style>
|
||||
.loader {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border: 3px dotted #fff;
|
||||
border-style: solid solid dotted dotted;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
animation: rotation 2s linear infinite;
|
||||
}
|
||||
.loader::after {
|
||||
content: '';
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
border: 3px dotted #ff3d00;
|
||||
border-style: solid solid dotted;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
animation: rotationBack 1s linear infinite;
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
||||
@keyframes rotation {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes rotationBack {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
import Loading from './Loading.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Feedback/Loading',
|
||||
component: Loading,
|
||||
argTypes: {
|
||||
color: {
|
||||
control: 'select',
|
||||
options: [
|
||||
'neutral',
|
||||
'primary',
|
||||
'secondary',
|
||||
'accent',
|
||||
'info',
|
||||
'success',
|
||||
'warning',
|
||||
'error',
|
||||
],
|
||||
},
|
||||
size: { control: 'select', options: ['xs', 'sm', 'md', 'lg', 'xl'] },
|
||||
variant: {
|
||||
control: 'select',
|
||||
options: ['spinner', 'dots', 'ring', 'ball', 'bars', 'infinity'],
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template(props: ComponentProps<typeof Loading>)}
|
||||
<Loading {...props} />
|
||||
{/snippet}
|
||||
|
||||
<Story
|
||||
name="Default"
|
||||
args={{ color: 'neutral', size: 'md', variant: 'spinner' }}
|
||||
children={template}
|
||||
/>
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { DaisyColor, DaisySize } from '$lib/types';
|
||||
import clsx from 'clsx';
|
||||
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
type Props = {
|
||||
color?: Exclude<DaisyColor, 'ghost'>;
|
||||
size?: DaisySize;
|
||||
variant?: 'spinner' | 'dots' | 'ring' | 'ball' | 'bars' | 'infinity';
|
||||
} & Pick<SvelteHTMLElements['span'], 'class'>;
|
||||
let { class: className, color, size = 'md', variant = 'spinner' }: Props = $props();
|
||||
</script>
|
||||
|
||||
<span
|
||||
class={twMerge('loading', clsx(className))}
|
||||
class:text-primary={color === 'primary'}
|
||||
class:text-secondary={color === 'secondary'}
|
||||
class:text-accent={color === 'accent'}
|
||||
class:text-info={color === 'info'}
|
||||
class:text-success={color === 'success'}
|
||||
class:text-warning={color === 'warning'}
|
||||
class:text-error={color === 'error'}
|
||||
class:loading-xs={size === 'xs'}
|
||||
class:loading-sm={size === 'sm'}
|
||||
class:loading-md={size === 'md'}
|
||||
class:loading-lg={size === 'lg'}
|
||||
class:loading-xl={size === 'xl'}
|
||||
class:loading-spinner={variant === 'spinner'}
|
||||
class:loading-dots={variant === 'dots'}
|
||||
class:loading-ring={variant === 'ring'}
|
||||
class:loading-ball={variant === 'ball'}
|
||||
class:loading-bars={variant === 'bars'}
|
||||
class:loading-infinity={variant === 'infinity'}
|
||||
></span>
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
import Progress from './Progress.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Feedback/Progress',
|
||||
component: Progress,
|
||||
argTypes: {
|
||||
color: {
|
||||
control: 'select',
|
||||
options: ['primary', 'secondary', 'accent', 'info', 'success', 'warning', 'error'],
|
||||
},
|
||||
value: { control: 'number' },
|
||||
max: { control: 'number' },
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template(props: ComponentProps<typeof Progress>)}
|
||||
<Progress {...props} />
|
||||
{/snippet}
|
||||
|
||||
<Story name="Default" args={{}} children={template} />
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
<script lang="ts">
|
||||
import clsx from 'clsx';
|
||||
import type { DaisyColor } from '$lib/types';
|
||||
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
type Props = {
|
||||
color?: Exclude<DaisyColor, 'neutral' | 'ghost'>;
|
||||
} & SvelteHTMLElements['progress'];
|
||||
let { children, class: className, color, ...props }: Props = $props();
|
||||
</script>
|
||||
|
||||
<progress
|
||||
{...props}
|
||||
class={twMerge('progress', clsx(className))}
|
||||
class:progress-primary={color === 'primary'}
|
||||
class:progress-secondary={color === 'secondary'}
|
||||
class:progress-accent={color === 'accent'}
|
||||
class:progress-info={color === 'info'}
|
||||
class:progress-success={color === 'success'}
|
||||
class:progress-warning={color === 'warning'}
|
||||
class:progress-error={color === 'error'}
|
||||
>
|
||||
{@render children?.()}
|
||||
</progress>
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import Skeleton from './Skeleton.svelte';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Feedback/Skeleton',
|
||||
component: Skeleton,
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template(props: ComponentProps<typeof Skeleton>)}
|
||||
<Skeleton {...props} />
|
||||
{/snippet}
|
||||
|
||||
<Story name="Default" args={{ class: 'h-32 w-32' }} children={template} />
|
||||
|
||||
<Story name="Circle" args={{ class: 'h-32 w-32 rounded-full' }} children={template} />
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<script lang="ts">
|
||||
import clsx from 'clsx';
|
||||
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
type Props = SvelteHTMLElements['div'];
|
||||
let { children, class: className, ...props }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div {...props} class={twMerge('skeleton', clsx(className))}>{@render children?.()}</div>
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import Tooltip from './Tooltip.svelte';
|
||||
import { Button } from '../Actions';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Feedback/Tooltip',
|
||||
component: Tooltip,
|
||||
argTypes: {
|
||||
color: {
|
||||
control: 'select',
|
||||
options: ['primary', 'secondary', 'accent', 'info', 'success', 'warning', 'error'],
|
||||
},
|
||||
open: { control: 'boolean' },
|
||||
position: { control: 'select', options: ['top', 'bottom', 'left', 'right'] },
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template(props: ComponentProps<typeof Tooltip>)}
|
||||
<Tooltip {...props}>
|
||||
<Button color="primary">Button</Button>
|
||||
</Tooltip>
|
||||
{/snippet}
|
||||
|
||||
<Story name="Default" args={{ tip: "It's a button" }} children={template} />
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { DaisyColor } from '$lib/types';
|
||||
import clsx from 'clsx';
|
||||
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
type Props = {
|
||||
color?: Exclude<DaisyColor, 'neutral' | 'ghost'>;
|
||||
open?: boolean;
|
||||
position?: 'top' | 'bottom' | 'left' | 'right';
|
||||
tip?: string;
|
||||
} & SvelteHTMLElements['div'];
|
||||
let { children, class: className, color, open, position, tip, ...props }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
{...props}
|
||||
class={twMerge('tooltip', clsx(className))}
|
||||
class:tooltip-primary={color === 'primary'}
|
||||
class:tooltip-secondary={color === 'secondary'}
|
||||
class:tooltip-accent={color === 'accent'}
|
||||
class:tooltip-info={color === 'info'}
|
||||
class:tooltip-success={color === 'success'}
|
||||
class:tooltip-warning={color === 'warning'}
|
||||
class:tooltip-error={color === 'error'}
|
||||
class:tooltip-open={open}
|
||||
class:tooltip-top={position === 'top'}
|
||||
class:tooltip-bottom={position === 'bottom'}
|
||||
class:tooltip-left={position === 'left'}
|
||||
class:tooltip-right={position === 'right'}
|
||||
data-tip={tip}
|
||||
>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
export { default as Alert } from './Alert.svelte';
|
||||
export { default as Loader } from './Loader.svelte';
|
||||
export { default as Loading } from './Loading.svelte';
|
||||
export { default as Progress } from './Progress.svelte';
|
||||
export { default as Skeleton } from './Skeleton.svelte';
|
||||
export { default as Tooltip } from './Tooltip.svelte';
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import Divider from './Divider.svelte';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Layout/Divider',
|
||||
component: Divider,
|
||||
argTypes: {
|
||||
color: {
|
||||
control: 'select',
|
||||
options: [
|
||||
'neutral',
|
||||
'primary',
|
||||
'secondary',
|
||||
'accent',
|
||||
'info',
|
||||
'success',
|
||||
'warning',
|
||||
'error',
|
||||
],
|
||||
},
|
||||
direction: { control: 'select', options: ['horizontal', 'vertical'] },
|
||||
variant: { control: 'select', options: ['start', 'end'] },
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template(props: ComponentProps<typeof Divider>)}
|
||||
<div
|
||||
class="flex"
|
||||
class:flex-row={props.direction === 'horizontal'}
|
||||
class:flex-col={props.direction === 'vertical'}
|
||||
>
|
||||
<span>Side A</span>
|
||||
<Divider {...props} />
|
||||
<span>Side B</span>
|
||||
</div>
|
||||
{/snippet}
|
||||
|
||||
<Story name="Default" args={{}} children={template} />
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { DaisyColor } from '$lib/types';
|
||||
import clsx from 'clsx';
|
||||
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
type Props = {
|
||||
color?: Exclude<DaisyColor, 'ghost'>;
|
||||
direction?: 'horizontal' | 'vertical';
|
||||
variant?: 'start' | 'end';
|
||||
} & SvelteHTMLElements['div'];
|
||||
let { children, class: className, color, direction, variant, ...props }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
{...props}
|
||||
class={twMerge('divider', clsx(className))}
|
||||
class:divider-neutral={color === 'neutral'}
|
||||
class:divider-primary={color === 'primary'}
|
||||
class:divider-secondary={color === 'secondary'}
|
||||
class:divider-accent={color === 'accent'}
|
||||
class:divider-info={color === 'info'}
|
||||
class:divider-success={color === 'success'}
|
||||
class:divider-warning={color === 'warning'}
|
||||
class:divider-error={color === 'error'}
|
||||
class:divider-horizontal={direction === 'horizontal'}
|
||||
class:divider-vertical={direction === 'vertical'}
|
||||
class:divider-start={variant === 'start'}
|
||||
class:divider-end={variant === 'end'}
|
||||
>
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
|
@ -1 +0,0 @@
|
|||
export { default as Divider } from './Divider.svelte';
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
import Link from './Link.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Navigation/Link',
|
||||
component: Link,
|
||||
argTypes: {
|
||||
color: {
|
||||
control: 'select',
|
||||
options: [
|
||||
'primary',
|
||||
'secondary',
|
||||
'accent',
|
||||
'neutral',
|
||||
'info',
|
||||
'success',
|
||||
'warning',
|
||||
'error',
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template(props: ComponentProps<typeof Link>)}
|
||||
<Link {...props}>Hello world!</Link>
|
||||
{/snippet}
|
||||
|
||||
<Story name="Default" children={template} />
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { DaisyColor } from '$lib/types';
|
||||
import clsx from 'clsx';
|
||||
import type { SvelteHTMLElements } from 'svelte/elements';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
type Props = { color?: DaisyColor; hover?: boolean } & SvelteHTMLElements['a'];
|
||||
|
||||
let { children, class: className, color, hover, ...props }: Props = $props();
|
||||
</script>
|
||||
|
||||
<a
|
||||
{...props}
|
||||
class={twMerge('link', clsx(className))}
|
||||
class:link-primary={color === 'primary'}
|
||||
class:link-secondary={color === 'secondary'}
|
||||
class:link-accent={color === 'accent'}
|
||||
class:link-neutral={color === 'neutral'}
|
||||
class:link-info={color === 'info'}
|
||||
class:link-success={color === 'success'}
|
||||
class:link-warning={color === 'warning'}
|
||||
class:link-error={color === 'error'}
|
||||
class:link-hover={hover}>{@render children?.()}</a
|
||||
>
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import Navbar from './Navbar.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Navigation/Navbar',
|
||||
component: Navbar,
|
||||
});
|
||||
</script>
|
||||
|
||||
<Story name="Default">
|
||||
<Navbar>
|
||||
{#snippet start()}
|
||||
<button class="btn">Home</button>
|
||||
{/snippet}
|
||||
{#snippet center()}
|
||||
<h2 class="text-xl">Title</h2>
|
||||
{/snippet}
|
||||
{#snippet end()}
|
||||
<div class="avatar placeholder">
|
||||
<div class="bg-neutral text-neutral-content w-8 rounded-full">
|
||||
<span class="text-xs">UI</span>
|
||||
</div>
|
||||
</div>
|
||||
{/snippet}
|
||||
</Navbar>
|
||||
</Story>
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
let { start, center, end }: { start?: Snippet; center?: Snippet; end?: Snippet } = $props();
|
||||
</script>
|
||||
|
||||
<header class="navbar rounded-box bg-base-200 justify-between px-4">
|
||||
<div class="navbar-start">{@render start?.()}</div>
|
||||
<div class="navbar-center">{@render center?.()}</div>
|
||||
<div class="navbar-end">{@render end?.()}</div>
|
||||
</header>
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
import Navbar from './Navbar.svelte';
|
||||
|
||||
export default Navbar;
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
<script lang="ts">
|
||||
let { active, label, onclick } = $props();
|
||||
</script>
|
||||
|
||||
<input aria-label={label} type="radio" role="tab" class="tab" class:tab-active={active} {onclick} />
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<script module lang="ts">
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
import Tabs from './Tabs.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Navigation/Tabs',
|
||||
component: Tabs,
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
size: {
|
||||
control: 'select',
|
||||
options: ['xs', 'sm', 'md', 'lg', 'xl'],
|
||||
},
|
||||
variant: {
|
||||
control: 'select',
|
||||
options: ['none', 'bordered', 'lifted', 'boxed'],
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{#snippet template(args: Partial<ComponentProps<typeof Tabs>>)}
|
||||
<Tabs tabs={['Tab 1', 'Tab 2']} {...args} />
|
||||
{/snippet}
|
||||
|
||||
<Story name="Default" args={{}} children={template} />
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<script lang="ts">
|
||||
import type { DaisySize } from '$lib/types';
|
||||
import Tab from './Tab.svelte';
|
||||
|
||||
type Props = {
|
||||
size?: DaisySize;
|
||||
tabs: string[];
|
||||
selected?: number;
|
||||
variant?: 'none' | 'bordered' | 'lifted' | 'boxed';
|
||||
};
|
||||
|
||||
let { size, tabs, selected: value = $bindable(0), variant = 'none' }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
role="tablist"
|
||||
class="tabs w-full"
|
||||
class:tabs-xs={size === 'xs'}
|
||||
class:tabs-sm={size === 'sm'}
|
||||
class:tabs-lg={size === 'lg'}
|
||||
class:tabs-xl={size === 'xl'}
|
||||
class:tabs-bordered={variant === 'bordered'}
|
||||
class:tabs-lifted={variant === 'lifted'}
|
||||
class:tabs-boxed={variant === 'boxed'}
|
||||
>
|
||||
{#each tabs as tab, index}
|
||||
{#key [tab, value]}
|
||||
<Tab
|
||||
active={index === value}
|
||||
label={tab}
|
||||
onclick={() => {
|
||||
value = index;
|
||||
}}
|
||||
/>
|
||||
{/key}
|
||||
{/each}
|
||||
</div>
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
import Tabs from './Tabs.svelte';
|
||||
|
||||
export default Tabs;
|
||||
export { default as Tabs } from './Tabs.svelte';
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
import Navbar from './Navbar';
|
||||
import Tabs from './Tabs';
|
||||
|
||||
export { default as Link } from './Link.svelte';
|
||||
export { Navbar, Tabs };
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
export * from './Actions/';
|
||||
export * from './DataInput/';
|
||||
export * from './DataDisplay';
|
||||
export * from './Feedback/';
|
||||
export * from './Layout/';
|
||||
export * from './Navigation/';
|
||||
|
|
@ -1 +0,0 @@
|
|||
export {};
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
export type DaisyColor =
|
||||
| 'neutral'
|
||||
| 'primary'
|
||||
| 'secondary'
|
||||
| 'accent'
|
||||
| 'info'
|
||||
| 'success'
|
||||
| 'warning'
|
||||
| 'error';
|
||||
|
|
@ -1 +0,0 @@
|
|||
export type DaisySize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
export * from './daisy-colors';
|
||||
export * from './daisy-sizes';
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||
// for more information about preprocessors
|
||||
preprocess: vitePreprocess(),
|
||||
|
||||
kit: {},
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
import type { Config } from 'tailwindcss';
|
||||
|
||||
export default {
|
||||
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||
} satisfies Config;
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"moduleResolution": "bundler"
|
||||
}
|
||||
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
|
||||
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
|
||||
//
|
||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
import { defineConfig } from 'vitest/config';
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()],
|
||||
|
||||
test: {
|
||||
include: ['src/**/*.{test,spec}.{js,ts}'],
|
||||
},
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue