bard-attachment_field 0.3.1 → 0.4.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: 3b550a7ccc4937f60e42b9a19129cae22ba0e357705e9c239d4962abbb6dc005
4
- data.tar.gz: 2d471d6085ac11fd2013006ae3397efc163c6ca0d91ca996d23697ce231eb50b
3
+ metadata.gz: 2e6782336d0ead03e5a80c840f02b3427a0e4a9397c192e424057305b6ec8110
4
+ data.tar.gz: eac00b7e082a15f20f0ec8bc4d858da978a19ba6d5b701bfec1f96c1a5964c7a
5
5
  SHA512:
6
- metadata.gz: 7aba1939902c829690034fc9f2db0f0b6068fca76f297c54baaba98f6f227c35e4f27b397eaeefd13175d52af565c924d2ee3b7e8d27ea0f30d8126a524c47be
7
- data.tar.gz: d51ffb195e0637448f30100051d5cc0e6a99073d7bc1e9858c5edb18a04b88b26e2b52ed3b462580024a352a2f6ec8a101ca2a6096f828dd236dcc1359509668
6
+ metadata.gz: d60984b410b8fd23682468b45d58244c867c57e567accabd8f02f22f73170b50abb15f37324b367dfeb1c7809e28edfb5885948e92fdba16209a4c6bb958536e
7
+ data.tar.gz: 77fbabc4df6df530b394883c4481488ee2c0ea1ffc5ce1da5a18797d4d499057e536e033d391980c53201cc96b4dbc8c383a4104721f9deb6c7bf5935a90bbfb
@@ -5788,54 +5788,12 @@ var InputAttachment$1 = /* @__PURE__ */ proxyCustomElement(class InputAttachment
5788
5788
  const existingFiles = Array.from(this.el.children).filter((e) => e.tagName == "ATTACHMENT-FILE");
5789
5789
  if (existingFiles.length > 0)
5790
5790
  this.files = existingFiles;
5791
- this.restoreFromLocalStorage();
5792
5791
  if (this.files.length > 0)
5793
5792
  this.updateFormValue();
5794
5793
  }
5795
5794
  componentDidLoad() {
5796
- if (this.form) {
5797
- this.form.addEventListener("submit", () => this.clearLocalStorage());
5798
- }
5799
5795
  this.fileInput?.addEventListener("change", this.handleFileInputChange);
5800
5796
  }
5801
- get localStorageKey() {
5802
- if (!this.form || !this.name)
5803
- return null;
5804
- const formId = this.form.id || this.form.action || "form";
5805
- return `input-attachment:${formId}:${this.name}`;
5806
- }
5807
- saveToLocalStorage() {
5808
- const key = this.localStorageKey;
5809
- if (!key)
5810
- return;
5811
- const data = this.persistenceData;
5812
- if (data.length > 0) {
5813
- localStorage.setItem(key, JSON.stringify(data));
5814
- } else {
5815
- localStorage.removeItem(key);
5816
- }
5817
- }
5818
- restoreFromLocalStorage() {
5819
- const key = this.localStorageKey;
5820
- if (!key || this.files.length > 0)
5821
- return;
5822
- try {
5823
- const stored = localStorage.getItem(key);
5824
- if (stored) {
5825
- const data = JSON.parse(stored);
5826
- if (Array.isArray(data) && data.length > 0) {
5827
- this.restoreFromPersistence(data);
5828
- }
5829
- }
5830
- } catch (e) {
5831
- }
5832
- }
5833
- clearLocalStorage() {
5834
- const key = this.localStorageKey;
5835
- if (key) {
5836
- localStorage.removeItem(key);
5837
- }
5838
- }
5839
5797
  // Methods
