Add Field

This commit is contained in:
venashial 2022-06-13 12:48:43 -07:00
parent 496c08b075
commit aa88115d45
15 changed files with 97 additions and 70 deletions

View File

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 25 25">
<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: 728 B

After

Width:  |  Height:  |  Size: 747 B

View File

@ -48,7 +48,8 @@
stroke-linejoin="round"
stroke-miterlimit="1.5"
clip-rule="evenodd"
viewBox="0 0 104 104">
viewBox="0 0 104 104"
aria-hidden="true">
<path fill="none" d="M0 0h103.4v103.4H0z" />
<path
fill="none"

View File

@ -1,7 +1,7 @@
<script lang="ts">
// TODO: sizes
// TODO: icon only buttons should have uniform padding
import { createEventDispatcher } from 'svelte'
import { classCombine } from '../utils/classCombine'
/** The element to be styled as a button */
@ -42,16 +42,22 @@
`button--color-${color}`,
badge && 'has-badge',
])
const dispatch = createEventDispatcher()
function dispatchClick() {
if (!disabled) dispatch('click')
}
</script>
{#if as === 'a'}
<a class={className} {href} {disabled} {title} {target} on:click>
<a class={className} {href} {disabled} {title} {target} on:click={dispatchClick}>
<slot />
</a>
{:else if as === 'input'}
<input class={className} {value} {disabled} {title} on:click />
<input class={className} {value} {disabled} {title} on:click={dispatchClick} />
{:else}
<svelte:element this={as} class={className} {disabled} {title} on:click>
<svelte:element this={as} class={className} {disabled} {title} on:click={dispatchClick}>
<slot />
</svelte:element>
{/if}
@ -76,13 +82,14 @@
background-color: var(--color-button-bg);
border-radius: var(--rounded);
transition: opacity 0.5s ease-in-out, filter 0.2s ease-in-out, transform 0.05s ease-in-out;
transition: opacity 0.5s ease-in-out, filter 0.2s ease-in-out, transform 0.05s ease-in-out,
outline 0.2s ease-in-out;
&:hover:not(&--color-transparent) {
&:hover:not(&--color-transparent, &:disabled) {
filter: brightness(0.85);
}
&:active:not(&--color-transparent) {
&:active:not(&--color-transparent, &:disabled) {
transform: scale(0.95);
filter: brightness(0.8);
}
@ -140,9 +147,6 @@
opacity: 50%;
cursor: not-allowed;
filter: grayscale(50%);
/* Not ideal, but preventing events being fired needs to be implemented */
pointer-events: none;
}
&--pad-even {

View File

@ -0,0 +1,46 @@
<script lang="ts">
import { uniqueId } from '../utils/uniqueId'
export let required = false
export let label: string
export let helper = ''
const id = `field-${uniqueId()}`
</script>
<div class="field">
<label for={id} class="field__label" class:required>
<span class="field__label__title">{@html label}</span>
{#if helper}
<span class="field__label__helper">{helper}</span>
{/if}
</label>
<slot {id} />
</div>
<style lang="postcss">
.field {
display: flex;
flex-direction: column;
gap: 0.5rem;
&__label {
display: flex;
flex-direction: column;
gap: 0;
&__title {
font-weight: var(--font-weight-bold);
:global(i) {
font-weight: var(--font-weight-normal);
}
}
&__helper {
font-size: var(--font-size-sm);
color: var(--color-text-light);
}
}
}
</style>

View File

@ -1,23 +0,0 @@
<script lang="ts">
import { uniqueId } from '../utils/uniqueId'
export let required = false
export let label: string
const id = `form-field-${uniqueId()}`
</script>
<div class="form-field">
<label for={id} class="text-input__label" class:required>
{label}
</label>
<slot {id} />
</div>
<style lang="postcss">
.form-field {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
</style>

View File

@ -6,6 +6,7 @@
import IconExclamation from 'virtual:icons/heroicons-outline/exclamation'
import IconTrash from 'virtual:icons/heroicons-outline/trash'
import { markdown } from '../utils'
import Field from './Field.svelte'
export let key: string
export let type: 'project' | 'version' | 'account' | 'image'
@ -22,10 +23,12 @@
</div>
{/if}
{@html markdown($t(`modal.deletion.${type}.description`))}
<span class="verify-label">{@html $t('modal.deletion.generic.verify', { values: { key } })}</span>
<TextInput
placeholder={$t('modal.deletion.generic.placeholder', { values: { key } })}
bind:value={keyInput} />
<Field label={$t('modal.deletion.generic.verify', { values: { key } })} let:id>
<TextInput
placeholder={$t('modal.deletion.generic.placeholder', { values: { key } })}
bind:value={keyInput}
{id} />
</Field>
<Button color="danger" slot="button" disabled={key !== keyInput}>
<IconTrash />
{$t(`modal.deletion.${type}.action`)}
@ -50,12 +53,4 @@
width: 1.5rem;
}
}
.verify-label {
font-weight: var(--font-weight-bold);
}
:global(i) {
font-weight: var(--font-weight-normal);
}
</style>

View File

@ -44,7 +44,7 @@
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>
sveltekit:noscroll={!resetScroll || null}>{link.label}</a>
{/each}
</nav>

View File

@ -68,7 +68,7 @@
if (!open) {
open = true
// Needs delay before trying to move focus
setTimeout(() => element.children[1].children[0].focus(), 0)
setTimeout(() => (element.children[1].children[0] as HTMLButtonElement).focus(), 0)
} else {
const option = options.find(
({ label }) => label === document.activeElement.innerHTML.trim()
@ -112,12 +112,15 @@
transition:fade={{ duration: 70 }}
class="select__options"
style:--selected-index={options.indexOf(selected)}>
{#each options as option (option.value)}
{#each options as option, index (option.value)}
{@const isSelected = selected?.value === option.value}
<button
on:click={() => selectOption(option)}
class:is-selected={isSelected}
tabindex={isSelected ? -1 : 0}>
tabindex={isSelected ? -1 : 0}
on:focusout={() => {
if (index + 1 === options.length) open = false
}}>
{option.label || option.value}
{#if selected?.value === option.value}
<IconCheck />

View File

@ -6,7 +6,7 @@
</script>
<div class="slider">
<input class="slider-input" type="range" name={id} {min} {max} bind:value />
<input class="slider__input" type="range" {id} {min} {max} bind:value />
<span>{value}</span>
</div>
@ -17,7 +17,7 @@
align-items: center;
gap: 0.5rem;
.slider-input {
&__input {
-webkit-appearance: none;
appearance: none;
border-radius: var(--rounded-sm);

View File

@ -11,9 +11,9 @@
<div class="text-input" class:fill>
{#if multiline}
<textarea name={id} {placeholder} bind:value />
<textarea {id} {placeholder} bind:value />
{:else}
<input type="text" name={id} {placeholder} bind:value class:has-icon={icon} />
<input type="text" {id} {placeholder} bind:value class:has-icon={icon} />
{#if icon}
<svelte:component this={icon} />
{/if}

View File

@ -12,7 +12,7 @@ export { default as CheckboxVirtualList } from './components/CheckboxVirtualList
export { default as Chips } from './components/Chips.svelte'
export { default as FormField } from './components/FormField.svelte'
export { default as Field } from './components/Field.svelte'
export { default as Modal } from './components/Modal.svelte'

View File

@ -36,7 +36,8 @@ input:focus-visible,
input,
button,
a {
a,
.select {
outline: 0 solid hsla(290, 100%, 40%, 0);
transition: outline 0.2s ease-in-out;
}

View File

@ -0,0 +1,12 @@
```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>
```

View File

@ -1,12 +0,0 @@
```svelte example raised
<script lang="ts">
import { FormField, Slider, TextInput } from 'omorphia'
</script>
<FormField label="Favorite number">
<Slider min="0" max="100" value="69" />
</FormField>
<FormField label="Favorite color">
<TextInput placeholder="Enter another color..." />
</FormField>
```

View File

@ -6,7 +6,7 @@ title: Icons
The follwing icon packs are included with omorphia:
`heroicons-outline` `lucide` `fa-regular` `heroicons-solid` `carbon`
`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)