www/components/lists.tsx

108 lines
2.8 KiB
TypeScript
Raw Normal View History

2022-04-24 00:35:53 +00:00
import style from '../styles/lists.module.css';
import React, { ReactElement } from 'react';
export interface listItem {
[x: string]: any;
2022-04-24 00:35:53 +00:00
children?: listItem[] | string[];
url?: string;
type?: string;
2022-04-24 00:35:53 +00:00
title: string;
description?: string;
};
export function toListItem(record: Record<string, any>): listItem | null {
if (!record.title)
return null;
let children: listItem[] | string[] = [];
if (Array.isArray(record.children) && record.children.length) {
let lchildren: listItem[] = [];
let schildren: string[] = [];
for (const child of record.children) {
if (typeof child === 'string') {
schildren.push(child);
continue;
}
const lChild = toListItem(child);
if (lChild)
lchildren.push(lChild);
}
if (!lchildren.length) {
children = schildren;
}
else {
children = [...lchildren, ...schildren.map((s: string): listItem => {
2022-04-24 00:35:53 +00:00
return { title: s };
})];
2022-04-24 00:35:53 +00:00
}
}
return Object.assign(record, {
2022-04-24 00:35:53 +00:00
title: record.title,
url: record.url,
children: children.length ? children : undefined,
type: record.type?.length ? record.type : undefined,
2022-04-24 00:35:53 +00:00
description: record.description,
});
2022-04-24 00:35:53 +00:00
}
const s = {
"af": 123,
"asdf" : 123
}
export function mapChild(
obj: listItem | string,
level: number,
typeMap? : Record<string, (o: listItem) => JSX.Element>
) {
2022-04-24 00:35:53 +00:00
if (typeof obj === 'string') {
if (obj === '')
return <></>
return <span className={style.listItem}>{obj}</span>
}
if (obj.title === '')
return <></>
2022-04-27 09:36:54 +00:00
const desc = obj.description
? <span className={style.listItemDesc}>{obj.description}</span>
: <></>;
2022-04-24 00:35:53 +00:00
if (obj.url)
2022-04-27 09:36:54 +00:00
return (
<>
<span className={style.listItem}><a href={obj.url}>{obj.title}</a></span>
{desc}
</>);
2022-04-24 00:35:53 +00:00
if (!obj.children) {
let cb;
if (obj.type && typeMap) {
cb = typeMap[obj.type]
}
return cb
? cb(obj)
: (<><span className={style.listItem}>{obj.title}</span>{desc}</>);
}
2022-04-24 00:35:53 +00:00
let title: ReactElement;
if (level >= 0 && level <= 4)
title = React.createElement(`h${level + 2}`, {}, obj.title);
else
title = React.createElement('strong', {}, obj.title);
return (
2022-04-28 01:55:18 +00:00
<section className={level < 4 && `block ${style.block}` || ''}>
2022-04-24 00:35:53 +00:00
{title}
2022-04-27 09:36:54 +00:00
{obj.description ? <p className={style.desc}>{obj.description}</p> : <></>}
2022-04-24 00:35:53 +00:00
<div>
{obj.children.map(l => mapChild(l, level + 1, typeMap))}
2022-04-24 00:35:53 +00:00
</div>
2022-04-27 09:10:49 +00:00
</section>
2022-04-24 00:35:53 +00:00
);
}