-
-
Notifications
You must be signed in to change notification settings - Fork 163
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ feat: add ActionIconGroup component
- Loading branch information
1 parent
fb15ef5
commit eea5bff
Showing
18 changed files
with
813 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { | ||
ActionIconGroup, | ||
ActionIconGroupProps, | ||
StroyBook, | ||
useControls, | ||
useCreateStore, | ||
} from '@lobehub/ui'; | ||
import { Copy, RotateCw } from 'lucide-react'; | ||
|
||
const items: ActionIconGroupProps['items'] = [ | ||
{ | ||
icon: Copy, | ||
title: 'Copy', | ||
onClick: () => console.log('click Copy'), | ||
}, | ||
{ | ||
icon: RotateCw, | ||
title: 'Regenerate', | ||
onClick: () => console.log('click Regenerate'), | ||
}, | ||
]; | ||
|
||
export default () => { | ||
const store = useCreateStore(); | ||
const control: ActionIconGroupProps | any = useControls( | ||
{ | ||
type: { | ||
value: 'block', | ||
options: ['ghost', 'block', 'pure'], | ||
}, | ||
direction: { | ||
value: 'row', | ||
options: ['row', 'column'], | ||
}, | ||
spotlight: true, | ||
}, | ||
{ store }, | ||
); | ||
|
||
return ( | ||
<StroyBook levaStore={store}> | ||
<ActionIconGroup items={items} {...control} /> | ||
</StroyBook> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
--- | ||
nav: Components | ||
group: Common | ||
title: ActionIconGroup | ||
description: ActionIconGroup is a component used to render multi buttons | ||
--- | ||
|
||
## Default | ||
|
||
<code src="./demos/index.tsx" nopadding></code> | ||
|
||
## APIs | ||
|
||
<API></API> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { ActionIcon, ActionIconProps, Spotlight } from '@lobehub/ui'; | ||
import { memo } from 'react'; | ||
|
||
import { DivProps } from '@/types'; | ||
|
||
import { useStyles } from './style'; | ||
|
||
export interface ActionIconGroupProps extends DivProps { | ||
direction?: 'row' | 'column'; | ||
items: ActionIconProps[]; | ||
/** | ||
* @description The position of the tooltip relative to the target | ||
* @enum ["top","left","right","bottom","topLeft","topRight","bottomLeft","bottomRight","leftTop","leftBottom","rightTop","rightBottom"] | ||
*/ | ||
placement?: ActionIconProps['placement']; | ||
/** | ||
* @description Whether add spotlight background | ||
* @default true | ||
*/ | ||
spotlight?: boolean; | ||
/** | ||
* @description The type of the group | ||
* @default 'block' | ||
*/ | ||
type?: 'ghost' | 'block' | 'pure'; | ||
} | ||
|
||
const ActionIconGroup = memo<ActionIconGroupProps>( | ||
({ type = 'block', items, placement, spotlight = true, direction = 'row', ...props }) => { | ||
const { styles } = useStyles({ direction, type }); | ||
|
||
return ( | ||
<div className={styles.container} {...props}> | ||
{spotlight && <Spotlight />} | ||
{items.map((item, index) => ( | ||
<ActionIcon | ||
key={index} | ||
placement={placement || (direction === 'column' ? 'right' : 'top')} | ||
size="small" | ||
{...item} | ||
/> | ||
))} | ||
</div> | ||
); | ||
}, | ||
); | ||
|
||
export default ActionIconGroup; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { createStyles } from 'antd-style'; | ||
|
||
export const useStyles = createStyles( | ||
( | ||
{ css, token, stylish, cx }, | ||
{ direction, type }: { direction: 'row' | 'column'; type: 'ghost' | 'block' | 'pure' }, | ||
) => { | ||
const typeStylish = css` | ||
background-color: ${type === 'block' ? token.colorFillTertiary : 'transparent'}; | ||
border: 1px solid ${type === 'block' ? 'transparent' : token.colorBorder}; | ||
`; | ||
|
||
return { | ||
container: cx( | ||
type !== 'pure' && typeStylish, | ||
stylish.blur, | ||
css` | ||
position: relative; | ||
display: flex; | ||
flex-direction: ${direction}; | ||
padding: 2px; | ||
border-radius: ${token.borderRadius}px; | ||
`, | ||
), | ||
}; | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
const strokeWidth = 2.2; | ||
const iconSize = '13px'; | ||
|
||
export const CommandIcon = () => ( | ||
<svg | ||
fill="none" | ||
height={iconSize} | ||
stroke="currentColor" | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
strokeWidth={strokeWidth} | ||
viewBox="0 0 24 24" | ||
width={iconSize} | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path d="M18 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3H6a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3V6a3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3h12a3 3 0 0 0 3-3 3 3 0 0 0-3-3z"></path> | ||
</svg> | ||
); | ||
export const ControlIcon = () => ( | ||
<svg | ||
className="lucide lucide-chevron-up" | ||
fill="none" | ||
height={iconSize} | ||
stroke="currentColor" | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
strokeWidth={strokeWidth} | ||
viewBox="0 0 24 24" | ||
width={iconSize} | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<polyline points="18 15 12 9 6 15"></polyline> | ||
</svg> | ||
); | ||
export const ShiftIcon = () => ( | ||
<svg | ||
className="lucide lucide-chevron-up" | ||
fill="none" | ||
height={iconSize} | ||
stroke="currentColor" | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
strokeWidth={strokeWidth} | ||
viewBox="0 0 24 24" | ||
width={iconSize} | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path d="M9 18v-6H5l7-7 7 7h-4v6H9z"></path> | ||
</svg> | ||
); | ||
|
||
export const AltIcon = () => ( | ||
<svg | ||
className="lucide lucide-chevron-up" | ||
fill="none" | ||
height={iconSize} | ||
stroke="currentColor" | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
strokeWidth={strokeWidth} | ||
viewBox="0 0 24 24" | ||
width={iconSize} | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path d="M3 3h6l6 18h6"></path> | ||
<path d="M14 3h7"></path> | ||
</svg> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { ChevronRightIcon } from 'lucide-react'; | ||
import { ReactNode, forwardRef } from 'react'; | ||
import { Flexbox } from 'react-layout-kit'; | ||
|
||
import { AltIcon, CommandIcon, ControlIcon, ShiftIcon } from './icons'; | ||
import { useStyles } from './style'; | ||
|
||
const KEYBOARD_ICON_MAP: Record<string, any> = { | ||
meta: <CommandIcon />, | ||
control: <ControlIcon />, | ||
|
||
shift: <ShiftIcon />, | ||
alt: <AltIcon />, | ||
enter: '↵', | ||
}; | ||
|
||
const CODE_MAP: Record<string, 'meta' | 'control' | 'shift' | 'alt'> = { | ||
meta: 'meta', | ||
command: 'meta', | ||
cmd: 'meta', | ||
ctl: 'control', | ||
control: 'control', | ||
shift: 'shift', | ||
alt: 'alt', | ||
}; | ||
|
||
interface MenuItemProps { | ||
active?: boolean; | ||
disabled?: boolean; | ||
icon?: ReactNode; | ||
label: ReactNode; | ||
nested?: boolean; | ||
selected?: boolean; | ||
shortcut?: string[]; | ||
} | ||
|
||
const MenuItem = forwardRef<HTMLButtonElement, MenuItemProps>( | ||
({ label, icon, disabled, nested, shortcut, active, selected, ...props }, ref) => { | ||
const { styles, cx } = useStyles(); | ||
|
||
return ( | ||
<button | ||
type={'button'} | ||
{...props} | ||
className={cx(styles.item, { | ||
[styles.selected]: selected, | ||
[styles.active]: active, | ||
})} | ||
disabled={disabled} | ||
ref={ref} | ||
role="menuitem" | ||
> | ||
<Flexbox gap={8} horizontal> | ||
{icon && <span>{icon}</span>} | ||
{label} | ||
</Flexbox> | ||
{nested ? ( | ||
<span aria-hidden> | ||
<ChevronRightIcon className={styles.arrow} /> | ||
</span> | ||
) : shortcut ? ( | ||
<Flexbox align={'center'} horizontal> | ||
{shortcut.map((c) => { | ||
const code = CODE_MAP[c.toLowerCase()]; | ||
|
||
return ( | ||
<kbd className={styles.kbd} key={c}> | ||
{code ? KEYBOARD_ICON_MAP[code] : c.toUpperCase()} | ||
</kbd> | ||
); | ||
})} | ||
</Flexbox> | ||
) : null} | ||
</button> | ||
); | ||
}, | ||
); | ||
|
||
export default MenuItem; |
Oops, something went wrong.
eea5bff
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
lobe-ui – ./
lobe-ui-lobehub.vercel.app
lobe-ui.vercel.app
ui.lobehub.com
lobe-ui-git-master-lobehub.vercel.app