ionbase-ui 0.59.0 → 0.69.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 (102) hide show
  1. package/dist/components/AgentActivity.d.ts +2 -1
  2. package/dist/components/AgentActivity.d.ts.map +1 -1
  3. package/dist/components/AgentActivity.js +4 -17
  4. package/dist/components/AgentActivity.js.map +1 -1
  5. package/dist/components/Calendar.d.ts +20 -0
  6. package/dist/components/Calendar.d.ts.map +1 -0
  7. package/dist/components/Calendar.js +151 -0
  8. package/dist/components/Calendar.js.map +1 -0
  9. package/dist/components/CalendarPopover.d.ts +26 -0
  10. package/dist/components/CalendarPopover.d.ts.map +1 -0
  11. package/dist/components/CalendarPopover.js +45 -0
  12. package/dist/components/CalendarPopover.js.map +1 -0
  13. package/dist/components/DateField.d.ts +15 -0
  14. package/dist/components/DateField.d.ts.map +1 -0
  15. package/dist/components/DateField.js +74 -0
  16. package/dist/components/DateField.js.map +1 -0
  17. package/dist/components/DatePicker.d.ts +81 -0
  18. package/dist/components/DatePicker.d.ts.map +1 -0
  19. package/dist/components/DatePicker.js +102 -0
  20. package/dist/components/DatePicker.js.map +1 -0
  21. package/dist/components/DateRangePicker.d.ts +117 -0
  22. package/dist/components/DateRangePicker.d.ts.map +1 -0
  23. package/dist/components/DateRangePicker.js +152 -0
  24. package/dist/components/DateRangePicker.js.map +1 -0
  25. package/dist/components/Header.d.ts +10 -0
  26. package/dist/components/Header.d.ts.map +1 -1
  27. package/dist/components/Header.js +18 -3
  28. package/dist/components/Header.js.map +1 -1
  29. package/dist/components/NumberInput.d.ts +63 -0
  30. package/dist/components/NumberInput.d.ts.map +1 -0
  31. package/dist/components/NumberInput.js +102 -0
  32. package/dist/components/NumberInput.js.map +1 -0
  33. package/dist/components/PromptInput.d.ts +89 -0
  34. package/dist/components/PromptInput.d.ts.map +1 -0
  35. package/dist/components/PromptInput.js +130 -0
  36. package/dist/components/PromptInput.js.map +1 -0
  37. package/dist/components/SegmentedControl.d.ts +63 -0
  38. package/dist/components/SegmentedControl.d.ts.map +1 -0
  39. package/dist/components/SegmentedControl.js +79 -0
  40. package/dist/components/SegmentedControl.js.map +1 -0
  41. package/dist/components/Sidebar.d.ts +109 -0
  42. package/dist/components/Sidebar.d.ts.map +1 -0
  43. package/dist/components/Sidebar.js +106 -0
  44. package/dist/components/Sidebar.js.map +1 -0
  45. package/dist/components/Stepper.d.ts +73 -0
  46. package/dist/components/Stepper.d.ts.map +1 -0
  47. package/dist/components/Stepper.js +82 -0
  48. package/dist/components/Stepper.js.map +1 -0
  49. package/dist/components/ToolCall.d.ts +66 -0
  50. package/dist/components/ToolCall.d.ts.map +1 -0
  51. package/dist/components/ToolCall.js +78 -0
  52. package/dist/components/ToolCall.js.map +1 -0
  53. package/dist/components/agent-status.d.ts +14 -0
  54. package/dist/components/agent-status.d.ts.map +1 -0
  55. package/dist/components/agent-status.js +16 -0
  56. package/dist/components/agent-status.js.map +1 -0
  57. package/dist/components/index.d.ts +17 -0
  58. package/dist/components/index.d.ts.map +1 -1
  59. package/dist/components/index.js +8 -0
  60. package/dist/components/index.js.map +1 -1
  61. package/dist/components/iso-date.d.ts +53 -0
  62. package/dist/components/iso-date.d.ts.map +1 -0
  63. package/dist/components/iso-date.js +102 -0
  64. package/dist/components/iso-date.js.map +1 -0
  65. package/dist/figma-descriptions.json +107 -52
  66. package/dist/figma-map.json +735 -2
  67. package/dist/meta/AgentActivityStep.json +2 -2
  68. package/dist/meta/DatePicker.json +270 -0
  69. package/dist/meta/DateRangePicker.json +284 -0
  70. package/dist/meta/Header.json +32 -2
  71. package/dist/meta/NumberInput.json +407 -0
  72. package/dist/meta/PromptInput.json +212 -0
  73. package/dist/meta/SegmentedControl.json +217 -0
  74. package/dist/meta/SegmentedControlItem.json +122 -0
  75. package/dist/meta/Sidebar.json +150 -0
  76. package/dist/meta/SidebarItem.json +184 -0
  77. package/dist/meta/SidebarSection.json +131 -0
  78. package/dist/meta/Stepper.json +135 -0
  79. package/dist/meta/StepperStep.json +148 -0
  80. package/dist/meta/Tabs.json +5 -0
  81. package/dist/meta/ToolCall.json +192 -0
  82. package/dist/meta/components.json +5784 -3297
  83. package/dist/meta/contrast.json +7776 -2478
  84. package/dist/meta/index.json +139 -2
  85. package/dist/meta/patterns/AgentRun.json +27 -0
  86. package/dist/meta/patterns/Form.json +9 -0
  87. package/dist/meta/patterns/PageShell.json +43 -3
  88. package/dist/meta/patterns/Wizard.json +20 -1
  89. package/dist/meta/patterns/index.json +10 -1
  90. package/dist/styles/date-picker.css +420 -0
  91. package/dist/styles/date-range-picker.css +280 -0
  92. package/dist/styles/header.css +26 -0
  93. package/dist/styles/index.css +15 -0
  94. package/dist/styles/number-input.css +83 -0
  95. package/dist/styles/prompt-input.css +127 -0
  96. package/dist/styles/segmented-control.css +182 -0
  97. package/dist/styles/sidebar.css +307 -0
  98. package/dist/styles/stepper.css +250 -0
  99. package/dist/styles/tool-call.css +202 -0
  100. package/llms.txt +2 -2
  101. package/package.json +20 -19
  102. package/LICENSE +0 -21
