You've already forked AstralRinth
forked from didirus/AstralRinth
Update style vars + Add examples to docs + Add Avatar, NavRow, Pagination, & Link
This commit is contained in:
@@ -38,8 +38,8 @@
|
||||
"postcss-nested": "^5.0.6",
|
||||
"postcss-preset-env": "^7.4.2",
|
||||
"postcss-strip-inline-comments": "^0.1.5",
|
||||
"prettier": "^2.5.1",
|
||||
"prettier-plugin-svelte": "^2.5.0",
|
||||
"prism-svelte": "^0.5.0",
|
||||
"prismjs": "^1.27.0",
|
||||
"svelte": "^3.44.0",
|
||||
"svelte-check": "^2.2.6",
|
||||
"svelte-preprocess": "^4.10.1",
|
||||
@@ -65,5 +65,8 @@
|
||||
"bugs": {
|
||||
"url": "https://github.com/modrinth/omorphia/issues"
|
||||
},
|
||||
"homepage": "https://omorphia.modrinth.com"
|
||||
"homepage": "https://omorphia.modrinth.com",
|
||||
"dependencies": {
|
||||
"sanitize.css": "^13.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
42
pnpm-lock.yaml
generated
42
pnpm-lock.yaml
generated
@@ -23,8 +23,9 @@ specifiers:
|
||||
postcss-nested: ^5.0.6
|
||||
postcss-preset-env: ^7.4.2
|
||||
postcss-strip-inline-comments: ^0.1.5
|
||||
prettier: ^2.5.1
|
||||
prettier-plugin-svelte: ^2.5.0
|
||||
prism-svelte: ^0.5.0
|
||||
prismjs: ^1.27.0
|
||||
sanitize.css: ^13.0.0
|
||||
svelte: ^3.44.0
|
||||
svelte-check: ^2.2.6
|
||||
svelte-preprocess: ^4.10.1
|
||||
@@ -34,13 +35,16 @@ specifiers:
|
||||
typescript: ~4.6.2
|
||||
unplugin-icons: ^0.13.3
|
||||
|
||||
dependencies:
|
||||
sanitize.css: 13.0.0
|
||||
|
||||
devDependencies:
|
||||
'@iconify-json/carbon': 1.1.1
|
||||
'@iconify-json/heroicons-outline': 1.1.1
|
||||
'@iconify-json/lucide': 1.1.7
|
||||
'@poppanator/sveltekit-svg': 0.3.1_svelte@3.46.4
|
||||
'@sveltejs/adapter-auto': 1.0.0-next.33
|
||||
'@sveltejs/kit': 1.0.0-next.299_svelte@3.46.4
|
||||
'@sveltejs/kit': 1.0.0-next.301_svelte@3.46.4
|
||||
'@typescript-eslint/eslint-plugin': 5.14.0_e3f5f4efe2bd492e36eb6c1c619dfc98
|
||||
'@typescript-eslint/parser': 5.14.0_eslint@7.32.0+typescript@4.6.2
|
||||
autoprefixer: 10.4.2_postcss@8.4.8
|
||||
@@ -57,8 +61,8 @@ devDependencies:
|
||||
postcss-nested: 5.0.6_postcss@8.4.8
|
||||
postcss-preset-env: 7.4.2_postcss@8.4.8
|
||||
postcss-strip-inline-comments: 0.1.5
|
||||
prettier: 2.5.1
|
||||
prettier-plugin-svelte: 2.6.0_prettier@2.5.1+svelte@3.46.4
|
||||
prism-svelte: 0.5.0
|
||||
prismjs: 1.27.0
|
||||
svelte: 3.46.4
|
||||
svelte-check: 2.4.5_33233005e4be8b4492b63cc9de0a2fd4
|
||||
svelte-preprocess: 4.10.4_8c88c4f1b7a55bcfafd385f58ef1abcd
|
||||
@@ -360,8 +364,8 @@ packages:
|
||||
esbuild: 0.14.25
|
||||
dev: true
|
||||
|
||||
/@sveltejs/kit/1.0.0-next.299_svelte@3.46.4:
|
||||
resolution: {integrity: sha512-m8VBccfX3ozgHjjz193pZbfTK02P47bqdhj07cveUEhVLwbujOVWbgblPCrNh0rkTER7z1k5hRZnWrFYaDjQJA==}
|
||||
/@sveltejs/kit/1.0.0-next.301_svelte@3.46.4:
|
||||
resolution: {integrity: sha512-F/XP1VEu+fpvgY04JekNxAFupccNMKOyXtbox0LwNJvBulL15/Tzy6tf4g+9t2Jy7mprwI3h0ZC9G/nVujRFnQ==}
|
||||
engines: {node: '>=14.13'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@@ -3114,26 +3118,14 @@ packages:
|
||||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/prettier-plugin-svelte/2.6.0_prettier@2.5.1+svelte@3.46.4:
|
||||
resolution: {integrity: sha512-NPSRf6Y5rufRlBleok/pqg4+1FyGsL0zYhkYP6hnueeL1J/uCm3OfOZPsLX4zqD9VAdcXfyEL2PYqGv8ZoOSfA==}
|
||||
peerDependencies:
|
||||
prettier: ^1.16.4 || ^2.0.0
|
||||
svelte: ^3.2.0
|
||||
dependencies:
|
||||
prettier: 2.5.1
|
||||
svelte: 3.46.4
|
||||
dev: true
|
||||
|
||||
/prettier/2.5.1:
|
||||
resolution: {integrity: sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/prism-svelte/0.4.7:
|
||||
resolution: {integrity: sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==}
|
||||
dev: true
|
||||
|
||||
/prism-svelte/0.5.0:
|
||||
resolution: {integrity: sha512-db91Bf3pRGKDPz1lAqLFSJXeW13mulUJxhycysFpfXV5MIK7RgWWK2E5aPAa71s8TCzQUXxF5JOV42/iOs6QkA==}
|
||||
dev: true
|
||||
|
||||
/prismjs/1.27.0:
|
||||
resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -3287,6 +3279,10 @@ packages:
|
||||
rimraf: 2.7.1
|
||||
dev: true
|
||||
|
||||
/sanitize.css/13.0.0:
|
||||
resolution: {integrity: sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==}
|
||||
dev: false
|
||||
|
||||
/semver-diff/3.1.1:
|
||||
resolution: {integrity: sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
@@ -2,10 +2,10 @@ const config = {
|
||||
plugins: [
|
||||
require('postcss-import'),
|
||||
require('postcss-strip-inline-comments'),
|
||||
require('postcss-extend-rule'),
|
||||
require('postcss-nested'),
|
||||
require('postcss-preset-env'),
|
||||
require('autoprefixer'),
|
||||
require('postcss-extend-rule'),
|
||||
process.env.NODE_ENV === 'development' && require('cssnano')({
|
||||
preset: 'default',
|
||||
})
|
||||
|
||||
94
src/lib/components/Avatar.svelte
Normal file
94
src/lib/components/Avatar.svelte
Normal file
@@ -0,0 +1,94 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte'
|
||||
import { classCombine } from '$lib/utils/classCombine'
|
||||
|
||||
export let src: string | null
|
||||
export let size: 'xs' | 'sm' | 'md' | 'lg'
|
||||
export let circle = false
|
||||
export let floatUp = false
|
||||
|
||||
let className: string;
|
||||
$: className = classCombine(['avatar', circle && 'avatar--circle', `avatar--size-${size}`, floatUp && 'avatar--float-up'])
|
||||
|
||||
let img
|
||||
|
||||
onMount(() => {
|
||||
if (img && img.naturalWidth) {
|
||||
const isPixelated = () => {
|
||||
if (img.naturalWidth < 96 && img.naturalWidth > 0) {
|
||||
img.style = 'image-rendering: pixelated;'
|
||||
}
|
||||
}
|
||||
|
||||
if (img.naturalWidth) {
|
||||
isPixelated()
|
||||
} else {
|
||||
img.onload = isPixelated
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if src}
|
||||
<img {src} bind:this={img} class={className} alt=""/>
|
||||
{:else}
|
||||
<svg
|
||||
class={className}
|
||||
xml:space="preserve"
|
||||
fill-rule="evenodd"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-miterlimit="1.5"
|
||||
clip-rule="evenodd"
|
||||
viewBox="0 0 104 104"
|
||||
>
|
||||
<path fill="none" d="M0 0h103.4v103.4H0z"/>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="#9a9a9a"
|
||||
stroke-width="5"
|
||||
d="M51.7 92.5V51.7L16.4 31.3l35.3 20.4L87 31.3 51.7 11 16.4 31.3v40.8l35.3 20.4L87 72V31.3L51.7 11"
|
||||
/>
|
||||
</svg>
|
||||
{/if}
|
||||
|
||||
<style lang="postcss">
|
||||
.avatar {
|
||||
border-radius: var(--rounded);
|
||||
box-shadow: var(--shadow-inset-lg), var(--shadow-raised-lg);
|
||||
height: var(--size);
|
||||
width: var(--size);
|
||||
background-color: var(--color-button-bg);
|
||||
|
||||
&--size {
|
||||
&-xs {
|
||||
--size: 2.25rem;
|
||||
box-shadow: var(--shadow-inset), var(--shadow-raised);
|
||||
border-radius: var(--rounded-sm);
|
||||
}
|
||||
|
||||
&-sm {
|
||||
--size: 3rem;
|
||||
box-shadow: var(--shadow-inset), var(--shadow-raised);
|
||||
border-radius: var(--rounded-sm);
|
||||
}
|
||||
|
||||
&-md {
|
||||
--size: 6rem;
|
||||
}
|
||||
|
||||
&-lg {
|
||||
--size: 9rem;
|
||||
background-color: var(--color-brand-contrast);
|
||||
}
|
||||
}
|
||||
|
||||
&--float-up {
|
||||
margin-top: calc(var(--size) * (-2 / 3));
|
||||
}
|
||||
|
||||
&--circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
51
src/lib/components/Badge.svelte
Normal file
51
src/lib/components/Badge.svelte
Normal file
@@ -0,0 +1,51 @@
|
||||
<script lang="ts">
|
||||
export let label = ''
|
||||
// Supports `green`, `yellow`, `red`, & `gray`
|
||||
export let color = 'gray'
|
||||
</script>
|
||||
|
||||
<div class="badge badge--color-{color}">
|
||||
{label}
|
||||
</div>
|
||||
|
||||
<style lang="postcss">
|
||||
.badge {
|
||||
font-weight: var(--font-weight-bold);
|
||||
display: inline;
|
||||
position: relative;
|
||||
padding-left: 0.9rem;
|
||||
line-height: 1rem;
|
||||
|
||||
&--color-green {
|
||||
color: var(--color-badge-green-text);
|
||||
--color-dot: var(--color-badge-green-dot);
|
||||
}
|
||||
|
||||
&--color-yellow {
|
||||
color: var(--color-badge-yellow-text);
|
||||
--color-dot: var(--color-badge-yellow-dot);
|
||||
}
|
||||
|
||||
&--color-red {
|
||||
color: var(--color-badge-red-text);
|
||||
--color-dot: var(--color-badge-red-dot);
|
||||
}
|
||||
|
||||
&--color-gray {
|
||||
color: var(--color-badge-gray-text);
|
||||
--color-dot: var(--color-badge-gray-dot);
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
border-radius: 50%;
|
||||
background-color: var(--color-dot);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 25%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,323 +1,145 @@
|
||||
<script lang="ts">
|
||||
export let as: 'button' | 'a' | 'summary' | 'input' = 'button'
|
||||
import { classCombine } from '$lib/utils/classCombine'
|
||||
|
||||
// The element to be styled as a button
|
||||
export let as: 'button' | 'a' | 'summary' | 'input' = 'button'
|
||||
export let href: string
|
||||
if (href) as = 'a'
|
||||
|
||||
// Use `value` if the button is an `<input`>
|
||||
export let value: string;
|
||||
export let value: string
|
||||
|
||||
export let size: 'sm' | 'md' | 'lg' = 'md'
|
||||
export let color: 'raised' | 'primary' | 'danger';
|
||||
export let color: 'raised' | 'primary' | 'primary-light' | 'danger'| 'danger-light' | 'transparent'
|
||||
|
||||
let className = `btn btn--${size}`;
|
||||
className += color && (` btn--${color}`)
|
||||
// Show notification badge in the upper right of button
|
||||
export let badge = false
|
||||
|
||||
export let disabled = false
|
||||
|
||||
let className: string
|
||||
$: className = classCombine(['button', `button--size-${size}`, `button--color-${color}`, badge && 'has-badge'])
|
||||
</script>
|
||||
|
||||
{#if as === 'button'}
|
||||
<button class={className}>
|
||||
<slot />
|
||||
<button class={className} {disabled}>
|
||||
<slot/>
|
||||
</button>
|
||||
{:else if as === 'a'}
|
||||
<a class={className} {href}>
|
||||
<slot />
|
||||
<a class={className} {href} {disabled}>
|
||||
<slot/>
|
||||
</a>
|
||||
{:else if as === 'summary'}
|
||||
<summary class={className}>
|
||||
<slot />
|
||||
<summary class={className} {disabled}>
|
||||
<slot/>
|
||||
</summary>
|
||||
{:else if as === 'input'}
|
||||
<input class={className} {value} />
|
||||
<input class={className} {value} {disabled}/>
|
||||
{/if}
|
||||
|
||||
<style lang="postcss">
|
||||
/* Base button styles */
|
||||
.btn {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 5px var(--spacer-3);
|
||||
font-size: var(--body-font-size);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
line-height: 20px; /* Specifically not inherit our `<body>` default */
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
border: var(--border-width) var(--border-style);
|
||||
border-radius: var(--radii-2);
|
||||
appearance: none; /* Corrects inability to style clickable `input` types in iOS. */
|
||||
.button {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: 0.25rem 1rem;
|
||||
grid-gap: 0.4rem;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
box-shadow: var(--shadow-inset-sm);
|
||||
|
||||
&:disabled,
|
||||
&.disabled,
|
||||
&[aria-disabled='true'] {
|
||||
cursor: default;
|
||||
}
|
||||
background-color: var(--color-button-bg);
|
||||
border-radius: var(--rounded);
|
||||
transition: opacity 0.5s ease-in-out, filter 0.5s ease-in-out;
|
||||
|
||||
i {
|
||||
font-style: normal;
|
||||
font-weight: var(--font-weight-semibold);
|
||||
opacity: 0.75;
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--color-button-bg-hover);
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-right: var(--spacer-1);
|
||||
color: var(--color-fg-muted);
|
||||
&--color {
|
||||
&-raised {
|
||||
background-color: var(--color-raised-bg);
|
||||
|
||||
&:only-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--color-raised-bg-hover);
|
||||
}
|
||||
}
|
||||
|
||||
&-primary {
|
||||
background-color: var(--color-brand);
|
||||
color: var(--color-brand-contrast);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-brand-dark);
|
||||
}
|
||||
}
|
||||
|
||||
&-primary-light {
|
||||
background-color: var(--color-brand-light);
|
||||
transition: filter 0s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-brand-light);
|
||||
filter: brightness(0.9);
|
||||
}
|
||||
}
|
||||
|
||||
&-transparent {
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&-danger {
|
||||
background-color: var(--color-badge-red-dot);
|
||||
color: var(--color-brand-contrast);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-badge-red-text);
|
||||
}
|
||||
}
|
||||
|
||||
&-danger-light {
|
||||
color: var(--color-danger-text);
|
||||
transition: filter 0s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
filter: brightness(0.9);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 50%;
|
||||
cursor: not-allowed;
|
||||
filter: grayscale(50%);
|
||||
|
||||
/* Not ideal, but preventing events being fired needs to be implemented */
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&--pad-even {
|
||||
padding: 0.5rem;
|
||||
font-size: 1rem;
|
||||
line-height: 0;
|
||||
min-width: 2rem;
|
||||
min-height: 2rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&.is-iconified {
|
||||
padding: 0.25rem 0.75rem;
|
||||
}
|
||||
|
||||
&.has-badge::after {
|
||||
content: '';
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
border-radius: var(--rounded-max);
|
||||
background-color: var(--color-brand);
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
right: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.Counter {
|
||||
margin-left: 2px;
|
||||
color: inherit;
|
||||
text-shadow: none;
|
||||
vertical-align: top;
|
||||
background-color: var(--color-btn-counter-bg);
|
||||
}
|
||||
|
||||
.dropdown-caret {
|
||||
margin-left: var(--spacer-1);
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Default button */
|
||||
.btn {
|
||||
color: var(--color-btn-text);
|
||||
background-color: var(--color-btn-bg);
|
||||
border-color: var(--color-btn-border);
|
||||
box-shadow: var(--color-btn-shadow), var(--color-btn-inset-shadow);
|
||||
transition: 0.2s cubic-bezier(0.3, 0, 0.5, 1);
|
||||
transition-property: color, background-color, border-color;
|
||||
|
||||
&:hover,
|
||||
&.hover,
|
||||
[open] > & {
|
||||
background-color: var(--color-btn-hover-bg);
|
||||
border-color: var(--color-btn-hover-border);
|
||||
transition-duration: 0.1s;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var(--color-btn-active-bg);
|
||||
border-color: var(--color-btn-active-border);
|
||||
transition: none;
|
||||
}
|
||||
|
||||
&.selected,
|
||||
&[aria-selected='true'] {
|
||||
background-color: var(--color-btn-selected-bg);
|
||||
box-shadow: var(--color-primer-shadow-inset);
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&.disabled,
|
||||
&[aria-disabled='true'] {
|
||||
color: var(--color-primer-fg-disabled);
|
||||
background-color: var(--color-btn-bg);
|
||||
border-color: var(--color-btn-border);
|
||||
|
||||
:global(.icon) {
|
||||
color: var(--color-primer-fg-disabled);
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep :focus after :disabled. Allows to see the focus ring even on disabled buttons */
|
||||
&:focus,
|
||||
&.focus {
|
||||
border-color: var(--color-btn-focus-border);
|
||||
outline: none;
|
||||
box-shadow: var(--color-btn-focus-shadow);
|
||||
}
|
||||
}
|
||||
|
||||
/* Primary button */
|
||||
.btn--primary {
|
||||
color: var(--color-btn-primary-text);
|
||||
background-color: var(--color-btn-primary-bg);
|
||||
border-color: var(--color-btn-primary-border);
|
||||
box-shadow: var(--color-btn-primary-shadow), var(--color-btn-primary-inset-shadow);
|
||||
|
||||
&:hover,
|
||||
&.hover,
|
||||
[open] > & {
|
||||
background-color: var(--color-btn-primary-hover-bg);
|
||||
border-color: var(--color-btn-primary-hover-border);
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.selected,
|
||||
&[aria-selected='true'] {
|
||||
background-color: var(--color-btn-primary-selected-bg);
|
||||
box-shadow: var(--color-btn-primary-selected-shadow);
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&.disabled,
|
||||
&[aria-disabled='true'] {
|
||||
color: var(--color-btn-primary-disabled-text);
|
||||
background-color: var(--color-btn-primary-disabled-bg);
|
||||
border-color: var(--color-btn-primary-disabled-border);
|
||||
|
||||
:global(.icon) {
|
||||
color: var(--color-btn-primary-disabled-text);
|
||||
}
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&.focus {
|
||||
background-color: var(--color-btn-primary-focus-bg);
|
||||
border-color: var(--color-btn-primary-focus-border);
|
||||
box-shadow: var(--color-btn-primary-focus-shadow);
|
||||
}
|
||||
|
||||
.Counter {
|
||||
color: inherit;
|
||||
background-color: var(--color-btn-primary-counter-bg);
|
||||
}
|
||||
|
||||
:global(.icon) {
|
||||
color: var(--color-btn-primary-icon);
|
||||
}
|
||||
}
|
||||
|
||||
/* Outline button */
|
||||
.btn--outline {
|
||||
color: var(--color-btn-outline-text);
|
||||
|
||||
&:hover,
|
||||
[open] > & {
|
||||
color: var(--color-btn-outline-hover-text);
|
||||
background-color: var(--color-btn-outline-hover-bg);
|
||||
border-color: var(--color-btn-outline-hover-border);
|
||||
box-shadow: var(--color-btn-outline-hover-shadow), var(--color-btn-outline-hover-inset-shadow);
|
||||
|
||||
.Counter {
|
||||
background-color: var(--color-btn-outline-hover-counter-bg);
|
||||
}
|
||||
|
||||
:global(.icon) {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.selected,
|
||||
&[aria-selected='true'] {
|
||||
color: var(--color-btn-outline-selected-text);
|
||||
background-color: var(--color-btn-outline-selected-bg);
|
||||
border-color: var(--color-btn-outline-selected-border);
|
||||
box-shadow: var(--color-btn-outline-selected-shadow);
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&.disabled,
|
||||
&[aria-disabled='true'] {
|
||||
color: var(--color-btn-outline-disabled-text);
|
||||
background-color: var(--color-btn-outline-disabled-bg);
|
||||
border-color: var(--color-btn-border);
|
||||
box-shadow: none;
|
||||
|
||||
.Counter {
|
||||
background-color: var(--color-btn-outline-disabled-counter-bg);
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: var(--color-btn-outline-focus-border);
|
||||
box-shadow: var(--color-btn-outline-focus-shadow);
|
||||
}
|
||||
|
||||
.Counter {
|
||||
color: inherit;
|
||||
background-color: var(--color-btn-outline-counter-bg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Danger button */
|
||||
.btn--danger {
|
||||
color: var(--color-btn-danger-text);
|
||||
|
||||
:global(.icon) {
|
||||
color: var(--color-btn-danger-icon);
|
||||
}
|
||||
|
||||
&:hover,
|
||||
[open] > & {
|
||||
color: var(--color-btn-danger-hover-text);
|
||||
background-color: var(--color-btn-danger-hover-bg);
|
||||
border-color: var(--color-btn-danger-hover-border);
|
||||
box-shadow: var(--color-btn-danger-hover-shadow), var(--color-btn-danger-hover-inset-shadow);
|
||||
|
||||
.Counter {
|
||||
background-color: var(--color-btn-danger-hover-counter-bg);
|
||||
}
|
||||
|
||||
:global(.icon) {
|
||||
color: var(--color-btn-danger-hover-icon);
|
||||
}
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.selected,
|
||||
&[aria-selected='true'] {
|
||||
color: var(--color-btn-danger-selected-text);
|
||||
background-color: var(--color-btn-danger-selected-bg);
|
||||
border-color: var(--color-btn-danger-selected-border);
|
||||
box-shadow: var(--color-btn-danger-selected-shadow);
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&.disabled,
|
||||
&[aria-disabled='true'] {
|
||||
color: var(--color-btn-danger-disabled-text);
|
||||
background-color: var(--color-btn-danger-disabled-bg);
|
||||
border-color: var(--color-btn-border);
|
||||
box-shadow: none;
|
||||
|
||||
.Counter {
|
||||
background-color: var(--color-btn-danger-disabled-counter-bg);
|
||||
}
|
||||
|
||||
:global(.icon) {
|
||||
color: var(--color-btn-danger-disabled-text);
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: var(--color-btn-danger-focus-border);
|
||||
box-shadow: var(--color-btn-danger-focus-shadow);
|
||||
}
|
||||
|
||||
.Counter {
|
||||
color: inherit;
|
||||
background-color: var(--color-btn-danger-counter-bg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Sizes */
|
||||
.btn--sm {
|
||||
padding: 3px 12px;
|
||||
font-size: var(--font-0);
|
||||
}
|
||||
|
||||
.btn--lg {
|
||||
font-size: var(--font-size-large);
|
||||
padding: 8px 16px;
|
||||
border-radius: var(--radii-3);
|
||||
}
|
||||
|
||||
/* Full-width button */
|
||||
/* These buttons expand to the full width of their parent container */
|
||||
.btn-block {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
<style lang="postcss">
|
||||
a {
|
||||
color: blue;
|
||||
color: var(--color-link);
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
81
src/lib/components/NavRow.svelte
Normal file
81
src/lib/components/NavRow.svelte
Normal file
@@ -0,0 +1,81 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
|
||||
interface Link {
|
||||
href: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export let links: Link[];
|
||||
export let query = '';
|
||||
|
||||
export let resetScroll = false
|
||||
|
||||
/** Path level in URL, zero-indexed */
|
||||
export let level = 0;
|
||||
|
||||
let path: string[];
|
||||
$: path = [
|
||||
...$page.url.pathname
|
||||
.substring(1)
|
||||
.split('/')
|
||||
.map((route) => '/' + route),
|
||||
'/',
|
||||
];
|
||||
|
||||
$: basePath = path.slice(0, level).join('');
|
||||
</script>
|
||||
|
||||
<nav class="navigation">
|
||||
{#each links as link}
|
||||
<a
|
||||
href={query
|
||||
? link.href
|
||||
? `?${query}=${link.href}`
|
||||
: '?'
|
||||
: level === 0
|
||||
? link.href
|
||||
: basePath + link.href}
|
||||
|
||||
on:click={() => { if (resetScroll) document.body.scrollTo(0,0)}}
|
||||
|
||||
class="navigation__link"
|
||||
class:is-active={query
|
||||
? ($page.url.searchParams.get(query) || '') === link.href
|
||||
: path[level] === link.href || path[level] === link.href.slice(0, -1)}
|
||||
sveltekit:noscroll={!resetScroll}
|
||||
>{link.label}</a
|
||||
>
|
||||
{/each}
|
||||
</nav>
|
||||
|
||||
<style lang="postcss">
|
||||
.navigation {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
grid-gap: 1rem;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&__link {
|
||||
font-weight: var(--font-weight-bold);
|
||||
color: var(--color-text-light);
|
||||
|
||||
&.is-active {
|
||||
color: var(--color-text);
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: -0.1rem;
|
||||
width: 100%;
|
||||
border-radius: var(--rounded-max);
|
||||
height: 0.2rem;
|
||||
background-color: var(--color-brand);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
// TODO: Modify to match new button props
|
||||
// TODO: Fix mobile support, currently just cuts off buttons
|
||||
|
||||
import IconArrowRight from 'virtual:icons/heroicons-outline/arrow-right'
|
||||
import IconArrowLeft from 'virtual:icons/heroicons-outline/arrow-left'
|
||||
|
||||
3
src/lib/styles.postcss
Normal file
3
src/lib/styles.postcss
Normal file
@@ -0,0 +1,3 @@
|
||||
@import "./styles/normalize.postcss";
|
||||
@import "./styles/themes.postcss";
|
||||
@import "./styles/variables.postcss";
|
||||
55
src/lib/styles/normalize.postcss
Normal file
55
src/lib/styles/normalize.postcss
Normal file
@@ -0,0 +1,55 @@
|
||||
@import 'sanitize.css';
|
||||
@import 'sanitize.css/forms.css';
|
||||
@import 'sanitize.css/typography.css';
|
||||
|
||||
/* Overrides */
|
||||
|
||||
button {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: inherit;
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
*:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
button:focus-visible,
|
||||
a:focus-visible,
|
||||
[tabindex='0']:focus-visible {
|
||||
outline: 0.2rem solid var(--color-brand);
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#svelte {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
html {
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p {
|
||||
line-height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0 0 0 1.5rem;
|
||||
}
|
||||
@@ -1,2 +1,4 @@
|
||||
@import "themes/base.postcss";
|
||||
@import "themes/light.postcss";
|
||||
@import "themes/old.postcss";
|
||||
@import "themes/dark.postcss";
|
||||
@import "themes/oled.postcss";
|
||||
|
||||
17
src/lib/styles/themes/base.postcss
Normal file
17
src/lib/styles/themes/base.postcss
Normal file
@@ -0,0 +1,17 @@
|
||||
:root {
|
||||
--rounded: 1rem;
|
||||
--rounded-top: 1rem 1rem 0 0;
|
||||
--rounded-bottom: 0 0 1rem 1rem;
|
||||
--rounded-sm: 0.6rem;
|
||||
--rounded-max: 999999999px;
|
||||
|
||||
--font-standard: Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Roboto,
|
||||
Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
|
||||
--font-size-nm: 1rem; /* 16px */
|
||||
--font-size-xl: 1.5rem; /* 24px */
|
||||
|
||||
--font-weight-regular: 400;
|
||||
--font-weight-medium: 600;
|
||||
--font-weight-bold: 700;
|
||||
}
|
||||
61
src/lib/styles/themes/dark.postcss
Normal file
61
src/lib/styles/themes/dark.postcss
Normal file
@@ -0,0 +1,61 @@
|
||||
.theme-dark {
|
||||
/* Brand colors */
|
||||
--color-brand: hsl(155, 58%, 40%);
|
||||
--color-brand-light: hsl(155, 54%, 30%);
|
||||
--color-brand-dark: hsl(155, 58%, 25%);
|
||||
--color-brand-contrast: hsl(0, 0%, 100%);
|
||||
|
||||
/* Shadows */
|
||||
--shadow-inset-lg: inset 0px -2px 2px hsla(221, 39%, 11%, 0.1);
|
||||
--shadow-inset: inset 0px -2px 2px hsla(221, 39%, 11%, 0.05);
|
||||
--shadow-inset-sm: inset 0px -1px 1px hsla(221, 39%, 11%, 0.25);
|
||||
|
||||
--shadow-raised-lg: 0px 2px 4px hsla(221, 39%, 11%, 0.2);
|
||||
--shadow-raised: 0px -2px 4px hsla(221, 39%, 11%, 0.1);
|
||||
--shadow-floating: hsla(0, 0%, 0%, 0) 0px 0px 0px 0px, hsla(0, 0%, 0%, 0) 0px 0px 0px 0px,
|
||||
hsla(0, 0%, 0%, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;
|
||||
--shadow-mobile-bar: hsla(0, 0%, 0%, 0.3) 0 0 20px 2px;
|
||||
|
||||
/* Text colors */
|
||||
--color-text: hsl(221, 39%, 90%);
|
||||
--color-text-light: hsl(215, 14%, 74%);
|
||||
--color-text-lightest: hsl(220, 9%, 70%);
|
||||
--color-heading: hsl(222, 16%, 80%);
|
||||
--color-link: hsl(215, 100%, 75%);
|
||||
|
||||
/* Container colors */
|
||||
--color-bg: hsl(220, 13%, 15%);
|
||||
--color-raised-bg: hsl(220, 13%, 25%);
|
||||
--color-raised-bg-hover: hsl(220, 13%, 20%);
|
||||
--color-divider: hsl(220, 13%, 50%);
|
||||
--color-button-bg: hsl(220, 13%, 35%);
|
||||
--color-button-bg-hover: hsl(220, 13%, 32%);
|
||||
|
||||
/* Label colors */
|
||||
--color-badge-gray-text: hsl(0, 2%, 69%);
|
||||
--color-badge-gray-dot: hsl(0, 6%, 77%);
|
||||
--color-badge-red-text: hsl(343, 63%, 67%);
|
||||
--color-badge-red-dot: hsl(342, 70%, 53%);
|
||||
--color-badge-green-text: hsl(156, 53%, 50%);
|
||||
--color-badge-green-dot: hsl(140, 64%, 40%);
|
||||
--color-badge-yellow-text: hsl(40, 57%, 60%);
|
||||
--color-badge-yellow-dot: hsl(40, 92%, 62%);
|
||||
|
||||
/* Markdown colors */
|
||||
--color-table-border: hsl(214, 12%, 35%);
|
||||
--color-table-alternate-row: hsl(216, 12%, 17%);
|
||||
--color-code-bg: hsl(217, 12%, 29%);
|
||||
|
||||
/* Ad colors */
|
||||
--color-ad-bg: hsl(200, 70%, 25%);
|
||||
--color-ad-link: hsl(200, 70%, 50%);
|
||||
|
||||
/* Popup colors */
|
||||
--color-popup-danger-bg: hsl(355, 70%, 20%);
|
||||
--color-popup-danger-text: hsl(342, 70%, 75%);
|
||||
|
||||
--color-input-light: hsl(220, 13%, 20%);
|
||||
|
||||
/* Scrollbar color */
|
||||
--color-scrollbar-thumb: hsl(220, 13%, 40%);
|
||||
}
|
||||
@@ -1,3 +1,60 @@
|
||||
.theme-light {
|
||||
/* Brand colors */
|
||||
--color-brand: hsl(155, 58%, 44%);
|
||||
--color-brand-light: hsl(135, 50%, 78%);
|
||||
--color-brand-dark: hsl(155, 58%, 38%);
|
||||
--color-brand-contrast: hsl(0, 0%, 100%);
|
||||
|
||||
}
|
||||
/* Shadows */
|
||||
--shadow-inset-lg: inset 0px -2px 2px hsla(221, 39%, 11%, 0.1);
|
||||
--shadow-inset: inset 0px -2px 2px hsla(221, 39%, 11%, 0.05);
|
||||
--shadow-inset-sm: inset 0px -1px 2px hsla(221, 39%, 11%, 0.15);
|
||||
|
||||
--shadow-raised-lg: 0px 2px 4px hsla(221, 39%, 11%, 0.2);
|
||||
--shadow-raised: 0px 2px 4px hsla(221, 39%, 11%, 0.1);
|
||||
--shadow-floating: hsla(0, 0%, 0%, 0) 0px 0px 0px 0px, hsla(0, 0%, 0%, 0) 0px 0px 0px 0px,
|
||||
hsla(0, 0%, 0%, 0.1) 0px 4px 6px -1px, hsla(0, 0%, 0%, 0.1) 0px 2px 4px -1px;
|
||||
--shadow-mobile-bar: hsla(0, 0%, 0%, 0.3) 0 0 20px 2px;
|
||||
|
||||
/* Text colors */
|
||||
--color-text: hsl(221, 39%, 11%);
|
||||
--color-text-light: hsl(215, 14%, 34%);
|
||||
--color-text-lightest: hsl(220, 9%, 46%);
|
||||
--color-heading: hsl(222, 16%, 20%);
|
||||
--color-link: hsl(221, 55%, 50%);
|
||||
|
||||
/* Container colors */
|
||||
--color-bg: hsl(220, 13%, 91%);
|
||||
--color-raised-bg: hsl(0, 0%, 100%);
|
||||
--color-raised-bg-hover: hsl(220, 13%, 93%);
|
||||
--color-divider: hsl(220, 13%, 91%);
|
||||
--color-button-bg: hsl(220, 13%, 91%);
|
||||
--color-button-bg-hover: hsl(0, 0%, 85%);
|
||||
--color-input-text-light: hsl(0, 0%, 94%);
|
||||
|
||||
/* Label colors */
|
||||
--color-badge-gray-text: hsl(0, 2%, 39%);
|
||||
--color-badge-gray-dot: hsl(0, 6%, 77%);
|
||||
--color-badge-red-text: hsl(343, 63%, 27%);
|
||||
--color-badge-red-dot: hsl(342, 70%, 53%);
|
||||
--color-badge-green-text: hsl(156, 53%, 20%);
|
||||
--color-badge-green-dot: hsl(140, 64%, 40%);
|
||||
--color-badge-yellow-text: hsl(40, 57%, 29%);
|
||||
--color-badge-yellow-dot: hsl(40, 92%, 62%);
|
||||
|
||||
/* Markdown colors */
|
||||
--color-table-border: hsl(210, 10%, 89%);
|
||||
--color-table-alternate-row: hsl(210, 29%, 97%);
|
||||
--color-code-bg: hsl(210, 29%, 96%);
|
||||
|
||||
/* Ad colors */
|
||||
--color-ad-bg: hsl(200, 70%, 82%);
|
||||
--color-ad-link: hsl(200, 80%, 40%);
|
||||
|
||||
/* Popup colors */
|
||||
--color-popup-danger-bg: hsl(355, 70%, 88%);
|
||||
--color-popup-danger-text: hsl(342, 70%, 35%);
|
||||
|
||||
/* Scrollbar color */
|
||||
--color-scrollbar-thumb: hsl(220, 13%, 70%);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
15
src/lib/styles/themes/oled.postcss
Normal file
15
src/lib/styles/themes/oled.postcss
Normal file
@@ -0,0 +1,15 @@
|
||||
.oled-theme {
|
||||
@extend .dark-theme;
|
||||
|
||||
/* Container colors */
|
||||
--color-bg: hsl(220, 13%, 0%);
|
||||
--color-raised-bg: hsl(220, 13%, 10%);
|
||||
--color-raised-bg-hover: hsl(220, 13%, 20%);
|
||||
--color-divider: hsl(220, 13%, 35%);
|
||||
--color-button-bg: hsl(220, 13%, 20%);
|
||||
--color-button-bg-hover: hsl(220, 13%, 15%);
|
||||
|
||||
/* Ad colors */
|
||||
--color-ad-bg: hsl(200, 70%, 15%);
|
||||
--color-ad-link: hsl(200, 70%, 45%);
|
||||
}
|
||||
@@ -4,10 +4,13 @@
|
||||
--border-style: solid;
|
||||
--border: var(--border-width) var(--border-style);
|
||||
|
||||
/* Radii */
|
||||
--radii-1: 8px;
|
||||
--radii-2: 10px;
|
||||
--radii-3: 12px;
|
||||
--radii-max: 100px;
|
||||
--radii: var(--radii-2);
|
||||
/* Rounded radii */
|
||||
--rounded-sm: 8px;
|
||||
--rounded: 10px;
|
||||
--rounded-lg: 12px;
|
||||
--rounded-max: 100px;
|
||||
--rounded-top: var(--rounded) var(--rounded) 0 0;
|
||||
--rounded-bottom: 0 0 var(--rounded) var(--rounded);
|
||||
--rounded-sm-top: var(--rounded-sm) var(--rounded-sm) 0 0;
|
||||
--rounded-sm-bottom: 0 0 var(--rounded-sm) var(--rounded-sm);
|
||||
}
|
||||
@@ -17,10 +17,9 @@
|
||||
--h5-size: 14px;
|
||||
--h6-size: 12px;
|
||||
|
||||
--font-size-large: 17px;
|
||||
--font-size-small: 12px;
|
||||
--font-size-normal: 14px;
|
||||
--body-line-height: --lh-default;
|
||||
--font-size-lg: 17px;
|
||||
--font-size-sm: 12px;
|
||||
--font-size: 14px;
|
||||
|
||||
/* Line heights */
|
||||
--lh-condensed-ultra: 1;
|
||||
@@ -34,6 +33,6 @@
|
||||
--font-weight-bold: 600;
|
||||
|
||||
/* Font stacks */
|
||||
--body-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
|
||||
--body-font: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
|
||||
--mono-font: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
|
||||
}
|
||||
3
src/lib/utils/classCombine.ts
Normal file
3
src/lib/utils/classCombine.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export function classCombine(names) {
|
||||
return names.filter(name => name && !name.includes('undefined')).join(' ')
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import "$lib/styles/variables.postcss"
|
||||
import "$lib/styles/themes.postcss"
|
||||
import "$lib/styles.postcss"
|
||||
import "./_internal/styles/prism-one-dark.css"
|
||||
import "./_internal/styles/gh-markdown.css"
|
||||
import Sidebar from "./_internal/components/Sidebar.svelte"
|
||||
@@ -21,8 +20,8 @@
|
||||
font-size: var(--body-font-size);
|
||||
font-family: var(--body-font);
|
||||
overflow-y: scroll;
|
||||
--accent-color: hsl(331, 60%, 45%);
|
||||
--accent-color-transparent: hsla(331, 60%, 45%, 0.15);
|
||||
--accent-color: hsl(331, 80%, 45%);
|
||||
--accent-color-transparent: hsla(331, 80%, 45%, 0.15);
|
||||
}
|
||||
|
||||
.app {
|
||||
@@ -36,13 +35,6 @@
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
:global(a) {
|
||||
color: var(--accent-color);
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
padding: var(--header-height) 0 0 var(--sidebar-width);
|
||||
overflow-x: hidden;
|
||||
@@ -57,5 +49,15 @@
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
:global(a) {
|
||||
color: var(--accent-color);
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
35
src/routes/_internal/components/Example.svelte
Normal file
35
src/routes/_internal/components/Example.svelte
Normal file
@@ -0,0 +1,35 @@
|
||||
<script lang="ts">
|
||||
import Prism from 'prismjs';
|
||||
import 'prism-svelte';
|
||||
|
||||
export let background: 'var(--color-raised-bg)' | 'transparent' = 'var(--color-raised-bg)'
|
||||
|
||||
export let code = ''
|
||||
const highlighted = Prism.highlight(code.trim(), Prism.languages.svelte, 'svelte');
|
||||
</script>
|
||||
|
||||
<div class="example theme-light">
|
||||
<div class="example__preview" style:background={background}>
|
||||
<slot />
|
||||
</div>
|
||||
<pre class="example__code language-">{@html highlighted}</pre>
|
||||
</div>
|
||||
|
||||
<style lang="postcss">
|
||||
.example {
|
||||
&__preview {
|
||||
padding: 16px;
|
||||
border-radius: var(--rounded-sm-top);
|
||||
border: solid 2px hsl(0, 0%, 20%);
|
||||
border-bottom: none;
|
||||
display: flex;
|
||||
grid-gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&__code {
|
||||
margin: 0;
|
||||
border-radius: var(--rounded-sm-bottom) !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
const components = ['button', 'pagination', 'link']
|
||||
const components = ['Button', 'Pagination', 'Link', 'NavRow', 'Badge', 'Avatar'].sort()
|
||||
</script>
|
||||
|
||||
<nav class="sidebar">
|
||||
@@ -43,7 +43,6 @@
|
||||
}
|
||||
|
||||
&__link {
|
||||
text-transform: capitalize;
|
||||
color: hsl(216, 10%, 90%);
|
||||
text-decoration: none;
|
||||
|
||||
|
||||
@@ -3,15 +3,18 @@
|
||||
import { page } from '$app/stores'
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
export let title
|
||||
export let component
|
||||
export let componentName = $page.url.pathname.includes('components') ? $page.url.pathname.replace('/components/', '') : undefined
|
||||
|
||||
export let title = ''
|
||||
if (!title && componentName) title = componentName
|
||||
|
||||
let pageUrl = `https://github.com/modrinth/omorphia/edit/main/src/routes/${$page.url.pathname.replace('/', '') || 'index'}.md`
|
||||
|
||||
let api
|
||||
|
||||
onMount(async () => {
|
||||
if (component) {
|
||||
api = (await import(`../../../lib/components/${component}.svelte?raw&api`)).default
|
||||
if (componentName) {
|
||||
api = (await import(`../../../lib/components/${componentName}.svelte?raw&api`)).default
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -27,7 +30,7 @@
|
||||
Edit this page on GitHub</a>
|
||||
<slot/>
|
||||
|
||||
{#if component && api}
|
||||
{#if componentName && api}
|
||||
<div class="extra-info">
|
||||
{#if api.data.length > 0}
|
||||
<h2>Properties</h2>
|
||||
@@ -38,7 +41,6 @@
|
||||
<th>Type</th>
|
||||
<th>Default</th>
|
||||
<th>Description</th>
|
||||
<th>Read only</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -46,9 +48,8 @@
|
||||
<tr>
|
||||
<td>{prop.name}</td>
|
||||
<td>{prop.type.type}</td>
|
||||
<td>{prop.defaultValue}</td>
|
||||
<td>{prop.description?.replace('null', '') || ''}</td>
|
||||
<td>{prop.readonly}</td>
|
||||
<td>{prop.defaultValue ?? ''}</td>
|
||||
<td>{prop.readonly ? '[Read only] ' : ''}{prop.description?.replace('null', '') || ''}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
@@ -94,6 +95,9 @@
|
||||
</tbody>
|
||||
</table>
|
||||
{/if}
|
||||
|
||||
<h2>Import</h2>
|
||||
<pre class="language-js"><code class="language-js"><span class="token keyword">import</span> <span class="token punctuation">{</span> {componentName} <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">"omorphia"</span></code></pre>
|
||||
</div>
|
||||
{/if}
|
||||
</article>
|
||||
@@ -101,7 +105,7 @@
|
||||
<style lang="postcss">
|
||||
article {
|
||||
max-width: 800px;
|
||||
padding: 5rem max(8vw, 1rem);
|
||||
padding: 5rem 1rem;
|
||||
}
|
||||
|
||||
.edit-link {
|
||||
@@ -109,28 +113,30 @@
|
||||
align-items: center;
|
||||
grid-gap: 8px;
|
||||
margin-bottom: 54px;
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.extra-info {
|
||||
margin-top: 48px;
|
||||
margin-top: 64px;
|
||||
}
|
||||
|
||||
.api-table {
|
||||
border-collapse: collapse;
|
||||
margin-top: -6px;
|
||||
}
|
||||
|
||||
tr {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
.api-table tr {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
tbody {
|
||||
border: 2px solid grey;
|
||||
}
|
||||
.api-table tbody {
|
||||
border: 2px solid grey;
|
||||
}
|
||||
|
||||
th {
|
||||
text-transform: uppercase;
|
||||
font-size: 12.5px;
|
||||
border: none;
|
||||
}
|
||||
.api-table th {
|
||||
text-transform: uppercase;
|
||||
font-size: 12.5px;
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
@@ -198,6 +198,7 @@ blockquote > :last-child {
|
||||
table {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table tr {
|
||||
border-top: 1px solid #cccccc;
|
||||
background-color: white;
|
||||
@@ -341,24 +342,13 @@ pre code {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.highlight pre {
|
||||
background-color: #f8f8f8;
|
||||
border: 1px solid #cccccc;
|
||||
font-size: 13px;
|
||||
line-height: 19px;
|
||||
overflow: auto;
|
||||
padding: 6px 10px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #f8f8f8;
|
||||
border: 1px solid #cccccc;
|
||||
font-size: 13px;
|
||||
line-height: 19px;
|
||||
overflow: auto;
|
||||
padding: 6px 10px;
|
||||
border-radius: 3px;
|
||||
border-radius: var(--rounded-sm) !important;
|
||||
}
|
||||
|
||||
pre code, pre tt {
|
||||
@@ -367,7 +357,6 @@ pre code, pre tt {
|
||||
}
|
||||
|
||||
/* Custom styles */
|
||||
|
||||
h1 {
|
||||
font-weight: 600;
|
||||
}
|
||||
@@ -381,4 +370,4 @@ blockquote {
|
||||
padding: 15px 15px;
|
||||
color: unset;
|
||||
background-color: var(--accent-color-transparent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,10 +68,10 @@ pre[class*="language-"] *::selection {
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
padding: 16px;
|
||||
margin: 0.5em 0;
|
||||
overflow: auto;
|
||||
border-radius: 0.3em;
|
||||
border-radius: var(--rounded);
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
|
||||
14
src/routes/components/Avatar.md
Normal file
14
src/routes/components/Avatar.md
Normal file
@@ -0,0 +1,14 @@
|
||||
<script lang="ts">
|
||||
import Avatar from "$lib/components/Avatar.svelte";
|
||||
import Example from "../_internal/components/Example.svelte"
|
||||
</script>
|
||||
|
||||
<Example code={`<Avatar src="https://avatars3.githubusercontent.com/u/44736536?v=4" size="lg" circle />
|
||||
<Avatar src="https://cdn.modrinth.com/data/AANobbMI/icon.png" size="md" />
|
||||
<Avatar size="sm" />
|
||||
<Avatar src="https://avatars1.githubusercontent.com/u/6166773?v=4" size="xs" circle />`}>
|
||||
<Avatar src="https://avatars3.githubusercontent.com/u/44736536?v=4" size="lg" circle />
|
||||
<Avatar src="https://cdn.modrinth.com/data/AANobbMI/icon.png" size="md" />
|
||||
<Avatar size="sm" />
|
||||
<Avatar src="https://avatars1.githubusercontent.com/u/6166773?v=4" size="xs" circle />
|
||||
</Example>
|
||||
14
src/routes/components/Badge.md
Normal file
14
src/routes/components/Badge.md
Normal file
@@ -0,0 +1,14 @@
|
||||
<script lang="ts">
|
||||
import Badge from "$lib/components/Badge.svelte";
|
||||
import Example from "../_internal/components/Example.svelte"
|
||||
</script>
|
||||
|
||||
<Example code={`<Badge color="red" label="Tomato" />
|
||||
<Badge color="yellow" label="Squash" />
|
||||
<Badge color="green" label="Lettuce" />
|
||||
<Badge label="Onion" />`}>
|
||||
<Badge color="red" label="Tomato" />
|
||||
<Badge color="yellow" label="Squash" />
|
||||
<Badge color="green" label="Lettuce" />
|
||||
<Badge label="Onion" />
|
||||
</Example>
|
||||
14
src/routes/components/Button.md
Normal file
14
src/routes/components/Button.md
Normal file
@@ -0,0 +1,14 @@
|
||||
<script lang="ts">
|
||||
import Button from "$lib/components/Button.svelte";
|
||||
import Example from "../_internal/components/Example.svelte"
|
||||
</script>
|
||||
|
||||
<Example code={`<Button>Eat cake</Button>
|
||||
<Button size="sm" color="primary">Small piece</Button>
|
||||
<Button size="lg" color="danger">Big part</Button>
|
||||
<Button disabled>Nice try</Button>`}>
|
||||
<Button>Eat cake</Button>
|
||||
<Button size="sm" color="primary">Small piece</Button>
|
||||
<Button size="lg" color="danger">Big part</Button>
|
||||
<Button disabled>Nice try</Button>
|
||||
</Example>
|
||||
8
src/routes/components/Link.md
Normal file
8
src/routes/components/Link.md
Normal file
@@ -0,0 +1,8 @@
|
||||
<script lang="ts">
|
||||
import Link from "$lib/components/Link.svelte";
|
||||
import Example from "../_internal/components/Example.svelte"
|
||||
</script>
|
||||
|
||||
<Example code={`<Link href="#clicked">Click for fun</Link>`}>
|
||||
<Link href="#clicked">Click for fun</Link>
|
||||
</Example>
|
||||
46
src/routes/components/NavRow.md
Normal file
46
src/routes/components/NavRow.md
Normal file
@@ -0,0 +1,46 @@
|
||||
<script lang="ts">
|
||||
import NavRow from "$lib/components/NavRow.svelte";
|
||||
import Example from "../_internal/components/Example.svelte"
|
||||
</script>
|
||||
|
||||
`NavRow` works well for most horizontal navigation with less than 10 items. It can be used with paths & query params, and supports specific path level (depths).
|
||||
|
||||
<Example code={`
|
||||
<NavRow
|
||||
level={1}
|
||||
links={[
|
||||
{
|
||||
href: '/Button',
|
||||
label: 'Button'
|
||||
},
|
||||
{
|
||||
href: '/Link',
|
||||
label: 'Link'
|
||||
},
|
||||
{
|
||||
href: '/NavRow',
|
||||
label: 'NavRow'
|
||||
}
|
||||
]}>
|
||||
Click for fun
|
||||
</NavRow>
|
||||
`}>
|
||||
<NavRow
|
||||
level={1}
|
||||
links={[
|
||||
{
|
||||
href: '/Button',
|
||||
label: 'Button'
|
||||
},
|
||||
{
|
||||
href: '/Link',
|
||||
label: 'Link'
|
||||
},
|
||||
{
|
||||
href: '/NavRow',
|
||||
label: 'NavRow'
|
||||
}
|
||||
]}>
|
||||
Click for fun
|
||||
</NavRow>
|
||||
</Example>
|
||||
@@ -1,12 +1,10 @@
|
||||
---
|
||||
title: Pagination
|
||||
component: Pagination
|
||||
---
|
||||
|
||||
<script lang="ts">
|
||||
import Pagination from "$lib/components/Pagination.svelte"
|
||||
import Example from "../_internal/components/Example.svelte"
|
||||
</script>
|
||||
|
||||
Use pagination to show a set of page numbers and navigation directions to move through paginated data.
|
||||
|
||||
<Pagination page={20} count={50} />
|
||||
<Example code={`<Pagination page={20} count={50} />`} background="transparent">
|
||||
<Pagination page={20} count={50} />
|
||||
</Example>
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
title: Button
|
||||
component: Button
|
||||
---
|
||||
|
||||
<script lang="ts">
|
||||
import Button from "$lib/components/Button.svelte";
|
||||
</script>
|
||||
|
||||
<Button>Eat cake</Button>
|
||||
|
||||
<Button size="sm" color="primary">Small piece</Button>
|
||||
|
||||
<Button size="lg" color="danger">Big part</Button>
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: Link
|
||||
component: Link
|
||||
---
|
||||
|
||||
<script lang="ts">
|
||||
import Link from "$lib/components/Link.svelte";
|
||||
</script>
|
||||
|
||||
<Link href="#clicked">Click for fun</Link>
|
||||
Reference in New Issue
Block a user