@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.
- package/README.md +35 -18
- package/dist/docs/AGENTS.md +325 -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 +210 -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/ScWorkspaceAccountMenu.md +115 -0
- package/dist/docs/ScWorkspaceCard.md +234 -0
- package/dist/docs/ScWorkspaceSettingsMobile.md +265 -0
- package/dist/docs/ScWorkspaceSwitchCard.md +312 -0
- package/dist/docs/ScWorkspaceSwitchMobile.md +241 -0
- package/dist/docs/ScWorkspaceSwitchMobileV2.md +278 -0
- package/dist/docs/StreamoidSidebar.md +413 -0
- package/dist/docs/StreamoidWorkspaceSwitcher.md +307 -0
- package/dist/docs/UsageHistoryMobile.md +235 -0
- package/dist/docs/components.json +4931 -0
- package/dist/index.css +361 -36
- package/dist/index.d.mts +213 -88
- package/dist/index.d.ts +213 -88
- package/dist/index.js +2486 -1629
- package/dist/index.mjs +2487 -1620
- package/package.json +5 -3
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: ScAccess
|
|
3
|
+
package: "@streamoid/ui"
|
|
4
|
+
category: profile
|
|
5
|
+
status: stable
|
|
6
|
+
renders: div
|
|
7
|
+
tags: [access, permissions, apps, icon-chip, icon-group, entitlements, team-table, read-only]
|
|
8
|
+
related: [ScTableList, ScRole, ScBadges, ScAppField]
|
|
9
|
+
do_not_confuse_with: [ScAppField, ScRole, ScBadges, ScAppSwitchPanel, ScAppCard]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# ScAccess
|
|
13
|
+
|
|
14
|
+
**A read-only chip holding up to three small icons.** (Its own fallback icons are
|
|
15
|
+
pinned to 20×20; icons *you* pass keep their own size — `Sicon*` default to 24.)
|
|
16
|
+
In the team table it is the
|
|
17
|
+
"what does this user have access to" cell — one chip for the apps they can open,
|
|
18
|
+
another for the permissions they hold. It is **not** a form control despite living
|
|
19
|
+
next to them: there is no state, no click handler, and no label.
|
|
20
|
+
|
|
21
|
+
## TL;DR for agents
|
|
22
|
+
|
|
23
|
+
- **Reach for it when:** you need a compact, non-interactive icon group summarising
|
|
24
|
+
entitlements in a dense table row.
|
|
25
|
+
- **Don't reach for it when:** the user should be able to *change* those
|
|
26
|
+
entitlements (→ `ScAppField`), you need text (→ `ScBadges`), or you're showing a
|
|
27
|
+
role name (→ `ScRole`).
|
|
28
|
+
- **Four things that will bite you:**
|
|
29
|
+
1. Every empty slot defaults to **`<SiconCatalogix />`** ⚠️ — forget a slot and you
|
|
30
|
+
ship a Catalogix logo.
|
|
31
|
+
2. `visibleSiconCatalogix` is **misnamed**: it gates the **third slot**, whatever
|
|
32
|
+
icon you put there.
|
|
33
|
+
3. **Hard cap of three icons.** Need four? Render two chips (that's what
|
|
34
|
+
`ScTableList` does).
|
|
35
|
+
4. **No props spread at all** — no `onClick`, `style`, `title`, `aria-*`, `id`. The
|
|
36
|
+
icons carry meaning with zero accessible text.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 1. How to use it
|
|
41
|
+
|
|
42
|
+
### Import
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { ScAccess } from "@streamoid/ui";
|
|
46
|
+
import "@streamoid/ui/dist/index.css"; // once, at your app root
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Minimal usage
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
// Always fill the slots — the defaults are Catalogix logos.
|
|
53
|
+
// Size your own icons: the chip does not resize what you pass in.
|
|
54
|
+
<ScAccess
|
|
55
|
+
component={<SiconArtifacts size={20} />}
|
|
56
|
+
component2={<SiconPhotogenix size={20} />}
|
|
57
|
+
component3={<SiconCatalogix size={20} />}
|
|
58
|
+
/>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Props
|
|
62
|
+
|
|
63
|
+
| Prop | Type | Default | Notes |
|
|
64
|
+
|---|---|---|---|
|
|
65
|
+
| `component` | `JSX.Element` | `<SiconCatalogix />` | ⚠️ Slot 1. Always rendered. |
|
|
66
|
+
| `component2` | `JSX.Element` | `<SiconCatalogix />` | ⚠️ Slot 2. Always rendered. |
|
|
67
|
+
| `component3` | `JSX.Element` | `<SiconCatalogix />` | ⚠️ Slot 3. Rendered only while `visibleSiconCatalogix` is true. |
|
|
68
|
+
| `visibleSiconCatalogix` | `boolean` | `true` | ⚠️ Misnamed — it is the **slot-3 visibility flag**, not a Catalogix-specific one. Set `false` for a two-icon chip. |
|
|
69
|
+
| `className` | `string` | – | Concatenated onto the root. |
|
|
70
|
+
|
|
71
|
+
That is the entire API. `IScAccessProps` does **not** extend `HTMLAttributes`, and
|
|
72
|
+
the component spreads nothing onto the root: no `onClick`, `style`, `title`, `id`,
|
|
73
|
+
`data-*`, `aria-*`, no `ref`.
|
|
74
|
+
|
|
75
|
+
### What renders
|
|
76
|
+
|
|
77
|
+
| Slots shown | Condition |
|
|
78
|
+
|---|---|
|
|
79
|
+
| 3 | default (`visibleSiconCatalogix` true) |
|
|
80
|
+
| 2 | `visibleSiconCatalogix={false}` |
|
|
81
|
+
| 1 or 0 | impossible — slots 1 and 2 always render (falling back to `SiconCatalogix`) |
|
|
82
|
+
|
|
83
|
+
Chrome: `--alias-fill-neutral-neutral` fill, `--radius-lg`, `0.5rem` padding,
|
|
84
|
+
`0.75rem` gap, **fixed `2.5rem` height**. The `1.25rem !important` size rules
|
|
85
|
+
(`.siconCatalogixInstance{,2,3}`) are applied **only to the fallback icons** — an
|
|
86
|
+
icon you pass via `component*` keeps whatever size you gave it (see Gotcha 6).
|
|
87
|
+
|
|
88
|
+
### Recipes
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
// The team-table pattern: two chips, apps then permissions
|
|
92
|
+
<div style={{ display: "flex", gap: 8 }}>
|
|
93
|
+
<ScAccess
|
|
94
|
+
component={<SiconArtifacts size={20} />}
|
|
95
|
+
component2={<SiconPhotogenix size={20} />}
|
|
96
|
+
component3={<SiconCatalogix size={20} />}
|
|
97
|
+
/>
|
|
98
|
+
<ScAccess
|
|
99
|
+
component={<SiconUserAdd size={20} />}
|
|
100
|
+
component2={<SiconCoins size={20} />}
|
|
101
|
+
visibleSiconCatalogix={false}
|
|
102
|
+
/>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
// Make it accessible + hoverable — wrap it, you can't pass props through
|
|
106
|
+
<div title="Access: Artifax, Photogenix" aria-label="Access: Artifax, Photogenix">
|
|
107
|
+
<ScAccess component={<SiconArtifacts size={20} />} component2={<SiconPhotogenix size={20} />}
|
|
108
|
+
visibleSiconCatalogix={false} />
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
// Fewer than 2 entitlements? Don't fake it with a blank element —
|
|
112
|
+
// render nothing, or a text badge instead.
|
|
113
|
+
{apps.length >= 2
|
|
114
|
+
? <ScAccess component={icon(apps[0])} component2={icon(apps[1])}
|
|
115
|
+
component3={apps[2] ? icon(apps[2]) : undefined}
|
|
116
|
+
visibleSiconCatalogix={!!apps[2]} />
|
|
117
|
+
: <ScBadges /* … */ />}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 2. Where to use it
|
|
123
|
+
|
|
124
|
+
- **`ScTableList`** (the CXO team/members table) renders **two** of these per row
|
|
125
|
+
inside its `accessInfo` region: an apps chip (`SiconArtifacts` +
|
|
126
|
+
`SiconPhotogenix` + the default Catalogix icon) and a permissions chip
|
|
127
|
+
(`SiconUserAdd` + `SiconCoins`, third slot hidden). This is its only render site.
|
|
128
|
+
- Any **dense table or list row** that needs an at-a-glance entitlement summary
|
|
129
|
+
beside `ScProfile` and `ScRole`.
|
|
130
|
+
|
|
131
|
+
If you are building the CXO members table, use `ScTableList` /
|
|
132
|
+
`ScTableListMobile` and let it place these — don't compose the row by hand.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 3. When to use it
|
|
137
|
+
|
|
138
|
+
### Use it when
|
|
139
|
+
|
|
140
|
+
- You need a **read-only** summary of 2–3 entitlements in a fixed-height row.
|
|
141
|
+
- The icons are self-evident brand/permission glyphs and the row already has a
|
|
142
|
+
header column explaining what the chip means.
|
|
143
|
+
|
|
144
|
+
### Don't use it — reach for this instead
|
|
145
|
+
|
|
146
|
+
| Situation | Use instead |
|
|
147
|
+
|---|---|
|
|
148
|
+
| The user must **toggle** app access (invite/manage flows) | `ScAppField` (+ `ScCatalogixInvite` / `ScPhtogenixInvite` / `ScArtifaxInvite`) |
|
|
149
|
+
| A role name ("Admin" / "Member") | `ScRole` / `ScRoleMobile` |
|
|
150
|
+
| A status or count chip **with text** | `ScBadges` |
|
|
151
|
+
| More than three icons | two `ScAccess` chips, or your own icon row |
|
|
152
|
+
| A clickable app entry point | `ScAppCard` / `ScAppCardV3` / `ScAppSwitchPanel` |
|
|
153
|
+
| The whole members-table row | `ScTableList` (it composes this) |
|
|
154
|
+
|
|
155
|
+
### Don't confuse with
|
|
156
|
+
|
|
157
|
+
| You may actually want | Not this |
|
|
158
|
+
|---|---|
|
|
159
|
+
| `ScAppField` — the editable app-permission block with toggles and store pickers | `ScAccess` is display-only, no callbacks at all |
|
|
160
|
+
| `ScAppSwitchPanel` — the app switcher you click to navigate | `ScAccess` is inert |
|
|
161
|
+
| `ScRole` — text label for a role | `ScAccess` has no text |
|
|
162
|
+
| `ScBadges` — labelled chip | Same chip shape family, but `ScBadges` carries words |
|
|
163
|
+
| `ScAppCard` / `ScAppListingCard` — full app cards | Different scale entirely |
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## 4. Why to use it
|
|
168
|
+
|
|
169
|
+
- **Row-height stability.** The chip is a fixed `2.5rem` tall, so table rows can't
|
|
170
|
+
jitter when one user has more entitlements than another. (Icon sizing is still on
|
|
171
|
+
you — the `1.25rem !important` rules cover only the fallback icons.)
|
|
172
|
+
- **Token-correct surface.** `--alias-fill-neutral-neutral` keeps the chip readable
|
|
173
|
+
against both the base surface and hovered row states, in both themes.
|
|
174
|
+
- **Consistent icon rhythm** — the `0.75rem` gap and `0.5rem` padding match `ScRole`
|
|
175
|
+
and `ScBadges`, so the three sit together cleanly in one row.
|
|
176
|
+
- **One place to change the entitlement summary shape**, which currently appears
|
|
177
|
+
twice per team-table row.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Gotchas
|
|
182
|
+
|
|
183
|
+
**1. Empty slots render a Catalogix logo.** All three slots default to
|
|
184
|
+
`<SiconCatalogix />`. There is no "empty" state.
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
// WRONG — slot 2 and 3 silently become Catalogix logos
|
|
188
|
+
<ScAccess component={<SiconArtifacts />} />
|
|
189
|
+
|
|
190
|
+
// RIGHT — fill what you show, hide what you don't
|
|
191
|
+
<ScAccess component={<SiconArtifacts />} component2={<SiconPhotogenix />}
|
|
192
|
+
visibleSiconCatalogix={false} />
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**2. `visibleSiconCatalogix` gates slot 3, not "the Catalogix icon".** Reading the
|
|
196
|
+
name literally will lead you to the wrong conclusion about what disappears.
|
|
197
|
+
|
|
198
|
+
**3. Only three slots, and slots 1–2 are unconditional.** You cannot render a
|
|
199
|
+
one-icon chip, and you cannot render four. `ScTableList` handles four by rendering two
|
|
200
|
+
chips.
|
|
201
|
+
|
|
202
|
+
**4. No passthrough props whatsoever.** No `onClick`, `style`, `title`, `aria-label`,
|
|
203
|
+
`data-testid`, `id`, `ref`. Wrap it in a div for tooltips, tests or hit areas.
|
|
204
|
+
|
|
205
|
+
**5. Zero accessible text.** Screen readers get three unlabelled SVGs. Whatever the
|
|
206
|
+
icons mean, put it on a wrapper (`aria-label` / `title`) or in a visible table header.
|
|
207
|
+
|
|
208
|
+
**6. Your icons are NOT sized for you.** The `width/height: 1.25rem !important`
|
|
209
|
+
rules live on `.siconCatalogixInstance{,2,3}`, and those classes are attached only to
|
|
210
|
+
the three **fallback** `<SiconCatalogix />` elements. An element you pass via
|
|
211
|
+
`component`/`component2`/`component3` is rendered verbatim — no `cloneElement`, no
|
|
212
|
+
injected class — so `<SiconArtifacts size={32} />` really is 32px and will blow out
|
|
213
|
+
the chip's `2.5rem` height. Size your own icons to `1.25rem` (that is what
|
|
214
|
+
`ScTableList` does, with its own local classes).
|
|
215
|
+
|
|
216
|
+
**7. `className` is string-concatenated**, so the DOM class list contains a literal
|
|
217
|
+
`undefined` when omitted — don't assert on the class string.
|
|
218
|
+
|
|
219
|
+
**8. Category note:** it ships in the `SC-Access` folder alongside the form controls
|
|
220
|
+
but it is a **profile/table display** part. Don't try to use it as an "access
|
|
221
|
+
control" input.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## In the wild
|
|
226
|
+
|
|
227
|
+
_No host render site found — used by the agent runtime / composed internally._
|
|
228
|
+
|
|
229
|
+
Composed internally by `ScTableList` — two chips per row:
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
// @streamoid/ui packages/ui/src/SC-tableList/ScTableList.tsx:45
|
|
233
|
+
<ScAccess
|
|
234
|
+
component={<SiconArtifacts className={styles.siconArtifactsInstance} />}
|
|
235
|
+
component2={<SiconPhotogenix className={styles.siconPhotogenixInstance} />}
|
|
236
|
+
className={styles.scAccessInstance}
|
|
237
|
+
/>
|
|
238
|
+
<ScAccess
|
|
239
|
+
component={<SiconUserAdd className={styles.siconUserAddInstance} />}
|
|
240
|
+
component2={<SiconCoins className={styles.siconCoinsInstance} />}
|
|
241
|
+
visibleSiconCatalogix={false}
|
|
242
|
+
className={styles.scAccessInstance}
|
|
243
|
+
/>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Note the first chip deliberately leaves `component3` unset so slot 3 falls back to
|
|
247
|
+
`SiconCatalogix` — the one place where that surprising default is actually intended.
|
|
248
|
+
If a host ever needs this outside a table, the natural home is a members/team row or
|
|
249
|
+
a workspace-member popup beside `ScProfile` and `ScRole`.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Related
|
|
254
|
+
|
|
255
|
+
- `ScTableList` / `ScTableListMobile` — the members table that renders these.
|
|
256
|
+
- `ScRole` / `ScRoleMobile` — the role label that sits beside it.
|
|
257
|
+
- `ScBadges` — chip with text when icons aren't enough.
|
|
258
|
+
- `ScAppField` — the editable counterpart for app permissions.
|
|
259
|
+
- `@streamoid/icons` — the `Sicon*` set; check `packages/icons/ICONS.md` for names.
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: ScAppCard
|
|
3
|
+
package: "@streamoid/ui"
|
|
4
|
+
category: cards
|
|
5
|
+
status: stable
|
|
6
|
+
renders: div
|
|
7
|
+
tags: [card, app, product, row, icon, name, subtitle, invite, appfield, compact]
|
|
8
|
+
related: [ScAppField, ScArtifaxInvite, ScCatalogixInvite, ScPhtogenixInvite, ScAppCardV3, ScAppListingCard]
|
|
9
|
+
do_not_confuse_with: [ScAppCardV3, ScAppListingCard, ScAppCardForCopilot, ScAppSwitchRow]
|
|
10
|
+
used_by: [cxo]
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# ScAppCard
|
|
14
|
+
|
|
15
|
+
**The compact icon + name + subtitle row for an app.** A 200px-wide horizontal
|
|
16
|
+
strip: rounded icon chip on the left, two lines of text on the right, both
|
|
17
|
+
single-line and ellipsised. It has no surface, no border and no hover — it is a
|
|
18
|
+
*label block* meant to be dropped into a bordered parent next to a control.
|
|
19
|
+
|
|
20
|
+
## TL;DR for agents
|
|
21
|
+
|
|
22
|
+
- **Reach for it when:** you need to identify an app inside a row that already has
|
|
23
|
+
its own container and its own control (a toggle, a checkbox, a chevron).
|
|
24
|
+
- **Don't reach for it when:** you want a clickable tile in a grid
|
|
25
|
+
(→ `ScAppListingCard` for a landing page, `ScAppCardV3` for the app switcher), or
|
|
26
|
+
a floating glassy card with a wordmark (→ `ScAppCardForCopilot`).
|
|
27
|
+
- **Three things that will bite you:**
|
|
28
|
+
1. **It has a hardcoded `width: 12.5rem` (200px)** and no way to override it
|
|
29
|
+
except your own `className`. It does not grow with its parent.
|
|
30
|
+
2. **All three content props default to Artifax copy** — `appName` defaults to
|
|
31
|
+
`"Artifax"` and `appDescription` to `"Info about artifax"`.
|
|
32
|
+
3. It draws **no card chrome at all**: no background, no border, no radius, no
|
|
33
|
+
hover. If you expected a "card", you want a different component.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 1. How to use it
|
|
38
|
+
|
|
39
|
+
### Import
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { ScAppCard } from "@streamoid/ui";
|
|
43
|
+
import "@streamoid/ui/dist/index.css"; // once, at your app root
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Minimal usage
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<ScAppCard
|
|
50
|
+
appIcon={<SiconArtifacts size={20} />}
|
|
51
|
+
appName="Artifax"
|
|
52
|
+
appDescription="Planning & buying"
|
|
53
|
+
/>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Props
|
|
57
|
+
|
|
58
|
+
| Prop | Type | Default | Notes |
|
|
59
|
+
|---|---|---|---|
|
|
60
|
+
| `appIcon` | `JSX.Element` | `<SiconArtifacts />` | ⚠️ Real default. Typed `JSX.Element`, not `ReactNode`. Sits in a `radius-xl` chip filled with `--alias-fill-neutral-neutralhover`; the chip has 8px padding and no fixed size, so the icon's own `size` sets it. The chip sets `color: --alias-text-and-icons-primary`, so a `currentColor` icon themes itself. |
|
|
61
|
+
| `appName` | `string` | `"Artifax"` | ⚠️ Real default. `text-sm-medium`, primary, **single line, ellipsised**. |
|
|
62
|
+
| `appDescription` | `string` | `"Info about artifax"` | ⚠️ Real default. `text-xs-regular`, tertiary, **single line, ellipsised**. |
|
|
63
|
+
| `className` | `string` | – | Appended after the internal class. The only way to beat the fixed width. |
|
|
64
|
+
| `...props` | `HTMLAttributes<HTMLDivElement>` | – | Spread onto the root div (`onClick`, `style`, `title`, `aria-*`, …). |
|
|
65
|
+
|
|
66
|
+
### Recipes
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
// The DS idiom — an identity block beside a control, inside your own row
|
|
70
|
+
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
|
|
71
|
+
<ScAppCard
|
|
72
|
+
appIcon={<SiconCatalog size={20} />}
|
|
73
|
+
appName="Catalogix"
|
|
74
|
+
appDescription="Catalog enrichment"
|
|
75
|
+
/>
|
|
76
|
+
<ScToggleSwitch checked={enabled} onToggle={setEnabled} />
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
// Escape the 200px width when the parent is fluid
|
|
80
|
+
<ScAppCard
|
|
81
|
+
appIcon={<SiconPhotogenix size={20} />}
|
|
82
|
+
appName={app.name}
|
|
83
|
+
appDescription={app.tagline}
|
|
84
|
+
style={{ width: "100%" }} // inline style wins over the module class
|
|
85
|
+
/>
|
|
86
|
+
|
|
87
|
+
// Long names need a tooltip — the text is clipped, not wrapped
|
|
88
|
+
<ScAppCard appName={app.name} appDescription={app.tagline} title={app.name} />
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 2. Where to use it
|
|
94
|
+
|
|
95
|
+
- **Inside the `Sc*Invite` trio.** `ScArtifaxInvite`, `ScCatalogixInvite` and
|
|
96
|
+
`ScPhtogenixInvite` each render one `ScAppCard` plus a `ScToggleSwitch` — the
|
|
97
|
+
"enable this product for the invitee" row.
|
|
98
|
+
- **Therefore inside `ScAppField`**, which stacks all three invite rows; that is how
|
|
99
|
+
it reaches CXO's mobile teams invite/manage popups.
|
|
100
|
+
- Any **settings row** where the left half must identify a product and the right
|
|
101
|
+
half carries the control.
|
|
102
|
+
|
|
103
|
+
It is the oldest member of the app-card family, but it is **not superseded by
|
|
104
|
+
`ScAppCardV3`** — they are different shapes (row vs tile) with different jobs.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## 3. When to use it
|
|
109
|
+
|
|
110
|
+
### Use it when
|
|
111
|
+
|
|
112
|
+
- The parent already owns the surface, border, spacing and interaction, and you
|
|
113
|
+
only need the icon+name+subtitle unit to look like everywhere else.
|
|
114
|
+
- The text is **short** — both lines are single-line ellipsised by design.
|
|
115
|
+
- 200px is the right width (or you are prepared to override it).
|
|
116
|
+
|
|
117
|
+
### Don't use it — reach for this instead
|
|
118
|
+
|
|
119
|
+
| Situation | Use instead |
|
|
120
|
+
|---|---|
|
|
121
|
+
| A large clickable product tile on a landing page | `ScAppListingCard` |
|
|
122
|
+
| A tile in the cross-product app switcher (gradient border, `active`) | `ScAppCardV3` |
|
|
123
|
+
| The whole "enable product X" row, toggle included | `ScArtifaxInvite` / `ScCatalogixInvite` / `ScPhtogenixInvite` — or `ScAppField` for all three |
|
|
124
|
+
| A dark glassy card carrying a product **wordmark** | `ScAppCardForCopilot` |
|
|
125
|
+
| A row in the app-switcher flyout | `ScAppSwitchPanel` (+ its item/row parts) |
|
|
126
|
+
| Just the product wordmark art | `ScAppcardLogos` / `ProductWordmark` |
|
|
127
|
+
| A generic option card with a centred title | `ScDefaultCard` |
|
|
128
|
+
|
|
129
|
+
### Don't confuse with
|
|
130
|
+
|
|
131
|
+
| You may actually want | Not this |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `ScAppCardV3` — a bordered, glowing, `active`-able tile; prop is `description` | `ScAppCard` has no chrome and uses `appDescription` |
|
|
134
|
+
| `ScAppListingCard` — landing-page tile; props are `title`/`descrp` | This is a 200px row with `appName`/`appDescription` |
|
|
135
|
+
| `ScAppSwitchRow` — a row in the app-switcher overlay | Different family, owns its own hover/active |
|
|
136
|
+
|
|
137
|
+
Prop-name cheat sheet for the family:
|
|
138
|
+
|
|
139
|
+
| Component | Title prop | Description prop | Icon prop |
|
|
140
|
+
|---|---|---|---|
|
|
141
|
+
| `ScAppCard` | `appName` | `appDescription` | `appIcon` |
|
|
142
|
+
| `ScAppCardV3` | `appName` | `description` | `appIcon` |
|
|
143
|
+
| `ScAppListingCard` | `title` | `descrp` | `icon` |
|
|
144
|
+
| `ScAppCardForCopilot` | *(none — `product`)* | `subText` | *(none)* |
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## 4. Why to use it
|
|
149
|
+
|
|
150
|
+
- **Consistent icon chip.** The 8px-padded `radius-xl` chip filled with
|
|
151
|
+
`--alias-fill-neutral-neutralhover` is the product's standard "app mark" frame;
|
|
152
|
+
hand-rolling it is how invite rows drifted out of alignment before.
|
|
153
|
+
- **Ellipsis behaviour is settled.** Both lines are `text-overflow: ellipsis` with
|
|
154
|
+
`white-space: nowrap`, so a long product name can never reflow the row and shove
|
|
155
|
+
the adjacent toggle out of place.
|
|
156
|
+
- **The chip sets `color`,** so any `currentColor` `Sicon*` you pass is themed
|
|
157
|
+
correctly without you naming a token.
|
|
158
|
+
- **Two type ramps already paired** (`text-sm-medium` over `text-xs-regular`,
|
|
159
|
+
primary over tertiary) — the same pairing used by every other identity row.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Gotchas
|
|
164
|
+
|
|
165
|
+
**1. Hardcoded `width: 12.5rem`.** The module CSS pins the root to 200px. In a
|
|
166
|
+
fluid row it will not grow, and in a narrow one it will not shrink (it is a flex
|
|
167
|
+
child with default `flex-shrink: 1`, so it *can* be squeezed, which then clips the
|
|
168
|
+
text earlier than you expect).
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
// WRONG — expecting the card to fill a fluid row
|
|
172
|
+
<div style={{ display: "flex" }}><ScAppCard appName="Catalogix" /></div>
|
|
173
|
+
|
|
174
|
+
// RIGHT
|
|
175
|
+
<ScAppCard appName="Catalogix" style={{ width: "100%" }} />
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**2. The defaults are Artifax copy.** Forget `appName`/`appDescription` and you
|
|
179
|
+
ship `"Artifax"` / `"Info about artifax"` — a real string that has shipped before.
|
|
180
|
+
|
|
181
|
+
```tsx
|
|
182
|
+
// WRONG — renders "Artifax" / "Info about artifax"
|
|
183
|
+
<ScAppCard appIcon={<SiconPhotogenix size={20} />} />
|
|
184
|
+
|
|
185
|
+
// RIGHT
|
|
186
|
+
<ScAppCard appIcon={<SiconPhotogenix size={20} />} appName="Photogenix" appDescription="Product imagery" />
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**3. It is not a card.** No background, no border, no radius, no shadow, no hover,
|
|
190
|
+
no `cursor`. If you place it on a page with nothing around it, it looks like loose
|
|
191
|
+
text. That is by design — the parent supplies the container.
|
|
192
|
+
|
|
193
|
+
**4. Both text lines are clipped, never wrapped.** There is no `title` attribute
|
|
194
|
+
wired internally, so the clipped text has no tooltip. Pass `title={appName}`
|
|
195
|
+
yourself if names can be long.
|
|
196
|
+
|
|
197
|
+
**5. `appIcon` is typed `JSX.Element`.** `ScAppCardV3.appIcon` is `ReactNode`;
|
|
198
|
+
these two are not interchangeable in TypeScript even though they look alike.
|
|
199
|
+
|
|
200
|
+
**6. `className` is concatenated unguarded** — the root is
|
|
201
|
+
`styles.scAppCard + " " + className`, so omitting `className` puts a literal
|
|
202
|
+
`undefined` class in the DOM. Harmless visually, noisy in snapshot tests.
|
|
203
|
+
|
|
204
|
+
**7. `appName`/`appDescription` render with a trailing space** (`{appName} ` in the
|
|
205
|
+
JSX). Exact-string assertions must allow for it.
|
|
206
|
+
|
|
207
|
+
**8. No interaction semantics.** If you attach `onClick`, add `role="button"`,
|
|
208
|
+
`tabIndex={0}` and a key handler — and remember there is no `cursor: pointer`
|
|
209
|
+
either, so you must supply that too.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## In the wild
|
|
214
|
+
|
|
215
|
+
_No host render site found — used by the agent runtime / composed internally._
|
|
216
|
+
|
|
217
|
+
It is composed inside the DS by all three invite rows, e.g.
|
|
218
|
+
`packages/ui/src/SC-artifaxInvite/ScArtifaxInvite.tsx:36`:
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
<ScAppCard
|
|
222
|
+
appIcon={appIcon || <SiconArtifacts className={styles.siconArtifactsInstance} />}
|
|
223
|
+
appName={appName}
|
|
224
|
+
appDescription={appDescription}
|
|
225
|
+
className={styles.scAppCardInstance}
|
|
226
|
+
/>
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Those invite rows are stacked by `ScAppField`, which CXO renders at
|
|
230
|
+
`cxo-dashboard src/app/components/mobile-teams-invite-popup.tsx:162` — so this is
|
|
231
|
+
the path by which `ScAppCard` actually reaches a screen. If you are building a new
|
|
232
|
+
"enable product X" row, reach for `ScAppField` or the invite trio rather than
|
|
233
|
+
composing `ScAppCard` yourself.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Related
|
|
238
|
+
|
|
239
|
+
- `ScAppField` — the settings field that stacks all three product invite rows.
|
|
240
|
+
- `ScArtifaxInvite` / `ScCatalogixInvite` / `ScPhtogenixInvite` — the rows that wrap
|
|
241
|
+
this card with a `ScToggleSwitch`.
|
|
242
|
+
- `ScAppCardV3` — the app-switcher tile; different shape, not a newer version of this.
|
|
243
|
+
- `ScAppListingCard` — the landing-page product tile.
|
|
244
|
+
- `ScToggleSwitch` — the control you almost always place beside this card.
|