@astryxdesign/lab 0.7.5-canary.fd0aba8 → 0.7.6-canary.0d71e8d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +1 -1
  2. package/dist/CircularProgress/CircularProgress.d.ts +2 -1
  3. package/dist/CircularProgress/CircularProgress.d.ts.map +1 -1
  4. package/dist/CircularProgress/CircularProgress.js +293 -16
  5. package/dist/CommentPin/CommentPin.d.ts.map +1 -1
  6. package/dist/CommentPin/CommentPin.js +37 -3
  7. package/dist/Comments/CommentComposer.d.ts.map +1 -1
  8. package/dist/Comments/CommentComposer.js +10 -3
  9. package/dist/Comments/CommentParts.d.ts +9 -2
  10. package/dist/Comments/CommentParts.d.ts.map +1 -1
  11. package/dist/Comments/CommentParts.js +32 -15
  12. package/dist/Comments/CommentRow.d.ts.map +1 -1
  13. package/dist/Comments/CommentRow.js +5 -2
  14. package/dist/Comments/Comments.d.ts.map +1 -1
  15. package/dist/Comments/Comments.js +10 -1
  16. package/dist/Comments/CommentsContext.d.ts +2 -0
  17. package/dist/Comments/CommentsContext.d.ts.map +1 -1
  18. package/dist/Comments/CommentsContext.js +7 -3
  19. package/dist/Comments/useStatusAnnouncement.d.ts +26 -0
  20. package/dist/Comments/useStatusAnnouncement.d.ts.map +1 -0
  21. package/dist/Comments/useStatusAnnouncement.js +48 -0
  22. package/dist/lab.css +8 -1
  23. package/package.json +4 -4
  24. package/src/Chat/__tests__/ChatTypingIndicator.a11y.chromium.spec.ts +20 -8
  25. package/src/CircularProgress/CircularProgress.test.tsx +389 -10
  26. package/src/CircularProgress/CircularProgress.tsx +364 -20
  27. package/src/CircularProgress/__tests__/CircularProgress.a11y.chromium.spec.ts +21 -9
  28. package/src/CircularProgress/__tests__/CircularProgress.a11y.states.ts +2 -2
  29. package/src/CircularProgress/__tests__/CircularProgressMotion.a11y.chromium.spec.ts +886 -0
  30. package/src/CommentPin/CommentPin.doc.mjs +6 -4
  31. package/src/CommentPin/CommentPin.spec.md +14 -13
  32. package/src/CommentPin/CommentPin.test.tsx +177 -1
  33. package/src/CommentPin/CommentPin.tsx +44 -1
  34. package/src/Comments/CommentComposer.test.tsx +54 -4
  35. package/src/Comments/CommentComposer.tsx +10 -2
  36. package/src/Comments/CommentParts.tsx +50 -14
  37. package/src/Comments/CommentRow.tsx +5 -6
  38. package/src/Comments/Comments.doc.mjs +1 -1
  39. package/src/Comments/Comments.test.tsx +339 -13
  40. package/src/Comments/Comments.tsx +16 -1
  41. package/src/Comments/CommentsContext.tsx +13 -1
  42. package/src/Comments/useStatusAnnouncement.ts +57 -0
