@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,256 @@
1
+ ---
2
+ component: ScValueMappingL1
3
+ package: "@streamoid/ui"
4
+ category: feed-taxonomy
5
+ status: stable
6
+ renders: div
7
+ tags: [value-mapping, curation, attribute-value, list-row, selectable-row, updated-dot, catalogix, map-values]
8
+ related: [ScMappingCard, ScSelectionPillGroup, ScTaxonomyPill, ScDefaultCard]
9
+ do_not_confuse_with: [ScMappingCard, ScSelectionPill, ScDefaultCard, ScTableList]
10
+ used_by: [catalogix]
11
+ ---
12
+
13
+ # ScValueMappingL1
14
+
15
+ **One selectable row in a value-mapping / curation list.** A full-width rounded box
16
+ containing a single truncating label, three visual states (`default` / `hover` /
17
+ `active`), and an optional blue "this value was edited" dot on the right.
18
+
19
+ ## TL;DR for agents
20
+
21
+ - **Reach for it when:** you need a vertical list of *values* (attribute values,
22
+ categories, enum members) where exactly one is the current selection and some
23
+ carry an "updated" marker.
24
+ - **Don't reach for it when:** you're mapping *columns* to attributes with a
25
+ confirm/ignore lifecycle (→ `ScMappingCard`), you want a horizontal segmented
26
+ switch (→ `ScSelectionPillGroup`), or you need a multi-column data row
27
+ (→ `ScTableList` / `ScCatalogixStoreTableList`).
28
+ - **Three things that will bite you:**
29
+ 1. `label` defaults to **`"Title"`** — forget it and every row says "Title".
30
+ 2. It's a plain `<div>`. `onClick` works because it's spread, but there is **no
31
+ `role`, no `tabIndex`, no keyboard handler**. You add those.
32
+ 3. `state` is a *skin*, not selection state. Nothing is tracked; you compute
33
+ `"active"` yourself.
34
+
35
+ ---
36
+
37
+ ## 1. How to use it
38
+
39
+ ### Import
40
+
41
+ ```tsx
42
+ import { ScValueMappingL1 } from "@streamoid/ui";
43
+ import "@streamoid/ui/dist/index.css"; // once, at your app root
44
+ ```
45
+
46
+ ### Minimal usage
47
+
48
+ ```tsx
49
+ <ScValueMappingL1 label="Red" onClick={() => setSelected("Red")} />
50
+ ```
51
+
52
+ ### Props
53
+
54
+ | Prop | Type | Default | Notes |
55
+ |---|---|---|---|
56
+ | `label` | `string` | `"Title"` | ⚠️ Has a real default. The whole content of the row. Truncates with ellipsis and gets a native `title` tooltip with the same text. |
57
+ | `state` | `"default"` \| `"hover"` \| `"active"` | `"default"` | Forced visual state. `"active"` = "this is the currently selected row". Real `:hover` also applies the hover skin. |
58
+ | `updated` | `boolean` | `false` | Renders the trailing blue dot **and** adds `padding-right: 0.5rem` to the row. The dot is `aria-hidden`. |
59
+ | `className` | `string` | – | Appended after the internal classes, so it wins on equal specificity. |
60
+ | `...props` | `HTMLAttributes<HTMLDivElement>` | – | `onClick`, `role`, `tabIndex`, `onKeyDown`, `style`, `data-*` all land on the root div. |
61
+
62
+ ### What renders in each state
63
+
64
+ | `state` | Background token | Border token |
65
+ |---|---|---|
66
+ | `default` | `--alias-surface-base` | `--alias-border-subtle` |
67
+ | `hover` (or real `:hover`) | `--alias-surface-basesubtle` | `--alias-border-default` |
68
+ | `active` | `--alias-surface-raisedoverlay` | `--alias-border-default` |
69
+
70
+ `active` wins over real `:hover` (its rule is last), so hovering the selected row
71
+ does not flicker back to the hover skin.
72
+
73
+ ### Recipes
74
+
75
+ ```tsx
76
+ // The standard list: one active row, some rows flagged as edited
77
+ <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
78
+ {attributeValues.map((attr) => (
79
+ <ScValueMappingL1
80
+ key={attr}
81
+ label={attr}
82
+ state={attr === selectedValue ? "active" : "default"}
83
+ updated={isEdited(attr)}
84
+ onClick={() => setSelectedValue(attr)}
85
+ />
86
+ ))}
87
+ </div>
88
+
89
+ // Make it actually keyboard-operable (the DS does not do this for you)
90
+ <ScValueMappingL1
91
+ label={attr}
92
+ state={attr === selectedValue ? "active" : "default"}
93
+ role="option"
94
+ aria-selected={attr === selectedValue}
95
+ tabIndex={0}
96
+ onClick={() => setSelectedValue(attr)}
97
+ onKeyDown={(e) => {
98
+ if (e.key === "Enter" || e.key === " ") {
99
+ e.preventDefault();
100
+ setSelectedValue(attr);
101
+ }
102
+ }}
103
+ />
104
+
105
+ // Give the "updated" dot a meaning screen readers can reach
106
+ <ScValueMappingL1 label={attr} updated aria-label={`${attr} (edited)`} />
107
+ ```
108
+
109
+ ---
110
+
111
+ ## 2. Where to use it
112
+
113
+ - **Catalogix Curation V2 → the attribute-values column.** The left panel lists every
114
+ value of the selected attribute; clicking one loads its curation rules in the right
115
+ panel. This is the component's only production surface today.
116
+ - Any **master/detail list of values** on the feed side: map-values screens,
117
+ synonym lists, enum pickers — a narrow scrolling column of single-line rows next to
118
+ a detail pane.
119
+ - It composes *nothing*. It expects to be stacked directly inside a scrolling flex
120
+ column that supplies the gap.
121
+
122
+ ---
123
+
124
+ ## 3. When to use it
125
+
126
+ ### Use it when
127
+
128
+ - The list items are **single strings** with no secondary line, no icon, no counts.
129
+ - Exactly **one** row is "current", and the selection drives a neighbouring panel.
130
+ - Some rows need a **subtle "changed since last save" marker** that doesn't steal
131
+ attention (the blue info dot).
132
+
133
+ ### Don't use it — reach for this instead
134
+
135
+ | Situation | Use instead |
136
+ |---|---|
137
+ | Mapping a feed **column** to target attributes, with Ignore/Confirm/Edit | `ScMappingCard` |
138
+ | Horizontal segmented switch between 2–5 views | `ScSelectionPillGroup` |
139
+ | A node in a taxonomy tree, with child counts and expand/collapse | `ScTaxonomyPill` |
140
+ | Title + description "pick one of these options" card | `ScDefaultCard` |
141
+ | A row with several aligned columns | `ScTableList`, or `ScCatalogixStoreHeader` + `ScCatalogixStoreTableList` |
142
+ | Multi-select over the list | `ScCheckField` / `ScCheckbox` rows — this row has no checkbox and no multi-select affordance |
143
+ | A real form control whose value gets saved | `ScRadio` / `ScTabField` |
144
+
145
+ ### Don't confuse with
146
+
147
+ | You may actually want | Not this |
148
+ |---|---|
149
+ | `ScMappingCard` — column-level card with a `default`/`confirmed`/`ignored` lifecycle, a `targets` slot and an action footer | `ScValueMappingL1` is a single value row with a forced skin and nothing else |
150
+ | `ScSelectionPill` — a *horizontal* pill in a segmented row, real `<button>`, `aria-pressed` | This is a *vertical* full-width row, a `<div>`, no aria |
151
+ | `ScDefaultCard` — generic option card (`title` + optional `description`) | No description line here, and it has an `active` state that `ScDefaultCard` lacks |
152
+
153
+ Both `ScValueMappingL1` and `ScDefaultCard` take a `state` prop with a `"hover"`
154
+ member; only `ScValueMappingL1` has `"active"`. If you need a persistent
155
+ "selected" look, that's the deciding factor.
156
+
157
+ ---
158
+
159
+ ## 4. Why to use it
160
+
161
+ - **The three-state token ladder is already correct.** `surface-base` →
162
+ `surface-basesubtle` → `surface-raisedoverlay` stay visually distinct in both
163
+ themes. Hand-rolled selection rows almost always reach for a hard-coded grey that
164
+ collapses to white in light mode and loses the "selected" read entirely.
165
+ - **Truncation with a tooltip, for free.** Long attribute values ellipsise and get a
166
+ `title` fallback, so a 200-character value can't blow out the column width.
167
+ - **The "updated" dot is a token, not a colour.** It uses
168
+ `--alias-text-and-icons-infocont`, matching every other "changed / info" marker
169
+ in the product.
170
+ - **One row height everywhere.** `0.75rem` padding on a `text-sm` line, so the
171
+ Curation list and any future value list line up without per-screen CSS.
172
+
173
+ ---
174
+
175
+ ## Gotchas
176
+
177
+ **1. `label` defaults to `"Title"`.** There is no required prop, so a typo'd prop
178
+ name renders a list of "Title".
179
+
180
+ ```tsx
181
+ // WRONG — renders "Title" (typo'd prop is silently ignored)
182
+ <ScValueMappingL1 lable={attr} />
183
+
184
+ // RIGHT
185
+ <ScValueMappingL1 label={attr} />
186
+ ```
187
+
188
+ **2. No button semantics.** The root is a `<div>` with `cursor: pointer` and nothing
189
+ else — no `role`, no `tabIndex`, no `onKeyDown`, no `aria-selected`. A mouse user
190
+ sees an affordance a keyboard user cannot reach. Pass them yourself (see Recipes).
191
+
192
+ **3. `state` does not track anything.** It is a forced skin. There is no `selected`
193
+ prop and no internal state; if you never compute `"active"`, nothing ever looks
194
+ selected.
195
+
196
+ ```tsx
197
+ // WRONG — nothing looks selected, ever
198
+ {values.map((v) => <ScValueMappingL1 key={v} label={v} onClick={() => pick(v)} />)}
199
+
200
+ // RIGHT
201
+ {values.map((v) => (
202
+ <ScValueMappingL1 key={v} label={v} state={v === picked ? "active" : "default"} onClick={() => pick(v)} />
203
+ ))}
204
+ ```
205
+
206
+ **4. `state="hover"` is for design parity, not interaction.** Real `:hover` already
207
+ works. Wiring `onMouseEnter` to flip `state` just fights the CSS.
208
+
209
+ **5. The row supplies no vertical gap.** No margin, no `:not(:last-child)` rule.
210
+ Stacked rows touch unless the parent sets `gap` (Catalogix uses `12px`).
211
+
212
+ **6. It has `width: 100%` but no `flex-shrink: 0`.** Inside a **height-capped** flex
213
+ column the rows compress toward zero height and the list looks empty. Put them in a
214
+ scrolling wrapper instead of a fixed-height column:
215
+
216
+ ```css
217
+ /* RIGHT — the host pattern */
218
+ .list-scroll { overflow-y: auto; }
219
+ .list { display: flex; flex-direction: column; gap: 12px; }
220
+ ```
221
+
222
+ **7. The `updated` dot carries no accessible name.** It's `aria-hidden` decoration
223
+ occupying `1.5rem`. If "edited" is information the user needs, put it in
224
+ `aria-label` or a visible legend.
225
+
226
+ **8. `updated` changes the row's inner metrics.** It adds `padding-right: 0.5rem`
227
+ plus a `1.5rem` dot slot, so an updated row has a narrower label area than its
228
+ neighbours. Expected, but it means truncation points differ down the list.
229
+
230
+ ---
231
+
232
+ ## In the wild
233
+
234
+ ```jsx
235
+ // catalogix/dashboard app/containers/StoreSettingsV2/CurationV2/index.jsx:394
236
+ <ScValueMappingL1
237
+ key={idx}
238
+ label={attr}
239
+ state={attr === selectedAttribute ? "active" : "default"}
240
+ updated={isAttrUpdated(attr)}
241
+ onClick={() => setSelectedAttribute(attr)}
242
+ />
243
+ ```
244
+
245
+ Rendered inside `.smp-values { overflow-y: auto }` → `.block { display: flex;
246
+ flex-direction: column; gap: 12px }` — i.e. the host supplies both the scroll
247
+ container and the gap (see Gotchas 5 and 6).
248
+
249
+ ---
250
+
251
+ ## Related
252
+
253
+ - `ScMappingCard` — the column-level sibling on the feed Map-Attributes screen; has the confirm/ignore state machine this row deliberately lacks.
254
+ - `ScSelectionPillGroup` — the horizontal segmented switch that usually sits *above* a `ScValueMappingL1` list (Curation V2 has both).
255
+ - `ScTaxonomyPill` — hierarchy node chip for tree layouts rather than flat lists.
256
+ - `ScDefaultCard` — reach for it when the row needs a description line and no `active` state.
@@ -0,0 +1,251 @@
1
+ ---
2
+ component: ScVersion
3
+ package: "@streamoid/ui"
4
+ category: sidebar
5
+ status: legacy
6
+ renders: div
7
+ tags: [sidebar, version, footer, version-stamp, collapse-toggle, legacy, build-number]
8
+ related: [StreamoidSidebar, ScSidebarIcons, ScSidebar, ScMenuOptions]
9
+ do_not_confuse_with: [StreamoidSidebar, ScSidebarIcons, ScMenuOptions, ScBadges]
10
+ ---
11
+
12
+ # ScVersion
13
+
14
+ **Legacy. Superseded by `StreamoidSidebar`'s `versionText` prop.** The old rail's bottom
15
+ footer: a version string plus a collapse chevron. The chevron is **decorative** (it goes
16
+ through `ScSidebarIcons`, which drops all props), and the version defaults to the
17
+ hardcoded string `"v2.1.2"`.
18
+
19
+ ## TL;DR for agents
20
+
21
+ - **Reach for it when:** never. `StreamoidSidebar` renders its own version footer
22
+ inline from `versionText`.
23
+ - **Reach for this instead:** `StreamoidSidebar` with `versionText="v2.1.2"` — or
24
+ `toggleInProfile` if you want the collapse control beside the profile row and no
25
+ version footer at all.
26
+ - **Four things that will bite you:**
27
+ 1. ⚠️ `version` defaults to `"v2.1.2"`. Forget it and you ship a stale build number.
28
+ 2. `component` and `scSidebarIconsinstance` are **only read in the `collapsed`
29
+ branch**. In `expanded` the component builds its own `SiconCollapse` and ignores
30
+ both props.
31
+ 3. The chevron in `expanded` is hardcoded to `state="hover"` — permanently
32
+ hover-skinned.
33
+ 4. Nothing inside is clickable. Wire `onClick` on the root (that prop *is* spread) and
34
+ accept that the whole footer becomes the hit area.
35
+
36
+ ---
37
+
38
+ ## 1. How to use it
39
+
40
+ ### Import
41
+
42
+ ```tsx
43
+ import { ScVersion } from "@streamoid/ui";
44
+ import { SiconCollapse } from "@streamoid/icons";
45
+ import "@streamoid/ui/dist/index.css"; // once, at your app root
46
+ ```
47
+
48
+ ### Minimal usage
49
+
50
+ ```tsx
51
+ <ScVersion state="expanded" version={`v${appVersion}`} onClick={toggleSidebar} />
52
+ ```
53
+
54
+ ### Props
55
+
56
+ | Prop | Type | Default | Notes |
57
+ |---|---|---|---|
58
+ | `version` | `string` | `"v2.1.2"` | ⚠️ Has a real default — a specific stale version string. Rendered with a **trailing space** (`{version}&nbsp;`). Single line, ellipsised. |
59
+ | `state` | `"expanded"` \| `"collapsed"` | `"expanded"` | Changes both the layout direction and which icon branch runs. See the table below. |
60
+ | `scSidebarIconsinstance` | `JSX.Element` | – | ⚠️ Note the lower-case `i` in `…instance`. The icon handed to the internal `ScSidebarIcons`. **`collapsed` only** — falls back to `<SiconCollapse />`. |
61
+ | `component` | `JSX.Element` | – | Replaces the whole icon slot (wins over `scSidebarIconsinstance`). **`collapsed` only.** |
62
+ | `className` | `string` | – | Concatenated onto the root. ⚠️ Unguarded — omitting it puts a literal `undefined` in the class list. |
63
+ | `...props` | `HTMLAttributes<HTMLDivElement>` | – | **Is** spread onto the root, so `onClick`, `style`, `aria-*`, `data-*` work — on the whole row, not on the chevron. |
64
+
65
+ ### What renders in each state
66
+
67
+ | | `expanded` | `collapsed` |
68
+ |---|---|---|
69
+ | Direction | `row`, 4 px gap, padding `4px 4px 4px 16px` | `column`, 12 px gap, padding `16px 8px`, fixed `width: 3.5rem` |
70
+ | Order | `version` (flex: 1) → chevron | chevron → `version` |
71
+ | Icon source | **hardcoded** `<SiconCollapse />` inside `ScSidebarIcons state="hover"`. `component` and `scSidebarIconsinstance` are **ignored**. | `component` ?? `ScSidebarIcons instance={scSidebarIconsinstance ?? <SiconCollapse />}` |
72
+ | Type ramp | `text-sm-regular`, left-aligned | `text-xs-regular`, centred |
73
+ | Colour | `--alias-text-and-icons-muted` | same |
74
+
75
+ ### Recipes
76
+
77
+ ```tsx
78
+ // Collapsed footer with your own icon (the only state where the icon props work)
79
+ <ScVersion
80
+ state="collapsed"
81
+ version={`v${appVersion}`}
82
+ scSidebarIconsinstance={<SiconCollapse size={20} />}
83
+ onClick={toggleSidebar}
84
+ />
85
+
86
+ // Collapsed footer, replacing the entire icon slot
87
+ <ScVersion
88
+ state="collapsed"
89
+ version={`v${appVersion}`}
90
+ component={<MyOwnToggleButton onClick={toggleSidebar} />}
91
+ />
92
+ ```
93
+
94
+ The replacement, which is what you should actually write:
95
+
96
+ ```tsx
97
+ // Version footer + a working collapse toggle, rendered by the shell
98
+ <StreamoidSidebar
99
+ expanded={expanded}
100
+ onToggle={() => setExpanded((v) => !v)}
101
+ config={config}
102
+ iconMap={iconMap}
103
+ versionText={`v${appVersion}`} // default is "v1.0.0"
104
+ toggleIcon={(isExpanded) => <SiconCollapse size={20} />}
105
+ />
106
+
107
+ // Or: no version footer at all — profile row + a separate collapse button beside it
108
+ <StreamoidSidebar … versionText={undefined} toggleInProfile />
109
+ ```
110
+
111
+ ---
112
+
113
+ ## 2. Where to use it
114
+
115
+ Nowhere. Its only render site is the legacy `ScSidebar`
116
+ (`src/SC-Sidebar/ScSidebar.tsx:140` collapsed, `:248` expanded), which is itself unused.
117
+
118
+ `StreamoidSidebar` renders the version footer **inline** — it does not compose
119
+ `ScVersion` — from `versionText` (default `"v1.0.0"`), and owns the collapse toggle via
120
+ `onToggle` / `toggleIcon` / `toggleInProfile`.
121
+
122
+ ---
123
+
124
+ ## 3. When to use it
125
+
126
+ ### Use it when
127
+
128
+ - Never.
129
+
130
+ ### Don't use it — reach for this instead
131
+
132
+ | Situation | Use instead |
133
+ |---|---|
134
+ | A version stamp in a real sidebar footer | `StreamoidSidebar`'s `versionText` |
135
+ | A working collapse/expand control | `StreamoidSidebar`'s `onToggle` + `toggleIcon`, or `toggleInProfile` |
136
+ | A version line inside a profile/settings popup menu row | `ScMenuOptions` (`variant="with-v"`, `version` prop) |
137
+ | A version pill/chip somewhere in the UI | `ScBadges` (`text`, `variant`, `styleVariant`) |
138
+ | Any clickable icon | `ScButton styleVariant="icon-only"` |
139
+
140
+ ### Don't confuse with
141
+
142
+ | You may actually want | Not this |
143
+ |---|---|
144
+ | `StreamoidSidebar`'s `versionText` — the current, working footer | `ScVersion` is the standalone legacy footer |
145
+ | `ScMenuOptions` with `variant="with-v"` — a **popup menu row** that also shows a version | not a sidebar footer |
146
+ | `ScBadges` — a small status/count chip | `ScVersion` is a full-width footer row |
147
+ | `ScSidebarIcons` — the inert icon box this component wraps | also legacy |
148
+
149
+ ---
150
+
151
+ ## 4. Why to use it
152
+
153
+ You wouldn't. What it still encodes correctly:
154
+
155
+ - The version stamp is `--alias-text-and-icons-muted` — the dimmest text token, so a
156
+ build number never competes with nav labels.
157
+ - Expanded uses `text-sm` left-aligned with the chevron pushed right by `flex: 1`;
158
+ collapsed drops to `text-xs`, centres, and stacks the chevron above the string. Both
159
+ are the correct Figma treatments.
160
+ - `text-overflow: ellipsis` on the version, so a long build hash truncates rather than
161
+ widening the rail.
162
+
163
+ What you lose: a working toggle, and any way to change the icon in the expanded state.
164
+
165
+ ---
166
+
167
+ ## Gotchas
168
+
169
+ **1. `version` defaults to `"v2.1.2"`.** Not a placeholder like "Version" — an actual
170
+ version number that will look plausible and be wrong.
171
+
172
+ ```tsx
173
+ // WRONG — ships "v2.1.2"
174
+ <ScVersion state="expanded" />
175
+
176
+ // RIGHT
177
+ <ScVersion state="expanded" version={`v${appVersion}`} />
178
+ ```
179
+
180
+ **2. `component` and `scSidebarIconsinstance` are ignored when expanded.** The expanded
181
+ branch constructs its own `<ScSidebarIcons instance={<SiconCollapse />} state="hover" />`
182
+ and never consults either prop. The legacy `ScSidebar` passes both anyway — don't take
183
+ that call site as an example.
184
+
185
+ ```tsx
186
+ // WRONG — your icon never appears
187
+ <ScVersion state="expanded" scSidebarIconsinstance={<SiconUp />} />
188
+
189
+ // RIGHT — the icon props only work collapsed
190
+ <ScVersion state="collapsed" scSidebarIconsinstance={<SiconUp />} />
191
+ ```
192
+
193
+ **3. The chevron is not a button.** It renders through `ScSidebarIcons`, which
194
+ destructures `...props` and never spreads it, so there is no way to attach a handler to
195
+ the icon. `ScVersion`'s own `...props` *is* spread on the root, so an `onClick` there
196
+ makes the **whole footer row** the hit area — including the version text.
197
+
198
+ **4. `state="hover"` is baked into the expanded chevron.** It permanently renders the
199
+ hover background. There is no prop to turn it off.
200
+
201
+ **5. The prop name is `scSidebarIconsinstance`.** Lower-case `i` on `instance`, mixed
202
+ into a camel-cased component name. It's a Figma-export artifact and an easy typo — and
203
+ a typo is silent, because every prop is optional.
204
+
205
+ **6. Fixed `width: 3.5rem` when collapsed.** 56 px, wider than the 40 px collapsed nav
206
+ squares and the 48 px collapsed profile box, so the footer sets the rail's minimum
207
+ width.
208
+
209
+ **7. `version` renders with a trailing space.** The JSX is `{version} ` — visible in DOM
210
+ snapshots and in text assertions.
211
+
212
+ **8. `className` produces a literal `undefined` class when omitted.**
213
+ `styles.scVersion + " " + className + " " + variantsClassName`.
214
+
215
+ **9. No `role`, `tabIndex` or keyboard handling.** If you make the row clickable via
216
+ `onClick`, supply those yourself through `...props`.
217
+
218
+ ---
219
+
220
+ ## In the wild
221
+
222
+ _No host render site found — used by the agent runtime / composed internally._
223
+
224
+ Composed only inside the legacy sidebar:
225
+
226
+ ```tsx
227
+ // npm-components packages/ui/src/SC-Sidebar/ScSidebar.tsx:140
228
+ <ScVersion
229
+ state="collapsed"
230
+ scSidebarIconsinstance={
231
+ <SiconCollapse className={styles.siconCollapseInstance} />
232
+ }
233
+ className={styles.scVersionInstance}
234
+ />
235
+ ```
236
+
237
+ Where it *would* belong — the rail's bottom footer — is now rendered inline by
238
+ `StreamoidSidebar` from `versionText`
239
+ (`packages/ui/src/SC-Sidebar-new/streamoid-sidebar.tsx:787`), which every host drives
240
+ (e.g. `cxo-dashboard src/app/components/app-sidebar.tsx`).
241
+
242
+ ---
243
+
244
+ ## Related
245
+
246
+ - `StreamoidSidebar` — **the replacement.** `versionText` for the stamp, `onToggle` /
247
+ `toggleIcon` / `toggleInProfile` for the collapse control.
248
+ - `ScSidebarIcons` — the inert icon box this composes; also legacy.
249
+ - `ScMenuOptions` — popup menu row with a `version` slot (`variant="with-v"`).
250
+ - `ScSidebar` / `ScLogoUnit` / `ScSidebarProfile` — the rest of this legacy sidebar
251
+ family.