@agent-native/toolkit 0.208.0 → 0.209.0-nightly-20261014070126
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/app/chat/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/app/chat/MultiTabAssistantChat.js +12 -1
- package/dist/app/chat/MultiTabAssistantChat.js.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts +12 -0
- package/dist/app/chat/agentkit-chat/guided-questions.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/guided-questions.js +32 -4
- package/dist/app/chat/agentkit-chat/guided-questions.js.map +1 -1
- package/dist/app/chat/agentkit-chat/index.d.ts +1 -1
- package/dist/app/chat/agentkit-chat/index.d.ts.map +1 -1
- package/dist/app/chat/agentkit-chat/index.js +1 -1
- package/dist/app/chat/agentkit-chat/index.js.map +1 -1
- package/dist/app/chat/chat/run-recovery.d.ts.map +1 -1
- package/dist/app/chat/chat/run-recovery.js +15 -8
- package/dist/app/chat/chat/run-recovery.js.map +1 -1
- package/dist/app/sharing/ShareButton.d.ts.map +1 -1
- package/dist/app/sharing/ShareButton.js +66 -73
- package/dist/app/sharing/ShareButton.js.map +1 -1
- package/dist/app/sharing/ShareDialog.d.ts.map +1 -1
- package/dist/app/sharing/ShareDialog.js +4 -12
- package/dist/app/sharing/ShareDialog.js.map +1 -1
- package/dist/sharing/ShareControls.d.ts +19 -1
- package/dist/sharing/ShareControls.d.ts.map +1 -1
- package/dist/sharing/ShareControls.js +14 -7
- package/dist/sharing/ShareControls.js.map +1 -1
- package/dist/sharing/SharePrimitives.js +1 -1
- package/dist/sharing/SharePrimitives.js.map +1 -1
- package/dist/sharing/index.d.ts +1 -1
- package/dist/sharing/index.d.ts.map +1 -1
- package/dist/sharing/index.js +1 -1
- package/dist/sharing/index.js.map +1 -1
- package/package.json +4 -4
- package/src/app/chat/MultiTabAssistantChat.spec.tsx +101 -2
- package/src/app/chat/MultiTabAssistantChat.tsx +14 -1
- package/src/app/chat/agentkit-chat/guided-questions.flow.spec.tsx +168 -0
- package/src/app/chat/agentkit-chat/guided-questions.tsx +54 -9
- package/src/app/chat/agentkit-chat/index.ts +2 -0
- package/src/app/chat/chat/run-recovery.spec.tsx +64 -0
- package/src/app/chat/chat/run-recovery.tsx +14 -8
- package/src/app/sharing/ShareButton.spec.tsx +125 -32
- package/src/app/sharing/ShareButton.tsx +119 -149
- package/src/app/sharing/ShareDialog.spec.tsx +31 -0
- package/src/app/sharing/ShareDialog.tsx +46 -71
- package/src/sharing/ShareControls.spec.tsx +86 -1
- package/src/sharing/ShareControls.tsx +83 -27
- package/src/sharing/SharePrimitives.tsx +1 -1
- package/src/sharing/index.ts +4 -0
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
JoinedShareControl,
|
|
17
17
|
ShareCopyRow,
|
|
18
18
|
ShareModeTabs,
|
|
19
|
+
ShareTabs,
|
|
19
20
|
ShareTrigger,
|
|
20
21
|
} from "@agent-native/toolkit/sharing";
|
|
21
22
|
import {
|
|
@@ -39,8 +40,8 @@ import {
|
|
|
39
40
|
IconCheck,
|
|
40
41
|
IconChevronDown,
|
|
41
42
|
IconLoader2,
|
|
42
|
-
IconSearch,
|
|
43
43
|
IconSearchOff,
|
|
44
|
+
IconSend2,
|
|
44
45
|
IconUsersGroup,
|
|
45
46
|
IconUserPlus,
|
|
46
47
|
} from "@tabler/icons-react";
|
|
@@ -161,14 +162,15 @@ type Share = ShareButtonShare;
|
|
|
161
162
|
|
|
162
163
|
const BUTTON_BASE =
|
|
163
164
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0";
|
|
164
|
-
const
|
|
165
|
+
const BUTTON_PRIMARY_ICON = cn(
|
|
165
166
|
BUTTON_BASE,
|
|
166
|
-
"
|
|
167
|
+
"size-10 shrink-0 bg-primary p-0 text-primary-foreground hover:bg-primary/90 sm:size-8",
|
|
167
168
|
);
|
|
168
169
|
const BUTTON_GHOST_ICON = cn(
|
|
169
170
|
BUTTON_BASE,
|
|
170
171
|
"h-7 w-7 p-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground",
|
|
171
172
|
);
|
|
173
|
+
const SHARE_SECTION_LABEL = "text-xs font-medium text-muted-foreground";
|
|
172
174
|
const SHARE_POPOVER_SURFACE =
|
|
173
175
|
"border border-border bg-popover text-popover-foreground";
|
|
174
176
|
const SHARE_NESTED_OVERLAY_ATTR = "data-agent-native-share-overlay";
|
|
@@ -427,7 +429,7 @@ export function ShareButton(props: ShareButtonProps) {
|
|
|
427
429
|
sideOffset={6}
|
|
428
430
|
data-agent-native-share-overlay=""
|
|
429
431
|
className={cn(
|
|
430
|
-
"z-[2000] w-[
|
|
432
|
+
"z-[2000] w-[360px] max-w-[calc(100vw-1rem)] rounded-lg p-3 shadow-lg",
|
|
431
433
|
SHARE_POPOVER_SURFACE,
|
|
432
434
|
props.popoverClassName,
|
|
433
435
|
)}
|
|
@@ -446,7 +448,6 @@ function SharePanel(
|
|
|
446
448
|
},
|
|
447
449
|
) {
|
|
448
450
|
const t = useT();
|
|
449
|
-
const tabIds = useId();
|
|
450
451
|
const { controller } = props;
|
|
451
452
|
const {
|
|
452
453
|
inviteEmail,
|
|
@@ -514,7 +515,7 @@ function SharePanel(
|
|
|
514
515
|
linkType="share"
|
|
515
516
|
/>
|
|
516
517
|
) : props.shareUrlPlaceholder ? (
|
|
517
|
-
<div className="mb-
|
|
518
|
+
<div className="mb-3 rounded-md border border-dashed border-border bg-muted/20 px-3 py-2 text-xs text-muted-foreground">
|
|
518
519
|
{props.shareUrlLabel ? (
|
|
519
520
|
<div className="mb-0.5 font-medium text-foreground">
|
|
520
521
|
{props.shareUrlLabel}
|
|
@@ -577,27 +578,33 @@ function SharePanel(
|
|
|
577
578
|
) : isLoading ? (
|
|
578
579
|
<div>
|
|
579
580
|
{showShareLinks ? (
|
|
580
|
-
<div className="mb-
|
|
581
|
+
<div className="mb-3 h-8 rounded-md bg-muted animate-pulse" />
|
|
581
582
|
) : null}
|
|
582
|
-
<div className="mb-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
<div className="mb-
|
|
583
|
+
<div className={cn("mb-1.5", SHARE_SECTION_LABEL)}>
|
|
584
|
+
{generalAccessLabel}
|
|
585
|
+
</div>
|
|
586
|
+
<div className="mb-3 h-8 rounded-md bg-muted animate-pulse" />
|
|
587
|
+
<div className={cn("mb-1.5", SHARE_SECTION_LABEL)}>
|
|
588
|
+
{peopleAccessLabel}
|
|
589
|
+
</div>
|
|
590
|
+
<div className="mb-3 h-8 rounded-md bg-muted animate-pulse" />
|
|
586
591
|
</div>
|
|
587
592
|
) : (
|
|
588
593
|
<div className={props.agentTabContent ? "flex flex-col" : undefined}>
|
|
589
594
|
{showShareLinks && shareUrlPlacement === "top" ? shareLinks : null}
|
|
590
595
|
|
|
591
|
-
<div className={cn("mb-
|
|
596
|
+
<div className={cn("mb-3", props.agentTabContent && "order-2")}>
|
|
592
597
|
{!props.agentTabContent ? (
|
|
593
|
-
<div className="mb-
|
|
598
|
+
<div className={cn("mb-1.5", SHARE_SECTION_LABEL)}>
|
|
599
|
+
{generalAccessLabel}
|
|
600
|
+
</div>
|
|
594
601
|
) : null}
|
|
595
|
-
<div className="flex items-center gap-
|
|
602
|
+
<div className="flex items-center gap-2">
|
|
596
603
|
<span
|
|
597
604
|
aria-hidden
|
|
598
|
-
className="inline-flex
|
|
605
|
+
className="inline-flex size-6 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground"
|
|
599
606
|
>
|
|
600
|
-
<meta.Icon size={
|
|
607
|
+
<meta.Icon size={12} strokeWidth={1.75} />
|
|
601
608
|
</span>
|
|
602
609
|
<div className="min-w-0 flex-1">
|
|
603
610
|
<VisibilitySelect
|
|
@@ -624,76 +631,78 @@ function SharePanel(
|
|
|
624
631
|
</div>
|
|
625
632
|
</div>
|
|
626
633
|
|
|
627
|
-
<div className={cn("mb-
|
|
634
|
+
<div className={cn("mb-3 space-y-3", props.agentTabContent && "order-1")}>
|
|
628
635
|
{!props.agentTabContent ? (
|
|
629
636
|
<>
|
|
630
637
|
{accessRequests}
|
|
631
|
-
<div className=
|
|
638
|
+
<div className={SHARE_SECTION_LABEL}>{peopleAccessLabel}</div>
|
|
632
639
|
</>
|
|
633
640
|
) : null}
|
|
634
641
|
{canManage ? (
|
|
635
642
|
<div className="space-y-2">
|
|
636
|
-
<div className="flex
|
|
637
|
-
<
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
onInviteEmailChange(suggestion.email);
|
|
653
|
-
}
|
|
654
|
-
setSuggestionsOpen(false);
|
|
655
|
-
if (shareError) setShareError(null);
|
|
656
|
-
}}
|
|
657
|
-
onSubmit={handleAdd}
|
|
658
|
-
placeholder={
|
|
659
|
-
policy.requireOrgMemberForUserShares
|
|
660
|
-
? t("agentChat.share.addPeopleOrganization", {
|
|
661
|
-
defaultValue: "Add people from your organization",
|
|
662
|
-
})
|
|
663
|
-
: t("agentChat.share.addPeopleEmail", {
|
|
664
|
-
defaultValue: policy.supportsGroupShares
|
|
665
|
-
? "Add people or groups"
|
|
666
|
-
: "Add people by email",
|
|
667
|
-
})
|
|
643
|
+
<div className="flex items-stretch gap-1.5">
|
|
644
|
+
<MemberAutocomplete
|
|
645
|
+
value={inviteEmail}
|
|
646
|
+
open={suggestionsOpen && !props.basicSharingOnly}
|
|
647
|
+
onOpenChange={(open) => {
|
|
648
|
+
if (!props.basicSharingOnly) setSuggestionsOpen(open);
|
|
649
|
+
}}
|
|
650
|
+
onValueChange={(next) => {
|
|
651
|
+
onInviteEmailChange(next);
|
|
652
|
+
if (shareError) setShareError(null);
|
|
653
|
+
}}
|
|
654
|
+
onSelectSuggestion={(suggestion) => {
|
|
655
|
+
if (suggestion.principalType === "group") {
|
|
656
|
+
selectGroup(suggestion);
|
|
657
|
+
} else {
|
|
658
|
+
onInviteEmailChange(suggestion.email);
|
|
668
659
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
660
|
+
setSuggestionsOpen(false);
|
|
661
|
+
if (shareError) setShareError(null);
|
|
662
|
+
}}
|
|
663
|
+
onSubmit={handleAdd}
|
|
664
|
+
placeholder={
|
|
665
|
+
policy.requireOrgMemberForUserShares
|
|
666
|
+
? t("agentChat.share.addPeopleOrganization", {
|
|
667
|
+
defaultValue: "Add people from your organization",
|
|
668
|
+
})
|
|
669
|
+
: t("agentChat.share.addPeopleEmail", {
|
|
670
|
+
defaultValue: policy.supportsGroupShares
|
|
671
|
+
? "Add people or groups"
|
|
672
|
+
: "Add people by email",
|
|
673
|
+
})
|
|
674
|
+
}
|
|
675
|
+
suggestions={[
|
|
676
|
+
...memberSuggestions.map((member) => ({
|
|
677
|
+
...member,
|
|
678
|
+
principalType: "user" as const,
|
|
679
|
+
})),
|
|
680
|
+
...(policy.supportsGroupShares
|
|
681
|
+
? groupSuggestions.map((group) => ({
|
|
682
|
+
...group,
|
|
683
|
+
principalType: "group" as const,
|
|
684
|
+
}))
|
|
685
|
+
: []),
|
|
686
|
+
]}
|
|
687
|
+
search={memberSearch}
|
|
688
|
+
trailing={
|
|
689
|
+
<RoleSelect
|
|
690
|
+
value={role}
|
|
691
|
+
onChange={setRole}
|
|
692
|
+
roleCopy={props.roleCopy}
|
|
693
|
+
allowedRoles={allowedRolesFor(props)}
|
|
694
|
+
/>
|
|
695
|
+
}
|
|
689
696
|
/>
|
|
690
697
|
<button
|
|
691
698
|
type="button"
|
|
692
699
|
onClick={handleAdd}
|
|
693
700
|
disabled={!hasInviteEmail}
|
|
694
|
-
|
|
701
|
+
aria-label={t("agentChat.share.add", { defaultValue: "Add" })}
|
|
702
|
+
title={t("agentChat.share.add", { defaultValue: "Add" })}
|
|
703
|
+
className={BUTTON_PRIMARY_ICON}
|
|
695
704
|
>
|
|
696
|
-
|
|
705
|
+
<IconSend2 />
|
|
697
706
|
</button>
|
|
698
707
|
</div>
|
|
699
708
|
{shareError ? (
|
|
@@ -761,12 +770,12 @@ function SharePanel(
|
|
|
761
770
|
{props.agentTabContent ? (
|
|
762
771
|
<>
|
|
763
772
|
{accessRequests}
|
|
764
|
-
<div className=
|
|
773
|
+
<div className={SHARE_SECTION_LABEL}>{peopleAccessLabel}</div>
|
|
765
774
|
</>
|
|
766
775
|
) : null}
|
|
767
776
|
<ul className="flex list-none flex-col gap-1 p-0 m-0">
|
|
768
777
|
{data?.ownerEmail ? (
|
|
769
|
-
<li className="flex items-center gap-
|
|
778
|
+
<li className="flex min-h-8 items-center gap-2 px-1.5 py-1 text-sm">
|
|
770
779
|
<Avatar
|
|
771
780
|
email={data.ownerEmail}
|
|
772
781
|
image={memberImage(data.ownerEmail, knownMembers)}
|
|
@@ -784,7 +793,7 @@ function SharePanel(
|
|
|
784
793
|
<li
|
|
785
794
|
key={keyOf(s)}
|
|
786
795
|
className={cn(
|
|
787
|
-
"flex items-center gap-
|
|
796
|
+
"flex min-h-8 items-center gap-2 px-1.5 py-1 text-sm",
|
|
788
797
|
inFlight.has(keyOf(s)) && "opacity-60",
|
|
789
798
|
)}
|
|
790
799
|
>
|
|
@@ -832,7 +841,7 @@ function SharePanel(
|
|
|
832
841
|
</li>
|
|
833
842
|
))}
|
|
834
843
|
{!shares.length && !data?.ownerEmail ? (
|
|
835
|
-
<li className="px-1 py-1
|
|
844
|
+
<li className="px-1.5 py-1 text-sm text-muted-foreground">
|
|
836
845
|
{t("agentChat.share.noAccess", {
|
|
837
846
|
defaultValue: "No one has access yet.",
|
|
838
847
|
})}
|
|
@@ -844,7 +853,7 @@ function SharePanel(
|
|
|
844
853
|
{shareError && !canManage ? (
|
|
845
854
|
<div
|
|
846
855
|
role="alert"
|
|
847
|
-
className="mb-
|
|
856
|
+
className="mb-3 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive"
|
|
848
857
|
>
|
|
849
858
|
{shareError}
|
|
850
859
|
</div>
|
|
@@ -860,7 +869,7 @@ function SharePanel(
|
|
|
860
869
|
) : null}
|
|
861
870
|
|
|
862
871
|
{props.accessNote ? (
|
|
863
|
-
<div className="mb-
|
|
872
|
+
<div className="mb-3 rounded-md border border-border bg-muted/35 p-3 text-xs text-muted-foreground">
|
|
864
873
|
{props.accessNote}
|
|
865
874
|
</div>
|
|
866
875
|
) : null}
|
|
@@ -872,14 +881,17 @@ function SharePanel(
|
|
|
872
881
|
);
|
|
873
882
|
|
|
874
883
|
const panelTitle = props.panelTitle ? (
|
|
875
|
-
<h2 className="text-
|
|
884
|
+
<h2 className="text-sm font-semibold leading-normal tracking-normal">
|
|
876
885
|
{props.panelTitle}
|
|
877
886
|
</h2>
|
|
878
887
|
) : null;
|
|
888
|
+
const shareOptionsLabel = t("agentChat.share.shareOptions", {
|
|
889
|
+
defaultValue: "Share options",
|
|
890
|
+
});
|
|
879
891
|
|
|
880
892
|
if (props.agentTabContent) {
|
|
881
893
|
const agentPanel = (
|
|
882
|
-
<div className="space-y-
|
|
894
|
+
<div className="space-y-3">
|
|
883
895
|
{props.agentTabContent}
|
|
884
896
|
{!loadFailed && !isLoading && !props.basicSharingOnly ? (
|
|
885
897
|
<AgentShareSection
|
|
@@ -892,13 +904,14 @@ function SharePanel(
|
|
|
892
904
|
</div>
|
|
893
905
|
);
|
|
894
906
|
return (
|
|
895
|
-
<div className="flex flex-col gap-
|
|
907
|
+
<div className="flex flex-col gap-3">
|
|
896
908
|
{panelTitle}
|
|
897
909
|
<ShareModeTabs
|
|
898
910
|
value={activeShareTab === "share" ? "people" : activeShareTab}
|
|
899
911
|
onValueChange={(value) =>
|
|
900
912
|
handleShareTabChange(value === "people" ? "share" : value)
|
|
901
913
|
}
|
|
914
|
+
listLabel={shareOptionsLabel}
|
|
902
915
|
peopleLabel={props.peopleTabLabel ?? t("agentChat.share.people")}
|
|
903
916
|
agentsLabel={props.agentsTabLabel ?? t("agentChat.share.agents")}
|
|
904
917
|
people={sharePanel}
|
|
@@ -916,7 +929,7 @@ function SharePanel(
|
|
|
916
929
|
|
|
917
930
|
if (!hasTabs) {
|
|
918
931
|
return props.panelTitle ? (
|
|
919
|
-
<div className="flex flex-col gap-
|
|
932
|
+
<div className="flex flex-col gap-3">
|
|
920
933
|
{panelTitle}
|
|
921
934
|
{sharePanel}
|
|
922
935
|
</div>
|
|
@@ -938,54 +951,14 @@ function SharePanel(
|
|
|
938
951
|
? activeShareTab
|
|
939
952
|
: "share";
|
|
940
953
|
return (
|
|
941
|
-
<div className="flex flex-col gap-
|
|
954
|
+
<div className="flex flex-col gap-3">
|
|
942
955
|
{panelTitle}
|
|
943
|
-
<
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
>
|
|
950
|
-
{tabs.map((tab, index) => {
|
|
951
|
-
const active = tab.value === activeTab;
|
|
952
|
-
const tabId = `${tabIds}-tab-${index}`;
|
|
953
|
-
const panelId = `${tabIds}-panel-${index}`;
|
|
954
|
-
return (
|
|
955
|
-
<button
|
|
956
|
-
key={tab.value}
|
|
957
|
-
type="button"
|
|
958
|
-
id={tabId}
|
|
959
|
-
role="tab"
|
|
960
|
-
aria-selected={active}
|
|
961
|
-
aria-controls={panelId}
|
|
962
|
-
disabled={tab.disabled}
|
|
963
|
-
onClick={() => handleShareTabChange(tab.value)}
|
|
964
|
-
className={cn(
|
|
965
|
-
"h-11 min-w-0 flex-1 rounded-lg px-3 text-sm font-medium text-muted-foreground hover:bg-background/70 hover:text-foreground disabled:pointer-events-none disabled:opacity-50",
|
|
966
|
-
active && "bg-background text-foreground shadow-sm",
|
|
967
|
-
)}
|
|
968
|
-
>
|
|
969
|
-
<span className="block truncate">{tab.label}</span>
|
|
970
|
-
</button>
|
|
971
|
-
);
|
|
972
|
-
})}
|
|
973
|
-
</div>
|
|
974
|
-
{tabs.map((tab, index) => {
|
|
975
|
-
const active = tab.value === activeTab;
|
|
976
|
-
return (
|
|
977
|
-
<div
|
|
978
|
-
key={tab.value}
|
|
979
|
-
id={`${tabIds}-panel-${index}`}
|
|
980
|
-
role="tabpanel"
|
|
981
|
-
aria-labelledby={`${tabIds}-tab-${index}`}
|
|
982
|
-
tabIndex={active ? 0 : -1}
|
|
983
|
-
hidden={!active}
|
|
984
|
-
>
|
|
985
|
-
{active ? tab.content : null}
|
|
986
|
-
</div>
|
|
987
|
-
);
|
|
988
|
-
})}
|
|
956
|
+
<ShareTabs
|
|
957
|
+
value={activeTab}
|
|
958
|
+
onValueChange={handleShareTabChange}
|
|
959
|
+
listLabel={shareOptionsLabel}
|
|
960
|
+
tabs={tabs}
|
|
961
|
+
/>
|
|
989
962
|
</div>
|
|
990
963
|
);
|
|
991
964
|
}
|
|
@@ -1094,6 +1067,8 @@ interface MemberAutocompleteProps {
|
|
|
1094
1067
|
placeholder: string;
|
|
1095
1068
|
suggestions: ShareSuggestion[];
|
|
1096
1069
|
search: OrgMemberSearch;
|
|
1070
|
+
/** Rendered inside the field, after the input. */
|
|
1071
|
+
trailing?: ReactNode;
|
|
1097
1072
|
}
|
|
1098
1073
|
|
|
1099
1074
|
type ShareSuggestion =
|
|
@@ -1110,6 +1085,7 @@ function MemberAutocomplete({
|
|
|
1110
1085
|
placeholder,
|
|
1111
1086
|
suggestions,
|
|
1112
1087
|
search,
|
|
1088
|
+
trailing,
|
|
1113
1089
|
}: MemberAutocompleteProps) {
|
|
1114
1090
|
const t = useT();
|
|
1115
1091
|
const rawListboxId = useId();
|
|
@@ -1202,13 +1178,7 @@ function MemberAutocomplete({
|
|
|
1202
1178
|
return (
|
|
1203
1179
|
<Popover open={open} onOpenChange={onOpenChange}>
|
|
1204
1180
|
<PopoverAnchor asChild>
|
|
1205
|
-
<div className="
|
|
1206
|
-
<IconSearch
|
|
1207
|
-
aria-hidden
|
|
1208
|
-
size={15}
|
|
1209
|
-
strokeWidth={1.8}
|
|
1210
|
-
className="pointer-events-none absolute start-2.5 top-1/2 -translate-y-1/2 text-muted-foreground"
|
|
1211
|
-
/>
|
|
1181
|
+
<div className="flex h-10 min-w-0 flex-1 items-center overflow-hidden rounded-md border border-input bg-card focus-within:ring-1 focus-within:ring-ring sm:h-8">
|
|
1212
1182
|
<input
|
|
1213
1183
|
ref={inputRef}
|
|
1214
1184
|
type="text"
|
|
@@ -1235,16 +1205,17 @@ function MemberAutocomplete({
|
|
|
1235
1205
|
}}
|
|
1236
1206
|
onKeyDown={handleKeyDown}
|
|
1237
1207
|
autoComplete="off"
|
|
1238
|
-
className="h-
|
|
1208
|
+
className="h-full min-w-0 flex-1 bg-transparent px-2.5 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none"
|
|
1239
1209
|
/>
|
|
1240
1210
|
{search.isLoading ? (
|
|
1241
1211
|
<IconLoader2
|
|
1242
1212
|
aria-hidden
|
|
1243
|
-
size={
|
|
1213
|
+
size={14}
|
|
1244
1214
|
strokeWidth={1.8}
|
|
1245
|
-
className="
|
|
1215
|
+
className="me-2 shrink-0 animate-spin text-muted-foreground"
|
|
1246
1216
|
/>
|
|
1247
1217
|
) : null}
|
|
1218
|
+
{trailing}
|
|
1248
1219
|
</div>
|
|
1249
1220
|
</PopoverAnchor>
|
|
1250
1221
|
<PopoverContent
|
|
@@ -1276,7 +1247,7 @@ function MemberAutocomplete({
|
|
|
1276
1247
|
onMouseEnter={() => setActiveIndex(index)}
|
|
1277
1248
|
onClick={() => chooseSuggestion(suggestion)}
|
|
1278
1249
|
className={cn(
|
|
1279
|
-
"flex cursor-pointer select-none flex-col rounded-sm px-
|
|
1250
|
+
"flex cursor-pointer select-none flex-col rounded-sm px-2 py-1.5 text-sm outline-none",
|
|
1280
1251
|
active
|
|
1281
1252
|
? "bg-accent text-accent-foreground"
|
|
1282
1253
|
: "text-foreground hover:bg-accent hover:text-accent-foreground",
|
|
@@ -1295,7 +1266,6 @@ function MemberAutocomplete({
|
|
|
1295
1266
|
email={suggestion.email}
|
|
1296
1267
|
image={suggestion.image}
|
|
1297
1268
|
label={suggestion.name?.trim() || suggestion.email}
|
|
1298
|
-
className="h-6 w-6 text-[10px]"
|
|
1299
1269
|
/>
|
|
1300
1270
|
)}
|
|
1301
1271
|
<span className="truncate">
|
|
@@ -1416,14 +1386,14 @@ function CopyLinkField({
|
|
|
1416
1386
|
copyLabel={t("agentChat.share.copy", { defaultValue: "Copy" })}
|
|
1417
1387
|
copiedLabel={t("agentChat.share.copied", { defaultValue: "Copied" })}
|
|
1418
1388
|
onCopy={copy}
|
|
1419
|
-
className="mb-
|
|
1389
|
+
className="mb-3"
|
|
1420
1390
|
/>
|
|
1421
1391
|
);
|
|
1422
1392
|
}
|
|
1423
1393
|
|
|
1424
1394
|
const selectContentClass = `${SHARE_NESTED_OVERLAY_Z} min-w-[12rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0`;
|
|
1425
1395
|
const selectItemClass =
|
|
1426
|
-
"relative flex w-full cursor-pointer select-none items-start gap-2 rounded-sm py-
|
|
1396
|
+
"relative flex w-full cursor-pointer select-none items-start gap-2 rounded-sm py-1.5 ps-8 pe-3 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
|
|
1427
1397
|
|
|
1428
1398
|
interface ShadSelectItemProps {
|
|
1429
1399
|
value: string;
|
|
@@ -1440,7 +1410,7 @@ function SelectItems({ items }: { items: ShadSelectItemProps[] }) {
|
|
|
1440
1410
|
value={it.value}
|
|
1441
1411
|
className={selectItemClass}
|
|
1442
1412
|
>
|
|
1443
|
-
<span className="absolute start-2 top-
|
|
1413
|
+
<span className="absolute start-2 top-1.5 flex h-4 w-4 items-center justify-center">
|
|
1444
1414
|
<Select.ItemIndicator>
|
|
1445
1415
|
<IconCheck size={14} />
|
|
1446
1416
|
</Select.ItemIndicator>
|
|
@@ -1489,11 +1459,11 @@ function RoleSelect(props: {
|
|
|
1489
1459
|
props.plain
|
|
1490
1460
|
? cn(
|
|
1491
1461
|
BUTTON_BASE,
|
|
1492
|
-
"h-7 px-2 bg-transparent text-muted-foreground hover:bg-accent hover:text-accent-foreground",
|
|
1462
|
+
"h-7 gap-1 px-2 bg-transparent text-xs font-normal text-muted-foreground hover:bg-accent hover:text-accent-foreground [&_svg]:size-3.5",
|
|
1493
1463
|
)
|
|
1494
1464
|
: cn(
|
|
1495
1465
|
BUTTON_BASE,
|
|
1496
|
-
"h-
|
|
1466
|
+
"h-full gap-1 rounded-none bg-transparent px-2 text-xs font-normal text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:ring-inset focus-visible:ring-offset-0 [&_svg]:size-3.5",
|
|
1497
1467
|
)
|
|
1498
1468
|
}
|
|
1499
1469
|
aria-label={t("agentChat.share.role", { defaultValue: "Role" })}
|
|
@@ -1547,7 +1517,7 @@ function VisibilitySelect(props: {
|
|
|
1547
1517
|
<Select.Trigger
|
|
1548
1518
|
className={cn(
|
|
1549
1519
|
BUTTON_BASE,
|
|
1550
|
-
"h-7 px-1 -ms-1 bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground",
|
|
1520
|
+
"h-7 px-1 -ms-1 bg-transparent font-normal text-foreground hover:bg-accent hover:text-accent-foreground",
|
|
1551
1521
|
props.sentenceTrigger && "w-full justify-between text-sm font-normal",
|
|
1552
1522
|
)}
|
|
1553
1523
|
aria-label={t("agentChat.share.generalAccess", {
|
|
@@ -1605,12 +1575,12 @@ function Avatar({
|
|
|
1605
1575
|
<span
|
|
1606
1576
|
aria-hidden
|
|
1607
1577
|
className={cn(
|
|
1608
|
-
"inline-flex
|
|
1578
|
+
"inline-flex size-6 shrink-0 items-center justify-center overflow-hidden rounded-full bg-muted text-[10px] font-semibold text-muted-foreground",
|
|
1609
1579
|
className,
|
|
1610
1580
|
)}
|
|
1611
1581
|
>
|
|
1612
1582
|
{org || group ? (
|
|
1613
|
-
<IconUsersGroup size={
|
|
1583
|
+
<IconUsersGroup size={12} strokeWidth={1.75} />
|
|
1614
1584
|
) : profileImage || avatarUrl ? (
|
|
1615
1585
|
<img
|
|
1616
1586
|
src={profileImage || avatarUrl || undefined}
|
|
@@ -158,6 +158,37 @@ describe("ShareDialog primitive normalization", () => {
|
|
|
158
158
|
).toContain("mt-10");
|
|
159
159
|
});
|
|
160
160
|
|
|
161
|
+
it("draws the tab row as underline tabs that switch between link and embed", async () => {
|
|
162
|
+
await renderDialog(vi.fn(), {
|
|
163
|
+
shareUrl: "https://share.example.test/doc-1",
|
|
164
|
+
embedUrl: "https://embed.example.test/doc-1",
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const list = document.body.querySelector('[role="tablist"]');
|
|
168
|
+
expect(list?.className).toContain("bg-transparent");
|
|
169
|
+
expect(list?.className).not.toContain("bg-muted");
|
|
170
|
+
const tabs = Array.from(
|
|
171
|
+
document.body.querySelectorAll<HTMLElement>('[role="tab"]'),
|
|
172
|
+
);
|
|
173
|
+
expect(tabs.map((tab) => tab.textContent)).toEqual([
|
|
174
|
+
"share.link",
|
|
175
|
+
"share.embed",
|
|
176
|
+
]);
|
|
177
|
+
for (const tab of tabs) expect(tab.className).toContain("after:h-0.5");
|
|
178
|
+
expect(tabs[0].getAttribute("aria-selected")).toBe("true");
|
|
179
|
+
expect(document.body.textContent).toContain("share.generalAccess");
|
|
180
|
+
|
|
181
|
+
act(() => {
|
|
182
|
+
tabs[1].dispatchEvent(
|
|
183
|
+
new MouseEvent("mousedown", { bubbles: true, button: 0 }),
|
|
184
|
+
);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
expect(tabs[1].getAttribute("aria-selected")).toBe("true");
|
|
188
|
+
expect(document.body.textContent).toContain("share.embedUrl");
|
|
189
|
+
expect(document.body.textContent).not.toContain("share.generalAccess");
|
|
190
|
+
});
|
|
191
|
+
|
|
161
192
|
it("keeps individual access on the primary link surface", async () => {
|
|
162
193
|
await renderDialog(vi.fn(), {
|
|
163
194
|
shareUrl: "https://share.example.test/doc-1",
|