@terra-symposium/docs 0.1.80 → 0.1.81
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/lib-dist/style.css +1 -1
- package/package.json +1 -1
- package/site/astro.config.mjs +91 -30
- package/site/src/components/SkillsExplorer.tsx +13 -16
package/package.json
CHANGED
package/site/astro.config.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { terraErrorBoundaryIntegration as __terraErrorBoundaryIntegration } from '@terra-symposium/standards-error-boundaries/astro-integration';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import { resolve } from 'node:path';
|
|
3
|
+
import { dirname, resolve } from 'node:path';
|
|
4
4
|
import { readFileSync } from 'node:fs';
|
|
5
5
|
import { createRequire } from 'node:module';
|
|
6
6
|
import { defineConfig } from 'astro/config';
|
|
@@ -13,11 +13,9 @@ import { docsContentPlugin } from './docs-content-plugin.mjs';
|
|
|
13
13
|
|
|
14
14
|
const packageRoot = fileURLToPath(new URL('../', import.meta.url));
|
|
15
15
|
const requireFromPackage = createRequire(import.meta.url);
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
readFileSync(requireFromPackage.resolve('astro/package.json'), 'utf8'),
|
|
20
|
-
);
|
|
16
|
+
const astroManifestPath = requireFromPackage.resolve('astro/package.json');
|
|
17
|
+
const astroManifest = JSON.parse(readFileSync(astroManifestPath, 'utf8'));
|
|
18
|
+
const astroPackageRoot = dirname(astroManifestPath);
|
|
21
19
|
const docsManifest = JSON.parse(readFileSync(resolve(packageRoot, 'package.json'), 'utf8'));
|
|
22
20
|
const projectRoot = process.env.TERRA_DOCS_ROOT ?? process.cwd();
|
|
23
21
|
const publicDir = resolve(projectRoot, '.terra-docs/public');
|
|
@@ -32,7 +30,6 @@ const projectManifest = (() => {
|
|
|
32
30
|
}
|
|
33
31
|
})();
|
|
34
32
|
const requireFromProject = createRequire(resolve(projectRoot, 'package.json'));
|
|
35
|
-
|
|
36
33
|
function packageExportAliases() {
|
|
37
34
|
if (!projectManifest.name || !projectManifest.exports) return [];
|
|
38
35
|
const escapeRegex = (value) => value.replace(/[|\\{}()[\]^$+?.]/g, '\\$&');
|
|
@@ -51,36 +48,53 @@ function packageExportAliases() {
|
|
|
51
48
|
}
|
|
52
49
|
|
|
53
50
|
function astroPackageExportAliases() {
|
|
54
|
-
return
|
|
51
|
+
return [
|
|
52
|
+
{
|
|
53
|
+
// Astro's MDX renderer imports this internal runtime path, which Astro
|
|
54
|
+
// does not expose through package exports. Resolve it from Docs' Astro.
|
|
55
|
+
find: /^astro\/runtime\/(.+)$/,
|
|
56
|
+
replacement: resolve(astroPackageRoot, 'dist/runtime/$1'),
|
|
57
|
+
},
|
|
58
|
+
...Object.keys(astroManifest.exports)
|
|
55
59
|
.filter((key) => key.startsWith('./') && !key.includes('*'))
|
|
56
60
|
.map((key) => {
|
|
57
61
|
const specifier = `astro${key.slice(1)}`;
|
|
58
|
-
try {
|
|
59
|
-
requireFromProject.resolve(specifier);
|
|
60
|
-
return null;
|
|
61
|
-
} catch {
|
|
62
|
-
// Package-owned Astro installation is the fallback for content-only repos.
|
|
63
|
-
}
|
|
64
62
|
return {
|
|
65
63
|
find: new RegExp(`^${specifier.replace(/[|\\{}()[\]^$+?.]/g, '\\$&')}$`),
|
|
66
64
|
replacement: requireFromPackage.resolve(specifier),
|
|
67
65
|
};
|
|
68
|
-
})
|
|
69
|
-
|
|
66
|
+
}),
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function dependencyManifest(name, resolver = requireFromPackage) {
|
|
71
|
+
let entry;
|
|
72
|
+
try {
|
|
73
|
+
entry = resolver.resolve(name);
|
|
74
|
+
} catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
let directory = resolve(entry, '..');
|
|
78
|
+
while (directory !== resolve(directory, '..')) {
|
|
79
|
+
const manifestPath = resolve(directory, 'package.json');
|
|
80
|
+
try {
|
|
81
|
+
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
82
|
+
if (manifest.name === name) return manifest;
|
|
83
|
+
} catch {
|
|
84
|
+
// Keep walking through package subdirectories until the owning manifest is found.
|
|
85
|
+
}
|
|
86
|
+
directory = resolve(directory, '..');
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
70
89
|
}
|
|
71
90
|
|
|
72
91
|
function packageDependencyAliases() {
|
|
73
92
|
return Object.keys(docsManifest.dependencies ?? {})
|
|
74
93
|
.filter((name) => name !== 'astro')
|
|
75
94
|
.flatMap((name) => {
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
dependencyManifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
80
|
-
} catch {
|
|
81
|
-
return [];
|
|
82
|
-
}
|
|
83
|
-
const subpaths = Object.keys(dependencyManifest.exports ?? {}).filter(
|
|
95
|
+
const manifest = dependencyManifest(name);
|
|
96
|
+
if (!manifest) return [];
|
|
97
|
+
const subpaths = Object.keys(manifest.exports ?? {}).filter(
|
|
84
98
|
(key) => key.startsWith('./') && !key.includes('*'),
|
|
85
99
|
);
|
|
86
100
|
return [name, ...subpaths.map((key) => `${name}${key.slice(1)}`)].flatMap((specifier) => {
|
|
@@ -98,6 +112,35 @@ function packageDependencyAliases() {
|
|
|
98
112
|
});
|
|
99
113
|
}
|
|
100
114
|
|
|
115
|
+
function stylingDependencyAliases() {
|
|
116
|
+
const stylingManifest =
|
|
117
|
+
projectManifest.name === '@terra-symposium/styling'
|
|
118
|
+
? projectManifest
|
|
119
|
+
: dependencyManifest('@terra-symposium/styling', requireFromProject);
|
|
120
|
+
if (!stylingManifest) return [];
|
|
121
|
+
return Object.keys(stylingManifest.dependencies ?? {})
|
|
122
|
+
.filter((name) => name !== 'react' && name !== 'react-dom' && (name.includes('react') || ['cmdk', 'vaul'].includes(name)))
|
|
123
|
+
.flatMap((name) => {
|
|
124
|
+
const manifest = dependencyManifest(name, requireFromProject);
|
|
125
|
+
if (!manifest) return [];
|
|
126
|
+
const subpaths = Object.keys(manifest.exports ?? {}).filter(
|
|
127
|
+
(key) => key.startsWith('./') && !key.includes('*'),
|
|
128
|
+
);
|
|
129
|
+
return [name, ...subpaths.map((key) => `${name}${key.slice(1)}`)].flatMap((specifier) => {
|
|
130
|
+
try {
|
|
131
|
+
return [
|
|
132
|
+
{
|
|
133
|
+
find: new RegExp(`^${specifier.replace(/[|\\{}()[\]^$+?.]/g, '\\$&')}$`),
|
|
134
|
+
replacement: requireFromProject.resolve(specifier),
|
|
135
|
+
},
|
|
136
|
+
];
|
|
137
|
+
} catch {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
101
144
|
function sharedReactAliases() {
|
|
102
145
|
const specifiers = [
|
|
103
146
|
'react',
|
|
@@ -106,14 +149,32 @@ function sharedReactAliases() {
|
|
|
106
149
|
'react/jsx-runtime',
|
|
107
150
|
'react-dom',
|
|
108
151
|
'react-dom/client',
|
|
109
|
-
'react-dom/server',
|
|
110
152
|
];
|
|
111
|
-
return
|
|
153
|
+
return [
|
|
154
|
+
...specifiers.map((specifier) => {
|
|
155
|
+
let replacement;
|
|
156
|
+
try {
|
|
157
|
+
// Externalized component dependencies resolve React from the consumer's
|
|
158
|
+
// installation during SSR. Prefer that same copy for bundled imports.
|
|
159
|
+
replacement = requireFromProject.resolve(specifier);
|
|
160
|
+
} catch {
|
|
161
|
+
// Content-only repositories can rely on the React runtime shipped by Docs.
|
|
162
|
+
replacement = requireFromPackage.resolve(specifier);
|
|
163
|
+
}
|
|
112
164
|
return {
|
|
113
165
|
find: new RegExp(`^${specifier.replace(/[|\\{}()[\]^$+?.]/g, '\\$&')}$`),
|
|
114
|
-
replacement
|
|
166
|
+
replacement,
|
|
115
167
|
};
|
|
116
|
-
|
|
168
|
+
}),
|
|
169
|
+
{
|
|
170
|
+
// The Docs editor imports `react-dom/server` for Markdown previews. Its
|
|
171
|
+
// Node entrypoint pulls `util.TextEncoder` into browser chunks, where
|
|
172
|
+
// `util` is externalized and the Docs workspace fails to hydrate. The
|
|
173
|
+
// browser server renderer also works during Node prerendering.
|
|
174
|
+
find: /^react-dom\/server$/,
|
|
175
|
+
replacement: requireFromProject.resolve('react-dom/server.browser'),
|
|
176
|
+
},
|
|
177
|
+
];
|
|
117
178
|
}
|
|
118
179
|
|
|
119
180
|
export default defineConfig({
|
|
@@ -139,12 +200,12 @@ export default defineConfig({
|
|
|
139
200
|
...sharedReactAliases(),
|
|
140
201
|
...astroPackageExportAliases(),
|
|
141
202
|
...packageDependencyAliases(),
|
|
203
|
+
...stylingDependencyAliases(),
|
|
142
204
|
],
|
|
143
205
|
dedupe: ['react', 'react-dom'],
|
|
144
206
|
},
|
|
145
207
|
ssr: {
|
|
146
|
-
// Bundle
|
|
147
|
-
// static rendering does not load two copies across pnpm virtual stores.
|
|
208
|
+
// Bundle the shared UI packages while retaining their peer runtime.
|
|
148
209
|
noExternal: ['@terra-symposium/styling', '@terra-symposium/standards-error-boundaries'],
|
|
149
210
|
},
|
|
150
211
|
server: { fs: { allow: [projectRoot, packageRoot] } },
|
|
@@ -9,9 +9,6 @@ IMPORTS
|
|
|
9
9
|
// API
|
|
10
10
|
import { useMemo, useState } from 'react';
|
|
11
11
|
|
|
12
|
-
// COMPONENTS
|
|
13
|
-
import { Button, Input, Label } from '@terra-symposium/styling/ui';
|
|
14
|
-
|
|
15
12
|
/*//////////////////////////////////////////////////
|
|
16
13
|
CONFIG
|
|
17
14
|
//////////////////////////////////////////////////*/
|
|
@@ -133,8 +130,11 @@ export function SkillsExplorer({ skills }: { skills: SkillRecord[] }) {
|
|
|
133
130
|
className="max-h-[78vh] min-w-0 overflow-auto rounded-xl border border-gray-6 bg-gray-1 p-3"
|
|
134
131
|
>
|
|
135
132
|
<div>
|
|
136
|
-
<
|
|
137
|
-
|
|
133
|
+
<label className="text-sm font-medium text-gray-11" htmlFor="skills-explorer-filter">
|
|
134
|
+
Filter skills
|
|
135
|
+
</label>
|
|
136
|
+
<input
|
|
137
|
+
className="mt-1 w-full rounded-md border border-gray-6 bg-gray-1 px-3 py-2 text-sm text-gray-12 shadow-sm outline-none placeholder:text-gray-9 focus-visible:ring-2 focus-visible:ring-primary-8"
|
|
138
138
|
id="skills-explorer-filter"
|
|
139
139
|
onChange={(event) => setQuery(event.currentTarget.value)}
|
|
140
140
|
placeholder="Name, topic, or text"
|
|
@@ -154,17 +154,14 @@ export function SkillsExplorer({ skills }: { skills: SkillRecord[] }) {
|
|
|
154
154
|
<ul className="m-0 grid list-none gap-1 p-0">
|
|
155
155
|
{entries.map((skill) => (
|
|
156
156
|
<li key={skill.sourcePath}>
|
|
157
|
-
<
|
|
158
|
-
aria-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
className="h-auto w-full justify-start px-3 py-2 text-left"
|
|
162
|
-
onClick={() => setActivePath(skill.sourcePath)}
|
|
163
|
-
variant={
|
|
157
|
+
<button
|
|
158
|
+
aria-pressed={selectedSkill?.sourcePath === skill.sourcePath}
|
|
159
|
+
className={`grid h-auto w-full min-w-0 justify-start rounded-md border px-3 py-2 text-left transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-8 ${
|
|
164
160
|
selectedSkill?.sourcePath === skill.sourcePath
|
|
165
|
-
? 'primary-
|
|
166
|
-
: 'gray-
|
|
167
|
-
}
|
|
161
|
+
? 'border-primary-7 bg-primary-3 text-primary-12'
|
|
162
|
+
: 'border-transparent bg-transparent text-gray-11 hover:border-gray-6 hover:bg-gray-2 hover:text-gray-12'
|
|
163
|
+
}`}
|
|
164
|
+
onClick={() => setActivePath(skill.sourcePath)}
|
|
168
165
|
type="button"
|
|
169
166
|
>
|
|
170
167
|
<span className="grid min-w-0 gap-1">
|
|
@@ -176,7 +173,7 @@ export function SkillsExplorer({ skills }: { skills: SkillRecord[] }) {
|
|
|
176
173
|
{skill.directory}
|
|
177
174
|
</span>
|
|
178
175
|
</span>
|
|
179
|
-
</
|
|
176
|
+
</button>
|
|
180
177
|
</li>
|
|
181
178
|
))}
|
|
182
179
|
</ul>
|