chroma-panel 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +44 -0
- package/README.md +119 -0
- package/dist/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/a11y/contrast.cjs +107 -0
- package/dist/a11y/contrast.d.cts +34 -0
- package/dist/a11y/contrast.d.ts +34 -0
- package/dist/a11y/contrast.js +101 -0
- package/dist/color/convert.cjs +162 -0
- package/dist/color/convert.d.cts +16 -0
- package/dist/color/convert.d.ts +16 -0
- package/dist/color/convert.js +153 -0
- package/dist/color/parse.cjs +153 -0
- package/dist/color/parse.d.cts +7 -0
- package/dist/color/parse.d.ts +7 -0
- package/dist/color/parse.js +151 -0
- package/dist/color/serialize.cjs +79 -0
- package/dist/color/serialize.d.cts +11 -0
- package/dist/color/serialize.d.ts +11 -0
- package/dist/color/serialize.js +73 -0
- package/dist/color/sticky.cjs +20 -0
- package/dist/color/sticky.d.cts +6 -0
- package/dist/color/sticky.d.ts +6 -0
- package/dist/color/sticky.js +19 -0
- package/dist/color/types.d.cts +43 -0
- package/dist/color/types.d.ts +43 -0
- package/dist/components/ChromaPanel.cjs +254 -0
- package/dist/components/ChromaPanel.d.cts +47 -0
- package/dist/components/ChromaPanel.d.ts +47 -0
- package/dist/components/ChromaPanel.js +251 -0
- package/dist/components/ColorInput.cjs +128 -0
- package/dist/components/ColorInput.d.cts +19 -0
- package/dist/components/ColorInput.d.ts +19 -0
- package/dist/components/ColorInput.js +127 -0
- package/dist/components/ModeToolbar.cjs +33 -0
- package/dist/components/ModeToolbar.d.cts +10 -0
- package/dist/components/ModeToolbar.d.ts +10 -0
- package/dist/components/ModeToolbar.js +32 -0
- package/dist/components/PanelFooter.cjs +82 -0
- package/dist/components/PanelFooter.d.cts +5 -0
- package/dist/components/PanelFooter.d.ts +5 -0
- package/dist/components/PanelFooter.js +80 -0
- package/dist/components/Popover.cjs +154 -0
- package/dist/components/Popover.d.cts +13 -0
- package/dist/components/Popover.d.ts +13 -0
- package/dist/components/Popover.js +153 -0
- package/dist/contrast.cjs +10 -0
- package/dist/contrast.d.cts +2 -0
- package/dist/contrast.d.ts +2 -0
- package/dist/contrast.js +2 -0
- package/dist/core/context.cjs +30 -0
- package/dist/core/context.d.cts +43 -0
- package/dist/core/context.d.ts +43 -0
- package/dist/core/context.js +26 -0
- package/dist/core/dev.cjs +11 -0
- package/dist/core/dev.js +11 -0
- package/dist/core/store.cjs +43 -0
- package/dist/core/store.d.cts +17 -0
- package/dist/core/store.d.ts +17 -0
- package/dist/core/store.js +44 -0
- package/dist/core/styleInjector.cjs +38 -0
- package/dist/core/styleInjector.d.cts +4 -0
- package/dist/core/styleInjector.d.ts +4 -0
- package/dist/core/styleInjector.js +38 -0
- package/dist/core/useColorStore.cjs +43 -0
- package/dist/core/useColorStore.d.cts +6 -0
- package/dist/core/useColorStore.d.ts +6 -0
- package/dist/core/useColorStore.js +41 -0
- package/dist/core/useFormControl.cjs +87 -0
- package/dist/core/useFormControl.js +82 -0
- package/dist/core/useMediaQuery.cjs +48 -0
- package/dist/core/useMediaQuery.js +46 -0
- package/dist/core/usePointerDrag.cjs +177 -0
- package/dist/core/usePointerDrag.d.cts +35 -0
- package/dist/core/usePointerDrag.d.ts +35 -0
- package/dist/core/usePointerDrag.js +175 -0
- package/dist/core/useScrollFade.cjs +44 -0
- package/dist/core/useScrollFade.js +43 -0
- package/dist/core.cjs +33 -0
- package/dist/core.d.cts +7 -0
- package/dist/core.d.ts +7 -0
- package/dist/core.js +6 -0
- package/dist/data/defaults.cjs +123 -0
- package/dist/data/defaults.d.cts +6 -0
- package/dist/data/defaults.d.ts +6 -0
- package/dist/data/defaults.js +122 -0
- package/dist/data/namedColors.cjs +11 -0
- package/dist/data/namedColors.d.cts +3 -0
- package/dist/data/namedColors.d.ts +3 -0
- package/dist/data/namedColors.js +12 -0
- package/dist/image/extract.cjs +98 -0
- package/dist/image/extract.d.cts +16 -0
- package/dist/image/extract.d.ts +16 -0
- package/dist/image/extract.js +99 -0
- package/dist/image/mmcq.cjs +182 -0
- package/dist/image/mmcq.d.cts +8 -0
- package/dist/image/mmcq.d.ts +8 -0
- package/dist/image/mmcq.js +183 -0
- package/dist/image-worker.js +202 -0
- package/dist/image.cjs +12 -0
- package/dist/image.d.cts +4 -0
- package/dist/image.d.ts +4 -0
- package/dist/image.js +9 -0
- package/dist/index.cjs +119 -0
- package/dist/index.d.cts +36 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +44 -0
- package/dist/modes/gradients.cjs +48 -0
- package/dist/modes/gradients.js +43 -0
- package/dist/modes/image/index.cjs +193 -0
- package/dist/modes/image/index.d.cts +10 -0
- package/dist/modes/image/index.d.ts +10 -0
- package/dist/modes/image/index.js +191 -0
- package/dist/modes/palettes/index.cjs +76 -0
- package/dist/modes/palettes/index.d.cts +6 -0
- package/dist/modes/palettes/index.d.ts +6 -0
- package/dist/modes/palettes/index.js +74 -0
- package/dist/modes/pencils/index.cjs +36 -0
- package/dist/modes/pencils/index.d.cts +6 -0
- package/dist/modes/pencils/index.d.ts +6 -0
- package/dist/modes/pencils/index.js +34 -0
- package/dist/modes/registry.cjs +26 -0
- package/dist/modes/registry.d.cts +13 -0
- package/dist/modes/registry.d.ts +13 -0
- package/dist/modes/registry.js +25 -0
- package/dist/modes/sliders/index.cjs +300 -0
- package/dist/modes/sliders/index.d.cts +6 -0
- package/dist/modes/sliders/index.d.ts +6 -0
- package/dist/modes/sliders/index.js +298 -0
- package/dist/modes/wheel/index.cjs +62 -0
- package/dist/modes/wheel/index.d.cts +6 -0
- package/dist/modes/wheel/index.d.ts +6 -0
- package/dist/modes/wheel/index.js +60 -0
- package/dist/named-colors.cjs +3 -0
- package/dist/named-colors.d.cts +2 -0
- package/dist/named-colors.d.ts +2 -0
- package/dist/named-colors.js +2 -0
- package/dist/palettes.cjs +8 -0
- package/dist/palettes.d.cts +2 -0
- package/dist/palettes.d.ts +2 -0
- package/dist/palettes.js +7 -0
- package/dist/panel.cjs +80 -0
- package/dist/panel.d.cts +27 -0
- package/dist/panel.d.ts +27 -0
- package/dist/panel.js +27 -0
- package/dist/pencils.cjs +8 -0
- package/dist/pencils.d.cts +2 -0
- package/dist/pencils.d.ts +2 -0
- package/dist/pencils.js +7 -0
- package/dist/primitives/AxisInput.cjs +26 -0
- package/dist/primitives/AxisInput.js +25 -0
- package/dist/primitives/ChannelSlider.cjs +94 -0
- package/dist/primitives/ChannelSlider.d.cts +18 -0
- package/dist/primitives/ChannelSlider.d.ts +18 -0
- package/dist/primitives/ChannelSlider.js +93 -0
- package/dist/primitives/ColorArea.cjs +85 -0
- package/dist/primitives/ColorArea.d.cts +8 -0
- package/dist/primitives/ColorArea.d.ts +8 -0
- package/dist/primitives/ColorArea.js +84 -0
- package/dist/primitives/ColorDisc.cjs +95 -0
- package/dist/primitives/ColorDisc.d.cts +8 -0
- package/dist/primitives/ColorDisc.d.ts +8 -0
- package/dist/primitives/ColorDisc.js +94 -0
- package/dist/primitives/ColorField.cjs +68 -0
- package/dist/primitives/ColorField.d.cts +9 -0
- package/dist/primitives/ColorField.d.ts +9 -0
- package/dist/primitives/ColorField.js +67 -0
- package/dist/primitives/NumberField.cjs +65 -0
- package/dist/primitives/NumberField.d.cts +14 -0
- package/dist/primitives/NumberField.d.ts +14 -0
- package/dist/primitives/NumberField.js +64 -0
- package/dist/primitives/SegmentedControl.cjs +66 -0
- package/dist/primitives/SegmentedControl.d.cts +21 -0
- package/dist/primitives/SegmentedControl.d.ts +21 -0
- package/dist/primitives/SegmentedControl.js +65 -0
- package/dist/primitives/Swatch.cjs +22 -0
- package/dist/primitives/Swatch.d.cts +13 -0
- package/dist/primitives/Swatch.d.ts +13 -0
- package/dist/primitives/Swatch.js +21 -0
- package/dist/primitives/SwatchGrid.cjs +63 -0
- package/dist/primitives/SwatchGrid.d.cts +17 -0
- package/dist/primitives/SwatchGrid.d.ts +17 -0
- package/dist/primitives/SwatchGrid.js +62 -0
- package/dist/primitives/icons.cjs +149 -0
- package/dist/primitives/icons.d.cts +9 -0
- package/dist/primitives/icons.d.ts +9 -0
- package/dist/primitives/icons.js +141 -0
- package/dist/primitives/useEyedropper.cjs +30 -0
- package/dist/primitives/useEyedropper.d.cts +7 -0
- package/dist/primitives/useEyedropper.d.ts +7 -0
- package/dist/primitives/useEyedropper.js +29 -0
- package/dist/sliders.cjs +8 -0
- package/dist/sliders.d.cts +2 -0
- package/dist/sliders.d.ts +2 -0
- package/dist/sliders.js +7 -0
- package/dist/style.css +2 -0
- package/dist/styles/css.cjs +4 -0
- package/dist/styles/css.js +5 -0
- package/dist/wheel.cjs +8 -0
- package/dist/wheel.d.cts +2 -0
- package/dist/wheel.d.ts +2 -0
- package/dist/wheel.js +7 -0
- package/package.json +222 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//#region src/core/styleInjector.ts
|
|
2
|
+
let nonceProvider = null;
|
|
3
|
+
function setStyleNonce(provider) {
|
|
4
|
+
nonceProvider = typeof provider === "function" ? provider : () => provider;
|
|
5
|
+
}
|
|
6
|
+
const injectedByRoot = /* @__PURE__ */ new WeakMap();
|
|
7
|
+
function containerFor(root) {
|
|
8
|
+
if (typeof ShadowRoot !== "undefined" && root instanceof ShadowRoot) return root;
|
|
9
|
+
const doc = root.head !== void 0 ? root : document;
|
|
10
|
+
return doc.head ?? doc.documentElement ?? null;
|
|
11
|
+
}
|
|
12
|
+
function injectStyles(css, id, node) {
|
|
13
|
+
if (typeof document === "undefined") return;
|
|
14
|
+
const root = node?.getRootNode?.() ?? document;
|
|
15
|
+
let seen = injectedByRoot.get(root);
|
|
16
|
+
if (seen === void 0) {
|
|
17
|
+
seen = /* @__PURE__ */ new Set();
|
|
18
|
+
injectedByRoot.set(root, seen);
|
|
19
|
+
}
|
|
20
|
+
if (seen.has(id)) return;
|
|
21
|
+
const container = containerFor(root);
|
|
22
|
+
if (container === null) return;
|
|
23
|
+
const existing = container.querySelector?.(`style[data-chroma-panel="${id}"]`);
|
|
24
|
+
if (existing !== null && existing !== void 0) {
|
|
25
|
+
seen.add(id);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const style = document.createElement("style");
|
|
29
|
+
style.setAttribute("data-chroma-panel", id);
|
|
30
|
+
const nonce = nonceProvider?.();
|
|
31
|
+
if (nonce !== void 0 && nonce !== "") style.setAttribute("nonce", nonce);
|
|
32
|
+
style.appendChild(document.createTextNode(css));
|
|
33
|
+
container.appendChild(style);
|
|
34
|
+
seen.add(id);
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
exports.injectStyles = injectStyles;
|
|
38
|
+
exports.setStyleNonce = setStyleNonce;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//#region src/core/styleInjector.ts
|
|
2
|
+
let nonceProvider = null;
|
|
3
|
+
function setStyleNonce(provider) {
|
|
4
|
+
nonceProvider = typeof provider === "function" ? provider : () => provider;
|
|
5
|
+
}
|
|
6
|
+
const injectedByRoot = /* @__PURE__ */ new WeakMap();
|
|
7
|
+
function containerFor(root) {
|
|
8
|
+
if (typeof ShadowRoot !== "undefined" && root instanceof ShadowRoot) return root;
|
|
9
|
+
const doc = root.head !== void 0 ? root : document;
|
|
10
|
+
return doc.head ?? doc.documentElement ?? null;
|
|
11
|
+
}
|
|
12
|
+
function injectStyles(css, id, node) {
|
|
13
|
+
if (typeof document === "undefined") return;
|
|
14
|
+
const root = node?.getRootNode?.() ?? document;
|
|
15
|
+
let seen = injectedByRoot.get(root);
|
|
16
|
+
if (seen === void 0) {
|
|
17
|
+
seen = /* @__PURE__ */ new Set();
|
|
18
|
+
injectedByRoot.set(root, seen);
|
|
19
|
+
}
|
|
20
|
+
if (seen.has(id)) return;
|
|
21
|
+
const container = containerFor(root);
|
|
22
|
+
if (container === null) return;
|
|
23
|
+
const existing = container.querySelector?.(`style[data-chroma-panel="${id}"]`);
|
|
24
|
+
if (existing !== null && existing !== void 0) {
|
|
25
|
+
seen.add(id);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const style = document.createElement("style");
|
|
29
|
+
style.setAttribute("data-chroma-panel", id);
|
|
30
|
+
const nonce = nonceProvider?.();
|
|
31
|
+
if (nonce !== void 0 && nonce !== "") style.setAttribute("nonce", nonce);
|
|
32
|
+
style.appendChild(document.createTextNode(css));
|
|
33
|
+
container.appendChild(style);
|
|
34
|
+
seen.add(id);
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { injectStyles, setStyleNonce };
|
|
38
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
react = require_runtime.__toESM(react, 1);
|
|
5
|
+
//#region src/core/useColorStore.ts
|
|
6
|
+
function useSyncExternalStoreFallback(subscribe, getSnapshot) {
|
|
7
|
+
const value = getSnapshot();
|
|
8
|
+
const [, force] = react.useState(0);
|
|
9
|
+
const latest = react.useRef(value);
|
|
10
|
+
react.useEffect(() => {
|
|
11
|
+
latest.current = value;
|
|
12
|
+
});
|
|
13
|
+
react.useEffect(() => {
|
|
14
|
+
const check = () => {
|
|
15
|
+
const next = getSnapshot();
|
|
16
|
+
if (!Object.is(latest.current, next)) {
|
|
17
|
+
latest.current = next;
|
|
18
|
+
force((n) => n + 1);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
check();
|
|
22
|
+
return subscribe(check);
|
|
23
|
+
}, [subscribe, getSnapshot]);
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
const useSyncExternal = react.useSyncExternalStore ?? useSyncExternalStoreFallback;
|
|
27
|
+
function useColorValue(store) {
|
|
28
|
+
return useSyncExternal(store.subscribe, store.getSnapshot, store.getServerSnapshot);
|
|
29
|
+
}
|
|
30
|
+
function useTransientColor(store, effect) {
|
|
31
|
+
const latest = react.useRef(effect);
|
|
32
|
+
react.useEffect(() => {
|
|
33
|
+
latest.current = effect;
|
|
34
|
+
});
|
|
35
|
+
react.useEffect(() => {
|
|
36
|
+
const run = (color) => latest.current(color);
|
|
37
|
+
run(store.get());
|
|
38
|
+
return store.subscribe(run);
|
|
39
|
+
}, [store]);
|
|
40
|
+
}
|
|
41
|
+
//#endregion
|
|
42
|
+
exports.useColorValue = useColorValue;
|
|
43
|
+
exports.useTransientColor = useTransientColor;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Hsva } from "../color/types.cjs";
|
|
2
|
+
import { ColorStore } from "./store.cjs";
|
|
3
|
+
//#region src/core/useColorStore.d.ts
|
|
4
|
+
export declare function useColorValue(store: ColorStore): Hsva;
|
|
5
|
+
export declare function useTransientColor(store: ColorStore, effect: (color: Hsva) => void): void;
|
|
6
|
+
//#endregion
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Hsva } from "../color/types.js";
|
|
2
|
+
import { ColorStore } from "./store.js";
|
|
3
|
+
//#region src/core/useColorStore.d.ts
|
|
4
|
+
export declare function useColorValue(store: ColorStore): Hsva;
|
|
5
|
+
export declare function useTransientColor(store: ColorStore, effect: (color: Hsva) => void): void;
|
|
6
|
+
//#endregion
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
//#region src/core/useColorStore.ts
|
|
4
|
+
function useSyncExternalStoreFallback(subscribe, getSnapshot) {
|
|
5
|
+
const value = getSnapshot();
|
|
6
|
+
const [, force] = React.useState(0);
|
|
7
|
+
const latest = React.useRef(value);
|
|
8
|
+
React.useEffect(() => {
|
|
9
|
+
latest.current = value;
|
|
10
|
+
});
|
|
11
|
+
React.useEffect(() => {
|
|
12
|
+
const check = () => {
|
|
13
|
+
const next = getSnapshot();
|
|
14
|
+
if (!Object.is(latest.current, next)) {
|
|
15
|
+
latest.current = next;
|
|
16
|
+
force((n) => n + 1);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
check();
|
|
20
|
+
return subscribe(check);
|
|
21
|
+
}, [subscribe, getSnapshot]);
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
const useSyncExternal = React.useSyncExternalStore ?? useSyncExternalStoreFallback;
|
|
25
|
+
function useColorValue(store) {
|
|
26
|
+
return useSyncExternal(store.subscribe, store.getSnapshot, store.getServerSnapshot);
|
|
27
|
+
}
|
|
28
|
+
function useTransientColor(store, effect) {
|
|
29
|
+
const latest = React.useRef(effect);
|
|
30
|
+
React.useEffect(() => {
|
|
31
|
+
latest.current = effect;
|
|
32
|
+
});
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
const run = (color) => latest.current(color);
|
|
35
|
+
run(store.get());
|
|
36
|
+
return store.subscribe(run);
|
|
37
|
+
}, [store]);
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { useColorValue, useTransientColor };
|
|
41
|
+
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
react = require_runtime.__toESM(react, 1);
|
|
5
|
+
//#region src/core/useFormControl.ts
|
|
6
|
+
function setNativeValue(input, value) {
|
|
7
|
+
Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set?.call(input, value);
|
|
8
|
+
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
9
|
+
}
|
|
10
|
+
function useFormReset(ref, onReset) {
|
|
11
|
+
const latest = react.useRef(onReset);
|
|
12
|
+
react.useEffect(() => {
|
|
13
|
+
latest.current = onReset;
|
|
14
|
+
});
|
|
15
|
+
react.useEffect(() => {
|
|
16
|
+
const form = ref.current?.form;
|
|
17
|
+
if (form === null || form === void 0) return;
|
|
18
|
+
const handle = (event) => {
|
|
19
|
+
if (event.defaultPrevented) return;
|
|
20
|
+
latest.current();
|
|
21
|
+
};
|
|
22
|
+
form.addEventListener("reset", handle);
|
|
23
|
+
return () => form.removeEventListener("reset", handle);
|
|
24
|
+
}, [ref]);
|
|
25
|
+
}
|
|
26
|
+
function useFieldsetDisabled(ref) {
|
|
27
|
+
const [disabled, setDisabled] = react.useState(false);
|
|
28
|
+
react.useEffect(() => {
|
|
29
|
+
const fieldset = ref.current?.closest("fieldset");
|
|
30
|
+
if (fieldset === null || fieldset === void 0) {
|
|
31
|
+
setDisabled(false);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
setDisabled(fieldset.disabled);
|
|
35
|
+
const observer = new MutationObserver(() => setDisabled(fieldset.disabled));
|
|
36
|
+
observer.observe(fieldset, {
|
|
37
|
+
attributes: true,
|
|
38
|
+
attributeFilter: ["disabled"]
|
|
39
|
+
});
|
|
40
|
+
return () => observer.disconnect();
|
|
41
|
+
}, [ref]);
|
|
42
|
+
return disabled;
|
|
43
|
+
}
|
|
44
|
+
function useConstraintValidation(ref, options) {
|
|
45
|
+
const latest = react.useRef(options);
|
|
46
|
+
react.useEffect(() => {
|
|
47
|
+
latest.current = options;
|
|
48
|
+
});
|
|
49
|
+
react.useEffect(() => {
|
|
50
|
+
const input = ref.current;
|
|
51
|
+
if (input === null) return;
|
|
52
|
+
const { behavior, required, isEmpty } = latest.current;
|
|
53
|
+
const message = behavior === "native" && required && isEmpty ? "Please choose a colour." : "";
|
|
54
|
+
input.setCustomValidity(message);
|
|
55
|
+
if (!input.hasAttribute("title")) input.title = "";
|
|
56
|
+
});
|
|
57
|
+
react.useEffect(() => {
|
|
58
|
+
const input = ref.current;
|
|
59
|
+
if (input === null) return;
|
|
60
|
+
const onInvalid = (event) => {
|
|
61
|
+
event.preventDefault();
|
|
62
|
+
latest.current.focusTrigger();
|
|
63
|
+
};
|
|
64
|
+
input.addEventListener("invalid", onInvalid);
|
|
65
|
+
return () => input.removeEventListener("invalid", onInvalid);
|
|
66
|
+
}, [ref]);
|
|
67
|
+
}
|
|
68
|
+
const visuallyHiddenInput = {
|
|
69
|
+
position: "absolute",
|
|
70
|
+
width: 1,
|
|
71
|
+
height: 1,
|
|
72
|
+
padding: 0,
|
|
73
|
+
margin: -1,
|
|
74
|
+
overflow: "hidden",
|
|
75
|
+
clip: "rect(0 0 0 0)",
|
|
76
|
+
clipPath: "inset(50%)",
|
|
77
|
+
whiteSpace: "nowrap",
|
|
78
|
+
border: 0,
|
|
79
|
+
opacity: 0,
|
|
80
|
+
pointerEvents: "none"
|
|
81
|
+
};
|
|
82
|
+
//#endregion
|
|
83
|
+
exports.setNativeValue = setNativeValue;
|
|
84
|
+
exports.useConstraintValidation = useConstraintValidation;
|
|
85
|
+
exports.useFieldsetDisabled = useFieldsetDisabled;
|
|
86
|
+
exports.useFormReset = useFormReset;
|
|
87
|
+
exports.visuallyHiddenInput = visuallyHiddenInput;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
//#region src/core/useFormControl.ts
|
|
4
|
+
function setNativeValue(input, value) {
|
|
5
|
+
Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set?.call(input, value);
|
|
6
|
+
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
7
|
+
}
|
|
8
|
+
function useFormReset(ref, onReset) {
|
|
9
|
+
const latest = React.useRef(onReset);
|
|
10
|
+
React.useEffect(() => {
|
|
11
|
+
latest.current = onReset;
|
|
12
|
+
});
|
|
13
|
+
React.useEffect(() => {
|
|
14
|
+
const form = ref.current?.form;
|
|
15
|
+
if (form === null || form === void 0) return;
|
|
16
|
+
const handle = (event) => {
|
|
17
|
+
if (event.defaultPrevented) return;
|
|
18
|
+
latest.current();
|
|
19
|
+
};
|
|
20
|
+
form.addEventListener("reset", handle);
|
|
21
|
+
return () => form.removeEventListener("reset", handle);
|
|
22
|
+
}, [ref]);
|
|
23
|
+
}
|
|
24
|
+
function useFieldsetDisabled(ref) {
|
|
25
|
+
const [disabled, setDisabled] = React.useState(false);
|
|
26
|
+
React.useEffect(() => {
|
|
27
|
+
const fieldset = ref.current?.closest("fieldset");
|
|
28
|
+
if (fieldset === null || fieldset === void 0) {
|
|
29
|
+
setDisabled(false);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
setDisabled(fieldset.disabled);
|
|
33
|
+
const observer = new MutationObserver(() => setDisabled(fieldset.disabled));
|
|
34
|
+
observer.observe(fieldset, {
|
|
35
|
+
attributes: true,
|
|
36
|
+
attributeFilter: ["disabled"]
|
|
37
|
+
});
|
|
38
|
+
return () => observer.disconnect();
|
|
39
|
+
}, [ref]);
|
|
40
|
+
return disabled;
|
|
41
|
+
}
|
|
42
|
+
function useConstraintValidation(ref, options) {
|
|
43
|
+
const latest = React.useRef(options);
|
|
44
|
+
React.useEffect(() => {
|
|
45
|
+
latest.current = options;
|
|
46
|
+
});
|
|
47
|
+
React.useEffect(() => {
|
|
48
|
+
const input = ref.current;
|
|
49
|
+
if (input === null) return;
|
|
50
|
+
const { behavior, required, isEmpty } = latest.current;
|
|
51
|
+
const message = behavior === "native" && required && isEmpty ? "Please choose a colour." : "";
|
|
52
|
+
input.setCustomValidity(message);
|
|
53
|
+
if (!input.hasAttribute("title")) input.title = "";
|
|
54
|
+
});
|
|
55
|
+
React.useEffect(() => {
|
|
56
|
+
const input = ref.current;
|
|
57
|
+
if (input === null) return;
|
|
58
|
+
const onInvalid = (event) => {
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
latest.current.focusTrigger();
|
|
61
|
+
};
|
|
62
|
+
input.addEventListener("invalid", onInvalid);
|
|
63
|
+
return () => input.removeEventListener("invalid", onInvalid);
|
|
64
|
+
}, [ref]);
|
|
65
|
+
}
|
|
66
|
+
const visuallyHiddenInput = {
|
|
67
|
+
position: "absolute",
|
|
68
|
+
width: 1,
|
|
69
|
+
height: 1,
|
|
70
|
+
padding: 0,
|
|
71
|
+
margin: -1,
|
|
72
|
+
overflow: "hidden",
|
|
73
|
+
clip: "rect(0 0 0 0)",
|
|
74
|
+
clipPath: "inset(50%)",
|
|
75
|
+
whiteSpace: "nowrap",
|
|
76
|
+
border: 0,
|
|
77
|
+
opacity: 0,
|
|
78
|
+
pointerEvents: "none"
|
|
79
|
+
};
|
|
80
|
+
//#endregion
|
|
81
|
+
export { setNativeValue, useConstraintValidation, useFieldsetDisabled, useFormReset, visuallyHiddenInput };
|
|
82
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
let react = require("react");
|
|
4
|
+
react = require_runtime.__toESM(react, 1);
|
|
5
|
+
//#region src/core/useMediaQuery.ts
|
|
6
|
+
function useSyncExternalStoreFallback(subscribe, getSnapshot) {
|
|
7
|
+
const value = getSnapshot();
|
|
8
|
+
const [, force] = react.useState(0);
|
|
9
|
+
const latest = react.useRef(value);
|
|
10
|
+
react.useEffect(() => {
|
|
11
|
+
latest.current = value;
|
|
12
|
+
});
|
|
13
|
+
react.useEffect(() => {
|
|
14
|
+
const check = () => {
|
|
15
|
+
const next = getSnapshot();
|
|
16
|
+
if (!Object.is(latest.current, next)) {
|
|
17
|
+
latest.current = next;
|
|
18
|
+
force((n) => n + 1);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
check();
|
|
22
|
+
return subscribe(check);
|
|
23
|
+
}, [subscribe, getSnapshot]);
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
const useSyncExternal = react.useSyncExternalStore ?? useSyncExternalStoreFallback;
|
|
27
|
+
function useMediaQuery(query) {
|
|
28
|
+
const subscribe = react.useCallback((onChange) => {
|
|
29
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return () => {};
|
|
30
|
+
const list = window.matchMedia(query);
|
|
31
|
+
if (typeof list.addEventListener === "function") {
|
|
32
|
+
list.addEventListener("change", onChange);
|
|
33
|
+
return () => list.removeEventListener("change", onChange);
|
|
34
|
+
}
|
|
35
|
+
list.addListener(onChange);
|
|
36
|
+
return () => list.removeListener(onChange);
|
|
37
|
+
}, [query]);
|
|
38
|
+
const getSnapshot = react.useCallback(() => {
|
|
39
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
40
|
+
return window.matchMedia(query).matches;
|
|
41
|
+
}, [query]);
|
|
42
|
+
const getServerSnapshot = react.useCallback(() => false, []);
|
|
43
|
+
return useSyncExternal(subscribe, getSnapshot, getServerSnapshot);
|
|
44
|
+
}
|
|
45
|
+
const COMPACT_QUERY = "(max-width: 640px)";
|
|
46
|
+
//#endregion
|
|
47
|
+
exports.COMPACT_QUERY = COMPACT_QUERY;
|
|
48
|
+
exports.useMediaQuery = useMediaQuery;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
//#region src/core/useMediaQuery.ts
|
|
4
|
+
function useSyncExternalStoreFallback(subscribe, getSnapshot) {
|
|
5
|
+
const value = getSnapshot();
|
|
6
|
+
const [, force] = React.useState(0);
|
|
7
|
+
const latest = React.useRef(value);
|
|
8
|
+
React.useEffect(() => {
|
|
9
|
+
latest.current = value;
|
|
10
|
+
});
|
|
11
|
+
React.useEffect(() => {
|
|
12
|
+
const check = () => {
|
|
13
|
+
const next = getSnapshot();
|
|
14
|
+
if (!Object.is(latest.current, next)) {
|
|
15
|
+
latest.current = next;
|
|
16
|
+
force((n) => n + 1);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
check();
|
|
20
|
+
return subscribe(check);
|
|
21
|
+
}, [subscribe, getSnapshot]);
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
const useSyncExternal = React.useSyncExternalStore ?? useSyncExternalStoreFallback;
|
|
25
|
+
function useMediaQuery(query) {
|
|
26
|
+
const subscribe = React.useCallback((onChange) => {
|
|
27
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return () => {};
|
|
28
|
+
const list = window.matchMedia(query);
|
|
29
|
+
if (typeof list.addEventListener === "function") {
|
|
30
|
+
list.addEventListener("change", onChange);
|
|
31
|
+
return () => list.removeEventListener("change", onChange);
|
|
32
|
+
}
|
|
33
|
+
list.addListener(onChange);
|
|
34
|
+
return () => list.removeListener(onChange);
|
|
35
|
+
}, [query]);
|
|
36
|
+
const getSnapshot = React.useCallback(() => {
|
|
37
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
38
|
+
return window.matchMedia(query).matches;
|
|
39
|
+
}, [query]);
|
|
40
|
+
const getServerSnapshot = React.useCallback(() => false, []);
|
|
41
|
+
return useSyncExternal(subscribe, getSnapshot, getServerSnapshot);
|
|
42
|
+
}
|
|
43
|
+
const COMPACT_QUERY = "(max-width: 640px)";
|
|
44
|
+
//#endregion
|
|
45
|
+
export { COMPACT_QUERY, useMediaQuery };
|
|
46
|
+
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_convert = require("../color/convert.cjs");
|
|
4
|
+
let react = require("react");
|
|
5
|
+
react = require_runtime.__toESM(react, 1);
|
|
6
|
+
//#region src/core/usePointerDrag.ts
|
|
7
|
+
function positionIn(element, clientX, clientY) {
|
|
8
|
+
const rect = element.getBoundingClientRect();
|
|
9
|
+
return {
|
|
10
|
+
x: rect.width === 0 ? 0 : require_convert.clamp((clientX - rect.left) / rect.width, 0, 1),
|
|
11
|
+
y: rect.height === 0 ? 0 : require_convert.clamp((clientY - rect.top) / rect.height, 0, 1)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function usePointerDrag(options) {
|
|
15
|
+
const latest = react.useRef(options);
|
|
16
|
+
react.useEffect(() => {
|
|
17
|
+
latest.current = options;
|
|
18
|
+
});
|
|
19
|
+
const frame = react.useRef(0);
|
|
20
|
+
const pending = react.useRef(null);
|
|
21
|
+
const dragging = react.useRef(false);
|
|
22
|
+
const activePointer = react.useRef(null);
|
|
23
|
+
const captured = react.useRef(false);
|
|
24
|
+
const flush = react.useCallback(() => {
|
|
25
|
+
if (frame.current !== 0) {
|
|
26
|
+
cancelAnimationFrame(frame.current);
|
|
27
|
+
frame.current = 0;
|
|
28
|
+
}
|
|
29
|
+
if (pending.current !== null) {
|
|
30
|
+
latest.current.onMove(pending.current);
|
|
31
|
+
pending.current = null;
|
|
32
|
+
}
|
|
33
|
+
}, []);
|
|
34
|
+
react.useEffect(() => {
|
|
35
|
+
return () => {
|
|
36
|
+
if (frame.current !== 0) cancelAnimationFrame(frame.current);
|
|
37
|
+
};
|
|
38
|
+
}, []);
|
|
39
|
+
const schedule = react.useCallback((position) => {
|
|
40
|
+
pending.current = position;
|
|
41
|
+
if (frame.current !== 0) return;
|
|
42
|
+
frame.current = requestAnimationFrame(() => {
|
|
43
|
+
frame.current = 0;
|
|
44
|
+
const next = pending.current;
|
|
45
|
+
pending.current = null;
|
|
46
|
+
if (next !== null) latest.current.onMove(next);
|
|
47
|
+
});
|
|
48
|
+
}, []);
|
|
49
|
+
const onPointerDown = react.useCallback((event) => {
|
|
50
|
+
if (latest.current.disabled === true) return;
|
|
51
|
+
if (event.pointerType === "mouse" && event.button !== 0) return;
|
|
52
|
+
const element = event.currentTarget;
|
|
53
|
+
try {
|
|
54
|
+
element.setPointerCapture(event.pointerId);
|
|
55
|
+
captured.current = true;
|
|
56
|
+
} catch {
|
|
57
|
+
captured.current = false;
|
|
58
|
+
}
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
dragging.current = true;
|
|
61
|
+
activePointer.current = event.pointerId;
|
|
62
|
+
const position = positionIn(element, event.clientX, event.clientY);
|
|
63
|
+
latest.current.onStart?.(position);
|
|
64
|
+
latest.current.onMove(position);
|
|
65
|
+
}, []);
|
|
66
|
+
const onPointerMove = react.useCallback((event) => {
|
|
67
|
+
if (!dragging.current || latest.current.disabled === true) return;
|
|
68
|
+
if (activePointer.current !== event.pointerId) return;
|
|
69
|
+
schedule(positionIn(event.currentTarget, event.clientX, event.clientY));
|
|
70
|
+
}, [schedule]);
|
|
71
|
+
const endDrag = react.useCallback(() => {
|
|
72
|
+
if (!dragging.current) return;
|
|
73
|
+
dragging.current = false;
|
|
74
|
+
activePointer.current = null;
|
|
75
|
+
captured.current = false;
|
|
76
|
+
flush();
|
|
77
|
+
latest.current.onEnd?.();
|
|
78
|
+
}, [flush]);
|
|
79
|
+
const onLostPointerCapture = react.useCallback(() => endDrag(), [endDrag]);
|
|
80
|
+
const onPointerUp = react.useCallback((event) => {
|
|
81
|
+
if (captured.current) return;
|
|
82
|
+
if (activePointer.current !== event.pointerId) return;
|
|
83
|
+
endDrag();
|
|
84
|
+
}, [endDrag]);
|
|
85
|
+
react.useEffect(() => {
|
|
86
|
+
if (typeof document === "undefined") return;
|
|
87
|
+
const onWindowUp = (event) => {
|
|
88
|
+
if (captured.current || !dragging.current) return;
|
|
89
|
+
if (activePointer.current !== event.pointerId) return;
|
|
90
|
+
endDrag();
|
|
91
|
+
};
|
|
92
|
+
document.addEventListener("pointerup", onWindowUp);
|
|
93
|
+
document.addEventListener("pointercancel", onWindowUp);
|
|
94
|
+
return () => {
|
|
95
|
+
document.removeEventListener("pointerup", onWindowUp);
|
|
96
|
+
document.removeEventListener("pointercancel", onWindowUp);
|
|
97
|
+
};
|
|
98
|
+
}, [endDrag]);
|
|
99
|
+
return {
|
|
100
|
+
onPointerDown,
|
|
101
|
+
onPointerMove,
|
|
102
|
+
onPointerUp,
|
|
103
|
+
onLostPointerCapture,
|
|
104
|
+
style: {
|
|
105
|
+
touchAction: "none",
|
|
106
|
+
WebkitUserSelect: "none",
|
|
107
|
+
userSelect: "none",
|
|
108
|
+
WebkitTouchCallout: "none"
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function useAxisKeyboard(options) {
|
|
113
|
+
const latest = react.useRef(options);
|
|
114
|
+
react.useEffect(() => {
|
|
115
|
+
latest.current = options;
|
|
116
|
+
});
|
|
117
|
+
return {
|
|
118
|
+
onKeyDown: react.useCallback((event) => {
|
|
119
|
+
const o = latest.current;
|
|
120
|
+
if (o.disabled === true) return;
|
|
121
|
+
const step = o.step ?? 1;
|
|
122
|
+
const large = o.largeStep ?? 10;
|
|
123
|
+
const axis = o.axis ?? "both";
|
|
124
|
+
const allowX = axis === "x" || axis === "both";
|
|
125
|
+
const allowY = axis === "y" || axis === "both";
|
|
126
|
+
const amount = event.shiftKey ? large : step;
|
|
127
|
+
let dx = 0;
|
|
128
|
+
let dy = 0;
|
|
129
|
+
switch (event.key) {
|
|
130
|
+
case "ArrowLeft":
|
|
131
|
+
if (allowX) dx = -amount;
|
|
132
|
+
break;
|
|
133
|
+
case "ArrowRight":
|
|
134
|
+
if (allowX) dx = amount;
|
|
135
|
+
break;
|
|
136
|
+
case "ArrowUp":
|
|
137
|
+
if (allowY) dy = amount;
|
|
138
|
+
else if (allowX) dx = amount;
|
|
139
|
+
break;
|
|
140
|
+
case "ArrowDown":
|
|
141
|
+
if (allowY) dy = -amount;
|
|
142
|
+
else if (allowX) dx = -amount;
|
|
143
|
+
break;
|
|
144
|
+
case "PageUp":
|
|
145
|
+
if (allowY) dy = large;
|
|
146
|
+
else if (allowX) dx = large;
|
|
147
|
+
break;
|
|
148
|
+
case "PageDown":
|
|
149
|
+
if (allowY) dy = -large;
|
|
150
|
+
else if (allowX) dx = -large;
|
|
151
|
+
break;
|
|
152
|
+
case "Home":
|
|
153
|
+
o.onEdge?.("min", allowX ? "x" : "y");
|
|
154
|
+
event.preventDefault();
|
|
155
|
+
return;
|
|
156
|
+
case "End":
|
|
157
|
+
o.onEdge?.("max", allowX ? "x" : "y");
|
|
158
|
+
event.preventDefault();
|
|
159
|
+
return;
|
|
160
|
+
default: return;
|
|
161
|
+
}
|
|
162
|
+
if (dx === 0 && dy === 0) return;
|
|
163
|
+
event.preventDefault();
|
|
164
|
+
o.onStep({
|
|
165
|
+
x: dx,
|
|
166
|
+
y: dy
|
|
167
|
+
});
|
|
168
|
+
}, []),
|
|
169
|
+
onKeyUp: react.useCallback((event) => {
|
|
170
|
+
const key = event.key;
|
|
171
|
+
if (key === "ArrowLeft" || key === "ArrowRight" || key === "ArrowUp" || key === "ArrowDown" || key === "PageUp" || key === "PageDown" || key === "Home" || key === "End") latest.current.onEnd?.();
|
|
172
|
+
}, [])
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
//#endregion
|
|
176
|
+
exports.useAxisKeyboard = useAxisKeyboard;
|
|
177
|
+
exports.usePointerDrag = usePointerDrag;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
//#region src/core/usePointerDrag.d.ts
|
|
3
|
+
export interface DragPosition {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
}
|
|
7
|
+
export interface UsePointerDragOptions {
|
|
8
|
+
onMove: (position: DragPosition) => void;
|
|
9
|
+
onStart?: (position: DragPosition) => void;
|
|
10
|
+
onEnd?: () => void;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface PointerDragProps {
|
|
14
|
+
onPointerDown: React.PointerEventHandler<HTMLElement>;
|
|
15
|
+
onPointerMove: React.PointerEventHandler<HTMLElement>;
|
|
16
|
+
onPointerUp: React.PointerEventHandler<HTMLElement>;
|
|
17
|
+
onLostPointerCapture: React.PointerEventHandler<HTMLElement>;
|
|
18
|
+
style: React.CSSProperties;
|
|
19
|
+
}
|
|
20
|
+
export declare function usePointerDrag(options: UsePointerDragOptions): PointerDragProps;
|
|
21
|
+
export interface UseAxisKeyboardOptions {
|
|
22
|
+
onStep: (delta: DragPosition) => void;
|
|
23
|
+
onEdge?: (edge: "min" | "max", axis: "x" | "y") => void;
|
|
24
|
+
onEnd?: () => void;
|
|
25
|
+
step?: number;
|
|
26
|
+
largeStep?: number;
|
|
27
|
+
axis?: "x" | "y" | "both";
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface AxisKeyboardProps {
|
|
31
|
+
onKeyDown: React.KeyboardEventHandler<HTMLElement>;
|
|
32
|
+
onKeyUp: React.KeyboardEventHandler<HTMLElement>;
|
|
33
|
+
}
|
|
34
|
+
export declare function useAxisKeyboard(options: UseAxisKeyboardOptions): AxisKeyboardProps;
|
|
35
|
+
//#endregion
|