@godxjp/ui 31.1.0 → 31.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/agent/START-HERE.md +6 -6
  2. package/agent/components/AuthExpiryProvider.json +40 -0
  3. package/agent/components/DataState.json +3 -1
  4. package/agent/components/DataTable.json +1 -1
  5. package/agent/components/InfiniteQueryState.json +1 -1
  6. package/agent/components/ListRow.json +1 -0
  7. package/agent/components-index.json +5 -0
  8. package/agent/components.json +46 -3
  9. package/agent/index.json +7 -7
  10. package/agent/llms.txt +7 -7
  11. package/agent/patterns/async-data-state.json +1 -1
  12. package/agent/patterns.json +1 -1
  13. package/agent/tokens.json +6 -0
  14. package/dist/components/admin/index.d.ts +2 -0
  15. package/dist/components/admin/index.js +2 -0
  16. package/dist/components/data-display/data-table.js +2 -1
  17. package/dist/components/feedback/alert.d.ts +4 -0
  18. package/dist/components/feedback/alert.js +29 -8
  19. package/dist/components/feedback/auth-expiry.d.ts +30 -0
  20. package/dist/components/feedback/auth-expiry.js +64 -0
  21. package/dist/components/feedback/index.d.ts +2 -0
  22. package/dist/components/feedback/index.js +2 -0
  23. package/dist/components/query/data-state.js +9 -0
  24. package/dist/components/query/index.d.ts +2 -0
  25. package/dist/components/query/index.js +2 -0
  26. package/dist/components/query/infinite-query-state.js +9 -0
  27. package/dist/contracts/measurement.json +1 -1
  28. package/dist/i18n/messages/en.json +3 -0
  29. package/dist/i18n/messages/ja.json +3 -0
  30. package/dist/i18n/messages/vi.json +3 -0
  31. package/dist/props/components/feedback.prop.d.ts +13 -0
  32. package/dist/props/components/index.d.ts +1 -1
  33. package/dist/props/registry.d.ts +10 -1
  34. package/dist/props/registry.js +12 -0
  35. package/dist/props/vocabulary/data.prop.d.ts +8 -0
  36. package/dist/styles/alert-layout.css +4 -0
  37. package/dist/styles/layers.json +35 -1
  38. package/dist/styles/table-layout.css +6 -2
  39. package/dist/tokens/components/feedback.css +2 -0
  40. package/docs/FRAME-COVERAGE-REPORT.md +4 -2
  41. package/docs/data-display/data-table/examples/selectable-inbox.tsx +113 -0
  42. package/docs/data-display/data-table/index.md +2 -0
  43. package/docs/feedback/auth-expiry.tsx +104 -0
  44. package/docs/i18n/messages/en.json +6 -0
  45. package/docs/i18n/messages/ja.json +6 -0
  46. package/docs/i18n/messages/vi.json +6 -0
  47. package/docs/query/data-state.tsx +53 -5
  48. package/package.json +2 -2
@@ -0,0 +1,64 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ const AuthExpiryContext = React.createContext(null);
5
+ function AuthExpiryProvider({ onAuthExpired, children }) {
6
+ const handlerRef = React.useRef(onAuthExpired);
7
+ handlerRef.current = onAuthExpired;
8
+ const countRef = React.useRef(0);
9
+ const firedRef = React.useRef(false);
10
+ const [failed, setFailed] = React.useState(false);
11
+ const invoke = React.useCallback((error) => {
12
+ firedRef.current = true;
13
+ setFailed(false);
14
+ const fail = () => setFailed(true);
15
+ try {
16
+ const result = handlerRef.current({ error });
17
+ if (result && typeof result.then === "function") {
18
+ result.then(void 0, fail);
19
+ }
20
+ } catch {
21
+ fail();
22
+ }
23
+ }, []);
24
+ const register = React.useCallback(
25
+ (error) => {
26
+ countRef.current += 1;
27
+ if (!firedRef.current) invoke(error);
28
+ return () => {
29
+ countRef.current -= 1;
30
+ setTimeout(() => {
31
+ if (countRef.current === 0) {
32
+ firedRef.current = false;
33
+ setFailed(false);
34
+ }
35
+ }, 0);
36
+ };
37
+ },
38
+ [invoke]
39
+ );
40
+ const value = React.useMemo(
41
+ () => ({ register, retry: invoke, failed }),
42
+ [register, invoke, failed]
43
+ );
44
+ return /* @__PURE__ */ jsx(AuthExpiryContext.Provider, { value, children });
45
+ }
46
+ function useAuthExpiry(active, error) {
47
+ const ctx = React.useContext(AuthExpiryContext);
48
+ const errorRef = React.useRef(error);
49
+ errorRef.current = error;
50
+ const register = ctx?.register;
51
+ React.useEffect(() => {
52
+ if (!register || !active) return void 0;
53
+ return register(errorRef.current);
54
+ }, [register, active]);
55
+ if (!ctx || !active) return null;
56
+ return {
57
+ status: ctx.failed ? "failed" : "redirecting",
58
+ retry: () => ctx.retry(errorRef.current)
59
+ };
60
+ }
61
+ export {
62
+ AuthExpiryProvider,
63
+ useAuthExpiry
64
+ };
@@ -14,4 +14,6 @@ export { Callout } from "./callout.js";
14
14
  export type { CalloutProp, CalloutProps } from "./callout.js";
