diff --git a/src/_test.tsx b/src/_test.tsx index 4e3a04d..79a64a4 100644 --- a/src/_test.tsx +++ b/src/_test.tsx @@ -1,17 +1,31 @@ - -import React, { useState } from 'react'; -import ReactDom from 'react-dom' -import Modal from './components/modal/modal'; -import Upload from './components/upload/upload'; -import Tab from './components/tab/tab'; - -import * as GOJI from 'goji_ui' +import React, { useState } from "react"; +import ReactDom from "react-dom"; +import Modal from "./components/modal/modal"; +import Upload from "./components/upload/upload"; +import Tab from "./components/tab/tab"; +import Table from "./components/table/table"; +import Popover from "./components/Popover/Popover"; +import * as GOJI from "goji_ui"; function App() { - const [visible, setVisible] = useState(false) - const [ev, setEv] = useState(false) - return
- {/* + {/* 这是扩展的内容
} items={[ @@ -27,77 +41,102 @@ function App() { } ]} /> */} - - -

test

- - { - setEv(true) - }} - hiddenStyle={{ - height:'0px', - overflow:'hidden' - }} - tabContentVisible={ev} - extSelector={'[aria-label="tab"]'} - extension={
{ setEv(!ev) }} className="ext">这是扩展的内容
} - items={[ - { - title: "tab1", - key: "tab1", - children:
tab1
- }, - { - title: "tab2", - key: "tab2", - children:
tab2
- } - ]} - /> - - { - setVisible(false) - }} - visible={visible} - > -
- how to set default value for typescript interface field - -
-
- - { - for (var i = 0; i < f.length; i++) { - console.log(f[i].name) - } - return new Promise((r, j) => { - setTimeout(() => { - r(f) - }, 1000); - }) - }} - - valueFilter={({ response }) => { - return (response as Record).url - }} - onComplete={(res: any[]) => { - console.log(res) - }} - > - 请选择文件 - - +

test

