stimulus-pdf-viewer-rails 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2b8580f37e1f69672150d18e71bda47daff6b3eb2b082becc5f0090bea57d43
4
- data.tar.gz: 6f3ecaf5db5c8248a6037c0f416149df1af21980e83236a9ffe9a9d395aa5e99
3
+ metadata.gz: 43f0f370e8cb71ab25bae045345269c4567e3afaecb6a15f43dfe8dd26b4766c
4
+ data.tar.gz: ce65b690119f2d649ef611f227e4da9bfddf4f27da9273221a9653211eb84445
5
5
  SHA512:
6
- metadata.gz: 27b13a4566eefe38263b236ba1fd96a0bec05651a27f5e333147b2f6635e9dac5e100b58ff4a67db6f36360895fc1b2ca8facdd58e091aa8b1c2053accf76f28
7
- data.tar.gz: 65a0c1284f86ffc83680d9ac95c6e20f64cec6dad84f3f5edb9ea6ec6e4cd1f6003f865d4d959400e05eab4f8e56b2db39494b2cec520506c1a8078770d3d605
6
+ metadata.gz: cd3c15bcfccb692d88527594f57cbcbe280b7c0ec79b84f15a8c36016e907b29431554098602042c51ed80a2cdd1601ced8782cf33ae9fd4fba216c29a764ffa
7
+ data.tar.gz: c275cb1442a607111a11564d1ecf5326c69be6653ef497c49c45f602c0d4f44e38373b9d6d5308cc821ba92c1933bdc4f929185de0f524533a60b84d52bb7d6f
data/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.3.0] - 2026-04-01
6
+
7
+ ### Added
8
+ - Updated stimulus-pdf-viewer to 0.3.0
9
+
5
10
  ## [0.2.0] - 2026-01-11
6
11
 
7
12
  ### Added
@@ -3665,6 +3665,17 @@ class AnnotationSidebar {
3665
3665
  this.listContainer.appendChild(item);
3666
3666
  }
3667
3667
  }
3668
+
3669
+ // Re-fire selected event after rebuild so consumers can re-attach detail panels
3670
+ if (this.selectedAnnotationId) {
3671
+ const annotation = this.annotationManager.getAnnotation(this.selectedAnnotationId);
3672
+ if (annotation) {
3673
+ this.element.dispatchEvent(new CustomEvent("pdf-sidebar:annotation-selected", {
3674
+ bubbles: true,
3675
+ detail: { annotationId: this.selectedAnnotationId, annotation }
3676
+ }));
3677
+ }
3678
+ }
3668
3679
  }
3669
3680
 
3670
3681
  _matchesFilter(annotation) {
@@ -3887,18 +3898,36 @@ class AnnotationSidebar {
3887
3898
  }
3888
3899
 
3889
3900
  _selectItem(annotationId) {
3901
+ const previousId = this.selectedAnnotationId;
3902
+
3903
+ // Skip if already selected
3904
+ if (previousId === annotationId) return
3905
+
3890
3906
  // Deselect previous
3891
3907
  const prev = this.listContainer.querySelector(".annotation-list-item.selected");
3892
3908
  if (prev) {
3893
3909
  prev.classList.remove("selected");
3894
3910
  }
3895
3911
 
3912
+ if (previousId) {
3913
+ this.element.dispatchEvent(new CustomEvent("pdf-sidebar:annotation-deselected", {
3914
+ bubbles: true,
3915
+ detail: { annotationId: previousId }
3916
+ }));
3917
+ }
3918
+
3896
3919
  // Select new
3897
3920
  this.selectedAnnotationId = annotationId;
3898
3921
  const item = this.listContainer.querySelector(`[data-annotation-id="${annotationId}"]`);
3899
3922
  if (item) {
3900
3923
  item.classList.add("selected");
3901
3924
  }
3925
+
3926
+ const annotation = this.annotationManager.getAnnotation(annotationId);
3927
+ this.element.dispatchEvent(new CustomEvent("pdf-sidebar:annotation-selected", {
3928
+ bubbles: true,
3929
+ detail: { annotationId, annotation }
3930
+ }));
3902
3931
  }
3903
3932
 
3904
3933
  /**
@@ -3926,7 +3955,12 @@ class AnnotationSidebar {
3926
3955
  if (this.isOpen) {
3927
3956
  // Clear selection if deleted annotation was selected
3928
3957
  if (this.selectedAnnotationId === annotation.id) {
3958
+ const previousId = this.selectedAnnotationId;
3929
3959
  this.selectedAnnotationId = null;
3960
+ this.element.dispatchEvent(new CustomEvent("pdf-sidebar:annotation-deselected", {
3961
+ bubbles: true,
3962
+ detail: { annotationId: previousId }
3963
+ }));
3930
3964
  }
3931
3965
  this._refreshList();
3932
3966
  }
@@ -3954,6 +3988,10 @@ class AnnotationSidebar {
3954
3988
  this.element.classList.add("open");
3955
3989
  this.container.classList.add("annotation-sidebar-open");
3956
3990
  this._refreshList();
3991
+
3992
+ this.element.dispatchEvent(new CustomEvent("pdf-sidebar:annotation-sidebar-opened", {
3993
+ bubbles: true
3994
+ }));
3957
3995
  }
3958
3996
 
3959
3997
  /**
@@ -3963,6 +4001,10 @@ class AnnotationSidebar {
3963
4001
  this.isOpen = false;
3964
4002
  this.element.classList.remove("open");
3965
4003
  this.container.classList.remove("annotation-sidebar-open");
4004
+
4005
+ this.element.dispatchEvent(new CustomEvent("pdf-sidebar:annotation-sidebar-closed", {
4006
+ bubbles: true
4007
+ }));
3966
4008
  }
3967
4009
 
3968
4010
  /**
@@ -6873,6 +6915,10 @@ class PdfViewer {
6873
6915
  if (e.target.closest(".annotation") || e.target.closest(".annotation-edit-toolbar")) {
6874
6916
  return
6875
6917
  }
6918
+ // Skip if an annotation was just created (click follows pointerup from text selection)
6919
+ if (this._suppressClickDeselect) {
6920
+ return
6921
+ }
6876
6922
  this._deselectAnnotation();
6877
6923
  });
6878
6924
 
@@ -6922,6 +6968,12 @@ class PdfViewer {
6922
6968
  // Render annotations on all rendered pages
6923
6969
  this._renderAnnotations();
6924
6970
 
6971
+ const annotations = this.annotationManager.getAllAnnotations();
6972
+ this.container.dispatchEvent(new CustomEvent("pdf-viewer:annotations-loaded", {
6973
+ bubbles: true,
6974
+ detail: { annotations, count: annotations.length }
6975
+ }));
6976
+
6925
6977
  // Navigate to initial page if specified
6926
6978
  if (this.initialPage > 1) {
6927
6979
  this.viewer.goToPage(this.initialPage);
@@ -7049,11 +7101,15 @@ class PdfViewer {
7049
7101
 
7050
7102
  // Auto-select the newly created annotation
7051
7103
  const pageContainer = this.viewer.getPageContainer(annotation.page);
7052
- const element = pageContainer?.querySelector(`[data-annotation-id="${annotation.id}"]`);
7104
+ const element = pageContainer?.querySelector(`.annotation[data-annotation-id="${annotation.id}"]`);
7053
7105
  if (element) {
7054
7106
  this._selectAnnotation(annotation, element);
7055
7107
  }
7056
7108
 
7109
+ // Suppress the click-to-deselect that follows pointerup after text selection
7110
+ this._suppressClickDeselect = true;
7111
+ setTimeout(() => { this._suppressClickDeselect = false; }, 100);
7112
+
7057
7113
  // Notify annotation sidebar
7058
7114
  this.annotationSidebar?.onAnnotationCreated(annotation);
7059
7115
 
@@ -7081,7 +7137,7 @@ class PdfViewer {
7081
7137
  // Re-select the annotation after re-render
7082
7138
  if (wasSelected) {
7083
7139
  const pageContainer = this.viewer.getPageContainer(annotation.page);
7084
- const element = pageContainer?.querySelector(`[data-annotation-id="${annotation.id}"]`);
7140
+ const element = pageContainer?.querySelector(`.annotation[data-annotation-id="${annotation.id}"]`);
7085
7141
  if (element) {
7086
7142
  // Get the fresh annotation data from the manager
7087
7143
  const updatedAnnotation = this.annotationManager.getAnnotation(annotation.id);
@@ -7102,6 +7158,11 @@ class PdfViewer {
7102
7158
  // Announce to screen readers
7103
7159
  const typeLabel = this._getAnnotationTypeLabel(annotation.annotation_type);
7104
7160
  getAnnouncer().announce(`${typeLabel} updated`);
7161
+
7162
+ this.container.dispatchEvent(new CustomEvent("pdf-viewer:annotation-updated", {
7163
+ bubbles: true,
7164
+ detail: { annotation }
7165
+ }));
7105
7166
  }
7106
7167
 
7107
7168
  _onAnnotationDeleted(annotation) {
@@ -7756,6 +7817,8 @@ class PdfViewer {
7756
7817
  }
7757
7818
 
7758
7819
  _deselectAnnotation() {
7820
+ const previousAnnotation = this.selectedAnnotation;
7821
+
7759
7822
  if (this.selectedAnnotationElement) {
7760
7823
  this.selectedAnnotationElement.classList.remove("selected");
7761
7824
  }
@@ -7764,6 +7827,13 @@ class PdfViewer {
7764
7827
 
7765
7828
  // Hide the edit toolbar
7766
7829
  this.annotationEditToolbar.hide();
7830
+
7831
+ if (previousAnnotation) {
7832
+ this.container.dispatchEvent(new CustomEvent("pdf-viewer:annotation-deselected", {
7833
+ bubbles: true,
7834
+ detail: { annotationId: previousAnnotation.id }
7835
+ }));
7836
+ }
7767
7837
  }
7768
7838
 
7769
7839
  async _onAnnotationColorChange(annotation, color) {
@@ -3685,6 +3685,17 @@
3685
3685
  this.listContainer.appendChild(item);
3686
3686
  }
3687
3687
  }
3688
+
3689
+ // Re-fire selected event after rebuild so consumers can re-attach detail panels
3690
+ if (this.selectedAnnotationId) {
3691
+ const annotation = this.annotationManager.getAnnotation(this.selectedAnnotationId);
3692
+ if (annotation) {
3693
+ this.element.dispatchEvent(new CustomEvent("pdf-sidebar:annotation-selected", {
3694
+ bubbles: true,
3695
+ detail: { annotationId: this.selectedAnnotationId, annotation }
3696
+ }));
3697
+ }
3698
+ }
3688
3699
  }
3689
3700
 
3690
3701
  _matchesFilter(annotation) {
@@ -3907,18 +3918,36 @@
3907
3918
  }
3908
3919
 
3909
3920
  _selectItem(annotationId) {
3921
+ const previousId = this.selectedAnnotationId;
3922
+
3923
+ // Skip if already selected
3924
+ if (previousId === annotationId) return
3925
+
3910
3926
  // Deselect previous
3911
3927
  const prev = this.listContainer.querySelector(".annotation-list-item.selected");
3912
3928
  if (prev) {
3913
3929
  prev.classList.remove("selected");
3914
3930
  }
3915
3931
 
3932
+ if (previousId) {
3933
+ this.element.dispatchEvent(new CustomEvent("pdf-sidebar:annotation-deselected", {
3934
+ bubbles: true,
3935
+ detail: { annotationId: previousId }
3936
+ }));
3937
+ }
3938
+
3916
3939
  // Select new
3917
3940
  this.selectedAnnotationId = annotationId;
3918
3941
  const item = this.listContainer.querySelector(`[data-annotation-id="${annotationId}"]`);
3919
3942
  if (item) {
3920
3943
  item.classList.add("selected");
3921
3944
  }
3945
+
3946
+ const annotation = this.annotationManager.getAnnotation(annotationId);
3947
+ this.element.dispatchEvent(new CustomEvent("pdf-sidebar:annotation-selected", {
3948
+ bubbles: true,
3949
+ detail: { annotationId, annotation }
3950
+ }));
3922
3951
  }
3923
3952
 
3924
3953
  /**
@@ -3946,7 +3975,12 @@
3946
3975
  if (this.isOpen) {
3947
3976
  // Clear selection if deleted annotation was selected
3948
3977
  if (this.selectedAnnotationId === annotation.id) {
3978
+ const previousId = this.selectedAnnotationId;
3949
3979
  this.selectedAnnotationId = null;
3980
+ this.element.dispatchEvent(new CustomEvent("pdf-sidebar:annotation-deselected", {
3981
+ bubbles: true,
3982
+ detail: { annotationId: previousId }
3983
+ }));
3950
3984
  }
3951
3985
  this._refreshList();
3952
3986
  }
@@ -3974,6 +4008,10 @@
3974
4008
  this.element.classList.add("open");
3975
4009
  this.container.classList.add("annotation-sidebar-open");
3976
4010
  this._refreshList();
4011
+
4012
+ this.element.dispatchEvent(new CustomEvent("pdf-sidebar:annotation-sidebar-opened", {
4013
+ bubbles: true
4014
+ }));
3977
4015
  }
3978
4016
 
3979
4017
  /**
@@ -3983,6 +4021,10 @@
3983
4021
  this.isOpen = false;
3984
4022
  this.element.classList.remove("open");
3985
4023
  this.container.classList.remove("annotation-sidebar-open");
4024
+
4025
+ this.element.dispatchEvent(new CustomEvent("pdf-sidebar:annotation-sidebar-closed", {
4026
+ bubbles: true
4027
+ }));
3986
4028
  }
3987
4029
 
3988
4030
  /**
@@ -6893,6 +6935,10 @@
6893
6935
  if (e.target.closest(".annotation") || e.target.closest(".annotation-edit-toolbar")) {
6894
6936
  return
6895
6937
  }
6938
+ // Skip if an annotation was just created (click follows pointerup from text selection)
6939
+ if (this._suppressClickDeselect) {
6940
+ return
6941
+ }
6896
6942
  this._deselectAnnotation();
6897
6943
  });
6898
6944
 
@@ -6942,6 +6988,12 @@
6942
6988
  // Render annotations on all rendered pages
6943
6989
  this._renderAnnotations();
6944
6990
 
6991
+ const annotations = this.annotationManager.getAllAnnotations();
6992
+ this.container.dispatchEvent(new CustomEvent("pdf-viewer:annotations-loaded", {
6993
+ bubbles: true,
6994
+ detail: { annotations, count: annotations.length }
6995
+ }));
6996
+
6945
6997
  // Navigate to initial page if specified
6946
6998
  if (this.initialPage > 1) {
6947
6999
  this.viewer.goToPage(this.initialPage);
@@ -7069,11 +7121,15 @@
7069
7121
 
7070
7122
  // Auto-select the newly created annotation
7071
7123
  const pageContainer = this.viewer.getPageContainer(annotation.page);
7072
- const element = pageContainer?.querySelector(`[data-annotation-id="${annotation.id}"]`);
7124
+ const element = pageContainer?.querySelector(`.annotation[data-annotation-id="${annotation.id}"]`);
7073
7125
  if (element) {
7074
7126
  this._selectAnnotation(annotation, element);
7075
7127
  }
7076
7128
 
7129
+ // Suppress the click-to-deselect that follows pointerup after text selection
7130
+ this._suppressClickDeselect = true;
7131
+ setTimeout(() => { this._suppressClickDeselect = false; }, 100);
7132
+
7077
7133
  // Notify annotation sidebar
7078
7134
  this.annotationSidebar?.onAnnotationCreated(annotation);
7079
7135
 
@@ -7101,7 +7157,7 @@
7101
7157
  // Re-select the annotation after re-render
7102
7158
  if (wasSelected) {
7103
7159
  const pageContainer = this.viewer.getPageContainer(annotation.page);
7104
- const element = pageContainer?.querySelector(`[data-annotation-id="${annotation.id}"]`);
7160
+ const element = pageContainer?.querySelector(`.annotation[data-annotation-id="${annotation.id}"]`);
7105
7161
  if (element) {
7106
7162
  // Get the fresh annotation data from the manager
7107
7163
  const updatedAnnotation = this.annotationManager.getAnnotation(annotation.id);
@@ -7122,6 +7178,11 @@
7122
7178
  // Announce to screen readers
7123
7179
  const typeLabel = this._getAnnotationTypeLabel(annotation.annotation_type);
7124
7180
  getAnnouncer().announce(`${typeLabel} updated`);
7181
+
7182
+ this.container.dispatchEvent(new CustomEvent("pdf-viewer:annotation-updated", {
7183
+ bubbles: true,
7184
+ detail: { annotation }
7185
+ }));
7125
7186
  }
7126
7187
 
7127
7188
  _onAnnotationDeleted(annotation) {
@@ -7776,6 +7837,8 @@
7776
7837
  }
7777
7838
 
7778
7839
  _deselectAnnotation() {
7840
+ const previousAnnotation = this.selectedAnnotation;
7841
+
7779
7842
  if (this.selectedAnnotationElement) {
7780
7843
  this.selectedAnnotationElement.classList.remove("selected");
7781
7844
  }
@@ -7784,6 +7847,13 @@
7784
7847
 
7785
7848
  // Hide the edit toolbar
7786
7849
  this.annotationEditToolbar.hide();
7850
+
7851
+ if (previousAnnotation) {
7852
+ this.container.dispatchEvent(new CustomEvent("pdf-viewer:annotation-deselected", {
7853
+ bubbles: true,
7854
+ detail: { annotationId: previousAnnotation.id }
7855
+ }));
7856
+ }
7787
7857
  }
7788
7858
 
7789
7859
  async _onAnnotationColorChange(annotation, color) {
@@ -1,7 +1,7 @@
1
1
  module StimulusPdfViewer
2
2
  module Rails
3
- VERSION = "0.2.1"
3
+ VERSION = "0.3.0"
4
4
  # This should match the npm package version
5
- STIMULUS_PDF_VIEWER_VERSION = "0.2.1"
5
+ STIMULUS_PDF_VIEWER_VERSION = "0.3.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stimulus-pdf-viewer-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Baker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-01-12 00:00:00.000000000 Z
11
+ date: 2026-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties