import { FieldSchema, StructureSchema } from '@ephox/boulder'; import type { Optional, Result } from '@ephox/katamari'; import * as ComponentSchema from '../../core/ComponentSchema'; import { type DialogToggleMenuItem, dialogToggleMenuItemSchema, type DialogToggleMenuItemSpec } from './ToggleMenuItem'; export type DialogFooterMenuButtonItemSpec = DialogToggleMenuItemSpec; export type DialogFooterToggleMenuItem = DialogToggleMenuItem; // Note: This interface doesn't extend from a common button interface as this is only a configuration that specifies a button, but it's not by itself a button. interface BaseDialogFooterButtonSpec { name?: string; align?: 'start' | 'end'; /** @deprecated use `buttonType: "primary"` instead */ primary?: boolean; enabled?: boolean; icon?: string; buttonType?: 'primary' | 'secondary'; context?: string; } export interface DialogFooterNormalButtonSpec extends BaseDialogFooterButtonSpec { type: 'submit' | 'cancel' | 'custom'; text: string; } export interface DialogFooterMenuButtonSpec extends BaseDialogFooterButtonSpec { type: 'menu'; text?: string; tooltip?: string; icon?: string; items: DialogFooterMenuButtonItemSpec[]; } export interface DialogFooterToggleButtonSpec extends BaseDialogFooterButtonSpec { type: 'togglebutton'; tooltip?: string; icon?: string; text?: string; active?: boolean; } export type DialogFooterButtonSpec = DialogFooterNormalButtonSpec | DialogFooterMenuButtonSpec | DialogFooterToggleButtonSpec; interface BaseDialogFooterButton { name: string; align: 'start' | 'end'; /** @deprecated use `buttonType: "primary"` instead */ primary: boolean; enabled: boolean; icon: Optional; buttonType: Optional<'primary' | 'secondary'>; context: string; } export interface DialogFooterNormalButton extends BaseDialogFooterButton { type: 'submit' | 'cancel' | 'custom'; text: string; } export interface DialogFooterMenuButton extends BaseDialogFooterButton { type: 'menu'; text: Optional; tooltip: Optional; icon: Optional; items: DialogFooterToggleMenuItem[]; } export interface DialogFooterToggleButton extends BaseDialogFooterButton { type: 'togglebutton'; tooltip: Optional; text: Optional; active: boolean; } export type DialogFooterButton = DialogFooterNormalButton | DialogFooterMenuButton | DialogFooterToggleButton; const baseFooterButtonFields = [ ComponentSchema.generatedName('button'), ComponentSchema.optionalIcon, FieldSchema.defaultedStringEnum('align', 'end', [ 'start', 'end' ]), // this should be removed, but must live here because FieldSchema doesn't have a way to manage deprecated fields ComponentSchema.primary, ComponentSchema.enabled, // this should be defaulted to `secondary` but the implementation needs to manage the deprecation FieldSchema.optionStringEnum('buttonType', [ 'primary', 'secondary' ]), FieldSchema.defaultedString('context', 'mode:design') ]; export const dialogFooterButtonFields = [ ...baseFooterButtonFields, ComponentSchema.text ]; const normalFooterButtonFields = [ FieldSchema.requiredStringEnum('type', [ 'submit', 'cancel', 'custom' ]), ...dialogFooterButtonFields ]; const menuFooterButtonFields = [ FieldSchema.requiredStringEnum('type', [ 'menu' ]), ComponentSchema.optionalText, ComponentSchema.optionalTooltip, ComponentSchema.optionalIcon, FieldSchema.requiredArrayOf('items', dialogToggleMenuItemSchema), ...baseFooterButtonFields ]; const toggleButtonSpecFields = [ ...baseFooterButtonFields, FieldSchema.requiredStringEnum('type', [ 'togglebutton' ]), ComponentSchema.optionalTooltip, ComponentSchema.optionalIcon, ComponentSchema.optionalText, FieldSchema.defaultedBoolean('active', false) ]; export const dialogFooterButtonSchema = StructureSchema.choose( 'type', { submit: normalFooterButtonFields, cancel: normalFooterButtonFields, custom: normalFooterButtonFields, menu: menuFooterButtonFields, togglebutton: toggleButtonSpecFields } ); export const createDialogFooterButton = (spec: DialogFooterButtonSpec): Result> => StructureSchema.asRaw('dialogfooterbutton', dialogFooterButtonSchema, spec);