From d519427f6bf88b71ea470c54a4be8994616b34bd Mon Sep 17 00:00:00 2001 From: drl990114 Date: Mon, 4 Nov 2024 21:22:12 +0800 Subject: [PATCH] feat: support menu divider --- package.json | 4 ++-- src/Menu/demo/basic.tsx | 7 +++++-- src/Menu/index.tsx | 20 ++++++++++++++++++-- src/Menu/styles.ts | 27 +++++++++++++++++---------- src/Theme/dark.ts | 1 + src/Theme/light.ts | 1 + yarn.lock | 8 ++++---- 7 files changed, 48 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 362b80f..51fd4bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zens", - "version": "0.0.36", + "version": "0.0.38", "description": "MarkFlowy's ui component library.", "keywords": [], "homepage": "https://github.com/drl990114/zens#readme", @@ -73,7 +73,7 @@ "react-dom": "^18.2.0", "react-spinners": "^0.13.8", "sonner": "^1.4.0", - "styled-components": "^6.1.11", + "styled-components": "^6.1.13", "stylis": "^4.0.0" }, "devDependencies": { diff --git a/src/Menu/demo/basic.tsx b/src/Menu/demo/basic.tsx index 73932f2..f3dbabe 100644 --- a/src/Menu/demo/basic.tsx +++ b/src/Menu/demo/basic.tsx @@ -1,7 +1,7 @@ -import { Menu } from 'zens'; +import { Menu, MenuItemData } from 'zens'; export default () => { - const menuData = [ + const menuData: MenuItemData[] = [ { label: 'menu1', value: 'menu1', @@ -10,6 +10,9 @@ export default () => { console.log('menu1'); }, }, + { + type: 'divider', + }, { label: 'menu2', value: 'menu2', diff --git a/src/Menu/index.tsx b/src/Menu/index.tsx index 093eb76..bd1d344 100644 --- a/src/Menu/index.tsx +++ b/src/Menu/index.tsx @@ -1,13 +1,17 @@ import type { MenuProps as AkMenuProps } from '@ariakit/react'; import { MenuButton, MenuButtonArrow, MenuProvider, useMenuStore } from '@ariakit/react'; + +import { MenuItem, MenuItemCheckIcon, MenuWrapper, MenuSeparator } from './styles'; + import Button from '../Button'; -import { MenuItem, MenuItemCheckIcon, MenuWrapper } from './styles'; export { MenuProvider } from '@ariakit/react'; export * from './styles'; export { useMenuStore }; -export type MenuItemData = { +export type MenuItemData = MenuGroupType | MenuDividerType; + +export type MenuGroupType = { label: string; keybinding?: string; value: string; @@ -16,12 +20,20 @@ export type MenuItemData = { children?: MenuItemData[]; }; +export type MenuDividerType = { + type: 'divider'; +}; + interface MenuProps extends AkMenuProps { menuButtonProps?: React.ComponentProps; triggerBtnClass?: string; items: MenuItemData[]; } +export const isDivider = (item: MenuItemData): item is MenuDividerType => { + return (item as MenuDividerType)?.type === 'divider'; +} + const Menu = (props: MenuProps) => { const { open, @@ -36,6 +48,10 @@ const Menu = (props: MenuProps) => { const renderItems = (menuItems: MenuItemData[]) => { return menuItems.map((item) => { + if (isDivider(item)) { + return + } + const key = item.value; if (item.children && item.children?.length > 0) { diff --git a/src/Menu/styles.ts b/src/Menu/styles.ts index a0dfe31..37679d8 100644 --- a/src/Menu/styles.ts +++ b/src/Menu/styles.ts @@ -1,5 +1,7 @@ -import * as Ariakit from '@ariakit/react'; import styled from 'styled-components'; + +import * as Ariakit from '@ariakit/react'; + import { darken } from '../Theme'; export const MenuItem = styled(Ariakit.MenuItem)` @@ -48,16 +50,21 @@ export const MenuWrapper = styled(Ariakit.Menu)` outline: none; overflow: visible; - .separator { - width: 100%; - height: 0px; - margin-top: 0.5rem; - margin-bottom: 0.5rem; - border-color: ${(props) => props.theme.borderColor}; - border-top-width: 1px; - } - .menu-label { flex: 1 1 0%; } `; + +export const MenuSeparator = styled(Ariakit.MenuSeparator)` + margin-top: 0.5rem; + margin-bottom: 0.5rem; + height: 0px; + width: 100%; + background-color: ${(props) => props.theme.contextMenuBgColor}; + border-top-width: 1px; + border-bottom: none; + border-right: none; + border-left: none; + border-color: ${(props) => props.theme.contextMenuSeparatorColor}; + color: ${(props) => props.theme.contextMenuSeparatorColor}; +`; diff --git a/src/Theme/dark.ts b/src/Theme/dark.ts index 296cbbd..b9c89b0 100644 --- a/src/Theme/dark.ts +++ b/src/Theme/dark.ts @@ -14,6 +14,7 @@ export const styledDarkTheme = { // components contextMenuBgColor: '#18191B', contextMenuBgColorHover: '#2D3134', + contextMenuSeparatorColor: '#919191', buttonBgColor: '#21262c', tooltipBgColor: '#43414A', dialogBgColor: '#151515', diff --git a/src/Theme/light.ts b/src/Theme/light.ts index fa0a01b..e3da9b8 100644 --- a/src/Theme/light.ts +++ b/src/Theme/light.ts @@ -14,6 +14,7 @@ export const styledLightTheme = { // components contextMenuBgColor: '#FFFFFF', contextMenuBgColorHover: '#E8E8EC', + contextMenuSeparatorColor: '#ffffff66', buttonBgColor: '#f6f7f9', tooltipBgColor: '#d7d7dc', dialogBgColor: '#f6f7f9', diff --git a/yarn.lock b/yarn.lock index 39a2f04..9bbfc3c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17761,10 +17761,10 @@ style-to-object@^0.4.1: dependencies: inline-style-parser "0.1.1" -styled-components@^6.1.11: - version "6.1.11" - resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-6.1.11.tgz#01948e5195bf1d39e57e0a85b41958c80e40cfb8" - integrity sha512-Ui0jXPzbp1phYij90h12ksljKGqF8ncGx+pjrNPsSPhbUUjWT2tD1FwGo2LF6USCnbrsIhNngDfodhxbegfEOA== +styled-components@^6.1.13: + version "6.1.13" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-6.1.13.tgz#2d777750b773b31469bd79df754a32479e9f475e" + integrity sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw== dependencies: "@emotion/is-prop-valid" "1.2.2" "@emotion/unitless" "0.8.1"