Skip to content

Commit

Permalink
Refactor virtual module system for layout components (#1383)
Browse files Browse the repository at this point in the history
Co-authored-by: Paul Valladares <85648028+dreyfus92@users.noreply.github.com>
  • Loading branch information
delucis and dreyfus92 committed Jan 19, 2024
1 parent 308854f commit 490c6ef
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 69 deletions.
9 changes: 9 additions & 0 deletions .changeset/chatty-drinks-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@astrojs/starlight': minor
---

Refactors Starlight’s internal virtual module system for components to avoid circular references

This is a change to an internal API.
If you were importing the internal `virtual:starlight/components` module, this no longer exists.
Update your imports to use the individual virtual modules now available for each component, for example `virtual:starlight/components/EditLink`.
4 changes: 3 additions & 1 deletion packages/starlight/components/Footer.astro
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
---
import type { Props } from '../props';
import { EditLink, LastUpdated, Pagination } from 'virtual:starlight/components';
import EditLink from 'virtual:starlight/components/EditLink';
import LastUpdated from 'virtual:starlight/components/LastUpdated';
import Pagination from 'virtual:starlight/components/Pagination';
---

<footer>
Expand Down
12 changes: 5 additions & 7 deletions packages/starlight/components/Header.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
import config from 'virtual:starlight/user-config';
import type { Props } from '../props';
import {
LanguageSelect,
Search,
SiteTitle,
SocialIcons,
ThemeSelect,
} from 'virtual:starlight/components';
import LanguageSelect from 'virtual:starlight/components/LanguageSelect';
import Search from 'virtual:starlight/components/Search';
import SiteTitle from 'virtual:starlight/components/SiteTitle';
import SocialIcons from 'virtual:starlight/components/SocialIcons';
import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
/**
* Render the `Search` component if Pagefind is enabled or the default search component has been overridden.
Expand Down
4 changes: 3 additions & 1 deletion packages/starlight/components/MobileMenuFooter.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
import { LanguageSelect, ThemeSelect, SocialIcons } from 'virtual:starlight/components';
import LanguageSelect from 'virtual:starlight/components/LanguageSelect';
import SocialIcons from 'virtual:starlight/components/SocialIcons';
import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
import type { Props } from '../props';
---

Expand Down
32 changes: 15 additions & 17 deletions packages/starlight/components/Page.astro
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,21 @@ import '../style/shiki.css';
import '../style/util.css';
// Components — can override built-in CSS, but not user CSS.
import {
Banner,
ContentPanel,
PageTitle,
FallbackContentNotice,
Footer,
Header,
Head,
Hero,
MarkdownContent,
PageSidebar,
Sidebar,
SkipLink,
ThemeProvider,
PageFrame,
TwoColumnContent,
} from 'virtual:starlight/components';
import Banner from 'virtual:starlight/components/Banner';
import ContentPanel from 'virtual:starlight/components/ContentPanel';
import FallbackContentNotice from 'virtual:starlight/components/FallbackContentNotice';
import Footer from 'virtual:starlight/components/Footer';
import Head from 'virtual:starlight/components/Head';
import Header from 'virtual:starlight/components/Header';
import Hero from 'virtual:starlight/components/Hero';
import MarkdownContent from 'virtual:starlight/components/MarkdownContent';
import PageFrame from 'virtual:starlight/components/PageFrame';
import PageSidebar from 'virtual:starlight/components/PageSidebar';
import PageTitle from 'virtual:starlight/components/PageTitle';
import Sidebar from 'virtual:starlight/components/Sidebar';
import SkipLink from 'virtual:starlight/components/SkipLink';
import ThemeProvider from 'virtual:starlight/components/ThemeProvider';
import TwoColumnContent from 'virtual:starlight/components/TwoColumnContent';
// Remark component CSS (needs to override `MarkdownContent.astro`)
import '../style/asides.css';
Expand Down
2 changes: 1 addition & 1 deletion packages/starlight/components/PageFrame.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
import { MobileMenuToggle } from 'virtual:starlight/components';
import MobileMenuToggle from 'virtual:starlight/components/MobileMenuToggle';
import type { Props } from '../props';
const { hasSidebar, labels } = Astro.props;
Expand Down
7 changes: 4 additions & 3 deletions packages/starlight/components/PageSidebar.astro
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
import type { Props } from '../props';
import { TableOfContents, MobileTableOfContents } from 'virtual:starlight/components';
import MobileTableOfContents from 'virtual:starlight/components/MobileTableOfContents';
import TableOfContents from 'virtual:starlight/components/TableOfContents';
---

{
Expand Down Expand Up @@ -33,14 +34,14 @@ import { TableOfContents, MobileTableOfContents } from 'virtual:starlight/compon
line-height: var(--sl-line-height-headings);
margin-bottom: 0.5rem;
}
.right-sidebar-panel :global(a) {
.right-sidebar-panel :global(:where(a)) {
display: block;
font-size: var(--sl-text-xs);
text-decoration: none;
color: var(--sl-color-gray-3);
overflow-wrap: anywhere;
}
.right-sidebar-panel :global(a:hover) {
.right-sidebar-panel :global(:where(a):hover) {
color: var(--sl-color-white);
}
@media (min-width: 72rem) {
Expand Down
2 changes: 1 addition & 1 deletion packages/starlight/components/Sidebar.astro
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
import type { Props } from '../props';
import { MobileMenuFooter } from 'virtual:starlight/components';
import MobileMenuFooter from 'virtual:starlight/components/MobileMenuFooter';
import SidebarSublist from './SidebarSublist.astro';
const { sidebar } = Astro.props;
Expand Down
11 changes: 8 additions & 3 deletions packages/starlight/integrations/virtual-user-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ export function vitePluginStarlightUserConfig(
const resolveId = (id: string) =>
JSON.stringify(id.startsWith('.') ? resolve(fileURLToPath(root), id) : id);

const virtualComponentModules = Object.fromEntries(
Object.entries(opts.components).map(([name, path]) => [
`virtual:starlight/components/${name}`,
`export { default } from ${resolveId(path)};`,
])
);

/** Map of virtual module names to their code contents as strings. */
const modules = {
'virtual:starlight/user-config': `export default ${JSON.stringify(opts)}`,
Expand All @@ -41,9 +48,7 @@ export function vitePluginStarlightUserConfig(
opts.logo.light
)}; export const logos = { dark, light };`
: 'export const logos = {};',
'virtual:starlight/components': Object.entries(opts.components)
.map(([name, path]) => `export { default as ${name} } from ${resolveId(path)};`)
.join(''),
...virtualComponentModules,
} satisfies Record<string, string>;

/** Mapping names prefixed with `\0` to their original form. */
Expand Down
149 changes: 114 additions & 35 deletions packages/starlight/virtual.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,39 +24,118 @@ declare module 'virtual:starlight/user-images' {
};
}

declare module 'virtual:starlight/components' {
export const Banner: typeof import('./components/Banner.astro').default;
export const ContentPanel: typeof import('./components/ContentPanel.astro').default;
export const PageTitle: typeof import('./components/PageTitle.astro').default;
export const FallbackContentNotice: typeof import('./components/FallbackContentNotice.astro').default;

export const Footer: typeof import('./components/Footer.astro').default;
export const LastUpdated: typeof import('./components/LastUpdated.astro').default;
export const Pagination: typeof import('./components/Pagination.astro').default;
export const EditLink: typeof import('./components/EditLink.astro').default;

export const Header: typeof import('./components/Header.astro').default;
export const LanguageSelect: typeof import('./components/LanguageSelect.astro').default;
export const Search: typeof import('./components/Search.astro').default;
export const SiteTitle: typeof import('./components/SiteTitle.astro').default;
export const SocialIcons: typeof import('./components/SocialIcons.astro').default;
export const ThemeSelect: typeof import('./components/ThemeSelect.astro').default;

export const Head: typeof import('./components/Head.astro').default;
export const Hero: typeof import('./components/Hero.astro').default;
export const MarkdownContent: typeof import('./components/MarkdownContent.astro').default;

export const PageSidebar: typeof import('./components/PageSidebar.astro').default;
export const TableOfContents: typeof import('./components/TableOfContents.astro').default;
export const MobileTableOfContents: typeof import('./components/MobileTableOfContents.astro').default;

export const Sidebar: typeof import('./components/Sidebar.astro').default;
export const SkipLink: typeof import('./components/SkipLink.astro').default;
export const ThemeProvider: typeof import('./components/ThemeProvider.astro').default;

export const PageFrame: typeof import('./components/PageFrame.astro').default;
export const MobileMenuToggle: typeof import('./components/MobileMenuToggle.astro').default;
export const MobileMenuFooter: typeof import('./components/MobileMenuFooter.astro').default;

export const TwoColumnContent: typeof import('./components/TwoColumnContent.astro').default;
declare module 'virtual:starlight/components/Banner' {
const Banner: typeof import('./components/Banner.astro').default;
export default Banner;
}
declare module 'virtual:starlight/components/ContentPanel' {
const ContentPanel: typeof import('./components/ContentPanel.astro').default;
export default ContentPanel;
}
declare module 'virtual:starlight/components/PageTitle' {
const PageTitle: typeof import('./components/PageTitle.astro').default;
export default PageTitle;
}
declare module 'virtual:starlight/components/FallbackContentNotice' {
const FallbackContentNotice: typeof import('./components/FallbackContentNotice.astro').default;
export default FallbackContentNotice;
}

declare module 'virtual:starlight/components/Footer' {
const Footer: typeof import('./components/Footer.astro').default;
export default Footer;
}
declare module 'virtual:starlight/components/LastUpdated' {
const LastUpdated: typeof import('./components/LastUpdated.astro').default;
export default LastUpdated;
}
declare module 'virtual:starlight/components/Pagination' {
const Pagination: typeof import('./components/Pagination.astro').default;
export default Pagination;
}
declare module 'virtual:starlight/components/EditLink' {
const EditLink: typeof import('./components/EditLink.astro').default;
export default EditLink;
}

declare module 'virtual:starlight/components/Header' {
const Header: typeof import('./components/Header.astro').default;
export default Header;
}
declare module 'virtual:starlight/components/LanguageSelect' {
const LanguageSelect: typeof import('./components/LanguageSelect.astro').default;
export default LanguageSelect;
}
declare module 'virtual:starlight/components/Search' {
const Search: typeof import('./components/Search.astro').default;
export default Search;
}
declare module 'virtual:starlight/components/SiteTitle' {
const SiteTitle: typeof import('./components/SiteTitle.astro').default;
export default SiteTitle;
}
declare module 'virtual:starlight/components/SocialIcons' {
const SocialIcons: typeof import('./components/SocialIcons.astro').default;
export default SocialIcons;
}
declare module 'virtual:starlight/components/ThemeSelect' {
const ThemeSelect: typeof import('./components/ThemeSelect.astro').default;
export default ThemeSelect;
}

declare module 'virtual:starlight/components/Head' {
const Head: typeof import('./components/Head.astro').default;
export default Head;
}
declare module 'virtual:starlight/components/Hero' {
const Hero: typeof import('./components/Hero.astro').default;
export default Hero;
}
declare module 'virtual:starlight/components/MarkdownContent' {
const MarkdownContent: typeof import('./components/MarkdownContent.astro').default;
export default MarkdownContent;
}

declare module 'virtual:starlight/components/PageSidebar' {
const PageSidebar: typeof import('./components/PageSidebar.astro').default;
export default PageSidebar;
}
declare module 'virtual:starlight/components/TableOfContents' {
const TableOfContents: typeof import('./components/TableOfContents.astro').default;
export default TableOfContents;
}
declare module 'virtual:starlight/components/MobileTableOfContents' {
const MobileTableOfContents: typeof import('./components/MobileTableOfContents.astro').default;
export default MobileTableOfContents;
}

declare module 'virtual:starlight/components/Sidebar' {
const Sidebar: typeof import('./components/Sidebar.astro').default;
export default Sidebar;
}
declare module 'virtual:starlight/components/SkipLink' {
const SkipLink: typeof import('./components/SkipLink.astro').default;
export default SkipLink;
}
declare module 'virtual:starlight/components/ThemeProvider' {
const ThemeProvider: typeof import('./components/ThemeProvider.astro').default;
export default ThemeProvider;
}

declare module 'virtual:starlight/components/PageFrame' {
const PageFrame: typeof import('./components/PageFrame.astro').default;
export default PageFrame;
}
declare module 'virtual:starlight/components/MobileMenuToggle' {
const MobileMenuToggle: typeof import('./components/MobileMenuToggle.astro').default;
export default MobileMenuToggle;
}
declare module 'virtual:starlight/components/MobileMenuFooter' {
const MobileMenuFooter: typeof import('./components/MobileMenuFooter.astro').default;
export default MobileMenuFooter;
}

declare module 'virtual:starlight/components/TwoColumnContent' {
const TwoColumnContent: typeof import('./components/TwoColumnContent.astro').default;
export default TwoColumnContent;
}

0 comments on commit 490c6ef

Please sign in to comment.