@godxjp/ui 31.4.0 → 31.6.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 (80) hide show
  1. package/agent/START-HERE.md +6 -6
  2. package/agent/components/BranchScopePicker.json +5 -0
  3. package/agent/components/Cascader.json +1 -1
  4. package/agent/components/CodeBlock.json +7 -1
  5. package/agent/components/DataTable.json +2 -2
  6. package/agent/components/InfiniteQueryState.json +6 -1
  7. package/agent/components/OrgChart.json +59 -0
  8. package/agent/components/RangeTimeline.json +6 -0
  9. package/agent/components/RecordPicker.json +10 -0
  10. package/agent/components/Transfer.json +5 -0
  11. package/agent/components/Tree.json +21 -4
  12. package/agent/components/TreeSelect.json +1 -1
  13. package/agent/components-index.json +5 -0
  14. package/agent/components.json +123 -10
  15. package/agent/index.json +7 -7
  16. package/agent/llms.txt +7 -7
  17. package/agent/tokens.json +114 -0
  18. package/dist/components/data-display/code-block.js +90 -4
  19. package/dist/components/data-display/data-table.d.ts +3 -0
  20. package/dist/components/data-display/data-table.js +415 -370
  21. package/dist/components/data-display/index.d.ts +2 -0
  22. package/dist/components/data-display/index.js +2 -0
  23. package/dist/components/data-display/org-chart.d.ts +5 -0
  24. package/dist/components/data-display/org-chart.js +169 -0
  25. package/dist/components/data-display/range-timeline.d.ts +20 -0
  26. package/dist/components/data-display/range-timeline.js +217 -197
  27. package/dist/components/data-display/tree.js +179 -23
  28. package/dist/components/data-entry/branch-scope-picker.d.ts +1 -0
  29. package/dist/components/data-entry/branch-scope-picker.js +2 -1
  30. package/dist/components/data-entry/cascader.js +4 -5
  31. package/dist/components/data-entry/record-picker.d.ts +2 -0
  32. package/dist/components/data-entry/record-picker.js +22 -3
  33. package/dist/components/data-entry/transfer.d.ts +1 -1
  34. package/dist/components/data-entry/transfer.js +5 -2
  35. package/dist/components/data-entry/tree-select.js +14 -5
  36. package/dist/components/general/typography.d.ts +32 -0
  37. package/dist/components/general/typography.js +11 -2
  38. package/dist/components/query/infinite-query-state.d.ts +1 -1
  39. package/dist/components/query/infinite-query-state.js +2 -1
  40. package/dist/contracts/measurement.json +1 -1
  41. package/dist/i18n/messages/en.json +26 -2
  42. package/dist/i18n/messages/ja.json +17 -2
  43. package/dist/i18n/messages/vi.json +17 -2
  44. package/dist/lib/hooks.d.ts +8 -4
  45. package/dist/lib/hooks.js +5 -2
  46. package/dist/lib/tree.d.ts +23 -0
  47. package/dist/lib/tree.js +29 -0
  48. package/dist/props/components/data-display.prop.d.ts +72 -3
  49. package/dist/props/components/data-entry.prop.d.ts +31 -4
  50. package/dist/props/components/query.prop.d.ts +8 -1
  51. package/dist/props/registry.d.ts +63 -6
  52. package/dist/props/registry.js +90 -4
  53. package/dist/props/vocabulary/data.prop.d.ts +32 -2
  54. package/dist/props/vocabulary/index.d.ts +1 -1
  55. package/dist/styles/data-display-layout.css +225 -0
  56. package/dist/styles/layers.json +14 -1
  57. package/dist/styles/table-layout.css +16 -1
  58. package/dist/tokens/base.css +1 -0
  59. package/dist/tokens/components/org-chart.css +27 -0
  60. package/dist/tokens/components/tree.css +2 -0
  61. package/docs/FRAME-COVERAGE-REPORT.md +3 -2
  62. package/docs/data-display/code-block.tsx +27 -0
  63. package/docs/data-display/data-table/examples/server-paged.tsx +23 -0
  64. package/docs/data-display/data-table/index.md +2 -0
  65. package/docs/data-display/org-chart.tsx +165 -0
  66. package/docs/data-display/timeline.tsx +33 -0
  67. package/docs/data-display/tree.tsx +154 -0
  68. package/docs/data-entry/branch-scope-picker.tsx +6 -1
  69. package/docs/data-entry/record-picker.tsx +1 -0
  70. package/docs/data-entry/transfer.tsx +1 -0
  71. package/docs/i18n/messages/en.json +19 -0
  72. package/docs/i18n/messages/ja.json +18 -0
  73. package/docs/i18n/messages/vi.json +18 -0
  74. package/docs/navigation/tabs.tsx +17 -15
  75. package/docs/query/data-state.tsx +2 -4
  76. package/docs/query/infinite-query-state.tsx +5 -1
  77. package/docs/roadmap/tree-components.md +2 -1
  78. package/docs/showcase/table-view-tabs.tsx +1 -1
  79. package/package.json +2 -2
  80. package/scripts/ui-audit.mjs +15 -5