@@ -0,0 +1,131 @@
1
+ {
2
+ "name": "SidebarSection",
3
+ "source": "src/components/Sidebar.tsx",
4
+ "propsType": "SidebarSectionProps",
5
+ "import": "import { SidebarSection } from 'ionbase-ui';",
6
+ "status": "stable",
7
+ "summary": "A group of sidebar items under an optional title, which can fold away and carry its own actions.",
8
+ "useWhen": [
9
+ "inside a Sidebar, once per group — the untitled top group, then Favorites, Spaces"
10
+ ],
11
+ "useInstead": [
12
+ {
13
+ "when": "the grouping is one item and its children",
14
+ "use": "SidebarItem",
15
+ "why": "an item with nested items already expands; a section per parent doubles the structure"
16
+ }
17
+ ],
18
+ "slots": {
19
+ "children": {
20
+ "accepts": "SidebarItem",
21
+ "note": "items only — the section renders a list"
22
+ },
23
+ "actions": {
24
+ "accepts": "Button",
25
+ "note": "beside the title — a + to create in this group. Icon-only buttons need aria-label"
26
+ }
27
+ },
28
+ "a11y": {
29
+ "guarantees": [
30
+ "a titled section's list is named by its title, so a screen reader announces \"Spaces, list, 4 items\"",
31
+ "a collapsible title is a button with aria-expanded and aria-controls; the folded list is hidden, not unmounted"
32
+ ]
33
+ },
34
+ "antiPatterns": [
35
+ {
36
+ "dont": "isCollapsible with no title",
37
+ "why": "there is nothing to press; the prop is ignored"
38
+ },
39
+ {
40
+ "dont": "collapsing the section that holds the current page by default",
41
+ "why": "the user's location is hidden on arrival — leave it open, or open it when the page is inside"
42
+ }
43
+ ],
44
+ "stylesheet": "src/styles/sidebar.css",
45
+ "tokens": [
46
+ "--border-focus",
47
+ "--border-subtle",
48
+ "--border-width-default",
49
+ "--border-width-thick",
50
+ "--font-family-sans",
51
+ "--font-weight-medium",
52
+ "--icon-disabled",
53
+ "--icon-primary",
54
+ "--icon-secondary",
55
+ "--icon-size-sm",
56
+ "--icon-tertiary",
57
+ "--ion-duration-base",
58
+ "--ion-ease-out",
59
+ "--radius-md",
60
+ "--radius-sm",
61
+ "--radius-xs",
62
+ "--spacing-12",
63
+ "--spacing-16",
64
+ "--spacing-2",
65
+ "--spacing-24",
66
+ "--spacing-32",
67
+ "--spacing-4",
68
+ "--spacing-8",
69
+ "--surface-default",
70
+ "--surface-hover",
71
+ "--surface-selected",
72
+ "--surface-selected-hover",
73
+ "--text-default",
74
+ "--text-disabled",
75
+ "--text-secondary",
76
+ "--text-tertiary",
77
+ "--type-body-sm",
78
+ "--type-body-sm-line-height",
79
+ "--type-caption",
80
+ "--type-caption-line-height"
81
+ ],
82
+ "props": {
83
+ "title": {
84
+ "type": "string | undefined",
85
+ "required": false,
86
+ "origin": "own",
87
+ "description": "The group's name — \"Spaces\", \"Favorites\". Omit for the top group."
88
+ },
89
+ "isCollapsible": {
90
+ "type": "boolean | undefined",
91
+ "required": false,
92
+ "origin": "own",
93
+ "description": "Lets the title fold the section away. Needs a `title`."
94
+ },
95
+ "defaultExpanded": {
96
+ "type": "boolean | undefined",
97
+ "required": false,
98
+ "origin": "own",
99
+ "description": "Uncontrolled: whether a collapsible section starts open."
100
+ },
101
+ "isExpanded": {
102
+ "type": "boolean | undefined",
103
+ "required": false,
104
+ "origin": "own",
105
+ "description": "Controlled: whether a collapsible section is open."
106
+ },
107
+ "onExpandedChange": {
108
+ "type": "((isExpanded: boolean) => void) | undefined",
109
+ "required": false,
110
+ "origin": "own"
111
+ },
112
+ "actions": {
113
+ "type": "React.ReactNode",
114
+ "required": false,
115
+ "origin": "own",
116
+ "description": "Controls beside the title — a `+` Button to create a space. Icon-only\nbuttons need their own `aria-label`."
117
+ },
118
+ "children": {
119
+ "type": "React.ReactNode",
120
+ "required": false,
121
+ "origin": "own",
122
+ "description": "`SidebarItem`s only — the section renders a list."
123
+ }
124
+ },
125
+ "propCounts": {
126
+ "own": 7,
127
+ "aria": 0,
128
+ "dom": 276,
129
+ "other": 0
130
+ }
131
+ }
@@ -0,0 +1,135 @@
1
+ {
2
+ "name": "Stepper",
3
+ "source": "src/components/Stepper.tsx",
4
+ "propsType": "StepperProps",
5
+ "description": "Stepper — where the user is in a task that has an order.\n\nWHY NOT TABS\n\nThe `tablist` role announces peers that can be visited in any order, which is\nthe opposite of a wizard. This is an ordered list: the steps are a sequence,\nand `ol` says so. Nothing here is a tab, and arrow keys do nothing.\n\nPOSITION AND STATUS ARE TEXT, NOT ONLY DRAWING\n\nEvery step renders \"Step 2 of 5\" and its status as visually hidden text. The\nnumber in the circle is for the eye; a screen reader cannot be relied on to\nannounce list position, and a coloured ring carries nothing in forced-colours\nmode. The complete and error glyphs also differ in SHAPE — a check and an\nexclamation — so the states survive greyscale, which WCAG 1.4.1 requires.\n\nONLY VISITED STEPS ARE LINKS\n\n`href` / `onPress` are honoured on `complete` and `error` steps that are not\ncurrent. An `incomplete` step renders as text even when given one, because\njumping forward past unanswered steps is exactly what a wizard exists to\nprevent — and a link that is there but should not be followed is worse than\nno link. The current step is text for the same reason Breadcrumb's is: a link\nto where you already are is a dead control.\n\nIT DOES NOT ANNOUNCE STEP CHANGES\n\nThe Wizard pattern moves focus to the new step's heading, which announces it.\nA live region here as well would say the same thing twice, on every step.",
6
+ "import": "import { Stepper } from 'ionbase-ui';",
7
+ "status": "stable",
8
+ "summary": "Where the user is in a task that has an order. An ordered list of steps, each stating its position and status in text.",
9
+ "useWhen": [
10
+ "a Wizard — later steps depend on earlier answers and the user needs to see what is left",
11
+ "a multi-page flow such as checkout or onboarding, where the steps are fixed and known in advance"
12
+ ],
13
+ "useInstead": [
14
+ {
15
+ "when": "the sections can be visited in any order",
16
+ "use": "Tabs",
17
+ "why": "tabs promise peers; a stepper promises a sequence, and using one for the other misleads in both directions"
18
+ },
19
+ {
20
+ "when": "the progress is a quantity with no named stages — an upload, an import",
21
+ "use": "ProgressBar",
22
+ "why": "a stepper with no meaningful step names is a progress bar drawn in circles"
23
+ },
24
+ {
25
+ "when": "the steps are an agent's actions rather than the user's",
26
+ "use": "AgentActivity",
27
+ "why": "the user is not moving through those steps; they are supervising them"
28
+ }
29
+ ],
30
+ "variants": {
31
+ "orientation": {
32
+ "horizontal": {
33
+ "use": "the default — a header above the step's form. Below 40rem it keeps only the current label visible"
34
+ },
35
+ "vertical": {
36
+ "use": "a side rail beside the form, or when step names or descriptions are long"
37
+ }
38
+ }
39
+ },
40
+ "slots": {
41
+ "children": {
42
+ "accepts": "StepperStep",
43
+ "note": "first step first, and exactly one with isCurrent"
44
+ }
45
+ },
46
+ "a11y": {
47
+ "requires": [
48
+ "`label` naming the task when a page carries more than one stepper — it defaults to \"Progress\""
49
+ ],
50
+ "guarantees": [
51
+ "every step renders \"Step N of M\" and its status as visually hidden text, derived from the children rather than passed in",
52
+ "the current step carries aria-current=\"step\"",
53
+ "connectors are CSS and never enter the accessibility tree"
54
+ ],
55
+ "notes": [
56
+ "it does not announce step changes. The Wizard pattern moves focus to the new step's heading, which announces it; a live region here would say it twice"
57
+ ]
58
+ },
59
+ "antiPatterns": [
60
+ {
61
+ "dont": "<Tabs> as a wizard's step indicator",
62
+ "do": "<Stepper>",
63
+ "why": "the tablist role announces peers that can be visited in any order, which is the opposite of a wizard"
64
+ },
65
+ {
66
+ "dont": "more than about seven steps",
67
+ "why": "a stepper that has to scroll or wrap no longer shows what is left, which is the only thing it is for — group the steps instead"
68
+ }
69
+ ],
70
+ "stylesheet": "src/styles/stepper.css",
71
+ "tokens": [
72
+ "--border-default",
73
+ "--border-error",
74
+ "--border-focus",
75
+ "--border-primary",
76
+ "--border-strong",
77
+ "--border-width-thick",
78
+ "--border-width-thicker",
79
+ "--font-family-sans",
80
+ "--font-weight-medium",
81
+ "--font-weight-semibold",
82
+ "--icon-error",
83
+ "--icon-primary",
84
+ "--icon-size-lg",
85
+ "--icon-size-sm",
86
+ "--radius-full",
87
+ "--radius-xs",
88
+ "--spacing-16",
89
+ "--spacing-2",
90
+ "--spacing-24",
91
+ "--spacing-4",
92
+ "--spacing-8",
93
+ "--surface-error",
94
+ "--surface-primary",
95
+ "--text-default",
96
+ "--text-error",
97
+ "--text-on-color",
98
+ "--text-secondary",
99
+ "--text-tertiary",
100
+ "--type-body-sm",
101
+ "--type-body-sm-line-height",
102
+ "--type-caption",
103
+ "--type-caption-line-height"
104
+ ],
105
+ "props": {
106
+ "label": {
107
+ "type": "string | undefined",
108
+ "required": false,
109
+ "origin": "own",
110
+ "description": "Names the list. Defaults to \"Progress\"; give it the task's name when a page\ncarries more than one — \"Checkout progress\"."
111
+ },
112
+ "orientation": {
113
+ "type": "StepperOrientation | undefined",
114
+ "required": false,
115
+ "origin": "own",
116
+ "description": "`horizontal` for a page-width header above the form, `vertical` for a side\nrail. Below 40rem a horizontal stepper hides every label but the current\none, so it does not need a second variant for mobile.",
117
+ "values": [
118
+ "horizontal",
119
+ "vertical"
120
+ ]
121
+ },
122
+ "children": {
123
+ "type": "React.ReactNode",
124
+ "required": false,
125
+ "origin": "own",
126
+ "description": "`StepperStep` elements, first step first."
127
+ }
128
+ },
129
+ "propCounts": {
130
+ "own": 3,
131
+ "aria": 0,
132
+ "dom": 277,
133
+ "other": 0
134
+ }
135
+ }
@@ -0,0 +1,148 @@
1
+ {
2
+ "name": "StepperStep",
3
+ "source": "src/components/Stepper.tsx",
4
+ "propsType": "StepperStepProps",
5
+ "import": "import { StepperStep } from 'ionbase-ui';",
6
+ "status": "stable",
7
+ "summary": "One step in a Stepper: a numbered indicator, a name, and a status carried by shape and text as well as colour.",
8
+ "useWhen": [
9
+ "inside a Stepper, once per step"
10
+ ],
11
+ "useInstead": [
12
+ {
13
+ "when": "it is a step an agent is running",
14
+ "use": "AgentActivityStep"
15
+ }
16
+ ],
17
+ "variants": {
18
+ "status": {
19
+ "incomplete": {
20
+ "use": "the default — not yet answered. Never a link, even with href"
21
+ },
22
+ "complete": {
23
+ "use": "answers accepted by the server, not merely filled in"
24
+ },
25
+ "error": {
26
+ "use": "the step's answers were rejected. Put the reason on the step's fields, not here"
27
+ }
28
+ }
29
+ },
30
+ "slots": {
31
+ "children": {
32
+ "accepts": "text",
33
+ "note": "the step's name, short — \"Shipping\", not \"Enter your shipping details\""
34
+ },
35
+ "description": {
36
+ "accepts": "text",
37
+ "note": "what the step asks for, or a summary of the answer once complete"
38
+ }
39
+ },
40
+ "a11y": {
41
+ "guarantees": [
42
+ "the current step and incomplete steps render as text, never as links, whatever href or onPress say",
43
+ "complete and error use different glyphs — a check and an exclamation — so status survives greyscale and forced-colours mode"
44
+ ],
45
+ "notes": [
46
+ "status and isCurrent are separate on purpose: a user who goes Back to step 1 is on a step that is both current and complete"
47
+ ]
48
+ },
49
+ "antiPatterns": [
50
+ {
51
+ "dont": "status=\"complete\" as soon as the fields are filled",
52
+ "do": "mark it complete when the server accepts the step",
53
+ "why": "a green check on answers that are later rejected sends the user back through a step they were told was finished"
54
+ },
55
+ {
56
+ "dont": "href on every step so users can jump ahead",
57
+ "why": "incomplete steps ignore it; skipping unanswered steps is what a wizard exists to prevent"
58
+ },
59
+ {
60
+ "dont": "using it outside Stepper",
61
+ "why": "it renders an <li> and reads its position from the Stepper, and throws without one"
62
+ }
63
+ ],
64
+ "stylesheet": "src/styles/stepper.css",
65
+ "tokens": [
66
+ "--border-default",
67
+ "--border-error",
68
+ "--border-focus",
69
+ "--border-primary",
70
+ "--border-strong",
71
+ "--border-width-thick",
72
+ "--border-width-thicker",
73
+ "--font-family-sans",
74
+ "--font-weight-medium",
75
+ "--font-weight-semibold",
76
+ "--icon-error",
77
+ "--icon-primary",
78
+ "--icon-size-lg",
79
+ "--icon-size-sm",
80
+ "--radius-full",
81
+ "--radius-xs",
82
+ "--spacing-16",
83
+ "--spacing-2",
84
+ "--spacing-24",
85
+ "--spacing-4",
86
+ "--spacing-8",
87
+ "--surface-error",
88
+ "--surface-primary",
89
+ "--text-default",
90
+ "--text-error",
91
+ "--text-on-color",
92
+ "--text-secondary",
93
+ "--text-tertiary",
94
+ "--type-body-sm",
95
+ "--type-body-sm-line-height",
96
+ "--type-caption",
97
+ "--type-caption-line-height"
98
+ ],
99
+ "props": {
100
+ "children": {
101
+ "type": "React.ReactNode",
102
+ "required": false,
103
+ "origin": "own",
104
+ "description": "The step's name, in the user's language."
105
+ },
106
+ "description": {
107
+ "type": "React.ReactNode",
108
+ "required": false,
109
+ "origin": "own",
110
+ "description": "A short second line — what the step asks for, or a summary of the answer."
111
+ },
112
+ "status": {
113
+ "type": "StepperStepStatus | undefined",
114
+ "required": false,
115
+ "origin": "own",
116
+ "description": "Whether the step's answers have been accepted. Orthogonal to `isCurrent`:\na user who goes Back to step 1 is on a step that is both current and\ncomplete.",
117
+ "values": [
118
+ "error",
119
+ "incomplete",
120
+ "complete"
121
+ ]
122
+ },
123
+ "isCurrent": {
124
+ "type": "boolean | undefined",
125
+ "required": false,
126
+ "origin": "own",
127
+ "description": "The step the user is on. Marked `aria-current=\"step\"`."
128
+ },
129
+ "href": {
130
+ "type": "string | undefined",
131
+ "required": false,
132
+ "origin": "own",
133
+ "description": "Makes a visited step a link back to it. Ignored on the current step and on\n`incomplete` steps — see the component's comment for why."
134
+ },
135
+ "onPress": {
136
+ "type": "(() => void) | undefined",
137
+ "required": false,
138
+ "origin": "own",
139
+ "description": "As `href`, for a wizard that changes step without a route."
140
+ }
141
+ },
142
+ "propCounts": {
143
+ "own": 6,
144
+ "aria": 0,
145
+ "dom": 277,
146
+ "other": 0
147
+ }
148
+ }
@@ -20,6 +20,11 @@
20
20
  "use": "Divider",
