@zag-js/clipboard 0.53.0 → 0.55.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/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +255 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +222 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
- package/src/clipboard.connect.ts +53 -37
- package/src/clipboard.types.ts +5 -5
package/dist/index.d.mts
CHANGED
|
@@ -63,11 +63,11 @@ interface MachineApi<T extends PropTypes = PropTypes> {
|
|
|
63
63
|
* Copy the value to the clipboard
|
|
64
64
|
*/
|
|
65
65
|
copy(): void;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
getRootProps(): T["element"];
|
|
67
|
+
getLabelProps(): T["label"];
|
|
68
|
+
getControlProps(): T["element"];
|
|
69
|
+
getTriggerProps(): T["button"];
|
|
70
|
+
getInputProps(): T["input"];
|
|
71
71
|
getIndicatorProps(props: IndicatorProps): T["element"];
|
|
72
72
|
}
|
|
73
73
|
|
package/dist/index.d.ts
CHANGED
|
@@ -63,11 +63,11 @@ interface MachineApi<T extends PropTypes = PropTypes> {
|
|
|
63
63
|
* Copy the value to the clipboard
|
|
64
64
|
*/
|
|
65
65
|
copy(): void;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
getRootProps(): T["element"];
|
|
67
|
+
getLabelProps(): T["label"];
|
|
68
|
+
getControlProps(): T["element"];
|
|
69
|
+
getTriggerProps(): T["button"];
|
|
70
|
+
getInputProps(): T["input"];
|
|
71
71
|
getIndicatorProps(props: IndicatorProps): T["element"];
|
|
72
72
|
}
|
|
73
73
|
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,256 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
anatomy: () => anatomy,
|
|
24
|
+
connect: () => connect,
|
|
25
|
+
contextProps: () => contextProps,
|
|
26
|
+
indicatorProps: () => indicatorProps,
|
|
27
|
+
machine: () => machine,
|
|
28
|
+
props: () => props,
|
|
29
|
+
splitIndicatorProps: () => splitIndicatorProps
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(src_exports);
|
|
32
|
+
|
|
33
|
+
// src/clipboard.anatomy.ts
|
|
34
|
+
var import_anatomy = require("@zag-js/anatomy");
|
|
35
|
+
var anatomy = (0, import_anatomy.createAnatomy)("clipboard").parts("root", "control", "trigger", "indicator", "input", "label");
|
|
36
|
+
var parts = anatomy.build();
|
|
37
|
+
|
|
38
|
+
// src/clipboard.connect.ts
|
|
39
|
+
var import_dom_query2 = require("@zag-js/dom-query");
|
|
40
|
+
|
|
41
|
+
// src/clipboard.dom.ts
|
|
42
|
+
var import_dom_query = require("@zag-js/dom-query");
|
|
43
|
+
var dom = (0, import_dom_query.createScope)({
|
|
44
|
+
getRootId: (ctx) => ctx.ids?.root ?? `clip-${ctx.id}`,
|
|
45
|
+
getInputId: (ctx) => ctx.ids?.input ?? `clip-input-${ctx.id}`,
|
|
46
|
+
getLabelId: (ctx) => ctx.ids?.label ?? `clip-label-${ctx.id}`,
|
|
47
|
+
getInputEl: (ctx) => dom.getById(ctx, dom.getInputId(ctx)),
|
|
48
|
+
writeToClipboard: (ctx) => copyText(dom.getDoc(ctx), ctx.value)
|
|
49
|
+
});
|
|
50
|
+
function createNode(doc, text) {
|
|
51
|
+
const node = doc.createElement("pre");
|
|
52
|
+
Object.assign(node.style, {
|
|
53
|
+
width: "1px",
|
|
54
|
+
height: "1px",
|
|
55
|
+
position: "fixed",
|
|
56
|
+
top: "5px"
|
|
57
|
+
});
|
|
58
|
+
node.textContent = text;
|
|
59
|
+
return node;
|
|
60
|
+
}
|
|
61
|
+
function copyNode(node) {
|
|
62
|
+
const win = (0, import_dom_query.getWindow)(node);
|
|
63
|
+
const selection = win.getSelection();
|
|
64
|
+
if (selection == null) {
|
|
65
|
+
return Promise.reject(new Error());
|
|
66
|
+
}
|
|
67
|
+
selection.removeAllRanges();
|
|
68
|
+
const doc = node.ownerDocument;
|
|
69
|
+
const range = doc.createRange();
|
|
70
|
+
range.selectNodeContents(node);
|
|
71
|
+
selection.addRange(range);
|
|
72
|
+
doc.execCommand("copy");
|
|
73
|
+
selection.removeAllRanges();
|
|
74
|
+
return Promise.resolve();
|
|
75
|
+
}
|
|
76
|
+
function copyText(doc, text) {
|
|
77
|
+
const win = doc.defaultView || window;
|
|
78
|
+
if (win.navigator.clipboard?.writeText !== void 0) {
|
|
79
|
+
return win.navigator.clipboard.writeText(text);
|
|
80
|
+
}
|
|
81
|
+
if (!doc.body) {
|
|
82
|
+
return Promise.reject(new Error());
|
|
83
|
+
}
|
|
84
|
+
const node = createNode(doc, text);
|
|
85
|
+
doc.body.appendChild(node);
|
|
86
|
+
copyNode(node);
|
|
87
|
+
doc.body.removeChild(node);
|
|
88
|
+
return Promise.resolve();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/clipboard.connect.ts
|
|
92
|
+
function connect(state, send, normalize) {
|
|
93
|
+
const copied = state.matches("copied");
|
|
94
|
+
return {
|
|
95
|
+
copied,
|
|
96
|
+
value: state.context.value,
|
|
97
|
+
setValue(value) {
|
|
98
|
+
send({ type: "VALUE.SET", value });
|
|
99
|
+
},
|
|
100
|
+
copy() {
|
|
101
|
+
send({ type: "COPY" });
|
|
102
|
+
},
|
|
103
|
+
getRootProps() {
|
|
104
|
+
return normalize.element({
|
|
105
|
+
...parts.root.attrs,
|
|
106
|
+
"data-copied": (0, import_dom_query2.dataAttr)(copied),
|
|
107
|
+
id: dom.getRootId(state.context)
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
getLabelProps() {
|
|
111
|
+
return normalize.label({
|
|
112
|
+
...parts.label.attrs,
|
|
113
|
+
htmlFor: dom.getInputId(state.context),
|
|
114
|
+
"data-copied": (0, import_dom_query2.dataAttr)(copied),
|
|
115
|
+
id: dom.getLabelId(state.context)
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
getControlProps() {
|
|
119
|
+
return normalize.element({
|
|
120
|
+
...parts.control.attrs,
|
|
121
|
+
"data-copied": (0, import_dom_query2.dataAttr)(copied)
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
getInputProps() {
|
|
125
|
+
return normalize.input({
|
|
126
|
+
...parts.input.attrs,
|
|
127
|
+
defaultValue: state.context.value,
|
|
128
|
+
"data-copied": (0, import_dom_query2.dataAttr)(copied),
|
|
129
|
+
readOnly: true,
|
|
130
|
+
"data-readonly": "true",
|
|
131
|
+
id: dom.getInputId(state.context),
|
|
132
|
+
onFocus(event) {
|
|
133
|
+
event.currentTarget.select();
|
|
134
|
+
},
|
|
135
|
+
onCopy() {
|
|
136
|
+
send({ type: "INPUT.COPY" });
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
getTriggerProps() {
|
|
141
|
+
return normalize.button({
|
|
142
|
+
...parts.trigger.attrs,
|
|
143
|
+
"aria-label": copied ? "Copied to clipboard" : "Copy to clipboard",
|
|
144
|
+
"data-copied": (0, import_dom_query2.dataAttr)(copied),
|
|
145
|
+
onClick() {
|
|
146
|
+
send({ type: "COPY" });
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
},
|
|
150
|
+
getIndicatorProps(props2) {
|
|
151
|
+
return normalize.element({
|
|
152
|
+
...parts.indicator.attrs,
|
|
153
|
+
hidden: props2.copied !== copied
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// src/clipboard.machine.ts
|
|
160
|
+
var import_core = require("@zag-js/core");
|
|
161
|
+
var import_utils = require("@zag-js/utils");
|
|
162
|
+
function machine(userContext) {
|
|
163
|
+
const ctx = (0, import_utils.compact)(userContext);
|
|
164
|
+
return (0, import_core.createMachine)(
|
|
165
|
+
{
|
|
166
|
+
id: "clipboard",
|
|
167
|
+
initial: "idle",
|
|
168
|
+
context: {
|
|
169
|
+
value: "",
|
|
170
|
+
timeout: 3e3,
|
|
171
|
+
...ctx
|
|
172
|
+
},
|
|
173
|
+
watch: {
|
|
174
|
+
value: ["syncInputElement"]
|
|
175
|
+
},
|
|
176
|
+
on: {
|
|
177
|
+
"VALUE.SET": {
|
|
178
|
+
actions: ["setValue"]
|
|
179
|
+
},
|
|
180
|
+
COPY: {
|
|
181
|
+
target: "copied",
|
|
182
|
+
actions: ["copyToClipboard", "invokeOnCopy"]
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
states: {
|
|
186
|
+
idle: {
|
|
187
|
+
on: {
|
|
188
|
+
"INPUT.COPY": {
|
|
189
|
+
target: "copied",
|
|
190
|
+
actions: ["invokeOnCopy"]
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
copied: {
|
|
195
|
+
after: {
|
|
196
|
+
COPY_TIMEOUT: "idle"
|
|
197
|
+
},
|
|
198
|
+
on: {
|
|
199
|
+
COPY: {
|
|
200
|
+
target: "copied",
|
|
201
|
+
actions: ["copyToClipboard", "invokeOnCopy"]
|
|
202
|
+
},
|
|
203
|
+
"INPUT.COPY": {
|
|
204
|
+
actions: ["invokeOnCopy"]
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
actions: {
|
|
212
|
+
setValue(ctx2, evt) {
|
|
213
|
+
ctx2.value = evt.value;
|
|
214
|
+
},
|
|
215
|
+
copyToClipboard(ctx2) {
|
|
216
|
+
dom.writeToClipboard(ctx2);
|
|
217
|
+
},
|
|
218
|
+
invokeOnCopy(ctx2) {
|
|
219
|
+
ctx2.onStatusChange?.({ copied: true });
|
|
220
|
+
},
|
|
221
|
+
syncInputElement(ctx2) {
|
|
222
|
+
dom.setValue(dom.getInputEl(ctx2), ctx2.value);
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
delays: {
|
|
226
|
+
COPY_TIMEOUT: (ctx2) => ctx2.timeout
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// src/clipboard.props.ts
|
|
233
|
+
var import_types = require("@zag-js/types");
|
|
234
|
+
var import_utils2 = require("@zag-js/utils");
|
|
235
|
+
var props = (0, import_types.createProps)()([
|
|
236
|
+
"getRootNode",
|
|
237
|
+
"id",
|
|
238
|
+
"ids",
|
|
239
|
+
"value",
|
|
240
|
+
"timeout",
|
|
241
|
+
"onStatusChange"
|
|
242
|
+
]);
|
|
243
|
+
var contextProps = (0, import_utils2.createSplitProps)(props);
|
|
244
|
+
var indicatorProps = (0, import_types.createProps)()(["copied"]);
|
|
245
|
+
var splitIndicatorProps = (0, import_utils2.createSplitProps)(indicatorProps);
|
|
246
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
247
|
+
0 && (module.exports = {
|
|
248
|
+
anatomy,
|
|
249
|
+
connect,
|
|
250
|
+
contextProps,
|
|
251
|
+
indicatorProps,
|
|
252
|
+
machine,
|
|
253
|
+
props,
|
|
254
|
+
splitIndicatorProps
|
|
255
|
+
});
|
|
2
256
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/clipboard.anatomy.ts","../src/clipboard.connect.ts","../src/clipboard.dom.ts","../src/clipboard.machine.ts","../src/clipboard.props.ts"],"sourcesContent":["export { anatomy } from \"./clipboard.anatomy\"\nexport { connect } from \"./clipboard.connect\"\nexport { machine } from \"./clipboard.machine\"\nexport * from \"./clipboard.props\"\nexport type {\n MachineApi as Api,\n UserDefinedContext as Context,\n CopyStatusDetails,\n ElementIds,\n IndicatorProps,\n} from \"./clipboard.types\"\n","import { createAnatomy } from \"@zag-js/anatomy\"\n\nexport const anatomy = createAnatomy(\"clipboard\").parts(\"root\", \"control\", \"trigger\", \"indicator\", \"input\", \"label\")\n\nexport const parts = anatomy.build()\n","import { dataAttr } from \"@zag-js/dom-query\"\nimport type { NormalizeProps, PropTypes } from \"@zag-js/types\"\nimport { parts } from \"./clipboard.anatomy\"\nimport type { MachineApi, Send, State } from \"./clipboard.types\"\nimport { dom } from \"./clipboard.dom\"\n\nexport function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T> {\n const copied = state.matches(\"copied\")\n\n return {\n copied,\n value: state.context.value,\n setValue(value) {\n send({ type: \"VALUE.SET\", value })\n },\n copy() {\n send({ type: \"COPY\" })\n },\n rootProps: normalize.element({\n ...parts.root.attrs,\n \"data-copied\": dataAttr(copied),\n id: dom.getRootId(state.context),\n }),\n labelProps: normalize.label({\n ...parts.label.attrs,\n htmlFor: dom.getInputId(state.context),\n \"data-copied\": dataAttr(copied),\n id: dom.getLabelId(state.context),\n }),\n controlProps: normalize.element({\n ...parts.control.attrs,\n \"data-copied\": dataAttr(copied),\n }),\n inputProps: normalize.input({\n ...parts.input.attrs,\n defaultValue: state.context.value,\n \"data-copied\": dataAttr(copied),\n readOnly: true,\n \"data-readonly\": \"true\",\n id: dom.getInputId(state.context),\n onFocus(event) {\n event.currentTarget.select()\n },\n onCopy() {\n send({ type: \"INPUT.COPY\" })\n },\n }),\n triggerProps: normalize.button({\n ...parts.trigger.attrs,\n \"aria-label\": copied ? \"Copied to clipboard\" : \"Copy to clipboard\",\n \"data-copied\": dataAttr(copied),\n onClick() {\n send({ type: \"COPY\" })\n },\n }),\n getIndicatorProps(props) {\n return normalize.element({\n ...parts.indicator.attrs,\n hidden: props.copied !== copied,\n })\n },\n }\n}\n","import { createScope, getWindow } from \"@zag-js/dom-query\"\nimport type { MachineContext as Ctx } from \"./clipboard.types\"\n\nexport const dom = createScope({\n getRootId: (ctx: Ctx) => ctx.ids?.root ?? `clip-${ctx.id}`,\n getInputId: (ctx: Ctx) => ctx.ids?.input ?? `clip-input-${ctx.id}`,\n getLabelId: (ctx: Ctx) => ctx.ids?.label ?? `clip-label-${ctx.id}`,\n getInputEl: (ctx: Ctx) => dom.getById<HTMLInputElement>(ctx, dom.getInputId(ctx)),\n writeToClipboard: (ctx: Ctx) => copyText(dom.getDoc(ctx), ctx.value),\n})\n\nfunction createNode(doc: Document, text: string): HTMLElement {\n const node = doc.createElement(\"pre\")\n Object.assign(node.style, {\n width: \"1px\",\n height: \"1px\",\n position: \"fixed\",\n top: \"5px\",\n })\n node.textContent = text\n return node\n}\n\nfunction copyNode(node: HTMLElement): Promise<void> {\n const win = getWindow(node)\n\n const selection = win.getSelection()\n\n if (selection == null) {\n return Promise.reject(new Error())\n }\n\n selection.removeAllRanges()\n\n const doc = node.ownerDocument\n\n const range = doc.createRange()\n range.selectNodeContents(node)\n selection.addRange(range)\n\n doc.execCommand(\"copy\")\n selection.removeAllRanges()\n\n return Promise.resolve()\n}\n\nfunction copyText(doc: Document, text: string): Promise<void> {\n const win = doc.defaultView || window\n\n if (win.navigator.clipboard?.writeText !== undefined) {\n return win.navigator.clipboard.writeText(text)\n }\n\n if (!doc.body) {\n return Promise.reject(new Error())\n }\n\n const node = createNode(doc, text)\n\n doc.body.appendChild(node)\n copyNode(node)\n doc.body.removeChild(node)\n\n return Promise.resolve()\n}\n","import { createMachine } from \"@zag-js/core\"\nimport { compact } from \"@zag-js/utils\"\nimport { dom } from \"./clipboard.dom\"\nimport type { MachineContext, MachineState, UserDefinedContext } from \"./clipboard.types\"\n\nexport function machine(userContext: UserDefinedContext) {\n const ctx = compact(userContext)\n return createMachine<MachineContext, MachineState>(\n {\n id: \"clipboard\",\n initial: \"idle\",\n context: {\n value: \"\",\n timeout: 3000,\n ...ctx,\n },\n watch: {\n value: [\"syncInputElement\"],\n },\n on: {\n \"VALUE.SET\": {\n actions: [\"setValue\"],\n },\n COPY: {\n target: \"copied\",\n actions: [\"copyToClipboard\", \"invokeOnCopy\"],\n },\n },\n states: {\n idle: {\n on: {\n \"INPUT.COPY\": {\n target: \"copied\",\n actions: [\"invokeOnCopy\"],\n },\n },\n },\n copied: {\n after: {\n COPY_TIMEOUT: \"idle\",\n },\n on: {\n COPY: {\n target: \"copied\",\n actions: [\"copyToClipboard\", \"invokeOnCopy\"],\n },\n \"INPUT.COPY\": {\n actions: [\"invokeOnCopy\"],\n },\n },\n },\n },\n },\n {\n actions: {\n setValue(ctx, evt) {\n ctx.value = evt.value\n },\n copyToClipboard(ctx) {\n dom.writeToClipboard(ctx)\n },\n invokeOnCopy(ctx) {\n ctx.onStatusChange?.({ copied: true })\n },\n syncInputElement(ctx) {\n dom.setValue(dom.getInputEl(ctx), ctx.value)\n },\n },\n delays: {\n COPY_TIMEOUT: (ctx) => ctx.timeout,\n },\n },\n )\n}\n","import { createProps } from \"@zag-js/types\"\nimport type { IndicatorProps, UserDefinedContext } from \"./clipboard.types\"\nimport { createSplitProps } from \"@zag-js/utils\"\n\nexport const props = createProps<UserDefinedContext>()([\n \"getRootNode\",\n \"id\",\n \"ids\",\n \"value\",\n \"timeout\",\n \"onStatusChange\",\n])\nexport const contextProps = createSplitProps<UserDefinedContext>(props)\n\nexport const indicatorProps = createProps<IndicatorProps>()([\"copied\"])\nexport const splitIndicatorProps = createSplitProps<IndicatorProps>(indicatorProps)\n"],"mappings":"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","names":["import_dom_query","props","ctx","import_utils"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/clipboard.anatomy.ts","../src/clipboard.connect.ts","../src/clipboard.dom.ts","../src/clipboard.machine.ts","../src/clipboard.props.ts"],"sourcesContent":["export { anatomy } from \"./clipboard.anatomy\"\nexport { connect } from \"./clipboard.connect\"\nexport { machine } from \"./clipboard.machine\"\nexport * from \"./clipboard.props\"\nexport type {\n MachineApi as Api,\n UserDefinedContext as Context,\n CopyStatusDetails,\n ElementIds,\n IndicatorProps,\n} from \"./clipboard.types\"\n","import { createAnatomy } from \"@zag-js/anatomy\"\n\nexport const anatomy = createAnatomy(\"clipboard\").parts(\"root\", \"control\", \"trigger\", \"indicator\", \"input\", \"label\")\n\nexport const parts = anatomy.build()\n","import { dataAttr } from \"@zag-js/dom-query\"\nimport type { NormalizeProps, PropTypes } from \"@zag-js/types\"\nimport { parts } from \"./clipboard.anatomy\"\nimport type { MachineApi, Send, State } from \"./clipboard.types\"\nimport { dom } from \"./clipboard.dom\"\n\nexport function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T> {\n const copied = state.matches(\"copied\")\n\n return {\n copied,\n value: state.context.value,\n setValue(value) {\n send({ type: \"VALUE.SET\", value })\n },\n copy() {\n send({ type: \"COPY\" })\n },\n\n getRootProps() {\n return normalize.element({\n ...parts.root.attrs,\n \"data-copied\": dataAttr(copied),\n id: dom.getRootId(state.context),\n })\n },\n\n getLabelProps() {\n return normalize.label({\n ...parts.label.attrs,\n htmlFor: dom.getInputId(state.context),\n \"data-copied\": dataAttr(copied),\n id: dom.getLabelId(state.context),\n })\n },\n\n getControlProps() {\n return normalize.element({\n ...parts.control.attrs,\n \"data-copied\": dataAttr(copied),\n })\n },\n\n getInputProps() {\n return normalize.input({\n ...parts.input.attrs,\n defaultValue: state.context.value,\n \"data-copied\": dataAttr(copied),\n readOnly: true,\n \"data-readonly\": \"true\",\n id: dom.getInputId(state.context),\n onFocus(event) {\n event.currentTarget.select()\n },\n onCopy() {\n send({ type: \"INPUT.COPY\" })\n },\n })\n },\n\n getTriggerProps() {\n return normalize.button({\n ...parts.trigger.attrs,\n \"aria-label\": copied ? \"Copied to clipboard\" : \"Copy to clipboard\",\n \"data-copied\": dataAttr(copied),\n onClick() {\n send({ type: \"COPY\" })\n },\n })\n },\n\n getIndicatorProps(props) {\n return normalize.element({\n ...parts.indicator.attrs,\n hidden: props.copied !== copied,\n })\n },\n }\n}\n","import { createScope, getWindow } from \"@zag-js/dom-query\"\nimport type { MachineContext as Ctx } from \"./clipboard.types\"\n\nexport const dom = createScope({\n getRootId: (ctx: Ctx) => ctx.ids?.root ?? `clip-${ctx.id}`,\n getInputId: (ctx: Ctx) => ctx.ids?.input ?? `clip-input-${ctx.id}`,\n getLabelId: (ctx: Ctx) => ctx.ids?.label ?? `clip-label-${ctx.id}`,\n getInputEl: (ctx: Ctx) => dom.getById<HTMLInputElement>(ctx, dom.getInputId(ctx)),\n writeToClipboard: (ctx: Ctx) => copyText(dom.getDoc(ctx), ctx.value),\n})\n\nfunction createNode(doc: Document, text: string): HTMLElement {\n const node = doc.createElement(\"pre\")\n Object.assign(node.style, {\n width: \"1px\",\n height: \"1px\",\n position: \"fixed\",\n top: \"5px\",\n })\n node.textContent = text\n return node\n}\n\nfunction copyNode(node: HTMLElement): Promise<void> {\n const win = getWindow(node)\n\n const selection = win.getSelection()\n\n if (selection == null) {\n return Promise.reject(new Error())\n }\n\n selection.removeAllRanges()\n\n const doc = node.ownerDocument\n\n const range = doc.createRange()\n range.selectNodeContents(node)\n selection.addRange(range)\n\n doc.execCommand(\"copy\")\n selection.removeAllRanges()\n\n return Promise.resolve()\n}\n\nfunction copyText(doc: Document, text: string): Promise<void> {\n const win = doc.defaultView || window\n\n if (win.navigator.clipboard?.writeText !== undefined) {\n return win.navigator.clipboard.writeText(text)\n }\n\n if (!doc.body) {\n return Promise.reject(new Error())\n }\n\n const node = createNode(doc, text)\n\n doc.body.appendChild(node)\n copyNode(node)\n doc.body.removeChild(node)\n\n return Promise.resolve()\n}\n","import { createMachine } from \"@zag-js/core\"\nimport { compact } from \"@zag-js/utils\"\nimport { dom } from \"./clipboard.dom\"\nimport type { MachineContext, MachineState, UserDefinedContext } from \"./clipboard.types\"\n\nexport function machine(userContext: UserDefinedContext) {\n const ctx = compact(userContext)\n return createMachine<MachineContext, MachineState>(\n {\n id: \"clipboard\",\n initial: \"idle\",\n context: {\n value: \"\",\n timeout: 3000,\n ...ctx,\n },\n watch: {\n value: [\"syncInputElement\"],\n },\n on: {\n \"VALUE.SET\": {\n actions: [\"setValue\"],\n },\n COPY: {\n target: \"copied\",\n actions: [\"copyToClipboard\", \"invokeOnCopy\"],\n },\n },\n states: {\n idle: {\n on: {\n \"INPUT.COPY\": {\n target: \"copied\",\n actions: [\"invokeOnCopy\"],\n },\n },\n },\n copied: {\n after: {\n COPY_TIMEOUT: \"idle\",\n },\n on: {\n COPY: {\n target: \"copied\",\n actions: [\"copyToClipboard\", \"invokeOnCopy\"],\n },\n \"INPUT.COPY\": {\n actions: [\"invokeOnCopy\"],\n },\n },\n },\n },\n },\n {\n actions: {\n setValue(ctx, evt) {\n ctx.value = evt.value\n },\n copyToClipboard(ctx) {\n dom.writeToClipboard(ctx)\n },\n invokeOnCopy(ctx) {\n ctx.onStatusChange?.({ copied: true })\n },\n syncInputElement(ctx) {\n dom.setValue(dom.getInputEl(ctx), ctx.value)\n },\n },\n delays: {\n COPY_TIMEOUT: (ctx) => ctx.timeout,\n },\n },\n )\n}\n","import { createProps } from \"@zag-js/types\"\nimport type { IndicatorProps, UserDefinedContext } from \"./clipboard.types\"\nimport { createSplitProps } from \"@zag-js/utils\"\n\nexport const props = createProps<UserDefinedContext>()([\n \"getRootNode\",\n \"id\",\n \"ids\",\n \"value\",\n \"timeout\",\n \"onStatusChange\",\n])\nexport const contextProps = createSplitProps<UserDefinedContext>(props)\n\nexport const indicatorProps = createProps<IndicatorProps>()([\"copied\"])\nexport const splitIndicatorProps = createSplitProps<IndicatorProps>(indicatorProps)\n"],"mappings":"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","names":["import_dom_query","props","ctx","import_utils"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,223 @@
|
|
|
1
|
-
|
|
1
|
+
// src/clipboard.anatomy.ts
|
|
2
|
+
import { createAnatomy } from "@zag-js/anatomy";
|
|
3
|
+
var anatomy = createAnatomy("clipboard").parts("root", "control", "trigger", "indicator", "input", "label");
|
|
4
|
+
var parts = anatomy.build();
|
|
5
|
+
|
|
6
|
+
// src/clipboard.connect.ts
|
|
7
|
+
import { dataAttr } from "@zag-js/dom-query";
|
|
8
|
+
|
|
9
|
+
// src/clipboard.dom.ts
|
|
10
|
+
import { createScope, getWindow } from "@zag-js/dom-query";
|
|
11
|
+
var dom = createScope({
|
|
12
|
+
getRootId: (ctx) => ctx.ids?.root ?? `clip-${ctx.id}`,
|
|
13
|
+
getInputId: (ctx) => ctx.ids?.input ?? `clip-input-${ctx.id}`,
|
|
14
|
+
getLabelId: (ctx) => ctx.ids?.label ?? `clip-label-${ctx.id}`,
|
|
15
|
+
getInputEl: (ctx) => dom.getById(ctx, dom.getInputId(ctx)),
|
|
16
|
+
writeToClipboard: (ctx) => copyText(dom.getDoc(ctx), ctx.value)
|
|
17
|
+
});
|
|
18
|
+
function createNode(doc, text) {
|
|
19
|
+
const node = doc.createElement("pre");
|
|
20
|
+
Object.assign(node.style, {
|
|
21
|
+
width: "1px",
|
|
22
|
+
height: "1px",
|
|
23
|
+
position: "fixed",
|
|
24
|
+
top: "5px"
|
|
25
|
+
});
|
|
26
|
+
node.textContent = text;
|
|
27
|
+
return node;
|
|
28
|
+
}
|
|
29
|
+
function copyNode(node) {
|
|
30
|
+
const win = getWindow(node);
|
|
31
|
+
const selection = win.getSelection();
|
|
32
|
+
if (selection == null) {
|
|
33
|
+
return Promise.reject(new Error());
|
|
34
|
+
}
|
|
35
|
+
selection.removeAllRanges();
|
|
36
|
+
const doc = node.ownerDocument;
|
|
37
|
+
const range = doc.createRange();
|
|
38
|
+
range.selectNodeContents(node);
|
|
39
|
+
selection.addRange(range);
|
|
40
|
+
doc.execCommand("copy");
|
|
41
|
+
selection.removeAllRanges();
|
|
42
|
+
return Promise.resolve();
|
|
43
|
+
}
|
|
44
|
+
function copyText(doc, text) {
|
|
45
|
+
const win = doc.defaultView || window;
|
|
46
|
+
if (win.navigator.clipboard?.writeText !== void 0) {
|
|
47
|
+
return win.navigator.clipboard.writeText(text);
|
|
48
|
+
}
|
|
49
|
+
if (!doc.body) {
|
|
50
|
+
return Promise.reject(new Error());
|
|
51
|
+
}
|
|
52
|
+
const node = createNode(doc, text);
|
|
53
|
+
doc.body.appendChild(node);
|
|
54
|
+
copyNode(node);
|
|
55
|
+
doc.body.removeChild(node);
|
|
56
|
+
return Promise.resolve();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/clipboard.connect.ts
|
|
60
|
+
function connect(state, send, normalize) {
|
|
61
|
+
const copied = state.matches("copied");
|
|
62
|
+
return {
|
|
63
|
+
copied,
|
|
64
|
+
value: state.context.value,
|
|
65
|
+
setValue(value) {
|
|
66
|
+
send({ type: "VALUE.SET", value });
|
|
67
|
+
},
|
|
68
|
+
copy() {
|
|
69
|
+
send({ type: "COPY" });
|
|
70
|
+
},
|
|
71
|
+
getRootProps() {
|
|
72
|
+
return normalize.element({
|
|
73
|
+
...parts.root.attrs,
|
|
74
|
+
"data-copied": dataAttr(copied),
|
|
75
|
+
id: dom.getRootId(state.context)
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
getLabelProps() {
|
|
79
|
+
return normalize.label({
|
|
80
|
+
...parts.label.attrs,
|
|
81
|
+
htmlFor: dom.getInputId(state.context),
|
|
82
|
+
"data-copied": dataAttr(copied),
|
|
83
|
+
id: dom.getLabelId(state.context)
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
getControlProps() {
|
|
87
|
+
return normalize.element({
|
|
88
|
+
...parts.control.attrs,
|
|
89
|
+
"data-copied": dataAttr(copied)
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
getInputProps() {
|
|
93
|
+
return normalize.input({
|
|
94
|
+
...parts.input.attrs,
|
|
95
|
+
defaultValue: state.context.value,
|
|
96
|
+
"data-copied": dataAttr(copied),
|
|
97
|
+
readOnly: true,
|
|
98
|
+
"data-readonly": "true",
|
|
99
|
+
id: dom.getInputId(state.context),
|
|
100
|
+
onFocus(event) {
|
|
101
|
+
event.currentTarget.select();
|
|
102
|
+
},
|
|
103
|
+
onCopy() {
|
|
104
|
+
send({ type: "INPUT.COPY" });
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
getTriggerProps() {
|
|
109
|
+
return normalize.button({
|
|
110
|
+
...parts.trigger.attrs,
|
|
111
|
+
"aria-label": copied ? "Copied to clipboard" : "Copy to clipboard",
|
|
112
|
+
"data-copied": dataAttr(copied),
|
|
113
|
+
onClick() {
|
|
114
|
+
send({ type: "COPY" });
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
getIndicatorProps(props2) {
|
|
119
|
+
return normalize.element({
|
|
120
|
+
...parts.indicator.attrs,
|
|
121
|
+
hidden: props2.copied !== copied
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/clipboard.machine.ts
|
|
128
|
+
import { createMachine } from "@zag-js/core";
|
|
129
|
+
import { compact } from "@zag-js/utils";
|
|
130
|
+
function machine(userContext) {
|
|
131
|
+
const ctx = compact(userContext);
|
|
132
|
+
return createMachine(
|
|
133
|
+
{
|
|
134
|
+
id: "clipboard",
|
|
135
|
+
initial: "idle",
|
|
136
|
+
context: {
|
|
137
|
+
value: "",
|
|
138
|
+
timeout: 3e3,
|
|
139
|
+
...ctx
|
|
140
|
+
},
|
|
141
|
+
watch: {
|
|
142
|
+
value: ["syncInputElement"]
|
|
143
|
+
},
|
|
144
|
+
on: {
|
|
145
|
+
"VALUE.SET": {
|
|
146
|
+
actions: ["setValue"]
|
|
147
|
+
},
|
|
148
|
+
COPY: {
|
|
149
|
+
target: "copied",
|
|
150
|
+
actions: ["copyToClipboard", "invokeOnCopy"]
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
states: {
|
|
154
|
+
idle: {
|
|
155
|
+
on: {
|
|
156
|
+
"INPUT.COPY": {
|
|
157
|
+
target: "copied",
|
|
158
|
+
actions: ["invokeOnCopy"]
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
copied: {
|
|
163
|
+
after: {
|
|
164
|
+
COPY_TIMEOUT: "idle"
|
|
165
|
+
},
|
|
166
|
+
on: {
|
|
167
|
+
COPY: {
|
|
168
|
+
target: "copied",
|
|
169
|
+
actions: ["copyToClipboard", "invokeOnCopy"]
|
|
170
|
+
},
|
|
171
|
+
"INPUT.COPY": {
|
|
172
|
+
actions: ["invokeOnCopy"]
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
actions: {
|
|
180
|
+
setValue(ctx2, evt) {
|
|
181
|
+
ctx2.value = evt.value;
|
|
182
|
+
},
|
|
183
|
+
copyToClipboard(ctx2) {
|
|
184
|
+
dom.writeToClipboard(ctx2);
|
|
185
|
+
},
|
|
186
|
+
invokeOnCopy(ctx2) {
|
|
187
|
+
ctx2.onStatusChange?.({ copied: true });
|
|
188
|
+
},
|
|
189
|
+
syncInputElement(ctx2) {
|
|
190
|
+
dom.setValue(dom.getInputEl(ctx2), ctx2.value);
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
delays: {
|
|
194
|
+
COPY_TIMEOUT: (ctx2) => ctx2.timeout
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// src/clipboard.props.ts
|
|
201
|
+
import { createProps } from "@zag-js/types";
|
|
202
|
+
import { createSplitProps } from "@zag-js/utils";
|
|
203
|
+
var props = createProps()([
|
|
204
|
+
"getRootNode",
|
|
205
|
+
"id",
|
|
206
|
+
"ids",
|
|
207
|
+
"value",
|
|
208
|
+
"timeout",
|
|
209
|
+
"onStatusChange"
|
|
210
|
+
]);
|
|
211
|
+
var contextProps = createSplitProps(props);
|
|
212
|
+
var indicatorProps = createProps()(["copied"]);
|
|
213
|
+
var splitIndicatorProps = createSplitProps(indicatorProps);
|
|
214
|
+
export {
|
|
215
|
+
anatomy,
|
|
216
|
+
connect,
|
|
217
|
+
contextProps,
|
|
218
|
+
indicatorProps,
|
|
219
|
+
machine,
|
|
220
|
+
props,
|
|
221
|
+
splitIndicatorProps
|
|
222
|
+
};
|
|
2
223
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/clipboard.anatomy.ts","../src/clipboard.connect.ts","../src/clipboard.dom.ts","../src/clipboard.machine.ts","../src/clipboard.props.ts"],"sourcesContent":["import { createAnatomy } from \"@zag-js/anatomy\"\n\nexport const anatomy = createAnatomy(\"clipboard\").parts(\"root\", \"control\", \"trigger\", \"indicator\", \"input\", \"label\")\n\nexport const parts = anatomy.build()\n","import { dataAttr } from \"@zag-js/dom-query\"\nimport type { NormalizeProps, PropTypes } from \"@zag-js/types\"\nimport { parts } from \"./clipboard.anatomy\"\nimport type { MachineApi, Send, State } from \"./clipboard.types\"\nimport { dom } from \"./clipboard.dom\"\n\nexport function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T> {\n const copied = state.matches(\"copied\")\n\n return {\n copied,\n value: state.context.value,\n setValue(value) {\n send({ type: \"VALUE.SET\", value })\n },\n copy() {\n send({ type: \"COPY\" })\n },\n rootProps: normalize.element({\n ...parts.root.attrs,\n \"data-copied\": dataAttr(copied),\n id: dom.getRootId(state.context),\n }),\n labelProps: normalize.label({\n ...parts.label.attrs,\n htmlFor: dom.getInputId(state.context),\n \"data-copied\": dataAttr(copied),\n id: dom.getLabelId(state.context),\n }),\n controlProps: normalize.element({\n ...parts.control.attrs,\n \"data-copied\": dataAttr(copied),\n }),\n inputProps: normalize.input({\n ...parts.input.attrs,\n defaultValue: state.context.value,\n \"data-copied\": dataAttr(copied),\n readOnly: true,\n \"data-readonly\": \"true\",\n id: dom.getInputId(state.context),\n onFocus(event) {\n event.currentTarget.select()\n },\n onCopy() {\n send({ type: \"INPUT.COPY\" })\n },\n }),\n triggerProps: normalize.button({\n ...parts.trigger.attrs,\n \"aria-label\": copied ? \"Copied to clipboard\" : \"Copy to clipboard\",\n \"data-copied\": dataAttr(copied),\n onClick() {\n send({ type: \"COPY\" })\n },\n }),\n getIndicatorProps(props) {\n return normalize.element({\n ...parts.indicator.attrs,\n hidden: props.copied !== copied,\n })\n },\n }\n}\n","import { createScope, getWindow } from \"@zag-js/dom-query\"\nimport type { MachineContext as Ctx } from \"./clipboard.types\"\n\nexport const dom = createScope({\n getRootId: (ctx: Ctx) => ctx.ids?.root ?? `clip-${ctx.id}`,\n getInputId: (ctx: Ctx) => ctx.ids?.input ?? `clip-input-${ctx.id}`,\n getLabelId: (ctx: Ctx) => ctx.ids?.label ?? `clip-label-${ctx.id}`,\n getInputEl: (ctx: Ctx) => dom.getById<HTMLInputElement>(ctx, dom.getInputId(ctx)),\n writeToClipboard: (ctx: Ctx) => copyText(dom.getDoc(ctx), ctx.value),\n})\n\nfunction createNode(doc: Document, text: string): HTMLElement {\n const node = doc.createElement(\"pre\")\n Object.assign(node.style, {\n width: \"1px\",\n height: \"1px\",\n position: \"fixed\",\n top: \"5px\",\n })\n node.textContent = text\n return node\n}\n\nfunction copyNode(node: HTMLElement): Promise<void> {\n const win = getWindow(node)\n\n const selection = win.getSelection()\n\n if (selection == null) {\n return Promise.reject(new Error())\n }\n\n selection.removeAllRanges()\n\n const doc = node.ownerDocument\n\n const range = doc.createRange()\n range.selectNodeContents(node)\n selection.addRange(range)\n\n doc.execCommand(\"copy\")\n selection.removeAllRanges()\n\n return Promise.resolve()\n}\n\nfunction copyText(doc: Document, text: string): Promise<void> {\n const win = doc.defaultView || window\n\n if (win.navigator.clipboard?.writeText !== undefined) {\n return win.navigator.clipboard.writeText(text)\n }\n\n if (!doc.body) {\n return Promise.reject(new Error())\n }\n\n const node = createNode(doc, text)\n\n doc.body.appendChild(node)\n copyNode(node)\n doc.body.removeChild(node)\n\n return Promise.resolve()\n}\n","import { createMachine } from \"@zag-js/core\"\nimport { compact } from \"@zag-js/utils\"\nimport { dom } from \"./clipboard.dom\"\nimport type { MachineContext, MachineState, UserDefinedContext } from \"./clipboard.types\"\n\nexport function machine(userContext: UserDefinedContext) {\n const ctx = compact(userContext)\n return createMachine<MachineContext, MachineState>(\n {\n id: \"clipboard\",\n initial: \"idle\",\n context: {\n value: \"\",\n timeout: 3000,\n ...ctx,\n },\n watch: {\n value: [\"syncInputElement\"],\n },\n on: {\n \"VALUE.SET\": {\n actions: [\"setValue\"],\n },\n COPY: {\n target: \"copied\",\n actions: [\"copyToClipboard\", \"invokeOnCopy\"],\n },\n },\n states: {\n idle: {\n on: {\n \"INPUT.COPY\": {\n target: \"copied\",\n actions: [\"invokeOnCopy\"],\n },\n },\n },\n copied: {\n after: {\n COPY_TIMEOUT: \"idle\",\n },\n on: {\n COPY: {\n target: \"copied\",\n actions: [\"copyToClipboard\", \"invokeOnCopy\"],\n },\n \"INPUT.COPY\": {\n actions: [\"invokeOnCopy\"],\n },\n },\n },\n },\n },\n {\n actions: {\n setValue(ctx, evt) {\n ctx.value = evt.value\n },\n copyToClipboard(ctx) {\n dom.writeToClipboard(ctx)\n },\n invokeOnCopy(ctx) {\n ctx.onStatusChange?.({ copied: true })\n },\n syncInputElement(ctx) {\n dom.setValue(dom.getInputEl(ctx), ctx.value)\n },\n },\n delays: {\n COPY_TIMEOUT: (ctx) => ctx.timeout,\n },\n },\n )\n}\n","import { createProps } from \"@zag-js/types\"\nimport type { IndicatorProps, UserDefinedContext } from \"./clipboard.types\"\nimport { createSplitProps } from \"@zag-js/utils\"\n\nexport const props = createProps<UserDefinedContext>()([\n \"getRootNode\",\n \"id\",\n \"ids\",\n \"value\",\n \"timeout\",\n \"onStatusChange\",\n])\nexport const contextProps = createSplitProps<UserDefinedContext>(props)\n\nexport const indicatorProps = createProps<IndicatorProps>()([\"copied\"])\nexport const splitIndicatorProps = createSplitProps<IndicatorProps>(indicatorProps)\n"],"mappings":"AAAA,OAAS,kBAAqB,kBAEvB,IAAM,QAAU,cAAc,WAAW,EAAE,MAAM,OAAQ,UAAW,UAAW,YAAa,QAAS,OAAO,EAE5G,IAAM,MAAQ,QAAQ,MAAM,ECJnC,OAAS,aAAgB,oBCAzB,OAAS,YAAa,cAAiB,oBAGhC,IAAM,IAAM,YAAY,CAC7B,UAAY,KAAa,IAAI,KAAK,MAAQ,QAAQ,IAAI,EAAE,GACxD,WAAa,KAAa,IAAI,KAAK,OAAS,cAAc,IAAI,EAAE,GAChE,WAAa,KAAa,IAAI,KAAK,OAAS,cAAc,IAAI,EAAE,GAChE,WAAa,KAAa,IAAI,QAA0B,IAAK,IAAI,WAAW,GAAG,CAAC,EAChF,iBAAmB,KAAa,SAAS,IAAI,OAAO,GAAG,EAAG,IAAI,KAAK,CACrE,CAAC,EAED,SAAS,WAAW,IAAe,KAA2B,CAC5D,MAAM,KAAO,IAAI,cAAc,KAAK,EACpC,OAAO,OAAO,KAAK,MAAO,CACxB,MAAO,MACP,OAAQ,MACR,SAAU,QACV,IAAK,KACP,CAAC,EACD,KAAK,YAAc,KACnB,OAAO,IACT,CAEA,SAAS,SAAS,KAAkC,CAClD,MAAM,IAAM,UAAU,IAAI,EAE1B,MAAM,UAAY,IAAI,aAAa,EAEnC,GAAI,WAAa,KAAM,CACrB,OAAO,QAAQ,OAAO,IAAI,KAAO,CACnC,CAEA,UAAU,gBAAgB,EAE1B,MAAM,IAAM,KAAK,cAEjB,MAAM,MAAQ,IAAI,YAAY,EAC9B,MAAM,mBAAmB,IAAI,EAC7B,UAAU,SAAS,KAAK,EAExB,IAAI,YAAY,MAAM,EACtB,UAAU,gBAAgB,EAE1B,OAAO,QAAQ,QAAQ,CACzB,CAEA,SAAS,SAAS,IAAe,KAA6B,CAC5D,MAAM,IAAM,IAAI,aAAe,OAE/B,GAAI,IAAI,UAAU,WAAW,YAAc,OAAW,CACpD,OAAO,IAAI,UAAU,UAAU,UAAU,IAAI,CAC/C,CAEA,GAAI,CAAC,IAAI,KAAM,CACb,OAAO,QAAQ,OAAO,IAAI,KAAO,CACnC,CAEA,MAAM,KAAO,WAAW,IAAK,IAAI,EAEjC,IAAI,KAAK,YAAY,IAAI,EACzB,SAAS,IAAI,EACb,IAAI,KAAK,YAAY,IAAI,EAEzB,OAAO,QAAQ,QAAQ,CACzB,CD1DO,SAAS,QAA6B,MAAc,KAAY,UAA6C,CAClH,MAAM,OAAS,MAAM,QAAQ,QAAQ,EAErC,MAAO,CACL,OACA,MAAO,MAAM,QAAQ,MACrB,SAAS,MAAO,CACd,KAAK,CAAE,KAAM,YAAa,KAAM,CAAC,CACnC,EACA,MAAO,CACL,KAAK,CAAE,KAAM,MAAO,CAAC,CACvB,EACA,UAAW,UAAU,QAAQ,CAC3B,GAAG,MAAM,KAAK,MACd,cAAe,SAAS,MAAM,EAC9B,GAAI,IAAI,UAAU,MAAM,OAAO,CACjC,CAAC,EACD,WAAY,UAAU,MAAM,CAC1B,GAAG,MAAM,MAAM,MACf,QAAS,IAAI,WAAW,MAAM,OAAO,EACrC,cAAe,SAAS,MAAM,EAC9B,GAAI,IAAI,WAAW,MAAM,OAAO,CAClC,CAAC,EACD,aAAc,UAAU,QAAQ,CAC9B,GAAG,MAAM,QAAQ,MACjB,cAAe,SAAS,MAAM,CAChC,CAAC,EACD,WAAY,UAAU,MAAM,CAC1B,GAAG,MAAM,MAAM,MACf,aAAc,MAAM,QAAQ,MAC5B,cAAe,SAAS,MAAM,EAC9B,SAAU,KACV,gBAAiB,OACjB,GAAI,IAAI,WAAW,MAAM,OAAO,EAChC,QAAQ,MAAO,CACb,MAAM,cAAc,OAAO,CAC7B,EACA,QAAS,CACP,KAAK,CAAE,KAAM,YAAa,CAAC,CAC7B,CACF,CAAC,EACD,aAAc,UAAU,OAAO,CAC7B,GAAG,MAAM,QAAQ,MACjB,aAAc,OAAS,sBAAwB,oBAC/C,cAAe,SAAS,MAAM,EAC9B,SAAU,CACR,KAAK,CAAE,KAAM,MAAO,CAAC,CACvB,CACF,CAAC,EACD,kBAAkBA,OAAO,CACvB,OAAO,UAAU,QAAQ,CACvB,GAAG,MAAM,UAAU,MACnB,OAAQA,OAAM,SAAW,MAC3B,CAAC,CACH,CACF,CACF,CE9DA,OAAS,kBAAqB,eAC9B,OAAS,YAAe,gBAIjB,SAAS,QAAQ,YAAiC,CACvD,MAAM,IAAM,QAAQ,WAAW,EAC/B,OAAO,cACL,CACE,GAAI,YACJ,QAAS,OACT,QAAS,CACP,MAAO,GACP,QAAS,IACT,GAAG,GACL,EACA,MAAO,CACL,MAAO,CAAC,kBAAkB,CAC5B,EACA,GAAI,CACF,YAAa,CACX,QAAS,CAAC,UAAU,CACtB,EACA,KAAM,CACJ,OAAQ,SACR,QAAS,CAAC,kBAAmB,cAAc,CAC7C,CACF,EACA,OAAQ,CACN,KAAM,CACJ,GAAI,CACF,aAAc,CACZ,OAAQ,SACR,QAAS,CAAC,cAAc,CAC1B,CACF,CACF,EACA,OAAQ,CACN,MAAO,CACL,aAAc,MAChB,EACA,GAAI,CACF,KAAM,CACJ,OAAQ,SACR,QAAS,CAAC,kBAAmB,cAAc,CAC7C,EACA,aAAc,CACZ,QAAS,CAAC,cAAc,CAC1B,CACF,CACF,CACF,CACF,EACA,CACE,QAAS,CACP,SAASC,KAAK,IAAK,CACjBA,KAAI,MAAQ,IAAI,KAClB,EACA,gBAAgBA,KAAK,CACnB,IAAI,iBAAiBA,IAAG,CAC1B,EACA,aAAaA,KAAK,CAChBA,KAAI,iBAAiB,CAAE,OAAQ,IAAK,CAAC,CACvC,EACA,iBAAiBA,KAAK,CACpB,IAAI,SAAS,IAAI,WAAWA,IAAG,EAAGA,KAAI,KAAK,CAC7C,CACF,EACA,OAAQ,CACN,aAAeA,MAAQA,KAAI,OAC7B,CACF,CACF,CACF,CCzEA,OAAS,gBAAmB,gBAE5B,OAAS,qBAAwB,gBAE1B,IAAM,MAAQ,YAAgC,EAAE,CACrD,cACA,KACA,MACA,QACA,UACA,gBACF,CAAC,EACM,IAAM,aAAe,iBAAqC,KAAK,EAE/D,IAAM,eAAiB,YAA4B,EAAE,CAAC,QAAQ,CAAC,EAC/D,IAAM,oBAAsB,iBAAiC,cAAc","names":["props","ctx"]}
|
|
1
|
+
{"version":3,"sources":["../src/clipboard.anatomy.ts","../src/clipboard.connect.ts","../src/clipboard.dom.ts","../src/clipboard.machine.ts","../src/clipboard.props.ts"],"sourcesContent":["import { createAnatomy } from \"@zag-js/anatomy\"\n\nexport const anatomy = createAnatomy(\"clipboard\").parts(\"root\", \"control\", \"trigger\", \"indicator\", \"input\", \"label\")\n\nexport const parts = anatomy.build()\n","import { dataAttr } from \"@zag-js/dom-query\"\nimport type { NormalizeProps, PropTypes } from \"@zag-js/types\"\nimport { parts } from \"./clipboard.anatomy\"\nimport type { MachineApi, Send, State } from \"./clipboard.types\"\nimport { dom } from \"./clipboard.dom\"\n\nexport function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T> {\n const copied = state.matches(\"copied\")\n\n return {\n copied,\n value: state.context.value,\n setValue(value) {\n send({ type: \"VALUE.SET\", value })\n },\n copy() {\n send({ type: \"COPY\" })\n },\n\n getRootProps() {\n return normalize.element({\n ...parts.root.attrs,\n \"data-copied\": dataAttr(copied),\n id: dom.getRootId(state.context),\n })\n },\n\n getLabelProps() {\n return normalize.label({\n ...parts.label.attrs,\n htmlFor: dom.getInputId(state.context),\n \"data-copied\": dataAttr(copied),\n id: dom.getLabelId(state.context),\n })\n },\n\n getControlProps() {\n return normalize.element({\n ...parts.control.attrs,\n \"data-copied\": dataAttr(copied),\n })\n },\n\n getInputProps() {\n return normalize.input({\n ...parts.input.attrs,\n defaultValue: state.context.value,\n \"data-copied\": dataAttr(copied),\n readOnly: true,\n \"data-readonly\": \"true\",\n id: dom.getInputId(state.context),\n onFocus(event) {\n event.currentTarget.select()\n },\n onCopy() {\n send({ type: \"INPUT.COPY\" })\n },\n })\n },\n\n getTriggerProps() {\n return normalize.button({\n ...parts.trigger.attrs,\n \"aria-label\": copied ? \"Copied to clipboard\" : \"Copy to clipboard\",\n \"data-copied\": dataAttr(copied),\n onClick() {\n send({ type: \"COPY\" })\n },\n })\n },\n\n getIndicatorProps(props) {\n return normalize.element({\n ...parts.indicator.attrs,\n hidden: props.copied !== copied,\n })\n },\n }\n}\n","import { createScope, getWindow } from \"@zag-js/dom-query\"\nimport type { MachineContext as Ctx } from \"./clipboard.types\"\n\nexport const dom = createScope({\n getRootId: (ctx: Ctx) => ctx.ids?.root ?? `clip-${ctx.id}`,\n getInputId: (ctx: Ctx) => ctx.ids?.input ?? `clip-input-${ctx.id}`,\n getLabelId: (ctx: Ctx) => ctx.ids?.label ?? `clip-label-${ctx.id}`,\n getInputEl: (ctx: Ctx) => dom.getById<HTMLInputElement>(ctx, dom.getInputId(ctx)),\n writeToClipboard: (ctx: Ctx) => copyText(dom.getDoc(ctx), ctx.value),\n})\n\nfunction createNode(doc: Document, text: string): HTMLElement {\n const node = doc.createElement(\"pre\")\n Object.assign(node.style, {\n width: \"1px\",\n height: \"1px\",\n position: \"fixed\",\n top: \"5px\",\n })\n node.textContent = text\n return node\n}\n\nfunction copyNode(node: HTMLElement): Promise<void> {\n const win = getWindow(node)\n\n const selection = win.getSelection()\n\n if (selection == null) {\n return Promise.reject(new Error())\n }\n\n selection.removeAllRanges()\n\n const doc = node.ownerDocument\n\n const range = doc.createRange()\n range.selectNodeContents(node)\n selection.addRange(range)\n\n doc.execCommand(\"copy\")\n selection.removeAllRanges()\n\n return Promise.resolve()\n}\n\nfunction copyText(doc: Document, text: string): Promise<void> {\n const win = doc.defaultView || window\n\n if (win.navigator.clipboard?.writeText !== undefined) {\n return win.navigator.clipboard.writeText(text)\n }\n\n if (!doc.body) {\n return Promise.reject(new Error())\n }\n\n const node = createNode(doc, text)\n\n doc.body.appendChild(node)\n copyNode(node)\n doc.body.removeChild(node)\n\n return Promise.resolve()\n}\n","import { createMachine } from \"@zag-js/core\"\nimport { compact } from \"@zag-js/utils\"\nimport { dom } from \"./clipboard.dom\"\nimport type { MachineContext, MachineState, UserDefinedContext } from \"./clipboard.types\"\n\nexport function machine(userContext: UserDefinedContext) {\n const ctx = compact(userContext)\n return createMachine<MachineContext, MachineState>(\n {\n id: \"clipboard\",\n initial: \"idle\",\n context: {\n value: \"\",\n timeout: 3000,\n ...ctx,\n },\n watch: {\n value: [\"syncInputElement\"],\n },\n on: {\n \"VALUE.SET\": {\n actions: [\"setValue\"],\n },\n COPY: {\n target: \"copied\",\n actions: [\"copyToClipboard\", \"invokeOnCopy\"],\n },\n },\n states: {\n idle: {\n on: {\n \"INPUT.COPY\": {\n target: \"copied\",\n actions: [\"invokeOnCopy\"],\n },\n },\n },\n copied: {\n after: {\n COPY_TIMEOUT: \"idle\",\n },\n on: {\n COPY: {\n target: \"copied\",\n actions: [\"copyToClipboard\", \"invokeOnCopy\"],\n },\n \"INPUT.COPY\": {\n actions: [\"invokeOnCopy\"],\n },\n },\n },\n },\n },\n {\n actions: {\n setValue(ctx, evt) {\n ctx.value = evt.value\n },\n copyToClipboard(ctx) {\n dom.writeToClipboard(ctx)\n },\n invokeOnCopy(ctx) {\n ctx.onStatusChange?.({ copied: true })\n },\n syncInputElement(ctx) {\n dom.setValue(dom.getInputEl(ctx), ctx.value)\n },\n },\n delays: {\n COPY_TIMEOUT: (ctx) => ctx.timeout,\n },\n },\n )\n}\n","import { createProps } from \"@zag-js/types\"\nimport type { IndicatorProps, UserDefinedContext } from \"./clipboard.types\"\nimport { createSplitProps } from \"@zag-js/utils\"\n\nexport const props = createProps<UserDefinedContext>()([\n \"getRootNode\",\n \"id\",\n \"ids\",\n \"value\",\n \"timeout\",\n \"onStatusChange\",\n])\nexport const contextProps = createSplitProps<UserDefinedContext>(props)\n\nexport const indicatorProps = createProps<IndicatorProps>()([\"copied\"])\nexport const splitIndicatorProps = createSplitProps<IndicatorProps>(indicatorProps)\n"],"mappings":"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","names":["props","ctx"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/clipboard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.55.0",
|
|
4
4
|
"description": "Core logic for the clipboard widget implemented as a state machine",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"js",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"url": "https://github.com/chakra-ui/zag/issues"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@zag-js/anatomy": "0.
|
|
32
|
-
"@zag-js/core": "0.
|
|
33
|
-
"@zag-js/dom-query": "0.
|
|
34
|
-
"@zag-js/utils": "0.
|
|
35
|
-
"@zag-js/types": "0.
|
|
31
|
+
"@zag-js/anatomy": "0.55.0",
|
|
32
|
+
"@zag-js/core": "0.55.0",
|
|
33
|
+
"@zag-js/dom-query": "0.55.0",
|
|
34
|
+
"@zag-js/utils": "0.55.0",
|
|
35
|
+
"@zag-js/types": "0.55.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"clean-package": "2.2.0"
|
package/src/clipboard.connect.ts
CHANGED
|
@@ -16,43 +16,59 @@ export function connect<T extends PropTypes>(state: State, send: Send, normalize
|
|
|
16
16
|
copy() {
|
|
17
17
|
send({ type: "COPY" })
|
|
18
18
|
},
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
19
|
+
|
|
20
|
+
getRootProps() {
|
|
21
|
+
return normalize.element({
|
|
22
|
+
...parts.root.attrs,
|
|
23
|
+
"data-copied": dataAttr(copied),
|
|
24
|
+
id: dom.getRootId(state.context),
|
|
25
|
+
})
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
getLabelProps() {
|
|
29
|
+
return normalize.label({
|
|
30
|
+
...parts.label.attrs,
|
|
31
|
+
htmlFor: dom.getInputId(state.context),
|
|
32
|
+
"data-copied": dataAttr(copied),
|
|
33
|
+
id: dom.getLabelId(state.context),
|
|
34
|
+
})
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
getControlProps() {
|
|
38
|
+
return normalize.element({
|
|
39
|
+
...parts.control.attrs,
|
|
40
|
+
"data-copied": dataAttr(copied),
|
|
41
|
+
})
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
getInputProps() {
|
|
45
|
+
return normalize.input({
|
|
46
|
+
...parts.input.attrs,
|
|
47
|
+
defaultValue: state.context.value,
|
|
48
|
+
"data-copied": dataAttr(copied),
|
|
49
|
+
readOnly: true,
|
|
50
|
+
"data-readonly": "true",
|
|
51
|
+
id: dom.getInputId(state.context),
|
|
52
|
+
onFocus(event) {
|
|
53
|
+
event.currentTarget.select()
|
|
54
|
+
},
|
|
55
|
+
onCopy() {
|
|
56
|
+
send({ type: "INPUT.COPY" })
|
|
57
|
+
},
|
|
58
|
+
})
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
getTriggerProps() {
|
|
62
|
+
return normalize.button({
|
|
63
|
+
...parts.trigger.attrs,
|
|
64
|
+
"aria-label": copied ? "Copied to clipboard" : "Copy to clipboard",
|
|
65
|
+
"data-copied": dataAttr(copied),
|
|
66
|
+
onClick() {
|
|
67
|
+
send({ type: "COPY" })
|
|
68
|
+
},
|
|
69
|
+
})
|
|
70
|
+
},
|
|
71
|
+
|
|
56
72
|
getIndicatorProps(props) {
|
|
57
73
|
return normalize.element({
|
|
58
74
|
...parts.indicator.attrs,
|
package/src/clipboard.types.ts
CHANGED
|
@@ -73,10 +73,10 @@ export interface MachineApi<T extends PropTypes = PropTypes> {
|
|
|
73
73
|
*/
|
|
74
74
|
copy(): void
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
getRootProps(): T["element"]
|
|
77
|
+
getLabelProps(): T["label"]
|
|
78
|
+
getControlProps(): T["element"]
|
|
79
|
+
getTriggerProps(): T["button"]
|
|
80
|
+
getInputProps(): T["input"]
|
|
81
81
|
getIndicatorProps(props: IndicatorProps): T["element"]
|
|
82
82
|
}
|