Skip to content

Commit cc57fa3

Browse files
authored
feat(annotator): Add public query methods to BaseAnnotator (#736)
Add getActiveId, getAnnotationContainerEl, and isPopupOpen methods to support annotation escape key handling from Preview SDK.
1 parent b9fae1b commit cc57fa3

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/common/BaseAnnotator.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ export default class BaseAnnotator extends EventEmitter {
136136
this.removeListener(Event.VISIBLE_SET, this.handleSetVisible);
137137
}
138138

139+
public getActiveId(): string | null {
140+
return store.getActiveAnnotationId(this.store.getState());
141+
}
142+
143+
public getAnnotationContainerEl(): HTMLElement | null {
144+
return this.containerEl ?? null;
145+
}
146+
139147
public init(scale = 1, rotation = 0): void {
140148
this.containerEl = this.getElement(this.container);
141149
this.annotatedEl = this.getAnnotatedElement();
@@ -162,6 +170,10 @@ export default class BaseAnnotator extends EventEmitter {
162170
return getProp(this.features, feature, false);
163171
}
164172

173+
public isPopupOpen(): boolean {
174+
return !!this.containerEl?.querySelector('.ba-Popup');
175+
}
176+
165177
public removeAnnotation = (annotationId: string): void => {
166178
this.store.dispatch(store.removeAnnotationAction(annotationId));
167179
};

src/common/__tests__/BaseAnnotator-test.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,66 @@ describe('BaseAnnotator', () => {
304304
});
305305
});
306306

307+
describe('getActiveId()', () => {
308+
test('should return the active annotation id from the store', () => {
309+
(annotator.store.getState as jest.Mock).mockReturnValue({
310+
annotations: { activeId: 'abc123' },
311+
});
312+
313+
expect(annotator.getActiveId()).toBe('abc123');
314+
});
315+
316+
test('should return null if no active annotation', () => {
317+
(annotator.store.getState as jest.Mock).mockReturnValue({
318+
annotations: { activeId: null },
319+
});
320+
321+
expect(annotator.getActiveId()).toBeNull();
322+
});
323+
});
324+
325+
describe('getAnnotationContainerEl()', () => {
326+
test('should return the container element when initialized', () => {
327+
annotator.init(1);
328+
329+
expect(annotator.getAnnotationContainerEl()).toBe(annotator.containerEl);
330+
});
331+
332+
test('should return null when containerEl is undefined', () => {
333+
annotator.containerEl = undefined;
334+
335+
expect(annotator.getAnnotationContainerEl()).toBeNull();
336+
});
337+
});
338+
307339
describe('isFeatureEnabled()', () => {
308340
test('should return whether feature is enabled or not', () => {
309341
expect(annotator.isFeatureEnabled('enabledFeature')).toBe(true);
310342
expect(annotator.isFeatureEnabled('notEnabledFeature')).toBe(false);
311343
});
312344
});
345+
346+
describe('isPopupOpen()', () => {
347+
test('should return true when a popup element exists', () => {
348+
annotator.init(1);
349+
const popup = document.createElement('div');
350+
popup.classList.add('ba-Popup');
351+
annotator.containerEl?.appendChild(popup);
352+
353+
expect(annotator.isPopupOpen()).toBe(true);
354+
});
355+
356+
test('should return false when no popup element exists', () => {
357+
annotator.init(1);
358+
annotator.containerEl?.querySelectorAll('.ba-Popup').forEach(el => el.remove());
359+
360+
expect(annotator.isPopupOpen()).toBe(false);
361+
});
362+
363+
test('should return false when containerEl is undefined', () => {
364+
annotator.containerEl = undefined;
365+
366+
expect(annotator.isPopupOpen()).toBe(false);
367+
});
368+
});
313369
});

0 commit comments

Comments
 (0)