Add component snippet generator (#108)

This commit is contained in:
ABarnob
2021-09-16 21:47:35 +06:00
committed by GitHub
parent 7e5ff4446b
commit 2f68cd89da
8 changed files with 280 additions and 9 deletions

View File

@@ -12,7 +12,7 @@ import prettier from 'prettier';
const files = [
'src/routes/components/components.json',
'src/routes/templates/templates.json',
'src/routes/tooling/tools.json'
'src/routes/tools/tools.json'
];
if (!process.env.GH_TOKEN) {

View File

@@ -5,7 +5,7 @@
const linksLeft = [
['/templates', 'templates'],
['/components', 'components'],
['/tooling', 'tooling']
['/tools', 'tools']
];
const linksRight = [
['/recipes', 'recipes'],

View File

@@ -87,7 +87,7 @@
</Button>
</div>
<a href="/help/components" class="submit">Submit a component</a>
<a href="/help/submitting?type=component" class="submit">Submit a component</a>
<input
class="searchbar"
type="text"

View File

@@ -0,0 +1,271 @@
<script>
import SvelteSelect from 'svelte-select';
import components from '../components/components.json';
import templates from '../templates/templates.json';
import tools from '../tools/tools.json';
import { tick } from 'svelte';
import { page } from '$app/stores';
import { copyToClipboard } from '$lib/utils/clipboard';
import { extractUnique } from '$lib/utils/extractUnique';
const repoURL = 'https://github.com/svelte-society/sveltesociety.dev';
const typeQuery = $page.query.get('type');
const types = ['Component', 'Template', 'Tool'].map((t) => ({
label: t,
value: t.toLowerCase()
}));
const data = {
component: {
tags: extractUnique(components, 'tags'),
categories: [...extractUnique(components, 'category').filter((cat) => cat.label !== '')]
},
template: {
tags: extractUnique(templates, 'tags'),
categories: extractUnique(templates, 'category')
},
tool: {
tags: extractUnique(tools, 'tags'),
categories: extractUnique(tools, 'category')
}
};
let clipboardCopy = false;
const copy = () => {
copyToClipboard(JSON.stringify(jsonSnippet, null, 4)).then(() => (clipboardCopy = false));
clipboardCopy = true;
};
let type = types.find((t) => t.value == typeQuery) || types[0];
let title = 'svelte-lorem-ipsum';
let url = 'https://github.com/sveltejs/svelte-lorem-ipsum';
let description = 'A dummy text generator that does not exist';
let npm = 'svelte-lorem-ipsum';
let addedOn = todaysDate();
let category;
let tags;
$: pathName = `${type.value}s`;
$: jsonSnippet = {
title,
url,
description,
npm,
addedOn,
category: category?.value,
tags: tags?.map((tag) => tag.value)
};
$: currentTags = data[type.value].tags;
$: currentCategories = data[type.value].categories;
function padWithZero(date) {
return date.toString().padStart(2, '0');
}
function todaysDate() {
const date = new Date();
const day = padWithZero(date.getDate());
const month = padWithZero(date.getMonth() + 1);
const year = date.getFullYear();
const sep = '-';
return [year, month, day].join(sep);
}
async function clearCategoryAndTags() {
await tick();
category = null;
tags = null;
}
</script>
<h1>Submitting a new component</h1>
<p>
To add a new component on the website, the process is rather simple. You have to add a snippet in
the appropriate file.
</p>
<h2>Generating file contents snippet</h2>
<p>
Each component is represented by a JSON Object. Use the generator below to generate the Object.
</p>
<p><code>*</code> marked fields are required</p>
<div class="json-generator">
<div class="input-wrapper">
<label for="type">Type:</label>
<div>
<SvelteSelect
id="type"
items={types}
isClearable={false}
showIndicator
bind:value={type}
on:select={clearCategoryAndTags}
/>
<span class="input-helper">The type of snippet to generate</span>
</div>
</div>
<div class="input-wrapper">
<label for="title" class="required">Title:</label>
<div>
<input id="title" type="text" required bind:value={title} />
<span class="input-helper">Name of the component</span>
</div>
</div>
<div class="input-wrapper">
<label for="url">URL:</label>
<div>
<input id="url" type="url" bind:value={url} />
<span class="input-helper">The URL where to find it</span>
</div>
</div>
<div class="input-wrapper">
<label for="desc">Description:</label>
<div>
<input id="desc" type="text" bind:value={description} />
<span class="input-helper">A short description of the component</span>
</div>
</div>
<div class="input-wrapper">
<label for="npm">NPM:</label>
<div>
<input id="npm" type="text" bind:value={npm} />
<span class="input-helper">The npm name of the component</span>
</div>
</div>
<div class="input-wrapper">
<label for="adden-on" class="required">Added On:</label>
<div>
<input id="adden-on" type="date" required bind:value={addedOn} />
<span class="input-helper">
The date when the component have been added on the website (generally its today)
</span>
</div>
</div>
<div class="input-wrapper">
<label for="category">Category:</label>
<div>
<SvelteSelect
id="category"
items={currentCategories}
isClearable={false}
showIndicator
bind:value={category}
/>
<span class="input-helper">The category of the component</span>
</div>
</div>
<div class="input-wrapper">
<label for="tags" class="required">Tags:</label>
<div>
<SvelteSelect id="category" items={currentTags} showIndicator isMulti bind:value={tags} />
<span class="input-helper">A list of tags</span>
</div>
</div>
</div>
<h2>JSON Snippet</h2>
<pre>
{JSON.stringify(jsonSnippet,null,4)}<button on:click={copy}>{clipboardCopy ? 'Copied' : 'Copy'}</button>
</pre>
<br />
Copy this snippet and add it to
<a href="{repoURL}/blob/staging/src/routes/{pathName}/{pathName}.json">{pathName}.json</a>. You can
propose your changes
<a href="{repoURL}/edit/staging/src/routes/{pathName}/{pathName}.json">directly in GitHub</a>.
<style>
.json-generator,
pre {
max-width: var(--s-max);
padding: var(--s-4);
border-radius: 14px;
background-color: #f3f6f9;
}
.json-generator {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: var(--s-4) var(--s-20);
padding-block: var(--s-5);
}
.input-wrapper {
--borderRadius: 5px;
--border: 2px solid var(--dark-gray);
--borderFocusColor: var(--secondary);
--borderHoverColor: var(--secondary);
--itemIsActiveBG: var(--secondary);
--multiItemActiveBG: var(--secondary);
--indicatorColor: var(--dark-gray);
--indicatorTop: calc(50% - 13px);
display: flex;
gap: var(--s-4);
}
.input-wrapper label {
min-width: 10ch;
}
.input-wrapper > div {
display: flex;
flex-grow: 1;
gap: var(--s-1);
flex-direction: column;
}
input {
width: 100%;
padding: var(--s-2) 16px;
border: var(--border);
border-radius: var(--borderRadius);
font-size: inherit;
}
input:hover,
input:focus {
outline: none;
border-color: var(--borderFocusColor);
}
.input-helper {
color: var(--dark-gray);
font-size: var(--font-100);
}
.required::after {
content: '*';
color: var(--error);
}
pre {
position: relative;
}
pre button {
position: absolute;
top: var(--s-4);
right: var(--s-4);
padding: var(--s-1);
border: none;
border-radius: 5px;
color: var(--white);
background-color: var(--primary-color);
cursor: pointer;
}
@media screen and (max-width: 700px) {
.json-generator {
grid-template-columns: minmax(0, 1fr);
}
}
@media screen and (max-width: 450px) {
.input-wrapper {
flex-direction: column;
gap: var(--s-1);
}
}
</style>

View File

@@ -13,7 +13,7 @@
let filterTag = [];
let selectedTags = null;
const categoryItems = [{ label: 'all', value: null }, ...extractUnique(components, 'category')];
const categoryItems = [{ label: 'All', value: null }, ...extractUnique(components, 'category')];
let selectedCategory = null;
let filterCategory = null;
@@ -73,7 +73,7 @@
isClearable={false}
/>
<a href="/help/components" class="submit">Submit a template</a>
<a href="/help/submitting?type=template" class="submit">Submit a template</a>
</div>
<input

View File

@@ -14,7 +14,7 @@
let filterTag = [];
let selectedTags = null;
const categoryItems = [{ label: 'all', value: null }, ...extractUnique(components, 'category')];
const categoryItems = [{ label: 'All', value: null }, ...extractUnique(components, 'category')];
let selectedCategory = null;
let filterCategory = null;
@@ -50,10 +50,10 @@
</script>
<svelte:head>
<title>Tooling - Svelte Society</title>
<title>Tools - Svelte Society</title>
</svelte:head>
<SearchLayout title="Tooling">
<SearchLayout title="Tools">
<section slot="controls" class="controls">
<div class="inputs">
<Select bind:value={selectedTags} items={tagItems} isMulti label="Tags" />
@@ -72,7 +72,7 @@
showIndicator
isClearable={false}
/>
<a href="/help/components" class="submit">Submit a tool</a>
<a href="/help/submitting?type=tool" class="submit">Submit a tool</a>
</div>
<input