Skip to content
1 change: 1 addition & 0 deletions libs/react/ui-core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './lib/table/table';
export * from './lib/markdown/markdown';
export * from './lib/spinner/spinner';
export * from './lib/steps/steps';
Expand Down
2 changes: 1 addition & 1 deletion libs/react/ui-core/src/lib/dropdown/dropdown.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ Primary.args = {
{label: 'Вариант 04', key: 'key 4'},
],
icon: <Icon size={24} name={"ri-calendar-event-line"} />,
errorText: 'Ошибка!!!'
errorText: 'Ошибка!!!',
};
8 changes: 7 additions & 1 deletion libs/react/ui-core/src/lib/dropdown/useDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@ export function useDropdown(props:DropdownProps):useDropdownProps {
props.defaultSelectedKey && props.items.find((item) => item.key === props.defaultSelectedKey)?.label
|| null)

useEffect(() => {
if(props.defaultSelectedKey) {
setActiveItemKey(props.defaultSelectedKey)
}
}, [props.defaultSelectedKey])

useEffect(() => {
document.addEventListener('mousedown', handleClickOutside)

return () => {
document.removeEventListener('mousedown', handleClickOutside)
}
})
}, [])

const handleOpen = useCallback((isOpen: boolean) => {
if(!props.disabled) {
Expand Down
41 changes: 41 additions & 0 deletions libs/react/ui-core/src/lib/table/Body/tableBody.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, {FC} from 'react'
import styles from '../table.module.scss'
import {ColumnsType} from '../TableProps'

const TableBody:FC<MyProps<any>> = React.memo(({data, columns}) => {
return (
<tbody>
{
(data.map((item, index) => {
return (
<tr key={item.key}>
{columns.map((column, tdIndex) => {
let attributes
if(column.onCell) {
attributes = column.onCell(item, index)
}
if((attributes?.colSpan === 0 || column.colSpan === 0) || (attributes?.rowSpan === 0 || column.rowSpan === 0)) return null
return (
<td className={styles['table-cell']} colSpan={attributes?.colSpan || column.colSpan} rowSpan={attributes?.rowSpan || column.rowSpan} style={{width: column.width, ...attributes?.style}} key={tdIndex}>
{
column.render
? column.render(item[column.dataIndex], index) // index - row number
: item[column.dataIndex]
}
</td>
)
})}
</tr>
)
}))
}
</tbody>
)
})

export default TableBody

type MyProps<RecordType> = {
data: RecordType[]
columns: ColumnsType<RecordType>[]
}
49 changes: 49 additions & 0 deletions libs/react/ui-core/src/lib/table/Footer/tableFooter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, {FC} from 'react'
import styles from '../table.module.scss'
import {ColumnsType} from '../TableProps'

const TableFooter:FC<MyProps<any>> = React.memo(({footer, columns, dataLength}) => {

return (
<>
{
footer &&
(!React.isValidElement(footer)
?
<tfoot className={styles['table-footer']}>
<tr>
{columns.map((column, index) => {
let attributes
if(column.onCell) {
attributes = column.onCell(footer, dataLength) // footer row number
}
console.log(attributes?.colSpan)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нужно убрать

if((attributes?.colSpan === 0 || column.colSpan === 0) || (attributes?.rowSpan === 0 || column.rowSpan === 0)) return null
return (
<td className={styles['table-cell']} colSpan={attributes?.colSpan || column.colSpan} rowSpan={attributes?.rowSpan || column.rowSpan} style={{width: column.width, ...attributes?.style}} key={index}>
{footer[column.dataIndex]}
</td>
)
})}
</tr>
</tfoot>
:
<tfoot className={styles['table-footer']}>
<tr>
<td className={`${styles['table-cell']} ${styles['table-footer-element']}`} colSpan={columns.length}>
{footer}
</td>
</tr>
</tfoot>)
}
</>
)
})

export default TableFooter

type MyProps<RecordType> = {
footer?: RecordType | React.ReactNode
columns: ColumnsType<RecordType>[]
dataLength: number
}
37 changes: 37 additions & 0 deletions libs/react/ui-core/src/lib/table/Header/tableHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, {FC} from 'react'
import styles from '../table.module.scss'
import {ColumnsType, TableSortType} from '../TableProps'
import Icon from '../../icon/icon'
import {useTableHeader} from './useTableHeader'

const TableHeader:FC<TableHeaderProps<any>> = React.memo(({columns, sortValue, sortType, sortTable}) => {
const {getIconClasses} = useTableHeader({columns, sortValue, sortType, sortTable})
return (
<thead>
<tr>
{columns.map((item) => {
if(item.colSpan === 0 || item.rowSpan === 0) return null
return (
<th className={styles['table-head']} colSpan={item.colSpan} rowSpan={item.rowSpan} style={{width: item.width}} key={item.key}>
<span className={styles['table-head-cell']}>
{item.title}
{
item.sorter && <Icon onClick={() => item.sorter && sortTable(item.dataIndex, sortType)} className={getIconClasses(item.dataIndex)} name={'ri-arrow-down-s-fill'} size={18} type={'fill'} />
}
</span>
</th>
)
})}
</tr>
</thead>
)
})

export default TableHeader

export type TableHeaderProps<RecordType> = {
columns: ColumnsType<RecordType>[]
sortValue: string
sortType: TableSortType
sortTable: (value: string, type: TableSortType) => void
}
18 changes: 18 additions & 0 deletions libs/react/ui-core/src/lib/table/Header/useTableHeader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {useCallback} from 'react'
import styles from '../table.module.scss'
import {TableHeaderProps} from './tableHeader'
import {getClasses} from '../../../utils/getClasses'

export const useTableHeader = (props: TableHeaderProps<any>) => {

const getIconClasses = useCallback((dataIndex: string) => {
const conditions:{[index: string]:boolean} = {
"table-head-sort": true,
"table-head-sort-active": props.sortValue === dataIndex && props.sortType !== '',
"table-head-sort-ascending": props.sortValue === dataIndex && props.sortType === 'ascending',
};
return getClasses(conditions, styles)
}, [props]);

return {getIconClasses}
}
62 changes: 62 additions & 0 deletions libs/react/ui-core/src/lib/table/TableProps.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {DefaultParams} from '../../default-types/defaultParams'
import React from 'react'
import {ClickableObjectMini} from '../../default-types/ClickableObjectMini'

export interface TableProps<RecordType> extends DefaultParams, ClickableObjectMini{

/** ColumnsType<{DataType}> { <br/>
* &nbsp;&nbsp; title: string <br/>
* &nbsp;&nbsp; key: React.Key <br/>
* &nbsp;&nbsp; dataIndex: string <br/>
* &nbsp;&nbsp; colSpan?: number <br/>
* &nbsp;&nbsp; rowSpan?: number <br/>
* &nbsp;&nbsp; width?: number <br/>
* &nbsp;&nbsp; render?: (value: DataType, index: number) => React.ReactNode <br/>
* &nbsp;&nbsp; sorter?: boolean <br/>
* &nbsp;&nbsp; onCell?: GetComponentProps<RecordType> <br/>
* }
*
* */
columns: ColumnsType<RecordType>[]

/** Data of table body
*
* DataType[] - Array of column's dataIndexes
*
* */
data: RecordType[]

/** Data of table footer
*
* DataType - Last object of column's dataIndexes or ReactNode
*
* */
footer?: RecordType | React.ReactNode

/** Table layout prop */
tableLayout?: TableLayout
}

export interface ColumnsType<RecordType> {
title: string
key: React.Key
dataIndex: string
colSpan?: number
rowSpan?: number
width?: number
sorter?: boolean
render?: (
value: RecordType,
index: number,
) => React.ReactNode;
onCell?: GetComponentProps<RecordType>
}

export type GetComponentProps<DataType> = (
data: DataType,
index: number,
) => React.TdHTMLAttributes<any>;

export type TableLayout = 'auto' | 'fixed';

export type TableSortType = 'descending' | 'ascending' | ''
1 change: 1 addition & 0 deletions libs/react/ui-core/src/lib/table/table.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@use '../../../../../../styles/components/table' as *;
10 changes: 10 additions & 0 deletions libs/react/ui-core/src/lib/table/table.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { render } from '@testing-library/react';

import { Table } from './table';

describe('Table', () => {
it('should render successfully', () => {
const { baseElement } = render(<Table columns={[]} data={[]} />);
expect(baseElement).toBeTruthy();
});
});
Loading