From 8f277e3cf7afc6eaa92b3a6d40ea51d9dbb57711 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 6 Nov 2026 14:13:58 +0000 Subject: [PATCH] fix(docs): depend on published @bloxwap/hig@0.2.0 The 0.1 split packages 404 on npm. Docs now import tokens, React, CSS, and OG fonts from the unified package, and both lockfiles resolve @bloxwap/hig@0.2.0 from the registry while keeping the workspace chart link. Co-authored-by: Joe Blau --- apps/docs/README.md | 18 ++--- apps/docs/app/global.css | 8 +-- apps/docs/components/callout.tsx | 2 +- apps/docs/components/chart-preview.tsx | 4 +- apps/docs/components/copy-button.tsx | 2 +- apps/docs/components/hero-code.tsx | 2 +- apps/docs/components/install-command.tsx | 4 +- apps/docs/components/search.tsx | 2 +- apps/docs/lib/og-card.tsx | 4 +- apps/docs/next.config.mjs | 3 +- apps/docs/package.json | 5 +- apps/docs/scripts/hig-tokens.mjs | 44 +++++++----- apps/docs/scripts/measure-hig.mjs | 2 +- apps/docs/scripts/prepare-demo.mjs | 2 +- apps/docs/scripts/test-hig-browser.mjs | 2 +- bun.lock | 13 +--- docs/hig-adoption/README.md | 45 +++++++----- docs/hig-adoption/registry-release.json | 26 ++----- package-lock.json | 91 ++++++++++++++++-------- 19 files changed, 153 insertions(+), 126 deletions(-) diff --git a/apps/docs/README.md b/apps/docs/README.md index 94f4763..7124276 100644 --- a/apps/docs/README.md +++ b/apps/docs/README.md @@ -25,16 +25,18 @@ path from the built artifact. It does not run Next.js or a search backend. Edit MDX in `content/docs/` and sidebar order in each `meta.json`. The build checks local HTML links and assets, and emits a browser-searchable index at -`search.json`. Fonts come from the installed `@bloxwap/font` package (and `@bloxwap/hig-og-fonts` for social cards), so builds do not fetch Google Fonts. +`search.json`. Fonts come from the installed `@bloxwap/font` package (and `@bloxwap/hig/og-fonts` for social cards), so builds do not fetch Google Fonts. The presentation follows the Bloxwap HIG and consumes it as packages, not copies: -- `@bloxwap/hig-tokens`, `@bloxwap/hig-contracts` and `@bloxwap/hig-react` (plus the build-time - `@bloxwap/hig-og-fonts`) are pinned to published npm version `0.1.0`; the lockfile and [release record](../../docs/hig-adoption/registry-release.json) retain their registry integrity hashes. - `app/global.css` imports `@bloxwap/hig-tokens/css` and `@bloxwap/hig-react/css` and maps HIG roles - onto Fumadocs; it does not declare palette values. +- `@bloxwap/hig` is pinned to published npm version `0.2.0`. The 0.1 split packages + (`@bloxwap/hig-tokens`, `@bloxwap/hig-contracts`, `@bloxwap/hig-react`, `@bloxwap/hig-og-fonts`) + 404 on npm; tokens, contracts, React and OG fonts are subpath exports of the one package. + The lockfiles and [release record](../../docs/hig-adoption/registry-release.json) retain the registry integrity hash. + `app/global.css` imports `@bloxwap/hig/tokens/css` and `@bloxwap/hig/react/css` and maps HIG roles + onto Fumadocs; it does not declare palette values. `next.config.mjs` lists `@bloxwap/hig` in `transpilePackages`. - Radius, type, motion and density roles (`--hig-radius-*`, `--hig-type-*`, `--hig-motion-*`, - `--hig-density-*`) and the font roles come from `@bloxwap/hig-tokens/css`; the docs declare none. + `--hig-density-*`) and the font roles come from `@bloxwap/hig/tokens/css`; the docs declare none. `npm run lint` (`scripts/hig-tokens.mjs --check`) fails on registry version or integrity changes, local role declarations or retired role names, copied palettes, `.btn`-style primitive copies or font binaries in the docs source. - Buttons, install tabs/copy, code-window copy, callouts, search error/empty states and the playground @@ -94,8 +96,8 @@ chrome's `--cts-font`/`--cts-mono` at Bloxwap Sans/Mono, and sets the canvas `theme.fontFamily` to Bloxwap Sans and `monoFamily`/`scaleFontFamily` (status line, drawing labels and scales) to Bloxwap Mono. The standalone playground and SDK presets retain their existing font defaults. -Social cards use the static Bloxwap Sans faces shipped in `@bloxwap/hig-og-fonts/fonts` (OFL), a -build-time devDependency; Satori cannot read the variable WOFF2 in `@bloxwap/font`. +Social cards use the static Bloxwap Sans faces shipped in `@bloxwap/hig/og-fonts/fonts` (OFL); +Satori cannot read the variable WOFF2 in `@bloxwap/font`. The Node loader is `@bloxwap/hig/og-fonts/node`. HIG presentation, registry integrity, validation, exceptions and upgrade/rollback instructions are recorded in [the adoption report](../../docs/hig-adoption/README.md). diff --git a/apps/docs/app/global.css b/apps/docs/app/global.css index 39ab6da..7909d58 100644 --- a/apps/docs/app/global.css +++ b/apps/docs/app/global.css @@ -1,9 +1,9 @@ @import 'tailwindcss'; @import 'fumadocs-ui/css/neutral.css'; @import 'fumadocs-ui/css/preset.css'; -@import '@bloxwap/hig-tokens/css'; -@import '@bloxwap/hig-react/css/base'; -@import '@bloxwap/hig-react/css'; +@import '@bloxwap/hig/tokens/css'; +@import '@bloxwap/hig/react/css/base'; +@import '@bloxwap/hig/react/css'; @theme inline { --font-sans: var(--font-bloxwap-sans), ui-rounded, system-ui, sans-serif; @@ -151,7 +151,7 @@ html > body[data-scroll-locked] { } /* - * HIG controls (@bloxwap/hig-react/css) in the docs shell. HIG reads --hig-font-sans/--hig-font-mono, which + * HIG controls (@bloxwap/hig/react/css) in the docs shell. HIG reads --hig-font-sans/--hig-font-mono, which * resolve to the @bloxwap/font Next loader variables, so no family bridge is needed. Links and icons share the * button. Dense docs regions opt into HIG compact density on fine pointers; coarse pointers keep 48px targets. */ diff --git a/apps/docs/components/callout.tsx b/apps/docs/components/callout.tsx index f4a7972..ae05df9 100644 --- a/apps/docs/components/callout.tsx +++ b/apps/docs/components/callout.tsx @@ -1,5 +1,5 @@ import type { ReactNode } from 'react'; -import { Callout as HigCallout } from '@bloxwap/hig-react/status'; +import { Callout as HigCallout } from '@bloxwap/hig/react/status'; type FumadocsType = 'info' | 'note' | 'idea' | 'success' | 'warn' | 'warning' | 'error'; const severity = { info: 'info', note: 'note', idea: 'tip', success: 'success', warn: 'warning', warning: 'warning', error: 'error' } as const; diff --git a/apps/docs/components/chart-preview.tsx b/apps/docs/components/chart-preview.tsx index 0fb0649..0044a75 100644 --- a/apps/docs/components/chart-preview.tsx +++ b/apps/docs/components/chart-preview.tsx @@ -2,8 +2,8 @@ import { useEffect, useRef, useState, type ReactNode } from 'react'; import { ArrowUpRight, Maximize2, Minimize2 } from 'lucide-react'; -import { Button } from '@bloxwap/hig-react/button'; -import { Spinner } from '@bloxwap/hig-react/status'; +import { Button } from '@bloxwap/hig/react/button'; +import { Spinner } from '@bloxwap/hig/react/status'; import { assetUrl } from '@/lib/site'; /** diff --git a/apps/docs/components/copy-button.tsx b/apps/docs/components/copy-button.tsx index 18774e9..ddb3954 100644 --- a/apps/docs/components/copy-button.tsx +++ b/apps/docs/components/copy-button.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { Check, Copy } from 'lucide-react'; -import { IconButton } from '@bloxwap/hig-react/button'; +import { IconButton } from '@bloxwap/hig/react/button'; import { useClipboard } from '@/lib/clipboard'; /** HIG icon button that copies `text`, with a check mark, a screen-reader status and visible failure recovery. */ diff --git a/apps/docs/components/hero-code.tsx b/apps/docs/components/hero-code.tsx index bf9c1ea..7c2f00f 100644 --- a/apps/docs/components/hero-code.tsx +++ b/apps/docs/components/hero-code.tsx @@ -1,7 +1,7 @@ import { readFileSync } from 'node:fs'; import { join } from 'node:path'; import type { ReactNode } from 'react'; -import { CodeWindow } from '@bloxwap/hig-react/recipes/code-window'; +import { CodeWindow } from '@bloxwap/hig/react/recipes/code-window'; import { CopyButton } from './copy-button'; /* diff --git a/apps/docs/components/install-command.tsx b/apps/docs/components/install-command.tsx index 8dcbdfa..ddc1de2 100644 --- a/apps/docs/components/install-command.tsx +++ b/apps/docs/components/install-command.tsx @@ -1,7 +1,7 @@ 'use client'; -import { Tabs } from '@bloxwap/hig-react/navigation'; -import { InstallCommand as HigInstallCommand } from '@bloxwap/hig-react/recipes/install-command'; +import { Tabs } from '@bloxwap/hig/react/navigation'; +import { InstallCommand as HigInstallCommand } from '@bloxwap/hig/react/recipes/install-command'; import { useClipboard } from '@/lib/clipboard'; const managers = [ diff --git a/apps/docs/components/search.tsx b/apps/docs/components/search.tsx index f476015..9f65e1a 100644 --- a/apps/docs/components/search.tsx +++ b/apps/docs/components/search.tsx @@ -7,7 +7,7 @@ import { SearchDialogIcon, SearchDialogInput, SearchDialogList, SearchDialogOverlay, type SharedProps, } from 'fumadocs-ui/components/dialog/search'; -import { Alert, EmptyState } from '@bloxwap/hig-react/status'; +import { Alert, EmptyState } from '@bloxwap/hig/react/status'; import { assetUrl } from '@/lib/site'; function NoResults() { diff --git a/apps/docs/lib/og-card.tsx b/apps/docs/lib/og-card.tsx index b7d17ab..4e2c91f 100644 --- a/apps/docs/lib/og-card.tsx +++ b/apps/docs/lib/og-card.tsx @@ -1,5 +1,5 @@ -import { readOgFont } from '@bloxwap/hig-og-fonts/node'; -import { tokens as hig } from '@bloxwap/hig-tokens'; +import { readOgFont } from '@bloxwap/hig/og-fonts/node'; +import { tokens as hig } from '@bloxwap/hig/tokens'; import { readFile } from 'node:fs/promises'; import { join } from 'node:path'; import { ImageResponse } from 'next/og'; diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs index 885fcfb..eb53eda 100644 --- a/apps/docs/next.config.mjs +++ b/apps/docs/next.config.mjs @@ -11,7 +11,8 @@ export default withMDX({ reactStrictMode: true, // Resolve both this app and the local chart package from the workspace root. turbopack: { root: new URL('../..', import.meta.url).pathname }, - transpilePackages: ['@bloxwap/chart'], + // HIG 0.2 is one package. Next must transpile it (the 0.1 split names are unpublished). + transpilePackages: ['@bloxwap/chart', '@bloxwap/hig'], // Type checking runs through tsrs in `npm run check` (prebuild), so Next skips its own tsc pass. typescript: { ignoreBuildErrors: true }, }); diff --git a/apps/docs/package.json b/apps/docs/package.json index 5eb19f6..a59fa0b 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -17,9 +17,7 @@ "dependencies": { "@bloxwap/chart": "0.4.0", "@bloxwap/font": "0.1.2", - "@bloxwap/hig-contracts": "0.1.0", - "@bloxwap/hig-react": "0.1.0", - "@bloxwap/hig-tokens": "0.1.0", + "@bloxwap/hig": "0.2.0", "fumadocs-core": "16.17.7", "fumadocs-mdx": "15.4.9", "fumadocs-ui": "16.17.7", @@ -29,7 +27,6 @@ "react-dom": "^19.3.1" }, "devDependencies": { - "@bloxwap/hig-og-fonts": "0.1.0", "@tailwindcss/postcss": "^4.3.3", "@types/mdx": "^2.0.14", "@types/node": "^24.19.2", diff --git a/apps/docs/scripts/hig-tokens.mjs b/apps/docs/scripts/hig-tokens.mjs index a9688ec..6304db8 100644 --- a/apps/docs/scripts/hig-tokens.mjs +++ b/apps/docs/scripts/hig-tokens.mjs @@ -1,18 +1,18 @@ -// HIG adoption guard for the docs site. Tokens, roles, CSS and components come from published -// @bloxwap/hig-* registry packages. @bloxwap/hig-tokens/css emits the radius, type, +// HIG adoption guard for the docs site. Tokens, roles, CSS and components come from the published +// @bloxwap/hig package. @bloxwap/hig/tokens/css emits the radius, type, // motion and density roles, so this script only derives the canvas-compatible sRGB chart theme from the // typed manifest, and its --check fails CI when copies of HIG sources or role declarations creep back in. import { readFile, readdir } from 'node:fs/promises'; import { existsSync } from 'node:fs'; import { createRequire } from 'node:module'; import assert from 'node:assert/strict'; -import { tokens } from '@bloxwap/hig-tokens'; +import { tokens } from '@bloxwap/hig/tokens'; const require = createRequire(import.meta.url); export const manifest = tokens; -export const tokensCssPath = require.resolve('@bloxwap/hig-tokens/css'); +export const tokensCssPath = require.resolve('@bloxwap/hig/tokens/css'); export const colors = Object.fromEntries(Object.entries(manifest.colors).map(([key, value]) => [key, value.srgb])); -/** CSS value of a role as a modern browser computes it from @bloxwap/hig-tokens/css. */ +/** CSS value of a role as a modern browser computes it from @bloxwap/hig/tokens/css. */ export const cssColor = (role) => manifest.colors[role].oklch ?? manifest.colors[role].srgb; export const chartTheme = { theme: { background: colors.surface, textColor: colors.text, borderColor: colors.border, fontFamily: '"Bloxwap Sans", system-ui, sans-serif', monoFamily: '"Bloxwap Mono", monospace', scaleFontFamily: '"Bloxwap Mono", monospace' }, @@ -25,25 +25,33 @@ if (process.argv.includes('--check')) { const release = JSON.parse(await readFile(new URL('../../../docs/hig-adoption/registry-release.json', import.meta.url), 'utf8')); const lock = JSON.parse(await readFile(new URL('../../../package-lock.json', import.meta.url), 'utf8')); const docsPackage = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8')); - for (const name of ['tokens', 'contracts', 'react', 'og-fonts']) { - const packageName = `@bloxwap/hig-${name}`; - const field = name === 'og-fonts' ? 'devDependencies' : 'dependencies'; - assert.equal(docsPackage[field][packageName], release.version, `${packageName} must use the coordinated registry version`); - const locked = lock.packages[`node_modules/${packageName}`]; - assert.equal(locked.version, release.version, `${packageName} lockfile version drifted`); - assert.equal(locked.resolved, `https://registry.npmjs.org/${packageName}/-/hig-${name}-${release.version}.tgz`, `${packageName} must resolve from npm`); - assert.equal(locked.resolved, release.packages[packageName].resolved); - assert.equal(locked.integrity, release.packages[packageName].integrity, `${packageName} registry integrity drifted`); - assert.equal(JSON.parse(await readFile(new URL(`../../../node_modules/${packageName}/package.json`, import.meta.url), 'utf8')).version, release.version, `Installed ${packageName} is not ${release.version}; run npm ci`); + const packageName = '@bloxwap/hig'; + const splitPackages = ['@bloxwap/hig-tokens', '@bloxwap/hig-contracts', '@bloxwap/hig-react', '@bloxwap/hig-og-fonts', '@bloxwap/hig-native', '@bloxwap/hig-native-fonts', '@bloxwap/hig-chart', '@bloxwap/hig-feedback']; + assert.equal(docsPackage.dependencies[packageName], release.version, `${packageName} must use the coordinated registry version`); + assert.equal(docsPackage.devDependencies?.[packageName], undefined, `${packageName} is the docs dependency, not a second devDependency`); + for (const name of splitPackages) { + assert.equal(docsPackage.dependencies?.[name], undefined, `${name} is an unpublished 0.1 package`); + assert.equal(docsPackage.devDependencies?.[name], undefined, `${name} is an unpublished 0.1 package`); } - assert.ok(!existsSync(new URL('../styles/', import.meta.url)), 'styles/ is gone: radius/type/motion/density roles come from @bloxwap/hig-tokens/css'); + const locked = lock.packages[`node_modules/${packageName}`]; + assert.equal(locked.version, release.version, `${packageName} lockfile version drifted`); + assert.equal(locked.resolved, `https://registry.npmjs.org/${packageName}/-/hig-${release.version}.tgz`, `${packageName} must resolve from npm`); + assert.equal(locked.resolved, release.packages[packageName].resolved); + assert.equal(locked.integrity, release.packages[packageName].integrity, `${packageName} registry integrity drifted`); + assert.equal(JSON.parse(await readFile(new URL(`../../../node_modules/${packageName}/package.json`, import.meta.url), 'utf8')).version, release.version, `Installed ${packageName} is not ${release.version}; run bun install --frozen-lockfile`); + const splitLocked = Object.keys(lock.packages).filter((key) => splitPackages.some((name) => key === `node_modules/${name}` || key.endsWith(`/node_modules/${name}`))); + assert.deepEqual(splitLocked, [], `unpublished 0.1 HIG packages are still locked: ${splitLocked.join(', ')}`); + const chart = lock.packages['node_modules/@bloxwap/chart']; + assert.equal(chart?.link, true, '@bloxwap/chart must stay the workspace package'); + assert.equal(chart.resolved, 'packages/chart'); + assert.ok(!existsSync(new URL('../styles/', import.meta.url)), 'styles/ is gone: radius/type/motion/density roles come from @bloxwap/hig/tokens/css'); // No copied palettes, role declarations, token snapshots, primitive classes or font binaries in the docs shell. const forbidden = [ [/--(hig|bloxwap)-[\w-]+\s*:\s*(#|oklch\(|rgb|color\()/, 'copied palette declaration'], - [/--hig-(radius|type|motion|density|font|duration|control)-[\w-]+\s*:/, 'local HIG role declaration (use the @bloxwap/hig-tokens/css role)'], + [/--hig-(radius|type|motion|density|font|duration|control)-[\w-]+\s*:/, 'local HIG role declaration (use the @bloxwap/hig/tokens/css role)'], [/var\(--hig-(duration|control)-|var\(--hig-type-[a-z]+-line\)/, 'retired generated role name (use --hig-motion-duration-*, --hig-density-*-control, --hig-type-*-line-height)'], [/vendor\/hig\/|tokens\.generated\.css|@workspace\/(tokens|ui)/, 'obsolete token snapshot import'], - [/(^|[\s"'.])btn(--[\w-]+)?\b(?![-\w])/m, 'duplicate .btn primitive (use @bloxwap/hig-react Button or .hig-button)'], + [/(^|[\s"'.])btn(--[\w-]+)?\b(?![-\w])/m, 'duplicate .btn primitive (use @bloxwap/hig/react Button or .hig-button)'], ]; async function checkSurface(dir) { for (const entry of await readdir(dir, { withFileTypes: true })) { diff --git a/apps/docs/scripts/measure-hig.mjs b/apps/docs/scripts/measure-hig.mjs index c10739f..2fceb18 100644 --- a/apps/docs/scripts/measure-hig.mjs +++ b/apps/docs/scripts/measure-hig.mjs @@ -37,7 +37,7 @@ const afterLock = lockPackages(await readFile('package-lock.json', 'utf8')); const docsDeps = (text) => Object.keys({ ...JSON.parse(text).dependencies, ...JSON.parse(text).devDependencies }); const release = JSON.parse(await readFile('docs/hig-adoption/registry-release.json', 'utf8')); // Generated token adapters: hig.generated.css (copied snapshot, step 1), hig-roles.generated.css (step 2), none since -// @bloxwap/hig-tokens/css emits the roles itself. +// @bloxwap/hig/tokens/css emits the roles itself. const generated = (ref) => ['hig.generated.css', 'hig-roles.generated.css'].reduce((sum, file) => { try { return sum + Buffer.byteLength(git('show', `${ref}:apps/docs/styles/${file}`)); } catch { return sum; } }, 0); console.log(JSON.stringify({ diff --git a/apps/docs/scripts/prepare-demo.mjs b/apps/docs/scripts/prepare-demo.mjs index 5bce7fd..d7bc793 100644 --- a/apps/docs/scripts/prepare-demo.mjs +++ b/apps/docs/scripts/prepare-demo.mjs @@ -12,7 +12,7 @@ await rm(output, { recursive: true, force: true }); await mkdir(new URL('demo/', output), { recursive: true }); await Promise.all([ cp(new URL('apps/playground/index.html', repository), new URL('demo/index.html', output)), - cp(tokensCssPath, new URL('assets/hig-tokens.css', output)), // @bloxwap/hig-tokens/css, unmodified + cp(tokensCssPath, new URL('assets/hig-tokens.css', output)), // @bloxwap/hig/tokens/css, unmodified cp(new URL('packages/chart/dist/', repository), new URL('dist/', output), { recursive: true }), ]); diff --git a/apps/docs/scripts/test-hig-browser.mjs b/apps/docs/scripts/test-hig-browser.mjs index 75b5adb..02724ca 100644 --- a/apps/docs/scripts/test-hig-browser.mjs +++ b/apps/docs/scripts/test-hig-browser.mjs @@ -101,7 +101,7 @@ try { assert.deepEqual(presentation.legacy, []); assert.match(presentation.motion, /^0(m?s)$/); assert.equal(presentation.transform, 'none'); - record('@bloxwap/hig-tokens palette, HIG controls in Bloxwap typography, no legacy aliases, reduced motion'); + record('@bloxwap/hig/tokens palette, HIG controls in Bloxwap typography, no legacy aliases, reduced motion'); await page.getByRole('tab', { name: 'npm', exact: true }).click(); await page.getByRole('tab', { name: 'bun', exact: true }).click(); if (evidence) { await mkdir(evidence, { recursive: true }); await page.screenshot({ path: `${evidence}/after-home.png`, fullPage: true }); } diff --git a/bun.lock b/bun.lock index 0334e5c..7d0182f 100644 --- a/bun.lock +++ b/bun.lock @@ -11,9 +11,7 @@ "dependencies": { "@bloxwap/chart": "0.4.0", "@bloxwap/font": "0.1.2", - "@bloxwap/hig-contracts": "0.1.0", - "@bloxwap/hig-react": "0.1.0", - "@bloxwap/hig-tokens": "0.1.0", + "@bloxwap/hig": "0.2.0", "fumadocs-core": "16.17.7", "fumadocs-mdx": "15.4.9", "fumadocs-ui": "16.17.7", @@ -23,7 +21,6 @@ "react-dom": "^19.3.1", }, "devDependencies": { - "@bloxwap/hig-og-fonts": "0.1.0", "@tailwindcss/postcss": "^4.3.3", "@types/mdx": "^2.0.14", "@types/node": "^24.19.2", @@ -79,13 +76,7 @@ "@bloxwap/font": ["@bloxwap/font@0.1.2", "", { "peerDependencies": { "next": ">=15.0.0" }, "optionalPeers": ["next"] }, "sha512-3aWepyHUKhbRtpIZxYYN4ixY703YsKXcfgsRQR1BjiH8hkvahm/xfCkzFhb8fKoN6g1y6vTSb9FA5HCxJ9O0uQ=="], - "@bloxwap/hig-contracts": ["@bloxwap/hig-contracts@0.1.0", "", {}, "sha512-FshDRNoR8/qMySeQHzJE4VWN4X1W8XVoKH7Cx3bVD8e0Tw+eq9qU9KGVPzTbiHRa/Axp6xwNxrS81TPU90xzUA=="], - - "@bloxwap/hig-og-fonts": ["@bloxwap/hig-og-fonts@0.1.0", "", {}, "sha512-Mu2bBjXL+SkswkTAS1m66M4x8r1qRFi6SM6LwJ3ehh99bJp2CBzVpLGVZWvIzR+lJ5nzl5kyE12+Pitq/HW5FA=="], - - "@bloxwap/hig-react": ["@bloxwap/hig-react@0.1.0", "", { "dependencies": { "@bloxwap/hig-contracts": "0.1.0", "@bloxwap/hig-tokens": "0.1.0" }, "peerDependencies": { "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-tooltip": "^1.2.8", "react": "^19.1.0", "react-dom": "^19.1.0", "vaul": "^1.1.2" }, "optionalPeers": ["@radix-ui/react-dialog", "@radix-ui/react-dropdown-menu", "@radix-ui/react-popover", "@radix-ui/react-tooltip", "vaul"] }, "sha512-0LdFe1i79CHWi6wjZnC+Khj+2wyQgH6RHhu1EGSL0eL1W+jQhEAXr7GmMS7eulJJeijlW6a1wbQgA7FkczvyZw=="], - - "@bloxwap/hig-tokens": ["@bloxwap/hig-tokens@0.1.0", "", {}, "sha512-udpntFJd+V056S9CtBYQWFKY++me1h7fTTXfwq+ivyfDIveZrUW4tE10fghAtmDPz2m6jzOzMRCm/Cg5lw09GA=="], + "@bloxwap/hig": ["@bloxwap/hig@0.2.0", "", { "peerDependencies": { "@bloxwap/chart": "^0.3.0", "@bloxwap/haptic": "^0.2.0 || ^0.3.0", "@bloxwap/sfx": "^0.2.0", "@gorhom/bottom-sheet": "^5.2.14", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-tooltip": "^1.2.8", "@react-native-community/slider": "5.0.1 || 5.1.2 || 5.2.1", "expo-audio": "~1.1.1 || ~55.0.18 || ~58.0.10", "expo-haptics": "~15.0.7 || ~55.0.18 || ~58.0.7", "react": "^19.1.0", "react-dom": "^19.1.0", "react-native": "^0.81.5 || ^0.83.10 || ^0.88.0", "react-native-gesture-handler": "^2.28.0 || ^3.3.0", "react-native-reanimated": "^4.1.1", "react-native-safe-area-context": "~5.6.0 || ~5.10.1", "react-native-svg": "15.12.1 || 15.15.3 || 15.16.0", "react-native-worklets": "^0.5.1 || ^0.7.4 || ^0.13.0", "vaul": "^1.1.2" }, "optionalPeers": ["@bloxwap/haptic", "@bloxwap/sfx", "@gorhom/bottom-sheet", "@radix-ui/react-dialog", "@radix-ui/react-dropdown-menu", "@radix-ui/react-popover", "@radix-ui/react-tooltip", "@react-native-community/slider", "expo-audio", "expo-haptics", "react", "react-dom", "react-native", "react-native-gesture-handler", "react-native-reanimated", "react-native-safe-area-context", "react-native-svg", "react-native-worklets", "vaul"] }, "sha512-gQuAosZSDrEHioO3O4TN1Fj3bx0c+kA1pf3EcWNfpEf3yfYYysF9DYDV5mo1vX1ZgFQn8b7cHzn/ImCEkiQZMw=="], "@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="], diff --git a/docs/hig-adoption/README.md b/docs/hig-adoption/README.md index 970ff5c..3ae1506 100644 --- a/docs/hig-adoption/README.md +++ b/docs/hig-adoption/README.md @@ -1,6 +1,6 @@ -# Chart docs adoption · HIG 0.1.0 +# Chart docs adoption · HIG 0.2.0 -Owner: Chart maintainers. Updated 2026-10-23; exceptions reviewed by 2026-11-13. +Owner: Chart maintainers. Updated 2026-11-06; exceptions reviewed by 2026-11-13. This repository owns the Chart row of [hig#34](https://github.com/bloxwap/hig/issues/34) and its repository-level evidence for [hig#36](https://github.com/bloxwap/hig/issues/36). @@ -12,23 +12,33 @@ repository-level evidence for [hig#36](https://github.com/bloxwap/hig/issues/36) | 3 | [#56](https://github.com/bloxwap/chart/pull/56) | [872906a](https://github.com/bloxwap/hig/tree/872906a9071469af8714b3b6fb5cc7bd64d2d6f3) | Same packages plus build-time `@bloxwap/hig-native-fonts`; upstream fixes replace the step 2 workarounds | | 4 | [#58](https://github.com/bloxwap/chart/pull/58) | [e3390bbd](https://github.com/bloxwap/hig/tree/e3390bbd0ac12b9d4b371175bd250d01ea866abe) | Scoped OG-font candidate; normal npm workspace resolution | | 5 | Registry adoption | [v0.1.0](https://github.com/bloxwap/hig/releases/tag/v0.1.0) | Exact npm `0.1.0` for tokens, contracts, React and build-time OG fonts | +| 6 | Unified package | [f4c23cc](https://github.com/bloxwap/hig/commit/f4c23cc98d7e034062e82deba222bcb2dadbe2a1) | `@bloxwap/hig@0.2.0`; the 0.1 packages are subpath exports | ## Current registry installation -The docs install four coordinated HIG packages directly from npm. Vendored candidate archives -are removed. `package-lock.json` and [`registry-release.json`](registry-release.json) record the -registry URLs and integrity hashes; `npm ci` verifies downloaded package bytes and `npm run lint` -checks the coordinated declarations, lockfile and installed versions. This release used token -publishing and has no npm provenance attestation. Earlier candidate evidence below remains historical. -The current install, test, export and browser results are in [`registry-verification.json`](registry-verification.json). - -`@bloxwap/hig-react` has no chart peer, so ordinary peer resolution preserves the repository's -`@bloxwap/chart` workspace. OG cards use only `@bloxwap/hig-og-fonts/node`; no native-font package -is installed. Whole-page docs retain the explicit `@bloxwap/hig-react/css/base` import. - -For upgrades, update all four exact versions, regenerate the lockfile and registry record, then run -`npm ci`, `npm run lint`, `npm run typecheck`, `npm test`, `NEXT_PUBLIC_BASE_PATH=/chart npm run docs:build` -and `NEXT_PUBLIC_BASE_PATH=/chart npm run docs:test`. Roll back by reverting the dependency migration. +The docs install one HIG package, `@bloxwap/hig@0.2.0`, directly from npm. The 0.1 split packages +(`@bloxwap/hig-tokens`, `-contracts`, `-react` and `-og-fonts`) 404, so tokens, contracts, React and +OG fonts are imported from `@bloxwap/hig/tokens`, `@bloxwap/hig/contracts`, `@bloxwap/hig/react/*` +and `@bloxwap/hig/og-fonts`. `bun.lock`, `package-lock.json` and [`registry-release.json`](registry-release.json) +record the registry URL and integrity hash. CI installs with `bun install --frozen-lockfile`; `npm ci` +checks the same bytes. `npm run lint` checks the declaration, lockfile and installed version. +`@bloxwap/hig@0.2.0` was published manually and has no GitHub release tag or npm provenance attestation. +The 0.1.0 install, test, export and browser results in [`registry-verification.json`](registry-verification.json) +stay historical. Sections below that name the split packages describe those earlier steps. + +The published 0.2.0 tarball requires `@bloxwap/chart` `^0.3.0` so npm keeps a host workspace link +(hig#96). This repository's workspace is `@bloxwap/chart@0.4.0`, which is outside that range. Later HIG +source accepts `^0.3.0 || ^0.4.0`; that widening is not in the published tarball. `bun install` and +`npm ci` keep `node_modules/@bloxwap/chart` pointed at `packages/chart` and do not fetch chart 0.3.0. +A resolving `npm install` stops with `ERESOLVE` on that peer; do not pass `--force`, which can replace +the workspace link with the registry package. OG cards use `@bloxwap/hig/og-fonts/node`; +the native-font entry is not imported. Whole-page docs retain the explicit `@bloxwap/hig/react/css/base` +import, and Next lists `@bloxwap/hig` in `transpilePackages`. + +For upgrades, change the exact version, regenerate both lockfiles and the registry record, then run +`bun install --frozen-lockfile`, `npm run lint`, `npm run typecheck`, `npm test`, +`NEXT_PUBLIC_BASE_PATH=/chart npm run docs:build` and `NEXT_PUBLIC_BASE_PATH=/chart npm run docs:test`. +Roll back by reverting the dependency migration. ## What changed in step 2 @@ -135,7 +145,7 @@ copy guards) and `docs:test` (browser checks). | Repository/surface | Applicability | Version | Owner | Status | Residual work / review date | | --- | --- | --- | --- | --- | --- | -| chart / apps/docs | SDK docs shell and embedded DOM chart | HIG 0.1.0 from npm (tokens, contracts, react; og-fonts build-time); Font 0.1.2 | Chart maintainers | Migrated to HIG packages; automated + browser evidence | Physical touch/mobile chart gestures, VoiceOver/TalkBack, iOS/Android hardware; 2026-11-13 | +| chart / apps/docs | SDK docs shell and embedded DOM chart | HIG 0.2.0 from npm (`@bloxwap/hig` tokens, contracts, react and og-fonts subpaths); Font 0.1.2 | Chart maintainers | Migrated to the unified HIG package; automated + browser evidence | Physical touch/mobile chart gestures, VoiceOver/TalkBack, iOS/Android hardware; 2026-11-13 | | chart / published SDK | Engine and optional DOM UI | SDK 0.4.0 | Chart maintainers | Unchanged; standalone themes stay host-configurable | Product owners configure the HIG theme in their host; 2026-11-13 | Exceptions (Chart maintainers, review 2026-11-13): @@ -144,6 +154,7 @@ Exceptions (Chart maintainers, review 2026-11-13): generated role CSS, the button font bridge and local Callout edges. - Resolved in step 4: normal lockfile regeneration keeps the Chart workspace; scoped OG fonts replace the native-font archive. - Resolved in step 5: all HIG dependencies use the published npm release, with no vendored tarballs. +- Resolved in step 6: the unpublished 0.1 split packages are replaced by `@bloxwap/hig@0.2.0` subpath exports. - Decorative OG brand-spectrum colors (purple/pink/yellow) are illustration assets, not a control palette. The canonical org matrix lives in `bloxwap/hig/planning/adoption.json`; HIG maintainers copy this row, diff --git a/docs/hig-adoption/registry-release.json b/docs/hig-adoption/registry-release.json index 169157a..c881d50 100644 --- a/docs/hig-adoption/registry-release.json +++ b/docs/hig-adoption/registry-release.json @@ -1,25 +1,13 @@ { "repository": "bloxwap/hig", - "commit": "bdf8d07014fea5e69ea51a061b82707661a9d701", - "version": "0.1.0", - "release": "https://github.com/bloxwap/hig/releases/tag/v0.1.0", - "distribution": "npm registry; integrity checked by npm ci; this token-published release has no npm provenance attestation", + "commit": "f4c23cc98d7e034062e82deba222bcb2dadbe2a1", + "version": "0.2.0", + "release": "https://github.com/bloxwap/hig/commit/f4c23cc98d7e034062e82deba222bcb2dadbe2a1", + "distribution": "npm registry package @bloxwap/hig@0.2.0; the lockfiles check this tarball's integrity. Published manually (no GitHub release tag, no npm provenance attestation). commit is the public consolidation of the unified package, not a byte match of the tarball: the published peer on @bloxwap/chart is ^0.3.0, while that commit accepts ^0.3.0 || ^0.4.0.", "packages": { - "@bloxwap/hig-tokens": { - "resolved": "https://registry.npmjs.org/@bloxwap/hig-tokens/-/hig-tokens-0.1.0.tgz", - "integrity": "sha512-udpntFJd+V056S9CtBYQWFKY++me1h7fTTXfwq+ivyfDIveZrUW4tE10fghAtmDPz2m6jzOzMRCm/Cg5lw09GA==" - }, - "@bloxwap/hig-contracts": { - "resolved": "https://registry.npmjs.org/@bloxwap/hig-contracts/-/hig-contracts-0.1.0.tgz", - "integrity": "sha512-FshDRNoR8/qMySeQHzJE4VWN4X1W8XVoKH7Cx3bVD8e0Tw+eq9qU9KGVPzTbiHRa/Axp6xwNxrS81TPU90xzUA==" - }, - "@bloxwap/hig-react": { - "resolved": "https://registry.npmjs.org/@bloxwap/hig-react/-/hig-react-0.1.0.tgz", - "integrity": "sha512-0LdFe1i79CHWi6wjZnC+Khj+2wyQgH6RHhu1EGSL0eL1W+jQhEAXr7GmMS7eulJJeijlW6a1wbQgA7FkczvyZw==" - }, - "@bloxwap/hig-og-fonts": { - "resolved": "https://registry.npmjs.org/@bloxwap/hig-og-fonts/-/hig-og-fonts-0.1.0.tgz", - "integrity": "sha512-Mu2bBjXL+SkswkTAS1m66M4x8r1qRFi6SM6LwJ3ehh99bJp2CBzVpLGVZWvIzR+lJ5nzl5kyE12+Pitq/HW5FA==" + "@bloxwap/hig": { + "resolved": "https://registry.npmjs.org/@bloxwap/hig/-/hig-0.2.0.tgz", + "integrity": "sha512-gQuAosZSDrEHioO3O4TN1Fj3bx0c+kA1pf3EcWNfpEf3yfYYysF9DYDV5mo1vX1ZgFQn8b7cHzn/ImCEkiQZMw==" } } } diff --git a/package-lock.json b/package-lock.json index 96bf034..b00d044 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,9 +20,7 @@ "dependencies": { "@bloxwap/chart": "0.4.0", "@bloxwap/font": "0.1.2", - "@bloxwap/hig-contracts": "0.1.0", - "@bloxwap/hig-react": "0.1.0", - "@bloxwap/hig-tokens": "0.1.0", + "@bloxwap/hig": "0.2.0", "fumadocs-core": "16.17.7", "fumadocs-mdx": "15.4.9", "fumadocs-ui": "16.17.7", @@ -32,7 +30,6 @@ "react-dom": "^19.3.1" }, "devDependencies": { - "@bloxwap/hig-og-fonts": "0.1.0", "@tailwindcss/postcss": "^4.3.3", "@types/mdx": "^2.0.14", "@types/node": "^24.19.2", @@ -454,38 +451,43 @@ } } }, - "node_modules/@bloxwap/hig-contracts": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@bloxwap/hig-contracts/-/hig-contracts-0.1.0.tgz", - "integrity": "sha512-FshDRNoR8/qMySeQHzJE4VWN4X1W8XVoKH7Cx3bVD8e0Tw+eq9qU9KGVPzTbiHRa/Axp6xwNxrS81TPU90xzUA==", - "license": "MIT" - }, - "node_modules/@bloxwap/hig-og-fonts": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@bloxwap/hig-og-fonts/-/hig-og-fonts-0.1.0.tgz", - "integrity": "sha512-Mu2bBjXL+SkswkTAS1m66M4x8r1qRFi6SM6LwJ3ehh99bJp2CBzVpLGVZWvIzR+lJ5nzl5kyE12+Pitq/HW5FA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@bloxwap/hig-react": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@bloxwap/hig-react/-/hig-react-0.1.0.tgz", - "integrity": "sha512-0LdFe1i79CHWi6wjZnC+Khj+2wyQgH6RHhu1EGSL0eL1W+jQhEAXr7GmMS7eulJJeijlW6a1wbQgA7FkczvyZw==", + "node_modules/@bloxwap/hig": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@bloxwap/hig/-/hig-0.2.0.tgz", + "integrity": "sha512-gQuAosZSDrEHioO3O4TN1Fj3bx0c+kA1pf3EcWNfpEf3yfYYysF9DYDV5mo1vX1ZgFQn8b7cHzn/ImCEkiQZMw==", "license": "MIT", - "dependencies": { - "@bloxwap/hig-contracts": "0.1.0", - "@bloxwap/hig-tokens": "0.1.0" - }, "peerDependencies": { + "@bloxwap/chart": "^0.3.0", + "@bloxwap/haptic": "^0.2.0 || ^0.3.0", + "@bloxwap/sfx": "^0.2.0", + "@gorhom/bottom-sheet": "^5.2.14", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-tooltip": "^1.2.8", + "@react-native-community/slider": "5.0.1 || 5.1.2 || 5.2.1", + "expo-audio": "~1.1.1 || ~55.0.18 || ~58.0.10", + "expo-haptics": "~15.0.7 || ~55.0.18 || ~58.0.7", "react": "^19.1.0", "react-dom": "^19.1.0", + "react-native": "^0.81.5 || ^0.83.10 || ^0.88.0", + "react-native-gesture-handler": "^2.28.0 || ^3.3.0", + "react-native-reanimated": "^4.1.1", + "react-native-safe-area-context": "~5.6.0 || ~5.10.1", + "react-native-svg": "15.12.1 || 15.15.3 || 15.16.0", + "react-native-worklets": "^0.5.1 || ^0.7.4 || ^0.13.0", "vaul": "^1.1.2" }, "peerDependenciesMeta": { + "@bloxwap/haptic": { + "optional": true + }, + "@bloxwap/sfx": { + "optional": true + }, + "@gorhom/bottom-sheet": { + "optional": true + }, "@radix-ui/react-dialog": { "optional": true }, @@ -498,17 +500,44 @@ "@radix-ui/react-tooltip": { "optional": true }, + "@react-native-community/slider": { + "optional": true + }, + "expo-audio": { + "optional": true + }, + "expo-haptics": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "react-native-gesture-handler": { + "optional": true + }, + "react-native-reanimated": { + "optional": true + }, + "react-native-safe-area-context": { + "optional": true + }, + "react-native-svg": { + "optional": true + }, + "react-native-worklets": { + "optional": true + }, "vaul": { "optional": true } } }, - "node_modules/@bloxwap/hig-tokens": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@bloxwap/hig-tokens/-/hig-tokens-0.1.0.tgz", - "integrity": "sha512-udpntFJd+V056S9CtBYQWFKY++me1h7fTTXfwq+ivyfDIveZrUW4tE10fghAtmDPz2m6jzOzMRCm/Cg5lw09GA==", - "license": "MIT" - }, "node_modules/@emnapi/runtime": { "version": "1.11.3", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz",