@intellihr/blueberry 1.0.0-beta.111 → 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 +97 -0
- package/.claude-dist/skills/bb-icons/SKILL.md +135 -0
- package/.claude-dist/skills/bb-mango-app-shell/SKILL.md +9 -5
- package/.claude-dist/skills/bb-mango-combobox/SKILL.md +27 -7
- package/.claude-dist/skills/bb-mango-components/SKILL.md +7 -3
- 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-heading/SKILL.md +1 -0
- package/.claude-dist/skills/bb-mango-icon/SKILL.md +2 -2
- 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-text-field/SKILL.md +2 -2
- package/.claude-dist/skills/bb-mango-textarea/SKILL.md +2 -2
- package/.claude-dist/skills/bb-mango-utility-classes/SKILL.md +288 -0
- package/.claude-dist/skills/bb-mango-workspace-badge/SKILL.md +10 -0
- package/.claude-dist/skills/bb-setup/SKILL.md +105 -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 +3677 -3232
- 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 +16441 -15489
- package/dist/index.es.js.map +1 -1
- package/package.json +2 -2
- package/scripts/link-claude.js +16 -1
- package/.claude-dist/CLAUDE.md +0 -50
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bb-blueberry
|
|
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
|
+
allowed-tools: Read, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Blueberry + Mango UI
|
|
8
|
+
|
|
9
|
+
**Blueberry** (`@intellihr/blueberry`) is a React component library. It provides two things:
|
|
10
|
+
|
|
11
|
+
1. **Mango wrapper components** — React wrappers around `@humanforce/mango-ui` web components, giving them a JSX-friendly API with React props, TypeScript types, and standard React event names (`onChange`, `onBlur`, etc.)
|
|
12
|
+
2. **Custom components** — additional components built from scratch with Vanilla Extract CSS
|
|
13
|
+
|
|
14
|
+
**Mango UI** (`@humanforce/mango-ui`) is the underlying web component library. In a Blueberry app you should always use the Blueberry wrapper (e.g. `MangoButton`) rather than the raw web component (`mgo-button`) directly.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Priority order
|
|
19
|
+
|
|
20
|
+
When building UI, follow this order strictly:
|
|
21
|
+
|
|
22
|
+
1. **Mango wrapper component** — if a `Mango*` component does the job, use it
|
|
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. **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
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Skills to use
|
|
31
|
+
|
|
32
|
+
| Task | Skill |
|
|
33
|
+
|---|---|
|
|
34
|
+
| Setting up Blueberry in a new React app | `/bb-setup` |
|
|
35
|
+
| Picking the right component | `/bb-mango-components` |
|
|
36
|
+
| Full props + JSX examples for a specific component | `/bb-mango-<name>` (e.g. `/bb-mango-button`) |
|
|
37
|
+
| Icon names and `MangoIcon` usage | `/bb-icons` |
|
|
38
|
+
| Illustration names and usage | `/bb-mango-illustrations` |
|
|
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` |
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## All available component skills
|
|
46
|
+
|
|
47
|
+
### Forms
|
|
48
|
+
- `/bb-mango-text-field` — Single-line text input
|
|
49
|
+
- `/bb-mango-textarea` — Multi-line text input
|
|
50
|
+
- `/bb-mango-checkbox` — Checkbox
|
|
51
|
+
- `/bb-mango-radio-group` — Radio button group
|
|
52
|
+
- `/bb-mango-combobox` — Dropdown select with search
|
|
53
|
+
- `/bb-mango-combobox-chip` — Multi-select chip (used in `MangoCombobox` `valueDisplay`)
|
|
54
|
+
- `/bb-mango-date-field` — Date picker
|
|
55
|
+
|
|
56
|
+
### Actions
|
|
57
|
+
- `/bb-mango-button` — Button
|
|
58
|
+
- `/bb-mango-icon-button` — Icon-only button
|
|
59
|
+
- `/bb-mango-link` — Inline text link
|
|
60
|
+
|
|
61
|
+
### Layout
|
|
62
|
+
- `/bb-mango-card` — Elevated content surface
|
|
63
|
+
- `/bb-mango-disclosure` — Collapsible section
|
|
64
|
+
- `/bb-mango-heading` — Styled h1–h6 heading
|
|
65
|
+
- `/bb-mango-split-panel` — Resizable split panel
|
|
66
|
+
|
|
67
|
+
### Navigation
|
|
68
|
+
- `/bb-mango-app-shell` — App chrome with sidebar and top bar
|
|
69
|
+
- `/bb-mango-breadcrumbs` — Breadcrumb trail
|
|
70
|
+
- `/bb-mango-navigation` — Sidebar navigation
|
|
71
|
+
- `/bb-mango-tabs` — Tabbed content
|
|
72
|
+
- `/bb-mango-workspace-badge` — Workspace/tenant badge
|
|
73
|
+
- `/bb-mango-turn-back` — Error/dead-end page
|
|
74
|
+
|
|
75
|
+
### Overlays
|
|
76
|
+
- `/bb-mango-modal` — Dialog modal
|
|
77
|
+
- `/bb-mango-wizard-modal` — Multi-step wizard modal
|
|
78
|
+
- `/bb-mango-dropdown-menu` — Trigger + action menu
|
|
79
|
+
- `/bb-mango-tooltip` — Hover tooltip
|
|
80
|
+
|
|
81
|
+
### Feedback
|
|
82
|
+
- `/bb-mango-callout` — Inline alert/notice
|
|
83
|
+
- `/bb-mango-toast` — Notification toast
|
|
84
|
+
- `/bb-mango-toast-stack` — Toast container
|
|
85
|
+
- `/bb-mango-progress-bar` — Linear progress
|
|
86
|
+
- `/bb-mango-progress-ring` — Circular progress
|
|
87
|
+
- `/bb-mango-empty-state` — Empty state placeholder
|
|
88
|
+
- `/bb-mango-badge` — Notification badge
|
|
89
|
+
- `/bb-mango-tag` — Status label tag
|
|
90
|
+
- `/bb-mango-splash` — Full-screen loading spinner
|
|
91
|
+
|
|
92
|
+
### Display
|
|
93
|
+
- `/bb-mango-table` — Data table (TanStack Table)
|
|
94
|
+
- `/bb-mango-name-value-list` — Key/value display list
|
|
95
|
+
- `/bb-mango-person` — Avatar + name + info
|
|
96
|
+
- `/bb-mango-avatar` — Avatar
|
|
97
|
+
- `/bb-mango-icon` — Icon by name
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bb-icons
|
|
3
|
+
description: Icon names and the icon system for Blueberry React apps — finding available icons, complete icon list, how icons work
|
|
4
|
+
allowed-tools: Read, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Icons in Blueberry
|
|
8
|
+
|
|
9
|
+
> **Derived from `mango-icons`** — when that skill is updated with new icon names or system changes, update this skill to match.
|
|
10
|
+
|
|
11
|
+
For how to use the `MangoIcon` component or pass icons as props, see `/bb-mango-icon`.
|
|
12
|
+
|
|
13
|
+
Icons render with `fill="currentColor"` — they inherit the text colour of their container and scale with font size.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
### All available icon names
|
|
18
|
+
|
|
19
|
+
#### Navigation & Directional
|
|
20
|
+
- `back` — left chevron (previous page/step)
|
|
21
|
+
- `back-far` — double left chevron (skip to start)
|
|
22
|
+
- `back-first` — left chevron with stop bar (first page)
|
|
23
|
+
- `next` — right chevron (next page/step)
|
|
24
|
+
- `next-far` — double right chevron (skip to end)
|
|
25
|
+
- `next-last` — right chevron with stop bar (last page)
|
|
26
|
+
- `indicator-down` — down chevron (disclosure open, dropdown)
|
|
27
|
+
- `indicator-up` — up chevron (disclosure close)
|
|
28
|
+
- `home` — house
|
|
29
|
+
- `external-link` — arrow pointing out of box (opens in new tab)
|
|
30
|
+
- `sidebar` — sidebar panel toggle
|
|
31
|
+
|
|
32
|
+
#### Actions — General
|
|
33
|
+
- `add` — plus
|
|
34
|
+
- `edit` — pencil
|
|
35
|
+
- `delete` — trash with X
|
|
36
|
+
- `copy` — copy
|
|
37
|
+
- `paste` — paste
|
|
38
|
+
- `close` — X mark (dismiss, remove)
|
|
39
|
+
- `search` — magnifying glass
|
|
40
|
+
- `filter` — funnel
|
|
41
|
+
- `filter-clear` — funnel with slash
|
|
42
|
+
- `upload` — arrow up from tray
|
|
43
|
+
- `download` — arrow down to tray
|
|
44
|
+
- `share` — share nodes
|
|
45
|
+
- `send` — paper plane
|
|
46
|
+
- `archive` — box taped
|
|
47
|
+
- `redo` — turn right arrow
|
|
48
|
+
- `undo` — turn left arrow
|
|
49
|
+
- `refresh` — rotate clockwise (reload)
|
|
50
|
+
- `reset` — rotate (reset to default)
|
|
51
|
+
- `expand-all` — arrows expanding from line
|
|
52
|
+
- `collapse-all` — arrows collapsing to lines
|
|
53
|
+
- `pin` — thumbtack
|
|
54
|
+
|
|
55
|
+
#### Actions — Specialised
|
|
56
|
+
- `assign-person` — person with plus (assign to user)
|
|
57
|
+
- `add-notification` — bell with plus
|
|
58
|
+
- `start-work` — clock (clock in)
|
|
59
|
+
- `end-work` — checkered flag (clock out)
|
|
60
|
+
- `work-break` — mug with saucer (start break)
|
|
61
|
+
- `end-work-break` — mug with saucer and slash (end break)
|
|
62
|
+
- `action-magic` — lightning bolt (automated action)
|
|
63
|
+
- `ai-magic` — sparkles (AI feature)
|
|
64
|
+
|
|
65
|
+
#### Status & Feedback
|
|
66
|
+
- `checkmark` — plain check mark
|
|
67
|
+
- `status-positive` — circle with check (success)
|
|
68
|
+
- `status-caution` — triangle with exclamation (warning)
|
|
69
|
+
- `status-critical` — diamond with X (error/critical)
|
|
70
|
+
- `status-pending` — small circle (pending/dot)
|
|
71
|
+
- `status-new` — single sparkle (new item)
|
|
72
|
+
- `status-no-action` — hexagon minus (no action required)
|
|
73
|
+
- `info` — circle with i
|
|
74
|
+
- `help` — circle with question mark
|
|
75
|
+
|
|
76
|
+
#### UI Controls & Indicators
|
|
77
|
+
- `more` — horizontal ellipsis (overflow menu)
|
|
78
|
+
- `settings` — gear
|
|
79
|
+
- `page-config` — sliders (page/view configuration)
|
|
80
|
+
- `navigation-menu` — hamburger bars
|
|
81
|
+
- `grip` — vertical grip dots (drag handle)
|
|
82
|
+
- `apps` — grid of rounded squares (app switcher)
|
|
83
|
+
- `indeterminate` — minus (checkbox indeterminate state)
|
|
84
|
+
- `radio` — small filled circle (radio button indicator)
|
|
85
|
+
- `show-on` — eye (show password/content)
|
|
86
|
+
- `show-off` — eye with slash (hide password/content)
|
|
87
|
+
- `notifications` — bell
|
|
88
|
+
- `comment` — message with lines
|
|
89
|
+
- `note` — memo / note
|
|
90
|
+
- `task-list` — clipboard with checklist
|
|
91
|
+
|
|
92
|
+
#### People & Identity
|
|
93
|
+
- `person` — single user silhouette
|
|
94
|
+
- `login` — arrow into bracket (sign in)
|
|
95
|
+
- `logout` — arrow out of bracket (sign out)
|
|
96
|
+
- `lock` — padlock
|
|
97
|
+
- `language` — language/globe symbol
|
|
98
|
+
|
|
99
|
+
#### Data & Analytics
|
|
100
|
+
- `chart` — bar chart
|
|
101
|
+
- `analytics-dashboard` — column chart (dashboard)
|
|
102
|
+
- `analytics-visualisation` — pie chart
|
|
103
|
+
- `date` — calendar with lines
|
|
104
|
+
- `timezone` — globe (Americas)
|
|
105
|
+
- `percent` — percent sign
|
|
106
|
+
- `dollar-sign` — dollar sign
|
|
107
|
+
- `payroll-dollar` — circle with dollar sign
|
|
108
|
+
|
|
109
|
+
#### Stars & Ratings
|
|
110
|
+
- `star` — filled star
|
|
111
|
+
- `star-hollow` — outline star
|
|
112
|
+
|
|
113
|
+
#### Media
|
|
114
|
+
- `play` — play triangle
|
|
115
|
+
- `pause` — pause bars
|
|
116
|
+
|
|
117
|
+
#### Brand Icons
|
|
118
|
+
- `brand-monogram` — Humanforce monogram
|
|
119
|
+
- `brand-core-hr` — Core HR product mark
|
|
120
|
+
- `brand-payroll` — Payroll product mark
|
|
121
|
+
- `brand-workforce-management` — Workforce Management product mark
|
|
122
|
+
- `brand-financial-wellbeing` — Financial Wellbeing product mark
|
|
123
|
+
- `brand-onboarding` — Onboarding product mark
|
|
124
|
+
- `brand-analytics` — Analytics product mark
|
|
125
|
+
- `brand-talent` — Talent product mark
|
|
126
|
+
- `brand-lms` — Learning Management System product mark
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
### How it works
|
|
131
|
+
|
|
132
|
+
1. You provide an icon name (e.g. `"indicator-down"`)
|
|
133
|
+
2. The resolver looks it up in the `icons` export from `@humanforce/mango-ui/src/icons/icons.ts`
|
|
134
|
+
3. It returns a data URL: `data:image/svg+xml,${encodeURIComponent(svg)}`
|
|
135
|
+
4. Renders with `fill="currentColor"` — inherits text colour automatically
|
|
@@ -58,7 +58,7 @@ import type { TMangoAppShell, TMangoAppShellRef } from '@intellihr/blueberry'
|
|
|
58
58
|
### JSX Examples
|
|
59
59
|
|
|
60
60
|
```tsx
|
|
61
|
-
import { MangoAppShell, MangoNavigation } from '@intellihr/blueberry'
|
|
61
|
+
import { MangoAppShell, MangoNavigation, MangoWorkspaceBadge } from '@intellihr/blueberry'
|
|
62
62
|
import type { TMangoAppShellRef } from '@intellihr/blueberry'
|
|
63
63
|
|
|
64
64
|
// Basic usage
|
|
@@ -68,22 +68,26 @@ import type { TMangoAppShellRef } from '@intellihr/blueberry'
|
|
|
68
68
|
logoAlt="My App"
|
|
69
69
|
logoHref="/"
|
|
70
70
|
sidebar={<MangoNavigation items={navItems} />}
|
|
71
|
+
topLeft={<MangoWorkspaceBadge label="Acme Corp" />}
|
|
71
72
|
topRight={<UserMenu />}
|
|
72
73
|
>
|
|
73
74
|
<MainContent />
|
|
74
75
|
</MangoAppShell>
|
|
75
76
|
|
|
76
|
-
// With imperative ref control
|
|
77
|
+
// With workspace badge image and imperative ref control
|
|
77
78
|
const appShellRef = React.useRef<TMangoAppShellRef>(null)
|
|
78
79
|
|
|
79
80
|
<MangoAppShell
|
|
80
81
|
ref={appShellRef}
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
logo="/logo.svg"
|
|
83
|
+
logoShort="/logo-short.svg"
|
|
84
|
+
logoAlt="My App"
|
|
83
85
|
sidebar={<MangoNavigation items={navItems} />}
|
|
86
|
+
topLeft={<MangoWorkspaceBadge label="Acme Corp" src="/workspace-logo.png" />}
|
|
87
|
+
topRight={<MangoAvatar size="small" initials="JS" label="John Smith" />}
|
|
84
88
|
>
|
|
85
89
|
<button onClick={() => appShellRef.current?.toggleSidebar()}>
|
|
86
|
-
Toggle
|
|
90
|
+
Toggle sidebar
|
|
87
91
|
</button>
|
|
88
92
|
</MangoAppShell>
|
|
89
93
|
```
|
|
@@ -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
|
|
|
@@ -51,7 +52,7 @@ import type { MgoInputEvent, MgoComboboxSearchEvent } from '@humanforce/mango-ui
|
|
|
51
52
|
|
|
52
53
|
// Read new value from onChange
|
|
53
54
|
onChange={(event: MgoInputEvent) => {
|
|
54
|
-
const newValue = event.
|
|
55
|
+
const newValue = event.target.value // string or string[]
|
|
55
56
|
}}
|
|
56
57
|
|
|
57
58
|
// Server-side search
|
|
@@ -72,7 +73,7 @@ const [value, setValue] = React.useState('')
|
|
|
72
73
|
<MangoCombobox
|
|
73
74
|
id="department"
|
|
74
75
|
value={value}
|
|
75
|
-
onChange={(e) => setValue(e.
|
|
76
|
+
onChange={(e) => setValue(e.target.value as string)}
|
|
76
77
|
label="Department"
|
|
77
78
|
items={[
|
|
78
79
|
{ label: 'Engineering', value: 'engineering' },
|
|
@@ -88,7 +89,7 @@ const [values, setValues] = React.useState<string[]>([])
|
|
|
88
89
|
id="skills"
|
|
89
90
|
value={values}
|
|
90
91
|
isMultiSelect
|
|
91
|
-
onChange={(e) => setValues(e.
|
|
92
|
+
onChange={(e) => setValues(e.target.value as string[])}
|
|
92
93
|
label="Skills"
|
|
93
94
|
items={skillOptions}
|
|
94
95
|
/>
|
|
@@ -97,7 +98,7 @@ const [values, setValues] = React.useState<string[]>([])
|
|
|
97
98
|
<MangoCombobox
|
|
98
99
|
id="employee"
|
|
99
100
|
value={selectedEmployee}
|
|
100
|
-
onChange={(e) => setSelectedEmployee(e.
|
|
101
|
+
onChange={(e) => setSelectedEmployee(e.target.value as string)}
|
|
101
102
|
onSearchChange={(e) => fetchEmployees(e.detail.value)}
|
|
102
103
|
searchMode="server"
|
|
103
104
|
label="Employee"
|
|
@@ -110,7 +111,7 @@ const [values, setValues] = React.useState<string[]>([])
|
|
|
110
111
|
<MangoCombobox
|
|
111
112
|
id="role"
|
|
112
113
|
value={role}
|
|
113
|
-
onChange={(e) => setRole(e.
|
|
114
|
+
onChange={(e) => setRole(e.target.value as string)}
|
|
114
115
|
label="Role"
|
|
115
116
|
status="critical"
|
|
116
117
|
statusText="Please select a role"
|
|
@@ -128,7 +129,7 @@ import { MangoCombobox, MangoComboboxChip } from '@intellihr/blueberry'
|
|
|
128
129
|
id="team-members"
|
|
129
130
|
value={selectedIds}
|
|
130
131
|
isMultiSelect
|
|
131
|
-
onChange={(e) => setSelectedIds(e.
|
|
132
|
+
onChange={(e) => setSelectedIds(e.target.value as string[])}
|
|
132
133
|
label="Team members"
|
|
133
134
|
items={memberItems}
|
|
134
135
|
valueDisplay={selectedIds.map((id) => {
|
|
@@ -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
|
-
- `onChange` receives `MgoInputEvent
|
|
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
|
---
|
|
@@ -107,7 +110,7 @@ Use this skill to pick the right component. Then load the component-specific ski
|
|
|
107
110
|
| `MangoNameValueList` | Key/value display list. `items[]` required. |
|
|
108
111
|
| `MangoPerson` | Avatar + name + info. `name` required. |
|
|
109
112
|
| `MangoAvatar` | Avatar. `label` (accessibility) required. |
|
|
110
|
-
| `MangoIcon` | Icon by name. Use `/
|
|
113
|
+
| `MangoIcon` | Icon by name. Use `/bb-icons` skill for icon names. |
|
|
111
114
|
|
|
112
115
|
---
|
|
113
116
|
|
|
@@ -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. |
|
|
@@ -37,3 +37,4 @@ import { MangoHeading } from '@intellihr/blueberry'
|
|
|
37
37
|
|
|
38
38
|
- `level` is a **string** (`'1'` through `'6'`), not a number — pass `level="2"` not `level={2}`
|
|
39
39
|
- Use `MangoHeading` instead of raw `<h1>`–`<h6>` elements to get consistent Mango UI typography
|
|
40
|
+
- **Use sparingly** — `MangoHeading` is intended for main page headings and major section titles. For body text, labels, captions, and supporting text, prefer Mango utility classes (`mgo-text-m`, `mgo-text-s`, `mgo-weight-strong`, etc.) or rely on default slot styling provided by the parent component.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bb-mango-icon
|
|
3
|
-
description: MangoIcon React component — renders an icon by name; use /
|
|
3
|
+
description: MangoIcon React component — renders an icon by name; use /bb-icons skill for icon names
|
|
4
4
|
allowed-tools: Read, Glob, Grep
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -40,6 +40,6 @@ import { MangoIcon } from '@intellihr/blueberry'
|
|
|
40
40
|
### Notes
|
|
41
41
|
|
|
42
42
|
- The `icon` prop maps to the `name` attribute on the underlying `mgo-icon` web component
|
|
43
|
-
- Use the `/
|
|
43
|
+
- Use the `/bb-icons` skill to look up available icon names
|
|
44
44
|
- Do not set a `library` attribute — the correct library is handled automatically
|
|
45
45
|
- For icon-only buttons, use `MangoIconButton` instead
|