@common-origin/design-system 2.20.0 → 2.21.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/client.js +844 -344
- package/dist/client.js.map +1 -1
- package/dist/components/atoms/AILabel/AILabel.d.mts +30 -0
- package/dist/components/atoms/AILabel/AILabel.d.ts +30 -0
- package/dist/components/atoms/AILabel/AILabel.mjs +94 -0
- package/dist/components/atoms/AILabel/AILabel.mjs.map +1 -0
- package/dist/components/atoms/AILabel/index.d.mts +1 -0
- package/dist/components/atoms/AILabel/index.d.ts +1 -0
- package/dist/components/atoms/Chip/SuggestionChip.d.mts +24 -0
- package/dist/components/atoms/Chip/SuggestionChip.d.ts +24 -0
- package/dist/components/atoms/Chip/SuggestionChip.mjs +61 -0
- package/dist/components/atoms/Chip/SuggestionChip.mjs.map +1 -0
- package/dist/components/atoms/Chip/index.d.mts +1 -0
- package/dist/components/atoms/Chip/index.d.ts +1 -0
- package/dist/components/atoms/index.d.mts +1 -0
- package/dist/components/atoms/index.d.ts +1 -0
- package/dist/components/molecules/AgentInput/AgentInput.d.mts +63 -1
- package/dist/components/molecules/AgentInput/AgentInput.d.ts +63 -1
- package/dist/components/molecules/AgentInput/AgentInput.mjs +476 -112
- package/dist/components/molecules/AgentInput/agentInputSpeech.d.mts +2 -0
- package/dist/components/molecules/AgentInput/agentInputSpeech.d.ts +2 -0
- package/dist/components/molecules/AgentInput/agentInputSpeech.mjs +5 -1
- package/dist/components/molecules/AgentInput/agentInputSpeech.mjs.map +1 -1
- package/dist/components/molecules/AgentInput/index.d.mts +1 -1
- package/dist/components/molecules/AgentInput/index.d.ts +1 -1
- package/dist/components/molecules/CardLarge/CardLarge.mjs +1 -0
- package/dist/components/molecules/ChipGroup/ChipGroup.mjs +2 -0
- package/dist/components/molecules/FeatureBlock/FeatureBlock.mjs +1 -0
- package/dist/data.js +316 -3
- package/dist/data.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -1
- package/dist/lib/tokenAliases.mjs +1 -0
- package/dist/lib/tokenAliases.mjs.map +1 -1
- package/dist/styles/icons.json +30 -1
- package/dist/styles/icons.json.mjs +33 -2
- package/dist/styles/icons.json.mjs.map +1 -1
- package/dist/styles/tokens.d.mts +545 -1
- package/dist/styles/tokens.d.ts +545 -1
- package/dist/styles/tokens.json +284 -2
- package/dist/styles/tokens.json.mjs +284 -2
- package/dist/styles/tokens.json.mjs.map +1 -1
- package/dist/tokens/index.js +284 -2
- package/dist/tokens/index.js.map +1 -1
- package/dist/tokens/index.mjs +284 -2
- package/dist/tokens/index.mjs.map +1 -1
- package/dist/tokens/styles/tokens.d.mts +545 -1
- package/dist/tokens/styles/tokens.d.ts +545 -1
- package/dist/tokens.css +242 -0
- package/dist/types/icons.d.mts +1 -1
- package/dist/types/icons.d.ts +1 -1
- package/dist/types/icons.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1,106 +1,182 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { __makeTemplateObject, __awaiter, __spreadArray, __generator } from '../../../vendor/tslib/tslib.es6.mjs';
|
|
3
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
-
import { useState, useRef, useId, useCallback,
|
|
3
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
|
+
import { forwardRef, useState, useRef, useId, useEffect, useCallback, useImperativeHandle, useMemo, useLayoutEffect } from 'react';
|
|
5
5
|
import styled$module, { keyframes, css } from 'styled-components';
|
|
6
6
|
const styled = styled$module.default || styled$module;
|
|
7
|
+
import { Button } from '../../atoms/Button/Button.mjs';
|
|
8
|
+
import '../../atoms/Chip/shared/ChipBase.mjs';
|
|
9
|
+
import '../../atoms/Icon/Icon.mjs';
|
|
10
|
+
import { SuggestionChip } from '../../atoms/Chip/SuggestionChip.mjs';
|
|
7
11
|
import { IconButton } from '../../atoms/IconButton/IconButton.mjs';
|
|
8
12
|
import { Typography } from '../../atoms/Typography/Typography.mjs';
|
|
9
|
-
import { visuallyHidden } from '../../../lib/styleUtils.mjs';
|
|
13
|
+
import { reducedMotion, visuallyHidden } from '../../../lib/styleUtils.mjs';
|
|
14
|
+
import { usePresence, EXIT_DURATION_MS, useInert } from '../../../lib/usePresence.mjs';
|
|
10
15
|
import tokens from '../../../lib/cssTokens.mjs';
|
|
11
|
-
import { normalizeTranscript, detectSpeechRecognitionConstructor, defaultVoiceErrorMessage, mapSpeechErrorCode } from './agentInputSpeech.mjs';
|
|
16
|
+
import { normalizeTranscript, normalizeMessage, detectSpeechRecognitionConstructor, defaultVoiceErrorMessage, mapSpeechErrorCode } from './agentInputSpeech.mjs';
|
|
12
17
|
import { agentInputStateTransition } from './agentInputStateMachine.mjs';
|
|
13
18
|
|
|
14
19
|
var semantic = tokens.semantic,
|
|
15
20
|
component = tokens.component;
|
|
16
|
-
var DEFAULT_IDLE_HELPER = 'Ask about transactions, spending, or transfers';
|
|
17
21
|
var DEFAULT_LISTENING_MESSAGE = 'Listening… speak now';
|
|
18
22
|
var DEFAULT_PROCESSING_MESSAGE = 'Finishing voice input…';
|
|
23
|
+
// The counter appears from this share of maxLength
|
|
24
|
+
var COUNTER_THRESHOLD = 0.8;
|
|
25
|
+
// Layout effects warn during server rendering in React 18
|
|
26
|
+
var useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
|
|
19
27
|
var rotateRing = keyframes(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n"], ["\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n"])));
|
|
20
28
|
var Container = /*#__PURE__*/styled.div.withConfig({
|
|
29
|
+
shouldForwardProp: function shouldForwardProp(prop) {
|
|
30
|
+
return !prop.startsWith('$');
|
|
31
|
+
},
|
|
21
32
|
displayName: "AgentInput__Container",
|
|
22
33
|
componentId: "sc-fhl996-0"
|
|
23
|
-
})(
|
|
34
|
+
})(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n display: flex;\n flex-direction: column;\n gap: ", ";\n width: 100%;\n\n ", "\n"], ["\n display: flex;\n flex-direction: column;\n gap: ", ";\n width: 100%;\n\n ", "\n"])), semantic.space[200], function (_a) {
|
|
35
|
+
var $docked = _a.$docked;
|
|
36
|
+
return $docked && css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n position: sticky;\n bottom: 0;\n z-index: ", ";\n /* The band hides content scrolling past the field and status line (decisions 0006, 0031) */\n background-color: ", ";\n padding-top: ", ";\n /* Clears the home indicator; zero unless the page sets viewport-fit=cover */\n padding-bottom: env(safe-area-inset-bottom, 0px);\n "], ["\n position: sticky;\n bottom: 0;\n z-index: ", ";\n /* The band hides content scrolling past the field and status line (decisions 0006, 0031) */\n background-color: ", ";\n padding-top: ", ";\n /* Clears the home indicator; zero unless the page sets viewport-fit=cover */\n padding-bottom: env(safe-area-inset-bottom, 0px);\n "])), semantic.layer.sticky, semantic.surface.base, semantic.space[300]);
|
|
37
|
+
});
|
|
24
38
|
var ControlsRow = /*#__PURE__*/styled.div.withConfig({
|
|
25
39
|
displayName: "AgentInput__ControlsRow",
|
|
26
40
|
componentId: "sc-fhl996-1"
|
|
27
|
-
})(
|
|
41
|
+
})(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n width: 100%;\n"], ["\n width: 100%;\n"])));
|
|
28
42
|
var InputShell = /*#__PURE__*/styled.div.withConfig({
|
|
29
43
|
displayName: "AgentInput__InputShell",
|
|
30
44
|
componentId: "sc-fhl996-2"
|
|
31
|
-
})(
|
|
32
|
-
|
|
45
|
+
})(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n display: flex;\n /* Actions sit beside the last line as the field grows */\n align-items: flex-end;\n gap: ", ";\n width: 100%;\n padding: ", " ", " ", " ", ";\n background-color: ", ";\n border: ", " solid ", ";\n border-radius: ", ";\n box-shadow: ", ";\n transition: border-color ", " ", ", outline ", " ", ";\n\n &:focus-within {\n border-color: ", ";\n outline: ", ";\n outline-offset: ", ";\n }\n\n &[data-disabled='true'] {\n background-color: ", ";\n border-color: ", ";\n }\n"], ["\n display: flex;\n /* Actions sit beside the last line as the field grows */\n align-items: flex-end;\n gap: ", ";\n width: 100%;\n padding: ", " ", " ", " ", ";\n background-color: ", ";\n border: ", " solid ", ";\n border-radius: ", ";\n box-shadow: ", ";\n transition: border-color ", " ", ", outline ", " ", ";\n\n &:focus-within {\n border-color: ", ";\n outline: ", ";\n outline-offset: ", ";\n }\n\n &[data-disabled='true'] {\n background-color: ", ";\n border-color: ", ";\n }\n"
|
|
46
|
+
// One row is a control-height field; it grows with its content to six rows, then scrolls.
|
|
47
|
+
// The height is set from scrollHeight in resizeField; 1lh is the body line height.
|
|
48
|
+
])), semantic.space[200], semantic.space[100], semantic.space[200], semantic.space[100], semantic.space.inset.lg, component.input["default"].backgroundColor, component.input["default"].borderWidth, component.input["default"].borderColor, semantic.radius['3xl'], semantic.elevation.raised, semantic.motion.duration.moderate, semantic.motion.easing.standard, semantic.motion.duration.moderate, semantic.motion.easing.standard, component.input.focus.borderColor, component.input.focus.outline, semantic.border.focusOffset, component.input.disabled.backgroundColor, component.input.disabled.borderColor);
|
|
49
|
+
// One row is a control-height field; it grows with its content to six rows, then scrolls.
|
|
50
|
+
// The height is set from scrollHeight in resizeField; 1lh is the body line height.
|
|
51
|
+
var Input = /*#__PURE__*/styled.textarea.withConfig({
|
|
33
52
|
displayName: "AgentInput__Input",
|
|
34
53
|
componentId: "sc-fhl996-3"
|
|
35
|
-
})(
|
|
54
|
+
})(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n display: block;\n flex: 1;\n min-width: 0;\n box-sizing: border-box;\n height: ", ";\n min-height: ", ";\n max-height: calc(5lh + ", ");\n margin: 0;\n padding: calc((", " - 1lh) / 2) 0;\n resize: none;\n overflow-y: hidden;\n border: none;\n background: transparent;\n font: ", ";\n color: ", ";\n outline: none;\n\n &::placeholder {\n color: ", ";\n /* Firefox fades placeholders to 0.54 by default, which would undo the 4.5:1 contrast */\n opacity: 1;\n }\n\n &:disabled {\n color: ", ";\n cursor: not-allowed;\n }\n"], ["\n display: block;\n flex: 1;\n min-width: 0;\n box-sizing: border-box;\n height: ", ";\n min-height: ", ";\n max-height: calc(5lh + ", ");\n margin: 0;\n padding: calc((", " - 1lh) / 2) 0;\n resize: none;\n overflow-y: hidden;\n border: none;\n background: transparent;\n font: ", ";\n color: ", ";\n outline: none;\n\n &::placeholder {\n color: ", ";\n /* Firefox fades placeholders to 0.54 by default, which would undo the 4.5:1 contrast */\n opacity: 1;\n }\n\n &:disabled {\n color: ", ";\n cursor: not-allowed;\n }\n"])), semantic.size.control.lg, semantic.size.control.lg, semantic.size.control.lg, semantic.size.control.lg, semantic.typography.body, semantic.color.text["default"], component.input.placeholder.textColor, semantic.color.text.disabled);
|
|
36
55
|
var InputActions = /*#__PURE__*/styled.div.withConfig({
|
|
37
56
|
displayName: "AgentInput__InputActions",
|
|
38
57
|
componentId: "sc-fhl996-4"
|
|
39
|
-
})(
|
|
58
|
+
})(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n display: inline-flex;\n align-items: center;\n gap: ", ";\n /* Centres the buttons on a one-row field, and keeps them level with the last line as it grows */\n padding-bottom: calc((", " - ", ") / 2);\n"], ["\n display: inline-flex;\n align-items: center;\n gap: ", ";\n /* Centres the buttons on a one-row field, and keeps them level with the last line as it grows */\n padding-bottom: calc((", " - ", ") / 2);\n"])), semantic.space[200], semantic.size.control.lg, semantic.size.control.md);
|
|
40
59
|
var CircularActionIconButton = /*#__PURE__*/styled(IconButton).withConfig({
|
|
41
60
|
displayName: "AgentInput__CircularActionIconButton",
|
|
42
61
|
componentId: "sc-fhl996-5"
|
|
43
|
-
})(
|
|
62
|
+
})(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n border-radius: ", ";\n"], ["\n border-radius: ", ";\n"])), semantic.radius.full);
|
|
44
63
|
var InputWrapper = /*#__PURE__*/styled.div.withConfig({
|
|
45
64
|
displayName: "AgentInput__InputWrapper",
|
|
46
65
|
componentId: "sc-fhl996-6"
|
|
47
|
-
})(
|
|
66
|
+
})(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n flex: 1;\n min-width: 0;\n"], ["\n flex: 1;\n min-width: 0;\n"])));
|
|
48
67
|
var MicButtonWrapper = /*#__PURE__*/styled.div.withConfig({
|
|
49
68
|
shouldForwardProp: function shouldForwardProp(prop) {
|
|
50
69
|
return !prop.startsWith('$');
|
|
51
70
|
},
|
|
52
71
|
displayName: "AgentInput__MicButtonWrapper",
|
|
53
72
|
componentId: "sc-fhl996-7"
|
|
54
|
-
})(
|
|
73
|
+
})(templateObject_10 || (templateObject_10 = __makeTemplateObject(["\n position: relative;\n display: inline-flex;\n border-radius: ", ";\n\n & > button {\n position: relative;\n z-index: 1;\n }\n"], ["\n position: relative;\n display: inline-flex;\n border-radius: ", ";\n\n & > button {\n position: relative;\n z-index: 1;\n }\n"
|
|
55
74
|
// Masks read only alpha, so the opaque stop is a mask value, not a colour (decision 0010).
|
|
56
75
|
// eslint-disable-next-line no-restricted-syntax
|
|
57
76
|
])), semantic.radius.full);
|
|
58
77
|
// Masks read only alpha, so the opaque stop is a mask value, not a colour (decision 0010).
|
|
59
78
|
// eslint-disable-next-line no-restricted-syntax
|
|
60
|
-
var ringMask = css(
|
|
79
|
+
var ringMask = css(templateObject_11 || (templateObject_11 = __makeTemplateObject(["radial-gradient(farthest-side, transparent calc(100% - var(--ring-thickness)), #000 calc(100% - var(--ring-thickness)))"], ["radial-gradient(farthest-side, transparent calc(100% - var(--ring-thickness)), #000 calc(100% - var(--ring-thickness)))"])));
|
|
61
80
|
var MicListeningRing = /*#__PURE__*/styled.span.withConfig({
|
|
62
81
|
shouldForwardProp: function shouldForwardProp(prop) {
|
|
63
82
|
return !prop.startsWith('$');
|
|
64
83
|
},
|
|
65
84
|
displayName: "AgentInput__MicListeningRing",
|
|
66
85
|
componentId: "sc-fhl996-8"
|
|
67
|
-
})(
|
|
86
|
+
})(templateObject_13 || (templateObject_13 = __makeTemplateObject(["\n --ring-thickness: ", ";\n position: absolute;\n inset: calc(-1 * ", " - ", ");\n border-radius: ", ";\n pointer-events: none;\n z-index: 0;\n background: conic-gradient(\n from 0deg,\n ", " 0deg,\n ", " 110deg,\n ", " 210deg,\n ", " 300deg,\n ", " 360deg\n );\n mask: ", ";\n -webkit-mask: ", ";\n\n ", "\n\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n }\n"], ["\n --ring-thickness: ", ";\n position: absolute;\n inset: calc(-1 * ", " - ", ");\n border-radius: ", ";\n pointer-events: none;\n z-index: 0;\n background: conic-gradient(\n from 0deg,\n ", " 0deg,\n ", " 110deg,\n ", " 210deg,\n ", " 300deg,\n ", " 360deg\n );\n mask: ", ";\n -webkit-mask: ", ";\n\n ", "\n\n @media (prefers-reduced-motion: reduce) {\n animation: none;\n }\n"
|
|
87
|
+
// Maximum suggestions shown (decision 0046, #280)
|
|
88
|
+
])), semantic.border.width.thick, semantic.space[100], semantic.border.focusOffset, semantic.radius.full, semantic.color.fill['accent-muted'], semantic.color.fill.accent, semantic.color.fill['accent-hover'], semantic.color.fill.accent, semantic.color.fill['accent-muted'], ringMask, ringMask, function (_a) {
|
|
68
89
|
var $reducedMotion = _a.$reducedMotion;
|
|
69
|
-
return !$reducedMotion && css(
|
|
90
|
+
return !$reducedMotion && css(templateObject_12 || (templateObject_12 = __makeTemplateObject(["\n animation: ", " 1300ms linear infinite;\n "], ["\n animation: ", " 1300ms linear infinite;\n "])), rotateRing);
|
|
91
|
+
});
|
|
92
|
+
// Maximum suggestions shown (decision 0046, #280)
|
|
93
|
+
var MAX_SUGGESTIONS = 3;
|
|
94
|
+
var regionEnter = keyframes(templateObject_14 || (templateObject_14 = __makeTemplateObject(["\n from {\n opacity: 0;\n transform: translateY(", ");\n }\n"], ["\n from {\n opacity: 0;\n transform: translateY(", ");\n }\n"])), semantic.motion.distance.sm);
|
|
95
|
+
var regionFadeIn = keyframes(templateObject_15 || (templateObject_15 = __makeTemplateObject(["\n from {\n opacity: 0;\n }\n"], ["\n from {\n opacity: 0;\n }\n"
|
|
96
|
+
// Leaving content fades, then its space closes, as with Alert's dismiss (decision 0015). A grid
|
|
97
|
+
// row from 1fr to 0fr collapses to the content's own height without measuring it.
|
|
98
|
+
])));
|
|
99
|
+
// Leaving content fades, then its space closes, as with Alert's dismiss (decision 0015). A grid
|
|
100
|
+
// row from 1fr to 0fr collapses to the content's own height without measuring it.
|
|
101
|
+
var regionFadeThenCollapse = keyframes(templateObject_16 || (templateObject_16 = __makeTemplateObject(["\n 0%, 50% {\n grid-template-rows: 1fr;\n }\n 0% {\n opacity: 1;\n }\n 50%, 100% {\n opacity: 0;\n }\n 100% {\n grid-template-rows: 0fr;\n }\n"], ["\n 0%, 50% {\n grid-template-rows: 1fr;\n }\n 0% {\n opacity: 1;\n }\n 50%, 100% {\n opacity: 0;\n }\n 100% {\n grid-template-rows: 0fr;\n }\n"])));
|
|
102
|
+
var regionFadeOut = keyframes(templateObject_17 || (templateObject_17 = __makeTemplateObject(["\n to {\n opacity: 0;\n }\n"], ["\n to {\n opacity: 0;\n }\n"
|
|
103
|
+
// One part of the region above the field: the review bar or the suggestions
|
|
104
|
+
])));
|
|
105
|
+
// One part of the region above the field: the review bar or the suggestions
|
|
106
|
+
var RegionItem = /*#__PURE__*/styled.div.withConfig({
|
|
107
|
+
shouldForwardProp: function shouldForwardProp(prop) {
|
|
108
|
+
return !prop.startsWith('$');
|
|
109
|
+
},
|
|
110
|
+
displayName: "AgentInput__RegionItem",
|
|
111
|
+
componentId: "sc-fhl996-9"
|
|
112
|
+
})(templateObject_21 || (templateObject_21 = __makeTemplateObject(["\n display: grid;\n grid-template-rows: 1fr;\n animation: ", " ", " ", ";\n\n ", " {\n animation-name: ", ";\n }\n\n ", "\n"], ["\n display: grid;\n grid-template-rows: 1fr;\n animation: ", " ", " ", ";\n\n ", " {\n animation-name: ", ";\n }\n\n ", "\n"
|
|
113
|
+
// Clips while the row collapses. Its bottom padding is the space to the next part, so it closes too.
|
|
114
|
+
])), regionEnter, semantic.motion.duration.moderate, semantic.motion.easing.decelerate, reducedMotion, regionFadeIn, function (_a) {
|
|
115
|
+
var $exiting = _a.$exiting,
|
|
116
|
+
$reducedExit = _a.$reducedExit;
|
|
117
|
+
return $exiting && css(templateObject_20 || (templateObject_20 = __makeTemplateObject(["\n pointer-events: none;\n animation: ", ";\n "], ["\n pointer-events: none;\n animation: ", ";\n "])), $reducedExit ? css(templateObject_18 || (templateObject_18 = __makeTemplateObject(["", " ", " ", " forwards"], ["", " ", " ", " forwards"])), regionFadeOut, semantic.motion.duration.fast, semantic.motion.easing.accelerate) : css(templateObject_19 || (templateObject_19 = __makeTemplateObject(["", " calc(2 * ", ") ", " forwards"], ["", " calc(2 * ", ") ", " forwards"])), regionFadeThenCollapse, semantic.motion.duration.fast, semantic.motion.easing.accelerate));
|
|
70
118
|
});
|
|
119
|
+
// Clips while the row collapses. Its bottom padding is the space to the next part, so it closes too.
|
|
120
|
+
var RegionItemContent = /*#__PURE__*/styled.div.withConfig({
|
|
121
|
+
displayName: "AgentInput__RegionItemContent",
|
|
122
|
+
componentId: "sc-fhl996-10"
|
|
123
|
+
})(templateObject_22 || (templateObject_22 = __makeTemplateObject(["\n min-height: 0;\n overflow: hidden;\n padding-bottom: ", ";\n padding-left: ", ";\n"], ["\n min-height: 0;\n overflow: hidden;\n padding-bottom: ", ";\n padding-left: ", ";\n"
|
|
124
|
+
// The summary first, then the actions, left-aligned after it; they wrap below on narrow screens (0021)
|
|
125
|
+
])), semantic.space[200], semantic.space[500]);
|
|
126
|
+
// The summary first, then the actions, left-aligned after it; they wrap below on narrow screens (0021)
|
|
127
|
+
var ReviewBar = /*#__PURE__*/styled.div.withConfig({
|
|
128
|
+
displayName: "AgentInput__ReviewBar",
|
|
129
|
+
componentId: "sc-fhl996-11"
|
|
130
|
+
})(templateObject_23 || (templateObject_23 = __makeTemplateObject(["\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n column-gap: ", ";\n row-gap: ", ";\n"], ["\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n column-gap: ", ";\n row-gap: ", ";\n"])), semantic.space[300], semantic.space[200]);
|
|
131
|
+
var ReviewActions = /*#__PURE__*/styled.div.withConfig({
|
|
132
|
+
displayName: "AgentInput__ReviewActions",
|
|
133
|
+
componentId: "sc-fhl996-12"
|
|
134
|
+
})(templateObject_24 || (templateObject_24 = __makeTemplateObject(["\n display: flex;\n flex-wrap: wrap;\n gap: ", ";\n"], ["\n display: flex;\n flex-wrap: wrap;\n gap: ", ";\n"])), semantic.space[200]);
|
|
135
|
+
var SuggestionList = /*#__PURE__*/styled.ul.withConfig({
|
|
136
|
+
displayName: "AgentInput__SuggestionList",
|
|
137
|
+
componentId: "sc-fhl996-13"
|
|
138
|
+
})(templateObject_25 || (templateObject_25 = __makeTemplateObject(["\n display: flex;\n flex-wrap: wrap;\n gap: ", ";\n margin: 0;\n padding: 0;\n list-style: none;\n\n & > li {\n max-width: 100%;\n }\n"], ["\n display: flex;\n flex-wrap: wrap;\n gap: ", ";\n margin: 0;\n padding: 0;\n list-style: none;\n\n & > li {\n max-width: 100%;\n }\n"])), semantic.space[200]);
|
|
71
139
|
var StatusRow = /*#__PURE__*/styled.div.withConfig({
|
|
72
140
|
displayName: "AgentInput__StatusRow",
|
|
73
|
-
componentId: "sc-fhl996-
|
|
74
|
-
})(
|
|
141
|
+
componentId: "sc-fhl996-14"
|
|
142
|
+
})(templateObject_26 || (templateObject_26 = __makeTemplateObject(["\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: ", ";\n min-height: ", ";\n"], ["\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: ", ";\n min-height: ", ";\n"])), semantic.space[300], semantic.space[600]);
|
|
75
143
|
var StatusText = /*#__PURE__*/styled.div.withConfig({
|
|
76
144
|
shouldForwardProp: function shouldForwardProp(prop) {
|
|
77
145
|
return !prop.startsWith('$');
|
|
78
146
|
},
|
|
79
147
|
displayName: "AgentInput__StatusText",
|
|
80
|
-
componentId: "sc-fhl996-
|
|
81
|
-
})(
|
|
148
|
+
componentId: "sc-fhl996-15"
|
|
149
|
+
})(templateObject_27 || (templateObject_27 = __makeTemplateObject(["\n padding-left: ", ";\n"], ["\n padding-left: ", ";\n"])), semantic.space[500]);
|
|
82
150
|
var StatusAnnouncement = /*#__PURE__*/styled.div.withConfig({
|
|
83
151
|
displayName: "AgentInput__StatusAnnouncement",
|
|
84
|
-
componentId: "sc-fhl996-
|
|
85
|
-
})(
|
|
152
|
+
componentId: "sc-fhl996-16"
|
|
153
|
+
})(templateObject_28 || (templateObject_28 = __makeTemplateObject([""], [""])));
|
|
154
|
+
var StatusEnd = /*#__PURE__*/styled.div.withConfig({
|
|
155
|
+
displayName: "AgentInput__StatusEnd",
|
|
156
|
+
componentId: "sc-fhl996-17"
|
|
157
|
+
})(templateObject_29 || (templateObject_29 = __makeTemplateObject(["\n display: inline-flex;\n align-items: center;\n gap: ", ";\n"], ["\n display: inline-flex;\n align-items: center;\n gap: ", ";\n"])), semantic.space[300]);
|
|
158
|
+
var VisuallyHidden = /*#__PURE__*/styled.span.withConfig({
|
|
159
|
+
displayName: "AgentInput__VisuallyHidden",
|
|
160
|
+
componentId: "sc-fhl996-18"
|
|
161
|
+
})(templateObject_30 || (templateObject_30 = __makeTemplateObject(["\n ", "\n"], ["\n ", "\n"])), visuallyHidden);
|
|
86
162
|
var MeterContainer = /*#__PURE__*/styled.div.withConfig({
|
|
87
163
|
displayName: "AgentInput__MeterContainer",
|
|
88
|
-
componentId: "sc-fhl996-
|
|
89
|
-
})(
|
|
164
|
+
componentId: "sc-fhl996-19"
|
|
165
|
+
})(templateObject_31 || (templateObject_31 = __makeTemplateObject(["\n display: inline-flex;\n align-items: flex-end;\n gap: ", ";\n height: ", ";\n"], ["\n display: inline-flex;\n align-items: flex-end;\n gap: ", ";\n height: ", ";\n"])), semantic.space[100], semantic.space[400]);
|
|
90
166
|
var MeterBar = /*#__PURE__*/styled.div.withConfig({
|
|
91
167
|
shouldForwardProp: function shouldForwardProp(prop) {
|
|
92
168
|
return !prop.startsWith('$');
|
|
93
169
|
},
|
|
94
170
|
displayName: "AgentInput__MeterBar",
|
|
95
|
-
componentId: "sc-fhl996-
|
|
96
|
-
})(
|
|
171
|
+
componentId: "sc-fhl996-20"
|
|
172
|
+
})(templateObject_32 || (templateObject_32 = __makeTemplateObject(["\n width: ", ";\n border-radius: ", ";\n background-color: ", ";\n height: ", ";\n transition: height ", " ", ";\n"], ["\n width: ", ";\n border-radius: ", ";\n background-color: ", ";\n height: ", ";\n transition: height ", " ", ";\n"])), semantic.space[100], semantic.radius.xs, semantic.color.fill.accent, function (_a) {
|
|
97
173
|
var $height = _a.$height;
|
|
98
174
|
return "".concat($height * 100, "%");
|
|
99
175
|
}, semantic.motion.duration.fast, semantic.motion.easing.decelerate);
|
|
100
176
|
var VisuallyHiddenLabel = /*#__PURE__*/styled.label.withConfig({
|
|
101
177
|
displayName: "AgentInput__VisuallyHiddenLabel",
|
|
102
|
-
componentId: "sc-fhl996-
|
|
103
|
-
})(
|
|
178
|
+
componentId: "sc-fhl996-21"
|
|
179
|
+
})(templateObject_33 || (templateObject_33 = __makeTemplateObject(["\n ", "\n"], ["\n ", "\n"])), visuallyHidden);
|
|
104
180
|
function getInitialState(hasText) {
|
|
105
181
|
return hasText ? 'typing' : 'idle';
|
|
106
182
|
}
|
|
@@ -108,60 +184,104 @@ function createMeterBars(level) {
|
|
|
108
184
|
var clampedLevel = Math.max(0, Math.min(level, 1));
|
|
109
185
|
return [0.25 + clampedLevel * 0.75, 0.2 + clampedLevel * 0.6, 0.3 + clampedLevel * 0.7, 0.2 + clampedLevel * 0.5];
|
|
110
186
|
}
|
|
111
|
-
|
|
187
|
+
// Declared separately so the react-hooks lint rules analyse it (they skip functions inline in forwardRef)
|
|
188
|
+
// Development builds warn about props that break the pattern. Bundlers replace process.env.NODE_ENV
|
|
189
|
+
// with a literal; without a bundler, a browser has no process, so reading it throws.
|
|
190
|
+
function readIsProduction() {
|
|
191
|
+
try {
|
|
192
|
+
return process.env.NODE_ENV === 'production';
|
|
193
|
+
} catch (_a) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
var isProduction = readIsProduction();
|
|
198
|
+
// A part of the region above the field. It stays mounted while it fades out and its space closes.
|
|
199
|
+
function RegionPart(_a) {
|
|
200
|
+
var show = _a.show,
|
|
201
|
+
reducedExit = _a.reducedExit,
|
|
202
|
+
children = _a.children;
|
|
203
|
+
var _b = usePresence(show, reducedExit ? EXIT_DURATION_MS : EXIT_DURATION_MS * 2),
|
|
204
|
+
isPresent = _b.isPresent,
|
|
205
|
+
isExiting = _b.isExiting;
|
|
206
|
+
var ref = useRef(null);
|
|
207
|
+
// Leaving controls drop out of the tab order and can't be activated
|
|
208
|
+
useInert(ref, isExiting);
|
|
209
|
+
if (!isPresent) return null;
|
|
210
|
+
return jsx(RegionItem, {
|
|
211
|
+
ref: ref,
|
|
212
|
+
"$exiting": isExiting,
|
|
213
|
+
"$reducedExit": reducedExit,
|
|
214
|
+
"aria-hidden": isExiting || undefined,
|
|
215
|
+
children: jsx(RegionItemContent, {
|
|
216
|
+
children: children
|
|
217
|
+
})
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
function AgentInputWithRef(_a, ref) {
|
|
221
|
+
var _this = this;
|
|
222
|
+
var _b;
|
|
112
223
|
var value = _a.value,
|
|
113
|
-
|
|
114
|
-
defaultValue =
|
|
224
|
+
_c = _a.defaultValue,
|
|
225
|
+
defaultValue = _c === void 0 ? '' : _c,
|
|
115
226
|
onChange = _a.onChange,
|
|
116
227
|
onSubmit = _a.onSubmit,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
228
|
+
onStop = _a.onStop,
|
|
229
|
+
review = _a.review,
|
|
230
|
+
suggestions = _a.suggestions,
|
|
231
|
+
onSuggestionSelect = _a.onSuggestionSelect,
|
|
232
|
+
_d = _a.placeholder,
|
|
233
|
+
placeholder = _d === void 0 ? 'Ask a question' : _d,
|
|
234
|
+
maxLength = _a.maxLength,
|
|
235
|
+
_e = _a.disabled,
|
|
236
|
+
disabled = _e === void 0 ? false : _e,
|
|
121
237
|
isSubmitting = _a.isSubmitting,
|
|
122
|
-
|
|
123
|
-
enableVoice =
|
|
124
|
-
|
|
125
|
-
autoSubmitOnVoiceFinal =
|
|
126
|
-
|
|
127
|
-
voiceLanguage =
|
|
128
|
-
|
|
129
|
-
noSpeechTimeoutMs =
|
|
238
|
+
_f = _a.enableVoice,
|
|
239
|
+
enableVoice = _f === void 0 ? true : _f,
|
|
240
|
+
_g = _a.autoSubmitOnVoiceFinal,
|
|
241
|
+
autoSubmitOnVoiceFinal = _g === void 0 ? true : _g,
|
|
242
|
+
_h = _a.voiceLanguage,
|
|
243
|
+
voiceLanguage = _h === void 0 ? 'en-AU' : _h,
|
|
244
|
+
_j = _a.noSpeechTimeoutMs,
|
|
245
|
+
noSpeechTimeoutMs = _j === void 0 ? 8000 : _j,
|
|
130
246
|
onVoiceStart = _a.onVoiceStart,
|
|
131
247
|
onVoiceStop = _a.onVoiceStop,
|
|
132
248
|
onVoiceInterim = _a.onVoiceInterim,
|
|
133
249
|
onVoiceFinal = _a.onVoiceFinal,
|
|
134
250
|
onVoiceError = _a.onVoiceError,
|
|
251
|
+
_k = _a.helperText,
|
|
252
|
+
helperText = _k === void 0 ? '' : _k,
|
|
135
253
|
statusMessage = _a.statusMessage,
|
|
136
254
|
errorMessage = _a.errorMessage,
|
|
137
|
-
|
|
138
|
-
label =
|
|
255
|
+
_l = _a.label,
|
|
256
|
+
label = _l === void 0 ? 'Agent input' : _l,
|
|
257
|
+
_m = _a.docked,
|
|
258
|
+
docked = _m === void 0 ? false : _m,
|
|
139
259
|
dataTestId = _a["data-testid"];
|
|
140
260
|
var isControlled = value !== undefined;
|
|
141
|
-
var
|
|
142
|
-
internalValue =
|
|
143
|
-
setInternalValue =
|
|
144
|
-
var
|
|
145
|
-
machineState =
|
|
146
|
-
setMachineState =
|
|
147
|
-
var
|
|
148
|
-
interimTranscript =
|
|
149
|
-
setInterimTranscript =
|
|
150
|
-
var _o = useState(false),
|
|
151
|
-
internalSubmitting = _o[0],
|
|
152
|
-
setInternalSubmitting = _o[1];
|
|
153
|
-
var _p = useState(undefined),
|
|
154
|
-
internalErrorMessage = _p[0],
|
|
155
|
-
setInternalErrorMessage = _p[1];
|
|
156
|
-
var _q = useState(false),
|
|
157
|
-
voiceSupported = _q[0],
|
|
158
|
-
setVoiceSupported = _q[1];
|
|
261
|
+
var _o = useState(defaultValue),
|
|
262
|
+
internalValue = _o[0],
|
|
263
|
+
setInternalValue = _o[1];
|
|
264
|
+
var _p = useState(getInitialState(normalizeTranscript(value !== null && value !== void 0 ? value : defaultValue).length > 0)),
|
|
265
|
+
machineState = _p[0],
|
|
266
|
+
setMachineState = _p[1];
|
|
267
|
+
var _q = useState(''),
|
|
268
|
+
interimTranscript = _q[0],
|
|
269
|
+
setInterimTranscript = _q[1];
|
|
159
270
|
var _r = useState(false),
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
var _s = useState(
|
|
163
|
-
|
|
164
|
-
|
|
271
|
+
internalSubmitting = _r[0],
|
|
272
|
+
setInternalSubmitting = _r[1];
|
|
273
|
+
var _s = useState(undefined),
|
|
274
|
+
internalErrorMessage = _s[0],
|
|
275
|
+
setInternalErrorMessage = _s[1];
|
|
276
|
+
var _t = useState(false),
|
|
277
|
+
voiceSupported = _t[0],
|
|
278
|
+
setVoiceSupported = _t[1];
|
|
279
|
+
var _u = useState(false),
|
|
280
|
+
prefersReducedMotion = _u[0],
|
|
281
|
+
setPrefersReducedMotion = _u[1];
|
|
282
|
+
var _v = useState(0),
|
|
283
|
+
meterLevel = _v[0],
|
|
284
|
+
setMeterLevel = _v[1];
|
|
165
285
|
var recognitionRef = useRef(null);
|
|
166
286
|
var noSpeechTimeoutRef = useRef(null);
|
|
167
287
|
var isStoppingRef = useRef(false);
|
|
@@ -169,10 +289,19 @@ var AgentInput = function AgentInput(_a) {
|
|
|
169
289
|
var audioStreamRef = useRef(null);
|
|
170
290
|
var audioContextRef = useRef(null);
|
|
171
291
|
var meterRafRef = useRef(null);
|
|
292
|
+
var inputRef = useRef(null);
|
|
172
293
|
var inputId = useId();
|
|
173
294
|
var statusId = "".concat(inputId, "-status");
|
|
295
|
+
var counterId = "".concat(inputId, "-counter");
|
|
174
296
|
var currentValue = isControlled ? value !== null && value !== void 0 ? value : '' : internalValue;
|
|
297
|
+
// Read after onSubmit settles, when the closure's value may be stale
|
|
298
|
+
var currentValueRef = useRef(currentValue);
|
|
299
|
+
useEffect(function () {
|
|
300
|
+
currentValueRef.current = currentValue;
|
|
301
|
+
}, [currentValue]);
|
|
175
302
|
var hasText = normalizeTranscript(currentValue).length > 0;
|
|
303
|
+
var messageLength = normalizeMessage(currentValue).length;
|
|
304
|
+
var isOverLimit = maxLength !== undefined && messageLength > maxLength;
|
|
176
305
|
var effectiveSubmitting = isSubmitting !== null && isSubmitting !== void 0 ? isSubmitting : internalSubmitting;
|
|
177
306
|
var effectiveState = disabled ? 'disabled' : machineState;
|
|
178
307
|
var isListening = effectiveState === 'listening';
|
|
@@ -195,7 +324,7 @@ var AgentInput = function AgentInput(_a) {
|
|
|
195
324
|
}
|
|
196
325
|
}, []);
|
|
197
326
|
var stopMeter = useCallback(function () {
|
|
198
|
-
return __awaiter(
|
|
327
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
199
328
|
return __generator(this, function (_a) {
|
|
200
329
|
switch (_a.label) {
|
|
201
330
|
case 0:
|
|
@@ -223,7 +352,7 @@ var AgentInput = function AgentInput(_a) {
|
|
|
223
352
|
});
|
|
224
353
|
}, []);
|
|
225
354
|
var startMeter = useCallback(function () {
|
|
226
|
-
return __awaiter(
|
|
355
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
227
356
|
var stream, audioContext, analyser_1, source, data_1, _loop_;
|
|
228
357
|
var _b;
|
|
229
358
|
return __generator(this, function (_c) {
|
|
@@ -284,15 +413,22 @@ var AgentInput = function AgentInput(_a) {
|
|
|
284
413
|
});
|
|
285
414
|
}, [onVoiceError, updateMachineState]);
|
|
286
415
|
var submitPayload = useCallback(function (rawText, source) {
|
|
287
|
-
return __awaiter(
|
|
416
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
288
417
|
var text;
|
|
289
418
|
return __generator(this, function (_b) {
|
|
290
419
|
switch (_b.label) {
|
|
291
420
|
case 0:
|
|
292
|
-
text = normalizeTranscript(rawText);
|
|
421
|
+
text = source === 'text' ? normalizeMessage(rawText) : normalizeTranscript(rawText);
|
|
293
422
|
if (!text || disabled || effectiveSubmitting) {
|
|
294
423
|
return [2 /*return*/];
|
|
295
424
|
}
|
|
425
|
+
if (maxLength !== undefined && text.length > maxLength) {
|
|
426
|
+
// A long transcript goes into the field to be shortened, unless the user has typed since
|
|
427
|
+
if (source === 'voice-final' && !normalizeMessage(currentValueRef.current)) {
|
|
428
|
+
updateValue(text);
|
|
429
|
+
}
|
|
430
|
+
return [2 /*return*/];
|
|
431
|
+
}
|
|
296
432
|
updateMachineState({
|
|
297
433
|
type: 'SUBMIT'
|
|
298
434
|
});
|
|
@@ -314,14 +450,18 @@ var AgentInput = function AgentInput(_a) {
|
|
|
314
450
|
type: 'SUBMIT_SUCCESS'
|
|
315
451
|
});
|
|
316
452
|
setInterimTranscript('');
|
|
317
|
-
|
|
453
|
+
// Keep a follow-up typed while submitting
|
|
454
|
+
if (normalizeMessage(currentValueRef.current) === text) {
|
|
455
|
+
updateValue('');
|
|
456
|
+
}
|
|
318
457
|
return [3 /*break*/, 5];
|
|
319
458
|
case 3:
|
|
320
459
|
_b.sent();
|
|
321
460
|
updateMachineState({
|
|
322
461
|
type: 'SUBMIT_ERROR'
|
|
323
462
|
});
|
|
324
|
-
|
|
463
|
+
// Restore the transcript unless the user has typed something since
|
|
464
|
+
if (source === 'voice-final' && !normalizeMessage(currentValueRef.current)) {
|
|
325
465
|
updateValue(text);
|
|
326
466
|
}
|
|
327
467
|
setInternalErrorMessage('Submission failed. Please try again.');
|
|
@@ -336,13 +476,13 @@ var AgentInput = function AgentInput(_a) {
|
|
|
336
476
|
}
|
|
337
477
|
});
|
|
338
478
|
});
|
|
339
|
-
}, [disabled, effectiveSubmitting, isSubmitting, onSubmit, updateMachineState, updateValue]);
|
|
479
|
+
}, [disabled, effectiveSubmitting, isSubmitting, maxLength, onSubmit, updateMachineState, updateValue]);
|
|
340
480
|
var stopListening = useCallback(function (emitStopEvent_1) {
|
|
341
481
|
var args_1 = [];
|
|
342
482
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
343
483
|
args_1[_i - 1] = arguments[_i];
|
|
344
484
|
}
|
|
345
|
-
return __awaiter(
|
|
485
|
+
return __awaiter(_this, __spreadArray([emitStopEvent_1], args_1, true), void 0, function (emitStopEvent, preserveState) {
|
|
346
486
|
if (preserveState === void 0) {
|
|
347
487
|
preserveState = false;
|
|
348
488
|
}
|
|
@@ -378,7 +518,7 @@ var AgentInput = function AgentInput(_a) {
|
|
|
378
518
|
});
|
|
379
519
|
}, [clearNoSpeechTimeout, hasText, onVoiceStop, stopMeter, updateMachineState]);
|
|
380
520
|
var onNoSpeechTimeout = useCallback(function () {
|
|
381
|
-
return __awaiter(
|
|
521
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
382
522
|
var message;
|
|
383
523
|
return __generator(this, function (_a) {
|
|
384
524
|
switch (_a.label) {
|
|
@@ -402,7 +542,7 @@ var AgentInput = function AgentInput(_a) {
|
|
|
402
542
|
});
|
|
403
543
|
}, [clearNoSpeechTimeout, onVoiceError, stopListening, updateMachineState]);
|
|
404
544
|
var beginListening = useCallback(function () {
|
|
405
|
-
return __awaiter(
|
|
545
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
406
546
|
return __generator(this, function (_b) {
|
|
407
547
|
switch (_b.label) {
|
|
408
548
|
case 0:
|
|
@@ -446,7 +586,7 @@ var AgentInput = function AgentInput(_a) {
|
|
|
446
586
|
recognition.interimResults = true;
|
|
447
587
|
recognition.continuous = false;
|
|
448
588
|
recognition.onresult = function (event) {
|
|
449
|
-
return __awaiter(
|
|
589
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
450
590
|
var interim, finalText, index, result, normalizedInterim, normalizedFinal;
|
|
451
591
|
return __generator(this, function (_a) {
|
|
452
592
|
switch (_a.label) {
|
|
@@ -504,7 +644,7 @@ var AgentInput = function AgentInput(_a) {
|
|
|
504
644
|
});
|
|
505
645
|
};
|
|
506
646
|
recognition.onerror = function (event) {
|
|
507
|
-
return __awaiter(
|
|
647
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
508
648
|
var mappedCode;
|
|
509
649
|
return __generator(this, function (_a) {
|
|
510
650
|
switch (_a.label) {
|
|
@@ -520,7 +660,7 @@ var AgentInput = function AgentInput(_a) {
|
|
|
520
660
|
});
|
|
521
661
|
};
|
|
522
662
|
recognition.onend = function () {
|
|
523
|
-
return __awaiter(
|
|
663
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
524
664
|
return __generator(this, function (_a) {
|
|
525
665
|
switch (_a.label) {
|
|
526
666
|
case 0:
|
|
@@ -549,6 +689,95 @@ var AgentInput = function AgentInput(_a) {
|
|
|
549
689
|
stopMeter();
|
|
550
690
|
};
|
|
551
691
|
}, [autoSubmitOnVoiceFinal, clearNoSpeechTimeout, emitVoiceError, enableVoice, hasText, noSpeechTimeoutMs, onNoSpeechTimeout, onVoiceFinal, onVoiceInterim, stopListening, stopMeter, submitPayload, updateMachineState, updateValue, voiceLanguage]);
|
|
692
|
+
var focusField = useCallback(function (cursor) {
|
|
693
|
+
var input = inputRef.current;
|
|
694
|
+
if (!input) return;
|
|
695
|
+
input.focus();
|
|
696
|
+
if (!cursor) return;
|
|
697
|
+
var placeCursor = function placeCursor() {
|
|
698
|
+
if (cursor === 'all') {
|
|
699
|
+
input.select();
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
var position = cursor === 'start' ? 0 : input.value.length;
|
|
703
|
+
input.setSelectionRange(position, position);
|
|
704
|
+
};
|
|
705
|
+
placeCursor();
|
|
706
|
+
// Again after the render a prefill in the same handler triggers, so 'end' lands after the new text
|
|
707
|
+
window.setTimeout(placeCursor, 0);
|
|
708
|
+
}, []);
|
|
709
|
+
useImperativeHandle(ref, function () {
|
|
710
|
+
return {
|
|
711
|
+
focus: function focus(options) {
|
|
712
|
+
return focusField(options === null || options === void 0 ? void 0 : options.cursor);
|
|
713
|
+
},
|
|
714
|
+
clear: function clear() {
|
|
715
|
+
setInterimTranscript('');
|
|
716
|
+
updateValue('');
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
}, [focusField, updateValue]);
|
|
720
|
+
// The region above the field (decision 0046). The last review and suggestions shown are kept, so
|
|
721
|
+
// they can fade out after the product removes them.
|
|
722
|
+
var _w = useState(review),
|
|
723
|
+
shownReview = _w[0],
|
|
724
|
+
setShownReview = _w[1];
|
|
725
|
+
var _x = useState(null),
|
|
726
|
+
lastReviewAction = _x[0],
|
|
727
|
+
setLastReviewAction = _x[1];
|
|
728
|
+
if (review && review !== shownReview) {
|
|
729
|
+
setShownReview(review);
|
|
730
|
+
// A new proposal or change replaces what the last Discard or Undo announced
|
|
731
|
+
if (lastReviewAction) setLastReviewAction(null);
|
|
732
|
+
}
|
|
733
|
+
// A proposal replacing an open one is announced as an update (decision 0047). Consecutive
|
|
734
|
+
// replacements alternate a trailing no-break space, so the live region's text changes each time
|
|
735
|
+
// even when the summary doesn't; screen readers don't speak it.
|
|
736
|
+
var openProposalId = (review === null || review === void 0 ? void 0 : review.state) === 'proposal' ? review.id : null;
|
|
737
|
+
var _y = useState(openProposalId),
|
|
738
|
+
announcedProposalId = _y[0],
|
|
739
|
+
setAnnouncedProposalId = _y[1];
|
|
740
|
+
var _z = useState(0),
|
|
741
|
+
replacementCount = _z[0],
|
|
742
|
+
setReplacementCount = _z[1];
|
|
743
|
+
if (openProposalId !== announcedProposalId) {
|
|
744
|
+
setAnnouncedProposalId(openProposalId);
|
|
745
|
+
setReplacementCount(openProposalId !== null && announcedProposalId !== null ? replacementCount + 1 : 0);
|
|
746
|
+
}
|
|
747
|
+
var cappedSuggestions = useMemo(function () {
|
|
748
|
+
return (suggestions !== null && suggestions !== void 0 ? suggestions : []).slice(0, MAX_SUGGESTIONS);
|
|
749
|
+
}, [suggestions]);
|
|
750
|
+
var showSuggestions = cappedSuggestions.length > 0 && !hasText && (review === null || review === void 0 ? void 0 : review.state) !== 'proposal';
|
|
751
|
+
var _0 = useState(cappedSuggestions),
|
|
752
|
+
shownSuggestions = _0[0],
|
|
753
|
+
setShownSuggestions = _0[1];
|
|
754
|
+
if (showSuggestions && cappedSuggestions !== shownSuggestions) {
|
|
755
|
+
setShownSuggestions(cappedSuggestions);
|
|
756
|
+
}
|
|
757
|
+
var suggestionCount = (_b = suggestions === null || suggestions === void 0 ? void 0 : suggestions.length) !== null && _b !== void 0 ? _b : 0;
|
|
758
|
+
useEffect(function () {
|
|
759
|
+
if (!isProduction && suggestionCount > MAX_SUGGESTIONS) {
|
|
760
|
+
console.warn("AgentInput shows at most ".concat(MAX_SUGGESTIONS, " suggestions (decision 0046); ").concat(suggestionCount, " were passed, so the rest are hidden."));
|
|
761
|
+
}
|
|
762
|
+
}, [suggestionCount]);
|
|
763
|
+
var reviewAnnouncement = review ? review.state === 'proposal' ? "".concat(replacementCount > 0 ? 'Proposal updated. ' : '').concat(review.summary, ". Accept or discard.").concat(replacementCount > 0 && replacementCount % 2 === 0 ? "\xA0" : '') : 'Changes applied. Undo available.' : lastReviewAction === 'discarded' ? 'Suggestion discarded.' : lastReviewAction === 'undone' ? 'Changes undone.' : '';
|
|
764
|
+
var onReviewDiscard = function onReviewDiscard(onDiscard) {
|
|
765
|
+
setLastReviewAction('discarded');
|
|
766
|
+
onDiscard();
|
|
767
|
+
// The bar is leaving, so focus goes to the field rather than being lost
|
|
768
|
+
focusField();
|
|
769
|
+
};
|
|
770
|
+
var onReviewUndo = function onReviewUndo(onUndo) {
|
|
771
|
+
setLastReviewAction('undone');
|
|
772
|
+
onUndo();
|
|
773
|
+
focusField();
|
|
774
|
+
};
|
|
775
|
+
var onPickSuggestion = function onPickSuggestion(text) {
|
|
776
|
+
updateValue(text);
|
|
777
|
+
onSuggestionSelect === null || onSuggestionSelect === void 0 ? void 0 : onSuggestionSelect(text);
|
|
778
|
+
// Fills, never sends: the user reviews the text in the field first
|
|
779
|
+
focusField('end');
|
|
780
|
+
};
|
|
552
781
|
useEffect(function () {
|
|
553
782
|
var mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
554
783
|
var sync = function sync() {
|
|
@@ -580,8 +809,40 @@ var AgentInput = function AgentInput(_a) {
|
|
|
580
809
|
if (!interimTranscript) {
|
|
581
810
|
return currentValue;
|
|
582
811
|
}
|
|
583
|
-
return
|
|
812
|
+
return normalizeMessage([currentValue, interimTranscript].filter(Boolean).join(' '));
|
|
584
813
|
}, [currentValue, interimTranscript]);
|
|
814
|
+
var lastFieldWidthRef = useRef(0);
|
|
815
|
+
var resizeField = useCallback(function () {
|
|
816
|
+
var field = inputRef.current;
|
|
817
|
+
// Hidden (for example in a closed sheet): measure when it's shown, via the observer below
|
|
818
|
+
if (!field || field.clientWidth === 0) return;
|
|
819
|
+
lastFieldWidthRef.current = field.clientWidth;
|
|
820
|
+
// Collapsing the field to measure it shrinks the page for a moment; some engines clamp a page
|
|
821
|
+
// scrolled to the bottom when that happens, so restore its scroll position
|
|
822
|
+
var scrollX = window.scrollX,
|
|
823
|
+
scrollY = window.scrollY;
|
|
824
|
+
field.style.height = 'auto';
|
|
825
|
+
field.style.height = "".concat(field.scrollHeight, "px");
|
|
826
|
+
if (window.scrollY !== scrollY) window.scrollTo(scrollX, scrollY);
|
|
827
|
+
// Scroll only once max-height (six rows) clips the content
|
|
828
|
+
field.style.overflowY = field.scrollHeight > field.clientHeight ? 'auto' : 'hidden';
|
|
829
|
+
}, []);
|
|
830
|
+
useIsomorphicLayoutEffect(function () {
|
|
831
|
+
resizeField();
|
|
832
|
+
}, [displayedValue, resizeField]);
|
|
833
|
+
// Text rewraps when the field's width changes (layout, or being shown), not only the window's
|
|
834
|
+
useEffect(function () {
|
|
835
|
+
var field = inputRef.current;
|
|
836
|
+
if (!field || typeof ResizeObserver === 'undefined') return;
|
|
837
|
+
var observer = new ResizeObserver(function () {
|
|
838
|
+
// Its own height changes trigger this too; only a width change can rewrap the text
|
|
839
|
+
if (field.clientWidth !== lastFieldWidthRef.current) resizeField();
|
|
840
|
+
});
|
|
841
|
+
observer.observe(field);
|
|
842
|
+
return function () {
|
|
843
|
+
return observer.disconnect();
|
|
844
|
+
};
|
|
845
|
+
}, [resizeField]);
|
|
585
846
|
var onTextChange = function onTextChange(event) {
|
|
586
847
|
updateValue(event.target.value);
|
|
587
848
|
if (effectiveState === 'error') {
|
|
@@ -593,10 +854,18 @@ var AgentInput = function AgentInput(_a) {
|
|
|
593
854
|
}
|
|
594
855
|
};
|
|
595
856
|
var onInputKeyDown = function onInputKeyDown(event) {
|
|
596
|
-
return __awaiter(
|
|
857
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
858
|
+
var isComposing;
|
|
597
859
|
return __generator(this, function (_a) {
|
|
598
860
|
switch (_a.label) {
|
|
599
861
|
case 0:
|
|
862
|
+
isComposing = event.nativeEvent.isComposing || event.keyCode === 229;
|
|
863
|
+
// Escape during an IME composition cancels the composition, not the request
|
|
864
|
+
if (event.key === 'Escape' && onStop && effectiveSubmitting && !isComposing) {
|
|
865
|
+
event.preventDefault();
|
|
866
|
+
onStop();
|
|
867
|
+
return [2 /*return*/];
|
|
868
|
+
}
|
|
600
869
|
if (!(event.key === 'Escape' && isListening)) return [3 /*break*/, 2];
|
|
601
870
|
event.preventDefault();
|
|
602
871
|
return [4 /*yield*/, stopListening(true)];
|
|
@@ -604,7 +873,7 @@ var AgentInput = function AgentInput(_a) {
|
|
|
604
873
|
_a.sent();
|
|
605
874
|
return [2 /*return*/];
|
|
606
875
|
case 2:
|
|
607
|
-
if (!(event.key === 'Enter')) return [3 /*break*/, 4];
|
|
876
|
+
if (!(event.key === 'Enter' && !event.shiftKey && !isComposing)) return [3 /*break*/, 4];
|
|
608
877
|
event.preventDefault();
|
|
609
878
|
return [4 /*yield*/, submitPayload(currentValue, 'text')];
|
|
610
879
|
case 3:
|
|
@@ -617,7 +886,7 @@ var AgentInput = function AgentInput(_a) {
|
|
|
617
886
|
});
|
|
618
887
|
};
|
|
619
888
|
var onMicToggle = function onMicToggle() {
|
|
620
|
-
return __awaiter(
|
|
889
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
621
890
|
return __generator(this, function (_a) {
|
|
622
891
|
switch (_a.label) {
|
|
623
892
|
case 0:
|
|
@@ -637,40 +906,105 @@ var AgentInput = function AgentInput(_a) {
|
|
|
637
906
|
});
|
|
638
907
|
};
|
|
639
908
|
var statusByState = {
|
|
640
|
-
idle: statusMessage ||
|
|
641
|
-
typing: statusMessage ||
|
|
909
|
+
idle: statusMessage || helperText,
|
|
910
|
+
typing: statusMessage || helperText,
|
|
642
911
|
listening: statusMessage || DEFAULT_LISTENING_MESSAGE,
|
|
643
912
|
processingFinalTranscript: statusMessage || DEFAULT_PROCESSING_MESSAGE,
|
|
644
913
|
submitting: statusMessage || 'Submitting…',
|
|
645
914
|
error: errorMessage || internalErrorMessage || 'Voice input failed. Try again.',
|
|
646
|
-
disabled: statusMessage ||
|
|
915
|
+
disabled: statusMessage || helperText
|
|
647
916
|
};
|
|
648
|
-
var
|
|
649
|
-
|
|
650
|
-
var resolvedStatus =
|
|
651
|
-
var isStatusError = effectiveState === 'error'
|
|
917
|
+
var overLimitMessage = isOverLimit && maxLength !== undefined ? "Over the ".concat(maxLength, "-character limit. Shorten your message to send.") : undefined;
|
|
918
|
+
// A product-set error shows in any state. Unsupported voice hides the mic without a message.
|
|
919
|
+
var resolvedStatus = errorMessage || overLimitMessage || statusByState[effectiveState];
|
|
920
|
+
var isStatusError = Boolean(errorMessage) || isOverLimit || effectiveState === 'error';
|
|
652
921
|
var meterBars = createMeterBars(meterLevel);
|
|
653
|
-
var
|
|
922
|
+
var showStop = Boolean(onStop) && effectiveSubmitting;
|
|
923
|
+
var sendDisabled = disabled || effectiveSubmitting || isOverLimit || messageLength === 0;
|
|
924
|
+
var showCounter = maxLength !== undefined && messageLength >= maxLength * COUNTER_THRESHOLD;
|
|
925
|
+
// Announced once when the limit is reached; going over is announced by the status line
|
|
926
|
+
var limitAnnouncement = maxLength !== undefined && messageLength === maxLength ? "Character limit reached: ".concat(maxLength, " characters") : '';
|
|
654
927
|
return jsxs(Container, {
|
|
655
928
|
"data-testid": dataTestId,
|
|
929
|
+
"$docked": docked,
|
|
930
|
+
"data-docked": docked || undefined,
|
|
656
931
|
children: [jsx(VisuallyHiddenLabel, {
|
|
657
932
|
htmlFor: inputId,
|
|
658
933
|
children: label
|
|
659
|
-
}),
|
|
660
|
-
children: jsx(
|
|
934
|
+
}), jsxs(ControlsRow, {
|
|
935
|
+
children: [jsx(RegionPart, {
|
|
936
|
+
show: Boolean(review),
|
|
937
|
+
reducedExit: prefersReducedMotion,
|
|
938
|
+
children: shownReview && jsxs(ReviewBar, {
|
|
939
|
+
"data-testid": "agent-input-review",
|
|
940
|
+
children: [jsx(Typography, {
|
|
941
|
+
variant: "small",
|
|
942
|
+
color: "default",
|
|
943
|
+
children: shownReview.state === 'proposal' ? shownReview.summary : 'Changes applied'
|
|
944
|
+
}), jsx(ReviewActions, {
|
|
945
|
+
children: shownReview.state === 'proposal' ? jsxs(Fragment, {
|
|
946
|
+
children: [jsx(Button, {
|
|
947
|
+
variant: "primary",
|
|
948
|
+
size: "small",
|
|
949
|
+
onClick: shownReview.onAccept,
|
|
950
|
+
children: "Accept"
|
|
951
|
+
}), jsx(Button, {
|
|
952
|
+
variant: "secondary",
|
|
953
|
+
size: "small",
|
|
954
|
+
onClick: function onClick() {
|
|
955
|
+
return onReviewDiscard(shownReview.onDiscard);
|
|
956
|
+
},
|
|
957
|
+
children: "Discard"
|
|
958
|
+
})]
|
|
959
|
+
}) : jsx(Button, {
|
|
960
|
+
variant: "naked",
|
|
961
|
+
size: "small",
|
|
962
|
+
onClick: function onClick() {
|
|
963
|
+
return onReviewUndo(shownReview.onUndo);
|
|
964
|
+
},
|
|
965
|
+
children: "Undo"
|
|
966
|
+
})
|
|
967
|
+
})]
|
|
968
|
+
})
|
|
969
|
+
}), jsx(RegionPart, {
|
|
970
|
+
show: showSuggestions,
|
|
971
|
+
reducedExit: prefersReducedMotion,
|
|
972
|
+
children: jsx(SuggestionList, {
|
|
973
|
+
"aria-label": "Suggestions",
|
|
974
|
+
"data-testid": "agent-input-suggestions",
|
|
975
|
+
children: shownSuggestions.map(function (suggestion, index) {
|
|
976
|
+
return jsx("li", {
|
|
977
|
+
children: jsx(SuggestionChip, {
|
|
978
|
+
onClick: function onClick() {
|
|
979
|
+
return onPickSuggestion(suggestion);
|
|
980
|
+
},
|
|
981
|
+
children: suggestion
|
|
982
|
+
})
|
|
983
|
+
}, "".concat(index, "-").concat(suggestion));
|
|
984
|
+
})
|
|
985
|
+
})
|
|
986
|
+
}), jsx(VisuallyHidden, {
|
|
987
|
+
"aria-live": "polite",
|
|
988
|
+
"aria-atomic": "true",
|
|
989
|
+
"data-testid": "agent-input-review-announcement",
|
|
990
|
+
children: reviewAnnouncement
|
|
991
|
+
}), jsx(InputWrapper, {
|
|
661
992
|
children: jsxs(InputShell, {
|
|
662
|
-
"data-disabled": disabled
|
|
993
|
+
"data-disabled": disabled,
|
|
663
994
|
children: [jsx(Input, {
|
|
995
|
+
ref: inputRef,
|
|
664
996
|
id: inputId,
|
|
665
|
-
|
|
997
|
+
rows: 1,
|
|
998
|
+
enterKeyHint: "send",
|
|
666
999
|
"aria-label": label,
|
|
667
1000
|
value: displayedValue,
|
|
668
1001
|
onChange: onTextChange,
|
|
669
1002
|
onKeyDown: onInputKeyDown,
|
|
670
1003
|
placeholder: placeholder,
|
|
671
|
-
disabled: disabled
|
|
1004
|
+
disabled: disabled,
|
|
672
1005
|
readOnly: isListening,
|
|
673
|
-
"aria-describedby": statusId
|
|
1006
|
+
"aria-describedby": showCounter ? "".concat(statusId, " ").concat(counterId) : statusId,
|
|
1007
|
+
"aria-invalid": isOverLimit || undefined
|
|
674
1008
|
}), jsxs(InputActions, {
|
|
675
1009
|
children: [hasVoice && jsxs(MicButtonWrapper, {
|
|
676
1010
|
"$isListening": isListening,
|
|
@@ -690,7 +1024,17 @@ var AgentInput = function AgentInput(_a) {
|
|
|
690
1024
|
disabled: disabled || effectiveSubmitting,
|
|
691
1025
|
type: "button"
|
|
692
1026
|
})]
|
|
693
|
-
}), jsx(CircularActionIconButton, {
|
|
1027
|
+
}), showStop ? jsx(CircularActionIconButton, {
|
|
1028
|
+
variant: "secondary",
|
|
1029
|
+
size: "medium",
|
|
1030
|
+
iconName: "stop",
|
|
1031
|
+
onClick: function onClick() {
|
|
1032
|
+
return onStop === null || onStop === void 0 ? void 0 : onStop();
|
|
1033
|
+
},
|
|
1034
|
+
disabled: disabled,
|
|
1035
|
+
"aria-label": "Stop",
|
|
1036
|
+
type: "button"
|
|
1037
|
+
}) : jsx(CircularActionIconButton, {
|
|
694
1038
|
variant: "secondary",
|
|
695
1039
|
size: "medium",
|
|
696
1040
|
iconName: "directionUp",
|
|
@@ -703,7 +1047,7 @@ var AgentInput = function AgentInput(_a) {
|
|
|
703
1047
|
})]
|
|
704
1048
|
})]
|
|
705
1049
|
})
|
|
706
|
-
})
|
|
1050
|
+
})]
|
|
707
1051
|
}), jsxs(StatusRow, {
|
|
708
1052
|
children: [jsx(StatusText, {
|
|
709
1053
|
"$isError": isStatusError,
|
|
@@ -712,24 +1056,44 @@ var AgentInput = function AgentInput(_a) {
|
|
|
712
1056
|
role: "status",
|
|
713
1057
|
"aria-live": "polite",
|
|
714
1058
|
"aria-atomic": "true",
|
|
715
|
-
children: jsx(Typography, {
|
|
1059
|
+
children: resolvedStatus && jsx(Typography, {
|
|
716
1060
|
variant: "small",
|
|
717
1061
|
color: isStatusError ? 'error' : 'subdued',
|
|
718
1062
|
children: resolvedStatus
|
|
719
1063
|
})
|
|
720
1064
|
})
|
|
721
|
-
}),
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
1065
|
+
}), jsxs(StatusEnd, {
|
|
1066
|
+
children: [isListening && !prefersReducedMotion && jsx(MeterContainer, {
|
|
1067
|
+
"aria-hidden": "true",
|
|
1068
|
+
children: meterBars.map(function (barHeight, index) {
|
|
1069
|
+
return jsx(MeterBar, {
|
|
1070
|
+
"$height": barHeight
|
|
1071
|
+
}, "meter-".concat(index));
|
|
1072
|
+
})
|
|
1073
|
+
}), showCounter && jsx(Typography, {
|
|
1074
|
+
variant: "small",
|
|
1075
|
+
color: isOverLimit ? 'error' : 'subdued',
|
|
1076
|
+
children: jsxs("span", {
|
|
1077
|
+
id: counterId,
|
|
1078
|
+
"data-testid": "agent-input-counter",
|
|
1079
|
+
children: [messageLength, "/", maxLength, jsx(VisuallyHidden, {
|
|
1080
|
+
children: " characters"
|
|
1081
|
+
})]
|
|
1082
|
+
})
|
|
1083
|
+
})]
|
|
1084
|
+
}), maxLength !== undefined && jsx(VisuallyHidden, {
|
|
1085
|
+
role: "status",
|
|
1086
|
+
"aria-live": "polite",
|
|
1087
|
+
"aria-atomic": "true",
|
|
1088
|
+
"data-testid": "agent-input-limit-announcement",
|
|
1089
|
+
children: limitAnnouncement
|
|
728
1090
|
})]
|
|
729
1091
|
})]
|
|
730
1092
|
});
|
|
731
|
-
}
|
|
732
|
-
var
|
|
1093
|
+
}
|
|
1094
|
+
var AgentInput = /*#__PURE__*/forwardRef(AgentInputWithRef);
|
|
1095
|
+
AgentInput.displayName = 'AgentInput';
|
|
1096
|
+
var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10, templateObject_11, templateObject_12, templateObject_13, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21, templateObject_22, templateObject_23, templateObject_24, templateObject_25, templateObject_26, templateObject_27, templateObject_28, templateObject_29, templateObject_30, templateObject_31, templateObject_32, templateObject_33;
|
|
733
1097
|
|
|
734
1098
|
export { AgentInput };
|
|
735
1099
|
//# sourceMappingURL=AgentInput.mjs.map
|