5840
5798
  get files() {
5841
5799
  return this._files;
@@ -5848,23 +5806,7 @@ var InputAttachment$1 = /* @__PURE__ */ proxyCustomElement(class InputAttachment
5848
5806
  this.fireChangeEvent();
5849
5807
  }
5850
5808
  get value() {
5851
- return this.files.map((e) => e.value);
5852
- }
5853
- set value(val) {
5854
- const newValue = val || [];
5855
- if (JSON.stringify(this.value) !== JSON.stringify(newValue)) {
5856
- this.files = newValue.map((signedId) => {
5857
- const attachmentFile = document.createElement("attachment-file");
5858
- attachmentFile.name = this.name;
5859
- attachmentFile.preview = this.preview;
5860
- attachmentFile.signedId = signedId;
5861
- return attachmentFile;
5862
- });
5863
- }
5864
- }
5865
- // For form-persistence: store complete attachment data (not just signed_ids)
5866
- get persistenceData() {
5867
- return this.files.map((f) => ({
5809
+ return JSON.stringify(this.files.map((f) => ({
5868
5810
  value: f.value,
5869
5811
  filename: f.filename,
5870
5812
  src: f.src,
@@ -5872,11 +5814,14 @@ var InputAttachment$1 = /* @__PURE__ */ proxyCustomElement(class InputAttachment
5872
5814
  percent: f.percent,
5873
5815
  size: f.size,
5874
5816
  filetype: f.filetype
5875
- }));
5817
+ })));
5876
5818
  }
5877
- restoreFromPersistence(data) {
5878
- if (!Array.isArray(data) || data.length === 0)
5819
+ set value(val) {
5820
+ const data = JSON.parse(val || "[]");
5821
+ if (data.length === 0) {
5822
+ this.files = [];
5879
5823
  return;
5824
+ }
5880
5825
  this.files = data.map((item) => {
5881
5826
  const attachmentFile = document.createElement("attachment-file");
5882
5827
  attachmentFile.name = this.name;
@@ -5896,7 +5841,7 @@ var InputAttachment$1 = /* @__PURE__ */ proxyCustomElement(class InputAttachment
5896
5841
  if (!this.name || !this.internals?.setFormValue)
5897
5842
  return;
5898
5843
  const formData = new FormData();
5899
- const values = this.value.filter((v) => v);
5844
+ const values = this.files.map((f) => f.value).filter((v) => v);
5900
5845
  if (this.multiple) {
5901
5846
  values.forEach((signedId) => formData.append(this.name, signedId));
5902
5847
  if (values.length === 0)
@@ -5905,7 +5850,6 @@ var InputAttachment$1 = /* @__PURE__ */ proxyCustomElement(class InputAttachment
5905
5850
  formData.set(this.name, values[0] || "");
5906
5851
  }
5907
5852
  this.internals.setFormValue(formData);
5908
- this.saveToLocalStorage();
5909
5853
  if (this.required && this.files.length === 0) {
5910
5854
  this.internals.setValidity({ valueMissing: true }, "Please select a file.", this.fileInput);
5911
5855
  } else {
@@ -5918,8 +5862,7 @@ var InputAttachment$1 = /* @__PURE__ */ proxyCustomElement(class InputAttachment
5918
5862
  }
5919
5863
  }
5920
5864
  reset() {
5921
- this.value = [];
5922
- this.clearLocalStorage();
5865
+ this.files = [];
5923
5866
  }
5924
5867
  handleFileInputChange = () => {
5925
5868
  if (!this.fileInput?.files?.length)
@@ -5956,12 +5899,12 @@ var InputAttachment$1 = /* @__PURE__ */ proxyCustomElement(class InputAttachment
5956
5899
  return this.disabled || !!this.el.closest("fieldset[disabled]");
5957
5900
  }
5958
5901
  render() {
5959
- return h(Host, { key: "e63c2624a4d88232adacc7d1610983fac89eb9db" }, h("input", { key: "baea544d4d62e31e1228d92ba8b0356d40e75ce5", ref: (el) => this.fileInput = el, type: "file", multiple: this.multiple, accept: this.accepts, required: this.required && this.files.length === 0, disabled: this.isDisabled, onChange: () => this.handleFileInputChange(), style: {
5902
+ return h(Host, { key: "d6cdfb923931f8232c1a6118dcb38889266cc5d0" }, h("input", { key: "e77f98d380aa090cabc70f712fd0787c0cf1373b", ref: (el) => this.fileInput = el, type: "file", multiple: this.multiple, accept: this.accepts, required: this.required && this.files.length === 0, disabled: this.isDisabled, onChange: () => this.handleFileInputChange(), style: {
5960
5903
  opacity: "0.01",
5961
5904
  width: "1px",
5962
5905
  height: "1px",
5963
5906
  zIndex: "-999"
5964
- } }), h("file-drop", { key: "0b5621010445988462b8056cb360bf18ac6b0b59", onClick: () => this.fileInput?.click(), onDrop: this.handleDrop }, h("p", { key: "718fe6b91ed9cdc5c5a2b54317fad8f1f25b3cd4", part: "title" }, h("strong", { key: "f28b9ffc58bb086bb1941ee01e943fe5068482a4" }, "Choose ", this.multiple ? "files" : "file", " "), h("span", { key: "eeca7b2f619a7a4d7863f98ba37218d6a66fdcfd" }, "or drag ", this.multiple ? "them" : "it", " here.")), h("div", { key: "2a1d0a824139f5c26833611a5523354965be0d9d", class: `media-preview ${this.multiple ? "-stacked" : ""}` }, h("slot", { key: "59455a857d01dfabd7aa5e697616f4be72cbbb20" }))));
5907
+ } }), h("file-drop", { key: "87f1d105a94d63b1ff23061cca0787d6dcf909cf", onClick: () => this.fileInput?.click(), onDrop: this.handleDrop }, h("p", { key: "97fbb415cf9d528f1813a4c4ab512819f63e1838", part: "title" }, h("strong", { key: "f856b14d87bee688d2bec237b0cdef748f9ddc33" }, "Choose ", this.multiple ? "files" : "file", " "), h("span", { key: "c51929dd34c8826a434ee15dc577ce8ae4e65c72" }, "or drag ", this.multiple ? "them" : "it", " here.")), h("div", { key: "9a847df1d30360e515f6dd69652841ff56efb915", class: `media-preview ${this.multiple ? "-stacked" : ""}` }, h("slot", { key: "e2d06462bddde0191f1071eb6f1fd78b04c4b49a" }))));
5965
5908
  }
5966
5909
  componentDidRender() {
5967
5910
  if (this.files.length === 0) {
@@ -46,65 +46,15 @@ export class InputAttachment {
46
46
  const existingFiles = Array.from(this.el.children).filter(e => e.tagName == "ATTACHMENT-FILE");
47
47
  if(existingFiles.length > 0) this.files = existingFiles
48
48
 
49
- // Restore from localStorage BEFORE setting initial validity (which triggers saveToLocalStorage)
50
- this.restoreFromLocalStorage()
51
-
52
49
  // Set initial validity state (only if we have files from above)
53
50
  if(this.files.length > 0) this.updateFormValue()
54
51
  }
55
52
 
56
53
  componentDidLoad() {
57
- // Clear persistence data when form is submitted
58
- if (this.form) {
59
- this.form.addEventListener('submit', () => this.clearLocalStorage())
60
- }
61
-
62
54
  // Listen for file input changes directly (JSX onChange doesn't reliably work in shadow DOM)
63
55
  this.fileInput?.addEventListener('change', this.handleFileInputChange)
64
56
  }
65
57
 
66
- get localStorageKey() {
67
- if (!this.form || !this.name) return null
68
- const formId = this.form.id || this.form.action || 'form'
69
- return `input-attachment:${formId}:${this.name}`
70
- }
71
-
72
- saveToLocalStorage() {
73
- const key = this.localStorageKey
74
- if (!key) return
75
-
76
- const data = this.persistenceData
77
- if (data.length > 0) {
78
- localStorage.setItem(key, JSON.stringify(data))
79
- } else {
80
- localStorage.removeItem(key)
81
- }
82
- }
83
-
84
- restoreFromLocalStorage() {
85
- const key = this.localStorageKey
86
- if (!key || this.files.length > 0) return
87
-
88
- try {
89
- const stored = localStorage.getItem(key)
90
- if (stored) {
91
- const data = JSON.parse(stored)
92
- if (Array.isArray(data) && data.length > 0) {
93
- this.restoreFromPersistence(data)
94
- }
95
- }
96
- } catch (e) {
97
- // Invalid JSON, ignore
98
- }
99
- }
100
-
101
- clearLocalStorage() {
102
- const key = this.localStorageKey
103
- if (key) {
104
- localStorage.removeItem(key)
105
- }
106
- }
107
-
108
58
  // Methods
109
59
 
110
60
  get files() {
@@ -119,25 +69,7 @@ export class InputAttachment {
119
69
  }
120
70
 
121
71
  get value() {
122
- return this.files.map(e => e.value)
123
- }
124
-
125
- set value(val) {
126
- const newValue = val || []
127
- if(JSON.stringify(this.value) !== JSON.stringify(newValue)) { // this is insane. javascript is fucking garbage.
128
- this.files = newValue.map(signedId => {
129
- const attachmentFile = document.createElement('attachment-file') as any
130
- attachmentFile.name = this.name
131
- attachmentFile.preview = this.preview
132
- attachmentFile.signedId = signedId
133
- return attachmentFile
134
- })
135
- }
136
- }
137
-
138
- // For form-persistence: store complete attachment data (not just signed_ids)
139
- get persistenceData() {
140
- return this.files.map(f => ({
72
+ return JSON.stringify(this.files.map(f => ({
141
73
  value: f.value,
142
74
  filename: f.filename,
143
75
  src: f.src,
@@ -145,12 +77,15 @@ export class InputAttachment {
145
77
  percent: f.percent,
146
78
  size: f.size,
147
79
  filetype: f.filetype,
148
- }))
80
+ })))
149
81
  }
150
82
 
151
- restoreFromPersistence(data: any[]) {
152
- if (!Array.isArray(data) || data.length === 0) return
153
-
83
+ set value(val) {
84
+ const data = JSON.parse(val || "[]")
85
+ if (data.length === 0) {
86
+ this.files = []
87
+ return
88
+ }
154
89
  this.files = data.map(item => {
155
90
  const attachmentFile = document.createElement('attachment-file') as any
156
91
  attachmentFile.name = this.name
@@ -170,7 +105,7 @@ export class InputAttachment {
170
105
  updateFormValue() {
171
106
  if (!this.name || !this.internals?.setFormValue) return
172
107
  const formData = new FormData()
173
- const values = this.value.filter(v => v) // filter out empty values
108
+ const values = this.files.map(f => f.value).filter(v => v)
174
109
  if (this.multiple) {
175
110
  // For has_many_attached: append each signed_id separately
176
111
  values.forEach(signedId => formData.append(this.name, signedId))
@@ -182,9 +117,6 @@ export class InputAttachment {
182
117
  }
183
118
  this.internals.setFormValue(formData)
184
119
 
185
- // Save to localStorage for persistence across page reloads
186
- this.saveToLocalStorage()
187
-
188
120
  // Update validity state - check for required and child validation errors
189
121
  if (this.required && this.files.length === 0) {
190
122
  this.internals.setValidity({ valueMissing: true }, "Please select a file.", this.fileInput)
@@ -202,8 +134,7 @@ export class InputAttachment {
202
134
  }
203
135
 
204
136
  reset() {
205
- this.value = []
206
- this.clearLocalStorage()
137
+ this.files = []
207
138
  }
208
139
 
209
140
  handleFileInputChange = () => {
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Bard
4
4
  module AttachmentField
5
- VERSION = "0.3.1"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bard-attachment_field
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Micah Geisel
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-03-15 00:00:00.000000000 Z
11
+ date: 2026-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activestorage