@@ -302,10 +302,20 @@ const VOCABULARY_REGISTRY = {
302
302
  category: "data",
303
303
  description: "One entry in the selection-column dropdown \u2014 { key, text, onSelect } (antd SelectionItem)"
304
304
  },
305
+ TableSelectionBuiltInProp: {
306
+ file: "vocabulary/data.prop.ts",
307
+ category: "data",
308
+ description: "Built-in selections entry \u2014 SELECT_ALL | SELECT_INVERT | SELECT_NONE (antd Table.SELECTION_ALL / SELECTION_INVERT / SELECTION_NONE, published as DataTable.SELECTION_*)"
309
+ },
310
+ TableSelectAllMatchingProp: {
311
+ file: "vocabulary/data.prop.ts",
312
+ category: "data",
313
+ description: "Server-paged 'select all N matching' banner \u2014 { total, selected, onSelectedChange } (no antd equivalent; Gmail/Jira/GitHub pattern)"
314
+ },
305
315
  TableRowSelectionProp: {
306
316
  file: "vocabulary/data.prop.ts",
307
317
  category: "data",
308
- description: "DataTable row-selection config \u2014 type | selectedRowKeys | onChange | getCheckboxProps | preserveSelectedRowKeys | selections | hideSelectAll | columnTitle (antd TableRowSelection)"
318
+ description: "DataTable row-selection config \u2014 type | selectedRowKeys | onChange | getCheckboxProps | preserveSelectedRowKeys | selections | hideSelectAll | columnTitle | selectAllLabel | matching (antd TableRowSelection + select-all-matching)"
309
319
  },
