Skip to content

Commit

Permalink
Merge pull request #206 from oddbird/svelte-5
Browse files Browse the repository at this point in the history
Svelte 5
  • Loading branch information
jgerigmeyer authored Nov 8, 2024
2 parents 9143bb8 + 77d1cf4 commit f3d871a
Show file tree
Hide file tree
Showing 33 changed files with 918 additions and 838 deletions.
36 changes: 18 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"prettier": "prettier --write .",
"prettier:ci": "prettier --check .",
"lint:sass": "yarn lint:sass:ci --fix",
"lint:ci": "run-p prettier:ci sync check lint:js:ci lint:sass:ci tsc tsc:tests",
"lint:ci": "run-s prettier:ci sync check lint:js:ci lint:sass:ci tsc tsc:tests",
"lint:sass:ci": "stylelint '**/*.scss'",
"docs:json": "sass -p node src/sass/json.scss static/built/json.css",
"docs:sass": "sass -p node src/sass/app.scss static/built/app.css",
Expand All @@ -38,23 +38,23 @@
"colorjs.io": "^0.5.2"
},
"devDependencies": {
"@eslint/js": "^9.13.0",
"@sveltejs/adapter-auto": "^3.2.5",
"@sveltejs/kit": "^2.7.2",
"@sveltejs/vite-plugin-svelte": "^3.1.2",
"@testing-library/jest-dom": "^6.6.2",
"@eslint/js": "^9.14.0",
"@sveltejs/adapter-auto": "^3.3.1",
"@sveltejs/kit": "^2.8.0",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/svelte": "^5.2.4",
"@types/eslint-config-prettier": "^6.11.3",
"@types/eslint__js": "^8.42.3",
"@types/lodash": "^4.17.12",
"@types/lodash": "^4.17.13",
"@types/node": "^20",
"@typescript-eslint/eslint-plugin": "^8.10.0",
"@typescript-eslint/parser": "^8.10.0",
"@typescript-eslint/utils": "^8.10.0",
"@vitest/coverage-v8": "^2.1.3",
"@typescript-eslint/eslint-plugin": "^8.13.0",
"@typescript-eslint/parser": "^8.13.0",
"@typescript-eslint/utils": "^8.13.0",
"@vitest/coverage-v8": "^2.1.4",
"@vitest/eslint-plugin": "^1.1.7",
"chokidar-cli": "^3.0.0",
"eslint": "^9.13.0",
"eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.3",
"eslint-plugin-import": "^2.31.0",
Expand All @@ -67,18 +67,18 @@
"postcss": "^8.4.47",
"prettier": "^3.3.3",
"prettier-plugin-svelte": "^3.2.7",
"sass-embedded": "^1.80.3",
"sass-embedded": "^1.80.6",
"sassdoc": "^2.7.4",
"sassdoc-theme-herman": "^6.0.1",
"stylelint": "^16.10.0",
"stylelint-config-standard-scss": "^13.1.0",
"svelte": "^4.2.19",
"svelte": "^5.1.12",
"svelte-check": "^4.0.5",
"svelte-eslint-parser": "^0.43.0",
"typescript": "^5.6.3",
"typescript-eslint": "^8.10.0",
"vite": "^5.4.9",
"vitest": "^2.1.3"
"typescript-eslint": "^8.13.0",
"vite": "^5.4.10",
"vitest": "^2.1.4"
},
"packageManager": "[email protected].0"
"packageManager": "[email protected].1"
}
11 changes: 5 additions & 6 deletions src/lib/components/SpaceSelect.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,22 @@
import { bg, ColorSpace, fg, format } from '$lib/stores';
import { getSpaceFromFormatId } from '$lib/utils';
let spaces: ColorSpace[] = [];
$: spaces = FORMATS.map((s) => {
let spaces: ColorSpace[] = FORMATS.map((s) => {
if (s === 'hex') return { id: 'hex', name: 'Hex' } as ColorSpace;
return ColorSpace.get(s);
});
$: targetSpace = getSpaceFromFormatId($format);
// Update color formats when space selection changes
$: {
// Use $effect.pre to change colors before the $format update is applied.
$effect.pre(() => {
let targetSpace = getSpaceFromFormatId($format);
if ($bg.space.id !== targetSpace) {
$bg = to($bg, targetSpace, { inGamut: true });
}
if ($fg.space.id !== targetSpace) {
$fg = to($fg, targetSpace, { inGamut: true });
}
}
});
</script>

<div data-field="color-format">
Expand Down
12 changes: 8 additions & 4 deletions src/lib/components/colors/FormatGroup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
import ExternalLink from '../util/ExternalLink.svelte';
export let type: 'bg' | 'fg';
export let color: PlainColorObject;
export let formatGroup: FormatGroup;
interface Props {
type: 'bg' | 'fg';
color: PlainColorObject;
formatGroup: FormatGroup;
}
let { type, color, formatGroup }: Props = $props();
function inGamutForSpace(color: PlainColorObject) {
if (!formatGroup.gamutFormat) return true;
Expand All @@ -19,7 +23,7 @@
);
return inGamut(color, gamutSpace);
}
$: isInGamut = inGamutForSpace(color);
let isInGamut = $derived(inGamutForSpace(color));
</script>

<div data-content="format-group">
Expand Down
14 changes: 9 additions & 5 deletions src/lib/components/colors/Formats.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
type FormatGroup as FormatGroupType,
} from '$lib/constants';
export let type: 'bg' | 'fg';
export let color: PlainColorObject;
export let format: ColorFormatId;
interface Props {
type: 'bg' | 'fg';
color: PlainColorObject;
format: ColorFormatId;
}
let { type, color, format }: Props = $props();
function otherFormatGroups(
selectedFormat: ColorFormatId,
Expand All @@ -25,8 +29,8 @@
return otherFormats;
}
$: displayType = type === 'bg' ? 'Background' : 'Foreground';
$: otherFormats = otherFormatGroups(format);
let displayType = $derived(type === 'bg' ? 'Background' : 'Foreground');
let otherFormats = $derived(otherFormatGroups(format));
</script>

<div data-content="formats" data-column="tool">
Expand Down
42 changes: 24 additions & 18 deletions src/lib/components/colors/Header.svelte
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
<script lang="ts">
import { type PlainColorObject, serialize, to } from 'colorjs.io/fn';
import type { Writable } from 'svelte/store';
import { type Writable } from 'svelte/store';
import CopyButton from '$lib/components/util/CopyButton.svelte';
import type { ColorFormatId } from '$lib/constants';
import { getSpaceFromFormatId } from '$lib/utils';
export let type: 'bg' | 'fg';
export let color: Writable<PlainColorObject>;
export let format: ColorFormatId;
interface Props {
type: 'bg' | 'fg';
color: Writable<PlainColorObject>;
format: ColorFormatId;
}
let { type, color, format }: Props = $props();
$: targetSpace = getSpaceFromFormatId(format);
$: display = serialize($color, { inGamut: false, format });
$: displayType = type === 'bg' ? 'Background' : 'Foreground';
let editing = false;
let inputValue = '';
let hasError = false;
let targetSpace = $derived(getSpaceFromFormatId(format));
let display = $derived(serialize($color, { inGamut: false, format }));
let displayType = $derived(type === 'bg' ? 'Background' : 'Foreground');
let editing = $state(false);
let inputValue = $state('');
let hasError = $state(false);
// When not editing, sync input value with color (e.g. when sliders change)
$: if (!editing) {
inputValue = display;
}
$effect(() => {
if (!editing) {
inputValue = display;
}
});
const handleFocus = () => {
editing = true;
Expand Down Expand Up @@ -82,7 +88,7 @@
data-column="tool"
data-needs-changes={hasError}
>
<div class="swatch {type}" />
<div class="swatch {type}"></div>
<label for="{type}-color" data-label>
{displayType} Color
</label>
Expand All @@ -92,10 +98,10 @@
type="text"
data-input="color"
value={inputValue}
on:focus={handleFocus}
on:blur={handleBlur}
on:input={handleInput}
on:keydown={handleKeydown}
onfocus={handleFocus}
onblur={handleBlur}
oninput={handleInput}
onkeydown={handleKeydown}
/>
<CopyButton text={display} size="medium" />
{#if hasError}
Expand Down
24 changes: 15 additions & 9 deletions src/lib/components/colors/Output.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@
import type { ColorFormatId } from '$lib/constants';
import { getSpaceFromFormatId } from '$lib/utils';
export let type: 'bg' | 'fg';
export let color: PlainColorObject;
export let format: ColorFormatId;
interface Props {
type: 'bg' | 'fg';
color: PlainColorObject;
format: ColorFormatId;
}
let { type, color, format }: Props = $props();
$: targetSpace = getSpaceFromFormatId(format);
$: targetColor = to(color, targetSpace);
$: targetColorValue = serialize(targetColor, {
format,
inGamut: false,
});
let targetSpace = $derived(getSpaceFromFormatId(format));
let targetColor = $derived(to(color, targetSpace));
let targetColorValue = $derived(
serialize(targetColor, {
format,
inGamut: false,
}),
);
</script>

<ul data-group="output {type}">
Expand Down
106 changes: 56 additions & 50 deletions src/lib/components/colors/Sliders.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,39 @@
import { ColorSpace } from '$lib/stores';
import { getSpaceFromFormatId, sliderGradient } from '$lib/utils';
export let type: 'bg' | 'fg';
export let color: Writable<PlainColorObject>;
export let format: ColorFormatId;
interface Props {
type: 'bg' | 'fg';
color: Writable<PlainColorObject>;
format: ColorFormatId;
}
let { type, color, format }: Props = $props();
$: targetSpace = getSpaceFromFormatId(format);
$: spaceObject = ColorSpace.get(targetSpace);
$: sliders = SLIDERS[format].map((id) => {
const coord = spaceObject.coords[id];
const range = coord?.range ?? coord?.refRange ?? [0, 1];
const gradient = sliderGradient($color, id, range);
return {
id,
name: coord?.name ?? '',
range,
index: Number(
ColorSpace.resolveCoord({
space: spaceObject,
coordId: id,
}).index,
),
gradient,
};
});
let targetSpace = $derived(getSpaceFromFormatId(format));
let spaceObject = $derived(ColorSpace.get(targetSpace));
let sliders = $derived(
SLIDERS[format].map((id) => {
const coord = spaceObject.coords[id];
const range = coord?.range ?? coord?.refRange ?? [0, 1];
const gradient = sliderGradient($color, id, range);
return {
id,
name: coord?.name ?? '',
range,
index: Number(
ColorSpace.resolveCoord({
space: spaceObject,
coordId: id,
}).index,
),
gradient,
};
}),
);
$: alphaGradient = sliderGradient($color, 'alpha', [0, $color.alpha]);
let alphaGradient = $derived(
sliderGradient($color, 'alpha', [0, $color.alpha]),
);
const handleInput = (
e: Event & { currentTarget: EventTarget & HTMLInputElement },
Expand Down Expand Up @@ -59,38 +67,36 @@
</script>

<div data-actions="edit-color" data-group="sliders {type}">
<form>
{#each sliders as slider (slider.id)}
<div data-field="color-slider">
<label for="{type}_{slider.id}" data-label>{slider.name}</label>
<input
id="{type}_{slider.id}"
name="{type}_{slider.id}"
type="range"
min={slider.range[0]}
max={slider.range[1]}
step={getStep(slider.range)}
style={`--stops: ${slider.gradient}`}
value={$color.coords[slider.index]}
on:input={(e) => handleInput(e, slider.index)}
/>
</div>
{/each}
{#each sliders as slider (slider.id)}
<div data-field="color-slider">
<label for="{type}_alpha" data-label>Alpha</label>
<label for="{type}_{slider.id}" data-label>{slider.name}</label>
<input
id="{type}_alpha"
name="{type}_alpha"
id="{type}_{slider.id}"
name="{type}_{slider.id}"
type="range"
min={0}
max={1}
step={getStep([0, 1])}
style={`--stops: ${alphaGradient}`}
value={$color.alpha}
on:input={(e) => handleInput(e)}
min={slider.range[0]}
max={slider.range[1]}
step={getStep(slider.range)}
style={`--stops: ${slider.gradient}`}
value={$color.coords[slider.index]}
oninput={(e) => handleInput(e, slider.index)}
/>
</div>
</form>
{/each}
<div data-field="color-slider">
<label for="{type}_alpha" data-label>Alpha</label>
<input
id="{type}_alpha"
name="{type}_alpha"
type="range"
min={0}
max={1}
step={getStep([0, 1])}
style={`--stops: ${alphaGradient}`}
value={$color.alpha}
oninput={(e) => handleInput(e)}
/>
</div>
</div>

<style lang="scss">
Expand Down
Loading

0 comments on commit f3d871a

Please sign in to comment.