UI: Support fd-* prefixes to Tailwind CSS utils

This commit is contained in:
Fuma Nama
2025-01-16 22:00:59 +08:00
parent a2a6d99a33
commit a9593745e2
4 changed files with 68 additions and 48 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'fumadocs-ui': patch
---
Support `fd-*` prefixes to Tailwind CSS utils
@@ -13,8 +13,8 @@ description: Build your own content source
You can see examples to use Fumadocs with a CMS, which allows a nice experience on publishing content, and real-time update without re-building the app.
BaseHub: https://github.com/fuma-nama/fumadocs-basehub
Sanity: https://github.com/fuma-nama/fumadocs-sanity
- [BaseHub](https://github.com/fuma-nama/fumadocs-basehub)
- [Sanity](https://github.com/fuma-nama/fumadocs-sanity)
For a custom content source implementation, you will need:
+4 -12
View File
@@ -1,17 +1,9 @@
import type { ReactNode } from 'react';
export function Steps({
children,
}: {
children: ReactNode;
}): React.ReactElement {
return <div className="steps">{children}</div>;
export function Steps({ children }: { children: ReactNode }) {
return <div className="fd-steps">{children}</div>;
}
export function Step({
children,
}: {
children: ReactNode;
}): React.ReactElement {
return <div className="step">{children}</div>;
export function Step({ children }: { children: ReactNode }) {
return <div className="fd-step">{children}</div>;
}
+57 -34
View File
@@ -43,6 +43,14 @@ export interface DocsUIOptions
preset?: keyof typeof presets | Preset;
typography?: TypographyOptions;
// TODO: disable by default at next major/minor
/**
* Add Fumadocs UI `fd-*` utilities
*
* @defaultValue true
*/
addGlobalUtils?: boolean;
}
type Keys =
@@ -119,8 +127,51 @@ function createTailwindColors(
return Object.fromEntries(v.entries());
}
function createTailwindUtilities(prefix: string): CSSRuleObject {
const append = prefix.length > 0 ? prefix + '-' : prefix;
return {
[`.${append}steps`]: {
'counter-reset': 'step',
'border-left-width': '1px',
'margin-left': '1rem',
'padding-left': '1.75rem',
position: 'relative',
},
[`.${append}step:before`]: {
'background-color': `theme('colors.fd-secondary.DEFAULT')`,
color: `theme('colors.fd-secondary.foreground')`,
content: 'counter(step)',
'counter-increment': 'step',
'border-radius': `theme('borderRadius.full')`,
'justify-content': 'center',
'align-items': 'center',
width: '2rem',
height: '2rem',
'font-size': '.875rem',
'line-height': '1.25rem',
display: 'flex',
position: 'absolute',
left: '-1rem',
},
'.prose-no-margin': {
'& > :first-child': {
marginTop: '0',
},
'& > :last-child': {
marginBottom: '0',
},
},
};
}
export const docsUi = plugin.withOptions<DocsUIOptions>(
({ cssPrefix = 'fd', preset = 'default', layoutWidth = '100vw' } = {}) => {
({
cssPrefix = 'fd',
preset = 'default',
layoutWidth = '100vw',
addGlobalUtils = true,
} = {}) => {
return ({ addBase, addComponents, addUtilities }) => {
const { light, dark, css } =
typeof preset === 'string' ? presets[preset] : preset;
@@ -208,39 +259,11 @@ export const docsUi = plugin.withOptions<DocsUIOptions>(
},
});
addUtilities({
'.steps': {
'counter-reset': 'step',
'border-left-width': '1px',
'margin-left': '1rem',
'padding-left': '1.75rem',
position: 'relative',
},
'.step:before': {
'background-color': `theme('colors.fd-secondary.DEFAULT')`,
color: `theme('colors.fd-secondary.foreground')`,
content: 'counter(step)',
'counter-increment': 'step',
'border-radius': `theme('borderRadius.full')`,
'justify-content': 'center',
'align-items': 'center',
width: '2rem',
height: '2rem',
'font-size': '.875rem',
'line-height': '1.25rem',
display: 'flex',
position: 'absolute',
left: '-1rem',
},
'.prose-no-margin': {
'& > :first-child': {
marginTop: '0',
},
'& > :last-child': {
marginBottom: '0',
},
},
});
if (addGlobalUtils) {
addUtilities(createTailwindUtilities(''));
}
addUtilities(createTailwindUtilities('fd'));
};
},
({