@crewlethq/ui 0.57.0 → 0.57.2

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/README.md CHANGED
@@ -205,6 +205,22 @@ places:
205
205
  - A surface that pans or zooms dispatches `LAYER_REPOSITION_EVENT` on its host
206
206
  when the content beneath it moves, and every panel anchored inside follows.
207
207
 
208
+ ## Changes in 0.57.2
209
+
210
+ **`ResultTableCard`'s first column wraps rather than cutting a long name.** It ended a long name in an ellipsis on one line, and a result's row is not a link and its cell has no title, so in a 358px assistant panel "Write the MVP plan and the first sprint" read "Write the MVP ..." with no way to read the rest. The first column now wraps between words like every other text cell and takes no width of its own, so the automatic layout shares the room by content: the name takes the most, and a short column beside it keeps its line where there is room. Figures and dates (`end` columns) still stay on one line. A host that gave the cell its own tooltip because the name was cut can drop it.
211
+
212
+ **`ChatThread`'s scroller is the containing block for what is positioned inside it.** An absolutely positioned descendant with no positioned ancestor of its own, such as a `VisuallyHidden` phrase inside a `Tag` ("Sent with"), was placed against the thread instead of its scroller: outside the scroller's clip, at its spot in the whole conversation. That gave whatever held the thread overflow to scroll (a flush `SidePanel` body read a scroll height of 4752px around a 557px thread), and a focus inside could scroll it, lifting the thread off the panel's foot over a blank band that no wheel or Jump to latest brought back. Such a descendant now scrolls and clips with the conversation.
213
+
214
+ **A flush `SidePanel` body does not scroll** (`flush`). It clips (`overflow: clip`) where it scrolled, so a focus, `scrollIntoView` or a script inside it cannot move it: what it holds owns its scrolling, as `ChatThread` does. `overflow: hidden` would not do, since a hidden box is still a scroll container that a focus can scroll. Content in a flush body that may be taller than the panel scrolls itself (`min-height: 0` in the body's column) or does not take `flush`.
215
+
216
+ ## Changes in 0.57.1
217
+
218
+ **`ResultTableCard` keeps words whole.** Its text cells inherited Table's `overflow-wrap: anywhere`, which under the card's automatic layout let a column shrink to one letter, so "Product Manager" wrapped letter by letter beside columns with room to spare. Its cells now break between words (`overflow-wrap: break-word`); figures and dates (`end` columns) stay on one line, and the first column still ends a long name in an ellipsis.
219
+
220
+ **`ProposalCard` keeps focus when it settles.** Approving or declining from the keyboard removed the focused button and left focus on the page body. When focus is in the card as it settles, it now moves to the strip that says what happened (the receipt, the declined, expired or stale notice, or the failure), or to the card itself when there is no strip. Both take focus by script only (`tabindex="-1"`) and draw the token focus ring for a keyboard reader. A reader whose focus has moved elsewhere is not pulled back. The card's own `id`, when given, is kept.
221
+
222
+ **`@crewlethq/ui/ProposalCard` carries the visually hidden style it uses.** The foot's empty live region (0.57.0) borrowed the shared visually hidden class through a bare module import, which the build drops because the package marks only stylesheets as side effects. A consumer that imported the folder alone, without `styles.css`, drew the empty region as a blank line. The folder now imports the stylesheet itself.
223
+
208
224
  ## Changes in 0.57.0
209
225
 
210
226
  **`AppShell` takes `asideModal`**, so an `overlay` aside can leave the page live beside it. `true`, the default, keeps the 0.56.0 overlay: a modal dialog behind a veil with Tab held inside. `false` draws the overlay with no veil, no trap and nothing made inert: it is a complementary region named by `asideLabel`, focus moves into it when it opens, Escape from inside it calls `onAsideClose` (unless a control inside answered the key, or a menu or dialog on the layer stack owns it), and focus goes back to what opened it if it was still inside when it closed. A column is never modal and a `sheet` always is, whatever the prop says. The aside carries `data-modal`.
@@ -1,9 +1,9 @@
1
- export { AGENT_HANDOFF_LABELS, AgentHandoffPanel } from '../chunk-GCASX3FD.js';
1
+ export { AGENT_HANDOFF_LABELS, AgentHandoffPanel } from '../chunk-G3CUCHBA.js';
2
2
  import '../chunk-AUQPBL4O.js';
3
3
  import '../chunk-JQ7IFSF6.js';
4
4
  import '../chunk-JLRXCKTS.js';
5
5
  import '../chunk-GG4QZWMQ.js';
6
- import '../chunk-HGYHWWA5.js';
6
+ import '../chunk-ALU5EGQB.js';
7
7
  import '../chunk-XODESBSR.js';
8
8
  import '../chunk-SMBKXWML.js';
9
9
  import '../chunk-FXQLNETQ.js';
@@ -1,4 +1,4 @@
1
- export { ARTIFACT_PANEL_LABELS, ArtifactPanel, ArtifactWorkspace } from '../chunk-HGYHWWA5.js';
1
+ export { ARTIFACT_PANEL_LABELS, ArtifactPanel, ArtifactWorkspace } from '../chunk-ALU5EGQB.js';
2
2
  import '../chunk-XODESBSR.js';
3
3
  import '../chunk-PQADV6P6.js';
4
4
  import '../chunk-PIYJNCN7.js';
@@ -1,4 +1,4 @@
1
- export { CHAT_THREAD_FOLLOW_WITHIN, CHAT_THREAD_LABELS, ChatThread } from '../chunk-RV2FGESF.js';
1
+ export { CHAT_THREAD_FOLLOW_WITHIN, CHAT_THREAD_LABELS, ChatThread } from '../chunk-PE7XWOUS.js';
2
2
  import '../chunk-RTPQDNW3.js';
3
3
  import '../chunk-HD4QJ2SI.js';
4
4
  import '../chunk-EA23JG6R.js';
@@ -15,8 +15,19 @@
15
15
  * THE BROWSER'S SCROLL ANCHORING IS OFF: it pins the content above the
16
16
  * reader's view, which fights a last child that keeps growing as an answer
17
17
  * streams in. ChatThread.tsx anchors to the end itself.
18
+ *
19
+ * THE SCROLLER IS THE CONTAINING BLOCK for everything positioned inside it.
20
+ * It was not, so an absolutely positioned descendant with no positioned
21
+ * ancestor of its own (a visually hidden phrase inside a tag, "Sent with")
22
+ * was placed against the thread instead: outside the scroller's clip, at its
23
+ * spot in the whole conversation, thousands of pixels below the view. That
24
+ * made whatever held the thread overflowable (a flush side panel's body read
25
+ * a scroll height of 4752px around a 557px thread), and a focus could scroll
26
+ * it, lifting the thread off the panel's foot over a blank band. Positioned
27
+ * here, such a descendant scrolls and clips with the conversation.
18
28
  */
19
29
  .crewlet-chat-thread__scroller {
30
+ position: relative;
20
31
  flex: 1;
21
32
  min-height: 0;
22
33
  overflow: auto;
@@ -1,7 +1,6 @@
1
- import type { HTMLAttributes, ReactNode } from 'react';
1
+ import { type HTMLAttributes, type ReactNode } from 'react';
2
2
  import { type ChangeListLabels, type ChangeListRow } from '../ChangeList/index.js';
3
3
  import type { DiffListLabels } from '../DiffList/index.js';
4
- import '../VisuallyHidden/index.js';
5
4
  /**
6
5
  * Where a proposed change stands: `pending` (waiting on the person),
7
6
  * `stepup` (the approval needs a fresh sign-in), `applying` (approved and
@@ -176,6 +175,12 @@ export interface ProposalCardProps extends Omit<HTMLAttributes<HTMLElement>, 'ti
176
175
  * Every sentence a refusal shows is the caller's (the engine's), never the
177
176
  * card's own words about why.
178
177
  *
178
+ * FOCUS IS NEVER DROPPED. The decision's buttons leave when the card
179
+ * settles, and a reader who pressed one from the keyboard would be left on
180
+ * the page body. Focus moves to what replaced them: the strip that says what
181
+ * happened, or the card itself when there is none. Only when focus was in
182
+ * the card as it settled: a reader who has moved on is not pulled back.
183
+ *
179
184
  * "NOTHING CHANGED." ONLY WHEN IT IS TRUE. A failure whose outcome nobody
180
185
  * could confirm (`failureOutcome="unknown"`) may have landed, so the card
181
186
  * says "Not confirmed" and never adds the reassurance.
@@ -1,3 +1,4 @@
1
+ import '../VisuallyHidden/VisuallyHidden.css';
1
2
  import './ProposalCard.css';
2
3
  export { PROPOSAL_CARD_LABELS, PROPOSAL_FAILURE_OUTCOMES, PROPOSAL_STATES, ProposalCard } from './ProposalCard.js';
3
4
  export type { ProposalCardLabels, ProposalCardProps, ProposalDecisionRefusal, ProposalFailureOutcome, ProposalKind, ProposalScope, ProposalState, } from './ProposalCard.js';
@@ -1,4 +1,4 @@
1
- export { PROPOSAL_CARD_LABELS, PROPOSAL_FAILURE_OUTCOMES, PROPOSAL_STATES, ProposalCard } from '../chunk-CIYHSTIF.js';
1
+ export { PROPOSAL_CARD_LABELS, PROPOSAL_FAILURE_OUTCOMES, PROPOSAL_STATES, ProposalCard } from '../chunk-SW4XVX7K.js';
2
2
  import '../chunk-LZXY6IMO.js';
3
3
  import '../chunk-WDIVALLP.js';
4
4
  import '../chunk-NEHSV55H.js';
@@ -27,3 +27,18 @@
27
27
  justify-content: flex-end;
28
28
  text-align: end;
29
29
  }
30
+
31
+ /* WHERE FOCUS LANDS WHEN THE CARD SETTLES (the strip, or the card when it
32
+ has none): the token ring for a reader on the keyboard, inset so the
33
+ card's corner does not clip it, and nothing for a pointer (transparent
34
+ rather than none, so forced colours still draw one). */
35
+ .crewlet-proposal-card:focus,
36
+ .crewlet-proposal-card .crewlet-receipt-strip:focus {
37
+ outline: 2px solid transparent;
38
+ }
39
+
40
+ .crewlet-proposal-card:focus-visible,
41
+ .crewlet-proposal-card .crewlet-receipt-strip:focus-visible {
42
+ outline: 2px solid var(--color-focus);
43
+ outline-offset: -2px;
44
+ }
@@ -50,9 +50,10 @@ export interface ResultTableCardProps extends Omit<HTMLAttributes<HTMLElement>,
50
50
  * the page the rows come from.
51
51
  *
52
52
  * THE CARD IS THE FRAME. The table draws no edge of its own and its outer
53
- * cells take the card's inset, so every row lines up with the title. The
54
- * first column takes the room the figures leave and ends a long name in an
55
- * ellipsis; a host that cuts names gives the cell its own tooltip.
53
+ * cells take the card's inset, so every row lines up with the title. A text
54
+ * cell, the first column's name included, wraps between words, so the whole
55
+ * of it is read at any width; figures and dates (`end` columns) stay on one
56
+ * line.
56
57
  *
57
58
  * A FOOT OF UTILITIES, so it starts on the card's text edge: the downloads
58
59
  * first (their ghost padding pulled out so the first glyph sits on that edge)
@@ -1,4 +1,4 @@
1
- export { RESULT_TABLE_CARD_LABELS, RESULT_TABLE_COLLAPSED_ROWS, RESULT_TABLE_MAX_ROWS, ResultTableCard } from '../chunk-GZMEWWXW.js';
1
+ export { RESULT_TABLE_CARD_LABELS, RESULT_TABLE_COLLAPSED_ROWS, RESULT_TABLE_MAX_ROWS, ResultTableCard } from '../chunk-2BWBDKF6.js';
2
2
  import '../chunk-45KMH3E3.js';
3
3
  import '../chunk-WDIVALLP.js';
4
4
  import '../chunk-HNK43Z3P.js';
@@ -0,0 +1,50 @@
1
+ /*
2
+ * A result in a card. The card, its head and its foot are StatusCard's and
3
+ * the table is Table's, drawn flush; what a result adds is the column model:
4
+ * a text column wraps between words, and the figures never wrap.
5
+ */
6
+ .crewlet-result-table-card__table .crewlet-table__table {
7
+ table-layout: auto;
8
+ font-variant-numeric: tabular-nums;
9
+ }
10
+
11
+ /*
12
+ * WORDS STAY WHOLE. Table breaks a cell anywhere, which suits its fixed
13
+ * layout, but under this card's auto layout it lets a column shrink to one
14
+ * letter, so "Product Manager" stacked letter by letter beside columns with
15
+ * room to spare. Breaking at words keeps a column as wide as its longest
16
+ * word, and a word wider than the card still breaks rather than overflow.
17
+ *
18
+ * THE NAME WRAPS TOO. The first column used to end a long name in an
19
+ * ellipsis on one line, and a result's row is not a link and its cell has no
20
+ * title, so in a 358px panel "Write the MVP plan" read "Write the MVP ..."
21
+ * with no way to reach the rest. It takes no width of its own: the auto
22
+ * layout gives each column the room its words ask for, so the name, the
23
+ * longest text, takes the most and wraps between words, and a short column
24
+ * beside it keeps its line where there is room. A `width: 100%` on it would
25
+ * squeeze every other text column to its longest word.
26
+ */
27
+ .crewlet-result-table-card__table td {
28
+ overflow-wrap: break-word;
29
+ }
30
+
31
+ .crewlet-result-table-card__table .crewlet-table__cell--end {
32
+ white-space: nowrap;
33
+ }
34
+
35
+ /*
36
+ * THE DOWNLOADS ARE SPANS AROUND A BUTTON (the status region beside each is
37
+ * a sibling of its button), so the foot's ghost outdent is stated for them
38
+ * here: the first one's padding and edge are pulled out so its glyph sits on
39
+ * the card's text edge.
40
+ */
41
+ .crewlet-result-table-card .crewlet-status-card__actions > .crewlet-result-table-card__download:first-child {
42
+ margin-inline-start: calc(-1 * (var(--spacing-2) + 1px));
43
+ }
44
+
45
+ /* The link stands at the foot's far end, its own padding pulled out to the edge. */
46
+ .crewlet-result-table-card__link {
47
+ display: inline-flex;
48
+ margin-inline-start: auto;
49
+ margin-inline-end: calc(-1 * (var(--spacing-2) + 1px));
50
+ }
@@ -31,12 +31,13 @@ export interface SidePanelProps {
31
31
  */
32
32
  footer?: ReactNode;
33
33
  /**
34
- * Drops the body's inset, for content that owns its own edges: a
34
+ * Drops the body's inset and its scrolling, for content that owns both: a
35
35
  * `ChatThread`, which scrolls itself and insets its own items, so its
36
- * scrollbar stands on the panel's edge and the inset is not drawn twice; or
37
- * a table whose rules meet the panel's sides. `--crewlet-side-panel-inset`
38
- * reads 0 inside the body, so a sticky foot that offsets itself by the
39
- * inset still sits on the edge.
36
+ * scrollbar stands on the panel's edge and the inset is not drawn twice.
37
+ * The body clips (`overflow: clip`) rather than scrolls, so a focus or a
38
+ * script inside cannot move it; content that may be taller than the panel
39
+ * scrolls itself (`min-height: 0` in the body's column, as `ChatThread`
40
+ * does). `--crewlet-side-panel-inset` reads 0 inside the body.
40
41
  */
41
42
  flush?: boolean | undefined;
42
43
  /**
@@ -34,7 +34,7 @@ export interface SidePanelBaseProps {
34
34
  closeLabel: string;
35
35
  actions?: ReactNode;
36
36
  footer?: ReactNode;
37
- /** Whether the body drops its inset, for content that draws its own. */
37
+ /** Whether the body drops its inset and its scrolling, for content that owns both. */
38
38
  flush?: boolean | undefined;
39
39
  initialFocus?: SidePanelInitialFocus | undefined;
40
40
  /** Whether the heading draws the focus ring when it holds focus. */
@@ -1,4 +1,4 @@
1
- import '../chunk-NVZCANJ5.js';
1
+ import '../chunk-73GUXYYE.js';
2
2
  export { SIDE_PANEL_LABELS, SIDE_PANEL_MAX_WIDTH, SIDE_PANEL_MIN_WIDTH, SIDE_PANEL_WIDTH, SidePanel, SidePanelFrame } from '../chunk-XODESBSR.js';
3
3
  import '../chunk-PQADV6P6.js';
4
4
  import '../chunk-PIYJNCN7.js';
@@ -157,11 +157,19 @@
157
157
  overscroll-behavior: contain;
158
158
  }
159
159
 
160
- /* FLUSH, the body draws no inset of its own: what it holds owns its edges
161
- (a chat thread that scrolls and insets itself). The published inset reads 0
162
- inside it, so anything that offsets itself by the inset follows. */
160
+ /* FLUSH, the body draws no inset of its own and does not scroll: what it
161
+ holds owns its edges and its scrolling (a chat thread that scrolls and
162
+ insets itself, shrunk to the body by `min-height: 0`). The published inset
163
+ reads 0 inside it, so anything that offsets itself by the inset follows.
164
+
165
+ CLIPPED, NOT SCROLLABLE. `overflow: hidden` would still be a scroll
166
+ container, which a focus, `scrollIntoView` or a script can scroll; a flush
167
+ body that was scrolled 238px lifted its thread off the panel's foot and
168
+ left a blank band no wheel could reach. `clip` is not a scroll container,
169
+ so nothing moves it. */
163
170
  .crewlet-side-panel__body--flush {
164
171
  --crewlet-side-panel-inset: 0px;
172
+ overflow: clip;
165
173
  }
166
174
 
167
175
  /* THE FOOT holds the panel's own commit, outside the scrolling body, so it
@@ -2,7 +2,7 @@ import { Table } from './chunk-45KMH3E3.js';
2
2
  import { StatusCard } from './chunk-WDIVALLP.js';
3
3
  import { DownloadButton } from './chunk-HNK43Z3P.js';
4
4
  import { cx } from './chunk-ODEQTPFM.js';
5
- import './ResultTableCard-HZRUDNTX.css';
5
+ import './ResultTableCard-AP355LQM.css';
6
6
  import { useState } from 'react';
7
7
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
8
8
 
@@ -1,3 +1,3 @@
1
1
  import './HitArea-QUOS6ZDJ.css';
2
2
  import './ResizeHandle-2UNSZ4ZQ.css';
3
- import './SidePanel-ERBUIELD.css';
3
+ import './SidePanel-VXKUKLOJ.css';
@@ -2,7 +2,7 @@ import { SidePanelBase, SidePanelFrameBase } from './chunk-XODESBSR.js';
2
2
  import { cx } from './chunk-ODEQTPFM.js';
3
3
  import './HitArea-QUOS6ZDJ.css';
4
4
  import './ResizeHandle-2UNSZ4ZQ.css';
5
- import './SidePanel-ERBUIELD.css';
5
+ import './SidePanel-VXKUKLOJ.css';
6
6
  import './ArtifactPanel-TN4FFK2F.css';
7
7
  import { jsx } from 'react/jsx-runtime';
8
8
 
@@ -2,7 +2,7 @@ import { Timeline } from './chunk-AUQPBL4O.js';
2
2
  import { Section } from './chunk-JQ7IFSF6.js';
3
3
  import { Composer } from './chunk-JLRXCKTS.js';
4
4
  import { Disclosure } from './chunk-GG4QZWMQ.js';
5
- import { ArtifactPanel } from './chunk-HGYHWWA5.js';
5
+ import { ArtifactPanel } from './chunk-ALU5EGQB.js';
6
6
  import { Button } from './chunk-HD4QJ2SI.js';
7
7
  import { cx } from './chunk-ODEQTPFM.js';
8
8
  import './AgentHandoffPanel-JWSW62GU.css';
@@ -2,7 +2,7 @@ import { useMediaMatch } from './chunk-RTPQDNW3.js';
2
2
  import { Button } from './chunk-HD4QJ2SI.js';
3
3
  import { VisuallyHidden } from './chunk-BZFWDIV6.js';
4
4
  import { cx } from './chunk-ODEQTPFM.js';
5
- import './ChatThread-52KMDXHB.css';
5
+ import './ChatThread-FGXVDLI2.css';
6
6
  import { forwardRef, useRef, Children, useState, useCallback, useLayoutEffect, useEffect, useImperativeHandle } from 'react';
7
7
  import { ArrowDownGlyph } from '@crewlethq/icons/glyphs';
8
8
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -4,7 +4,9 @@ import { ChangeList } from './chunk-NEHSV55H.js';
4
4
  import { Button } from './chunk-HD4QJ2SI.js';
5
5
  import { Spinner } from './chunk-EA23JG6R.js';
6
6
  import { cx } from './chunk-ODEQTPFM.js';
7
- import './ProposalCard-23575F4C.css';
7
+ import './VisuallyHidden-L552H7OA.css';
8
+ import './ProposalCard-YDGECRES.css';
9
+ import { useId, useRef, useLayoutEffect } from 'react';
8
10
  import { RefreshCwGlyph, LockGlyph, BanGlyph, ClockGlyph, CircleAlertGlyph, CircleCheckGlyph } from '@crewlethq/icons/glyphs';
9
11
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
10
12
 
@@ -108,6 +110,25 @@ function ProposalCard({
108
110
  }) {
109
111
  const labels = overrides ? { ...PROPOSAL_CARD_LABELS, ...overrides } : PROPOSAL_CARD_LABELS;
110
112
  const settled = SETTLED.has(state);
113
+ const uid = useId();
114
+ const cardId = rest.id ?? `${uid}-card`;
115
+ const stripId = `${uid}-strip`;
116
+ const previous = useRef(state);
117
+ const regain = useRef(false);
118
+ if (previous.current !== state) {
119
+ if (settled && !SETTLED.has(previous.current) && typeof document !== "undefined") {
120
+ regain.current = document.getElementById(cardId)?.contains(document.activeElement) ?? false;
121
+ }
122
+ previous.current = state;
123
+ }
124
+ useLayoutEffect(() => {
125
+ if (!regain.current) return;
126
+ regain.current = false;
127
+ const holder = document.activeElement;
128
+ if (holder && holder !== document.body) return;
129
+ (document.getElementById(stripId) ?? document.getElementById(cardId))?.focus({ preventScroll: true });
130
+ }, [state, stripId, cardId]);
131
+ const landing = settled ? { id: stripId, tabIndex: -1 } : {};
111
132
  const deciding = state === "pending" || state === "stepup";
112
133
  const blocked = deciding && approveBlocked ? approveBlocked : void 0;
113
134
  const refusal = deciding ? decisionRefusal : void 0;
@@ -133,9 +154,10 @@ function ProposalCard({
133
154
  /* @__PURE__ */ jsx(Button, { variant: "primary", loading: state === "applying", disabledReason: blocked, onClick: onApprove, children: state === "stepup" ? labels.confirmIdentity : approveLabel })
134
155
  ] }) : void 0;
