@orianatech/pire 0.2.1 → 0.4.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 +43 -5
- package/dist/components/core/Icon.d.cts +22 -7
- package/dist/components/core/Icon.d.ts +22 -7
- package/dist/components/core/Icon.d.ts.map +1 -1
- package/dist/components/core/icon-data.generated.d.cts +1 -0
- package/dist/components/core/icon-data.generated.d.ts +2 -0
- package/dist/components/core/icon-data.generated.d.ts.map +1 -0
- package/dist/components/core/icon-map.d.cts +13 -0
- package/dist/components/core/icon-map.d.ts +14 -0
- package/dist/components/core/icon-map.d.ts.map +1 -0
- package/dist/components/feedback/Skeleton.d.cts +43 -0
- package/dist/components/feedback/Skeleton.d.ts +44 -0
- package/dist/components/feedback/Skeleton.d.ts.map +1 -0
- package/dist/components/forms/MultiComboBox.d.cts +58 -0
- package/dist/components/forms/MultiComboBox.d.ts +59 -0
- package/dist/components/forms/MultiComboBox.d.ts.map +1 -0
- package/dist/components/forms/TextArea.d.cts +42 -0
- package/dist/components/forms/TextArea.d.ts +43 -0
- package/dist/components/forms/TextArea.d.ts.map +1 -0
- package/dist/components/navigation/ShellBar.d.cts +8 -1
- package/dist/components/navigation/ShellBar.d.ts +8 -1
- package/dist/components/navigation/ShellBar.d.ts.map +1 -1
- package/dist/components/navigation/SideNav.d.cts +56 -4
- package/dist/components/navigation/SideNav.d.ts +56 -4
- package/dist/components/navigation/SideNav.d.ts.map +1 -1
- package/dist/components.css +73 -1
- package/dist/index.cjs +806 -353
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +809 -347
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -10,7 +10,8 @@ Requires Node 20+ and pnpm.
|
|
|
10
10
|
```bash
|
|
11
11
|
pnpm install
|
|
12
12
|
pnpm storybook # docs + playground at http://localhost:6006
|
|
13
|
-
pnpm build # dist/ (ESM + CJS + .d.ts + CSS)
|
|
13
|
+
pnpm build # dist/ (ESM + CJS + .d.ts + CSS), icon codegen first
|
|
14
|
+
pnpm icons:generate # re-inline the Carbon glyphs listed in icon-map.ts
|
|
14
15
|
pnpm typecheck # tsc --noEmit
|
|
15
16
|
pnpm lint # biome
|
|
16
17
|
```
|
|
@@ -76,14 +77,45 @@ Override tokens, never component rules:
|
|
|
76
77
|
|
|
77
78
|
### Icons
|
|
78
79
|
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
**Zero configuration, and no network.** Every glyph is inlined into the bundle at build time and
|
|
81
|
+
rendered as inline SVG, so icons paint offline, cost no requests, and report nothing to anyone.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
<Icon name="shopping-cart" size={20} /> {/* decorative: aria-hidden */}
|
|
85
|
+
<Icon name="lock" size={20} label="Locked record" /> {/* meaningful: role="img" + aria-label */}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Names are canonical **Lucide slugs**; the shipped pack is IBM Carbon, reached through an internal
|
|
89
|
+
map, so a pack swap never touches a call site. The same names are what the `icon` prop on `Button`,
|
|
90
|
+
`IconButton`, `Card`, `KpiTile`, `Tabs`, `EmptyState` and `InlineMessage` takes.
|
|
91
|
+
|
|
92
|
+
Glyphs are filled with `currentColor`, so an icon takes the colour of the text it sits in — style the
|
|
93
|
+
container, not the icon. `size` is the pixel box: 16 in dense UI, 20 in headers, 24 in tiles.
|
|
94
|
+
|
|
95
|
+
An unrecognised name renders an empty box of the right size and logs one `[pire]` console warning
|
|
96
|
+
naming it. The warning is compiled out of production builds.
|
|
97
|
+
|
|
98
|
+
The bundled set covers what the ERP screens use. For anything else, register the *inner* markup of a
|
|
99
|
+
32×32 SVG once at startup:
|
|
81
100
|
|
|
82
101
|
```ts
|
|
83
102
|
import { configureIcons } from '@orianatech/pire';
|
|
84
|
-
|
|
103
|
+
|
|
104
|
+
configureIcons({
|
|
105
|
+
resolve: (name) => (name === 'oriana-mark' ? '<circle cx="16" cy="16" r="8"/>' : undefined),
|
|
106
|
+
});
|
|
85
107
|
```
|
|
86
108
|
|
|
109
|
+
> **Upgrading from 0.3 or earlier.** Glyphs used to be fetched per render from `cdn.jsdelivr.net`,
|
|
110
|
+
> which meant blank icons in an offline PWA, so apps self-hosted the SVGs and called
|
|
111
|
+
> `configureIcons({ base })`. That is now unnecessary: **delete the `configureIcons({ base })` call
|
|
112
|
+
> and the vendored `<slug>.svg` files.** `base` and `pack` are still accepted so existing code keeps
|
|
113
|
+
> compiling, but they are ignored and warn in development. The `lucide` pack is gone —
|
|
114
|
+
> `pack="lucide"` now renders the Carbon glyph.
|
|
115
|
+
|
|
116
|
+
Adding a glyph to the library itself is one line in `src/components/core/icon-map.ts` plus a build;
|
|
117
|
+
see the Icons section of `CLAUDE.md`.
|
|
118
|
+
|
|
87
119
|
## Migrating from the HTML/JSX prototypes
|
|
88
120
|
|
|
89
121
|
| Prototype API | Package API |
|
|
@@ -104,7 +136,13 @@ configureIcons({ base: '/assets/icons/' }); // folder of <slug>.svg
|
|
|
104
136
|
|
|
105
137
|
## Toolchain notes
|
|
106
138
|
|
|
107
|
-
- `pnpm build` runs `
|
|
139
|
+
- `pnpm build` first runs `scripts/generate-icon-data.mjs`, which inlines the Carbon SVGs listed in
|
|
140
|
+
`src/components/core/icon-map.ts` into a committed `icon-data.generated.ts`. `@carbon/icons` is a
|
|
141
|
+
**devDependency on purpose** — it depends on `@ibm/telemetry-js` and runs `ibmtelemetry` from a
|
|
142
|
+
`postinstall` script, which as a runtime dependency would execute in every app that installs Pire.
|
|
143
|
+
The generated file is committed because typecheck, lint, tests and Storybook all read `src/`
|
|
144
|
+
without building; its install script is denied in `pnpm-workspace.yaml`.
|
|
145
|
+
- `pnpm build` then runs `tsup` for the JS bundles, then `tsc -p tsconfig.build.json` for the
|
|
108
146
|
`.d.ts` files, then `scripts/postbuild-types.mjs`. tsup's own declaration pipeline is not
|
|
109
147
|
compatible with the TypeScript 7 native compiler, so `dts` is off in `tsup.config.ts` —
|
|
110
148
|
leave it that way. The post-pass makes the emitted declarations resolvable under
|
|
@@ -1,22 +1,37 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
/** @deprecated Retained only so existing `pack` values still typecheck. Glyphs are bundled from
|
|
3
|
+
* the Carbon pack; there is no second pack and no remote fetch, so the value is ignored. */
|
|
2
4
|
export type IconPack = 'carbon' | 'lucide';
|
|
3
5
|
export interface IconConfig {
|
|
4
|
-
/**
|
|
6
|
+
/** @deprecated Ignored. The bundled Carbon pack is the only pack — `lucide` was a remote-URL
|
|
7
|
+
* pack and no longer exists. Setting this warns in development. */
|
|
5
8
|
pack?: IconPack;
|
|
6
|
-
/**
|
|
9
|
+
/** @deprecated Ignored — glyphs are inlined in the bundle, so there is nothing to serve from a
|
|
10
|
+
* folder. Apps that vendored `<slug>.svg` files into `public/` to survive offline can delete
|
|
11
|
+
* both the files and this call. Setting it warns in development. */
|
|
7
12
|
base?: string;
|
|
13
|
+
/** Escape hatch for a glyph Pire does not bundle, or to override one. Return the *inner* markup
|
|
14
|
+
* of a 32x32 SVG (`'<path d="…"/>'`), or `undefined` to fall through to the bundled set. The
|
|
15
|
+
* string is injected as-is, so it must be authored markup, never user input. */
|
|
16
|
+
resolve?: (name: string) => string | undefined;
|
|
8
17
|
}
|
|
9
|
-
/**
|
|
18
|
+
/** Optional. The bundled Carbon set needs no configuration — this exists only to register glyphs
|
|
19
|
+
* Pire does not ship, once at startup. */
|
|
10
20
|
export declare function configureIcons(next: IconConfig): void;
|
|
11
21
|
export interface IconProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'children'> {
|
|
12
|
-
/** Canonical (Lucide) slug, e.g. "shopping-cart".
|
|
22
|
+
/** Canonical (Lucide) slug, e.g. "shopping-cart". Translated to the Carbon pack automatically. */
|
|
13
23
|
name: string;
|
|
14
24
|
/** Pixel box. 16 in dense UI, 20 in headers, 24 in tiles. */
|
|
15
25
|
size?: number;
|
|
16
26
|
/** Accessible name. Omit for decorative icons — they are hidden from assistive tech. */
|
|
17
27
|
label?: string;
|
|
28
|
+
/** @deprecated Ignored. See {@link IconConfig.pack}. */
|
|
18
29
|
pack?: IconPack;
|
|
19
30
|
}
|
|
20
|
-
/** Glyph
|
|
21
|
-
*
|
|
31
|
+
/** Glyph rendered as inline SVG filled with `currentColor`, so it inherits text colour everywhere
|
|
32
|
+
* and paints with no network at all — which the previous CDN-backed implementation did not, leaving
|
|
33
|
+
* every icon blank offline in the PWAs that consume this library.
|
|
34
|
+
*
|
|
35
|
+
* An unknown name still renders nothing, so a typo cannot collapse a layout, but it warns in
|
|
36
|
+
* development: the silent blank gap was the failure mode worth killing. */
|
|
22
37
|
export declare function Icon({ name, size, label, pack, style, ...rest }: IconProps): React.JSX.Element;
|
|
@@ -1,23 +1,38 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
/** @deprecated Retained only so existing `pack` values still typecheck. Glyphs are bundled from
|
|
3
|
+
* the Carbon pack; there is no second pack and no remote fetch, so the value is ignored. */
|
|
2
4
|
export type IconPack = 'carbon' | 'lucide';
|
|
3
5
|
export interface IconConfig {
|
|
4
|
-
/**
|
|
6
|
+
/** @deprecated Ignored. The bundled Carbon pack is the only pack — `lucide` was a remote-URL
|
|
7
|
+
* pack and no longer exists. Setting this warns in development. */
|
|
5
8
|
pack?: IconPack;
|
|
6
|
-
/**
|
|
9
|
+
/** @deprecated Ignored — glyphs are inlined in the bundle, so there is nothing to serve from a
|
|
10
|
+
* folder. Apps that vendored `<slug>.svg` files into `public/` to survive offline can delete
|
|
11
|
+
* both the files and this call. Setting it warns in development. */
|
|
7
12
|
base?: string;
|
|
13
|
+
/** Escape hatch for a glyph Pire does not bundle, or to override one. Return the *inner* markup
|
|
14
|
+
* of a 32x32 SVG (`'<path d="…"/>'`), or `undefined` to fall through to the bundled set. The
|
|
15
|
+
* string is injected as-is, so it must be authored markup, never user input. */
|
|
16
|
+
resolve?: (name: string) => string | undefined;
|
|
8
17
|
}
|
|
9
|
-
/**
|
|
18
|
+
/** Optional. The bundled Carbon set needs no configuration — this exists only to register glyphs
|
|
19
|
+
* Pire does not ship, once at startup. */
|
|
10
20
|
export declare function configureIcons(next: IconConfig): void;
|
|
11
21
|
export interface IconProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'children'> {
|
|
12
|
-
/** Canonical (Lucide) slug, e.g. "shopping-cart".
|
|
22
|
+
/** Canonical (Lucide) slug, e.g. "shopping-cart". Translated to the Carbon pack automatically. */
|
|
13
23
|
name: string;
|
|
14
24
|
/** Pixel box. 16 in dense UI, 20 in headers, 24 in tiles. */
|
|
15
25
|
size?: number;
|
|
16
26
|
/** Accessible name. Omit for decorative icons — they are hidden from assistive tech. */
|
|
17
27
|
label?: string;
|
|
28
|
+
/** @deprecated Ignored. See {@link IconConfig.pack}. */
|
|
18
29
|
pack?: IconPack;
|
|
19
30
|
}
|
|
20
|
-
/** Glyph
|
|
21
|
-
*
|
|
31
|
+
/** Glyph rendered as inline SVG filled with `currentColor`, so it inherits text colour everywhere
|
|
32
|
+
* and paints with no network at all — which the previous CDN-backed implementation did not, leaving
|
|
33
|
+
* every icon blank offline in the PWAs that consume this library.
|
|
34
|
+
*
|
|
35
|
+
* An unknown name still renders nothing, so a typo cannot collapse a layout, but it warns in
|
|
36
|
+
* development: the silent blank gap was the failure mode worth killing. */
|
|
22
37
|
export declare function Icon({ name, size, label, pack, style, ...rest }: IconProps): React.JSX.Element;
|
|
23
38
|
//# sourceMappingURL=Icon.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../../src/components/core/Icon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../../src/components/core/Icon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AA2BpC;6FAC6F;AAC7F,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE3C,MAAM,WAAW,UAAU;IACzB;wEACoE;IACpE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;yEAEqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;qFAEiF;IACjF,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAChD;AAID;2CAC2C;AAC3C,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAerD;AAED,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC;IACxF,kGAAkG;IAClG,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED;;;;;4EAK4E;AAC5E,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,IAAS,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,qBAqC/E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const ICON_MARKUP: Record<string, string>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icon-data.generated.d.ts","sourceRoot":"","sources":["../../../src/components/core/icon-data.generated.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAgE9C,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Canonical Pire icon names are Lucide slugs; the shipped IBM Carbon pack is reached through
|
|
2
|
+
* this map, so swapping packs never touches a call site. A new icon name used by a component
|
|
3
|
+
* must be added here — that is the whole registration step.
|
|
4
|
+
*
|
|
5
|
+
* This file is also the single source of truth for *which glyphs get vendored*:
|
|
6
|
+
* `scripts/generate-icon-data.mjs` reads it and inlines the matching SVG from
|
|
7
|
+
* `@carbon/icons` into `icon-data.generated.ts`. The script cannot import TypeScript, so it
|
|
8
|
+
* parses this object textually. **Every entry must stay a literal `'name': 'slug',` pair.**
|
|
9
|
+
* A spread, a computed key or a template literal is invisible to the generator: the glyph
|
|
10
|
+
* never gets vendored and `Icon` warns at runtime instead of rendering. Multiple names may
|
|
11
|
+
* point at one slug (`boxes` and `package` both mean `box`); the generator de-duplicates.
|
|
12
|
+
*/
|
|
13
|
+
export declare const CARBON_MAP: Record<string, string>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Canonical Pire icon names are Lucide slugs; the shipped IBM Carbon pack is reached through
|
|
2
|
+
* this map, so swapping packs never touches a call site. A new icon name used by a component
|
|
3
|
+
* must be added here — that is the whole registration step.
|
|
4
|
+
*
|
|
5
|
+
* This file is also the single source of truth for *which glyphs get vendored*:
|
|
6
|
+
* `scripts/generate-icon-data.mjs` reads it and inlines the matching SVG from
|
|
7
|
+
* `@carbon/icons` into `icon-data.generated.ts`. The script cannot import TypeScript, so it
|
|
8
|
+
* parses this object textually. **Every entry must stay a literal `'name': 'slug',` pair.**
|
|
9
|
+
* A spread, a computed key or a template literal is invisible to the generator: the glyph
|
|
10
|
+
* never gets vendored and `Icon` warns at runtime instead of rendering. Multiple names may
|
|
11
|
+
* point at one slug (`boxes` and `package` both mean `box`); the generator de-duplicates.
|
|
12
|
+
*/
|
|
13
|
+
export declare const CARBON_MAP: Record<string, string>;
|
|
14
|
+
//# sourceMappingURL=icon-map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icon-map.d.ts","sourceRoot":"","sources":["../../../src/components/core/icon-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAiB7C,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
export type SkeletonShape = 'text' | 'block' | 'circle';
|
|
3
|
+
export interface SkeletonProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
4
|
+
/** text — a line of copy; block — a card, chart or image; circle — an avatar. */
|
|
5
|
+
shape?: SkeletonShape;
|
|
6
|
+
/** Overrides the shape's default. A percentage reads better than a pixel count in a
|
|
7
|
+
* fluid layout, and keeps the placeholder honest when the real value is unknown. */
|
|
8
|
+
width?: number | string;
|
|
9
|
+
height?: number | string;
|
|
10
|
+
}
|
|
11
|
+
/** Loading placeholder for content whose shape is known before its value is.
|
|
12
|
+
*
|
|
13
|
+
* Deliberately `aria-hidden`: a screen reader gains nothing from "graphic, graphic, graphic",
|
|
14
|
+
* and announcing placeholders as content is worse than silence. Announce the wait once, on the
|
|
15
|
+
* region that is loading — `aria-busy="true"` on the container, or a live-region message — and
|
|
16
|
+
* let the skeleton be purely visual. Nothing inside is focusable, so keyboard order is
|
|
17
|
+
* unaffected while the data is in flight.
|
|
18
|
+
*
|
|
19
|
+
* The shimmer is suppressed under `prefers-reduced-motion`; the placeholder still reads as one
|
|
20
|
+
* because the shape and the surface contrast carry it, not the animation. */
|
|
21
|
+
export declare function Skeleton({ shape, width, height, className, style, ...rest }: SkeletonProps): React.JSX.Element;
|
|
22
|
+
export interface SkeletonTableColumn {
|
|
23
|
+
align?: 'left' | 'right' | 'center';
|
|
24
|
+
/** Fixed column width. Omit to let the column share the free space, as DataTable does. */
|
|
25
|
+
width?: number | string;
|
|
26
|
+
/** Right-aligns the bar. Mirrors DataTable's column flag so a loading table and a loaded one
|
|
27
|
+
* put their numbers in the same place. */
|
|
28
|
+
numeric?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface SkeletonTableRowProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
31
|
+
/** A column count, or one descriptor per column when alignment or width matters. */
|
|
32
|
+
columns: number | SkeletonTableColumn[];
|
|
33
|
+
/** Must match the DataTable it stands in for, or the rows jump on load. */
|
|
34
|
+
density?: 'condensed' | 'regular' | 'comfortable';
|
|
35
|
+
}
|
|
36
|
+
/** One placeholder row, sized to line up with `DataTable` — same row height per density, same
|
|
37
|
+
* cell padding, same bottom rule. Render a handful inside `.pire-table-wrap` (or above a real
|
|
38
|
+
* table's body) while the first page loads, so the grid does not resize when it arrives.
|
|
39
|
+
*
|
|
40
|
+
* It is not a real `<tr>` and cannot be handed to `DataTable` as a row: DataTable builds its
|
|
41
|
+
* collection from `rows`, and React Aria's table owns everything under it. Use it in place of
|
|
42
|
+
* the table, not inside one. */
|
|
43
|
+
export declare function SkeletonTableRow({ columns, density, className, style, ...rest }: SkeletonTableRowProps): React.JSX.Element;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
export type SkeletonShape = 'text' | 'block' | 'circle';
|
|
3
|
+
export interface SkeletonProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
4
|
+
/** text — a line of copy; block — a card, chart or image; circle — an avatar. */
|
|
5
|
+
shape?: SkeletonShape;
|
|
6
|
+
/** Overrides the shape's default. A percentage reads better than a pixel count in a
|
|
7
|
+
* fluid layout, and keeps the placeholder honest when the real value is unknown. */
|
|
8
|
+
width?: number | string;
|
|
9
|
+
height?: number | string;
|
|
10
|
+
}
|
|
11
|
+
/** Loading placeholder for content whose shape is known before its value is.
|
|
12
|
+
*
|
|
13
|
+
* Deliberately `aria-hidden`: a screen reader gains nothing from "graphic, graphic, graphic",
|
|
14
|
+
* and announcing placeholders as content is worse than silence. Announce the wait once, on the
|
|
15
|
+
* region that is loading — `aria-busy="true"` on the container, or a live-region message — and
|
|
16
|
+
* let the skeleton be purely visual. Nothing inside is focusable, so keyboard order is
|
|
17
|
+
* unaffected while the data is in flight.
|
|
18
|
+
*
|
|
19
|
+
* The shimmer is suppressed under `prefers-reduced-motion`; the placeholder still reads as one
|
|
20
|
+
* because the shape and the surface contrast carry it, not the animation. */
|
|
21
|
+
export declare function Skeleton({ shape, width, height, className, style, ...rest }: SkeletonProps): React.JSX.Element;
|
|
22
|
+
export interface SkeletonTableColumn {
|
|
23
|
+
align?: 'left' | 'right' | 'center';
|
|
24
|
+
/** Fixed column width. Omit to let the column share the free space, as DataTable does. */
|
|
25
|
+
width?: number | string;
|
|
26
|
+
/** Right-aligns the bar. Mirrors DataTable's column flag so a loading table and a loaded one
|
|
27
|
+
* put their numbers in the same place. */
|
|
28
|
+
numeric?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface SkeletonTableRowProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
31
|
+
/** A column count, or one descriptor per column when alignment or width matters. */
|
|
32
|
+
columns: number | SkeletonTableColumn[];
|
|
33
|
+
/** Must match the DataTable it stands in for, or the rows jump on load. */
|
|
34
|
+
density?: 'condensed' | 'regular' | 'comfortable';
|
|
35
|
+
}
|
|
36
|
+
/** One placeholder row, sized to line up with `DataTable` — same row height per density, same
|
|
37
|
+
* cell padding, same bottom rule. Render a handful inside `.pire-table-wrap` (or above a real
|
|
38
|
+
* table's body) while the first page loads, so the grid does not resize when it arrives.
|
|
39
|
+
*
|
|
40
|
+
* It is not a real `<tr>` and cannot be handed to `DataTable` as a row: DataTable builds its
|
|
41
|
+
* collection from `rows`, and React Aria's table owns everything under it. Use it in place of
|
|
42
|
+
* the table, not inside one. */
|
|
43
|
+
export declare function SkeletonTableRow({ columns, density, className, style, ...rest }: SkeletonTableRowProps): React.JSX.Element;
|
|
44
|
+
//# sourceMappingURL=Skeleton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skeleton.d.ts","sourceRoot":"","sources":["../../../src/components/feedback/Skeleton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAGpC,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAExD,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC3F,iFAAiF;IACjF,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB;yFACqF;IACrF,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED;;;;;;;;;8EAS8E;AAC9E,wBAAgB,QAAQ,CAAC,EAAE,KAAc,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,qBAKnG;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpC,0FAA0F;IAC1F,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB;+CAC2C;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IACnG,oFAAoF;IACpF,OAAO,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAAC;IACxC,2EAA2E;IAC3E,OAAO,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC;CACnD;AAOD;;;;;;iCAMiC;AACjC,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,OAAmB,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,qBAAqB,qBAmBlH"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { ComboBoxOption } from './ComboBox.cjs';
|
|
3
|
+
export interface MultiComboBoxProps {
|
|
4
|
+
label?: React.ReactNode;
|
|
5
|
+
/** Selected values, in the order they were picked. */
|
|
6
|
+
value?: string[];
|
|
7
|
+
defaultValue?: string[];
|
|
8
|
+
onChange?: (values: string[]) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Free-text as typed, on every keystroke.
|
|
11
|
+
*
|
|
12
|
+
* Server-side search is only partly supported, exactly as on ComboBox. `options` is passed
|
|
13
|
+
* to React Aria as `defaultItems`, so React Aria applies its own local "contains" filter on
|
|
14
|
+
* top of whatever you supply: any result whose `label` does not literally contain the typed
|
|
15
|
+
* text is hidden client-side, and when the local filter matches nothing the menu closes.
|
|
16
|
+
* Fuzzy, synonym, code-to-description and server-ranked matches are therefore dropped. Use
|
|
17
|
+
* this to observe input (analytics, a debounced prefetch), or for server search only where
|
|
18
|
+
* the returned labels are guaranteed to contain the query as a substring.
|
|
19
|
+
*/
|
|
20
|
+
onInputChange?: (text: string) => void;
|
|
21
|
+
options?: Array<string | ComboBoxOption>;
|
|
22
|
+
placeholder?: string;
|
|
23
|
+
description?: React.ReactNode;
|
|
24
|
+
errorMessage?: React.ReactNode;
|
|
25
|
+
isInvalid?: boolean;
|
|
26
|
+
isDisabled?: boolean;
|
|
27
|
+
isRequired?: boolean;
|
|
28
|
+
isReadOnly?: boolean;
|
|
29
|
+
/** Let Enter commit text that is not in `options` — how product tags get coined. */
|
|
30
|
+
allowsCustomValue?: boolean;
|
|
31
|
+
size?: 'sm' | 'md' | 'lg';
|
|
32
|
+
fullWidth?: boolean;
|
|
33
|
+
name?: string;
|
|
34
|
+
className?: string;
|
|
35
|
+
style?: React.CSSProperties;
|
|
36
|
+
}
|
|
37
|
+
/** Multi-value type-ahead: pick several options, each shown as a removable chip, and — with
|
|
38
|
+
* `allowsCustomValue` — coin new ones by typing. Product tags, cost-centre sets, watchers.
|
|
39
|
+
*
|
|
40
|
+
* A separate component rather than a mode on ComboBox: ComboBox's `value` is a `string | null`
|
|
41
|
+
* and its `onChange` emits one key, while multi-select needs an array on both. Folding the two
|
|
42
|
+
* together would put a discriminated union in front of every existing consumer of
|
|
43
|
+
* `ComboBoxProps` — a breaking change in exchange for a purely additive feature.
|
|
44
|
+
*
|
|
45
|
+
* Three things worth knowing before you use it:
|
|
46
|
+
*
|
|
47
|
+
* - **Free text commits on Enter, never on blur.** React Aria treats the input text as
|
|
48
|
+
* independent of the selection in multi-select mode, so leaving the field discards whatever
|
|
49
|
+
* was typed but not committed. The chips are the only record of what was entered.
|
|
50
|
+
* - **Backspace on an empty input removes the last chip.** The handler runs in the capture
|
|
51
|
+
* phase because React Aria's own key handling sits on the same input and would otherwise act
|
|
52
|
+
* on the same key.
|
|
53
|
+
* - **The chips are plain `Tag`s, not a React Aria TagGroup.** React Aria's ComboBox builds its
|
|
54
|
+
* listbox collection by shallow-rendering its entire subtree, which swallows any collection
|
|
55
|
+
* component nested inside it — a TagGroup there registers its tags as listbox items and then
|
|
56
|
+
* crashes looking for grid state. Each chip's remove button is an ordinary Tab stop instead,
|
|
57
|
+
* and removals are announced through the live region below. */
|
|
58
|
+
export declare function MultiComboBox({ label, value, defaultValue, onChange, onInputChange, options, description, errorMessage, allowsCustomValue, size, fullWidth, className, style, ...rest }: MultiComboBoxProps): React.JSX.Element;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { ComboBoxOption } from './ComboBox.js';
|
|
3
|
+
export interface MultiComboBoxProps {
|
|
4
|
+
label?: React.ReactNode;
|
|
5
|
+
/** Selected values, in the order they were picked. */
|
|
6
|
+
value?: string[];
|
|
7
|
+
defaultValue?: string[];
|
|
8
|
+
onChange?: (values: string[]) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Free-text as typed, on every keystroke.
|
|
11
|
+
*
|
|
12
|
+
* Server-side search is only partly supported, exactly as on ComboBox. `options` is passed
|
|
13
|
+
* to React Aria as `defaultItems`, so React Aria applies its own local "contains" filter on
|
|
14
|
+
* top of whatever you supply: any result whose `label` does not literally contain the typed
|
|
15
|
+
* text is hidden client-side, and when the local filter matches nothing the menu closes.
|
|
16
|
+
* Fuzzy, synonym, code-to-description and server-ranked matches are therefore dropped. Use
|
|
17
|
+
* this to observe input (analytics, a debounced prefetch), or for server search only where
|
|
18
|
+
* the returned labels are guaranteed to contain the query as a substring.
|
|
19
|
+
*/
|
|
20
|
+
onInputChange?: (text: string) => void;
|
|
21
|
+
options?: Array<string | ComboBoxOption>;
|
|
22
|
+
placeholder?: string;
|
|
23
|
+
description?: React.ReactNode;
|
|
24
|
+
errorMessage?: React.ReactNode;
|
|
25
|
+
isInvalid?: boolean;
|
|
26
|
+
isDisabled?: boolean;
|
|
27
|
+
isRequired?: boolean;
|
|
28
|
+
isReadOnly?: boolean;
|
|
29
|
+
/** Let Enter commit text that is not in `options` — how product tags get coined. */
|
|
30
|
+
allowsCustomValue?: boolean;
|
|
31
|
+
size?: 'sm' | 'md' | 'lg';
|
|
32
|
+
fullWidth?: boolean;
|
|
33
|
+
name?: string;
|
|
34
|
+
className?: string;
|
|
35
|
+
style?: React.CSSProperties;
|
|
36
|
+
}
|
|
37
|
+
/** Multi-value type-ahead: pick several options, each shown as a removable chip, and — with
|
|
38
|
+
* `allowsCustomValue` — coin new ones by typing. Product tags, cost-centre sets, watchers.
|
|
39
|
+
*
|
|
40
|
+
* A separate component rather than a mode on ComboBox: ComboBox's `value` is a `string | null`
|
|
41
|
+
* and its `onChange` emits one key, while multi-select needs an array on both. Folding the two
|
|
42
|
+
* together would put a discriminated union in front of every existing consumer of
|
|
43
|
+
* `ComboBoxProps` — a breaking change in exchange for a purely additive feature.
|
|
44
|
+
*
|
|
45
|
+
* Three things worth knowing before you use it:
|
|
46
|
+
*
|
|
47
|
+
* - **Free text commits on Enter, never on blur.** React Aria treats the input text as
|
|
48
|
+
* independent of the selection in multi-select mode, so leaving the field discards whatever
|
|
49
|
+
* was typed but not committed. The chips are the only record of what was entered.
|
|
50
|
+
* - **Backspace on an empty input removes the last chip.** The handler runs in the capture
|
|
51
|
+
* phase because React Aria's own key handling sits on the same input and would otherwise act
|
|
52
|
+
* on the same key.
|
|
53
|
+
* - **The chips are plain `Tag`s, not a React Aria TagGroup.** React Aria's ComboBox builds its
|
|
54
|
+
* listbox collection by shallow-rendering its entire subtree, which swallows any collection
|
|
55
|
+
* component nested inside it — a TagGroup there registers its tags as listbox items and then
|
|
56
|
+
* crashes looking for grid state. Each chip's remove button is an ordinary Tab stop instead,
|
|
57
|
+
* and removals are announced through the live region below. */
|
|
58
|
+
export declare function MultiComboBox({ label, value, defaultValue, onChange, onInputChange, options, description, errorMessage, allowsCustomValue, size, fullWidth, className, style, ...rest }: MultiComboBoxProps): React.JSX.Element;
|
|
59
|
+
//# sourceMappingURL=MultiComboBox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultiComboBox.d.ts","sourceRoot":"","sources":["../../../src/components/forms/MultiComboBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACtC;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAKD;;;;;;;;;;;;;;;;;;;;kEAoBkE;AAClE,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAY,EAC/F,WAAW,EAAE,YAAY,EAAE,iBAAiB,EAAE,IAAW,EACzD,SAAgB,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,kBAAkB,qBAiHlE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface TextAreaProps {
|
|
3
|
+
label?: React.ReactNode;
|
|
4
|
+
value?: string;
|
|
5
|
+
defaultValue?: string;
|
|
6
|
+
/** Receives the raw string value. */
|
|
7
|
+
onChange?: (value: string) => void;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
/** Help text below the field. Replaced by errorMessage when invalid. */
|
|
10
|
+
description?: React.ReactNode;
|
|
11
|
+
errorMessage?: React.ReactNode;
|
|
12
|
+
isInvalid?: boolean;
|
|
13
|
+
isDisabled?: boolean;
|
|
14
|
+
isReadOnly?: boolean;
|
|
15
|
+
isRequired?: boolean;
|
|
16
|
+
size?: 'sm' | 'md' | 'lg';
|
|
17
|
+
/** Visible lines before scrolling. Three is the ERP default: an address or a short note. */
|
|
18
|
+
rows?: number;
|
|
19
|
+
/** Grow with the content instead of scrolling. Off by default — see the component note. */
|
|
20
|
+
autoGrow?: boolean;
|
|
21
|
+
/** Ceiling for `autoGrow`, in lines. Beyond it the field scrolls, so a pasted essay
|
|
22
|
+
* cannot push the form's buttons off screen. */
|
|
23
|
+
maxRows?: number;
|
|
24
|
+
fullWidth?: boolean;
|
|
25
|
+
name?: string;
|
|
26
|
+
autoFocus?: boolean;
|
|
27
|
+
className?: string;
|
|
28
|
+
style?: React.CSSProperties;
|
|
29
|
+
textAreaRef?: React.Ref<HTMLTextAreaElement>;
|
|
30
|
+
}
|
|
31
|
+
/** Multi-line text entry — notes, addresses, rejection reasons. The prop API is Input's, so a
|
|
32
|
+
* field can be swapped between the two without relearning; labels, descriptions and errors are
|
|
33
|
+
* wired up by React Aria, so no manual aria-describedby is ever needed.
|
|
34
|
+
*
|
|
35
|
+
* `autoGrow` is opt-in, not always-on, for two reasons. It costs a synchronous measure-and-write
|
|
36
|
+
* on every keystroke, and in a dense form it makes every field below the one being typed in jump
|
|
37
|
+
* — the wrong trade in a screen the user is tabbing through. Turn it on where the content length
|
|
38
|
+
* is genuinely unknown (a long free-text comment) and leave it off everywhere else. When on, the
|
|
39
|
+
* height is only written when it actually changed, so a keystroke that does not wrap costs no
|
|
40
|
+
* layout; and the resize grip is removed, since a manual height would be overwritten on the next
|
|
41
|
+
* keystroke anyway. */
|
|
42
|
+
export declare function TextArea({ label, description, errorMessage, size, rows, autoGrow, maxRows, fullWidth, className, style, textAreaRef, onChange, ...rest }: TextAreaProps): React.JSX.Element;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface TextAreaProps {
|
|
3
|
+
label?: React.ReactNode;
|
|
4
|
+
value?: string;
|
|
5
|
+
defaultValue?: string;
|
|
6
|
+
/** Receives the raw string value. */
|
|
7
|
+
onChange?: (value: string) => void;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
/** Help text below the field. Replaced by errorMessage when invalid. */
|
|
10
|
+
description?: React.ReactNode;
|
|
11
|
+
errorMessage?: React.ReactNode;
|
|
12
|
+
isInvalid?: boolean;
|
|
13
|
+
isDisabled?: boolean;
|
|
14
|
+
isReadOnly?: boolean;
|
|
15
|
+
isRequired?: boolean;
|
|
16
|
+
size?: 'sm' | 'md' | 'lg';
|
|
17
|
+
/** Visible lines before scrolling. Three is the ERP default: an address or a short note. */
|
|
18
|
+
rows?: number;
|
|
19
|
+
/** Grow with the content instead of scrolling. Off by default — see the component note. */
|
|
20
|
+
autoGrow?: boolean;
|
|
21
|
+
/** Ceiling for `autoGrow`, in lines. Beyond it the field scrolls, so a pasted essay
|
|
22
|
+
* cannot push the form's buttons off screen. */
|
|
23
|
+
maxRows?: number;
|
|
24
|
+
fullWidth?: boolean;
|
|
25
|
+
name?: string;
|
|
26
|
+
autoFocus?: boolean;
|
|
27
|
+
className?: string;
|
|
28
|
+
style?: React.CSSProperties;
|
|
29
|
+
textAreaRef?: React.Ref<HTMLTextAreaElement>;
|
|
30
|
+
}
|
|
31
|
+
/** Multi-line text entry — notes, addresses, rejection reasons. The prop API is Input's, so a
|
|
32
|
+
* field can be swapped between the two without relearning; labels, descriptions and errors are
|
|
33
|
+
* wired up by React Aria, so no manual aria-describedby is ever needed.
|
|
34
|
+
*
|
|
35
|
+
* `autoGrow` is opt-in, not always-on, for two reasons. It costs a synchronous measure-and-write
|
|
36
|
+
* on every keystroke, and in a dense form it makes every field below the one being typed in jump
|
|
37
|
+
* — the wrong trade in a screen the user is tabbing through. Turn it on where the content length
|
|
38
|
+
* is genuinely unknown (a long free-text comment) and leave it off everywhere else. When on, the
|
|
39
|
+
* height is only written when it actually changed, so a keystroke that does not wrap costs no
|
|
40
|
+
* layout; and the resize grip is removed, since a manual height would be overwritten on the next
|
|
41
|
+
* keystroke anyway. */
|
|
42
|
+
export declare function TextArea({ label, description, errorMessage, size, rows, autoGrow, maxRows, fullWidth, className, style, textAreaRef, onChange, ...rest }: TextAreaProps): React.JSX.Element;
|
|
43
|
+
//# sourceMappingURL=TextArea.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextArea.d.ts","sourceRoot":"","sources":["../../../src/components/forms/TextArea.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,4FAA4F;IAC5F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;qDACiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,WAAW,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;CAC9C;AAED;;;;;;;;;;wBAUwB;AACxB,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,IAAW,EAAE,IAAQ,EAAE,QAAQ,EAC1F,OAAO,EAAE,SAAgB,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,qBAsD7F"}
|
|
@@ -8,10 +8,17 @@ export interface ShellBarProps extends Omit<React.HTMLAttributes<HTMLElement>, '
|
|
|
8
8
|
title?: React.ReactNode;
|
|
9
9
|
onMenu?: () => void;
|
|
10
10
|
onSearch?: () => void;
|
|
11
|
+
/** Accessible name for the menu button. Defaults to English, and the bar has no access to the app's
|
|
12
|
+
* catalogue — a Spanish product must pass its own or ship an English screen-reader label. */
|
|
13
|
+
menuLabel?: string;
|
|
14
|
+
/** Accessible name for the search button, for the same reason as {@link ShellBarProps.menuLabel}.
|
|
15
|
+
* Until this existed the only way to localise it was to drop `onSearch` and re-render the icon by
|
|
16
|
+
* hand, which is how a shell ends up with two search icons. */
|
|
17
|
+
searchLabel?: string;
|
|
11
18
|
/** IconButtons with variant="inverse". */
|
|
12
19
|
actions?: React.ReactNode;
|
|
13
20
|
/** Full name — initials render into the avatar. */
|
|
14
21
|
user?: string;
|
|
15
22
|
}
|
|
16
23
|
/** Fixed 48px application chrome. One per page, always the first landmark. */
|
|
17
|
-
export declare function ShellBar({ product, monogram, title, onMenu, onSearch, actions, user, className, ...rest }: ShellBarProps): React.JSX.Element;
|
|
24
|
+
export declare function ShellBar({ product, monogram, title, onMenu, onSearch, menuLabel, searchLabel, actions, user, className, ...rest }: ShellBarProps): React.JSX.Element;
|
|
@@ -8,11 +8,18 @@ export interface ShellBarProps extends Omit<React.HTMLAttributes<HTMLElement>, '
|
|
|
8
8
|
title?: React.ReactNode;
|
|
9
9
|
onMenu?: () => void;
|
|
10
10
|
onSearch?: () => void;
|
|
11
|
+
/** Accessible name for the menu button. Defaults to English, and the bar has no access to the app's
|
|
12
|
+
* catalogue — a Spanish product must pass its own or ship an English screen-reader label. */
|
|
13
|
+
menuLabel?: string;
|
|
14
|
+
/** Accessible name for the search button, for the same reason as {@link ShellBarProps.menuLabel}.
|
|
15
|
+
* Until this existed the only way to localise it was to drop `onSearch` and re-render the icon by
|
|
16
|
+
* hand, which is how a shell ends up with two search icons. */
|
|
17
|
+
searchLabel?: string;
|
|
11
18
|
/** IconButtons with variant="inverse". */
|
|
12
19
|
actions?: React.ReactNode;
|
|
13
20
|
/** Full name — initials render into the avatar. */
|
|
14
21
|
user?: string;
|
|
15
22
|
}
|
|
16
23
|
/** Fixed 48px application chrome. One per page, always the first landmark. */
|
|
17
|
-
export declare function ShellBar({ product, monogram, title, onMenu, onSearch, actions, user, className, ...rest }: ShellBarProps): React.JSX.Element;
|
|
24
|
+
export declare function ShellBar({ product, monogram, title, onMenu, onSearch, menuLabel, searchLabel, actions, user, className, ...rest }: ShellBarProps): React.JSX.Element;
|
|
18
25
|
//# sourceMappingURL=ShellBar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShellBar.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/ShellBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAIpC,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IACrF,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"ShellBar.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/ShellBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAIpC,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IACrF,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB;kGAC8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;oEAEgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,SAA6B,EAClG,WAAsB,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,qBAa3E"}
|