@rblabs-dev/axiom 1.2.1 → 1.2.2
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 +33 -13
- package/cli/build-brand-assets.mjs +12 -18
- package/cli/project.mjs +6 -0
- package/cli/verify-production-assets.mjs +71 -6
- package/fesm2022/rblabs-dev-axiom.mjs +1 -1
- package/fesm2022/rblabs-dev-axiom.mjs.map +1 -1
- package/fonts/LICENSE +93 -0
- package/fonts/inter-latin-ext-wght-normal.woff2 +0 -0
- package/fonts/inter-latin-wght-normal.woff2 +0 -0
- package/package.json +2 -2
- package/styles/_fonts.scss +7 -7
- package/styles/_index.scss +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,8 @@ This README covers installing the package and wiring it into an app.
|
|
|
23
23
|
npm install @rblabs-dev/axiom @angular/material@<major> @angular/cdk@<major>
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Inter Variable
|
|
26
|
+
Inter Variable ships in the package's `fonts/` folder, and the app serves it (step 3). Nothing loads
|
|
27
|
+
from a CDN.
|
|
27
28
|
|
|
28
29
|
## Set up an app
|
|
29
30
|
|
|
@@ -54,7 +55,25 @@ Run these steps from the folder that holds the app's `angular.json`.
|
|
|
54
55
|
`NOTICE.txt`. `angular.json` must serve `public/` (`{ "glob": "**/*", "input": "public" }`, the
|
|
55
56
|
Angular CLI default); no other asset entry is needed.
|
|
56
57
|
|
|
57
|
-
3. **
|
|
58
|
+
3. **Inter.** Serve the package's Inter files at `/fonts/` with this entry in the build `assets` of
|
|
59
|
+
`angular.json`:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{ "glob": "*.woff2", "input": "node_modules/@rblabs-dev/axiom/fonts", "output": "fonts" }
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Then preload the Latin file in the `<head>` of `src/index.html`:
|
|
66
|
+
|
|
67
|
+
```html
|
|
68
|
+
<link rel="preload" href="/fonts/inter-latin-wght-normal.woff2" as="font" type="font/woff2" crossorigin />
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The kit declares Inter with `font-display: optional`, so a first visit gets Inter only if the
|
|
72
|
+
file arrives within about 100 ms of the first render; the preload starts it with the HTML instead
|
|
73
|
+
of after the global stylesheet. Keep `crossorigin`: without it the browser does not reuse the
|
|
74
|
+
preloaded file. `axiom verify-production-assets` fails the build when either step is missing.
|
|
75
|
+
|
|
76
|
+
4. **Global styles.** Call the entry mixin once, at the top of `src/styles.scss`, with the subset's
|
|
58
77
|
file name (later runs of `build:icon-font` update it):
|
|
59
78
|
|
|
60
79
|
```scss
|
|
@@ -67,7 +86,7 @@ Run these steps from the folder that holds the app's `angular.json`.
|
|
|
67
86
|
`$scope: '.rb-scope'` applies the kit only inside that class, for an app that still has global
|
|
68
87
|
styles of its own. The module also forwards `rb.below()`, `rb.above()` and `$breakpoints`.
|
|
69
88
|
|
|
70
|
-
|
|
89
|
+
5. **Providers.** In `app.config.ts`:
|
|
71
90
|
|
|
72
91
|
```ts
|
|
73
92
|
import { provideRbDesignSystem } from '@rblabs-dev/axiom';
|
|
@@ -81,7 +100,7 @@ Run these steps from the folder that holds the app's `angular.json`.
|
|
|
81
100
|
`<mat-icon>` font. `provideRbDesignSystem({ forcedTheme: 'dark' })` keeps an app dark-only
|
|
82
101
|
while it migrates, and `legacyStorageKeys` moves a theme choice stored under an older key.
|
|
83
102
|
|
|
84
|
-
|
|
103
|
+
6. **Showcase route.** Route `/design-system` to the showcase, lazily, so it stays out of the
|
|
85
104
|
initial bundle:
|
|
86
105
|
|
|
87
106
|
```ts
|
|
@@ -93,7 +112,7 @@ Run these steps from the folder that holds the app's `angular.json`.
|
|
|
93
112
|
}
|
|
94
113
|
```
|
|
95
114
|
|
|
96
|
-
|
|
115
|
+
7. **Favicon and document head.** Write the app's favicon from the brand template, then reference
|
|
97
116
|
it in `index.html` with the theme colors:
|
|
98
117
|
|
|
99
118
|
```bash
|
|
@@ -106,7 +125,7 @@ Run these steps from the folder that holds the app's `angular.json`.
|
|
|
106
125
|
<meta name="theme-color" content="#08111d" media="(prefers-color-scheme: dark)" />
|
|
107
126
|
```
|
|
108
127
|
|
|
109
|
-
|
|
128
|
+
8. **Build.** `npm run build` builds the app and runs `axiom verify-production-assets`.
|
|
110
129
|
|
|
111
130
|
Then use the components and kit classes in templates:
|
|
112
131
|
|
|
@@ -130,6 +149,7 @@ each pull request needs.
|
|
|
130
149
|
| `@rblabs-dev/axiom/showcase` | `DesignSystemShowcaseComponent`, the `/design-system` page |
|
|
131
150
|
| `@use '@rblabs-dev/axiom'` (SCSS) | `rb.design-system()`, `rb.below()`, `rb.above()`, `$breakpoints` and `$version`; emits no CSS until the mixin is called |
|
|
132
151
|
| `axiom` (command) | The four commands below |
|
|
152
|
+
| `fonts/` | Inter Variable (Latin and Latin Extended WOFF2) and its license, served by the app at `/fonts/` |
|
|
133
153
|
| `brand/`, `material-symbols-icons.txt` | Brand templates and the kit's icon inventory, read by the commands |
|
|
134
154
|
|
|
135
155
|
## The `axiom` command
|
|
@@ -137,12 +157,12 @@ each pull request needs.
|
|
|
137
157
|
Each command reads the app's source root, `public/` folder and build output from `angular.json`.
|
|
138
158
|
With several applications in one workspace, pass `--project <name>`. `npx axiom help` lists them.
|
|
139
159
|
|
|
140
|
-
| Command | What it does
|
|
141
|
-
| --------------------------------------------------------- |
|
|
142
|
-
| `axiom build-icon-font [--output <dir>]` | Downloads the Material Symbols subset for the kit's and the app's icons, replaces the previous one in `public/fonts/` and updates its name in `src/**/*.scss`
|
|
143
|
-
| `axiom build-brand-assets --app <name> [--out-dir <dir>]` | Writes `public/favicon.svg`. With `--og-image <out.svg> --description <text> --domain <host>`, also writes the social preview SVG
|
|
144
|
-
| `axiom verify-production-assets [--scan <dir>]...` | After a production build, fails on Google Fonts references, a missing favicon or icon font, or an icon used in `src/` that no inventory lists
|
|
145
|
-
| `axiom check-style-literals` | Fails on hex, `rgb()` or `hsl()` color literals in `src/**/*.scss` that `style-literals.allowlist.json` does not list
|
|
160
|
+
| Command | What it does |
|
|
161
|
+
| --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
162
|
+
| `axiom build-icon-font [--output <dir>]` | Downloads the Material Symbols subset for the kit's and the app's icons, replaces the previous one in `public/fonts/` and updates its name in `src/**/*.scss` |
|
|
163
|
+
| `axiom build-brand-assets --app <name> [--out-dir <dir>]` | Writes `public/favicon.svg`. With `--og-image <out.svg> --description <text> --domain <host>`, also writes the social preview SVG |
|
|
164
|
+
| `axiom verify-production-assets [--scan <dir>]...` | After a production build, fails on Google Fonts references, a missing favicon, Inter preload or font file, a missing icon font, or an icon used in `src/` that no inventory lists |
|
|
165
|
+
| `axiom check-style-literals` | Fails on hex, `rgb()` or `hsl()` color literals in `src/**/*.scss` that `style-literals.allowlist.json` does not list |
|
|
146
166
|
|
|
147
167
|
## Versions
|
|
148
168
|
|
|
@@ -153,4 +173,4 @@ showcase and `RB_DESIGN_SYSTEM_VERSION` report. Release notes are on the
|
|
|
153
173
|
## License
|
|
154
174
|
|
|
155
175
|
MIT. The icon font that `axiom build-icon-font` downloads is Material Symbols (Apache License 2.0),
|
|
156
|
-
and Inter Variable is licensed under the SIL Open Font License 1.1.
|
|
176
|
+
and Inter Variable, in `fonts/`, is licensed under the SIL Open Font License 1.1 (`fonts/LICENSE`).
|
|
@@ -8,19 +8,23 @@
|
|
|
8
8
|
//
|
|
9
9
|
// ... --og-image <out.svg> --description "<at most 60 characters>" --domain <host>
|
|
10
10
|
// also writes the filled social preview template to <out.svg>, for export to the app's
|
|
11
|
-
// public/og-image.png (1200x630). The SVG loads Inter from
|
|
12
|
-
// machine that generated it.
|
|
11
|
+
// public/og-image.png (1200x630). The SVG loads Inter from this package's fonts/ folder, so
|
|
12
|
+
// export it on the machine that generated it.
|
|
13
13
|
//
|
|
14
14
|
// The output is per-app and lives in the app; commit its public/favicon.svg and og-image.png.
|
|
15
15
|
|
|
16
16
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
17
|
-
import { createRequire } from 'node:module';
|
|
18
17
|
import path from 'node:path';
|
|
19
18
|
import { pathToFileURL } from 'node:url';
|
|
20
19
|
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
import {
|
|
21
|
+
brandDir,
|
|
22
|
+
fontsDir,
|
|
23
|
+
interFontFiles,
|
|
24
|
+
parseOptions,
|
|
25
|
+
relativeToCwd,
|
|
26
|
+
resolveProject,
|
|
27
|
+
} from './project.mjs';
|
|
24
28
|
|
|
25
29
|
// Section 12.3. Badge colors exist only in favicons; they are not UI tokens.
|
|
26
30
|
export const RB_APPS = {
|
|
@@ -55,15 +59,6 @@ function readTemplate(name) {
|
|
|
55
59
|
return readFileSync(path.join(brandDir, name), 'utf8');
|
|
56
60
|
}
|
|
57
61
|
|
|
58
|
-
// The variable Inter file the og-image template embeds, from this package's dependency.
|
|
59
|
-
function interFontPath() {
|
|
60
|
-
try {
|
|
61
|
-
return require.resolve('@fontsource-variable/inter/files/inter-latin-wght-normal.woff2');
|
|
62
|
-
} catch {
|
|
63
|
-
throw new Error('Cannot find @fontsource-variable/inter; run npm install first.');
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
62
|
export function run(argv) {
|
|
68
63
|
const options = parseOptions(argv);
|
|
69
64
|
const app = RB_APPS[options.app];
|
|
@@ -77,7 +72,6 @@ export function run(argv) {
|
|
|
77
72
|
? path.resolve(options['out-dir'])
|
|
78
73
|
: resolveProject(options.project).publicDir;
|
|
79
74
|
if (!existsSync(outDir)) throw new Error(`${relativeToCwd(outDir)} does not exist.`);
|
|
80
|
-
let interFont;
|
|
81
75
|
if (options['og-image']) {
|
|
82
76
|
if (!description || !domain) {
|
|
83
77
|
throw new Error('--og-image needs --description and --domain.');
|
|
@@ -87,7 +81,6 @@ export function run(argv) {
|
|
|
87
81
|
`--description has ${description.length} characters; the limit is ${maxDescriptionLength}.`,
|
|
88
82
|
);
|
|
89
83
|
}
|
|
90
|
-
interFont = interFontPath();
|
|
91
84
|
}
|
|
92
85
|
|
|
93
86
|
const faviconPath = path.join(outDir, 'favicon.svg');
|
|
@@ -108,7 +101,8 @@ export function run(argv) {
|
|
|
108
101
|
appName: app.name,
|
|
109
102
|
description,
|
|
110
103
|
domain,
|
|
111
|
-
|
|
104
|
+
// The Latin file covers the template's text.
|
|
105
|
+
interFontUrl: pathToFileURL(path.join(fontsDir, interFontFiles[0])).href,
|
|
112
106
|
}),
|
|
113
107
|
);
|
|
114
108
|
console.log(`Wrote ${relativeToCwd(ogPath)}; export it to public/og-image.png at 1200x630.`);
|
package/cli/project.mjs
CHANGED
|
@@ -11,6 +11,12 @@ import { fileURLToPath } from 'node:url';
|
|
|
11
11
|
export const kitDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
12
12
|
export const kitInventoryPath = path.join(kitDir, 'material-symbols-icons.txt');
|
|
13
13
|
export const brandDir = path.join(kitDir, 'brand');
|
|
14
|
+
// The Inter Variable files the kit's @font-face rules load from /fonts/<name> (section 6.1).
|
|
15
|
+
export const fontsDir = path.join(kitDir, 'fonts');
|
|
16
|
+
export const interFontFiles = [
|
|
17
|
+
'inter-latin-wght-normal.woff2',
|
|
18
|
+
'inter-latin-ext-wght-normal.woff2',
|
|
19
|
+
];
|
|
14
20
|
|
|
15
21
|
// Parses `--name value` pairs. Options listed in `repeatable` collect every value in an array.
|
|
16
22
|
export function parseOptions(argv, { repeatable = [] } = {}) {
|
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
//
|
|
8
8
|
// - the built index.html references Google Fonts;
|
|
9
9
|
// - the favicon is missing or not referenced;
|
|
10
|
+
// - the built index.html does not preload /fonts/inter-latin-wght-normal.woff2 (as="font",
|
|
11
|
+
// type="font/woff2", crossorigin), the build output does not hold the kit's Inter files at
|
|
12
|
+
// /fonts/ unchanged, or the built stylesheet does not load Inter from there (section 6.1);
|
|
10
13
|
// - the app's public/fonts/ does not hold exactly one Material Symbols subset, the built
|
|
11
14
|
// stylesheet does not reference it, its name's content hash does not match its bytes, or it
|
|
12
15
|
// exceeds 16 KB;
|
|
@@ -22,7 +25,20 @@ import { createHash } from 'node:crypto';
|
|
|
22
25
|
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
23
26
|
import path from 'node:path';
|
|
24
27
|
|
|
25
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
fontsDir,
|
|
30
|
+
interFontFiles,
|
|
31
|
+
parseOptions,
|
|
32
|
+
readIconInventories,
|
|
33
|
+
relativeToCwd,
|
|
34
|
+
resolveProject,
|
|
35
|
+
} from './project.mjs';
|
|
36
|
+
|
|
37
|
+
const interPreloadUrl = `/fonts/${interFontFiles[0]}`;
|
|
38
|
+
const interPreloadTag = `<link rel="preload" href="${interPreloadUrl}" as="font" type="font/woff2" crossorigin />`;
|
|
39
|
+
|
|
40
|
+
const linkTagPattern = /<link\b[^>]*>/giu;
|
|
41
|
+
const attributePattern = /([^\s=/>]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+)))?/gu;
|
|
26
42
|
|
|
27
43
|
const fontPattern = /^material-symbols-outlined-.+\.woff2$/u;
|
|
28
44
|
const hashedFontPattern = /\.([0-9a-f]{8})\.woff2$/u;
|
|
@@ -51,6 +67,33 @@ function listFiles(directory, predicate) {
|
|
|
51
67
|
return files;
|
|
52
68
|
}
|
|
53
69
|
|
|
70
|
+
// The attributes of every <link> in an HTML document outside comments, as name → value maps
|
|
71
|
+
// (lowercase names; an attribute without a value maps to '').
|
|
72
|
+
export function linkTags(html) {
|
|
73
|
+
const markup = html.replace(/<!--[\s\S]*?-->/gu, '');
|
|
74
|
+
return [...markup.matchAll(linkTagPattern)].map(([tag]) => {
|
|
75
|
+
const attributes = new Map();
|
|
76
|
+
for (const match of tag.slice('<link'.length).matchAll(attributePattern)) {
|
|
77
|
+
attributes.set(match[1].toLowerCase(), match[2] ?? match[3] ?? match[4] ?? '');
|
|
78
|
+
}
|
|
79
|
+
return attributes;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Whether an HTML document preloads the Latin Inter file so that the kit's @font-face rule reuses
|
|
84
|
+
// the request: same URL, as="font", type="font/woff2" and an anonymous CORS request, which is how
|
|
85
|
+
// browsers fetch fonts.
|
|
86
|
+
export function preloadsInter(html) {
|
|
87
|
+
return linkTags(html).some(
|
|
88
|
+
(link) =>
|
|
89
|
+
link.get('rel')?.toLowerCase().split(/\s+/u).includes('preload') &&
|
|
90
|
+
link.get('href') === interPreloadUrl &&
|
|
91
|
+
link.get('as')?.toLowerCase() === 'font' &&
|
|
92
|
+
link.get('type')?.toLowerCase() === 'font/woff2' &&
|
|
93
|
+
['', 'anonymous'].includes(link.get('crossorigin')?.toLowerCase()),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
54
97
|
// Icon names used by one template or component source.
|
|
55
98
|
export function iconNamesInSource(source) {
|
|
56
99
|
const names = new Set();
|
|
@@ -97,6 +140,24 @@ export function run(argv) {
|
|
|
97
140
|
if (!existsSync(path.join(browserDir, 'favicon.svg')))
|
|
98
141
|
fail(`Missing favicon asset in ${relativeToCwd(browserDir)}.`);
|
|
99
142
|
|
|
143
|
+
if (!preloadsInter(indexHtml)) {
|
|
144
|
+
fail(
|
|
145
|
+
`Production index does not preload Inter. Add to the app's index.html: ${interPreloadTag}`,
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
for (const name of interFontFiles) {
|
|
149
|
+
const interPath = path.join(browserDir, 'fonts', name);
|
|
150
|
+
if (!existsSync(interPath)) {
|
|
151
|
+
fail(
|
|
152
|
+
`Missing ${relativeToCwd(interPath)}. Copy the kit's Inter files with this angular.json ` +
|
|
153
|
+
'assets entry: { "glob": "*.woff2", "input": "node_modules/@rblabs-dev/axiom/fonts", "output": "fonts" }',
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
if (!readFileSync(interPath).equals(readFileSync(path.join(fontsDir, name)))) {
|
|
157
|
+
fail(`${relativeToCwd(interPath)} differs from the kit's copy; serve the package's file.`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
100
161
|
const publicFontsDir = path.join(project.publicDir, 'fonts');
|
|
101
162
|
if (!existsSync(publicFontsDir))
|
|
102
163
|
fail(`Missing ${relativeToCwd(publicFontsDir)}; run axiom build-icon-font.`);
|
|
@@ -124,10 +185,14 @@ export function run(argv) {
|
|
|
124
185
|
|
|
125
186
|
const stylesheets = readdirSync(browserDir).filter((name) => /^styles-[^/]+\.css$/u.test(name));
|
|
126
187
|
if (stylesheets.length === 0) fail('Missing hashed production stylesheet.');
|
|
127
|
-
const
|
|
128
|
-
readFileSync(path.join(browserDir, name), 'utf8')
|
|
188
|
+
const stylesheetSources = stylesheets.map((name) =>
|
|
189
|
+
readFileSync(path.join(browserDir, name), 'utf8'),
|
|
129
190
|
);
|
|
130
|
-
|
|
191
|
+
for (const url of [`/fonts/${fontName}`, interPreloadUrl]) {
|
|
192
|
+
if (!stylesheetSources.some((source) => source.includes(url))) {
|
|
193
|
+
fail(`Production stylesheet does not reference ${url}.`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
131
196
|
|
|
132
197
|
const inventory = new Set(readIconInventories(project).names);
|
|
133
198
|
const scanned = [project.sourceDir, ...options.scan.map((directory) => path.resolve(directory))];
|
|
@@ -140,7 +205,7 @@ export function run(argv) {
|
|
|
140
205
|
}
|
|
141
206
|
|
|
142
207
|
console.log(
|
|
143
|
-
`Production asset verification passed: favicon present,
|
|
144
|
-
|
|
208
|
+
`Production asset verification passed: favicon present, Inter preloaded, ` +
|
|
209
|
+
`${inventory.size} icon names tracked, icon font ${fontName} is ${statSync(fontPath).size} bytes.`,
|
|
145
210
|
);
|
|
146
211
|
}
|
|
@@ -2949,7 +2949,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
2949
2949
|
}]
|
|
2950
2950
|
}
|
|
2951
2951
|
});
|
|
2952
|
-
const RB_DESIGN_SYSTEM_VERSION = "1.2.
|
|
2952
|
+
const RB_DESIGN_SYSTEM_VERSION = "1.2.2";
|
|
2953
2953
|
export { RB_BREAKPOINTS, RB_BREAKPOINT_WIDTHS, RB_DESIGN_SYSTEM_VERSION, RB_ICON_FONT_SET, RB_MESSAGE_TONE_LABELS, RB_THEME_COLORS, RB_THEME_OPTIONS, RB_THEME_STORAGE_KEY, RB_TONE_ICONS, RbAppShellComponent, RbBrandLockupComponent, RbCentralSignInComponent, RbConfirmDialogComponent, RbConfirmDialogService, RbEmptyStateComponent, RbMessageComponent, RbMonogramComponent, RbPageHeaderComponent, RbPanelComponent, RbPublicShellComponent, RbShellFooterComponent, RbStatusChipComponent, RbTechnicalValueComponent, RbThemeToggleComponent, ThemeService, provideRbDesignSystem, rbConfirmDialogId };
|
|
2954
2954
|
|
|
2955
2955
|
//# sourceMappingURL=rblabs-dev-axiom.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rblabs-dev-axiom.mjs","names":[],"sources":["../../../projects/axiom/src/lib/brand/monogram/monogram.ts","../../../projects/axiom/src/lib/brand/brand-lockup/brand-lockup.ts","../../../projects/axiom/src/lib/breakpoints.ts","../../../projects/axiom/src/lib/components/confirm-dialog/confirm-dialog.ts","../../../projects/axiom/src/lib/components/confirm-dialog/confirm-dialog.service.ts","../../../projects/axiom/src/lib/components/empty-state/empty-state.ts","../../../projects/axiom/src/lib/components/tones.ts","../../../projects/axiom/src/lib/components/message/message.ts","../../../projects/axiom/src/lib/components/page-header/page-header.ts","../../../projects/axiom/src/lib/components/panel/panel.ts","../../../projects/axiom/src/lib/components/status-chip/status-chip.ts","../../../projects/axiom/src/lib/components/technical-value/technical-value.ts","../../../projects/axiom/src/lib/theme/theme.service.ts","../../../projects/axiom/src/lib/provide-design-system.ts","../../../projects/axiom/src/lib/theme/theme-toggle.ts","../../../projects/axiom/src/lib/shell/shell-footer/shell-footer.ts","../../../projects/axiom/src/lib/shell/app-shell/app-shell.ts","../../../projects/axiom/src/lib/shell/central-sign-in/central-sign-in.ts","../../../projects/axiom/src/lib/shell/public-shell/public-shell.ts","../../../projects/axiom/src/lib/version.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core';\n\nlet nextId = 0;\n\n/**\n * The RB monogram (docs/design-system.md, section 12.1), drawn inline from the brand tokens so it\n * needs no request and is identical in both themes. Decorative: the element that contains it (the\n * brand lockup link) carries the accessible name. Size it with `inline-size` on the host.\n */\n@Component({\n selector: 'rb-monogram',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'rb-monogram', 'aria-hidden': 'true' },\n template: `\n <svg class=\"rb-monogram__svg\" viewBox=\"0 0 64 64\" focusable=\"false\">\n <defs>\n <linearGradient\n [attr.id]=\"gradientId\"\n x1=\"8\"\n y1=\"8\"\n x2=\"56\"\n y2=\"56\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop class=\"rb-monogram__gradient-start\" />\n <stop class=\"rb-monogram__gradient-end\" offset=\"1\" />\n </linearGradient>\n </defs>\n <rect class=\"rb-monogram__frame\" width=\"64\" height=\"64\" rx=\"16\" />\n <rect x=\"5\" y=\"5\" width=\"54\" height=\"54\" rx=\"14\" [attr.fill]=\"'url(#' + gradientId + ')'\" />\n <g class=\"rb-monogram__letters\">\n <path d=\"M17 47V17h7.3c4.9 0 7.8 2.7 7.8 6.9s-2.9 6.8-7.8 6.8H17M24.3 30.7 34.5 47\" />\n <path\n d=\"M40 17v30M40 17h6.8c4.4 0 7.1 2.6 7.1 6.2s-2.7 5.9-7.1 5.9H40M40 29.1h7.5c4.7 0 7.7 3.2 7.7 7.1s-3 7.8-7.7 7.8H40\"\n />\n </g>\n </svg>\n `,\n styleUrl: './monogram.scss',\n})\nexport class RbMonogramComponent {\n /** Unique per instance: several monograms can share a page. */\n protected readonly gradientId = `rb-monogram-gradient-${nextId++}`;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n} from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nimport { RbMonogramComponent } from '../monogram/monogram';\n\n/** `true` shows only the monogram; `'below-sm'` does so only below the `sm` breakpoint. */\nexport type RbBrandLockupCompact = boolean | 'below-sm';\n\n/**\n * The RB monogram followed by \"RB Labs · <App name>\", as a link to the app's home\n * (docs/design-system.md, section 12.2). The accessible name stays \"RB Labs <App name> home\" in\n * every variant.\n */\n@Component({\n selector: 'rb-brand-lockup',\n imports: [RbMonogramComponent, RouterLink],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-brand-lockup',\n '[attr.data-compact]': 'compactAttribute()',\n },\n template: `\n <a class=\"rb-brand-lockup__link\" [routerLink]=\"link()\" [attr.aria-label]=\"accessibleName()\">\n <rb-monogram class=\"rb-brand-lockup__mark\" />\n <span class=\"rb-brand-lockup__wordmark\">\n <span class=\"rb-brand-lockup__brand\">RB Labs</span>\n <span class=\"rb-brand-lockup__app\"><span aria-hidden=\"true\">·</span> {{ appName() }}</span>\n </span>\n </a>\n `,\n styleUrl: './brand-lockup.scss',\n})\nexport class RbBrandLockupComponent {\n /** `Admin`, `Auth`, `Rover`, `Photogrammetry` or a new app's name. */\n readonly appName = input.required<string>();\n /** The app's home, as a `routerLink` value. */\n readonly link = input<string | readonly unknown[]>('/');\n readonly compact = input<RbBrandLockupCompact, RbBrandLockupCompact | ''>(false, {\n transform: (value) => (value === '' ? true : value),\n });\n\n protected readonly accessibleName = computed(() => `RB Labs ${this.appName()} home`);\n protected readonly compactAttribute = computed(() => {\n const compact = this.compact();\n return compact === true ? 'always' : compact || null;\n });\n}\n","/** Breakpoint widths (docs/design-system.md, section 8). Mirrors `$breakpoints` in _breakpoints.scss. */\nexport const RB_BREAKPOINT_WIDTHS = {\n xs: '30rem',\n sm: '40rem',\n md: '48rem',\n lg: '60rem',\n xl: '75rem',\n '2xl': '87.5rem',\n} as const;\n\nexport type RbBreakpoint = keyof typeof RB_BREAKPOINT_WIDTHS;\n\n/** Media queries for the CDK `BreakpointObserver`, e.g. `observe(RB_BREAKPOINTS.belowLg)`. */\nexport const RB_BREAKPOINTS = {\n belowXs: '(width < 30rem)',\n belowSm: '(width < 40rem)',\n belowMd: '(width < 48rem)',\n belowLg: '(width < 60rem)',\n belowXl: '(width < 75rem)',\n below2xl: '(width < 87.5rem)',\n aboveXs: '(width >= 30rem)',\n aboveSm: '(width >= 40rem)',\n aboveMd: '(width >= 48rem)',\n aboveLg: '(width >= 60rem)',\n aboveXl: '(width >= 75rem)',\n above2xl: '(width >= 87.5rem)',\n} as const;\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n inject,\n signal,\n viewChild,\n} from '@angular/core';\nimport { FormControl, ReactiveFormsModule, ValidatorFn } from '@angular/forms';\nimport { MatButton } from '@angular/material/button';\nimport {\n MAT_DIALOG_DATA,\n MatDialogActions,\n MatDialogContent,\n MatDialogRef,\n MatDialogTitle,\n} from '@angular/material/dialog';\nimport { MatIcon } from '@angular/material/icon';\n\nexport type RbConfirmDialogTone = 'primary' | 'danger';\n\nexport interface RbConfirmDialogReason {\n /** Visible label of the reason field. Defaults to \"Reason\". */\n label?: string;\n /** Helper text under the field. */\n hint?: string;\n /** Minimum length of the trimmed reason. Defaults to 3. */\n minimumLength?: number;\n}\n\nexport interface RbConfirmDialogData {\n title: string;\n description: string;\n confirmLabel: string;\n /** Defaults to \"Cancel\". */\n cancelLabel?: string;\n /** `danger` is for destructive or irreversible actions. Defaults to `primary`. */\n tone?: RbConfirmDialogTone;\n /** Asks for a required reason, returned trimmed in the result. */\n reason?: RbConfirmDialogReason;\n}\n\nexport interface RbConfirmDialogResult {\n confirmed: boolean;\n reason?: string;\n}\n\n/** Data the service adds so the dialog container can reference the description. */\nexport interface RbConfirmDialogInternalData extends RbConfirmDialogData {\n descriptionId?: string;\n}\n\nlet nextId = 0;\n\n/** Generates the ids shared by the service (dialog config) and the dialog content. */\nexport function rbConfirmDialogId(): string {\n return `rb-confirm-dialog-${nextId++}`;\n}\n\n/**\n * Confirmation content opened by `RbConfirmDialogService` (docs/design-system.md, section 15.7).\n * Use the service rather than opening this component directly.\n */\n@Component({\n selector: 'rb-confirm-dialog',\n imports: [\n MatButton,\n MatDialogActions,\n MatDialogContent,\n MatDialogTitle,\n MatIcon,\n ReactiveFormsModule,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-confirm-dialog',\n '[attr.data-tone]': 'tone',\n },\n template: `\n <div class=\"rb-confirm-dialog__layout\">\n <span class=\"rb-confirm-dialog__icon\" aria-hidden=\"true\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{\n tone === 'danger' ? 'warning' : 'help'\n }}</mat-icon>\n </span>\n <div class=\"rb-confirm-dialog__body\">\n <h2 mat-dialog-title class=\"rb-confirm-dialog__title\">{{ data.title }}</h2>\n <mat-dialog-content class=\"rb-confirm-dialog__content\">\n <p class=\"rb-confirm-dialog__description\" [id]=\"descriptionId\">{{ data.description }}</p>\n @if (data.reason) {\n <div class=\"rb-field\" [class.rb-field--invalid]=\"showReasonError()\">\n <label class=\"rb-field__label\" [for]=\"reasonId\">{{\n data.reason.label ?? 'Reason'\n }}</label>\n <input\n #reasonInput\n class=\"rb-field__control\"\n type=\"text\"\n autocomplete=\"off\"\n [id]=\"reasonId\"\n [formControl]=\"reason\"\n [attr.aria-invalid]=\"showReasonError() ? 'true' : null\"\n [attr.aria-describedby]=\"reasonDescribedBy()\"\n />\n @if (data.reason.hint) {\n <p class=\"rb-field__hint\" [id]=\"reasonId + '-hint'\">{{ data.reason.hint }}</p>\n }\n @if (showReasonError()) {\n <p class=\"rb-field__error\" [id]=\"reasonId + '-error'\">\n Enter at least {{ minimumReasonLength }} characters.\n </p>\n }\n </div>\n }\n </mat-dialog-content>\n </div>\n </div>\n <mat-dialog-actions align=\"end\" class=\"rb-confirm-dialog__actions\">\n <button matButton type=\"button\" (click)=\"cancel()\">{{ data.cancelLabel ?? 'Cancel' }}</button>\n <button\n matButton=\"filled\"\n type=\"button\"\n [color]=\"tone === 'danger' ? 'warn' : 'primary'\"\n (click)=\"confirm()\"\n >\n {{ data.confirmLabel }}\n </button>\n </mat-dialog-actions>\n `,\n styleUrl: './confirm-dialog.scss',\n})\nexport class RbConfirmDialogComponent {\n protected readonly data = inject<RbConfirmDialogInternalData>(MAT_DIALOG_DATA);\n private readonly dialogRef =\n inject<MatDialogRef<RbConfirmDialogComponent, RbConfirmDialogResult>>(MatDialogRef);\n private readonly reasonInput = viewChild<ElementRef<HTMLInputElement>>('reasonInput');\n\n private readonly id = rbConfirmDialogId();\n protected readonly descriptionId = this.data.descriptionId ?? `${this.id}-description`;\n protected readonly reasonId = `${this.id}-reason`;\n protected readonly tone: RbConfirmDialogTone = this.data.tone ?? 'primary';\n protected readonly minimumReasonLength = this.data.reason?.minimumLength ?? 3;\n\n private readonly trimmedMinLength: ValidatorFn = (control) =>\n String(control.value).trim().length >= this.minimumReasonLength\n ? null\n : { trimmedMinLength: true };\n\n protected readonly reason = new FormControl('', {\n nonNullable: true,\n validators: this.data.reason ? [this.trimmedMinLength] : [],\n });\n\n private readonly submitted = signal(false);\n\n protected showReasonError(): boolean {\n return this.submitted() && this.reason.invalid;\n }\n\n protected reasonDescribedBy(): string | null {\n const ids = [\n this.data.reason?.hint ? `${this.reasonId}-hint` : null,\n this.showReasonError() ? `${this.reasonId}-error` : null,\n ].filter((value): value is string => value !== null);\n return ids.length > 0 ? ids.join(' ') : null;\n }\n\n cancel(): void {\n this.dialogRef.close({ confirmed: false });\n }\n\n confirm(): void {\n if (this.data.reason) {\n this.submitted.set(true);\n if (this.reason.invalid) {\n // Focus returns to the field, which now announces its error through aria-describedby.\n this.reasonInput()?.nativeElement.focus();\n return;\n }\n }\n\n this.dialogRef.close({\n confirmed: true,\n ...(this.data.reason ? { reason: this.reason.value.trim() } : {}),\n });\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { MatDialog } from '@angular/material/dialog';\nimport { firstValueFrom } from 'rxjs';\n\nimport {\n RbConfirmDialogComponent,\n RbConfirmDialogData,\n RbConfirmDialogInternalData,\n RbConfirmDialogResult,\n rbConfirmDialogId,\n} from './confirm-dialog';\n\n/**\n * Asks the user to confirm an action (docs/design-system.md, section 15.7):\n *\n * ```ts\n * const { confirmed, reason } = await confirmDialog.confirm({\n * title: 'Revoke credential?',\n * description: 'Clients using it stop working immediately.',\n * confirmLabel: 'Revoke credential',\n * tone: 'danger',\n * reason: { label: 'Reason for revoking' },\n * });\n * ```\n *\n * Closing the dialog in any other way (Cancel, Escape, the backdrop) resolves `confirmed: false`.\n */\n@Injectable({ providedIn: 'root' })\nexport class RbConfirmDialogService {\n private readonly dialog = inject(MatDialog);\n\n async confirm(data: RbConfirmDialogData): Promise<RbConfirmDialogResult> {\n const descriptionId = `${rbConfirmDialogId()}-description`;\n const dialogRef = this.dialog.open<\n RbConfirmDialogComponent,\n RbConfirmDialogInternalData,\n RbConfirmDialogResult\n >(RbConfirmDialogComponent, {\n data: { ...data, descriptionId },\n // A destructive confirmation interrupts the task, so it is announced as an alert dialog.\n role: data.tone === 'danger' ? 'alertdialog' : 'dialog',\n ariaDescribedBy: descriptionId,\n // The reason field when there is one, otherwise Cancel: never the destructive button.\n autoFocus: 'first-tabbable',\n restoreFocus: true,\n width: 'min(var(--rb-size-card-wide), calc(100vw - 2 * var(--rb-space-4)))',\n maxWidth: '100vw',\n // `rb-scope` gives the pane the kit's tokens while the kit is applied scoped (14).\n panelClass: ['rb-confirm-dialog-panel', 'rb-scope'],\n });\n\n return (await firstValueFrom(dialogRef.afterClosed())) ?? { confirmed: false };\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n input,\n output,\n} from '@angular/core';\nimport { MatButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\n\nimport { RbHeadingLevel } from '../panel/panel';\n\nexport type RbEmptyStateLayout = 'centered' | 'inline';\n\n/**\n * Explains why a region has no content and, when there is one, offers the next step\n * (docs/design-system.md, section 15.4). `actionLabel` renders an outlined button that emits\n * `action`; elements marked `rbActions` are projected next to it, for links or several actions.\n */\n@Component({\n selector: 'rb-empty-state',\n imports: [MatButton, MatIcon],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-empty-state',\n // `title` is an input; a static `title=\"…\"` would also leave a native tooltip on the host.\n '[attr.title]': 'null',\n '[attr.data-layout]': 'layout()',\n },\n template: `\n <mat-icon class=\"rb-empty-state__icon\" fontSet=\"material-symbols-outlined\" aria-hidden=\"true\">{{\n icon()\n }}</mat-icon>\n <div class=\"rb-empty-state__copy\">\n @switch (headingLevel()) {\n @case (2) {\n <h2 class=\"rb-empty-state__title\">{{ title() }}</h2>\n }\n @case (4) {\n <h4 class=\"rb-empty-state__title\">{{ title() }}</h4>\n }\n @case (5) {\n <h5 class=\"rb-empty-state__title\">{{ title() }}</h5>\n }\n @case (6) {\n <h6 class=\"rb-empty-state__title\">{{ title() }}</h6>\n }\n @default {\n <h3 class=\"rb-empty-state__title\">{{ title() }}</h3>\n }\n }\n @if (description()) {\n <p class=\"rb-empty-state__description\">{{ description() }}</p>\n }\n <div class=\"rb-empty-state__actions\">\n @if (actionLabel()) {\n <button matButton=\"outlined\" type=\"button\" (click)=\"action.emit()\">\n {{ actionLabel() }}\n </button>\n }\n <ng-content select=\"[rbActions]\" />\n </div>\n </div>\n `,\n styleUrl: './empty-state.scss',\n})\nexport class RbEmptyStateComponent {\n readonly title = input.required<string>();\n readonly description = input<string>('');\n readonly icon = input<string>('inbox');\n /** Heading level of the title; follows the document outline, not the visual size. */\n readonly headingLevel = input<RbHeadingLevel>(3);\n /** `inline` is the compact variant for sidebars and narrow panels. */\n readonly layout = input<RbEmptyStateLayout>('centered');\n /** Label of the recovery button; leave empty for a purely informational state. */\n readonly actionLabel = input<string>('');\n readonly action = output<void>();\n}\n","/** Tones of `rb-message` (docs/design-system.md, section 15.3). */\nexport type RbMessageTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';\n\n/** Tones of `rb-status-chip` and page header metrics (15.1, 15.5). `active` means in progress. */\nexport type RbStatusTone = 'neutral' | 'active' | 'success' | 'warning' | 'danger';\n\n/**\n * Default icon per tone, so state is never carried by color alone (section 9.4). Neutral status\n * chips and metrics have no default icon: their label is the whole message.\n */\nexport const RB_TONE_ICONS: Readonly<Record<RbMessageTone | RbStatusTone, string | null>> = {\n neutral: null,\n info: 'info',\n active: 'autorenew',\n success: 'check_circle',\n warning: 'warning',\n danger: 'error',\n};\n\n/** Visually hidden prefix that names a message's tone for screen reader users. */\nexport const RB_MESSAGE_TONE_LABELS: Readonly<Record<RbMessageTone, string | null>> = {\n neutral: null,\n info: 'Information',\n success: 'Success',\n warning: 'Warning',\n danger: 'Error',\n};\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n} from '@angular/core';\nimport { MatIcon } from '@angular/material/icon';\n\nimport { RB_MESSAGE_TONE_LABELS, RB_TONE_ICONS, RbMessageTone } from '../tones';\n\n/**\n * How the message is announced. `auto` makes a danger message an assertive alert and every other\n * tone a polite status; `off` renders a static message with no live region.\n */\nexport type RbMessageLive = 'auto' | 'polite' | 'assertive' | 'off';\n\n/**\n * Inline status message (docs/design-system.md, section 15.3). The host is the live region, so keep\n * the component mounted and change its content: a region inserted together with its text is not\n * announced by most screen readers (section 9.5).\n */\n@Component({\n selector: 'rb-message',\n imports: [MatIcon],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-message',\n // `title` is an input; a static `title=\"…\"` would also leave a native tooltip on the host.\n '[attr.title]': 'null',\n '[attr.data-tone]': 'tone()',\n '[attr.role]': 'role()',\n '[attr.aria-live]': 'ariaLive()',\n },\n template: `\n <mat-icon class=\"rb-message__icon\" fontSet=\"material-symbols-outlined\" aria-hidden=\"true\">{{\n resolvedIcon()\n }}</mat-icon>\n <div class=\"rb-message__copy\">\n @if (title()) {\n <p class=\"rb-message__title\">\n @if (toneLabel()) {\n <span class=\"rb-visually-hidden\">{{ toneLabel() }}: </span>\n }\n {{ title() }}\n </p>\n } @else if (toneLabel()) {\n <span class=\"rb-visually-hidden\">{{ toneLabel() }}: </span>\n }\n <div class=\"rb-message__body\"><ng-content /></div>\n </div>\n `,\n styleUrl: './message.scss',\n})\nexport class RbMessageComponent {\n readonly tone = input<RbMessageTone>('neutral');\n /** Optional bold first line. */\n readonly title = input<string>('');\n /** Overrides the tone's default icon. */\n readonly icon = input<string>('');\n readonly live = input<RbMessageLive>('auto');\n\n protected readonly resolvedIcon = computed(\n () => this.icon() || RB_TONE_ICONS[this.tone()] || 'info',\n );\n protected readonly toneLabel = computed(() => RB_MESSAGE_TONE_LABELS[this.tone()]);\n\n private readonly politeness = computed(() => {\n const live = this.live();\n if (live !== 'auto') return live;\n return this.tone() === 'danger' ? 'assertive' : 'polite';\n });\n\n protected readonly role = computed(() => {\n const politeness = this.politeness();\n if (politeness === 'off') return null;\n return politeness === 'assertive' ? 'alert' : 'status';\n });\n\n protected readonly ariaLive = computed(() => {\n const politeness = this.politeness();\n return politeness === 'off' ? null : politeness;\n });\n}\n","import { ChangeDetectionStrategy, Component, ViewEncapsulation, input } from '@angular/core';\nimport { MatIcon } from '@angular/material/icon';\n\nimport { RB_TONE_ICONS, RbStatusTone } from '../tones';\n\nexport interface RbPageHeaderMetric {\n label: string;\n value: string | number;\n /** Adds a tone color and icon to the value; the label and value carry the meaning. */\n tone?: RbStatusTone;\n}\n\n/**\n * The page's single `<h1>` with its eyebrow, description, summary metrics and page actions\n * (docs/design-system.md, section 15.1). Elements marked `rbActions` are projected next to the\n * title.\n */\n@Component({\n selector: 'rb-page-header',\n imports: [MatIcon],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-page-header',\n // `title` is an input; a static `title=\"…\"` would also leave a native tooltip on the host.\n '[attr.title]': 'null',\n },\n template: `\n <header class=\"rb-page-header__main\">\n <div class=\"rb-page-header__copy\">\n @if (eyebrow()) {\n <p class=\"rb-page-header__eyebrow\">{{ eyebrow() }}</p>\n }\n <h1 class=\"rb-page-header__title\">{{ title() }}</h1>\n @if (description()) {\n <p class=\"rb-page-header__description\">{{ description() }}</p>\n }\n </div>\n <div class=\"rb-page-header__actions\"><ng-content select=\"[rbActions]\" /></div>\n </header>\n @if (metrics().length > 0) {\n <dl class=\"rb-page-header__metrics\">\n @for (metric of metrics(); track metric.label) {\n <div class=\"rb-page-header__metric\" [attr.data-tone]=\"metric.tone ?? 'neutral'\">\n <dt class=\"rb-page-header__metric-label\">{{ metric.label }}</dt>\n <dd class=\"rb-page-header__metric-value\">\n @if (toneIcon(metric); as icon) {\n <mat-icon fontSet=\"material-symbols-outlined\" aria-hidden=\"true\">{{\n icon\n }}</mat-icon>\n }\n <span>{{ metric.value }}</span>\n </dd>\n </div>\n }\n </dl>\n }\n `,\n styleUrl: './page-header.scss',\n})\nexport class RbPageHeaderComponent {\n readonly title = input.required<string>();\n /** Short context line above the title, such as the app area. */\n readonly eyebrow = input<string>('');\n readonly description = input<string>('');\n readonly metrics = input<readonly RbPageHeaderMetric[]>([]);\n\n protected toneIcon(metric: RbPageHeaderMetric): string | null {\n return RB_TONE_ICONS[metric.tone ?? 'neutral'];\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n booleanAttribute,\n input,\n} from '@angular/core';\n\nexport type RbPanelVariant = 'default' | 'soft' | 'elevated' | 'danger';\nexport type RbHeadingLevel = 2 | 3 | 4 | 5 | 6;\n\n/**\n * Content container with an optional header (docs/design-system.md, section 15.2). Elements marked\n * `rbActions` are projected into the header next to the title.\n */\n@Component({\n selector: 'rb-panel',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-panel',\n // `title` is an input; a static `title=\"…\"` would also leave a native tooltip on the host.\n '[attr.title]': 'null',\n '[attr.data-variant]': 'variant()',\n '[attr.data-flush]': 'flush() ? \"\" : null',\n },\n template: `\n @if (title() || description()) {\n <header class=\"rb-panel__header\">\n <div class=\"rb-panel__heading\">\n @if (title()) {\n @switch (headingLevel()) {\n @case (3) {\n <h3 class=\"rb-panel__title\">{{ title() }}</h3>\n }\n @case (4) {\n <h4 class=\"rb-panel__title\">{{ title() }}</h4>\n }\n @case (5) {\n <h5 class=\"rb-panel__title\">{{ title() }}</h5>\n }\n @case (6) {\n <h6 class=\"rb-panel__title\">{{ title() }}</h6>\n }\n @default {\n <h2 class=\"rb-panel__title\">{{ title() }}</h2>\n }\n }\n }\n @if (description()) {\n <p class=\"rb-panel__description\">{{ description() }}</p>\n }\n </div>\n <div class=\"rb-panel__actions\"><ng-content select=\"[rbActions]\" /></div>\n </header>\n }\n <div class=\"rb-panel__body\"><ng-content /></div>\n `,\n styleUrl: './panel.scss',\n})\nexport class RbPanelComponent {\n readonly title = input<string>('');\n readonly description = input<string>('');\n readonly variant = input<RbPanelVariant>('default');\n /** Heading level of the title; follows the document outline, not the visual size. */\n readonly headingLevel = input<RbHeadingLevel>(2);\n /** Removes the body padding, for a table or list that runs to the panel's edges. */\n readonly flush = input(false, { transform: booleanAttribute });\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n} from '@angular/core';\nimport { MatIcon } from '@angular/material/icon';\n\nimport { RB_TONE_ICONS, RbStatusTone } from '../tones';\n\nexport type RbStatusChipSize = 'default' | 'compact';\n\n/**\n * Read-only status label (docs/design-system.md, section 15.5). The label is always visible and\n * every non-neutral tone has an icon, so the state is never carried by color alone. It is not\n * interactive and not a live region: announce changes through `rb-message` or a status region.\n */\n@Component({\n selector: 'rb-status-chip',\n imports: [MatIcon],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-status-chip',\n '[attr.data-tone]': 'tone()',\n '[attr.data-size]': 'size()',\n },\n template: `\n @if (resolvedIcon(); as icon) {\n <mat-icon\n class=\"rb-status-chip__icon\"\n fontSet=\"material-symbols-outlined\"\n aria-hidden=\"true\"\n >{{ icon }}</mat-icon\n >\n }\n <span class=\"rb-status-chip__label\">{{ label() }}</span>\n `,\n styleUrl: './status-chip.scss',\n})\nexport class RbStatusChipComponent {\n readonly label = input.required<string>();\n readonly tone = input<RbStatusTone>('neutral');\n /** Overrides the tone's default icon. */\n readonly icon = input<string>('');\n /** `compact` fits a single table row line. */\n readonly size = input<RbStatusChipSize>('default');\n\n protected readonly resolvedIcon = computed(() => this.icon() || RB_TONE_ICONS[this.tone()]);\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n ViewEncapsulation,\n afterNextRender,\n afterRenderEffect,\n computed,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { MatTooltip } from '@angular/material/tooltip';\n\n/**\n * Identifier, key, hash or path in monospace on one line (docs/design-system.md, section 15.6).\n * A value that does not fit is truncated with an ellipsis and the full value appears in a tooltip.\n * Screen readers and copying always get the full value, even when `displayValue` shortens it.\n */\n@Component({\n selector: 'rb-technical-value',\n imports: [MatTooltip],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-technical-value',\n '(copy)': 'copyFullValue($event)',\n },\n template: `\n <span\n #text\n class=\"rb-technical-value__text\"\n [matTooltip]=\"value()\"\n [matTooltipDisabled]=\"!tooltipEnabled()\"\n [attr.aria-hidden]=\"shortened() ? 'true' : null\"\n >{{ shownValue() }}</span\n >\n @if (shortened()) {\n <span class=\"rb-visually-hidden\">{{ value() }}</span>\n }\n `,\n styleUrl: './technical-value.scss',\n})\nexport class RbTechnicalValueComponent {\n readonly value = input.required<string>();\n /** Shorter text to show instead of the value, such as the first characters of a hash. */\n readonly displayValue = input<string>('');\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n private readonly text = viewChild.required<ElementRef<HTMLElement>>('text');\n private readonly truncated = signal(false);\n\n protected readonly shownValue = computed(() => this.displayValue() || this.value());\n protected readonly shortened = computed(() => this.shownValue() !== this.value());\n protected readonly tooltipEnabled = computed(\n () => this.value() !== '' && (this.shortened() || this.truncated()),\n );\n\n constructor() {\n // Re-measured whenever the text changes and whenever the element is resized.\n afterRenderEffect({\n read: () => {\n this.shownValue();\n this.measure();\n },\n });\n\n afterNextRender(() => {\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => this.measure());\n observer.observe(this.text().nativeElement);\n this.destroyRef.onDestroy(() => observer.disconnect());\n });\n }\n\n /** Copying a selection inside the component copies the full value, not the shortened text. */\n protected copyFullValue(event: ClipboardEvent): void {\n if (!this.shortened() || !event.clipboardData) return;\n const selection = this.host.nativeElement.ownerDocument.getSelection();\n const host = this.host.nativeElement;\n if (!selection || !host.contains(selection.anchorNode) || !host.contains(selection.focusNode))\n return;\n event.clipboardData.setData('text/plain', this.value());\n event.preventDefault();\n }\n\n private measure(): void {\n const element = this.text().nativeElement;\n this.truncated.set(element.scrollWidth > element.clientWidth);\n }\n}\n","import { DOCUMENT } from '@angular/common';\nimport { DestroyRef, Injectable, InjectionToken, computed, inject, signal } from '@angular/core';\n\nexport type RbTheme = 'light' | 'dark';\n\n/** localStorage key holding the user's explicit choice (docs/design-system.md, section 11). */\nexport const RB_THEME_STORAGE_KEY = 'rb-theme';\n\n/** `--rb-color-bg` per theme; also the `<meta name=\"theme-color\">` value. */\nexport const RB_THEME_COLORS: Readonly<Record<RbTheme, string>> = {\n light: '#f4f7fb',\n dark: '#08111d',\n};\n\nexport interface RbThemeOptions {\n /**\n * Forces a theme regardless of the stored choice and the OS, without persisting anything. Used by\n * apps that only support one theme until their migration is done. The theme toggle hides itself\n * while a theme is forced.\n */\n forcedTheme?: RbTheme | null;\n /** Storage keys an app used before adopting the kit; a valid value is moved to `rb-theme` once. */\n legacyStorageKeys?: readonly string[];\n}\n\nexport const RB_THEME_OPTIONS = new InjectionToken<RbThemeOptions>('RB_THEME_OPTIONS', {\n providedIn: 'root',\n factory: () => ({}),\n});\n\nconst DARK_SCHEME_QUERY = '(prefers-color-scheme: dark)';\n\nfunction isTheme(value: unknown): value is RbTheme {\n return value === 'light' || value === 'dark';\n}\n\n/**\n * Owns the light/dark theme contract (docs/design-system.md, section 11):\n *\n * - an explicit choice is stored under `rb-theme` and wins over the OS;\n * - without one, the theme follows `prefers-color-scheme` and tracks OS changes live;\n * - the resolved theme is written to `<html>` as `data-theme`, and every\n * `<meta name=\"theme-color\">` is kept in sync;\n * - `color-scheme` is only set inline for an explicit or forced theme; otherwise the stylesheet's\n * `color-scheme: light dark` already follows the OS before any script runs.\n *\n * `provideRbDesignSystem()` calls `initialize()` from an app initializer, before first paint.\n */\n@Injectable({ providedIn: 'root' })\nexport class ThemeService {\n private readonly document = inject(DOCUMENT);\n private readonly options = inject(RB_THEME_OPTIONS);\n private readonly window = this.document.defaultView;\n private readonly darkScheme = this.window?.matchMedia?.(DARK_SCHEME_QUERY) ?? null;\n\n private readonly systemTheme = signal<RbTheme>(this.darkScheme?.matches ? 'dark' : 'light');\n private readonly storedTheme = signal<RbTheme | null>(null);\n private readonly forcedTheme = signal<RbTheme | null>(this.options.forcedTheme ?? null);\n private initialized = false;\n\n /** The user's explicit choice, or `null` while the theme follows the OS. */\n readonly preference = this.storedTheme.asReadonly();\n /** The theme in effect: forced, then stored, then the OS preference. */\n readonly theme = computed<RbTheme>(\n () => this.forcedTheme() ?? this.storedTheme() ?? this.systemTheme(),\n );\n readonly isDark = computed(() => this.theme() === 'dark');\n /** True while a theme is forced; the toggle is hidden then. */\n readonly isForced = computed(() => this.forcedTheme() !== null);\n\n constructor() {\n const onSystemChange = (event: MediaQueryListEvent): void => {\n this.systemTheme.set(event.matches ? 'dark' : 'light');\n this.apply();\n };\n this.darkScheme?.addEventListener('change', onSystemChange);\n inject(DestroyRef).onDestroy(() =>\n this.darkScheme?.removeEventListener('change', onSystemChange),\n );\n }\n\n /** Reads the stored choice and applies the theme to the document. Safe to call more than once. */\n initialize(): void {\n if (!this.initialized) {\n this.initialized = true;\n this.storedTheme.set(this.readStoredTheme());\n }\n this.apply();\n }\n\n /** Switches between light and dark and stores the result as an explicit choice. */\n toggle(): void {\n this.setTheme(this.theme() === 'dark' ? 'light' : 'dark');\n }\n\n /** Stores an explicit choice; OS changes are ignored from now on. */\n setTheme(theme: RbTheme): void {\n this.initialized = true;\n this.storedTheme.set(theme);\n this.write(RB_THEME_STORAGE_KEY, theme);\n this.apply();\n }\n\n /** Forgets the explicit choice, so the theme follows the OS again. */\n clearPreference(): void {\n this.initialized = true;\n this.storedTheme.set(null);\n this.remove(RB_THEME_STORAGE_KEY);\n this.apply();\n }\n\n /** Forces a theme (or releases it with `null`) without touching the stored choice. */\n forceTheme(theme: RbTheme | null): void {\n this.forcedTheme.set(theme);\n this.apply();\n }\n\n private apply(): void {\n const root = this.document.documentElement;\n const theme = this.theme();\n const explicit = this.forcedTheme() ?? this.storedTheme();\n\n root.dataset['theme'] = theme;\n if (explicit) {\n root.style.colorScheme = explicit;\n } else {\n root.style.removeProperty('color-scheme');\n }\n\n for (const meta of Array.from(\n this.document.querySelectorAll<HTMLMetaElement>('meta[name=\"theme-color\"]'),\n )) {\n meta.content = RB_THEME_COLORS[theme];\n }\n }\n\n private readStoredTheme(): RbTheme | null {\n const stored = this.read(RB_THEME_STORAGE_KEY);\n let theme: RbTheme | null = isTheme(stored) ? stored : null;\n\n for (const legacyKey of this.options.legacyStorageKeys ?? []) {\n const legacy = this.read(legacyKey);\n if (theme === null && isTheme(legacy)) {\n theme = legacy;\n this.write(RB_THEME_STORAGE_KEY, legacy);\n }\n if (legacy !== null) this.remove(legacyKey);\n }\n\n return theme;\n }\n\n // Storage can be unavailable (privacy modes, disabled storage); the theme then follows the OS.\n private read(key: string): string | null {\n try {\n return this.window?.localStorage.getItem(key) ?? null;\n } catch {\n return null;\n }\n }\n\n private write(key: string, value: string): void {\n try {\n this.window?.localStorage.setItem(key, value);\n } catch {\n // Ignore: the choice still applies for this session.\n }\n }\n\n private remove(key: string): void {\n try {\n this.window?.localStorage.removeItem(key);\n } catch {\n // Ignore: nothing to clean up without storage.\n }\n }\n}\n","import {\n EnvironmentProviders,\n inject,\n makeEnvironmentProviders,\n provideAppInitializer,\n} from '@angular/core';\nimport { MatIconRegistry } from '@angular/material/icon';\n\nimport { RB_THEME_OPTIONS, RbThemeOptions, ThemeService } from './theme/theme.service';\n\n/** Font set class of the self-hosted Material Symbols subset (docs/design-system.md, section 10). */\nexport const RB_ICON_FONT_SET = 'material-symbols-outlined';\n\nexport type RbDesignSystemOptions = RbThemeOptions;\n\n/**\n * Registers the kit's runtime pieces in `app.config.ts`:\n *\n * - applies the theme before the root component renders (no flash for a stored choice);\n * - makes `material-symbols-outlined` the default `<mat-icon>` font set.\n */\nexport function provideRbDesignSystem(options: RbDesignSystemOptions = {}): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: RB_THEME_OPTIONS, useValue: options },\n provideAppInitializer(() => {\n inject(ThemeService).initialize();\n inject(MatIconRegistry).setDefaultFontSetClass(RB_ICON_FONT_SET);\n }),\n ]);\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatTooltip } from '@angular/material/tooltip';\n\nimport { ThemeService } from './theme.service';\n\n/**\n * Light/dark switch for the app shell (docs/design-system.md, section 11). The accessible name stays\n * \"Dark theme\" and `aria-pressed` carries the state, so the label never rewrites itself into the\n * opposite action. Renders nothing while the app forces a theme.\n */\n@Component({\n selector: 'rb-theme-toggle',\n imports: [MatIconButton, MatIcon, MatTooltip],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (!theme.isForced()) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"rb-theme-toggle\"\n aria-label=\"Dark theme\"\n matTooltip=\"Dark theme\"\n [attr.aria-pressed]=\"theme.isDark()\"\n (click)=\"theme.toggle()\"\n >\n <mat-icon fontSet=\"material-symbols-outlined\" aria-hidden=\"true\">dark_mode</mat-icon>\n </button>\n }\n `,\n styles: `\n :host {\n display: inline-flex;\n }\n\n .rb-theme-toggle[aria-pressed='true'] {\n background-color: var(--rb-color-primary-soft);\n color: var(--rb-color-on-primary-soft);\n }\n `,\n})\nexport class RbThemeToggleComponent {\n protected readonly theme = inject(ThemeService);\n}\n","import { ChangeDetectionStrategy, Component, ViewEncapsulation, input } from '@angular/core';\n\n/**\n * The standard footer of every shell (docs/design-system.md, section 12.5): \"© <year> RB Labs ·\n * <App name>\", followed on the same line by any projected links or status.\n */\n@Component({\n selector: 'rb-shell-footer',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'rb-shell-footer' },\n template: `\n <footer class=\"rb-shell-footer__inner\">\n <p class=\"rb-shell-footer__copy\">© {{ year }} RB Labs · {{ appName() }}</p>\n <div class=\"rb-shell-footer__extra\"><ng-content /></div>\n </footer>\n `,\n styleUrl: './shell-footer.scss',\n})\nexport class RbShellFooterComponent {\n readonly appName = input.required<string>();\n\n protected readonly year = new Date().getFullYear();\n}\n","import { BreakpointObserver } from '@angular/cdk/layout';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n ViewEncapsulation,\n computed,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { NavigationEnd, Router } from '@angular/router';\nimport { filter } from 'rxjs';\n\nimport { RbBrandLockupComponent } from '../../brand/brand-lockup/brand-lockup';\nimport { RB_BREAKPOINTS } from '../../breakpoints';\nimport { RbThemeToggleComponent } from '../../theme/theme-toggle';\nimport { RbShellFooterComponent } from '../shell-footer/shell-footer';\n\n/**\n * `sidenav`: a navigation rail beside the content that becomes a drawer below `lg`.\n * `modules`: a short list of sections beside the content that becomes a row, then a tab bar.\n * `none`: top-level links, if any, go in the `[rbShellActions]` slot.\n */\nexport type RbAppShellNavigation = 'none' | 'sidenav' | 'modules';\n\n/**\n * Frame for authenticated and operational areas (docs/design-system.md, section 16.1): skip link,\n * top bar with the brand lockup, title, actions and theme toggle, optional navigation, the content\n * column and the standard footer.\n */\n@Component({\n selector: 'rb-app-shell',\n imports: [\n MatIcon,\n MatIconButton,\n MatSidenav,\n MatSidenavContainer,\n MatSidenavContent,\n MatTooltip,\n NgTemplateOutlet,\n RbBrandLockupComponent,\n RbShellFooterComponent,\n RbThemeToggleComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-app-shell',\n '[attr.data-navigation]': 'navigation()',\n '[attr.data-drawer]': 'isDrawer() ? \"\" : null',\n },\n template: `\n <a class=\"rb-skip-link\" href=\"#main-content\" (click)=\"skipToMain($event)\"\n >Skip to main content</a\n >\n\n <header class=\"rb-app-shell__topbar\">\n @if (hasSidenav() && isDrawer()) {\n <button\n matIconButton\n type=\"button\"\n class=\"rb-app-shell__menu\"\n aria-label=\"Navigation\"\n matTooltip=\"Navigation\"\n aria-controls=\"rb-app-shell-sidenav\"\n [attr.aria-expanded]=\"drawerOpen()\"\n (click)=\"toggleDrawer()\"\n >\n <mat-icon fontSet=\"material-symbols-outlined\" aria-hidden=\"true\">menu</mat-icon>\n </button>\n }\n <rb-brand-lockup [appName]=\"appName()\" [link]=\"homeLink()\" compact=\"below-sm\" />\n <div class=\"rb-app-shell__title\"><ng-content select=\"[rbShellTitle]\" /></div>\n <div class=\"rb-app-shell__actions\">\n <ng-content select=\"[rbShellActions]\" />\n <rb-theme-toggle />\n </div>\n </header>\n\n @if (hasSidenav()) {\n <mat-sidenav-container class=\"rb-app-shell__container\">\n <mat-sidenav\n id=\"rb-app-shell-sidenav\"\n class=\"rb-app-shell__sidenav\"\n [mode]=\"isDrawer() ? 'over' : 'side'\"\n [opened]=\"!isDrawer() || drawerOpen()\"\n (closedStart)=\"drawerOpen.set(false)\"\n >\n <ng-content select=\"[rbShellSidenav]\" />\n </mat-sidenav>\n <mat-sidenav-content class=\"rb-app-shell__scroller\">\n <ng-container [ngTemplateOutlet]=\"body\" />\n </mat-sidenav-content>\n </mat-sidenav-container>\n } @else {\n <ng-container [ngTemplateOutlet]=\"body\" />\n }\n\n <ng-template #body>\n <div class=\"rb-app-shell__body\">\n @if (navigation() === 'modules') {\n <div class=\"rb-app-shell__module-nav\"><ng-content select=\"[rbShellModuleNav]\" /></div>\n }\n <main #main class=\"rb-app-shell__main\" id=\"main-content\" tabindex=\"-1\">\n <ng-content />\n </main>\n </div>\n <rb-shell-footer [appName]=\"appName()\"\n ><ng-content select=\"[rbShellFooter]\"\n /></rb-shell-footer>\n </ng-template>\n `,\n styleUrl: './app-shell.scss',\n})\nexport class RbAppShellComponent {\n /** Shown in the lockup and the footer: `Admin`, `Auth`, `Rover`, `Photogrammetry`… */\n readonly appName = input.required<string>();\n /** The lockup's link target, as a `routerLink` value. */\n readonly homeLink = input<string | readonly unknown[]>('/');\n readonly navigation = input<RbAppShellNavigation>('none');\n\n protected readonly hasSidenav = computed(() => this.navigation() === 'sidenav');\n\n private readonly breakpointObserver = inject(BreakpointObserver);\n /** Below `lg` the sidenav is an overlay drawer (section 8.1). */\n readonly isDrawer = signal(this.breakpointObserver.isMatched(RB_BREAKPOINTS.belowLg));\n readonly drawerOpen = signal(false);\n\n private readonly main = viewChild.required<ElementRef<HTMLElement>>('main');\n\n constructor() {\n const destroyRef = inject(DestroyRef);\n\n this.breakpointObserver\n .observe(RB_BREAKPOINTS.belowLg)\n .pipe(takeUntilDestroyed(destroyRef))\n .subscribe(({ matches }) => {\n this.isDrawer.set(matches);\n if (!matches) this.drawerOpen.set(false);\n });\n\n inject(Router)\n .events.pipe(\n filter((event) => event instanceof NavigationEnd),\n takeUntilDestroyed(destroyRef),\n )\n .subscribe(() => this.drawerOpen.set(false));\n }\n\n toggleDrawer(): void {\n this.drawerOpen.update((open) => !open);\n }\n\n /**\n * Moves focus to `<main>` without changing the URL: with `<base href=\"/\">` a bare `#main-content`\n * link would resolve to the root route instead of the current page.\n */\n protected skipToMain(event: Event): void {\n event.preventDefault();\n this.main().nativeElement.focus();\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n output,\n} from '@angular/core';\nimport { MatButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { RouterLink } from '@angular/router';\n\nimport { RbMonogramComponent } from '../../brand/monogram/monogram';\nimport { RbMessageComponent } from '../../components/message/message';\n\nlet nextId = 0;\n\n/**\n * The central sign-in page (docs/design-system.md, section 16.3): one card that hands the user off\n * to RB Labs Auth. Apps that sign in through Auth place it alone in `rb-public-shell`; it renders\n * the page's single `<h1>`, collects no credentials and emits `signIn` for the app to start the\n * handoff with its own return path.\n */\n@Component({\n selector: 'rb-central-sign-in',\n imports: [MatButton, MatIcon, RbMessageComponent, RbMonogramComponent, RouterLink],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-central-sign-in',\n // `title` is an input; a static `title=\"…\"` would also leave a native tooltip on the host.\n '[attr.title]': 'null',\n },\n template: `\n <section class=\"rb-central-sign-in__card\" [attr.aria-labelledby]=\"titleId\">\n <div class=\"rb-central-sign-in__intro\">\n <span class=\"rb-central-sign-in__icon\" aria-hidden=\"true\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{ icon() }}</mat-icon>\n </span>\n @if (eyebrow()) {\n <p class=\"rb-central-sign-in__eyebrow\">{{ eyebrow() }}</p>\n }\n <h1 class=\"rb-central-sign-in__title\" [id]=\"titleId\">{{ resolvedTitle() }}</h1>\n <p class=\"rb-central-sign-in__description\">{{ resolvedDescription() }}</p>\n </div>\n\n <div class=\"rb-central-sign-in__provider\">\n <rb-monogram class=\"rb-central-sign-in__mark\" />\n <span class=\"rb-central-sign-in__provider-name\">\n <strong>RB Labs Auth</strong>\n <code>{{ authHost() }}</code>\n </span>\n </div>\n\n @if (error()) {\n <rb-message tone=\"danger\">\n <p>{{ error() }}</p>\n </rb-message>\n }\n\n <div class=\"rb-central-sign-in__actions\">\n <button\n class=\"rb-central-sign-in__continue\"\n matButton=\"filled\"\n type=\"button\"\n (click)=\"signIn.emit()\"\n >\n Continue to RB Labs Auth\n <mat-icon fontSet=\"material-symbols-outlined\" aria-hidden=\"true\" iconPositionEnd\n >arrow_forward</mat-icon\n >\n </button>\n <a class=\"rb-central-sign-in__back\" matButton=\"outlined\" [routerLink]=\"backLink()\"\n >Back to home</a\n >\n </div>\n\n @if (note()) {\n <p class=\"rb-central-sign-in__note\">{{ note() }}</p>\n }\n </section>\n `,\n styleUrl: './central-sign-in.scss',\n})\nexport class RbCentralSignInComponent {\n /** The app the user signs in to: `Admin`, `Rover`, `Photogrammetry`… */\n readonly appName = input.required<string>();\n /** Overrides the default title, `Sign in to RB Labs <appName>`. */\n readonly title = input<string>('');\n /** Short context above the title, such as the workspace the page protects. */\n readonly eyebrow = input<string>('');\n /** Overrides the default sentence about where the user is sent. */\n readonly description = input<string>('');\n /** Material Symbols name of the app's icon in the card header. */\n readonly icon = input<string>('login');\n /** Host shown in the identity row. */\n readonly authHost = input<string>('auth.rblabs.dev');\n /** Optional closing note, such as who may enter the app. */\n readonly note = input<string>('');\n /** A safe, non-disclosing message for the failure the app was sent back with. */\n readonly error = input<string | null>(null);\n /** The \"Back to home\" target, as a `routerLink` value. */\n readonly backLink = input<string | readonly unknown[]>('/');\n\n /** The primary action: the app starts the Auth handoff with its return path. */\n readonly signIn = output<void>();\n\n protected readonly titleId = `rb-central-sign-in-title-${nextId++}`;\n\n protected readonly resolvedTitle = computed(\n () => this.title() || `Sign in to RB Labs ${this.appName()}`,\n );\n protected readonly resolvedDescription = computed(\n () =>\n this.description() ||\n `You will be taken to RB Labs Auth to sign in, then returned to ${this.appName()}.`,\n );\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n input,\n viewChild,\n} from '@angular/core';\n\nimport { RbBrandLockupComponent } from '../../brand/brand-lockup/brand-lockup';\nimport { RbThemeToggleComponent } from '../../theme/theme-toggle';\nimport { RbShellFooterComponent } from '../shell-footer/shell-footer';\n\n/**\n * Frame for landing, sign-in and other public pages (docs/design-system.md, section 16.2): skip\n * link, a header with the brand lockup and theme toggle, a centered content area on the brand\n * background, and the standard footer.\n */\n@Component({\n selector: 'rb-public-shell',\n imports: [RbBrandLockupComponent, RbShellFooterComponent, RbThemeToggleComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'rb-public-shell' },\n template: `\n <a class=\"rb-skip-link\" href=\"#main-content\" (click)=\"skipToMain($event)\"\n >Skip to main content</a\n >\n\n <header class=\"rb-public-shell__header\">\n <rb-brand-lockup [appName]=\"appName()\" [link]=\"homeLink()\" />\n <div class=\"rb-public-shell__actions\">\n <ng-content select=\"[rbShellActions]\" />\n <rb-theme-toggle />\n </div>\n </header>\n\n <main #main class=\"rb-public-shell__main\" id=\"main-content\" tabindex=\"-1\">\n <ng-content />\n </main>\n\n <rb-shell-footer [appName]=\"appName()\"><ng-content select=\"[rbShellFooter]\" /></rb-shell-footer>\n `,\n styleUrl: './public-shell.scss',\n})\nexport class RbPublicShellComponent {\n /** Shown in the lockup and the footer: `Admin`, `Auth`, `Rover`, `Photogrammetry`… */\n readonly appName = input.required<string>();\n /** The lockup's link target, as a `routerLink` value. */\n readonly homeLink = input<string | readonly unknown[]>('/');\n\n private readonly main = viewChild.required<ElementRef<HTMLElement>>('main');\n\n /** See RbAppShellComponent: keeps the skip link on the current route. */\n protected skipToMain(event: Event): void {\n event.preventDefault();\n this.main().nativeElement.focus();\n }\n}\n","/**\n * Kit version. The build stamps it from projects/axiom/package.json (scripts/stamp-version.mjs);\n * source and development builds show the placeholder.\n */\nexport const RB_DESIGN_SYSTEM_VERSION: string = '1.2.1';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rblabs-dev-axiom.mjs","names":[],"sources":["../../../projects/axiom/src/lib/brand/monogram/monogram.ts","../../../projects/axiom/src/lib/brand/brand-lockup/brand-lockup.ts","../../../projects/axiom/src/lib/breakpoints.ts","../../../projects/axiom/src/lib/components/confirm-dialog/confirm-dialog.ts","../../../projects/axiom/src/lib/components/confirm-dialog/confirm-dialog.service.ts","../../../projects/axiom/src/lib/components/empty-state/empty-state.ts","../../../projects/axiom/src/lib/components/tones.ts","../../../projects/axiom/src/lib/components/message/message.ts","../../../projects/axiom/src/lib/components/page-header/page-header.ts","../../../projects/axiom/src/lib/components/panel/panel.ts","../../../projects/axiom/src/lib/components/status-chip/status-chip.ts","../../../projects/axiom/src/lib/components/technical-value/technical-value.ts","../../../projects/axiom/src/lib/theme/theme.service.ts","../../../projects/axiom/src/lib/provide-design-system.ts","../../../projects/axiom/src/lib/theme/theme-toggle.ts","../../../projects/axiom/src/lib/shell/shell-footer/shell-footer.ts","../../../projects/axiom/src/lib/shell/app-shell/app-shell.ts","../../../projects/axiom/src/lib/shell/central-sign-in/central-sign-in.ts","../../../projects/axiom/src/lib/shell/public-shell/public-shell.ts","../../../projects/axiom/src/lib/version.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core';\n\nlet nextId = 0;\n\n/**\n * The RB monogram (docs/design-system.md, section 12.1), drawn inline from the brand tokens so it\n * needs no request and is identical in both themes. Decorative: the element that contains it (the\n * brand lockup link) carries the accessible name. Size it with `inline-size` on the host.\n */\n@Component({\n selector: 'rb-monogram',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'rb-monogram', 'aria-hidden': 'true' },\n template: `\n <svg class=\"rb-monogram__svg\" viewBox=\"0 0 64 64\" focusable=\"false\">\n <defs>\n <linearGradient\n [attr.id]=\"gradientId\"\n x1=\"8\"\n y1=\"8\"\n x2=\"56\"\n y2=\"56\"\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop class=\"rb-monogram__gradient-start\" />\n <stop class=\"rb-monogram__gradient-end\" offset=\"1\" />\n </linearGradient>\n </defs>\n <rect class=\"rb-monogram__frame\" width=\"64\" height=\"64\" rx=\"16\" />\n <rect x=\"5\" y=\"5\" width=\"54\" height=\"54\" rx=\"14\" [attr.fill]=\"'url(#' + gradientId + ')'\" />\n <g class=\"rb-monogram__letters\">\n <path d=\"M17 47V17h7.3c4.9 0 7.8 2.7 7.8 6.9s-2.9 6.8-7.8 6.8H17M24.3 30.7 34.5 47\" />\n <path\n d=\"M40 17v30M40 17h6.8c4.4 0 7.1 2.6 7.1 6.2s-2.7 5.9-7.1 5.9H40M40 29.1h7.5c4.7 0 7.7 3.2 7.7 7.1s-3 7.8-7.7 7.8H40\"\n />\n </g>\n </svg>\n `,\n styleUrl: './monogram.scss',\n})\nexport class RbMonogramComponent {\n /** Unique per instance: several monograms can share a page. */\n protected readonly gradientId = `rb-monogram-gradient-${nextId++}`;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n} from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nimport { RbMonogramComponent } from '../monogram/monogram';\n\n/** `true` shows only the monogram; `'below-sm'` does so only below the `sm` breakpoint. */\nexport type RbBrandLockupCompact = boolean | 'below-sm';\n\n/**\n * The RB monogram followed by \"RB Labs · <App name>\", as a link to the app's home\n * (docs/design-system.md, section 12.2). The accessible name stays \"RB Labs <App name> home\" in\n * every variant.\n */\n@Component({\n selector: 'rb-brand-lockup',\n imports: [RbMonogramComponent, RouterLink],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-brand-lockup',\n '[attr.data-compact]': 'compactAttribute()',\n },\n template: `\n <a class=\"rb-brand-lockup__link\" [routerLink]=\"link()\" [attr.aria-label]=\"accessibleName()\">\n <rb-monogram class=\"rb-brand-lockup__mark\" />\n <span class=\"rb-brand-lockup__wordmark\">\n <span class=\"rb-brand-lockup__brand\">RB Labs</span>\n <span class=\"rb-brand-lockup__app\"><span aria-hidden=\"true\">·</span> {{ appName() }}</span>\n </span>\n </a>\n `,\n styleUrl: './brand-lockup.scss',\n})\nexport class RbBrandLockupComponent {\n /** `Admin`, `Auth`, `Rover`, `Photogrammetry` or a new app's name. */\n readonly appName = input.required<string>();\n /** The app's home, as a `routerLink` value. */\n readonly link = input<string | readonly unknown[]>('/');\n readonly compact = input<RbBrandLockupCompact, RbBrandLockupCompact | ''>(false, {\n transform: (value) => (value === '' ? true : value),\n });\n\n protected readonly accessibleName = computed(() => `RB Labs ${this.appName()} home`);\n protected readonly compactAttribute = computed(() => {\n const compact = this.compact();\n return compact === true ? 'always' : compact || null;\n });\n}\n","/** Breakpoint widths (docs/design-system.md, section 8). Mirrors `$breakpoints` in _breakpoints.scss. */\nexport const RB_BREAKPOINT_WIDTHS = {\n xs: '30rem',\n sm: '40rem',\n md: '48rem',\n lg: '60rem',\n xl: '75rem',\n '2xl': '87.5rem',\n} as const;\n\nexport type RbBreakpoint = keyof typeof RB_BREAKPOINT_WIDTHS;\n\n/** Media queries for the CDK `BreakpointObserver`, e.g. `observe(RB_BREAKPOINTS.belowLg)`. */\nexport const RB_BREAKPOINTS = {\n belowXs: '(width < 30rem)',\n belowSm: '(width < 40rem)',\n belowMd: '(width < 48rem)',\n belowLg: '(width < 60rem)',\n belowXl: '(width < 75rem)',\n below2xl: '(width < 87.5rem)',\n aboveXs: '(width >= 30rem)',\n aboveSm: '(width >= 40rem)',\n aboveMd: '(width >= 48rem)',\n aboveLg: '(width >= 60rem)',\n aboveXl: '(width >= 75rem)',\n above2xl: '(width >= 87.5rem)',\n} as const;\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n inject,\n signal,\n viewChild,\n} from '@angular/core';\nimport { FormControl, ReactiveFormsModule, ValidatorFn } from '@angular/forms';\nimport { MatButton } from '@angular/material/button';\nimport {\n MAT_DIALOG_DATA,\n MatDialogActions,\n MatDialogContent,\n MatDialogRef,\n MatDialogTitle,\n} from '@angular/material/dialog';\nimport { MatIcon } from '@angular/material/icon';\n\nexport type RbConfirmDialogTone = 'primary' | 'danger';\n\nexport interface RbConfirmDialogReason {\n /** Visible label of the reason field. Defaults to \"Reason\". */\n label?: string;\n /** Helper text under the field. */\n hint?: string;\n /** Minimum length of the trimmed reason. Defaults to 3. */\n minimumLength?: number;\n}\n\nexport interface RbConfirmDialogData {\n title: string;\n description: string;\n confirmLabel: string;\n /** Defaults to \"Cancel\". */\n cancelLabel?: string;\n /** `danger` is for destructive or irreversible actions. Defaults to `primary`. */\n tone?: RbConfirmDialogTone;\n /** Asks for a required reason, returned trimmed in the result. */\n reason?: RbConfirmDialogReason;\n}\n\nexport interface RbConfirmDialogResult {\n confirmed: boolean;\n reason?: string;\n}\n\n/** Data the service adds so the dialog container can reference the description. */\nexport interface RbConfirmDialogInternalData extends RbConfirmDialogData {\n descriptionId?: string;\n}\n\nlet nextId = 0;\n\n/** Generates the ids shared by the service (dialog config) and the dialog content. */\nexport function rbConfirmDialogId(): string {\n return `rb-confirm-dialog-${nextId++}`;\n}\n\n/**\n * Confirmation content opened by `RbConfirmDialogService` (docs/design-system.md, section 15.7).\n * Use the service rather than opening this component directly.\n */\n@Component({\n selector: 'rb-confirm-dialog',\n imports: [\n MatButton,\n MatDialogActions,\n MatDialogContent,\n MatDialogTitle,\n MatIcon,\n ReactiveFormsModule,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-confirm-dialog',\n '[attr.data-tone]': 'tone',\n },\n template: `\n <div class=\"rb-confirm-dialog__layout\">\n <span class=\"rb-confirm-dialog__icon\" aria-hidden=\"true\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{\n tone === 'danger' ? 'warning' : 'help'\n }}</mat-icon>\n </span>\n <div class=\"rb-confirm-dialog__body\">\n <h2 mat-dialog-title class=\"rb-confirm-dialog__title\">{{ data.title }}</h2>\n <mat-dialog-content class=\"rb-confirm-dialog__content\">\n <p class=\"rb-confirm-dialog__description\" [id]=\"descriptionId\">{{ data.description }}</p>\n @if (data.reason) {\n <div class=\"rb-field\" [class.rb-field--invalid]=\"showReasonError()\">\n <label class=\"rb-field__label\" [for]=\"reasonId\">{{\n data.reason.label ?? 'Reason'\n }}</label>\n <input\n #reasonInput\n class=\"rb-field__control\"\n type=\"text\"\n autocomplete=\"off\"\n [id]=\"reasonId\"\n [formControl]=\"reason\"\n [attr.aria-invalid]=\"showReasonError() ? 'true' : null\"\n [attr.aria-describedby]=\"reasonDescribedBy()\"\n />\n @if (data.reason.hint) {\n <p class=\"rb-field__hint\" [id]=\"reasonId + '-hint'\">{{ data.reason.hint }}</p>\n }\n @if (showReasonError()) {\n <p class=\"rb-field__error\" [id]=\"reasonId + '-error'\">\n Enter at least {{ minimumReasonLength }} characters.\n </p>\n }\n </div>\n }\n </mat-dialog-content>\n </div>\n </div>\n <mat-dialog-actions align=\"end\" class=\"rb-confirm-dialog__actions\">\n <button matButton type=\"button\" (click)=\"cancel()\">{{ data.cancelLabel ?? 'Cancel' }}</button>\n <button\n matButton=\"filled\"\n type=\"button\"\n [color]=\"tone === 'danger' ? 'warn' : 'primary'\"\n (click)=\"confirm()\"\n >\n {{ data.confirmLabel }}\n </button>\n </mat-dialog-actions>\n `,\n styleUrl: './confirm-dialog.scss',\n})\nexport class RbConfirmDialogComponent {\n protected readonly data = inject<RbConfirmDialogInternalData>(MAT_DIALOG_DATA);\n private readonly dialogRef =\n inject<MatDialogRef<RbConfirmDialogComponent, RbConfirmDialogResult>>(MatDialogRef);\n private readonly reasonInput = viewChild<ElementRef<HTMLInputElement>>('reasonInput');\n\n private readonly id = rbConfirmDialogId();\n protected readonly descriptionId = this.data.descriptionId ?? `${this.id}-description`;\n protected readonly reasonId = `${this.id}-reason`;\n protected readonly tone: RbConfirmDialogTone = this.data.tone ?? 'primary';\n protected readonly minimumReasonLength = this.data.reason?.minimumLength ?? 3;\n\n private readonly trimmedMinLength: ValidatorFn = (control) =>\n String(control.value).trim().length >= this.minimumReasonLength\n ? null\n : { trimmedMinLength: true };\n\n protected readonly reason = new FormControl('', {\n nonNullable: true,\n validators: this.data.reason ? [this.trimmedMinLength] : [],\n });\n\n private readonly submitted = signal(false);\n\n protected showReasonError(): boolean {\n return this.submitted() && this.reason.invalid;\n }\n\n protected reasonDescribedBy(): string | null {\n const ids = [\n this.data.reason?.hint ? `${this.reasonId}-hint` : null,\n this.showReasonError() ? `${this.reasonId}-error` : null,\n ].filter((value): value is string => value !== null);\n return ids.length > 0 ? ids.join(' ') : null;\n }\n\n cancel(): void {\n this.dialogRef.close({ confirmed: false });\n }\n\n confirm(): void {\n if (this.data.reason) {\n this.submitted.set(true);\n if (this.reason.invalid) {\n // Focus returns to the field, which now announces its error through aria-describedby.\n this.reasonInput()?.nativeElement.focus();\n return;\n }\n }\n\n this.dialogRef.close({\n confirmed: true,\n ...(this.data.reason ? { reason: this.reason.value.trim() } : {}),\n });\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { MatDialog } from '@angular/material/dialog';\nimport { firstValueFrom } from 'rxjs';\n\nimport {\n RbConfirmDialogComponent,\n RbConfirmDialogData,\n RbConfirmDialogInternalData,\n RbConfirmDialogResult,\n rbConfirmDialogId,\n} from './confirm-dialog';\n\n/**\n * Asks the user to confirm an action (docs/design-system.md, section 15.7):\n *\n * ```ts\n * const { confirmed, reason } = await confirmDialog.confirm({\n * title: 'Revoke credential?',\n * description: 'Clients using it stop working immediately.',\n * confirmLabel: 'Revoke credential',\n * tone: 'danger',\n * reason: { label: 'Reason for revoking' },\n * });\n * ```\n *\n * Closing the dialog in any other way (Cancel, Escape, the backdrop) resolves `confirmed: false`.\n */\n@Injectable({ providedIn: 'root' })\nexport class RbConfirmDialogService {\n private readonly dialog = inject(MatDialog);\n\n async confirm(data: RbConfirmDialogData): Promise<RbConfirmDialogResult> {\n const descriptionId = `${rbConfirmDialogId()}-description`;\n const dialogRef = this.dialog.open<\n RbConfirmDialogComponent,\n RbConfirmDialogInternalData,\n RbConfirmDialogResult\n >(RbConfirmDialogComponent, {\n data: { ...data, descriptionId },\n // A destructive confirmation interrupts the task, so it is announced as an alert dialog.\n role: data.tone === 'danger' ? 'alertdialog' : 'dialog',\n ariaDescribedBy: descriptionId,\n // The reason field when there is one, otherwise Cancel: never the destructive button.\n autoFocus: 'first-tabbable',\n restoreFocus: true,\n width: 'min(var(--rb-size-card-wide), calc(100vw - 2 * var(--rb-space-4)))',\n maxWidth: '100vw',\n // `rb-scope` gives the pane the kit's tokens while the kit is applied scoped (14).\n panelClass: ['rb-confirm-dialog-panel', 'rb-scope'],\n });\n\n return (await firstValueFrom(dialogRef.afterClosed())) ?? { confirmed: false };\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n input,\n output,\n} from '@angular/core';\nimport { MatButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\n\nimport { RbHeadingLevel } from '../panel/panel';\n\nexport type RbEmptyStateLayout = 'centered' | 'inline';\n\n/**\n * Explains why a region has no content and, when there is one, offers the next step\n * (docs/design-system.md, section 15.4). `actionLabel` renders an outlined button that emits\n * `action`; elements marked `rbActions` are projected next to it, for links or several actions.\n */\n@Component({\n selector: 'rb-empty-state',\n imports: [MatButton, MatIcon],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-empty-state',\n // `title` is an input; a static `title=\"…\"` would also leave a native tooltip on the host.\n '[attr.title]': 'null',\n '[attr.data-layout]': 'layout()',\n },\n template: `\n <mat-icon class=\"rb-empty-state__icon\" fontSet=\"material-symbols-outlined\" aria-hidden=\"true\">{{\n icon()\n }}</mat-icon>\n <div class=\"rb-empty-state__copy\">\n @switch (headingLevel()) {\n @case (2) {\n <h2 class=\"rb-empty-state__title\">{{ title() }}</h2>\n }\n @case (4) {\n <h4 class=\"rb-empty-state__title\">{{ title() }}</h4>\n }\n @case (5) {\n <h5 class=\"rb-empty-state__title\">{{ title() }}</h5>\n }\n @case (6) {\n <h6 class=\"rb-empty-state__title\">{{ title() }}</h6>\n }\n @default {\n <h3 class=\"rb-empty-state__title\">{{ title() }}</h3>\n }\n }\n @if (description()) {\n <p class=\"rb-empty-state__description\">{{ description() }}</p>\n }\n <div class=\"rb-empty-state__actions\">\n @if (actionLabel()) {\n <button matButton=\"outlined\" type=\"button\" (click)=\"action.emit()\">\n {{ actionLabel() }}\n </button>\n }\n <ng-content select=\"[rbActions]\" />\n </div>\n </div>\n `,\n styleUrl: './empty-state.scss',\n})\nexport class RbEmptyStateComponent {\n readonly title = input.required<string>();\n readonly description = input<string>('');\n readonly icon = input<string>('inbox');\n /** Heading level of the title; follows the document outline, not the visual size. */\n readonly headingLevel = input<RbHeadingLevel>(3);\n /** `inline` is the compact variant for sidebars and narrow panels. */\n readonly layout = input<RbEmptyStateLayout>('centered');\n /** Label of the recovery button; leave empty for a purely informational state. */\n readonly actionLabel = input<string>('');\n readonly action = output<void>();\n}\n","/** Tones of `rb-message` (docs/design-system.md, section 15.3). */\nexport type RbMessageTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';\n\n/** Tones of `rb-status-chip` and page header metrics (15.1, 15.5). `active` means in progress. */\nexport type RbStatusTone = 'neutral' | 'active' | 'success' | 'warning' | 'danger';\n\n/**\n * Default icon per tone, so state is never carried by color alone (section 9.4). Neutral status\n * chips and metrics have no default icon: their label is the whole message.\n */\nexport const RB_TONE_ICONS: Readonly<Record<RbMessageTone | RbStatusTone, string | null>> = {\n neutral: null,\n info: 'info',\n active: 'autorenew',\n success: 'check_circle',\n warning: 'warning',\n danger: 'error',\n};\n\n/** Visually hidden prefix that names a message's tone for screen reader users. */\nexport const RB_MESSAGE_TONE_LABELS: Readonly<Record<RbMessageTone, string | null>> = {\n neutral: null,\n info: 'Information',\n success: 'Success',\n warning: 'Warning',\n danger: 'Error',\n};\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n} from '@angular/core';\nimport { MatIcon } from '@angular/material/icon';\n\nimport { RB_MESSAGE_TONE_LABELS, RB_TONE_ICONS, RbMessageTone } from '../tones';\n\n/**\n * How the message is announced. `auto` makes a danger message an assertive alert and every other\n * tone a polite status; `off` renders a static message with no live region.\n */\nexport type RbMessageLive = 'auto' | 'polite' | 'assertive' | 'off';\n\n/**\n * Inline status message (docs/design-system.md, section 15.3). The host is the live region, so keep\n * the component mounted and change its content: a region inserted together with its text is not\n * announced by most screen readers (section 9.5).\n */\n@Component({\n selector: 'rb-message',\n imports: [MatIcon],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-message',\n // `title` is an input; a static `title=\"…\"` would also leave a native tooltip on the host.\n '[attr.title]': 'null',\n '[attr.data-tone]': 'tone()',\n '[attr.role]': 'role()',\n '[attr.aria-live]': 'ariaLive()',\n },\n template: `\n <mat-icon class=\"rb-message__icon\" fontSet=\"material-symbols-outlined\" aria-hidden=\"true\">{{\n resolvedIcon()\n }}</mat-icon>\n <div class=\"rb-message__copy\">\n @if (title()) {\n <p class=\"rb-message__title\">\n @if (toneLabel()) {\n <span class=\"rb-visually-hidden\">{{ toneLabel() }}: </span>\n }\n {{ title() }}\n </p>\n } @else if (toneLabel()) {\n <span class=\"rb-visually-hidden\">{{ toneLabel() }}: </span>\n }\n <div class=\"rb-message__body\"><ng-content /></div>\n </div>\n `,\n styleUrl: './message.scss',\n})\nexport class RbMessageComponent {\n readonly tone = input<RbMessageTone>('neutral');\n /** Optional bold first line. */\n readonly title = input<string>('');\n /** Overrides the tone's default icon. */\n readonly icon = input<string>('');\n readonly live = input<RbMessageLive>('auto');\n\n protected readonly resolvedIcon = computed(\n () => this.icon() || RB_TONE_ICONS[this.tone()] || 'info',\n );\n protected readonly toneLabel = computed(() => RB_MESSAGE_TONE_LABELS[this.tone()]);\n\n private readonly politeness = computed(() => {\n const live = this.live();\n if (live !== 'auto') return live;\n return this.tone() === 'danger' ? 'assertive' : 'polite';\n });\n\n protected readonly role = computed(() => {\n const politeness = this.politeness();\n if (politeness === 'off') return null;\n return politeness === 'assertive' ? 'alert' : 'status';\n });\n\n protected readonly ariaLive = computed(() => {\n const politeness = this.politeness();\n return politeness === 'off' ? null : politeness;\n });\n}\n","import { ChangeDetectionStrategy, Component, ViewEncapsulation, input } from '@angular/core';\nimport { MatIcon } from '@angular/material/icon';\n\nimport { RB_TONE_ICONS, RbStatusTone } from '../tones';\n\nexport interface RbPageHeaderMetric {\n label: string;\n value: string | number;\n /** Adds a tone color and icon to the value; the label and value carry the meaning. */\n tone?: RbStatusTone;\n}\n\n/**\n * The page's single `<h1>` with its eyebrow, description, summary metrics and page actions\n * (docs/design-system.md, section 15.1). Elements marked `rbActions` are projected next to the\n * title.\n */\n@Component({\n selector: 'rb-page-header',\n imports: [MatIcon],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-page-header',\n // `title` is an input; a static `title=\"…\"` would also leave a native tooltip on the host.\n '[attr.title]': 'null',\n },\n template: `\n <header class=\"rb-page-header__main\">\n <div class=\"rb-page-header__copy\">\n @if (eyebrow()) {\n <p class=\"rb-page-header__eyebrow\">{{ eyebrow() }}</p>\n }\n <h1 class=\"rb-page-header__title\">{{ title() }}</h1>\n @if (description()) {\n <p class=\"rb-page-header__description\">{{ description() }}</p>\n }\n </div>\n <div class=\"rb-page-header__actions\"><ng-content select=\"[rbActions]\" /></div>\n </header>\n @if (metrics().length > 0) {\n <dl class=\"rb-page-header__metrics\">\n @for (metric of metrics(); track metric.label) {\n <div class=\"rb-page-header__metric\" [attr.data-tone]=\"metric.tone ?? 'neutral'\">\n <dt class=\"rb-page-header__metric-label\">{{ metric.label }}</dt>\n <dd class=\"rb-page-header__metric-value\">\n @if (toneIcon(metric); as icon) {\n <mat-icon fontSet=\"material-symbols-outlined\" aria-hidden=\"true\">{{\n icon\n }}</mat-icon>\n }\n <span>{{ metric.value }}</span>\n </dd>\n </div>\n }\n </dl>\n }\n `,\n styleUrl: './page-header.scss',\n})\nexport class RbPageHeaderComponent {\n readonly title = input.required<string>();\n /** Short context line above the title, such as the app area. */\n readonly eyebrow = input<string>('');\n readonly description = input<string>('');\n readonly metrics = input<readonly RbPageHeaderMetric[]>([]);\n\n protected toneIcon(metric: RbPageHeaderMetric): string | null {\n return RB_TONE_ICONS[metric.tone ?? 'neutral'];\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n booleanAttribute,\n input,\n} from '@angular/core';\n\nexport type RbPanelVariant = 'default' | 'soft' | 'elevated' | 'danger';\nexport type RbHeadingLevel = 2 | 3 | 4 | 5 | 6;\n\n/**\n * Content container with an optional header (docs/design-system.md, section 15.2). Elements marked\n * `rbActions` are projected into the header next to the title.\n */\n@Component({\n selector: 'rb-panel',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-panel',\n // `title` is an input; a static `title=\"…\"` would also leave a native tooltip on the host.\n '[attr.title]': 'null',\n '[attr.data-variant]': 'variant()',\n '[attr.data-flush]': 'flush() ? \"\" : null',\n },\n template: `\n @if (title() || description()) {\n <header class=\"rb-panel__header\">\n <div class=\"rb-panel__heading\">\n @if (title()) {\n @switch (headingLevel()) {\n @case (3) {\n <h3 class=\"rb-panel__title\">{{ title() }}</h3>\n }\n @case (4) {\n <h4 class=\"rb-panel__title\">{{ title() }}</h4>\n }\n @case (5) {\n <h5 class=\"rb-panel__title\">{{ title() }}</h5>\n }\n @case (6) {\n <h6 class=\"rb-panel__title\">{{ title() }}</h6>\n }\n @default {\n <h2 class=\"rb-panel__title\">{{ title() }}</h2>\n }\n }\n }\n @if (description()) {\n <p class=\"rb-panel__description\">{{ description() }}</p>\n }\n </div>\n <div class=\"rb-panel__actions\"><ng-content select=\"[rbActions]\" /></div>\n </header>\n }\n <div class=\"rb-panel__body\"><ng-content /></div>\n `,\n styleUrl: './panel.scss',\n})\nexport class RbPanelComponent {\n readonly title = input<string>('');\n readonly description = input<string>('');\n readonly variant = input<RbPanelVariant>('default');\n /** Heading level of the title; follows the document outline, not the visual size. */\n readonly headingLevel = input<RbHeadingLevel>(2);\n /** Removes the body padding, for a table or list that runs to the panel's edges. */\n readonly flush = input(false, { transform: booleanAttribute });\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n} from '@angular/core';\nimport { MatIcon } from '@angular/material/icon';\n\nimport { RB_TONE_ICONS, RbStatusTone } from '../tones';\n\nexport type RbStatusChipSize = 'default' | 'compact';\n\n/**\n * Read-only status label (docs/design-system.md, section 15.5). The label is always visible and\n * every non-neutral tone has an icon, so the state is never carried by color alone. It is not\n * interactive and not a live region: announce changes through `rb-message` or a status region.\n */\n@Component({\n selector: 'rb-status-chip',\n imports: [MatIcon],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-status-chip',\n '[attr.data-tone]': 'tone()',\n '[attr.data-size]': 'size()',\n },\n template: `\n @if (resolvedIcon(); as icon) {\n <mat-icon\n class=\"rb-status-chip__icon\"\n fontSet=\"material-symbols-outlined\"\n aria-hidden=\"true\"\n >{{ icon }}</mat-icon\n >\n }\n <span class=\"rb-status-chip__label\">{{ label() }}</span>\n `,\n styleUrl: './status-chip.scss',\n})\nexport class RbStatusChipComponent {\n readonly label = input.required<string>();\n readonly tone = input<RbStatusTone>('neutral');\n /** Overrides the tone's default icon. */\n readonly icon = input<string>('');\n /** `compact` fits a single table row line. */\n readonly size = input<RbStatusChipSize>('default');\n\n protected readonly resolvedIcon = computed(() => this.icon() || RB_TONE_ICONS[this.tone()]);\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n ViewEncapsulation,\n afterNextRender,\n afterRenderEffect,\n computed,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { MatTooltip } from '@angular/material/tooltip';\n\n/**\n * Identifier, key, hash or path in monospace on one line (docs/design-system.md, section 15.6).\n * A value that does not fit is truncated with an ellipsis and the full value appears in a tooltip.\n * Screen readers and copying always get the full value, even when `displayValue` shortens it.\n */\n@Component({\n selector: 'rb-technical-value',\n imports: [MatTooltip],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-technical-value',\n '(copy)': 'copyFullValue($event)',\n },\n template: `\n <span\n #text\n class=\"rb-technical-value__text\"\n [matTooltip]=\"value()\"\n [matTooltipDisabled]=\"!tooltipEnabled()\"\n [attr.aria-hidden]=\"shortened() ? 'true' : null\"\n >{{ shownValue() }}</span\n >\n @if (shortened()) {\n <span class=\"rb-visually-hidden\">{{ value() }}</span>\n }\n `,\n styleUrl: './technical-value.scss',\n})\nexport class RbTechnicalValueComponent {\n readonly value = input.required<string>();\n /** Shorter text to show instead of the value, such as the first characters of a hash. */\n readonly displayValue = input<string>('');\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n private readonly text = viewChild.required<ElementRef<HTMLElement>>('text');\n private readonly truncated = signal(false);\n\n protected readonly shownValue = computed(() => this.displayValue() || this.value());\n protected readonly shortened = computed(() => this.shownValue() !== this.value());\n protected readonly tooltipEnabled = computed(\n () => this.value() !== '' && (this.shortened() || this.truncated()),\n );\n\n constructor() {\n // Re-measured whenever the text changes and whenever the element is resized.\n afterRenderEffect({\n read: () => {\n this.shownValue();\n this.measure();\n },\n });\n\n afterNextRender(() => {\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => this.measure());\n observer.observe(this.text().nativeElement);\n this.destroyRef.onDestroy(() => observer.disconnect());\n });\n }\n\n /** Copying a selection inside the component copies the full value, not the shortened text. */\n protected copyFullValue(event: ClipboardEvent): void {\n if (!this.shortened() || !event.clipboardData) return;\n const selection = this.host.nativeElement.ownerDocument.getSelection();\n const host = this.host.nativeElement;\n if (!selection || !host.contains(selection.anchorNode) || !host.contains(selection.focusNode))\n return;\n event.clipboardData.setData('text/plain', this.value());\n event.preventDefault();\n }\n\n private measure(): void {\n const element = this.text().nativeElement;\n this.truncated.set(element.scrollWidth > element.clientWidth);\n }\n}\n","import { DOCUMENT } from '@angular/common';\nimport { DestroyRef, Injectable, InjectionToken, computed, inject, signal } from '@angular/core';\n\nexport type RbTheme = 'light' | 'dark';\n\n/** localStorage key holding the user's explicit choice (docs/design-system.md, section 11). */\nexport const RB_THEME_STORAGE_KEY = 'rb-theme';\n\n/** `--rb-color-bg` per theme; also the `<meta name=\"theme-color\">` value. */\nexport const RB_THEME_COLORS: Readonly<Record<RbTheme, string>> = {\n light: '#f4f7fb',\n dark: '#08111d',\n};\n\nexport interface RbThemeOptions {\n /**\n * Forces a theme regardless of the stored choice and the OS, without persisting anything. Used by\n * apps that only support one theme until their migration is done. The theme toggle hides itself\n * while a theme is forced.\n */\n forcedTheme?: RbTheme | null;\n /** Storage keys an app used before adopting the kit; a valid value is moved to `rb-theme` once. */\n legacyStorageKeys?: readonly string[];\n}\n\nexport const RB_THEME_OPTIONS = new InjectionToken<RbThemeOptions>('RB_THEME_OPTIONS', {\n providedIn: 'root',\n factory: () => ({}),\n});\n\nconst DARK_SCHEME_QUERY = '(prefers-color-scheme: dark)';\n\nfunction isTheme(value: unknown): value is RbTheme {\n return value === 'light' || value === 'dark';\n}\n\n/**\n * Owns the light/dark theme contract (docs/design-system.md, section 11):\n *\n * - an explicit choice is stored under `rb-theme` and wins over the OS;\n * - without one, the theme follows `prefers-color-scheme` and tracks OS changes live;\n * - the resolved theme is written to `<html>` as `data-theme`, and every\n * `<meta name=\"theme-color\">` is kept in sync;\n * - `color-scheme` is only set inline for an explicit or forced theme; otherwise the stylesheet's\n * `color-scheme: light dark` already follows the OS before any script runs.\n *\n * `provideRbDesignSystem()` calls `initialize()` from an app initializer, before first paint.\n */\n@Injectable({ providedIn: 'root' })\nexport class ThemeService {\n private readonly document = inject(DOCUMENT);\n private readonly options = inject(RB_THEME_OPTIONS);\n private readonly window = this.document.defaultView;\n private readonly darkScheme = this.window?.matchMedia?.(DARK_SCHEME_QUERY) ?? null;\n\n private readonly systemTheme = signal<RbTheme>(this.darkScheme?.matches ? 'dark' : 'light');\n private readonly storedTheme = signal<RbTheme | null>(null);\n private readonly forcedTheme = signal<RbTheme | null>(this.options.forcedTheme ?? null);\n private initialized = false;\n\n /** The user's explicit choice, or `null` while the theme follows the OS. */\n readonly preference = this.storedTheme.asReadonly();\n /** The theme in effect: forced, then stored, then the OS preference. */\n readonly theme = computed<RbTheme>(\n () => this.forcedTheme() ?? this.storedTheme() ?? this.systemTheme(),\n );\n readonly isDark = computed(() => this.theme() === 'dark');\n /** True while a theme is forced; the toggle is hidden then. */\n readonly isForced = computed(() => this.forcedTheme() !== null);\n\n constructor() {\n const onSystemChange = (event: MediaQueryListEvent): void => {\n this.systemTheme.set(event.matches ? 'dark' : 'light');\n this.apply();\n };\n this.darkScheme?.addEventListener('change', onSystemChange);\n inject(DestroyRef).onDestroy(() =>\n this.darkScheme?.removeEventListener('change', onSystemChange),\n );\n }\n\n /** Reads the stored choice and applies the theme to the document. Safe to call more than once. */\n initialize(): void {\n if (!this.initialized) {\n this.initialized = true;\n this.storedTheme.set(this.readStoredTheme());\n }\n this.apply();\n }\n\n /** Switches between light and dark and stores the result as an explicit choice. */\n toggle(): void {\n this.setTheme(this.theme() === 'dark' ? 'light' : 'dark');\n }\n\n /** Stores an explicit choice; OS changes are ignored from now on. */\n setTheme(theme: RbTheme): void {\n this.initialized = true;\n this.storedTheme.set(theme);\n this.write(RB_THEME_STORAGE_KEY, theme);\n this.apply();\n }\n\n /** Forgets the explicit choice, so the theme follows the OS again. */\n clearPreference(): void {\n this.initialized = true;\n this.storedTheme.set(null);\n this.remove(RB_THEME_STORAGE_KEY);\n this.apply();\n }\n\n /** Forces a theme (or releases it with `null`) without touching the stored choice. */\n forceTheme(theme: RbTheme | null): void {\n this.forcedTheme.set(theme);\n this.apply();\n }\n\n private apply(): void {\n const root = this.document.documentElement;\n const theme = this.theme();\n const explicit = this.forcedTheme() ?? this.storedTheme();\n\n root.dataset['theme'] = theme;\n if (explicit) {\n root.style.colorScheme = explicit;\n } else {\n root.style.removeProperty('color-scheme');\n }\n\n for (const meta of Array.from(\n this.document.querySelectorAll<HTMLMetaElement>('meta[name=\"theme-color\"]'),\n )) {\n meta.content = RB_THEME_COLORS[theme];\n }\n }\n\n private readStoredTheme(): RbTheme | null {\n const stored = this.read(RB_THEME_STORAGE_KEY);\n let theme: RbTheme | null = isTheme(stored) ? stored : null;\n\n for (const legacyKey of this.options.legacyStorageKeys ?? []) {\n const legacy = this.read(legacyKey);\n if (theme === null && isTheme(legacy)) {\n theme = legacy;\n this.write(RB_THEME_STORAGE_KEY, legacy);\n }\n if (legacy !== null) this.remove(legacyKey);\n }\n\n return theme;\n }\n\n // Storage can be unavailable (privacy modes, disabled storage); the theme then follows the OS.\n private read(key: string): string | null {\n try {\n return this.window?.localStorage.getItem(key) ?? null;\n } catch {\n return null;\n }\n }\n\n private write(key: string, value: string): void {\n try {\n this.window?.localStorage.setItem(key, value);\n } catch {\n // Ignore: the choice still applies for this session.\n }\n }\n\n private remove(key: string): void {\n try {\n this.window?.localStorage.removeItem(key);\n } catch {\n // Ignore: nothing to clean up without storage.\n }\n }\n}\n","import {\n EnvironmentProviders,\n inject,\n makeEnvironmentProviders,\n provideAppInitializer,\n} from '@angular/core';\nimport { MatIconRegistry } from '@angular/material/icon';\n\nimport { RB_THEME_OPTIONS, RbThemeOptions, ThemeService } from './theme/theme.service';\n\n/** Font set class of the self-hosted Material Symbols subset (docs/design-system.md, section 10). */\nexport const RB_ICON_FONT_SET = 'material-symbols-outlined';\n\nexport type RbDesignSystemOptions = RbThemeOptions;\n\n/**\n * Registers the kit's runtime pieces in `app.config.ts`:\n *\n * - applies the theme before the root component renders (no flash for a stored choice);\n * - makes `material-symbols-outlined` the default `<mat-icon>` font set.\n */\nexport function provideRbDesignSystem(options: RbDesignSystemOptions = {}): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: RB_THEME_OPTIONS, useValue: options },\n provideAppInitializer(() => {\n inject(ThemeService).initialize();\n inject(MatIconRegistry).setDefaultFontSetClass(RB_ICON_FONT_SET);\n }),\n ]);\n}\n","import { ChangeDetectionStrategy, Component, inject } from '@angular/core';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatTooltip } from '@angular/material/tooltip';\n\nimport { ThemeService } from './theme.service';\n\n/**\n * Light/dark switch for the app shell (docs/design-system.md, section 11). The accessible name stays\n * \"Dark theme\" and `aria-pressed` carries the state, so the label never rewrites itself into the\n * opposite action. Renders nothing while the app forces a theme.\n */\n@Component({\n selector: 'rb-theme-toggle',\n imports: [MatIconButton, MatIcon, MatTooltip],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (!theme.isForced()) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"rb-theme-toggle\"\n aria-label=\"Dark theme\"\n matTooltip=\"Dark theme\"\n [attr.aria-pressed]=\"theme.isDark()\"\n (click)=\"theme.toggle()\"\n >\n <mat-icon fontSet=\"material-symbols-outlined\" aria-hidden=\"true\">dark_mode</mat-icon>\n </button>\n }\n `,\n styles: `\n :host {\n display: inline-flex;\n }\n\n .rb-theme-toggle[aria-pressed='true'] {\n background-color: var(--rb-color-primary-soft);\n color: var(--rb-color-on-primary-soft);\n }\n `,\n})\nexport class RbThemeToggleComponent {\n protected readonly theme = inject(ThemeService);\n}\n","import { ChangeDetectionStrategy, Component, ViewEncapsulation, input } from '@angular/core';\n\n/**\n * The standard footer of every shell (docs/design-system.md, section 12.5): \"© <year> RB Labs ·\n * <App name>\", followed on the same line by any projected links or status.\n */\n@Component({\n selector: 'rb-shell-footer',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'rb-shell-footer' },\n template: `\n <footer class=\"rb-shell-footer__inner\">\n <p class=\"rb-shell-footer__copy\">© {{ year }} RB Labs · {{ appName() }}</p>\n <div class=\"rb-shell-footer__extra\"><ng-content /></div>\n </footer>\n `,\n styleUrl: './shell-footer.scss',\n})\nexport class RbShellFooterComponent {\n readonly appName = input.required<string>();\n\n protected readonly year = new Date().getFullYear();\n}\n","import { BreakpointObserver } from '@angular/cdk/layout';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n ViewEncapsulation,\n computed,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatSidenav, MatSidenavContainer, MatSidenavContent } from '@angular/material/sidenav';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { NavigationEnd, Router } from '@angular/router';\nimport { filter } from 'rxjs';\n\nimport { RbBrandLockupComponent } from '../../brand/brand-lockup/brand-lockup';\nimport { RB_BREAKPOINTS } from '../../breakpoints';\nimport { RbThemeToggleComponent } from '../../theme/theme-toggle';\nimport { RbShellFooterComponent } from '../shell-footer/shell-footer';\n\n/**\n * `sidenav`: a navigation rail beside the content that becomes a drawer below `lg`.\n * `modules`: a short list of sections beside the content that becomes a row, then a tab bar.\n * `none`: top-level links, if any, go in the `[rbShellActions]` slot.\n */\nexport type RbAppShellNavigation = 'none' | 'sidenav' | 'modules';\n\n/**\n * Frame for authenticated and operational areas (docs/design-system.md, section 16.1): skip link,\n * top bar with the brand lockup, title, actions and theme toggle, optional navigation, the content\n * column and the standard footer.\n */\n@Component({\n selector: 'rb-app-shell',\n imports: [\n MatIcon,\n MatIconButton,\n MatSidenav,\n MatSidenavContainer,\n MatSidenavContent,\n MatTooltip,\n NgTemplateOutlet,\n RbBrandLockupComponent,\n RbShellFooterComponent,\n RbThemeToggleComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-app-shell',\n '[attr.data-navigation]': 'navigation()',\n '[attr.data-drawer]': 'isDrawer() ? \"\" : null',\n },\n template: `\n <a class=\"rb-skip-link\" href=\"#main-content\" (click)=\"skipToMain($event)\"\n >Skip to main content</a\n >\n\n <header class=\"rb-app-shell__topbar\">\n @if (hasSidenav() && isDrawer()) {\n <button\n matIconButton\n type=\"button\"\n class=\"rb-app-shell__menu\"\n aria-label=\"Navigation\"\n matTooltip=\"Navigation\"\n aria-controls=\"rb-app-shell-sidenav\"\n [attr.aria-expanded]=\"drawerOpen()\"\n (click)=\"toggleDrawer()\"\n >\n <mat-icon fontSet=\"material-symbols-outlined\" aria-hidden=\"true\">menu</mat-icon>\n </button>\n }\n <rb-brand-lockup [appName]=\"appName()\" [link]=\"homeLink()\" compact=\"below-sm\" />\n <div class=\"rb-app-shell__title\"><ng-content select=\"[rbShellTitle]\" /></div>\n <div class=\"rb-app-shell__actions\">\n <ng-content select=\"[rbShellActions]\" />\n <rb-theme-toggle />\n </div>\n </header>\n\n @if (hasSidenav()) {\n <mat-sidenav-container class=\"rb-app-shell__container\">\n <mat-sidenav\n id=\"rb-app-shell-sidenav\"\n class=\"rb-app-shell__sidenav\"\n [mode]=\"isDrawer() ? 'over' : 'side'\"\n [opened]=\"!isDrawer() || drawerOpen()\"\n (closedStart)=\"drawerOpen.set(false)\"\n >\n <ng-content select=\"[rbShellSidenav]\" />\n </mat-sidenav>\n <mat-sidenav-content class=\"rb-app-shell__scroller\">\n <ng-container [ngTemplateOutlet]=\"body\" />\n </mat-sidenav-content>\n </mat-sidenav-container>\n } @else {\n <ng-container [ngTemplateOutlet]=\"body\" />\n }\n\n <ng-template #body>\n <div class=\"rb-app-shell__body\">\n @if (navigation() === 'modules') {\n <div class=\"rb-app-shell__module-nav\"><ng-content select=\"[rbShellModuleNav]\" /></div>\n }\n <main #main class=\"rb-app-shell__main\" id=\"main-content\" tabindex=\"-1\">\n <ng-content />\n </main>\n </div>\n <rb-shell-footer [appName]=\"appName()\"\n ><ng-content select=\"[rbShellFooter]\"\n /></rb-shell-footer>\n </ng-template>\n `,\n styleUrl: './app-shell.scss',\n})\nexport class RbAppShellComponent {\n /** Shown in the lockup and the footer: `Admin`, `Auth`, `Rover`, `Photogrammetry`… */\n readonly appName = input.required<string>();\n /** The lockup's link target, as a `routerLink` value. */\n readonly homeLink = input<string | readonly unknown[]>('/');\n readonly navigation = input<RbAppShellNavigation>('none');\n\n protected readonly hasSidenav = computed(() => this.navigation() === 'sidenav');\n\n private readonly breakpointObserver = inject(BreakpointObserver);\n /** Below `lg` the sidenav is an overlay drawer (section 8.1). */\n readonly isDrawer = signal(this.breakpointObserver.isMatched(RB_BREAKPOINTS.belowLg));\n readonly drawerOpen = signal(false);\n\n private readonly main = viewChild.required<ElementRef<HTMLElement>>('main');\n\n constructor() {\n const destroyRef = inject(DestroyRef);\n\n this.breakpointObserver\n .observe(RB_BREAKPOINTS.belowLg)\n .pipe(takeUntilDestroyed(destroyRef))\n .subscribe(({ matches }) => {\n this.isDrawer.set(matches);\n if (!matches) this.drawerOpen.set(false);\n });\n\n inject(Router)\n .events.pipe(\n filter((event) => event instanceof NavigationEnd),\n takeUntilDestroyed(destroyRef),\n )\n .subscribe(() => this.drawerOpen.set(false));\n }\n\n toggleDrawer(): void {\n this.drawerOpen.update((open) => !open);\n }\n\n /**\n * Moves focus to `<main>` without changing the URL: with `<base href=\"/\">` a bare `#main-content`\n * link would resolve to the root route instead of the current page.\n */\n protected skipToMain(event: Event): void {\n event.preventDefault();\n this.main().nativeElement.focus();\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n output,\n} from '@angular/core';\nimport { MatButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { RouterLink } from '@angular/router';\n\nimport { RbMonogramComponent } from '../../brand/monogram/monogram';\nimport { RbMessageComponent } from '../../components/message/message';\n\nlet nextId = 0;\n\n/**\n * The central sign-in page (docs/design-system.md, section 16.3): one card that hands the user off\n * to RB Labs Auth. Apps that sign in through Auth place it alone in `rb-public-shell`; it renders\n * the page's single `<h1>`, collects no credentials and emits `signIn` for the app to start the\n * handoff with its own return path.\n */\n@Component({\n selector: 'rb-central-sign-in',\n imports: [MatButton, MatIcon, RbMessageComponent, RbMonogramComponent, RouterLink],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'rb-central-sign-in',\n // `title` is an input; a static `title=\"…\"` would also leave a native tooltip on the host.\n '[attr.title]': 'null',\n },\n template: `\n <section class=\"rb-central-sign-in__card\" [attr.aria-labelledby]=\"titleId\">\n <div class=\"rb-central-sign-in__intro\">\n <span class=\"rb-central-sign-in__icon\" aria-hidden=\"true\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{ icon() }}</mat-icon>\n </span>\n @if (eyebrow()) {\n <p class=\"rb-central-sign-in__eyebrow\">{{ eyebrow() }}</p>\n }\n <h1 class=\"rb-central-sign-in__title\" [id]=\"titleId\">{{ resolvedTitle() }}</h1>\n <p class=\"rb-central-sign-in__description\">{{ resolvedDescription() }}</p>\n </div>\n\n <div class=\"rb-central-sign-in__provider\">\n <rb-monogram class=\"rb-central-sign-in__mark\" />\n <span class=\"rb-central-sign-in__provider-name\">\n <strong>RB Labs Auth</strong>\n <code>{{ authHost() }}</code>\n </span>\n </div>\n\n @if (error()) {\n <rb-message tone=\"danger\">\n <p>{{ error() }}</p>\n </rb-message>\n }\n\n <div class=\"rb-central-sign-in__actions\">\n <button\n class=\"rb-central-sign-in__continue\"\n matButton=\"filled\"\n type=\"button\"\n (click)=\"signIn.emit()\"\n >\n Continue to RB Labs Auth\n <mat-icon fontSet=\"material-symbols-outlined\" aria-hidden=\"true\" iconPositionEnd\n >arrow_forward</mat-icon\n >\n </button>\n <a class=\"rb-central-sign-in__back\" matButton=\"outlined\" [routerLink]=\"backLink()\"\n >Back to home</a\n >\n </div>\n\n @if (note()) {\n <p class=\"rb-central-sign-in__note\">{{ note() }}</p>\n }\n </section>\n `,\n styleUrl: './central-sign-in.scss',\n})\nexport class RbCentralSignInComponent {\n /** The app the user signs in to: `Admin`, `Rover`, `Photogrammetry`… */\n readonly appName = input.required<string>();\n /** Overrides the default title, `Sign in to RB Labs <appName>`. */\n readonly title = input<string>('');\n /** Short context above the title, such as the workspace the page protects. */\n readonly eyebrow = input<string>('');\n /** Overrides the default sentence about where the user is sent. */\n readonly description = input<string>('');\n /** Material Symbols name of the app's icon in the card header. */\n readonly icon = input<string>('login');\n /** Host shown in the identity row. */\n readonly authHost = input<string>('auth.rblabs.dev');\n /** Optional closing note, such as who may enter the app. */\n readonly note = input<string>('');\n /** A safe, non-disclosing message for the failure the app was sent back with. */\n readonly error = input<string | null>(null);\n /** The \"Back to home\" target, as a `routerLink` value. */\n readonly backLink = input<string | readonly unknown[]>('/');\n\n /** The primary action: the app starts the Auth handoff with its return path. */\n readonly signIn = output<void>();\n\n protected readonly titleId = `rb-central-sign-in-title-${nextId++}`;\n\n protected readonly resolvedTitle = computed(\n () => this.title() || `Sign in to RB Labs ${this.appName()}`,\n );\n protected readonly resolvedDescription = computed(\n () =>\n this.description() ||\n `You will be taken to RB Labs Auth to sign in, then returned to ${this.appName()}.`,\n );\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n input,\n viewChild,\n} from '@angular/core';\n\nimport { RbBrandLockupComponent } from '../../brand/brand-lockup/brand-lockup';\nimport { RbThemeToggleComponent } from '../../theme/theme-toggle';\nimport { RbShellFooterComponent } from '../shell-footer/shell-footer';\n\n/**\n * Frame for landing, sign-in and other public pages (docs/design-system.md, section 16.2): skip\n * link, a header with the brand lockup and theme toggle, a centered content area on the brand\n * background, and the standard footer.\n */\n@Component({\n selector: 'rb-public-shell',\n imports: [RbBrandLockupComponent, RbShellFooterComponent, RbThemeToggleComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'rb-public-shell' },\n template: `\n <a class=\"rb-skip-link\" href=\"#main-content\" (click)=\"skipToMain($event)\"\n >Skip to main content</a\n >\n\n <header class=\"rb-public-shell__header\">\n <rb-brand-lockup [appName]=\"appName()\" [link]=\"homeLink()\" />\n <div class=\"rb-public-shell__actions\">\n <ng-content select=\"[rbShellActions]\" />\n <rb-theme-toggle />\n </div>\n </header>\n\n <main #main class=\"rb-public-shell__main\" id=\"main-content\" tabindex=\"-1\">\n <ng-content />\n </main>\n\n <rb-shell-footer [appName]=\"appName()\"><ng-content select=\"[rbShellFooter]\" /></rb-shell-footer>\n `,\n styleUrl: './public-shell.scss',\n})\nexport class RbPublicShellComponent {\n /** Shown in the lockup and the footer: `Admin`, `Auth`, `Rover`, `Photogrammetry`… */\n readonly appName = input.required<string>();\n /** The lockup's link target, as a `routerLink` value. */\n readonly homeLink = input<string | readonly unknown[]>('/');\n\n private readonly main = viewChild.required<ElementRef<HTMLElement>>('main');\n\n /** See RbAppShellComponent: keeps the skip link on the current route. */\n protected skipToMain(event: Event): void {\n event.preventDefault();\n this.main().nativeElement.focus();\n }\n}\n","/**\n * Kit version. The build stamps it from projects/axiom/package.json (scripts/stamp-version.mjs);\n * source and development builds show the placeholder.\n */\nexport const RB_DESIGN_SYSTEM_VERSION: string = '1.2.2';\n"],"mappings":"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"}
|
package/fonts/LICENSE
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2016 The Inter Project Authors (https://github.com/rsms/inter) Inter-Italic[opsz,wght].ttf: Copyright 2016 The Inter Project Authors (https://github.com/rsms/inter)
|
|
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.
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rblabs-dev/axiom",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Axiom, the RB Labs design system for Angular and Angular Material 3",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"types",
|
|
45
45
|
"showcase",
|
|
46
46
|
"styles",
|
|
47
|
+
"fonts",
|
|
47
48
|
"brand",
|
|
48
49
|
"material-symbols-icons.txt",
|
|
49
50
|
"cli"
|
|
@@ -59,7 +60,6 @@
|
|
|
59
60
|
"rxjs": "^7.8.0"
|
|
60
61
|
},
|
|
61
62
|
"dependencies": {
|
|
62
|
-
"@fontsource-variable/inter": "^5.3.0",
|
|
63
63
|
"tslib": "^2.3.0"
|
|
64
64
|
},
|
|
65
65
|
"sideEffects": false,
|
package/styles/_fonts.scss
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
// Self-hosted fonts (docs/design-system.md, sections 6.1 and 10). Nothing here loads from a CDN:
|
|
2
|
-
// Inter Variable
|
|
3
|
-
//
|
|
2
|
+
// the app serves Inter Variable from the package's fonts/ folder and its Material Symbols subset
|
|
3
|
+
// from public/fonts/, both at /fonts/.
|
|
4
4
|
|
|
5
5
|
// Inter Variable, Latin and Latin Extended. `optional` paints with the system fallback at once on a
|
|
6
|
-
// slow network instead of delaying or reflowing the first render.
|
|
6
|
+
// slow network instead of delaying or reflowing the first render. The URLs are stable so that the
|
|
7
|
+
// app's index.html can preload the Latin file: the font then loads with the HTML instead of after
|
|
8
|
+
// the global stylesheet, which a first visit needs to get Inter within the `optional` window.
|
|
7
9
|
@mixin inter() {
|
|
8
10
|
@font-face {
|
|
9
11
|
font-family: 'Inter Variable';
|
|
10
12
|
font-style: normal;
|
|
11
13
|
font-display: optional;
|
|
12
14
|
font-weight: 100 900;
|
|
13
|
-
src: url('
|
|
14
|
-
format('woff2-variations');
|
|
15
|
+
src: url('/fonts/inter-latin-wght-normal.woff2') format('woff2-variations');
|
|
15
16
|
unicode-range:
|
|
16
17
|
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
|
|
17
18
|
U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
|
@@ -22,8 +23,7 @@
|
|
|
22
23
|
font-style: normal;
|
|
23
24
|
font-display: optional;
|
|
24
25
|
font-weight: 100 900;
|
|
25
|
-
src: url('
|
|
26
|
-
format('woff2-variations');
|
|
26
|
+
src: url('/fonts/inter-latin-ext-wght-normal.woff2') format('woff2-variations');
|
|
27
27
|
unicode-range:
|
|
28
28
|
U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
|
|
29
29
|
U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
|
package/styles/_index.scss
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
@forward 'breakpoints' show below, above, $breakpoints;
|
|
28
28
|
|
|
29
29
|
// Stamped from projects/axiom/package.json by the build (scripts/stamp-version.mjs).
|
|
30
|
-
$version: '1.2.
|
|
30
|
+
$version: '1.2.2';
|
|
31
31
|
|
|
32
32
|
@mixin design-system($scope: null, $icon-font-url: null) {
|
|
33
33
|
@include fonts.inter();
|