package/README.md CHANGED
@@ -24,7 +24,7 @@ See the **[Component Lifecycle](https://github.com/meta/astryx/wiki/Component-Li
24
24
 
25
25
  The [Accessibility Checklist](https://github.com/meta/astryx/wiki/Accessibility-Checklist) is a hard requirement for graduating to core — every item, verified in the promotion PR, alongside the hardening bar linked above.
26
26
 
27
- Lab components get the same scan coverage as core (the `pr-a11y` axe audit and the weekly full scan run against lab too), but a11y findings on a lab component do not block lab merges — they block **promotion**. Iterate freely in lab; clear the checklist to graduate.
27
+ Lab components get the same scan coverage as core (the `pr-a11y` axe audit and the full release-check scan run against lab too), but a11y findings on a lab component do not block lab merges — they block **promotion**. Iterate freely in lab; clear the checklist to graduate.
28
28
 
29
29
  ## Usage
30
30
 
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @file CircularProgress.tsx
3
- * @input Uses React, useId, stylex, SVG, color/spacing/duration/ease tokens
3
+ * @input Uses React (useId, refs, layout effects), stylex, SVG, Web
4
+ * Animations, color/spacing/duration/ease tokens
4
5
  * @output Exports CircularProgress component, CircularProgressProps, CircularProgressSize, CircularProgressVariant types
5
6
  * @position Core implementation; consumed by index.ts
6
7
  *
@@ -1 +1 @@
1
- {"version":3,"file":"CircularProgress.d.ts","sourceRoot":"","sources":["../../src/CircularProgress/CircularProgress.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAQ,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAY5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAGlD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,IAAI,CAAC;IACb,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;IACZ,OAAO,EAAE,IAAI,CAAC;CACf;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,0BAA0B,CAAC;AAEvE,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAQtD,MAAM,WAAW,qBAAsB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACtE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1D;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,uBAAuB,CAAC;IAClC;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAuKD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAS,EACT,GAAS,EACT,KAAK,EACL,aAAoB,EACpB,aAAqB,EACrB,gBAA0C,EAC1C,QAAQ,EACR,IAAW,EACX,OAAkB,EAClB,eAAuB,EACvB,UAAkB,EAClB,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,UAAU,EACzB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,qBAAqB,+BAuHvB;yBAzIe,gBAAgB"}
1
+ {"version":3,"file":"CircularProgress.d.ts","sourceRoot":"","sources":["../../src/CircularProgress/CircularProgress.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAiC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAYrE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAGlD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,IAAI,CAAC;IACb,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;IACZ,OAAO,EAAE,IAAI,CAAC;CACf;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,0BAA0B,CAAC;AAEvE,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAWtD,MAAM,WAAW,qBAAsB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACtE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1D;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,uBAAuB,CAAC;IAClC;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAmWD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAS,EACT,GAAS,EACT,KAAK,EACL,aAAoB,EACpB,aAAqB,EACrB,gBAA0C,EAC1C,QAAQ,EACR,IAAW,EACX,OAAkB,EAClB,eAAuB,EACvB,UAAkB,EAClB,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,UAAU,EACzB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,qBAAqB,+BA+QvB;yBAjSe,gBAAgB"}
@@ -4,7 +4,8 @@
4
4
 
5
5
  /**
6
6
  * @file CircularProgress.tsx
7
- * @input Uses React, useId, stylex, SVG, color/spacing/duration/ease tokens
7
+ * @input Uses React (useId, refs, layout effects), stylex, SVG, Web
8
+ * Animations, color/spacing/duration/ease tokens
8
9
  * @output Exports CircularProgress component, CircularProgressProps, CircularProgressSize, CircularProgressVariant types
9
10
  * @position Core implementation; consumed by index.ts
10
11
  *
@@ -14,7 +15,7 @@
14
15
  * - /packages/lab/src/CircularProgress/index.ts (exports if types change)
15
16
  * - /apps/storybook/stories/CircularProgress.stories.tsx (storybook stories)
16
17
  */
17
- import { useId } from 'react';
18
+ import { useId, useLayoutEffect, useRef } from 'react';
18
19
  import * as stylex from '@stylexjs/stylex';
19
20
  import '@astryxdesign/core/theme/tokens.stylex';
20
21
  import { colorVars, durationVars, easeVars, fontWeightVars, spacingVars, typeScaleVars } from '@astryxdesign/core/theme/tokens.stylex';
@@ -35,6 +36,8 @@ import { themeProps } from '@astryxdesign/core/utils';
35
36
  * ```
36
37
  */
37
38
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
39
+ /** How far a turning layer's drawing reaches past the ring's box, in px. */
40
+ const FILL_BLEED = 2;
38
41
  const SIZE_CONFIG = {
39
42
  sm: {
40
43
  diameter: 32,
@@ -83,9 +86,11 @@ const styles = {
83
86
  $$css: true
84
87
  },
85
88
  fill: {
86
- kDwRjp: "xbh8q5q",
87
- kU5bRw: "x1owpc8m",
88
- k1ekBW: "xxnu56j",
89
+ kVAEAm: "x10l6tqk",
90
+ kpwlN0: "x10a8y8t",
91
+ kVQacm: "xb3r6kr",
92
+ kfzvcC: "x47corl",
93
+ k1ekBW: "x13b0p5u",
89
94
  kIyJzY: "x80gvsz",
90
95
  kAMwcw: "xlr8y92",
91
96
  $$css: true
@@ -153,6 +158,129 @@ function defaultFormatValueLabel(value, max) {
153
158
  return `${pct}%`;
154
159
  }
155
160
 
161
+ /**
162
+ * Each half-ring's turn and the leading cap's for a filled share `p` (0–1),
163
+ * and which parts show. A half-ring parked at the edge of its half (the right
164
+ * one at 0, the left one until the value passes half) is hidden, so its
165
+ * antialiased end never leaves a hairline at 6 o'clock.
166
+ */
167
+ function fillTurns(p) {
168
+ const turn = 360 * p;
169
+ return {
170
+ right: Math.min(Math.max(turn, 0), 180),
171
+ left: Math.min(Math.max(turn, 180), 360),
172
+ cap: turn,
173
+ rightShown: p > 0 ? 1 : 0,
174
+ leftShown: p > 0.5 ? 1 : 0,
175
+ caps: p > 0 ? 1 : 0
176
+ };
177
+ }
178
+
179
+ /** A CSS time (`410ms`, `0.41s`, or a list's first entry) in milliseconds. */
180
+ function parseTime(value) {
181
+ const first = value.split(',')[0]?.trim() ?? '';
182
+ const amount = Number.parseFloat(first);
183
+ if (!Number.isFinite(amount)) {
184
+ return 0;
185
+ }
186
+ return first.endsWith('ms') ? amount : amount * 1000;
187
+ }
188
+
189
+ /**
190
+ * The theme's easing as a function of time (0–1), evaluated by the browser
191
+ * itself through a detached animation, so any CSS easing works. It runs only
192
+ * where Web Animations exists (its caller returns first otherwise), on the
193
+ * fill's computed `transition-timing-function`: one easing, which a browser
194
+ * always reports as valid CSS.
195
+ */
196
+ function easingOf(easing) {
197
+ const effect = new KeyframeEffect(null, null, {
198
+ duration: 1000,
199
+ easing,
200
+ fill: 'both'
201
+ });
202
+ const probe = new Animation(effect);
203
+ return t => {
204
+ probe.currentTime = t * 1000;
205
+ return effect.getComputedTiming().progress ?? t;
206
+ };
207
+ }
208
+
209
+ /**
210
+ * Keyframes for a change from `from` to `to` (filled shares), sampled once a
211
+ * frame on the theme's easing, with an extra sample exactly where the arc
212
+ * crosses 12 or 6 o'clock so each half stops and starts on time.
213
+ */
214
+ function fillKeyframes(from, to, duration, ease) {
215
+ const count = Math.max(8, Math.ceil(duration / (1000 / 60)));
216
+ const grid = Array.from({
217
+ length: count + 1
218
+ }, (_, i) => i / count);
219
+ const at = t => from + (to - from) * ease(t);
220
+ // Where the eased path passes half (p = 0.5): a sample there, and one just
221
+ // after it, so the halves hand over on time and the left half's
222
+ // visibility steps rather than fades.
223
+ const crossings = [];
224
+ for (let i = 0; i < count; i++) {
225
+ const a = grid[i];
226
+ const b = grid[i + 1];
227
+ const fa = at(a) - 0.5;
228
+ const fb = at(b) - 0.5;
229
+ if (fa === 0) {
230
+ crossings.push(a);
231
+ } else if (fa * fb < 0) {
232
+ let low = a;
233
+ let high = b;
234
+ for (let k = 0; k < 24; k++) {
235
+ const mid = (low + high) / 2;
236
+ if ((at(low) - 0.5) * (at(mid) - 0.5) <= 0) {
237
+ high = mid;
238
+ } else {
239
+ low = mid;
240
+ }
241
+ }
242
+ crossings.push((low + high) / 2);
243
+ }
244
+ }
245
+ const times = [...new Set([...grid, ...crossings, ...crossings.map(c => c + 1e-4).filter(t => t < 1)])].sort((x, y) => x - y);
246
+ const frames = times.map(t => ({
247
+ t,
248
+ ...fillTurns(t === 1 ? to : at(t))
249
+ }));
250
+ // The sample at a crossing sits exactly on half, where the left half reads
251
+ // as hidden. Give it the side the arc is leaving instead, so the left half
252
+ // steps at once both ways: shrinking through half, it used to fade out
253
+ // from the sample before, while it still drew part of the arc (a lighter
254
+ // band between the end cap and 6 o'clock for a frame).
255
+ const onHalf = new Set(crossings);
256
+ for (let i = 1; i < frames.length; i += 1) {
257
+ if (onHalf.has(frames[i].t) || frames[i].t === 1 && to === 0.5) {
258
+ frames[i].leftShown = frames[i - 1].leftShown;
259
+ }
260
+ }
261
+ return {
262
+ right: frames.map(f => ({
263
+ offset: f.t,
264
+ transform: `rotate(${f.right}deg)`,
265
+ opacity: f.rightShown
266
+ })),
267
+ left: frames.map(f => ({
268
+ offset: f.t,
269
+ transform: `rotate(${f.left}deg)`,
270
+ opacity: f.leftShown
271
+ })),
272
+ cap: frames.map(f => ({
273
+ offset: f.t,
274
+ transform: `rotate(${f.cap}deg)`,
275
+ opacity: f.caps
276
+ })),
277
+ start: frames.map(f => ({
278
+ offset: f.t,
279
+ opacity: f.caps
280
+ }))
281
+ };
282
+ }
283
+
156
284
  /**
157
285
  * A circular/radial progress indicator that shows completion as a ring.
158
286
  *
@@ -205,7 +333,6 @@ export function CircularProgress({
205
333
  const safeMax = Number.isFinite(max) ? max : 0;
206
334
  const clampedValue = Math.min(Math.max(0, safeValue), safeMax);
207
335
  const percentage = safeMax > 0 ? clampedValue / safeMax : 0;
208
- const dashoffset = circumference * (1 - percentage);
209
336
  const valueText = formatValueLabel(clampedValue, safeMax);
210
337
  const center = diameter / 2;
211
338
  const showLabel = !isLabelHidden;
@@ -213,6 +340,89 @@ export function CircularProgress({
213
340
  const centerContent = children != null ? children : showValueLabel ? valueText : null;
214
341
  const fillVariant = isDisabled ? 'disabled' : variant;
215
342
  const trackVariant = isDisabled ? 'neutral' : variant;
343
+
344
+ // A value change turns the fill's layers with Web Animations on the
345
+ // compositor, from wherever the arc is drawn now (mid-change, the running
346
+ // change's own curve says where) to the new value, on the theme's
347
+ // duration and easing. What renders is always the resting state, so a
348
+ // first render, a render without script, or a skipped animation shows the
349
+ // value.
350
+ const fillRef = useRef(null);
351
+ const rightRef = useRef(null);
352
+ const leftRef = useRef(null);
353
+ const capRef = useRef(null);
354
+ const startRef = useRef(null);
355
+ // Where the arc is drawn: the value at rest, or, when a change is
356
+ // interrupted, the point its own curve has reached. A change's cleanup
357
+ // records it and releases the change's animations (react-component-runtime
358
+ // INV3), so the next change starts from there and an unmount or a switch to
359
+ // indeterminate leaves nothing running. While indeterminate no value is
360
+ // drawn (null): the ring draws its own arc, not the value it holds, so the
361
+ // next value draws at once instead of sweeping from that held value.
362
+ const drawn = useRef(percentage);
363
+ useLayoutEffect(() => {
364
+ const from = drawn.current;
365
+ if (isIndeterminate) {
366
+ drawn.current = null;
367
+ return;
368
+ }
369
+ if (from === null || from === percentage) {
370
+ drawn.current = percentage;
371
+ return;
372
+ }
373
+ const fill = fillRef.current;
374
+ const layers = [rightRef.current, leftRef.current, capRef.current, startRef.current];
375
+ drawn.current = percentage;
376
+ if (fill == null || layers.some(layer => typeof layer?.animate !== 'function')) {
377
+ return;
378
+ }
379
+ const style = getComputedStyle(fill);
380
+ const duration = parseTime(style.transitionDuration);
381
+ if (duration <= 0) {
382
+ return;
383
+ }
384
+ const ease = easingOf(style.transitionTimingFunction);
385
+ const frames = fillKeyframes(from, percentage, duration, ease);
386
+ const timing = {
387
+ duration,
388
+ easing: 'linear',
389
+ fill: 'backwards'
390
+ };
391
+ const [right, left, cap, start] = layers;
392
+ const animations = [right.animate(frames.right, timing), left.animate(frames.left, timing), cap.animate(frames.cap, timing), start.animate(frames.start, timing)];
393
+ return () => {
394
+ const [first] = animations;
395
+ const progress = first.playState !== 'finished' ? Number(first.effect?.getComputedTiming().progress ?? 1) : 1;
396
+ // `progress` is the change's linear time fraction; the arc is drawn on
397
+ // its easing, so the eased position is where it is.
398
+ drawn.current = from + (percentage - from) * ease(progress);
399
+ for (const animation of animations) {
400
+ animation.cancel();
401
+ }
402
+ };
403
+ }, [percentage, isIndeterminate]);
404
+ const turns = fillTurns(percentage);
405
+ // One half of the ring's stroke, from 6 o'clock clockwise to 12 (the left
406
+ // half) before its layer turns; butt ends, the caps are drawn apart.
407
+ const bleedBox = `${-FILL_BLEED} ${-FILL_BLEED} ${diameter + 2 * FILL_BLEED} ${diameter + 2 * FILL_BLEED}`;
408
+ const halfRing = /*#__PURE__*/_jsx("svg", {
409
+ width: diameter + 2 * FILL_BLEED,
410
+ height: diameter + 2 * FILL_BLEED,
411
+ viewBox: bleedBox,
412
+ ...{
413
+ className: "x1lliihq xbh8q5q xy6n8ys"
414
+ },
415
+ children: /*#__PURE__*/_jsx("circle", {
416
+ cx: center,
417
+ cy: center,
418
+ r: radius,
419
+ strokeWidth: strokeWidth,
420
+ strokeDasharray: `${circumference / 2} ${circumference}`,
421
+ transform: `rotate(90 ${center} ${center})`
422
+ })
423
+ });
424
+ // A round cap at 12 o'clock on the ring's centerline (a zero-length stroke).
425
+ const capPath = `M ${center} ${strokeWidth / 2} h 0`;
216
426
  return /*#__PURE__*/_jsxs("div", {
217
427
  ref: ref,
218
428
  ...mergeProps(themeProps('circular-progress', {
@@ -274,16 +484,83 @@ export function CircularProgress({
274
484
  cy: center,
275
485
  r: radius,
276
486
  strokeWidth: strokeWidth
277
- }) : /*#__PURE__*/_jsx("circle", {
278
- ...mergeProps(themeProps('circular-progress-fill', {
279
- variant: fillVariant
280
- }), stylex.props(styles.fill, variantStyles[fillVariant])),
281
- cx: center,
282
- cy: center,
283
- r: radius,
284
- strokeWidth: strokeWidth,
285
- strokeDasharray: circumference,
286
- strokeDashoffset: dashoffset
487
+ }) : null]
488
+ }), isIndeterminate ? null :
489
+ /*#__PURE__*/
490
+ // The determinate fill (see `styles.fill`). Its stroke color is
491
+ // set on the theming target and inherited by every part.
492
+ _jsxs("span", {
493
+ ref: fillRef,
494
+ "aria-hidden": "true",
495
+ ...mergeProps(themeProps('circular-progress-fill', {
496
+ variant: fillVariant
497
+ }), stylex.props(styles.fill, variantStyles[fillVariant])),
498
+ children: [/*#__PURE__*/_jsx("span", {
499
+ ...{
500
+ className: "x10l6tqk x13vifvy x3hqpx7 x5yr21d xb3r6kr x1nrll8i"
501
+ },
502
+ children: /*#__PURE__*/_jsx("span", {
503
+ ref: rightRef,
504
+ ...{
505
+ className: "x10l6tqk x13vifvy x75ztot x5yr21d x1q1rmc8 xb5nubl"
506
+ },
507
+ style: {
508
+ transform: `rotate(${turns.right}deg)`,
509
+ opacity: turns.rightShown
510
+ },
511
+ children: halfRing
512
+ })
513
+ }), /*#__PURE__*/_jsx("span", {
514
+ ...{
515
+ className: "x10l6tqk x13vifvy x3hqpx7 x5yr21d xb3r6kr xu96u03"
516
+ },
517
+ children: /*#__PURE__*/_jsx("span", {
518
+ ref: leftRef,
519
+ ...{
520
+ className: "x10l6tqk x13vifvy x75ztot x5yr21d x1q1rmc8 xu96u03"
521
+ },
522
+ style: {
523
+ transform: `rotate(${turns.left}deg)`,
524
+ opacity: turns.leftShown
525
+ },
526
+ children: halfRing
527
+ })
528
+ }), /*#__PURE__*/_jsx("svg", {
529
+ width: diameter,
530
+ height: diameter,
531
+ viewBox: `0 0 ${diameter} ${diameter}`,
532
+ ...{
533
+ className: "x10l6tqk x10a8y8t x1q1rmc8 x1lliihq xbh8q5q x1owpc8m"
534
+ },
535
+ children: /*#__PURE__*/_jsx("path", {
536
+ ref: startRef,
537
+ d: capPath,
538
+ strokeWidth: strokeWidth,
539
+ style: {
540
+ opacity: turns.caps
541
+ }
542
+ })
543
+ }), /*#__PURE__*/_jsx("span", {
544
+ ref: capRef,
545
+ ...{
546
+ className: "x10l6tqk x10a8y8t x1q1rmc8"
547
+ },
548
+ style: {
549
+ transform: `rotate(${turns.cap}deg)`,
550
+ opacity: turns.caps
551
+ },
552
+ children: /*#__PURE__*/_jsx("svg", {
553
+ width: diameter + 2 * FILL_BLEED,
554
+ height: diameter + 2 * FILL_BLEED,
555
+ viewBox: bleedBox,
556
+ ...{
557
+ className: "x1owpc8m x1lliihq xbh8q5q xy6n8ys"
558
+ },
559
+ children: /*#__PURE__*/_jsx("path", {
560
+ d: capPath,
561
+ strokeWidth: strokeWidth
562
+ })
563
+ })
287
564
  })]
288
565
  }), centerContent != null && /*#__PURE__*/_jsx("div", {
289
566
  ...{
@@ -1 +1 @@
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"}
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;AA6OD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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,CAwLnC;yBAvMe,UAAU"}
@@ -88,6 +88,11 @@ const styles = {
88
88
  kSiTet: "xyd83as x1tbh5bv",
89
89
  $$css: true
90
90
  },
91
+ disabledUnselected: {
92
+ kVAM5u: "x9r1u3d xmnqt3w",
93
+ kMwMTN: "xv1l7n4 x1bhcspo",
94
+ $$css: true
95
+ },
91
96
  overflowCircle: {
92
97
  kg3NbH: "xnjsko4",
93
98
  $$css: true
@@ -269,8 +274,37 @@ export function CommentPin({
269
274
  ref: mergedRef,
270
275
  type: "button",
271
276
  "aria-label": label,
272
- "aria-pressed": isSelected,
273
- disabled: isDisabled,
277
+ "aria-pressed": isSelected
278
+ // A disabled pin keeps its tab stop and is announced as disabled through
279
+ // aria-disabled instead of the native attribute (spec:AST-085 FR1). The
280
+ // activation guards below keep it inert (FR2); focus is kept when the
281
+ // pin becomes disabled while focused (FR4), and the shared focus outline
282
+ // still paints, dimmed with the rest of the pin (FR6).
283
+ ,
284
+ "aria-disabled": isDisabled ? 'true' : undefined,
285
+ onClick: e => {
286
+ if (isDisabled) {
287
+ // A natively disabled element dispatched no click at all, so an
288
+ // aria-disabled pin must not reach the caller's handler, and the
289
+ // click must not leak to a clickable ancestor (annotation surface)
290
+ // the native attribute never let it reach either (FR2).
291
+ e.preventDefault();
292
+ e.stopPropagation();
293
+ return;
294
+ }
295
+ rest.onClick?.(e);
296
+ }
297
+ // The keyboard paths to activation are Enter and Space; other keys still
298
+ // reach caller handlers, as on an enabled pin (FR2).
299
+ ,
300
+ onKeyDown: e => {
301
+ if (isDisabled && (e.key === 'Enter' || e.key === ' ')) {
302
+ e.preventDefault();
303
+ e.stopPropagation();
304
+ return;
305
+ }
306
+ rest.onKeyDown?.(e);
307
+ },
274
308
  ...mergeProps(themeProps('comment-pin', {
275
309
  size: resolvedSize,
276
310
  grouped: isGrouped ? 'grouped' : null,
@@ -279,7 +313,7 @@ export function CommentPin({
279
313
  dimmed: isDimmed ? 'dimmed' : null,
280
314
  resolved: isResolved ? 'resolved' : null,
281
315
  disabled: isDisabled ? 'disabled' : null
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),
316
+ }), focusOutlineProps.focusVisible(styles.root, sizeStyles[resolvedSize], interactionOverlayStyles.backgroundImage, (isGrouped || hasUnread) && styles.withCount, isDimmed && !isSelected && styles.dimmed, isSelected && styles.selected, isDisabled && styles.disabled, isDisabled && !isSelected && styles.disabledUnselected, xstyle), className, style),
283
317
  children: [/*#__PURE__*/_jsx("span", {
284
318
  "aria-hidden": "true",
285
319
  ...{
@@ -1 +1 @@
1
- {"version":3,"file":"CommentComposer.d.ts","sourceRoot":"","sources":["../../src/Comments/CommentComposer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CommentComposer.d.ts","sourceRoot":"","sources":["../../src/Comments/CommentComposer.tsx"],"names":[],"mappings":"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"}
@@ -169,6 +169,13 @@ export function CommentComposerBase({
169
169
  }
170
170
  }, [focusKey]);
171
171
  const [actionError, setActionError] = useState();
172
+ // Counts action failures so each one mounts its own Banner: a second failure
173
+ // with the same words is a new occasion and is announced again (AST-086 FR6).
174
+ const [actionErrorSerial, setActionErrorSerial] = useState(0);
175
+ const reportActionError = content => {
176
+ setActionError(content);
177
+ setActionErrorSerial(serial => serial + 1);
178
+ };
172
179
  const [isActionPending, setIsActionPending] = useState(false);
173
180
  const [isPickerOpen, setIsPickerOpen] = useState(false);
174
181
  const updateActionPending = useCallback(nextPending => {
@@ -205,7 +212,7 @@ export function CommentComposerBase({
205
212
  }
206
213
  } catch {
207
214
  if (isMountedRef.current) {
208
- setActionError({
215
+ reportActionError({
209
216
  title: t('@astryx.commentComposer.uploadFailed'),
210
217
  actionLabel: t('@astryx.comments.retry'),
211
218
  onAction: () => beginImageUpload(files)
@@ -223,7 +230,7 @@ export function CommentComposerBase({
223
230
  }
224
231
  const images = files.filter(file => file.type.startsWith('image/'));
225
232
  if (images.length !== files.length) {
226
- setActionError({
233
+ reportActionError({
227
234
  title: t('@astryx.commentComposer.imagesOnly'),
228
235
  actionLabel: t('@astryx.commentComposer.chooseImages'),
229
236
  onAction: () => {
@@ -276,7 +283,7 @@ export function CommentComposerBase({
276
283
  ,
277
284
  onBeforeAction: () => inputRef.current?.focus(),
278
285
  "data-composer-error": "banner"
279
- }), /*#__PURE__*/_jsx(ChatComposer, {
286
+ }, error != null ? 'error' : `action-${actionErrorSerial}`), /*#__PURE__*/_jsx(ChatComposer, {
280
287
  value: value,
281
288
  onChange: onChange,
282
289
  onSubmit: submitInput,
@@ -132,10 +132,17 @@ export type ErrorBannerContent = {
132
132
  actionLabel?: string;
133
133
  onAction?: () => void;
134
134
  isActionDisabled?: boolean;
135
+ /** Its own retry is running: say nothing until the outcome (FR6). */
136
+ isRetrying?: boolean;
137
+ /** The failure was already announced elsewhere; this Banner stays silent. */
138
+ isAnnounced?: boolean;
135
139
  };
136
140
  /**
137
- * An inline failure as an error Banner. It sets role="alert" itself (Banner
138
- * adds no live-region role from `status`), so mounting it announces it.
141
+ * An inline failure as an error Banner. The Banner carries no live role: it
142
+ * mounts already holding its text, which may not be announced. The failure is
143
+ * announced once, assertively, through the shared channel instead, unless the
144
+ * Banner sits inside a live container such as the chat log, which delivers it
145
+ * (spec:AST-086 FR2, FR4, FR5).
139
146
  */
140
147
  export declare function ErrorBanner({ actionRef, content, onBeforeAction, ...dataProps }: {
141
148
  actionRef?: Ref<HTMLButtonElement>;
@@ -1 +1 @@
1
- {"version":3,"file":"CommentParts.d.ts","sourceRoot":"","sources":["../../src/Comments/CommentParts.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CommentParts.d.ts","sourceRoot":"","sources":["../../src/Comments/CommentParts.tsx"],"names":[],"mappings":"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"}