21
21
  "why": "tabs hide everything but the active panel, including from Ctrl-F"
22
22
  },
23
+ {
24
+ "when": "the options set a value — a view mode, a range, a unit — and no panel belongs to each",
25
+ "use": "SegmentedControl",
26
+ "why": "it looks like the pill type and is a radiogroup: a tab with no panel announces a relationship that does not exist"
27
+ },
23
28
  {
24
29
  "when": "it is navigation between pages rather than panels within one",
25
30
  "use": "NavItem"
@@ -0,0 +1,192 @@
1
+ {
2
+ "name": "ToolCall",
3
+ "source": "src/components/ToolCall.tsx",
4
+ "propsType": "ToolCallProps",
5
+ "description": "ToolCall — the evidence behind one step of an agent run.\n\nAgentActivityStep says what the agent did in the user's language. ToolCall\nis where the person checking that account goes next: which tool, with what\narguments, and what came back. The title is still plain language and still\nrequired, so the technical detail supplements the account rather than\nreplacing it.\n\nCOLLAPSED BY DEFAULT, EXCEPT THE FAILURE\n\nA run makes dozens of calls, and a thread of expanded JSON is unreadable.\nBut `errorMessage` renders outside the disclosure: evidence that takes a\nclick to reach is evidence nobody reads, and a failure is the one thing in\nthe call a reader must not miss.\n\nTHE DETAILS ARE UNMOUNTED WHEN CLOSED — unlike Accordion, deliberately.\nAccordion keeps collapsed panels for the form state inside them; a tool call\nholds no user state, and its payloads can be megabytes of JSON multiplied by\nevery call in the thread.\n\nA CALL WITH NOTHING TO SHOW IS NOT A BUTTON. With no input and no output the\nheader renders as text: a disclosure that discloses nothing announces as\nexpandable and does nothing.\n\nTHE PAYLOADS ARE FOCUSABLE. Each is a scroll container capped in height, and\na scroll container a keyboard user cannot focus is one they cannot scroll.\n\nIt does not announce status changes. AgentActivity owns the run's live\nregion; a second one here would talk over it.",
6
+ "import": "import { ToolCall } from 'ionbase-ui';",
7
+ "status": "stable",
8
+ "summary": "The evidence behind one step of an agent run: which tool, with what input, and what came back — collapsed by default, with any failure shown without a click.",
9
+ "useWhen": [
10
+ "a person may need to check how an agent reached a result — which search it ran, which record it wrote",
11
+ "beneath or beside an AgentActivityStep, for the steps that called a tool",
12
+ "debugging or audit views where the arguments matter as much as the outcome"
13
+ ],
14
+ "useInstead": [
15
+ {
16
+ "when": "the reader needs to know what the agent did, not how",
17
+ "use": "AgentActivityStep",
18
+ "why": "the plain-language log is the account; ToolCall is the evidence for it, and a thread of tool calls alone is a log nobody but an engineer can read"
19
+ },
20
+ {
21
+ "when": "the call has not happened yet and needs permission",
22
+ "use": "ApprovalGate",
23
+ "why": "ToolCall reports a call; it does not ask whether to make one"
24
+ }
25
+ ],
26
+ "variants": {
27
+ "status": {
28
+ "pending": {
29
+ "use": "the default — queued, not started"
30
+ },
31
+ "active": {
32
+ "use": "running now"
33
+ },
34
+ "done": {
35
+ "use": "returned successfully"
36
+ },
37
+ "failed": {
38
+ "use": "errored. Pass `errorMessage`, which shows without expanding"
39
+ },
40
+ "skipped": {
41
+ "use": "not run — rejected at an ApprovalGate, or a cached result was used"
42
+ }
43
+ }
44
+ },
45
+ "slots": {
46
+ "errorMessage": {
47
+ "accepts": "text",
48
+ "note": "what went wrong, in words — not a stack trace"
49
+ }
50
+ },
51
+ "a11y": {
52
+ "guarantees": [
53
+ "the header is a disclosure button with aria-expanded; with no input and no output it is plain text instead, because a disclosure that discloses nothing is a dead control",
54
+ "status is rendered as visually hidden text inside the header, and the glyph differs in shape per status",
55
+ "each payload is a focusable, named scroll region, so a keyboard user can scroll a capped payload",
56
+ "errorMessage renders outside the disclosure, so a failure is never hidden behind a click"
57
+ ],
58
+ "notes": [
59
+ "it does not announce status changes — AgentActivity owns the run's live region, and a second one would talk over it",
60
+ "the details unmount when collapsed, unlike Accordion: a tool call holds no user state and payloads can be large"
61
+ ]
62
+ },
63
+ "antiPatterns": [
64
+ {
65
+ "dont": "title=\"search_invoices\"",
66
+ "do": "title=\"Searched the invoice archive\" name=\"search_invoices\"",
67
+ "why": "the function name describes the implementation; the title is what tells a reader whether the step was the right one"
68
+ },
69
+ {
70
+ "dont": "passing input or output with credentials, tokens or personal data still in it",
71
+ "why": "it renders exactly what it is given, to anyone who can see the thread"
72
+ },
73
+ {
74
+ "dont": "defaultExpanded on every call in a run",
75
+ "why": "a thread of open JSON buries the answer; open the one the reader is likely to check, or none"
76
+ },
77
+ {
78
+ "dont": "status=\"failed\" with no errorMessage",
79
+ "why": "a failure the reader cannot diagnose is just a red mark"
80
+ }
81
+ ],
82
+ "stylesheet": "src/styles/tool-call.css",
83
+ "tokens": [
84
+ "--border-error-subtle",
85
+ "--border-focus",
86
+ "--border-subtle",
87
+ "--border-width-default",
88
+ "--border-width-thick",
89
+ "--font-family-mono",
90
+ "--font-family-sans",
91
+ "--font-weight-medium",
92
+ "--icon-error",
93
+ "--icon-primary",
94
+ "--icon-secondary",
95
+ "--icon-size-sm",
96
+ "--icon-success",
97
+ "--icon-tertiary",
98
+ "--ion-duration-base",
99
+ "--ion-ease-out",
100
+ "--radius-md",
101
+ "--radius-sm",
102
+ "--spacing-12",
103
+ "--spacing-4",
104
+ "--spacing-8",
105
+ "--surface-default",
106
+ "--surface-error-subtle",
107
+ "--surface-hover",
108
+ "--surface-muted",
109
+ "--text-default",
110
+ "--text-error",
111
+ "--text-secondary",
112
+ "--text-tertiary",
113
+ "--type-body-sm",
114
+ "--type-body-sm-line-height",
115
+ "--type-caption",
116
+ "--type-caption-line-height"
117
+ ],
118
+ "props": {
119
+ "title": {
120
+ "type": "string",
121
+ "required": true,
122
+ "origin": "own",
123
+ "description": "What the call did, in the user's language — \"Searched the invoice archive\".\nRequired: the tool's function name is not a description of the work."
124
+ },
125
+ "name": {
126
+ "type": "string | undefined",
127
+ "required": false,
128
+ "origin": "own",
129
+ "description": "The tool's technical name, shown in monospace beside the title."
130
+ },
131
+ "status": {
132
+ "type": "AgentActivityStatus | undefined",
133
+ "required": false,
134
+ "origin": "own",
135
+ "description": "The same vocabulary as AgentActivityStep, so the two never disagree.",
136
+ "values": [
137
+ "pending",
138
+ "active",
139
+ "done",
140
+ "failed",
141
+ "skipped"
142
+ ]
143
+ },
144
+ "input": {
145
+ "type": "unknown",
146
+ "required": false,
147
+ "origin": "own",
148
+ "description": "What the agent passed in. Objects and arrays render as formatted JSON,\nstrings as they are. Redact secrets before passing it — this renders\nexactly what it is given."
149
+ },
150
+ "output": {
151
+ "type": "unknown",
152
+ "required": false,
153
+ "origin": "own",
154
+ "description": "What came back. Rendered as `input` is."
155
+ },
156
+ "errorMessage": {
157
+ "type": "React.ReactNode",
158
+ "required": false,
159
+ "origin": "own",
160
+ "description": "Why a `failed` call failed. Shown under the header whether or not the\ndetails are expanded — a failure that takes a click to read is not read."
161
+ },
162
+ "durationMs": {
163
+ "type": "number | undefined",
164
+ "required": false,
165
+ "origin": "own",
166
+ "description": "How long the call took, in milliseconds."
167
+ },
168
+ "defaultExpanded": {
169
+ "type": "boolean | undefined",
170
+ "required": false,
171
+ "origin": "own",
172
+ "description": "Uncontrolled: whether the details start open."
173
+ },
174
+ "isExpanded": {
175
+ "type": "boolean | undefined",
176
+ "required": false,
177
+ "origin": "own",
178
+ "description": "Controlled: whether the details are open. Pass `onExpandedChange` with it."
179
+ },
180
+ "onExpandedChange": {
181
+ "type": "((isExpanded: boolean) => void) | undefined",
182
+ "required": false,
183
+ "origin": "own"
184
+ }
185
+ },
186
+ "propCounts": {
187
+ "own": 10,
188
+ "aria": 0,
189
+ "dom": 277,
190
+ "other": 0
191
+ }
192
+ }