@streamoid/ui 0.6.16 → 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.
- package/README.md +35 -18
- package/dist/docs/AGENTS.md +321 -0
- package/dist/docs/CreditWarningBanner.md +305 -0
- package/dist/docs/InvoiceHistoryMobile.md +222 -0
- package/dist/docs/ScAccess.md +259 -0
- package/dist/docs/ScAppCard.md +244 -0
- package/dist/docs/ScAppCardForCopilot.md +230 -0
- package/dist/docs/ScAppCardV3.md +273 -0
- package/dist/docs/ScAppField.md +308 -0
- package/dist/docs/ScAppListingCard.md +271 -0
- package/dist/docs/ScAppSwitchPanel.md +286 -0
- package/dist/docs/ScAppcardLogos.md +226 -0
- package/dist/docs/ScArtifaxInvite.md +262 -0
- package/dist/docs/ScArtifaxSidebar.md +330 -0
- package/dist/docs/ScAskAgentButton.md +307 -0
- package/dist/docs/ScBadges.md +261 -0
- package/dist/docs/ScBeacon.md +244 -0
- package/dist/docs/ScBillingHistoryHeader.md +210 -0
- package/dist/docs/ScBillingHistoryTableList.md +243 -0
- package/dist/docs/ScBillingLogsTableHeader.md +212 -0
- package/dist/docs/ScBillingLogsTableList.md +251 -0
- package/dist/docs/ScBriefCard.md +255 -0
- package/dist/docs/ScButton.md +251 -0
- package/dist/docs/ScCalendar.md +268 -0
- package/dist/docs/ScCalendarDateComps.md +264 -0
- package/dist/docs/ScCatalogixInvite.md +345 -0
- package/dist/docs/ScCatalogixSidebar.md +337 -0
- package/dist/docs/ScCatalogixStoreHeader.md +246 -0
- package/dist/docs/ScCatalogixStoreTableList.md +316 -0
- package/dist/docs/ScCheckField.md +233 -0
- package/dist/docs/ScCheckbox.md +272 -0
- package/dist/docs/ScCounter.md +235 -0
- package/dist/docs/ScCreditsUsageCard.md +247 -0
- package/dist/docs/ScCreditsUsageCardMobile.md +224 -0
- package/dist/docs/ScDefaultCard.md +269 -0
- package/dist/docs/ScDp.md +245 -0
- package/dist/docs/ScDrawer.md +318 -0
- package/dist/docs/ScFieldButton.md +255 -0
- package/dist/docs/ScFileField.md +268 -0
- package/dist/docs/ScGoogleSignIn.md +250 -0
- package/dist/docs/ScGuide.md +278 -0
- package/dist/docs/ScHDivider.md +213 -0
- package/dist/docs/ScHeader.md +222 -0
- package/dist/docs/ScImageField.md +253 -0
- package/dist/docs/ScInChatList.md +277 -0
- package/dist/docs/ScInChatMessage.md +205 -0
- package/dist/docs/ScInfoPopup.md +248 -0
- package/dist/docs/ScIntialProfileCover.md +233 -0
- package/dist/docs/ScInvoiceHistoryMobile.md +187 -0
- package/dist/docs/ScLogoUnit.md +232 -0
- package/dist/docs/ScMappingCard.md +241 -0
- package/dist/docs/ScMediaApproval.md +301 -0
- package/dist/docs/ScMediaSelect.md +310 -0
- package/dist/docs/ScMenuOptions.md +308 -0
- package/dist/docs/ScMobileBottomAction.md +252 -0
- package/dist/docs/ScMobileTopNav.md +279 -0
- package/dist/docs/ScModal.md +291 -0
- package/dist/docs/ScOnlyField.md +302 -0
- package/dist/docs/ScOnlyIcon.md +213 -0
- package/dist/docs/ScPagination.md +284 -0
- package/dist/docs/ScPairtext.md +287 -0
- package/dist/docs/ScPendingAction.md +238 -0
- package/dist/docs/ScPhtogenixInvite.md +275 -0
- package/dist/docs/ScPlanCard.md +302 -0
- package/dist/docs/ScPlanComparison.md +264 -0
- package/dist/docs/ScPlanDetailsCard.md +246 -0
- package/dist/docs/ScPlanDetailsCardMobile.md +240 -0
- package/dist/docs/ScPopUpMenu.md +224 -0
- package/dist/docs/ScProfile.md +234 -0
- package/dist/docs/ScProfileImageUpdate.md +261 -0
- package/dist/docs/ScProfileOptions.md +245 -0
- package/dist/docs/ScProfilePopup.md +396 -0
- package/dist/docs/ScProfileSettingsComp.md +250 -0
- package/dist/docs/ScProfileV2Mobile.md +216 -0
- package/dist/docs/ScProgressBar.md +267 -0
- package/dist/docs/ScQuickPrompt.md +277 -0
- package/dist/docs/ScRadio.md +228 -0
- package/dist/docs/ScReferralCardMobile.md +226 -0
- package/dist/docs/ScReferralTableHeader.md +260 -0
- package/dist/docs/ScReferralTableList.md +293 -0
- package/dist/docs/ScRole.md +226 -0
- package/dist/docs/ScRoleMobile.md +199 -0
- package/dist/docs/ScSelect.md +270 -0
- package/dist/docs/ScSelection.md +256 -0
- package/dist/docs/ScSelectionList.md +272 -0
- package/dist/docs/ScSelectionPill.md +240 -0
- package/dist/docs/ScSelectionPillGroup.md +302 -0
- package/dist/docs/ScSettingsNav.md +212 -0
- package/dist/docs/ScSettingsTabComp.md +260 -0
- package/dist/docs/ScSideBarLogoUnit.md +340 -0
- package/dist/docs/ScSidebar.md +243 -0
- package/dist/docs/ScSidebarIcons.md +232 -0
- package/dist/docs/ScSidebarMenu.md +283 -0
- package/dist/docs/ScSidebarProfile.md +231 -0
- package/dist/docs/ScSidebarSwitchMenu.md +258 -0
- package/dist/docs/ScSlider.md +194 -0
- package/dist/docs/ScStoreCard.md +252 -0
- package/dist/docs/ScStrLogo.md +253 -0
- package/dist/docs/ScStreamoidWordmark.md +302 -0
- package/dist/docs/ScSubAgent.md +226 -0
- package/dist/docs/ScTabComp.md +308 -0
- package/dist/docs/ScTabField.md +258 -0
- package/dist/docs/ScTabSwitcher.md +307 -0
- package/dist/docs/ScTableHeader.md +261 -0
- package/dist/docs/ScTableList.md +301 -0
- package/dist/docs/ScTableListMobile.md +282 -0
- package/dist/docs/ScTabs.md +268 -0
- package/dist/docs/ScTaxonomyPill.md +263 -0
- package/dist/docs/ScTextArea.md +259 -0
- package/dist/docs/ScTextField.md +324 -0
- package/dist/docs/ScThinkingStepIcon.md +249 -0
- package/dist/docs/ScTodoList.md +288 -0
- package/dist/docs/ScToggleSwitch.md +229 -0
- package/dist/docs/ScUsageHistoryMobile.md +194 -0
- package/dist/docs/ScVDivider.md +215 -0
- package/dist/docs/ScValueMappingL1.md +256 -0
- package/dist/docs/ScVersion.md +251 -0
- package/dist/docs/ScWorkspace.md +233 -0
- package/dist/docs/ScWorkspaceCard.md +234 -0
- package/dist/docs/ScWorkspaceSettingsMobile.md +265 -0
- package/dist/docs/ScWorkspaceSwitchCard.md +314 -0
- package/dist/docs/ScWorkspaceSwitchMobile.md +241 -0
- package/dist/docs/ScWorkspaceSwitchMobileV2.md +278 -0
- package/dist/docs/StreamoidSidebar.md +403 -0
- package/dist/docs/StreamoidWorkspaceSwitcher.md +307 -0
- package/dist/docs/UsageHistoryMobile.md +235 -0
- package/dist/docs/components.json +4849 -0
- package/dist/index.css +43 -37
- package/dist/index.d.mts +10 -0
- package/dist/index.d.ts +10 -0
- package/package.json +3 -2
|
@@ -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}`.
|