@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,241 @@
1
+ ---
2
+ component: ScWorkspaceSwitchMobile
3
+ package: "@streamoid/ui"
4
+ category: mobile
5
+ status: legacy
6
+ renders: div
7
+ tags: [mobile, workspace, switcher, switch, card, role, owner, legacy, v1]
8
+ related: [ScWorkspaceSwitchMobileV2, ScWorkspaceSettingsMobile, ScWorkspaceSwitchCard, ScDp]
9
+ do_not_confuse_with: [ScWorkspaceSwitchMobileV2, ScWorkspaceSettingsMobile, ScWorkspaceCard, ScWorkspaceSwitchCard, StreamoidWorkspaceSwitcher]
10
+ ---
11
+
12
+ # ScWorkspaceSwitchMobile
13
+
14
+ **The V1 mobile workspace-switch card — superseded by `ScWorkspaceSwitchMobileV2`.**
15
+ A fixed 326px rounded card: a 48px initials tile beside the workspace name with an
16
+ always-blue role badge on the right, a divider, then an owner row with an icon slot.
17
+ Still exported, but every CXO mobile surface uses V2 instead.
18
+
19
+ ## TL;DR for agents
20
+
21
+ - **Reach for it when:** you specifically need the V1 look — a two-block card with a
22
+ divider and an owner row that carries your own icon. In new code, don't.
23
+ - **Don't reach for it when:** you are building anything new on mobile
24
+ (→ `ScWorkspaceSwitchMobileV2`, which is fluid, composes `ScDp`, and has a
25
+ three-way `type`), or you need the workspace **settings** card with a team-count row
26
+ (→ `ScWorkspaceSettingsMobile`).
27
+ - **Four things that will bite you:**
28
+ 1. **It is `width: 326px`, fixed.** Not `100%`.
29
+ 2. **The role badge is always info-blue**, whatever `role` says — a "Member" looks
30
+ like an admin.
31
+ 3. **`ownerIcon` has no default.** Omit it and the 48px icon gutter still reserves
32
+ space, so the owner email sits oddly indented next to nothing.
33
+ 4. **There is no initials fallback and no image support at all** — no `imageUrl`
34
+ prop; the tile is text only.
35
+
36
+ ---
37
+
38
+ ## 1. How to use it
39
+
40
+ ### Import
41
+
42
+ ```tsx
43
+ import { ScWorkspaceSwitchMobile } from "@streamoid/ui";
44
+ import "@streamoid/ui/dist/index.css"; // once, at your app root
45
+ ```
46
+
47
+ ### Minimal usage
48
+
49
+ ```tsx
50
+ <ScWorkspaceSwitchMobile
51
+ storeName={ws.name}
52
+ initials={ws.initials}
53
+ role={ws.role === "admin" ? "Admin" : "Member"}
54
+ ownerId={ws.ownerEmail}
55
+ ownerIcon={<SiconUser size={20} />}
56
+ currentWs={ws._id === currentId}
57
+ />
58
+ ```
59
+
60
+ ### Props
61
+
62
+ | Prop | Type | Default | Notes |
63
+ |---|---|---|---|
64
+ | `storeName` | `string` | `"Stores"` | ⚠️ Demo default. The workspace name — note the prop is `storeName`, not `wsName` (V2 renamed it). Clips but does **not** ellipsise: `.storeName` omits `white-space: nowrap` — see Gotcha 9. |
65
+ | `initials` | `string` | `"WS"` | ⚠️ Demo default. Rendered into a hand-rolled 48px `--radius-xl` tile. No name-derived fallback. |
66
+ | `role` | `string` | `"Admin"` | ⚠️ Demo default. Free text in a **fixed 80px always-blue** badge. Colour never varies. |
67
+ | `ownerId` | `string` | `"rohan@streamoid.com"` | ⚠️ Demo default — a real-looking Streamoid address. Bottom row, tertiary grey, truncates. |
68
+ | `currentWs` | `boolean` | `true` | ⚠️ Defaults to **true**. Picks the `current` vs `other` skin. See the table below. |
69
+ | `ownerIcon` | `JSX.Element` | – | **Slot** for the icon before `ownerId`. No default; the 48px gutter renders regardless. |
70
+ | `className` | `string` | – | Appended after internal classes. Unguarded concat — see Gotcha 5. |
71
+ | `onClick` | `(e: React.MouseEvent) => void` | – | Attached to the root. No `role`/`tabIndex`/`cursor` come with it. |
72
+ | `...props` | `React.HTMLAttributes<HTMLDivElement>` | – | Spread onto the root `div`. |
73
+
74
+ ### What each `currentWs` value renders
75
+
76
+ | `currentWs` | Class | Background | Border |
77
+ |---|---|---|---|
78
+ | `true` | `variant-current` | `--alias-surface-canvas` | **none** |
79
+ | `false` | `variant-other` | `--alias-surface-subtle` | 1px `--alias-border-subtle` |
80
+
81
+ Note the asymmetry: the *current* card has no border at all, so on a canvas-coloured
82
+ page it reads as a recessed well rather than a card.
83
+
84
+ ### Recipes
85
+
86
+ ```tsx
87
+ // Make it fluid (the card is 326px by default)
88
+ <ScWorkspaceSwitchMobile storeName={ws.name} initials={ws.initials} className="w-full" />
89
+
90
+ // Always pass ownerIcon — the gutter is reserved whether or not you do
91
+ import { SiconUser } from "@streamoid/icons";
92
+ <ScWorkspaceSwitchMobile
93
+ storeName={ws.name}
94
+ initials={ws.initials}
95
+ ownerId={ws.ownerEmail}
96
+ ownerIcon={<SiconUser size={24} />} // the wrapper is 24×24
97
+ currentWs={false}
98
+ />
99
+
100
+ // Migrating to V2 (recommended)
101
+ // BEFORE
102
+ // <ScWorkspaceSwitchMobile storeName={n} initials={i} role={r} ownerId={o} currentWs={isCurrent} />
103
+ // AFTER
104
+ <ScWorkspaceSwitchMobileV2
105
+ wsName={n}
106
+ initials={i}
107
+ imageUrl={ws.imageUrl} // V2 supports images
108
+ role={r} // exact "Member" turns blue in V2
109
+ plan={ws.plan} // V2 adds a plan segment
110
+ ownerId={o}
111
+ type={isCurrent ? "currentWS" : "otherWS"}
112
+ />
113
+ ```
114
+
115
+ ---
116
+
117
+ ## 2. Where to use it
118
+
119
+ Its intended home was the mobile workspace-switcher sheet, one card per workspace. That
120
+ surface now renders `ScWorkspaceSwitchMobileV2`
121
+ (`cxo-dashboard/src/app/components/mobile-workspace-switcher.tsx:169` and `:246`), so
122
+ this component has no live placement.
123
+
124
+ It composes nothing from the DS — the initials tile and the role badge are hand-rolled
125
+ markup, and the owner icon is a slot you fill.
126
+
127
+ ---
128
+
129
+ ## 3. When to use it
130
+
131
+ ### Use it when
132
+
133
+ - You are maintaining an existing V1 call site and don't want a visual change.
134
+ - You genuinely need an owner row with a caller-supplied icon — V2 has no icon slot.
135
+
136
+ Otherwise: don't. This is `status: legacy`.
137
+
138
+ ### Don't use it — reach for this instead
139
+
140
+ | Situation | Use instead |
141
+ |---|---|
142
+ | Any new mobile workspace row | `ScWorkspaceSwitchMobileV2` — fluid, `ScDp` avatar, `type` triad, `plan` segment |
143
+ | Mobile workspace **settings** card (owner **and** team-count rows) | `ScWorkspaceSettingsMobile` |
144
+ | Desktop sidebar workspace switcher | `StreamoidWorkspaceSwitcher` or `ScWorkspaceSwitchCard` |
145
+ | A workspace summary card on desktop | `ScWorkspaceCard` |
146
+ | A workspace avatar on its own, image or initials | `ScDp` (`variant="workspace"`) |
147
+ | A **person's** identity row on mobile | `ScProfileV2Mobile` / `ScTableListMobile` |
148
+ | A role chip you can control | `ScRoleMobile` (two fixed skins) or `ScBadges` (any colour) |
149
+
150
+ ### Don't confuse with
151
+
152
+ | You may actually want | Not this |
153
+ |---|---|
154
+ | `ScWorkspaceSwitchMobileV2` — the current component. `wsName` not `storeName`, `type` triad not `currentWs` boolean, adds `imageUrl` + `plan`, fluid width, composes `ScDp` | Nothing in the name tells you V1 is superseded — check the suffix |
155
+ | `ScWorkspaceSettingsMobile` — **almost the same component**: identical props plus `teamCount` and `teamIcon`, and a slightly different skin pair (`surface-canvas` / `surface-base`, always bordered) | The only structural difference is that extra info row |
156
+ | `ScWorkspaceSwitchCard` — the desktop switcher card | Desktop metrics |
157
+ | `ScWorkspaceCard` — a workspace summary tile | Not a switcher row |
158
+ | `StreamoidWorkspaceSwitcher` / `NscWorkspaceSwitch` | Config-driven / other namesakes; check what you imported |
159
+
160
+ `ScWorkspaceSwitchMobile` and `ScWorkspaceSettingsMobile` are the closest pair of
161
+ near-duplicates in the whole library. Decide by the **screen**: switching → this one
162
+ (really, V2); settings → `ScWorkspaceSettingsMobile`.
163
+
164
+ ---
165
+
166
+ ## 4. Why to use it
167
+
168
+ Honestly: mostly you shouldn't. What it does give you:
169
+
170
+ - **A caller-supplied owner icon slot**, which V2 dropped — the only capability V1 has
171
+ that V2 does not.
172
+ - **Truncation is handled** on `ownerId` (`flex: 1 0 0; min-width: 0` +
173
+ `white-space: nowrap` + ellipsis). `storeName` gets the flex treatment but not
174
+ `nowrap`, so it wraps instead (Gotcha 9) — V2's `wsName` fixes this.
175
+ - **Two skins for current-vs-other** in one boolean.
176
+
177
+ What V2 gives you that this does not: fluid width, workspace images via `ScDp`, a `plan`
178
+ segment, a chrome-less `display` mode, and an actual live call site to copy.
179
+
180
+ ---
181
+
182
+ ## Gotchas
183
+
184
+ **1. Fixed `width: 326px`.** The root is not fluid; it will not fill a mobile sheet and
185
+ overflows a 360px phone with 20px side padding.
186
+
187
+ **2. The role badge is always info-blue.** `.roleBadge` hardcodes
188
+ `--alias-fill-info-soft` + `--alias-border-info` + info text, and is a fixed 80px wide.
189
+
190
+ ```tsx
191
+ // MISLEADING — "Member" renders in the same blue as "Admin"
192
+ <ScWorkspaceSwitchMobile role="Member" />
193
+ ```
194
+
195
+ **3. `currentWs` defaults to `true`.** In a list, forgetting it makes every card look
196
+ like the active workspace.
197
+
198
+ **4. `ownerIcon` has no default, but its gutter does.** `.ownerIconContainer` is
199
+ `width: 48px; flex-shrink: 0` unconditionally, so with no icon you get 48px of empty
200
+ space before the email. Always pass an icon (the inner wrapper is 24×24, so `size={20}`
201
+ or `24`).
202
+
203
+ **5. `className` is concatenated unguarded.** Omit it and the root carries a literal
204
+ `undefined` class.
205
+
206
+ **6. `.initialsText` has a wrong fallback.** It uses
207
+ `var(--font-size-font-size-md, 14px)`, but `md` is 16px everywhere else — so the
208
+ initials shift size depending on whether the tokens stylesheet is loaded.
209
+
210
+ **7. `onClick` brings no semantics.** Plain `div`, no `cursor: pointer` in the CSS. Add
211
+ `role="button"`, `tabIndex={0}`, `onKeyDown` and a pointer cursor yourself.
212
+
213
+ **8. No image support.** There is no `imageUrl` prop; workspaces with a logo cannot show
214
+ it. That alone is a reason to move to V2.
215
+
216
+ **9. `storeName` wraps, it does not ellipsise.** `.storeName` sets `overflow: hidden`
217
+ and `text-overflow: ellipsis` but omits `white-space: nowrap`, so a long workspace name
218
+ breaks to a second line and is then clipped. `.ownerText` does set `nowrap` and
219
+ truncates properly. (`ScWorkspaceSettingsMobile` has the identical bug; V2's `wsName`
220
+ does not.)
221
+
222
+ ---
223
+
224
+ ## In the wild
225
+
226
+ _No host render site found — used by the agent runtime / composed internally._
227
+
228
+ To be precise: it is exported from `@streamoid/ui` but no host app renders it, and it is
229
+ not agent-runtime — it has been superseded. The surface it was built for now uses V2:
230
+ `cxo-dashboard/src/app/components/mobile-workspace-switcher.tsx:169` renders
231
+ `ScWorkspaceSwitchMobileV2` with `type="currentWS"`, and `:246` the `otherWS` list.
232
+
233
+ ---
234
+
235
+ ## Related
236
+
237
+ - `ScWorkspaceSwitchMobileV2` — **the replacement**; use it for anything new.
238
+ - `ScWorkspaceSettingsMobile` — this card plus a team-count row, for the settings screen.
239
+ - `ScWorkspaceSwitchCard` / `StreamoidWorkspaceSwitcher` — the desktop switchers.
240
+ - `ScDp` — what V2 uses for the avatar; this card hand-rolls a 48px initials tile.
241
+ - `ScRoleMobile` / `ScBadges` — if you need a role chip whose colour actually varies.
@@ -0,0 +1,278 @@
1
+ ---
2
+ component: ScWorkspaceSwitchMobileV2
3
+ package: "@streamoid/ui"
4
+ category: mobile
5
+ status: stable
6
+ renders: div
7
+ tags: [mobile, workspace, switcher, switch, current, other, card, role, plan, cxo]
8
+ related: [ScWorkspaceSwitchMobile, ScWorkspaceSettingsMobile, ScWorkspaceSwitchCard, StreamoidWorkspaceSwitcher, ScDp]
9
+ do_not_confuse_with: [ScWorkspaceSwitchMobile, ScWorkspaceSettingsMobile, ScWorkspaceCard, ScWorkspaceSwitchCard, StreamoidWorkspaceSwitcher]
10
+ used_by: [cxo]
11
+ ---
12
+
13
+ # ScWorkspaceSwitchMobileV2
14
+
15
+ **The mobile workspace row that CXO actually ships.** A full-width rounded row: a 60px
16
+ `ScDp` workspace avatar on the left, then the workspace name over a single meta line
17
+ reading `role · plan · owner-email`. Three `type`s change the chrome — the current
18
+ workspace, a switchable other workspace, and a chrome-less "display" mode for embedding
19
+ in a popup header.
20
+
21
+ ## TL;DR for agents
22
+
23
+ - **Reach for it when:** you need a workspace identity row on mobile — in the workspace
24
+ switcher sheet, in mobile settings, or as the header of a workspace popup.
25
+ - **Don't reach for it when:** you're on desktop (→ `ScWorkspaceSwitchCard` /
26
+ `StreamoidWorkspaceSwitcher`), or you need the older mobile card with an owner row and
27
+ a separate role badge (→ `ScWorkspaceSwitchMobile`, which this component supersedes).
28
+ - **Four things that will bite you:**
29
+ 1. **`role` is colour-matched by exact string.** `"Member"` renders blue; **everything
30
+ else** — including `"member"` lowercase — renders amber. Pass the capitalised words.
31
+ 2. **`onClick` brings no semantics.** Plain `div`: no `role`, no `tabIndex`, no
32
+ `cursor: pointer`. CXO adds `className="w-full cursor-pointer"` at every call site.
33
+ 3. **The `role · plan · owner` dots always render**, even when `plan` or `ownerId` is
34
+ an empty string, leaving a trailing `·`.
35
+ 4. Every text prop has a demo default, including
36
+ `wsName = "Workspace name is kepler"`.
37
+
38
+ ---
39
+
40
+ ## 1. How to use it
41
+
42
+ ### Import
43
+
44
+ ```tsx
45
+ import { ScWorkspaceSwitchMobileV2 } from "@streamoid/ui";
46
+ import "@streamoid/ui/dist/index.css"; // once, at your app root
47
+ ```
48
+
49
+ ### Minimal usage
50
+
51
+ ```tsx
52
+ <ScWorkspaceSwitchMobileV2
53
+ wsName={ws.name}
54
+ initials={ws.initials}
55
+ imageUrl={ws.imageUrl}
56
+ role={ws.role === "admin" ? "Admin" : "Member"}
57
+ plan={ws.plan}
58
+ ownerId={ws.ownerEmail}
59
+ type="currentWS"
60
+ />
61
+ ```
62
+
63
+ ### Props
64
+
65
+ | Prop | Type | Default | Notes |
66
+ |---|---|---|---|
67
+ | `wsName` | `string` | `"Workspace name is kepler"` | ⚠️ Demo default. 16px/500 primary, truncates with ellipsis. |
68
+ | `initials` | `string` | `"WS"` | ⚠️ Demo default. Passed to `ScDp` as `initial`. Used only when `imageUrl` is unset. |
69
+ | `imageUrl` | `string` | – | When set, `ScDp` switches to `type="image"`. |
70
+ | `role` | `string` | `"Admin"` | ⚠️ Demo default. Free text, but **only the exact string `"Member"` turns it blue** — see Gotcha 1. |
71
+ | `plan` | `string` | `"Free"` | ⚠️ Demo default. Second meta segment, tertiary grey. |
72
+ | `ownerId` | `string` | `"rohan@streamoid.com"` | ⚠️ Demo default — a real-looking Streamoid address. Third meta segment; `flex: 1 0 0` so it truncates. |
73
+ | `type` | `"currentWS"` \| `"otherWS"` \| `"display"` | `"currentWS"` | The chrome. See the table below. |
74
+ | `onClick` | `(e: React.MouseEvent) => void` | – | Attached to the root. Bare — see Gotcha 2. |
75
+ | `className` | `string` | – | Appended after internal classes. Unguarded concat — see Gotcha 6. |
76
+ | `...props` | `React.HTMLAttributes<HTMLDivElement>` | – | Spread onto the root `div`. |
77
+
78
+ ### What each `type` renders
79
+
80
+ | `type` | Background | Border | Padding | Avatar background | Use for |
81
+ |---|---|---|---|---|---|
82
+ | `"currentWS"` | `--alias-surface-raised` | 0.5px `--alias-border-default` | `4px 12px 4px 4px` | forced `--alias-fill-neutral-neutralactive` when there is no `imageUrl` | the workspace you're in |
83
+ | `"otherWS"` | `--alias-surface-base` | 0.5px `--alias-border-subtle` | `4px 12px 4px 4px` | `ScDp` default | workspaces you can switch to |
84
+ | `"display"` | `--alias-surface-base` | **none** | **0** | `ScDp` default | embedding inside another surface (a popup header) — no card chrome at all |
85
+
86
+ ### Role colours
87
+
88
+ | `role` value | Colour |
89
+ |---|---|
90
+ | `"Member"` | `--alias-text-and-icons-info` (blue) |
91
+ | `"Admin"`, `"admin"`, `"member"`, `"Owner"`, anything else | `--alias-text-and-icons-warning` (amber) |
92
+
93
+ ### Recipes
94
+
95
+ ```tsx
96
+ // Current + other workspaces in a switcher sheet (the CXO shape)
97
+ <ScWorkspaceSwitchMobileV2
98
+ wsName={current.name}
99
+ initials={current.initials}
100
+ imageUrl={current.imageUrl}
101
+ role={current.role === "admin" ? "Admin" : "Member"} // exact capitalisation matters
102
+ plan={current.plan}
103
+ ownerId={current.ownerEmail}
104
+ type="currentWS"
105
+ />
106
+
107
+ {others.map((ws) => (
108
+ <ScWorkspaceSwitchMobileV2
109
+ key={ws._id}
110
+ wsName={ws.name}
111
+ initials={ws.initials}
112
+ imageUrl={ws.imageUrl}
113
+ role={ws.role === "admin" ? "Admin" : "Member"}
114
+ plan={ws.plan}
115
+ ownerId={ws.ownerEmail}
116
+ type="otherWS"
117
+ onClick={() => switchTo(ws)}
118
+ className="w-full cursor-pointer" // the component supplies no pointer/keyboard affordance
119
+ />
120
+ ))}
121
+
122
+ // As the identity header of a workspace-options popup — no card chrome
123
+ <ScWorkspaceSwitchMobileV2 {...wsProps} type="display" />
124
+
125
+ // Derive initials yourself; there is no name→initials fallback
126
+ initials={
127
+ ws.initials ||
128
+ ws.name.split(/\s+/).slice(0, 2).map((w) => w[0]?.toUpperCase() ?? "").join("") ||
129
+ "WS"
130
+ }
131
+ ```
132
+
133
+ ---
134
+
135
+ ## 2. Where to use it
136
+
137
+ All three of CXO's mobile workspace surfaces:
138
+
139
+ - **`mobile-workspace-switcher.tsx`** — "Current Workspace" then a list of "Other
140
+ Workspaces" (`type="currentWS"` / `"otherWS"`).
141
+ - **`mobile-settings-content.tsx`** — the same two groups inside the settings screen,
142
+ each row tappable to open the manage sheet.
143
+ - **`mobile-settings-workspace-options-popup.tsx`** — as the popup's header
144
+ (`type="display"`), between two hand-drawn dividers.
145
+
146
+ It composes `ScDp` (`variant="workspace"`, `size={60}`) internally. Don't nest your own
147
+ avatar.
148
+
149
+ ---
150
+
151
+ ## 3. When to use it
152
+
153
+ ### Use it when
154
+
155
+ - The surface is mobile and the row must be full width.
156
+ - You need the four workspace facts (name, role, plan, owner) in one line of meta.
157
+ - You want the same component to serve "current", "switchable" and "embedded header".
158
+
159
+ ### Don't use it — reach for this instead
160
+
161
+ | Situation | Use instead |
162
+ |---|---|
163
+ | Desktop sidebar workspace switcher | `StreamoidWorkspaceSwitcher` (config-driven) or `ScWorkspaceSwitchCard` |
164
+ | A workspace summary card on desktop | `ScWorkspaceCard` |
165
+ | Mobile workspace **settings** card with an owner row **and** a team-count row | `ScWorkspaceSettingsMobile` |
166
+ | The older mobile switch card (48px initials box, separate role badge, owner row with icon slot) | `ScWorkspaceSwitchMobile` — but it is superseded by this component; prefer this |
167
+ | A **person's** identity row | `ScProfileV2Mobile` / `ScTableListMobile` |
168
+ | Just the workspace avatar | `ScDp` (`variant="workspace"`) |
169
+
170
+ ### Don't confuse with
171
+
172
+ | You may actually want | Not this |
173
+ |---|---|
174
+ | `ScWorkspaceSwitchMobile` — the V1 mobile card: `storeName` not `wsName`, `currentWs` boolean not `type`, fixed 326px width, its own 80px always-blue role badge, a separate owner row with an `ownerIcon` slot | This V2 is fluid, has a `type` triad, one meta line, and uses `ScDp` |
175
+ | `ScWorkspaceSettingsMobile` — V1 shape **plus** a `teamCount` row and a `teamIcon` slot | Different screen (workspace settings, not switching) |
176
+ | `ScWorkspaceSwitchCard` — the **desktop** switcher card | Desktop metrics; note also `NscWorkspaceSwitch`, a `@deprecated` alias of `ScWorkspaceSwitchCard` exported from the same file |
177
+ | `ScWorkspaceCard` — a workspace summary tile | Not a switcher row |
178
+ | `StreamoidWorkspaceSwitcher` — the config-driven desktop switcher that owns its own list and open/close state | This component is one row and owns nothing |
179
+ | `NscWorkspaceSwitch` — also exported from `@streamoid/ui` | Yet another namesake; check what you imported |
180
+
181
+ There is no `ScWorkspaceSwitchMobileV1`. "V1" is `ScWorkspaceSwitchMobile`.
182
+
183
+ ---
184
+
185
+ ## 4. Why to use it
186
+
187
+ - **One component covers three placements.** The `display` type strips border and
188
+ padding entirely, so the same row can be a card in a list and a header inside a
189
+ popup — no duplicate markup, guaranteed identical typography.
190
+ - **It composes `ScDp`**, so the workspace avatar handles image-vs-initials, the
191
+ rounded-rect `workspace` shape, and sizing consistently with every other avatar in
192
+ the product. The V1 mobile cards hand-roll a 48px initials box instead.
193
+ - **Fluid by default** (`width: 100%`) — unlike the rest of the `*Mobile` family, which
194
+ is full of fixed pixel widths (`ScWorkspaceSwitchMobile` is 326px,
195
+ `ScReferralCardMobile` is 349px, `ScProfileV2Mobile` is 288px).
196
+ - **The meta line's truncation is solved**: `wsName` and `ownerId` both ellipsise inside
197
+ `min-width: 0` flex children, so long workspace names and long emails never break the
198
+ row.
199
+ - **Role/plan/owner in one line** keeps the row two lines tall, which is what makes a
200
+ 10-workspace list scannable on a phone.
201
+
202
+ ---
203
+
204
+ ## Gotchas
205
+
206
+ **1. Role colour is an exact string match on `"Member"`.**
207
+
208
+ ```tsx
209
+ // WRONG — lowercase "member" falls through to the amber (admin) colour
210
+ <ScWorkspaceSwitchMobileV2 role={ws.role} /> // ws.role === "member"
211
+
212
+ // RIGHT — map to the exact capitalised words
213
+ <ScWorkspaceSwitchMobileV2 role={ws.role === "admin" ? "Admin" : "Member"} />
214
+ ```
215
+
216
+ **2. `onClick` gives you no affordance and no keyboard access.** The root is a plain
217
+ `div`, and the CSS sets no `cursor`. Every CXO call site that passes `onClick` also
218
+ passes `className="w-full cursor-pointer"`. For real accessibility add
219
+ `role="button"`, `tabIndex={0}` and an `onKeyDown`.
220
+
221
+ **3. The meta separators are unconditional.** The two 16px dot divs always render.
222
+ `plan=""` gives you `Admin · · owner@x.com`; `ownerId=""` gives a trailing `·`. Pass
223
+ `"—"` rather than an empty string.
224
+
225
+ **4. Demo defaults on all five text props** (`wsName`, `initials`, `role`, `plan`,
226
+ `ownerId`), including a real-looking address
227
+ (`rohan@streamoid.com`) and `"Workspace name is kepler"`. Rendering the row bare in a
228
+ placeholder ships a fake workspace.
229
+
230
+ **5. `initials` has no name-derived fallback.** Unlike `ScProfileV2Mobile` and
231
+ `ScReferralCardMobile`, this component does not compute initials from the name — omit
232
+ `initials` and you get the literal `"WS"`. Compute them at the call site.
233
+
234
+ **6. `className` is concatenated unguarded.** Omit it and the root carries a literal
235
+ `undefined` class.
236
+
237
+ **7. The avatar is a fixed 60px.** `size={60}` is hardcoded in the call to `ScDp`
238
+ (which also defaults to 60), so the row height is fixed regardless of your text sizes.
239
+ `ScDp` accepts no `onClick` and no props spread, so the whole click target is the root.
240
+
241
+ **8. `type="currentWS"` overrides the avatar background.** When there is no `imageUrl`
242
+ the initials tile is forced to `--alias-fill-neutral-neutralactive` via an inline
243
+ `style`, so it looks different from an `otherWS` row with the same initials. That is
244
+ deliberate; you cannot turn it off.
245
+
246
+ ---
247
+
248
+ ## In the wild
249
+
250
+ ```tsx
251
+ // cxo-dashboard src/app/components/mobile-settings-content.tsx:313
252
+ <ScWorkspaceSwitchMobileV2
253
+ wsName={currentWs.name}
254
+ initials={currentWs.initials}
255
+ imageUrl={currentWs.imageUrl}
256
+ role={currentWs.role === "admin" ? "Admin" : "Member"}
257
+ plan={currentWs.plan}
258
+ ownerId={currentWs.ownerEmail}
259
+ type="currentWS"
260
+ onClick={() => handleWsCardClick(currentWs)}
261
+ className="w-full cursor-pointer"
262
+ />
263
+ ```
264
+
265
+ Also rendered at `src/app/components/mobile-workspace-switcher.tsx:169` (current) and
266
+ `:246` (others), and as a chrome-less header at
267
+ `src/app/components/mobile-settings-workspace-options-popup.tsx:95` (`type="display"`).
268
+
269
+ ---
270
+
271
+ ## Related
272
+
273
+ - `ScWorkspaceSwitchMobile` — the superseded V1 mobile card (fixed width, `currentWs`
274
+ boolean, separate role badge).
275
+ - `ScWorkspaceSettingsMobile` — V1 shape plus a team-count row, for the settings screen.
276
+ - `ScWorkspaceSwitchCard` / `StreamoidWorkspaceSwitcher` — the desktop switchers.
277
+ - `ScWorkspaceCard` — a workspace summary tile.
278
+ - `ScDp` — the avatar it composes; `variant="workspace"`, `size={60}`.