@streamoid/ui 0.6.17 → 0.6.18

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 (131) hide show
  1. package/README.md +35 -18
  2. package/dist/docs/AGENTS.md +321 -0
  3. package/dist/docs/CreditWarningBanner.md +305 -0
  4. package/dist/docs/InvoiceHistoryMobile.md +222 -0
  5. package/dist/docs/ScAccess.md +259 -0
  6. package/dist/docs/ScAppCard.md +244 -0
  7. package/dist/docs/ScAppCardForCopilot.md +230 -0
  8. package/dist/docs/ScAppCardV3.md +273 -0
  9. package/dist/docs/ScAppField.md +308 -0
  10. package/dist/docs/ScAppListingCard.md +271 -0
  11. package/dist/docs/ScAppSwitchPanel.md +286 -0
  12. package/dist/docs/ScAppcardLogos.md +226 -0
  13. package/dist/docs/ScArtifaxInvite.md +262 -0
  14. package/dist/docs/ScArtifaxSidebar.md +330 -0
  15. package/dist/docs/ScAskAgentButton.md +307 -0
  16. package/dist/docs/ScBadges.md +261 -0
  17. package/dist/docs/ScBeacon.md +244 -0
  18. package/dist/docs/ScBillingHistoryHeader.md +210 -0
  19. package/dist/docs/ScBillingHistoryTableList.md +243 -0
  20. package/dist/docs/ScBillingLogsTableHeader.md +212 -0
  21. package/dist/docs/ScBillingLogsTableList.md +251 -0
  22. package/dist/docs/ScBriefCard.md +255 -0
  23. package/dist/docs/ScButton.md +251 -0
  24. package/dist/docs/ScCalendar.md +268 -0
  25. package/dist/docs/ScCalendarDateComps.md +264 -0
  26. package/dist/docs/ScCatalogixInvite.md +345 -0
  27. package/dist/docs/ScCatalogixSidebar.md +337 -0
  28. package/dist/docs/ScCatalogixStoreHeader.md +246 -0
  29. package/dist/docs/ScCatalogixStoreTableList.md +316 -0
  30. package/dist/docs/ScCheckField.md +233 -0
  31. package/dist/docs/ScCheckbox.md +272 -0
  32. package/dist/docs/ScCounter.md +235 -0
  33. package/dist/docs/ScCreditsUsageCard.md +247 -0
  34. package/dist/docs/ScCreditsUsageCardMobile.md +224 -0
  35. package/dist/docs/ScDefaultCard.md +269 -0
  36. package/dist/docs/ScDp.md +245 -0
  37. package/dist/docs/ScDrawer.md +318 -0
  38. package/dist/docs/ScFieldButton.md +255 -0
  39. package/dist/docs/ScFileField.md +268 -0
  40. package/dist/docs/ScGoogleSignIn.md +250 -0
  41. package/dist/docs/ScGuide.md +278 -0
  42. package/dist/docs/ScHDivider.md +213 -0
  43. package/dist/docs/ScHeader.md +222 -0
  44. package/dist/docs/ScImageField.md +253 -0
  45. package/dist/docs/ScInChatList.md +277 -0
  46. package/dist/docs/ScInChatMessage.md +205 -0
  47. package/dist/docs/ScInfoPopup.md +248 -0
  48. package/dist/docs/ScIntialProfileCover.md +233 -0
  49. package/dist/docs/ScInvoiceHistoryMobile.md +187 -0
  50. package/dist/docs/ScLogoUnit.md +232 -0
  51. package/dist/docs/ScMappingCard.md +241 -0
  52. package/dist/docs/ScMediaApproval.md +301 -0
  53. package/dist/docs/ScMediaSelect.md +310 -0
  54. package/dist/docs/ScMenuOptions.md +308 -0
  55. package/dist/docs/ScMobileBottomAction.md +252 -0
  56. package/dist/docs/ScMobileTopNav.md +279 -0
  57. package/dist/docs/ScModal.md +291 -0
  58. package/dist/docs/ScOnlyField.md +302 -0
  59. package/dist/docs/ScOnlyIcon.md +213 -0
  60. package/dist/docs/ScPagination.md +284 -0
  61. package/dist/docs/ScPairtext.md +287 -0
  62. package/dist/docs/ScPendingAction.md +238 -0
  63. package/dist/docs/ScPhtogenixInvite.md +275 -0
  64. package/dist/docs/ScPlanCard.md +302 -0
  65. package/dist/docs/ScPlanComparison.md +264 -0
  66. package/dist/docs/ScPlanDetailsCard.md +246 -0
  67. package/dist/docs/ScPlanDetailsCardMobile.md +240 -0
  68. package/dist/docs/ScPopUpMenu.md +224 -0
  69. package/dist/docs/ScProfile.md +234 -0
  70. package/dist/docs/ScProfileImageUpdate.md +261 -0
  71. package/dist/docs/ScProfileOptions.md +245 -0
  72. package/dist/docs/ScProfilePopup.md +396 -0
  73. package/dist/docs/ScProfileSettingsComp.md +250 -0
  74. package/dist/docs/ScProfileV2Mobile.md +216 -0
  75. package/dist/docs/ScProgressBar.md +267 -0
  76. package/dist/docs/ScQuickPrompt.md +277 -0
  77. package/dist/docs/ScRadio.md +228 -0
  78. package/dist/docs/ScReferralCardMobile.md +226 -0
  79. package/dist/docs/ScReferralTableHeader.md +260 -0
  80. package/dist/docs/ScReferralTableList.md +293 -0
  81. package/dist/docs/ScRole.md +226 -0
  82. package/dist/docs/ScRoleMobile.md +199 -0
  83. package/dist/docs/ScSelect.md +270 -0
  84. package/dist/docs/ScSelection.md +256 -0
  85. package/dist/docs/ScSelectionList.md +272 -0
  86. package/dist/docs/ScSelectionPill.md +240 -0
  87. package/dist/docs/ScSelectionPillGroup.md +302 -0
  88. package/dist/docs/ScSettingsNav.md +212 -0
  89. package/dist/docs/ScSettingsTabComp.md +260 -0
  90. package/dist/docs/ScSideBarLogoUnit.md +340 -0
  91. package/dist/docs/ScSidebar.md +243 -0
  92. package/dist/docs/ScSidebarIcons.md +232 -0
  93. package/dist/docs/ScSidebarMenu.md +283 -0
  94. package/dist/docs/ScSidebarProfile.md +231 -0
  95. package/dist/docs/ScSidebarSwitchMenu.md +258 -0
  96. package/dist/docs/ScSlider.md +194 -0
  97. package/dist/docs/ScStoreCard.md +252 -0
  98. package/dist/docs/ScStrLogo.md +253 -0
  99. package/dist/docs/ScStreamoidWordmark.md +302 -0
  100. package/dist/docs/ScSubAgent.md +226 -0
  101. package/dist/docs/ScTabComp.md +308 -0
  102. package/dist/docs/ScTabField.md +258 -0
  103. package/dist/docs/ScTabSwitcher.md +307 -0
  104. package/dist/docs/ScTableHeader.md +261 -0
  105. package/dist/docs/ScTableList.md +301 -0
  106. package/dist/docs/ScTableListMobile.md +282 -0
  107. package/dist/docs/ScTabs.md +268 -0
  108. package/dist/docs/ScTaxonomyPill.md +263 -0
  109. package/dist/docs/ScTextArea.md +259 -0
  110. package/dist/docs/ScTextField.md +324 -0
  111. package/dist/docs/ScThinkingStepIcon.md +249 -0
  112. package/dist/docs/ScTodoList.md +288 -0
  113. package/dist/docs/ScToggleSwitch.md +229 -0
  114. package/dist/docs/ScUsageHistoryMobile.md +194 -0
  115. package/dist/docs/ScVDivider.md +215 -0
  116. package/dist/docs/ScValueMappingL1.md +256 -0
  117. package/dist/docs/ScVersion.md +251 -0
  118. package/dist/docs/ScWorkspace.md +233 -0
  119. package/dist/docs/ScWorkspaceCard.md +234 -0
  120. package/dist/docs/ScWorkspaceSettingsMobile.md +265 -0
  121. package/dist/docs/ScWorkspaceSwitchCard.md +314 -0
  122. package/dist/docs/ScWorkspaceSwitchMobile.md +241 -0
  123. package/dist/docs/ScWorkspaceSwitchMobileV2.md +278 -0
  124. package/dist/docs/StreamoidSidebar.md +403 -0
  125. package/dist/docs/StreamoidWorkspaceSwitcher.md +307 -0
  126. package/dist/docs/UsageHistoryMobile.md +235 -0
  127. package/dist/docs/components.json +4849 -0
  128. package/dist/index.css +36 -36
  129. package/dist/index.d.mts +10 -0
  130. package/dist/index.d.ts +10 -0
  131. package/package.json +3 -2
