-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GUI Components: add List component (#3780)
- Loading branch information
1 parent
a550313
commit e813d2a
Showing
4 changed files
with
134 additions
and
4 deletions.
There are no files selected for viewing
71 changes: 71 additions & 0 deletions
71
portals-ui/packages/components/lib/components/list/index.tsx
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,71 @@ | ||
import type { Key, ReactNode } from 'react'; | ||
import React, { useState } from 'react'; | ||
import type { VirtualListState } from '@epam/uui-core'; | ||
import type { CommonProps } from '../..'; | ||
import { VirtualList } from '@epam/uui'; | ||
import classNames from 'classnames'; | ||
|
||
const MIN_VISIBLE_COUNT = 20; | ||
|
||
export type ListProps<Item> = CommonProps & { | ||
data: Item[]; | ||
renderItem: (item: Item, index: number) => ReactNode | string; | ||
header?: ReactNode; | ||
footer?: ReactNode; | ||
virtualized?: boolean; | ||
fieldKey?: string; | ||
}; | ||
|
||
export default function List<Item>(props: ListProps<Item>): ReactNode { | ||
const { | ||
header, | ||
footer, | ||
data, | ||
renderItem, | ||
fieldKey, | ||
virtualized = false, | ||
style, | ||
className, | ||
} = props; | ||
const [listState, setListState] = useState<VirtualListState>({ | ||
topIndex: 0, | ||
visibleCount: MIN_VISIBLE_COUNT, | ||
}); | ||
const visibleData = data.slice( | ||
listState.topIndex, | ||
(listState.topIndex ?? 0) + (listState.visibleCount ?? MIN_VISIBLE_COUNT), | ||
); | ||
const rows = visibleData.map((item, index) => ( | ||
<React.Fragment key={index}>{renderItem(item, index)}</React.Fragment> | ||
)); | ||
const listComponent = virtualized ? ( | ||
<VirtualList | ||
cx="max-h-full" | ||
rows={rows} | ||
value={listState} | ||
onValueChange={setListState} | ||
rowsCount={data.length} | ||
/> | ||
) : ( | ||
<div className="overflow-y-auto"> | ||
{data.map((item, index) => { | ||
let key: Key = `key_${index}`; | ||
if (item && typeof item === 'object' && fieldKey) { | ||
key = (item[fieldKey as keyof typeof item] as string | number) ?? key; | ||
} | ||
return ( | ||
<React.Fragment key={key}>{renderItem(item, index)}</React.Fragment> | ||
); | ||
})} | ||
</div> | ||
); | ||
return ( | ||
<div | ||
style={style} | ||
className={classNames('overflow-hidden flex flex-col', className)}> | ||
{header ?? null} | ||
{listComponent} | ||
{footer ?? null} | ||
</div> | ||
); | ||
} |
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 |
---|---|---|
@@ -1,7 +1,8 @@ | ||
import DummyComponent from './components/dummy-component'; | ||
import List from './components/list'; | ||
import '@epam/uui-components/styles.css'; | ||
import '@epam/uui/styles.css'; | ||
import './style.css'; | ||
|
||
export { DummyComponent }; | ||
export { DummyComponent, List }; | ||
export * from './components/common.types'; |
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 |
---|---|---|
@@ -1,9 +1,59 @@ | ||
import { DummyComponent } from '@cloud-pipeline/components'; | ||
import { useEffect } from 'react'; | ||
import { List } from '@cloud-pipeline/components'; | ||
import { useProjectsState } from '../../state/projects/hooks'; | ||
import { loadProjects } from '../../state/projects/load-projects'; | ||
import type { Project } from '@cloud-pipeline/core'; | ||
import './style.css'; | ||
|
||
export const Home = () => { | ||
const { projects } = useProjectsState(); | ||
useEffect(() => { | ||
loadProjects() | ||
.then(() => {}) | ||
.catch(() => {}); | ||
}, []); | ||
if (!projects) { | ||
return null; | ||
} | ||
return ( | ||
<div> | ||
<DummyComponent /> | ||
<div className="flex h-full gap-5 overflow-hidden flex-nowrap justify-around p-2"> | ||
<List | ||
className="list-container" | ||
header={<div className="p-2 list-header-container">Projects</div>} | ||
footer={<div className="p-2">List footer</div>} | ||
data={projects} | ||
virtualized | ||
renderItem={(item: Project) => ( | ||
<div className="p-2" style={{ height: 100 }}> | ||
{item.name} | ||
</div> | ||
)} | ||
style={{ flex: 1 }} | ||
/> | ||
<List | ||
className="list-container" | ||
header={<div className="p-2">List header</div>} | ||
footer={<div className="p-2">List footer</div>} | ||
data={projects} | ||
virtualized | ||
renderItem={(item: Project) => ( | ||
<div className="p-2" style={{ height: 100 }}> | ||
{item.name} | ||
</div> | ||
)} | ||
style={{ flex: 1 }} | ||
/> | ||
<List | ||
className="list-container" | ||
data={projects} | ||
virtualized | ||
renderItem={(item: Project) => ( | ||
<div className="p-2" style={{ height: 300 }}> | ||
{item.name} | ||
</div> | ||
)} | ||
style={{ flex: 1 }} | ||
/> | ||
</div> | ||
); | ||
}; |
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,8 @@ | ||
.list-container { | ||
box-shadow: var(--uui-shadow-level-1); | ||
border-radius: var(--uui-border-radius); | ||
} | ||
|
||
.list-header-container { | ||
box-shadow: var(--uui-shadow-level-1); | ||
} |