Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
93f274b
refactor(docs): revise code block (#3922)
wingkwong Nov 5, 2024
e056c0b
refactor(docs): autocomplete dx (#3934)
wingkwong Nov 6, 2024
17c1419
refactor(docs): breadcrumbs dx (#3968)
wingkwong Nov 7, 2024
717206b
refactor(docs): avatar dx (#3951)
wingkwong Nov 7, 2024
2dc2bcd
refactor(docs): badge dx (#3960)
wingkwong Nov 7, 2024
74a2268
refactor(docs): button dx (#3981)
wingkwong Nov 7, 2024
473b40b
refactor(docs): calendar dx (#4022)
wingkwong Nov 13, 2024
0b9fd36
refactor(docs): switch dx (#4037)
wingkwong Nov 13, 2024
9c38799
refactor(docs): tooltip (#4035)
wingkwong Nov 13, 2024
e44916c
refactor(docs): usage dx (#4036)
wingkwong Nov 13, 2024
9590950
refactor(docs): circular-progress dx (#4029)
wingkwong Nov 13, 2024
565197d
refactor(docs): chip-dx (#4028)
wingkwong Nov 13, 2024
09037e8
refactor(docs): checkbox-group dx (#4027)
wingkwong Nov 13, 2024
4846192
refactor(docs): checkbox dx (#4024)
wingkwong Nov 13, 2024
c037ff9
refactor(docs): card dx (#4023)
wingkwong Nov 13, 2024
6f37311
refactor(docs): skeleton dx (#4042)
wingkwong Nov 14, 2024
6a2a717
refactor(docs): spacer dx (#4043)
wingkwong Nov 14, 2024
2fad7a6
refactor(docs): snippet dx (#4044)
wingkwong Nov 14, 2024
6d7e098
refactor(docs): scroll-shadow dx (#4045)
wingkwong Nov 14, 2024
1fe7eb2
refactor(docs): code dx (#4046)
wingkwong Nov 14, 2024
5aad6fe
refactor(docs): kbd dx (#4047)
wingkwong Nov 14, 2024
bfcc75c
refactor(docs): link dx (#4048)
wingkwong Nov 14, 2024
fb89747
refactor(docs): progress dx (#4049)
wingkwong Nov 14, 2024
0d89609
refactor(docs): divider dx (#4050)
wingkwong Nov 14, 2024
7956ad1
refactor(docs): listbox dx (#4051)
wingkwong Nov 14, 2024
2debe54
Merge branch 'beta/release-next' into refactor/overall-dx
wingkwong Nov 15, 2024
945a37e
Merge branch 'beta/release-next' into refactor/overall-dx
wingkwong Nov 17, 2024
c91a6dc
chore(docs): replace the props of autocomplete from value to key (#4129)
ryo-manba Nov 21, 2024
e77306a
refactor(docs): alert dx (#4108)
wingkwong Nov 22, 2024
e5a69d9
refactor(docs): image dx (#4061)
wingkwong Nov 22, 2024
7eab2e8
refactor(docs): textarea dx (#4063)
wingkwong Nov 22, 2024
8282d2e
refactor(docs): spinner dx (#4088)
wingkwong Nov 22, 2024
d7fa7ea
refactor(docs): radio-group dx (#4064)
wingkwong Nov 22, 2024
dd0ac9b
refactor(docs): pagination dx (#4062)
wingkwong Nov 22, 2024
75e13a8
refactor(docs): time-input dx (#4065)
wingkwong Nov 22, 2024
5d796e2
refactor(docs): slider dx (#4066)
wingkwong Nov 22, 2024
971b068
Merge branch 'beta/release-next' into refactor/overall-dx
wingkwong Nov 23, 2024
597edb3
refactor(docs): make icon code collapsible
wingkwong Nov 23, 2024
d8b6f91
refactor(docs): specify versions for date packages (#4138)
wingkwong Nov 27, 2024
db383c2
refactor(docs): tabs dx (#4067)
wingkwong Nov 27, 2024
f2ec5c9
refactor(docs): input dx (#4102)
wingkwong Nov 27, 2024
392280d
refactor(docs): navbar dx (#4076)
wingkwong Nov 27, 2024
ce610d7
refactor(docs): modal dx (#4077)
wingkwong Nov 27, 2024
54b4a14
refactor(docs): select dx (#4078)
wingkwong Nov 27, 2024
5dc662e
refactor(docs): table dx (#4079)
wingkwong Nov 27, 2024
a7ebb75
refactor(docs): popover dx (#4090)
wingkwong Nov 27, 2024
a01c77a
refactor(docs): range-calendar dx (#4089)
wingkwong Nov 27, 2024
5dabfa8
refactor(docs): date input dx (#4100)
wingkwong Nov 27, 2024
0aa6ed0
refactor(docs): dropdown dx (#4101)
wingkwong Nov 27, 2024
e8baabf
refactor(docs): date-picker dx (#4103)
wingkwong Nov 27, 2024
a668e7b
refactor(docs): date-range-picker dx (#4104)
wingkwong Nov 27, 2024
79737db
Merge branch 'beta/release-next' into refactor/overall-dx
wingkwong Nov 28, 2024
fe1a1ef
refactor(docs): drawer dx (#4109)
wingkwong Nov 28, 2024
c75ee3e
refactor(docs): make icon collapsible
wingkwong Nov 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 0 additions & 4 deletions apps/docs/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
4 changes: 2 additions & 2 deletions apps/docs/components/docs/components/code-demo/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {FileCode} from "./types";

const importRegex = /^(import)\s(?!type(of\s|\s)(?!from)).*?$/gm;
const importRegex = /^(import\s+(?!type\s+\{)[\s\S]*?;)/gm;

const exportDefaultRegex = /export\s+default\s+function\s+\w+\s*\(\s*\)\s*\{/;

Expand Down Expand Up @@ -31,7 +31,7 @@ export const transformCode = (
// replace match with const Name = () => (
return `const ${compName} = () => {`;
})
.replace("export", "");
.replace(/export/g, "");

// add render(<App/>) to cleanedCode if has const App = () => {
if (cleanedCode.includes(`const App = () => {`)) {
Expand Down
106 changes: 84 additions & 22 deletions apps/docs/components/docs/components/codeblock.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import type {Language, PrismTheme} from "prism-react-renderer";
import type {TransformTokensTypes} from "./helper";

import React, {forwardRef, useEffect} from "react";
import {clsx, dataAttr, getUniqueID} from "@nextui-org/shared-utils";
import BaseHighlight, {Language, PrismTheme, defaultProps} from "prism-react-renderer";
import {debounce, omit} from "@nextui-org/shared-utils";
import {cn} from "@nextui-org/react";

import {transformTokens} from "./helper";

import defaultTheme from "@/libs/prism-theme";

Expand Down Expand Up @@ -142,21 +148,36 @@ const Codeblock = forwardRef<HTMLPreElement, CodeblockProps>(
{...props}
>
{({className, style, tokens, getLineProps, getTokenProps}) => (
<div className="w-full" data-language={language}>
<pre
ref={ref}
className={clsx(className, classNameProp, "flex max-w-full", {
<pre
ref={ref}
className={clsx(
className,
classNameProp,
`language-${codeLang}`,
"max-w-full contents",
{
"flex-col": isMultiLine,
"scrollbar-hide overflow-x-scroll": hideScrollBar,
})}
style={style}
translate="no"
>
{tokens.map((line, i) => {
"overflow-x-scroll scrollbar-hide": hideScrollBar,
},
)}
data-language={language}
style={style}
>
{transformTokens(tokens).map((line) => {
const folderLine = line[0] as TransformTokensTypes;

const isFolder = folderLine.types?.includes("folderStart");

const renderLine = (
line: TransformTokensTypes[],
i: number,
as: "div" | "span" = "div",
) => {
const Tag = as;
const lineProps = getLineProps({line, key: i});

return (
<div
<Tag
{...omit(lineProps, ["key"])}
key={`${i}-${getUniqueID("line-wrapper")}`}
className={clsx(
Expand All @@ -167,25 +188,48 @@ const Codeblock = forwardRef<HTMLPreElement, CodeblockProps>(
"px-2": showLines,
},
{
"before:content-[''] before:w-full before:h-full before:absolute before:z-0 before:left-0 before:bg-gradient-to-r before:from-white/10 before:to-code-background":
shouldHighlightLine(i),
"before:to-code-background before:absolute before:left-0 before:z-0 before:h-full before:w-full before:bg-gradient-to-r before:from-white/10 before:content-['']":
isFolder ? false : shouldHighlightLine(i),
},
)}
data-deleted={dataAttr(highlightStyle?.[i] === "deleted")}
data-inserted={dataAttr(highlightStyle?.[i] === "inserted")}
>
{showLines && (
<span className="select-none text-xs mr-6 opacity-30">{i + 1}</span>
<span
className={cn(
"mr-6 select-none text-xs opacity-30",
i + 1 >= 10 ? "mr-4" : "",
i + 1 >= 100 ? "mr-2" : "",
i + 1 >= 1000 ? "mr-0" : "",
)}
>
{i + 1}
</span>
)}

{line.map((token, key) => {
// Bun has no color style by default in the code block, so hack add in here
const props = getTokenProps({token, key}) || {};

return (
const isCopy = token.types.includes("copy");

return isCopy ? (
<span key={key} className="copy-token" style={{whiteSpace: "inherit"}}>
{token.folderContent?.map((folderTokens) => {
return folderTokens.map((token, index) => {
// Hack for wrap line
return token.content === "" ? (
<div key={`${index}-${getUniqueID("line")}`} />
) : (
<span key={`${index}-${getUniqueID("line")}`}>{token.content}</span>
);
});
})}
</span>
) : (
<span
{...omit(props, ["key"])}
key={`${key}-${getUniqueID("line")}`}
className={className}
className={cn(className, token.class)}
style={{
...props.style,
...(highlightStyleToken.some((t) => {
Expand All @@ -201,11 +245,29 @@ const Codeblock = forwardRef<HTMLPreElement, CodeblockProps>(
/>
);
})}
</div>
</Tag>
);
})}
</pre>
</div>
};
const renderFolderTokens = (tokens: TransformTokensTypes[][]) => {
return tokens.map((token, key) => {
const index = key + folderLine.index! + 1;

return renderLine(token, index);
});
};

return isFolder ? (
<details key={`${folderLine.index}`} open={folderLine.open ? true : undefined}>
<summary className="cursor-pointer">
{renderLine(folderLine.summaryContent as any, folderLine.index!, "span")}
</summary>
{renderFolderTokens(folderLine.folderContent as any)}
</details>
) : (
renderLine(line, folderLine.index!)
);
})}
</pre>
)}
</BaseHighlight>
);
Expand Down
189 changes: 189 additions & 0 deletions apps/docs/components/docs/components/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import type Highlight from "prism-react-renderer";

export type TransformTokens = Parameters<Highlight["props"]["children"]>[0]["tokens"];

export type TransformTokensTypes = TransformTokens[0][0] & {
folderContent?: TransformTokens;
summaryContent?: TransformTokens[0];
class?: string;
index?: number;
open?: boolean;
};

const startFlag = ["{", "["];
const endFlag = ["}", "]"];
const specialStartFlag = ["("];
const specialEndFlag = [")"];
const defaultFoldFlagList = ["cn", "HTMLAttributes"];
const defaultShowFlagList = ["Component", "forwardRef", "App"];

/**
* Transform tokens from `prism-react-renderer` to wrap them in folder structure
*
* @example
* transformTokens(tokens) -> wrap tokens in folder structure
*/
export function transformTokens(tokens: TransformTokens, folderLine = 10) {
const result: TransformTokens = [];
let lastIndex = 0;
let isShowFolder = false;
let fold = false;

tokens.forEach((token, index) => {
if (index < lastIndex) {
return;
}

let startToken: TransformTokens[0][0] = null as any;
let mergedStartFlagList = [...startFlag];

token.forEach((t) => {
if (defaultFoldFlagList.some((text) => t.content.includes(text))) {
// If cn then need to judge whether it is import token
if (t.content.includes("cn") && token.some((t) => t.content === "import")) {
return;
}

// If HTMLAttributes then need to judge whether it have start flag
if (
t.content.includes("HTMLAttributes") &&
!token.some((t) => startFlag.includes(t.content))
) {
return;
}

fold = true;
mergedStartFlagList.push(...specialStartFlag);
}

if (mergedStartFlagList.includes(t.content)) {
startToken = t;
}

if (defaultShowFlagList.some((text) => t.content.includes(text))) {
isShowFolder = true;
}
});

const mergedOptions = fold
? {
specialEndFlag,
specialStartFlag,
}
: undefined;
const isFolder = checkIsFolder(token, mergedOptions);

if (isFolder && startToken) {
const endIndex = findEndIndex(tokens, index + 1, mergedOptions);

// Greater than or equal to folderLine then will folder otherwise it will show directly
if (endIndex !== -1 && (endIndex - index >= folderLine || isShowFolder || fold)) {
lastIndex = endIndex;
const folder = tokens.slice(index + 1, endIndex);
const endToken = tokens[endIndex];
const ellipsisToken: TransformTokensTypes = {
types: ["ellipsis"],
content: "",
class: "custom-folder ellipsis-token",
};
const copyContent: TransformTokensTypes = {
types: ["copy"],
content: "",
folderContent: folder,
class: "custom-folder copy-token",
};

endToken.forEach((t, _, arr) => {
let className = "";

className += "custom-folder";
if (t.content.trim() === "" && (arr.length === 3 || arr.length === 4)) {
// Add length check to sure it's added to } token
className += " empty-token";
}
(t as TransformTokensTypes).class = className;
});

startToken.types = ["folderStart"];
(startToken as TransformTokensTypes).folderContent = folder;
(startToken as TransformTokensTypes).summaryContent = [
...token,
ellipsisToken,
copyContent,
...endToken,
];
(startToken as TransformTokensTypes).index = index;
if (isShowFolder && !fold) {
(startToken as TransformTokensTypes).open = true;
}

result.push([startToken]);

isShowFolder = false;
fold = false;

return;
}
}
token.forEach((t) => {
(t as TransformTokensTypes).index = index;
});
result.push(token);
});

return result;
}

interface SpecialOptions {
specialStartFlag?: string[];
specialEndFlag?: string[];
}

function checkIsFolder(
token: TransformTokens[0],
{specialStartFlag, specialEndFlag}: SpecialOptions = {},
) {
const stack: string[] = [];
const mergedStartFlagList = specialStartFlag ? [...startFlag, ...specialStartFlag] : startFlag;
const mergedEndFlagList = specialEndFlag ? [...endFlag, ...specialEndFlag] : endFlag;

for (const t of token) {
if (mergedStartFlagList.includes(t.content)) {
stack.push(t.content);
} else if (mergedEndFlagList.includes(t.content)) {
stack.pop();
}
}

return stack.length !== 0;
}

function findEndIndex(
tokens: TransformTokens,
startIndex: number,
{specialStartFlag, specialEndFlag}: SpecialOptions = {},
) {
const stack: string[] = ["flag"];
const mergedStartFlagList = specialStartFlag ? [...startFlag, ...specialStartFlag] : startFlag;
const mergedEndFlagList = specialEndFlag ? [...endFlag, ...specialEndFlag] : endFlag;

for (let i = startIndex; i < tokens.length; i++) {
const token = tokens[i];

for (const line of token) {
const transformLine = line.content.replace(/\$/g, "");

if (mergedStartFlagList.includes(transformLine)) {
stack.push("flag");
} else if (mergedEndFlagList.includes(transformLine)) {
stack.pop();
}

if (stack.length === 0) {
return i;
}
}
}

return -1;
}
7 changes: 6 additions & 1 deletion apps/docs/components/mdx-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,12 @@ const Code = ({
});
}}
>
<Codeblock codeString={codeString} language={language} metastring={meta} />
<Codeblock
className="sp-editor"
codeString={codeString}
language={language}
metastring={meta}
/>
</Components.Snippet>
);
};
Expand Down
Loading