feat(app): add mobile responsive

This commit is contained in:
chenos 2021-01-05 12:50:28 +08:00
parent 63033d57c4
commit 31edb3a1fe
13 changed files with 136 additions and 20 deletions

View File

@ -1,6 +1,14 @@
import './css_browser_selector';
import { RequestConfig, request as umiRequest, history } from 'umi';
import { configResponsive } from 'ahooks';
configResponsive({
small: 0,
middle: 800,
large: 1200,
});
export const request: RequestConfig = {
prefix: process.env.API,
errorConfig: {

View File

@ -55,6 +55,7 @@ function DrawerSelectComponent(props) {
onChange(data.value);
setSelectedRowKeys([data.value]);
} else {
console.log(data);
onChange(null);
setSelectedRowKeys([]);
}
@ -65,6 +66,7 @@ function DrawerSelectComponent(props) {
></Select>
<Drawer
width={'40%'}
className={'noco-drawer'}
title={'关联数据'}
visible={visible}
bodyStyle={{padding: 0}}

View File

@ -1,4 +1,5 @@
import { connect } from '@formily/react-schema-renderer'
import React from 'react';
import { Input as AntdInput } from 'antd'
import { acceptEnum, mapStyledProps, mapTextComponent } from '../shared'
@ -10,6 +11,6 @@ export const Input = connect<'TextArea'>({
Input.TextArea = connect({
getProps: mapStyledProps,
getComponent: mapTextComponent
})(acceptEnum(AntdInput.TextArea))
})(acceptEnum((props) => <AntdInput.TextArea autoSize={{minRows: 2}} {...props}/>))
export default Input

View File

@ -48,6 +48,7 @@ export default forwardRef((props: any, ref) => {
{...props}
destroyOnClose
visible={visible}
className={'noco-drawer'}
width={'40%'}
onClose={() => {
setVisible(false);

View File

@ -11,3 +11,16 @@
padding-right: 20px;
}
}
@media only screen and (max-width: 800px) {
.avatar-dropdown-wrapper {
bottom: 0;
left: 0;
right: auto;
width: 100%;
.dropdown-link {
display: block;
padding: 10px 20px;
}
}
}

View File

@ -37,6 +37,13 @@
margin: 16px;
}
@media only screen and (max-width: 800px) {
.collection-content {
margin: 0;
margin-top: 1px;
}
}
// .ant-page-header.has-footer {
// padding-top: 50px;
// }

View File

@ -1,29 +1,51 @@
import React, { useState } from 'react';
import { Layout, Breadcrumb } from 'antd';
import { Layout, Breadcrumb, Drawer } from 'antd';
import { Link } from 'umi';
import './style.less';
import Menu from '@/components/menu';
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons';
import { useLocalStorageState } from 'ahooks';
import { useResponsive } from 'ahooks';
export function SideMenuLayout(props: any) {
const { menu = [], id } = props.page;
const [visible, setVisible] = useState(false);
// console.log(menu);
const [collapsed, setCollapsed] = useLocalStorageState(`nocobase-menu-collapsed-${id}`, false);
const responsive = useResponsive();
const isMobile = responsive.small && !responsive.middle && !responsive.large;
return (
<Layout style={{height: 'calc(100vh - 48px)'}}>
<Layout.Sider className={`nb-sider${collapsed ? ' collapsed' : ''}`} theme={'light'}>
{!isMobile && <Layout.Sider className={`nb-sider${collapsed ? ' collapsed' : ''}`} theme={'light'}>
<Menu items={menu} mode={'inline'}/>
<div onClick={() => {
setCollapsed(!collapsed);
setVisible(true);
}} className={'menu-toggle'}>
{React.createElement(collapsed ? MenuUnfoldOutlined : MenuFoldOutlined, {
style: { fontSize: 16 },
})}
</div>
</Layout.Sider>
</Layout.Sider>}
<Layout.Content>
{props.children}
{isMobile && <Drawer visible={visible} onClose={() => {
setCollapsed(!collapsed);
setVisible(false);
}} placement={'left'} closable={false} bodyStyle={{padding: 0}}>
<Menu onSelect={() => {
setCollapsed(false);
setVisible(false);
}} items={menu} mode={'inline'}/>
</Drawer>}
{isMobile && <div onClick={() => {
setCollapsed(!collapsed);
setVisible(true);
}} className={'menu-toggle'}>
{React.createElement(collapsed ? MenuUnfoldOutlined : MenuFoldOutlined, {
style: { fontSize: 16 },
})}
</div>}
</Layout.Content>
</Layout>
);

View File

@ -9,11 +9,13 @@
.ant-menu-light {
border-right-color: transparent !important;
}
}
.menu-toggle {
position: fixed;
bottom: 12px;
left: 12px;
line-height: 1;
cursor: pointer;
}
z-index: 1000;
}

View File

@ -1,21 +1,42 @@
import React from 'react';
import { Layout, Dropdown, Avatar } from 'antd';
import React, { useState } from 'react';
import { Layout, Dropdown, Avatar, Drawer } from 'antd';
import './style.less';
import { history, Link, request, useModel } from 'umi';
import { UserOutlined, CodeOutlined } from '@ant-design/icons';
import { UserOutlined, CodeOutlined, MenuOutlined } from '@ant-design/icons';
import AvatarDropdown from '../AvatarDropdown';
import Menu from '@/components/menu';
import { ReactComponent as Logo } from './logo-white.svg';
import { useResponsive, useLocalStorageState } from 'ahooks';
export function TopMenuLayout(props: any) {
const { menu = [] } = props.page;
// const [visible, setVisible] = useState(false);
const [visible, setVisible] = useLocalStorageState(`nocobase-nav-visible`, false);
const responsive = useResponsive();
const isMobile = responsive.small && !responsive.middle && !responsive.large;
return (
<Layout style={{ height: '100vh' }}>
<Layout.Header style={{height: 48, lineHeight: '48px', padding: 0}} className="nb-header">
<div className="logo" style={{width: 200, height: 20, float: 'left'}}><Logo/></div>
<Menu hideChildren={true} items={menu} className={'noco-top-menu'} style={{float: 'left'}} theme="dark" mode="horizontal">
</Menu>
{!isMobile && <Menu hideChildren={true} items={menu} className={'noco-top-menu'} style={{float: 'left'}} theme="dark" mode="horizontal"/>}
{!isMobile && <AvatarDropdown/>}
{isMobile && <MenuOutlined onClick={() => {
setVisible(true);
}} style={{
fontSize: 16,
color: '#fff',
position: 'absolute',
right: 16,
top: 16,
}}/>}
{isMobile && <Drawer visible={visible} onClose={() => {
setVisible(false);
}} placement={'right'} closable={false} bodyStyle={{background: '#001529', padding: 0}}>
<Menu onSelect={() => {
setVisible(false);
}} mode={'inline'} hideChildren={true} items={menu} className={'noco-top-menu'} style={{float: 'left'}} theme="dark"/>
<AvatarDropdown/>
</Drawer>}
</Layout.Header>
<Layout.Content>
{props.children}

View File

@ -6,8 +6,17 @@ import { useRequest } from 'umi';
import { Spin } from '@nocobase/client';
import Field from './Field';
import get from 'lodash/get';
import { useSize } from 'ahooks';
import { configResponsive, useResponsive } from 'ahooks';
configResponsive({
small: 0,
middle: 800,
large: 1200,
});
export function Details(props: any) {
const dom = document.querySelector('body');
const responsive = useResponsive();
const {
activeTab = {},
pageInfo = {},
@ -26,6 +35,15 @@ export function Details(props: any) {
...actionDefaultParams,
});
});
let descriptionsProps: any = {
size: 'middle',
bordered: true,
}
if (responsive.small && !responsive.middle && !responsive.large) {
descriptionsProps = {
layout: 'vertical'
}
}
console.log(props);
return (
<Card bordered={false}>
@ -38,7 +56,12 @@ export function Details(props: any) {
actions={actions}
/>
{loading ? <Spin/> : (
<Descriptions size={'middle'} bordered column={1}>
<Descriptions
// layout={'vertical'}
// size={'middle'}
// bordered
{...descriptionsProps}
column={1}>
{fields.map((field: any) => {
return (
<Descriptions.Item label={field.title||field.name}>

View File

@ -219,6 +219,7 @@ export function LinkToFieldLink(props) {
onClick={(e) => {
e.stopPropagation();
}}
className={'noco-drawer'}
bodyStyle={{padding: 0}}
width={'40%'}
title={`查看${title}详情`}

View File

@ -60,6 +60,7 @@ export const DrawerForm = forwardRef((props: any, ref) => {
destroyOnClose
visible={visible}
width={'40%'}
className={'noco-drawer'}
onClose={() => {
setVisible(false);
}}

View File

@ -42,3 +42,17 @@
justify-content: center;
max-height: inherit !important;
}
.ant-drawer.noco-drawer {
.ant-drawer-content-wrapper {
width: 40%;
}
}
@media only screen and (max-width: 800px) {
.ant-drawer.noco-drawer {
.ant-drawer-content-wrapper {
width: 100% !important;
}
}
}