#32 initial dynamic search packages

This commit is contained in:
neil 2022-11-27 15:08:25 +08:00
parent 1423d3bb15
commit e7e23c3af3
67 changed files with 1357 additions and 1091 deletions

View file

@ -40,6 +40,26 @@ jobs:
message-id: preview-comment-${{needs.changes.outputs.preview_folder}} message-id: preview-comment-${{needs.changes.outputs.preview_folder}}
message: | message: |
no preview or changes related to UI no preview or changes related to UI
test:
needs: changes
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
persist-credentials: false
- uses: pnpm/action-setup@v2
with:
version: 7
- name: setup node
uses: actions/setup-node@v1
with:
node-version: 16
cache: 'pnpm'
cache-dependency-path: pnpm-lock.yaml
- name: install app dependencies
run: pnpm install
- name: lint
run: pnpm -r lint
build_svelte: build_svelte:
needs: changes needs: changes
if: needs.changes.outputs.svelte == 'true' if: needs.changes.outputs.svelte == 'true'
@ -62,6 +82,8 @@ jobs:
with: with:
toolchain: stable toolchain: stable
- name: install app dependencies and build it - name: install app dependencies and build it
env:
BUILD_FOR: preview
run: pnpm install && pnpm --filter gui build run: pnpm install && pnpm --filter gui build
- uses: aws-actions/configure-aws-credentials@v1 - uses: aws-actions/configure-aws-credentials@v1
with: with:

View file

@ -11,3 +11,4 @@ node_modules
pnpm-lock.yaml pnpm-lock.yaml
package-lock.json package-lock.json
yarn.lock yarn.lock
src-tauri/target/*

View file

@ -1,23 +1,25 @@
module.exports = { module.exports = {
root: true, root: true,
parser: '@typescript-eslint/parser', parser: '@typescript-eslint/parser',
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
plugins: ['svelte3', '@typescript-eslint'], plugins: ['svelte3', '@typescript-eslint'],
ignorePatterns: ['*.cjs'], ignorePatterns: ['*.cjs'],
overrides: [{ overrides: [
files: ['*.svelte'], {
processor: 'svelte3/svelte3' files: ['*.svelte'],
}], processor: 'svelte3/svelte3'
settings: { }
'svelte3/typescript': () => require('typescript') ],
}, settings: {
parserOptions: { 'svelte3/typescript': () => require('typescript')
sourceType: 'module', },
ecmaVersion: 2020 parserOptions: {
}, sourceType: 'module',
env: { ecmaVersion: 2020
browser: true, },
es2017: true, env: {
node: true browser: true,
} es2017: true,
node: true
}
}; };

View file

@ -11,3 +11,11 @@ node_modules
pnpm-lock.yaml pnpm-lock.yaml
package-lock.json package-lock.json
yarn.lock yarn.lock
build
/src-tauri/src/*
/src-tauri/icons/*
/src-tauri/target/**/*
/src-tauri/build/*
/src-tauri/Cargo.lock
/src-tauri/Cargo.toml
src-tauri

View file

@ -1,4 +1,5 @@
{ {
"tabWidth": 2,
"useTabs": true, "useTabs": true,
"singleQuote": true, "singleQuote": true,
"trailingComma": "none", "trailingComma": "none",

View file

@ -1,4 +1,5 @@
# @tea/gui # @tea/gui
Desktop app of [tea](https://tea.xyz) for installing packages/softwares Desktop app of [tea](https://tea.xyz) for installing packages/softwares
More interesting and possibly updated documentations are at this [NOTION](https://www.notion.so/teaxyz/tea-gui-fdd9f50aa980432fa370b2cf6a03cb50) page. It is ideal to review it also, its more updated. More interesting and possibly updated documentations are at this [NOTION](https://www.notion.so/teaxyz/tea-gui-fdd9f50aa980432fa370b2cf6a03cb50) page. It is ideal to review it also, its more updated.
@ -29,5 +30,4 @@ You can preview the production build with `npm run preview`.
## Intuition Building Links ## Intuition Building Links
* [Rust module system is weird?](https://www.sheshbabu.com/posts/rust-module-system/) - [Rust module system is weird?](https://www.sheshbabu.com/posts/rust-module-system/)

View file

@ -1,50 +1,51 @@
{ {
"name": "@tea/gui", "name": "@tea/gui",
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"scripts": { "scripts": {
"tauri": "tauri", "tauri": "tauri",
"dev": "vite dev --port 8080", "dev": "vite dev --port 8080",
"build": "vite build && cp build/app.html build/index.html", "build": "vite build && cp build/app.html build/index.html",
"preview": "vite preview", "preview": "vite preview",
"test": "playwright test", "test": "playwright test",
"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",
"lint": "prettier --plugin-search-dir . --check . && eslint .", "lint": "prettier --plugin-search-dir . --check . && eslint .",
"format": "prettier --plugin-search-dir . --write ." "format": "prettier --plugin-search-dir . --write ."
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "1.25.0", "@playwright/test": "1.25.0",
"@sveltejs/adapter-auto": "next", "@sveltejs/adapter-auto": "next",
"@sveltejs/adapter-static": "1.0.0-next.48", "@sveltejs/adapter-static": "1.0.0-next.48",
"@sveltejs/kit": "next", "@sveltejs/kit": "next",
"@tauri-apps/cli": "1.2.0", "@tauri-apps/cli": "1.2.0",
"@tea/ui": "workspace:*", "@tea/ui": "workspace:*",
"@typescript-eslint/eslint-plugin": "^5.27.0", "@typescript-eslint/eslint-plugin": "^5.27.0",
"@typescript-eslint/parser": "^5.27.0", "@typescript-eslint/parser": "^5.27.0",
"autoprefixer": "^10.4.13", "autoprefixer": "^10.4.13",
"eslint": "^8.16.0", "eslint": "^8.16.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-svelte3": "^4.0.0", "eslint-plugin-svelte3": "^4.0.0",
"postcss": "^8.4.19", "postcss": "^8.4.19",
"prettier": "^2.6.2", "prettier": "^2.6.2",
"prettier-plugin-svelte": "^2.7.0", "prettier-plugin-svelte": "^2.7.0",
"svelte": "^3.49.0", "svelte": "^3.49.0",
"svelte-check": "^2.8.0", "svelte-check": "^2.8.0",
"svelte-preprocess": "^4.10.7", "svelte-preprocess": "^4.10.7",
"tailwindcss": "^3.2.4", "svelte2tsx": "^0.5.20",
"tslib": "^2.3.1", "tailwindcss": "^3.2.4",
"typescript": "^4.7.4", "tslib": "^2.3.1",
"vite": "^3.1.0" "typescript": "^4.7.4",
}, "vite": "^3.1.0"
"type": "module", },
"dependencies": { "type": "module",
"@tauri-apps/api": "^1.2.0", "dependencies": {
"buffer": "^6.0.3" "@tauri-apps/api": "^1.2.0",
}, "buffer": "^6.0.3"
"pnpm": { },
"onlyBuiltDependencies": [ "pnpm": {
"@tea/ui" "onlyBuiltDependencies": [
] "@tea/ui"
} ]
}
} }

View file

@ -1,6 +1,6 @@
module.exports = { module.exports = {
plugins: { plugins: {
tailwindcss: {}, tailwindcss: {},
autoprefixer: {}, autoprefixer: {}
}, }
} };

View file

@ -1,113 +1,110 @@
{ {
"$schema": "../../../node_modules/@tauri-apps/cli/schema.json", "$schema": "../../../node_modules/@tauri-apps/cli/schema.json",
"build": { "build": {
"beforeBuildCommand": "pnpm build", "beforeBuildCommand": "pnpm build",
"beforeDevCommand": "pnpm dev", "beforeDevCommand": "pnpm dev",
"devPath": "http://localhost:8080", "devPath": "http://localhost:8080",
"distDir": "../build" "distDir": "../build"
}, },
"package": { "package": {
"productName": "gui", "productName": "gui",
"version": "0.1.0" "version": "0.1.0"
}, },
"tauri": { "tauri": {
"allowlist": { "allowlist": {
"http": { "http": {
"all": true, "all": true,
"request": true, "request": true,
"scope": [ "scope": ["https://api.tea.xyz/v1/*", "https://github.com/*"]
"https://api.tea.xyz/v1/*", },
"https://github.com/*" "shell": {
] "all": false,
}, "execute": false,
"shell": { "open": true,
"all": false, "scope": [],
"execute": false, "sidecar": false
"open": true, },
"scope": [], "window": {
"sidecar": false "all": true,
}, "center": true,
"window": { "close": true,
"all": true, "create": true,
"center": true, "hide": true,
"close": true, "maximize": true,
"create": true, "minimize": true,
"hide": true, "print": true,
"maximize": true, "requestUserAttention": true,
"minimize": true, "setAlwaysOnTop": true,
"print": true, "setCursorGrab": true,
"requestUserAttention": true, "setCursorIcon": true,
"setAlwaysOnTop": true, "setCursorPosition": true,
"setCursorGrab": true, "setCursorVisible": true,
"setCursorIcon": true, "setDecorations": true,
"setCursorPosition": true, "setFocus": true,
"setCursorVisible": true, "setFullscreen": true,
"setDecorations": true, "setIcon": true,
"setFocus": true, "setIgnoreCursorEvents": true,
"setFullscreen": true, "setMaxSize": true,
"setIcon": true, "setMinSize": true,
"setIgnoreCursorEvents": true, "setPosition": true,
"setMaxSize": true, "setResizable": true,
"setMinSize": true, "setSize": true,
"setPosition": true, "setSkipTaskbar": true,
"setResizable": true, "setTitle": true,
"setSize": true, "show": true,
"setSkipTaskbar": true, "startDragging": true,
"setTitle": true, "unmaximize": true,
"show": true, "unminimize": true
"startDragging": true, }
"unmaximize": true, },
"unminimize": true "bundle": {
} "active": true,
}, "category": "DeveloperTool",
"bundle": { "copyright": "",
"active": true, "deb": {
"category": "DeveloperTool", "depends": []
"copyright": "", },
"deb": { "externalBin": [],
"depends": [] "icon": [
}, "icons/32x32.png",
"externalBin": [], "icons/128x128.png",
"icon": [ "icons/128x128@2x.png",
"icons/32x32.png", "icons/icon.icns",
"icons/128x128.png", "icons/icon.ico"
"icons/128x128@2x.png", ],
"icons/icon.icns", "identifier": "com.tea.xyz",
"icons/icon.ico" "longDescription": "",
], "macOS": {
"identifier": "com.tea.xyz", "entitlements": null,
"longDescription": "", "exceptionDomain": "",
"macOS": { "frameworks": [],
"entitlements": null, "providerShortName": null,
"exceptionDomain": "", "signingIdentity": null
"frameworks": [], },
"providerShortName": null, "resources": [],
"signingIdentity": null "shortDescription": "",
}, "targets": "all",
"resources": [], "windows": {
"shortDescription": "", "certificateThumbprint": null,
"targets": "all", "digestAlgorithm": "sha256",
"windows": { "timestampUrl": ""
"certificateThumbprint": null, }
"digestAlgorithm": "sha256", },
"timestampUrl": "" "security": {
} "csp": null
}, },
"security": { "updater": {
"csp": null "active": false
}, },
"updater": { "windows": [
"active": false {
}, "fullscreen": false,
"windows": [ "height": 600,
{ "resizable": true,
"fullscreen": false, "title": "gui",
"height": 600, "width": 800,
"resizable": true, "decorations": false
"title": "gui", }
"width": 800, ]
"decorations": false }
}
]
}
} }

View file

@ -3,22 +3,22 @@
@tailwind utilities; @tailwind utilities;
@font-face { @font-face {
font-family: "pp-neue-machina"; font-family: 'pp-neue-machina';
src: url("/fonts/PPNeueMachina-InktrapLight.woff"); src: url('/fonts/PPNeueMachina-InktrapLight.woff');
} }
@font-face { @font-face {
font-family: "sono"; font-family: 'sono';
src: url("/fonts/Sono-Light.woff2"); src: url('/fonts/Sono-Light.woff2');
} }
html { html {
background-color: #1a1a1a; background-color: #1a1a1a;
color: #fff; color: #fff;
} }
@layer base { @layer base {
html { html {
font-family: sono, sans-serif; font-family: sono, sans-serif;
} }
} }

View file

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import Placeholder from '$components/Placeholder/Placeholder.svelte';
</script> </script>
<Placeholder label="Badges"/>
<Placeholder label="Badges" />

View file

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import Placeholder from '$components/Placeholder/Placeholder.svelte';
</script> </script>
<Placeholder label="BigBlackSpace"/>
<Placeholder label="BigBlackSpace" />

View file

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import Placeholder from '$components/Placeholder/Placeholder.svelte';
</script> </script>
<Placeholder label="CLI Hero"/>
<Placeholder label="CLI Hero" />

View file

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import Placeholder from '$components/Placeholder/Placeholder.svelte';
</script> </script>
<Placeholder label="EssentialWorkshops"/>
<Placeholder label="EssentialWorkshops" />

View file

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import Placeholder from '$components/Placeholder/Placeholder.svelte';
</script> </script>
<Placeholder label="FeaturedCourses"/>
<Placeholder label="FeaturedCourses" />

View file

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import Placeholder from '$components/Placeholder/Placeholder.svelte';
</script> </script>
<Placeholder label="FeaturedPackages"/>
<Placeholder label="FeaturedPackages" />

View file

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import Placeholder from '$components/Placeholder/Placeholder.svelte';
</script> </script>
<Placeholder label="GettingStarted"/>
<Placeholder label="GettingStarted" />

View file

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import Placeholder from '$components/Placeholder/Placeholder.svelte';
</script> </script>
<Placeholder label="InstalledPackages"/>
<Placeholder label="InstalledPackages" />

View file

@ -1,164 +1,161 @@
<script type="ts"> <script type="ts">
import { page } from '$app/stores'; import { page } from '$app/stores';
import { open } from '@tauri-apps/api/shell'; import { open } from '@tauri-apps/api/shell';
import { appWindow } from '@tauri-apps/api/window'; import { appWindow } from '@tauri-apps/api/window';
import { beforeUpdate } from 'svelte'; import { beforeUpdate } from 'svelte';
const openGithub = () => {
open('https://github.com/teaxyz');
};
const openGithub = () => { let maximized = false;
open('https://github.com/teaxyz') const toggleMaximize = () => {
} maximized = !maximized;
if (maximized) {
appWindow.maximize();
} else {
appWindow.unmaximize();
}
};
let maximized = false; let routes = [
const toggleMaximize = () => { {
maximized = !maximized; path: '/',
if (maximized) { active: false,
appWindow.maximize(); label: 'DISCOVER'
} else { },
appWindow.unmaximize(); {
} path: '/documentation',
} active: false,
label: 'DOCUMENTATION'
},
{
path: '/cli',
active: false,
label: 'TEA CLI INSTALL'
},
{
path: '/packages',
active: false,
label: 'PACKAGES'
}
];
let routes = [ beforeUpdate(async () => {
{ const currentPath = $page.url.pathname;
path: '/',
active: false,
label: 'DISCOVER'
},
{
path: '/documentation',
active: false,
label: 'DOCUMENTATION'
},
{
path: '/cli',
active: false,
label: 'TEA CLI INSTALL'
},
{
path: '/packages',
active: false,
label: 'PACKAGES'
}
];
beforeUpdate(async () => { for (let i = 0; i < routes.length; i++) {
const currentPath = $page.url.pathname; let { path } = routes[i];
routes[i].active = currentPath.includes(path);
for(let i = 0; i < routes.length; i++) { }
let { path } = routes[i]; if (currentPath !== '/') {
routes[i].active = currentPath.includes(path); routes[0].active = false;
} }
if (currentPath !== '/') { });
routes[0].active = false;
}
});
</script> </script>
<ul id="NavBar" > <ul id="NavBar">
<nav data-tauri-drag-region class="flex justify-between"> <nav data-tauri-drag-region class="flex justify-between">
<div class="flex gap-1 p-3"> <div class="flex gap-1 p-3">
<button class="titlebar-button" id="titlebar-close" on:click={appWindow.close}> <button class="titlebar-button" id="titlebar-close" on:click={appWindow.close}>
<img src="/images/close.svg" alt="close" /> <img src="/images/close.svg" alt="close" />
</button> </button>
<button class="titlebar-button" id="titlebar-minimize" on:click={appWindow.minimize}> <button class="titlebar-button" id="titlebar-minimize" on:click={appWindow.minimize}>
<img <img src="/images/minimize.svg" alt="minimize" />
src="/images/minimize.svg" </button>
alt="minimize" <button class="titlebar-button" id="titlebar-maximize" on:click={toggleMaximize}>
/> <img src="/images/expand.svg" alt="maximize" />
</button> </button>
<button class="titlebar-button" id="titlebar-maximize" on:click={toggleMaximize}> </div>
<img <a href="/">
src="/images/expand.svg" <img width="40" height="40" src="/images/tea-icon.png" alt="tea" />
alt="maximize" </a>
/> </nav>
</button>
</div>
<a href="/">
<img width="40" height="40" src="/images/tea-icon.png" alt="tea" />
</a>
</nav>
<input class="w-full bg-black h-12 p-4 border border-x-0 border-gray" type="search" placeholder="search" /> <input
class="w-full bg-black h-12 p-4 border border-x-0 border-gray"
type="search"
placeholder="search"
/>
{#each routes as route} {#each routes as route}
<li class={route.active ? "nav_button active": "nav_button"}> <li class={route.active ? 'nav_button active' : 'nav_button'}>
<a href={route.path}>{route.label}</a> <a href={route.path}>{route.label}</a>
</li> </li>
{/each} {/each}
<li class="nav_button"> <li class="nav_button">
<button on:click={openGithub}>VIEW ON GITHUB</button> <button on:click={openGithub}>VIEW ON GITHUB</button>
</li> </li>
<footer class="border border-x-0 border-gray w-full"> <footer class="border border-x-0 border-gray w-full">
<a href="/profile"> <a href="/profile">
<section class="flex"> <section class="flex">
<img width="40" height="40" src="/images/bored-ape.png" alt="profile"/> <img width="40" height="40" src="/images/bored-ape.png" alt="profile" />
<div class="p-2 text-gray">@user_name</div> <div class="p-2 text-gray">@user_name</div>
</section> </section>
</a> </a>
</footer> </footer>
</ul> </ul>
<style> <style>
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
ul { ul {
height: 100vh; height: 100vh;
width: 100%; width: 100%;
} }
@layer components { @layer components {
.nav_button { .nav_button {
transition: all .3s; transition: all 0.3s;
color: theme('colors.white'); color: theme('colors.white');
padding: theme('spacing.4') theme('spacing.2'); padding: theme('spacing.4') theme('spacing.2');
} }
.nav_button:hover { .nav_button:hover {
color: theme('colors.black'); color: theme('colors.black');
background-color: theme('colors.primary'); background-color: theme('colors.primary');
} }
.nav_button.active { .nav_button.active {
color: theme('colors.black'); color: theme('colors.black');
background-color: theme('colors.primary'); background-color: theme('colors.primary');
} }
} }
nav:hover { nav:hover {
transition: all .3s; transition: all 0.3s;
background-color: #2d2d2d; background-color: #2d2d2d;
} }
.titlebar-button { .titlebar-button {
display: inline-flex; display: inline-flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 16px; width: 16px;
height: 16px; height: 16px;
border-radius: 8px; border-radius: 8px;
opacity: 0.9; opacity: 0.9;
} }
.titlebar-button img { .titlebar-button img {
transition: opacity .3s; transition: opacity 0.3s;
opacity: 0; opacity: 0;
} }
.titlebar-button:hover img { .titlebar-button:hover img {
opacity: 1; opacity: 1;
} }
#titlebar-close { #titlebar-close {
background-color: orangered; background-color: orangered;
} }
#titlebar-minimize { #titlebar-minimize {
background-color: orange; background-color: orange;
} }
#titlebar-maximize { #titlebar-maximize {
background-color: green; background-color: green;
} }
footer { footer {
position: absolute; position: absolute;
bottom: 20px; bottom: 20px;
} }
</style> </style>

View file

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import Placeholder from '$components/Placeholder/Placeholder.svelte';
</script> </script>
<Placeholder label="PackageBanner"/>
<Placeholder label="PackageBanner" />

View file

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import Placeholder from '$components/Placeholder/Placeholder.svelte';
</script> </script>
<Placeholder label="PackageReviews"/> <Placeholder label="PackageReviews" />

View file

@ -1,3 +1,3 @@
<header class="text-primary text-6xl font-machina uppercase"> <header class="text-primary text-6xl font-machina uppercase">
<slot></slot> <slot />
</header> </header>

View file

@ -1,24 +1,24 @@
<script type="ts"> <script type="ts">
export let label:string = ""; export let label = '';
</script> </script>
<section> <section>
<header>{label}</header> <header>{label}</header>
<slot></slot> <slot />
</section> </section>
<style> <style>
section { section {
position: relative; position: relative;
min-height: 240px; min-height: 240px;
height: 100%; height: 100%;
width: 100%; width: 100%;
min-width: 100%; min-width: 100%;
background-color: #CCC; background-color: #ccc;
display: flex; display: flex;
} }
header { header {
color: rgb(50, 48, 48); color: rgb(50, 48, 48);
font-size: 3em; font-size: 3em;
} }
</style> </style>

View file

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import Placeholder from '$components/Placeholder/Placeholder.svelte';
</script> </script>
<Placeholder label="Preflight"/>
<Placeholder label="Preflight" />

View file

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import Placeholder from '$components/Placeholder/Placeholder.svelte';
</script> </script>
<Placeholder label="ProfileBanner"/>
<Placeholder label="ProfileBanner" />

View file

@ -1,31 +1,35 @@
<script> <script type="ts">
import "$appcss"; import '$appcss';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import Placeholder from '$components/Placeholder/Placeholder.svelte';
import { packages as packagesStore, initializePackages } from '$libs/stores';
import type { Package } from '$libs/types';
import { onMount } from 'svelte';
let packages: Package[] = [];
let initialized = false;
packagesStore.subscribe((v) => {
packages = v;
});
onMount(async () => {
if (!packages.length && !initialized) {
initialized = true;
initializePackages();
}
});
</script> </script>
<div class="bg-black border border-gray"> <div class="bg-black border border-gray">
<section class="flex"> <section class="flex">
<h2>Filter Packages</h2> <h2>Filter Packages</h2>
<input type="search" class="text-white bg-black border border-gray"/> <input type="search" class="text-white bg-black border border-gray" />
</section> </section>
<ul class="grid grid-cols-3 gap-8 mt-8"> <ul class="grid grid-cols-3 gap-8 mt-8">
<li> {#each packages as pkg}
<a href="/packages/pkg-a"><Placeholder label="Pkg A"></Placeholder></a> <li>
</li> <a href={`/packages/${pkg.slug}`}><Placeholder label={pkg.name} /></a>
<li> </li>
<a href="/packages/pkg-b"><Placeholder label="Pkg B"></Placeholder></a> {/each}
</li> </ul>
<li>
<a href="/packages/pkg-c"><Placeholder label="Pkg C"></Placeholder></a>
</li>
<li>
<a href="/packages/pkg-a"><Placeholder label="Pkg D"></Placeholder></a>
</li>
<li>
<a href="/packages/pkg-b"><Placeholder label="Pkg E"></Placeholder></a>
</li>
<li>
<a href="/packages/pkg-c"><Placeholder label="Pkg F"></Placeholder></a>
</li>
</ul>
</div> </div>

View file

@ -1,32 +0,0 @@
import { getClient } from '@tauri-apps/api/http';
import { Buffer } from 'buffer';
const username = 'user';
const password = 'password';
const auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
const base = 'https://api.tea.xyz/v1';
export async function get<T>(path: string){
const client = await getClient();
const uri = join(base, path);
const { data } = await client.get<T>(uri.toString(), {
headers: {
Authorization: auth
}
});
return data;
}
const join = function(...paths: string[]){
return paths.map(function(path){
if(path[0] === "/"){
path = path.slice(1);
}
if(path[path.length - 1] === "/"){
path = path.slice(0, path.length - 1);
}
return path;
}).join("/");
}

View file

@ -0,0 +1,154 @@
/**
* primarily used to make this desktop app work in the website preview setting in the CI/CD
* may contain fake/mock data
*
* TODO:
* * make cors work with api.tea.xyz/v1
*/
import type { Package } from '../types';
export async function getPackages(): Promise<Package[]> {
const packages: Package[] = [
{
slug: 'mesonbuild_com',
homepage: 'https://mesonbuild.com',
name: 'mesonbuild.com',
version: '0.63.3',
last_modified: '2022-10-06T15:45:08.000Z',
full_name: 'mesonbuild.com',
dl_count: 270745,
thumb_image_name: 'mesonbuild_com_option 1.jpg ',
maintainer: '',
desc: 'Fast and user friendly build system',
thumb_image_url: 'https://tea.xyz/Images/packages/mesonbuild_com.jpg',
installs: 0
},
{
slug: 'pixman_org',
homepage: 'http://www.pixman.org/',
maintainer: 'freedesktop',
name: 'pixman.org',
version: '0.40.0',
last_modified: '2022-09-26T19:37:47.000Z',
full_name: 'pixman.org',
dl_count: 0,
thumb_image_name: 'pixman_org_option 1.jpg ',
desc: 'Pixman is a library that provides low-level pixel manipulation features such as image compositing and trapezoid rasterization.',
thumb_image_url: 'https://tea.xyz/Images/packages/pixman_org.jpg',
installs: 0
},
{
slug: 'freedesktop_org_pkg_config',
homepage: 'https://freedesktop.org',
maintainer: 'freedesktop.org',
name: 'pkg-config',
version: '0.29.2',
last_modified: '2022-10-20T01:32:15.000Z',
full_name: 'freedesktop.org/pkg-config',
dl_count: 2661501,
thumb_image_name: 'freedecktop_org_pkg_config option 1.jpg ',
desc: 'Manage compile and link flags for libraries',
thumb_image_url: 'https://tea.xyz/Images/packages/freedesktop_org_pkg_config.jpg',
installs: 0
},
{
slug: 'gnu_org_gettext',
homepage: 'https://gnu.org',
maintainer: 'gnu.org',
name: 'gettext',
version: '0.21.1',
last_modified: '2022-10-20T01:23:46.000Z',
full_name: 'gnu.org/gettext',
dl_count: 3715970,
thumb_image_name: 'gnu_org_gettext_option 1.jpg ',
desc: 'GNU internationalization (i18n) and localization (l10n) library',
thumb_image_url: 'https://tea.xyz/Images/packages/gnu_org_gettext.jpg',
installs: 0
},
{
slug: 'ipfs_tech',
homepage: 'https://ipfs.tech',
name: 'ipfs.tech',
version: '0.16.0',
last_modified: '2022-10-19T21:36:52.000Z',
full_name: 'ipfs.tech',
dl_count: 14457,
thumb_image_name: 'ipfs_tech_option 2.jpg ',
maintainer: '',
desc: 'Peer-to-peer hypermedia protocol',
thumb_image_url: 'https://tea.xyz/Images/packages/ipfs_tech.jpg',
installs: 0
},
{
slug: 'nixos_org_patchelf',
homepage: 'https://nixos.org',
maintainer: 'nixos.org',
name: 'patchelf',
version: '0.15.0',
last_modified: '2022-09-27T04:50:44.000Z',
full_name: 'nixos.org/patchelf',
dl_count: 0,
thumb_image_name: 'nixos_org_patchelf_option 1.jpg ',
desc: 'PatchELF is a simple utility for modifying existing ELF executables and libraries.',
thumb_image_url: 'https://tea.xyz/Images/packages/nixos_org_patchelf.jpg',
installs: 0
},
{
slug: 'tea_xyz',
homepage: 'https://tea.xyz',
maintainer: 'tea.xyz',
name: 'tea.xyz',
version: '0.8.6',
last_modified: '2022-10-19T19:13:51.000Z',
full_name: 'tea.xyz',
dl_count: 0,
thumb_image_name: 'tea_xyz_option 2.jpg ',
desc: 'Website of tea.xyz',
thumb_image_url: 'https://tea.xyz/Images/packages/tea_xyz.jpg',
installs: 0
},
{
slug: 'charm_sh_gum',
homepage: 'https://charm.sh',
maintainer: 'charm.sh',
name: 'gum',
version: '0.8.0',
last_modified: '2022-10-21T02:15:16.000Z',
full_name: 'charm.sh/gum',
dl_count: 0,
thumb_image_name: 'charm_sh_gum.jpg ',
desc: '',
thumb_image_url: 'https://tea.xyz/Images/packages/charm_sh_gum.jpg',
installs: 0
},
{
slug: 'pyyaml_org',
homepage: 'https://pyyaml.org',
name: 'pyyaml.org',
version: '0.2.5',
last_modified: '2022-10-03T15:35:14.000Z',
full_name: 'pyyaml.org',
dl_count: 107505,
thumb_image_name: 'pyyaml_org_option 1.jpg ',
maintainer: '',
desc: 'YAML framework for Python',
thumb_image_url: 'https://tea.xyz/Images/packages/pyyaml_org.jpg',
installs: 0
},
{
slug: 'tea_xyz_gx_cc',
homepage: 'https://tea.xyz',
maintainer: 'tea.xyz',
name: 'cc',
version: '0.1.0',
last_modified: '2022-10-19T16:47:44.000Z',
full_name: 'tea.xyz/gx/cc',
dl_count: 0,
thumb_image_name: 'tea_xyz_gx.jpg ',
desc: '',
thumb_image_url: 'https://tea.xyz/Images/packages/tea_xyz_gx_cc.jpg',
installs: 0
}
];
return packages;
}

View file

@ -0,0 +1,51 @@
/**
* this is the main api integration, anything added here
* should be mock replicated in ./mock.ts
* why? to make it easier to verify features without us always
* going through
* the build->download->install->test loop
* thus saving us so much time
*
* primary concerns here are any method that does the following:
* - connect to remote api(api.tea.xyz) and returns a data
* - connect to a local platform api and returns a data
*/
import { getClient } from '@tauri-apps/api/http';
import { Buffer } from 'buffer';
import type { Package } from '../types';
const username = 'user';
const password = 'password';
const auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
const base = 'https://api.tea.xyz/v1';
async function get<T>(path: string) {
const client = await getClient();
const uri = join(base, path);
const { data } = await client.get<T>(uri.toString(), {
headers: {
Authorization: auth
}
});
return data;
}
const join = function (...paths: string[]) {
return paths
.map(function (path) {
if (path[0] === '/') {
path = path.slice(1);
}
if (path[path.length - 1] === '/') {
path = path.slice(0, path.length - 1);
}
return path;
})
.join('/');
};
export async function getPackages(): Promise<Package[]> {
const packages = await get<Package[]>('packages');
return packages;
}

View file

@ -1,3 +1,15 @@
import { writable } from "svelte/store"; import { writable } from 'svelte/store';
import type { Package } from './types';
import { getPackages } from '@api';
export const backLink = writable<string>('/'); export const backLink = writable<string>('/');
export const packages = writable<Package[]>([]);
export const initializePackages = async () => {
console.log("getting packages");
const newPackages = await getPackages();
console.log("got packages", newPackages);
packages.set(newPackages);
};

