or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

authorization.mdcharts.mdcompiler.mdconditional-formatting.mddashboards.mddbt.mdee-features.mdexplore-fields.mdfilters.mdformatting.mdindex.mdmetric-queries.mdparameters.mdpivot.mdprojects-spaces.mdsql-runner.mdtemplating.mdtypes.mdutilities.mdvisualizations.mdwarehouse.md
tile.json

formatting.mddocs/

Data Formatting

Value formatting for numbers, dates, timestamps, currencies, and custom formats.

Core Functions

/**
 * Primary formatting function - converts raw values to human-readable strings
 * @param item - Field definition with format rules (if undefined, uses default formatting)
 * @param value - Raw value (any type: number, string, Date, boolean, null, undefined)
 * @param convertToUTC - If true, converts timestamps to UTC before formatting
 * @param parameters - Values for format expressions with ${parameter_name} placeholders
 * @returns Formatted string
 *
 * Special return values:
 * - Returns '∅' for null values
 * - Returns '-' for undefined values
 * - Returns '' for empty string values
 *
 * Behavior:
 * 1. Checks for format expressions (item.format) and applies if valid
 * 2. Falls back to formatOptions (CustomFormat) if present
 * 3. Applies type-specific formatting for dates, timestamps, booleans
 * 4. Uses default formatting for unformatted values
 */
function formatItemValue(
  item: Field | Dimension | AdditionalMetric | TableCalculation | CustomDimension | undefined,
  value: unknown,
  convertToUTC?: boolean,
  parameters?: Record<string, unknown>
): string;

function formatDate(date: Date | string, timeInterval?: TimeFrames, convertToUTC?: boolean): string;
function formatTimestamp(value: Date | string, timeInterval?: TimeFrames, convertToUTC?: boolean): string;
function formatNumberValue(value: number, options?: NumberFormatOptions): string;

Custom Format Types

enum CustomFormatType {
  DEFAULT = 'default',
  PERCENT = 'percent',
  CURRENCY = 'currency',
  NUMBER = 'number',
  DATE = 'date',
  TIMESTAMP = 'timestamp',
  ID = 'id',
  CUSTOM = 'custom'
}

enum NumberSeparator {
  COMMA_PERIOD = 'commaPeriod',    // 1,234.56
  SPACE_PERIOD = 'spacePeriod',    // 1 234.56
  PERIOD_COMMA = 'periodComma',    // 1.234,56
  NO_SEPARATOR_PERIOD = 'noSeparatorPeriod'  // 1234.56
}

enum Compact {
  THOUSANDS = 'thousands',  // K
  MILLIONS = 'millions',    // M
  BILLIONS = 'billions',    // B
  KILOBYTES = 'kilobytes',  // KB
  MEGABYTES = 'megabytes',  // MB
  GIGABYTES = 'gigabytes'   // GB
}

interface CustomFormat {
  type: CustomFormatType;
  round?: number;
  separator?: NumberSeparator;
  currency?: string;
  compact?: Compact;
  prefix?: string;
  suffix?: string;
  timeInterval?: TimeFrames;
  custom?: string;  // Custom format expression
}

Examples

import { formatItemValue, formatDate, formatNumberValue } from '@lightdash/common';

// Format field value
const formatted = formatItemValue(field, 1234.56);

// Format date
const dateStr = formatDate(new Date(), TimeFrames.DAY);

// Format number with options
const currency = formatNumberValue(1234.56, {
  separator: NumberSeparator.COMMA_PERIOD,
  round: 2,
  compact: Compact.THOUSANDS
});
// Result: "1.23K"

// Custom format
const field: Field = {
  // ... other properties
  formatOptions: {
    type: CustomFormatType.CURRENCY,
    currency: 'USD',
    round: 2,
    separator: NumberSeparator.COMMA_PERIOD
  }
};
const result = formatItemValue(field, 1234.567);
// Result: "$1,234.57"

Format Utilities

function applyCustomFormat(item: Field | Metric, value: unknown, customFormat: CustomFormat): string;
function findCompactConfig(compact: Compact | undefined): CompactConfig | undefined;
function getCompactOptionsForFormatType(formatType: CustomFormatType): Compact[];

Edge Cases & Special Behaviors

ScenarioBehaviorExample
Null valueReturns '∅'formatItemValue(field, null)'∅'
Undefined valueReturns '-'formatItemValue(field, undefined)'-'
Empty stringReturns ''formatItemValue(field, '')''
Item is undefinedUses default formattingformatItemValue(undefined, 123)'123'
Boolean valuesReturns 'true'/'false' unless custom format specifiedformatItemValue(boolField, true)'true'
Format expression invalidFalls back to formatOptionsIf format expression fails, uses item.formatOptions
No formatOptionsUses type-based defaultNumbers as-is, dates as ISO, etc.
Currency without codeThrows errorMust specify valid ISO 4217 currency code
Compact with non-numericReturns value as-isOnly applies compact to numbers

Advanced Formatting Pattern

import {
  formatItemValue,
  formatNumberValue,
  type CustomFormat,
  CustomFormatType,
  NumberSeparator,
  Compact,
} from '@lightdash/common';

// Format with multiple options
const customFormat: CustomFormat = {
  type: CustomFormatType.CURRENCY,
  currency: 'EUR',
  separator: NumberSeparator.PERIOD_COMMA,  // European format: 1.234,56
  round: 2,
  compact: Compact.THOUSANDS,  // Show as K
  prefix: '',  // Override default currency symbol prefix if needed
  suffix: ' EUR',  // Add suffix
};

const formatted = formatNumberValue(1234567.89, customFormat);
// Result: "1.234,57K EUR"

// Conditional formatting based on value
function formatMetric(field: Field, value: unknown): string {
  if (value === null) return 'No data';  // Custom null handling
  if (value === undefined) return 'N/A';  // Custom undefined handling

  // Apply custom logic before formatting
  if (typeof value === 'number' && value < 0) {
    return `(${formatItemValue(field, Math.abs(value))})`;  // Negative in parens
  }

  return formatItemValue(field, value);
}

// Format with parameters (for format expressions)
const fieldWithExpression: Field = {
  // ... other properties
  format: '${value} / ${total} = ${percentage}%',
};

const formatted = formatItemValue(
  fieldWithExpression,
  0.75,
  false,
  { value: 75, total: 100, percentage: 75 }  // Parameters for expression
);
// Result: "75 / 100 = 75%"

Supported Currencies

Full list of ISO 4217 currency codes: USD, EUR, GBP, JPY, DKK, CHF, CAD, AUD, CNY, ARS, BRL, CLP, COP, CZK, HKD, HUF, INR, ILS, KRW, MYR, MXN, MAD, NZD, NOK, PHP, PLN, RUB, SAR, SGD, ZAR, SEK, TWD, THB, TRY, VND