@masmarino/gabarit 1.4.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.
@@ -1,3 +1,5 @@
1
+ @use 'a11y';
2
+
1
3
  .gbt-form-error {
2
4
  margin: 0 0 0.75rem;
3
5
  font-size: 0.875rem;
@@ -85,8 +87,7 @@
85
87
  }
86
88
  }
87
89
 
88
- // Global, so it reaches the links the app projects: each piece of the rail keeps its height, and a rail taller than the
89
- // window scrolls rather than squeezing its links together.
90
+ // Global to reach the projected links: a rail taller than the window scrolls instead of squeezing them.
90
91
  .gbt-app-shell__nav > * {
91
92
  flex-shrink: 0;
92
93
  }
@@ -101,6 +102,7 @@
101
102
  border-radius: var(--site-border-radius-sm);
102
103
  color: var(--text-secondary);
103
104
  font-size: 0.875rem;
105
+ font-weight: 500;
104
106
  text-decoration: none;
105
107
  overflow: hidden;
106
108
  white-space: nowrap;
@@ -118,16 +120,15 @@
118
120
  }
119
121
 
120
122
  &:focus-visible {
121
- outline: 2px solid var(--gbt-focus-ring, var(--primary));
122
- outline-offset: -2px;
123
+ @include a11y.focus-ring(-2px);
123
124
  }
124
125
 
125
126
  // An app can tone the current page down to a tint with a mark on its edge (--gbt-nav-active-*).
126
127
  &[aria-current] {
127
- background: var(--gbt-nav-active-bg, var(--primary));
128
- color: var(--gbt-nav-active-text, var(--text-on-primary));
128
+ background: var(--gbt-nav-active-bg, color-mix(in srgb, var(--text-primary) 9%, transparent));
129
+ color: var(--gbt-nav-active-text, var(--text-primary));
129
130
  font-weight: 600;
130
- box-shadow: inset 2px 0 0 var(--gbt-nav-active-mark, transparent);
131
+ box-shadow: inset 2px 0 0 var(--gbt-nav-active-mark, var(--accent));
131
132
  }
132
133
  }
133
134
 
@@ -223,7 +224,7 @@
223
224
  gap: 0.5rem;
224
225
  width: 100%;
225
226
  padding: 8px 10px;
226
- border-radius: var(--gbt-radius-menu, 8px);
227
+ border-radius: var(--gbt-radius-menu, 4px);
227
228
  color: var(--text-primary);
228
229
  font-size: 14px;
229
230
  text-align: left;
@@ -238,8 +239,7 @@
238
239
  }
239
240
 
240
241
  &:focus-visible {
241
- outline: 2px solid var(--gbt-focus-ring, var(--primary));
242
- outline-offset: -2px;
242
+ @include a11y.focus-ring(-2px);
243
243
  }
244
244
  }
245
245
 
@@ -1,3 +1,6 @@
1
1
  @forward 'palette';
2
2
  @forward 'semantic';
3
+ @forward 'themes';
4
+ @forward 'a11y';
5
+ @forward 'base';
3
6
  @forward 'utilities';
@@ -5,23 +5,16 @@ import { CanActivateFn, Routes } from "@angular/router";
5
5
  import { SafeHtml } from "@angular/platform-browser";
6
6
  import { AutocompleteSearchFn, PanelHeadingLevel } from "@masmarino/gabarit";
7
7
  interface DocsConfig {
8
- /**
9
- * Where the pages are, both as files and as the reader's routes: `<root>/index.json`, `<root>/<section>/<page>.md`,
10
- * and the page `<root>/<section>/<page>`. `/docs` by default.
11
- */
8
+ /** Where the files (`<root>/index.json`, `<root>/<section>/<page>.md`) and the routes live. `/docs` by default. */
12
9
  root: string;
13
- /**
14
- * The quotes that become callouts: a quote whose first word, in bold, is one of these keys (`> **Note** …`), drawn
15
- * in the tone it maps to. Case does not matter.
16
- */
10
+ /** A quote opening on one of these words in bold (`> **Note** …`) becomes a callout of that tone. Any case. */
17
11
  callouts: Readonly<Record<string, 'note' | 'warning'>>;
18
12
  }
19
13
  export declare const DEFAULT_DOCS_CONFIG: Readonly<DocsConfig>;
20
14
  export declare const DOCS_CONFIG: InjectionToken<DocsConfig>;
21
15
  /**
22
- * Where the shown page's title goes, for an app that names its pages somewhere of its own (a header, a breadcrumb):
23
- * called with the page's title, "not found" or the reader's name while loading. Without it the reader leaves the
24
- * title alone.
16
+ * Gets the shown page's title (or "not found", or the reader's name while loading), for an app that shows titles in
17
+ * its own header. Optional.
25
18
  */
26
19
  export declare const DOCS_TITLE: InjectionToken<(title: string) => void>;
27
20
  export declare function provideDocs(config?: Partial<DocsConfig>): Provider;
