mirror of
https://github.com/wireadmin/wireadmin
synced 2025-05-15 09:05:44 +00:00
add tailwindcss
and shadcn
This commit is contained in:
parent
686172b27b
commit
414538daf6
@ -1,3 +1,3 @@
|
|||||||
.idea
|
.idea
|
||||||
node_modules
|
.ignore
|
||||||
assets
|
assets
|
||||||
|
70
Dockerfile
70
Dockerfile
@ -1,5 +1,6 @@
|
|||||||
FROM node:alpine as base
|
FROM oven/bun:alpine as base
|
||||||
WORKDIR /app
|
LABEL Maintainer="Shahrad Elahi <https://github.com/shahradelahi>"
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
ENV TZ=UTC
|
ENV TZ=UTC
|
||||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||||
@ -7,6 +8,16 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
|||||||
COPY --from=chriswayg/tor-alpine:latest /usr/local/bin/obfs4proxy /usr/local/bin/obfs4proxy
|
COPY --from=chriswayg/tor-alpine:latest /usr/local/bin/obfs4proxy /usr/local/bin/obfs4proxy
|
||||||
COPY --from=chriswayg/tor-alpine:latest /usr/local/bin/meek-server /usr/local/bin/meek-server
|
COPY --from=chriswayg/tor-alpine:latest /usr/local/bin/meek-server /usr/local/bin/meek-server
|
||||||
|
|
||||||
|
# Set the mirror list
|
||||||
|
RUN echo "https://uk.alpinelinux.org/alpine/latest-stable/main" > /etc/apk/repositories && \
|
||||||
|
echo "https://mirror.bardia.tech/alpine/latest-stable/main" >> /etc/apk/repositories && \
|
||||||
|
echo "https://uk.alpinelinux.org/alpine/latest-stable/community" >> /etc/apk/repositories &&\
|
||||||
|
echo "https://mirror.bardia.tech/alpine/latest-stable/community" >> /etc/apk/repositories
|
||||||
|
|
||||||
|
# Update and upgrade packages
|
||||||
|
RUN apk update && apk upgrade
|
||||||
|
|
||||||
|
# Install required packages
|
||||||
RUN apk add -U --no-cache \
|
RUN apk add -U --no-cache \
|
||||||
iproute2 iptables net-tools \
|
iproute2 iptables net-tools \
|
||||||
screen vim curl bash \
|
screen vim curl bash \
|
||||||
@ -16,42 +27,39 @@ RUN apk add -U --no-cache \
|
|||||||
tor \
|
tor \
|
||||||
redis
|
redis
|
||||||
|
|
||||||
|
# Clear cache
|
||||||
|
RUN rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
FROM node:alpine as builder
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
COPY /src/package.json /src/package-lock.json ./
|
FROM base AS deps
|
||||||
RUN npm install
|
|
||||||
|
|
||||||
|
RUN mkdir -p /temp/dev
|
||||||
|
COPY web/package.json web/bun.lockb /temp/dev/
|
||||||
|
RUN cd /temp/dev && bun install --frozen-lockfile
|
||||||
|
|
||||||
|
RUN mkdir -p /temp/prod
|
||||||
|
COPY web/package.json web/bun.lockb /temp/prod/
|
||||||
|
RUN cd /temp/prod && bun install --frozen-lockfile --production
|
||||||
|
|
||||||
|
|
||||||
|
FROM base AS build
|
||||||
|
COPY --from=deps /temp/dev/node_modules node_modules
|
||||||
|
COPY web .
|
||||||
|
|
||||||
|
# build
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
COPY /src/ .
|
RUN bun run build
|
||||||
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
|
|
||||||
FROM base
|
FROM base AS release
|
||||||
WORKDIR /app
|
|
||||||
|
COPY --from=deps /temp/prod/node_modules node_modules
|
||||||
|
COPY --from=build /usr/src/app/build .
|
||||||
|
COPY --from=build /usr/src/app/package.json .
|
||||||
|
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
LABEL Maintainer="Shahrad Elahi <https://github.com/shahradelahi>"
|
# run the app
|
||||||
|
USER bun
|
||||||
COPY /config/torrc /etc/tor/torrc
|
|
||||||
|
|
||||||
COPY --from=builder /app/.next ./.next
|
|
||||||
COPY --from=builder /app/next.config.js ./next.config.js
|
|
||||||
COPY --from=builder /app/public ./public
|
|
||||||
|
|
||||||
COPY /src/package.json /src/package-lock.json ./
|
|
||||||
RUN npm install --omit dev
|
|
||||||
|
|
||||||
EXPOSE 3000/tcp
|
EXPOSE 3000/tcp
|
||||||
|
CMD [ "bun", "start" ]
|
||||||
HEALTHCHECK --interval=60s --timeout=10s --start-period=5s --retries=3 \
|
|
||||||
CMD curl -f http://127.0.0.1:3000/api/healthcheck || exit 1
|
|
||||||
|
|
||||||
COPY docker-entrypoint.sh /usr/bin/entrypoint
|
|
||||||
RUN chmod +x /usr/bin/entrypoint
|
|
||||||
ENTRYPOINT ["/usr/bin/entrypoint"]
|
|
||||||
|
|
||||||
CMD ["npm", "run", "start"]
|
|
||||||
|
@ -8,6 +8,16 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
|||||||
COPY --from=chriswayg/tor-alpine:latest /usr/local/bin/obfs4proxy /usr/local/bin/obfs4proxy
|
COPY --from=chriswayg/tor-alpine:latest /usr/local/bin/obfs4proxy /usr/local/bin/obfs4proxy
|
||||||
COPY --from=chriswayg/tor-alpine:latest /usr/local/bin/meek-server /usr/local/bin/meek-server
|
COPY --from=chriswayg/tor-alpine:latest /usr/local/bin/meek-server /usr/local/bin/meek-server
|
||||||
|
|
||||||
|
# Set the mirror list
|
||||||
|
RUN echo "https://uk.alpinelinux.org/alpine/latest-stable/main" > /etc/apk/repositories && \
|
||||||
|
echo "https://mirror.bardia.tech/alpine/latest-stable/main" >> /etc/apk/repositories && \
|
||||||
|
echo "https://uk.alpinelinux.org/alpine/latest-stable/community" >> /etc/apk/repositories &&\
|
||||||
|
echo "https://mirror.bardia.tech/alpine/latest-stable/community" >> /etc/apk/repositories
|
||||||
|
|
||||||
|
# Update and upgrade packages
|
||||||
|
RUN apk update && apk upgrade
|
||||||
|
|
||||||
|
# Install required packages
|
||||||
RUN apk add -U --no-cache \
|
RUN apk add -U --no-cache \
|
||||||
iproute2 iptables net-tools \
|
iproute2 iptables net-tools \
|
||||||
screen vim curl bash \
|
screen vim curl bash \
|
||||||
@ -17,36 +27,22 @@ RUN apk add -U --no-cache \
|
|||||||
tor \
|
tor \
|
||||||
redis
|
redis
|
||||||
|
|
||||||
|
# Clear cache
|
||||||
|
RUN rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
|
||||||
FROM base AS deps
|
FROM base AS deps
|
||||||
|
|
||||||
RUN mkdir -p /temp/dev
|
RUN mkdir -p /temp/dev
|
||||||
COPY web/package.json web/bun.lockb /temp/dev/
|
COPY web/package.json web/bun.lockb web/node_modules* /temp/dev/
|
||||||
RUN cd /temp/dev && bun install --frozen-lockfile
|
RUN cd /temp/dev && bun install --frozen-lockfile
|
||||||
|
|
||||||
RUN mkdir -p /temp/prod
|
|
||||||
COPY web/package.json web/bun.lockb /temp/prod/
|
|
||||||
RUN cd /temp/prod && bun install --frozen-lockfile --production
|
|
||||||
|
|
||||||
|
FROM base AS runner
|
||||||
|
|
||||||
FROM install AS build
|
|
||||||
COPY --from=deps /temp/dev/node_modules node_modules
|
COPY --from=deps /temp/dev/node_modules node_modules
|
||||||
COPY web .
|
COPY web .
|
||||||
|
|
||||||
# build
|
# run the appc
|
||||||
ENV NODE_ENV=production
|
EXPOSE 5173/tcp
|
||||||
RUN bun run build
|
CMD [ "bun", "dev", "--host" ]
|
||||||
|
|
||||||
|
|
||||||
FROM base AS release
|
|
||||||
|
|
||||||
COPY --from=deps /temp/prod/node_modules node_modules
|
|
||||||
COPY --from=build /usr/src/app/build .
|
|
||||||
COPY --from=build /usr/src/app/package.json .
|
|
||||||
|
|
||||||
ENV NODE_ENV=production
|
|
||||||
|
|
||||||
# run the app
|
|
||||||
USER bun
|
|
||||||
EXPOSE 3000/tcp
|
|
||||||
CMD [ "bun", "start" ]
|
|
@ -3,7 +3,9 @@ services:
|
|||||||
wireadmin:
|
wireadmin:
|
||||||
image: wireadmin
|
image: wireadmin
|
||||||
volumes:
|
volumes:
|
||||||
- ./src/:/app/
|
- ./web/:/usr/src/app/
|
||||||
|
ports:
|
||||||
|
- "5173:5173"
|
||||||
environment:
|
environment:
|
||||||
- UI_PASSWORD=password
|
- UI_PASSWORD=password
|
||||||
- WG_HOST=192.168.1.102
|
- WG_HOST=192.168.1.102
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"description": "",
|
"description": "",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:image": "DOCKER_BUILDKIT=1 docker build --tag wireadmin -f Dockerfile-Dev .",
|
"dev:image": "DOCKER_BUILDKIT=1 docker build --tag wireadmin -f Dockerfile-Dev .",
|
||||||
"dev": "docker-compose -f docker-compose.yml -f docker-compose.dev.yml up; docker rm -f wireadmin"
|
"dev": "docker compose rm -fsv && docker compose -f docker-compose.yml -f docker-compose.dev.yml up && docker compose rm -fsv"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "Shahrad Elahi <https://github.com/shahradelahi>",
|
"author": "Shahrad Elahi <https://github.com/shahradelahi>",
|
||||||
|
5
pnpm-lock.yaml
Normal file
5
pnpm-lock.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
lockfileVersion: '6.0'
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"useTabs": false,
|
"useTabs": true,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "none",
|
"trailingComma": "none",
|
||||||
"printWidth": 100,
|
"printWidth": 100,
|
||||||
@ -9,7 +9,6 @@
|
|||||||
"pluginSearchDirs": [
|
"pluginSearchDirs": [
|
||||||
"."
|
"."
|
||||||
],
|
],
|
||||||
"tabWidth": 2,
|
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": "*.svelte",
|
"files": "*.svelte",
|
||||||
|
BIN
web/bun.lockb
BIN
web/bun.lockb
Binary file not shown.
13
web/components.json
Normal file
13
web/components.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://shadcn-svelte.com/schema.json",
|
||||||
|
"style": "default",
|
||||||
|
"tailwind": {
|
||||||
|
"config": "tailwind.config.js",
|
||||||
|
"css": "src/app.postcss",
|
||||||
|
"baseColor": "gray"
|
||||||
|
},
|
||||||
|
"aliases": {
|
||||||
|
"components": "$lib/components",
|
||||||
|
"utils": "$lib/utils"
|
||||||
|
}
|
||||||
|
}
|
@ -8,20 +8,32 @@
|
|||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||||
|
"test": "vitest",
|
||||||
"lint": "prettier --plugin-search-dir . --check .",
|
"lint": "prettier --plugin-search-dir . --check .",
|
||||||
"format": "prettier --plugin-search-dir . --write .",
|
"format": "prettier --plugin-search-dir . --write ."
|
||||||
"start": "bun ./build/index.js"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-auto": "^2.0.0",
|
"@sveltejs/adapter-auto": "^2.0.0",
|
||||||
"@sveltejs/kit": "^1.20.4",
|
"@sveltejs/kit": "^1.20.4",
|
||||||
|
"autoprefixer": "^10.4.14",
|
||||||
|
"postcss": "^8.4.24",
|
||||||
|
"postcss-load-config": "^4.0.1",
|
||||||
"prettier": "^2.8.0",
|
"prettier": "^2.8.0",
|
||||||
"prettier-plugin-svelte": "^2.10.1",
|
"prettier-plugin-svelte": "^2.10.1",
|
||||||
"svelte": "^4.0.5",
|
"svelte": "^4.0.5",
|
||||||
"svelte-check": "^3.4.3",
|
"svelte-check": "^3.4.3",
|
||||||
|
"tailwindcss": "^3.3.2",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
"typescript": "^5.0.0",
|
"typescript": "^5.0.0",
|
||||||
"vite": "^4.4.2"
|
"vite": "^4.4.2",
|
||||||
|
"vitest": "^0.34.0"
|
||||||
},
|
},
|
||||||
"type": "module"
|
"type": "module",
|
||||||
|
"dependencies": {
|
||||||
|
"bits-ui": "^0.9.0",
|
||||||
|
"clsx": "^2.0.0",
|
||||||
|
"lucide-svelte": "^0.292.0",
|
||||||
|
"tailwind-merge": "^2.0.0",
|
||||||
|
"tailwind-variants": "^0.1.18"
|
||||||
|
}
|
||||||
}
|
}
|
13
web/postcss.config.cjs
Normal file
13
web/postcss.config.cjs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
const tailwindcss = require('tailwindcss');
|
||||||
|
const autoprefixer = require('autoprefixer');
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
plugins: [
|
||||||
|
//Some plugins, like tailwindcss/nesting, need to run before Tailwind,
|
||||||
|
tailwindcss(),
|
||||||
|
//But others, like autoprefixer, need to run after,
|
||||||
|
autoprefixer
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = config;
|
78
web/src/app.postcss
Normal file
78
web/src/app.postcss
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
:root {
|
||||||
|
--background: 0 0% 100%;
|
||||||
|
--foreground: 224 71.4% 4.1%;
|
||||||
|
|
||||||
|
--muted: 220 14.3% 95.9%;
|
||||||
|
--muted-foreground: 220 8.9% 46.1%;
|
||||||
|
|
||||||
|
--popover: 0 0% 100%;
|
||||||
|
--popover-foreground: 224 71.4% 4.1%;
|
||||||
|
|
||||||
|
--card: 0 0% 100%;
|
||||||
|
--card-foreground: 224 71.4% 4.1%;
|
||||||
|
|
||||||
|
--border: 220 13% 91%;
|
||||||
|
--input: 220 13% 91%;
|
||||||
|
|
||||||
|
--primary: 220.9 39.3% 11%;
|
||||||
|
--primary-foreground: 210 20% 98%;
|
||||||
|
|
||||||
|
--secondary: 220 14.3% 95.9%;
|
||||||
|
--secondary-foreground: 220.9 39.3% 11%;
|
||||||
|
|
||||||
|
--accent: 220 14.3% 95.9%;
|
||||||
|
--accent-foreground: 220.9 39.3% 11%;
|
||||||
|
|
||||||
|
--destructive: 0 84.2% 60.2%;
|
||||||
|
--destructive-foreground: 210 20% 98%;
|
||||||
|
|
||||||
|
--ring: 224 71.4% 4.1%;
|
||||||
|
|
||||||
|
--radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--background: 224 71.4% 4.1%;
|
||||||
|
--foreground: 210 20% 98%;
|
||||||
|
|
||||||
|
--muted: 215 27.9% 16.9%;
|
||||||
|
--muted-foreground: 217.9 10.6% 64.9%;
|
||||||
|
|
||||||
|
--popover: 224 71.4% 4.1%;
|
||||||
|
--popover-foreground: 210 20% 98%;
|
||||||
|
|
||||||
|
--card: 224 71.4% 4.1%;
|
||||||
|
--card-foreground: 210 20% 98%;
|
||||||
|
|
||||||
|
--border: 215 27.9% 16.9%;
|
||||||
|
--input: 215 27.9% 16.9%;
|
||||||
|
|
||||||
|
--primary: 210 20% 98%;
|
||||||
|
--primary-foreground: 220.9 39.3% 11%;
|
||||||
|
|
||||||
|
--secondary: 215 27.9% 16.9%;
|
||||||
|
--secondary-foreground: 210 20% 98%;
|
||||||
|
|
||||||
|
--accent: 215 27.9% 16.9%;
|
||||||
|
--accent-foreground: 210 20% 98%;
|
||||||
|
|
||||||
|
--destructive: 0 62.8% 30.6%;
|
||||||
|
--destructive-foreground: 210 20% 98%;
|
||||||
|
|
||||||
|
--ring: 216 12.2% 83.9%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
* {
|
||||||
|
@apply border-border;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
@apply bg-background text-foreground;
|
||||||
|
}
|
||||||
|
}
|
7
web/src/index.test.ts
Normal file
7
web/src/index.test.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
|
describe('sum test', () => {
|
||||||
|
it('adds 1 + 2 to equal 3', () => {
|
||||||
|
expect(1 + 2).toBe(3);
|
||||||
|
});
|
||||||
|
});
|
24
web/src/lib/components/ui/button/button.svelte
Normal file
24
web/src/lib/components/ui/button/button.svelte
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
import { buttonVariants, type Events, type Props } from '.';
|
||||||
|
|
||||||
|
type $$Props = Props;
|
||||||
|
type $$Events = Events;
|
||||||
|
|
||||||
|
let className: $$Props['class'] = undefined;
|
||||||
|
export let variant: $$Props['variant'] = 'default';
|
||||||
|
export let size: $$Props['size'] = 'default';
|
||||||
|
export let builders: $$Props['builders'] = [];
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ButtonPrimitive.Root
|
||||||
|
{builders}
|
||||||
|
class={cn(buttonVariants({ variant, size, className }))}
|
||||||
|
type="button"
|
||||||
|
{...$$restProps}
|
||||||
|
on:click
|
||||||
|
on:keydown
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</ButtonPrimitive.Root>
|
51
web/src/lib/components/ui/button/index.ts
Normal file
51
web/src/lib/components/ui/button/index.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import Root from './button.svelte';
|
||||||
|
import { tv, type VariantProps } from 'tailwind-variants';
|
||||||
|
import type { Button as ButtonPrimitive } from 'bits-ui';
|
||||||
|
|
||||||
|
const buttonVariants = tv({
|
||||||
|
base: 'inline-flex items-center justify-center rounded-md text-sm font-medium whitespace-nowrap ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
||||||
|
destructive:
|
||||||
|
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
||||||
|
outline:
|
||||||
|
'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
|
||||||
|
secondary:
|
||||||
|
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
||||||
|
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
||||||
|
link: 'text-primary underline-offset-4 hover:underline'
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
default: 'h-10 px-4 py-2',
|
||||||
|
sm: 'h-9 rounded-md px-3',
|
||||||
|
lg: 'h-11 rounded-md px-8',
|
||||||
|
icon: 'h-10 w-10'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: 'default',
|
||||||
|
size: 'default'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
type Variant = VariantProps<typeof buttonVariants>['variant'];
|
||||||
|
type Size = VariantProps<typeof buttonVariants>['size'];
|
||||||
|
|
||||||
|
type Props = ButtonPrimitive.Props & {
|
||||||
|
variant?: Variant;
|
||||||
|
size?: Size;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Events = ButtonPrimitive.Events;
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
type Props,
|
||||||
|
type Events,
|
||||||
|
//
|
||||||
|
Root as Button,
|
||||||
|
type Props as ButtonProps,
|
||||||
|
type Events as ButtonEvents,
|
||||||
|
buttonVariants
|
||||||
|
};
|
62
web/src/lib/utils.ts
Normal file
62
web/src/lib/utils.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { type ClassValue, clsx } from 'clsx';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
import { cubicOut } from 'svelte/easing';
|
||||||
|
import type { TransitionConfig } from 'svelte/transition';
|
||||||
|
|
||||||
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
return twMerge(clsx(inputs));
|
||||||
|
}
|
||||||
|
|
||||||
|
type FlyAndScaleParams = {
|
||||||
|
y?: number;
|
||||||
|
x?: number;
|
||||||
|
start?: number;
|
||||||
|
duration?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const flyAndScale = (
|
||||||
|
node: Element,
|
||||||
|
params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }
|
||||||
|
): TransitionConfig => {
|
||||||
|
const style = getComputedStyle(node);
|
||||||
|
const transform = style.transform === 'none' ? '' : style.transform;
|
||||||
|
|
||||||
|
const scaleConversion = (
|
||||||
|
valueA: number,
|
||||||
|
scaleA: [ number, number ],
|
||||||
|
scaleB: [ number, number ]
|
||||||
|
) => {
|
||||||
|
const [ minA, maxA ] = scaleA;
|
||||||
|
const [ minB, maxB ] = scaleB;
|
||||||
|
|
||||||
|
const percentage = (valueA - minA) / (maxA - minA);
|
||||||
|
const valueB = percentage * (maxB - minB) + minB;
|
||||||
|
|
||||||
|
return valueB;
|
||||||
|
};
|
||||||
|
|
||||||
|
const styleToString = (
|
||||||
|
style: Record<string, number | string | undefined>
|
||||||
|
): string => {
|
||||||
|
return Object.keys(style).reduce((str, key) => {
|
||||||
|
if (style[key] === undefined) return str;
|
||||||
|
return str + `${key}:${style[key]};`;
|
||||||
|
}, '');
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
duration: params.duration ?? 200,
|
||||||
|
delay: 0,
|
||||||
|
css: (t) => {
|
||||||
|
const y = scaleConversion(t, [ 0, 1 ], [ params.y ?? 5, 0 ]);
|
||||||
|
const x = scaleConversion(t, [ 0, 1 ], [ params.x ?? 0, 0 ]);
|
||||||
|
const scale = scaleConversion(t, [ 0, 1 ], [ params.start ?? 0.95, 1 ]);
|
||||||
|
|
||||||
|
return styleToString({
|
||||||
|
transform: `${transform} translate3d(${x}px, ${y}px, 0) scale(${scale})`,
|
||||||
|
opacity: t
|
||||||
|
});
|
||||||
|
},
|
||||||
|
easing: cubicOut
|
||||||
|
};
|
||||||
|
};
|
1
web/src/routes/+layout.svelte
Normal file
1
web/src/routes/+layout.svelte
Normal file
@ -0,0 +1 @@
|
|||||||
|
<script>import '../app.postcss';</script><slot></slot>
|
@ -1,2 +1,8 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
</script>
|
||||||
|
|
||||||
<h1>Welcome to SvelteKit</h1>
|
<h1>Welcome to SvelteKit</h1>
|
||||||
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
|
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
|
||||||
|
|
||||||
|
<Button variant="outline">Button</Button>
|
@ -5,13 +5,16 @@ import { vitePreprocess } from '@sveltejs/kit/vite';
|
|||||||
const config = {
|
const config = {
|
||||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||||
// for more information about preprocessors
|
// for more information about preprocessors
|
||||||
preprocess: vitePreprocess(),
|
preprocess: [ vitePreprocess({}) ],
|
||||||
|
|
||||||
kit: {
|
kit: {
|
||||||
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
||||||
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
|
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
|
||||||
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
||||||
adapter: adapter()
|
adapter: adapter(),
|
||||||
|
alias: {
|
||||||
|
$lib: './src/lib'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
64
web/tailwind.config.js
Normal file
64
web/tailwind.config.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import { fontFamily } from 'tailwindcss/defaultTheme';
|
||||||
|
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
const config = {
|
||||||
|
darkMode: [ 'class' ],
|
||||||
|
content: [ './src/**/*.{html,js,svelte,ts}' ],
|
||||||
|
safelist: [ 'dark' ],
|
||||||
|
theme: {
|
||||||
|
container: {
|
||||||
|
center: true,
|
||||||
|
padding: '2rem',
|
||||||
|
screens: {
|
||||||
|
'2xl': '1400px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
border: 'hsl(var(--border) / <alpha-value>)',
|
||||||
|
input: 'hsl(var(--input) / <alpha-value>)',
|
||||||
|
ring: 'hsl(var(--ring) / <alpha-value>)',
|
||||||
|
background: 'hsl(var(--background) / <alpha-value>)',
|
||||||
|
foreground: 'hsl(var(--foreground) / <alpha-value>)',
|
||||||
|
primary: {
|
||||||
|
DEFAULT: 'hsl(var(--primary) / <alpha-value>)',
|
||||||
|
foreground: 'hsl(var(--primary-foreground) / <alpha-value>)'
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
DEFAULT: 'hsl(var(--secondary) / <alpha-value>)',
|
||||||
|
foreground: 'hsl(var(--secondary-foreground) / <alpha-value>)'
|
||||||
|
},
|
||||||
|
destructive: {
|
||||||
|
DEFAULT: 'hsl(var(--destructive) / <alpha-value>)',
|
||||||
|
foreground: 'hsl(var(--destructive-foreground) / <alpha-value>)'
|
||||||
|
},
|
||||||
|
muted: {
|
||||||
|
DEFAULT: 'hsl(var(--muted) / <alpha-value>)',
|
||||||
|
foreground: 'hsl(var(--muted-foreground) / <alpha-value>)'
|
||||||
|
},
|
||||||
|
accent: {
|
||||||
|
DEFAULT: 'hsl(var(--accent) / <alpha-value>)',
|
||||||
|
foreground: 'hsl(var(--accent-foreground) / <alpha-value>)'
|
||||||
|
},
|
||||||
|
popover: {
|
||||||
|
DEFAULT: 'hsl(var(--popover) / <alpha-value>)',
|
||||||
|
foreground: 'hsl(var(--popover-foreground) / <alpha-value>)'
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
DEFAULT: 'hsl(var(--card) / <alpha-value>)',
|
||||||
|
foreground: 'hsl(var(--card-foreground) / <alpha-value>)'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
borderRadius: {
|
||||||
|
lg: 'var(--radius)',
|
||||||
|
md: 'calc(var(--radius) - 2px)',
|
||||||
|
sm: 'calc(var(--radius) - 4px)'
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
sans: [ ...fontFamily.sans ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
@ -1,6 +1,9 @@
|
|||||||
import { sveltekit } from '@sveltejs/kit/vite';
|
import { sveltekit } from '@sveltejs/kit/vite';
|
||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [ sveltekit() ]
|
plugins: [ sveltekit() ],
|
||||||
|
test: {
|
||||||
|
include: [ 'src/**/*.{test,spec}.{js,ts}' ]
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user