Skip to content

Commit 032b679

Browse files
committed
feat: contents menu style
1 parent 273fcde commit 032b679

File tree

10 files changed

+85
-190
lines changed

10 files changed

+85
-190
lines changed

packages/nextra-editor/css/styles.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ html {
1919
'calt' 1,
2020
'ss01' 1;
2121
-webkit-tap-highlight-color: transparent;
22-
@apply nx-overflow-hidden;
22+
/* @apply nx-overflow-hidden; */
2323
}
2424

2525
body {

packages/nextra-editor/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@
106106
"@types/react": "^18.2.21",
107107
"@types/react-dom": "^18.2.7",
108108
"@types/title": "^3.4.3",
109-
"@typescript-eslint/eslint-plugin": "^7.5.0",
110-
"@typescript-eslint/parser": "^7.6.0",
109+
"@typescript-eslint/eslint-plugin": "^7.11.0",
110+
"@typescript-eslint/parser": "^7.11.0",
111111
"@vitejs/plugin-react": "^4.1.0",
112112
"concurrently": "^8.0.0",
113113
"eslint": "^9.5.0",

packages/nextra-editor/src/components/sidebar/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ export function Sidebar({
115115

116116
return (
117117
<>
118+
<div id="menu-root"></div>
118119
{includePlaceholder && asPopover ? (
119120
<div className="nx-h-0 nx-w-80 nx-shrink-0 max-xl:nx-hidden" />
120121
) : null}
@@ -132,8 +133,7 @@ export function Sidebar({
132133
'nextra-sidebar-container nx-flex nx-flex-col',
133134
'motion-reduce:nx-transform-none md:nx-shrink-0',
134135
'nx-transform-gpu nx-transition-all nx-ease-in-out',
135-
'print:nx-hidden',
136-
'nx-relative nx-select-none nx-overflow-hidden',
136+
'nx-relative nx-select-none',
137137
showSidebar ? 'md:nx-w-80' : 'md:nx-w-20',
138138
asPopover ? 'md:nx-hidden' : 'md:nx-relative md:nx-top-0 md:nx-self-start',
139139
menu

packages/nextra-editor/src/components/sidebar/sidebar-controller/control-menu.tsx

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,42 @@
1-
import useOutsideClick from '@/hooks/use-outside-click'
1+
import { EditIcon } from '@/nextra/icons/edit'
2+
import { TrashIcon } from '@/nextra/icons/trash'
23
import cn from 'clsx'
3-
import { forwardRef, RefObject } from 'react'
4+
import { forwardRef } from 'react'
45

56
type Props = {
67
isOpen: boolean
8+
position: { top: number; left: number }
79
}
810

911
const style = {
10-
list: cn('nx-w-full nx-p-3 hover:nx-bg-gray-100'),
12+
list: cn(
13+
'nx-w-full nx-flex nx-items-center nx-p-3 hover:nx-bg-gray-100 dark:hover:nx-bg-neutral-700',
14+
'nx-cursor-pointer nx-select-none',
15+
),
16+
svg: cn('nx-mr-2'),
1117
}
1218

13-
const ControlMenu = forwardRef<HTMLDivElement, Props>(({ isOpen }, ref) => {
19+
const ControlMenu = forwardRef<HTMLDivElement, Props>(({ isOpen, position }, ref) => {
1420
return (
1521
<div
1622
ref={ref}
1723
className={cn(
18-
'nx-absolute nx-right-0 nx-top-0 nx-z-10 nx-py-2',
19-
'nx-bg-white',
20-
isOpen ? 'nx-visible' : 'nx-invisible',
24+
'nx-absolute nx-z-20 nx-w-[150px] nx-rounded-md nx-py-2 nx-shadow-lg',
25+
'nx-text-sm',
26+
'nx-bg-white nx-text-gray-600',
27+
'dark:nx-bg-neutral-800 dark:nx-text-gray-300',
2128
)}
29+
style={{ top: position.top, left: 280, display: isOpen ? 'block' : 'none' }}
2230
>
2331
<ul>
24-
<li className={style.list}>이름 바꾸기</li>
25-
<li className={style.list}>삭제</li>
32+
<li className={style.list}>
33+
<EditIcon className={style.svg} />
34+
<span>이름 바꾸기</span>
35+
</li>
36+
<li className={style.list}>
37+
<TrashIcon className={style.svg} />
38+
<span>삭제</span>
39+
</li>
2640
</ul>
2741
</div>
2842
)

packages/nextra-editor/src/components/sidebar/sortable-tree/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ function SortableTree({ items, sidebarRef, showSidebar, onItemsChanged }: Props)
308308
>
309309
<div
310310
className={cn(
311-
'nx-overflow-y-auto nx-overflow-x-hidden',
311+
'nx-overflow-y-auto',
312312
'nx-grow nx-px-4 md:nx-h-[calc(100vh-var(--nextra-navbar-height)-var(--nextra-menu-height))]',
313313
'nx-pb-4',
314314
showSidebar ? 'nextra-scrollbar' : 'no-scrollbar',

packages/nextra-editor/src/components/sidebar/sortable-tree/sortable-item.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CSSProperties, forwardRef, MouseEventHandler, useEffect, useState } from 'react'
1+
import { CSSProperties, forwardRef, useEffect, useState } from 'react'
22
import cn from 'clsx'
33
import { ActionType, useSidebar } from '@/contexts/sidebar'
44
import { useRouter } from 'next/router'
@@ -10,10 +10,12 @@ import type { SortableItemProps } from './types'
1010
import ControlInput from '../sidebar-controller/control-input'
1111
import ControlMenu from '../sidebar-controller/control-menu'
1212
import useOutsideClick from '@/hooks/use-outside-click'
13+
import { createPortal } from 'react-dom'
1314

1415
export const SortableItem = forwardRef<HTMLDivElement, SortableItemProps>((props, ref) => {
1516
const { isDragging, overItem, setOverItem } = useDndTree()
1617
const { focusedItem, setFocusedItem, showMenuId, setShowMenuId } = useSidebar()
18+
const [mousePosition, setMousePosition] = useState({ top: 0, left: 0 })
1719
const [isEdit, setIsEdit] = useState<boolean>(false)
1820

1921
const router = useRouter()
@@ -32,7 +34,6 @@ export const SortableItem = forwardRef<HTMLDivElement, SortableItemProps>((props
3234
clone,
3335
isOver,
3436
transform,
35-
disabled,
3637
} = props
3738

3839
const isControlAction = ['newPage', 'newFolder', 'newSeparator'].includes(item.type)
@@ -53,6 +54,7 @@ export const SortableItem = forwardRef<HTMLDivElement, SortableItemProps>((props
5354
if (showMenuId === item.id) {
5455
setShowMenuId(null)
5556
} else {
57+
setMousePosition({ top: e.clientY, left: e.clientX })
5658
setShowMenuId(item.id)
5759
}
5860
}
@@ -92,7 +94,10 @@ export const SortableItem = forwardRef<HTMLDivElement, SortableItemProps>((props
9294
className={cn('nx-relative')}
9395
onContextMenu={onOpenMenu}
9496
>
95-
<ControlMenu isOpen={showMenuId === item.id} ref={menuRef} />
97+
{createPortal(
98+
<ControlMenu ref={menuRef} isOpen={showMenuId === item.id} position={mousePosition} />,
99+
document.getElementById('menu-root')!,
100+
)}
96101
<div
97102
ref={ref}
98103
{...handleProps}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { ComponentProps, ReactElement } from 'react'
2+
3+
export function EditIcon(props: ComponentProps<'svg'>): ReactElement {
4+
return (
5+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16" {...props}>
6+
<path
7+
fill="currentColor"
8+
d="M13.23 1h-1.46L3.52 9.25l-.16.22L1 13.59L2.41 15l4.12-2.36l.22-.16L15 4.23V2.77zM2.41 13.59l1.51-3l1.45 1.45zm3.83-2.06L4.47 9.76l8-8l1.77 1.77z"
9+
/>
10+
</svg>
11+
)
12+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { ComponentProps, ReactElement } from 'react'
2+
3+
export function TrashIcon(props: ComponentProps<'svg'>): ReactElement {
4+
return (
5+
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16" {...props}>
6+
<path
7+
fill="currentColor"
8+
fillRule="evenodd"
9+
d="M10 3h3v1h-1v9l-1 1H4l-1-1V4H2V3h3V2a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1zM9 2H6v1h3zM4 13h7V4H4zm2-8H5v7h1zm1 0h1v7H7zm2 0h1v7H9z"
10+
clipRule="evenodd"
11+
/>
12+
</svg>
13+
)
14+
}

packages/nextra-editor/style.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)