@ionic/core 8.6.1-dev.11749575087.1b86eb67 → 8.6.1-dev.11749648223.169ce853

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.
@@ -14,6 +14,9 @@ const ReorderGroup = /*@__PURE__*/ proxyCustomElement(class ReorderGroup extends
14
14
  super();
15
15
  this.__registerHost();
16
16
  this.ionItemReorder = createEvent(this, "ionItemReorder", 7);
17
+ this.ionReorderStart = createEvent(this, "ionReorderStart", 7);
18
+ this.ionReorderMove = createEvent(this, "ionReorderMove", 7);
19
+ this.ionReorderEnd = createEvent(this, "ionReorderEnd", 7);
17
20
  this.lastToIndex = -1;
18
21
  this.cachedHeights = [];
19
22
  this.scrollElTop = 0;
@@ -59,7 +62,7 @@ const ReorderGroup = /*@__PURE__*/ proxyCustomElement(class ReorderGroup extends
59
62
  }
60
63
  }
61
64
  /**
62
- * Completes the reorder operation. Must be called by the `ionItemReorder` event.
65
+ * Completes the reorder operation. Must be called by the `ionReorderEnd` event.
63
66
  *
64
67
  * If a list of items is passed, the list will be reordered and returned in the
65
68
  * proper order.
@@ -126,6 +129,7 @@ const ReorderGroup = /*@__PURE__*/ proxyCustomElement(class ReorderGroup extends
126
129
  this.state = 1 /* ReorderGroupState.Active */;
127
130
  item.classList.add(ITEM_REORDER_SELECTED);
128
131
  hapticSelectionStart();
132
+ this.ionReorderStart.emit();
129
133
  }
