@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,301 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: ScTableList
|
|
3
|
+
package: "@streamoid/ui"
|
|
4
|
+
category: tables
|
|
5
|
+
status: stable
|
|
6
|
+
renders: div
|
|
7
|
+
tags: [table, row, members, team, users, invites, pending, settings, teams-row]
|
|
8
|
+
related: [ScTableHeader, ScProfile, ScRole, ScAccess, ScPendingAction, ScTableListMobile, ScCatalogixStoreTableList]
|
|
9
|
+
do_not_confuse_with: [ScTableHeader, ScTableListMobile, ScReferralTableList, ScBillingLogsTableList, ScBillingHistoryTableList, ScCatalogixStoreTableList]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# ScTableList
|
|
13
|
+
|
|
14
|
+
**One row of the Teams / members table — the Figma export, largely un-parameterised.**
|
|
15
|
+
It renders `ScProfile` + `ScRole` + two `ScAccess` icon groups + an "invited by" cell,
|
|
16
|
+
then either a date (`variant="active"`) or `ScPendingAction` (`variant="pending"`), on
|
|
17
|
+
the widths `ScTableHeader` defines.
|
|
18
|
+
|
|
19
|
+
## TL;DR for agents
|
|
20
|
+
|
|
21
|
+
- **Reach for it when:** you want a quick, visually correct members-table row and the
|
|
22
|
+
*only* real data you need to show is the user's **email**, who **invited** them, and
|
|
23
|
+
the **signed-on date**.
|
|
24
|
+
- **Don't reach for it when:** you need to show the member's real **name**, real
|
|
25
|
+
**role**, real **avatar**, real **app access**, or wire the pending Cancel/Resend
|
|
26
|
+
buttons. None of that is reachable through props. Compose the row yourself from
|
|
27
|
+
`ScProfile` + `ScRole` + `ScAccess` + `ScPendingAction` under a `ScTableHeader` —
|
|
28
|
+
which is exactly what CXO and `@streamoid/settings` both do.
|
|
29
|
+
- **Five things that will bite you:**
|
|
30
|
+
1. The display **name is always "Chris Hemsworth"**. `ScProfile` is rendered with
|
|
31
|
+
only `subText`, so its `name` default leaks into production.
|
|
32
|
+
2. The **role chip is always the blue "Admin"**. `ScRole` is rendered with no props.
|
|
33
|
+
3. The **access icons are hardcoded** — Artifax + Photogenix + Catalogix, then
|
|
34
|
+
User-add + Coins — regardless of the member's actual permissions.
|
|
35
|
+
4. `ScPendingAction`'s Cancel/Resend buttons have **no callbacks at all**; the row
|
|
36
|
+
exposes none either.
|
|
37
|
+
5. `{...props}` is spread **after** the internal `onClick`, so passing your own
|
|
38
|
+
`onClick` silently disables `onRowClick`.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 1. How to use it
|
|
43
|
+
|
|
44
|
+
### Import
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { ScTableHeader, ScTableList } from "@streamoid/ui";
|
|
48
|
+
import "@streamoid/ui/dist/index.css"; // once, at your app root
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Minimal usage
|
|
52
|
+
|
|
53
|
+
Every prop has a placeholder default, so the bare call renders — with demo data:
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
<ScTableList
|
|
57
|
+
userEmail={member.userEmail}
|
|
58
|
+
invitedBy={member.invitedBy}
|
|
59
|
+
signedOn={member.signedOn}
|
|
60
|
+
variant="active"
|
|
61
|
+
/>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Props
|
|
65
|
+
|
|
66
|
+
| Prop | Type | Default | Notes |
|
|
67
|
+
|---|---|---|---|
|
|
68
|
+
| `userEmail` | `string` | `"chris@kepler.com"` | ⚠️ Placeholder default. Passed to `ScProfile` as `subText` — the **second** line of the profile cell. |
|
|
69
|
+
| `invitedBy` | `string` | `"Rohan"` | ⚠️ Placeholder default. The INVITED BY cell (7.5rem, truncated, no tooltip). Also doubles as the `rowId` handed to `onRowClick` — see Gotcha 6. |
|
|
70
|
+
| `signedOn` | `string` | `"Nov 9th, 2025"` | ⚠️ Placeholder default. Pre-formatted string; the row does no date formatting. **`variant="active"` only.** |
|
|
71
|
+
| `variant` | `"active"` \| `"pending"` | `"active"` | Picks the fifth column: `active` → the `signedOn` date cell; `pending` → `ScPendingAction`. |
|
|
72
|
+
| `hover` | `"false"` \| `"true"` | `"false"` | ⚠️ A **string** union, not a boolean. `"true"` force-paints the hover background (Figma parity / screenshots). Real `:hover` already works without it. |
|
|
73
|
+
| `className` | `string` | – | Appended after the internal class. |
|
|
74
|
+
| `onRowClick` | `(rowId: string, event: React.MouseEvent) => void` | – | Fires on the whole row. `rowId` is **`invitedBy`**, not an id. |
|
|
75
|
+
| `...props` | `HTMLAttributes<HTMLDivElement>` | – | Spread onto the root div **after** `onClick` — so a passed `onClick` wins over `onRowClick`. |
|
|
76
|
+
|
|
77
|
+
### What renders in each column — and what you can control
|
|
78
|
+
|
|
79
|
+
| Column | Rendered by | Controllable? |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| USER (`flex: 1`) | `ScProfile subText={userEmail}` | ⚠️ **email only.** `name` falls back to `"Chris Hemsworth"`; `profileImage` falls back to the relative path `"profile-image0.png"` → a broken image in every host. |
|
|
82
|
+
| ROLE (`5rem`) | `ScRole` with **no props** | ❌ Always the blue `Admin` chip. |
|
|
83
|
+
| ACCESS (`11.25rem`) | two `ScAccess` groups | ❌ Group 1 = Artifax + Photogenix + Catalogix; group 2 = User-add + Coins. Always all five. |
|
|
84
|
+
| INVITED BY (`7.5rem`) | plain text cell | ✅ `invitedBy` |
|
|
85
|
+
| SIGNED ON (`7.5rem`, `variant="active"`) | plain text cell | ✅ `signedOn` |
|
|
86
|
+
| INVITE ACTION (`10rem`, `variant="pending"`) | `ScPendingAction` | ❌ Renders "Cancel" + divider + "Resend" with **no handlers**. |
|
|
87
|
+
|
|
88
|
+
### Recipes
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
// The full table, as far as this component can take you
|
|
92
|
+
<div style={{ display: "flex", flexDirection: "column" }}>
|
|
93
|
+
<ScTableHeader type={tab === "active" ? "default" : "pending"} />
|
|
94
|
+
{members.map((m) => (
|
|
95
|
+
<ScTableList
|
|
96
|
+
key={m.id}
|
|
97
|
+
variant={tab}
|
|
98
|
+
userEmail={m.userEmail}
|
|
99
|
+
invitedBy={m.invitedBy}
|
|
100
|
+
signedOn={m.signedOn}
|
|
101
|
+
onRowClick={() => openMember(m)} // ignore the rowId arg; close over `m` instead
|
|
102
|
+
/>
|
|
103
|
+
))}
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
// Row click — use onRowClick, never onClick (see Gotcha 5)
|
|
107
|
+
<ScTableList userEmail={m.userEmail} onRowClick={(_rowId, e) => { e.stopPropagation(); edit(m); }} />
|
|
108
|
+
|
|
109
|
+
// What you should actually build when the data is real: the same contract, your own row.
|
|
110
|
+
// Widths and gap must match ScTableHeader exactly: flex:1 / 5rem / 11.25rem / 7.5rem / 7.5rem|10rem,
|
|
111
|
+
// gap 1.5rem, padding-inline 1rem.
|
|
112
|
+
<div style={{ display: "flex", alignItems: "center", gap: "1.5rem", padding: "1.25rem 1rem" }}>
|
|
113
|
+
<div style={{ flex: 1, minWidth: 0 }}>{/* your avatar + name/email stack */}</div>
|
|
114
|
+
<ScRole type={m.role === "admin" ? "admin" : "member"} /> {/* type is "admin" | "member" only */}
|
|
115
|
+
{/* your permission-driven access icons, 11.25rem */}
|
|
116
|
+
<div style={{ width: "7.5rem" }}>{m.invitedBy}</div>
|
|
117
|
+
{tab === "active" ? <div style={{ width: "7.5rem" }}>{m.signedOn}</div> : <ScPendingAction /* see Gotcha 4 */ />}
|
|
118
|
+
</div>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 2. Where to use it
|
|
124
|
+
|
|
125
|
+
- **Settings → Teams**, desktop, under a `ScTableHeader` — Active members and Pending
|
|
126
|
+
invitations. That is the only surface it was drawn for.
|
|
127
|
+
- It composes `ScProfile`, `ScRole`, `ScAccess` ×2 and `ScPendingAction`. Those four are
|
|
128
|
+
the pieces to reuse when you outgrow the row (which happens as soon as the member's
|
|
129
|
+
name or role is real data).
|
|
130
|
+
- The mobile equivalent of this screen is `ScTableListMobile` — a stacked card, no
|
|
131
|
+
shared width contract, and fully parameterised.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 3. When to use it
|
|
136
|
+
|
|
137
|
+
### Use it when
|
|
138
|
+
|
|
139
|
+
- You are prototyping or screenshotting the Teams table and want pixel-correct
|
|
140
|
+
chrome with zero wiring.
|
|
141
|
+
- Your row genuinely only needs email + invited-by + date, and the Admin chip and the
|
|
142
|
+
five access icons happen to be right.
|
|
143
|
+
|
|
144
|
+
### Don't use it — reach for this instead
|
|
145
|
+
|
|
146
|
+
| Situation | Use instead |
|
|
147
|
+
|---|---|
|
|
148
|
+
| Real member data — name, role, avatar, per-app access | Your own row composed from `ScProfile` + `ScRole` + `ScAccess` + `ScPendingAction`, under `ScTableHeader`. See the third recipe. |
|
|
149
|
+
| Working Cancel / Resend on a pending invite | `ScPendingAction` rendered directly, with the click hit-test described in Gotcha 4 |
|
|
150
|
+
| Mobile members list | `ScTableListMobile` |
|
|
151
|
+
| Referral history row (User / Date / Status / Reward) | `ScReferralTableList` |
|
|
152
|
+
| Credit & usage log row | `ScBillingLogsTableList` |
|
|
153
|
+
| Invoice row with a download action | `ScBillingHistoryTableList` |
|
|
154
|
+
| Catalogix stores row | `ScCatalogixStoreTableList` |
|
|
155
|
+
| Just the role chip, or just the access icons | `ScRole` / `ScAccess` on their own |
|
|
156
|
+
|
|
157
|
+
### Don't confuse with
|
|
158
|
+
|
|
159
|
+
| You may actually want | Not this |
|
|
160
|
+
|---|---|
|
|
161
|
+
| `ScTableHeader` — the header strip; takes `type`, not row data | `ScTableList` is one row |
|
|
162
|
+
| `ScTableListMobile` — the members row for mobile: `name`, `email`, `imageUrl`, `role`, `accessIcons[]`, `permissionIcons[]` all real props | This desktop row hardcodes all of those |
|
|
163
|
+
| `ScCatalogixStoreTableList` — the stores row, fully prop-driven, with `showAssets`/`showCreatedBy` gating | Different table, different schema |
|
|
164
|
+
| `ScReferralTableList` — looks similar (a `ScProfile` + text cells) but its columns are Date / Status / Reward | Not interchangeable; the widths differ |
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 4. Why to use it
|
|
169
|
+
|
|
170
|
+
- **It is the alignment contract's other half.** Its widths (`flex:1`, `5rem` from
|
|
171
|
+
`ScRole`, `11.25rem`, `7.5rem`, `7.5rem`/`10rem` from `ScPendingAction`), its
|
|
172
|
+
`1.5rem` gap and its `1rem` inline padding are the same numbers `ScTableHeader`
|
|
173
|
+
uses. Copy them if you hand-roll.
|
|
174
|
+
- **The hover skin and the row rule are tokenised** — `--alias-fill-neutral-neutralplus`
|
|
175
|
+
on hover, `--alias-border-subtle` for the 1px bottom rule — so both survive the
|
|
176
|
+
light/dark flip.
|
|
177
|
+
- **The two-column-collapse behaviour is already right:** the profile cell flexes and
|
|
178
|
+
truncates with an ellipsis while every other cell holds its width.
|
|
179
|
+
- Honest caveat: beyond the chrome and those numbers, the value here is low. Read
|
|
180
|
+
Gotchas 1–4 before choosing it over composing the four child components yourself.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Gotchas
|
|
185
|
+
|
|
186
|
+
**1. The member's name is a hardcoded demo string.** `ScProfile` is rendered with only
|
|
187
|
+
`subText={userEmail}`, so `ScProfile`'s own `name` default — `"Chris Hemsworth"` —
|
|
188
|
+
renders on every row. There is no `userName` prop (`ScReferralTableList`, confusingly,
|
|
189
|
+
*does* have one).
|
|
190
|
+
|
|
191
|
+
```tsx
|
|
192
|
+
// WRONG — you will ship "Chris Hemsworth" above every email
|
|
193
|
+
<ScTableList userEmail={m.userEmail} />
|
|
194
|
+
|
|
195
|
+
// RIGHT — compose the profile cell yourself
|
|
196
|
+
<ScProfile name={m.name} subText={m.userEmail} profileImage={m.avatarUrl} style={{ flex: 1 }} />
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**2. The avatar is a broken image.** `ScProfile`'s `profileImage` default is the
|
|
200
|
+
relative path `"profile-image0.png"`, resolved against the current route, and the row
|
|
201
|
+
gives you no way to override it. You get a broken-image glyph (and the `<img>` has no
|
|
202
|
+
`alt`).
|
|
203
|
+
|
|
204
|
+
**3. The role chip and the access icons are decoration.** `ScRole` gets no props →
|
|
205
|
+
always the blue `Admin` chip, even for members. `ScAccess` gets a fixed icon set →
|
|
206
|
+
Artifax, Photogenix, Catalogix, then User-add and Coins, for everyone. A row will
|
|
207
|
+
happily claim a read-only member is an admin with access to all three apps.
|
|
208
|
+
|
|
209
|
+
**4. `ScPendingAction` has no per-button callbacks.** Its own props are `className` plus
|
|
210
|
+
the usual `React.HTMLAttributes<HTMLDivElement>` spread — there is no `onCancel` /
|
|
211
|
+
`onResend`, and the two `ScButton`s inside are constructed internally with no `onClick`.
|
|
212
|
+
So `variant="pending"` renders a Cancel and a Resend button that do nothing, and the row
|
|
213
|
+
offers no `onCancel`/`onResend`. The working pattern (used by both hosts) is to render
|
|
214
|
+
`ScPendingAction` yourself and hit-test the click against its first/last child:
|
|
215
|
+
|
|
216
|
+
```tsx
|
|
217
|
+
<ScPendingAction
|
|
218
|
+
onClick={(event) => {
|
|
219
|
+
event.stopPropagation();
|
|
220
|
+
const root = event.currentTarget as HTMLElement;
|
|
221
|
+
const target = event.target as HTMLElement;
|
|
222
|
+
const cancel = root.children.item(0) as HTMLElement | null;
|
|
223
|
+
const resend = root.children.item(root.children.length - 1) as HTMLElement | null;
|
|
224
|
+
if (cancel?.contains(target)) return onCancelInvite();
|
|
225
|
+
if (resend?.contains(target)) return onResendInvite();
|
|
226
|
+
}}
|
|
227
|
+
/>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**5. Your `onClick` kills `onRowClick`.** The root is
|
|
231
|
+
`<div onClick={…onRowClick…} {...props}>` — the spread comes last, so a passed
|
|
232
|
+
`onClick` overwrites the internal handler.
|
|
233
|
+
|
|
234
|
+
```tsx
|
|
235
|
+
// WRONG — onRowClick never fires
|
|
236
|
+
<ScTableList onClick={handle} onRowClick={handleRow} />
|
|
237
|
+
|
|
238
|
+
// RIGHT — pick one
|
|
239
|
+
<ScTableList onRowClick={handleRow} />
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**6. `onRowClick`'s first argument is `invitedBy`, not an id.** Signature is
|
|
243
|
+
`(rowId: string, event) => void` and the row calls `onRowClick(invitedBy, e)`. Ignore
|
|
244
|
+
the argument and close over your own record.
|
|
245
|
+
|
|
246
|
+
**7. `hover` is `"true"` / `"false"` as strings.** `hover={true}` is a type error;
|
|
247
|
+
`hover="true"` force-paints the hover background permanently. Only use it for design
|
|
248
|
+
parity — real `:hover` is already wired in CSS.
|
|
249
|
+
|
|
250
|
+
**8. Placeholder defaults everywhere.** `invitedBy`, `signedOn` and `userEmail` all
|
|
251
|
+
default to demo values, so a typo'd prop name renders plausible-looking fake data
|
|
252
|
+
instead of failing. Check spelling against the props table.
|
|
253
|
+
|
|
254
|
+
**9. Not a table row.** No `role="row"`/`cell`, no `<td>`. The cells are not associated
|
|
255
|
+
with `ScTableHeader`'s labels for assistive tech.
|
|
256
|
+
|
|
257
|
+
**10. Every row draws a bottom border, including the last one.** Suppress it on the
|
|
258
|
+
final row via `className` if your container already has a border.
|
|
259
|
+
|
|
260
|
+
**11. Cells truncate with no tooltip.** INVITED BY and SIGNED ON are fixed-width,
|
|
261
|
+
`nowrap`, `overflow: hidden`, `text-overflow: ellipsis`, and there is **no `title`
|
|
262
|
+
attribute**. A long inviter name just disappears.
|
|
263
|
+
|
|
264
|
+
**12. `className` lands as the literal string `"undefined"` when omitted** — the class
|
|
265
|
+
list is built by concatenation. Harmless in the browser; breaks exact-string class
|
|
266
|
+
assertions in tests.
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## In the wild
|
|
271
|
+
|
|
272
|
+
_No host render site found — used by the agent runtime / composed internally._
|
|
273
|
+
|
|
274
|
+
More precisely: **no consumer renders it, and that is deliberate.** Both Teams screens
|
|
275
|
+
render `ScTableHeader` and then a *local* row, because of Gotchas 1–4:
|
|
276
|
+
|
|
277
|
+
- `cxo-dashboard src/app/components/teams-content.tsx:530` — `function TeamRow(...)`,
|
|
278
|
+
which reuses `ScRole` (with real `type`/`label`), `ScPendingAction` (with the
|
|
279
|
+
hit-test from Gotcha 4) and a hand-built profile cell, on this component's widths.
|
|
280
|
+
- `npm-components packages/settings/src/teams-content.tsx:514` — the same `TeamRow`,
|
|
281
|
+
in the shared settings package that ships into CXO desktop settings.
|
|
282
|
+
|
|
283
|
+
Where it *belongs*: Settings → Teams, desktop, directly under
|
|
284
|
+
`<ScTableHeader type="default" | "pending" />` — once `userName`, `profileImage`,
|
|
285
|
+
`role`, an access-icons prop and `onCancelInvite`/`onResendInvite` are added to the DS,
|
|
286
|
+
at which point both `TeamRow` copies can be deleted.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Related
|
|
291
|
+
|
|
292
|
+
- `ScTableHeader` — the header strip that defines this row's widths; always render it above.
|
|
293
|
+
- `ScProfile` — the USER cell; pass `name` **and** `subText` **and** `profileImage` yourself.
|
|
294
|
+
- `ScRole` — the role chip; `type="admin" | "member"` plus an optional `label` override
|
|
295
|
+
(fixed `5rem × 2.5rem`, which is where this row's ROLE width comes from).
|
|
296
|
+
- `ScAccess` — one access-icon group; `component` / `component2` / `component3` +
|
|
297
|
+
`visibleSiconCatalogix` let you drive it from real permissions.
|
|
298
|
+
- `ScPendingAction` — the Cancel/Resend pair (no per-button callbacks; see Gotcha 4).
|
|
299
|
+
- `ScTableListMobile` — the mobile twin, and the fully prop-driven one.
|
|
300
|
+
- `ScReferralTableList` / `ScBillingLogsTableList` / `ScBillingHistoryTableList` /
|
|
301
|
+
`ScCatalogixStoreTableList` — the other domain rows, same header+row pattern.
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: ScTableListMobile
|
|
3
|
+
package: "@streamoid/ui"
|
|
4
|
+
category: mobile
|
|
5
|
+
status: stable
|
|
6
|
+
renders: div
|
|
7
|
+
tags: [table, row, mobile, members, team, users, invites, teams, responsive, card]
|
|
8
|
+
related: [ScTableList, ScTableHeader, ScProfileV2Mobile, ScRoleMobile, ScRole, ScAccess, ScMobileBottomAction]
|
|
9
|
+
do_not_confuse_with: [ScTableList, ScTableHeader, ScReferralCardMobile, ScProfileV2Mobile, ScRoleMobile, ScRole]
|
|
10
|
+
used_by: [cxo]
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# ScTableListMobile
|
|
14
|
+
|
|
15
|
+
**The members row for narrow screens — a two-line stacked card, not a table row.**
|
|
16
|
+
Line 1 is name + email on the left with a 40px avatar (or initials) on the **right**;
|
|
17
|
+
line 2 is a role badge on the left and up to two pill-shaped icon groups on the right.
|
|
18
|
+
Unlike its desktop twin `ScTableList`, everything it shows is a real prop.
|
|
19
|
+
|
|
20
|
+
## TL;DR for agents
|
|
21
|
+
|
|
22
|
+
- **Reach for it when:** you are rendering the Teams / members list on CXO mobile, or
|
|
23
|
+
a single member's summary card in a mobile drawer or popup.
|
|
24
|
+
- **Don't reach for it when:** you're on desktop (→ `ScTableHeader` + your own row, see
|
|
25
|
+
`SC-tableList/README.md`), or you want the referral card (→ `ScReferralCardMobile`).
|
|
26
|
+
- **Three things that will bite you:**
|
|
27
|
+
1. `name`, `email` and `role` all have **placeholder defaults** — forget one and you
|
|
28
|
+
ship "Chris Hemsworth / chris@kepler.com / Admin".
|
|
29
|
+
2. The role badge is a **fixed 64×32px blue info chip with no variants**. "Member"
|
|
30
|
+
is as blue as "Admin", and anything longer than ~7 characters overflows it.
|
|
31
|
+
3. `{...props}` is spread **after** `onClick={onRowClick}`, so passing your own
|
|
32
|
+
`onClick` silently replaces `onRowClick`. There is also **no `cursor: pointer`**
|
|
33
|
+
and no hover/press state — a tappable row looks inert.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 1. How to use it
|
|
38
|
+
|
|
39
|
+
### Import
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { ScTableListMobile } from "@streamoid/ui";
|
|
43
|
+
import "@streamoid/ui/dist/index.css"; // once, at your app root
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Minimal usage
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<ScTableListMobile
|
|
50
|
+
name={member.name}
|
|
51
|
+
email={member.userEmail}
|
|
52
|
+
role={member.permissions.role === "admin" ? "Admin" : "Member"}
|
|
53
|
+
onRowClick={() => openMember(member)}
|
|
54
|
+
/>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Props
|
|
58
|
+
|
|
59
|
+
| Prop | Type | Default | Notes |
|
|
60
|
+
|---|---|---|---|
|
|
61
|
+
| `name` | `string` | `"Chris Hemsworth"` | ⚠️ Placeholder default. Line 1, medium 14px, truncates. Also the source of the initials fallback and the `<img alt>`. |
|
|
62
|
+
| `email` | `string` | `"chris@kepler.com"` | ⚠️ Placeholder default. Line 2, regular 12px tertiary, truncates. |
|
|
63
|
+
| `imageUrl` | `string` | – | Avatar `src`. When omitted, a 40px circle of **initials derived from `name`** is drawn instead (first letter of each space-separated word, uppercased, first 2 chars). |
|
|
64
|
+
| `role` | `string` | `"Admin"` | ⚠️ Placeholder default. Free string, rendered in a fixed 64×32px blue info badge. **No variants** — see Gotcha 2. |
|
|
65
|
+
| `accessIcons` | `JSX.Element[]` | – | First icon pill (app access). Each element is wrapped in a 20×20 span. The whole pill is **omitted when the array is empty or undefined**. |
|
|
66
|
+
| `permissionIcons` | `JSX.Element[]` | – | Second icon pill (capabilities, e.g. invite / credits). Same rules. |
|
|
67
|
+
| `onRowClick` | `(e: React.MouseEvent) => void` | – | Wired to the root's `onClick`. Takes the event only — no id (unlike `ScTableList`, which passes `invitedBy`). |
|
|
68
|
+
| `className` | `string` | – | Appended after the internal class. |
|
|
69
|
+
| `...props` | `HTMLAttributes<HTMLDivElement>` | – | Spread onto the root div **after** `onClick` — a passed `onClick` wins over `onRowClick`. |
|
|
70
|
+
|
|
71
|
+
### Layout at a glance
|
|
72
|
+
|
|
73
|
+
| Region | Contents | Notes |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| `profileRow` | `name` / `email` stack (`flex: 1`, truncating) → avatar | ⚠️ Avatar is on the **right**. `ScProfile` (desktop) puts it on the left. |
|
|
76
|
+
| avatar | `<img src={imageUrl} alt={name}>` **or** an initials circle | 40×40, `border-radius: full`, `object-fit: cover`, `overflow: hidden` |
|
|
77
|
+
| `detailsRow` | role badge ← `space-between` → icon pills | Badge fixed 64×32; pills are `--alias-fill-neutral-neutral` at `radius-lg` |
|
|
78
|
+
| root | `width: 100%`, `padding: 20px 16px`, `border-bottom: 0.5px` | Bottom rule on every card, including the last |
|
|
79
|
+
|
|
80
|
+
### Recipes
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
// The mobile members list — icons built from real permissions
|
|
84
|
+
{members.map((m) => (
|
|
85
|
+
<ScTableListMobile
|
|
86
|
+
key={m.id}
|
|
87
|
+
name={m.name || m.userEmail.split("@")[0]}
|
|
88
|
+
email={m.userEmail}
|
|
89
|
+
role={m.permissions.role === "admin" ? "Admin" : "Member"}
|
|
90
|
+
accessIcons={[
|
|
91
|
+
...(m.permissions.artifax ? [<SiconArtifacts key="a" size={20} />] : []),
|
|
92
|
+
...(m.permissions.photogenix ? [<SiconPhotogenix key="p" size={20} />] : []),
|
|
93
|
+
...(m.permissions.catalogix ? [<SiconCatalogix key="c" size={20} />] : []),
|
|
94
|
+
]}
|
|
95
|
+
permissionIcons={[
|
|
96
|
+
...(m.permissions.canInviteUser ? [<SiconUserAdd key="u" size={20} />] : []),
|
|
97
|
+
...(m.permissions.canUseCredits ? [<SiconCoins key="cr" size={20} />] : []),
|
|
98
|
+
]}
|
|
99
|
+
onRowClick={() => handleMemberClick(m)}
|
|
100
|
+
className="w-full"
|
|
101
|
+
/>
|
|
102
|
+
))}
|
|
103
|
+
|
|
104
|
+
// One member as the header of a detail drawer — non-interactive, custom rule
|
|
105
|
+
<ScTableListMobile
|
|
106
|
+
name={member.name}
|
|
107
|
+
email={member.userEmail}
|
|
108
|
+
role="Member"
|
|
109
|
+
style={{ borderBottom: "0.5px solid var(--alias-border-subtle)", paddingBottom: "20px" }}
|
|
110
|
+
/>
|
|
111
|
+
|
|
112
|
+
// Give a tappable card an affordance — the DS supplies none
|
|
113
|
+
<ScTableListMobile name={m.name} email={m.userEmail} onRowClick={open} className="cursor-pointer" />
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 2. Where to use it
|
|
119
|
+
|
|
120
|
+
- **CXO mobile → Settings → Teams**, in both the members list and the pending-invites
|
|
121
|
+
list. There is **no mobile header strip** — the label/value pairing that
|
|
122
|
+
`ScTableHeader` provides on desktop is replaced by the card's own two-line layout.
|
|
123
|
+
- **CXO mobile → pending-invite detail popup**, rendered once at the top as the
|
|
124
|
+
member summary, with `style` overriding the bottom rule.
|
|
125
|
+
- It composes nothing from the DS — plain divs, an `<img>` and your icons. It does
|
|
126
|
+
**not** use `ScProfile`, `ScRole`, `ScAccess`, `ScProfileV2Mobile` or `ScRoleMobile`,
|
|
127
|
+
even though the last two are near-identical to the regions it inlines. That
|
|
128
|
+
duplication is why its role badge doesn't distinguish admin from member.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 3. When to use it
|
|
133
|
+
|
|
134
|
+
### Use it when
|
|
135
|
+
|
|
136
|
+
- The viewport is narrow and a five-column table would be unusable.
|
|
137
|
+
- You have real member data (name, email, role, permissions) — this component, unlike
|
|
138
|
+
`ScTableList`, actually accepts all of it.
|
|
139
|
+
- You want the member summary card in a mobile drawer/popup to look identical to the
|
|
140
|
+
rows in the list behind it.
|
|
141
|
+
|
|
142
|
+
### Don't use it — reach for this instead
|
|
143
|
+
|
|
144
|
+
| Situation | Use instead |
|
|
145
|
+
|---|---|
|
|
146
|
+
| Desktop members table | `ScTableHeader` + your own row (see `SC-tableList/README.md`); `ScTableList` only if placeholder content is acceptable |
|
|
147
|
+
| Referral entry on mobile | `ScReferralCardMobile` |
|
|
148
|
+
| Just an avatar + name/email pair on mobile | `ScProfileV2Mobile` — same layout as this card's line 1, plus `dpPosition="left" \| "right"` |
|
|
149
|
+
| A role chip that distinguishes admin from member | `ScRoleMobile` (`role="admin" \| "member"`, identical 64×32 box) on mobile, `ScRole` on desktop. This card's inline badge does not |
|
|
150
|
+
| Sticky bottom "Invite user" action on the same screen | `ScMobileBottomAction` |
|
|
151
|
+
| Referral / billing / stores rows | `ScReferralTableList`, `ScBillingLogsTableList`, `ScBillingHistoryTableList`, `ScCatalogixStoreTableList` (all desktop) |
|
|
152
|
+
|
|
153
|
+
### Don't confuse with
|
|
154
|
+
|
|
155
|
+
| You may actually want | Not this |
|
|
156
|
+
|---|---|
|
|
157
|
+
| `ScTableList` — the desktop members row. Hardcodes name, avatar, role and access icons; has `variant="active" \| "pending"` and `hover` | `ScTableListMobile` parameterises all of that but has **no** `variant` and no pending-action buttons |
|
|
158
|
+
| `ScTableHeader` — the desktop column-header strip | Mobile has no header; don't try to pair one with these cards |
|
|
159
|
+
| `ScReferralCardMobile` — the mobile card for the *referral* table | Different data, different layout |
|
|
160
|
+
| `ScRoleMobile` — the standalone mobile role chip, `role="admin" \| "member"`, same 64×32 box | This card draws an equivalent badge inline and ignores `ScRoleMobile` entirely, so it has no member skin |
|
|
161
|
+
| `ScProfileV2Mobile` — the same name/email/avatar block as line 1, but with `dpPosition` | This card's avatar is fixed to the **right**; `ScProfile` (desktop) puts it on the left |
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 4. Why to use it
|
|
166
|
+
|
|
167
|
+
- **It is the only members row in the DS you can actually drive with data.** Name,
|
|
168
|
+
email, avatar, role and both icon groups are props; the desktop `ScTableList`
|
|
169
|
+
hardcodes every one of them.
|
|
170
|
+
- **The truncation is already correct.** The name/email stack is `flex: 1; min-width: 0`
|
|
171
|
+
with `overflow: hidden; text-overflow: ellipsis`, so long emails ellipsise instead of
|
|
172
|
+
pushing the avatar off-screen — the single most common hand-rolled mobile row bug.
|
|
173
|
+
- **Initials fallback for free.** No avatar URL still yields a filled circle rather
|
|
174
|
+
than a broken `<img>` (which is exactly what `ScTableList` ships).
|
|
175
|
+
- **Empty icon pills disappear.** A member with no app access renders no pill at all,
|
|
176
|
+
instead of an empty grey rectangle.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Gotchas
|
|
181
|
+
|
|
182
|
+
**1. `name`, `email` and `role` default to demo values.** A typo'd prop name renders
|
|
183
|
+
plausible fake data instead of failing.
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
// WRONG — renders "Chris Hemsworth / chris@kepler.com / Admin"
|
|
187
|
+
<ScTableListMobile userName={m.name} userEmail={m.userEmail} />
|
|
188
|
+
|
|
189
|
+
// RIGHT
|
|
190
|
+
<ScTableListMobile name={m.name} email={m.userEmail} role="Member" />
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**2. The role badge has no variants and a fixed 64px width.** It is always the blue
|
|
194
|
+
info skin (`fill-info-soft` / `border-infoplus`), so "Member", "Viewer" and "Admin" are
|
|
195
|
+
visually identical. The text is `white-space: nowrap` inside a `width: 64px` flex box
|
|
196
|
+
with no `overflow: hidden`, so anything longer than ~7 characters spills outside the
|
|
197
|
+
badge outline. Keep `role` to one short word, or use `ScRole` in your own row.
|
|
198
|
+
|
|
199
|
+
**3. Your `onClick` replaces `onRowClick`.** The root is
|
|
200
|
+
`<div onClick={onRowClick} {...props}>` — the spread wins.
|
|
201
|
+
|
|
202
|
+
```tsx
|
|
203
|
+
// WRONG — onRowClick never fires
|
|
204
|
+
<ScTableListMobile onClick={handle} onRowClick={handleRow} />
|
|
205
|
+
|
|
206
|
+
// RIGHT
|
|
207
|
+
<ScTableListMobile onRowClick={handleRow} />
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**4. No tap affordance and no hover/active state.** No `cursor: pointer`, no
|
|
211
|
+
`role="button"`, no `tabIndex`, no background change. Add `cursor-pointer` (and, if the
|
|
212
|
+
row is a real control, `role="button"` + `tabIndex={0}` via `...props`) yourself.
|
|
213
|
+
|
|
214
|
+
**5. Initials come from `name` only, and only the first two words.**
|
|
215
|
+
`name.split(" ").map(n => n[0]).join("").toUpperCase().slice(0, 2)`. An email-derived
|
|
216
|
+
name like `"chris.hemsworth"` yields `"C"`; `name=""` yields an empty circle. Pass
|
|
217
|
+
`imageUrl` whenever you have one.
|
|
218
|
+
|
|
219
|
+
**6. Icon arrays must already be sized.** Each element is wrapped in a 20×20 span but
|
|
220
|
+
is **not** cloned or resized — pass `size={20}` (and a colour, since the card sets none
|
|
221
|
+
on the pill contents) on every `Sicon*`.
|
|
222
|
+
|
|
223
|
+
**7. Empty vs undefined matters.** `accessIcons={[]}` and `accessIcons={undefined}`
|
|
224
|
+
both remove the pill entirely; there is no placeholder. Build the array with spreads
|
|
225
|
+
(see the recipe) rather than pushing `null`s — a `null` element still renders an empty
|
|
226
|
+
20×20 span.
|
|
227
|
+
|
|
228
|
+
**8. Every card draws a 0.5px bottom border, including the last.** Override via
|
|
229
|
+
`className`/`style` if your container already has one.
|
|
230
|
+
|
|
231
|
+
**9. Hardcoded px, not rem.** Font sizes 14/12, avatar 40, badge 64×32 and icon 20 are
|
|
232
|
+
literal pixels (some behind token fallbacks). It does not respond to root font scaling
|
|
233
|
+
the way the desktop `rem`-based rows do.
|
|
234
|
+
|
|
235
|
+
**10. `className` lands as the literal string `"undefined"` when omitted** — the class
|
|
236
|
+
list is built by concatenation. Harmless in the browser; breaks exact-string class
|
|
237
|
+
assertions in tests.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## In the wild
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
// cxo-dashboard src/app/components/mobile-teams-content.tsx:307
|
|
245
|
+
<ScTableListMobile
|
|
246
|
+
key={member.id}
|
|
247
|
+
name={member.name || member.userEmail.split("@")[0]}
|
|
248
|
+
email={member.userEmail}
|
|
249
|
+
role={member.permissions.role === "admin" ? "Admin" : "Member"}
|
|
250
|
+
accessIcons={[
|
|
251
|
+
...(member.permissions.artifax ? [<SiconArtifacts key="a" size={20} color={T.primary} />] : []),
|
|
252
|
+
...(member.permissions.photogenix ? [<SiconPhotogenix key="p" size={20} color={T.primary} />] : []),
|
|
253
|
+
...(member.permissions.catalogix ? [<SiconCatalogix key="c" size={20} color={T.primary} />] : []),
|
|
254
|
+
]}
|
|
255
|
+
permissionIcons={[
|
|
256
|
+
...(member.permissions.canInviteUser ? [<SiconUserAdd key="u" size={20} color={T.primary} />] : []),
|
|
257
|
+
...(member.permissions.canUseCredits ? [<SiconCoins key="cr" size={20} color={T.primary} />] : []),
|
|
258
|
+
]}
|
|
259
|
+
onRowClick={() => handleMemberClick(member)}
|
|
260
|
+
className="w-full"
|
|
261
|
+
/>
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Also rendered once as a detail-popup header at
|
|
265
|
+
`cxo-dashboard src/app/components/mobile-teams-pending-popup.tsx:131`, there with no
|
|
266
|
+
`onRowClick` and a `style` that replaces the bottom rule.
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Related
|
|
271
|
+
|
|
272
|
+
- `ScTableList` — the desktop twin; read its README before choosing it (most of its
|
|
273
|
+
content is hardcoded).
|
|
274
|
+
- `ScTableHeader` — the desktop column strip; deliberately absent on mobile.
|
|
275
|
+
- `ScRoleMobile` — the mobile role chip with real admin/member variants; use it if the
|
|
276
|
+
badge here is too blunt. `ScRole` is its desktop equivalent.
|
|
277
|
+
- `ScAccess` — the desktop icon-group equivalent of `accessIcons` / `permissionIcons`.
|
|
278
|
+
- `ScProfileV2Mobile` — the name/email/avatar block on its own, with `dpPosition`;
|
|
279
|
+
`ScProfile` for the desktop, avatar-left form.
|
|
280
|
+
- `ScMobileBottomAction` — the sticky footer action that usually sits below this list.
|
|
281
|
+
- `@streamoid/icons` — `SiconArtifacts`, `SiconPhotogenix`, `SiconCatalogix`,
|
|
282
|
+
`SiconUserAdd`, `SiconCoins` are the icons these pills carry; see `packages/icons/ICONS.md`.
|