@automattic/jetpack-components 0.71.0 → 0.72.1

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/build/components/action-button/index.d.ts +10 -10
  3. package/build/components/action-button/index.js +1 -1
  4. package/build/components/action-popover/types.d.ts +0 -1
  5. package/build/components/admin-page/types.d.ts +0 -1
  6. package/build/components/admin-section/types.d.ts +0 -1
  7. package/build/components/boost-score-graph/uplot-line-chart.js +2 -2
  8. package/build/components/dot-pager/index.d.ts +14 -0
  9. package/build/components/dot-pager/index.js +52 -0
  10. package/build/components/icon-tooltip/index.js +1 -1
  11. package/build/components/icon-tooltip/types.d.ts +0 -1
  12. package/build/components/layout/types.d.ts +0 -1
  13. package/build/components/number-control/index.js +1 -1
  14. package/build/components/popover/index.d.ts +0 -1
  15. package/build/components/pricing-table/types.d.ts +0 -1
  16. package/build/components/product-offer/types.d.ts +0 -1
  17. package/build/components/product-price/types.d.ts +0 -1
  18. package/build/components/radio-control/index.d.ts +0 -1
  19. package/build/components/spinner/index.d.ts +3 -3
  20. package/build/components/spinner/index.js +1 -1
  21. package/build/components/split-button/types.d.ts +0 -1
  22. package/build/components/stat-card/types.d.ts +0 -1
  23. package/build/components/status/index.d.ts +0 -1
  24. package/build/components/swipeable/index.d.ts +12 -0
  25. package/build/components/swipeable/index.js +293 -0
  26. package/build/components/terms-of-service/index.d.ts +0 -1
  27. package/build/components/theme-provider/types.d.ts +0 -1
  28. package/build/components/toggle-control/index.d.ts +0 -1
  29. package/build/index.d.ts +1 -0
  30. package/build/index.js +1 -0
  31. package/components/action-button/index.jsx +1 -1
  32. package/components/dot-pager/README.md +20 -0
  33. package/components/dot-pager/index.tsx +147 -0
  34. package/components/dot-pager/style.scss +80 -0
  35. package/components/number-control/index.jsx +3 -1
  36. package/components/swipeable/README.md +34 -0
  37. package/components/swipeable/index.tsx +425 -0
  38. package/components/swipeable/style.scss +34 -0
  39. package/index.ts +1 -0
  40. package/package.json +4 -4
