import type { CSSProperties } from 'react';
import type { JsonSchemaObject } from '../json-schema';
import type { RendererId, TemplateInfo } from '../renderers';
import type { BlockConfig } from './blocks';
import type { ContentMeta, Folder, KnapsackImage } from '../misc';
import type { Page } from './page';
import type { PatternTab } from './tabs';
import type { TokenSrcValueInfo } from './design-tokens-types/token-src-value-info';
export interface KsStatus {
    id: string;
    title: string;
    color?: string;
}
export interface KsStatusSet {
    id: string;
    title: string;
    statuses: KsStatus[];
}
/**
 * Used by template renderers in addition to `path`
 * Twig: `@components/button.twig`
 * Web Components: `my-button` => `<my-button>`
 * React: a named export of the file if not `default`
 * @todo Replace this with {@link TemplateInfo}
 */
type TemplateAlias = string;
export type SlottedTemplateDemo = {
    type: 'template-demo';
    /**
     * The demo referenced by `demoId` is inlined here before sending to server to
     * render, but is never stored in the json data. If this is present, it is
     * used instead of the demo referenced by `demoId`. This is done to ensure
     * server has all the latest data for a template demo by ensuring it includes
     * it's slotted children's data.
     * @see {inlineDemoData}
     */
    demo?: DemoWithData;
    /**
     * ID will be to demo that must be {@link DemoWithData}
     */
    demoId: DemoWithData['id'];
};
/**
 * i.e. Given a React Component, `Button`, this set to null/false would be
 * `<Button>` and set to true it would just be a reference to it: `Button`
 * @see {KsSlotInfo['isTemplateReference']}
 */
export type SlottedTemplateReference = {
    type: 'template-reference';
    patternId: string;
    templateId: string;
};
export type SlottedText = {
    type: 'text';
    text: string;
};
export type SlottedData = SlottedText | SlottedTemplateDemo | SlottedTemplateReference;
/**
 * Collection ID: Mode ID
 */
export type ThemeDefinition = {
    [collectionId: string]: string;
};
export type SlotOptions = {
    /**
     * @default 'div'
     */
    wrappingElementName?: string;
    cssClasses?: string[];
    align?: {
        value: 'top-left' | 'top-center' | 'top-right' | 'left' | 'center' | 'right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
    };
    layout?: {
        value: 'horizontal' | 'vertical' | 'wrap';
    };
    gap?: {
        value: TokenSrcValueInfo<'dimension'>;
    };
    paddingHorizontal?: {
        value: TokenSrcValueInfo<'dimension'>[];
    };
    paddingVertical?: {
        value: TokenSrcValueInfo<'dimension'>[];
    };
    /**
     * Collection ID: Mode ID
     */
    theme?: ThemeDefinition;
};
/**
 * These are created from {SlotOptions}
 * Only available in App Client for rendering - this is NOT saved in App Client Data
 */
export type SlotOptionsComputed = {
    styles: CSSProperties;
    cssClasses: string[];
    /**
     * @default 'div'
     */
    wrappingElementName: string;
    /**
     * can't be `style` or `class` or `className`
     */
    attributes: {
        [attributeName: string]: string;
    };
};
export type KnapsackTemplateData = {
    /**
     * @todo Ideal would be `{ [key: string]: string | boolean | number }`
     */
    props: {
        [prop: string]: unknown;
    };
    slots?: {
        [slotName: string]: Array<SlottedData>;
    };
    /**
     * Settings from users are stored here and saved in App Client Data
     * This is used to dynamically create `slotsOptionsComputed`
     */
    slotsOptions?: {
        [slotName: string]: SlotOptions;
    };
    /**
     * Use `slotsOptions` to set & save styles on slotted children
     * Never set nor stored in App Client Data that gets saved
     * This is only inlined in the demo data for rendering so the App Client can
     * apply the styles to the slotted children
     * @see {inlineDemoData}
     */
    slotsOptionsComputed?: {
        [slotName: string]: SlotOptionsComputed;
    };
};
type DemoBase = {
    id: string;
    title: string;
    description?: string;
    /**
     * Would override what was on the template
     */
    assetSetId?: string;
    width?: number;
    height?: number;
    /** Collection ID: Mode ID */
    theme?: ThemeDefinition;
    meta: ContentMeta;
};
/**
 * A {@link Demo} that has data from a form and a template to render
 * Uses `patternId` & `templateId` to find the template to render
 * @see {@link TemplateDemo}
 * @see {@link DataDemoWithTemplateInfo}
 */
export type DataDemo = DemoBase & {
    type: 'data';
    patternId: string;
    templateId: string;
    data: KnapsackTemplateData;
};
/**
 * A {@link Demo} that shows source code from a rendered template that is passed no data
 * @see {@link DataDemo}
 * @see {@link DataDemoWithTemplateInfo}
 */
export type TemplateDemo = DemoBase & {
    type: 'template';
    templateInfo: {
        alias?: TemplateAlias;
        path?: string;
    };
};
/**
 * A {@link Demo} that has data from a form and a template to render
 * Similar to {@link DataDemo} but instead of using `patternId` & `templateId`
 * it uses `templateInfo` which is {@link TemplateInfo} and contains renderer specific information
 * for finding things like package path & named export (which `patternId` & `templateId` were used to find)
 * @see {@link DataDemo}
 * @see {@link TemplateDemo}
 */
export type DataDemoWithTemplateInfo = DemoBase & {
    type: 'data-w-template-info';
    templateInfo: TemplateInfo;
    data: KnapsackTemplateData;
};
/**
 * A Demo that results in rendered HTML seen in iFrame Stage.
 * Can be one of:
 * - {@link DataDemo}
 * - {@link DataDemoWithTemplateInfo}
 * - {@link TemplateDemo}
 */
export type Demo = TemplateDemo | DataDemo | DataDemoWithTemplateInfo;
/**
 * A {@link Demo} that has data from a form
 * @see {@link DataDemo}
 * @see {@link DataDemoWithTemplateInfo}
 * @see {@link isDemoWithData}
 */
export type DemoWithData = DataDemo | DataDemoWithTemplateInfo;
export type RenderDataDemo = Demo & {
    inlineStyles?: string;
    bodyAttributes?: Record<string, string>;
};
/**
 * Does this demo have data from the stage form?
 * Can be one of these kinds of {@link Demo} types:
 * - {@link DataDemo}
 * - {@link DataDemoWithTemplateInfo}
 */
export declare function isDemoWithData(demo: Demo): demo is DataDemo | DataDemoWithTemplateInfo;
export declare function isDataDemo(demo: Demo): demo is DataDemo;
export declare function isTemplateDemo(demo: Demo): demo is TemplateDemo;
export type KsSlotInfo = {
    title: string;
    description?: string;
    disallowText?: boolean;
    isRequired?: boolean;
    allowOnlyOne?: boolean;
    /**
     * i.e. Given a React Component, `Button`, this set to null/false would be
     * `<Button>` and set to true it would just be a reference to it: `Button`
     * @see {SlottedTemplateReference}
     */
    isTemplateReference?: boolean;
    allowedPatternIds?: string[];
};
/**
 * Supersedes `schema`
 */
export type KsTemplateSpec<IsInferred extends boolean | undefined = boolean | undefined> = {
    /**
     * Attempt to create the props & slots spec by reading the source file.
     * Prevents ability to use spec editor.
     */
    isInferred?: IsInferred;
    /**
     * JSON Schema defining the serializable data passed in
     * The classic, formerly `schema`
     */
    props?: JsonSchemaObject;
    /**
     * Child component slots
     */
    propOrder?: string[];
    slots?: {
        [name: string]: KsSlotInfo;
    };
    slotOrder?: string[];
    /**
     * @todo evaluate & refine
     */
    hidePropsTable?: boolean;
    hideSlotsTable?: boolean;
    /**
     * Extra Docs are each shown in their own table.
     * Useful for non-traditional spec docs that are more template language specific.
     * Examples: events, methods, etc
     */
    extraDocs?: {
        id: string;
        title: string;
        description?: string;
        tableRows?: {
            [columnTitle: string]: string;
        }[];
    }[];
};
/**
 * Used in {@link KsSpecMeta}
 */
