@wordpress/components 28.7.0 → 28.8.1-next.5368f64a9.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.
- package/CHANGELOG.md +30 -0
- package/build/composite/context.js +1 -1
- package/build/composite/context.js.map +1 -1
- package/build/composite/group-label.js +1 -1
- package/build/composite/group-label.js.map +1 -1
- package/build/composite/group.js +1 -1
- package/build/composite/group.js.map +1 -1
- package/build/composite/hover.js +1 -1
- package/build/composite/hover.js.map +1 -1
- package/build/composite/index.js +17 -26
- package/build/composite/index.js.map +1 -1
- package/build/composite/item.js +1 -1
- package/build/composite/item.js.map +1 -1
- package/build/composite/legacy/index.js +59 -8
- package/build/composite/legacy/index.js.map +1 -1
- package/build/composite/row.js +1 -1
- package/build/composite/row.js.map +1 -1
- package/build/composite/typeahead.js +1 -1
- package/build/composite/typeahead.js.map +1 -1
- package/build/composite/types.js.map +1 -1
- package/build/date-time/date/index.js +1 -1
- package/build/date-time/date/index.js.map +1 -1
- package/build/date-time/date/styles.js +35 -24
- package/build/date-time/date/styles.js.map +1 -1
- package/build/date-time/date/use-lilius/index.js +163 -0
- package/build/date-time/date/use-lilius/index.js.map +1 -0
- package/build/index.js +7 -0
- package/build/index.js.map +1 -1
- package/build/modal/index.js +11 -4
- package/build/modal/index.js.map +1 -1
- package/build/navigator/navigator-screen/component.js +5 -0
- package/build/navigator/navigator-screen/component.js.map +1 -1
- package/build/private-apis.js +0 -9
- package/build/private-apis.js.map +1 -1
- package/build/slot-fill/index.js +1 -0
- package/build/slot-fill/index.js.map +1 -1
- package/build/tabs/styles.js +3 -3
- package/build/tabs/styles.js.map +1 -1
- package/build/tabs/tablist.js +5 -4
- package/build/tabs/tablist.js.map +1 -1
- package/build/utils/element-rect.js +73 -105
- package/build/utils/element-rect.js.map +1 -1
- package/build-module/composite/context.js +1 -1
- package/build-module/composite/context.js.map +1 -1
- package/build-module/composite/group-label.js +1 -1
- package/build-module/composite/group-label.js.map +1 -1
- package/build-module/composite/group.js +1 -1
- package/build-module/composite/group.js.map +1 -1
- package/build-module/composite/hover.js +1 -1
- package/build-module/composite/hover.js.map +1 -1
- package/build-module/composite/index.js +17 -26
- package/build-module/composite/index.js.map +1 -1
- package/build-module/composite/item.js +1 -1
- package/build-module/composite/item.js.map +1 -1
- package/build-module/composite/legacy/index.js +56 -8
- package/build-module/composite/legacy/index.js.map +1 -1
- package/build-module/composite/row.js +1 -1
- package/build-module/composite/row.js.map +1 -1
- package/build-module/composite/typeahead.js +1 -1
- package/build-module/composite/typeahead.js.map +1 -1
- package/build-module/composite/types.js.map +1 -1
- package/build-module/date-time/date/index.js +1 -2
- package/build-module/date-time/date/index.js.map +1 -1
- package/build-module/date-time/date/styles.js +31 -24
- package/build-module/date-time/date/styles.js.map +1 -1
- package/build-module/date-time/date/use-lilius/index.js +158 -0
- package/build-module/date-time/date/use-lilius/index.js.map +1 -0
- package/build-module/index.js +1 -0
- package/build-module/index.js.map +1 -1
- package/build-module/modal/index.js +12 -4
- package/build-module/modal/index.js.map +1 -1
- package/build-module/navigator/navigator-screen/component.js +4 -0
- package/build-module/navigator/navigator-screen/component.js.map +1 -1
- package/build-module/private-apis.js +0 -9
- package/build-module/private-apis.js.map +1 -1
- package/build-module/slot-fill/index.js +1 -0
- package/build-module/slot-fill/index.js.map +1 -1
- package/build-module/tabs/styles.js +3 -3
- package/build-module/tabs/styles.js.map +1 -1
- package/build-module/tabs/tablist.js +5 -4
- package/build-module/tabs/tablist.js.map +1 -1
- package/build-module/utils/element-rect.js +74 -105
- package/build-module/utils/element-rect.js.map +1 -1
- package/build-style/style-rtl.css +0 -4
- package/build-style/style.css +0 -4
- package/build-types/composite/context.d.ts.map +1 -1
- package/build-types/composite/index.d.ts +36 -24
- package/build-types/composite/index.d.ts.map +1 -1
- package/build-types/composite/legacy/index.d.ts +25 -2
- package/build-types/composite/legacy/index.d.ts.map +1 -1
- package/build-types/composite/legacy/stories/index.story.d.ts.map +1 -1
- package/build-types/composite/stories/index.story.d.ts +9 -9
- package/build-types/composite/stories/index.story.d.ts.map +1 -1
- package/build-types/composite/types.d.ts +11 -10
- package/build-types/composite/types.d.ts.map +1 -1
- package/build-types/date-time/date/index.d.ts +0 -3
- package/build-types/date-time/date/index.d.ts.map +1 -1
- package/build-types/date-time/date/styles.d.ts.map +1 -1
- package/build-types/date-time/date/test/use-lilius.d.ts +2 -0
- package/build-types/date-time/date/test/use-lilius.d.ts.map +1 -0
- package/build-types/date-time/date/use-lilius/index.d.ts +169 -0
- package/build-types/date-time/date/use-lilius/index.d.ts.map +1 -0
- package/build-types/index.d.ts +1 -0
- package/build-types/index.d.ts.map +1 -1
- package/build-types/modal/index.d.ts.map +1 -1
- package/build-types/modal/stories/index.story.d.ts +3 -0
- package/build-types/modal/stories/index.story.d.ts.map +1 -1
- package/build-types/navigator/navigator-screen/component.d.ts.map +1 -1
- package/build-types/private-apis.d.ts.map +1 -1
- package/build-types/slot-fill/index.d.ts +3 -0
- package/build-types/slot-fill/index.d.ts.map +1 -1
- package/build-types/tabs/styles.d.ts.map +1 -1
- package/build-types/tabs/tablist.d.ts.map +1 -1
- package/build-types/utils/element-rect.d.ts +32 -74
- package/build-types/utils/element-rect.d.ts.map +1 -1
- package/package.json +19 -20
- package/src/composite/README.md +5 -24
- package/src/composite/{context.ts → context.tsx} +1 -2
- package/src/composite/group-label.tsx +1 -1
- package/src/composite/group.tsx +1 -1
- package/src/composite/hover.tsx +1 -1
- package/src/composite/index.tsx +17 -28
- package/src/composite/item.tsx +1 -1
- package/src/composite/legacy/index.tsx +72 -11
- package/src/composite/legacy/stories/index.story.tsx +2 -1
- package/src/composite/legacy/test/index.tsx +57 -1
- package/src/composite/row.tsx +1 -1
- package/src/composite/stories/index.story.tsx +185 -169
- package/src/composite/typeahead.tsx +1 -1
- package/src/composite/types.ts +13 -15
- package/src/date-time/date/index.tsx +1 -1
- package/src/date-time/date/styles.ts +31 -11
- package/src/date-time/date/test/use-lilius.ts +417 -0
- package/src/date-time/date/use-lilius/index.ts +394 -0
- package/src/index.ts +1 -0
- package/src/modal/index.tsx +16 -7
- package/src/modal/stories/index.story.tsx +8 -14
- package/src/modal/style.scss +0 -5
- package/src/navigator/navigator-screen/component.tsx +7 -0
- package/src/navigator/test/index.tsx +8 -0
- package/src/private-apis.ts +0 -9
- package/src/select-control/README.md +2 -2
- package/src/slot-fill/index.tsx +1 -0
- package/src/tabs/styles.ts +40 -11
- package/src/tabs/tablist.tsx +5 -4
- package/src/utils/element-rect.ts +93 -130
- package/tsconfig.tsbuildinfo +1 -1
- package/build/composite/store.js +0 -54
- package/build/composite/store.js.map +0 -1
- package/build-module/composite/store.js +0 -46
- package/build-module/composite/store.js.map +0 -1
- package/build-types/composite/store.d.ts +0 -25
- package/build-types/composite/store.d.ts.map +0 -1
- package/build-types/composite/stories/utils.d.ts +0 -29
- package/build-types/composite/stories/utils.d.ts.map +0 -1
- package/src/composite/store.ts +0 -46
- package/src/composite/stories/utils.tsx +0 -76
|
@@ -2,134 +2,37 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* WordPress dependencies
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { useLayoutEffect, useRef, useState } from '@wordpress/element';
|
|
6
|
+
import { useResizeObserver } from '@wordpress/compose';
|
|
6
7
|
/**
|
|
7
8
|
* Internal dependencies
|
|
8
9
|
*/
|
|
9
10
|
import { useEvent } from './hooks/use-event';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
+
* The position and dimensions of an element, relative to its offset parent.
|
|
13
14
|
*/
|
|
14
|
-
export type
|
|
15
|
+
export type ElementOffsetRect = {
|
|
15
16
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* @default true
|
|
17
|
+
* The distance from the top edge of the offset parent to the top edge of
|
|
18
|
+
* the element.
|
|
20
19
|
*/
|
|
21
|
-
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Tracks an element's "rect" (size and position) and fires `onRect` for all
|
|
26
|
-
* of its discrete values. The element can be changed dynamically and **it
|
|
27
|
-
* must not be stored in a ref**. Instead, it should be stored in a React
|
|
28
|
-
* state or equivalent.
|
|
29
|
-
*
|
|
30
|
-
* By default, `onRect` is called initially for the target element (including
|
|
31
|
-
* when the target element changes), not only on size or position updates.
|
|
32
|
-
* This allows consumers of the hook to always be in sync with all rect values
|
|
33
|
-
* of the target element throughout its lifetime. This behavior can be
|
|
34
|
-
* disabled by setting the `fireOnElementInit` option to `false`.
|
|
35
|
-
*
|
|
36
|
-
* Under the hood, it sets up a `ResizeObserver` that tracks the element. The
|
|
37
|
-
* target element can be changed dynamically, and the observer will be
|
|
38
|
-
* updated accordingly.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
*
|
|
42
|
-
* ```tsx
|
|
43
|
-
* const [ targetElement, setTargetElement ] = useState< HTMLElement | null >();
|
|
44
|
-
*
|
|
45
|
-
* useTrackElementRectUpdates( targetElement, ( element ) => {
|
|
46
|
-
* console.log( 'Element resized:', element );
|
|
47
|
-
* } );
|
|
48
|
-
*
|
|
49
|
-
* <div ref={ setTargetElement } />;
|
|
50
|
-
* ```
|
|
51
|
-
*/
|
|
52
|
-
export function useTrackElementRectUpdates(
|
|
20
|
+
top: number;
|
|
53
21
|
/**
|
|
54
|
-
* The
|
|
22
|
+
* The distance from the right edge of the offset parent to the right edge
|
|
23
|
+
* of the element.
|
|
55
24
|
*/
|
|
56
|
-
|
|
25
|
+
right: number;
|
|
57
26
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* set to `false`.
|
|
27
|
+
* The distance from the bottom edge of the offset parent to the bottom edge
|
|
28
|
+
* of the element.
|
|
61
29
|
*/
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* The element being tracked at the time of this update.
|
|
65
|
-
*/
|
|
66
|
-
element: HTMLElement,
|
|
67
|
-
/**
|
|
68
|
-
* The list of
|
|
69
|
-
* [`ResizeObserverEntry`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry)
|
|
70
|
-
* objects passed to the `ResizeObserver.observe` callback. This list
|
|
71
|
-
* won't be available when the observer is set up, and only on updates.
|
|
72
|
-
*/
|
|
73
|
-
resizeObserverEntries?: ResizeObserverEntry[]
|
|
74
|
-
) => void,
|
|
75
|
-
{ fireOnElementInit = true }: UseTrackElementRectUpdatesOptions = {}
|
|
76
|
-
) {
|
|
77
|
-
const onRectEvent = useEvent( onRect );
|
|
78
|
-
|
|
79
|
-
const observedElementRef = useRef< HTMLElement | null >();
|
|
80
|
-
const resizeObserverRef = useRef< ResizeObserver >();
|
|
81
|
-
|
|
82
|
-
// TODO: could this be a layout effect?
|
|
83
|
-
useEffect( () => {
|
|
84
|
-
if ( targetElement === observedElementRef.current ) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
observedElementRef.current = targetElement;
|
|
89
|
-
|
|
90
|
-
// Set up a ResizeObserver.
|
|
91
|
-
if ( ! resizeObserverRef.current ) {
|
|
92
|
-
resizeObserverRef.current = new ResizeObserver( ( entries ) => {
|
|
93
|
-
if ( observedElementRef.current ) {
|
|
94
|
-
onRectEvent( observedElementRef.current, entries );
|
|
95
|
-
}
|
|
96
|
-
} );
|
|
97
|
-
}
|
|
98
|
-
const { current: resizeObserver } = resizeObserverRef;
|
|
99
|
-
|
|
100
|
-
// Observe new element.
|
|
101
|
-
if ( targetElement ) {
|
|
102
|
-
if ( fireOnElementInit ) {
|
|
103
|
-
// TODO: investigate if this can be removed,
|
|
104
|
-
// see: https://stackoverflow.com/a/60026394
|
|
105
|
-
onRectEvent( targetElement );
|
|
106
|
-
}
|
|
107
|
-
resizeObserver.observe( targetElement );
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return () => {
|
|
111
|
-
// Unobserve previous element.
|
|
112
|
-
if ( observedElementRef.current ) {
|
|
113
|
-
resizeObserver.unobserve( observedElementRef.current );
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
}, [ fireOnElementInit, onRectEvent, targetElement ] );
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* The position and dimensions of an element, relative to its offset parent.
|
|
121
|
-
*/
|
|
122
|
-
export type ElementOffsetRect = {
|
|
30
|
+
bottom: number;
|
|
123
31
|
/**
|
|
124
32
|
* The distance from the left edge of the offset parent to the left edge of
|
|
125
33
|
* the element.
|
|
126
34
|
*/
|
|
127
35
|
left: number;
|
|
128
|
-
/**
|
|
129
|
-
* The distance from the top edge of the offset parent to the top edge of
|
|
130
|
-
* the element.
|
|
131
|
-
*/
|
|
132
|
-
top: number;
|
|
133
36
|
/**
|
|
134
37
|
* The width of the element.
|
|
135
38
|
*/
|
|
@@ -144,51 +47,111 @@ export type ElementOffsetRect = {
|
|
|
144
47
|
* An `ElementOffsetRect` object with all values set to zero.
|
|
145
48
|
*/
|
|
146
49
|
export const NULL_ELEMENT_OFFSET_RECT = {
|
|
147
|
-
left: 0,
|
|
148
50
|
top: 0,
|
|
51
|
+
right: 0,
|
|
52
|
+
bottom: 0,
|
|
53
|
+
left: 0,
|
|
149
54
|
width: 0,
|
|
150
55
|
height: 0,
|
|
151
56
|
} satisfies ElementOffsetRect;
|
|
152
57
|
|
|
153
58
|
/**
|
|
154
59
|
* Returns the position and dimensions of an element, relative to its offset
|
|
155
|
-
* parent
|
|
156
|
-
*
|
|
60
|
+
* parent, with subpixel precision. Values reflect the real measures before any
|
|
61
|
+
* potential scaling distortions along the X and Y axes.
|
|
157
62
|
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
63
|
+
* Useful in contexts where plain `getBoundingClientRect` calls or `ResizeObserver`
|
|
64
|
+
* entries are not suitable, such as when the element is transformed, and when
|
|
65
|
+
* `element.offset<Top|Left|Width|Height>` methods are not precise enough.
|
|
66
|
+
*
|
|
67
|
+
* **Note:** in some contexts, like when the scale is 0, this method will fail
|
|
68
|
+
* because it's impossible to calculate a scaling ratio. When that happens, it
|
|
69
|
+
* will return `undefined`.
|
|
162
70
|
*/
|
|
163
71
|
export function getElementOffsetRect(
|
|
164
72
|
element: HTMLElement
|
|
165
|
-
): ElementOffsetRect {
|
|
73
|
+
): ElementOffsetRect | undefined {
|
|
74
|
+
// Position and dimension values computed with `getBoundingClientRect` have
|
|
75
|
+
// subpixel precision, but are affected by distortions since they represent
|
|
76
|
+
// the "real" measures, or in other words, the actual final values as rendered
|
|
77
|
+
// by the browser.
|
|
78
|
+
const rect = element.getBoundingClientRect();
|
|
79
|
+
if ( rect.width === 0 || rect.height === 0 ) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const offsetParentRect =
|
|
83
|
+
element.offsetParent?.getBoundingClientRect() ??
|
|
84
|
+
NULL_ELEMENT_OFFSET_RECT;
|
|
85
|
+
|
|
86
|
+
// Computed widths and heights have subpixel precision, and are not affected
|
|
87
|
+
// by distortions.
|
|
88
|
+
const computedWidth = parseFloat( getComputedStyle( element ).width );
|
|
89
|
+
const computedHeight = parseFloat( getComputedStyle( element ).height );
|
|
90
|
+
|
|
91
|
+
// We can obtain the current scale factor for the element by comparing "computed"
|
|
92
|
+
// dimensions with the "real" ones.
|
|
93
|
+
const scaleX = computedWidth / rect.width;
|
|
94
|
+
const scaleY = computedHeight / rect.height;
|
|
95
|
+
|
|
166
96
|
return {
|
|
167
|
-
//
|
|
168
|
-
//
|
|
169
|
-
//
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
//
|
|
175
|
-
width:
|
|
176
|
-
height:
|
|
97
|
+
// To obtain the adjusted values for the position:
|
|
98
|
+
// 1. Compute the element's position relative to the offset parent.
|
|
99
|
+
// 2. Correct for the scale factor.
|
|
100
|
+
top: ( rect.top - offsetParentRect?.top ) * scaleY,
|
|
101
|
+
right: ( offsetParentRect?.right - rect.right ) * scaleX,
|
|
102
|
+
bottom: ( offsetParentRect?.bottom - rect.bottom ) * scaleY,
|
|
103
|
+
left: ( rect.left - offsetParentRect?.left ) * scaleX,
|
|
104
|
+
// Computed dimensions don't need any adjustments.
|
|
105
|
+
width: computedWidth,
|
|
106
|
+
height: computedHeight,
|
|
177
107
|
};
|
|
178
108
|
}
|
|
179
109
|
|
|
110
|
+
const POLL_RATE = 100;
|
|
111
|
+
|
|
180
112
|
/**
|
|
181
113
|
* Tracks the position and dimensions of an element, relative to its offset
|
|
182
114
|
* parent. The element can be changed dynamically.
|
|
115
|
+
*
|
|
116
|
+
* **Note:** sometimes, the measurement will fail (see `getElementOffsetRect`'s
|
|
117
|
+
* documentation for more details). When that happens, this hook will attempt
|
|
118
|
+
* to measure again after a frame, and if that fails, it will poll every 100
|
|
119
|
+
* milliseconds until it succeeds.
|
|
183
120
|
*/
|
|
184
121
|
export function useTrackElementOffsetRect(
|
|
185
122
|
targetElement: HTMLElement | undefined | null
|
|
186
123
|
) {
|
|
187
124
|
const [ indicatorPosition, setIndicatorPosition ] =
|
|
188
125
|
useState< ElementOffsetRect >( NULL_ELEMENT_OFFSET_RECT );
|
|
126
|
+
const intervalRef = useRef< ReturnType< typeof setInterval > >();
|
|
127
|
+
|
|
128
|
+
const measure = useEvent( () => {
|
|
129
|
+
if ( targetElement ) {
|
|
130
|
+
const elementOffsetRect = getElementOffsetRect( targetElement );
|
|
131
|
+
if ( elementOffsetRect ) {
|
|
132
|
+
setIndicatorPosition( elementOffsetRect );
|
|
133
|
+
clearInterval( intervalRef.current );
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
} else {
|
|
137
|
+
clearInterval( intervalRef.current );
|
|
138
|
+
}
|
|
139
|
+
return false;
|
|
140
|
+
} );
|
|
141
|
+
|
|
142
|
+
const setElement = useResizeObserver( () => {
|
|
143
|
+
if ( ! measure() ) {
|
|
144
|
+
requestAnimationFrame( () => {
|
|
145
|
+
if ( ! measure() ) {
|
|
146
|
+
intervalRef.current = setInterval( measure, POLL_RATE );
|
|
147
|
+
}
|
|
148
|
+
} );
|
|
149
|
+
}
|
|
150
|
+
} );
|
|
189
151
|
|
|
190
|
-
|
|
191
|
-
|
|
152
|
+
useLayoutEffect(
|
|
153
|
+
() => setElement( targetElement ),
|
|
154
|
+
[ setElement, targetElement ]
|
|
192
155
|
);
|
|
193
156
|
|
|
194
157
|
return indicatorPosition;
|