@@ -0,0 +1,20 @@
1
+ # Dot pager
2
+
3
+ `DotPager` wraps all its child components into a browsable container that shows only one child at time.
4
+
5
+ ## Usage
6
+
7
+ ```js
8
+ import { DotPager } from '@automattic/jetpack-components';
9
+
10
+
11
+ function myDotPager() {
12
+ return (
13
+ <DotPager>
14
+ <div>Item 1</div>
15
+ <div>Item 2</div>
16
+ <div>Item 3</div>
17
+ </DotPager>
18
+ );
19
+ }
20
+ ```
@@ -0,0 +1,147 @@
1
+ import { Button } from '@wordpress/components';
2
+ import { __, sprintf } from '@wordpress/i18n';
3
+ import clsx from 'clsx';
4
+ import React, { Children, useState, useEffect, ReactNode, useCallback, useMemo } from 'react';
5
+ import { Swipeable } from '../swipeable/index.js';
6
+
7
+ import './style.scss';
8
+
9
+ type ControlsProps = {
10
+ currentPage: number;
11
+ numberOfPages: number;
12
+ setCurrentPage: ( page: number ) => void;
13
+ tracksPrefix: string;
14
+ tracksFn: ( eventName: string, data?: Record< string, unknown > ) => void;
15
+ };
16
+
17
+ const Controls = ( {
18
+ currentPage,
19
+ numberOfPages,
20
+ setCurrentPage,
21
+ tracksPrefix,
22
+ tracksFn,
23
+ }: ControlsProps ) => {
24
+ // Create a map of memoized handlers for each page
25
+ const pageHandlers = useMemo(
26
+ () =>
27
+ Array.from( { length: numberOfPages }, ( _, page ) => () => {
28
+ tracksFn( tracksPrefix + '_dot_click', {
29
+ current_page: currentPage,
30
+ destination_page: page,
31
+ } );
32
+ setCurrentPage( page );
33
+ } ),
34
+ [ numberOfPages, currentPage, tracksFn, tracksPrefix, setCurrentPage ]
35
+ );
36
+
37
+ if ( numberOfPages < 2 ) {
38
+ return null;
39
+ }
40
+
41
+ return (
42
+ <ul className="dot-pager__controls" aria-label={ __( 'Pager controls', 'jetpack-components' ) }>
43
+ { Array.from( { length: numberOfPages }, ( _, page ) => (
44
+ <li key={ `page-${ page }` } aria-current={ page === currentPage ? 'page' : undefined }>
45
+ <Button
46
+ key={ page.toString() }
47
+ className={ clsx( 'dot-pager__control-choose-page', {
48
+ 'dot-pager__control-current': page === currentPage,
49
+ } ) }
50
+ disabled={ page === currentPage }
51
+ aria-label={ sprintf(
52
+ /* translators: %1$d: current page number, %2$d: total number of pages */
53
+ __( 'Page %1$d of %2$d', 'jetpack-components' ),
54
+ page + 1,
55
+ numberOfPages
56
+ ) }
57
+ onClick={ pageHandlers[ page ] }
58
+ />
59
+ </li>
60
+ ) ) }
61
+ </ul>
62
+ );
63
+ };
64
+
65
+ type DotPagerProps = {
66
+ hasDynamicHeight?: boolean;
67
+ children: ReactNode;
68
+ className?: string;
69
+ onPageSelected?: ( index: number ) => void;
70
+ isClickEnabled?: boolean;
71
+ rotateTime?: number;
72
+ tracksPrefix?: string;
73
+ tracksFn?: ( eventName: string, data?: Record< string, unknown > ) => void;
74
+ };
75
+
76
+ const DotPager = ( {
77
+ hasDynamicHeight = false,
78
+ children,
79
+ className = '',
80
+ onPageSelected,
81
+ isClickEnabled = false,
82
+ rotateTime = 0,
83
+ tracksPrefix = '',
84
+ tracksFn = () => {},
85
+ ...props
86
+ }: DotPagerProps ) => {
87
+ const normalizedChildren = Children.toArray( children ).filter( Boolean );
88
+ const [ currentPage, setCurrentPage ] = useState( 0 );
89
+ const [ isPaused, setIsPaused ] = useState( false );
90
+ const numPages = Children.count( normalizedChildren );
91
+
92
+ useEffect( () => {
93
+ if ( rotateTime > 0 && numPages > 1 && ! isPaused ) {
94
+ const timerId = setTimeout( () => {
95
+ // Add 1 to numPages to account for the clones
96
+ setCurrentPage( ( currentPage + 1 ) % ( numPages + 1 ) );
97
+ }, rotateTime * 1000 );
98
+
99
+ return () => clearTimeout( timerId );
100
+ }
101
+ }, [ currentPage, numPages, rotateTime, isPaused ] );
102
+
103
+ const handleSelectPage = useCallback(
104
+ ( index: number ) => {
105
+ setCurrentPage( index );
106
+ onPageSelected?.( index );
107
+ },
108
+ [ onPageSelected ]
109
+ );
110
+
111
+ const handleMouseEnter = useCallback( () => {
112
+ setIsPaused( true );
113
+ }, [] );
114
+
115
+ const handleMouseLeave = useCallback( () => {
116
+ setIsPaused( false );
117
+ }, [] );
118
+
119
+ return (
120
+ <div
121
+ className={ clsx( 'dot-pager', className ) }
122
+ onMouseEnter={ handleMouseEnter }
123
+ onMouseLeave={ handleMouseLeave }
124
+ { ...props }
125
+ >
126
+ <Controls
127
+ currentPage={ currentPage }
128
+ numberOfPages={ numPages }
129
+ setCurrentPage={ handleSelectPage }
130
+ tracksPrefix={ tracksPrefix }
131
+ tracksFn={ tracksFn }
132
+ />
133
+ <Swipeable
134
+ hasDynamicHeight={ hasDynamicHeight }
135
+ onPageSelect={ handleSelectPage }
136
+ currentPage={ currentPage }
137
+ pageClassName="dot-pager__page"
138
+ containerClassName="dot-pager__pages"
139
+ isClickEnabled={ isClickEnabled }
140
+ >
141
+ { normalizedChildren }
142
+ </Swipeable>
143
+ </div>
144
+ );
145
+ };
146
+
147
+ export default DotPager;
@@ -0,0 +1,80 @@
1
+ @import '@automattic/jetpack-base-styles/gutenberg-base-styles';
2
+ @import '@automattic/jetpack-base-styles/root-variables';
3
+
4
+ .dot-pager {
5
+ width: 100%;
6
+ height: 100%;
7
+ position: relative;
8
+ }
9
+
10
+ .dot-pager__page {
11
+ height: 100%;
12
+ transition: opacity 0.5s ease-in-out, visibility 0.5s ease-in-out;
13
+ @include reduce-motion( "transition" );
14
+ opacity: 1;
15
+ visibility: visible;
16
+ }
17
+
18
+ .dot-pager__controls {
19
+ margin: 0;
20
+ margin-bottom: 16px;
21
+ margin-top: auto;
22
+ display: flex;
23
+ justify-content: center;
24
+ position: absolute;
25
+ bottom: 0px;
26
+ left: 0;
27
+ right: 0;
28
+ z-index: 1;
29
+ li {
30
+ display: inline-flex;
31
+ margin: 0 4px;
32
+ height: 18px;
33
+ align-items: center;
34
+
35
+ &:first-child {
36
+ margin-left: 0;
37
+ }
38
+ &:last-child {
39
+ margin-right: 0;
40
+ }
41
+ }
42
+
43
+ .dot-pager__control-gap {
44
+ margin-left: auto;
45
+ }
46
+ }
47
+
48
+ .dot-pager__control-choose-page {
49
+ cursor: pointer;
50
+
51
+ &:disabled {
52
+ cursor: default;
53
+ }
54
+
55
+ &:focus-visible {
56
+ box-shadow: 0 0 0 2px var(--jp-gray-90);
57
+ }
58
+ }
59
+
60
+ .dot-pager__control-choose-page {
61
+ border-radius: 50%;
62
+ width: 6px;
63
+ height: 6px;
64
+ padding: 0px;
65
+ background-color: var(--jp-white-off);
66
+
67
+ &:hover {
68
+ background-color: var(--jp-gray-20);
69
+ }
70
+
71
+ &.dot-pager__control-current {
72
+ background-color: var(--jp-gray-80);
73
+ }
74
+ }
75
+
76
+ .dot-pager {
77
+ &__button {
78
+ margin-right: 10px;
79
+ }
80
+ }
@@ -14,7 +14,9 @@ import {
14
14
  const NumberControl =
15
15
  ExperimentalNumberControl ||
16
16
  function CustomNumberControl( props ) {
17
- return <TextControl type="number" inputMode="numeric" { ...props } />;
17
+ return (
18
+ <TextControl type="number" inputMode="numeric" { ...props } __next40pxDefaultSize={ true } />
19
+ );
18
20
  };
19
21
 
20
22
  export default NumberControl;
@@ -0,0 +1,34 @@
1
+ # Swipeable
2
+
3
+ This component is used to add horizontal swipe controls to a list of elements (pages).
4
+
5
+ ## Example Usage
6
+
7
+ ```js
8
+ import { Swipeable } from '@automattic/jetpack-components';
9
+
10
+ function Pager() {
11
+ const [ currentPage, setCurrentPage ] = useState( 0 );
12
+ return (
13
+ <Swipeable
14
+ onPageSelect={ ( index ) => {
15
+ setCurrentPage( index );
16
+ } }
17
+ currentPage={ currentPage }
18
+ pageClassName="example-page-component-class"
19
+ >
20
+ <div>Page 1</div>
21
+ <div>Page 2</div>
22
+ <div>Page 3</div>
23
+ </Swipeable>
24
+ );
25
+ }
26
+ ```
27
+
28
+ ## Props
29
+
30
+ - `onPageSelect` - (function) Function that runs when the page is selected on using a swipe. Useful for updating the current page.
31
+ - `currentPage` - (number) Index of the currently selected/shown page.
32
+ - `hasDynamicHeight` - (bool) Whether height should be changed dynamically.
33
+ - `pageClassName` - _optional_ (string) Optional class attribute of the page component.
34
+ - `containerClassName` - _optional_ (string) Optional class attribute of the page container component.