15
15
  export { Alert, AlertTitle, AlertContent, AlertDescription, AlertActions, AlertQueryError, } from "./alert.js";
16
16
  export type { AlertProp, AlertProps, AlertTitleProp, AlertTitleProps, AlertContentProp, AlertContentProps, AlertDescriptionProp, AlertDescriptionProps, AlertActionsProp, AlertActionsProps, AlertQueryErrorProp, AlertQueryErrorProps, } from "./alert.js";
17
+ export { AuthExpiryProvider } from "./auth-expiry.js";
18
+ export type { AuthExpiryProviderProp, AuthExpiryProviderProps } from "./auth-expiry.js";
17
19
  export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "./tooltip.js";
@@ -66,6 +66,7 @@ import {
66
66
  AlertActions,
67
67
  AlertQueryError
68
68
  } from "./alert.js";
69
+ import { AuthExpiryProvider } from "./auth-expiry.js";
69
70
  import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "./tooltip.js";
70
71
  export {
71
72
  Alert,
@@ -86,6 +87,7 @@ export {
86
87
  AlertDialogTrigger,
87
88
  AlertQueryError,
88
89
  AlertTitle,
90
+ AuthExpiryProvider,
89
91
  Banner,
90
92
  Callout,
91
93
  Dialog,
@@ -2,6 +2,7 @@
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { AlertQueryError } from "../feedback/alert.js";
5
+ import { useAuthExpiry } from "../feedback/auth-expiry.js";
5
6
  import { useTranslation } from "../../i18n/use-translation.js";
6
7
  import { classifyQueryError } from "../../lib/query-error.js";
7
8
  function defaultIsEmpty(data) {
@@ -34,10 +35,18 @@ function DataState({
34
35
  }
35
36
  void query.refetch();
36
37
  }, [onRetry, query]);
38
+ const showingAuthError = query.isError && !query.isFetching && classifyQueryError(query.error).category === "auth";
39
+ const authExpiry = useAuthExpiry(showingAuthError, query.error);
37
40
  if (query.isPending && query.fetchStatus === "idle") return /* @__PURE__ */ jsx(Fragment, { children: prerequisite });
38
41
  if (query.isPending) return /* @__PURE__ */ jsx(Fragment, { children: skeleton });
39
42
  if (query.isError) {
40
43
  if (query.isFetching) return /* @__PURE__ */ jsx(Fragment, { children: skeleton });
44
+ if (authExpiry?.status === "redirecting") {
45
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
46
+ skeleton,
47
+ /* @__PURE__ */ jsx("span", { role: "status", "aria-live": "polite", className: "sr-only", children: t("query.authExpiry.redirecting") })
48
+ ] });
49
+ }
41
50
  if (errorRenderer) return /* @__PURE__ */ jsx(Fragment, { children: errorRenderer(query.error, retry) });
42
51
  const info = classifyQueryError(query.error);
43
52
  const canRetry = (info.category === "transient" || info.category === "unknown") && (info.retryable || showRetry || Boolean(onRetry));
@@ -1,6 +1,8 @@
1
1
  export { DataState } from "./data-state.js";
2
2
  export type { DataStateProp, DataStateProps } from "./data-state.js";
3
3
  export { AlertMutationFeedback } from "./mutation-feedback.js";
4
+ export { AuthExpiryProvider } from "../feedback/auth-expiry.js";
5
+ export type { AuthExpiryProviderProp, AuthExpiryProviderProps } from "../feedback/auth-expiry.js";
4
6
  export type { AlertMutationFeedbackProp, AlertMutationFeedbackProps } from "./mutation-feedback.js";
5
7
  export { ButtonRefetch } from "./query-refetch-button.js";
6
8
  export type { ButtonRefetchProp, ButtonRefetchProps } from "./query-refetch-button.js";
@@ -1,10 +1,12 @@
1
1
  import { DataState } from "./data-state.js";
2
2
  import { AlertMutationFeedback } from "./mutation-feedback.js";
3
+ import { AuthExpiryProvider } from "../feedback/auth-expiry.js";
3
4
  import { ButtonRefetch } from "./query-refetch-button.js";
4
5
  import { InfiniteQueryState, flattenItemPages } from "./infinite-query-state.js";
5
6
  import { classifyQueryError, isRetryableQueryError } from "../../lib/query-error.js";
6
7
  export {
7
8
  AlertMutationFeedback,
9
+ AuthExpiryProvider,
8
10
  ButtonRefetch,
9
11
  DataState,
10
12
  InfiniteQueryState,
@@ -2,6 +2,7 @@
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { AlertQueryError } from "../feedback/alert.js";
5
+ import { useAuthExpiry } from "../feedback/auth-expiry.js";
5
6
  import { Button } from "../general/button.js";
6
7
  import { useTranslation } from "../../i18n/use-translation.js";
7
8
  import { classifyQueryError } from "../../lib/query-error.js";
@@ -36,9 +37,17 @@ function InfiniteQueryState({
36
37
  }
37
38
  void query.refetch();
38
39
  }, [onRetry, query]);
40
+ const showingAuthError = query.isError && !(query.isFetching && !query.isFetchingNextPage) && classifyQueryError(query.error).category === "auth";
41
+ const authExpiry = useAuthExpiry(showingAuthError, query.error);
39
42
  if (query.isPending) return /* @__PURE__ */ jsx(Fragment, { children: skeleton });
40
43
  if (query.isError) {
41
44
  if (query.isFetching && !query.isFetchingNextPage) return /* @__PURE__ */ jsx(Fragment, { children: skeleton });
45
+ if (authExpiry?.status === "redirecting") {
46
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
47
+ skeleton,
48
+ /* @__PURE__ */ jsx("span", { role: "status", "aria-live": "polite", className: "sr-only", children: t("query.authExpiry.redirecting") })
49
+ ] });
50
+ }
42
51
  if (errorRenderer) return /* @__PURE__ */ jsx(Fragment, { children: errorRenderer(query.error, retry) });
43
52
  const info = classifyQueryError(query.error);
44
53
  const canRetry = (info.category === "transient" || info.category === "unknown") && (info.retryable || showRetry || Boolean(onRetry));
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$comment": "AUTO-GENERATED by scripts/gen-measurement-contract.mjs — do not edit. Read this instead of guessing: docs/MEASUREMENT-CONTRACT.md.",
3
- "version": "31.1.0",
3
+ "version": "31.3.0",
4
4
  "targetSize": {
5
5
  "standard": "WCAG 2.2 SC 2.5.8 Target Size (Minimum), level AA — 24×24 CSS px",
6
6
  "min": 24,
@@ -635,6 +635,9 @@
635
635
  "action": {
636
636
  "signIn": "Sign in again"
637
637
  }
638
+ },
639
+ "authExpiry": {
640
+ "redirecting": "Your session has ended. Redirecting to sign-in…"
638
641
  }
639
642
  },
640
643
  "chart": {
@@ -622,6 +622,9 @@
622
622
  "action": {
623
623
  "signIn": "再度サインイン"
624
624
  }
625
+ },
626
+ "authExpiry": {
627
+ "redirecting": "セッションの有効期限が切れました。サインイン画面へ移動しています…"
625
628
  }
626
629
  },
627
630
  "chart": {
@@ -623,6 +623,9 @@
623
623
  "action": {
624
624
  "signIn": "Đăng nhập lại"
625
625
  }
626
+ },
627
+ "authExpiry": {
628
+ "redirecting": "Phiên đăng nhập đã hết hạn. Đang chuyển đến trang đăng nhập…"
626
629
  }
627
630
  },
