@agent-native/toolkit 0.15.0 → 0.16.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.
Files changed (54) hide show
  1. package/README.md +26 -0
  2. package/agent-native.eject.json +35 -1
  3. package/dist/chat-history.css +3 -1
  4. package/dist/composer/PromptComposer.d.ts +7 -1
  5. package/dist/composer/PromptComposer.d.ts.map +1 -1
  6. package/dist/composer/PromptComposer.js +2 -2
  7. package/dist/composer/PromptComposer.js.map +1 -1
  8. package/dist/composer/TiptapComposer.d.ts +19 -1
  9. package/dist/composer/TiptapComposer.d.ts.map +1 -1
  10. package/dist/composer/TiptapComposer.js +27 -4
  11. package/dist/composer/TiptapComposer.js.map +1 -1
  12. package/dist/data-grid/DataGrid.d.ts +92 -0
  13. package/dist/data-grid/DataGrid.d.ts.map +1 -0
  14. package/dist/data-grid/DataGrid.js +315 -0
  15. package/dist/data-grid/DataGrid.js.map +1 -0
  16. package/dist/data-grid/DataGrid.spec.d.ts +2 -0
  17. package/dist/data-grid/DataGrid.spec.d.ts.map +1 -0
  18. package/dist/data-grid/DataGrid.spec.js +134 -0
  19. package/dist/data-grid/DataGrid.spec.js.map +1 -0
  20. package/dist/data-grid/index.d.ts +2 -0
  21. package/dist/data-grid/index.d.ts.map +1 -0
  22. package/dist/data-grid/index.js +2 -0
  23. package/dist/data-grid/index.js.map +1 -0
  24. package/dist/design-system/default-adapter.d.ts.map +1 -1
  25. package/dist/design-system/default-adapter.js +4 -1
  26. package/dist/design-system/default-adapter.js.map +1 -1
  27. package/dist/design-system/default-adapter.spec.js +12 -0
  28. package/dist/design-system/default-adapter.spec.js.map +1 -1
  29. package/dist/design-system/types.d.ts +2 -0
  30. package/dist/design-system/types.d.ts.map +1 -1
  31. package/dist/provider.d.ts.map +1 -1
  32. package/dist/provider.js +5 -2
  33. package/dist/provider.js.map +1 -1
  34. package/dist/sharing/SharePrimitives.d.ts +42 -0
  35. package/dist/sharing/SharePrimitives.d.ts.map +1 -0
  36. package/dist/sharing/SharePrimitives.js +53 -0
  37. package/dist/sharing/SharePrimitives.js.map +1 -0
  38. package/dist/sharing/index.d.ts +1 -0
  39. package/dist/sharing/index.d.ts.map +1 -1
  40. package/dist/sharing/index.js +1 -0
  41. package/dist/sharing/index.js.map +1 -1
  42. package/package.json +15 -1
  43. package/src/chat-history.css +3 -1
  44. package/src/composer/PromptComposer.tsx +13 -0
  45. package/src/composer/TiptapComposer.tsx +107 -1
  46. package/src/data-grid/DataGrid.spec.tsx +243 -0
  47. package/src/data-grid/DataGrid.tsx +754 -0
  48. package/src/data-grid/index.ts +15 -0
  49. package/src/design-system/default-adapter.spec.tsx +15 -0
  50. package/src/design-system/default-adapter.tsx +5 -1
  51. package/src/design-system/types.ts +2 -0
  52. package/src/provider.tsx +9 -1
  53. package/src/sharing/SharePrimitives.tsx +224 -0
  54. package/src/sharing/index.ts +12 -0
@@ -0,0 +1,15 @@
1
+ export {
2
+ DataGrid,
3
+ clampDataGridColumnWidth,
4
+ dataGridColumnTemplate,
5
+ type DataGridActiveCell,
6
+ type DataGridCellContext,
7
+ type DataGridColumn,
8
+ type DataGridCommitContext,
9
+ type DataGridDirection,
10
+ type DataGridEditorContext,
11
+ type DataGridProps,
12
+ type DataGridRowContext,
13
+ type DataGridSelectionMode,
14
+ type DataGridSlotContext,
15
+ } from "./DataGrid.js";
@@ -43,6 +43,21 @@ function renderComponent(
43
43
  }
