@nexub/mcp 2.9.0 → 3.1.0
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/dist/skill/SKILL.md +19 -6
- package/dist/skill/references/components/badge.md +1 -1
- package/dist/skill/references/components/button.md +19 -1
- package/dist/skill/references/components/card.md +29 -2
- package/dist/skill/references/components/cta-band.md +34 -0
- package/dist/skill/references/components/eyebrow-chip.md +21 -1
- package/dist/skill/references/components/faq.md +35 -0
- package/dist/skill/references/components/feature-split.md +40 -0
- package/dist/skill/references/components/hero.md +44 -0
- package/dist/skill/references/components/how-it-works.md +35 -0
- package/dist/skill/references/components/logo-strip.md +35 -0
- package/dist/skill/references/components/marketing-footer.md +43 -0
- package/dist/skill/references/components/marketing-nav.md +63 -0
- package/dist/skill/references/components/motion-float.md +33 -0
- package/dist/skill/references/components/motion-marquee.md +35 -0
- package/dist/skill/references/components/motion-reveal.md +33 -0
- package/dist/skill/references/components/number-ticker.md +18 -0
- package/dist/skill/references/components/pricing-table.md +42 -0
- package/dist/skill/references/components/product-grid.md +39 -0
- package/dist/skill/references/components/section-header.md +35 -0
- package/dist/skill/references/components/stat-band.md +37 -0
- package/dist/skill/references/components/testimonial-grid.md +37 -0
- package/dist/skill/references/components/toast.md +1 -1
- package/dist/skill/references/components.md +20 -5
- package/dist/skill/references/tokens.md +3 -2
- package/package.json +1 -1
- package/dist/skill/references/components/banner.md +0 -43
- package/dist/skill/references/components/callout.md +0 -35
- package/dist/skill/references/components/status-pill.md +0 -43
- package/dist/skill/references/components/tag.md +0 -33
package/dist/skill/SKILL.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: nexub-ds
|
|
3
|
-
description: Build SaaS UI with the Nexub Design System (@nexub/react, @nexub/patterns, @nexub/tokens, @nexub/themes, @nexub/icons). Use when building or restyling any React screen, page, dashboard, form, settings page, auth flow, pricing page or component in a project that uses Nexub DS, or when the user asks for Nexub, Calm Depth or Liquid Glass UI.
|
|
3
|
+
description: Build SaaS UI with the Nexub Design System (@nexub/react, @nexub/patterns, @nexub/marketing, @nexub/tokens, @nexub/themes, @nexub/icons). Use when building or restyling any React screen, page, dashboard, form, settings page, auth flow, pricing page, marketing or landing page, or component in a project that uses Nexub DS, or when the user asks for Nexub, Calm Depth, marketing mode or Liquid Glass UI.
|
|
4
4
|
license: MIT
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Nexub Design System
|
|
8
8
|
|
|
9
|
-
Nexub DS is a token-driven React design system for SaaS products. The visual language is **Calm Depth**: tonal surfaces, one accent per view, spring motion, honest numbers. **Liquid Glass** is an optional material for the floating control layer.
|
|
9
|
+
Nexub DS is a token-driven React design system for SaaS products. The visual language is **Calm Depth**: tonal surfaces, one accent per view, spring motion, honest numbers. **Liquid Glass** is an optional material for the floating control layer. **Marketing mode** (`data-mode="marketing"`) is the livelier look for marketing sites, on the same tokens.
|
|
10
10
|
|
|
11
11
|
Reference files (read only what the task needs):
|
|
12
12
|
|
|
@@ -54,6 +54,8 @@ export default {
|
|
|
54
54
|
@source "../node_modules/@nexub/patterns/dist";
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
+
**Next.js App Router:** presentational components (Heading, Text, Container, Section, Stack, Badge, EyebrowChip, Logo, Float, Marquee and every `@nexub/marketing` section except `MarketingNav`, `PricingTable` and `FAQ`) are server components. Import per component (`@nexub/react/Button`, `@nexub/marketing/Hero`, `cn` from `@nexub/react/cn`) or set `experimental.optimizePackageImports: ['@nexub/react', '@nexub/marketing', '@nexub/icons']`, or the page ships every client component. Compound components (`Accordion.Root`, `TopNav.Root`) only work inside a `'use client'` file. To use `next/font`, import `@nexub/themes/core` (no fonts, no page backdrop) instead of `base` and name the font variables `--font-family-sans` and `--font-family-display`. With Tailwind, never also import `@nexub/react/styles.css`.
|
|
58
|
+
|
|
57
59
|
Wrap the app in `<ThemeProvider defaultTheme="system" storageKey="app-theme">` from `@nexub/react`. In server-rendered apps (Next.js), put `<ThemeScript storageKey="app-theme" />` in `<head>` and add `suppressHydrationWarning` to `<html>`. Product brands: set `data-product="leap" | "bookub" | "payub" | "founderub"` on the root. This remaps the `tertiary` role.
|
|
58
60
|
|
|
59
61
|
## 2. How to build a screen
|
|
@@ -76,13 +78,14 @@ Starting points for typical SaaS screens:
|
|
|
76
78
|
| Onboarding | `StepIndicator` + `CheckList` |
|
|
77
79
|
| Search / commands | `CommandPalette` + `KeyboardShortcut` |
|
|
78
80
|
| Empty, loading, error | `EmptyState`, `Skeleton`, `ErrorState`, `Toast` |
|
|
81
|
+
| Marketing / landing page | `@nexub/marketing` under `data-mode="marketing"`: `MarketingNav`, `Hero`, `LogoStrip`, `StatBand`, `FeatureSplit`, `HowItWorks`, `ProductGrid`, `TestimonialGrid`, `PricingTable`, `FAQ`, `CTABand`, `MarketingFooter` |
|
|
79
82
|
|
|
80
83
|
Money: use `Amount` and `MoneyInput`. They use tabular figures, the currency's own minor unit and a true minus sign. Icons: import from `@nexub/icons`, not `lucide-react` directly.
|
|
81
84
|
|
|
82
85
|
## 3. Calm Depth principles
|
|
83
86
|
|
|
84
87
|
1. **Content leads, chrome recedes.** Navigation is quieter than content. Remove a divider before you add one; let spacing and tone separate regions. Do: a tonal sidebar with no border, where the active item is a soft pill. Don't: a saturated brand-blue sidebar item, or a hard line around every region.
|
|
85
|
-
2. **Hierarchy through tone and layout, not decoration.** Surfaces step `surface` → `surface-container-*` → `surface-elevated`. Shadows are only for things that float. Product UI has no gradients, no colored icon tiles and no gradient eyebrow chips.
|
|
88
|
+
2. **Hierarchy through tone and layout, not decoration.** Surfaces step `surface` → `surface-container-*` → `surface-elevated`. Shadows are only for things that float. Product UI has no gradients, no colored icon tiles and no gradient eyebrow chips (those belong to marketing mode only).
|
|
86
89
|
3. **One accent, spent deliberately.** Each view gets one filled (primary) button. Everything else is `tonal`, `outlined` or `text`. Never put two filled buttons side by side.
|
|
87
90
|
4. **Physical, interruptible motion.** Use the spring tokens (`ease-spatial-default duration-spatial-default`), not raw durations. Exits are faster than entrances. Honor `prefers-reduced-motion`.
|
|
88
91
|
5. **Honest numbers and states.** Use tabular figures in data. Hover, pressed, selected and disabled are explicit component states. Never fake a state with opacity.
|
|
@@ -95,15 +98,25 @@ Money: use `Amount` and `MoneyInput`. They use tabular figures, the currency's o
|
|
|
95
98
|
- Never put glass on glass. Show at most three glass layers at a time. Tint only the one primary action (`data-glass-tint="primary"`).
|
|
96
99
|
- Never put white text on glass over an unknown background.
|
|
97
100
|
|
|
98
|
-
## 5.
|
|
101
|
+
## 5. Marketing mode rules
|
|
102
|
+
|
|
103
|
+
- Turn it on with `data-mode="marketing"` and `@nexub/themes/marketing`. Nothing outside the attribute changes; never use it in product UI.
|
|
104
|
+
- Gradients in three places only: the `Hero`, the main button (`Button variant="hero"`) and the `CTABand`.
|
|
105
|
+
- At most one `variant="hero"` button per screen; pair it with an outlined button.
|
|
106
|
+
- Product accents (`Card variant="showcase" accent="payub"`, `TestimonialCard accent`) only on product-specific content.
|
|
107
|
+
- Motion budget: one entrance per section (`Reveal` or the hero's rise), at most two `Float`s in view, one `Marquee` plus the footer's. All of it stops under reduced motion.
|
|
108
|
+
- Page width `Container size="marketing"` (1280px); headlines `text-display-xl` on the hero only; one h1 per page (the `Hero` title).
|
|
109
|
+
|
|
110
|
+
## 6. UI copy
|
|
99
111
|
|
|
100
112
|
Copy is clear, direct, human and confident. Use sentence case, active voice, contractions and specific verbs ("Save changes", not "Submit"). Errors say what happened and what to do: "Your session expired. Sign in again." No "Oops", no emoji in errors, no "Please be advised".
|
|
101
113
|
|
|
102
|
-
##
|
|
114
|
+
## 7. Before you finish
|
|
103
115
|
|
|
104
116
|
- [ ] Every control comes from `@nexub/react` or `@nexub/patterns`. No deprecated component (see the index).
|
|
105
117
|
- [ ] There are no hex or rgb colors, Tailwind palette colors, arbitrary px values or custom shadows. Everything is a token utility or `var(--…)`.
|
|
106
118
|
- [ ] Every background role is paired with its `on-` role. Secondary text uses `on-surface-variant` or `on-surface-muted`.
|
|
107
|
-
- [ ] Each view has at most one filled button.
|
|
119
|
+
- [ ] Each view has at most one filled button (marketing: at most one hero button).
|
|
120
|
+
- [ ] In Next.js, server pages import per component and use no compound component outside a `'use client'` file.
|
|
108
121
|
- [ ] The screen works in light and dark (`data-theme`) and at `data-contrast="high"`.
|
|
109
122
|
- [ ] Every input has a label. Icon-only buttons have an `aria-label`. Keyboard paths work.
|
|
@@ -89,4 +89,4 @@ export default function Example() {
|
|
|
89
89
|
- Reads as inline text. For live status changes, wrap in an element with `role="status"` and `aria-live="polite"`.
|
|
90
90
|
- For interactive equivalents (filtering, dismissing) reach for `Chip` or `FilterChip`.
|
|
91
91
|
|
|
92
|
-
Related: [chip](chip.md)
|
|
92
|
+
Related: [chip](chip.md)
|
|
@@ -24,7 +24,7 @@ Triggers an action or event. Supports multiple variants, sizes, and semantic ton
|
|
|
24
24
|
|
|
25
25
|
| Prop | Type | Default | Description |
|
|
26
26
|
| --- | --- | --- | --- |
|
|
27
|
-
| `variant` | `'filled' \| 'tonal' \| 'outlined' \| 'text' \| 'glass' \| 'subtle' \| 'link' \| 'destructive' \| 'accent'` | `'primary'` | Visual style of the button. Legacy aliases still work: primary = filled, secondary = tonal, outline = outlined, ghost = text. |
|
|
27
|
+
| `variant` | `'filled' \| 'tonal' \| 'outlined' \| 'text' \| 'glass' \| 'hero' \| 'subtle' \| 'link' \| 'destructive' \| 'accent'` | `'primary'` | Visual style of the button. `hero` is the marketing-mode main button (gradient, glow, spring lift): a filled button outside `data-mode="marketing"`; one per screen. Legacy aliases still work: primary = filled, secondary = tonal, outline = outlined, ghost = text. |
|
|
28
28
|
| `size` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Control height and padding. |
|
|
29
29
|
| `status` | `'idle' \| 'loading' \| 'success' \| 'error'` | `'idle'` | Async feedback (beta, 1.7.0). `loading` shows a spinner and blocks clicks but keeps focus; `success` draws a check; `error` shakes once. The label stays in flow, so the width holds. |
|
|
30
30
|
| `loading` | `boolean` | `false` | Alias for `status="loading"`. |
|
|
@@ -127,6 +127,24 @@ export default function Example() {
|
|
|
127
127
|
}
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
+
## Example: Hero (marketing mode)
|
|
131
|
+
|
|
132
|
+
Inside `data-mode="marketing"` with `@nexub/themes/marketing` loaded. The focus ring sits outside the gradient.
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
import { Button } from '@nexub/react';
|
|
136
|
+
import { ArrowRight } from '@nexub/icons';
|
|
137
|
+
|
|
138
|
+
export default function Example() {
|
|
139
|
+
return (
|
|
140
|
+
<div data-mode="marketing" className="flex flex-wrap items-center gap-3">
|
|
141
|
+
<Button variant="hero" size="lg" trailingIcon={<ArrowRight size={16} />}>Start free</Button>
|
|
142
|
+
<Button variant="outlined" size="lg">Book a demo</Button>
|
|
143
|
+
</div>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
130
148
|
## Accessibility
|
|
131
149
|
|
|
132
150
|
- Roles: button
|
|
@@ -10,7 +10,8 @@ Surface container for grouping related content. Supports flat, surface, and inte
|
|
|
10
10
|
|
|
11
11
|
| Prop | Type | Default | Description |
|
|
12
12
|
| --- | --- | --- | --- |
|
|
13
|
-
| `variant` | `'flat' \| 'surface' \| 'interactive'` | `'flat'` | `interactive` lifts 2px on hover (spatial spring, elevation 1 → 2), sinks to 0.99 on press and adds a state layer. Use it for cards that are links or buttons. |
|
|
13
|
+
| `variant` | `'flat' \| 'surface' \| 'interactive' \| 'showcase'` | `'flat'` | `interactive` lifts 2px on hover (spatial spring, elevation 1 → 2), sinks to 0.99 on press and adds a state layer. Use it for cards that are links or buttons. `showcase` is the marketing-mode card (24px corners, soft shadow, hover lift); a flat card outside `data-mode="marketing"`. |
|
|
14
|
+
| `accent` | `'leap' \| 'bookub' \| 'payub' \| 'founderub'` | | With `variant="showcase"`: a product-coloured top edge and tint in marketing mode. Sets `data-product` on the card. Only for product-specific content. |
|
|
14
15
|
| `effect` | `'none' \| 'sheen'` | `'none'` | Opt-in. `sheen` is a soft light that follows the pointer, with a brighter rim near the edge. Off for touch, reduced motion and reduced transparency. |
|
|
15
16
|
| `tone` | `ToneValue` | `undefined` | Applies a semantic left-border accent. |
|
|
16
17
|
| `asChild` | `boolean` | `false` | Merges props onto the immediate child element. |
|
|
@@ -95,6 +96,32 @@ export default function Example() {
|
|
|
95
96
|
}
|
|
96
97
|
```
|
|
97
98
|
|
|
99
|
+
## Example: Showcase (marketing mode)
|
|
100
|
+
|
|
101
|
+
Product accents on showcase cards, inside `data-mode="marketing"`.
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
import { Card } from '@nexub/react';
|
|
105
|
+
|
|
106
|
+
const products = [
|
|
107
|
+
{ accent: 'payub', name: 'Payub', line: 'Payroll and HR' },
|
|
108
|
+
{ accent: 'bookub', name: 'Bookub', line: 'Bookkeeping' },
|
|
109
|
+
] as const;
|
|
110
|
+
|
|
111
|
+
export default function Example() {
|
|
112
|
+
return (
|
|
113
|
+
<div data-mode="marketing" className="grid w-full gap-6 sm:grid-cols-2">
|
|
114
|
+
{products.map((p) => (
|
|
115
|
+
<Card key={p.name} variant="showcase" accent={p.accent} className="flex flex-col gap-2 p-6">
|
|
116
|
+
<h3 className="m-0 text-title-lg">{p.name}</h3>
|
|
117
|
+
<p className="m-0 text-body-md text-[var(--color-on-surface-variant)]">{p.line}</p>
|
|
118
|
+
</Card>
|
|
119
|
+
))}
|
|
120
|
+
</div>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
98
125
|
## Accessibility
|
|
99
126
|
|
|
100
127
|
- Roles: region (when used as a landmark)
|
|
@@ -103,4 +130,4 @@ export default function Example() {
|
|
|
103
130
|
- Prefer CardLink over wrapping the whole card in `<a>`: the link’s accessible name stays the title instead of every word on the card.
|
|
104
131
|
- Group related content with a heading inside the Card so AT users can navigate by heading level.
|
|
105
132
|
|
|
106
|
-
Related: [media-card](media-card.md), [radio-card](radio-card.md), [
|
|
133
|
+
Related: [media-card](media-card.md), [radio-card](radio-card.md), [alert](alert.md)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# CTABand
|
|
2
|
+
|
|
3
|
+
The closing call to action on a primary band: the hero gradient in marketing mode. Server component.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/marketing` · Category: Marketing · Status: beta
|
|
6
|
+
- Import: `import { CtaBand } from '@nexub/marketing';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/patterns/cta-band
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `title` (required) | `React.ReactNode` | | The heading (h2). |
|
|
14
|
+
| `description` | `React.ReactNode` | | One supporting line. |
|
|
15
|
+
| `actions` | `React.ReactNode` | | Buttons. On the band use `variant="filled" tone="neutral"` or an outlined button. |
|
|
16
|
+
|
|
17
|
+
## Example: Default
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { Button } from '@nexub/react';
|
|
21
|
+
import { CTABand } from '@nexub/marketing';
|
|
22
|
+
|
|
23
|
+
export default function Example() {
|
|
24
|
+
return (
|
|
25
|
+
<div data-mode="marketing" className="w-full">
|
|
26
|
+
<CTABand
|
|
27
|
+
title="Start running your company on Nexub"
|
|
28
|
+
description="Free for 30 days. No card needed."
|
|
29
|
+
actions={<Button variant="filled" tone="neutral" size="lg">Create an account</Button>}
|
|
30
|
+
/>
|
|
31
|
+
</div>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
```
|
|
@@ -10,7 +10,10 @@ A compact eyebrow label, typically used above headings.
|
|
|
10
10
|
|
|
11
11
|
| Prop | Type | Default | Description |
|
|
12
12
|
| --- | --- | --- | --- |
|
|
13
|
-
| `
|
|
13
|
+
| `tone` | `ToneValue` | `'neutral'` | Text colour. |
|
|
14
|
+
| `variant` | `'soft' \| 'gradient'` | `'soft'` | `gradient`: the marketing-mode chip; looks like `soft` outside `data-mode="marketing"`. |
|
|
15
|
+
| `live` | `boolean` | `false` | A decorative "live" dot before the label; it pings in marketing mode and stays still under reduced motion. |
|
|
16
|
+
| `leadingIcon` | `React.ReactNode` | | Icon before the label. |
|
|
14
17
|
|
|
15
18
|
## Example: Default
|
|
16
19
|
|
|
@@ -36,3 +39,20 @@ export default function Example() {
|
|
|
36
39
|
);
|
|
37
40
|
}
|
|
38
41
|
```
|
|
42
|
+
|
|
43
|
+
## Example: Gradient and live (marketing mode)
|
|
44
|
+
|
|
45
|
+
Inside `data-mode="marketing"`.
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { EyebrowChip } from '@nexub/react';
|
|
49
|
+
|
|
50
|
+
export default function Example() {
|
|
51
|
+
return (
|
|
52
|
+
<div data-mode="marketing" className="flex flex-wrap items-center gap-3">
|
|
53
|
+
<EyebrowChip variant="gradient" tone="info">Now in Vietnam</EyebrowChip>
|
|
54
|
+
<EyebrowChip variant="gradient" tone="success" live>Live</EyebrowChip>
|
|
55
|
+
</div>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# FAQ
|
|
2
|
+
|
|
3
|
+
Questions and answers in an Accordion, one open at a time. Client component.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/marketing` · Category: Marketing · Status: beta
|
|
6
|
+
- Import: `import { Faq } from '@nexub/marketing';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/patterns/faq
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `items` (required) | `{ question, answer }[]` | | The questions; answers can hold links. |
|
|
14
|
+
| `header` | `React.ReactNode` | | A SectionHeader, usually. |
|
|
15
|
+
|
|
16
|
+
## Example: Default
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import { FAQ, SectionHeader } from '@nexub/marketing';
|
|
20
|
+
|
|
21
|
+
export default function Example() {
|
|
22
|
+
return (
|
|
23
|
+
<div data-mode="marketing" className="w-full">
|
|
24
|
+
<FAQ
|
|
25
|
+
header={<SectionHeader title="Questions" />}
|
|
26
|
+
items={[
|
|
27
|
+
{ question: 'Which countries do you support?', answer: 'Singapore, India, Indonesia, Malaysia and Vietnam.' },
|
|
28
|
+
{ question: 'Can I switch plans later?', answer: 'Yes, at any time. We prorate the difference.' },
|
|
29
|
+
{ question: 'Is my data secure?', answer: 'Data is encrypted at rest and in transit, and stored in the region you choose.' },
|
|
30
|
+
]}
|
|
31
|
+
/>
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# FeatureSplit
|
|
2
|
+
|
|
3
|
+
Text and a check list beside a visual; `reverse` swaps the sides on wide screens. Server component.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/marketing` · Category: Marketing · Status: beta
|
|
6
|
+
- Import: `import { FeatureSplit } from '@nexub/marketing';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/patterns/feature-split
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `title` (required) | `React.ReactNode` | | The heading (h2). |
|
|
14
|
+
| `visual` (required) | `React.ReactNode` | | Screenshot or illustration. |
|
|
15
|
+
| `eyebrow` | `React.ReactNode` | | A string becomes a gradient EyebrowChip. |
|
|
16
|
+
| `description` | `React.ReactNode` | | Body copy. |
|
|
17
|
+
| `points` | `string[]` | | Benefit lines, shown as a check list. |
|
|
18
|
+
| `actions` | `React.ReactNode` | | Buttons. |
|
|
19
|
+
| `reverse` | `boolean` | `false` | Visual on the left on wide screens. |
|
|
20
|
+
|
|
21
|
+
## Example: Default
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { Card } from '@nexub/react';
|
|
25
|
+
import { FeatureSplit } from '@nexub/marketing';
|
|
26
|
+
|
|
27
|
+
export default function Example() {
|
|
28
|
+
return (
|
|
29
|
+
<div data-mode="marketing" className="w-full">
|
|
30
|
+
<FeatureSplit
|
|
31
|
+
eyebrow="Payroll"
|
|
32
|
+
title="Pay your team on time, every time"
|
|
33
|
+
description="Run payroll in minutes with tax and statutory filings handled for you."
|
|
34
|
+
points={['CPF, EPF and BPJS filed for you', 'Payslips in every employee’s language', 'Approvals on your phone']}
|
|
35
|
+
visual={<Card variant="showcase" accent="payub" className="aspect-[4/3] w-full" aria-label="Payroll screenshot" />}
|
|
36
|
+
/>
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Hero
|
|
2
|
+
|
|
3
|
+
The page hero: ambient backdrop, eyebrow, display headline (the page's one h1), lead, actions and a visual. Server component.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/marketing` · Category: Marketing · Status: beta
|
|
6
|
+
- Import: `import { Hero } from '@nexub/marketing';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/patterns/hero
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `title` (required) | `React.ReactNode` | | The headline, rendered as the h1. |
|
|
14
|
+
| `eyebrow` | `React.ReactNode` | | A string becomes a gradient EyebrowChip. |
|
|
15
|
+
| `description` | `React.ReactNode` | | The lead paragraph. |
|
|
16
|
+
| `actions` | `React.ReactNode` | | One `Button variant="hero"` and one outlined button, usually. |
|
|
17
|
+
| `visual` | `React.ReactNode` | | Product shot or illustration. Beside the text on wide screens with `align="start"`. |
|
|
18
|
+
| `align` | `'center' \| 'start'` | `'center'` | Text alignment and layout. |
|
|
19
|
+
|
|
20
|
+
## Example: Default
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { Button } from '@nexub/react';
|
|
24
|
+
import { Hero } from '@nexub/marketing';
|
|
25
|
+
import { ArrowRight } from '@nexub/icons';
|
|
26
|
+
|
|
27
|
+
export default function Example() {
|
|
28
|
+
return (
|
|
29
|
+
<div data-mode="marketing" className="w-full">
|
|
30
|
+
<Hero
|
|
31
|
+
eyebrow="Now in Vietnam"
|
|
32
|
+
title="Run your whole company in one place"
|
|
33
|
+
description="Payroll, bookkeeping and compliance for growing teams across Southeast Asia and India."
|
|
34
|
+
actions={
|
|
35
|
+
<>
|
|
36
|
+
<Button variant="hero" size="lg" trailingIcon={<ArrowRight size={16} />}>Start free</Button>
|
|
37
|
+
<Button variant="outlined" size="lg">Book a demo</Button>
|
|
38
|
+
</>
|
|
39
|
+
}
|
|
40
|
+
/>
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# HowItWorks
|
|
2
|
+
|
|
3
|
+
Numbered steps in an ordered list. Server component.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/marketing` · Category: Marketing · Status: beta
|
|
6
|
+
- Import: `import { HowItWorks } from '@nexub/marketing';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/patterns/how-it-works
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `steps` (required) | `{ title, description, icon? }[]` | | The steps; the number shows unless an icon is given. |
|
|
14
|
+
| `header` | `React.ReactNode` | | A SectionHeader, usually. |
|
|
15
|
+
|
|
16
|
+
## Example: Default
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import { HowItWorks, SectionHeader } from '@nexub/marketing';
|
|
20
|
+
|
|
21
|
+
export default function Example() {
|
|
22
|
+
return (
|
|
23
|
+
<div data-mode="marketing" className="w-full">
|
|
24
|
+
<HowItWorks
|
|
25
|
+
header={<SectionHeader title="Up and running in a day" />}
|
|
26
|
+
steps={[
|
|
27
|
+
{ title: 'Create your account', description: 'Sign up with your company details.' },
|
|
28
|
+
{ title: 'Invite your team', description: 'Add people and their bank details.' },
|
|
29
|
+
{ title: 'Run your first payroll', description: 'Review, approve and pay.' },
|
|
30
|
+
]}
|
|
31
|
+
/>
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# LogoStrip
|
|
2
|
+
|
|
3
|
+
A row of customer logos under the hero, scrolling sideways (paused on hover and focus) or wrapped. Server component.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/marketing` · Category: Marketing · Status: beta
|
|
6
|
+
- Import: `import { LogoStrip } from '@nexub/marketing';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/patterns/logo-strip
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `label` | `React.ReactNode` | | e.g. "Trusted by 2,000+ teams". |
|
|
14
|
+
| `scroll` | `boolean` | `true` | Scroll the logos (marketing mode only); off gives a wrapped row. |
|
|
15
|
+
| `children` (required) | `React.ReactNode` | | The logos. Give each its alt text. |
|
|
16
|
+
|
|
17
|
+
## Example: Default
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { LogoStrip } from '@nexub/marketing';
|
|
21
|
+
|
|
22
|
+
const customers = ['Acme', 'Globex', 'Initech', 'Umbrella', 'Hooli', 'Vandelay'];
|
|
23
|
+
|
|
24
|
+
export default function Example() {
|
|
25
|
+
return (
|
|
26
|
+
<div data-mode="marketing" className="w-full">
|
|
27
|
+
<LogoStrip label="Trusted by 2,000+ teams">
|
|
28
|
+
{customers.map((name) => (
|
|
29
|
+
<span key={name} className="text-title-lg text-[var(--color-on-surface-muted)]">{name}</span>
|
|
30
|
+
))}
|
|
31
|
+
</LogoStrip>
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# MarketingFooter
|
|
2
|
+
|
|
3
|
+
The site footer: a tools strip, the logo, link columns and the legal line. Server component.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/marketing` · Category: Marketing · Status: beta
|
|
6
|
+
- Import: `import { MarketingFooter } from '@nexub/marketing';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/patterns/marketing-footer
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `columns` (required) | `{ title, links: { label, href }[] }[]` | | Link columns, each a labelled nav. |
|
|
14
|
+
| `logo` | `React.ReactNode` | | Logo. |
|
|
15
|
+
| `tagline` | `React.ReactNode` | | A line under the logo. |
|
|
16
|
+
| `tools` | `React.ReactNode[]` | | Tools or integrations, scrolling in a strip. |
|
|
17
|
+
| `toolsLabel` | `string` | `'Works with'` | Label of the tools strip. |
|
|
18
|
+
| `bottom` | `React.ReactNode` | | Copyright and legal links. |
|
|
19
|
+
|
|
20
|
+
## Example: Default
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { Logo } from '@nexub/react';
|
|
24
|
+
import { MarketingFooter } from '@nexub/marketing';
|
|
25
|
+
|
|
26
|
+
export default function Example() {
|
|
27
|
+
return (
|
|
28
|
+
<div data-mode="marketing" className="w-full">
|
|
29
|
+
<MarketingFooter
|
|
30
|
+
logo={<Logo size="sm" />}
|
|
31
|
+
tagline="The operating system for growing companies."
|
|
32
|
+
tools={['Slack', 'Xero', 'Google Workspace', 'Stripe', 'QuickBooks', 'WhatsApp']}
|
|
33
|
+
columns={[
|
|
34
|
+
{ title: 'Products', links: [{ label: 'Payub', href: '#payub' }, { label: 'Bookub', href: '#bookub' }, { label: 'Leap', href: '#leap' }] },
|
|
35
|
+
{ title: 'Company', links: [{ label: 'About', href: '#about' }, { label: 'Careers', href: '#careers' }] },
|
|
36
|
+
{ title: 'Resources', links: [{ label: 'Help centre', href: '#help' }, { label: 'Status', href: '#status' }] },
|
|
37
|
+
]}
|
|
38
|
+
bottom="© 2026 Nexub Pte. Ltd., Singapore"
|
|
39
|
+
/>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
```
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# MarketingNav
|
|
2
|
+
|
|
3
|
+
The site header: logo, links with mega-menus, a country switcher and actions. Below `lg` the links move into a side sheet.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/marketing` · Category: Marketing · Status: beta
|
|
6
|
+
- Import: `import { MarketingNav } from '@nexub/marketing';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/patterns/marketing-nav
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `logo` (required) | `React.ReactNode` | | Logo, wrapped in a link to `logoHref`. |
|
|
14
|
+
| `items` (required) | `MarketingNavItem[]` | | Links; an item with `items` opens a mega-menu of links with descriptions. |
|
|
15
|
+
| `countries` | `MarketingCountry[]` | | Country sites: `{ code, label, href }`. The switcher shows when there are two or more. |
|
|
16
|
+
| `country` | `string` | | Current country code. |
|
|
17
|
+
| `actions` | `React.ReactNode` | | Sign in / Get started buttons. |
|
|
18
|
+
| `logoHref` | `string` | `'/'` | Where the logo links. |
|
|
19
|
+
| `menuLabel` | `string` | `'Open menu'` | Accessible name of the mobile menu button. |
|
|
20
|
+
|
|
21
|
+
## Example: Default
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { Button, Logo } from '@nexub/react';
|
|
25
|
+
import { MarketingNav } from '@nexub/marketing';
|
|
26
|
+
|
|
27
|
+
export default function Example() {
|
|
28
|
+
return (
|
|
29
|
+
<div data-mode="marketing" className="w-full">
|
|
30
|
+
<MarketingNav
|
|
31
|
+
logo={<Logo size="sm" />}
|
|
32
|
+
items={[
|
|
33
|
+
{
|
|
34
|
+
label: 'Products',
|
|
35
|
+
items: [
|
|
36
|
+
{ label: 'Payub', href: '#payub', description: 'Payroll and HR' },
|
|
37
|
+
{ label: 'Bookub', href: '#bookub', description: 'Bookkeeping' },
|
|
38
|
+
{ label: 'Leap', href: '#leap', description: 'Company formation' },
|
|
39
|
+
{ label: 'Founderub', href: '#founderub', description: 'Founder tools' },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{ label: 'Pricing', href: '#pricing' },
|
|
43
|
+
{ label: 'Customers', href: '#customers' },
|
|
44
|
+
]}
|
|
45
|
+
countries={[
|
|
46
|
+
{ code: 'SG', label: 'Singapore', href: '#sg' },
|
|
47
|
+
{ code: 'IN', label: 'India', href: '#in' },
|
|
48
|
+
{ code: 'ID', label: 'Indonesia', href: '#id' },
|
|
49
|
+
{ code: 'MY', label: 'Malaysia', href: '#my' },
|
|
50
|
+
{ code: 'VN', label: 'Vietnam', href: '#vn' },
|
|
51
|
+
]}
|
|
52
|
+
country="SG"
|
|
53
|
+
actions={
|
|
54
|
+
<>
|
|
55
|
+
<Button variant="text" size="sm" asChild><a href="#signin">Sign in</a></Button>
|
|
56
|
+
<Button variant="filled" size="sm" asChild><a href="#start">Get started</a></Button>
|
|
57
|
+
</>
|
|
58
|
+
}
|
|
59
|
+
/>
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Float
|
|
2
|
+
|
|
3
|
+
Gently bobs its content (floating cards over a hero visual), in marketing mode. Server component; still under reduced motion.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Motion · Status: beta
|
|
6
|
+
- Import: `import { MotionFloat } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/motion-float
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `speed` | `'normal' \| 'slow'` | `'normal'` | `slow` drifts on a longer, reversed loop, so two floating cards don’t move in step. |
|
|
14
|
+
| `asChild` | `boolean` | `false` | Merge onto the child element instead of a div. |
|
|
15
|
+
|
|
16
|
+
## Example: Default
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import { Card, Float } from '@nexub/react';
|
|
20
|
+
|
|
21
|
+
export default function Example() {
|
|
22
|
+
return (
|
|
23
|
+
<div data-mode="marketing" className="flex gap-8 p-6">
|
|
24
|
+
<Float>
|
|
25
|
+
<Card variant="showcase" className="nx-mkt-float-card p-5">Payroll approved</Card>
|
|
26
|
+
</Float>
|
|
27
|
+
<Float speed="slow">
|
|
28
|
+
<Card variant="showcase" className="nx-mkt-float-card p-5">Books closed</Card>
|
|
29
|
+
</Float>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Marquee
|
|
2
|
+
|
|
3
|
+
A row that scrolls sideways forever (logo strips, tool lists), in marketing mode. Pauses on hover and while focus is inside, stands still under reduced motion; the repeated copy is hidden from assistive tech and can’t be focused. Server component.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Motion · Status: beta
|
|
6
|
+
- Import: `import { MotionMarquee } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/motion-marquee
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `speed` | `'slow' \| 'normal' \| 'fast'` | `'normal'` | Loop length: 44s, 28s or 18s. |
|
|
14
|
+
| `rowClassName` | `string` | `'gap-12 pe-12 items-center'` | Classes for each copy of the row. |
|
|
15
|
+
| `children` (required) | `React.ReactNode` | | The items. |
|
|
16
|
+
|
|
17
|
+
## Example: Default
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { Marquee } from '@nexub/react';
|
|
21
|
+
|
|
22
|
+
const tools = ['Slack', 'Xero', 'Google Workspace', 'Stripe', 'QuickBooks', 'WhatsApp'];
|
|
23
|
+
|
|
24
|
+
export default function Example() {
|
|
25
|
+
return (
|
|
26
|
+
<div data-mode="marketing" className="w-full">
|
|
27
|
+
<Marquee>
|
|
28
|
+
{tools.map((t) => (
|
|
29
|
+
<span key={t} className="text-title-md text-[var(--color-on-surface-variant)]">{t}</span>
|
|
30
|
+
))}
|
|
31
|
+
</Marquee>
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Reveal
|
|
2
|
+
|
|
3
|
+
Fades its content up as it scrolls into view, in marketing mode. CSS scroll-driven where supported, an IntersectionObserver elsewhere; content on screen at load, and every visitor without JS or with reduced motion, just sees it.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Motion · Status: beta
|
|
6
|
+
- Import: `import { MotionReveal } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/motion-reveal
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `asChild` | `boolean` | `false` | Merge onto the child element instead of a div. |
|
|
14
|
+
| `children` (required) | `React.ReactNode` | | Content to reveal. |
|
|
15
|
+
|
|
16
|
+
## Example: Default
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import { Card, Reveal } from '@nexub/react';
|
|
20
|
+
|
|
21
|
+
export default function Example() {
|
|
22
|
+
return (
|
|
23
|
+
<div data-mode="marketing" className="flex h-64 w-full flex-col gap-6 overflow-y-auto p-2">
|
|
24
|
+
<p className="m-0 shrink-0 pb-40 text-body-md text-[var(--color-on-surface-variant)]">Scroll down</p>
|
|
25
|
+
{[1, 2, 3].map((n) => (
|
|
26
|
+
<Reveal key={n} className="shrink-0">
|
|
27
|
+
<Card variant="showcase" className="p-6">Section {n}</Card>
|
|
28
|
+
</Reveal>
|
|
29
|
+
))}
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
@@ -14,6 +14,7 @@ A number whose digits roll to new values on the spatial spring. The first render
|
|
|
14
14
|
| `format` | `Intl.NumberFormatOptions` | | Formatting for a number `value`. |
|
|
15
15
|
| `locale` | `string` | | BCP 47 locale. Defaults to the user's. |
|
|
16
16
|
| `aria-live` | `'off' \| 'polite'` | `'off'` | Announce changes to screen readers. Use `polite` only for values the user is waiting on. |
|
|
17
|
+
| `countOnView` | `boolean` | `false` | Count up from zeros when the ticker first scrolls into view (3.1). Only for a ticker that starts below the fold; the server HTML and screen readers always get the real value. Off under reduced motion. |
|
|
17
18
|
|
|
18
19
|
## Example: Formatted number
|
|
19
20
|
|
|
@@ -57,6 +58,23 @@ export default function Example() {
|
|
|
57
58
|
}
|
|
58
59
|
```
|
|
59
60
|
|
|
61
|
+
## Example: Count on view
|
|
62
|
+
|
|
63
|
+
Scroll the preview so the number enters the view; it counts up once.
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { NumberTicker } from '@nexub/react';
|
|
67
|
+
|
|
68
|
+
export default function Example() {
|
|
69
|
+
return (
|
|
70
|
+
<div className="flex h-48 w-full flex-col overflow-y-auto">
|
|
71
|
+
<p className="m-0 shrink-0 pb-64 text-body-md text-[var(--color-on-surface-variant)]">Scroll down</p>
|
|
72
|
+
<NumberTicker value={2000} countOnView className="shrink-0 text-display-sm" />
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
60
78
|
## Accessibility
|
|
61
79
|
|
|
62
80
|
- The full value is read as one string; the rolling digits are hidden from assistive tech.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# PricingTable
|
|
2
|
+
|
|
3
|
+
Plans side by side with a monthly / yearly switch, built on PlanCard and SegmentedControl. Client component.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/marketing` · Category: Marketing · Status: beta
|
|
6
|
+
- Import: `import { PricingTable } from '@nexub/marketing';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/patterns/pricing-table
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `plans` (required) | `PricingPlan[]` | | Each plan: `name`, `price: { monthly, yearly }` per month, `features`, `cta`, and `href` or `onSelect`; `highlighted` and `badge` optional. |
|
|
14
|
+
| `currency` (required) | `string` | | ISO 4217 code. |
|
|
15
|
+
| `locale` | `string` | | BCP 47 locale for the prices. |
|
|
16
|
+
| `defaultPeriod` | `'monthly' \| 'yearly'` | `'monthly'` | Billing period shown first. |
|
|
17
|
+
| `periodLabels` | `Record<BillingPeriod, string>` | | Labels of the switch. |
|
|
18
|
+
| `perMonthLabel` | `string` | `'/month'` | Shown after each price. |
|
|
19
|
+
| `header` | `React.ReactNode` | | A SectionHeader, usually. |
|
|
20
|
+
|
|
21
|
+
## Example: Default
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { PricingTable, SectionHeader } from '@nexub/marketing';
|
|
25
|
+
|
|
26
|
+
export default function Example() {
|
|
27
|
+
return (
|
|
28
|
+
<div data-mode="marketing" className="w-full">
|
|
29
|
+
<PricingTable
|
|
30
|
+
header={<SectionHeader title="Simple pricing" description="Save two months with yearly billing." />}
|
|
31
|
+
currency="SGD"
|
|
32
|
+
locale="en-SG"
|
|
33
|
+
plans={[
|
|
34
|
+
{ name: 'Starter', price: { monthly: 29, yearly: 24 }, features: ['Up to 10 people', 'Payroll', 'Email support'], cta: 'Start free', href: '#starter' },
|
|
35
|
+
{ name: 'Growth', price: { monthly: 79, yearly: 66 }, features: ['Up to 100 people', 'Payroll and HR', 'Bookkeeping'], cta: 'Start free', href: '#growth', highlighted: true, badge: 'Most popular' },
|
|
36
|
+
{ name: 'Scale', price: { monthly: 199, yearly: 166 }, features: ['Unlimited people', 'All products', 'Dedicated manager'], cta: 'Talk to sales', href: '#scale' },
|
|
37
|
+
]}
|
|
38
|
+
/>
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# ProductGrid
|
|
2
|
+
|
|
3
|
+
Product cards in a grid; each card is one link with the product's accent. Server component.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/marketing` · Category: Marketing · Status: beta
|
|
6
|
+
- Import: `import { ProductGrid } from '@nexub/marketing';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/patterns/product-grid
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `header` | `React.ReactNode` | | ProductGrid: a SectionHeader, usually. |
|
|
14
|
+
| `name` (required) | `string` | | ProductCard: product name, the card's link text. |
|
|
15
|
+
| `description` (required) | `React.ReactNode` | | ProductCard: one line on what it does. |
|
|
16
|
+
| `href` (required) | `string` | | ProductCard: the product page. |
|
|
17
|
+
| `icon` | `React.ReactNode` | | ProductCard: the product mark. |
|
|
18
|
+
| `accent` | `'leap' \| 'bookub' \| 'payub' \| 'founderub'` | | ProductCard: coloured top edge and tint in marketing mode. |
|
|
19
|
+
| `linkLabel` | `string` | `'Learn more'` | ProductCard: the visual link cue. |
|
|
20
|
+
|
|
21
|
+
## Example: Default
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { BookubMark, FounderubMark, LeapMark, PayubMark } from '@nexub/icons';
|
|
25
|
+
import { ProductCard, ProductGrid, SectionHeader } from '@nexub/marketing';
|
|
26
|
+
|
|
27
|
+
export default function Example() {
|
|
28
|
+
return (
|
|
29
|
+
<div data-mode="marketing" className="w-full">
|
|
30
|
+
<ProductGrid header={<SectionHeader eyebrow="Platform" title="One account, four products" />}>
|
|
31
|
+
<ProductCard name="Leap" description="Incorporate and stay compliant." href="#leap" accent="leap" icon={<LeapMark size={24} />} />
|
|
32
|
+
<ProductCard name="Bookub" description="Bookkeeping that closes itself." href="#bookub" accent="bookub" icon={<BookubMark size={24} />} />
|
|
33
|
+
<ProductCard name="Payub" description="Payroll and HR in one place." href="#payub" accent="payub" icon={<PayubMark size={24} />} />
|
|
34
|
+
<ProductCard name="Founderub" description="Cap table and fundraising." href="#founderub" accent="founderub" icon={<FounderubMark size={24} />} />
|
|
35
|
+
</ProductGrid>
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# SectionHeader
|
|
2
|
+
|
|
3
|
+
Eyebrow, headline and lead that open a section. Server component.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/marketing` · Category: Marketing · Status: beta
|
|
6
|
+
- Import: `import { SectionHeader } from '@nexub/marketing';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/patterns/section-header
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `title` (required) | `React.ReactNode` | | The section heading (h2 by default). |
|
|
14
|
+
| `eyebrow` | `React.ReactNode` | | A string becomes a gradient EyebrowChip. |
|
|
15
|
+
| `description` | `React.ReactNode` | | The lead paragraph. |
|
|
16
|
+
| `align` | `'center' \| 'start'` | `'center'` | Alignment. |
|
|
17
|
+
| `level` | `2 \| 3` | `2` | Heading level. |
|
|
18
|
+
|
|
19
|
+
## Example: Default
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { SectionHeader } from '@nexub/marketing';
|
|
23
|
+
|
|
24
|
+
export default function Example() {
|
|
25
|
+
return (
|
|
26
|
+
<div data-mode="marketing" className="w-full py-10">
|
|
27
|
+
<SectionHeader
|
|
28
|
+
eyebrow="Platform"
|
|
29
|
+
title="Everything your company needs"
|
|
30
|
+
description="Four products on one account, one login and one bill."
|
|
31
|
+
/>
|
|
32
|
+
</div>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# StatBand
|
|
2
|
+
|
|
3
|
+
A band of headline numbers that count up as they scroll into view. StatBandItem is named apart from the StatCard pattern. Server component.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/marketing` · Category: Marketing · Status: beta
|
|
6
|
+
- Import: `import { StatBand } from '@nexub/marketing';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/patterns/stat-band
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `title` | `React.ReactNode` | | StatBand: a heading above the stats. |
|
|
14
|
+
| `value` (required) | `number \| string` | | StatBandItem: a number counts up from zeros when it scrolls into view; the server HTML keeps the real value. |
|
|
15
|
+
| `label` (required) | `React.ReactNode` | | StatBandItem: what the number counts. |
|
|
16
|
+
| `prefix / suffix` | `string` | | StatBandItem: e.g. "$" or "+". |
|
|
17
|
+
| `tone` | `ToneValue` | `'info'` | StatBandItem: the number's colour (accent roles, AA as large text). |
|
|
18
|
+
| `format` | `Intl.NumberFormatOptions` | | StatBandItem: number formatting. |
|
|
19
|
+
|
|
20
|
+
## Example: Default
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { StatBand, StatBandItem } from '@nexub/marketing';
|
|
24
|
+
|
|
25
|
+
export default function Example() {
|
|
26
|
+
return (
|
|
27
|
+
<div data-mode="marketing" className="w-full">
|
|
28
|
+
<StatBand title="Teams run on Nexub">
|
|
29
|
+
<StatBandItem value={2000} suffix="+" label="Companies" />
|
|
30
|
+
<StatBandItem value={5} label="Countries" tone="success" />
|
|
31
|
+
<StatBandItem value={98} suffix="%" label="On-time payroll" tone="payub" />
|
|
32
|
+
<StatBandItem value={4.9} label="Average rating" tone="founderub" format={{ minimumFractionDigits: 1 }} />
|
|
33
|
+
</StatBand>
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# TestimonialGrid
|
|
2
|
+
|
|
3
|
+
Customer quotes in product-coloured cards, with an optional star rating. Server component.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/marketing` · Category: Marketing · Status: beta
|
|
6
|
+
- Import: `import { TestimonialGrid } from '@nexub/marketing';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/patterns/testimonial-grid
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `header` | `React.ReactNode` | | TestimonialGrid: a SectionHeader, usually. |
|
|
14
|
+
| `quote` (required) | `React.ReactNode` | | TestimonialCard: the quote. |
|
|
15
|
+
| `name` (required) | `string` | | TestimonialCard: who said it. |
|
|
16
|
+
| `role` | `React.ReactNode` | | TestimonialCard: job title and company. |
|
|
17
|
+
| `avatarSrc` | `string` | | TestimonialCard: photo; initials otherwise. |
|
|
18
|
+
| `rating` | `number` | | TestimonialCard: stars out of 5, announced as "Rated n out of 5". |
|
|
19
|
+
| `accent` | `'leap' \| 'bookub' \| 'payub' \| 'founderub'` | | TestimonialCard: the product the customer uses. |
|
|
20
|
+
|
|
21
|
+
## Example: Default
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { SectionHeader, TestimonialCard, TestimonialGrid } from '@nexub/marketing';
|
|
25
|
+
|
|
26
|
+
export default function Example() {
|
|
27
|
+
return (
|
|
28
|
+
<div data-mode="marketing" className="w-full">
|
|
29
|
+
<TestimonialGrid header={<SectionHeader eyebrow="Customers" title="Loved by finance teams" />}>
|
|
30
|
+
<TestimonialCard accent="payub" rating={5} name="Priya Nair" role="Head of People, Kopi Labs" quote="Payroll used to take two days. Now it takes twenty minutes." />
|
|
31
|
+
<TestimonialCard accent="bookub" rating={5} name="Daniel Tan" role="CFO, Harbourline" quote="Our books close on the third working day, every month." />
|
|
32
|
+
<TestimonialCard accent="leap" rating={5} name="Linh Pham" role="Founder, Sonvo" quote="We incorporated in Singapore without leaving Hanoi." />
|
|
33
|
+
</TestimonialGrid>
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
```
|
|
@@ -17,7 +17,7 @@ Imperative toast notifications using the toast object. Render <Toaster /> once i
|
|
|
17
17
|
|
|
18
18
|
- Critical errors that block the user — use Alert or AlertDialog
|
|
19
19
|
- Information the user must read and acknowledge — use Dialog
|
|
20
|
-
- Persistent status that should remain visible — use
|
|
20
|
+
- Persistent status that should remain visible — use Alert
|
|
21
21
|
- Long messages with multiple lines of text
|
|
22
22
|
|
|
23
23
|
## Props
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Component index
|
|
2
2
|
|
|
3
|
-
Nexub DS
|
|
3
|
+
Nexub DS v3.1.0. Open `components/<slug>.md` for props, examples and accessibility notes.
|
|
4
4
|
Never use a component marked deprecated.
|
|
5
5
|
|
|
6
6
|
## Components — Actions
|
|
@@ -46,8 +46,6 @@ Never use a component marked deprecated.
|
|
|
46
46
|
## Components — Feedback
|
|
47
47
|
|
|
48
48
|
- [Alert](components/alert.md) `@nexub/react`: Inline contextual message with optional title, icon, and dismiss action.
|
|
49
|
-
- [Banner](components/banner.md) `@nexub/react` **(deprecated)**: Deprecated — use Alert. Full-width announcement banner, typically used at the top of a page.
|
|
50
|
-
- [Callout](components/callout.md) `@nexub/react` **(deprecated)**: Deprecated — use Alert. Highlighted content block for tips, warnings, or notes.
|
|
51
49
|
- [Spinner](components/spinner.md) `@nexub/react`: Animated loading indicator. Inherits color from context.
|
|
52
50
|
- [Toast](components/toast.md) `@nexub/react`: Imperative toast notifications using the toast object. Render <Toaster /> once in your layout.
|
|
53
51
|
|
|
@@ -97,8 +95,6 @@ Never use a component marked deprecated.
|
|
|
97
95
|
- [Chip](components/chip.md) `@nexub/react`: Compact label chip, optionally dismissible.
|
|
98
96
|
- [Eyebrow Chip](components/eyebrow-chip.md) `@nexub/react`: A compact eyebrow label, typically used above headings.
|
|
99
97
|
- [Filter Chip](components/filter-chip.md) `@nexub/react`: Interactive chip for filtering, supports selected/unselected state.
|
|
100
|
-
- [Status Pill](components/status-pill.md) `@nexub/react` **(deprecated)**: Deprecated — use Badge. A pill indicator for status values like active, pending, error.
|
|
101
|
-
- [Tag](components/tag.md) `@nexub/react` **(deprecated)**: Deprecated — use Badge. Non-interactive label tag for categorisation.
|
|
102
98
|
|
|
103
99
|
## Components — Layout
|
|
104
100
|
|
|
@@ -118,6 +114,9 @@ Never use a component marked deprecated.
|
|
|
118
114
|
|
|
119
115
|
- [Collapse](components/motion-collapse.md) `@nexub/react`: Expands and collapses content along the block axis.
|
|
120
116
|
- [Fade](components/motion-fade.md) `@nexub/react`: Animates opacity between 0 and 1 based on the `in` prop.
|
|
117
|
+
- [Float](components/motion-float.md) `@nexub/react`: Gently bobs its content (floating cards over a hero visual), in marketing mode. Server component; still under reduced motion.
|
|
118
|
+
- [Marquee](components/motion-marquee.md) `@nexub/react`: A row that scrolls sideways forever (logo strips, tool lists), in marketing mode. Pauses on hover and while focus is inside, stands still under reduced motion; the repeated copy is hidden from assistive tech and can’t be focused. Server component.
|
|
119
|
+
- [Reveal](components/motion-reveal.md) `@nexub/react`: Fades its content up as it scrolls into view, in marketing mode. CSS scroll-driven where supported, an IntersectionObserver elsewhere; content on screen at load, and every visitor without JS or with reduced motion, just sees it.
|
|
121
120
|
- [Scale](components/motion-scale.md) `@nexub/react`: Scales content in/out from its center.
|
|
122
121
|
- [Slide](components/motion-slide.md) `@nexub/react`: Slides content in from a direction based on the `in` prop.
|
|
123
122
|
|
|
@@ -143,6 +142,22 @@ Never use a component marked deprecated.
|
|
|
143
142
|
- [Heading](components/heading.md) `@nexub/react`: Semantic heading component with size, weight, and tone control.
|
|
144
143
|
- [Text](components/text.md) `@nexub/react`: Paragraph text component with size, tone, and weight variants.
|
|
145
144
|
|
|
145
|
+
## Marketing — Marketing
|
|
146
|
+
|
|
147
|
+
- [CTABand](components/cta-band.md) `@nexub/marketing`: The closing call to action on a primary band: the hero gradient in marketing mode. Server component.
|
|
148
|
+
- [FAQ](components/faq.md) `@nexub/marketing`: Questions and answers in an Accordion, one open at a time. Client component.
|
|
149
|
+
- [FeatureSplit](components/feature-split.md) `@nexub/marketing`: Text and a check list beside a visual; `reverse` swaps the sides on wide screens. Server component.
|
|
150
|
+
- [Hero](components/hero.md) `@nexub/marketing`: The page hero: ambient backdrop, eyebrow, display headline (the page's one h1), lead, actions and a visual. Server component.
|
|
151
|
+
- [HowItWorks](components/how-it-works.md) `@nexub/marketing`: Numbered steps in an ordered list. Server component.
|
|
152
|
+
- [LogoStrip](components/logo-strip.md) `@nexub/marketing`: A row of customer logos under the hero, scrolling sideways (paused on hover and focus) or wrapped. Server component.
|
|
153
|
+
- [MarketingFooter](components/marketing-footer.md) `@nexub/marketing`: The site footer: a tools strip, the logo, link columns and the legal line. Server component.
|
|
154
|
+
- [MarketingNav](components/marketing-nav.md) `@nexub/marketing`: The site header: logo, links with mega-menus, a country switcher and actions. Below `lg` the links move into a side sheet.
|
|
155
|
+
- [PricingTable](components/pricing-table.md) `@nexub/marketing`: Plans side by side with a monthly / yearly switch, built on PlanCard and SegmentedControl. Client component.
|
|
156
|
+
- [ProductGrid](components/product-grid.md) `@nexub/marketing`: Product cards in a grid; each card is one link with the product's accent. Server component.
|
|
157
|
+
- [SectionHeader](components/section-header.md) `@nexub/marketing`: Eyebrow, headline and lead that open a section. Server component.
|
|
158
|
+
- [StatBand](components/stat-band.md) `@nexub/marketing`: A band of headline numbers that count up as they scroll into view. StatBandItem is named apart from the StatCard pattern. Server component.
|
|
159
|
+
- [TestimonialGrid](components/testimonial-grid.md) `@nexub/marketing`: Customer quotes in product-coloured cards, with an optional star rating. Server component.
|
|
160
|
+
|
|
146
161
|
## Patterns — AI
|
|
147
162
|
|
|
148
163
|
- [Conversation](components/conversation.md) `@nexub/patterns`: Chat layout: a scrolling message list that follows new content, with a sticky composer underneath.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Tokens
|
|
2
2
|
|
|
3
|
-
Nexub DS
|
|
3
|
+
Nexub DS v3.1.0. Every token is a CSS custom property from `@nexub/tokens/css` (loaded by `@nexub/themes/base`).
|
|
4
4
|
The Tailwind preset (`@nexub/tokens/tailwind`) maps them to utilities. Never hardcode a hex, px spacing or shadow that a token covers.
|
|
5
5
|
|
|
6
6
|
## Color roles
|
|
@@ -93,6 +93,7 @@ Fonts: `font-sans` (Inter, UI), `font-display` (Plus Jakarta Sans, headlines), `
|
|
|
93
93
|
|
|
94
94
|
| Tailwind | Size / line height | Weight |
|
|
95
95
|
| --- | --- | --- |
|
|
96
|
+
| `text-display-xl` | 64px / 68px | 800 |
|
|
96
97
|
| `text-display-lg` | 56px / 60px | 700 |
|
|
97
98
|
| `text-display-md` | 44px / 48px | 700 |
|
|
98
99
|
| `text-display-sm` | 36px / 40px | 700 |
|
|
@@ -142,7 +143,7 @@ Fonts: `font-sans` (Inter, UI), `font-display` (Plus Jakarta Sans, headlines), `
|
|
|
142
143
|
| `--spacing-2-5` | `2-5` | 10px |
|
|
143
144
|
| `--spacing-3-5` | `3-5` | 14px |
|
|
144
145
|
|
|
145
|
-
Containers: `max-w-container-sm` (640px), `max-w-container-md` (768px), `max-w-container-lg` (1024px), `max-w-container-xl` (1280px), `max-w-container-2xl` (1536px), `max-w-container-nexub` (1440px), `max-w-container-prose` (65ch).
|
|
146
|
+
Containers: `max-w-container-sm` (640px), `max-w-container-md` (768px), `max-w-container-lg` (1024px), `max-w-container-xl` (1280px), `max-w-container-2xl` (1536px), `max-w-container-nexub` (1440px), `max-w-container-marketing` (1280px), `max-w-container-prose` (65ch).
|
|
146
147
|
|
|
147
148
|
## Control and component sizes
|
|
148
149
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexub/mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "MCP server for Nexub Design System: gives Claude, Cursor and any MCP client the components, patterns, tokens and design rules of the installed release.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# Banner
|
|
2
|
-
|
|
3
|
-
> **Deprecated.** Do not use in new code. Removal planned in 3.0: use [Alert](alert.md). `<Alert>` has the same props (tone, title, icon, action, onClose), so rename the element. Deprecated — use Alert. Full-width announcement banner, typically used at the top of a page.
|
|
4
|
-
|
|
5
|
-
- Package: `@nexub/react` · Category: Feedback · Status: deprecated
|
|
6
|
-
- Import: `import { Banner } from '@nexub/react';`
|
|
7
|
-
- Docs: https://nexub-ds-docs.pages.dev/components/banner
|
|
8
|
-
|
|
9
|
-
## Props
|
|
10
|
-
|
|
11
|
-
| Prop | Type | Default | Description |
|
|
12
|
-
| --- | --- | --- | --- |
|
|
13
|
-
| `tone` | `'neutral' \| 'info' \| 'success' \| 'warning' \| 'danger'` | | Semantic colour tone of the banner. |
|
|
14
|
-
| `action` | `ReactNode` | | Action element (e.g. a button or link) rendered to the right of the content. |
|
|
15
|
-
| `onClose` | `() => void` | | When provided, renders a close button that dismisses the banner. |
|
|
16
|
-
|
|
17
|
-
## Example: Default
|
|
18
|
-
|
|
19
|
-
```tsx
|
|
20
|
-
import { Banner } from '@nexub/react';
|
|
21
|
-
|
|
22
|
-
export default function Example() {
|
|
23
|
-
return <Banner tone="info">New features available — <strong>see what's new</strong></Banner>;
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Example: With action
|
|
28
|
-
|
|
29
|
-
```tsx
|
|
30
|
-
import { Banner, Button } from '@nexub/react';
|
|
31
|
-
|
|
32
|
-
export default function Example() {
|
|
33
|
-
return (
|
|
34
|
-
<Banner
|
|
35
|
-
tone="warning"
|
|
36
|
-
action={<Button variant="outline" size="sm">Review now</Button>}
|
|
37
|
-
onClose={() => {}}
|
|
38
|
-
>
|
|
39
|
-
Your payment method is expiring soon.
|
|
40
|
-
</Banner>
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
```
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# Callout
|
|
2
|
-
|
|
3
|
-
> **Deprecated.** Do not use in new code. Removal planned in 3.0: use [Alert](alert.md). `<Alert>` covers tone and icon. Deprecated — use Alert. Highlighted content block for tips, warnings, or notes.
|
|
4
|
-
|
|
5
|
-
- Package: `@nexub/react` · Category: Feedback · Status: deprecated
|
|
6
|
-
- Import: `import { Callout } from '@nexub/react';`
|
|
7
|
-
- Docs: https://nexub-ds-docs.pages.dev/components/callout
|
|
8
|
-
|
|
9
|
-
## Props
|
|
10
|
-
|
|
11
|
-
| Prop | Type | Default | Description |
|
|
12
|
-
| --- | --- | --- | --- |
|
|
13
|
-
| `tone` | `'neutral' \| 'info' \| 'success' \| 'warning' \| 'danger'` | | Semantic colour tone of the callout. |
|
|
14
|
-
| `title` | `string` | | Bold title rendered at the top of the callout. |
|
|
15
|
-
| `icon` | `ReactNode` | | Custom icon rendered beside the title. |
|
|
16
|
-
|
|
17
|
-
## Example: Default
|
|
18
|
-
|
|
19
|
-
```tsx
|
|
20
|
-
import { Callout } from '@nexub/react';
|
|
21
|
-
|
|
22
|
-
export default function Example() {
|
|
23
|
-
return <Callout tone="warning" title="Before you continue">Deleting this record is permanent and cannot be undone.</Callout>;
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Example: Info
|
|
28
|
-
|
|
29
|
-
```tsx
|
|
30
|
-
import { Callout } from '@nexub/react';
|
|
31
|
-
|
|
32
|
-
export default function Example() {
|
|
33
|
-
return <Callout tone="info">Use token names instead of raw hex values for consistent theming.</Callout>;
|
|
34
|
-
}
|
|
35
|
-
```
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# Status Pill
|
|
2
|
-
|
|
3
|
-
> **Deprecated.** Do not use in new code. Removal planned in 3.0: use [Badge](badge.md). `<Badge variant="soft" leadingIcon={dot}>` covers it. Deprecated — use Badge. A pill indicator for status values like active, pending, error.
|
|
4
|
-
|
|
5
|
-
- Package: `@nexub/react` · Category: Labels & Badges · Status: deprecated
|
|
6
|
-
- Import: `import { StatusPill } from '@nexub/react';`
|
|
7
|
-
- Docs: https://nexub-ds-docs.pages.dev/components/status-pill
|
|
8
|
-
|
|
9
|
-
## Props
|
|
10
|
-
|
|
11
|
-
| Prop | Type | Default | Description |
|
|
12
|
-
| --- | --- | --- | --- |
|
|
13
|
-
| `label` (required) | `string` | | Text displayed inside the pill. |
|
|
14
|
-
| `tone` | `'neutral' \| 'info' \| 'success' \| 'warning' \| 'danger'` | `'neutral'` | Semantic colour tone of the pill. |
|
|
15
|
-
| `dot` | `boolean` | `false` | Renders a small status dot before the label. Pulses automatically for success and info tones. |
|
|
16
|
-
|
|
17
|
-
## Example: Default
|
|
18
|
-
|
|
19
|
-
```tsx
|
|
20
|
-
import { StatusPill } from '@nexub/react';
|
|
21
|
-
|
|
22
|
-
export default function Example() {
|
|
23
|
-
return (
|
|
24
|
-
<div className="flex gap-2 flex-wrap items-center justify-center">
|
|
25
|
-
<StatusPill tone="success" label="Active" />
|
|
26
|
-
<StatusPill tone="warning" label="Pending" />
|
|
27
|
-
<StatusPill tone="danger" label="Error" />
|
|
28
|
-
<StatusPill tone="neutral" label="Draft" />
|
|
29
|
-
<StatusPill tone="info" label="Syncing" />
|
|
30
|
-
</div>
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Example: With dot
|
|
36
|
-
|
|
37
|
-
```tsx
|
|
38
|
-
import { StatusPill } from '@nexub/react';
|
|
39
|
-
|
|
40
|
-
export default function Example() {
|
|
41
|
-
return <StatusPill tone="success" dot label="Live" />;
|
|
42
|
-
}
|
|
43
|
-
```
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# Tag
|
|
2
|
-
|
|
3
|
-
> **Deprecated.** Do not use in new code. Removal planned in 3.0: use [Badge](badge.md). `<Badge size="sm">` covers it. Deprecated — use Badge. Non-interactive label tag for categorisation.
|
|
4
|
-
|
|
5
|
-
- Package: `@nexub/react` · Category: Labels & Badges · Status: deprecated
|
|
6
|
-
- Import: `import { Tag } from '@nexub/react';`
|
|
7
|
-
- Docs: https://nexub-ds-docs.pages.dev/components/tag
|
|
8
|
-
|
|
9
|
-
## Props
|
|
10
|
-
|
|
11
|
-
| Prop | Type | Default | Description |
|
|
12
|
-
| --- | --- | --- | --- |
|
|
13
|
-
| `variant` | `'solid' \| 'soft' \| 'outline'` | `'soft'` | Visual style of the tag. |
|
|
14
|
-
| `tone` | `'neutral' \| 'info' \| 'success' \| 'warning' \| 'danger'` | | Semantic colour tone of the tag. |
|
|
15
|
-
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Controls tag size. |
|
|
16
|
-
|
|
17
|
-
## Example: Default
|
|
18
|
-
|
|
19
|
-
```tsx
|
|
20
|
-
import { Tag } from '@nexub/react';
|
|
21
|
-
|
|
22
|
-
export default function Example() {
|
|
23
|
-
return (
|
|
24
|
-
<div className="flex gap-2 flex-wrap items-center justify-center">
|
|
25
|
-
<Tag>Frontend</Tag>
|
|
26
|
-
<Tag tone="info">Backend</Tag>
|
|
27
|
-
<Tag tone="success">Deployed</Tag>
|
|
28
|
-
<Tag tone="warning">Review</Tag>
|
|
29
|
-
<Tag tone="danger">Blocked</Tag>
|
|
30
|
-
</div>
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
```
|