A Pagination Table & Scroll List component suite for CRUD operation, which is based on MobX RESTful & React.
SemVer | status | ES decorator | MobX |
---|---|---|---|
>=2 |
✅developing | stage-3 | >=6.11 |
<2 |
❌deprecated | stage-2 | >=4 <6.11 |
- Image Preview
- File Preview
- File Picker
- File Uploader
- Form Field
- Range Input
- Badge Input
- REST Form
- Pager
- REST Table
- Scroll Boundary
- Scroll List
npm i react \
mobx \
mobx-react \
mobx-i18n \
mobx-restful \
mobx-restful-table
Some Node.js tips about the upstream
mobx-restful
you should know: https://github.com/idea2app/MobX-RESTful?tab=readme-ov-file#usage
{
"compilerOptions": {
"target": "ES6",
"module": "ES6",
"moduleResolution": "Node",
"useDefineForClassFields": true,
"jsx": "react-jsx",
"skipLibCheck": true,
"lib": ["ES2023", "DOM"]
}
}
Inspired by Ant Design - Pro Table
import { computed } from 'mobx';
import { observer } from 'mobx-react';
import { PureComponent } from 'react';
import { Container, Button, Badge } from 'react-bootstrap';
import { Column, RestTable } from 'mobx-restful-table';
import repositoryStore, { Repository } from '../models/Repository';
import { i18n } from '../models/Translation';
@observer
export default class PaginationPage extends PureComponent {
@computed
get columns(): Column<Repository>[] {
const { t } = i18n;
return [
{
key: 'full_name',
renderHead: t('repository_name'),
renderBody: ({ html_url, full_name }) => (
<a target="_blank" href={html_url}>
{full_name}
</a>
),
},
{ key: 'homepage', type: 'url', renderHead: t('home_page') },
{ key: 'language', renderHead: t('programming_language') },
{
key: 'topics',
renderHead: t('topic'),
renderBody: ({ topics }) => (
<>
{topics?.map(topic => (
<Badge
key={topic}
className="me-2"
as="a"
target="_blank"
href={`https://github.com/topics/${topic}`}
>
{topic}
</Badge>
))}
</>
),
},
{ key: 'stargazers_count', type: 'number', renderHead: t('star_count') },
];
}
render() {
return (
<Container style={{ height: '91vh' }}>
<RestTable
className="text-center"
striped
hover
editable
deletable
columns={this.columns}
store={repositoryStore}
translator={i18n}
onCheck={console.log}
/>
</Container>
);
}
}
import { observer } from 'mobx-react';
import { FC } from 'react';
import { Container, Row, Col } from 'react-bootstrap';
import { Loading } from 'idea-react';
import { ScrollList } from 'mobx-restful-table';
import { GitCard } from '../components/Git';
import repositoryStore from '../models/Repository';
import { i18n } from '../models/Translation';
const ScrollListPage: FC = observer(() => (
<Container>
<h1 className="my-4">{i18n.t('scroll_list')}</h1>
{repositoryStore.downloading > 0 && <Loading />}
<ScrollList
translator={i18n}
store={repositoryStore}
renderList={allItems => (
<Row as="ul" className="list-unstyled g-4" xs={1} sm={2}>
{allItems.map(item => (
<Col as="li" key={item.id}>
<GitCard className="h-100 shadow-sm" {...item} />
</Col>
))}
</Row>
)}
/>
</Container>
));
export default ScrollListPage;
import { toggle } from 'mobx-restful';
import { FileModel } from 'mobx-restful-table';
import { uploadFile } from '../utility';
export class AssetFileModel extends FileModel {
@toggle('uploading')
async upload(file: File) {
const URI = await uploadFile(file);
return super.upload(URI);
}
}
export default new AssetFileModel();
import { FileUploader } from 'mobx-restful-table';
import fileStore from '../model/File';
export const EditorPage = () => (
<FileUploader
store={fileStore}
accept="image/*"
name="images"
multiple
required
onChange={console.log}
/>
);