Tree Sorting
Sort tree rows in ascending or descending order by providing a single sort function or an array of sort dimensions to the hook.
Note
Tree data sorting provides the same capabilities as client row sorting. Review the Client Row Sorting guide before proceeding.
Sort Function
In the tree data source, the sort function compares two row nodes.
Each node is a group row node unless it’s pinned.
The demo below shows basic sorting. Click Sort: Size to sort rows by Size in descending order.
Tree Sort Function
1import "@1771technologies/lytenyte-pro/light-dark.css";2import { Grid, useTreeDataSource } from "@1771technologies/lytenyte-pro";3import { data } from "./tree.js";4import { AvatarCell, GroupCell, ModifiedCell, SizeCell } from "./components.jsx";5import { useState } from "react";6
7export interface GridSpec {8 readonly data: {9 kind: string;10 name: string;11 size: number;12 modified: string;13 lastEditedBy: string;14 permissions: string;15 };16}17
18const group: Grid.RowGroupColumn<GridSpec> = {19 width: 240,20 cellRenderer: GroupCell,21 pin: "start",22};23
24const columns: Grid.Column<GridSpec>[] = [25 { id: "size", type: "number", name: "Size", cellRenderer: SizeCell },26 { id: "modified", name: "Modified", cellRenderer: ModifiedCell, width: 130 },27 { id: "lastEditedBy", name: "Last Edited By", cellRenderer: AvatarCell },28 { id: "permissions", name: "Permissions" },29];30
31const base: Grid.ColumnBase<GridSpec> = { widthFlex: 1, width: 120 };32
33const sortBySize: Grid.T.SortFn<GridSpec["data"]> = (left, right) => {34 const leftData = left.data.size as number | null;35 const rightData = right.data.size as number | null;36
37 if (left == null && right == null) return 0;38 else if (left == null && right != null) return 1;39 else if (left != null && right == null) return -1;40 else {41 return rightData! - leftData!;42 }43};44
45export default function TreeDataDemo() {46 const [sort, setSort] = useState<Grid.T.SortFn<any> | null>(null);47
48 const ds = useTreeDataSource({49 data: data,50 rowGroupDefaultExpansion: true,51 sort,52
53 rowChildrenFn: (x: any) => {54 if (!x.children) return [];55 return x.children.map((r: any) => [r.name, r]);56 },57 rowValueFn: (x) => ({58 name: x.name,59 kind: x.kind,60 size: x.size || null,61 modified: x.modified,62 lastEditedBy: x.lastEditedBy,63 permissions: x.permissions,64 }),65 });66
67 return (68 <>69 <div className="border-ln-border flex gap-4 border-b px-4 py-3">70 <button71 data-ln-button="website"72 data-ln-size="md"73 onClick={() => {74 setSort(() => sortBySize);75 }}76 >77 Sort: Size78 </button>79 <button80 data-ln-button="website"81 data-ln-size="md"82 onClick={() => {83 setSort(null);84 }}85 >86 Clear Sort87 </button>88 </div>89 <div className="ln-grid" style={{ height: 500 }}>90 <Grid rowSource={ds} rowGroupColumn={group} columnBase={base} columns={columns} />91 </div>92 </>93 );94}1import "@1771technologies/lytenyte-pro/components.css";2import type { Grid } from "@1771technologies/lytenyte-pro";3import type { GridSpec } from "./demo.jsx";4import {5 ComponentsFolderClose,6 ComponentsFolderOpen,7 ConfigFolderClosed,8 ConfigFolderOpen,9 CSSIcon,10 DocumentIcon,11 DotFile,12 FolderBaseOpen,13 FolderIcon,14 GitIcon,15 HooksFolderClosedIcon,16 HooksFolderOpenIcon,17 HtmlIcon,18 IcoIcon,19 ImageIcon,20 JSIcon,21 JSONIcon,22 JSXIcon,23 MarkdownIcon,24 PublicFolderClosed,25 PublicFolderOpen,26 SrcFolderClosed,27 SrcFolderOpen,28 SvgIcon,29 TestsFolderClosed,30 TestsFolderOpen,31 TestsIcon,32 UtilsFolderClosedIcon,33 UtilsFolderOpenIcon,34} from "./icons.jsx";35import { useMemo } from "react";36import { format } from "date-fns";37import { customerToAvatar } from "@1771technologies/grid-sample-data/orders";38
39export function GroupCell({ api, row }: Grid.T.CellRendererParams<GridSpec>) {40 const expanded = api.rowIsGroup(row) && row.expandable && row.expanded;41 const expandable = api.rowIsGroup(row) && row.expandable;42 const name = api.rowIsGroup(row) ? (row.key ?? "") : ((row.data.name as string) ?? "");43
44 const Icon = useMemo(() => {45 if (name.includes(".test")) return TestsIcon;46 if (name.includes(".git")) return GitIcon;47 if (name.includes(".env")) return DotFile;48
49 if (name === "public") return expanded ? PublicFolderOpen : PublicFolderClosed;50
51 if (name === "src") return expanded ? SrcFolderOpen : SrcFolderClosed;52 if (name === "utils") return expanded ? UtilsFolderOpenIcon : UtilsFolderClosedIcon;53 if (name === "components") return expanded ? ComponentsFolderOpen : ComponentsFolderClose;54 if (name === "tests") return expanded ? TestsFolderOpen : TestsFolderClosed;55 if (name === "hooks") return expanded ? HooksFolderOpenIcon : HooksFolderClosedIcon;56 if (name === "config") return expanded ? ConfigFolderOpen : ConfigFolderClosed;57
58 if (name.endsWith(".jsx")) return JSXIcon;59 if (name.endsWith(".js")) return JSIcon;60 if (name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg")) return ImageIcon;61 if (name.endsWith(".json")) return JSONIcon;62 if (name.endsWith(".md") || name.endsWith(".mdx")) return MarkdownIcon;63 if (name.endsWith(".html")) return HtmlIcon;64 if (name.endsWith(".ico")) return IcoIcon;65 if (name.endsWith(".svg")) return SvgIcon;66 if (name.endsWith(".css")) return CSSIcon;67
68 if (name.includes(".") || !expandable) return DocumentIcon;69 return expanded ? FolderBaseOpen : FolderIcon;70 }, [expandable, expanded, name]);71
72 return (73 <div74 className="relative flex h-full w-full items-center text-sm"75 style={{ paddingInlineStart: row.depth * 22 }}76 >77 {row.depth > 0 &&78 Array.from({ length: row.depth }, (_, i) => {79 return (80 <div81 key={i}82 className="border-ln-gray-30 absolute h-full border-s border-dashed"83 style={{ left: i === 0 ? 16 : i * 16 + 16 + i * 6 }}84 />85 );86 })}87 {expandable && (88 <button89 onClick={() => api.rowGroupToggle(row.id)}90 data-ln-button="secondary"91 data-ln-size="md"92 data-ln-icon93 >94 <Icon className="size-4" />95 </button>96 )}97 {!expandable && (98 <div className="flex size-8 items-center justify-center">99 <Icon className="size-4" />100 </div>101 )}102 <div>{name}</div>103 </div>104 );105}106
107const number = new Intl.NumberFormat("en-US", { maximumFractionDigits: 0, minimumFractionDigits: 0 });108
109export function SizeCell({ api, column, row }: Grid.T.CellRendererParams<GridSpec>) {110 if (!api.rowIsGroup(row)) return null;111
112 const field = api.columnField(column, row);113
114 if (typeof field !== "number") return "-";115
116 return (117 <div className="flex items-baseline gap-1 tabular-nums">118 {number.format(field)}119 <span className="text-ln-text-xlight text-xs font-semibold">kb</span>120 </div>121 );122}123
124export function ModifiedCell({ api, column, row }: Grid.T.CellRendererParams<GridSpec>) {125 if (!api.rowIsGroup(row)) return;126
127 const field = api.columnField(column, row);128
129 if (typeof field !== "string") return "-";130
131 return <div className="text-sm tabular-nums">{format(field, "yyyy MMM dd | hh:mm")}</div>;132}133
134export function AvatarCell({ api, row, column }: Grid.T.CellRendererParams<GridSpec>) {135 if (!api.rowIsGroup(row)) return;136
137 const name = api.columnField(column, row);138
139 if (typeof name !== "string") return;140 const url = customerToAvatar[name];141
142 return (143 <div className="flex h-full w-full items-center gap-2">144 <img className="border-ln-border-strong h-7 w-7 rounded-full border" src={url} alt={name} />145 <div className="text-ln-text-dark flex flex-col gap-0.5">146 <div>{name}</div>147 </div>148 </div>149 );150}1import React from "react";2import type { SVGProps } from "react";3
4export function ImageIcon(props: SVGProps<SVGSVGElement>) {5 return (6 <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} viewBox="0 0 16 16" {...props}>7 <path8 fill="#26a69a"9 d="M8.5 6h4l-4-4zM3.875 1H9.5l4 4v8.6c0 .773-.616 1.4-1.375 1.4h-8.25c-.76 0-1.375-.627-1.375-1.4V2.4c0-.777.612-1.4 1.375-1.4M4 13.6h8V8l-2.625 2.8L8 9.4zm1.25-7.7c-.76 0-1.375.627-1.375 1.4s.616 1.4 1.375 1.4c.76 0 1.375-.627 1.375-1.4S6.009 5.9 5.25 5.9"10 ></path>11 </svg>12 );13}14
15export function FolderIcon(props: SVGProps<SVGSVGElement>) {16 return (17 <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} viewBox="0 0 32 32" {...props}>18 <path19 fill="#8d6e63"20 d="m13.844 7.536l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464"21 ></path>22 <rect width={18} height={6} x={14} y={22} fill="#d7ccc8" rx={1}></rect>23 </svg>24 );25}26
27export function FolderBaseOpen(props: SVGProps<SVGSVGElement>) {28 return (29 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>30 <path31 fill="#8d6e63"32 d="M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12"33 ></path>34 <rect width={18} height={6} x={14} y={22} fill="#d7ccc8" rx={1}></rect>35 </svg>36 );37}38
39export function DocumentIcon(props: SVGProps<SVGSVGElement>) {40 return (41 <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} viewBox="0 0 24 24" {...props}>42 <g fill="none">43 <path d="M0 0h24v24H0z"></path>44 <path45 fill="#42a5f5"46 d="M8 16h8v2H8zm0-4h8v2H8zm6-10H6c-1.1 0-2 .9-2 2v16c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8zm4 18H6V4h7v5h5z"47 ></path>48 </g>49 </svg>50 );51}52
53export function JSONIcon(props: SVGProps<SVGSVGElement>) {54 return (55 <svg xmlns="http://www.w3.org/2000/svg" width={960} height={960} viewBox="0 -960 960 960" {...props}>56 <path57 fill="#f9a825"58 d="M560-160v-80h120q17 0 28.5-11.5T720-280v-80q0-38 22-69t58-44v-14q-36-13-58-44t-22-69v-80q0-17-11.5-28.5T680-720H560v-80h120q50 0 85 35t35 85v80q0 17 11.5 28.5T840-560h40v160h-40q-17 0-28.5 11.5T800-360v80q0 50-35 85t-85 35zm-280 0q-50 0-85-35t-35-85v-80q0-17-11.5-28.5T120-400H80v-160h40q17 0 28.5-11.5T160-600v-80q0-50 35-85t85-35h120v80H280q-17 0-28.5 11.5T240-680v80q0 38-22 69t-58 44v14q36 13 58 44t22 69v80q0 17 11.5 28.5T280-240h120v80z"59 ></path>60 </svg>61 );62}63
64export function MarkdownIcon(props: SVGProps<SVGSVGElement>) {65 return (66 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>67 <path fill="#ffca28" d="m14 10l-4 3.5L6 10H4v12h4v-6l2 2l2-2v6h4V10zm12 6v-6h-4v6h-4l6 8l6-8z"></path>68 </svg>69 );70}71
72export function HtmlIcon(props: SVGProps<SVGSVGElement>) {73 return (74 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>75 <path76 fill="#e65100"77 d="m4 4l2 22l10 2l10-2l2-22Zm19.72 7H11.28l.29 3h11.86l-.802 9.335L15.99 25l-6.635-1.646L8.93 19h3.02l.19 2l3.86.77l3.84-.77l.29-4H8.84L8 8h16Z"78 ></path>79 </svg>80 );81}82
83export function IcoIcon(props: SVGProps<SVGSVGElement>) {84 return (85 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>86 <path fill="#ffd54f" d="m16 24l10 6l-4-10l8-8l-10-.032L16 2l-4 10H2l8 8l-4 10Z"></path>87 </svg>88 );89}90
91export function SvgIcon(props: SVGProps<SVGSVGElement>) {92 return (93 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>94 <path95 fill="#ffb300"96 d="M29.168 14.03a2.7 2.7 0 0 0-1.968-.83a2.51 2.51 0 0 0-1.929.8h-4.443l3.078-3.078a2.835 2.835 0 0 0 2.857-2.842a2.6 2.6 0 0 0-.831-1.969a2.82 2.82 0 0 0-2.014-.788a2.67 2.67 0 0 0-1.968.788a2.36 2.36 0 0 0-.812 1.922L18 11.17V6.726a2.51 2.51 0 0 0 .8-1.929a2.7 2.7 0 0 0-.832-1.968a2.745 2.745 0 0 0-3.936 0a2.7 2.7 0 0 0-.832 1.968a2.51 2.51 0 0 0 .8 1.93v4.443l-3.138-3.138a2.36 2.36 0 0 0-.812-1.922a2.66 2.66 0 0 0-1.968-.788a2.83 2.83 0 0 0-2.014.788a2.6 2.6 0 0 0-.831 1.969a2.74 2.74 0 0 0 .831 2.013a2.8 2.8 0 0 0 2.026.829l3.078 3.078H6.729a2.51 2.51 0 0 0-1.929-.8a2.7 2.7 0 0 0-1.968.831a2.745 2.745 0 0 0 0 3.937a2.7 2.7 0 0 0 1.968.832a2.51 2.51 0 0 0 1.929-.8h4.443l-3.078 3.077a2.835 2.835 0 0 0-2.857 2.842a2.6 2.6 0 0 0 .831 1.969a2.82 2.82 0 0 0 2.014.788a2.67 2.67 0 0 0 1.968-.788a2.36 2.36 0 0 0 .812-1.922L14 20.827v4.444a2.51 2.51 0 0 0-.8 1.929a2.784 2.784 0 0 0 4.768 1.968A2.7 2.7 0 0 0 18.8 27.2a2.51 2.51 0 0 0-.8-1.929v-4.444l3.138 3.138a2.36 2.36 0 0 0 .812 1.922a2.66 2.66 0 0 0 1.968.788a2.83 2.83 0 0 0 2.014-.788a2.6 2.6 0 0 0 .831-1.969a2.74 2.74 0 0 0-.831-2.013a2.8 2.8 0 0 0-2.026-.829L20.828 18h4.443a2.51 2.51 0 0 0 1.93.8a2.784 2.784 0 0 0 1.967-4.769Z"97 ></path>98 </svg>99 );100}101
102export function PublicFolderClosed(props: SVGProps<SVGSVGElement>) {103 return (104 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>105 <path106 fill="#039be5"107 d="m13.844 7.536l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464"108 ></path>109 <path110 fill="#b3e5fc"111 d="M22 10a10 10 0 1 0 10 10a10 10 0 0 0-10-10m6.918 6H25.96a15.8 15.8 0 0 0-1.342-3.54a8.04 8.04 0 0 1 4.3 3.54M22 12a14.1 14.1 0 0 1 1.89 4h-3.78A14.1 14.1 0 0 1 22 12m-2.618.46A15.8 15.8 0 0 0 18.04 16h-2.958a8.04 8.04 0 0 1 4.3-3.54M14.263 22a7.7 7.7 0 0 1 0-4h3.407a15.5 15.5 0 0 0 0 4Zm.82 2h2.957a15.8 15.8 0 0 0 1.342 3.54a8.04 8.04 0 0 1-4.3-3.54ZM22 28a14.1 14.1 0 0 1-1.89-4h3.78A14.1 14.1 0 0 1 22 28m2.31-6h-4.62a13.4 13.4 0 0 1 0-4h4.62a13.4 13.4 0 0 1 0 4m.308 5.54A15.8 15.8 0 0 0 25.96 24h2.958a8.04 8.04 0 0 1-4.3 3.54M29.737 22H26.33a15.5 15.5 0 0 0 0-4h3.407a7.7 7.7 0 0 1 0 4"112 ></path>113 </svg>114 );115}116
117export function PublicFolderOpen(props: SVGProps<SVGSVGElement>) {118 return (119 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>120 <path121 fill="#039be5"122 d="M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12"123 ></path>124 <path125 fill="#b3e5fc"126 d="M22 10a10 10 0 1 0 10 10a10 10 0 0 0-10-10m6.918 6H25.96a15.8 15.8 0 0 0-1.342-3.54a8.04 8.04 0 0 1 4.3 3.54M22 12a14.1 14.1 0 0 1 1.89 4h-3.78A14.1 14.1 0 0 1 22 12m-2.618.46A15.8 15.8 0 0 0 18.04 16h-2.958a8.04 8.04 0 0 1 4.3-3.54M14.263 22a7.7 7.7 0 0 1 0-4h3.407a15.5 15.5 0 0 0 0 4Zm.82 2h2.957a15.8 15.8 0 0 0 1.342 3.54a8.04 8.04 0 0 1-4.3-3.54ZM22 28a14.1 14.1 0 0 1-1.89-4h3.78A14.1 14.1 0 0 1 22 28m2.31-6h-4.62a13.4 13.4 0 0 1 0-4h4.62a13.4 13.4 0 0 1 0 4m.308 5.54A15.8 15.8 0 0 0 25.96 24h2.958a8.04 8.04 0 0 1-4.3 3.54M29.737 22H26.33a15.5 15.5 0 0 0 0-4h3.407a7.7 7.7 0 0 1 0 4"127 ></path>128 </svg>129 );130}131
132export function ComponentsFolderClose(props: SVGProps<SVGSVGElement>) {133 return (134 <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} viewBox="0 0 16 16" {...props}>135 <path136 fill="#00bcd4"137 d="m6.922 3.768l-.644-.536A1 1 0 0 0 5.638 3H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H7.562a1 1 0 0 1-.64-.232"138 ></path>139 <g fill="#b2ebf2">140 <path d="M10.5 8.399c2.924 0 4.714 1.037 4.714 1.6s-1.79 1.602-4.714 1.602S5.785 10.564 5.785 10s1.79-1.601 4.715-1.601m0-.8c-3.038 0-5.5 1.075-5.5 2.4s2.462 2.402 5.5 2.402S16 11.326 16 10s-2.463-2.401-5.5-2.401"></path>141 <path d="M10.5 9.2a.786.8 0 1 0 .785.8a.786.8 0 0 0-.785-.8"></path>142 <path d="M8.322 5.8c.793 0 2.333 1.272 3.538 3.4c1.463 2.58 1.476 4.677.997 4.959a.354.36 0 0 1-.18.04c-.792 0-2.333-1.271-3.538-3.399c-1.463-2.58-1.476-4.677-.997-4.96a.354.36 0 0 1 .18-.04m0-.8a1.128 1.149 0 0 0-.572.147c-1.128.663-.81 3.374.708 6.054C9.748 13.478 11.491 15 12.678 15a1.128 1.149 0 0 0 .572-.148c1.127-.663.81-3.373-.71-6.053C11.25 6.522 9.509 5 8.323 5Z"></path>143 <path d="M12.677 5.8a.354.36 0 0 1 .18.04c.48.283.466 2.38-.997 4.96c-1.206 2.128-2.746 3.4-3.538 3.4a.354.36 0 0 1-.18-.04c-.48-.284-.466-2.38.997-4.96c1.206-2.128 2.746-3.4 3.538-3.4m0-.8c-1.186 0-2.929 1.522-4.22 3.8c-1.517 2.68-1.835 5.39-.707 6.052a1.128 1.149 0 0 0 .572.148c1.186 0 2.929-1.523 4.22-3.8c1.517-2.68 1.835-5.39.708-6.052A1.128 1.149 0 0 0 12.677 5"></path>144 </g>145 </svg>146 );147}148
149export function ComponentsFolderOpen(props: SVGProps<SVGSVGElement>) {150 return (151 <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} viewBox="0 0 16 16" {...props}>152 <path153 fill="#00bcd4"154 d="M14.484 6H4.72a1 1 0 0 0-.949.684L2 12V5h13a1 1 0 0 0-1-1H7.562a1 1 0 0 1-.64-.232l-.644-.536A1 1 0 0 0 5.638 3H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h11l2.403-5.606A1 1 0 0 0 14.483 6"155 ></path>156 <g fill="#b2ebf2">157 <path d="M10.5 8.399c2.924 0 4.714 1.037 4.714 1.6s-1.79 1.602-4.714 1.602S5.785 10.564 5.785 10s1.79-1.601 4.715-1.601m0-.8c-3.038 0-5.5 1.075-5.5 2.4s2.462 2.402 5.5 2.402S16 11.326 16 10s-2.463-2.401-5.5-2.401"></path>158 <path d="M10.5 9.2a.786.8 0 1 0 .785.8a.786.8 0 0 0-.785-.8"></path>159 <path d="M8.322 5.8c.793 0 2.333 1.272 3.538 3.4c1.463 2.58 1.476 4.677.997 4.959a.354.36 0 0 1-.18.04c-.792 0-2.333-1.271-3.538-3.399c-1.463-2.58-1.476-4.677-.997-4.96a.354.36 0 0 1 .18-.04m0-.8a1.128 1.149 0 0 0-.572.147c-1.128.663-.81 3.374.708 6.054C9.748 13.478 11.491 15 12.678 15a1.128 1.149 0 0 0 .572-.148c1.127-.663.81-3.373-.71-6.053C11.25 6.522 9.509 5 8.323 5Z"></path>160 <path d="M12.677 5.8a.354.36 0 0 1 .18.04c.48.283.466 2.38-.997 4.96c-1.206 2.128-2.746 3.4-3.538 3.4a.354.36 0 0 1-.18-.04c-.48-.284-.466-2.38.997-4.96c1.206-2.128 2.746-3.4 3.538-3.4m0-.8c-1.186 0-2.929 1.522-4.22 3.8c-1.517 2.68-1.835 5.39-.707 6.052a1.128 1.149 0 0 0 .572.148c1.186 0 2.929-1.523 4.22-3.8c1.517-2.68 1.835-5.39.708-6.052A1.128 1.149 0 0 0 12.677 5"></path>161 </g>162 </svg>163 );164}165
166export function CSSIcon(props: SVGProps<SVGSVGElement>) {167 return (168 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>169 <path170 fill="#7e57c2"171 d="M20 18h-2v-2h-2v2c0 .193 0 .703 1.254 1.033A3.345 3.345 0 0 1 20 22h2v2h2v-2c0-.388-.562-.851-1.254-1.034C20.356 20.34 20 18.84 20 18m-3.254 2.966C14.356 20.34 14 18.84 14 18h-2v-2h-2v8h2v-2h4v2h2v-2c0-.388-.562-.851-1.254-1.034"172 ></path>173 <path174 fill="#7e57c2"175 d="M24 4H4v20a4 4 0 0 0 4 4h16.16A3.84 3.84 0 0 0 28 24.16V8a4 4 0 0 0-4-4m2 14h-2v-2h-2v2c0 .193 0 .703 1.254 1.033A3.345 3.345 0 0 1 26 22v2a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2Z"176 ></path>177 </svg>178 );179}180
181export function SrcFolderClosed(props: SVGProps<SVGSVGElement>) {182 return (183 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>184 <path185 fill="#4caf50"186 d="m13.844 7.536l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464"187 ></path>188 <path189 fill="#c8e6c9"190 d="M18.435 30a1 1 0 0 1-.238-.028a1.137 1.137 0 0 1-.828-1.323l3.093-15.744a1.13 1.13 0 0 1 .507-.744a1.06 1.06 0 0 1 .8-.134a1.14 1.14 0 0 1 .828 1.324l-3.1 15.744a1.12 1.12 0 0 1-.505.743a1.06 1.06 0 0 1-.557.162m6.2-2h-.077a1.08 1.08 0 0 1-.762-.412a1.164 1.164 0 0 1 .113-1.548l5.32-4.967l-5.297-4.623a1.165 1.165 0 0 1-.162-1.544a1.08 1.08 0 0 1 .754-.437a1.06 1.06 0 0 1 .81.258l6.244 5.455a1.156 1.156 0 0 1 .004 1.723l-6.22 5.808a1.07 1.07 0 0 1-.728.289Zm-9.31 0a1.07 1.07 0 0 1-.728-.292l-6.225-5.811a1.16 1.16 0 0 1-.01-1.692l.02-.018l6.246-5.454a1.03 1.03 0 0 1 .8-.26a1.08 1.08 0 0 1 .758.436a1.165 1.165 0 0 1-.16 1.547l-5.293 4.62l5.32 4.964a1.156 1.156 0 0 1 .112 1.548a1.07 1.07 0 0 1-.762.412Z"191 ></path>192 </svg>193 );194}195
196export function SrcFolderOpen(props: SVGProps<SVGSVGElement>) {197 return (198 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>199 <path200 fill="#4caf50"201 d="M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12"202 ></path>203 <path204 fill="#c8e6c9"205 d="M18.473 30a1 1 0 0 1-.238-.028a1.137 1.137 0 0 1-.828-1.323L20.5 12.905a1.13 1.13 0 0 1 .507-.744a1.06 1.06 0 0 1 .8-.134a1.14 1.14 0 0 1 .828 1.324l-3.101 15.744a1.12 1.12 0 0 1-.504.743a1.06 1.06 0 0 1-.557.162m6.2-2h-.077a1.08 1.08 0 0 1-.762-.412a1.164 1.164 0 0 1 .113-1.548l5.319-4.967l-5.296-4.623a1.165 1.165 0 0 1-.162-1.544a1.08 1.08 0 0 1 .754-.437a1.06 1.06 0 0 1 .81.258l6.244 5.455a1.156 1.156 0 0 1 .003 1.723l-6.218 5.808a1.07 1.07 0 0 1-.729.289Zm-9.31 0a1.07 1.07 0 0 1-.728-.292l-6.226-5.811a1.16 1.16 0 0 1-.01-1.692l.02-.018l6.246-5.454a1.03 1.03 0 0 1 .8-.26a1.08 1.08 0 0 1 .76.436a1.165 1.165 0 0 1-.16 1.547l-5.294 4.62l5.32 4.964a1.156 1.156 0 0 1 .112 1.548a1.07 1.07 0 0 1-.762.412Z"206 ></path>207 </svg>208 );209}210
211export function JSXIcon(props: SVGProps<SVGSVGElement>) {212 return (213 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>214 <path215 fill="#0288d1"216 d="M16 12c7.444 0 12 2.59 12 4s-4.556 4-12 4s-12-2.59-12-4s4.556-4 12-4m0-2c-7.732 0-14 2.686-14 6s6.268 6 14 6s14-2.686 14-6s-6.268-6-14-6"217 ></path>218 <path fill="#0288d1" d="M16 14a2 2 0 1 0 2 2a2 2 0 0 0-2-2"></path>219 <path220 fill="#0288d1"221 d="M10.458 5.507c2.017 0 5.937 3.177 9.006 8.493c3.722 6.447 3.757 11.687 2.536 12.392a.9.9 0 0 1-.457.1c-2.017 0-5.938-3.176-9.007-8.492C8.814 11.553 8.779 6.313 10 5.608a.9.9 0 0 1 .458-.1m-.001-2A2.87 2.87 0 0 0 9 3.875C6.13 5.532 6.938 12.304 10.804 19c3.284 5.69 7.72 9.493 10.74 9.493A2.87 2.87 0 0 0 23 28.124c2.87-1.656 2.062-8.428-1.804-15.124c-3.284-5.69-7.72-9.493-10.74-9.493Z"222 ></path>223 <path224 fill="#0288d1"225 d="M21.543 5.507a.9.9 0 0 1 .457.1c1.221.706 1.186 5.946-2.536 12.393c-3.07 5.316-6.99 8.493-9.007 8.493a.9.9 0 0 1-.457-.1C8.779 25.686 8.814 20.446 12.536 14c3.07-5.316 6.99-8.493 9.007-8.493m0-2c-3.02 0-7.455 3.804-10.74 9.493C6.939 19.696 6.13 26.468 9 28.124a2.87 2.87 0 0 0 1.457.369c3.02 0 7.455-3.804 10.74-9.493C25.061 12.304 25.87 5.532 23 3.876a2.87 2.87 0 0 0-1.457-.369"226 ></path>227 </svg>228 );229}230
231export function JSIcon(props: SVGProps<SVGSVGElement>) {232 return (233 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>234 <path235 fill="#8bc34a"236 d="M16 20.003v2h4a2 2 0 0 0 2-2v-2a2 2 0 0 0-2-2h-2v-2h4v-2h-4a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h2v2Z"237 ></path>238 <path239 fill="#8bc34a"240 d="m16 3.003l-12 7v14l4 2h6v-13.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v11.5H8l-2-1.034V11.15l10-5.833l10 5.833v11.703l-10 5.833l-1.745-1.022L13 29.253l3 1.75l12-7v-14Z"241 ></path>242 </svg>243 );244}245
246export function TestsFolderClosed(props: SVGProps<SVGSVGElement>) {247 return (248 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>249 <path250 fill="#00bfa5"251 d="m13.844 7.536l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464"252 ></path>253 <path254 fill="#a7ffeb"255 d="M16 12v2h2v12a4 4 0 0 0 8 0V14h2v-2Zm5 14a1 1 0 1 1 1-1a1 1 0 0 1-1 1m2-4a1 1 0 1 1 1-1a1 1 0 0 1-1 1m1-4h-4v-4h4Z"256 ></path>257 </svg>258 );259}260
261export function TestsFolderOpen(props: SVGProps<SVGSVGElement>) {262 return (263 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>264 <path265 fill="#00bfa5"266 d="M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12"267 ></path>268 <path269 fill="#a7ffeb"270 d="M16 12v2h2v12a4 4 0 0 0 8 0V14h2v-2Zm5 14a1 1 0 1 1 1-1a1 1 0 0 1-1 1m2-4a1 1 0 1 1 1-1a1 1 0 0 1-1 1m1-4h-4v-4h4Z"271 ></path>272 </svg>273 );274}275
276export function TestsIcon(props: SVGProps<SVGSVGElement>) {277 return (278 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>279 <path280 fill="#0288d1"281 d="M20 4v2h-2v4.531l.264.461l7.473 13.078a2 2 0 0 1 .263.992V26a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2v-.938a2 2 0 0 1 .264-.992l7.473-13.078l.263-.46V6h-2V4zm0-2h-8a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2v2L4.527 23.078A4 4 0 0 0 4 25.062V26a4 4 0 0 0 4 4h16a4 4 0 0 0 4-4v-.938a4 4 0 0 0-.527-1.984L20 10V8a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2"282 ></path>283 <circle cx={17} cy={17} r={1} fill="#0288d1"></circle>284 <path285 fill="#0288d1"286 d="M19.72 20.715a1 1 0 0 0-1.134-.318a5 5 0 0 1-1.18.262a3.95 3.95 0 0 1-1.862-.292a2.74 2.74 0 0 0-3.371.489a2 2 0 0 0-.237.35L10 24h12Z"287 ></path>288 </svg>289 );290}291
292export function ConfigFolderClosed(props: SVGProps<SVGSVGElement>) {293 return (294 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>295 <path296 fill="#00acc1"297 d="m13.844 7.536l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464"298 ></path>299 <path300 fill="#80deea"301 d="M23.001 24.15A3.195 3.195 0 0 1 19.762 21a3.24 3.24 0 1 1 3.239 3.15m6.875-2.277a7 7 0 0 0 .064-.874a8 8 0 0 0-.064-.9l1.951-1.467a.446.446 0 0 0 .113-.576l-1.853-3.112a.46.46 0 0 0-.564-.199l-2.302.9a6.8 6.8 0 0 0-1.565-.882l-.342-2.385A.464.464 0 0 0 24.85 12h-3.7a.464.464 0 0 0-.463.378l-.341 2.385a6.8 6.8 0 0 0-1.563.881l-2.304-.899a.46.46 0 0 0-.564.198l-1.851 3.113a.436.436 0 0 0 .112.576l1.95 1.468a8 8 0 0 0-.064.9a7 7 0 0 0 .064.873l-1.95 1.493a.436.436 0 0 0-.112.576l1.85 3.115a.47.47 0 0 0 .565.198l2.304-.91a6.4 6.4 0 0 0 1.563.892l.342 2.385a.464.464 0 0 0 .463.378h3.7a.464.464 0 0 0 .464-.378l.34-2.385a6.8 6.8 0 0 0 1.566-.891l2.302.909a.475.475 0 0 0 .566-.198l1.85-3.115a.446.446 0 0 0-.112-.576Z"302 ></path>303 </svg>304 );305}306
307export function ConfigFolderOpen(props: SVGProps<SVGSVGElement>) {308 return (309 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>310 <path311 fill="#00acc1"312 d="M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12"313 ></path>314 <path315 fill="#80deea"316 d="M23.001 24.15A3.195 3.195 0 0 1 19.762 21a3.24 3.24 0 1 1 3.239 3.15m6.875-2.277a7 7 0 0 0 .064-.874a8 8 0 0 0-.064-.9l1.951-1.467a.446.446 0 0 0 .113-.576l-1.853-3.112a.46.46 0 0 0-.564-.199l-2.302.9a6.8 6.8 0 0 0-1.565-.882l-.342-2.385A.464.464 0 0 0 24.85 12h-3.7a.464.464 0 0 0-.463.378l-.341 2.385a6.8 6.8 0 0 0-1.563.881l-2.304-.899a.46.46 0 0 0-.564.198l-1.851 3.113a.436.436 0 0 0 .112.576l1.95 1.468a8 8 0 0 0-.064.9a7 7 0 0 0 .064.873l-1.95 1.493a.436.436 0 0 0-.112.576l1.85 3.115a.47.47 0 0 0 .565.198l2.304-.91a6.4 6.4 0 0 0 1.563.892l.342 2.385a.464.464 0 0 0 .463.378h3.7a.464.464 0 0 0 .464-.378l.34-2.385a6.8 6.8 0 0 0 1.566-.891l2.302.909a.475.475 0 0 0 .566-.198l1.85-3.115a.446.446 0 0 0-.112-.576Z"317 ></path>318 </svg>319 );320}321
322export function UtilsFolderClosedIcon(props: SVGProps<SVGSVGElement>) {323 return (324 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>325 <path326 fill="#7cb342"327 d="m13.844 7.536l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464"328 ></path>329 <path330 fill="#dcedc8"331 d="M31 12H19a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V13a1 1 0 0 0-1-1m-1 8h-4v4h-2v-4h-4v-2h4v-4h2v4h4Z"332 ></path>333 <path fill="#dcedc8" d="M16 28V16h-2v13a1 1 0 0 0 1 1h13v-2Z"></path>334 </svg>335 );336}337
338export function UtilsFolderOpenIcon(props: SVGProps<SVGSVGElement>) {339 return (340 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>341 <path342 fill="#7cb342"343 d="M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12"344 ></path>345 <path346 fill="#dcedc8"347 d="M31 12H19a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V13a1 1 0 0 0-1-1m-1 8h-4v4h-2v-4h-4v-2h4v-4h2v4h4Z"348 ></path>349 <path fill="#dcedc8" d="M16 28V16h-2v13a1 1 0 0 0 1 1h13v-2Z"></path>350 </svg>351 );352}353
354export function HooksFolderClosedIcon(props: SVGProps<SVGSVGElement>) {355 return (356 <svg xmlns="http://www.w3.org/2000/svg" width={1024} height={1024} viewBox="0 0 1024 1024" {...props}>357 <path358 fill="#7e57c2"359 d="m443.008 241.152l-41.216-34.304A64 64 0 0 0 360.832 192H128a64 64 0 0 0-64 64v512a64 64 0 0 0 64 64h768a64 64 0 0 0 64-64V320a64 64 0 0 0-64-64H483.968a64 64 0 0 1-40.96-14.848"360 ></path>361 <path362 fill="#d1c4e9"363 d="M800 320c-53.02 0-96 42.98-96 96c.104 40.593 25.729 76.733 64 90.264V768c0 35.346-28.654 64-64 64s-64-28.654-64-64v-64h64L576 576v192c0 70.692 57.308 128 128 128s128-57.308 128-128V506.264c38.271-13.531 63.896-49.671 64-90.264c0-53.02-42.98-96-96-96m0 64c17.673 0 32 14.327 32 32s-14.327 32-32 32s-32-14.327-32-32s14.327-32 32-32"364 ></path>365 </svg>366 );367}368
369export function HooksFolderOpenIcon(props: SVGProps<SVGSVGElement>) {370 return (371 <svg xmlns="http://www.w3.org/2000/svg" width={1024} height={1024} viewBox="0 0 1024 1024" {...props}>372 <path373 fill="#7e57c2"374 d="M926.944 384h-624.8a64 64 0 0 0-60.736 43.776L128 768V320h768a64 64 0 0 0-64-64H483.968a64 64 0 0 1-40.96-14.848l-41.216-34.304A64 64 0 0 0 360.832 192H128a64 64 0 0 0-64 64v512a64 64 0 0 0 64 64h704l153.76-358.784A64 64 0 0 0 926.944 384"375 ></path>376 <path377 fill="#d1c4e9"378 d="M800 320c-53.02 0-96 42.98-96 96c.104 40.593 25.729 76.733 64 90.264V768c0 35.346-28.654 64-64 64s-64-28.654-64-64v-64h64L576 576v192c0 70.692 57.308 128 128 128s128-57.308 128-128V506.264c38.271-13.531 63.896-49.671 64-90.264c0-53.02-42.98-96-96-96m0 64c17.673 0 32 14.327 32 32s-14.327 32-32 32s-32-14.327-32-32s14.327-32 32-32"379 ></path>380 </svg>381 );382}383
384export function GitIcon(props: SVGProps<SVGSVGElement>) {385 return (386 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>387 <path388 fill="#e64a19"389 d="M13.172 2.828L11.78 4.22l1.91 1.91l2 2A2.986 2.986 0 0 1 20 10.81a3.25 3.25 0 0 1-.31 1.31l2.06 2a2.68 2.68 0 0 1 3.37.57a2.86 2.86 0 0 1 .88 2.117a3.02 3.02 0 0 1-.856 2.109A2.9 2.9 0 0 1 23 19.81a2.93 2.93 0 0 1-2.13-.87a2.694 2.694 0 0 1-.56-3.38l-2-2.06a3 3 0 0 1-.31.12V20a3 3 0 0 1 1.44 1.09a2.92 2.92 0 0 1 .56 1.72a2.88 2.88 0 0 1-.878 2.128a2.98 2.98 0 0 1-2.048.871a2.981 2.981 0 0 1-2.514-4.719A3 3 0 0 1 16 20v-6.38a2.96 2.96 0 0 1-1.44-1.09a2.9 2.9 0 0 1-.56-1.72a2.9 2.9 0 0 1 .31-1.31l-3.9-3.9l-7.579 7.572a4 4 0 0 0-.001 5.658l10.342 10.342a4 4 0 0 0 5.656 0l10.344-10.344a4 4 0 0 0 0-5.656L18.828 2.828a4 4 0 0 0-5.656 0"390 ></path>391 </svg>392 );393}394
395export function DotFile(props: SVGProps<SVGSVGElement>) {396 return (397 <svg xmlns="http://www.w3.org/2000/svg" width={400} height={400} viewBox="0 0 400 400" {...props}>398 <g fill="#2196f3" fillOpacity={0.604} transform="translate(-6.66 100.49)">399 <ellipse400 cx={37.18}401 cy={-256.97}402 rx={110.14}403 ry={139.47}404 transform="matrix(-.3005 .95378 -.96071 -.27755 0 0)"405 ></ellipse>406 <ellipse407 cx={38.835}408 cy={-197.03}409 rx={110.14}410 ry={139.47}411 transform="matrix(-.3005 .95378 -.96071 -.27755 0 0)"412 ></ellipse>413 <ellipse414 cx={-224.78}415 cy={-5.066}416 rx={110.14}417 ry={139.47}418 transform="matrix(-.95378 -.3005 .27755 -.96071 0 0)"419 ></ellipse>420 <ellipse421 cx={-228.55}422 cy={-60.291}423 rx={110.14}424 ry={139.47}425 transform="matrix(-.95378 -.3005 .27755 -.96071 0 0)"426 ></ellipse>427 </g>428 </svg>429 );430}1export const data = {2 root: {3 name: "root",4 kind: "folder",5 size: 0,6 modified: "2026-01-22T09:00:00Z",7 children: [8 {9 name: "package.json",10 kind: "file",11 size: 1840,12 modified: "2026-01-21T18:12:00Z",13 lastEditedBy: "Joseph Allen",14 permissions: "rw-r--r--",15 },16 {17 name: "package-lock.json",18 kind: "file",19 size: 92000,20 modified: "2026-01-21T18:12:30Z",21 lastEditedBy: "Joseph Allen",22 permissions: "rw-r--r--",23 },24 {25 name: "README.md",26 kind: "file",27 size: 1240,28 modified: "2026-01-20T10:05:00Z",29 lastEditedBy: "Betty Hall",30 permissions: "rw-r--r--",31 },32 {33 name: ".gitignore",34 kind: "file",35 size: 180,36 modified: "2026-01-19T09:00:00Z",37 lastEditedBy: "Betty Hall",38 permissions: "rw-r--r--",39 },40 {41 name: ".env",42 kind: "file",43 size: 220,44 modified: "2026-01-21T08:30:00Z",45 lastEditedBy: "Nancy Lewis",46 permissions: "rw-------",47 },48
49 {50 name: "public",51 kind: "folder",52 size: 0,53 modified: "2026-01-18T12:00:00Z",54 children: [55 {56 name: "index.html",57 kind: "file",58 size: 3420,59 modified: "2026-01-18T12:01:00Z",60 lastEditedBy: "Charles Clark",61 permissions: "rw-r--r--",62 },63 {64 name: "favicon.ico",65 kind: "file",66 size: 5430,67 modified: "2026-01-18T12:01:30Z",68 lastEditedBy: "Charles Clark",69 permissions: "rw-r--r--",70 },71 {72 name: "manifest.json",73 kind: "file",74 size: 820,75 modified: "2026-01-18T12:02:00Z",76 lastEditedBy: "Charles Clark",77 permissions: "rw-r--r--",78 },79 {80 name: "assets",81 kind: "folder",82 size: 0,83 modified: "2026-01-17T15:40:00Z",84 children: [85 {86 name: "logo.svg",87 kind: "file",88 size: 2048,89 modified: "2026-01-17T15:42:00Z",90 lastEditedBy: "Richard White",91 permissions: "rw-r--r--",92 },93 {94 name: "hero.png",95 kind: "file",96 size: 482000,97 modified: "2026-01-17T15:45:00Z",98 lastEditedBy: "Richard White",99 permissions: "rw-r--r--",100 },101 ],102 },103 ],104 },105
106 {107 name: "src",108 kind: "folder",109 size: 0,110 modified: "2026-01-22T08:30:00Z",111 children: [112 {113 name: "assets",114 kind: "folder",115 size: 0,116 modified: "2026-01-20T14:00:00Z",117 children: [118 {119 name: "global.css",120 kind: "file",121 size: 2140,122 modified: "2026-01-20T14:05:00Z",123 lastEditedBy: "Jennifer Taylor",124 permissions: "rw-r--r--",125 },126 {127 name: "variables.css",128 kind: "file",129 size: 980,130 modified: "2026-01-20T14:04:00Z",131 lastEditedBy: "Jennifer Taylor",132 permissions: "rw-r--r--",133 },134 ],135 },136
137 {138 name: "components",139 kind: "folder",140 size: 0,141 modified: "2026-01-21T09:30:00Z",142 children: [143 {144 name: "Button",145 kind: "folder",146 size: 0,147 modified: "2026-01-21T09:31:00Z",148 children: [149 {150 name: "Button.jsx",151 kind: "file",152 size: 1620,153 modified: "2026-01-21T09:35:00Z",154 lastEditedBy: "Sarah Wilson",155 permissions: "rw-r--r--",156 },157 {158 name: "Button.module.css",159 kind: "file",160 size: 740,161 modified: "2026-01-21T09:34:00Z",162 lastEditedBy: "Sarah Wilson",163 permissions: "rw-r--r--",164 },165 {166 name: "Button.test.jsx",167 kind: "file",168 size: 1280,169 modified: "2026-01-21T09:36:00Z",170 lastEditedBy: "Joseph Allen",171 permissions: "rw-r--r--",172 },173 ],174 },175
176 {177 name: "Modal",178 kind: "folder",179 size: 0,180 modified: "2026-01-21T11:10:00Z",181 children: [182 {183 name: "Modal.jsx",184 kind: "file",185 size: 1980,186 modified: "2026-01-21T11:15:00Z",187 lastEditedBy: "Nancy Lewis",188 permissions: "rw-r--r--",189 },190 {191 name: "Modal.css",192 kind: "file",193 size: 860,194 modified: "2026-01-21T11:14:00Z",195 lastEditedBy: "Nancy Lewis",196 permissions: "rw-r--r--",197 },198 ],199 },200 ],201 },202
203 {204 name: "hooks",205 kind: "folder",206 size: 0,207 modified: "2026-01-19T16:00:00Z",208 children: [209 {210 name: "useAuth.js",211 kind: "file",212 size: 1320,213 modified: "2026-01-19T16:05:00Z",214 lastEditedBy: "Betty Hall",215 permissions: "rw-r--r--",216 },217 {218 name: "useFetch.js",219 kind: "file",220 size: 1740,221 modified: "2026-01-19T16:06:00Z",222 lastEditedBy: "Betty Hall",223 permissions: "rw-r--r--",224 },225 ],226 },227
228 {229 name: "context",230 kind: "folder",231 size: 0,232 modified: "2026-01-20T10:40:00Z",233 children: [234 {235 name: "AuthContext.jsx",236 kind: "file",237 size: 1560,238 modified: "2026-01-20T10:42:00Z",239 lastEditedBy: "Jennifer Taylor",240 permissions: "rw-r--r--",241 },242 ],243 },244
245 {246 name: "services",247 kind: "folder",248 size: 0,249 modified: "2026-01-20T11:30:00Z",250 children: [251 {252 name: "api.js",253 kind: "file",254 size: 980,255 modified: "2026-01-20T11:32:00Z",256 lastEditedBy: "Charles Clark",257 permissions: "rw-r--r--",258 },259 {260 name: "authService.js",261 kind: "file",262 size: 1420,263 modified: "2026-01-20T11:33:00Z",264 lastEditedBy: "Charles Clark",265 permissions: "rw-r--r--",266 },267 ],268 },269
270 {271 name: "utils",272 kind: "folder",273 size: 0,274 modified: "2026-01-19T15:10:00Z",275 children: [276 {277 name: "constants.js",278 kind: "file",279 size: 540,280 modified: "2026-01-19T15:12:00Z",281 lastEditedBy: "Richard White",282 permissions: "rw-r--r--",283 },284 {285 name: "formatDate.js",286 kind: "file",287 size: 620,288 modified: "2026-01-19T15:11:00Z",289 lastEditedBy: "Richard White",290 permissions: "rw-r--r--",291 },292 ],293 },294
295 {296 name: "routes.jsx",297 kind: "file",298 size: 1240,299 modified: "2026-01-22T08:10:00Z",300 lastEditedBy: "Sarah Wilson",301 permissions: "rw-r--r--",302 },303 {304 name: "App.jsx",305 kind: "file",306 size: 2140,307 modified: "2026-01-22T08:20:00Z",308 lastEditedBy: "Sarah Wilson",309 permissions: "rw-r--r--",310 },311 {312 name: "main.jsx",313 kind: "file",314 size: 860,315 modified: "2026-01-22T08:25:00Z",316 lastEditedBy: "Sarah Wilson",317 permissions: "rw-r--r--",318 },319 ],320 },321
322 {323 name: "tests",324 kind: "folder",325 size: 0,326 modified: "2026-01-21T13:00:00Z",327 children: [328 {329 name: "setupTests.js",330 kind: "file",331 size: 520,332 modified: "2026-01-21T13:01:00Z",333 lastEditedBy: "Joseph Allen",334 permissions: "rw-r--r--",335 },336 {337 name: "App.test.jsx",338 kind: "file",339 size: 1620,340 modified: "2026-01-21T13:02:00Z",341 lastEditedBy: "Joseph Allen",342 permissions: "rw-r--r--",343 },344 ],345 },346
347 {348 name: "config",349 kind: "folder",350 size: 0,351 modified: "2026-01-18T17:00:00Z",352 children: [353 {354 name: "vite.config.js",355 kind: "file",356 size: 1120,357 modified: "2026-01-18T17:02:00Z",358 lastEditedBy: "Betty Hall",359 permissions: "rw-r--r--",360 },361 {362 name: "eslint.config.js",363 kind: "file",364 size: 980,365 modified: "2026-01-18T17:01:00Z",366 lastEditedBy: "Betty Hall",367 permissions: "rw-r--r--",368 },369 ],370 },371 ],372 },373};Sort Dimensions
You can set the sort property to an array of DimensionSort objects. Each
dimension sort uses the field property of a column to compare rows.
A dimension can be applied to sort rows in ascending or descending order.
Since the hook receives an array of DimensionSort objects, LyteNyte Grid can perform a multi-way sort.
The tree data source applies the comparators in the order they appear in the provided array,
stopping when a comparator result is not 0.
The demo below shows dimension sorting. Click a column header to sort. To sort by multiple columns, hold Control or Command and click additional headers.
Tree Sort Dimensions
1import "@1771technologies/lytenyte-pro/light-dark.css";2import { computeField, Grid, useTreeDataSource } from "@1771technologies/lytenyte-pro";3import { data } from "./tree.js";4import { AvatarCell, GroupCell, Header, ModifiedCell, SizeCell } from "./components.jsx";5import { useMemo, useState } from "react";6
7export interface GridSpec {8 readonly data: {9 kind: string;10 name: string;11 size: number;12 modified: string;13 lastEditedBy: string;14 permissions: string;15 };16 readonly column: { sort?: "asc" | "desc"; sortIndex?: number };17 readonly api: {18 sortColumn: (id: string, dir: "asc" | "desc" | null, additive?: boolean) => void;19 };20}21
22const initialColumns: Grid.Column<GridSpec>[] = [23 { id: "name", name: "Group", cellRenderer: GroupCell, width: 240, pin: "start" },24 { id: "size", type: "number", name: "Size", cellRenderer: SizeCell },25 { id: "modified", name: "Modified", cellRenderer: ModifiedCell, width: 130 },26 { id: "lastEditedBy", name: "Last Edited By", cellRenderer: AvatarCell },27 { id: "permissions", name: "Permissions" },28];29
30const base: Grid.ColumnBase<GridSpec> = { widthFlex: 1, width: 120, headerRenderer: Header };31
32export default function TreeDataDemo() {33 const [columns, setColumns] = useState(initialColumns);34
35 const sortDimension = useMemo(() => {36 const sorts = columns.filter((x) => x.sort).sort((l, r) => (l.sortIndex ?? 0) - (r.sortIndex ?? 0));37
38 return sorts.map((columnWithSort) => {39 return {40 dim: {41 ...columnWithSort,42 field: (p) => {43 const value = computeField(columnWithSort.id ?? columnWithSort.field, p.row);44 if (typeof value === "string") return value.toLowerCase();45 return value;46 },47 },48 descending: columnWithSort.sort === "desc",49 } satisfies Grid.T.DimensionSort<GridSpec["data"]>;50 });51 }, [columns]);52
53 const apiExtension = useMemo<GridSpec["api"]>(() => {54 return {55 sortColumn: (id, dir, additive) => {56 setColumns((prev) => {57 const nextIndex = Math.max(0, ...prev.map((x) => x.sortIndex ?? 0));58
59 const updated = prev.map((x) => {60 let next = x;61 // Remove any existing sort when we are performing a non-additive sort.62 if (x.sort && x.id !== id && !additive) {63 next = { ...x };64 delete next.sort;65 delete next.sortIndex;66 } else if (x.id === id) {67 next = { ...x };68 if (dir == null) {69 delete next.sort;70 delete next.sortIndex;71 } else {72 // We are adding a new sort73 next.sort = dir;74 if (additive && next.sortIndex == null) {75 next.sortIndex = nextIndex + 1;76 }77 }78 }79
80 return next;81 });82
83 // Ensures the sort index consistency84 const sortIndexEntries = updated85 .filter((x) => x.sort)86 .toSorted((l, r) => (l.sortIndex ?? 0) - (r.sortIndex ?? 0))87 .map((c, i) => [c.id, i + 1]);88 const newSortIndices = Object.fromEntries(sortIndexEntries);89
90 return updated.map((col) => {91 if (newSortIndices[col.id])92 return {93 ...col,94 // If we have only one sort there is no need for a sort index number.95 sortIndex: sortIndexEntries.length === 1 ? undefined : newSortIndices[col.id],96 };97 return col;98 });99 });100 },101 };102 }, []);103
104 const ds = useTreeDataSource({105 data: data,106 rowGroupDefaultExpansion: true,107 sort: sortDimension,108
109 rowChildrenFn: (x: any) => {110 if (!x.children) return [];111 return x.children.map((r: any) => [r.name, r]);112 },113 rowValueFn: (x) => ({114 name: x.name,115 kind: x.kind,116 size: x.size || null,117 modified: x.modified,118 lastEditedBy: x.lastEditedBy,119 permissions: x.permissions,120 }),121 });122
123 return (124 <>125 <div className="ln-grid" style={{ height: 500 }}>126 <Grid127 apiExtension={apiExtension}128 rowSource={ds}129 rowGroupColumn={false}130 columnBase={base}131 columns={columns}132 events={{133 headerCell: {134 keyDown: ({ column, event: ev }) => {135 if (ev.key === "Enter") {136 const nextSort = column.sort === "asc" ? null : column.sort === "desc" ? "asc" : "desc";137 apiExtension.sortColumn(column.id, nextSort, ev.metaKey || ev.ctrlKey);138 }139 },140 },141 }}142 />143 </div>144 </>145 );146}1import "@1771technologies/lytenyte-pro/components.css";2import type { Grid } from "@1771technologies/lytenyte-pro";3import type { GridSpec } from "./demo.jsx";4import {5 ComponentsFolderClose,6 ComponentsFolderOpen,7 ConfigFolderClosed,8 ConfigFolderOpen,9 CSSIcon,10 DocumentIcon,11 DotFile,12 FolderBaseOpen,13 FolderIcon,14 GitIcon,15 HooksFolderClosedIcon,16 HooksFolderOpenIcon,17 HtmlIcon,18 IcoIcon,19 ImageIcon,20 JSIcon,21 JSONIcon,22 JSXIcon,23 MarkdownIcon,24 PublicFolderClosed,25 PublicFolderOpen,26 SrcFolderClosed,27 SrcFolderOpen,28 SvgIcon,29 TestsFolderClosed,30 TestsFolderOpen,31 TestsIcon,32 UtilsFolderClosedIcon,33 UtilsFolderOpenIcon,34} from "./icons.jsx";35import { useMemo } from "react";36import { format } from "date-fns";37import { customerToAvatar } from "@1771technologies/grid-sample-data/orders";38import { ArrowDownIcon, ArrowUpIcon } from "@radix-ui/react-icons";39
40export function GroupCell({ api, row }: Grid.T.CellRendererParams<GridSpec>) {41 const expanded = api.rowIsGroup(row) && row.expandable && row.expanded;42 const expandable = api.rowIsGroup(row) && row.expandable;43 const name = api.rowIsGroup(row) ? (row.key ?? "") : ((row.data.name as string) ?? "");44
45 const Icon = useMemo(() => {46 if (name.includes(".test")) return TestsIcon;47 if (name.includes(".git")) return GitIcon;48 if (name.includes(".env")) return DotFile;49
50 if (name === "public") return expanded ? PublicFolderOpen : PublicFolderClosed;51
52 if (name === "src") return expanded ? SrcFolderOpen : SrcFolderClosed;53 if (name === "utils") return expanded ? UtilsFolderOpenIcon : UtilsFolderClosedIcon;54 if (name === "components") return expanded ? ComponentsFolderOpen : ComponentsFolderClose;55 if (name === "tests") return expanded ? TestsFolderOpen : TestsFolderClosed;56 if (name === "hooks") return expanded ? HooksFolderOpenIcon : HooksFolderClosedIcon;57 if (name === "config") return expanded ? ConfigFolderOpen : ConfigFolderClosed;58
59 if (name.endsWith(".jsx")) return JSXIcon;60 if (name.endsWith(".js")) return JSIcon;61 if (name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg")) return ImageIcon;62 if (name.endsWith(".json")) return JSONIcon;63 if (name.endsWith(".md") || name.endsWith(".mdx")) return MarkdownIcon;64 if (name.endsWith(".html")) return HtmlIcon;65 if (name.endsWith(".ico")) return IcoIcon;66 if (name.endsWith(".svg")) return SvgIcon;67 if (name.endsWith(".css")) return CSSIcon;68
69 if (name.includes(".") || !expandable) return DocumentIcon;70 return expanded ? FolderBaseOpen : FolderIcon;71 }, [expandable, expanded, name]);72
73 return (74 <div75 className="relative flex h-full w-full items-center text-sm"76 style={{ paddingInlineStart: row.depth * 22 }}77 >78 {row.depth > 0 &&79 Array.from({ length: row.depth }, (_, i) => {80 return (81 <div82 key={i}83 className="border-ln-gray-30 absolute h-full border-s border-dashed"84 style={{ left: i === 0 ? 16 : i * 16 + 16 + i * 6 }}85 />86 );87 })}88 {expandable && (89 <button90 onClick={() => api.rowGroupToggle(row.id)}91 data-ln-button="secondary"92 data-ln-size="md"93 data-ln-icon94 >95 <Icon className="size-4" />96 </button>97 )}98 {!expandable && (99 <div className="flex size-8 items-center justify-center">100 <Icon className="size-4" />101 </div>102 )}103 <div>{name}</div>104 </div>105 );106}107
108const number = new Intl.NumberFormat("en-US", { maximumFractionDigits: 0, minimumFractionDigits: 0 });109
110export function SizeCell({ api, column, row }: Grid.T.CellRendererParams<GridSpec>) {111 if (!api.rowIsGroup(row)) return null;112
113 const field = api.columnField(column, row);114
115 if (typeof field !== "number") return "-";116
117 return (118 <div className="flex items-baseline gap-1 tabular-nums">119 {number.format(field)}120 <span className="text-ln-text-xlight text-xs font-semibold">kb</span>121 </div>122 );123}124
125export function ModifiedCell({ api, column, row }: Grid.T.CellRendererParams<GridSpec>) {126 if (!api.rowIsGroup(row)) return;127
128 const field = api.columnField(column, row);129
130 if (typeof field !== "string") return "-";131
132 return <div className="text-sm tabular-nums">{format(field, "yyyy MMM dd | hh:mm")}</div>;133}134
135export function AvatarCell({ api, row, column }: Grid.T.CellRendererParams<GridSpec>) {136 if (!api.rowIsGroup(row)) return;137
138 const name = api.columnField(column, row);139
140 if (typeof name !== "string") return;141 const url = customerToAvatar[name];142
143 return (144 <div className="flex h-full w-full items-center gap-2">145 <img className="border-ln-border-strong h-7 w-7 rounded-full border" src={url} alt={name} />146 <div className="text-ln-text-dark flex flex-col gap-0.5">147 <div>{name}</div>148 </div>149 </div>150 );151}152
153export function Header({ api, column }: Grid.T.HeaderParams<GridSpec>) {154 return (155 <div156 className="group relative flex h-full w-full cursor-pointer items-center px-1 text-sm transition-colors"157 onClick={(ev) => {158 const nextSort = column.sort === "asc" ? null : column.sort === "desc" ? "asc" : "desc";159 api.sortColumn(column.id, nextSort, ev.metaKey || ev.ctrlKey);160 }}161 >162 <div className="sort-button flex w-full items-center justify-between rounded px-1 py-1 transition-colors">163 {column.name ?? column.id}164
165 <div className="relative">166 {column.sortIndex != null && (167 <span className="text-ln-primary-50 absolute -right-1.5 -top-1">{column.sortIndex}</span>168 )}169 {column.sort === "asc" && <ArrowUpIcon className="text-ln-text-dark size-4" />}170 {column.sort === "desc" && <ArrowDownIcon className="text-ln-text-dark size-4" />}171 </div>172 </div>173 </div>174 );175}1import React from "react";2import type { SVGProps } from "react";3
4export function ImageIcon(props: SVGProps<SVGSVGElement>) {5 return (6 <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} viewBox="0 0 16 16" {...props}>7 <path8 fill="#26a69a"9 d="M8.5 6h4l-4-4zM3.875 1H9.5l4 4v8.6c0 .773-.616 1.4-1.375 1.4h-8.25c-.76 0-1.375-.627-1.375-1.4V2.4c0-.777.612-1.4 1.375-1.4M4 13.6h8V8l-2.625 2.8L8 9.4zm1.25-7.7c-.76 0-1.375.627-1.375 1.4s.616 1.4 1.375 1.4c.76 0 1.375-.627 1.375-1.4S6.009 5.9 5.25 5.9"10 ></path>11 </svg>12 );13}14
15export function FolderIcon(props: SVGProps<SVGSVGElement>) {16 return (17 <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} viewBox="0 0 32 32" {...props}>18 <path19 fill="#8d6e63"20 d="m13.844 7.536l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464"21 ></path>22 <rect width={18} height={6} x={14} y={22} fill="#d7ccc8" rx={1}></rect>23 </svg>24 );25}26
27export function FolderBaseOpen(props: SVGProps<SVGSVGElement>) {28 return (29 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>30 <path31 fill="#8d6e63"32 d="M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12"33 ></path>34 <rect width={18} height={6} x={14} y={22} fill="#d7ccc8" rx={1}></rect>35 </svg>36 );37}38
39export function DocumentIcon(props: SVGProps<SVGSVGElement>) {40 return (41 <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} viewBox="0 0 24 24" {...props}>42 <g fill="none">43 <path d="M0 0h24v24H0z"></path>44 <path45 fill="#42a5f5"46 d="M8 16h8v2H8zm0-4h8v2H8zm6-10H6c-1.1 0-2 .9-2 2v16c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8zm4 18H6V4h7v5h5z"47 ></path>48 </g>49 </svg>50 );51}52
53export function JSONIcon(props: SVGProps<SVGSVGElement>) {54 return (55 <svg xmlns="http://www.w3.org/2000/svg" width={960} height={960} viewBox="0 -960 960 960" {...props}>56 <path57 fill="#f9a825"58 d="M560-160v-80h120q17 0 28.5-11.5T720-280v-80q0-38 22-69t58-44v-14q-36-13-58-44t-22-69v-80q0-17-11.5-28.5T680-720H560v-80h120q50 0 85 35t35 85v80q0 17 11.5 28.5T840-560h40v160h-40q-17 0-28.5 11.5T800-360v80q0 50-35 85t-85 35zm-280 0q-50 0-85-35t-35-85v-80q0-17-11.5-28.5T120-400H80v-160h40q17 0 28.5-11.5T160-600v-80q0-50 35-85t85-35h120v80H280q-17 0-28.5 11.5T240-680v80q0 38-22 69t-58 44v14q36 13 58 44t22 69v80q0 17 11.5 28.5T280-240h120v80z"59 ></path>60 </svg>61 );62}63
64export function MarkdownIcon(props: SVGProps<SVGSVGElement>) {65 return (66 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>67 <path fill="#ffca28" d="m14 10l-4 3.5L6 10H4v12h4v-6l2 2l2-2v6h4V10zm12 6v-6h-4v6h-4l6 8l6-8z"></path>68 </svg>69 );70}71
72export function HtmlIcon(props: SVGProps<SVGSVGElement>) {73 return (74 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>75 <path76 fill="#e65100"77 d="m4 4l2 22l10 2l10-2l2-22Zm19.72 7H11.28l.29 3h11.86l-.802 9.335L15.99 25l-6.635-1.646L8.93 19h3.02l.19 2l3.86.77l3.84-.77l.29-4H8.84L8 8h16Z"78 ></path>79 </svg>80 );81}82
83export function IcoIcon(props: SVGProps<SVGSVGElement>) {84 return (85 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>86 <path fill="#ffd54f" d="m16 24l10 6l-4-10l8-8l-10-.032L16 2l-4 10H2l8 8l-4 10Z"></path>87 </svg>88 );89}90
91export function SvgIcon(props: SVGProps<SVGSVGElement>) {92 return (93 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>94 <path95 fill="#ffb300"96 d="M29.168 14.03a2.7 2.7 0 0 0-1.968-.83a2.51 2.51 0 0 0-1.929.8h-4.443l3.078-3.078a2.835 2.835 0 0 0 2.857-2.842a2.6 2.6 0 0 0-.831-1.969a2.82 2.82 0 0 0-2.014-.788a2.67 2.67 0 0 0-1.968.788a2.36 2.36 0 0 0-.812 1.922L18 11.17V6.726a2.51 2.51 0 0 0 .8-1.929a2.7 2.7 0 0 0-.832-1.968a2.745 2.745 0 0 0-3.936 0a2.7 2.7 0 0 0-.832 1.968a2.51 2.51 0 0 0 .8 1.93v4.443l-3.138-3.138a2.36 2.36 0 0 0-.812-1.922a2.66 2.66 0 0 0-1.968-.788a2.83 2.83 0 0 0-2.014.788a2.6 2.6 0 0 0-.831 1.969a2.74 2.74 0 0 0 .831 2.013a2.8 2.8 0 0 0 2.026.829l3.078 3.078H6.729a2.51 2.51 0 0 0-1.929-.8a2.7 2.7 0 0 0-1.968.831a2.745 2.745 0 0 0 0 3.937a2.7 2.7 0 0 0 1.968.832a2.51 2.51 0 0 0 1.929-.8h4.443l-3.078 3.077a2.835 2.835 0 0 0-2.857 2.842a2.6 2.6 0 0 0 .831 1.969a2.82 2.82 0 0 0 2.014.788a2.67 2.67 0 0 0 1.968-.788a2.36 2.36 0 0 0 .812-1.922L14 20.827v4.444a2.51 2.51 0 0 0-.8 1.929a2.784 2.784 0 0 0 4.768 1.968A2.7 2.7 0 0 0 18.8 27.2a2.51 2.51 0 0 0-.8-1.929v-4.444l3.138 3.138a2.36 2.36 0 0 0 .812 1.922a2.66 2.66 0 0 0 1.968.788a2.83 2.83 0 0 0 2.014-.788a2.6 2.6 0 0 0 .831-1.969a2.74 2.74 0 0 0-.831-2.013a2.8 2.8 0 0 0-2.026-.829L20.828 18h4.443a2.51 2.51 0 0 0 1.93.8a2.784 2.784 0 0 0 1.967-4.769Z"97 ></path>98 </svg>99 );100}101
102export function PublicFolderClosed(props: SVGProps<SVGSVGElement>) {103 return (104 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>105 <path106 fill="#039be5"107 d="m13.844 7.536l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464"108 ></path>109 <path110 fill="#b3e5fc"111 d="M22 10a10 10 0 1 0 10 10a10 10 0 0 0-10-10m6.918 6H25.96a15.8 15.8 0 0 0-1.342-3.54a8.04 8.04 0 0 1 4.3 3.54M22 12a14.1 14.1 0 0 1 1.89 4h-3.78A14.1 14.1 0 0 1 22 12m-2.618.46A15.8 15.8 0 0 0 18.04 16h-2.958a8.04 8.04 0 0 1 4.3-3.54M14.263 22a7.7 7.7 0 0 1 0-4h3.407a15.5 15.5 0 0 0 0 4Zm.82 2h2.957a15.8 15.8 0 0 0 1.342 3.54a8.04 8.04 0 0 1-4.3-3.54ZM22 28a14.1 14.1 0 0 1-1.89-4h3.78A14.1 14.1 0 0 1 22 28m2.31-6h-4.62a13.4 13.4 0 0 1 0-4h4.62a13.4 13.4 0 0 1 0 4m.308 5.54A15.8 15.8 0 0 0 25.96 24h2.958a8.04 8.04 0 0 1-4.3 3.54M29.737 22H26.33a15.5 15.5 0 0 0 0-4h3.407a7.7 7.7 0 0 1 0 4"112 ></path>113 </svg>114 );115}116
117export function PublicFolderOpen(props: SVGProps<SVGSVGElement>) {118 return (119 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>120 <path121 fill="#039be5"122 d="M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12"123 ></path>124 <path125 fill="#b3e5fc"126 d="M22 10a10 10 0 1 0 10 10a10 10 0 0 0-10-10m6.918 6H25.96a15.8 15.8 0 0 0-1.342-3.54a8.04 8.04 0 0 1 4.3 3.54M22 12a14.1 14.1 0 0 1 1.89 4h-3.78A14.1 14.1 0 0 1 22 12m-2.618.46A15.8 15.8 0 0 0 18.04 16h-2.958a8.04 8.04 0 0 1 4.3-3.54M14.263 22a7.7 7.7 0 0 1 0-4h3.407a15.5 15.5 0 0 0 0 4Zm.82 2h2.957a15.8 15.8 0 0 0 1.342 3.54a8.04 8.04 0 0 1-4.3-3.54ZM22 28a14.1 14.1 0 0 1-1.89-4h3.78A14.1 14.1 0 0 1 22 28m2.31-6h-4.62a13.4 13.4 0 0 1 0-4h4.62a13.4 13.4 0 0 1 0 4m.308 5.54A15.8 15.8 0 0 0 25.96 24h2.958a8.04 8.04 0 0 1-4.3 3.54M29.737 22H26.33a15.5 15.5 0 0 0 0-4h3.407a7.7 7.7 0 0 1 0 4"127 ></path>128 </svg>129 );130}131
132export function ComponentsFolderClose(props: SVGProps<SVGSVGElement>) {133 return (134 <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} viewBox="0 0 16 16" {...props}>135 <path136 fill="#00bcd4"137 d="m6.922 3.768l-.644-.536A1 1 0 0 0 5.638 3H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H7.562a1 1 0 0 1-.64-.232"138 ></path>139 <g fill="#b2ebf2">140 <path d="M10.5 8.399c2.924 0 4.714 1.037 4.714 1.6s-1.79 1.602-4.714 1.602S5.785 10.564 5.785 10s1.79-1.601 4.715-1.601m0-.8c-3.038 0-5.5 1.075-5.5 2.4s2.462 2.402 5.5 2.402S16 11.326 16 10s-2.463-2.401-5.5-2.401"></path>141 <path d="M10.5 9.2a.786.8 0 1 0 .785.8a.786.8 0 0 0-.785-.8"></path>142 <path d="M8.322 5.8c.793 0 2.333 1.272 3.538 3.4c1.463 2.58 1.476 4.677.997 4.959a.354.36 0 0 1-.18.04c-.792 0-2.333-1.271-3.538-3.399c-1.463-2.58-1.476-4.677-.997-4.96a.354.36 0 0 1 .18-.04m0-.8a1.128 1.149 0 0 0-.572.147c-1.128.663-.81 3.374.708 6.054C9.748 13.478 11.491 15 12.678 15a1.128 1.149 0 0 0 .572-.148c1.127-.663.81-3.373-.71-6.053C11.25 6.522 9.509 5 8.323 5Z"></path>143 <path d="M12.677 5.8a.354.36 0 0 1 .18.04c.48.283.466 2.38-.997 4.96c-1.206 2.128-2.746 3.4-3.538 3.4a.354.36 0 0 1-.18-.04c-.48-.284-.466-2.38.997-4.96c1.206-2.128 2.746-3.4 3.538-3.4m0-.8c-1.186 0-2.929 1.522-4.22 3.8c-1.517 2.68-1.835 5.39-.707 6.052a1.128 1.149 0 0 0 .572.148c1.186 0 2.929-1.523 4.22-3.8c1.517-2.68 1.835-5.39.708-6.052A1.128 1.149 0 0 0 12.677 5"></path>144 </g>145 </svg>146 );147}148
149export function ComponentsFolderOpen(props: SVGProps<SVGSVGElement>) {150 return (151 <svg xmlns="http://www.w3.org/2000/svg" width={16} height={16} viewBox="0 0 16 16" {...props}>152 <path153 fill="#00bcd4"154 d="M14.484 6H4.72a1 1 0 0 0-.949.684L2 12V5h13a1 1 0 0 0-1-1H7.562a1 1 0 0 1-.64-.232l-.644-.536A1 1 0 0 0 5.638 3H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h11l2.403-5.606A1 1 0 0 0 14.483 6"155 ></path>156 <g fill="#b2ebf2">157 <path d="M10.5 8.399c2.924 0 4.714 1.037 4.714 1.6s-1.79 1.602-4.714 1.602S5.785 10.564 5.785 10s1.79-1.601 4.715-1.601m0-.8c-3.038 0-5.5 1.075-5.5 2.4s2.462 2.402 5.5 2.402S16 11.326 16 10s-2.463-2.401-5.5-2.401"></path>158 <path d="M10.5 9.2a.786.8 0 1 0 .785.8a.786.8 0 0 0-.785-.8"></path>159 <path d="M8.322 5.8c.793 0 2.333 1.272 3.538 3.4c1.463 2.58 1.476 4.677.997 4.959a.354.36 0 0 1-.18.04c-.792 0-2.333-1.271-3.538-3.399c-1.463-2.58-1.476-4.677-.997-4.96a.354.36 0 0 1 .18-.04m0-.8a1.128 1.149 0 0 0-.572.147c-1.128.663-.81 3.374.708 6.054C9.748 13.478 11.491 15 12.678 15a1.128 1.149 0 0 0 .572-.148c1.127-.663.81-3.373-.71-6.053C11.25 6.522 9.509 5 8.323 5Z"></path>160 <path d="M12.677 5.8a.354.36 0 0 1 .18.04c.48.283.466 2.38-.997 4.96c-1.206 2.128-2.746 3.4-3.538 3.4a.354.36 0 0 1-.18-.04c-.48-.284-.466-2.38.997-4.96c1.206-2.128 2.746-3.4 3.538-3.4m0-.8c-1.186 0-2.929 1.522-4.22 3.8c-1.517 2.68-1.835 5.39-.707 6.052a1.128 1.149 0 0 0 .572.148c1.186 0 2.929-1.523 4.22-3.8c1.517-2.68 1.835-5.39.708-6.052A1.128 1.149 0 0 0 12.677 5"></path>161 </g>162 </svg>163 );164}165
166export function CSSIcon(props: SVGProps<SVGSVGElement>) {167 return (168 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>169 <path170 fill="#7e57c2"171 d="M20 18h-2v-2h-2v2c0 .193 0 .703 1.254 1.033A3.345 3.345 0 0 1 20 22h2v2h2v-2c0-.388-.562-.851-1.254-1.034C20.356 20.34 20 18.84 20 18m-3.254 2.966C14.356 20.34 14 18.84 14 18h-2v-2h-2v8h2v-2h4v2h2v-2c0-.388-.562-.851-1.254-1.034"172 ></path>173 <path174 fill="#7e57c2"175 d="M24 4H4v20a4 4 0 0 0 4 4h16.16A3.84 3.84 0 0 0 28 24.16V8a4 4 0 0 0-4-4m2 14h-2v-2h-2v2c0 .193 0 .703 1.254 1.033A3.345 3.345 0 0 1 26 22v2a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2Z"176 ></path>177 </svg>178 );179}180
181export function SrcFolderClosed(props: SVGProps<SVGSVGElement>) {182 return (183 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>184 <path185 fill="#4caf50"186 d="m13.844 7.536l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464"187 ></path>188 <path189 fill="#c8e6c9"190 d="M18.435 30a1 1 0 0 1-.238-.028a1.137 1.137 0 0 1-.828-1.323l3.093-15.744a1.13 1.13 0 0 1 .507-.744a1.06 1.06 0 0 1 .8-.134a1.14 1.14 0 0 1 .828 1.324l-3.1 15.744a1.12 1.12 0 0 1-.505.743a1.06 1.06 0 0 1-.557.162m6.2-2h-.077a1.08 1.08 0 0 1-.762-.412a1.164 1.164 0 0 1 .113-1.548l5.32-4.967l-5.297-4.623a1.165 1.165 0 0 1-.162-1.544a1.08 1.08 0 0 1 .754-.437a1.06 1.06 0 0 1 .81.258l6.244 5.455a1.156 1.156 0 0 1 .004 1.723l-6.22 5.808a1.07 1.07 0 0 1-.728.289Zm-9.31 0a1.07 1.07 0 0 1-.728-.292l-6.225-5.811a1.16 1.16 0 0 1-.01-1.692l.02-.018l6.246-5.454a1.03 1.03 0 0 1 .8-.26a1.08 1.08 0 0 1 .758.436a1.165 1.165 0 0 1-.16 1.547l-5.293 4.62l5.32 4.964a1.156 1.156 0 0 1 .112 1.548a1.07 1.07 0 0 1-.762.412Z"191 ></path>192 </svg>193 );194}195
196export function SrcFolderOpen(props: SVGProps<SVGSVGElement>) {197 return (198 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>199 <path200 fill="#4caf50"201 d="M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12"202 ></path>203 <path204 fill="#c8e6c9"205 d="M18.473 30a1 1 0 0 1-.238-.028a1.137 1.137 0 0 1-.828-1.323L20.5 12.905a1.13 1.13 0 0 1 .507-.744a1.06 1.06 0 0 1 .8-.134a1.14 1.14 0 0 1 .828 1.324l-3.101 15.744a1.12 1.12 0 0 1-.504.743a1.06 1.06 0 0 1-.557.162m6.2-2h-.077a1.08 1.08 0 0 1-.762-.412a1.164 1.164 0 0 1 .113-1.548l5.319-4.967l-5.296-4.623a1.165 1.165 0 0 1-.162-1.544a1.08 1.08 0 0 1 .754-.437a1.06 1.06 0 0 1 .81.258l6.244 5.455a1.156 1.156 0 0 1 .003 1.723l-6.218 5.808a1.07 1.07 0 0 1-.729.289Zm-9.31 0a1.07 1.07 0 0 1-.728-.292l-6.226-5.811a1.16 1.16 0 0 1-.01-1.692l.02-.018l6.246-5.454a1.03 1.03 0 0 1 .8-.26a1.08 1.08 0 0 1 .76.436a1.165 1.165 0 0 1-.16 1.547l-5.294 4.62l5.32 4.964a1.156 1.156 0 0 1 .112 1.548a1.07 1.07 0 0 1-.762.412Z"206 ></path>207 </svg>208 );209}210
211export function JSXIcon(props: SVGProps<SVGSVGElement>) {212 return (213 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>214 <path215 fill="#0288d1"216 d="M16 12c7.444 0 12 2.59 12 4s-4.556 4-12 4s-12-2.59-12-4s4.556-4 12-4m0-2c-7.732 0-14 2.686-14 6s6.268 6 14 6s14-2.686 14-6s-6.268-6-14-6"217 ></path>218 <path fill="#0288d1" d="M16 14a2 2 0 1 0 2 2a2 2 0 0 0-2-2"></path>219 <path220 fill="#0288d1"221 d="M10.458 5.507c2.017 0 5.937 3.177 9.006 8.493c3.722 6.447 3.757 11.687 2.536 12.392a.9.9 0 0 1-.457.1c-2.017 0-5.938-3.176-9.007-8.492C8.814 11.553 8.779 6.313 10 5.608a.9.9 0 0 1 .458-.1m-.001-2A2.87 2.87 0 0 0 9 3.875C6.13 5.532 6.938 12.304 10.804 19c3.284 5.69 7.72 9.493 10.74 9.493A2.87 2.87 0 0 0 23 28.124c2.87-1.656 2.062-8.428-1.804-15.124c-3.284-5.69-7.72-9.493-10.74-9.493Z"222 ></path>223 <path224 fill="#0288d1"225 d="M21.543 5.507a.9.9 0 0 1 .457.1c1.221.706 1.186 5.946-2.536 12.393c-3.07 5.316-6.99 8.493-9.007 8.493a.9.9 0 0 1-.457-.1C8.779 25.686 8.814 20.446 12.536 14c3.07-5.316 6.99-8.493 9.007-8.493m0-2c-3.02 0-7.455 3.804-10.74 9.493C6.939 19.696 6.13 26.468 9 28.124a2.87 2.87 0 0 0 1.457.369c3.02 0 7.455-3.804 10.74-9.493C25.061 12.304 25.87 5.532 23 3.876a2.87 2.87 0 0 0-1.457-.369"226 ></path>227 </svg>228 );229}230
231export function JSIcon(props: SVGProps<SVGSVGElement>) {232 return (233 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>234 <path235 fill="#8bc34a"236 d="M16 20.003v2h4a2 2 0 0 0 2-2v-2a2 2 0 0 0-2-2h-2v-2h4v-2h-4a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h2v2Z"237 ></path>238 <path239 fill="#8bc34a"240 d="m16 3.003l-12 7v14l4 2h6v-13.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v11.5H8l-2-1.034V11.15l10-5.833l10 5.833v11.703l-10 5.833l-1.745-1.022L13 29.253l3 1.75l12-7v-14Z"241 ></path>242 </svg>243 );244}245
246export function TestsFolderClosed(props: SVGProps<SVGSVGElement>) {247 return (248 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>249 <path250 fill="#00bfa5"251 d="m13.844 7.536l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464"252 ></path>253 <path254 fill="#a7ffeb"255 d="M16 12v2h2v12a4 4 0 0 0 8 0V14h2v-2Zm5 14a1 1 0 1 1 1-1a1 1 0 0 1-1 1m2-4a1 1 0 1 1 1-1a1 1 0 0 1-1 1m1-4h-4v-4h4Z"256 ></path>257 </svg>258 );259}260
261export function TestsFolderOpen(props: SVGProps<SVGSVGElement>) {262 return (263 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>264 <path265 fill="#00bfa5"266 d="M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12"267 ></path>268 <path269 fill="#a7ffeb"270 d="M16 12v2h2v12a4 4 0 0 0 8 0V14h2v-2Zm5 14a1 1 0 1 1 1-1a1 1 0 0 1-1 1m2-4a1 1 0 1 1 1-1a1 1 0 0 1-1 1m1-4h-4v-4h4Z"271 ></path>272 </svg>273 );274}275
276export function TestsIcon(props: SVGProps<SVGSVGElement>) {277 return (278 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>279 <path280 fill="#0288d1"281 d="M20 4v2h-2v4.531l.264.461l7.473 13.078a2 2 0 0 1 .263.992V26a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2v-.938a2 2 0 0 1 .264-.992l7.473-13.078l.263-.46V6h-2V4zm0-2h-8a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2v2L4.527 23.078A4 4 0 0 0 4 25.062V26a4 4 0 0 0 4 4h16a4 4 0 0 0 4-4v-.938a4 4 0 0 0-.527-1.984L20 10V8a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2"282 ></path>283 <circle cx={17} cy={17} r={1} fill="#0288d1"></circle>284 <path285 fill="#0288d1"286 d="M19.72 20.715a1 1 0 0 0-1.134-.318a5 5 0 0 1-1.18.262a3.95 3.95 0 0 1-1.862-.292a2.74 2.74 0 0 0-3.371.489a2 2 0 0 0-.237.35L10 24h12Z"287 ></path>288 </svg>289 );290}291
292export function ConfigFolderClosed(props: SVGProps<SVGSVGElement>) {293 return (294 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>295 <path296 fill="#00acc1"297 d="m13.844 7.536l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464"298 ></path>299 <path300 fill="#80deea"301 d="M23.001 24.15A3.195 3.195 0 0 1 19.762 21a3.24 3.24 0 1 1 3.239 3.15m6.875-2.277a7 7 0 0 0 .064-.874a8 8 0 0 0-.064-.9l1.951-1.467a.446.446 0 0 0 .113-.576l-1.853-3.112a.46.46 0 0 0-.564-.199l-2.302.9a6.8 6.8 0 0 0-1.565-.882l-.342-2.385A.464.464 0 0 0 24.85 12h-3.7a.464.464 0 0 0-.463.378l-.341 2.385a6.8 6.8 0 0 0-1.563.881l-2.304-.899a.46.46 0 0 0-.564.198l-1.851 3.113a.436.436 0 0 0 .112.576l1.95 1.468a8 8 0 0 0-.064.9a7 7 0 0 0 .064.873l-1.95 1.493a.436.436 0 0 0-.112.576l1.85 3.115a.47.47 0 0 0 .565.198l2.304-.91a6.4 6.4 0 0 0 1.563.892l.342 2.385a.464.464 0 0 0 .463.378h3.7a.464.464 0 0 0 .464-.378l.34-2.385a6.8 6.8 0 0 0 1.566-.891l2.302.909a.475.475 0 0 0 .566-.198l1.85-3.115a.446.446 0 0 0-.112-.576Z"302 ></path>303 </svg>304 );305}306
307export function ConfigFolderOpen(props: SVGProps<SVGSVGElement>) {308 return (309 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>310 <path311 fill="#00acc1"312 d="M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12"313 ></path>314 <path315 fill="#80deea"316 d="M23.001 24.15A3.195 3.195 0 0 1 19.762 21a3.24 3.24 0 1 1 3.239 3.15m6.875-2.277a7 7 0 0 0 .064-.874a8 8 0 0 0-.064-.9l1.951-1.467a.446.446 0 0 0 .113-.576l-1.853-3.112a.46.46 0 0 0-.564-.199l-2.302.9a6.8 6.8 0 0 0-1.565-.882l-.342-2.385A.464.464 0 0 0 24.85 12h-3.7a.464.464 0 0 0-.463.378l-.341 2.385a6.8 6.8 0 0 0-1.563.881l-2.304-.899a.46.46 0 0 0-.564.198l-1.851 3.113a.436.436 0 0 0 .112.576l1.95 1.468a8 8 0 0 0-.064.9a7 7 0 0 0 .064.873l-1.95 1.493a.436.436 0 0 0-.112.576l1.85 3.115a.47.47 0 0 0 .565.198l2.304-.91a6.4 6.4 0 0 0 1.563.892l.342 2.385a.464.464 0 0 0 .463.378h3.7a.464.464 0 0 0 .464-.378l.34-2.385a6.8 6.8 0 0 0 1.566-.891l2.302.909a.475.475 0 0 0 .566-.198l1.85-3.115a.446.446 0 0 0-.112-.576Z"317 ></path>318 </svg>319 );320}321
322export function UtilsFolderClosedIcon(props: SVGProps<SVGSVGElement>) {323 return (324 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>325 <path326 fill="#7cb342"327 d="m13.844 7.536l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464"328 ></path>329 <path330 fill="#dcedc8"331 d="M31 12H19a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V13a1 1 0 0 0-1-1m-1 8h-4v4h-2v-4h-4v-2h4v-4h2v4h4Z"332 ></path>333 <path fill="#dcedc8" d="M16 28V16h-2v13a1 1 0 0 0 1 1h13v-2Z"></path>334 </svg>335 );336}337
338export function UtilsFolderOpenIcon(props: SVGProps<SVGSVGElement>) {339 return (340 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>341 <path342 fill="#7cb342"343 d="M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12"344 ></path>345 <path346 fill="#dcedc8"347 d="M31 12H19a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V13a1 1 0 0 0-1-1m-1 8h-4v4h-2v-4h-4v-2h4v-4h2v4h4Z"348 ></path>349 <path fill="#dcedc8" d="M16 28V16h-2v13a1 1 0 0 0 1 1h13v-2Z"></path>350 </svg>351 );352}353
354export function HooksFolderClosedIcon(props: SVGProps<SVGSVGElement>) {355 return (356 <svg xmlns="http://www.w3.org/2000/svg" width={1024} height={1024} viewBox="0 0 1024 1024" {...props}>357 <path358 fill="#7e57c2"359 d="m443.008 241.152l-41.216-34.304A64 64 0 0 0 360.832 192H128a64 64 0 0 0-64 64v512a64 64 0 0 0 64 64h768a64 64 0 0 0 64-64V320a64 64 0 0 0-64-64H483.968a64 64 0 0 1-40.96-14.848"360 ></path>361 <path362 fill="#d1c4e9"363 d="M800 320c-53.02 0-96 42.98-96 96c.104 40.593 25.729 76.733 64 90.264V768c0 35.346-28.654 64-64 64s-64-28.654-64-64v-64h64L576 576v192c0 70.692 57.308 128 128 128s128-57.308 128-128V506.264c38.271-13.531 63.896-49.671 64-90.264c0-53.02-42.98-96-96-96m0 64c17.673 0 32 14.327 32 32s-14.327 32-32 32s-32-14.327-32-32s14.327-32 32-32"364 ></path>365 </svg>366 );367}368
369export function HooksFolderOpenIcon(props: SVGProps<SVGSVGElement>) {370 return (371 <svg xmlns="http://www.w3.org/2000/svg" width={1024} height={1024} viewBox="0 0 1024 1024" {...props}>372 <path373 fill="#7e57c2"374 d="M926.944 384h-624.8a64 64 0 0 0-60.736 43.776L128 768V320h768a64 64 0 0 0-64-64H483.968a64 64 0 0 1-40.96-14.848l-41.216-34.304A64 64 0 0 0 360.832 192H128a64 64 0 0 0-64 64v512a64 64 0 0 0 64 64h704l153.76-358.784A64 64 0 0 0 926.944 384"375 ></path>376 <path377 fill="#d1c4e9"378 d="M800 320c-53.02 0-96 42.98-96 96c.104 40.593 25.729 76.733 64 90.264V768c0 35.346-28.654 64-64 64s-64-28.654-64-64v-64h64L576 576v192c0 70.692 57.308 128 128 128s128-57.308 128-128V506.264c38.271-13.531 63.896-49.671 64-90.264c0-53.02-42.98-96-96-96m0 64c17.673 0 32 14.327 32 32s-14.327 32-32 32s-32-14.327-32-32s14.327-32 32-32"379 ></path>380 </svg>381 );382}383
384export function GitIcon(props: SVGProps<SVGSVGElement>) {385 return (386 <svg xmlns="http://www.w3.org/2000/svg" width={32} height={32} viewBox="0 0 32 32" {...props}>387 <path388 fill="#e64a19"389 d="M13.172 2.828L11.78 4.22l1.91 1.91l2 2A2.986 2.986 0 0 1 20 10.81a3.25 3.25 0 0 1-.31 1.31l2.06 2a2.68 2.68 0 0 1 3.37.57a2.86 2.86 0 0 1 .88 2.117a3.02 3.02 0 0 1-.856 2.109A2.9 2.9 0 0 1 23 19.81a2.93 2.93 0 0 1-2.13-.87a2.694 2.694 0 0 1-.56-3.38l-2-2.06a3 3 0 0 1-.31.12V20a3 3 0 0 1 1.44 1.09a2.92 2.92 0 0 1 .56 1.72a2.88 2.88 0 0 1-.878 2.128a2.98 2.98 0 0 1-2.048.871a2.981 2.981 0 0 1-2.514-4.719A3 3 0 0 1 16 20v-6.38a2.96 2.96 0 0 1-1.44-1.09a2.9 2.9 0 0 1-.56-1.72a2.9 2.9 0 0 1 .31-1.31l-3.9-3.9l-7.579 7.572a4 4 0 0 0-.001 5.658l10.342 10.342a4 4 0 0 0 5.656 0l10.344-10.344a4 4 0 0 0 0-5.656L18.828 2.828a4 4 0 0 0-5.656 0"390 ></path>391 </svg>392 );393}394
395export function DotFile(props: SVGProps<SVGSVGElement>) {396 return (397 <svg xmlns="http://www.w3.org/2000/svg" width={400} height={400} viewBox="0 0 400 400" {...props}>398 <g fill="#2196f3" fillOpacity={0.604} transform="translate(-6.66 100.49)">399 <ellipse400 cx={37.18}401 cy={-256.97}402 rx={110.14}403 ry={139.47}404 transform="matrix(-.3005 .95378 -.96071 -.27755 0 0)"405 ></ellipse>406 <ellipse407 cx={38.835}408 cy={-197.03}409 rx={110.14}410 ry={139.47}411 transform="matrix(-.3005 .95378 -.96071 -.27755 0 0)"412 ></ellipse>413 <ellipse414 cx={-224.78}415 cy={-5.066}416 rx={110.14}417 ry={139.47}418 transform="matrix(-.95378 -.3005 .27755 -.96071 0 0)"419 ></ellipse>420 <ellipse421 cx={-228.55}422 cy={-60.291}423 rx={110.14}424 ry={139.47}425 transform="matrix(-.95378 -.3005 .27755 -.96071 0 0)"426 ></ellipse>427 </g>428 </svg>429 );430}1export const data = {2 root: {3 name: "root",4 kind: "folder",5 size: 0,6 modified: "2026-01-22T09:00:00Z",7 children: [8 {9 name: "package.json",10 kind: "file",11 size: 1840,12 modified: "2026-01-21T18:12:00Z",13 lastEditedBy: "Joseph Allen",14 permissions: "rw-r--r--",15 },16 {17 name: "package-lock.json",18 kind: "file",19 size: 92000,20 modified: "2026-01-21T18:12:30Z",21 lastEditedBy: "Joseph Allen",22 permissions: "rw-r--r--",23 },24 {25 name: "README.md",26 kind: "file",27 size: 1240,28 modified: "2026-01-20T10:05:00Z",29 lastEditedBy: "Betty Hall",30 permissions: "rw-r--r--",31 },32 {33 name: ".gitignore",34 kind: "file",35 size: 180,36 modified: "2026-01-19T09:00:00Z",37 lastEditedBy: "Betty Hall",38 permissions: "rw-r--r--",39 },40 {41 name: ".env",42 kind: "file",43 size: 220,44 modified: "2026-01-21T08:30:00Z",45 lastEditedBy: "Nancy Lewis",46 permissions: "rw-------",47 },48
49 {50 name: "public",51 kind: "folder",52 size: 0,53 modified: "2026-01-18T12:00:00Z",54 children: [55 {56 name: "index.html",57 kind: "file",58 size: 3420,59 modified: "2026-01-18T12:01:00Z",60 lastEditedBy: "Charles Clark",61 permissions: "rw-r--r--",62 },63 {64 name: "favicon.ico",65 kind: "file",66 size: 5430,67 modified: "2026-01-18T12:01:30Z",68 lastEditedBy: "Charles Clark",69 permissions: "rw-r--r--",70 },71 {72 name: "manifest.json",73 kind: "file",74 size: 820,75 modified: "2026-01-18T12:02:00Z",76 lastEditedBy: "Charles Clark",77 permissions: "rw-r--r--",78 },79 {80 name: "assets",81 kind: "folder",82 size: 0,83 modified: "2026-01-17T15:40:00Z",84 children: [85 {86 name: "logo.svg",87 kind: "file",88 size: 2048,89 modified: "2026-01-17T15:42:00Z",90 lastEditedBy: "Richard White",91 permissions: "rw-r--r--",92 },93 {94 name: "hero.png",95 kind: "file",96 size: 482000,97 modified: "2026-01-17T15:45:00Z",98 lastEditedBy: "Richard White",99 permissions: "rw-r--r--",100 },101 ],102 },103 ],104 },105
106 {107 name: "src",108 kind: "folder",109 size: 0,110 modified: "2026-01-22T08:30:00Z",111 children: [112 {113 name: "assets",114 kind: "folder",115 size: 0,116 modified: "2026-01-20T14:00:00Z",117 children: [118 {119 name: "global.css",120 kind: "file",121 size: 2140,122 modified: "2026-01-20T14:05:00Z",123 lastEditedBy: "Jennifer Taylor",124 permissions: "rw-r--r--",125 },126 {127 name: "variables.css",128 kind: "file",129 size: 980,130 modified: "2026-01-20T14:04:00Z",131 lastEditedBy: "Jennifer Taylor",132 permissions: "rw-r--r--",133 },134 ],135 },136
137 {138 name: "components",139 kind: "folder",140 size: 0,141 modified: "2026-01-21T09:30:00Z",142 children: [143 {144 name: "Button",145 kind: "folder",146 size: 0,147 modified: "2026-01-21T09:31:00Z",148 children: [149 {150 name: "Button.jsx",151 kind: "file",152 size: 1620,153 modified: "2026-01-21T09:35:00Z",154 lastEditedBy: "Sarah Wilson",155 permissions: "rw-r--r--",156 },157 {158 name: "Button.module.css",159 kind: "file",160 size: 740,161 modified: "2026-01-21T09:34:00Z",162 lastEditedBy: "Sarah Wilson",163 permissions: "rw-r--r--",164 },165 {166 name: "Button.test.jsx",167 kind: "file",168 size: 1280,169 modified: "2026-01-21T09:36:00Z",170 lastEditedBy: "Joseph Allen",171 permissions: "rw-r--r--",172 },173 ],174 },175
176 {177 name: "Modal",178 kind: "folder",179 size: 0,180 modified: "2026-01-21T11:10:00Z",181 children: [182 {183 name: "Modal.jsx",184 kind: "file",185 size: 1980,186 modified: "2026-01-21T11:15:00Z",187 lastEditedBy: "Nancy Lewis",188 permissions: "rw-r--r--",189 },190 {191 name: "Modal.css",192 kind: "file",193 size: 860,194 modified: "2026-01-21T11:14:00Z",195 lastEditedBy: "Nancy Lewis",196 permissions: "rw-r--r--",197 },198 ],199 },200 ],201 },202
203 {204 name: "hooks",205 kind: "folder",206 size: 0,207 modified: "2026-01-19T16:00:00Z",208 children: [209 {210 name: "useAuth.js",211 kind: "file",212 size: 1320,213 modified: "2026-01-19T16:05:00Z",214 lastEditedBy: "Betty Hall",215 permissions: "rw-r--r--",216 },217 {218 name: "useFetch.js",219 kind: "file",220 size: 1740,221 modified: "2026-01-19T16:06:00Z",222 lastEditedBy: "Betty Hall",223 permissions: "rw-r--r--",224 },225 ],226 },227
228 {229 name: "context",230 kind: "folder",231 size: 0,232 modified: "2026-01-20T10:40:00Z",233 children: [234 {235 name: "AuthContext.jsx",236 kind: "file",237 size: 1560,238 modified: "2026-01-20T10:42:00Z",239 lastEditedBy: "Jennifer Taylor",240 permissions: "rw-r--r--",241 },242 ],243 },244
245 {246 name: "services",247 kind: "folder",248 size: 0,249 modified: "2026-01-20T11:30:00Z",250 children: [251 {252 name: "api.js",253 kind: "file",254 size: 980,255 modified: "2026-01-20T11:32:00Z",256 lastEditedBy: "Charles Clark",257 permissions: "rw-r--r--",258 },259 {260 name: "authService.js",261 kind: "file",262 size: 1420,263 modified: "2026-01-20T11:33:00Z",264 lastEditedBy: "Charles Clark",265 permissions: "rw-r--r--",266 },267 ],268 },269
270 {271 name: "utils",272 kind: "folder",273 size: 0,274 modified: "2026-01-19T15:10:00Z",275 children: [276 {277 name: "constants.js",278 kind: "file",279 size: 540,280 modified: "2026-01-19T15:12:00Z",281 lastEditedBy: "Richard White",282 permissions: "rw-r--r--",283 },284 {285 name: "formatDate.js",286 kind: "file",287 size: 620,288 modified: "2026-01-19T15:11:00Z",289 lastEditedBy: "Richard White",290 permissions: "rw-r--r--",291 },292 ],293 },294
295 {296 name: "routes.jsx",297 kind: "file",298 size: 1240,299 modified: "2026-01-22T08:10:00Z",300 lastEditedBy: "Sarah Wilson",301 permissions: "rw-r--r--",302 },303 {304 name: "App.jsx",305 kind: "file",306 size: 2140,307 modified: "2026-01-22T08:20:00Z",308 lastEditedBy: "Sarah Wilson",309 permissions: "rw-r--r--",310 },311 {312 name: "main.jsx",313 kind: "file",314 size: 860,315 modified: "2026-01-22T08:25:00Z",316 lastEditedBy: "Sarah Wilson",317 permissions: "rw-r--r--",318 },319 ],320 },321
322 {323 name: "tests",324 kind: "folder",325 size: 0,326 modified: "2026-01-21T13:00:00Z",327 children: [328 {329 name: "setupTests.js",330 kind: "file",331 size: 520,332 modified: "2026-01-21T13:01:00Z",333 lastEditedBy: "Joseph Allen",334 permissions: "rw-r--r--",335 },336 {337 name: "App.test.jsx",338 kind: "file",339 size: 1620,340 modified: "2026-01-21T13:02:00Z",341 lastEditedBy: "Joseph Allen",342 permissions: "rw-r--r--",343 },344 ],345 },346
347 {348 name: "config",349 kind: "folder",350 size: 0,351 modified: "2026-01-18T17:00:00Z",352 children: [353 {354 name: "vite.config.js",355 kind: "file",356 size: 1120,357 modified: "2026-01-18T17:02:00Z",358 lastEditedBy: "Betty Hall",359 permissions: "rw-r--r--",360 },361 {362 name: "eslint.config.js",363 kind: "file",364 size: 980,365 modified: "2026-01-18T17:01:00Z",366 lastEditedBy: "Betty Hall",367 permissions: "rw-r--r--",368 },369 ],370 },371 ],372 },373};Next Steps
- Tree Filtering: Remove tree data rows by providing a custom filter function.
- Tree Data: Generate hierarchical rows from nested object data.
- Client Row Sorting: Sort rows in ascending or descending order with the client row source.
