@terra-symposium/docs 0.2.0 → 0.2.1

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.
Files changed (63) hide show
  1. package/README.md +4 -0
  2. package/bin/generate-skills.mjs +1 -3
  3. package/bin/terra-docs.mjs +1 -3
  4. package/dist/lib/components/LocalDocsWorkspace.d.ts +3 -0
  5. package/dist/lib/components/LocalDocsWorkspace.d.ts.map +1 -1
  6. package/dist/lib/components/LocalDocsWorkspace.js +2 -2
  7. package/dist/lib/components/LocalDocsWorkspace.js.map +1 -1
  8. package/dist/lib/components/SiteLayout.d.ts +3 -1
  9. package/dist/lib/components/SiteLayout.d.ts.map +1 -1
  10. package/dist/lib/components/SiteLayout.js +2 -2
  11. package/dist/lib/components/SiteLayout.js.map +1 -1
  12. package/dist/lib/components/StaticWorkspace.d.ts +4 -1
  13. package/dist/lib/components/StaticWorkspace.d.ts.map +1 -1
  14. package/dist/lib/components/StaticWorkspace.js +2 -2
  15. package/dist/lib/components/StaticWorkspace.js.map +1 -1
  16. package/dist/lib/components/StrictLocalWorkspaceHarness.d.ts +5 -0
  17. package/dist/lib/components/StrictLocalWorkspaceHarness.d.ts.map +1 -1
  18. package/dist/lib/components/StrictLocalWorkspaceHarness.js +14 -1
  19. package/dist/lib/components/StrictLocalWorkspaceHarness.js.map +1 -1
  20. package/dist/lib/components/blocks.d.ts +1 -1
  21. package/dist/lib/components/blocks.d.ts.map +1 -1
  22. package/dist/lib/components/blocks.js +6 -0
  23. package/dist/lib/components/blocks.js.map +1 -1
  24. package/dist/lib/components/quiz.d.ts +51 -0
  25. package/dist/lib/components/quiz.d.ts.map +1 -0
  26. package/dist/lib/components/quiz.js +167 -0
  27. package/dist/lib/components/quiz.js.map +1 -0
  28. package/dist/lib/components/terra/Workspace.d.ts.map +1 -1
  29. package/dist/lib/components/terra/Workspace.js +2 -1
  30. package/dist/lib/components/terra/Workspace.js.map +1 -1
  31. package/dist/lib/components/terra/editor/ContentEditor.d.ts.map +1 -1
  32. package/dist/lib/components/terra/editor/ContentEditor.js +2 -0
  33. package/dist/lib/components/terra/editor/ContentEditor.js.map +1 -1
  34. package/dist/lib/components/terra/editor/docs/TerraToolbar.d.ts.map +1 -1
  35. package/dist/lib/components/terra/editor/docs/TerraToolbar.js +1 -0
  36. package/dist/lib/components/terra/editor/docs/TerraToolbar.js.map +1 -1
  37. package/dist/lib/components/terra/pages/docs/_icons.d.ts +1 -0
  38. package/dist/lib/components/terra/pages/docs/_icons.d.ts.map +1 -1
  39. package/dist/lib/components/terra/pages/docs/_icons.js +1 -0
  40. package/dist/lib/components/terra/pages/docs/_icons.js.map +1 -1
  41. package/dist/lib/components/terra/pages/docs/_sidebar.js +2 -2
  42. package/dist/lib/components/terra/pages/docs/_sidebar.js.map +1 -1
  43. package/dist/lib/components/terra/pages/docs/_toc.js +1 -1
  44. package/dist/lib/components/terra/pages/docs/_toc.js.map +1 -1
  45. package/dist/lib/components/terra/pages/docs/_toolbar.d.ts.map +1 -1
  46. package/dist/lib/components/terra/pages/docs/_toolbar.js +12 -9
  47. package/dist/lib/components/terra/pages/docs/_toolbar.js.map +1 -1
  48. package/dist/lib/lib/host.d.ts +3 -0
  49. package/dist/lib/lib/host.d.ts.map +1 -1
  50. package/dist/lib/lib/index.d.ts +3 -0
  51. package/dist/lib/lib/index.d.ts.map +1 -1
  52. package/dist/lib/lib/index.js +2 -0
  53. package/dist/lib/lib/index.js.map +1 -1
  54. package/dist/lib/lib/schema.d.ts +2 -2
  55. package/dist/lib/lib/terra/runtime/types.d.ts +6 -0
  56. package/dist/lib/lib/terra/runtime/types.d.ts.map +1 -1
  57. package/dist/lib/lib/terra/runtime/types.js +1 -0
  58. package/dist/lib/lib/terra/runtime/types.js.map +1 -1
  59. package/dist/lib/style.css +1 -1
  60. package/package.json +1 -1
  61. package/site/astro.config.mjs +27 -22
  62. package/site/src/components/DocsSiteSearch.tsx +51 -33
  63. package/site/src/lib/catalog.ts +1 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@terra-symposium/docs",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Docs workspace and Markdown site generator.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -56,14 +56,14 @@ function astroPackageExportAliases() {
