chore: some updates
All checks were successful
Deploy to GitHub Pages / build_site (push) Successful in 2m6s
All checks were successful
Deploy to GitHub Pages / build_site (push) Successful in 2m6s
This commit is contained in:
@@ -1,29 +1,28 @@
|
||||
<script lang="ts">
|
||||
import Checkbox from './elements/Checkbox.svelte';
|
||||
import Float from './elements/Float.svelte';
|
||||
import Integer from './elements/Integer.svelte';
|
||||
import Select from './elements/Select.svelte';
|
||||
import Checkbox from './inputs/Checkbox.svelte';
|
||||
import Float from './inputs/Float.svelte';
|
||||
import Integer from './inputs/Integer.svelte';
|
||||
import Select from './inputs/Select.svelte';
|
||||
|
||||
import type { NodeInput } from '@nodarium/types';
|
||||
import Vec3 from './elements/Vec3.svelte';
|
||||
import Vec3 from './inputs/Vec3.svelte';
|
||||
|
||||
interface Props {
|
||||
input: NodeInput;
|
||||
value: any;
|
||||
id: string;
|
||||
}
|
||||
|
||||
let { input, value = $bindable(), id }: Props = $props();
|
||||
let { input, value = $bindable() }: Props = $props();
|
||||
</script>
|
||||
|
||||
{#if input.type === 'float'}
|
||||
<Float {id} bind:value min={input?.min} max={input?.max} />
|
||||
<Float bind:value min={input?.min} max={input?.max} />
|
||||
{:else if input.type === 'integer'}
|
||||
<Integer {id} bind:value min={input?.min} max={input?.max} />
|
||||
<Integer bind:value min={input?.min} max={input?.max} />
|
||||
{:else if input.type === 'boolean'}
|
||||
<Checkbox {id} bind:value />
|
||||
<Checkbox bind:value />
|
||||
{:else if input.type === 'select'}
|
||||
<Select {id} bind:value options={input.options} />
|
||||
<Select bind:value options={input.options} />
|
||||
{:else if input.type === 'vec3'}
|
||||
<Vec3 {id} bind:value />
|
||||
<Vec3 bind:value />
|
||||
{/if}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
/* fira-code-300 - latin */
|
||||
@font-face {
|
||||
font-display: swap;
|
||||
@@ -63,11 +65,9 @@ html {
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
|
||||
|
||||
color: var(--text-color);
|
||||
background-color: var(--layer-0);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body * {
|
||||
@@ -140,10 +140,6 @@ html.theme-dracula {
|
||||
--connection: #6272A4;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: var(--layer-2);
|
||||
border: 1px solid var(--outline);
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
value: boolean;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
let { value = $bindable(false), id = '' }: Props = $props();
|
||||
$effect(() => {
|
||||
if (typeof value === 'string') {
|
||||
value = value === 'true';
|
||||
} else if (typeof value === 'number') {
|
||||
value = value === 1;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<input {id} type="checkbox" bind:checked={value} />
|
||||
<label for={id}>
|
||||
<svg viewBox="0 0 19 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M2 7L7 12L17 2"
|
||||
stroke="currentColor"
|
||||
stroke-width="3"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</label>
|
||||
|
||||
<style>
|
||||
input[type='checkbox'] {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
#inputPreview {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
justify-content: center;
|
||||
}
|
||||
input + label {
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
height: 22px;
|
||||
color: rgb(0, 0, 0);
|
||||
}
|
||||
input + label::before {
|
||||
content: ' ';
|
||||
display: inline;
|
||||
vertical-align: middle;
|
||||
margin-right: 3px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background-color: var(--layer-2);
|
||||
border-radius: 5px;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
input:checked + label::after {
|
||||
content: ' ';
|
||||
background-repeat: no-repeat;
|
||||
background-size: 12px 12px;
|
||||
background-position: center center;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-left: 0px;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
text-align: center;
|
||||
background-color: transparent;
|
||||
color: red;
|
||||
font-size: 10px;
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
}
|
||||
|
||||
input + label > svg {
|
||||
position: absolute;
|
||||
display: none;
|
||||
width: 12px;
|
||||
height: 10px;
|
||||
left: 5px;
|
||||
color: var(--text-color);
|
||||
top: 5.9px;
|
||||
}
|
||||
|
||||
input:checked + label > svg {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
@@ -1,11 +0,0 @@
|
||||
<script module>
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import FloatComp from './Float.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Inputs/Float',
|
||||
component: FloatComp
|
||||
});
|
||||
</script>
|
||||
|
||||
<Story name="Float" />
|
||||
@@ -1,11 +0,0 @@
|
||||
<script module>
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import IntegerComp from './Integer.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Inputs/Integer',
|
||||
component: IntegerComp
|
||||
});
|
||||
</script>
|
||||
|
||||
<Story name="Integer" />
|
||||
@@ -1,23 +0,0 @@
|
||||
<script module>
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import SelectComp from '$lib/elements/Select.svelte';
|
||||
const { Story } = defineMeta({
|
||||
title: 'Inputs/Select',
|
||||
component: SelectComp,
|
||||
|
||||
argTypes: {
|
||||
options: {
|
||||
control: {
|
||||
type: 'select'
|
||||
}
|
||||
}
|
||||
},
|
||||
parameters: {
|
||||
actions: {
|
||||
handles: ['change']
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<Story name="Select" args={{ options: ['strawberry', 'raspberry', 'chickpeas'] }} />
|
||||
@@ -1,10 +0,0 @@
|
||||
<script module>
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import Vec3Comp from './Vec3.svelte';
|
||||
const { Story } = defineMeta({
|
||||
title: 'Inputs/Vec3',
|
||||
component: Vec3Comp
|
||||
});
|
||||
</script>
|
||||
|
||||
<Story name="Vec3" />
|
||||
@@ -1,16 +1,12 @@
|
||||
// Reexport your entry components here
|
||||
import Input from './Input.svelte';
|
||||
|
||||
import Float from "./elements/Float.svelte";
|
||||
import Integer from "./elements/Integer.svelte";
|
||||
import Select from "./elements/Select.svelte";
|
||||
import Checkbox from "./elements/Checkbox.svelte";
|
||||
import Details from "./Details.svelte";
|
||||
|
||||
export const icons = import.meta.glob('./icons/*.svg?raw', { eager: true })
|
||||
|
||||
export { Float, Integer, Select, Checkbox, Input, Details };
|
||||
|
||||
export default Input;
|
||||
export { default as Input } from "./Input.svelte"
|
||||
export { default as Float } from "./inputs/Float.svelte"
|
||||
export { default as Integer } from "./inputs/Integer.svelte"
|
||||
export { default as Select } from "./inputs/Select.svelte"
|
||||
export { default as Checkbox } from "./inputs/Checkbox.svelte"
|
||||
export { default as Vec3 } from "./inputs/Vec3.svelte";
|
||||
|
||||
export { default as Details } from "./Details.svelte"
|
||||
export { default as ShortCut } from "./ShortCut.svelte";
|
||||
|
||||
import Input from './Input.svelte';
|
||||
export default Input;
|
||||
|
||||
45
packages/ui/src/lib/inputs/Checkbox.svelte
Normal file
45
packages/ui/src/lib/inputs/Checkbox.svelte
Normal file
@@ -0,0 +1,45 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
value: boolean;
|
||||
}
|
||||
|
||||
let { value = $bindable(false) }: Props = $props();
|
||||
|
||||
$effect(() => {
|
||||
if (typeof value === 'string') {
|
||||
value = value === 'true';
|
||||
} else if (typeof value === 'number') {
|
||||
value = value === 1;
|
||||
} else if (!(typeof value === 'boolean')) {
|
||||
value = !!value;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<label
|
||||
class="relative inline-flex h-[22px] w-[22px] cursor-pointer items-center justify-center bg-[var(--layer-2)] rounded-[5px]"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={value}
|
||||
class="peer absolute h-px w-px overflow-hidden whitespace-nowrap border-0 p-0 [clip:rect(0,0,0,0)]"
|
||||
/>
|
||||
<span
|
||||
class="absolute opacity-0 peer-checked:opacity-100 transition-opacity duration-100 flex w-full h-full items-center justify-center"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 19 14"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-[10px] w-[12px] text-[var(--text-color)]"
|
||||
>
|
||||
<path
|
||||
d="M2 7L7 12L17 2"
|
||||
stroke="currentColor"
|
||||
stroke-width="3"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</label>
|
||||
@@ -4,15 +4,13 @@
|
||||
step?: number;
|
||||
min?: number;
|
||||
max?: number;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
let {
|
||||
value = $bindable(0.5),
|
||||
step = 0.01,
|
||||
min = $bindable(0),
|
||||
max = $bindable(1),
|
||||
id = ''
|
||||
max = $bindable(1)
|
||||
}: Props = $props();
|
||||
|
||||
if (min > max) {
|
||||
@@ -55,6 +53,7 @@
|
||||
window.addEventListener('mousemove', handleMouseMove);
|
||||
window.addEventListener('mouseup', handleMouseUp);
|
||||
document.body.style.cursor = 'ew-resize';
|
||||
(ev.target as HTMLElement)?.blur();
|
||||
}
|
||||
|
||||
function handleMouseUp() {
|
||||
@@ -93,6 +92,7 @@
|
||||
} else {
|
||||
value = Math.max(Math.min(min + (max - min) * vx, max), min);
|
||||
}
|
||||
(ev.target as HTMLElement)?.blur();
|
||||
}
|
||||
$effect(() => {
|
||||
if ((value || 0).toString().length > 5) {
|
||||
@@ -110,7 +110,6 @@
|
||||
<input
|
||||
bind:value
|
||||
bind:this={inputEl}
|
||||
{id}
|
||||
{step}
|
||||
{max}
|
||||
{min}
|
||||
@@ -1,29 +1,64 @@
|
||||
<script lang="ts">
|
||||
import '$lib/app.css';
|
||||
import Float from '$lib/elements/Float.svelte';
|
||||
import Integer from '$lib/elements/Integer.svelte';
|
||||
import Vec3 from '$lib/elements/Vec3.svelte';
|
||||
import { Checkbox, Details, Float, Integer, Select, ShortCut, Vec3 } from '$lib/index.js';
|
||||
import Section from './Section.svelte';
|
||||
|
||||
let intValue = $state(0);
|
||||
let floatValue = $state(0.2);
|
||||
let vecValue = $state([0.2, 0.3, 0.4]);
|
||||
const options = ['strawberry', 'raspberry', 'chickpeas'];
|
||||
let selectValue = $state(0);
|
||||
const d = $derived(options[selectValue]);
|
||||
|
||||
let checked = $state(false);
|
||||
let detailsOpen = $state(false);
|
||||
|
||||
const themes = ['light', 'solarized', 'catppuccin', 'high-contrast', 'nord', 'dracula'];
|
||||
let themeIndex = $state(0);
|
||||
$effect(() => {
|
||||
const classList = document.documentElement.classList;
|
||||
for (const c of classList) {
|
||||
if (c.startsWith('theme-')) document.documentElement.classList.remove(c);
|
||||
}
|
||||
document.documentElement.classList.add(`theme-${themes[themeIndex]}`);
|
||||
});
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<section>
|
||||
<h3>Integer {intValue}</h3>
|
||||
<main class="flex flex-col gap-8 py-8">
|
||||
<div class="flex gap-4">
|
||||
<h1 class="text-4xl">@nodarium/ui</h1>
|
||||
<Select bind:value={themeIndex} options={themes}></Select>
|
||||
</div>
|
||||
|
||||
<Section title="Integer" value={intValue}>
|
||||
<Integer bind:value={intValue} />
|
||||
</section>
|
||||
</Section>
|
||||
|
||||
<section>
|
||||
<h3>Float {floatValue}</h3>
|
||||
<Section title="Float" value={floatValue}>
|
||||
<Float bind:value={floatValue} />
|
||||
</section>
|
||||
</Section>
|
||||
|
||||
<section>
|
||||
<h3>Vec3 {JSON.stringify(vecValue)}</h3>
|
||||
<Section title="Vec3" value={JSON.stringify(vecValue)}>
|
||||
<Vec3 bind:value={vecValue} />
|
||||
</section>
|
||||
</Section>
|
||||
|
||||
<Section title="Select" value={d}>
|
||||
<Select bind:value={selectValue} {options} />
|
||||
</Section>
|
||||
|
||||
<Section title="Checkbox" value={checked}>
|
||||
<Checkbox bind:value={checked} />
|
||||
</Section>
|
||||
|
||||
<Section title="Details" value={detailsOpen}>
|
||||
<Details title="More Information" bind:open={detailsOpen}>
|
||||
<p>Here is some more information that was previously hidden.</p>
|
||||
</Details>
|
||||
</Section>
|
||||
|
||||
<Section title="Shortcut">
|
||||
<ShortCut ctrl key="S" />
|
||||
</Section>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
|
||||
18
packages/ui/src/routes/Section.svelte
Normal file
18
packages/ui/src/routes/Section.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import { type Snippet } from 'svelte';
|
||||
let { title, value, children } = $props<{
|
||||
title?: string;
|
||||
value?: unknown;
|
||||
children?: Snippet;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<section class="border border-1/2 mb-4 p-4 flex flex-col gap-4">
|
||||
<h3 class="flex gap-2 font-bold">
|
||||
{title}
|
||||
<p class="font-normal! opacity-50!">{value}</p>
|
||||
</h3>
|
||||
<div>
|
||||
{@render children()}
|
||||
</div>
|
||||
</section>
|
||||
Reference in New Issue
Block a user