@masmarino/gabarit 1.3.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -59
- package/docs/README.md +102 -0
- package/fesm2022/masmarino-gabarit-docs.mjs +1414 -0
- package/fesm2022/masmarino-gabarit-docs.mjs.map +1 -0
- package/fesm2022/masmarino-gabarit.mjs +212 -119
- package/fesm2022/masmarino-gabarit.mjs.map +1 -1
- package/fonts/OFL-ibm-plex.txt +93 -0
- package/fonts/ibm-plex-mono-400.woff2 +0 -0
- package/fonts/ibm-plex-mono-500.woff2 +0 -0
- package/fonts/ibm-plex-sans-400.woff2 +0 -0
- package/fonts/ibm-plex-sans-500.woff2 +0 -0
- package/fonts/ibm-plex-sans-600.woff2 +0 -0
- package/fonts/ibm-plex-sans-condensed-600.woff2 +0 -0
- package/fonts/index.scss +28 -0
- package/package.json +27 -2
- package/src/lib/tokens/_a11y.scss +22 -0
- package/src/lib/tokens/_base.scss +31 -0
- package/src/lib/tokens/_palette.scss +52 -51
- package/src/lib/tokens/_semantic.scss +17 -124
- package/src/lib/tokens/_themes.scss +144 -0
- package/src/lib/tokens/_utilities.scss +14 -8
- package/src/lib/tokens/index.scss +3 -0
- package/types/masmarino-gabarit-docs.d.ts +345 -0
- package/types/masmarino-gabarit.d.ts +49 -9
package/README.md
CHANGED
|
@@ -135,6 +135,12 @@ but plain, without the layout the directive provides.
|
|
|
135
135
|
| `MenuTrigger` | `[gbtMenuTrigger]` | `gbt-menu`: a custom trigger element instead of the default button. |
|
|
136
136
|
| `StatTileLink` | `a[gbtStatTileLink]` | `gbt-stat-tile`: the router-agnostic link, its text is the label. |
|
|
137
137
|
|
|
138
|
+
## Documentation reader
|
|
139
|
+
|
|
140
|
+
`@masmarino/gabarit/docs` is a reader for documentation written in Markdown and shipped with an app (navigation,
|
|
141
|
+
search, outline, neighbours), with `gbt-markdown-view` for Markdown anywhere else. It is a separate entry point
|
|
142
|
+
because it needs `@angular/router`, `marked` and `dompurify`; see [its README](docs/README.md).
|
|
143
|
+
|
|
138
144
|
## Primitives and pipes
|
|
139
145
|
|
|
140
146
|
Pure functions exported from `@masmarino/gabarit`, usable in any TypeScript
|
|
@@ -285,92 +291,133 @@ keep their source order); with `compare`, `desc` reverses the ascending result.
|
|
|
285
291
|
|
|
286
292
|
## Styles
|
|
287
293
|
|
|
288
|
-
|
|
294
|
+
Gabarit carries the look of the Ferris family: white paper and near-black ink in the light theme, a
|
|
295
|
+
cool graphite in the dark one, IBM Plex throughout, hairlines and square-ish corners. Neutrals carry
|
|
296
|
+
the screens; the crab's rust is kept for the marks that are the brand's own (focus, the current page),
|
|
297
|
+
patina green says success. Every text token reaches 7:1 on the page and on a panel, in both themes
|
|
298
|
+
(`contrast.spec.ts`).
|
|
299
|
+
|
|
300
|
+
Import the tokens, and the fonts, in the application's `styles.scss`:
|
|
289
301
|
|
|
290
302
|
```scss
|
|
291
|
-
@use 'gabarit/
|
|
303
|
+
@use '@masmarino/gabarit/fonts' with ($path: '/fonts/ibm-plex/');
|
|
304
|
+
@use '@masmarino/gabarit/tokens';
|
|
305
|
+
|
|
306
|
+
// Optional: body, h1–h3, code and selection in the family's type.
|
|
307
|
+
@include tokens.document-base;
|
|
292
308
|
```
|
|
293
309
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
310
|
+
The fonts entry declares IBM Plex Sans (400, 500, 600), Sans Condensed (600) and Mono (400, 500),
|
|
311
|
+
subset to Latin-1 (OFL licence beside the files). The application serves the files at `$path`, for
|
|
312
|
+
instance with an Angular asset:
|
|
313
|
+
|
|
314
|
+
```json
|
|
315
|
+
{ "glob": "*.woff2", "input": "node_modules/@masmarino/gabarit/fonts", "output": "fonts/ibm-plex" }
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Without them the stacks fall back to the system's sans and monospace.
|
|
319
|
+
|
|
320
|
+
### The graphite frame
|
|
321
|
+
|
|
322
|
+
`gbt-app-shell` draws its rail and its bar as one graphite frame, the same in both themes, with the
|
|
323
|
+
page set into it as a sheet whose corner is rounded. The auth pages (`gbt-auth-panel`) open on the
|
|
324
|
+
same graphite, their panel keeping the page's theme. An application can lay its own parts on the
|
|
325
|
+
frame with the `frame-tokens` mixin, which sets the dark tokens on a deeper ground:
|
|
326
|
+
|
|
327
|
+
```scss
|
|
328
|
+
.public-header {
|
|
329
|
+
@include tokens.frame-tokens;
|
|
330
|
+
background: var(--bg-panel);
|
|
331
|
+
}
|
|
332
|
+
```
|
|
297
333
|
|
|
298
334
|
### Color tokens
|
|
299
335
|
|
|
300
|
-
Every component
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
(
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
|
307
|
-
|
|
|
308
|
-
|
|
|
309
|
-
|
|
|
310
|
-
|
|
|
311
|
-
| | `--bg-
|
|
312
|
-
| | `--bg-
|
|
313
|
-
|
|
|
314
|
-
| | `--
|
|
315
|
-
|
|
|
316
|
-
| | `--
|
|
317
|
-
|
|
|
318
|
-
|
|
|
319
|
-
|
|
|
320
|
-
|
|
|
321
|
-
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
336
|
+
Every component reads only the custom properties below, set on `:root` from the `light-tokens` and
|
|
337
|
+
`dark-tokens` mixins (`_themes.scss`). **These are what an application overrides to re-theme
|
|
338
|
+
itself**; the raw palette (`--slate-*`, `--graphite-*`, `--rust-*`…) is never referenced by a
|
|
339
|
+
component (enforced by `token-usage.spec.ts`).
|
|
340
|
+
|
|
341
|
+
| Category | Token | Role |
|
|
342
|
+
| ----------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------- |
|
|
343
|
+
| Brand | `--primary` / `--primary-hover` | Action colour (buttons, selected states): the ink |
|
|
344
|
+
| | `--accent` / `--accent-text` | The rust, for marks; its text shade |
|
|
345
|
+
| | `--focus-ring` | Every focus outline |
|
|
346
|
+
| Backgrounds | `--bg-principal` | Surfaces: cards, panels, fields |
|
|
347
|
+
| | `--bg-panel` | The page's ground |
|
|
348
|
+
| | `--bg-hover` | Hover state of an interactive element on a neutral background |
|
|
349
|
+
| | `--bg-track` | Track of a segmented control, visible on the page and on a panel |
|
|
350
|
+
| | `--frame` | The graphite of the shell and the auth pages, in both themes |
|
|
351
|
+
| Border | `--border-color` | The edge of a field or a control (3:1) |
|
|
352
|
+
| | `--gbt-hairline` / `--gbt-card-border` | Quiet separators and card edges |
|
|
353
|
+
| Text | `--text-primary` / `--text-secondary` / `--text-discret` | From most to least emphasized |
|
|
354
|
+
| | `--text-on-primary` / `--text-on-error` / `--text-on-color` | Text set on a `--primary` fill, an error fill, or a solid colour |
|
|
355
|
+
| Success | `--color-success-base` / `-hover` / `-text` / `-bg` / `-bg-text` | Fill, hover, text, light background, text on that background |
|
|
356
|
+
| Warning | `--color-warning-base` / `-hover` / `-text` / `-bg` / `-bg-text` | Same |
|
|
357
|
+
| Error | `--color-error-base` / `-fill` / `-hover` / `-text` / `-bg` / `-bg-text` | Same (`-fill`: a solid fill, the danger button) |
|
|
358
|
+
| Info | `--color-info-bg` / `-bg-text` / `-vivid-base` | Light background, text on it, the mark |
|
|
359
|
+
| Dataviz | `--chart-series-1-base` … `-6-base` | The chart series, in order |
|
|
360
|
+
| | `--chart-grid` | Chart grid and axes |
|
|
361
|
+
|
|
362
|
+
Other tokens live on `:root` without being colours: border radii (`--site-border-radius*`, 3 to
|
|
363
|
+
6px), shadows (`--site-shadow-*`, rings rather than drops), transitions (`--site-transition-*`) and
|
|
364
|
+
the type stacks (`--font-family`, `--font-display`, `--gbt-font-mono`).
|
|
326
365
|
|
|
327
366
|
### Theming hooks
|
|
328
367
|
|
|
329
|
-
A few more tokens are not set on `:root`: each component falls back to the
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
|
334
|
-
|
|
|
335
|
-
| `--gbt-
|
|
336
|
-
| `--gbt-
|
|
337
|
-
| `--gbt-radius-
|
|
338
|
-
| `--gbt-radius-
|
|
339
|
-
| `--gbt-radius-
|
|
340
|
-
| `--gbt-radius-
|
|
341
|
-
| `--gbt-
|
|
342
|
-
| `--gbt-nav-active-
|
|
343
|
-
| `--gbt-
|
|
344
|
-
| `--gbt-shell-border` | The app shell's navigation and header edges | `
|
|
345
|
-
| `--gbt-shell-header-bg` | The app shell's header |
|
|
346
|
-
| `--gbt-shell-content-padding` | The app shell's main content area
|
|
347
|
-
| `--gbt-auth-panel-backdrop` | The page behind the auth panels (login, register…) |
|
|
348
|
-
| `--gbt-auth-panel-radius` | The auth panel card | `
|
|
368
|
+
A few more tokens are not set on `:root`: each component falls back to the value in the last column,
|
|
369
|
+
so an app that leaves them alone gets the family's look. Set one to take that part in hand.
|
|
370
|
+
|
|
371
|
+
| Token | Used by | Fallback |
|
|
372
|
+
| ----------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------ |
|
|
373
|
+
| `--gbt-focus-ring` | Every focus outline | `var(--focus-ring)` |
|
|
374
|
+
| `--gbt-font-display` | Page, card, panel, modal and drawer titles, stat tile values, empty state | `var(--font-display)` |
|
|
375
|
+
| `--gbt-radius-badge` | Badges, card and tab counts | `3px` |
|
|
376
|
+
| `--gbt-radius-chip` | Mono badges, inline code in a list row, search bar keys | `2px` |
|
|
377
|
+
| `--gbt-radius-menu` | Select and autocomplete panels, menu items, search results | `4px` |
|
|
378
|
+
| `--gbt-radius-tile` | Icon marker tiles, job graph nodes, avatar group overflow, TOTP QR code | `4px` |
|
|
379
|
+
| `--gbt-radius-search` | The search bar field | `3px` |
|
|
380
|
+
| `--gbt-nav-active-bg` / `--gbt-nav-active-text` | The current page in the app shell navigation | a 9% ink tint / `--text-primary` |
|
|
381
|
+
| `--gbt-nav-active-mark` | A 2px rule on the start edge of the current page link | `var(--accent)` |
|
|
382
|
+
| `--gbt-shell-bar` | The height of the app shell's bar and of the logo's corner | `4rem` |
|
|
383
|
+
| `--gbt-shell-border` | The app shell's navigation and header edges | `transparent` |
|
|
384
|
+
| `--gbt-shell-header-bg` | The app shell's header | the frame |
|
|
385
|
+
| `--gbt-shell-content-padding` | The app shell's bar and main content area | `clamp(1rem, 0.25rem + 2vw, 2rem)` |
|
|
386
|
+
| `--gbt-auth-panel-backdrop` | The page behind the auth panels (login, register…) | `var(--frame)` |
|
|
387
|
+
| `--gbt-auth-panel-radius` | The auth panel card | `var(--site-border-radius-lg)` |
|
|
349
388
|
|
|
350
389
|
Overriding a token after the import:
|
|
351
390
|
|
|
352
391
|
```scss
|
|
353
|
-
@use 'gabarit/tokens'
|
|
392
|
+
@use '@masmarino/gabarit/tokens';
|
|
354
393
|
|
|
355
394
|
:root {
|
|
356
|
-
--
|
|
395
|
+
--accent: #7c3aed;
|
|
357
396
|
}
|
|
358
397
|
```
|
|
359
398
|
|
|
360
|
-
**Dark mode activates via `prefers-color-scheme` or `[data-theme='dark']`
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
dark mode, redeclare it under the same conditions as Gabarit, after its
|
|
364
|
-
import:
|
|
399
|
+
**Dark mode activates via `prefers-color-scheme` or `[data-theme='dark']` on `<html>`, and
|
|
400
|
+
reapplies to the same tokens.** An override set on a bare `:root` applies to both themes; for a value
|
|
401
|
+
specific to dark mode, redeclare it under the same conditions as Gabarit, after its import:
|
|
365
402
|
|
|
366
403
|
```scss
|
|
367
404
|
@media (prefers-color-scheme: dark) {
|
|
368
405
|
:root {
|
|
369
|
-
--
|
|
406
|
+
--accent: #a78bfa;
|
|
370
407
|
}
|
|
371
408
|
}
|
|
372
409
|
```
|
|
373
410
|
|
|
411
|
+
### Upgrading from 1.x
|
|
412
|
+
|
|
413
|
+
- The default look is the Ferris family's (palette, IBM Plex, radii, the graphite shell and auth
|
|
414
|
+
pages). An application that themed 1.x by mapping its own tokens onto Gabarit's can drop that map.
|
|
415
|
+
- The raw palette is new (`--slate-*`, `--graphite-*`, `--rust-*`, `--patina-*`, `--amber-*`,
|
|
416
|
+
`--red-*`, `--indigo-*`); `--brand-*`, `--grey-*`, `--green-*` and `--emerald-*` are gone.
|
|
417
|
+
- New tokens: `--accent`, `--accent-text`, `--focus-ring`, `--frame`, `--font-display`; new mixins:
|
|
418
|
+
`light-tokens`, `dark-tokens`, `frame-tokens`, `document-base`, `visually-hidden`, `focus-ring`.
|
|
419
|
+
- `@masmarino/gabarit/fonts` replaces the font an application served for `'Inter'`.
|
|
420
|
+
|
|
374
421
|
## Internationalization
|
|
375
422
|
|
|
376
423
|
Gabarit ships no translation mechanism. Every visible string is a
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# @masmarino/gabarit/docs
|
|
2
|
+
|
|
3
|
+
A reader for documentation written in Markdown and shipped with an app: a navigation with search on the left, the page
|
|
4
|
+
with its breadcrumb and neighbours, and its outline on a wide screen. It is its own entry point because it needs
|
|
5
|
+
`@angular/router`, [marked](https://marked.js.org) and [DOMPurify](https://github.com/cure53/DOMPurify), which the rest
|
|
6
|
+
of Gabarit does not; install them next to Gabarit:
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
npm install marked dompurify
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## The pages
|
|
13
|
+
|
|
14
|
+
The app serves the documentation as static files under a root (`/docs` by default), for instance from its `public/`
|
|
15
|
+
folder:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
public/docs/
|
|
19
|
+
index.json # the sections and their pages, in reading order
|
|
20
|
+
demarrer/presentation.md # one Markdown file per page: <section>/<page>.md
|
|
21
|
+
demarrer/prise-en-main.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"sections": [
|
|
27
|
+
{
|
|
28
|
+
"slug": "demarrer",
|
|
29
|
+
"title": "Démarrer",
|
|
30
|
+
"pages": [
|
|
31
|
+
{ "slug": "presentation", "title": "Présentation", "description": "What the app does." }
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The index and each page are fetched once and kept. A page links to another with a root-relative link
|
|
39
|
+
(`[Configuration](/docs/installation/configuration#variables)`): the reader follows it through the router. A quote
|
|
40
|
+
whose first word is a bold callout key becomes a callout: `> **Note** …` (and `> **Warning** …` by default).
|
|
41
|
+
|
|
42
|
+
## Wiring
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
// app.routes.ts
|
|
46
|
+
import { docsRoutes } from '@masmarino/gabarit/docs'
|
|
47
|
+
|
|
48
|
+
export const routes: Routes = [
|
|
49
|
+
{
|
|
50
|
+
path: 'docs',
|
|
51
|
+
// The app's own page around the reader (its layout, its header), or DocsPage itself.
|
|
52
|
+
children: docsRoutes(() => import('./docs/docs-route').then((m) => m.DocsRoute)),
|
|
53
|
+
},
|
|
54
|
+
]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
// docs-route.ts: the reader inside the app's layout
|
|
59
|
+
@Component({
|
|
60
|
+
imports: [AppLayout, DocsPage],
|
|
61
|
+
providers: [
|
|
62
|
+
provideDocs({ callouts: { note: 'note', attention: 'warning' } }),
|
|
63
|
+
provideDocsLabels(FRENCH_DOCS_LABELS),
|
|
64
|
+
{ provide: DOCS_TITLE, useFactory: () => (title: string) => inject(Title).setTitle(title) },
|
|
65
|
+
],
|
|
66
|
+
template: `<app-layout><gbt-docs-page /></app-layout>`,
|
|
67
|
+
})
|
|
68
|
+
export class DocsRoute {}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`docsRoutes()` sends the root to the first page, mounts `<section>/<page>`, and gives any other address the reader's
|
|
72
|
+
own "not found". `gbt-docs-page` reads the section and the page from the route.
|
|
73
|
+
|
|
74
|
+
## Providers
|
|
75
|
+
|
|
76
|
+
| Token | Role |
|
|
77
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
78
|
+
| `provideDocs(config)` | `root` (`/docs`) and the `callouts` keys (`note`, `warning`). |
|
|
79
|
+
| `provideDocsLabels()` | The reader's strings, over the English defaults (`DEFAULT_DOCS_LABELS`). |
|
|
80
|
+
| `DOCS_TITLE` | A function given the shown page's title (or "not found", or the reader's name while loading). Optional. |
|
|
81
|
+
|
|
82
|
+
## Pieces
|
|
83
|
+
|
|
84
|
+
| Piece | Role |
|
|
85
|
+
| ---------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
86
|
+
| `gbt-docs-page` | The whole reader for the routed page: navigation, page, neighbours, outline, loading, failure, not found. |
|
|
87
|
+
| `gbt-docs-nav` | The sections and their pages, with the search; folds behind a toggle on a narrow layout. |
|
|
88
|
+
| `gbt-docs-search` | A search over every page, in the browser, loaded on first focus. |
|
|
89
|
+
| `gbt-markdown-view` | Markdown to sanitised HTML, with the reading styles; usable on its own (a README, release notes). |
|
|
90
|
+
| `gbt-markdown-outline` | The "On this page" panel for the headings a `gbt-markdown-view` emits. |
|
|
91
|
+
|
|
92
|
+
## Security
|
|
93
|
+
|
|
94
|
+
The Markdown is sanitised with a dedicated DOMPurify instance, stricter than its defaults: no `<style>`, no `style`
|
|
95
|
+
attribute, no forms or buttons, no IDREFs or `tabindex`, ids and names prefixed with `user-content-`, only the
|
|
96
|
+
`language-*` classes of code blocks kept, task-list checkboxes disabled, remote images lazy and without a referrer.
|
|
97
|
+
|
|
98
|
+
## Accessibility
|
|
99
|
+
|
|
100
|
+
Every heading gets a stable id; the outline and in-page links move the focus to the heading they reach. Code blocks
|
|
101
|
+
and tables that scroll sideways take the focus and are named. Task-list checkboxes are named by their item. A new page
|
|
102
|
+
moves the focus to its title, except on the first visit.
|