@rak200/ui 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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) rak200
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # @rak200/ui
2
+
3
+ [![CI](https://github.com/rak200/ui/actions/workflows/ci.yml/badge.svg)](https://github.com/rak200/ui/actions/workflows/ci.yml)
4
+ [![node](https://img.shields.io/badge/node-%3E%3D22-339933?logo=nodedotjs&logoColor=white)](https://nodejs.org/)
5
+ [![Mutation testing](https://img.shields.io/badge/Stryker-MSI%20100%25-brightgreen)](stryker.config.js)
6
+ [![Code style](https://img.shields.io/badge/code%20style-Prettier-blue?logo=prettier&logoColor=white)](prettier.config.js)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
8
+ [![SemVer](https://img.shields.io/badge/semver-2.0.0-blue)](https://semver.org/spec/v2.0.0.html)
9
+
10
+ Host-agnostic custom-element UI components for the rak200 ecosystem.
11
+
12
+ They are **custom elements**, so they work in any page and any framework — or none. That is the
13
+ whole point: a component welded to one framework is not reusable outside it, and this kit exists to
14
+ be reused. Built with [Lit](https://lit.dev) for a thin runtime with no build step required of the
15
+ host. See [RFC 0016](https://github.com/rak200/devr/blob/master/docs/proposals/0016-ui-component-library.md)
16
+ for how that was decided and what was rejected.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npm install @rak200/ui
22
+ ```
23
+
24
+ ## Use
25
+
26
+ ```html
27
+ <script type="module">
28
+ import '@rak200/ui';
29
+ </script>
30
+
31
+ <rak-button>Save</rak-button>
32
+ <rak-button variant="secondary">Cancel</rak-button>
33
+ <rak-button disabled>Unavailable</rak-button>
34
+ ```
35
+
36
+ Every visual decision is a CSS custom property, so a host restyles the kit without forking it:
37
+
38
+ ```css
39
+ :root {
40
+ --rak-color-accent: rebeccapurple;
41
+ --rak-radius: 0;
42
+ }
43
+ ```
44
+
45
+ ## Documentation
46
+
47
+ The reference lives in [docs/](docs/README.md) — one page per unit.
48
+
49
+ ## Status
50
+
51
+ **v0.** One component and the token layer, built to the ecosystem's full quality bar rather than
52
+ sketched: type-checked at the strictest available setting, formatted, tested in a real browser,
53
+ 100% coverage and **100% mutation score**, scanned, and every public symbol documented. The v0
54
+ surface in RFC 0016 grows from here — see [ROADMAP.md](ROADMAP.md).
@@ -0,0 +1,49 @@
1
+ import { LitElement, type TemplateResult } from 'lit';
2
+ /** How much visual weight a button carries. */
3
+ export type ButtonVariant = 'primary' | 'secondary';
4
+ /**
5
+ * A button.
6
+ *
7
+ * It delegates to a real `<button>` in its shadow root rather than reimplementing one,
8
+ * which is what makes the keyboard behaviour, the accessible name and the disabled
9
+ * semantics the platform's job instead of this file's. No state machine is involved
10
+ * because a button has no state to model — Zag arrives with the first component that
11
+ * does.
12
+ *
13
+ * @example
14
+ * ```html
15
+ * <rak-button variant="primary">Save</rak-button>
16
+ * ```
17
+ */
18
+ export declare class RakButton extends LitElement {
19
+ static readonly styles: import("lit").CSSResult;
20
+ static readonly properties: {
21
+ variant: {
22
+ type: StringConstructor;
23
+ reflect: boolean;
24
+ };
25
+ disabled: {
26
+ type: BooleanConstructor;
27
+ reflect: boolean;
28
+ };
29
+ };
30
+ /**
31
+ * How much visual weight the button carries.
32
+ *
33
+ * A plain field, not the `accessor` keyword: `accessor` is an auto-accessor, the
34
+ * browser the suite runs in does not implement it, and the transform leaves it in
35
+ * place — the module then fails to parse. The classic Lit pattern, a `static
36
+ * properties` map beside plain fields with `useDefineForClassFields: false`, needs
37
+ * neither the keyword nor decorators.
38
+ */
39
+ variant: ButtonVariant;
40
+ /** Whether the button rejects interaction. Reflected, so CSS can select on it. */
41
+ disabled: boolean;
42
+ render(): TemplateResult;
43
+ }
44
+ declare global {
45
+ interface HTMLElementTagNameMap {
46
+ 'rak-button': RakButton;
47
+ }
48
+ }
49
+ //# sourceMappingURL=button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../src/button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAEjE,+CAA+C;AAC/C,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,CAAC;AAEpD;;;;;;;;;;;;;GAaG;AACH,qBAAa,SAAU,SAAQ,UAAU;IACrC,gBAAyB,MAAM,0BAoC7B;IAEF,gBAAyB,UAAU;;;;;;;;;MAGjC;IAEF;;;;;;;;OAQG;IACH,OAAO,EAAE,aAAa,CAAa;IAEnC,kFAAkF;IAClF,QAAQ,UAAS;IAER,MAAM,IAAI,cAAc;CAOpC;AAQD,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,YAAY,EAAE,SAAS,CAAC;KAC3B;CACJ"}
package/dist/button.js ADDED
@@ -0,0 +1,86 @@
1
+ import { LitElement, css, html } from 'lit';
2
+ /**
3
+ * A button.
4
+ *
5
+ * It delegates to a real `<button>` in its shadow root rather than reimplementing one,
6
+ * which is what makes the keyboard behaviour, the accessible name and the disabled
7
+ * semantics the platform's job instead of this file's. No state machine is involved
8
+ * because a button has no state to model — Zag arrives with the first component that
9
+ * does.
10
+ *
11
+ * @example
12
+ * ```html
13
+ * <rak-button variant="primary">Save</rak-button>
14
+ * ```
15
+ */
16
+ export class RakButton extends LitElement {
17
+ constructor() {
18
+ super(...arguments);
19
+ /**
20
+ * How much visual weight the button carries.
21
+ *
22
+ * A plain field, not the `accessor` keyword: `accessor` is an auto-accessor, the
23
+ * browser the suite runs in does not implement it, and the transform leaves it in
24
+ * place — the module then fails to parse. The classic Lit pattern, a `static
25
+ * properties` map beside plain fields with `useDefineForClassFields: false`, needs
26
+ * neither the keyword nor decorators.
27
+ */
28
+ this.variant = 'primary';
29
+ /** Whether the button rejects interaction. Reflected, so CSS can select on it. */
30
+ this.disabled = false;
31
+ }
32
+ static { this.styles = css `
33
+ :host {
34
+ display: inline-block;
35
+ }
36
+
37
+ button {
38
+ font: inherit;
39
+ font-family: var(--rak-font, system-ui, sans-serif);
40
+ border: 1px solid transparent;
41
+ border-radius: var(--rak-radius, 0.375rem);
42
+ padding: var(--rak-space, 0.5rem) calc(var(--rak-space, 0.5rem) * 2);
43
+ cursor: pointer;
44
+ }
45
+
46
+ button:disabled {
47
+ cursor: not-allowed;
48
+ opacity: 0.5;
49
+ }
50
+
51
+ /* A visible focus ring is not decoration: removing it is the single most common
52
+ way a component stops being usable by keyboard. */
53
+ button:focus-visible {
54
+ outline: 2px solid var(--rak-color-focus, #f59e0b);
55
+ outline-offset: 2px;
56
+ }
57
+
58
+ button.primary {
59
+ background: var(--rak-color-accent, #2563eb);
60
+ color: var(--rak-color-accent-contrast, #ffffff);
61
+ }
62
+
63
+ button.secondary {
64
+ background: var(--rak-color-surface, #ffffff);
65
+ color: var(--rak-color-text, #1f2937);
66
+ border-color: currentcolor;
67
+ }
68
+ `; }
69
+ static { this.properties = {
70
+ variant: { type: String, reflect: true },
71
+ disabled: { type: Boolean, reflect: true },
72
+ }; }
73
+ render() {
74
+ return html `
75
+ <button class=${this.variant} ?disabled=${this.disabled} part="button">
76
+ <slot></slot>
77
+ </button>
78
+ `;
79
+ }
80
+ }
81
+ // Stryker disable next-line StringLiteral: the registration runs once, at import,
82
+ // inside the warm process Stryker switches mutants in — so by the time a mutant on this
83
+ // line is active the element is already defined under the original name, and no test can
84
+ // observe the change. Outside the runner's reach, not an equivalent mutant.
85
+ customElements.define('rak-button', RakButton);
86
+ //# sourceMappingURL=button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.js","sourceRoot":"","sources":["../src/button.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAuB,MAAM,KAAK,CAAC;AAKjE;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,SAAU,SAAQ,UAAU;IAAzC;;QA4CI;;;;;;;;WAQG;QACH,YAAO,GAAkB,SAAS,CAAC;QAEnC,kFAAkF;QAClF,aAAQ,GAAG,KAAK,CAAC;IASrB,CAAC;aAhE4B,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAoCpC,AApC8B,CAoC7B;aAEuB,eAAU,GAAG;QAClC,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;QACxC,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;KAC7C,AAHkC,CAGjC;IAgBO,MAAM;QACX,OAAO,IAAI,CAAA;4BACS,IAAI,CAAC,OAAO,cAAc,IAAI,CAAC,QAAQ;;;SAG1D,CAAC;IACN,CAAC;;AAGL,kFAAkF;AAClF,wFAAwF;AACxF,yFAAyF;AACzF,4EAA4E;AAC5E,cAAc,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { RakButton, type ButtonVariant } from './button.js';
2
+ export { tokens, defaults, tokenStyleSheet, type Token } from './tokens.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { RakButton } from './button.js';
2
+ export { tokens, defaults, tokenStyleSheet } from './tokens.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAsB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAc,MAAM,aAAa,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Design tokens — the single source of truth for the visual language.
3
+ *
4
+ * They exist from day one because they are the only thing that reaches every target the
5
+ * roadmap has: the web components below consume them as CSS custom properties, and a
6
+ * native shell (RFC 0016, M4) can read the same values without the components. A token
7
+ * added later is a token some target already hardcoded.
8
+ *
9
+ * Every token is a CSS custom property under `--rak-`, so a host overrides one by
10
+ * setting it anywhere above the component — no build step, no theme object, no fork.
11
+ */
12
+ /** The token names this package defines, as they appear in CSS. */
13
+ export declare const tokens: readonly ["--rak-color-accent", "--rak-color-accent-contrast", "--rak-color-surface", "--rak-color-text", "--rak-color-focus", "--rak-radius", "--rak-space", "--rak-font"];
14
+ /** A CSS custom property this package defines. */
15
+ export type Token = (typeof tokens)[number];
16
+ /**
17
+ * The default value of every token, applied at `:root` by {@link tokenStyleSheet}.
18
+ *
19
+ * These are deliberately plain and low-contrast-safe rather than branded: a design
20
+ * system's defaults are what a host sees before it has decided anything.
21
+ */
22
+ export declare const defaults: Readonly<Record<Token, string>>;
23
+ /**
24
+ * The token defaults as a CSS rule, for a host that wants them without importing a
25
+ * component. Returns the text of a `:root` block; a host inserts it however it prefers.
26
+ */
27
+ export declare function tokenStyleSheet(): string;
28
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,mEAAmE;AACnE,eAAO,MAAM,MAAM,6KAST,CAAC;AAEX,kDAAkD;AAClD,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5C;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CASpD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAIxC"}
package/dist/tokens.js ADDED
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Design tokens — the single source of truth for the visual language.
3
+ *
4
+ * They exist from day one because they are the only thing that reaches every target the
5
+ * roadmap has: the web components below consume them as CSS custom properties, and a
6
+ * native shell (RFC 0016, M4) can read the same values without the components. A token
7
+ * added later is a token some target already hardcoded.
8
+ *
9
+ * Every token is a CSS custom property under `--rak-`, so a host overrides one by
10
+ * setting it anywhere above the component — no build step, no theme object, no fork.
11
+ */
12
+ /** The token names this package defines, as they appear in CSS. */
13
+ export const tokens = [
14
+ '--rak-color-accent',
15
+ '--rak-color-accent-contrast',
16
+ '--rak-color-surface',
17
+ '--rak-color-text',
18
+ '--rak-color-focus',
19
+ '--rak-radius',
20
+ '--rak-space',
21
+ '--rak-font',
22
+ ];
23
+ /**
24
+ * The default value of every token, applied at `:root` by {@link tokenStyleSheet}.
25
+ *
26
+ * These are deliberately plain and low-contrast-safe rather than branded: a design
27
+ * system's defaults are what a host sees before it has decided anything.
28
+ */
29
+ export const defaults = {
30
+ '--rak-color-accent': '#2563eb',
31
+ '--rak-color-accent-contrast': '#ffffff',
32
+ '--rak-color-surface': '#ffffff',
33
+ '--rak-color-text': '#1f2937',
34
+ '--rak-color-focus': '#f59e0b',
35
+ '--rak-radius': '0.375rem',
36
+ '--rak-space': '0.5rem',
37
+ '--rak-font': 'system-ui, sans-serif',
38
+ };
39
+ /**
40
+ * The token defaults as a CSS rule, for a host that wants them without importing a
41
+ * component. Returns the text of a `:root` block; a host inserts it however it prefers.
42
+ */
43
+ export function tokenStyleSheet() {
44
+ const body = tokens.map((token) => ` ${token}: ${defaults[token]};`).join('\n');
45
+ return `:root {\n${body}\n}`;
46
+ }
47
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,mEAAmE;AACnE,MAAM,CAAC,MAAM,MAAM,GAAG;IAClB,oBAAoB;IACpB,6BAA6B;IAC7B,qBAAqB;IACrB,kBAAkB;IAClB,mBAAmB;IACnB,cAAc;IACd,aAAa;IACb,YAAY;CACN,CAAC;AAKX;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAoC;IACrD,oBAAoB,EAAE,SAAS;IAC/B,6BAA6B,EAAE,SAAS;IACxC,qBAAqB,EAAE,SAAS;IAChC,kBAAkB,EAAE,SAAS;IAC7B,mBAAmB,EAAE,SAAS;IAC9B,cAAc,EAAE,UAAU;IAC1B,aAAa,EAAE,QAAQ;IACvB,YAAY,EAAE,uBAAuB;CACxC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEjF,OAAO,YAAY,IAAI,KAAK,CAAC;AACjC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@rak200/ui",
3
+ "version": "0.1.0",
4
+ "description": "Host-agnostic custom-element UI components for the rak200 ecosystem",
5
+ "license": "MIT",
6
+ "author": "rak200 <rak.ricardo@windowslive.com>",
7
+ "homepage": "https://github.com/rak200/ui",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/rak200/ui.git"
11
+ },
12
+ "type": "module",
13
+ "engines": {
14
+ "node": ">=22.13.0"
15
+ },
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "default": "./dist/index.js"
22
+ }
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "sideEffects": [
28
+ "./dist/*.js"
29
+ ],
30
+ "scripts": {
31
+ "validate": "npm run build && publint --strict",
32
+ "lint": "prettier --check .",
33
+ "fix": "prettier --write . && eslint --fix .",
34
+ "analyse": "tsc --noEmit && eslint .",
35
+ "test": "vitest run",
36
+ "coverage": "coverage-floor",
37
+ "scan": "semgrep scan --config=p/typescript --severity=ERROR --sarif -o semgrep.sarif",
38
+ "mutation": "stryker run",
39
+ "build": "tsc -p tsconfig.build.json"
40
+ },
41
+ "dependencies": {
42
+ "lit": "^3.3.3"
43
+ },
44
+ "devDependencies": {
45
+ "@rak200/coding-standard-ts": "github:rak200/coding-standard-ts#0.4.0",
46
+ "@types/node": "^26.1.2",
47
+ "@vitest/browser-playwright": "^4.1.10"
48
+ }
49
+ }