@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,232 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: ScLogoUnit
|
|
3
|
+
package: "@streamoid/ui"
|
|
4
|
+
category: sidebar
|
|
5
|
+
status: legacy
|
|
6
|
+
renders: div
|
|
7
|
+
tags: [sidebar, logo, wordmark, header, brand, streamoid, legacy, logo-unit]
|
|
8
|
+
related: [ScSideBarLogoUnit, ScStrLogo, ScStreamoidWordmark, ScStreamoidMascot, StreamoidSidebar]
|
|
9
|
+
do_not_confuse_with: [ScSideBarLogoUnit, ScStrLogo, ScStreamoidWordmark, ScStreamoidMascot, ScCxoCopilotLogo, ScAppcardLogos]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# ScLogoUnit
|
|
13
|
+
|
|
14
|
+
**Legacy. Superseded by `ScSideBarLogoUnit`.** A fixed-width 240 px padded box holding
|
|
15
|
+
the full Streamoid wordmark (`ScStrLogo`). No product branding, no click target, no
|
|
16
|
+
app-switcher chevron — and its "collapsed" state squeezes the *whole wordmark* into a
|
|
17
|
+
32 × 12 px sliver instead of showing a product mark.
|
|
18
|
+
|
|
19
|
+
## TL;DR for agents
|
|
20
|
+
|
|
21
|
+
- **Reach for it when:** never. It cannot be clicked and cannot show a product.
|
|
22
|
+
- **Reach for this instead:** `ScSideBarLogoUnit` (product wordmark + switcher chevron
|
|
23
|
+
+ `onClick` + `hover`/`disabled` + a11y label), which is what every current sidebar
|
|
24
|
+
passes into `StreamoidSidebar`'s `expandedLogo` / `collapsedLogo` slots.
|
|
25
|
+
- **Three things that will bite you:**
|
|
26
|
+
1. ⚠️ **`...props` is destructured and never spread.** No `onClick`, no `style`, no
|
|
27
|
+
`data-*`. The interface doesn't extend `HTMLAttributes` either.
|
|
28
|
+
2. Hardcoded `width: 15rem` (240 px) when expanded. It does not adapt to its rail.
|
|
29
|
+
3. `state="collapsed"` still renders the **full "Streamoid" wordmark**, scaled to
|
|
30
|
+
32 × 12 px. It is not a logo mark — it is an unreadable smear.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 1. How to use it
|
|
35
|
+
|
|
36
|
+
### Import
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import { ScLogoUnit } from "@streamoid/ui";
|
|
40
|
+
import "@streamoid/ui/dist/index.css"; // once, at your app root
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Minimal usage
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
// This is the whole API.
|
|
47
|
+
<ScLogoUnit state="expanded" />
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Props
|
|
51
|
+
|
|
52
|
+
| Prop | Type | Default | Notes |
|
|
53
|
+
|---|---|---|---|
|
|
54
|
+
| `state` | `"expanded"` \| `"collapsed"` | `"expanded"` | `expanded` = 240 px wide, 16 px padding, wordmark at 167 × 16. `collapsed` = 48 × 48 box, 8 px padding, wordmark at 32 × 12. |
|
|
55
|
+
| `className` | `string` | – | Concatenated onto the root. ⚠️ Unguarded — omitting it puts a literal `undefined` in the class list. |
|
|
56
|
+
| `...props` | – | – | ⚠️ **Destructured and discarded.** `IScLogoUnitProps` does **not** extend `React.HTMLAttributes`, so there is no supported way to attach `onClick`, `style` or `aria-*`. |
|
|
57
|
+
|
|
58
|
+
The child is a hardcoded `<ScStrLogo type="default" />` — the Streamoid wordmark SVG.
|
|
59
|
+
There is no `product`, `wordmark` or `children` prop.
|
|
60
|
+
|
|
61
|
+
### What renders in each state
|
|
62
|
+
|
|
63
|
+
| | `expanded` | `collapsed` |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| Box | `width: 15rem` (240 px), 16 px padding | 48 × 48, 8 px padding, contents centred |
|
|
66
|
+
| Wordmark | `ScStrLogo` at 167 × 16 (`aspect-ratio: 167/16`) | the **same** wordmark at 32 × 12 (`aspect-ratio: 32/12`) |
|
|
67
|
+
| Colour | the SVG paths are filled with `--alias-text-and-icons-primary`, so it flips with the theme | same |
|
|
68
|
+
|
|
69
|
+
### Recipes
|
|
70
|
+
|
|
71
|
+
None. Here is the replacement:
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
// Expanded rail header: product wordmark + app-switcher chevron, one click target
|
|
75
|
+
<ScSideBarLogoUnit
|
|
76
|
+
product="CXO" // "CXO" | "Catalogix" | "Artifax" | "Photogenix" | "Tactix"
|
|
77
|
+
onClick={() => setAppListOpen((v) => !v)}
|
|
78
|
+
switchAriaLabel="Switch product"
|
|
79
|
+
/>
|
|
80
|
+
|
|
81
|
+
// Collapsed rail header: the square product icon
|
|
82
|
+
<ScSideBarLogoUnit
|
|
83
|
+
state="collapsed"
|
|
84
|
+
product="CXO"
|
|
85
|
+
onClick={() => setAppListOpen((v) => !v)}
|
|
86
|
+
/>
|
|
87
|
+
|
|
88
|
+
// Wired into the current shell
|
|
89
|
+
<StreamoidSidebar
|
|
90
|
+
expanded={expanded}
|
|
91
|
+
onToggle={() => setExpanded((v) => !v)}
|
|
92
|
+
config={config}
|
|
93
|
+
iconMap={iconMap}
|
|
94
|
+
expandedLogo={<ScSideBarLogoUnit product="CXO" onClick={openSwitcher} />}
|
|
95
|
+
collapsedLogo={<ScSideBarLogoUnit state="collapsed" product="CXO" onClick={openSwitcher} />}
|
|
96
|
+
switchPanel={<ScAppSwitchPanel apps={apps} />}
|
|
97
|
+
switchPanelOpen={appListOpen}
|
|
98
|
+
onSwitchPanelClose={() => setAppListOpen(false)}
|
|
99
|
+
/>
|
|
100
|
+
|
|
101
|
+
// If you only want the Streamoid mark itself, skip the wrapper entirely
|
|
102
|
+
<ScStreamoidWordmark width={110} height={16} />
|
|
103
|
+
<ScStreamoidMascot size={24} />
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## 2. Where to use it
|
|
109
|
+
|
|
110
|
+
Nowhere. Its only render site is the legacy `ScSidebar`
|
|
111
|
+
(`src/SC-Sidebar/ScSidebar.tsx:37` collapsed, `:154` expanded), which is itself unused.
|
|
112
|
+
|
|
113
|
+
The current rail header is `ScSideBarLogoUnit`, passed into `StreamoidSidebar`'s
|
|
114
|
+
`expandedLogo` / `collapsedLogo`. CXO, Photogenix, Catalogix and Artifax all do this.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 3. When to use it
|
|
119
|
+
|
|
120
|
+
### Use it when
|
|
121
|
+
|
|
122
|
+
- Never.
|
|
123
|
+
|
|
124
|
+
### Don't use it — reach for this instead
|
|
125
|
+
|
|
126
|
+
| Situation | Use instead |
|
|
127
|
+
|---|---|
|
|
128
|
+
| The sidebar's logo + product-switch header row | `ScSideBarLogoUnit` |
|
|
129
|
+
| The whole rail, with the logo slotted in | `StreamoidSidebar` (`expandedLogo` / `collapsedLogo`) |
|
|
130
|
+
| Just the Streamoid wordmark, sized by you | `ScStreamoidWordmark` (`width`, `height`, `color`) |
|
|
131
|
+
| Just the Streamoid mascot/monogram | `ScStreamoidMascot` (`size`) |
|
|
132
|
+
| The raw legacy wordmark SVG | `ScStrLogo` (`type: "default" \| "logo-only"`) |
|
|
133
|
+
| A product wordmark in a page header | `ProductWordmark` / `ProductCollapsedMark` |
|
|
134
|
+
| A product logo inside an app card | `ScAppcardLogos` |
|
|
135
|
+
| The CXO Copilot lockup | `ScCxoCopilotLogo` |
|
|
136
|
+
|
|
137
|
+
### Don't confuse with
|
|
138
|
+
|
|
139
|
+
| You may actually want | Not this |
|
|
140
|
+
|---|---|
|
|
141
|
+
| `ScSideBarLogoUnit` — the current header row: `product`/`wordmark`, `onClick`, `onSwitchClick`, `switchAriaLabel`, `hideSwitch`, `hover`, `disabled` | `ScLogoUnit` has `state` and `className`, full stop |
|
|
142
|
+
| `ScStreamoidWordmark` — the current brand wordmark component (110 × 16 header size) | `ScLogoUnit` embeds the older `ScStrLogo` SVG |
|
|
143
|
+
| `ScStreamoidMascot` — the square monogram, which is what a *collapsed* rail actually wants | `ScLogoUnit state="collapsed"` shows a 32 px-wide full wordmark |
|
|
144
|
+
| `ScStrLogo` — the bare SVG with no padding box | `ScLogoUnit` is `ScStrLogo` + a 240 px box |
|
|
145
|
+
|
|
146
|
+
The names are one word apart: **`ScLogoUnit`** (legacy, Streamoid-only, inert) vs
|
|
147
|
+
**`ScSideBarLogoUnit`** (current, per-product, clickable). Autocomplete will offer both.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 4. Why to use it
|
|
152
|
+
|
|
153
|
+
You wouldn't. What it still gets right:
|
|
154
|
+
|
|
155
|
+
- The wordmark SVG's paths are filled with `var(--alias-text-and-icons-primary)`, so
|
|
156
|
+
the logo inverts correctly between dark and light mode with no conditional.
|
|
157
|
+
- `aspect-ratio` is pinned in both states, so the mark never distorts when the box
|
|
158
|
+
is squeezed.
|
|
159
|
+
|
|
160
|
+
What you lose versus `ScSideBarLogoUnit`: the product wordmark, the switcher chevron,
|
|
161
|
+
the single unified click target, hover/disabled states, and the `switchAriaLabel`
|
|
162
|
+
accessible name.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Gotchas
|
|
167
|
+
|
|
168
|
+
**1. It is completely inert.** `...props` is destructured out and never spread onto the
|
|
169
|
+
root `<div>`, and the props interface doesn't extend `HTMLAttributes`. You cannot make
|
|
170
|
+
it clickable, cannot pass `style`, cannot pass `aria-*`.
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
// WRONG — does not compile, and would be dropped anyway
|
|
174
|
+
<ScLogoUnit onClick={openAppSwitcher} />
|
|
175
|
+
|
|
176
|
+
// RIGHT
|
|
177
|
+
<ScSideBarLogoUnit product="CXO" onClick={openAppSwitcher} />
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**2. Hardcoded 240 px width.** `.scLogoUnit { width: 15rem }` in the expanded state.
|
|
181
|
+
`StreamoidSidebar`'s expanded rail is 16 rem wide with 8 px padding, so this box
|
|
182
|
+
overflows it. And since `style` is dropped (Gotcha 1) you can only fix it with a
|
|
183
|
+
`className` override.
|
|
184
|
+
|
|
185
|
+
**3. "Collapsed" is not a logo mark.** It renders the same full wordmark at
|
|
186
|
+
`width: 2rem; height: 0.75rem`. Every current rail shows a square product icon there
|
|
187
|
+
instead — `ScSideBarLogoUnit state="collapsed"`, or `ScStreamoidMascot`.
|
|
188
|
+
|
|
189
|
+
**4. Streamoid-only.** `ScStrLogo type="default"` is hardcoded. There is no way to show
|
|
190
|
+
CXO, Catalogix, Artifax, Photogenix or Tactix branding.
|
|
191
|
+
|
|
192
|
+
**5. `className` produces a literal `undefined` class when omitted.**
|
|
193
|
+
`styles.scLogoUnit + " " + className + " " + variantsClassName`.
|
|
194
|
+
|
|
195
|
+
**6. Padding, not gap, does the spacing.** Expanded uses 16 px padding on all four
|
|
196
|
+
sides; collapsed drops to 8 px and centres. If you nest it in a rail that also pads,
|
|
197
|
+
the logo drifts out of alignment with the nav rows below it.
|
|
198
|
+
|
|
199
|
+
**7. Don't pass the app switcher next to it.** The whole reason
|
|
200
|
+
`StreamoidSidebar` grew `switchPanel` / `switchPanelOpen` is that rendering an app list
|
|
201
|
+
inline beside the logo pushes the nav down. Use the overlay slot.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## In the wild
|
|
206
|
+
|
|
207
|
+
_No host render site found — used by the agent runtime / composed internally._
|
|
208
|
+
|
|
209
|
+
Composed only inside the legacy sidebar:
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
// npm-components packages/ui/src/SC-Sidebar/ScSidebar.tsx:154
|
|
213
|
+
<ScLogoUnit className={styles.scLogoUnitInstance}></ScLogoUnit>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Where it *would* belong — the rail header — is now `ScSideBarLogoUnit`, passed into
|
|
217
|
+
`StreamoidSidebar`'s `expandedLogo` / `collapsedLogo` (see
|
|
218
|
+
`cxo-dashboard src/app/components/app-sidebar.tsx`).
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Related
|
|
223
|
+
|
|
224
|
+
- `ScSideBarLogoUnit` — **the replacement.** Product wordmark + switcher, clickable.
|
|
225
|
+
- `StreamoidSidebar` — the shell with `expandedLogo` / `collapsedLogo` slots.
|
|
226
|
+
- `ScStreamoidWordmark` / `ScStreamoidMascot` (`SC-Brand`) — the current brand marks.
|
|
227
|
+
The plain header wordmark (110 × 16) and the app-switcher lockup are different
|
|
228
|
+
things; don't conflate them.
|
|
229
|
+
- `ScStrLogo` — the raw legacy wordmark SVG this component wraps.
|
|
230
|
+
- `ScAppcardLogos` / `ProductWordmark` / `ScCxoCopilotLogo` — other branded marks.
|
|
231
|
+
- `ScSidebar` / `ScSidebarProfile` / `ScSidebarIcons` / `ScVersion` — the rest of this
|
|
232
|
+
legacy sidebar family.
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: ScMappingCard
|
|
3
|
+
package: "@streamoid/ui"
|
|
4
|
+
category: feed-taxonomy
|
|
5
|
+
status: stable
|
|
6
|
+
renders: div
|
|
7
|
+
tags: [feed, mapping, map-attributes, column, source-target, catalogix, slot]
|
|
8
|
+
related: [ScValueMappingL1, ScDefaultCard, ScSelect, ScTaxonomyPill]
|
|
9
|
+
do_not_confuse_with: [ScValueMappingL1, ScDefaultCard, ScTableList]
|
|
10
|
+
used_by: [catalogix]
|
|
11
|
+
required_props: [columnName]
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# ScMappingCard
|
|
15
|
+
|
|
16
|
+
**One row of the Catalogix feed Map-Attributes screen.** A source feed column on the
|
|
17
|
+
left, the target attribute(s) it maps to on the right, and the confirm/ignore
|
|
18
|
+
actions for that pairing — as a single card with three mutually exclusive states.
|
|
19
|
+
|
|
20
|
+
## TL;DR for agents
|
|
21
|
+
|
|
22
|
+
- **Reach for it when:** you are building a source→target mapping review list where
|
|
23
|
+
each row can be confirmed, ignored, or is still pending.
|
|
24
|
+
- **Don't reach for it when:** you are mapping *values* rather than *columns*
|
|
25
|
+
(→ `ScValueMappingL1`), or you just need a generic titled option card
|
|
26
|
+
(→ `ScDefaultCard`).
|
|
27
|
+
- **Three things that will bite you:**
|
|
28
|
+
1. `status` gates almost every other prop. In `confirmed`/`ignored`, the `targets`
|
|
29
|
+
slot, `sampleRows`, `warning` and `validityText` are **not rendered at all**.
|
|
30
|
+
2. `targets` is a **slot** — you render your own dropdowns into it. The card
|
|
31
|
+
supplies no select control.
|
|
32
|
+
3. The card sets `overflow: hidden`. Dropdowns opened inside the slot **must be
|
|
33
|
+
portalled to `<body>`** or they get clipped.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 1. How to use it
|
|
38
|
+
|
|
39
|
+
### Import
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { ScMappingCard } from "@streamoid/ui";
|
|
43
|
+
import "@streamoid/ui/dist/index.css"; // once, at your app root
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Minimal usage
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<ScMappingCard
|
|
50
|
+
columnName="STYLE ID"
|
|
51
|
+
status="default"
|
|
52
|
+
targets={<MyTargetSelect value={target} onChange={setTarget} />}
|
|
53
|
+
onIgnore={() => ignore(col)}
|
|
54
|
+
onConfirm={() => confirm(col)}
|
|
55
|
+
/>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Props
|
|
59
|
+
|
|
60
|
+
| Prop | Type | Default | Notes |
|
|
61
|
+
|---|---|---|---|
|
|
62
|
+
| `columnName` | `string` | — | **Required.** Source feed-column name, e.g. `"STYLE ID"`. Truncates with a `title` tooltip. |
|
|
63
|
+
| `status` | `"default"` \| `"confirmed"` \| `"ignored"` | `"default"` | The state machine. Gates every region below. |
|
|
64
|
+
| `badge` | `string` | – | Single letter for the narrow left gutter, e.g. `"A"`. Gutter is omitted entirely when unset. `aria-hidden`. |
|
|
65
|
+
| `sampleRows` | `string[]` | `[]` | Sample-value preview lines under the column name. **`default` status only.** |
|
|
66
|
+
| `targets` | `ReactNode` | – | **SLOT** for your target dropdown rows. **`default` status only.** |
|
|
67
|
+
| `confirmedTargets` | `string[]` | `[]` | Mapped target names as read-only boxes with connector arrows. **`confirmed` status only.** |
|
|
68
|
+
| `validityText` | `string` | – | Data-quality line, e.g. `"50% of rows … (200 out of 400)"`. **`default` status only.** |
|
|
69
|
+
| `warning` | `ReactNode` | – | Link-warning message with an error icon. **`default` status only.** |
|
|
70
|
+
| `canConfirm` | `boolean` | `false` | Shows "Confirm Mapping". Gate on "at least one target chosen". **`default` status only.** |
|
|
71
|
+
| `onAddColumn` | `() => void` | – | The `+` in the source card header ("map this column to another target too"). **`default` status only.** |
|
|
72
|
+
| `onIgnore` | `() => void` | – | "Ignore Column". **`default` status only.** |
|
|
73
|
+
| `onConfirm` | `() => void` | – | "Confirm Mapping". Only reachable when `canConfirm`. |
|
|
74
|
+
| `onEdit` | `() => void` | – | "Edit". **`confirmed` and `ignored` status only** — reopens the pairing. |
|
|
75
|
+
| `className` | `string` | – | Appended after internal classes. |
|
|
76
|
+
| `...props` | `HTMLAttributes<HTMLDivElement>` | – | Spread onto the card root. |
|
|
77
|
+
|
|
78
|
+
### What renders in each status
|
|
79
|
+
|
|
80
|
+
| Region | `default` | `confirmed` | `ignored` |
|
|
81
|
+
|---|---|---|---|
|
|
82
|
+
| Source | expanded card: name + `+` button + `sampleRows` | collapsed: name only | collapsed: name only |
|
|
83
|
+
| Target | your `targets` slot | `confirmedTargets` as read-only boxes | a single `-` box |
|
|
84
|
+
| Warning | `warning` if set | — | — |
|
|
85
|
+
| Actions | "Ignore Column" + "Confirm Mapping" (if `canConfirm`) + `validityText` | ✓ "Column Confirmed" + "Edit" | ✕ "Column Ignored" + "Edit" |
|
|
86
|
+
|
|
87
|
+
### Recipes
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
// Driving the full list from mapping state
|
|
91
|
+
{mappings.map((m, i) => (
|
|
92
|
+
<ScMappingCard
|
|
93
|
+
key={m.feedCol}
|
|
94
|
+
badge={m.headerLetter}
|
|
95
|
+
columnName={m.feedCol}
|
|
96
|
+
sampleRows={m.rows?.slice(0, 2).map((r) => r || "-")}
|
|
97
|
+
status={m.status} // "default" | "confirmed" | "ignored"
|
|
98
|
+
targets={<TargetRows mapping={m} />} // your selects go here
|
|
99
|
+
confirmedTargets={[...m.mappedCols, ...m.customCols]}
|
|
100
|
+
validityText={m.validityText}
|
|
101
|
+
warning={m.warning?.msg}
|
|
102
|
+
canConfirm={[...m.mappedCols, ...m.customCols].length > 0}
|
|
103
|
+
onAddColumn={() => showExtraTarget(i)}
|
|
104
|
+
onIgnore={() => act(i, "ignore")}
|
|
105
|
+
onConfirm={() => act(i, "confirm")}
|
|
106
|
+
onEdit={() => act(i, "edit")}
|
|
107
|
+
/>
|
|
108
|
+
))}
|
|
109
|
+
|
|
110
|
+
// The dropdown inside `targets` MUST portal out of the card
|
|
111
|
+
<Select
|
|
112
|
+
menuPortalTarget={document.body}
|
|
113
|
+
styles={{ menuPortal: (b) => ({ ...b, zIndex: 9999 }) }}
|
|
114
|
+
/>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 2. Where to use it
|
|
120
|
+
|
|
121
|
+
- **The Catalogix feed Map-Attributes screen** — one card per source column, stacked
|
|
122
|
+
in a scrolling list. This is its reason for existing.
|
|
123
|
+
- Any future **schema/import mapping review** flow with the same
|
|
124
|
+
source→target→confirm shape.
|
|
125
|
+
|
|
126
|
+
Currently rendered from `catalogix/dashboard app/components/FeedMapping/MapSingleAttribute`.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 3. When to use it
|
|
131
|
+
|
|
132
|
+
### Use it when
|
|
133
|
+
|
|
134
|
+
- You are reviewing a **column-to-attribute** pairing, one card per source column.
|
|
135
|
+
- Each row needs a **three-way lifecycle** (pending → confirmed | ignored) that the
|
|
136
|
+
user can reopen.
|
|
137
|
+
- The target control is **product-specific** and you want to supply it yourself
|
|
138
|
+
while inheriting the card's layout, states and actions.
|
|
139
|
+
|
|
140
|
+
### Don't use it — reach for this instead
|
|
141
|
+
|
|
142
|
+
| Situation | Use instead |
|
|
143
|
+
|---|---|
|
|
144
|
+
| Mapping individual **values** within an attribute (Map-Values / curation) | `ScValueMappingL1` |
|
|
145
|
+
| A generic pick-one-option card (title + description) | `ScDefaultCard` |
|
|
146
|
+
| A flat data row in a table | `ScTableList` / `ScCatalogixStoreTableList` |
|
|
147
|
+
| The target dropdown itself | `ScSelect`, or your app's select — this card only provides the slot |
|
|
148
|
+
| A taxonomy tree node | `ScTaxonomyPill` |
|
|
149
|
+
|
|
150
|
+
### Don't confuse with
|
|
151
|
+
|
|
152
|
+
| You may actually want | Not this |
|
|
153
|
+
|---|---|
|
|
154
|
+
| `ScValueMappingL1` — a single value-mapping row with `default`/`hover`/`active` + an "updated" dot | `ScMappingCard` is the column-level card with its own action footer |
|
|
155
|
+
| `ScDefaultCard` — generic option card, no states, no actions | This card carries a mapping lifecycle |
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 4. Why to use it
|
|
160
|
+
|
|
161
|
+
- **The state machine is already correct.** Three statuses × four regions is a lot
|
|
162
|
+
of conditional rendering to get wrong; the card collapses the source, swaps the
|
|
163
|
+
target region, and switches the footer to a status label in one prop.
|
|
164
|
+
- **Slot design keeps product logic out of the DS.** Feed target dropdowns need
|
|
165
|
+
app-specific data, search and portalling, so `targets` stays a slot — you get the
|
|
166
|
+
chrome without the DS needing to know about your data layer.
|
|
167
|
+
- **Two-tone surfaces that survive light mode.** The source card and card body use
|
|
168
|
+
two distinct tokens (`fill-neutral-*` body / raised source) that stay visually
|
|
169
|
+
separate in both themes, instead of relying on a grey that collapses to white.
|
|
170
|
+
- **Status semantics are tokenised** — the ✓/✕ and their colours come from
|
|
171
|
+
`--alias-text-and-icons-success` / `-error`, so they match every other status in
|
|
172
|
+
the product.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Gotchas
|
|
177
|
+
|
|
178
|
+
**1. `status` silently drops props.** Passing `targets` while `status="confirmed"`
|
|
179
|
+
renders nothing — a very common "my dropdowns disappeared" bug.
|
|
180
|
+
|
|
181
|
+
```tsx
|
|
182
|
+
// WRONG — targets ignored; confirmed status renders confirmedTargets instead
|
|
183
|
+
<ScMappingCard columnName="COLOR" status="confirmed" targets={<MySelect />} />
|
|
184
|
+
|
|
185
|
+
// RIGHT
|
|
186
|
+
<ScMappingCard columnName="COLOR" status="confirmed" confirmedTargets={["color"]} onEdit={reopen} />
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**2. Dropdowns get clipped.** The card root is `overflow: hidden`. Any menu opened
|
|
190
|
+
from inside `targets` must be portalled to `document.body` with an explicit z-index.
|
|
191
|
+
|
|
192
|
+
**3. `canConfirm` defaults to `false`.** Forget it and "Confirm Mapping" never
|
|
193
|
+
appears, no matter how many targets are selected.
|
|
194
|
+
|
|
195
|
+
**4. Button labels are hardcoded English.** "Ignore Column", "Confirm Mapping",
|
|
196
|
+
"Edit", "Column Confirmed", "Column Ignored" and the `"Add column"` aria-label are
|
|
197
|
+
baked into the component. There is no label prop — do not use this card in a
|
|
198
|
+
localised surface without changing the DS first.
|
|
199
|
+
|
|
200
|
+
**5. `columnName` is the only required prop.** Everything else is optional, so a
|
|
201
|
+
typo'd prop name fails silently rather than erroring. Check spelling against the
|
|
202
|
+
table above.
|
|
203
|
+
|
|
204
|
+
**6. `onEdit` is unreachable in `default` status,** and `onIgnore`/`onConfirm`/
|
|
205
|
+
`onAddColumn` are unreachable in the other two. Wire all of them; the card decides
|
|
206
|
+
which are live.
|
|
207
|
+
|
|
208
|
+
**7. `badge` is `aria-hidden`.** It is decoration, not information — don't put
|
|
209
|
+
anything meaning-bearing there.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## In the wild
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
// catalogix/dashboard app/components/FeedMapping/MapSingleAttribute/index.jsx:302
|
|
217
|
+
<ScMappingCard
|
|
218
|
+
badge={headerColumnName}
|
|
219
|
+
columnName={feedCol}
|
|
220
|
+
sampleRows={rows?.slice(0, 2).map((rowItem) => rowItem || "-")}
|
|
221
|
+
status={status}
|
|
222
|
+
targets={targets}
|
|
223
|
+
confirmedTargets={[...mappedCols, ...customCols]}
|
|
224
|
+
validityText={validityText}
|
|
225
|
+
warning={warningInfo ? warningInfo.msg : undefined}
|
|
226
|
+
canConfirm={[...mappedCols, ...customCols].length > 0}
|
|
227
|
+
onAddColumn={() => setShowAdditionalMappingOption(true)}
|
|
228
|
+
onIgnore={() => handleActionForMapAttribute(mappingItemIdx, "ignore")}
|
|
229
|
+
onConfirm={() => handleActionForMapAttribute(mappingItemIdx, "confirm")}
|
|
230
|
+
onEdit={() => handleActionForMapAttribute(mappingItemIdx, "edit")}
|
|
231
|
+
/>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Related
|
|
237
|
+
|
|
238
|
+
- `ScValueMappingL1` — the value-level sibling (Map-Values / curation rows).
|
|
239
|
+
- `ScDefaultCard` — generic option card when you don't need the lifecycle.
|
|
240
|
+
- `ScSelect` — a DS select you can render into the `targets` slot.
|
|
241
|
+
- `ScTaxonomyPill` — taxonomy nodes on adjacent Catalogix screens.
|