5 changed files with 0 additions and 315 deletions
			
			
		| @ -1,114 +0,0 @@ | |||
| import React, { useState, useEffect } from 'react' | |||
| // import DataList from './dataList'
 | |||
| import Simple from './simple' | |||
| import styles from './index.module.less' | |||
| 
 | |||
| const previewComplex = (data: any) => { | |||
|   if (Array.isArray(data)) { | |||
|     return <span>Array[{data.length}]</span> | |||
|   } | |||
|   switch (typeof data) { | |||
|     case 'function': | |||
|       return <span>{data.name || 'fn'}()</span> | |||
|     case 'object': | |||
|     case 'undefined': | |||
|     case null: | |||
|       return '{…}' | |||
|   } | |||
|   return null | |||
| } | |||
| 
 | |||
| interface Props { | |||
|   startOpen?: boolean | |||
|   noSort?: boolean | |||
|   name: string | |||
|   value: any | |||
| } | |||
| 
 | |||
| interface State { | |||
|   open: boolean | |||
|   loading?: boolean | |||
| } | |||
| 
 | |||
| const DataItem: React.FC<Props> = (props) => { | |||
|   const [state, setState] = useState<State>({ open: !!props.startOpen, loading: false }) | |||
|   let opener = null | |||
|   let children = null | |||
|   let { name } = props | |||
|   let preview | |||
| 
 | |||
|   useEffect(() => { | |||
|     if (state.open && props.value) { | |||
|       setState({ loading: true, open: true }) | |||
|     } | |||
|   }, []) | |||
| 
 | |||
|   useEffect(() => { | |||
|     const data = props.value | |||
|     const otype = typeof data | |||
|     let complex = true | |||
| 
 | |||
|     if ( | |||
|       otype === 'number' || | |||
|       otype === 'string' || | |||
|       data == null || | |||
|       otype === 'boolean' | |||
|     ) { | |||
|       preview = <Simple data={data} /> | |||
|       complex = false | |||
|     } else { | |||
|       preview = previewComplex(data) | |||
|     } | |||
| 
 | |||
|     const open = state.open | |||
| 
 | |||
|     if (complex && Object.keys(props.value).length) { | |||
|       opener = ( | |||
|         <div onClick={toggleOpen()} className={styles.opener}> | |||
|           {open ? | |||
|             <span className={styles.openerOpen} /> : | |||
|             <span className={styles.openerClose} /> | |||
|           } | |||
|         </div> | |||
|       ) | |||
|     } | |||
| 
 | |||
|     // if (complex && open) {
 | |||
|     //   children = <DataList data={data} />
 | |||
|     // }
 | |||
| 
 | |||
|     if (name.length > 50) { | |||
|       name = name.slice(0, 50) + '…' | |||
|     } | |||
|   }, [props]) | |||
| 
 | |||
|   const toggleOpen = () => { | |||
|     return () => { | |||
|       const data = props.value | |||
|       const isArray = Array.isArray(data) | |||
| 
 | |||
|       if (state.loading) return | |||
|       if (!isArray && !Object.keys(props.value).length) return | |||
|       if (isArray && data.length === 0) return | |||
| 
 | |||
|       setState({ | |||
|         open: !state.open | |||
|       }) | |||
|     } | |||
|   } | |||
| 
 | |||
|   return ( | |||
|     <li className={styles.codeWrap}> | |||
|       <div className={styles.codeBox}> | |||
|         {opener} | |||
|         <div onClick={toggleOpen()} className={styles.codeKey}> | |||
|           {name ? `${name}:` : ''} | |||
|         </div> | |||
|         <div className={styles.codeVal}>{preview}</div> | |||
|       </div> | |||
|       {children} | |||
|     </li> | |||
|   ) | |||
| } | |||
| 
 | |||
| export default DataItem | |||
| @ -1,64 +0,0 @@ | |||
| import React, { useState, useEffect } from 'react' | |||
| import DataItem from './dataItem' | |||
| import styles from './index.module.less' | |||
| 
 | |||
| interface DataListProps { | |||
|   data: any | |||
|   startOpen?: boolean | |||
|   noSort?: boolean | |||
| } | |||
| 
 | |||
| const alphanumericSort = (a: string, b: string): number => { | |||
|   if ('' + +a === a) { | |||
|     if ('' + +b !== b) { | |||
|       return -1 | |||
|     } | |||
|     return +a < +b ? -1 : 1 | |||
|   } | |||
|   return a < b ? -1 : 1 | |||
| } | |||
| 
 | |||
| const DataList: React.FC<DataListProps> = (props) => { | |||
|   const [element, setElement] = useState<any[]>([]) | |||
|   const renderItem = (name: string, key: string) => { | |||
|     const data = props.data | |||
|     return ( | |||
|       <DataItem | |||
|         key={key} | |||
|         name={name} | |||
|         startOpen={props.startOpen} | |||
|         value={data[name]} | |||
|       /> | |||
|     ) | |||
|   } | |||
| 
 | |||
|   useEffect(() => { | |||
|     const { data } = props | |||
|     if (!data) return | |||
| 
 | |||
|     const isArray = Array.isArray(data) | |||
|     const ele: any[] = [] | |||
|     if (isArray) { | |||
|       data.forEach((item: any, i: number) => { | |||
|         ele.push(renderItem(String(i), String(i))) | |||
|       }) | |||
|     } else { | |||
|       const names = Object.keys(data) | |||
|       if (!props.noSort) { | |||
|         names.sort(alphanumericSort) | |||
|       } | |||
|       names.forEach((name, i) => { | |||
|         ele.push(renderItem(name, name)) | |||
|       }) | |||
|     } | |||
|     setElement(ele) | |||
|   }) | |||
| 
 | |||
|   return ( | |||
|     !element.length ? | |||
|       <div>{Array.isArray(props.data) ? 'Empty array' : 'Empty object'}</div> : | |||
|       <ul className={styles.codeContainer}>{element}</ul> | |||
|   ) | |||
| } | |||
| 
 | |||
