Skip to content

Commit 61817ea

Browse files
committed
ArcBrowser and ReadME
1 parent 4030a47 commit 61817ea

File tree

18 files changed

+593
-128
lines changed

18 files changed

+593
-128
lines changed

README.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# react-browser-containers
22

3-
React Browser "container" components library , with tabs functionality.
3+
React Browser "container" components library , with tabs functionality. The library currency provides two browser components: `ChromeBrowser` and `ArcBrowser`.
44

55
## Basic Usage
66

@@ -29,7 +29,7 @@ const App = () => {
2929

3030
```js
3131
export type ChromeBrowserProps = {
32-
theme?: "light" | "dark"; // theme of the browser, default is light
32+
theme?: "light" | "dark"; // theme of the browser, default is light. The light and dark theme of ArcBrowser is the same.
3333
tabs?: Array<{ // pages in the browser
3434
name: string;
3535
link: string; // decorative link in the URL bar
@@ -39,12 +39,29 @@ export type ChromeBrowserProps = {
3939
usecontentsize?: boolean; // default is false: browser will be the size of it's parent element. true: browser will be the size of it's content
4040
leftIcons?: React.ReactNode; // leave empty for default icons
4141
rightIcons?: React.ReactNode; // leave empty for default icons
42+
lightTheme?: Theme; // changes the light theme of the browser
43+
darkTheme?: Theme; // changes the dark theme of the browser
4244
children?: React.ReactNode; // content displayed under all pages
4345
tab?: number;
4446
setTab?: (tab: number) => void;
4547
};
4648
```
4749

50+
```js
51+
export default interface Theme {
52+
theme: string;
53+
bg: string;
54+
contentBg: string;
55+
text: string;
56+
border: string;
57+
searchBarBg: string;
58+
tabBarBg: string;
59+
tabDivider: string;
60+
tabHoverBg: string;
61+
tabSelectedBg: string;
62+
}
63+
```
64+
4865
## Development
4966

5067
To get started:

src/assets/morehori.svg

Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import React from "react";
2+
import { ThemeProvider } from "styled-components";
3+
import BrowserProps from "../types/BrowserProp";
4+
import {
5+
BrowserContainer,
6+
ContentContainer,
7+
Dot,
8+
Dots,
9+
IconsFlex,
10+
SearchBar,
11+
SideBar,
12+
TabContainer,
13+
TabsContainer,
14+
TitleRow,
15+
darkTheme as defaultDarkTheme,
16+
lightTheme as defaultLightTheme,
17+
} from "./styles";
18+
19+
// Import SVGs
20+
import ArrowBackIcon from "../../assets/arrowback.svg?react";
21+
import ArrowForwardIcon from "../../assets/arrowforward.svg?react";
22+
import MoreHoriIcon from "../../assets/morehori.svg?react";
23+
24+
const ChromeBrowser: React.FC<BrowserProps> = ({
25+
theme = "light",
26+
tabs = [
27+
{
28+
name: "Example",
29+
link: "example.com",
30+
content: (
31+
<div
32+
style={{
33+
display: "flex",
34+
justifyContent: "center",
35+
alignItems: "center",
36+
width: "640px",
37+
height: "480px",
38+
}}
39+
>
40+
Hello
41+
</div>
42+
),
43+
},
44+
],
45+
shadow = true,
46+
usecontentsize = false,
47+
leftIcons = (
48+
<>
49+
<ArrowBackIcon width={16} height={16} />
50+
<ArrowForwardIcon width={16} height={16} />
51+
</>
52+
),
53+
rightIcons = <MoreHoriIcon width={16} height={16} />,
54+
children = null,
55+
lightTheme = null,
56+
darkTheme = null,
57+
tab = 0,
58+
setTab = () => {},
59+
...props
60+
}) => {
61+
return (
62+
<ThemeProvider
63+
theme={
64+
theme === "dark"
65+
? darkTheme || defaultDarkTheme
66+
: lightTheme || defaultLightTheme
67+
}
68+
>
69+
<BrowserContainer
70+
{...props}
71+
$shadow={shadow}
72+
$usecontentsize={usecontentsize}
73+
>
74+
<SideBar>
75+
<TitleRow>
76+
<Dots>
77+
<Dot color="red" />
78+
<Dot />
79+
<Dot color="green" />
80+
</Dots>
81+
<IconsFlex>
82+
{leftIcons}
83+
{rightIcons}
84+
</IconsFlex>
85+
</TitleRow>
86+
<SearchBar>
87+
{Array.isArray(tabs) && tabs.length > 0 && tabs[tab].link}
88+
</SearchBar>
89+
<TabsContainer>
90+
{Array.isArray(tabs) &&
91+
tabs.length > 0 &&
92+
tabs.map((t, index) => {
93+
if (index === tab) {
94+
return (
95+
<TabContainer
96+
key={index}
97+
onClick={() => setTab(index)}
98+
selected
99+
>
100+
{t.name}
101+
</TabContainer>
102+
);
103+
} else {
104+
return (
105+
<TabContainer key={index} onClick={() => setTab(index)}>
106+
{t.name}
107+
</TabContainer>
108+
);
109+
}
110+
})}
111+
</TabsContainer>
112+
</SideBar>
113+
<ContentContainer>
114+
{Array.isArray(tabs) && tabs.length > 0 && tabs[tab].content}
115+
<div style={{ position: "absolute" }}>{children}</div>
116+
</ContentContainer>
117+
</BrowserContainer>
118+
</ThemeProvider>
119+
);
120+
};
121+
122+
export default ChromeBrowser;
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
import React from "react";
3+
import Example from "./Example";
4+
5+
const meta: Meta<typeof Example> = {
6+
title: "ArcBrowser",
7+
component: Example,
8+
};
9+
10+
export default meta;
11+
type Story = StoryObj<typeof Example>;
12+
13+
export const Default: Story = {
14+
args: {},
15+
};
16+
17+
export const MultipleTabs: Story = {
18+
args: {
19+
tabs: [
20+
{
21+
name: "Tab 1",
22+
link: "google.com",
23+
content: (
24+
<div
25+
style={{
26+
display: "flex",
27+
justifyContent: "center",
28+
alignItems: "center",
29+
width: "640px",
30+
height: "2000px",
31+
}}
32+
>
33+
Hello 1
34+
</div>
35+
),
36+
},
37+
{
38+
name: "Tab 2",
39+
link: "bing.com",
40+
content: (
41+
<div
42+
style={{
43+
display: "flex",
44+
justifyContent: "center",
45+
alignItems: "center",
46+
width: "400px",
47+
height: "200px",
48+
}}
49+
>
50+
Hello 2
51+
</div>
52+
),
53+
},
54+
{
55+
name: "Tab 3",
56+
link: "duckduckgo.com",
57+
content: (
58+
<div
59+
style={{
60+
display: "flex",
61+
justifyContent: "center",
62+
alignItems: "center",
63+
width: "90px",
64+
height: "280px",
65+
}}
66+
>
67+
Hello 3
68+
</div>
69+
),
70+
},
71+
],
72+
},
73+
};
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React, { FC } from "react";
2+
import BrowserProps from "../../types/BrowserProp";
3+
import ArcBrowser from "../ArcBrowser";
4+
5+
const Example: FC<BrowserProps> = ({
6+
theme,
7+
tabs,
8+
shadow,
9+
usecontentsize,
10+
leftIcons,
11+
rightIcons,
12+
children,
13+
}) => {
14+
const [tab, setTab] = React.useState(0);
15+
16+
return (
17+
<div
18+
style={{
19+
width: "100%",
20+
height: "600px",
21+
}}
22+
>
23+
<ArcBrowser
24+
theme={theme}
25+
tabs={tabs}
26+
tab={tab}
27+
setTab={setTab}
28+
usecontentsize={usecontentsize}
29+
shadow={shadow}
30+
leftIcons={leftIcons}
31+
rightIcons={rightIcons}
32+
>
33+
{children}
34+
</ArcBrowser>
35+
</div>
36+
);
37+
};
38+
39+
export default Example;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { render, screen } from "@testing-library/react";
2+
import React from "react";
3+
import { describe, expect, it } from "vitest";
4+
import ArcBrowser from "../ArcBrowser";
5+
6+
describe("ArcBrowser", () => {
7+
it("renders correctly", () => {
8+
render(<ArcBrowser />);
9+
10+
// Assuming the ArcBrowser component has a title or some identifiable text
11+
const browserElement = screen.getByText(/Hello/i);
12+
expect(browserElement).toBeInTheDocument();
13+
});
14+
});

src/components/ArcBrowser/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// components/ChromeBrowser/index.ts
2+
export { default as ChromeBrowser } from "./ChromeBrowser";

0 commit comments

Comments
 (0)