OSS-first docs

These docs teach the open system first: contracts, generated surfaces, runtimes, governance, and incremental adoption. Studio shows up as the operating layer on top, not as the source of truth.

AI index

DataViews Runtime Library

The

@lssm-tech/lib.contracts-spec/data-views

and

@lssm-tech/lib.design-system

libraries provide the runtime logic and UI components to render DataViews in your application.

Installation

bun add @lssm-tech/lib.contracts-spec @lssm-tech/lib.design-system

DataViewRenderer

The primary component for rendering any DataView. It automatically selects the correct layout (List, Table, Grid, Detail) based on the spec.

import { DataViewRenderer } from '@lssm-tech/lib.design-system';
import { MyUserList } from './specs/users.data-view';

export function UserPage() {
  return (
    <DataViewRenderer
      spec={MyUserList}
      items={users}
      pagination={{ page: 1, pageSize: 20, total: 100 }}
      onPageChange={(page) => fetchPage(page)}
    />
  );
}

Props

  • spec

    : The DataViewSpec definition.

  • items

    : Array of data items to render.

  • filters

    : Current filter state object.

  • onFilterChange

    : Callback when typed filters change. Renderers emit

    DataViewFilterValue

    objects for numeric, percent, currency, temporal, duration, and boolean filters.

  • pagination

    : Object with

    page

    ,

    pageSize

    ,

    total

    .

  • onPageChange

    : Callback when page changes.

  • viewMode

    /

    defaultViewMode

    : Controlled or initial collection mode for specs that allow

    list

    ,

    grid

    , or

    table

    projections through

    view.collection.viewModes

    .

  • density

    /

    defaultDensity

    : Controlled or initial density for collection renderers. Host apps can seed this from

    @lssm-tech/lib.personalization

    while specs can declare

    view.collection.density

    and table

    view.density

    defaults.

  • dataDepth

    /

    defaultDataDepth

    : Controlled or initial summary/standard/detailed/exhaustive projection. Fields can declare

    visibility.minDataDepth

    , and collection specs can opt into

    view.collection.personalization

    persistence hints.

Collection Defaults And Data Depth

Use one authored

DataViewSpec

for list, grid, and table experiences.

view.collection

declares allowed modes, toolbar controls, pagination defaults, density, data depth, and persistence hints.

visibility.minDataDepth

lets a field appear only when the renderer is in a detailed or exhaustive mode.

import { defineDataView } from '@lssm-tech/lib.contracts-spec/data-views';

export const AccountsDataView = defineDataView({
  meta: {
    key: 'crm.accounts',
    version: '1.0.0',
    title: 'Accounts',
    description: 'Customer account workspace',
    domain: 'crm',
    entity: 'account',
    owners: ['@crm'],
    tags: ['crm', 'accounts'],
    stability: 'stable',
  },
  source: {
    primary: { key: 'crm.accounts.list', version: '1.0.0' },
  },
  view: {
    kind: 'table',
    fields: [
      { key: 'name', label: 'Name', dataPath: 'name', sortable: true },
      { key: 'owner', label: 'Owner', dataPath: 'owner' },
      { key: 'arr', label: 'ARR', dataPath: 'arr', format: { type: 'currency', currency: 'EUR' } },
      {
        key: 'internalNotes',
        label: 'Internal notes',
        dataPath: 'internalNotes',
        visibility: { minDataDepth: 'detailed' },
      },
    ],
    columns: [
      { field: 'name' },
      { field: 'owner' },
      { field: 'arr' },
      { field: 'internalNotes' },
    ],
    collection: {
      viewModes: {
        defaultMode: 'table',
        allowedModes: ['list', 'grid', 'table'],
      },
      pagination: {
        pageSize: 25,
        pageSizeOptions: [10, 25, 50],
      },
      toolbar: {
        search: true,
        viewMode: true,
        filters: true,
        density: true,
        dataDepth: true,
      },
      density: 'comfortable',
      dataDepth: 'standard',
      personalization: {
        enabled: true,
        persist: {
          viewMode: true,
          density: true,
          dataDepth: true,
          pageSize: true,
        },
      },
    },
  },
});

Personalization Bridge

Resolve user preferences in the host app, then pass ordinary renderer props into

DataViewRenderer

. The bridge helper lives in

@lssm-tech/lib.personalization

, so the design-system renderer stays portable for apps that do not use personalization. See the

personalization library guide

for the behavior tracker, analyzer, and DataView preference resolver.

import { DataViewRenderer } from '@lssm-tech/lib.design-system';
import { resolveDataViewPreferences } from '@lssm-tech/lib.personalization/data-view-preferences';

const resolved = resolveDataViewPreferences({
  spec: AccountsDataView,
  preferences: profile.canonical,
  insights,
  record: savedDataViewPreference,
});

<DataViewRenderer
  spec={AccountsDataView}
  items={accounts}
  defaultViewMode={resolved.viewMode}
  defaultDensity={resolved.density}
  defaultDataDepth={resolved.dataDepth}
  pagination={{
    page,
    pageSize: resolved.pageSize ?? 25,
    total,
  }}
  onViewModeChange={(viewMode) => {
    tracker.trackDataViewInteraction({
      dataViewKey: AccountsDataView.meta.key,
      dataViewVersion: AccountsDataView.meta.version,
      action: 'view_mode_changed',
      viewMode,
    });
  }}
  onDensityChange={(density) => {
    tracker.trackDataViewInteraction({
      dataViewKey: AccountsDataView.meta.key,
      action: 'density_changed',
      density,
    });
  }}
  onDataDepthChange={(dataDepth) => {
    tracker.trackDataViewInteraction({
      dataViewKey: AccountsDataView.meta.key,
      action: 'data_depth_changed',
      dataDepth,
    });
  }}
/>;

Agent Prompt

Use this prompt when asking an implementation agent to add a preference-aware collection DataView without breaking package boundaries.

Implement a production DataView for <entity>.

Requirements:
- Define one canonical DataViewSpec with kind 'table', collection viewModes for list/grid/table, pagination defaults, toolbar search/filter/view mode/density/dataDepth controls, and personalization persist hints.
- Mark fields that should only appear in richer experiences with visibility.minDataDepth.
- Render it with DataViewRenderer using plain props from resolveDataViewPreferences.
- Track user interactions with trackDataViewInteraction for view mode, density, data depth, search, filters, sorting, and pagination.
- Keep @lssm-tech/lib.design-system independent from @lssm-tech/lib.personalization.
- Add focused tests for default resolution, invalid-mode fallback, data-depth projection, and behavior-derived preferred view mode.

Query Generation

The

DataViewQueryGenerator

utility helps translate DataView parameters (filters, sorting, pagination) into query arguments for your backend.

import { DataViewQueryGenerator } from '@lssm-tech/lib.contracts-spec/data-views/query-generator';

const generator = new DataViewQueryGenerator(MyUserList);
const params = {
  pagination: { page: 1, pageSize: 20 },
  filters: {
    role: { kind: 'single', value: 'admin' },
    revenue: { kind: 'range', from: 1000, to: 5000 },
    lastSeenAt: { kind: 'single', value: '2026-04-28T08:30:00Z' }
  }
};

const errors = generator.validateParams(params);
const query = generator.generate(params);

// query.input contains skip/take plus the typed filter payloads.