From 7d3115a29dd4713ef4ef097b9f370da673b8ecbc Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Fri, 19 Sep 2025 02:44:47 -0400 Subject: [PATCH 01/42] Reworks all addOnUISdk constants ref and explanation, new how-to --- .../guides/learn/how_to/ui_sdk_constants.md | 486 ++++++++++++++++++ .../references/addonsdk/addonsdk-constants.md | 324 +++++++++++- 2 files changed, 802 insertions(+), 8 deletions(-) create mode 100644 src/pages/guides/learn/how_to/ui_sdk_constants.md diff --git a/src/pages/guides/learn/how_to/ui_sdk_constants.md b/src/pages/guides/learn/how_to/ui_sdk_constants.md new file mode 100644 index 000000000..d107f4aaa --- /dev/null +++ b/src/pages/guides/learn/how_to/ui_sdk_constants.md @@ -0,0 +1,486 @@ +# Using Add-on UI SDK Constants + +This guide shows you how to effectively use constants in your Adobe Express add-ons. Constants provide type-safe ways to interact with the Add-on UI SDK and help prevent runtime errors. + +For complete technical specifications of all constants, see the [Constants Reference](../../../references/addonsdk/addonsdk-constants.md). + + + +**Quick Import Guide:** Some constants require explicit imports, others don't. Check the [Import Quick Reference](#import-quick-reference) below or use the [Constants Cheat Sheet](#constants-cheat-sheet) to avoid runtime errors. + + + +**Why Use Constants?** Constants are equal to their variable name as a string value (e.g., `ButtonType.primary` equals `"primary"`), but using constants provides type safety, IDE autocomplete, and future-proofing against API changes. + +## Quick Start + +Most constants support two import patterns. Choose based on your needs: + +```javascript +// Named imports (recommended for cleaner code) +import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Constants object access (good for dynamic access) +const format = addOnUISdk.constants.RenditionFormat.png; +``` + + + +**Important:** Some constants (like `AppEvent`, `SupportedMimeTypes`) are **only available as named exports** and cannot be accessed through `addOnUISdk.constants.*`. See [Import Patterns](#import-patterns) below. + +## Constants Cheat Sheet + +This quick reference shows you exactly how to import and use each constant type. Copy the import statements you need: + +### Most Common Constants (Copy & Paste Ready) + +```javascript +// For document export/rendering +import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Usage examples: +const options = { + range: Range.currentPage, // or: addOnUISdk.constants.Range.currentPage + format: RenditionFormat.png, // or: addOnUISdk.constants.RenditionFormat.png + intent: RenditionIntent.export // or: addOnUISdk.constants.RenditionIntent.export +}; +``` + +```javascript +// For modal dialogs +import addOnUISdk, { Variant, ButtonType, FieldType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Usage examples: +const dialogOptions = { + variant: Variant.confirmation, // or: addOnUISdk.constants.Variant.confirmation + // ... handle result.buttonType === ButtonType.primary +}; +``` + +```javascript +// For events (MUST import - not available in constants object) +import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Usage examples: +addOnUISdk.app.on(AppEvent.themechange, handler); +picker.addEventListener(ColorPickerEvent.colorChange, handler); +// ❌ addOnUISdk.constants.AppEvent.themechange <- This will NOT work! +``` + +```javascript +// For platform detection +import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Usage examples: +if (platform.platformType === PlatformType.iOS) { /* iOS code */ } +if (platform.deviceClass === DeviceClass.mobile) { /* mobile UI */ } +``` + +### Import Required (Cannot Use Constants Object) + +These constants **must be imported** - they're not available through `addOnUISdk.constants.*`: + +| Constant | Import | Won't Work | +|----------|---------|---------------| +| `AppEvent` | `import { AppEvent }` | `addOnUISdk.constants.AppEvent` | +| `ColorPickerEvent` | `import { ColorPickerEvent }` | `addOnUISdk.constants.ColorPickerEvent` | +| `SupportedMimeTypes` | `import { SupportedMimeTypes }` | `addOnUISdk.constants.SupportedMimeTypes` | +| `EntrypointType` | `import { EntrypointType }` | `addOnUISdk.constants.EntrypointType` | +| `PdfReturnUrlType` | `import { PdfReturnUrlType }` | `addOnUISdk.constants.PdfReturnUrlType` | + +### Flexible Access (Both Ways Work) + +These constants can be used with **either** import pattern: + +| Constant | Named Import | Constants Object | +|----------|--------------|------------------| +| `Range` | `Range.currentPage` | `addOnUISdk.constants.Range.currentPage` | +| `RenditionFormat` | `RenditionFormat.png` | `addOnUISdk.constants.RenditionFormat.png` | +| `Variant` | `Variant.confirmation` | `addOnUISdk.constants.Variant.confirmation` | +| `ButtonType` | `ButtonType.primary` | `addOnUISdk.constants.ButtonType.primary` | +| `PlatformType` | `PlatformType.iOS` | `addOnUISdk.constants.PlatformType.iOS` | +| `EditorPanel` | `EditorPanel.media` | `addOnUISdk.constants.EditorPanel.media` | + +*Complete list in [Import Patterns](#import-patterns) section.* + +## Common Use Cases by Category + +### Dialog & UI Interactions + +Use these constants when creating modal dialogs and handling user interactions: + +```javascript +import addOnUISdk, { Variant, ButtonType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Show different dialog types +await addOnUISdk.app.showModalDialog({ + variant: Variant.error, // Error dialog + title: "Upload Failed", + description: "File size exceeds limit" +}); + +await addOnUISdk.app.showModalDialog({ + variant: Variant.confirmation, // Confirmation dialog + title: "Delete Item", + description: "Are you sure?" +}); + +// Handle dialog responses +const result = await addOnUISdk.app.showModalDialog({...}); +if (result.buttonType === ButtonType.primary) { + // User clicked primary button +} else if (result.buttonType === ButtonType.cancel) { + // User cancelled +} +``` + +**Available Dialog Constants:** + +- `Variant`: `confirmation`, `information`, `warning`, `destructive`, `error`, `input`, `custom` +- `ButtonType`: `primary`, `secondary`, `cancel`, `close` +- `FieldType`: `text` (for input dialogs) + +### Document Export & Rendering + +Use these constants when creating renditions (exports) of documents: + +```javascript +import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Export current page as PNG +await addOnUISdk.app.document.createRenditions({ + range: Range.currentPage, + format: RenditionFormat.png +}); + +// Export entire document as PDF for printing +await addOnUISdk.app.document.createRenditions({ + range: Range.entireDocument, + format: RenditionFormat.pdf, + intent: RenditionIntent.print +}); + +// Export specific pages as JPG +await addOnUISdk.app.document.createRenditions({ + range: Range.specificPages, + pageIds: ["page1", "page3"], + format: RenditionFormat.jpg +}); +``` + +**Available Export Constants:** + +- `Range`: `currentPage`, `entireDocument`, `specificPages` +- `RenditionFormat`: `png`, `jpg`, `mp4`, `pdf`, `pptx` +- `RenditionIntent`: `export`, `preview`, `print` + +### Platform Detection + +Use these constants to create responsive add-ons that work across different platforms: + +```javascript +import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +const platform = await addOnUISdk.app.getCurrentPlatform(); + +// Platform-specific behavior +if (platform.platformType === PlatformType.iOS || platform.platformType === PlatformType.iPadOS) { + // iOS/iPadOS specific handling + showTouchOptimizedUI(); +} else if (platform.platformType === PlatformType.chromeBrowser) { + // Chrome browser specific handling + enableKeyboardShortcuts(); +} + +// Device class responsive design +if (platform.deviceClass === DeviceClass.mobile) { + showMobileLayout(); +} else if (platform.deviceClass === DeviceClass.desktop) { + showDesktopLayout(); +} + +// Environment-specific features +if (platform.environment === PlatformEnvironment.app) { + // Native app features available + enableAdvancedFeatures(); +} else { + // Web browser limitations + showWebFallback(); +} +``` + +**Available Platform Constants:** + +- `PlatformType`: `iOS`, `iPadOS`, `android`, `chromeBrowser`, `firefoxBrowser`, etc. +- `DeviceClass`: `mobile`, `tablet`, `desktop` +- `PlatformEnvironment`: `app`, `web` + +### Editor Panel Navigation + +Use these constants to programmatically navigate Express editor panels: + +```javascript +import addOnUISdk, { EditorPanel, MediaTabs, ElementsTabs } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Open specific editor panels +addOnUISdk.app.ui.openEditorPanel(EditorPanel.media); +addOnUISdk.app.ui.openEditorPanel(EditorPanel.elements); +addOnUISdk.app.ui.openEditorPanel(EditorPanel.text); + +// Navigate to specific tabs within panels +addOnUISdk.app.ui.openEditorPanel(EditorPanel.media, { + tab: MediaTabs.photos +}); + +addOnUISdk.app.ui.openEditorPanel(EditorPanel.elements, { + tab: ElementsTabs.shapes +}); +``` + +**Available Navigation Constants:** + +- `EditorPanel`: `search`, `yourStuff`, `templates`, `media`, `text`, `elements`, `grids`, `brands`, `addOns` +- `MediaTabs`: `video`, `audio`, `photos` +- `ElementsTabs`: `designAssets`, `backgrounds`, `shapes`, `stockIcons`, `charts` + +### Event Handling + +Use these constants when listening to SDK events: + +```javascript +import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Listen to app events (named export only!) +addOnUISdk.app.on(AppEvent.themechange, (event) => { + updateUITheme(event.theme); +}); + +addOnUISdk.app.on(AppEvent.documentTitleChange, (event) => { + console.log("Document title changed to:", event.title); +}); + +// Color picker events (named export only!) +colorPickerElement.addEventListener(ColorPickerEvent.colorChange, (event) => { + applyColor(event.color); +}); +``` + + + +**Event constants are named-export only** - they cannot be accessed through `addOnUISdk.constants.*`. + +## Import Patterns + +Understanding import patterns is crucial for avoiding runtime errors. + +### Named Exports (Import Required) + +These constants **must be imported** and are **not available** through `addOnUISdk.constants.*`: + +```javascript +import addOnUISdk, { + AppEvent, // ❌ NOT in constants object + ColorPickerEvent, // ❌ NOT in constants object + SupportedMimeTypes, // ❌ NOT in constants object + EntrypointType, // ❌ NOT in constants object + PdfReturnUrlType // ❌ NOT in constants object +} from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// ✅ Correct usage +const docxType = SupportedMimeTypes.docx; +const colorEvent = ColorPickerEvent.colorChange; + +// ❌ Will NOT work - returns undefined +const docxType = addOnUISdk.constants.SupportedMimeTypes.docx; // undefined! +``` + +### Dual Access Constants + +These constants support **both patterns** - choose what works best for your code: + +```javascript +import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Option 1: Named imports (cleaner, recommended) +const options = { + range: Range.currentPage, + format: RenditionFormat.png, + variant: Variant.error +}; + +// Option 2: Constants object (good for dynamic access) +const userFormat = "png"; +const format = addOnUISdk.constants.RenditionFormat[userFormat]; +const range = addOnUISdk.constants.Range.currentPage; +``` + +**All Dual Access Constants:** +`Range`, `RenditionFormat`, `RenditionType`, `RenditionIntent`, `Variant`, `DialogResultType`, `ButtonType`, `RuntimeType`, `BleedUnit`, `EditorPanel`, `MediaTabs`, `ElementsTabs`, `PanelActionType`, `ColorPickerPlacement`, `AuthorizationStatus`, `FieldType`, `PlatformEnvironment`, `DeviceClass`, `PlatformType`, `MediaType`, `VideoResolution`, `FrameRate`, `BitRate`, `FileSizeLimitUnit`, `LinkOptions` + +## Best Practices + +### 1. Use Named Imports for Known Constants + +When you know which constants you need, use named imports for cleaner code: + +```javascript +// ✅ Good - clear and concise +import addOnUISdk, { Range, RenditionFormat } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +const options = { + range: Range.currentPage, + format: RenditionFormat.png +}; +``` + +### 2. Use Constants Object for Dynamic Access + +When the constant name is determined at runtime: + +```javascript +// ✅ Good - dynamic constant access +const userSelectedFormat = getUserSelection(); // "png", "jpg", etc. +const format = addOnUISdk.constants.RenditionFormat[userSelectedFormat]; +``` + +### 3. Always Import Named-Only Exports + +There's no alternative way to access these: + +```javascript +// ✅ Required - no other way to access these +import addOnUISdk, { AppEvent, SupportedMimeTypes } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +``` + +### 4. Group Related Imports + +Organize imports by functionality: + +```javascript +import addOnUISdk, { + // Dialog constants + Variant, ButtonType, FieldType, + // Export constants + Range, RenditionFormat, RenditionIntent, + // Platform constants + PlatformType, DeviceClass, + // Event constants (named-only) + AppEvent, ColorPickerEvent +} from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +``` + +## Troubleshooting + + + +**Most Common Error:** `Cannot read property 'X' of undefined` - This happens when you try to access import-required constants through the constants object. + +### "Cannot read property of undefined" Errors + +**Problem**: Trying to access named-only exports through constants object. + +```javascript +// ❌ This causes errors +const event = addOnUISdk.constants.AppEvent.themechange; // undefined! +const mimeType = addOnUISdk.constants.SupportedMimeTypes.docx; // undefined! +``` + +**Solution**: Always import named-only exports. + +```javascript +// ✅ This works +import addOnUISdk, { AppEvent, SupportedMimeTypes } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +const event = AppEvent.themechange; +const mimeType = SupportedMimeTypes.docx; +``` + +### TypeScript Type Errors + +**Problem**: TypeScript doesn't recognize constant values. + +**Solution**: Use proper imports for type checking: + +```typescript +import addOnUISdk, { Range, RenditionFormat } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// ✅ TypeScript knows these types +const options: RenditionOptions = { + range: Range.currentPage, // Type-safe + format: RenditionFormat.png // Type-safe +}; +``` + +### Runtime "Invalid constant" Errors + +**Problem**: Using string literals instead of constants. + +```javascript +// ❌ Fragile - might break if API changes +await createRenditions({ + range: "currentPage", // String literal + format: "image/png" // String literal +}); +``` + +**Solution**: Always use constants for future compatibility. + +```javascript +// ✅ Safe - will be updated if API changes +await createRenditions({ + range: Range.currentPage, // Constant + format: RenditionFormat.png // Constant +}); +``` + +### Quick Debug Checklist + +When you encounter constant-related errors: + +1. **Check if the constant requires import**: Look for constants marked as import-required in the [cheat sheet](#constants-cheat-sheet) +2. **Verify your import statement**: Make sure you're importing the constant name exactly as documented +3. **Use TypeScript**: Add types to catch import issues at development time +4. **Test your constants**: Log the constant values to ensure they're defined: + +```javascript +console.log('Range:', Range); // Should log the Range object +console.log('AppEvent:', AppEvent); // Should log the AppEvent object +``` + +## Related Guides + +- [Create Renditions](./create_renditions.md) - Using export constants +- [Modal Dialogs](./modal_dialogs.md) - Using dialog constants +- [Theme & Locale](./theme_locale.md) - Using platform constants +- [Constants Reference](../../../references/addonsdk/addonsdk-constants.md) - Complete technical specification + +## Import Quick Reference + +| Need | What to Import | Copy This | +|------|----------------|-----------| +| **Document Export** | `Range, RenditionFormat, RenditionIntent` | `import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` | +| **Modal Dialogs** | `Variant, ButtonType, FieldType` | `import addOnUISdk, { Variant, ButtonType, FieldType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` | +| **Events** | `AppEvent, ColorPickerEvent` | `import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` | +| **Platform Detection** | `PlatformType, DeviceClass, PlatformEnvironment` | `import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` | +| **Editor Panels** | `EditorPanel, MediaTabs, ElementsTabs` | `import addOnUISdk, { EditorPanel, MediaTabs, ElementsTabs } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` | +| **File Types** | `SupportedMimeTypes` | `import addOnUISdk, { SupportedMimeTypes } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` | + + + +**Pro Tip:** You can import multiple constants in one statement: `import addOnUISdk, { Range, RenditionFormat, Variant, ButtonType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` + +## When to Use Which Pattern + +### Use Named Imports When: + +- You know which constants you need at development time +- You want cleaner, more readable code +- You're using TypeScript for better autocomplete +- You want to avoid potential `undefined` errors + +### Use Constants Object When: + +- The constant name is determined at runtime +- You're migrating existing code gradually +- You prefer the traditional `addOnUISdk.constants.X` pattern + +Remember: When in doubt, use named imports - they work for all constants and provide the cleanest code! diff --git a/src/pages/references/addonsdk/addonsdk-constants.md b/src/pages/references/addonsdk/addonsdk-constants.md index ba11aab2b..6a37bae50 100644 --- a/src/pages/references/addonsdk/addonsdk-constants.md +++ b/src/pages/references/addonsdk/addonsdk-constants.md @@ -1,6 +1,213 @@ # addOnUISdk.constants -A set of constants used throughout the add-on SDK. These constants are equal to their variable name as a string value, ie: for the `ButtonType` constant, `primary` has a value of "primary". +This reference provides the complete technical specification for all constants used throughout the Add-on UI SDK, including: + +- Constants available in `addOnUISdk.constants.*` (dual access) +- Constants available only as named exports (import required) + +For practical examples and use cases, see the [Using Constants Guide](../../guides/learn/platform_concepts/ui-sdk-constants.md). + + + +The constants listed in this reference are equal to their variable name as a string value, ie: for the `ButtonType` constant, `primary` has a value of "primary". + +## Import Patterns + +Adobe Express Add-on SDK constants are available through different import patterns depending on the constant type. Understanding these patterns is imperative for avoiding runtime errors. + + + +**Critical:** Attempting to access import-required constants through `addOnUISdk.constants.*` will return `undefined` and cause runtime errors. Always check the patterns below before using any constant. + +### Named Exports Only (Import Required) + +These constants are **only available as named exports** and must be imported explicitly. They are **not** available through `addOnUISdk.constants.*`: + +```javascript +import addOnUISdk, { + AppEvent, // Import required + ColorPickerEvent, // Import required + SupportedMimeTypes, // Import required + EntrypointType, // Import required + PdfReturnUrlType // Import required +} from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// ✅ Correct usage +const docxMimeType = SupportedMimeTypes.docx; +const colorChangeEvent = ColorPickerEvent.colorChange; + +// ❌ Will NOT work - these are not in the constants object +const docxMimeType = addOnUISdk.constants.SupportedMimeTypes.docx; // undefined +``` + +### Dual Access Constants (Flexible) + +These constants support **both import patterns** for flexibility. You can use either approach: + +```javascript +import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Option 1: Named import (recommended for cleaner code) +const currentPage = Range.currentPage; +const pngFormat = RenditionFormat.png; +const confirmDialog = Variant.confirmation; + +// Option 2: Constants object access (traditional pattern) +const currentPage = addOnUISdk.constants.Range.currentPage; +const pngFormat = addOnUISdk.constants.RenditionFormat.png; +const confirmDialog = addOnUISdk.constants.Variant.confirmation; +``` + +**Dual Access Constants List:** + +- `Range` / `addOnUISdk.constants.Range` +- `RenditionFormat` / `addOnUISdk.constants.RenditionFormat` +- `RenditionType` / `addOnUISdk.constants.RenditionType` +- `RenditionIntent` / `addOnUISdk.constants.RenditionIntent` +- `Variant` / `addOnUISdk.constants.Variant` +- `DialogResultType` / `addOnUISdk.constants.DialogResultType` +- `ButtonType` / `addOnUISdk.constants.ButtonType` +- `RuntimeType` / `addOnUISdk.constants.RuntimeType` +- `BleedUnit` / `addOnUISdk.constants.BleedUnit` +- `EditorPanel` / `addOnUISdk.constants.EditorPanel` +- `MediaTabs` / `addOnUISdk.constants.MediaTabs` +- `ElementsTabs` / `addOnUISdk.constants.ElementsTabs` +- `PanelActionType` / `addOnUISdk.constants.PanelActionType` +- `ColorPickerPlacement` / `addOnUISdk.constants.ColorPickerPlacement` +- `AuthorizationStatus` / `addOnUISdk.constants.AuthorizationStatus` +- `FieldType` / `addOnUISdk.constants.FieldType` +- `PlatformEnvironment` / `addOnUISdk.constants.PlatformEnvironment` +- `DeviceClass` / `addOnUISdk.constants.DeviceClass` +- `PlatformType` / `addOnUISdk.constants.PlatformType` +- `MediaType` / `addOnUISdk.constants.MediaType` +- `VideoResolution` / `addOnUISdk.constants.VideoResolution` +- `FrameRate` / `addOnUISdk.constants.FrameRate` +- `BitRate` / `addOnUISdk.constants.BitRate` +- `FileSizeLimitUnit` / `addOnUISdk.constants.FileSizeLimitUnit` +- `LinkOptions` / `addOnUISdk.constants.LinkOptions` + +### Best Practices + +1. **Use named imports for cleaner code** when you know which constants you need: + + ```javascript + import addOnUISdk, { Range, RenditionFormat } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + + const options = { + range: Range.currentPage, + format: RenditionFormat.png + }; + ``` + +2. **Use constants object for dynamic access** when the constant name is determined at runtime: + + ```javascript + const format = addOnUISdk.constants.RenditionFormat[userSelectedFormat]; + ``` + +3. **Always import named-only exports** - there's no alternative way to access them: + + ```javascript + import addOnUISdk, { SupportedMimeTypes } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + ``` + +### Quick Reference Table + +| Constant | Named Export | Constants Object | Import Required | +|----------|--------------|------------------|-----------------| +| `AppEvent` | ✅ | ❌ | **Yes** | +| `ColorPickerEvent` | ✅ | ❌ | **Yes** | +| `SupportedMimeTypes` | ✅ | ❌ | **Yes** | +| `EntrypointType` | ✅ | ❌ | **Yes** | +| `PdfReturnUrlType` | ✅ | ❌ | **Yes** | +| `Range` | ✅ | ✅ | Optional | +| `RenditionFormat` | ✅ | ✅ | Optional | +| `Variant` | ✅ | ✅ | Optional | +| `ButtonType` | ✅ | ✅ | Optional | +| `FieldType` | ✅ | ✅ | Optional | +| `PlatformEnvironment` | ✅ | ✅ | Optional | +| `DeviceClass` | ✅ | ✅ | Optional | +| `PlatformType` | ✅ | ✅ | Optional | +| `AuthorizationStatus` | ✅ | ✅ | Optional | +| `RenditionType` | ✅ | ✅ | Optional | +| `RenditionIntent` | ✅ | ✅ | Optional | +| `DialogResultType` | ✅ | ✅ | Optional | +| `RuntimeType` | ✅ | ✅ | Optional | +| `BleedUnit` | ✅ | ✅ | Optional | +| `EditorPanel` | ✅ | ✅ | Optional | +| `MediaTabs` | ✅ | ✅ | Optional | +| `ElementsTabs` | ✅ | ✅ | Optional | +| `PanelActionType` | ✅ | ✅ | Optional | +| `ColorPickerPlacement` | ✅ | ✅ | Optional | +| `MediaType` | ✅ | ✅ | Optional | +| `VideoResolution` | ✅ | ✅ | Optional | +| `FrameRate` | ✅ | ✅ | Optional | +| `BitRate` | ✅ | ✅ | Optional | +| `FileSizeLimitUnit` | ✅ | ✅ | Optional | +| `LinkOptions` | ✅ | ✅ | Optional | + + + +**Important:** Attempting to access named-only exports through `addOnUISdk.constants.*` will return `undefined` and may cause runtime errors. Always check the table above or use TypeScript for compile-time validation. + +## Import Generator + +Use these copy-paste ready import statements for common scenarios: + +### Complete Import (All Constants) + +```javascript +// Import everything (use this if you're unsure) +import addOnUISdk, { + // Import-required constants + AppEvent, ColorPickerEvent, SupportedMimeTypes, EntrypointType, PdfReturnUrlType, + // Dual-access constants (most common) + Range, RenditionFormat, RenditionIntent, Variant, ButtonType, FieldType, + PlatformType, DeviceClass, PlatformEnvironment, EditorPanel, MediaTabs, ElementsTabs, + AuthorizationStatus, DialogResultType, RuntimeType, BleedUnit, PanelActionType, + ColorPickerPlacement, MediaType, VideoResolution, FrameRate, BitRate, FileSizeLimitUnit, LinkOptions +} from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +``` + +### By Use Case (Recommended) + +```javascript +// Document Export & Rendering +import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Modal Dialogs & UI +import addOnUISdk, { Variant, ButtonType, FieldType, DialogResultType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Event Handling (Import Required!) +import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Platform Detection +import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Editor Navigation +import addOnUISdk, { EditorPanel, MediaTabs, ElementsTabs, PanelActionType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// File Types & MIME (Import Required!) +import addOnUISdk, { SupportedMimeTypes, PdfReturnUrlType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// OAuth & Authorization +import addOnUISdk, { AuthorizationStatus } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +``` + +## Constants Reference + +This section provides the complete technical specification for all Add-on UI SDK constants, organized by functional category. For practical examples and usage patterns, see the [Using Constants Guide](../../guides/learn/platform_concepts/ui-sdk-constants.md). + +## Developer Tips + + + +**Quick Start Tips:** + +- **When in doubt, use named imports** - they work for ALL constants +- **Copy import statements** from the [Import Generator](#import-generator) above +- **Never guess** - check if constants are import-required before using +- **Use TypeScript** for compile-time validation and better IDE support ## Constants @@ -46,7 +253,7 @@ A set of constants used throughout the add-on SDK. These constants are equal to

ButtonType

string

-

The type of the button pressed in a dialog.

+

The type of the button pressed in a dialog. Dual access: both named export and constants object.

  • primary
  • Primary button pressed.
  • secondary
  • Secondary button pressed. @@ -59,7 +266,7 @@ A set of constants used throughout the add-on SDK. These constants are equal to

    ColorPickerEvent

    string

    -

    Custom events dispatched by the Color Picker.

    +

    Custom events dispatched by the Color Picker. Named export only - not available in constants object.

    • colorChange
    • "colorpicker-color-change"
    • close
    • "colorpicker-close"
      @@ -70,7 +277,7 @@ A set of constants used throughout the add-on SDK. These constants are equal to

      ColorPickerPlacement

      string

      -

      Placement of the color picker popover with respect to the anchor element.

      +

      Placement of the color picker popover with respect to the anchor element. Dual access: both named export and constants object.

      • top
      • "top"
      • bottom
      • "bottom"
        @@ -187,7 +394,7 @@ A set of constants used throughout the add-on SDK. These constants are equal to

        Range

        string

        -

        Rendition page range. Options:

        +

        Rendition page range. Dual access: both named export and constants object.

        • currentPage
        • Generate rendition for the current page
        • entireDocument
        • Generate rendition for all pages @@ -199,7 +406,7 @@ A set of constants used throughout the add-on SDK. These constants are equal to

          RenditionFormat

          string

          -

          Required output format of the rendition.

          +

          Required output format of the rendition. Dual access: both named export and constants object.

          • jpg
          • "image/jpeg"
          • png
          • "image/png"
            @@ -213,7 +420,7 @@ A set of constants used throughout the add-on SDK. These constants are equal to

            RenditionIntent

            string

            -

            The intent to set for creating the rendition. Options:

            +

            The intent to set for creating the rendition. Dual access: both named export and constants object.

            • preview
            • Intent to preview the content.
            • export
            • Intent to export/download the content (default). @@ -245,7 +452,7 @@ A set of constants used throughout the add-on SDK. These constants are equal to

              Variant

              string

              -

              Types of dialog variants supported.

              +

              Types of dialog variants supported. Dual access: both named export and constants object.

              • confirmation
              • Ask a user to confirm an action.
              • information
              • Share information for user to acknowledge. @@ -272,5 +479,106 @@ A set of constants used throughout the add-on SDK. These constants are equal to
              + +

              AppEvent

              +

              string

              + +

              Events dispatched by the Add-on SDK. Named export only - not available in constants object.

              +
                +
              • documentIdAvailable
              • Document ID becomes available +
              • documentTitleChange
              • Document title changes +
              • documentLinkAvailable
              • Document link becomes available +
              • documentPublishedLinkAvailable
              • Published document link becomes available +
              + + + +

              AuthorizationStatus

              +

              string

              + +

              OAuth authorization status values. Dual access: both named export and constants object.

              +
                +
              • authorized
              • Authorization successful +
              • cancelled
              • Authorization cancelled by user +
              • error
              • Authorization error occurred +
              + + + +

              SupportedMimeTypes

              +

              string

              + +

              MIME types for original source assets converted to PDF. Named export only - not available in constants object.

              +
                +
              • docx
              • "docx"
                +
              • gdoc
              • "gdoc"
                +
              + + + + +

              PdfReturnUrlType

              +

              string

              + +

              Specifies the type of URL returned for PDF rendition export. Named export only - not available in constants object.

              +
                +
              • cdnUrl
              • "cdnUrl"
                +
              • jumpUrl
              • "jumpUrl"
                +
              + + + + +

              FieldType

              +

              string

              + +

              The type of input field supported in Simple Dialog. Dual access: both named export and constants object.

              +
                +
              • text
              • "text"
                +
              + + + +

              PlatformEnvironment

              +

              string

              + +

              Denotes the current environment where the add-on is running. Dual access: both named export and constants object.

              +
                +
              • app
              • "app"
                +
              • web
              • "web"
                +
              + + + +

              DeviceClass

              +

              string

              + +

              Denotes the device class/form factor where the add-on is running. Dual access: both named export and constants object.

              +
                +
              • mobile
              • "mobile"
                +
              • tablet
              • "tablet"
                +
              • desktop
              • "desktop"
                +
              + + + +

              PlatformType

              +

              string

              + +

              Denotes the specific platform/operating system where the add-on is running. Dual access: both named export and constants object.

              +
                +
              • iOS
              • "ios"
                +
              • iPadOS
              • "ipad"
                +
              • chromeOS
              • "chromeOS"
                +
              • android
              • "android"
                +
              • chromeBrowser
              • "chromeBrowser"
                +
              • firefoxBrowser
              • "firefoxBrowser"
                +
              • edgeBrowser
              • "edgeBrowser"
                +
              • samsungBrowser
              • "samsumgBrowser"
                (Note: Contains typo in SDK) +
              • safariBrowser
              • "safariBrowser"
                +
              • unknown
              • "unknown"
                +
              + + From 7aa72999a7a4299a4de76f355ab8cb4995c2e28c Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Fri, 19 Sep 2025 03:16:25 -0400 Subject: [PATCH 02/42] Lint fixes --- .../guides/learn/how_to/selection_events.md | 1668 +++++++++++++++++ 1 file changed, 1668 insertions(+) create mode 100644 src/pages/guides/learn/how_to/selection_events.md diff --git a/src/pages/guides/learn/how_to/selection_events.md b/src/pages/guides/learn/how_to/selection_events.md new file mode 100644 index 000000000..8d711b6e4 --- /dev/null +++ b/src/pages/guides/learn/how_to/selection_events.md @@ -0,0 +1,1668 @@ +--- +keywords: + - Adobe Express + - Express Add-on SDK + - Document API + - Selection + - selectionChange + - Events + - Node selection + - UI integration + - Document sandbox + - Event handlers + - Selection filtering + - Locked nodes + - Properties panel + - Real-time updates +title: Selection Events and Methods +description: Complete guide to working with selections in Adobe Express documents - from basic operations to advanced UI integration patterns. +contributors: + - https://github.com/hollyschinsky +faq: + questions: + - question: "How do I get the current selection?" + answer: "Use `editor.context.selection` to get an array of currently selected editable nodes, or `editor.context.hasSelection` to check if anything is selected." + + - question: "How do I listen for selection changes?" + answer: "Use `editor.context.on('selectionChange', callback)` to register a handler. Always store the returned ID for cleanup." + + - question: "How do I programmatically select elements?" + answer: "Set `editor.context.selection = node` for single elements or `editor.context.selection = [node1, node2]` for multiple elements." + + - question: "What's the difference between selection and selectionIncludingNonEditable?" + answer: "`selection` only includes editable nodes, while `selectionIncludingNonEditable` includes locked/non-editable nodes that users can see but not modify." + + - question: "Can I modify the document in a selection change callback?" + answer: "Never modify the document in selection change handlers - this can crash the application. Only update UI, analyze data, or communicate with your panel." + + - question: "How do I clear the selection?" + answer: "Set `editor.context.selection = []` or `editor.context.selection = undefined` to clear all selections." + + - question: "What selection rules should I know?" + answer: "Only nodes within the current artboard can be selected, you cannot select both parent and child nodes simultaneously, and locked nodes are automatically filtered from the main selection." + + - question: "How do I clean up selection event handlers?" + answer: "Always call `editor.context.off('selectionChange', handlerId)` using the ID returned from `on()` to prevent memory leaks." + + - question: "How do I communicate selection changes to my UI?" + answer: "Use the runtime API to send selection data from the document sandbox to your UI panel, enabling real-time interface updates." + + - question: "What are common selection-based actions?" + answer: "Typical actions include updating properties panels, enabling/disabling tools, applying formatting to selected text, grouping elements, and showing context-appropriate options." +--- + +# Selection Events and Methods + +Learn how to work with user selections, handle selection changes, and respond to user interactions in Adobe Express documents using the Document API. + + + +Document API Context Required + +Selection methods and events are part of the Document API and require the document sandbox environment. These examples should be used in your `code.js` file, not in the main iframe panel. + +Make sure your manifest includes `"documentSandbox": "code.js"` in the entry points. + +For more details on the Context class, see the [Context API reference](../../../references/document-sandbox/document-apis/classes/Context.md). + +## Getting Started with Selections + +Selections in Adobe Express represent the elements (nodes) that users have currently selected in their document. The selection system provides access to what's selected, the ability to change selections programmatically, and events to respond to selection changes. + +### Check Current Selection + + + +#### JavaScript + +```js +// code.js +import { editor } from "express-document-sdk"; + +// Check if anything is selected +if (editor.context.hasSelection) { + const selection = editor.context.selection; + console.log(`Selected ${selection.length} item(s)`); + + // Process each selected node + selection.forEach((node, index) => { + console.log(`Node ${index + 1}: ${node.type}`); + }); +} else { + console.log("Nothing is selected"); +} +``` + +#### TypeScript + +```ts +// code.js +import { editor, Node } from "express-document-sdk"; + +// Check if anything is selected +if (editor.context.hasSelection) { + const selection: readonly Node[] = editor.context.selection; + console.log(`Selected ${selection.length} item(s)`); + + // Process each selected node + selection.forEach((node: Node, index: number) => { + console.log(`Node ${index + 1}: ${node.type}`); + }); +} else { + console.log("Nothing is selected"); +} +``` + +## Understanding Selections + +In Adobe Express, the selection system provides: + +- **Current selection access** - Get what's currently selected +- **Selection modification** - Programmatically change selections +- **Selection events** - React to selection changes +- **Selection filtering** - Handle locked/non-editable content + +### Selection Rules + +Adobe Express enforces these constraints: + +1. **Artboard constraint** - Only nodes within the current artboard can be selected +2. **Hierarchy filtering** - Cannot select both parent and child nodes simultaneously +3. **Locked node filtering** - Locked nodes are excluded from the main selection +4. **Editable-only** - Main selection only includes editable nodes + +## Basic Selection Operations + +Core operations for working with selections. + +### Getting the Current Selection + + + +#### JavaScript + +```js +// code.js +import { editor } from "express-document-sdk"; + +// Get the current selection +const selection = editor.context.selection; + +console.log("Selected nodes:", selection.length); + +// Process each selected node +selection.forEach((node, index) => { + console.log(`Node ${index + 1}: ${node.type}`); + + // Common node properties you can access + console.log(" Position:", node.translation); + console.log(" Size:", { width: node.width, height: node.height }); +}); +``` + +#### TypeScript + +```ts +// code.js +import { editor, Node } from "express-document-sdk"; + +// Get the current selection +const selection: readonly Node[] = editor.context.selection; + +console.log("Selected nodes:", selection.length); + +// Process each selected node +selection.forEach((node: Node, index: number) => { + console.log(`Node ${index + 1}: ${node.type}`); + + // Common node properties you can access + console.log(" Position:", node.translation); + console.log(" Size:", { width: node.width, height: node.height }); +}); +``` + +### Programmatic Selection + + + +#### JavaScript + +```js +// code.js +import { editor } from "express-document-sdk"; + +// Create and select a single element +const rectangle = editor.createRectangle(); +rectangle.width = 100; +rectangle.height = 100; +rectangle.translation = { x: 50, y: 50 }; + +// Add to document +editor.context.insertionParent.children.append(rectangle); + +// Select the rectangle (single element) +editor.context.selection = rectangle; +// OR using array syntax: editor.context.selection = [rectangle]; + +console.log("Rectangle is now selected"); +``` + +#### TypeScript + +```ts +// code.js +import { editor, RectangleNode, ContainerNode } from "express-document-sdk"; + +// Create a simple rectangle to demonstrate selection +const rectangle: RectangleNode = editor.createRectangle(); +rectangle.width = 100; +rectangle.height = 100; +rectangle.translation = { x: 50, y: 50 }; + +// Add to document +const insertionParent: ContainerNode = editor.context.insertionParent; +insertionParent.children.append(rectangle); + +// Select the rectangle (single element) +editor.context.selection = rectangle; +// OR using array syntax: editor.context.selection = [rectangle]; + +console.log("Rectangle is now selected"); +``` + +### Multiple Selection + + + +#### JavaScript + +```js +// code.js +import { editor } from "express-document-sdk"; + +// Create multiple elements +const rectangle = editor.createRectangle(); +rectangle.width = 80; +rectangle.height = 80; +rectangle.translation = { x: 50, y: 50 }; + +const ellipse = editor.createEllipse(); +ellipse.rx = 40; +ellipse.ry = 40; +ellipse.translation = { x: 200, y: 50 }; + +// Add both to document +const parent = editor.context.insertionParent; +parent.children.append(rectangle, ellipse); + +// Select both elements at once +editor.context.selection = [rectangle, ellipse]; + +console.log("Multiple elements selected:", editor.context.selection.length); +``` + +#### TypeScript + +```ts +// code.js +import { editor, RectangleNode, EllipseNode, ContainerNode } from "express-document-sdk"; + +// Create multiple simple elements +const rectangle: RectangleNode = editor.createRectangle(); +rectangle.width = 80; +rectangle.height = 80; +rectangle.translation = { x: 50, y: 50 }; + +const ellipse: EllipseNode = editor.createEllipse(); +ellipse.rx = 40; +ellipse.ry = 40; +ellipse.translation = { x: 200, y: 50 }; + +// Add both to document +const parent: ContainerNode = editor.context.insertionParent; +parent.children.append(rectangle, ellipse); + +// Select both elements at once +editor.context.selection = [rectangle, ellipse]; + +console.log("Multiple elements selected:", editor.context.selection.length); +``` + +### Clearing the Selection + + + +#### JavaScript + +```js +// code.js +import { editor } from "express-document-sdk"; + +// Clear the selection - both ways work +editor.context.selection = []; +// OR: editor.context.selection = undefined; + +console.log("Selection cleared"); +console.log("Has selection:", editor.context.hasSelection); // false +``` + +#### TypeScript + +```ts +// code.js +import { editor } from "express-document-sdk"; + +// Clear the selection - both ways work +editor.context.selection = []; +// OR: editor.context.selection = undefined; + +console.log("Selection cleared"); +console.log("Has selection:", editor.context.hasSelection); // false +``` + +## Selection Events + +Respond to selection changes to create dynamic UIs that update based on what's selected. + +### Basic Selection Change Handler + + + +#### JavaScript + +```js +// code.js +import { editor } from "express-document-sdk"; + +// Listen for selection changes +const handlerId = editor.context.on("selectionChange", () => { + const selection = editor.context.selection; + + console.log("Selection changed!"); + console.log("New selection count:", selection.length); + + if (selection.length === 0) { + console.log("Nothing selected"); + } else if (selection.length === 1) { + console.log("One item selected:", selection[0].type); + } else { + console.log("Multiple items selected"); + } +}); + +// Store handlerId if you need to unregister later +console.log("Selection handler registered:", handlerId); +``` + +#### TypeScript + +```ts +// code.js +import { editor, Node } from "express-document-sdk"; + +// Listen for selection changes +const handlerId: string = editor.context.on("selectionChange", () => { + const selection: readonly Node[] = editor.context.selection; + + console.log("Selection changed!"); + console.log("New selection count:", selection.length); + + if (selection.length === 0) { + console.log("Nothing selected"); + } else if (selection.length === 1) { + console.log("One item selected:", selection[0].type); + } else { + console.log("Multiple items selected"); + } +}); + +// Store handlerId if you need to unregister later +console.log("Selection handler registered:", handlerId); +``` + +### Properties Panel Example + +Dynamic properties panel based on selection: + + + +#### JavaScript + +```js +// code.js +import { editor } from "express-document-sdk"; + +function updatePropertiesPanel() { + const selection = editor.context.selection; + + if (selection.length === 0) { + console.log("Properties Panel: Show 'Nothing Selected' state"); + return; + } + + if (selection.length === 1) { + const node = selection[0]; + console.log("Properties Panel: Show properties for", node.type); + + // Show different properties based on node type + if (node.type === "Text") { + console.log(" - Show font controls"); + console.log(" - Show text color picker"); + } else if (node.type === "Rectangle" || node.type === "Ellipse") { + console.log(" - Show fill color picker"); + console.log(" - Show stroke controls"); + } + + // Common properties for all nodes + console.log(" - Show position controls"); + console.log(" - Show size controls"); + + } else { + console.log("Properties Panel: Show multi-selection options"); + console.log(` - ${selection.length} items selected`); + console.log(" - Show alignment tools"); + console.log(" - Show group option"); + } +} + +// Register the handler +editor.context.on("selectionChange", updatePropertiesPanel); + +// Call once on startup to initialize +updatePropertiesPanel(); +``` + +#### TypeScript + +```ts +// code.js +import { editor, Node, TextNode } from "express-document-sdk"; + +function updatePropertiesPanel(): void { + const selection: readonly Node[] = editor.context.selection; + + if (selection.length === 0) { + console.log("Properties Panel: Show 'Nothing Selected' state"); + return; + } + + if (selection.length === 1) { + const node: Node = selection[0]; + console.log("Properties Panel: Show properties for", node.type); + + // Show different properties based on node type + if (node.type === "Text") { + console.log(" - Show font controls"); + console.log(" - Show text color picker"); + } else if (node.type === "Rectangle" || node.type === "Ellipse") { + console.log(" - Show fill color picker"); + console.log(" - Show stroke controls"); + } + + // Common properties for all nodes + console.log(" - Show position controls"); + console.log(" - Show size controls"); + + } else { + console.log("Properties Panel: Show multi-selection options"); + console.log(` - ${selection.length} items selected`); + console.log(" - Show alignment tools"); + console.log(" - Show group option"); + } +} + +// Register the handler +editor.context.on("selectionChange", updatePropertiesPanel); + +// Call once on startup to initialize +updatePropertiesPanel(); +``` + +### Event Handler Cleanup + +⚠️ **Important**: Always clean up event handlers to prevent memory leaks. + + + +#### JavaScript + +```js +// code.js +import { editor } from "express-document-sdk"; + +// Store handler IDs so you can unregister them later +let selectionHandlerId = null; + +function startListening() { + // Register handler and store the ID + selectionHandlerId = editor.context.on("selectionChange", () => { + console.log("Selection changed!"); + // Handle selection change + }); + + console.log("✅ Selection handler registered"); +} + +function stopListening() { + // Clean up the handler + if (selectionHandlerId) { + editor.context.off("selectionChange", selectionHandlerId); + selectionHandlerId = null; + console.log("✅ Selection handler cleaned up"); + } +} + +// Start listening +startListening(); + +// Clean up when your add-on is being destroyed or reset +// stopListening(); +``` + +#### TypeScript + +```ts +// code.js +import { editor } from "express-document-sdk"; + +// Store handler IDs so you can unregister them later +let selectionHandlerId: string | null = null; + +function startListening(): void { + // Register handler and store the ID + selectionHandlerId = editor.context.on("selectionChange", () => { + console.log("Selection changed!"); + // Handle selection change + }); + + console.log("✅ Selection handler registered"); +} + +function stopListening(): void { + // Clean up the handler + if (selectionHandlerId) { + editor.context.off("selectionChange", selectionHandlerId); + selectionHandlerId = null; + console.log("✅ Selection handler cleaned up"); + } +} + +// Start listening +startListening(); + +// Clean up when your add-on is being destroyed or reset +// stopListening(); +## Advanced Selection Techniques + +Advanced patterns for complex add-ons. + +### Working with Locked/Non-Editable Elements + +Handle selections that include locked or non-editable content: + + + +#### JavaScript + +```js +// code.js +import { editor } from "express-document-sdk"; + +function analyzeCompleteSelection() { + const editableSelection = editor.context.selection; + const fullSelection = editor.context.selectionIncludingNonEditable; + + return { + editableCount: selection.length, + totalCount: fullSelection.length, + lockedCount: fullSelection.length - selection.length, + types: [...new Set(selection.map(node => node.type))], // Unique types + hasText: selection.some(node => node.type === "Text"), + hasShapes: selection.some(node => + node.type === "Rectangle" || node.type === "Ellipse" + ), + isEmpty: !editor.context.hasSelection + }; +} + +// Example: Dynamic UI updates based on detailed analysis +editor.context.on("selectionChange", () => { + const analysis = analyzeSelection(); + + console.log("📊 Detailed Selection Info:"); + console.log(` Editable: ${analysis.editableCount}`); + if (analysis.lockedCount > 0) { + console.log(` Locked: ${analysis.lockedCount}`); + } + console.log(` Types: ${analysis.types.join(", ")}`); + + // Enable specific tools based on content + if (analysis.hasText) { + console.log("🔤 Text formatting tools available"); + } + if (analysis.hasShapes) { + console.log("🔷 Shape styling tools available"); + } + if (analysis.editableCount > 1) { + console.log("📐 Alignment tools available"); + } +}); +``` + +#### TypeScript + +```ts +// code.js +import { editor, Node } from "express-document-sdk"; + +interface DetailedSelectionAnalysis { + editableCount: number; + totalCount: number; + lockedCount: number; + types: string[]; + hasText: boolean; + hasShapes: boolean; + isEmpty: boolean; +} + +function analyzeSelection(): DetailedSelectionAnalysis { + const selection: readonly Node[] = editor.context.selection; + const fullSelection: readonly Node[] = editor.context.selectionIncludingNonEditable; + + return { + editableCount: selection.length, + totalCount: fullSelection.length, + lockedCount: fullSelection.length - selection.length, + types: [...new Set(selection.map((node: Node) => node.type))], // Unique types + hasText: selection.some((node: Node) => node.type === "Text"), + hasShapes: selection.some((node: Node) => + node.type === "Rectangle" || node.type === "Ellipse" + ), + isEmpty: !editor.context.hasSelection + }; +} + +// Example: Dynamic UI updates based on detailed analysis +editor.context.on("selectionChange", () => { + const analysis: DetailedSelectionAnalysis = analyzeSelection(); + + console.log("📊 Detailed Selection Info:"); + console.log(` Editable: ${analysis.editableCount}`); + if (analysis.lockedCount > 0) { + console.log(` Locked: ${analysis.lockedCount}`); + } + console.log(` Types: ${analysis.types.join(", ")}`); + + // Enable specific tools based on content + if (analysis.hasText) { + console.log("🔤 Text formatting tools available"); + } + if (analysis.hasShapes) { + console.log("🔷 Shape styling tools available"); + } + if (analysis.editableCount > 1) { + console.log("📐 Alignment tools available"); + } +}); +``` + +## UI Integration + +Communicate selection changes between the document sandbox and your UI panel to create responsive interfaces. + +### Selection-Based Actions + +Common patterns for performing actions on selected elements: + + + +#### JavaScript + +```js +// code.js +import { editor, colorUtils } from "express-document-sdk"; + +// Function to apply red color to selected text +function applyRedToSelectedText() { + const selection = editor.context.selection; + + // Filter for text nodes only + const textNodes = selection.filter(node => node.type === "Text"); + + if (textNodes.length === 0) { + console.log("No text nodes selected"); + return; + } + + // Apply red color to all selected text + const redColor = colorUtils.fromHex("#FF0000"); + + textNodes.forEach(textNode => { + textNode.fullContent.applyCharacterStyles({ color: redColor }); + }); + + console.log(`Applied red color to ${textNodes.length} text nodes`); +} + +// Function to group selected elements +function groupSelection() { + const selection = editor.context.selection; + + if (selection.length < 2) { + console.log("Need at least 2 elements to create a group"); + return; + } + + // Create a group + const group = editor.createGroup(); + + // Add selected elements to the group + selection.forEach(node => { + // Remove from current parent and add to group + node.removeFromParent(); + group.children.append(node); + }); + + // Add group to the document + editor.context.insertionParent.children.append(group); + + // Select the new group + editor.context.selection = group; + + console.log(`Created group with ${selection.length} elements`); +} + +// Register handlers for different actions +editor.context.on("selectionChange", () => { + const selection = editor.context.selection; + + // Update UI or enable/disable actions based on selection + if (selection.length === 0) { + console.log("No selection - disable all actions"); + } else if (selection.length === 1) { + console.log("Single selection - enable individual actions"); + } else { + console.log("Multiple selection - enable group actions"); + } +}); +``` + +#### TypeScript + +```ts +// code.js +import { editor, colorUtils, Node, TextNode, GroupNode, ContainerNode } from "express-document-sdk"; + +// Function to apply red color to selected text +function applyRedToSelectedText(): void { + const selection: readonly Node[] = editor.context.selection; + + // Filter for text nodes only + const textNodes = selection.filter((node: Node): node is TextNode => + node.type === "Text" + ); + + if (textNodes.length === 0) { + console.log("No text nodes selected"); + return; + } + + // Apply red color to all selected text + const redColor = colorUtils.fromHex("#FF0000"); + + textNodes.forEach((textNode: TextNode) => { + textNode.fullContent.applyCharacterStyles({ color: redColor }); + }); + + console.log(`Applied red color to ${textNodes.length} text nodes`); +} + +// Function to group selected elements +function groupSelection(): void { + const selection: readonly Node[] = editor.context.selection; + + if (selection.length < 2) { + console.log("Need at least 2 elements to create a group"); + return; + } + + // Create a group + const group: GroupNode = editor.createGroup(); + + // Add selected elements to the group + selection.forEach((node: Node) => { + // Remove from current parent and add to group + node.removeFromParent(); + group.children.append(node); + }); + + // Add group to the document + const insertionParent: ContainerNode = editor.context.insertionParent; + insertionParent.children.append(group); + + // Select the new group + editor.context.selection = group; + + console.log(`Created group with ${selection.length} elements`); +} + +// Register handlers for different actions +editor.context.on("selectionChange", () => { + const selection: readonly Node[] = editor.context.selection; + + // Update UI or enable/disable actions based on selection + if (selection.length === 0) { + console.log("No selection - disable all actions"); + } else if (selection.length === 1) { + console.log("Single selection - enable individual actions"); + } else { + console.log("Multiple selection - enable group actions"); + } +}); +``` + +### Selection State Management + + + +#### JavaScript + +```js +// code.js +import { editor } from "express-document-sdk"; + +class SelectionManager { + constructor() { + this.selectionHistory = []; + this.handlerId = null; + this.startListening(); + } + + startListening() { + this.handlerId = editor.context.on("selectionChange", () => { + const selection = editor.context.selection; + + // Store selection in history (limit to last 10) + this.selectionHistory.push([...selection]); + if (this.selectionHistory.length > 10) { + this.selectionHistory.shift(); + } + + console.log("Selection history length:", this.selectionHistory.length); + this.notifySelectionChange(selection); + }); + } + + notifySelectionChange(selection) { + // Custom logic based on selection + if (selection.length === 0) { + this.onNoSelection(); + } else if (selection.length === 1) { + this.onSingleSelection(selection[0]); + } else { + this.onMultipleSelection(selection); + } + } + + onNoSelection() { + console.log("No elements selected"); + // Disable context-sensitive UI + } + + onSingleSelection(node) { + console.log("Single element selected:", node.type); + // Enable single-element actions + } + + onMultipleSelection(selection) { + console.log("Multiple elements selected:", selection.length); + // Enable multi-element actions + } + + restorePreviousSelection() { + if (this.selectionHistory.length >= 2) { + const previousSelection = this.selectionHistory[this.selectionHistory.length - 2]; + editor.context.selection = previousSelection; + } + } + + stopListening() { + if (this.handlerId) { + editor.context.off("selectionChange", this.handlerId); + this.handlerId = null; + } + } +} + +// Usage +const selectionManager = new SelectionManager(); +``` + +#### TypeScript + +```ts +// code.js +import { editor, Node } from "express-document-sdk"; + +class SelectionManager { + private selectionHistory: Node[][] = []; + private handlerId: string | null = null; + + constructor() { + this.startListening(); + } + + startListening(): void { + this.handlerId = editor.context.on("selectionChange", () => { + const selection: readonly Node[] = editor.context.selection; + + // Store selection in history (limit to last 10) + this.selectionHistory.push([...selection]); + if (this.selectionHistory.length > 10) { + this.selectionHistory.shift(); + } + + console.log("Selection history length:", this.selectionHistory.length); + this.notifySelectionChange(selection); + }); + } + + private notifySelectionChange(selection: readonly Node[]): void { + // Custom logic based on selection + if (selection.length === 0) { + this.onNoSelection(); + } else if (selection.length === 1) { + this.onSingleSelection(selection[0]); + } else { + this.onMultipleSelection(selection); + } + } + + private onNoSelection(): void { + console.log("No elements selected"); + // Disable context-sensitive UI + } + + private onSingleSelection(node: Node): void { + console.log("Single element selected:", node.type); + // Enable single-element actions + } + + private onMultipleSelection(selection: readonly Node[]): void { + console.log("Multiple elements selected:", selection.length); + // Enable multi-element actions + } + + restorePreviousSelection(): void { + if (this.selectionHistory.length >= 2) { + const previousSelection = this.selectionHistory[this.selectionHistory.length - 2]; + editor.context.selection = previousSelection; + } + } + + stopListening(): void { + if (this.handlerId) { + editor.context.off("selectionChange", this.handlerId); + this.handlerId = null; + } + } +} + +// Usage +const selectionManager = new SelectionManager(); +``` + +## Cleanup and Best Practices + +### Unregistering Event Handlers + + + +#### JavaScript + +```js +// code.js +import { editor } from "express-document-sdk"; + +// Store handler IDs for cleanup +let selectionHandlerId = null; + +function setupSelectionHandling() { + // Register handler and store ID + selectionHandlerId = editor.context.on("selectionChange", () => { + console.log("Selection changed"); + // Handle selection change + }); + + console.log("Selection handler registered"); +} + +function cleanupSelectionHandling() { + // Unregister the handler + if (selectionHandlerId) { + editor.context.off("selectionChange", selectionHandlerId); + selectionHandlerId = null; + console.log("Selection handler unregistered"); + } +} + +// Setup +setupSelectionHandling(); + +// Cleanup when add-on is being destroyed or reset +// cleanupSelectionHandling(); +``` + +#### TypeScript + +```ts +// code.js +import { editor } from "express-document-sdk"; + +// Store handler IDs for cleanup +let selectionHandlerId: string | null = null; + +function setupSelectionHandling(): void { + // Register handler and store ID + selectionHandlerId = editor.context.on("selectionChange", () => { + console.log("Selection changed"); + // Handle selection change + }); + + console.log("Selection handler registered"); +} + +function cleanupSelectionHandling(): void { + // Unregister the handler + if (selectionHandlerId) { + editor.context.off("selectionChange", selectionHandlerId); + selectionHandlerId = null; + console.log("Selection handler unregistered"); + } +} + +// Setup +setupSelectionHandling(); + +// Cleanup when add-on is being destroyed or reset +// cleanupSelectionHandling(); +``` + +## Best Practices & Guidelines + +### Selection System Rules + +1. **Artboard constraint**: Only nodes within the current artboard can be selected +2. **Hierarchy filtering**: Cannot select both parent and child nodes simultaneously +3. **Locked node handling**: Locked nodes are excluded from main selection but available in `selectionIncludingNonEditable` +4. **Automatic filtering**: System automatically filters out invalid selections + +### Critical: Selection Handler Restrictions + + + +⚠️ Document Modification Restrictions + +**Never modify the document inside selection change handlers!** This can crash the application. + +✅ **Safe in selection handlers:** + +- Update UI panels +- Log information +- Analyze selection +- Enable/disable buttons +- Send data to UI panel + +❌ **Never do in selection handlers:** + +- Create, delete, or modify nodes +- Change document structure +- Set properties on selected elements + +### Performance Guidelines + +1. **Keep handlers fast**: Minimize processing time +2. **Essential work only**: Avoid heavy computations +3. **Clean Up**: Always unregister handlers when done (`editor.context.off()`) +4. **Avoid Heavy Work**: Don't do complex calculations in selection callbacks + +### Selection System Rules (Advanced) + +Understanding these rules helps you work with selections more effectively: + +1. **Artboard Limitation**: Only nodes within the current artboard can be selected +2. **Hierarchy Rules**: Cannot select both a parent node and its children simultaneously + +## Communication Between UI and Document Sandbox + +One of the most important real-world patterns is communicating selection changes from the document sandbox to your UI panel, allowing you to update the interface based on what the user has selected. + +For detailed information on the communication APIs, see the [Communication API reference](../../../references/document-sandbox/communication/). + +### Complete Communication Example + +This example shows how to set up bidirectional communication between your UI panel and document sandbox for selection-based interactions. + + + +#### JavaScript + +**UI Panel (index.js):** + +```js +// ui/index.js +import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +let documentSandbox; + +addOnUISdk.ready.then(async () => { + // Get access to the document sandbox APIs + documentSandbox = await addOnUISdk.instance.runtime.apiProxy("documentSandbox"); + + // Set up UI elements + setupSelectionUI(); + + // Start listening for selection updates from sandbox + documentSandbox.registerSelectionUpdateHandler(handleSelectionUpdate); +}); + +function setupSelectionUI() { + const container = document.getElementById("selection-info"); + + container.innerHTML = ` +
              Nothing selected
              +
              + + + +
              +
              + `; + + // Set up button handlers + document.getElementById("apply-red-btn").addEventListener("click", () => { + documentSandbox.applyRedToSelection(); + }); + + document.getElementById("group-btn").addEventListener("click", () => { + documentSandbox.groupSelection(); + }); + + document.getElementById("clear-selection-btn").addEventListener("click", () => { + documentSandbox.clearSelection(); + }); +} + +function handleSelectionUpdate(selectionInfo) { + console.log("Selection update received:", selectionInfo); + + // Update status + const statusEl = document.getElementById("selection-status"); + if (selectionInfo.count === 0) { + statusEl.textContent = "Nothing selected"; + } else if (selectionInfo.count === 1) { + statusEl.textContent = `1 ${selectionInfo.types[0]} selected`; + } else { + statusEl.textContent = `${selectionInfo.count} elements selected`; + } + + // Update action buttons + document.getElementById("apply-red-btn").disabled = !selectionInfo.hasText; + document.getElementById("group-btn").disabled = selectionInfo.count < 2; + document.getElementById("clear-selection-btn").disabled = selectionInfo.count === 0; + + // Update details + const detailsEl = document.getElementById("selection-details"); + if (selectionInfo.count > 0) { + detailsEl.innerHTML = ` +

              Selection Details:

              +

              Types: ${selectionInfo.types.join(", ")}

              +

              Has Text: ${selectionInfo.hasText ? "Yes" : "No"}

              +

              Has Shapes: ${selectionInfo.hasShapes ? "Yes" : "No"}

              +

              Locked Elements: ${selectionInfo.lockedCount}

              + `; + } else { + detailsEl.innerHTML = ""; + } +} +``` + +**Document Sandbox (code.js):** + +```js +// code.js +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; +import { editor, colorUtils } from "express-document-sdk"; + +const { runtime } = addOnSandboxSdk.instance; +let uiPanel; + +// Wait for UI panel to be ready +runtime.ready.then(async () => { + // Get access to the UI panel APIs + uiPanel = await runtime.apiProxy("panel"); + + // Set up selection change handler + setupSelectionHandling(); +}); + +function setupSelectionHandling() { + editor.context.on("selectionChange", () => { + const selectionInfo = analyzeCurrentSelection(); + + // Send selection info to UI panel + uiPanel.handleSelectionUpdate(selectionInfo); + }); + + // Send initial selection state + const initialSelection = analyzeCurrentSelection(); + uiPanel.handleSelectionUpdate(initialSelection); +} + +function analyzeCurrentSelection() { + const selection = editor.context.selection; + const fullSelection = editor.context.selectionIncludingNonEditable; + + return { + count: selection.length, + totalCount: fullSelection.length, + lockedCount: fullSelection.length - selection.length, + types: [...new Set(selection.map(node => node.type))], + hasText: selection.some(node => node.type === "Text"), + hasShapes: selection.some(node => + ["Rectangle", "Ellipse"].includes(node.type) + ), + isEmpty: selection.length === 0 + }; +} + +// Export functions for UI to call +function registerSelectionUpdateHandler(handler) { + // Store the handler function from UI + runtime.exposeApi({ + applyRedToSelection() { + const selection = editor.context.selection; + const textNodes = selection.filter(node => node.type === "Text"); + + if (textNodes.length > 0) { + const redColor = colorUtils.fromHex("#FF0000"); + textNodes.forEach(textNode => { + textNode.fullContent.applyCharacterStyles({ color: redColor }); + }); + + console.log(`Applied red to ${textNodes.length} text nodes`); + } + }, + + groupSelection() { + const selection = editor.context.selection; + + if (selection.length >= 2) { + const group = editor.createGroup(); + + // Move selected elements to group + selection.forEach(node => { + node.removeFromParent(); + group.children.append(node); + }); + + // Add group to document + editor.context.insertionParent.children.append(group); + + // Select the new group + editor.context.selection = group; + + console.log(`Created group with ${selection.length} elements`); + } + }, + + clearSelection() { + editor.context.selection = []; + console.log("Selection cleared"); + }, + + registerSelectionUpdateHandler: handler + }); +} + +// Expose the registration function immediately +runtime.exposeApi({ registerSelectionUpdateHandler }); +``` + +#### TypeScript + +**UI Panel (index.ts):** + +```ts +// ui/index.ts +import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +interface SelectionInfo { + count: number; + totalCount: number; + lockedCount: number; + types: string[]; + hasText: boolean; + hasShapes: boolean; + isEmpty: boolean; +} + +interface DocumentSandboxAPI { + registerSelectionUpdateHandler: (handler: (info: SelectionInfo) => void) => void; + applyRedToSelection: () => void; + groupSelection: () => void; + clearSelection: () => void; +} + +let documentSandbox: DocumentSandboxAPI; + +addOnUISdk.ready.then(async () => { + // Get access to the document sandbox APIs + documentSandbox = await addOnUISdk.instance.runtime.apiProxy("documentSandbox"); + + // Set up UI elements + setupSelectionUI(); + + // Start listening for selection updates from sandbox + documentSandbox.registerSelectionUpdateHandler(handleSelectionUpdate); +}); + +function setupSelectionUI(): void { + const container = document.getElementById("selection-info"); + + if (container) { + container.innerHTML = ` +
              Nothing selected
              +
              + + + +
              +
              + `; + + // Set up button handlers + const applyRedBtn = document.getElementById("apply-red-btn"); + const groupBtn = document.getElementById("group-btn"); + const clearBtn = document.getElementById("clear-selection-btn"); + + applyRedBtn?.addEventListener("click", () => { + documentSandbox.applyRedToSelection(); + }); + + groupBtn?.addEventListener("click", () => { + documentSandbox.groupSelection(); + }); + + clearBtn?.addEventListener("click", () => { + documentSandbox.clearSelection(); + }); + } +} + +function handleSelectionUpdate(selectionInfo: SelectionInfo): void { + console.log("Selection update received:", selectionInfo); + + // Update status + const statusEl = document.getElementById("selection-status"); + if (statusEl) { + if (selectionInfo.count === 0) { + statusEl.textContent = "Nothing selected"; + } else if (selectionInfo.count === 1) { + statusEl.textContent = `1 ${selectionInfo.types[0]} selected`; + } else { + statusEl.textContent = `${selectionInfo.count} elements selected`; + } + } + + // Update action buttons + const applyRedBtn = document.getElementById("apply-red-btn") as HTMLButtonElement; + const groupBtn = document.getElementById("group-btn") as HTMLButtonElement; + const clearBtn = document.getElementById("clear-selection-btn") as HTMLButtonElement; + + if (applyRedBtn) applyRedBtn.disabled = !selectionInfo.hasText; + if (groupBtn) groupBtn.disabled = selectionInfo.count < 2; + if (clearBtn) clearBtn.disabled = selectionInfo.count === 0; + + // Update details + const detailsEl = document.getElementById("selection-details"); + if (detailsEl) { + if (selectionInfo.count > 0) { + detailsEl.innerHTML = ` +

              Selection Details:

              +

              Types: ${selectionInfo.types.join(", ")}

              +

              Has Text: ${selectionInfo.hasText ? "Yes" : "No"}

              +

              Has Shapes: ${selectionInfo.hasShapes ? "Yes" : "No"}

              +

              Locked Elements: ${selectionInfo.lockedCount}

              + `; + } else { + detailsEl.innerHTML = ""; + } + } +} +``` + +**Document Sandbox (code.ts):** + +```ts +// code.ts +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; +import { editor, colorUtils, Node, TextNode, GroupNode, ContainerNode } from "express-document-sdk"; + +interface SelectionInfo { + count: number; + totalCount: number; + lockedCount: number; + types: string[]; + hasText: boolean; + hasShapes: boolean; + isEmpty: boolean; +} + +interface UIPanelAPI { + handleSelectionUpdate: (info: SelectionInfo) => void; +} + +const { runtime } = addOnSandboxSdk.instance; +let uiPanel: UIPanelAPI; + +// Wait for UI panel to be ready +runtime.ready.then(async () => { + // Get access to the UI panel APIs + uiPanel = await runtime.apiProxy("panel"); + + // Set up selection change handler + setupSelectionHandling(); +}); + +function setupSelectionHandling(): void { + editor.context.on("selectionChange", () => { + const selectionInfo: SelectionInfo = analyzeCurrentSelection(); + + // Send selection info to UI panel + uiPanel.handleSelectionUpdate(selectionInfo); + }); + + // Send initial selection state + const initialSelection: SelectionInfo = analyzeCurrentSelection(); + uiPanel.handleSelectionUpdate(initialSelection); +} + +function analyzeCurrentSelection(): SelectionInfo { + const selection: readonly Node[] = editor.context.selection; + const fullSelection: readonly Node[] = editor.context.selectionIncludingNonEditable; + + return { + count: selection.length, + totalCount: fullSelection.length, + lockedCount: fullSelection.length - selection.length, + types: [...new Set(selection.map((node: Node) => node.type))], + hasText: selection.some((node: Node) => node.type === "Text"), + hasShapes: selection.some((node: Node) => + ["Rectangle", "Ellipse"].includes(node.type) + ), + isEmpty: selection.length === 0 + }; +} + +// Export functions for UI to call +function registerSelectionUpdateHandler(handler: (info: SelectionInfo) => void): void { + // Store the handler function from UI + runtime.exposeApi({ + applyRedToSelection(): void { + const selection: readonly Node[] = editor.context.selection; + const textNodes = selection.filter((node: Node): node is TextNode => + node.type === "Text" + ); + + if (textNodes.length > 0) { + const redColor = colorUtils.fromHex("#FF0000"); + textNodes.forEach((textNode: TextNode) => { + textNode.fullContent.applyCharacterStyles({ color: redColor }); + }); + + console.log(`Applied red to ${textNodes.length} text nodes`); + } + }, + + groupSelection(): void { + const selection: readonly Node[] = editor.context.selection; + + if (selection.length >= 2) { + const group: GroupNode = editor.createGroup(); + + // Move selected elements to group + selection.forEach((node: Node) => { + node.removeFromParent(); + group.children.append(node); + }); + + // Add group to document + const insertionParent: ContainerNode = editor.context.insertionParent; + insertionParent.children.append(group); + + // Select the new group + editor.context.selection = group; + + console.log(`Created group with ${selection.length} elements`); + } + }, + + clearSelection(): void { + editor.context.selection = []; + console.log("Selection cleared"); + }, + + registerSelectionUpdateHandler: handler + }); +} + +// Expose the registration function immediately +runtime.exposeApi({ registerSelectionUpdateHandler }); +``` + +### HTML Structure + +Your `index.html` should include the selection UI container: + +```html + + + + Selection Demo + + + +
              + +
              + + + + +``` + +### Key Communication Patterns + +1. **Initialization**: UI panel registers a callback with the document sandbox +2. **Event Flow**: Document sandbox listens for selection changes and sends updates to UI +3. **Action Triggers**: UI sends action requests back to document sandbox +4. **Bidirectional**: Both sides can call methods on the other + +This pattern enables rich, responsive UIs that react to document changes in real-time. + +## Quick Reference & Common Patterns + +Here are some frequently used patterns you can copy and adapt: + +### Conditional Actions Based on Selection + +```js +// Enable/disable actions based on selection type +editor.context.on("selectionChange", () => { + const selection = editor.context.selection; + + // Communicate with your UI panel + const actions = { + canGroup: selection.length >= 2, + canApplyTextStyle: selection.some(node => node.type === "Text"), + canApplyFill: selection.some(node => + ["Rectangle", "Ellipse"].includes(node.type) + ), + isEmpty: selection.length === 0 + }; + + // Send to UI panel for enabling/disabling buttons + // (Use the communication API to send this data) +}); +``` + +### Selection-Based Properties Panel + +```js +// Update properties panel based on selection +editor.context.on("selectionChange", () => { + const selection = editor.context.selection; + + if (selection.length === 1) { + const node = selection[0]; // Common pattern: access first selected element + + // Send node properties to UI for editing + const properties = { + type: node.type, + width: node.width || null, + height: node.height || null, + x: node.translation?.x || null, + y: node.translation?.y || null, + locked: node.locked || false + }; + + // Update UI panel with these properties + console.log("Node properties:", properties); + } +}); +``` + +### Working with Single Selection + +Many add-ons focus on single-element operations. Here's a common pattern used throughout the documentation: + +```js +// Safe access to first selected element (used in use_text.md and other guides) +if (editor.context.hasSelection) { + const selectedNode = editor.context.selection[0]; + + // Perform operations on the selected node + if (selectedNode.type === "Text") { + // Handle text-specific operations + } +} +``` + +## FAQs + +#### Q: How do I get the current selection? + +**A:** Use `editor.context.selection` to get an array of currently selected nodes. + +#### Q: How do I listen for selection changes? + +**A:** Use `editor.context.on('selectionChange', callback)` to register a selection change handler. + +#### Q: How do I programmatically select elements? + +**A:** Set `editor.context.selection = [node]` or `editor.context.selection = [node1, node2]` for multiple elements. + +#### Q: What's the difference between selection and selectionIncludingNonEditable? + +**A:** `selection` only includes editable nodes, while `selectionIncludingNonEditable` also includes locked/non-editable nodes. + +#### Q: Can I modify the document in a selection change callback? + +**A:** No, avoid making document changes in selection change callbacks as it may destabilize the application. + +#### Q: How do I clear the selection? + +**A:** Set `editor.context.selection = []` or `editor.context.selection = undefined`. + +#### Q: What are the selection rules? + +**A:** Nodes must be within the current artboard, ancestors cannot be selected with descendants, and locked nodes are filtered out. + +#### Q: How do I unregister selection event handlers? + +**A:** Use `editor.context.off('selectionChange', handlerId)` with the ID returned from the `on()` method. + +## Related Topics + +- **[Context API Reference](../../../references/document-sandbox/document-apis/classes/Context.md)** - Complete API documentation for the Context class +- **[Communication APIs](../../../references/document-sandbox/communication/)** - Learn how to communicate between document sandbox and UI panel +- **[Group Elements](./group_elements.md)** - Working with selections to create and manage groups +- **[Position Elements](./position_elements.md)** - Positioning and transforming selected elements +- **[Use Text](./use_text.md)** - Examples of working with text selections using `editor.context.selection[0]` +- **[EditorEvent Enumeration](../../../references/document-sandbox/document-apis/enumerations/EditorEvent.md)** - All available editor events +- **[Node API Reference](../../../references/document-sandbox/document-apis/classes/Node.md)** - Understanding the Node class used in selections + +#### Q: How do I unregister selection event handlers? + +**A:** Use `editor.context.off('selectionChange', handlerId)` with the ID returned from the `on()` method. From ba41da47185a37acab8fab19bd40e927a50906c8 Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Fri, 19 Sep 2025 03:31:17 -0400 Subject: [PATCH 03/42] Fix link --- src/pages/references/addonsdk/addonsdk-constants.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/references/addonsdk/addonsdk-constants.md b/src/pages/references/addonsdk/addonsdk-constants.md index 6a37bae50..938064b58 100644 --- a/src/pages/references/addonsdk/addonsdk-constants.md +++ b/src/pages/references/addonsdk/addonsdk-constants.md @@ -196,7 +196,7 @@ import addOnUISdk, { AuthorizationStatus } from "https://new.express.adobe.com/s ## Constants Reference -This section provides the complete technical specification for all Add-on UI SDK constants, organized by functional category. For practical examples and usage patterns, see the [Using Constants Guide](../../guides/learn/platform_concepts/ui-sdk-constants.md). +This section provides the complete technical specification for all Add-on UI SDK constants, organized by functional category. For practical examples and usage patterns, see the [Using Constants Guide](../../guides/learn/how_to/ui_sdk_constants.md). ## Developer Tips From a07ba9538dc54890ecf04aa02b1e36f468dc3190 Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Fri, 19 Sep 2025 18:56:15 -0400 Subject: [PATCH 04/42] Fix link --- src/pages/references/addonsdk/addonsdk-constants.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/references/addonsdk/addonsdk-constants.md b/src/pages/references/addonsdk/addonsdk-constants.md index 938064b58..a0b9b4b6a 100644 --- a/src/pages/references/addonsdk/addonsdk-constants.md +++ b/src/pages/references/addonsdk/addonsdk-constants.md @@ -5,7 +5,7 @@ This reference provides the complete technical specification for all constants u - Constants available in `addOnUISdk.constants.*` (dual access) - Constants available only as named exports (import required) -For practical examples and use cases, see the [Using Constants Guide](../../guides/learn/platform_concepts/ui-sdk-constants.md). +For practical examples and use cases, see the [Using Constants Guide](../../guides/learn/how_to/ui_sdk_constants.md). From 6fc22667f0e1018dac3763c01d2ddc5218a77872 Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Fri, 3 Oct 2025 05:11:45 -0400 Subject: [PATCH 05/42] Adds new terminology page and new constants pages --- gatsby-config.js | 18 + .../guides/learn/fundamentals/constants.md | 218 ++++ .../document-sandbox-constants.md | 325 ++++++ .../guides/learn/fundamentals/terminology.md | 654 ++++++++++++ .../learn/fundamentals/ui-sdk-constants.md | 253 +++++ .../references/addonsdk/addonsdk-constants.md | 938 +++++++++++------- 6 files changed, 2029 insertions(+), 377 deletions(-) create mode 100644 src/pages/guides/learn/fundamentals/constants.md create mode 100644 src/pages/guides/learn/fundamentals/document-sandbox-constants.md create mode 100644 src/pages/guides/learn/fundamentals/terminology.md create mode 100644 src/pages/guides/learn/fundamentals/ui-sdk-constants.md diff --git a/gatsby-config.js b/gatsby-config.js index 6ac34db67..244f19145 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -776,6 +776,24 @@ module.exports = { }, ], }, + { + title: "SDK Fundamentals", + path: "guides/learn/fundamentals/ui-sdk-constants.md", + pages: [ + { + title: "Add-on UI SDK Constants", + path: "guides/learn/fundamentals/ui-sdk-constants.md", + }, + { + title: "Document Sandbox Constants", + path: "guides/learn/fundamentals/document-sandbox-constants.md", + }, + { + title: "Developer Terminology", + path: "guides/learn/fundamentals/terminology.md", + }, + ], + }, { title: "Sample add-ons", path: "guides/learn/samples.md", diff --git a/src/pages/guides/learn/fundamentals/constants.md b/src/pages/guides/learn/fundamentals/constants.md new file mode 100644 index 000000000..38599dc57 --- /dev/null +++ b/src/pages/guides/learn/fundamentals/constants.md @@ -0,0 +1,218 @@ +# Using Add-on UI SDK Constants + +Constants provide type-safe ways to interact with the Add-on UI SDK and help prevent runtime errors. This guide covers the most common patterns you'll need to get started quickly. + +## Why Use Constants? + +Constants equal their variable name as a string (e.g., `ButtonType.primary` equals `"primary"`), but using constants provides type safety, IDE autocomplete, and future-proofing against API changes. + + + +For complete technical specifications of all constants, see the [Constants Reference](../../../references/addonsdk/addonsdk-constants.md). + +## Quick Start + +Most constants support two import patterns. Choose based on your needs: + +```javascript +// Named imports (recommended for cleaner code) +import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Constants object access (good for dynamic access) +const format = addOnUISdk.constants.RenditionFormat.png; +``` + + + +#### Important + +Some constants (like `AppEvent`, `SupportedMimeTypes`) are **only available as named exports** and cannot be accessed through `addOnUISdk.constants.*`. See [Import Patterns](#import-patterns) below. + +## Most Common Use Cases + +### Document Export + +The most common constants you'll use for exporting documents: + +```javascript +import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Export current page as PNG +await addOnUISdk.app.document.createRenditions({ + range: Range.currentPage, + format: RenditionFormat.png +}); + +// Export entire document as PDF for printing +await addOnUISdk.app.document.createRenditions({ + range: Range.entireDocument, + format: RenditionFormat.pdf, + intent: RenditionIntent.print +}); +``` + +**Available Options:** + +- `Range`: `currentPage`, `entireDocument`, `specificPages` +- `RenditionFormat`: `png`, `jpg`, `mp4`, `pdf`, `pptx` +- `RenditionIntent`: `export`, `preview`, `print` + +### Modal Dialogs + +Essential constants for user interactions: + +```javascript +import addOnUISdk, { Variant, ButtonType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Show confirmation dialog +const result = await addOnUISdk.app.showModalDialog({ + variant: Variant.confirmation, + title: "Delete Item", + description: "Are you sure?" +}); + +// Handle user response +if (result.buttonType === ButtonType.primary) { + // User confirmed +} else if (result.buttonType === ButtonType.cancel) { + // User cancelled +} +``` + +**Available Options:** + +- `Variant`: `confirmation`, `information`, `warning`, `error`, `input` +- `ButtonType`: `primary`, `secondary`, `cancel`, `close` + +### Event Handling + +**Critical:** Event constants must be imported - they're not available in the constants object: + +```javascript +import addOnUISdk, { AppEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// ✅ Correct - must import AppEvent +addOnUISdk.app.on(AppEvent.themechange, (event) => { + updateUITheme(event.theme); +}); + +// ❌ This will NOT work +addOnUISdk.app.on(addOnUISdk.constants.AppEvent.themechange, handler); // undefined! +``` + +## Import Patterns + +Understanding import patterns is crucial for avoiding runtime errors. + +### Must Import (Named Exports Only) + +These constants **must be imported** and are **not available** through `addOnUISdk.constants.*`: + +```javascript +import addOnUISdk, { + AppEvent, // ❌ NOT in constants object + ColorPickerEvent, // ❌ NOT in constants object + SupportedMimeTypes, // ❌ NOT in constants object + EntrypointType, // ❌ NOT in constants object + PdfReturnUrlType // ❌ NOT in constants object +} from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +``` + +### Flexible Access (Both Ways Work) + +These constants support **both patterns**: + +```javascript +import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Option 1: Named import (recommended) +const options = { + range: Range.currentPage, + format: RenditionFormat.png, + variant: Variant.error +}; + +// Option 2: Constants object (good for dynamic access) +const userFormat = "png"; +const format = addOnUISdk.constants.RenditionFormat[userFormat]; +``` + +## Copy-Paste Import Statements + +### Most Common Scenarios + +```javascript +// Document Export & Rendering +import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Modal Dialogs & UI +import addOnUISdk, { Variant, ButtonType, FieldType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Event Handling (Import Required!) +import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Platform Detection +import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +``` + +## Common Errors & Solutions + +### "Cannot read property of undefined" + +**Problem**: Trying to access named-only exports through constants object. + +```javascript +// ❌ This causes errors +const event = addOnUISdk.constants.AppEvent.themechange; // undefined! +``` + +**Solution**: Always import named-only exports. + +```javascript +// ✅ This works +import addOnUISdk, { AppEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +const event = AppEvent.themechange; +``` + +### Using String Literals Instead of Constants + +**Problem**: Using fragile string literals. + +```javascript +// ❌ Fragile - might break if API changes +await createRenditions({ + range: "currentPage", // String literal + format: "image/png" // String literal +}); +``` + +**Solution**: Always use constants. + +```javascript +// ✅ Safe - will be updated if API changes +await createRenditions({ + range: Range.currentPage, // Constant + format: RenditionFormat.png // Constant +}); +``` + +## Best Practices + +1. **Use named imports for known constants** - cleaner and more reliable +2. **Use constants object for dynamic access** - when the constant name is determined at runtime +3. **Always import named-only exports** - there's no alternative way to access them +4. **Group related imports** - organize by functionality for better readability + +## Next Steps + +- **Complete Reference**: See [Constants Reference](../../../references/addonsdk/addonsdk-constants.md) for all available constants +- **Practical Guides**: + - [Create Renditions](../how_to/create_renditions.md) - Using export constants + - [Modal Dialogs](../how_to/modal_dialogs.md) - Using dialog constants + - [Theme & Locale](../how_to/theme_locale.md) - Using platform constants + + + +#### Pro Tip + +When in doubt, use named imports - they work for all constants and provide the cleanest code! diff --git a/src/pages/guides/learn/fundamentals/document-sandbox-constants.md b/src/pages/guides/learn/fundamentals/document-sandbox-constants.md new file mode 100644 index 000000000..e3024a7e5 --- /dev/null +++ b/src/pages/guides/learn/fundamentals/document-sandbox-constants.md @@ -0,0 +1,325 @@ +--- +keywords: + - Adobe Express + - Express Add-on SDK + - Document Sandbox + - Document APIs + - Constants + - Type safety + - JavaScript + - TypeScript + - Document constants + - Fill types + - Stroke types + - Text alignment + - Blend modes + - Scene node types + - Content creation + - Document manipulation +title: Using Document Sandbox Constants +description: A comprehensive guide to using constants in the Document Sandbox environment for + type-safe document manipulation, covering fill types, text styling, blend modes, and node types. +contributors: + - https://github.com/hollyschinsky +# LLM optimization metadata +canonical: true +ai_assistant_note: "This guide focuses specifically on Document Sandbox constants used in the + document sandbox environment (code.js). For UI SDK constants, refer to the Add-on UI SDK Constants guide. + Covers document-specific constants like FillType, StrokeType, TextAlignment, BlendMode, and SceneNodeType." +semantic_tags: + - document-sandbox-constants + - document-environment + - content-creation + - document-manipulation + - type-safety + - practical-guide +--- + +# Using Document Sandbox Constants + +Document Sandbox constants provide type-safe ways to interact with the Document APIs when creating and manipulating content in Adobe Express documents. This guide covers the most common patterns for document-side development. + +## Why Use Document Constants? + +Document constants ensure consistency when working with document elements, styling, and content creation. They provide type safety, IDE autocomplete, and prevent errors from typos in string values. + + + +For complete technical specifications of all document constants, see the [Document APIs Constants Reference](../../../references/document-sandbox/document-apis/enumerations/ArrowHeadType.md). + +## Quick Start + +Document constants are available directly in the document sandbox environment without imports: + +```javascript +// Document constants are globally available in sandbox +const fillType = FillType.color; +const blendMode = BlendMode.normal; +const textAlignment = TextAlignment.center; +``` + + + +**Important**: Document constants are only available in the document sandbox environment (`code.js`). They cannot be accessed from the iframe UI environment. + +## Most Common Use Cases + +### Fill and Stroke Properties + +```javascript +// Creating solid color fills +const rectangle = editor.createRectangle(); +rectangle.fill = { + type: FillType.color, + color: { red: 1, green: 0, blue: 0, alpha: 1 } +}; + +// Adding strokes +rectangle.stroke = { + type: StrokeType.solid, + color: { red: 0, green: 0, blue: 1, alpha: 1 }, + width: 2, + position: StrokePosition.inside +}; +``` + +**Available Fill Types:** + +- `FillType.color` - Solid color fills +- `FillType.none` - No fill + +**Available Stroke Types:** + +- `StrokeType.solid` - Solid color stroke +- `StrokeType.none` - No stroke + +**Available Stroke Positions:** + +- `StrokePosition.center` - Stroke centered on edge +- `StrokePosition.inside` - Stroke inside the shape +- `StrokePosition.outside` - Stroke outside the shape + +### Text Alignment and Styling + +```javascript +// Creating and styling text +const textNode = editor.createText(); +textNode.text = "Hello World"; + +// Set text alignment +textNode.textAlignment = TextAlignment.center; + +// Set text script style +textNode.textScriptStyle = TextScriptStyle.normal; +``` + +**Available Text Alignments:** + +- `TextAlignment.left` - Left-aligned text +- `TextAlignment.center` - Center-aligned text +- `TextAlignment.right` - Right-aligned text +- `TextAlignment.justify` - Justified text + +**Available Text Script Styles:** + +- `TextScriptStyle.normal` - Normal text +- `TextScriptStyle.superscript` - Superscript text +- `TextScriptStyle.subscript` - Subscript text + +### Blend Modes + +```javascript +// Apply blend modes to visual elements +const shape = editor.createEllipse(); +shape.blendMode = BlendMode.multiply; +``` + +**Common Blend Modes:** + +- `BlendMode.normal` - Normal blending +- `BlendMode.multiply` - Multiply blending +- `BlendMode.screen` - Screen blending +- `BlendMode.overlay` - Overlay blending +- `BlendMode.softLight` - Soft light blending +- `BlendMode.hardLight` - Hard light blending + +### Scene Node Types + +```javascript +// Check node types when traversing the document +editor.context.selection.forEach(node => { + switch (node.type) { + case SceneNodeType.rectangle: + console.log("Selected rectangle"); + break; + case SceneNodeType.ellipse: + console.log("Selected ellipse"); + break; + case SceneNodeType.text: + console.log("Selected text"); + break; + case SceneNodeType.mediaRectangle: + console.log("Selected image/video"); + break; + } +}); +``` + +**Available Scene Node Types:** + +- `SceneNodeType.rectangle` - Rectangle shapes +- `SceneNodeType.ellipse` - Ellipse/circle shapes +- `SceneNodeType.text` - Text elements +- `SceneNodeType.mediaRectangle` - Images and videos +- `SceneNodeType.line` - Line elements +- `SceneNodeType.path` - Custom path shapes +- `SceneNodeType.group` - Grouped elements + +## Import Patterns + +### Document Sandbox Environment + +```javascript +// In code.js - constants are globally available +const editor = addOnSandboxSdk.editor; + +// Use constants directly (no imports needed) +const newRect = editor.createRectangle(); +newRect.fill = { + type: FillType.color, + color: { red: 0.5, green: 0.5, blue: 0.5, alpha: 1 } +}; +``` + +### Communication with UI + +```javascript +// In code.js - expose constants to UI if needed +addOnSandboxSdk.instance.runtime.exposeApi({ + getAvailableBlendModes() { + return { + normal: BlendMode.normal, + multiply: BlendMode.multiply, + screen: BlendMode.screen, + overlay: BlendMode.overlay + }; + } +}); +``` + +## Common Patterns + +### Creating Styled Shapes + +```javascript +function createStyledRectangle(color, strokeColor) { + const rect = editor.createRectangle(); + + // Set fill + rect.fill = { + type: FillType.color, + color: color + }; + + // Set stroke + rect.stroke = { + type: StrokeType.solid, + color: strokeColor, + width: 2, + position: StrokePosition.inside + }; + + // Set blend mode + rect.blendMode = BlendMode.normal; + + return rect; +} +``` + +### Text Formatting + +```javascript +function createFormattedText(content, alignment = TextAlignment.left) { + const textNode = editor.createText(); + textNode.text = content; + textNode.textAlignment = alignment; + + // Apply character styling + const characterStyles = { + fontSize: 24, + fontFamily: "Arial", + textScriptStyle: TextScriptStyle.normal + }; + + textNode.setRangeCharacterStyles(0, content.length, characterStyles); + + return textNode; +} +``` + +### Node Type Checking + +```javascript +function processSelectedNodes() { + const selection = editor.context.selection; + + selection.forEach(node => { + // Type-safe node processing + if (node.type === SceneNodeType.rectangle || node.type === SceneNodeType.ellipse) { + // Handle shapes + if (node.fill?.type === FillType.color) { + console.log("Shape has color fill"); + } + } else if (node.type === SceneNodeType.text) { + // Handle text + console.log(`Text alignment: ${node.textAlignment}`); + } + }); +} +``` + +## Common Pitfalls + +### Environment Confusion + +```javascript +// ❌ Wrong - Document constants not available in UI +// In index.html/index.js +import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +const fillType = FillType.color; // Error: FillType is not defined + +// ✅ Correct - Use in document sandbox only +// In code.js +const fillType = FillType.color; // Works correctly +``` + +### Missing Type Checks + +```javascript +// ❌ Risky - assuming node type +function changeColor(node, color) { + node.fill = { type: FillType.color, color }; // May fail on text nodes +} + +// ✅ Safe - check node type first +function changeColor(node, color) { + if (node.type === SceneNodeType.rectangle || node.type === SceneNodeType.ellipse) { + node.fill = { type: FillType.color, color }; + } +} +``` + +## Best Practices + +1. **Always use constants** instead of string literals for better type safety +2. **Check node types** before applying properties that may not be available +3. **Use meaningful variable names** when working with complex styling +4. **Group related constants** for better code organization +5. **Document your styling functions** with the constants they expect + +## Related Documentation + +- [Document APIs Reference](../../../references/document-sandbox/document-apis/) +- [Document APIs Constants](../../../references/document-sandbox/document-apis/enumerations/ArrowHeadType.md) +- [Add-on UI SDK Constants](./ui-sdk-constants.md) +- [Developer Terminology](./terminology.md) diff --git a/src/pages/guides/learn/fundamentals/terminology.md b/src/pages/guides/learn/fundamentals/terminology.md new file mode 100644 index 000000000..7a6f8c841 --- /dev/null +++ b/src/pages/guides/learn/fundamentals/terminology.md @@ -0,0 +1,654 @@ +--- +keywords: + - Adobe Express + - Express Add-on SDK + - Add-on UI SDK + - Document Sandbox + - Document APIs + - SDK terminology + - API reference + - Developer glossary + - Naming conventions + - Import statements + - Runtime environments + - Communication APIs + - JavaScript + - TypeScript + - Extensibility + - Manifest configuration + - File structure + - Bundle organization + - Development workflow + - Debugging + - Cross-origin isolation +title: Developer Terminology Reference +description: A comprehensive reference guide for Adobe Express Add-ons SDK terminology, + naming conventions, and standardized definitions to ensure consistency across + documentation and development. +contributors: + - https://github.com/hollyschinsky +# LLM optimization metadata +canonical: true +ai_assistant_note: "This page provides authoritative definitions and relationships + for Adobe Express Add-on terminology. Use these standardized terms when helping + developers choose between Add-on UI SDK (iframe/UI), Document APIs (content + creation), and Communication APIs (connecting the two environments)." +semantic_tags: + - canonical-reference + - terminology-authority + - sdk-disambiguation + - import-patterns + - runtime-environments + - manifest-configuration + - file-structure + - development-workflow + - debugging-guide +--- + +# Developer Terminology Reference + +## Overview + +This reference clarifies the naming conventions and terminology used throughout the Adobe Express Add-ons documentation. Use this guide to understand the standardized terms and their relationships. + +## Quick Reference + + + +**Need a quick answer?** Jump to these common questions: + +- **Building UI?** → [Add-on UI SDK](#add-on-ui-sdk) (iframe environment) +- **Creating content?** → [Document APIs](#document-apis) (document sandbox) +- **Connecting UI to content?** → [Communication APIs](#communication--apis) +- **File organization?** → [File Structure & Bundle](#file-structure--bundle-terminology) +- **Manifest setup?** → [Manifest & Configuration](#manifest--configuration-terminology) +- **Debugging issues?** → [Development Workflow & Debugging](#development-workflow--debugging-terminology) +- **Import errors?** → [Troubleshooting](#troubleshooting-common-issues) +- **Which SDK when?** → [Decision Matrix](#decision-matrix-which-sdk-to-use) + +### Key Relationships + +```mermaid +graph TB + subgraph "Adobe Express Add-on" + subgraph "Iframe Runtime Environment" + UI[Add-on UI SDK] + DOM[DOM & Browser APIs] + UIF[User Interface] + IE[Import/Export] + end + + subgraph "Document Sandbox Runtime Environment" + DOC[Document APIs] + WEB[Limited Web APIs] + CC[Content Creation] + DM[Document Manipulation] + end + + subgraph "Communication Layer" + COMM[Communication APIs] + EXPOSE[exposeApi] + PROXY[apiProxy] + end + end + + UI --> UIF + UI --> IE + UI --> EXPOSE + DOC --> CC + DOC --> DM + DOC --> PROXY + WEB --> DOC + + EXPOSE <--> COMM + PROXY <--> COMM + + classDef iframe fill:#e1f5fe,stroke:#01579b,stroke-width:2px + classDef sandbox fill:#f3e5f5,stroke:#4a148c,stroke-width:2px + classDef communication fill:#fff3e0,stroke:#e65100,stroke-width:2px + + class UI,DOM,UIF,IE iframe + class DOC,WEB,CC,DM sandbox + class COMM,EXPOSE,PROXY communication +``` + +## Core SDK Components + +### Add-on UI SDK + + + +**Preferred Term:** Add-on UI SDK + +The SDK that provides APIs for the UI panel of your add-on running in the iframe environment. + +**Import Statement:** + +```javascript +import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js" +``` + +**Also Known As:** UI SDK, addOnUISdk (in code) +**Use When:** Building UI components, handling user interactions, importing/exporting content + +### Document Sandbox + + + +**Preferred Term:** Document Sandbox + +The sandboxed JavaScript runtime environment that provides access to the Document APIs for content authoring. + +**Import Statement:** + +```javascript +import addOnSandboxSdk from "add-on-sdk-document-sandbox" +``` + +**Also Known As:** Document Model Sandbox, documentSandbox (in manifest) +**Use When:** Creating or modifying document content, accessing document structure + +### Document APIs + + + +**Preferred Term:** Document APIs + +The APIs that allow you to interact with and modify Adobe Express documents. + +**Package:** + +```javascript +import { Editor, Context } from "@express-document-sdk" +``` + +**Also Known As:** Document API, Express Document API +**Use When:** Manipulating document elements, creating shapes, working with text + +## Runtime Environments + +| Term | Definition | Context | Related Terms | +|------|------------|---------|---------------| +| **Iframe Runtime** | The browser environment where your add-on's UI runs | UI development, user interactions | Add-on UI SDK, Panel, UI Runtime | +| **Document Sandbox Runtime** | The isolated JavaScript environment for document manipulation | Content authoring, document editing | Document Sandbox SDK, documentSandbox | + +## Communication & APIs + +| Term | Definition | Import/Access | Related Terms | +|------|------------|---------------|---------------| +| **Communication APIs** | APIs for bidirectional communication between iframe and document sandbox | `addOnSandboxSdk.instance.runtime` | exposeApi(), apiProxy() | +| **Web APIs** | Limited browser APIs available in the document sandbox | Global objects in sandbox | Console, fetch (via proxy) | + +## Import Patterns & Code References + +### Standardized Import Statements + +```javascript +// Add-on UI SDK (for iframe/UI code) +import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Document Sandbox SDK (for document sandbox code) +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; + +// Document APIs (for TypeScript types) +import { Editor, Context } from "@express-document-sdk"; +``` + +### Runtime References + +```javascript +// In iframe code +const { runtime } = addOnUISdk.instance; + +// In document sandbox code +const { runtime } = addOnSandboxSdk.instance; +``` + +## Decision Matrix: Which SDK to Use? + + + +**Choose the right tool for your task:** + +| Your Goal | Use This | Import Statement | +|-----------|----------|------------------| +| Build UI components, handle user input | **Add-on UI SDK** | `import addOnUISdk from "..."` | +| Create/modify document content | **Document APIs** | Available in document sandbox | +| Communicate between UI and document | **Communication APIs** | `runtime.exposeApi()` / `runtime.apiProxy()` | +| Access limited browser features in sandbox | **Web APIs** | Global objects in document sandbox | + +## Quick Reference by Use Case + +**Building a UI Panel?** → Add-on UI SDK +**Creating new content?** → Document APIs (in Document Sandbox) +**Modifying existing content?** → Document APIs (in Document Sandbox) +**Connecting UI to Document?** → Communication APIs +**Need browser features in sandbox?** → Web APIs or proxy from iframe + +## Common Confusion Points + +### "SDK" vs "API" vs "Runtime" + +- **SDK (Software Development Kit)**: A collection of tools, libraries, and documentation (e.g., Add-on UI SDK) +- **API (Application Programming Interface)**: Specific methods and interfaces you can call (e.g., Document APIs) +- **Runtime**: The execution environment where code runs (e.g., Iframe Runtime, Document Sandbox Runtime) + +### Import Statement Patterns + +```javascript +// ✅ Correct patterns +import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; + +// ❌ Common mistakes +import { addOnUISdk } from "..."; // Wrong: should be default import +import addOnSandboxSdk from "add-on-ui-sdk"; // Wrong: mixed up the SDKs +``` + +### Context Switching + +| When you're in... | You have access to... | To communicate with the other side... | +|-------------------|----------------------|--------------------------------------| +| **Iframe Runtime** | Add-on UI SDK, DOM, browser APIs | Use `runtime.exposeApi()` or `runtime.apiProxy()` | +| **Document Sandbox** | Document APIs, limited Web APIs | Use `runtime.exposeApi()` or `runtime.apiProxy()` | + +## File Structure & Bundle Terminology + +### Add-on Bundle Structure + +**Add-on Bundle** +The complete packaged structure of your add-on, including all files and the manifest. + +Based on the Adobe Express Add-on CLI templates: + +**Basic JavaScript Template (UI only, no document sandbox):** + +```text +my-addon/ +└── src/ + ├── index.html # Main UI entry point + ├── index.js # UI logic + ├── manifest.json # Configuration + └── README.md # Documentation +``` + +**JavaScript Template with Document Sandbox:** + +```text +my-addon/ +└── src/ + ├── sandbox/ + │ ├── code.js # Document sandbox code + │ └── tsconfig.json # TypeScript config for sandbox + ├── ui/ + │ ├── index.html # Main UI entry point + │ ├── index.js # UI logic + │ └── tsconfig.json # TypeScript config for UI + ├── index.html # Root HTML file + ├── manifest.json # Configuration + └── README.md # Documentation +``` + +### Entry Point Files + +**Main Entry File (`index.html`)** +The primary HTML file that loads when your add-on panel opens. Contains or references your UI code. + +**Document Sandbox Entry (`code.js`)** +The JavaScript file that runs in the document sandbox environment. Contains document manipulation logic. + +**Relative Path Resolution** +How files within your bundle reference each other using relative paths: + +```html + + + + + +``` + +```javascript +// In sandbox/code.js - no imports needed for sandbox SDK +// addOnSandboxSdk is globally available +``` + +### Static Assets Organization + +**Static Assets** +Non-code resources like images, icons, fonts, and media files included in your bundle. + +**Asset Referencing** +How to properly reference static assets from your code: + +```html + +Logo +``` + +```javascript +// Dynamic asset loading +const iconUrl = new URL('./assets/icons/star.svg', import.meta.url); +``` + +### Bundle Optimization + +**Bundle Size Considerations** +Keeping your add-on bundle small for faster loading: + +- Minimize large assets +- Use efficient image formats +- Remove unused dependencies +- Consider lazy loading for non-critical resources + +**File Organization Best Practices** +Structuring your bundle for maintainability: + +- Separate concerns (UI, logic, styling) +- Group related assets in folders +- Use consistent naming conventions +- Keep manifest.json at root level + +### External Dependencies + +**Library Integration** +How to include external JavaScript libraries in your bundle: + +```html + + + + + +``` + +**Dependency Management** +Strategies for managing external dependencies: + +- **Bundle locally** - Include in your add-on bundle (recommended for reliability) +- **CDN loading** - Load from external CDN (requires internet connection) +- **Hybrid approach** - Local fallback with CDN primary + +## Manifest & Configuration Terminology + +### Core Manifest Concepts + +**Manifest File (`manifest.json`)** +The configuration file at the root of your add-on bundle that defines metadata, entry points, and permissions. + +**Manifest Version** +The schema version of the manifest format. Currently version 2 is the latest standard. + +```json +{ + "manifestVersion": 2, + "version": "1.0.0" +} +``` + +### Entry Points & Structure + +**Entry Point** +A defined way for users to access your add-on functionality. Currently only `"panel"` type is supported. + +**Panel Entry Point** +The main UI interface of your add-on that appears in the Adobe Express sidebar. + +```json +// Basic template (UI only, no document sandbox) +"entryPoints": [{ + "type": "panel", + "id": "panel1", + "main": "index.html" +}] + +// With document sandbox (separate ui/ and sandbox/ folders) +"entryPoints": [{ + "type": "panel", + "id": "panel1", + "main": "ui/index.html", + "documentSandbox": "sandbox/code.js" +}] +``` + +**Main File** +The HTML file that serves as the entry point for your add-on's UI (typically `index.html`). + +**Document Sandbox File** +The JavaScript file containing code that runs in the document sandbox environment (typically `code.js`). + +### Development vs Production + +**Test ID** +A unique identifier used during development workflows only. Auto-generated by CLI and ignored in marketplace submissions. + +**Production Name** +The add-on name provided during marketplace submission, which overrides the development `name` field. + +### Permissions & Security + +**Sandbox Permissions** +Security restrictions that control what browser features your add-on can access: + +- `allow-popups` - Enable popup windows +- `allow-downloads` - Enable file downloads +- `allow-presentation` - Enable presentation API +- `allow-popups-to-escape-sandbox` - Required for premium content flows + +**OAuth Permissions** +Domains allowed for OAuth authentication flows: + +```json +"permissions": { + "oauth": ["www.dropbox.com", "api.example.com"] +} +``` + +### Device & Platform Support + +**Device Class** +The form factor categories your add-on supports: + +- `desktop` - Browser on desktop/laptop (currently the only supported option) +- `mobile` - Browser on mobile devices (future support) +- `tablet` - Browser on tablet devices (future support) + +**Touch Support** +Boolean flag indicating whether your add-on works on touch-only devices: + +```json +"requirements": { + "supportsTouch": false +} +``` + +## Development Workflow & Debugging Terminology + +### Development Environment + +**Add-on Development Panel** +The built-in debugging interface in Adobe Express that allows you to load, reload, and manage add-ons during development. + +**Hot Reload** +Automatic refresh of your add-on when file changes are detected during development. May occasionally fail and require manual reload. + +**Manual Reload** +Using the "Refresh" button in the Add-on Development Panel to force reload your add-on and pick up changes. + +### Debugging Context + +**Browser Developer Tools** +Standard browser debugging features accessible by right-clicking and selecting "Inspect Element": + +- **Console** - Log messages, errors, and execute JavaScript +- **Debugger** - Set breakpoints and step through code +- **Network Monitor** - Track network requests and responses +- **Profiler** - Analyze performance and identify bottlenecks + +**Console Context** +Understanding which runtime environment your console messages appear in: + +- **Iframe Console** - Messages from UI code (`index.html` and related scripts) +- **Document Sandbox Console** - Messages from document manipulation code (`code.js`) + +### Common Development Issues + +**Communication Bridge Failure** +When the connection between iframe and document sandbox fails to initialize properly. Often resolved by manual reload. + +**Race Condition** +Timing issue where the communication bridge isn't ready when UI interactions occur. Clicking buttons may appear to do nothing. + +**Reentrancy Protection** +Preventing users from triggering multiple simultaneous operations that could corrupt the document or undo stack: + +```javascript +// Disable UI during async operations +button.disabled = true; +await performDocumentOperation(); +button.disabled = false; +``` + +**API Proxy Mismatch** +Common error where wrong proxy types are requested: + +```javascript +// ✅ Correct +// In iframe: runtime.apiProxy("script") +// In sandbox: runtime.apiProxy("panel") + +// ❌ Wrong - will fail silently +// In iframe: runtime.apiProxy("panel") +``` + +### Cross-Origin Isolation (COI) + +**Cross-Origin Isolation** +Security model that affects how your add-on can interact with external resources and APIs. May require specific headers or workarounds for certain integrations. + +**COI Handling** +Techniques for working within the cross-origin isolation constraints, such as using proxy endpoints or alternative authentication flows. + +### Performance Monitoring + +**Frame Duration Warnings** +Console messages about excessive frame duration (e.g., "Detected a possible stutter") that can generally be ignored during development. + +**Transaction Warnings** +Messages like "Empty transaction not added to pendingTransaction" that are informational and can be ignored. + +## Semantic Relationships + +### Hierarchical Structure + +```text +Adobe Express Add-on +├── Iframe Runtime Environment +│ ├── Add-on UI SDK +│ ├── User Interface Components +│ └── Import/Export Capabilities +└── Document Sandbox Runtime Environment + ├── Document APIs + ├── Content Authoring + └── Limited Web APIs +``` + +### Functional Relationships + +- **Add-on UI SDK** ↔ **Communication APIs** ↔ **Document APIs** +- **Iframe Runtime** ↔ **Document Sandbox Runtime** (via Communication APIs) +- **Document APIs** ⊂ **Document Sandbox** (APIs are available within the sandbox) + +## Troubleshooting Common Issues + +### "undefined" Errors + + + +**Problem**: `addOnUISdk.constants.SomeConstant` returns `undefined` + +**Solution**: Some constants require explicit imports. Check the [Add-on UI SDK Constants Guide](./ui-sdk-constants.md) or [Constants Reference](../../../references/addonsdk/addonsdk-constants.md) + +### Import Errors + + + +**Problem**: `Cannot resolve module 'add-on-sdk-document-sandbox'` + +**Solution**: This import only works in document sandbox context, not iframe context + +### Communication Errors + + + +**Problem**: Cannot call methods between iframe and document sandbox + +**Solution**: Ensure you're using `exposeApi()` in one environment and `apiProxy()` in the other + +## Frequently Asked Questions + +### General Terminology + +**Q: What's the difference between "Add-on UI SDK" and "Document APIs"?** +A: The **Add-on UI SDK** runs in the iframe and handles UI, user interactions, and import/export. **Document APIs** run in the document sandbox and handle content creation and document manipulation. Think of it as UI vs Content. + +**Q: Why are there two different runtime environments?** +A: Security and performance. The **iframe runtime** is sandboxed for security but has full browser capabilities. The **document sandbox runtime** has direct access to Adobe Express's document engine but limited browser APIs. + +**Q: What does "sandbox" mean in this context?** +A: A **sandbox** is an isolated execution environment. The **document sandbox** specifically refers to the secure JavaScript environment where Document APIs run, separate from the iframe where your UI runs. + +### Import and Usage + +**Q: Why do I get "undefined" when accessing `addOnUISdk.constants.SomeConstant`?** +A: Some constants require explicit imports and aren't available through the `constants` object. Check the [Constants Reference](../../../references/addonsdk/addonsdk-constants.md) to see which constants need to be imported directly. + +**Q: When do I use `addOnUISdk` vs `addOnSandboxSdk`?** +A: Use `addOnUISdk` in your **iframe code** (usually `index.html` or `ui/` folder). Use `addOnSandboxSdk` in your **document sandbox code** (usually `code.js` or `sandbox/` folder). + +**Q: Can I use Document APIs in my iframe code?** +A: No, Document APIs only work in the document sandbox. To use them from your iframe, you need to expose them via Communication APIs using `exposeApi()` and `apiProxy()`. + +### Architecture and Communication + +**Q: How do I communicate between my UI and document sandbox?** +A: Use the **Communication APIs**: + +- In one environment: `runtime.exposeApi(myObject)` +- In the other: `const proxy = await runtime.apiProxy("environmentName")` + +**Q: What's the difference between "iframe runtime" and "UI runtime"?** +A: They're the same thing. **"Iframe runtime"** is the preferred term - it's the browser environment where your add-on's UI runs. + +**Q: Why can't I use `fetch()` in the document sandbox?** +A: The document sandbox has limited Web APIs for security. You can either use the limited APIs available or proxy `fetch()` from your iframe using Communication APIs. + +### Choosing the Right SDK + +**Q: I want to add a button that creates a rectangle. Which SDK do I use?** +A: Both! Use the **Add-on UI SDK** to create the button in your iframe, then use **Communication APIs** to call **Document APIs** in the document sandbox to create the rectangle. + +**Q: I'm building a form to collect user input. Which environment should this be in?** +A: The **iframe runtime** using the **Add-on UI SDK**. Forms and user interactions belong in the iframe where you have full DOM access. + +**Q: I want to change the color of selected elements. Where does this code go?** +A: In the **document sandbox** using **Document APIs**. Content manipulation always happens in the document sandbox. + +### Legacy and Deprecated Terms + +**Q: I see "Document SDK" in some older documentation. What should I use instead?** +A: Use **"Document APIs"** instead. "Document SDK" is deprecated terminology. + +**Q: What's the difference between "Document Model Sandbox" and "Document Sandbox"?** +A: They're the same thing. **"Document Sandbox"** is the preferred, simplified term. + +**Q: I see references to "UI SDK" - is this different from "Add-on UI SDK"?** +A: No, they're the same. **"Add-on UI SDK"** is the full, preferred term for clarity. + +## Related Documentation + +- [Add-on UI SDK Reference](../../../references/addonsdk/index.md) +- [Document Sandbox Overview](../../../references/document-sandbox/index.md) +- [Communication APIs](../../../references/document-sandbox/communication/index.md) +- [Platform Concepts](../platform_concepts/context.md) +- [Constants Usage Guide](./constants.md) diff --git a/src/pages/guides/learn/fundamentals/ui-sdk-constants.md b/src/pages/guides/learn/fundamentals/ui-sdk-constants.md new file mode 100644 index 000000000..6ae279440 --- /dev/null +++ b/src/pages/guides/learn/fundamentals/ui-sdk-constants.md @@ -0,0 +1,253 @@ +--- +keywords: + - Adobe Express + - Express Add-on SDK + - Add-on UI SDK + - Constants + - Import patterns + - Type safety + - JavaScript + - TypeScript + - Named exports + - SDK constants + - UI constants + - Modal dialogs + - Document export + - Platform detection + - Event handling +title: Using Add-on UI SDK Constants +description: A practical guide to using constants in the Add-on UI SDK for type-safe development, + covering import patterns, common use cases, and best practices for iframe environment development. +contributors: + - https://github.com/hollyschinsky +# LLM optimization metadata +canonical: true +ai_assistant_note: "This guide focuses specifically on Add-on UI SDK constants used in the iframe + environment. For document sandbox constants, refer to the Document Sandbox Constants guide. + Covers import patterns, dual access vs named-only exports, and practical usage examples." +semantic_tags: + - ui-sdk-constants + - iframe-environment + - import-patterns + - type-safety + - practical-guide +--- + +# Using Add-on UI SDK Constants + +Constants provide type-safe ways to interact with the Add-on UI SDK and help prevent runtime errors. This guide covers the most common patterns you'll need to get started quickly. + +## Why Use Constants? + +Constants equal their variable name as a string (e.g., `ButtonType.primary` equals `"primary"`), but using constants provides type safety, IDE autocomplete, and future-proofing against API changes. + + + +For complete technical specifications of all constants, see the [Constants Reference](../../../references/addonsdk/addonsdk-constants.md). + +## Quick Start + +Most constants support two import patterns. Choose based on your needs: + +```javascript +// Named imports (recommended for cleaner code) +import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Constants object access (good for dynamic access) +const format = addOnUISdk.constants.RenditionFormat.png; +``` + + + +#### Important + +Some constants (like `AppEvent`, `SupportedMimeTypes`) are **only available as named exports** and cannot be accessed through `addOnUISdk.constants.*`. See [Import Patterns](#import-patterns) below. + +## Most Common Use Cases + +### Document Export + +The most common constants you'll use for exporting documents: + +```javascript +import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Export current page as PNG +await addOnUISdk.app.document.createRenditions({ + range: Range.currentPage, + format: RenditionFormat.png +}); + +// Export entire document as PDF for printing +await addOnUISdk.app.document.createRenditions({ + range: Range.entireDocument, + format: RenditionFormat.pdf, + intent: RenditionIntent.print +}); +``` + +**Available Options:** + +- `Range`: `currentPage`, `entireDocument`, `specificPages` +- `RenditionFormat`: `png`, `jpg`, `mp4`, `pdf`, `pptx` +- `RenditionIntent`: `export`, `preview`, `print` + +### Modal Dialogs + +Essential constants for user interactions: + +```javascript +import addOnUISdk, { Variant, ButtonType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Show confirmation dialog +const result = await addOnUISdk.app.showModalDialog({ + variant: Variant.confirmation, + title: "Delete Item", + description: "Are you sure?" +}); + +// Handle user response +if (result.buttonType === ButtonType.primary) { + // User confirmed +} else if (result.buttonType === ButtonType.cancel) { + // User cancelled +} +``` + +**Available Options:** + +- `Variant`: `confirmation`, `information`, `warning`, `error`, `input` +- `ButtonType`: `primary`, `secondary`, `cancel`, `close` + +### Event Handling + +**Critical:** Event constants must be imported - they're not available in the constants object: + +```javascript +import addOnUISdk, { AppEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// ✅ Correct - must import AppEvent +addOnUISdk.app.on(AppEvent.themechange, (event) => { + updateUITheme(event.theme); +}); + +// ❌ This will NOT work +addOnUISdk.app.on(addOnUISdk.constants.AppEvent.themechange, handler); // undefined! +``` + +## Import Patterns + +Understanding import patterns is crucial for avoiding runtime errors. + +### Must Import (Named Exports Only) + +These constants **must be imported** and are **not available** through `addOnUISdk.constants.*`: + +```javascript +import addOnUISdk, { + AppEvent, // ❌ NOT in constants object + ColorPickerEvent, // ❌ NOT in constants object + SupportedMimeTypes, // ❌ NOT in constants object + EntrypointType, // ❌ NOT in constants object + PdfReturnUrlType // ❌ NOT in constants object +} from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +``` + +### Flexible Access (Both Ways Work) + +These constants support **both patterns**: + +```javascript +import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Option 1: Named import (recommended) +const options = { + range: Range.currentPage, + format: RenditionFormat.png, + variant: Variant.error +}; + +// Option 2: Constants object (good for dynamic access) +const userFormat = "png"; +const format = addOnUISdk.constants.RenditionFormat[userFormat]; +``` + +## Copy-Paste Import Statements + +### Most Common Scenarios + +```javascript +// Document Export & Rendering +import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Modal Dialogs & UI +import addOnUISdk, { Variant, ButtonType, FieldType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Event Handling (Import Required!) +import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// Platform Detection +import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +``` + +## Common Errors & Solutions + +### "Cannot read property of undefined" + +**Problem**: Trying to access named-only exports through constants object. + +```javascript +// ❌ This causes errors +const event = addOnUISdk.constants.AppEvent.themechange; // undefined! +``` + +**Solution**: Always import named-only exports. + +```javascript +// ✅ This works +import addOnUISdk, { AppEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +const event = AppEvent.themechange; +``` + +### Using String Literals Instead of Constants + +**Problem**: Using fragile string literals. + +```javascript +// ❌ Fragile - might break if API changes +await createRenditions({ + range: "currentPage", // String literal + format: "image/png" // String literal +}); +``` + +**Solution**: Always use constants. + +```javascript +// ✅ Safe - will be updated if API changes +await createRenditions({ + range: Range.currentPage, // Constant + format: RenditionFormat.png // Constant +}); +``` + +## Best Practices + +1. **Use named imports for known constants** - cleaner and more reliable +2. **Use constants object for dynamic access** - when the constant name is determined at runtime +3. **Always import named-only exports** - there's no alternative way to access them +4. **Group related imports** - organize by functionality for better readability + +## Next Steps + +- **Complete Reference**: See [Constants Reference](../../../references/addonsdk/addonsdk-constants.md) for all available constants +- **Practical Guides**: + - [Create Renditions](../how_to/create_renditions.md) - Using export constants + - [Modal Dialogs](../how_to/modal_dialogs.md) - Using dialog constants + - [Theme & Locale](../how_to/theme_locale.md) - Using platform constants + + + +#### Pro Tip + +When in doubt, use named imports - they work for all constants and provide the cleanest code! diff --git a/src/pages/references/addonsdk/addonsdk-constants.md b/src/pages/references/addonsdk/addonsdk-constants.md index a0b9b4b6a..49c2ec9c9 100644 --- a/src/pages/references/addonsdk/addonsdk-constants.md +++ b/src/pages/references/addonsdk/addonsdk-constants.md @@ -5,7 +5,7 @@ This reference provides the complete technical specification for all constants u - Constants available in `addOnUISdk.constants.*` (dual access) - Constants available only as named exports (import required) -For practical examples and use cases, see the [Using Constants Guide](../../guides/learn/how_to/ui_sdk_constants.md). +For practical examples and use cases, see the [Add-on UI SDK Constants Guide](../../guides/learn/fundamentals/ui-sdk-constants.md). @@ -17,7 +17,7 @@ Adobe Express Add-on SDK constants are available through different import patter -**Critical:** Attempting to access import-required constants through `addOnUISdk.constants.*` will return `undefined` and cause runtime errors. Always check the patterns below before using any constant. +**Important:** Attempting to access import-required constants through `addOnUISdk.constants.*` will return `undefined` and cause runtime errors. Always check the patterns below before using any constant. ### Named Exports Only (Import Required) @@ -196,11 +196,11 @@ import addOnUISdk, { AuthorizationStatus } from "https://new.express.adobe.com/s ## Constants Reference -This section provides the complete technical specification for all Add-on UI SDK constants, organized by functional category. For practical examples and usage patterns, see the [Using Constants Guide](../../guides/learn/how_to/ui_sdk_constants.md). +This section provides the complete technical specification for all Add-on UI SDK constants, organized by functional category. For practical examples and usage patterns, see the [Add-on UI SDK Constants Guide](../../guides/learn/fundamentals/ui-sdk-constants.md). ## Developer Tips - + **Quick Start Tips:** @@ -209,376 +209,560 @@ This section provides the complete technical specification for all Add-on UI SDK - **Never guess** - check if constants are import-required before using - **Use TypeScript** for compile-time validation and better IDE support -## Constants - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

              Name

              Type

              Description

              BitRate

              number

              -

              Bit rate in bits per second.

              -
                -
              • mbps4
              • 4000000
                -
              • mbps8
              • 8000000
                -
              • mbps10
              • 10000000
                -
              • mbps12
              • 12000000
                -
              • mbps15
              • 15000000
                -
              • mbps25
              • 25000000
                -
              • mbps50
              • 50000000
                -
              -

              BleedUnit

              string

              -

              Units for the page bleed.

              -
                -
              • "in" (`Inch`)
              • Inch units. -
              • "mm" (`Millimeter`)
              • Millimeter units. -
              -

              ButtonType

              string

              -

              The type of the button pressed in a dialog. Dual access: both named export and constants object.

              -
                -
              • primary
              • Primary button pressed. -
              • secondary
              • Secondary button pressed. -
              • cancel
              • Cancel button pressed. -
              • close
              • Dialog closed via ESC or close(X) button. -
              -

              ColorPickerEvent

              string

              -

              Custom events dispatched by the Color Picker. Named export only - not available in constants object.

              -
                -
              • colorChange
              • "colorpicker-color-change"
                -
              • close
              • "colorpicker-close"
                -
              -

              ColorPickerPlacement

              string

              -

              Placement of the color picker popover with respect to the anchor element. Dual access: both named export and constants object.

              -
                -
              • top
              • "top"
                -
              • bottom
              • "bottom"
                -
              • left
              • "left"
                -
              • right
              • "right"
                -
              -

              DialogResultType

              string

              -

              The type of modal dialog result.

              -
                -
              • alert
              • Alert dialog result (simple dialogs all return this). -
              • input
              • Input dialog result. -
              • custom
              • Custom dialog result. -
              -

              EditorPanel

              string

              -

              The Adobe Express Editor panel to be opened.

              -
                -
              • search
              • Editor Search panel. -
              • yourStuff
              • Editor Your stuff panel. -
              • templates
              • Editor Templates panel. -
              • media
              • Editor Media panel. -
              • text
              • Editor Text panel. -
              • elements
              • Editor Elements panel. -
              • grids
              • Editor Grids panel. -
              • brands
              • Editor Brands panel. -
              • addOns
              • Editor Add-ons panel. -
              -

              ElementsTabs

              string

              -

              Tabs in the Editor's Elements panel.

              -
                -
              • designAssets
              • Design assets tab. -
              • backgrounds
              • Backgrounds tab. -
              • shapes
              • Shapes tab. -
              • stockIcons
              • Icons tab. -
              • charts
              • Charts tab. -
              -

              FileSizeLimitUnit

              string

              -

              Unit of the file size limit.

              -
                -
              • KB
              • "KB"
                -
              • MB
              • "MB"
                -
              -

              FrameRate

              number

              -

              Frame rate in frames per second.

              -
                -
              • fps23_976
              • 23.976
                -
              • fps24
              • 24
                -
              • fps25
              • 25
                -
              • fps29_97
              • 29.97
                -
              • fps30
              • 30
                -
              • fps60
              • 60
                -
              -

              LinkOptions

              string

              -

              The type of link

              -
                -
              • document
              • Link to the current document. -
              • published
              • Link to the published document. -
              -

              MediaTabs

              string

              -

              Tabs in the Editor's Media panel.

              -
                -
              • video
              • Video tab. -
              • audio
              • Audio tab. -
              • photos
              • Photos tab. -
              -

              PanelActionType

              string

              -

              Types of actions that can be performed on Editor panels.

              -
                -
              • search
              • Action type to perform search within the Editor panel. -
              • navigate
              • Action type to perform navigation within the Editor panel. -
              -

              Range

              string

              -

              Rendition page range. Dual access: both named export and constants object.

              -
                -
              • currentPage
              • Generate rendition for the current page -
              • entireDocument
              • Generate rendition for all pages -
              • specificPages
              • Generate rendition for specific pages -
              -

              RenditionFormat

              string

              -

              Required output format of the rendition. Dual access: both named export and constants object.

              -
                -
              • jpg
              • "image/jpeg"
                -
              • png
              • "image/png"
                -
              • mp4
              • "video/mp4"
                -
              • pdf
              • "application/pdf"
                -
              • pptx
              • "application/vnd.openxmlformats-officedocument.presentationml.presentation"
                -
              -

              RenditionIntent

              string

              -

              The intent to set for creating the rendition. Dual access: both named export and constants object.

              -
                -
              • preview
              • Intent to preview the content. -
              • export
              • Intent to export/download the content (default). -
              • print
              • Intent to export and print the content **Note:** For `pdf` format, a print optimized pdf is generated. This option is not supported for `mp4` format. -
              -

              RenditionType

              string

              -

              The type of rendition. Currently returns "page".

              -

              RuntimeType

              string

              -

              Runtime type of the entrypoint creating this backend object. -

                -
              • panel
              • add-on's iframe runtime, ie: code running in index.html -
              • script
              • add-on's document sandbox code ie: code running in code.js -
              • dialog
              • currently open dialog code -
              -

              -

              Variant

              string

              -

              Types of dialog variants supported. Dual access: both named export and constants object.

              -
                -
              • confirmation
              • Ask a user to confirm an action. -
              • information
              • Share information for user to acknowledge. -
              • warning
              • Share information that a user needs to consider before proceeding. -
              • destructive
              • Tell a user that if they proceed with an action, it may impact their data in a negative way. -
              • error
              • Communicate critical issue that a user needs to resolve before proceeding. -
              • input
              • Ask a user to provide some inputs. -
              • custom
              • A dialog that can render complex forms and content. -
              -

              VideoResolution

              string

              -

              Video resolution options for the mp4 renditions.

              -
                -
              • sd480p
              • "480p"
                -
              • hd720p
              • "720p"
                -
              • fhd1080p
              • "1080p"
                -
              • qhd1440p
              • "1440p"
                -
              • uhd2160p
              • "2160p"
                -
              • custom
              • Custom resolution -
              -

              AppEvent

              string

              -

              Events dispatched by the Add-on SDK. Named export only - not available in constants object.

              -
                -
              • documentIdAvailable
              • Document ID becomes available -
              • documentTitleChange
              • Document title changes -
              • documentLinkAvailable
              • Document link becomes available -
              • documentPublishedLinkAvailable
              • Published document link becomes available -
              -

              AuthorizationStatus

              string

              -

              OAuth authorization status values. Dual access: both named export and constants object.

              -
                -
              • authorized
              • Authorization successful -
              • cancelled
              • Authorization cancelled by user -
              • error
              • Authorization error occurred -
              -

              SupportedMimeTypes

              string

              -

              MIME types for original source assets converted to PDF. Named export only - not available in constants object.

              -
                -
              • docx
              • "docx"
                -
              • gdoc
              • "gdoc"
                -
              -

              PdfReturnUrlType

              string

              -

              Specifies the type of URL returned for PDF rendition export. Named export only - not available in constants object.

              -
                -
              • cdnUrl
              • "cdnUrl"
                -
              • jumpUrl
              • "jumpUrl"
                -
              -

              FieldType

              string

              -

              The type of input field supported in Simple Dialog. Dual access: both named export and constants object.

              -
                -
              • text
              • "text"
                -
              -

              PlatformEnvironment

              string

              -

              Denotes the current environment where the add-on is running. Dual access: both named export and constants object.

              -
                -
              • app
              • "app"
                -
              • web
              • "web"
                -
              -

              DeviceClass

              string

              -

              Denotes the device class/form factor where the add-on is running. Dual access: both named export and constants object.

              -
                -
              • mobile
              • "mobile"
                -
              • tablet
              • "tablet"
                -
              • desktop
              • "desktop"
                -
              -

              PlatformType

              string

              -

              Denotes the specific platform/operating system where the add-on is running. Dual access: both named export and constants object.

              -
                -
              • iOS
              • "ios"
                -
              • iPadOS
              • "ipad"
                -
              • chromeOS
              • "chromeOS"
                -
              • android
              • "android"
                -
              • chromeBrowser
              • "chromeBrowser"
                -
              • firefoxBrowser
              • "firefoxBrowser"
                -
              • edgeBrowser
              • "edgeBrowser"
                -
              • samsungBrowser
              • "samsumgBrowser"
                (Note: Contains typo in SDK) -
              • safariBrowser
              • "safariBrowser"
                -
              • unknown
              • "unknown"
                -
              -
              +## Constants Reference + +The following constants are organized by functional category for easier navigation. Each constant includes its import requirements, available values, and usage context. + +### Table of Contents + +- [Dialog & UI Constants](#dialog--ui-constants) +- [Document Export Constants](#document-export-constants) +- [Platform Detection Constants](#platform-detection-constants) +- [Editor Navigation Constants](#editor-navigation-constants) +- [Event Constants](#event-constants) +- [File & Media Constants](#file--media-constants) +- [OAuth & Authorization Constants](#oauth--authorization-constants) +- [Video & Media Settings Constants](#video--media-settings-constants) + +--- + +## Dialog & UI Constants + +### ButtonType {#buttontype} + + + +**Import**: `import { ButtonType }` or `addOnUISdk.constants.ButtonType` ✅ **Dual Access** + +The type of button pressed in a modal dialog. + +| Value | Description | +|-------|-------------| +| `primary` | Primary button pressed | +| `secondary` | Secondary button pressed | +| `cancel` | Cancel button pressed | +| `close` | Dialog closed via ESC or close(X) button | + +**Example Usage:** + +```javascript +const result = await addOnUISdk.app.showModalDialog({...}); +if (result.buttonType === ButtonType.primary) { + // Handle primary action +} +``` + +### Variant {#variant} + + + +**Import**: `import { Variant }` or `addOnUISdk.constants.Variant` ✅ **Dual Access** + +Types of dialog variants supported for different user interaction scenarios. + +| Value | Description | +|-------|-------------| +| `confirmation` | Ask a user to confirm an action | +| `information` | Share information for user to acknowledge | +| `warning` | Share information that a user needs to consider before proceeding | +| `destructive` | Tell a user that if they proceed with an action, it may impact their data in a negative way | +| `error` | Communicate critical issue that a user needs to resolve before proceeding | +| `input` | Ask a user to provide some inputs | +| `custom` | A dialog that can render complex forms and content | + +**Example Usage:** + +```javascript +await addOnUISdk.app.showModalDialog({ + variant: Variant.confirmation, + title: "Delete Item", + description: "Are you sure?" +}); +``` + +### FieldType {#fieldtype} + + + +**Import**: `import { FieldType }` or `addOnUISdk.constants.FieldType` ✅ **Dual Access** + +The type of input field supported in Simple Dialog. + +| Value | Description | +|-------|-------------| +| `text` | Text input field | + +### DialogResultType {#dialogresulttype} + + + +**Import**: `import { DialogResultType }` or `addOnUISdk.constants.DialogResultType` ✅ **Dual Access** + +The type of modal dialog result returned. + +| Value | Description | +|-------|-------------| +| `alert` | Alert dialog result (simple dialogs all return this) | +| `input` | Input dialog result | +| `custom` | Custom dialog result | + +### ColorPickerPlacement {#colorpickerplacement} + + + +**Import**: `import { ColorPickerPlacement }` or `addOnUISdk.constants.ColorPickerPlacement` ✅ **Dual Access** + +Placement of the color picker popover with respect to the anchor element. + +| Value | Description | +|-------|-------------| +| `top` | Position above the anchor | +| `bottom` | Position below the anchor | +| `left` | Position to the left of the anchor | +| `right` | Position to the right of the anchor | + +--- + +## Document Export Constants + +### Range {#range} + + + +**Import**: `import { Range }` or `addOnUISdk.constants.Range` ✅ **Dual Access** + +Specifies which pages to include in a rendition export. + +| Value | Description | +|-------|-------------| +| `currentPage` | Generate rendition for the current page | +| `entireDocument` | Generate rendition for all pages | +| `specificPages` | Generate rendition for specific pages (requires `pageIds` parameter) | + +**Example Usage:** + +```javascript +await addOnUISdk.app.document.createRenditions({ + range: Range.currentPage, + format: RenditionFormat.png +}); +``` + +### RenditionFormat {#renditionformat} + + + +**Import**: `import { RenditionFormat }` or `addOnUISdk.constants.RenditionFormat` ✅ **Dual Access** + +Required output format of the rendition. + +| Value | MIME Type | Description | +|-------|-----------|-------------| +| `jpg` | `"image/jpeg"` | JPEG image format | +| `png` | `"image/png"` | PNG image format | +| `mp4` | `"video/mp4"` | MP4 video format | +| `pdf` | `"application/pdf"` | PDF document format | +| `pptx` | `"application/vnd.openxmlformats-officedocument.presentationml.presentation"` | PowerPoint presentation format | + +### RenditionIntent {#renditionintent} + + + +**Import**: `import { RenditionIntent }` or `addOnUISdk.constants.RenditionIntent` ✅ **Dual Access** + +The intent to set for creating the rendition, which may affect optimization. + +| Value | Description | +|-------|-------------| +| `preview` | Intent to preview the content | +| `export` | Intent to export/download the content (default) | +| `print` | Intent to export and print the content | + + + +**Note**: For `pdf` format, `print` intent generates a print-optimized PDF. This option is not supported for `mp4` format. + +### RenditionType {#renditiontype} + + + +**Import**: `import { RenditionType }` or `addOnUISdk.constants.RenditionType` ✅ **Dual Access** + +The type of rendition. Currently returns `"page"` for all renditions. + +### BleedUnit {#bleedunit} + + + +**Import**: `import { BleedUnit }` or `addOnUISdk.constants.BleedUnit` ✅ **Dual Access** + +Units for specifying page bleed in print-ready documents. + +| Value | Description | +|-------|-------------| +| `"in"` | Inch units | +| `"mm"` | Millimeter units | + +--- + +## Platform Detection Constants + +### PlatformType {#platformtype} + + + +**Import**: `import { PlatformType }` or `addOnUISdk.constants.PlatformType` ✅ **Dual Access** + +Denotes the specific platform/operating system where the add-on is running. + +| Value | Platform | Description | +|-------|----------|-------------| +| `iOS` | `"ios"` | iOS mobile devices | +| `iPadOS` | `"ipad"` | iPad devices | +| `chromeOS` | `"chromeOS"` | Chrome OS devices | +| `android` | `"android"` | Android devices | +| `chromeBrowser` | `"chromeBrowser"` | Chrome browser | +| `firefoxBrowser` | `"firefoxBrowser"` | Firefox browser | +| `edgeBrowser` | `"edgeBrowser"` | Microsoft Edge browser | +| `samsungBrowser` | `"samsumgBrowser"` | Samsung browser *(Note: Contains typo in SDK)* | +| `safariBrowser` | `"safariBrowser"` | Safari browser | +| `unknown` | `"unknown"` | Unknown platform | + +**Example Usage:** + +```javascript +const platform = await addOnUISdk.app.getCurrentPlatform(); +if (platform.platformType === PlatformType.iOS) { + // iOS-specific handling +} +``` + +### DeviceClass {#deviceclass} + + + +**Import**: `import { DeviceClass }` or `addOnUISdk.constants.DeviceClass` ✅ **Dual Access** + +Denotes the device class/form factor where the add-on is running. + +| Value | Description | +|-------|-------------| +| `mobile` | Mobile phone devices | +| `tablet` | Tablet devices | +| `desktop` | Desktop/laptop devices | + +### PlatformEnvironment {#platformenvironment} + + + +**Import**: `import { PlatformEnvironment }` or `addOnUISdk.constants.PlatformEnvironment` ✅ **Dual Access** + +Denotes the current environment where the add-on is running. + +| Value | Description | +|-------|-------------| +| `app` | Native application environment | +| `web` | Web browser environment | + +--- + +## Editor Navigation Constants + +### EditorPanel {#editorpanel} + + + +**Import**: `import { EditorPanel }` or `addOnUISdk.constants.EditorPanel` ✅ **Dual Access** + +The Adobe Express Editor panel to be opened programmatically. + +| Value | Description | +|-------|-------------| +| `search` | Editor Search panel | +| `yourStuff` | Editor Your stuff panel | +| `templates` | Editor Templates panel | +| `media` | Editor Media panel | +| `text` | Editor Text panel | +| `elements` | Editor Elements panel | +| `grids` | Editor Grids panel | +| `brands` | Editor Brands panel | +| `addOns` | Editor Add-ons panel | + +**Example Usage:** + +```javascript +addOnUISdk.app.ui.openEditorPanel(EditorPanel.media); +``` + +### MediaTabs {#mediatabs} + + + +**Import**: `import { MediaTabs }` or `addOnUISdk.constants.MediaTabs` ✅ **Dual Access** + +Tabs available in the Editor's Media panel. + +| Value | Description | +|-------|-------------| +| `video` | Video tab | +| `audio` | Audio tab | +| `photos` | Photos tab | + +### ElementsTabs {#elementstabs} + + + +**Import**: `import { ElementsTabs }` or `addOnUISdk.constants.ElementsTabs` ✅ **Dual Access** + +Tabs available in the Editor's Elements panel. + +| Value | Description | +|-------|-------------| +| `designAssets` | Design assets tab | +| `backgrounds` | Backgrounds tab | +| `shapes` | Shapes tab | +| `stockIcons` | Icons tab | +| `charts` | Charts tab | + +### PanelActionType {#panelactiontype} + + + +**Import**: `import { PanelActionType }` or `addOnUISdk.constants.PanelActionType` ✅ **Dual Access** + +Types of actions that can be performed on Editor panels. + +| Value | Description | +|-------|-------------| +| `search` | Action type to perform search within the Editor panel | +| `navigate` | Action type to perform navigation within the Editor panel | + +--- + +## Event Constants + + + +**Critical**: Event constants are **named export only** and cannot be accessed through `addOnUISdk.constants.*` + +### AppEvent {#appevent} + + + +**Import**: `import { AppEvent }` ❌ **Named Export Only** + +Events dispatched by the Add-on SDK for application-level changes. + +| Value | Description | +|-------|-------------| +| `documentIdAvailable` | Document ID becomes available | +| `documentTitleChange` | Document title changes | +| `documentLinkAvailable` | Document link becomes available | +| `documentPublishedLinkAvailable` | Published document link becomes available | +| `themechange` | Application theme changes | + +**Example Usage:** + +```javascript +import addOnUISdk, { AppEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +addOnUISdk.app.on(AppEvent.themechange, (event) => { + updateUITheme(event.theme); +}); +``` + +### ColorPickerEvent {#colorpickerevent} + + + +**Import**: `import { ColorPickerEvent }` ❌ **Named Export Only** + +Custom events dispatched by the Color Picker component. + +| Value | Event Name | Description | +|-------|------------|-------------| +| `colorChange` | `"colorpicker-color-change"` | Color selection changed | +| `close` | `"colorpicker-close"` | Color picker closed | + +**Example Usage:** + +```javascript +import addOnUISdk, { ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +colorPickerElement.addEventListener(ColorPickerEvent.colorChange, (event) => { + applyColor(event.color); +}); +``` + +--- + +## File & Media Constants + +### SupportedMimeTypes {#supportedmimetypes} + + + +**Import**: `import { SupportedMimeTypes }` ❌ **Named Export Only** + +MIME types for original source assets that can be converted to PDF. + +| Value | Description | +|-------|-------------| +| `docx` | Microsoft Word document | +| `gdoc` | Google Docs document | + +### PdfReturnUrlType {#pdfreturnurltype} + + + +**Import**: `import { PdfReturnUrlType }` ❌ **Named Export Only** + +Specifies the type of URL returned for PDF rendition export. + +| Value | Description | +|-------|-------------| +| `cdnUrl` | CDN URL for the PDF | +| `jumpUrl` | Jump URL for the PDF | + +### FileSizeLimitUnit {#filesizelimitunit} + + + +**Import**: `import { FileSizeLimitUnit }` or `addOnUISdk.constants.FileSizeLimitUnit` ✅ **Dual Access** + +Unit of the file size limit. + +| Value | Description | +|-------|-------------| +| `KB` | Kilobytes | +| `MB` | Megabytes | + +### LinkOptions {#linkoptions} + + + +**Import**: `import { LinkOptions }` or `addOnUISdk.constants.LinkOptions` ✅ **Dual Access** + +The type of link to generate for documents. + +| Value | Description | +|-------|-------------| +| `document` | Link to the current document | +| `published` | Link to the published document | + +--- + +## OAuth & Authorization Constants + +### AuthorizationStatus {#authorizationstatus} + + + +**Import**: `import { AuthorizationStatus }` or `addOnUISdk.constants.AuthorizationStatus` ✅ **Dual Access** + +OAuth authorization status values returned from authorization flows. + +| Value | Description | +|-------|-------------| +| `authorized` | Authorization successful | +| `cancelled` | Authorization cancelled by user | +| `error` | Authorization error occurred | + +**Example Usage:** + +```javascript +const result = await addOnUISdk.app.oauth.authorize({...}); +if (result.status === AuthorizationStatus.authorized) { + // Handle successful authorization +} +``` + +--- + +## Video & Media Settings Constants + +### VideoResolution {#videoresolution} + + + +**Import**: `import { VideoResolution }` or `addOnUISdk.constants.VideoResolution` ✅ **Dual Access** + +Video resolution options for MP4 renditions. + +| Value | Resolution | Description | +|-------|------------|-------------| +| `sd480p` | `"480p"` | Standard definition | +| `hd720p` | `"720p"` | High definition | +| `fhd1080p` | `"1080p"` | Full high definition | +| `qhd1440p` | `"1440p"` | Quad high definition | +| `uhd2160p` | `"2160p"` | Ultra high definition (4K) | +| `custom` | Custom | Custom resolution | + +### FrameRate {#framerate} + + + +**Import**: `import { FrameRate }` or `addOnUISdk.constants.FrameRate` ✅ **Dual Access** + +Frame rate options in frames per second for video exports. + +| Value | FPS | Description | +|-------|-----|-------------| +| `fps23_976` | `23.976` | Cinema standard | +| `fps24` | `24` | Film standard | +| `fps25` | `25` | PAL standard | +| `fps29_97` | `29.97` | NTSC standard | +| `fps30` | `30` | Common web standard | +| `fps60` | `60` | High frame rate | + +### BitRate {#bitrate} + + + +**Import**: `import { BitRate }` or `addOnUISdk.constants.BitRate` ✅ **Dual Access** + +Bit rate options in bits per second for video quality control. + +| Value | Bitrate | Description | +|-------|---------|-------------| +| `mbps4` | `4000000` | 4 Mbps | +| `mbps8` | `8000000` | 8 Mbps | +| `mbps10` | `10000000` | 10 Mbps | +| `mbps12` | `12000000` | 12 Mbps | +| `mbps15` | `15000000` | 15 Mbps | +| `mbps25` | `25000000` | 25 Mbps | +| `mbps50` | `50000000` | 50 Mbps | + +--- + +## Runtime & System Constants + +### RuntimeType {#runtimetype} + + + +**Import**: `import { RuntimeType }` or `addOnUISdk.constants.RuntimeType` ✅ **Dual Access** + +Runtime type of the entrypoint creating this backend object. + +| Value | Description | +|-------|-------------| +| `panel` | Add-on's iframe runtime (code running in `index.html`) | +| `script` | Add-on's document sandbox code (code running in `code.js`) | +| `dialog` | Currently open dialog code | + +### EntrypointType {#entrypointtype} + + + +**Import**: `import { EntrypointType }` ❌ **Named Export Only** + +Types of entry points for add-on execution contexts. + +### MediaType {#mediatype} + + + +**Import**: `import { MediaType }` or `addOnUISdk.constants.MediaType` ✅ **Dual Access** + +Types of media content supported by the platform. From 7f75ec77013b100b1f97c7182713160d8c01da86 Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Mon, 6 Oct 2025 11:58:10 -0400 Subject: [PATCH 06/42] Fixed jsx issue --- src/pages/references/addonsdk/addonsdk-constants.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pages/references/addonsdk/addonsdk-constants.md b/src/pages/references/addonsdk/addonsdk-constants.md index 49c2ec9c9..2dd92841e 100644 --- a/src/pages/references/addonsdk/addonsdk-constants.md +++ b/src/pages/references/addonsdk/addonsdk-constants.md @@ -200,7 +200,7 @@ This section provides the complete technical specification for all Add-on UI SDK ## Developer Tips - + **Quick Start Tips:** @@ -766,3 +766,9 @@ Types of entry points for add-on execution contexts. **Import**: `import { MediaType }` or `addOnUISdk.constants.MediaType` ✅ **Dual Access** Types of media content supported by the platform. + +| Value | Description | +|-------|-------------| +| `image` | Image media content | +| `video` | Video media content | +| `audio` | Audio media content | From cb7bda517fec5857c3f989ab0a1923863e6470eb Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Mon, 6 Oct 2025 12:24:49 -0400 Subject: [PATCH 07/42] Closing alert --- src/pages/references/addonsdk/addonsdk-constants.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/references/addonsdk/addonsdk-constants.md b/src/pages/references/addonsdk/addonsdk-constants.md index 2dd92841e..2f4f8ba91 100644 --- a/src/pages/references/addonsdk/addonsdk-constants.md +++ b/src/pages/references/addonsdk/addonsdk-constants.md @@ -200,7 +200,7 @@ This section provides the complete technical specification for all Add-on UI SDK ## Developer Tips - + **Quick Start Tips:** @@ -209,6 +209,8 @@ This section provides the complete technical specification for all Add-on UI SDK - **Never guess** - check if constants are import-required before using - **Use TypeScript** for compile-time validation and better IDE support + + ## Constants Reference The following constants are organized by functional category for easier navigation. Each constant includes its import requirements, available values, and usage context. From 27de265951e9b13c44b1a650c617e13df907b1eb Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Mon, 6 Oct 2025 14:03:16 -0400 Subject: [PATCH 08/42] Misc fixes --- src/pages/guides/learn/fundamentals/terminology.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/pages/guides/learn/fundamentals/terminology.md b/src/pages/guides/learn/fundamentals/terminology.md index 7a6f8c841..9751707f2 100644 --- a/src/pages/guides/learn/fundamentals/terminology.md +++ b/src/pages/guides/learn/fundamentals/terminology.md @@ -156,10 +156,10 @@ import addOnSandboxSdk from "add-on-sdk-document-sandbox" The APIs that allow you to interact with and modify Adobe Express documents. -**Package:** +**Import Statement:** ```javascript -import { Editor, Context } from "@express-document-sdk" +import { editor } from "express-document-sdk" ``` **Also Known As:** Document API, Express Document API @@ -190,8 +190,11 @@ import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; // Document Sandbox SDK (for document sandbox code) import addOnSandboxSdk from "add-on-sdk-document-sandbox"; -// Document APIs (for TypeScript types) -import { Editor, Context } from "@express-document-sdk"; +// Document APIs (for document manipulation) +import { editor } from "express-document-sdk"; + +// Additional common imports in document sandbox +import { editor, colorUtils, constants } from "express-document-sdk"; ``` ### Runtime References From aee1d359d1628d756bdd54189845628d0b7dd666 Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Mon, 6 Oct 2025 16:20:12 -0400 Subject: [PATCH 09/42] Updates for accuracy --- .../document-sandbox-constants.md | 117 ++- .../guides/learn/fundamentals/terminology.md | 3 +- .../learn/fundamentals/ui-sdk-constants.md | 3 +- .../references/addonsdk/addonsdk-constants.md | 950 +++++++----------- 4 files changed, 447 insertions(+), 626 deletions(-) diff --git a/src/pages/guides/learn/fundamentals/document-sandbox-constants.md b/src/pages/guides/learn/fundamentals/document-sandbox-constants.md index e3024a7e5..7b7b90161 100644 --- a/src/pages/guides/learn/fundamentals/document-sandbox-constants.md +++ b/src/pages/guides/learn/fundamentals/document-sandbox-constants.md @@ -49,13 +49,15 @@ For complete technical specifications of all document constants, see the [Docume ## Quick Start -Document constants are available directly in the document sandbox environment without imports: +Document constants are available through the constants export in the document sandbox environment: ```javascript -// Document constants are globally available in sandbox -const fillType = FillType.color; -const blendMode = BlendMode.normal; -const textAlignment = TextAlignment.center; +import { constants } from "express-document-sdk"; + +// Access constants through the constants object +const fillType = constants.FillType.color; +const blendMode = constants.BlendMode.normal; +const textAlignment = constants.TextAlignment.center; ``` @@ -67,31 +69,31 @@ const textAlignment = TextAlignment.center; ### Fill and Stroke Properties ```javascript +import { editor, constants } from "express-document-sdk"; + // Creating solid color fills const rectangle = editor.createRectangle(); rectangle.fill = { - type: FillType.color, + type: constants.FillType.color, color: { red: 1, green: 0, blue: 0, alpha: 1 } }; // Adding strokes rectangle.stroke = { - type: StrokeType.solid, + type: constants.StrokeType.color, color: { red: 0, green: 0, blue: 1, alpha: 1 }, width: 2, - position: StrokePosition.inside + position: constants.StrokePosition.inside }; ``` **Available Fill Types:** -- `FillType.color` - Solid color fills -- `FillType.none` - No fill +- `FillType.color` - Solid color fills (only available type) **Available Stroke Types:** -- `StrokeType.solid` - Solid color stroke -- `StrokeType.none` - No stroke +- `StrokeType.color` - Solid color stroke (only available type) **Available Stroke Positions:** @@ -102,15 +104,17 @@ rectangle.stroke = { ### Text Alignment and Styling ```javascript +import { editor, constants } from "express-document-sdk"; + // Creating and styling text const textNode = editor.createText(); textNode.text = "Hello World"; // Set text alignment -textNode.textAlignment = TextAlignment.center; +textNode.textAlignment = constants.TextAlignment.center; // Set text script style -textNode.textScriptStyle = TextScriptStyle.normal; +textNode.textScriptStyle = constants.TextScriptStyle.none; ``` **Available Text Alignments:** @@ -118,20 +122,22 @@ textNode.textScriptStyle = TextScriptStyle.normal; - `TextAlignment.left` - Left-aligned text - `TextAlignment.center` - Center-aligned text - `TextAlignment.right` - Right-aligned text -- `TextAlignment.justify` - Justified text +- `TextAlignment.justifyLeft` - Left-justified text **Available Text Script Styles:** -- `TextScriptStyle.normal` - Normal text +- `TextScriptStyle.none` - Normal text (standard baseline) - `TextScriptStyle.superscript` - Superscript text - `TextScriptStyle.subscript` - Subscript text ### Blend Modes ```javascript +import { editor, constants } from "express-document-sdk"; + // Apply blend modes to visual elements const shape = editor.createEllipse(); -shape.blendMode = BlendMode.multiply; +shape.blendMode = constants.BlendMode.multiply; ``` **Common Blend Modes:** @@ -146,20 +152,22 @@ shape.blendMode = BlendMode.multiply; ### Scene Node Types ```javascript +import { editor, constants } from "express-document-sdk"; + // Check node types when traversing the document editor.context.selection.forEach(node => { switch (node.type) { - case SceneNodeType.rectangle: + case constants.SceneNodeType.rectangle: console.log("Selected rectangle"); break; - case SceneNodeType.ellipse: + case constants.SceneNodeType.ellipse: console.log("Selected ellipse"); break; - case SceneNodeType.text: - console.log("Selected text"); + case constants.SceneNodeType.imageRectangle: + console.log("Selected image"); break; - case SceneNodeType.mediaRectangle: - console.log("Selected image/video"); + case constants.SceneNodeType.unknownMediaRectangle: + console.log("Selected media"); break; } }); @@ -169,8 +177,9 @@ editor.context.selection.forEach(node => { - `SceneNodeType.rectangle` - Rectangle shapes - `SceneNodeType.ellipse` - Ellipse/circle shapes -- `SceneNodeType.text` - Text elements -- `SceneNodeType.mediaRectangle` - Images and videos +- `SceneNodeType.text` - Text elements (not available in current types) +- `SceneNodeType.imageRectangle` - Image elements +- `SceneNodeType.unknownMediaRectangle` - Unknown media elements - `SceneNodeType.line` - Line elements - `SceneNodeType.path` - Custom path shapes - `SceneNodeType.group` - Grouped elements @@ -180,13 +189,13 @@ editor.context.selection.forEach(node => { ### Document Sandbox Environment ```javascript -// In code.js - constants are globally available -const editor = addOnSandboxSdk.editor; +// In code.js - import constants from express-document-sdk +import { editor, constants } from "express-document-sdk"; -// Use constants directly (no imports needed) +// Use constants through the constants object const newRect = editor.createRectangle(); newRect.fill = { - type: FillType.color, + type: constants.FillType.color, color: { red: 0.5, green: 0.5, blue: 0.5, alpha: 1 } }; ``` @@ -195,13 +204,16 @@ newRect.fill = { ```javascript // In code.js - expose constants to UI if needed +import { constants } from "express-document-sdk"; +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; + addOnSandboxSdk.instance.runtime.exposeApi({ getAvailableBlendModes() { return { - normal: BlendMode.normal, - multiply: BlendMode.multiply, - screen: BlendMode.screen, - overlay: BlendMode.overlay + normal: constants.BlendMode.normal, + multiply: constants.BlendMode.multiply, + screen: constants.BlendMode.screen, + overlay: constants.BlendMode.overlay }; } }); @@ -212,25 +224,27 @@ addOnSandboxSdk.instance.runtime.exposeApi({ ### Creating Styled Shapes ```javascript +import { editor, constants } from "express-document-sdk"; + function createStyledRectangle(color, strokeColor) { const rect = editor.createRectangle(); // Set fill rect.fill = { - type: FillType.color, + type: constants.FillType.color, color: color }; // Set stroke rect.stroke = { - type: StrokeType.solid, + type: constants.StrokeType.color, color: strokeColor, width: 2, - position: StrokePosition.inside + position: constants.StrokePosition.inside }; // Set blend mode - rect.blendMode = BlendMode.normal; + rect.blendMode = constants.BlendMode.normal; return rect; } @@ -239,7 +253,9 @@ function createStyledRectangle(color, strokeColor) { ### Text Formatting ```javascript -function createFormattedText(content, alignment = TextAlignment.left) { +import { editor, constants } from "express-document-sdk"; + +function createFormattedText(content, alignment = constants.TextAlignment.left) { const textNode = editor.createText(); textNode.text = content; textNode.textAlignment = alignment; @@ -248,7 +264,7 @@ function createFormattedText(content, alignment = TextAlignment.left) { const characterStyles = { fontSize: 24, fontFamily: "Arial", - textScriptStyle: TextScriptStyle.normal + textScriptStyle: constants.TextScriptStyle.none }; textNode.setRangeCharacterStyles(0, content.length, characterStyles); @@ -260,19 +276,21 @@ function createFormattedText(content, alignment = TextAlignment.left) { ### Node Type Checking ```javascript +import { editor, constants } from "express-document-sdk"; + function processSelectedNodes() { const selection = editor.context.selection; selection.forEach(node => { // Type-safe node processing - if (node.type === SceneNodeType.rectangle || node.type === SceneNodeType.ellipse) { + if (node.type === constants.SceneNodeType.rectangle || node.type === constants.SceneNodeType.ellipse) { // Handle shapes - if (node.fill?.type === FillType.color) { + if (node.fill?.type === constants.FillType.color) { console.log("Shape has color fill"); } - } else if (node.type === SceneNodeType.text) { - // Handle text - console.log(`Text alignment: ${node.textAlignment}`); + } else if (node.type === constants.SceneNodeType.imageRectangle) { + // Handle images + console.log("Processing image node"); } }); } @@ -290,21 +308,24 @@ const fillType = FillType.color; // Error: FillType is not defined // ✅ Correct - Use in document sandbox only // In code.js -const fillType = FillType.color; // Works correctly +import { constants } from "express-document-sdk"; +const fillType = constants.FillType.color; // Works correctly ``` ### Missing Type Checks ```javascript +import { constants } from "express-document-sdk"; + // ❌ Risky - assuming node type function changeColor(node, color) { - node.fill = { type: FillType.color, color }; // May fail on text nodes + node.fill = { type: constants.FillType.color, color }; // May fail on non-fillable nodes } // ✅ Safe - check node type first function changeColor(node, color) { - if (node.type === SceneNodeType.rectangle || node.type === SceneNodeType.ellipse) { - node.fill = { type: FillType.color, color }; + if (node.type === constants.SceneNodeType.rectangle || node.type === constants.SceneNodeType.ellipse) { + node.fill = { type: constants.FillType.color, color }; } } ``` diff --git a/src/pages/guides/learn/fundamentals/terminology.md b/src/pages/guides/learn/fundamentals/terminology.md index 9751707f2..e23afe90d 100644 --- a/src/pages/guides/learn/fundamentals/terminology.md +++ b/src/pages/guides/learn/fundamentals/terminology.md @@ -654,4 +654,5 @@ A: No, they're the same. **"Add-on UI SDK"** is the full, preferred term for cla - [Document Sandbox Overview](../../../references/document-sandbox/index.md) - [Communication APIs](../../../references/document-sandbox/communication/index.md) - [Platform Concepts](../platform_concepts/context.md) -- [Constants Usage Guide](./constants.md) +- [Add-on UI SDK Constants Usage Guide](./ui-sdk-constants.md) +- [Document Sandbox Constants Usage Guide](./document-sandbox-constants.md) diff --git a/src/pages/guides/learn/fundamentals/ui-sdk-constants.md b/src/pages/guides/learn/fundamentals/ui-sdk-constants.md index 6ae279440..cd9440764 100644 --- a/src/pages/guides/learn/fundamentals/ui-sdk-constants.md +++ b/src/pages/guides/learn/fundamentals/ui-sdk-constants.md @@ -148,8 +148,7 @@ import addOnUISdk, { AppEvent, // ❌ NOT in constants object ColorPickerEvent, // ❌ NOT in constants object SupportedMimeTypes, // ❌ NOT in constants object - EntrypointType, // ❌ NOT in constants object - PdfReturnUrlType // ❌ NOT in constants object + EntrypointType // ❌ NOT in constants object } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; ``` diff --git a/src/pages/references/addonsdk/addonsdk-constants.md b/src/pages/references/addonsdk/addonsdk-constants.md index 2f4f8ba91..6b90309f8 100644 --- a/src/pages/references/addonsdk/addonsdk-constants.md +++ b/src/pages/references/addonsdk/addonsdk-constants.md @@ -17,7 +17,7 @@ Adobe Express Add-on SDK constants are available through different import patter -**Important:** Attempting to access import-required constants through `addOnUISdk.constants.*` will return `undefined` and cause runtime errors. Always check the patterns below before using any constant. +**Critical:** Attempting to access import-required constants through `addOnUISdk.constants.*` will return `undefined` and cause runtime errors. Always check the patterns below before using any constant. ### Named Exports Only (Import Required) @@ -28,8 +28,7 @@ import addOnUISdk, { AppEvent, // Import required ColorPickerEvent, // Import required SupportedMimeTypes, // Import required - EntrypointType, // Import required - PdfReturnUrlType // Import required + EntrypointType // Import required } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; // ✅ Correct usage @@ -79,7 +78,6 @@ const confirmDialog = addOnUISdk.constants.Variant.confirmation; - `PlatformEnvironment` / `addOnUISdk.constants.PlatformEnvironment` - `DeviceClass` / `addOnUISdk.constants.DeviceClass` - `PlatformType` / `addOnUISdk.constants.PlatformType` -- `MediaType` / `addOnUISdk.constants.MediaType` - `VideoResolution` / `addOnUISdk.constants.VideoResolution` - `FrameRate` / `addOnUISdk.constants.FrameRate` - `BitRate` / `addOnUISdk.constants.BitRate` @@ -119,7 +117,6 @@ const confirmDialog = addOnUISdk.constants.Variant.confirmation; | `ColorPickerEvent` | ✅ | ❌ | **Yes** | | `SupportedMimeTypes` | ✅ | ❌ | **Yes** | | `EntrypointType` | ✅ | ❌ | **Yes** | -| `PdfReturnUrlType` | ✅ | ❌ | **Yes** | | `Range` | ✅ | ✅ | Optional | | `RenditionFormat` | ✅ | ✅ | Optional | | `Variant` | ✅ | ✅ | Optional | @@ -139,7 +136,6 @@ const confirmDialog = addOnUISdk.constants.Variant.confirmation; | `ElementsTabs` | ✅ | ✅ | Optional | | `PanelActionType` | ✅ | ✅ | Optional | | `ColorPickerPlacement` | ✅ | ✅ | Optional | -| `MediaType` | ✅ | ✅ | Optional | | `VideoResolution` | ✅ | ✅ | Optional | | `FrameRate` | ✅ | ✅ | Optional | | `BitRate` | ✅ | ✅ | Optional | @@ -160,12 +156,12 @@ Use these copy-paste ready import statements for common scenarios: // Import everything (use this if you're unsure) import addOnUISdk, { // Import-required constants - AppEvent, ColorPickerEvent, SupportedMimeTypes, EntrypointType, PdfReturnUrlType, + AppEvent, ColorPickerEvent, SupportedMimeTypes, EntrypointType, // Dual-access constants (most common) Range, RenditionFormat, RenditionIntent, Variant, ButtonType, FieldType, PlatformType, DeviceClass, PlatformEnvironment, EditorPanel, MediaTabs, ElementsTabs, AuthorizationStatus, DialogResultType, RuntimeType, BleedUnit, PanelActionType, - ColorPickerPlacement, MediaType, VideoResolution, FrameRate, BitRate, FileSizeLimitUnit, LinkOptions + ColorPickerPlacement, VideoResolution, FrameRate, BitRate, FileSizeLimitUnit, LinkOptions } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; ``` @@ -188,7 +184,7 @@ import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "http import addOnUISdk, { EditorPanel, MediaTabs, ElementsTabs, PanelActionType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; // File Types & MIME (Import Required!) -import addOnUISdk, { SupportedMimeTypes, PdfReturnUrlType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { SupportedMimeTypes } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; // OAuth & Authorization import addOnUISdk, { AuthorizationStatus } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; @@ -200,7 +196,7 @@ This section provides the complete technical specification for all Add-on UI SDK ## Developer Tips - + **Quick Start Tips:** @@ -209,568 +205,372 @@ This section provides the complete technical specification for all Add-on UI SDK - **Never guess** - check if constants are import-required before using - **Use TypeScript** for compile-time validation and better IDE support - - -## Constants Reference - -The following constants are organized by functional category for easier navigation. Each constant includes its import requirements, available values, and usage context. - -### Table of Contents - -- [Dialog & UI Constants](#dialog--ui-constants) -- [Document Export Constants](#document-export-constants) -- [Platform Detection Constants](#platform-detection-constants) -- [Editor Navigation Constants](#editor-navigation-constants) -- [Event Constants](#event-constants) -- [File & Media Constants](#file--media-constants) -- [OAuth & Authorization Constants](#oauth--authorization-constants) -- [Video & Media Settings Constants](#video--media-settings-constants) - ---- - -## Dialog & UI Constants - -### ButtonType {#buttontype} - - - -**Import**: `import { ButtonType }` or `addOnUISdk.constants.ButtonType` ✅ **Dual Access** - -The type of button pressed in a modal dialog. - -| Value | Description | -|-------|-------------| -| `primary` | Primary button pressed | -| `secondary` | Secondary button pressed | -| `cancel` | Cancel button pressed | -| `close` | Dialog closed via ESC or close(X) button | - -**Example Usage:** - -```javascript -const result = await addOnUISdk.app.showModalDialog({...}); -if (result.buttonType === ButtonType.primary) { - // Handle primary action -} -``` - -### Variant {#variant} - - - -**Import**: `import { Variant }` or `addOnUISdk.constants.Variant` ✅ **Dual Access** - -Types of dialog variants supported for different user interaction scenarios. - -| Value | Description | -|-------|-------------| -| `confirmation` | Ask a user to confirm an action | -| `information` | Share information for user to acknowledge | -| `warning` | Share information that a user needs to consider before proceeding | -| `destructive` | Tell a user that if they proceed with an action, it may impact their data in a negative way | -| `error` | Communicate critical issue that a user needs to resolve before proceeding | -| `input` | Ask a user to provide some inputs | -| `custom` | A dialog that can render complex forms and content | - -**Example Usage:** - -```javascript -await addOnUISdk.app.showModalDialog({ - variant: Variant.confirmation, - title: "Delete Item", - description: "Are you sure?" -}); -``` - -### FieldType {#fieldtype} - - - -**Import**: `import { FieldType }` or `addOnUISdk.constants.FieldType` ✅ **Dual Access** - -The type of input field supported in Simple Dialog. - -| Value | Description | -|-------|-------------| -| `text` | Text input field | - -### DialogResultType {#dialogresulttype} - - - -**Import**: `import { DialogResultType }` or `addOnUISdk.constants.DialogResultType` ✅ **Dual Access** - -The type of modal dialog result returned. - -| Value | Description | -|-------|-------------| -| `alert` | Alert dialog result (simple dialogs all return this) | -| `input` | Input dialog result | -| `custom` | Custom dialog result | - -### ColorPickerPlacement {#colorpickerplacement} - - - -**Import**: `import { ColorPickerPlacement }` or `addOnUISdk.constants.ColorPickerPlacement` ✅ **Dual Access** - -Placement of the color picker popover with respect to the anchor element. - -| Value | Description | -|-------|-------------| -| `top` | Position above the anchor | -| `bottom` | Position below the anchor | -| `left` | Position to the left of the anchor | -| `right` | Position to the right of the anchor | - ---- - -## Document Export Constants - -### Range {#range} - - - -**Import**: `import { Range }` or `addOnUISdk.constants.Range` ✅ **Dual Access** - -Specifies which pages to include in a rendition export. - -| Value | Description | -|-------|-------------| -| `currentPage` | Generate rendition for the current page | -| `entireDocument` | Generate rendition for all pages | -| `specificPages` | Generate rendition for specific pages (requires `pageIds` parameter) | - -**Example Usage:** - -```javascript -await addOnUISdk.app.document.createRenditions({ - range: Range.currentPage, - format: RenditionFormat.png -}); -``` - -### RenditionFormat {#renditionformat} - - - -**Import**: `import { RenditionFormat }` or `addOnUISdk.constants.RenditionFormat` ✅ **Dual Access** - -Required output format of the rendition. - -| Value | MIME Type | Description | -|-------|-----------|-------------| -| `jpg` | `"image/jpeg"` | JPEG image format | -| `png` | `"image/png"` | PNG image format | -| `mp4` | `"video/mp4"` | MP4 video format | -| `pdf` | `"application/pdf"` | PDF document format | -| `pptx` | `"application/vnd.openxmlformats-officedocument.presentationml.presentation"` | PowerPoint presentation format | - -### RenditionIntent {#renditionintent} - - - -**Import**: `import { RenditionIntent }` or `addOnUISdk.constants.RenditionIntent` ✅ **Dual Access** - -The intent to set for creating the rendition, which may affect optimization. - -| Value | Description | -|-------|-------------| -| `preview` | Intent to preview the content | -| `export` | Intent to export/download the content (default) | -| `print` | Intent to export and print the content | - - - -**Note**: For `pdf` format, `print` intent generates a print-optimized PDF. This option is not supported for `mp4` format. - -### RenditionType {#renditiontype} - - - -**Import**: `import { RenditionType }` or `addOnUISdk.constants.RenditionType` ✅ **Dual Access** - -The type of rendition. Currently returns `"page"` for all renditions. - -### BleedUnit {#bleedunit} - - - -**Import**: `import { BleedUnit }` or `addOnUISdk.constants.BleedUnit` ✅ **Dual Access** - -Units for specifying page bleed in print-ready documents. - -| Value | Description | -|-------|-------------| -| `"in"` | Inch units | -| `"mm"` | Millimeter units | - ---- - -## Platform Detection Constants - -### PlatformType {#platformtype} - - - -**Import**: `import { PlatformType }` or `addOnUISdk.constants.PlatformType` ✅ **Dual Access** - -Denotes the specific platform/operating system where the add-on is running. - -| Value | Platform | Description | -|-------|----------|-------------| -| `iOS` | `"ios"` | iOS mobile devices | -| `iPadOS` | `"ipad"` | iPad devices | -| `chromeOS` | `"chromeOS"` | Chrome OS devices | -| `android` | `"android"` | Android devices | -| `chromeBrowser` | `"chromeBrowser"` | Chrome browser | -| `firefoxBrowser` | `"firefoxBrowser"` | Firefox browser | -| `edgeBrowser` | `"edgeBrowser"` | Microsoft Edge browser | -| `samsungBrowser` | `"samsumgBrowser"` | Samsung browser *(Note: Contains typo in SDK)* | -| `safariBrowser` | `"safariBrowser"` | Safari browser | -| `unknown` | `"unknown"` | Unknown platform | - -**Example Usage:** - -```javascript -const platform = await addOnUISdk.app.getCurrentPlatform(); -if (platform.platformType === PlatformType.iOS) { - // iOS-specific handling -} -``` - -### DeviceClass {#deviceclass} - - - -**Import**: `import { DeviceClass }` or `addOnUISdk.constants.DeviceClass` ✅ **Dual Access** - -Denotes the device class/form factor where the add-on is running. - -| Value | Description | -|-------|-------------| -| `mobile` | Mobile phone devices | -| `tablet` | Tablet devices | -| `desktop` | Desktop/laptop devices | - -### PlatformEnvironment {#platformenvironment} - - - -**Import**: `import { PlatformEnvironment }` or `addOnUISdk.constants.PlatformEnvironment` ✅ **Dual Access** - -Denotes the current environment where the add-on is running. - -| Value | Description | -|-------|-------------| -| `app` | Native application environment | -| `web` | Web browser environment | - ---- - -## Editor Navigation Constants - -### EditorPanel {#editorpanel} - - - -**Import**: `import { EditorPanel }` or `addOnUISdk.constants.EditorPanel` ✅ **Dual Access** - -The Adobe Express Editor panel to be opened programmatically. - -| Value | Description | -|-------|-------------| -| `search` | Editor Search panel | -| `yourStuff` | Editor Your stuff panel | -| `templates` | Editor Templates panel | -| `media` | Editor Media panel | -| `text` | Editor Text panel | -| `elements` | Editor Elements panel | -| `grids` | Editor Grids panel | -| `brands` | Editor Brands panel | -| `addOns` | Editor Add-ons panel | - -**Example Usage:** - -```javascript -addOnUISdk.app.ui.openEditorPanel(EditorPanel.media); -``` - -### MediaTabs {#mediatabs} - - - -**Import**: `import { MediaTabs }` or `addOnUISdk.constants.MediaTabs` ✅ **Dual Access** - -Tabs available in the Editor's Media panel. - -| Value | Description | -|-------|-------------| -| `video` | Video tab | -| `audio` | Audio tab | -| `photos` | Photos tab | - -### ElementsTabs {#elementstabs} - - - -**Import**: `import { ElementsTabs }` or `addOnUISdk.constants.ElementsTabs` ✅ **Dual Access** - -Tabs available in the Editor's Elements panel. - -| Value | Description | -|-------|-------------| -| `designAssets` | Design assets tab | -| `backgrounds` | Backgrounds tab | -| `shapes` | Shapes tab | -| `stockIcons` | Icons tab | -| `charts` | Charts tab | - -### PanelActionType {#panelactiontype} - - - -**Import**: `import { PanelActionType }` or `addOnUISdk.constants.PanelActionType` ✅ **Dual Access** - -Types of actions that can be performed on Editor panels. - -| Value | Description | -|-------|-------------| -| `search` | Action type to perform search within the Editor panel | -| `navigate` | Action type to perform navigation within the Editor panel | - ---- - -## Event Constants - - - -**Critical**: Event constants are **named export only** and cannot be accessed through `addOnUISdk.constants.*` - -### AppEvent {#appevent} - - - -**Import**: `import { AppEvent }` ❌ **Named Export Only** - -Events dispatched by the Add-on SDK for application-level changes. - -| Value | Description | -|-------|-------------| -| `documentIdAvailable` | Document ID becomes available | -| `documentTitleChange` | Document title changes | -| `documentLinkAvailable` | Document link becomes available | -| `documentPublishedLinkAvailable` | Published document link becomes available | -| `themechange` | Application theme changes | - -**Example Usage:** - -```javascript -import addOnUISdk, { AppEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -addOnUISdk.app.on(AppEvent.themechange, (event) => { - updateUITheme(event.theme); -}); -``` - -### ColorPickerEvent {#colorpickerevent} - - - -**Import**: `import { ColorPickerEvent }` ❌ **Named Export Only** - -Custom events dispatched by the Color Picker component. - -| Value | Event Name | Description | -|-------|------------|-------------| -| `colorChange` | `"colorpicker-color-change"` | Color selection changed | -| `close` | `"colorpicker-close"` | Color picker closed | - -**Example Usage:** - -```javascript -import addOnUISdk, { ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -colorPickerElement.addEventListener(ColorPickerEvent.colorChange, (event) => { - applyColor(event.color); -}); -``` - ---- - -## File & Media Constants - -### SupportedMimeTypes {#supportedmimetypes} - - - -**Import**: `import { SupportedMimeTypes }` ❌ **Named Export Only** - -MIME types for original source assets that can be converted to PDF. - -| Value | Description | -|-------|-------------| -| `docx` | Microsoft Word document | -| `gdoc` | Google Docs document | - -### PdfReturnUrlType {#pdfreturnurltype} - - - -**Import**: `import { PdfReturnUrlType }` ❌ **Named Export Only** - -Specifies the type of URL returned for PDF rendition export. - -| Value | Description | -|-------|-------------| -| `cdnUrl` | CDN URL for the PDF | -| `jumpUrl` | Jump URL for the PDF | - -### FileSizeLimitUnit {#filesizelimitunit} - - - -**Import**: `import { FileSizeLimitUnit }` or `addOnUISdk.constants.FileSizeLimitUnit` ✅ **Dual Access** - -Unit of the file size limit. - -| Value | Description | -|-------|-------------| -| `KB` | Kilobytes | -| `MB` | Megabytes | - -### LinkOptions {#linkoptions} - - - -**Import**: `import { LinkOptions }` or `addOnUISdk.constants.LinkOptions` ✅ **Dual Access** - -The type of link to generate for documents. - -| Value | Description | -|-------|-------------| -| `document` | Link to the current document | -| `published` | Link to the published document | - ---- - -## OAuth & Authorization Constants - -### AuthorizationStatus {#authorizationstatus} - - - -**Import**: `import { AuthorizationStatus }` or `addOnUISdk.constants.AuthorizationStatus` ✅ **Dual Access** - -OAuth authorization status values returned from authorization flows. - -| Value | Description | -|-------|-------------| -| `authorized` | Authorization successful | -| `cancelled` | Authorization cancelled by user | -| `error` | Authorization error occurred | - -**Example Usage:** - -```javascript -const result = await addOnUISdk.app.oauth.authorize({...}); -if (result.status === AuthorizationStatus.authorized) { - // Handle successful authorization -} -``` - ---- - -## Video & Media Settings Constants - -### VideoResolution {#videoresolution} - - - -**Import**: `import { VideoResolution }` or `addOnUISdk.constants.VideoResolution` ✅ **Dual Access** - -Video resolution options for MP4 renditions. - -| Value | Resolution | Description | -|-------|------------|-------------| -| `sd480p` | `"480p"` | Standard definition | -| `hd720p` | `"720p"` | High definition | -| `fhd1080p` | `"1080p"` | Full high definition | -| `qhd1440p` | `"1440p"` | Quad high definition | -| `uhd2160p` | `"2160p"` | Ultra high definition (4K) | -| `custom` | Custom | Custom resolution | - -### FrameRate {#framerate} - - - -**Import**: `import { FrameRate }` or `addOnUISdk.constants.FrameRate` ✅ **Dual Access** - -Frame rate options in frames per second for video exports. - -| Value | FPS | Description | -|-------|-----|-------------| -| `fps23_976` | `23.976` | Cinema standard | -| `fps24` | `24` | Film standard | -| `fps25` | `25` | PAL standard | -| `fps29_97` | `29.97` | NTSC standard | -| `fps30` | `30` | Common web standard | -| `fps60` | `60` | High frame rate | - -### BitRate {#bitrate} - - - -**Import**: `import { BitRate }` or `addOnUISdk.constants.BitRate` ✅ **Dual Access** - -Bit rate options in bits per second for video quality control. - -| Value | Bitrate | Description | -|-------|---------|-------------| -| `mbps4` | `4000000` | 4 Mbps | -| `mbps8` | `8000000` | 8 Mbps | -| `mbps10` | `10000000` | 10 Mbps | -| `mbps12` | `12000000` | 12 Mbps | -| `mbps15` | `15000000` | 15 Mbps | -| `mbps25` | `25000000` | 25 Mbps | -| `mbps50` | `50000000` | 50 Mbps | - ---- - -## Runtime & System Constants - -### RuntimeType {#runtimetype} - - - -**Import**: `import { RuntimeType }` or `addOnUISdk.constants.RuntimeType` ✅ **Dual Access** - -Runtime type of the entrypoint creating this backend object. - -| Value | Description | -|-------|-------------| -| `panel` | Add-on's iframe runtime (code running in `index.html`) | -| `script` | Add-on's document sandbox code (code running in `code.js`) | -| `dialog` | Currently open dialog code | - -### EntrypointType {#entrypointtype} - - - -**Import**: `import { EntrypointType }` ❌ **Named Export Only** - -Types of entry points for add-on execution contexts. - -### MediaType {#mediatype} - - - -**Import**: `import { MediaType }` or `addOnUISdk.constants.MediaType` ✅ **Dual Access** - -Types of media content supported by the platform. - -| Value | Description | -|-------|-------------| -| `image` | Image media content | -| `video` | Video media content | -| `audio` | Audio media content | +## Constants + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

              Name

              Type

              Description

              BitRate

              number

              +

              Bit rate in bits per second.

              +
                +
              • mbps4
              • 4000000
                +
              • mbps8
              • 8000000
                +
              • mbps10
              • 10000000
                +
              • mbps12
              • 12000000
                +
              • mbps15
              • 15000000
                +
              • mbps25
              • 25000000
                +
              • mbps50
              • 50000000
                +
              +

              BleedUnit

              string

              +

              Units for the page bleed.

              +
                +
              • "in" (`Inch`)
              • Inch units. +
              • "mm" (`Millimeter`)
              • Millimeter units. +
              +

              ButtonType

              string

              +

              The type of the button pressed in a dialog. Dual access: both named export and constants object.

              +
                +
              • primary
              • Primary button pressed. +
              • secondary
              • Secondary button pressed. +
              • cancel
              • Cancel button pressed. +
              • close
              • Dialog closed via ESC or close(X) button. +
              +

              ColorPickerEvent

              string

              +

              Custom events dispatched by the Color Picker. Named export only - not available in constants object.

              +
                +
              • colorChange
              • "colorpicker-color-change"
                +
              • close
              • "colorpicker-close"
                +
              +

              ColorPickerPlacement

              string

              +

              Placement of the color picker popover with respect to the anchor element. Dual access: both named export and constants object.

              +
                +
              • top
              • "top"
                +
              • bottom
              • "bottom"
                +
              • left
              • "left"
                +
              • right
              • "right"
                +
              +

              DialogResultType

              string

              +

              The type of modal dialog result.

              +
                +
              • alert
              • Alert dialog result (simple dialogs all return this). +
              • input
              • Input dialog result. +
              • custom
              • Custom dialog result. +
              +

              EditorPanel

              string

              +

              The Adobe Express Editor panel to be opened.

              +
                +
              • search
              • Editor Search panel. +
              • yourStuff
              • Editor Your stuff panel. +
              • templates
              • Editor Templates panel. +
              • media
              • Editor Media panel. +
              • text
              • Editor Text panel. +
              • elements
              • Editor Elements panel. +
              • grids
              • Editor Grids panel. +
              • brands
              • Editor Brands panel. +
              • addOns
              • Editor Add-ons panel. +
              +

              ElementsTabs

              string

              +

              Tabs in the Editor's Elements panel.

              +
                +
              • designAssets
              • Design assets tab. +
              • backgrounds
              • Backgrounds tab. +
              • shapes
              • Shapes tab. +
              • stockIcons
              • Icons tab. +
              • charts
              • Charts tab. +
              +

              FileSizeLimitUnit

              string

              +

              Unit of the file size limit.

              +
                +
              • KB
              • "KB"
                +
              • MB
              • "MB"
                +
              +

              FrameRate

              number

              +

              Frame rate in frames per second.

              +
                +
              • fps23_976
              • 23.976
                +
              • fps24
              • 24
                +
              • fps25
              • 25
                +
              • fps29_97
              • 29.97
                +
              • fps30
              • 30
                +
              • fps60
              • 60
                +
              +

              LinkOptions

              string

              +

              The type of link

              +
                +
              • document
              • Link to the current document. +
              • published
              • Link to the published document. +
              +

              MediaTabs

              string

              +

              Tabs in the Editor's Media panel.

              +
                +
              • video
              • Video tab. +
              • audio
              • Audio tab. +
              • photos
              • Photos tab. +
              +

              PanelActionType

              string

              +

              Types of actions that can be performed on Editor panels.

              +
                +
              • search
              • Action type to perform search within the Editor panel. +
              • navigate
              • Action type to perform navigation within the Editor panel. +
              +

              Range

              string

              +

              Rendition page range. Dual access: both named export and constants object.

              +
                +
              • currentPage
              • Generate rendition for the current page +
              • entireDocument
              • Generate rendition for all pages +
              • specificPages
              • Generate rendition for specific pages +
              +

              RenditionFormat

              string

              +

              Required output format of the rendition. Dual access: both named export and constants object.

              +
                +
              • jpg
              • "image/jpeg"
                +
              • png
              • "image/png"
                +
              • mp4
              • "video/mp4"
                +
              • pdf
              • "application/pdf"
                +
              • pptx
              • "application/vnd.openxmlformats-officedocument.presentationml.presentation"
                +
              +

              RenditionIntent

              string

              +

              The intent to set for creating the rendition. Dual access: both named export and constants object.

              +
                +
              • preview
              • Intent to preview the content. +
              • export
              • Intent to export/download the content (default). +
              • print
              • Intent to export and print the content **Note:** For `pdf` format, a print optimized pdf is generated. This option is not supported for `mp4` format. +
              +

              RenditionType

              string

              +

              The type of rendition. Currently returns "page".

              +

              RuntimeType

              string

              +

              Runtime type of the entrypoint creating this backend object. +

                +
              • panel
              • add-on's iframe runtime, ie: code running in index.html +
              • script
              • add-on's document sandbox code ie: code running in code.js +
              • dialog
              • currently open dialog code +
              +

              +

              Variant

              string

              +

              Types of dialog variants supported. Dual access: both named export and constants object.

              +
                +
              • confirmation
              • Ask a user to confirm an action. +
              • information
              • Share information for user to acknowledge. +
              • warning
              • Share information that a user needs to consider before proceeding. +
              • destructive
              • Tell a user that if they proceed with an action, it may impact their data in a negative way. +
              • error
              • Communicate critical issue that a user needs to resolve before proceeding. +
              • input
              • Ask a user to provide some inputs. +
              • custom
              • A dialog that can render complex forms and content. +
              +

              VideoResolution

              string

              +

              Video resolution options for the mp4 renditions.

              +
                +
              • sd480p
              • "480p"
                +
              • hd720p
              • "720p"
                +
              • fhd1080p
              • "1080p"
                +
              • qhd1440p
              • "1440p"
                +
              • uhd2160p
              • "2160p"
                +
              • custom
              • Custom resolution +
              +

              AppEvent

              string

              +

              Events dispatched by the Add-on SDK. Named export only - not available in constants object.

              +
                +
              • themechange
              • "themechange"
                +
              • localechange
              • "localechange"
                +
              • formatchange
              • "formatchange"
                +
              • reset
              • "reset"
                +
              • dragstart
              • "dragstart"
                +
              • dragend
              • "dragend"
                +
              • dragcancel
              • "dragcancel"
                +
              • documentIdAvailable
              • "documentIdAvailable"
                +
              • documentLinkAvailable
              • "documentLinkAvailable"
                +
              • documentPublishedLinkAvailable
              • "documentPublishedLinkAvailable"
                +
              • documentTitleChange
              • "documentTitleChange"
                +
              • documentExportAllowedChange
              • "documentExportAllowedChange"
                +
              +

              AuthorizationStatus

              string

              +

              OAuth authorization status values. Dual access: both named export and constants object.

              +
                +
              • authorized
              • Authorization successful +
              • cancelled
              • Authorization cancelled by user +
              • error
              • Authorization error occurred +
              +

              SupportedMimeTypes

              string

              +

              MIME types for original source assets converted to PDF. Named export only - not available in constants object.

              +
                +
              • docx
              • "docx"
                +
              • gdoc
              • "gdoc"
                +
              +

              FieldType

              string

              +

              The type of input field supported in Simple Dialog. Dual access: both named export and constants object.

              +
                +
              • text
              • "text"
                +
              +

              PlatformEnvironment

              string

              +

              Denotes the current environment where the add-on is running. Dual access: both named export and constants object.

              +
                +
              • app
              • "app"
                +
              • web
              • "web"
                +
              +

              DeviceClass

              string

              +

              Denotes the device class/form factor where the add-on is running. Dual access: both named export and constants object.

              +
                +
              • mobile
              • "mobile"
                +
              • tablet
              • "tablet"
                +
              • desktop
              • "desktop"
                +
              +

              PlatformType

              string

              +

              Denotes the specific platform/operating system where the add-on is running. Dual access: both named export and constants object.

              +
                +
              • iOS
              • "ios"
                +
              • iPadOS
              • "ipad"
                +
              • chromeOS
              • "chromeOS"
                +
              • android
              • "android"
                +
              • chromeBrowser
              • "chromeBrowser"
                +
              • firefoxBrowser
              • "firefoxBrowser"
                +
              • edgeBrowser
              • "edgeBrowser"
                +
              • samsungBrowser
              • "samsumgBrowser"
                (Note: Contains typo in SDK) +
              • safariBrowser
              • "safariBrowser"
                +
              • unknown
              • "unknown"
                +
              +
              From b9242468ccaab9050f09c7d084937e0cd1767b9b Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Mon, 6 Oct 2025 17:45:59 -0400 Subject: [PATCH 10/42] Continued updates --- gatsby-config.js | 4 + .../document-sandbox-constants.md | 132 ++- .../guides/learn/fundamentals/terminology.md | 6 +- .../learn/fundamentals/ui-sdk-constants.md | 52 +- .../learn/how_to/tutorials/grids-addon.md | 2 +- .../platform_concepts/runtime-architecture.md | 758 ++++++++++++++++++ .../references/addonsdk/addonsdk-constants.md | 24 +- 7 files changed, 948 insertions(+), 30 deletions(-) create mode 100644 src/pages/guides/learn/platform_concepts/runtime-architecture.md diff --git a/gatsby-config.js b/gatsby-config.js index 244f19145..0e90095c8 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -770,6 +770,10 @@ module.exports = { title: "Add-on Iframe Context", path: "guides/learn/platform_concepts/context.md", }, + { + title: "Runtime Architecture & Communication", + path: "guides/learn/platform_concepts/runtime-architecture.md", + }, { title: "The Document API", path: "guides/learn/platform_concepts/document-api.md", diff --git a/src/pages/guides/learn/fundamentals/document-sandbox-constants.md b/src/pages/guides/learn/fundamentals/document-sandbox-constants.md index 7b7b90161..4d980b44a 100644 --- a/src/pages/guides/learn/fundamentals/document-sandbox-constants.md +++ b/src/pages/guides/learn/fundamentals/document-sandbox-constants.md @@ -190,7 +190,7 @@ editor.context.selection.forEach(node => { ```javascript // In code.js - import constants from express-document-sdk -import { editor, constants } from "express-document-sdk"; +import { editor, constants, colorUtils } from "express-document-sdk"; // Use constants through the constants object const newRect = editor.createRectangle(); @@ -200,6 +200,88 @@ newRect.fill = { }; ``` +## Working with Colors and Constants + +Document constants work hand-in-hand with the `colorUtils` utility for creating and managing colors. Here's how to combine them effectively: + +### Creating Colors with colorUtils + +```javascript +import { editor, constants, colorUtils } from "express-document-sdk"; + +// Create colors using colorUtils +const redColor = colorUtils.fromRGB(1, 0, 0); // Bright red +const blueColor = colorUtils.fromHex("#0066CC"); // Blue from hex +const greenColor = colorUtils.fromRGB(0, 1, 0, 0.5); // Semi-transparent green + +// Use with fill constants +const rectangle = editor.createRectangle(); +rectangle.fill = { + type: constants.FillType.color, // Use constant for type safety + color: redColor // Use colorUtils for color creation +}; +``` + +### Color Conversion Methods + +```javascript +import { colorUtils } from "express-document-sdk"; + +// Multiple ways to create the same color +const orange = colorUtils.fromRGB(1, 0.5, 0); // RGB values (0-1) +const orange2 = colorUtils.fromRGB({ red: 1, green: 0.5, blue: 0 }); // RGB object +const orange3 = colorUtils.fromHex("#FF8000"); // Hex string +const orange4 = { red: 1, green: 0.5, blue: 0, alpha: 1 }; // Direct object + +// Convert color to hex string +const hexString = colorUtils.toHex(orange); // "#FF8000FF" (includes alpha) +``` + +### Practical Color + Constants Examples + +```javascript +import { editor, constants, colorUtils } from "express-document-sdk"; + +// Example: Create a styled button-like rectangle +function createStyledButton(text, bgColor, textColor) { + // Create background rectangle + const button = editor.createRectangle(); + button.width = 120; + button.height = 40; + + // Apply background color using constants + colorUtils + button.fill = { + type: constants.FillType.color, + color: colorUtils.fromHex(bgColor) + }; + + // Add border stroke + button.stroke = { + type: constants.StrokeType.color, + color: colorUtils.fromHex("#CCCCCC"), + width: 1, + position: constants.StrokePosition.inside + }; + + // Create text element + const textNode = editor.createText(); + textNode.text = text; + textNode.textAlignment = constants.TextAlignment.center; + + // Apply text color + const textStyles = { + fontSize: 14, + color: colorUtils.fromHex(textColor) + }; + textNode.setRangeCharacterStyles(0, text.length, textStyles); + + return { button, textNode }; +} + +// Usage +const { button, textNode } = createStyledButton("Click Me", "#007ACC", "#FFFFFF"); +``` + ### Communication with UI ```javascript @@ -303,8 +385,8 @@ function processSelectedNodes() { ```javascript // ❌ Wrong - Document constants not available in UI // In index.html/index.js -import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; -const fillType = FillType.color; // Error: FillType is not defined +import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; +const fillType = addOnUISdk.constants.FillType.color; // Error: FillType is not defined // ✅ Correct - Use in document sandbox only // In code.js @@ -338,9 +420,53 @@ function changeColor(node, color) { 4. **Group related constants** for better code organization 5. **Document your styling functions** with the constants they expect +## FAQs + +#### Q: Why can't I access document constants from the UI? + +**A:** Document constants are only available in the Document Sandbox (`code.js`) for security isolation. UI and Document environments are separate - use communication APIs to pass data between them. + +#### Q: How do I import document constants? + +**A:** Use `import { constants } from "express-document-sdk"` in your `code.js` file. Access them as `constants.FillType.color`, `constants.BlendMode.normal`, etc. + +#### Q: What's the difference between UI SDK constants and Document Sandbox constants? + +**A:** UI SDK constants are for iframe operations (dialogs, exports, events). Document constants are for content creation (fills, strokes, text alignment, node types). + +#### Q: Can I use `FillType.gradient` or other fill types? + +**A:** Currently, only `FillType.color` is available. Adobe Express may add more fill types in future releases. + +#### Q: How do I check if a node supports fills or strokes? + +**A:** Check the node type first: `if (node.type === constants.SceneNodeType.rectangle || node.type === constants.SceneNodeType.ellipse)` before applying fill/stroke properties. + +#### Q: Why does my blend mode not work? + +**A:** Ensure you're applying blend modes to visual nodes and using valid constants like `constants.BlendMode.multiply`. Not all nodes support all blend modes. + +#### Q: How do I pass constants from Document Sandbox to UI? + +**A:** Expose them through communication APIs: `runtime.exposeApi({ getBlendModes: () => ({ normal: constants.BlendMode.normal }) })`. + +#### Q: What constants should I use for text alignment? + +**A:** Use `constants.TextAlignment.left`, `constants.TextAlignment.center`, `constants.TextAlignment.right`, or `constants.TextAlignment.justifyLeft`. + +#### Q: How do I create colors for use with constants? + +**A:** Use `colorUtils.fromRGB(r, g, b, alpha)` or `colorUtils.fromHex("#RRGGBB")` to create Color objects. Always import: `import { colorUtils } from "express-document-sdk"`. + +#### Q: What's the difference between colorUtils and manual color objects? + +**A:** `colorUtils` provides validation and conversion methods. Manual objects like `{ red: 1, green: 0, blue: 0, alpha: 1 }` work but lack validation and helper functions. + ## Related Documentation - [Document APIs Reference](../../../references/document-sandbox/document-apis/) - [Document APIs Constants](../../../references/document-sandbox/document-apis/enumerations/ArrowHeadType.md) +- [ColorUtils Reference](../../../references/document-sandbox/document-apis/classes/ColorUtils.md) +- [Use Color Guide](../how_to/use_color.md) - Comprehensive color workflow examples - [Add-on UI SDK Constants](./ui-sdk-constants.md) - [Developer Terminology](./terminology.md) diff --git a/src/pages/guides/learn/fundamentals/terminology.md b/src/pages/guides/learn/fundamentals/terminology.md index e23afe90d..711f77511 100644 --- a/src/pages/guides/learn/fundamentals/terminology.md +++ b/src/pages/guides/learn/fundamentals/terminology.md @@ -125,7 +125,7 @@ The SDK that provides APIs for the UI panel of your add-on running in the iframe **Import Statement:** ```javascript -import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js" +import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js" ``` **Also Known As:** UI SDK, addOnUISdk (in code) @@ -185,7 +185,7 @@ import { editor } from "express-document-sdk" ```javascript // Add-on UI SDK (for iframe/UI code) -import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // Document Sandbox SDK (for document sandbox code) import addOnSandboxSdk from "add-on-sdk-document-sandbox"; @@ -240,7 +240,7 @@ const { runtime } = addOnSandboxSdk.instance; ```javascript // ✅ Correct patterns -import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; import addOnSandboxSdk from "add-on-sdk-document-sandbox"; // ❌ Common mistakes diff --git a/src/pages/guides/learn/fundamentals/ui-sdk-constants.md b/src/pages/guides/learn/fundamentals/ui-sdk-constants.md index cd9440764..884d9068e 100644 --- a/src/pages/guides/learn/fundamentals/ui-sdk-constants.md +++ b/src/pages/guides/learn/fundamentals/ui-sdk-constants.md @@ -51,7 +51,7 @@ Most constants support two import patterns. Choose based on your needs: ```javascript // Named imports (recommended for cleaner code) -import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { Range, RenditionFormat, Variant } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // Constants object access (good for dynamic access) const format = addOnUISdk.constants.RenditionFormat.png; @@ -70,7 +70,7 @@ Some constants (like `AppEvent`, `SupportedMimeTypes`) are **only available as n The most common constants you'll use for exporting documents: ```javascript -import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // Export current page as PNG await addOnUISdk.app.document.createRenditions({ @@ -97,7 +97,7 @@ await addOnUISdk.app.document.createRenditions({ Essential constants for user interactions: ```javascript -import addOnUISdk, { Variant, ButtonType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { Variant, ButtonType } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // Show confirmation dialog const result = await addOnUISdk.app.showModalDialog({ @@ -124,7 +124,7 @@ if (result.buttonType === ButtonType.primary) { **Critical:** Event constants must be imported - they're not available in the constants object: ```javascript -import addOnUISdk, { AppEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { AppEvent } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // ✅ Correct - must import AppEvent addOnUISdk.app.on(AppEvent.themechange, (event) => { @@ -149,7 +149,7 @@ import addOnUISdk, { ColorPickerEvent, // ❌ NOT in constants object SupportedMimeTypes, // ❌ NOT in constants object EntrypointType // ❌ NOT in constants object -} from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +} from "https://express.adobe.com/static/add-on-sdk/sdk.js"; ``` ### Flexible Access (Both Ways Work) @@ -157,7 +157,7 @@ import addOnUISdk, { These constants support **both patterns**: ```javascript -import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { Range, RenditionFormat, Variant } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // Option 1: Named import (recommended) const options = { @@ -177,16 +177,16 @@ const format = addOnUISdk.constants.RenditionFormat[userFormat]; ```javascript // Document Export & Rendering -import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // Modal Dialogs & UI -import addOnUISdk, { Variant, ButtonType, FieldType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { Variant, ButtonType, FieldType } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // Event Handling (Import Required!) -import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // Platform Detection -import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; ``` ## Common Errors & Solutions @@ -204,7 +204,7 @@ const event = addOnUISdk.constants.AppEvent.themechange; // undefined! ```javascript // ✅ This works -import addOnUISdk, { AppEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { AppEvent } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; const event = AppEvent.themechange; ``` @@ -237,6 +237,36 @@ await createRenditions({ 3. **Always import named-only exports** - there's no alternative way to access them 4. **Group related imports** - organize by functionality for better readability +## FAQs + +#### Q: Why do some constants require imports while others don't? + +**A:** Adobe Express SDK has two types of constants: dual-access (available both ways) and named-only exports (security/architecture reasons). Always check the [Import Patterns](#import-patterns) section. + +#### Q: How do I know if a constant requires import? + +**A:** Check the [Quick Reference Table](../../../references/addonsdk/addonsdk-constants.md#quick-reference-table) in the Constants Reference or use TypeScript for compile-time validation. When in doubt, use named imports - they work for all constants. + +#### Q: What's the difference between `Range.currentPage` and `addOnUISdk.constants.Range.currentPage`? + +**A:** Both work for dual-access constants like `Range`. Named imports (`Range.currentPage`) are recommended for cleaner code, while constants object access is useful for dynamic scenarios. + +#### Q: Why does `addOnUISdk.constants.AppEvent` return undefined? + +**A:** `AppEvent` is a named-only export and must be imported: `import addOnUISdk, { AppEvent } from "..."`. It's not available through the constants object. + +#### Q: Can I use string literals instead of constants? + +**A:** While possible, constants provide type safety, IDE autocomplete, and future-proofing. Always prefer constants over string literals like `"currentPage"`. + +#### Q: What import should I use for document export? + +**A:** Use `import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://express.adobe.com/static/add-on-sdk/sdk.js"` for most export scenarios. + +#### Q: Do constants work the same in Document Sandbox? + +**A:** No, Document Sandbox has different constants from `express-document-sdk`. See [Document Sandbox Constants](./document-sandbox-constants.md) for sandbox-specific constants. + ## Next Steps - **Complete Reference**: See [Constants Reference](../../../references/addonsdk/addonsdk-constants.md) for all available constants diff --git a/src/pages/guides/learn/how_to/tutorials/grids-addon.md b/src/pages/guides/learn/how_to/tutorials/grids-addon.md index 674e71643..1adf4d457 100644 --- a/src/pages/guides/learn/how_to/tutorials/grids-addon.md +++ b/src/pages/guides/learn/how_to/tutorials/grids-addon.md @@ -569,7 +569,7 @@ The only tricky UI bit worth mentioning here is relative to the **color pickers* import addOnUISdk, { ColorPickerEvent, ColorPickerPlacement, -} from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +} from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // ... diff --git a/src/pages/guides/learn/platform_concepts/runtime-architecture.md b/src/pages/guides/learn/platform_concepts/runtime-architecture.md new file mode 100644 index 000000000..01d6bd873 --- /dev/null +++ b/src/pages/guides/learn/platform_concepts/runtime-architecture.md @@ -0,0 +1,758 @@ +--- +keywords: + - Adobe Express + - Add-on SDK + - Adobe Express Editor + - SDK (Software Development Kit) + - JavaScript + - TypeScript + - Extend + - Extensibility + - API + - Runtime + - Communication + - Document Sandbox + - Document Sandbox SDK + - Document API + - UI Runtime + - Iframe Runtime + - Architecture + - Two-Runtime System + - Cross-Runtime Communication + - API Proxy + - Expose API + - Runtime Bridge + - Sandbox Environment + - Security + - Performance + - Debugging + - Error Handling + - Best Practices + - Manifest Configuration + - Web APIs + - Console APIs + - Blob API + - QuickJS + - Isolated Environment + - Express Document SDK + - Add-on UI SDK + - Communication APIs + - Runtime Types + - Panel Runtime + - Script Runtime + - Document Manipulation + - Content Creation + - UI Components + - Event Handling + - Asynchronous Operations + - queueAsyncEdit + - Editor Context + - Insertion Parent + - Document Root + - Scene Graph + - Node Creation + - File Organization + - Import Patterns + - SDK Imports + - Development Workflow +title: Runtime Architecture & Communication +description: A comprehensive deep-dive guide to Adobe Express add-on architecture, explaining the two-runtime system, communication patterns, SDK imports, debugging techniques, and best practices for building secure and performant add-ons. +contributors: + - https://github.com/hollyschinsky +--- + +# Add-on Architecture Guide: Two-Runtime System, Communication & Development + +Learn about the dual-runtime architecture, communication patterns, and development workflow essential for building Adobe Express add-ons. + +## Overview + +Understanding Adobe Express add-on architecture is crucial for building effective add-ons. This comprehensive deep-dive guide covers the two-runtime system, cross-runtime communication patterns, SDK imports and usage, debugging techniques, security considerations, performance optimization, and development best practices. Whether you're new to add-on development or looking to master advanced concepts, this guide provides the foundational knowledge needed to build robust, secure, and performant add-ons. + +## Dual-Runtime Architecture + +Adobe Express add-ons run in **two separate JavaScript execution environments** that work together: + +1. **UI Runtime** - Your add-on's user interface (iframe) +2. **Document Sandbox** - Secure environment for document manipulation + +## Architecture Diagrams + +### **Architecture: Two Runtime Communication** + +```text +┌─────────────────────────────────────┐ ┌─────────────────────────────────────┐ +│ UI iframe │ │ Document Sandbox │ +│ (Add-on UI SDK) │ │ (Document Sandbox SDK) │ +├─────────────────────────────────────┤ ├─────────────────────────────────────┤ +│ • DOM access │ │ • Document APIs (editor, nodes) │ +│ • Full browser APIs │◄──►│ • Limited browser APIs (console, │ +│ • Event handling │ │ Blob) │ +│ • UI interactions │ │ • Communication APIs (runtime) │ +│ • addOnUISdk.app.document.addImage()│ │ • Direct scenegraph manipulation │ +└─────────────────────────────────────┘ └─────────────────────────────────────┘ + │ │ + │ runtime.apiProxy() │ + │ runtime.exposeApi() │ + └──────────────────────────────────────────────┘ + Communication Layer +``` + +## What is the Runtime Object? + +The `runtime` object acts as a **communication bridge** between the two environments. Each environment has its own runtime object: + +- **UI Runtime**: `addOnUISdk.instance.runtime` +- **Document Sandbox**: `addOnSandboxSdk.instance.runtime` + +The communication bridge can be thought of like a phone line - each side has their own phone to call the other side. + +## The Two Environments Explained + +### UI Runtime Environment + +**File:** `index.js` or `index.html` +**Purpose:** User interface and browser interactions +**SDK Import:** + +```js +import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; +``` + +**Capabilities:** + +- Render your add-on's user interface +- Handle user interactions (clicks, form inputs) +- Access browser APIs (fetch, localStorage) +- OAuth authentication +- Modal dialogs +- File uploads/downloads + +### Document Sandbox Environment + +**File:** `code.js` +**Purpose:** Document manipulation and content creation +**SDK Import:** + +```js +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; +``` + +**Capabilities:** + +- Access Adobe Express Document API +- Create and modify document elements +- Export renditions +- Secure, isolated execution +- Limited browser API access + +## Communication Flow + +### From UI to Document Sandbox + +When you want to manipulate the document from your UI: + +#### UI Runtime (index.js) + +```js +// ui/index.js - Your add-on's interface +import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; + +addOnUISdk.ready.then(async () => { + const { runtime } = addOnUISdk.instance; + + // Button click handler + document.getElementById("createText").addEventListener("click", async () => { + // Get a proxy to call document sandbox functions + const sandboxProxy = await runtime.apiProxy("documentSandbox"); + + // Call function exposed in code.js + await sandboxProxy.createTextElement("Hello World!"); + }); +}); +``` + +#### Document Sandbox (code.js) + +```js +// sandbox/code.js - Document manipulation +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; +import { editor } from "express-document-sdk"; + +const { runtime } = addOnSandboxSdk.instance; + +// Expose functions that UI can call +runtime.exposeApi({ + createTextElement: async function(text) { + await editor.queueAsyncEdit(() => { + const textNode = editor.createText(text); + editor.context.insertionParent.children.append(textNode); + }); + } +}); +``` + +### From Document Sandbox to UI + +When you want to update the UI from document operations: + +#### Document Sandbox (code.js) + +```js +// sandbox/code.js - Document manipulation +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; + +const { runtime } = addOnSandboxSdk.instance; + +async function processDocument() { + // Get a proxy to call UI functions + const uiProxy = await runtime.apiProxy("panel"); + + // Update UI with progress + await uiProxy.updateProgress(50); + + // Document manipulation here... + + await uiProxy.updateProgress(100); +} +``` + +#### UI Runtime (index.js) + +```js +// ui/index.js - Your add-on's interface +import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; + +addOnUISdk.ready.then(() => { + const { runtime } = addOnUISdk.instance; + + // Expose functions that document sandbox can call + runtime.exposeApi({ + updateProgress: function(percentage) { + const progressBar = document.getElementById("progress"); + progressBar.style.width = percentage + "%"; + } + }); +}); +``` + +### Runtime Type Detection + +#### UI Runtime (index.js) + +```js +// ui/index.js - Your add-on's interface +import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; + +addOnUISdk.ready.then(() => { + const { runtime } = addOnUISdk.instance; + // Check what type of runtime you're in + console.log(runtime.type); // "panel" +}); +``` + +#### Document Sandbox (code.js) + +```js +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; + +const { runtime } = addOnSandboxSdk.instance; + +// Check what type of runtime you're in +console.log(runtime.type); // "documentSandbox" +``` + +## Understanding the Document Sandbox SDK Imports + +### When do I need both SDK imports in `code.js`? + +This is a common source of confusion. In your `code.js` file, you may need one or both imports depending on what your add-on does: + +#### Option 1: Communication Only + +```js +// sandbox/code.js - Only communication, no document manipulation +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; + +const { runtime } = addOnSandboxSdk.instance; + +// Only exposing APIs, not creating document content +runtime.exposeApi({ + processData: function(data) { + // Process data, return results + return data.map(item => item.toUpperCase()); + } +}); +``` + +#### Option 2: Document Manipulation Only + +```js +// sandbox/code.js - Only document creation, no communication +import { editor } from "express-document-sdk"; + +// Directly manipulate document without UI communication +editor.queueAsyncEdit(() => { + const text = editor.createText("Auto-generated content"); + editor.context.insertionParent.children.append(text); +}); +``` + +#### Option 3: Both Communication AND Document Manipulation + +```js +// sandbox/code.js - Most common pattern +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; // For communication +import { editor } from "express-document-sdk"; // For document manipulation + +const { runtime } = addOnSandboxSdk.instance; + +// Expose APIs that manipulate the document +runtime.exposeApi({ + createTextElement: async function(text) { + await editor.queueAsyncEdit(() => { + const textNode = editor.createText(text); + editor.context.insertionParent.children.append(textNode); + }); + } +}); +``` + +### Quick Decision Guide + +**Do I need `addOnSandboxSdk`?** + +- ✅ YES if your `code.js` needs to communicate with the UI +- ✅ YES if UI triggers document operations +- ❌ NO if `code.js` runs independently + +**Do I need `express-document-sdk`?** + +- ✅ YES if creating/modifying document content +- ✅ YES if accessing document properties +- ❌ NO if only processing data or communicating + +### Examples + +#### Example 1: Text Generator Add-on + +```js +// sandbox/code.js - Needs BOTH imports +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; // UI sends text data +import { editor } from "express-document-sdk"; // Create text elements + +const { runtime } = addOnSandboxSdk.instance; + +runtime.exposeApi({ + generateText: async function(userInput) { + await editor.queueAsyncEdit(() => { + const text = editor.createText(userInput); + editor.context.insertionParent.children.append(text); + }); + } +}); +``` + +#### Example 2: Document Analytics Add-on + +```js +// sandbox/code.js - Needs BOTH imports +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; // Send results to UI +import { editor } from "express-document-sdk"; // Analyze document + +const { runtime } = addOnSandboxSdk.instance; + +runtime.exposeApi({ + analyzeDocument: function() { + const pageCount = editor.documentRoot.pages.length; + return { pageCount, elements: pageCount * 5 }; // Send data back to UI + } +}); +``` + +#### Example 3: Document Analysis Utility + +```js +// sandbox/code.js - Only needs express-document-sdk +import { editor } from "express-document-sdk"; + +// Analyze current document structure (no UI communication needed) +function analyzeDocument() { + const pages = editor.documentRoot.pages; + const elementCount = pages.length; + + console.log(`Document analysis: ${elementCount} elements found`); + + // Could save analysis results to document metadata or + // trigger other document operations based on analysis + return { elementCount, timestamp: new Date().toISOString() }; +} + +// Execute analysis +const results = analyzeDocument(); +``` + +## Common Patterns + +### Pattern 1: UI-Triggered Document Operations (Most Common) + +User interactions in the UI trigger document changes: + +```js +// UI: User clicks button → Document: Create content +// Requires BOTH imports in code.js +``` + +### Pattern 2: Document-Driven UI Updates + +Document analysis sends results to update the UI: + +```js +// Document: Analyze content → UI: Show results +// Requires BOTH imports in code.js +``` + +### Pattern 3: Independent Document Operations + +Document analysis or operations that run without UI interaction: + +```js +// Document: Analyze/process content +// Only requires express-document-sdk +``` + +## Complete add-on-sdk-document-sandbox Package Overview + +The `add-on-sdk-document-sandbox` package provides more than just the `runtime` object. Here's what you get: + +### Core Features + +#### 1. Communication System (`addOnSandboxSdk.instance.runtime`) + +```js +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; + +const { runtime } = addOnSandboxSdk.instance; + +// Expose APIs to UI +runtime.exposeApi({ /* your functions */ }); + +// Get proxy to UI APIs +const uiProxy = await runtime.apiProxy("panel"); +``` + +#### 2. Injected Web APIs (Global - No Import Needed) + +The document sandbox automatically injects limited browser APIs for common tasks. See the complete [Web APIs Reference](../../../references/document-sandbox/web/index.md) for details. + +```js +// These are automatically available in your code.js +console.log("Debugging output"); +console.error("Something went wrong"); +console.warn("Be careful here"); +console.clear(); // Clear console +``` + +#### 3. Secure Execution Environment + +- **Isolated JavaScript context**: Your code runs in a secure sandbox +- **Limited browser APIs**: Only essential APIs like `console` and `Blob` are available +- **Performance considerations**: Slower than UI runtime but secure +- **No direct DOM access**: Must communicate through UI runtime + +### What You DON'T Need to Import + +These are automatically injected and available globally in the document sandbox. For complete details, see [Web APIs Reference](../../../references/document-sandbox/web/index.md). + +```js +// ✅ Available automatically - no import needed + +// Console APIs for debugging +console.log("This works!"); +console.error("Error logging works!"); +console.warn("Warning logging works!"); +console.info("Info logging works!"); +console.debug("Debug logging works!"); +console.clear(); // Clear console +console.assert(condition, "Assertion message"); + +// Blob interface for binary data handling +const blob = new Blob(['data'], { type: 'text/plain' }); +blob.text().then(text => console.log(text)); +blob.arrayBuffer().then(buffer => console.log(buffer)); +blob.size; // Get blob size +blob.type; // Get MIME type + +// Basic JavaScript globals +setTimeout; // Available but limited +clearTimeout; // Available but limited +``` + +### What You DO Need to Import + +#### For Communication: + +```js +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; +const { runtime } = addOnSandboxSdk.instance; +``` + +#### For Document Manipulation: + +```js +import { editor, colorUtils, constants, fonts } from "express-document-sdk"; +``` + +### Debugging Capabilities + +Since the document sandbox has limited debugging, use these patterns: + +```js +// Basic debugging with console +console.log("Variable value:", myVariable); + +// Object inspection (be careful with large objects) +console.log("Full object:", JSON.stringify(myObject, null, 2)); + +// Error tracking +try { + // Risky operation + const result = editor.createText("Hello"); + console.log("Success:", result); +} catch (error) { + console.error("Operation failed:", error.message); + console.error("Stack trace:", error.stack); +} + +// Assertion testing +console.assert(myVariable !== undefined, "Variable should be defined"); + +// Performance debugging +const startTime = performance.now(); +// ... your code ... +const endTime = performance.now(); +console.log(`Operation took ${endTime - startTime} milliseconds`); +``` + +### Quick Reference: All SDK Imports + +| Feature | UI Runtime
              `addOnUISdk` | Document Sandbox
              `addOnSandboxSdk` | Document Sandbox
              `express-document-sdk` | +|---------|------------|------------------|-----------------| +| **Import Statement** | `import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"` | `import addOnSandboxSdk from "add-on-sdk-document-sandbox"` | `import { editor } from "express-document-sdk"` | +| **File Location** | `index.js/index.html` | `code.js` | `code.js` | +| **Primary Purpose** | User interface & browser interactions | Communication between environments | Document manipulation | +| **Runtime Communication** | ✅ `instance.runtime` | ✅ `instance.runtime` | ❌ No communication | +| **Document Creation** | ❌ No direct access | ❌ No direct access | ✅ `editor.createText()`, etc. | +| **Document Reading** | ❌ No direct access | ❌ No direct access | ✅ `editor.context` | +| **Export Renditions** | ✅ `app.document.createRenditions()` | ❌ No direct access | ❌ No direct access | +| **Modal Dialogs** | ✅ `app.showModalDialog()` | ❌ No direct access | ❌ No direct access | +| **OAuth** | ✅ `app.oauth` | ❌ No direct access | ❌ No direct access | +| **File Upload/Download** | ✅ Full browser APIs | ❌ No direct access | ❌ No direct access | +| **DOM Manipulation** | ✅ Full DOM access | ❌ No DOM access | ❌ No DOM access | +| **Browser APIs** | ✅ All browser APIs | ❌ Limited (console, Blob) | ❌ Limited (console, Blob) | +| **Platform Detection** | ✅ `app.getCurrentPlatform()` | ❌ No direct access | ❌ No direct access | +| **Client Storage** | ✅ `instance.clientStorage` | ❌ No direct access | ❌ No direct access | +| **Constants** | ✅ `constants.*` | ❌ No constants | ✅ Document constants | + +### Manifest Configuration + +The sandbox requires proper manifest setup: + +```json +{ + "entryPoints": [ + { + "type": "panel", + "id": "panel1", + "main": "index.html", + "documentSandbox": "code.js" + } + ] +} +``` + +### SDK Import Decision Matrix + +| Your Add-on Needs | UI Runtime | Document Sandbox | Required Imports | +|-------------------|------------|------------------|------------------| +| **UI only** (no document changes) | ✅ | ❌ | `addOnUISdk` | +| **Document manipulation only** | ❌ | ✅ | `express-document-sdk` | +| **UI + Document communication** | ✅ | ✅ | `addOnUISdk` + `addOnSandboxSdk` | +| **UI + Document creation** | ✅ | ✅ | `addOnUISdk` + `addOnSandboxSdk` + `express-document-sdk` | +| **Data processing only** | ❌ | ✅ | `addOnSandboxSdk` (for communication) | +| **Export/Import only** | ✅ | ❌ | `addOnUISdk` | + +### Common Import Patterns + +```js +// Pattern 1: UI-only add-on (no document changes) +// index.js +import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; +// No code.js file needed + +// Pattern 2: Document manipulation only +// code.js +import { editor } from "express-document-sdk"; +// No index.js communication needed + +// Pattern 3: Full communication + document manipulation (most common) +// index.js +import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; + +// code.js +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; // For communication +import { editor } from "express-document-sdk"; // For document APIs +``` + +## Best Practices + +1. **Clear File Organization** + - Keep UI logic in `index.js` + - Keep document logic in `code.js` + - Use consistent naming for exposed APIs + - Separate concerns clearly between environments + +2. **Error Handling** + - Always wrap API calls in try-catch blocks + - Provide meaningful error messages to users + - Handle communication failures gracefully + - Use `console.error()` for debugging in sandbox + - Validate inputs before processing + +3. **Performance** + - Minimize data transfer between environments + - Batch multiple operations when possible + - Use appropriate data types (see [Communication APIs](../../../references/document-sandbox/communication/index.md#data-types)) + - Remember sandbox runs slower than UI runtime + - Avoid frequent cross-runtime communication in loops + +4. **Debugging** + - Use `console.log` in both environments + - Check browser dev tools for UI runtime + - Use sandbox console for document sandbox debugging + - Use `console.assert()` for validation checks + - Test communication flows thoroughly + +5. **Security** + - Never expose sensitive data through communication APIs + - Validate all data received from the UI + - Use the sandbox's isolation as intended + - Don't attempt to bypass security restrictions + +## Error Handling + +### Common Error: "Runtime is undefined" + +❌ **Wrong:** Trying to use runtime before SDK is ready + +```js +const { runtime } = addOnUISdk.instance; // Error! SDK not ready yet +``` + +✅ **Correct:** Wait for SDK ready state + +```js +addOnUISdk.ready.then(() => { + const { runtime } = addOnUISdk.instance; // Now it's safe +}); +``` + +### Common Error: "Cannot read property 'apiProxy' of undefined" + +❌ **Wrong:** Using wrong SDK in wrong environment + +```js +// In code.js (Document Sandbox) +import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; +const { runtime } = addOnUISdk.instance; // Wrong SDK! +``` + +✅ **Correct:** Use appropriate SDK for each environment + +```js +// In code.js (Document Sandbox) +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; +const { runtime } = addOnSandboxSdk.instance; // Correct SDK! +``` + +## Frequently Asked Questions + +### Q: Why are there two different runtime objects? + +**A:** Each environment has its own runtime object that acts as a "communication phone." The UI runtime calls the document sandbox, and the document sandbox runtime calls the UI. This separation ensures security and proper isolation. + +### Q: When do I use `addOnUISdk.instance.runtime` vs `addOnSandboxSdk.instance.runtime`? + +**A:** Use the runtime object from the environment you're currently in: + +- In `index.js` (UI): Use `addOnUISdk.instance.runtime` +- In `code.js` (Sandbox): Use `addOnSandboxSdk.instance.runtime` + +### Q: What does `await runtime.apiProxy("documentSandbox")` actually do? + +**A:** It creates a proxy object that lets you call functions you've exposed in the document sandbox from your UI code. Think of it as getting a "remote control" for the other environment. + +### Q: What's the difference between `"documentSandbox"` and `"panel"` in apiProxy? + +**A:** These specify which environment you want to communicate with: + +- `"documentSandbox"` - Call from UI to document sandbox +- `"panel"` - Call from document sandbox to UI + +### Q: Can I access document APIs directly from the UI? + +**A:** No, document APIs are only available in the document sandbox for security reasons. You must use the communication system to bridge between environments. + +### Q: How do I know which environment my code is running in? + +**A:** Check your file structure and imports: + +- If you're importing `addOnUISdk` → You're in the UI runtime +- If you're importing `addOnSandboxSdk` → You're in the document sandbox + +### Q: Do I always need both imports in my code.js file? + +**A:** No! It depends on what your add-on does: + +- **Communication only**: Just `addOnSandboxSdk` (no document changes) +- **Document only**: Just `express-document-sdk` (no UI communication) +- **Both**: Most add-ons need both for UI-triggered document operations + +### Q: Why do some examples show one import and others show both? + +**A:** Different add-on types have different needs: + +- Simple document manipulation → One import +- UI-controlled document changes → Both imports +- The example context determines which imports are shown + +### Q: What else is available in the add-on-sdk-document-sandbox package? + +**A:** Besides `runtime`, the sandbox SDK provides: + +- **Web APIs**: Limited browser APIs like `console` and `Blob` for debugging and data handling +- **Automatic global injections**: No need to import basic APIs like `console` +- **Secure execution environment**: Isolated JavaScript context with performance monitoring +- **Communication infrastructure**: Handles the complex proxy system between environments + +### Q: Can I use fetch() or other network APIs in the document sandbox? + +**A:** No, network APIs like `fetch()` are not available in the document sandbox for security reasons. If you need to make network requests, do them in the UI runtime and pass the data to the document sandbox via communication APIs. + +### Q: Why does my add-on feel slower in the document sandbox? + +**A:** The document sandbox runs in an isolated environment (QuickJS) which is inherently slower than the native browser JavaScript engine. This is by design for security. Minimize complex operations and data transfer between environments. + +## Related Topics + +- [Communication APIs Reference](../../../references/document-sandbox/communication/index.md) +- [UI SDK Reference](../../../references/addonsdk/index.md) +- [Document API Concepts](./document-api.md) + +## Next Steps + +Now that you understand the architecture, explore these guides and tutorials: + +- [Document API deep dive](./document-api.md): Learn how to use the Document API to create and modify document content. +- [Building your first add-on](../how_to/tutorials/grids-addon.md): Use the Document API to create a simple add-on that adds a grid to the document. +- [Using the Communication APIs](../how_to/tutorials/stats-addon.md): Build an add-on to gather statistics on the active document using the Communication APIs. diff --git a/src/pages/references/addonsdk/addonsdk-constants.md b/src/pages/references/addonsdk/addonsdk-constants.md index 6b90309f8..1e4d7823c 100644 --- a/src/pages/references/addonsdk/addonsdk-constants.md +++ b/src/pages/references/addonsdk/addonsdk-constants.md @@ -29,7 +29,7 @@ import addOnUISdk, { ColorPickerEvent, // Import required SupportedMimeTypes, // Import required EntrypointType // Import required -} from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +} from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // ✅ Correct usage const docxMimeType = SupportedMimeTypes.docx; @@ -44,7 +44,7 @@ const docxMimeType = addOnUISdk.constants.SupportedMimeTypes.docx; // undefined These constants support **both import patterns** for flexibility. You can use either approach: ```javascript -import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { Range, RenditionFormat, Variant } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // Option 1: Named import (recommended for cleaner code) const currentPage = Range.currentPage; @@ -89,7 +89,7 @@ const confirmDialog = addOnUISdk.constants.Variant.confirmation; 1. **Use named imports for cleaner code** when you know which constants you need: ```javascript - import addOnUISdk, { Range, RenditionFormat } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + import addOnUISdk, { Range, RenditionFormat } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; const options = { range: Range.currentPage, @@ -106,7 +106,7 @@ const confirmDialog = addOnUISdk.constants.Variant.confirmation; 3. **Always import named-only exports** - there's no alternative way to access them: ```javascript - import addOnUISdk, { SupportedMimeTypes } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + import addOnUISdk, { SupportedMimeTypes } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; ``` ### Quick Reference Table @@ -162,32 +162,32 @@ import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment, EditorPanel, MediaTabs, ElementsTabs, AuthorizationStatus, DialogResultType, RuntimeType, BleedUnit, PanelActionType, ColorPickerPlacement, VideoResolution, FrameRate, BitRate, FileSizeLimitUnit, LinkOptions -} from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +} from "https://express.adobe.com/static/add-on-sdk/sdk.js"; ``` ### By Use Case (Recommended) ```javascript // Document Export & Rendering -import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // Modal Dialogs & UI -import addOnUISdk, { Variant, ButtonType, FieldType, DialogResultType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { Variant, ButtonType, FieldType, DialogResultType } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // Event Handling (Import Required!) -import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // Platform Detection -import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // Editor Navigation -import addOnUISdk, { EditorPanel, MediaTabs, ElementsTabs, PanelActionType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { EditorPanel, MediaTabs, ElementsTabs, PanelActionType } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // File Types & MIME (Import Required!) -import addOnUISdk, { SupportedMimeTypes } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { SupportedMimeTypes } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; // OAuth & Authorization -import addOnUISdk, { AuthorizationStatus } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnUISdk, { AuthorizationStatus } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; ``` ## Constants Reference From b735b9f3c167a14655cc9206425b71ef05899ebf Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Mon, 6 Oct 2025 17:46:42 -0400 Subject: [PATCH 11/42] Remove old files --- .../guides/learn/fundamentals/constants.md | 218 --- .../guides/learn/how_to/selection_events.md | 1668 ----------------- .../guides/learn/how_to/ui_sdk_constants.md | 486 ----- 3 files changed, 2372 deletions(-) delete mode 100644 src/pages/guides/learn/fundamentals/constants.md delete mode 100644 src/pages/guides/learn/how_to/selection_events.md delete mode 100644 src/pages/guides/learn/how_to/ui_sdk_constants.md diff --git a/src/pages/guides/learn/fundamentals/constants.md b/src/pages/guides/learn/fundamentals/constants.md deleted file mode 100644 index 38599dc57..000000000 --- a/src/pages/guides/learn/fundamentals/constants.md +++ /dev/null @@ -1,218 +0,0 @@ -# Using Add-on UI SDK Constants - -Constants provide type-safe ways to interact with the Add-on UI SDK and help prevent runtime errors. This guide covers the most common patterns you'll need to get started quickly. - -## Why Use Constants? - -Constants equal their variable name as a string (e.g., `ButtonType.primary` equals `"primary"`), but using constants provides type safety, IDE autocomplete, and future-proofing against API changes. - - - -For complete technical specifications of all constants, see the [Constants Reference](../../../references/addonsdk/addonsdk-constants.md). - -## Quick Start - -Most constants support two import patterns. Choose based on your needs: - -```javascript -// Named imports (recommended for cleaner code) -import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Constants object access (good for dynamic access) -const format = addOnUISdk.constants.RenditionFormat.png; -``` - - - -#### Important - -Some constants (like `AppEvent`, `SupportedMimeTypes`) are **only available as named exports** and cannot be accessed through `addOnUISdk.constants.*`. See [Import Patterns](#import-patterns) below. - -## Most Common Use Cases - -### Document Export - -The most common constants you'll use for exporting documents: - -```javascript -import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Export current page as PNG -await addOnUISdk.app.document.createRenditions({ - range: Range.currentPage, - format: RenditionFormat.png -}); - -// Export entire document as PDF for printing -await addOnUISdk.app.document.createRenditions({ - range: Range.entireDocument, - format: RenditionFormat.pdf, - intent: RenditionIntent.print -}); -``` - -**Available Options:** - -- `Range`: `currentPage`, `entireDocument`, `specificPages` -- `RenditionFormat`: `png`, `jpg`, `mp4`, `pdf`, `pptx` -- `RenditionIntent`: `export`, `preview`, `print` - -### Modal Dialogs - -Essential constants for user interactions: - -```javascript -import addOnUISdk, { Variant, ButtonType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Show confirmation dialog -const result = await addOnUISdk.app.showModalDialog({ - variant: Variant.confirmation, - title: "Delete Item", - description: "Are you sure?" -}); - -// Handle user response -if (result.buttonType === ButtonType.primary) { - // User confirmed -} else if (result.buttonType === ButtonType.cancel) { - // User cancelled -} -``` - -**Available Options:** - -- `Variant`: `confirmation`, `information`, `warning`, `error`, `input` -- `ButtonType`: `primary`, `secondary`, `cancel`, `close` - -### Event Handling - -**Critical:** Event constants must be imported - they're not available in the constants object: - -```javascript -import addOnUISdk, { AppEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// ✅ Correct - must import AppEvent -addOnUISdk.app.on(AppEvent.themechange, (event) => { - updateUITheme(event.theme); -}); - -// ❌ This will NOT work -addOnUISdk.app.on(addOnUISdk.constants.AppEvent.themechange, handler); // undefined! -``` - -## Import Patterns - -Understanding import patterns is crucial for avoiding runtime errors. - -### Must Import (Named Exports Only) - -These constants **must be imported** and are **not available** through `addOnUISdk.constants.*`: - -```javascript -import addOnUISdk, { - AppEvent, // ❌ NOT in constants object - ColorPickerEvent, // ❌ NOT in constants object - SupportedMimeTypes, // ❌ NOT in constants object - EntrypointType, // ❌ NOT in constants object - PdfReturnUrlType // ❌ NOT in constants object -} from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; -``` - -### Flexible Access (Both Ways Work) - -These constants support **both patterns**: - -```javascript -import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Option 1: Named import (recommended) -const options = { - range: Range.currentPage, - format: RenditionFormat.png, - variant: Variant.error -}; - -// Option 2: Constants object (good for dynamic access) -const userFormat = "png"; -const format = addOnUISdk.constants.RenditionFormat[userFormat]; -``` - -## Copy-Paste Import Statements - -### Most Common Scenarios - -```javascript -// Document Export & Rendering -import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Modal Dialogs & UI -import addOnUISdk, { Variant, ButtonType, FieldType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Event Handling (Import Required!) -import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Platform Detection -import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; -``` - -## Common Errors & Solutions - -### "Cannot read property of undefined" - -**Problem**: Trying to access named-only exports through constants object. - -```javascript -// ❌ This causes errors -const event = addOnUISdk.constants.AppEvent.themechange; // undefined! -``` - -**Solution**: Always import named-only exports. - -```javascript -// ✅ This works -import addOnUISdk, { AppEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; -const event = AppEvent.themechange; -``` - -### Using String Literals Instead of Constants - -**Problem**: Using fragile string literals. - -```javascript -// ❌ Fragile - might break if API changes -await createRenditions({ - range: "currentPage", // String literal - format: "image/png" // String literal -}); -``` - -**Solution**: Always use constants. - -```javascript -// ✅ Safe - will be updated if API changes -await createRenditions({ - range: Range.currentPage, // Constant - format: RenditionFormat.png // Constant -}); -``` - -## Best Practices - -1. **Use named imports for known constants** - cleaner and more reliable -2. **Use constants object for dynamic access** - when the constant name is determined at runtime -3. **Always import named-only exports** - there's no alternative way to access them -4. **Group related imports** - organize by functionality for better readability - -## Next Steps - -- **Complete Reference**: See [Constants Reference](../../../references/addonsdk/addonsdk-constants.md) for all available constants -- **Practical Guides**: - - [Create Renditions](../how_to/create_renditions.md) - Using export constants - - [Modal Dialogs](../how_to/modal_dialogs.md) - Using dialog constants - - [Theme & Locale](../how_to/theme_locale.md) - Using platform constants - - - -#### Pro Tip - -When in doubt, use named imports - they work for all constants and provide the cleanest code! diff --git a/src/pages/guides/learn/how_to/selection_events.md b/src/pages/guides/learn/how_to/selection_events.md deleted file mode 100644 index 8d711b6e4..000000000 --- a/src/pages/guides/learn/how_to/selection_events.md +++ /dev/null @@ -1,1668 +0,0 @@ ---- -keywords: - - Adobe Express - - Express Add-on SDK - - Document API - - Selection - - selectionChange - - Events - - Node selection - - UI integration - - Document sandbox - - Event handlers - - Selection filtering - - Locked nodes - - Properties panel - - Real-time updates -title: Selection Events and Methods -description: Complete guide to working with selections in Adobe Express documents - from basic operations to advanced UI integration patterns. -contributors: - - https://github.com/hollyschinsky -faq: - questions: - - question: "How do I get the current selection?" - answer: "Use `editor.context.selection` to get an array of currently selected editable nodes, or `editor.context.hasSelection` to check if anything is selected." - - - question: "How do I listen for selection changes?" - answer: "Use `editor.context.on('selectionChange', callback)` to register a handler. Always store the returned ID for cleanup." - - - question: "How do I programmatically select elements?" - answer: "Set `editor.context.selection = node` for single elements or `editor.context.selection = [node1, node2]` for multiple elements." - - - question: "What's the difference between selection and selectionIncludingNonEditable?" - answer: "`selection` only includes editable nodes, while `selectionIncludingNonEditable` includes locked/non-editable nodes that users can see but not modify." - - - question: "Can I modify the document in a selection change callback?" - answer: "Never modify the document in selection change handlers - this can crash the application. Only update UI, analyze data, or communicate with your panel." - - - question: "How do I clear the selection?" - answer: "Set `editor.context.selection = []` or `editor.context.selection = undefined` to clear all selections." - - - question: "What selection rules should I know?" - answer: "Only nodes within the current artboard can be selected, you cannot select both parent and child nodes simultaneously, and locked nodes are automatically filtered from the main selection." - - - question: "How do I clean up selection event handlers?" - answer: "Always call `editor.context.off('selectionChange', handlerId)` using the ID returned from `on()` to prevent memory leaks." - - - question: "How do I communicate selection changes to my UI?" - answer: "Use the runtime API to send selection data from the document sandbox to your UI panel, enabling real-time interface updates." - - - question: "What are common selection-based actions?" - answer: "Typical actions include updating properties panels, enabling/disabling tools, applying formatting to selected text, grouping elements, and showing context-appropriate options." ---- - -# Selection Events and Methods - -Learn how to work with user selections, handle selection changes, and respond to user interactions in Adobe Express documents using the Document API. - - - -Document API Context Required - -Selection methods and events are part of the Document API and require the document sandbox environment. These examples should be used in your `code.js` file, not in the main iframe panel. - -Make sure your manifest includes `"documentSandbox": "code.js"` in the entry points. - -For more details on the Context class, see the [Context API reference](../../../references/document-sandbox/document-apis/classes/Context.md). - -## Getting Started with Selections - -Selections in Adobe Express represent the elements (nodes) that users have currently selected in their document. The selection system provides access to what's selected, the ability to change selections programmatically, and events to respond to selection changes. - -### Check Current Selection - - - -#### JavaScript - -```js -// code.js -import { editor } from "express-document-sdk"; - -// Check if anything is selected -if (editor.context.hasSelection) { - const selection = editor.context.selection; - console.log(`Selected ${selection.length} item(s)`); - - // Process each selected node - selection.forEach((node, index) => { - console.log(`Node ${index + 1}: ${node.type}`); - }); -} else { - console.log("Nothing is selected"); -} -``` - -#### TypeScript - -```ts -// code.js -import { editor, Node } from "express-document-sdk"; - -// Check if anything is selected -if (editor.context.hasSelection) { - const selection: readonly Node[] = editor.context.selection; - console.log(`Selected ${selection.length} item(s)`); - - // Process each selected node - selection.forEach((node: Node, index: number) => { - console.log(`Node ${index + 1}: ${node.type}`); - }); -} else { - console.log("Nothing is selected"); -} -``` - -## Understanding Selections - -In Adobe Express, the selection system provides: - -- **Current selection access** - Get what's currently selected -- **Selection modification** - Programmatically change selections -- **Selection events** - React to selection changes -- **Selection filtering** - Handle locked/non-editable content - -### Selection Rules - -Adobe Express enforces these constraints: - -1. **Artboard constraint** - Only nodes within the current artboard can be selected -2. **Hierarchy filtering** - Cannot select both parent and child nodes simultaneously -3. **Locked node filtering** - Locked nodes are excluded from the main selection -4. **Editable-only** - Main selection only includes editable nodes - -## Basic Selection Operations - -Core operations for working with selections. - -### Getting the Current Selection - - - -#### JavaScript - -```js -// code.js -import { editor } from "express-document-sdk"; - -// Get the current selection -const selection = editor.context.selection; - -console.log("Selected nodes:", selection.length); - -// Process each selected node -selection.forEach((node, index) => { - console.log(`Node ${index + 1}: ${node.type}`); - - // Common node properties you can access - console.log(" Position:", node.translation); - console.log(" Size:", { width: node.width, height: node.height }); -}); -``` - -#### TypeScript - -```ts -// code.js -import { editor, Node } from "express-document-sdk"; - -// Get the current selection -const selection: readonly Node[] = editor.context.selection; - -console.log("Selected nodes:", selection.length); - -// Process each selected node -selection.forEach((node: Node, index: number) => { - console.log(`Node ${index + 1}: ${node.type}`); - - // Common node properties you can access - console.log(" Position:", node.translation); - console.log(" Size:", { width: node.width, height: node.height }); -}); -``` - -### Programmatic Selection - - - -#### JavaScript - -```js -// code.js -import { editor } from "express-document-sdk"; - -// Create and select a single element -const rectangle = editor.createRectangle(); -rectangle.width = 100; -rectangle.height = 100; -rectangle.translation = { x: 50, y: 50 }; - -// Add to document -editor.context.insertionParent.children.append(rectangle); - -// Select the rectangle (single element) -editor.context.selection = rectangle; -// OR using array syntax: editor.context.selection = [rectangle]; - -console.log("Rectangle is now selected"); -``` - -#### TypeScript - -```ts -// code.js -import { editor, RectangleNode, ContainerNode } from "express-document-sdk"; - -// Create a simple rectangle to demonstrate selection -const rectangle: RectangleNode = editor.createRectangle(); -rectangle.width = 100; -rectangle.height = 100; -rectangle.translation = { x: 50, y: 50 }; - -// Add to document -const insertionParent: ContainerNode = editor.context.insertionParent; -insertionParent.children.append(rectangle); - -// Select the rectangle (single element) -editor.context.selection = rectangle; -// OR using array syntax: editor.context.selection = [rectangle]; - -console.log("Rectangle is now selected"); -``` - -### Multiple Selection - - - -#### JavaScript - -```js -// code.js -import { editor } from "express-document-sdk"; - -// Create multiple elements -const rectangle = editor.createRectangle(); -rectangle.width = 80; -rectangle.height = 80; -rectangle.translation = { x: 50, y: 50 }; - -const ellipse = editor.createEllipse(); -ellipse.rx = 40; -ellipse.ry = 40; -ellipse.translation = { x: 200, y: 50 }; - -// Add both to document -const parent = editor.context.insertionParent; -parent.children.append(rectangle, ellipse); - -// Select both elements at once -editor.context.selection = [rectangle, ellipse]; - -console.log("Multiple elements selected:", editor.context.selection.length); -``` - -#### TypeScript - -```ts -// code.js -import { editor, RectangleNode, EllipseNode, ContainerNode } from "express-document-sdk"; - -// Create multiple simple elements -const rectangle: RectangleNode = editor.createRectangle(); -rectangle.width = 80; -rectangle.height = 80; -rectangle.translation = { x: 50, y: 50 }; - -const ellipse: EllipseNode = editor.createEllipse(); -ellipse.rx = 40; -ellipse.ry = 40; -ellipse.translation = { x: 200, y: 50 }; - -// Add both to document -const parent: ContainerNode = editor.context.insertionParent; -parent.children.append(rectangle, ellipse); - -// Select both elements at once -editor.context.selection = [rectangle, ellipse]; - -console.log("Multiple elements selected:", editor.context.selection.length); -``` - -### Clearing the Selection - - - -#### JavaScript - -```js -// code.js -import { editor } from "express-document-sdk"; - -// Clear the selection - both ways work -editor.context.selection = []; -// OR: editor.context.selection = undefined; - -console.log("Selection cleared"); -console.log("Has selection:", editor.context.hasSelection); // false -``` - -#### TypeScript - -```ts -// code.js -import { editor } from "express-document-sdk"; - -// Clear the selection - both ways work -editor.context.selection = []; -// OR: editor.context.selection = undefined; - -console.log("Selection cleared"); -console.log("Has selection:", editor.context.hasSelection); // false -``` - -## Selection Events - -Respond to selection changes to create dynamic UIs that update based on what's selected. - -### Basic Selection Change Handler - - - -#### JavaScript - -```js -// code.js -import { editor } from "express-document-sdk"; - -// Listen for selection changes -const handlerId = editor.context.on("selectionChange", () => { - const selection = editor.context.selection; - - console.log("Selection changed!"); - console.log("New selection count:", selection.length); - - if (selection.length === 0) { - console.log("Nothing selected"); - } else if (selection.length === 1) { - console.log("One item selected:", selection[0].type); - } else { - console.log("Multiple items selected"); - } -}); - -// Store handlerId if you need to unregister later -console.log("Selection handler registered:", handlerId); -``` - -#### TypeScript - -```ts -// code.js -import { editor, Node } from "express-document-sdk"; - -// Listen for selection changes -const handlerId: string = editor.context.on("selectionChange", () => { - const selection: readonly Node[] = editor.context.selection; - - console.log("Selection changed!"); - console.log("New selection count:", selection.length); - - if (selection.length === 0) { - console.log("Nothing selected"); - } else if (selection.length === 1) { - console.log("One item selected:", selection[0].type); - } else { - console.log("Multiple items selected"); - } -}); - -// Store handlerId if you need to unregister later -console.log("Selection handler registered:", handlerId); -``` - -### Properties Panel Example - -Dynamic properties panel based on selection: - - - -#### JavaScript - -```js -// code.js -import { editor } from "express-document-sdk"; - -function updatePropertiesPanel() { - const selection = editor.context.selection; - - if (selection.length === 0) { - console.log("Properties Panel: Show 'Nothing Selected' state"); - return; - } - - if (selection.length === 1) { - const node = selection[0]; - console.log("Properties Panel: Show properties for", node.type); - - // Show different properties based on node type - if (node.type === "Text") { - console.log(" - Show font controls"); - console.log(" - Show text color picker"); - } else if (node.type === "Rectangle" || node.type === "Ellipse") { - console.log(" - Show fill color picker"); - console.log(" - Show stroke controls"); - } - - // Common properties for all nodes - console.log(" - Show position controls"); - console.log(" - Show size controls"); - - } else { - console.log("Properties Panel: Show multi-selection options"); - console.log(` - ${selection.length} items selected`); - console.log(" - Show alignment tools"); - console.log(" - Show group option"); - } -} - -// Register the handler -editor.context.on("selectionChange", updatePropertiesPanel); - -// Call once on startup to initialize -updatePropertiesPanel(); -``` - -#### TypeScript - -```ts -// code.js -import { editor, Node, TextNode } from "express-document-sdk"; - -function updatePropertiesPanel(): void { - const selection: readonly Node[] = editor.context.selection; - - if (selection.length === 0) { - console.log("Properties Panel: Show 'Nothing Selected' state"); - return; - } - - if (selection.length === 1) { - const node: Node = selection[0]; - console.log("Properties Panel: Show properties for", node.type); - - // Show different properties based on node type - if (node.type === "Text") { - console.log(" - Show font controls"); - console.log(" - Show text color picker"); - } else if (node.type === "Rectangle" || node.type === "Ellipse") { - console.log(" - Show fill color picker"); - console.log(" - Show stroke controls"); - } - - // Common properties for all nodes - console.log(" - Show position controls"); - console.log(" - Show size controls"); - - } else { - console.log("Properties Panel: Show multi-selection options"); - console.log(` - ${selection.length} items selected`); - console.log(" - Show alignment tools"); - console.log(" - Show group option"); - } -} - -// Register the handler -editor.context.on("selectionChange", updatePropertiesPanel); - -// Call once on startup to initialize -updatePropertiesPanel(); -``` - -### Event Handler Cleanup - -⚠️ **Important**: Always clean up event handlers to prevent memory leaks. - - - -#### JavaScript - -```js -// code.js -import { editor } from "express-document-sdk"; - -// Store handler IDs so you can unregister them later -let selectionHandlerId = null; - -function startListening() { - // Register handler and store the ID - selectionHandlerId = editor.context.on("selectionChange", () => { - console.log("Selection changed!"); - // Handle selection change - }); - - console.log("✅ Selection handler registered"); -} - -function stopListening() { - // Clean up the handler - if (selectionHandlerId) { - editor.context.off("selectionChange", selectionHandlerId); - selectionHandlerId = null; - console.log("✅ Selection handler cleaned up"); - } -} - -// Start listening -startListening(); - -// Clean up when your add-on is being destroyed or reset -// stopListening(); -``` - -#### TypeScript - -```ts -// code.js -import { editor } from "express-document-sdk"; - -// Store handler IDs so you can unregister them later -let selectionHandlerId: string | null = null; - -function startListening(): void { - // Register handler and store the ID - selectionHandlerId = editor.context.on("selectionChange", () => { - console.log("Selection changed!"); - // Handle selection change - }); - - console.log("✅ Selection handler registered"); -} - -function stopListening(): void { - // Clean up the handler - if (selectionHandlerId) { - editor.context.off("selectionChange", selectionHandlerId); - selectionHandlerId = null; - console.log("✅ Selection handler cleaned up"); - } -} - -// Start listening -startListening(); - -// Clean up when your add-on is being destroyed or reset -// stopListening(); -## Advanced Selection Techniques - -Advanced patterns for complex add-ons. - -### Working with Locked/Non-Editable Elements - -Handle selections that include locked or non-editable content: - - - -#### JavaScript - -```js -// code.js -import { editor } from "express-document-sdk"; - -function analyzeCompleteSelection() { - const editableSelection = editor.context.selection; - const fullSelection = editor.context.selectionIncludingNonEditable; - - return { - editableCount: selection.length, - totalCount: fullSelection.length, - lockedCount: fullSelection.length - selection.length, - types: [...new Set(selection.map(node => node.type))], // Unique types - hasText: selection.some(node => node.type === "Text"), - hasShapes: selection.some(node => - node.type === "Rectangle" || node.type === "Ellipse" - ), - isEmpty: !editor.context.hasSelection - }; -} - -// Example: Dynamic UI updates based on detailed analysis -editor.context.on("selectionChange", () => { - const analysis = analyzeSelection(); - - console.log("📊 Detailed Selection Info:"); - console.log(` Editable: ${analysis.editableCount}`); - if (analysis.lockedCount > 0) { - console.log(` Locked: ${analysis.lockedCount}`); - } - console.log(` Types: ${analysis.types.join(", ")}`); - - // Enable specific tools based on content - if (analysis.hasText) { - console.log("🔤 Text formatting tools available"); - } - if (analysis.hasShapes) { - console.log("🔷 Shape styling tools available"); - } - if (analysis.editableCount > 1) { - console.log("📐 Alignment tools available"); - } -}); -``` - -#### TypeScript - -```ts -// code.js -import { editor, Node } from "express-document-sdk"; - -interface DetailedSelectionAnalysis { - editableCount: number; - totalCount: number; - lockedCount: number; - types: string[]; - hasText: boolean; - hasShapes: boolean; - isEmpty: boolean; -} - -function analyzeSelection(): DetailedSelectionAnalysis { - const selection: readonly Node[] = editor.context.selection; - const fullSelection: readonly Node[] = editor.context.selectionIncludingNonEditable; - - return { - editableCount: selection.length, - totalCount: fullSelection.length, - lockedCount: fullSelection.length - selection.length, - types: [...new Set(selection.map((node: Node) => node.type))], // Unique types - hasText: selection.some((node: Node) => node.type === "Text"), - hasShapes: selection.some((node: Node) => - node.type === "Rectangle" || node.type === "Ellipse" - ), - isEmpty: !editor.context.hasSelection - }; -} - -// Example: Dynamic UI updates based on detailed analysis -editor.context.on("selectionChange", () => { - const analysis: DetailedSelectionAnalysis = analyzeSelection(); - - console.log("📊 Detailed Selection Info:"); - console.log(` Editable: ${analysis.editableCount}`); - if (analysis.lockedCount > 0) { - console.log(` Locked: ${analysis.lockedCount}`); - } - console.log(` Types: ${analysis.types.join(", ")}`); - - // Enable specific tools based on content - if (analysis.hasText) { - console.log("🔤 Text formatting tools available"); - } - if (analysis.hasShapes) { - console.log("🔷 Shape styling tools available"); - } - if (analysis.editableCount > 1) { - console.log("📐 Alignment tools available"); - } -}); -``` - -## UI Integration - -Communicate selection changes between the document sandbox and your UI panel to create responsive interfaces. - -### Selection-Based Actions - -Common patterns for performing actions on selected elements: - - - -#### JavaScript - -```js -// code.js -import { editor, colorUtils } from "express-document-sdk"; - -// Function to apply red color to selected text -function applyRedToSelectedText() { - const selection = editor.context.selection; - - // Filter for text nodes only - const textNodes = selection.filter(node => node.type === "Text"); - - if (textNodes.length === 0) { - console.log("No text nodes selected"); - return; - } - - // Apply red color to all selected text - const redColor = colorUtils.fromHex("#FF0000"); - - textNodes.forEach(textNode => { - textNode.fullContent.applyCharacterStyles({ color: redColor }); - }); - - console.log(`Applied red color to ${textNodes.length} text nodes`); -} - -// Function to group selected elements -function groupSelection() { - const selection = editor.context.selection; - - if (selection.length < 2) { - console.log("Need at least 2 elements to create a group"); - return; - } - - // Create a group - const group = editor.createGroup(); - - // Add selected elements to the group - selection.forEach(node => { - // Remove from current parent and add to group - node.removeFromParent(); - group.children.append(node); - }); - - // Add group to the document - editor.context.insertionParent.children.append(group); - - // Select the new group - editor.context.selection = group; - - console.log(`Created group with ${selection.length} elements`); -} - -// Register handlers for different actions -editor.context.on("selectionChange", () => { - const selection = editor.context.selection; - - // Update UI or enable/disable actions based on selection - if (selection.length === 0) { - console.log("No selection - disable all actions"); - } else if (selection.length === 1) { - console.log("Single selection - enable individual actions"); - } else { - console.log("Multiple selection - enable group actions"); - } -}); -``` - -#### TypeScript - -```ts -// code.js -import { editor, colorUtils, Node, TextNode, GroupNode, ContainerNode } from "express-document-sdk"; - -// Function to apply red color to selected text -function applyRedToSelectedText(): void { - const selection: readonly Node[] = editor.context.selection; - - // Filter for text nodes only - const textNodes = selection.filter((node: Node): node is TextNode => - node.type === "Text" - ); - - if (textNodes.length === 0) { - console.log("No text nodes selected"); - return; - } - - // Apply red color to all selected text - const redColor = colorUtils.fromHex("#FF0000"); - - textNodes.forEach((textNode: TextNode) => { - textNode.fullContent.applyCharacterStyles({ color: redColor }); - }); - - console.log(`Applied red color to ${textNodes.length} text nodes`); -} - -// Function to group selected elements -function groupSelection(): void { - const selection: readonly Node[] = editor.context.selection; - - if (selection.length < 2) { - console.log("Need at least 2 elements to create a group"); - return; - } - - // Create a group - const group: GroupNode = editor.createGroup(); - - // Add selected elements to the group - selection.forEach((node: Node) => { - // Remove from current parent and add to group - node.removeFromParent(); - group.children.append(node); - }); - - // Add group to the document - const insertionParent: ContainerNode = editor.context.insertionParent; - insertionParent.children.append(group); - - // Select the new group - editor.context.selection = group; - - console.log(`Created group with ${selection.length} elements`); -} - -// Register handlers for different actions -editor.context.on("selectionChange", () => { - const selection: readonly Node[] = editor.context.selection; - - // Update UI or enable/disable actions based on selection - if (selection.length === 0) { - console.log("No selection - disable all actions"); - } else if (selection.length === 1) { - console.log("Single selection - enable individual actions"); - } else { - console.log("Multiple selection - enable group actions"); - } -}); -``` - -### Selection State Management - - - -#### JavaScript - -```js -// code.js -import { editor } from "express-document-sdk"; - -class SelectionManager { - constructor() { - this.selectionHistory = []; - this.handlerId = null; - this.startListening(); - } - - startListening() { - this.handlerId = editor.context.on("selectionChange", () => { - const selection = editor.context.selection; - - // Store selection in history (limit to last 10) - this.selectionHistory.push([...selection]); - if (this.selectionHistory.length > 10) { - this.selectionHistory.shift(); - } - - console.log("Selection history length:", this.selectionHistory.length); - this.notifySelectionChange(selection); - }); - } - - notifySelectionChange(selection) { - // Custom logic based on selection - if (selection.length === 0) { - this.onNoSelection(); - } else if (selection.length === 1) { - this.onSingleSelection(selection[0]); - } else { - this.onMultipleSelection(selection); - } - } - - onNoSelection() { - console.log("No elements selected"); - // Disable context-sensitive UI - } - - onSingleSelection(node) { - console.log("Single element selected:", node.type); - // Enable single-element actions - } - - onMultipleSelection(selection) { - console.log("Multiple elements selected:", selection.length); - // Enable multi-element actions - } - - restorePreviousSelection() { - if (this.selectionHistory.length >= 2) { - const previousSelection = this.selectionHistory[this.selectionHistory.length - 2]; - editor.context.selection = previousSelection; - } - } - - stopListening() { - if (this.handlerId) { - editor.context.off("selectionChange", this.handlerId); - this.handlerId = null; - } - } -} - -// Usage -const selectionManager = new SelectionManager(); -``` - -#### TypeScript - -```ts -// code.js -import { editor, Node } from "express-document-sdk"; - -class SelectionManager { - private selectionHistory: Node[][] = []; - private handlerId: string | null = null; - - constructor() { - this.startListening(); - } - - startListening(): void { - this.handlerId = editor.context.on("selectionChange", () => { - const selection: readonly Node[] = editor.context.selection; - - // Store selection in history (limit to last 10) - this.selectionHistory.push([...selection]); - if (this.selectionHistory.length > 10) { - this.selectionHistory.shift(); - } - - console.log("Selection history length:", this.selectionHistory.length); - this.notifySelectionChange(selection); - }); - } - - private notifySelectionChange(selection: readonly Node[]): void { - // Custom logic based on selection - if (selection.length === 0) { - this.onNoSelection(); - } else if (selection.length === 1) { - this.onSingleSelection(selection[0]); - } else { - this.onMultipleSelection(selection); - } - } - - private onNoSelection(): void { - console.log("No elements selected"); - // Disable context-sensitive UI - } - - private onSingleSelection(node: Node): void { - console.log("Single element selected:", node.type); - // Enable single-element actions - } - - private onMultipleSelection(selection: readonly Node[]): void { - console.log("Multiple elements selected:", selection.length); - // Enable multi-element actions - } - - restorePreviousSelection(): void { - if (this.selectionHistory.length >= 2) { - const previousSelection = this.selectionHistory[this.selectionHistory.length - 2]; - editor.context.selection = previousSelection; - } - } - - stopListening(): void { - if (this.handlerId) { - editor.context.off("selectionChange", this.handlerId); - this.handlerId = null; - } - } -} - -// Usage -const selectionManager = new SelectionManager(); -``` - -## Cleanup and Best Practices - -### Unregistering Event Handlers - - - -#### JavaScript - -```js -// code.js -import { editor } from "express-document-sdk"; - -// Store handler IDs for cleanup -let selectionHandlerId = null; - -function setupSelectionHandling() { - // Register handler and store ID - selectionHandlerId = editor.context.on("selectionChange", () => { - console.log("Selection changed"); - // Handle selection change - }); - - console.log("Selection handler registered"); -} - -function cleanupSelectionHandling() { - // Unregister the handler - if (selectionHandlerId) { - editor.context.off("selectionChange", selectionHandlerId); - selectionHandlerId = null; - console.log("Selection handler unregistered"); - } -} - -// Setup -setupSelectionHandling(); - -// Cleanup when add-on is being destroyed or reset -// cleanupSelectionHandling(); -``` - -#### TypeScript - -```ts -// code.js -import { editor } from "express-document-sdk"; - -// Store handler IDs for cleanup -let selectionHandlerId: string | null = null; - -function setupSelectionHandling(): void { - // Register handler and store ID - selectionHandlerId = editor.context.on("selectionChange", () => { - console.log("Selection changed"); - // Handle selection change - }); - - console.log("Selection handler registered"); -} - -function cleanupSelectionHandling(): void { - // Unregister the handler - if (selectionHandlerId) { - editor.context.off("selectionChange", selectionHandlerId); - selectionHandlerId = null; - console.log("Selection handler unregistered"); - } -} - -// Setup -setupSelectionHandling(); - -// Cleanup when add-on is being destroyed or reset -// cleanupSelectionHandling(); -``` - -## Best Practices & Guidelines - -### Selection System Rules - -1. **Artboard constraint**: Only nodes within the current artboard can be selected -2. **Hierarchy filtering**: Cannot select both parent and child nodes simultaneously -3. **Locked node handling**: Locked nodes are excluded from main selection but available in `selectionIncludingNonEditable` -4. **Automatic filtering**: System automatically filters out invalid selections - -### Critical: Selection Handler Restrictions - - - -⚠️ Document Modification Restrictions - -**Never modify the document inside selection change handlers!** This can crash the application. - -✅ **Safe in selection handlers:** - -- Update UI panels -- Log information -- Analyze selection -- Enable/disable buttons -- Send data to UI panel - -❌ **Never do in selection handlers:** - -- Create, delete, or modify nodes -- Change document structure -- Set properties on selected elements - -### Performance Guidelines - -1. **Keep handlers fast**: Minimize processing time -2. **Essential work only**: Avoid heavy computations -3. **Clean Up**: Always unregister handlers when done (`editor.context.off()`) -4. **Avoid Heavy Work**: Don't do complex calculations in selection callbacks - -### Selection System Rules (Advanced) - -Understanding these rules helps you work with selections more effectively: - -1. **Artboard Limitation**: Only nodes within the current artboard can be selected -2. **Hierarchy Rules**: Cannot select both a parent node and its children simultaneously - -## Communication Between UI and Document Sandbox - -One of the most important real-world patterns is communicating selection changes from the document sandbox to your UI panel, allowing you to update the interface based on what the user has selected. - -For detailed information on the communication APIs, see the [Communication API reference](../../../references/document-sandbox/communication/). - -### Complete Communication Example - -This example shows how to set up bidirectional communication between your UI panel and document sandbox for selection-based interactions. - - - -#### JavaScript - -**UI Panel (index.js):** - -```js -// ui/index.js -import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -let documentSandbox; - -addOnUISdk.ready.then(async () => { - // Get access to the document sandbox APIs - documentSandbox = await addOnUISdk.instance.runtime.apiProxy("documentSandbox"); - - // Set up UI elements - setupSelectionUI(); - - // Start listening for selection updates from sandbox - documentSandbox.registerSelectionUpdateHandler(handleSelectionUpdate); -}); - -function setupSelectionUI() { - const container = document.getElementById("selection-info"); - - container.innerHTML = ` -
              Nothing selected
              -
              - - - -
              -
              - `; - - // Set up button handlers - document.getElementById("apply-red-btn").addEventListener("click", () => { - documentSandbox.applyRedToSelection(); - }); - - document.getElementById("group-btn").addEventListener("click", () => { - documentSandbox.groupSelection(); - }); - - document.getElementById("clear-selection-btn").addEventListener("click", () => { - documentSandbox.clearSelection(); - }); -} - -function handleSelectionUpdate(selectionInfo) { - console.log("Selection update received:", selectionInfo); - - // Update status - const statusEl = document.getElementById("selection-status"); - if (selectionInfo.count === 0) { - statusEl.textContent = "Nothing selected"; - } else if (selectionInfo.count === 1) { - statusEl.textContent = `1 ${selectionInfo.types[0]} selected`; - } else { - statusEl.textContent = `${selectionInfo.count} elements selected`; - } - - // Update action buttons - document.getElementById("apply-red-btn").disabled = !selectionInfo.hasText; - document.getElementById("group-btn").disabled = selectionInfo.count < 2; - document.getElementById("clear-selection-btn").disabled = selectionInfo.count === 0; - - // Update details - const detailsEl = document.getElementById("selection-details"); - if (selectionInfo.count > 0) { - detailsEl.innerHTML = ` -

              Selection Details:

              -

              Types: ${selectionInfo.types.join(", ")}

              -

              Has Text: ${selectionInfo.hasText ? "Yes" : "No"}

              -

              Has Shapes: ${selectionInfo.hasShapes ? "Yes" : "No"}

              -

              Locked Elements: ${selectionInfo.lockedCount}

              - `; - } else { - detailsEl.innerHTML = ""; - } -} -``` - -**Document Sandbox (code.js):** - -```js -// code.js -import addOnSandboxSdk from "add-on-sdk-document-sandbox"; -import { editor, colorUtils } from "express-document-sdk"; - -const { runtime } = addOnSandboxSdk.instance; -let uiPanel; - -// Wait for UI panel to be ready -runtime.ready.then(async () => { - // Get access to the UI panel APIs - uiPanel = await runtime.apiProxy("panel"); - - // Set up selection change handler - setupSelectionHandling(); -}); - -function setupSelectionHandling() { - editor.context.on("selectionChange", () => { - const selectionInfo = analyzeCurrentSelection(); - - // Send selection info to UI panel - uiPanel.handleSelectionUpdate(selectionInfo); - }); - - // Send initial selection state - const initialSelection = analyzeCurrentSelection(); - uiPanel.handleSelectionUpdate(initialSelection); -} - -function analyzeCurrentSelection() { - const selection = editor.context.selection; - const fullSelection = editor.context.selectionIncludingNonEditable; - - return { - count: selection.length, - totalCount: fullSelection.length, - lockedCount: fullSelection.length - selection.length, - types: [...new Set(selection.map(node => node.type))], - hasText: selection.some(node => node.type === "Text"), - hasShapes: selection.some(node => - ["Rectangle", "Ellipse"].includes(node.type) - ), - isEmpty: selection.length === 0 - }; -} - -// Export functions for UI to call -function registerSelectionUpdateHandler(handler) { - // Store the handler function from UI - runtime.exposeApi({ - applyRedToSelection() { - const selection = editor.context.selection; - const textNodes = selection.filter(node => node.type === "Text"); - - if (textNodes.length > 0) { - const redColor = colorUtils.fromHex("#FF0000"); - textNodes.forEach(textNode => { - textNode.fullContent.applyCharacterStyles({ color: redColor }); - }); - - console.log(`Applied red to ${textNodes.length} text nodes`); - } - }, - - groupSelection() { - const selection = editor.context.selection; - - if (selection.length >= 2) { - const group = editor.createGroup(); - - // Move selected elements to group - selection.forEach(node => { - node.removeFromParent(); - group.children.append(node); - }); - - // Add group to document - editor.context.insertionParent.children.append(group); - - // Select the new group - editor.context.selection = group; - - console.log(`Created group with ${selection.length} elements`); - } - }, - - clearSelection() { - editor.context.selection = []; - console.log("Selection cleared"); - }, - - registerSelectionUpdateHandler: handler - }); -} - -// Expose the registration function immediately -runtime.exposeApi({ registerSelectionUpdateHandler }); -``` - -#### TypeScript - -**UI Panel (index.ts):** - -```ts -// ui/index.ts -import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -interface SelectionInfo { - count: number; - totalCount: number; - lockedCount: number; - types: string[]; - hasText: boolean; - hasShapes: boolean; - isEmpty: boolean; -} - -interface DocumentSandboxAPI { - registerSelectionUpdateHandler: (handler: (info: SelectionInfo) => void) => void; - applyRedToSelection: () => void; - groupSelection: () => void; - clearSelection: () => void; -} - -let documentSandbox: DocumentSandboxAPI; - -addOnUISdk.ready.then(async () => { - // Get access to the document sandbox APIs - documentSandbox = await addOnUISdk.instance.runtime.apiProxy("documentSandbox"); - - // Set up UI elements - setupSelectionUI(); - - // Start listening for selection updates from sandbox - documentSandbox.registerSelectionUpdateHandler(handleSelectionUpdate); -}); - -function setupSelectionUI(): void { - const container = document.getElementById("selection-info"); - - if (container) { - container.innerHTML = ` -
              Nothing selected
              -
              - - - -
              -
              - `; - - // Set up button handlers - const applyRedBtn = document.getElementById("apply-red-btn"); - const groupBtn = document.getElementById("group-btn"); - const clearBtn = document.getElementById("clear-selection-btn"); - - applyRedBtn?.addEventListener("click", () => { - documentSandbox.applyRedToSelection(); - }); - - groupBtn?.addEventListener("click", () => { - documentSandbox.groupSelection(); - }); - - clearBtn?.addEventListener("click", () => { - documentSandbox.clearSelection(); - }); - } -} - -function handleSelectionUpdate(selectionInfo: SelectionInfo): void { - console.log("Selection update received:", selectionInfo); - - // Update status - const statusEl = document.getElementById("selection-status"); - if (statusEl) { - if (selectionInfo.count === 0) { - statusEl.textContent = "Nothing selected"; - } else if (selectionInfo.count === 1) { - statusEl.textContent = `1 ${selectionInfo.types[0]} selected`; - } else { - statusEl.textContent = `${selectionInfo.count} elements selected`; - } - } - - // Update action buttons - const applyRedBtn = document.getElementById("apply-red-btn") as HTMLButtonElement; - const groupBtn = document.getElementById("group-btn") as HTMLButtonElement; - const clearBtn = document.getElementById("clear-selection-btn") as HTMLButtonElement; - - if (applyRedBtn) applyRedBtn.disabled = !selectionInfo.hasText; - if (groupBtn) groupBtn.disabled = selectionInfo.count < 2; - if (clearBtn) clearBtn.disabled = selectionInfo.count === 0; - - // Update details - const detailsEl = document.getElementById("selection-details"); - if (detailsEl) { - if (selectionInfo.count > 0) { - detailsEl.innerHTML = ` -

              Selection Details:

              -

              Types: ${selectionInfo.types.join(", ")}

              -

              Has Text: ${selectionInfo.hasText ? "Yes" : "No"}

              -

              Has Shapes: ${selectionInfo.hasShapes ? "Yes" : "No"}

              -

              Locked Elements: ${selectionInfo.lockedCount}

              - `; - } else { - detailsEl.innerHTML = ""; - } - } -} -``` - -**Document Sandbox (code.ts):** - -```ts -// code.ts -import addOnSandboxSdk from "add-on-sdk-document-sandbox"; -import { editor, colorUtils, Node, TextNode, GroupNode, ContainerNode } from "express-document-sdk"; - -interface SelectionInfo { - count: number; - totalCount: number; - lockedCount: number; - types: string[]; - hasText: boolean; - hasShapes: boolean; - isEmpty: boolean; -} - -interface UIPanelAPI { - handleSelectionUpdate: (info: SelectionInfo) => void; -} - -const { runtime } = addOnSandboxSdk.instance; -let uiPanel: UIPanelAPI; - -// Wait for UI panel to be ready -runtime.ready.then(async () => { - // Get access to the UI panel APIs - uiPanel = await runtime.apiProxy("panel"); - - // Set up selection change handler - setupSelectionHandling(); -}); - -function setupSelectionHandling(): void { - editor.context.on("selectionChange", () => { - const selectionInfo: SelectionInfo = analyzeCurrentSelection(); - - // Send selection info to UI panel - uiPanel.handleSelectionUpdate(selectionInfo); - }); - - // Send initial selection state - const initialSelection: SelectionInfo = analyzeCurrentSelection(); - uiPanel.handleSelectionUpdate(initialSelection); -} - -function analyzeCurrentSelection(): SelectionInfo { - const selection: readonly Node[] = editor.context.selection; - const fullSelection: readonly Node[] = editor.context.selectionIncludingNonEditable; - - return { - count: selection.length, - totalCount: fullSelection.length, - lockedCount: fullSelection.length - selection.length, - types: [...new Set(selection.map((node: Node) => node.type))], - hasText: selection.some((node: Node) => node.type === "Text"), - hasShapes: selection.some((node: Node) => - ["Rectangle", "Ellipse"].includes(node.type) - ), - isEmpty: selection.length === 0 - }; -} - -// Export functions for UI to call -function registerSelectionUpdateHandler(handler: (info: SelectionInfo) => void): void { - // Store the handler function from UI - runtime.exposeApi({ - applyRedToSelection(): void { - const selection: readonly Node[] = editor.context.selection; - const textNodes = selection.filter((node: Node): node is TextNode => - node.type === "Text" - ); - - if (textNodes.length > 0) { - const redColor = colorUtils.fromHex("#FF0000"); - textNodes.forEach((textNode: TextNode) => { - textNode.fullContent.applyCharacterStyles({ color: redColor }); - }); - - console.log(`Applied red to ${textNodes.length} text nodes`); - } - }, - - groupSelection(): void { - const selection: readonly Node[] = editor.context.selection; - - if (selection.length >= 2) { - const group: GroupNode = editor.createGroup(); - - // Move selected elements to group - selection.forEach((node: Node) => { - node.removeFromParent(); - group.children.append(node); - }); - - // Add group to document - const insertionParent: ContainerNode = editor.context.insertionParent; - insertionParent.children.append(group); - - // Select the new group - editor.context.selection = group; - - console.log(`Created group with ${selection.length} elements`); - } - }, - - clearSelection(): void { - editor.context.selection = []; - console.log("Selection cleared"); - }, - - registerSelectionUpdateHandler: handler - }); -} - -// Expose the registration function immediately -runtime.exposeApi({ registerSelectionUpdateHandler }); -``` - -### HTML Structure - -Your `index.html` should include the selection UI container: - -```html - - - - Selection Demo - - - -
              - -
              - - - - -``` - -### Key Communication Patterns - -1. **Initialization**: UI panel registers a callback with the document sandbox -2. **Event Flow**: Document sandbox listens for selection changes and sends updates to UI -3. **Action Triggers**: UI sends action requests back to document sandbox -4. **Bidirectional**: Both sides can call methods on the other - -This pattern enables rich, responsive UIs that react to document changes in real-time. - -## Quick Reference & Common Patterns - -Here are some frequently used patterns you can copy and adapt: - -### Conditional Actions Based on Selection - -```js -// Enable/disable actions based on selection type -editor.context.on("selectionChange", () => { - const selection = editor.context.selection; - - // Communicate with your UI panel - const actions = { - canGroup: selection.length >= 2, - canApplyTextStyle: selection.some(node => node.type === "Text"), - canApplyFill: selection.some(node => - ["Rectangle", "Ellipse"].includes(node.type) - ), - isEmpty: selection.length === 0 - }; - - // Send to UI panel for enabling/disabling buttons - // (Use the communication API to send this data) -}); -``` - -### Selection-Based Properties Panel - -```js -// Update properties panel based on selection -editor.context.on("selectionChange", () => { - const selection = editor.context.selection; - - if (selection.length === 1) { - const node = selection[0]; // Common pattern: access first selected element - - // Send node properties to UI for editing - const properties = { - type: node.type, - width: node.width || null, - height: node.height || null, - x: node.translation?.x || null, - y: node.translation?.y || null, - locked: node.locked || false - }; - - // Update UI panel with these properties - console.log("Node properties:", properties); - } -}); -``` - -### Working with Single Selection - -Many add-ons focus on single-element operations. Here's a common pattern used throughout the documentation: - -```js -// Safe access to first selected element (used in use_text.md and other guides) -if (editor.context.hasSelection) { - const selectedNode = editor.context.selection[0]; - - // Perform operations on the selected node - if (selectedNode.type === "Text") { - // Handle text-specific operations - } -} -``` - -## FAQs - -#### Q: How do I get the current selection? - -**A:** Use `editor.context.selection` to get an array of currently selected nodes. - -#### Q: How do I listen for selection changes? - -**A:** Use `editor.context.on('selectionChange', callback)` to register a selection change handler. - -#### Q: How do I programmatically select elements? - -**A:** Set `editor.context.selection = [node]` or `editor.context.selection = [node1, node2]` for multiple elements. - -#### Q: What's the difference between selection and selectionIncludingNonEditable? - -**A:** `selection` only includes editable nodes, while `selectionIncludingNonEditable` also includes locked/non-editable nodes. - -#### Q: Can I modify the document in a selection change callback? - -**A:** No, avoid making document changes in selection change callbacks as it may destabilize the application. - -#### Q: How do I clear the selection? - -**A:** Set `editor.context.selection = []` or `editor.context.selection = undefined`. - -#### Q: What are the selection rules? - -**A:** Nodes must be within the current artboard, ancestors cannot be selected with descendants, and locked nodes are filtered out. - -#### Q: How do I unregister selection event handlers? - -**A:** Use `editor.context.off('selectionChange', handlerId)` with the ID returned from the `on()` method. - -## Related Topics - -- **[Context API Reference](../../../references/document-sandbox/document-apis/classes/Context.md)** - Complete API documentation for the Context class -- **[Communication APIs](../../../references/document-sandbox/communication/)** - Learn how to communicate between document sandbox and UI panel -- **[Group Elements](./group_elements.md)** - Working with selections to create and manage groups -- **[Position Elements](./position_elements.md)** - Positioning and transforming selected elements -- **[Use Text](./use_text.md)** - Examples of working with text selections using `editor.context.selection[0]` -- **[EditorEvent Enumeration](../../../references/document-sandbox/document-apis/enumerations/EditorEvent.md)** - All available editor events -- **[Node API Reference](../../../references/document-sandbox/document-apis/classes/Node.md)** - Understanding the Node class used in selections - -#### Q: How do I unregister selection event handlers? - -**A:** Use `editor.context.off('selectionChange', handlerId)` with the ID returned from the `on()` method. diff --git a/src/pages/guides/learn/how_to/ui_sdk_constants.md b/src/pages/guides/learn/how_to/ui_sdk_constants.md deleted file mode 100644 index d107f4aaa..000000000 --- a/src/pages/guides/learn/how_to/ui_sdk_constants.md +++ /dev/null @@ -1,486 +0,0 @@ -# Using Add-on UI SDK Constants - -This guide shows you how to effectively use constants in your Adobe Express add-ons. Constants provide type-safe ways to interact with the Add-on UI SDK and help prevent runtime errors. - -For complete technical specifications of all constants, see the [Constants Reference](../../../references/addonsdk/addonsdk-constants.md). - - - -**Quick Import Guide:** Some constants require explicit imports, others don't. Check the [Import Quick Reference](#import-quick-reference) below or use the [Constants Cheat Sheet](#constants-cheat-sheet) to avoid runtime errors. - - - -**Why Use Constants?** Constants are equal to their variable name as a string value (e.g., `ButtonType.primary` equals `"primary"`), but using constants provides type safety, IDE autocomplete, and future-proofing against API changes. - -## Quick Start - -Most constants support two import patterns. Choose based on your needs: - -```javascript -// Named imports (recommended for cleaner code) -import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Constants object access (good for dynamic access) -const format = addOnUISdk.constants.RenditionFormat.png; -``` - - - -**Important:** Some constants (like `AppEvent`, `SupportedMimeTypes`) are **only available as named exports** and cannot be accessed through `addOnUISdk.constants.*`. See [Import Patterns](#import-patterns) below. - -## Constants Cheat Sheet - -This quick reference shows you exactly how to import and use each constant type. Copy the import statements you need: - -### Most Common Constants (Copy & Paste Ready) - -```javascript -// For document export/rendering -import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Usage examples: -const options = { - range: Range.currentPage, // or: addOnUISdk.constants.Range.currentPage - format: RenditionFormat.png, // or: addOnUISdk.constants.RenditionFormat.png - intent: RenditionIntent.export // or: addOnUISdk.constants.RenditionIntent.export -}; -``` - -```javascript -// For modal dialogs -import addOnUISdk, { Variant, ButtonType, FieldType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Usage examples: -const dialogOptions = { - variant: Variant.confirmation, // or: addOnUISdk.constants.Variant.confirmation - // ... handle result.buttonType === ButtonType.primary -}; -``` - -```javascript -// For events (MUST import - not available in constants object) -import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Usage examples: -addOnUISdk.app.on(AppEvent.themechange, handler); -picker.addEventListener(ColorPickerEvent.colorChange, handler); -// ❌ addOnUISdk.constants.AppEvent.themechange <- This will NOT work! -``` - -```javascript -// For platform detection -import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Usage examples: -if (platform.platformType === PlatformType.iOS) { /* iOS code */ } -if (platform.deviceClass === DeviceClass.mobile) { /* mobile UI */ } -``` - -### Import Required (Cannot Use Constants Object) - -These constants **must be imported** - they're not available through `addOnUISdk.constants.*`: - -| Constant | Import | Won't Work | -|----------|---------|---------------| -| `AppEvent` | `import { AppEvent }` | `addOnUISdk.constants.AppEvent` | -| `ColorPickerEvent` | `import { ColorPickerEvent }` | `addOnUISdk.constants.ColorPickerEvent` | -| `SupportedMimeTypes` | `import { SupportedMimeTypes }` | `addOnUISdk.constants.SupportedMimeTypes` | -| `EntrypointType` | `import { EntrypointType }` | `addOnUISdk.constants.EntrypointType` | -| `PdfReturnUrlType` | `import { PdfReturnUrlType }` | `addOnUISdk.constants.PdfReturnUrlType` | - -### Flexible Access (Both Ways Work) - -These constants can be used with **either** import pattern: - -| Constant | Named Import | Constants Object | -|----------|--------------|------------------| -| `Range` | `Range.currentPage` | `addOnUISdk.constants.Range.currentPage` | -| `RenditionFormat` | `RenditionFormat.png` | `addOnUISdk.constants.RenditionFormat.png` | -| `Variant` | `Variant.confirmation` | `addOnUISdk.constants.Variant.confirmation` | -| `ButtonType` | `ButtonType.primary` | `addOnUISdk.constants.ButtonType.primary` | -| `PlatformType` | `PlatformType.iOS` | `addOnUISdk.constants.PlatformType.iOS` | -| `EditorPanel` | `EditorPanel.media` | `addOnUISdk.constants.EditorPanel.media` | - -*Complete list in [Import Patterns](#import-patterns) section.* - -## Common Use Cases by Category - -### Dialog & UI Interactions - -Use these constants when creating modal dialogs and handling user interactions: - -```javascript -import addOnUISdk, { Variant, ButtonType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Show different dialog types -await addOnUISdk.app.showModalDialog({ - variant: Variant.error, // Error dialog - title: "Upload Failed", - description: "File size exceeds limit" -}); - -await addOnUISdk.app.showModalDialog({ - variant: Variant.confirmation, // Confirmation dialog - title: "Delete Item", - description: "Are you sure?" -}); - -// Handle dialog responses -const result = await addOnUISdk.app.showModalDialog({...}); -if (result.buttonType === ButtonType.primary) { - // User clicked primary button -} else if (result.buttonType === ButtonType.cancel) { - // User cancelled -} -``` - -**Available Dialog Constants:** - -- `Variant`: `confirmation`, `information`, `warning`, `destructive`, `error`, `input`, `custom` -- `ButtonType`: `primary`, `secondary`, `cancel`, `close` -- `FieldType`: `text` (for input dialogs) - -### Document Export & Rendering - -Use these constants when creating renditions (exports) of documents: - -```javascript -import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Export current page as PNG -await addOnUISdk.app.document.createRenditions({ - range: Range.currentPage, - format: RenditionFormat.png -}); - -// Export entire document as PDF for printing -await addOnUISdk.app.document.createRenditions({ - range: Range.entireDocument, - format: RenditionFormat.pdf, - intent: RenditionIntent.print -}); - -// Export specific pages as JPG -await addOnUISdk.app.document.createRenditions({ - range: Range.specificPages, - pageIds: ["page1", "page3"], - format: RenditionFormat.jpg -}); -``` - -**Available Export Constants:** - -- `Range`: `currentPage`, `entireDocument`, `specificPages` -- `RenditionFormat`: `png`, `jpg`, `mp4`, `pdf`, `pptx` -- `RenditionIntent`: `export`, `preview`, `print` - -### Platform Detection - -Use these constants to create responsive add-ons that work across different platforms: - -```javascript -import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -const platform = await addOnUISdk.app.getCurrentPlatform(); - -// Platform-specific behavior -if (platform.platformType === PlatformType.iOS || platform.platformType === PlatformType.iPadOS) { - // iOS/iPadOS specific handling - showTouchOptimizedUI(); -} else if (platform.platformType === PlatformType.chromeBrowser) { - // Chrome browser specific handling - enableKeyboardShortcuts(); -} - -// Device class responsive design -if (platform.deviceClass === DeviceClass.mobile) { - showMobileLayout(); -} else if (platform.deviceClass === DeviceClass.desktop) { - showDesktopLayout(); -} - -// Environment-specific features -if (platform.environment === PlatformEnvironment.app) { - // Native app features available - enableAdvancedFeatures(); -} else { - // Web browser limitations - showWebFallback(); -} -``` - -**Available Platform Constants:** - -- `PlatformType`: `iOS`, `iPadOS`, `android`, `chromeBrowser`, `firefoxBrowser`, etc. -- `DeviceClass`: `mobile`, `tablet`, `desktop` -- `PlatformEnvironment`: `app`, `web` - -### Editor Panel Navigation - -Use these constants to programmatically navigate Express editor panels: - -```javascript -import addOnUISdk, { EditorPanel, MediaTabs, ElementsTabs } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Open specific editor panels -addOnUISdk.app.ui.openEditorPanel(EditorPanel.media); -addOnUISdk.app.ui.openEditorPanel(EditorPanel.elements); -addOnUISdk.app.ui.openEditorPanel(EditorPanel.text); - -// Navigate to specific tabs within panels -addOnUISdk.app.ui.openEditorPanel(EditorPanel.media, { - tab: MediaTabs.photos -}); - -addOnUISdk.app.ui.openEditorPanel(EditorPanel.elements, { - tab: ElementsTabs.shapes -}); -``` - -**Available Navigation Constants:** - -- `EditorPanel`: `search`, `yourStuff`, `templates`, `media`, `text`, `elements`, `grids`, `brands`, `addOns` -- `MediaTabs`: `video`, `audio`, `photos` -- `ElementsTabs`: `designAssets`, `backgrounds`, `shapes`, `stockIcons`, `charts` - -### Event Handling - -Use these constants when listening to SDK events: - -```javascript -import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Listen to app events (named export only!) -addOnUISdk.app.on(AppEvent.themechange, (event) => { - updateUITheme(event.theme); -}); - -addOnUISdk.app.on(AppEvent.documentTitleChange, (event) => { - console.log("Document title changed to:", event.title); -}); - -// Color picker events (named export only!) -colorPickerElement.addEventListener(ColorPickerEvent.colorChange, (event) => { - applyColor(event.color); -}); -``` - - - -**Event constants are named-export only** - they cannot be accessed through `addOnUISdk.constants.*`. - -## Import Patterns - -Understanding import patterns is crucial for avoiding runtime errors. - -### Named Exports (Import Required) - -These constants **must be imported** and are **not available** through `addOnUISdk.constants.*`: - -```javascript -import addOnUISdk, { - AppEvent, // ❌ NOT in constants object - ColorPickerEvent, // ❌ NOT in constants object - SupportedMimeTypes, // ❌ NOT in constants object - EntrypointType, // ❌ NOT in constants object - PdfReturnUrlType // ❌ NOT in constants object -} from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// ✅ Correct usage -const docxType = SupportedMimeTypes.docx; -const colorEvent = ColorPickerEvent.colorChange; - -// ❌ Will NOT work - returns undefined -const docxType = addOnUISdk.constants.SupportedMimeTypes.docx; // undefined! -``` - -### Dual Access Constants - -These constants support **both patterns** - choose what works best for your code: - -```javascript -import addOnUISdk, { Range, RenditionFormat, Variant } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// Option 1: Named imports (cleaner, recommended) -const options = { - range: Range.currentPage, - format: RenditionFormat.png, - variant: Variant.error -}; - -// Option 2: Constants object (good for dynamic access) -const userFormat = "png"; -const format = addOnUISdk.constants.RenditionFormat[userFormat]; -const range = addOnUISdk.constants.Range.currentPage; -``` - -**All Dual Access Constants:** -`Range`, `RenditionFormat`, `RenditionType`, `RenditionIntent`, `Variant`, `DialogResultType`, `ButtonType`, `RuntimeType`, `BleedUnit`, `EditorPanel`, `MediaTabs`, `ElementsTabs`, `PanelActionType`, `ColorPickerPlacement`, `AuthorizationStatus`, `FieldType`, `PlatformEnvironment`, `DeviceClass`, `PlatformType`, `MediaType`, `VideoResolution`, `FrameRate`, `BitRate`, `FileSizeLimitUnit`, `LinkOptions` - -## Best Practices - -### 1. Use Named Imports for Known Constants - -When you know which constants you need, use named imports for cleaner code: - -```javascript -// ✅ Good - clear and concise -import addOnUISdk, { Range, RenditionFormat } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -const options = { - range: Range.currentPage, - format: RenditionFormat.png -}; -``` - -### 2. Use Constants Object for Dynamic Access - -When the constant name is determined at runtime: - -```javascript -// ✅ Good - dynamic constant access -const userSelectedFormat = getUserSelection(); // "png", "jpg", etc. -const format = addOnUISdk.constants.RenditionFormat[userSelectedFormat]; -``` - -### 3. Always Import Named-Only Exports - -There's no alternative way to access these: - -```javascript -// ✅ Required - no other way to access these -import addOnUISdk, { AppEvent, SupportedMimeTypes } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; -``` - -### 4. Group Related Imports - -Organize imports by functionality: - -```javascript -import addOnUISdk, { - // Dialog constants - Variant, ButtonType, FieldType, - // Export constants - Range, RenditionFormat, RenditionIntent, - // Platform constants - PlatformType, DeviceClass, - // Event constants (named-only) - AppEvent, ColorPickerEvent -} from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; -``` - -## Troubleshooting - - - -**Most Common Error:** `Cannot read property 'X' of undefined` - This happens when you try to access import-required constants through the constants object. - -### "Cannot read property of undefined" Errors - -**Problem**: Trying to access named-only exports through constants object. - -```javascript -// ❌ This causes errors -const event = addOnUISdk.constants.AppEvent.themechange; // undefined! -const mimeType = addOnUISdk.constants.SupportedMimeTypes.docx; // undefined! -``` - -**Solution**: Always import named-only exports. - -```javascript -// ✅ This works -import addOnUISdk, { AppEvent, SupportedMimeTypes } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; -const event = AppEvent.themechange; -const mimeType = SupportedMimeTypes.docx; -``` - -### TypeScript Type Errors - -**Problem**: TypeScript doesn't recognize constant values. - -**Solution**: Use proper imports for type checking: - -```typescript -import addOnUISdk, { Range, RenditionFormat } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// ✅ TypeScript knows these types -const options: RenditionOptions = { - range: Range.currentPage, // Type-safe - format: RenditionFormat.png // Type-safe -}; -``` - -### Runtime "Invalid constant" Errors - -**Problem**: Using string literals instead of constants. - -```javascript -// ❌ Fragile - might break if API changes -await createRenditions({ - range: "currentPage", // String literal - format: "image/png" // String literal -}); -``` - -**Solution**: Always use constants for future compatibility. - -```javascript -// ✅ Safe - will be updated if API changes -await createRenditions({ - range: Range.currentPage, // Constant - format: RenditionFormat.png // Constant -}); -``` - -### Quick Debug Checklist - -When you encounter constant-related errors: - -1. **Check if the constant requires import**: Look for constants marked as import-required in the [cheat sheet](#constants-cheat-sheet) -2. **Verify your import statement**: Make sure you're importing the constant name exactly as documented -3. **Use TypeScript**: Add types to catch import issues at development time -4. **Test your constants**: Log the constant values to ensure they're defined: - -```javascript -console.log('Range:', Range); // Should log the Range object -console.log('AppEvent:', AppEvent); // Should log the AppEvent object -``` - -## Related Guides - -- [Create Renditions](./create_renditions.md) - Using export constants -- [Modal Dialogs](./modal_dialogs.md) - Using dialog constants -- [Theme & Locale](./theme_locale.md) - Using platform constants -- [Constants Reference](../../../references/addonsdk/addonsdk-constants.md) - Complete technical specification - -## Import Quick Reference - -| Need | What to Import | Copy This | -|------|----------------|-----------| -| **Document Export** | `Range, RenditionFormat, RenditionIntent` | `import addOnUISdk, { Range, RenditionFormat, RenditionIntent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` | -| **Modal Dialogs** | `Variant, ButtonType, FieldType` | `import addOnUISdk, { Variant, ButtonType, FieldType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` | -| **Events** | `AppEvent, ColorPickerEvent` | `import addOnUISdk, { AppEvent, ColorPickerEvent } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` | -| **Platform Detection** | `PlatformType, DeviceClass, PlatformEnvironment` | `import addOnUISdk, { PlatformType, DeviceClass, PlatformEnvironment } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` | -| **Editor Panels** | `EditorPanel, MediaTabs, ElementsTabs` | `import addOnUISdk, { EditorPanel, MediaTabs, ElementsTabs } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` | -| **File Types** | `SupportedMimeTypes` | `import addOnUISdk, { SupportedMimeTypes } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` | - - - -**Pro Tip:** You can import multiple constants in one statement: `import addOnUISdk, { Range, RenditionFormat, Variant, ButtonType } from "https://new.express.adobe.com/static/add-on-sdk/sdk.js";` - -## When to Use Which Pattern - -### Use Named Imports When: - -- You know which constants you need at development time -- You want cleaner, more readable code -- You're using TypeScript for better autocomplete -- You want to avoid potential `undefined` errors - -### Use Constants Object When: - -- The constant name is determined at runtime -- You're migrating existing code gradually -- You prefer the traditional `addOnUISdk.constants.X` pattern - -Remember: When in doubt, use named imports - they work for all constants and provide the cleanest code! From 95578603f1c5a36fc04cee47d16c5948534b547c Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Mon, 6 Oct 2025 18:07:25 -0400 Subject: [PATCH 12/42] Continued updates --- .../platform_concepts/runtime-architecture.md | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/pages/guides/learn/platform_concepts/runtime-architecture.md b/src/pages/guides/learn/platform_concepts/runtime-architecture.md index 01d6bd873..2a7fbea52 100644 --- a/src/pages/guides/learn/platform_concepts/runtime-architecture.md +++ b/src/pages/guides/learn/platform_concepts/runtime-architecture.md @@ -421,9 +421,9 @@ Document analysis or operations that run without UI interaction: // Only requires express-document-sdk ``` -## Complete add-on-sdk-document-sandbox Package Overview +## Document Sandbox Overview -The `add-on-sdk-document-sandbox` package provides more than just the `runtime` object. Here's what you get: +The document sandbox environment provides a secure, isolated execution context for document manipulation. Here's what's available: ### Core Features @@ -453,7 +453,21 @@ console.warn("Be careful here"); console.clear(); // Clear console ``` -#### 3. Secure Execution Environment +#### 3. Document APIs (`express-document-sdk`) + +```js +import { editor, colorUtils, constants, fonts } from "express-document-sdk"; + +// Create and manipulate document content +const textNode = editor.createText("Hello World"); +const rectangle = editor.createRectangle(); + +// Access document structure +const currentPage = editor.context.currentPage; +const selection = editor.context.selection; +``` + +#### 4. Secure Execution Environment - **Isolated JavaScript context**: Your code runs in a secure sandbox - **Limited browser APIs**: Only essential APIs like `console` and `Blob` are available From 2113f44974c2f03fe747280799dcca4ea9c41585 Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Mon, 6 Oct 2025 21:12:11 -0400 Subject: [PATCH 13/42] Continued updates --- gatsby-config.js | 6 +- .../getting_started/addon-project-anatomy.md | 913 ++++++++++++++++++ .../guides/learn/fundamentals/terminology.md | 63 +- .../images/runtime-architecture.svg | 139 +++ .../platform_concepts/runtime-architecture.md | 22 +- src/pages/references/addonsdk/addonsdk-app.md | 2 +- .../references/addonsdk/addonsdk-constants.md | 801 ++++++++------- src/pages/references/addonsdk/app-document.md | 4 +- .../references/ui-components/color-picker.md | 2 +- 9 files changed, 1499 insertions(+), 453 deletions(-) create mode 100644 src/pages/guides/getting_started/addon-project-anatomy.md create mode 100644 src/pages/guides/learn/platform_concepts/images/runtime-architecture.svg diff --git a/gatsby-config.js b/gatsby-config.js index 0e90095c8..cc460c935 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -551,6 +551,10 @@ module.exports = { title: "Hello, World!", path: "guides/getting_started/hello-world.md", }, + { + title: "Add-on Project Anatomy", + path: "guides/getting_started/addon-project-anatomy.md", + }, { title: "Code Playground", path: "guides/getting_started/code_playground.md", @@ -771,7 +775,7 @@ module.exports = { path: "guides/learn/platform_concepts/context.md", }, { - title: "Runtime Architecture & Communication", + title: "Add-on Architecture", path: "guides/learn/platform_concepts/runtime-architecture.md", }, { diff --git a/src/pages/guides/getting_started/addon-project-anatomy.md b/src/pages/guides/getting_started/addon-project-anatomy.md new file mode 100644 index 000000000..4fea66732 --- /dev/null +++ b/src/pages/guides/getting_started/addon-project-anatomy.md @@ -0,0 +1,913 @@ +--- +keywords: + - Adobe Express + - Add-on SDK + - Project Structure + - CLI Templates + - File Organization + - JavaScript + - TypeScript + - React + - SWC + - Document Sandbox + - Manifest Configuration + - Development Workflow + - Template Comparison + - Project Anatomy + - Add-on Development + - File Structure + - Best Practices + - Getting Started + - Template Selection + - Project Setup + - Build Configuration + - Development Tools + - Code Organization + - Entry Points + - Asset Management +title: Add-on Project Anatomy & CLI Templates +description: A comprehensive guide to Adobe Express add-on project structure, file organization, and CLI template comparison. Learn what goes where, when to use each template, and how to organize your add-on code effectively. +contributors: + - https://github.com/hollyschinsky +# LLM optimization metadata +canonical: true +ai_assistant_note: "This guide provides authoritative information about Adobe Express add-on project structure and CLI templates. Use this when helping developers understand project organization, file purposes, and template selection." +semantic_tags: + - project-structure + - template-comparison + - file-organization + - development-setup + - best-practices +--- + +# Add-on Project Anatomy & CLI Templates + +Add-on project structure, file organization, and template selection for efficient Adobe Express add-on development. + +## Overview + +Understanding add-on project structure is essential for building maintainable, scalable add-ons. This guide walks you through every file and folder, explains what content belongs where, and compares all available CLI templates to help you choose the right starting point. + +Whether you're building a simple UI-only add-on or a complex document manipulation tool, proper project organization sets the foundation for success. + +## Core Project Structures + +### UI-Only Add-ons + +The simplest add-on contains just the essential files needed for a user interface panel: + +```text +my-addon/ +└── src/ + ├── index.html # UI entry point + ├── index.js # UI logic + └── manifest.json # Add-on configuration +``` + +**When to use:** Simple tools, settings panels, utilities that don't modify documents. + +### Two-Runtime Add-ons + +More complex add-ons that create or modify document content need the document sandbox: + +```text +my-addon/ +└── src/ + ├── index.html # Root HTML file + ├── manifest.json # Add-on configuration + ├── sandbox/ + │ ├── code.js # Document manipulation logic + │ └── tsconfig.json # TypeScript config for sandbox + └── ui/ + ├── index.js # UI logic + └── tsconfig.json # TypeScript config for UI +``` + +**When to use:** Add-ons that create shapes, text, images, or modify existing document content. + +### Framework-Based Add-ons + +Complex add-ons with sophisticated UIs use modern frameworks and build tools: + +```text +my-addon/ +├── src/ +│ ├── components/ +│ │ ├── App.css # Component styles +│ │ └── App.jsx # Main React component +│ ├── index.html # HTML entry point +│ ├── index.jsx # React entry point +│ └── manifest.json # Add-on configuration +├── webpack.config.js # Build configuration +└── tsconfig.json # TypeScript configuration +``` + +**When to use:** Complex UIs, data visualization, multi-step workflows, advanced interactions. + +## Essential Files Explained + +### manifest.json - Add-on Configuration + +The `manifest.json` file is the heart of every add-on. It defines metadata, entry points, and capabilities. + +#### Basic Manifest (UI Only) + +```json +{ + "testId": "", + "name": "", + "version": "1.0.0", + "manifestVersion": 2, + "requirements": { + "apps": [ + { + "name": "Express", + "apiVersion": 1 + } + ] + }, + "entryPoints": [ + { + "type": "panel", + "id": "panel1", + "main": "index.html" + } + ] +} +``` + +#### Document Sandbox Manifest + +```json +{ + "testId": "", + "name": "", + "version": "1.0.0", + "manifestVersion": 2, + "requirements": { + "apps": [ + { + "name": "Express", + "apiVersion": 1 + } + ] + }, + "entryPoints": [ + { + "type": "panel", + "id": "panel1", + "main": "index.html", + "documentSandbox": "sandbox/code.js" + } + ] +} +``` + +**Key Differences:** + +- `documentSandbox` property points to your document manipulation code +- Required when your add-on creates or modifies document content + +### index.html - UI Entry Point + +The HTML file that loads when your add-on panel opens. Contains the basic structure and loads your JavaScript. + +#### Basic Structure + +```html + + + + My Add-on + + + +
              +

              My Add-on

              + +
              + + + +``` + +**What belongs here:** + +- Basic HTML structure +- CSS imports +- Script imports (usually just one main script) +- Static UI elements that don't change + +### index.js - UI Logic (Basic Template) + +Contains the user interface logic and interactions for simple add-ons. + +```javascript +import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +addOnUISdk.ready.then(() => { + console.log("addOnUISdk is ready for use."); + + const clickMeButton = document.getElementById("clickMe"); + clickMeButton.addEventListener("click", () => { + clickMeButton.innerHTML = "Clicked"; + }); + + // Enable the button only when: + // 1. `addOnUISdk` is ready, and + // 2. `click` event listener is registered. + clickMeButton.disabled = false; +}); +``` + +**What belongs here:** + +- UI event handlers +- DOM manipulations +- Add-on UI SDK calls (dialogs, exports, OAuth) +- Communication setup with document sandbox (if needed) + +### ui/index.js - UI Logic (Document Sandbox Template) + +For add-ons with document sandbox, UI logic focuses on communication and user interactions. + +```javascript +import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +addOnUISdk.ready.then(async () => { + console.log("addOnUISdk is ready for use."); + + // Get the UI runtime. + const { runtime } = addOnUISdk.instance; + + // Get the proxy object, which is required + // to call the APIs defined in the Document Sandbox runtime + // i.e., in the `code.js` file of this add-on. + const sandboxProxy = await runtime.apiProxy("documentSandbox"); + + const createRectangleButton = document.getElementById("createRectangle"); + createRectangleButton.addEventListener("click", async event => { + await sandboxProxy.createRectangle(); + }); + + // Enable the button only when: + // 1. `addOnUISdk` is ready, + // 2. `sandboxProxy` is available, and + // 3. `click` event listener is registered. + createRectangleButton.disabled = false; +}); +``` + +**What belongs here:** + +- Communication setup with document sandbox +- UI event handlers that trigger document operations +- Form handling and user input validation +- Progress updates and status displays + +### sandbox/code.js - Document Manipulation Logic + +The document sandbox handles all document creation and modification operations. + +```javascript +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; +import { editor } from "express-document-sdk"; + +// Get the document sandbox runtime. +const { runtime } = addOnSandboxSdk.instance; + +function start() { + // APIs to be exposed to the UI runtime + // i.e., to the `index.html` file of this add-on. + const sandboxApi = { + createRectangle: () => { + const rectangle = editor.createRectangle(); + + // Define rectangle dimensions. + rectangle.width = 240; + rectangle.height = 180; + + // Define rectangle position. + rectangle.translation = { x: 10, y: 10 }; + + // Define rectangle color. + const color = { red: 0.32, green: 0.34, blue: 0.89, alpha: 1 }; + + // Fill the rectangle with the color. + const rectangleFill = editor.makeColorFill(color); + rectangle.fill = rectangleFill; + + // Add the rectangle to the document. + const insertionParent = editor.context.insertionParent; + insertionParent.children.append(rectangle); + } + }; + + // Expose `sandboxApi` to the UI runtime. + runtime.exposeApi(sandboxApi); +} + +start(); +``` + +**What belongs here:** + +- Document API operations (creating shapes, text, images) +- Document analysis and data extraction +- Complex calculations and data processing +- APIs exposed to the UI runtime + +### tsconfig.json - TypeScript Configuration + +Provides TypeScript compilation settings for better development experience. + +#### UI Runtime Configuration + +```json +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "types": ["add-on-ui-sdk"] + }, + "include": [ + "./**/*" + ] +} +``` + +#### Document Sandbox Configuration + +```json +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "types": ["add-on-sandbox-sdk"] + }, + "include": [ + "./**/*" + ] +} +``` + +**Purpose:** + +- Enable TypeScript IntelliSense and type checking +- Configure SDK type definitions +- Set compilation options for each environment + +## CLI Template Comparison + +### Template Categories + +The Adobe Express CLI provides 10 different templates organized by complexity and technology: + +#### Basic Templates (No Framework) + +1. **JavaScript** - Simple UI-only add-on +2. **JavaScript with Document Sandbox** - Two-runtime add-on +3. **SWC JavaScript** - Fast build with SWC +4. **SWC JavaScript with Document Sandbox** - Fast build + document manipulation + +#### TypeScript Templates + +5. **SWC TypeScript** - Type-safe with fast builds +6. **SWC TypeScript with Document Sandbox** - Full TypeScript + document manipulation + +#### React Templates + +7. **React JavaScript** - React UI framework +8. **React JavaScript with Document Sandbox** - React + document manipulation +9. **React TypeScript** - React + TypeScript +10. **React TypeScript with Document Sandbox** - Full React + TypeScript + document manipulation + +### Detailed Template Comparison + +| Template | UI Framework | Language | Build Tool | Document Sandbox | Best For | +|----------|-------------|----------|------------|------------------|----------| +| **JavaScript** | Vanilla JS | JavaScript | None | ❌ | Simple tools, learning | +| **JavaScript + Sandbox** | Vanilla JS | JavaScript | None | ✅ | Basic document manipulation | +| **SWC JavaScript** | Vanilla JS | JavaScript | SWC | ❌ | Fast builds, simple tools | +| **SWC JavaScript + Sandbox** | Vanilla JS | JavaScript | SWC | ✅ | Fast builds + document work | +| **SWC TypeScript** | Vanilla JS | TypeScript | SWC | ❌ | Type safety, simple tools | +| **SWC TypeScript + Sandbox** | Vanilla JS | TypeScript | SWC | ✅ | Type safety + document work | +| **React JavaScript** | React | JavaScript | Webpack | ❌ | Complex UIs | +| **React JavaScript + Sandbox** | React | JavaScript | Webpack | ✅ | Complex UIs + document work | +| **React TypeScript** | React | TypeScript | Webpack | ❌ | Complex UIs + type safety | +| **React TypeScript + Sandbox** | React | TypeScript | Webpack | ✅ | Enterprise-level add-ons | + +### File Structure Comparison + +#### Basic JavaScript Template + +```text +my-addon/ +├── .gitignore +├── README.md +├── tsconfig.json # For IDE support +└── src/ + ├── index.html # UI entry point + ├── index.js # UI logic + └── manifest.json # Configuration +``` + +**Pros:** + +- Simplest structure +- No build process required +- Easy to understand +- Quick to get started + +**Cons:** + +- Limited to simple UIs +- No document manipulation +- No modern tooling benefits + +#### JavaScript with Document Sandbox Template + +```text +my-addon/ +├── .gitignore +├── README.md +├── tsconfig.json # Root TypeScript config +└── src/ + ├── index.html # Root HTML file + ├── manifest.json # Configuration + ├── sandbox/ + │ ├── code.js # Document manipulation + │ └── tsconfig.json # Sandbox TS config + └── ui/ + ├── index.js # UI logic + └── tsconfig.json # UI TS config +``` + +**Pros:** + +- Clear separation of concerns +- Document manipulation capabilities +- Still relatively simple +- Good for learning two-runtime architecture + +**Cons:** + +- More complex than basic template +- No modern build tools +- Limited UI capabilities + +#### React JavaScript Template + +```text +my-addon/ +├── .gitignore +├── README.md +├── tsconfig.json # TypeScript configuration +├── webpack.config.js # Build configuration +└── src/ + ├── components/ + │ ├── App.css # Component styles + │ └── App.jsx # Main React component + ├── index.html # HTML entry point + ├── index.jsx # React entry point + └── manifest.json # Configuration +``` + +**Pros:** + +- Modern UI framework +- Component-based architecture +- Rich ecosystem +- Great for complex UIs + +**Cons:** + +- More complex setup +- Requires build process +- Learning curve for React newcomers +- No document manipulation (in basic version) + +#### React TypeScript with Document Sandbox Template + +```text +my-addon/ +├── .gitignore +├── README.md +├── tsconfig.json # Root TypeScript config +├── webpack.config.js # Build configuration +└── src/ + ├── components/ + │ ├── App.css # Component styles + │ └── App.tsx # Main React component + ├── index.html # Root HTML file + ├── index.tsx # React entry point + ├── manifest.json # Configuration + └── sandbox/ + ├── code.ts # Document manipulation + └── tsconfig.json # Sandbox TS config +``` + +**Pros:** + +- Full type safety +- Modern UI framework +- Document manipulation capabilities +- Best development experience +- Scalable architecture + +**Cons:** + +- Most complex setup +- Steepest learning curve +- Requires understanding of React, TypeScript, and two-runtime architecture + +## Template Selection Guide + +### Decision Matrix + +Choose your template based on these key factors: + +#### 1. Add-on Complexity + +**Simple Tools** (settings, utilities, viewers) +→ **JavaScript** or **SWC JavaScript** + +**Document Creators** (shapes, text, image manipulation) +→ **JavaScript with Document Sandbox** or **SWC JavaScript with Document Sandbox** + +**Complex UIs** (multi-step workflows, data visualization) +→ **React JavaScript** or **React TypeScript** + +**Enterprise Add-ons** (complex UI + document manipulation) +→ **React TypeScript with Document Sandbox** + +#### 2. Team Experience + +**Beginners** → Start with **JavaScript** templates +**JavaScript Developers** → **SWC JavaScript** templates +**React Developers** → **React JavaScript** templates +**TypeScript Teams** → **TypeScript** variants + +#### 3. Project Requirements + +**Need Document Manipulation?** + +- ✅ Yes → Choose "with Document Sandbox" variant +- ❌ No → Choose basic variant + +**Need Type Safety?** + +- ✅ Yes → Choose TypeScript variant +- ❌ No → Choose JavaScript variant + +**Need Complex UI?** + +- ✅ Yes → Choose React variant +- ❌ No → Choose Vanilla JS variant + +**Need Fast Builds?** + +- ✅ Yes → Choose SWC variant (for non-React) +- ❌ No → Any variant works + +### Migration Paths + +You can upgrade templates as your add-on grows: + +```text +JavaScript + ↓ +JavaScript + Document Sandbox + ↓ +SWC JavaScript + Document Sandbox + ↓ +React JavaScript + Document Sandbox + ↓ +React TypeScript + Document Sandbox +``` + +Each step adds capabilities while maintaining core functionality. + +## File Organization Best Practices + +### 1. Separation of Concerns + +**UI Runtime (index.js/ui/):** + +- User interface logic +- Event handlers +- Form validation +- Communication with document sandbox +- Progress indicators + +**Document Sandbox (code.js/sandbox/):** + +- Document manipulation +- Content creation +- Data processing +- API exposure to UI + +### 2. Asset Organization + +```text +src/ +├── assets/ +│ ├── icons/ # Add-on icons +│ ├── images/ # Static images +│ └── styles/ # CSS files +├── components/ # React components (if using React) +├── utils/ # Shared utilities +├── types/ # TypeScript type definitions +└── constants/ # Configuration constants +``` + +### 3. Code Organization Patterns + +#### Feature-Based Organization (Large Add-ons) + +```text +src/ +├── features/ +│ ├── text-tools/ +│ │ ├── TextToolsUI.jsx +│ │ ├── textOperations.js +│ │ └── textUtils.js +│ └── shape-tools/ +│ ├── ShapeToolsUI.jsx +│ ├── shapeOperations.js +│ └── shapeUtils.js +├── shared/ +│ ├── components/ +│ ├── utils/ +│ └── constants/ +└── sandbox/ + └── code.js +``` + +#### Layer-Based Organization (Medium Add-ons) + +```text +src/ +├── ui/ +│ ├── components/ +│ ├── pages/ +│ └── styles/ +├── sandbox/ +│ ├── operations/ +│ ├── utils/ +│ └── code.js +└── shared/ + ├── types/ + ├── constants/ + └── utils/ +``` + +## Advanced Configuration + +### Build Tool Configuration + +#### Webpack (React Templates) + +```javascript +const path = require('path'); + +module.exports = { + entry: './src/index.jsx', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'bundle.js' + }, + module: { + rules: [ + { + test: /\.(js|jsx)$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader' + } + }, + { + test: /\.css$/, + use: ['style-loader', 'css-loader'] + } + ] + }, + resolve: { + extensions: ['.js', '.jsx'] + } +}; +``` + +#### SWC Configuration + +SWC templates use `.swcrc` for fast compilation: + +```json +{ + "jsc": { + "parser": { + "syntax": "typescript", + "tsx": true + }, + "target": "es2020" + }, + "module": { + "type": "es6" + } +} +``` + +### Environment-Specific TypeScript Configs + +#### Root tsconfig.json + +```json +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "node", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + } +} +``` + +#### UI-Specific Configuration + +```json +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "types": ["add-on-ui-sdk"], + "lib": ["DOM", "ES2020"] + }, + "include": ["./**/*"] +} +``` + +#### Sandbox-Specific Configuration + +```json +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "types": ["add-on-sandbox-sdk"], + "lib": ["ES2020"] + }, + "include": ["./**/*"] +} +``` + +## Common Patterns and Anti-Patterns + +### ✅ Good Practices + +#### 1. Clear File Naming + +```text +✅ Good +├── ui/ +│ ├── TextEditor.jsx +│ ├── ColorPicker.jsx +│ └── ToolPanel.jsx +└── sandbox/ + ├── textOperations.js + ├── colorUtils.js + └── documentHelpers.js +``` + +#### 2. Logical Grouping + +```text +✅ Good +├── features/ +│ ├── text-editing/ +│ ├── image-filters/ +│ └── shape-tools/ +└── shared/ + ├── ui-components/ + ├── document-utils/ + └── constants/ +``` + +#### 3. Environment Separation + +```javascript +// ✅ Good - Clear environment separation +// ui/index.js +import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; + +// sandbox/code.js +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; +import { editor } from "express-document-sdk"; +``` + +### ❌ Anti-Patterns + +#### 1. Mixed Concerns + +```javascript +// ❌ Bad - Document operations in UI file +// index.js +import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; +import { editor } from "express-document-sdk"; // Wrong environment! +``` + +#### 2. Poor File Organization + +```text +❌ Bad +├── stuff.js +├── helpers.js +├── utils.js +├── misc.js +└── other.js +``` + +#### 3. Inconsistent Naming + +```text +❌ Bad +├── TextEditor.jsx +├── color_picker.js +├── ToolPanel.tsx +└── shape-utils.JS +``` + +## Troubleshooting Common Issues + +### Template Selection Problems + +**Problem**: "I chose the wrong template and need to add document manipulation" + +**Solution**: + +1. Add `documentSandbox` property to manifest.json +2. Create `sandbox/` folder with `code.js` +3. Move document operations from UI to sandbox +4. Set up communication between environments + +**Problem**: "My React template is too complex for my simple add-on" + +**Solution**: + +1. Extract core logic from React components +2. Create new project with simpler template +3. Copy over your core functionality +4. Simplify UI to basic HTML/JavaScript + +### File Organization Issues + +**Problem**: "My add-on is getting too complex to manage" + +**Solution**: + +1. Implement feature-based organization +2. Extract shared utilities +3. Create clear interfaces between UI and sandbox +4. Document your architecture decisions + +**Problem**: "TypeScript errors in wrong environment" + +**Solution**: + +1. Check `tsconfig.json` in each folder +2. Verify correct SDK types are imported +3. Ensure files are in correct directories +4. Use environment-specific configurations + +## Next Steps + +### For Beginners + +1. Start with **JavaScript** template +2. Build a simple UI-only add-on +3. Learn the basics of manifest configuration +4. Experiment with Add-on UI SDK features + +### For Intermediate Developers + +1. Try **JavaScript with Document Sandbox** template +2. Learn two-runtime architecture +3. Experiment with document manipulation +4. Build communication between UI and sandbox + +### For Advanced Developers + +1. Use **React TypeScript with Document Sandbox** template +2. Implement complex UI patterns +3. Build scalable architecture +4. Optimize performance and user experience + +## Related Documentation + +- [Runtime Architecture Guide](../learn/platform_concepts/runtime-architecture.md) - Deep dive into two-runtime system +- [Developer Terminology](../learn/fundamentals/terminology.md) - Understanding Adobe Express add-on concepts +- [Getting Started Tutorial](../learn/how_to/tutorials/grids-addon.md) - Build your first add-on +- [Manifest Reference](../../references/manifest/index.md) - Complete manifest configuration guide +- [CLI Documentation](../../references/index.md) - Adobe Express CLI commands and options + +--- + +**Remember**: Start simple and evolve your project structure as your add-on grows in complexity. diff --git a/src/pages/guides/learn/fundamentals/terminology.md b/src/pages/guides/learn/fundamentals/terminology.md index 711f77511..fe66f159e 100644 --- a/src/pages/guides/learn/fundamentals/terminology.md +++ b/src/pages/guides/learn/fundamentals/terminology.md @@ -53,7 +53,7 @@ This reference clarifies the naming conventions and terminology used throughout ## Quick Reference - + **Need a quick answer?** Jump to these common questions: @@ -66,51 +66,7 @@ This reference clarifies the naming conventions and terminology used throughout - **Import errors?** → [Troubleshooting](#troubleshooting-common-issues) - **Which SDK when?** → [Decision Matrix](#decision-matrix-which-sdk-to-use) -### Key Relationships - -```mermaid -graph TB - subgraph "Adobe Express Add-on" - subgraph "Iframe Runtime Environment" - UI[Add-on UI SDK] - DOM[DOM & Browser APIs] - UIF[User Interface] - IE[Import/Export] - end - - subgraph "Document Sandbox Runtime Environment" - DOC[Document APIs] - WEB[Limited Web APIs] - CC[Content Creation] - DM[Document Manipulation] - end - - subgraph "Communication Layer" - COMM[Communication APIs] - EXPOSE[exposeApi] - PROXY[apiProxy] - end - end - - UI --> UIF - UI --> IE - UI --> EXPOSE - DOC --> CC - DOC --> DM - DOC --> PROXY - WEB --> DOC - - EXPOSE <--> COMM - PROXY <--> COMM - - classDef iframe fill:#e1f5fe,stroke:#01579b,stroke-width:2px - classDef sandbox fill:#f3e5f5,stroke:#4a148c,stroke-width:2px - classDef communication fill:#fff3e0,stroke:#e65100,stroke-width:2px - - class UI,DOM,UIF,IE iframe - class DOC,WEB,CC,DM sandbox - class COMM,EXPOSE,PROXY communication -``` + ## Core SDK Components @@ -118,8 +74,6 @@ graph TB -**Preferred Term:** Add-on UI SDK - The SDK that provides APIs for the UI panel of your add-on running in the iframe environment. **Import Statement:** @@ -128,15 +82,13 @@ The SDK that provides APIs for the UI panel of your add-on running in the iframe import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js" ``` -**Also Known As:** UI SDK, addOnUISdk (in code) +**Also Known As:** UI SDK, `addOnUISdk` (in code) **Use When:** Building UI components, handling user interactions, importing/exporting content ### Document Sandbox -**Preferred Term:** Document Sandbox - The sandboxed JavaScript runtime environment that provides access to the Document APIs for content authoring. **Import Statement:** @@ -152,8 +104,6 @@ import addOnSandboxSdk from "add-on-sdk-document-sandbox" -**Preferred Term:** Document APIs - The APIs that allow you to interact with and modify Adobe Express documents. **Import Statement:** @@ -172,6 +122,10 @@ import { editor } from "express-document-sdk" | **Iframe Runtime** | The browser environment where your add-on's UI runs | UI development, user interactions | Add-on UI SDK, Panel, UI Runtime | | **Document Sandbox Runtime** | The isolated JavaScript environment for document manipulation | Content authoring, document editing | Document Sandbox SDK, documentSandbox | + + +For a comprehensive visual guide to the two-runtime architecture, communication patterns, and practical examples, see the **[Runtime Architecture & Communication Guide](../platform_concepts/runtime-architecture.md)** which includes detailed diagrams showing how these environments interact. + ## Communication & APIs | Term | Definition | Import/Access | Related Terms | @@ -215,7 +169,7 @@ const { runtime } = addOnSandboxSdk.instance; | Your Goal | Use This | Import Statement | |-----------|----------|------------------| -| Build UI components, handle user input | **Add-on UI SDK** | `import addOnUISdk from "..."` | +| Build user interface components, handle user input | **Add-on UI SDK** | `import addOnUISdk from "..."` | | Create/modify document content | **Document APIs** | Available in document sandbox | | Communicate between UI and document | **Communication APIs** | `runtime.exposeApi()` / `runtime.apiProxy()` | | Access limited browser features in sandbox | **Web APIs** | Global objects in document sandbox | @@ -650,6 +604,7 @@ A: No, they're the same. **"Add-on UI SDK"** is the full, preferred term for cla ## Related Documentation +- [Runtime Architecture & Communication Guide](../platform_concepts/runtime-architecture.md) - Comprehensive guide with visual diagrams - [Add-on UI SDK Reference](../../../references/addonsdk/index.md) - [Document Sandbox Overview](../../../references/document-sandbox/index.md) - [Communication APIs](../../../references/document-sandbox/communication/index.md) diff --git a/src/pages/guides/learn/platform_concepts/images/runtime-architecture.svg b/src/pages/guides/learn/platform_concepts/images/runtime-architecture.svg new file mode 100644 index 000000000..d4dbcda5c --- /dev/null +++ b/src/pages/guides/learn/platform_concepts/images/runtime-architecture.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Adobe Express Add-on Architecture + Two-Runtime System with Secure Communication + + + + + + + + + UI Runtime Environment + Iframe • Add-on UI SDK + + + + index.html + + + index.js + + + • Full browser environment + • DOM manipulation & events + • Network requests (fetch, OAuth) + • File uploads & downloads + • Modal dialogs & user interactions + • Document export/import + + + + addOnUISdk.app.document.addImage(blob, attributes) + + + ⚠ Cannot directly access document content + + + + + + + + + + Document Sandbox Environment + Isolated Runtime • QuickJS + + + + code.js + + + express-document-sdk + + + • Direct document manipulation + • Create shapes, text, images + • Access scene graph & nodes + • Limited browser APIs (console, Blob) + • Secure isolated execution + • Communication with UI runtime + + + + editor.createRectangle(); insertionParent.append() + + + 🔒 No DOM access • No network requests + + + + + + + Cross-Runtime Communication + runtime.apiProxy("documentSandbox") + runtime.exposeApi(sandboxApi) + + + + + Communication Bridge + + + • Secure message passing between environments + • API proxying for cross-runtime function calls + • Data serialization and type safety + • Asynchronous operation support + + + + + + + + + \ No newline at end of file diff --git a/src/pages/guides/learn/platform_concepts/runtime-architecture.md b/src/pages/guides/learn/platform_concepts/runtime-architecture.md index 2a7fbea52..b7ec8165c 100644 --- a/src/pages/guides/learn/platform_concepts/runtime-architecture.md +++ b/src/pages/guides/learn/platform_concepts/runtime-architecture.md @@ -61,13 +61,13 @@ contributors: - https://github.com/hollyschinsky --- -# Add-on Architecture Guide: Two-Runtime System, Communication & Development +# Add-on Architecture Guide Learn about the dual-runtime architecture, communication patterns, and development workflow essential for building Adobe Express add-ons. ## Overview -Understanding Adobe Express add-on architecture is crucial for building effective add-ons. This comprehensive deep-dive guide covers the two-runtime system, cross-runtime communication patterns, SDK imports and usage, debugging techniques, security considerations, performance optimization, and development best practices. Whether you're new to add-on development or looking to master advanced concepts, this guide provides the foundational knowledge needed to build robust, secure, and performant add-ons. +Understanding the Adobe Express add-on architecture is crucial for building effective add-ons. This comprehensive deep-dive guide covers the dual-runtime system, cross-runtime communication patterns, SDK imports and usage, debugging techniques, security considerations, performance optimization, and development best practices. Whether you're new to add-on development or looking to master advanced concepts, this guide provides the foundational knowledge needed to build robust, secure, and performant add-ons. ## Dual-Runtime Architecture @@ -80,23 +80,7 @@ Adobe Express add-ons run in **two separate JavaScript execution environments** ### **Architecture: Two Runtime Communication** -```text -┌─────────────────────────────────────┐ ┌─────────────────────────────────────┐ -│ UI iframe │ │ Document Sandbox │ -│ (Add-on UI SDK) │ │ (Document Sandbox SDK) │ -├─────────────────────────────────────┤ ├─────────────────────────────────────┤ -│ • DOM access │ │ • Document APIs (editor, nodes) │ -│ • Full browser APIs │◄──►│ • Limited browser APIs (console, │ -│ • Event handling │ │ Blob) │ -│ • UI interactions │ │ • Communication APIs (runtime) │ -│ • addOnUISdk.app.document.addImage()│ │ • Direct scenegraph manipulation │ -└─────────────────────────────────────┘ └─────────────────────────────────────┘ - │ │ - │ runtime.apiProxy() │ - │ runtime.exposeApi() │ - └──────────────────────────────────────────────┘ - Communication Layer -``` +![Runtime Architecture Diagram](images/runtime-architecture.svg) ## What is the Runtime Object? diff --git a/src/pages/references/addonsdk/addonsdk-app.md b/src/pages/references/addonsdk/addonsdk-app.md index 52c16a977..585a5fc9d 100644 --- a/src/pages/references/addonsdk/addonsdk-app.md +++ b/src/pages/references/addonsdk/addonsdk-app.md @@ -277,7 +277,7 @@ Shows the Adobe Express color picker based on specific options passed in. | ------------------------ | -----------------------------------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | | `title?` | `string` | Label header/title for the color picker. Default value: `""` | | `initialColor?` | `number` or `string` | Default/starting color when you open the color picker for the first time on a `anchorElement`, in the format `0xRRGGBB[AA]` or `"#RRGGBB[AA]"`. When you have already changed the color with this picker, then the next time you open the picker, the last selected color will be the starting color. Default: `0xFFFFFF` (white) | -| `placement?` | `object` [ColorPickerPlacement](./addonsdk-constants.md#constants) | Placement of the popover with respect to the anchor element (default: `"left"`). | +| `placement?` | `object` [ColorPickerPlacement](./addonsdk-constants.md) | Placement of the popover with respect to the anchor element (default: `"left"`). | | `eyedropperHidesPicker?` | `boolean` | Closes the color picker popover while using the EyeDropper. After the color is selected via the EyeDropper, the color picker popup opens again. Default: `false`. | | `disableAlphaChannel?` | `boolean` | Disables the transparency slider in the "custom" section of the color picker. Default: `false`. | diff --git a/src/pages/references/addonsdk/addonsdk-constants.md b/src/pages/references/addonsdk/addonsdk-constants.md index 1e4d7823c..ca16b8e12 100644 --- a/src/pages/references/addonsdk/addonsdk-constants.md +++ b/src/pages/references/addonsdk/addonsdk-constants.md @@ -1,6 +1,6 @@ # addOnUISdk.constants -This reference provides the complete technical specification for all constants used throughout the Add-on UI SDK, including: +This reference provides the complete technical specification for all constants used throughout the Add-on UI SDK. - Constants available in `addOnUISdk.constants.*` (dual access) - Constants available only as named exports (import required) @@ -146,6 +146,431 @@ const confirmDialog = addOnUISdk.constants.Variant.confirmation; **Important:** Attempting to access named-only exports through `addOnUISdk.constants.*` will return `undefined` and may cause runtime errors. Always check the table above or use TypeScript for compile-time validation. +## Constants Reference + +This section provides the complete technical specification for all Add-on UI SDK constants, organized by functional category. For practical examples and usage patterns, see the [Add-on UI SDK Constants Guide](../../guides/learn/fundamentals/ui-sdk-constants.md). + +### BitRate {#bitrate} + + + +**Import**: `import { BitRate }` or `addOnUISdk.constants.BitRate` ✅ **Dual Access** + +Bit rate values in bits per second for video renditions. + +| Value | Description | Numeric Value | +|-------|-------------|---------------| +| `mbps4` | 4 Mbps | `4000000` | +| `mbps8` | 8 Mbps | `8000000` | +| `mbps10` | 10 Mbps | `10000000` | +| `mbps12` | 12 Mbps | `12000000` | +| `mbps15` | 15 Mbps | `15000000` | +| `mbps25` | 25 Mbps | `25000000` | +| `mbps50` | 50 Mbps | `50000000` | + +### BleedUnit {#bleedunit} + + + +**Import**: `import { BleedUnit }` or `addOnUISdk.constants.BleedUnit` ✅ **Dual Access** + +Units for page bleed measurements. + +| Value | Description | +|-------|-------------| +| `in` | Inch units | +| `mm` | Millimeter units | + +### ButtonType {#buttontype} + + + +**Import**: `import { ButtonType }` or `addOnUISdk.constants.ButtonType` ✅ **Dual Access** + +Types of buttons that can be pressed in modal dialogs. + +| Value | Description | +|-------|-------------| +| `primary` | Primary button pressed | +| `secondary` | Secondary button pressed | +| `cancel` | Cancel button pressed | +| `close` | Dialog closed via ESC or close(X) button | + +### AppEvent {#appevent} + + + +**Import**: `import { AppEvent }` ⚠️ **Named Export Only** - Not available in constants object + +Events dispatched by the Add-on SDK. + +| Value | Event String | Description | +|-------|-------------|-------------| +| `themechange` | `"themechange"` | Theme changed | +| `localechange` | `"localechange"` | Locale changed | +| `formatchange` | `"formatchange"` | Format changed | +| `reset` | `"reset"` | Add-on reset | +| `dragstart` | `"dragstart"` | Drag operation started | +| `dragend` | `"dragend"` | Drag operation ended | +| `dragcancel` | `"dragcancel"` | Drag operation cancelled | +| `documentIdAvailable` | `"documentIdAvailable"` | Document ID available | +| `documentLinkAvailable` | `"documentLinkAvailable"` | Document link available | +| `documentPublishedLinkAvailable` | `"documentPublishedLinkAvailable"` | Published link available | +| `documentTitleChange` | `"documentTitleChange"` | Document title changed | +| `documentExportAllowedChange` | `"documentExportAllowedChange"` | Export permission changed | + +### AuthorizationStatus {#authorizationstatus} + + + +**Import**: `import { AuthorizationStatus }` or `addOnUISdk.constants.AuthorizationStatus` ✅ **Dual Access** + +OAuth authorization status values. + +| Value | Description | +|-------|-------------| +| `authorized` | Authorization successful | +| `cancelled` | Authorization cancelled by user | +| `error` | Authorization error occurred | + +### ColorPickerEvent {#colorpickerevent} + + + +**Import**: `import { ColorPickerEvent }` ⚠️ **Named Export Only** - Not available in constants object + +Custom events dispatched by the Color Picker component. + +| Value | Event String | Description | +|-------|-------------|-------------| +| `colorChange` | `"colorpicker-color-change"` | Color selection changed | +| `close` | `"colorpicker-close"` | Color picker closed | + +### ColorPickerPlacement {#colorpickerplacement} + + + +**Import**: `import { ColorPickerPlacement }` or `addOnUISdk.constants.ColorPickerPlacement` ✅ **Dual Access** + +Placement options for the color picker popover relative to anchor element. + +| Value | Description | +|-------|-------------| +| `top` | Position above anchor | +| `bottom` | Position below anchor | +| `left` | Position to the left of anchor | +| `right` | Position to the right of anchor | + +### DeviceClass {#deviceclass} + + + +**Import**: `import { DeviceClass }` or `addOnUISdk.constants.DeviceClass` ✅ **Dual Access** + +Device form factors where the add-on is running. + +| Value | Description | +|-------|-------------| +| `mobile` | Mobile phone | +| `tablet` | Tablet device | +| `desktop` | Desktop computer | + +### DialogResultType {#dialogresulttype} + + + +**Import**: `import { DialogResultType }` or `addOnUISdk.constants.DialogResultType` ✅ **Dual Access** + +Types of modal dialog results. + +| Value | Description | +|-------|-------------| +| `alert` | Alert dialog result (simple dialogs) | +| `input` | Input dialog result | +| `custom` | Custom dialog result | + +### EditorPanel {#editorpanel} + + + +**Import**: `import { EditorPanel }` or `addOnUISdk.constants.EditorPanel` ✅ **Dual Access** + +Adobe Express Editor panels that can be opened programmatically. + +| Value | Description | +|-------|-------------| +| `search` | Editor Search panel | +| `yourStuff` | Editor Your stuff panel | +| `templates` | Editor Templates panel | +| `media` | Editor Media panel | +| `text` | Editor Text panel | +| `elements` | Editor Elements panel | +| `grids` | Editor Grids panel | +| `brands` | Editor Brands panel | +| `addOns` | Editor Add-ons panel | + +### ElementsTabs {#elementstabs} + + + +**Import**: `import { ElementsTabs }` or `addOnUISdk.constants.ElementsTabs` ✅ **Dual Access** + +Tabs within the Editor's Elements panel. + +| Value | Description | +|-------|-------------| +| `designAssets` | Design assets tab | +| `backgrounds` | Backgrounds tab | +| `shapes` | Shapes tab | +| `stockIcons` | Icons tab | +| `charts` | Charts tab | + +### EntrypointType {#entrypointtype} + + + +**Import**: `import { EntrypointType }` ⚠️ **Named Export Only** - Not available in constants object + +Types of add-on entry points (currently only panel is supported). + +| Value | Description | +|-------|-------------| +| `panel` | Panel entry point | + +### FieldType {#fieldtype} + + + +**Import**: `import { FieldType }` or `addOnUISdk.constants.FieldType` ✅ **Dual Access** + +Input field types supported in Simple Dialog. + +| Value | Description | +|-------|-------------| +| `text` | Text input field | + +### FileSizeLimitUnit {#filesizelimitunit} + + + +**Import**: `import { FileSizeLimitUnit }` or `addOnUISdk.constants.FileSizeLimitUnit` ✅ **Dual Access** + +Units for file size limits. + +| Value | Description | +|-------|-------------| +| `KB` | Kilobytes | +| `MB` | Megabytes | + +### FrameRate {#framerate} + + + +**Import**: `import { FrameRate }` or `addOnUISdk.constants.FrameRate` ✅ **Dual Access** + +Frame rate values in frames per second for video renditions. + +| Value | Description | Numeric Value | +|-------|-------------|---------------| +| `fps23_976` | 23.976 fps | `23.976` | +| `fps24` | 24 fps | `24` | +| `fps25` | 25 fps | `25` | +| `fps29_97` | 29.97 fps | `29.97` | +| `fps30` | 30 fps | `30` | +| `fps60` | 60 fps | `60` | + +### LinkOptions {#linkoptions} + + + +**Import**: `import { LinkOptions }` or `addOnUISdk.constants.LinkOptions` ✅ **Dual Access** + +Types of document links that can be generated. + +| Value | Description | +|-------|-------------| +| `document` | Link to the current document | +| `published` | Link to the published document | + +### MediaTabs {#mediatabs} + + + +**Import**: `import { MediaTabs }` or `addOnUISdk.constants.MediaTabs` ✅ **Dual Access** + +Tabs within the Editor's Media panel. + +| Value | Description | +|-------|-------------| +| `video` | Video tab | +| `audio` | Audio tab | +| `photos` | Photos tab | + +### PanelActionType {#panelactiontype} + + + +**Import**: `import { PanelActionType }` or `addOnUISdk.constants.PanelActionType` ✅ **Dual Access** + +Types of actions that can be performed on Editor panels. + +| Value | Description | +|-------|-------------| +| `search` | Perform search within the Editor panel | +| `navigate` | Perform navigation within the Editor panel | + +### PlatformEnvironment {#platformenvironment} + + + +**Import**: `import { PlatformEnvironment }` or `addOnUISdk.constants.PlatformEnvironment` ✅ **Dual Access** + +Environment where the add-on is running. + +| Value | Description | +|-------|-------------| +| `app` | Native app environment | +| `web` | Web browser environment | + +### PlatformType {#platformtype} + + + +**Import**: `import { PlatformType }` or `addOnUISdk.constants.PlatformType` ✅ **Dual Access** + +Specific platform/operating system where the add-on is running. + +| Value | Description | +|-------|-------------| +| `iOS` | iOS mobile | +| `iPadOS` | iPadOS tablet | +| `chromeOS` | Chrome OS | +| `android` | Android mobile | +| `chromeBrowser` | Chrome browser | +| `firefoxBrowser` | Firefox browser | +| `edgeBrowser` | Edge browser | +| `samsungBrowser` | Samsung browser (note: contains typo in SDK) | +| `safariBrowser` | Safari browser | +| `unknown` | Unknown platform | + +### Range {#range} + + + +**Import**: `import { Range }` or `addOnUISdk.constants.Range` ✅ **Dual Access** + +Page range options for document renditions. + +| Value | Description | +|-------|-------------| +| `currentPage` | Generate rendition for the current page | +| `entireDocument` | Generate rendition for all pages | +| `specificPages` | Generate rendition for specific pages | + +### RenditionFormat {#renditionformat} + + + +**Import**: `import { RenditionFormat }` or `addOnUISdk.constants.RenditionFormat` ✅ **Dual Access** + +Output formats for document renditions. + +| Value | MIME Type | Description | +|-------|-----------|-------------| +| `jpg` | `"image/jpeg"` | JPEG image | +| `png` | `"image/png"` | PNG image | +| `mp4` | `"video/mp4"` | MP4 video | +| `pdf` | `"application/pdf"` | PDF document | +| `pptx` | `"application/vnd.openxmlformats-officedocument.presentationml.presentation"` | PowerPoint presentation | + +### RenditionIntent {#renditionintent} + + + +**Import**: `import { RenditionIntent }` or `addOnUISdk.constants.RenditionIntent` ✅ **Dual Access** + +Intent for creating renditions (affects optimization). + +| Value | Description | +|-------|-------------| +| `preview` | Intent to preview the content | +| `export` | Intent to export/download the content (default) | +| `print` | Intent to export and print the content (PDF optimized, not supported for MP4) | + +### RenditionType {#renditiontype} + + + +**Import**: `import { RenditionType }` or `addOnUISdk.constants.RenditionType` ✅ **Dual Access** + +Type of rendition being created. + +| Value | Description | +|-------|-------------| +| `page` | Page rendition (currently the only type) | + +### RuntimeType {#runtimetype} + + + +**Import**: `import { RuntimeType }` or `addOnUISdk.constants.RuntimeType` ✅ **Dual Access** + +Runtime type of the entrypoint creating the backend object. + +| Value | Description | +|-------|-------------| +| `panel` | Add-on's iframe runtime (code running in `index.html`) | +| `script` | Add-on's document sandbox code (code running in `code.js`) | +| `dialog` | Currently open dialog code | + +### SupportedMimeTypes {#supportedmimetypes} + + + +**Import**: `import { SupportedMimeTypes }` ⚠️ **Named Export Only** - Not available in constants object + +MIME types for original source assets that can be converted to PDF. + +| Value | Description | +|-------|-------------| +| `docx` | Microsoft Word document | +| `gdoc` | Google Docs document | + +### Variant {#variant} + + + +**Import**: `import { Variant }` or `addOnUISdk.constants.Variant` ✅ **Dual Access** + +Dialog variants that determine appearance and behavior. + +| Value | Description | +|-------|-------------| +| `confirmation` | Ask user to confirm an action | +| `information` | Share information for user to acknowledge | +| `warning` | Share information user needs to consider before proceeding | +| `destructive` | Warn about actions that may impact data negatively | +| `error` | Communicate critical issue that needs resolution | +| `input` | Ask user to provide input | +| `custom` | Dialog that can render complex forms and content | + +### VideoResolution {#videoresolution} + + + +**Import**: `import { VideoResolution }` or `addOnUISdk.constants.VideoResolution` ✅ **Dual Access** + +Video resolution options for MP4 renditions. + +| Value | Description | +|-------|-------------| +| `sd480p` | 480p Standard Definition | +| `hd720p` | 720p High Definition | +| `fhd1080p` | 1080p Full High Definition | +| `qhd1440p` | 1440p Quad High Definition | +| `uhd2160p` | 2160p Ultra High Definition (4K) | +| `custom` | Custom resolution | + ## Import Generator Use these copy-paste ready import statements for common scenarios: @@ -190,10 +615,6 @@ import addOnUISdk, { SupportedMimeTypes } from "https://express.adobe.com/static import addOnUISdk, { AuthorizationStatus } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; ``` -## Constants Reference - -This section provides the complete technical specification for all Add-on UI SDK constants, organized by functional category. For practical examples and usage patterns, see the [Add-on UI SDK Constants Guide](../../guides/learn/fundamentals/ui-sdk-constants.md). - ## Developer Tips @@ -204,373 +625,3 @@ This section provides the complete technical specification for all Add-on UI SDK - **Copy import statements** from the [Import Generator](#import-generator) above - **Never guess** - check if constants are import-required before using - **Use TypeScript** for compile-time validation and better IDE support - -## Constants - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

              Name

              Type

              Description

              BitRate

              number

              -

              Bit rate in bits per second.

              -
                -
              • mbps4
              • 4000000
                -
              • mbps8
              • 8000000
                -
              • mbps10
              • 10000000
                -
              • mbps12
              • 12000000
                -
              • mbps15
              • 15000000
                -
              • mbps25
              • 25000000
                -
              • mbps50
              • 50000000
                -
              -

              BleedUnit

              string

              -

              Units for the page bleed.

              -
                -
              • "in" (`Inch`)
              • Inch units. -
              • "mm" (`Millimeter`)
              • Millimeter units. -
              -

              ButtonType

              string

              -

              The type of the button pressed in a dialog. Dual access: both named export and constants object.

              -
                -
              • primary
              • Primary button pressed. -
              • secondary
              • Secondary button pressed. -
              • cancel
              • Cancel button pressed. -
              • close
              • Dialog closed via ESC or close(X) button. -
              -

              ColorPickerEvent

              string

              -

              Custom events dispatched by the Color Picker. Named export only - not available in constants object.

              -
                -
              • colorChange
              • "colorpicker-color-change"
                -
              • close
              • "colorpicker-close"
                -
              -

              ColorPickerPlacement

              string

              -

              Placement of the color picker popover with respect to the anchor element. Dual access: both named export and constants object.

              -
                -
              • top
              • "top"
                -
              • bottom
              • "bottom"
                -
              • left
              • "left"
                -
              • right
              • "right"
                -
              -

              DialogResultType

              string

              -

              The type of modal dialog result.

              -
                -
              • alert
              • Alert dialog result (simple dialogs all return this). -
              • input
              • Input dialog result. -
              • custom
              • Custom dialog result. -
              -

              EditorPanel

              string

              -

              The Adobe Express Editor panel to be opened.

              -
                -
              • search
              • Editor Search panel. -
              • yourStuff
              • Editor Your stuff panel. -
              • templates
              • Editor Templates panel. -
              • media
              • Editor Media panel. -
              • text
              • Editor Text panel. -
              • elements
              • Editor Elements panel. -
              • grids
              • Editor Grids panel. -
              • brands
              • Editor Brands panel. -
              • addOns
              • Editor Add-ons panel. -
              -

              ElementsTabs

              string

              -

              Tabs in the Editor's Elements panel.

              -
                -
              • designAssets
              • Design assets tab. -
              • backgrounds
              • Backgrounds tab. -
              • shapes
              • Shapes tab. -
              • stockIcons
              • Icons tab. -
              • charts
              • Charts tab. -
              -

              FileSizeLimitUnit

              string

              -

              Unit of the file size limit.

              -
                -
              • KB
              • "KB"
                -
              • MB
              • "MB"
                -
              -

              FrameRate

              number

              -

              Frame rate in frames per second.

              -
                -
              • fps23_976
              • 23.976
                -
              • fps24
              • 24
                -
              • fps25
              • 25
                -
              • fps29_97
              • 29.97
                -
              • fps30
              • 30
                -
              • fps60
              • 60
                -
              -

              LinkOptions

              string

              -

              The type of link

              -
                -
              • document
              • Link to the current document. -
              • published
              • Link to the published document. -
              -

              MediaTabs

              string

              -

              Tabs in the Editor's Media panel.

              -
                -
              • video
              • Video tab. -
              • audio
              • Audio tab. -
              • photos
              • Photos tab. -
              -

              PanelActionType

              string

              -

              Types of actions that can be performed on Editor panels.

              -
                -
              • search
              • Action type to perform search within the Editor panel. -
              • navigate
              • Action type to perform navigation within the Editor panel. -
              -

              Range

              string

              -

              Rendition page range. Dual access: both named export and constants object.

              -
                -
              • currentPage
              • Generate rendition for the current page -
              • entireDocument
              • Generate rendition for all pages -
              • specificPages
              • Generate rendition for specific pages -
              -

              RenditionFormat

              string

              -

              Required output format of the rendition. Dual access: both named export and constants object.

              -
                -
              • jpg
              • "image/jpeg"
                -
              • png
              • "image/png"
                -
              • mp4
              • "video/mp4"
                -
              • pdf
              • "application/pdf"
                -
              • pptx
              • "application/vnd.openxmlformats-officedocument.presentationml.presentation"
                -
              -

              RenditionIntent

              string

              -

              The intent to set for creating the rendition. Dual access: both named export and constants object.

              -
                -
              • preview
              • Intent to preview the content. -
              • export
              • Intent to export/download the content (default). -
              • print
              • Intent to export and print the content **Note:** For `pdf` format, a print optimized pdf is generated. This option is not supported for `mp4` format. -
              -

              RenditionType

              string

              -

              The type of rendition. Currently returns "page".

              -

              RuntimeType

              string

              -

              Runtime type of the entrypoint creating this backend object. -

                -
              • panel
              • add-on's iframe runtime, ie: code running in index.html -
              • script
              • add-on's document sandbox code ie: code running in code.js -
              • dialog
              • currently open dialog code -
              -

              -

              Variant

              string

              -

              Types of dialog variants supported. Dual access: both named export and constants object.

              -
                -
              • confirmation
              • Ask a user to confirm an action. -
              • information
              • Share information for user to acknowledge. -
              • warning
              • Share information that a user needs to consider before proceeding. -
              • destructive
              • Tell a user that if they proceed with an action, it may impact their data in a negative way. -
              • error
              • Communicate critical issue that a user needs to resolve before proceeding. -
              • input
              • Ask a user to provide some inputs. -
              • custom
              • A dialog that can render complex forms and content. -
              -

              VideoResolution

              string

              -

              Video resolution options for the mp4 renditions.

              -
                -
              • sd480p
              • "480p"
                -
              • hd720p
              • "720p"
                -
              • fhd1080p
              • "1080p"
                -
              • qhd1440p
              • "1440p"
                -
              • uhd2160p
              • "2160p"
                -
              • custom
              • Custom resolution -
              -

              AppEvent

              string

              -

              Events dispatched by the Add-on SDK. Named export only - not available in constants object.

              -
                -
              • themechange
              • "themechange"
                -
              • localechange
              • "localechange"
                -
              • formatchange
              • "formatchange"
                -
              • reset
              • "reset"
                -
              • dragstart
              • "dragstart"
                -
              • dragend
              • "dragend"
                -
              • dragcancel
              • "dragcancel"
                -
              • documentIdAvailable
              • "documentIdAvailable"
                -
              • documentLinkAvailable
              • "documentLinkAvailable"
                -
              • documentPublishedLinkAvailable
              • "documentPublishedLinkAvailable"
                -
              • documentTitleChange
              • "documentTitleChange"
                -
              • documentExportAllowedChange
              • "documentExportAllowedChange"
                -
              -

              AuthorizationStatus

              string

              -

              OAuth authorization status values. Dual access: both named export and constants object.

              -
                -
              • authorized
              • Authorization successful -
              • cancelled
              • Authorization cancelled by user -
              • error
              • Authorization error occurred -
              -

              SupportedMimeTypes

              string

              -

              MIME types for original source assets converted to PDF. Named export only - not available in constants object.

              -
                -
              • docx
              • "docx"
                -
              • gdoc
              • "gdoc"
                -
              -

              FieldType

              string

              -

              The type of input field supported in Simple Dialog. Dual access: both named export and constants object.

              -
                -
              • text
              • "text"
                -
              -

              PlatformEnvironment

              string

              -

              Denotes the current environment where the add-on is running. Dual access: both named export and constants object.

              -
                -
              • app
              • "app"
                -
              • web
              • "web"
                -
              -

              DeviceClass

              string

              -

              Denotes the device class/form factor where the add-on is running. Dual access: both named export and constants object.

              -
                -
              • mobile
              • "mobile"
                -
              • tablet
              • "tablet"
                -
              • desktop
              • "desktop"
                -
              -

              PlatformType

              string

              -

              Denotes the specific platform/operating system where the add-on is running. Dual access: both named export and constants object.

              -
                -
              • iOS
              • "ios"
                -
              • iPadOS
              • "ipad"
                -
              • chromeOS
              • "chromeOS"
                -
              • android
              • "android"
                -
              • chromeBrowser
              • "chromeBrowser"
                -
              • firefoxBrowser
              • "firefoxBrowser"
                -
              • edgeBrowser
              • "edgeBrowser"
                -
              • samsungBrowser
              • "samsumgBrowser"
                (Note: Contains typo in SDK) -
              • safariBrowser
              • "safariBrowser"
                -
              • unknown
              • "unknown"
                -
              -
              diff --git a/src/pages/references/addonsdk/app-document.md b/src/pages/references/addonsdk/app-document.md index a0e942eba..6873c418f 100644 --- a/src/pages/references/addonsdk/app-document.md +++ b/src/pages/references/addonsdk/app-document.md @@ -250,7 +250,7 @@ This object is passed as a parameter to the [`getPagesMetadata`](#getpagesmetada | Name | Type | Description | | -------------------- | ------------------------------------------------------ | --------------------------------------------------------------------: | -| `range` | [`Range`](../addonsdk/addonsdk-constants.md#constants) | Range of the document to get the metadata | +| `range` | [`Range`](../addonsdk/addonsdk-constants.md) | Range of the document to get the metadata | | `pageIds?: string[]` | `string` | Id's of the pages. (Only required when the range is `specificPages`). | ### getSelectedPageIds() @@ -822,7 +822,7 @@ Represents a _bleed_ for a page. In printing, _bleed_ is printing that goes beyo | Name | Type | Description | | --------- | ---------------------------------------------------------- | -----------------------------------------------: | | `amount?` | `number` | The amount for the bleed. | -| `unit` | [`BleedUnit`](../addonsdk/addonsdk-constants.md#constants) | The unit in which the bleed amount is expressed. | +| `unit` | [`BleedUnit`](../addonsdk/addonsdk-constants.md) | The unit in which the bleed amount is expressed. | #### `PdfPageBoxes` diff --git a/src/pages/references/ui-components/color-picker.md b/src/pages/references/ui-components/color-picker.md index ee8903e20..722672c81 100644 --- a/src/pages/references/ui-components/color-picker.md +++ b/src/pages/references/ui-components/color-picker.md @@ -70,7 +70,7 @@ showColorPicker( The method accepts a reference to an HTML element as its first argument, which will become the color picker's anchor element. This is important for two reasons: -1. The picker will be positioned relative to this element, based on the placement options available in the [`ColorPickerPlacement`](../addonsdk/addonsdk-constants.md#constants) enumerable; +1. The picker will be positioned relative to this element, based on the placement options available in the [`ColorPickerPlacement`](../addonsdk/addonsdk-constants.md) enumerable; 2. The anchor will receive two custom events: - `"colorpicker-color-change"` when the color changes—use it to get the color. - `"colorpicker-close"` when the picker is closed—use it to clean up any state. From 8fc6083810d93d40dc3d4c9315133b44d4a96a59 Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Mon, 6 Oct 2025 22:43:23 -0400 Subject: [PATCH 14/42] Continued updates --- gatsby-config.js | 2 +- .../getting_started/addon-project-anatomy.md | 2 +- .../guides/learn/fundamentals/terminology.md | 41 ++++++++++------ .../images/runtime-architecture.svg | 12 ++--- .../platform_concepts/runtime-architecture.md | 47 ++++++++++--------- 5 files changed, 59 insertions(+), 45 deletions(-) diff --git a/gatsby-config.js b/gatsby-config.js index cc460c935..19dcdd691 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -797,7 +797,7 @@ module.exports = { path: "guides/learn/fundamentals/document-sandbox-constants.md", }, { - title: "Developer Terminology", + title: "Add-on SDK Terminology", path: "guides/learn/fundamentals/terminology.md", }, ], diff --git a/src/pages/guides/getting_started/addon-project-anatomy.md b/src/pages/guides/getting_started/addon-project-anatomy.md index 4fea66732..6044c03bf 100644 --- a/src/pages/guides/getting_started/addon-project-anatomy.md +++ b/src/pages/guides/getting_started/addon-project-anatomy.md @@ -40,7 +40,7 @@ semantic_tags: - best-practices --- -# Add-on Project Anatomy & CLI Templates +# Add-on Project Anatomy Add-on project structure, file organization, and template selection for efficient Adobe Express add-on development. diff --git a/src/pages/guides/learn/fundamentals/terminology.md b/src/pages/guides/learn/fundamentals/terminology.md index fe66f159e..6c860f220 100644 --- a/src/pages/guides/learn/fundamentals/terminology.md +++ b/src/pages/guides/learn/fundamentals/terminology.md @@ -21,7 +21,7 @@ keywords: - Development workflow - Debugging - Cross-origin isolation -title: Developer Terminology Reference +title: Add-on SDK Terminology description: A comprehensive reference guide for Adobe Express Add-ons SDK terminology, naming conventions, and standardized definitions to ensure consistency across documentation and development. @@ -45,7 +45,7 @@ semantic_tags: - debugging-guide --- -# Developer Terminology Reference +# Add-on SDK Terminology ## Overview @@ -165,14 +165,29 @@ const { runtime } = addOnSandboxSdk.instance; -**Choose the right tool for your task:** +**Choose the right approach for your task:** -| Your Goal | Use This | Import Statement | -|-----------|----------|------------------| -| Build user interface components, handle user input | **Add-on UI SDK** | `import addOnUISdk from "..."` | -| Create/modify document content | **Document APIs** | Available in document sandbox | -| Communicate between UI and document | **Communication APIs** | `runtime.exposeApi()` / `runtime.apiProxy()` | -| Access limited browser features in sandbox | **Web APIs** | Global objects in document sandbox | +| Your Goal | Primary Environment | Required SDKs | Notes | +|-----------|-------------------|---------------|-------| +| Build user interface components, handle user input | **Iframe Runtime** | Add-on UI SDK | UI-only add-ons may not need document sandbox | +| Create/modify document content | **Document Sandbox** | Add-on UI SDK + Document APIs | UI SDK needed to trigger sandbox operations | +| Communicate between UI and document | **Both Environments** | Add-on UI SDK + Document Sandbox SDK | Communication APIs available in both | +| Import/export documents | **Iframe Runtime** | Add-on UI SDK | Document operations happen via UI SDK | +| Access browser features (fetch, OAuth) | **Iframe Runtime** | Add-on UI SDK | Limited browser APIs available in sandbox | + +### Typical Architecture Patterns + +**UI-Only Add-on (no document manipulation):** +- Import: Add-on UI SDK only +- Use cases: Settings panels, external integrations, file uploads + +**Document-Focused Add-on (content creation/editing):** +- Import: Add-on UI SDK + Document APIs + Document Sandbox SDK +- UI triggers operations → Communication APIs → Document manipulation in sandbox + +**Hybrid Add-on (UI + document + external services):** +- Import: All SDKs +- Complex workflows involving UI, document operations, and external APIs ## Quick Reference by Use Case @@ -450,9 +465,6 @@ Understanding which runtime environment your console messages appear in: ### Common Development Issues -**Communication Bridge Failure** -When the connection between iframe and document sandbox fails to initialize properly. Often resolved by manual reload. - **Race Condition** Timing issue where the communication bridge isn't ready when UI interactions occur. Clicking buttons may appear to do nothing. @@ -604,10 +616,11 @@ A: No, they're the same. **"Add-on UI SDK"** is the full, preferred term for cla ## Related Documentation -- [Runtime Architecture & Communication Guide](../platform_concepts/runtime-architecture.md) - Comprehensive guide with visual diagrams +- [Add-on Architecture Guide](../platform_concepts/runtime-architecture.md) - Comprehensive guide with visual diagrams - [Add-on UI SDK Reference](../../../references/addonsdk/index.md) - [Document Sandbox Overview](../../../references/document-sandbox/index.md) - [Communication APIs](../../../references/document-sandbox/communication/index.md) -- [Platform Concepts](../platform_concepts/context.md) +- [Document API Concepts Guide](../platform_concepts/document-api.md) +- [Add-on Iframe Context](../platform_concepts/context.md) - [Add-on UI SDK Constants Usage Guide](./ui-sdk-constants.md) - [Document Sandbox Constants Usage Guide](./document-sandbox-constants.md) diff --git a/src/pages/guides/learn/platform_concepts/images/runtime-architecture.svg b/src/pages/guides/learn/platform_concepts/images/runtime-architecture.svg index d4dbcda5c..6c08e9621 100644 --- a/src/pages/guides/learn/platform_concepts/images/runtime-architecture.svg +++ b/src/pages/guides/learn/platform_concepts/images/runtime-architecture.svg @@ -40,8 +40,8 @@ - Adobe Express Add-on Architecture - Two-Runtime System with Secure Communication + Adobe Express Add-on Architecture + Two-Runtime System with Secure Communication @@ -115,8 +115,8 @@ Cross-Runtime Communication - runtime.apiProxy("documentSandbox") - runtime.exposeApi(sandboxApi) + runtime.apiProxy("documentSandbox") + runtime.exposeApi(sandboxApi) @@ -131,8 +131,8 @@ - - + + diff --git a/src/pages/guides/learn/platform_concepts/runtime-architecture.md b/src/pages/guides/learn/platform_concepts/runtime-architecture.md index b7ec8165c..aac6b01df 100644 --- a/src/pages/guides/learn/platform_concepts/runtime-architecture.md +++ b/src/pages/guides/learn/platform_concepts/runtime-architecture.md @@ -73,12 +73,10 @@ Understanding the Adobe Express add-on architecture is crucial for building effe Adobe Express add-ons run in **two separate JavaScript execution environments** that work together: -1. **UI Runtime** - Your add-on's user interface (iframe) +1. **UI Runtime** - Your add-on's user interface (aka: iframe runtime) 2. **Document Sandbox** - Secure environment for document manipulation -## Architecture Diagrams - -### **Architecture: Two Runtime Communication** +## Architecture Diagram ![Runtime Architecture Diagram](images/runtime-architecture.svg) @@ -93,7 +91,7 @@ The communication bridge can be thought of like a phone line - each side has the ## The Two Environments Explained -### UI Runtime Environment +### UI Runtime Environment (Iframe) **File:** `index.js` or `index.html` **Purpose:** User interface and browser interactions @@ -196,7 +194,6 @@ async function processDocument() { await uiProxy.updateProgress(50); // Document manipulation here... - await uiProxy.updateProgress(100); } ``` @@ -304,17 +301,21 @@ runtime.exposeApi({ ### Quick Decision Guide -**Do I need `addOnSandboxSdk`?** + + + **Do I need `addOnSandboxSdk`?** + + - ✅ YES if your `code.js` needs to communicate with the UI + - ✅ YES if UI triggers document operations + - ❌ NO if `code.js` runs independently -- ✅ YES if your `code.js` needs to communicate with the UI -- ✅ YES if UI triggers document operations -- ❌ NO if `code.js` runs independently + **Do I need `express-document-sdk`?** -**Do I need `express-document-sdk`?** + - ✅ YES if creating/modifying document content + - ✅ YES if accessing document properties + - ❌ NO if only processing data or communicating -- ✅ YES if creating/modifying document content -- ✅ YES if accessing document properties -- ❌ NO if only processing data or communicating + ### Examples @@ -534,7 +535,7 @@ console.log(`Operation took ${endTime - startTime} milliseconds`); ### Quick Reference: All SDK Imports -| Feature | UI Runtime
              `addOnUISdk` | Document Sandbox
              `addOnSandboxSdk` | Document Sandbox
              `express-document-sdk` | +| Feature | UI Runtime | Document Sandbox Runtime| Document APIs | |---------|------------|------------------|-----------------| | **Import Statement** | `import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"` | `import addOnSandboxSdk from "add-on-sdk-document-sandbox"` | `import { editor } from "express-document-sdk"` | | **File Location** | `index.js/index.html` | `code.js` | `code.js` | @@ -571,14 +572,14 @@ The sandbox requires proper manifest setup: ### SDK Import Decision Matrix -| Your Add-on Needs | UI Runtime | Document Sandbox | Required Imports | -|-------------------|------------|------------------|------------------| -| **UI only** (no document changes) | ✅ | ❌ | `addOnUISdk` | -| **Document manipulation only** | ❌ | ✅ | `express-document-sdk` | -| **UI + Document communication** | ✅ | ✅ | `addOnUISdk` + `addOnSandboxSdk` | -| **UI + Document creation** | ✅ | ✅ | `addOnUISdk` + `addOnSandboxSdk` + `express-document-sdk` | -| **Data processing only** | ❌ | ✅ | `addOnSandboxSdk` (for communication) | -| **Export/Import only** | ✅ | ❌ | `addOnUISdk` | +| Your Add-on Needs | UI Runtime | Document Sandbox | Required Imports | Notes | +|-------------------|------------|------------------|------------------|-------| +| **UI only** (no document changes) | ✅ | ❌ | `addOnUISdk` | Settings panels, external integrations | +| **Document manipulation** | ✅ | ✅ | `addOnUISdk` + `express-document-sdk` + `addOnSandboxSdk` | UI triggers document operations | +| **UI + Document communication** | ✅ | ✅ | `addOnUISdk` + `addOnSandboxSdk` | Cross-runtime communication | +| **Document creation/editing** | ✅ | ✅ | `addOnUISdk` + `addOnSandboxSdk` + `express-document-sdk` | Full document workflow | +| **Data processing in sandbox** | ✅ | ✅ | `addOnUISdk` + `addOnSandboxSdk` | UI needed to trigger processing | +| **Export/Import workflows** | ✅ | ❌ | `addOnUISdk` | Document operations via UI SDK | ### Common Import Patterns From 741349a95cd9859f866649846f5953c4296565ad Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Tue, 7 Oct 2025 00:55:27 -0400 Subject: [PATCH 15/42] Updated changelogs and misc --- gatsby-config.js | 2 +- src/pages/guides/getting_started/changelog.md | 29 +++++++++++++++++++ .../guides/learn/fundamentals/terminology.md | 3 ++ .../platform_concepts/runtime-architecture.md | 2 +- src/pages/references/changelog.md | 28 ++++++++++++++++++ 5 files changed, 62 insertions(+), 2 deletions(-) diff --git a/gatsby-config.js b/gatsby-config.js index 19dcdd691..41eccaa7d 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -552,7 +552,7 @@ module.exports = { path: "guides/getting_started/hello-world.md", }, { - title: "Add-on Project Anatomy", + title: "Project Anatomy", path: "guides/getting_started/addon-project-anatomy.md", }, { diff --git a/src/pages/guides/getting_started/changelog.md b/src/pages/guides/getting_started/changelog.md index d14322759..513abb3df 100644 --- a/src/pages/guides/getting_started/changelog.md +++ b/src/pages/guides/getting_started/changelog.md @@ -22,6 +22,35 @@ contributors: # Changelog +## 2025-10-08 + +### Added + +- New [Architecture Guide](../learn/platform_concepts/runtime-architecture.md) with dual-runtime system explanation, SDK imports and usage, and cross-runtime communication patterns. +- New [Project Anatomy](../getting_started/addon-project-anatomy.md) guide with add-on project structure, file organization, and template selection for efficient Adobe Express add-on development. +- New [Add-on SDK Terminology](../learn/fundamentals/terminology.md) guide with standardized definitions, decision matrices, and troubleshooting for Adobe Express Add-on development terminology. +- New [Add-on UI SDK Constants](../learn/fundamentals/ui-sdk-constants.md) practical usage guide focusing on import patterns, common pitfalls, and solutions for UI SDK constants. +- New [Document Sandbox Constants](../learn/fundamentals/document-sandbox-constants.md) usage guide for constants in the Document Sandbox environment, including `colorUtils` integration and practical examples. +- New ["SDK Fundamentals"](../learn/fundamentals/index.md) section in navigation under "Learn" to group terminology and constants usage guides for better discoverability. + +### Updated + +- **Major restructure** of the [Add-on UI SDK Constants Reference](../../references/addonsdk/addonsdk-constants.md) - converted. +- Improved content and metadata for SEO and AI assistant optimization across all new guides. + +### Enhanced + +- **Visual improvements** to runtime architecture diagrams with better spacing, color coding (green for Document Sandbox, blue for UI Runtime), and clearer communication flow arrows. +- **Expanded terminology coverage** with new sections for Manifest & Configuration, Development Workflow & Debugging, and File Structure & Bundle terminology. +- **Improved file structure examples** in terminology guide to accurately match CLI-generated project templates. +- **Added FAQ sections** to constants guides addressing common developer questions about import patterns, dual-access vs named-only exports, and environment differences. +- **Integrated colorUtils guidance** in Document Sandbox constants guide with practical examples for color creation and usage with constants. + +### Fixed + +- Resolved all markdown linting issues across updated documentation files. +- Corrected misleading SDK decision matrices that incorrectly suggested document manipulation could be done without UI SDK involvement. + ## 2025-09-10 ### Added diff --git a/src/pages/guides/learn/fundamentals/terminology.md b/src/pages/guides/learn/fundamentals/terminology.md index 6c860f220..7945dbbc4 100644 --- a/src/pages/guides/learn/fundamentals/terminology.md +++ b/src/pages/guides/learn/fundamentals/terminology.md @@ -178,14 +178,17 @@ const { runtime } = addOnSandboxSdk.instance; ### Typical Architecture Patterns **UI-Only Add-on (no document manipulation):** + - Import: Add-on UI SDK only - Use cases: Settings panels, external integrations, file uploads **Document-Focused Add-on (content creation/editing):** + - Import: Add-on UI SDK + Document APIs + Document Sandbox SDK - UI triggers operations → Communication APIs → Document manipulation in sandbox **Hybrid Add-on (UI + document + external services):** + - Import: All SDKs - Complex workflows involving UI, document operations, and external APIs diff --git a/src/pages/guides/learn/platform_concepts/runtime-architecture.md b/src/pages/guides/learn/platform_concepts/runtime-architecture.md index aac6b01df..df26e13ea 100644 --- a/src/pages/guides/learn/platform_concepts/runtime-architecture.md +++ b/src/pages/guides/learn/platform_concepts/runtime-architecture.md @@ -63,7 +63,7 @@ contributors: # Add-on Architecture Guide -Learn about the dual-runtime architecture, communication patterns, and development workflow essential for building Adobe Express add-ons. +Learn about the dual-runtime architecture, communication patterns, and development workflow essentials for building Adobe Express add-ons. ## Overview diff --git a/src/pages/references/changelog.md b/src/pages/references/changelog.md index 16e0bcf0b..4360df53f 100644 --- a/src/pages/references/changelog.md +++ b/src/pages/references/changelog.md @@ -25,6 +25,34 @@ contributors: # Changelog +## 2025-10-08 + +### Added + +- New [Architecture Guide](../guides/learn/platform_concepts/runtime-architecture.md) with dual-runtime system explanation, SDK imports and usage, and cross-runtime communication patterns. +- New [Project Anatomy](../guides/getting_started/addon-project-anatomy.md) guide with add-on project structure, file organization, and template selection for efficient Adobe Express add-on development. +- New [Add-on SDK Terminology](../guides/learn/fundamentals/terminology.md) guide with standardized definitions, decision matrices, and troubleshooting for Adobe Express Add-on development terminology. +- New [Add-on UI SDK Constants](../guides/learn/fundamentals/ui-sdk-constants.md) practical usage guide focusing on import patterns, common pitfalls, and solutions for UI SDK constants. +- New [Document Sandbox Constants](../guides/learn/fundamentals/document-sandbox-constants.md) usage guide for constants in the Document Sandbox environment, including `colorUtils` integration and practical examples. +- New ["SDK Fundamentals"](../guides/learn/fundamentals/index.md) section in navigation under "Learn" to group terminology and constants usage guides for better discoverability. + +### Updated + +- **Major restructure** of the [Add-on UI SDK Constants Reference](./addonsdk/addonsdk-constants.md) - converted from dense HTML table format to readable markdown sections with individual headings, anchor links, and prominent import information for each constant. +- Improved content and metadata for SEO and AI assistant optimization across all new guides. + +### Enhanced + +- **Visual improvements** to runtime architecture diagrams with better spacing, color coding (green for Document Sandbox, blue for UI Runtime), and clearer communication flow arrows. +- **Expanded terminology coverage** with new sections for Manifest & Configuration, Development Workflow & Debugging, and File Structure & Bundle terminology. +- **Improved file structure examples** in terminology guide to accurately match CLI-generated project templates. +- **Added FAQ sections** to constants guides addressing common developer questions about import patterns, dual-access vs named-only exports, and environment differences. +- **Integrated colorUtils guidance** in Document Sandbox constants guide with practical examples for color creation and usage with constants. + +### Fixed + +- Corrected misleading SDK decision matrices that incorrectly suggested document manipulation could be done without UI SDK involvement. + ## 2025-09-10 ### Added From 9fa5d68ec88541ef3b463fbb433c8664a3fd2d83 Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Tue, 7 Oct 2025 01:01:57 -0400 Subject: [PATCH 16/42] Updated desc --- src/pages/guides/getting_started/changelog.md | 15 +-------------- src/pages/references/changelog.md | 18 +++--------------- 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/src/pages/guides/getting_started/changelog.md b/src/pages/guides/getting_started/changelog.md index 513abb3df..4ea90cc5f 100644 --- a/src/pages/guides/getting_started/changelog.md +++ b/src/pages/guides/getting_started/changelog.md @@ -36,20 +36,7 @@ contributors: ### Updated - **Major restructure** of the [Add-on UI SDK Constants Reference](../../references/addonsdk/addonsdk-constants.md) - converted. -- Improved content and metadata for SEO and AI assistant optimization across all new guides. - -### Enhanced - -- **Visual improvements** to runtime architecture diagrams with better spacing, color coding (green for Document Sandbox, blue for UI Runtime), and clearer communication flow arrows. -- **Expanded terminology coverage** with new sections for Manifest & Configuration, Development Workflow & Debugging, and File Structure & Bundle terminology. -- **Improved file structure examples** in terminology guide to accurately match CLI-generated project templates. -- **Added FAQ sections** to constants guides addressing common developer questions about import patterns, dual-access vs named-only exports, and environment differences. -- **Integrated colorUtils guidance** in Document Sandbox constants guide with practical examples for color creation and usage with constants. - -### Fixed - -- Resolved all markdown linting issues across updated documentation files. -- Corrected misleading SDK decision matrices that incorrectly suggested document manipulation could be done without UI SDK involvement. +- Improved content and metadata for SEO and AI assistant optimization. ## 2025-09-10 diff --git a/src/pages/references/changelog.md b/src/pages/references/changelog.md index 4360df53f..b88ab7699 100644 --- a/src/pages/references/changelog.md +++ b/src/pages/references/changelog.md @@ -38,20 +38,8 @@ contributors: ### Updated -- **Major restructure** of the [Add-on UI SDK Constants Reference](./addonsdk/addonsdk-constants.md) - converted from dense HTML table format to readable markdown sections with individual headings, anchor links, and prominent import information for each constant. -- Improved content and metadata for SEO and AI assistant optimization across all new guides. - -### Enhanced - -- **Visual improvements** to runtime architecture diagrams with better spacing, color coding (green for Document Sandbox, blue for UI Runtime), and clearer communication flow arrows. -- **Expanded terminology coverage** with new sections for Manifest & Configuration, Development Workflow & Debugging, and File Structure & Bundle terminology. -- **Improved file structure examples** in terminology guide to accurately match CLI-generated project templates. -- **Added FAQ sections** to constants guides addressing common developer questions about import patterns, dual-access vs named-only exports, and environment differences. -- **Integrated colorUtils guidance** in Document Sandbox constants guide with practical examples for color creation and usage with constants. - -### Fixed - -- Corrected misleading SDK decision matrices that incorrectly suggested document manipulation could be done without UI SDK involvement. +- **Major restructure** of the [Add-on UI SDK Constants Reference](./addonsdk/addonsdk-constants.md). +- Improved content and metadata for SEO and AI assistant optimization. ## 2025-09-10 @@ -100,7 +88,7 @@ With MCP-enabled IDEs (Cursor, Claude Desktop, VS Code etc.), developers can [co - [Page Metadata how-to guide](../guides/learn/how_to/page_metadata.md) with documentation and examples for the new experimental `getSelectedPageIds()` method, including usage patterns for getting metadata of only selected pages. - [Create Renditions how-to guide](../guides/learn/how_to/create_renditions.md) with comprehensive PPTX export support documentation, including developer guidance about font differences and content limitations when exporting to PowerPoint format. -- [Add-on Context guide](../guides/learn/platform_concepts/context.md) with additional permissions documentation, including details about `oauth`, `clipboard`, `microphone`, and `camera` permissions beyond the existing sandbox permissions. +- [Iframe Context guide](../guides/learn/platform_concepts/context.md) with additional permissions documentation, including details about `oauth`, `clipboard`, `microphone`, and `camera` permissions beyond the existing sandbox permissions. - [FAQ](../guides/support/faq.md) with a new comprehensive entry about available add-on permissions and their configuration, plus updated supported file formats for imported content organized by category (Image, Design, Video, Audio). ## 2025-07-27 From 02a065c7fe006796a88ec9a0b0878fb57906ceee Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Tue, 7 Oct 2025 01:10:46 -0400 Subject: [PATCH 17/42] Fix links --- src/pages/guides/getting_started/changelog.md | 2 +- src/pages/references/changelog.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/guides/getting_started/changelog.md b/src/pages/guides/getting_started/changelog.md index 4ea90cc5f..0db1dd1fd 100644 --- a/src/pages/guides/getting_started/changelog.md +++ b/src/pages/guides/getting_started/changelog.md @@ -31,7 +31,7 @@ contributors: - New [Add-on SDK Terminology](../learn/fundamentals/terminology.md) guide with standardized definitions, decision matrices, and troubleshooting for Adobe Express Add-on development terminology. - New [Add-on UI SDK Constants](../learn/fundamentals/ui-sdk-constants.md) practical usage guide focusing on import patterns, common pitfalls, and solutions for UI SDK constants. - New [Document Sandbox Constants](../learn/fundamentals/document-sandbox-constants.md) usage guide for constants in the Document Sandbox environment, including `colorUtils` integration and practical examples. -- New ["SDK Fundamentals"](../learn/fundamentals/index.md) section in navigation under "Learn" to group terminology and constants usage guides for better discoverability. +- New ["SDK Fundamentals"](../learn/fundamentals/terminology.md) section in navigation under "Learn" to group terminology and constants usage guides for better discoverability. ### Updated diff --git a/src/pages/references/changelog.md b/src/pages/references/changelog.md index b88ab7699..705e34e5b 100644 --- a/src/pages/references/changelog.md +++ b/src/pages/references/changelog.md @@ -34,7 +34,7 @@ contributors: - New [Add-on SDK Terminology](../guides/learn/fundamentals/terminology.md) guide with standardized definitions, decision matrices, and troubleshooting for Adobe Express Add-on development terminology. - New [Add-on UI SDK Constants](../guides/learn/fundamentals/ui-sdk-constants.md) practical usage guide focusing on import patterns, common pitfalls, and solutions for UI SDK constants. - New [Document Sandbox Constants](../guides/learn/fundamentals/document-sandbox-constants.md) usage guide for constants in the Document Sandbox environment, including `colorUtils` integration and practical examples. -- New ["SDK Fundamentals"](../guides/learn/fundamentals/index.md) section in navigation under "Learn" to group terminology and constants usage guides for better discoverability. +- New ["SDK Fundamentals"](../guides/learn/fundamentals/terminology.md) section in navigation under "Learn" to group terminology and constants usage guides for better discoverability. ### Updated From 9918c7497d3c2bf2baa3ca77f0318751f17cf55e Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Tue, 7 Oct 2025 01:24:52 -0400 Subject: [PATCH 18/42] Updates --- src/pages/guides/getting_started/changelog.md | 18 ++++++++++++++++++ src/pages/references/changelog.md | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/pages/guides/getting_started/changelog.md b/src/pages/guides/getting_started/changelog.md index 0db1dd1fd..ff21bf5b6 100644 --- a/src/pages/guides/getting_started/changelog.md +++ b/src/pages/guides/getting_started/changelog.md @@ -38,6 +38,24 @@ contributors: - **Major restructure** of the [Add-on UI SDK Constants Reference](../../references/addonsdk/addonsdk-constants.md) - converted. - Improved content and metadata for SEO and AI assistant optimization. +## 2025-10-02 + +### Added + +- New [`ImportAddOnData`](../../references/addonsdk/addonsdk-app.md#importaddondata) parameter support for enhanced metadata tracking on imported media in [`addImage()`](../../references/addonsdk/app-document.md#addimage), [`addVideo()`](../../references/addonsdk/app-document.md#addvideo), [`addAnimatedImage()`](../../references/addonsdk/app-document.md#addanimatedimage), and [`enableDragToDocument()`](../../references/addonsdk/addonsdk-app.md#enabledragtodocument) methods. +- New [Handle Element Selection How-to Guide](../../guides/learn/how_to/handle_selection.md) covering selection operations, real-time selection events, UI integration patterns, selection-based actions, and working with locked elements. +- New [Manage Pages How-to Guide](../../guides/learn/how_to/manage_pages.md) covering page creation, navigation, and management, positioned in a new **Document Structure** navigation category. +- [`MediaAttributes`](../../references/addonsdk/addonsdk-app.md#mediaattributes) parameter documentation for [`addVideo()`](../../references/addonsdk/app-document.md#addvideo) method. + +### Updated + +The following how-to guides have been updated with `ImportAddOnData` support for enhanced metadata tracking on imported media, including examples and implementation patterns: + +- [Use Images](../../guides/learn/how_to/use_images.md) +- [Use Videos](../../guides/learn/how_to/use_videos.md) +- [Drag and Drop](../../guides/learn/how_to/drag_and_drop.md) +- [Element Metadata](../../guides/learn/how_to/element_metadata.md) + ## 2025-09-10 ### Added diff --git a/src/pages/references/changelog.md b/src/pages/references/changelog.md index 705e34e5b..cc9112b0f 100644 --- a/src/pages/references/changelog.md +++ b/src/pages/references/changelog.md @@ -41,6 +41,24 @@ contributors: - **Major restructure** of the [Add-on UI SDK Constants Reference](./addonsdk/addonsdk-constants.md). - Improved content and metadata for SEO and AI assistant optimization. +## 2025-10-02 + +### Added + +- New [`ImportAddOnData`](./addonsdk/addonsdk-app.md#importaddondata) support for enhanced metadata tracking on imported media in [`addImage()`](./addonsdk/app-document.md#addimage), [`addVideo()`](./addonsdk/app-document.md#addvideo), [`addAnimatedImage()`](./addonsdk/app-document.md#addanimatedimage), and [`enableDragToDocument()`](./addonsdk/addonsdk-app.md#enabledragtodocument) methods. +- New [Handle Element Selection How-to Guide](../guides/learn/how_to/handle_selection.md) covering selection operations, real-time selection events, UI integration patterns, selection-based actions, and working with locked elements. +- New [Manage Pages How-to Guide](../guides/learn/how_to/manage_pages.md) covering page creation, navigation, and management, positioned in a new **Document Structure** navigation category. +- [`MediaAttributes`](./addonsdk/addonsdk-app.md#mediaattributes) parameter documentation for [`addVideo()`](./addonsdk/app-document.md#addvideo) method. + +### Updated + +The following how-to guides have been updated with `ImportAddOnData` support for enhanced metadata tracking on imported media, including examples and implementation patterns: + +- [Use Images](../guides/learn/how_to/use_images.md) +- [Use Videos](../guides/learn/how_to/use_videos.md) +- [Drag and Drop](../guides/learn/how_to/drag_and_drop.md) +- [Element Metadata](../guides/learn/how_to/element_metadata.md) + ## 2025-09-10 ### Added From 29c8718627df38f04e311f8bc6da00ebf5c3a3e0 Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Tue, 7 Oct 2025 02:16:16 -0400 Subject: [PATCH 19/42] Mark new and misc --- gatsby-config.js | 32 +++++++++---------- .../guides/learn/fundamentals/terminology.md | 8 ----- .../platform_concepts/runtime-architecture.md | 12 +++---- 3 files changed, 22 insertions(+), 30 deletions(-) diff --git a/gatsby-config.js b/gatsby-config.js index 116adc9d6..e9a279f47 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -97,7 +97,7 @@ module.exports = { ], }, { - title: "constants", + title: "*constants", path: "references/addonsdk/addonsdk-constants.md", }, ], @@ -552,7 +552,7 @@ module.exports = { path: "guides/getting_started/hello-world.md", }, { - title: "Project Anatomy", + title: "*Project Anatomy", path: "guides/getting_started/addon-project-anatomy.md", }, { @@ -689,7 +689,7 @@ module.exports = { path: "guides/learn/how_to/resize_rescale_elements.md", }, { - title: "Handle Element Selection", + title: "*Handle Element Selection", path: "guides/learn/how_to/handle_selection.md", }, { @@ -711,7 +711,7 @@ module.exports = { path: "guides/learn/how_to/page_metadata.md", }, { - title: "Element", + title: "*Element", path: "guides/learn/how_to/element_metadata.md", }, ], @@ -785,13 +785,13 @@ module.exports = { path: "guides/learn/platform_concepts/context.md", pages: [ { - title: "Add-on Iframe Context", - path: "guides/learn/platform_concepts/context.md", - }, - { - title: "Add-on Architecture", + title: "*Add-on Architecture", path: "guides/learn/platform_concepts/runtime-architecture.md", }, + { + title: "Add-on Iframe Context", + path: "guides/learn/platform_concepts/context.md", + }, { title: "The Document API", path: "guides/learn/platform_concepts/document-api.md", @@ -803,17 +803,17 @@ module.exports = { path: "guides/learn/fundamentals/ui-sdk-constants.md", pages: [ { - title: "Add-on UI SDK Constants", - path: "guides/learn/fundamentals/ui-sdk-constants.md", + title: "*Terminology", + path: "guides/learn/fundamentals/terminology.md", }, { - title: "Document Sandbox Constants", - path: "guides/learn/fundamentals/document-sandbox-constants.md", + title: "*Add-on UI SDK Constants", + path: "guides/learn/fundamentals/ui-sdk-constants.md", }, { - title: "Add-on SDK Terminology", - path: "guides/learn/fundamentals/terminology.md", - }, + title: "*Document Sandbox Constants", + path: "guides/learn/fundamentals/document-sandbox-constants.md", + } ], }, { diff --git a/src/pages/guides/learn/fundamentals/terminology.md b/src/pages/guides/learn/fundamentals/terminology.md index 7945dbbc4..0a471a103 100644 --- a/src/pages/guides/learn/fundamentals/terminology.md +++ b/src/pages/guides/learn/fundamentals/terminology.md @@ -72,8 +72,6 @@ This reference clarifies the naming conventions and terminology used throughout ### Add-on UI SDK - - The SDK that provides APIs for the UI panel of your add-on running in the iframe environment. **Import Statement:** @@ -87,8 +85,6 @@ import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js" ### Document Sandbox - - The sandboxed JavaScript runtime environment that provides access to the Document APIs for content authoring. **Import Statement:** @@ -102,8 +98,6 @@ import addOnSandboxSdk from "add-on-sdk-document-sandbox" ### Document APIs - - The APIs that allow you to interact with and modify Adobe Express documents. **Import Statement:** @@ -163,8 +157,6 @@ const { runtime } = addOnSandboxSdk.instance; ## Decision Matrix: Which SDK to Use? - - **Choose the right approach for your task:** | Your Goal | Primary Environment | Required SDKs | Notes | diff --git a/src/pages/guides/learn/platform_concepts/runtime-architecture.md b/src/pages/guides/learn/platform_concepts/runtime-architecture.md index df26e13ea..072d2b1e4 100644 --- a/src/pages/guides/learn/platform_concepts/runtime-architecture.md +++ b/src/pages/guides/learn/platform_concepts/runtime-architecture.md @@ -305,15 +305,15 @@ runtime.exposeApi({ **Do I need `addOnSandboxSdk`?** - - ✅ YES if your `code.js` needs to communicate with the UI - - ✅ YES if UI triggers document operations - - ❌ NO if `code.js` runs independently + - ✅ YES if your `code.js` needs to communicate with the UI + - ✅ YES if UI triggers document operations + - ❌ NO if `code.js` runs independently **Do I need `express-document-sdk`?** - - ✅ YES if creating/modifying document content - - ✅ YES if accessing document properties - - ❌ NO if only processing data or communicating + - ✅ YES if creating/modifying document content + - ✅ YES if accessing document properties + - ❌ NO if only processing data or communicating
              From eb8415e48d6ac60f92c8f1f5f1ed75e29f098575 Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Wed, 8 Oct 2025 12:39:37 -0400 Subject: [PATCH 20/42] Marks new content --- gatsby-config.js | 18 +++--- .../platform_concepts/runtime-architecture.md | 20 +++---- .../references/addonsdk/addonsdk-constants.md | 56 +++++++++---------- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/gatsby-config.js b/gatsby-config.js index e9a279f47..fe633411d 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -97,7 +97,7 @@ module.exports = { ], }, { - title: "*constants", + title: "constants", path: "references/addonsdk/addonsdk-constants.md", }, ], @@ -552,7 +552,7 @@ module.exports = { path: "guides/getting_started/hello-world.md", }, { - title: "*Project Anatomy", + title: "(NEW) Project Anatomy", path: "guides/getting_started/addon-project-anatomy.md", }, { @@ -689,7 +689,7 @@ module.exports = { path: "guides/learn/how_to/resize_rescale_elements.md", }, { - title: "*Handle Element Selection", + title: "(NEW)Handle Element Selection", path: "guides/learn/how_to/handle_selection.md", }, { @@ -711,7 +711,7 @@ module.exports = { path: "guides/learn/how_to/page_metadata.md", }, { - title: "*Element", + title: "Element", path: "guides/learn/how_to/element_metadata.md", }, ], @@ -785,7 +785,7 @@ module.exports = { path: "guides/learn/platform_concepts/context.md", pages: [ { - title: "*Add-on Architecture", + title: "(NEW)Add-on Architecture", path: "guides/learn/platform_concepts/runtime-architecture.md", }, { @@ -799,19 +799,19 @@ module.exports = { ], }, { - title: "SDK Fundamentals", + title: "(NEW) SDK Fundamentals", path: "guides/learn/fundamentals/ui-sdk-constants.md", pages: [ { - title: "*Terminology", + title: "Terminology", path: "guides/learn/fundamentals/terminology.md", }, { - title: "*Add-on UI SDK Constants", + title: "Add-on UI SDK Constants", path: "guides/learn/fundamentals/ui-sdk-constants.md", }, { - title: "*Document Sandbox Constants", + title: "Document Sandbox Constants", path: "guides/learn/fundamentals/document-sandbox-constants.md", } ], diff --git a/src/pages/guides/learn/platform_concepts/runtime-architecture.md b/src/pages/guides/learn/platform_concepts/runtime-architecture.md index 072d2b1e4..b7a6ca076 100644 --- a/src/pages/guides/learn/platform_concepts/runtime-architecture.md +++ b/src/pages/guides/learn/platform_concepts/runtime-architecture.md @@ -303,17 +303,17 @@ runtime.exposeApi({ - **Do I need `addOnSandboxSdk`?** +**Do I need `addOnSandboxSdk`?** - - ✅ YES if your `code.js` needs to communicate with the UI - - ✅ YES if UI triggers document operations - - ❌ NO if `code.js` runs independently + - ✅ YES if your `code.js` needs to communicate with the UI + - ✅ YES if UI triggers document operations + - ❌ NO if `code.js` runs independently - **Do I need `express-document-sdk`?** +**Do I need `express-document-sdk`?** - - ✅ YES if creating/modifying document content - - ✅ YES if accessing document properties - - ❌ NO if only processing data or communicating + - ✅ YES if creating/modifying document content + - ✅ YES if accessing document properties + - ❌ NO if only processing data or communicating @@ -533,7 +533,7 @@ const endTime = performance.now(); console.log(`Operation took ${endTime - startTime} milliseconds`); ``` -### Quick Reference: All SDK Imports + ### Manifest Configuration diff --git a/src/pages/references/addonsdk/addonsdk-constants.md b/src/pages/references/addonsdk/addonsdk-constants.md index ca16b8e12..ad6f8f278 100644 --- a/src/pages/references/addonsdk/addonsdk-constants.md +++ b/src/pages/references/addonsdk/addonsdk-constants.md @@ -154,7 +154,7 @@ This section provides the complete technical specification for all Add-on UI SDK -**Import**: `import { BitRate }` or `addOnUISdk.constants.BitRate` ✅ **Dual Access** +**Import**: `import { BitRate }` or `addOnUISdk.constants.BitRate` Bit rate values in bits per second for video renditions. @@ -172,7 +172,7 @@ Bit rate values in bits per second for video renditions. -**Import**: `import { BleedUnit }` or `addOnUISdk.constants.BleedUnit` ✅ **Dual Access** +**Import**: `import { BleedUnit }` or `addOnUISdk.constants.BleedUnit` Units for page bleed measurements. @@ -185,7 +185,7 @@ Units for page bleed measurements. -**Import**: `import { ButtonType }` or `addOnUISdk.constants.ButtonType` ✅ **Dual Access** +**Import**: `import { ButtonType }` or `addOnUISdk.constants.ButtonType` Types of buttons that can be pressed in modal dialogs. @@ -200,7 +200,7 @@ Types of buttons that can be pressed in modal dialogs. -**Import**: `import { AppEvent }` ⚠️ **Named Export Only** - Not available in constants object +**Import**: `import { AppEvent }` - Not available in constants object Events dispatched by the Add-on SDK. @@ -223,7 +223,7 @@ Events dispatched by the Add-on SDK. -**Import**: `import { AuthorizationStatus }` or `addOnUISdk.constants.AuthorizationStatus` ✅ **Dual Access** +**Import**: `import { AuthorizationStatus }` or `addOnUISdk.constants.AuthorizationStatus` OAuth authorization status values. @@ -237,7 +237,7 @@ OAuth authorization status values. -**Import**: `import { ColorPickerEvent }` ⚠️ **Named Export Only** - Not available in constants object +**Import**: `import { ColorPickerEvent }` - Not available in constants object Custom events dispatched by the Color Picker component. @@ -250,7 +250,7 @@ Custom events dispatched by the Color Picker component. -**Import**: `import { ColorPickerPlacement }` or `addOnUISdk.constants.ColorPickerPlacement` ✅ **Dual Access** +**Import**: `import { ColorPickerPlacement }` or `addOnUISdk.constants.ColorPickerPlacement` Placement options for the color picker popover relative to anchor element. @@ -265,7 +265,7 @@ Placement options for the color picker popover relative to anchor element. -**Import**: `import { DeviceClass }` or `addOnUISdk.constants.DeviceClass` ✅ **Dual Access** +**Import**: `import { DeviceClass }` or `addOnUISdk.constants.DeviceClass` Device form factors where the add-on is running. @@ -279,7 +279,7 @@ Device form factors where the add-on is running. -**Import**: `import { DialogResultType }` or `addOnUISdk.constants.DialogResultType` ✅ **Dual Access** +**Import**: `import { DialogResultType }` or `addOnUISdk.constants.DialogResultType` Types of modal dialog results. @@ -293,7 +293,7 @@ Types of modal dialog results. -**Import**: `import { EditorPanel }` or `addOnUISdk.constants.EditorPanel` ✅ **Dual Access** +**Import**: `import { EditorPanel }` or `addOnUISdk.constants.EditorPanel` Adobe Express Editor panels that can be opened programmatically. @@ -313,7 +313,7 @@ Adobe Express Editor panels that can be opened programmatically. -**Import**: `import { ElementsTabs }` or `addOnUISdk.constants.ElementsTabs` ✅ **Dual Access** +**Import**: `import { ElementsTabs }` or `addOnUISdk.constants.ElementsTabs` Tabs within the Editor's Elements panel. @@ -329,7 +329,7 @@ Tabs within the Editor's Elements panel. -**Import**: `import { EntrypointType }` ⚠️ **Named Export Only** - Not available in constants object +**Import**: `import { EntrypointType }` - Not available in constants object Types of add-on entry points (currently only panel is supported). @@ -341,7 +341,7 @@ Types of add-on entry points (currently only panel is supported). -**Import**: `import { FieldType }` or `addOnUISdk.constants.FieldType` ✅ **Dual Access** +**Import**: `import { FieldType }` or `addOnUISdk.constants.FieldType` Input field types supported in Simple Dialog. @@ -353,7 +353,7 @@ Input field types supported in Simple Dialog. -**Import**: `import { FileSizeLimitUnit }` or `addOnUISdk.constants.FileSizeLimitUnit` ✅ **Dual Access** +**Import**: `import { FileSizeLimitUnit }` or `addOnUISdk.constants.FileSizeLimitUnit` Units for file size limits. @@ -366,7 +366,7 @@ Units for file size limits. -**Import**: `import { FrameRate }` or `addOnUISdk.constants.FrameRate` ✅ **Dual Access** +**Import**: `import { FrameRate }` or `addOnUISdk.constants.FrameRate` Frame rate values in frames per second for video renditions. @@ -383,7 +383,7 @@ Frame rate values in frames per second for video renditions. -**Import**: `import { LinkOptions }` or `addOnUISdk.constants.LinkOptions` ✅ **Dual Access** +**Import**: `import { LinkOptions }` or `addOnUISdk.constants.LinkOptions` Types of document links that can be generated. @@ -396,7 +396,7 @@ Types of document links that can be generated. -**Import**: `import { MediaTabs }` or `addOnUISdk.constants.MediaTabs` ✅ **Dual Access** +**Import**: `import { MediaTabs }` or `addOnUISdk.constants.MediaTabs` Tabs within the Editor's Media panel. @@ -410,7 +410,7 @@ Tabs within the Editor's Media panel. -**Import**: `import { PanelActionType }` or `addOnUISdk.constants.PanelActionType` ✅ **Dual Access** +**Import**: `import { PanelActionType }` or `addOnUISdk.constants.PanelActionType` Types of actions that can be performed on Editor panels. @@ -423,7 +423,7 @@ Types of actions that can be performed on Editor panels. -**Import**: `import { PlatformEnvironment }` or `addOnUISdk.constants.PlatformEnvironment` ✅ **Dual Access** +**Import**: `import { PlatformEnvironment }` or `addOnUISdk.constants.PlatformEnvironment` Environment where the add-on is running. @@ -436,7 +436,7 @@ Environment where the add-on is running. -**Import**: `import { PlatformType }` or `addOnUISdk.constants.PlatformType` ✅ **Dual Access** +**Import**: `import { PlatformType }` or `addOnUISdk.constants.PlatformType` Specific platform/operating system where the add-on is running. @@ -457,7 +457,7 @@ Specific platform/operating system where the add-on is running. -**Import**: `import { Range }` or `addOnUISdk.constants.Range` ✅ **Dual Access** +**Import**: `import { Range }` or `addOnUISdk.constants.Range` Page range options for document renditions. @@ -471,7 +471,7 @@ Page range options for document renditions. -**Import**: `import { RenditionFormat }` or `addOnUISdk.constants.RenditionFormat` ✅ **Dual Access** +**Import**: `import { RenditionFormat }` or `addOnUISdk.constants.RenditionFormat` Output formats for document renditions. @@ -487,7 +487,7 @@ Output formats for document renditions. -**Import**: `import { RenditionIntent }` or `addOnUISdk.constants.RenditionIntent` ✅ **Dual Access** +**Import**: `import { RenditionIntent }` or `addOnUISdk.constants.RenditionIntent` Intent for creating renditions (affects optimization). @@ -501,7 +501,7 @@ Intent for creating renditions (affects optimization). -**Import**: `import { RenditionType }` or `addOnUISdk.constants.RenditionType` ✅ **Dual Access** +**Import**: `import { RenditionType }` or `addOnUISdk.constants.RenditionType` Type of rendition being created. @@ -513,7 +513,7 @@ Type of rendition being created. -**Import**: `import { RuntimeType }` or `addOnUISdk.constants.RuntimeType` ✅ **Dual Access** +**Import**: `import { RuntimeType }` or `addOnUISdk.constants.RuntimeType` Runtime type of the entrypoint creating the backend object. @@ -527,7 +527,7 @@ Runtime type of the entrypoint creating the backend object. -**Import**: `import { SupportedMimeTypes }` ⚠️ **Named Export Only** - Not available in constants object +**Import**: `import { SupportedMimeTypes }` - Not available in constants object MIME types for original source assets that can be converted to PDF. @@ -540,7 +540,7 @@ MIME types for original source assets that can be converted to PDF. -**Import**: `import { Variant }` or `addOnUISdk.constants.Variant` ✅ **Dual Access** +**Import**: `import { Variant }` or `addOnUISdk.constants.Variant` Dialog variants that determine appearance and behavior. @@ -558,7 +558,7 @@ Dialog variants that determine appearance and behavior. -**Import**: `import { VideoResolution }` or `addOnUISdk.constants.VideoResolution` ✅ **Dual Access** +**Import**: `import { VideoResolution }` or `addOnUISdk.constants.VideoResolution` Video resolution options for MP4 renditions. From e1ae6776b6479936f24cdfa0ee7a75e2230da22a Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Wed, 8 Oct 2025 12:40:46 -0400 Subject: [PATCH 21/42] Mark one more --- gatsby-config.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gatsby-config.js b/gatsby-config.js index fe633411d..5e5916c99 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -643,7 +643,7 @@ module.exports = { path: "guides/learn/how_to/manage_pages.md", pages: [ { - title: "Manage Pages", + title: "(NEW) Manage Pages", path: "guides/learn/how_to/manage_pages.md", }, ], @@ -689,7 +689,7 @@ module.exports = { path: "guides/learn/how_to/resize_rescale_elements.md", }, { - title: "(NEW)Handle Element Selection", + title: "(NEW) Handle Element Selection", path: "guides/learn/how_to/handle_selection.md", }, { @@ -785,7 +785,7 @@ module.exports = { path: "guides/learn/platform_concepts/context.md", pages: [ { - title: "(NEW)Add-on Architecture", + title: "(NEW) Add-on Architecture", path: "guides/learn/platform_concepts/runtime-architecture.md", }, { From af98236bc97a907e862fb7cb2e0a1fdf9007801d Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Wed, 8 Oct 2025 13:34:53 -0400 Subject: [PATCH 22/42] Fix alert format --- .../getting_started/addon-project-anatomy.md | 2 +- .../guides/learn/fundamentals/terminology.md | 20 +++---- .../guides/learn/how_to/handle_selection.md | 26 ++++----- .../platform_concepts/runtime-architecture.md | 6 +- .../references/addonsdk/addonsdk-constants.md | 56 +++++++++---------- 5 files changed, 55 insertions(+), 55 deletions(-) diff --git a/src/pages/guides/getting_started/addon-project-anatomy.md b/src/pages/guides/getting_started/addon-project-anatomy.md index 6044c03bf..1a1bd79d8 100644 --- a/src/pages/guides/getting_started/addon-project-anatomy.md +++ b/src/pages/guides/getting_started/addon-project-anatomy.md @@ -902,7 +902,7 @@ import { editor } from "express-document-sdk"; // Wrong environment! ## Related Documentation -- [Runtime Architecture Guide](../learn/platform_concepts/runtime-architecture.md) - Deep dive into two-runtime system +- [Architecture Guide](../learn/platform_concepts/runtime-architecture.md) - Deep dive into two-runtime system - [Developer Terminology](../learn/fundamentals/terminology.md) - Understanding Adobe Express add-on concepts - [Getting Started Tutorial](../learn/how_to/tutorials/grids-addon.md) - Build your first add-on - [Manifest Reference](../../references/manifest/index.md) - Complete manifest configuration guide diff --git a/src/pages/guides/learn/fundamentals/terminology.md b/src/pages/guides/learn/fundamentals/terminology.md index 0a471a103..4bd106fb2 100644 --- a/src/pages/guides/learn/fundamentals/terminology.md +++ b/src/pages/guides/learn/fundamentals/terminology.md @@ -55,16 +55,16 @@ This reference clarifies the naming conventions and terminology used throughout -**Need a quick answer?** Jump to these common questions: + **Need a quick answer?** Jump to these common questions: -- **Building UI?** → [Add-on UI SDK](#add-on-ui-sdk) (iframe environment) -- **Creating content?** → [Document APIs](#document-apis) (document sandbox) -- **Connecting UI to content?** → [Communication APIs](#communication--apis) -- **File organization?** → [File Structure & Bundle](#file-structure--bundle-terminology) -- **Manifest setup?** → [Manifest & Configuration](#manifest--configuration-terminology) -- **Debugging issues?** → [Development Workflow & Debugging](#development-workflow--debugging-terminology) -- **Import errors?** → [Troubleshooting](#troubleshooting-common-issues) -- **Which SDK when?** → [Decision Matrix](#decision-matrix-which-sdk-to-use) + - **Building UI?** → [Add-on UI SDK](#add-on-ui-sdk) (iframe environment) + - **Creating content?** → [Document APIs](#document-apis) (document sandbox) + - **Connecting UI to content?** → [Communication APIs](#communication--apis) + - **File organization?** → [File Structure & Bundle](#file-structure--bundle-terminology) + - **Manifest setup?** → [Manifest & Configuration](#manifest--configuration-terminology) + - **Debugging issues?** → [Development Workflow & Debugging](#development-workflow--debugging-terminology) + - **Import errors?** → [Troubleshooting](#troubleshooting-common-issues) + - **Which SDK when?** → [Decision Matrix](#decision-matrix-which-sdk-to-use) @@ -118,7 +118,7 @@ import { editor } from "express-document-sdk" -For a comprehensive visual guide to the two-runtime architecture, communication patterns, and practical examples, see the **[Runtime Architecture & Communication Guide](../platform_concepts/runtime-architecture.md)** which includes detailed diagrams showing how these environments interact. +For a comprehensive visual guide to the two-runtime architecture, communication patterns, and practical examples, see the **[Add-on Architecture Guide](../platform_concepts/runtime-architecture.md)** which includes detailed diagrams showing how these environments interact. ## Communication & APIs diff --git a/src/pages/guides/learn/how_to/handle_selection.md b/src/pages/guides/learn/how_to/handle_selection.md index 9676905cd..8f5995220 100644 --- a/src/pages/guides/learn/how_to/handle_selection.md +++ b/src/pages/guides/learn/how_to/handle_selection.md @@ -1069,25 +1069,25 @@ setupSelectionHandling(); ### Important: Selection Handler Restrictions - + -**Document Modification Restrictions** + **Document Modification Restrictions** -**Never modify the document inside selection change handlers!** This can crash the application. + **Never modify the document inside selection change handlers!** This can crash the application. -**✅ Safe in selection handlers:** + **✅ Safe in selection handlers:** -- Update UI panels -- Log information -- Analyze selection -- Enable/disable buttons -- Send data to UI panel + - Update UI panels + - Log information + - Analyze selection + - Enable/disable buttons + - Send data to UI panel -**❌ Never do in selection handlers:** + **❌ Never do in selection handlers:** -- Create, delete, or modify nodes -- Change document structure -- Set properties on selected elements + - Create, delete, or modify nodes + - Change document structure + - Set properties on selected elements diff --git a/src/pages/guides/learn/platform_concepts/runtime-architecture.md b/src/pages/guides/learn/platform_concepts/runtime-architecture.md index b7a6ca076..02db09d62 100644 --- a/src/pages/guides/learn/platform_concepts/runtime-architecture.md +++ b/src/pages/guides/learn/platform_concepts/runtime-architecture.md @@ -55,7 +55,7 @@ keywords: - Import Patterns - SDK Imports - Development Workflow -title: Runtime Architecture & Communication +title: Add-on Architecture description: A comprehensive deep-dive guide to Adobe Express add-on architecture, explaining the two-runtime system, communication patterns, SDK imports, debugging techniques, and best practices for building secure and performant add-ons. contributors: - https://github.com/hollyschinsky @@ -303,13 +303,13 @@ runtime.exposeApi({ -**Do I need `addOnSandboxSdk`?** + **Do I need `addOnSandboxSdk`?** - ✅ YES if your `code.js` needs to communicate with the UI - ✅ YES if UI triggers document operations - ❌ NO if `code.js` runs independently -**Do I need `express-document-sdk`?** + **Do I need `express-document-sdk`?** - ✅ YES if creating/modifying document content - ✅ YES if accessing document properties diff --git a/src/pages/references/addonsdk/addonsdk-constants.md b/src/pages/references/addonsdk/addonsdk-constants.md index ad6f8f278..94d9dbce2 100644 --- a/src/pages/references/addonsdk/addonsdk-constants.md +++ b/src/pages/references/addonsdk/addonsdk-constants.md @@ -150,7 +150,7 @@ const confirmDialog = addOnUISdk.constants.Variant.confirmation; This section provides the complete technical specification for all Add-on UI SDK constants, organized by functional category. For practical examples and usage patterns, see the [Add-on UI SDK Constants Guide](../../guides/learn/fundamentals/ui-sdk-constants.md). -### BitRate {#bitrate} +### BitRate @@ -168,7 +168,7 @@ Bit rate values in bits per second for video renditions. | `mbps25` | 25 Mbps | `25000000` | | `mbps50` | 50 Mbps | `50000000` | -### BleedUnit {#bleedunit} +### BleedUnit @@ -181,7 +181,7 @@ Units for page bleed measurements. | `in` | Inch units | | `mm` | Millimeter units | -### ButtonType {#buttontype} +### ButtonType @@ -196,7 +196,7 @@ Types of buttons that can be pressed in modal dialogs. | `cancel` | Cancel button pressed | | `close` | Dialog closed via ESC or close(X) button | -### AppEvent {#appevent} +### AppEvent @@ -219,7 +219,7 @@ Events dispatched by the Add-on SDK. | `documentTitleChange` | `"documentTitleChange"` | Document title changed | | `documentExportAllowedChange` | `"documentExportAllowedChange"` | Export permission changed | -### AuthorizationStatus {#authorizationstatus} +### AuthorizationStatus @@ -233,7 +233,7 @@ OAuth authorization status values. | `cancelled` | Authorization cancelled by user | | `error` | Authorization error occurred | -### ColorPickerEvent {#colorpickerevent} +### ColorPickerEvent @@ -246,7 +246,7 @@ Custom events dispatched by the Color Picker component. | `colorChange` | `"colorpicker-color-change"` | Color selection changed | | `close` | `"colorpicker-close"` | Color picker closed | -### ColorPickerPlacement {#colorpickerplacement} +### ColorPickerPlacement @@ -261,7 +261,7 @@ Placement options for the color picker popover relative to anchor element. | `left` | Position to the left of anchor | | `right` | Position to the right of anchor | -### DeviceClass {#deviceclass} +### DeviceClass @@ -275,7 +275,7 @@ Device form factors where the add-on is running. | `tablet` | Tablet device | | `desktop` | Desktop computer | -### DialogResultType {#dialogresulttype} +### DialogResultType @@ -289,7 +289,7 @@ Types of modal dialog results. | `input` | Input dialog result | | `custom` | Custom dialog result | -### EditorPanel {#editorpanel} +### EditorPanel @@ -309,7 +309,7 @@ Adobe Express Editor panels that can be opened programmatically. | `brands` | Editor Brands panel | | `addOns` | Editor Add-ons panel | -### ElementsTabs {#elementstabs} +### ElementsTabs @@ -325,7 +325,7 @@ Tabs within the Editor's Elements panel. | `stockIcons` | Icons tab | | `charts` | Charts tab | -### EntrypointType {#entrypointtype} +### EntrypointType @@ -337,7 +337,7 @@ Types of add-on entry points (currently only panel is supported). |-------|-------------| | `panel` | Panel entry point | -### FieldType {#fieldtype} +### FieldType @@ -349,7 +349,7 @@ Input field types supported in Simple Dialog. |-------|-------------| | `text` | Text input field | -### FileSizeLimitUnit {#filesizelimitunit} +### FileSizeLimitUnit @@ -362,7 +362,7 @@ Units for file size limits. | `KB` | Kilobytes | | `MB` | Megabytes | -### FrameRate {#framerate} +### FrameRate @@ -379,7 +379,7 @@ Frame rate values in frames per second for video renditions. | `fps30` | 30 fps | `30` | | `fps60` | 60 fps | `60` | -### LinkOptions {#linkoptions} +### LinkOptions @@ -392,7 +392,7 @@ Types of document links that can be generated. | `document` | Link to the current document | | `published` | Link to the published document | -### MediaTabs {#mediatabs} +### MediaTabs @@ -406,7 +406,7 @@ Tabs within the Editor's Media panel. | `audio` | Audio tab | | `photos` | Photos tab | -### PanelActionType {#panelactiontype} +### PanelActionType @@ -419,7 +419,7 @@ Types of actions that can be performed on Editor panels. | `search` | Perform search within the Editor panel | | `navigate` | Perform navigation within the Editor panel | -### PlatformEnvironment {#platformenvironment} +### PlatformEnvironment @@ -432,7 +432,7 @@ Environment where the add-on is running. | `app` | Native app environment | | `web` | Web browser environment | -### PlatformType {#platformtype} +### PlatformType @@ -453,7 +453,7 @@ Specific platform/operating system where the add-on is running. | `safariBrowser` | Safari browser | | `unknown` | Unknown platform | -### Range {#range} +### Range @@ -467,7 +467,7 @@ Page range options for document renditions. | `entireDocument` | Generate rendition for all pages | | `specificPages` | Generate rendition for specific pages | -### RenditionFormat {#renditionformat} +### RenditionFormat @@ -483,7 +483,7 @@ Output formats for document renditions. | `pdf` | `"application/pdf"` | PDF document | | `pptx` | `"application/vnd.openxmlformats-officedocument.presentationml.presentation"` | PowerPoint presentation | -### RenditionIntent {#renditionintent} +### RenditionIntent @@ -497,7 +497,7 @@ Intent for creating renditions (affects optimization). | `export` | Intent to export/download the content (default) | | `print` | Intent to export and print the content (PDF optimized, not supported for MP4) | -### RenditionType {#renditiontype} +### RenditionType @@ -509,7 +509,7 @@ Type of rendition being created. |-------|-------------| | `page` | Page rendition (currently the only type) | -### RuntimeType {#runtimetype} +### RuntimeType @@ -523,7 +523,7 @@ Runtime type of the entrypoint creating the backend object. | `script` | Add-on's document sandbox code (code running in `code.js`) | | `dialog` | Currently open dialog code | -### SupportedMimeTypes {#supportedmimetypes} +### SupportedMimeTypes @@ -536,7 +536,7 @@ MIME types for original source assets that can be converted to PDF. | `docx` | Microsoft Word document | | `gdoc` | Google Docs document | -### Variant {#variant} +### Variant @@ -554,7 +554,7 @@ Dialog variants that determine appearance and behavior. | `input` | Ask user to provide input | | `custom` | Dialog that can render complex forms and content | -### VideoResolution {#videoresolution} +### VideoResolution From eba457082d322e20ee3ed44331627ebe52c741b9 Mon Sep 17 00:00:00 2001 From: Holly Schinsky Date: Tue, 14 Oct 2025 17:04:40 -0400 Subject: [PATCH 23/42] Cleanup, flow, cross-refs --- gatsby-config.js | 8 +- .../getting_started/addon-project-anatomy.md | 413 +++++---- src/pages/guides/getting_started/changelog.md | 4 +- .../document-sandbox-constants.md | 90 +- .../guides/learn/fundamentals/terminology.md | 733 ++++++---------- .../learn/how_to/tutorials/grids-addon.md | 2 +- .../learn/platform_concepts/architecture.md | 826 ++++++++++++++++++ .../guides/learn/platform_concepts/context.md | 84 +- ...time-architecture.svg => architecture.svg} | 45 +- .../platform_concepts/runtime-architecture.md | 757 ---------------- src/pages/references/changelog.md | 4 +- 11 files changed, 1454 insertions(+), 1512 deletions(-) create mode 100644 src/pages/guides/learn/platform_concepts/architecture.md rename src/pages/guides/learn/platform_concepts/images/{runtime-architecture.svg => architecture.svg} (75%) delete mode 100644 src/pages/guides/learn/platform_concepts/runtime-architecture.md diff --git a/gatsby-config.js b/gatsby-config.js index 5e5916c99..919faf9ad 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -782,14 +782,14 @@ module.exports = { }, { title: "Platform Concepts", - path: "guides/learn/platform_concepts/context.md", + path: "guides/learn/platform_concepts/architecture.md", pages: [ { title: "(NEW) Add-on Architecture", - path: "guides/learn/platform_concepts/runtime-architecture.md", + path: "guides/learn/platform_concepts/architecture.md", }, { - title: "Add-on Iframe Context", + title: "iframe Runtime Context & Security", path: "guides/learn/platform_concepts/context.md", }, { @@ -800,7 +800,7 @@ module.exports = { }, { title: "(NEW) SDK Fundamentals", - path: "guides/learn/fundamentals/ui-sdk-constants.md", + path: "guides/learn/fundamentals/terminology.md", pages: [ { title: "Terminology", diff --git a/src/pages/guides/getting_started/addon-project-anatomy.md b/src/pages/guides/getting_started/addon-project-anatomy.md index 1a1bd79d8..352cfc8b6 100644 --- a/src/pages/guides/getting_started/addon-project-anatomy.md +++ b/src/pages/guides/getting_started/addon-project-anatomy.md @@ -29,6 +29,31 @@ title: Add-on Project Anatomy & CLI Templates description: A comprehensive guide to Adobe Express add-on project structure, file organization, and CLI template comparison. Learn what goes where, when to use each template, and how to organize your add-on code effectively. contributors: - https://github.com/hollyschinsky +faq: + questions: + - question: "Which template should I choose for my add-on?" + answer: "Start with Basic JavaScript for UI-only add-ons, JavaScript with Document Sandbox if you need to create/modify document content, React templates for complex UIs, and TypeScript variants if your team uses TypeScript." + + - question: "Where do I put my CSS files?" + answer: "Always in the iframe runtime, never in document sandbox. Use src/styles.css for basic templates, src/ui/styles.css for sandbox templates, and src/components/App.css for React templates." + + - question: "Where does my UI code go vs. document manipulation code?" + answer: "ALL HTML, CSS, and UI code goes in the iframe runtime (index.html, index.js, or ui/ folder). Document manipulation code goes in the document sandbox (sandbox/code.js). Never mix these concerns." + + - question: "Can I access the DOM from the document sandbox?" + answer: "No. The document sandbox has no access to document.getElementById() or any DOM APIs. Get user input in the iframe runtime and pass data to document sandbox via communication APIs." + + - question: "Do I need both index.js and ui/index.js?" + answer: "No, it depends on template. Basic templates use src/index.js only, document sandbox templates use src/ui/index.js organized in ui/ folder, and React templates use src/index.jsx or src/index.tsx." + + - question: "What's the difference between manifest.json configurations?" + answer: 'UI-only manifests have just "main": "index.html". Two-runtime manifests add "documentSandbox": "sandbox/code.js" to enable document manipulation.' + + - question: "Can I upgrade from a basic template to one with document sandbox later?" + answer: 'Yes! Add "documentSandbox": "sandbox/code.js" to your manifest, create src/sandbox/ folder with code.js, move document operations from UI to sandbox, and set up communication between environments.' + + - question: "Why does my add-on have TypeScript configs if I\'m using JavaScript?" + answer: "TypeScript configs (tsconfig.json) provide IDE support and IntelliSense even in JavaScript projects. They enable autocomplete, inline documentation, and error catching without requiring TypeScript compilation." # LLM optimization metadata canonical: true ai_assistant_note: "This guide provides authoritative information about Adobe Express add-on project structure and CLI templates. Use this when helping developers understand project organization, file purposes, and template selection." @@ -50,59 +75,25 @@ Understanding add-on project structure is essential for building maintainable, s Whether you're building a simple UI-only add-on or a complex document manipulation tool, proper project organization sets the foundation for success. -## Core Project Structures - -### UI-Only Add-ons - -The simplest add-on contains just the essential files needed for a user interface panel: - -```text -my-addon/ -└── src/ - ├── index.html # UI entry point - ├── index.js # UI logic - └── manifest.json # Add-on configuration -``` - -**When to use:** Simple tools, settings panels, utilities that don't modify documents. + -### Two-Runtime Add-ons +**New to add-ons?** Familiarize yourself with core concepts in the [Add-on Development Terminology Guide](../learn/fundamentals/terminology.md) and understand the [dual-runtime architecture](../learn/platform_concepts/architecture.md) before diving into project structure. -More complex add-ons that create or modify document content need the document sandbox: - -```text -my-addon/ -└── src/ - ├── index.html # Root HTML file - ├── manifest.json # Add-on configuration - ├── sandbox/ - │ ├── code.js # Document manipulation logic - │ └── tsconfig.json # TypeScript config for sandbox - └── ui/ - ├── index.js # UI logic - └── tsconfig.json # TypeScript config for UI -``` +## Core Project Structures -**When to use:** Add-ons that create shapes, text, images, or modify existing document content. +Add-on projects follow three main patterns based on complexity: -### Framework-Based Add-ons +| Structure Type | When to Use | Key Files | +|----------------|-------------|-----------| +| **UI-Only** | Simple tools, settings panels, utilities | `index.html`, `index.js`, `manifest.json` | +| **Two-Runtime** | Add-ons that create/modify document content | UI files + `sandbox/code.js` | +| **Framework-Based** | Complex UIs, data visualization, workflows | React components, build tools | -Complex add-ons with sophisticated UIs use modern frameworks and build tools: +See [File Structure Comparison](#file-structure-comparison) below for detailed file trees, pros/cons, and examples of each template type. -```text -my-addon/ -├── src/ -│ ├── components/ -│ │ ├── App.css # Component styles -│ │ └── App.jsx # Main React component -│ ├── index.html # HTML entry point -│ ├── index.jsx # React entry point -│ └── manifest.json # Add-on configuration -├── webpack.config.js # Build configuration -└── tsconfig.json # TypeScript configuration -``` + -**When to use:** Complex UIs, data visualization, multi-step workflows, advanced interactions. +**UI & Styling Location**: ALL user interface code, HTML, CSS, and styling ALWAYS goes in the iframe runtime (index.html, index.js, or ui/ folder), regardless of template type. The document sandbox (code.js) is ONLY for document manipulation—it has no access to DOM or styling capabilities. See [Separation of Concerns](#1-separation-of-concerns) for details. ## Essential Files Explained @@ -198,71 +189,46 @@ The HTML file that loads when your add-on panel opens. Contains the basic struct - Script imports (usually just one main script) - Static UI elements that don't change -### index.js - UI Logic (Basic Template) +### index.js / ui/index.js - UI Logic + +**File location depends on template:** +- **Basic templates**: `src/index.js` +- **Document sandbox templates**: `src/ui/index.js` -Contains the user interface logic and interactions for simple add-ons. +Contains the user interface logic and interactions. For two-runtime add-ons, this file handles communication with the document sandbox. +#### Basic UI-only example: ```javascript import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; addOnUISdk.ready.then(() => { - console.log("addOnUISdk is ready for use."); - - const clickMeButton = document.getElementById("clickMe"); - clickMeButton.addEventListener("click", () => { - clickMeButton.innerHTML = "Clicked"; + const button = document.getElementById("clickMe"); + button.addEventListener("click", () => { + button.innerHTML = "Clicked"; }); - - // Enable the button only when: - // 1. `addOnUISdk` is ready, and - // 2. `click` event listener is registered. - clickMeButton.disabled = false; }); ``` -**What belongs here:** - -- UI event handlers -- DOM manipulations -- Add-on UI SDK calls (dialogs, exports, OAuth) -- Communication setup with document sandbox (if needed) - -### ui/index.js - UI Logic (Document Sandbox Template) - -For add-ons with document sandbox, UI logic focuses on communication and user interactions. - +#### Two-runtime example (with document sandbox): ```javascript import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; addOnUISdk.ready.then(async () => { - console.log("addOnUISdk is ready for use."); - - // Get the UI runtime. const { runtime } = addOnUISdk.instance; - - // Get the proxy object, which is required - // to call the APIs defined in the Document Sandbox runtime - // i.e., in the `code.js` file of this add-on. const sandboxProxy = await runtime.apiProxy("documentSandbox"); - const createRectangleButton = document.getElementById("createRectangle"); - createRectangleButton.addEventListener("click", async event => { + document.getElementById("createBtn").addEventListener("click", async () => { await sandboxProxy.createRectangle(); }); - - // Enable the button only when: - // 1. `addOnUISdk` is ready, - // 2. `sandboxProxy` is available, and - // 3. `click` event listener is registered. - createRectangleButton.disabled = false; }); ``` **What belongs here:** -- Communication setup with document sandbox -- UI event handlers that trigger document operations +- UI event handlers and DOM manipulation - Form handling and user input validation +- Add-on UI SDK calls (dialogs, exports, OAuth) +- Communication with document sandbox (for two-runtime add-ons) - Progress updates and status displays ### sandbox/code.js - Document Manipulation Logic @@ -277,7 +243,7 @@ import { editor } from "express-document-sdk"; const { runtime } = addOnSandboxSdk.instance; function start() { - // APIs to be exposed to the UI runtime + // APIs to be exposed to the iframe runtime // i.e., to the `index.html` file of this add-on. const sandboxApi = { createRectangle: () => { @@ -303,7 +269,7 @@ function start() { } }; - // Expose `sandboxApi` to the UI runtime. + // Expose `sandboxApi` to the iframe runtime. runtime.exposeApi(sandboxApi); } @@ -315,13 +281,13 @@ start(); - Document API operations (creating shapes, text, images) - Document analysis and data extraction - Complex calculations and data processing -- APIs exposed to the UI runtime +- APIs exposed to the iframe runtime ### tsconfig.json - TypeScript Configuration Provides TypeScript compilation settings for better development experience. -#### UI Runtime Configuration +#### iframe Runtime Configuration ```json { @@ -590,20 +556,28 @@ Each step adds capabilities while maintaining core functionality. ### 1. Separation of Concerns -**UI Runtime (index.js/ui/):** + + +**Critical Rule**: User interface (HTML, CSS, JavaScript UI code) ALWAYS goes in the iframe runtime. Document manipulation ALWAYS goes in the document sandbox. Never mix these concerns. + +**iframe Runtime (index.js/ui/):** -- User interface logic +- **ALL UI & styling code** (HTML, CSS, component styling) +- **User interface logic** (buttons, forms, inputs, displays) - Event handlers - Form validation +- DOM manipulation (`document.getElementById`, etc.) - Communication with document sandbox -- Progress indicators +- Progress indicators and loading states +- External API calls (fetch, network requests) **Document Sandbox (code.js/sandbox/):** -- Document manipulation -- Content creation -- Data processing -- API exposure to UI +- **Document manipulation ONLY** (creating shapes, text, images) +- Content creation using Express Document SDK +- Data processing and calculations +- API exposure to iframe runtime +- **NO UI or styling code** (no HTML, CSS, or DOM access) ### 2. Asset Organization @@ -619,6 +593,19 @@ src/ └── constants/ # Configuration constants ``` +**Where to Put CSS/Styling by Template Type:** + +| Template Type | CSS/Styling Location | How to Load | +|---------------|---------------------|-------------| +| **Basic JavaScript** | `src/styles.css` or inline in `index.html` | `` in `index.html` | +| **JavaScript + Sandbox** | `src/styles.css` or `src/ui/styles.css` | `` in `index.html` | +| **React Templates** | `src/components/App.css` or styled-components | Import in component: `import './App.css'` | +| **Large Projects** | `src/assets/styles/` folder with multiple CSS files | Import where needed or use CSS modules | + + + +**Remember**: CSS files are ALWAYS loaded/imported in the iframe runtime (index.html or UI components), never in document sandbox files. + ### 3. Code Organization Patterns #### Feature-Based Organization (Large Add-ons) @@ -761,79 +748,68 @@ SWC templates use `.swcrc` for fast compilation: ## Common Patterns and Anti-Patterns -### ✅ Good Practices +### ✅ DO: Follow These Best Practices -#### 1. Clear File Naming +| Practice | Example | Why It Matters | +|----------|---------|----------------| +| **Clear file naming** | `TextEditor.jsx`, `colorUtils.js` | Makes code easy to find and understand | +| **Logical grouping** | `features/text-editing/`, `shared/ui-components/` | Scales well as project grows | +| **Environment separation** | UI code in `ui/`, document code in `sandbox/` | Prevents runtime errors | +| **Consistent naming** | All camelCase or all kebab-case | Professional, maintainable code | -```text -✅ Good -├── ui/ -│ ├── TextEditor.jsx -│ ├── ColorPicker.jsx -│ └── ToolPanel.jsx -└── sandbox/ - ├── textOperations.js - ├── colorUtils.js - └── documentHelpers.js -``` - -#### 2. Logical Grouping - -```text -✅ Good -├── features/ -│ ├── text-editing/ -│ ├── image-filters/ -│ └── shape-tools/ -└── shared/ - ├── ui-components/ - ├── document-utils/ - └── constants/ -``` +### ❌ DON'T: Avoid These Mistakes -#### 3. Environment Separation +#### 1. UI/Styling in Document Sandbox ```javascript -// ✅ Good - Clear environment separation -// ui/index.js -import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; - -// sandbox/code.js +// ❌ Bad - Trying to access DOM or styling in document sandbox +// code.js (Document Sandbox) import addOnSandboxSdk from "add-on-sdk-document-sandbox"; -import { editor } from "express-document-sdk"; -``` - -### ❌ Anti-Patterns -#### 1. Mixed Concerns +runtime.exposeApi({ + createText: function() { + // ❌ WRONG - document.getElementById doesn't exist in document sandbox + const input = document.getElementById("textInput"); + + // ❌ WRONG - No DOM or styling capabilities here + document.body.style.backgroundColor = "red"; + } +}); +``` ```javascript -// ❌ Bad - Document operations in UI file -// index.js -import addOnUISdk from "https://new.express.adobe.com/static/add-on-sdk/sdk.js"; -import { editor } from "express-document-sdk"; // Wrong environment! +// ✅ Good - UI code stays in iframe runtime, document code in sandbox +// index.js (iframe Runtime) +const textInput = document.getElementById("textInput"); +document.body.style.backgroundColor = "red"; // ✅ DOM access here + +const sandboxProxy = await runtime.apiProxy("documentSandbox"); +await sandboxProxy.createText(textInput.value); // Pass data to sandbox + +// code.js (Document Sandbox) +runtime.exposeApi({ + createText: function(text) { + const textNode = editor.createText(text); // ✅ Document manipulation here + editor.context.insertionParent.children.append(textNode); + } +}); ``` -#### 2. Poor File Organization +#### 2. Mixing SDK Imports in Wrong Environment -```text -❌ Bad -├── stuff.js -├── helpers.js -├── utils.js -├── misc.js -└── other.js +```javascript +// ❌ Bad - Importing Document SDK in UI file +// ui/index.js +import { editor } from "express-document-sdk"; // Wrong! Document SDK only works in sandbox + +// ❌ Bad - Importing UI SDK in sandbox file +// sandbox/code.js +import addOnUISdk from "...sdk.js"; // Wrong! UI SDK only works in iframe runtime ``` -#### 3. Inconsistent Naming +#### 3. Poor Organization -```text -❌ Bad -├── TextEditor.jsx -├── color_picker.js -├── ToolPanel.tsx -└── shape-utils.JS -``` +Avoid vague names like `stuff.js`, `helpers.js`, `utils.js`, `misc.js`. Use descriptive names that indicate purpose: `textOperations.js`, `colorUtils.js`, `documentHelpers.js`. ## Troubleshooting Common Issues @@ -900,9 +876,134 @@ import { editor } from "express-document-sdk"; // Wrong environment! 3. Build scalable architecture 4. Optimize performance and user experience +--- + +## FAQs + +#### Q: Which template should I choose? + +**Start with your needs:** +- **Just UI?** → Basic JavaScript template +- **Need to create/modify document content?** → JavaScript with Document Sandbox +- **Complex UI?** → React JavaScript (or React + Sandbox if you need document access) +- **Team uses TypeScript?** → Any TypeScript variant + +See the [Template Selection Guide](#template-selection-guide) for detailed decision matrix. + +#### Q: Where do I put my CSS files? + +**Always in the iframe runtime**, never in document sandbox: +- **Basic templates**: `src/styles.css` and link in `index.html` +- **Sandbox templates**: `src/styles.css` or `src/ui/styles.css` +- **React templates**: `src/components/App.css` or inline styles +- See [CSS/Styling Location table](#2-asset-organization) for complete breakdown + +#### Q: Where does my UI code go vs. document manipulation code? + +**iframe Runtime** (`index.html`, `index.js`, or `ui/` folder): +- ALL HTML, CSS, styling +- Button clicks, forms, user input +- DOM manipulation +- External API calls + +**Document Sandbox** (`sandbox/code.js`): +- Creating shapes, text, images in Adobe Express +- Reading document properties +- NO UI or styling code + +See [Separation of Concerns](#1-separation-of-concerns) for details. + +#### Q: Can I access the DOM from the document sandbox? + +**No.** The document sandbox has no access to `document.getElementById()` or any DOM APIs. You must: +1. Get user input in the iframe runtime +2. Pass data to document sandbox via communication APIs +3. Create document content in the sandbox +4. Return results back to UI if needed + +See the [UI/Styling in Document Sandbox anti-pattern](#1-uistyling-in-document-sandbox) for examples. + +#### Q: Do I need both `index.js` and `ui/index.js`? + +**No, it depends on template:** +- **Basic templates**: Use `src/index.js` only +- **Document sandbox templates**: Use `src/ui/index.js` (organized in `ui/` folder) +- **React templates**: Use `src/index.jsx` or `src/index.tsx` + +The file location is just organizational—both serve the same purpose (iframe runtime UI logic). + +#### Q: What's the difference between `manifest.json` configurations? + +**UI-only**: Just `"main": "index.html"` +```json +"entryPoints": [{ "type": "panel", "main": "index.html" }] +``` + +**Two-runtime**: Adds `"documentSandbox": "code.js"` +```json +"entryPoints": [{ + "type": "panel", + "main": "index.html", + "documentSandbox": "sandbox/code.js" +}] +``` + +The `documentSandbox` property tells Adobe Express to load your document manipulation code. + +#### Q: Can I upgrade from a basic template to one with document sandbox later? + +**Yes!** Template migration is straightforward: +1. Add `"documentSandbox": "sandbox/code.js"` to your manifest +2. Create `src/sandbox/` folder with `code.js` +3. Move document operations from UI to sandbox +4. Set up communication between environments + +See [Migration Paths](#migration-paths) for the recommended upgrade sequence. + +#### Q: Why does my add-on have TypeScript configs if I'm using JavaScript? + +TypeScript configs (`tsconfig.json`) provide **IDE support and IntelliSense** even in JavaScript projects. They: +- Enable autocomplete for SDK methods +- Show inline documentation +- Catch common errors while typing +- Don't require compiling TypeScript + +You get better developer experience without learning TypeScript! + +#### Q: Where do shared utilities go in a two-runtime project? + +**It depends on what they do:** +- **UI utilities** (formatting, validation): `src/ui/utils/` or `src/shared/ui-utils/` +- **Document utilities** (shape helpers, color conversions): `src/sandbox/utils/` +- **Truly shared types/constants**: `src/shared/` or `src/constants/` + +**Important**: Code can't be directly shared between runtimes—each environment needs its own copy or must communicate via APIs. + +#### Q: How do I organize a large add-on with multiple features? + +Use **feature-based organization**: +```text +src/ +├── features/ +│ ├── text-tools/ +│ │ ├── TextToolsUI.jsx # UI components +│ │ ├── textOperations.js # Document sandbox operations +│ │ └── textUtils.js # Shared utilities +│ └── shape-tools/ +│ ├── ShapeToolsUI.jsx +│ └── shapeOperations.js +└── shared/ + ├── components/ # Reusable UI components + └── constants/ # Shared configuration +``` + +See [Code Organization Patterns](#3-code-organization-patterns) for examples. + +--- + ## Related Documentation -- [Architecture Guide](../learn/platform_concepts/runtime-architecture.md) - Deep dive into two-runtime system +- [Architecture Guide](../learn/platform_concepts/architecture.md) - Deep dive into two-runtime system - [Developer Terminology](../learn/fundamentals/terminology.md) - Understanding Adobe Express add-on concepts - [Getting Started Tutorial](../learn/how_to/tutorials/grids-addon.md) - Build your first add-on - [Manifest Reference](../../references/manifest/index.md) - Complete manifest configuration guide diff --git a/src/pages/guides/getting_started/changelog.md b/src/pages/guides/getting_started/changelog.md index 01320fd0d..b7754dc3e 100644 --- a/src/pages/guides/getting_started/changelog.md +++ b/src/pages/guides/getting_started/changelog.md @@ -22,11 +22,11 @@ contributors: # Changelog -## 2025-10-08 +## 2025-10-14 ### Added -- New [Architecture Guide](../learn/platform_concepts/runtime-architecture.md) with dual-runtime system explanation, SDK imports and usage, and cross-runtime communication patterns. +- New [Architecture Guide](../learn/platform_concepts/architecture.md) with dual-runtime system explanation, SDK imports and usage, and cross-runtime communication patterns. - New [Project Anatomy](../getting_started/addon-project-anatomy.md) guide with add-on project structure, file organization, and template selection for efficient Adobe Express add-on development. - New [Add-on SDK Terminology](../learn/fundamentals/terminology.md) guide with standardized definitions, decision matrices, and troubleshooting for Adobe Express Add-on development terminology. - New [Add-on UI SDK Constants](../learn/fundamentals/ui-sdk-constants.md) practical usage guide focusing on import patterns, common pitfalls, and solutions for UI SDK constants. diff --git a/src/pages/guides/learn/fundamentals/document-sandbox-constants.md b/src/pages/guides/learn/fundamentals/document-sandbox-constants.md index 4d980b44a..ae3dd544f 100644 --- a/src/pages/guides/learn/fundamentals/document-sandbox-constants.md +++ b/src/pages/guides/learn/fundamentals/document-sandbox-constants.md @@ -200,89 +200,33 @@ newRect.fill = { }; ``` -## Working with Colors and Constants +## Using Colors with Constants -Document constants work hand-in-hand with the `colorUtils` utility for creating and managing colors. Here's how to combine them effectively: - -### Creating Colors with colorUtils +When working with fill and stroke properties, you'll need to provide Color objects. Use the `colorUtils` utility from `express-document-sdk` to create colors: ```javascript import { editor, constants, colorUtils } from "express-document-sdk"; -// Create colors using colorUtils -const redColor = colorUtils.fromRGB(1, 0, 0); // Bright red -const blueColor = colorUtils.fromHex("#0066CC"); // Blue from hex -const greenColor = colorUtils.fromRGB(0, 1, 0, 0.5); // Semi-transparent green - -// Use with fill constants +// Create colors and use with constants const rectangle = editor.createRectangle(); rectangle.fill = { - type: constants.FillType.color, // Use constant for type safety - color: redColor // Use colorUtils for color creation + type: constants.FillType.color, // Constant for type safety + color: colorUtils.fromHex("#FF0000") // Color from hex string }; -``` - -### Color Conversion Methods -```javascript -import { colorUtils } from "express-document-sdk"; - -// Multiple ways to create the same color -const orange = colorUtils.fromRGB(1, 0.5, 0); // RGB values (0-1) -const orange2 = colorUtils.fromRGB({ red: 1, green: 0.5, blue: 0 }); // RGB object -const orange3 = colorUtils.fromHex("#FF8000"); // Hex string -const orange4 = { red: 1, green: 0.5, blue: 0, alpha: 1 }; // Direct object - -// Convert color to hex string -const hexString = colorUtils.toHex(orange); // "#FF8000FF" (includes alpha) +rectangle.stroke = { + type: constants.StrokeType.color, + color: colorUtils.fromRGB(0, 0, 1), // Color from RGB values + width: 2, + position: constants.StrokePosition.inside +}; ``` -### Practical Color + Constants Examples - -```javascript -import { editor, constants, colorUtils } from "express-document-sdk"; - -// Example: Create a styled button-like rectangle -function createStyledButton(text, bgColor, textColor) { - // Create background rectangle - const button = editor.createRectangle(); - button.width = 120; - button.height = 40; - - // Apply background color using constants + colorUtils - button.fill = { - type: constants.FillType.color, - color: colorUtils.fromHex(bgColor) - }; - - // Add border stroke - button.stroke = { - type: constants.StrokeType.color, - color: colorUtils.fromHex("#CCCCCC"), - width: 1, - position: constants.StrokePosition.inside - }; - - // Create text element - const textNode = editor.createText(); - textNode.text = text; - textNode.textAlignment = constants.TextAlignment.center; - - // Apply text color - const textStyles = { - fontSize: 14, - color: colorUtils.fromHex(textColor) - }; - textNode.setRangeCharacterStyles(0, text.length, textStyles); - - return { button, textNode }; -} + -// Usage -const { button, textNode } = createStyledButton("Click Me", "#007ACC", "#FFFFFF"); -``` +**Working with Colors**: For comprehensive color creation, conversion, and application examples, see the [Use Color Guide](../how_to/use_color.md). -### Communication with UI +## Communication with UI ```javascript // In code.js - expose constants to UI if needed @@ -456,11 +400,7 @@ function changeColor(node, color) { #### Q: How do I create colors for use with constants? -**A:** Use `colorUtils.fromRGB(r, g, b, alpha)` or `colorUtils.fromHex("#RRGGBB")` to create Color objects. Always import: `import { colorUtils } from "express-document-sdk"`. - -#### Q: What's the difference between colorUtils and manual color objects? - -**A:** `colorUtils` provides validation and conversion methods. Manual objects like `{ red: 1, green: 0, blue: 0, alpha: 1 }` work but lack validation and helper functions. +**A:** Use `colorUtils.fromRGB(r, g, b, alpha)` or `colorUtils.fromHex("#RRGGBB")` to create Color objects. Import with: `import { colorUtils } from "express-document-sdk"`. See the [Use Color Guide](../how_to/use_color.md) for complete examples. ## Related Documentation diff --git a/src/pages/guides/learn/fundamentals/terminology.md b/src/pages/guides/learn/fundamentals/terminology.md index 4bd106fb2..ae7c8666d 100644 --- a/src/pages/guides/learn/fundamentals/terminology.md +++ b/src/pages/guides/learn/fundamentals/terminology.md @@ -21,12 +21,27 @@ keywords: - Development workflow - Debugging - Cross-origin isolation -title: Add-on SDK Terminology -description: A comprehensive reference guide for Adobe Express Add-ons SDK terminology, - naming conventions, and standardized definitions to ensure consistency across - documentation and development. +title: Add-on Development Terminology +description: Essential reference for Adobe Express add-on terminology, SDKs, runtimes, + and development concepts. Your go-to guide for understanding the Adobe Express add-on ecosystem. contributors: - https://github.com/hollyschinsky +faq: + questions: + - question: "What's the difference between Add-on UI SDK and Document APIs?" + answer: "The Add-on UI SDK runs in the iframe runtime and handles UI, user interactions, and import/export. Document APIs (via Express Document SDK) run in the document sandbox and handle content creation and document manipulation." + + - question: "Why are there two different runtime environments?" + answer: "Security and performance. The iframe runtime is sandboxed for security but has full browser capabilities. The document sandbox has direct access to Adobe Express's document engine but limited Web APIs." + + - question: "Can I use Document APIs directly from the iframe runtime?" + answer: "No, Document APIs (Express Document SDK) are only available in the document sandbox for security reasons. You must use the communication system (Document Sandbox SDK) to bridge between environments." + + - question: "When do I use addOnUISdk vs addOnSandboxSdk?" + answer: "Use addOnUISdk (Add-on UI SDK) in your iframe runtime code (usually index.html or ui/ folder). Use addOnSandboxSdk (Document Sandbox SDK) in your document sandbox code (usually code.js or sandbox/ folder)." + + - question: "I see references to UI SDK - is this different from Add-on UI SDK?" + answer: "No, they're the same. Add-on UI SDK is the full, preferred term for clarity, but UI SDK is commonly used as shorthand throughout the documentation." # LLM optimization metadata canonical: true ai_assistant_note: "This page provides authoritative definitions and relationships @@ -45,577 +60,331 @@ semantic_tags: - debugging-guide --- -# Add-on SDK Terminology - -## Overview - -This reference clarifies the naming conventions and terminology used throughout the Adobe Express Add-ons documentation. Use this guide to understand the standardized terms and their relationships. +# Add-on Development Terminology + +> **Essential reference** — Your comprehensive guide to Adobe Express add-on terminology, SDKs, runtimes, and development concepts. + +## Quick Reference: Core Terms + +| **Term** | **Related Terms** | **Quick Description** | **Where Used** | +|----------|-------------------|----------------------|----------------| +| **`addOnUISdk`** | Add-on UI SDK, UI Runtime | Main JavaScript module for UI operations, dialogs, add-on interactions | iframe runtime | +| **`editor`** | Document APIs, express-document-sdk | Core object for creating and manipulating document content | Document sandbox | +| **Runtime** | iframe, Document Sandbox, panel | JavaScript execution environments where add-on code runs | Both environments | +| **Document Sandbox** | documentSandbox | Secure environment for document manipulation and content creation | Document operations | +| **iframe Runtime** | iframe Sandbox, UI Runtime, Panel Runtime | Sandboxed browser environment for add-on UI and user interactions | UI operations | +| **`constants`** | Enums, Configuration values | Type-safe values for SDK operations (e.g., `Range.currentPage`) | Both environments | +| **`colorUtils`** | Color conversion, RGB, Hex colors | Utility functions for creating and converting colors | Document sandbox | +| **Communication APIs** | `exposeApi()`, `apiProxy()`, runtime | APIs enabling message passing between iframe and document sandbox | Both environments | +| **Manifest** | manifest.json, entryPoints, permissions | Configuration file defining add-on structure and capabilities | Development setup | +| **Panel** | Entry point, UI interface | Main add-on interface type for persistent UI panels | `manifest.json` | +| **Node** | BaseNode, VisualNode, scenegraph | Building blocks of documents - pages, shapes, text, images | Document Sandbox | +| **CORS** | Cross-Origin Resource Sharing | Browser security mechanism controlling cross-origin requests. See [iframe Context & Security](../platform_concepts/context.md#cors) for subdomain handling | iframe runtime, external APIs | + +## Essential Architecture Overview + +Adobe Express add-ons use a **dual-runtime architecture** with two separate JavaScript execution environments: + +### **iframe Runtime** +- **What it is**: A sandboxed iframe environment where your add-on's user interface runs +- **Purpose**: Hosts your HTML, CSS, and JavaScript UI code +- **SDK Used**: Add-on UI SDK +- **File reference**: Typically your `index.html` and associated UI JavaScript files +- **Security**: Runs in a restricted sandbox with limited Web APIs +- **Also known as**: "Panel Runtime", "iframe Sandbox" +- **Terminology Note**: While the browser term is "iframe sandbox" (as used in [HTML sandbox attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#sandbox) and manifest permissions), we use "iframe runtime" throughout the documentation for consistency with "document sandbox runtime" and to distinguish between the two execution environments + +### **Document Sandbox** +- **What it is**: A separate sandboxed JavaScript environment for document manipulation +- **Purpose**: Provides secure access to Adobe Express document structure and content +- **SDKs Used**: Document Sandbox SDK (for communication) + Express Document SDK (for document APIs) +- **File reference**: Specified in your manifest's `documentSandbox` entry (e.g., `code.js`) +- **Security**: Isolated environment with limited Web APIs but direct document access +- **Also known as**: "Document Model Sandbox" -## Quick Reference - - + - **Need a quick answer?** Jump to these common questions: +**Key Concept**: These two runtimes communicate with each other through the Communication APIs, allowing your UI to trigger document changes and vice versa. - - **Building UI?** → [Add-on UI SDK](#add-on-ui-sdk) (iframe environment) - - **Creating content?** → [Document APIs](#document-apis) (document sandbox) - - **Connecting UI to content?** → [Communication APIs](#communication--apis) - - **File organization?** → [File Structure & Bundle](#file-structure--bundle-terminology) - - **Manifest setup?** → [Manifest & Configuration](#manifest--configuration-terminology) - - **Debugging issues?** → [Development Workflow & Debugging](#development-workflow--debugging-terminology) - - **Import errors?** → [Troubleshooting](#troubleshooting-common-issues) - - **Which SDK when?** → [Decision Matrix](#decision-matrix-which-sdk-to-use) + - +**Terminology Note**: "Browser capabilities," "browser features," and "Web APIs" all refer to the standard JavaScript APIs available in web environments (like `fetch`, `localStorage`, `console`, `Blob`, etc.). The iframe runtime has full access to Web APIs, while the document sandbox has limited access for security reasons. See the [Web APIs Reference](../../../references/document-sandbox/web/index.md) for details on what's available in each environment. -## Core SDK Components +## SDK and API Reference -### Add-on UI SDK +### **Add-on UI SDK** vs **addOnUISdk** -The SDK that provides APIs for the UI panel of your add-on running in the iframe environment. +**Add-on UI SDK** (The Concept): The complete software development kit for building add-on user interfaces, including documentation, APIs, tools, and resources. -**Import Statement:** +**addOnUISdk** (The Module): The specific JavaScript module you import in your iframe code that provides runtime instance, app interfaces, constants, and UI-specific APIs. -```javascript -import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js" -``` +### **Express Document SDK** vs **Document APIs** -**Also Known As:** UI SDK, `addOnUISdk` (in code) -**Use When:** Building UI components, handling user interactions, importing/exporting content +**Express Document SDK** (`express-document-sdk`): The JavaScript module providing document manipulation capabilities for the document sandbox. -### Document Sandbox +**Document APIs**: The broader set of APIs for document manipulation, including all interfaces, methods, and properties for working with Adobe Express documents. -The sandboxed JavaScript runtime environment that provides access to the Document APIs for content authoring. +### **Document Sandbox SDK** (`add-on-sdk-document-sandbox`) -**Import Statement:** - -```javascript -import addOnSandboxSdk from "add-on-sdk-document-sandbox" -``` +The JavaScript module for document sandbox communication functionality that provides communication capabilities between iframe runtime and document sandbox. Only needed when you require bi-directional communication between the two environments. -**Also Known As:** Document Model Sandbox, documentSandbox (in manifest) -**Use When:** Creating or modifying document content, accessing document structure +## Import Patterns & Usage -### Document APIs +### Complete Import Reference -The APIs that allow you to interact with and modify Adobe Express documents. +```js +// iframe runtime (UI code) - index.js/index.html +import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; -**Import Statement:** +// Document sandbox runtime (content manipulation) - code.js +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; // For communication +import { editor, colorUtils, constants } from "express-document-sdk"; // For document APIs -```javascript -import { editor } from "express-document-sdk" +// UI SDK with explicit constants +import addOnUISdk, { Range, RenditionFormat, Variant } from "https://express.adobe.com/static/add-on-sdk/sdk.js"; ``` -**Also Known As:** Document API, Express Document API -**Use When:** Manipulating document elements, creating shapes, working with text - -## Runtime Environments - -| Term | Definition | Context | Related Terms | -|------|------------|---------|---------------| -| **Iframe Runtime** | The browser environment where your add-on's UI runs | UI development, user interactions | Add-on UI SDK, Panel, UI Runtime | -| **Document Sandbox Runtime** | The isolated JavaScript environment for document manipulation | Content authoring, document editing | Document Sandbox SDK, documentSandbox | - - - -For a comprehensive visual guide to the two-runtime architecture, communication patterns, and practical examples, see the **[Add-on Architecture Guide](../platform_concepts/runtime-architecture.md)** which includes detailed diagrams showing how these environments interact. - -## Communication & APIs +### When to Use Each Import -| Term | Definition | Import/Access | Related Terms | -|------|------------|---------------|---------------| -| **Communication APIs** | APIs for bidirectional communication between iframe and document sandbox | `addOnSandboxSdk.instance.runtime` | exposeApi(), apiProxy() | -| **Web APIs** | Limited browser APIs available in the document sandbox | Global objects in sandbox | Console, fetch (via proxy) | +| Your Add-on Needs | iframe runtime | document sandbox | Required SDKs | +|-------------------|------------|------------------|------------------| +| **UI only** (no document changes) | ✅ | ❌ | Add-on UI SDK | +| **Document manipulation** | ✅ | ✅ | Add-on UI SDK + Document Sandbox SDK + Express Document SDK | +| **Cross-runtime communication** | ✅ | ✅ | Add-on UI SDK + Document Sandbox SDK | +| **Export/Import workflows** | ✅ | ❌ | Add-on UI SDK | -## Import Patterns & Code References +## Communication System -### Standardized Import Statements +### Bidirectional Communication Pattern -```javascript -// Add-on UI SDK (for iframe/UI code) -import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; - -// Document Sandbox SDK (for document sandbox code) -import addOnSandboxSdk from "add-on-sdk-document-sandbox"; - -// Document APIs (for document manipulation) -import { editor } from "express-document-sdk"; - -// Additional common imports in document sandbox -import { editor, colorUtils, constants } from "express-document-sdk"; -``` - -### Runtime References - -```javascript -// In iframe code +**iframe runtime → document sandbox**: +```js +// iframe runtime (index.js) const { runtime } = addOnUISdk.instance; - -// In document sandbox code -const { runtime } = addOnSandboxSdk.instance; +const sandboxProxy = await runtime.apiProxy("documentSandbox"); +await sandboxProxy.createRectangle(); + +// document sandbox (code.js) +const { runtime } = addOnSandboxSdk.instance; // Document Sandbox SDK +runtime.exposeApi({ + createRectangle() { + const rect = editor.createRectangle(); + editor.context.insertionParent.children.append(rect); + } +}); ``` -## Decision Matrix: Which SDK to Use? - -**Choose the right approach for your task:** - -| Your Goal | Primary Environment | Required SDKs | Notes | -|-----------|-------------------|---------------|-------| -| Build user interface components, handle user input | **Iframe Runtime** | Add-on UI SDK | UI-only add-ons may not need document sandbox | -| Create/modify document content | **Document Sandbox** | Add-on UI SDK + Document APIs | UI SDK needed to trigger sandbox operations | -| Communicate between UI and document | **Both Environments** | Add-on UI SDK + Document Sandbox SDK | Communication APIs available in both | -| Import/export documents | **Iframe Runtime** | Add-on UI SDK | Document operations happen via UI SDK | -| Access browser features (fetch, OAuth) | **Iframe Runtime** | Add-on UI SDK | Limited browser APIs available in sandbox | - -### Typical Architecture Patterns - -**UI-Only Add-on (no document manipulation):** - -- Import: Add-on UI SDK only -- Use cases: Settings panels, external integrations, file uploads - -**Document-Focused Add-on (content creation/editing):** - -- Import: Add-on UI SDK + Document APIs + Document Sandbox SDK -- UI triggers operations → Communication APIs → Document manipulation in sandbox - -**Hybrid Add-on (UI + document + external services):** - -- Import: All SDKs -- Complex workflows involving UI, document operations, and external APIs - -## Quick Reference by Use Case - -**Building a UI Panel?** → Add-on UI SDK -**Creating new content?** → Document APIs (in Document Sandbox) -**Modifying existing content?** → Document APIs (in Document Sandbox) -**Connecting UI to Document?** → Communication APIs -**Need browser features in sandbox?** → Web APIs or proxy from iframe - -## Common Confusion Points - -### "SDK" vs "API" vs "Runtime" - -- **SDK (Software Development Kit)**: A collection of tools, libraries, and documentation (e.g., Add-on UI SDK) -- **API (Application Programming Interface)**: Specific methods and interfaces you can call (e.g., Document APIs) -- **Runtime**: The execution environment where code runs (e.g., Iframe Runtime, Document Sandbox Runtime) - -### Import Statement Patterns - -```javascript -// ✅ Correct patterns -import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; -import addOnSandboxSdk from "add-on-sdk-document-sandbox"; - -// ❌ Common mistakes -import { addOnUISdk } from "..."; // Wrong: should be default import -import addOnSandboxSdk from "add-on-ui-sdk"; // Wrong: mixed up the SDKs +**document sandbox → iframe runtime**: +```js +// document sandbox (code.js) +const panelProxy = await runtime.apiProxy("panel"); +await panelProxy.updateUI("Rectangle created"); + +// iframe runtime (index.js) +runtime.exposeApi({ + updateUI(message) { + document.getElementById('status').textContent = message; + } +}); ``` -### Context Switching - -| When you're in... | You have access to... | To communicate with the other side... | -|-------------------|----------------------|--------------------------------------| -| **Iframe Runtime** | Add-on UI SDK, DOM, browser APIs | Use `runtime.exposeApi()` or `runtime.apiProxy()` | -| **Document Sandbox** | Document APIs, limited Web APIs | Use `runtime.exposeApi()` or `runtime.apiProxy()` | - -## File Structure & Bundle Terminology - -### Add-on Bundle Structure +### Runtime Types +- **`panel`**: The main iframe runtime for your add-on UI +- **`documentSandbox`**: The document manipulation runtime +- **`dialog`**: Runtime context when code is running within a modal dialog -**Add-on Bundle** -The complete packaged structure of your add-on, including all files and the manifest. +## Essential Development Objects -Based on the Adobe Express Add-on CLI templates: +### **Editor Object** +Primary interface for document manipulation in the document sandbox. -**Basic JavaScript Template (UI only, no document sandbox):** +```js +import { editor } from "express-document-sdk"; -```text -my-addon/ -└── src/ - ├── index.html # Main UI entry point - ├── index.js # UI logic - ├── manifest.json # Configuration - └── README.md # Documentation +const rectangle = editor.createRectangle(); +const textNode = editor.createText("Hello World"); +const insertionParent = editor.context.insertionParent; ``` -**JavaScript Template with Document Sandbox:** - -```text -my-addon/ -└── src/ - ├── sandbox/ - │ ├── code.js # Document sandbox code - │ └── tsconfig.json # TypeScript config for sandbox - ├── ui/ - │ ├── index.html # Main UI entry point - │ ├── index.js # UI logic - │ └── tsconfig.json # TypeScript config for UI - ├── index.html # Root HTML file - ├── manifest.json # Configuration - └── README.md # Documentation +### **Constants** +Type-safe values for SDK operations that prevent string literal errors. + +```js +// UI SDK Constants +await addOnUISdk.app.document.createRenditions({ + range: Range.currentPage, + format: RenditionFormat.png +}); + +// Document Sandbox Constants +rectangle.fill = { + type: constants.FillType.color, + color: { red: 1, green: 0, blue: 0, alpha: 1 } +}; ``` -### Entry Point Files - -**Main Entry File (`index.html`)** -The primary HTML file that loads when your add-on panel opens. Contains or references your UI code. - -**Document Sandbox Entry (`code.js`)** -The JavaScript file that runs in the document sandbox environment. Contains document manipulation logic. - -**Relative Path Resolution** -How files within your bundle reference each other using relative paths: - -```html - - +### **ColorUtils** +Utility functions for creating and converting colors in the document sandbox. - - -``` +```js +import { colorUtils } from "express-document-sdk"; -```javascript -// In sandbox/code.js - no imports needed for sandbox SDK -// addOnSandboxSdk is globally available +const redColor = colorUtils.fromRGB(1, 0, 0); // RGB values (0-1) +const blueColor = colorUtils.fromHex("#0066CC"); // Hex string +const hexString = colorUtils.toHex(redColor); // "#FF0000FF" ``` -### Static Assets Organization +## Document Context Disambiguation -**Static Assets** -Non-code resources like images, icons, fonts, and media files included in your bundle. +The term "document" has different meanings depending on context: -**Asset Referencing** -How to properly reference static assets from your code: +### **Browser Document** (DOM) +- **Access**: Via global `document` object (e.g., `document.getElementById()`) +- **Purpose**: Manipulating HTML elements, event handling, CSS styling +- **Scope**: Limited to your add-on's iframe HTML content -```html - -Logo -``` +### **UI SDK Document** +- **Access**: Via `addOnUISdk.app.document` +- **Purpose**: High-level operations like importing media, creating renditions, getting metadata +- **Scope**: Operations on the entire Adobe Express document -```javascript -// Dynamic asset loading -const iconUrl = new URL('./assets/icons/star.svg', import.meta.url); -``` +### **Document APIs** +- **Access**: Via `editor.documentRoot` and `editor.context` +- **Purpose**: Fine-grained manipulation of document nodes, pages, artboards, and content +- **Scope**: Direct manipulation of Adobe Express document elements -### Bundle Optimization + -**Bundle Size Considerations** -Keeping your add-on bundle small for faster loading: +**Rule of Thumb**: Browser `document` is for your add-on's HTML UI, UI SDK document is for importing/exporting content, and Document API operations are for creating and manipulating content within the Adobe Express document structure. -- Minimize large assets -- Use efficient image formats -- Remove unused dependencies -- Consider lazy loading for non-critical resources +## Node Hierarchy -**File Organization Best Practices** -Structuring your bundle for maintainability: +Adobe Express documents are structured as a **scenegraph** - a hierarchical tree of nodes representing visual elements. -- Separate concerns (UI, logic, styling) -- Group related assets in folders -- Use consistent naming conventions -- Keep manifest.json at root level +**BaseNode**: The minimal base class for all document elements with basic properties like `id`, `type`, `parent`, `allChildren`. -### External Dependencies +**Node**: Full-featured visual content that extends `BaseNode` with visual properties and transformations. -**Library Integration** -How to include external JavaScript libraries in your bundle: +**Common Node Types**: +- **Container Nodes**: `ArtboardNode`, `GroupNode`, `PageNode` (hold other elements) +- **Content Nodes**: `RectangleNode`, `EllipseNode`, `TextNode`, `LineNode`, `PathNode` (visual elements) +- **Media Nodes**: `MediaContainerNode`, `ImageRectangleNode` (images and media) -```html - - +```js +// Navigate the document hierarchy +const root = editor.documentRoot; // ExpressRootNode +const currentPage = root.pages.first; // PageNode +const artboard = currentPage.artboards.first; // ArtboardNode - - +// Create and add content +const rectangle = editor.createRectangle(); // RectangleNode +artboard.children.append(rectangle); ``` -**Dependency Management** -Strategies for managing external dependencies: - -- **Bundle locally** - Include in your add-on bundle (recommended for reliability) -- **CDN loading** - Load from external CDN (requires internet connection) -- **Hybrid approach** - Local fallback with CDN primary - -## Manifest & Configuration Terminology +## Development Environment & Tools -### Core Manifest Concepts +### **Add-on Marketplace** +Distribution platform where users discover and install add-ons within Adobe Express via the "Add-ons" button in the left sidebar. -**Manifest File (`manifest.json`)** -The configuration file at the root of your add-on bundle that defines metadata, entry points, and permissions. +### **Code Playground** +Interactive browser-based development environment for experimenting with add-on APIs without local setup. -**Manifest Version** -The schema version of the manifest format. Currently version 2 is the latest standard. +### **Adobe Express Add-on CLI** +Command Line Interface tool for creating, building, and packaging add-ons for local development. +- **Installation**: `npm install -g @adobe/ccweb-add-on-cli` +- **Key Commands**: `create`, `start`, `build`, `package` -```json -{ - "manifestVersion": 2, - "version": "1.0.0" -} -``` - -### Entry Points & Structure +### **MCP Server (Model Context Protocol)** +AI-assisted development tool that enhances LLM responses with Adobe Express add-on documentation and TypeScript definitions. +- **Purpose**: Provide semantic documentation search and accurate code suggestions through AI assistants +- **Requirements**: Node.js 18+ and MCP-compatible IDE (Cursor, VS Code, Claude Desktop) -**Entry Point** -A defined way for users to access your add-on functionality. Currently only `"panel"` type is supported. +### **Add-on Development Mode** +Special mode in Adobe Express (Settings > Add-on Development toggle) that allows loading and testing local add-ons during development. -**Panel Entry Point** -The main UI interface of your add-on that appears in the Adobe Express sidebar. +## Manifest Configuration ```json -// Basic template (UI only, no document sandbox) -"entryPoints": [{ - "type": "panel", - "id": "panel1", - "main": "index.html" -}] - -// With document sandbox (separate ui/ and sandbox/ folders) -"entryPoints": [{ - "type": "panel", - "id": "panel1", - "main": "ui/index.html", - "documentSandbox": "sandbox/code.js" -}] -``` - -**Main File** -The HTML file that serves as the entry point for your add-on's UI (typically `index.html`). - -**Document Sandbox File** -The JavaScript file containing code that runs in the document sandbox environment (typically `code.js`). - -### Development vs Production - -**Test ID** -A unique identifier used during development workflows only. Auto-generated by CLI and ignored in marketplace submissions. - -**Production Name** -The add-on name provided during marketplace submission, which overrides the development `name` field. - -### Permissions & Security - -**Sandbox Permissions** -Security restrictions that control what browser features your add-on can access: - -- `allow-popups` - Enable popup windows -- `allow-downloads` - Enable file downloads -- `allow-presentation` - Enable presentation API -- `allow-popups-to-escape-sandbox` - Required for premium content flows - -**OAuth Permissions** -Domains allowed for OAuth authentication flows: - -```json -"permissions": { - "oauth": ["www.dropbox.com", "api.example.com"] -} -``` - -### Device & Platform Support - -**Device Class** -The form factor categories your add-on supports: - -- `desktop` - Browser on desktop/laptop (currently the only supported option) -- `mobile` - Browser on mobile devices (future support) -- `tablet` - Browser on tablet devices (future support) - -**Touch Support** -Boolean flag indicating whether your add-on works on touch-only devices: - -```json -"requirements": { - "supportsTouch": false +{ + "entryPoints": [ + { + "type": "panel", + "id": "panel1", + "main": "index.html", // iframe runtime entry + "documentSandbox": "code.js" // document sandbox entry (optional) + } + ], + "permissions": { + "sandbox": ["allow-popups", "allow-downloads"], + "oauth": ["www.dropbox.com", "api.example.com"] + } } ``` -## Development Workflow & Debugging Terminology - -### Development Environment - -**Add-on Development Panel** -The built-in debugging interface in Adobe Express that allows you to load, reload, and manage add-ons during development. - -**Hot Reload** -Automatic refresh of your add-on when file changes are detected during development. May occasionally fail and require manual reload. - -**Manual Reload** -Using the "Refresh" button in the Add-on Development Panel to force reload your add-on and pick up changes. - -### Debugging Context - -**Browser Developer Tools** -Standard browser debugging features accessible by right-clicking and selecting "Inspect Element": - -- **Console** - Log messages, errors, and execute JavaScript -- **Debugger** - Set breakpoints and step through code -- **Network Monitor** - Track network requests and responses -- **Profiler** - Analyze performance and identify bottlenecks - -**Console Context** -Understanding which runtime environment your console messages appear in: - -- **Iframe Console** - Messages from UI code (`index.html` and related scripts) -- **Document Sandbox Console** - Messages from document manipulation code (`code.js`) - -### Common Development Issues - -**Race Condition** -Timing issue where the communication bridge isn't ready when UI interactions occur. Clicking buttons may appear to do nothing. - -**Reentrancy Protection** -Preventing users from triggering multiple simultaneous operations that could corrupt the document or undo stack: - -```javascript -// Disable UI during async operations -button.disabled = true; -await performDocumentOperation(); -button.disabled = false; -``` - -**API Proxy Mismatch** -Common error where wrong proxy types are requested: - -```javascript -// ✅ Correct -// In iframe: runtime.apiProxy("script") -// In sandbox: runtime.apiProxy("panel") - -// ❌ Wrong - will fail silently -// In iframe: runtime.apiProxy("panel") -``` - -### Cross-Origin Isolation (COI) - -**Cross-Origin Isolation** -Security model that affects how your add-on can interact with external resources and APIs. May require specific headers or workarounds for certain integrations. - -**COI Handling** -Techniques for working within the cross-origin isolation constraints, such as using proxy endpoints or alternative authentication flows. - -### Performance Monitoring - -**Frame Duration Warnings** -Console messages about excessive frame duration (e.g., "Detected a possible stutter") that can generally be ignored during development. - -**Transaction Warnings** -Messages like "Empty transaction not added to pendingTransaction" that are informational and can be ignored. - -## Semantic Relationships +## Quick Decision Guide -### Hierarchical Structure - -```text -Adobe Express Add-on -├── Iframe Runtime Environment -│ ├── Add-on UI SDK -│ ├── User Interface Components -│ └── Import/Export Capabilities -└── Document Sandbox Runtime Environment - ├── Document APIs - ├── Content Authoring - └── Limited Web APIs -``` - -### Functional Relationships - -- **Add-on UI SDK** ↔ **Communication APIs** ↔ **Document APIs** -- **Iframe Runtime** ↔ **Document Sandbox Runtime** (via Communication APIs) -- **Document APIs** ⊂ **Document Sandbox** (APIs are available within the sandbox) +**Building a UI Panel?** → Add-on UI SDK +**Creating new content?** → Document APIs (in Document Sandbox) +**Modifying existing content?** → Document APIs (in Document Sandbox) +**Connecting UI to Document?** → Communication APIs +**Need browser features in sandbox?** → Web APIs or proxy from iframe ## Troubleshooting Common Issues -### "undefined" Errors - - - -**Problem**: `addOnUISdk.constants.SomeConstant` returns `undefined` - -**Solution**: Some constants require explicit imports. Check the [Add-on UI SDK Constants Guide](./ui-sdk-constants.md) or [Constants Reference](../../../references/addonsdk/addonsdk-constants.md) - ### Import Errors +```js +// ✅ Correct patterns +import addOnUISdk from "https://express.adobe.com/static/add-on-sdk/sdk.js"; +import addOnSandboxSdk from "add-on-sdk-document-sandbox"; +import { editor, colorUtils, constants } from "express-document-sdk"; - - -**Problem**: `Cannot resolve module 'add-on-sdk-document-sandbox'` - -**Solution**: This import only works in document sandbox context, not iframe context - -### Communication Errors - - - -**Problem**: Cannot call methods between iframe and document sandbox - -**Solution**: Ensure you're using `exposeApi()` in one environment and `apiProxy()` in the other - -## Frequently Asked Questions - -### General Terminology - -**Q: What's the difference between "Add-on UI SDK" and "Document APIs"?** -A: The **Add-on UI SDK** runs in the iframe and handles UI, user interactions, and import/export. **Document APIs** run in the document sandbox and handle content creation and document manipulation. Think of it as UI vs Content. - -**Q: Why are there two different runtime environments?** -A: Security and performance. The **iframe runtime** is sandboxed for security but has full browser capabilities. The **document sandbox runtime** has direct access to Adobe Express's document engine but limited browser APIs. - -**Q: What does "sandbox" mean in this context?** -A: A **sandbox** is an isolated execution environment. The **document sandbox** specifically refers to the secure JavaScript environment where Document APIs run, separate from the iframe where your UI runs. - -### Import and Usage - -**Q: Why do I get "undefined" when accessing `addOnUISdk.constants.SomeConstant`?** -A: Some constants require explicit imports and aren't available through the `constants` object. Check the [Constants Reference](../../../references/addonsdk/addonsdk-constants.md) to see which constants need to be imported directly. +// ❌ Common mistakes +import { addOnUISdk } from "..."; // Wrong: should be default import +import addOnSandboxSdk from "add-on-ui-sdk"; // Wrong: mixed up the SDKs +``` -**Q: When do I use `addOnUISdk` vs `addOnSandboxSdk`?** -A: Use `addOnUISdk` in your **iframe code** (usually `index.html` or `ui/` folder). Use `addOnSandboxSdk` in your **document sandbox code** (usually `code.js` or `sandbox/` folder). +### Runtime Context +| When you're in... | You have access to... | To communicate with the other side... | +|-------------------|----------------------|--------------------------------------| +| **iframe runtime** | Add-on UI SDK, DOM, Web APIs | Use `runtime.exposeApi()` or `runtime.apiProxy()` | +| **document sandbox** | Express Document SDK, limited Web APIs | Use `runtime.exposeApi()` or `runtime.apiProxy()` (from Document Sandbox SDK) | -**Q: Can I use Document APIs in my iframe code?** -A: No, Document APIs only work in the document sandbox. To use them from your iframe, you need to expose them via Communication APIs using `exposeApi()` and `apiProxy()`. +### "undefined" Errors +**Problem**: `addOnUISdk.constants.SomeConstant` returns `undefined` +**Solution**: Some constants require explicit imports. Check the [Constants Reference](../../../references/addonsdk/addonsdk-constants.md) -### Architecture and Communication +--- -**Q: How do I communicate between my UI and document sandbox?** -A: Use the **Communication APIs**: +## FAQs -- In one environment: `runtime.exposeApi(myObject)` -- In the other: `const proxy = await runtime.apiProxy("environmentName")` +#### Q: What's the difference between "Add-on UI SDK" and "Document APIs"? -**Q: What's the difference between "iframe runtime" and "UI runtime"?** -A: They're the same thing. **"Iframe runtime"** is the preferred term - it's the browser environment where your add-on's UI runs. +**A:** The **Add-on UI SDK** runs in the iframe runtime and handles UI, user interactions, and import/export. **Document APIs** (via Express Document SDK) run in the document sandbox and handle content creation and document manipulation. -**Q: Why can't I use `fetch()` in the document sandbox?** -A: The document sandbox has limited Web APIs for security. You can either use the limited APIs available or proxy `fetch()` from your iframe using Communication APIs. +#### Q: Why are there two different runtime environments? -### Choosing the Right SDK +**A:** Security and performance. The **iframe runtime** is sandboxed for security but has full browser capabilities. The **document sandbox** has direct access to Adobe Express's document engine but limited Web APIs. -**Q: I want to add a button that creates a rectangle. Which SDK do I use?** -A: Both! Use the **Add-on UI SDK** to create the button in your iframe, then use **Communication APIs** to call **Document APIs** in the document sandbox to create the rectangle. +#### Q: Can I use Document APIs directly from the iframe runtime? -**Q: I'm building a form to collect user input. Which environment should this be in?** -A: The **iframe runtime** using the **Add-on UI SDK**. Forms and user interactions belong in the iframe where you have full DOM access. +**A:** No, Document APIs (Express Document SDK) are only available in the document sandbox for security reasons. You must use the communication system (Document Sandbox SDK) to bridge between environments. -**Q: I want to change the color of selected elements. Where does this code go?** -A: In the **document sandbox** using **Document APIs**. Content manipulation always happens in the document sandbox. +#### Q: When do I use `addOnUISdk` vs `addOnSandboxSdk`? -### Legacy and Deprecated Terms +**A:** Use `addOnUISdk` (Add-on UI SDK) in your **iframe runtime code** (usually `index.html` or `ui/` folder). Use `addOnSandboxSdk` (Document Sandbox SDK) in your **document sandbox code** (usually `code.js` or `sandbox/` folder). -**Q: I see "Document SDK" in some older documentation. What should I use instead?** -A: Use **"Document APIs"** instead. "Document SDK" is deprecated terminology. +#### Q: I see references to "UI SDK" - is this different from "Add-on UI SDK"? -**Q: What's the difference between "Document Model Sandbox" and "Document Sandbox"?** -A: They're the same thing. **"Document Sandbox"** is the preferred, simplified term. +**A:** No, they're the same. **"Add-on UI SDK"** is the full, preferred term for clarity, but "UI SDK" is commonly used as shorthand throughout the documentation. -**Q: I see references to "UI SDK" - is this different from "Add-on UI SDK"?** -A: No, they're the same. **"Add-on UI SDK"** is the full, preferred term for clarity. +--- ## Related Documentation -- [Add-on Architecture Guide](../platform_concepts/runtime-architecture.md) - Comprehensive guide with visual diagrams +- [Adobe Express Add-ons Developer Guide](https://developer-stage.adobe.com/express/add-ons/docs/guides/) - Official documentation and getting started guide +- [Add-on Architecture Guide](../platform_concepts/architecture.md) - Comprehensive guide with visual diagrams - [Add-on UI SDK Reference](../../../references/addonsdk/index.md) - [Document Sandbox Overview](../../../references/document-sandbox/index.md) - [Communication APIs](../../../references/document-sandbox/communication/index.md) -- [Document API Concepts Guide](../platform_concepts/document-api.md) -- [Add-on Iframe Context](../platform_concepts/context.md) - [Add-on UI SDK Constants Usage Guide](./ui-sdk-constants.md) - [Document Sandbox Constants Usage Guide](./document-sandbox-constants.md) diff --git a/src/pages/guides/learn/how_to/tutorials/grids-addon.md b/src/pages/guides/learn/how_to/tutorials/grids-addon.md index 1adf4d457..ec424a5af 100644 --- a/src/pages/guides/learn/how_to/tutorials/grids-addon.md +++ b/src/pages/guides/learn/how_to/tutorials/grids-addon.md @@ -99,7 +99,7 @@ Your add-on will allow users to create a variable number of rows and columns, co As part of the [Document Model Sandbox](/references/document-sandbox/index.md), the Adobe Express Document API (from now on, Document API) is a powerful tool that extends the capabilities of Adobe Express add-ons, offering direct interaction with the open document. Let's take a moment to review the difference between the two core components of the architecture of an add-on. -- The **iframe** hosts the add-on User Interface and runs its internal logic. You can think about it as a web application operating in a sandboxed environment: it needs to be separate from the rest of the Adobe Express content for security reasons, which is precisely why the add-on is hosted within an `