@genesislcap/foundation-rapid-cdn 14.430.2-FUI-2528.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -0
- package/components.md +554 -0
- package/dist/dts/index.d.ts +13 -0
- package/dist/dts/index.d.ts.map +1 -0
- package/dist/foundation-rapid-cdn.iife.min.js +112 -0
- package/dist/foundation-rapid-cdn.js +82880 -0
- package/dist/foundation-rapid-cdn.min.js +112 -0
- package/license.txt +46 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Rapid Design System CDN bundle
|
|
2
|
+
|
|
3
|
+
A side-effecting, self-contained IIFE bundle of `@genesislcap/rapid-design-system`. One `<script>` tag, no build step — drop into Claude Artifacts, CodePen, JSFiddle, plain HTML files, or any other sandboxed environment that has no module resolution.
|
|
4
|
+
|
|
5
|
+
> **Not for production apps.** Real applications should depend on `@genesislcap/rapid-design-system` directly and follow the standard `provideDesignSystem().register(...)` pattern. This package inlines every dependency, auto-registers everything against `document.body`, and trades bundle size for zero-config startup.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<!doctype html>
|
|
11
|
+
<html>
|
|
12
|
+
<body>
|
|
13
|
+
<rapid-button appearance="accent">Click me</rapid-button>
|
|
14
|
+
<rapid-card>
|
|
15
|
+
<h3>Hello</h3>
|
|
16
|
+
<p>Rapid components, no setup.</p>
|
|
17
|
+
</rapid-card>
|
|
18
|
+
|
|
19
|
+
<script src="https://cdn.jsdelivr.net/npm/@genesislcap/foundation-rapid-cdn"></script>
|
|
20
|
+
</body>
|
|
21
|
+
</html>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
On load the bundle:
|
|
25
|
+
|
|
26
|
+
1. Registers every component in `baseComponents` (button, card, dialog, data-grid, …).
|
|
27
|
+
2. Wraps `document.body`'s children in a `<rapid-design-system-provider with-defaults>` so design tokens apply.
|
|
28
|
+
3. Exposes `window.rapid` for advanced use:
|
|
29
|
+
- `provideDesignSystem`, `baseComponents`, `registerRapidDesignSystem` — the registration primitives.
|
|
30
|
+
- `tokens` — the most-overridden design tokens (`baseLayerLuminance`, semantic colors, `designUnit`, `density`, `bodyFont`, …) so artifact code can call `window.rapid.tokens.baseLayerLuminance.withDefault(window.rapid.StandardLuminance.LightMode)` without a module loader.
|
|
31
|
+
- `StandardLuminance` — `{ LightMode: 1, DarkMode: 0.23 }`.
|
|
32
|
+
- `docsUrl`, `aiReference` — pointers to the AI-facing component reference.
|
|
33
|
+
|
|
34
|
+
## React component reference for AI tools
|
|
35
|
+
|
|
36
|
+
[`components.md`](./components.md) is a React-focused quick reference: import paths, event/prop conventions, and example usage of the most common ~50 components. Designed to be fed to a coding assistant generating React code that consumes `@genesislcap/rapid-design-system/react`.
|
|
37
|
+
|
|
38
|
+
CDN URL:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
https://cdn.jsdelivr.net/npm/@genesislcap/foundation-rapid-cdn/components.md
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Drop that URL into a Claude project's instructions, a `CLAUDE.md`, or a system prompt so the assistant fetches it on demand.
|
|
45
|
+
|
|
46
|
+
## Pinning a version
|
|
47
|
+
|
|
48
|
+
`@latest` follows stable releases, `@alpha` follows the prerelease channel:
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<!-- pinned, immutable, cached forever -->
|
|
52
|
+
<script src="https://cdn.jsdelivr.net/npm/@genesislcap/foundation-rapid-cdn@14.430.2"></script>
|
|
53
|
+
|
|
54
|
+
<!-- prerelease channel -->
|
|
55
|
+
<script src="https://cdn.jsdelivr.net/npm/@genesislcap/foundation-rapid-cdn@alpha"></script>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`unpkg.com` and `esm.sh` mirror the same files.
|
|
59
|
+
|
|
60
|
+
## Local smoke test
|
|
61
|
+
|
|
62
|
+
After `npm run build`, open `test/index.html` from this package — it loads the bundle from `../dist/...` and renders a button/card/dialog/tabs grid for visual verification.
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
npm run test:browser # serves on :4321 and opens /test/ in the browser
|
|
66
|
+
# or just: open test/index.html
|
|
67
|
+
```
|
package/components.md
ADDED
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
# Genesis Rapid — React component reference
|
|
2
|
+
|
|
3
|
+
> **Audience: AI coding assistants generating React code for the Genesis client app.**
|
|
4
|
+
> Always emit React components from `@genesislcap/rapid-design-system/react`, not raw `<rapid-*>` web component tags. The web-component tags exist, but engineers consume Rapid via the React wrappers — using JSX with PascalCase components keeps types, refs, and event signatures correct.
|
|
5
|
+
|
|
6
|
+
This is a v0 quick reference. Prefer it over guessing; if a component or prop isn't listed, fall back to the rules in [Conventions](#conventions) below — the React wrappers are auto-generated and follow them strictly.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Setup (one-time, done in the app entry — engineers usually don't repeat this)
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
// genesis-components.ts (or equivalent app entry)
|
|
14
|
+
import * as rapidDesignSystem from '@genesislcap/rapid-design-system';
|
|
15
|
+
|
|
16
|
+
rapidDesignSystem.provideDesignSystem().register(rapidDesignSystem.baseComponents);
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The app's root element should sit inside a `<rapid-design-system-provider>` so design tokens (colors, spacing, typography) apply. New page components can assume this is already in place.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Import statement
|
|
24
|
+
|
|
25
|
+
Always:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { Button, Card, TextField /* … */ } from '@genesislcap/rapid-design-system/react';
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Never:
|
|
32
|
+
- `import { Button } from '@genesislcap/rapid-design-system'` — that's the WC export, not the React wrapper
|
|
33
|
+
- `<rapid-button>` in JSX — works, but loses types and forces `as any` casts
|
|
34
|
+
|
|
35
|
+
For ref types, use the auto-generated `XxxRef` aliases:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { TextField, type TextFieldRef } from '@genesislcap/rapid-design-system/react';
|
|
39
|
+
const ref = useRef<TextFieldRef>(null);
|
|
40
|
+
ref.current?.focus();
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Conventions
|
|
46
|
+
|
|
47
|
+
These rules let you predict the React API for any component without looking it up:
|
|
48
|
+
|
|
49
|
+
| Source (web component) | React prop | Notes |
|
|
50
|
+
| ------------------------------- | ----------------------------------- | -------------------------------------------------------------------- |
|
|
51
|
+
| Standard DOM event `change` | `onChange?(e: Event): void` | Typed as `Event`, not `React.FormEvent` — bivariant. |
|
|
52
|
+
| Standard DOM event `input` | `onInput?(e: Event): void` | Same as above. |
|
|
53
|
+
| Standard DOM event `click` | `onClick?: MouseEventHandler` | Standard React signature. |
|
|
54
|
+
| Custom event `value-changed` | `onValueChanged?(e: CustomEvent)` | kebab → `on` + PascalCase. Payload on `e.detail`. |
|
|
55
|
+
| Custom event `submit-success` | `onSubmitSuccess?(e: CustomEvent)` | |
|
|
56
|
+
| Custom event `selection-change` | `onSelectionChange?(e: CustomEvent)`| |
|
|
57
|
+
| Boolean attr `inline-calendar` | `inlineCalendar?: boolean` | kebab attr → camelCase boolean prop. Pass bare (`<X inlineCalendar/>`). |
|
|
58
|
+
| String-union attr `appearance` | `appearance?: 'primary' \| …` | Pass plain strings. |
|
|
59
|
+
| TS enum attr (e.g. `crud-menu-position`) | `crudMenuPosition?: CrudMenuPosition` | **Must** import the enum; string literals are not assignable. |
|
|
60
|
+
| `slot="…"` | `slot="…"` (unchanged) | Use to target named slots in components like `Tabs`, `Dialog`. |
|
|
61
|
+
|
|
62
|
+
Slots in JSX use the standard `slot="name"` attribute on the child element.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Design tokens
|
|
67
|
+
|
|
68
|
+
Rapid is built on FAST design tokens, exposed as **kebab-case CSS custom properties** on the `<rapid-design-system-provider>` element. Any descendant — including any rapid component — inherits them. Reference them from `style={{ color: 'var(--accent-fill-rest)' }}` or from a CSS class.
|
|
69
|
+
|
|
70
|
+
> Tokens are **not** prefixed with `rapid-`. The `rapid-` prefix only applies to component tag names. CSS variables are the standard FAST names.
|
|
71
|
+
|
|
72
|
+
### Theme defaults
|
|
73
|
+
|
|
74
|
+
The Rapid provider ships **dark mode by default**. Colors are derived from the accent + neutral palettes; the hex values below are the seed values from which fill/foreground/hover/active variants are computed. See [Light / dark mode](#light--dark-mode) below for switching themes.
|
|
75
|
+
|
|
76
|
+
| Purpose | Default seed | Notes |
|
|
77
|
+
| ------------------------ | ------------ | ------------------------------------ |
|
|
78
|
+
| accent / primary | `#11C9FC` | Drives all `accent-*` tokens. |
|
|
79
|
+
| neutral | `#7C909B` | Drives all `neutral-*` tokens. |
|
|
80
|
+
| `--error-color` | `#F9644D` | Genesis custom token. |
|
|
81
|
+
| `--success-color` | `#7ACC79` | Genesis custom token. |
|
|
82
|
+
| `--warning-color` | `#FFB660` | Genesis custom token. |
|
|
83
|
+
| `--info-color` | `#11C9FC` | Genesis custom token. |
|
|
84
|
+
| `--buy-color` | `#7ACC79` | Trading semantic. |
|
|
85
|
+
| `--sell-color` | `#F14376` | Trading semantic. |
|
|
86
|
+
| `--serious-notify-color` | `#F9644D` | Genesis custom token. |
|
|
87
|
+
|
|
88
|
+
### Light / dark mode
|
|
89
|
+
|
|
90
|
+
> **Default to dark mode.** Generated UI should keep the provider's default (`--base-layer-luminance: 0.23`) unless the user has explicitly asked for light mode (or for a user-controlled toggle). Don't switch to light by default, and don't add a theme toggle without being asked.
|
|
91
|
+
|
|
92
|
+
Theme is controlled by a single token: **`--base-layer-luminance`**. It's a number between 0 (black) and 1 (white) that drives every neutral surface, fill, foreground, and stroke. Set it once and the whole surface palette flips — you do **not** override each `--neutral-*` variable individually.
|
|
93
|
+
|
|
94
|
+
| Mode | `--base-layer-luminance` | Constant |
|
|
95
|
+
| ----- | ------------------------ | ------------------------------ |
|
|
96
|
+
| Dark | `0.23` (default) | `StandardLuminance.DarkMode` |
|
|
97
|
+
| Light | `1` | `StandardLuminance.LightMode` |
|
|
98
|
+
|
|
99
|
+
The accent palette is luminance-independent — switching modes recolors surfaces and text, but `--accent-fill-rest` (your primary action color) stays on-brand.
|
|
100
|
+
|
|
101
|
+
> **Contrast caveat for AI-generated UI:** because the accent palette doesn't adapt, `appearance="primary-outline"` and `appearance="link"` (which use the accent color for text) can read poorly on a white background — the default accent (`#11C9FC` cyan) lacks contrast in light mode. If a design needs to support light mode, prefer `appearance="primary"` (filled — the foreground recomputes to stay readable) or `appearance="neutral-outline"` (uses the neutral palette, which does adapt) for outline-style buttons.
|
|
102
|
+
|
|
103
|
+
**Switching:** the cleanest mechanism for a light/dark toggle is to set the CSS variable on the provider (or a wrapper element) — every descendant component picks it up automatically.
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
// Whole-app toggle (set on the design-system-provider or document root)
|
|
107
|
+
<div style={{ ['--base-layer-luminance' as any]: theme === 'light' ? 1 : 0.23 }}>
|
|
108
|
+
{children}
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
// Or scoped to one subtree (e.g. a single panel that's always light)
|
|
112
|
+
<section style={{ ['--base-layer-luminance' as any]: 1 }}>
|
|
113
|
+
<Card>This card and everything inside it is light-mode.</Card>
|
|
114
|
+
</section>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Important — `withDefault()` does not work after the provider has been registered.** The Rapid provider sets its own per-element token value during construction, which shadows the global default. To change the live theme you have to set the value *on the provider element*, either by setting the CSS variable directly (above) or with `setValueFor`:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
// In a real React app
|
|
121
|
+
import { baseLayerLuminance } from '@genesislcap/rapid-design-system';
|
|
122
|
+
import { StandardLuminance } from '@microsoft/fast-components';
|
|
123
|
+
const provider = document.querySelector('rapid-design-system-provider')!;
|
|
124
|
+
baseLayerLuminance.setValueFor(provider, StandardLuminance.LightMode);
|
|
125
|
+
|
|
126
|
+
// In an artifact / sandbox using the foundation-rapid-cdn bundle (no imports available)
|
|
127
|
+
const provider = document.querySelector('rapid-design-system-provider');
|
|
128
|
+
window.rapid.tokens.baseLayerLuminance.setValueFor(provider, window.rapid.StandardLuminance.LightMode);
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
`withDefault()` is only useful *before* the design system is registered (i.e. as part of app bootstrap), and even then setting the CSS variable on the provider is usually clearer.
|
|
132
|
+
|
|
133
|
+
Intermediate values (e.g. `0.5`) work too but aren't standard — they produce a mid-grey theme that the palette generator wasn't tuned for. Stick to `1` or `0.23` unless you have a specific reason.
|
|
134
|
+
|
|
135
|
+
### Surfaces, fills & strokes
|
|
136
|
+
|
|
137
|
+
These are the most common tokens you'll reach for when laying out around components.
|
|
138
|
+
|
|
139
|
+
| Token | What it is |
|
|
140
|
+
| ---------------------------------- | -------------------------------------------------------------------------- |
|
|
141
|
+
| `--fill-color` | Page background. |
|
|
142
|
+
| `--neutral-layer-1` … `--neutral-layer-4` | Stacked surface layers, light → dark. |
|
|
143
|
+
| `--neutral-layer-card-container` | Card body fill. |
|
|
144
|
+
| `--neutral-layer-floating` | Dialog / menu / tooltip floating surface. |
|
|
145
|
+
| `--accent-fill-rest` | Primary action fill (button, switch on, etc.). Variants: `-hover`, `-active`, `-focus`. |
|
|
146
|
+
| `--accent-foreground-rest` | Text/icon on neutral surfaces that should read as "primary". |
|
|
147
|
+
| `--foreground-on-accent-rest` | Text/icon to place **on top of** an `accent-fill-*` surface. |
|
|
148
|
+
| `--neutral-fill-rest` | Secondary action fill. Variants: `-hover`, `-active`, `-focus`. |
|
|
149
|
+
| `--neutral-fill-input-rest` | Input field background. Variants as above. |
|
|
150
|
+
| `--neutral-fill-stealth-rest` | Subtle hover-only buttons (icon buttons, table rows). Variants as above. |
|
|
151
|
+
| `--neutral-foreground-rest` | Body text. |
|
|
152
|
+
| `--neutral-foreground-hint` | Muted/secondary text. |
|
|
153
|
+
| `--neutral-stroke-rest` | Borders. Variants: `-hover`, `-active`, `-focus`. |
|
|
154
|
+
| `--neutral-stroke-divider-rest` | Divider lines (lighter than `stroke-rest`). |
|
|
155
|
+
| `--focus-stroke-outer` / `--focus-stroke-inner` | Focus ring colors. |
|
|
156
|
+
|
|
157
|
+
### Sizing & spacing
|
|
158
|
+
|
|
159
|
+
These drive the geometry of every component. Override on the provider (or a wrapper element) to retune density site-wide.
|
|
160
|
+
|
|
161
|
+
| Token | Default | What it controls |
|
|
162
|
+
| --------------------------- | ------- | ----------------------------------------------------------------- |
|
|
163
|
+
| `--design-unit` | `4` | Base unit (px). Multiply by it for spacing: `padding: calc(var(--design-unit) * 2px)`. |
|
|
164
|
+
| `--base-height-multiplier` | `10` | Component height = `(base-height-multiplier + density) × design-unit`. Default control height = 40px. |
|
|
165
|
+
| `--density` | `0` | Adjust ±1 / ±2 to shrink / grow controls without re-styling each one. |
|
|
166
|
+
| `--control-corner-radius` | `4` | Border radius (px) for buttons, fields, cards. |
|
|
167
|
+
| `--stroke-width` | `1` | Default border width (px). |
|
|
168
|
+
| `--focus-stroke-width` | `2` | Focus ring width (px). |
|
|
169
|
+
| `--disabled-opacity` | `0.3` | Opacity applied to `disabled` controls. |
|
|
170
|
+
|
|
171
|
+
### Typography
|
|
172
|
+
|
|
173
|
+
| Token | Default |
|
|
174
|
+
| --------------------------------------- | --------------------------------------------- |
|
|
175
|
+
| `--body-font` | `"Segoe UI", Arial, Helvetica, sans-serif` |
|
|
176
|
+
| `--type-ramp-base-font-size` / `-line-height` | `14px` / `20px` — body default |
|
|
177
|
+
| `--type-ramp-minus-1-font-size` / `-line-height` | `13px` / `19px` — small text |
|
|
178
|
+
| `--type-ramp-minus-2-font-size` / `-line-height` | `12px` / `18px` — captions |
|
|
179
|
+
| `--type-ramp-plus-1-font-size` / `-line-height` | `15px` / `21px` |
|
|
180
|
+
| `--type-ramp-plus-2-font-size` / `-line-height` | `16px` / `22px` |
|
|
181
|
+
| `--type-ramp-plus-3-font-size` / `-line-height` | `17px` / `23px` |
|
|
182
|
+
| `--type-ramp-plus-4-font-size` / `-line-height` | `18px` / `24px` — section headings |
|
|
183
|
+
| `--type-ramp-plus-5-font-size` / `-line-height` | `19px` / `25px` |
|
|
184
|
+
| `--type-ramp-plus-6-font-size` / `-line-height` | `20px` / `26px` — page headings |
|
|
185
|
+
|
|
186
|
+
### Using tokens in JSX
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
<Card style={{
|
|
190
|
+
background: 'var(--neutral-layer-card-container)',
|
|
191
|
+
padding: 'calc(var(--design-unit) * 4px)',
|
|
192
|
+
borderRadius: 'calc(var(--control-corner-radius) * 1px)',
|
|
193
|
+
}}>
|
|
194
|
+
<h2 style={{ font: 'var(--type-ramp-plus-4-font-size) var(--body-font)', color: 'var(--neutral-foreground-rest)' }}>
|
|
195
|
+
Settings
|
|
196
|
+
</h2>
|
|
197
|
+
<p style={{ color: 'var(--neutral-foreground-hint)' }}>Choose how you'd like to be notified.</p>
|
|
198
|
+
</Card>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
When a component already uses a token internally (e.g. `Button` uses `--accent-fill-*`), don't restyle it from outside — pick a different `appearance` instead.
|
|
202
|
+
|
|
203
|
+
### Overriding tokens
|
|
204
|
+
|
|
205
|
+
Two ways:
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
// Per-subtree override via inline CSS variable — works everywhere
|
|
209
|
+
<div style={{ ['--accent-fill-rest' as any]: '#ff8800' }}>
|
|
210
|
+
<Button appearance="primary">Orange primary</Button>
|
|
211
|
+
</div>
|
|
212
|
+
|
|
213
|
+
// Override on the provider element after registration (the common case)
|
|
214
|
+
// Real React app:
|
|
215
|
+
import { accentFillRest } from '@genesislcap/rapid-design-system';
|
|
216
|
+
const provider = document.querySelector('rapid-design-system-provider')!;
|
|
217
|
+
accentFillRest.setValueFor(provider, '#ff8800' as any);
|
|
218
|
+
|
|
219
|
+
// Artifact / CDN bundle: a focused set of tokens is exposed at window.rapid.tokens.
|
|
220
|
+
// Available: baseLayerLuminance, fillColor, accentPalette, neutralPalette,
|
|
221
|
+
// errorColor, successColor, warningColor, infoColor, buyColor, sellColor,
|
|
222
|
+
// seriousNotifyColor, designUnit, baseHeightMultiplier, density,
|
|
223
|
+
// controlCornerRadius, bodyFont. For anything outside that list, use the
|
|
224
|
+
// CSS-variable form above.
|
|
225
|
+
const provider = document.querySelector('rapid-design-system-provider');
|
|
226
|
+
window.rapid.tokens.errorColor.setValueFor(provider, '#ff0000' as any);
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The CSS-variable form and `setValueFor(provider, …)` are equivalent for runtime overrides — both work *because* the provider already has its own per-element value, so global `withDefault()` is shadowed and won't take effect after registration.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Buttons & actions
|
|
234
|
+
|
|
235
|
+
### `Button`
|
|
236
|
+
Props: `appearance?: 'primary' | 'primary-outline' | 'neutral' | 'neutral-outline' | 'link' | 'danger' | 'accent' | 'lightweight' | 'outline' | 'stealth'`, `disabled?`, all standard `<button>` attrs.
|
|
237
|
+
|
|
238
|
+
```tsx
|
|
239
|
+
<Button appearance="primary" onClick={handleSave}>Save</Button>
|
|
240
|
+
<Button appearance="primary-outline" disabled>Cancel</Button>
|
|
241
|
+
<Button appearance="danger" onClick={handleDelete}>Delete</Button>
|
|
242
|
+
|
|
243
|
+
// With icon in a slot
|
|
244
|
+
<Button appearance="primary">
|
|
245
|
+
Save
|
|
246
|
+
<Icon name="check" size="md" slot="end" />
|
|
247
|
+
</Button>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### `DropdownMenu`, `Menu`, `MenuItem`, `ActionsMenu`
|
|
251
|
+
Use for action lists. `MenuItem` accepts `onClick`; named slot `start`/`end` for icons.
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Form fields
|
|
256
|
+
|
|
257
|
+
### `TextField`
|
|
258
|
+
Props: `value?`, `placeholder?`, `disabled?`, `readonly?`, `type?` ('text' | 'email' | 'password' | 'tel' | 'url' | 'datetime-local' | …), `appearance?`, plus children for the label.
|
|
259
|
+
|
|
260
|
+
```tsx
|
|
261
|
+
<TextField
|
|
262
|
+
value={name}
|
|
263
|
+
placeholder="Enter your name"
|
|
264
|
+
onChange={(e: Event) => setName((e.target as HTMLInputElement).value)}
|
|
265
|
+
>
|
|
266
|
+
Name
|
|
267
|
+
</TextField>
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### `TextArea`
|
|
271
|
+
Props: `value?`, `placeholder?`, `rows?`, `cols?`, `resize?` ('none' | 'vertical' | 'horizontal' | 'both'), children = label.
|
|
272
|
+
|
|
273
|
+
### `NumberField`
|
|
274
|
+
Props: `value?`, `min?`, `max?`, `step?`, `withFormatting?: boolean`, `placeholder?`, children = label.
|
|
275
|
+
|
|
276
|
+
```tsx
|
|
277
|
+
<NumberField min={0} max={100} step={1} withFormatting>
|
|
278
|
+
Quantity
|
|
279
|
+
</NumberField>
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### `Checkbox`, `Switch`
|
|
283
|
+
Boolean state. `checked?: boolean`, `onChange?(e: Event)`. Children render as the label.
|
|
284
|
+
|
|
285
|
+
```tsx
|
|
286
|
+
<Checkbox checked={agreed} onChange={(e) => setAgreed((e.target as HTMLInputElement).checked)}>
|
|
287
|
+
I agree
|
|
288
|
+
</Checkbox>
|
|
289
|
+
|
|
290
|
+
<Switch checked={notifyOn} onChange={…}>Notifications</Switch>
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### `Radio`, `RadioGroup`
|
|
294
|
+
```tsx
|
|
295
|
+
<RadioGroup orientation="horizontal" value={size} onChange={…}>
|
|
296
|
+
<Radio value="s">Small</Radio>
|
|
297
|
+
<Radio value="m">Medium</Radio>
|
|
298
|
+
<Radio value="l">Large</Radio>
|
|
299
|
+
</RadioGroup>
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### `Select` + `ListboxOption`
|
|
303
|
+
Note: the option component is `ListboxOption`, not `Option`.
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
<Select value={pick} onChange={(e) => setPick((e.target as HTMLSelectElement).value)}>
|
|
307
|
+
<ListboxOption value="a">Alpha</ListboxOption>
|
|
308
|
+
<ListboxOption value="b">Beta</ListboxOption>
|
|
309
|
+
</Select>
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### `Combobox`
|
|
313
|
+
Free-text-with-suggestions. Same option shape as `Select`.
|
|
314
|
+
|
|
315
|
+
```tsx
|
|
316
|
+
<Combobox position="below">
|
|
317
|
+
<ListboxOption value="a">Alpha</ListboxOption>
|
|
318
|
+
<ListboxOption value="b">Beta</ListboxOption>
|
|
319
|
+
</Combobox>
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### `Multiselect`, `CategorizedMultiselect`
|
|
323
|
+
Multi-value selection. Pass `options={[…]}` (array prop, not children) and listen for `onSelectionChange`.
|
|
324
|
+
|
|
325
|
+
```tsx
|
|
326
|
+
<Multiselect options={[{value: 'a', text: 'Alpha'}, {value: 'b', text: 'Beta'}]}
|
|
327
|
+
onSelectionChange={(e: CustomEvent) => setSelected(e.detail)} />
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### `Slider`, `SliderLabel`
|
|
331
|
+
Range input. `min?`, `max?`, `step?`, `value?`, `orientation?`.
|
|
332
|
+
|
|
333
|
+
### `DatePicker`, `Calendar`
|
|
334
|
+
Props: `value?`, `format?`, `inlineCalendar?: boolean`, `hideWeekends?: boolean`, `label?`, fires `onValueChanged?(e: CustomEvent)` with the new date string in `e.detail`.
|
|
335
|
+
|
|
336
|
+
```tsx
|
|
337
|
+
<DatePicker
|
|
338
|
+
value={date}
|
|
339
|
+
format="yyyy-MM-dd"
|
|
340
|
+
inlineCalendar
|
|
341
|
+
onValueChanged={(e: CustomEvent) => setDate(String(e.detail ?? ''))}
|
|
342
|
+
/>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### `FileUpload`, `FileReader`, `UrlInput`, `SearchBar`, `SearchBarCombobox`
|
|
346
|
+
Specialised inputs. Same conventions: `value`/`onChange` for value, slots for icons/labels.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Layout & containers
|
|
351
|
+
|
|
352
|
+
### `Card`
|
|
353
|
+
Generic container with elevation/border. Children are the body.
|
|
354
|
+
|
|
355
|
+
```tsx
|
|
356
|
+
<Card style={{ padding: 16 }}>
|
|
357
|
+
<h3>Title</h3>
|
|
358
|
+
<p>Body content.</p>
|
|
359
|
+
</Card>
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### `Divider`
|
|
363
|
+
Visual separator. `orientation?: 'horizontal' | 'vertical'`.
|
|
364
|
+
|
|
365
|
+
### `Tabs`, `Tab`, `TabPanel`
|
|
366
|
+
Slot-driven. `Tab`s go in `slot="tab"`, panels in `slot="tabpanel"`. Order pairs them.
|
|
367
|
+
|
|
368
|
+
```tsx
|
|
369
|
+
<Tabs activeid="overview">
|
|
370
|
+
<span slot="start">Account</span>
|
|
371
|
+
<Tab slot="tab" id="overview">Overview</Tab>
|
|
372
|
+
<Tab slot="tab" id="settings">Settings</Tab>
|
|
373
|
+
<TabPanel slot="tabpanel">Overview content</TabPanel>
|
|
374
|
+
<TabPanel slot="tabpanel">Settings content</TabPanel>
|
|
375
|
+
</Tabs>
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### `Accordion`, `AccordionItem`
|
|
379
|
+
```tsx
|
|
380
|
+
<Accordion>
|
|
381
|
+
<AccordionItem slot="item" id="a1" expanded>
|
|
382
|
+
<span slot="heading">Section 1</span>
|
|
383
|
+
<p>Content 1</p>
|
|
384
|
+
</AccordionItem>
|
|
385
|
+
<AccordionItem slot="item" id="a2">
|
|
386
|
+
<span slot="heading">Section 2</span>
|
|
387
|
+
<p>Content 2</p>
|
|
388
|
+
</AccordionItem>
|
|
389
|
+
</Accordion>
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### `Banner`, `Breadcrumb`/`BreadcrumbItem`, `Toolbar`, `SectionNavigator`, `Stepper`/`StepperTab`/`StepperTabPanel`
|
|
393
|
+
Containers for navigation/announcement patterns. `BreadcrumbItem` accepts `href`. `Stepper` follows the same slot pattern as `Tabs` (`slot="tab"`, `slot="tabpanel"`).
|
|
394
|
+
|
|
395
|
+
### `FlexLayout`, `GridLayout`, `GridLayoutItem`, `HorizontalScroll`, `Disclosure`
|
|
396
|
+
Layout primitives. Use `FlexLayout`/`GridLayout` for app shells; `Disclosure` for show/hide chunks.
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## Feedback
|
|
401
|
+
|
|
402
|
+
### `Badge`, `StatusPill`
|
|
403
|
+
Inline labels. Children are the text.
|
|
404
|
+
|
|
405
|
+
```tsx
|
|
406
|
+
<Badge>New</Badge>
|
|
407
|
+
<StatusPill>Active</StatusPill>
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### `Progress`, `ProgressRing`, `Skeleton`
|
|
411
|
+
`Progress`/`ProgressRing` have `value?: number` (0–100) and `min`/`max`. `Skeleton` for loading placeholders.
|
|
412
|
+
|
|
413
|
+
### `Snackbar`, `Toast`
|
|
414
|
+
Notifications. `Toast` has `notify?: 'info' | 'warning' | 'success' | 'critical'`. Typically toggled imperatively via a ref or a singleton helper — see existing code for the project's convention.
|
|
415
|
+
|
|
416
|
+
### `Tooltip`
|
|
417
|
+
Anchored to another element by id.
|
|
418
|
+
|
|
419
|
+
```tsx
|
|
420
|
+
<Button id="save-btn">Save</Button>
|
|
421
|
+
<Tooltip anchor="save-btn">Saves the form</Tooltip>
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### `Avatar`, `Icon`, `StackingIcons`, `ConnectionIndicator`, `EnvironmentIndicator`
|
|
425
|
+
Visual indicators. `Icon` props: `name?: string`, `size?: '1x' | '2x' | … | 'sm' | 'md' | 'lg'`, `variant?: 'regular' | 'solid' | 'brand' | …`.
|
|
426
|
+
|
|
427
|
+
```tsx
|
|
428
|
+
<Icon name="check" size="md" />
|
|
429
|
+
<Icon name="github" size="2x" variant="brand" />
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## Overlays
|
|
435
|
+
|
|
436
|
+
`Dialog` and `Modal` are imperative — open with `ref.current.show()`, close with `ref.current.close()`. Slots: `top` (header), default (body), `bottom` (footer / actions).
|
|
437
|
+
|
|
438
|
+
### `Dialog`
|
|
439
|
+
```tsx
|
|
440
|
+
const dialogRef = useRef<DialogRef>(null);
|
|
441
|
+
|
|
442
|
+
<>
|
|
443
|
+
<Button onClick={() => dialogRef.current?.show()}>Open</Button>
|
|
444
|
+
<Dialog ref={dialogRef} type="default">
|
|
445
|
+
<div slot="top">Confirm action</div>
|
|
446
|
+
<p>Are you sure you want to continue?</p>
|
|
447
|
+
<Button slot="bottom" appearance="primary" onClick={() => dialogRef.current?.close()}>
|
|
448
|
+
Confirm
|
|
449
|
+
</Button>
|
|
450
|
+
</Dialog>
|
|
451
|
+
</>
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
`type?: 'default' | 'error' | 'success'`. Width via CSS custom property: `style={{ '--dialog-max-width': '600px' }}`.
|
|
455
|
+
|
|
456
|
+
### `Modal`
|
|
457
|
+
Like `Dialog` but draggable; supports `draggable?: boolean`.
|
|
458
|
+
|
|
459
|
+
### `Flyout`
|
|
460
|
+
Edge-anchored panel. Useful for filter drawers, side menus.
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## Navigation
|
|
465
|
+
|
|
466
|
+
### `Anchor`
|
|
467
|
+
Renders a styled `<a>`. Props: `href`, `target`, `appearance?`.
|
|
468
|
+
|
|
469
|
+
### `Menu`, `MenuItem`, `DropdownMenu`, `ActionsMenu`
|
|
470
|
+
Click-to-open menus. `DropdownMenu` is the typical "select an option from a button" pattern; `ActionsMenu` is the "..." overflow menu with named actions.
|
|
471
|
+
|
|
472
|
+
### `TreeView`, `TreeItem`
|
|
473
|
+
Hierarchical lists. `TreeItem` accepts children (nested items) and `expanded?: boolean`.
|
|
474
|
+
|
|
475
|
+
### `SegmentedControl`, `SegmentedItem`
|
|
476
|
+
Toggle group. Same shape as `RadioGroup` but visually a single pill.
|
|
477
|
+
|
|
478
|
+
```tsx
|
|
479
|
+
<SegmentedControl value="day">
|
|
480
|
+
<SegmentedItem value="day">Day</SegmentedItem>
|
|
481
|
+
<SegmentedItem value="week">Week</SegmentedItem>
|
|
482
|
+
<SegmentedItem value="month">Month</SegmentedItem>
|
|
483
|
+
</SegmentedControl>
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### `Listbox`, `ListboxOption`
|
|
487
|
+
Standalone list selection (without the `Select` chrome). Same option shape.
|
|
488
|
+
|
|
489
|
+
### `Optgroup`
|
|
490
|
+
Groups `ListboxOption`s inside `Select` / `Listbox`. Has a `label`.
|
|
491
|
+
|
|
492
|
+
---
|
|
493
|
+
|
|
494
|
+
## Refs & imperative APIs
|
|
495
|
+
|
|
496
|
+
Every wrapper is `React.forwardRef`. Use the generated `XxxRef` type:
|
|
497
|
+
|
|
498
|
+
```ts
|
|
499
|
+
import { TextField, type TextFieldRef } from '@genesislcap/rapid-design-system/react';
|
|
500
|
+
|
|
501
|
+
const ref = useRef<TextFieldRef>(null);
|
|
502
|
+
ref.current?.focus();
|
|
503
|
+
const value = (ref.current as any)?.value;
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
Common imperative methods: `.show()` / `.close()` (Dialog, Modal), `.focus()` / `.blur()` (form fields), `.value` (form fields).
|
|
507
|
+
|
|
508
|
+
---
|
|
509
|
+
|
|
510
|
+
## Patterns
|
|
511
|
+
|
|
512
|
+
**Controlled form field:**
|
|
513
|
+
```tsx
|
|
514
|
+
const [name, setName] = useState('');
|
|
515
|
+
<TextField
|
|
516
|
+
value={name}
|
|
517
|
+
onChange={(e: Event) => setName((e.target as HTMLInputElement).value)}
|
|
518
|
+
>
|
|
519
|
+
Name
|
|
520
|
+
</TextField>
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
**Submit + success/failure events from a connected form (e.g. EntityManagement):**
|
|
524
|
+
```tsx
|
|
525
|
+
<EntityManagement
|
|
526
|
+
resourceName="ALL_USERS"
|
|
527
|
+
onSubmitSuccess={(e: CustomEvent) => toast.show('Saved')}
|
|
528
|
+
onSubmitFailure={(e: CustomEvent) => toast.show(`Error: ${e.detail?.message}`, 'critical')}
|
|
529
|
+
/>
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
**Open a dialog from a list-row action:**
|
|
533
|
+
```tsx
|
|
534
|
+
const [editing, setEditing] = useState<User | null>(null);
|
|
535
|
+
const dialog = useRef<DialogRef>(null);
|
|
536
|
+
|
|
537
|
+
const onEdit = (user: User) => { setEditing(user); dialog.current?.show(); };
|
|
538
|
+
|
|
539
|
+
<Dialog ref={dialog}>
|
|
540
|
+
<div slot="top">Edit user</div>
|
|
541
|
+
{editing && <UserForm user={editing} />}
|
|
542
|
+
<Button slot="bottom" onClick={() => dialog.current?.close()}>Done</Button>
|
|
543
|
+
</Dialog>
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
---
|
|
547
|
+
|
|
548
|
+
## When this reference is silent
|
|
549
|
+
|
|
550
|
+
If you need a component or prop not listed here:
|
|
551
|
+
|
|
552
|
+
1. The full export list is the same as the names in the [Components by category](#buttons--actions) sections — there are 66 React wrappers in total. Anything from the `baseComponents` set has a wrapper.
|
|
553
|
+
2. To predict the prop API for an unlisted component, apply the [Conventions](#conventions) rules to its web component attribute names — that's exactly how the wrappers are generated.
|
|
554
|
+
3. For complex components (`GridPro`, `EntityManagement`, `Scheduler`), consult the project's existing usage rather than guessing — they have non-trivial setup (datasources, options) that this reference doesn't cover.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Side-effecting entry that registers the Rapid Design System and ensures
|
|
3
|
+
* a `<rapid-design-system-provider>` is present in the DOM so design tokens
|
|
4
|
+
* apply to all components.
|
|
5
|
+
*
|
|
6
|
+
* This package exists for AI/prototyping tools (e.g. Claude Artifacts) that
|
|
7
|
+
* load a single IIFE bundle from a CDN. App code should depend on
|
|
8
|
+
* `@genesislcap/rapid-design-system` directly and follow the standard
|
|
9
|
+
* registration pattern.
|
|
10
|
+
*/
|
|
11
|
+
import { baseComponents, provideDesignSystem, registerRapidDesignSystem } from '@genesislcap/rapid-design-system';
|
|
12
|
+
export { baseComponents, provideDesignSystem, registerRapidDesignSystem };
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAEL,cAAc,EAYd,mBAAmB,EACnB,yBAAyB,EAK1B,MAAM,kCAAkC,CAAC;AA6F1C,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,CAAC"}
|