diff --git a/.changeset/cursor-solid2-migration.md b/.changeset/cursor-solid2-migration.md new file mode 100644 index 000000000..c5a0427a8 --- /dev/null +++ b/.changeset/cursor-solid2-migration.md @@ -0,0 +1,19 @@ +--- +"@solid-primitives/cursor": major +--- + +Migrate to Solid.js v2.0 and add new primitives + +## Breaking Changes + +**Peer dependency**: `solid-js@^2.0.0-beta.10` and `@solidjs/web@^2.0.0-beta.10` are now required. + +- `isServer` now imported from `@solidjs/web` (not `solid-js/web`) +- `createElementCursor` and `createBodyCursor` updated to the split compute/apply effect pattern required by Solid 2.0 — cleanup is returned from the apply phase instead of using `onCleanup` + +## New Exports + +- `makeBodyCursor(cursor)` — sets cursor on body immediately, returns a cleanup function +- `makeElementCursor(target, cursor)` — sets cursor on an element immediately, returns a cleanup function +- `createDragCursor(target, options?)` — reactively sets `"grab"` on a target element and switches to `"grabbing"` on the body during pointer drag +- `cursorRef(cursor)` — ref factory for inline JSX use: `
` diff --git a/packages/cursor/README.md b/packages/cursor/README.md index e01d17576..ab29ddfc3 100644 --- a/packages/cursor/README.md +++ b/packages/cursor/README.md @@ -8,10 +8,14 @@ [![version](https://img.shields.io/npm/v/@solid-primitives/cursor?style=for-the-badge)](https://www.npmjs.com/package/@solid-primitives/cursor) [![stage](https://img.shields.io/endpoint?style=for-the-badge&url=https%3A%2F%2Fraw.githubusercontent.com%2Fsolidjs-community%2Fsolid-primitives%2Fmain%2Fassets%2Fbadges%2Fstage-0.json)](https://github.com/solidjs-community/solid-primitives#contribution-process) -Two simple primitives for setting cursor css property reactively. +Primitives for setting the CSS cursor property reactively. -- [`createElementCursor`](#createelementcursor) - Set provided cursor to given HTML Element styles reactively. -- [`createBodyCursor`](#createbodycursor) - Set selected cursor to body element styles reactively. +- [`makeBodyCursor`](#makebodycursor) - Set cursor on body immediately; returns a cleanup function. +- [`makeElementCursor`](#makeelementcursor) - Set cursor on an element immediately; returns a cleanup function. +- [`createBodyCursor`](#createbodycursor) - Set cursor on body reactively. +- [`createElementCursor`](#createelementcursor) - Set cursor on a specific element reactively. +- [`createDragCursor`](#createdragcursor) - Show `grab`/`grabbing` cursors during pointer drag. +- [`cursorRef`](#cursorref) - Ref factory for inline JSX use. ## Installation @@ -23,14 +27,50 @@ yarn add @solid-primitives/cursor pnpm add @solid-primitives/cursor ``` -## `createElementCursor` +## `makeBodyCursor` + +Sets a cursor on the body element immediately and returns a cleanup function that restores the previous value. No reactive owner required. + +```ts +import { makeBodyCursor } from "@solid-primitives/cursor"; + +// Show a loading cursor during an async operation +const restore = makeBodyCursor("wait"); +await doSomething(); +restore(); +``` + +## `makeElementCursor` + +Sets a cursor on a specific element immediately and returns a cleanup function that restores the previous value. No reactive owner required. + +```ts +import { makeElementCursor } from "@solid-primitives/cursor"; + +const el = document.querySelector("#element")!; +const restore = makeElementCursor(el, "not-allowed"); +// ... later +restore(); +``` + +## `createBodyCursor` + +Sets a cursor on the body element reactively. The cursor is removed when the owner is disposed or when the signal returns a falsy value. + +```ts +import { createBodyCursor } from "@solid-primitives/cursor"; + +const [cursor, setCursor] = createSignal("pointer"); +const [enabled, setEnabled] = createSignal(true); + +createBodyCursor(() => enabled() && cursor()); -Set provided cursor to given HTML Element styles reactively. +setCursor("help"); +``` -It takes two arguments: +## `createElementCursor` -- `element` - HTMLElement or a reactive signal returning one. Returning falsy value will unset the cursor. -- `cursor` - Cursor css property. E.g. "pointer", "grab", "zoom-in", "wait", etc. +Sets a cursor on a specific element reactively. Accepts an element or a signal returning one — returning a falsy value unsets the cursor. ```ts import { createElementCursor } from "@solid-primitives/cursor"; @@ -44,23 +84,39 @@ createElementCursor(() => enabled() && target, cursor); setCursor("help"); ``` -## `createBodyCursor` +## `createDragCursor` + +Shows `"grab"` on a target element and switches to `"grabbing"` on the body during a pointer drag. Setting `"grabbing"` on the body ensures the cursor renders correctly everywhere during drag, not just over the target element. + +```ts +import { createDragCursor } from "@solid-primitives/cursor"; -Set selected cursor to body element styles reactively. +const [ref, setRef] = createSignal(); -It takes only one argument: +createDragCursor(ref); -- `cursor` - Signal returing a cursor css property. E.g. "pointer", "grab", "zoom-in", "wait", etc. Returning falsy value will unset the cursor. +
Drag me
+``` + +Custom cursor values can be provided via options: ```ts -import { createBodyCursor } from "@solid-primitives/cursor"; +createDragCursor(el, { grab: "crosshair", grabbing: "move" }); +``` -const [cursor, setCursor] = createSignal("pointer"); -const [enabled, setEnabled] = createSignal(true); +## `cursorRef` -createBodyCursor(() => enabled() && cursor()); +A ref factory for setting a cursor inline in JSX. Accepts a static cursor value or a reactive signal. The cursor is removed when the component unmounts. -setCursor("help"); +```tsx +import { cursorRef } from "@solid-primitives/cursor"; + +// Static +
...
; + +// Reactive +const [cursor, setCursor] = createSignal("pointer"); +
...
; ``` ## Changelog diff --git a/packages/cursor/package.json b/packages/cursor/package.json index ca52fabee..aa94e4c71 100644 --- a/packages/cursor/package.json +++ b/packages/cursor/package.json @@ -1,7 +1,7 @@ { "name": "@solid-primitives/cursor", - "version": "0.1.3", - "description": "Two simple primitives for setting cursor css property reactively.", + "version": "0.2.0", + "description": "Primitives for setting CSS cursor property reactively.", "author": "Damian Tarnawski ", "contributors": [], "license": "MIT", @@ -17,8 +17,12 @@ "name": "cursor", "stage": 0, "list": [ + "makeBodyCursor", + "makeElementCursor", + "createBodyCursor", "createElementCursor", - "createBodyCursor" + "createDragCursor", + "cursorRef" ], "category": "Utilities" }, @@ -55,10 +59,12 @@ "@solid-primitives/utils": "workspace:^" }, "peerDependencies": { - "solid-js": "^1.6.12" + "@solidjs/web": "^2.0.0-beta.10", + "solid-js": "^2.0.0-beta.10" }, "typesVersions": {}, "devDependencies": { - "solid-js": "^1.9.7" + "@solidjs/web": "2.0.0-beta.10", + "solid-js": "2.0.0-beta.10" } } diff --git a/packages/cursor/src/index.ts b/packages/cursor/src/index.ts index 6420521bb..1f35c6474 100644 --- a/packages/cursor/src/index.ts +++ b/packages/cursor/src/index.ts @@ -1,6 +1,6 @@ -import { type Accessor, createEffect, onCleanup } from "solid-js"; -import { isServer } from "solid-js/web"; -import { access, type FalsyValue, type MaybeAccessor } from "@solid-primitives/utils"; +import { type Accessor, createEffect, createSignal } from "solid-js"; +import { isServer } from "@solidjs/web"; +import { access, noop, type FalsyValue, type MaybeAccessor } from "@solid-primitives/utils"; export type CursorProperty = | "-moz-grab" @@ -43,6 +43,47 @@ export type CursorProperty = | "zoom-out" | (string & {}); +/** + * Set selected {@link cursor} to body element styles immediately. + * + * Returns a cleanup function that restores the previous cursor. + * + * @param cursor Cursor css property. E.g. "pointer", "grab", "zoom-in", "wait", etc. + * + * @example + * ```ts + * const restore = makeBodyCursor("wait"); + * // ... async operation ... + * restore(); + * ``` + */ +export function makeBodyCursor(cursor: CursorProperty): VoidFunction { + if (isServer) return noop; + return makeElementCursor(document.body, cursor); +} + +/** + * Set selected {@link cursor} to {@link target} element styles immediately. + * + * Returns a cleanup function that restores the previous cursor. + * + * @param target HTMLElement to set the cursor on. + * @param cursor Cursor css property. E.g. "pointer", "grab", "zoom-in", "wait", etc. + * + * @example + * ```ts + * const restore = makeElementCursor(el, "wait"); + * // ... async operation ... + * restore(); + * ``` + */ +export function makeElementCursor(target: HTMLElement, cursor: CursorProperty): VoidFunction { + if (isServer) return noop; + const overwritten = target.style.cursor; + target.style.setProperty("cursor", cursor, "important"); + return () => (target.style.cursor = overwritten); +} + /** * Set selected {@link cursor} to {@link target} styles reactively. * @@ -66,14 +107,21 @@ export function createElementCursor( ): void { if (isServer) return; - createEffect(() => { - const el = access(target); - const cursorValue = access(cursor); + type State = { el: HTMLElement | FalsyValue; cursorValue: CursorProperty }; + + const compute = (): State => ({ + el: access(target), + cursorValue: access(cursor), + }); + + const apply = ({ el, cursorValue }: State) => { if (!el) return; const overwritten = el.style.cursor; el.style.setProperty("cursor", cursorValue, "important"); - onCleanup(() => (el.style.cursor = overwritten)); - }); + return () => (el.style.cursor = overwritten); + }; + + createEffect(compute, apply); } /** @@ -94,11 +142,85 @@ export function createElementCursor( export function createBodyCursor(cursor: Accessor): void { if (isServer) return; - createEffect(() => { - const cursorValue = cursor(); + createEffect(cursor, cursorValue => { if (!cursorValue) return; const overwritten = document.body.style.cursor; document.body.style.setProperty("cursor", cursorValue, "important"); - onCleanup(() => (document.body.style.cursor = overwritten)); + return () => (document.body.style.cursor = overwritten); }); } + +/** + * Reactively sets "grab" cursor on {@link target} and switches to "grabbing" on the body during drag. + * + * Setting "grabbing" on the body ensures the cursor renders correctly everywhere during drag, + * not just over the target element. + * + * @param target HTMLElement or a reactive signal returning one. Returning falsy value will disable the cursor. + * @param options Optional overrides for the grab and grabbing cursor values. + * + * @example + * ```ts + * const [ref, setRef] = createSignal(); + * + * createDragCursor(ref); + * + *
Drag me
+ * ``` + */ +export function createDragCursor( + target: Accessor | HTMLElement, + options?: { grab?: CursorProperty; grabbing?: CursorProperty }, +): void { + if (isServer) return; + + const grab = options?.grab ?? "grab"; + const grabbing = options?.grabbing ?? "grabbing"; + const [dragging, setDragging] = createSignal(false); + + // During drag, "grabbing" is set on body so it shows globally. + // "grab" is cleared from the element so the body cursor can inherit through — + // element inline styles (even without !important) would otherwise win over body. + createBodyCursor(() => dragging() && grabbing); + createElementCursor(() => { + const el = access(target); + return dragging() ? false : el; + }, grab); + + createEffect( + () => access(target), + el => { + if (!el) return; + const onDown = () => setDragging(true); + const onUp = () => setDragging(false); + el.addEventListener("pointerdown", onDown); + document.addEventListener("pointerup", onUp); + document.addEventListener("pointercancel", onUp); + return () => { + el.removeEventListener("pointerdown", onDown); + document.removeEventListener("pointerup", onUp); + document.removeEventListener("pointercancel", onUp); + }; + }, + ); +} + +/** + * Returns a ref callback that sets a cursor on the element it is attached to. + * + * Accepts a static cursor value or a reactive signal. The cursor is removed when the + * component unmounts. + * + * @example + * ```tsx + * // static + *
...
+ * + * // reactive + * const [cursor, setCursor] = createSignal("pointer"); + *
...
+ * ``` + */ +export function cursorRef(cursor: MaybeAccessor): (el: HTMLElement) => void { + return el => createElementCursor(el, cursor); +} diff --git a/packages/cursor/test/index.test.ts b/packages/cursor/test/index.test.ts index 019cb787c..8d3fff1ef 100644 --- a/packages/cursor/test/index.test.ts +++ b/packages/cursor/test/index.test.ts @@ -1,6 +1,54 @@ import { describe, test, expect } from "vitest"; -import { createRoot, createSignal } from "solid-js"; -import { createBodyCursor, createElementCursor, CursorProperty } from "../src/index.js"; +import { createRoot, createSignal, flush } from "solid-js"; +import { + createBodyCursor, + createDragCursor, + createElementCursor, + cursorRef, + makeBodyCursor, + makeElementCursor, + type CursorProperty, +} from "../src/index.js"; + +describe("makeBodyCursor", () => { + test("sets cursor and returns cleanup", () => { + const restore = makeBodyCursor("pointer"); + expect(document.body.style.cursor).toBe("pointer"); + restore(); + expect(document.body.style.cursor).toBe(""); + }); + + test("restores nested cursors in stack order", () => { + const restore1 = makeBodyCursor("pointer"); + const restore2 = makeBodyCursor("help"); + expect(document.body.style.cursor).toBe("help"); + restore2(); + expect(document.body.style.cursor).toBe("pointer"); + restore1(); + expect(document.body.style.cursor).toBe(""); + }); +}); + +describe("makeElementCursor", () => { + test("sets cursor on element and returns cleanup", () => { + const el = document.createElement("div"); + const restore = makeElementCursor(el, "pointer"); + expect(el.style.cursor).toBe("pointer"); + restore(); + expect(el.style.cursor).toBe(""); + }); + + test("restores previous cursor value", () => { + const el = document.createElement("div"); + const restore1 = makeElementCursor(el, "pointer"); + const restore2 = makeElementCursor(el, "help"); + expect(el.style.cursor).toBe("help"); + restore2(); + expect(el.style.cursor).toBe("pointer"); + restore1(); + expect(el.style.cursor).toBe(""); + }); +}); describe("createBodyCursor", () => { test("switches previous cursor to provided one", () => { @@ -11,16 +59,20 @@ describe("createBodyCursor", () => { createBodyCursor(() => enabled() && cursor()); return dispose; }); + flush(); expect(document.body.style.cursor).toBe("pointer"); setCursor("help"); + flush(); expect(document.body.style.cursor).toBe("help"); setEnabled(false); + flush(); expect(document.body.style.cursor, "unsets cursor").toBe(""); setEnabled(true); + flush(); expect(document.body.style.cursor).toBe("help"); dispose(); @@ -38,16 +90,20 @@ describe("createElementCursor", () => { createElementCursor(() => enabled() && div, cursor); return dispose; }); + flush(); expect(div.style.cursor).toBe("pointer"); setCursor("help"); + flush(); expect(div.style.cursor).toBe("help"); setEnabled(false); + flush(); expect(div.style.cursor, "unsets cursor").toBe(""); setEnabled(true); + flush(); expect(div.style.cursor).toBe("help"); dispose(); @@ -65,28 +121,35 @@ describe("createElementCursor", () => { createElementCursor(() => enabled() && target(), cursor); return dispose; }); + flush(); expect(div1.style.cursor).toBe("pointer"); setCursor("help"); + flush(); expect(div1.style.cursor).toBe("help"); setTarget(div2); + flush(); expect(div1.style.cursor).toBe(""); expect(div2.style.cursor).toBe("help"); setEnabled(false); + flush(); expect(div2.style.cursor).toBe(""); setTarget(div1); + flush(); expect(div1.style.cursor).toBe(""); expect(div2.style.cursor).toBe(""); setCursor("pointer"); + flush(); expect(div1.style.cursor).toBe(""); expect(div2.style.cursor).toBe(""); setEnabled(true); + flush(); expect(div1.style.cursor).toBe("pointer"); expect(div2.style.cursor).toBe(""); @@ -94,3 +157,129 @@ describe("createElementCursor", () => { expect(div1.style.cursor).toBe(""); }); }); + +describe("createDragCursor", () => { + test("shows grab/grabbing cursors during drag", () => { + const el = document.createElement("div"); + + const dispose = createRoot(dispose => { + createDragCursor(el); + return dispose; + }); + flush(); + + expect(el.style.cursor).toBe("grab"); + expect(document.body.style.cursor).toBe(""); + + el.dispatchEvent(new Event("pointerdown")); + flush(); + expect(document.body.style.cursor).toBe("grabbing"); + expect(el.style.cursor).toBe(""); + + document.dispatchEvent(new Event("pointerup")); + flush(); + expect(document.body.style.cursor).toBe(""); + expect(el.style.cursor).toBe("grab"); + + dispose(); + expect(el.style.cursor).toBe(""); + }); + + test("resets on pointercancel", () => { + const el = document.createElement("div"); + + const dispose = createRoot(dispose => { + createDragCursor(el); + return dispose; + }); + flush(); + + el.dispatchEvent(new Event("pointerdown")); + flush(); + expect(document.body.style.cursor).toBe("grabbing"); + + document.dispatchEvent(new Event("pointercancel")); + flush(); + expect(document.body.style.cursor).toBe(""); + expect(el.style.cursor).toBe("grab"); + + dispose(); + }); + + test("supports custom cursor values", () => { + const el = document.createElement("div"); + + const dispose = createRoot(dispose => { + createDragCursor(el, { grab: "crosshair", grabbing: "move" }); + return dispose; + }); + flush(); + + expect(el.style.cursor).toBe("crosshair"); + + el.dispatchEvent(new Event("pointerdown")); + flush(); + expect(document.body.style.cursor).toBe("move"); + + document.dispatchEvent(new Event("pointerup")); + flush(); + expect(el.style.cursor).toBe("crosshair"); + + dispose(); + }); + + test("cleans up listeners and cursors on dispose", () => { + const el = document.createElement("div"); + + const dispose = createRoot(dispose => { + createDragCursor(el); + return dispose; + }); + flush(); + + dispose(); + expect(el.style.cursor).toBe(""); + expect(document.body.style.cursor).toBe(""); + + el.dispatchEvent(new Event("pointerdown")); + flush(); + expect(document.body.style.cursor).toBe(""); + }); +}); + +describe("cursorRef", () => { + test("applies cursor to element", () => { + const el = document.createElement("div"); + + const dispose = createRoot(dispose => { + cursorRef("pointer")(el); + return dispose; + }); + flush(); + + expect(el.style.cursor).toBe("pointer"); + + dispose(); + expect(el.style.cursor).toBe(""); + }); + + test("reacts to cursor signal changes", () => { + const el = document.createElement("div"); + const [cursor, setCursor] = createSignal("pointer"); + + const dispose = createRoot(dispose => { + cursorRef(cursor)(el); + return dispose; + }); + flush(); + + expect(el.style.cursor).toBe("pointer"); + + setCursor("help"); + flush(); + expect(el.style.cursor).toBe("help"); + + dispose(); + expect(el.style.cursor).toBe(""); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 726871879..ef69d507f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -211,9 +211,12 @@ importers: specifier: workspace:^ version: link:../utils devDependencies: + '@solidjs/web': + specifier: 2.0.0-beta.10 + version: 2.0.0-beta.10(solid-js@2.0.0-beta.10) solid-js: - specifier: ^1.9.7 - version: 1.9.7 + specifier: 2.0.0-beta.10 + version: 2.0.0-beta.10 packages/date: dependencies: @@ -2366,36 +2369,42 @@ packages: engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm-musl@2.5.1': resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [musl] '@parcel/watcher-linux-arm64-glibc@2.5.1': resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm64-musl@2.5.1': resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [musl] '@parcel/watcher-linux-x64-glibc@2.5.1': resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-x64-musl@2.5.1': resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [musl] '@parcel/watcher-wasm@2.3.0': resolution: {integrity: sha512-ejBAX8H0ZGsD8lSICDNyMbSEtPMWgDL0WFCt/0z7hyf5v8Imz4rAM8xY379mBsECkq/Wdqa5WEDLqtjZ+6NxfA==} @@ -2506,36 +2515,42 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': resolution: {integrity: sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': resolution: {integrity: sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': resolution: {integrity: sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': resolution: {integrity: sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': resolution: {integrity: sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': resolution: {integrity: sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==} @@ -2672,56 +2687,67 @@ packages: resolution: {integrity: sha512-gTJ/JnnjCMc15uwB10TTATBEhK9meBIY+gXP4s0sHD1zHOaIh4Dmy1X9wup18IiY9tTNk5gJc4yx9ctj/fjrIw==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.43.0': resolution: {integrity: sha512-ZJ3gZynL1LDSIvRfz0qXtTNs56n5DI2Mq+WACWZ7yGHFUEirHBRt7fyIk0NsCKhmRhn7WAcjgSkSVVxKlPNFFw==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.43.0': resolution: {integrity: sha512-8FnkipasmOOSSlfucGYEu58U8cxEdhziKjPD2FIa0ONVMxvl/hmONtX/7y4vGjdUhjcTHlKlDhw3H9t98fPvyA==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.43.0': resolution: {integrity: sha512-KPPyAdlcIZ6S9C3S2cndXDkV0Bb1OSMsX0Eelr2Bay4EsF9yi9u9uzc9RniK3mcUGCLhWY9oLr6er80P5DE6XA==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loongarch64-gnu@4.43.0': resolution: {integrity: sha512-HPGDIH0/ZzAZjvtlXj6g+KDQ9ZMHfSP553za7o2Odegb/BEfwJcR0Sw0RLNpQ9nC6Gy8s+3mSS9xjZ0n3rhcYg==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-powerpc64le-gnu@4.43.0': resolution: {integrity: sha512-gEmwbOws4U4GLAJDhhtSPWPXUzDfMRedT3hFMyRAvM9Mrnj+dJIFIeL7otsv2WF3D7GrV0GIewW0y28dOYWkmw==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.43.0': resolution: {integrity: sha512-XXKvo2e+wFtXZF/9xoWohHg+MuRnvO29TI5Hqe9xwN5uN8NKUYy7tXUG3EZAlfchufNCTHNGjEx7uN78KsBo0g==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.43.0': resolution: {integrity: sha512-ruf3hPWhjw6uDFsOAzmbNIvlXFXlBQ4nk57Sec8E8rUxs/AI4HD6xmiiasOOx/3QxS2f5eQMKTAwk7KHwpzr/Q==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.43.0': resolution: {integrity: sha512-QmNIAqDiEMEvFV15rsSnjoSmO0+eJLoKRD9EAa9rrYNwO/XRCtOGM3A5A0X+wmG+XRrw9Fxdsw+LnyYiZWWcVw==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.43.0': resolution: {integrity: sha512-jAHr/S0iiBtFyzjhOkAics/2SrXE092qyqEg96e90L3t9Op8OTzS6+IX0Fy5wCt2+KqeHAkti+eitV0wvblEoQ==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.43.0': resolution: {integrity: sha512-3yATWgdeXyuHtBhrLt98w+5fKurdqvs8B53LaoKD7P7H7FKOONLsBVMNl9ghPQZQuYcceV5CDyPfyfGpMWD9mQ==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-win32-arm64-msvc@4.43.0': resolution: {integrity: sha512-wVzXp2qDSCOpcBCT5WRWLmpJRIzv23valvcTwMHEobkjippNf+C3ys/+wf07poPkeNix0paTNemB2XrHr2TnGw==} @@ -5208,24 +5234,28 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.32.0: resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.32.0: resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.32.0: resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.32.0: resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}