View file

@ -1,10 +1,14 @@
export interface S3Package { export interface Package {
slug: string, slug: string;
version: string, version: string;
full_name: string, full_name: string;
name: string, name: string;
maintainer: string, maintainer: string;
homepage: string, homepage: string;
// key: string, last_modified: Date | string;
last_modified: Date | string, thumb_image_url: string;
thumb_image_name: string;
desc: string;
dl_count: number;
installs: number;
} }

View file

@ -1,72 +1,72 @@
<!-- home / discover / welcome page --> <!-- home / discover / welcome page -->
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import NavBar from '$components/NavBar/NavBar.svelte'; import NavBar from '$components/NavBar/NavBar.svelte';
import { backLink as backLinkStore } from '$libs/stores'; import { backLink as backLinkStore } from '$libs/stores';
let backLink: string = ''; let backLink = '';
backLinkStore.subscribe((v) => { backLinkStore.subscribe((v) => {
backLink = v; backLink = v;
}); });
</script> </script>
<div id="main-layout"> <div id="main-layout">
<nav class=""> <nav class="">
<NavBar/> <NavBar />
</nav> </nav>
<section class="px-16 pt-24"> <section class="px-16 pt-24">
{#if backLink} {#if backLink}
<header> <header>
<a href={backLink}>back</a> <a href={backLink}>back</a>
</header> </header>
{/if} {/if}
<figure></figure> <figure />
<div> <div>
<slot></slot> <slot />
</div> </div>
</section> </section>
</div> </div>
<style> <style>
#main-layout { #main-layout {
width: 100vh; width: 100vh;
height: 100vh; height: 100vh;
} }
nav { nav {
position: fixed; position: fixed;
width: 240px; width: 240px;
} }
section { section {
position: fixed; position: fixed;
left: 240px; left: 240px;
right: 0px; right: 0px;
height: 100vh; height: 100vh;
overflow-y: scroll; overflow-y: scroll;
} }
figure { figure {
position: absolute; position: absolute;
z-index: 0; z-index: 0;
top: 180px; top: 180px;
left: 0px; left: 0px;
right: 0px; right: 0px;
bottom: 0px; bottom: 0px;
background-image: url('/images/footer-grid-element.svg'); background-image: url('/images/footer-grid-element.svg');
} }
header { header {
position: absolute; position: absolute;
top: 0px; top: 0px;
left: 0px; left: 0px;
width: 100%; width: 100%;
height: 50px; height: 50px;
border-bottom: #CCC 1px solid; border-bottom: #ccc 1px solid;
} }
slot { slot {
z-index: 1; z-index: 1;
} }
div { div {
position: relative; position: relative;
} }
</style> </style>

View file

@ -1,22 +1,21 @@
<!-- home / discover / welcome page --> <!-- home / discover / welcome page -->
<script lang="ts"> <script lang="ts">
import "$appcss"; import '$appcss';
import { backLink } from '$libs/stores'; import { backLink } from '$libs/stores';
import PageHeader from "$components/PageHeader/PageHeader.svelte"; import PageHeader from '$components/PageHeader/PageHeader.svelte';
import FeaturedPackages from "$components/FeaturedPackages/FeaturedPackages.svelte"; import FeaturedPackages from '$components/FeaturedPackages/FeaturedPackages.svelte';
import GettingStarted from "$components/GettingStarted/GettingStarted.svelte"; import GettingStarted from '$components/GettingStarted/GettingStarted.svelte';
backLink.set(''); backLink.set('');
</script> </script>
<div> <div>
<PageHeader>Discover</PageHeader> <PageHeader>Discover</PageHeader>
<section> <section>
<FeaturedPackages/> <FeaturedPackages />
</section> </section>
<section class="mt-8"> <section class="mt-8">
<GettingStarted/> <GettingStarted />
</section> </section>
</div> </div>
<style> <style>

View file

@ -1,21 +1,20 @@
<script> <script>
import "$appcss"; import '$appcss';
import PageHeader from "$components/PageHeader/PageHeader.svelte"; import PageHeader from '$components/PageHeader/PageHeader.svelte';
import CliBanner from "$components/CliBanner/CliBanner.svelte"; import CliBanner from '$components/CliBanner/CliBanner.svelte';
import BigBlackSpace from "$components/BigBlackSpace/BigBlackSpace.svelte"; import BigBlackSpace from '$components/BigBlackSpace/BigBlackSpace.svelte';
import { backLink } from '$libs/stores'; import { backLink } from '$libs/stores';
backLink.set('/'); backLink.set('/');
</script> </script>
<div> <div>
<PageHeader>INSTALL TEA</PageHeader> <PageHeader>INSTALL TEA</PageHeader>
<section> <section>
<CliBanner/> <CliBanner />
</section> </section>
<section class="mt-8"> <section class="mt-8">
<BigBlackSpace/> <BigBlackSpace />
</section> </section>
</div> </div>

View file

@ -1,21 +1,20 @@
<script> <script>
import "$appcss"; import '$appcss';
import PageHeader from "$components/PageHeader/PageHeader.svelte"; import PageHeader from '$components/PageHeader/PageHeader.svelte';
import FeaturedCourses from "$components/FeaturedCourses/FeaturedCourses.svelte"; import FeaturedCourses from '$components/FeaturedCourses/FeaturedCourses.svelte';
import EssentialWorkshops from "$components/EssentialWorkshops/EssentialWorkshops.svelte"; import EssentialWorkshops from '$components/EssentialWorkshops/EssentialWorkshops.svelte';
import { backLink } from '$libs/stores'; import { backLink } from '$libs/stores';
backLink.set('/'); backLink.set('/');
</script> </script>
<div> <div>
<PageHeader>Documentation</PageHeader> <PageHeader>Documentation</PageHeader>
<section> <section>
<FeaturedCourses/> <FeaturedCourses />
</section> </section>
<section class="mt-8"> <section class="mt-8">
<EssentialWorkshops/> <EssentialWorkshops />
</section> </section>
</div> </div>

View file

@ -1,13 +1,13 @@
<script lang="ts"> <script lang="ts">
import { invoke } from '@tauri-apps/api/tauri' import { invoke } from '@tauri-apps/api/tauri';
import Button from '@tea/ui/Button/Button.svelte'; import Button from '@tea/ui/Button/Button.svelte';
let pkg = ''; let pkg = '';
async function installPackage(){ async function installPackage() {
await invoke('install_package', { package: pkg }); await invoke('install_package', { package: pkg });
} }
</script> </script>
<h1>Others</h1> <h1>Others</h1>
<input bind:value={pkg}> <input bind:value={pkg} />
<Button on:click={installPackage} label="install package"></Button> <Button on:click={installPackage} label="install package" />
<a href="/">Back</a> <a href="/">Back</a>

