123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- import { useEffect, useState } from "react";
- import type {
- InkeepBaseSettings,
- InkeepAIChatSettings,
- InkeepSearchSettings,
- } from "@inkeep/cxkit-react";
- const baseSettings: InkeepBaseSettings = {
- apiKey: "815f8fee7a5da7d98c681626dfbd268bdf7f7dc7cb80f618",
- primaryBrandColor: "#9945ff",
- theme: {
- styles: [
- {
- key: "custom-theme",
- type: "style",
- value: `
- #inkeep-widget-root {
- font-size: 1rem;
- }
- .ikp-search-bar__container {
- margin: 0 0 0 16px;
- }
- .ikp-search-bar__button {
- padding: 0px 8px;
- }
- @media (min-width: 768px) {
- .ikp-search-bar__container {
- min-width: 0px;
- }
- }
- @media (max-width: 768px) {
- .ikp-search-bar__icon {
- font-size: 24px;
- color: var(--docsearch-text-color);
- }
- .ikp-search-bar__button {
- border-color: transparent;
- }
- .ikp-search-bar__text {
- display: none;
- }
- .ikp-search-bar__kbd-wrapper {
- display: none;
- }
- .search-bar__content-wrapper {
- gap: 0;
- }
- }
- `,
- },
- ],
- },
- transformSource: source => {
- const urlPatterns = {
- anchorDocs: "https://www.anchor-lang.com/docs",
- solanaDocs: "solana.com",
- stackExchange: "https://solana.stackexchange.com/",
- anzaDocs: "https://docs.anza.xyz/",
- github: "github.com",
- } as const;
- const tabConfig = {
- [urlPatterns.anchorDocs]: {
- tab: "Anchor Docs",
- icon: undefined,
- shouldOpenInNewTab: false,
- getBreadcrumbs: (crumbs: string[]) => crumbs,
- },
- [urlPatterns.solanaDocs]: {
- tab: "Solana Docs",
- icon: undefined,
- shouldOpenInNewTab: true,
- getBreadcrumbs: (crumbs: string[]) => ["Docs", ...crumbs.slice(1)],
- },
- [urlPatterns.anzaDocs]: {
- tab: "Anza Docs",
- icon: undefined,
- shouldOpenInNewTab: true,
- getBreadcrumbs: (crumbs: string[]) => crumbs,
- },
- [urlPatterns.stackExchange]: {
- tab: "Stack Exchange",
- icon: undefined,
- shouldOpenInNewTab: true,
- getBreadcrumbs: (crumbs: string[]) => crumbs,
- },
- [urlPatterns.github]: {
- tab: "GitHub",
- icon: "FaGithub",
- shouldOpenInNewTab: true,
- getBreadcrumbs: (crumbs: string[]) => crumbs,
- },
- } as const;
- // Find matching config based on URL
- const matchingPattern = Object.keys(tabConfig).find(pattern =>
- source.url.includes(pattern),
- );
- const config = matchingPattern
- ? tabConfig[matchingPattern as keyof typeof tabConfig]
- : null;
- if (!config) {
- return source;
- }
- const breadcrumbs = config.getBreadcrumbs(source.breadcrumbs);
- const existingTabs = source.tabs ?? [];
- // Check if tab already exists
- const tabExists = existingTabs.some(existingTab =>
- typeof existingTab === "string"
- ? existingTab === config.tab
- : Array.isArray(existingTab) && existingTab[0] === config.tab,
- );
- const tabs = tabExists
- ? existingTabs
- : [
- ...existingTabs,
- [
- config.tab,
- {
- breadcrumbs:
- breadcrumbs[0] === config.tab
- ? breadcrumbs.slice(1)
- : breadcrumbs,
- },
- ] as const,
- ];
- return {
- ...source,
- breadcrumbs,
- tabs,
- shouldOpenInNewTab: config.shouldOpenInNewTab,
- icon: config.icon ? { builtIn: config.icon } : undefined,
- };
- },
- };
- const searchSettings: InkeepSearchSettings = {
- placeholder: "Search",
- tabs: [
- "All",
- "Anchor Docs",
- "Solana Docs",
- "Anza Docs",
- "Stack Exchange",
- "GitHub",
- ],
- };
- const aiChatSettings: InkeepAIChatSettings = {
- chatSubjectName: "Anchor",
- introMessage:
- "I'm an AI assistant trained on documentation, github repos, and other content. Ask me anything about `Solana`.",
- aiAssistantAvatar: "https://solana.com/favicon.png",
- disclaimerSettings: {
- isEnabled: true,
- label: "",
- },
- toolbarButtonLabels: {
- getHelp: "Get Support",
- },
- getHelpOptions: [
- {
- name: "Discord",
- action: {
- type: "open_link",
- url: "https://discord.com/invite/NHHGSXAnXk",
- },
- icon: {
- builtIn: "FaDiscord",
- },
- },
- {
- name: "Stack Exchange",
- action: {
- type: "open_link",
- url: "https://solana.stackexchange.com/",
- },
- icon: {
- builtIn: "FaStackOverflow",
- },
- },
- ],
- exampleQuestions: [
- "How to quickly install Solana dependencies for local development?",
- "What is the Anchor Framework?",
- "How to build an Anchor Program?",
- ],
- };
- export function useInkeepConfig() {
- const [syncTarget, setSyncTarget] = useState<HTMLElement | null>(null);
- // We do this because document is not available in the server
- useEffect(() => {
- setSyncTarget(document.documentElement);
- }, []);
- return {
- baseSettings: {
- ...baseSettings,
- colorMode: {
- sync: {
- target: syncTarget,
- attributes: ["class"],
- isDarkMode: (attributes: { class: string | string[] }) =>
- !!attributes.class?.includes("dark"),
- },
- },
- },
- searchSettings,
- aiChatSettings,
- };
- }
|