@wordpress/block-library 8.19.2 → 8.19.3

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.
package/src/image/view.js CHANGED
@@ -17,6 +17,69 @@ const focusableSelectors = [
17
17
  '[tabindex]:not([tabindex^="-"])',
18
18
  ];
19
19
 
20
+ /*
21
+ * Stores a context-bound scroll handler.
22
+ *
23
+ * This callback could be defined inline inside of the store
24
+ * object but it's created externally to avoid confusion about
25
+ * how its logic is called. This logic is not referenced directly
26
+ * by the directives in the markup because the scroll event we
27
+ * need to listen to is triggered on the window; so by defining it
28
+ * outside of the store, we signal that the behavior here is different.
29
+ * If we find a compelling reason to move it to the store, feel free.
30
+ *
31
+ * @type {Function}
32
+ */
33
+ let scrollCallback;
34
+
35
+ /*
36
+ * Tracks whether user is touching screen; used to
37
+ * differentiate behavior for touch and mouse input.
38
+ *
39
+ * @type {boolean}
40
+ */
41
+ let isTouching = false;
42
+
43
+ /*
44
+ * Tracks the last time the screen was touched; used to
45
+ * differentiate behavior for touch and mouse input.
46
+ *
47
+ * @type {number}
48
+ */
49
+ let lastTouchTime = 0;
50
+
51
+ /*
52
+ * Lightbox page-scroll handler: prevents scrolling.
53
+ *
54
+ * This handler is added to prevent scrolling behaviors that
55
+ * trigger content shift while the lightbox is open.
56
+ *
57
+ * It would be better to accomplish this through CSS alone, but
58
+ * using overflow: hidden is currently the only way to do so, and
59
+ * that causes the layout to shift and prevents the zoom animation
60
+ * from working in some cases because we're unable to account for
61
+ * the layout shift when doing the animation calculations. Instead,
62
+ * here we use JavaScript to prevent and reset the scrolling
63
+ * behavior. In the future, we may be able to use CSS or overflow: hidden
64
+ * instead to not rely on JavaScript, but this seems to be the best approach
65
+ * for now that provides the best visual experience.
66
+ *
67
+ * @param {Object} context Interactivity page context?
68
+ */
69
+ function handleScroll( context ) {
70
+ // We can't override the scroll behavior on mobile devices
71
+ // because doing so breaks the pinch to zoom functionality, and we
72
+ // want to allow users to zoom in further on the high-res image.
73
+ if ( ! isTouching && Date.now() - lastTouchTime > 450 ) {
74
+ // We are unable to use event.preventDefault() to prevent scrolling
75
+ // because the scroll event can't be canceled, so we reset the position instead.
76
+ window.scrollTo(
77
+ context.core.image.scrollLeftReset,
78
+ context.core.image.scrollTopReset
79
+ );
80
+ }
81
+ }
82
+
20
83
  store(
21
84
  {
22
85
  state: {
@@ -43,54 +106,49 @@ store(
43
106
 
44
107
  context.core.image.lightboxEnabled = true;
45
108
  setStyles( context, event );
46
- // Hide overflow only when the animation is in progress,
47
- // otherwise the removal of the scrollbars will draw attention
48
- // to itself and look like an error
49
- document.documentElement.classList.add(
50
- 'wp-has-lightbox-open'
109
+
110
+ context.core.image.scrollTopReset =
111
+ window.pageYOffset ||
112
+ document.documentElement.scrollTop;
113
+
114
+ // In most cases, this value will be 0, but this is included
115
+ // in case a user has created a page with horizontal scrolling.
116
+ context.core.image.scrollLeftReset =
117
+ window.pageXOffset ||
118
+ document.documentElement.scrollLeft;
119
+
120
+ // We define and bind the scroll callback here so
121
+ // that we can pass the context and as an argument.
122
+ // We may be able to change this in the future if we
123
+ // define the scroll callback in the store instead, but
124
+ // this approach seems to tbe clearest for now.
125
+ scrollCallback = handleScroll.bind( null, context );
126
+
127
+ // We need to add a scroll event listener to the window
128
+ // here because we are unable to otherwise access it via
129
+ // the Interactivity API directives. If we add a native way
130
+ // to access the window, we can remove this.
131
+ window.addEventListener(
132
+ 'scroll',
133
+ scrollCallback,
134
+ false
51
135
  );
52
136
  },
53
- hideLightbox: async ( { context, event } ) => {
137
+ hideLightbox: async ( { context } ) => {
54
138
  context.core.image.hideAnimationEnabled = true;
55
139
  if ( context.core.image.lightboxEnabled ) {
56
- // If scrolling, wait a moment before closing the lightbox.
57
- if (
58
- context.core.image.lightboxAnimation === 'fade'
59
- ) {
60
- context.core.image.scrollDelta += event.deltaY;
61
- if (
62
- event.type === 'mousewheel' &&
63
- Math.abs(
64
- window.scrollY -
65
- context.core.image.scrollDelta
66
- ) < 10
67
- ) {
68
- return;
69
- }
70
- } else if (
71
- context.core.image.lightboxAnimation === 'zoom'
72
- ) {
73
- // Disable scroll until the zoom animation ends.
74
- // Get the current page scroll position
75
- const scrollTop =
76
- window.pageYOffset ||
77
- document.documentElement.scrollTop;
78
- const scrollLeft =
79
- window.pageXOffset ||
80
- document.documentElement.scrollLeft;
81
- // if any scroll is attempted, set this to the previous value.
82
- window.onscroll = function () {
83
- window.scrollTo( scrollLeft, scrollTop );
84
- };
85
- // Enable scrolling after the animation finishes
86
- setTimeout( function () {
87
- window.onscroll = function () {};
88
- }, 400 );
89
- }
90
-
91
- document.documentElement.classList.remove(
92
- 'wp-has-lightbox-open'
93
- );
140
+ // We want to wait until the close animation is completed
141
+ // before allowing a user to scroll again. The duration of this
142
+ // animation is defined in the styles.scss and depends on if the
143
+ // animation is 'zoom' or 'fade', but in any case we should wait
144
+ // a few milliseconds longer than the duration, otherwise a user
145
+ // may scroll too soon and cause the animation to look sloppy.
146
+ setTimeout( function () {
147
+ window.removeEventListener(
148
+ 'scroll',
149
+ scrollCallback
150
+ );
151
+ }, 450 );
94
152
 
95
153
  context.core.image.lightboxEnabled = false;
96
154
  context.core.image.lastFocusedElement.focus( {
@@ -139,6 +197,27 @@ store(
139
197
  ref,
140
198
  } );
141
199
  },
200
+ handleTouchStart: () => {
201
+ isTouching = true;
202
+ },
203
+ handleTouchMove: ( { context, event } ) => {
204
+ // On mobile devices, we want to prevent triggering the
205
+ // scroll event because otherwise the page jumps around as
206
+ // we reset the scroll position. This also means that closing
207
+ // the lightbox requires that a user perform a simple tap. This
208
+ // may be changed in the future if we find a better alternative
209
+ // to override or reset the scroll position during swipe actions.
210
+ if ( context.core.image.lightboxEnabled ) {
211
+ event.preventDefault();
212
+ }
213
+ },
214
+ handleTouchEnd: () => {
215
+ // We need to wait a few milliseconds before resetting
216
+ // to ensure that pinch to zoom works consistently
217
+ // on mobile devices when the lightbox is open.
218
+ lastTouchTime = Date.now();
219
+ isTouching = false;
220
+ },
142
221
  },
143
222
  },
144
223
  },
@@ -266,6 +345,13 @@ store(
266
345
  }
267
346
  );
268
347
 
348
+ /*
349
+ * Computes styles for the lightbox and adds them to the document.
350
+ *
351
+ * @function
352
+ * @param {Object} context - An Interactivity API context
353
+ * @param {Object} event - A triggering event
354
+ */
269
355
  function setStyles( context, event ) {
270
356
  // The reference img element lies adjacent
271
357
  // to the event target button in the DOM.
@@ -434,6 +520,13 @@ function setStyles( context, event ) {
434
520
  `;
435
521
  }
436
522
 
523
+ /*
524
+ * Debounces a function call.
525
+ *
526
+ * @function
527
+ * @param {Function} func - A function to be called
528
+ * @param {number} wait - The time to wait before calling the function
529
+ */
437
530
  function debounce( func, wait = 50 ) {
438
531
  let timeout;
439
532
  return () => {
@@ -5,7 +5,6 @@
5
5
  .wp-block-navigation {
6
6
  // This wraps just the innermost text for custom menu items.
7
7
  .wp-block-navigation-item__label {
8
- word-break: normal;
9
8
  overflow-wrap: break-word;
10
9
  }
11
10
 
@@ -155,7 +155,7 @@ function ParagraphBlock( {
155
155
  onRemove={ onRemove }
156
156
  aria-label={
157
157
  content
158
- ? __( 'Paragraph block' )
158
+ ? __( 'Block: Paragraph' )
159
159
  : __(
160
160
  'Empty block; start writing or type forward slash to choose a block'
161
161
  )
@@ -84,7 +84,7 @@ export default function SearchEdit( {
84
84
  style,
85
85
  } = attributes;
86
86
 
87
- const insertedInNavigationBlock = useSelect(
87
+ const wasJustInsertedIntoNavigationBlock = useSelect(
88
88
  ( select ) => {
89
89
  const { getBlockParentsByBlockName, wasBlockJustInserted } =
90
90
  select( blockEditorStore );
@@ -98,15 +98,21 @@ export default function SearchEdit( {
98
98
  const { __unstableMarkNextChangeAsNotPersistent } =
99
99
  useDispatch( blockEditorStore );
100
100
 
101
- if ( insertedInNavigationBlock ) {
102
- // This side-effect should not create an undo level.
103
- __unstableMarkNextChangeAsNotPersistent();
104
- setAttributes( {
105
- showLabel: false,
106
- buttonUseIcon: true,
107
- buttonPosition: 'button-inside',
108
- } );
109
- }
101
+ useEffect( () => {
102
+ if ( wasJustInsertedIntoNavigationBlock ) {
103
+ // This side-effect should not create an undo level.
104
+ __unstableMarkNextChangeAsNotPersistent();
105
+ setAttributes( {
106
+ showLabel: false,
107
+ buttonUseIcon: true,
108
+ buttonPosition: 'button-inside',
109
+ } );
110
+ }
111
+ }, [
112
+ __unstableMarkNextChangeAsNotPersistent,
113
+ wasJustInsertedIntoNavigationBlock,
114
+ setAttributes,
115
+ ] );
110
116
 
111
117
  const borderRadius = style?.border?.radius;
112
118
  const borderProps = useBorderProps( attributes );