@flamingo-stack/openframe-frontend-core 0.0.592 → 0.0.593-snapshot.20260905112237

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 (114) hide show
  1. package/dist/{chunk-F543W3F2.js → chunk-3OQIZPUX.js} +3 -3
  2. package/dist/{chunk-CRW4WRMH.js → chunk-3T7ZP3TL.js} +2 -2
  3. package/dist/{chunk-ASFEUMFW.js → chunk-3XDPXOMS.js} +4 -4
  4. package/dist/{chunk-3JOBM57M.cjs → chunk-43ADGEWL.cjs} +24 -24
  5. package/dist/{chunk-3JOBM57M.cjs.map → chunk-43ADGEWL.cjs.map} +1 -1
  6. package/dist/{chunk-YBENO4XG.cjs → chunk-5XQMEDGE.cjs} +10 -10
  7. package/dist/{chunk-YBENO4XG.cjs.map → chunk-5XQMEDGE.cjs.map} +1 -1
  8. package/dist/{chunk-HGEA6PW7.cjs → chunk-66I2QUFE.cjs} +3 -3
  9. package/dist/{chunk-HGEA6PW7.cjs.map → chunk-66I2QUFE.cjs.map} +1 -1
  10. package/dist/{chunk-ZT2Z2BYH.cjs → chunk-ACU7J5BL.cjs} +69 -69
  11. package/dist/{chunk-ZT2Z2BYH.cjs.map → chunk-ACU7J5BL.cjs.map} +1 -1
  12. package/dist/{chunk-FVADHGDP.cjs → chunk-C4YJC5X7.cjs} +4 -4
  13. package/dist/{chunk-FVADHGDP.cjs.map → chunk-C4YJC5X7.cjs.map} +1 -1
  14. package/dist/{chunk-5LJZWTOE.cjs → chunk-CCLPJSY3.cjs} +10 -10
  15. package/dist/{chunk-5LJZWTOE.cjs.map → chunk-CCLPJSY3.cjs.map} +1 -1
  16. package/dist/{chunk-WOGLPNK3.cjs → chunk-CQ35OMPJ.cjs} +3 -3
  17. package/dist/{chunk-WOGLPNK3.cjs.map → chunk-CQ35OMPJ.cjs.map} +1 -1
  18. package/dist/{chunk-XNGE5EE5.js → chunk-DRZ224RU.js} +6 -6
  19. package/dist/{chunk-O4VGEJ7I.cjs → chunk-EWOFXJGH.cjs} +43 -43
  20. package/dist/{chunk-O4VGEJ7I.cjs.map → chunk-EWOFXJGH.cjs.map} +1 -1
  21. package/dist/{chunk-6GMMR667.js → chunk-F5Q3DTP5.js} +5 -5
  22. package/dist/{chunk-R25AUM2R.js → chunk-GBIC3VNA.js} +3 -3
  23. package/dist/{chunk-LXD2QJFG.js → chunk-HOLK4ZMT.js} +3 -3
  24. package/dist/{chunk-W2RUBABW.cjs → chunk-HQWZ4IXU.cjs} +21 -21
  25. package/dist/{chunk-W2RUBABW.cjs.map → chunk-HQWZ4IXU.cjs.map} +1 -1
  26. package/dist/{chunk-JIINHJIT.js → chunk-IKQVXZB5.js} +5 -5
  27. package/dist/{chunk-FSCQOWXI.js → chunk-KVNA3HU2.js} +2 -2
  28. package/dist/{chunk-I7JYX5O3.js → chunk-LKN2KKYZ.js} +57 -4
  29. package/dist/{chunk-I7JYX5O3.js.map → chunk-LKN2KKYZ.js.map} +1 -1
  30. package/dist/{chunk-NZQYZKIN.js → chunk-M5HGULIY.js} +5 -5
  31. package/dist/{chunk-AUA6OSU7.js → chunk-MEWAFY6X.js} +2 -2
  32. package/dist/{chunk-OO6AMBHV.js → chunk-N3RHX26N.js} +3 -3
  33. package/dist/{chunk-NICIJRZ4.cjs → chunk-PETYVGEQ.cjs} +5 -5
  34. package/dist/{chunk-NICIJRZ4.cjs.map → chunk-PETYVGEQ.cjs.map} +1 -1
  35. package/dist/{chunk-WVHQQ3NY.js → chunk-PMN7WDXI.js} +31 -10
  36. package/dist/chunk-PMN7WDXI.js.map +1 -0
  37. package/dist/{chunk-5MHDMDPX.cjs → chunk-QAVT6P5F.cjs} +22 -22
  38. package/dist/{chunk-5MHDMDPX.cjs.map → chunk-QAVT6P5F.cjs.map} +1 -1
  39. package/dist/{chunk-V7RUX5CX.cjs → chunk-S7VW4HVL.cjs} +15 -15
  40. package/dist/{chunk-V7RUX5CX.cjs.map → chunk-S7VW4HVL.cjs.map} +1 -1
  41. package/dist/{chunk-COY57SZP.cjs → chunk-UBRVIVY4.cjs} +188 -167
  42. package/dist/chunk-UBRVIVY4.cjs.map +1 -0
  43. package/dist/{chunk-NYH3NVUF.js → chunk-Y22VQDVW.js} +3 -3
  44. package/dist/{chunk-TVPJ5DIB.cjs → chunk-YLVPQNLO.cjs} +57 -4
  45. package/dist/chunk-YLVPQNLO.cjs.map +1 -0
  46. package/dist/{chunk-XHDBU5EI.js → chunk-YZLUOZKR.js} +2 -2
  47. package/dist/{chunk-WP3AVAMP.cjs → chunk-ZEG3ZJPY.cjs} +33 -33
  48. package/dist/{chunk-WP3AVAMP.cjs.map → chunk-ZEG3ZJPY.cjs.map} +1 -1
  49. package/dist/{chunk-TQMZFXWZ.cjs → chunk-ZK3AZ5YF.cjs} +9 -9
  50. package/dist/{chunk-TQMZFXWZ.cjs.map → chunk-ZK3AZ5YF.cjs.map} +1 -1
  51. package/dist/components/case-studies/index.cjs +9 -9
  52. package/dist/components/case-studies/index.js +3 -3
  53. package/dist/components/chat/entity-cards/dispatch.d.ts.map +1 -1
  54. package/dist/components/chat/index.cjs +2 -2
  55. package/dist/components/chat/index.js +1 -1
  56. package/dist/components/contact/index.cjs +4 -4
  57. package/dist/components/contact/index.js +3 -3
  58. package/dist/components/docs/index.cjs +7 -7
  59. package/dist/components/docs/index.js +6 -6
  60. package/dist/components/embeds/index.cjs +4 -4
  61. package/dist/components/embeds/index.js +3 -3
  62. package/dist/components/faq/index.cjs +4 -4
  63. package/dist/components/faq/index.js +3 -3
  64. package/dist/components/features/index.cjs +3 -3
  65. package/dist/components/features/index.js +2 -2
  66. package/dist/components/help-center-pages/index.cjs +23 -23
  67. package/dist/components/help-center-pages/index.js +14 -14
  68. package/dist/components/index.cjs +38 -38
  69. package/dist/components/index.js +13 -13
  70. package/dist/components/meeting-scheduler/index.cjs +21 -21
  71. package/dist/components/meeting-scheduler/index.js +2 -2
  72. package/dist/components/navigation/index.cjs +6 -6
  73. package/dist/components/navigation/index.js +5 -5
  74. package/dist/components/onboarding-guides/index.cjs +6 -6
  75. package/dist/components/onboarding-guides/index.js +5 -5
  76. package/dist/components/tickets/index.cjs +7 -7
  77. package/dist/components/tickets/index.js +6 -6
  78. package/dist/components/ui/data-table/data-table-row.d.ts +5 -0
  79. package/dist/components/ui/data-table/data-table-row.d.ts.map +1 -1
  80. package/dist/components/ui/data-table/data-table-skeleton.d.ts +1 -0
  81. package/dist/components/ui/data-table/data-table-skeleton.d.ts.map +1 -1
  82. package/dist/components/ui/index.cjs +3 -3
  83. package/dist/components/ui/index.js +2 -2
  84. package/dist/index.cjs +7 -7
  85. package/dist/index.js +6 -6
  86. package/dist/utils/index.cjs +14 -2
  87. package/dist/utils/index.cjs.map +1 -1
  88. package/dist/utils/index.js +14 -2
  89. package/dist/utils/index.js.map +1 -1
  90. package/dist/utils/source-icons.d.ts.map +1 -1
  91. package/package.json +1 -1
  92. package/src/__tests__/data-table-row-height.test.tsx +31 -0
  93. package/src/components/chat/entity-cards/dispatch.tsx +57 -0
  94. package/src/components/ui/data-table/data-table-body.tsx +12 -3
  95. package/src/components/ui/data-table/data-table-row.tsx +15 -3
  96. package/src/components/ui/data-table/data-table-skeleton.tsx +5 -2
  97. package/src/utils/source-icons.ts +24 -0
  98. package/dist/chunk-COY57SZP.cjs.map +0 -1
  99. package/dist/chunk-TVPJ5DIB.cjs.map +0 -1
  100. package/dist/chunk-WVHQQ3NY.js.map +0 -1
  101. /package/dist/{chunk-F543W3F2.js.map → chunk-3OQIZPUX.js.map} +0 -0
  102. /package/dist/{chunk-CRW4WRMH.js.map → chunk-3T7ZP3TL.js.map} +0 -0
  103. /package/dist/{chunk-ASFEUMFW.js.map → chunk-3XDPXOMS.js.map} +0 -0
  104. /package/dist/{chunk-XNGE5EE5.js.map → chunk-DRZ224RU.js.map} +0 -0
  105. /package/dist/{chunk-6GMMR667.js.map → chunk-F5Q3DTP5.js.map} +0 -0
  106. /package/dist/{chunk-R25AUM2R.js.map → chunk-GBIC3VNA.js.map} +0 -0
  107. /package/dist/{chunk-LXD2QJFG.js.map → chunk-HOLK4ZMT.js.map} +0 -0
  108. /package/dist/{chunk-JIINHJIT.js.map → chunk-IKQVXZB5.js.map} +0 -0
  109. /package/dist/{chunk-FSCQOWXI.js.map → chunk-KVNA3HU2.js.map} +0 -0
  110. /package/dist/{chunk-NZQYZKIN.js.map → chunk-M5HGULIY.js.map} +0 -0
  111. /package/dist/{chunk-AUA6OSU7.js.map → chunk-MEWAFY6X.js.map} +0 -0
  112. /package/dist/{chunk-OO6AMBHV.js.map → chunk-N3RHX26N.js.map} +0 -0
  113. /package/dist/{chunk-NYH3NVUF.js.map → chunk-Y22VQDVW.js.map} +0 -0
  114. /package/dist/{chunk-XHDBU5EI.js.map → chunk-YZLUOZKR.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"source-icons.d.ts","sourceRoot":"","sources":["../../src/utils/source-icons.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA2CpD,CAAC;AAEF;;6DAE6D;AAC7D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGxF;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAiDzD,CAAC;AAEF;;kEAEkE;AAClE,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,iCAAiC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA2CpE,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEjF"}
1
+ {"version":3,"file":"source-icons.d.ts","sourceRoot":"","sources":["../../src/utils/source-icons.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAmDpD,CAAC;AAEF;;6DAE6D;AAC7D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGxF;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAyDzD,CAAC;AAEF;;kEAEkE;AAClE,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,iCAAiC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAmDpE,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEjF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flamingo-stack/openframe-frontend-core",
3
- "version": "0.0.592",
3
+ "version": "0.0.593-snapshot.20260905112237",
4
4
  "description": "Shared design system and components for all Flamingo platforms",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -48,6 +48,21 @@ function Table({
48
48
  );
49
49
  }
50
50
 
51
+ /** The same table, but every row carries a sub-row beneath its cells. */
52
+ function TableWithSubRows({ data, rowHeightClassName }: { data: Row[]; rowHeightClassName?: string }) {
53
+ const table = useDataTable({ data, columns });
54
+ return (
55
+ <DataTable table={table}>
56
+ <DataTable.Body<Row>
57
+ minRows={4}
58
+ skeletonRows={4}
59
+ rowHeightClassName={rowHeightClassName}
60
+ renderSubRow={() => <div style={{ height: 96 }}>sub</div>}
61
+ />
62
+ </DataTable>
63
+ );
64
+ }
65
+
51
66
  const rows = (n: number): Row[] => Array.from({ length: n }, (_, i) => ({ id: String(i), name: `Row ${i}` }));
52
67
 
53
68
  /**
@@ -108,6 +123,22 @@ describe('DataTable row height', () => {
108
123
  expect(slots.every(cls => cls.split(/\s+/).includes('border'))).toBe(true);
109
124
  });
110
125
 
126
+ it('sizes the ROW SLOT, so a sub-row does not make real rows outgrow pad rows', () => {
127
+ // The trap: a row with a sub-row is taller than its cells. Sizing the cells
128
+ // left every pad row short by exactly the sub-row — 96px each on a phone
129
+ // board — which is the same jump `minRows` exists to prevent, reintroduced
130
+ // one level down.
131
+ const { container } = render(<TableWithSubRows data={rows(2)} rowHeightClassName={ROW_H} />);
132
+ const slots = slotClasses(container);
133
+
134
+ expect(slots.length).toBeGreaterThanOrEqual(4);
135
+ // Every card — the two real rows and the two pad rows — carries the height.
136
+ expect(slots.every(cls => cls.split(/\s+/).includes(ROW_H))).toBe(true);
137
+ // And the cells inside a real row FILL it rather than restating it, or the
138
+ // card would be the cells plus the sub-row.
139
+ expect(container.innerHTML).toContain('flex-1');
140
+ });
141
+
111
142
  it('keeps the design height when a table does not state one', () => {
112
143
  const { container } = render(<Table data={rows(1)} />);
113
144
  expect(container.innerHTML).toContain('md:h-[78px]');
@@ -45,6 +45,7 @@ import { MingoIcon } from '../../icons';
45
45
  import { ArrowRightUpIcon } from '../../icons-v2-generated/arrows/arrow-right-up-icon';
46
46
  import { ClickupLogoIcon } from '../../icons-v2-generated/brand-logos/clickup-logo-icon';
47
47
  import { SlackLogoGreyIcon } from '../../icons-v2-generated/brand-logos/slack-logo-grey-icon';
48
+ import { BuildingsIcon } from '../../icons-v2-generated/buildings/buildings-icon';
48
49
  import { ChartBar01VerIcon } from '../../icons-v2-generated/charts/chart-bar-01-ver-icon';
49
50
  import { ChartPieIcon } from '../../icons-v2-generated/charts/chart-pie-icon';
50
51
  import { PresentationBarIcon } from '../../icons-v2-generated/charts/presentation-bar-icon';
@@ -53,6 +54,7 @@ import { CodeIcon } from '../../icons-v2-generated/coding/code-icon';
53
54
  import { CodingCommitIcon } from '../../icons-v2-generated/coding/coding-commit-icon';
54
55
  import { CodingPullRequestIcon } from '../../icons-v2-generated/coding/coding-pull-request-icon';
55
56
  import { CalendarIcon } from '../../icons-v2-generated/date-and-time/calendar-icon';
57
+ import { ClipboardListIcon } from '../../icons-v2-generated/documents/clipboard-list-icon';
56
58
  import { FileContentIcon } from '../../icons-v2-generated/documents/file-content-icon';
57
59
  import { NewspaperIcon } from '../../icons-v2-generated/documents/newspaper-icon';
58
60
  import { BankIcon } from '../../icons-v2-generated/finance/bank-icon';
@@ -616,6 +618,35 @@ function SlackChatCard({
616
618
  );
617
619
  }
618
620
 
621
+ /**
622
+ * Generic REF-ONLY card — for types with no `?ids=` list endpoint whose
623
+ * ChatRef already carries everything the card shows (title / preview /
624
+ * url). Same posture as `video`: nothing to fetch, so no skeleton and no
625
+ * `contentRefType`. The per-type glyph is the only thing that varies.
626
+ */
627
+ function RefOnlyChatCard({
628
+ chatRef,
629
+ icon,
630
+ isNewTab,
631
+ discuss,
632
+ }: {
633
+ chatRef: ChatRef;
634
+ icon: React.ReactNode;
635
+ isNewTab: boolean;
636
+ discuss?: CardDiscussAction;
637
+ }) {
638
+ return (
639
+ <MingoInfoCard
640
+ title={chatRef.title}
641
+ description={chatRef.preview ?? undefined}
642
+ icon={icon}
643
+ anchorProps={buildAnchorProps(chatRef.url, isNewTab)}
644
+ menuGroups={cardMenuGroups(chatRef.url, discuss)}
645
+ menuAriaLabel="Card actions"
646
+ />
647
+ );
648
+ }
649
+
619
650
  function DataRoomDocChatCard({
620
651
  chatRef,
621
652
  isNewTab,
@@ -1312,6 +1343,30 @@ const GITHUB_CARD_CONFIGS: Record<string, GitHubCardConfig> = {
1312
1343
  github_pr_review: { label: 'GitHub review', kind: 'pr_review' },
1313
1344
  github_pr_review_public: { label: 'GitHub review (public)', kind: 'pr_review' },
1314
1345
  };
1346
+ interface RefOnlyCardConfig {
1347
+ label: string;
1348
+ icon: () => React.ReactNode;
1349
+ }
1350
+ /** Hub-internal row types whose mapper declares `listApi: () => null` —
1351
+ * design docs + the tenant roster (product-hub), the two people-hub
1352
+ * employee feeds. Adding one = one line here + the `source-icons.ts`
1353
+ * label / icon / documentType entries. */
1354
+ const REF_ONLY_CARD_CONFIGS: Record<string, RefOnlyCardConfig> = {
1355
+ design_doc: { label: 'Design doc', icon: () => <FileContentIcon size={24} /> },
1356
+ openframe_tenant: { label: 'OpenFrame tenant', icon: () => <BuildingsIcon size={24} /> },
1357
+ what_i_shipped: { label: 'What I Shipped', icon: () => <Rocket02Icon size={24} /> },
1358
+ how_i_work: { label: 'How I Work', icon: () => <ClipboardListIcon size={24} /> },
1359
+ };
1360
+ function refOnlyRegistryEntries(): Record<string, ChatCardRegistryEntry> {
1361
+ return registryEntries(REF_ONLY_CARD_CONFIGS, cfg => ({
1362
+ label: cfg.label,
1363
+ bareInline: true,
1364
+ render: (_item, chatRef, opts) => (
1365
+ <RefOnlyChatCard chatRef={chatRef} icon={cfg.icon()} isNewTab={opts.isNewTab} discuss={opts.discuss} />
1366
+ ),
1367
+ }));
1368
+ }
1369
+
1315
1370
  function githubRegistryEntries(): Record<string, ChatCardRegistryEntry> {
1316
1371
  return registryEntries(GITHUB_CARD_CONFIGS, (cfg, docType) =>
1317
1372
  refHydratedEntry(docType, cfg.label, (displayRef, opts) => (
@@ -1423,6 +1478,8 @@ const CHAT_CARD_REGISTRY: Record<string, ChatCardRegistryEntry> = {
1423
1478
  />
1424
1479
  ),
1425
1480
  },
1481
+ // ───────── ref-only types (no list endpoint; the ChatRef IS the card) ─────────
1482
+ ...refOnlyRegistryEntries(),
1426
1483
  slack_message: refHydratedEntry('slack_message', 'Slack message', (displayRef, opts) => (
1427
1484
  <SlackChatCard chatRef={displayRef} isNewTab={opts.isNewTab} discuss={opts.discuss} />
1428
1485
  )),
@@ -172,15 +172,24 @@ function PlaceholderRows({ count, rowHeightClassName }: { count: number; rowHeig
172
172
  // A pad row without one is 2px shorter than the row it stands in for
173
173
  // — invisible per row, 54px over a 27-row remainder, which is the
174
174
  // same shift `minRows` exists to prevent.
175
- className="pointer-events-none relative overflow-hidden rounded-md border border-transparent"
175
+ className={cn(
176
+ 'pointer-events-none relative overflow-hidden rounded-md border border-transparent',
177
+ // The stated slot height belongs on the CARD, exactly as a real
178
+ // row carries it — a real row with a sub-row is taller than its
179
+ // cells, so reserving the cells' height here left every pad row
180
+ // short by the sub-row.
181
+ rowHeightClassName,
182
+ )}
176
183
  aria-hidden="true"
177
184
  >
178
- <div className={cn('hidden py-0 md:flex', ROW_SHELL_CLASSES, rowHeightClassName ?? ROW_HEIGHT_DESKTOP)} />
185
+ <div
186
+ className={cn('hidden py-0 md:flex', ROW_SHELL_CLASSES, rowHeightClassName ? 'h-full' : ROW_HEIGHT_DESKTOP)}
187
+ />
179
188
  <div
180
189
  className={cn(
181
190
  'flex justify-start py-0 md:hidden',
182
191
  ROW_SHELL_CLASSES,
183
- rowHeightClassName ?? ROW_HEIGHT_MOBILE,
192
+ rowHeightClassName ? 'h-full' : ROW_HEIGHT_MOBILE,
184
193
  )}
185
194
  />
186
195
  </div>
@@ -25,6 +25,11 @@ export interface DataTableRowProps<T> {
25
25
  * or the design default). The one place a table states how tall a row is, so
26
26
  * the pad rows and the skeleton can reserve the SAME number — see
27
27
  * `DataTableBodyProps.rowHeightClassName`.
28
+ *
29
+ * It sizes the row SLOT — the whole card — not the cells inside it. A row
30
+ * with a `subRow` is taller than its cells, so sizing the cells would leave
31
+ * the pad rows (which have no sub-row) short by exactly the sub-row: on a
32
+ * phone board that was 96px per missing row.
28
33
  */
29
34
  rowHeightClassName?: string;
30
35
  className?: string;
@@ -106,7 +111,11 @@ function DataTableRowImpl<T>({
106
111
  );
107
112
 
108
113
  const containerClassName = cn(
109
- 'block overflow-hidden rounded-md border border-ods-border bg-ods-card text-inherit no-underline',
114
+ 'overflow-hidden rounded-md border border-ods-border bg-ods-card text-inherit no-underline',
115
+ // A stated slot height goes HERE, on the card, with the cells flexing to
116
+ // fill whatever the sub-row leaves. `border-box` sizing means the number a
117
+ // caller writes is the number the row occupies, borders included.
118
+ rowHeightClassName ? `flex flex-col ${rowHeightClassName}` : 'block',
110
119
  // With a sub-row the link wraps only the cells, so keep the clickable affordance off the whole card.
111
120
  (onClick || isWholeCardLink) && 'cursor-pointer transition-colors hover:bg-ods-bg-active',
112
121
  className,
@@ -118,7 +127,7 @@ function DataTableRowImpl<T>({
118
127
  'flex',
119
128
  ROW_SHELL_CLASSES,
120
129
  rowHeightClassName
121
- ? `py-0 ${rowHeightClassName}`
130
+ ? 'min-h-0 flex-1 py-0'
122
131
  : compact
123
132
  ? 'py-[var(--spacing-system-xsf)]'
124
133
  : autoHeight
@@ -171,7 +180,10 @@ function DataTableRowImpl<T>({
171
180
  <Link
172
181
  href={href}
173
182
  prefetch={false}
174
- className="block cursor-pointer text-inherit no-underline transition-colors hover:bg-ods-bg-active"
183
+ className={cn(
184
+ 'cursor-pointer text-inherit no-underline transition-colors hover:bg-ods-bg-active',
185
+ rowHeightClassName ? 'flex min-h-0 flex-1 flex-col' : 'block',
186
+ )}
175
187
  onClick={handleClick}
176
188
  >
177
189
  {cells}
@@ -31,6 +31,7 @@ export interface DataTableSkeletonProps {
31
31
  rowClassName?: string;
32
32
  /**
33
33
  * REPLACES the design row height, for a table whose rows are not that tall.
34
+ * Sizes the CARD, as a real row does.
34
35
  * Appending a height through `rowClassName` cannot do this: tailwind-merge
35
36
  * drops the plain `h-[66px]` but keeps `md:h-[78px]`, so the override held
36
37
  * on a phone and lost on a desktop. See `DataTableBodyProps.rowHeightClassName`.
@@ -50,6 +51,8 @@ export function DataTableSkeleton({ rows = 10, className, rowClassName, rowHeigh
50
51
  key={index}
51
52
  className={cn(
52
53
  'relative animate-pulse overflow-hidden rounded-md border border-ods-border bg-ods-card',
54
+ // The slot height sits on the card, matching a real row.
55
+ rowHeightClassName,
53
56
  className,
54
57
  )}
55
58
  >
@@ -57,7 +60,7 @@ export function DataTableSkeleton({ rows = 10, className, rowClassName, rowHeigh
57
60
  className={cn(
58
61
  'hidden py-0 md:flex',
59
62
  ROW_SHELL_CLASSES,
60
- rowHeightClassName ?? ROW_HEIGHT_DESKTOP,
63
+ rowHeightClassName ? 'h-full' : ROW_HEIGHT_DESKTOP,
61
64
  rowClassName,
62
65
  )}
63
66
  >
@@ -89,7 +92,7 @@ export function DataTableSkeleton({ rows = 10, className, rowClassName, rowHeigh
89
92
  className={cn(
90
93
  'flex justify-start py-0 md:hidden',
91
94
  ROW_SHELL_CLASSES,
92
- rowHeightClassName ?? ROW_HEIGHT_MOBILE,
95
+ rowHeightClassName ? 'h-full' : ROW_HEIGHT_MOBILE,
93
96
  rowClassName,
94
97
  )}
95
98
  >
@@ -68,6 +68,14 @@ export const SOURCE_ICON_NAMES: Record<string, string> = {
68
68
 
69
69
  // Communications
70
70
  'slack-messages': 'slack',
71
+
72
+ // People-hub employee content
73
+ 'what-i-shipped': 'package',
74
+ 'how-i-work': 'book-open',
75
+
76
+ // Product-hub internal
77
+ 'design-docs': 'file-text',
78
+ 'openframe-tenants': 'globe',
71
79
  };
72
80
 
73
81
  /** Lookup an icon name by RagTableConfig.id. Returns undefined when
@@ -139,6 +147,14 @@ export const SOURCE_LABELS_BY_TABLE: Record<string, string> = {
139
147
 
140
148
  // Communications
141
149
  'slack-messages': 'OpenMSP Community',
150
+
151
+ // People-hub employee content
152
+ 'what-i-shipped': 'What I Shipped',
153
+ 'how-i-work': 'How I Work',
154
+
155
+ // Product-hub internal
156
+ 'design-docs': 'Design Docs',
157
+ 'openframe-tenants': 'OpenFrame Tenants',
142
158
  };
143
159
 
144
160
  /** Lookup a human-readable label by RagTableConfig.id. Falls back
@@ -212,6 +228,14 @@ export const DEFAULT_DOCUMENT_TYPE_TO_TABLE_ID: Record<string, string> = {
212
228
 
213
229
  // Communications
214
230
  slack_message: 'slack-messages',
231
+
232
+ // People-hub employee content
233
+ what_i_shipped: 'what-i-shipped',
234
+ how_i_work: 'how-i-work',
235
+
236
+ // Product-hub internal
237
+ design_doc: 'design-docs',
238
+ openframe_tenant: 'openframe-tenants',
215
239
  };
216
240
 
217
241
  /**