mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
feat(docs): comparative code section done
This commit is contained in:
parent
45c9f47865
commit
a379fa3d21
@ -6,8 +6,8 @@
|
||||
{
|
||||
"root": ["./"],
|
||||
"alias": {
|
||||
"@components": "./src/components",
|
||||
"@content": "./content",
|
||||
"@components": "./src/components",
|
||||
"@layouts": "./src/layouts",
|
||||
"@hooks": "./src/hooks",
|
||||
"@utils": "./src/utils",
|
||||
|
||||
101
apps/docs/content/landing/index.tsx
Normal file
101
apps/docs/content/landing/index.tsx
Normal file
@ -0,0 +1,101 @@
|
||||
import React from 'react';
|
||||
import { Moon, Magic, Flash, Devices } from '@components';
|
||||
|
||||
export default {
|
||||
topFeatures: [
|
||||
{
|
||||
title: 'Themeable',
|
||||
description:
|
||||
'Provides a simple way to customize default themes, you can change the colors, fonts, breakpoints and everything you need.',
|
||||
icon: <Magic fill="#FF4ECD" />
|
||||
},
|
||||
{
|
||||
title: 'Fast',
|
||||
description:
|
||||
'Avoids unnecessary styles props at runtime, making it more performant than other UI libraries.',
|
||||
icon: <Flash fill="#FF4ECD" />
|
||||
},
|
||||
{
|
||||
title: 'Light & Dark UI',
|
||||
description:
|
||||
'Automatic dark mode recognition, NextUI automatically changes the theme when detects HTML theme prop changes.',
|
||||
icon: <Moon fill="#FF4ECD" />
|
||||
},
|
||||
{
|
||||
title: 'Unique DX',
|
||||
description:
|
||||
'NextUI is fully-typed to minimize the learning curve, and provide the best possible developer experience.',
|
||||
icon: <Devices fill="#FF4ECD" />
|
||||
}
|
||||
],
|
||||
comparativeCode: {
|
||||
nextui: `import * as React from 'react';
|
||||
import { Input } from '@nextui-org/react';
|
||||
|
||||
const MyComponent = () => {
|
||||
return (
|
||||
<Input.Password bordered labelPlaceholder="Password" />
|
||||
);
|
||||
};
|
||||
|
||||
export default MyComponent
|
||||
`,
|
||||
others: `import * as React from 'react';
|
||||
import ButtonIcon from '@other-library/ButtonIcon';
|
||||
import InputOutlined from '@other-library/InputOutlined';
|
||||
import LabelInput from '@other-library/LabelInput';
|
||||
import AdornmentInput from '@other-library/AdornmentInput';
|
||||
import ControlForm from '@other-library/ControlForm';
|
||||
import EyeIcon from '@other-library/icons/EyeIcon';
|
||||
import EyeIconOff from '@other-library/icons/EyeIconOff';
|
||||
|
||||
const MyComponent = () => {
|
||||
const [values, setValues] = React.useState({
|
||||
password: '',
|
||||
showPassword: false
|
||||
});
|
||||
|
||||
const handleChange = (event) => {
|
||||
setValues({ ...values, password: event.target.value });
|
||||
};
|
||||
|
||||
const handleClickShowPassword = () => {
|
||||
setValues({
|
||||
...values,
|
||||
showPassword: !values.showPassword
|
||||
});
|
||||
};
|
||||
|
||||
const handleMouseDownPassword = (event) => {
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
return (
|
||||
<ControlForm sx={{ m: 1, width: '25ch' }} variant="outlined">
|
||||
<LabelInput htmlFor="outlined-adornment-password">Password</LabelInput>
|
||||
<InputOutlined
|
||||
id="outlined-adornment-password"
|
||||
type={values.showPassword ? 'text' : 'password'}
|
||||
value={values.password}
|
||||
onChange={handleChange}
|
||||
endAdornment={
|
||||
<AdornmentInput position="end">
|
||||
<ButtonIcon
|
||||
aria-label="toggle password visibility"
|
||||
onClick={handleClickShowPassword}
|
||||
onMouseDown={handleMouseDownPassword}
|
||||
edge="end"
|
||||
>
|
||||
{values.showPassword ? <EyeIcon /> : <EyeIconOff />}
|
||||
</ButtonIcon>
|
||||
</AdornmentInput>
|
||||
}
|
||||
label="Password"
|
||||
/>
|
||||
</ControlForm>
|
||||
);
|
||||
};
|
||||
|
||||
export default MyComponent;`
|
||||
}
|
||||
};
|
||||
@ -19,12 +19,14 @@
|
||||
"algoliasearch": "^4.10.3",
|
||||
"classnames": "^2.3.1",
|
||||
"gray-matter": "^4.0.3",
|
||||
"hast-util-to-html": "7.1.2",
|
||||
"kbar": "0.1.0-beta.6",
|
||||
"lodash": "^4.17.21",
|
||||
"match-sorter": "^6.3.0",
|
||||
"next": "^11.0.0",
|
||||
"next-mdx-remote": "^3.0.2",
|
||||
"next-themes": "^0.0.15",
|
||||
"parse-numeric-range": "1.2.0",
|
||||
"prism-react-renderer": "^1.2.1",
|
||||
"querystring": "^0.2.1",
|
||||
"react": "^17.0.2",
|
||||
@ -35,17 +37,24 @@
|
||||
"react-instantsearch-dom": "^6.12.0",
|
||||
"react-live": "^2.2.3",
|
||||
"react-markdown": "^6.0.2",
|
||||
"refractor": "3.3.1",
|
||||
"rehype": "11.0.0",
|
||||
"rehype-parse": "7.0.1",
|
||||
"remark-autolink-headings": "^6.0.1",
|
||||
"remark-slug": "^6.0.0",
|
||||
"shelljs": "^0.8.4",
|
||||
"styled-jsx": "^4.0.1",
|
||||
"unified": "9.2.1",
|
||||
"unist-util-visit": "2.0.3",
|
||||
"util.promisify": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/parse-numeric-range": "^0.0.1",
|
||||
"@types/react": "^17.0.11",
|
||||
"@types/react-autosuggest": "^10.1.5",
|
||||
"@types/react-dom": "^17.0.8",
|
||||
"@types/react-instantsearch-dom": "^6.12.0",
|
||||
"@types/refractor": "^3.0.2",
|
||||
"@types/shelljs": "^0.8.9",
|
||||
"babel-plugin-module-resolver": "^4.1.0",
|
||||
"eslint-config-next": "^11.0.0",
|
||||
|
||||
167
apps/docs/src/components/code-demo/index.tsx
Normal file
167
apps/docs/src/components/code-demo/index.tsx
Normal file
@ -0,0 +1,167 @@
|
||||
// Inspired by https://github.dev/modulz/stitches-site code demo
|
||||
import React from 'react';
|
||||
import refractor from 'refractor/core';
|
||||
import js from 'refractor/lang/javascript';
|
||||
import jsx from 'refractor/lang/jsx';
|
||||
import bash from 'refractor/lang/bash';
|
||||
import css from 'refractor/lang/css';
|
||||
import diff from 'refractor/lang/diff';
|
||||
import hastToHtml from 'hast-util-to-html';
|
||||
import rangeParser from 'parse-numeric-range';
|
||||
import highlightLine from '@lib/rehype-highlight-line';
|
||||
import highlightWord from '@lib/rehype-highlight-word';
|
||||
import { Pre } from './pre';
|
||||
|
||||
refractor.register(js);
|
||||
refractor.register(jsx);
|
||||
refractor.register(bash);
|
||||
refractor.register(css);
|
||||
refractor.register(diff);
|
||||
|
||||
type PreProps = Omit<React.ComponentProps<typeof Pre>, 'css'>;
|
||||
|
||||
type CodeBlockProps = PreProps & {
|
||||
language: 'js' | 'jsx' | 'bash' | 'css' | 'diff';
|
||||
value: string;
|
||||
line?: string;
|
||||
css?: any;
|
||||
mode?: 'static' | 'typewriter';
|
||||
showLineNumbers?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* recursively get all text nodes as an array for a given element
|
||||
*/
|
||||
function getTextNodes(node: any) {
|
||||
let childTextNodes = [];
|
||||
|
||||
if (!node.hasChildNodes()) return;
|
||||
|
||||
const childNodes = node.childNodes;
|
||||
for (let i = 0; i < childNodes.length; i++) {
|
||||
if (childNodes[i].nodeType == Node.TEXT_NODE) {
|
||||
childTextNodes.push(childNodes[i]);
|
||||
} else if (childNodes[i].nodeType == Node.ELEMENT_NODE) {
|
||||
Array.prototype.push.apply(childTextNodes, getTextNodes(childNodes[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return childTextNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* given a text node, wrap each character in the
|
||||
* given tag.
|
||||
*/
|
||||
function wrapEachCharacter(textNode: any, tag: string, count: number) {
|
||||
const text = textNode.nodeValue;
|
||||
const parent = textNode.parentNode;
|
||||
|
||||
const characters = text.split('');
|
||||
characters.forEach(function (character: any, letterIndex: any) {
|
||||
const delay = (count + letterIndex) * 50;
|
||||
var element = document.createElement(tag);
|
||||
var characterNode = document.createTextNode(character);
|
||||
element.appendChild(characterNode);
|
||||
element.style.opacity = '0';
|
||||
element.style.transition = `all ease 0ms ${delay}ms`;
|
||||
|
||||
parent.insertBefore(element, textNode);
|
||||
|
||||
// skip a couple of frames to trigger transition
|
||||
requestAnimationFrame(() =>
|
||||
requestAnimationFrame(() => (element.style.opacity = '1'))
|
||||
);
|
||||
});
|
||||
|
||||
parent.removeChild(textNode);
|
||||
}
|
||||
|
||||
function CodeTypewriter({ value, className, css, ...props }: any) {
|
||||
const wrapperRef = React.useRef(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
const wrapper = wrapperRef.current as any;
|
||||
|
||||
if (wrapper) {
|
||||
var allTextNodes = getTextNodes(wrapper);
|
||||
|
||||
let count = 0;
|
||||
allTextNodes?.forEach((textNode) => {
|
||||
wrapEachCharacter(textNode, 'span', count);
|
||||
count = count + textNode.nodeValue.length;
|
||||
});
|
||||
wrapper.style.opacity = '1';
|
||||
}
|
||||
|
||||
return () => (wrapper.innerHTML = value);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Pre className={className} css={css} {...props}>
|
||||
<code
|
||||
ref={wrapperRef}
|
||||
style={{ opacity: 0 }}
|
||||
className={className}
|
||||
dangerouslySetInnerHTML={{ __html: value }}
|
||||
/>
|
||||
</Pre>
|
||||
);
|
||||
}
|
||||
|
||||
const CodeBlock = React.forwardRef<HTMLPreElement, CodeBlockProps>(
|
||||
(_props, forwardedRef) => {
|
||||
const {
|
||||
language,
|
||||
value,
|
||||
line = '0',
|
||||
className = '',
|
||||
mode,
|
||||
css,
|
||||
showLineNumbers,
|
||||
...props
|
||||
} = _props;
|
||||
let result: any = refractor.highlight(value, language);
|
||||
|
||||
result = highlightLine(result, rangeParser(line));
|
||||
|
||||
result = highlightWord(result);
|
||||
|
||||
// convert to html
|
||||
result = hastToHtml(result);
|
||||
|
||||
// TODO reset theme
|
||||
|
||||
const classes = `language-${language} ${className}`;
|
||||
|
||||
if (mode === 'typewriter') {
|
||||
return (
|
||||
<CodeTypewriter
|
||||
className={classes}
|
||||
css={css}
|
||||
value={result}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Pre
|
||||
ref={forwardedRef}
|
||||
className={classes}
|
||||
css={css}
|
||||
data-line-numbers={showLineNumbers}
|
||||
{...props}
|
||||
>
|
||||
<code
|
||||
className={classes}
|
||||
dangerouslySetInnerHTML={{ __html: result }}
|
||||
/>
|
||||
</Pre>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
CodeBlock.displayName = 'NextUI - CodeBlock';
|
||||
|
||||
export default CodeBlock;
|
||||
200
apps/docs/src/components/code-demo/pre.tsx
Normal file
200
apps/docs/src/components/code-demo/pre.tsx
Normal file
@ -0,0 +1,200 @@
|
||||
import { styled } from '@nextui-org/react';
|
||||
import makeCodeTheme, { getCodeThemeColors } from '../playground/code-theme';
|
||||
|
||||
const codeTheme = makeCodeTheme();
|
||||
const {
|
||||
stringColor,
|
||||
functionColor,
|
||||
punctuationColor,
|
||||
primitiveColor,
|
||||
classnameColor
|
||||
} = getCodeThemeColors();
|
||||
|
||||
export const Pre = styled('pre', {
|
||||
$$background: codeTheme.plain.backgroundColor,
|
||||
$$text: codeTheme.plain.color,
|
||||
$$outline: '$shadows$md',
|
||||
$$syntax1: functionColor?.style.color,
|
||||
$$syntax2: stringColor?.style.color,
|
||||
$$syntax3: primitiveColor?.style.color,
|
||||
$$syntax4: '$colors$yellow600',
|
||||
$$syntax5: classnameColor?.style.color,
|
||||
$$syntax6: '$colors$yellow400',
|
||||
$$comment: punctuationColor?.style.color,
|
||||
$$removed: '$colors$red300',
|
||||
$$added: '$colors$green300',
|
||||
$$lineNumbers: punctuationColor?.style.color,
|
||||
$$fadedLines: punctuationColor?.style.color,
|
||||
$$highlightedWord1Bg: '$colors$purple500',
|
||||
$$highlightedWord1BgActive: '$colors$purple600',
|
||||
$$highlightedWord1Text: '$colors$purple800',
|
||||
$$highlightedWord2Bg: '$colors$red100',
|
||||
$$highlightedWord2BgActive: '$colors$red500',
|
||||
$$highlightedWord2Text: '$colors$red200',
|
||||
$$highlightedWord3Bg: '$colors$green300',
|
||||
$$highlightedWord3BgActive: '$colors$green500',
|
||||
$$highlightedWord3Text: '$colors$green100',
|
||||
|
||||
boxSizing: 'border-box',
|
||||
borderRadius: '$lg',
|
||||
padding: '$8',
|
||||
overflow: 'auto',
|
||||
fontFamily: '$mono',
|
||||
fontSize: '$xs',
|
||||
lineHeight: '21px',
|
||||
whiteSpace: 'pre',
|
||||
position: 'relative',
|
||||
backgroundColor: '$$background',
|
||||
color: '$$text',
|
||||
boxShadow: '$$outline',
|
||||
width: '100%',
|
||||
|
||||
'& > code': {
|
||||
color: 'inherit',
|
||||
fontSize: 'inherit',
|
||||
background: 'inherit',
|
||||
display: 'block',
|
||||
transition: 'none',
|
||||
'&:hover': {
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
|
||||
'.token.parameter': {
|
||||
color: '$$text'
|
||||
},
|
||||
|
||||
'.token.tag, .token.selector, .token.selector .class, .token.function': {
|
||||
color: '$$syntax1'
|
||||
},
|
||||
|
||||
'.token.script.language-javascript': {
|
||||
color: '$$text'
|
||||
},
|
||||
|
||||
'.token.class-name': {
|
||||
color: '$$syntax5'
|
||||
},
|
||||
|
||||
'.token.attr-value, .token.class, .token.string, .token.number, .token.unit, .token.color':
|
||||
{
|
||||
color: '$$syntax2'
|
||||
},
|
||||
|
||||
'.token.keyword, .token.rule, .token.operator, .token.pseudo-class, .token.important':
|
||||
{
|
||||
color: '$$syntax3'
|
||||
},
|
||||
'.token.attr-name': {
|
||||
color: '$$syntax6'
|
||||
},
|
||||
'.token.punctuation, .token.module, .token.property': {
|
||||
color: '$$syntax4'
|
||||
},
|
||||
|
||||
'.token.comment': {
|
||||
color: '$$comment'
|
||||
},
|
||||
|
||||
'.token.atapply .token:not(.rule):not(.important)': {
|
||||
color: 'inherit'
|
||||
},
|
||||
|
||||
'.language-shell .token:not(.comment)': {
|
||||
color: 'inherit'
|
||||
},
|
||||
|
||||
'.language-css .token.function': {
|
||||
color: 'inherit'
|
||||
},
|
||||
|
||||
'.token.deleted:not(.prefix), .token.inserted:not(.prefix)': {
|
||||
display: 'block',
|
||||
px: '$4',
|
||||
mx: '-20px'
|
||||
},
|
||||
|
||||
'.token.deleted:not(.prefix)': {
|
||||
color: '$$removed'
|
||||
},
|
||||
|
||||
'.token.inserted:not(.prefix)': {
|
||||
color: '$$added'
|
||||
},
|
||||
|
||||
'.token.deleted.prefix, .token.inserted.prefix': {
|
||||
userSelect: 'none'
|
||||
},
|
||||
|
||||
// Styles for highlighted word
|
||||
'.highlight-word': {
|
||||
$$bgAndShadow: '$$highlightedWord1Bg',
|
||||
$$xOffset: '1px',
|
||||
color: '$$highlightedWord1Text',
|
||||
backgroundColor: '$$bgAndShadow',
|
||||
display: 'inline-block',
|
||||
boxShadow: '$$xOffset 0 0 0 $$bgAndShadow, -$$xOffset 0 0 0 $$bgAndShadow',
|
||||
|
||||
// reset the color for tokens inside highlighted words
|
||||
'.token': {
|
||||
color: 'inherit'
|
||||
},
|
||||
|
||||
'&.on': {
|
||||
$$bgAndShadow: '$$highlightedWord1BgActive',
|
||||
transition: 'all 100ms ease',
|
||||
cursor: 'pointer'
|
||||
}
|
||||
},
|
||||
|
||||
'.token.deleted .highlight-word': {
|
||||
$$bgAndShadow: '$$highlightedWord2Bg',
|
||||
color: '$$highlightedWord2Text',
|
||||
|
||||
'&.on': {
|
||||
$$bgAndShadow: '$$highlightedWord2BgActive'
|
||||
}
|
||||
},
|
||||
|
||||
'.token.inserted .highlight-word': {
|
||||
$$bgAndShadow: '$$highlightedWord3Bg',
|
||||
color: '$$highlightedWord3Text',
|
||||
|
||||
'&.on': {
|
||||
$$bgAndShadow: '$$highlightedWord3BgActive'
|
||||
}
|
||||
},
|
||||
|
||||
// Line numbers
|
||||
'&[data-line-numbers=true]': {
|
||||
'.highlight-line': {
|
||||
position: 'relative',
|
||||
paddingLeft: '$9',
|
||||
|
||||
'&::before': {
|
||||
content: 'attr(data-line)',
|
||||
position: 'absolute',
|
||||
left: -5,
|
||||
top: 0,
|
||||
color: '$$lineNumbers'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Styles for highlighted lines
|
||||
'.highlight-line': {
|
||||
'&, *': {
|
||||
transition: 'color 150ms ease'
|
||||
},
|
||||
'&[data-highlighted=false]': {
|
||||
'&, *': {
|
||||
color: '$$fadedLines'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Typewriter styles
|
||||
'.typewriter': {
|
||||
opacity: 0
|
||||
}
|
||||
});
|
||||
@ -3,8 +3,7 @@ import {
|
||||
Snippet,
|
||||
StyledSnippetPre,
|
||||
globalCss,
|
||||
StyledSnippetCopyButton,
|
||||
useTheme
|
||||
StyledSnippetCopyButton
|
||||
} from '@nextui-org/react';
|
||||
import makeCodeTheme from '../playground/code-theme';
|
||||
|
||||
@ -18,9 +17,7 @@ const globalStyles = globalCss({
|
||||
const Codeblock: React.FC<React.PropsWithChildren<unknown>> = ({
|
||||
children
|
||||
}) => {
|
||||
const themeObj = useTheme();
|
||||
const { theme, isDark } = themeObj;
|
||||
const codeTheme = makeCodeTheme(themeObj);
|
||||
const codeTheme = makeCodeTheme();
|
||||
const stringColor = codeTheme.styles.find((style) =>
|
||||
style.types.includes('string')
|
||||
);
|
||||
@ -101,9 +98,7 @@ const Codeblock: React.FC<React.PropsWithChildren<unknown>> = ({
|
||||
[`& ${StyledSnippetCopyButton}`]: {
|
||||
bg: codeTheme.plain.backgroundColor,
|
||||
path: {
|
||||
fill: !isDark
|
||||
? theme?.colors?.accents2?.value
|
||||
: theme?.colors?.accents5?.value
|
||||
fill: '$colors$codeCopyIconColor'
|
||||
}
|
||||
}
|
||||
}}
|
||||
@ -16,7 +16,7 @@ export type FeaturesGridProps = Props & GridProps;
|
||||
|
||||
const FeaturesGrid: React.FC<FeaturesGridProps> = ({ features, ...props }) => {
|
||||
return (
|
||||
<Grid.Container gap={2} {...props}>
|
||||
<Grid.Container gap={2} css={{ px: 0 }} {...props}>
|
||||
{features.map((feat, index) => (
|
||||
<Grid key={`${feat.title}_${index}`} xs={12} sm={4} lg={3}>
|
||||
<FeatureItem>
|
||||
|
||||
@ -6,7 +6,7 @@ export const FeatureItem = styled(Grid, {
|
||||
borderRadius: '$lg',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
px: '$8',
|
||||
p: '$8',
|
||||
bf: 'saturate(180%) blur(14px)',
|
||||
bg: 'rgba(255, 255, 255, 0.05)',
|
||||
'& .icon-wrapper': {
|
||||
|
||||
@ -23,7 +23,10 @@ import { useTheme as useNextTheme } from 'next-themes';
|
||||
const StyledContainer = styled('div', {
|
||||
dflex: 'center',
|
||||
position: 'absolute',
|
||||
zIndex: '$2'
|
||||
zIndex: '$2',
|
||||
'@xsMax': {
|
||||
display: 'none'
|
||||
}
|
||||
});
|
||||
|
||||
const HeroComponents = () => {
|
||||
|
||||
@ -34,16 +34,14 @@ const Hero: React.FC = () => {
|
||||
alignItems="center"
|
||||
justify="space-between"
|
||||
wrap="nowrap"
|
||||
gap={0}
|
||||
as="section"
|
||||
css={{
|
||||
position: 'relative',
|
||||
height: '60vh',
|
||||
height: 'calc(84vh - 76px)',
|
||||
'@xsMax': {
|
||||
height: 'calc(100vh - 64px)',
|
||||
overflow: 'hidden'
|
||||
},
|
||||
'@lgMax': {
|
||||
padding: '0 20px'
|
||||
}
|
||||
}}
|
||||
>
|
||||
@ -83,7 +81,7 @@ const Hero: React.FC = () => {
|
||||
</StyledSubtitle>
|
||||
<Spacer y={1.5} />
|
||||
<Grid.Container
|
||||
gap={1}
|
||||
gap={0}
|
||||
alignItems="center"
|
||||
css={{
|
||||
'@md': {
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
export * from './search';
|
||||
export * from './icons';
|
||||
export * from './templates';
|
||||
export * from './primitives';
|
||||
|
||||
export { default as Logo } from './logo';
|
||||
export { default as Hero } from './hero';
|
||||
export { default as ImageBrowser } from './image-browser';
|
||||
@ -24,6 +29,5 @@ export { default as Blockholder } from './blockholder';
|
||||
export { default as LooperBG } from './looper-bg';
|
||||
export { default as FeaturesGrid } from './features-grid';
|
||||
export type { Feature as FeatureType } from './features-grid';
|
||||
export * from './search';
|
||||
export * from './icons';
|
||||
export * from './templates';
|
||||
export { default as Codeblock } from './codeblock';
|
||||
export { default as CodeDemo } from './code-demo';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/* eslint-disable react/display-name */
|
||||
import * as React from 'react';
|
||||
import Playground from '../playground';
|
||||
import Codeblock from './codeblock';
|
||||
import Codeblock from '../codeblock';
|
||||
import CarbonAd from '../carbon-ad';
|
||||
import * as Icons from '../icons';
|
||||
import { useTheme } from '@nextui-org/react';
|
||||
|
||||
@ -1,23 +1,20 @@
|
||||
import { PrismTheme } from 'prism-react-renderer';
|
||||
import { NextUIThemeContext } from '@nextui-org/react';
|
||||
|
||||
const makeCodeTheme = ({ theme, isDark }: NextUIThemeContext): PrismTheme => ({
|
||||
const makeCodeTheme = (): PrismTheme => ({
|
||||
plain: {
|
||||
backgroundColor: isDark ? '#111' : '#363449',
|
||||
color: '#fff',
|
||||
backgroundColor: '$colors$codeBackground',
|
||||
color: '$colors$white',
|
||||
fontWeight: '500',
|
||||
fontStyle: 'normal',
|
||||
fontFamily: theme?.fonts?.mono?.value,
|
||||
fontSize: theme?.fontSizes?.xs?.value,
|
||||
fontFamily: '$mono',
|
||||
fontSize: '$xs',
|
||||
textRendering: 'geometricPrecision'
|
||||
},
|
||||
styles: [
|
||||
{
|
||||
types: ['comment', 'prolog', 'doctype', 'cdata', 'punctuation'],
|
||||
style: {
|
||||
color: isDark
|
||||
? theme?.colors?.accents6?.value
|
||||
: theme?.colors?.accents3?.value,
|
||||
color: '$colors$codeComment',
|
||||
opacity: 0.5
|
||||
}
|
||||
},
|
||||
@ -48,7 +45,7 @@ const makeCodeTheme = ({ theme, isDark }: NextUIThemeContext): PrismTheme => ({
|
||||
{
|
||||
types: ['property', 'function'],
|
||||
style: {
|
||||
color: theme?.colors?.success?.value
|
||||
color: '$success'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -60,7 +57,7 @@ const makeCodeTheme = ({ theme, isDark }: NextUIThemeContext): PrismTheme => ({
|
||||
{
|
||||
types: ['attr-name'],
|
||||
style: {
|
||||
color: theme?.colors?.yellow500?.value
|
||||
color: '$yellow500'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -93,7 +90,7 @@ const makeCodeTheme = ({ theme, isDark }: NextUIThemeContext): PrismTheme => ({
|
||||
{
|
||||
types: ['language-javascript', 'script'],
|
||||
style: {
|
||||
color: theme?.colors?.success?.value
|
||||
color: '$success'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -115,7 +112,7 @@ const makeCodeTheme = ({ theme, isDark }: NextUIThemeContext): PrismTheme => ({
|
||||
}
|
||||
},
|
||||
{
|
||||
types: ['important'],
|
||||
types: ['important', 'primitive'],
|
||||
style: {
|
||||
color: '#c678dd'
|
||||
}
|
||||
@ -123,4 +120,52 @@ const makeCodeTheme = ({ theme, isDark }: NextUIThemeContext): PrismTheme => ({
|
||||
]
|
||||
});
|
||||
|
||||
export const getCodeThemeColors = () => {
|
||||
const codeTheme = makeCodeTheme();
|
||||
const stringColor = codeTheme.styles.find((style) =>
|
||||
style.types.includes('string')
|
||||
);
|
||||
const punctuationColor = codeTheme.styles.find((style) =>
|
||||
style.types.includes('punctuation')
|
||||
);
|
||||
const numberColor = codeTheme.styles.find((style) =>
|
||||
style.types.includes('number')
|
||||
);
|
||||
const textColor = codeTheme.styles.find((style) =>
|
||||
style.types.includes('text')
|
||||
);
|
||||
const selectorColor = codeTheme.styles.find((style) =>
|
||||
style.types.includes('selector')
|
||||
);
|
||||
const commentColor = codeTheme.styles.find((style) =>
|
||||
style.types.includes('comment')
|
||||
);
|
||||
const classnameColor = codeTheme.styles.find((style) =>
|
||||
style.types.includes('tag')
|
||||
);
|
||||
const attrColor = codeTheme.styles.find((style) =>
|
||||
style.types.includes('attr-name')
|
||||
);
|
||||
const functionColor = codeTheme.styles.find((style) =>
|
||||
style.types.includes('function')
|
||||
);
|
||||
|
||||
const primitiveColor = codeTheme.styles.find((style) =>
|
||||
style.types.includes('primitive')
|
||||
);
|
||||
|
||||
return {
|
||||
stringColor,
|
||||
punctuationColor,
|
||||
numberColor,
|
||||
textColor,
|
||||
selectorColor,
|
||||
commentColor,
|
||||
classnameColor,
|
||||
attrColor,
|
||||
functionColor,
|
||||
primitiveColor
|
||||
};
|
||||
};
|
||||
|
||||
export default makeCodeTheme;
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { LivePreview, LiveProvider, LiveError } from 'react-live';
|
||||
import { useTheme } from '@nextui-org/react';
|
||||
import makeCodeTheme from './code-theme';
|
||||
import Editor from './editor';
|
||||
import NextLink from 'next/link';
|
||||
@ -9,6 +8,7 @@ import * as TemplateComponents from '../templates';
|
||||
import { useMediaQuery } from '@hooks/use-media-query';
|
||||
import { validateEmail } from '@utils/index';
|
||||
import withDefaults from '@utils/with-defaults';
|
||||
import { Box } from '@components';
|
||||
import * as Components from '@nextui-org/react';
|
||||
import * as Icons from '../icons';
|
||||
|
||||
@ -23,15 +23,41 @@ const defaultProps = {
|
||||
showEditor: true
|
||||
};
|
||||
|
||||
const StyledWrapper = Components.styled(Box, {
|
||||
width: '100%',
|
||||
padding: '$lg $sm',
|
||||
marginLeft: '-$sm',
|
||||
display: 'flex',
|
||||
flexWrap: 'wrap',
|
||||
flexDirection: 'column',
|
||||
'& > div': {
|
||||
width: '100%'
|
||||
},
|
||||
variants: {
|
||||
overflow: {
|
||||
visible: {
|
||||
overflowX: 'visible'
|
||||
},
|
||||
hidden: {
|
||||
overflowX: 'hidden'
|
||||
},
|
||||
auto: {
|
||||
overflowX: 'auto'
|
||||
}
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
overflow: 'hidden'
|
||||
}
|
||||
});
|
||||
|
||||
const DynamicLive: React.FC<Props> = ({
|
||||
code,
|
||||
showEditor,
|
||||
initialEditorOpen,
|
||||
overflow
|
||||
}) => {
|
||||
const themeObject = useTheme();
|
||||
const { theme } = themeObject;
|
||||
const codeTheme = makeCodeTheme(themeObject);
|
||||
const codeTheme = makeCodeTheme();
|
||||
const scope = {
|
||||
...Components,
|
||||
...Icons,
|
||||
@ -43,26 +69,11 @@ const DynamicLive: React.FC<Props> = ({
|
||||
};
|
||||
return (
|
||||
<LiveProvider code={code} scope={scope} theme={codeTheme}>
|
||||
<div className="wrapper">
|
||||
<StyledWrapper className="wrapper" overflow={overflow}>
|
||||
<LivePreview />
|
||||
<LiveError />
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
{showEditor && <Editor initialOpen={initialEditorOpen} />}
|
||||
<style jsx>{`
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
padding: ${theme?.space?.lg?.value} ${theme?.space?.sm?.value};
|
||||
margin-left: -${theme?.space?.sm?.value};
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
overflow-x: ${overflow};
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.wrapper > :global(div) {
|
||||
width: 100%;
|
||||
}
|
||||
`}</style>
|
||||
</LiveProvider>
|
||||
);
|
||||
};
|
||||
|
||||
55
apps/docs/src/components/primitives/index.ts
Normal file
55
apps/docs/src/components/primitives/index.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { styled } from '@nextui-org/react';
|
||||
|
||||
export const Title = styled('h1', {
|
||||
display: 'inline',
|
||||
fontWeight: '$bold',
|
||||
color: '$text',
|
||||
lh: '1.2',
|
||||
fs: '2.5rem',
|
||||
mb: 0,
|
||||
'@sm': {
|
||||
fs: '3rem'
|
||||
},
|
||||
'@lg': {
|
||||
fs: '3.5rem'
|
||||
},
|
||||
variants: {
|
||||
color: {
|
||||
violet: {
|
||||
textGradient: '180deg, #FF1CF7 25%, #b249f8 100%'
|
||||
},
|
||||
warning: {
|
||||
textGradient: '180deg, #f36534 25%, #F69F27 100%'
|
||||
}
|
||||
},
|
||||
fullWidth: {
|
||||
true: {
|
||||
display: 'block',
|
||||
width: '100%'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const Subtitle = styled('p', {
|
||||
pl: '$1',
|
||||
fs: '$sm',
|
||||
fontWeight: '$medium',
|
||||
color: '$accents6',
|
||||
display: 'block',
|
||||
mw: '100%',
|
||||
width: '100%',
|
||||
'@sm': {
|
||||
mw: '50%'
|
||||
}
|
||||
});
|
||||
|
||||
export const Section = styled('section', {
|
||||
zIndex: '$2',
|
||||
width: '100%'
|
||||
});
|
||||
|
||||
export const Box = styled('div', {
|
||||
// Reset
|
||||
boxSizing: 'border-box'
|
||||
});
|
||||
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import cn from 'classnames';
|
||||
import { Moon, Sun } from '../icons';
|
||||
import { useTheme, styled } from '@nextui-org/react';
|
||||
import { styled } from '@nextui-org/react';
|
||||
import { useTheme as useNextTheme } from 'next-themes';
|
||||
import Blockholder from '../blockholder';
|
||||
import useIsMounted from '@hooks/use-is-mounted';
|
||||
@ -17,6 +17,9 @@ const StyledButton = styled('button', {
|
||||
background: 'transparent',
|
||||
border: 'none',
|
||||
padding: 0,
|
||||
'& .theme-selector-icon': {
|
||||
color: '$colors$headerIconColor'
|
||||
},
|
||||
'@xsMax': {
|
||||
px: '$2'
|
||||
}
|
||||
@ -24,8 +27,8 @@ const StyledButton = styled('button', {
|
||||
|
||||
export const ThemeToggle: React.FC<Props> = ({ className }) => {
|
||||
const isMounted = useIsMounted();
|
||||
const { setTheme } = useNextTheme();
|
||||
const { theme, isDark } = useTheme();
|
||||
const { setTheme, theme } = useNextTheme();
|
||||
const isDark = theme === 'dark';
|
||||
|
||||
if (!isMounted) {
|
||||
return (
|
||||
@ -45,25 +48,9 @@ export const ThemeToggle: React.FC<Props> = ({ className }) => {
|
||||
onClick={handleToggleTheme}
|
||||
>
|
||||
{isDark ? (
|
||||
<Sun
|
||||
filled
|
||||
fill={
|
||||
isDark
|
||||
? theme?.colors?.accents6?.value
|
||||
: theme?.colors?.accents4?.value
|
||||
}
|
||||
size={20}
|
||||
/>
|
||||
<Sun filled className="theme-selector-icon" size={20} />
|
||||
) : (
|
||||
<Moon
|
||||
filled
|
||||
fill={
|
||||
isDark
|
||||
? theme?.colors?.accents6?.value
|
||||
: theme?.colors?.accents4?.value
|
||||
}
|
||||
size={20}
|
||||
/>
|
||||
<Moon filled className="theme-selector-icon" size={20} />
|
||||
)}
|
||||
</StyledButton>
|
||||
);
|
||||
|
||||
@ -3,7 +3,6 @@ import Header from './header';
|
||||
import Footer from './footer';
|
||||
import Navbar from './navbar';
|
||||
import { Container } from '@nextui-org/react';
|
||||
// import { DotsContainer } from '@components';
|
||||
import { Route } from '@lib/docs/page';
|
||||
|
||||
export interface Props {
|
||||
@ -20,6 +19,7 @@ const DefaultLayout: React.FC<React.PropsWithChildren<Props>> = ({
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<Navbar isHome routes={routes} />
|
||||
<Container
|
||||
lg
|
||||
display="flex"
|
||||
@ -30,9 +30,7 @@ const DefaultLayout: React.FC<React.PropsWithChildren<Props>> = ({
|
||||
position: 'relative',
|
||||
minHeight: '100vh'
|
||||
}}
|
||||
gap={0}
|
||||
>
|
||||
<Navbar isHome routes={routes} />
|
||||
{children}
|
||||
<Footer />
|
||||
</Container>
|
||||
|
||||
@ -34,25 +34,9 @@ const DocsLayout: React.FC<React.PropsWithChildren<Props>> = ({
|
||||
meta
|
||||
}) => {
|
||||
const [headings, setHeadings] = useState<Heading[]>([]);
|
||||
const [scrollPosition, setScrollPosition] = useState(
|
||||
(typeof window !== 'undefined' && window.pageYOffset) || 0
|
||||
);
|
||||
const { theme, type } = useTheme();
|
||||
const isDark = type === 'dark';
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('scroll', onScroll.bind(this));
|
||||
return () => {
|
||||
window.removeEventListener('scroll', onScroll.bind(this));
|
||||
};
|
||||
}, []);
|
||||
|
||||
const onScroll = () => {
|
||||
requestAnimationFrame(() => {
|
||||
setScrollPosition(window.pageYOffset);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setHeadings(getHeadings());
|
||||
}, [routes]);
|
||||
@ -60,140 +44,147 @@ const DocsLayout: React.FC<React.PropsWithChildren<Props>> = ({
|
||||
const editUrl = `${GITHUB_URL}/${REPO_NAME}/edit/${TAG}/${CONTENT_PATH}${currentRoute?.path}`;
|
||||
|
||||
return (
|
||||
<Container lg as="main" className="docs__container" display="flex" gap={0}>
|
||||
<Header {...meta} />
|
||||
<Navbar routes={routes} detached={scrollPosition > 0} />
|
||||
<Row className="docs__content" gap={0}>
|
||||
<Sticky offset={10} className="docs__left-sidebar">
|
||||
<Sidebar routes={routes} tag={tag} slug={slug} />
|
||||
</Sticky>
|
||||
<Col className="docs__center">
|
||||
{children}
|
||||
<PageNav tag={tag} prevRoute={prevRoute} nextRoute={nextRoute} />
|
||||
<footer>
|
||||
{tag ? (
|
||||
<NextLink href={slug || ''}>
|
||||
<Link>
|
||||
<small>Go to the live version of this page</small>
|
||||
</Link>
|
||||
</NextLink>
|
||||
) : (
|
||||
<a href={editUrl} target="_blank" rel="noopener noreferrer">
|
||||
<small>Edit this page on GitHub</small>
|
||||
</a>
|
||||
)}
|
||||
</footer>
|
||||
</Col>
|
||||
<Sticky offset={10} className="docs__right-sidebar">
|
||||
<TableOfContent headings={headings} />
|
||||
</Sticky>
|
||||
{isDark && (
|
||||
<img
|
||||
className="docs__gradient-blue"
|
||||
src="/gradient-left-dark.svg"
|
||||
alt="gradient blue background"
|
||||
/>
|
||||
)}
|
||||
{isDark && (
|
||||
<img
|
||||
className="docs__gradient-violet"
|
||||
src="/gradient-right-dark.svg"
|
||||
alt="gradient violet background"
|
||||
/>
|
||||
)}
|
||||
</Row>
|
||||
<Footer />
|
||||
<style jsx>
|
||||
{`
|
||||
:global(.docs__container) {
|
||||
position: relative;
|
||||
}
|
||||
:global(.docs__left-sidebar) {
|
||||
width: 20%;
|
||||
max-height: calc(100vh - 4rem);
|
||||
overflow: auto;
|
||||
display: none;
|
||||
}
|
||||
:global(.docs__center) {
|
||||
z-index: 99;
|
||||
padding: 0 1.4rem !important;
|
||||
}
|
||||
:global(.docs__left-sidebar::-webkit-scrollbar) {
|
||||
width: 0px;
|
||||
}
|
||||
:global(.docs__content) {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
:global(.docs__right-sidebar, .docs__left-sidebar) {
|
||||
display: none;
|
||||
width: 24%;
|
||||
}
|
||||
:global(.docs__gradient-blue, .docs__gradient-violet) {
|
||||
top: 0;
|
||||
opacity: 0;
|
||||
position: fixed;
|
||||
animation: appear 200ms 100ms ease forwards;
|
||||
}
|
||||
:global(.docs__gradient-blue) {
|
||||
top: 10%;
|
||||
left: -10%;
|
||||
z-index: 1;
|
||||
}
|
||||
:global(.docs__gradient-violet) {
|
||||
display: block;
|
||||
z-index: 1;
|
||||
top: -50%;
|
||||
right: -50%;
|
||||
}
|
||||
@media only screen and (max-width: ${theme?.breakpoints?.xs.value}) {
|
||||
:global(.docs__content) {
|
||||
margin-top: 64px;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
padding: 0;
|
||||
<>
|
||||
<Navbar routes={routes} />
|
||||
<Container lg as="main" className="docs__container" display="flex">
|
||||
<Header {...meta} />
|
||||
<Row className="docs__content" gap={0}>
|
||||
<Sticky offset={84} className="docs__left-sidebar">
|
||||
<Sidebar routes={routes} tag={tag} slug={slug} />
|
||||
</Sticky>
|
||||
<Col className="docs__center">
|
||||
{children}
|
||||
<PageNav tag={tag} prevRoute={prevRoute} nextRoute={nextRoute} />
|
||||
<footer>
|
||||
{tag ? (
|
||||
<NextLink href={slug || ''}>
|
||||
<Link>
|
||||
<small>Go to the live version of this page</small>
|
||||
</Link>
|
||||
</NextLink>
|
||||
) : (
|
||||
<a href={editUrl} target="_blank" rel="noopener noreferrer">
|
||||
<small>Edit this page on GitHub</small>
|
||||
</a>
|
||||
)}
|
||||
</footer>
|
||||
</Col>
|
||||
<Sticky offset={84} className="docs__right-sidebar">
|
||||
<TableOfContent headings={headings} />
|
||||
</Sticky>
|
||||
{isDark && (
|
||||
<img
|
||||
className="docs__gradient-blue"
|
||||
src="/gradient-left-dark.svg"
|
||||
alt="gradient blue background"
|
||||
/>
|
||||
)}
|
||||
{isDark && (
|
||||
<img
|
||||
className="docs__gradient-violet"
|
||||
src="/gradient-right-dark.svg"
|
||||
alt="gradient violet background"
|
||||
/>
|
||||
)}
|
||||
</Row>
|
||||
<Footer />
|
||||
<style jsx>
|
||||
{`
|
||||
:global(.docs__container) {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: ${theme?.breakpoints?.md.value}) {
|
||||
:global(.docs__left-sidebar) {
|
||||
display: block;
|
||||
width: 20%;
|
||||
max-height: calc(100vh - 4rem);
|
||||
overflow: auto;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: ${theme?.breakpoints?.md.value}) {
|
||||
:global(.docs__center) {
|
||||
padding: 0 1rem !important;
|
||||
z-index: 99;
|
||||
padding: 0 1.4rem !important;
|
||||
}
|
||||
:global(.docs__left-sidebar::-webkit-scrollbar) {
|
||||
width: 0px;
|
||||
}
|
||||
:global(.docs__content) {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
:global(.docs__right-sidebar, .docs__left-sidebar) {
|
||||
display: none;
|
||||
width: 24%;
|
||||
}
|
||||
:global(.docs__gradient-blue, .docs__gradient-violet) {
|
||||
top: 0;
|
||||
opacity: 0;
|
||||
position: fixed;
|
||||
animation: appear 200ms 100ms ease forwards;
|
||||
}
|
||||
:global(.docs__gradient-blue) {
|
||||
top: 10%;
|
||||
left: -10%;
|
||||
z-index: 1;
|
||||
}
|
||||
:global(.docs__gradient-violet) {
|
||||
top: -35%;
|
||||
right: -45%;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: ${theme?.breakpoints?.lg.value}) {
|
||||
:global(.docs__content) {
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: ${theme?.breakpoints?.lg.value}) {
|
||||
:global(.docs__right-sidebar) {
|
||||
display: block;
|
||||
}
|
||||
:global(.docs__right-sidebar, .docs__gradient-violet) {
|
||||
z-index: 1;
|
||||
top: -50%;
|
||||
right: -50%;
|
||||
}
|
||||
}
|
||||
@keyframes appear {
|
||||
from {
|
||||
opacity: 0;
|
||||
@media only screen and (max-width: ${theme?.breakpoints?.xs
|
||||
.value}) {
|
||||
:global(.docs__content) {
|
||||
margin-top: 64px;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
@media only screen and (min-width: ${theme?.breakpoints?.md
|
||||
.value}) {
|
||||
:global(.docs__left-sidebar) {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
</Container>
|
||||
@media only screen and (max-width: ${theme?.breakpoints?.md
|
||||
.value}) {
|
||||
:global(.docs__center) {
|
||||
padding: 0 1rem !important;
|
||||
}
|
||||
:global(.docs__gradient-violet) {
|
||||
top: -35%;
|
||||
right: -45%;
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: ${theme?.breakpoints?.lg
|
||||
.value}) {
|
||||
:global(.docs__content) {
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: ${theme?.breakpoints?.lg
|
||||
.value}) {
|
||||
:global(.docs__right-sidebar) {
|
||||
display: block;
|
||||
}
|
||||
:global(.docs__right-sidebar, .docs__gradient-violet) {
|
||||
top: -50%;
|
||||
right: -50%;
|
||||
}
|
||||
}
|
||||
@keyframes appear {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -20,15 +20,16 @@ import {
|
||||
useBodyScroll
|
||||
} from '@nextui-org/react';
|
||||
import { Route } from '@lib/docs/page';
|
||||
import { Container } from '@nextui-org/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useMediaQuery } from '@hooks/use-media-query';
|
||||
import { addColorAlpha } from '@utils/index';
|
||||
import { isActive } from '@utils/links';
|
||||
import { StyledNavContainer } from './styles';
|
||||
|
||||
export interface Props {
|
||||
isHome?: boolean;
|
||||
detached?: boolean;
|
||||
routes?: Route[];
|
||||
isHome?: boolean;
|
||||
}
|
||||
|
||||
const MobileNavigation = dynamic(
|
||||
@ -45,12 +46,30 @@ const SearchInput = dynamic(
|
||||
}
|
||||
);
|
||||
|
||||
const Navbar: React.FC<Props> = ({ detached, routes }) => {
|
||||
const Navbar: React.FC<Props> = ({ isHome, routes }) => {
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const router = useRouter();
|
||||
const { theme, isDark } = useTheme();
|
||||
const isMobile = useMediaQuery(960);
|
||||
const [, setBodyHidden] = useBodyScroll(null, { scrollLayer: true });
|
||||
const [scrollPosition, setScrollPosition] = useState(
|
||||
(typeof window !== 'undefined' && window.pageYOffset) || 0
|
||||
);
|
||||
|
||||
const detached = scrollPosition > 0;
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('scroll', onScroll.bind(this));
|
||||
return () => {
|
||||
window.removeEventListener('scroll', onScroll.bind(this));
|
||||
};
|
||||
}, []);
|
||||
|
||||
const onScroll = () => {
|
||||
requestAnimationFrame(() => {
|
||||
setScrollPosition(window.pageYOffset);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!isMobile) {
|
||||
@ -64,12 +83,13 @@ const Navbar: React.FC<Props> = ({ detached, routes }) => {
|
||||
isMobile && setBodyHidden(!expanded);
|
||||
};
|
||||
|
||||
const showBlur = !!expanded || !!detached;
|
||||
const showBlur = !!expanded || !!detached || isHome;
|
||||
|
||||
return (
|
||||
<nav className="navbar__container">
|
||||
<div className="navbar__wrapper">
|
||||
<StyledNavContainer detached={detached} showBlur={showBlur}>
|
||||
<Container lg as="nav" display="flex" wrap="nowrap" alignItems="center">
|
||||
<Col
|
||||
className="navbar__logo-container"
|
||||
className="navbar__logo-conta8iner"
|
||||
css={{
|
||||
'@mdMax': {
|
||||
width: '100%'
|
||||
@ -155,14 +175,7 @@ const Navbar: React.FC<Props> = ({ detached, routes }) => {
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Twitter
|
||||
size={24}
|
||||
fill={
|
||||
isDark
|
||||
? theme?.colors?.accents6?.value
|
||||
: theme?.colors?.accents4?.value
|
||||
}
|
||||
/>
|
||||
<Twitter size={24} />
|
||||
</Link>
|
||||
<Link
|
||||
className="navbar__social-icon"
|
||||
@ -170,14 +183,7 @@ const Navbar: React.FC<Props> = ({ detached, routes }) => {
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Discord
|
||||
size={24}
|
||||
fill={
|
||||
isDark
|
||||
? theme?.colors?.accents6?.value
|
||||
: theme?.colors?.accents4?.value
|
||||
}
|
||||
/>
|
||||
<Discord size={24} />
|
||||
</Link>
|
||||
<Link
|
||||
className="navbar__social-icon"
|
||||
@ -185,14 +191,7 @@ const Navbar: React.FC<Props> = ({ detached, routes }) => {
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Github
|
||||
size={24}
|
||||
fill={
|
||||
isDark
|
||||
? theme?.colors?.accents6?.value
|
||||
: theme?.colors?.accents4?.value
|
||||
}
|
||||
/>
|
||||
<Github size={24} />
|
||||
</Link>
|
||||
<ThemeToggle className="navbar__social-icon" />
|
||||
</Row>
|
||||
@ -216,19 +215,8 @@ const Navbar: React.FC<Props> = ({ detached, routes }) => {
|
||||
setBodyHidden(false);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Container>
|
||||
<style jsx>{`
|
||||
.navbar__container,
|
||||
.navbar__wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.navbar__container {
|
||||
height: 76px;
|
||||
z-index: 9999;
|
||||
}
|
||||
:global(.navbar__search-row) {
|
||||
position: initial !important;
|
||||
}
|
||||
@ -274,38 +262,12 @@ const Navbar: React.FC<Props> = ({ detached, routes }) => {
|
||||
}
|
||||
@media only screen and (max-width: ${theme?.breakpoints.xs.value}) {
|
||||
:global(.navbar__container) {
|
||||
top: 0;
|
||||
position: fixed;
|
||||
background: ${showBlur
|
||||
? addColorAlpha(theme?.colors.background.value, 0.6)
|
||||
: 'transparent'};
|
||||
box-shadow: ${detached
|
||||
? '0px 5px 20px -5px rgba(2, 1, 1, 0.1)'
|
||||
: 'none'};
|
||||
min-height: 64px;
|
||||
max-height: 64px;
|
||||
}
|
||||
:global(.navbar__search-row) {
|
||||
justify-content: center;
|
||||
}
|
||||
@supports (
|
||||
(-webkit-backdrop-filter: blur(10px)) or
|
||||
(backdrop-filter: blur(10px))
|
||||
) {
|
||||
:global(.navbar__container) {
|
||||
backdrop-filter: ${showBlur
|
||||
? 'saturate(180%) blur(10px)'
|
||||
: 'none'};
|
||||
}
|
||||
}
|
||||
@supports (
|
||||
not (-webkit-backdrop-filter: blur(10px)) and not
|
||||
(backdrop-filter: blur(10px))
|
||||
) {
|
||||
:global(.navbar__container) {
|
||||
background: ${theme?.colors.background.value};
|
||||
}
|
||||
}
|
||||
:global(.navbar__logo-container a:active) {
|
||||
opacity: 0.7;
|
||||
}
|
||||
@ -328,7 +290,7 @@ const Navbar: React.FC<Props> = ({ detached, routes }) => {
|
||||
}
|
||||
}
|
||||
`}</style>
|
||||
</nav>
|
||||
</StyledNavContainer>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
27
apps/docs/src/layouts/styles.ts
Normal file
27
apps/docs/src/layouts/styles.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { styled } from '@nextui-org/react';
|
||||
|
||||
export const StyledNavContainer = styled('nav', {
|
||||
top: 0,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
height: '76px',
|
||||
position: 'sticky',
|
||||
background: 'transparent',
|
||||
zIndex: '$max',
|
||||
'& .navbar__social-icon': {
|
||||
fill: '$colors$headerIconColor'
|
||||
},
|
||||
variants: {
|
||||
showBlur: {
|
||||
true: {
|
||||
background: '$headerBackground',
|
||||
backdropFilter: 'saturate(180%) blur(10px)'
|
||||
}
|
||||
},
|
||||
detached: {
|
||||
true: {
|
||||
boxShadow: '0px 5px 20px -5px rgba(2, 1, 1, 0.1)'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
119
apps/docs/src/lib/rehype-highlight-line.js
Normal file
119
apps/docs/src/lib/rehype-highlight-line.js
Normal file
@ -0,0 +1,119 @@
|
||||
// Inspired by https://github.dev/modulz/stitches-site
|
||||
|
||||
const hastToHtml = require('hast-util-to-html');
|
||||
const unified = require('unified');
|
||||
const parse = require('rehype-parse');
|
||||
|
||||
const lineNumberify = function lineNumberify(ast, lineNum = 1) {
|
||||
let lineNumber = lineNum;
|
||||
return ast.reduce(
|
||||
(result, node) => {
|
||||
if (node.type === 'text') {
|
||||
if (node.value.indexOf('\n') === -1) {
|
||||
node.lineNumber = lineNumber;
|
||||
result.nodes.push(node);
|
||||
return result;
|
||||
}
|
||||
|
||||
const lines = node.value.split('\n');
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
// eslint-disable-next-line no-plusplus
|
||||
if (i !== 0) ++lineNumber;
|
||||
if (i === lines.length - 1 && lines[i].length === 0) continue;
|
||||
result.nodes.push({
|
||||
type: 'text',
|
||||
value: i === lines.length - 1 ? lines[i] : `${lines[i]}\n`,
|
||||
lineNumber: lineNumber
|
||||
});
|
||||
}
|
||||
|
||||
result.lineNumber = lineNumber;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (node.children) {
|
||||
node.lineNumber = lineNumber;
|
||||
const processed = lineNumberify(node.children, lineNumber);
|
||||
node.children = processed.nodes;
|
||||
result.lineNumber = processed.lineNumber;
|
||||
result.nodes.push(node);
|
||||
return result;
|
||||
}
|
||||
|
||||
result.nodes.push(node);
|
||||
return result;
|
||||
},
|
||||
{ nodes: [], lineNumber: lineNumber }
|
||||
);
|
||||
};
|
||||
|
||||
const wrapLines = function wrapLines(ast, linesToHighlight) {
|
||||
const highlightAll =
|
||||
linesToHighlight.length === 1 && linesToHighlight[0] === 0;
|
||||
const allLines = Array.from(new Set(ast.map((x) => x.lineNumber)));
|
||||
let i = 0;
|
||||
const wrapped = allLines.reduce((nodes, marker) => {
|
||||
const line = marker;
|
||||
const children = [];
|
||||
for (; i < ast.length; i++) {
|
||||
if (ast[i].lineNumber < line) {
|
||||
nodes.push(ast[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ast[i].lineNumber === line) {
|
||||
children.push(ast[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ast[i].lineNumber > line) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nodes.push({
|
||||
type: 'element',
|
||||
tagName: 'div',
|
||||
properties: {
|
||||
dataLine: line,
|
||||
className: 'highlight-line',
|
||||
dataHighlighted:
|
||||
linesToHighlight.includes(line) || highlightAll ? 'true' : 'false'
|
||||
},
|
||||
children: children,
|
||||
lineNumber: line
|
||||
});
|
||||
|
||||
return nodes;
|
||||
}, []);
|
||||
|
||||
return wrapped;
|
||||
};
|
||||
|
||||
// https://github.com/gatsbyjs/gatsby/pull/26161/files
|
||||
const MULTILINE_TOKEN_SPAN =
|
||||
/<span class="token ([^"]+)">[^<]*\n[^<]*<\/span>/g;
|
||||
|
||||
const applyMultilineFix = function (ast) {
|
||||
// AST to HTML
|
||||
let html = hastToHtml(ast);
|
||||
|
||||
// Fix JSX issue
|
||||
html = html.replace(MULTILINE_TOKEN_SPAN, (match, token) =>
|
||||
match.replace(/\n/g, `</span>\n<span class="token ${token}">`)
|
||||
);
|
||||
|
||||
// HTML to AST
|
||||
const hast = unified()
|
||||
.use(parse, { emitParseErrors: true, fragment: true })
|
||||
.parse(html);
|
||||
|
||||
return hast.children;
|
||||
};
|
||||
|
||||
module.exports = function (ast, lines) {
|
||||
const formattedAst = applyMultilineFix(ast);
|
||||
const numbered = lineNumberify(formattedAst).nodes;
|
||||
|
||||
return wrapLines(numbered, lines);
|
||||
};
|
||||
17
apps/docs/src/lib/rehype-highlight-word.js
Normal file
17
apps/docs/src/lib/rehype-highlight-word.js
Normal file
@ -0,0 +1,17 @@
|
||||
const hastToHtml = require('hast-util-to-html');
|
||||
const unified = require('unified');
|
||||
const parse = require('rehype-parse');
|
||||
|
||||
const CALLOUT = /__(.*?)__/g;
|
||||
|
||||
module.exports = (code) => {
|
||||
const html = hastToHtml(code);
|
||||
const result = html.replace(
|
||||
CALLOUT,
|
||||
(_, text) => `<span class="highlight-word">${text}</span>`
|
||||
);
|
||||
const hast = unified()
|
||||
.use(parse, { emitParseErrors: true, fragment: true })
|
||||
.parse(result);
|
||||
return hast.children;
|
||||
};
|
||||
@ -58,7 +58,6 @@ const DocsPage: React.FC<Props> = ({ routes, currentRoute, source, meta }) => {
|
||||
}, [routes]);
|
||||
|
||||
useRegisterActions([homeAction].filter(Boolean));
|
||||
|
||||
return (
|
||||
<DocsLayout
|
||||
routes={routes}
|
||||
|
||||
@ -3,58 +3,26 @@ import { GetStaticProps } from 'next';
|
||||
import router, { useRouter } from 'next/router';
|
||||
import {
|
||||
FeaturesGrid,
|
||||
FeatureType,
|
||||
Hero,
|
||||
Moon,
|
||||
Magic,
|
||||
Flash,
|
||||
Devices
|
||||
Section,
|
||||
Title,
|
||||
Subtitle,
|
||||
CodeDemo,
|
||||
Logo
|
||||
} from '@components';
|
||||
import landingContent from '@content/landing';
|
||||
import DefaultLayout from '@layouts/default';
|
||||
import { getSlug } from '@lib/docs/utils';
|
||||
import { Route, getCurrentTag, fetchDocsManifest } from '@lib/docs/page';
|
||||
import { Action, useRegisterActions } from 'kbar';
|
||||
import { getId } from '@utils/collections';
|
||||
import { styled } from '@nextui-org/react';
|
||||
import { Spacer, Row, Grid, Text, Col } from '@nextui-org/react';
|
||||
|
||||
interface Props {
|
||||
routes: Route[];
|
||||
currentRoute: Route;
|
||||
}
|
||||
|
||||
const Section = styled('section', {
|
||||
zIndex: '$2',
|
||||
px: '$10',
|
||||
width: '100%'
|
||||
});
|
||||
|
||||
const topFeatures: FeatureType[] = [
|
||||
{
|
||||
title: 'Themeable',
|
||||
description:
|
||||
'Provides a simple way to customize default themes, you can change the colors, fonts, breakpoints and everything you need.',
|
||||
icon: <Magic fill="#FF4ECD" />
|
||||
},
|
||||
{
|
||||
title: 'Fast',
|
||||
description:
|
||||
'Avoids unnecessary styles props at runtime, making it more performant than other UI libraries.',
|
||||
icon: <Flash fill="#FF4ECD" />
|
||||
},
|
||||
{
|
||||
title: 'Light & Dark UI',
|
||||
description:
|
||||
'Automatic dark mode recognition, NextUI automatically changes the theme when detects HTML theme prop changes.',
|
||||
icon: <Moon fill="#FF4ECD" />
|
||||
},
|
||||
{
|
||||
title: 'Unique DX',
|
||||
description:
|
||||
'NextUI is fully-typed to minimize the learning curve, and provide the best possible developer experience.',
|
||||
icon: <Devices fill="#FF4ECD" />
|
||||
}
|
||||
];
|
||||
|
||||
const IndexPage: React.FC<Props> = ({ routes, currentRoute }) => {
|
||||
const { query } = useRouter();
|
||||
const { tag, slug } = getSlug(query);
|
||||
@ -82,7 +50,51 @@ const IndexPage: React.FC<Props> = ({ routes, currentRoute }) => {
|
||||
>
|
||||
<Hero />
|
||||
<Section>
|
||||
<FeaturesGrid features={topFeatures} />
|
||||
<FeaturesGrid features={landingContent.topFeatures} />
|
||||
</Section>
|
||||
<Spacer y={4} />
|
||||
<Section>
|
||||
<Row justify="flex-start">
|
||||
<Title>Do</Title>
|
||||
<Spacer x={0.5} />
|
||||
<Title color="violet">more.</Title>
|
||||
</Row>
|
||||
<Row justify="flex-start">
|
||||
<Title>Write</Title>
|
||||
<Spacer x={0.5} />
|
||||
<Title color="warning">less code.</Title>
|
||||
</Row>
|
||||
<Subtitle>
|
||||
NextUI Components has been built taking into account Developer’s
|
||||
Experience in mind avoding having to import multiples components for
|
||||
showing only one.
|
||||
</Subtitle>
|
||||
<Grid.Container gap={1.5}>
|
||||
<Grid xs={12} sm={6} css={{ pl: 0 }}>
|
||||
<Col css={{ dflex: 'center', fd: 'column' }}>
|
||||
<CodeDemo
|
||||
language="jsx"
|
||||
value={landingContent.comparativeCode.nextui}
|
||||
css={{
|
||||
minHeight: 300
|
||||
}}
|
||||
/>
|
||||
<Text css={{ color: '$text', fontSize: '$md' }}>NextUI</Text>
|
||||
</Col>
|
||||
</Grid>
|
||||
<Grid xs={12} sm={6} css={{ pr: 0 }}>
|
||||
<Col css={{ dflex: 'center', fd: 'column' }}>
|
||||
<CodeDemo
|
||||
language="jsx"
|
||||
css={{
|
||||
height: 300
|
||||
}}
|
||||
value={landingContent.comparativeCode.others}
|
||||
/>
|
||||
<Text css={{ color: '$accents5', fontSize: '$md' }}>Others</Text>
|
||||
</Col>
|
||||
</Grid>
|
||||
</Grid.Container>
|
||||
</Section>
|
||||
</DefaultLayout>
|
||||
);
|
||||
|
||||
56
apps/docs/src/pages/test.jsx
Normal file
56
apps/docs/src/pages/test.jsx
Normal file
@ -0,0 +1,56 @@
|
||||
import * as React from 'react';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import OutlinedInput from '@mui/material/OutlinedInput';
|
||||
import InputLabel from '@mui/material/InputLabel';
|
||||
import InputAdornment from '@mui/material/InputAdornment';
|
||||
import FormControl from '@mui/material/FormControl';
|
||||
import Visibility from '@mui/icons-material/Visibility';
|
||||
import VisibilityOff from '@mui/icons-material/VisibilityOff';
|
||||
|
||||
const App = () => {
|
||||
const [values, setValues] = React.useState({
|
||||
password: '',
|
||||
showPassword: false
|
||||
});
|
||||
|
||||
const handleChange = (event) => {
|
||||
setValues({ ...values, password: event.target.value });
|
||||
};
|
||||
|
||||
const handleClickShowPassword = () => {
|
||||
setValues({
|
||||
...values,
|
||||
showPassword: !values.showPassword
|
||||
});
|
||||
};
|
||||
const handleMouseDownPassword = (event) => {
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
return (
|
||||
<FormControl sx={{ m: 1, width: '25ch' }} variant="outlined">
|
||||
<InputLabel htmlFor="outlined-adornment-password">Password</InputLabel>
|
||||
<OutlinedInput
|
||||
id="outlined-adornment-password"
|
||||
type={values.showPassword ? 'text' : 'password'}
|
||||
value={values.password}
|
||||
onChange={handleChange}
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
aria-label="toggle password visibility"
|
||||
onClick={handleClickShowPassword}
|
||||
onMouseDown={handleMouseDownPassword}
|
||||
edge="end"
|
||||
>
|
||||
{values.showPassword ? <VisibilityOff /> : <Visibility />}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
}
|
||||
label="Password"
|
||||
/>
|
||||
</FormControl>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
@ -13,10 +13,28 @@ const sharedTheme: Theme = {
|
||||
|
||||
export const lightTheme = createTheme({
|
||||
...sharedTheme,
|
||||
type: 'light'
|
||||
type: 'light',
|
||||
theme: {
|
||||
colors: {
|
||||
headerBackground: 'hsla(0,0%,100%,0.8)',
|
||||
headerIconColor: '$accents4',
|
||||
codeBackground: '#363449',
|
||||
codeComment: '$accents3',
|
||||
codeCopyIconColor: '$accents2'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export const darkTheme = createTheme({
|
||||
...sharedTheme,
|
||||
type: 'dark'
|
||||
type: 'dark',
|
||||
theme: {
|
||||
colors: {
|
||||
headerBackground: 'rgba(0,0,0,0.5)',
|
||||
headerIconColor: '$accents6',
|
||||
codeBackground: '#111111',
|
||||
codeComment: '$accents6',
|
||||
codeCopyIconColor: '$accents5'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
// Code based on the code from mantine SsrProvider https://github.dev/mantinedev/mantine
|
||||
|
||||
import React, { createContext, useContext, useState } from 'react';
|
||||
|
||||
function randomId() {
|
||||
return `mantine-${Math.random().toString(36).substr(2, 9)}`;
|
||||
}
|
||||
|
||||
const UuidContext = createContext<() => string>(() => randomId());
|
||||
|
||||
export const useUuid = (staticId?: string) => {
|
||||
const generateId = useContext(UuidContext);
|
||||
const [uid, setUid] = useState('');
|
||||
const _useEffect =
|
||||
typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
|
||||
|
||||
_useEffect(() => {
|
||||
setUid(generateId());
|
||||
}, []);
|
||||
|
||||
return staticId || uid;
|
||||
};
|
||||
|
||||
interface SsrProviderProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function SsrProvider({ children }: SsrProviderProps) {
|
||||
let id = 0;
|
||||
|
||||
const generateId = () => {
|
||||
id += 1;
|
||||
return `nextui-${id}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<UuidContext.Provider value={generateId}>{children}</UuidContext.Provider>
|
||||
);
|
||||
}
|
||||
@ -5,7 +5,6 @@ import withDefaults from '../utils/with-defaults';
|
||||
import { CreateTheme, NextUIThemeContext, ThemeType } from './types';
|
||||
import deepMerge from '../utils/deep-merge';
|
||||
import { copyObject } from '../utils/object';
|
||||
import { SsrProvider } from './ssr-provider';
|
||||
import {
|
||||
changeTheme,
|
||||
getThemeName,
|
||||
@ -97,12 +96,10 @@ const ThemeProvider: React.FC<PropsWithChildren<ThemeProviderProps>> = ({
|
||||
}, [isBrowser, userTheme]);
|
||||
|
||||
return (
|
||||
<SsrProvider>
|
||||
<ThemeContext.Provider value={providerValue}>
|
||||
{!disableBaseline && <CssBaseline />}
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
</SsrProvider>
|
||||
<ThemeContext.Provider value={providerValue}>
|
||||
{!disableBaseline && <CssBaseline />}
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
161
yarn.lock
161
yarn.lock
@ -4025,6 +4025,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
|
||||
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
|
||||
|
||||
"@types/parse-numeric-range@^0.0.1":
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/parse-numeric-range/-/parse-numeric-range-0.0.1.tgz#1a807487565a753f486cb3ee4b2145937d49759d"
|
||||
integrity sha512-nI3rPGKk8BxedokP2VilnW5JyZHYNjGCUDsAZ2JQgISgDflHNUO0wXMfGYP8CkihrKYDm5tilD52XfGhO/ZFCA==
|
||||
|
||||
"@types/parse5@^5.0.0":
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109"
|
||||
@ -4040,6 +4045,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.1.tgz#72a26101dc567b0d68fd956cf42314556e42d601"
|
||||
integrity sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ==
|
||||
|
||||
"@types/prismjs@*":
|
||||
version "1.16.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.16.6.tgz#377054f72f671b36dbe78c517ce2b279d83ecc40"
|
||||
integrity sha512-dTvnamRITNqNkqhlBd235kZl3KfVJQQoT5jkXeiWSBK7i4/TLKBNLV0S1wOt8gy4E2TY722KLtdmv2xc6+Wevg==
|
||||
|
||||
"@types/prop-types@*":
|
||||
version "15.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
|
||||
@ -4104,6 +4114,13 @@
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/refractor@^3.0.2":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/refractor/-/refractor-3.0.2.tgz#2d42128d59f78f84d2c799ffc5ab5cadbcba2d82"
|
||||
integrity sha512-2HMXuwGuOqzUG+KUTm9GDJCHl0LCBKsB5cg28ujEmVi/0qgTb6jOmkVSO5K48qXksyl2Fr3C0Q2VrgD4zbwyXg==
|
||||
dependencies:
|
||||
"@types/prismjs" "*"
|
||||
|
||||
"@types/scheduler@*":
|
||||
version "0.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
|
||||
@ -6084,6 +6101,11 @@ char-regex@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf"
|
||||
integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==
|
||||
|
||||
character-entities-html4@^1.0.0:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.4.tgz#0e64b0a3753ddbf1fdc044c5fd01d0199a02e125"
|
||||
integrity sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==
|
||||
|
||||
character-entities-legacy@^1.0.0:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1"
|
||||
@ -6292,6 +6314,15 @@ cli-width@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
|
||||
integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
|
||||
|
||||
clipboard@^2.0.0:
|
||||
version "2.0.8"
|
||||
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.8.tgz#ffc6c103dd2967a83005f3f61976aa4655a4cdba"
|
||||
integrity sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==
|
||||
dependencies:
|
||||
good-listener "^1.2.2"
|
||||
select "^1.1.2"
|
||||
tiny-emitter "^2.0.0"
|
||||
|
||||
cliui@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5"
|
||||
@ -7131,6 +7162,11 @@ delayed-stream@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
|
||||
|
||||
delegate@^3.1.2:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
|
||||
integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==
|
||||
|
||||
delegates@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
|
||||
@ -9227,6 +9263,13 @@ globrex@^0.1.2:
|
||||
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
|
||||
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
|
||||
|
||||
good-listener@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
|
||||
integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=
|
||||
dependencies:
|
||||
delegate "^3.1.2"
|
||||
|
||||
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.3, graceful-fs@^4.2.4, graceful-fs@^4.2.6:
|
||||
version "4.2.8"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
|
||||
@ -9438,6 +9481,11 @@ hast-util-from-parse5@^6.0.0:
|
||||
vfile-location "^3.2.0"
|
||||
web-namespaces "^1.0.0"
|
||||
|
||||
hast-util-is-element@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz#3b3ed5159a2707c6137b48637fbfe068e175a425"
|
||||
integrity sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==
|
||||
|
||||
hast-util-parse-selector@^2.0.0:
|
||||
version "2.2.5"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a"
|
||||
@ -9459,6 +9507,38 @@ hast-util-raw@6.0.1:
|
||||
xtend "^4.0.0"
|
||||
zwitch "^1.0.0"
|
||||
|
||||
hast-util-to-html@7.1.2:
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-7.1.2.tgz#db677f0ee483658cea0eecc9dec30aba42b67111"
|
||||
integrity sha512-pu73bvORzdF6XZgwl9eID/0RjBb/jtRfoGRRSykpR1+o9rCdiAHpgkSukZsQBRlIqMg6ylAcd7F0F7myJUb09Q==
|
||||
dependencies:
|
||||
ccount "^1.0.0"
|
||||
comma-separated-tokens "^1.0.0"
|
||||
hast-util-is-element "^1.0.0"
|
||||
hast-util-whitespace "^1.0.0"
|
||||
html-void-elements "^1.0.0"
|
||||
property-information "^5.0.0"
|
||||
space-separated-tokens "^1.0.0"
|
||||
stringify-entities "^3.0.1"
|
||||
unist-util-is "^4.0.0"
|
||||
xtend "^4.0.0"
|
||||
|
||||
hast-util-to-html@^7.1.1:
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-7.1.3.tgz#9f339ca9bea71246e565fc79ff7dbfe98bb50f5e"
|
||||
integrity sha512-yk2+1p3EJTEE9ZEUkgHsUSVhIpCsL/bvT8E5GzmWc+N1Po5gBw+0F8bo7dpxXR0nu0bQVxVZGX2lBGF21CmeDw==
|
||||
dependencies:
|
||||
ccount "^1.0.0"
|
||||
comma-separated-tokens "^1.0.0"
|
||||
hast-util-is-element "^1.0.0"
|
||||
hast-util-whitespace "^1.0.0"
|
||||
html-void-elements "^1.0.0"
|
||||
property-information "^5.0.0"
|
||||
space-separated-tokens "^1.0.0"
|
||||
stringify-entities "^3.0.1"
|
||||
unist-util-is "^4.0.0"
|
||||
xtend "^4.0.0"
|
||||
|
||||
hast-util-to-parse5@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz#1ec44650b631d72952066cea9b1445df699f8479"
|
||||
@ -9475,6 +9555,11 @@ hast-util-to-string@^1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/hast-util-to-string/-/hast-util-to-string-1.0.4.tgz#9b24c114866bdb9478927d7e9c36a485ac728378"
|
||||
integrity sha512-eK0MxRX47AV2eZ+Lyr18DCpQgodvaS3fAQO2+b9Two9F5HEoRPhiUMNzoXArMJfZi2yieFzUBMRl3HNJ3Jus3w==
|
||||
|
||||
hast-util-whitespace@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz#e4fe77c4a9ae1cb2e6c25e02df0043d0164f6e41"
|
||||
integrity sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==
|
||||
|
||||
hastscript@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640"
|
||||
@ -13062,6 +13147,11 @@ parse-json@^5.0.0:
|
||||
json-parse-even-better-errors "^2.3.0"
|
||||
lines-and-columns "^1.1.6"
|
||||
|
||||
parse-numeric-range@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-numeric-range/-/parse-numeric-range-1.2.0.tgz#aa70b00f29624ed13e9f943e9461b306e386b0fa"
|
||||
integrity sha512-1q2tXpAOplPxcl8vrIGPWz1dJxxfmdRkCFcpxxMBerDnGuuHalOWF/xj9L8Nn5XoTUoB/6F0CeQBp2fMgkOYFg==
|
||||
|
||||
parse-passwd@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
|
||||
@ -13532,6 +13622,13 @@ prismjs@^1.21.0, prismjs@~1.25.0:
|
||||
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756"
|
||||
integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==
|
||||
|
||||
prismjs@~1.23.0:
|
||||
version "1.23.0"
|
||||
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33"
|
||||
integrity sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==
|
||||
optionalDependencies:
|
||||
clipboard "^2.0.0"
|
||||
|
||||
process-nextick-args@~2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||
@ -14344,6 +14441,15 @@ redent@^3.0.0:
|
||||
indent-string "^4.0.0"
|
||||
strip-indent "^3.0.0"
|
||||
|
||||
refractor@3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.3.1.tgz#ebbc04b427ea81dc25ad333f7f67a0b5f4f0be3a"
|
||||
integrity sha512-vaN6R56kLMuBszHSWlwTpcZ8KTMG6aUCok4GrxYDT20UIOXxOc5o6oDc8tNTzSlH3m2sI+Eu9Jo2kVdDcUTWYw==
|
||||
dependencies:
|
||||
hastscript "^6.0.0"
|
||||
parse-entities "^2.0.0"
|
||||
prismjs "~1.23.0"
|
||||
|
||||
refractor@^3.1.0, refractor@^3.3.1:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.5.0.tgz#334586f352dda4beaf354099b48c2d18e0819aec"
|
||||
@ -14427,6 +14533,30 @@ regjsparser@^0.7.0:
|
||||
dependencies:
|
||||
jsesc "~0.5.0"
|
||||
|
||||
rehype-parse@7.0.1, rehype-parse@^7.0.0:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-7.0.1.tgz#58900f6702b56767814afc2a9efa2d42b1c90c57"
|
||||
integrity sha512-fOiR9a9xH+Le19i4fGzIEowAbwG7idy2Jzs4mOrFWBSJ0sNUgy0ev871dwWnbOo371SjgjG4pwzrbgSVrKxecw==
|
||||
dependencies:
|
||||
hast-util-from-parse5 "^6.0.0"
|
||||
parse5 "^6.0.0"
|
||||
|
||||
rehype-stringify@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/rehype-stringify/-/rehype-stringify-8.0.0.tgz#9b6afb599bcf3165f10f93fc8548f9a03d2ec2ba"
|
||||
integrity sha512-VkIs18G0pj2xklyllrPSvdShAV36Ff3yE5PUO9u36f6+2qJFnn22Z5gKwBOwgXviux4UC7K+/j13AnZfPICi/g==
|
||||
dependencies:
|
||||
hast-util-to-html "^7.1.1"
|
||||
|
||||
rehype@11.0.0:
|
||||
version "11.0.0"
|
||||
resolved "https://registry.yarnpkg.com/rehype/-/rehype-11.0.0.tgz#d81729e65f4ac2b26f5de0b6bafc257eb0780e1f"
|
||||
integrity sha512-qXqRqiCFJD5CJ61CSJuNImTFrm3zVkOU9XywHDwrUuvWN74MWt72KJ67c5CM5x8g0vGcOkRVCrYj85vqkmHulQ==
|
||||
dependencies:
|
||||
rehype-parse "^7.0.0"
|
||||
rehype-stringify "^8.0.0"
|
||||
unified "^9.0.0"
|
||||
|
||||
relateurl@^0.2.7:
|
||||
version "0.2.7"
|
||||
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
|
||||
@ -14892,6 +15022,11 @@ secure-compare@3.0.1:
|
||||
resolved "https://registry.yarnpkg.com/secure-compare/-/secure-compare-3.0.1.tgz#f1a0329b308b221fae37b9974f3d578d0ca999e3"
|
||||
integrity sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=
|
||||
|
||||
select@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
|
||||
integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=
|
||||
|
||||
"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.1:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
@ -15614,6 +15749,15 @@ string_decoder@~1.1.1:
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
stringify-entities@^3.0.1:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-3.1.0.tgz#b8d3feac256d9ffcc9fa1fefdcf3ca70576ee903"
|
||||
integrity sha512-3FP+jGMmMV/ffZs86MoghGqAoqXAdxLrJP4GUdrDN1aIScYih5tuIO3eF4To5AJZ79KDZ8Fpdy7QJnK8SsL1Vg==
|
||||
dependencies:
|
||||
character-entities-html4 "^1.0.0"
|
||||
character-entities-legacy "^1.0.0"
|
||||
xtend "^4.0.0"
|
||||
|
||||
strip-ansi@6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
|
||||
@ -16014,6 +16158,11 @@ timers-browserify@2.0.12, timers-browserify@^2.0.4:
|
||||
dependencies:
|
||||
setimmediate "^1.0.4"
|
||||
|
||||
tiny-emitter@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
|
||||
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
|
||||
|
||||
tiny-glob@^0.2.6:
|
||||
version "0.2.9"
|
||||
resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.9.tgz#2212d441ac17928033b110f8b3640683129d31e2"
|
||||
@ -16507,6 +16656,18 @@ unified@9.2.0:
|
||||
trough "^1.0.0"
|
||||
vfile "^4.0.0"
|
||||
|
||||
unified@9.2.1:
|
||||
version "9.2.1"
|
||||
resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.1.tgz#ae18d5674c114021bfdbdf73865ca60f410215a3"
|
||||
integrity sha512-juWjuI8Z4xFg8pJbnEZ41b5xjGUWGHqXALmBZ3FC3WX0PIx1CZBIIJ6mXbYMcf6Yw4Fi0rFUTA1cdz/BglbOhA==
|
||||
dependencies:
|
||||
bail "^1.0.0"
|
||||
extend "^3.0.0"
|
||||
is-buffer "^2.0.0"
|
||||
is-plain-obj "^2.0.0"
|
||||
trough "^1.0.0"
|
||||
vfile "^4.0.0"
|
||||
|
||||
unified@^9.0.0:
|
||||
version "9.2.2"
|
||||
resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user