Refactor the TypeScript data flow for full type safety and auto-generation of Rust types (#3865)

* Migrate Specta to Tsify to auto-generate messages.ts, working except colors and widgets

* Adopt the generated FillColor/Color/GradientStops

* Fix widget typing

* Separate WidgetGroup enum variants into wrapper structs

* Small rename

* Simplify widgets further

* Clean up message type references

* Switch type imports to the auto-generated file

* Remove lowercase serde rename

* Fix FillChoice deserialization

* Fix small regression from #3837

* Improve type safety

* Make WidgetSpan type-safe

* More cleanup and type safety

* More type safety

* More type safety

* Get the rest to type-check without errors; improve widget builder macro to have optional icons; improve Svelte 5 configs

* Cargo fmt

* Fix imports

* Update outdated readme info

* Fix lint command rename references

* Fix typos

* One more typos fix

* Remove unnecessary dep: prefix from the edited Cargo.toml files

* Remove excess parts from Cargo.toml

* Fix compiling on desktop

* Revert "Remove excess parts from Cargo.toml"

This reverts commit 6b711117b3a5d5d8a3ee20f36a43bc74930b7c82.

* Update dev docs with simpler, more accurate instructions
This commit is contained in:
Keavon Chambers
2026-03-09 16:35:04 -07:00
parent fbd2658148
commit 52d2b38a82
199 changed files with 2265 additions and 2811 deletions
@@ -1,6 +1,4 @@
<script lang="ts" context="module">
export type MenuType = "Popover" | "Tooltip" | "Dropdown" | "Dialog" | "Cursor";
/// Prevents the escape key from closing the parent floating menu of the given element.
/// This works by momentarily setting the `data-escape-does-not-close` attribute on the parent floating menu element.
/// After checking for the Escape key, it checks (in one `setTimeout`) for the attribute and ignores the key if it's present.
@@ -21,7 +19,7 @@
<script lang="ts">
import { onMount, afterUpdate, createEventDispatcher, tick } from "svelte";
import type { MenuDirection } from "@graphite/messages";
import type { MenuDirection } from "@graphite/../wasm/pkg/graphite_wasm";
import { browserVersion } from "@graphite/utility-functions/platform";
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
@@ -38,7 +36,7 @@
export { styleName as style };
export let styles: Record<string, string | number | undefined> = {};
export let open: boolean;
export let type: MenuType;
export let type: "Popover" | "Tooltip" | "Dropdown" | "Dialog" | "Cursor";
export let direction: MenuDirection = "Bottom";
export let windowEdgeMargin = 6;
export let scrollableY = false;
@@ -309,7 +307,7 @@
function pointerMoveHandler(e: PointerEvent) {
// This element and the element being hovered over
const target = e.target as HTMLElement | undefined;
const target = e.target instanceof HTMLElement ? e.target : undefined;
// Get the spawner element (that which is clicked to spawn this floating menu)
// Assumes the spawner is a sibling of this FloatingMenu component
@@ -398,9 +396,9 @@
else {
const foundTarget = filteredListOfDescendantSpawners.find((item: Element): boolean => item === targetSpawner);
// If the currently hovered spawner is one of the found valid hover-transferrable spawners, swap to it by clicking on it
if (foundTarget) {
if (foundTarget instanceof HTMLElement) {
dispatch("open", false);
(foundTarget as HTMLElement).click();
foundTarget.click();
}
// In either case, we are done searching
@@ -1,5 +1,5 @@
<script lang="ts">
import type { ActionShortcut } from "@graphite/messages";
import type { ActionShortcut } from "@graphite/../wasm/pkg/graphite_wasm";
let className = "";
export { className as class };
@@ -1,5 +1,5 @@
<script lang="ts">
import type { ActionShortcut } from "@graphite/messages";
import type { ActionShortcut } from "@graphite/../wasm/pkg/graphite_wasm";
let className = "";
export { className as class };