130
134
  onMove(ev) {
131
135
  const selectedItem = this.selectedItemEl;
@@ -140,6 +144,7 @@ const ReorderGroup = /*@__PURE__*/ proxyCustomElement(class ReorderGroup extends
140
144
  const currentY = Math.max(top, Math.min(ev.currentY, bottom));
141
145
  const deltaY = scroll + currentY - ev.startY;
142
146
  const normalizedY = currentY - top;
147
+ const fromIndex = this.lastToIndex;
143
148
  const toIndex = this.itemIndexForTop(normalizedY);
144
149
  if (toIndex !== this.lastToIndex) {
145
150
  const fromIndex = indexForItem(selectedItem);
@@ -149,6 +154,10 @@ const ReorderGroup = /*@__PURE__*/ proxyCustomElement(class ReorderGroup extends
149
154
  }
150
155
  // Update selected item position
151
156
  selectedItem.style.transform = `translateY(${deltaY}px)`;
157
+ this.ionReorderMove.emit({
158
+ from: fromIndex,
159
+ to: toIndex,
160
+ });
152
161
  }
153
162
  onEnd() {
154
163
  const selectedItemEl = this.selectedItemEl;
@@ -160,14 +169,23 @@ const ReorderGroup = /*@__PURE__*/ proxyCustomElement(class ReorderGroup extends
160
169
  const toIndex = this.lastToIndex;
161
170
  const fromIndex = indexForItem(selectedItemEl);
162
171
  if (toIndex === fromIndex) {
172
+ this.ionReorderEnd.emit({
173
+ complete: this.completeReorder.bind(this),
174
+ });
163
175
  this.completeReorder();
164
176
  }
165
177
  else {
178
+ // TODO(FW-6590): Remove this once the deprecated event is removed
166
179
  this.ionItemReorder.emit({
167
180
  from: fromIndex,
168
181
  to: toIndex,
169
182
  complete: this.completeReorder.bind(this),
170
183
  });
184
+ this.ionReorderEnd.emit({
185
+ from: fromIndex,
186
+ to: toIndex,
187
+ complete: this.completeReorder.bind(this),
188
+ });
171
189
  }
172
190
  hapticSelectionEnd();
173
191
  }
@@ -247,7 +265,7 @@ const ReorderGroup = /*@__PURE__*/ proxyCustomElement(class ReorderGroup extends
247
265
  }
248
266
  render() {
249
267
  const mode = getIonMode(this);
250
- return (h(Host, { key: 'f30613b361c5c3095b7928a92fb4b1e8d6eff600', class: {
268
+ return (h(Host, { key: '8f47e24dfc7b8ef53ad3f5816fa13a8fa07de2a6', class: {
251
269
  [mode]: true,
252
270
  'reorder-enabled': !this.disabled,
253
271
  'reorder-list-active': this.state !== 0 /* ReorderGroupState.Idle */,
@@ -827,7 +827,7 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
827
827
  let offset = 0;
828
828
  let canDismissBlocksGesture = false;
829
829
  let cachedScrollEl = null;
830
- let cachedFooterEls = null;
830
+ let cachedFooterEl = null;
831
831
  let cachedFooterYPosition = null;
832
832
  let currentFooterState = null;
833
833
  const canDismissMaxStep = 0.95;
@@ -864,81 +864,60 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
864
864
  * @param newPosition Whether the footer is in a moving or stationary position.
865
865
  */
866
866
  const swapFooterPosition = (newPosition) => {
867
- if (!cachedFooterEls) {
868
- cachedFooterEls = Array.from(baseEl.querySelectorAll('ion-footer'));
869
- if (!cachedFooterEls.length) {
867
+ if (!cachedFooterEl) {
868
+ cachedFooterEl = baseEl.querySelector('ion-footer');
869
+ if (!cachedFooterEl) {
870
870
  return;
871
871
  }
872
872
  }
873
873
  const page = baseEl.querySelector('.ion-page');
874
874
  currentFooterState = newPosition;
875
875
  if (newPosition === 'stationary') {
876
- cachedFooterEls.forEach((cachedFooterEl) => {
877
- // Reset positioning styles to allow normal document flow
878
- cachedFooterEl.classList.remove('modal-footer-moving');
879
- cachedFooterEl.style.removeProperty('position');
880
- cachedFooterEl.style.removeProperty('width');
881
- cachedFooterEl.style.removeProperty('height');
882
- cachedFooterEl.style.removeProperty('top');
883
- cachedFooterEl.style.removeProperty('left');
884
- page === null || page === void 0 ? void 0 : page.style.removeProperty('padding-bottom');
885
- // Move to page
886
- page === null || page === void 0 ? void 0 : page.appendChild(cachedFooterEl);
887
- });
876
+ // Reset positioning styles to allow normal document flow
877
+ cachedFooterEl.classList.remove('modal-footer-moving');
878
+ cachedFooterEl.style.removeProperty('position');
879
+ cachedFooterEl.style.removeProperty('width');
880
+ cachedFooterEl.style.removeProperty('height');
881
+ cachedFooterEl.style.removeProperty('top');
882
+ cachedFooterEl.style.removeProperty('left');
883
+ page === null || page === void 0 ? void 0 : page.style.removeProperty('padding-bottom');
884
+ // Move to page
885
+ page === null || page === void 0 ? void 0 : page.appendChild(cachedFooterEl);
888
886
  }
889
887
  else {
890
- let footerHeights = 0;
891
- cachedFooterEls.forEach((cachedFooterEl, index) => {
892
- // Get both the footer and document body positions
893
- const cachedFooterElRect = cachedFooterEl.getBoundingClientRect();
894
- const bodyRect = document.body.getBoundingClientRect();
895
- // Calculate the total height of all footers
896
- // so we can add padding to the page element
897
- footerHeights += cachedFooterEl.clientHeight;
898
- // Calculate absolute position relative to body
899
- // We need to subtract the body's offsetTop to get true position within document.body
900
- const absoluteTop = cachedFooterElRect.top - bodyRect.top;
901
- const absoluteLeft = cachedFooterElRect.left - bodyRect.left;
902
- // Capture the footer's current dimensions and store them in CSS variables for
903
- // later use when applying absolute positioning.
904
- cachedFooterEl.style.setProperty('--pinned-width', `${cachedFooterEl.clientWidth}px`);
905
- cachedFooterEl.style.setProperty('--pinned-height', `${cachedFooterEl.clientHeight}px`);
906
- cachedFooterEl.style.setProperty('--pinned-top', `${absoluteTop}px`);
907
- cachedFooterEl.style.setProperty('--pinned-left', `${absoluteLeft}px`);
908
- // Only cache the first footer's Y position
909
- // This is used to determine if the sheet has been moved below the footer
910
- // and needs to be swapped back to stationary so it collapses correctly.
911
- if (index === 0) {
912
- cachedFooterYPosition = absoluteTop;
913
- // If there's a header, we need to combine the header height with the footer position
914
- // because the header moves with the drag handle, so when it starts overlapping the footer,
915
- // we need to account for that.
916
- const header = baseEl.querySelector('ion-header');
917
- if (header) {
918
- cachedFooterYPosition -= header.clientHeight;
919
- }
920
- }
921
- });
922
- // Apply the pinning of styles after we've calculated everything
923
- // so that we don't cause layouts to shift while calculating the footer positions.
924
- // Otherwise, with multiple footers we'll end up capturing the wrong positions.
925
- cachedFooterEls.forEach((cachedFooterEl) => {
926
- // Add padding to the parent element to prevent content from being hidden
927
- // when the footer is positioned absolutely. This has to be done before we
928
- // make the footer absolutely positioned or we may accidentally cause the
929
- // sheet to scroll.
930
- page === null || page === void 0 ? void 0 : page.style.setProperty('padding-bottom', `${footerHeights}px`);
931
- // Apply positioning styles to keep footer at bottom
932
- cachedFooterEl.classList.add('modal-footer-moving');
933
- // Apply our preserved styles to pin the footer
934
- cachedFooterEl.style.setProperty('position', 'absolute');
935
- cachedFooterEl.style.setProperty('width', 'var(--pinned-width)');
936
- cachedFooterEl.style.setProperty('height', 'var(--pinned-height)');
937
- cachedFooterEl.style.setProperty('top', 'var(--pinned-top)');
938
- cachedFooterEl.style.setProperty('left', 'var(--pinned-left)');
939
- // Move the element to the body when everything else is done
940
- document.body.appendChild(cachedFooterEl);
941
- });
888
+ // Get both the footer and document body positions
889
+ const cachedFooterElRect = cachedFooterEl.getBoundingClientRect();
890
+ const bodyRect = document.body.getBoundingClientRect();
891
+ // Add padding to the parent element to prevent content from being hidden
892
+ // when the footer is positioned absolutely. This has to be done before we
893
+ // make the footer absolutely positioned or we may accidentally cause the
894
+ // sheet to scroll.
895
+ const footerHeight = cachedFooterEl.clientHeight;
896
+ page === null || page === void 0 ? void 0 : page.style.setProperty('padding-bottom', `${footerHeight}px`);
897
+ // Apply positioning styles to keep footer at bottom
898
+ cachedFooterEl.classList.add('modal-footer-moving');
899
+ // Calculate absolute position relative to body
900
+ // We need to subtract the body's offsetTop to get true position within document.body
901
+ const absoluteTop = cachedFooterElRect.top - bodyRect.top;
902
+ const absoluteLeft = cachedFooterElRect.left - bodyRect.left;
903
+ // Capture the footer's current dimensions and hard code them during the drag
904
+ cachedFooterEl.style.setProperty('position', 'absolute');
905
+ cachedFooterEl.style.setProperty('width', `${cachedFooterEl.clientWidth}px`);
906
+ cachedFooterEl.style.setProperty('height', `${cachedFooterEl.clientHeight}px`);
907
+ cachedFooterEl.style.setProperty('top', `${absoluteTop}px`);
908
+ cachedFooterEl.style.setProperty('left', `${absoluteLeft}px`);
909
+ // Also cache the footer Y position, which we use to determine if the
910
+ // sheet has been moved below the footer. When that happens, we need to swap
911
+ // the position back so it will collapse correctly.
912
+ cachedFooterYPosition = absoluteTop;
913
+ // If there's a toolbar, we need to combine the toolbar height with the footer position
914
+ // because the toolbar moves with the drag handle, so when it starts overlapping the footer,
915
+ // we need to account for that.
916
+ const toolbar = baseEl.querySelector('ion-toolbar');
917
+ if (toolbar) {
918
+ cachedFooterYPosition -= toolbar.clientHeight;
919
+ }
920
+ document.body.appendChild(cachedFooterEl);
942
921
  }
943
922
  };
944
923
  /**
@@ -1130,16 +1109,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
1130
1109
  * is not scrolled to the top.
1131
1110
  */
1132
1111
  if (!expandToScroll && detail.deltaY <= 0 && cachedScrollEl && cachedScrollEl.scrollTop > 0) {
1133
- /**
1134
- * If expand to scroll is disabled, we need to make sure we swap the footer position
1135
- * back to stationary so that it will collapse correctly if the modal is dismissed without
1136
- * dragging (e.g. through a dismiss button).
1137
- * This can cause issues if the user has a modal with content that can be dragged, as we'll
1138
- * swap to moving on drag and if we don't swap back here then the footer will get stuck.
1139
- */
1140
- if (!expandToScroll) {
1141
- swapFooterPosition('stationary');
1142
- }
1143
1112
  return;
1144
1113
  }
1145
1114
  /**
@@ -829,7 +829,7 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
829
829
  let offset = 0;
830
830
  let canDismissBlocksGesture = false;
831
831
  let cachedScrollEl = null;
832
- let cachedFooterEls = null;
832
+ let cachedFooterEl = null;
833
833
  let cachedFooterYPosition = null;
834
834
  let currentFooterState = null;
835
835
  const canDismissMaxStep = 0.95;
@@ -866,81 +866,60 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
866
866
  * @param newPosition Whether the footer is in a moving or stationary position.
867
867
  */
868
868
  const swapFooterPosition = (newPosition) => {
869
- if (!cachedFooterEls) {
870
- cachedFooterEls = Array.from(baseEl.querySelectorAll('ion-footer'));
871
- if (!cachedFooterEls.length) {
869
+ if (!cachedFooterEl) {
870
+ cachedFooterEl = baseEl.querySelector('ion-footer');
871
+ if (!cachedFooterEl) {
872
872
  return;
873
873
  }
874
874
  }
875
875
  const page = baseEl.querySelector('.ion-page');
876
876
  currentFooterState = newPosition;
877
877
  if (newPosition === 'stationary') {
878
- cachedFooterEls.forEach((cachedFooterEl) => {
879
- // Reset positioning styles to allow normal document flow
880
- cachedFooterEl.classList.remove('modal-footer-moving');
881
- cachedFooterEl.style.removeProperty('position');
882
- cachedFooterEl.style.removeProperty('width');
883
- cachedFooterEl.style.removeProperty('height');
884
- cachedFooterEl.style.removeProperty('top');
885
- cachedFooterEl.style.removeProperty('left');
886
- page === null || page === void 0 ? void 0 : page.style.removeProperty('padding-bottom');
887
- // Move to page
888
- page === null || page === void 0 ? void 0 : page.appendChild(cachedFooterEl);
889
- });
878
+ // Reset positioning styles to allow normal document flow
879
+ cachedFooterEl.classList.remove('modal-footer-moving');
880
+ cachedFooterEl.style.removeProperty('position');
881
+ cachedFooterEl.style.removeProperty('width');
882
+ cachedFooterEl.style.removeProperty('height');
883
+ cachedFooterEl.style.removeProperty('top');
884
+ cachedFooterEl.style.removeProperty('left');
885
+ page === null || page === void 0 ? void 0 : page.style.removeProperty('padding-bottom');
886
+ // Move to page
887
+ page === null || page === void 0 ? void 0 : page.appendChild(cachedFooterEl);
890
888
  }
891
889
  else {
892
- let footerHeights = 0;
893
- cachedFooterEls.forEach((cachedFooterEl, index) => {
894
- // Get both the footer and document body positions
895
- const cachedFooterElRect = cachedFooterEl.getBoundingClientRect();
896
- const bodyRect = document.body.getBoundingClientRect();
897
- // Calculate the total height of all footers
898
- // so we can add padding to the page element
899
- footerHeights += cachedFooterEl.clientHeight;
900
- // Calculate absolute position relative to body
901
- // We need to subtract the body's offsetTop to get true position within document.body
902
- const absoluteTop = cachedFooterElRect.top - bodyRect.top;
903
- const absoluteLeft = cachedFooterElRect.left - bodyRect.left;
904
- // Capture the footer's current dimensions and store them in CSS variables for
905
- // later use when applying absolute positioning.
906
- cachedFooterEl.style.setProperty('--pinned-width', `${cachedFooterEl.clientWidth}px`);
907
- cachedFooterEl.style.setProperty('--pinned-height', `${cachedFooterEl.clientHeight}px`);
908
- cachedFooterEl.style.setProperty('--pinned-top', `${absoluteTop}px`);
909
- cachedFooterEl.style.setProperty('--pinned-left', `${absoluteLeft}px`);
910
- // Only cache the first footer's Y position
911
- // This is used to determine if the sheet has been moved below the footer
912
- // and needs to be swapped back to stationary so it collapses correctly.
913
- if (index === 0) {
914
- cachedFooterYPosition = absoluteTop;
915
- // If there's a header, we need to combine the header height with the footer position
916
- // because the header moves with the drag handle, so when it starts overlapping the footer,
917
- // we need to account for that.
918
- const header = baseEl.querySelector('ion-header');
919
- if (header) {
920
- cachedFooterYPosition -= header.clientHeight;
921
- }
922
- }
923
- });
924
- // Apply the pinning of styles after we've calculated everything
925
- // so that we don't cause layouts to shift while calculating the footer positions.
926
- // Otherwise, with multiple footers we'll end up capturing the wrong positions.
927
- cachedFooterEls.forEach((cachedFooterEl) => {
928
- // Add padding to the parent element to prevent content from being hidden
929
- // when the footer is positioned absolutely. This has to be done before we
930
- // make the footer absolutely positioned or we may accidentally cause the
931
- // sheet to scroll.
932
- page === null || page === void 0 ? void 0 : page.style.setProperty('padding-bottom', `${footerHeights}px`);
933
- // Apply positioning styles to keep footer at bottom
934
- cachedFooterEl.classList.add('modal-footer-moving');
935
- // Apply our preserved styles to pin the footer
936
- cachedFooterEl.style.setProperty('position', 'absolute');
937
- cachedFooterEl.style.setProperty('width', 'var(--pinned-width)');
938
- cachedFooterEl.style.setProperty('height', 'var(--pinned-height)');
939
- cachedFooterEl.style.setProperty('top', 'var(--pinned-top)');
940
- cachedFooterEl.style.setProperty('left', 'var(--pinned-left)');
941
- // Move the element to the body when everything else is done
942
- document.body.appendChild(cachedFooterEl);
943
- });
890
+ // Get both the footer and document body positions
891
+ const cachedFooterElRect = cachedFooterEl.getBoundingClientRect();
892
+ const bodyRect = document.body.getBoundingClientRect();
893
+ // Add padding to the parent element to prevent content from being hidden
894
+ // when the footer is positioned absolutely. This has to be done before we
895
+ // make the footer absolutely positioned or we may accidentally cause the
896
+ // sheet to scroll.
897
+ const footerHeight = cachedFooterEl.clientHeight;
898
+ page === null || page === void 0 ? void 0 : page.style.setProperty('padding-bottom', `${footerHeight}px`);
899
+ // Apply positioning styles to keep footer at bottom
900
+ cachedFooterEl.classList.add('modal-footer-moving');
901
+ // Calculate absolute position relative to body
902
+ // We need to subtract the body's offsetTop to get true position within document.body
903
+ const absoluteTop = cachedFooterElRect.top - bodyRect.top;
904
+ const absoluteLeft = cachedFooterElRect.left - bodyRect.left;
905
+ // Capture the footer's current dimensions and hard code them during the drag
906
+ cachedFooterEl.style.setProperty('position', 'absolute');
907
+ cachedFooterEl.style.setProperty('width', `${cachedFooterEl.clientWidth}px`);
908
+ cachedFooterEl.style.setProperty('height', `${cachedFooterEl.clientHeight}px`);
909
+ cachedFooterEl.style.setProperty('top', `${absoluteTop}px`);
910
+ cachedFooterEl.style.setProperty('left', `${absoluteLeft}px`);
911
+ // Also cache the footer Y position, which we use to determine if the
912
+ // sheet has been moved below the footer. When that happens, we need to swap
913
+ // the position back so it will collapse correctly.
914
+ cachedFooterYPosition = absoluteTop;
915
+ // If there's a toolbar, we need to combine the toolbar height with the footer position
916
+ // because the toolbar moves with the drag handle, so when it starts overlapping the footer,
917
+ // we need to account for that.
918
+ const toolbar = baseEl.querySelector('ion-toolbar');
919
+ if (toolbar) {
920
+ cachedFooterYPosition -= toolbar.clientHeight;
921
+ }
922
+ document.body.appendChild(cachedFooterEl);
944
923
  }
945
924
  };
946
925
  /**
@@ -1132,16 +1111,6 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
1132
1111
  * is not scrolled to the top.
1133
1112
  */
1134
1113
  if (!expandToScroll && detail.deltaY <= 0 && cachedScrollEl && cachedScrollEl.scrollTop > 0) {
1135
- /**
1136
- * If expand to scroll is disabled, we need to make sure we swap the footer position
1137
- * back to stationary so that it will collapse correctly if the modal is dismissed without
1138
- * dragging (e.g. through a dismiss button).
1139
- * This can cause issues if the user has a modal with content that can be dragged, as we'll
1140
- * swap to moving on drag and if we don't swap back here then the footer will get stuck.
1141
- */
1142
- if (!expandToScroll) {
1143
- swapFooterPosition('stationary');
1144
- }
1145
1114
  return;
1146
1115
  }
1147
1116
  /**
@@ -46,6 +46,9 @@ const ReorderGroup = class {
46
46
  constructor(hostRef) {
47
47
  index.registerInstance(this, hostRef);
48
48
  this.ionItemReorder = index.createEvent(this, "ionItemReorder", 7);
49
+ this.ionReorderStart = index.createEvent(this, "ionReorderStart", 7);
50
+ this.ionReorderMove = index.createEvent(this, "ionReorderMove", 7);
51
+ this.ionReorderEnd = index.createEvent(this, "ionReorderEnd", 7);
49
52
  this.lastToIndex = -1;
50
53
  this.cachedHeights = [];
51
54
  this.scrollElTop = 0;
@@ -91,7 +94,7 @@ const ReorderGroup = class {
91
94
  }
92
95
  }
93
96
  /**
94
- * Completes the reorder operation. Must be called by the `ionItemReorder` event.
97
+ * Completes the reorder operation. Must be called by the `ionReorderEnd` event.
95
98
  *
96
99
  * If a list of items is passed, the list will be reordered and returned in the
97
100
  * proper order.
@@ -158,6 +161,7 @@ const ReorderGroup = class {
158
161
  this.state = 1 /* ReorderGroupState.Active */;
159
162
  item.classList.add(ITEM_REORDER_SELECTED);
160
163
  haptic.hapticSelectionStart();
164
+ this.ionReorderStart.emit();
161
165
  }
162
166
  onMove(ev) {
163
167
  const selectedItem = this.selectedItemEl;
@@ -172,6 +176,7 @@ const ReorderGroup = class {
172
176
  const currentY = Math.max(top, Math.min(ev.currentY, bottom));
173
177
  const deltaY = scroll + currentY - ev.startY;
174
178
  const normalizedY = currentY - top;
179
+ const fromIndex = this.lastToIndex;
175
180
  const toIndex = this.itemIndexForTop(normalizedY);
176
181
  if (toIndex !== this.lastToIndex) {
177
182
  const fromIndex = indexForItem(selectedItem);
@@ -181,6 +186,10 @@ const ReorderGroup = class {
181
186
  }
182
187
  // Update selected item position
183
188
  selectedItem.style.transform = `translateY(${deltaY}px)`;
189
+ this.ionReorderMove.emit({
190
+ from: fromIndex,
191
+ to: toIndex,
192
+ });
184
193
  }
185
194
  onEnd() {
186
195
  const selectedItemEl = this.selectedItemEl;
@@ -192,14 +201,23 @@ const ReorderGroup = class {
192
201
  const toIndex = this.lastToIndex;
193
202
  const fromIndex = indexForItem(selectedItemEl);
194
203
  if (toIndex === fromIndex) {
204
+ this.ionReorderEnd.emit({
205
+ complete: this.completeReorder.bind(this),
206
+ });
195
207
  this.completeReorder();
196
208
  }
197
209
  else {
210
+ // TODO(FW-6590): Remove this once the deprecated event is removed
198
211
  this.ionItemReorder.emit({
199
212
  from: fromIndex,
200
213
  to: toIndex,
201
214
  complete: this.completeReorder.bind(this),
202
215
  });
216
+ this.ionReorderEnd.emit({
217
+ from: fromIndex,
218
+ to: toIndex,
219
+ complete: this.completeReorder.bind(this),
220
+ });
203
221
  }
204
222
  haptic.hapticSelectionEnd();
205
223
  }
@@ -279,7 +297,7 @@ const ReorderGroup = class {
279
297
  }
280
298
  render() {
281
299
  const mode = index.getIonMode(this);
282
- return (index.h(index.Host, { key: 'f30613b361c5c3095b7928a92fb4b1e8d6eff600', class: {
300
+ return (index.h(index.Host, { key: '8f47e24dfc7b8ef53ad3f5816fa13a8fa07de2a6', class: {
283
301
  [mode]: true,
284
302
  'reorder-enabled': !this.disabled,
285
303
  'reorder-list-active': this.state !== 0 /* ReorderGroupState.Idle */,
@@ -35,7 +35,7 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
35
35
  let offset = 0;
36
36
  let canDismissBlocksGesture = false;
37
37
  let cachedScrollEl = null;
38
- let cachedFooterEls = null;
38
+ let cachedFooterEl = null;
39
39
  let cachedFooterYPosition = null;
40
40
  let currentFooterState = null;
41
41
  const canDismissMaxStep = 0.95;
@@ -72,81 +72,60 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
72
72
  * @param newPosition Whether the footer is in a moving or stationary position.
73
73
  */
74
74
  const swapFooterPosition = (newPosition) => {
75
- if (!cachedFooterEls) {
76
- cachedFooterEls = Array.from(baseEl.querySelectorAll('ion-footer'));
77
- if (!cachedFooterEls.length) {
75
+ if (!cachedFooterEl) {
76
+ cachedFooterEl = baseEl.querySelector('ion-footer');
77
+ if (!cachedFooterEl) {
78
78
  return;
79
79
  }
80
80
  }
81
81
  const page = baseEl.querySelector('.ion-page');
82
82
  currentFooterState = newPosition;
83
83
  if (newPosition === 'stationary') {
84
- cachedFooterEls.forEach((cachedFooterEl) => {
85
- // Reset positioning styles to allow normal document flow
86
- cachedFooterEl.classList.remove('modal-footer-moving');
87
- cachedFooterEl.style.removeProperty('position');
88
- cachedFooterEl.style.removeProperty('width');
89
- cachedFooterEl.style.removeProperty('height');
90
- cachedFooterEl.style.removeProperty('top');
91
- cachedFooterEl.style.removeProperty('left');
92
- page === null || page === void 0 ? void 0 : page.style.removeProperty('padding-bottom');
93
- // Move to page
94
- page === null || page === void 0 ? void 0 : page.appendChild(cachedFooterEl);
95
- });
84
+ // Reset positioning styles to allow normal document flow
85
+ cachedFooterEl.classList.remove('modal-footer-moving');
86
+ cachedFooterEl.style.removeProperty('position');
87
+ cachedFooterEl.style.removeProperty('width');
88
+ cachedFooterEl.style.removeProperty('height');
89
+ cachedFooterEl.style.removeProperty('top');
90
+ cachedFooterEl.style.removeProperty('left');
91
+ page === null || page === void 0 ? void 0 : page.style.removeProperty('padding-bottom');
92
+ // Move to page
93
+ page === null || page === void 0 ? void 0 : page.appendChild(cachedFooterEl);
96
94
  }
97
95
  else {
98
- let footerHeights = 0;
99
- cachedFooterEls.forEach((cachedFooterEl, index) => {
100
- // Get both the footer and document body positions
101
- const cachedFooterElRect = cachedFooterEl.getBoundingClientRect();
102
- const bodyRect = document.body.getBoundingClientRect();
103
- // Calculate the total height of all footers
104
- // so we can add padding to the page element
105
- footerHeights += cachedFooterEl.clientHeight;
106
- // Calculate absolute position relative to body
107
- // We need to subtract the body's offsetTop to get true position within document.body
108
- const absoluteTop = cachedFooterElRect.top - bodyRect.top;
109
- const absoluteLeft = cachedFooterElRect.left - bodyRect.left;
110
- // Capture the footer's current dimensions and store them in CSS variables for
111
- // later use when applying absolute positioning.
112
- cachedFooterEl.style.setProperty('--pinned-width', `${cachedFooterEl.clientWidth}px`);
113
- cachedFooterEl.style.setProperty('--pinned-height', `${cachedFooterEl.clientHeight}px`);
114
- cachedFooterEl.style.setProperty('--pinned-top', `${absoluteTop}px`);
115
- cachedFooterEl.style.setProperty('--pinned-left', `${absoluteLeft}px`);
116
- // Only cache the first footer's Y position
117
- // This is used to determine if the sheet has been moved below the footer
118
- // and needs to be swapped back to stationary so it collapses correctly.
119
- if (index === 0) {
120
- cachedFooterYPosition = absoluteTop;
121
- // If there's a header, we need to combine the header height with the footer position
122
- // because the header moves with the drag handle, so when it starts overlapping the footer,
123
- // we need to account for that.
124
- const header = baseEl.querySelector('ion-header');
125
- if (header) {
126
- cachedFooterYPosition -= header.clientHeight;
127
- }
128
- }
129
- });
130
- // Apply the pinning of styles after we've calculated everything
131
- // so that we don't cause layouts to shift while calculating the footer positions.
132
- // Otherwise, with multiple footers we'll end up capturing the wrong positions.
133
- cachedFooterEls.forEach((cachedFooterEl) => {
134
- // Add padding to the parent element to prevent content from being hidden
135
- // when the footer is positioned absolutely. This has to be done before we
136
- // make the footer absolutely positioned or we may accidentally cause the
137
- // sheet to scroll.
138
- page === null || page === void 0 ? void 0 : page.style.setProperty('padding-bottom', `${footerHeights}px`);
139
- // Apply positioning styles to keep footer at bottom
140
- cachedFooterEl.classList.add('modal-footer-moving');
141
- // Apply our preserved styles to pin the footer
142
- cachedFooterEl.style.setProperty('position', 'absolute');
143
- cachedFooterEl.style.setProperty('width', 'var(--pinned-width)');
144
- cachedFooterEl.style.setProperty('height', 'var(--pinned-height)');
145
- cachedFooterEl.style.setProperty('top', 'var(--pinned-top)');
146
- cachedFooterEl.style.setProperty('left', 'var(--pinned-left)');
147
- // Move the element to the body when everything else is done
148
- document.body.appendChild(cachedFooterEl);
149
- });
96
+ // Get both the footer and document body positions
97
+ const cachedFooterElRect = cachedFooterEl.getBoundingClientRect();
98
+ const bodyRect = document.body.getBoundingClientRect();
99
+ // Add padding to the parent element to prevent content from being hidden
100
+ // when the footer is positioned absolutely. This has to be done before we
101
+ // make the footer absolutely positioned or we may accidentally cause the
102
+ // sheet to scroll.
103
+ const footerHeight = cachedFooterEl.clientHeight;
104
+ page === null || page === void 0 ? void 0 : page.style.setProperty('padding-bottom', `${footerHeight}px`);
105
+ // Apply positioning styles to keep footer at bottom
106
+ cachedFooterEl.classList.add('modal-footer-moving');
107
+ // Calculate absolute position relative to body
108
+ // We need to subtract the body's offsetTop to get true position within document.body
109
+ const absoluteTop = cachedFooterElRect.top - bodyRect.top;
110
+ const absoluteLeft = cachedFooterElRect.left - bodyRect.left;
111
+ // Capture the footer's current dimensions and hard code them during the drag
112
+ cachedFooterEl.style.setProperty('position', 'absolute');
113
+ cachedFooterEl.style.setProperty('width', `${cachedFooterEl.clientWidth}px`);
114
+ cachedFooterEl.style.setProperty('height', `${cachedFooterEl.clientHeight}px`);
115
+ cachedFooterEl.style.setProperty('top', `${absoluteTop}px`);
116
+ cachedFooterEl.style.setProperty('left', `${absoluteLeft}px`);
117
+ // Also cache the footer Y position, which we use to determine if the
118
+ // sheet has been moved below the footer. When that happens, we need to swap
119
+ // the position back so it will collapse correctly.
120
+ cachedFooterYPosition = absoluteTop;
121
+ // If there's a toolbar, we need to combine the toolbar height with the footer position
122
+ // because the toolbar moves with the drag handle, so when it starts overlapping the footer,
123
+ // we need to account for that.
124
+ const toolbar = baseEl.querySelector('ion-toolbar');
125
+ if (toolbar) {
126
+ cachedFooterYPosition -= toolbar.clientHeight;
127
+ }
128
+ document.body.appendChild(cachedFooterEl);
150
129
  }
151
130
  };
152
131
  /**
@@ -338,16 +317,6 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
338
317
  * is not scrolled to the top.
339
318
  */
340
319
  if (!expandToScroll && detail.deltaY <= 0 && cachedScrollEl && cachedScrollEl.scrollTop > 0) {
341
- /**
342
- * If expand to scroll is disabled, we need to make sure we swap the footer position
343
- * back to stationary so that it will collapse correctly if the modal is dismissed without
344
- * dragging (e.g. through a dismiss button).
345
- * This can cause issues if the user has a modal with content that can be dragged, as we'll
346
- * swap to moving on drag and if we don't swap back here then the footer will get stuck.
347
- */
348
- if (!expandToScroll) {
349
- swapFooterPosition('stationary');
350
- }
351
320
  return;
352
321
  }
353
322
  /**