@streamoid/ui 0.6.17 → 0.6.19

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 (134) hide show
  1. package/README.md +35 -18
  2. package/dist/docs/AGENTS.md +325 -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 +210 -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/ScWorkspaceAccountMenu.md +115 -0
  120. package/dist/docs/ScWorkspaceCard.md +234 -0
  121. package/dist/docs/ScWorkspaceSettingsMobile.md +265 -0
  122. package/dist/docs/ScWorkspaceSwitchCard.md +312 -0
  123. package/dist/docs/ScWorkspaceSwitchMobile.md +241 -0
  124. package/dist/docs/ScWorkspaceSwitchMobileV2.md +278 -0
  125. package/dist/docs/StreamoidSidebar.md +413 -0
  126. package/dist/docs/StreamoidWorkspaceSwitcher.md +307 -0
  127. package/dist/docs/UsageHistoryMobile.md +235 -0
  128. package/dist/docs/components.json +4931 -0
  129. package/dist/index.css +361 -36
  130. package/dist/index.d.mts +213 -88
  131. package/dist/index.d.ts +213 -88
  132. package/dist/index.js +2486 -1629
  133. package/dist/index.mjs +2487 -1620
  134. package/package.json +5 -3
@@ -0,0 +1,226 @@
1
+ ---
2
+ component: ScReferralCardMobile
3
+ package: "@streamoid/ui"
4
+ category: mobile
5
+ status: stable
6
+ renders: div
7
+ tags: [mobile, referral, invite, credits, card, badge, avatar, billing]
8
+ related: [ScReferralTableHeader, ScReferralTableList, ScProfileV2Mobile, ScTableListMobile, ScBadges]
9
+ do_not_confuse_with: [ScReferralTableList, ScTableListMobile, ScProfileV2Mobile, ScBadges]
10
+ ---
11
+
12
+ # ScReferralCardMobile
13
+
14
+ **One referral, as a mobile card.** A bordered rounded card: 40px avatar + name/email
15
+ with a grey status pill on the right, a divider, then the referral date on the left and
16
+ the credits earned in green on the right.
17
+
18
+ ## TL;DR for agents
19
+
20
+ - **Reach for it when:** you are building the mobile view of a referral programme
21
+ screen — one card per person referred.
22
+ - **Don't reach for it when:** you're on desktop (→ `ScReferralTableHeader` +
23
+ `ScReferralTableList`) or the row is a workspace member (→ `ScTableListMobile`).
24
+ - **Four things that will bite you:**
25
+ 1. **It is `width: 349px`, fixed.** Not `100%`. It overflows a 360px phone with any
26
+ side padding.
27
+ 2. **The status pill is always neutral grey.** "Confirmed" and "Pending" look
28
+ identical — there is no variant, and it is not `ScBadges`.
29
+ 3. **`credits` is always success-green**, so a clawback still reads as a gain.
30
+ 4. Every text prop has a demo default, including a fake person
31
+ (`"Chris Hemsworth"` / `"chris@kepler.com"`) and `credits = "+ 500"`.
32
+
33
+ ---
34
+
35
+ ## 1. How to use it
36
+
37
+ ### Import
38
+
39
+ ```tsx
40
+ import { ScReferralCardMobile } from "@streamoid/ui";
41
+ import "@streamoid/ui/dist/index.css"; // once, at your app root
42
+ ```
43
+
44
+ ### Minimal usage
45
+
46
+ ```tsx
47
+ <ScReferralCardMobile
48
+ name={r.name}
49
+ email={r.email}
50
+ imageUrl={r.avatarUrl}
51
+ badge={r.status}
52
+ date={formatDate(r.createdAt)}
53
+ credits={`+ ${r.points}`}
54
+ />
55
+ ```
56
+
57
+ ### Props
58
+
59
+ | Prop | Type | Default | Notes |
60
+ |---|---|---|---|
61
+ | `name` | `string` | `"Chris Hemsworth"` | ⚠️ Demo default. Also the source of the initials **and** the `<img alt>`. |
62
+ | `email` | `string` | `"chris@kepler.com"` | ⚠️ Demo default. 12px tertiary sub-line. |
63
+ | `imageUrl` | `string` | – | When set, `<img src>` with `object-fit: cover`; otherwise initials. No error fallback. |
64
+ | `badge` | `string` | `"Confirmed"` | ⚠️ Demo default. Free text in a **fixed neutral-grey** pill. Never recolours. |
65
+ | `date` | `string` | `"Nov 9th, 2025"` | ⚠️ Demo default. Pre-formatted string; 14px secondary. |
66
+ | `credits` | `string` | `"+ 500"` | ⚠️ Demo default. 16px/600, hardcoded success green. You supply the `+`/`-`. |
67
+ | `onClick` | `(e: React.MouseEvent) => void` | – | Attached to the card root. **No `role`, `tabIndex` or `cursor: pointer` come with it** — see Gotcha 5. |
68
+ | `className` | `string` | – | Appended after internal classes. Unguarded concat — see Gotcha 4. |
69
+ | `...props` | `React.HTMLAttributes<HTMLDivElement>` | – | Spread onto the root `div`. |
70
+
71
+ ### Layout
72
+
73
+ | Region | Content |
74
+ |---|---|
75
+ | Row 1 | 40px avatar (image or initials) · `name` / `email` column (`flex: 1`, both truncate) · `badge` pill (`flex-shrink: 0`) |
76
+ | Divider | 0.5px `--alias-border-subtle`, full width |
77
+ | Row 2 | `date` (left) · `credits` (right, green) — **both `flex: 1 0 0`**, so they split the row 50/50 |
78
+
79
+ ### Recipes
80
+
81
+ ```tsx
82
+ // Full-width in a mobile list (the card is 349px by default)
83
+ <ScReferralCardMobile
84
+ name={r.name}
85
+ email={r.email}
86
+ badge={r.confirmed ? "Confirmed" : "Pending"}
87
+ date={formatDate(r.createdAt)}
88
+ credits={`+ ${r.points.toLocaleString("en-US")}`}
89
+ className="w-full"
90
+ />
91
+
92
+ // The pill can't show state through colour — put the state in the words, or
93
+ // render your own ScBadges beside the card
94
+ import { ScBadges } from "@streamoid/ui";
95
+ <ScBadges text="Pending" variant="warning" styleVariant="opaque" />
96
+
97
+ // Tappable card — add the semantics yourself
98
+ <ScReferralCardMobile
99
+ name={r.name}
100
+ email={r.email}
101
+ onClick={() => openReferral(r)}
102
+ role="button"
103
+ tabIndex={0}
104
+ className="w-full cursor-pointer"
105
+ />
106
+ ```
107
+
108
+ ---
109
+
110
+ ## 2. Where to use it
111
+
112
+ The mobile referral-programme screen: a vertical stack of cards, one per person
113
+ referred, where the desktop shows a table (`ScReferralTableHeader` +
114
+ `ScReferralTableList`). Because the card has its own border and radius, stack them with
115
+ a real gap — unlike `InvoiceHistoryMobile`/`UsageHistoryMobile`, which are
116
+ self-dividing rows.
117
+
118
+ It composes nothing from the DS — the avatar and the badge are hand-rolled, not `ScDp`
119
+ and not `ScBadges`.
120
+
121
+ ---
122
+
123
+ ## 3. When to use it
124
+
125
+ ### Use it when
126
+
127
+ - The viewport is mobile and each referral is a card, not a table row.
128
+ - The status vocabulary is small and doesn't need colour to be legible.
129
+ - Credits earned are always positive.
130
+
131
+ ### Don't use it — reach for this instead
132
+
133
+ | Situation | Use instead |
134
+ |---|---|
135
+ | Desktop referral table | `ScReferralTableHeader` + `ScReferralTableList` (`userName`, `userEmail`, `date`, `status`, `points`) |
136
+ | A workspace member row on mobile (role + access icons + click) | `ScTableListMobile` |
137
+ | Just identity (avatar + name + email), no badge or credits | `ScProfileV2Mobile` |
138
+ | A status chip that must change colour | `ScBadges` |
139
+ | Invoice rows on mobile | `InvoiceHistoryMobile` |
140
+ | Credit-usage rows on mobile | `UsageHistoryMobile` |
141
+
142
+ ### Don't confuse with
143
+
144
+ | You may actually want | Not this |
145
+ |---|---|
146
+ | `ScReferralTableList` — the desktop row; props are `userName`/`userEmail`/`status`/`points` | This card uses `name`/`email`/`badge`/`credits` for the same data |
147
+ | `ScTableListMobile` — the mobile *member* row, with `onRowClick` and icon groups | Referrals, not team members |
148
+ | `ScProfileV2Mobile` — the same 40px avatar + name/email block, no card chrome | This is that block plus a badge, a divider and a credits row |
149
+ | `ScBadges` — the real status chip | The `badge` here is a plain grey `<div>`; it will not colour by state |
150
+
151
+ ---
152
+
153
+ ## 4. Why to use it
154
+
155
+ - **The whole referral row in one prop set** — identity, status, date and reward —
156
+ instead of composing four components and getting the truncation wrong.
157
+ - **Truncation is handled** in both text columns (`flex: 1 0 0; min-width: 0` with
158
+ ellipsis), so long emails don't push the badge off the card.
159
+ - **Consistent mobile metrics** — 40px avatar, 14/12px type pair, `--radius-3xl` card,
160
+ 12px padding — matching `ScProfileV2Mobile` and `ScTableListMobile`.
161
+ - **Credits colour matches the billing family** (green = credits in), the same
162
+ convention `InvoiceHistoryMobile` uses.
163
+
164
+ ---
165
+
166
+ ## Gotchas
167
+
168
+ **1. Fixed `width: 349px`.** The root is not fluid.
169
+
170
+ ```tsx
171
+ // WRONG — 349px inside a 360px phone with 16px side padding = horizontal scroll
172
+ <ScReferralCardMobile name={n} email={e} />
173
+
174
+ // RIGHT
175
+ <ScReferralCardMobile name={n} email={e} className="w-full" />
176
+ ```
177
+
178
+ **2. The badge never changes colour.** `.badge` is hardcoded
179
+ `--alias-fill-neutral-neutralactive` with primary text.
180
+
181
+ ```tsx
182
+ // MISLEADING — "Pending" and "Confirmed" are visually identical
183
+ <ScReferralCardMobile badge="Pending" />
184
+ ```
185
+
186
+ **3. `credits` is unconditionally green.** No sign handling, no variant. A negative
187
+ value still renders in `--alias-text-and-icons-success`.
188
+
189
+ **4. `className` is concatenated unguarded.** Omit it and the root carries a literal
190
+ `undefined` class.
191
+
192
+ **5. `onClick` brings no semantics.** The root is a plain `div` with no `role`, no
193
+ `tabIndex` and no `cursor: pointer` in the CSS. Add all three yourself.
194
+
195
+ **6. `date` and `credits` split the bottom row 50/50.** Both are `flex: 1 0 0`, so the
196
+ credits figure sits at the midpoint-right, not hugged to the edge. Don't expect a
197
+ right-hugged number.
198
+
199
+ **7. A broken `imageUrl` shows a broken image, not initials.** The initials branch is
200
+ chosen purely on `imageUrl` being truthy; there is no `onError`.
201
+
202
+ **8. Initials come only from `name`.** `name.split(" ").map(n => n[0]).join("").toUpperCase().slice(0, 2)`
203
+ — no `initials` prop. An empty `name` gives an empty circle.
204
+
205
+ ---
206
+
207
+ ## In the wild
208
+
209
+ _No host render site found — used by the agent runtime / composed internally._
210
+
211
+ To be precise: it is exported from `@streamoid/ui` but no host app renders it, and it is
212
+ not agent-runtime — it is currently unused. The **desktop** referral screen *is* built:
213
+ `packages/settings/src/settings-content.tsx:1011` renders `ScReferralTableHeader` +
214
+ `ScReferralTableList`. This card is the missing mobile half of that screen, and belongs
215
+ in CXO's mobile settings surface (`cxo-dashboard/src/app/components/mobile-*.tsx`), which
216
+ has no referral tab yet.
217
+
218
+ ---
219
+
220
+ ## Related
221
+
222
+ - `ScReferralTableHeader` / `ScReferralTableList` — the desktop table for the same data.
223
+ - `ScProfileV2Mobile` — the avatar + name/email block on its own.
224
+ - `ScTableListMobile` — the mobile member row, with `onRowClick` and icon groups.
225
+ - `ScBadges` — use this when the status must be colour-coded.
226
+ - `InvoiceHistoryMobile` / `UsageHistoryMobile` — the other mobile billing list rows.
@@ -0,0 +1,260 @@
1
+ ---
2
+ component: ScReferralTableHeader
3
+ package: "@streamoid/ui"
4
+ category: tables
5
+ status: stable
6
+ renders: div
7
+ tags: [table, header, column-headers, referral, referrals, rewards, invite, settings, referral-history]
8
+ related: [ScReferralTableList, ScHeader, ScReferralCardMobile, ScTableHeader, ScBillingHistoryHeader, ScBillingLogsTableHeader, ScCatalogixStoreHeader]
9
+ do_not_confuse_with: [ScTableHeader, ScHeader, ScReferralCardMobile, ScBillingHistoryHeader, ScBillingLogsTableHeader, ScCatalogixStoreHeader]
10
+ ---
11
+
12
+ # ScReferralTableHeader
13
+
14
+ **The column-header strip of the Referral History table.** A shaded flex row of exactly
15
+ four uppercase muted labels — USER, DATE, STATUS, REWARD — rendered as four internal
16
+ `ScHeader` cells on the widths `ScReferralTableList` uses. It is the *ruler*; the rows
17
+ are the data.
18
+
19
+ ## TL;DR for agents
20
+
21
+ - **Reach for it when:** you are building the Settings → Referral "Referral History"
22
+ table and need the header above `ScReferralTableList` rows.
23
+ - **Don't reach for it when:** you need the members table header (→ `ScTableHeader`),
24
+ a single sortable column label (→ `ScHeader`), or the mobile referral surface
25
+ (→ `ScReferralCardMobile`, which has no header strip).
26
+ - **Four things that will bite you:**
27
+ 1. `className` is the **only** prop. No `type` variant, no label props, no
28
+ `HTMLAttributes` — the four English labels are baked in.
29
+ 2. **`...props` is destructured but never spread.** `style`, `onClick`, `data-*`,
30
+ `aria-*` are dropped (and are type errors).
31
+ 3. Unlike `ScTableHeader`, its CSS has **no `flex-shrink: 0` and no
32
+ `align-self: stretch`** — inside a constrained flex column it can be squashed or
33
+ fail to fill the width.
34
+ 4. The USER column shows a **descending chevron that is pure decoration**. Nothing
35
+ is sortable.
36
+
37
+ ---
38
+
39
+ ## 1. How to use it
40
+
41
+ ### Import
42
+
43
+ ```tsx
44
+ import { ScReferralTableHeader, ScReferralTableList } from "@streamoid/ui";
45
+ import "@streamoid/ui/dist/index.css"; // once, at your app root
46
+ ```
47
+
48
+ ### Minimal usage
49
+
50
+ There is nothing to configure:
51
+
52
+ ```tsx
53
+ <ScReferralTableHeader />
54
+ ```
55
+
56
+ ### Props
57
+
58
+ | Prop | Type | Default | Notes |
59
+ |---|---|---|---|
60
+ | `className` | `string` | – | Appended after the internal class. The only escape hatch — there is no `style` prop. |
61
+
62
+ ⚠️ `...props` exists in the signature but is **never applied to the DOM**, and
63
+ `IScReferralTableHeaderProps` does not extend `React.HTMLAttributes`, so anything else
64
+ you pass is both a compile error and a no-op.
65
+
66
+ ### The column contract (shared with `ScReferralTableList`)
67
+
68
+ | Column | Header label | Row prop | Width | Notes |
69
+ |---|---|---|---|---|
70
+ | USER | `"User"` (`state="down"`) | `userName` + `userEmail` → `ScProfile` | `flex: 1` | The only flexible column |
71
+ | DATE | `"Date"` | `date` | `7.5rem` | Row cell truncates, no tooltip |
72
+ | STATUS | `"Status"` | `status` → `ScBadges` | `5rem` | Badge width is forced to `5rem` by the row; long words wrap, they don't truncate |
73
+ | REWARD | `"Reward"` | `points` | `7.5rem` | Row cell is always green |
74
+
75
+ Both components use `gap: 1.5rem` and `padding-inline: 1rem`. That, plus the widths
76
+ above, is what makes header and rows line up. Change neither via `className` unless you
77
+ change both.
78
+
79
+ ### Recipes
80
+
81
+ ```tsx
82
+ // The whole Referral History table
83
+ <div style={{ display: "flex", flexDirection: "column" }}>
84
+ <ScReferralTableHeader />
85
+ {referrals.map((r) => (
86
+ <ScReferralTableList
87
+ key={r.id}
88
+ userName={r.name}
89
+ userEmail={r.email}
90
+ date={r.date}
91
+ status={r.status}
92
+ points={r.points}
93
+ />
94
+ ))}
95
+ </div>
96
+
97
+ // Sticky + non-shrinking. You cannot pass `style`, so use className.
98
+ <ScReferralTableHeader className={styles.stickyHead} />
99
+ /* .stickyHead {
100
+ position: sticky; top: 0; z-index: 1;
101
+ flex-shrink: 0; align-self: stretch; // the DS CSS omits both — see Gotcha 3
102
+ background: var(--alias-fill-neutral-neutral);
103
+ } */
104
+
105
+ // Or wrap it, which is the pattern the rest of the settings screens use
106
+ <div style={{ position: "sticky", top: 0, zIndex: 1, flexShrink: 0 }}>
107
+ <ScReferralTableHeader />
108
+ </div>
109
+ ```
110
+
111
+ ---
112
+
113
+ ## 2. Where to use it
114
+
115
+ - **Settings → Referral → "Referral History"**, desktop, directly above a list of
116
+ `ScReferralTableList` rows. That screen lives in the shared `@streamoid/settings`
117
+ package (which ships into CXO desktop settings) — and the history block there is
118
+ currently **commented out**, so nothing renders it today. See "In the wild".
119
+ - The live part of that screen is the referral-link / invite-by-email pair of
120
+ `ScTextField`s above where this table would sit.
121
+ - Mobile uses `ScReferralCardMobile` instead — stacked cards, **no header strip**.
122
+ - It composes four `ScHeader` cells and a background. Nothing else.
123
+
124
+ ---
125
+
126
+ ## 3. When to use it
127
+
128
+ ### Use it when
129
+
130
+ - You are rendering **referral history** in a desktop table and want the header pinned
131
+ to the same widths the DS row uses.
132
+ - You want the "shaded header strip over transparent rows" treatment shared by every
133
+ table in the products.
134
+
135
+ ### Don't use it — reach for this instead
136
+
137
+ | Situation | Use instead |
138
+ |---|---|
139
+ | Members / invites table header (User / Role / Access / Invited by / …) | `ScTableHeader` — it also has a `type="pending"` variant |
140
+ | Billing history header (Invoice / Amount / Date / Action) | `ScBillingHistoryHeader` |
141
+ | Credit & usage logs header (App / Activity / Used by / Date / Credits used / Balance) | `ScBillingLogsTableHeader` |
142
+ | Catalogix stores list header | `ScCatalogixStoreHeader` — the only header in the family whose labels are props |
143
+ | One sortable column label with an asc/desc chevron | `ScHeader` — this strip is four of them, pre-labelled |
144
+ | Renaming a column ("Reward" → "Credits") | Nothing here; the strings are hardcoded. Compose `ScHeader` cells yourself or change the DS |
145
+ | The mobile referral list | `ScReferralCardMobile` |
146
+
147
+ ### Don't confuse with
148
+
149
+ | You may actually want | Not this |
150
+ |---|---|
151
+ | `ScTableHeader` — the **members** strip: five columns, a `type="default" \| "pending"` prop | `ScReferralTableHeader` has four fixed columns and no variants |
152
+ | `ScHeader` — a **single** column-label cell with `state="up" \| "down" \| "none"` | This is the whole strip |
153
+ | `ScCatalogixStoreHeader` — same shape, but every label is a prop plus `showAssets`/`showCreatedBy` | This one takes no labels at all |
154
+ | `ScReferralCardMobile` — the mobile referral entry | Not a header; and mobile has no header row |
155
+ | `ScReferralTableList` — the *row* sibling | Different component; pair them |
156
+
157
+ ---
158
+
159
+ ## 4. Why to use it
160
+
161
+ - **It is the alignment contract.** `flex:1 / 7.5rem / 5rem / 7.5rem`, `gap: 1.5rem`,
162
+ `padding: 0.75rem 1rem` exist in exactly two files — this one and
163
+ `ScReferralTableList`. Hand-rolling the header is how the table shears apart when
164
+ someone adds a column.
165
+ - **Two-tone that survives light mode.** The strip paints
166
+ `--alias-fill-neutral-neutral` while rows stay transparent, so it still reads as a
167
+ header when the theme flips instead of relying on a grey that collapses to white.
168
+ - **Label typography is already the DS's** `font-size-xs` +
169
+ `--alias-text-and-icons-muted` + uppercase, matching every other table header in the
170
+ products.
171
+ - Zero API to get wrong: there is exactly one optional prop.
172
+
173
+ ---
174
+
175
+ ## Gotchas
176
+
177
+ **1. No label props, no variants.** "User", "Date", "Status" and "Reward" are literal
178
+ strings inside the component. There is no `type` prop, so there is no pending/settled
179
+ variant of this table. Don't use it on a localised surface without changing the DS.
180
+
181
+ **2. `...props` is destructured and thrown away.** The root div receives only
182
+ `className`.
183
+
184
+ ```tsx
185
+ // WRONG — type error, and even with a cast the style is dropped
186
+ <ScReferralTableHeader style={{ position: "sticky", top: 0 }} />
187
+
188
+ // RIGHT — className, or your own wrapper
189
+ <div style={{ position: "sticky", top: 0, zIndex: 1 }}>
190
+ <ScReferralTableHeader />
191
+ </div>
192
+ ```
193
+
194
+ **3. It omits `flex-shrink: 0` and `align-self: stretch`.** `ScTableHeader` and
195
+ `ScTableList` both set them; this pair does not. Inside a constrained
196
+ `flex-direction: column` container (a fixed-height, `overflow-y: auto` panel — exactly
197
+ what a settings screen is) the strip can be compressed toward zero height, and if the
198
+ parent overrides `align-items` it won't span the full width either. Add both via
199
+ `className` when you drop it into a scrolling column.
200
+
201
+ **4. The USER chevron is decoration.** The first cell is `<ScHeader state="down">`, so
202
+ it renders a double-down arrow that *looks* like "sorted descending". No `onClick`
203
+ reaches any cell and there is no sort prop anywhere.
204
+
205
+ **5. It is not a table.** No `role="table"`/`row`/`columnheader`, no `<th>`, no
206
+ `scope`, no `aria-sort`. Row cells are not associated with these labels for assistive
207
+ tech.
208
+
209
+ **6. Not sticky, and it doesn't own the scroll.** Long histories scroll the header
210
+ away. Add `position: sticky; top: 0`, an opaque `background` and a `z-index` (the rows
211
+ are `position: relative`, so without one they paint over it).
212
+
213
+ **7. `className` lands as the literal string `"undefined"` when omitted** — the class
214
+ list is built by concatenation. Harmless in the browser; breaks exact-string class
215
+ assertions in tests.
216
+
217
+ **8. Labels are force-uppercased** by `ScHeader`'s `text-transform: uppercase`. Nothing
218
+ you can do about it here, but don't be surprised by the shouty rendering in snapshots.
219
+
220
+ ---
221
+
222
+ ## In the wild
223
+
224
+ _No host render site found — used by the agent runtime / composed internally._
225
+
226
+ More precisely: **the only integration that exists is commented out.** In the shared
227
+ settings package the Referral History block — header plus row loop — sits inside a
228
+ `{/* Referral History section commented out … */}` comment:
229
+
230
+ ```tsx
231
+ // npm-components packages/settings/src/settings-content.tsx:1011 (inside a commented-out block)
232
+ <ScReferralTableHeader />
233
+ {REFERRALS.map((ref) => (
234
+ <ScReferralTableList
235
+ key={ref.id}
236
+ userEmail={ref.email}
237
+ date={ref.date}
238
+ status={ref.status}
239
+ points={ref.points}
240
+ />
241
+ ))}
242
+ ```
243
+
244
+ Where it belongs: **Settings → Referral**, desktop, under the "Referral History" label
245
+ and above the row loop — uncomment that block (and note that the `REFERRALS` array
246
+ there is local demo data, and `userName` is not passed, which triggers
247
+ `ScReferralTableList` Gotcha 1). CXO reaches this screen through
248
+ `@streamoid/settings`, so no CXO-side change is needed.
249
+
250
+ ---
251
+
252
+ ## Related
253
+
254
+ - `ScReferralTableList` — the row sibling; the two share one width contract and must be
255
+ rendered together.
256
+ - `ScHeader` — the single column-label cell this strip is built from; use it to compose
257
+ a header for a table the DS doesn't cover.
258
+ - `ScReferralCardMobile` — the mobile form of the same data.
259
+ - `ScTableHeader` / `ScCatalogixStoreHeader` / `ScBillingHistoryHeader` /
260
+ `ScBillingLogsTableHeader` — the other domain-specific header/row pairs, same pattern.