mirror of
https://github.com/ivabus/gui
synced 2025-06-08 00:00:27 +03:00
commit
1cfe217d11
19 changed files with 166 additions and 120 deletions
|
@ -102,7 +102,7 @@
|
||||||
"height": 600,
|
"height": 600,
|
||||||
"resizable": true,
|
"resizable": true,
|
||||||
"title": "gui",
|
"title": "gui",
|
||||||
"width": 1024,
|
"width": 1200,
|
||||||
"decorations": false
|
"decorations": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
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 SearchInput from '@tea/ui/SearchInput/SearchInput.svelte';
|
import SearchInput from '@tea/ui/SearchInput/SearchInput.svelte';
|
||||||
|
import Button from '@tea/ui/Button/Button.svelte';
|
||||||
|
|
||||||
import { beforeUpdate } from 'svelte';
|
import { beforeUpdate } from 'svelte';
|
||||||
|
|
||||||
|
@ -82,11 +83,13 @@
|
||||||
|
|
||||||
{#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}>
|
||||||
|
<Button class="h-16 text-left pl-4 text-white" active={route.active}>{route.label}</Button>
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
<li class="nav_button">
|
<li class="nav_button">
|
||||||
<button on:click={openGithub}>VIEW ON GITHUB</button>
|
<Button class="h-16 text-left pl-4 text-white" onClick={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">
|
||||||
|
@ -112,7 +115,10 @@
|
||||||
.nav_button {
|
.nav_button {
|
||||||
transition: all 0.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 button {
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
.nav_button:hover {
|
.nav_button:hover {
|
||||||
color: theme('colors.black');
|
color: theme('colors.black');
|
||||||
|
|
|
@ -1,6 +1,43 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import '$appcss';
|
import '$appcss';
|
||||||
import Placeholder from '$components/Placeholder/Placeholder.svelte';
|
import '@tea/ui/icons/icons.css';
|
||||||
|
import type { Package } from '@tea/ui/types';
|
||||||
|
import Button from '@tea/ui/Button/Button.svelte';
|
||||||
|
import StarRating from '@tea/ui/StarRating/StarRating.svelte';
|
||||||
|
|
||||||
|
export let pkg: Package;
|
||||||
|
|
||||||
|
let packageRating = 0;
|
||||||
|
let copyButtonText = 'COPY';
|
||||||
|
const copyValue = `sh <(curl tea.xyz ) +${pkg.full_name}`;
|
||||||
|
|
||||||
|
const onCopy = () => {
|
||||||
|
copyButtonText = 'COPIED!';
|
||||||
|
navigator.clipboard.writeText(copyValue);
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Placeholder label="PackageBanner" />
|
<section class="border-gray border bg-black mt-4">
|
||||||
|
<header class="flex p-2">
|
||||||
|
<figure class="w-1/3 grow-1">
|
||||||
|
<img width={260} src={pkg.thumb_image_url} alt={pkg.full_name} />
|
||||||
|
</figure>
|
||||||
|
<article class="w-2/3 p-4">
|
||||||
|
<h3 class="text-primary text-5xl">{pkg.full_name}</h3>
|
||||||
|
{#if pkg.maintainer}
|
||||||
|
<h3>* {pkg.maintainer}</h3>
|
||||||
|
{/if}
|
||||||
|
<div class="mt-4">
|
||||||
|
<StarRating maxRating={5} rating={packageRating} />
|
||||||
|
</div>
|
||||||
|
<p class="font-sono mt-4 text-sm">{pkg.desc}</p>
|
||||||
|
</article>
|
||||||
|
</header>
|
||||||
|
<footer class="flex text-white border-gray border-t h-20">
|
||||||
|
<input class="flex-grow bg-black pl-4" disabled value={copyValue} />
|
||||||
|
<Button class="text-sm border-0 border-l-2 w-16" onClick={onCopy}>{copyButtonText}</Button>
|
||||||
|
<Button class="text-sm border-0 border-l-2 w-56" onClick={() => console.log('cli')}
|
||||||
|
>OPEN IN TERMINAL</Button
|
||||||
|
>
|
||||||
|
</footer>
|
||||||
|
</section>
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
</section>
|
</section>
|
||||||
<ul class="grid grid-cols-3">
|
<ul class="grid grid-cols-3">
|
||||||
{#each packages as pkg}
|
{#each packages as pkg}
|
||||||
<PackageCard {pkg} link={`/packages/${pkg.full_name}`} />
|
<PackageCard {pkg} link={`/packages/${pkg.slug}`} />
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<script>
|
<script type="ts">
|
||||||
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';
|
||||||
|
@ -8,12 +8,25 @@
|
||||||
|
|
||||||
/** @type {import('./$types').PageData} */
|
/** @type {import('./$types').PageData} */
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
|
import { packages as packagesStore } from '$libs/stores';
|
||||||
|
|
||||||
|
import type { Package } from '@tea/ui/types';
|
||||||
|
|
||||||
|
let pkg: Package;
|
||||||
|
|
||||||
|
packagesStore.subscribe((allPackages) => {
|
||||||
|
const foundPackage = allPackages.find(({ slug }) => slug === data?.slug) as Package;
|
||||||
|
if (foundPackage) {
|
||||||
|
pkg = foundPackage;
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<PageHeader>{data.title}</PageHeader>
|
<PageHeader>{pkg.full_name}</PageHeader>
|
||||||
<section>
|
<section>
|
||||||
<PackageBanner />
|
<PackageBanner {pkg} />
|
||||||
</section>
|
</section>
|
||||||
<section class="mt-8">
|
<section class="mt-8">
|
||||||
<PackageReviews />
|
<PackageReviews />
|
||||||
|
|
|
@ -4,7 +4,8 @@ import type { LoadEvent } from '@sveltejs/kit';
|
||||||
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: '',
|
||||||
|
slug: params.slug
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ async function main() {
|
||||||
|
|
||||||
const newCssFile = cssFile
|
const newCssFile = cssFile
|
||||||
.replaceAll('https://file.myfontastic.com/Fd33ifaooDVpESwnDXETgR/', '')
|
.replaceAll('https://file.myfontastic.com/Fd33ifaooDVpESwnDXETgR/', '')
|
||||||
.replaceAll('1669684803', 'tea-icons');
|
.replaceAll(fileVersion, 'tea-icons');
|
||||||
await fs.writeFileSync(path.join(iconsFolder, 'icons.css'), newCssFile, { encoding: 'utf-8' });
|
await fs.writeFileSync(path.join(iconsFolder, 'icons.css'), newCssFile, { encoding: 'utf-8' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Button from './Button.svelte';
|
import Button from './ButtonView.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 {
|
||||||
|
@ -7,47 +7,12 @@ export default {
|
||||||
tags: ['docsPage'],
|
tags: ['docsPage'],
|
||||||
render: (args) => ({
|
render: (args) => ({
|
||||||
Component: Button,
|
Component: Button,
|
||||||
props: args,
|
props: args
|
||||||
on: {
|
|
||||||
click: args.onClick
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
argTypes: {
|
argTypes: {
|
||||||
backgroundColor: { control: 'color' },
|
onClick: () => console.log('does nothing')
|
||||||
label: { control: 'text' },
|
|
||||||
onClick: { action: 'onClick' },
|
|
||||||
primary: { control: 'boolean' },
|
|
||||||
size: {
|
|
||||||
control: { type: 'select' },
|
|
||||||
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: {
|
|
||||||
primary: true,
|
|
||||||
label: 'Button'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Secondary = {
|
|
||||||
args: {
|
|
||||||
label: 'Button'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Large = {
|
|
||||||
args: {
|
|
||||||
size: 'large',
|
|
||||||
label: 'Button'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Small = {
|
|
||||||
args: {
|
|
||||||
size: 'small',
|
|
||||||
label: 'Button'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,44 +1,32 @@
|
||||||
<script type="ts">
|
<script type="ts">
|
||||||
import './button.css';
|
let clazz = '';
|
||||||
import { createEventDispatcher } from 'svelte';
|
export { clazz as class };
|
||||||
|
|
||||||
/**
|
// export let size: 'large' | 'medium' | 'small' = 'medium';
|
||||||
* Is this the principal call to action on the page?
|
|
||||||
*/
|
|
||||||
export let primary = false;
|
|
||||||
|
|
||||||
/**
|
export let onClick: undefined | (() => void) = undefined;
|
||||||
* What background color to use
|
export let active = false;
|
||||||
*/
|
|
||||||
export let backgroundColor = '';
|
|
||||||
/**
|
|
||||||
* How large should the button be?
|
|
||||||
*/
|
|
||||||
export let size: 'large' | 'medium' | 'small' = 'medium';
|
|
||||||
/**
|
|
||||||
* Button contents
|
|
||||||
*/
|
|
||||||
export let label = '';
|
|
||||||
|
|
||||||
$: mode = primary ? 'storybook-button--primary bg-primary' : 'storybook-button--secondary';
|
|
||||||
|
|
||||||
$: style = backgroundColor ? `background-color: ${backgroundColor}` : '';
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional click handler
|
|
||||||
*/
|
|
||||||
export let onClick = (event: any) => {
|
|
||||||
dispatch('click', event);
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button font-sans"
|
||||||
class={['storybook-button', `storybook-button--${size}`, 'hover:font-light', mode].join(' ')}
|
class={`p-2 font-machina text-gray w-full ${clazz} ${active ? 'active' : ''}`}
|
||||||
{style}
|
on:click={() => onClick && onClick()}
|
||||||
on:click={onClick}
|
|
||||||
>
|
>
|
||||||
{label}
|
<slot />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
button {
|
||||||
|
min-width: 100px;
|
||||||
|
transition: 0.2s ease-in-out !important;
|
||||||
|
}
|
||||||
|
button.active {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
box-shadow: inset 0px 0px 0px 5px #1a1a1a !important;
|
||||||
|
background-color: #00ffd0 !important;
|
||||||
|
color: #1a1a1a !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
5
packages/ui/src/Button/ButtonView.svelte
Normal file
5
packages/ui/src/Button/ButtonView.svelte
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import Button from './Button.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Button>Click Me</Button>
|
|
@ -1,31 +0,0 @@
|
||||||
@import '../app.css';
|
|
||||||
|
|
||||||
.storybook-button {
|
|
||||||
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
|
||||||
font-weight: 700;
|
|
||||||
border: 0;
|
|
||||||
border-radius: 3em;
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
.storybook-button--primary {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.storybook-button--secondary {
|
|
||||||
color: #333;
|
|
||||||
background-color: transparent;
|
|
||||||
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
|
|
||||||
}
|
|
||||||
.storybook-button--small {
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 10px 16px;
|
|
||||||
}
|
|
||||||
.storybook-button--medium {
|
|
||||||
font-size: 14px;
|
|
||||||
padding: 11px 20px;
|
|
||||||
}
|
|
||||||
.storybook-button--large {
|
|
||||||
font-size: 16px;
|
|
||||||
padding: 12px 24px;
|
|
||||||
}
|
|
|
@ -23,7 +23,7 @@ export default {
|
||||||
tags: ['docsPage'],
|
tags: ['docsPage'],
|
||||||
render: ({ pkg, link }: { pkg: Package; link: string }) => ({
|
render: ({ pkg, link }: { pkg: Package; link: string }) => ({
|
||||||
Component: PackageCard,
|
Component: PackageCard,
|
||||||
props: { pkg }
|
props: { pkg, link }
|
||||||
}),
|
}),
|
||||||
argTypes: {
|
argTypes: {
|
||||||
pkg: {
|
pkg: {
|
||||||
|
|
25
packages/ui/src/StarRating/StarRating.svelte
Normal file
25
packages/ui/src/StarRating/StarRating.svelte
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<script type="ts">
|
||||||
|
import '../app.css';
|
||||||
|
|
||||||
|
export let rating = 0;
|
||||||
|
export let maxRating = 5;
|
||||||
|
|
||||||
|
let stars: string[] = [];
|
||||||
|
for (let i = 1; i <= maxRating; i++) {
|
||||||
|
const mod1 = rating % 1;
|
||||||
|
|
||||||
|
if (i < rating) {
|
||||||
|
stars.push('icon-star-full');
|
||||||
|
} else if (mod1 >= 0.5) {
|
||||||
|
stars.push('icon-star-half');
|
||||||
|
} else {
|
||||||
|
stars.push('icon-star-empty');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section class="flex text-primary">
|
||||||
|
{#each stars as star}
|
||||||
|
<i class={star} />
|
||||||
|
{/each}
|
||||||
|
</section>
|
25
packages/ui/src/StarRating/StartRating.stories.ts
Normal file
25
packages/ui/src/StarRating/StartRating.stories.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import StarRating from './StarRating.svelte';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Example/StarRating',
|
||||||
|
component: StarRating,
|
||||||
|
// This component will have an automatically generated docsPage entry: https://storybook.js.org/docs/7.0/svelte/writing-docs/docs-page
|
||||||
|
tags: [],
|
||||||
|
render: (args) => ({
|
||||||
|
Component: StarRating,
|
||||||
|
props: args
|
||||||
|
}),
|
||||||
|
parameters: {
|
||||||
|
// More on how to position stories at: https://storybook.js.org/docs/7.0/svelte/configure/story-layout
|
||||||
|
// layout: 'fullscreen'
|
||||||
|
},
|
||||||
|
argTypes: {
|
||||||
|
// onLogin: { action: 'onLogin' },
|
||||||
|
// onLogout: { action: 'onLogout' },
|
||||||
|
// onCreateAccount: { action: 'onCreateAccount' }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Example = {
|
||||||
|
args: {}
|
||||||
|
};
|
Binary file not shown.
|
@ -25,4 +25,7 @@
|
||||||
<glyph glyph-name="pattern-random-19" unicode="p" d="M439 512l-201 0 0-91-37 0 0 91-201 0 0-201 91 0 0-110-91 0 0-201 512 0 0 421-73 0z m-183-18l165 0 0-73-165 0z m0-92l165 0 0-73-165 0z m-238-73l0 165 165 0 0-73-92 0 0-92z m165 73l0-73-73 0 0 73z m-165-384l0 165 73 0 0-165z m92 0l0 165 73 0 0-165z m384 384l0-384-293 0 0 183-91 0 0 110 91 0 0 91 37 0 0-91 201 0 0 91z m-256-347l201 0 0 201-201 0z m18 183l165 0 0-165-165 0z"/>
|
<glyph glyph-name="pattern-random-19" unicode="p" d="M439 512l-201 0 0-91-37 0 0 91-201 0 0-201 91 0 0-110-91 0 0-201 512 0 0 421-73 0z m-183-18l165 0 0-73-165 0z m0-92l165 0 0-73-165 0z m-238-73l0 165 165 0 0-73-92 0 0-92z m165 73l0-73-73 0 0 73z m-165-384l0 165 73 0 0-165z m92 0l0 165 73 0 0-165z m384 384l0-384-293 0 0 183-91 0 0 110 91 0 0 91 37 0 0-91 201 0 0 91z m-256-347l201 0 0 201-201 0z m18 183l165 0 0-165-165 0z"/>
|
||||||
<glyph glyph-name="click-copy-icon" unicode="q" d="M380 440l0 71-325 0 0-439 77 0 0-71 325 0 0 439z m-304-347l0 397 284 0 0-50-228 0 0-347z m360-71l-284 0 0 397 284 0z"/>
|
<glyph glyph-name="click-copy-icon" unicode="q" d="M380 440l0 71-325 0 0-439 77 0 0-71 325 0 0 439z m-304-347l0 397 284 0 0-50-228 0 0-347z m360-71l-284 0 0 397 284 0z"/>
|
||||||
<glyph glyph-name="search-icon" unicode="r" d="M422 340c0 92-74 166-166 166-92 0-166-74-166-166 0-85 64-156 147-165l0-169 38 0 0 169c83 9 147 80 147 165z m-166-128c-71 0-128 57-128 128 0 71 57 128 128 128 71 0 128-57 128-128 0-71-57-128-128-128z"/>
|
<glyph glyph-name="search-icon" unicode="r" d="M422 340c0 92-74 166-166 166-92 0-166-74-166-166 0-85 64-156 147-165l0-169 38 0 0 169c83 9 147 80 147 165z m-166-128c-71 0-128 57-128 128 0 71 57 128 128 128 71 0 128-57 128-128 0-71-57-128-128-128z"/>
|
||||||
|
<glyph glyph-name="star-full" unicode="s" d="M494 327c0-4-3-9-8-14l-103-101 24-143c0-1 0-3 0-5 0-4-1-8-3-10-2-3-4-5-8-5-4 0-8 2-12 4l-128 67-128-67c-4-2-8-4-12-4-4 0-7 2-9 5-2 2-3 6-3 10 0 1 0 3 1 5l24 143-104 101c-4 6-7 10-7 14 0 7 6 12 16 13l144 21 64 130c4 8 8 12 14 12 6 0 10-4 14-12l64-130 144-21c10-1 16-6 16-13z"/>
|
||||||
|
<glyph glyph-name="star-half" unicode="t" d="M357 239l74 71-102 15-19 3-9 17-45 92 0-275 17-9 91-48-17 101-4 19z m129 74l-103-101 24-143c1-6 1-11-2-14-2-4-5-6-9-6-4 0-7 2-12 4l-128 67-128-67c-5-2-8-4-12-4-4 0-7 2-9 6-3 3-3 8-2 14l24 143-104 101c-6 7-8 12-6 17 2 6 7 9 15 10l144 21 64 130c4 8 8 12 14 12 5 0 10-4 14-12l64-130 144-21c8-1 13-4 15-10 2-5 0-10-7-17z"/>
|
||||||
|
<glyph glyph-name="star-empty" unicode="u" d="M343 225l88 85-121 18-54 109-54-109-121-18 88-85-21-120 108 57 108-57z m151 102c0-4-3-9-8-14l-103-101 24-143c0-1 0-3 0-5 0-10-3-15-11-15-4 0-8 2-12 4l-128 67-128-67c-4-2-8-4-12-4-4 0-7 2-9 5-2 2-3 6-3 10 0 1 0 3 1 5l24 143-104 101c-4 6-7 10-7 14 0 7 6 12 16 13l144 21 64 130c4 8 8 12 14 12 6 0 10-4 14-12l64-130 144-21c10-1 16-6 16-13z"/>
|
||||||
</font></defs></svg>
|
</font></defs></svg>
|
||||||
|
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 10 KiB |
Binary file not shown.
Binary file not shown.
|
@ -91,3 +91,12 @@
|
||||||
.icon-search-icon:before {
|
.icon-search-icon:before {
|
||||||
content: '\72';
|
content: '\72';
|
||||||
}
|
}
|
||||||
|
.icon-star-full:before {
|
||||||
|
content: '\73';
|
||||||
|
}
|
||||||
|
.icon-star-half:before {
|
||||||
|
content: '\74';
|
||||||
|
}
|
||||||
|
.icon-star-empty:before {
|
||||||
|
content: '\75';
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue