@hirobius/design-system 0.10.0 → 0.12.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/README.md +44 -1
- package/dist/brand.js +36 -0
- package/dist/contexts.js +63 -59
- package/dist/hirobius-ui.js +22641 -3700
- package/dist/manifest.js +9 -9
- package/dist/scroll.js +42 -0
- package/dist/styles.css +1 -1
- package/dist/tokens.css +1 -1
- package/dist/tokens.js +26 -5
- package/dist/types/src/app/components/activity-feed.d.ts +24 -2
- package/dist/types/src/app/components/alert-dialog.d.ts +56 -0
- package/dist/types/src/app/components/app-shell.d.ts +38 -0
- package/dist/types/src/app/components/aspect-ratio.d.ts +25 -0
- package/dist/types/src/app/components/avatar-group.d.ts +22 -0
- package/dist/types/src/app/components/bleed.d.ts +39 -0
- package/dist/types/src/app/components/blockquote.d.ts +20 -0
- package/dist/types/src/app/components/box-sx.d.ts +69 -0
- package/dist/types/src/app/components/box.d.ts +42 -0
- package/dist/types/src/app/components/breadcrumb.d.ts +5 -0
- package/dist/types/src/app/components/button-group.d.ts +18 -0
- package/dist/types/src/app/components/calendar.d.ts +20 -0
- package/dist/types/src/app/components/card.d.ts +29 -13
- package/dist/types/src/app/components/carousel.d.ts +24 -0
- package/dist/types/src/app/components/center.d.ts +36 -0
- package/dist/types/src/app/components/circular-progress.d.ts +28 -0
- package/dist/types/src/app/components/cluster.d.ts +39 -0
- package/dist/types/src/app/components/code-block.d.ts +19 -1
- package/dist/types/src/app/components/command-palette.d.ts +44 -0
- package/dist/types/src/app/components/container.d.ts +10 -0
- package/dist/types/src/app/components/context-menu.d.ts +55 -0
- package/dist/types/src/app/components/cover.d.ts +43 -0
- package/dist/types/src/app/components/date-input.d.ts +31 -0
- package/dist/types/src/app/components/date-range-input.d.ts +34 -0
- package/dist/types/src/app/components/date-time-input.d.ts +30 -0
- package/dist/types/src/app/components/disclosure.d.ts +5 -1
- package/dist/types/src/app/components/divider.d.ts +14 -10
- package/dist/types/src/app/components/doc-link-card.d.ts +5 -1
- package/dist/types/src/app/components/field.d.ts +9 -11
- package/dist/types/src/app/components/file-input.d.ts +28 -0
- package/dist/types/src/app/components/frame.d.ts +38 -0
- package/dist/types/src/app/components/hds-tooltip.d.ts +45 -0
- package/dist/types/src/app/components/heading-stack.d.ts +15 -5
- package/dist/types/src/app/components/hover-card.d.ts +31 -0
- package/dist/types/src/app/components/image-lightbox.d.ts +13 -0
- package/dist/types/src/app/components/inline-code.d.ts +14 -3
- package/dist/types/src/app/components/input-group.d.ts +23 -0
- package/dist/types/src/app/components/kbd.d.ts +18 -0
- package/dist/types/src/app/components/metadata-list.d.ts +43 -0
- package/dist/types/src/app/components/multi-selector.d.ts +40 -0
- package/dist/types/src/app/components/nav-group.d.ts +7 -2
- package/dist/types/src/app/components/nav-item.d.ts +12 -2
- package/dist/types/src/app/components/overflow-list.d.ts +19 -0
- package/dist/types/src/app/components/pin.d.ts +30 -0
- package/dist/types/src/app/components/reveal.d.ts +31 -0
- package/dist/types/src/app/components/segmented-control.d.ts +37 -3
- package/dist/types/src/app/components/selectable-card.d.ts +29 -0
- package/dist/types/src/app/components/side-nav.d.ts +21 -0
- package/dist/types/src/app/components/sidebar.d.ts +45 -0
- package/dist/types/src/app/components/stat.d.ts +8 -10
- package/dist/types/src/app/components/status-dot.d.ts +25 -0
- package/dist/types/src/app/components/status-list-item.d.ts +10 -11
- package/dist/types/src/app/components/stepper.d.ts +31 -0
- package/dist/types/src/app/components/switcher.d.ts +41 -0
- package/dist/types/src/app/components/table.d.ts +12 -1
- package/dist/types/src/app/components/tag.d.ts +19 -18
- package/dist/types/src/app/components/text.d.ts +8 -2
- package/dist/types/src/app/components/textarea.d.ts +38 -0
- package/dist/types/src/app/components/time-input.d.ts +24 -0
- package/dist/types/src/app/components/timestamp.d.ts +24 -0
- package/dist/types/src/app/components/toast.d.ts +8 -2
- package/dist/types/src/app/components/toggle-button.d.ts +32 -0
- package/dist/types/src/app/components/token.d.ts +26 -1
- package/dist/types/src/app/components/tokenizer.d.ts +24 -0
- package/dist/types/src/app/components/toolbar.d.ts +36 -0
- package/dist/types/src/app/components/top-nav.d.ts +21 -0
- package/dist/types/src/app/components/tree-list.d.ts +28 -0
- package/dist/types/src/app/components/visually-hidden.d.ts +17 -0
- package/dist/types/src/app/context/TenantContext.d.ts +1 -1
- package/dist/types/src/app/context/hds-theme.d.ts +68 -0
- package/dist/types/src/app/data/nav-model.d.ts +39 -0
- package/dist/types/src/app/design-system/generated-token-refs.d.ts +20 -0
- package/dist/types/src/app/design-system/generated-token-values.d.ts +14 -1
- package/dist/types/src/app/{pages/hds → layouts}/HdsSystemDocLayout.d.ts +1 -1
- package/dist/types/src/app/lib/hds-search.d.ts +45 -0
- package/dist/types/src/brand/index.d.ts +9 -0
- package/dist/types/src/brand/overlay.d.ts +71 -0
- package/dist/types/src/index.d.ts +109 -2
- package/dist/types/src/scroll/index.d.ts +16 -0
- package/dist/types/src/scroll/smooth-scroll.d.ts +48 -0
- package/dist/types/src/scroll/use-scroll-progress.d.ts +34 -0
- package/dist/variables.css +22 -5
- package/hirobius.tokens.json +70 -10
- package/package.json +41 -68
- package/public/hds-manifest.json +6057 -4732
- package/dist/types/src/app/components/info-page.d.ts +0 -10
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** @internal — search engine behind the CommandPalette; not part of the public API. */
|
|
2
|
+
/**
|
|
3
|
+
* hds-search — the manifest search engine extracted from CommandPalette.
|
|
4
|
+
*
|
|
5
|
+
* A dependency-free subsequence + position scorer (think micro-fzf) over four
|
|
6
|
+
* corpora drawn from `virtual:hds-manifest`: component specs, utilities, role
|
|
7
|
+
* tokens, and curated foundation sections. Pure and side-effect-free — the
|
|
8
|
+
* manifest is passed in, never read from a module global — so it is unit-tested
|
|
9
|
+
* directly (see scripts/../tests/hds-search.test.ts) rather than through a
|
|
10
|
+
* component test hook.
|
|
11
|
+
*
|
|
12
|
+
* Lifted from command-palette.tsx per ADR-011's review (deep module behind a
|
|
13
|
+
* narrow interface): the UI shell now imports { buildIndex, rank } and owns no
|
|
14
|
+
* search logic.
|
|
15
|
+
*/
|
|
16
|
+
import type { ManifestSpec, RoleToken, SystemManifest } from '../data/manifest-types';
|
|
17
|
+
export type { ManifestSpec, RoleToken, SystemManifest };
|
|
18
|
+
export type ResultKind = 'component' | 'pattern' | 'template' | 'utility' | 'token' | 'section';
|
|
19
|
+
export interface PaletteResult {
|
|
20
|
+
id: string;
|
|
21
|
+
label: string;
|
|
22
|
+
description: string;
|
|
23
|
+
kind: ResultKind;
|
|
24
|
+
/** Where Enter/click navigates — relative React Router path. */
|
|
25
|
+
to: string;
|
|
26
|
+
/** Source string used for fuzzy matching (lowercased). */
|
|
27
|
+
haystack: string;
|
|
28
|
+
}
|
|
29
|
+
export declare const KIND_LABEL: Record<ResultKind, string>;
|
|
30
|
+
export declare const MAX_RESULTS = 30;
|
|
31
|
+
export declare function sanitize(text: string): string;
|
|
32
|
+
/** Build the searchable index from a manifest. Pure — pass the manifest in. */
|
|
33
|
+
export declare function buildIndex(manifest: SystemManifest): PaletteResult[];
|
|
34
|
+
/**
|
|
35
|
+
* Subsequence + position scorer:
|
|
36
|
+
* - Every char in `query` must appear in order inside `haystack`.
|
|
37
|
+
* - Earlier matches score higher (heavy weight on first hit).
|
|
38
|
+
* - Adjacent-char streaks score higher (clustered matches).
|
|
39
|
+
* - Word-start hits get a bonus.
|
|
40
|
+
*
|
|
41
|
+
* Returns -Infinity if `query` is not a subsequence of `haystack`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function fuzzyScore(query: string, haystack: string): number;
|
|
44
|
+
/** Rank items against a query. Empty query → a stable starter set. */
|
|
45
|
+
export declare function rank(query: string, items: PaletteResult[]): PaletteResult[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hirobius/design-system/brand — palette → HDS-semantic overlay bridge.
|
|
3
|
+
*
|
|
4
|
+
* Framework-free helpers that theme any render target (static Astro, SSR, email)
|
|
5
|
+
* from a small brand palette while inheriting the HDS semantic contract. Imports
|
|
6
|
+
* no React and no Node built-ins, so it is safe to pull into a build step or an
|
|
7
|
+
* edge runtime. See ./overlay.ts and docs on the Astro consumption path.
|
|
8
|
+
*/
|
|
9
|
+
export { brandOverlayVars, brandOverlayStyle, brandOverlayCss, type BrandPalette } from './overlay';
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* overlay.ts — pure palette → HDS-semantic overlay bridge.
|
|
3
|
+
*
|
|
4
|
+
* The seam that lets a downstream render target (a static Astro site, an email,
|
|
5
|
+
* an SSR shell) theme itself from a small brand palette while inheriting HDS's
|
|
6
|
+
* semantic contract — contrast-checked pairs, accent states, density, dark mode.
|
|
7
|
+
*
|
|
8
|
+
* A consumer resolves a brand palette (six colours + optional font/radius) and
|
|
9
|
+
* this module maps it onto the HDS semantic custom properties. Everything HDS
|
|
10
|
+
* ships downstream of those semantics (component tokens, utilities) then reads
|
|
11
|
+
* the brand automatically via the `var()` reference chain — the same strategy
|
|
12
|
+
* as the checked-in `[data-brand]` tenant overlays (`src/styles/tenants.css`),
|
|
13
|
+
* but computed at the consumer instead of at HDS build time, so HDS never has
|
|
14
|
+
* to know the client roster.
|
|
15
|
+
*
|
|
16
|
+
* Deliberately dependency-free (no React, no Node) so it runs in any render
|
|
17
|
+
* target and is unit-testable in isolation. Mirrors the zero-dependency idiom
|
|
18
|
+
* of `box-sx.ts`.
|
|
19
|
+
*
|
|
20
|
+
* Interactive accent states (hover/pressed/subtle) are derived from the primary
|
|
21
|
+
* with CSS `color-mix()` — no colour-math dependency, resolved by the browser.
|
|
22
|
+
* `color-mix()` is Baseline-supported (all evergreen engines since 2023); the
|
|
23
|
+
* factory ships new sites, so this is a safe floor.
|
|
24
|
+
*
|
|
25
|
+
* @packageDocumentation
|
|
26
|
+
*/
|
|
27
|
+
/** A resolved brand palette — the minimal input needed to theme a surface. */
|
|
28
|
+
export interface BrandPalette {
|
|
29
|
+
/** Primary brand colour — accent rest, key surfaces, links. */
|
|
30
|
+
primary: string;
|
|
31
|
+
/** Text/icon colour that sits on top of `primary`. */
|
|
32
|
+
onPrimary: string;
|
|
33
|
+
/** Page background. */
|
|
34
|
+
bg: string;
|
|
35
|
+
/** Body/foreground text colour. */
|
|
36
|
+
fg: string;
|
|
37
|
+
/** Muted surface — raised cards, subtle fills. */
|
|
38
|
+
muted: string;
|
|
39
|
+
/** Optional secondary accent. Kept brand-level (HDS has one accent ramp). */
|
|
40
|
+
accent?: string;
|
|
41
|
+
/** Optional corner radius as a CSS length (e.g. `'8px'`). */
|
|
42
|
+
radius?: string;
|
|
43
|
+
/** Optional heading font stack. */
|
|
44
|
+
fontHeading?: string;
|
|
45
|
+
/** Optional body font stack. */
|
|
46
|
+
fontBody?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Map a brand palette onto HDS semantic (and a few primitive) custom
|
|
50
|
+
* properties. Returns a flat `--var` → value record; the caller decides how to
|
|
51
|
+
* apply it (inline style string via {@link brandOverlayStyle} or a scoped CSS
|
|
52
|
+
* rule via {@link brandOverlayCss}).
|
|
53
|
+
*
|
|
54
|
+
* Only the accent ramp, page/content colours, and — when provided — radius and
|
|
55
|
+
* font families are overridden. All other semantics inherit HDS defaults
|
|
56
|
+
* unchanged, so a partial palette still yields a coherent theme.
|
|
57
|
+
*/
|
|
58
|
+
export declare function brandOverlayVars(palette: BrandPalette): Record<string, string>;
|
|
59
|
+
/**
|
|
60
|
+
* Serialize a palette to an inline `style` string (`k:v;k:v`) for the `<html>`
|
|
61
|
+
* element. Inline element styles beat stylesheet rules, so this is the most
|
|
62
|
+
* direct per-surface theming path (the model the clients factory already uses).
|
|
63
|
+
*/
|
|
64
|
+
export declare function brandOverlayStyle(palette: BrandPalette): string;
|
|
65
|
+
/**
|
|
66
|
+
* Serialize a palette to a scoped CSS rule (`<selector>{ --var: value; }`) for
|
|
67
|
+
* a static stylesheet — e.g. `[data-brand="acme"]` blocks in an Astro layout,
|
|
68
|
+
* mirroring the checked-in tenant overlays. `selector` is emitted verbatim; the
|
|
69
|
+
* caller owns its trust (typically a slug it controls).
|
|
70
|
+
*/
|
|
71
|
+
export declare function brandOverlayCss(selector: string, palette: BrandPalette): string;
|
|
@@ -2,6 +2,7 @@ export * from './app/components/alert';
|
|
|
2
2
|
export * from './app/components/asset-img';
|
|
3
3
|
export * from './app/components/avatar';
|
|
4
4
|
export * from './app/components/badge';
|
|
5
|
+
export * from './app/components/box';
|
|
5
6
|
export * from './app/components/button';
|
|
6
7
|
export * from './app/components/callout';
|
|
7
8
|
export * from './app/components/field';
|
|
@@ -16,6 +17,7 @@ export * from './app/components/dialog';
|
|
|
16
17
|
export * from './app/components/divider';
|
|
17
18
|
export * from './app/components/menu';
|
|
18
19
|
export * from './app/components/popover';
|
|
20
|
+
export * from './app/components/hds-tooltip';
|
|
19
21
|
export * from './app/components/doc-link-card';
|
|
20
22
|
export * from './app/components/grid';
|
|
21
23
|
export * from './app/components/heading-stack';
|
|
@@ -24,6 +26,7 @@ export * from './app/components/icon';
|
|
|
24
26
|
export * from './app/components/inline-code';
|
|
25
27
|
export * from './app/components/inline-link';
|
|
26
28
|
export * from './app/components/input';
|
|
29
|
+
export * from './app/components/textarea';
|
|
27
30
|
export * from './app/components/checkbox';
|
|
28
31
|
export * from './app/components/radio';
|
|
29
32
|
export * from './app/components/slider';
|
|
@@ -39,6 +42,49 @@ export * from './app/components/table';
|
|
|
39
42
|
export * from './app/components/tag';
|
|
40
43
|
export * from './app/components/text';
|
|
41
44
|
export * from './app/components/token';
|
|
45
|
+
export * from './app/components/kbd';
|
|
46
|
+
export * from './app/components/status-dot';
|
|
47
|
+
export * from './app/components/timestamp';
|
|
48
|
+
export * from './app/components/blockquote';
|
|
49
|
+
export * from './app/components/visually-hidden';
|
|
50
|
+
export * from './app/components/avatar-group';
|
|
51
|
+
export * from './app/components/button-group';
|
|
52
|
+
export * from './app/components/input-group';
|
|
53
|
+
export * from './app/components/circular-progress';
|
|
54
|
+
export * from './app/components/toggle-button';
|
|
55
|
+
export * from './app/components/aspect-ratio';
|
|
56
|
+
export * from './app/components/alert-dialog';
|
|
57
|
+
export * from './app/components/hover-card';
|
|
58
|
+
export * from './app/components/context-menu';
|
|
59
|
+
export * from './app/components/side-nav';
|
|
60
|
+
export * from './app/components/command-palette';
|
|
61
|
+
export * from './app/components/image-lightbox';
|
|
62
|
+
export * from './app/components/metadata-list';
|
|
63
|
+
export * from './app/components/overflow-list';
|
|
64
|
+
export * from './app/components/top-nav';
|
|
65
|
+
export * from './app/components/app-shell';
|
|
66
|
+
export * from './app/components/selectable-card';
|
|
67
|
+
export * from './app/components/tokenizer';
|
|
68
|
+
export * from './app/components/file-input';
|
|
69
|
+
export * from './app/components/multi-selector';
|
|
70
|
+
export * from './app/components/toolbar';
|
|
71
|
+
export * from './app/components/tree-list';
|
|
72
|
+
export * from './app/components/stepper';
|
|
73
|
+
export * from './app/components/carousel';
|
|
74
|
+
export * from './app/components/calendar';
|
|
75
|
+
export * from './app/components/time-input';
|
|
76
|
+
export * from './app/components/date-input';
|
|
77
|
+
export * from './app/components/date-range-input';
|
|
78
|
+
export * from './app/components/date-time-input';
|
|
79
|
+
export * from './app/components/cluster';
|
|
80
|
+
export * from './app/components/center';
|
|
81
|
+
export * from './app/components/sidebar';
|
|
82
|
+
export * from './app/components/switcher';
|
|
83
|
+
export * from './app/components/cover';
|
|
84
|
+
export * from './app/components/frame';
|
|
85
|
+
export * from './app/components/bleed';
|
|
86
|
+
export * from './app/components/reveal';
|
|
87
|
+
export * from './app/components/pin';
|
|
42
88
|
export * from './app/components/page';
|
|
43
89
|
export * from './app/components/empty-state';
|
|
44
90
|
export * from './app/components/error-boundary';
|
|
@@ -61,8 +107,7 @@ export * from './app/components/text-lockup';
|
|
|
61
107
|
export * from './app/components/toast';
|
|
62
108
|
export * from './app/layouts/CaseStudyLayout';
|
|
63
109
|
export * from './app/components/error-pattern';
|
|
64
|
-
export * from './app/
|
|
65
|
-
export * from './app/pages/hds/HdsSystemDocLayout';
|
|
110
|
+
export * from './app/layouts/HdsSystemDocLayout';
|
|
66
111
|
export { default as hds } from './app/design-system/tokens';
|
|
67
112
|
/** Raw DTCG design tokens (the contents of `hirobius.tokens.json`). */
|
|
68
113
|
export declare const tokens: {
|
|
@@ -235,6 +280,53 @@ export declare const tokens: {
|
|
|
235
280
|
};
|
|
236
281
|
$description: string;
|
|
237
282
|
};
|
|
283
|
+
lilac: {
|
|
284
|
+
"50": {
|
|
285
|
+
$value: string;
|
|
286
|
+
$description: string;
|
|
287
|
+
};
|
|
288
|
+
"100": {
|
|
289
|
+
$value: string;
|
|
290
|
+
$description: string;
|
|
291
|
+
};
|
|
292
|
+
"200": {
|
|
293
|
+
$value: string;
|
|
294
|
+
$description: string;
|
|
295
|
+
};
|
|
296
|
+
"300": {
|
|
297
|
+
$value: string;
|
|
298
|
+
$description: string;
|
|
299
|
+
};
|
|
300
|
+
"400": {
|
|
301
|
+
$value: string;
|
|
302
|
+
$description: string;
|
|
303
|
+
};
|
|
304
|
+
"450": {
|
|
305
|
+
$value: string;
|
|
306
|
+
$description: string;
|
|
307
|
+
};
|
|
308
|
+
"500": {
|
|
309
|
+
$value: string;
|
|
310
|
+
$description: string;
|
|
311
|
+
};
|
|
312
|
+
"600": {
|
|
313
|
+
$value: string;
|
|
314
|
+
$description: string;
|
|
315
|
+
};
|
|
316
|
+
"700": {
|
|
317
|
+
$value: string;
|
|
318
|
+
$description: string;
|
|
319
|
+
};
|
|
320
|
+
"800": {
|
|
321
|
+
$value: string;
|
|
322
|
+
$description: string;
|
|
323
|
+
};
|
|
324
|
+
"900": {
|
|
325
|
+
$value: string;
|
|
326
|
+
$description: string;
|
|
327
|
+
};
|
|
328
|
+
$description: string;
|
|
329
|
+
};
|
|
238
330
|
amber: {
|
|
239
331
|
"50": {
|
|
240
332
|
$value: string;
|
|
@@ -1557,6 +1649,19 @@ export declare const tokens: {
|
|
|
1557
1649
|
};
|
|
1558
1650
|
$description: string;
|
|
1559
1651
|
};
|
|
1652
|
+
caption: {
|
|
1653
|
+
$value: {
|
|
1654
|
+
fontFamily: string;
|
|
1655
|
+
fontSize: {
|
|
1656
|
+
value: number;
|
|
1657
|
+
unit: string;
|
|
1658
|
+
};
|
|
1659
|
+
fontWeight: string;
|
|
1660
|
+
letterSpacing: string;
|
|
1661
|
+
lineHeight: string;
|
|
1662
|
+
};
|
|
1663
|
+
$description: string;
|
|
1664
|
+
};
|
|
1560
1665
|
eyebrow: {
|
|
1561
1666
|
$value: {
|
|
1562
1667
|
fontFamily: string;
|
|
@@ -2315,5 +2420,7 @@ export declare const tokens: {
|
|
|
2315
2420
|
};
|
|
2316
2421
|
};
|
|
2317
2422
|
export { cn } from './lib/utils';
|
|
2423
|
+
export { HdsThemeProvider, useHdsTheme } from './app/context/hds-theme';
|
|
2424
|
+
export type { HdsTheme, HdsDensity, HdsThemeValue, HdsThemeProviderProps, } from './app/context/hds-theme';
|
|
2318
2425
|
export { HdsRouterProvider, useHdsRouter } from './app/context/RouterContext';
|
|
2319
2426
|
export type { HdsRouterAdapter, HdsRouterProviderProps, HdsLinkComponent, HdsLinkProps, HdsNavigateOptions, } from './app/context/RouterContext';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hirobius/design-system/scroll — opt-in scroll-motion primitives.
|
|
3
|
+
*
|
|
4
|
+
* Ships behind a dedicated subpath with `lenis` as an OPTIONAL peer dependency
|
|
5
|
+
* (install `lenis` alongside HDS to use `SmoothScroll`). Never in the main
|
|
6
|
+
* barrel — consumers who don't import this pay nothing. See ADR-021 and #116.
|
|
7
|
+
*
|
|
8
|
+
* - `SmoothScroll` — Lenis momentum-scroll provider (reduced-motion-first, SSR-safe).
|
|
9
|
+
* - `useLenis` — access the active Lenis instance / subscribe to scroll (re-exported
|
|
10
|
+
* from `lenis/react`).
|
|
11
|
+
* - `useScrollProgress` — Motion-based 0→1 scroll progress for a target element
|
|
12
|
+
* (no new dependency; works with or without `SmoothScroll`).
|
|
13
|
+
*/
|
|
14
|
+
export { SmoothScroll, type SmoothScrollProps, type SmoothScrollOptions } from './smooth-scroll';
|
|
15
|
+
export { useScrollProgress, type UseScrollProgressOptions, type ScrollOffset, } from './use-scroll-progress';
|
|
16
|
+
export { useLenis } from 'lenis/react';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SmoothScroll — opt-in Lenis smooth-scroll provider for HDS.
|
|
3
|
+
*
|
|
4
|
+
* The one scroll capability neither CSS `animation-timeline` nor Motion's
|
|
5
|
+
* `useScroll` can provide: momentum-smoothed ("inertia") scrolling. Ships behind
|
|
6
|
+
* the dedicated `@hirobius/design-system/scroll` subpath with `lenis` as an
|
|
7
|
+
* OPTIONAL peer dependency, so it is never in the main barrel and consumers who
|
|
8
|
+
* don't import it pay nothing (ADR-021).
|
|
9
|
+
*
|
|
10
|
+
* Wraps Lenis's official React integration (`lenis/react`) and adds HDS
|
|
11
|
+
* conventions:
|
|
12
|
+
* - **Reduced-motion first.** When the user prefers reduced motion, Lenis is
|
|
13
|
+
* not instantiated at all — children render against native scroll. Override
|
|
14
|
+
* with `ignoreReducedMotion` only for a deliberate art-directed exception.
|
|
15
|
+
* - **SSR-safe.** The reduced-motion probe runs client-side; server render and
|
|
16
|
+
* first paint fall back to native scroll, then upgrade on mount.
|
|
17
|
+
* - **Tokenized defaults.** A premium duration/easing out of the box,
|
|
18
|
+
* overridable via `options`.
|
|
19
|
+
*
|
|
20
|
+
* Lenis drives the real scroll position, so CSS scroll-driven animations and
|
|
21
|
+
* `useScrollProgress` (Motion) keep working underneath it unchanged.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* import { SmoothScroll } from '@hirobius/design-system/scroll';
|
|
25
|
+
* // one provider at the app/site root:
|
|
26
|
+
* <SmoothScroll><App /></SmoothScroll>
|
|
27
|
+
*/
|
|
28
|
+
import * as React from 'react';
|
|
29
|
+
import { ReactLenis } from 'lenis/react';
|
|
30
|
+
/** Lenis options, derived from the official React integration (no extra import). */
|
|
31
|
+
export type SmoothScrollOptions = NonNullable<React.ComponentProps<typeof ReactLenis>['options']>;
|
|
32
|
+
export interface SmoothScrollProps {
|
|
33
|
+
children: React.ReactNode;
|
|
34
|
+
/** Lenis options merged over the HDS defaults (duration, easing, smoothWheel). */
|
|
35
|
+
options?: SmoothScrollOptions;
|
|
36
|
+
/**
|
|
37
|
+
* Hijack the window/document scroll (the usual root-level setup). Default `true`.
|
|
38
|
+
* Set `false` to scope smoothing to a wrapper element instead.
|
|
39
|
+
*/
|
|
40
|
+
root?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Run smoothing even when the user prefers reduced motion. Default `false`
|
|
43
|
+
* (the preference is respected — momentum scroll is a motion effect).
|
|
44
|
+
*/
|
|
45
|
+
ignoreReducedMotion?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/** @public */
|
|
48
|
+
export declare function SmoothScroll({ children, options, root, ignoreReducedMotion, }: SmoothScrollProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useScrollProgress — a tokenized wrapper over Motion's `useScroll`.
|
|
3
|
+
*
|
|
4
|
+
* Returns a `0 → 1` MotionValue tracking a target element's travel through the
|
|
5
|
+
* viewport, for JS-driven scroll effects that CSS `animation-timeline` can't
|
|
6
|
+
* express (cross-element choreography, canvas/WebGL, values you need in React).
|
|
7
|
+
* Built on `motion/react` — already the HDS animation engine — so it adds no new
|
|
8
|
+
* dependency, and it works with or without {@link SmoothScroll} (Lenis drives
|
|
9
|
+
* the real scroll position, which Motion reads).
|
|
10
|
+
*
|
|
11
|
+
* For the common "reveal on enter / scale on scroll" cases, prefer CSS
|
|
12
|
+
* scroll-driven animation (`animation-timeline: view()`) — zero JS. Reach for
|
|
13
|
+
* this hook only when you genuinely need the progress value in React.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const ref = useRef<HTMLDivElement>(null);
|
|
17
|
+
* const progress = useScrollProgress(ref);
|
|
18
|
+
* const scale = useTransform(progress, [0, 1], [0.4, 1]);
|
|
19
|
+
* return <motion.div ref={ref} style={{ scale }} />;
|
|
20
|
+
*/
|
|
21
|
+
import { useScroll, type MotionValue } from 'motion/react';
|
|
22
|
+
import type { RefObject } from 'react';
|
|
23
|
+
/** Scroll offset pair (Motion `useScroll` semantics), e.g. `['start end', 'end start']`. */
|
|
24
|
+
export type ScrollOffset = NonNullable<Parameters<typeof useScroll>[0]>['offset'];
|
|
25
|
+
export interface UseScrollProgressOptions {
|
|
26
|
+
/**
|
|
27
|
+
* Where progress starts (0) and ends (1), in Motion's `[targetEdge viewportEdge, …]`
|
|
28
|
+
* form. Defaults to `['start end', 'end start']` — 0 as the target's top enters
|
|
29
|
+
* the bottom of the viewport, 1 as its bottom leaves the top.
|
|
30
|
+
*/
|
|
31
|
+
offset?: ScrollOffset;
|
|
32
|
+
}
|
|
33
|
+
/** @public */
|
|
34
|
+
export declare function useScrollProgress(target: RefObject<HTMLElement | null>, options?: UseScrollProgressOptions): MotionValue<number>;
|
package/dist/variables.css
CHANGED
|
@@ -52,6 +52,17 @@
|
|
|
52
52
|
--primitive-color-violet-400: #a78bfa;
|
|
53
53
|
--primitive-color-violet-700: #6d28d9;
|
|
54
54
|
--primitive-color-violet-950: #2e1065;
|
|
55
|
+
--primitive-color-lilac-50: #f7f4fe;
|
|
56
|
+
--primitive-color-lilac-100: #efe9fd;
|
|
57
|
+
--primitive-color-lilac-200: #ddd0fb;
|
|
58
|
+
--primitive-color-lilac-300: #c3aef6;
|
|
59
|
+
--primitive-color-lilac-400: #a585ee;
|
|
60
|
+
--primitive-color-lilac-450: #9a6fe8;
|
|
61
|
+
--primitive-color-lilac-500: #6f3fd4;
|
|
62
|
+
--primitive-color-lilac-600: #5f33c0;
|
|
63
|
+
--primitive-color-lilac-700: #4f2aa3;
|
|
64
|
+
--primitive-color-lilac-800: #3a1f78;
|
|
65
|
+
--primitive-color-lilac-900: #2a1659;
|
|
55
66
|
--primitive-color-amber-50: #fffbeb;
|
|
56
67
|
--primitive-color-amber-400: #fbbf24;
|
|
57
68
|
--primitive-color-amber-800: #92400e;
|
|
@@ -95,7 +106,7 @@
|
|
|
95
106
|
--primitive-radius-12: 12px;
|
|
96
107
|
--primitive-radius-full: 9999px;
|
|
97
108
|
--primitive-typography-family-primary: Satoshi, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
98
|
-
--primitive-typography-family-display:
|
|
109
|
+
--primitive-typography-family-display: Satoshi, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
99
110
|
--primitive-typography-family-mono: "Geist Mono", "Courier New", monospace;
|
|
100
111
|
--primitive-typography-size-2xs: 10px;
|
|
101
112
|
--primitive-typography-size-xs: 13px;
|
|
@@ -238,25 +249,25 @@
|
|
|
238
249
|
/* semantic.typography.display */
|
|
239
250
|
--semantic-typography-display-font-family: var(--primitive-typography-family-display);
|
|
240
251
|
--semantic-typography-display-font-size: var(--primitive-typography-size-7xl);
|
|
241
|
-
--semantic-typography-display-font-weight: var(--primitive-typography-weight-
|
|
252
|
+
--semantic-typography-display-font-weight: var(--primitive-typography-weight-bold);
|
|
242
253
|
--semantic-typography-display-letter-spacing: var(--primitive-typography-letterSpacing-tight);
|
|
243
254
|
--semantic-typography-display-line-height: var(--primitive-typography-lineHeight-none);
|
|
244
255
|
/* semantic.typography.h1 */
|
|
245
256
|
--semantic-typography-h1-font-family: var(--primitive-typography-family-display);
|
|
246
257
|
--semantic-typography-h1-font-size: var(--primitive-typography-size-4xl);
|
|
247
|
-
--semantic-typography-h1-font-weight: var(--primitive-typography-weight-
|
|
258
|
+
--semantic-typography-h1-font-weight: var(--primitive-typography-weight-bold);
|
|
248
259
|
--semantic-typography-h1-letter-spacing: var(--primitive-typography-letterSpacing-tight);
|
|
249
260
|
--semantic-typography-h1-line-height: var(--primitive-typography-lineHeight-tight);
|
|
250
261
|
/* semantic.typography.h2 */
|
|
251
262
|
--semantic-typography-h2-font-family: var(--primitive-typography-family-display);
|
|
252
263
|
--semantic-typography-h2-font-size: var(--primitive-typography-size-2xl);
|
|
253
|
-
--semantic-typography-h2-font-weight: var(--primitive-typography-weight-
|
|
264
|
+
--semantic-typography-h2-font-weight: var(--primitive-typography-weight-bold);
|
|
254
265
|
--semantic-typography-h2-letter-spacing: var(--primitive-typography-letterSpacing-tight);
|
|
255
266
|
--semantic-typography-h2-line-height: 42px;
|
|
256
267
|
/* semantic.typography.h3 */
|
|
257
268
|
--semantic-typography-h3-font-family: var(--primitive-typography-family-display);
|
|
258
269
|
--semantic-typography-h3-font-size: var(--primitive-typography-size-lg);
|
|
259
|
-
--semantic-typography-h3-font-weight: var(--primitive-typography-weight-
|
|
270
|
+
--semantic-typography-h3-font-weight: var(--primitive-typography-weight-bold);
|
|
260
271
|
--semantic-typography-h3-letter-spacing: var(--primitive-typography-letterSpacing-normal);
|
|
261
272
|
--semantic-typography-h3-line-height: 28px;
|
|
262
273
|
/* semantic.typography.body */
|
|
@@ -273,6 +284,12 @@
|
|
|
273
284
|
--semantic-typography-ui-letter-spacing: var(--primitive-typography-letterSpacing-normal);
|
|
274
285
|
--semantic-typography-ui-line-height: 24px;
|
|
275
286
|
--semantic-typography-ui-max-width: 60ch;
|
|
287
|
+
/* semantic.typography.caption */
|
|
288
|
+
--semantic-typography-caption-font-family: var(--primitive-typography-family-primary);
|
|
289
|
+
--semantic-typography-caption-font-size: 12px;
|
|
290
|
+
--semantic-typography-caption-font-weight: var(--primitive-typography-weight-medium);
|
|
291
|
+
--semantic-typography-caption-letter-spacing: var(--primitive-typography-letterSpacing-normal);
|
|
292
|
+
--semantic-typography-caption-line-height: 16px;
|
|
276
293
|
/* semantic.typography.eyebrow */
|
|
277
294
|
--semantic-typography-eyebrow-font-family: var(--primitive-typography-family-primary);
|
|
278
295
|
--semantic-typography-eyebrow-font-size: var(--primitive-typography-size-xs);
|
package/hirobius.tokens.json
CHANGED
|
@@ -168,6 +168,53 @@
|
|
|
168
168
|
},
|
|
169
169
|
"$description": "Discrete values within the violet range at defined lightness steps."
|
|
170
170
|
},
|
|
171
|
+
"lilac": {
|
|
172
|
+
"50": {
|
|
173
|
+
"$value": "#f7f4fe",
|
|
174
|
+
"$description": "Specific value within the lilac range at a defined lightness step."
|
|
175
|
+
},
|
|
176
|
+
"100": {
|
|
177
|
+
"$value": "#efe9fd",
|
|
178
|
+
"$description": "Specific value within the lilac range at a defined lightness step."
|
|
179
|
+
},
|
|
180
|
+
"200": {
|
|
181
|
+
"$value": "#ddd0fb",
|
|
182
|
+
"$description": "Specific value within the lilac range at a defined lightness step."
|
|
183
|
+
},
|
|
184
|
+
"300": {
|
|
185
|
+
"$value": "#c3aef6",
|
|
186
|
+
"$description": "Specific value within the lilac range at a defined lightness step."
|
|
187
|
+
},
|
|
188
|
+
"400": {
|
|
189
|
+
"$value": "#a585ee",
|
|
190
|
+
"$description": "Specific value within the lilac range at a defined lightness step."
|
|
191
|
+
},
|
|
192
|
+
"450": {
|
|
193
|
+
"$value": "#9a6fe8",
|
|
194
|
+
"$description": "Specific value within the lilac range at a defined lightness step."
|
|
195
|
+
},
|
|
196
|
+
"500": {
|
|
197
|
+
"$value": "#6f3fd4",
|
|
198
|
+
"$description": "Lilac Bonds accent rest — AA for white text on page and card surfaces."
|
|
199
|
+
},
|
|
200
|
+
"600": {
|
|
201
|
+
"$value": "#5f33c0",
|
|
202
|
+
"$description": "Specific value within the lilac range at a defined lightness step."
|
|
203
|
+
},
|
|
204
|
+
"700": {
|
|
205
|
+
"$value": "#4f2aa3",
|
|
206
|
+
"$description": "Specific value within the lilac range at a defined lightness step."
|
|
207
|
+
},
|
|
208
|
+
"800": {
|
|
209
|
+
"$value": "#3a1f78",
|
|
210
|
+
"$description": "Specific value within the lilac range at a defined lightness step."
|
|
211
|
+
},
|
|
212
|
+
"900": {
|
|
213
|
+
"$value": "#2a1659",
|
|
214
|
+
"$description": "Specific value within the lilac range at a defined lightness step."
|
|
215
|
+
},
|
|
216
|
+
"$description": "Discrete values within the lilac range at defined lightness steps. Mirrors the blue ramp's stop set; consumed by the lilac-bonds tenant overlay."
|
|
217
|
+
},
|
|
171
218
|
"amber": {
|
|
172
219
|
"50": {
|
|
173
220
|
"$value": "#fffbeb",
|
|
@@ -432,14 +479,14 @@
|
|
|
432
479
|
},
|
|
433
480
|
"display": {
|
|
434
481
|
"$value": [
|
|
435
|
-
"
|
|
482
|
+
"Satoshi",
|
|
436
483
|
"system-ui",
|
|
437
484
|
"-apple-system",
|
|
438
485
|
"BlinkMacSystemFont",
|
|
439
486
|
"Segoe UI",
|
|
440
487
|
"sans-serif"
|
|
441
488
|
],
|
|
442
|
-
"$description": "Display face:
|
|
489
|
+
"$description": "Display face: Satoshi Bold (ITF), bound to display/h1/h2/h3 composites."
|
|
443
490
|
},
|
|
444
491
|
"mono": {
|
|
445
492
|
"$value": ["Geist Mono", "Courier New", "monospace"],
|
|
@@ -1416,11 +1463,11 @@
|
|
|
1416
1463
|
"$value": {
|
|
1417
1464
|
"fontFamily": "{primitive.typography.family.display}",
|
|
1418
1465
|
"fontSize": "{primitive.typography.size.7xl}",
|
|
1419
|
-
"fontWeight": "{primitive.typography.weight.
|
|
1466
|
+
"fontWeight": "{primitive.typography.weight.bold}",
|
|
1420
1467
|
"letterSpacing": "{primitive.typography.letterSpacing.tight}",
|
|
1421
1468
|
"lineHeight": "{primitive.typography.lineHeight.none}"
|
|
1422
1469
|
},
|
|
1423
|
-
"$description": "Display headline. 72px /
|
|
1470
|
+
"$description": "Display headline. 72px / Satoshi bold 700 / leading-none.",
|
|
1424
1471
|
"$extensions": {
|
|
1425
1472
|
"com.figma.variables": {
|
|
1426
1473
|
"fontSize": "clamp(40px, 8vw, 72px)",
|
|
@@ -1432,11 +1479,11 @@
|
|
|
1432
1479
|
"$value": {
|
|
1433
1480
|
"fontFamily": "{primitive.typography.family.display}",
|
|
1434
1481
|
"fontSize": "{primitive.typography.size.4xl}",
|
|
1435
|
-
"fontWeight": "{primitive.typography.weight.
|
|
1482
|
+
"fontWeight": "{primitive.typography.weight.bold}",
|
|
1436
1483
|
"letterSpacing": "{primitive.typography.letterSpacing.tight}",
|
|
1437
1484
|
"lineHeight": "{primitive.typography.lineHeight.tight}"
|
|
1438
1485
|
},
|
|
1439
|
-
"$description": "Primary section headings (h1). 48px /
|
|
1486
|
+
"$description": "Primary section headings (h1). 48px / Satoshi bold 700 / leading-tight.",
|
|
1440
1487
|
"$extensions": {
|
|
1441
1488
|
"com.figma.variables": {
|
|
1442
1489
|
"fontSize": "clamp(32px, 6vw, 48px)",
|
|
@@ -1448,11 +1495,11 @@
|
|
|
1448
1495
|
"$value": {
|
|
1449
1496
|
"fontFamily": "{primitive.typography.family.display}",
|
|
1450
1497
|
"fontSize": "{primitive.typography.size.2xl}",
|
|
1451
|
-
"fontWeight": "{primitive.typography.weight.
|
|
1498
|
+
"fontWeight": "{primitive.typography.weight.bold}",
|
|
1452
1499
|
"letterSpacing": "{primitive.typography.letterSpacing.tight}",
|
|
1453
1500
|
"lineHeight": "42px"
|
|
1454
1501
|
},
|
|
1455
|
-
"$description": "Secondary section headings (h2).
|
|
1502
|
+
"$description": "Secondary section headings (h2). Satoshi bold 700, 30px, line-height 42px.",
|
|
1456
1503
|
"$extensions": {
|
|
1457
1504
|
"com.figma.variables": {
|
|
1458
1505
|
"fontSize": "clamp(24px, 3.5vw, 30px)",
|
|
@@ -1464,11 +1511,11 @@
|
|
|
1464
1511
|
"$value": {
|
|
1465
1512
|
"fontFamily": "{primitive.typography.family.display}",
|
|
1466
1513
|
"fontSize": "{primitive.typography.size.lg}",
|
|
1467
|
-
"fontWeight": "{primitive.typography.weight.
|
|
1514
|
+
"fontWeight": "{primitive.typography.weight.bold}",
|
|
1468
1515
|
"letterSpacing": "{primitive.typography.letterSpacing.normal}",
|
|
1469
1516
|
"lineHeight": "28px"
|
|
1470
1517
|
},
|
|
1471
|
-
"$description": "Component and card headers (h3). 20px /
|
|
1518
|
+
"$description": "Component and card headers (h3). 20px / Satoshi bold 700 500 / leading-snug.",
|
|
1472
1519
|
"$extensions": {
|
|
1473
1520
|
"com.figma.variables": {
|
|
1474
1521
|
"fontSize": "clamp(18px, 2vw, 20px)",
|
|
@@ -1504,6 +1551,19 @@
|
|
|
1504
1551
|
},
|
|
1505
1552
|
"$description": "UI text for nav, labels, captions. Satoshi medium, 15px, line-height 24px."
|
|
1506
1553
|
},
|
|
1554
|
+
"caption": {
|
|
1555
|
+
"$value": {
|
|
1556
|
+
"fontFamily": "{primitive.typography.family.primary}",
|
|
1557
|
+
"fontSize": {
|
|
1558
|
+
"value": 12,
|
|
1559
|
+
"unit": "px"
|
|
1560
|
+
},
|
|
1561
|
+
"fontWeight": "{primitive.typography.weight.medium}",
|
|
1562
|
+
"letterSpacing": "{primitive.typography.letterSpacing.normal}",
|
|
1563
|
+
"lineHeight": "16px"
|
|
1564
|
+
},
|
|
1565
|
+
"$description": "Caption / helper text. Satoshi medium, 12px, line-height 16px. Matches the Figma typography/caption text style."
|
|
1566
|
+
},
|
|
1507
1567
|
"eyebrow": {
|
|
1508
1568
|
"$value": {
|
|
1509
1569
|
"fontFamily": "{primitive.typography.family.primary}",
|