@@ -92,10 +85,7 @@ export declare function docsReadingOrder(index: DocsIndex): {
92
85
  /** Where `<root>` leads: the first page of the first section, or `null` for an empty index. */
93
86
  export declare function firstDocsPage(root: string, index: DocsIndex): string[] | null;
94
87
  export declare function locateDocsPage(root: string, index: DocsIndex, section: string | null, page: string | null): DocsLocation | null;
95
- /**
96
- * The documentation, shipped as static files under the configured root. The index and each page are fetched once
97
- * and kept, since they only change with a new version of the app. A failure isn't kept, so it gets retried.
98
- */
88
+ /** Fetches the index and each page once; they only change with a new app version. Failures aren't cached. */
99
89
  export declare class DocsService {
100
90
  private readonly http;
101
91
  readonly root: string;
@@ -124,10 +114,7 @@ interface DocsSearchHit {
124
114
  };
125
115
  }
126
116
  export declare function searchTokens(query: string): string[];
127
- /**
128
- * Title, headings and body text of one page. Heading ids follow `gbt-markdown-view`: `user-content-<slug>` on every
129
- * h1–h4, and `-2`, `-3`… on a repeated slug in document order.
130
- */
117
+ /** Title, headings and text of a page. Heading ids must match gbt-markdown-view's (`-2`, `-3` on repeats). */
131
118
  export declare function parseDocsPage(markdown: string): {
132
119
  headings: {
133
120
  id: string;
@@ -136,9 +123,8 @@ export declare function parseDocsPage(markdown: string): {
136
123
  body: string;
137
124
  };
138
125
  /**
139
- * Search over the whole documentation, in the browser. Nothing is fetched until the first search (or `prepare()`),
140
- * then every page once, kept by `DocsService`. Every word of the query must appear in the page; a word in the title
141
- * ranks higher than one in a heading, and a heading higher than the text.
126
+ * Searches every page in the browser, fetching them on first use. All words must match; title beats heading beats
127
+ * text.
142
128
  */
143
129
  export declare class DocsSearchService {
144
130
  private docs;
@@ -150,21 +136,11 @@ export declare class DocsSearchService {
150
136
  static ɵfac: i0.ɵɵFactoryDeclaration<DocsSearchService, never>;
151
137
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
152
138
  }
153
- /**
154
- * The root opens the first page of the index. If the index can't be read or is empty, the reader shows that itself,
155
- * inside its own layout.
156
- */
139
+ /** Sends the root to the first page. A broken or empty index is left for the reader to show. */
157
140
  export declare const docsHomeGuard: CanActivateFn;
158
- /**
159
- * The reader's routes, to mount at the configured root: the root (to the first page), `<section>/<page>`, and any
160
- * other depth, which gets the reader's own "not found". `page` is the routed component that shows the reader (often
161
- * the app's own, wrapping `gbt-docs-page` in its layout).
162
- */
141
+ /** The reader's routes, for the configured root. `page` loads the component that shows it (often the app's). */
163
142
  export declare function docsRoutes(page: () => Promise<unknown>): Routes;
164
- /**
165
- * The documentation's left column: the search field, then every section with its pages. Only the current section
166
- * starts open. On a narrow layout the sections fold behind a toggle and the search stays.
167
- */
143
+ /** The left column: search, then the sections and their pages, only the current one open. */
168
144
  export declare class DocsNav {
169
145
  index: import("@angular/core").InputSignal<DocsIndex>;
170
146
  section: import("@angular/core").InputSignal<string | null>;
@@ -218,18 +194,12 @@ export declare function headingSlug(text: string): string;
218
194
  export declare function decodeFragment(rawFragment: string): string;
219
195
  /** The element a `#fragment` points at: the plain `id`, else the `user-content-` id or `<a name>` the sanitiser made. */
220
196
  export declare function findAnchorTarget(root: HTMLElement, rawFragment: string): HTMLElement | null;
221
- /**
222
- * A long code block or a wide table scrolls sideways, which a keyboard can only do once it takes the focus (WCAG
223
- * 2.1.1): each one becomes a named stop in the tab order. A table keeps its own role and gets only the stop and the
224
- * name.
225
- */
197
+ /** A keyboard only scrolls a wide code block or table it has focused (WCAG 2.1.1): each gets a tab stop. */
226
198
  export declare function makeScrollableBlocksFocusable(container: HTMLElement, names: {
227
199
  codeBlock: string;
228
200
  table: string;
229
201
  }): void;
230
- /**
231
- * A task-list checkbox is named by its item's text, so a screen reader says what is done or still to do.
232
- */
202
+ /** Names each task-list checkbox after its item, so a screen reader says what's done. */
233
203
  export declare function nameTaskCheckboxes(container: HTMLElement): void;
234
204
  /**
235
205
  * Markdown rendered to sanitised HTML, with the reading styles of the design system: headings, lists, code, tables,
@@ -239,10 +209,7 @@ export declare class MarkdownView {
239
209
  content: import("@angular/core").InputSignal<string>;
240
210
  /** Levels added to every heading (up to h6), so a `# Title` under the page's own headings keeps the outline. */
241
211
  headingOffset: import("@angular/core").InputSignal<number>;
242
- /**
243
- * Links under this prefix (`/docs` → `/docs/install/configuration#variables`) go through the router instead of
244
- * reloading the app. Off by default: a link in a README is left to the browser.
245
- */
212
+ /** Links under this prefix (say `/docs`) go through the router instead of reloading the app. Off by default. */
246
213
  routedLinkPrefix: import("@angular/core").InputSignal<string | null>;
247
214
  /** The h2–h4 headings, emitted after each render once their ids are in the DOM. */
248
215
  outline: import("@angular/core").OutputEmitterRef<MarkdownOutlineEntry[]>;
@@ -252,8 +219,8 @@ export declare class MarkdownView {
252
219
  private readonly container;
253
220
  constructor();
254
221
  /**
255
- * In-content `#anchor` links would resolve against `<base href="/">` and load the home page, so a plain left click
256
- * scrolls to the target inside this view and focuses it. Modified and middle clicks are left to the browser.
222
+ * A bare #anchor resolves against <base href="/"> and would load the home page, so a plain click scrolls here
223
+ * instead. Modified and middle clicks are the browser's.
257
224
  */
258
225
  protected onClick(event: MouseEvent): void;
259
226
  /** The `href` of a clicked in-content link under `routedLinkPrefix`, or `null` when the browser should follow it. */
@@ -292,11 +259,7 @@ type DocsView = {
292
259
  location: DocsLocation;
293
260
  content: string;
294
261
  };
295
- /**
296
- * One documentation page (`<root>/<section>/<page>`, read from the route): the navigation, the page with its
297
- * breadcrumb and neighbours, and on a wide screen the outline beside it. An unknown address gets a "not found" in the
298
- * same frame.
299
- */
262
+ /** The routed page with its nav, breadcrumb, neighbours and outline, or a "not found" in the same frame. */
300
263
  export declare class DocsPage {
301
264
  private readonly docs;
302
265
  private readonly route;
@@ -358,10 +321,7 @@ export declare class DocsSearch {
358
321
  }
359
322
  /** An outline is worth a panel from two headings on: one heading is no table of contents. */
360
323
  export declare function hasOutline(entries: readonly MarkdownOutlineEntry[]): boolean;
361
- /**
362
- * The "On this page" panel beside rendered Markdown. Each entry links to `#user-content-…` on the current URL; the
363
- * router does no anchor scrolling, so the click scrolls to the heading and focuses it itself.
364
- */
324
+ /** "On this page" for rendered Markdown. The router doesn't scroll to anchors, so a click does it here. */
365
325
  export declare class MarkdownOutline {
366
326
  entries: import("@angular/core").InputSignal<MarkdownOutlineEntry[]>;
367
327
  headingLevel: import("@angular/core").InputSignal<PanelHeadingLevel>;
@@ -2,7 +2,7 @@ import * as i0 from "@angular/core";
2
2
  import { ElementRef, InjectionToken, Injector, OnDestroy, PipeTransform, Provider, Signal, TemplateRef, WritableSignal } from "@angular/core";
3
3
  import { ControlValueAccessor, FormControl } from "@angular/forms";
4
4
  import { Observable } from "rxjs";
5
- export declare const GABARIT_VERSION = "1.4.0";
5
+ export declare const GABARIT_VERSION = "2.0.0";
6
6
  export declare class Icon {
7
7
  private readonly sanitizer;
8
8
  private readonly registry;
@@ -1064,10 +1064,7 @@ type InputSize = 'md' | 'sm';
1064
1064
  type InputInputmode = 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';
1065
1065
  type InputAutocapitalize = 'off' | 'none' | 'on' | 'sentences' | 'words' | 'characters';
1066
1066
  type InputEnterkeyhint = 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';
1067
- /**
1068
- * The field as the combobox of a list of suggestions it does not render itself: the caller owns the
1069
- * listbox, the keys (`(keydown)` on the host) and the active option.
1070
- */
1067
+ /** Makes the field the combobox of a suggestion list the caller renders, with its keys and active option. */
1071
1068
  interface InputCombobox {
1072
1069
  /** Whether the listbox is shown. */
1073
1070
  expanded: boolean;
@@ -4841,10 +4838,7 @@ export declare class ListCard {
4841
4838
  emptyMessage: import("@angular/core").InputSignal<string>;
4842
4839
  emptyIllustration: import("@angular/core").InputSignal<EmptyStateIllustration | null>;
4843
4840
  emptyIcon: import("@angular/core").InputSignal<string | null>;
4844
- /**
4845
- * What sits above the box: the projected `[list-card-header]` (ready), its placeholder (loading,
4846
- * unless `skeletonHeader` is off), or nothing (failed, empty).
4847
- */
4841
+ /** The projected header when ready, its placeholder while loading (unless skeletonHeader is off), else nothing. */
4848
4842
  protected readonly header: import("@angular/core").Signal<"slot" | "skeleton" | null>;
4849
4843
  protected readonly placeholders: import("@angular/core").Signal<string[]>;
4850
4844
  static ɵfac: i0.ɵɵFactoryDeclaration<ListCard, never>;