@dxos/react-hooks 0.3.11-main.f08de7a → 0.3.11-main.f437bee
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/dist/lib/browser/index.mjs +16 -2
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +22 -9
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/useFileDownload.d.ts +12 -0
- package/dist/types/src/useFileDownload.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/useFileDownload.ts +29 -0
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
// packages/ui/primitives/react-hooks/src/useFileDownload.ts
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
var useFileDownload = () => {
|
|
4
|
+
return useMemo(() => (data, filename) => {
|
|
5
|
+
const url = typeof data === "string" ? data : URL.createObjectURL(data);
|
|
6
|
+
const element = document.createElement("a");
|
|
7
|
+
element.setAttribute("href", url);
|
|
8
|
+
element.setAttribute("download", filename);
|
|
9
|
+
element.setAttribute("target", "download");
|
|
10
|
+
element.click();
|
|
11
|
+
}, []);
|
|
12
|
+
};
|
|
13
|
+
|
|
1
14
|
// packages/ui/primitives/react-hooks/src/useForwardedRef.ts
|
|
2
15
|
import { useRef, useEffect } from "react";
|
|
3
16
|
var useForwardedRef = (ref) => {
|
|
@@ -17,11 +30,11 @@ var useForwardedRef = (ref) => {
|
|
|
17
30
|
|
|
18
31
|
// packages/ui/primitives/react-hooks/src/useId.ts
|
|
19
32
|
import alea from "alea";
|
|
20
|
-
import { useMemo } from "react";
|
|
33
|
+
import { useMemo as useMemo2 } from "react";
|
|
21
34
|
var Alea = alea;
|
|
22
35
|
var prng = new Alea("@dxos/react-hooks");
|
|
23
36
|
var randomString = (n = 4) => prng().toString(16).slice(2, n + 2);
|
|
24
|
-
var useId = (namespace, propsId, opts) =>
|
|
37
|
+
var useId = (namespace, propsId, opts) => useMemo2(() => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`, [
|
|
25
38
|
propsId
|
|
26
39
|
]);
|
|
27
40
|
|
|
@@ -120,6 +133,7 @@ var useMediaQuery = (query, options = {}) => {
|
|
|
120
133
|
};
|
|
121
134
|
export {
|
|
122
135
|
randomString,
|
|
136
|
+
useFileDownload,
|
|
123
137
|
useForwardedRef,
|
|
124
138
|
useId,
|
|
125
139
|
useIsFocused,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/useForwardedRef.ts", "../../../src/useId.ts", "../../../src/useIsFocused.ts", "../../../src/useMediaQuery.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { useRef, useEffect } from 'react';\n\nexport const useForwardedRef = <T>(ref: React.ForwardedRef<T>) => {\n const innerRef = useRef<T>(null);\n\n useEffect(() => {\n if (!ref) {\n return;\n }\n if (typeof ref === 'function') {\n ref(innerRef.current);\n } else {\n ref.current = innerRef.current;\n }\n });\n\n return innerRef;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport alea from 'alea';\nimport { useMemo } from 'react';\n\ninterface PrngFactory {\n new (seed?: string): () => number;\n}\n\nconst Alea: PrngFactory = alea as unknown as PrngFactory;\n\nconst prng = new Alea('@dxos/react-hooks');\n\n// TODO(burdon): Replace with PublicKey.random().\nexport const randomString = (n = 4) =>\n prng()\n .toString(16)\n .slice(2, n + 2);\n\nexport const useId = (namespace: string, propsId?: string, opts?: Partial<{ n: number }>) =>\n useMemo(() => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`, [propsId]);\n", "//\n// Copyright 2022 DXOS.org\n//\n\n// Based upon the useIsFocused hook which is part of the `rci` project:\n/// https://github.com/leonardodino/rci/blob/main/packages/use-is-focused\n\nimport { useEffect, useRef, useState, type RefObject } from 'react';\n\nexport const useIsFocused = (inputRef: RefObject<HTMLInputElement>) => {\n const [isFocused, setIsFocused] = useState<boolean | undefined>(undefined);\n const isFocusedRef = useRef<boolean | undefined>(isFocused);\n\n isFocusedRef.current = isFocused;\n\n useEffect(() => {\n const input = inputRef.current;\n if (!input) {\n return;\n }\n\n const onFocus = () => setIsFocused(true);\n const onBlur = () => setIsFocused(false);\n input.addEventListener('focus', onFocus);\n input.addEventListener('blur', onBlur);\n\n if (isFocusedRef.current === undefined) {\n setIsFocused(document.activeElement === input);\n }\n\n return () => {\n input.removeEventListener('focus', onFocus);\n input.removeEventListener('blur', onBlur);\n };\n }, [inputRef, setIsFocused]);\n\n return isFocused;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\n// This hook is based on Chakra UI’s `useMediaQuery`: https://github.com/chakra-ui/chakra-ui/blob/main/packages/components/media-query/src/use-media-query.ts\n\nimport { useEffect, useState } from 'react';\n\nexport type UseMediaQueryOptions = {\n fallback?: boolean | boolean[];\n ssr?: boolean;\n};\n\n// TODO(thure): This should be derived from the same source of truth as the Tailwind theme config\nconst breakpointMediaQueries: Record<string, string> = {\n sm: '(min-width: 640px)',\n md: '(min-width: 768px)',\n lg: '(min-width: 1024px)',\n xl: '(min-width: 1280px)',\n '2xl': '(min-width: 1536px)',\n};\n\n/**\n * React hook that tracks state of a CSS media query\n *\n * @param query the media query to match, or a recognized breakpoint token\n * @param options the media query options { fallback, ssr }\n *\n * @see Docs https://chakra-ui.com/docs/hooks/use-media-query\n */\nexport const useMediaQuery = (query: string | string[], options: UseMediaQueryOptions = {}): boolean[] => {\n const { ssr = true, fallback } = options;\n\n const queries = (Array.isArray(query) ? query : [query]).map((query) =>\n query in breakpointMediaQueries ? breakpointMediaQueries[query] : query,\n );\n\n let fallbackValues = Array.isArray(fallback) ? fallback : [fallback];\n fallbackValues = fallbackValues.filter((v) => v != null) as boolean[];\n\n const [value, setValue] = useState(() => {\n return queries.map((query, index) => ({\n media: query,\n matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query).matches,\n }));\n });\n\n useEffect(() => {\n setValue(\n queries.map((query) => ({\n media: query,\n matches: document.defaultView?.matchMedia(query).matches,\n })),\n );\n\n const mql = queries.map((query) => document.defaultView?.matchMedia(query));\n\n const handler = (evt: MediaQueryListEvent) => {\n setValue((prev) => {\n return prev.slice().map((item) => {\n if (item.media === evt.media) {\n return { ...item, matches: evt.matches };\n }\n return item;\n });\n });\n };\n\n mql.forEach((mql) => {\n if (typeof mql?.addListener === 'function') {\n mql?.addListener(handler);\n } else {\n mql?.addEventListener('change', handler);\n }\n });\n\n return () => {\n mql.forEach((mql) => {\n if (typeof mql?.removeListener === 'function') {\n mql?.removeListener(handler);\n } else {\n mql?.removeEventListener('change', handler);\n }\n });\n };\n }, [document.defaultView]);\n\n return value.map((item) => !!item.matches);\n};\n"],
|
|
5
|
-
"mappings": ";AAIA,SAASA,QAAQC,iBAAiB;AAE3B,IAAMC,kBAAkB,CAAIC,QAAAA;AACjC,QAAMC,WAAWC,OAAU,IAAA;AAE3BC,YAAU,MAAA;AACR,QAAI,CAACH,KAAK;AACR;IACF;AACA,QAAI,OAAOA,QAAQ,YAAY;AAC7BA,UAAIC,SAASG,OAAO;IACtB,OAAO;AACLJ,UAAII,UAAUH,SAASG;IACzB;EACF,CAAA;AAEA,SAAOH;AACT;;;ACjBA,OAAOI,UAAU;AACjB,SAASC,
|
|
6
|
-
"names": ["useRef", "useEffect", "useForwardedRef", "ref", "innerRef", "useRef", "useEffect", "current", "alea", "useMemo", "Alea", "alea", "prng", "randomString", "n", "toString", "slice", "useId", "namespace", "propsId", "opts", "useMemo", "useEffect", "useRef", "useState", "useIsFocused", "inputRef", "isFocused", "setIsFocused", "useState", "undefined", "isFocusedRef", "useRef", "current", "useEffect", "input", "onFocus", "onBlur", "addEventListener", "document", "activeElement", "removeEventListener", "useEffect", "useState", "breakpointMediaQueries", "sm", "md", "lg", "xl", "useMediaQuery", "query", "options", "ssr", "fallback", "queries", "Array", "isArray", "map", "fallbackValues", "filter", "v", "value", "setValue", "useState", "index", "media", "matches", "document", "defaultView", "matchMedia", "useEffect", "mql", "handler", "evt", "prev", "slice", "item", "forEach", "addListener", "addEventListener", "removeListener", "removeEventListener"]
|
|
3
|
+
"sources": ["../../../src/useFileDownload.ts", "../../../src/useForwardedRef.ts", "../../../src/useId.ts", "../../../src/useIsFocused.ts", "../../../src/useMediaQuery.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { useMemo } from 'react';\n\n/**\n * File download anchor.\n *\n * ```\n * const download = useDownload();\n * const handleDownload = (data: string) => {\n * download(new Blob([data], { type: 'text/plain' }), 'test.txt');\n * };\n * ```\n */\nexport const useFileDownload = (): ((data: Blob | string, filename: string) => void) => {\n return useMemo(\n () => (data: Blob | string, filename: string) => {\n const url = typeof data === 'string' ? data : URL.createObjectURL(data);\n const element = document.createElement('a');\n element.setAttribute('href', url);\n element.setAttribute('download', filename);\n element.setAttribute('target', 'download');\n element.click();\n },\n [],\n );\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { useRef, useEffect } from 'react';\n\nexport const useForwardedRef = <T>(ref: React.ForwardedRef<T>) => {\n const innerRef = useRef<T>(null);\n\n useEffect(() => {\n if (!ref) {\n return;\n }\n if (typeof ref === 'function') {\n ref(innerRef.current);\n } else {\n ref.current = innerRef.current;\n }\n });\n\n return innerRef;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport alea from 'alea';\nimport { useMemo } from 'react';\n\ninterface PrngFactory {\n new (seed?: string): () => number;\n}\n\nconst Alea: PrngFactory = alea as unknown as PrngFactory;\n\nconst prng = new Alea('@dxos/react-hooks');\n\n// TODO(burdon): Replace with PublicKey.random().\nexport const randomString = (n = 4) =>\n prng()\n .toString(16)\n .slice(2, n + 2);\n\nexport const useId = (namespace: string, propsId?: string, opts?: Partial<{ n: number }>) =>\n useMemo(() => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`, [propsId]);\n", "//\n// Copyright 2022 DXOS.org\n//\n\n// Based upon the useIsFocused hook which is part of the `rci` project:\n/// https://github.com/leonardodino/rci/blob/main/packages/use-is-focused\n\nimport { useEffect, useRef, useState, type RefObject } from 'react';\n\nexport const useIsFocused = (inputRef: RefObject<HTMLInputElement>) => {\n const [isFocused, setIsFocused] = useState<boolean | undefined>(undefined);\n const isFocusedRef = useRef<boolean | undefined>(isFocused);\n\n isFocusedRef.current = isFocused;\n\n useEffect(() => {\n const input = inputRef.current;\n if (!input) {\n return;\n }\n\n const onFocus = () => setIsFocused(true);\n const onBlur = () => setIsFocused(false);\n input.addEventListener('focus', onFocus);\n input.addEventListener('blur', onBlur);\n\n if (isFocusedRef.current === undefined) {\n setIsFocused(document.activeElement === input);\n }\n\n return () => {\n input.removeEventListener('focus', onFocus);\n input.removeEventListener('blur', onBlur);\n };\n }, [inputRef, setIsFocused]);\n\n return isFocused;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\n// This hook is based on Chakra UI’s `useMediaQuery`: https://github.com/chakra-ui/chakra-ui/blob/main/packages/components/media-query/src/use-media-query.ts\n\nimport { useEffect, useState } from 'react';\n\nexport type UseMediaQueryOptions = {\n fallback?: boolean | boolean[];\n ssr?: boolean;\n};\n\n// TODO(thure): This should be derived from the same source of truth as the Tailwind theme config\nconst breakpointMediaQueries: Record<string, string> = {\n sm: '(min-width: 640px)',\n md: '(min-width: 768px)',\n lg: '(min-width: 1024px)',\n xl: '(min-width: 1280px)',\n '2xl': '(min-width: 1536px)',\n};\n\n/**\n * React hook that tracks state of a CSS media query\n *\n * @param query the media query to match, or a recognized breakpoint token\n * @param options the media query options { fallback, ssr }\n *\n * @see Docs https://chakra-ui.com/docs/hooks/use-media-query\n */\nexport const useMediaQuery = (query: string | string[], options: UseMediaQueryOptions = {}): boolean[] => {\n const { ssr = true, fallback } = options;\n\n const queries = (Array.isArray(query) ? query : [query]).map((query) =>\n query in breakpointMediaQueries ? breakpointMediaQueries[query] : query,\n );\n\n let fallbackValues = Array.isArray(fallback) ? fallback : [fallback];\n fallbackValues = fallbackValues.filter((v) => v != null) as boolean[];\n\n const [value, setValue] = useState(() => {\n return queries.map((query, index) => ({\n media: query,\n matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query).matches,\n }));\n });\n\n useEffect(() => {\n setValue(\n queries.map((query) => ({\n media: query,\n matches: document.defaultView?.matchMedia(query).matches,\n })),\n );\n\n const mql = queries.map((query) => document.defaultView?.matchMedia(query));\n\n const handler = (evt: MediaQueryListEvent) => {\n setValue((prev) => {\n return prev.slice().map((item) => {\n if (item.media === evt.media) {\n return { ...item, matches: evt.matches };\n }\n return item;\n });\n });\n };\n\n mql.forEach((mql) => {\n if (typeof mql?.addListener === 'function') {\n mql?.addListener(handler);\n } else {\n mql?.addEventListener('change', handler);\n }\n });\n\n return () => {\n mql.forEach((mql) => {\n if (typeof mql?.removeListener === 'function') {\n mql?.removeListener(handler);\n } else {\n mql?.removeEventListener('change', handler);\n }\n });\n };\n }, [document.defaultView]);\n\n return value.map((item) => !!item.matches);\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["useMemo", "useFileDownload", "useMemo", "data", "filename", "url", "URL", "createObjectURL", "element", "document", "createElement", "setAttribute", "click", "useRef", "useEffect", "useForwardedRef", "ref", "innerRef", "useRef", "useEffect", "current", "alea", "useMemo", "Alea", "alea", "prng", "randomString", "n", "toString", "slice", "useId", "namespace", "propsId", "opts", "useMemo", "useEffect", "useRef", "useState", "useIsFocused", "inputRef", "isFocused", "setIsFocused", "useState", "undefined", "isFocusedRef", "useRef", "current", "useEffect", "input", "onFocus", "onBlur", "addEventListener", "document", "activeElement", "removeEventListener", "useEffect", "useState", "breakpointMediaQueries", "sm", "md", "lg", "xl", "useMediaQuery", "query", "options", "ssr", "fallback", "queries", "Array", "isArray", "map", "fallbackValues", "filter", "v", "value", "setValue", "useState", "index", "media", "matches", "document", "defaultView", "matchMedia", "useEffect", "mql", "handler", "evt", "prev", "slice", "item", "forEach", "addListener", "addEventListener", "removeListener", "removeEventListener"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/ui/primitives/react-hooks/src/useForwardedRef.ts":{"bytes":1711,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useId.ts":{"bytes":2123,"imports":[{"path":"alea","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useIsFocused.ts":{"bytes":3922,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useMediaQuery.ts":{"bytes":9262,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/index.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/ui/primitives/react-hooks/src/useFileDownload.ts":{"bytes":2684,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useForwardedRef.ts":{"bytes":1711,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useId.ts":{"bytes":2123,"imports":[{"path":"alea","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useIsFocused.ts":{"bytes":3922,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useMediaQuery.ts":{"bytes":9262,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/index.ts":{"bytes":886,"imports":[{"path":"packages/ui/primitives/react-hooks/src/useFileDownload.ts","kind":"import-statement","original":"./useFileDownload"},{"path":"packages/ui/primitives/react-hooks/src/useForwardedRef.ts","kind":"import-statement","original":"./useForwardedRef"},{"path":"packages/ui/primitives/react-hooks/src/useId.ts","kind":"import-statement","original":"./useId"},{"path":"packages/ui/primitives/react-hooks/src/useIsFocused.ts","kind":"import-statement","original":"./useIsFocused"},{"path":"packages/ui/primitives/react-hooks/src/useMediaQuery.ts","kind":"import-statement","original":"./useMediaQuery"}],"format":"esm"}},"outputs":{"packages/ui/primitives/react-hooks/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":9924},"packages/ui/primitives/react-hooks/dist/lib/browser/index.mjs":{"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"alea","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"exports":["randomString","useFileDownload","useForwardedRef","useId","useIsFocused","useMediaQuery"],"entryPoint":"packages/ui/primitives/react-hooks/src/index.ts","inputs":{"packages/ui/primitives/react-hooks/src/useFileDownload.ts":{"bytesInOutput":403},"packages/ui/primitives/react-hooks/src/index.ts":{"bytesInOutput":0},"packages/ui/primitives/react-hooks/src/useForwardedRef.ts":{"bytesInOutput":316},"packages/ui/primitives/react-hooks/src/useId.ts":{"bytesInOutput":326},"packages/ui/primitives/react-hooks/src/useIsFocused.ts":{"bytesInOutput":819},"packages/ui/primitives/react-hooks/src/useMediaQuery.ts":{"bytesInOutput":1940}},"bytes":4240}}}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
var node_exports = {};
|
|
30
30
|
__export(node_exports, {
|
|
31
31
|
randomString: () => randomString,
|
|
32
|
+
useFileDownload: () => useFileDownload,
|
|
32
33
|
useForwardedRef: () => useForwardedRef,
|
|
33
34
|
useId: () => useId,
|
|
34
35
|
useIsFocused: () => useIsFocused,
|
|
@@ -36,13 +37,24 @@ __export(node_exports, {
|
|
|
36
37
|
});
|
|
37
38
|
module.exports = __toCommonJS(node_exports);
|
|
38
39
|
var import_react = require("react");
|
|
39
|
-
var import_alea = __toESM(require("alea"));
|
|
40
40
|
var import_react2 = require("react");
|
|
41
|
+
var import_alea = __toESM(require("alea"));
|
|
41
42
|
var import_react3 = require("react");
|
|
42
43
|
var import_react4 = require("react");
|
|
44
|
+
var import_react5 = require("react");
|
|
45
|
+
var useFileDownload = () => {
|
|
46
|
+
return (0, import_react.useMemo)(() => (data, filename) => {
|
|
47
|
+
const url = typeof data === "string" ? data : URL.createObjectURL(data);
|
|
48
|
+
const element = document.createElement("a");
|
|
49
|
+
element.setAttribute("href", url);
|
|
50
|
+
element.setAttribute("download", filename);
|
|
51
|
+
element.setAttribute("target", "download");
|
|
52
|
+
element.click();
|
|
53
|
+
}, []);
|
|
54
|
+
};
|
|
43
55
|
var useForwardedRef = (ref) => {
|
|
44
|
-
const innerRef = (0,
|
|
45
|
-
(0,
|
|
56
|
+
const innerRef = (0, import_react2.useRef)(null);
|
|
57
|
+
(0, import_react2.useEffect)(() => {
|
|
46
58
|
if (!ref) {
|
|
47
59
|
return;
|
|
48
60
|
}
|
|
@@ -57,14 +69,14 @@ var useForwardedRef = (ref) => {
|
|
|
57
69
|
var Alea = import_alea.default;
|
|
58
70
|
var prng = new Alea("@dxos/react-hooks");
|
|
59
71
|
var randomString = (n = 4) => prng().toString(16).slice(2, n + 2);
|
|
60
|
-
var useId = (namespace, propsId, opts) => (0,
|
|
72
|
+
var useId = (namespace, propsId, opts) => (0, import_react3.useMemo)(() => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`, [
|
|
61
73
|
propsId
|
|
62
74
|
]);
|
|
63
75
|
var useIsFocused = (inputRef) => {
|
|
64
|
-
const [isFocused, setIsFocused] = (0,
|
|
65
|
-
const isFocusedRef = (0,
|
|
76
|
+
const [isFocused, setIsFocused] = (0, import_react4.useState)(void 0);
|
|
77
|
+
const isFocusedRef = (0, import_react4.useRef)(isFocused);
|
|
66
78
|
isFocusedRef.current = isFocused;
|
|
67
|
-
(0,
|
|
79
|
+
(0, import_react4.useEffect)(() => {
|
|
68
80
|
const input = inputRef.current;
|
|
69
81
|
if (!input) {
|
|
70
82
|
return;
|
|
@@ -102,13 +114,13 @@ var useMediaQuery = (query, options = {}) => {
|
|
|
102
114
|
fallback
|
|
103
115
|
];
|
|
104
116
|
fallbackValues = fallbackValues.filter((v) => v != null);
|
|
105
|
-
const [value, setValue] = (0,
|
|
117
|
+
const [value, setValue] = (0, import_react5.useState)(() => {
|
|
106
118
|
return queries.map((query2, index) => ({
|
|
107
119
|
media: query2,
|
|
108
120
|
matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query2).matches
|
|
109
121
|
}));
|
|
110
122
|
});
|
|
111
|
-
(0,
|
|
123
|
+
(0, import_react5.useEffect)(() => {
|
|
112
124
|
setValue(queries.map((query2) => ({
|
|
113
125
|
media: query2,
|
|
114
126
|
matches: document.defaultView?.matchMedia(query2).matches
|
|
@@ -151,6 +163,7 @@ var useMediaQuery = (query, options = {}) => {
|
|
|
151
163
|
// Annotate the CommonJS export names for ESM import in node:
|
|
152
164
|
0 && (module.exports = {
|
|
153
165
|
randomString,
|
|
166
|
+
useFileDownload,
|
|
154
167
|
useForwardedRef,
|
|
155
168
|
useId,
|
|
156
169
|
useIsFocused,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/useForwardedRef.ts", "../../../src/useId.ts", "../../../src/useIsFocused.ts", "../../../src/useMediaQuery.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { useRef, useEffect } from 'react';\n\nexport const useForwardedRef = <T>(ref: React.ForwardedRef<T>) => {\n const innerRef = useRef<T>(null);\n\n useEffect(() => {\n if (!ref) {\n return;\n }\n if (typeof ref === 'function') {\n ref(innerRef.current);\n } else {\n ref.current = innerRef.current;\n }\n });\n\n return innerRef;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport alea from 'alea';\nimport { useMemo } from 'react';\n\ninterface PrngFactory {\n new (seed?: string): () => number;\n}\n\nconst Alea: PrngFactory = alea as unknown as PrngFactory;\n\nconst prng = new Alea('@dxos/react-hooks');\n\n// TODO(burdon): Replace with PublicKey.random().\nexport const randomString = (n = 4) =>\n prng()\n .toString(16)\n .slice(2, n + 2);\n\nexport const useId = (namespace: string, propsId?: string, opts?: Partial<{ n: number }>) =>\n useMemo(() => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`, [propsId]);\n", "//\n// Copyright 2022 DXOS.org\n//\n\n// Based upon the useIsFocused hook which is part of the `rci` project:\n/// https://github.com/leonardodino/rci/blob/main/packages/use-is-focused\n\nimport { useEffect, useRef, useState, type RefObject } from 'react';\n\nexport const useIsFocused = (inputRef: RefObject<HTMLInputElement>) => {\n const [isFocused, setIsFocused] = useState<boolean | undefined>(undefined);\n const isFocusedRef = useRef<boolean | undefined>(isFocused);\n\n isFocusedRef.current = isFocused;\n\n useEffect(() => {\n const input = inputRef.current;\n if (!input) {\n return;\n }\n\n const onFocus = () => setIsFocused(true);\n const onBlur = () => setIsFocused(false);\n input.addEventListener('focus', onFocus);\n input.addEventListener('blur', onBlur);\n\n if (isFocusedRef.current === undefined) {\n setIsFocused(document.activeElement === input);\n }\n\n return () => {\n input.removeEventListener('focus', onFocus);\n input.removeEventListener('blur', onBlur);\n };\n }, [inputRef, setIsFocused]);\n\n return isFocused;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\n// This hook is based on Chakra UI’s `useMediaQuery`: https://github.com/chakra-ui/chakra-ui/blob/main/packages/components/media-query/src/use-media-query.ts\n\nimport { useEffect, useState } from 'react';\n\nexport type UseMediaQueryOptions = {\n fallback?: boolean | boolean[];\n ssr?: boolean;\n};\n\n// TODO(thure): This should be derived from the same source of truth as the Tailwind theme config\nconst breakpointMediaQueries: Record<string, string> = {\n sm: '(min-width: 640px)',\n md: '(min-width: 768px)',\n lg: '(min-width: 1024px)',\n xl: '(min-width: 1280px)',\n '2xl': '(min-width: 1536px)',\n};\n\n/**\n * React hook that tracks state of a CSS media query\n *\n * @param query the media query to match, or a recognized breakpoint token\n * @param options the media query options { fallback, ssr }\n *\n * @see Docs https://chakra-ui.com/docs/hooks/use-media-query\n */\nexport const useMediaQuery = (query: string | string[], options: UseMediaQueryOptions = {}): boolean[] => {\n const { ssr = true, fallback } = options;\n\n const queries = (Array.isArray(query) ? query : [query]).map((query) =>\n query in breakpointMediaQueries ? breakpointMediaQueries[query] : query,\n );\n\n let fallbackValues = Array.isArray(fallback) ? fallback : [fallback];\n fallbackValues = fallbackValues.filter((v) => v != null) as boolean[];\n\n const [value, setValue] = useState(() => {\n return queries.map((query, index) => ({\n media: query,\n matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query).matches,\n }));\n });\n\n useEffect(() => {\n setValue(\n queries.map((query) => ({\n media: query,\n matches: document.defaultView?.matchMedia(query).matches,\n })),\n );\n\n const mql = queries.map((query) => document.defaultView?.matchMedia(query));\n\n const handler = (evt: MediaQueryListEvent) => {\n setValue((prev) => {\n return prev.slice().map((item) => {\n if (item.media === evt.media) {\n return { ...item, matches: evt.matches };\n }\n return item;\n });\n });\n };\n\n mql.forEach((mql) => {\n if (typeof mql?.addListener === 'function') {\n mql?.addListener(handler);\n } else {\n mql?.addEventListener('change', handler);\n }\n });\n\n return () => {\n mql.forEach((mql) => {\n if (typeof mql?.removeListener === 'function') {\n mql?.removeListener(handler);\n } else {\n mql?.removeEventListener('change', handler);\n }\n });\n };\n }, [document.defaultView]);\n\n return value.map((item) => !!item.matches);\n};\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["import_react", "useForwardedRef", "ref", "innerRef", "useRef", "useEffect", "current", "Alea", "alea", "prng", "randomString", "n", "toString", "slice", "useId", "namespace", "propsId", "opts", "
|
|
3
|
+
"sources": ["../../../src/useFileDownload.ts", "../../../src/useForwardedRef.ts", "../../../src/useId.ts", "../../../src/useIsFocused.ts", "../../../src/useMediaQuery.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { useMemo } from 'react';\n\n/**\n * File download anchor.\n *\n * ```\n * const download = useDownload();\n * const handleDownload = (data: string) => {\n * download(new Blob([data], { type: 'text/plain' }), 'test.txt');\n * };\n * ```\n */\nexport const useFileDownload = (): ((data: Blob | string, filename: string) => void) => {\n return useMemo(\n () => (data: Blob | string, filename: string) => {\n const url = typeof data === 'string' ? data : URL.createObjectURL(data);\n const element = document.createElement('a');\n element.setAttribute('href', url);\n element.setAttribute('download', filename);\n element.setAttribute('target', 'download');\n element.click();\n },\n [],\n );\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { useRef, useEffect } from 'react';\n\nexport const useForwardedRef = <T>(ref: React.ForwardedRef<T>) => {\n const innerRef = useRef<T>(null);\n\n useEffect(() => {\n if (!ref) {\n return;\n }\n if (typeof ref === 'function') {\n ref(innerRef.current);\n } else {\n ref.current = innerRef.current;\n }\n });\n\n return innerRef;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport alea from 'alea';\nimport { useMemo } from 'react';\n\ninterface PrngFactory {\n new (seed?: string): () => number;\n}\n\nconst Alea: PrngFactory = alea as unknown as PrngFactory;\n\nconst prng = new Alea('@dxos/react-hooks');\n\n// TODO(burdon): Replace with PublicKey.random().\nexport const randomString = (n = 4) =>\n prng()\n .toString(16)\n .slice(2, n + 2);\n\nexport const useId = (namespace: string, propsId?: string, opts?: Partial<{ n: number }>) =>\n useMemo(() => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`, [propsId]);\n", "//\n// Copyright 2022 DXOS.org\n//\n\n// Based upon the useIsFocused hook which is part of the `rci` project:\n/// https://github.com/leonardodino/rci/blob/main/packages/use-is-focused\n\nimport { useEffect, useRef, useState, type RefObject } from 'react';\n\nexport const useIsFocused = (inputRef: RefObject<HTMLInputElement>) => {\n const [isFocused, setIsFocused] = useState<boolean | undefined>(undefined);\n const isFocusedRef = useRef<boolean | undefined>(isFocused);\n\n isFocusedRef.current = isFocused;\n\n useEffect(() => {\n const input = inputRef.current;\n if (!input) {\n return;\n }\n\n const onFocus = () => setIsFocused(true);\n const onBlur = () => setIsFocused(false);\n input.addEventListener('focus', onFocus);\n input.addEventListener('blur', onBlur);\n\n if (isFocusedRef.current === undefined) {\n setIsFocused(document.activeElement === input);\n }\n\n return () => {\n input.removeEventListener('focus', onFocus);\n input.removeEventListener('blur', onBlur);\n };\n }, [inputRef, setIsFocused]);\n\n return isFocused;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\n// This hook is based on Chakra UI’s `useMediaQuery`: https://github.com/chakra-ui/chakra-ui/blob/main/packages/components/media-query/src/use-media-query.ts\n\nimport { useEffect, useState } from 'react';\n\nexport type UseMediaQueryOptions = {\n fallback?: boolean | boolean[];\n ssr?: boolean;\n};\n\n// TODO(thure): This should be derived from the same source of truth as the Tailwind theme config\nconst breakpointMediaQueries: Record<string, string> = {\n sm: '(min-width: 640px)',\n md: '(min-width: 768px)',\n lg: '(min-width: 1024px)',\n xl: '(min-width: 1280px)',\n '2xl': '(min-width: 1536px)',\n};\n\n/**\n * React hook that tracks state of a CSS media query\n *\n * @param query the media query to match, or a recognized breakpoint token\n * @param options the media query options { fallback, ssr }\n *\n * @see Docs https://chakra-ui.com/docs/hooks/use-media-query\n */\nexport const useMediaQuery = (query: string | string[], options: UseMediaQueryOptions = {}): boolean[] => {\n const { ssr = true, fallback } = options;\n\n const queries = (Array.isArray(query) ? query : [query]).map((query) =>\n query in breakpointMediaQueries ? breakpointMediaQueries[query] : query,\n );\n\n let fallbackValues = Array.isArray(fallback) ? fallback : [fallback];\n fallbackValues = fallbackValues.filter((v) => v != null) as boolean[];\n\n const [value, setValue] = useState(() => {\n return queries.map((query, index) => ({\n media: query,\n matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query).matches,\n }));\n });\n\n useEffect(() => {\n setValue(\n queries.map((query) => ({\n media: query,\n matches: document.defaultView?.matchMedia(query).matches,\n })),\n );\n\n const mql = queries.map((query) => document.defaultView?.matchMedia(query));\n\n const handler = (evt: MediaQueryListEvent) => {\n setValue((prev) => {\n return prev.slice().map((item) => {\n if (item.media === evt.media) {\n return { ...item, matches: evt.matches };\n }\n return item;\n });\n });\n };\n\n mql.forEach((mql) => {\n if (typeof mql?.addListener === 'function') {\n mql?.addListener(handler);\n } else {\n mql?.addEventListener('change', handler);\n }\n });\n\n return () => {\n mql.forEach((mql) => {\n if (typeof mql?.removeListener === 'function') {\n mql?.removeListener(handler);\n } else {\n mql?.removeEventListener('change', handler);\n }\n });\n };\n }, [document.defaultView]);\n\n return value.map((item) => !!item.matches);\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_react", "useFileDownload", "useMemo", "data", "filename", "url", "URL", "createObjectURL", "element", "document", "createElement", "setAttribute", "click", "useForwardedRef", "ref", "innerRef", "useRef", "useEffect", "current", "Alea", "alea", "prng", "randomString", "n", "toString", "slice", "useId", "namespace", "propsId", "opts", "useIsFocused", "inputRef", "isFocused", "setIsFocused", "useState", "undefined", "isFocusedRef", "input", "onFocus", "onBlur", "addEventListener", "activeElement", "removeEventListener", "breakpointMediaQueries", "sm", "md", "lg", "xl", "useMediaQuery", "query", "options", "ssr", "fallback", "queries", "Array", "isArray", "map", "fallbackValues", "filter", "v", "value", "setValue", "index", "media", "matches", "defaultView", "matchMedia", "mql", "handler", "evt", "prev", "item", "forEach", "addListener", "removeListener"]
|
|
7
7
|
}
|
package/dist/lib/node/meta.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/ui/primitives/react-hooks/src/useForwardedRef.ts":{"bytes":1711,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useId.ts":{"bytes":2123,"imports":[{"path":"alea","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useIsFocused.ts":{"bytes":3922,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useMediaQuery.ts":{"bytes":9262,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/index.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/ui/primitives/react-hooks/src/useFileDownload.ts":{"bytes":2684,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useForwardedRef.ts":{"bytes":1711,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useId.ts":{"bytes":2123,"imports":[{"path":"alea","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useIsFocused.ts":{"bytes":3922,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useMediaQuery.ts":{"bytes":9262,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/index.ts":{"bytes":886,"imports":[{"path":"packages/ui/primitives/react-hooks/src/useFileDownload.ts","kind":"import-statement","original":"./useFileDownload"},{"path":"packages/ui/primitives/react-hooks/src/useForwardedRef.ts","kind":"import-statement","original":"./useForwardedRef"},{"path":"packages/ui/primitives/react-hooks/src/useId.ts","kind":"import-statement","original":"./useId"},{"path":"packages/ui/primitives/react-hooks/src/useIsFocused.ts","kind":"import-statement","original":"./useIsFocused"},{"path":"packages/ui/primitives/react-hooks/src/useMediaQuery.ts","kind":"import-statement","original":"./useMediaQuery"}],"format":"esm"}},"outputs":{"packages/ui/primitives/react-hooks/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":9924},"packages/ui/primitives/react-hooks/dist/lib/node/index.cjs":{"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"alea","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"exports":["randomString","useFileDownload","useForwardedRef","useId","useIsFocused","useMediaQuery"],"entryPoint":"packages/ui/primitives/react-hooks/src/index.ts","inputs":{"packages/ui/primitives/react-hooks/src/useFileDownload.ts":{"bytesInOutput":403},"packages/ui/primitives/react-hooks/src/index.ts":{"bytesInOutput":0},"packages/ui/primitives/react-hooks/src/useForwardedRef.ts":{"bytesInOutput":316},"packages/ui/primitives/react-hooks/src/useId.ts":{"bytesInOutput":326},"packages/ui/primitives/react-hooks/src/useIsFocused.ts":{"bytesInOutput":819},"packages/ui/primitives/react-hooks/src/useMediaQuery.ts":{"bytesInOutput":1940}},"bytes":4240}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File download anchor.
|
|
3
|
+
*
|
|
4
|
+
* ```
|
|
5
|
+
* const download = useDownload();
|
|
6
|
+
* const handleDownload = (data: string) => {
|
|
7
|
+
* download(new Blob([data], { type: 'text/plain' }), 'test.txt');
|
|
8
|
+
* };
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare const useFileDownload: () => (data: Blob | string, filename: string) => void;
|
|
12
|
+
//# sourceMappingURL=useFileDownload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFileDownload.d.ts","sourceRoot":"","sources":["../../../src/useFileDownload.ts"],"names":[],"mappings":"AAMA;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,eAAe,IAAI,GAAG,MAAM,YAAY,MAAM,KAAK,IAY9E,CAAC"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { useMemo } from 'react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* File download anchor.
|
|
9
|
+
*
|
|
10
|
+
* ```
|
|
11
|
+
* const download = useDownload();
|
|
12
|
+
* const handleDownload = (data: string) => {
|
|
13
|
+
* download(new Blob([data], { type: 'text/plain' }), 'test.txt');
|
|
14
|
+
* };
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export const useFileDownload = (): ((data: Blob | string, filename: string) => void) => {
|
|
18
|
+
return useMemo(
|
|
19
|
+
() => (data: Blob | string, filename: string) => {
|
|
20
|
+
const url = typeof data === 'string' ? data : URL.createObjectURL(data);
|
|
21
|
+
const element = document.createElement('a');
|
|
22
|
+
element.setAttribute('href', url);
|
|
23
|
+
element.setAttribute('download', filename);
|
|
24
|
+
element.setAttribute('target', 'download');
|
|
25
|
+
element.click();
|
|
26
|
+
},
|
|
27
|
+
[],
|
|
28
|
+
);
|
|
29
|
+
};
|