add info and server section

This commit is contained in:
Malte Teichert
2024-05-19 18:47:51 +02:00
parent f2467815a1
commit 13ecd58c9f
9 changed files with 223 additions and 33 deletions

View File

@@ -12,34 +12,35 @@
"format": "prettier --write ."
},
"devDependencies": {
"@skeletonlabs/skeleton": "2.10.0",
"@skeletonlabs/tw-plugin": "0.4.0",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@tailwindcss/forms": "0.5.7",
"@tailwindcss/typography": "0.5.13",
"@types/eslint": "^8.56.0",
"@types/node": "20.12.12",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"autoprefixer": "10.4.19",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.35.1",
"postcss": "8.4.38",
"prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2",
"svelte": "^4.2.7",
"svelte-check": "^3.6.0",
"tailwindcss": "3.4.3",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^5.0.3",
"postcss": "8.4.38",
"autoprefixer": "10.4.19",
"tailwindcss": "3.4.3",
"@skeletonlabs/skeleton": "2.10.0",
"@skeletonlabs/tw-plugin": "0.4.0",
"vite-plugin-tailwind-purgecss": "0.3.3",
"@tailwindcss/typography": "0.5.13",
"@tailwindcss/forms": "0.5.7",
"@types/node": "20.12.12"
"vite-plugin-tailwind-purgecss": "0.3.3"
},
"type": "module",
"dependencies": {
"@floating-ui/dom": "1.6.5"
"@floating-ui/dom": "1.6.5",
"svelte-persisted-store": "^0.9.2"
}
}

22
pnpm-lock.yaml generated
View File

@@ -11,9 +11,9 @@ importers:
'@floating-ui/dom':
specifier: 1.6.5
version: 1.6.5
highlight.js:
specifier: 11.9.0
version: 11.9.0
svelte-persisted-store:
specifier: ^0.9.2
version: 0.9.2(svelte@4.2.17)
devDependencies:
'@skeletonlabs/skeleton':
specifier: 2.10.0
@@ -909,10 +909,6 @@ packages:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
highlight.js@11.9.0:
resolution: {integrity: sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==}
engines: {node: '>=12.0.0'}
ignore@5.3.1:
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
engines: {node: '>= 4'}
@@ -1414,6 +1410,12 @@ packages:
peerDependencies:
svelte: ^3.19.0 || ^4.0.0
svelte-persisted-store@0.9.2:
resolution: {integrity: sha512-jp7W98yMgBhgz5fWnjZBCmCX89Rse13iqVpjK+1ByS6iYkvW9WT+F2vwsep3f0Zy/tnGYbb8MI+9Vx7W0NQsPg==}
engines: {node: '>=0.14'}
peerDependencies:
svelte: ^3.48.0 || ^4.0.0 || ^5.0.0-next.0
svelte-preprocess@5.1.4:
resolution: {integrity: sha512-IvnbQ6D6Ao3Gg6ftiM5tdbR6aAETwjhHV+UKGf5bHGYR69RQvF1ho0JKPcbUON4vy4R7zom13jPjgdOWCQ5hDA==}
engines: {node: '>= 16.0.0'}
@@ -2402,8 +2404,6 @@ snapshots:
dependencies:
function-bind: 1.1.2
highlight.js@11.9.0: {}
ignore@5.3.1: {}
import-fresh@3.3.0:
@@ -2873,6 +2873,10 @@ snapshots:
dependencies:
svelte: 4.2.17
svelte-persisted-store@0.9.2(svelte@4.2.17):
dependencies:
svelte: 4.2.17
svelte-preprocess@5.1.4(postcss-load-config@4.0.2(postcss@8.4.38))(postcss@8.4.38)(svelte@4.2.17)(typescript@5.4.5):
dependencies:
'@types/pug': 2.0.10

View File

@@ -0,0 +1,48 @@
<script lang="ts">
import { popup, type PopupSettings } from '@skeletonlabs/skeleton';
import Info from '../icons/Info.svelte';
export let id: number;
export let url: string;
export let description: string = '';
const descriptionTooltip: PopupSettings = {
event: 'click',
target: `descriptionTooltip${id}`,
placement: 'top'
};
</script>
<div class="space-y-4">
<label class="space-y-2">
<span>URL (required)</span>
<input
class="input"
name="url {id}"
placeholder="https://api.example.com"
type="url"
bind:value={url}
/>
</label>
<label class="space-y-2">
<span>
Description (optional)
<button type="button" use:popup={descriptionTooltip}>
<Info />
</button>
</span>
<textarea
class="textarea"
name="description {id}"
placeholder="The main API server"
bind:value={description}
/>
</label>
</div>
<!-- Description Tooltip -->
<div class="card px-4 py-2 variant-filled-primary" data-popup="descriptionTooltip{id}">
<p>Optional multiline or single-line description. Supports Markdown.</p>
<div class="arrow variant-filled-primary" />
</div>

View File

@@ -0,0 +1,14 @@
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z"
/>
</svg>

After

Width:  |  Height:  |  Size: 365 B

View File

