DevSchema types
The simplified shape of twilight.json settings and components that virtual:twilight/schema exports and DevSettingsWidget draws.
import { DevSchema, DevSchemaField, DevSchemaComponent, DevSchemaOption, DevFieldKind } from '@salla.sa/twilight-theme-engine/dev';In plain words
twilight.json describes each setting in the dashboard's vocabulary: a type and a format per field. The dev server turns that into a simpler list the dev widget can draw: for each field, which control to show (kind), its label and its default value.
These types describe that list. They are TypeScript shapes only, removed when the theme builds. You meet them when you type a schema by hand, as the dev widget's live demo does.
Signature
type DevFieldKind = 'toggle' | 'select' | 'text' | 'readonly';
interface DevSchemaOption { label: string; value: string }
interface DevSchemaField {
id: string; // the twilight.json id, also the override key
label: string; // the entry's label, else its id
kind: DevFieldKind;
default: unknown; // null for readonly fields
options?: DevSchemaOption[]; // select only
note?: string; // readonly only: why, e.g. 'remote (products)'
}
interface DevSchemaComponent {
path: string; // 'home.brands'; falls back to the component's key
title: string; // title.en, else title.ar, else path
fields: DevSchemaField[];
}
interface DevSchema {
settings: DevSchemaField[];
components: DevSchemaComponent[];
settingsDefaults: Record<string, unknown>; // editable settings only
componentDefaults: Record<string, Record<string, unknown>>; // by component path
}Example
import type { DevSchema } from '@salla.sa/twilight-theme-engine/dev';
// What the dev server builds from:
// { "id": "footer_is_dark", "type": "boolean", "format": "switch", "label": "Dark footer", "value": false }
// { "id": "brands", "type": "items", "format": "dropdown-list", "label": "Brands", "source": "brands" }
export const sampleSchema: DevSchema = {
settings: [
{ id: 'footer_is_dark', label: 'Dark footer', kind: 'toggle', default: false },
{
id: 'brands',
label: 'Brands',
kind: 'readonly',
default: null,
note: 'remote (brands)',
},
],
components: [],
settingsDefaults: { footer_is_dark: false },
componentDefaults: {},
};
How it behaves
type: booleanbecomestoggle, withvalueas the default when it is a boolean, elsefalse.type: itemswithformat: dropdown-listand inlineoptionsbecomesselect; its default is the first ofvalue, thenselected, then the first option. Without inline options it isreadonlywith the noteremote (<source>).type: stringwith formattext,textarea,image,iconorlinebecomestext, withvalueas the default when it is a string, else''.type: staticis skipped. Anything else (collection,variable-list,number, an unknown type) isreadonlywith the note<type>/<format>. Entries without anid, and components withoutpathorkey, are dropped.virtual:twilight/schemahas the same shape, declared separately in the engine'sdist/ambient/virtual-modules.d.ts, which a theme lists underfilesintsconfig.json(aspackages/theme-custom/tsconfig.jsondoes).
Gotchas
The function that builds a
DevSchemafromtwilight.jsonis not exported, and neither is the empty schema. A schema made outside the dev server has to be written by hand, and nothing checks it against your manifest.In a production build
virtual:twilight/schemais{ settings: [], components: [], settingsDefaults: {}, componentDefaults: {} }, whatever your manifest holds. Code that reads it for anything other than the widget sees nothing once built.
Related
A development-only floating panel that lists your twilight.json settings and home-component fields with defaults, and previews edited values in vite dev.
REACT_THEME_TYPE & manifest helpersNode helpers that check twilight.json declares "type": "react", the line that tells the Salla CLI this is a React theme.
Source and docs
- Engine source:
packages/theme-engine/src/dev/schema-types.ts