Skip to content

Commit aa6c729

Browse files
feat(chore): merge commit
2 parents fdef8ce + 493eef7 commit aa6c729

File tree

372 files changed

+30918
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

372 files changed

+30918
-1
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
node_modules
2+
dist
3+
out
4+
.next
25

36
# env vars
47
.env*

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ Once you've forked this repository, you can clone it and follow the instructions
2828
A monorepo using pnpm workspace, Module Federation, React, and Vite as the bundler
2929
* __[`react-vite-nx`](./examples/react-vite-nx)__
3030
A monorepo using Nx, React, and Vite as the bundler
31-
* __[`react-vite-ts`](./examples/react-vite-ts)__
31+
* __[`turbo-rspack-mf`](./examples/turbo-rspack-mf/)__
32+
A monorepo using Turborepo, React, and Rspack as the bundler
33+
*`` __[`react-vite-ts`](./examples/react-vite-ts)__
3234
A React application built in TypeScript, using Vite as the bundler.
3335
* __[`rspress`](./examples/rspress)__
3436
A Rspress application.
37+
* __[`rspack-project`](./examples/rspack-project)__
38+
A simple Rspack application using React.
3539

3640
## Deploying an example project
3741
After cloning your fork of this repository locally, follow these steps:
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@mf-types

examples/react-airbnb-clone/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Airbnb Example
2+
3+
This is an Airbnb clone sample based on [another example](https://github.com/AntonioErdeljac/next13-airbnb-clone) made by [Antonio Erdeljac](https://github.com/AntonioErdeljac). ([video](https://www.youtube.com/watch?v=c_-b_isI4vg&t=9493s))
4+
5+
The example was ported from Next.js to vanilla React using React Router for the purposes of showcasing the use of federated components with Zephyr.
6+
7+
To run:
8+
9+
```bash
10+
pnpm i
11+
pnpm dev
12+
```
13+
14+
To build
15+
16+
```bash
17+
# You need to first build the remotes in order for the host to attach them to the application
18+
pnpm build-remotes
19+
pnpm build-host
20+
```
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"plugins": [],
3+
"presets": [["@babel/preset-react", { "runtime": "automatic" }], "@babel/preset-typescript"]
4+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "airbnb-categories",
3+
"version": "0.1.0",
4+
"private": true,
5+
"scripts": {
6+
"dev": "webpack serve",
7+
"build": "rimraf dist && webpack --mode production",
8+
"start": "http-server dist -p 3011"
9+
}
10+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
};
Binary file not shown.
Loading
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<html>
2+
<head>
3+
<title>Host App</title>
4+
</head>
5+
<body>
6+
<div id="root"></div>
7+
</body>
8+
</html>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { MemoryRouter } from 'react-router-dom';
2+
import Categories from './components/Categories';
3+
import './globals.css';
4+
5+
export default function App() {
6+
return (
7+
<MemoryRouter>
8+
<Categories />
9+
</MemoryRouter>
10+
);
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { StrictMode } from 'react';
2+
import { createRoot } from 'react-dom/client';
3+
import App from './app';
4+
5+
const container = document.getElementById('root');
6+
7+
createRoot(container!).render(
8+
<StrictMode>
9+
<App />
10+
</StrictMode>,
11+
);
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { TbBeach, TbMountain, TbPool } from 'react-icons/tb';
2+
import {
3+
GiBarn,
4+
GiBoatFishing,
5+
GiCactus,
6+
GiCastle,
7+
GiCaveEntrance,
8+
GiForestCamp,
9+
GiIsland,
10+
GiWindmill,
11+
} from 'react-icons/gi';
12+
import { FaSkiing } from 'react-icons/fa';
13+
import { BsSnow } from 'react-icons/bs';
14+
import { IoDiamond } from 'react-icons/io5';
15+
import { MdOutlineVilla } from 'react-icons/md';
16+
17+
import CategoryBox from './CategoryBox';
18+
import Container from './Container';
19+
import { useLocation, useSearchParams } from 'react-router-dom';
20+
21+
export const categories = [
22+
{
23+
label: 'Beach',
24+
icon: TbBeach,
25+
description: 'This property is close to the beach!',
26+
},
27+
{
28+
label: 'Windmills',
29+
icon: GiWindmill,
30+
description: 'This property is has windmills!',
31+
},
32+
{
33+
label: 'Modern',
34+
icon: MdOutlineVilla,
35+
description: 'This property is modern!',
36+
},
37+
{
38+
label: 'Countryside',
39+
icon: TbMountain,
40+
description: 'This property is in the countryside!',
41+
},
42+
{
43+
label: 'Pools',
44+
icon: TbPool,
45+
description: 'This is property has a beautiful pool!',
46+
},
47+
{
48+
label: 'Islands',
49+
icon: GiIsland,
50+
description: 'This property is on an island!',
51+
},
52+
{
53+
label: 'Lake',
54+
icon: GiBoatFishing,
55+
description: 'This property is near a lake!',
56+
},
57+
{
58+
label: 'Skiing',
59+
icon: FaSkiing,
60+
description: 'This property has skiing activies!',
61+
},
62+
{
63+
label: 'Castles',
64+
icon: GiCastle,
65+
description: 'This property is an ancient castle!',
66+
},
67+
{
68+
label: 'Caves',
69+
icon: GiCaveEntrance,
70+
description: 'This property is in a spooky cave!',
71+
},
72+
{
73+
label: 'Camping',
74+
icon: GiForestCamp,
75+
description: 'This property offers camping activities!',
76+
},
77+
{
78+
label: 'Arctic',
79+
icon: BsSnow,
80+
description: 'This property is in arctic environment!',
81+
},
82+
{
83+
label: 'Desert',
84+
icon: GiCactus,
85+
description: 'This property is in the desert!',
86+
},
87+
{
88+
label: 'Barns',
89+
icon: GiBarn,
90+
description: 'This property is in a barn!',
91+
},
92+
{
93+
label: 'Lux',
94+
icon: IoDiamond,
95+
description: 'This property is brand new and luxurious!',
96+
},
97+
];
98+
99+
const Categories = () => {
100+
const [params] = useSearchParams();
101+
const category = params?.get('category');
102+
return (
103+
<Container>
104+
<div
105+
className="
106+
pt-4
107+
flex
108+
flex-row
109+
items-center
110+
justify-between
111+
overflow-x-auto
112+
"
113+
>
114+
{categories.map((item) => (
115+
<CategoryBox
116+
key={item.label}
117+
label={item.label}
118+
icon={item.icon}
119+
selected={category === item.label}
120+
/>
121+
))}
122+
</div>
123+
</Container>
124+
);
125+
};
126+
127+
export default Categories;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import qs from 'query-string';
2+
import { useCallback } from 'react';
3+
import { IconType } from 'react-icons';
4+
import { useNavigate, useSearchParams } from 'react-router-dom';
5+
6+
interface CategoryBoxProps {
7+
icon: IconType;
8+
label: string;
9+
selected?: boolean;
10+
}
11+
12+
const CategoryBox: React.FC<CategoryBoxProps> = ({ icon: Icon, label, selected }) => {
13+
const navigate = useNavigate();
14+
const [params] = useSearchParams();
15+
16+
const handleClick = useCallback(() => {
17+
let currentQuery = {};
18+
19+
if (params) {
20+
currentQuery = qs.parse(params.toString());
21+
}
22+
23+
const updatedQuery: any = {
24+
...currentQuery,
25+
category: label,
26+
};
27+
28+
if (params?.get('category') === label) {
29+
delete updatedQuery.category;
30+
}
31+
32+
const url = qs.stringifyUrl(
33+
{
34+
url: '/',
35+
query: updatedQuery,
36+
},
37+
{ skipNull: true },
38+
);
39+
40+
navigate(url);
41+
}, [label, navigate, params]);
42+
43+
return (
44+
<div
45+
onClick={handleClick}
46+
className={`
47+
flex
48+
flex-col
49+
items-center
50+
justify-center
51+
gap-2
52+
p-3
53+
border-b-2
54+
hover:text-neutral-800
55+
transition
56+
cursor-pointer
57+
${selected ? 'border-b-neutral-800' : 'border-transparent'}
58+
${selected ? 'text-neutral-800' : 'text-neutral-500'}
59+
`}
60+
>
61+
<Icon size={26} />
62+
<div className="font-medium text-sm">{label}</div>
63+
</div>
64+
);
65+
};
66+
67+
export default CategoryBox;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
interface ContainerProps {
2+
children: React.ReactNode;
3+
}
4+
5+
const Container: React.FC<ContainerProps> = ({ children }) => {
6+
return (
7+
<div
8+
className="
9+
max-w-[2520px]
10+
mx-auto
11+
xl:px-20
12+
md:px-10
13+
sm:px-2
14+
px-4
15+
"
16+
>
17+
{children}
18+
</div>
19+
);
20+
};
21+
22+
export default Container;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import './globals.css';
2+
import Categories from './components/Categories';
3+
export default Categories;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import('./bootstrap');
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/** @type {import('tailwindcss').Config} */
2+
module.exports = {
3+
content: ['./src/**/*.{js,ts,jsx,tsx}'],
4+
theme: {
5+
extend: {},
6+
},
7+
plugins: [],
8+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"extends": "../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"target": "es5",
5+
"lib": ["dom", "dom.iterable", "esnext"],
6+
"allowJs": true,
7+
"skipLibCheck": true,
8+
"strict": true,
9+
"noEmit": true,
10+
"esModuleInterop": true,
11+
"module": "esnext",
12+
"moduleResolution": "node",
13+
"resolveJsonModule": true,
14+
"isolatedModules": true,
15+
"jsx": "preserve",
16+
"incremental": true,
17+
"forceConsistentCasingInFileNames": true
18+
},
19+
"include": ["federated.d.ts", "**/*.ts", "**/*.tsx"],
20+
"exclude": ["node_modules"]
21+
}

0 commit comments

Comments
 (0)