Skip to content

⬅️ Back to Table of Contents

📄 DataRenderer

📊 Analysis Summary

Metric Count
🔧 Functions 6
📦 Imports 19
💠 JSX Elements 25
📐 Interfaces 2

📚 Table of Contents

🛠️ File Location:

📂 packages/website/src/components/ast/DataRenderer.tsx

📦 Imports

Name Source
clsx clsx
useCallback react
useEffect react
useMemo react
React react
OnHoverNodeFn ./types
ParentNodeType ./types
useBool ../../hooks/useBool
Tooltip ../inputs/Tooltip
styles ./ASTViewer.module.css
HiddenItem ./HiddenItem
PropertyName ./PropertyName
PropertyValue ./PropertyValue
filterProperties ./utils
getNodeType ./utils
getRange ./utils
getTooltipLabel ./utils
getTypeName ./utils
isRecord ./utils

JSX Elements

Component Type Props Children
div element className={clsx( styles.expand, !expanded && styles.open, isActive && styles.... {field && ( <PropertyName className={styles.propName} onClick={toggleExpanded...
PropertyName component className={styles.propName}, onClick={toggleExpanded}, onHover={onHoverItem},... none
span element none text: ":"
PropertyName component className={styles.tokenName}, onClick={toggleExpanded}, onHover={onHoverItem}... none
span element none none
span element none {openBracket}
div element className={styles.subList} {data.map((dataElement, index) => ( <DataRender field={dataElement[0]} key={d...
DataRender component field={dataElement[0]}, key={dataElement[0]}, lastElement={index === lastInde... none
HiddenItem component isArray={openBracket === '['}, level={level}, value={data} none
span element none {closeBracket}
span element none text: ","
RenderExpandableObject component closeBracket="}", data={computed.value}, nodeType={computed.nodeType}, openBr... none
RenderExpandableObject component closeBracket="]", data={Object.entries(props.value)}, openBracket="[" none
RenderExpandableObject component closeBracket=")", data={Object.entries(props.value)}, openBracket="(" none
div element className={styles.valueBody}, role="listitem" {field && {field}: }, {tooltip ? ( <...
span element className={styles.propName} {field}, text: ":"
Tooltip component hover={true}, position="right", text={tooltip}
PropertyValue component value={value} none
PropertyValue component value={value} none
span element className={styles.label} text: ","
JsonArray component value={value} none
JsonObject component value={value} none
JsonIterable component typeName="Map", value={value} none
JsonIterable component typeName="Set", value={value} none
JsonPrimitiveValue component none none

Functions

DataRender(props: JsonRenderProps<unknown>): React.JSX.Element

Parameters:

  • props JsonRenderProps<unknown>

Returns: React.JSX.Element

Calls:

  • Array.isArray
  • isRecord (from ./utils)
Code
export default function DataRender(
  props: JsonRenderProps<unknown>,
): React.JSX.Element {
  const value = props.value;

  if (Array.isArray(value)) {
    return <JsonArray {...props} value={value} />;
  }

  if (isRecord(value)) {
    return <JsonObject {...props} value={value} />;
  }

  if (value instanceof Map) {
    return <JsonIterable typeName="Map" {...props} value={value} />;
  }

  if (value instanceof Set) {
    return <JsonIterable typeName="Set" {...props} value={value} />;
  }

  return <JsonPrimitiveValue {...props} />;
}

RenderExpandableObject({ closeBracket, data, field, la…: ExpandableRenderProps): React.JSX.Element

Parameters:

  • { closeBracket, data, field, lastElement, level, nodeType, onHover, openBracket, selectedPath, showTokens, typeName, value, } ExpandableRenderProps

Returns: React.JSX.Element

Calls:

  • useBool (from ../../hooks/useBool)
  • selectedPath?.startsWith
  • useMemo (from react)
  • useCallback (from react)
  • onHover
  • getRange (from ./utils)
  • useEffect (from react)
  • setExpanded
  • clsx (from clsx)
  • data.map
Code
function RenderExpandableObject({
  closeBracket,
  data,
  field,
  lastElement,
  level,
  nodeType,
  onHover,
  openBracket,
  selectedPath,
  showTokens,
  typeName,
  value,
}: ExpandableRenderProps): React.JSX.Element {
  const [expanded, toggleExpanded, setExpanded] = useBool(
    () => level === 'ast' || !!selectedPath?.startsWith(level),
  );

  const isActive = useMemo(
    () => level !== 'ast' && selectedPath === level,
    [selectedPath, level],
  );

  const onHoverItem = useCallback(
    (hover: boolean): void => {
      if (onHover) {
        if (hover) {
          onHover(getRange(value, nodeType));
        } else {
          onHover(undefined);
        }
      }
    },
    [onHover, value, nodeType],
  );

  useEffect(() => {
    const shouldOpen = !!selectedPath?.startsWith(level);
    if (shouldOpen) {
      setExpanded(current => current || shouldOpen);
    }
  }, [selectedPath, level, setExpanded]);

  const lastIndex = data.length - 1;

  return (
    <div
      className={clsx(
        styles.expand,
        !expanded && styles.open,
        isActive && styles.selected,
      )}
      data-level={level}
      role="list"
    >
      {field && (
        <PropertyName
          className={styles.propName}
          onClick={toggleExpanded}
          onHover={onHoverItem}
          value={field}
        />
      )}
      {field && <span>: </span>}
      {typeName && (
        <PropertyName
          className={styles.tokenName}
          onClick={toggleExpanded}
          onHover={onHoverItem}
          value={typeName}
        />
      )}
      {typeName && <span> </span>}
      <span>{openBracket}</span>

      {expanded ? (
        <div className={styles.subList}>
          {data.map((dataElement, index) => (
            <DataRender
              field={dataElement[0]}
              key={dataElement[0]}
              lastElement={index === lastIndex}
              level={`${level}.${dataElement[0]}`}
              nodeType={nodeType}
              onHover={onHover}
              selectedPath={selectedPath}
              showTokens={showTokens}
              value={dataElement[1]}
            />
          ))}
        </div>
      ) : (
        <HiddenItem isArray={openBracket === '['} level={level} value={data} />
      )}

      <span>{closeBracket}</span>
      {!lastElement && <span>,</span>}
    </div>
  );
}

JsonObject(props: JsonRenderProps<Record<string, unknown>>): React.JSX.Element

Parameters:

  • props JsonRenderProps<Record<string, unknown>>

Returns: React.JSX.Element

Calls:

  • useMemo (from react)
  • getNodeType (from ./utils)
  • getTypeName (from ./utils)
  • Object.entries(props.value).filter
  • filterProperties (from ./utils)
Code
function JsonObject(
  props: JsonRenderProps<Record<string, unknown>>,
): React.JSX.Element {
  const computed = useMemo(() => {
    const nodeType = getNodeType(props.value);
    return {
      nodeType,
      typeName: getTypeName(props.value, nodeType),
      value: Object.entries(props.value).filter(item =>
        filterProperties(item[0], item[1], nodeType, props.showTokens),
      ),
    };
  }, [props.value, props.showTokens]);

  return (
    <RenderExpandableObject
      {...props}
      closeBracket="}"
      data={computed.value}
      nodeType={computed.nodeType}
      openBracket="{"
      typeName={computed.typeName}
    />
  );
}

JsonArray(props: JsonRenderProps<unknown[]>): React.JSX.Element

Parameters:

  • props JsonRenderProps<unknown[]>

Returns: React.JSX.Element

Calls:

  • Object.entries
Code
function JsonArray(props: JsonRenderProps<unknown[]>): React.JSX.Element {
  return (
    <RenderExpandableObject
      {...props}
      closeBracket="]"
      data={Object.entries(props.value)}
      openBracket="["
    />
  );
}

JsonIterable(props: JsonRenderProps<Iterable<unknown>>): React.JSX.Element

Parameters:

  • props JsonRenderProps<Iterable<unknown>>

Returns: React.JSX.Element

Calls:

  • Object.entries
Code
function JsonIterable(
  props: JsonRenderProps<Iterable<unknown>>,
): React.JSX.Element {
  return (
    <RenderExpandableObject
      {...props}
      closeBracket=")"
      data={Object.entries(props.value)}
      openBracket="("
    />
  );
}

JsonPrimitiveValue({ field, lastElement, nodeType,…: JsonRenderProps<unknown>): React.JSX.Element

Parameters:

  • { field, lastElement, nodeType, value, } JsonRenderProps<unknown>

Returns: React.JSX.Element

Calls:

  • useMemo (from react)
  • getTooltipLabel (from ./utils)
Code
function JsonPrimitiveValue({
  field,
  lastElement,
  nodeType,
  value,
}: JsonRenderProps<unknown>): React.JSX.Element {
  const tooltip = useMemo(() => {
    if (field && nodeType) {
      return getTooltipLabel(value, field, nodeType);
    }
    return undefined;
  }, [value, field, nodeType]);

  return (
    <div className={styles.valueBody} role="listitem">
      {field && <span className={styles.propName}>{field}: </span>}
      {tooltip ? (
        <Tooltip hover={true} position="right" text={tooltip}>
          <PropertyValue value={value} />
        </Tooltip>
      ) : (
        <PropertyValue value={value} />
      )}
      {!lastElement && <span className={styles.label}>,</span>}
    </div>
  );
}

Interfaces

JsonRenderProps<T>

Interface Code
export interface JsonRenderProps<T> {
  readonly field?: string;
  readonly lastElement?: boolean;
  readonly level: string;
  readonly nodeType?: ParentNodeType;
  readonly onHover?: OnHoverNodeFn;
  readonly selectedPath?: string;
  readonly showTokens?: boolean;
  readonly typeName?: string;
  readonly value: T;
}

Properties

Name Type Optional Description
field string not shown
lastElement boolean not shown
level string not shown
nodeType ParentNodeType not shown
onHover OnHoverNodeFn not shown
selectedPath string not shown
showTokens boolean not shown
typeName string not shown
value T not shown

ExpandableRenderProps

Interface Code
export interface ExpandableRenderProps extends JsonRenderProps<
  object | unknown[]
> {
  readonly closeBracket: string;
  readonly data: [string, unknown][];
  readonly openBracket: string;
}

Properties

Name Type Optional Description
closeBracket string not shown
data [string, unknown][] not shown
openBracket string not shown

Generated by Syntax Scribe