Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/docusaurus-preset/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# `@elastic/eui-docusaurus-preset`

23 changes: 23 additions & 0 deletions packages/docusaurus-preset/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "@elastic/eui-docusaurus-preset",
"description": "EUI preset for Docusaurus",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"scripts": {
"build": "tsc",
"start": "tsc --watch"
},
"repository": {
"type": "git",
"url": "https://github.com/elastic/eui.git",
"directory": "packages/docusaurus-preset"
},
"devDependencies": {
"@docusaurus/types": "^3.7.0",
"typescript": "~5.5.4"
},
"peerDependencies": {
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
}
}
109 changes: 109 additions & 0 deletions packages/docusaurus-preset/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import type {
LoadContext,
PluginConfig,
PluginModule,
PluginOptions,
Preset,
} from '@docusaurus/types';
import { Options } from './options';

/**
* Docusaurus plugin to ignore any Infima stylesheet imports.
* This is needed so that Infima doesn't pollute global CSS scope
* and affect how EUI components are rendered
*/
const ignoreInfimaPlugin: PluginModule = () => ({
name: 'ignore-infima-plugin',
configureWebpack(config: any, isServer: boolean, utils: any) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocking:

We're not using these values, can we remove them?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Removed in 68fe775

return {
module: {
rules: [
{
test: /node_modules\/infima/,
use: 'null-loader',
},
],
},
};
},
});

const makePluginConfig = (
source: string,
options?: PluginOptions
): string | [string, PluginOptions] => {
if (!options) {
return require.resolve(source);
}

return [require.resolve(source), options];
};

export default function preset(
context: LoadContext,
options: Options = {}
): Preset {
const isProd = process.env.NODE_ENV === 'production';

const themes: PluginConfig[] = [
// EUI theme is based on the classic docusaurus theme
require.resolve('@docusaurus/theme-classic'),

require.resolve('@elastic/eui-docusaurus-theme'),
];

const plugins: PluginConfig[] = [
ignoreInfimaPlugin,
makePluginConfig('@docusaurus/plugin-content-docs', options.docs),
makePluginConfig('@docusaurus/plugin-content-pages', options.pages),
makePluginConfig('@docusaurus/plugin-svgr', options.svgr),
];

if (options.blog !== false) {
plugins.push(
makePluginConfig('@docusaurus/plugin-content-blog', options.blog)
);
}

if (isProd) {
plugins.push(
makePluginConfig('@docusaurus/plugin-sitemap', options.sitemap)
);
}

if (options.googleAnalytics) {
plugins.push(
makePluginConfig(
'@docusaurus/plugin-google-analytics',
options.googleAnalytics
)
);
}

if (options.googleTagManager) {
plugins.push(
makePluginConfig(
'@docusaurus/plugin-google-tag-manager',
options.googleTagManager
)
);
}

if (options.gtag) {
plugins.push(
makePluginConfig('@docusaurus/plugin-google-gtag', options.gtag)
);
}

return { themes, plugins };
}

export type { Options };
76 changes: 76 additions & 0 deletions packages/docusaurus-preset/src/options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

// Based on https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-preset-classic/src/options.ts

import type { ThemeConfig as BaseThemeConfig } from '@docusaurus/types';
import type { UserThemeConfig as ClassicThemeConfig } from '@docusaurus/theme-common';

import type { Options as DocsPluginOptions } from '@docusaurus/plugin-content-docs';
import type { Options as BlogPluginOptions } from '@docusaurus/plugin-content-blog';
import type { Options as PagesPluginOptions } from '@docusaurus/plugin-content-pages';
import type { Options as SitemapPluginOptions } from '@docusaurus/plugin-sitemap';
import type { Options as SVGRPluginOptions } from '@docusaurus/plugin-svgr';
import type { Options as ThemeOptions } from '@docusaurus/theme-classic';
import type { Options as GAPluginOptions } from '@docusaurus/plugin-google-analytics';
import type { Options as GtagPluginOptions } from '@docusaurus/plugin-google-gtag';
import type { Options as GTMPluginOptions } from '@docusaurus/plugin-google-tag-manager';

export type Options = {
/**
* Options for `@docusaurus/plugin-content-docs`.
*/
docs?: DocsPluginOptions;

/**
* Options for `@docusaurus/plugin-content-pages`.
*/
pages?: PagesPluginOptions;

/**
* Options for `@docusaurus/plugin-svgr`.
*/
svgr?: SVGRPluginOptions;

/**
* Options for `@docusaurus/plugin-sitemap`.
* Enabled in production builds
*/
sitemap?: SitemapPluginOptions;

/**
* Options for `@docusaurus/theme-classic`.
*/
theme?: ThemeOptions;

/**
* Options for `@docusaurus/plugin-content-blog`.
* Use `false` to disable.
*/
blog?: false | BlogPluginOptions;

/**
* Options for `@docusaurus/plugin-google-analytics`. Only enabled when the
* key is present.
*/
googleAnalytics?: GAPluginOptions;

/**
* Options for `@docusaurus/plugin-google-gtag`. Only enabled when the key
* is present.
*/
gtag?: GtagPluginOptions;

/**
* Options for `@docusaurus/plugin-google-tag-manager`. Only enabled when
* the key is present.
*/
googleTagManager?: GTMPluginOptions;
};

