@intellihr/blueberry 1.0.0-beta.112 → 1.0.0-beta.113
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/.claude-dist/skills/bb-blueberry/SKILL.md +7 -3
- package/.claude-dist/skills/bb-icons/SKILL.md +1 -0
- package/.claude-dist/skills/bb-mango-combobox/SKILL.md +20 -0
- package/.claude-dist/skills/bb-mango-components/SKILL.md +6 -2
- package/.claude-dist/skills/bb-mango-copy-button/SKILL.md +70 -0
- package/.claude-dist/skills/bb-mango-forms/SKILL.md +156 -0
- package/.claude-dist/skills/bb-mango-illustrations/SKILL.md +88 -0
- package/.claude-dist/skills/bb-mango-navigation/SKILL.md +1 -1
- package/.claude-dist/skills/bb-mango-pipeline/SKILL.md +92 -0
- package/.claude-dist/skills/bb-mango-popover/SKILL.md +102 -0
- package/.claude-dist/skills/bb-mango-styling/SKILL.md +215 -0
- package/.claude-dist/skills/bb-mango-tag/SKILL.md +67 -18
- package/.claude-dist/skills/bb-mango-utility-classes/SKILL.md +105 -1
- package/.claude-dist/skills/bb-mango-workspace-badge/SKILL.md +10 -0
- package/.claude-dist/skills/bb-setup/SKILL.md +12 -0
- package/dist/BlueberryProvider/BlueberryProvider.d.ts +1 -1
- package/dist/BlueberryProvider/BlueberryProvider.d.ts.map +1 -1
- package/dist/MangoCombobox/MangoCombobox.d.ts +1 -0
- package/dist/MangoCombobox/MangoCombobox.d.ts.map +1 -1
- package/dist/MangoCopyButton/MangoCopyButton.d.ts +23 -0
- package/dist/MangoCopyButton/MangoCopyButton.d.ts.map +1 -0
- package/dist/MangoCopyButton/index.d.ts +3 -0
- package/dist/MangoCopyButton/index.d.ts.map +1 -0
- package/dist/MangoNavigation/MangoNavigation.d.ts +1 -0
- package/dist/MangoNavigation/MangoNavigation.d.ts.map +1 -1
- package/dist/MangoPipeline/MangoPipeline.d.ts +24 -0
- package/dist/MangoPipeline/MangoPipeline.d.ts.map +1 -0
- package/dist/MangoPipeline/index.d.ts +3 -0
- package/dist/MangoPipeline/index.d.ts.map +1 -0
- package/dist/MangoPopover/MangoPopover.d.ts +31 -0
- package/dist/MangoPopover/MangoPopover.d.ts.map +1 -0
- package/dist/MangoPopover/index.d.ts +3 -0
- package/dist/MangoPopover/index.d.ts.map +1 -0
- package/dist/MangoTag/MangoTag.d.ts +3 -1
- package/dist/MangoTag/MangoTag.d.ts.map +1 -1
- package/dist/MangoTag/index.d.ts +1 -0
- package/dist/MangoTag/index.d.ts.map +1 -1
- package/dist/MangoWorkspaceBadge/MangoWorkspaceBadge.d.ts +2 -0
- package/dist/MangoWorkspaceBadge/MangoWorkspaceBadge.d.ts.map +1 -1
- package/dist/_private/BlueberryContext/BlueberryContext.d.ts +2 -0
- package/dist/_private/BlueberryContext/BlueberryContext.d.ts.map +1 -1
- package/dist/_private/MangoCompatibilityWrapper/MangoCompatibilityWrapper.d.ts +1 -0
- package/dist/_private/MangoCompatibilityWrapper/MangoCompatibilityWrapper.d.ts.map +1 -1
- package/dist/index.cjs.js +4342 -3904
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.es.js +16586 -15641
- package/dist/index.es.js.map +1 -1
- package/package.json +2 -2
- package/.claude-dist/CLAUDE.md +0 -54
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bb-blueberry
|
|
3
|
-
description:
|
|
3
|
+
description: Use when building or modifying UI in this project — adding components, forms, buttons, inputs, layouts, icons, styling, or anything visual. This project uses @intellihr/blueberry (Mango* React components). Load this skill before touching any UI code.
|
|
4
4
|
allowed-tools: Read, Glob, Grep
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -21,8 +21,9 @@ When building UI, follow this order strictly:
|
|
|
21
21
|
|
|
22
22
|
1. **Mango wrapper component** — if a `Mango*` component does the job, use it
|
|
23
23
|
2. **Mango utility classes** — for layout, typography, spacing, and colour reach for `mgo-*` classes via `className` before writing any CSS (see `/bb-mango-utility-classes`)
|
|
24
|
-
3. **
|
|
25
|
-
4. **
|
|
24
|
+
3. **Design token CSS variables** — when utility classes don't cover the need, use `--mgo-*` tokens in Vanilla Extract styles (see `/bb-mango-styling`)
|
|
25
|
+
4. **Custom CSS** — Vanilla Extract only, last resort when tokens genuinely can't do the job
|
|
26
|
+
5. **No other design systems or UI libraries** — do not introduce Tailwind, MUI, Chakra, Ant Design, or any other component/CSS library
|
|
26
27
|
|
|
27
28
|
---
|
|
28
29
|
|
|
@@ -34,7 +35,10 @@ When building UI, follow this order strictly:
|
|
|
34
35
|
| Picking the right component | `/bb-mango-components` |
|
|
35
36
|
| Full props + JSX examples for a specific component | `/bb-mango-<name>` (e.g. `/bb-mango-button`) |
|
|
36
37
|
| Icon names and `MangoIcon` usage | `/bb-icons` |
|
|
38
|
+
| Illustration names and usage | `/bb-mango-illustrations` |
|
|
37
39
|
| Layout, typography, and colour utility classes | `/bb-mango-utility-classes` |
|
|
40
|
+
| Design tokens, CSS variables, borders, colours, typography | `/bb-mango-styling` |
|
|
41
|
+
| Form component best practices (labelling, validation, status) | `/bb-mango-forms` |
|
|
38
42
|
|
|
39
43
|
---
|
|
40
44
|
|
|
@@ -123,6 +123,7 @@ Icons render with `fill="currentColor"` — they inherit the text colour of thei
|
|
|
123
123
|
- `brand-onboarding` — Onboarding product mark
|
|
124
124
|
- `brand-analytics` — Analytics product mark
|
|
125
125
|
- `brand-talent` — Talent product mark
|
|
126
|
+
- `brand-lms` — Learning Management System product mark
|
|
126
127
|
|
|
127
128
|
---
|
|
128
129
|
|
|
@@ -35,6 +35,7 @@ Source: `src/MangoCombobox/MangoCombobox.tsx`
|
|
|
35
35
|
| `loading` | `boolean` | — | Show loading state in dropdown |
|
|
36
36
|
| `listPlaceholder` | `string` | — | Text shown when no items match |
|
|
37
37
|
| `searchCharacterMinimum` | `string` | — | Min characters before search triggers |
|
|
38
|
+
| `trigger` | `ReactNode` | — | Custom trigger element. Replaces the default button, label, clear button, and chevron. `label` slot is suppressed when set. |
|
|
38
39
|
| `name` | `string` | `id` | HTML name attribute |
|
|
39
40
|
| `testId` | `string` | — | Test identifier |
|
|
40
41
|
|
|
@@ -147,9 +148,28 @@ import { MangoCombobox, MangoComboboxChip } from '@intellihr/blueberry'
|
|
|
147
148
|
/>
|
|
148
149
|
```
|
|
149
150
|
|
|
151
|
+
### Custom trigger
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
// Replace the default button with any element (e.g. a MangoButton or MangoIconButton)
|
|
155
|
+
<MangoCombobox
|
|
156
|
+
id="filter"
|
|
157
|
+
value={value}
|
|
158
|
+
onChange={(e) => setValue(e.target.value as string)}
|
|
159
|
+
trigger={<MangoButton variant="secondary" icon="filter">Filter</MangoButton>}
|
|
160
|
+
items={filterOptions}
|
|
161
|
+
/>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
When `trigger` is provided:
|
|
165
|
+
- The default field button, label, clear button, and chevron are all replaced
|
|
166
|
+
- The `label` prop/slot is suppressed — do not pass `label` alongside `trigger`
|
|
167
|
+
- ARIA is applied automatically by mango-ui
|
|
168
|
+
|
|
150
169
|
### Notes
|
|
151
170
|
|
|
152
171
|
- `items` is an array prop — do not use children for options
|
|
153
172
|
- `onChange` receives `MgoInputEvent` — read `event.target.value` for the selected value (string or string[])
|
|
154
173
|
- `valueDisplay` is used to customise multi-select chip rendering; use `MangoComboboxChip` for person-like chips
|
|
155
174
|
- Always hoists the dropdown to avoid z-index clipping
|
|
175
|
+
- `trigger` replaces the entire default trigger — do not combine with `label`
|
|
@@ -80,6 +80,7 @@ Use this skill to pick the right component. Then load the component-specific ski
|
|
|
80
80
|
| `MangoWizardModal` | Multi-step wizard modal. `currentStep` is 1-indexed. |
|
|
81
81
|
| `MangoDropdownMenu` | Trigger + action menu. `trigger` + `items[]` required. |
|
|
82
82
|
| `MangoTooltip` | Hover tooltip. `trigger` + `content` required. |
|
|
83
|
+
| `MangoPopover` | Click-triggered floating panel. `trigger` + `children` required. Optional `header`/`footer`. `ref` gives imperative `show()`/`hide()`. |
|
|
83
84
|
|
|
84
85
|
---
|
|
85
86
|
|
|
@@ -94,7 +95,9 @@ Use this skill to pick the right component. Then load the component-specific ski
|
|
|
94
95
|
| `MangoProgressRing` | Circular progress. `value` (0–100) required. |
|
|
95
96
|
| `MangoEmptyState` | Empty state placeholder. `title` required. |
|
|
96
97
|
| `MangoBadge` | Notification badge. Passed as `badge` prop to Button/IconButton/Navigation items. |
|
|
97
|
-
| `MangoTag` | Status tag.
|
|
98
|
+
| `MangoTag` | Status tag. 14 tone options. Optional `icon` prop. |
|
|
99
|
+
| `MangoPipeline` | Filter bar with stage/status counts. `items[]` + `onChange` required. `variant`: tile or compact. |
|
|
100
|
+
| `MangoCopyButton` | Clipboard icon button. `value` required. Auto success/error feedback. |
|
|
98
101
|
| `MangoSplash` | Full-screen loading spinner. Requires parent with defined height. |
|
|
99
102
|
|
|
100
103
|
---
|
|
@@ -117,7 +120,8 @@ Every component exports a type alias: `TMangoButton`, `TMangoTextField`, etc.
|
|
|
117
120
|
Import: `import type { TMangoButton } from '@intellihr/blueberry'`
|
|
118
121
|
|
|
119
122
|
Exceptions:
|
|
120
|
-
- `MangoBadge`, `MangoCallout`, `MangoHeading`, `
|
|
123
|
+
- `MangoBadge`, `MangoCallout`, `MangoHeading`, `MangoToast`, `MangoToastStack`, `MangoTurnBack` — no exported type alias
|
|
121
124
|
- `MangoTooltip` — exports `IMangoTooltip` (not `TMangoTooltip`)
|
|
122
125
|
- `MangoWizardModal` — exports 4 types: `TMangoWizardModal`, `TMangoWizardModalStepItem`, `TMangoWizardModalStep`, `TMangoWizardModalStepLabel`
|
|
123
126
|
- `MangoAppShell` — exports `TMangoAppShell` + `TMangoAppShellRef`
|
|
127
|
+
- `MangoPopover` — exports `TMangoPopover` + `TMangoPopoverRef`
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bb-mango-copy-button
|
|
3
|
+
description: MangoCopyButton React component — clipboard button with automatic success/error feedback states and tooltip
|
|
4
|
+
allowed-tools: Read, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## `MangoCopyButton`
|
|
8
|
+
|
|
9
|
+
Import: `import { MangoCopyButton } from '@intellihr/blueberry'`
|
|
10
|
+
Source: `src/MangoCopyButton/MangoCopyButton.tsx`
|
|
11
|
+
|
|
12
|
+
### Props
|
|
13
|
+
|
|
14
|
+
| Prop | Type | Default | Description |
|
|
15
|
+
|---|---|---|---|
|
|
16
|
+
| `value` | `string` | — | Text to copy to clipboard |
|
|
17
|
+
| `from` | `string` | — | ID of another DOM element to copy from. Supports `id` (text content), `id.property`, or `id[attribute]` |
|
|
18
|
+
| `disabled` | `boolean` | — | Disabled state |
|
|
19
|
+
| `copyLabel` | `string` | — | Tooltip label in default state (default: i18n "Copy") |
|
|
20
|
+
| `successLabel` | `string` | — | Tooltip label after successful copy (default: i18n "Copied") |
|
|
21
|
+
| `errorLabel` | `string` | — | Tooltip label on copy failure (default: i18n "Error") |
|
|
22
|
+
| `tooltipPlacement` | `'top' \| 'right' \| 'bottom' \| 'left'` | `'top'` | Tooltip position |
|
|
23
|
+
| `onCopy` | `(event: MgoCopyEvent) => void` | — | Called when text is successfully copied |
|
|
24
|
+
| `onError` | `(event: MgoErrorEvent) => void` | — | Called when copy fails |
|
|
25
|
+
| `testId` | `string` | — | Test identifier |
|
|
26
|
+
|
|
27
|
+
### Exported type
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import type { TMangoCopyButton } from '@intellihr/blueberry'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### JSX Examples
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
import { MangoCopyButton } from '@intellihr/blueberry'
|
|
37
|
+
|
|
38
|
+
// Basic
|
|
39
|
+
<MangoCopyButton value="Text to copy" />
|
|
40
|
+
|
|
41
|
+
// With custom labels
|
|
42
|
+
<MangoCopyButton
|
|
43
|
+
value="user@example.com"
|
|
44
|
+
copyLabel="Copy email"
|
|
45
|
+
successLabel="Copied!"
|
|
46
|
+
errorLabel="Failed to copy"
|
|
47
|
+
/>
|
|
48
|
+
|
|
49
|
+
// Copy from another DOM element by ID (text content)
|
|
50
|
+
<code id="install-cmd">npm install @intellihr/blueberry</code>
|
|
51
|
+
<MangoCopyButton from="install-cmd" copyLabel="Copy command" />
|
|
52
|
+
|
|
53
|
+
// Copy a property of another element
|
|
54
|
+
<MangoCopyButton from="my-input.value" copyLabel="Copy" />
|
|
55
|
+
|
|
56
|
+
// With copy callback
|
|
57
|
+
<MangoCopyButton
|
|
58
|
+
value={apiKey}
|
|
59
|
+
copyLabel="Copy API key"
|
|
60
|
+
onCopy={(e) => console.log('Copied:', e.detail.value)}
|
|
61
|
+
/>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Notes
|
|
65
|
+
|
|
66
|
+
- Renders as an icon button — no label text is shown; use `copyLabel` for the tooltip
|
|
67
|
+
- Either `value` or `from` must be provided
|
|
68
|
+
- `from` supports: plain `id` (copies text content), `id.property` (property access), `id[attribute]` (attribute access)
|
|
69
|
+
- `onCopy` event detail contains `{ value: string }` — the copied text
|
|
70
|
+
- Feedback state (success/error icon) reverts automatically after a short time
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bb-mango-forms
|
|
3
|
+
description: Best practices for Blueberry Mango form components — labelling, validation status, help text, required/disabled, form methods. Read this before implementing any form field.
|
|
4
|
+
allowed-tools: Read, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Blueberry Mango Form Best Practices
|
|
8
|
+
|
|
9
|
+
> **Derived from `mango-forms`** — when that skill is updated, sync the relevant parts here, replacing web component/Angular patterns with React/Blueberry equivalents.
|
|
10
|
+
|
|
11
|
+
Applies to: `MangoTextField`, `MangoTextarea`, `MangoDateField`, `MangoCombobox`, `MangoCheckbox`, `MangoRadioGroup`
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
### Labelling
|
|
16
|
+
|
|
17
|
+
**Always provide a `label` prop. Never add a native `<label>` element.**
|
|
18
|
+
|
|
19
|
+
Every Mango wrapper renders its own label internally. Adding a separate native `<label>` will produce a duplicate and break accessibility.
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
// ❌ WRONG — do not do this
|
|
23
|
+
<label htmlFor="name">Full name</label>
|
|
24
|
+
<MangoTextField id="name" />
|
|
25
|
+
|
|
26
|
+
// ✅ CORRECT
|
|
27
|
+
<MangoTextField label="Full name" />
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
### Validation Status
|
|
33
|
+
|
|
34
|
+
All form components share the same `status` / `statusText` props.
|
|
35
|
+
|
|
36
|
+
| Prop | Type | Values | Description |
|
|
37
|
+
| ------------ | -------- | ----------------------------------------------- | -------------------------------------------------- |
|
|
38
|
+
| `status` | `string` | `'critical'` \| `'caution'` \| `'positive'` \| `''` | Visual validation state |
|
|
39
|
+
| `statusText` | `string` | any | Message shown below the field with a status icon |
|
|
40
|
+
|
|
41
|
+
**When to use each value:**
|
|
42
|
+
|
|
43
|
+
- `critical` — validation error, field is invalid
|
|
44
|
+
- `caution` — warning, field is valid but needs attention
|
|
45
|
+
- `positive` — explicit confirmation the value is valid
|
|
46
|
+
- `''` (empty, default) — neutral, no validation state shown
|
|
47
|
+
|
|
48
|
+
**Always pair `status` with `statusText`** so the user knows what to fix:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
// ❌ WRONG — status with no explanation
|
|
52
|
+
<MangoTextField label="Email" status="critical" />
|
|
53
|
+
|
|
54
|
+
// ✅ CORRECT
|
|
55
|
+
<MangoTextField
|
|
56
|
+
label="Email"
|
|
57
|
+
status="critical"
|
|
58
|
+
statusText="Enter a valid email address."
|
|
59
|
+
/>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
### Help Text
|
|
65
|
+
|
|
66
|
+
Use `helpText` for persistent instructional text shown below the field. It is always visible, unlike `statusText` which only shows when a status is set.
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
<MangoTextField
|
|
70
|
+
label="Username"
|
|
71
|
+
helpText="Must be 3–20 characters. Letters, numbers, and underscores only."
|
|
72
|
+
/>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Do not use `helpText` for validation errors — use `status` + `statusText` for that.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### Event Handling
|
|
80
|
+
|
|
81
|
+
Form components expose React-style event props. For components that wrap `mgo-*` web components, events are prefixed with `onMgo`:
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
// MangoTextField
|
|
85
|
+
<MangoTextField
|
|
86
|
+
label="Name"
|
|
87
|
+
onChange={(value: string) => setName(value)}
|
|
88
|
+
/>
|
|
89
|
+
|
|
90
|
+
// MangoDateField
|
|
91
|
+
<MangoDateField
|
|
92
|
+
label="Start date"
|
|
93
|
+
onChange={(isoValue: string) => setDate(isoValue)}
|
|
94
|
+
/>
|
|
95
|
+
|
|
96
|
+
// MangoCombobox
|
|
97
|
+
<MangoCombobox
|
|
98
|
+
label="Status"
|
|
99
|
+
options={options}
|
|
100
|
+
onChange={(value) => setValue(value)}
|
|
101
|
+
/>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Check each component's own skill (`/bb-mango-text-field`, `/bb-mango-date-field`, etc.) for the exact event prop signature.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
### Icon Props
|
|
109
|
+
|
|
110
|
+
Some form components accept `leadingIcon` / `trailingIcon` props. These always expect an **icon name string** from the Mango icon set — not a component or element.
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
// ✅ CORRECT — pass an icon name string
|
|
114
|
+
<MangoTextField label="Search" leadingIcon="search" />
|
|
115
|
+
|
|
116
|
+
// ❌ WRONG — do not pass a component
|
|
117
|
+
<MangoTextField label="Search" leadingIcon={<MangoIcon name="search" />} />
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
For valid icon names, see the `/bb-icons` skill.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### Required, Disabled, Readonly
|
|
125
|
+
|
|
126
|
+
| Prop | Behaviour |
|
|
127
|
+
| ---------- | ---------------------------------------------------------------------------- |
|
|
128
|
+
| `required` | Marks the field as required (shown visually and enforced in form submission) |
|
|
129
|
+
| `disabled` | Field is non-interactive and excluded from form submission |
|
|
130
|
+
| `readonly` | Field is non-interactive but included in form submission |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
### Form Validation Methods
|
|
135
|
+
|
|
136
|
+
Mango form components implement the Constraint Validation API. Access them via a React ref:
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
import { useRef } from 'react'
|
|
140
|
+
import { MangoTextField } from '@intellihr/blueberry'
|
|
141
|
+
|
|
142
|
+
const fieldRef = useRef<HTMLElement>(null)
|
|
143
|
+
|
|
144
|
+
// After a server-side error
|
|
145
|
+
fieldRef.current?.setCustomValidity('This username is already taken.')
|
|
146
|
+
fieldRef.current?.reportValidity()
|
|
147
|
+
|
|
148
|
+
// To clear
|
|
149
|
+
fieldRef.current?.setCustomValidity('')
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
| Method | Description |
|
|
153
|
+
| ---------------------------- | -------------------------------------------------------------- |
|
|
154
|
+
| `checkValidity()` | Returns `true` if valid, `false` if not (no UI shown) |
|
|
155
|
+
| `reportValidity()` | Like `checkValidity()` but also shows browser validation UI |
|
|
156
|
+
| `setCustomValidity(message)` | Set a custom validation message. Pass `''` to clear. |
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bb-mango-illustrations
|
|
3
|
+
description: Illustration names and the illustration system for Blueberry React apps — finding available illustrations, complete illustration list, how illustrations work
|
|
4
|
+
allowed-tools: Read, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Illustrations in Blueberry
|
|
8
|
+
|
|
9
|
+
> **Derived from `mango-illustrations`** — when that skill is updated with new illustration names or system changes, update this skill to match.
|
|
10
|
+
|
|
11
|
+
Mango UI has a built-in illustration system with full-colour SVG illustrations for common empty and error states.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
### How to use illustrations
|
|
16
|
+
|
|
17
|
+
There is no `MangoIllustration` React wrapper component. Illustrations surface in two ways in Blueberry:
|
|
18
|
+
|
|
19
|
+
**1. Via `MangoEmptyState` — preferred for empty/no-data states**
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { MangoEmptyState } from '@intellihr/blueberry'
|
|
23
|
+
|
|
24
|
+
<MangoEmptyState
|
|
25
|
+
variant="no-data"
|
|
26
|
+
title="No results"
|
|
27
|
+
description="Try adjusting your filters."
|
|
28
|
+
/>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**2. Via `MangoTurnBack` — for error/dead-end pages**
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { MangoTurnBack } from '@intellihr/blueberry'
|
|
35
|
+
|
|
36
|
+
<MangoTurnBack
|
|
37
|
+
variant="page-not-found"
|
|
38
|
+
title="Page not found"
|
|
39
|
+
description="The page you're looking for doesn't exist."
|
|
40
|
+
actions={[{ label: 'Go home', href: '/' }]}
|
|
41
|
+
/>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**3. Directly via the `mgo-illustration` web component** — use only when the above wrappers don't fit
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
// Blueberry loads mango-ui, so web components can be used directly
|
|
48
|
+
<mgo-illustration name="no-data" label="No data available" />
|
|
49
|
+
|
|
50
|
+
// Decorative (no label, aria-hidden applied automatically)
|
|
51
|
+
<mgo-illustration name="form-complete" />
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Never set a `library` attribute — the default library is used automatically.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### All available illustration names
|
|
59
|
+
|
|
60
|
+
#### Error States
|
|
61
|
+
|
|
62
|
+
- `page-not-found` — 404 / page not found
|
|
63
|
+
- `generic-error` — General or unexpected application error
|
|
64
|
+
- `connection-error` — Network or connection failure
|
|
65
|
+
- `identity-error` — Authentication or identity problem
|
|
66
|
+
- `permission-error` — Authorisation / access denied
|
|
67
|
+
|
|
68
|
+
#### Empty & Completion States
|
|
69
|
+
|
|
70
|
+
- `no-data` — No results or empty data set
|
|
71
|
+
- `form-complete` — Form or task successfully completed
|
|
72
|
+
|
|
73
|
+
#### Internal / Component Use
|
|
74
|
+
|
|
75
|
+
- `turnback-background` — Background graphic used internally by `MangoTurnBack`. Do not use as a general illustration.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### How the illustration system works
|
|
80
|
+
|
|
81
|
+
1. You provide a `name` (e.g. `"no-data"`)
|
|
82
|
+
2. The default library resolver returns a data URL: `data:image/svg+xml,${encodeURIComponent(svg)}`
|
|
83
|
+
3. The illustration is safely embedded — no network requests, all bundled
|
|
84
|
+
|
|
85
|
+
**Important differences from icons:**
|
|
86
|
+
|
|
87
|
+
- Illustrations are fixed-colour SVGs — they do **not** inherit text colour via `currentColor`
|
|
88
|
+
- All built-in illustrations are 256×256px except `turnback-background` (448×94px)
|
|
@@ -84,7 +84,7 @@ import type { TMangoNavigation } from '@intellihr/blueberry'
|
|
|
84
84
|
productSwitcher={{
|
|
85
85
|
currentProduct: {
|
|
86
86
|
label: 'Workforce Management',
|
|
87
|
-
type: 'workforceManagement' // 'workforceManagement'|'coreHr'|'financialWellbeing'|'payroll'|'analytics'|'talent'|'benefits'|'generic'
|
|
87
|
+
type: 'workforceManagement' // 'workforceManagement'|'coreHr'|'financialWellbeing'|'payroll'|'analytics'|'talent'|'lms'|'benefits'|'generic'
|
|
88
88
|
},
|
|
89
89
|
apps: [
|
|
90
90
|
{ href: 'https://corehr.example.com', label: 'Core HR', type: 'coreHr' },
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bb-mango-pipeline
|
|
3
|
+
description: MangoPipeline React component — filter bar showing stage/status counts; mutually exclusive selection; tile and compact variants
|
|
4
|
+
allowed-tools: Read, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## `MangoPipeline`
|
|
8
|
+
|
|
9
|
+
Import: `import { MangoPipeline } from '@intellihr/blueberry'`
|
|
10
|
+
Source: `src/MangoPipeline/MangoPipeline.tsx`
|
|
11
|
+
|
|
12
|
+
### Props
|
|
13
|
+
|
|
14
|
+
| Prop | Type | Default | Description |
|
|
15
|
+
|---|---|---|---|
|
|
16
|
+
| `items` | `IMangoPipelineItem[]` | **required** | Pipeline stage items |
|
|
17
|
+
| `value` | `string` | — | Currently selected value. Empty string = All (no filter). |
|
|
18
|
+
| `onChange` | `(event: MgoPipelineChangeEvent) => void` | — | Called when selection changes |
|
|
19
|
+
| `variant` | `'tile' \| 'compact'` | `'tile'` | `tile`: large count above label. `compact`: label with inline count badge. |
|
|
20
|
+
| `totalLabel` | `string` | `'All'` | Label for the auto-generated All/Total item |
|
|
21
|
+
| `totalCount` | `number` | — | Count shown on the Total item (omit to hide count) |
|
|
22
|
+
| `fill` | `boolean` | — | Stretch items to fill the full container width equally |
|
|
23
|
+
| `testId` | `string` | — | Test identifier |
|
|
24
|
+
|
|
25
|
+
### `IMangoPipelineItem`
|
|
26
|
+
|
|
27
|
+
| Field | Type | Default | Description |
|
|
28
|
+
|---|---|---|---|
|
|
29
|
+
| `value` | `string` | **required** | Value emitted when this item is selected |
|
|
30
|
+
| `label` | `string` | **required** | Stage label text |
|
|
31
|
+
| `count` | `number` | — | Number of items in this stage (omit to hide count) |
|
|
32
|
+
| `tone` | `'blue' \| 'purple' \| 'red' \| 'green' \| 'yellow' \| 'pink' \| 'teal' \| 'grey'` | — | Colour tone for the active state |
|
|
33
|
+
| `disabled` | `boolean` | — | Prevents selection |
|
|
34
|
+
|
|
35
|
+
### Exported type
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import type { TMangoPipeline } from '@intellihr/blueberry'
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Event type
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import type { MgoPipelineChangeEvent } from '@humanforce/mango-ui'
|
|
45
|
+
|
|
46
|
+
// Read selected value from onChange
|
|
47
|
+
onChange={(event: MgoPipelineChangeEvent) => {
|
|
48
|
+
const selected = event.detail.value // string — empty string means All
|
|
49
|
+
}}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### JSX Examples
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { MangoPipeline } from '@intellihr/blueberry'
|
|
56
|
+
|
|
57
|
+
const [filter, setFilter] = React.useState('')
|
|
58
|
+
|
|
59
|
+
<MangoPipeline
|
|
60
|
+
value={filter}
|
|
61
|
+
onChange={(e) => setFilter(e.detail.value)}
|
|
62
|
+
totalLabel="All employees"
|
|
63
|
+
totalCount={24}
|
|
64
|
+
items={[
|
|
65
|
+
{ value: 'active', label: 'Active', count: 12, tone: 'green' },
|
|
66
|
+
{ value: 'on-leave', label: 'On leave', count: 4, tone: 'yellow' },
|
|
67
|
+
{ value: 'terminated', label: 'Terminated', count: 8, tone: 'red' },
|
|
68
|
+
]}
|
|
69
|
+
/>
|
|
70
|
+
|
|
71
|
+
// Compact variant
|
|
72
|
+
<MangoPipeline
|
|
73
|
+
variant="compact"
|
|
74
|
+
value={filter}
|
|
75
|
+
onChange={(e) => setFilter(e.detail.value)}
|
|
76
|
+
items={[
|
|
77
|
+
{ value: 'active', label: 'Active', count: 12, tone: 'green' },
|
|
78
|
+
{ value: 'pending', label: 'Pending', count: 4, tone: 'yellow' },
|
|
79
|
+
]}
|
|
80
|
+
/>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Notes
|
|
84
|
+
|
|
85
|
+
- `value` empty string means the All/Total item is selected (no filter active)
|
|
86
|
+
- The All/Total item is auto-generated by mango-ui — do not add it to `items`
|
|
87
|
+
- `active` state on items is managed by `mgo-pipeline` based on `value` — do not set it manually
|
|
88
|
+
- Read the new value from `event.detail.value` (not `event.target.value`)
|
|
89
|
+
- Setting `value` programmatically syncs active state but does NOT fire `onChange`
|
|
90
|
+
- Clicking an already-active non-Total item deselects it and returns to All
|
|
91
|
+
- `tone` controls the colour of an item's active/selected state only
|
|
92
|
+
- `tile` variant is designed around displaying a large count — omitting `count` leaves an empty gap. Use `compact` when counts are not available
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bb-mango-popover
|
|
3
|
+
description: MangoPopover React component — click-triggered floating panel with trigger, body, optional header/footer, and imperative show/hide via ref
|
|
4
|
+
allowed-tools: Read, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## `MangoPopover`
|
|
8
|
+
|
|
9
|
+
Import: `import { MangoPopover } from '@intellihr/blueberry'`
|
|
10
|
+
Source: `src/MangoPopover/MangoPopover.tsx`
|
|
11
|
+
|
|
12
|
+
### Props
|
|
13
|
+
|
|
14
|
+
| Prop | Type | Default | Description |
|
|
15
|
+
|---|---|---|---|
|
|
16
|
+
| `trigger` | `ReactNode` | **required** | Element that opens the popover (button, icon-button, etc.) |
|
|
17
|
+
| `children` | `ReactNode` | **required** | Body content of the popover |
|
|
18
|
+
| `header` | `ReactNode` | — | Content rendered in the panel header |
|
|
19
|
+
| `footer` | `ReactNode` | — | Content rendered in the panel footer |
|
|
20
|
+
| `open` | `boolean` | — | Controlled open state |
|
|
21
|
+
| `placement` | `TPopoverPlacement` | `'bottom-start'` | Preferred placement of the panel |
|
|
22
|
+
| `disabled` | `boolean` | — | Prevents the popover from opening |
|
|
23
|
+
| `distance` | `number` | `6` | Distance in px from trigger to panel |
|
|
24
|
+
| `skidding` | `number` | `0` | Offset in px along the trigger axis |
|
|
25
|
+
| `hoist` | `boolean` | `true` | Use fixed positioning to prevent clipping |
|
|
26
|
+
| `onShow` | `(event: Event) => void` | — | Called when the panel opens |
|
|
27
|
+
| `onAfterShow` | `(event: Event) => void` | — | Called after open animation completes |
|
|
28
|
+
| `onHide` | `(event: Event) => void` | — | Called when the panel closes |
|
|
29
|
+
| `onAfterHide` | `(event: Event) => void` | — | Called after close animation completes |
|
|
30
|
+
| `testId` | `string` | — | Test identifier |
|
|
31
|
+
|
|
32
|
+
### Placement values
|
|
33
|
+
|
|
34
|
+
`'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'right' | 'right-start' | 'right-end' | 'left' | 'left-start' | 'left-end'`
|
|
35
|
+
|
|
36
|
+
### Exported types
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import type { TMangoPopover, TMangoPopoverRef } from '@intellihr/blueberry'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Imperative ref
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
const popoverRef = React.useRef<TMangoPopoverRef>(null)
|
|
46
|
+
|
|
47
|
+
<MangoPopover ref={popoverRef} trigger={...}>...</MangoPopover>
|
|
48
|
+
|
|
49
|
+
// Methods
|
|
50
|
+
popoverRef.current?.show()
|
|
51
|
+
popoverRef.current?.hide()
|
|
52
|
+
popoverRef.current?.reposition()
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### JSX Examples
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { MangoPopover, MangoButton, MangoIconButton } from '@intellihr/blueberry'
|
|
59
|
+
|
|
60
|
+
// Basic
|
|
61
|
+
<MangoPopover
|
|
62
|
+
trigger={<MangoButton variant="secondary">Open</MangoButton>}
|
|
63
|
+
>
|
|
64
|
+
<p className="mgo-text-m">Popover content goes here.</p>
|
|
65
|
+
</MangoPopover>
|
|
66
|
+
|
|
67
|
+
// With header and footer
|
|
68
|
+
<MangoPopover
|
|
69
|
+
trigger={<MangoIconButton icon="settings" label="Settings" />}
|
|
70
|
+
header={<span className="mgo-text-m mgo-weight-strong">Settings</span>}
|
|
71
|
+
footer={
|
|
72
|
+
<div className="mgo-cluster mgo-justify-end">
|
|
73
|
+
<MangoButton variant="secondary" size="small">Cancel</MangoButton>
|
|
74
|
+
<MangoButton size="small">Save</MangoButton>
|
|
75
|
+
</div>
|
|
76
|
+
}
|
|
77
|
+
>
|
|
78
|
+
<div className="mgo-stack">
|
|
79
|
+
<p className="mgo-text-s">Adjust your preferences.</p>
|
|
80
|
+
</div>
|
|
81
|
+
</MangoPopover>
|
|
82
|
+
|
|
83
|
+
// Custom placement
|
|
84
|
+
<MangoPopover placement="top-start" trigger={<MangoButton>Open</MangoButton>}>
|
|
85
|
+
Content above.
|
|
86
|
+
</MangoPopover>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### CSS custom properties
|
|
90
|
+
|
|
91
|
+
| Property | Default | Description |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| `--min-width` | `14rem` | Minimum width of the panel |
|
|
94
|
+
| `--max-width` | `25rem` | Maximum width of the panel |
|
|
95
|
+
|
|
96
|
+
### Notes
|
|
97
|
+
|
|
98
|
+
- `trigger` is required and must be a clickable element (button, icon-button) for accessibility
|
|
99
|
+
- The popover closes when the user clicks outside or presses Escape
|
|
100
|
+
- `hoist` defaults to `true` — use `hoist={false}` to opt out of fixed positioning
|
|
101
|
+
- For action menus use `MangoDropdownMenu` instead — `MangoPopover` is for richer non-menu content (info panels, filter widgets, notifications)
|
|
102
|
+
- Prefer MangoPopover over MangoTooltip when content is interactive or requires persistent display
|