135
156
  const again = (state === "expired" || state === "stale") && onPrepareAgain ? /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", leadingIcon: /* @__PURE__ */ jsx(RefreshCwGlyph, {}), onClick: onPrepareAgain, children: labels.prepareAgain }) : void 0;
136
- const strip = state === "stepup" ? /* @__PURE__ */ jsx(ReceiptStrip, { tone: "neutral", icon: /* @__PURE__ */ jsx(LockGlyph, { size: "md" }), children: notice ?? labels.stepUpNotice }) : state === "applied" && receipt !== void 0 ? /* @__PURE__ */ jsx(ReceiptStrip, { tone: "success", children: receipt }) : state === "declined" ? /* @__PURE__ */ jsx(ReceiptStrip, { tone: "neutral", icon: /* @__PURE__ */ jsx(BanGlyph, { size: "md" }), children: notice ?? labels.declinedNotice }) : state === "expired" ? /* @__PURE__ */ jsx(ReceiptStrip, { tone: "neutral", icon: /* @__PURE__ */ jsx(ClockGlyph, { size: "md" }), children: notice ?? labels.expiredNotice }) : state === "stale" ? /* @__PURE__ */ jsx(ReceiptStrip, { tone: "neutral", icon: /* @__PURE__ */ jsx(ClockGlyph, { size: "md" }), children: notice ?? labels.staleNotice }) : state === "failed" ? /* @__PURE__ */ jsx(
157
+ const strip = state === "stepup" ? /* @__PURE__ */ jsx(ReceiptStrip, { tone: "neutral", icon: /* @__PURE__ */ jsx(LockGlyph, { size: "md" }), children: notice ?? labels.stepUpNotice }) : state === "applied" && receipt !== void 0 ? /* @__PURE__ */ jsx(ReceiptStrip, { ...landing, tone: "success", children: receipt }) : state === "declined" ? /* @__PURE__ */ jsx(ReceiptStrip, { ...landing, tone: "neutral", icon: /* @__PURE__ */ jsx(BanGlyph, { size: "md" }), children: notice ?? labels.declinedNotice }) : state === "expired" ? /* @__PURE__ */ jsx(ReceiptStrip, { ...landing, tone: "neutral", icon: /* @__PURE__ */ jsx(ClockGlyph, { size: "md" }), children: notice ?? labels.expiredNotice }) : state === "stale" ? /* @__PURE__ */ jsx(ReceiptStrip, { ...landing, tone: "neutral", icon: /* @__PURE__ */ jsx(ClockGlyph, { size: "md" }), children: notice ?? labels.staleNotice }) : state === "failed" ? /* @__PURE__ */ jsx(
137
158
  RefusalStrip,
138
159
  {
160
+ ...landing,
139
161
  placement: "foot",
140
162
  hint: failure === void 0 ? void 0 : failureHint,
141
163
  onRetry,
@@ -151,6 +173,8 @@ function ProposalCard({
151
173
  StatusCard,
152
174
  {
153
175
  ...rest,
176
+ id: cardId,
177
+ tabIndex: settled ? -1 : rest.tabIndex,
154
178
  title,
155
179
  subtitle,
156
180
  status: statusOf(state, scope, failureOutcome, labels),
@@ -1,11 +1,10 @@
1
1
  import '../chunk-EWTPXRRM.js';
2
2
  export { ElementToPngError, elementToPng, parseCsv, serializeElement, toCsv } from '../chunk-FEJANUZK.js';
3
3
  export { TreeCanvas } from '../chunk-YCZ2FBKA.js';
4
- export { VERSION_COMPARE_LABELS, VERSION_COMPARE_LENSES, VersionCompare } from '../chunk-OHG7762N.js';
5
4
  export { TypeSpecimen } from '../chunk-JKAFEFFC.js';
5
+ export { VERSION_COMPARE_LABELS, VERSION_COMPARE_LENSES, VersionCompare } from '../chunk-OHG7762N.js';
6
6
  export { VersionTimeline } from '../chunk-67MW366X.js';
7
7
  export { WidgetFrame } from '../chunk-PDTEPN4D.js';
8
- export { ThemeToggle } from '../chunk-N3ISZVLK.js';
9
8
  export { TileGrid } from '../chunk-Q6CQMS6R.js';
10
9
  export { TIME_RANGE_CUSTOM, TIME_RANGE_PICKER_LABELS, TimeRangePicker, timeRangeFieldKey, timeRangeProblem } from '../chunk-QYEOGGVS.js';
11
10
  export { DEFAULT_TIME_WINDOW_LABELS, TIME_WINDOW_SPANS, TimeWindowPicker, describeTimeWindow, isTimeWindowSet, parseTimeWindowDuration, resolveTimeWindow, timeWindowMatchesPreset } from '../chunk-MYX4XABB.js';
@@ -14,6 +13,7 @@ export { TagsInput } from '../chunk-JS2TRHBF.js';
14
13
  export { ThemeGallery } from '../chunk-ESUZ27TS.js';
15
14
  export { ThemeSwatch } from '../chunk-MNFU2RNT.js';
16
15
  export { DensitySwitcher, ThemeSwitcher } from '../chunk-S5C64PTT.js';
16
+ export { ThemeToggle } from '../chunk-N3ISZVLK.js';
17
17
  export { applyStoredPreferences, resolveTheme, useDensityPreference, useSystemTheme, useThemePreference } from '../chunk-Z24ZUSTX.js';
18
18
  export { SuggestionList, SuggestionRow } from '../chunk-SDSBVVLL.js';
19
19
  export { Switcher } from '../chunk-67F2AM4R.js';
@@ -23,20 +23,20 @@ export { SOURCE_EDITOR_KEYS, SourceEditor, lineStart } from '../chunk-D3EJSLCL.j
23
23
  export { StatCard } from '../chunk-YPTTSJPM.js';
24
24
  export { StatGroup } from '../chunk-OUD75UB2.js';
25
25
  export { Statement } from '../chunk-MZJKPTA5.js';
26
- export { CellDisplay, CellEditor, CheckboxCell, DateCell, LongTextCell, MultiSelectCell, NumberCell, PersonCell, RatingCell, SelectCell, SheetCell, SheetGrid, StatusCell, TextCell, UrlCell } from '../chunk-TD3UHDFY.js';
27
- export { TagGroup } from '../chunk-O2EGEONV.js';
26
+ export { SHEET_COLUMN_EDITOR_LABELS, SheetColumnEditor, SheetColumnTypeGlyph } from '../chunk-EBG3V4MK.js';
28
27
  export { matchesShortcut, useShortcut } from '../chunk-AYHIF6DH.js';
29
- import '../chunk-NVZCANJ5.js';
28
+ import '../chunk-73GUXYYE.js';
30
29
  export { SLIDE_COMPARE_LABELS, SlideCompare } from '../chunk-UV4LOQ3E.js';
31
30
  export { SlideFilmstrip } from '../chunk-WOW5SCEK.js';
32
31
  export { SegmentedMeter, segmentedMeterLabel } from '../chunk-4AK52VHB.js';
33
32
  export { SelectionBar } from '../chunk-NK3D66PB.js';
34
33
  export { SEND_BUTTON_LABELS, SendButton } from '../chunk-JILNCBBS.js';
35
- export { SetupWizard } from '../chunk-D5OSP3KI.js';
36
34
  export { SettingsTable, SettingsTableRow } from '../chunk-4RKTZSEW.js';
35
+ export { SetupWizard } from '../chunk-D5OSP3KI.js';
37
36
  export { ARTIFACT_ROLES, SHAREABLE_ROLES, ShareDialog, roleAtLeast } from '../chunk-OOZ5AGPS.js';
38
- export { SHEET_COLUMN_EDITOR_LABELS, SheetColumnEditor, SheetColumnTypeGlyph } from '../chunk-EBG3V4MK.js';
39
37
  export { Select } from '../chunk-XQZ6EWOE.js';
38
+ export { CellDisplay, CellEditor, CheckboxCell, DateCell, LongTextCell, MultiSelectCell, NumberCell, PersonCell, RatingCell, SelectCell, SheetCell, SheetGrid, StatusCell, TextCell, UrlCell } from '../chunk-TD3UHDFY.js';
39
+ export { TagGroup } from '../chunk-O2EGEONV.js';
40
40
  export { canonicalMarkdown, roundTripMarkdown } from '../chunk-SWD4QBL6.js';
41
41
  import '../chunk-QH6VYJ3X.js';
42
42
  export { RichEditor, preloadRichEditor } from '../chunk-WBTCOFMZ.js';
@@ -51,7 +51,7 @@ export { ReadingPane, ReadingPaneByline, ReadingPaneLead, ReadingPaneOutcome, Re
51
51
  export { REFUSAL_CARD_LABELS, RefusalCard } from '../chunk-BLPT6GHV.js';
52
52
  export { RelatedRow } from '../chunk-N4GBDK4L.js';
53
53
  export { Text } from '../chunk-QP2P6GDQ.js';
54
- export { RESULT_TABLE_CARD_LABELS, RESULT_TABLE_COLLAPSED_ROWS, RESULT_TABLE_MAX_ROWS, ResultTableCard } from '../chunk-GZMEWWXW.js';
54
+ export { RESULT_TABLE_CARD_LABELS, RESULT_TABLE_COLLAPSED_ROWS, RESULT_TABLE_MAX_ROWS, ResultTableCard } from '../chunk-2BWBDKF6.js';
55
55
  export { Table } from '../chunk-45KMH3E3.js';
56
56
  export { ReviewList } from '../chunk-OJ2QULVH.js';
57
57
  export { PresenterView, formatStopwatch } from '../chunk-EGL24VY5.js';
@@ -60,7 +60,7 @@ export { SLIDE_HEIGHT, SLIDE_WIDTH, SlideStage, useSlideKeys } from '../chunk-RM
60
60
  export { PricingCard } from '../chunk-U3ILLCR2.js';
61
61
  export { PrincipalPicker } from '../chunk-TA72CURM.js';
62
62
  export { PropertyList } from '../chunk-XZ42MKHK.js';
63
- export { PROPOSAL_CARD_LABELS, PROPOSAL_FAILURE_OUTCOMES, PROPOSAL_STATES, ProposalCard } from '../chunk-CIYHSTIF.js';
63
+ export { PROPOSAL_CARD_LABELS, PROPOSAL_FAILURE_OUTCOMES, PROPOSAL_STATES, ProposalCard } from '../chunk-SW4XVX7K.js';
64
64
  export { Prose } from '../chunk-JCSA3XVH.js';
65
65
  export { QR_DARK, QR_LIGHT, QR_QUIET_ZONE, QrCode, qrModulePath, qrModules } from '../chunk-Y56FM3K4.js';
66
66
  export { PageNote } from '../chunk-CV4NES3P.js';
@@ -73,15 +73,15 @@ export { FactLine, ObjectHeader, SetByLine } from '../chunk-ICWUDNAZ.js';
73
73
  export { OPEN_IN_APP_CARD_LABELS, OpenInAppCard } from '../chunk-CZNG3V6L.js';
74
74
  export { REFUSAL_STRIP_LABELS, ReceiptStrip, RefusalStrip } from '../chunk-LZXY6IMO.js';
75
75
  export { OrgNodeDisclosure, OrgNodeLabel, OrgNodeLead } from '../chunk-YA3AWELW.js';
76
+ export { Outline, scrollToHeading, useActiveHeading } from '../chunk-A5YKNRG6.js';
76
77
  export { OrgTable, OrgTableActions, OrgTableAdd, OrgTableName } from '../chunk-GPW4M4OI.js';
77
78
  export { TreeGrid } from '../chunk-VRNUKH2W.js';
78
79
  export { SIZE_EPSILON, TYPE_AHEAD_RESET_MS, createTreeModel, isTypeAheadKey, layoutConnectors, layoutForest, placeGroups, treeAllExpandable, treeAncestors, treeCollapseOrAscend, treeExpandOrDescend, treeExpandTo, treeExpandable, treeFirst, treeFirstChild, treeItemAction, treeLast, treeLevel, treeNext, treeParent, treePosInSet, treePrevious, treeSetSize, treeStep, treeTypeAhead, treeVisible, typeAheadBuffer, useLayoutAnchor, useMeasuredSizes, useTreeState } from '../chunk-MY374UUD.js';
79
80
  export { OrgLabel } from '../chunk-ONQKKHON.js';
80
- export { Outline, scrollToHeading, useActiveHeading } from '../chunk-A5YKNRG6.js';
81
81
  export { MARKDOWN_FORMATS, MarkdownEditor, formatMarkdown, insertMarkdown, markdownWords } from '../chunk-272Y3YMV.js';
82
82
  export { MERGE_CONFLICTS_LABELS, MergeConflicts } from '../chunk-2TTFDRR3.js';
83
- export { MessageBubble } from '../chunk-C3FX7ZSU.js';
84
83
  export { DEFAULT_METER_THRESHOLDS, METER_STATES, Meter, meterState, meterStateTone, meterTone, progressTone } from '../chunk-UGNUUVRI.js';
84
+ export { MessageBubble } from '../chunk-C3FX7ZSU.js';
85
85
  export { NewItemsNotice } from '../chunk-PXU6HOZB.js';
86
86
  export { ListDetail } from '../chunk-R5RCGD7N.js';
87
87
  export { ListInput, withDraft } from '../chunk-DOPPU6TZ.js';
@@ -112,6 +112,7 @@ import '../chunk-MICRGE3J.js';
112
112
  export { EntityChip } from '../chunk-OSKJZNBT.js';
113
113
  export { EntityList } from '../chunk-FA44M2YT.js';
114
114
  export { StatusCard } from '../chunk-WDIVALLP.js';
115
+ export { EditingStatus } from '../chunk-XRZGGB6I.js';
115
116
  export { ErrorBoundary } from '../chunk-WBRC3MNE.js';
116
117
  export { Eyebrow } from '../chunk-RK4XPHVG.js';
117
118
  export { FactList } from '../chunk-RLJXVFEH.js';
@@ -122,7 +123,6 @@ export { Divider } from '../chunk-6KWNXIDE.js';
122
123
  export { DOC_TABS_EDITOR_LABELS, DocTabsEditor } from '../chunk-5OMV75GE.js';
123
124
  export { DownloadButton } from '../chunk-HNK43Z3P.js';
124
125
  export { downloadBlob, downloadText, safeFilename, useDownload } from '../chunk-YNRKVY7X.js';
125
- export { EditingStatus } from '../chunk-XRZGGB6I.js';
126
126
  export { CursorFlag } from '../chunk-3BYIWOTV.js';
127
127
  export { PresenceRing, presenceHueClass } from '../chunk-I6POAB4V.js';
128
128
  export { ChooserList, ColumnChooser, DataGrid, columnChoicesOf, countDataGridRows, fitGridColumns, parseGridSort, useAnyDataGridDriving, useDataGridDriving } from '../chunk-EDNZHW4K.js';
@@ -132,14 +132,15 @@ export { ALL_ITEMS, CopyableCell, DATA_TABLE_LABELS, DataTable, RowActionsMenu }
132
132
  export { DATASET_SOURCE_KINDS, DatasetSource, DatasetSourceList } from '../chunk-AZ5BKSGV.js';
133
133
  export { DEFAULT_DATE_TIME_PICKER_LABELS, DateTimePicker } from '../chunk-6NJW5KSX.js';
134
134
  export { DescriptionList, DescriptionListItem } from '../chunk-MFS6F2P7.js';
135
+ export { COMMENT_THREAD_LABELS, CommentThread } from '../chunk-56P72ZBE.js';
135
136
  export { ConfirmField, confirmMatches } from '../chunk-4CBGIRVU.js';
136
137
  export { InlineCode } from '../chunk-5CLW2CXT.js';
137
138
  export { CONFLICT_NOTE_LABELS, ConflictNote } from '../chunk-HVEDVKXL.js';
138
139
  export { Container } from '../chunk-HJO4WCH6.js';
139
140
  export { ContrastHelp } from '../chunk-YCGZK2E4.js';
140
141
  export { ContrastBadge, ContrastLevelTag, contrastLevel, contrastRatio, formatContrastRatio } from '../chunk-WW7TU6HE.js';
141
- export { CodeBlock } from '../chunk-6T6V5565.js';
142
142
  export { ChoiceList } from '../chunk-EAQLI2SO.js';
143
+ export { CodeBlock } from '../chunk-6T6V5565.js';
143
144
  export { ColorChip } from '../chunk-6GTTRJWJ.js';
144
145
  export { ColorField } from '../chunk-3NQS6KYG.js';
145
146
  export { ColorSwatch } from '../chunk-NQGZRMUG.js';
@@ -150,7 +151,6 @@ export { Combobox } from '../chunk-U5PJSGHG.js';
150
151
  export { CommandPalette } from '../chunk-Z7PJF6F3.js';
151
152
  export { ConfirmModal, Modal } from '../chunk-QZ4B72FP.js';
152
153
  export { HIGHLIGHT_REST_MS, TYPE_AHEAD_WINDOW, useHighlightRest, useListbox, useOptionKeys } from '../chunk-7KHM2FZH.js';
153
- export { COMMENT_THREAD_LABELS, CommentThread } from '../chunk-56P72ZBE.js';
154
154
  export { CHANGE_LIST_COLLAPSE_OVER, CHANGE_LIST_LABELS, ChangeList, shortenUnchanged } from '../chunk-NEHSV55H.js';
155
155
  export { DIFF_LIST_LABELS, DiffList } from '../chunk-Z3GDMNMU.js';
156
156
  export { Tag } from '../chunk-KYIAFNU7.js';
@@ -159,7 +159,7 @@ export { LONGTEXT_MAX_DEFAULT, RATING_MAX_CEILING, RATING_MAX_DEFAULT, SHEET_COL
159
159
  export { PRESENCE_ACTIVITIES, PRESENCE_HUES, PRESENCE_LABELS, assignPresenceHues, collapseSessions, joinNames, presenceLabels, presenceOrder } from '../chunk-Z7JYG5TF.js';
160
160
  import '../chunk-3L5NHASN.js';
161
161
  export { ActivityStrip, BarList, ChartEmpty, ChartTooltip, DATA_COLORS, DATA_COLOR_OTHER, Histogram, Legend, Sparkline, StackedBar, StackedColumns, TimeSeries, dataColor, histogramTicks, niceScale, useChartHover } from '../chunk-HMVQQEHW.js';
162
- export { CHAT_THREAD_FOLLOW_WITHIN, CHAT_THREAD_LABELS, ChatThread } from '../chunk-RV2FGESF.js';
162
+ export { CHAT_THREAD_FOLLOW_WITHIN, CHAT_THREAD_LABELS, ChatThread } from '../chunk-PE7XWOUS.js';
163
163
  export { ChoiceButtons } from '../chunk-WXRH7NZW.js';
164
164
  export { CalendarGrid, compareDays, daysInMonth, sameDay, shiftDay, shiftMonth, today } from '../chunk-GXQ3B46I.js';
165
165
  export { Callout } from '../chunk-BPCY7ZID.js';
@@ -221,12 +221,12 @@ export { ACCESS_DENIED_REASONS, AccessDeniedCard } from '../chunk-QTMUKRTN.js';
221
221
  export { EmptyState } from '../chunk-PPUR46MK.js';
222
222
  export { Accordion, AccordionItem } from '../chunk-T4D7RZNI.js';
223
223
  export { ADD_PILL_MS, AddPill } from '../chunk-TROLVEZY.js';
224
- export { AGENT_HANDOFF_LABELS, AgentHandoffPanel } from '../chunk-GCASX3FD.js';
224
+ export { AGENT_HANDOFF_LABELS, AgentHandoffPanel } from '../chunk-G3CUCHBA.js';
225
225
  export { Timeline, TimelineItem } from '../chunk-AUQPBL4O.js';
226
226
  export { Section } from '../chunk-JQ7IFSF6.js';
227
227
  export { COMPOSER_COUNTER_AT, Composer } from '../chunk-JLRXCKTS.js';
228
228
  export { Disclosure } from '../chunk-GG4QZWMQ.js';
229
- export { ARTIFACT_PANEL_LABELS, ArtifactPanel, ArtifactWorkspace } from '../chunk-HGYHWWA5.js';
229
+ export { ARTIFACT_PANEL_LABELS, ArtifactPanel, ArtifactWorkspace } from '../chunk-ALU5EGQB.js';
230
230
  export { SIDE_PANEL_LABELS, SIDE_PANEL_MAX_WIDTH, SIDE_PANEL_MIN_WIDTH, SIDE_PANEL_WIDTH, SidePanel, SidePanelFrame } from '../chunk-XODESBSR.js';
231
231
  export { Kbd, isApplePlatform, keyGlyph } from '../chunk-SMBKXWML.js';
232
232
  export { FormField, FormRow, FormSection, Input, InputAffix, Label, ReadOnlyField, Textarea, foldLineBreaks } from '../chunk-FXQLNETQ.js';
package/dist/index.js CHANGED
@@ -1,11 +1,10 @@
1
1
  import './chunk-EWTPXRRM.js';
2
2
  export { ElementToPngError, elementToPng, parseCsv, serializeElement, toCsv } from './chunk-FEJANUZK.js';
3
3
  export { TreeCanvas } from './chunk-YCZ2FBKA.js';
4
- export { VERSION_COMPARE_LABELS, VERSION_COMPARE_LENSES, VersionCompare } from './chunk-OHG7762N.js';
5
4
  export { TypeSpecimen } from './chunk-JKAFEFFC.js';
5
+ export { VERSION_COMPARE_LABELS, VERSION_COMPARE_LENSES, VersionCompare } from './chunk-OHG7762N.js';
6
6
  export { VersionTimeline } from './chunk-67MW366X.js';
7
7
  export { WidgetFrame } from './chunk-PDTEPN4D.js';
8
- export { ThemeToggle } from './chunk-N3ISZVLK.js';
9
8
  export { TileGrid } from './chunk-Q6CQMS6R.js';
10
9
  export { TIME_RANGE_CUSTOM, TIME_RANGE_PICKER_LABELS, TimeRangePicker, timeRangeFieldKey, timeRangeProblem } from './chunk-QYEOGGVS.js';
11
10
  export { DEFAULT_TIME_WINDOW_LABELS, TIME_WINDOW_SPANS, TimeWindowPicker, describeTimeWindow, isTimeWindowSet, parseTimeWindowDuration, resolveTimeWindow, timeWindowMatchesPreset } from './chunk-MYX4XABB.js';
@@ -14,6 +13,7 @@ export { TagsInput } from './chunk-JS2TRHBF.js';
14
13
  export { ThemeGallery } from './chunk-ESUZ27TS.js';
15
14
  export { ThemeSwatch } from './chunk-MNFU2RNT.js';
16
15
  export { DensitySwitcher, ThemeSwitcher } from './chunk-S5C64PTT.js';
16
+ export { ThemeToggle } from './chunk-N3ISZVLK.js';
17
17
  export { applyStoredPreferences, resolveTheme, useDensityPreference, useSystemTheme, useThemePreference } from './chunk-Z24ZUSTX.js';
18
18
  export { SuggestionList, SuggestionRow } from './chunk-SDSBVVLL.js';
19
19
  export { Switcher } from './chunk-67F2AM4R.js';
@@ -23,20 +23,20 @@ export { SOURCE_EDITOR_KEYS, SourceEditor, lineStart } from './chunk-D3EJSLCL.js
23
23
  export { StatCard } from './chunk-YPTTSJPM.js';
24
24
  export { StatGroup } from './chunk-OUD75UB2.js';
25
25
  export { Statement } from './chunk-MZJKPTA5.js';
26
- export { CellDisplay, CellEditor, CheckboxCell, DateCell, LongTextCell, MultiSelectCell, NumberCell, PersonCell, RatingCell, SelectCell, SheetCell, SheetGrid, StatusCell, TextCell, UrlCell } from './chunk-TD3UHDFY.js';
27
- export { TagGroup } from './chunk-O2EGEONV.js';
26
+ export { SHEET_COLUMN_EDITOR_LABELS, SheetColumnEditor, SheetColumnTypeGlyph } from './chunk-EBG3V4MK.js';
28
27
  export { matchesShortcut, useShortcut } from './chunk-AYHIF6DH.js';
29
- import './chunk-NVZCANJ5.js';
28
+ import './chunk-73GUXYYE.js';
30
29
  export { SLIDE_COMPARE_LABELS, SlideCompare } from './chunk-UV4LOQ3E.js';
31
30
  export { SlideFilmstrip } from './chunk-WOW5SCEK.js';
32
31
  export { SegmentedMeter, segmentedMeterLabel } from './chunk-4AK52VHB.js';
33
32
  export { SelectionBar } from './chunk-NK3D66PB.js';
34
33
  export { SEND_BUTTON_LABELS, SendButton } from './chunk-JILNCBBS.js';
35
- export { SetupWizard } from './chunk-D5OSP3KI.js';
36
34
  export { SettingsTable, SettingsTableRow } from './chunk-4RKTZSEW.js';
35
+ export { SetupWizard } from './chunk-D5OSP3KI.js';
37
36
  export { ARTIFACT_ROLES, SHAREABLE_ROLES, ShareDialog, roleAtLeast } from './chunk-OOZ5AGPS.js';
38
- export { SHEET_COLUMN_EDITOR_LABELS, SheetColumnEditor, SheetColumnTypeGlyph } from './chunk-EBG3V4MK.js';
39
37
  export { Select } from './chunk-XQZ6EWOE.js';
38
+ export { CellDisplay, CellEditor, CheckboxCell, DateCell, LongTextCell, MultiSelectCell, NumberCell, PersonCell, RatingCell, SelectCell, SheetCell, SheetGrid, StatusCell, TextCell, UrlCell } from './chunk-TD3UHDFY.js';
39
+ export { TagGroup } from './chunk-O2EGEONV.js';
40
40
  export { canonicalMarkdown, roundTripMarkdown } from './chunk-SWD4QBL6.js';
41
41
  import './chunk-QH6VYJ3X.js';
42
42
  export { RichEditor, preloadRichEditor } from './chunk-WBTCOFMZ.js';
@@ -51,7 +51,7 @@ export { ReadingPane, ReadingPaneByline, ReadingPaneLead, ReadingPaneOutcome, Re
51
51
  export { REFUSAL_CARD_LABELS, RefusalCard } from './chunk-BLPT6GHV.js';
52
52
  export { RelatedRow } from './chunk-N4GBDK4L.js';
53
53
  export { Text } from './chunk-QP2P6GDQ.js';
54
- export { RESULT_TABLE_CARD_LABELS, RESULT_TABLE_COLLAPSED_ROWS, RESULT_TABLE_MAX_ROWS, ResultTableCard } from './chunk-GZMEWWXW.js';
54
+ export { RESULT_TABLE_CARD_LABELS, RESULT_TABLE_COLLAPSED_ROWS, RESULT_TABLE_MAX_ROWS, ResultTableCard } from './chunk-2BWBDKF6.js';
55
55
  export { Table } from './chunk-45KMH3E3.js';
56
56
  export { ReviewList } from './chunk-OJ2QULVH.js';
57
57
  export { PresenterView, formatStopwatch } from './chunk-EGL24VY5.js';
@@ -60,7 +60,7 @@ export { SLIDE_HEIGHT, SLIDE_WIDTH, SlideStage, useSlideKeys } from './chunk-RME
60
60
  export { PricingCard } from './chunk-U3ILLCR2.js';
61
61
  export { PrincipalPicker } from './chunk-TA72CURM.js';
62
62
  export { PropertyList } from './chunk-XZ42MKHK.js';
63
- export { PROPOSAL_CARD_LABELS, PROPOSAL_FAILURE_OUTCOMES, PROPOSAL_STATES, ProposalCard } from './chunk-CIYHSTIF.js';
63
+ export { PROPOSAL_CARD_LABELS, PROPOSAL_FAILURE_OUTCOMES, PROPOSAL_STATES, ProposalCard } from './chunk-SW4XVX7K.js';
64
64
  export { Prose } from './chunk-JCSA3XVH.js';
65
65
  export { QR_DARK, QR_LIGHT, QR_QUIET_ZONE, QrCode, qrModulePath, qrModules } from './chunk-Y56FM3K4.js';
66
66
  export { PageNote } from './chunk-CV4NES3P.js';
@@ -73,15 +73,15 @@ export { FactLine, ObjectHeader, SetByLine } from './chunk-ICWUDNAZ.js';
73
73
  export { OPEN_IN_APP_CARD_LABELS, OpenInAppCard } from './chunk-CZNG3V6L.js';
74
74
  export { REFUSAL_STRIP_LABELS, ReceiptStrip, RefusalStrip } from './chunk-LZXY6IMO.js';
75
75
  export { OrgNodeDisclosure, OrgNodeLabel, OrgNodeLead } from './chunk-YA3AWELW.js';
76
+ export { Outline, scrollToHeading, useActiveHeading } from './chunk-A5YKNRG6.js';
76
77
  export { OrgTable, OrgTableActions, OrgTableAdd, OrgTableName } from './chunk-GPW4M4OI.js';
77
78
  export { TreeGrid } from './chunk-VRNUKH2W.js';
78
79
  export { SIZE_EPSILON, TYPE_AHEAD_RESET_MS, createTreeModel, isTypeAheadKey, layoutConnectors, layoutForest, placeGroups, treeAllExpandable, treeAncestors, treeCollapseOrAscend, treeExpandOrDescend, treeExpandTo, treeExpandable, treeFirst, treeFirstChild, treeItemAction, treeLast, treeLevel, treeNext, treeParent, treePosInSet, treePrevious, treeSetSize, treeStep, treeTypeAhead, treeVisible, typeAheadBuffer, useLayoutAnchor, useMeasuredSizes, useTreeState } from './chunk-MY374UUD.js';
79
80
  export { OrgLabel } from './chunk-ONQKKHON.js';
80
- export { Outline, scrollToHeading, useActiveHeading } from './chunk-A5YKNRG6.js';
81
81
  export { MARKDOWN_FORMATS, MarkdownEditor, formatMarkdown, insertMarkdown, markdownWords } from './chunk-272Y3YMV.js';
82
82
  export { MERGE_CONFLICTS_LABELS, MergeConflicts } from './chunk-2TTFDRR3.js';
83
- export { MessageBubble } from './chunk-C3FX7ZSU.js';
84
83
  export { DEFAULT_METER_THRESHOLDS, METER_STATES, Meter, meterState, meterStateTone, meterTone, progressTone } from './chunk-UGNUUVRI.js';
84
+ export { MessageBubble } from './chunk-C3FX7ZSU.js';
85
85
  export { NewItemsNotice } from './chunk-PXU6HOZB.js';
86
86
  export { ListDetail } from './chunk-R5RCGD7N.js';
87
87
  export { ListInput, withDraft } from './chunk-DOPPU6TZ.js';
@@ -112,6 +112,7 @@ import './chunk-MICRGE3J.js';
112
112
  export { EntityChip } from './chunk-OSKJZNBT.js';
113
113
  export { EntityList } from './chunk-FA44M2YT.js';
114
114
  export { StatusCard } from './chunk-WDIVALLP.js';
115
+ export { EditingStatus } from './chunk-XRZGGB6I.js';
115
116
  export { ErrorBoundary } from './chunk-WBRC3MNE.js';
116
117
  export { Eyebrow } from './chunk-RK4XPHVG.js';
117
118
  export { FactList } from './chunk-RLJXVFEH.js';
@@ -122,7 +123,6 @@ export { Divider } from './chunk-6KWNXIDE.js';
122
123
  export { DOC_TABS_EDITOR_LABELS, DocTabsEditor } from './chunk-5OMV75GE.js';
123
124
  export { DownloadButton } from './chunk-HNK43Z3P.js';
124
125
  export { downloadBlob, downloadText, safeFilename, useDownload } from './chunk-YNRKVY7X.js';
125
- export { EditingStatus } from './chunk-XRZGGB6I.js';
126
126
  export { CursorFlag } from './chunk-3BYIWOTV.js';
127
127
  export { PresenceRing, presenceHueClass } from './chunk-I6POAB4V.js';
128
128
  export { ChooserList, ColumnChooser, DataGrid, columnChoicesOf, countDataGridRows, fitGridColumns, parseGridSort, useAnyDataGridDriving, useDataGridDriving } from './chunk-EDNZHW4K.js';
@@ -132,14 +132,15 @@ export { ALL_ITEMS, CopyableCell, DATA_TABLE_LABELS, DataTable, RowActionsMenu }
132
132
  export { DATASET_SOURCE_KINDS, DatasetSource, DatasetSourceList } from './chunk-AZ5BKSGV.js';
133
133
  export { DEFAULT_DATE_TIME_PICKER_LABELS, DateTimePicker } from './chunk-6NJW5KSX.js';
134
134
  export { DescriptionList, DescriptionListItem } from './chunk-MFS6F2P7.js';
135
+ export { COMMENT_THREAD_LABELS, CommentThread } from './chunk-56P72ZBE.js';
135
136
  export { ConfirmField, confirmMatches } from './chunk-4CBGIRVU.js';
136
137
  export { InlineCode } from './chunk-5CLW2CXT.js';
137
138
  export { CONFLICT_NOTE_LABELS, ConflictNote } from './chunk-HVEDVKXL.js';
138
139
  export { Container } from './chunk-HJO4WCH6.js';
139
140
  export { ContrastHelp } from './chunk-YCGZK2E4.js';
140
141
  export { ContrastBadge, ContrastLevelTag, contrastLevel, contrastRatio, formatContrastRatio } from './chunk-WW7TU6HE.js';
141
- export { CodeBlock } from './chunk-6T6V5565.js';
142
142
  export { ChoiceList } from './chunk-EAQLI2SO.js';
143
+ export { CodeBlock } from './chunk-6T6V5565.js';
143
144
  export { ColorChip } from './chunk-6GTTRJWJ.js';
144
145
  export { ColorField } from './chunk-3NQS6KYG.js';
145
146
  export { ColorSwatch } from './chunk-NQGZRMUG.js';
@@ -150,7 +151,6 @@ export { Combobox } from './chunk-U5PJSGHG.js';
150
151
  export { CommandPalette } from './chunk-Z7PJF6F3.js';
151
152
  export { ConfirmModal, Modal } from './chunk-QZ4B72FP.js';
152
153
  export { HIGHLIGHT_REST_MS, TYPE_AHEAD_WINDOW, useHighlightRest, useListbox, useOptionKeys } from './chunk-7KHM2FZH.js';
153
- export { COMMENT_THREAD_LABELS, CommentThread } from './chunk-56P72ZBE.js';
154
154
  export { CHANGE_LIST_COLLAPSE_OVER, CHANGE_LIST_LABELS, ChangeList, shortenUnchanged } from './chunk-NEHSV55H.js';
155
155
  export { DIFF_LIST_LABELS, DiffList } from './chunk-Z3GDMNMU.js';
156
156
  export { Tag } from './chunk-KYIAFNU7.js';
@@ -159,7 +159,7 @@ export { LONGTEXT_MAX_DEFAULT, RATING_MAX_CEILING, RATING_MAX_DEFAULT, SHEET_COL
159
159
  export { PRESENCE_ACTIVITIES, PRESENCE_HUES, PRESENCE_LABELS, assignPresenceHues, collapseSessions, joinNames, presenceLabels, presenceOrder } from './chunk-Z7JYG5TF.js';
160
160
  import './chunk-3L5NHASN.js';
161
161
  export { ActivityStrip, BarList, ChartEmpty, ChartTooltip, DATA_COLORS, DATA_COLOR_OTHER, Histogram, Legend, Sparkline, StackedBar, StackedColumns, TimeSeries, dataColor, histogramTicks, niceScale, useChartHover } from './chunk-HMVQQEHW.js';
162
- export { CHAT_THREAD_FOLLOW_WITHIN, CHAT_THREAD_LABELS, ChatThread } from './chunk-RV2FGESF.js';
162
+ export { CHAT_THREAD_FOLLOW_WITHIN, CHAT_THREAD_LABELS, ChatThread } from './chunk-PE7XWOUS.js';
163
163
  export { ChoiceButtons } from './chunk-WXRH7NZW.js';
164
164
  export { CalendarGrid, compareDays, daysInMonth, sameDay, shiftDay, shiftMonth, today } from './chunk-GXQ3B46I.js';
165
165
  export { Callout } from './chunk-BPCY7ZID.js';
@@ -221,12 +221,12 @@ export { ACCESS_DENIED_REASONS, AccessDeniedCard } from './chunk-QTMUKRTN.js';
221
221
  export { EmptyState } from './chunk-PPUR46MK.js';
222
222
  export { Accordion, AccordionItem } from './chunk-T4D7RZNI.js';
223
223
  export { ADD_PILL_MS, AddPill } from './chunk-TROLVEZY.js';
224
- export { AGENT_HANDOFF_LABELS, AgentHandoffPanel } from './chunk-GCASX3FD.js';
224
+ export { AGENT_HANDOFF_LABELS, AgentHandoffPanel } from './chunk-G3CUCHBA.js';
225
225
  export { Timeline, TimelineItem } from './chunk-AUQPBL4O.js';
226
226
  export { Section } from './chunk-JQ7IFSF6.js';
227
227
  export { COMPOSER_COUNTER_AT, Composer } from './chunk-JLRXCKTS.js';
228
228
  export { Disclosure } from './chunk-GG4QZWMQ.js';
229
- export { ARTIFACT_PANEL_LABELS, ArtifactPanel, ArtifactWorkspace } from './chunk-HGYHWWA5.js';
229
+ export { ARTIFACT_PANEL_LABELS, ArtifactPanel, ArtifactWorkspace } from './chunk-ALU5EGQB.js';
230
230
  export { SIDE_PANEL_LABELS, SIDE_PANEL_MAX_WIDTH, SIDE_PANEL_MIN_WIDTH, SIDE_PANEL_WIDTH, SidePanel, SidePanelFrame } from './chunk-XODESBSR.js';
231
231
  export { Kbd, isApplePlatform, keyGlyph } from './chunk-SMBKXWML.js';
232
232
  export { FormField, FormRow, FormSection, Input, InputAffix, Label, ReadOnlyField, Textarea, foldLineBreaks } from './chunk-FXQLNETQ.js';
package/dist/styles.css CHANGED
@@ -9074,7 +9074,7 @@ button.crewlet-histogram__bar[data-empty]:focus-visible > .crewlet-histogram__fi
9074
9074
  }
9075
9075
 
9076
9076
 
9077
- /* ChatThread-52KMDXHB.css */
9077
+ /* ChatThread-FGXVDLI2.css */
9078
9078
  /*
9079
9079
  * A conversation as it grows: the scroller, the items a spacing step and a
9080
9080
  * half apart on the panel's 16px inset, and the Jump to latest pill floating
@@ -9092,8 +9092,19 @@ button.crewlet-histogram__bar[data-empty]:focus-visible > .crewlet-histogram__fi
9092
9092
  * THE BROWSER'S SCROLL ANCHORING IS OFF: it pins the content above the
9093
9093
  * reader's view, which fights a last child that keeps growing as an answer
9094
9094
  * streams in. ChatThread.tsx anchors to the end itself.
9095
+ *
9096
+ * THE SCROLLER IS THE CONTAINING BLOCK for everything positioned inside it.
9097
+ * It was not, so an absolutely positioned descendant with no positioned
9098
+ * ancestor of its own (a visually hidden phrase inside a tag, "Sent with")
9099
+ * was placed against the thread instead: outside the scroller's clip, at its
9100
+ * spot in the whole conversation, thousands of pixels below the view. That
9101
+ * made whatever held the thread overflowable (a flush side panel's body read
9102
+ * a scroll height of 4752px around a 557px thread), and a focus could scroll
9103
+ * it, lifting the thread off the panel's foot over a blank band. Positioned
9104
+ * here, such a descendant scrolls and clips with the conversation.
9095
9105
  */
9096
9106
  .crewlet-chat-thread__scroller {
9107
+ position: relative;
9097
9108
  flex: 1;
9098
9109
  min-height: 0;
9099
9110
  overflow: auto;
@@ -25260,7 +25271,7 @@ button.crewlet-presence-stack__member:focus-visible {
25260
25271
  }
25261
25272
 
25262
25273
 
25263
- /* ProposalCard-23575F4C.css */
25274
+ /* ProposalCard-YDGECRES.css */
25264
25275
  /*
25265
25276
  * A proposed change. The card, its head, its strip and its foot are
25266
25277
  * StatusCard's; only the note's register is said here: the consequence is a
@@ -25291,6 +25302,21 @@ button.crewlet-presence-stack__member:focus-visible {
25291
25302
  text-align: end;
25292
25303
  }
25293
25304
 
25305
+ /* WHERE FOCUS LANDS WHEN THE CARD SETTLES (the strip, or the card when it
25306
+ has none): the token ring for a reader on the keyboard, inset so the
25307
+ card's corner does not clip it, and nothing for a pointer (transparent
25308
+ rather than none, so forced colours still draw one). */
25309
+ .crewlet-proposal-card:focus,
25310
+ .crewlet-proposal-card .crewlet-receipt-strip:focus {
25311
+ outline: 2px solid transparent;
25312
+ }
25313
+
25314
+ .crewlet-proposal-card:focus-visible,
25315
+ .crewlet-proposal-card .crewlet-receipt-strip:focus-visible {
25316
+ outline: 2px solid var(--color-focus);
25317
+ outline-offset: -2px;
25318
+ }
25319
+
25294
25320
 
25295
25321
  /* Prose-BTXNFT2Q.css */
25296
25322
  /*
@@ -25804,25 +25830,35 @@ button.crewlet-presence-stack__member:focus-visible {
25804
25830
  }
25805
25831
 
25806
25832
 
25807
- /* ResultTableCard-HZRUDNTX.css */
25833
+ /* ResultTableCard-AP355LQM.css */
25808
25834
  /*
25809
25835
  * A result in a card. The card, its head and its foot are StatusCard's and
25810
25836
  * the table is Table's, drawn flush; what a result adds is the column model:
25811
- * the first column takes the room the figures leave and ends a long name in
25812
- * an ellipsis, and the figures never wrap.
25837
+ * a text column wraps between words, and the figures never wrap.
25813
25838
  */
25814
25839
  .crewlet-result-table-card__table .crewlet-table__table {
25815
25840
  table-layout: auto;
25816
25841
  font-variant-numeric: tabular-nums;
25817
25842
  }
25818
25843
 
25819
- .crewlet-result-table-card__table td:first-child {
25820
- width: 100%;
25821
- max-width: 0;
25822
- overflow: hidden;
25823
- text-overflow: ellipsis;
25824
- white-space: nowrap;
25825
- overflow-wrap: normal;
25844
+ /*
25845
+ * WORDS STAY WHOLE. Table breaks a cell anywhere, which suits its fixed
25846
+ * layout, but under this card's auto layout it lets a column shrink to one
25847
+ * letter, so "Product Manager" stacked letter by letter beside columns with
25848
+ * room to spare. Breaking at words keeps a column as wide as its longest
25849
+ * word, and a word wider than the card still breaks rather than overflow.
25850
+ *
25851
+ * THE NAME WRAPS TOO. The first column used to end a long name in an
25852
+ * ellipsis on one line, and a result's row is not a link and its cell has no
25853
+ * title, so in a 358px panel "Write the MVP plan" read "Write the MVP ..."
25854
+ * with no way to reach the rest. It takes no width of its own: the auto
25855
+ * layout gives each column the room its words ask for, so the name, the
25856
+ * longest text, takes the most and wraps between words, and a short column
25857
+ * beside it keeps its line where there is room. A `width: 100%` on it would
25858
+ * squeeze every other text column to its longest word.
25859
+ */
25860
+ .crewlet-result-table-card__table td {
25861
+ overflow-wrap: break-word;
25826
25862
  }
25827
25863
 
25828
25864
  .crewlet-result-table-card__table .crewlet-table__cell--end {
@@ -29384,7 +29420,7 @@ svg.crewlet-select__chevron {
29384
29420
  }
29385
29421
 
29386
29422
 
29387
- /* SidePanel-ERBUIELD.css */
29423
+ /* SidePanel-VXKUKLOJ.css */
29388
29424
  /*
29389
29425
  * A side panel and the frame that lays it beside the content or over it
29390
29426
  * (`SidePanel`, `SidePanelFrame`, and their artifact presets).
@@ -29544,11 +29580,19 @@ svg.crewlet-select__chevron {
29544
29580
  overscroll-behavior: contain;
29545
29581
  }
29546
29582
 
29547
- /* FLUSH, the body draws no inset of its own: what it holds owns its edges
29548
- (a chat thread that scrolls and insets itself). The published inset reads 0
29549
- inside it, so anything that offsets itself by the inset follows. */
29583
+ /* FLUSH, the body draws no inset of its own and does not scroll: what it
29584
+ holds owns its edges and its scrolling (a chat thread that scrolls and
29585
+ insets itself, shrunk to the body by `min-height: 0`). The published inset
29586
+ reads 0 inside it, so anything that offsets itself by the inset follows.
29587
+
29588
+ CLIPPED, NOT SCROLLABLE. `overflow: hidden` would still be a scroll
29589
+ container, which a focus, `scrollIntoView` or a script can scroll; a flush
29590
+ body that was scrolled 238px lifted its thread off the panel's foot and
29591
+ left a blank band no wheel could reach. `clip` is not a scroll container,
29592
+ so nothing moves it. */
29550
29593
  .crewlet-side-panel__body--flush {
29551
29594
  --crewlet-side-panel-inset: 0px;
29595
+ overflow: clip;
29552
29596
  }
29553
29597
 
29554
29598
  /* THE FOOT holds the panel's own commit, outside the scrolling body, so it
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewlethq/ui",
3
- "version": "0.57.0",
3
+ "version": "0.57.2",
4
4
  "description": "Crewlet shared React components built on @crewlethq/tokens and @crewlethq/icons.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -42,8 +42,8 @@
42
42
  "clean": "rm -rf dist src/generated"
43
43
  },
44
44
  "dependencies": {
45
- "@crewlethq/icons": "0.57.0",
46
- "@crewlethq/tokens": "0.57.0",
45
+ "@crewlethq/icons": "0.57.2",
46
+ "@crewlethq/tokens": "0.57.2",
47
47
  "prosemirror-commands": "1.7.2",
48
48
  "prosemirror-gapcursor": "1.4.1",
49
49
  "prosemirror-history": "1.5.1",
@@ -1,40 +0,0 @@
1
- /*
2
- * A result in a card. The card, its head and its foot are StatusCard's and
3
- * the table is Table's, drawn flush; what a result adds is the column model:
4
- * the first column takes the room the figures leave and ends a long name in
5
- * an ellipsis, and the figures never wrap.
6
- */
7
- .crewlet-result-table-card__table .crewlet-table__table {
8
- table-layout: auto;
9
- font-variant-numeric: tabular-nums;
10
- }
11
-
12
- .crewlet-result-table-card__table td:first-child {
13
- width: 100%;
14
- max-width: 0;
15
- overflow: hidden;
16
- text-overflow: ellipsis;
17
- white-space: nowrap;
18
- overflow-wrap: normal;
19
- }
20
-
21
- .crewlet-result-table-card__table .crewlet-table__cell--end {
22
- white-space: nowrap;
23
- }
24
-
25
- /*
26
- * THE DOWNLOADS ARE SPANS AROUND A BUTTON (the status region beside each is
27
- * a sibling of its button), so the foot's ghost outdent is stated for them
28
- * here: the first one's padding and edge are pulled out so its glyph sits on
29
- * the card's text edge.
30
- */
31
- .crewlet-result-table-card .crewlet-status-card__actions > .crewlet-result-table-card__download:first-child {
32
- margin-inline-start: calc(-1 * (var(--spacing-2) + 1px));
33
- }
34
-
35
- /* The link stands at the foot's far end, its own padding pulled out to the edge. */
36
- .crewlet-result-table-card__link {
37
- display: inline-flex;
38
- margin-inline-start: auto;
39
- margin-inline-end: calc(-1 * (var(--spacing-2) + 1px));
40
- }