@astryxdesign/lab 0.7.5-canary.bc40b80 → 0.7.5-canary.c26ae3f
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/blocks/CommentPinShowcase.doc.mjs +1 -1
- package/blocks/CommentPinShowcase.tsx +2 -3
- package/dist/CommentPin/CommentPin.d.ts +22 -7
- package/dist/CommentPin/CommentPin.d.ts.map +1 -1
- package/dist/CommentPin/CommentPin.js +115 -38
- package/dist/ListInput/ListInput.d.ts.map +1 -1
- package/dist/ListInput/ListInput.js +19 -0
- package/dist/MobilePowerSearch/MobilePowerSearch.d.ts +5 -0
- package/dist/MobilePowerSearch/MobilePowerSearch.d.ts.map +1 -1
- package/dist/MobilePowerSearch/MobilePowerSearch.js +100 -7
- package/dist/TransferList/TransferList.d.ts.map +1 -1
- package/dist/TransferList/TransferList.js +20 -0
- package/dist/lab.css +20 -14
- package/dist/reorderStyles.d.ts +2 -2
- package/dist/reorderStyles.d.ts.map +1 -1
- package/dist/reorderStyles.js +2 -2
- package/package.json +7 -7
- package/src/Chat/__tests__/ChatTypingIndicator.a11y.chromium.spec.ts +1 -0
- package/src/CircularProgress/__tests__/CircularProgress.a11y.chromium.spec.ts +1 -0
- package/src/CommentPin/CommentPin.doc.mjs +82 -34
- package/src/CommentPin/CommentPin.spec.md +92 -81
- package/src/CommentPin/CommentPin.test.tsx +98 -19
- package/src/CommentPin/CommentPin.tsx +146 -82
- package/src/Comments/Comments.test.tsx +10 -4
- package/src/InfoTip/InfoTip.test.tsx +9 -4
- package/src/ListInput/ListInput.test.tsx +43 -3
- package/src/ListInput/ListInput.tsx +23 -0
- package/src/MobilePowerSearch/MobilePowerSearch.test.tsx +165 -5
- package/src/MobilePowerSearch/MobilePowerSearch.tsx +113 -5
- package/src/MobileTokenizer/MobileTokenizer.test.tsx +12 -3
- package/src/TransferList/TransferList.composition.test.tsx +4 -4
- package/src/TransferList/TransferList.test.tsx +36 -0
- package/src/TransferList/TransferList.tsx +24 -0
- package/src/TransferList/TransferListSelector.test.tsx +4 -4
- package/src/__tests__/ReorderGripPinchZoom.a11y.chromium.spec.ts +178 -0
- package/src/reorderStyles.ts +7 -2
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
name: 'Avatar-first annotations',
|
|
7
7
|
displayName: 'Avatar-first annotations',
|
|
8
8
|
description:
|
|
9
|
-
'Caller-positioned comment pins over media and in a content margin. Every coordinate maps to the pin’s logical bottom-start corner. The selected group caps its participants at three circles (two Avatars plus
|
|
9
|
+
'Caller-positioned comment pins over media and in a content margin. Every coordinate maps to the pin’s logical bottom-start corner. The selected group caps its participants at three circles (two Avatars plus an ellipsis) and ends with its total and an accent unread dot; the unread margin pin shows the dot too. Other pins dim without becoming disabled, activating the selected pin again clears the selection, and no pin dims while nothing is selected.',
|
|
10
10
|
exampleFor: 'CommentPin',
|
|
11
11
|
isReady: true,
|
|
12
12
|
isShowcase: true,
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* participant/thread/unread counts, and controlled selected/dimmed state
|
|
8
8
|
* that may be empty
|
|
9
9
|
* @output A grouped pin with a three-circle participant cap and an unread
|
|
10
|
-
*
|
|
10
|
+
* dot, a single pin, and an unread margin pin; activating the selected
|
|
11
11
|
* pin clears the selection, and non-selected pins dim only while another pin
|
|
12
12
|
* is selected
|
|
13
13
|
* @position CommentPin docsite showcase and copyable Lab block
|
|
@@ -160,9 +160,8 @@ export default function CommentPinShowcase() {
|
|
|
160
160
|
xstyle={styles.groupedMarker}
|
|
161
161
|
/>
|
|
162
162
|
<CommentPin
|
|
163
|
-
label="Open
|
|
163
|
+
label="Open annotation from Mira"
|
|
164
164
|
participants={[PEOPLE.mira]}
|
|
165
|
-
isResolved
|
|
166
165
|
isSelected={selected === 'resolved'}
|
|
167
166
|
isDimmed={selected != null && selected !== 'resolved'}
|
|
168
167
|
onClick={() => toggle('resolved')}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { BaseProps } from '@astryxdesign/core';
|
|
2
|
+
/** Pin heights on the shared element-size scale: 28, 32, or 36px. */
|
|
3
|
+
export type CommentPinSize = 'sm' | 'md' | 'lg';
|
|
2
4
|
/** Identity data for one representative shown inside a CommentPin. */
|
|
3
5
|
export interface CommentPinParticipant {
|
|
4
6
|
/** Stable identity used to remove duplicate representatives. */
|
|
@@ -21,10 +23,17 @@ export interface CommentPinProps extends Omit<BaseProps<HTMLButtonElement>, 'chi
|
|
|
21
23
|
* Ordered participants, lead first. A single marker shows the first. A
|
|
22
24
|
* grouped marker shows distinct IDs as an AvatarGroup of at most three
|
|
23
25
|
* circles: every participant when three or fewer are distinct, otherwise the
|
|
24
|
-
* first two plus
|
|
25
|
-
* the overflow
|
|
26
|
+
* first two plus an ellipsis overflow circle. Pass every distinct
|
|
27
|
+
* participant so the overflow appears only when more than three people
|
|
28
|
+
* participate.
|
|
26
29
|
*/
|
|
27
30
|
participants: readonly [CommentPinParticipant, ...CommentPinParticipant[]];
|
|
31
|
+
/**
|
|
32
|
+
* Pin height on the element-size scale: `sm` 28px, `md` 32px, `lg` 36px,
|
|
33
|
+
* with 22px, 24px, and 28px participant circles.
|
|
34
|
+
* @default 'sm'
|
|
35
|
+
*/
|
|
36
|
+
size?: CommentPinSize;
|
|
28
37
|
/**
|
|
29
38
|
* Total number of threads represented by this marker. Values above one use
|
|
30
39
|
* the grouped presentation and show the exact total.
|
|
@@ -33,8 +42,9 @@ export interface CommentPinProps extends Omit<BaseProps<HTMLButtonElement>, 'chi
|
|
|
33
42
|
threadCount?: number;
|
|
34
43
|
/**
|
|
35
44
|
* Number of represented threads with unread activity. When above zero, an
|
|
36
|
-
* accent
|
|
37
|
-
*
|
|
45
|
+
* accent status dot appears at the end of the pin: after the thread total,
|
|
46
|
+
* or after the participant on a single pin. Values above `threadCount` are
|
|
47
|
+
* capped.
|
|
38
48
|
* @default 0
|
|
39
49
|
*/
|
|
40
50
|
unreadCount?: number;
|
|
@@ -45,7 +55,11 @@ export interface CommentPinProps extends Omit<BaseProps<HTMLButtonElement>, 'chi
|
|
|
45
55
|
* disabling it, so it remains available to switch selection.
|
|
46
56
|
*/
|
|
47
57
|
isDimmed?: boolean;
|
|
48
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* Whether every thread represented by this pin is resolved. A resolved pin
|
|
60
|
+
* renders nothing unless it is selected, so resolved discussion leaves the
|
|
61
|
+
* content while a thread the reader opened keeps its anchor.
|
|
62
|
+
*/
|
|
49
63
|
isResolved?: boolean;
|
|
50
64
|
/** Whether activation is unavailable. */
|
|
51
65
|
isDisabled?: boolean;
|
|
@@ -56,7 +70,8 @@ export interface CommentPinProps extends Omit<BaseProps<HTMLButtonElement>, 'chi
|
|
|
56
70
|
* The caller owns grouping, representative selection, coordinates, collision
|
|
57
71
|
* handling, and the content opened by activation. Absolute placement maps the
|
|
58
72
|
* host anchor to the pin's logical bottom-start corner. The pin only owns its
|
|
59
|
-
* compact button surface and controlled visual states.
|
|
73
|
+
* compact button surface and controlled visual states. `size` sets its height
|
|
74
|
+
* on the element-size scale.
|
|
60
75
|
*
|
|
61
76
|
* @example
|
|
62
77
|
* ```
|
|
@@ -79,7 +94,7 @@ export interface CommentPinProps extends Omit<BaseProps<HTMLButtonElement>, 'chi
|
|
|
79
94
|
* />
|
|
80
95
|
* ```
|
|
81
96
|
*/
|
|
82
|
-
export declare function CommentPin({ label, participants, threadCount, unreadCount, isSelected, isDimmed, isResolved, isDisabled, ref, xstyle, className, style, ...rest }: CommentPinProps): React.ReactNode;
|
|
97
|
+
export declare function CommentPin({ label, participants, size, threadCount, unreadCount, isSelected, isDimmed, isResolved, isDisabled, ref, xstyle, className, style, ...rest }: CommentPinProps): React.ReactNode;
|
|
83
98
|
export declare namespace CommentPin {
|
|
84
99
|
var displayName: string;
|
|
85
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommentPin.d.ts","sourceRoot":"","sources":["../../src/CommentPin/CommentPin.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CommentPin.d.ts","sourceRoot":"","sources":["../../src/CommentPin/CommentPin.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AA4BlD,qEAAqE;AACrE,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhD,sEAAsE;AACtE,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,EAAE,EAAE,MAAM,CAAC;IACX,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,SAAS,CAAC,iBAAiB,CAAC,EAC5B,UAAU,CACX;IACC,0CAA0C;IAC1C,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,YAAY,EAAE,SAAS,CAAC,qBAAqB,EAAE,GAAG,qBAAqB,EAAE,CAAC,CAAC;IAC3E;;;;OAIG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AA8ND;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,YAAY,EACZ,IAAW,EACX,WAAe,EACf,WAAe,EACf,UAAkB,EAClB,QAAgB,EAChB,UAAkB,EAClB,UAAkB,EAClB,GAAG,EACH,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,IAAI,EACR,EAAE,eAAe,GAAG,KAAK,CAAC,SAAS,CA4JnC;yBA3Ke,UAAU"}
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* @file CommentPin.tsx
|
|
7
7
|
* @input Ordered participants (grouped pins show at most three circles),
|
|
8
|
-
* total and unread represented thread counts,
|
|
9
|
-
*
|
|
8
|
+
* total and unread represented thread counts (unread shows as a dot), a
|
|
9
|
+
* size on the element-size
|
|
10
|
+
* scale, controlled selected/dimmed/resolved/disabled state, and button DOM
|
|
11
|
+
* props
|
|
10
12
|
* @output Exports the avatar-first CommentPin button and its public types
|
|
11
13
|
* @position Lab collaboration primitive for annotation anchors over content or
|
|
12
14
|
* in content margins; callers own grouping, coordinates, and opened content
|
|
@@ -23,11 +25,15 @@ import * as stylex from '@stylexjs/stylex';
|
|
|
23
25
|
import { Avatar } from '@astryxdesign/core/Avatar';
|
|
24
26
|
import { AvatarGroup, AvatarGroupOverflow } from '@astryxdesign/core/AvatarGroup';
|
|
25
27
|
import { useDevWarning, useMergedRefs, usePressFeedback } from '@astryxdesign/core/hooks';
|
|
28
|
+
import { Icon } from '@astryxdesign/core/Icon';
|
|
29
|
+
import { StatusDot } from '@astryxdesign/core/StatusDot';
|
|
26
30
|
import '@astryxdesign/core/theme/tokens.stylex';
|
|
27
|
-
import { borderVars, colorVars, fontWeightVars,
|
|
31
|
+
import { borderVars, colorVars, fontWeightVars, shadowVars, sizeVars, spacingVars, typeScaleVars, typographyVars } from '@astryxdesign/core/theme/tokens.stylex';
|
|
28
32
|
import { useTooltip } from '@astryxdesign/core/Tooltip';
|
|
29
33
|
import { focusOutlineProps, interactionOverlayStyles, mergeProps, themeProps } from '@astryxdesign/core/utils';
|
|
30
34
|
|
|
35
|
+
/** Pin heights on the shared element-size scale: 28, 32, or 36px. */
|
|
36
|
+
|
|
31
37
|
/** Identity data for one representative shown inside a CommentPin. */
|
|
32
38
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
33
39
|
const styles = {
|
|
@@ -41,17 +47,11 @@ const styles = {
|
|
|
41
47
|
kmuXW: "x2lah0s",
|
|
42
48
|
kXLuUW: "xxymvpz",
|
|
43
49
|
k3nNDw: "x1bd091l x173emx3",
|
|
44
|
-
k7Eaqz: "x1nkkqge",
|
|
45
|
-
kZKoxP: "x6k0iem",
|
|
46
50
|
kogj98: "x1ghz6dp",
|
|
47
|
-
kmVPX3: "x12nba7r",
|
|
48
51
|
kMzoRj: "x1litavf",
|
|
49
52
|
ksu8eU: "x1y0btm7",
|
|
50
53
|
kVAM5u: "x9r1u3d",
|
|
51
|
-
|
|
52
|
-
kfmiAY: "x8agd5o",
|
|
53
|
-
kT0f0o: "x1dgc8on",
|
|
54
|
-
kVL7Gh: "x1pczhz8",
|
|
54
|
+
kVL7Gh: "x6en5u8",
|
|
55
55
|
kWkggS: "x1prclbq",
|
|
56
56
|
kKwaWg: "x18o3ruo",
|
|
57
57
|
kGVxlE: "x14hfi27",
|
|
@@ -68,8 +68,6 @@ const styles = {
|
|
|
68
68
|
withCount: {
|
|
69
69
|
kjj79g: "x1nhvcw1",
|
|
70
70
|
kOIVth: "xzye2dw",
|
|
71
|
-
kZCmMZ: "x138rykx",
|
|
72
|
-
kwRFfy: "x1djylfy",
|
|
73
71
|
$$css: true
|
|
74
72
|
},
|
|
75
73
|
selected: {
|
|
@@ -81,15 +79,6 @@ const styles = {
|
|
|
81
79
|
kMwMTN: "xv1l7n4 x1k5gbb1",
|
|
82
80
|
$$css: true
|
|
83
81
|
},
|
|
84
|
-
resolved: {
|
|
85
|
-
kAXs8y: "x1kzknox",
|
|
86
|
-
kVAM5u: "x9r1u3d x1w1tqly",
|
|
87
|
-
kWkggS: "xwmxj5m x9yvj25",
|
|
88
|
-
kGVxlE: "x1gnnqk1",
|
|
89
|
-
kMwMTN: "xv1l7n4 xs5hli",
|
|
90
|
-
kSiTet: "xf9vgkq x1tbh5bv",
|
|
91
|
-
$$css: true
|
|
92
|
-
},
|
|
93
82
|
dimmed: {
|
|
94
83
|
kSiTet: "xti2d7y x1tbh5bv",
|
|
95
84
|
$$css: true
|
|
@@ -102,8 +91,69 @@ const styles = {
|
|
|
102
91
|
overflowCircle: {
|
|
103
92
|
kg3NbH: "xnjsko4",
|
|
104
93
|
$$css: true
|
|
94
|
+
},
|
|
95
|
+
unreadDot: {
|
|
96
|
+
kAXs8y: "x1kzknox",
|
|
97
|
+
kMwMTN: "x17wrial x1q73b31",
|
|
98
|
+
kWkggS: "x1ewilqj x438xzl",
|
|
99
|
+
$$css: true
|
|
105
100
|
}
|
|
106
101
|
};
|
|
102
|
+
|
|
103
|
+
// Each size pairs an element-size height with a participant circle diameter
|
|
104
|
+
// (see AVATAR_SIZE). The padding is the inset that centers that circle in the
|
|
105
|
+
// height, applied on every side: the avatars and overflow sit the same
|
|
106
|
+
// distance from all four edges. The three round corners are half the height,
|
|
107
|
+
// which is fully round: the 9999px full-radius token would make the browser
|
|
108
|
+
// scale every corner down to fit the box (the CSS corner-overlap rule) and
|
|
109
|
+
// shrink the 2px anchor corner to nothing.
|
|
110
|
+
const sizeStyles = {
|
|
111
|
+
sm: {
|
|
112
|
+
k7Eaqz: "x1nkkqge",
|
|
113
|
+
kZKoxP: "x6k0iem",
|
|
114
|
+
kmVPX3: "x5pt662",
|
|
115
|
+
krdFHd: "x404ayl",
|
|
116
|
+
kfmiAY: "x1096wwc",
|
|
117
|
+
kT0f0o: "xjc3rfe",
|
|
118
|
+
$$css: true
|
|
119
|
+
},
|
|
120
|
+
md: {
|
|
121
|
+
k7Eaqz: "x17ydmr0",
|
|
122
|
+
kZKoxP: "x1ueg155",
|
|
123
|
+
kmVPX3: "xnvfkzk",
|
|
124
|
+
krdFHd: "x17mafka",
|
|
125
|
+
kfmiAY: "x1fefpn5",
|
|
126
|
+
kT0f0o: "x11o29ay",
|
|
127
|
+
$$css: true
|
|
128
|
+
},
|
|
129
|
+
lg: {
|
|
130
|
+
k7Eaqz: "x1je4dsv",
|
|
131
|
+
kZKoxP: "xssyfek",
|
|
132
|
+
kmVPX3: "x1fx55se",
|
|
133
|
+
krdFHd: "xgwm7ou",
|
|
134
|
+
kfmiAY: "x7b04l7",
|
|
135
|
+
kT0f0o: "x9hxrvx",
|
|
136
|
+
$$css: true
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Participant circle diameter per pin size, matching the literals in
|
|
142
|
+
* `sizeStyles`. Avatar renders any pixel size; its typed scale lists neither
|
|
143
|
+
* 22 nor 28, hence the cast.
|
|
144
|
+
*/
|
|
145
|
+
const AVATAR_SIZE = {
|
|
146
|
+
sm: 22,
|
|
147
|
+
md: 24,
|
|
148
|
+
lg: 28
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/** The overflow ellipsis per pin size. */
|
|
152
|
+
const OVERFLOW_ICON_SIZE = {
|
|
153
|
+
sm: 'xsm',
|
|
154
|
+
md: 'xsm',
|
|
155
|
+
lg: 'sm'
|
|
156
|
+
};
|
|
107
157
|
function takeDistinctParticipants(participants, limit) {
|
|
108
158
|
const result = [];
|
|
109
159
|
const seen = new Set();
|
|
@@ -135,7 +185,8 @@ const MAX_GROUP_CIRCLES = 3;
|
|
|
135
185
|
* The caller owns grouping, representative selection, coordinates, collision
|
|
136
186
|
* handling, and the content opened by activation. Absolute placement maps the
|
|
137
187
|
* host anchor to the pin's logical bottom-start corner. The pin only owns its
|
|
138
|
-
* compact button surface and controlled visual states.
|
|
188
|
+
* compact button surface and controlled visual states. `size` sets its height
|
|
189
|
+
* on the element-size scale.
|
|
139
190
|
*
|
|
140
191
|
* @example
|
|
141
192
|
* ```
|
|
@@ -161,6 +212,7 @@ const MAX_GROUP_CIRCLES = 3;
|
|
|
161
212
|
export function CommentPin({
|
|
162
213
|
label,
|
|
163
214
|
participants,
|
|
215
|
+
size = 'sm',
|
|
164
216
|
threadCount = 1,
|
|
165
217
|
unreadCount = 0,
|
|
166
218
|
isSelected = false,
|
|
@@ -173,6 +225,8 @@ export function CommentPin({
|
|
|
173
225
|
style,
|
|
174
226
|
...rest
|
|
175
227
|
}) {
|
|
228
|
+
const resolvedSize = size === 'md' || size === 'lg' ? size : 'sm';
|
|
229
|
+
const avatarSize = AVATAR_SIZE[resolvedSize];
|
|
176
230
|
const validThreadCount = isValidThreadCount(threadCount);
|
|
177
231
|
const resolvedThreadCount = validThreadCount ? threadCount : 1;
|
|
178
232
|
const isGrouped = resolvedThreadCount > 1;
|
|
@@ -181,7 +235,7 @@ export function CommentPin({
|
|
|
181
235
|
const hasUnread = resolvedUnreadCount > 0;
|
|
182
236
|
|
|
183
237
|
// Grouped pins cap at MAX_GROUP_CIRCLES circles: every distinct participant
|
|
184
|
-
// when they fit, otherwise one fewer Avatar plus
|
|
238
|
+
// when they fit, otherwise one fewer Avatar plus an ellipsis overflow circle.
|
|
185
239
|
const distinctParticipants = takeDistinctParticipants(participants, isGrouped ? Number.POSITIVE_INFINITY : 1);
|
|
186
240
|
const hasOverflow = isGrouped && distinctParticipants.length > MAX_GROUP_CIRCLES;
|
|
187
241
|
const visibleParticipants = hasOverflow ? distinctParticipants.slice(0, MAX_GROUP_CIRCLES - 1) : distinctParticipants;
|
|
@@ -197,6 +251,13 @@ export function CommentPin({
|
|
|
197
251
|
isEnabled: hasTooltip
|
|
198
252
|
});
|
|
199
253
|
const mergedRef = useMergedRefs(ref, hasTooltip ? tooltip.ref : undefined);
|
|
254
|
+
|
|
255
|
+
// Resolved discussion leaves the content. A selected pin stays, so a thread
|
|
256
|
+
// the reader opened (or resolved from its popover) keeps its anchor until
|
|
257
|
+
// the host clears the selection.
|
|
258
|
+
if (isResolved && !isSelected) {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
200
261
|
const avatarParticipants = visibleParticipants.length > 0 ? visibleParticipants : [{
|
|
201
262
|
id: '__anonymous__',
|
|
202
263
|
name: '',
|
|
@@ -211,46 +272,62 @@ export function CommentPin({
|
|
|
211
272
|
"aria-pressed": isSelected,
|
|
212
273
|
disabled: isDisabled,
|
|
213
274
|
...mergeProps(themeProps('comment-pin', {
|
|
275
|
+
size: resolvedSize,
|
|
214
276
|
grouped: isGrouped ? 'grouped' : null,
|
|
215
277
|
unread: hasUnread ? 'unread' : null,
|
|
216
278
|
selected: isSelected ? 'selected' : null,
|
|
217
279
|
dimmed: isDimmed ? 'dimmed' : null,
|
|
218
280
|
resolved: isResolved ? 'resolved' : null,
|
|
219
281
|
disabled: isDisabled ? 'disabled' : null
|
|
220
|
-
}), focusOutlineProps.focusVisible(styles.root, interactionOverlayStyles.backgroundImage, (isGrouped || hasUnread) && styles.withCount,
|
|
282
|
+
}), focusOutlineProps.focusVisible(styles.root, sizeStyles[resolvedSize], interactionOverlayStyles.backgroundImage, (isGrouped || hasUnread) && styles.withCount, isDimmed && !isSelected && styles.dimmed, isSelected && styles.selected, isDisabled && styles.disabled, xstyle), className, style),
|
|
221
283
|
children: [/*#__PURE__*/_jsx("span", {
|
|
222
284
|
"aria-hidden": "true",
|
|
223
285
|
...{
|
|
224
|
-
|
|
225
|
-
|
|
286
|
+
0: {
|
|
287
|
+
className: "x3nfvp2 x6s0dn4 x2lah0s"
|
|
288
|
+
},
|
|
289
|
+
1: {
|
|
290
|
+
className: "x3nfvp2 x6s0dn4 x2lah0s xe9ewy2"
|
|
291
|
+
}
|
|
292
|
+
}[!!isGrouped << 0],
|
|
226
293
|
children: isGrouped ? /*#__PURE__*/_jsxs(AvatarGroup, {
|
|
227
|
-
size:
|
|
294
|
+
size: avatarSize,
|
|
228
295
|
children: [avatarParticipants.map(participant => /*#__PURE__*/_jsx(Avatar, {
|
|
229
296
|
name: participant.name,
|
|
230
297
|
src: participant.avatarSrc,
|
|
231
298
|
tooltip: false
|
|
232
299
|
}, participant.id)), overflowCount > 0 ? /*#__PURE__*/_jsx(AvatarGroupOverflow, {
|
|
233
300
|
count: overflowCount,
|
|
234
|
-
xstyle: styles.overflowCircle
|
|
301
|
+
xstyle: styles.overflowCircle,
|
|
302
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
303
|
+
icon: "moreHorizontal",
|
|
304
|
+
size: OVERFLOW_ICON_SIZE[resolvedSize]
|
|
305
|
+
})
|
|
235
306
|
}) : null]
|
|
236
307
|
}) : avatarParticipants.map(participant => /*#__PURE__*/_jsx(Avatar, {
|
|
237
308
|
name: participant.name,
|
|
238
309
|
src: participant.avatarSrc,
|
|
239
|
-
size:
|
|
310
|
+
size: avatarSize,
|
|
240
311
|
tooltip: false
|
|
241
312
|
}, participant.id))
|
|
242
|
-
}), hasUnread ? /*#__PURE__*/
|
|
243
|
-
"aria-hidden": "true",
|
|
244
|
-
...{
|
|
245
|
-
className: "x1kzknox x3nfvp2 x6s0dn4 xl56j7k x9f619 x16asifk x1grt7ep x7a5moj xjspbzw x1ewilqj x1jzqe4 x17wrial x1k5gbb1 xss6m8b xo5v014"
|
|
246
|
-
},
|
|
247
|
-
children: resolvedUnreadCount
|
|
248
|
-
}) : isGrouped ? /*#__PURE__*/_jsx("span", {
|
|
313
|
+
}), hasUnread || isGrouped ? /*#__PURE__*/_jsxs("span", {
|
|
249
314
|
"aria-hidden": "true",
|
|
250
315
|
...{
|
|
251
|
-
className: "
|
|
316
|
+
className: "x3nfvp2 x6s0dn4 xzye2dw x1nryj5t"
|
|
252
317
|
},
|
|
253
|
-
children:
|
|
318
|
+
children: [isGrouped ? /*#__PURE__*/_jsx("span", {
|
|
319
|
+
...{
|
|
320
|
+
className: "x1heor9g xss6m8b"
|
|
321
|
+
},
|
|
322
|
+
children: resolvedThreadCount
|
|
323
|
+
}) : null, hasUnread ?
|
|
324
|
+
/*#__PURE__*/
|
|
325
|
+
// Decorative: the button's label carries the unread context.
|
|
326
|
+
_jsx(StatusDot, {
|
|
327
|
+
variant: "accent",
|
|
328
|
+
label: "",
|
|
329
|
+
xstyle: styles.unreadDot
|
|
330
|
+
}) : null]
|
|
254
331
|
}) : null]
|
|
255
332
|
});
|
|
256
333
|
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListInput.d.ts","sourceRoot":"","sources":["../../src/ListInput/ListInput.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ListInput.d.ts","sourceRoot":"","sources":["../../src/ListInput/ListInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -476,6 +476,25 @@ export function ListInput({
|
|
|
476
476
|
announce(t('@astryx.listInput.announceReorderCancelled'));
|
|
477
477
|
}
|
|
478
478
|
}, [isDisabled, isLoading, announce, t]);
|
|
479
|
+
|
|
480
|
+
// A second pointer that lands anywhere during a pointer reorder (the second
|
|
481
|
+
// finger of a pinch) cancels the reorder. A pinch whose first finger slid
|
|
482
|
+
// first zooms without a pointercancel, so the drag would otherwise commit on
|
|
483
|
+
// release and drop the row at the end of the list.
|
|
484
|
+
useEffect(() => {
|
|
485
|
+
if (!isPointerReorderActive) {
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
const onPointerDown = event => {
|
|
489
|
+
const activeState = reorderStateRef.current;
|
|
490
|
+
if (activeState?.mode === 'pointer' && activeState.pointerId !== event.pointerId) {
|
|
491
|
+
setReorderState(null);
|
|
492
|
+
announce(t('@astryx.listInput.announceReorderCancelled'));
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
document.addEventListener('pointerdown', onPointerDown, true);
|
|
496
|
+
return () => document.removeEventListener('pointerdown', onPointerDown, true);
|
|
497
|
+
}, [isPointerReorderActive, announce, t]);
|
|
479
498
|
useEffect(() => {
|
|
480
499
|
const activeAnimations = activeMutationAnimationsRef.current;
|
|
481
500
|
return () => {
|
|
@@ -24,6 +24,11 @@
|
|
|
24
24
|
* and tokens wrap inside the trigger;
|
|
25
25
|
* - strings are literals (no new i18n keys; existing Core keys are reused
|
|
26
26
|
* only for the result count and the add announcement);
|
|
27
|
+
* - announcements made while a sheet is open go to a persistent polite
|
|
28
|
+
* region inside each sheet, created empty and kept mounted (spec AST-086
|
|
29
|
+
* FR3), because the shared page-body channel is not exposed while a
|
|
30
|
+
* native modal dialog is open (its Platform support section); the closed
|
|
31
|
+
* field still uses the shared channel;
|
|
27
32
|
* - no theming contract: no `power-search` theme target or selectors;
|
|
28
33
|
* - `components[type].Token` overrides receive Core's PowerSearchTokenProps,
|
|
29
34
|
* which carry no `timezoneID`; the built-in token renders Core `Token`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MobilePowerSearch.d.ts","sourceRoot":"","sources":["../../src/MobilePowerSearch/MobilePowerSearch.tsx"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"MobilePowerSearch.d.ts","sourceRoot":"","sources":["../../src/MobilePowerSearch/MobilePowerSearch.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,OAAO,KAAK,EAAE,EAQZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAGlD,OAAO,EAML,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAuB,KAAK,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AAI5E,OAAO,KAAK,EAEV,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EAEjB,iBAAiB,EACjB,iBAAiB,EAEjB,eAAe,EAChB,MAAM,gCAAgC,CAAC;AAyCxC,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAClD,SAAS,CAAC,WAAW,CAAC,EACtB,UAAU,CACX;IACC,yEAAyE;IACzE,MAAM,EAAE,iBAAiB,CAAC;IAC1B,gCAAgC;IAChC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAC1C,8EAA8E;IAC9E,QAAQ,EAAE,CACR,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,UAAU,EAAE,qBAAqB,EACjC,KAAK,EAAE,MAAM,KACV,IAAI,CAAC;IACV,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mFAAmF;IACnF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sCAAsC;IACtC,SAAS,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IACjC,sDAAsD;IACtD,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACxC,kDAAkD;IAClD,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACvC,yBAAyB;IACzB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wGAAwG;IACxG,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,yCAAyC;IACzC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,qEAAqE;IACrE,SAAS,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACzC,uCAAuC;IACvC,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,yDAAyD;IACzD,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACpC;AAmTD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EAAE,UAAU,EAClB,OAAO,EACP,QAAQ,EACR,KAAK,EAAE,cAAc,EACrB,aAAoB,EACpB,WAAW,EAAE,oBAAoB,EACjC,YAAoB,EACpB,QAAe,EACf,UAAkB,EAClB,UAAkB,EAClB,eAAe,EACf,SAAS,EACT,OAAO,EACP,MAAM,EACN,MAAM,EACN,aAA0B,EAC1B,cAAmB,EACnB,oBAAoB,EACpB,gBAA6C,EAC7C,sBAAsB,EACtB,UAAU,EACV,UAAU,EACV,WAAW,EACX,GAAG,EACH,SAAS,EACT,IAAI,EAAE,QAAQ,EACd,aAAa,EAAE,MAAM,EACrB,MAAM,EACN,SAAS,EACT,KAAK,EACL,UAAU,EAAE,kBAAkB,GAC/B,EAAE,sBAAsB,qBAuvCxB;yBAvxCe,iBAAiB"}
|
|
@@ -28,6 +28,11 @@
|
|
|
28
28
|
* and tokens wrap inside the trigger;
|
|
29
29
|
* - strings are literals (no new i18n keys; existing Core keys are reused
|
|
30
30
|
* only for the result count and the add announcement);
|
|
31
|
+
* - announcements made while a sheet is open go to a persistent polite
|
|
32
|
+
* region inside each sheet, created empty and kept mounted (spec AST-086
|
|
33
|
+
* FR3), because the shared page-body channel is not exposed while a
|
|
34
|
+
* native modal dialog is open (its Platform support section); the closed
|
|
35
|
+
* field still uses the shared channel;
|
|
31
36
|
* - no theming contract: no `power-search` theme target or selectors;
|
|
32
37
|
* - `components[type].Token` overrides receive Core's PowerSearchTokenProps,
|
|
33
38
|
* which carry no `timezoneID`; the built-in token renders Core `Token`
|
|
@@ -67,6 +72,7 @@ import { Text } from '@astryxdesign/core/Text';
|
|
|
67
72
|
import { TextInput } from '@astryxdesign/core/TextInput';
|
|
68
73
|
import { Token } from '@astryxdesign/core/Token';
|
|
69
74
|
import { useTooltip } from '@astryxdesign/core/Tooltip';
|
|
75
|
+
import { VisuallyHidden } from '@astryxdesign/core/VisuallyHidden';
|
|
70
76
|
import { useAnnounce, useDevWarning, useMergedRefs } from '@astryxdesign/core/hooks';
|
|
71
77
|
import { useLocale, useTranslator } from '@astryxdesign/core/i18n';
|
|
72
78
|
import '@astryxdesign/core/theme/tokens.stylex';
|
|
@@ -146,6 +152,9 @@ function resolveDraftFilterIndex(filters, draft) {
|
|
|
146
152
|
const SEARCHABLE_FIELD_COUNT = 8;
|
|
147
153
|
const DEFAULT_MAX_SEARCH_RESULTS = 10;
|
|
148
154
|
const MAX_BROWSE_MENU_ITEMS = 1000;
|
|
155
|
+
// How long a message stays in the sheets' live region; the shared channel
|
|
156
|
+
// clears on the same schedule.
|
|
157
|
+
const SHEET_ANNOUNCEMENT_CLEAR_MS = 2000;
|
|
149
158
|
|
|
150
159
|
// =============================================================================
|
|
151
160
|
// Token
|
|
@@ -235,7 +244,62 @@ export function MobilePowerSearch({
|
|
|
235
244
|
const config = useMobilePowerSearchConfig(configProp);
|
|
236
245
|
const t = useTranslator();
|
|
237
246
|
const locale = useLocale();
|
|
238
|
-
const
|
|
247
|
+
const announceOnPage = useAnnounce();
|
|
248
|
+
// While a sheet is open the page-body live region is not exposed (the
|
|
249
|
+
// sheets are native modal dialogs), so a message then goes to the polite
|
|
250
|
+
// region rendered inside the sheets; `step` is read through a ref because
|
|
251
|
+
// the add path changes the step in the same tick it announces.
|
|
252
|
+
const [sheetAnnouncement, setSheetAnnouncement] = useState('');
|
|
253
|
+
const sheetAnnouncementFrameRef = useRef(null);
|
|
254
|
+
const pendingSheetMessagesRef = useRef([]);
|
|
255
|
+
const sheetAnnouncementClearRef = useRef(null);
|
|
256
|
+
const stepRef = useRef(null);
|
|
257
|
+
const announce = useCallback(message => {
|
|
258
|
+
if (stepRef.current == null) {
|
|
259
|
+
announceOnPage(message);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
// Clear, then write on the next frame so the same words announce again
|
|
263
|
+
// (FR6: a new occasion), and clear shortly after so stale text does not
|
|
264
|
+
// linger in a sheet that opens later (FR3). Messages that arrive while
|
|
265
|
+
// the frame is pending are joined in order into that one write, the way
|
|
266
|
+
// the shared channel joins them (FR9), so an add and the result count
|
|
267
|
+
// it changes in the same commit are both heard.
|
|
268
|
+
pendingSheetMessagesRef.current.push(message);
|
|
269
|
+
if (sheetAnnouncementFrameRef.current != null) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
if (sheetAnnouncementClearRef.current != null) {
|
|
273
|
+
clearTimeout(sheetAnnouncementClearRef.current);
|
|
274
|
+
sheetAnnouncementClearRef.current = null;
|
|
275
|
+
}
|
|
276
|
+
setSheetAnnouncement('');
|
|
277
|
+
sheetAnnouncementFrameRef.current = requestAnimationFrame(() => {
|
|
278
|
+
sheetAnnouncementFrameRef.current = null;
|
|
279
|
+
const joined = pendingSheetMessagesRef.current.join(' ');
|
|
280
|
+
pendingSheetMessagesRef.current = [];
|
|
281
|
+
setSheetAnnouncement(joined);
|
|
282
|
+
sheetAnnouncementClearRef.current = setTimeout(() => {
|
|
283
|
+
sheetAnnouncementClearRef.current = null;
|
|
284
|
+
setSheetAnnouncement('');
|
|
285
|
+
}, SHEET_ANNOUNCEMENT_CLEAR_MS);
|
|
286
|
+
});
|
|
287
|
+
}, [announceOnPage]);
|
|
288
|
+
// Owns the sheet announcer's frame and clear timer: released on teardown,
|
|
289
|
+
// with the refs and the pending queue reset, so an Effect teardown that is
|
|
290
|
+
// not an unmount (an <Activity> hide) leaves no cancelled id behind that
|
|
291
|
+
// would block later in-sheet announcements.
|
|
292
|
+
useEffect(() => () => {
|
|
293
|
+
if (sheetAnnouncementFrameRef.current != null) {
|
|
294
|
+
cancelAnimationFrame(sheetAnnouncementFrameRef.current);
|
|
295
|
+
sheetAnnouncementFrameRef.current = null;
|
|
296
|
+
}
|
|
297
|
+
if (sheetAnnouncementClearRef.current != null) {
|
|
298
|
+
clearTimeout(sheetAnnouncementClearRef.current);
|
|
299
|
+
sheetAnnouncementClearRef.current = null;
|
|
300
|
+
}
|
|
301
|
+
pendingSheetMessagesRef.current = [];
|
|
302
|
+
}, []);
|
|
239
303
|
const triggerLabel = labelFromProps ?? 'Manage filters';
|
|
240
304
|
const fieldPlaceholder = placeholderFromProps ?? 'Filters…';
|
|
241
305
|
const contentSearchPlaceholder = placeholderFromProps ?? 'Search…';
|
|
@@ -244,6 +308,8 @@ export function MobilePowerSearch({
|
|
|
244
308
|
const hasContentSearch = contentSearchOperator?.value.type === 'string';
|
|
245
309
|
const contentSearchSource = useMemo(() => createContentSearchSource(config, t, maxSearchResults), [config, maxSearchResults, t]);
|
|
246
310
|
const triggerId = useId();
|
|
311
|
+
const triggerLabelId = useId();
|
|
312
|
+
const triggerContentId = useId();
|
|
247
313
|
const statusMessageId = useId();
|
|
248
314
|
const contentResultsId = useId();
|
|
249
315
|
const triggerRef = useRef(null);
|
|
@@ -258,6 +324,7 @@ export function MobilePowerSearch({
|
|
|
258
324
|
const pendingSheetFocusRef = useRef(null);
|
|
259
325
|
const pendingMutationFocusRef = useRef(false);
|
|
260
326
|
const [step, setStep] = useState(null);
|
|
327
|
+
stepRef.current = step;
|
|
261
328
|
// The draft outlives a step change on purpose: the switcher keeps the
|
|
262
329
|
// outgoing sheet mounted while the incoming one enters, and clearing the
|
|
263
330
|
// draft with the step would blank that sheet mid-transition.
|
|
@@ -667,12 +734,21 @@ export function MobilePowerSearch({
|
|
|
667
734
|
}
|
|
668
735
|
return resultCount;
|
|
669
736
|
}, [resultCount, t]);
|
|
670
|
-
|
|
737
|
+
|
|
738
|
+
// This Effect synchronizes a polite live region with the result count: the
|
|
739
|
+
// shared page-body one while the field is closed, the sheets' own while a
|
|
740
|
+
// sheet is open. A count present on mount is not announced unprompted, and
|
|
741
|
+
// the guard compares against the last announced text rather than a mounted
|
|
742
|
+
// flag, so StrictMode's effect replay announces nothing either (FR6). It
|
|
743
|
+
// needs no cleanup of its own: on the open-sheet path `announce` starts a
|
|
744
|
+
// frame and a clear timer, which the sheet announcer's teardown Effect and
|
|
745
|
+
// the next write release.
|
|
746
|
+
const announcedResultCountRef = useRef(resultCountText);
|
|
671
747
|
useEffect(() => {
|
|
672
|
-
if (
|
|
673
|
-
hasMountedRef.current = true;
|
|
748
|
+
if (resultCountText === announcedResultCountRef.current) {
|
|
674
749
|
return;
|
|
675
750
|
}
|
|
751
|
+
announcedResultCountRef.current = resultCountText;
|
|
676
752
|
if (resultCountText != null) {
|
|
677
753
|
announce(resultCountText);
|
|
678
754
|
}
|
|
@@ -758,10 +834,25 @@ export function MobilePowerSearch({
|
|
|
758
834
|
const isEditorDisabled = isDisabled || isReadOnly;
|
|
759
835
|
const isSaveDisabled = isEditorDisabled || draft?.operator == null || draft.value == null;
|
|
760
836
|
const isDraftRenderable = draft != null && draftField != null && draftOperator != null;
|
|
837
|
+
|
|
838
|
+
// One persistent polite region per sheet, created empty and kept mounted
|
|
839
|
+
// while its text changes (FR3), because the shared page-body channel is
|
|
840
|
+
// not exposed while a native modal dialog is open; only the active sheet's
|
|
841
|
+
// dialog is exposed, so a message is heard once. A polite status region
|
|
842
|
+
// needs no name to announce, so it carries none rather than one assembled
|
|
843
|
+
// from the label and a literal.
|
|
844
|
+
const sheetStatus = /*#__PURE__*/_jsx(VisuallyHidden, {
|
|
845
|
+
role: "status",
|
|
846
|
+
"aria-live": "polite",
|
|
847
|
+
"aria-atomic": "true",
|
|
848
|
+
"data-testid": "mobile-power-search-sheet-status",
|
|
849
|
+
children: sheetAnnouncement
|
|
850
|
+
});
|
|
761
851
|
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
762
852
|
children: [/*#__PURE__*/_jsxs(Field, {
|
|
763
853
|
ref: ref,
|
|
764
854
|
label: triggerLabel,
|
|
855
|
+
labelID: triggerLabelId,
|
|
765
856
|
isLabelHidden: isLabelHidden,
|
|
766
857
|
inputID: triggerId,
|
|
767
858
|
isDisabled: isDisabled,
|
|
@@ -783,6 +874,7 @@ export function MobilePowerSearch({
|
|
|
783
874
|
"aria-disabled": isDisabled ? true : undefined,
|
|
784
875
|
...stylex.props(inputWrapperStyles.base, styles.wrapper, filters.length > 0 && styles.wrapperWithTokens, sizeStyles[size], isDisabled && inputWrapperStyles.disabled, status && inputStatusBorderStyles[status.type], status && !isDisabled && inputStatusHoverShadowStyles[status.type], status && inputStatusFocusWithinStyles[status.type]),
|
|
785
876
|
children: [/*#__PURE__*/_jsxs("div", {
|
|
877
|
+
id: triggerContentId,
|
|
786
878
|
...{
|
|
787
879
|
className: "x1n2onr6 xeuugli x1iyjqo2 x78zum5 x6s0dn4 x1a02dak x1lfs0n9 xajebq8"
|
|
788
880
|
},
|
|
@@ -807,6 +899,7 @@ export function MobilePowerSearch({
|
|
|
807
899
|
"aria-disabled": isDisabled ? true : undefined,
|
|
808
900
|
"aria-haspopup": "dialog",
|
|
809
901
|
"aria-expanded": step != null,
|
|
902
|
+
"aria-labelledby": `${triggerLabelId} ${triggerContentId}`,
|
|
810
903
|
"aria-describedby": triggerDescribedBy,
|
|
811
904
|
...{
|
|
812
905
|
0: {
|
|
@@ -842,7 +935,7 @@ export function MobilePowerSearch({
|
|
|
842
935
|
...{
|
|
843
936
|
className: "x78zum5 xdt5ytf x1us19tq xc8icb0"
|
|
844
937
|
},
|
|
845
|
-
children: [/*#__PURE__*/_jsx("div", {
|
|
938
|
+
children: [sheetStatus, /*#__PURE__*/_jsx("div", {
|
|
846
939
|
...{
|
|
847
940
|
className: "x7wzq59 x13vifvy x1vjfegm x78zum5 xdt5ytf xjcht0a x1adxfkp xvmdzux x1pzlopt x10xzikg"
|
|
848
941
|
},
|
|
@@ -939,7 +1032,7 @@ export function MobilePowerSearch({
|
|
|
939
1032
|
...{
|
|
940
1033
|
className: "x78zum5 xdt5ytf x1us19tq xc8icb0"
|
|
941
1034
|
},
|
|
942
|
-
children: [/*#__PURE__*/_jsxs("div", {
|
|
1035
|
+
children: [sheetStatus, /*#__PURE__*/_jsxs("div", {
|
|
943
1036
|
...{
|
|
944
1037
|
className: "x7wzq59 x13vifvy x1vjfegm x78zum5 xdt5ytf xjcht0a x1adxfkp xvmdzux x1pzlopt x10xzikg"
|
|
945
1038
|
},
|
|
@@ -1104,7 +1197,7 @@ export function MobilePowerSearch({
|
|
|
1104
1197
|
...{
|
|
1105
1198
|
className: "x78zum5 xdt5ytf x1us19tq xc8icb0"
|
|
1106
1199
|
},
|
|
1107
|
-
children: [/*#__PURE__*/_jsx("div", {
|
|
1200
|
+
children: [sheetStatus, /*#__PURE__*/_jsx("div", {
|
|
1108
1201
|
...{
|
|
1109
1202
|
className: "x7wzq59 x13vifvy x1vjfegm x78zum5 xdt5ytf xjcht0a x1adxfkp xvmdzux x1pzlopt x10xzikg"
|
|
1110
1203
|
},
|