export type ThemeConfig = BaseThemeConfig & ClassicThemeConfig;
57 changes: 57 additions & 0 deletions packages/docusaurus-preset/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"outDir": "lib",
/* Emit */
"target": "ES2020",
"lib": ["ESNext", "DOM"],
"declaration": true,
// These two options will be selectively overridden in each project.
// Utility libraries will have source maps on, but plugins will not.
"declarationMap": false,
"sourceMap": false,
"jsx": "react-jsx",
"jsxImportSource": "@emotion/react",
"importHelpers": true,
"noEmitHelpers": true,

/* Strict Type-Checking Options */
"allowUnreachableCode": false,
// Too hard to turn on
"exactOptionalPropertyTypes": false,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
// `process.env` is usually accessed as property
"noPropertyAccessFromIndexSignature": false,
"noUncheckedIndexedAccess": true,
/* strict family */
"strict": true,
"alwaysStrict": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictBindCallApply": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"useUnknownInCatchVariables": true,
/* Handled by ESLint */
"noUnusedLocals": false,
"noUnusedParameters": false,
"importsNotUsedAsValues": "remove",

/* Module Resolution */
"moduleResolution": "Node",
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"allowJs": true,
"skipLibCheck": true
},
"include": ["src"],
"exclude": [
"node_modules"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ export const AppThemeProvider: FunctionComponent<PropsWithChildren> = ({
}}
>
<EuiProvider
globalStyles={false}
modify={EuiThemeOverrides}
colorMode={colorMode}
theme={theme.provider}
Expand Down
40 changes: 23 additions & 17 deletions packages/docusaurus-theme/src/theme/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,33 @@ const getFooterStyles = ({ euiTheme }: UseEuiTheme) => {
};
};

const Footer = () => {
const _Footer = () => {
const styles = useEuiMemoizedStyles(getFooterStyles);

return (
<footer css={styles.root}>
<EuiText textAlign="center" size="s" css={styles.text}>
EUI is dual-licensed under{' '}
<EuiLink href={ELASTIC_LICENSE_URL}>Elastic License 2.0</EuiLink>
{' and '}
<EuiLink href={SSPL_LICENSE_URL}>
Server Side Public License, v 1
</EuiLink>
{' | '}
Crafted with{' '}
<span role="img" aria-label="love" css={styles.heart}>
</span>{' '}
by <EuiLink href="https://elastic.co">Elastic</EuiLink>
</EuiText>
</footer>
);
};

const Footer = () => {
return (
<EuiThemeProvider colorMode="dark">
<footer css={styles.root}>
<EuiText textAlign="center" size="s" css={styles.text}>
EUI is dual-licensed under{' '}
<EuiLink href={ELASTIC_LICENSE_URL}>Elastic License 2.0</EuiLink>
{' and '}
<EuiLink href={SSPL_LICENSE_URL}>
Server Side Public License, v 1
</EuiLink>
{' | '}
Crafted with{' '}
<span role="img" aria-label="love" css={styles.heart}>
</span>{' '}
by <EuiLink href="https://elastic.co">Elastic</EuiLink>
</EuiText>
</footer>
<_Footer />
</EuiThemeProvider>
);
};
Expand Down
4 changes: 3 additions & 1 deletion packages/docusaurus-theme/src/theme/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { useEuiTheme } from '@elastic/eui';
import { AppThemeProvider } from '../components/theme_context';
import { getGlobalStyles } from './Root.styles';
import { getResetStyles } from './reset.styles';
import { getInfimaStyles } from './infima.styles';

const styles = {
root: css`
Expand All @@ -34,6 +35,7 @@ const _Root: FunctionComponent<PropsWithChildren> = ({ children }) => {
const euiTheme = useEuiTheme();
const globalStyles = getGlobalStyles(euiTheme);
const resetStyles = getResetStyles(euiTheme);
const infimaStyles = getInfimaStyles();

// NOTE: This is a temp. solution
// Emotion styles are loaded dynamically on client in contrast
Expand All @@ -55,7 +57,7 @@ const _Root: FunctionComponent<PropsWithChildren> = ({ children }) => {
rel="stylesheet"
/>
</Head>
<Global styles={[resetStyles, globalStyles]} />
<Global styles={[resetStyles, infimaStyles, globalStyles]} />
<div style={!mounted ? { display: 'none' } : undefined} css={styles.root}>
{children}
</div>
Expand Down
Loading