44
44
 
45
45
  describe("default design system adapter", () => {
46
+ it("preserves native click handlers for composed ActionButtons", () => {
47
+ const onPress = vi.fn();
48
+ const onClick = vi.fn();
49
+ const button = renderComponent(defaultDesignSystemComponents.ActionButton, {
50
+ children: "Share",
51
+ onPress,
52
+ onClick,
53
+ });
54
+
55
+ (button.props.onClick as ((event: unknown) => void) | undefined)?.({});
56
+
57
+ expect(onPress).toHaveBeenCalledOnce();
58
+ expect(onClick).toHaveBeenCalledOnce();
59
+ });
60
+
46
61
  it("maps visual size and shape props to default styles", () => {
47
62
  const iconButton = renderComponent(
48
63
  defaultDesignSystemComponents.IconButton,
@@ -91,6 +91,7 @@ const DefaultActionButton: DesignSystemComponents["ActionButton"] = ({
91
91
  leadingIcon,
92
92
  trailingIcon,
93
93
  onPress,
94
+ onClick,
94
95
  elementRef,
95
96
  ...props
96
97
  }) => (
@@ -101,7 +102,10 @@ const DefaultActionButton: DesignSystemComponents["ActionButton"] = ({
101
102
  variant={buttonVariant(intent, emphasis)}
102
103
  size={buttonSize(size)}
103
104
  disabled={disabled || pending}
104
- onClick={(event) => onPress?.(event)}
105
+ onClick={(event) => {
106
+ onPress?.(event);
107
+ onClick?.(event);
108
+ }}
105
109
  >
106
110
  {pending ? <DefaultSpinnerPrimitive aria-hidden="true" /> : leadingIcon}
107
111
  {children}
@@ -68,6 +68,8 @@ export interface ActionButtonProps
68
68
  leadingIcon?: ReactNode;
69
69
  trailingIcon?: ReactNode;
70
70
  onPress?: (event?: DesignSystemPressEvent) => void;
71
+ /** Native click interoperability for Radix `asChild` composition. */
72
+ onClick?: (event: ReactMouseEvent<HTMLButtonElement>) => void;
71
73
  elementRef?: Ref<HTMLButtonElement>;
72
74
  }
73
75
 
package/src/provider.tsx CHANGED
@@ -70,6 +70,7 @@ export function ToolkitProvider({
70
70
  leadingIcon,
71
71
  trailingIcon,
72
72
  onPress,
73
+ onClick,
73
74
  elementRef,
74
75
  ...props
75
76
  }: ActionButtonProps) {
@@ -94,7 +95,14 @@ export function ToolkitProvider({
94
95
  size={legacySize}
95
96
  disabled={props.disabled || pending}
96
97
  aria-busy={pending || undefined}
97
- onClick={(event) => onPress?.(event)}
98
+ onClick={(event) => {
99
+ onPress?.(event);
100
+ onClick?.(
101
+ event as Parameters<
102
+ NonNullable<ActionButtonProps["onClick"]>
103
+ >[0],
104
+ );
105
+ }}
98
106
  >
99
107
  {leadingIcon}
100
108
  {children}
@@ -0,0 +1,224 @@
1
+ import { IconChevronDown } from "@tabler/icons-react";
2
+ import { forwardRef, useEffect, useRef, useState, type ReactNode } from "react";
3
+
4
+ import { ActionButton } from "../design-system/components.js";
5
+ import type { ActionButtonProps } from "../design-system/types.js";
6
+ import {
7
+ Collapsible,
8
+ CollapsibleContent,
9
+ CollapsibleTrigger,
10
+ } from "../ui/collapsible.js";
11
+ import { cn } from "../utils.js";
12
+
13
+ export interface ShareTriggerProps extends Pick<
14
+ ActionButtonProps,
15
+ | "aria-label"
16
+ | "aria-expanded"
17
+ | "aria-controls"
18
+ | "className"
19
+ | "disabled"
20
+ | "emphasis"
21
+ | "intent"
22
+ | "onClick"
23
+ | "onPress"
24
+ | "pending"
25
+ | "size"
26
+ | "title"
27
+ > {
28
+ label?: ReactNode;
29
+ }
30
+
31
+ /** The shared text-only trigger for resource sharing surfaces. */
32
+ export const ShareTrigger = forwardRef<HTMLButtonElement, ShareTriggerProps>(
33
+ function ShareTrigger(
34
+ { label = "Share", "aria-label": ariaLabel, title, ...props },
35
+ ref,
36
+ ) {
37
+ return (
38
+ <ActionButton
39
+ type="button"
40
+ emphasis="outline"
41
+ size="compact"
42
+ elementRef={ref}
43
+ aria-label={ariaLabel ?? (typeof label === "string" ? label : "Share")}
44
+ title={title ?? (typeof label === "string" ? label : undefined)}
45
+ {...props}
46
+ >
47
+ {label}
48
+ </ActionButton>
49
+ );
50
+ },
51
+ );
52
+ ShareTrigger.displayName = "ShareTrigger";
53
+
54
+ export interface ShareCopyRowProps {
55
+ value: string;
56
+ label?: ReactNode;
57
+ description?: ReactNode;
58
+ disabled?: boolean;
59
+ className?: string;
60
+ copyLabel?: ReactNode;
61
+ copiedLabel?: ReactNode;
62
+ onCopy: (value: string) => Promise<boolean | void> | boolean | void;
63
+ }
64
+
65
+ /** Compact copy-only row. The underlying URL is deliberately not rendered. */
66
+ export function ShareCopyRow({
67
+ value,
68
+ label,
69
+ description,
70
+ disabled = false,
71
+ className,
72
+ copyLabel = "Copy",
73
+ copiedLabel = "Copied",
74
+ onCopy,
75
+ }: ShareCopyRowProps) {
76
+ const [copied, setCopied] = useState(false);
77
+ const resetTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
78
+
79
+ useEffect(
80
+ () => () => {
81
+ if (resetTimer.current) clearTimeout(resetTimer.current);
82
+ },
83
+ [],
84
+ );
85
+
86
+ const handleCopy = async () => {
87
+ if (disabled) return;
88
+ const result = await onCopy(value);
89
+ if (result === false) return;
90
+ setCopied(true);
91
+ if (resetTimer.current) clearTimeout(resetTimer.current);
92
+ resetTimer.current = setTimeout(() => setCopied(false), 1_400);
93
+ };
94
+
95
+ return (
96
+ <div className={cn("flex items-center justify-between gap-3", className)}>
97
+ <div className="min-w-0">
98
+ {label ? <div className="text-sm font-medium">{label}</div> : null}
99
+ {description ? (
100
+ <div className="text-xs text-muted-foreground">{description}</div>
101
+ ) : null}
102
+ </div>
103
+ <ActionButton
104
+ type="button"
105
+ emphasis="outline"
106
+ size="compact"
107
+ disabled={disabled}
108
+ aria-label={copied ? String(copiedLabel) : String(copyLabel)}
109
+ onPress={() => void handleCopy()}
110
+ className="h-9 shrink-0"
111
+ >
112
+ {copied ? copiedLabel : copyLabel}
113
+ </ActionButton>
114
+ </div>
115
+ );
116
+ }
117
+
118
+ export interface ShareDisclosureSectionProps {
119
+ children: ReactNode;
120
+ label: ReactNode;
121
+ fallbackLabel?: string;
122
+ defaultOpen?: boolean;
123
+ open?: boolean;
124
+ onOpenChange?: (open: boolean) => void;
125
+ className?: string;
126
+ contentClassName?: string;
127
+ }
128
+
129
+ /** Shared expandable boundary for optional share-access details. */
130
+ export function ShareDisclosureSection({
131
+ children,
132
+ label,
133
+ fallbackLabel = "Share details",
134
+ defaultOpen = false,
135
+ open,
136
+ onOpenChange,
137
+ className,
138
+ contentClassName,
139
+ }: ShareDisclosureSectionProps) {
140
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
141
+ const isOpen = open ?? internalOpen;
142
+ const accessibleLabel = typeof label === "string" ? label : fallbackLabel;
143
+ const handleOpenChange = (nextOpen: boolean) => {
144
+ if (open === undefined) setInternalOpen(nextOpen);
145
+ onOpenChange?.(nextOpen);
146
+ };
147
+
148
+ return (
149
+ <Collapsible
150
+ open={isOpen}
151
+ onOpenChange={handleOpenChange}
152
+ className={cn(
153
+ "overflow-hidden rounded-md border border-border",
154
+ className,
155
+ )}
156
+ >
157
+ <CollapsibleTrigger asChild>
158
+ <ShareTrigger
159
+ label={
160
+ <>
161
+ <span className="min-w-0 truncate">{label}</span>
162
+ <IconChevronDown
163
+ aria-hidden="true"
164
+ className={cn(
165
+ "size-4 shrink-0 text-muted-foreground transition-transform",
166
+ isOpen && "rotate-180",
167
+ )}
168
+ />
169
+ </>
170
+ }
171
+ emphasis="ghost"
172
+ size="default"
173
+ aria-label={accessibleLabel}
174
+ title={accessibleLabel}
175
+ aria-expanded={isOpen}
176
+ className="flex min-h-10 w-full items-center justify-between gap-3 px-3 py-2 text-left text-sm font-medium hover:bg-muted/50 focus-visible:ring-inset"
177
+ />
178
+ </CollapsibleTrigger>
179
+ <CollapsibleContent
180
+ className={cn("border-t border-border px-3 py-3", contentClassName)}
181
+ >
182
+ {children}
183
+ </CollapsibleContent>
184
+ </Collapsible>
185
+ );
186
+ }
187
+
188
+ export type ShareAgentsSectionProps = Omit<
189
+ ShareDisclosureSectionProps,
190
+ "label" | "fallbackLabel"
191
+ > & { label?: ReactNode };
192
+
193
+ /** Shared expandable boundary for agent-readable sharing details. */
194
+ export function ShareAgentsSection({
195
+ label = "Share with agents",
196
+ ...props
197
+ }: ShareAgentsSectionProps) {
198
+ return (
199
+ <ShareDisclosureSection
200
+ {...props}
201
+ label={label}
202
+ fallbackLabel="Share with agents"
203
+ />
204
+ );
205
+ }
206
+
207
+ export type SharePeopleSectionProps = Omit<
208
+ ShareDisclosureSectionProps,
209
+ "label" | "fallbackLabel"
210
+ > & { label?: ReactNode };
211
+
212
+ /** Shared expandable boundary for individual people access. */
213
+ export function SharePeopleSection({
214
+ label = "People with access",
215
+ ...props
216
+ }: SharePeopleSectionProps) {
217
+ return (
218
+ <ShareDisclosureSection
219
+ {...props}
220
+ label={label}
221
+ fallbackLabel="People with access"
222
+ />
223
+ );
224
+ }
@@ -1,3 +1,15 @@
1
+ export {
2
+ ShareAgentsSection,
3
+ type ShareAgentsSectionProps,
4
+ ShareCopyRow,
5
+ type ShareCopyRowProps,
6
+ ShareDisclosureSection,
7
+ type ShareDisclosureSectionProps,
8
+ SharePeopleSection,
9
+ type SharePeopleSectionProps,
10
+ ShareTrigger,
11
+ type ShareTriggerProps,
12
+ } from "./SharePrimitives.js";
1
13
  export {
2
14
  VisibilityBadge,
3
15
  type VisibilityBadgeProps,