@@ -0,0 +1,212 @@
1
+ ---
2
+ component: ScBillingLogsTableHeader
3
+ package: "@streamoid/ui"
4
+ category: billing
5
+ status: legacy
6
+ renders: div
7
+ tags: [credit-logs, usage-logs, table-header, column-headers, billing, credits, balance]
8
+ related: [ScBillingLogsTableList, ScHeader, ScBillingHistoryHeader]
9
+ do_not_confuse_with: [ScBillingHistoryHeader, ScHeader, ScTableHeader]
10
+ ---
11
+
12
+ # ScBillingLogsTableHeader
13
+
14
+ **The fixed 6-column header strip for the credit/usage-logs table:** `App` ·
15
+ `Activity` · `Used by` · `Date` · `Credits used` · `Balance`. Six `ScHeader` cells
16
+ on a neutral fill, width-matched to `ScBillingLogsTableList`. No content props at
17
+ all — every label is baked in.
18
+
19
+ > **Legacy.** Nothing renders this today. The live Billing → *Usage logs* tab in
20
+ > `@streamoid/settings` **hand-rolls** its header from raw `ScHeader` cells because
21
+ > this strip's column set no longer matches the API (see §3). It is not
22
+ > `@deprecated` in source and still exports fine — but if you reach for it you are
23
+ > almost certainly reproducing a layout the product has moved off.
24
+
25
+ ## TL;DR for agents
26
+
27
+ - **Reach for it when:** you genuinely want the original six columns *including*
28
+ a per-row running `Balance`, and you are pairing it with
29
+ `ScBillingLogsTableList`.
30
+ - **Don't reach for it when:** your log rows have no running balance, or the credits
31
+ figure needs a sign and two colours — that is the live shape, and it is built from
32
+ `ScHeader` cells directly (§3 has the recipe).
33
+ - **Three things that will bite you:**
34
+ 1. `className` is the **only** prop; the six labels are hardcoded English.
35
+ 2. Its `Credits used` cell is `7.5rem` **left-aligned**; the live table renamed it
36
+ to `Credits` at `5rem` **right-aligned**. Mixing the two misaligns the column.
37
+ 3. Not sticky, not rounded — your wrapper owns that.
38
+
39
+ ---
40
+
41
+ ## 1. How to use it
42
+
43
+ ### Import
44
+
45
+ ```tsx
46
+ import { ScBillingLogsTableHeader, ScBillingLogsTableList } from "@streamoid/ui";
47
+ import "@streamoid/ui/dist/index.css"; // once, at your app root
48
+ ```
49
+
50
+ ### Minimal usage
51
+
52
+ ```tsx
53
+ <ScBillingLogsTableHeader />
54
+ ```
55
+
56
+ ### Props
57
+
58
+ | Prop | Type | Default | Notes |
59
+ |---|---|---|---|
60
+ | `className` | `string` | – | Appended to the root class. **The only prop.** |
61
+
62
+ The interface does **not** extend `HTMLAttributes`, and the destructured `...props`
63
+ is never spread — `style`, `onClick`, `id` and `data-*` are both a type error and a
64
+ no-op.
65
+
66
+ ### Fixed layout (must match your rows)
67
+
68
+ | Cell | Label | Width |
69
+ |---|---|---|
70
+ | 1 | `App` | `flex: 1` |
71
+ | 2 | `Activity` | `flex: 1` |
72
+ | 3 | `Used by` | `7.5rem`, `flex-shrink: 0` |
73
+ | 4 | `Date` | `7.5rem`, `flex-shrink: 0` |
74
+ | 5 | `Credits used` | `7.5rem`, `flex-shrink: 0` |
75
+ | 6 | `Balance` | `7.5rem`, `flex-shrink: 0` |
76
+
77
+ Root: `padding: 0.75rem 1rem`, `gap: 1.5rem`, background
78
+ `--alias-fill-neutral-neutral` — identical to `ScBillingHistoryHeader`'s root, so
79
+ the two header strips are visually interchangeable even though their columns are not.
80
+
81
+ ### Recipes
82
+
83
+ ```tsx
84
+ // Original 6-column shape, sticky over a scrolling rounded surface
85
+ <div className="w-full relative" style={{ backgroundColor: "var(--alias-surface-base)", borderRadius: "var(--radius-3xl)", overflow: "clip" }}>
86
+ <ScBillingLogsTableHeader />
87
+ {logs.length === 0 && <EmptyRow>No usage logs found</EmptyRow>}
88
+ {logs.map((log) => (
89
+ <ScBillingLogsTableList
90
+ key={log._id}
91
+ app={log.service?.serviceGroupName || "—"}
92
+ activity={log.meta?.info || "Credit usage"}
93
+ usedBy={userMap[log.triggeredByUserId] || "System"}
94
+ date={formatDate(log.createdAt)}
95
+ creditsUsed={String(log.amount)}
96
+ balance={formatCredits(log.runningBalance)}
97
+ />
98
+ ))}
99
+ </div>
100
+ ```
101
+
102
+ ---
103
+
104
+ ## 2. Where to use it
105
+
106
+ - **Billing → Usage logs tab.** That is the surface it was designed for.
107
+ - **No live render site.** The only call in any repo is
108
+ `cxo-dashboard/src/app/components/billing-content.tsx:1670`, and nothing imports
109
+ `BillingContent` from that file — it is orphaned. The live page is
110
+ `packages/settings/src/billing-content.tsx` (`UsageLogsTable`), which builds its
111
+ own header.
112
+
113
+ ---
114
+
115
+ ## 3. When to use it
116
+
117
+ ### Use it when
118
+
119
+ - You have a per-row **running balance** to show and want the six-column shape
120
+ exactly as designed.
121
+
122
+ ### Don't use it — reach for this instead
123
+
124
+ | Situation | Use instead |
125
+ |---|---|
126
+ | Log rows without a running balance, and/or signed ±credits in green/red | `ScHeader` cells in your own flex row — this is what the live page does |
127
+ | Invoice columns (`Invoice`, `Amount`, `Date`, `Action`) | `ScBillingHistoryHeader` + `ScBillingHistoryTableList` |
128
+ | Renamed or localised labels, or a different column count | `ScHeader` — it is a two-prop primitive; the strip is 20 lines of flex |
129
+ | A sortable header | `ScHeader` with `state="up"` / `"down"` and your own handler |
130
+
131
+ The live replacement, verbatim in shape:
132
+
133
+ ```tsx
134
+ // 5 columns: Balance dropped, "Credits used" → "Credits" (5rem, right-aligned)
135
+ <div style={{ position: "sticky", top: 0, zIndex: 1,
136
+ background: "var(--alias-fill-neutral-neutral, #1a1a1a)",
137
+ padding: "var(--spacing-xl, 0.75rem) var(--spacing-3xl, 1rem)",
138
+ display: "flex", gap: "var(--spacing-6xl, 1.5rem)", alignItems: "center" }}>
139
+ <ScHeader text="App" state="none" style={{ flex: 1, alignItems: "flex-start", gap: "0.25rem" }} />
140
+ <ScHeader text="Activity" state="none" style={{ flex: 1, alignItems: "flex-start", gap: "0.25rem" }} />
141
+ <ScHeader text="Used by" state="none" style={{ flexShrink: 0, width: "7.5rem" }} />
142
+ <ScHeader text="Date" state="none" style={{ flexShrink: 0, width: "7.5rem" }} />
143
+ <ScHeader text="Credits" state="none" style={{ flexShrink: 0, width: "5rem", justifyContent: "flex-end" }} />
144
+ </div>
145
+ ```
146
+
147
+ ### Don't confuse with
148
+
149
+ | You may actually want | Not this |
150
+ |---|---|
151
+ | `ScBillingHistoryHeader` — 4 columns (`Invoice`, `Amount`, `Date`, `Action`), still live | Same background, padding and gap; different labels and widths. Swapping them silently misaligns your rows. |
152
+ | `ScHeader` — the single header **cell** (`text`, `state`, spreads props) | This is a fixed 6-cell strip |
153
+ | `ScTableHeader` — the generic library table header | Not billing-specific, not width-matched to the logs rows |
154
+
155
+ ---
156
+
157
+ ## 4. Why to use it
158
+
159
+ - **Width parity with `ScBillingLogsTableList`** is the only real value: the
160
+ `flex:1 / flex:1 / 7.5rem × 4` pattern and the `1.5rem` gap are duplicated in the
161
+ row component, so using both guarantees alignment.
162
+ - **Token-driven header fill and typography** via `ScHeader`, so the strip survives
163
+ light mode.
164
+
165
+ If you are not using `ScBillingLogsTableList`, this component buys you almost
166
+ nothing over five lines of `ScHeader` cells — and costs you six hardcoded labels.
167
+
168
+ ---
169
+
170
+ ## Gotchas
171
+
172
+ **1. Zero configuration.** No labels, no widths, no sort state, no `style`. Any
173
+ change to the column set means dropping the component.
174
+
175
+ **2. `state="none"` on every cell** — no sort arrows, ever, even though `ScHeader`
176
+ supports them.
177
+
178
+ **3. Extra props vanish.** `({ className, ...props })` never spreads the rest
179
+ object; TypeScript rejects the prop, and an `as any` spread disappears silently.
180
+
181
+ **4. Not sticky, not rounded, square corners.** Wrap it to pin it, and give the
182
+ wrapper the radius + `overflow: clip`.
183
+
184
+ **5. Missing `className` leaks `"undefined"` into the class list.**
185
+
186
+ **6. No table semantics** — no `<thead>`/`<th>`/`role="columnheader"`, nothing tying
187
+ these labels to the row cells below.
188
+
189
+ **7. It looks identical to `ScBillingHistoryHeader` at a glance.** Same fill, same
190
+ padding, same gap. In review, check the labels, not the shape.
191
+
192
+ ---
193
+
194
+ ## In the wild
195
+
196
+ ```tsx
197
+ // cxo-dashboard src/app/components/billing-content.tsx:1670
198
+ <ScBillingLogsTableHeader />
199
+ ```
200
+
201
+ ⚠️ That call site is **orphaned** — nothing imports `BillingContent` from that
202
+ file. There is no live render site for this component in any host app.
203
+
204
+ ---
205
+
206
+ ## Related
207
+
208
+ - `ScBillingLogsTableList` — the row component this header exists for (same legacy
209
+ status, same reasons).
210
+ - `ScHeader` — the cell primitive; the live usage-logs table is built from it.
211
+ - `ScBillingHistoryHeader` / `ScBillingHistoryTableList` — the still-live
212
+ invoice-table pair.
@@ -0,0 +1,251 @@
1
+ ---
2
+ component: ScBillingLogsTableList
3
+ package: "@streamoid/ui"
4
+ category: billing
5
+ status: legacy
6
+ renders: div
7
+ tags: [credit-logs, usage-logs, table-row, credits-used, balance, billing, audit]
8
+ related: [ScBillingLogsTableHeader, ScBillingHistoryTableList, ScHeader, ScTableList]
9
+ do_not_confuse_with: [ScBillingHistoryTableList, ScTableList, ScBillingLogsTableHeader]
10
+ ---
11
+
12
+ # ScBillingLogsTableList
13
+
14
+ **One credit-consumption row in the usage-logs table.** Six cells: app, activity,
15
+ who triggered it, date, credits used (hardcoded **error red**, semibold) and the
16
+ running balance — width-matched to `ScBillingLogsTableHeader`, separated by a bottom
17
+ hairline.
18
+
19
+ > **Legacy.** Nothing renders this today. The live Billing → *Usage logs* tab in
20
+ > `@streamoid/settings` hand-rolls its rows because this component cannot express
21
+ > what the API returns: there is **no per-row running balance**, and credit
22
+ > movements need a **sign and two colours** (`-50` red for a deduction, `+50` green
23
+ > for a return/top-up). It is not `@deprecated` in source and still exports fine —
24
+ > but reaching for it means reproducing a shape the product has moved off.
25
+
26
+ ## TL;DR for agents
27
+
28
+ - **Reach for it when:** you have logs with a genuine per-row running balance and
29
+ every row is a deduction.
30
+ - **Don't reach for it when:** rows can add credits back, or you have no balance
31
+ column — hand-roll the row (§3 has the live pattern) or extend the DS.
32
+ - **Four things that will bite you:**
33
+ 1. `creditsUsed` is **always red** and unsigned. A returned/added credit reads as
34
+ a charge.
35
+ 2. `balance` is required by the layout but absent from the credits API — passing
36
+ the row `amount` again (as the orphaned CXO call site does) is misleading data.
37
+ 3. All six values have demo defaults (`"Artifax"`, `"Rohan"`, `"84,902"`…), so a
38
+ misspelled prop shows plausible fake data.
39
+ 4. Column widths are duplicated by hand in `ScBillingLogsTableHeader` — use both
40
+ or neither.
41
+
42
+ ---
43
+
44
+ ## 1. How to use it
45
+
46
+ ### Import
47
+
48
+ ```tsx
49
+ import { ScBillingLogsTableHeader, ScBillingLogsTableList } from "@streamoid/ui";
50
+ import "@streamoid/ui/dist/index.css"; // once, at your app root
51
+ ```
52
+
53
+ ### Minimal usage
54
+
55
+ ```tsx
56
+ <ScBillingLogsTableList
57
+ app="Photogenix"
58
+ activity="Image generation"
59
+ usedBy="Rohan"
60
+ date="Nov 9th, 2025"
61
+ creditsUsed="50"
62
+ balance="84,902"
63
+ />
64
+ ```
65
+
66
+ ### Props
67
+
68
+ | Prop | Type | Default | Notes |
69
+ |---|---|---|---|
70
+ | `app` | `string` | `"Artifax"` | ⚠️ Real default. `flex: 1`, 14px, ellipsised. |
71
+ | `activity` | `string` | `"Artifax Generation"` | ⚠️ Real default. `flex: 1`, 14px, ellipsised. |
72
+ | `usedBy` | `string` | `"Rohan"` | ⚠️ Real default. `7.5rem`. Pass `"System"` for machine-triggered rows. |
73
+ | `date` | `string` | `"Nov 9th, 2025"` | ⚠️ Real default. `7.5rem`. Pre-formatted by you. |
74
+ | `creditsUsed` | `string` | `"50"` | ⚠️ Real default. `7.5rem`, 16px semibold, **`--alias-text-and-icons-error` (red), always**. |
75
+ | `balance` | `string` | `"84,902"` | ⚠️ Real default. `7.5rem`, 16px semibold, primary text. |
76
+ | `className` | `string` | – | Appended to the root class. |
77
+ | `...props` | `HTMLAttributes<HTMLDivElement>` | – | Spread onto the root (`onClick`, `style`, `data-*` all work — unlike the header). |
78
+
79
+ Root: `padding: 1.25rem 1rem`, `gap: 1.5rem`, bottom border
80
+ `--alias-border-subtle`, no background of its own. Every cell is
81
+ `nowrap + overflow:hidden + ellipsis`.
82
+
83
+ ### Recipes
84
+
85
+ ```tsx
86
+ // The full legacy table, if you do have a running balance
87
+ <div className="w-full relative" style={{ backgroundColor: "var(--alias-surface-base)", borderRadius: "var(--radius-3xl)", overflow: "clip" }}>
88
+ <ScBillingLogsTableHeader />
89
+ {logs.map((log) => (
90
+ <ScBillingLogsTableList
91
+ key={log._id}
92
+ app={log.service?.serviceGroupName || "—"}
93
+ activity={log.meta?.info || "Credit usage"}
94
+ usedBy={log.triggeredByUserId ? userMap[log.triggeredByUserId] || "Unknown" : "System"}
95
+ date={formatDate(log.createdAt)}
96
+ creditsUsed={String(log.amount)}
97
+ balance={formatCredits(log.runningBalance)}
98
+ />
99
+ ))}
100
+ </div>
101
+
102
+ // Rows are clickable if you need them to be (props are spread, unlike the header)
103
+ <ScBillingLogsTableList app={app} activity={activity} onClick={() => openLog(log)} />
104
+ ```
105
+
106
+ ---
107
+
108
+ ## 2. Where to use it
109
+
110
+ - **Billing → Usage logs tab**, stacked under `ScBillingLogsTableHeader`. That is
111
+ the surface it was designed for.
112
+ - **No live render site.** The only call in any repo is
113
+ `cxo-dashboard/src/app/components/billing-content.tsx:1697`, inside a file whose
114
+ `BillingContent` export nothing imports. The live page is
115
+ `packages/settings/src/billing-content.tsx` (`UsageLogsTable`), which renders raw
116
+ divs instead.
117
+
118
+ ---
119
+
120
+ ## 3. When to use it
121
+
122
+ ### Use it when
123
+
124
+ - Every row is a **deduction** (red, unsigned reads correctly), **and**
125
+ - you have a real **running balance** per row, **and**
126
+ - you are pairing it with `ScBillingLogsTableHeader`.
127
+
128
+ If any of those is false, don't.
129
+
130
+ ### Don't use it — reach for this instead
131
+
132
+ | Situation | Use instead |
133
+ |---|---|
134
+ | Credit movements that can be positive (returns, top-ups) | Hand-roll the row — see the live pattern below — or add a `tone`/`sign` prop to the DS first |
135
+ | No per-row balance from the API | Hand-roll a 5-column row; `balance` has no "hide" option |
136
+ | Invoice rows (`Invoice`, `Amount`, `Date`, `Download`) | `ScBillingHistoryTableList` + `ScBillingHistoryHeader` |
137
+ | A generic dashboard list row | `ScTableList` |
138
+ | Narrow screens | Nothing exists; the mobile billing surface has no usage-logs list |
139
+
140
+ The live replacement, in shape:
141
+
142
+ ```tsx
143
+ // 5 cells; credits signed and two-tone, 5rem, right-aligned
144
+ const isPositive = log.type === "return" || log.type === "add";
145
+ <div style={{ display: "flex", gap: "var(--spacing-6xl, 1.5rem)", alignItems: "center",
146
+ padding: "var(--spacing-5xl, 1.25rem) var(--spacing-3xl, 1rem)",
147
+ borderBottom: "0.0625rem solid var(--alias-border-subtle, #242424)" }}>
148
+ <div style={{ ...cell, flex: 1 }}>{app}</div>
149
+ <div style={{ ...cell, flex: 1 }}>{log.type === "return" ? "Returned Credits" : log.meta?.info || "Credit usage"}</div>
150
+ <div style={{ ...cell, width: "7.5rem" }}>{userName}</div>
151
+ <div style={{ ...cell, width: "7.5rem" }}>{formatDate(log.createdAt)}</div>
152
+ <div style={{ width: "5rem", textAlign: "right", fontWeight: 600,
153
+ color: isPositive ? "var(--alias-text---icons-success)" : "var(--alias-text---icons-error)" }}>
154
+ {`${isPositive ? "+" : "-"}${log.amount}`}
155
+ </div>
156
+ </div>
157
+ ```
158
+
159
+ ### Don't confuse with
160
+
161
+ | You may actually want | Not this |
162
+ |---|---|
163
+ | `ScBillingHistoryTableList` — 4 columns, amount hardcoded **green**, has an `onRowClick` + download cell | This row is 6 columns with credits hardcoded **red** and no action cell |
164
+ | `ScBillingLogsTableHeader` — the matching header strip (`className` only) | The header ignores extra props; this row spreads them |
165
+ | `ScTableList` — the generic dashboard row | Not width-matched to the logs header |
166
+
167
+ ---
168
+
169
+ ## 4. Why to use it
170
+
171
+ - **Width parity with `ScBillingLogsTableHeader`** (`flex:1 / flex:1 / 7.5rem × 4`,
172
+ `1.5rem` gap, `1rem` side padding) — the one thing you'd otherwise have to keep in
173
+ sync by hand.
174
+ - **Every cell truncates**, so a long activity string or app name degrades to an
175
+ ellipsis instead of breaking the row.
176
+ - **Emphasis via tokens** (`--alias-text-and-icons-error` for credits, primary for
177
+ balance), which hold contrast in light mode.
178
+
179
+ That is the whole value. It is a layout-only row; all formatting, sign logic and
180
+ colour semantics are yours — and two of those it actively gets in the way of.
181
+
182
+ ---
183
+
184
+ ## Gotchas
185
+
186
+ **1. Credits are always red and never signed.** There is no `tone`, `variant`,
187
+ `sign` or `type` prop. A returned credit renders exactly like a charge.
188
+
189
+ ```tsx
190
+ // MISLEADING — a +50 refund painted red, unsigned
191
+ <ScBillingLogsTableList activity="Returned Credits" creditsUsed="50" />
192
+
193
+ // Only honest option today: hand-roll the row (see §3)
194
+ ```
195
+
196
+ **2. `balance` cannot be hidden.** Omit it and you get the demo default
197
+ `"84,902"`; pass `""` and the column is an empty 7.5rem gap. There is no 5-column
198
+ mode.
199
+
200
+ **3. Demo defaults hide typos.** Misspell `usedBy` and the row shows `"Rohan"`. If a
201
+ usage log looks suspiciously like sample data, check your prop names.
202
+
203
+ **4. Header/row alignment is by convention.** If you swap in a custom header you
204
+ must reproduce `gap: 1.5rem`, `padding: … 1rem` and the exact widths, or the columns
205
+ drift.
206
+
207
+ **5. The bottom border is unconditional** — the last row keeps its hairline; trim it
208
+ from the wrapper if your container already has an edge.
209
+
210
+ **6. No background.** The row is transparent; the wrapper owns the surface colour,
211
+ which matters if you make the header sticky (it needs an opaque background).
212
+
213
+ **7. Missing `className` leaks `"undefined"` into the class list.**
214
+
215
+ **8. Trailing spaces in the DOM.** All six values render as `{value}` plus a literal
216
+ space; trim before exact-match text assertions.
217
+
218
+ **9. No row semantics.** Divs only — no `role="row"`/`"cell"`, no focus handling. If
219
+ you attach `onClick`, add your own keyboard affordance.
220
+
221
+ ---
222
+
223
+ ## In the wild
224
+
225
+ ```tsx
226
+ // cxo-dashboard src/app/components/billing-content.tsx:1697
227
+ <ScBillingLogsTableList
228
+ key={log._id}
229
+ app={app}
230
+ activity={activity}
231
+ usedBy={userName}
232
+ date={formatDate(log.createdAt)}
233
+ creditsUsed={log.amount.toString()}
234
+ balance={formatCredits(runningBalance)} // note: runningBalance = log.amount here
235
+ />
236
+ ```
237
+
238
+ ⚠️ That call site is **orphaned** — nothing imports `BillingContent` from that file
239
+ — and it illustrates the balance problem: `runningBalance` is just `log.amount`
240
+ again, because the API has no per-row balance. There is no live render site for this
241
+ component in any host app.
242
+
243
+ ---
244
+
245
+ ## Related
246
+
247
+ - `ScBillingLogsTableHeader` — the matching header strip (same legacy status).
248
+ - `ScBillingHistoryTableList` / `ScBillingHistoryHeader` — the still-live invoice
249
+ pair.
250
+ - `ScHeader` — what the live usage-logs table uses for its header cells.
251
+ - `ScCreditsUsageCard` — the aggregate credits meter on the same billing page.