Skip to content
This repository was archived by the owner on May 15, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"publishConfig": {
"registry": "https://npm.pkg.github.com"
},
"version": "0.0.6",
"version": "0.0.7",
"description": "system.css theme wrapped for React",
"type": "module",
"main": "dist/index.cjs.js",
Expand Down
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export type * from "./button";
export * from "./dialog";
export type * from "./dialog";

export * from "./menubar";
export type * from "./menubar";

export * from "./modal";
export type * from "./modal";

Expand Down
13 changes: 13 additions & 0 deletions src/menubar/MenuBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from "react";
import Item from "./MenuBarItem";
import "@sakun/system.css";

export type MenuBarProps = {
children: React.ReactElement<typeof Item> | React.ReactElement<typeof Item>[];
};

const MenuBar: React.FC<MenuBarProps> = ({ children }) => {
return <ul role="menu-bar">{children}</ul>;
};

export default MenuBar;
47 changes: 47 additions & 0 deletions src/menubar/MenuBarItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react";
import MenuBarMenu from "./MenuBarMenu";
import "@sakun/system.css";
import styles from "../styles";

export type MenuBarItemProps = {
children?:
| React.ReactNode
| [React.ReactNode, React.ReactElement<typeof MenuBarMenu>];
onClick?: React.MouseEventHandler<HTMLLIElement>;
divider?: boolean;
};

const MenuBarItem: React.FC<MenuBarItemProps> = ({
onClick,
divider,
children,
}) => {
const ariaHasPopup =
React.Children.toArray(children).find((child) => {
// if the child is an object with the key 'type' and the type is MenuBarMenu then return true
if (
typeof child === "object" &&
child &&
"type" in child &&
child.type === MenuBarMenu
) {
return true;
} else {
return false;
}
}) !== undefined;

return (
<li
className={`${divider ? styles["divider"] : ""}`}
role="menu-item"
aria-haspopup={ariaHasPopup}
tabIndex={0}
onClick={onClick}
>
{children}
</li>
);
};

export default MenuBarItem;
13 changes: 13 additions & 0 deletions src/menubar/MenuBarMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from "react";
import Item from "./MenuBarItem";
import "@sakun/system.css";

export type MenuBarMenuProps = {
children: React.ReactElement<typeof Item> | React.ReactElement<typeof Item>[];
};

const MenuBarMenu: React.FC<MenuBarMenuProps> = ({ children }) => {
return <ul role="menu">{children}</ul>;
};

export default MenuBarMenu;
102 changes: 102 additions & 0 deletions src/menubar/__docs__/Example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React, { FC } from "react";
import MenuBar from "..";

export type ExampleProps = {};

const Example: FC<ExampleProps> = ({}) => {
return (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100%",
}}
>
<MenuBar>
<MenuBar.Item>
File
<MenuBar.Menu>
<MenuBar.Item>
<a href="#menu">Open</a>
</MenuBar.Item>
<MenuBar.Item>
<a href="#menu">Save</a>
</MenuBar.Item>
<MenuBar.Item>
<a href="#menu">Another</a>
</MenuBar.Item>
<MenuBar.Item divider>
<a href="#menu">Option</a>
</MenuBar.Item>
<MenuBar.Item>
<a href="#menu">These</a>
</MenuBar.Item>
<MenuBar.Item>
<a href="#menu">Are</a>
</MenuBar.Item>
<MenuBar.Item>
<a href="#menu">Separate</a>
</MenuBar.Item>
</MenuBar.Menu>
</MenuBar.Item>
<MenuBar.Item>
<a href="https://google.com" target="_blank">
Googz
</a>
</MenuBar.Item>
<MenuBar.Item>
More Stuff
<MenuBar.Menu>
<MenuBar.Item>
<a href="#menu">Action</a>
</MenuBar.Item>
</MenuBar.Menu>
</MenuBar.Item>
</MenuBar>
</div>
);
};

// const Example = () => {
// return (
// <ul role="menu-bar">
// <li role="menu-item" tabindex="0" aria-haspopup="true">
// File
// <ul role="menu">
// <li role="menu-item"><a href="#menu">Action</a></li>
// <li role="menu-item"><a href="#menu">Another Action</a></li>
// <li role="menu-item" class="divider"><a href="#menu">Something else here</a></li>
// <li role="menu-item"><a href="https://twitter.com/sakofchit">sakun's twitter</a></li>
// </ul>
// </li>
// <li role="menu-item" tabindex="0" aria-haspopup="true">
// Edit
// <ul role="menu">
// <li role="menu-item"><a href="#menu">Action</a></li>
// <li role="menu-item"><a href="#menu">Another Action</a></li>
// <li role="menu-item" class="divider"><a href="#menu">Something else here</a></li>
// <li role="menu-item"><a href="https://sakun.co">sakun's projects</a></li>
// </ul>
// </li>
// <li role="menu-item" tabindex="0" aria-haspopup="true">
// View
// <ul role="menu">
// <li role="menu-item"><a href="#menu">Action</a></li>
// <li role="menu-item"><a href="#menu">Another Action</a></li>
// <li role="menu-item"><a href="#menu">Something else here</a></li>
// </ul>
// </li>
// <li role="menu-item" tabindex="0" aria-haspopup="true">
// Special
// <ul role="menu">
// <li role="menu-item"><a href="#menu">You</a></li>
// <li role="menu-item"><a href="#menu">Get the</a></li>
// <li role="menu-item"><a href="#menu">Idea</a></li>
// </ul>
// </li>
// </ul>
// );
// }

export default Example;
15 changes: 15 additions & 0 deletions src/menubar/__docs__/MenuBar.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { Meta, StoryObj } from "@storybook/react";
import Example from "./Example";
import MenuBar from "..";

const meta: Meta<typeof Example> = {
title: "MenuBar",
component: Example,
};

export default meta;
type Story = StoryObj<typeof Example>;

export const Primary: Story = {
args: {},
};
19 changes: 19 additions & 0 deletions src/menubar/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import MenuBarParent from "./MenuBar";
export type { MenuBarProps } from "./MenuBar";

import Menu from "./MenuBarMenu";
export type { MenuBarMenuProps } from "./MenuBarMenu";

import Item from "./MenuBarItem";
export type { MenuBarItemProps } from "./MenuBarItem";

type MenuBarNamespace = typeof MenuBarParent & {
Item: typeof Item;
Menu: typeof Menu;
};

const MenuBar = MenuBarParent as MenuBarNamespace;
MenuBar.Item = Item;
MenuBar.Menu = Menu;

export default MenuBar;