628
631
  "chart": {
@@ -71,6 +71,19 @@ export type AlertQueryErrorProp = {
71
71
  onAuthAction?: HandlerProp;
72
72
  className?: ClassNameProp;
73
73
  };
74
+ /** @see AuthExpiryProvider — central, deduplicated handling of an expired session (gh#1022). */
75
+ export type AuthExpiryProviderProp = {
76
+ /**
77
+ * Called ONCE when a query/mutation surface under the provider meets an auth-class error (401 /
78
+ * invalid or expired token); simultaneous 401s share one call, re-armed after every auth-errored
79
+ * view has gone. Typically redirects to the IdP with the current URL as the return target.
80
+ * Return a promise for a silent refresh: a rejection brings back the sign-in alert.
81
+ */
82
+ onAuthExpired: (context: {
83
+ error: unknown;
84
+ }) => void | Promise<void>;
85
+ children?: ChildrenProp;
86
+ };
74
87
  /** @see Alert */
75
88
  export type AlertProp = React.HTMLAttributes<HTMLDivElement> & {
76
89
  variant?: AlertVariantProp;
@@ -3,7 +3,7 @@ export type { ButtonProp } from "./general.prop.js";
3
3
  export type { CommandProp, InputProp, TextareaProp, FormFieldProp, SearchInputProp, CheckboxProp, CheckboxGroupProp, ChoiceOptionProp, RadioProp, RadioGroupProp, SwitchProp, SliderProp, CalendarProp, DatePickerProp, TimePickerProp, ColorPickerProp, UploadProp, UploadFileItemProp, UploadVariantProp, TreeOptionProp, TreeFieldNamesProp, CascaderProp, TreeSelectProp, ShowCheckedStrategyProp, TransferProp, TransferItemProp, } from "./data-entry.prop.js";
4
4
  export type { AvatarProp, EmptyStateProp, DescriptionsProp, DescriptionsItemProp, BadgeProp, DataTableProp, QrCodeProp, } from "./data-display.prop.js";
5
5
  export type { ChartDatum, ChartSeriesProp, LineChartProp, BarChartProp, AreaChartProp, PieChartProp, } from "./charts.prop.js";
6
- export type { AlertQueryErrorProp, AlertProp, DialogProp, DialogContentProp, AlertTitleProp, AlertContentProp, AlertDescriptionProp, AlertActionsProp, SheetResponsiveProp, SkeletonRowsProp, } from "./feedback.prop.js";
6
+ export type { AlertQueryErrorProp, AuthExpiryProviderProp, AlertProp, DialogProp, DialogContentProp, AlertTitleProp, AlertContentProp, AlertDescriptionProp, AlertActionsProp, SheetResponsiveProp, SkeletonRowsProp, } from "./feedback.prop.js";
7
7
  export type { DataStateProp, InfiniteQueryStateProp, InfiniteQueryHelpers, PrefetchLinkProp, } from "./query.prop.js";
8
8
  export type { DropdownMenuPlacementProp, DropdownMenuTriggerActionProp, PaginationProp, PaginationSizeProp, PaginationAlignProp, StepsProp, StepItemProp, StepStatusProp, StepsTypeProp, TabsProp, TabItemProp, TabsVariantProp, TabsPlacementProp, TabsExtraProp, TabsOnEditProp, } from "./navigation.prop.js";
9
9
  export type { AppProviderProp, AppContextValue, AppSettingKind, AppSettingPickerProp, AppSettingToggleKind, AppSettingToggleProp, ThemeScopeProp, } from "./app.prop.js";
@@ -848,7 +848,7 @@ export declare const COMPONENT_PROP_REGISTRY: {
848
848
  readonly vocabulary: readonly ["OrientationProp", {
849
849
  readonly field: "vertical";
850
850
  readonly local: true;
851
- readonly reason: "antd's boolean spelling of orientation=\"vertical\"; orientation wins over it.";
851
+ readonly reason: 'antd\'s boolean spelling of orientation="vertical"; orientation wins over it.';
852
852
  }, {
853
853
  readonly field: "fullWidth";
854
854
  readonly local: true;
@@ -2415,6 +2415,15 @@ export declare const COMPONENT_PROP_REGISTRY: {
2415
2415
  readonly file: "components/query.prop.ts";
2416
2416
  readonly vocabulary: readonly [];
2417
2417
  };
2418
+ readonly AuthExpiryProviderProp: {
2419
+ readonly group: "feedback";
2420
+ readonly file: "components/feedback.prop.ts";
2421
+ readonly vocabulary: readonly [{
2422
+ readonly field: "onAuthExpired";
2423
+ readonly local: true;
2424
+ readonly reason: "App-wide session-expiry callback receiving the triggering error; fired once per expiry (gh#1022).";
2425
+ }, "ChildrenProp"];
2426
+ };
2418
2427
  readonly AlertQueryErrorProp: {
2419
2428
  readonly group: "feedback";
2420
2429
  readonly file: "components/feedback.prop.ts";
@@ -2833,6 +2833,18 @@ const COMPONENT_PROP_REGISTRY = {
2833
2833
  vocabulary: ["HandlerProp"]
2834
2834
  },
2835
2835
  PrefetchLinkProp: { group: "query", file: "components/query.prop.ts", vocabulary: [] },
2836
+ AuthExpiryProviderProp: {
2837
+ group: "feedback",
2838
+ file: "components/feedback.prop.ts",
2839
+ vocabulary: [
2840
+ {
2841
+ field: "onAuthExpired",
2842
+ local: true,
2843
+ reason: "App-wide session-expiry callback receiving the triggering error; fired once per expiry (gh#1022)."
2844
+ },
2845
+ "ChildrenProp"
2846
+ ]
2847
+ },
2836
2848
  AlertQueryErrorProp: {
2837
2849
  group: "feedback",
2838
2850
  file: "components/feedback.prop.ts",
@@ -5,6 +5,7 @@
5
5
  import type * as React from "react";
6
6
  import type { BreakpointProp, ColumnAlignProp, SortDirectionProp } from "./interaction.prop.js";
7
7
  import type { TableDensityProp } from "./layout.prop.js";
8
+ import type { FlushProp } from "./shared.prop.js";
8
9
  /** Generic row identifier extractor for tables with selection. */
9
10
  export type GetRowIdProp<T> = (row: T) => string;
10
11
  /**
@@ -82,6 +83,13 @@ export type ColumnDefProp<T> = {
82
83
  * is kept reachable as the cell's `title`, so nothing is silently lost.
83
84
  */
84
85
  ellipsis?: boolean;
86
+ /**
87
+ * The cell's CONTENT owns its inset (the same contract as `TableCell flush`): the column's body
88
+ * cells drop their padding so a self-padded row primitive — a `ListRow` in a selectable list —
89
+ * sits on the column's text axis instead of stacking a second inset on the cell's (gh#1016).
90
+ * The header cell keeps its padding, which lines the header label up with the row's own inset.
91
+ */
92
+ flush?: FlushProp;
85
93
  /**
86
94
  * Sort declaration (antd `ColumnType.sorter`). `sorter: true` is the same opt-in as `sortable`;
87
95
  * a comparator sorts by it; `{ compare, multiple }` joins the MULTI-column sort, highest
@@ -50,6 +50,10 @@
50
50
  color: hsl(var(--foreground));
51
51
  }
52
52
 
53
+ [data-slot="alert"][data-query-category="auth"] {
54
+ max-inline-size: var(--query-auth-alert-max-inline-size);
55
+ }
56
+
53
57
  [data-slot="alert"][data-variant="banner"] {
54
58
  border-radius: var(--banner-radius);
55
59
  border-block-start-width: 0;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "31.1.0",
2
+ "version": "31.3.0",
3
3
  "generatedBy": "scripts/gen-style-layers.mjs — do not edit by hand; run `pnpm gen:style-layers`",
4
4
  "base": "base.css",
5
5
  "fonts": "fonts.css",
@@ -67,6 +67,8 @@
67
67
  "layers": [
68
68
  "layout.css",
69
69
  "control.css",
70
+ "text-layout.css",
71
+ "dialog-layout.css",
70
72
  "alert-layout.css"
71
73
  ]
72
74
  },
@@ -74,6 +76,7 @@
74
76
  "layers": [
75
77
  "layout.css",
76
78
  "control.css",
79
+ "text-layout.css",
77
80
  "dialog-layout.css",
78
81
  "alert-layout.css",
79
82
  "form-layout.css"
@@ -83,6 +86,7 @@
83
86
  "layers": [
84
87
  "layout.css",
85
88
  "control.css",
89
+ "text-layout.css",
86
90
  "dialog-layout.css",
87
91
  "alert-layout.css",
88
92
  "form-layout.css"
@@ -99,6 +103,7 @@
99
103
  "shell-layout.css",
100
104
  "layout.css",
101
105
  "control.css",
106
+ "text-layout.css",
102
107
  "dialog-layout.css",
103
108
  "alert-layout.css",
104
109
  "form-layout.css"
@@ -157,6 +162,9 @@
157
162
  "layout.css"
158
163
  ]
159
164
  },
165
+ "AuthExpiryProvider": {
166
+ "layers": []
167
+ },
160
168
  "AuthFooter": {
161
169
  "layers": [
162
170
  "shell-layout.css"
@@ -195,6 +203,8 @@
195
203
  "layers": [
196
204
  "layout.css",
197
205
  "control.css",
206
+ "text-layout.css",
207
+ "dialog-layout.css",
198
208
  "alert-layout.css"
199
209
  ]
200
210
  },
@@ -241,6 +251,8 @@
241
251
  "layers": [
242
252
  "layout.css",
243
253
  "control.css",
254
+ "text-layout.css",
255
+ "dialog-layout.css",
244
256
  "alert-layout.css"
245
257
  ]
246
258
  },
@@ -357,6 +369,7 @@
357
369
  "layers": [
358
370
  "layout.css",
359
371
  "control.css",
372
+ "text-layout.css",
360
373
  "dialog-layout.css",
361
374
  "alert-layout.css",
362
375
  "form-layout.css"
@@ -390,6 +403,8 @@
390
403
  "layers": [
391
404
  "layout.css",
392
405
  "control.css",
406
+ "text-layout.css",
407
+ "dialog-layout.css",
393
408
  "alert-layout.css"
394
409
  ]
395
410
  },
@@ -397,6 +412,7 @@
397
412
  "layers": [
398
413
  "layout.css",
399
414
  "control.css",
415
+ "text-layout.css",
400
416
  "table-layout.css",
401
417
  "dialog-layout.css",
402
418
  "alert-layout.css",
@@ -423,6 +439,7 @@
423
439
  "layers": [
424
440
  "layout.css",
425
441
  "control.css",
442
+ "text-layout.css",
426
443
  "dialog-layout.css",
427
444
  "alert-layout.css",
428
445
  "form-layout.css"
@@ -490,6 +507,8 @@
490
507
  "layers": [
491
508
  "layout.css",
492
509
  "control.css",
510
+ "text-layout.css",
511
+ "dialog-layout.css",
493
512
  "alert-layout.css",
494
513
  "form-layout.css"
495
514
  ]
@@ -498,6 +517,8 @@
498
517
  "layers": [
499
518
  "layout.css",
500
519
  "control.css",
520
+ "text-layout.css",
521
+ "dialog-layout.css",
501
522
  "alert-layout.css"
502
523
  ]
503
524
  },
@@ -505,6 +526,8 @@
505
526
  "layers": [
506
527
  "layout.css",
507
528
  "control.css",
529
+ "text-layout.css",
530
+ "dialog-layout.css",
508
531
  "alert-layout.css",
509
532
  "form-layout.css"
510
533
  ]
@@ -516,6 +539,8 @@
516
539
  "layers": [
517
540
  "layout.css",
518
541
  "control.css",
542
+ "text-layout.css",
543
+ "dialog-layout.css",
519
544
  "alert-layout.css",
520
545
  "form-layout.css"
521
546
  ]
@@ -524,6 +549,8 @@
524
549
  "layers": [
525
550
  "layout.css",
526
551
  "control.css",
552
+ "text-layout.css",
553
+ "dialog-layout.css",
527
554
  "alert-layout.css",
528
555
  "form-layout.css"
529
556
  ]
@@ -549,6 +576,8 @@
549
576
  "layers": [
550
577
  "layout.css",
551
578
  "control.css",
579
+ "text-layout.css",
580
+ "dialog-layout.css",
552
581
  "alert-layout.css"
553
582
  ]
554
583
  },
@@ -649,6 +678,7 @@
649
678
  "shell-layout.css",
650
679
  "layout.css",
651
680
  "control.css",
681
+ "text-layout.css",
652
682
  "dialog-layout.css",
653
683
  "alert-layout.css",
654
684
  "form-layout.css"
@@ -666,6 +696,7 @@
666
696
  "layers": [
667
697
  "layout.css",
668
698
  "control.css",
699
+ "text-layout.css",
669
700
  "dialog-layout.css",
670
701
  "alert-layout.css",
671
702
  "form-layout.css",
@@ -1103,6 +1134,7 @@
1103
1134
  "layers": [
1104
1135
  "layout.css",
1105
1136
  "control.css",
1137
+ "text-layout.css",
1106
1138
  "dialog-layout.css",
1107
1139
  "alert-layout.css",
1108
1140
  "data-display-layout.css",
@@ -1150,6 +1182,7 @@
1150
1182
  "layers": [
1151
1183
  "layout.css",
1152
1184
  "control.css",
1185
+ "text-layout.css",
1153
1186
  "dialog-layout.css",
1154
1187
  "alert-layout.css",
1155
1188
  "data-display-layout.css",
@@ -1162,6 +1195,7 @@
1162
1195
  "layers": [
1163
1196
  "layout.css",
1164
1197
  "control.css",
1198
+ "text-layout.css",
1165
1199
  "dialog-layout.css",
1166
1200
  "alert-layout.css",
1167
1201
  "form-layout.css"
@@ -136,7 +136,7 @@
136
136
  white-space: nowrap;
137
137
  }
138
138
 
139
- [data-slot="table-head"]:has([role="checkbox"]) {
139
+ [data-slot="table-head"]:has([data-slot="checkbox"], [role="checkbox"]) {
140
140
  padding-inline-end: 0;
141
141
  }
142
142
 
@@ -151,7 +151,7 @@
151
151
  white-space: nowrap;
152
152
  }
153
153
 
154
- [data-slot="table-cell"]:has([role="checkbox"]) {
154
+ [data-slot="table-cell"]:has([data-slot="checkbox"], [role="checkbox"]) {
155
155
  padding-inline-end: 0;
156
156
  }
157
157
 
@@ -187,6 +187,10 @@
187
187
  padding: 0;
188
188
  }
189
189
 
190
+ .ui-table-row:has(> [data-slot="table-cell"][data-flush] > [data-slot="list-row"][data-unread]) {
191
+ background-color: var(--list-row-unread-background, hsl(var(--muted)));
192
+ }
193
+
190
194
  .ui-data-table-toolbar {
191
195
  display: flex;
192
196
  flex-wrap: wrap;
@@ -133,6 +133,8 @@
133
133
  --query-load-more-space-block-start: var(--space-stack-md);
134
134
  --query-loading-more-space-block-start: var(--space-stack-sm);
135
135
 
136
+ --query-auth-alert-max-inline-size: 36rem;
137
+
136
138
  --tooltip-max-width: 20rem;
137
139
  --tooltip-space-inline: var(--space-2);
138
140
  --tooltip-space-block: var(--space-1);
@@ -3,8 +3,8 @@
3
3
  > Generated by `scripts/frame-coverage.mjs` (issue #163). Do not edit by hand — run `pnpm check:frame-coverage`.
4
4
  > Standard: [FRAME-COVERAGE-STANDARD.md](./FRAME-COVERAGE-STANDARD.md). A missing dimension is **UNTESTED**, never a pass.
5
5
 
6
- - Public components: **175**
7
- - With ≥1 frame: **152** · zero-frame: **23**
6
+ - Public components: **176**
7
+ - With ≥1 frame: **152** · zero-frame: **24**
8
8
  - Fully covered (every contract axis declared): **0**
9
9
 
10
10
  ## UNTESTED — no `/frame/**` route
@@ -20,6 +20,7 @@
20
20
  - [ ] `Paragraph`
21
21
  - [ ] `Link`
22
22
  - [ ] `ServiceCatalogCta`
23
+ - [ ] `AuthExpiryProvider`
23
24
  - [ ] `SkeletonRows`
24
25
  - [ ] `OverlayPortalProvider`
25
26
  - [ ] `SkeletonDetail`
@@ -101,6 +102,7 @@ Legend: ✓ covered · N/A reasoned skip · · UNTESTED (blank cell = UNTESTED).
101
102
  | TimelineGrid | ✓ | N/A | N/A | N/A | · | · | · | · | · | · |
102
103
  | Table | ✓ | N/A | N/A | N/A | · | · | · | · | · | · |
103
104
  | DataState | ✓ | N/A | · | N/A | · | · | · | · | · | · |
105
+ | AuthExpiryProvider | **✗** | N/A | N/A | N/A | · | · | · | · | · | · |
104
106
  | InfiniteQueryState | ✓ | N/A | · | N/A | · | · | · | · | · | · |
105
107
  | Form | ✓ | ✓ | · | N/A | · | · | · | · | · | · |
106
108
  | FormField | ✓ | N/A | · | N/A | · | · | · | · | · | · |