| export default DataList | |||
| @ -1,48 +0,0 @@ | |||
| .codeContainer { | |||
|   padding: 10px; | |||
|   font-size: 12px; | |||
|   list-style: none; | |||
|   margin: 0; | |||
|   padding: 0; | |||
| } | |||
| 
 | |||
| .codeBox { | |||
|   display: flex; | |||
|   position: relative; | |||
| } | |||
| 
 | |||
| .codeVal { | |||
|   display: flex; | |||
|   white-space: pre; | |||
|   word-break: break-word; | |||
|   margin-left: 10px; | |||
|   flex: 1; | |||
|   color: #183691; | |||
| } | |||
| 
 | |||
| .codeKey { | |||
|   margin-left: 5px; | |||
|   color: #905; | |||
| } | |||
| 
 | |||
| .opener { | |||
|   cursor: pointer; | |||
|   margin-left: -10px; | |||
|   position: absolute; | |||
| } | |||
| 
 | |||
| .openerOpen { | |||
|   border-color: #bbb transparent transparent transparent; | |||
|   border-style: solid; | |||
|   border-width: 6px 4px 0 4px; | |||
|   display: inline-block; | |||
|   vertical-align: middle; | |||
| } | |||
| 
 | |||
| .openerClose { | |||
|   border-color: transparent transparent transparent #bbb; | |||
|   border-style: solid; | |||
|   border-width: 4px 0 4px 6px; | |||
|   display: inline-block; | |||
|   vertical-align: middle; | |||
| } | |||
| @ -1,61 +0,0 @@ | |||
| import React, { useState, useEffect } from 'react' | |||
| import DataList from './dataList' | |||
| import styles from './index.module.less' | |||
| 
 | |||
| interface DataViewProps { | |||
|   data: any | |||
|   startOpen?: boolean | |||
| } | |||
| 
 | |||
| interface State { | |||
|   open: boolean | |||
| } | |||
| 
 | |||
| const DataView: React.FC<DataViewProps> = (props) => { | |||
|   const [state, setState] = useState<State>({ open: !!props.startOpen }) | |||
|   let children = null | |||
|   let preview | |||
| 
 | |||
|   const toggleOpen = () => { | |||
|     return () => { | |||
|       setState({ | |||
|         open: !state.open | |||
|       }) | |||
|     } | |||
|   } | |||
| 
 | |||
|   useEffect(() => { | |||
|     const { data } = props | |||
|     const { open } = state | |||
|     if (!data) { | |||
|       return | |||
|     } | |||
|     const isArray = Array.isArray(data) | |||
|     children = open ? <DataList data={data} /> : null | |||
|     if (isArray) { | |||
|       preview = '[...]' | |||
|     } else { | |||
|       preview = '{...}' | |||
|     } | |||
|   }, [props]) | |||
| 
 | |||
|   return ( | |||
|     <ul className={styles.codeContainer}> | |||
|       <li className={styles.codeWrap}> | |||
|         <div className={styles.codeBox}> | |||
|           <div onClick={toggleOpen()} className={styles.opener}> | |||
|             {state.open ? ( | |||
|               <span className={styles.openerOpen} /> | |||
|             ) : ( | |||
|                 <span className={styles.openerClose} /> | |||
|               )} | |||
|           </div> | |||
|           <div className={styles.codeVal}>{preview}</div> | |||
|         </div> | |||
|         {children} | |||
|       </li> | |||
|     </ul> | |||
|   ) | |||
| } | |||
| 
 | |||
| export default DataView | |||
| @ -1,28 +0,0 @@ | |||
| import React, { useState, useEffect } from 'react' | |||
| 
 | |||
| interface Props { | |||
|   data: any | |||
| } | |||
| 
 | |||
| const Simple: React.FC<Props> = (props) => { | |||
|   const [data, setData] = useState(props.data) | |||
| 
 | |||
|   const valueToText = (value: any) => { | |||
|     if (value === undefined) { | |||
|       return 'undefined' | |||
|     } else if (typeof value === 'number') { | |||
|       return value.toString() | |||
|     } | |||
|     return JSON.stringify(value) | |||
|   } | |||
| 
 | |||
|   useEffect(() => { | |||
|     if (typeof data === 'string' && data.length > 200) { | |||
|       setData(data.slice(0, 200) + '…') | |||
|     } | |||
|   }, [props]) | |||
| 
 | |||
|   return <div style={{ color: '#333' }}>{valueToText(data)}</div> | |||
| } | |||
| 
 | |||
| export default Simple | |||
					Loading…
					
					
				
		Reference in new issue