# Edison PowerPoint Add-in Developer Documentation This document provides detailed technical information for developers working on the Edison PowerPoint Add-in. ## Architecture Overview Edison is a PowerPoint add-in built with: - **TypeScript** for type-safe code - **React** for UI components - **Office.js API** for PowerPoint integration - **Fluent UI** for Microsoft-style interface components The application follows a component-based architecture where each tool is encapsulated in its own React component. ## UML Diagrams To better understand the architecture and structure of the Edison PowerPoint Add-in, refer to the following UML diagrams: - [UML Diagrams Index](powerpoint-toolbox-uml-index.md) - Overview and index of all UML diagrams - [Component Relationships](powerpoint-toolbox-uml.md) - Shows the relationships between React components - [Project Structure](powerpoint-toolbox-structure-uml.md) - Illustrates the file and directory organization - [Data Flow](powerpoint-toolbox-dataflow-uml.md) - Demonstrates the flow of data and interactions These diagrams provide visual representations of the application's architecture, component relationships, and data flow patterns, which can help new developers understand the codebase more quickly. ## Project Structure ``` / ├── assets/ # Images and icons ├── dist/ # Build output (generated) ├── src/ │ ├── commands/ # Command handlers │ │ ├── commands.html # HTML for command UI │ │ └── commands.ts # Command implementations │ └── taskpane/ # Main add-in UI │ ├── components/ # React components │ │ ├── ActionButton.tsx # Reusable button with error handling │ │ ├── AlignmentButtons.tsx │ │ ├── App.tsx # Main application component │ │ ├── ConfidentialButtons.tsx │ │ ├── DraftButtons.tsx │ │ ├── GridGuidelineManager.tsx │ │ ├── Header.tsx │ │ ├── InsertTitles.tsx │ │ ├── MatchProperties.tsx │ │ ├── MatchSizes.tsx │ │ ├── ProgressBarButtons.tsx │ │ ├── RoundImage.tsx │ │ ├── Section.tsx # Reusable section component │ │ ├── SmartTextFormatter.tsx │ │ ├── SwapPositions.tsx │ │ └── commonStyles.tsx │ ├── types/ # TypeScript type definitions │ │ └── office-types.ts # Office API type utilities │ ├── index.tsx # Entry point │ └── taskpane.html # Main HTML container ├── babel.config.json # Babel configuration ├── manifest.xml # Add-in manifest ├── package.json # Dependencies and scripts ├── tsconfig.json # TypeScript configuration └── webpack.config.js # Webpack configuration ``` ## Development Environment Setup ### Prerequisites - Node.js (LTS version recommended) - npm - Microsoft PowerPoint (desktop version) ### Setup Steps 1. Clone the repository: ```bash git clone https://github.com/your-org/edison-powerpoint-addin.git cd edison-powerpoint-addin ``` 2. Install dependencies: ```bash npm install ``` 3. Build the project: ```bash npm run build:dev ``` 4. Start the development server: ```bash npm run dev-server ``` 5. Start the add-in in PowerPoint: ```bash npm run start ``` ### Local Development Certificates Office Add-ins require HTTPS even for local development. The `office-addin-dev-certs` package is used to create and install self-signed certificates for development. If you encounter certificate issues, run: ```bash npx office-addin-dev-certs install ``` ## Component Development Guidelines ### Reusable Components #### ActionButton A reusable button component that handles error states, loading states, and consistent styling: ```tsx import ActionButton from "./ActionButton"; // In your component: } onClick={myAsyncFunction} /> ``` #### Section A consistent container for organizing the UI: ```tsx import Section from "./Section"; // In your component:
``` ### Creating a New Tool 1. Create a new component file in `src/taskpane/components/` 2. Import the necessary Office.js APIs and React hooks 3. Use the StatusContext for user feedback 4. Follow the pattern of existing components: - Use the `PowerPoint.run()` method for PowerPoint operations - Provide clear success/error messaging - Handle selection states appropriately Example component structure: ```tsx import * as React from "react"; import { useState } from "react"; import { Button } from "@fluentui/react-components"; import { useStatusContext } from "./App"; const MyNewTool: React.FC = () => { const { setStatusMessage, setStatusType, isProcessing, setIsProcessing } = useStatusContext(); const performAction = async () => { setIsProcessing(true); try { await PowerPoint.run(async (context) => { // Implement your PowerPoint operations here await context.sync(); }); setStatusMessage("Operation completed successfully!"); setStatusType("success"); } catch (error) { setStatusMessage(`Error: ${error.message}`); setStatusType("error"); console.error("Operation error:", error); } finally { setIsProcessing(false); } }; return ( ); }; export default MyNewTool; ``` ### Common PowerPoint.js Operations #### Type-Safe Utilities The application provides type-safe utility functions in `src/taskpane/types/office-types.ts`: ```typescript // Get error message safely from any error type const errorMsg = getErrorMessage(error); // Check if a shape is an image if (isPictureShape(shape)) { // It's a picture shape } // Get the first selected slide const slide = getFirstSelectedSlide(context); // Select shapes by ID selectShapesById(slide, [shape1.id, shape2.id]); ``` #### Selecting Shapes ```typescript const shapes = context.presentation.getSelectedShapes(); shapes.load("items"); await context.sync(); ``` #### Working with Slide Masters ```typescript const slideMasters = context.presentation.slideMasters; slideMasters.load("items"); await context.sync(); ``` #### Creating Shapes ```typescript const shape = slide.shapes.addGeometricShape("Rectangle"); shape.left = 100; shape.top = 100; shape.height = 50; shape.width = 50; await context.sync(); ``` ## Status System The application includes a status system that provides feedback to users: - **Success**: Operation completed successfully - **Warning**: Operation completed with concerns - **Error**: Operation failed - **Processing**: Shows a spinner while operations are in progress Use the status context in your components: ```typescript const { statusMessage, setStatusMessage, statusType, setStatusType, isProcessing, setIsProcessing } = useStatusContext(); ``` ## Build and Deployment ### Development Build ```bash npm run build:dev ``` ### Production Build ```bash npm run build ``` ### Manifest Validation ```bash npm run validate ``` This validates the manifest.xml file against the Office Add-in schema. ## Testing Currently, the project doesn't have automated tests. This is an area for future improvement. Recommended testing approach: 1. Manual testing in PowerPoint 2. Implementation of unit tests for individual utilities 3. Integration tests for PowerPoint API interactions ## Performance Considerations ### Optimizing context.sync() calls A key performance optimization is to batch context.sync() calls: ```typescript // BAD: Calling context.sync() in a loop for (let i = 0; i < shapes.items.length; i++) { shapes.items[i].load("name"); await context.sync(); // Slow! One network roundtrip per shape if (shapes.items[i].name === "Target") { // Do something } } // GOOD: Batching context.sync() calls // Load all properties at once for (let i = 0; i < shapes.items.length; i++) { shapes.items[i].load("name"); } await context.sync(); // Single network roundtrip for all shapes // Process the data locally for (let i = 0; i < shapes.items.length; i++) { if (shapes.items[i].name === "Target") { // Do something } } ``` Additional performance tips: - Use memoization for expensive calculations - Ensure proper cleanup of event listeners - Use the ActionButton component for consistent loading states - Consider using Web Workers for heavy computations ## Common Issues and Solutions ### Add-in not loading in PowerPoint - Verify the development server is running - Check for certificate errors in the browser console - Validate the manifest.xml file ### PowerPoint API errors - Ensure correct API version is being used - Check the sequence of operations (some operations require specific order) - Verify selections exist before operating on them ## Best Practices 1. **Error Handling**: Always use try/catch blocks with PowerPoint API calls and use proper types (see `office-types.ts`) 2. **User Feedback**: Provide clear status messages for all operations using the StatusContext 3. **Accessibility**: Ensure all UI elements have proper ARIA attributes and support keyboard navigation 4. **Theme Support**: Use Fluent UI theme tokens for consistent theming 5. **Code Organization**: Keep component files focused on a single responsibility 6. **Performance**: Batch context.sync() calls and avoid calling them inside loops 7. **Reusability**: Use custom hooks for common operations and shared components like ActionButton and Section 8. **Type Safety**: Avoid using "any" type and leverage TypeScript's static typing ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Submit a pull request with a clear description of the changes ## Resources - [Office Add-ins Documentation](https://docs.microsoft.com/en-us/office/dev/add-ins/) - [Office.js API Reference](https://docs.microsoft.com/en-us/javascript/api/overview/office) - [Fluent UI Documentation](https://developer.microsoft.com/en-us/fluentui) - [React Documentation](https://reactjs.org/docs/getting-started.html)