@pantoken/react 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/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # @pantoken/react
2
+
3
+ Thin React helpers over `@pantoken/web-components` and the token CSS: an `<Icon>` component, a
4
+ `useToken` hook, and a `<TokenProvider>` that registers the custom elements client-side.
5
+
6
+ ## Install
7
+
8
+ ```sh
9
+ npm i @pantoken/react
10
+ ```
11
+
12
+ Also available as `pantoken/react`.
13
+
14
+ ## Usage
15
+
16
+ ```tsx
17
+ import { TokenProvider, Icon, useToken } from "@pantoken/react";
18
+ import "@pantoken/css";
19
+
20
+ function App() {
21
+ const brand = useToken("--instui-color-background-brand", "#0374B5");
22
+ return (
23
+ <TokenProvider>
24
+ <Icon name="check-mark" size="1.25rem" /> Saved — {brand}
25
+ </TokenProvider>
26
+ );
27
+ }
28
+ ```
29
+
30
+ For InstUI's full React component library, use `@instructure/ui-*` directly. This package is the
31
+ lightweight token and icon layer.
32
+
33
+ ## API
34
+
35
+ - **`<Icon name size? color?>`** — render the `<instui-icon>` custom element (React 19 passes props straight to custom elements).
36
+ - **`<TokenProvider>`** — register the pantoken custom elements client-side, then render children.
37
+ - **`useToken(name, fallback?): string`** — hook returning a resolved `--instui-*` value. Re-reads when `name` changes; SSR-safe.
38
+ - **`readToken(name, fallback?): string`** — read a resolved `--instui-*` value once. Returns `fallback` on the server.
39
+ - **`IconProps`, `TokenProviderProps`** — component prop interfaces.
40
+ - **`register`** — re-exported from `@pantoken/web-components` for direct control over registration timing.
41
+
42
+ ## Related
43
+
44
+ - Pairs with `@pantoken/css` for the base `--instui-*` custom properties.
45
+ - Wraps `@pantoken/web-components`, which supplies the custom elements.
46
+
47
+ ## License
48
+
49
+ MIT
@@ -0,0 +1 @@
1
+ .pantoken-prose{color:var(--instui-component-text-base-color);font-family:var(--instui-component-text-content-font-family);font-size:var(--instui-component-text-content-font-size);font-weight:var(--instui-component-text-content-font-weight);line-height:var(--instui-component-text-content-line-height)}.pantoken-prose h1,.pantoken-prose h2,.pantoken-prose h3,.pantoken-prose h4,.pantoken-prose h5,.pantoken-prose h6{color:var(--instui-component-heading-base-color);font-family:var(--instui-component-heading-h1-font-family);line-height:var(--instui-component-heading-line-height);margin:var(--instui-spacing-space-lg) 0 var(--instui-spacing-space-sm)}.pantoken-prose h1{font-size:var(--instui-component-heading-h1-font-size);font-weight:var(--instui-component-heading-h1-font-weight)}.pantoken-prose h2{font-size:var(--instui-component-heading-h2-font-size);font-weight:var(--instui-component-heading-h2-font-weight)}.pantoken-prose h3{font-size:var(--instui-component-heading-h3-font-size);font-weight:var(--instui-component-heading-h3-font-weight)}.pantoken-prose h4{font-size:var(--instui-component-heading-h4-font-size);font-weight:var(--instui-component-heading-h4-font-weight)}.pantoken-prose h5{font-size:var(--instui-component-heading-h5-font-size);font-weight:var(--instui-component-heading-h5-font-weight)}.pantoken-prose h6{font-size:var(--instui-component-heading-h6-font-size);font-weight:var(--instui-component-heading-h6-font-weight)}.pantoken-prose p{margin:var(--instui-spacing-space-md) 0}.pantoken-prose a{color:var(--instui-color-text-interactive-navigation-primary-base);text-decoration:underline}.pantoken-prose a:hover{color:var(--instui-color-text-interactive-navigation-primary-hover)}.pantoken-prose strong,.pantoken-prose b{font-weight:var(--instui-component-text-content-important-font-weight)}.pantoken-prose em,.pantoken-prose i{font-style:italic}.pantoken-prose small{font-size:var(--instui-component-text-content-small-font-size)}.pantoken-prose del,.pantoken-prose s{color:var(--instui-color-text-muted);text-decoration:line-through}.pantoken-prose ul,.pantoken-prose ol{margin:var(--instui-spacing-space-md) 0;padding-inline-start:var(--instui-spacing-space-lg)}.pantoken-prose li{margin:var(--instui-spacing-space2xs) 0}.pantoken-prose li.task-list-item{list-style:none}.pantoken-prose input[type=checkbox]{accent-color:var(--instui-color-text-interactive-navigation-primary-base);margin-inline-end:var(--instui-spacing-space-xs)}.pantoken-prose blockquote{margin:var(--instui-spacing-space-md) 0;border-inline-start:var(--instui-border-width-lg) solid var(--instui-color-stroke-base);color:var(--instui-component-text-base-color);font-size:var(--instui-component-text-content-quote-font-size);line-height:var(--instui-component-text-content-quote-line-height);padding-inline-start:var(--instui-spacing-space-md)}.pantoken-prose code{font-family:var(--instui-font-family-code);background:var(--instui-color-background-muted);padding:var(--instui-spacing-space2xs) var(--instui-spacing-space-xs);border-radius:var(--instui-border-radius-sm);font-size:.9em}.pantoken-prose pre{font-family:var(--instui-font-family-code);background:var(--instui-color-background-container);color:var(--instui-color-text-base);padding:var(--instui-spacing-space-md);border:var(--instui-border-width-sm) solid var(--instui-color-stroke-base);border-radius:var(--instui-border-radius-md);overflow-x:auto}.pantoken-prose pre code{font-size:inherit;background:0 0;border-radius:0;padding:0}.pantoken-prose hr{border:none;border-top:var(--instui-border-width-sm) solid var(--instui-color-stroke-base);margin:var(--instui-spacing-space-lg) 0}.pantoken-prose img{border-radius:var(--instui-border-radius-md);max-width:100%}.pantoken-prose table:not([class]){border-collapse:collapse;width:100%;margin:var(--instui-spacing-space-md) 0;background:var(--instui-component-table-background);color:var(--instui-component-table-color);font-family:var(--instui-component-table-font-family);font-size:var(--instui-component-table-font-size)}.pantoken-prose table:not([class]) th{text-align:start;background:var(--instui-component-table-col-header-background);color:var(--instui-component-table-col-header-color);font-weight:var(--instui-component-table-head-font-weight);padding:var(--instui-component-table-col-header-padding-vertical) var(--instui-component-table-col-header-padding-horizontal);border-bottom:var(--instui-border-width-md) solid var(--instui-component-table-row-border-color)}.pantoken-prose table:not([class]) td{color:var(--instui-component-table-cell-color);line-height:var(--instui-component-table-cell-line-height);padding:var(--instui-component-table-cell-padding-vertical) var(--instui-component-table-cell-padding-horizontal);border-bottom:var(--instui-border-width-sm) solid var(--instui-component-table-row-border-color)}
@@ -0,0 +1,76 @@
1
+ import { register } from "@pantoken/web-components";
2
+ import { ReactNode } from "react";
3
+
4
+ //#region src/index.d.ts
5
+ /**
6
+ * Read a resolved token value from the document. Returns `fallback` on the server.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * import { readToken } from "@pantoken/react";
11
+ *
12
+ * const brand = readToken("--instui-color-background-brand", "#0374B5");
13
+ * ```
14
+ */
15
+ declare function readToken(name: string, fallback?: string): string;
16
+ /**
17
+ * React hook returning a resolved `--instui-*` token value (re-reads on `name` change).
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * import { useToken } from "@pantoken/react";
22
+ *
23
+ * function Banner() {
24
+ * const brand = useToken("--instui-color-background-brand", "#0374B5");
25
+ * return <div style={{ background: brand }}>Saved</div>;
26
+ * }
27
+ * ```
28
+ */
29
+ declare function useToken(name: string, fallback?: string): string;
30
+ /** Props for {@link Icon}. */
31
+ interface IconProps {
32
+ name: string;
33
+ size?: string;
34
+ color?: string;
35
+ }
36
+ /**
37
+ * Render an Instructure icon as the `<instui-icon>` custom element.
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * import { Icon } from "@pantoken/react";
42
+ *
43
+ * <Icon name="check-mark" size="1.25rem" color="var(--instui-color-text-success)" />;
44
+ * ```
45
+ */
46
+ declare function Icon({
47
+ name,
48
+ size,
49
+ color
50
+ }: IconProps): ReactNode;
51
+ /** Props for {@link TokenProvider}. */
52
+ interface TokenProviderProps {
53
+ children?: ReactNode;
54
+ }
55
+ /**
56
+ * Register the pantoken custom elements (client-side) and render children.
57
+ *
58
+ * @example
59
+ * ```tsx
60
+ * import { TokenProvider, Icon } from "@pantoken/react";
61
+ * import "@pantoken/css";
62
+ *
63
+ * function App() {
64
+ * return (
65
+ * <TokenProvider>
66
+ * <Icon name="check-mark" size="1.25rem" /> Saved
67
+ * </TokenProvider>
68
+ * );
69
+ * }
70
+ * ```
71
+ */
72
+ declare function TokenProvider({
73
+ children
74
+ }: TokenProviderProps): ReactNode;
75
+ //#endregion
76
+ export { Icon, IconProps, TokenProvider, TokenProviderProps, readToken, register, useToken };
package/dist/index.mjs ADDED
@@ -0,0 +1,90 @@
1
+ import { register, register as register$1 } from "@pantoken/web-components";
2
+ import { createElement, useEffect, useState } from "react";
3
+ //#region src/index.tsx
4
+ /**
5
+ * `@pantoken/react` — thin React helpers over `@pantoken/web-components` and the token CSS.
6
+ *
7
+ * - `<Icon>` renders the `<instui-icon>` custom element (React 19 passes props to custom elements).
8
+ * - `useToken` reads a resolved `--instui-*` value at runtime (SSR-safe: returns the fallback on
9
+ * the server).
10
+ * - `<TokenProvider>` registers the elements and is where an app can inject the stylesheet.
11
+ *
12
+ * @module
13
+ * @experimental
14
+ */
15
+ /**
16
+ * Read a resolved token value from the document. Returns `fallback` on the server.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * import { readToken } from "@pantoken/react";
21
+ *
22
+ * const brand = readToken("--instui-color-background-brand", "#0374B5");
23
+ * ```
24
+ */
25
+ function readToken(name, fallback = "") {
26
+ if (typeof window === "undefined" || typeof document === "undefined") return fallback;
27
+ return getComputedStyle(document.documentElement).getPropertyValue(name).trim() || fallback;
28
+ }
29
+ /**
30
+ * React hook returning a resolved `--instui-*` token value (re-reads on `name` change).
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * import { useToken } from "@pantoken/react";
35
+ *
36
+ * function Banner() {
37
+ * const brand = useToken("--instui-color-background-brand", "#0374B5");
38
+ * return <div style={{ background: brand }}>Saved</div>;
39
+ * }
40
+ * ```
41
+ */
42
+ function useToken(name, fallback = "") {
43
+ const [value, setValue] = useState(fallback);
44
+ useEffect(() => {
45
+ setValue(readToken(name, fallback));
46
+ }, [name, fallback]);
47
+ return value;
48
+ }
49
+ /**
50
+ * Render an Instructure icon as the `<instui-icon>` custom element.
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * import { Icon } from "@pantoken/react";
55
+ *
56
+ * <Icon name="check-mark" size="1.25rem" color="var(--instui-color-text-success)" />;
57
+ * ```
58
+ */
59
+ function Icon({ name, size, color }) {
60
+ return createElement("instui-icon", {
61
+ name,
62
+ size,
63
+ color
64
+ });
65
+ }
66
+ /**
67
+ * Register the pantoken custom elements (client-side) and render children.
68
+ *
69
+ * @example
70
+ * ```tsx
71
+ * import { TokenProvider, Icon } from "@pantoken/react";
72
+ * import "@pantoken/css";
73
+ *
74
+ * function App() {
75
+ * return (
76
+ * <TokenProvider>
77
+ * <Icon name="check-mark" size="1.25rem" /> Saved
78
+ * </TokenProvider>
79
+ * );
80
+ * }
81
+ * ```
82
+ */
83
+ function TokenProvider({ children }) {
84
+ useEffect(() => {
85
+ register$1();
86
+ }, []);
87
+ return children ?? null;
88
+ }
89
+ //#endregion
90
+ export { Icon, TokenProvider, readToken, register, useToken };
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@pantoken/react",
3
+ "version": "0.1.0",
4
+ "description": "React helpers for pantoken: <Icon>, useToken, and TokenProvider over the web components + token CSS.",
5
+ "license": "MIT",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "type": "module",
10
+ "exports": {
11
+ ".": "./dist/index.mjs",
12
+ "./components.css": "./dist/components.css",
13
+ "./package.json": "./package.json"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "dependencies": {
19
+ "@pantoken/web-components": "0.1.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^24.13.3",
23
+ "@types/react": "^19.2.17",
24
+ "@types/react-dom": "^19.2.3",
25
+ "react": "^19.2.7",
26
+ "react-dom": "^19.2.7",
27
+ "typescript": "^6.0.3",
28
+ "vite": "npm:@voidzero-dev/vite-plus-core@0.2.4",
29
+ "vite-plus": "0.2.4",
30
+ "@pantoken/components": "0.1.0"
31
+ },
32
+ "peerDependencies": {
33
+ "react": ">=18"
34
+ },
35
+ "pantoken": {
36
+ "key": "react",
37
+ "kind": "subpath"
38
+ },
39
+ "scripts": {
40
+ "generate": "node scripts/generate.ts",
41
+ "build": "vp run generate && vp pack",
42
+ "dev": "vp run generate && vp pack --watch",
43
+ "test": "vp test",
44
+ "check": "vp check"
45
+ }
46
+ }