LCOV - code coverage report
Current view: top level - dashql-app/src/ui/foundations - tree_entry.tsx Coverage Total Hit
Test: DashQL 915828b Lines: 100.0 % 24 24
Test Date: 2026-11-06 19:30:32

            Line data    Source code
       1              : import * as React from 'react';
       2              : 
       3              : import { ChevronDownIcon, ChevronRightIcon } from './symbol_icon.js';
       4              : import { classNames } from '../../utils/classnames.js';
       5              : import * as styles from './tree_entry.module.css';
       6              : 
       7              : /// The indentation of a tree level
       8              : export const TREE_ENTRY_INDENT_PX = 16;
       9              : /// The left padding of an entry at depth 0
      10            1 : const TREE_ENTRY_PADDING_PX = 8;
      11              : 
      12              : export interface TreeEntryProps extends Omit<React.HTMLAttributes<HTMLElement>, 'className' | 'style'> {
      13              :     /// The level of the entry, the root level is 0
      14              :     depth: number;
      15              :     /// Is the folder expanded? Files leave it undefined and get no caret.
      16              :     expanded?: boolean;
      17              :     /// The icon before the label, e.g. a folder or a file. Without one the label starts after the caret.
      18              :     icon?: React.ReactElement | null;
      19              :     /// The label of the entry, usually a TreeEntryName
      20              :     label: React.ReactNode;
      21              :     /// Is the entry selected?
      22              :     selected?: boolean;
      23              :     /// Additional classes, e.g. a grid with trailing columns
      24              :     className?: string;
      25              :     /// The trailing cells after the label
      26              :     children?: React.ReactNode;
      27              : }
      28              : 
      29              : /// An entry of a file tree: caret, icon and label in a padded, rounded card that highlights on hover.
      30              : /// Clickable entries are buttons, folders toggle themselves with their onClick.
      31            1 : export function TreeEntry({ depth, expanded, icon, label, selected, className, children, ...attributes }: TreeEntryProps): React.ReactElement {
      32            1 :     const Caret = expanded == null ? null : expanded ? ChevronDownIcon : ChevronRightIcon;
      33            1 :     const content = (
      34            1 :         <>
      35            1 :             <span className={classNames(styles.cell_name, icon == null && styles.cell_name_without_icon)}>
      36            1 :                 <span className={styles.caret}>{Caret && <Caret size={12} />}</span>
      37            1 :                 {icon != null && <span className={styles.icon} aria-hidden="true">{icon}</span>}
      38            1 :                 {label}
      39            1 :             </span>
      40            1 :             {children}
      41            1 :         </>
      42              :     );
      43            1 :     const props = {
      44            1 :         ...attributes,
      45            1 :         className: classNames(styles.entry, attributes.onClick != null && styles.entry_interactive, selected && styles.entry_selected, className),
      46            1 :         style: { paddingLeft: TREE_ENTRY_PADDING_PX + depth * TREE_ENTRY_INDENT_PX },
      47            1 :     };
      48            1 :     return attributes.onClick == null
      49            1 :         ? <div {...props}>{content}</div>
      50            1 :         : <button type="button" aria-expanded={expanded} {...props}>{content}</button>;
      51            1 : }
      52              : 
      53              : export interface TreeEntryNameProps {
      54              :     /// The name of the entry
      55              :     children: string;
      56              :     /// The hover text, e.g. the full path
      57              :     title?: string;
      58              : }
      59              : 
      60              : /// The name of a tree entry, cut with an ellipsis instead of wrapping
      61            1 : export function TreeEntryName(props: TreeEntryNameProps): React.ReactElement {
      62            1 :     return <span className={styles.name} title={props.title ?? props.children}>{props.children}</span>;
      63            1 : }
        

Generated by: LCOV version 2.0-1