Skip to content

Commit

Permalink
bootstrap list
Browse files Browse the repository at this point in the history
  • Loading branch information
John B committed May 25, 2021
1 parent de07583 commit 6e7df1e
Show file tree
Hide file tree
Showing 5 changed files with 284 additions and 18 deletions.
39 changes: 39 additions & 0 deletions src/list/index.ts
@@ -0,0 +1,39 @@
import React from 'react';
import SuperList, { InnerProps } from '../lib/list/list-super';
import {
GlobalSearch,
HeaderUnit,
FilterUnit,
OrderController,
Row,
ColCell,
RecordInfo,
NoRow,
ListWrapper,
ListContainer,
ListHeader,
ListBody,
Loader
} from './ui';

import Pagination from './ui/pagination';

const List = <A>(props: InnerProps<A>): JSX.Element =>
SuperList<A>({
HeaderUnit,
FilterUnit,
OrderController,
ColCell,
GlobalSearch,
NoRow,
Row,
ListWrapper,
ListContainer,
ListHeader,
ListBody,
RecordInfo,
Pagination,
Loader
})(props);

export default List;
178 changes: 178 additions & 0 deletions src/list/ui/index.tsx
@@ -0,0 +1,178 @@
import React from 'react';

import * as UIType from '../../lib/list/ui-type';
import { paginationBoundaries } from '../../lib/list/utils/pagination-utils';

const Loader = () => <p>Loading...</p>;

const Alert = ({
// type = 'success',
children
}: {
children: React.ReactNode | JSX.Element;
type?: 'error' | 'success' | 'info' | 'warning';
}): JSX.Element => <div className={'alert'}>{children}</div>;

const GlobalSearch = () => <></>;
const PopoverFilter = () => <></>;
const FilterUnit = () => <></>;

import {
PaginationUnitProps,
NoRowProps,
ListWrapperProps,
ListContainerProps,
ListBodyProps,
RecordInfoProps,
ListHeaderProps,
RowProps,
ColCellProps,
PaginationWrapperProps,
OrderControllerUpAndDownProps,
OrderControllerProps
} from '../../lib/list/ui-type';

export const NoRow = (props: NoRowProps): JSX.Element | null => {
if (props.n > 0) {
return null;
}

return <Alert type="warning">No rows found</Alert>;
};

export const PaginationWrapper = (
props: PaginationWrapperProps
): JSX.Element => {
return (
<nav>
<ul className="pagination">{props.children}</ul>
</nav>
);
};

export const PaginationUnit = (
props: PaginationUnitProps
): JSX.Element | null => {
const { isActive, isDisabled, children, onClick } = props;

// here we disable the button in case it is not valid
if (isDisabled) {
return null;
}

const className =
'page-item' + (isActive ? ' active' : '') + (isDisabled ? ' disabled' : '');

return (
<li className={className}>
<button className="page-link" onClick={onClick}>
{children}
</button>
</li>
);
};

export const ColCell = (props: ColCellProps): JSX.Element => {
const { children, colSpan, style } = props;
return (
<td colSpan={colSpan} style={style}>
{children}
</td>
);
};

export const HeaderUnit = (props: UIType.HeaderUnitProps): JSX.Element => {
const { children } = props;

return <th>{children}</th>;
};

const Icon = ({ name }: { name: string }) => <i className={'fa fa-' + name} />;

export const OrderControllerUpAndDown = (
props: OrderControllerUpAndDownProps
): JSX.Element => {
return (
<span>
<span key={'asc'} onClick={(): void => props.onClick(true)}>
<ChevronUp />
</span>
<span key={'desc'} onClick={(): void => props.onClick(false)}>
<ChevronDown />
</span>
</span>
);
};

const ChevronUp = () => <Icon name="chevron-up" />;
const ChevronDown = () => <Icon name="chevron-down" />;
const SortDefault = () => <Icon name="arrow" />;

