@rfdtech/components 1.21.0 → 2.0.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 +244 -74
- package/dist/adapters/context-adapter.d.ts +18 -0
- package/dist/adapters/context-adapter.d.ts.map +1 -0
- package/dist/adapters/next-adapter.d.ts +23 -0
- package/dist/adapters/next-adapter.d.ts.map +1 -0
- package/dist/adapters/react-router-adapter.d.ts +9 -0
- package/dist/adapters/react-router-adapter.d.ts.map +1 -0
- package/dist/adapters/registry.d.ts +19 -0
- package/dist/adapters/registry.d.ts.map +1 -0
- package/dist/components/app-header/AppHeader.d.ts +3 -2
- package/dist/components/app-header/AppHeader.d.ts.map +1 -1
- package/dist/components/app-header/AppHeaderNotificationItem.d.ts +3 -0
- package/dist/components/app-header/AppHeaderNotificationItem.d.ts.map +1 -0
- package/dist/components/app-header/AppHeaderProfile.d.ts +5 -0
- package/dist/components/app-header/AppHeaderProfile.d.ts.map +1 -1
- package/dist/components/app-header/index.d.ts +4 -2
- package/dist/components/app-header/index.d.ts.map +1 -1
- package/dist/components/app-layout/AppLayout.d.ts +6 -0
- package/dist/components/app-layout/AppLayout.d.ts.map +1 -1
- package/dist/components/app-layout/AppLayoutInner.d.ts +1 -0
- package/dist/components/app-layout/AppLayoutInner.d.ts.map +1 -1
- package/dist/components/app-switcher/AppIconTile.d.ts +10 -0
- package/dist/components/app-switcher/AppIconTile.d.ts.map +1 -0
- package/dist/components/app-switcher/AppSwitcher.d.ts +1 -1
- package/dist/components/app-switcher/AppSwitcher.d.ts.map +1 -1
- package/dist/components/app-switcher/AppSwitcherItem.d.ts.map +1 -1
- package/dist/components/app-switcher/IconPatterns.d.ts +8 -0
- package/dist/components/app-switcher/IconPatterns.d.ts.map +1 -0
- package/dist/components/app-switcher/SystemAppIcon.d.ts.map +1 -1
- package/dist/components/app-switcher/index.d.ts +2 -0
- package/dist/components/app-switcher/index.d.ts.map +1 -1
- package/dist/components/avatar/Avatar.d.ts.map +1 -1
- package/dist/components/bulk-import-modal/BulkImportModal.d.ts.map +1 -1
- package/dist/components/bulk-import-modal/steps/ValidateDataStep.d.ts.map +1 -1
- package/dist/components/button/Button.d.ts +1 -1
- package/dist/components/button/Button.d.ts.map +1 -1
- package/dist/components/button/Spinner.d.ts.map +1 -1
- package/dist/components/combobox/Combobox.d.ts +4 -0
- package/dist/components/combobox/Combobox.d.ts.map +1 -0
- package/dist/components/combobox/Combobox.test.d.ts +2 -0
- package/dist/components/combobox/Combobox.test.d.ts.map +1 -0
- package/dist/components/combobox/index.d.ts +3 -0
- package/dist/components/combobox/index.d.ts.map +1 -0
- package/dist/components/country-selector/CountrySelector.d.ts +7 -0
- package/dist/components/country-selector/CountrySelector.d.ts.map +1 -1
- package/dist/components/country-selector/index.d.ts +1 -0
- package/dist/components/country-selector/index.d.ts.map +1 -1
- package/dist/components/date-range-selector/DateRangeSelector.d.ts +2 -2
- package/dist/components/date-range-selector/DateRangeSelector.d.ts.map +1 -1
- package/dist/components/date-range-selector/index.d.ts +1 -1
- package/dist/components/date-range-selector/index.d.ts.map +1 -1
- package/dist/components/date-selector/DateSelector.d.ts.map +1 -1
- package/dist/components/dropdown/Dropdown.d.ts +1 -1
- package/dist/components/dropdown/Dropdown.d.ts.map +1 -1
- package/dist/components/export-button/ExportButton.d.ts +3 -0
- package/dist/components/export-button/ExportButton.d.ts.map +1 -0
- package/dist/components/export-button/ExportButton.test.d.ts +2 -0
- package/dist/components/export-button/ExportButton.test.d.ts.map +1 -0
- package/dist/components/export-button/index.d.ts +3 -0
- package/dist/components/export-button/index.d.ts.map +1 -0
- package/dist/components/launchpad/Launchpad.d.ts +4 -0
- package/dist/components/launchpad/Launchpad.d.ts.map +1 -0
- package/dist/components/launchpad/Launchpad.test.d.ts +2 -0
- package/dist/components/launchpad/Launchpad.test.d.ts.map +1 -0
- package/dist/components/launchpad/LaunchpadGridIcon.d.ts +2 -0
- package/dist/components/launchpad/LaunchpadGridIcon.d.ts.map +1 -0
- package/dist/components/launchpad/LaunchpadIconTile.d.ts +10 -0
- package/dist/components/launchpad/LaunchpadIconTile.d.ts.map +1 -0
- package/dist/components/launchpad/LaunchpadItem.d.ts +8 -0
- package/dist/components/launchpad/LaunchpadItem.d.ts.map +1 -0
- package/dist/components/launchpad/LaunchpadOverlays.d.ts +3 -0
- package/dist/components/launchpad/LaunchpadOverlays.d.ts.map +1 -0
- package/dist/components/launchpad/SystemLaunchpadIcon.d.ts +5 -0
- package/dist/components/launchpad/SystemLaunchpadIcon.d.ts.map +1 -0
- package/dist/components/launchpad/hooks/useLaunchpad.d.ts +3 -0
- package/dist/components/launchpad/hooks/useLaunchpad.d.ts.map +1 -0
- package/dist/components/launchpad/index.d.ts +10 -0
- package/dist/components/launchpad/index.d.ts.map +1 -0
- package/dist/components/metric-card/MetricCard.d.ts.map +1 -1
- package/dist/components/metric-card/index.d.ts +1 -1
- package/dist/components/metric-card/index.d.ts.map +1 -1
- package/dist/components/network-operator/NetworkOperator.d.ts +4 -0
- package/dist/components/network-operator/NetworkOperator.d.ts.map +1 -1
- package/dist/components/network-operator/index.d.ts +1 -0
- package/dist/components/network-operator/index.d.ts.map +1 -1
- package/dist/components/notice/Notice.d.ts +4 -0
- package/dist/components/notice/Notice.d.ts.map +1 -0
- package/dist/components/notice/Notice.test.d.ts +2 -0
- package/dist/components/notice/Notice.test.d.ts.map +1 -0
- package/dist/components/notice/index.d.ts +3 -0
- package/dist/components/notice/index.d.ts.map +1 -0
- package/dist/components/phone-number-input/PhoneNumberInput.d.ts.map +1 -1
- package/dist/components/popup/Popup.d.ts +15 -0
- package/dist/components/popup/Popup.d.ts.map +1 -0
- package/dist/components/popup/Popup.test.d.ts +2 -0
- package/dist/components/popup/Popup.test.d.ts.map +1 -0
- package/dist/components/popup/index.d.ts +3 -0
- package/dist/components/popup/index.d.ts.map +1 -0
- package/dist/components/profile-popover/ProfilePopover.d.ts +4 -0
- package/dist/components/profile-popover/ProfilePopover.d.ts.map +1 -0
- package/dist/components/profile-popover/ProfilePopover.test.d.ts +2 -0
- package/dist/components/profile-popover/ProfilePopover.test.d.ts.map +1 -0
- package/dist/components/profile-popover/index.d.ts +3 -0
- package/dist/components/profile-popover/index.d.ts.map +1 -0
- package/dist/components/role-select/RoleSelect.d.ts +4 -0
- package/dist/components/role-select/RoleSelect.d.ts.map +1 -0
- package/dist/components/role-select/RoleSelect.test.d.ts +2 -0
- package/dist/components/role-select/RoleSelect.test.d.ts.map +1 -0
- package/dist/components/role-select/index.d.ts +3 -0
- package/dist/components/role-select/index.d.ts.map +1 -0
- package/dist/components/section-header/SectionHeader.d.ts +7 -0
- package/dist/components/section-header/SectionHeader.d.ts.map +1 -0
- package/dist/components/section-header/SectionHeader.test.d.ts +2 -0
- package/dist/components/section-header/SectionHeader.test.d.ts.map +1 -0
- package/dist/components/section-header/index.d.ts +3 -0
- package/dist/components/section-header/index.d.ts.map +1 -0
- package/dist/components/sidebar/Sidebar.d.ts +3 -3
- package/dist/components/sidebar/Sidebar.d.ts.map +1 -1
- package/dist/components/sidebar/SidebarContext.d.ts +6 -0
- package/dist/components/sidebar/SidebarContext.d.ts.map +1 -1
- package/dist/components/sidebar/index.d.ts +1 -1
- package/dist/components/sidebar/index.d.ts.map +1 -1
- package/dist/components/stepper/Stepper.d.ts +12 -0
- package/dist/components/stepper/Stepper.d.ts.map +1 -0
- package/dist/components/stepper/Stepper.test.d.ts +2 -0
- package/dist/components/stepper/Stepper.test.d.ts.map +1 -0
- package/dist/components/stepper/StepperContext.d.ts +4 -0
- package/dist/components/stepper/StepperContext.d.ts.map +1 -0
- package/dist/components/stepper/index.d.ts +3 -0
- package/dist/components/stepper/index.d.ts.map +1 -0
- package/dist/components/switch/Switch.d.ts +4 -0
- package/dist/components/switch/Switch.d.ts.map +1 -0
- package/dist/components/switch/Switch.test.d.ts +2 -0
- package/dist/components/switch/Switch.test.d.ts.map +1 -0
- package/dist/components/switch/index.d.ts +3 -0
- package/dist/components/switch/index.d.ts.map +1 -0
- package/dist/components/table/Table.d.ts +3 -6
- package/dist/components/table/Table.d.ts.map +1 -1
- package/dist/components/table/TableHeader.d.ts +3 -10
- package/dist/components/table/TableHeader.d.ts.map +1 -1
- package/dist/components/table/TablePagination.d.ts.map +1 -1
- package/dist/components/table/index.d.ts +1 -1
- package/dist/components/table/index.d.ts.map +1 -1
- package/dist/components/tabs/Tabs.d.ts.map +1 -1
- package/dist/components/tabs/hooks/useTabsLineIndicator.d.ts.map +1 -1
- package/dist/components/theme/ThemeProvider.d.ts.map +1 -1
- package/dist/components/theme/cletTheme.d.ts +11 -0
- package/dist/components/theme/cletTheme.d.ts.map +1 -0
- package/dist/components/theme/cletTheme.test-d.d.ts +2 -0
- package/dist/components/theme/cletTheme.test-d.d.ts.map +1 -0
- package/dist/components/theme/cletTheme.test.d.ts +2 -0
- package/dist/components/theme/cletTheme.test.d.ts.map +1 -0
- package/dist/components/theme/index.d.ts +3 -1
- package/dist/components/theme/index.d.ts.map +1 -1
- package/dist/components/timeline/Timeline.d.ts +8 -0
- package/dist/components/timeline/Timeline.d.ts.map +1 -0
- package/dist/components/timeline/Timeline.test.d.ts +2 -0
- package/dist/components/timeline/Timeline.test.d.ts.map +1 -0
- package/dist/components/timeline/index.d.ts +3 -0
- package/dist/components/timeline/index.d.ts.map +1 -0
- package/dist/components/upload-field/UploadField.d.ts +5 -0
- package/dist/components/upload-field/UploadField.d.ts.map +1 -1
- package/dist/components/upload-field/index.d.ts +2 -2
- package/dist/components/upload-field/index.d.ts.map +1 -1
- package/dist/contexts/router-adapter-context.d.ts +27 -0
- package/dist/contexts/router-adapter-context.d.ts.map +1 -0
- package/dist/generated/components.theme.d.ts +313 -0
- package/dist/generated/components.theme.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useHasMounted.d.ts +10 -0
- package/dist/hooks/useHasMounted.d.ts.map +1 -0
- package/dist/hooks/useTableFilter.d.ts.map +1 -1
- package/dist/hooks/useTablePagination.d.ts.map +1 -1
- package/dist/hooks/useTableState.d.ts +1 -1
- package/dist/hooks/useTableState.d.ts.map +1 -1
- package/dist/index.cjs +85 -55
- package/dist/index.css +1 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19423 -31378
- package/dist/mcp/cli.js +75 -0
- package/dist/mcp/docs.js +122 -0
- package/dist/mcp/generated/components.json +3593 -0
- package/dist/mcp/generated/examples.json +1233 -0
- package/dist/mcp/generated/index.meta.json +252 -0
- package/dist/mcp/generated/rules.json +629 -0
- package/dist/mcp/generated/search.json +1618 -0
- package/dist/mcp/generated/tokens.json +1022 -0
- package/dist/mcp/index.js +337 -0
- package/dist/mcp/indexer.js +370 -0
- package/dist/mcp/installers/claude.js +37 -0
- package/dist/mcp/installers/codex.js +24 -0
- package/dist/mcp/installers/cursor.js +33 -0
- package/dist/mcp/installers/doctor.js +36 -0
- package/dist/mcp/installers/opencode.js +36 -0
- package/dist/mcp/installers/setup.js +34 -0
- package/dist/mcp/installers/util.js +41 -0
- package/dist/mcp/paths.js +63 -0
- package/dist/mcp/skill/SKILL.md +36 -0
- package/dist/mcp/skill/image-to-components.md +49 -0
- package/dist/next-index.d.ts +44 -0
- package/dist/next-index.d.ts.map +1 -0
- package/dist/next.cjs +282 -0
- package/dist/next.css +1 -0
- package/dist/next.d.ts +29 -0
- package/dist/next.js +37774 -0
- package/dist/types/app-header.d.ts +70 -10
- package/dist/types/app-header.d.ts.map +1 -1
- package/dist/types/app-switcher.d.ts +10 -1
- package/dist/types/app-switcher.d.ts.map +1 -1
- package/dist/types/avatar.d.ts +9 -0
- package/dist/types/avatar.d.ts.map +1 -1
- package/dist/types/combobox.d.ts +43 -0
- package/dist/types/combobox.d.ts.map +1 -0
- package/dist/types/country-selector.d.ts +4 -0
- package/dist/types/country-selector.d.ts.map +1 -1
- package/dist/types/date-range-selector.d.ts +11 -0
- package/dist/types/date-range-selector.d.ts.map +1 -1
- package/dist/types/dropdown.d.ts +8 -0
- package/dist/types/dropdown.d.ts.map +1 -1
- package/dist/types/export-button.d.ts +24 -0
- package/dist/types/export-button.d.ts.map +1 -0
- package/dist/types/launchpad.d.ts +79 -0
- package/dist/types/launchpad.d.ts.map +1 -0
- package/dist/types/metric-card.d.ts +7 -0
- package/dist/types/metric-card.d.ts.map +1 -1
- package/dist/types/network-operator.d.ts +8 -0
- package/dist/types/network-operator.d.ts.map +1 -1
- package/dist/types/notice.d.ts +24 -0
- package/dist/types/notice.d.ts.map +1 -0
- package/dist/types/popup.d.ts +43 -0
- package/dist/types/popup.d.ts.map +1 -0
- package/dist/types/profile-popover.d.ts +97 -0
- package/dist/types/profile-popover.d.ts.map +1 -0
- package/dist/types/role-select.d.ts +28 -0
- package/dist/types/role-select.d.ts.map +1 -0
- package/dist/types/router-adapter.d.ts +46 -0
- package/dist/types/router-adapter.d.ts.map +1 -0
- package/dist/types/section-header.d.ts +26 -0
- package/dist/types/section-header.d.ts.map +1 -0
- package/dist/types/sidebar.d.ts +16 -0
- package/dist/types/sidebar.d.ts.map +1 -1
- package/dist/types/stepper.d.ts +45 -0
- package/dist/types/stepper.d.ts.map +1 -0
- package/dist/types/switch.d.ts +24 -0
- package/dist/types/switch.d.ts.map +1 -0
- package/dist/types/table.d.ts +90 -1
- package/dist/types/table.d.ts.map +1 -1
- package/dist/types/tabs.d.ts +1 -1
- package/dist/types/tabs.d.ts.map +1 -1
- package/dist/types/theme.d.ts +28 -8
- package/dist/types/theme.d.ts.map +1 -1
- package/dist/types/timeline.d.ts +52 -0
- package/dist/types/timeline.d.ts.map +1 -0
- package/dist/types/upload-field.d.ts +23 -0
- package/dist/types/upload-field.d.ts.map +1 -1
- package/dist/utils/export.d.ts +15 -0
- package/dist/utils/export.d.ts.map +1 -0
- package/dist/utils/stringToColor.d.ts +25 -0
- package/dist/utils/stringToColor.d.ts.map +1 -1
- package/package.json +43 -7
- package/scripts/postinstall.mjs +40 -0
package/dist/mcp/cli.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { loadIndex, searchComponents } from "./docs.js";
|
|
3
|
+
import { runDoctor } from "./installers/doctor.js";
|
|
4
|
+
import { runSetup } from "./installers/setup.js";
|
|
5
|
+
import { buildIndex } from "./indexer.js";
|
|
6
|
+
import { GENERATED_DIR, hasRepoSource } from "./paths.js";
|
|
7
|
+
const USAGE = `rfdui — @rfdtech/components AI tooling
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
rfdui setup Detect installed AI tools (Claude Code, Cursor, Codex, OpenCode) and wire up
|
|
11
|
+
the MCP server + a shared skill doc for each.
|
|
12
|
+
rfdui doctor Report whether the index, MCP, and each AI tool are configured correctly.
|
|
13
|
+
rfdui index Rebuild the generated docs index (only works inside the repo checkout).
|
|
14
|
+
rfdui mcp Run the MCP server directly over stdio.
|
|
15
|
+
rfdui search <query> Lexical search over components from the terminal.
|
|
16
|
+
rfdui update Rebuild the index (if possible) and re-run setup.
|
|
17
|
+
`;
|
|
18
|
+
async function main() {
|
|
19
|
+
const [, , cmd, ...rest] = process.argv;
|
|
20
|
+
switch (cmd) {
|
|
21
|
+
case "index": {
|
|
22
|
+
if (!hasRepoSource) {
|
|
23
|
+
console.error("`rfdui index` only works inside the gsl-components repo checkout (no source found).");
|
|
24
|
+
process.exitCode = 1;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const result = await buildIndex(GENERATED_DIR);
|
|
28
|
+
console.log(`Index built: ${JSON.stringify(result, null, 2)}`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
case "search": {
|
|
32
|
+
const query = rest.join(" ").trim();
|
|
33
|
+
if (!query) {
|
|
34
|
+
console.error("Usage: rfdui search <query>");
|
|
35
|
+
process.exitCode = 1;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const idx = await loadIndex();
|
|
39
|
+
const results = searchComponents(idx, query);
|
|
40
|
+
if (results.length === 0) {
|
|
41
|
+
console.log(`No components matched "${query}".`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
for (const r of results) {
|
|
45
|
+
console.log(`${r.slug.padEnd(24)} ${r.name}${r.description ? ` — ${r.description}` : ""}`);
|
|
46
|
+
}
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
case "doctor":
|
|
50
|
+
await runDoctor();
|
|
51
|
+
return;
|
|
52
|
+
case "setup":
|
|
53
|
+
await runSetup();
|
|
54
|
+
return;
|
|
55
|
+
case "update":
|
|
56
|
+
if (hasRepoSource) {
|
|
57
|
+
const result = await buildIndex(GENERATED_DIR);
|
|
58
|
+
console.log(`Index rebuilt: ${JSON.stringify(result)}`);
|
|
59
|
+
}
|
|
60
|
+
await runSetup();
|
|
61
|
+
return;
|
|
62
|
+
case "mcp":
|
|
63
|
+
// Delegate to the server entry point (same process, same stdio streams).
|
|
64
|
+
await import("./index.js");
|
|
65
|
+
return;
|
|
66
|
+
default:
|
|
67
|
+
console.log(USAGE);
|
|
68
|
+
if (cmd && cmd !== "help" && cmd !== "--help")
|
|
69
|
+
process.exitCode = 1;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
main().catch((err) => {
|
|
73
|
+
console.error(err);
|
|
74
|
+
process.exitCode = 1;
|
|
75
|
+
});
|
package/dist/mcp/docs.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { GENERATED_DIR } from "./paths.js";
|
|
4
|
+
async function readJson(name) {
|
|
5
|
+
const raw = await readFile(path.join(GENERATED_DIR, name), "utf8");
|
|
6
|
+
return JSON.parse(raw);
|
|
7
|
+
}
|
|
8
|
+
export async function loadIndex() {
|
|
9
|
+
const [components, search, rules, tokens, examples] = await Promise.all([
|
|
10
|
+
readJson("components.json"),
|
|
11
|
+
readJson("search.json"),
|
|
12
|
+
readJson("rules.json"),
|
|
13
|
+
readJson("tokens.json"),
|
|
14
|
+
readJson("examples.json"),
|
|
15
|
+
]);
|
|
16
|
+
const rulesById = {};
|
|
17
|
+
for (const category of Object.values(rules)) {
|
|
18
|
+
for (const rule of category)
|
|
19
|
+
rulesById[rule.id] = rule;
|
|
20
|
+
}
|
|
21
|
+
return { components, search, rules, rulesById, tokens, examples };
|
|
22
|
+
}
|
|
23
|
+
export function listSlugs(idx) {
|
|
24
|
+
return Object.keys(idx.components).sort();
|
|
25
|
+
}
|
|
26
|
+
export function getComponent(idx, slug) {
|
|
27
|
+
return idx.components[slug.trim().toLowerCase()] ?? null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Lexical ranking over name/slug/keywords/description/headings. No embeddings —
|
|
31
|
+
* this is a local, offline MCP server; ranking is transparent term overlap, not
|
|
32
|
+
* semantic similarity. Good enough for "table pagination" -> Table, "wizard" ->
|
|
33
|
+
* Stepper (via keywords), etc.
|
|
34
|
+
*/
|
|
35
|
+
export function searchComponents(idx, query, limit = 8) {
|
|
36
|
+
const terms = query.toLowerCase().trim().split(/\s+/).filter(Boolean);
|
|
37
|
+
if (terms.length === 0)
|
|
38
|
+
return [];
|
|
39
|
+
const scored = idx.search.map((entry) => {
|
|
40
|
+
const slug = entry.slug.toLowerCase();
|
|
41
|
+
const name = (entry.name ?? "").toLowerCase();
|
|
42
|
+
const keywords = (entry.keywords ?? []).map((k) => k.toLowerCase());
|
|
43
|
+
const description = (entry.description ?? "").toLowerCase();
|
|
44
|
+
const headings = (entry.headings ?? []).map((h) => h.toLowerCase());
|
|
45
|
+
let score = 0;
|
|
46
|
+
for (const term of terms) {
|
|
47
|
+
if (slug === term)
|
|
48
|
+
score += 10;
|
|
49
|
+
if (slug.includes(term))
|
|
50
|
+
score += 5;
|
|
51
|
+
if (name.includes(term))
|
|
52
|
+
score += 4;
|
|
53
|
+
if (keywords.some((k) => k.includes(term)))
|
|
54
|
+
score += 3;
|
|
55
|
+
if (description.includes(term))
|
|
56
|
+
score += 2;
|
|
57
|
+
if (headings.some((h) => h.includes(term)))
|
|
58
|
+
score += 1;
|
|
59
|
+
}
|
|
60
|
+
return { entry, score };
|
|
61
|
+
});
|
|
62
|
+
return scored
|
|
63
|
+
.filter((r) => r.score > 0)
|
|
64
|
+
.sort((a, b) => b.score - a.score)
|
|
65
|
+
.slice(0, limit)
|
|
66
|
+
.map((r) => ({
|
|
67
|
+
slug: r.entry.slug,
|
|
68
|
+
name: r.entry.name,
|
|
69
|
+
category: r.entry.category,
|
|
70
|
+
description: r.entry.description,
|
|
71
|
+
score: r.score,
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
export function searchDocs(idx, query, limit = 8) {
|
|
75
|
+
const terms = query.toLowerCase().trim().split(/\s+/).filter(Boolean);
|
|
76
|
+
if (terms.length === 0)
|
|
77
|
+
return [];
|
|
78
|
+
const results = Object.values(idx.components).map((entry) => {
|
|
79
|
+
const body = entry.docs.toLowerCase();
|
|
80
|
+
const matchedHeadings = entry.headings.filter((h) => terms.some((t) => h.toLowerCase().includes(t)));
|
|
81
|
+
let score = 0;
|
|
82
|
+
for (const term of terms) {
|
|
83
|
+
if (body.includes(term))
|
|
84
|
+
score += 2;
|
|
85
|
+
}
|
|
86
|
+
score += matchedHeadings.length;
|
|
87
|
+
return { slug: entry.meta.slug, name: entry.meta.title, matchedHeadings, score };
|
|
88
|
+
});
|
|
89
|
+
return results
|
|
90
|
+
.filter((r) => r.score > 0)
|
|
91
|
+
.sort((a, b) => b.score - a.score)
|
|
92
|
+
.slice(0, limit);
|
|
93
|
+
}
|
|
94
|
+
/** `topic` may be a rules category (e.g. "forms") or a component slug (e.g. "dialog"). */
|
|
95
|
+
export function getRules(idx, topic) {
|
|
96
|
+
if (!topic)
|
|
97
|
+
return idx.rules;
|
|
98
|
+
const key = topic.trim().toLowerCase();
|
|
99
|
+
if (idx.rules[key])
|
|
100
|
+
return { [key]: idx.rules[key] };
|
|
101
|
+
const matched = [];
|
|
102
|
+
for (const rules of Object.values(idx.rules)) {
|
|
103
|
+
matched.push(...rules.filter((r) => r.components.includes(key)));
|
|
104
|
+
}
|
|
105
|
+
return matched.length ? { [key]: matched } : {};
|
|
106
|
+
}
|
|
107
|
+
export function searchRules(idx, query, limit = 10) {
|
|
108
|
+
const terms = query.toLowerCase().trim().split(/\s+/).filter(Boolean);
|
|
109
|
+
if (terms.length === 0)
|
|
110
|
+
return [];
|
|
111
|
+
const all = Object.values(idx.rules).flat();
|
|
112
|
+
const scored = all.map((rule) => {
|
|
113
|
+
const hay = `${rule.title} ${rule.body} ${rule.components.join(" ")}`.toLowerCase();
|
|
114
|
+
const score = terms.reduce((n, t) => n + (hay.includes(t) ? 1 : 0), 0);
|
|
115
|
+
return { rule, score };
|
|
116
|
+
});
|
|
117
|
+
return scored
|
|
118
|
+
.filter((r) => r.score > 0)
|
|
119
|
+
.sort((a, b) => b.score - a.score)
|
|
120
|
+
.slice(0, limit)
|
|
121
|
+
.map((r) => r.rule);
|
|
122
|
+
}
|