@astryxdesign/lab 0.7.8-canary.f50bc74 → 0.7.8-canary.ffd29c5
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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file CommentActions.tsx
|
|
3
|
-
* @input Uses React, React DOM flushSync, StyleX,
|
|
4
|
-
* ToggleButton, OverflowList, DropdownMenu, Popover, Text
|
|
3
|
+
* @input Uses React, React DOM flushSync, StyleX, useClipboard, IconButton,
|
|
4
|
+
* Button, Tooltip, ToggleButton, OverflowList, DropdownMenu, Popover, Text
|
|
5
5
|
* @output Exports CommentActions (a comment's header actions), ReactionSummary
|
|
6
6
|
* (its reaction toggles), and the action-lookup helpers rows use for focus
|
|
7
7
|
* hand-offs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommentActions.d.ts","sourceRoot":"","sources":["../../src/Comments/CommentActions.tsx"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"CommentActions.d.ts","sourceRoot":"","sources":["../../src/Comments/CommentActions.tsx"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,EAAgC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAIpE,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,iCAAiC,CAAC;AAczC,OAAO,EAAkB,KAAK,UAAU,EAAC,MAAM,SAAS,CAAC;AACzD,OAAO,KAAK,EAAkB,qBAAqB,EAAC,MAAM,SAAS,CAAC;AAmBpE,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAEhF,oEAAoE;AACpE,MAAM,MAAM,aAAa,GAAG;IAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAC,CAAC;AAE9E;;sBAEsB;AACtB,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,WAAW,GAAG,IAAI,EACxB,MAAM,EAAE,eAAe,GACtB,WAAW,GAAG,IAAI,CAMpB;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,WAAW,GAAG,IAAI,GACvB,WAAW,GAAG,IAAI,CAIpB;AAiCD,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,OAAO,EACP,MAAM,EACN,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD,sCA0CA;AAkDD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAC7B,iBAAiB,EACjB,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,MAAM,EACN,SAAS,EACT,SAAS,EACT,YAAY,EACZ,OAAO,EACP,OAAO,EACP,OAAO,EACP,aAAa,GACd,EAAE;IACD,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,OAAO,EAAE,CACP,OAAO,EAAE,UAAU,EACnB,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,qBAAqB,KAC3B,IAAI,CAAC;IACV,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC1C,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,+BAuQA"}
|
|
@@ -4,18 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file CommentActions.tsx
|
|
7
|
-
* @input Uses React, React DOM flushSync, StyleX,
|
|
8
|
-
* ToggleButton, OverflowList, DropdownMenu, Popover, Text
|
|
7
|
+
* @input Uses React, React DOM flushSync, StyleX, useClipboard, IconButton,
|
|
8
|
+
* Button, Tooltip, ToggleButton, OverflowList, DropdownMenu, Popover, Text
|
|
9
9
|
* @output Exports CommentActions (a comment's header actions), ReactionSummary
|
|
10
10
|
* (its reaction toggles), and the action-lookup helpers rows use for focus
|
|
11
11
|
* hand-offs
|
|
12
12
|
* @position Internal parts of a comment row in the Comments family
|
|
13
13
|
*/
|
|
14
|
-
import { useCallback,
|
|
14
|
+
import { useCallback, useRef, useState } from 'react';
|
|
15
15
|
import { flushSync } from 'react-dom';
|
|
16
16
|
import * as stylex from '@stylexjs/stylex';
|
|
17
17
|
import { Button } from '@astryxdesign/core/Button';
|
|
18
18
|
import { DropdownMenu } from '@astryxdesign/core/DropdownMenu';
|
|
19
|
+
import { useClipboard } from '@astryxdesign/core/hooks';
|
|
19
20
|
import { Icon } from '@astryxdesign/core/Icon';
|
|
20
21
|
import { IconButton } from '@astryxdesign/core/IconButton';
|
|
21
22
|
import { HStack, VStack } from '@astryxdesign/core/Layout';
|
|
@@ -31,7 +32,6 @@ import { reactionDescription } from "./i18n.js";
|
|
|
31
32
|
import { CommentIcon } from "./icons.js";
|
|
32
33
|
import { commentAnchorId } from "./utils.js";
|
|
33
34
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
34
|
-
const LINK_COPIED_RESET_MS = 2_000;
|
|
35
35
|
const MORE_MENU_MIN_WIDTH = `calc(${spacingVars['--spacing-8']} * 5)`;
|
|
36
36
|
const styles = {
|
|
37
37
|
actionsList: {
|
|
@@ -218,7 +218,10 @@ export function CommentActions({
|
|
|
218
218
|
resolveAction
|
|
219
219
|
}) {
|
|
220
220
|
const t = useTranslator();
|
|
221
|
-
const
|
|
221
|
+
const {
|
|
222
|
+
copy: copyToClipboard,
|
|
223
|
+
isCopied: isLinkCopied
|
|
224
|
+
} = useClipboard();
|
|
222
225
|
const [isLinkTooltipOpen, setIsLinkTooltipOpen] = useState(false);
|
|
223
226
|
const [isPickerOpen, setIsPickerOpen] = useState(false);
|
|
224
227
|
const [collapsed, setCollapsed] = useState(NO_COLLAPSED_ACTIONS);
|
|
@@ -236,24 +239,7 @@ export function CommentActions({
|
|
|
236
239
|
}) : /*#__PURE__*/_jsx(CommentIcon, {
|
|
237
240
|
name: "copyLink"
|
|
238
241
|
});
|
|
239
|
-
const copyCommentLink =
|
|
240
|
-
if (navigator.clipboard == null) {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
try {
|
|
244
|
-
await navigator.clipboard.writeText(new URL(href, window.location.href).href);
|
|
245
|
-
setIsLinkCopied(true);
|
|
246
|
-
} catch {
|
|
247
|
-
setIsLinkCopied(false);
|
|
248
|
-
}
|
|
249
|
-
};
|
|
250
|
-
useEffect(() => {
|
|
251
|
-
if (!isLinkCopied) {
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
const timer = window.setTimeout(() => setIsLinkCopied(false), LINK_COPIED_RESET_MS);
|
|
255
|
-
return () => window.clearTimeout(timer);
|
|
256
|
-
}, [isLinkCopied]);
|
|
242
|
+
const copyCommentLink = () => copyToClipboard(new URL(href, window.location.href).href);
|
|
257
243
|
const changePicker = isOpen => {
|
|
258
244
|
setIsPickerOpen(isOpen);
|
|
259
245
|
onOpenChange(isOpen);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/lab",
|
|
3
|
-
"version": "0.7.8-canary.
|
|
3
|
+
"version": "0.7.8-canary.ffd29c5",
|
|
4
4
|
"description": "Experimental Astryx components — published to npm only under the @canary dist-tag for early testing; never released as a stable (latest) version.",
|
|
5
5
|
"author": "Meta Open Source",
|
|
6
6
|
"license": "MIT",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"@stylexjs/stylex": ">=0.10.0",
|
|
52
|
-
"@astryxdesign/core": "0.7.8-canary.
|
|
52
|
+
"@astryxdesign/core": "0.7.8-canary.ffd29c5",
|
|
53
53
|
"react": ">=19.0.0",
|
|
54
54
|
"react-dom": ">=19.0.0"
|
|
55
55
|
},
|
|
@@ -59,9 +59,9 @@
|
|
|
59
59
|
"d3-shape": "^3.2.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@astryxdesign/a11y-spec": "0.7.8-canary.
|
|
63
|
-
"@astryxdesign/cli": "0.7.8-canary.
|
|
64
|
-
"@astryxdesign/interaction-harness": "0.7.8-canary.
|
|
62
|
+
"@astryxdesign/a11y-spec": "0.7.8-canary.ffd29c5",
|
|
63
|
+
"@astryxdesign/cli": "0.7.8-canary.ffd29c5",
|
|
64
|
+
"@astryxdesign/interaction-harness": "0.7.8-canary.ffd29c5",
|
|
65
65
|
"@babel/cli": "^7.29.7",
|
|
66
66
|
"@babel/core": "^7.29.7",
|
|
67
67
|
"@babel/preset-react": "^7.29.7",
|
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file CommentActions.tsx
|
|
7
|
-
* @input Uses React, React DOM flushSync, StyleX,
|
|
8
|
-
* ToggleButton, OverflowList, DropdownMenu, Popover, Text
|
|
7
|
+
* @input Uses React, React DOM flushSync, StyleX, useClipboard, IconButton,
|
|
8
|
+
* Button, Tooltip, ToggleButton, OverflowList, DropdownMenu, Popover, Text
|
|
9
9
|
* @output Exports CommentActions (a comment's header actions), ReactionSummary
|
|
10
10
|
* (its reaction toggles), and the action-lookup helpers rows use for focus
|
|
11
11
|
* hand-offs
|
|
12
12
|
* @position Internal parts of a comment row in the Comments family
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import {useCallback,
|
|
15
|
+
import {useCallback, useRef, useState, type ReactNode} from 'react';
|
|
16
16
|
import {flushSync} from 'react-dom';
|
|
17
17
|
import * as stylex from '@stylexjs/stylex';
|
|
18
18
|
import {Button} from '@astryxdesign/core/Button';
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
DropdownMenu,
|
|
21
21
|
type DropdownMenuOption,
|
|
22
22
|
} from '@astryxdesign/core/DropdownMenu';
|
|
23
|
+
import {useClipboard} from '@astryxdesign/core/hooks';
|
|
23
24
|
import {Icon} from '@astryxdesign/core/Icon';
|
|
24
25
|
import {IconButton} from '@astryxdesign/core/IconButton';
|
|
25
26
|
import {HStack, VStack} from '@astryxdesign/core/Layout';
|
|
@@ -35,7 +36,6 @@ import {CommentIcon} from './icons';
|
|
|
35
36
|
import {commentAnchorId, type AnyComment} from './utils';
|
|
36
37
|
import type {CommentReaction, CommentReactionOption} from './types';
|
|
37
38
|
|
|
38
|
-
const LINK_COPIED_RESET_MS = 2_000;
|
|
39
39
|
const MORE_MENU_MIN_WIDTH = `calc(${spacingVars['--spacing-8']} * 5)`;
|
|
40
40
|
|
|
41
41
|
const styles = stylex.create({
|
|
@@ -256,7 +256,7 @@ export function CommentActions({
|
|
|
256
256
|
resolveAction?: ResolveAction;
|
|
257
257
|
}) {
|
|
258
258
|
const t = useTranslator();
|
|
259
|
-
const
|
|
259
|
+
const {copy: copyToClipboard, isCopied: isLinkCopied} = useClipboard();
|
|
260
260
|
const [isLinkTooltipOpen, setIsLinkTooltipOpen] = useState(false);
|
|
261
261
|
const [isPickerOpen, setIsPickerOpen] = useState(false);
|
|
262
262
|
const [collapsed, setCollapsed] = useState(NO_COLLAPSED_ACTIONS);
|
|
@@ -276,30 +276,8 @@ export function CommentActions({
|
|
|
276
276
|
<CommentIcon name="copyLink" />
|
|
277
277
|
);
|
|
278
278
|
|
|
279
|
-
const copyCommentLink =
|
|
280
|
-
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
try {
|
|
284
|
-
await navigator.clipboard.writeText(
|
|
285
|
-
new URL(href, window.location.href).href,
|
|
286
|
-
);
|
|
287
|
-
setIsLinkCopied(true);
|
|
288
|
-
} catch {
|
|
289
|
-
setIsLinkCopied(false);
|
|
290
|
-
}
|
|
291
|
-
};
|
|
292
|
-
|
|
293
|
-
useEffect(() => {
|
|
294
|
-
if (!isLinkCopied) {
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
const timer = window.setTimeout(
|
|
298
|
-
() => setIsLinkCopied(false),
|
|
299
|
-
LINK_COPIED_RESET_MS,
|
|
300
|
-
);
|
|
301
|
-
return () => window.clearTimeout(timer);
|
|
302
|
-
}, [isLinkCopied]);
|
|
279
|
+
const copyCommentLink = () =>
|
|
280
|
+
copyToClipboard(new URL(href, window.location.href).href);
|
|
303
281
|
|
|
304
282
|
const changePicker = (isOpen: boolean) => {
|
|
305
283
|
setIsPickerOpen(isOpen);
|
|
@@ -957,6 +957,38 @@ describe('Comments threads', () => {
|
|
|
957
957
|
).toBeTruthy();
|
|
958
958
|
});
|
|
959
959
|
|
|
960
|
+
it('keeps the copied label for the full time after a second copy', async () => {
|
|
961
|
+
vi.useFakeTimers({toFake: ['setTimeout', 'clearTimeout']});
|
|
962
|
+
const wait = (ms: number) => act(() => vi.advanceTimersByTimeAsync(ms));
|
|
963
|
+
const copyButton = (name: string) => screen.getByRole('button', {name});
|
|
964
|
+
try {
|
|
965
|
+
render(
|
|
966
|
+
<Sized>
|
|
967
|
+
<Comments
|
|
968
|
+
comments={[{...COMMENTS[0], replies: []}]}
|
|
969
|
+
currentUser={OTHER}
|
|
970
|
+
/>
|
|
971
|
+
</Sized>,
|
|
972
|
+
);
|
|
973
|
+
await click(copyButton('Copy comment link'));
|
|
974
|
+
await wait(0);
|
|
975
|
+
expect(copyButton('Comment link copied')).toBeTruthy();
|
|
976
|
+
|
|
977
|
+
await wait(1500);
|
|
978
|
+
await click(copyButton('Comment link copied'));
|
|
979
|
+
await wait(0);
|
|
980
|
+
// 2.5 s after the first copy and 1 s after the second one.
|
|
981
|
+
await wait(1000);
|
|
982
|
+
expect(writeText).toHaveBeenCalledTimes(2);
|
|
983
|
+
expect(copyButton('Comment link copied')).toBeTruthy();
|
|
984
|
+
|
|
985
|
+
await wait(1000);
|
|
986
|
+
expect(copyButton('Copy comment link')).toBeTruthy();
|
|
987
|
+
} finally {
|
|
988
|
+
vi.useRealTimers();
|
|
989
|
+
}
|
|
990
|
+
});
|
|
991
|
+
|
|
960
992
|
it('collapses header actions into the more menu when space runs low', async () => {
|
|
961
993
|
overflowControl.collapsed = new Set(['reply', 'link']);
|
|
962
994
|
const onSubmit = vi.fn();
|