diff --git a/docs/DEVELOPERS.md b/docs/DEVELOPERS.md
index 1bae471e..baa2f8fc 100644
--- a/docs/DEVELOPERS.md
+++ b/docs/DEVELOPERS.md
@@ -24,18 +24,24 @@ The application follows a component-based architecture where each tool is encaps
│ │ └── 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
+│ │ ├── 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
@@ -92,6 +98,34 @@ 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/`
@@ -142,6 +176,25 @@ 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();
@@ -217,10 +270,40 @@ Recommended testing approach:
## Performance Considerations
-- Minimize `context.sync()` calls, especially in loops
-- Batch operations when possible
+### 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
@@ -236,11 +319,14 @@ Recommended testing approach:
## Best Practices
-1. **Error Handling**: Always use try/catch blocks with PowerPoint API calls
-2. **User Feedback**: Provide clear status messages for all operations
-3. **Accessibility**: Ensure all UI elements have proper labels and keyboard access
+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
diff --git a/docs/USER_GUIDE.md b/docs/USER_GUIDE.md
index 53f151ae..dc75717a 100644
--- a/docs/USER_GUIDE.md
+++ b/docs/USER_GUIDE.md
@@ -212,4 +212,12 @@ If you encounter issues not covered in this guide, contact your IT department or
## Version Information
-This user guide is for Edison PowerPoint Add-in v1.0.0.
\ No newline at end of file
+This user guide is for Edison PowerPoint Add-in v1.1.0.
+
+### What's New in v1.1.0
+
+* **Performance Improvements** - Faster operations especially when working with multiple shapes
+* **Enhanced Stability** - Improved error handling and recovery
+* **Better UI Experience** - More responsive interface with improved scrolling
+* **Accessibility Enhancements** - Better support for screen readers and keyboard navigation
+* **Code Quality** - Improved TypeScript typing for increased reliability
\ No newline at end of file
diff --git a/package.json b/package.json
index 8863736b..2899e9ee 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "edison-powerpoint-addin",
- "version": "1.0.0",
+ "version": "1.1.0",
"repository": {
"type": "git",
"url": "https://github.com/OfficeDev/Office-Addin-TaskPane-React.git"
diff --git a/src/taskpane/components/App.tsx b/src/taskpane/components/App.tsx
index e65525dc..0760651f 100644
--- a/src/taskpane/components/App.tsx
+++ b/src/taskpane/components/App.tsx
@@ -193,7 +193,7 @@ const App: React.FC = () => {
)}