You've already forked AstralRinth
forked from didirus/AstralRinth
Start omorphia 2 (#8)
This commit is contained in:
11
docs/app.d.ts
vendored
11
docs/app.d.ts
vendored
@@ -1,11 +0,0 @@
|
||||
/// <reference types="@sveltejs/kit" />
|
||||
/// <reference types="unplugin-icons/types/svelte" />
|
||||
|
||||
// See https://kit.svelte.dev/docs/types#the-app-namespace
|
||||
// for information about these interfaces
|
||||
declare namespace App {
|
||||
// interface Locals {}
|
||||
// interface Platform {}
|
||||
// interface Session {}
|
||||
// interface Stuff {}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-color-mode="light">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href="%sveltekit.assets%/omorphia.png" />
|
||||
|
||||
<link
|
||||
rel="preload"
|
||||
href="/assets/fonts/InterRegular.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin />
|
||||
<link
|
||||
rel="preload"
|
||||
href="/assets/fonts/InterBold.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin />
|
||||
<link
|
||||
rel="preload"
|
||||
href="/assets/fonts/InterSemiBold.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin />
|
||||
|
||||
<meta name="theme-color" content="#CF1971" />
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:image" content="https://omorphia.modrinth.com/omorphia.png" />
|
||||
<meta property="og:site_name" content="Modrinth" />
|
||||
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body>
|
||||
%sveltekit.body%
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 25 25" aria-hidden="true">
|
||||
<path stroke="var(--accent-color)" stroke-width="2" d="M15.933 18.394c-3.261-.286-11.074-1.466-14.644-8.469m22.422 0c-2.114 4.291-10.8 11.927-16.017 13.026m6.18-21.87C10.268 3.06 5.496 9.72 5.633 14.388m17.732-5.664c-2.232-1.888-9.562-5.15-16.943 1.716m8.652-3.947c1.888 1.087 5.492 3.288 4.806 8.369m-9.956 2.787c-.286-1.888-.103-6.213 2.918-8.41m4.12 4.977a2.43 2.43 0 0 0-.075-.4m0 0c-.528-1.965-2.354-5.652-6.963-5.908m6.963 5.908c-2.856 2.601-6.11 3.11-7.65 2.975m7.65-2.975c.752-.685 1.702-2.374 2.36-3.376m-8.98 2.575c.687.744 3.468 2.369 4.978 2.231M24 12.5C24 18.851 18.851 24 12.5 24S1 18.851 1 12.5 6.149 1 12.5 1 24 6.149 24 12.5Z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 747 B |
@@ -1,76 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Button } from 'omorphia'
|
||||
import IconMoon from 'virtual:icons/heroicons-outline/moon'
|
||||
import IconSun from 'virtual:icons/heroicons-outline/sun'
|
||||
|
||||
export let meta: { raised: boolean; column: boolean }
|
||||
|
||||
let theme = 'light'
|
||||
let background = meta.raised ? 'var(--color-raised-bg)' : 'var(--color-bg)'
|
||||
</script>
|
||||
|
||||
<div class="example">
|
||||
<div class="example__preview theme-{theme} base" class:column={meta.column} style:background>
|
||||
<slot name="example" />
|
||||
</div>
|
||||
<div class="example__source">
|
||||
<div class="example__source__options">
|
||||
<Button
|
||||
color="primary-light"
|
||||
on:click={() => (theme === 'light' ? (theme = 'dark') : (theme = 'light'))}>
|
||||
{#if theme === 'light'}
|
||||
<IconMoon />
|
||||
{:else}
|
||||
<IconSun />
|
||||
{/if}
|
||||
</Button>
|
||||
</div>
|
||||
<pre class="example__source__code language-svelte"><slot name="code" /></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="postcss">
|
||||
.example {
|
||||
margin: 1rem 0 2rem;
|
||||
|
||||
&__preview {
|
||||
border-radius: var(--rounded-sm-top);
|
||||
border: solid 2px hsl(0, 0%, 20%);
|
||||
border-bottom: none;
|
||||
display: flex;
|
||||
grid-gap: 1rem;
|
||||
flex-wrap: wrap;
|
||||
position: relative;
|
||||
justify-content: flex-start;
|
||||
z-index: 1;
|
||||
padding: 1rem;
|
||||
|
||||
&.column {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
&__source {
|
||||
position: relative;
|
||||
|
||||
&__options {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
:global(button) {
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
&__code {
|
||||
margin: 0;
|
||||
border-radius: var(--rounded-sm-bottom) !important;
|
||||
background: hsl(220, 13%, 22%);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,111 +0,0 @@
|
||||
<script lang="ts">
|
||||
import OmorphiaLogo from '../assets/omorphia.svg?component'
|
||||
import IconLogoGithub from 'virtual:icons/carbon/logo-github'
|
||||
import IconChat from 'virtual:icons/heroicons-outline/chat-alt-2'
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
let headerElement: HTMLElement
|
||||
|
||||
onMount(() => {
|
||||
let lastScrollTop: number
|
||||
window.addEventListener('scroll', () => {
|
||||
let scrollTop = window.pageYOffset || document.documentElement.scrollTop
|
||||
if (scrollTop > lastScrollTop && headerElement) {
|
||||
headerElement.style.top = '-100%'
|
||||
} else if (headerElement) {
|
||||
headerElement.style.top = '0'
|
||||
}
|
||||
lastScrollTop = scrollTop
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<header class="header" bind:this={headerElement}>
|
||||
<OmorphiaLogo class="header__logo" />
|
||||
<div class="header__title">Omorphia</div>
|
||||
<div class="header__links">
|
||||
<a class="hide-sm" href="https://modrinth.com">Modrinth.com</a>
|
||||
<span class="spacer-dot hide-sm" />
|
||||
<a href="https://www.npmjs.com/package/omorphia">NPM</a>
|
||||
<span class="spacer-dot" />
|
||||
<a href="https://rewrite.modrinth.com/discord">
|
||||
<IconChat />
|
||||
</a>
|
||||
<a href="https://github.com/modrinth/omorphia">
|
||||
<IconLogoGithub />
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<style lang="postcss">
|
||||
.header {
|
||||
display: flex;
|
||||
grid-gap: 0.5rem;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
padding: 1rem 1.5rem;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
background-color: hsl(0, 0%, 100%);
|
||||
box-shadow: hsla(221, 39%, 11%, 0.2) 0 2px 4px 0, hsla(221, 39%, 11%, 0.05) 0 -2px 2px 0 inset;
|
||||
transition: top 0.3s ease-in-out;
|
||||
|
||||
@media not (--sm) {
|
||||
top: 0 !important;
|
||||
}
|
||||
|
||||
@media (--sm) {
|
||||
padding: 12px 2rem;
|
||||
}
|
||||
|
||||
:global(&__logo) {
|
||||
max-width: 2rem;
|
||||
min-width: 2rem;
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&__links {
|
||||
margin-left: auto;
|
||||
grid-gap: 1rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
|
||||
:global(svg) {
|
||||
height: 22px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.hide-sm {
|
||||
display: none;
|
||||
|
||||
@media (--sm) {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
|
||||
&:not(:hover) {
|
||||
color: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.spacer-dot {
|
||||
background-color: hsla(0, 0%, 0%, 0.2);
|
||||
border-radius: var(--rounded-max);
|
||||
width: 5px;
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
</style>
|
||||
@@ -1,161 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores'
|
||||
import IconMenu from 'virtual:icons/lucide/menu'
|
||||
|
||||
const cleanPath = (it: string) => it.replace(/\.\.\/routes\/.*\//, '').replace('.md', '')
|
||||
|
||||
const components = Object.keys(import.meta.glob('../routes/components/**'))
|
||||
.map(cleanPath)
|
||||
.sort()
|
||||
|
||||
const classes = Object.keys(import.meta.glob('../routes/classes/**'))
|
||||
.map(cleanPath)
|
||||
.sort()
|
||||
|
||||
let slideIn = false
|
||||
|
||||
$: if ($page.url.pathname) {
|
||||
slideIn = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<nav class="sidebar" class:slideIn>
|
||||
<div class="sidebar__content">
|
||||
<div class="section">
|
||||
<a href="/" class="section__link">Introduction</a>
|
||||
<a href="/setup" class="section__link">Setup</a>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<span class="section__title">Usage</span>
|
||||
<a href="/usage/icons" class="section__link">Using Icons</a>
|
||||
<a href="/usage/css" class="section__link">Writing CSS</a>
|
||||
<a href="/usage/illustrations" class="section__link">Illustrations</a>
|
||||
<a href="/usage/utils" class="section__link">Built-in utilities</a>
|
||||
<a href="/usage/generator" class="section__link">Generator plugin</a>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<span class="section__title">Components</span>
|
||||
{#each components as component}
|
||||
<a href="/components/{component}" class="section__link">{component}</a>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<span class="section__title">Classes</span>
|
||||
{#each classes as page}
|
||||
<a href="/classes/{page}" class="section__link">{page}</a>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="sidebar__toggle" on:click={() => (slideIn = !slideIn)}>
|
||||
<IconMenu />
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<style lang="postcss">
|
||||
:root {
|
||||
--sidebar-color: hsl(220, 15%, 40%);
|
||||
--title-color: hsl(216, 10%, 80%);
|
||||
--link-color: hsl(216, 10%, 90%);
|
||||
--scrollbar-thumb-color: hsl(216, 10%, 70%);
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-color: var(--sidebar-color);
|
||||
color: var(--title-color);
|
||||
width: var(--sidebar-width);
|
||||
max-width: 70vw;
|
||||
position: fixed;
|
||||
left: -100%;
|
||||
top: 0;
|
||||
z-index: 5;
|
||||
transition: left 0.2s ease-in-out;
|
||||
box-shadow: 2px 0px 4px hsla(221, 39%, 11%, 0.2);
|
||||
|
||||
@media (--md) {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&__content {
|
||||
mask-image: linear-gradient(to bottom, transparent, hsla(0, 0%, 0%, 1) 5% 95%, transparent);
|
||||
padding: 88px 2rem 2rem;
|
||||
height: 100vh;
|
||||
max-height: 100vh;
|
||||
overflow-y: auto;
|
||||
grid-gap: 2.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
grid-gap: 0.5rem;
|
||||
|
||||
&__title {
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&__link {
|
||||
color: var(--link-color);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__toggle {
|
||||
position: fixed;
|
||||
left: 1rem;
|
||||
bottom: 1rem;
|
||||
padding: 0.5rem;
|
||||
aspect-ratio: 1 / 1;
|
||||
background-color: var(--accent-color);
|
||||
z-index: 20;
|
||||
border-radius: var(--rounded);
|
||||
color: white;
|
||||
box-shadow: var(--shadow-inset-sm), var(--shadow-floating);
|
||||
transition: left 0.2s cubic-bezier(0.38, 0.52, 0.37, 1.27);
|
||||
|
||||
:global(.icon) {
|
||||
width: 2rem;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@media (--md) {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
&.slideIn {
|
||||
left: 0;
|
||||
|
||||
.sidebar__toggle {
|
||||
left: calc(2rem + min(70vw, var(--sidebar-width)));
|
||||
}
|
||||
}
|
||||
|
||||
scrollbar-color: var(--scrollbar-thumb-color) var(--sidebar-color);
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 1rem;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background-color: var(--sidebar-color);
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: var(--scrollbar-thumb-color);
|
||||
border-radius: var(--rounded-max);
|
||||
border: 3px solid var(--sidebar-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,4 +0,0 @@
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
// Used in `src/utils/send.ts`
|
||||
export const token = writable('')
|
||||
8
docs/global.d.ts
vendored
8
docs/global.d.ts
vendored
@@ -1,8 +0,0 @@
|
||||
declare module '$assets/images/*'
|
||||
declare module '$locales/*'
|
||||
|
||||
declare module '*.svg?component' {
|
||||
import type { SvelteComponentTyped } from 'svelte/internal'
|
||||
class SVGComponent extends SvelteComponentTyped<{ class: string }> {}
|
||||
export default SVGComponent
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
<script lang="ts">
|
||||
import IconPencil from 'virtual:icons/heroicons-outline/pencil'
|
||||
import { page } from '$app/stores'
|
||||
import COMPONENT_API from '../../generated/COMPONENT_API.json'
|
||||
import { markdownInline } from 'omorphia/utils'
|
||||
|
||||
export let fileName = $page.url.pathname
|
||||
.substring($page.url.pathname.lastIndexOf('/') + 1)
|
||||
.replace('.html', '')
|
||||
|
||||
export let title = fileName
|
||||
|
||||
export let description = 'Learn about Omorphia, the component & style library'
|
||||
|
||||
let editUrl = `https://github.com/modrinth/omorphia/edit/main/docs/routes/${
|
||||
$page.url.pathname.replace('/', '') || 'index'
|
||||
}.md`
|
||||
|
||||
let api = { props: [], events: [], slots: [] }
|
||||
if ($page.url.pathname.includes('components')) {
|
||||
api = COMPONENT_API[`${title}.svelte`]
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{title ? `${title} • Omorphia` : 'Omorphia'}</title>
|
||||
<meta name="description" content={description} />
|
||||
</svelte:head>
|
||||
|
||||
{#if title}<h1>{title}</h1>{/if}
|
||||
<a class="edit-link" href={editUrl}>
|
||||
<IconPencil />
|
||||
Edit this page on GitHub</a>
|
||||
<slot />
|
||||
|
||||
{#if api}
|
||||
<div class="extra-info">
|
||||
{#if api.props.length > 0}
|
||||
<h2>Properties</h2>
|
||||
<table class="api-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Type</th>
|
||||
<th>Default</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each api.props as prop}
|
||||
<tr>
|
||||
<td><code>{prop.name}</code></td>
|
||||
<td><code>{prop.type ?? ''}</code></td>
|
||||
<td><code>{prop.value ?? ''}</code></td>
|
||||
<td>
|
||||
{prop.constant ? '[Read only] ' : ''}
|
||||
{@html markdownInline(prop.description?.replace('null', '') || '')}
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
{/if}
|
||||
{#if api.events.length > 0}
|
||||
<h2>Events</h2>
|
||||
<table class="api-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Forwarded</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each api.events as event}
|
||||
<tr>
|
||||
<td><code>{event.name}</code></td>
|
||||
<td>{!!event.parent}</td>
|
||||
<td>{event.description?.replace('null', '') || ''}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
{/if}
|
||||
{#if api.slots.length > 0}
|
||||
<h2>Slots</h2>
|
||||
<table class="api-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Fallback</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each api.slots as slot}
|
||||
<tr>
|
||||
<td><code>{slot.name}</code></td>
|
||||
<td>{slot.fallback ?? 'None'}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style lang="postcss">
|
||||
.edit-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
grid-gap: 0.5rem;
|
||||
margin-bottom: 54px;
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.extra-info {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
.api-table {
|
||||
border-collapse: collapse;
|
||||
margin-top: -6px;
|
||||
}
|
||||
|
||||
.api-table tr {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.api-table tbody {
|
||||
border: 2px solid grey;
|
||||
}
|
||||
|
||||
.api-table th {
|
||||
text-transform: uppercase;
|
||||
font-size: 12.5px;
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
@@ -1,53 +0,0 @@
|
||||
import { ComponentParser } from 'sveld'
|
||||
import * as svelte from 'svelte/compiler'
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
import { preprocess } from '../../src/config/svelte.js'
|
||||
|
||||
export default function sveld() {
|
||||
return {
|
||||
name: 'vite-plugin-sveld',
|
||||
// This generates a `COMPONENT_API.json` with sveld in the `/_app` folder which is used by the docs about components
|
||||
// TODO: Make more efficient & handle typescript types with `svelte2tsx`
|
||||
async transform(src, id) {
|
||||
if (id.includes('/src/components/')) {
|
||||
await generateComponentApi()
|
||||
}
|
||||
},
|
||||
async buildStart() {
|
||||
await generateComponentApi()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
async function parseRaw(raw, filePath) {
|
||||
let { code } = await svelte.preprocess(raw, preprocess, {
|
||||
filename: filePath,
|
||||
})
|
||||
return new ComponentParser({
|
||||
verbose: false,
|
||||
}).parseSvelteComponent(code, {
|
||||
filePath,
|
||||
moduleName: filePath,
|
||||
})
|
||||
}
|
||||
|
||||
async function generateComponentApi() {
|
||||
const output = {}
|
||||
|
||||
const componentFiles = await fs.readdir(path.resolve('./src/components'))
|
||||
|
||||
for (const fileName of componentFiles.filter((name) => name.endsWith('.svelte'))) {
|
||||
const filePath = path.resolve('./src/components', fileName)
|
||||
const raw = (await fs.readFile(filePath)).toString()
|
||||
output[fileName] = await parseRaw(raw, filePath)
|
||||
}
|
||||
|
||||
try {
|
||||
await fs.mkdir(path.resolve('./generated'))
|
||||
} catch {
|
||||
// Do nothing, directory already exists
|
||||
}
|
||||
|
||||
await fs.writeFile(path.resolve('./generated/COMPONENT_API.json'), JSON.stringify(output))
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
<script context="module" lang="ts">
|
||||
import { addMessages, init } from 'svelte-intl-precompile'
|
||||
import en from '$locales/en'
|
||||
addMessages('en', en)
|
||||
init({
|
||||
initialLocale: 'en',
|
||||
fallbackLocale: 'en',
|
||||
})
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import 'omorphia/styles.postcss'
|
||||
import '../styles/prism-one-dark.css'
|
||||
import '../styles/gh-markdown.postcss'
|
||||
import Sidebar from '../components/Sidebar.svelte'
|
||||
import Header from '../components/Header.svelte'
|
||||
</script>
|
||||
|
||||
<div class="app theme-light">
|
||||
<Header />
|
||||
<Sidebar />
|
||||
<main class="app__content">
|
||||
<article>
|
||||
<slot />
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<style lang="postcss">
|
||||
:global {
|
||||
html {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-size: var(--font-size);
|
||||
font-family: var(--body-font);
|
||||
|
||||
--accent-color: hsl(331, 80%, 45%);
|
||||
--accent-color-transparent: hsla(331, 80%, 45%, 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
.app {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
overflow: hidden;
|
||||
background-color: var(--color-bg);
|
||||
|
||||
--sidebar-width: 275px;
|
||||
|
||||
&__content {
|
||||
@media (--md) {
|
||||
padding-left: var(--sidebar-width);
|
||||
}
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
|
||||
article {
|
||||
max-width: 800px;
|
||||
padding-block: 9rem 4rem;
|
||||
padding-inline: 24px;
|
||||
|
||||
@media (--sm) {
|
||||
padding-inline: 48px;
|
||||
padding-block: 9rem 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,15 +0,0 @@
|
||||
```svelte example raised
|
||||
<script>
|
||||
import { Button } from 'omorphia'
|
||||
import IconHeartSolid from 'virtual:icons/heroicons-solid/heart'
|
||||
import IconCalendar from 'virtual:icons/lucide/calendar'
|
||||
</script>
|
||||
|
||||
<div class="actions">
|
||||
<Button><IconHeartSolid /> Unfollow</Button>
|
||||
<span class="stat">
|
||||
<IconCalendar />
|
||||
Updated 12 days ago
|
||||
</span>
|
||||
</div>
|
||||
```
|
||||
@@ -1,5 +0,0 @@
|
||||
Base should be applied to a "root" element, like `<body>`, to provide base styles for common things like text. The theme mode, `light-theme`, `dark-theme`, or `oled-theme`, should also be added to this element.
|
||||
|
||||
```svelte example
|
||||
<div class="base theme-light">...</div>
|
||||
```
|
||||
@@ -1,33 +0,0 @@
|
||||
### A simple example
|
||||
|
||||
```svelte example
|
||||
<div class="card">
|
||||
<h3>Moon/Distance to Earth</h3>
|
||||
<h2>238,900 mi</h2>
|
||||
<p>
|
||||
The moon's distance from Earth affects the strength of ocean tides and the appearance of solar
|
||||
eclipses in our skies. The average distance between the blue planet and its only natural
|
||||
satellite is about 238,855 miles (384,400 kilometers), according to NASA.
|
||||
</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
### A more complex example
|
||||
|
||||
```svelte example
|
||||
<script lang="ts">
|
||||
import { Button } from 'omorphia'
|
||||
import IconPencil from 'virtual:icons/heroicons-outline/pencil'
|
||||
import { Avatar } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<div class="card">
|
||||
<div class="card__overlay">
|
||||
<Button raised><IconPencil /> Edit</Button>
|
||||
</div>
|
||||
<div class="card__banner card__banner--short card__banner--dark" />
|
||||
<Avatar size="md" floatUp />
|
||||
<h1 class="title">Project</h1>
|
||||
<p class="summary">A project that has a description right here.</p>
|
||||
</div>
|
||||
```
|
||||
@@ -1,7 +0,0 @@
|
||||
```svelte example raised
|
||||
Some words could go here.
|
||||
|
||||
<hr class="divider" />
|
||||
|
||||
And some other words could go here.
|
||||
```
|
||||
@@ -1,14 +0,0 @@
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import IconFile from 'virtual:icons/lucide/file'
|
||||
import { Button } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<div class="file file--primary">
|
||||
<div class="file__tab">
|
||||
<IconFile />
|
||||
<div class="file__tab__name"><b>cool-mod.jar</b></div>
|
||||
<Button raised>Download</Button>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
@@ -1,10 +0,0 @@
|
||||
```svelte example raised
|
||||
<div class="info-table">
|
||||
<span class="info-table__label">License</span>
|
||||
<a href="#mit" class="link">MIT</a>
|
||||
<span class="info-table__label">Project ID</span>
|
||||
<span>11223344</span>
|
||||
<span class="info-table__label">Visibilty</span>
|
||||
<span>Approved</span>
|
||||
</div>
|
||||
```
|
||||
@@ -1,24 +0,0 @@
|
||||
### Single example
|
||||
|
||||
```svelte example raised
|
||||
<a class="link" href="#place"> Go somewhere! </a>
|
||||
```
|
||||
|
||||
### Group example
|
||||
|
||||
```svelte example raised
|
||||
<script>
|
||||
import IconIssues from 'virtual:icons/heroicons-outline/exclamation'
|
||||
import IconCode from 'virtual:icons/heroicons-outline/code'
|
||||
import IconClock from 'virtual:icons/lucide/flag-triangle-right'
|
||||
import IconWiki from 'virtual:icons/heroicons-outline/book-open'
|
||||
</script>
|
||||
|
||||
<div class="link-group" style="max-width: 18rem">
|
||||
<a class="link" href="#issues"><IconIssues /> Issues</a>
|
||||
<a class="link" href="#source"><IconCode /> Source</a>
|
||||
<a class="link" href="#wiki"><IconWiki /> Wiki</a>
|
||||
<a class="link" href="#issues"><IconIssues /> Discord chat</a>
|
||||
<a class="link" href="#source"><IconCode /> Source link</a>
|
||||
</div>
|
||||
```
|
||||
@@ -1,13 +0,0 @@
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Avatar } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<a class="member" href="#user">
|
||||
<Avatar src="https://avatars1.githubusercontent.com/u/6166773" size="sm" circle />
|
||||
<div class="member__info">
|
||||
<span class="member__info__link">Prospector</span>
|
||||
<span>Owner</span>
|
||||
</div>
|
||||
</a>
|
||||
```
|
||||
@@ -1,32 +0,0 @@
|
||||
### Single Example
|
||||
|
||||
```svelte example raised
|
||||
<script>
|
||||
import IconStar from 'virtual:icons/heroicons-outline/star'
|
||||
</script>
|
||||
|
||||
<div class="stat">
|
||||
<IconStar />
|
||||
123K stars
|
||||
</div>
|
||||
```
|
||||
|
||||
### Group Example
|
||||
|
||||
```svelte example raised
|
||||
<script>
|
||||
import IconDownload from 'virtual:icons/heroicons-outline/download'
|
||||
import IconHeart from 'virtual:icons/heroicons-outline/heart'
|
||||
</script>
|
||||
|
||||
<div class="stat-group">
|
||||
<div class="stat">
|
||||
<IconDownload />
|
||||
4.1B downloads
|
||||
</div>
|
||||
<div class="stat stat--light">
|
||||
<IconHeart />
|
||||
3 followers
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
@@ -1,15 +0,0 @@
|
||||
```svelte example raised
|
||||
<script>
|
||||
import IconCarrot from 'virtual:icons/lucide/carrot'
|
||||
import IconGlobe from 'virtual:icons/heroicons-outline/globe'
|
||||
</script>
|
||||
|
||||
<div class="tag-group">
|
||||
<div class="tag">
|
||||
<IconCarrot /> Food
|
||||
</div>
|
||||
<div class="tag">
|
||||
<IconGlobe /> World generation
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
@@ -1,5 +0,0 @@
|
||||
```svelte example raised
|
||||
<h1 class="title-primary">Tree Mod</h1>
|
||||
<h2 class="title-secondary">Information</h2>
|
||||
<h3 class="title-tertiary">Members</h3>
|
||||
```
|
||||
@@ -1,15 +0,0 @@
|
||||
Avatars are used for project icons and user profile pictures. Low resolution images are rendered pixelated to preserve pixel art.
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Avatar } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<Avatar size="lg" circle src="https://avatars3.githubusercontent.com/u/44736536?v=4" />
|
||||
<Avatar size="md" src="https://cdn.modrinth.com/data/AANobbMI/icon.png" />
|
||||
<Avatar
|
||||
size="md"
|
||||
src="https://staging-cdn.modrinth.com/data/d1SqMrzw/9a39b0c80a49976b0c04053682708374e18105fe.png" />
|
||||
<Avatar size="sm" />
|
||||
<Avatar size="xs" circle src="https://avatars1.githubusercontent.com/u/6166773?v=4" />
|
||||
```
|
||||
@@ -1,10 +0,0 @@
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Badge } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<Badge color="red" label="Tomato" />
|
||||
<Badge color="yellow" label="Squash" />
|
||||
<Badge color="green" label="Lettuce" />
|
||||
<Badge label="Onion" />
|
||||
```
|
||||
@@ -1,46 +0,0 @@
|
||||
### Single example
|
||||
|
||||
```svelte example
|
||||
<script lang="ts">
|
||||
import { Button } from 'omorphia'
|
||||
import IconDownload from 'virtual:icons/heroicons-outline/download'
|
||||
</script>
|
||||
|
||||
<Button raised><IconDownload /> Download</Button>
|
||||
```
|
||||
|
||||
### Color variants example
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Button } from 'omorphia'
|
||||
import IconDownload from 'virtual:icons/heroicons-outline/download'
|
||||
</script>
|
||||
|
||||
<div class="button-group">
|
||||
<Button>Default</Button>
|
||||
<Button color="primary">Primary</Button>
|
||||
<Button color="primary-light">Light primary</Button>
|
||||
<Button color="secondary">Secondary</Button>
|
||||
<Button color="tertiary">Tertiary</Button>
|
||||
<Button color="danger">Danger</Button>
|
||||
<Button color="danger-light">Light danger</Button>
|
||||
<Button color="transparent">Transparent</Button>
|
||||
<Button disabled>Disabled</Button>
|
||||
</div>
|
||||
```
|
||||
|
||||
### With icons example
|
||||
|
||||
```svelte example
|
||||
<script lang="ts">
|
||||
import { Button } from 'omorphia'
|
||||
import IconDownload from 'virtual:icons/heroicons-outline/download'
|
||||
import IconHeart from 'virtual:icons/heroicons-outline/heart'
|
||||
</script>
|
||||
|
||||
<div class="button-group">
|
||||
<Button color="primary" raised><IconDownload /></Button>
|
||||
<Button raised><IconHeart /> Follow mod</Button>
|
||||
</div>
|
||||
```
|
||||
@@ -1,20 +0,0 @@
|
||||
### Text-only Example
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Checkbox } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<Checkbox>Extra components</Checkbox>
|
||||
```
|
||||
|
||||
### Text with Icon Example
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Checkbox } from 'omorphia'
|
||||
import IconCarrot from 'virtual:icons/lucide/carrot'
|
||||
</script>
|
||||
|
||||
<Checkbox><IconCarrot /> Food</Checkbox>
|
||||
```
|
||||
@@ -1,36 +0,0 @@
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { CheckboxList } from 'omorphia'
|
||||
import IconSquare from 'virtual:icons/lucide/square'
|
||||
import IconCircle from 'virtual:icons/lucide/circle'
|
||||
import IconTriangle from 'virtual:icons/lucide/triangle'
|
||||
|
||||
let selected = ['TRI']
|
||||
</script>
|
||||
|
||||
<CheckboxList
|
||||
bind:value={selected}
|
||||
options={[
|
||||
{
|
||||
label: 'Circle',
|
||||
icon: IconCircle,
|
||||
value: 'CIR',
|
||||
},
|
||||
{
|
||||
label: 'Triangle',
|
||||
icon: IconTriangle,
|
||||
value: 'TRI',
|
||||
},
|
||||
{
|
||||
label: 'Square',
|
||||
icon: IconSquare,
|
||||
value: 'SQU',
|
||||
},
|
||||
{
|
||||
label: 'Blank',
|
||||
value: 'BLA',
|
||||
},
|
||||
]} />
|
||||
|
||||
Selected: {selected}
|
||||
```
|
||||
@@ -1,20 +0,0 @@
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { CheckboxVirtualList } from 'omorphia'
|
||||
import IconStar from 'virtual:icons/heroicons-outline/star'
|
||||
|
||||
let options = Array(100)
|
||||
.fill({})
|
||||
.map((option, index) => ({
|
||||
label: 'Star-' + index,
|
||||
icon: IconStar,
|
||||
value: index,
|
||||
}))
|
||||
|
||||
let selected = [22, 24]
|
||||
</script>
|
||||
|
||||
<CheckboxVirtualList bind:value={selected} {options} />
|
||||
|
||||
Selected: {selected}
|
||||
```
|
||||
@@ -1,47 +0,0 @@
|
||||
### Simple example
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Chips } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<Chips
|
||||
options={[
|
||||
{
|
||||
label: 'One',
|
||||
value: 'one',
|
||||
},
|
||||
{
|
||||
label: 'Two',
|
||||
value: 'two',
|
||||
},
|
||||
]} />
|
||||
```
|
||||
|
||||
### Force an option to be selected with `neverEmpty`
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Chips } from 'omorphia'
|
||||
|
||||
let foo = 'modpack'
|
||||
</script>
|
||||
|
||||
<Chips
|
||||
neverEmpty
|
||||
bind:value={foo}
|
||||
options={[
|
||||
{
|
||||
label: 'Mod',
|
||||
value: 'mod',
|
||||
},
|
||||
{
|
||||
label: 'Modpack',
|
||||
value: 'modpack',
|
||||
},
|
||||
{
|
||||
label: 'World',
|
||||
value: 'world',
|
||||
},
|
||||
]} />
|
||||
```
|
||||
@@ -1,7 +0,0 @@
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Code } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<Code text="AaBbCcDd" />
|
||||
```
|
||||
@@ -1,12 +0,0 @@
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Field, Slider, TextInput } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<Field label="Favorite number" let:id>
|
||||
<Slider min="0" max="100" value="69" {id} />
|
||||
</Field>
|
||||
<Field label="Favorite color" helper="Pick whatever color you like the most" let:id>
|
||||
<TextInput placeholder="Enter another color..." {id} />
|
||||
</Field>
|
||||
```
|
||||
@@ -1,31 +0,0 @@
|
||||
### Single constrained example
|
||||
|
||||
```svelte example raised column
|
||||
<script lang="ts">
|
||||
import { Field, FileUpload } from 'omorphia'
|
||||
|
||||
let file: File
|
||||
</script>
|
||||
|
||||
<Field label="Upload image">
|
||||
<FileUpload accept="image/*" constrained bind:file />
|
||||
</Field>
|
||||
|
||||
File name: {file?.name}
|
||||
```
|
||||
|
||||
### Multiple example
|
||||
|
||||
```svelte example raised column
|
||||
<script lang="ts">
|
||||
import { Field, FileUpload } from 'omorphia'
|
||||
|
||||
let files: File[] = []
|
||||
</script>
|
||||
|
||||
<Field label="Upload file">
|
||||
<FileUpload accept="*" multiple bind:files />
|
||||
</Field>
|
||||
|
||||
Count: {files.length}
|
||||
```
|
||||
@@ -1,21 +0,0 @@
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Modal, Button } from 'omorphia'
|
||||
import IconArrowRight from 'virtual:icons/heroicons-outline/arrow-right'
|
||||
import IconCheck from 'virtual:icons/heroicons-outline/check'
|
||||
</script>
|
||||
|
||||
<Modal title="Example modal" danger let:trigger>
|
||||
<Button on:click={trigger} slot="trigger">Open modal</Button>
|
||||
|
||||
<p>Secret message goes here!</p>
|
||||
<Button color="primary" slot="button"><IconArrowRight /> Continue</Button>
|
||||
</Modal>
|
||||
|
||||
<Modal let:trigger size="sm">
|
||||
<Button on:click={trigger} slot="trigger">Confirm modal</Button>
|
||||
|
||||
Are you sure you want to delete this gallery image?
|
||||
<Button color="primary" slot="button"><IconCheck /> Confirm</Button>
|
||||
</Modal>
|
||||
```
|
||||
@@ -1,13 +0,0 @@
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { ModalDeletion, Button } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<ModalDeletion
|
||||
type="account"
|
||||
key="venashial"
|
||||
let:trigger
|
||||
on:deletion={() => console.log('Do something...')}>
|
||||
<Button slot="trigger" color="danger" on:click={trigger}>Delete account</Button>
|
||||
</ModalDeletion>
|
||||
```
|
||||
@@ -1,66 +0,0 @@
|
||||
`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).
|
||||
|
||||
### Query example
|
||||
|
||||
```svelte example
|
||||
<script lang="ts">
|
||||
import { NavRow } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<div class="card card--strip card--pad-x">
|
||||
<NavRow
|
||||
level={1}
|
||||
query={'tab'}
|
||||
links={[
|
||||
{
|
||||
href: '',
|
||||
label: 'All',
|
||||
},
|
||||
{
|
||||
href: 'mods',
|
||||
label: 'Mods',
|
||||
},
|
||||
{
|
||||
href: 'modpacks',
|
||||
label: 'Modpacks',
|
||||
},
|
||||
{
|
||||
href: 'textures',
|
||||
label: 'Textures',
|
||||
},
|
||||
{
|
||||
href: 'shaders',
|
||||
label: 'Shaders',
|
||||
},
|
||||
{
|
||||
href: 'maps',
|
||||
label: 'Maps',
|
||||
},
|
||||
]} />
|
||||
</div>
|
||||
```
|
||||
|
||||
### Route example
|
||||
|
||||
```svelte example
|
||||
<script lang="ts">
|
||||
import { NavRow } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<NavRow
|
||||
level={1}
|
||||
links={[
|
||||
{
|
||||
href: '/Button',
|
||||
label: 'Button',
|
||||
},
|
||||
{
|
||||
href: '/Chips',
|
||||
label: 'Chips',
|
||||
},
|
||||
{
|
||||
href: '/NavRow',
|
||||
label: 'NavRow',
|
||||
},
|
||||
]} />
|
||||
```
|
||||
@@ -1,9 +0,0 @@
|
||||
Use pagination to show a set of page numbers and navigation directions to move through paginated data.
|
||||
|
||||
```svelte example
|
||||
<script lang="ts">
|
||||
import { Pagination } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<Pagination page={20} count={500} />
|
||||
```
|
||||
@@ -1,36 +0,0 @@
|
||||
### Default option example
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Select } from 'omorphia'
|
||||
|
||||
let sortMethod = 'downloads'
|
||||
</script>
|
||||
|
||||
<Select
|
||||
options={[
|
||||
{ value: '', label: 'Relevance' },
|
||||
{ value: 'downloads', label: 'Downloads' },
|
||||
{ value: 'follows', label: 'Followers' },
|
||||
{ value: 'newest', label: 'Recently created' },
|
||||
{ value: 'updated', label: 'Recently updated' },
|
||||
]}
|
||||
bind:value={sortMethod} />
|
||||
```
|
||||
|
||||
### Icon example
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Select } from 'omorphia'
|
||||
import IconSun from 'virtual:icons/heroicons-outline/sun'
|
||||
</script>
|
||||
|
||||
<Select
|
||||
options={[
|
||||
{ value: '1', label: 'Light' },
|
||||
{ value: '2', label: 'Dark' },
|
||||
{ value: '3', label: 'OLED' },
|
||||
]}
|
||||
icon={IconSun} />
|
||||
```
|
||||
@@ -1,7 +0,0 @@
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Slider } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<Slider min="0" max="10" value="4" />
|
||||
```
|
||||
@@ -1,9 +0,0 @@
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { TextInput } from 'omorphia'
|
||||
import IconSearch from 'virtual:icons/heroicons-outline/search'
|
||||
</script>
|
||||
|
||||
<TextInput placeholder="Enter another color..." />
|
||||
<TextInput icon={IconSearch} placeholder="Search..." />
|
||||
```
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
title: Introduction
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Omorphia is Modrinth's component, style, and utility library for Svelte projects. It includes:
|
||||
|
||||
- 🧩 Typed components which enhance HTML elements and provide a consistent UI
|
||||
- 🎨 CSS classes to easily style elements with a coherent style
|
||||
- 🧰 Typed utilities to solve common tasks quick and dependably
|
||||
- ⚙️ Configuration for SvelteKit and PostCSS to simplify setups
|
||||
- 🚚 A Rollup plugin to generate a cache of heavily used API requests and OpenAPI types
|
||||
|
||||
Omorphia is used in [Knossos](https://github.com/modrinth/knossos) (modrinth.com) and [Theseus](https://github.com/modrinth/theseus) (Minecraft launcher).
|
||||
|
||||
It uses [Svelte](https://svelte.dev/) to deliver the best performance with the least boilerplate.
|
||||
|
||||
## Try Omorphia online
|
||||
|
||||
You can try Omorphia online via [➜ **CodeSandbox** 💻](https://codesandbox.io/s/omorphia-starter-bsbgke).
|
||||
|
||||
## Getting started
|
||||
|
||||
Follow the instructions on the [➜ **setup page** 🛠️](/setup).
|
||||
@@ -1,210 +0,0 @@
|
||||
---
|
||||
title: Setup
|
||||
---
|
||||
|
||||
## `0.` Prerequisites
|
||||
|
||||
First install the following:
|
||||
|
||||
- [Node 16.x](https://docs.volta.sh/guide/getting-started) or higher
|
||||
- [PNPM](https://pnpm.io/installation) (required for Modrinth projects)
|
||||
|
||||
## `1.` Create a SvelteKit project
|
||||
|
||||
Run the following command to create a SvelteKit project:
|
||||
|
||||
```bash
|
||||
pnpm create svelte
|
||||
```
|
||||
|
||||
Follow the instructions to install dependencies and setup git.
|
||||
|
||||
## `2.` Add Omorphia to your project
|
||||
|
||||
```bash
|
||||
pnpm add omorphia
|
||||
```
|
||||
|
||||
## `3.` Setup translations
|
||||
|
||||
Install the translations submodule:
|
||||
|
||||
```bash
|
||||
git submodule add https://github.com/modrinth/translations locales/
|
||||
```
|
||||
|
||||
Install `svelte-intl-precompile`:
|
||||
|
||||
```bash
|
||||
pnpm add svelte-intl-precompile -D
|
||||
```
|
||||
|
||||
Add translations in `src/routes/__layout.svelte`:
|
||||
|
||||
```html
|
||||
<script context="module" lang="ts">
|
||||
import { init, waitLocale, t, getLocaleFromAcceptLanguageHeader } from 'svelte-intl-precompile'
|
||||
import { registerAll, availableLocales } from '$locales'
|
||||
|
||||
registerAll()
|
||||
|
||||
export const load: import('@sveltejs/kit').Load = async ({ session }) => {
|
||||
init({
|
||||
fallbackLocale: 'en',
|
||||
initialLocale: getLocaleFromAcceptLanguageHeader(session.acceptLanguage, availableLocales),
|
||||
})
|
||||
await waitLocale()
|
||||
|
||||
return {}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## `4.` Configure SvelteKit
|
||||
|
||||
Add the following parts to your `svelte.config.js` file:
|
||||
|
||||
```js
|
||||
import adapter from '@sveltejs/adapter-auto'
|
||||
import { preprocess } from 'omorphia/config/svelte'
|
||||
import path from 'path'
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
preprocess: [preprocess],
|
||||
|
||||
kit: {
|
||||
adapter: adapter(),
|
||||
|
||||
alias: {
|
||||
$generated: path.resolve('./generated'),
|
||||
$stores: path.resolve('./src/stores'),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
```
|
||||
|
||||
Create a `src/stores/account.ts` file with a `token` store export:
|
||||
|
||||
```ts
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
export const token = writable('')
|
||||
```
|
||||
|
||||
## `5.` Configure Vite
|
||||
|
||||
Add the following to your `vite.config.js` file:
|
||||
|
||||
```js
|
||||
import { plugins } from 'omorphia/config/vite.js'
|
||||
import { Generator } from 'omorphia/plugins'
|
||||
import precompileIntl from 'svelte-intl-precompile/sveltekit-plugin'
|
||||
|
||||
/** @type {import('vite').UserConfig} */
|
||||
const config = {
|
||||
plugins: [
|
||||
...plugins,
|
||||
precompileIntl('locales'),
|
||||
Generator({
|
||||
gameVersions: true,
|
||||
openapi: true,
|
||||
// Add more if needed
|
||||
}),
|
||||
],
|
||||
|
||||
server: {
|
||||
fs: {
|
||||
allow: ['generated'],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
```
|
||||
|
||||
## `6.` Configure PostCSS
|
||||
|
||||
Create a `postcss.config.cjs` file in the root of your project.
|
||||
|
||||
Add the following line to that file:
|
||||
|
||||
```js
|
||||
module.exports = require('omorphia/config/postcss.cjs')
|
||||
```
|
||||
|
||||
## `7.` Setup styles
|
||||
|
||||
Import styles in `src/routes/__layout.svelte`:
|
||||
|
||||
```html
|
||||
<script lang="ts">
|
||||
import 'omorphia/styles.postcss'
|
||||
</script>
|
||||
```
|
||||
|
||||
Add the `base` class and a theme to the `<body>` tag in `src/app.html`:
|
||||
|
||||
```html
|
||||
<body class="base theme-light">
|
||||
%sveltekit.body%
|
||||
</body>
|
||||
```
|
||||
|
||||
## `8.` Setup fonts
|
||||
|
||||
Copy the the `fonts/` folder from [Omorphia's repository](https://github.com/modrinth/omorphia/blob/main/docs/static/assets/fonts) and place them in the `static/` folder at the root of your project.
|
||||
|
||||
Add the following preload tags to your head in `app.html` to speed up font loading:
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
```html
|
||||
<head>
|
||||
<link rel="preload" href="/fonts/InterRegular.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/fonts/InterBold.woff2" as="font" type="font/woff2" crossorigin>
|
||||
<link rel="preload" href="/fonts/InterSemiBold.woff2" as="font" type="font/woff2" crossorigin>
|
||||
</head>
|
||||
```
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
## `9.` Using Omorphia
|
||||
|
||||
### Developing
|
||||
|
||||
Start the development server with:
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
> To get Svelte language support in your code editor, [use this list of extensions.](https://sveltesociety.dev/tools#editor-support)
|
||||
|
||||
### Components
|
||||
|
||||
Use a component by importing from `omorphia`. For example, use the [Button component](/components/Button) like so:
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Button } from 'omorphia'
|
||||
</script>
|
||||
|
||||
<Button color="primary">I'm a button!</Button>
|
||||
```
|
||||
|
||||
### Utils
|
||||
|
||||
Use a utility by importing from `omorphia/utils`.
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { ago } from 'omorphia/utils'
|
||||
</script>
|
||||
|
||||
{ago(Date.now() - 100000)}
|
||||
```
|
||||
|
||||
### Using icons and styles
|
||||
|
||||
Follow the guides on the sidebar to learn how to use [icons](/usage/icons) and general concepts.
|
||||
@@ -1,32 +0,0 @@
|
||||
---
|
||||
title: Writing CSS
|
||||
---
|
||||
|
||||
## Conventions
|
||||
|
||||
### Avoid inconsistent CSS units
|
||||
|
||||
Prefer using `rem` units, using only whole and half units, eg. `2rem` or `1.5rem`. If you need a specific pixel (`px`) measurement, use `px` and add comment explaining why you used it. The one exception is that `0.25rem` is allowed.
|
||||
|
||||
> Using `rem` units lets you change the scale of the UI by simply changing the body font size.
|
||||
|
||||
### Always use `HSL` colors
|
||||
|
||||
### All colors should be theme variables
|
||||
|
||||
## Abilities
|
||||
|
||||
Omorphia leverages PostCSS to allow you to write in future-standards-compliant CSS. Browse [the CSSWG drafts](https://cssdb.org/) to see what is possible (not including stage 0).
|
||||
|
||||
Notable features:
|
||||
|
||||
- [Nesting](https://www.w3.org/TR/css-nesting-1/#example-aecb8796)
|
||||
- [Gap](https://developer.mozilla.org/en-US/docs/Web/CSS/gap)
|
||||
- [`clamp` function](<https://developer.mozilla.org/en-US/docs/Web/CSS/clamp()>)
|
||||
- [Custom Media Queries](https://www.w3.org/TR/mediaqueries-5/#example-532b0adb)
|
||||
- [`:has()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:has)
|
||||
- [place-content](https://developer.mozilla.org/en-US/docs/Web/CSS/place-content)
|
||||
|
||||
## Styles
|
||||
|
||||
Conform to [BEM styling](http://getbem.com/introduction/) wherever possible. When working in components, you may want to leverage [Svelte's conditional class shorthand](https://svelte.dev/tutorial/class-shorthand) instead of BEM's modifier class name format.
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
title: Generator plugin
|
||||
---
|
||||
|
||||
The generator plugin creates static files from API responses to increase performance and perform tasks that would not be possible on the client. It regenerates files every 7 days, or when the plugin settings change.
|
||||
|
||||
### Current options
|
||||
|
||||
- `projectColors` (false) generates colors for every project
|
||||
- `tags` (false) copies & parses tags from API
|
||||
- `gameVersions` copies game versions from API
|
||||
- `landingPage` gets icon urls for top 100 mods
|
||||
|
||||
> All options are disabled by default
|
||||
|
||||
## Configuration
|
||||
|
||||
```js
|
||||
import Generator from 'omorphia/plugins/generator'
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
kit: {
|
||||
vite: {
|
||||
plugins: [
|
||||
Generator({
|
||||
projectColors: true,
|
||||
tags: true,
|
||||
gameVersions: true,
|
||||
landingPage: true,
|
||||
}),
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
```
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
title: Icons
|
||||
---
|
||||
|
||||
## Choosing icons
|
||||
|
||||
The follwing icon packs are included with omorphia:
|
||||
|
||||
`heroicons-outline` `lucide` `fa-regular` `heroicons-solid` `carbon` `simple-icons`
|
||||
|
||||
Aim to find icons from `heroicons-outline` first, and then from the following packs if you can't find what you are looking for. [Browse icons...](https://icones.js.org/collection/heroicons-outline)
|
||||
|
||||
## Using icons
|
||||
|
||||
Import an icon in the `<script>` tag of your component.
|
||||
|
||||
Then use the icon as if it were a Svelte component:
|
||||
|
||||
> You can style the icon with the `.icon` class. Note, you will have to use the `:global(.icon)` selector in Svelte components.
|
||||
|
||||
```svelte example
|
||||
<script lang="ts">
|
||||
import IconHeart from 'virtual:icons/heroicons-outline/heart'
|
||||
</script>
|
||||
|
||||
<p>That's lovely! <IconHeart /></p>
|
||||
```
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
title: Using illustrations
|
||||
---
|
||||
|
||||
Find an illustration from [unDraw](https://undraw.co/illustrations) and download it as an SVG.
|
||||
|
||||
Put the illustration in the `src/assets/images/illustrations` folder. Rename it to `undraw_` + the illustration slug.
|
||||
|
||||
Replace colors in the SVG with CSS variables such as `var(--color-brand)` and `var(--color-raised)`. For colors that are the same as the font color, use `currentColor`.
|
||||
|
||||
Add the `.illustration` class to the SVG
|
||||
|
||||
Import the SVG in the `<script>` of your svelte file, and treat the illustration as a Svelte component:
|
||||
|
||||
```svelte
|
||||
<script>
|
||||
import NoData from '$assets/images/illustrations/undraw_no_data.svg'
|
||||
</script>
|
||||
|
||||
<NoData />
|
||||
```
|
||||
@@ -1,116 +0,0 @@
|
||||
---
|
||||
title: Built-in utilities
|
||||
---
|
||||
|
||||
## API requests
|
||||
|
||||
Use the `send` function to make API requests.
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { send } from 'omorphia/utils'
|
||||
|
||||
const project = send<'getProject'>('GET', 'project/sodium')
|
||||
</script>
|
||||
|
||||
{#await project}
|
||||
fetching...
|
||||
{:then project}
|
||||
{project.downloads} downloads
|
||||
{/await}
|
||||
```
|
||||
|
||||
## Markdown
|
||||
|
||||
Use the markdown utilities to parse markdown text into HTML. Both markdown parsers have HTML sanitization built-in.
|
||||
|
||||
### Body parser
|
||||
|
||||
The `markdown` parser is designed for bodies of markdown text and supports images, tables, lists, and youtube `<iframe>`s.
|
||||
|
||||
> Use the `.markdown` class on the element containing your parsed markdown.
|
||||
|
||||
````svelte example
|
||||
<script lang="ts">
|
||||
import { markdown } from 'omorphia/utils'
|
||||
|
||||
const source =
|
||||
'## Example markdown \n\
|
||||
This is **some** *text*! \n\
|
||||
`console.log("test")` \n\
|
||||
#### An image \n\
|
||||
'
|
||||
</script>
|
||||
|
||||
<div class="card markdown">
|
||||
{@html markdown(source)}
|
||||
{@html markdown(
|
||||
` | Syntax | Description |
|
||||
| ----------- | ----------- |
|
||||
| Header | Title |
|
||||
| Paragraph | Text |`
|
||||
)}
|
||||
{@html markdown('```js\nconsole.log("test")\n```')}
|
||||
</div>
|
||||
````
|
||||
|
||||
### Inline parser
|
||||
|
||||
The `markdownInline` parser is perfect for translations and short bios. It doesn't allow complex elements such as images or tables.
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { markdownInline } from 'omorphia/utils'
|
||||
|
||||
const source = 'This is some **bolded** and *italicized* text.'
|
||||
</script>
|
||||
|
||||
<p>{@html markdownInline(source)}</p>
|
||||
```
|
||||
|
||||
## Human readable "ago" times
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { ago } from 'omorphia/utils'
|
||||
</script>
|
||||
|
||||
<p>Something happened {ago(Date.now())}.</p>
|
||||
<p>Something happened {ago(new Date(Date.now() - 1000 * 60 * 60 * 2))}.</p>
|
||||
<p>Something happened {ago(new Date(Date.now() - 1000 * 60 * 60 * 24 * 7))}.</p>
|
||||
<p>Something happened {ago(new Date(Date.now() - 1000 * 60 * 60 * 24 * 7 * 5))}.</p>
|
||||
```
|
||||
|
||||
## Permissions
|
||||
|
||||
The `Permissions` class provides an easy way to manage user permissions.
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { Permissions } from 'omorphia/utils'
|
||||
|
||||
const permissions = new Permissions(128) // Can be integer or 'ALL'
|
||||
</script>
|
||||
|
||||
<p>
|
||||
<input type="checkbox" bind:checked={permissions.uploadVersions} id="ex-1" />
|
||||
<label for="ex-1">Can edit versions</label><br />
|
||||
<input type="checkbox" bind:checked={permissions.deleteProject} id="ex-2" />
|
||||
<label for="ex-2">Can delete project</label><br /><br />
|
||||
|
||||
Integer: {permissions.toInteger()}<br />
|
||||
Can access settings page: {permissions.settingsPage}
|
||||
</p>
|
||||
```
|
||||
|
||||
## Versions
|
||||
|
||||
The `formatVersions` function provides an easy way to parse a project's versions into a readable string.
|
||||
|
||||
```svelte example raised
|
||||
<script lang="ts">
|
||||
import { formatVersions } from 'omorphia/utils'
|
||||
</script>
|
||||
|
||||
<p>{formatVersions(['1.18', '1.18.1', '1.18.2', '1.17.1'])}</p>
|
||||
```
|
||||
BIN
docs/static/fonts/InterBold.woff2
vendored
BIN
docs/static/fonts/InterBold.woff2
vendored
Binary file not shown.
BIN
docs/static/fonts/InterRegular.woff2
vendored
BIN
docs/static/fonts/InterRegular.woff2
vendored
Binary file not shown.
BIN
docs/static/fonts/InterSemiBold.woff2
vendored
BIN
docs/static/fonts/InterSemiBold.woff2
vendored
Binary file not shown.
BIN
docs/static/omorphia.png
vendored
BIN
docs/static/omorphia.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
@@ -1,392 +0,0 @@
|
||||
*:not(.example__preview) * {
|
||||
:where(a):not(.link) {
|
||||
text-decoration: none;
|
||||
|
||||
&.absent {
|
||||
color: #cc0000;
|
||||
}
|
||||
|
||||
&.anchor {
|
||||
display: block;
|
||||
padding-left: 30px;
|
||||
margin-left: -30px;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:where(h1, h2, h3, h4, h5, h6) {
|
||||
margin: 30px 0 10px;
|
||||
padding: 0;
|
||||
font-weight: bold;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
cursor: text;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&:where(h2:first-child, h1:first-child, h1:first-child
|
||||
+ h2, h3:first-child, h4:first-child, h5:first-child, h6:first-child) {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&:where(h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover
|
||||
a.anchor, h6:hover a.anchor) {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:where(h1 tt, h1 code) {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
&:where(h2 tt, h2 code) {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
&:where(h3 tt, h3 code) {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
&:where(h4 tt, h4 code) {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
&:where(h5 tt, h5 code) {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
&:where(h6 tt, h6 code) {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
&:where(h1) {
|
||||
font-size: 40px;
|
||||
color: black;
|
||||
font-weight: 600;
|
||||
|
||||
@media (--md) {
|
||||
font-size: 54px;
|
||||
}
|
||||
}
|
||||
|
||||
&:where(h2) {
|
||||
font-size: 24px;
|
||||
/*border-bottom: 1px solid #cccccc;*/
|
||||
color: black;
|
||||
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
&:where(h3) {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
&:where(h4) {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&:where(h5) {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&:where(h6) {
|
||||
color: #777777;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&:where(p, blockquote, ul, ol, dl, li, table, pre) {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
&:where(hr) {
|
||||
border: 0 none;
|
||||
color: #cccccc;
|
||||
height: 4px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&:where(body > h2:first-child) {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&:where(body > h1:first-child) {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&:where(body > h1:first-child + h2) {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&:where(body > h3:first-child, body > h4:first-child, body > h5:first-child, body
|
||||
> h6:first-child) {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&:where(a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child
|
||||
h5, a:first-child h6) {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
&:where(h1 p, h2 p, h3 p, h4 p, h5 p, h6 p) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:where(li p.first) {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&:where(ul, ol) {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
&:where(ul :first-child, ol :first-child) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:where(ul :last-child, ol :last-child) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&:where(dl) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&:where(dl dt) {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
padding: 0;
|
||||
margin: 15px 0 5px;
|
||||
}
|
||||
|
||||
&:where(dl dt:first-child) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&:where(dl dt > :first-child) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:where(dl dt > :last-child) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&:where(dl dd) {
|
||||
margin: 0 0 15px;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
&:where(dl dd > :first-child) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:where(dl dd > :last-child) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&:where(blockquote) {
|
||||
border-left: 4px solid #dddddd;
|
||||
padding: 0 15px;
|
||||
color: #777777;
|
||||
}
|
||||
|
||||
&:where(blockquote > :first-child) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:where(blockquote > :last-child) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&:where(table) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&:where(table tr) {
|
||||
border-top: 1px solid #cccccc;
|
||||
background-color: white;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&:where(table tr:nth-child(2n)) {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
&:where(table tr th) {
|
||||
font-weight: bold;
|
||||
border: 1px solid #cccccc;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
|
||||
&:where(table tr td) {
|
||||
border: 1px solid #cccccc;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
|
||||
&:where(table tr th :first-child, table tr td :first-child) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
&:where(table tr th :last-child, table tr td :last-child) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&:where(img) {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
&:where(span.frame) {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&:where(span.frame > span) {
|
||||
border: 1px solid #dddddd;
|
||||
display: block;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
margin: 13px 0 0;
|
||||
padding: 7px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
&:where(span.frame span img) {
|
||||
display: block;
|
||||
float: left;
|
||||
}
|
||||
|
||||
&:where(span.frame span span) {
|
||||
clear: both;
|
||||
color: #333333;
|
||||
display: block;
|
||||
padding: 5px 0 0;
|
||||
}
|
||||
|
||||
&:where(span.align-center) {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
&:where(span.align-center > span) {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
margin: 13px auto 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&:where(span.align-center span img) {
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&:where(span.align-right) {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
&:where(span.align-right > span) {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
margin: 13px 0 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&:where(span.align-right span img) {
|
||||
margin: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&:where(span.float-left) {
|
||||
display: block;
|
||||
margin-right: 13px;
|
||||
overflow: hidden;
|
||||
float: left;
|
||||
}
|
||||
|
||||
&:where(span.float-left span) {
|
||||
margin: 13px 0 0;
|
||||
}
|
||||
|
||||
&:where(span.float-right) {
|
||||
display: block;
|
||||
margin-left: 13px;
|
||||
overflow: hidden;
|
||||
float: right;
|
||||
}
|
||||
|
||||
&:where(span.float-right > span) {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
margin: 13px auto 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&:where(code, tt) {
|
||||
margin: 0 2px;
|
||||
padding: 0 5px;
|
||||
white-space: nowrap;
|
||||
border: 1px solid #eaeaea;
|
||||
background-color: #f8f8f8;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
&:where(pre code) {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
white-space: pre;
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&:where(pre) {
|
||||
background-color: #f8f8f8;
|
||||
font-size: 13px;
|
||||
line-height: 19px;
|
||||
overflow: auto;
|
||||
padding: 6px 10px;
|
||||
border-radius: var(--rounded-sm) !important;
|
||||
}
|
||||
|
||||
&:where(pre code, pre tt) {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
&:where(h2) {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&:where(blockquote) {
|
||||
border-left: 4px solid var(--accent-color);
|
||||
padding: 15px 15px;
|
||||
color: unset;
|
||||
background-color: var(--accent-color-transparent);
|
||||
}
|
||||
|
||||
&:where(a):not(.link) {
|
||||
color: var(--accent-color);
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
&:where(p) {
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
@@ -1,443 +0,0 @@
|
||||
/**
|
||||
* One Dark theme for prism.js
|
||||
* Based on Atom's One Dark theme: https://github.com/atom/atom/tree/master/packages/one-dark-syntax
|
||||
*/
|
||||
|
||||
/**
|
||||
* One Dark colours (accurate as of commit 8ae45ca on 6 Sep 2018)
|
||||
* From colors.less
|
||||
* --mono-1: hsl(220, 14%, 71%);
|
||||
* --mono-2: hsl(220, 9%, 55%);
|
||||
* --mono-3: hsl(220, 10%, 40%);
|
||||
* --hue-1: hsl(187, 47%, 55%);
|
||||
* --hue-2: hsl(207, 82%, 66%);
|
||||
* --hue-3: hsl(286, 60%, 67%);
|
||||
* --hue-4: hsl(95, 38%, 62%);
|
||||
* --hue-5: hsl(355, 65%, 65%);
|
||||
* --hue-5-2: hsl(5, 48%, 51%);
|
||||
* --hue-6: hsl(29, 54%, 61%);
|
||||
* --hue-6-2: hsl(39, 67%, 69%);
|
||||
* --syntax-fg: hsl(220, 14%, 71%);
|
||||
* --syntax-bg: hsl(220, 13%, 18%);
|
||||
* --syntax-gutter: hsl(220, 14%, 45%);
|
||||
* --syntax-guide: hsla(220, 14%, 71%, 0.15);
|
||||
* --syntax-accent: hsl(220, 100%, 66%);
|
||||
* From syntax-variables.less
|
||||
* --syntax-selection-color: hsl(220, 13%, 28%);
|
||||
* --syntax-gutter-background-color-selected: hsl(220, 13%, 26%);
|
||||
* --syntax-cursor-line: hsla(220, 100%, 80%, 0.04);
|
||||
*/
|
||||
|
||||
code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
background: hsl(220, 13%, 18%);
|
||||
color: hsl(220, 14%, 71%);
|
||||
font-family: 'Fira Code', 'Fira Mono', Menlo, Consolas, 'DejaVu Sans Mono', monospace;
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
line-height: 1.5;
|
||||
-moz-tab-size: 2;
|
||||
-o-tab-size: 2;
|
||||
tab-size: 2;
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
/* Selection */
|
||||
code[class*='language-']::-moz-selection,
|
||||
code[class*='language-'] *::-moz-selection,
|
||||
pre[class*='language-'] *::-moz-selection {
|
||||
background: hsl(220, 13%, 28%);
|
||||
color: inherit;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
code[class*='language-']::selection,
|
||||
code[class*='language-'] *::selection,
|
||||
pre[class*='language-'] *::selection {
|
||||
background: hsl(220, 13%, 28%);
|
||||
color: inherit;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*='language-'] {
|
||||
padding: 16px;
|
||||
margin: 0.5em 0;
|
||||
overflow: auto;
|
||||
border-radius: var(--rounded);
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*='language-'] {
|
||||
padding: 0.2em 0.3em;
|
||||
border-radius: 0.3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
/* Print */
|
||||
@media print {
|
||||
code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.cdata {
|
||||
color: hsl(220, 10%, 40%);
|
||||
}
|
||||
|
||||
.token.doctype,
|
||||
.token.punctuation,
|
||||
.token.entity {
|
||||
color: hsl(220, 14%, 71%);
|
||||
}
|
||||
|
||||
.token.attr-name,
|
||||
.token.class-name,
|
||||
.token.boolean,
|
||||
.token.constant,
|
||||
.token.number,
|
||||
.token.atrule {
|
||||
color: hsl(29, 54%, 61%);
|
||||
}
|
||||
|
||||
.token.keyword {
|
||||
color: hsl(286, 60%, 67%);
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.symbol,
|
||||
.token.deleted,
|
||||
.token.important {
|
||||
color: hsl(355, 65%, 65%) !important;
|
||||
display: unset;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted,
|
||||
.token.regex,
|
||||
.token.attr-value,
|
||||
.token.attr-value > .token.punctuation {
|
||||
color: hsl(95, 38%, 62%);
|
||||
}
|
||||
|
||||
.token.variable,
|
||||
.token.operator,
|
||||
.token.function {
|
||||
color: hsl(207, 82%, 66%);
|
||||
}
|
||||
|
||||
.token.url {
|
||||
color: hsl(187, 47%, 55%);
|
||||
}
|
||||
|
||||
/* HTML overrides */
|
||||
.token.attr-value > .token.punctuation.attr-equals,
|
||||
.token.special-attr > .token.attr-value > .token.value.css {
|
||||
color: hsl(220, 14%, 71%);
|
||||
}
|
||||
|
||||
/* CSS overrides */
|
||||
.language-css .token.selector {
|
||||
color: hsl(355, 65%, 65%);
|
||||
}
|
||||
|
||||
.language-css .token.property {
|
||||
color: hsl(220, 14%, 71%);
|
||||
}
|
||||
|
||||
.language-css .token.function,
|
||||
.language-css .token.url > .token.function {
|
||||
color: hsl(187, 47%, 55%);
|
||||
}
|
||||
|
||||
.language-css .token.url > .token.string.url {
|
||||
color: hsl(95, 38%, 62%);
|
||||
}
|
||||
|
||||
.language-css .token.important,
|
||||
.language-css .token.atrule .token.rule {
|
||||
color: hsl(286, 60%, 67%);
|
||||
}
|
||||
|
||||
/* JS overrides */
|
||||
.language-javascript .token.operator {
|
||||
color: hsl(286, 60%, 67%);
|
||||
}
|
||||
|
||||
.language-javascript
|
||||
.token.template-string
|
||||
> .token.interpolation
|
||||
> .token.interpolation-punctuation.punctuation {
|
||||
color: hsl(5, 48%, 51%);
|
||||
}
|
||||
|
||||
/* JSON overrides */
|
||||
.language-json .token.operator {
|
||||
color: hsl(220, 14%, 71%);
|
||||
}
|
||||
|
||||
.language-json .token.null.keyword {
|
||||
color: hsl(29, 54%, 61%);
|
||||
}
|
||||
|
||||
/* MD overrides */
|
||||
.language-markdown .token.url,
|
||||
.language-markdown .token.url > .token.operator,
|
||||
.language-markdown .token.url-reference.url > .token.string {
|
||||
color: hsl(220, 14%, 71%);
|
||||
}
|
||||
|
||||
.language-markdown .token.url > .token.content {
|
||||
color: hsl(207, 82%, 66%);
|
||||
}
|
||||
|
||||
.language-markdown .token.url > .token.url,
|
||||
.language-markdown .token.url-reference.url {
|
||||
color: hsl(187, 47%, 55%);
|
||||
}
|
||||
|
||||
.language-markdown .token.blockquote.punctuation,
|
||||
.language-markdown .token.hr.punctuation {
|
||||
color: hsl(220, 10%, 40%);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.language-markdown .token.code-snippet {
|
||||
color: hsl(95, 38%, 62%);
|
||||
}
|
||||
|
||||
.language-markdown .token.bold .token.content {
|
||||
color: hsl(29, 54%, 61%);
|
||||
}
|
||||
|
||||
.language-markdown .token.italic .token.content {
|
||||
color: hsl(286, 60%, 67%);
|
||||
}
|
||||
|
||||
.language-markdown .token.strike .token.content,
|
||||
.language-markdown .token.strike .token.punctuation,
|
||||
.language-markdown .token.list.punctuation,
|
||||
.language-markdown .token.title.important > .token.punctuation {
|
||||
color: hsl(355, 65%, 65%);
|
||||
}
|
||||
|
||||
/* General */
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.token.namespace {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* Plugin overrides */
|
||||
/* Selectors should have higher specificity than those in the plugins' default stylesheets */
|
||||
|
||||
/* Show Invisibles plugin overrides */
|
||||
.token.token.tab:not(:empty):before,
|
||||
.token.token.cr:before,
|
||||
.token.token.lf:before,
|
||||
.token.token.space:before {
|
||||
color: hsla(220, 14%, 71%, 0.15);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/* Toolbar plugin overrides */
|
||||
/* Space out all buttons and move them away from the right edge of the code block */
|
||||
div.code-toolbar > .toolbar.toolbar > .toolbar-item {
|
||||
margin-right: 0.4em;
|
||||
}
|
||||
|
||||
/* Styling the buttons */
|
||||
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button,
|
||||
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a,
|
||||
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span {
|
||||
background: hsl(220, 13%, 26%);
|
||||
color: hsl(220, 9%, 55%);
|
||||
padding: 0.1em 0.4em;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover,
|
||||
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:focus,
|
||||
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover,
|
||||
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus,
|
||||
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover,
|
||||
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus {
|
||||
background: hsl(220, 13%, 28%);
|
||||
color: hsl(220, 14%, 71%);
|
||||
}
|
||||
|
||||
/* Line Highlight plugin overrides */
|
||||
/* The highlighted line itself */
|
||||
.line-highlight.line-highlight {
|
||||
background: hsla(220, 100%, 80%, 0.04);
|
||||
}
|
||||
|
||||
/* Default line numbers in Line Highlight plugin */
|
||||
.line-highlight.line-highlight:before,
|
||||
.line-highlight.line-highlight[data-end]:after {
|
||||
background: hsl(220, 13%, 26%);
|
||||
color: hsl(220, 14%, 71%);
|
||||
padding: 0.1em 0.6em;
|
||||
border-radius: 0.3em;
|
||||
box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.2); /* same as Toolbar plugin default */
|
||||
}
|
||||
|
||||
/* Hovering over a linkable line number (in the gutter area) */
|
||||
/* Requires Line Numbers plugin as well */
|
||||
pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before {
|
||||
background-color: hsla(220, 100%, 80%, 0.04);
|
||||
}
|
||||
|
||||
/* Line Numbers and Command Line plugins overrides */
|
||||
/* Line separating gutter from coding area */
|
||||
.line-numbers.line-numbers .line-numbers-rows,
|
||||
.command-line .command-line-prompt {
|
||||
border-right-color: hsla(220, 14%, 71%, 0.15);
|
||||
}
|
||||
|
||||
/* Stuff in the gutter */
|
||||
.line-numbers .line-numbers-rows > span:before,
|
||||
.command-line .command-line-prompt > span:before {
|
||||
color: hsl(220, 14%, 45%);
|
||||
}
|
||||
|
||||
/* Match Braces plugin overrides */
|
||||
/* Note: Outline colour is inherited from the braces */
|
||||
.rainbow-braces .token.token.punctuation.brace-level-1,
|
||||
.rainbow-braces .token.token.punctuation.brace-level-5,
|
||||
.rainbow-braces .token.token.punctuation.brace-level-9 {
|
||||
color: hsl(355, 65%, 65%);
|
||||
}
|
||||
|
||||
.rainbow-braces .token.token.punctuation.brace-level-2,
|
||||
.rainbow-braces .token.token.punctuation.brace-level-6,
|
||||
.rainbow-braces .token.token.punctuation.brace-level-10 {
|
||||
color: hsl(95, 38%, 62%);
|
||||
}
|
||||
|
||||
.rainbow-braces .token.token.punctuation.brace-level-3,
|
||||
.rainbow-braces .token.token.punctuation.brace-level-7,
|
||||
.rainbow-braces .token.token.punctuation.brace-level-11 {
|
||||
color: hsl(207, 82%, 66%);
|
||||
}
|
||||
|
||||
.rainbow-braces .token.token.punctuation.brace-level-4,
|
||||
.rainbow-braces .token.token.punctuation.brace-level-8,
|
||||
.rainbow-braces .token.token.punctuation.brace-level-12 {
|
||||
color: hsl(286, 60%, 67%);
|
||||
}
|
||||
|
||||
/* Diff Highlight plugin overrides */
|
||||
/* Taken from https://github.com/atom/github/blob/master/styles/variables.less */
|
||||
pre.diff-highlight > code .token.token.deleted:not(.prefix),
|
||||
pre > code.diff-highlight .token.token.deleted:not(.prefix) {
|
||||
background-color: hsla(353, 100%, 66%, 0.15);
|
||||
}
|
||||
|
||||
pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection,
|
||||
pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection,
|
||||
pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection,
|
||||
pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection {
|
||||
background-color: hsla(353, 95%, 66%, 0.25);
|
||||
}
|
||||
|
||||
pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection,
|
||||
pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection,
|
||||
pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection,
|
||||
pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection {
|
||||
background-color: hsla(353, 95%, 66%, 0.25);
|
||||
}
|
||||
|
||||
pre.diff-highlight > code .token.token.inserted:not(.prefix),
|
||||
pre > code.diff-highlight .token.token.inserted:not(.prefix) {
|
||||
background-color: hsla(137, 100%, 55%, 0.15);
|
||||
}
|
||||
|
||||
pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection,
|
||||
pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection,
|
||||
pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection,
|
||||
pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection {
|
||||
background-color: hsla(135, 73%, 55%, 0.25);
|
||||
}
|
||||
|
||||
pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection,
|
||||
pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection,
|
||||
pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection,
|
||||
pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection {
|
||||
background-color: hsla(135, 73%, 55%, 0.25);
|
||||
}
|
||||
|
||||
/* Previewers plugin overrides */
|
||||
/* Based on https://github.com/atom-community/atom-ide-datatip/blob/master/styles/atom-ide-datatips.less and https://github.com/atom/atom/blob/master/packages/one-dark-ui */
|
||||
/* Border around popup */
|
||||
.prism-previewer.prism-previewer:before,
|
||||
.prism-previewer-gradient.prism-previewer-gradient div {
|
||||
border-color: hsl(224, 13%, 17%);
|
||||
}
|
||||
|
||||
/* Angle and time should remain as circles and are hence not included */
|
||||
.prism-previewer-color.prism-previewer-color:before,
|
||||
.prism-previewer-gradient.prism-previewer-gradient div,
|
||||
.prism-previewer-easing.prism-previewer-easing:before {
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
/* Triangles pointing to the code */
|
||||
.prism-previewer.prism-previewer:after {
|
||||
border-top-color: hsl(224, 13%, 17%);
|
||||
}
|
||||
|
||||
.prism-previewer-flipped.prism-previewer-flipped.after {
|
||||
border-bottom-color: hsl(224, 13%, 17%);
|
||||
}
|
||||
|
||||
/* Background colour within the popup */
|
||||
.prism-previewer-angle.prism-previewer-angle:before,
|
||||
.prism-previewer-time.prism-previewer-time:before,
|
||||
.prism-previewer-easing.prism-previewer-easing {
|
||||
background: hsl(219, 13%, 22%);
|
||||
}
|
||||
|
||||
/* For angle, this is the positive area (eg. 90deg will display one quadrant in this colour) */
|
||||
/* For time, this is the alternate colour */
|
||||
.prism-previewer-angle.prism-previewer-angle circle,
|
||||
.prism-previewer-time.prism-previewer-time circle {
|
||||
stroke: hsl(220, 14%, 71%);
|
||||
stroke-opacity: 1;
|
||||
}
|
||||
|
||||
/* Stroke colours of the handle, direction point, and vector itself */
|
||||
.prism-previewer-easing.prism-previewer-easing circle,
|
||||
.prism-previewer-easing.prism-previewer-easing path,
|
||||
.prism-previewer-easing.prism-previewer-easing line {
|
||||
stroke: hsl(220, 14%, 71%);
|
||||
}
|
||||
|
||||
/* Fill colour of the handle */
|
||||
.prism-previewer-easing.prism-previewer-easing circle {
|
||||
fill: transparent;
|
||||
}
|
||||
Reference in New Issue
Block a user