Browse Source

完善布局调整

main
dark 3 months ago
parent
commit
96e9dac0ca
  1. 67
      src/hooks/useScrollMask.ts
  2. 47
      src/hooks/useScrollStyle.ts
  3. 5
      src/layout/TwoColPageLayout.tsx
  4. 4
      src/layout/style.ts
  5. 2
      src/pages/system/menus/index.tsx
  6. 12
      src/pages/system/menus/style.ts

67
src/hooks/useScrollMask.ts

@ -0,0 +1,67 @@
import { useEffect } from 'react'
type Ref = { current: Element }
const useScrollMask = (ref: Ref | string) => {
useEffect(() => {
let element: Ref
if (typeof ref === 'string') {
element = {
current: document.querySelector(ref)!
}
if (!element.current) return
} else {
element = ref as Ref
}
if (!element.current) return
const handleScroll = () => {
const { scrollTop, scrollHeight, clientHeight } = element.current
const atTop = scrollTop === 0
const atBottom = scrollTop + clientHeight === scrollHeight
if (atTop && atBottom) {
element.current.setAttribute('data-top-bottom-scroll', 'true')
element.current.removeAttribute('data-top-scroll')
element.current.removeAttribute('data-bottom-scroll')
} else if (atTop) {
element.current.setAttribute('data-top-scroll', 'true')
element.current.removeAttribute('data-bottom-scroll')
element.current.removeAttribute('data-top-bottom-scroll')
} else if (atBottom) {
element.current.setAttribute('data-bottom-scroll', 'true')
element.current.removeAttribute('data-top-scroll')
element.current.removeAttribute('data-top-bottom-scroll')
} else {
element.current.setAttribute('data-top-bottom-scroll', 'true')
element.current.removeAttribute('data-bottom-scroll')
element.current.removeAttribute('data-top-scroll')
}
}
const checkScroll = () => {
const hasVerticalScrollbar = element.current.scrollHeight > element.current.clientHeight
if (hasVerticalScrollbar) {
element.current.classList.add('scroll-mask')
} else {
element.current.classList.remove('scroll-mask')
}
handleScroll() // Initial check
}
element.current.addEventListener('scroll', handleScroll)
window.addEventListener('resize', checkScroll)
checkScroll()
return () => {
element.current.removeEventListener('scroll', handleScroll)
window.removeEventListener('resize', checkScroll)
}
}, [ ref ])
}
export default useScrollMask

47
src/hooks/useScrollStyle.ts

@ -114,10 +114,57 @@ export const useScrollStyle = () => {
${darkScrollbar}
`;
const scrollbar1 = css `
/* 通用的 overflow 和 padding */
.scroll-mask {
--scroll-shadow-size: 40px;
overflow-y: auto;
margin-right: -1.5rem; /* -mr-6 */
height: 100%; /* h-full */
max-height: 100%; /* max-h-full */
padding-top: 1.5rem; /* py-6 */
padding-bottom: 1.5rem; /* py-6 */
padding-right: 1.5rem; /* pr-6 */
}
/* 顶部遮罩效果 */
.scroll-mask-top {
mask-image: linear-gradient(0deg, #000 calc(100% - var(--scroll-shadow-size)), transparent);
}
/* 底部遮罩效果 */
.scroll-mask-bottom {
mask-image: linear-gradient(180deg, #000 calc(100% - var(--scroll-shadow-size)), transparent);
}
/* 顶部和底部遮罩效果 */
.scroll-mask-top-bottom {
mask-image: linear-gradient(#000, #000, transparent 0, #000 var(--scroll-shadow-size), #000 calc(100% - var(--scroll-shadow-size)), transparent);
}
/* 根据滚动状态动态应用遮罩效果 */
[data-top-scroll="true"] {
mask-image: linear-gradient(0deg, #000 calc(100% - var(--scroll-shadow-size)), transparent);
}
[data-bottom-scroll="true"] {
mask-image: linear-gradient(180deg, #000 calc(100% - var(--scroll-shadow-size)), transparent);
}
[data-top-bottom-scroll="true"] {
mask-image: linear-gradient(#000, #000, transparent 0, #000 var(--scroll-shadow-size), #000 calc(100% - var(--scroll-shadow-size)), transparent);
}
`
return {
scrollbarBackground,
scrollbar,
darkScrollbarBackground,
darkScrollbar,
scrollbar1,
}
}

5
src/layout/TwoColPageLayout.tsx

@ -9,14 +9,15 @@ interface ITreePageLayoutProps {
draggableProps?: DraggablePanelProps
pageProps?: PageContainerProps
leftPanel?: React.ReactNode
className?: string
}
export const TwoColPageLayout: React.FC<ITreePageLayoutProps> = (props) => {
export const TwoColPageLayout: React.FC<ITreePageLayoutProps> = ({ className, ...props }) => {
const { styles, cx } = useStyle({ className: 'two-col' })
return (
<PageContainer
breadcrumbRender={false} title={false}
className={cx( styles.pageCard)}
className={cx(styles.pageCard, styles.layoutTable, className)}
{...props.pageProps}
>
<Flexbox horizontal className={styles.authHeight}>

4
src/layout/style.ts

@ -48,8 +48,8 @@ export const useStyle = createStyles(({ token, css, cx, prefixCls }, props: any)
.ant-pro-card-body{
padding-block-start: 0;
overflow: auto;
height: calc(100vh - 100px);
min-height: calc(100vh - 100px);
height: calc(100vh - 110px);
min-height: calc(100vh - 110px);
${scrollbarBackground}
}

2
src/pages/system/menus/index.tsx

@ -24,6 +24,7 @@ const Menus = () => {
const [ currentMenu, setMenuData ] = useAtom<MenuItem>(selectedMenuAtom) ?? {}
const menuInputRef = useRef<InputRef | undefined>(undefined)
useEffect(() => {
if (isError) {
@ -42,6 +43,7 @@ const Menus = () => {
return (
<TwoColPageLayout
className={styles.container}
leftPanel={<>
<ProCard title={t('system.menus.title', '菜单')}
extra={

12
src/pages/system/menus/style.ts

@ -3,12 +3,18 @@ import { useScrollStyle } from '@/hooks/useScrollStyle'
export const useStyle = createStyles(({ token, css, cx, prefixCls }) => {
const prefix = `${prefixCls}-${token?.proPrefix}-menu-page`
const { scrollbarBackground } = useScrollStyle()
const { scrollbarBackground, scrollbar1 } = useScrollStyle()
const container = css`
${scrollbar1}
`
const box = css`
flex: 1;
background: ${token.colorBgContainer};
`
const emptyForm = css`
`
@ -33,7 +39,7 @@ export const useStyle = createStyles(({ token, css, cx, prefixCls }) => {
const formButtons = css`
width: 500px;
.ant-pro-card-body {
overflow: hidden;
//overflow: hidden;
}
`
@ -81,7 +87,7 @@ export const useStyle = createStyles(({ token, css, cx, prefixCls }) => {
`
return {
container: cx(prefix),
container: cx(prefix, container),
box,
emptyForm,
tree,

Loading…
Cancel
Save