Skip to content

Commit

Permalink
Merge branch 'refactor/overall-dx' into refactor/button-dx
Browse files Browse the repository at this point in the history
  • Loading branch information
wingkwong committed Nov 7, 2024
2 parents fb087aa + 17c1419 commit 22da9ed
Show file tree
Hide file tree
Showing 103 changed files with 3,086 additions and 2,949 deletions.
6 changes: 1 addition & 5 deletions apps/docs/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"files": ["*.ts", "*.tsx"],
"parserOptions": {
"project": ["apps/docs/tsconfig(.*)?.json"],
"ecmaFeatures": {
Expand All @@ -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
Expand Up @@ -2,7 +2,7 @@ import {get} from "lodash";

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 All @@ -29,7 +29,7 @@ export const transformCode = (code: string, imports = {}, compName = "App") => {
// 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
34 changes: 34 additions & 0 deletions apps/docs/content/components/autocomplete/async-filtering.raw.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {Autocomplete, AutocompleteItem} from "@nextui-org/react";
import {useAsyncList} from "@react-stately/data";

export default function App() {
let list = useAsyncList({
async load({signal, filterText}) {
let res = await fetch(`https://swapi.py4e.com/api/people/?search=${filterText}`, {signal});
let json = await res.json();

return {
items: json.results,
};
},
});

return (
<Autocomplete
className="max-w-xs"
inputValue={list.filterText}
isLoading={list.isLoading}
items={list.items}
label="Select a character"
placeholder="Type to search..."
variant="bordered"
onInputChange={list.setFilterText}
>
{(item) => (
<AutocompleteItem key={item.name} className="capitalize">
{item.name}
</AutocompleteItem>
)}
</Autocomplete>
);
}
41 changes: 41 additions & 0 deletions apps/docs/content/components/autocomplete/async-filtering.raw.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {Autocomplete, AutocompleteItem} from "@nextui-org/react";
import {useAsyncList} from "@react-stately/data";

type SWCharacter = {
name: string;
height: string;
mass: string;
birth_year: string;
};

export default function App() {
let list = useAsyncList<SWCharacter>({
async load({signal, filterText}) {
let res = await fetch(`https://swapi.py4e.com/api/people/?search=${filterText}`, {signal});
let json = await res.json();

return {
items: json.results,
};
},
});

return (
<Autocomplete
className="max-w-xs"
inputValue={list.filterText}
isLoading={list.isLoading}
items={list.items}
label="Select a character"
placeholder="Type to search..."
variant="bordered"
onInputChange={list.setFilterText}
>
{(item) => (
<AutocompleteItem key={item.name} className="capitalize">
{item.name}
</AutocompleteItem>
)}
</Autocomplete>
);
}
78 changes: 2 additions & 76 deletions apps/docs/content/components/autocomplete/async-filtering.ts
Original file line number Diff line number Diff line change
@@ -1,79 +1,5 @@
const App = `import {Autocomplete, AutocompleteItem} from "@nextui-org/react";
import {useAsyncList} from "@react-stately/data";
export default function App() {
let list = useAsyncList({
async load({signal, filterText}) {
let res = await fetch(\`https://swapi.py4e.com/api/people/?search=\${filterText}\`, {signal});
let json = await res.json();
return {
items: json.results,
};
},
});
return (
<Autocomplete
className="max-w-xs"
inputValue={list.filterText}
isLoading={list.isLoading}
items={list.items}
label="Select a character"
placeholder="Type to search..."
variant="bordered"
onInputChange={list.setFilterText}
>
{(item) => (
<AutocompleteItem key={item.name} className="capitalize">
{item.name}
</AutocompleteItem>
)}
</Autocomplete>
);
}`;

const AppTs = `import {Autocomplete, AutocompleteItem} from "@nextui-org/react";
import {useAsyncList} from "@react-stately/data";
type SWCharacter = {
name: string;
height: string;
mass: string;
birth_year: string;
};
export default function App() {
let list = useAsyncList<SWCharacter>({
async load({signal, filterText}) {
let res = await fetch(\`https://swapi.py4e.com/api/people/?search=\${filterText}\`, {signal});
let json = await res.json();
return {
items: json.results,
};
},
});
return (
<Autocomplete
className="max-w-xs"
inputValue={list.filterText}
isLoading={list.isLoading}
items={list.items}
label="Select a character"
placeholder="Type to search..."
variant="bordered"
onInputChange={list.setFilterText}
>
{(item) => (
<AutocompleteItem key={item.name} className="capitalize">
{item.name}
</AutocompleteItem>
)}
</Autocomplete>
);
}`;
import App from "./async-filtering.raw.jsx?raw";
import AppTs from "./async-filtering.raw.tsx?raw";

const react = {
"/App.jsx": App,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React from "react";
import {Autocomplete, AutocompleteItem} from "@nextui-org/react";
import {useInfiniteScroll} from "@nextui-org/use-infinite-scroll";

export function usePokemonList({fetchDelay = 0} = {}) {
const [items, setItems] = React.useState([]);
const [hasMore, setHasMore] = React.useState(true);
const [isLoading, setIsLoading] = React.useState(false);
const [offset, setOffset] = React.useState(0);
const limit = 10; // Number of items per page, adjust as necessary

const loadPokemon = async (currentOffset) => {
const controller = new AbortController();
const {signal} = controller;

try {
setIsLoading(true);

if (offset > 0) {
// Delay to simulate network latency
await new Promise((resolve) => setTimeout(resolve, fetchDelay));
}

const res = await fetch(
`https://pokeapi.co/api/v2/pokemon?offset=${currentOffset}&limit=${limit}`,
{signal},
);

if (!res.ok) {
throw new Error("Network response was not ok");
}

let json = await res.json();

setHasMore(json.next !== null);
// Append new results to existing ones
setItems((prevItems) => [...prevItems, ...json.results]);
} catch (error) {
if (error.name === "AbortError") {
// eslint-disable-next-line no-console
console.log("Fetch aborted");
} else {
// eslint-disable-next-line no-console
console.error("There was an error with the fetch operation:", error);
}
} finally {
setIsLoading(false);
}
};

React.useEffect(() => {
loadPokemon(offset);
}, []);

const onLoadMore = () => {
const newOffset = offset + limit;

setOffset(newOffset);
loadPokemon(newOffset);
};

return {
items,
hasMore,
isLoading,
onLoadMore,
};
}

export default function App() {
const [isOpen, setIsOpen] = React.useState(false);
const {items, hasMore, isLoading, onLoadMore} = usePokemonList({fetchDelay: 1500});

const [, scrollerRef] = useInfiniteScroll({
hasMore,
isEnabled: isOpen,
shouldUseLoader: false, // We don't want to show the loader at the bottom of the list
onLoadMore,
});

return (
<Autocomplete
className="max-w-xs"
defaultItems={items}
isLoading={isLoading}
label="Pick a Pokemon"
placeholder="Select a Pokemon"
scrollRef={scrollerRef}
variant="bordered"
onOpenChange={setIsOpen}
>
{(item) => (
<AutocompleteItem key={item.name} className="capitalize">
{item.name}
</AutocompleteItem>
)}
</Autocomplete>
);
}
Loading

0 comments on commit 22da9ed

Please sign in to comment.