export const OrderController = (props: OrderControllerProps): JSX.Element => {
const { onClick, descAsc } = props;

let Icon = SortDefault;
if (descAsc !== null) {
Icon = descAsc ? ChevronUp : ChevronDown;
}

return (
<div
style={{
cursor: 'pointer',
display: 'inline-block',
color: descAsc === null ? '#ccc' : '#000'
}}
onClick={(): void => onClick(null)}
>
<Icon />
</div>
);
};

export const ListWrapper = (props: ListWrapperProps): JSX.Element => {
const { children } = props;
return <div className="table-responsive-sm">{children}</div>;
};

export const ListContainer = (props: ListContainerProps): JSX.Element => {
const { children, maxHeight, stickyHeader = false } = props;
return (
<div className={'container'} style={maxHeight ? { maxHeight } : undefined}>
<table className={'table table-striped'}>{children}</table>
</div>
);
};

export const Row = (props: RowProps): JSX.Element => {
const { children } = props;
return <tr>{children}</tr>;
};

export const ListHeader = (props: ListHeaderProps): JSX.Element => {
const { children } = props;
return <thead>{children}</thead>;
};

export const ListBody = ({ children }: ListBodyProps): JSX.Element => (
<tbody>{children}</tbody>
);

export const RecordInfo = (props: RecordInfoProps): JSX.Element | null => {
const { nPerPage, idx, n } = props;

if (n === 0) {
return null;
}

const { start, end } = paginationBoundaries(idx, nPerPage);

return (
<p className="pull-right">
Showing {start + 1} to {Number(start) + Number(nPerPage) > n ? n : end} of{' '}
{n} entries
</p>
);
};

export { FilterUnit, GlobalSearch, PopoverFilter, Loader };
47 changes: 47 additions & 0 deletions src/list/ui/pagination.tsx
@@ -0,0 +1,47 @@
import React from 'react';
import { getPagination } from '../../lib/list/utils/pagination-utils';
import { PaginationProps } from '../../lib/list/ui-type';

const Pagination = (props: PaginationProps): JSX.Element | null => {
const { n, nPerPage, idx, onClick } = props;

if (n === 0) {
return null;
}

const { nPage } = getPagination(n, nPerPage);

return (
<nav aria-label="Page navigation example">
<ul className="pagination">
<li className="page-item">
<a className="page-link" href="#">
Previous
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
1
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
2
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
3
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
Next
</a>
</li>
</ul>
</nav>
);
};

export default Pagination;
12 changes: 10 additions & 2 deletions src/public.tsx
@@ -1,12 +1,20 @@
import React from 'react';

import List from './list';

const Default = (): JSX.Element => (
<div>
<p><b>TODO</b>: examples for bootstrap</p>
<List
data={[{ name: 'Doe', firstName: 'John' }]}
def={[
{ name: 'name', label: 'Name' },
{ name: 'firstName', label: 'First Name' }
]}
/>

<p>
<a href="https://github.com/Nexysweb/mui-list-ts">Source</a> available under MIT license.
<a href="https://github.com/Nexysweb/mui-list-ts">Source</a> available
under MIT license.
</p>
</div>
);
Expand Down
26 changes: 10 additions & 16 deletions src/routes.tsx
@@ -1,22 +1,16 @@
import React from 'react';

import { Router, Switch, Route } from 'react-router-dom';
import * as History from 'history';
import { Switch, Route } from 'react-router-dom';

import Public from './public';
import Layout from './layout/index'


const basename: string = import.meta.env.SNOWPACK_PUBLIC_URL || '';

console.log(`basename: ${basename}`);

const history = History.createBrowserHistory({
basename
});

const Routes = (): JSX.Element => <Layout>gd</Layout>


import Layout from './layout/index';

const Routes = (): JSX.Element => (
<Layout>
<Switch>
<Route component={Public} />
</Switch>
</Layout>
);

export default Routes;

0 comments on commit 6e7df1e

Please sign in to comment.