export type KsSpecPropConfig = {
    hidden?: boolean;
};
/**
 * Metadata for {@link KsTemplateSpec}
 * Kept outside of the `spec` object b/c when it's `isInferred: true` the whole object gets replaced with `{ isInferred: true }`
 */
export type KsSpecMeta = {
    propOrder?: string[];
    slotOrder?: string[];
    propFilters?: string[];
    propConfig?: Record<string, KsSpecPropConfig>;
};
export interface KnapsackPatternTemplate {
    id: string;
    title?: string;
    /**
     * Relative file path to the template from the config file it is declared in
     */
    path: string;
    alias?: TemplateAlias;
    /**
     * Which template language? i.e. `twig`, `react` Replaces
     * KnapsackTemplateRenderer.test which ran a test on the file path (similar to
     * how WebPack loader `test` works)
     */
    templateLanguageId: RendererId;
    assetSetIds?: string[];
    spec?: {
        isInferred: true;
    } | KsTemplateSpec<false | undefined>;
    specMeta?: KsSpecMeta;
    /** Array of demo IDs, actual demo data is stored in `db.demos.demosById` */
    demoIds: Demo['id'][];
    /** Array of block IDs, actual block content is stored in db.blocks.blocksById */
    blockIds: BlockConfig['id'][];
}
/**
 * Determines if a `template.spec` is not inferred and therefore has a `props` object
 * @see {@link KsTemplateSpec}
 */
export declare function isSpecNotInferred(spec: KnapsackPatternTemplate['spec']): spec is KsTemplateSpec<false>;
export type KnapsackPattern = Page & {
    $schema?: string;
    statuses?: {
        [statusSetId: string]: string;
    };
    templates?: KnapsackPatternTemplate[];
    /**
     * @TODO: subPages will be deprecated in favor of tabs soon
     * */
    subPages?: {
        id: string;
        title: string;
        blockIds: BlockConfig['id'][];
    }[];
    designSrcComponentsById?: Record<string, {
        id: string;
        title: string;
        componentId: string;
        fileId: string;
    }>;
    /** Controls order of `templates` & `subPages` on Pattern Page */
    tabs?: PatternTab[];
    aliases?: string[];
    /**
     * Prevents pattern from appearing in System Overview and Status Table blocks
     */
    hideFromOverviewBlocks?: boolean;
    /**
     * Prevents pattern from appearing as an option in Component Embed and
     * Component Demo blocks
     */
    hideFromComponentBlocks?: boolean;
    hideStatusSets?: boolean;
    thumbnail?: KnapsackImage;
    demoFoldersById?: Record<string, Folder>;
    demoFoldersOrder?: Array<Folder['id']>;
};
export interface KnapsackPatternTemplateCode {
    html: string;
    data?: Record<string, any>;
    templateSrc: string;
    usage: string;
    language: string;
}
export type KnapsackPatternsConfig = {
    $schema?: string;
    statusSets: KsStatusSet[];
};
export interface TemplateRendererMeta {
    id: RendererId;
    title: string;
    version?: string;
    aliasTitle?: string;
    aliasDescription?: string;
    aliasUse: 'off' | 'optional' | 'required';
    aliasIsJsNamedExport?: boolean;
    syntaxHighlightingLanguage?: string;
    enableDataDemos: boolean;
    enableTemplateDemos: boolean;
    hasSlotsSupport: boolean;
    hasSlotOptionsSupport?: boolean;
    hasInferSpecSupport: boolean;
    hasTemplateSuggestionsSupport: boolean;
    prototypingTemplate?: {
        path: string;
        alias?: string;
        spec: Pick<KsTemplateSpec, 'props' | 'slots' | 'isInferred'>;
    };
}
export type PatternsState = {
    patterns: {
        [id: string]: KnapsackPattern;
    };
    renderers: Partial<Record<RendererId, {
        meta: TemplateRendererMeta;
    }>>;
} & KnapsackPatternsConfig;
export {};
//# sourceMappingURL=patterns.d.ts.map