Merge pull request #47 from teaxyz/package-banner

Package Page Banner
This commit is contained in:
Neil 2022-11-30 08:07:57 +08:00 committed by GitHub
commit 1cfe217d11
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 166 additions and 120 deletions

View file

@ -102,7 +102,7 @@
"height": 600, "height": 600,
"resizable": true, "resizable": true,
"title": "gui", "title": "gui",
"width": 1024, "width": 1200,
"decorations": false "decorations": false
} }
] ]

View file

@ -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');

View file

@ -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>

View file

@ -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>

View file

@ -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 />

View file

@ -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
}; };
} }

View file

@ -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' });
} }

View file

@ -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'
}
};

View file

@ -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>

View file

@ -0,0 +1,5 @@
<script lang="ts">
import Button from './Button.svelte';
</script>
<Button>Click Me</Button>

View file

@ -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;
}

View file

@ -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: {

View 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>

View 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: {}
};

View file

@ -25,4 +25,7 @@
<glyph glyph-name="pattern-random-19" unicode="&#112;" 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="&#112;" 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="&#113;" 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="&#113;" 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="&#114;" 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="&#114;" 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="&#115;" 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="&#116;" 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="&#117;" 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

View file

@ -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';
}