Bump frontend dependencies to Svelte 5 (#3648)
* Add more recommended VS Code default configs * Upgrade frontend dependencies including Svelte 5 * Fix derived_references_self runtime error * Fix lint warnings
This commit is contained in:
parent
3b55064f44
commit
915a344a05
|
|
@ -48,7 +48,7 @@ let
|
||||||
npmDeps = pkgs.fetchNpmDeps {
|
npmDeps = pkgs.fetchNpmDeps {
|
||||||
inherit (info) pname version;
|
inherit (info) pname version;
|
||||||
src = "${info.src}/frontend";
|
src = "${info.src}/frontend";
|
||||||
hash = "sha256-D8VCNK+Ca3gxO+5wriBn8FszG8/x8n/zM6/MPo9E2j4=";
|
hash = "sha256-WlwzWGoFi3hjRuM5ucrgavko/gg4iFAwMc6uMLjT/FI=";
|
||||||
};
|
};
|
||||||
|
|
||||||
npmRoot = "frontend";
|
npmRoot = "frontend";
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,10 @@
|
||||||
// Code quality
|
// Code quality
|
||||||
"wayou.vscode-todo-highlight",
|
"wayou.vscode-todo-highlight",
|
||||||
"streetsidesoftware.code-spell-checker",
|
"streetsidesoftware.code-spell-checker",
|
||||||
// Helpful
|
// Git
|
||||||
"mhutchie.git-graph",
|
"mhutchie.git-graph",
|
||||||
"qezhu.gitlink",
|
"qezhu.gitlink",
|
||||||
|
// Helpful
|
||||||
"wmaurer.change-case"
|
"wmaurer.change-case"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
"editor.formatOnSave": false
|
"editor.formatOnSave": false
|
||||||
},
|
},
|
||||||
// Rust Analyzer config
|
// Rust Analyzer config
|
||||||
|
"rust-analyzer.check.command": "clippy",
|
||||||
"rust-analyzer.cargo.allTargets": false,
|
"rust-analyzer.cargo.allTargets": false,
|
||||||
"rust-analyzer.procMacro.ignored": {
|
"rust-analyzer.procMacro.ignored": {
|
||||||
"serde_derive": ["Serialize", "Deserialize"],
|
"serde_derive": ["Serialize", "Deserialize"],
|
||||||
|
|
@ -47,13 +48,33 @@
|
||||||
"vite-plugin-svelte-css-no-scopable-elements": "ignore", // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
|
"vite-plugin-svelte-css-no-scopable-elements": "ignore", // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
|
||||||
"a11y-no-static-element-interactions": "ignore", // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
|
"a11y-no-static-element-interactions": "ignore", // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
|
||||||
"a11y-no-noninteractive-element-interactions": "ignore", // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
|
"a11y-no-noninteractive-element-interactions": "ignore", // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
|
||||||
"a11y-click-events-have-key-events": "ignore" // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
|
"a11y-click-events-have-key-events": "ignore", // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
|
||||||
|
"a11y_consider_explicit_label": "ignore", // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
|
||||||
|
"a11y_click_events_have_key_events": "ignore", // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
|
||||||
|
"a11y_no_noninteractive_element_interactions": "ignore" // NOTICE: Keep this list in sync with the list in `frontend/vite.config.ts`
|
||||||
},
|
},
|
||||||
|
// Git Graph config
|
||||||
|
"git-graph.repository.fetchAndPrune": true,
|
||||||
|
"git-graph.repository.showRemoteHeads": false,
|
||||||
|
"git-graph.repository.commits.fetchAvatars": true,
|
||||||
|
// VS Code Git config
|
||||||
|
"git.autofetch": true,
|
||||||
|
"git.enableStatusBarSync": false,
|
||||||
|
"git.showActionButton": {
|
||||||
|
"sync": false
|
||||||
|
},
|
||||||
|
// CSpell config
|
||||||
|
"cSpell.language": "en-US",
|
||||||
|
"cSpell.logLevel": "Information",
|
||||||
|
"cSpell.allowCompoundWords": true,
|
||||||
// VS Code config
|
// VS Code config
|
||||||
"html.format.wrapLineLength": 200,
|
"html.format.wrapLineLength": 200,
|
||||||
"files.eol": "\n",
|
"files.eol": "\n",
|
||||||
"files.insertFinalNewline": true,
|
"files.insertFinalNewline": true,
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.graphite": "json"
|
"*.graphite": "json"
|
||||||
}
|
},
|
||||||
|
"editor.renderWhitespace": "boundary",
|
||||||
|
"editor.minimap.markSectionHeaderRegex": "// ===+\\n\\s*//\\s*(?<label>[^\\n]{1,18})[^\\n]*(\\n\\s*//[^\\n]*)*\\n\\s*// ===+",
|
||||||
|
"evenBetterToml.formatter.alignComments": false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,6 @@ export default defineConfig([
|
||||||
"import/resolver": { typescript: true, node: true },
|
"import/resolver": { typescript: true, node: true },
|
||||||
},
|
},
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
parserOptions: {
|
|
||||||
project: "./tsconfig.json",
|
|
||||||
},
|
|
||||||
globals: {
|
globals: {
|
||||||
...globals.browser,
|
...globals.browser,
|
||||||
...globals.node,
|
...globals.node,
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,11 @@ if (isInstallNeeded()) {
|
||||||
console.log("Finished installing npm packages.");
|
console.log("Finished installing npm packages.");
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error("Failed to install npm packages. Please delete the `node_modules` folder and run `npm install` from the `/frontend` directory.");
|
console.error(
|
||||||
|
"\n\n" +
|
||||||
|
"------------------------------------------------------------> " +
|
||||||
|
"Failed to install npm packages. Please delete the `node_modules` folder and run `npm install` from the `/frontend` directory.",
|
||||||
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -38,32 +38,32 @@
|
||||||
"source-sans": "github:adobe-fonts/source-sans#2.045R-ro%2F1.095R-it"
|
"source-sans": "github:adobe-fonts/source-sans#2.045R-ro%2F1.095R-it"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/compat": "^1.3.2",
|
"@eslint/compat": "^2.0.1",
|
||||||
"@eslint/eslintrc": "^3.3.1",
|
"@eslint/eslintrc": "^3.3.3",
|
||||||
"@eslint/js": "^9.34.0",
|
"@eslint/js": "^9.39.2",
|
||||||
"@sveltejs/vite-plugin-svelte": "^3.1.2",
|
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
||||||
"@types/node": "^24.3.0",
|
"@types/node": "^25.0.9",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"concurrently": "^9.2.1",
|
"concurrently": "^9.2.1",
|
||||||
"eslint-import-resolver-typescript": "^4.4.4",
|
"eslint-import-resolver-typescript": "^4.4.4",
|
||||||
"eslint-plugin-import": "^2.32.0",
|
"eslint-plugin-import": "^2.32.0",
|
||||||
"eslint-plugin-prettier": "^5.5.4",
|
"eslint-plugin-prettier": "^5.5.5",
|
||||||
"eslint-plugin-svelte": "^3.11.0",
|
"eslint-plugin-svelte": "^3.14.0",
|
||||||
"globals": "^16.3.0",
|
"globals": "^17.0.0",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.8.0",
|
||||||
"prettier-plugin-svelte": "^3.4.0",
|
"prettier-plugin-svelte": "^3.4.1",
|
||||||
"process": "^0.11.10",
|
"process": "^0.11.10",
|
||||||
"rollup-plugin-license": "^3.6.0",
|
"rollup-plugin-license": "^3.6.0",
|
||||||
"sass": "^1.91.0",
|
"sass": "^1.97.2",
|
||||||
"svelte": "4.2.20",
|
"svelte": "5.46.4",
|
||||||
"svelte-preprocess": "^6.0.3",
|
"svelte-preprocess": "^6.0.3",
|
||||||
"tar": "^7.5.2",
|
"tar": "^7.5.3",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.9.2",
|
"typescript": "^5.9.3",
|
||||||
"typescript-eslint": "^8.41.0",
|
"typescript-eslint": "^8.53.0",
|
||||||
"vite": "^5.4.19",
|
"vite": "^7.3.1",
|
||||||
"vite-multiple-assets": "2.2.5"
|
"vite-multiple-assets": "2.2.6"
|
||||||
},
|
},
|
||||||
"homepage": "https://graphite.art",
|
"homepage": "https://graphite.art",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
|
|
||||||
|
|
@ -439,7 +439,7 @@
|
||||||
data-saturation-value-picker
|
data-saturation-value-picker
|
||||||
>
|
>
|
||||||
{#if !isNone}
|
{#if !isNone}
|
||||||
<div class="selection-circle" style:top={`${(1 - value) * 100}%`} style:left={`${saturation * 100}%`} />
|
<div class="selection-circle" style:top={`${(1 - value) * 100}%`} style:left={`${saturation * 100}%`}></div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if alignedAxis}
|
{#if alignedAxis}
|
||||||
<div
|
<div
|
||||||
|
|
@ -448,7 +448,7 @@
|
||||||
class:value={alignedAxis === "value"}
|
class:value={alignedAxis === "value"}
|
||||||
style:top={`${(1 - value) * 100}%`}
|
style:top={`${(1 - value) * 100}%`}
|
||||||
style:left={`${saturation * 100}%`}
|
style:left={`${saturation * 100}%`}
|
||||||
/>
|
></div>
|
||||||
{/if}
|
{/if}
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
<LayoutCol
|
<LayoutCol
|
||||||
|
|
@ -459,7 +459,7 @@
|
||||||
data-hue-picker
|
data-hue-picker
|
||||||
>
|
>
|
||||||
{#if !isNone}
|
{#if !isNone}
|
||||||
<div class="selection-needle" style:top={`${(1 - hue) * 100}%`} />
|
<div class="selection-needle" style:top={`${(1 - hue) * 100}%`}></div>
|
||||||
{/if}
|
{/if}
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
<LayoutCol
|
<LayoutCol
|
||||||
|
|
@ -470,7 +470,7 @@
|
||||||
data-alpha-picker
|
data-alpha-picker
|
||||||
>
|
>
|
||||||
{#if !isNone}
|
{#if !isNone}
|
||||||
<div class="selection-needle" style:top={`${(1 - alpha) * 100}%`} />
|
<div class="selection-needle" style:top={`${(1 - alpha) * 100}%`}></div>
|
||||||
{/if}
|
{/if}
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
|
|
@ -677,7 +677,7 @@
|
||||||
style:--pure-color-gray={gray}
|
style:--pure-color-gray={gray}
|
||||||
data-tooltip-label={`Set to ${name}`}
|
data-tooltip-label={`Set to ${name}`}
|
||||||
data-tooltip-description={disabled ? "Disabled (read-only)." : ""}
|
data-tooltip-description={disabled ? "Disabled (read-only)." : ""}
|
||||||
/>
|
></div>
|
||||||
{/each}
|
{/each}
|
||||||
</button>
|
</button>
|
||||||
{#if eyedropperSupported()}
|
{#if eyedropperSupported()}
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,8 @@
|
||||||
>
|
>
|
||||||
<div class="ring">
|
<div class="ring">
|
||||||
<div class="canvas-container">
|
<div class="canvas-container">
|
||||||
<canvas width={ZOOM_WINDOW_DIMENSIONS} height={ZOOM_WINDOW_DIMENSIONS} bind:this={zoomPreviewCanvas} />
|
<canvas width={ZOOM_WINDOW_DIMENSIONS} height={ZOOM_WINDOW_DIMENSIONS} bind:this={zoomPreviewCanvas}></canvas>
|
||||||
<div class="pixel-outline" />
|
<div class="pixel-outline"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</FloatingMenu>
|
</FloatingMenu>
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
// Keep the child references outside of the entries array so as to avoid infinite recursion.
|
// Keep the child references outside of the entries array so as to avoid infinite recursion.
|
||||||
let childReferences: MenuList[][] = [];
|
let childReferences: MenuList[][] = [];
|
||||||
|
let openChildValue: string | undefined = undefined;
|
||||||
let search = "";
|
let search = "";
|
||||||
let reactiveEntries = entries;
|
let reactiveEntries = entries;
|
||||||
let highlighted = activeEntry as MenuListEntry | undefined;
|
let highlighted = activeEntry as MenuListEntry | undefined;
|
||||||
|
|
@ -172,7 +173,7 @@
|
||||||
// Close the containing menu
|
// Close the containing menu
|
||||||
let childReference = getChildReference(menuListEntry);
|
let childReference = getChildReference(menuListEntry);
|
||||||
if (childReference) {
|
if (childReference) {
|
||||||
childReference.open = false;
|
openChildValue = undefined;
|
||||||
reactiveEntries = reactiveEntries;
|
reactiveEntries = reactiveEntries;
|
||||||
}
|
}
|
||||||
dispatch("open", false);
|
dispatch("open", false);
|
||||||
|
|
@ -192,7 +193,7 @@
|
||||||
|
|
||||||
let childReference = getChildReference(menuListEntry);
|
let childReference = getChildReference(menuListEntry);
|
||||||
if (childReference) {
|
if (childReference) {
|
||||||
childReference.open = true;
|
openChildValue = menuListEntry.value;
|
||||||
reactiveEntries = reactiveEntries;
|
reactiveEntries = reactiveEntries;
|
||||||
} else {
|
} else {
|
||||||
dispatch("open", true);
|
dispatch("open", true);
|
||||||
|
|
@ -207,19 +208,13 @@
|
||||||
|
|
||||||
let childReference = getChildReference(menuListEntry);
|
let childReference = getChildReference(menuListEntry);
|
||||||
if (childReference) {
|
if (childReference) {
|
||||||
childReference.open = false;
|
openChildValue = undefined;
|
||||||
reactiveEntries = reactiveEntries;
|
reactiveEntries = reactiveEntries;
|
||||||
} else {
|
} else {
|
||||||
dispatch("open", false);
|
dispatch("open", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEntryOpen(menuListEntry: MenuListEntry): boolean {
|
|
||||||
if (!menuListEntry.children?.length) return false;
|
|
||||||
|
|
||||||
return getChildReference(menuListEntry)?.open || false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function includeSeparator(entries: MenuListEntry[][], section: MenuListEntry[], sectionIndex: number, search: string): boolean {
|
function includeSeparator(entries: MenuListEntry[][], section: MenuListEntry[], sectionIndex: number, search: string): boolean {
|
||||||
const elementsBeforeCurrentSection = entries
|
const elementsBeforeCurrentSection = entries
|
||||||
.slice(0, sectionIndex)
|
.slice(0, sectionIndex)
|
||||||
|
|
@ -242,7 +237,7 @@
|
||||||
// No submenu to open
|
// No submenu to open
|
||||||
if (!childReference || !highlightedEntry.children?.length) return false;
|
if (!childReference || !highlightedEntry.children?.length) return false;
|
||||||
|
|
||||||
childReference.open = true;
|
openChildValue = highlightedEntry.value;
|
||||||
// The reason we bother taking `highlightdEntry` as an argument is because, when this function is called, it can ensure `highlightedEntry` is not undefined.
|
// The reason we bother taking `highlightdEntry` as an argument is because, when this function is called, it can ensure `highlightedEntry` is not undefined.
|
||||||
// But here we still have to set `highlighted` to itself so Svelte knows to reactively update it after we set its `childReference.open` property.
|
// But here we still have to set `highlighted` to itself so Svelte knows to reactively update it after we set its `childReference.open` property.
|
||||||
highlighted = highlighted;
|
highlighted = highlighted;
|
||||||
|
|
@ -262,7 +257,7 @@
|
||||||
|
|
||||||
const menuOpen = open;
|
const menuOpen = open;
|
||||||
const flatEntries = filteredEntries.flat().filter((entry) => !entry.disabled);
|
const flatEntries = filteredEntries.flat().filter((entry) => !entry.disabled);
|
||||||
const openChild = flatEntries.findIndex((entry) => (entry.children?.length ?? 0) > 0 && getChildReference(entry)?.open);
|
const openChild = (openChildValue !== undefined && flatEntries.findIndex((entry) => entry.value === openChildValue)) || -1;
|
||||||
|
|
||||||
// Allow opening menu with space or enter
|
// Allow opening menu with space or enter
|
||||||
if (!menuOpen && (e.key === " " || e.key === "Enter")) {
|
if (!menuOpen && (e.key === " " || e.key === "Enter")) {
|
||||||
|
|
@ -442,7 +437,7 @@
|
||||||
{#each currentEntries(section, virtualScrollingEntryHeight, virtualScrollingStartIndex, virtualScrollingEndIndex, search) as entry, entryIndex (entryIndex + startIndex)}
|
{#each currentEntries(section, virtualScrollingEntryHeight, virtualScrollingStartIndex, virtualScrollingEndIndex, search) as entry, entryIndex (entryIndex + startIndex)}
|
||||||
<LayoutRow
|
<LayoutRow
|
||||||
class="row"
|
class="row"
|
||||||
classes={{ open: isEntryOpen(entry), active: entry.label === highlighted?.label, disabled: Boolean(entry.disabled) }}
|
classes={{ open: openChildValue === entry.value, active: entry.label === highlighted?.label, disabled: Boolean(entry.disabled) }}
|
||||||
styles={{ height: virtualScrollingEntryHeight || "20px" }}
|
styles={{ height: virtualScrollingEntryHeight || "20px" }}
|
||||||
tooltipLabel={entry.tooltipLabel}
|
tooltipLabel={entry.tooltipLabel}
|
||||||
tooltipDescription={entry.tooltipDescription}
|
tooltipDescription={entry.tooltipDescription}
|
||||||
|
|
@ -454,7 +449,7 @@
|
||||||
{#if entry.icon && drawIcon}
|
{#if entry.icon && drawIcon}
|
||||||
<IconLabel icon={entry.icon} iconSizeOverride={16} class="entry-icon" />
|
<IconLabel icon={entry.icon} iconSizeOverride={16} class="entry-icon" />
|
||||||
{:else if drawIcon}
|
{:else if drawIcon}
|
||||||
<div class="no-icon" />
|
<div class="no-icon"></div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if entry.font}
|
{#if entry.font}
|
||||||
|
|
@ -470,7 +465,7 @@
|
||||||
{#if entry.children?.length}
|
{#if entry.children?.length}
|
||||||
<IconLabel class="submenu-arrow" icon="DropdownArrow" />
|
<IconLabel class="submenu-arrow" icon="DropdownArrow" />
|
||||||
{:else}
|
{:else}
|
||||||
<div class="no-submenu-arrow" />
|
<div class="no-submenu-arrow"></div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if entry.children}
|
{#if entry.children}
|
||||||
|
|
@ -483,7 +478,7 @@
|
||||||
}}
|
}}
|
||||||
on:selectedEntryValuePath={({ detail }) => dispatch("selectedEntryValuePath", detail)}
|
on:selectedEntryValuePath={({ detail }) => dispatch("selectedEntryValuePath", detail)}
|
||||||
parentsValuePath={[...parentsValuePath, entry.value]}
|
parentsValuePath={[...parentsValuePath, entry.value]}
|
||||||
open={getChildReference(entry)?.open || false}
|
open={openChildValue === entry.value}
|
||||||
direction="TopRight"
|
direction="TopRight"
|
||||||
entries={entry.children}
|
entries={entry.children}
|
||||||
entriesHash={entry.childrenHash || 0n}
|
entriesHash={entry.childrenHash || 0n}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher, getContext, onMount } from "svelte";
|
import { createEventDispatcher, getContext, onMount } from "svelte";
|
||||||
|
import { SvelteMap } from "svelte/reactivity";
|
||||||
|
|
||||||
import type { FrontendNodeType } from "@graphite/messages";
|
import type { FrontendNodeType } from "@graphite/messages";
|
||||||
import type { NodeGraphState } from "@graphite/state-providers/node-graph";
|
import type { NodeGraphState } from "@graphite/state-providers/node-graph";
|
||||||
|
|
@ -28,7 +29,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
function buildNodeCategories(nodeTypes: FrontendNodeType[], searchTerm: string): [string, NodeCategoryDetails][] {
|
function buildNodeCategories(nodeTypes: FrontendNodeType[], searchTerm: string): [string, NodeCategoryDetails][] {
|
||||||
const categories = new Map<string, NodeCategoryDetails>();
|
const categories = new SvelteMap<string, NodeCategoryDetails>();
|
||||||
const isTypeSearch = searchTerm.toLowerCase().startsWith("type:");
|
const isTypeSearch = searchTerm.toLowerCase().startsWith("type:");
|
||||||
let typeSearchTerm = "";
|
let typeSearchTerm = "";
|
||||||
let remainingSearchTerms = [searchTerm.toLowerCase()];
|
let remainingSearchTerms = [searchTerm.toLowerCase()];
|
||||||
|
|
|
||||||
|
|
@ -476,7 +476,7 @@
|
||||||
{...$$restProps}
|
{...$$restProps}
|
||||||
>
|
>
|
||||||
{#if displayTail}
|
{#if displayTail}
|
||||||
<div class="tail" bind:this={tail} />
|
<div class="tail" bind:this={tail}></div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if displayContainer}
|
{#if displayContainer}
|
||||||
<div class="floating-menu-container" bind:this={floatingMenuContainer}>
|
<div class="floating-menu-container" bind:this={floatingMenuContainer}>
|
||||||
|
|
|
||||||
|
|
@ -580,7 +580,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
<div class="text-input" style:width={canvasWidthCSS} style:height={canvasHeightCSS} style:pointer-events={showTextInput ? "auto" : ""}>
|
<div class="text-input" style:width={canvasWidthCSS} style:height={canvasHeightCSS} style:pointer-events={showTextInput ? "auto" : ""}>
|
||||||
{#if showTextInput}
|
{#if showTextInput}
|
||||||
<div bind:this={textInput} style:transform="matrix({textInputMatrix})" on:scroll={preventTextEditingScroll} />
|
<div bind:this={textInput} style:transform="matrix({textInputMatrix})" on:scroll={preventTextEditingScroll}></div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{#if !$appWindow.viewportHolePunch}
|
{#if !$appWindow.viewportHolePunch}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getContext, onMount, onDestroy, tick } from "svelte";
|
import { getContext, onMount, onDestroy, tick } from "svelte";
|
||||||
|
import { SvelteMap } from "svelte/reactivity";
|
||||||
|
|
||||||
import type { Editor } from "@graphite/editor";
|
import type { Editor } from "@graphite/editor";
|
||||||
import {
|
import {
|
||||||
|
|
@ -54,7 +55,7 @@
|
||||||
let list: LayoutCol | undefined;
|
let list: LayoutCol | undefined;
|
||||||
|
|
||||||
// Layer data
|
// Layer data
|
||||||
let layerCache = new Map<string, LayerPanelEntry>(); // TODO: replace with BigUint64Array as index
|
let layerCache = new SvelteMap<string, LayerPanelEntry>(); // TODO: replace with BigUint64Array as index
|
||||||
let layers: LayerListingInfo[] = [];
|
let layers: LayerListingInfo[] = [];
|
||||||
|
|
||||||
// Interactive dragging
|
// Interactive dragging
|
||||||
|
|
@ -686,7 +687,7 @@
|
||||||
{/each}
|
{/each}
|
||||||
</LayoutCol>
|
</LayoutCol>
|
||||||
{#if draggingData && !draggingData.highlightFolder && dragInPanel}
|
{#if draggingData && !draggingData.highlightFolder && dragInPanel}
|
||||||
<div class="insert-mark" style:left={`${4 + draggingData.insertDepth * 16}px`} style:top={`${draggingData.markerHeight}px`} />
|
<div class="insert-mark" style:left={`${4 + draggingData.insertDepth * 16}px`} style:top={`${draggingData.markerHeight}px`}></div>
|
||||||
{/if}
|
{/if}
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
<LayoutRow class="bottom-bar" scrollableX={true}>
|
<LayoutRow class="bottom-bar" scrollableX={true}>
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,7 @@
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{#if index > 0}
|
{#if index > 0}
|
||||||
<div class="reorder-drag-grip" data-tooltip-description="Reorder this export" />
|
<div class="reorder-drag-grip" data-tooltip-description="Reorder this export"></div>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -396,7 +396,7 @@
|
||||||
>
|
>
|
||||||
{#if (hoveringExportIndex === index || editingNameExportIndex === index) && $nodeGraph.updateImportsExports.addImportExport}
|
{#if (hoveringExportIndex === index || editingNameExportIndex === index) && $nodeGraph.updateImportsExports.addImportExport}
|
||||||
{#if index > 0}
|
{#if index > 0}
|
||||||
<div class="reorder-drag-grip" data-tooltip-description="Reorder this export" />
|
<div class="reorder-drag-grip" data-tooltip-description="Reorder this export"></div>
|
||||||
{/if}
|
{/if}
|
||||||
<IconButton
|
<IconButton
|
||||||
size={16}
|
size={16}
|
||||||
|
|
@ -457,7 +457,7 @@
|
||||||
x: Number($nodeGraph.updateImportsExports.importPosition.x),
|
x: Number($nodeGraph.updateImportsExports.importPosition.x),
|
||||||
y: Number($nodeGraph.updateImportsExports.importPosition.y) + Number($nodeGraph.reorderImportIndex) * 24,
|
y: Number($nodeGraph.updateImportsExports.importPosition.y) + Number($nodeGraph.reorderImportIndex) * 24,
|
||||||
}}
|
}}
|
||||||
<div class="reorder-bar" style:--offset-left={(position.x - 48) / 24} style:--offset-top={(position.y - 12) / 24} />
|
<div class="reorder-bar" style:--offset-left={(position.x - 48) / 24} style:--offset-top={(position.y - 12) / 24}></div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if $nodeGraph.reorderExportIndex !== undefined}
|
{#if $nodeGraph.reorderExportIndex !== undefined}
|
||||||
|
|
@ -465,7 +465,7 @@
|
||||||
x: Number($nodeGraph.updateImportsExports.exportPosition.x),
|
x: Number($nodeGraph.updateImportsExports.exportPosition.x),
|
||||||
y: Number($nodeGraph.updateImportsExports.exportPosition.y) + Number($nodeGraph.reorderExportIndex) * 24,
|
y: Number($nodeGraph.updateImportsExports.exportPosition.y) + Number($nodeGraph.reorderExportIndex) * 24,
|
||||||
}}
|
}}
|
||||||
<div class="reorder-bar" style:--offset-left={position.x / 24} style:--offset-top={(position.y - 12) / 24} />
|
<div class="reorder-bar" style:--offset-left={position.x / 24} style:--offset-top={(position.y - 12) / 24}></div>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
<!-- TODO: Implement collapsable sections with properties system -->
|
<!-- TODO: Implement collapsable sections with properties system -->
|
||||||
<LayoutCol class={`widget-section ${className}`.trim()} {classes}>
|
<LayoutCol class={`widget-section ${className}`.trim()} {classes}>
|
||||||
<button class="header" class:expanded on:click|stopPropagation={() => (expanded = !expanded)} tabindex="0">
|
<button class="header" class:expanded on:click|stopPropagation={() => (expanded = !expanded)} tabindex="0">
|
||||||
<div class="expand-arrow" />
|
<div class="expand-arrow"></div>
|
||||||
<TextLabel tooltipLabel={widgetData.name} tooltipDescription={widgetData.description} bold={true}>{widgetData.name}</TextLabel>
|
<TextLabel tooltipLabel={widgetData.name} tooltipDescription={widgetData.description} bold={true}>{widgetData.name}</TextLabel>
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={widgetData.pinned ? "PinActive" : "PinInactive"}
|
icon={widgetData.pinned ? "PinActive" : "PinInactive"}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
const dispatch = createEventDispatcher<{ selectedEntryValuePath: string[] }>();
|
const dispatch = createEventDispatcher<{ selectedEntryValuePath: string[] }>();
|
||||||
|
|
||||||
let self: MenuList;
|
let self: MenuList;
|
||||||
|
let open = false;
|
||||||
|
|
||||||
// Note: IconButton should instead be used if only an icon, but no label, is desired.
|
// Note: IconButton should instead be used if only an icon, but no label, is desired.
|
||||||
// However, if multiple TextButton widgets are used in a group with only some having no label, this component is able to accommodate that.
|
// However, if multiple TextButton widgets are used in a group with only some having no label, this component is able to accommodate that.
|
||||||
|
|
@ -93,9 +94,9 @@
|
||||||
</button>
|
</button>
|
||||||
{#if menuListChildrenExists}
|
{#if menuListChildrenExists}
|
||||||
<MenuList
|
<MenuList
|
||||||
on:open={({ detail }) => self && (self.open = detail)}
|
|
||||||
on:selectedEntryValuePath={({ detail }) => dispatch("selectedEntryValuePath", detail)}
|
on:selectedEntryValuePath={({ detail }) => dispatch("selectedEntryValuePath", detail)}
|
||||||
open={self?.open || false}
|
on:open={({ detail }) => (open = detail)}
|
||||||
|
{open}
|
||||||
entries={menuListChildren || []}
|
entries={menuListChildren || []}
|
||||||
entriesHash={menuListChildrenHash || 0n}
|
entriesHash={menuListChildrenHash || 0n}
|
||||||
direction="Bottom"
|
direction="Bottom"
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@
|
||||||
on:keydown={(e) => e.key === "Escape" && cancel()}
|
on:keydown={(e) => e.key === "Escape" && cancel()}
|
||||||
on:pointerdown
|
on:pointerdown
|
||||||
on:contextmenu={(e) => hideContextMenu && e.preventDefault()}
|
on:contextmenu={(e) => hideContextMenu && e.preventDefault()}
|
||||||
/>
|
></textarea>
|
||||||
{/if}
|
{/if}
|
||||||
{#if label}
|
{#if label}
|
||||||
<label for={`field-input-${id}`} on:pointerdown>{label}</label>
|
<label for={`field-input-${id}`} on:pointerdown>{label}</label>
|
||||||
|
|
|
||||||
|
|
@ -754,9 +754,9 @@
|
||||||
bind:this={inputRangeElement}
|
bind:this={inputRangeElement}
|
||||||
/>
|
/>
|
||||||
{#if rangeSliderClickDragState === "Deciding"}
|
{#if rangeSliderClickDragState === "Deciding"}
|
||||||
<div class="fake-slider-thumb" />
|
<div class="fake-slider-thumb"></div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="slider-progress" />
|
<div class="slider-progress"></div>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</FieldInput>
|
</FieldInput>
|
||||||
|
|
|
||||||
|
|
@ -25,15 +25,15 @@
|
||||||
data-tooltip-description={tooltipDescription}
|
data-tooltip-description={tooltipDescription}
|
||||||
data-tooltip-shortcut={tooltipShortcut?.shortcut ? JSON.stringify(tooltipShortcut.shortcut) : undefined}
|
data-tooltip-shortcut={tooltipShortcut?.shortcut ? JSON.stringify(tooltipShortcut.shortcut) : undefined}
|
||||||
>
|
>
|
||||||
<button on:click={() => setValue("TopLeft")} class="row-1 col-1" class:active={value === "TopLeft"} tabindex="-1" {disabled}><div /></button>
|
<button on:click={() => setValue("TopLeft")} class="row-1 col-1" class:active={value === "TopLeft"} tabindex="-1" {disabled}><div></div></button>
|
||||||
<button on:click={() => setValue("TopCenter")} class="row-1 col-2" class:active={value === "TopCenter"} tabindex="-1" {disabled}><div /></button>
|
<button on:click={() => setValue("TopCenter")} class="row-1 col-2" class:active={value === "TopCenter"} tabindex="-1" {disabled}><div></div></button>
|
||||||
<button on:click={() => setValue("TopRight")} class="row-1 col-3" class:active={value === "TopRight"} tabindex="-1" {disabled}><div /></button>
|
<button on:click={() => setValue("TopRight")} class="row-1 col-3" class:active={value === "TopRight"} tabindex="-1" {disabled}><div></div></button>
|
||||||
<button on:click={() => setValue("CenterLeft")} class="row-2 col-1" class:active={value === "CenterLeft"} tabindex="-1" {disabled}><div /></button>
|
<button on:click={() => setValue("CenterLeft")} class="row-2 col-1" class:active={value === "CenterLeft"} tabindex="-1" {disabled}><div></div></button>
|
||||||
<button on:click={() => setValue("Center")} class="row-2 col-2" class:active={value === "Center"} tabindex="-1" {disabled}><div /></button>
|
<button on:click={() => setValue("Center")} class="row-2 col-2" class:active={value === "Center"} tabindex="-1" {disabled}><div></div></button>
|
||||||
<button on:click={() => setValue("CenterRight")} class="row-2 col-3" class:active={value === "CenterRight"} tabindex="-1" {disabled}><div /></button>
|
<button on:click={() => setValue("CenterRight")} class="row-2 col-3" class:active={value === "CenterRight"} tabindex="-1" {disabled}><div></div></button>
|
||||||
<button on:click={() => setValue("BottomLeft")} class="row-3 col-1" class:active={value === "BottomLeft"} tabindex="-1" {disabled}><div /></button>
|
<button on:click={() => setValue("BottomLeft")} class="row-3 col-1" class:active={value === "BottomLeft"} tabindex="-1" {disabled}><div></div></button>
|
||||||
<button on:click={() => setValue("BottomCenter")} class="row-3 col-2" class:active={value === "BottomCenter"} tabindex="-1" {disabled}><div /></button>
|
<button on:click={() => setValue("BottomCenter")} class="row-3 col-2" class:active={value === "BottomCenter"} tabindex="-1" {disabled}><div></div></button>
|
||||||
<button on:click={() => setValue("BottomRight")} class="row-3 col-3" class:active={value === "BottomRight"} tabindex="-1" {disabled}><div /></button>
|
<button on:click={() => setValue("BottomRight")} class="row-3 col-3" class:active={value === "BottomRight"} tabindex="-1" {disabled}><div></div></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="scss" global>
|
<style lang="scss" global>
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@
|
||||||
<div class={`scrollbar-input ${direction.toLowerCase()}`}>
|
<div class={`scrollbar-input ${direction.toLowerCase()}`}>
|
||||||
<button class="arrow decrease" on:pointerdown={() => pressArrow(-1)} tabindex="-1" data-scrollbar-arrow></button>
|
<button class="arrow decrease" on:pointerdown={() => pressArrow(-1)} tabindex="-1" data-scrollbar-arrow></button>
|
||||||
<div class="scroll-track" on:pointerdown={pressTrack} bind:this={scrollTrack}>
|
<div class="scroll-track" on:pointerdown={pressTrack} bind:this={scrollTrack}>
|
||||||
<div class="scroll-thumb" on:pointerdown={dragThumb} class:dragging style:top={thumbTop} style:bottom={thumbBottom} style:left={thumbLeft} style:right={thumbRight} />
|
<div class="scroll-thumb" on:pointerdown={dragThumb} class:dragging style:top={thumbTop} style:bottom={thumbBottom} style:left={thumbLeft} style:right={thumbRight}></div>
|
||||||
</div>
|
</div>
|
||||||
<button class="arrow increase" on:pointerdown={() => pressArrow(1)} tabindex="-1" data-scrollbar-arrow></button>
|
<button class="arrow increase" on:pointerdown={() => pressArrow(1)} tabindex="-1" data-scrollbar-arrow></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
<div class={`separator ${direction.toLowerCase()} ${style.toLowerCase()}`}>
|
<div class={`separator ${direction.toLowerCase()} ${style.toLowerCase()}`}>
|
||||||
{#if style === "Section"}
|
{#if style === "Section"}
|
||||||
<div />
|
<div></div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,10 @@
|
||||||
// It is needed for class-transformer to work and is imported as a side effect.
|
// It is needed for class-transformer to work and is imported as a side effect.
|
||||||
// The library replaces the Reflect API on the window to support more features.
|
// The library replaces the Reflect API on the window to support more features.
|
||||||
import "reflect-metadata";
|
import "reflect-metadata";
|
||||||
|
import { mount } from "svelte";
|
||||||
|
|
||||||
import App from "@graphite/App.svelte";
|
import App from "@graphite/App.svelte";
|
||||||
|
|
||||||
document.body.setAttribute("data-app-container", "");
|
document.body.setAttribute("data-app-container", "");
|
||||||
|
|
||||||
export default new App({ target: document.body });
|
export default mount(App, { target: document.body });
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,9 @@ export default defineConfig(({ mode }) => {
|
||||||
"a11y-no-static-element-interactions", // NOTICE: Keep this list in sync with the list in `.vscode/settings.json`
|
"a11y-no-static-element-interactions", // NOTICE: Keep this list in sync with the list in `.vscode/settings.json`
|
||||||
"a11y-no-noninteractive-element-interactions", // NOTICE: Keep this list in sync with the list in `.vscode/settings.json`
|
"a11y-no-noninteractive-element-interactions", // NOTICE: Keep this list in sync with the list in `.vscode/settings.json`
|
||||||
"a11y-click-events-have-key-events", // NOTICE: Keep this list in sync with the list in `.vscode/settings.json`
|
"a11y-click-events-have-key-events", // NOTICE: Keep this list in sync with the list in `.vscode/settings.json`
|
||||||
|
"a11y_consider_explicit_label", // NOTICE: Keep this list in sync with the list in `.vscode/settings.json`
|
||||||
|
"a11y_click_events_have_key_events", // NOTICE: Keep this list in sync with the list in `.vscode/settings.json`
|
||||||
|
"a11y_no_noninteractive_element_interactions", // NOTICE: Keep this list in sync with the list in `.vscode/settings.json`
|
||||||
];
|
];
|
||||||
if (suppressed.includes(warning.code)) return;
|
if (suppressed.includes(warning.code)) return;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue