@cck-ui/hooks 0.18.5 → 0.20.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/cjs/index.cjs +4 -0
- package/cjs/use-clipboard/use-clipboard.cjs +59 -0
- package/cjs/use-clipboard/use-clipboard.cjs.map +1 -0
- package/cjs/use-timeout-fn/use-timeout-fn.cjs +43 -0
- package/cjs/use-timeout-fn/use-timeout-fn.cjs.map +1 -0
- package/cjs/utils/is/is.cjs +7 -0
- package/cjs/utils/is/is.cjs.map +1 -0
- package/esm/index.mjs +3 -1
- package/esm/use-clipboard/use-clipboard.mjs +59 -0
- package/esm/use-clipboard/use-clipboard.mjs.map +1 -0
- package/esm/use-timeout-fn/use-timeout-fn.mjs +43 -0
- package/esm/use-timeout-fn/use-timeout-fn.mjs.map +1 -0
- package/esm/utils/is/is.mjs +7 -0
- package/esm/utils/is/is.mjs.map +1 -0
- package/lib/index.d.mts +2 -0
- package/lib/index.d.ts +2 -0
- package/lib/use-clipboard/use-clipboard.d.ts +45 -0
- package/lib/use-timeout-fn/use-timeout-fn.d.ts +34 -0
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/is/is.d.ts +1 -0
- package/package.json +1 -1
package/cjs/index.cjs
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_use_timeout_fn = require("./use-timeout-fn/use-timeout-fn.cjs");
|
|
3
|
+
const require_use_clipboard = require("./use-clipboard/use-clipboard.cjs");
|
|
2
4
|
const require_use_id = require("./use-id/use-id.cjs");
|
|
3
5
|
const require_use_isomorphic_effect = require("./use-isomorphic-effect/use-isomorphic-effect.cjs");
|
|
4
6
|
const require_use_splitter = require("./use-splitter/use-splitter.cjs");
|
|
7
|
+
exports.useClipboard = require_use_clipboard.useClipboard;
|
|
5
8
|
exports.useId = require_use_id.useId;
|
|
6
9
|
exports.useIsomorphicEffect = require_use_isomorphic_effect.useIsomorphicEffect;
|
|
7
10
|
exports.useSplitter = require_use_splitter.useSplitter;
|
|
11
|
+
exports.useTimeoutFn = require_use_timeout_fn.useTimeoutFn;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_is = require("../utils/is/is.cjs");
|
|
3
|
+
const require_use_timeout_fn = require("../use-timeout-fn/use-timeout-fn.cjs");
|
|
4
|
+
let vue = require("vue");
|
|
5
|
+
//#region packages/@cck-ui/hooks/src/use-clipboard/use-clipboard.ts
|
|
6
|
+
const defaultNavigator = require_is.isClient ? navigator : void 0;
|
|
7
|
+
function useClipboard(options = {}) {
|
|
8
|
+
const { copiedDuring = 2e3, navigator = defaultNavigator, source } = options;
|
|
9
|
+
const error = (0, vue.ref)(null);
|
|
10
|
+
const text = (0, vue.shallowRef)("");
|
|
11
|
+
const copied = (0, vue.shallowRef)(false);
|
|
12
|
+
const copyPending = (0, vue.shallowRef)(false);
|
|
13
|
+
const timeout = require_use_timeout_fn.useTimeoutFn(() => copied.value = false, copiedDuring, { immediate: false });
|
|
14
|
+
async function copy(value) {
|
|
15
|
+
const resolvedValue = value ?? (0, vue.toValue)(source);
|
|
16
|
+
copyPending.value = true;
|
|
17
|
+
if (!navigator) {
|
|
18
|
+
error.value = /* @__PURE__ */ new Error("useClipboard: can only be used on client side.");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (typeof resolvedValue !== "string") {
|
|
22
|
+
error.value = /* @__PURE__ */ new Error("useClipboard: invalid value");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if ("clipboard" in navigator) {
|
|
26
|
+
const clipboardItem = createClipboardItem(resolvedValue);
|
|
27
|
+
await navigator.clipboard.write([clipboardItem]);
|
|
28
|
+
copied.value = true;
|
|
29
|
+
timeout.start();
|
|
30
|
+
copyPending.value = false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function createClipboardItem(value) {
|
|
34
|
+
if (typeof value === "string") {
|
|
35
|
+
text.value = value;
|
|
36
|
+
return new ClipboardItem({ "text/plain": value });
|
|
37
|
+
}
|
|
38
|
+
return new ClipboardItem({ "text/plain": value().then((resolvedText = "") => {
|
|
39
|
+
text.value = resolvedText;
|
|
40
|
+
return new Blob([resolvedText], { type: "text/plain" });
|
|
41
|
+
}) });
|
|
42
|
+
}
|
|
43
|
+
function reset() {
|
|
44
|
+
copied.value = false;
|
|
45
|
+
error.value = null;
|
|
46
|
+
timeout.clear();
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
error,
|
|
50
|
+
text: (0, vue.shallowReadonly)(text),
|
|
51
|
+
copied: (0, vue.shallowReadonly)(copied),
|
|
52
|
+
copy,
|
|
53
|
+
reset
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
exports.useClipboard = useClipboard;
|
|
58
|
+
|
|
59
|
+
//# sourceMappingURL=use-clipboard.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-clipboard.cjs","names":["isClient","useTimeoutFn"],"sources":["../../src/use-clipboard/use-clipboard.ts"],"sourcesContent":["import { MaybeRefOrGetter, ref, Ref, shallowReadonly, shallowRef, toValue } from 'vue'\nimport { useTimeoutFn } from '../use-timeout-fn/use-timeout-fn'\nimport { isClient } from '../utils'\n\ninterface ConfigurableNavigator {\n navigator?: Navigator\n}\n\nconst defaultNavigator = isClient ? navigator : undefined\n\nexport interface UseClipboardInput<Source> extends ConfigurableNavigator {\n /**\n * @description Enable reading clipboard content on copy/cut events\n * @default false\n */\n read?: boolean\n\n /**\n * @description Default content to copy when `copy()` is called without arguments\n */\n source?: Source\n\n /**\n * @description Time in ms after which the copied state will reset\n * @default 2000\n */\n copiedDuring?: number\n}\n\nexport interface UseClipboardReturnValue<Optional> {\n /**\n * @description Function to copy value to clipboard\n */\n copy: Optional extends true ? (text?: string) => Promise<void> : (text: string) => Promise<void>\n\n /**\n * @description Function to reset copied state and error\n */\n reset: () => void\n\n /**\n * @description Error if copying failed\n */\n error: Ref<Error | null>\n\n /**\n * @description Boolean indicating if the value was copied successfully\n */\n copied: Ref<boolean>\n\n /**\n * @description Current clipboard content (when `read: true`)\n */\n text: Ref<string>\n}\n\ntype ClipboardValue = string | (() => Promise<string | undefined>)\n\nexport function useClipboard(options?: UseClipboardInput<undefined>): UseClipboardReturnValue<false>\nexport function useClipboard(\n options: UseClipboardInput<MaybeRefOrGetter<string>>\n): UseClipboardReturnValue<true>\nexport function useClipboard(\n options: UseClipboardInput<MaybeRefOrGetter<string> | undefined> = {}\n): UseClipboardReturnValue<boolean> {\n const { copiedDuring = 2000, navigator = defaultNavigator, source } = options\n\n const error = ref<Error | null>(null)\n const text = shallowRef('')\n const copied = shallowRef(false)\n const copyPending = shallowRef(false)\n const timeout = useTimeoutFn(() => (copied.value = false), copiedDuring, { immediate: false })\n\n async function copy(value?: ClipboardValue) {\n const resolvedValue = value ?? toValue(source)\n copyPending.value = true\n\n if (!navigator) {\n error.value = new Error('useClipboard: can only be used on client side.')\n return\n }\n\n if (typeof resolvedValue !== 'string') {\n error.value = new Error('useClipboard: invalid value')\n return\n }\n\n if ('clipboard' in navigator) {\n const clipboardItem = createClipboardItem(resolvedValue)\n await navigator.clipboard.write([clipboardItem])\n\n copied.value = true\n timeout.start()\n copyPending.value = false\n }\n }\n\n function createClipboardItem(value: ClipboardValue): ClipboardItem {\n if (typeof value === 'string') {\n text.value = value\n return new ClipboardItem({ 'text/plain': value })\n }\n\n return new ClipboardItem({\n 'text/plain': value().then((resolvedText = '') => {\n text.value = resolvedText\n return new Blob([resolvedText], { type: 'text/plain' })\n }),\n })\n }\n\n function reset() {\n copied.value = false\n error.value = null\n timeout.clear()\n }\n\n return {\n error,\n text: shallowReadonly(text),\n copied: shallowReadonly(copied),\n copy,\n reset,\n }\n}\n"],"mappings":";;;;;AAQA,MAAM,mBAAmBA,WAAAA,WAAW,YAAY,KAAA;AAsDhD,SAAgB,aACd,UAAmE,CAAC,GAClC;CAClC,MAAM,EAAE,eAAe,KAAM,YAAY,kBAAkB,WAAW;CAEtE,MAAM,SAAA,GAAA,IAAA,IAAA,CAA0B,IAAI;CACpC,MAAM,QAAA,GAAA,IAAA,WAAA,CAAkB,EAAE;CAC1B,MAAM,UAAA,GAAA,IAAA,WAAA,CAAoB,KAAK;CAC/B,MAAM,eAAA,GAAA,IAAA,WAAA,CAAyB,KAAK;CACpC,MAAM,UAAUC,uBAAAA,mBAAoB,OAAO,QAAQ,OAAQ,cAAc,EAAE,WAAW,MAAM,CAAC;CAE7F,eAAe,KAAK,OAAwB;EAC1C,MAAM,gBAAgB,UAAA,GAAA,IAAA,QAAA,CAAiB,MAAM;EAC7C,YAAY,QAAQ;EAEpB,IAAI,CAAC,WAAW;GACd,MAAM,wBAAQ,IAAI,MAAM,gDAAgD;GACxE;EACF;EAEA,IAAI,OAAO,kBAAkB,UAAU;GACrC,MAAM,wBAAQ,IAAI,MAAM,6BAA6B;GACrD;EACF;EAEA,IAAI,eAAe,WAAW;GAC5B,MAAM,gBAAgB,oBAAoB,aAAa;GACvD,MAAM,UAAU,UAAU,MAAM,CAAC,aAAa,CAAC;GAE/C,OAAO,QAAQ;GACf,QAAQ,MAAM;GACd,YAAY,QAAQ;EACtB;CACF;CAEA,SAAS,oBAAoB,OAAsC;EACjE,IAAI,OAAO,UAAU,UAAU;GAC7B,KAAK,QAAQ;GACb,OAAO,IAAI,cAAc,EAAE,cAAc,MAAM,CAAC;EAClD;EAEA,OAAO,IAAI,cAAc,EACvB,cAAc,MAAM,CAAC,CAAC,MAAM,eAAe,OAAO;GAChD,KAAK,QAAQ;GACb,OAAO,IAAI,KAAK,CAAC,YAAY,GAAG,EAAE,MAAM,aAAa,CAAC;EACxD,CAAC,EACH,CAAC;CACH;CAEA,SAAS,QAAQ;EACf,OAAO,QAAQ;EACf,MAAM,QAAQ;EACd,QAAQ,MAAM;CAChB;CAEA,OAAO;EACL;EACA,OAAA,GAAA,IAAA,gBAAA,CAAsB,IAAI;EAC1B,SAAA,GAAA,IAAA,gBAAA,CAAwB,MAAM;EAC9B;EACA;CACF;AACF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_is = require("../utils/is/is.cjs");
|
|
3
|
+
let vue = require("vue");
|
|
4
|
+
//#region packages/@cck-ui/hooks/src/use-timeout-fn/use-timeout-fn.ts
|
|
5
|
+
function useTimeoutFn(callback, delay, options) {
|
|
6
|
+
const { immediate = false, immediateCallback = false } = options;
|
|
7
|
+
const isPending = (0, vue.shallowRef)(false);
|
|
8
|
+
let timer;
|
|
9
|
+
function clear() {
|
|
10
|
+
if (timer) {
|
|
11
|
+
clearTimeout(timer);
|
|
12
|
+
timer = null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function stop() {
|
|
16
|
+
isPending.value = false;
|
|
17
|
+
clear();
|
|
18
|
+
}
|
|
19
|
+
function start(...args) {
|
|
20
|
+
if (immediateCallback) callback();
|
|
21
|
+
clear();
|
|
22
|
+
isPending.value = true;
|
|
23
|
+
timer = setTimeout(() => {
|
|
24
|
+
isPending.value = false;
|
|
25
|
+
timer = null;
|
|
26
|
+
callback(...args);
|
|
27
|
+
}, (0, vue.toValue)(delay));
|
|
28
|
+
}
|
|
29
|
+
if (immediate) {
|
|
30
|
+
isPending.value = true;
|
|
31
|
+
if (require_is.isClient) start();
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
clear,
|
|
35
|
+
isPending: (0, vue.shallowReadonly)(isPending),
|
|
36
|
+
start,
|
|
37
|
+
stop
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
exports.useTimeoutFn = useTimeoutFn;
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=use-timeout-fn.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-timeout-fn.cjs","names":["isClient"],"sources":["../../src/use-timeout-fn/use-timeout-fn.ts"],"sourcesContent":["import { MaybeRefOrGetter, Ref, shallowReadonly, shallowRef, toValue } from 'vue'\nimport { isClient } from '../utils'\n\ninterface Stoppable<StartFnArgs extends any[] = any[]> {\n /**\n * @description A ref indicate whether a stoppable instance is executing\n */\n readonly isPending: Readonly<Ref<boolean>>\n\n /**\n * @description Clear the timer\n */\n clear: () => void\n\n /**\n * @description Stop the effect from executing\n */\n stop: () => void\n\n /**\n * @description Start the effects\n */\n start: (...args: StartFnArgs) => void\n}\n\nexport interface UseTimeoutFnOptions {\n /**\n * @description Start the timer immediately\n * @default false\n */\n immediate?: boolean\n\n /**\n * @description Execute the callback function at the beginning once\n * @default false\n */\n immediateCallback?: boolean\n}\n\nexport type UseTimeoutFnReturnValue<CallbackFn extends (...args: any[]) => any> = Stoppable<\n Parameters<CallbackFn> | []\n>\n\nexport function useTimeoutFn<CallbackFn extends (...args: any[]) => any>(\n callback: CallbackFn,\n delay: MaybeRefOrGetter<number>,\n options: UseTimeoutFnOptions\n): UseTimeoutFnReturnValue<CallbackFn> {\n const { immediate = false, immediateCallback = false } = options\n const isPending = shallowRef(false)\n\n let timer: ReturnType<typeof setTimeout> | null\n\n function clear() {\n if (timer) {\n clearTimeout(timer)\n timer = null\n }\n }\n\n function stop() {\n isPending.value = false\n clear()\n }\n\n function start(...args: any[]) {\n if (immediateCallback) {\n callback()\n }\n clear()\n isPending.value = true\n timer = setTimeout(() => {\n isPending.value = false\n timer = null\n\n callback(...args)\n }, toValue(delay))\n }\n\n if (immediate) {\n isPending.value = true\n if (isClient) {\n start()\n }\n }\n\n return {\n clear,\n isPending: shallowReadonly(isPending),\n start,\n stop,\n }\n}\n"],"mappings":";;;;AA2CA,SAAgB,aACd,UACA,OACA,SACqC;CACrC,MAAM,EAAE,YAAY,OAAO,oBAAoB,UAAU;CACzD,MAAM,aAAA,GAAA,IAAA,WAAA,CAAuB,KAAK;CAElC,IAAI;CAEJ,SAAS,QAAQ;EACf,IAAI,OAAO;GACT,aAAa,KAAK;GAClB,QAAQ;EACV;CACF;CAEA,SAAS,OAAO;EACd,UAAU,QAAQ;EAClB,MAAM;CACR;CAEA,SAAS,MAAM,GAAG,MAAa;EAC7B,IAAI,mBACF,SAAS;EAEX,MAAM;EACN,UAAU,QAAQ;EAClB,QAAQ,iBAAiB;GACvB,UAAU,QAAQ;GAClB,QAAQ;GAER,SAAS,GAAG,IAAI;EAClB,IAAA,GAAA,IAAA,QAAA,CAAW,KAAK,CAAC;CACnB;CAEA,IAAI,WAAW;EACb,UAAU,QAAQ;EAClB,IAAIA,WAAAA,UACF,MAAM;CAEV;CAEA,OAAO;EACL;EACA,YAAA,GAAA,IAAA,gBAAA,CAA2B,SAAS;EACpC;EACA;CACF;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is.cjs","names":[],"sources":["../../../src/utils/is/is.ts"],"sourcesContent":["export const isClient = typeof window !== 'undefined' && typeof document !== 'undefined'\n"],"mappings":";;AAAA,MAAa,WAAW,OAAO,WAAW,eAAe,OAAO,aAAa"}
|
package/esm/index.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { useTimeoutFn } from "./use-timeout-fn/use-timeout-fn.mjs";
|
|
2
|
+
import { useClipboard } from "./use-clipboard/use-clipboard.mjs";
|
|
1
3
|
import { useId } from "./use-id/use-id.mjs";
|
|
2
4
|
import { useIsomorphicEffect } from "./use-isomorphic-effect/use-isomorphic-effect.mjs";
|
|
3
5
|
import { useSplitter } from "./use-splitter/use-splitter.mjs";
|
|
4
|
-
export { useId, useIsomorphicEffect, useSplitter };
|
|
6
|
+
export { useClipboard, useId, useIsomorphicEffect, useSplitter, useTimeoutFn };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { isClient } from "../utils/is/is.mjs";
|
|
3
|
+
import { useTimeoutFn } from "../use-timeout-fn/use-timeout-fn.mjs";
|
|
4
|
+
import { ref, shallowReadonly, shallowRef, toValue } from "vue";
|
|
5
|
+
//#region packages/@cck-ui/hooks/src/use-clipboard/use-clipboard.ts
|
|
6
|
+
const defaultNavigator = isClient ? navigator : void 0;
|
|
7
|
+
function useClipboard(options = {}) {
|
|
8
|
+
const { copiedDuring = 2e3, navigator = defaultNavigator, source } = options;
|
|
9
|
+
const error = ref(null);
|
|
10
|
+
const text = shallowRef("");
|
|
11
|
+
const copied = shallowRef(false);
|
|
12
|
+
const copyPending = shallowRef(false);
|
|
13
|
+
const timeout = useTimeoutFn(() => copied.value = false, copiedDuring, { immediate: false });
|
|
14
|
+
async function copy(value) {
|
|
15
|
+
const resolvedValue = value ?? toValue(source);
|
|
16
|
+
copyPending.value = true;
|
|
17
|
+
if (!navigator) {
|
|
18
|
+
error.value = /* @__PURE__ */ new Error("useClipboard: can only be used on client side.");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (typeof resolvedValue !== "string") {
|
|
22
|
+
error.value = /* @__PURE__ */ new Error("useClipboard: invalid value");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if ("clipboard" in navigator) {
|
|
26
|
+
const clipboardItem = createClipboardItem(resolvedValue);
|
|
27
|
+
await navigator.clipboard.write([clipboardItem]);
|
|
28
|
+
copied.value = true;
|
|
29
|
+
timeout.start();
|
|
30
|
+
copyPending.value = false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function createClipboardItem(value) {
|
|
34
|
+
if (typeof value === "string") {
|
|
35
|
+
text.value = value;
|
|
36
|
+
return new ClipboardItem({ "text/plain": value });
|
|
37
|
+
}
|
|
38
|
+
return new ClipboardItem({ "text/plain": value().then((resolvedText = "") => {
|
|
39
|
+
text.value = resolvedText;
|
|
40
|
+
return new Blob([resolvedText], { type: "text/plain" });
|
|
41
|
+
}) });
|
|
42
|
+
}
|
|
43
|
+
function reset() {
|
|
44
|
+
copied.value = false;
|
|
45
|
+
error.value = null;
|
|
46
|
+
timeout.clear();
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
error,
|
|
50
|
+
text: shallowReadonly(text),
|
|
51
|
+
copied: shallowReadonly(copied),
|
|
52
|
+
copy,
|
|
53
|
+
reset
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { useClipboard };
|
|
58
|
+
|
|
59
|
+
//# sourceMappingURL=use-clipboard.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-clipboard.mjs","names":[],"sources":["../../src/use-clipboard/use-clipboard.ts"],"sourcesContent":["import { MaybeRefOrGetter, ref, Ref, shallowReadonly, shallowRef, toValue } from 'vue'\nimport { useTimeoutFn } from '../use-timeout-fn/use-timeout-fn'\nimport { isClient } from '../utils'\n\ninterface ConfigurableNavigator {\n navigator?: Navigator\n}\n\nconst defaultNavigator = isClient ? navigator : undefined\n\nexport interface UseClipboardInput<Source> extends ConfigurableNavigator {\n /**\n * @description Enable reading clipboard content on copy/cut events\n * @default false\n */\n read?: boolean\n\n /**\n * @description Default content to copy when `copy()` is called without arguments\n */\n source?: Source\n\n /**\n * @description Time in ms after which the copied state will reset\n * @default 2000\n */\n copiedDuring?: number\n}\n\nexport interface UseClipboardReturnValue<Optional> {\n /**\n * @description Function to copy value to clipboard\n */\n copy: Optional extends true ? (text?: string) => Promise<void> : (text: string) => Promise<void>\n\n /**\n * @description Function to reset copied state and error\n */\n reset: () => void\n\n /**\n * @description Error if copying failed\n */\n error: Ref<Error | null>\n\n /**\n * @description Boolean indicating if the value was copied successfully\n */\n copied: Ref<boolean>\n\n /**\n * @description Current clipboard content (when `read: true`)\n */\n text: Ref<string>\n}\n\ntype ClipboardValue = string | (() => Promise<string | undefined>)\n\nexport function useClipboard(options?: UseClipboardInput<undefined>): UseClipboardReturnValue<false>\nexport function useClipboard(\n options: UseClipboardInput<MaybeRefOrGetter<string>>\n): UseClipboardReturnValue<true>\nexport function useClipboard(\n options: UseClipboardInput<MaybeRefOrGetter<string> | undefined> = {}\n): UseClipboardReturnValue<boolean> {\n const { copiedDuring = 2000, navigator = defaultNavigator, source } = options\n\n const error = ref<Error | null>(null)\n const text = shallowRef('')\n const copied = shallowRef(false)\n const copyPending = shallowRef(false)\n const timeout = useTimeoutFn(() => (copied.value = false), copiedDuring, { immediate: false })\n\n async function copy(value?: ClipboardValue) {\n const resolvedValue = value ?? toValue(source)\n copyPending.value = true\n\n if (!navigator) {\n error.value = new Error('useClipboard: can only be used on client side.')\n return\n }\n\n if (typeof resolvedValue !== 'string') {\n error.value = new Error('useClipboard: invalid value')\n return\n }\n\n if ('clipboard' in navigator) {\n const clipboardItem = createClipboardItem(resolvedValue)\n await navigator.clipboard.write([clipboardItem])\n\n copied.value = true\n timeout.start()\n copyPending.value = false\n }\n }\n\n function createClipboardItem(value: ClipboardValue): ClipboardItem {\n if (typeof value === 'string') {\n text.value = value\n return new ClipboardItem({ 'text/plain': value })\n }\n\n return new ClipboardItem({\n 'text/plain': value().then((resolvedText = '') => {\n text.value = resolvedText\n return new Blob([resolvedText], { type: 'text/plain' })\n }),\n })\n }\n\n function reset() {\n copied.value = false\n error.value = null\n timeout.clear()\n }\n\n return {\n error,\n text: shallowReadonly(text),\n copied: shallowReadonly(copied),\n copy,\n reset,\n }\n}\n"],"mappings":";;;;;AAQA,MAAM,mBAAmB,WAAW,YAAY,KAAA;AAsDhD,SAAgB,aACd,UAAmE,CAAC,GAClC;CAClC,MAAM,EAAE,eAAe,KAAM,YAAY,kBAAkB,WAAW;CAEtE,MAAM,QAAQ,IAAkB,IAAI;CACpC,MAAM,OAAO,WAAW,EAAE;CAC1B,MAAM,SAAS,WAAW,KAAK;CAC/B,MAAM,cAAc,WAAW,KAAK;CACpC,MAAM,UAAU,mBAAoB,OAAO,QAAQ,OAAQ,cAAc,EAAE,WAAW,MAAM,CAAC;CAE7F,eAAe,KAAK,OAAwB;EAC1C,MAAM,gBAAgB,SAAS,QAAQ,MAAM;EAC7C,YAAY,QAAQ;EAEpB,IAAI,CAAC,WAAW;GACd,MAAM,wBAAQ,IAAI,MAAM,gDAAgD;GACxE;EACF;EAEA,IAAI,OAAO,kBAAkB,UAAU;GACrC,MAAM,wBAAQ,IAAI,MAAM,6BAA6B;GACrD;EACF;EAEA,IAAI,eAAe,WAAW;GAC5B,MAAM,gBAAgB,oBAAoB,aAAa;GACvD,MAAM,UAAU,UAAU,MAAM,CAAC,aAAa,CAAC;GAE/C,OAAO,QAAQ;GACf,QAAQ,MAAM;GACd,YAAY,QAAQ;EACtB;CACF;CAEA,SAAS,oBAAoB,OAAsC;EACjE,IAAI,OAAO,UAAU,UAAU;GAC7B,KAAK,QAAQ;GACb,OAAO,IAAI,cAAc,EAAE,cAAc,MAAM,CAAC;EAClD;EAEA,OAAO,IAAI,cAAc,EACvB,cAAc,MAAM,CAAC,CAAC,MAAM,eAAe,OAAO;GAChD,KAAK,QAAQ;GACb,OAAO,IAAI,KAAK,CAAC,YAAY,GAAG,EAAE,MAAM,aAAa,CAAC;EACxD,CAAC,EACH,CAAC;CACH;CAEA,SAAS,QAAQ;EACf,OAAO,QAAQ;EACf,MAAM,QAAQ;EACd,QAAQ,MAAM;CAChB;CAEA,OAAO;EACL;EACA,MAAM,gBAAgB,IAAI;EAC1B,QAAQ,gBAAgB,MAAM;EAC9B;EACA;CACF;AACF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { isClient } from "../utils/is/is.mjs";
|
|
3
|
+
import { shallowReadonly, shallowRef, toValue } from "vue";
|
|
4
|
+
//#region packages/@cck-ui/hooks/src/use-timeout-fn/use-timeout-fn.ts
|
|
5
|
+
function useTimeoutFn(callback, delay, options) {
|
|
6
|
+
const { immediate = false, immediateCallback = false } = options;
|
|
7
|
+
const isPending = shallowRef(false);
|
|
8
|
+
let timer;
|
|
9
|
+
function clear() {
|
|
10
|
+
if (timer) {
|
|
11
|
+
clearTimeout(timer);
|
|
12
|
+
timer = null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function stop() {
|
|
16
|
+
isPending.value = false;
|
|
17
|
+
clear();
|
|
18
|
+
}
|
|
19
|
+
function start(...args) {
|
|
20
|
+
if (immediateCallback) callback();
|
|
21
|
+
clear();
|
|
22
|
+
isPending.value = true;
|
|
23
|
+
timer = setTimeout(() => {
|
|
24
|
+
isPending.value = false;
|
|
25
|
+
timer = null;
|
|
26
|
+
callback(...args);
|
|
27
|
+
}, toValue(delay));
|
|
28
|
+
}
|
|
29
|
+
if (immediate) {
|
|
30
|
+
isPending.value = true;
|
|
31
|
+
if (isClient) start();
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
clear,
|
|
35
|
+
isPending: shallowReadonly(isPending),
|
|
36
|
+
start,
|
|
37
|
+
stop
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { useTimeoutFn };
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=use-timeout-fn.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-timeout-fn.mjs","names":[],"sources":["../../src/use-timeout-fn/use-timeout-fn.ts"],"sourcesContent":["import { MaybeRefOrGetter, Ref, shallowReadonly, shallowRef, toValue } from 'vue'\nimport { isClient } from '../utils'\n\ninterface Stoppable<StartFnArgs extends any[] = any[]> {\n /**\n * @description A ref indicate whether a stoppable instance is executing\n */\n readonly isPending: Readonly<Ref<boolean>>\n\n /**\n * @description Clear the timer\n */\n clear: () => void\n\n /**\n * @description Stop the effect from executing\n */\n stop: () => void\n\n /**\n * @description Start the effects\n */\n start: (...args: StartFnArgs) => void\n}\n\nexport interface UseTimeoutFnOptions {\n /**\n * @description Start the timer immediately\n * @default false\n */\n immediate?: boolean\n\n /**\n * @description Execute the callback function at the beginning once\n * @default false\n */\n immediateCallback?: boolean\n}\n\nexport type UseTimeoutFnReturnValue<CallbackFn extends (...args: any[]) => any> = Stoppable<\n Parameters<CallbackFn> | []\n>\n\nexport function useTimeoutFn<CallbackFn extends (...args: any[]) => any>(\n callback: CallbackFn,\n delay: MaybeRefOrGetter<number>,\n options: UseTimeoutFnOptions\n): UseTimeoutFnReturnValue<CallbackFn> {\n const { immediate = false, immediateCallback = false } = options\n const isPending = shallowRef(false)\n\n let timer: ReturnType<typeof setTimeout> | null\n\n function clear() {\n if (timer) {\n clearTimeout(timer)\n timer = null\n }\n }\n\n function stop() {\n isPending.value = false\n clear()\n }\n\n function start(...args: any[]) {\n if (immediateCallback) {\n callback()\n }\n clear()\n isPending.value = true\n timer = setTimeout(() => {\n isPending.value = false\n timer = null\n\n callback(...args)\n }, toValue(delay))\n }\n\n if (immediate) {\n isPending.value = true\n if (isClient) {\n start()\n }\n }\n\n return {\n clear,\n isPending: shallowReadonly(isPending),\n start,\n stop,\n }\n}\n"],"mappings":";;;;AA2CA,SAAgB,aACd,UACA,OACA,SACqC;CACrC,MAAM,EAAE,YAAY,OAAO,oBAAoB,UAAU;CACzD,MAAM,YAAY,WAAW,KAAK;CAElC,IAAI;CAEJ,SAAS,QAAQ;EACf,IAAI,OAAO;GACT,aAAa,KAAK;GAClB,QAAQ;EACV;CACF;CAEA,SAAS,OAAO;EACd,UAAU,QAAQ;EAClB,MAAM;CACR;CAEA,SAAS,MAAM,GAAG,MAAa;EAC7B,IAAI,mBACF,SAAS;EAEX,MAAM;EACN,UAAU,QAAQ;EAClB,QAAQ,iBAAiB;GACvB,UAAU,QAAQ;GAClB,QAAQ;GAER,SAAS,GAAG,IAAI;EAClB,GAAG,QAAQ,KAAK,CAAC;CACnB;CAEA,IAAI,WAAW;EACb,UAAU,QAAQ;EAClB,IAAI,UACF,MAAM;CAEV;CAEA,OAAO;EACL;EACA,WAAW,gBAAgB,SAAS;EACpC;EACA;CACF;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is.mjs","names":[],"sources":["../../../src/utils/is/is.ts"],"sourcesContent":["export const isClient = typeof window !== 'undefined' && typeof document !== 'undefined'\n"],"mappings":";;AAAA,MAAa,WAAW,OAAO,WAAW,eAAe,OAAO,aAAa"}
|
package/lib/index.d.mts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
export { useClipboard } from './use-clipboard/use-clipboard';
|
|
1
2
|
export { useId } from './use-id/use-id';
|
|
2
3
|
export { useIsomorphicEffect } from './use-isomorphic-effect/use-isomorphic-effect';
|
|
3
4
|
export { useSplitter } from './use-splitter/use-splitter';
|
|
5
|
+
export { useTimeoutFn } from './use-timeout-fn/use-timeout-fn';
|
|
4
6
|
export type { UseSplitterPanel, UseSplitterOptions, UseSplitterReturnValue, UseSplitterRedistributeInput, UseSplitterRedistributeFn, UseSplitterResolvedPanel, SplitterPaneSize, SplitterStep, } from './use-splitter/use-splitter';
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
export { useClipboard } from './use-clipboard/use-clipboard';
|
|
1
2
|
export { useId } from './use-id/use-id';
|
|
2
3
|
export { useIsomorphicEffect } from './use-isomorphic-effect/use-isomorphic-effect';
|
|
3
4
|
export { useSplitter } from './use-splitter/use-splitter';
|
|
5
|
+
export { useTimeoutFn } from './use-timeout-fn/use-timeout-fn';
|
|
4
6
|
export type { UseSplitterPanel, UseSplitterOptions, UseSplitterReturnValue, UseSplitterRedistributeInput, UseSplitterRedistributeFn, UseSplitterResolvedPanel, SplitterPaneSize, SplitterStep, } from './use-splitter/use-splitter';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { MaybeRefOrGetter, Ref } from 'vue';
|
|
2
|
+
interface ConfigurableNavigator {
|
|
3
|
+
navigator?: Navigator;
|
|
4
|
+
}
|
|
5
|
+
export interface UseClipboardInput<Source> extends ConfigurableNavigator {
|
|
6
|
+
/**
|
|
7
|
+
* @description Enable reading clipboard content on copy/cut events
|
|
8
|
+
* @default false
|
|
9
|
+
*/
|
|
10
|
+
read?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* @description Default content to copy when `copy()` is called without arguments
|
|
13
|
+
*/
|
|
14
|
+
source?: Source;
|
|
15
|
+
/**
|
|
16
|
+
* @description Time in ms after which the copied state will reset
|
|
17
|
+
* @default 2000
|
|
18
|
+
*/
|
|
19
|
+
copiedDuring?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface UseClipboardReturnValue<Optional> {
|
|
22
|
+
/**
|
|
23
|
+
* @description Function to copy value to clipboard
|
|
24
|
+
*/
|
|
25
|
+
copy: Optional extends true ? (text?: string) => Promise<void> : (text: string) => Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* @description Function to reset copied state and error
|
|
28
|
+
*/
|
|
29
|
+
reset: () => void;
|
|
30
|
+
/**
|
|
31
|
+
* @description Error if copying failed
|
|
32
|
+
*/
|
|
33
|
+
error: Ref<Error | null>;
|
|
34
|
+
/**
|
|
35
|
+
* @description Boolean indicating if the value was copied successfully
|
|
36
|
+
*/
|
|
37
|
+
copied: Ref<boolean>;
|
|
38
|
+
/**
|
|
39
|
+
* @description Current clipboard content (when `read: true`)
|
|
40
|
+
*/
|
|
41
|
+
text: Ref<string>;
|
|
42
|
+
}
|
|
43
|
+
export declare function useClipboard(options?: UseClipboardInput<undefined>): UseClipboardReturnValue<false>;
|
|
44
|
+
export declare function useClipboard(options: UseClipboardInput<MaybeRefOrGetter<string>>): UseClipboardReturnValue<true>;
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { MaybeRefOrGetter, Ref } from 'vue';
|
|
2
|
+
interface Stoppable<StartFnArgs extends any[] = any[]> {
|
|
3
|
+
/**
|
|
4
|
+
* @description A ref indicate whether a stoppable instance is executing
|
|
5
|
+
*/
|
|
6
|
+
readonly isPending: Readonly<Ref<boolean>>;
|
|
7
|
+
/**
|
|
8
|
+
* @description Clear the timer
|
|
9
|
+
*/
|
|
10
|
+
clear: () => void;
|
|
11
|
+
/**
|
|
12
|
+
* @description Stop the effect from executing
|
|
13
|
+
*/
|
|
14
|
+
stop: () => void;
|
|
15
|
+
/**
|
|
16
|
+
* @description Start the effects
|
|
17
|
+
*/
|
|
18
|
+
start: (...args: StartFnArgs) => void;
|
|
19
|
+
}
|
|
20
|
+
export interface UseTimeoutFnOptions {
|
|
21
|
+
/**
|
|
22
|
+
* @description Start the timer immediately
|
|
23
|
+
* @default false
|
|
24
|
+
*/
|
|
25
|
+
immediate?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* @description Execute the callback function at the beginning once
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
immediateCallback?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export type UseTimeoutFnReturnValue<CallbackFn extends (...args: any[]) => any> = Stoppable<Parameters<CallbackFn> | []>;
|
|
33
|
+
export declare function useTimeoutFn<CallbackFn extends (...args: any[]) => any>(callback: CallbackFn, delay: MaybeRefOrGetter<number>, options: UseTimeoutFnOptions): UseTimeoutFnReturnValue<CallbackFn>;
|
|
34
|
+
export {};
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isClient: boolean;
|