mirror of
https://github.com/wukko/cobalt.git
synced 2024-11-15 12:50:01 +00:00
web: omnibox base with meowbalt
This commit is contained in:
parent
7cab37fc30
commit
e6ffa4864c
11 changed files with 286 additions and 16 deletions
6
web/package-lock.json
generated
6
web/package-lock.json
generated
|
@ -9,6 +9,7 @@
|
|||
"version": "0.0.1",
|
||||
"license": "CC-BY-NC-SA-4.0",
|
||||
"dependencies": {
|
||||
"@fontsource-variable/noto-sans-mono": "^5.0.20",
|
||||
"@fontsource/ibm-plex-mono": "^5.0.13",
|
||||
"@tabler/icons-svelte": "^3.6.0"
|
||||
},
|
||||
|
@ -403,6 +404,11 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@fontsource-variable/noto-sans-mono": {
|
||||
"version": "5.0.20",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans-mono/-/noto-sans-mono-5.0.20.tgz",
|
||||
"integrity": "sha512-Mik/wbKjiir7t+KBaDZnPZ5GjDnPOXpMF7obmFeyRa528ZsrKcFiSn4ZvArrn3sJMCp/k23wakOcXOWlGNc9cw=="
|
||||
},
|
||||
"node_modules/@fontsource/ibm-plex-mono": {
|
||||
"version": "5.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/ibm-plex-mono/-/ibm-plex-mono-5.0.13.tgz",
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
"vite": "^5.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource-variable/noto-sans-mono": "^5.0.20",
|
||||
"@fontsource/ibm-plex-mono": "^5.0.13",
|
||||
"@tabler/icons-svelte": "^3.6.0"
|
||||
}
|
||||
|
|
111
web/src/components/save/Omnibox.svelte
Normal file
111
web/src/components/save/Omnibox.svelte
Normal file
|
@ -0,0 +1,111 @@
|
|||
<script lang="ts">
|
||||
import { IconLink } from '@tabler/icons-svelte';
|
||||
|
||||
import DownloadButton from './buttons/DownloadButton.svelte';
|
||||
import ClearButton from './buttons/ClearButton.svelte';
|
||||
|
||||
let link: string = "";
|
||||
let isFocused = false;
|
||||
|
||||
const validLink = (link: string) => {
|
||||
try {
|
||||
return /^https:/i.test(new URL(link).protocol);
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="omnibox">
|
||||
<div id="input-container" class:focused={isFocused} class:downloadable={validLink(link)}>
|
||||
<IconLink id="input-link-icon" color="var(--gray)" size="18px" />
|
||||
|
||||
<input
|
||||
id="link-area"
|
||||
bind:value={link}
|
||||
|
||||
on:input={() => isFocused = true}
|
||||
on:focus={() => isFocused = true}
|
||||
on:blur={() => isFocused = false}
|
||||
|
||||
spellcheck="false"
|
||||
autocomplete="off"
|
||||
autocapitalize="off"
|
||||
maxlength="256"
|
||||
|
||||
placeholder="paste the link here"
|
||||
aria-label="link input area"
|
||||
>
|
||||
|
||||
{#if link.length > 0}
|
||||
<ClearButton click={() => link = ""} />
|
||||
{/if}
|
||||
{#if validLink(link)}
|
||||
<DownloadButton />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#omnibox {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 640px;
|
||||
width: 100%;
|
||||
gap: var(--padding);
|
||||
}
|
||||
|
||||
#input-container {
|
||||
display: flex;
|
||||
box-shadow: 0 0 0 1.5px var(--gray) inset;
|
||||
border-radius: 11px;
|
||||
padding: 0 12px;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 14px;
|
||||
flex: 1
|
||||
}
|
||||
|
||||
#input-container.downloadable {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
#input-container.focused {
|
||||
box-shadow: 0 0 0 1.5px var(--secondary) inset;
|
||||
outline: var(--secondary) 0.5px solid;
|
||||
}
|
||||
|
||||
#input-container.focused :global(#input-link-icon) {
|
||||
stroke: var(--secondary);
|
||||
}
|
||||
#input-container.downloadable :global(#input-link-icon) {
|
||||
stroke: var(--secondary);
|
||||
}
|
||||
|
||||
#link-area {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 12px 0;
|
||||
height: 18px;
|
||||
|
||||
align-items: center;
|
||||
|
||||
border: none;
|
||||
outline: none;
|
||||
background-color: transparent;
|
||||
color: var(--secondary);
|
||||
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
flex: 1;
|
||||
|
||||
font-weight: 500;
|
||||
|
||||
/* workaround for safari */
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
#link-area::placeholder {
|
||||
color: var(--gray)
|
||||
}
|
||||
</style>
|
15
web/src/components/save/buttons/ClearButton.svelte
Normal file
15
web/src/components/save/buttons/ClearButton.svelte
Normal file
|
@ -0,0 +1,15 @@
|
|||
<script>
|
||||
export let click;
|
||||
import IconX from '@tabler/icons-svelte/IconX.svelte';
|
||||
</script>
|
||||
|
||||
<button id="clear-button" on:click={click}>
|
||||
<IconX color="var(--secondary)" size="16px"/>
|
||||
</button>
|
||||
|
||||
<style>
|
||||
#clear-button {
|
||||
padding: 3px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
</style>
|
54
web/src/components/save/buttons/DownloadButton.svelte
Normal file
54
web/src/components/save/buttons/DownloadButton.svelte
Normal file
|
@ -0,0 +1,54 @@
|
|||
<script>
|
||||
import '@fontsource-variable/noto-sans-mono';
|
||||
</script>
|
||||
|
||||
<button id="download-button">
|
||||
<span id="download-state">>></span>
|
||||
</button>
|
||||
|
||||
<style>
|
||||
#download-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
height: 100%;
|
||||
min-width: 48px;
|
||||
|
||||
border-radius: 0;
|
||||
padding: 0 12px;
|
||||
background: none;
|
||||
|
||||
border-left: 1px var(--gray) solid;
|
||||
border-top-right-radius: 11px;
|
||||
border-bottom-right-radius: 11px;
|
||||
}
|
||||
|
||||
#download-state {
|
||||
font-size: 24px;
|
||||
font-family: "Noto Sans Mono Variable", "Noto Sans Mono", "IBM Plex Mono", monospace;
|
||||
font-weight: 400;
|
||||
|
||||
text-align: center;
|
||||
text-indent: -5px;
|
||||
letter-spacing: -0.22em;
|
||||
|
||||
margin-bottom: 0.1rem;
|
||||
}
|
||||
|
||||
#download-button:hover {
|
||||
background: var(--button-hover-transparent);
|
||||
}
|
||||
|
||||
#download-button:disabled {
|
||||
cursor: unset;
|
||||
}
|
||||
|
||||
#download-button:disabled:hover {
|
||||
background: none;
|
||||
}
|
||||
|
||||
:global(#input-container.focused) #download-button {
|
||||
border-left: 2px var(--secondary) solid;
|
||||
}
|
||||
</style>
|
|
@ -10,7 +10,7 @@
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: calc(var(--sidebar-padding) * 2 - 2px);
|
||||
padding: calc(var(--padding) * 2 - 2px);
|
||||
}
|
||||
@media screen and (max-width: 535px) {
|
||||
#cobalt-logo {
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
}
|
||||
|
||||
#sidebar {
|
||||
background: black;
|
||||
background: var(--secondary);
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
width: var(--sidebar-width);
|
||||
|
@ -69,7 +69,7 @@
|
|||
#sidebar-tabs {
|
||||
height: 100%;
|
||||
justify-content: space-between;
|
||||
padding-bottom: var(--sidebar-padding);
|
||||
padding-bottom: var(--padding);
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,8 @@
|
|||
display: block;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
background: linear-gradient(90deg,
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(0, 0, 0, 0.9) 0%,
|
||||
rgba(0, 0, 0, 0) 4%,
|
||||
rgba(0, 0, 0, 0) 50%,
|
||||
|
|
|
@ -24,15 +24,15 @@
|
|||
align-items: center;
|
||||
text-align: center;
|
||||
gap: 5px;
|
||||
padding: var(--sidebar-padding) 5px;
|
||||
color: var(--accent);
|
||||
padding: var(--padding) 5px;
|
||||
color: var(--primary);
|
||||
font-size: var(--sidebar-font-size);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.sidebar-tab.active {
|
||||
color: var(--background);
|
||||
background: var(--accent);
|
||||
color: var(--secondary);
|
||||
background: var(--primary);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
|||
|
||||
@media screen and (max-width: 535px) {
|
||||
.sidebar-tab {
|
||||
padding: 5px var(--sidebar-padding);
|
||||
padding: 5px var(--padding);
|
||||
min-width: calc(var(--sidebar-width) / 2);
|
||||
}
|
||||
.sidebar-tab.active {
|
||||
|
|
|
@ -13,20 +13,32 @@
|
|||
|
||||
<style>
|
||||
:global(:root) {
|
||||
--accent: #ffffff;
|
||||
--background: #000000;
|
||||
--primary: #ffffff;
|
||||
--secondary: #000000;
|
||||
--gray: #8d8d95;
|
||||
|
||||
--button: #eeeeee;
|
||||
--button-hover: rgb(215, 215, 215);
|
||||
--button-hover-transparent: rgba(215, 215, 215, 0.5);
|
||||
--button-stroke: rgba(0, 0, 0, 0.8);
|
||||
|
||||
--padding: 12px;
|
||||
|
||||
--sidebar-width: 80px;
|
||||
--sidebar-font-size: 11px;
|
||||
--sidebar-padding: 12px;
|
||||
}
|
||||
|
||||
:global(html),
|
||||
:global(body) {
|
||||
font-family: "IBM Plex Mono", "Noto Sans Mono", monospace;
|
||||
margin: 0;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
:global(*) {
|
||||
font-family: "IBM Plex Mono", "Noto Sans Mono Variable", "Noto Sans Mono", monospace;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
|
||||
:global(a) {
|
||||
|
@ -34,6 +46,28 @@
|
|||
text-decoration-line: none;
|
||||
}
|
||||
|
||||
:global(svg),
|
||||
:global(img) {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
:global(button) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 7px 13px;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
background-color: var(--button);
|
||||
color: var(--secondary);
|
||||
}
|
||||
|
||||
:global(button:hover) {
|
||||
background-color: var(--button-hover);
|
||||
}
|
||||
|
||||
#cobalt {
|
||||
height: 100vh;
|
||||
display: grid;
|
||||
|
|
|
@ -1,2 +1,50 @@
|
|||
<!-- home (save) page -->
|
||||
<div>home</div>
|
||||
<script>
|
||||
import Omnibox from "../components/save/Omnibox.svelte";
|
||||
</script>
|
||||
|
||||
<div id="cobalt-save-container">
|
||||
<main id="cobalt-save">
|
||||
<img
|
||||
id="meowbalt-smile"
|
||||
src="/meowbalt/smile.png"
|
||||
height="152"
|
||||
alt="black and white cat smiling and loafing"
|
||||
/>
|
||||
<Omnibox />
|
||||
</main>
|
||||
<div id="terms-note">
|
||||
by continuing you agree to terms and ethics of use
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#cobalt-save-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
padding: var(--padding);
|
||||
}
|
||||
|
||||
#cobalt-save {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
#meowbalt-smile {
|
||||
display: block;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#terms-note {
|
||||
bottom: 0;
|
||||
color: var(--gray);
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
padding-bottom: var(--padding);
|
||||
}
|
||||
</style>
|
||||
|
|
BIN
web/static/meowbalt/smile.png
Normal file
BIN
web/static/meowbalt/smile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Loading…
Reference in a new issue