+ + { + setEv(true); + }} + hiddenStyle={{ + height: "0px", + overflow: "hidden", + }} + tabContentVisible={ev} + extSelector={'[aria-label="tab"]'} + extension={ +
{ + setEv(!ev); + }} + className="ext" + > + 这是扩展的内容 +
+ } + items={[ + { + title: "tab1", + key: "tab1", + children: ( + { + return ( +
+

Content

+

Content

+
+ ); + }} + title="气泡" + > +
这是一个气泡
+
+ ), + }, + { + title: "tab2", + key: "tab2", + children:
tab2
, + }, + ]} + /> + ; +
+ + + +
+ { + setVisible(false); + }} + visible={visible} + > +
+ how to set default value for typescript interface field + +
+
+ { + for (var i = 0; i < f.length; i++) { + console.log(f[i].name); + } + return new Promise((r, j) => { + setTimeout(() => { + r(f); + }, 1000); + }); + }} + valueFilter={({ response }) => { + return (response as Record).url; + }} + onComplete={(res: any[]) => { + console.log(res); + }} + > + 请选择文件 + + + ); } -ReactDom.render(, document.getElementById("app")) \ No newline at end of file +ReactDom.render(, document.getElementById("app")); diff --git a/src/components/Popover/Popover.module.css b/src/components/Popover/Popover.module.css new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Popover/Popover.module.less b/src/components/Popover/Popover.module.less new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Popover/Popover.tsx b/src/components/Popover/Popover.tsx new file mode 100644 index 0000000..7e783c0 --- /dev/null +++ b/src/components/Popover/Popover.tsx @@ -0,0 +1,43 @@ +import React, { useState } from "react"; +// import { motion } from "framer-motion"; +import styles from "./Popover.module.less"; + + + +function Popover({ content, children }) { + const [showPopover, setShowPopover] = useState(false); + + const handleMouseEnter = () => { + setShowPopover(true); + }; + + const handleMouseLeave = () => { + setShowPopover(false); + }; + + return ( +
+ {children} + {showPopover && ( +
+ {content} +
+ )} +
+ ); +} + +export default Popover; diff --git a/src/components/table/table.module.css b/src/components/table/table.module.css new file mode 100644 index 0000000..8e02534 --- /dev/null +++ b/src/components/table/table.module.css @@ -0,0 +1,31 @@ +.content table { + border-collapse: collapse; + width: 100%; +} +.content th, +.content td { + text-align: left; + padding: 8px; +} +.content th { + background-color: #f2f2f2; +} +.content tr:nth-child(even) { + background-color: #f2f2f2; +} +.content tr:hover { + background-color: #ddd; +} +.content td:first-child, +.content th:first-child { + border-left: 1px solid #ddd; +} +.content td:last-child, +.content th:last-child { + border-right: 1px solid #ddd; +} +.content td, +.content th { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; +} diff --git a/src/components/table/table.module.less b/src/components/table/table.module.less new file mode 100644 index 0000000..bfd2b0b --- /dev/null +++ b/src/components/table/table.module.less @@ -0,0 +1,36 @@ +.content{ + table { + border-collapse: collapse; + width:100%; + } + + th, td { + text-align: left; + padding:8px; + } + + th { + background-color: #f2f2f2; + } + + tr:nth-child(even) { + background-color: #f2f2f2; + } + + tr:hover { + background-color: #ddd; + } + + td:first-child, th:first-child { + border-left:1px solid #ddd; + } + + td:last-child, th:last-child { + border-right:1px solid #ddd; + } + + td, th { + border-top:1px solid #ddd; + border-bottom:1px solid #ddd; + } +} \ No newline at end of file diff --git a/src/components/table/table.tsx b/src/components/table/table.tsx index f357ad6..698a5b4 100644 --- a/src/components/table/table.tsx +++ b/src/components/table/table.tsx @@ -1,52 +1,146 @@ import React, { ReactElement, useMemo } from 'react'; - -interface IColProps { - key: string; +import styles from './table.module.less' + +interface Column { title: string; - render?(data: any): ReactElement -} - -interface ITableProps { - className?: string; - data: Array; - cols: Array -} - -export default function Table(props: ITableProps) { - const { data, cols, className } = props; - - const col = useMemo(() => { - return cols?.map(c => { - return
- }) - }, [cols]) - - return
- {c?.title} -
- - {col} - - - { - data?.map(d => { - return - {cols?.map(c => { - if (c.render) { - return - } - return - })} - - }) - } - -
- { - c.render(d) - } - - {d[c.key]} -
-} \ No newline at end of file + dataIndex: string; + } + + interface Props { + data: any[]; + columns: Column[]; + } + + enum SortOrder { + Ascending = "ascend", + Descending = "descend", + None = "none", + } + + interface State { + sortOrder: SortOrder; + sortColumn: string; + filteredData: any[]; + filterValues: { [key: string]: any }; + } + + export default class Table extends React.Component { + constructor(props: Props) { + super(props); + + this.state = { + sortOrder: SortOrder.None, + sortColumn: "", + filteredData: props.data, + filterValues: {}, + }; + } + + handleSort = (column: Column) => { + const { dataIndex } = column; + const { sortOrder, sortColumn } = this.state; + + let newSortOrder: SortOrder = SortOrder.Ascending; + if (sortColumn === dataIndex) { + newSortOrder = + sortOrder === SortOrder.Ascending + ? SortOrder.Descending + : SortOrder.Ascending; + } + + let newData = [...this.state.filteredData]; + if (newSortOrder !== SortOrder.None) { + newData = newData.sort((a, b) => + newSortOrder === SortOrder.Ascending + ? a[dataIndex] - b[dataIndex] + : b[dataIndex] - a[dataIndex] + ); + } + + this.setState({ + sortOrder: newSortOrder, + sortColumn: dataIndex, + filteredData: newData, + }); + }; + + handleFilter = (column: Column, value: any) => { + const { dataIndex } = column; + const { filterValues } = this.state; + + const newFilterValues = { ...filterValues, [dataIndex]: value }; + + let newData = [...this.props.data]; + Object.keys(newFilterValues).forEach((key) => { + const filterValue = newFilterValues[key]; + if (filterValue !== null && filterValue !== undefined) { + newData = newData.filter( + (item) => item[key].toString() === filterValue.toString() + ); + } + }); + + this.setState({ + filteredData: newData, + filterValues: newFilterValues, + }); + }; + + render() { + const { columns } = this.props; + const { sortOrder, sortColumn, filteredData, filterValues } = this.state; + + return ( +
+ + + + {columns.map((column) => ( + + ))} + + + + {filteredData.map((item, index) => ( + + {columns.map((column) => ( + + ))} + + ))} + +
+ {column.title} + + +
{item[column.dataIndex]}
+ ); + } + } \ No newline at end of file