@orianatech/pire 0.3.0 → 0.5.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/NOTICE +19 -0
- 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/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 +22 -0
- package/dist/fonts/LICENSE-jetbrains-mono.txt +93 -0
- package/dist/fonts/LICENSE-public-sans.txt +93 -0
- package/dist/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-latin-500-normal.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-latin-600-normal.woff2 +0 -0
- package/dist/fonts/public-sans-latin-400-normal.woff2 +0 -0
- package/dist/fonts/public-sans-latin-500-normal.woff2 +0 -0
- package/dist/fonts/public-sans-latin-600-normal.woff2 +0 -0
- package/dist/fonts/public-sans-latin-700-normal.woff2 +0 -0
- package/dist/index.cjs +276 -81
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +277 -82
- package/dist/index.js.map +1 -1
- package/dist/tokens/fonts.css +20 -15
- package/package.json +8 -3
package/NOTICE
CHANGED
|
@@ -5,3 +5,22 @@ This product includes software developed at Oriana Tech.
|
|
|
5
5
|
|
|
6
6
|
Licensed under the Apache License, Version 2.0. You may obtain a copy of the
|
|
7
7
|
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
--------------------------------------------------------------------------------
|
|
10
|
+
THIRD-PARTY FONT SOFTWARE
|
|
11
|
+
|
|
12
|
+
This package redistributes the font binaries under dist/fonts/. They are not
|
|
13
|
+
covered by the Apache License above; each is licensed under the SIL Open Font
|
|
14
|
+
License, Version 1.1, whose full text ships alongside them.
|
|
15
|
+
|
|
16
|
+
Public Sans
|
|
17
|
+
Copyright (c) 2015 Impallari Type; Copyright (c) 2019 United States Government
|
|
18
|
+
SIL Open Font License 1.1 - dist/fonts/LICENSE-public-sans.txt
|
|
19
|
+
|
|
20
|
+
JetBrains Mono
|
|
21
|
+
Copyright (c) 2020 JetBrains s.r.o.
|
|
22
|
+
SIL Open Font License 1.1 - dist/fonts/LICENSE-jetbrains-mono.txt
|
|
23
|
+
|
|
24
|
+
Both are redistributed unmodified. They are aliased only at the CSS
|
|
25
|
+
`font-family` level, to "Pire Sans" and "Pire Mono"; the binaries themselves are
|
|
26
|
+
untouched, so the Reserved Font Name clause is not engaged.
|
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"}
|
|
@@ -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"}
|
|
@@ -1,9 +1,24 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/** A second-level destination, nested under a first-level entry.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately has no `icon`: only the first level carries one, so the second level reads as an
|
|
5
|
+
* indented list of labels under a single glyph rather than a wall of decoration. Leaving `icon` off
|
|
6
|
+
* the *type* is what stops that drifting back in one call site at a time. */
|
|
7
|
+
export interface SideNavChildItem {
|
|
8
|
+
id: string;
|
|
9
|
+
label: string;
|
|
10
|
+
count?: number;
|
|
11
|
+
}
|
|
2
12
|
export interface SideNavItem {
|
|
3
13
|
id: string;
|
|
4
14
|
label: string;
|
|
5
15
|
icon?: string;
|
|
6
16
|
count?: number;
|
|
17
|
+
/** Second-level destinations. Supplying this turns the entry into a collapsible group: it stops
|
|
18
|
+
* being a destination itself (pressing it expands, never navigates) and `id` becomes the
|
|
19
|
+
* expansion key used by `expandedIds` / `defaultExpandedIds`, not something `onChange` can ever
|
|
20
|
+
* emit. Omit it and the entry behaves exactly as it always has. */
|
|
21
|
+
items?: SideNavChildItem[];
|
|
7
22
|
}
|
|
8
23
|
export interface SideNavGroup {
|
|
9
24
|
label?: string;
|
|
@@ -13,10 +28,47 @@ export interface SideNavProps extends Omit<React.HTMLAttributes<HTMLElement>, 'o
|
|
|
13
28
|
/** Spaces-and-pages hierarchy: one group per space. */
|
|
14
29
|
groups: SideNavGroup[];
|
|
15
30
|
value?: string;
|
|
16
|
-
/** Fires with the selected item id — not a DOM change event.
|
|
31
|
+
/** Fires with the selected item id — not a DOM change event. Only ever a destination id: a
|
|
32
|
+
* first-level entry that owns `items` is a disclosure, and toggling it does not fire this. */
|
|
17
33
|
onChange?: (id: string) => void;
|
|
18
|
-
/**
|
|
34
|
+
/** Expanded first-level entry ids — the controlled half of the pair. Pass it and you own expansion
|
|
35
|
+
* outright, including expanding the group that holds `value`. */
|
|
36
|
+
expandedIds?: string[];
|
|
37
|
+
/** Initial expanded ids for the uncontrolled case. Omit it and the group holding `value` opens
|
|
38
|
+
* itself; supply it and it is taken literally, so `value`'s group can start closed if that is
|
|
39
|
+
* genuinely what you want. */
|
|
40
|
+
defaultExpandedIds?: string[];
|
|
41
|
+
/** Fires with every expanded id after a toggle, controlled or not. */
|
|
42
|
+
onExpandedChange?: (ids: string[]) => void;
|
|
43
|
+
/** 48px icon rail. Labels move into tooltips, and second-level items are not rendered at all —
|
|
44
|
+
* see the note on {@link SideNav}. */
|
|
19
45
|
collapsed?: boolean;
|
|
20
46
|
footer?: React.ReactNode;
|
|
21
47
|
}
|
|
22
|
-
|
|
48
|
+
/** Primary navigation. A first-level entry is either a destination (icon + label, selectable) or a
|
|
49
|
+
* collapsible group (icon + label + chevron) when it carries `items` — the two coexist in one list,
|
|
50
|
+
* which is how a 35-destination ERP menu fits without showing all 35 at once.
|
|
51
|
+
*
|
|
52
|
+
* Both levels are plain `Button`s and the disclosure is React Aria's `Disclosure` /
|
|
53
|
+
* `DisclosureGroup`, so `aria-expanded`, `aria-controls`, the panel's `role="group"` and
|
|
54
|
+
* `aria-labelledby`, and Enter/Space on the trigger all come from React Aria rather than from
|
|
55
|
+
* hand-rolled ARIA here.
|
|
56
|
+
*
|
|
57
|
+
* Three things worth knowing before you use it:
|
|
58
|
+
*
|
|
59
|
+
* - **The panel is always in the DOM.** React Aria hides a collapsed panel with
|
|
60
|
+
* `hidden="until-found"`, applied imperatively in a layout effect, so find-in-page can reveal it.
|
|
61
|
+
* A test asserting a collapsed child is *absent* will fail; assert `aria-expanded` on the trigger,
|
|
62
|
+
* or visibility, instead. The corollary in CSS: any `display` we set on the panel would beat the
|
|
63
|
+
* UA's `[hidden] { display: none }`, leaving collapsed children focusable under
|
|
64
|
+
* `aria-hidden="true"`. `.pire-sidenav-subnav[hidden]` in `components.css` is that guard.
|
|
65
|
+
* - **`collapsed` and expansion are different axes, and the rail wins.** With `collapsed` set there
|
|
66
|
+
* are no labels, and a second level is nothing *but* labels, so children are not rendered in the
|
|
67
|
+
* rail. A group's row becomes an ordinary icon button that records the expansion (so the group is
|
|
68
|
+
* already open when the rail expands) and lights up while it holds `value`, which is the one thing
|
|
69
|
+
* a rail must still communicate. It follows that a nav with collapsible groups needs a way back
|
|
70
|
+
* out of the rail — `ShellBar`'s `onMenu` — or 25 of those 35 destinations are unreachable, for
|
|
71
|
+
* everyone, exactly as the labels already are.
|
|
72
|
+
* - **Several groups can be open at once**, and there is no accordion mode. Closing the group you
|
|
73
|
+
* are in to open another is the wrong trade in a nav whose whole job is showing where you are. */
|
|
74
|
+
export declare function SideNav({ groups, value, onChange, expandedIds, defaultExpandedIds, onExpandedChange, collapsed, footer, className, ...rest }: SideNavProps): React.JSX.Element;
|
|
@@ -1,9 +1,24 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/** A second-level destination, nested under a first-level entry.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately has no `icon`: only the first level carries one, so the second level reads as an
|
|
5
|
+
* indented list of labels under a single glyph rather than a wall of decoration. Leaving `icon` off
|
|
6
|
+
* the *type* is what stops that drifting back in one call site at a time. */
|
|
7
|
+
export interface SideNavChildItem {
|
|
8
|
+
id: string;
|
|
9
|
+
label: string;
|
|
10
|
+
count?: number;
|
|
11
|
+
}
|
|
2
12
|
export interface SideNavItem {
|
|
3
13
|
id: string;
|
|
4
14
|
label: string;
|
|
5
15
|
icon?: string;
|
|
6
16
|
count?: number;
|
|
17
|
+
/** Second-level destinations. Supplying this turns the entry into a collapsible group: it stops
|
|
18
|
+
* being a destination itself (pressing it expands, never navigates) and `id` becomes the
|
|
19
|
+
* expansion key used by `expandedIds` / `defaultExpandedIds`, not something `onChange` can ever
|
|
20
|
+
* emit. Omit it and the entry behaves exactly as it always has. */
|
|
21
|
+
items?: SideNavChildItem[];
|
|
7
22
|
}
|
|
8
23
|
export interface SideNavGroup {
|
|
9
24
|
label?: string;
|
|
@@ -13,11 +28,48 @@ export interface SideNavProps extends Omit<React.HTMLAttributes<HTMLElement>, 'o
|
|
|
13
28
|
/** Spaces-and-pages hierarchy: one group per space. */
|
|
14
29
|
groups: SideNavGroup[];
|
|
15
30
|
value?: string;
|
|
16
|
-
/** Fires with the selected item id — not a DOM change event.
|
|
31
|
+
/** Fires with the selected item id — not a DOM change event. Only ever a destination id: a
|
|
32
|
+
* first-level entry that owns `items` is a disclosure, and toggling it does not fire this. */
|
|
17
33
|
onChange?: (id: string) => void;
|
|
18
|
-
/**
|
|
34
|
+
/** Expanded first-level entry ids — the controlled half of the pair. Pass it and you own expansion
|
|
35
|
+
* outright, including expanding the group that holds `value`. */
|
|
36
|
+
expandedIds?: string[];
|
|
37
|
+
/** Initial expanded ids for the uncontrolled case. Omit it and the group holding `value` opens
|
|
38
|
+
* itself; supply it and it is taken literally, so `value`'s group can start closed if that is
|
|
39
|
+
* genuinely what you want. */
|
|
40
|
+
defaultExpandedIds?: string[];
|
|
41
|
+
/** Fires with every expanded id after a toggle, controlled or not. */
|
|
42
|
+
onExpandedChange?: (ids: string[]) => void;
|
|
43
|
+
/** 48px icon rail. Labels move into tooltips, and second-level items are not rendered at all —
|
|
44
|
+
* see the note on {@link SideNav}. */
|
|
19
45
|
collapsed?: boolean;
|
|
20
46
|
footer?: React.ReactNode;
|
|
21
47
|
}
|
|
22
|
-
|
|
48
|
+
/** Primary navigation. A first-level entry is either a destination (icon + label, selectable) or a
|
|
49
|
+
* collapsible group (icon + label + chevron) when it carries `items` — the two coexist in one list,
|
|
50
|
+
* which is how a 35-destination ERP menu fits without showing all 35 at once.
|
|
51
|
+
*
|
|
52
|
+
* Both levels are plain `Button`s and the disclosure is React Aria's `Disclosure` /
|
|
53
|
+
* `DisclosureGroup`, so `aria-expanded`, `aria-controls`, the panel's `role="group"` and
|
|
54
|
+
* `aria-labelledby`, and Enter/Space on the trigger all come from React Aria rather than from
|
|
55
|
+
* hand-rolled ARIA here.
|
|
56
|
+
*
|
|
57
|
+
* Three things worth knowing before you use it:
|
|
58
|
+
*
|
|
59
|
+
* - **The panel is always in the DOM.** React Aria hides a collapsed panel with
|
|
60
|
+
* `hidden="until-found"`, applied imperatively in a layout effect, so find-in-page can reveal it.
|
|
61
|
+
* A test asserting a collapsed child is *absent* will fail; assert `aria-expanded` on the trigger,
|
|
62
|
+
* or visibility, instead. The corollary in CSS: any `display` we set on the panel would beat the
|
|
63
|
+
* UA's `[hidden] { display: none }`, leaving collapsed children focusable under
|
|
64
|
+
* `aria-hidden="true"`. `.pire-sidenav-subnav[hidden]` in `components.css` is that guard.
|
|
65
|
+
* - **`collapsed` and expansion are different axes, and the rail wins.** With `collapsed` set there
|
|
66
|
+
* are no labels, and a second level is nothing *but* labels, so children are not rendered in the
|
|
67
|
+
* rail. A group's row becomes an ordinary icon button that records the expansion (so the group is
|
|
68
|
+
* already open when the rail expands) and lights up while it holds `value`, which is the one thing
|
|
69
|
+
* a rail must still communicate. It follows that a nav with collapsible groups needs a way back
|
|
70
|
+
* out of the rail — `ShellBar`'s `onMenu` — or 25 of those 35 destinations are unreachable, for
|
|
71
|
+
* everyone, exactly as the labels already are.
|
|
72
|
+
* - **Several groups can be open at once**, and there is no accordion mode. Closing the group you
|
|
73
|
+
* are in to open another is the wrong trade in a nav whose whole job is showing where you are. */
|
|
74
|
+
export declare function SideNav({ groups, value, onChange, expandedIds, defaultExpandedIds, onExpandedChange, collapsed, footer, className, ...rest }: SideNavProps): React.JSX.Element;
|
|
23
75
|
//# sourceMappingURL=SideNav.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SideNav.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/SideNav.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,
|
|
1
|
+
{"version":3,"file":"SideNav.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/SideNav.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B;;;;8EAI8E;AAC9E,MAAM,WAAW,gBAAgB;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AAE/E,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;wEAGoE;IACpE,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAAG,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,EAAE,CAAA;CAAE;AAEtE,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC;IACvF,uDAAuD;IACvD,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;mGAC+F;IAC/F,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC;sEACkE;IAClE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;mCAE+B;IAC/B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC3C;2CACuC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC1B;AAaD;;;;;;;;;;;;;;;;;;;;;;;;;qGAyBqG;AACrG,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAClG,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,YAAY,qBA+GtD"}
|
package/dist/components.css
CHANGED
|
@@ -188,6 +188,28 @@
|
|
|
188
188
|
.pire-sidenav-item[data-hovered]{background:var(--surface-hover)}
|
|
189
189
|
.pire-sidenav-item[data-selected="true"]{background:var(--surface-selected);border-left-color:var(--accent-bg);color:var(--accent-subtle-fg);font:var(--type-body-strong)}
|
|
190
190
|
.pire-sidenav-count{margin-left:auto;font:var(--type-code);color:var(--text-tertiary)}
|
|
191
|
+
/* Second level. `-tree` is React Aria's DisclosureGroup, `-section` one Disclosure; both exist only
|
|
192
|
+
to keep the rows in a column, since the wrappers are divs the component cannot avoid. */
|
|
193
|
+
.pire-sidenav-tree,.pire-sidenav-section{display:flex;flex-direction:column}
|
|
194
|
+
/* The trailing chevron. Its own auto margin pushes it to the edge on a group row with no count; when
|
|
195
|
+
there is a count, the count's auto margin has already claimed the free space and a second auto here
|
|
196
|
+
would split it and leave the count floating mid-row — hence the reset. */
|
|
197
|
+
.pire-sidenav-chevron{margin-left:auto;color:var(--text-tertiary);transition:transform var(--dur-fast) var(--ease-standard)}
|
|
198
|
+
.pire-sidenav-count + .pire-sidenav-chevron{margin-left:0}
|
|
199
|
+
.pire-sidenav-section:not([data-expanded]) .pire-sidenav-chevron{transform:rotate(-90deg)}
|
|
200
|
+
/* Marks a group row whose child is the current destination: the accent tick and label weight of a
|
|
201
|
+
selection without its fill, so the trail to `aria-current` reads at a glance and still loses to it.
|
|
202
|
+
Also the only cue left in the icon rail, where the children are not rendered. */
|
|
203
|
+
.pire-sidenav-item[data-active-child="true"]{border-left-color:var(--accent-bg);color:var(--accent-subtle-fg);font:var(--type-body-strong)}
|
|
204
|
+
/* React Aria animates the panel through --disclosure-panel-height, and applies `hidden` only once the
|
|
205
|
+
animation settles. The `display` above therefore has to be undone for the collapsed state: it beats
|
|
206
|
+
the UA's `[hidden]{display:none}`, and a visible-to-the-layout panel under `aria-hidden="true"`
|
|
207
|
+
leaves every child in the tab order — an aria-hidden-focus defect, not just a cosmetic one. */
|
|
208
|
+
.pire-sidenav-subnav{display:flex;flex-direction:column;overflow:hidden;height:var(--disclosure-panel-height,auto);transition:height var(--dur-fast) var(--ease-standard)}
|
|
209
|
+
.pire-sidenav-subnav[hidden]{display:none}
|
|
210
|
+
/* Indented to the parent's *label*, not its icon: page padding + the 16px glyph box + the row gap.
|
|
211
|
+
Condensed height because a two-level menu is 35 rows, not 10. */
|
|
212
|
+
.pire-sidenav-subitem{height:var(--row-h-condensed);padding-left:calc(var(--sp-4) + var(--sp-4) + var(--sp-3))}
|
|
191
213
|
.pire-sidenav-footer{margin-top:auto;padding:var(--sp-3) var(--sp-4);border-top:1px solid var(--border-subtle)}
|
|
192
214
|
|
|
193
215
|
/* ---- Feedback -------------------------------------------------------- */
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono) JetBrainsMono-Italic[wght].ttf: Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
|
5
|
+
http://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|