diff --git a/packages/ui_dialogs/components/ui.json b/packages/ui_dialogs/components/ui.json new file mode 100644 index 000000000..fd7bed0fd --- /dev/null +++ b/packages/ui_dialogs/components/ui.json @@ -0,0 +1,360 @@ +{ + "$schema": "https://metabuilder.dev/schemas/json-script-components.schema.json", + "schemaVersion": "2.0.0", + "package": "ui_dialogs", + "description": "Dialog components for confirmations, alerts, and forms", + "components": [ + { + "id": "confirm_dialog", + "name": "ConfirmDialog", + "description": "Confirmation dialog with title, message, and confirm/cancel buttons", + "props": [ + { + "name": "open", + "type": "boolean", + "required": true, + "default": false + }, + { + "name": "title", + "type": "string", + "required": true + }, + { + "name": "message", + "type": "string", + "required": true + }, + { + "name": "confirmLabel", + "type": "string", + "default": "Confirm" + }, + { + "name": "cancelLabel", + "type": "string", + "default": "Cancel" + }, + { + "name": "severity", + "type": "string", + "default": "primary", + "enum": ["primary", "secondary", "error", "warning", "info", "success"] + } + ], + "handlers": { + "onConfirm": "confirm.handleConfirm", + "onCancel": "confirm.handleCancel", + "onClose": "confirm.handleClose" + }, + "render": { + "type": "element", + "template": { + "type": "Dialog", + "open": "{{open}}", + "maxWidth": "sm", + "fullWidth": true, + "onClose": "onClose", + "children": [ + { + "type": "DialogTitle", + "sx": { + "display": "flex", + "alignItems": "center", + "gap": 1 + }, + "children": [ + { + "type": "Icon", + "name": "HelpOutline", + "color": "{{severity}}" + }, + "{{title}}" + ] + }, + { + "type": "DialogContent", + "dividers": true, + "children": [ + { + "type": "Text", + "variant": "body1", + "color": "textSecondary", + "children": "{{message}}" + } + ] + }, + { + "type": "DialogActions", + "sx": { + "px": 3, + "py": 2, + "gap": 1 + }, + "children": [ + { + "type": "Button", + "variant": "outlined", + "color": "secondary", + "onClick": "onCancel", + "children": "{{cancelLabel}}" + }, + { + "type": "Button", + "variant": "contained", + "color": "{{severity}}", + "autoFocus": true, + "onClick": "onConfirm", + "children": "{{confirmLabel}}" + } + ] + } + ] + } + } + }, + { + "id": "alert_dialog", + "name": "AlertDialog", + "description": "Simple alert dialog with message and OK button", + "props": [ + { + "name": "open", + "type": "boolean", + "required": true, + "default": false + }, + { + "name": "title", + "type": "string", + "required": true + }, + { + "name": "message", + "type": "string", + "required": true + }, + { + "name": "confirmLabel", + "type": "string", + "default": "OK" + }, + { + "name": "severity", + "type": "string", + "default": "info", + "enum": ["info", "error", "warning", "success"] + } + ], + "handlers": { + "onConfirm": "alert.handleConfirm", + "onClose": "alert.handleClose" + }, + "render": { + "type": "element", + "template": { + "type": "Dialog", + "open": "{{open}}", + "maxWidth": "xs", + "fullWidth": true, + "onClose": "onClose", + "children": [ + { + "type": "DialogTitle", + "sx": { + "display": "flex", + "alignItems": "center", + "gap": 1 + }, + "children": [ + { + "type": "Icon", + "name": "{{severity === 'error' ? 'Error' : severity === 'warning' ? 'Warning' : severity === 'success' ? 'CheckCircle' : 'Info'}}", + "color": "{{severity}}" + }, + "{{title}}" + ] + }, + { + "type": "DialogContent", + "children": [ + { + "type": "Text", + "variant": "body1", + "color": "textSecondary", + "children": "{{message}}" + } + ] + }, + { + "type": "DialogActions", + "sx": { + "px": 3, + "py": 2 + }, + "children": [ + { + "type": "Button", + "variant": "contained", + "color": "{{severity}}", + "autoFocus": true, + "onClick": "onConfirm", + "children": "{{confirmLabel}}" + } + ] + } + ] + } + } + }, + { + "id": "form_dialog", + "name": "FormDialog", + "description": "Dialog containing a form with submit/cancel buttons", + "props": [ + { + "name": "open", + "type": "boolean", + "required": true, + "default": false + }, + { + "name": "title", + "type": "string", + "required": true + }, + { + "name": "formFields", + "type": "array", + "required": true, + "description": "Array of form field components" + }, + { + "name": "submitLabel", + "type": "string", + "default": "Submit" + }, + { + "name": "cancelLabel", + "type": "string", + "default": "Cancel" + }, + { + "name": "hideCloseButton", + "type": "boolean", + "default": false + } + ], + "state": [ + { + "name": "isSubmitting", + "type": "boolean", + "default": false + } + ], + "handlers": { + "onSubmit": "confirm.handleSubmit", + "onCancel": "confirm.handleCancel", + "onClose": "confirm.handleClose", + "validate": "confirm.validate" + }, + "render": { + "type": "element", + "template": { + "type": "Dialog", + "open": "{{open}}", + "maxWidth": "sm", + "fullWidth": true, + "onClose": "onClose", + "children": [ + { + "type": "DialogTitle", + "sx": { + "display": "flex", + "alignItems": "center", + "justifyContent": "space-between" + }, + "children": [ + { + "type": "Text", + "variant": "h6", + "children": "{{title}}" + }, + { + "type": "conditional", + "condition": "{{!hideCloseButton}}", + "then": { + "type": "IconButton", + "size": "small", + "onClick": "onClose", + "children": [ + { + "type": "Icon", + "name": "Close", + "size": 20 + } + ] + } + } + ] + }, + { + "type": "DialogContent", + "dividers": true, + "children": [ + { + "type": "Box", + "component": "form", + "onSubmit": "onSubmit", + "sx": { + "display": "flex", + "flexDirection": "column", + "gap": 2, + "pt": 1 + }, + "children": [ + { + "type": "Stack", + "direction": "column", + "spacing": 2, + "children": "{{formFields}}" + } + ] + } + ] + }, + { + "type": "DialogActions", + "sx": { + "px": 3, + "py": 2, + "gap": 1 + }, + "children": [ + { + "type": "Button", + "variant": "outlined", + "color": "secondary", + "onClick": "onCancel", + "children": "{{cancelLabel}}" + }, + { + "type": "Button", + "variant": "contained", + "color": "primary", + "type": "submit", + "disabled": "{{isSubmitting}}", + "onClick": "onSubmit", + "children": "{{submitLabel}}" + } + ] + } + ] + } + } + } + ], + "exports": { + "components": ["ConfirmDialog", "AlertDialog", "FormDialog"] + } +} diff --git a/packages/ui_dialogs/package.json b/packages/ui_dialogs/package.json new file mode 100644 index 000000000..c3c3c7c1a --- /dev/null +++ b/packages/ui_dialogs/package.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://metabuilder.dev/schemas/package-metadata.schema.json", + "packageId": "ui_dialogs", + "name": "UI Dialogs", + "version": "1.0.0", + "description": "Confirmation, alert, and form dialogs for user interactions", + "author": "MetaBuilder", + "license": "MIT", + "category": "ui", + "minLevel": 1, + "primary": false, + "dependencies": {}, + "devDependencies": { + "lua_test": "*" + }, + "exports": { + "components": [ + "ConfirmDialog", + "AlertDialog", + "FormDialog" + ], + "scripts": [ + "confirm", + "alert" + ] + }, + "tests": { + "scripts": [ + "tests/metadata.test.lua", + "tests/components.test.lua" + ], + "parameterized": [ + { + "parameters": "tests/metadata.cases.json" + }, + { + "parameters": "tests/components.cases.json" + } + ] + } +} diff --git a/packages/ui_dialogs/scripts/functions.json b/packages/ui_dialogs/scripts/functions.json new file mode 100644 index 000000000..4f743b515 --- /dev/null +++ b/packages/ui_dialogs/scripts/functions.json @@ -0,0 +1,139 @@ +{ + "$schema": "https://metabuilder.dev/schemas/json-script-functions.schema.json", + "schemaVersion": "2.0.0", + "package": "ui_dialogs", + "functions": [ + { + "id": "handleConfirm", + "namespace": "confirm", + "name": "handleConfirm", + "description": "Handle confirm button click in dialog", + "parameters": [ + { + "name": "event", + "type": "object", + "required": true, + "description": "Click event object" + } + ], + "returns": { + "type": "void" + }, + "implementation": "function(event) { this.setState({ open: false }); if (this.props.onConfirm) { this.props.onConfirm(event); } }" + }, + { + "id": "handleCancel", + "namespace": "confirm", + "name": "handleCancel", + "description": "Handle cancel button click in dialog", + "parameters": [ + { + "name": "event", + "type": "object", + "required": true, + "description": "Click event object" + } + ], + "returns": { + "type": "void" + }, + "implementation": "function(event) { this.setState({ open: false }); if (this.props.onCancel) { this.props.onCancel(event); } }" + }, + { + "id": "handleClose", + "namespace": "confirm", + "name": "handleClose", + "description": "Handle dialog close event", + "parameters": [ + { + "name": "event", + "type": "object", + "required": true, + "description": "Close event object" + }, + { + "name": "reason", + "type": "string", + "required": false, + "description": "Close reason (backdropClick, escapeKeyDown)" + } + ], + "returns": { + "type": "void" + }, + "implementation": "function(event, reason) { if (reason !== 'backdropClick') { this.setState({ open: false }); if (this.props.onClose) { this.props.onClose(event, reason); } } }" + }, + { + "id": "handleSubmit", + "namespace": "confirm", + "name": "handleSubmit", + "description": "Handle form submission in form dialog", + "parameters": [ + { + "name": "event", + "type": "object", + "required": true, + "description": "Submit event object" + } + ], + "returns": { + "type": "Promise" + }, + "implementation": "async function(event) { event.preventDefault(); const isValid = this.validate(); if (!isValid) return; this.setState({ isSubmitting: true }); try { if (this.props.onSubmit) { await this.props.onSubmit(event); } this.setState({ open: false, isSubmitting: false }); } catch (error) { this.setState({ isSubmitting: false }); throw error; } }" + }, + { + "id": "validate", + "namespace": "confirm", + "name": "validate", + "description": "Validate form fields in form dialog", + "parameters": [], + "returns": { + "type": "boolean", + "description": "True if validation passes" + }, + "implementation": "function() { if (this.props.validate) { return this.props.validate(); } return true; }" + }, + { + "id": "handleAlertConfirm", + "namespace": "alert", + "name": "handleConfirm", + "description": "Handle OK button click in alert dialog", + "parameters": [ + { + "name": "event", + "type": "object", + "required": true, + "description": "Click event object" + } + ], + "returns": { + "type": "void" + }, + "implementation": "function(event) { this.setState({ open: false }); if (this.props.onConfirm) { this.props.onConfirm(event); } }" + }, + { + "id": "handleAlertClose", + "namespace": "alert", + "name": "handleClose", + "description": "Handle alert dialog close event", + "parameters": [ + { + "name": "event", + "type": "object", + "required": true, + "description": "Close event object" + }, + { + "name": "reason", + "type": "string", + "required": false, + "description": "Close reason" + } + ], + "returns": { + "type": "void" + }, + "implementation": "function(event, reason) { this.setState({ open: false }); if (this.props.onClose) { this.props.onClose(event, reason); } }" + } + ] +} diff --git a/packages/ui_dialogs/storybook/config.json b/packages/ui_dialogs/storybook/config.json new file mode 100644 index 000000000..d13503fac --- /dev/null +++ b/packages/ui_dialogs/storybook/config.json @@ -0,0 +1,161 @@ +{ + "$schema": "https://metabuilder.dev/schemas/package-storybook.schema.json", + "featured": false, + "title": "UI Dialogs", + "description": "Confirmation, alert, and form dialogs for user interactions", + "stories": [ + { + "name": "ConfirmDialog - Primary", + "component": "ConfirmDialog", + "description": "Standard confirmation dialog", + "args": { + "open": true, + "title": "Confirm Action", + "message": "Are you sure you want to proceed with this action?", + "severity": "primary", + "confirmLabel": "Confirm", + "cancelLabel": "Cancel" + } + }, + { + "name": "ConfirmDialog - Error", + "component": "ConfirmDialog", + "description": "Delete confirmation with error severity", + "args": { + "open": true, + "title": "Delete Item", + "message": "This action cannot be undone. Are you sure you want to delete this item?", + "severity": "error", + "confirmLabel": "Delete", + "cancelLabel": "Cancel" + } + }, + { + "name": "ConfirmDialog - Warning", + "component": "ConfirmDialog", + "description": "Warning confirmation dialog", + "args": { + "open": true, + "title": "Unsaved Changes", + "message": "You have unsaved changes. Do you want to discard them?", + "severity": "warning", + "confirmLabel": "Discard", + "cancelLabel": "Keep Editing" + } + }, + { + "name": "AlertDialog - Info", + "component": "AlertDialog", + "description": "Informational alert dialog", + "args": { + "open": true, + "title": "Information", + "message": "Your changes have been saved successfully.", + "severity": "info", + "confirmLabel": "OK" + } + }, + { + "name": "AlertDialog - Success", + "component": "AlertDialog", + "description": "Success alert dialog", + "args": { + "open": true, + "title": "Success", + "message": "Operation completed successfully!", + "severity": "success", + "confirmLabel": "OK" + } + }, + { + "name": "AlertDialog - Error", + "component": "AlertDialog", + "description": "Error alert dialog", + "args": { + "open": true, + "title": "Error", + "message": "An error occurred while processing your request. Please try again.", + "severity": "error", + "confirmLabel": "OK" + } + }, + { + "name": "AlertDialog - Warning", + "component": "AlertDialog", + "description": "Warning alert dialog", + "args": { + "open": true, + "title": "Warning", + "message": "This feature is currently in beta. Use with caution.", + "severity": "warning", + "confirmLabel": "Understood" + } + }, + { + "name": "FormDialog - Simple", + "component": "FormDialog", + "description": "Form dialog with text inputs", + "args": { + "open": true, + "title": "Create New Item", + "formFields": [ + { + "type": "TextField", + "name": "name", + "label": "Name", + "required": true, + "fullWidth": true + }, + { + "type": "TextField", + "name": "description", + "label": "Description", + "multiline": true, + "rows": 3, + "fullWidth": true + } + ], + "submitLabel": "Create", + "cancelLabel": "Cancel" + } + }, + { + "name": "FormDialog - With Close Button", + "component": "FormDialog", + "description": "Form dialog with visible close button", + "args": { + "open": true, + "title": "Edit Profile", + "hideCloseButton": false, + "formFields": [ + { + "type": "TextField", + "name": "email", + "label": "Email", + "type": "email", + "required": true, + "fullWidth": true + }, + { + "type": "TextField", + "name": "phone", + "label": "Phone Number", + "fullWidth": true + } + ], + "submitLabel": "Save", + "cancelLabel": "Cancel" + } + } + ], + "defaultContext": { + "user": { + "id": "test-user", + "username": "testuser", + "level": 1 + } + }, + "parameters": { + "layout": "centered" + } +} diff --git a/packages/ui_dialogs/styles/tokens.json b/packages/ui_dialogs/styles/tokens.json new file mode 100644 index 000000000..52c9e3e59 --- /dev/null +++ b/packages/ui_dialogs/styles/tokens.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://metabuilder.dev/schemas/package-styles.schema.json", + "schemaVersion": "2.0.0", + "colors": { + "dialogOverlay": "rgba(0, 0, 0, 0.5)", + "dialogBackground": "#ffffff", + "dialogBorder": "#e0e0e0", + "titleText": "#1f2937", + "bodyText": "#6b7280", + "divider": "#e5e7eb" + }, + "spacing": { + "dialogPadding": "24px", + "titlePadding": "16px 24px", + "contentPadding": "20px 24px", + "actionsPadding": "16px 24px", + "buttonGap": "8px", + "iconGap": "8px" + }, + "sizing": { + "maxWidthSm": "600px", + "maxWidthXs": "444px", + "iconSize": "24px", + "closeIconSize": "20px" + }, + "transitions": { + "dialogEnter": "225ms cubic-bezier(0.4, 0, 0.2, 1)", + "dialogExit": "195ms cubic-bezier(0.4, 0, 0.2, 1)" + }, + "shadows": { + "dialog": "0 11px 15px -7px rgba(0,0,0,0.2), 0 24px 38px 3px rgba(0,0,0,0.14), 0 9px 46px 8px rgba(0,0,0,0.12)" + }, + "borderRadius": { + "dialog": "8px" + } +}