310
320
  TableExpandableProp: {
311
321
  file: "vocabulary/data.prop.ts",
@@ -2146,7 +2156,16 @@ const COMPONENT_PROP_REGISTRY = {
2146
2156
  RecordPickerProp: {
2147
2157
  group: "data-entry",
2148
2158
  file: "components/data-entry.prop.ts",
2149
- vocabulary: ["ValueProp", "OnValueChangeProp", "DisabledProp", "SizeProp", "PlaceholderProp"],
2159
+ vocabulary: [
2160
+ "ValueProp",
2161
+ "OnValueChangeProp",
2162
+ "DisabledProp",
2163
+ "SizeProp",
2164
+ "PlaceholderProp",
2165
+ // gh#1044: antd `notFoundContent` for the empty search, and the dialog's load-more text.
2166
+ "NotFoundContentProp",
2167
+ "LabelProp"
2168
+ ],
2150
2169
  note: "One picker whose SHAPE follows the size of the set: Select at or under `threshold`, a searchable Dialog with consumer-declared filters over it (gh#932)."
2151
2170
  },
2152
2171
  RecordPickerFilterProp: {
@@ -2262,7 +2281,15 @@ const COMPONENT_PROP_REGISTRY = {
2262
2281
  TransferProp: {
2263
2282
  group: "data-entry",
2264
2283
  file: "components/data-entry.prop.ts",
2265
- vocabulary: ["DisabledProp", "ClassNameProp"]
2284
+ vocabulary: [
2285
+ "DisabledProp",
2286
+ "ClassNameProp",
2287
+ {
2288
+ field: "locale",
2289
+ local: true,
2290
+ reason: "antd Transfer `locale`, ported for `notFoundContent` only (one node, or a [source, target] pair) \u2014 gh#1044."
2291
+ }
2292
+ ]
2266
2293
  },
2267
2294
  TransferItemProp: {
2268
2295
  group: "data-entry",
@@ -2350,6 +2377,8 @@ const COMPONENT_PROP_REGISTRY = {
2350
2377
  "ColumnFilterStateProp",
2351
2378
  "ColumnSorterProp",
2352
2379
  "TableRowSelectionProp",
2380
+ "TableSelectionBuiltInProp",
2381
+ "TableSelectAllMatchingProp",
2353
2382
  "TableExpandableProp",
2354
2383
  "TableSummaryProp",
2355
2384
  "TableScrollProp",
@@ -2830,7 +2859,8 @@ const COMPONENT_PROP_REGISTRY = {
2830
2859
  InfiniteQueryStateProp: {
2831
2860
  group: "query",
2832
2861
  file: "components/query.prop.ts",
2833
- vocabulary: ["HandlerProp"]
2862
+ // LabelProp: `loadMoreLabel`, the built-in button's idle text (gh#1044).
2863
+ vocabulary: ["HandlerProp", "LabelProp"]
2834
2864
  },
2835
2865
  PrefetchLinkProp: { group: "query", file: "components/query.prop.ts", vocabulary: [] },
2836
2866
  AuthExpiryProviderProp: {
@@ -3905,6 +3935,11 @@ const COMPONENT_PROP_REGISTRY = {
3905
3935
  local: true,
3906
3936
  reason: "An endpoint movement command, not an internally owned value; the consumer commits its row data."
3907
3937
  },
3938
+ {
3939
+ field: "sticky",
3940
+ local: true,
3941
+ reason: "antd Table `sticky` \u2014 `true` or `{ offsetHeader }` (px) keeps the axis header on screen while the page scrolls (gh#1044)."
3942
+ },
3908
3943
  {
3909
3944
  field: "expandedValues",
3910
3945
  local: true,
@@ -4144,6 +4179,8 @@ const COMPONENT_PROP_REGISTRY = {
4144
4179
  local: true,
4145
4180
  reason: "Custom empty content when there are no branches."
4146
4181
  },
4182
+ // gh#1044: antd `notFoundContent` — the line shown when the branch SEARCH matches nothing.
4183
+ "NotFoundContentProp",
4147
4184
  {
4148
4185
  field: "listError",
4149
4186
  local: true,
@@ -4764,6 +4801,55 @@ const COMPONENT_PROP_REGISTRY = {
4764
4801
  "IdProp",
4765
4802
  "ClassNameProp"
4766
4803
  ]
4804
+ },
4805
+ OrgChartNodeVariantProp: {
4806
+ group: "data-display",
4807
+ file: "components/data-display.prop.ts",
4808
+ vocabulary: ["ControlVariantProp"]
4809
+ },
4810
+ OrgChartNodeProp: {
4811
+ group: "data-display",
4812
+ file: "components/data-display.prop.ts",
4813
+ vocabulary: [
4814
+ "TitleProp",
4815
+ "ExtraProp",
4816
+ "ControlVariantProp",
4817
+ { field: "key", local: true, reason: "The node's identity, unique across the chart." },
4818
+ {
4819
+ field: "name",
4820
+ local: true,
4821
+ reason: "The person's or agent's display name (a ReactNode), not a form field `name` \u2014 NameProp is the submitted-field key."
4822
+ },
4823
+ {
4824
+ field: "avatar",
4825
+ local: true,
4826
+ reason: "The mark at the box's inline start, usually an <Avatar>. Decorative."
4827
+ },
4828
+ {
4829
+ field: "children",
4830
+ local: true,
4831
+ reason: "The node's own reports \u2014 the hierarchy itself, not a slot."
4832
+ }
4833
+ ]
4834
+ },
4835
+ OrgChartProp: {
4836
+ group: "data-display",
4837
+ file: "components/data-display.prop.ts",
4838
+ vocabulary: [
4839
+ "LabelProp",
4840
+ "ClassNameProp",
4841
+ "IdProp",
4842
+ {
4843
+ field: "data",
4844
+ local: true,
4845
+ reason: "The hierarchy of OrgChartNodeProp \u2014 the same shape feeds the boxes and the narrow Tree."
4846
+ },
4847
+ {
4848
+ field: "renderNode",
4849
+ local: true,
4850
+ reason: "Escape hatch replacing a box's content; the box, connectors and keyboard stay the library's."
4851
+ }
4852
+ ]
4767
4853
  }
4768
4854
  };
4769
4855
  const PROP_ALIASES_FORBIDDEN = {
@@ -207,6 +207,25 @@ export type TableSelectionItemProp = {
207
207
  text: React.ReactNode;
208
208
  onSelect: (currentRowKeys: string[]) => void;
209
209
  };
210
+ /**
211
+ * A built-in entry for the `selections` list (antd `Table.SELECTION_ALL` / `SELECTION_INVERT` /
212
+ * `SELECTION_NONE`, published here as `DataTable.SELECTION_*`). Mix them with custom
213
+ * {@link TableSelectionItemProp} entries in any order, exactly as antd does.
214
+ */
215
+ export type TableSelectionBuiltInProp = "SELECT_ALL" | "SELECT_INVERT" | "SELECT_NONE";
216
+ /**
217
+ * "Select all N matching" for a server-paged table (Gmail / Jira / GitHub; antd has no
218
+ * equivalent). Once every row of the page is selected, a banner above the header offers the whole
219
+ * result set; choosing it flips `selected`, and the consumer then sends its FILTER to the server
220
+ * instead of the ids. Unticking any row, or "Clear selection", reports `false`.
221
+ */
222
+ export type TableSelectAllMatchingProp = {
223
+ /** Rows the current query matches on the server — the N in "Select all N". */
224
+ total: number;
225
+ /** Controlled: `true` while the whole matching set is selected. */
226
+ selected: boolean;
227
+ onSelectedChange: (selected: boolean) => void;
228
+ };
210
229
  /**
211
230
  * Row-selection configuration (antd `TableRowSelection`). The object form is the full surface;
212
231
  * the older `selectable` / `selected` / `onSelectChange` triple stays and drives the same state.
@@ -224,10 +243,21 @@ export type TableRowSelectionProp<T> = {
224
243
  };
225
244
  /** Keep keys selected even once their row leaves `data` (server paging / filtering). */
226
245
  preserveSelectedRowKeys?: boolean;
227
- /** Extra bulk-select entries under the header checkbox. `true` = the built-in all/none/invert. */
228
- selections?: TableSelectionItemProp[] | boolean;
246
+ /**
247
+ * Extra bulk-select entries under the header checkbox. `true` = the built-in all/invert/none;
248
+ * a list mixes `DataTable.SELECTION_*` built-ins with custom entries, in the order given.
249
+ */
250
+ selections?: (TableSelectionItemProp | TableSelectionBuiltInProp)[] | boolean;
229
251
  hideSelectAll?: boolean;
230
252
  columnTitle?: React.ReactNode;
253
+ /**
254
+ * Accessible name of the header checkbox. Default: "Select all rows", or "Select all rows on
255
+ * this page" once `matching` is set. Name what it really selects — on a server-paged table it
256
+ * is the page, not the result set.
257
+ */
258
+ selectAllLabel?: string;
259
+ /** Opt-in "select all N matching" banner for a server-paged table. */
260
+ matching?: TableSelectAllMatchingProp;
231
261
  };
232
262
  /** Expandable-row configuration (antd/rc-table `ExpandableConfig`). */
233
263
  export type TableExpandableProp<T> = {
@@ -4,4 +4,4 @@ export type { TitleProp, SubtitleProp, StatusProp, DescriptionProp, ExtraProp, F
4
4
  export type { PageDensityProp, PageContainerVariantProp, CenteredShellWidthProp, CenteredShellAlignProp, CenteredShellPresetProp, ErrorSurfaceModeProp, ErrorSurfaceStatusProp, AuthShellPresetProp, MobileShellHeightProp, MobileShellWidthProp, OrientationProp, TableDensityProp, DensityProp, GapNameProp, PadProp, PadRawProp, PadSides, GapProp, GapStepProp, } from "./layout.prop.js";
5
5
  export type { ButtonVariantProp, ButtonSizeProp, BadgeVariantProp, AppSettingPickerAppearanceProp, AppSettingToggleAppearanceProp, ShapeProp, AvatarShapeProp, TextSizeProp, TextToneProp, FontWeightProp, HeadingLevelProp, TextAlignProp, TextWhitespaceProp, TextBreakProp, TypographyTypeProp, TitleLevelProp, TypographyCopyConfigProp, TypographyEditConfigProp, TypographyEllipsisConfigProp, TypographyActionsConfigProp, SizeProp, ControlStatusProp, ControlVariantProp, FormLayoutProp, DescriptionsLayoutProp, BreakpointProp, ConfirmVariantProp, ToneProp, AlertVariantProp, CalloutKindProp, SortDirectionProp, ColumnAlignProp, SortStateProp, RevealDelayProp, RevealTriggerProp, InViewAmountProp, ActivityVariantProp, ActivityAnnounceProp, IconSizeProp, } from "./interaction.prop.js";
6
6
  export type { BreadcrumbItemProp, BreadcrumbProp, BreadcrumbItemMenuProp, BreadcrumbItemMenuEntryProp, BreadcrumbSeparatorProp, BreadcrumbItemRenderProp, } from "./navigation.prop.js";
7
- export type { GetRowIdProp, GetRowLabelProp, OnRowClickProp, ColumnDefProp, TablePresetProp, TableColumnPriorityProp, TableCellIndentProp, SelectedIdsProp, OnSelectChangeProp, OnTableDensityChangeProp, TableRowToneProp, RowToneProp, OnSortChangeProp, OnSearchChangeProp, OnClearFiltersProp, HasActiveFiltersProp, StickyProp, ColumnFixedProp, ColumnFilterValueProp, ColumnFilterItemProp, ColumnFilterStateProp, OnColumnFilterChangeProp, ColumnCompareProp, ColumnSorterProp, TableSelectionItemProp, TableRowSelectionProp, TableExpandableProp, TableSummaryProp, TableScrollProp, TableStickyProp, OnRowProp, TablePaginationProp, TablePaginationPositionProp, DescriptionsColumnProp, DescriptionsSpanProp, DescriptionsItemsProp, } from "./data.prop.js";
7
+ export type { GetRowIdProp, GetRowLabelProp, OnRowClickProp, ColumnDefProp, TablePresetProp, TableColumnPriorityProp, TableCellIndentProp, SelectedIdsProp, OnSelectChangeProp, OnTableDensityChangeProp, TableRowToneProp, RowToneProp, OnSortChangeProp, OnSearchChangeProp, OnClearFiltersProp, HasActiveFiltersProp, StickyProp, ColumnFixedProp, ColumnFilterValueProp, ColumnFilterItemProp, ColumnFilterStateProp, OnColumnFilterChangeProp, ColumnCompareProp, ColumnSorterProp, TableSelectionItemProp, TableSelectionBuiltInProp, TableSelectAllMatchingProp, TableRowSelectionProp, TableExpandableProp, TableSummaryProp, TableScrollProp, TableStickyProp, OnRowProp, TablePaginationProp, TablePaginationPositionProp, DescriptionsColumnProp, DescriptionsSpanProp, DescriptionsItemsProp, } from "./data.prop.js";
@@ -1120,6 +1120,37 @@
1120
1120
  max-block-size: var(--code-block-max-height-lg);
1121
1121
  }
1122
1122
 
1123
+ .ui-code-block-frame {
1124
+ position: relative;
1125
+ min-inline-size: 0;
1126
+ }
1127
+
1128
+ .ui-code-block[data-copyable] {
1129
+ padding-inline-end: calc(var(--code-block-space-inset) + var(--control-height-xs));
1130
+ }
1131
+
1132
+ .ui-code-block[data-copyable][data-wrap="false"] {
1133
+ padding-inline-end: var(--code-block-space-inset);
1134
+ border-inline-end: calc(var(--control-height-xs) + 2 * var(--space-1)) solid transparent;
1135
+ }
1136
+
1137
+ .ui-code-block-copy {
1138
+ position: absolute;
1139
+ inset-block-start: var(--space-1);
1140
+ inset-inline-end: var(--space-1);
1141
+ }
1142
+
1143
+ @media (pointer: coarse) {
1144
+ .ui-code-block[data-copyable] {
1145
+ padding-inline-end: calc(var(--code-block-space-inset) + var(--control-height-default));
1146
+ }
1147
+
1148
+ .ui-code-block[data-copyable][data-wrap="false"] {
1149
+ padding-inline-end: var(--code-block-space-inset);
1150
+ border-inline-end-width: calc(var(--control-height-default) + 2 * var(--space-1));
1151
+ }
1152
+ }
1153
+
1123
1154
  .ui-code-block [data-code-token="comment"],
1124
1155
  .ui-prose pre [data-code-token="comment"] {
1125
1156
  color: var(--code-block-token-comment-color, hsl(var(--muted-foreground)));
@@ -1524,6 +1555,20 @@
1524
1555
  border: var(--stroke-hairline) solid hsl(var(--range-timeline-border-color));
1525
1556
  border-radius: var(--radius-md, calc(var(--radius) / var(--radius-ratio)));
1526
1557
  }
1558
+
1559
+ .ui-range-timeline[data-sticky="true"] {
1560
+ overflow: clip;
1561
+ }
1562
+ .ui-range-timeline-sticky-header {
1563
+ position: sticky;
1564
+ inset-block-start: var(--range-timeline-sticky-offset, 0px);
1565
+ z-index: 2;
1566
+ overflow: hidden;
1567
+ }
1568
+ .ui-range-timeline-scroller {
1569
+ overflow-x: auto;
1570
+ overflow-y: hidden;
1571
+ }
1527
1572
  .ui-range-timeline-canvas {
1528
1573
  min-inline-size: calc(
1529
1574
  var(--range-timeline-label-width) + var(--range-timeline-columns, 1) *
@@ -2150,6 +2195,34 @@
2150
2195
  border-block-start-color: transparent;
2151
2196
  }
2152
2197
 
2198
+ .ui-tree-node[data-filter-node="true"]:not([data-disabled]) .ui-tree-label {
2199
+ color: var(--tree-node-filter-foreground, hsl(var(--text-brand, var(--primary))));
2200
+ font-weight: var(--font-weight-medium);
2201
+ }
2202
+
2203
+ .ui-tree[data-virtual="true"][data-show-line="true"] .ui-tree-node {
2204
+ position: relative;
2205
+ }
2206
+
2207
+ .ui-tree-rail {
2208
+ position: absolute;
2209
+ inset-block: 0;
2210
+ inset-inline-start: calc(
2211
+ var(--tree-node-padding-inline) + (var(--tree-rail-level, 1) - 1) * var(--tree-indent-width) +
2212
+ var(--tree-switcher-size) / 2
2213
+ );
2214
+ border-inline-start: var(--stroke-hairline) solid var(--tree-line-color, hsl(var(--border)));
2215
+ }
2216
+
2217
+ .ui-tree-spacer {
2218
+ flex: none;
2219
+ }
2220
+
2221
+ .ui-tree[data-virtual="true"][data-divided="true"]
2222
+ > .ui-tree-node[aria-level="1"][aria-posinset="1"] {
2223
+ border-block-start-color: transparent;
2224
+ }
2225
+
2153
2226
  .ui-tree-loading {
2154
2227
  display: flex;
2155
2228
  align-items: center;
@@ -2430,3 +2503,155 @@
2430
2503
  flex-direction: column;
2431
2504
  }
2432
2505
  }
2506
+
2507
+ @layer components {
2508
+
2509
+ .ui-org-chart {
2510
+ min-inline-size: 0;
2511
+ container: org-chart / inline-size;
2512
+ }
2513
+
2514
+ .ui-org-chart-scroll {
2515
+ overflow-x: auto;
2516
+ padding: var(--org-chart-padding);
2517
+ }
2518
+
2519
+ .ui-org-chart-tree,
2520
+ .ui-org-chart-children {
2521
+ display: flex;
2522
+ justify-content: center;
2523
+ margin: 0;
2524
+ padding: 0;
2525
+ list-style: none;
2526
+ }
2527
+
2528
+ .ui-org-chart-tree {
2529
+ inline-size: max-content;
2530
+ min-inline-size: 100%;
2531
+ }
2532
+
2533
+ .ui-org-chart-branch {
2534
+ position: relative;
2535
+ display: flex;
2536
+ flex-direction: column;
2537
+ align-items: center;
2538
+ padding-inline: calc(var(--org-chart-sibling-gap) / 2);
2539
+ }
2540
+
2541
+ .ui-org-chart-children {
2542
+ position: relative;
2543
+ padding-block-start: calc(var(--org-chart-level-gap) / 2);
2544
+ }
2545
+
2546
+ .ui-org-chart-children::before,
2547
+ .ui-org-chart-children > .ui-org-chart-branch::before,
2548
+ .ui-org-chart-children > .ui-org-chart-branch::after {
2549
+ position: absolute;
2550
+ box-sizing: border-box;
2551
+ inset-block-start: 0;
2552
+ block-size: calc(var(--org-chart-level-gap) / 2);
2553
+ border: 0 solid var(--org-chart-line-color, hsl(var(--border)));
2554
+ content: "";
2555
+ }
2556
+
2557
+ .ui-org-chart-children::before {
2558
+ inset-inline-start: calc(50% - var(--org-chart-line-width, var(--stroke-hairline)) / 2);
2559
+ border-inline-start-width: var(--org-chart-line-width, var(--stroke-hairline));
2560
+ }
2561
+
2562
+ .ui-org-chart-children > .ui-org-chart-branch {
2563
+ padding-block-start: calc(var(--org-chart-level-gap) / 2);
2564
+ }
2565
+
2566
+ .ui-org-chart-children > .ui-org-chart-branch::before {
2567
+ inset-inline: 0 50%;
2568
+ border-block-start-width: var(--org-chart-line-width, var(--stroke-hairline));
2569
+ }
2570
+
2571
+ .ui-org-chart-children > .ui-org-chart-branch::after {
2572
+ inset-inline: calc(50% - var(--org-chart-line-width, var(--stroke-hairline)) / 2) 0;
2573
+ border-block-start-width: var(--org-chart-line-width, var(--stroke-hairline));
2574
+ border-inline-start-width: var(--org-chart-line-width, var(--stroke-hairline));
2575
+ }
2576
+
2577
+ .ui-org-chart-children > .ui-org-chart-branch:first-child::before,
2578
+ .ui-org-chart-children > .ui-org-chart-branch:last-child::after {
2579
+ border-block-start-width: 0;
2580
+ }
2581
+
2582
+ .ui-org-chart-node {
2583
+ position: relative;
2584
+ display: flex;
2585
+ box-sizing: border-box;
2586
+ inline-size: var(--org-chart-node-inline-size);
2587
+ align-items: flex-start;
2588
+ gap: var(--org-chart-node-gap);
2589
+ padding-block: var(--org-chart-node-padding-block);
2590
+ padding-inline: var(--org-chart-node-padding-inline);
2591
+ border: var(--org-chart-node-border-width, var(--stroke-hairline)) solid
2592
+ var(--org-chart-node-border-color, hsl(var(--border)));
2593
+ border-radius: var(--org-chart-node-radius, var(--radius));
2594
+ background: var(--org-chart-node-background, hsl(var(--card)));
2595
+ color: var(--org-chart-node-foreground, hsl(var(--card-foreground)));
2596
+ font-size: var(--org-chart-node-font-size);
2597
+ text-align: start;
2598
+ }
2599
+
2600
+ .ui-org-chart-node[data-variant="agent"] {
2601
+ border-style: var(--org-chart-agent-border-style);
2602
+ }
2603
+
2604
+ .ui-org-chart-avatar {
2605
+ display: inline-flex;
2606
+ flex: 0 0 auto;
2607
+ }
2608
+
2609
+ .ui-org-chart-text {
2610
+ display: flex;
2611
+ min-inline-size: 0;
2612
+ flex: 1 1 auto;
2613
+ flex-direction: column;
2614
+ gap: var(--org-chart-node-text-gap);
2615
+ }
2616
+
2617
+ .ui-org-chart-name {
2618
+ font-weight: var(--font-weight-medium);
2619
+ overflow-wrap: anywhere;
2620
+ }
2621
+
2622
+ .ui-org-chart-title {
2623
+ color: var(--org-chart-node-title-color, hsl(var(--muted-foreground)));
2624
+ overflow-wrap: anywhere;
2625
+ }
2626
+
2627
+ .ui-org-chart-extra {
2628
+ display: flex;
2629
+ flex-wrap: wrap;
2630
+ gap: var(--org-chart-node-text-gap);
2631
+ }
2632
+
2633
+ .ui-org-chart-list {
2634
+ display: none;
2635
+ }
2636
+
2637
+ .ui-org-chart-list-row {
2638
+ display: inline-flex;
2639
+ min-inline-size: 0;
2640
+ align-items: center;
2641
+ gap: var(--org-chart-node-gap);
2642
+ }
2643
+
2644
+ .ui-org-chart-list-row .ui-org-chart-extra {
2645
+ display: inline-flex;
2646
+ }
2647
+
2648
+ @container org-chart (width < 40rem) {
2649
+ .ui-org-chart-scroll {
2650
+ display: none;
2651
+ }
2652
+
2653
+ .ui-org-chart-list {
2654
+ display: block;
2655
+ }
2656
+ }
2657
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "31.4.0",
2
+ "version": "31.6.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",
@@ -349,6 +349,9 @@
349
349
  },
350
350
  "CodeBlock": {
351
351
  "layers": [
352
+ "control.css",
353
+ "text-layout.css",
354
+ "dialog-layout.css",
352
355
  "data-display-layout.css"
353
356
  ]
354
357
  },
@@ -673,6 +676,16 @@
673
676
  "control.css"
674
677
  ]
675
678
  },
679
+ "OrgChart": {
680
+ "layers": [
681
+ "layout.css",
682
+ "control.css",
683
+ "table-layout.css",
684
+ "alert-layout.css",
685
+ "data-display-layout.css",
686
+ "form-layout.css"
687
+ ]
688
+ },
676
689
  "OrgSwitcher": {
677
690
  "layers": [
678
691
  "shell-layout.css",
@@ -187,7 +187,9 @@
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]) {
190
+ .ui-table-row:not([data-state="selected"]):has(
191
+ > [data-slot="table-cell"][data-flush] > [data-slot="list-row"][data-unread]
192
+ ) {
191
193
  background-color: var(--list-row-unread-background, hsl(var(--muted)));
192
194
  }
193
195
 
@@ -554,6 +556,19 @@
554
556
  gap: var(--table-selection-menu-gap);
555
557
  }
556
558
 
559
+ .ui-data-table-matching[data-active] {
560
+ display: flex;
561
+ flex-wrap: wrap;
562
+ align-items: center;
563
+ justify-content: center;
564
+ gap: var(--space-inline-sm);
565
+ padding-block: var(--space-stack-xs);
566
+ padding-inline: var(--table-cell-space-x, var(--space-section-active));
567
+ border-block-end: var(--stroke-hairline) solid var(--table-border-color, hsl(var(--border)));
568
+ background-color: hsl(var(--muted));
569
+ font-size: var(--font-size-sm);
570
+ }
571
+
557
572
  .ui-data-table-surface .ui-table-bordered {
558
573
  border-width: 0;
559
574
  }
@@ -38,6 +38,7 @@
38
38
  @import "./components/text.css";
39
39
  @import "./components/tree.css";
40
40
  @import "./components/thought-chain.css";
41
+ @import "./components/org-chart.css";
41
42
  @import "./components/welcome.css";
42
43
  @import "./components/actions.css";
43
44
  @import "./components/attachments.css";
@@ -0,0 +1,27 @@
1
+
2
+
3
+ :root {
4
+
5
+ --org-chart-node-inline-size: 13rem;
6
+ --org-chart-node-padding-block: var(--space-3);
7
+ --org-chart-node-padding-inline: var(--space-3);
8
+ --org-chart-node-gap: var(--space-3);
9
+ --org-chart-node-text-gap: var(--space-1);
10
+ --org-chart-node-radius: initial;
11
+ --org-chart-node-border-width: initial;
12
+ --org-chart-node-border-color: initial;
13
+ --org-chart-node-background: initial;
14
+ --org-chart-node-foreground: initial;
15
+ --org-chart-node-title-color: initial;
16
+ --org-chart-node-font-size: var(--font-size-sm, var(--font-size-base));
17
+
18
+ --org-chart-agent-border-style: dashed;
19
+
20
+ --org-chart-level-gap: var(--space-8);
21
+ --org-chart-sibling-gap: var(--space-4);
22
+
23
+ --org-chart-line-width: initial;
24
+ --org-chart-line-color: initial;
25
+
26
+ --org-chart-padding: var(--space-2);
27
+ }
@@ -27,5 +27,7 @@
27
27
  --tree-node-selected-background-alpha: initial;
28
28
  --tree-node-selected-foreground: initial;
29
29
 
30
+ --tree-node-filter-foreground: initial;
31
+
30
32
  --tree-loading-bar-inline-size: 40%;
31
33
  }
@@ -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: **176**
7
- - With ≥1 frame: **152** · zero-frame: **24**
6
+ - Public components: **177**
7
+ - With ≥1 frame: **153** · zero-frame: **24**
8
8
  - Fully covered (every contract axis declared): **0**
9
9
 
10
10
  ## UNTESTED — no `/frame/**` route
@@ -211,6 +211,7 @@ Legend: ✓ covered · N/A reasoned skip · · UNTESTED (blank cell = UNTESTED).
211
211
  | Welcome | ✓ | · | N/A | N/A | · | · | · | · | · | · |
212
212
  | Actions | ✓ | · | N/A | N/A | · | · | · | · | · | · |
213
213
  | ThoughtChain | ✓ | N/A | N/A | N/A | · | · | · | · | · | · |
214
+ | OrgChart | ✓ | N/A | N/A | N/A | · | · | · | · | · | · |
214
215
  | Attachments | ✓ | N/A | · | N/A | · | · | · | · | · | · |
215
216
  | Marquee | ✓ | N/A | N/A | N/A | · | · | · | · | · | · |
216
217
  | Masonry | ✓ | N/A | N/A | N/A | · | · | · | · | · | · |
@@ -84,6 +84,33 @@ export default function Demo() {
84
84
  </Flex>
85
85
  </CardContent>
86
86
  </Card>
87
+ <Card>
88
+ <CardHeader>
89
+ <CardTitle level={2}>Copyable (gh#1032)</CardTitle>
90
+ <CardDescription>
91
+ antd Typography&apos;s copyable, same name and semantics. The button sits in the
92
+ inline-end corner, the block reserves that column so no line runs under it, and the
93
+ copy is announced politely. Pass copyable.text to copy something other than the
94
+ block&apos;s text content; the button stays in its corner while the block scrolls.
95
+ </CardDescription>
96
+ </CardHeader>
97
+ <CardContent>
98
+ <Flex direction="col" gap="md">
99
+ <CodeBlock copyable language="bash" aria-label="Install command">
100
+ pnpm add @godxjp/ui
101
+ </CodeBlock>
102
+ <CodeBlock
103
+ copyable={{ tooltips: ["Copy response", "Copied"] }}
104
+ maxHeight="sm"
105
+ language="json"
106
+ aria-label="Response body with a copy button"
107
+ >
108
+ {responseBody}
109
+ </CodeBlock>
110
+ </Flex>
111
+ </CardContent>
112
+ </Card>
113
+
87
114
  <Card>
88
115
  <CardHeader>
89
116
  <CardTitle level={2}>Syntax colour · the package owns the palette (gh#784)</CardTitle>
@@ -26,6 +26,10 @@ import { Download, FileText, LayoutDashboard, Plus, ReceiptText } from "lucide-r
26
26
  * showTotal, onChange }}` — the real Pagination, total beside the page numbers, bottom-end. The
27
27
  * table is compact, so the pager is `size="sm"` and sits on the same control step as the toolbar
28
28
  * buttons above it. `data` is only the current page; the footer offers ceil(total / pageSize).
29
+ *
30
+ * Selection on a server-paged list (gh#1036): the header checkbox ticks THIS PAGE, and says so.
31
+ * Once the page is fully ticked, `rowSelection.matching` offers every matching row; while that is
32
+ * chosen the bulk action sends the query's filter to the server instead of a list of ids.
29
33
  */
30
34
  const sections: SidebarSectionProp[] = [
31
35
  {
@@ -86,6 +90,8 @@ export default function Demo() {
86
90
  const [page, setPage] = useState(1);
87
91
  const [pageSize, setPageSize] = useState(10);
88
92
  const rows = useMemo(() => fetchPage(page, pageSize), [page, pageSize]);
93
+ const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
94
+ const [allMatching, setAllMatching] = useState(false);
89
95
 
90
96
  return (
91
97
  <AppShell
@@ -126,6 +132,17 @@ export default function Demo() {
126
132
  data={rows}
127
133
  columns={columns}
128
134
  getRowId={(row) => row.id}
135
+ rowSelection={{
136
+ selectedRowKeys: selectedKeys,
137
+ onChange: (keys) => {
138
+ setSelectedKeys(keys);
139
+ },
140
+ matching: {
141
+ total: SERVER_TOTAL,
142
+ selected: allMatching,
143
+ onSelectedChange: setAllMatching,
144
+ },
145
+ }}
129
146
  pagination={{
130
147
  total: SERVER_TOTAL,
131
148
  current: page,
@@ -144,6 +161,12 @@ export default function Demo() {
144
161
  <Download />
145
162
  エクスポート
146
163
  </Button>
164
+ {/* While "all matching" is chosen the count is the server's, not the page's. */}
165
+ <DataTable.BulkActions count={allMatching ? SERVER_TOTAL : undefined}>
166
+ <Button size="sm" variant="outline">
167
+ Mark as paid
168
+ </Button>
169
+ </DataTable.BulkActions>
147
170
  </Flex>
148
171
  <DataTable.ViewOptions />
149
172
  </DataTable.Toolbar>
@@ -5,3 +5,5 @@ The admin list primitive — sticky header, sorting, bulk selection, density tog
5
5
  See the "Approval queue" example.
6
6
 
7
7
  See the "Selectable inbox" example for a `ListRow` hosted in a selectable DataTable: mark that column `flush: true` so the cell drops its own padding and the ListRow owns the inset (gh#1016).
8
+
9
+ See the "Server paged" example for selection on a server-paged list (gh#1036). `rowSelection.selectAllLabel` names the header checkbox; `rowSelection.matching={{ total, selected, onSelectedChange }}` adds the "Select all N matching rows" banner once the page is fully ticked. antd has no equivalent of `matching` — it is the Gmail / Jira / GitHub pattern, and the one deliberate deviation from antd's `rowSelection` here. While `selected` is true every row of any page shows ticked; send the query's filter to the server instead of the ids. Unticking a row or "Clear selection" reports `false`. `selections` also takes antd's `DataTable.SELECTION_ALL` / `SELECTION_INVERT` / `SELECTION_NONE` mixed with custom entries.