vintage-frames 0.1.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/LICENSE +21 -0
- package/README.md +262 -0
- package/custom-elements.json +19807 -0
- package/dist/_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js +9 -0
- package/dist/chrome.d.ts +73 -0
- package/dist/chrome.js +94 -0
- package/dist/components/vf-button-group.d.ts +50 -0
- package/dist/components/vf-button-group.js +68 -0
- package/dist/components/vf-button.d.ts +169 -0
- package/dist/components/vf-button.js +234 -0
- package/dist/components/vf-checkbox.d.ts +60 -0
- package/dist/components/vf-checkbox.js +135 -0
- package/dist/components/vf-container.d.ts +95 -0
- package/dist/components/vf-container.js +86 -0
- package/dist/components/vf-desktop.d.ts +243 -0
- package/dist/components/vf-desktop.js +310 -0
- package/dist/components/vf-dialog.d.ts +105 -0
- package/dist/components/vf-dialog.js +280 -0
- package/dist/components/vf-fieldset.d.ts +34 -0
- package/dist/components/vf-fieldset.js +76 -0
- package/dist/components/vf-grid.d.ts +124 -0
- package/dist/components/vf-grid.js +133 -0
- package/dist/components/vf-icon.d.ts +356 -0
- package/dist/components/vf-icon.js +507 -0
- package/dist/components/vf-img.d.ts +63 -0
- package/dist/components/vf-img.js +65 -0
- package/dist/components/vf-label.d.ts +117 -0
- package/dist/components/vf-label.js +151 -0
- package/dist/components/vf-list-item.d.ts +48 -0
- package/dist/components/vf-list-item.js +98 -0
- package/dist/components/vf-list.d.ts +77 -0
- package/dist/components/vf-list.js +256 -0
- package/dist/components/vf-menu-bar.d.ts +64 -0
- package/dist/components/vf-menu-bar.js +236 -0
- package/dist/components/vf-menu-item.d.ts +91 -0
- package/dist/components/vf-menu-item.js +252 -0
- package/dist/components/vf-menu.d.ts +95 -0
- package/dist/components/vf-menu.js +346 -0
- package/dist/components/vf-number-field.d.ts +60 -0
- package/dist/components/vf-number-field.js +248 -0
- package/dist/components/vf-option.d.ts +49 -0
- package/dist/components/vf-option.js +119 -0
- package/dist/components/vf-paragraph.d.ts +73 -0
- package/dist/components/vf-paragraph.js +66 -0
- package/dist/components/vf-progress-bar.d.ts +69 -0
- package/dist/components/vf-progress-bar.js +272 -0
- package/dist/components/vf-radio-group.d.ts +109 -0
- package/dist/components/vf-radio-group.js +105 -0
- package/dist/components/vf-radio.d.ts +59 -0
- package/dist/components/vf-radio.js +135 -0
- package/dist/components/vf-scroll-area.d.ts +75 -0
- package/dist/components/vf-scroll-area.js +124 -0
- package/dist/components/vf-select.d.ts +334 -0
- package/dist/components/vf-select.js +658 -0
- package/dist/components/vf-separator.d.ts +38 -0
- package/dist/components/vf-separator.js +55 -0
- package/dist/components/vf-slider.d.ts +80 -0
- package/dist/components/vf-slider.js +255 -0
- package/dist/components/vf-stack.d.ts +188 -0
- package/dist/components/vf-stack.js +168 -0
- package/dist/components/vf-swatch.d.ts +98 -0
- package/dist/components/vf-swatch.js +201 -0
- package/dist/components/vf-text-area.d.ts +77 -0
- package/dist/components/vf-text-area.js +121 -0
- package/dist/components/vf-text-field.d.ts +53 -0
- package/dist/components/vf-text-field.js +79 -0
- package/dist/components/vf-window.d.ts +157 -0
- package/dist/components/vf-window.js +377 -0
- package/dist/cursor-art.d.ts +37 -0
- package/dist/cursor-art.js +41 -0
- package/dist/cursor.d.ts +49 -0
- package/dist/cursor.js +171 -0
- package/dist/define.d.ts +45 -0
- package/dist/define.js +15 -0
- package/dist/document-listeners.d.ts +62 -0
- package/dist/document-listeners.js +29 -0
- package/dist/drag.d.ts +49 -0
- package/dist/drag.js +30 -0
- package/dist/events.d.ts +79 -0
- package/dist/events.js +25 -0
- package/dist/focus-modality.d.ts +94 -0
- package/dist/focus-modality.js +56 -0
- package/dist/form-control.d.ts +247 -0
- package/dist/form-control.js +127 -0
- package/dist/glyphs.d.ts +117 -0
- package/dist/glyphs.js +100 -0
- package/dist/grid-snap.d.ts +73 -0
- package/dist/grid-snap.js +135 -0
- package/dist/index.d.ts +145 -0
- package/dist/index.js +71 -0
- package/dist/menu-press.d.ts +60 -0
- package/dist/menu-press.js +97 -0
- package/dist/modal-dialog.d.ts +148 -0
- package/dist/modal-dialog.js +155 -0
- package/dist/motion.d.ts +72 -0
- package/dist/motion.js +22 -0
- package/dist/number.d.ts +24 -0
- package/dist/number.js +12 -0
- package/dist/open-art.d.ts +40 -0
- package/dist/open-art.js +35 -0
- package/dist/pixel-frame.d.ts +102 -0
- package/dist/pixel-frame.js +77 -0
- package/dist/popup-overflow.d.ts +157 -0
- package/dist/popup-overflow.js +45 -0
- package/dist/position.d.ts +187 -0
- package/dist/position.js +74 -0
- package/dist/scale.d.ts +259 -0
- package/dist/scale.js +133 -0
- package/dist/scroll-rail.d.ts +112 -0
- package/dist/scroll-rail.js +194 -0
- package/dist/scroll-state.d.ts +113 -0
- package/dist/scroll-state.js +55 -0
- package/dist/size.d.ts +47 -0
- package/dist/size.js +30 -0
- package/dist/styles/base.d.ts +38 -0
- package/dist/styles/body-font.d.ts +7 -0
- package/dist/styles/body-font.js +9 -0
- package/dist/styles/display-font.d.ts +7 -0
- package/dist/styles/display-font.js +9 -0
- package/dist/styles/recipes/body-face.d.ts +14 -0
- package/dist/styles/recipes/body-face.js +6 -0
- package/dist/styles/recipes/display-face.d.ts +23 -0
- package/dist/styles/recipes/display-face.js +10 -0
- package/dist/styles/recipes/field.d.ts +20 -0
- package/dist/styles/recipes/field.js +68 -0
- package/dist/styles/recipes/focus.d.ts +76 -0
- package/dist/styles/recipes/focus.js +39 -0
- package/dist/styles/recipes/host.d.ts +5 -0
- package/dist/styles/recipes/host.js +62 -0
- package/dist/styles/recipes/pattern.d.ts +80 -0
- package/dist/styles/recipes/pattern.js +82 -0
- package/dist/styles/recipes/scroll-rail.d.ts +69 -0
- package/dist/styles/recipes/scroll-rail.js +222 -0
- package/dist/styles/recipes/shadow.d.ts +13 -0
- package/dist/styles/recipes/shadow.js +5 -0
- package/dist/styles/recipes/static-text.d.ts +24 -0
- package/dist/styles/recipes/static-text.js +17 -0
- package/dist/styles/recipes/surface.d.ts +28 -0
- package/dist/styles/recipes/surface.js +27 -0
- package/dist/styles/recipes/tile.d.ts +122 -0
- package/dist/styles/recipes/tile.js +40 -0
- package/dist/styles/recipes/title-bar.d.ts +49 -0
- package/dist/styles/recipes/title-bar.js +134 -0
- package/dist/styles/recipes/toggle.d.ts +10 -0
- package/dist/styles/recipes/toggle.js +20 -0
- package/dist/styles/register-embedded-font.d.ts +64 -0
- package/dist/styles/register-embedded-font.js +30 -0
- package/dist/text-control.d.ts +131 -0
- package/dist/text-control.js +83 -0
- package/dist/tile-grid.d.ts +111 -0
- package/dist/tile-grid.js +53 -0
- package/dist/toggle-control.d.ts +60 -0
- package/dist/toggle-control.js +41 -0
- package/dist/track-width.d.ts +42 -0
- package/dist/track-width.js +30 -0
- package/dist/type-ahead.d.ts +35 -0
- package/dist/type-ahead.js +20 -0
- package/dist/zoom.d.ts +204 -0
- package/dist/zoom.js +105 -0
- package/docs/SPEC.md +2471 -0
- package/editor/vscode.html-custom-data.json +1320 -0
- package/editor/web-types.json +3237 -0
- package/package.json +118 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which input modality last drove the page — the signal a control consults to
|
|
3
|
+
* decide whether an incoming focus deserves a visible focus mark.
|
|
4
|
+
*
|
|
5
|
+
* `:focus-visible` answers that question for every control in the kit except
|
|
6
|
+
* the editable fields. The selector is specified to match ANY focus of an
|
|
7
|
+
* element that takes keyboard input, so a text field clicked with the mouse
|
|
8
|
+
* matches it exactly as a tabbed-to one does — unlike a button, which matches
|
|
9
|
+
* only from the keyboard (`npm run verify:focus` asserts both halves). That is
|
|
10
|
+
* the right default for a browser drawing a ring nobody asked for on a field
|
|
11
|
+
* with no other focus affordance. It is the wrong one here, where a click has
|
|
12
|
+
* already put the insertion point on screen and the kit draws its own mark.
|
|
13
|
+
*
|
|
14
|
+
* Why the document, rather than latching the field's own `pointerdown` the way
|
|
15
|
+
* `vf-slider` does for its ring: the pointer event that lands focus in a field
|
|
16
|
+
* is routinely not on the field. A `vf-label` `for` caption focuses its control
|
|
17
|
+
* from a click on the caption, and all the field sees is a programmatic
|
|
18
|
+
* `focus()` — locally indistinguishable from Tab. Watching the page catches
|
|
19
|
+
* that, and any other control that focuses a field on the user's behalf.
|
|
20
|
+
*
|
|
21
|
+
* The default is `'keyboard'`: focus that arrives with no preceding input at
|
|
22
|
+
* all is assistive tech, an `autofocus`, or a script, and all three should be
|
|
23
|
+
* marked. Only an observed pointer suppresses the mark.
|
|
24
|
+
*/
|
|
25
|
+
import type { LitElement, ReactiveController } from 'lit';
|
|
26
|
+
export type FocusModality = 'keyboard' | 'pointer';
|
|
27
|
+
/** The modality that last drove the page. `'keyboard'` until a pointer says otherwise. */
|
|
28
|
+
export declare function focusModality(): FocusModality;
|
|
29
|
+
/**
|
|
30
|
+
* Start watching the page's input modality; returns the release function.
|
|
31
|
+
*
|
|
32
|
+
* The two listeners are shared by every watcher and refcounted, so a page full
|
|
33
|
+
* of fields adds one capture-phase `pointerdown` and one `keydown` to the
|
|
34
|
+
* document, not one pair each. Both are passive and read-only — they set a
|
|
35
|
+
* variable and nothing else. Releasing the last watcher removes them, so a kit
|
|
36
|
+
* torn off a page leaves nothing behind (calling the release twice is a no-op).
|
|
37
|
+
*
|
|
38
|
+
* Capture phase, because the modality has to be recorded before the focus it
|
|
39
|
+
* explains: a `pointerdown` that a control stops from bubbling still moved the
|
|
40
|
+
* focus, and a `keydown` on the element being tabbed away from is the thing
|
|
41
|
+
* that makes the next focus a keyboard one.
|
|
42
|
+
*
|
|
43
|
+
* Both handlers assign one variable and do nothing else — no DOM reads, no
|
|
44
|
+
* `preventDefault` (a passive listener could not anyway), no
|
|
45
|
+
* `stopPropagation` — so a host page's own handlers see every event exactly as
|
|
46
|
+
* they would without the kit. The one way a page can defeat the tracker is to
|
|
47
|
+
* stop these events before the document sees them, e.g. a window-capture
|
|
48
|
+
* listener calling `stopPropagation()`. The modality then goes stale and a
|
|
49
|
+
* field may wear its mark after a click: the failure mode is a focus rule
|
|
50
|
+
* shown too eagerly, never an exception or a swallowed event.
|
|
51
|
+
*/
|
|
52
|
+
export declare function trackFocusModality(): () => void;
|
|
53
|
+
/**
|
|
54
|
+
* Whether a control should be wearing the kit's dashed focus rule right now:
|
|
55
|
+
* {@link focusModality} resolved against the host's own focus, as one reactive
|
|
56
|
+
* flag.
|
|
57
|
+
*
|
|
58
|
+
* Four controls need this rather than `:focus-visible`, for two different
|
|
59
|
+
* reasons (SPEC §4). The editable fields, because that selector is specified to
|
|
60
|
+
* match *any* focus of an element which takes keyboard input, so it is already
|
|
61
|
+
* true for a clicked text field. And the three that suppress the browser's own
|
|
62
|
+
* mouse focus so a press-drag gesture can own the pointer — `vf-select`,
|
|
63
|
+
* `vf-menu`, `vf-slider` — then call `focus()` themselves, which Blink reads as
|
|
64
|
+
* a *visible* focus, making `:focus-visible` true after a pure mouse gesture.
|
|
65
|
+
* One controller so the answer can't drift between them.
|
|
66
|
+
*
|
|
67
|
+
* `focusin`/`focusout`, not `focus`/`blur`: the focus usually lands on an
|
|
68
|
+
* element inside the shadow root, and only the bubbling, composed pair crosses
|
|
69
|
+
* that boundary to reach the host. Focus moving *within* the component — a
|
|
70
|
+
* `vf-select` pill handing off to its option rows, a `vf-menu` title to its
|
|
71
|
+
* dropped panel — is not leaving, so the mark survives it and the host takes it
|
|
72
|
+
* back when the panel closes.
|
|
73
|
+
*/
|
|
74
|
+
export declare class FocusRuleController implements ReactiveController {
|
|
75
|
+
#private;
|
|
76
|
+
private readonly host;
|
|
77
|
+
constructor(host: LitElement);
|
|
78
|
+
/** True while the host's focus should be marked. */
|
|
79
|
+
get marked(): boolean;
|
|
80
|
+
hostConnected(): void;
|
|
81
|
+
hostDisconnected(): void;
|
|
82
|
+
/**
|
|
83
|
+
* Force the mark on: the keyboard just drove the control, whatever put the
|
|
84
|
+
* focus there. `vf-slider` calls this from a handled arrow key, so a slider
|
|
85
|
+
* clicked and then nudged with the keys starts showing its rule.
|
|
86
|
+
*/
|
|
87
|
+
reveal(): void;
|
|
88
|
+
/**
|
|
89
|
+
* Force the mark off. A pointer press on an ALREADY-focused control moves no
|
|
90
|
+
* focus and so fires no `focusin` — the one pointer route this controller
|
|
91
|
+
* cannot see for itself.
|
|
92
|
+
*/
|
|
93
|
+
suppress(): void;
|
|
94
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
//#region src/focus-modality.ts
|
|
2
|
+
var e = "keyboard", t = 0, n = () => {
|
|
3
|
+
e = "pointer";
|
|
4
|
+
}, r = () => {
|
|
5
|
+
e = "keyboard";
|
|
6
|
+
};
|
|
7
|
+
function i() {
|
|
8
|
+
return e;
|
|
9
|
+
}
|
|
10
|
+
function a() {
|
|
11
|
+
t++ === 0 && (document.addEventListener("pointerdown", n, {
|
|
12
|
+
capture: !0,
|
|
13
|
+
passive: !0
|
|
14
|
+
}), document.addEventListener("keydown", r, {
|
|
15
|
+
capture: !0,
|
|
16
|
+
passive: !0
|
|
17
|
+
}));
|
|
18
|
+
let e = !1;
|
|
19
|
+
return () => {
|
|
20
|
+
e || (e = !0, --t === 0 && (document.removeEventListener("pointerdown", n, { capture: !0 }), document.removeEventListener("keydown", r, { capture: !0 })));
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
var o = class {
|
|
24
|
+
#e = !1;
|
|
25
|
+
#t;
|
|
26
|
+
constructor(e) {
|
|
27
|
+
this.host = e, e.addController(this);
|
|
28
|
+
}
|
|
29
|
+
get marked() {
|
|
30
|
+
return this.#e;
|
|
31
|
+
}
|
|
32
|
+
hostConnected() {
|
|
33
|
+
this.#t = a(), this.host.addEventListener("focusin", this.#r), this.host.addEventListener("focusout", this.#i);
|
|
34
|
+
}
|
|
35
|
+
hostDisconnected() {
|
|
36
|
+
this.host.removeEventListener("focusin", this.#r), this.host.removeEventListener("focusout", this.#i), this.#t?.(), this.#t = void 0, this.#n(!1);
|
|
37
|
+
}
|
|
38
|
+
reveal() {
|
|
39
|
+
this.#n(!0);
|
|
40
|
+
}
|
|
41
|
+
suppress() {
|
|
42
|
+
this.#n(!1);
|
|
43
|
+
}
|
|
44
|
+
#n(e) {
|
|
45
|
+
e !== this.#e && (this.#e = e, this.host.requestUpdate());
|
|
46
|
+
}
|
|
47
|
+
#r = () => {
|
|
48
|
+
this.#n(e === "keyboard");
|
|
49
|
+
};
|
|
50
|
+
#i = (e) => {
|
|
51
|
+
let t = e.relatedTarget;
|
|
52
|
+
t instanceof Node && (this.host.contains(t) || this.host.renderRoot.contains(t)) || this.#n(!1);
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
//#endregion
|
|
56
|
+
export { o as FocusRuleController, i as focusModality, a as trackFocusModality };
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { LitElement, nothing, type PropertyValues } from 'lit';
|
|
2
|
+
/**
|
|
3
|
+
* Shared base for the kit's form-associated controls (SPEC §4).
|
|
4
|
+
*
|
|
5
|
+
* Owns the boilerplate every one of them repeated: the `ElementInternals`
|
|
6
|
+
* handle, the reflected `disabled` property, the `formDisabled` state fed by
|
|
7
|
+
* `formDisabledCallback` (an ancestor `<fieldset disabled>`), the resolved
|
|
8
|
+
* {@link isDisabled} getter, the form-reset default latch
|
|
9
|
+
* ({@link latchFormDefault} / {@link formDefault}), and — crucially — the
|
|
10
|
+
* disabled-guarded {@link syncFormValue} funnel every subclass routes its
|
|
11
|
+
* `setFormValue` through, so a disabled control can never leak a value into
|
|
12
|
+
* submission.
|
|
13
|
+
*
|
|
14
|
+
* Subclasses supply their own value semantics, ARIA and (where needed) a
|
|
15
|
+
* `formResetCallback` restoring their captured default.
|
|
16
|
+
*/
|
|
17
|
+
export declare class VfFormControl extends LitElement {
|
|
18
|
+
#private;
|
|
19
|
+
/** Participates in native forms via ElementInternals. */
|
|
20
|
+
static formAssociated: boolean;
|
|
21
|
+
/** Form + ARIA internals; attached once here for every subclass. */
|
|
22
|
+
protected readonly internals: ElementInternals;
|
|
23
|
+
/**
|
|
24
|
+
* Disables the control: it stops responding and submits no value. Each
|
|
25
|
+
* control dims per SPEC §1 (typically the label greys while the 1-bit chrome
|
|
26
|
+
* stays black).
|
|
27
|
+
*/
|
|
28
|
+
disabled: boolean;
|
|
29
|
+
/** True while an ancestor `<fieldset disabled>` disables this control. */
|
|
30
|
+
protected formDisabled: boolean;
|
|
31
|
+
/** Effective disabled state: the `disabled` prop OR an ancestor fieldset. */
|
|
32
|
+
get isDisabled(): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Form-associated lifecycle: the browser calls this when this control's
|
|
35
|
+
* disabled state changes — an ancestor `<fieldset disabled>`, or the
|
|
36
|
+
* element's OWN `disabled` attribute (the browser counts both).
|
|
37
|
+
*
|
|
38
|
+
* Also mirrored as the `form-disabled` custom state: `disabled` reflects as
|
|
39
|
+
* an attribute a stylesheet can see, but a `<fieldset disabled>` ancestor
|
|
40
|
+
* lands here in otherwise-private state — `:state(form-disabled)` is the
|
|
41
|
+
* one selector that lets consumer CSS style that case. Optional-chained for
|
|
42
|
+
* engines without `CustomStateSet`.
|
|
43
|
+
*/
|
|
44
|
+
formDisabledCallback(disabled: boolean): void;
|
|
45
|
+
/**
|
|
46
|
+
* Form-associated lifecycle: the browser hands back state it stored for
|
|
47
|
+
* this control — a bfcache/session restore, or a browser autofill pass.
|
|
48
|
+
* The kit's controls all submit through single-argument `setFormValue`, so
|
|
49
|
+
* the stored state IS the last submitted string. Without this callback,
|
|
50
|
+
* every native input in the form repopulates on restore while the `vf-*`
|
|
51
|
+
* controls silently keep their defaults.
|
|
52
|
+
*/
|
|
53
|
+
formStateRestoreCallback(state: string | File | FormData | null, _mode: 'restore' | 'autofill'): void;
|
|
54
|
+
/**
|
|
55
|
+
* Maps stored form state back onto the control's own value semantics. The
|
|
56
|
+
* default covers the string-valued majority (the fields, `vf-select`,
|
|
57
|
+
* `vf-radio-group`); `vf-checkbox` (a checked flag) and `vf-slider` (a
|
|
58
|
+
* number) override.
|
|
59
|
+
*/
|
|
60
|
+
protected applyFormState(state: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* Submit `value` under the control's `name` — unless the control is disabled,
|
|
63
|
+
* in which case nothing is submitted (SPEC §4). The single guarded funnel for
|
|
64
|
+
* every subclass's form value, so the disabled contract holds in one place.
|
|
65
|
+
*/
|
|
66
|
+
protected syncFormValue(value: string | File | FormData | null): void;
|
|
67
|
+
/**
|
|
68
|
+
* Requires a value before the associated form submits (SPEC §4): an empty
|
|
69
|
+
* control fails constraint validation with `valueMissing`, exactly like a
|
|
70
|
+
* native `required`. What "empty" means is each control's own
|
|
71
|
+
* {@link valueMissing}; a control with no required semantics (a slider
|
|
72
|
+
* always has a value, a swatch submits nothing) never fails it, the way a
|
|
73
|
+
* native range input never does.
|
|
74
|
+
*/
|
|
75
|
+
required: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Installs a custom validity message — the native channel: a non-empty
|
|
78
|
+
* string makes the control invalid with exactly that message, `''` clears
|
|
79
|
+
* it.
|
|
80
|
+
*/
|
|
81
|
+
setCustomValidity(message: string): void;
|
|
82
|
+
/** The control's current `ValidityState`, as on a native control. */
|
|
83
|
+
get validity(): ValidityState;
|
|
84
|
+
/** The message of the currently failing constraint, `''` while valid. */
|
|
85
|
+
get validationMessage(): string;
|
|
86
|
+
/**
|
|
87
|
+
* Whether the control is a candidate for constraint validation — false
|
|
88
|
+
* while disabled or readonly, per HTML's barring rules (the browser
|
|
89
|
+
* computes this from the reflected attributes).
|
|
90
|
+
*/
|
|
91
|
+
get willValidate(): boolean;
|
|
92
|
+
/** True when the control satisfies its constraints; fires `invalid` if not. */
|
|
93
|
+
checkValidity(): boolean;
|
|
94
|
+
/** {@link checkValidity} plus the browser's own error UI on failure. */
|
|
95
|
+
reportValidity(): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Whether the control is empty for `required`'s purposes. Overridden by the
|
|
98
|
+
* controls a value can be missing from — `value === ''` on the fields, the
|
|
99
|
+
* select and the radio group, unchecked on the checkbox. The default never
|
|
100
|
+
* fails, which is what makes a bare `required` inert on the rest.
|
|
101
|
+
*/
|
|
102
|
+
protected get valueMissing(): boolean;
|
|
103
|
+
/** The `valueMissing` message; subclasses match their native counterpart's. */
|
|
104
|
+
protected get valueMissingMessage(): string;
|
|
105
|
+
/**
|
|
106
|
+
* The single funnel every validity write goes through — the
|
|
107
|
+
* {@link syncFormValue} shape, one place for the contract: the flags are
|
|
108
|
+
* computed from the live properties (`required` × {@link valueMissing},
|
|
109
|
+
* plus any custom error) and installed with `setValidity`, so `:invalid`
|
|
110
|
+
* matches on the host and `form.reportValidity()` blocks exactly as it
|
|
111
|
+
* would on a native control. Runs from {@link willUpdate}, before render,
|
|
112
|
+
* so the same update's template reads fresh validity. Also mirrors
|
|
113
|
+
* `aria-required`/`aria-invalid` through internals for the controls whose
|
|
114
|
+
* role sits on the host — internals lose to a consumer's own host
|
|
115
|
+
* attribute, which is the correct precedence direction.
|
|
116
|
+
*/
|
|
117
|
+
protected syncValidity(): void;
|
|
118
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
119
|
+
/**
|
|
120
|
+
* Capture the control's form-reset default. Only the first call latches, so
|
|
121
|
+
* lifecycle paths that can run more than once — reconnects, repeated
|
|
122
|
+
* slotchanges — may call it unconditionally. WHEN to call it is each
|
|
123
|
+
* control's own contract: most latch on first connect, `vf-select` waits
|
|
124
|
+
* until options exist, `vf-radio-group` lets a pre-checked radio adopted on
|
|
125
|
+
* slotchange claim an unauthored default.
|
|
126
|
+
*/
|
|
127
|
+
protected latchFormDefault(value: unknown): void;
|
|
128
|
+
/**
|
|
129
|
+
* The latched form-reset default, or `fallback` while nothing has latched.
|
|
130
|
+
* The cast is sound because a control only ever latches its own value type.
|
|
131
|
+
*/
|
|
132
|
+
protected formDefault<T>(fallback: T): T;
|
|
133
|
+
/**
|
|
134
|
+
* True when this update changed the *resolved* disabled state — the gate a
|
|
135
|
+
* subclass's `updated()` should use before re-running its form value, ARIA
|
|
136
|
+
* or tab-stop writes.
|
|
137
|
+
*
|
|
138
|
+
* It exists because {@link formDisabled} is protected, so `keyof this` can't
|
|
139
|
+
* name it and a `PropertyValues<this>` gate silently can't test for it: a
|
|
140
|
+
* `changed.has('disabled')` check compiles, reads as complete, and misses
|
|
141
|
+
* every ancestor `<fieldset disabled>` — which is the path that must clear a
|
|
142
|
+
* control's submitted value. One named predicate keeps that trap in one
|
|
143
|
+
* place instead of in each subclass's gate.
|
|
144
|
+
*/
|
|
145
|
+
protected disabledChanged(changed: PropertyValues): boolean;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* {@link VfFormControl} plus the name/description bridge, for the controls
|
|
149
|
+
* whose **role sits on a shadow-internal node** — `vf-button`, `vf-select`,
|
|
150
|
+
* `vf-swatch`, and the three fields via `VfTextControlBase` (SPEC §4).
|
|
151
|
+
*
|
|
152
|
+
* That one structural fact is the whole membership rule. On those controls the
|
|
153
|
+
* host is a generic wrapper AccName never consults, and a host-level IDREF
|
|
154
|
+
* cannot reach into a shadow tree, so the platform's own words — `aria-label`,
|
|
155
|
+
* `aria-labelledby`, `<label for>`, `aria-describedby` — land on nothing unless
|
|
156
|
+
* something resolves them to text and hands them inward. This class is that
|
|
157
|
+
* something.
|
|
158
|
+
*
|
|
159
|
+
* The controls whose role sits on the **host** (`vf-checkbox`,
|
|
160
|
+
* `vf-radio-group`, `vf-slider`) deliberately stay on the plain base: the
|
|
161
|
+
* platform reads their host attributes directly, so a bridge there would
|
|
162
|
+
* duplicate a working channel — and an inherited property that renders nothing
|
|
163
|
+
* is exactly the "advertised API that silently does nothing" this split exists
|
|
164
|
+
* to make impossible. `verify:manifest` holds the line: a tag whose manifest
|
|
165
|
+
* carries `description` must call {@link renderDescription} in its own source.
|
|
166
|
+
*/
|
|
167
|
+
export declare class VfShadowRoleControl extends VfFormControl {
|
|
168
|
+
/**
|
|
169
|
+
* The host-level ARIA attributes the bridge mirrors inward, observed so a
|
|
170
|
+
* consumer writing one after upgrade re-renders the control. They are
|
|
171
|
+
* deliberately not reactive properties: each has an IDL accessor on
|
|
172
|
+
* `Element` already, and a Lit `@property` would shadow the platform member
|
|
173
|
+
* (the kit's `align`/`draggable` trap) — so they are observed by name and
|
|
174
|
+
* read at render time, the `forwardedAttributes` shape.
|
|
175
|
+
*/
|
|
176
|
+
private static readonly bridgedAriaAttributes;
|
|
177
|
+
static get observedAttributes(): string[];
|
|
178
|
+
attributeChangedCallback(name: string, old: string | null, value: string | null): void;
|
|
179
|
+
/**
|
|
180
|
+
* Form-associated lifecycle: the association changed, so the `<label for>`
|
|
181
|
+
* set feeding {@link hostLabel} may have too — re-render whatever mirrors it.
|
|
182
|
+
*/
|
|
183
|
+
formAssociatedCallback(_form: HTMLFormElement | null): void;
|
|
184
|
+
/**
|
|
185
|
+
* The accessible name the *host* carries. A consumer's `aria-label`,
|
|
186
|
+
* `aria-labelledby` or `<label for>` used to be silently inert on these
|
|
187
|
+
* controls, so the bridge resolves them to text for the control to hand to
|
|
188
|
+
* its inner focusable element. The explicit `label` property still wins:
|
|
189
|
+
* templates read `this.label || this.hostLabel`.
|
|
190
|
+
*
|
|
191
|
+
* Precedence is html-aam's — `aria-labelledby`, then `aria-label`, then the
|
|
192
|
+
* associated `<label for>` elements (`internals.labels`). Referenced text is
|
|
193
|
+
* flattened at render time, so an edit to a referenced element's *text*
|
|
194
|
+
* lands on the control's next render rather than instantly — the one
|
|
195
|
+
* divergence from a native control, recorded in SPEC §4.
|
|
196
|
+
*/
|
|
197
|
+
protected get hostLabel(): string;
|
|
198
|
+
/**
|
|
199
|
+
* The ARIA half of {@link hostLabel} — `aria-labelledby`, then `aria-label`,
|
|
200
|
+
* in html-aam's order — without the `<label for>` leg.
|
|
201
|
+
*
|
|
202
|
+
* Split out because that leg does not apply to every control. A `<button>`
|
|
203
|
+
* is not a labelable element, so no caption names a native one and none
|
|
204
|
+
* should name a `vf-button` either (`verify:names` asserts that a `vf-label
|
|
205
|
+
* for=` leaves a button's own name alone). What a button DOES need is the
|
|
206
|
+
* other half: on a control whose role sits on a shadow-internal node, a
|
|
207
|
+
* consumer's `aria-label` is otherwise inert, because it lands on a generic
|
|
208
|
+
* host AccName never consults — so an icon button labelled the ordinary way
|
|
209
|
+
* was announced by its glyph.
|
|
210
|
+
*/
|
|
211
|
+
protected get hostAriaLabel(): string;
|
|
212
|
+
/**
|
|
213
|
+
* Description for the control — hint text, a format, a unit. A host-level
|
|
214
|
+
* `aria-describedby` cannot reach a focusable element inside a shadow root,
|
|
215
|
+
* so there was structurally no way to describe a field; this property is
|
|
216
|
+
* that channel. It renders as a hidden span in the control's own shadow root
|
|
217
|
+
* with the inner control's `aria-describedby` pointing at it — the
|
|
218
|
+
* shadow-internal IDREF idiom `vf-dialog`'s title patch already uses. A
|
|
219
|
+
* host-level `aria-describedby` is bridged into the same span when this
|
|
220
|
+
* property is empty, and a failing constraint's {@link validationMessage}
|
|
221
|
+
* joins it too, so AT hears the error where it hears the hint.
|
|
222
|
+
*
|
|
223
|
+
* Host-role controls get neither half: their `aria-describedby` already
|
|
224
|
+
* works, and their validation message reaches AT the way a native control's
|
|
225
|
+
* does — `aria-invalid` plus the browser's own validation UI, not AccName.
|
|
226
|
+
*/
|
|
227
|
+
description: string;
|
|
228
|
+
/**
|
|
229
|
+
* What {@link renderDescription}'s span carries: the current validation
|
|
230
|
+
* message while the control is invalid, then the description (the property,
|
|
231
|
+
* or the bridged host `aria-describedby` text).
|
|
232
|
+
*/
|
|
233
|
+
protected get descriptionText(): string;
|
|
234
|
+
/**
|
|
235
|
+
* `aria-describedby` value for the inner control — set only while the span
|
|
236
|
+
* has something to say, so an idle control isn't announced as described by
|
|
237
|
+
* nothing.
|
|
238
|
+
*/
|
|
239
|
+
protected get describedBy(): string | typeof nothing;
|
|
240
|
+
/**
|
|
241
|
+
* The hidden span the inner control's `aria-describedby` points at.
|
|
242
|
+
* `hidden` keeps it out of the page; AccName still resolves `display: none`
|
|
243
|
+
* reference targets (the fact vf-window's utility title patch leans on), so
|
|
244
|
+
* the text reaches AT without painting.
|
|
245
|
+
*/
|
|
246
|
+
protected renderDescription(): import("lit-html").TemplateResult<1> | typeof nothing;
|
|
247
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import e from "./_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
|
|
2
|
+
import { LitElement as t, html as n, nothing as r } from "lit";
|
|
3
|
+
import { property as i, state as a } from "lit/decorators.js";
|
|
4
|
+
//#region src/form-control.ts
|
|
5
|
+
function o(e, t) {
|
|
6
|
+
let n = e.getAttribute(t);
|
|
7
|
+
if (!n) return "";
|
|
8
|
+
let r = e.getRootNode();
|
|
9
|
+
return r instanceof Document || r instanceof ShadowRoot ? n.split(/\s+/).filter(Boolean).map((e) => r.getElementById(e)?.textContent?.trim() ?? "").filter(Boolean).join(" ") : "";
|
|
10
|
+
}
|
|
11
|
+
var s = class extends t {
|
|
12
|
+
constructor(...e) {
|
|
13
|
+
super(...e), this.internals = this.attachInternals(), this.disabled = !1, this.formDisabled = !1, this.required = !1, this.#e = "", this.#n = !1;
|
|
14
|
+
}
|
|
15
|
+
static {
|
|
16
|
+
this.formAssociated = !0;
|
|
17
|
+
}
|
|
18
|
+
get isDisabled() {
|
|
19
|
+
return this.disabled || this.formDisabled;
|
|
20
|
+
}
|
|
21
|
+
formDisabledCallback(e) {
|
|
22
|
+
let t = this.formDisabled !== e;
|
|
23
|
+
this.formDisabled = e, e ? this.internals.states?.add("form-disabled") : this.internals.states?.delete("form-disabled"), t && this.isUpdatePending && queueMicrotask(() => this.requestUpdate());
|
|
24
|
+
}
|
|
25
|
+
formStateRestoreCallback(e, t) {
|
|
26
|
+
typeof e == "string" && this.applyFormState(e);
|
|
27
|
+
}
|
|
28
|
+
applyFormState(e) {
|
|
29
|
+
this.value = e;
|
|
30
|
+
}
|
|
31
|
+
syncFormValue(e) {
|
|
32
|
+
this.internals.setFormValue(this.isDisabled ? null : e);
|
|
33
|
+
}
|
|
34
|
+
#e;
|
|
35
|
+
setCustomValidity(e) {
|
|
36
|
+
this.#e = e, this.syncValidity(), this.requestUpdate();
|
|
37
|
+
}
|
|
38
|
+
get validity() {
|
|
39
|
+
return this.internals.validity;
|
|
40
|
+
}
|
|
41
|
+
get validationMessage() {
|
|
42
|
+
return this.internals.validationMessage;
|
|
43
|
+
}
|
|
44
|
+
get willValidate() {
|
|
45
|
+
return this.internals.willValidate;
|
|
46
|
+
}
|
|
47
|
+
checkValidity() {
|
|
48
|
+
return this.internals.checkValidity();
|
|
49
|
+
}
|
|
50
|
+
reportValidity() {
|
|
51
|
+
return this.internals.reportValidity();
|
|
52
|
+
}
|
|
53
|
+
get valueMissing() {
|
|
54
|
+
return !1;
|
|
55
|
+
}
|
|
56
|
+
get valueMissingMessage() {
|
|
57
|
+
return "Please fill out this field.";
|
|
58
|
+
}
|
|
59
|
+
syncValidity() {
|
|
60
|
+
let e = this.required && this.valueMissing, t = this.#e || (e ? this.valueMissingMessage : "");
|
|
61
|
+
this.internals.setValidity({
|
|
62
|
+
customError: this.#e !== "",
|
|
63
|
+
valueMissing: e
|
|
64
|
+
}, t || void 0), this.internals.ariaRequired = this.required ? "true" : null, this.internals.ariaInvalid = this.internals.validity.valid ? null : "true";
|
|
65
|
+
}
|
|
66
|
+
willUpdate(e) {
|
|
67
|
+
super.willUpdate(e), this.syncValidity();
|
|
68
|
+
}
|
|
69
|
+
#t;
|
|
70
|
+
#n;
|
|
71
|
+
latchFormDefault(e) {
|
|
72
|
+
this.#n || (this.#n = !0, this.#t = e);
|
|
73
|
+
}
|
|
74
|
+
formDefault(e) {
|
|
75
|
+
return this.#n ? this.#t : e;
|
|
76
|
+
}
|
|
77
|
+
disabledChanged(e) {
|
|
78
|
+
return e.has("disabled") || e.has("formDisabled");
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
e([i({
|
|
82
|
+
type: Boolean,
|
|
83
|
+
reflect: !0
|
|
84
|
+
})], s.prototype, "disabled", void 0), e([a()], s.prototype, "formDisabled", void 0), e([i({
|
|
85
|
+
type: Boolean,
|
|
86
|
+
reflect: !0
|
|
87
|
+
})], s.prototype, "required", void 0);
|
|
88
|
+
var c = class e extends s {
|
|
89
|
+
constructor(...e) {
|
|
90
|
+
super(...e), this.description = "";
|
|
91
|
+
}
|
|
92
|
+
static {
|
|
93
|
+
this.bridgedAriaAttributes = [
|
|
94
|
+
"aria-label",
|
|
95
|
+
"aria-labelledby",
|
|
96
|
+
"aria-describedby"
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
static get observedAttributes() {
|
|
100
|
+
return [...super.observedAttributes, ...e.bridgedAriaAttributes];
|
|
101
|
+
}
|
|
102
|
+
attributeChangedCallback(t, n, r) {
|
|
103
|
+
super.attributeChangedCallback(t, n, r), e.bridgedAriaAttributes.includes(t) && this.requestUpdate();
|
|
104
|
+
}
|
|
105
|
+
formAssociatedCallback(e) {
|
|
106
|
+
this.requestUpdate();
|
|
107
|
+
}
|
|
108
|
+
get hostLabel() {
|
|
109
|
+
return this.hostAriaLabel || [...this.internals.labels].map((e) => e.textContent?.trim() ?? "").filter(Boolean).join(" ");
|
|
110
|
+
}
|
|
111
|
+
get hostAriaLabel() {
|
|
112
|
+
return o(this, "aria-labelledby") || this.getAttribute("aria-label")?.trim() || "";
|
|
113
|
+
}
|
|
114
|
+
get descriptionText() {
|
|
115
|
+
return [this.internals.validity.valid ? "" : this.internals.validationMessage, this.description || o(this, "aria-describedby")].filter(Boolean).join(" ");
|
|
116
|
+
}
|
|
117
|
+
get describedBy() {
|
|
118
|
+
return this.descriptionText ? "description" : r;
|
|
119
|
+
}
|
|
120
|
+
renderDescription() {
|
|
121
|
+
let e = this.descriptionText;
|
|
122
|
+
return e ? n`<span id="description" hidden>${e}</span>` : r;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
e([i()], c.prototype, "description", void 0);
|
|
126
|
+
//#endregion
|
|
127
|
+
export { s as VfFormControl, c as VfShadowRoleControl };
|
package/dist/glyphs.d.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { TemplateResult } from 'lit';
|
|
2
|
+
/**
|
|
3
|
+
* Pixel-exact 1-bit glyphs. Each glyph's `d` is a run-length-merged fill path
|
|
4
|
+
* on the System 7 pixel grid, one rectangle per run of ink. Rendered at its
|
|
5
|
+
* native pixel size (or an integer multiple) with `shape-rendering: crispEdges`
|
|
6
|
+
* it is pixel-exact — so consumers MUST size the SVG to `w`×`h` px (or a whole
|
|
7
|
+
* multiple), never a fractional scale, or the 1-bit edges snap unevenly to the
|
|
8
|
+
* device grid. It inherits `currentColor` (fully themeable) and ships as inline
|
|
9
|
+
* SVG — no external raster assets, matching the library's zero-CSS,
|
|
10
|
+
* `var(--vf-*)`-themeable design (see SPEC §1).
|
|
11
|
+
*
|
|
12
|
+
* This file is the authoritative source for these marks (the glyph-sprites note
|
|
13
|
+
* at the top of SPEC.md). They replace the earlier anti-aliased approximations
|
|
14
|
+
* (the checkbox ✕ was a 1.5px SVG stroke; the radio was a `border-radius: 50%`
|
|
15
|
+
* box; the menu ✓ was a font-dependent Unicode character; the popup ▼ was a
|
|
16
|
+
* CSS-border triangle) with the exact System 7 pixel shapes.
|
|
17
|
+
*/
|
|
18
|
+
export interface Glyph {
|
|
19
|
+
/** Native grid width (viewBox units = source-sprite pixels). */
|
|
20
|
+
readonly w: number;
|
|
21
|
+
/** Native grid height. */
|
|
22
|
+
readonly h: number;
|
|
23
|
+
/** SVG path data (a union of 1×N pixel-run rectangles). */
|
|
24
|
+
readonly d: string;
|
|
25
|
+
}
|
|
26
|
+
/** Checkbox ✕ — the interior corner-to-corner cross (`check Selected=True`). */
|
|
27
|
+
export declare const CHECKBOX_X: Glyph;
|
|
28
|
+
/** Radio solid disc — the white control face under the ring (`radio` outline, flood-filled). */
|
|
29
|
+
export declare const RADIO_FACE: Glyph;
|
|
30
|
+
/** Radio ring — the 1px pixel circle outline (`radio Selected=False`). */
|
|
31
|
+
export declare const RADIO_RING: Glyph;
|
|
32
|
+
/** Radio ring, pressed — the 2px-thick outline (`radio State=Press`). */
|
|
33
|
+
export declare const RADIO_RING_PRESSED: Glyph;
|
|
34
|
+
/** Radio dot — the centered pixel disc shown when selected (`radio Selected=True` minus ring). */
|
|
35
|
+
export declare const RADIO_DOT: Glyph;
|
|
36
|
+
/** Menu / popup ✓ checkmark (`Symbols/Check.png`). */
|
|
37
|
+
export declare const CHECKMARK: Glyph;
|
|
38
|
+
/**
|
|
39
|
+
* Popup-menu ▼ caret (`Symbols/Caret Down.png`).
|
|
40
|
+
*
|
|
41
|
+
* Also the *scroll* arrow a clipped popup shows in its bottom row slot: a
|
|
42
|
+
* screenshot of a real System 7 popup overflowing the screen (Find File's
|
|
43
|
+
* criteria menu, captured under Infinite Mac at 2×) puts a 22×12 device-pixel
|
|
44
|
+
* triangle there, which is this exact 11×6 shape — the popup's own ▼
|
|
45
|
+
* vocabulary, reused rather than a second arrow art.
|
|
46
|
+
*/
|
|
47
|
+
export declare const CARET_DOWN: Glyph;
|
|
48
|
+
/**
|
|
49
|
+
* The ▲ a clipped popup shows in its *top* row slot — {@link CARET_DOWN}
|
|
50
|
+
* mirrored vertically (the shape is left-right symmetric, so the mirror is its
|
|
51
|
+
* six rows in reverse order). Synthesized rather than traced: the reference
|
|
52
|
+
* sheets carry no scrolling menu, and the overflow screenshot above happened to
|
|
53
|
+
* catch a list clipped only at the bottom. If a top-clipped reference turns up,
|
|
54
|
+
* retrace both. Same synthesis convention as {@link STEPPER_UP_FILL}.
|
|
55
|
+
*/
|
|
56
|
+
export declare const CARET_UP: Glyph;
|
|
57
|
+
/**
|
|
58
|
+
* The "little arrows" stepper at rest — a rounded 1-bit frame enclosing hollow
|
|
59
|
+
* up/down arrows (`Little arrows.png`), used by `vf-number-field`.
|
|
60
|
+
*/
|
|
61
|
+
export declare const STEPPER: Glyph;
|
|
62
|
+
/**
|
|
63
|
+
* The horizontal slider thumb — a shield-shaped handle with three vertical grip
|
|
64
|
+
* lines and a pointed bottom (`Slider Handle.png`), used by `vf-slider`. Traced
|
|
65
|
+
* pixel-exact from the sprite: an 11×12 hollow 1-bit frame (flat top, tapering
|
|
66
|
+
* to a point) enclosing the three grip strokes. The grip lines sit at columns
|
|
67
|
+
* 3/5/7 so the middle stroke (x5) marks the thumb's value point.
|
|
68
|
+
*/
|
|
69
|
+
export declare const SLIDER_THUMB: Glyph;
|
|
70
|
+
/**
|
|
71
|
+
* Solid white face for the slider thumb — the filled shield silhouette drawn
|
|
72
|
+
* *behind* {@link SLIDER_THUMB} so the handle is opaque (the rail passes behind
|
|
73
|
+
* it, not through it). Same 11×12 grid, flood-filled to the outline's extent on
|
|
74
|
+
* each row. Analogous to {@link RADIO_FACE} under the radio ring.
|
|
75
|
+
*/
|
|
76
|
+
export declare const SLIDER_THUMB_FACE: Glyph;
|
|
77
|
+
/**
|
|
78
|
+
* Solid up-arrow fill for the pressed state — overlaid on {@link STEPPER} while
|
|
79
|
+
* the up arrow is held. Synthesized from the rest sprite (the only reference we
|
|
80
|
+
* have) by filling the hollow arrow solid, matching the kit's scroll-arrow
|
|
81
|
+
* hollow→solid press convention.
|
|
82
|
+
*/
|
|
83
|
+
export declare const STEPPER_UP_FILL: Glyph;
|
|
84
|
+
/** Solid down-arrow fill for the pressed state (mirror of {@link STEPPER_UP_FILL}). */
|
|
85
|
+
export declare const STEPPER_DOWN_FILL: Glyph;
|
|
86
|
+
/**
|
|
87
|
+
* Authentic System 7 scroll arrows (arrow + stem), traced from the Classic
|
|
88
|
+
* Macintosh UI Kit sprites — a hollow outline at rest that fills solid black
|
|
89
|
+
* while the button is pressed (the `*_FILL` variants). Each is stated on the
|
|
90
|
+
* scrollbar's full 16-unit cell (same convention as {@link STEPPER}): the
|
|
91
|
+
* outermost ring of that cell is the frame and divider lines, which the DOM
|
|
92
|
+
* rail draws as real borders, so the rail renders these through a
|
|
93
|
+
* `viewBox="1 1 14 14"` window onto the interior (src/scroll-rail.ts) — the
|
|
94
|
+
* ink never reaches the outer ring, so nothing is cropped.
|
|
95
|
+
*/
|
|
96
|
+
export declare const SCROLL_ARROW_UP: Glyph;
|
|
97
|
+
/** {@link SCROLL_ARROW_UP}, pressed — the arrow flood-filled solid. */
|
|
98
|
+
export declare const SCROLL_ARROW_UP_FILL: Glyph;
|
|
99
|
+
/** The ▼ scroll arrow (vertical increment). */
|
|
100
|
+
export declare const SCROLL_ARROW_DOWN: Glyph;
|
|
101
|
+
/** {@link SCROLL_ARROW_DOWN}, pressed. */
|
|
102
|
+
export declare const SCROLL_ARROW_DOWN_FILL: Glyph;
|
|
103
|
+
/** The ◀ scroll arrow (horizontal decrement). */
|
|
104
|
+
export declare const SCROLL_ARROW_LEFT: Glyph;
|
|
105
|
+
/** {@link SCROLL_ARROW_LEFT}, pressed. */
|
|
106
|
+
export declare const SCROLL_ARROW_LEFT_FILL: Glyph;
|
|
107
|
+
/** The ▶ scroll arrow (horizontal increment). */
|
|
108
|
+
export declare const SCROLL_ARROW_RIGHT: Glyph;
|
|
109
|
+
/** {@link SCROLL_ARROW_RIGHT}, pressed. */
|
|
110
|
+
export declare const SCROLL_ARROW_RIGHT_FILL: Glyph;
|
|
111
|
+
/**
|
|
112
|
+
* Render a single-color glyph as a crisp, theme-colored inline SVG.
|
|
113
|
+
*
|
|
114
|
+
* Size and color come from CSS on the passed `className` (the SVG fills with
|
|
115
|
+
* `currentColor`), so consumers theme it via `var(--vf-*)` like everything else.
|
|
116
|
+
*/
|
|
117
|
+
export declare function glyphSvg(g: Glyph, className: string): TemplateResult;
|