@streamoid/ui 0.6.17 → 0.6.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/README.md +35 -18
  2. package/dist/docs/AGENTS.md +325 -0
  3. package/dist/docs/CreditWarningBanner.md +305 -0
  4. package/dist/docs/InvoiceHistoryMobile.md +222 -0
  5. package/dist/docs/ScAccess.md +259 -0
  6. package/dist/docs/ScAppCard.md +244 -0
  7. package/dist/docs/ScAppCardForCopilot.md +230 -0
  8. package/dist/docs/ScAppCardV3.md +273 -0
  9. package/dist/docs/ScAppField.md +308 -0
  10. package/dist/docs/ScAppListingCard.md +271 -0
  11. package/dist/docs/ScAppSwitchPanel.md +286 -0
  12. package/dist/docs/ScAppcardLogos.md +226 -0
  13. package/dist/docs/ScArtifaxInvite.md +262 -0
  14. package/dist/docs/ScArtifaxSidebar.md +330 -0
  15. package/dist/docs/ScAskAgentButton.md +307 -0
  16. package/dist/docs/ScBadges.md +261 -0
  17. package/dist/docs/ScBeacon.md +244 -0
  18. package/dist/docs/ScBillingHistoryHeader.md +210 -0
  19. package/dist/docs/ScBillingHistoryTableList.md +243 -0
  20. package/dist/docs/ScBillingLogsTableHeader.md +212 -0
  21. package/dist/docs/ScBillingLogsTableList.md +251 -0
  22. package/dist/docs/ScBriefCard.md +255 -0
  23. package/dist/docs/ScButton.md +251 -0
  24. package/dist/docs/ScCalendar.md +268 -0
  25. package/dist/docs/ScCalendarDateComps.md +264 -0
  26. package/dist/docs/ScCatalogixInvite.md +345 -0
  27. package/dist/docs/ScCatalogixSidebar.md +337 -0
  28. package/dist/docs/ScCatalogixStoreHeader.md +246 -0
  29. package/dist/docs/ScCatalogixStoreTableList.md +316 -0
  30. package/dist/docs/ScCheckField.md +233 -0
  31. package/dist/docs/ScCheckbox.md +272 -0
  32. package/dist/docs/ScCounter.md +235 -0
  33. package/dist/docs/ScCreditsUsageCard.md +247 -0
  34. package/dist/docs/ScCreditsUsageCardMobile.md +224 -0
  35. package/dist/docs/ScDefaultCard.md +269 -0
  36. package/dist/docs/ScDp.md +245 -0
  37. package/dist/docs/ScDrawer.md +318 -0
  38. package/dist/docs/ScFieldButton.md +255 -0
  39. package/dist/docs/ScFileField.md +268 -0
  40. package/dist/docs/ScGoogleSignIn.md +250 -0
  41. package/dist/docs/ScGuide.md +278 -0
  42. package/dist/docs/ScHDivider.md +210 -0
  43. package/dist/docs/ScHeader.md +222 -0
  44. package/dist/docs/ScImageField.md +253 -0
  45. package/dist/docs/ScInChatList.md +277 -0
  46. package/dist/docs/ScInChatMessage.md +205 -0
  47. package/dist/docs/ScInfoPopup.md +248 -0
  48. package/dist/docs/ScIntialProfileCover.md +233 -0
  49. package/dist/docs/ScInvoiceHistoryMobile.md +187 -0
  50. package/dist/docs/ScLogoUnit.md +232 -0
  51. package/dist/docs/ScMappingCard.md +241 -0
  52. package/dist/docs/ScMediaApproval.md +301 -0
  53. package/dist/docs/ScMediaSelect.md +310 -0
  54. package/dist/docs/ScMenuOptions.md +308 -0
  55. package/dist/docs/ScMobileBottomAction.md +252 -0
  56. package/dist/docs/ScMobileTopNav.md +279 -0
  57. package/dist/docs/ScModal.md +291 -0
  58. package/dist/docs/ScOnlyField.md +302 -0
  59. package/dist/docs/ScOnlyIcon.md +213 -0
  60. package/dist/docs/ScPagination.md +284 -0
  61. package/dist/docs/ScPairtext.md +287 -0
  62. package/dist/docs/ScPendingAction.md +238 -0
  63. package/dist/docs/ScPhtogenixInvite.md +275 -0
  64. package/dist/docs/ScPlanCard.md +302 -0
  65. package/dist/docs/ScPlanComparison.md +264 -0
  66. package/dist/docs/ScPlanDetailsCard.md +246 -0
  67. package/dist/docs/ScPlanDetailsCardMobile.md +240 -0
  68. package/dist/docs/ScPopUpMenu.md +224 -0
  69. package/dist/docs/ScProfile.md +234 -0
  70. package/dist/docs/ScProfileImageUpdate.md +261 -0
  71. package/dist/docs/ScProfileOptions.md +245 -0
  72. package/dist/docs/ScProfilePopup.md +396 -0
  73. package/dist/docs/ScProfileSettingsComp.md +250 -0
  74. package/dist/docs/ScProfileV2Mobile.md +216 -0
  75. package/dist/docs/ScProgressBar.md +267 -0
  76. package/dist/docs/ScQuickPrompt.md +277 -0
  77. package/dist/docs/ScRadio.md +228 -0
  78. package/dist/docs/ScReferralCardMobile.md +226 -0
  79. package/dist/docs/ScReferralTableHeader.md +260 -0
  80. package/dist/docs/ScReferralTableList.md +293 -0
  81. package/dist/docs/ScRole.md +226 -0
  82. package/dist/docs/ScRoleMobile.md +199 -0
  83. package/dist/docs/ScSelect.md +270 -0
  84. package/dist/docs/ScSelection.md +256 -0
  85. package/dist/docs/ScSelectionList.md +272 -0
  86. package/dist/docs/ScSelectionPill.md +240 -0
  87. package/dist/docs/ScSelectionPillGroup.md +302 -0
  88. package/dist/docs/ScSettingsNav.md +212 -0
  89. package/dist/docs/ScSettingsTabComp.md +260 -0
  90. package/dist/docs/ScSideBarLogoUnit.md +340 -0
  91. package/dist/docs/ScSidebar.md +243 -0
  92. package/dist/docs/ScSidebarIcons.md +232 -0
  93. package/dist/docs/ScSidebarMenu.md +283 -0
  94. package/dist/docs/ScSidebarProfile.md +231 -0
  95. package/dist/docs/ScSidebarSwitchMenu.md +258 -0
  96. package/dist/docs/ScSlider.md +194 -0
  97. package/dist/docs/ScStoreCard.md +252 -0
  98. package/dist/docs/ScStrLogo.md +253 -0
  99. package/dist/docs/ScStreamoidWordmark.md +302 -0
  100. package/dist/docs/ScSubAgent.md +226 -0
  101. package/dist/docs/ScTabComp.md +308 -0
  102. package/dist/docs/ScTabField.md +258 -0
  103. package/dist/docs/ScTabSwitcher.md +307 -0
  104. package/dist/docs/ScTableHeader.md +261 -0
  105. package/dist/docs/ScTableList.md +301 -0
  106. package/dist/docs/ScTableListMobile.md +282 -0
  107. package/dist/docs/ScTabs.md +268 -0
  108. package/dist/docs/ScTaxonomyPill.md +263 -0
  109. package/dist/docs/ScTextArea.md +259 -0
  110. package/dist/docs/ScTextField.md +324 -0
  111. package/dist/docs/ScThinkingStepIcon.md +249 -0
  112. package/dist/docs/ScTodoList.md +288 -0
  113. package/dist/docs/ScToggleSwitch.md +229 -0
  114. package/dist/docs/ScUsageHistoryMobile.md +194 -0
  115. package/dist/docs/ScVDivider.md +215 -0
  116. package/dist/docs/ScValueMappingL1.md +256 -0
  117. package/dist/docs/ScVersion.md +251 -0
  118. package/dist/docs/ScWorkspace.md +233 -0
  119. package/dist/docs/ScWorkspaceAccountMenu.md +115 -0
  120. package/dist/docs/ScWorkspaceCard.md +234 -0
  121. package/dist/docs/ScWorkspaceSettingsMobile.md +265 -0
  122. package/dist/docs/ScWorkspaceSwitchCard.md +312 -0
  123. package/dist/docs/ScWorkspaceSwitchMobile.md +241 -0
  124. package/dist/docs/ScWorkspaceSwitchMobileV2.md +278 -0
  125. package/dist/docs/StreamoidSidebar.md +413 -0
  126. package/dist/docs/StreamoidWorkspaceSwitcher.md +307 -0
  127. package/dist/docs/UsageHistoryMobile.md +235 -0
  128. package/dist/docs/components.json +4931 -0
  129. package/dist/index.css +361 -36
  130. package/dist/index.d.mts +213 -88
  131. package/dist/index.d.ts +213 -88
  132. package/dist/index.js +2486 -1629
  133. package/dist/index.mjs +2487 -1620
  134. package/package.json +5 -3
@@ -0,0 +1,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.