[EDIT:已更新,将问题重点放在重叠的问题上;还对CodePens进行了编辑] [EDIT2:已更新,以包含有关Mohamed Mansour建议的方法的详细信息]
我在设计Office UI Fabric React UI的布局时遇到困难。这是我目前拥有的布局:
目标是将顶部的CommandBar和标题(文本标签和搜索框)固定在顶部,DetailsList和文件按钮固定在底部,并在标题区域之后占用尽可能多的空间。 / p>
我已经成功使用ScrollablePane和两个Sticky组件将CommandBar和按钮固定在所需的位置。但是,DetailsList滚动浏览包含CommandBar和标题的顶部Sticky,并且按钮稍微覆盖在DetailsList网格的顶部:
我尝试使用Fabric Grid组件来布局所有部分,但没有任何区别(如果有帮助的话)。最佳布局的项目部分位于两个Sticky元素之间;如果将项目部分添加到“页眉”或“页脚粘滞”元素中,则布局是可怕的。如何确保DetailsList不会在顶部和底部组件下方滚动?
以下是两个说明问题的代码笔:
无网格:https://codepen.io/elegault/pen/aQayvY?editors=0010(fileHeader的元素使用网格,但其他所有元素都不在网格中)
const columns = [{
key: 'projectNameColumn',
name: 'Project',
fieldName: 'name',
minWidth: 100,
maxWidth: 200,
isResizable: true,
ariaLabel: 'Operations for Project'
}];
const items = [{
id: '0',
name: 'ABC Construction'
},
{
id: '1',
name: 'Air Bee and Bee'
},
{
id: '2',
name: 'Architectural Salvage'
},
{
id: '3',
name: 'Arkham Airport'
},
{
id: '4',
name: 'Arkham Assembly Hall'
},
{
id: '5',
name: 'Arkham Library'
},
{
id: '6',
name: 'zArkham Renovation'
},
{
id: '7',
name: 'Foo'
},
{
id: '8',
name: 'Foo1'
},
{
id: '9',
name: 'Foo2'
},
{
id: '10',
name: 'Foo3'
},
{
id: '11',
name: 'Foo4'
},
{
id: '12',
name: 'Foo5'
},
{
id: '13',
name: 'Foo6'
},
{
id: '14',
name: 'Foo7'
},
{
id: '15',
name: 'Foo8'
},
{
id: '16',
name: 'Foo9'
},
{
id: '17',
name: 'Foo10'
},
];
class Content extends React.Component {
public render() {
const fileHeader = <
div className = 'ms-Grid' >
<
div className = 'ms-Grid-row' >
<
div className = 'ms-Grid-col ms-sm2 ms-md2 ms-lg2' >
<
img width = '32'
height = '32'
alt = 'logo'
title = 'logo' / >
<
/div> <
div className = 'ms-Grid-col ms-sm10 ms-md10 ms-lg10' >
<
Fabric.Label className = 'ms-font-l ms-fontWeight-bold ms-fontColor-blue' > [TITLE] < /Fabric.Label> <
/div> <
/div> <
div className = 'ms-Grid-row' >
<
div className = 'ms-Grid-col ms-sm2 ms-md2 ms-lg2' >
<
/div> <
div className = 'ms-Grid-col ms-sm10 ms-md10 ms-lg10' >
<
Fabric.Label
className = 'ms-font-m ms-fontWeight-bold ms-fontColor-neutralPrimary' > SELECTED PROJECT: < /Fabric.Label> <
/div> <
/div> <
/div>;
const commandBar = < div >
<
Fabric.CommandBar
isSearchBoxVisible = {
false
}
items = {
[{
key: 'openWebApp',
name: 'Open Web App',
icon: 'OpenInNewWindow', // Or Link
['data-automation-id']: 'openWebAppButton',
title: 'Open web app',
href: 'http://www.codepen.io',
target: '_blank',
}]
}
farItems = {
[{
key: 'menuOptions',
name: 'Options',
icon: 'Settings',
iconOnly: 'true',
['data-automation-id']: 'settingsButton',
subMenuProps: {
items: [{
key: 'privacyPolicy',
name: 'Privacy Policy',
icon: 'PageLock',
href: 'http://www.codepen.io',
target: '_blank',
},
{
key: 'termsOfUse',
name: 'Terms & Conditions',
icon: 'TextDocument',
href: 'http://www.codepen.io',
target: '_blank'
}
]
}
}]
}
/> <
/div>;
const projects = < Fabric.MarqueeSelection selection = {
null
}
data - is - scrollable = {
false
} >
<
Fabric.DetailsList
items = {
items
}
columns = {
columns
}
/> <
/Fabric.MarqueeSelection>;
const selection = < div > [project name] < /div>;
const search = < Fabric.TextField label = 'Search projects:' / > ;
const fileButton = <
div >
<
Fabric.DefaultButton primary = {
true
} > File To Project < /Fabric.DefaultButton> <
/div>;
return ( <
Fabric.Fabric >
<
div style = {
{
height: '500px',
position: 'relative',
maxHeight: 'inherit'
}
} >
<
Fabric.ScrollablePane scrollbarVisibility = {
Fabric.ScrollbarVisibility.auto
} >
<
Fabric.Sticky stickyPosition = {
Fabric.StickyPositionType.Header
} > {
commandBar
} {
fileHeader
} {
selection
} {
search
} <
/Fabric.Sticky> {
projects
} <
Fabric.Sticky stickyPosition = {
Fabric.StickyPositionType.Footer
} > {
fileButton
} <
/Fabric.Sticky> <
/Fabric.ScrollablePane> <
/div> <
/Fabric.Fabric>
);
}
}
ReactDOM.render( <
Content / > ,
document.getElementById('content')
);
使用完整网格:https://codepen.io/elegault/pen/wQxoRR
const columns = [
{
key: 'projectNameColumn',
name: 'Project',
fieldName: 'name',
minWidth: 100,
maxWidth: 200,
isResizable: true,
ariaLabel: 'Operations for Project'
}
];
const items = [
{id: '0', name: 'ABC Construction'},
{id: '1', name: 'Air Bee and Bee'},
{id: '2', name: 'Architectural Salvage'},
{id: '3', name: 'Arkham Airport'},
{id: '4', name: 'Arkham Assembly Hall'},
{id: '5', name: 'Arkham Library'},
{id: '6', name: 'zArkham Renovation'},
{id: '7', name: 'Foo'},
{id: '8', name: 'Foo1'},
{id: '9', name: 'Foo2'},
{id: '10', name: 'Foo3'},
{id: '11', name: 'Foo4'},
{id: '12', name: 'Foo5'},
{id: '13', name: 'Foo6'},
{id: '14', name: 'Foo7'},
{id: '15', name: 'Foo8'},
{id: '16', name: 'Foo9'},
{id: '17', name: 'Foo10'},
];
class Content extends React.Component {
public render() {
const commandBar = <div>
<Fabric.CommandBar
isSearchBoxVisible={false}
items={[
{
key: 'openWebApp',
name: 'Open Web App',
icon: 'OpenInNewWindow', // Or Link
title: 'Open web app',
href: 'http://www.codepen.io',
target: '_blank',
}
]}
farItems={[
{
key: 'menuOptions',
name: 'Options',
icon: 'Settings',
iconOnly: 'true',
['data-automation-id']: 'settingsButton',
subMenuProps: {
items: [
{
key: 'privacyPolicy',
name: 'Privacy Policy',
icon: 'PageLock',
href: 'http://www.codepen.io',
target: '_blank',
},
{
key: 'termsOfUse',
name: 'Terms & Conditions',
icon: 'TextDocument',
href: 'http://www.codepen.io',
target: '_blank'
}
]
}
}
]}
/>
</div>;
const projects = <Fabric.MarqueeSelection selection={null} data-is-scrollable={false}>
<Fabric.DetailsList
items={items}
columns={columns}
/>
</Fabric.MarqueeSelection>;
const selection = <div>[project name]</div>;
const search = <Fabric.TextField label='Search projects:'/>;
const fileButton =
<div>
<Fabric.DefaultButton primary={true}>File To Project</Fabric.DefaultButton>
</div>;
const fileHeader =
<div className='ms-Grid'>
<div className='ms-Grid-row'>
<div className='ms-Grid-col ms-sm2 ms-md2 ms-lg2'>
<img width='32' height='32' alt='logo' title='logo'/>
</div>
<div className='ms-Grid-col ms-sm10 ms-md10 ms-lg10'>
<Fabric.Label className='ms-font-l ms-fontWeight-bold ms-fontColor-blue'>[TITLE]</Fabric.Label>
</div>
</div>
<div className='ms-Grid-row'>
<div className='ms-Grid-col ms-sm2 ms-md2 ms-lg2'>
</div>
<div className='ms-Grid-col ms-sm10 ms-md10 ms-lg10'>
<Fabric.Label
className='ms-font-m ms-fontWeight-bold ms-fontColor-neutralPrimary'>SELECTED PROJECT:</Fabric.Label>
</div>
</div>
</div>;
return (
<Fabric.Fabric>
<div style={{height:'500px', position:'relative', maxHeight:'inherit'}}>
<Fabric.ScrollablePane scrollbarVisibility={Fabric.ScrollbarVisibility.auto}>
<div className='ms-Grid'>
<Fabric.Sticky stickyPosition={Fabric.StickyPositionType.Header}>
<div className='ms-Grid-row'>
<div className='ms-Grid-col ms-sm10 ms-md10 ms-lg10'>
{commandBar}
</div>
</div>
<div className='ms-Grid-row'>
<div className='ms-Grid-col ms-sm10 ms-md10 ms-lg10'>
{fileHeader}
</div>
</div>
<div className='ms-Grid-row'>
<div className='ms-Grid-col ms-sm10 ms-md10 ms-lg10'>
{selection}
</div>
</div>
<div className='ms-Grid-row'>
<div className='ms-Grid-col ms-sm10 ms-md10 ms-lg10'>
{search}
</div>
</div>
</Fabric.Sticky>
<div className='ms-Grid-row'>
<div className='ms-Grid-col ms-sm10 ms-md10 ms-lg10'>
{projects}
</div>
</div>
<Fabric.Sticky stickyPosition={Fabric.StickyPositionType.Footer}>
<div className='ms-Grid-row'>
<div className='ms-Grid-col ms-sm10 ms-md10 ms-lg10'>
{fileButton}
</div>
</div>
</Fabric.Sticky>
</div>
</Fabric.ScrollablePane>
</div>
</Fabric.Fabric>
);
}
}
ReactDOM.render(
<Content />,
document.getElementById('content')
);
此外,当尝试在使用嵌套自定义React组件的代码笔之外的项目中在父div中使用Flex类或在父div中定义的高度时(根据Mohamed Mansour的建议),整个DetailsList无法呈现。例如,此DOM资源管理器显示了即使在多个“主” div中设置了定义的高度并使用flex仍然仍然无法呈现DetailsList:
答案 0 :(得分:0)
让我们清除一些术语,这些术语来自文档:
要实现所需的效果,滚动条仅出现在页眉和页脚之间,可以添加一些普通的CSS。运行下面的代码片段以查看它。基本上只是弹性布局。
我也更新了您的示例:https://codepen.io/mohamedhmansour/pen/rQqqvP
Object { model: "general.module", pk: 1, fields: { name: "General" } }
let { DetailsList, Fabric, ScrollablePane, ScrollbarVisibility } = window.Fabric;
function Content() {
const items = [...Array(500).keys()].map(i => ({key: i, text: `Item ${i}`}));
return (
<ScrollablePane scrollbarVisibility={ScrollbarVisibility.auto}>
<DetailsList items={items} />
</ScrollablePane>
);
}
ReactDOM.render(
<Fabric className='wrapper'>
<div className='header'>Header</div>
<div className='main'>
<Content />
</div>
<div className='footer'>Footer</div>
</Fabric>,
document.getElementById('content')
);
.wrapper {
display: flex;
flex-direction: column;
width: 100%;
position: absolute;
top: 0;
bottom: 0;
}
.main {
flex: 1;
position: relative;
}
.header, .footer {
background: black;
color: white;
padding: 10px;
}