@@ -0,0 +1,53 @@
<script lang="ts">
import { popup, type PopupSettings } from '@skeletonlabs/skeleton';
import Info from '../icons/Info.svelte';
import { openApiStore } from '$lib';
const descriptionTooltip: PopupSettings = {
event: 'click',
target: 'descriptionTooltip',
placement: 'top'
};
</script>
<form class="container mx-auto card px-6 py-4 space-y-4">
<label class="text-xl space-y-2">
<span>Title (required)</span>
<input
class="input"
name="title"
placeholder="Sample API"
type="text"
bind:value={$openApiStore.title}
/>
</label>
<label class="text-xl space-y-2">
<span>
Description (optional) <button type="button" use:popup={descriptionTooltip}>
<Info />
</button>
</span>
<textarea
class="textarea"
name="description"
placeholder="Sample API description"
bind:value={$openApiStore.description}
/>
</label>
<label class="text-xl space-y-2">
<span>Version (required)</span>
<input
class="input"
name="version"
placeholder="0.1.0"
type="text"
bind:value={$openApiStore.version}
/>
</label>
</form>
<!-- Description Tooltip -->
<div class="card px-4 py-2 variant-filled-primary" data-popup="descriptionTooltip">
<p>Optional multiline or single-line description. Supports Markdown.</p>
<div class="arrow variant-filled-primary" />
</div>

View File

@@ -0,0 +1,44 @@
<script lang="ts">
import { openApiStore } from '$lib';
import ServerInput from '../atoms/ServerInput.svelte';
const addServer = () => {
let tempServers = [...$openApiStore.servers];
tempServers.push({ url: '', description: '' });
$openApiStore.servers = tempServers;
};
const removeServer = (index: number) => {
let tempServers = [...$openApiStore.servers];
tempServers.splice(index, 1);
$openApiStore.servers = tempServers;
};
</script>
<form class="container mx-auto card px-6 py-4 space-y-6">
<ul class="list space-y-6">
{#each $openApiStore.servers as server, index}
<li class="!block">
<span class="flex w-full justify-end">
<button
type="button"
class="btn btn-sm variant-ringed-error hover:variant-filled-error"
on:click={() => removeServer(index)}
>
Remove Server
</button>
</span>
<ServerInput id={1} bind:url={server.url} bind:description={server.description} />
</li>
{#if index < $openApiStore.servers.length - 1}
<hr />
{/if}
{/each}
</ul>
<!-- Add another Server Button -->
<span class="flex justify-center" class:!mt-0={$openApiStore.servers.length === 0}>
<button type="button" class="btn variant-filled-primary" on:click={addServer}>
Add Server
</button>
</span>
</form>

View File

@@ -1 +1,9 @@
// place files you want to import through the `$lib` alias in this folder.
import type { OpenAPI } from './types';
import { persisted } from 'svelte-persisted-store';
export const openApiStore = persisted<OpenAPI>('openApi', {
title: '',
version: '',
description: '',
servers: []
});

14
src/lib/types.ts Normal file
View File

@@ -0,0 +1,14 @@
export interface OpenAPI extends Info {
servers: Server[];
}
export interface Info {
title: string;
version: string;
description?: string;
}
export interface Server {
url: string;
description?: string;
}

View File

@@ -1,39 +1,43 @@
<script lang="ts">
import Servers from '$lib/components/sections/Servers.svelte';
import Info from '$lib/components/sections/Info.svelte';
import { TabGroup, Tab } from '@skeletonlabs/skeleton';
import { persisted } from 'svelte-persisted-store';
let tabSet: number = 0;
// let tabSet: number = 0;
const tabSet = persisted<number>('tabSet', 0);
</script>
<TabGroup>
<Tab bind:group={tabSet} name="info" value={0}>
<Tab bind:group={$tabSet} name="info" value={0}>
<h4 class="h4">Info</h4>
</Tab>
<Tab bind:group={tabSet} name="authentication" value={1}>
<Tab bind:group={$tabSet} name="authentication" value={1}>
<h4 class="h4">Authentication</h4>
</Tab>
<Tab bind:group={tabSet} name="servers" value={2}>
<Tab bind:group={$tabSet} name="servers" value={2}>
<h4 class="h4">Servers</h4>
</Tab>
<Tab bind:group={tabSet} name="paths" value={3}>
<Tab bind:group={$tabSet} name="paths" value={3}>
<h4 class="h4">Paths</h4>
</Tab>
<Tab bind:group={tabSet} name="components" value={4}>
<Tab bind:group={$tabSet} name="components" value={4}>
<h4 class="h4">Components</h4>
</Tab>
<svelte:fragment slot="panel">
{#if tabSet === 0}
<p>Info</p>
{#if $tabSet === 0}
<Info></Info>
{/if}
{#if tabSet === 1}
{#if $tabSet === 1}
<p>Authentication</p>
{/if}
{#if tabSet === 2}
<p>Servers</p>
{#if $tabSet === 2}
<Servers />
{/if}
{#if tabSet === 3}
{#if $tabSet === 3}
<p>Paths</p>
{/if}
{#if tabSet === 4}
{#if $tabSet === 4}
<p>Components</p>
{/if}
</svelte:fragment>