56
56
  replacement: resolve(astroPackageRoot, 'dist/runtime/$1'),
57
57
  },
58
58
  ...Object.keys(astroManifest.exports)
59
- .filter((key) => key.startsWith('./') && !key.includes('*'))
60
- .map((key) => {
61
- const specifier = `astro${key.slice(1)}`;
62
- return {
63
- find: new RegExp(`^${specifier.replace(/[|\\{}()[\]^$+?.]/g, '\\$&')}$`),
64
- replacement: requireFromPackage.resolve(specifier),
65
- };
66
- }),
59
+ .filter((key) => key.startsWith('./') && !key.includes('*'))
60
+ .map((key) => {
61
+ const specifier = `astro${key.slice(1)}`;
62
+ return {
63
+ find: new RegExp(`^${specifier.replace(/[|\\{}()[\]^$+?.]/g, '\\$&')}$`),
64
+ replacement: requireFromPackage.resolve(specifier),
65
+ };
66
+ }),
67
67
  ];
68
68
  }
69
69
 
@@ -119,7 +119,12 @@ function stylingDependencyAliases() {
119
119
  : dependencyManifest('@terra-symposium/styling', requireFromProject);
120
120
  if (!stylingManifest) return [];
121
121
  return Object.keys(stylingManifest.dependencies ?? {})
122
- .filter((name) => name !== 'react' && name !== 'react-dom' && (name.includes('react') || ['cmdk', 'vaul'].includes(name)))
122
+ .filter(
123
+ (name) =>
124
+ name !== 'react' &&
125
+ name !== 'react-dom' &&
126
+ (name.includes('react') || ['cmdk', 'vaul'].includes(name)),
127
+ )
123
128
  .flatMap((name) => {
124
129
  const manifest = dependencyManifest(name, requireFromProject);
125
130
  if (!manifest) return [];
@@ -152,19 +157,19 @@ function sharedReactAliases() {
152
157
  ];
153
158
  return [
154
159
  ...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
- }
164
- return {
165
- find: new RegExp(`^${specifier.replace(/[|\\{}()[\]^$+?.]/g, '\\$&')}$`),
166
- replacement,
167
- };
160
+ let replacement;
161
+ try {
162
+ // Externalized component dependencies resolve React from the consumer's
163
+ // installation during SSR. Prefer that same copy for bundled imports.
164
+ replacement = requireFromProject.resolve(specifier);
165
+ } catch {
166
+ // Content-only repositories can rely on the React runtime shipped by Docs.
167
+ replacement = requireFromPackage.resolve(specifier);
168
+ }
169
+ return {
170
+ find: new RegExp(`^${specifier.replace(/[|\\{}()[\]^$+?.]/g, '\\$&')}$`),
171
+ replacement,
172
+ };
168
173
  }),
169
174
  {
170
175
  // The Docs editor imports `react-dom/server` for Markdown previews. Its
@@ -7,7 +7,15 @@ IMPORTS
7
7
  //////////////////////////////////////////////////*/
8
8
 
9
9
  // API
10
- import { useEffect, useMemo, useRef, useState } from 'react';
10
+ import { useEffect, useMemo, useState } from 'react';
11
+ import {
12
+ CommandDialog,
13
+ CommandEmpty,
14
+ CommandGroup,
15
+ CommandInput,
16
+ CommandItem,
17
+ CommandList,
18
+ } from '@terra-symposium/styling/ui';
11
19
 
12
20
  /*//////////////////////////////////////////////////
13
21
  CONFIG
@@ -54,8 +62,6 @@ COMPONENTS
54
62
  * @return Search controls, loading and error states, and links to matching pages.
55
63
  */
56
64
  export function DocsSiteSearch({ base = '/' }: Props) {
57
- const dialog = useRef<HTMLDialogElement>(null);
58
- const input = useRef<HTMLInputElement>(null);
59
65
  const [query, setQuery] = useState('');
60
66
  const [documents, setDocuments] = useState<SearchDocument[]>([]);
61
67
  const [loaded, setLoaded] = useState(false);
@@ -68,9 +74,7 @@ export function DocsSiteSearch({ base = '/' }: Props) {
68
74
  * @return Nothing; the callback updates dialog state and browser focus.
69
75
  */
70
76
  const open = () => {
71
- if (!dialog.current?.open) dialog.current?.showModal();
72
77
  setOpened(true);
73
- window.setTimeout(() => input.current?.focus(), 0);
74
78
  };
75
79
  useEffect(() => {
76
80
  /**
@@ -137,35 +141,49 @@ export function DocsSiteSearch({ base = '/' }: Props) {
137
141
  .slice(0, 10);
138
142
  }, [documents, query]);
139
143
  return (
140
- <div className="terra-docs-search">
141
- <dialog className="terra-docs-search-dialog" ref={dialog} onClose={() => setQuery('')}>
142
- <div className="terra-docs-search-panel">
143
- <label className="terra-docs-search-input-row">
144
- <span aria-hidden="true">⌕</span>
145
- <input
146
- ref={input}
147
- value={query}
148
- onChange={(event) => setQuery(event.currentTarget.value)}
149
- placeholder="Search documentation…"
150
- />
151
- <button type="button" onClick={() => dialog.current?.close()} aria-label="Close search">
152
- Esc
153
- </button>
154
- </label>
155
- <div className="terra-docs-search-results" aria-live="polite">
156
- {failed ? <p>Search is unavailable right now.</p> : null}
157
- {!loaded && !failed ? <p>Loading search…</p> : null}
158
- {loaded && query.trim() && results.length === 0 ? <p>No matching pages.</p> : null}
144
+ <CommandDialog
145
+ open={opened}
146
+ onOpenChange={(nextOpen) => {
147
+ setOpened(nextOpen);
148
+ if (!nextOpen) setQuery('');
149
+ }}
150
+ size="lg"
151
+ className="max-w-2xl"
152
+ aria-label="Search documentation"
153
+ >
154
+ <CommandInput value={query} onValueChange={setQuery} placeholder="Search documentation…" />
155
+ <CommandList className="max-h-[min(60vh,32rem)] p-2">
156
+ {failed ? <CommandEmpty>Search is unavailable right now.</CommandEmpty> : null}
157
+ {!loaded && !failed ? <CommandEmpty>Loading search…</CommandEmpty> : null}
158
+ {loaded && query.trim() && results.length === 0 ? (
159
+ <CommandEmpty>No matching pages.</CommandEmpty>
160
+ ) : null}
161
+ {results.length > 0 ? (
162
+ <CommandGroup>
159
163
  {results.map(({ document }) => (
160
- <a key={document.href} href={document.href} onClick={() => dialog.current?.close()}>
161
- <strong>{document.title}</strong>
162
- {document.description ? <span>{document.description}</span> : null}
163
- <small>{excerpt(document.text, query.trim().split(S_REGEX)[0] ?? query)}</small>
164
- </a>
164
+ <CommandItem
165
+ key={document.href}
166
+ value={`${document.title} ${document.description} ${document.text}`}
167
+ onSelect={() => {
168
+ window.location.assign(document.href);
169
+ setOpened(false);
170
+ }}
171
+ className="items-start py-3"
172
+ >
173
+ <span className="flex min-w-0 flex-col gap-1">
174
+ <strong>{document.title}</strong>
175
+ {document.description ? (
176
+ <span className="text-sm text-primary-11">{document.description}</span>
177
+ ) : null}
178
+ <small className="line-clamp-2 text-xs text-primary-10">
179
+ {excerpt(document.text, query.trim().split(S_REGEX)[0] ?? query)}
180
+ </small>
181
+ </span>
182
+ </CommandItem>
165
183
  ))}
166
- </div>
167
- </div>
168
- </dialog>
169
- </div>
184
+ </CommandGroup>
185
+ ) : null}
186
+ </CommandList>
187
+ </CommandDialog>
170
188
  );
171
189
  }
@@ -201,9 +201,7 @@ export function pageForSlug(slug: string): SitePage | undefined {
201
201
  return sitePages.find((page) => page.slug === slug);
202
202
  }
203
203
  if (sitePages.length === 0)
204
- throw new Error(
205
- 'No Markdown files found in docs/. Add docs/index.md to start a Docs site.',
206
- );
204
+ throw new Error('No Markdown files found in docs/. Add docs/index.md to start a Docs site.');
207
205
  for (const page of sitePages.filter((i) => !i.hidden && i.slug !== '404')) {
208
206
  const segments = page.slug.split('/').filter(Boolean);
209
207
  let currentNodes = rootNodes;