View file

@ -1,13 +1,12 @@
<script> <script>
import "$appcss"; import '$appcss';
import PageHeader from "$components/PageHeader/PageHeader.svelte"; import PageHeader from '$components/PageHeader/PageHeader.svelte';
import SearchPackages from "$components/SearchPackages/SearchPackages.svelte"; import SearchPackages from '$components/SearchPackages/SearchPackages.svelte';
import { backLink } from '$libs/stores'; import { backLink } from '$libs/stores';
backLink.set('/'); backLink.set('/');
</script> </script>
<div> <div>
<PageHeader>Packages</PageHeader> <PageHeader>Packages</PageHeader>
<SearchPackages/> <SearchPackages />
</div> </div>

View file

@ -1,21 +1,21 @@
<script> <script>
import "$appcss"; import '$appcss';
import PageHeader from "$components/PageHeader/PageHeader.svelte"; import PageHeader from '$components/PageHeader/PageHeader.svelte';
import { backLink } from '$libs/stores'; import { backLink } from '$libs/stores';
import PackageBanner from '$components/PackageBanner/PackageBanner.svelte'; import PackageBanner from '$components/PackageBanner/PackageBanner.svelte';
import PackageReviews from '$components/PackageReviews/PackageReviews.svelte'; import PackageReviews from '$components/PackageReviews/PackageReviews.svelte';
backLink.set('/packages'); backLink.set('/packages');
/** @type {import('./$types').PageData} */ /** @type {import('./$types').PageData} */
export let data; export let data;
</script> </script>
<div> <div>
<PageHeader>{data.title}</PageHeader> <PageHeader>{data.title}</PageHeader>
<section> <section>
<PackageBanner/> <PackageBanner />
</section> </section>
<section class="mt-8"> <section class="mt-8">
<PackageReviews/> <PackageReviews />
</section> </section>
</div> </div>

View file

@ -2,9 +2,9 @@ import type { LoadEvent } from '@sveltejs/kit';
/** @type {import('./$types').PageLoad} */ /** @type {import('./$types').PageLoad} */
export function load({ params }: LoadEvent) { export function load({ params }: LoadEvent) {
// TODO: search package details here // TODO: search package details here
return { return {
title: `${params.slug}!`, title: `${params.slug}!`,
content: 'Welcome to our blog. Lorem ipsum dolor sit amet...' content: 'Welcome to our blog. Lorem ipsum dolor sit amet...'
}; };
} }

View file

@ -1,34 +1,31 @@
<script> <script>
import "$appcss"; import '$appcss';
import PageHeader from "$components/PageHeader/PageHeader.svelte"; import PageHeader from '$components/PageHeader/PageHeader.svelte';
import Placeholder from "$components/Placeholder/Placeholder.svelte"; import ProfileBanner from '$components/ProfileBanner/ProfileBanner.svelte';
import ProfileBanner from "$components/ProfileBanner/ProfileBanner.svelte"; import Preflight from '$components/Preflight/Preflight.svelte';
import Preflight from "$components/Preflight/Preflight.svelte"; import Badges from '$components/Badges/Badges.svelte';
import Badges from "$components/Badges/Badges.svelte"; import InstalledPackages from '$components/InstalledPackages/InstalledPackages.svelte';
import InstalledPackages from "$components/InstalledPackages/InstalledPackages.svelte"; import { backLink } from '$libs/stores';
import { backLink } from '$libs/stores'; backLink.set('/');
backLink.set('/');
</script> </script>
<div> <div>
<PageHeader>PROFILE</PageHeader> <PageHeader>PROFILE</PageHeader>
<section> <section>
<ProfileBanner/> <ProfileBanner />
</section> </section>
<section class="mt-8 grid grid-cols-2 gap-8"> <section class="mt-8 grid grid-cols-2 gap-8">
<div> <div>
<Preflight/> <Preflight />
</div> </div>
<div> <div>
<Badges/> <Badges />
</div> </div>
</section> </section>
<section class="mt-8">
<InstalledPackages/>
</section>
<section class="mt-8">
<InstalledPackages />
</section>
</div> </div>

View file

@ -7,17 +7,17 @@ const config = {
// for more information about preprocessors // for more information about preprocessors
preprocess: [ preprocess: [
preprocess({ preprocess({
postcss: true, postcss: true
}) })
], ],
kit: { kit: {
adapter: adapter({ adapter: adapter({
pages: 'build', pages: 'build',
assets: 'build', assets: 'build',
fallback: 'app.html', fallback: 'app.html'
}), }),
alias: { alias: {
'@tea/ui/*': '../ui/src/*', '@tea/ui/*': '../ui/src/*'
} }
// ssr: false, // ssr: false,
// hydrate the <div id="svelte"> element in src/app.html // hydrate the <div id="svelte"> element in src/app.html

View file

@ -1,10 +1,7 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
const { theme } = require('@tea/ui/tailwind.config.cjs') const { theme } = require('@tea/ui/tailwind.config.cjs');
module.exports = { module.exports = {
content: [ content: ['./src/**/*.{html,svelte,ts,js}', '../ui/src/**/*.{html,svelte,ts,js}'],
'./src/**/*.{html,svelte,ts,js}', theme,
'../ui/src/**/*.{html,svelte,ts,js}' plugins: []
], };
theme,
plugins: [],
}

View file

@ -12,11 +12,11 @@
"paths": { "paths": {
"$appcss": ["src/app.css"], "$appcss": ["src/app.css"],
"$libs/*": ["src/libs/*"], "$libs/*": ["src/libs/*"],
"@api": ["src/lib/api.ts"], "@api": ["src/lib/api/tauri.ts"],
"$components/*": ["src/components/*"], "$components/*": ["src/components/*"],
"@tea/ui": ["../ui/src/*"], "@tea/ui": ["../ui/src/*"]
} }
}, }
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
// //
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes

View file

@ -2,14 +2,21 @@ import { sveltekit } from '@sveltejs/kit/vite';
import type { UserConfig } from 'vite'; import type { UserConfig } from 'vite';
import path from 'path'; import path from 'path';
const isMock = process.env.BUILD_FOR === 'preview';
const config: UserConfig = { const config: UserConfig = {
plugins: [sveltekit()], plugins: [sveltekit()],
resolve: { resolve: {
alias: { alias: {
'@tea/ui/*': path.resolve('../ui/src/*'), '@tea/ui/*': path.resolve('../ui/src/*'),
// this dynamic-ish static importing is followed by the svelte build
// but for vscode editing intellisense tsconfig.json is being used
'@api': isMock ?
path.resolve('src/libs/api/mock.ts') :
path.resolve('src/libs/api/tauri.ts'),
$components: path.resolve('./src/components'), $components: path.resolve('./src/components'),
$libs: path.resolve('./src/libs'), $libs: path.resolve('./src/libs'),
$appcss: path.resolve('./src/app.css'), $appcss: path.resolve('./src/app.css')
} }
} }
}; };

View file

@ -1,23 +1,30 @@
module.exports = { module.exports = {
root: true, root: true,
parser: '@typescript-eslint/parser', parser: '@typescript-eslint/parser',
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier', 'plugin:storybook/recommended'], extends: [
plugins: ['svelte3', '@typescript-eslint'], 'eslint:recommended',
ignorePatterns: ['*.cjs'], 'plugin:@typescript-eslint/recommended',
overrides: [{ 'prettier',
files: ['*.svelte'], 'plugin:storybook/recommended'
processor: 'svelte3/svelte3' ],
}], plugins: ['svelte3', '@typescript-eslint'],
settings: { ignorePatterns: ['*.cjs'],
'svelte3/typescript': () => require('typescript') overrides: [
}, {
parserOptions: { files: ['*.svelte'],
sourceType: 'module', processor: 'svelte3/svelte3'
ecmaVersion: 2020 }
}, ],
env: { settings: {
browser: true, 'svelte3/typescript': () => require('typescript')
es2017: true, },
node: true parserOptions: {
} sourceType: 'module',
ecmaVersion: 2020
},
env: {
browser: true,
es2017: true,
node: true
}
}; };

View file

@ -1,4 +1,5 @@
{ {
"tabWidth": 2,
"useTabs": true, "useTabs": true,
"singleQuote": true, "singleQuote": true,
"trailingComma": "none", "trailingComma": "none",

View file

@ -1,19 +1,16 @@
const path = require('path'); const path = require('path');
module.exports = { module.exports = {
"stories": [ stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx|svelte)'],
"../src/**/*.stories.mdx", addons: [
"../src/**/*.stories.@(js|jsx|ts|tsx|svelte)" '@storybook/addon-links',
], '@storybook/addon-essentials',
"addons": [ '@storybook/addon-interactions'
"@storybook/addon-links", ],
"@storybook/addon-essentials", framework: {
"@storybook/addon-interactions" name: '@storybook/svelte-vite',
], options: {}
"framework": { },
"name": "@storybook/svelte-vite", docs: {
"options": {} docsPage: true
}, }
"docs": { };
"docsPage": true
}
}

View file

@ -1,3 +1,3 @@
<script> <script>
window.global = window; window.global = window;
</script> </script>

View file

@ -1,9 +1,9 @@
export const parameters = { export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" }, actions: { argTypesRegex: '^on[A-Z].*' },
controls: { controls: {
matchers: { matchers: {
color: /(background|color)$/i, color: /(background|color)$/i,
date: /Date$/, date: /Date$/
}, }
}, }
} };

View file

@ -1,4 +1,5 @@
# @tea/ui # @tea/ui
Isolated set of UI elements/components that can be reused across all svelte related apps of tea. Components here have to be maintained as much as possible as a [dumb/presentational components](https://medium.com/@thejasonfile/dumb-components-and-smart-components-e7b33a698d43). Isolated set of UI elements/components that can be reused across all svelte related apps of tea. Components here have to be maintained as much as possible as a [dumb/presentational components](https://medium.com/@thejasonfile/dumb-components-and-smart-components-e7b33a698d43).
## Developing ## Developing
@ -11,10 +12,12 @@ $ pnpm dev
``` ```
## Todo ## Todo
[] setup a scaffolding script to make it easier making elements [] setup a scaffolding script to make it easier making elements
## Design System ## Design System
This library is dependent on the following This library is dependent on the following
- [svelte](https://svelte.dev/) - [svelte](https://svelte.dev/)
- [tailwind](https://tailwindcss.com/) - [tailwind](https://tailwindcss.com/)

View file

@ -1,52 +1,52 @@
{ {
"name": "@tea/ui", "name": "@tea/ui",
"version": "0.0.1", "version": "0.0.1",
"scripts": { "scripts": {
"vite:dev": "vite dev", "vite:dev": "vite dev",
"build": "svelte-kit sync && svelte-package", "build": "svelte-kit sync && svelte-package",
"prepublishOnly": "echo 'Did you mean to publish `./package/`, instead of `./`?' && exit 1", "prepublishOnly": "echo 'Did you mean to publish `./package/`, instead of `./`?' && exit 1",
"test": "playwright test", "test": "playwright test",
"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",
"lint": "prettier --plugin-search-dir . --check . && eslint .", "lint": "prettier --plugin-search-dir . --check . && eslint .",
"format": "prettier --plugin-search-dir . --write .", "format": "prettier --plugin-search-dir . --write .",
"dev": "storybook dev -p 6006", "dev": "storybook dev -p 6006",
"build-storybook": "storybook build" "build-storybook": "storybook build"
}, },
"files": [ "files": [
"src/**/*", "src/**/*",
"tsconfig.json", "tsconfig.json",
"tailwind.config.cjs" "tailwind.config.cjs"
], ],
"devDependencies": { "devDependencies": {
"@playwright/test": "1.25.0", "@playwright/test": "1.25.0",
"@storybook/addon-essentials": "^7.0.0-alpha.51", "@storybook/addon-essentials": "^7.0.0-alpha.51",
"@storybook/addon-interactions": "^7.0.0-alpha.51", "@storybook/addon-interactions": "^7.0.0-alpha.51",
"@storybook/addon-links": "^7.0.0-alpha.51", "@storybook/addon-links": "^7.0.0-alpha.51",
"@storybook/svelte": "^7.0.0-alpha.51", "@storybook/svelte": "^7.0.0-alpha.51",
"@storybook/svelte-vite": "^7.0.0-alpha.51", "@storybook/svelte-vite": "^7.0.0-alpha.51",
"@storybook/testing-library": "^0.0.13", "@storybook/testing-library": "^0.0.13",
"@sveltejs/adapter-auto": "next", "@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "next", "@sveltejs/kit": "next",
"@sveltejs/package": "next", "@sveltejs/package": "next",
"@typescript-eslint/eslint-plugin": "^5.27.0", "@typescript-eslint/eslint-plugin": "^5.27.0",
"@typescript-eslint/parser": "^5.27.0", "@typescript-eslint/parser": "^5.27.0",
"autoprefixer": "^10.4.13", "autoprefixer": "^10.4.13",
"eslint": "^8.16.0", "eslint": "^8.16.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-storybook": "^0.6.7", "eslint-plugin-storybook": "^0.6.7",
"eslint-plugin-svelte3": "^4.0.0", "eslint-plugin-svelte3": "^4.0.0",
"postcss": "^8.4.19", "postcss": "^8.4.19",
"prettier": "^2.6.2", "prettier": "^2.6.2",
"prettier-plugin-svelte": "^2.7.0", "prettier-plugin-svelte": "^2.7.0",
"storybook": "^7.0.0-alpha.51", "storybook": "^7.0.0-alpha.51",
"svelte": "^3.44.0", "svelte": "^3.44.0",
"svelte-check": "^2.7.1", "svelte-check": "^2.7.1",
"svelte-preprocess": "^4.10.7", "svelte-preprocess": "^4.10.7",
"tailwindcss": "^3.2.4", "tailwindcss": "^3.2.4",
"tslib": "^2.3.1", "tslib": "^2.3.1",
"typescript": "^4.7.4", "typescript": "^4.7.4",
"vite": "^3.1.0" "vite": "^3.1.0"
}, },
"type": "module" "type": "module"
} }

View file

@ -1,6 +1,6 @@
module.exports = { module.exports = {
plugins: { plugins: {
tailwindcss: {}, tailwindcss: {},
autoprefixer: {}, autoprefixer: {}
}, }
} };

View file

@ -2,52 +2,52 @@ import Button from './Button.svelte';
// More on how to set up stories at: https://storybook.js.org/docs/7.0/svelte/writing-stories/introduction // More on how to set up stories at: https://storybook.js.org/docs/7.0/svelte/writing-stories/introduction
export default { export default {
title: 'Example/Button', title: 'Example/Button',
component: Button, component: Button,
tags: ['docsPage'], tags: ['docsPage'],
render: (args) => ({ render: (args) => ({
Component: Button, Component: Button,
props: args, props: args,
on: { on: {
click: args.onClick, click: args.onClick
}, }
}), }),
argTypes: { argTypes: {
backgroundColor: { control: 'color' }, backgroundColor: { control: 'color' },
label: { control: 'text' }, label: { control: 'text' },
onClick: { action: 'onClick' }, onClick: { action: 'onClick' },
primary: { control: 'boolean' }, primary: { control: 'boolean' },
size: { size: {
control: { type: 'select' }, control: { type: 'select' },
options: ['small', 'medium', 'large'], options: ['small', 'medium', 'large']
}, }
}, }
}; };
// More on writing stories with args: https://storybook.js.org/docs/7.0/svelte/writing-stories/args // More on writing stories with args: https://storybook.js.org/docs/7.0/svelte/writing-stories/args
export const Primary = { export const Primary = {
args: { args: {
primary: true, primary: true,
label: 'Button', label: 'Button'
}, }
}; };
export const Secondary = { export const Secondary = {
args: { args: {
label: 'Button', label: 'Button'
}, }
}; };
export const Large = { export const Large = {
args: { args: {
size: 'large', size: 'large',
label: 'Button', label: 'Button'
}, }
}; };
export const Small = { export const Small = {
args: { args: {
size: 'small', size: 'small',
label: 'Button', label: 'Button'
}, }
}; };

View file

@ -1,43 +1,44 @@
<script type="ts"> <script type="ts">
import './button.css'; import './button.css';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
/**
* Is this the principal call to action on the page?
*/
export let primary:boolean = false;
/** /**
* What background color to use * Is this the principal call to action on the page?
*/ */
export let backgroundColor:string = ''; export let primary = false;
/**
* How large should the button be?
*/
export let size:string = 'medium';
/**
* Button contents
*/
export let label:string = '';
$: mode = primary ? 'storybook-button--primary bg-primary' : 'storybook-button--secondary'; /**
* What background color to use
*/
export let backgroundColor = '';
/**
* How large should the button be?
*/
export let size: 'large' | 'medium' | 'small' = 'medium';
/**
* Button contents
*/
export let label = '';
$: style = backgroundColor ? `background-color: ${backgroundColor}` : ''; $: mode = primary ? 'storybook-button--primary bg-primary' : 'storybook-button--secondary';
const dispatch = createEventDispatcher(); $: style = backgroundColor ? `background-color: ${backgroundColor}` : '';
/** const dispatch = createEventDispatcher();
* Optional click handler
*/ /**
export let onClick = (event: any) => { * Optional click handler
dispatch('click', event); */
}; export let onClick = (event: any) => {
dispatch('click', event);
};
</script> </script>
<button <button
type="button" type="button"
class={['storybook-button', `storybook-button--${size}`, 'hover:font-light', mode].join(' ')} class={['storybook-button', `storybook-button--${size}`, 'hover:font-light', mode].join(' ')}
{style} {style}
on:click={onClick} on:click={onClick}
> >
{label} {label}
</button> </button>

View file

@ -1,31 +1,31 @@
@import "../app.css"; @import '../app.css';
.storybook-button { .storybook-button {
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: 700; font-weight: 700;
border: 0; border: 0;
border-radius: 3em; border-radius: 3em;
cursor: pointer; cursor: pointer;
display: inline-block; display: inline-block;
line-height: 1; line-height: 1;
} }
.storybook-button--primary { .storybook-button--primary {
color: white; color: white;
} }
.storybook-button--secondary { .storybook-button--secondary {
color: #333; color: #333;
background-color: transparent; background-color: transparent;
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset; box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
} }
.storybook-button--small { .storybook-button--small {
font-size: 12px; font-size: 12px;
padding: 10px 16px; padding: 10px 16px;
} }
.storybook-button--medium { .storybook-button--medium {
font-size: 14px; font-size: 14px;
padding: 11px 20px; padding: 11px 20px;
} }
.storybook-button--large { .storybook-button--large {
font-size: 16px; font-size: 16px;
padding: 12px 24px; padding: 12px 24px;
} }

View file

@ -1,36 +1,36 @@
import Header from './Header.svelte'; import Header from './Header.svelte';
export default { export default {
title: 'Example/Header', title: 'Example/Header',
component: Header, component: Header,
// This component will have an automatically generated docsPage entry: https://storybook.js.org/docs/7.0/svelte/writing-docs/docs-page // This component will have an automatically generated docsPage entry: https://storybook.js.org/docs/7.0/svelte/writing-docs/docs-page
tags: ['docsPage'], tags: ['docsPage'],
render: (args) => ({ render: (args) => ({
Component: Header, Component: Header,
props: args, props: args,
on: { on: {
login: args.onLogin, login: args.onLogin,
logout: args.onLogout, logout: args.onLogout,
createAccount: args.onCreateAccount, createAccount: args.onCreateAccount
}, }
}), }),
parameters: { parameters: {
// More on how to position stories at: https://storybook.js.org/docs/7.0/svelte/configure/story-layout // More on how to position stories at: https://storybook.js.org/docs/7.0/svelte/configure/story-layout
layout: 'fullscreen', layout: 'fullscreen'
}, },
argTypes: { argTypes: {
onLogin: { action: 'onLogin' }, onLogin: { action: 'onLogin' },
onLogout: { action: 'onLogout' }, onLogout: { action: 'onLogout' },
onCreateAccount: { action: 'onCreateAccount' }, onCreateAccount: { action: 'onCreateAccount' }
}, }
}; };
export const LoggedIn = { export const LoggedIn = {
args: { args: {
user: { user: {
name: 'Jane Doe', name: 'Jane Doe'
}, }
}, }
}; };
export const LoggedOut = {}; export const LoggedOut = {};

View file

@ -1,51 +1,53 @@
<script type="ts"> <script type="ts">
import './header.css'; import './header.css';
import Button from '../Button/Button.svelte'; import Button from '../Button/Button.svelte';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
export let user = null; export let user = null;
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
function onLogin(event) { function onLogin(event) {
dispatch('login', event); dispatch('login', event);
} }
function onLogout(event) { function onLogout(event) {
dispatch('logout', event); dispatch('logout', event);
} }
function onCreateAccount(event) { function onCreateAccount(event) {
dispatch('createAccount', event); dispatch('createAccount', event);
} }
</script> </script>
<header> <header>
<div class="wrapper"> <div class="wrapper">
<div> <div>
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"> <svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd"> <g fill="none" fill-rule="evenodd">
<path <path
d="M10 0h12a10 10 0 0110 10v12a10 10 0 01-10 10H10A10 10 0 010 22V10A10 10 0 0110 0z" d="M10 0h12a10 10 0 0110 10v12a10 10 0 01-10 10H10A10 10 0 010 22V10A10 10 0 0110 0z"
fill="#FFF" /> fill="#FFF"
<path />
d="M5.3 10.6l10.4 6v11.1l-10.4-6v-11zm11.4-6.2l9.7 5.5-9.7 5.6V4.4z" <path
fill="#555AB9" /> d="M5.3 10.6l10.4 6v11.1l-10.4-6v-11zm11.4-6.2l9.7 5.5-9.7 5.6V4.4z"
<path d="M27.2 10.6v11.2l-10.5 6V16.5l10.5-6zM15.7 4.4v11L6 10l9.7-5.5z" fill="#91BAF8" /> fill="#555AB9"
</g> />
</svg> <path d="M27.2 10.6v11.2l-10.5 6V16.5l10.5-6zM15.7 4.4v11L6 10l9.7-5.5z" fill="#91BAF8" />
<h1>Acme</h1> </g>
</div> </svg>
<div> <h1>Acme</h1>
{#if user} </div>
<span class="welcome"> <div>
Welcome, <b>{user.name}</b>! {#if user}
</span> <span class="welcome">
<Button size="small" on:click={onLogout} label="Log out" /> Welcome, <b>{user.name}</b>!
{/if} </span>
{#if !user} <Button size="small" on:click={onLogout} label="Log out" />
<Button size="small" on:click={onLogin} label="Log in" /> {/if}
<Button primary size="small" on:click={onCreateAccount} label="Sign up" /> {#if !user}
{/if} <Button size="small" on:click={onLogin} label="Log in" />
</div> <Button primary size="small" on:click={onCreateAccount} label="Sign up" />
</div> {/if}
</div>
</div>
</header> </header>

View file

@ -1,34 +1,34 @@
@import "../app.css"; @import '../app.css';
.wrapper { .wrapper {
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
border-bottom: 1px solid rgba(0, 0, 0, 0.1); border-bottom: 1px solid rgba(0, 0, 0, 0.1);
padding: 15px 20px; padding: 15px 20px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
} }
svg { svg {
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
} }
h1 { h1 {
font-weight: 900; font-weight: 900;
font-size: 20px; font-size: 20px;
line-height: 1; line-height: 1;
margin: 6px 0 6px 10px; margin: 6px 0 6px 10px;
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
} }
button + button { button + button {
margin-left: 10px; margin-left: 10px;
} }
.welcome { .welcome {
color: #333; color: #333;
font-size: 14px; font-size: 14px;
margin-right: 10px; margin-right: 10px;
} }

View file

@ -2,26 +2,26 @@ import { within, userEvent } from '@storybook/testing-library';
import Page from './Page.svelte'; import Page from './Page.svelte';
export default { export default {
title: 'Example/Page', title: 'Example/Page',
component: Page, component: Page,
parameters: { parameters: {
// More on how to position stories at: https://storybook.js.org/docs/7.0/svelte/configure/story-layout // More on how to position stories at: https://storybook.js.org/docs/7.0/svelte/configure/story-layout
layout: 'fullscreen', layout: 'fullscreen'
}, }
}; };
export const LoggedOut = {}; export const LoggedOut = {};
// More on interaction testing: https://storybook.js.org/docs/7.0/svelte/writing-tests/interaction-testing // More on interaction testing: https://storybook.js.org/docs/7.0/svelte/writing-tests/interaction-testing
export const LoggedIn = { export const LoggedIn = {
render: (args) => ({ render: (args) => ({
Component: Page, Component: Page,
props: args, props: args
}), }),
play: async ({ canvasElement }) => { play: async ({ canvasElement }) => {
const canvas = within(canvasElement); const canvas = within(canvasElement);
const loginButton = await canvas.getByRole('button', { const loginButton = await canvas.getByRole('button', {
name: /Log in/i, name: /Log in/i
}); });
await userEvent.click(loginButton); await userEvent.click(loginButton);
}, }
}; };

View file

@ -1,63 +1,70 @@
<script type="ts"> <script type="ts">
import './page.css'; import './page.css';
import Header from '../Header/Header.svelte'; import Header from '../Header/Header.svelte';
let user = null; let user = null;
</script> </script>
<article> <article>
<Header {user} on:login={() => user = { name: 'Jane Doe' }} on:logout={() => user = null} on:createAccount={() => user = { name: 'Jane Doe' }} /> <Header
{user}
on:login={() => (user = { name: 'Jane Doe' })}
on:logout={() => (user = null)}
on:createAccount={() => (user = { name: 'Jane Doe' })}
/>
<section> <section>
<h2>Pages in Storybook</h2> <h2>Pages in Storybook</h2>
<p> <p>
We recommend building UIs with a We recommend building UIs with a
<a <a
href="https://blog.hichroma.com/component-driven-development-ce1109d56c8e" href="https://blog.hichroma.com/component-driven-development-ce1109d56c8e"
target="_blank" target="_blank"
rel="noopener noreferrer"> rel="noopener noreferrer"
<strong>component-driven</strong> >
</a> <strong>component-driven</strong>
process starting with atomic components and ending with pages. </a>
</p> process starting with atomic components and ending with pages.
<p> </p>
Render pages with mock data. This makes it easy to build and review page states without <p>
needing to navigate to them in your app. Here are some handy patterns for managing page data Render pages with mock data. This makes it easy to build and review page states without
in Storybook: needing to navigate to them in your app. Here are some handy patterns for managing page data
</p> in Storybook:
<ul> </p>
<li> <ul>
Use a higher-level connected component. Storybook helps you compose such data from the <li>
"args" of child component stories Use a higher-level connected component. Storybook helps you compose such data from the
</li> "args" of child component stories
<li> </li>
Assemble data in the page component from your services. You can mock these services out <li>
using Storybook. Assemble data in the page component from your services. You can mock these services out
</li> using Storybook.
</ul> </li>
<p> </ul>
Get a guided tutorial on component-driven development at <p>
<a href="https://storybook.js.org/tutorials/" target="_blank" rel="noopener noreferrer"> Get a guided tutorial on component-driven development at
Storybook tutorials <a href="https://storybook.js.org/tutorials/" target="_blank" rel="noopener noreferrer">
</a> Storybook tutorials
. Read more in the </a>
<a href="https://storybook.js.org/docs" target="_blank" rel="noopener noreferrer">docs</a> . Read more in the
. <a href="https://storybook.js.org/docs" target="_blank" rel="noopener noreferrer">docs</a>
</p> .
<div class="tip-wrapper"> </p>
<span class="tip">Tip</span> <div class="tip-wrapper">
Adjust the width of the canvas with the <span class="tip">Tip</span>
<svg width="10" height="10" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"> Adjust the width of the canvas with the
<g fill="none" fill-rule="evenodd"> <svg width="10" height="10" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
<path <g fill="none" fill-rule="evenodd">
d="M1.5 5.2h4.8c.3 0 .5.2.5.4v5.1c-.1.2-.3.3-.4.3H1.4a.5.5 0 <path
d="M1.5 5.2h4.8c.3 0 .5.2.5.4v5.1c-.1.2-.3.3-.4.3H1.4a.5.5 0
01-.5-.4V5.7c0-.3.2-.5.5-.5zm0-2.1h6.9c.3 0 .5.2.5.4v7a.5.5 0 01-1 0V4H1.5a.5.5 0 01-.5-.4V5.7c0-.3.2-.5.5-.5zm0-2.1h6.9c.3 0 .5.2.5.4v7a.5.5 0 01-1 0V4H1.5a.5.5 0
010-1zm0-2.1h9c.3 0 .5.2.5.4v9.1a.5.5 0 01-1 0V2H1.5a.5.5 0 010-1zm4.3 5.2H2V10h3.8V6.2z" 010-1zm0-2.1h9c.3 0 .5.2.5.4v9.1a.5.5 0 01-1 0V2H1.5a.5.5 0 010-1zm4.3 5.2H2V10h3.8V6.2z"
id="a" id="a"
fill="#999" /> fill="#999"
</g> />
</svg> </g>
Viewports addon in the toolbar </svg>
</div> Viewports addon in the toolbar
</section> </div>
</section>
</article> </article>

View file

@ -1,71 +1,71 @@
@import "../app.css"; @import '../app.css';
section { section {
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 14px; font-size: 14px;
line-height: 24px; line-height: 24px;
padding: 48px 20px; padding: 48px 20px;
margin: 0 auto; margin: 0 auto;
max-width: 600px; max-width: 600px;
color: #333; color: #333;
} }
section h2 { section h2 {
font-weight: 900; font-weight: 900;
font-size: 32px; font-size: 32px;
line-height: 1; line-height: 1;
margin: 0 0 4px; margin: 0 0 4px;
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
} }
section p { section p {
margin: 1em 0; margin: 1em 0;
} }
section a { section a {
text-decoration: none; text-decoration: none;
color: #1ea7fd; color: #1ea7fd;
} }
section ul { section ul {
padding-left: 30px; padding-left: 30px;
margin: 1em 0; margin: 1em 0;
} }
section li { section li {
margin-bottom: 8px; margin-bottom: 8px;
} }
section .tip { section .tip {
display: inline-block; display: inline-block;
border-radius: 1em; border-radius: 1em;
font-size: 11px; font-size: 11px;
line-height: 12px; line-height: 12px;
font-weight: 700; font-weight: 700;
background: #e7fdd8; background: #e7fdd8;
color: #66bf3c; color: #66bf3c;
padding: 4px 12px; padding: 4px 12px;
margin-right: 10px; margin-right: 10px;
vertical-align: top; vertical-align: top;
} }
section .tip-wrapper { section .tip-wrapper {
font-size: 13px; font-size: 13px;
line-height: 20px; line-height: 20px;
margin-top: 40px; margin-top: 40px;
margin-bottom: 40px; margin-bottom: 40px;
} }
section .tip-wrapper svg { section .tip-wrapper svg {
display: inline-block; display: inline-block;
height: 12px; height: 12px;
width: 12px; width: 12px;
margin-right: 4px; margin-right: 4px;
vertical-align: top; vertical-align: top;
margin-top: 3px; margin-top: 3px;
} }
section .tip-wrapper svg path { section .tip-wrapper svg path {
fill: #1ea7fd; fill: #1ea7fd;
} }

View file

@ -2,14 +2,12 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
@font-face { @font-face {
font-family: "pp-neue-machina"; font-family: 'pp-neue-machina';
src: url("../static/fonts/PPNeueMachina-InktrapLight.woff"); src: url('../static/fonts/PPNeueMachina-InktrapLight.woff');
} }
@font-face { @font-face {
font-family: "sono"; font-family: 'sono';
src: url("../static/fonts/Sono-Light.woff2"); src: url('../static/fonts/Sono-Light.woff2');
} }

View file

@ -6,7 +6,7 @@ const config = {
// Consult https://github.com/sveltejs/svelte-preprocess // Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors // for more information about preprocessors
preprocess: preprocess({ preprocess: preprocess({
postcss: true, postcss: true
}), }),
kit: { kit: {

View file

@ -5,21 +5,21 @@ const white = '#fff';
const gray = '#949494'; const gray = '#949494';
module.exports = { module.exports = {
content: ['./src/**/*.{html,js,svelte,ts}'], content: ['./src/**/*.{html,js,svelte,ts}'],
theme: { theme: {
colors: { colors: {
primary, primary,
green: primary, green: primary,
black, black,
white, white,
gray, gray
}, },
extend: { extend: {
fontFamily: { fontFamily: {
sono: ['sono', 'sans-serif'], sono: ['sono', 'sans-serif'],
machina: ['pp-neue-machina', 'sans-serif'] machina: ['pp-neue-machina', 'sans-serif']
} }
}, }
}, },
plugins: [], plugins: []
} };

View file

@ -2,18 +2,11 @@
"compilerOptions": { "compilerOptions": {
"baseUrl": "..", "baseUrl": "..",
"paths": {}, "paths": {},
"rootDirs": [ "rootDirs": ["..", "./types"],
"..",
"./types"
],
"importsNotUsedAsValues": "error", "importsNotUsedAsValues": "error",
"isolatedModules": true, "isolatedModules": true,
"preserveValueImports": true, "preserveValueImports": true,
"lib": [ "lib": ["esnext", "DOM", "DOM.Iterable"],
"esnext",
"DOM",
"DOM.Iterable"
],
"moduleResolution": "node", "moduleResolution": "node",
"module": "esnext", "module": "esnext",
"target": "esnext", "target": "esnext",
@ -40,8 +33,5 @@
"../tests/**/*.ts", "../tests/**/*.ts",
"../tests/**/*.svelte" "../tests/**/*.svelte"
], ],
"exclude": [ "exclude": ["../node_modules/**", "./[!ambient.d.ts]**"]
"../node_modules/**",
"./[!ambient.d.ts]**"
]
} }

View file

@ -27,6 +27,7 @@ importers:
svelte: ^3.49.0 svelte: ^3.49.0
svelte-check: ^2.8.0 svelte-check: ^2.8.0
svelte-preprocess: ^4.10.7 svelte-preprocess: ^4.10.7
svelte2tsx: ^0.5.20
tailwindcss: ^3.2.4 tailwindcss: ^3.2.4
tslib: ^2.3.1 tslib: ^2.3.1
typescript: ^4.7.4 typescript: ^4.7.4
@ -38,7 +39,7 @@ importers:
'@playwright/test': 1.25.0 '@playwright/test': 1.25.0
'@sveltejs/adapter-auto': 1.0.0-next.89 '@sveltejs/adapter-auto': 1.0.0-next.89
'@sveltejs/adapter-static': 1.0.0-next.48 '@sveltejs/adapter-static': 1.0.0-next.48
'@sveltejs/kit': 1.0.0-next.561_svelte@3.53.1+vite@3.2.4 '@sveltejs/kit': 1.0.0-next.562_svelte@3.53.1+vite@3.2.4
'@tauri-apps/cli': 1.2.0 '@tauri-apps/cli': 1.2.0
'@tea/ui': link:../ui '@tea/ui': link:../ui
'@typescript-eslint/eslint-plugin': 5.43.0_wze2rj5tow7zwqpgbdx2buoy3m '@typescript-eslint/eslint-plugin': 5.43.0_wze2rj5tow7zwqpgbdx2buoy3m
@ -53,6 +54,7 @@ importers:
svelte: 3.53.1 svelte: 3.53.1
svelte-check: 2.9.2_mocwzvuqzrhb37u7s4hjvvzl3i svelte-check: 2.9.2_mocwzvuqzrhb37u7s4hjvvzl3i
svelte-preprocess: 4.10.7_mvbmsfnr3ibpjsbee6imjcb33m svelte-preprocess: 4.10.7_mvbmsfnr3ibpjsbee6imjcb33m
svelte2tsx: 0.5.20_7dvewpees4iyn2tkw2qzal77a4
tailwindcss: 3.2.4 tailwindcss: 3.2.4
tslib: 2.4.1 tslib: 2.4.1
typescript: 4.9.3 typescript: 4.9.3
@ -3028,6 +3030,34 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@sveltejs/kit/1.0.0-next.562_svelte@3.53.1+vite@3.2.4:
resolution: {integrity: sha512-VgJzjtfjVLW/4A/vDtURc10PrS3bb/N62LHzqLZcUNb5+eN4a0k5cayC7Hz2tmtvrb2Qsg+piEAogvqjKBxrOg==}
engines: {node: '>=16.14'}
hasBin: true
requiresBuild: true
peerDependencies:
svelte: ^3.44.0
vite: ^3.2.0
dependencies:
'@sveltejs/vite-plugin-svelte': 1.3.1_svelte@3.53.1+vite@3.2.4
'@types/cookie': 0.5.1
cookie: 0.5.0
devalue: 4.2.0
kleur: 4.1.5
magic-string: 0.26.7
mime: 3.0.0
sade: 1.8.1
set-cookie-parser: 2.5.1
sirv: 2.0.2
svelte: 3.53.1
tiny-glob: 0.2.9
undici: 5.12.0
vite: 3.2.4
transitivePeerDependencies:
- diff-match-patch
- supports-color
dev: true
/@sveltejs/package/1.0.0-next.1_7dvewpees4iyn2tkw2qzal77a4: /@sveltejs/package/1.0.0-next.1_7dvewpees4iyn2tkw2qzal77a4:
resolution: {integrity: sha512-U8XBk6Cfy8MjKG41Uyo+fqBpdhu7xUSnhiCNoODRaAtWV02RZoLh+McXrsxEvqi/ycgymctlhJhssqDnD+E+FA==} resolution: {integrity: sha512-U8XBk6Cfy8MjKG41Uyo+fqBpdhu7xUSnhiCNoODRaAtWV02RZoLh+McXrsxEvqi/ycgymctlhJhssqDnD+E+FA==}
engines: {node: '>=16.9'} engines: {node: '>=16.9'}