@wordpress/nux 9.47.0 → 10.0.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 +6 -0
- package/README.md +2 -103
- package/build/components/dot-tip/index.cjs +3 -90
- package/build/components/dot-tip/index.cjs.map +3 -3
- package/build/store/actions.cjs.map +2 -2
- package/build/store/reducer.cjs +8 -38
- package/build/store/reducer.cjs.map +2 -2
- package/build/store/selectors.cjs +7 -32
- package/build/store/selectors.cjs.map +2 -2
- package/build-module/components/dot-tip/index.mjs +3 -90
- package/build-module/components/dot-tip/index.mjs.map +2 -2
- package/build-module/store/actions.mjs.map +2 -2
- package/build-module/store/reducer.mjs +8 -32
- package/build-module/store/reducer.mjs.map +2 -2
- package/build-module/store/selectors.mjs +7 -32
- package/build-module/store/selectors.mjs.map +2 -2
- package/build-style/style-rtl.css +3 -185
- package/build-style/style.css +3 -189
- package/package.json +12 -14
- package/src/components/dot-tip/README.md +2 -34
- package/src/components/dot-tip/index.js +6 -94
- package/src/components/dot-tip/test/index.js +10 -67
- package/src/store/actions.js +10 -9
- package/src/store/reducer.js +13 -61
- package/src/store/selectors.js +11 -57
- package/src/store/test/reducer.js +20 -60
- package/src/store/test/selectors.js +6 -131
- package/src/style.scss +4 -1
- package/src/components/dot-tip/style.scss +0 -131
- package/src/components/dot-tip/test/__snapshots__/index.js.snap +0 -48
|
@@ -1,77 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*/
|
|
4
|
-
import { render, screen, waitFor } from '@testing-library/react';
|
|
5
|
-
import userEvent from '@testing-library/user-event';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Internal dependencies
|
|
9
|
-
*/
|
|
10
|
-
import { DotTip } from '..';
|
|
1
|
+
import { render } from '@testing-library/react';
|
|
2
|
+
import DotTip, { DotTip as NamedDotTip } from '..';
|
|
11
3
|
|
|
12
4
|
describe( 'DotTip', () => {
|
|
13
|
-
it( '
|
|
14
|
-
render(
|
|
15
|
-
<DotTip>
|
|
16
|
-
It looks like you’re writing a letter. Would you like help?
|
|
17
|
-
</DotTip>
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
expect( screen.queryByRole( 'dialog' ) ).not.toBeInTheDocument();
|
|
21
|
-
} );
|
|
22
|
-
|
|
23
|
-
it( 'should render correctly', async () => {
|
|
24
|
-
render(
|
|
25
|
-
<DotTip isVisible>
|
|
26
|
-
It looks like you’re writing a letter. Would you like help?
|
|
27
|
-
</DotTip>
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
// Wait for the dialog element to be positioned (aligned with the button)
|
|
31
|
-
await waitFor( () =>
|
|
32
|
-
expect( screen.getByRole( 'dialog' ) ).toBePositionedPopover()
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
expect( screen.getByRole( 'dialog' ) ).toMatchSnapshot();
|
|
36
|
-
} );
|
|
37
|
-
|
|
38
|
-
it( 'should call onDismiss when the dismiss button is clicked', async () => {
|
|
39
|
-
const user = userEvent.setup();
|
|
40
|
-
const onDismiss = jest.fn();
|
|
41
|
-
|
|
42
|
-
render(
|
|
43
|
-
<DotTip isVisible onDismiss={ onDismiss }>
|
|
44
|
-
It looks like you’re writing a letter. Would you like help?
|
|
45
|
-
</DotTip>
|
|
5
|
+
it( 'renders nothing when accessed through the default export', () => {
|
|
6
|
+
const { container } = render(
|
|
7
|
+
<DotTip tipId="test/tip">Tip content</DotTip>
|
|
46
8
|
);
|
|
47
9
|
|
|
48
|
-
|
|
49
|
-
expect( screen.getByRole( 'dialog' ) ).toBePositionedPopover()
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
await user.click( screen.getByRole( 'button', { name: 'Got it' } ) );
|
|
53
|
-
|
|
54
|
-
expect( onDismiss ).toHaveBeenCalled();
|
|
10
|
+
expect( container ).toBeEmptyDOMElement();
|
|
55
11
|
} );
|
|
56
12
|
|
|
57
|
-
it( '
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
render(
|
|
62
|
-
<DotTip isVisible onDisable={ onDisable }>
|
|
63
|
-
It looks like you’re writing a letter. Would you like help?
|
|
64
|
-
</DotTip>
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
await waitFor( () =>
|
|
68
|
-
expect( screen.getByRole( 'dialog' ) ).toBePositionedPopover()
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
await user.click(
|
|
72
|
-
screen.getByRole( 'button', { name: 'Disable tips' } )
|
|
13
|
+
it( 'renders nothing when accessed through the named export', () => {
|
|
14
|
+
const { container } = render(
|
|
15
|
+
<NamedDotTip tipId="test/tip">Tip content</NamedDotTip>
|
|
73
16
|
);
|
|
74
17
|
|
|
75
|
-
expect(
|
|
18
|
+
expect( container ).toBeEmptyDOMElement();
|
|
76
19
|
} );
|
|
77
20
|
} );
|
package/src/store/actions.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Returns
|
|
3
|
-
*
|
|
2
|
+
* Returns a no-op action object. This package is deprecated and no longer
|
|
3
|
+
* displays tips, but the action remains for backward compatibility.
|
|
4
4
|
*
|
|
5
|
-
* @param {string[]} tipIds Which tips
|
|
5
|
+
* @param {string[]} tipIds Which tips would have been shown in the guide.
|
|
6
6
|
*
|
|
7
7
|
* @return {Object} Action object.
|
|
8
8
|
*/
|
|
@@ -14,10 +14,10 @@ export function triggerGuide( tipIds ) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* Returns
|
|
18
|
-
*
|
|
17
|
+
* Returns a no-op action object. This package is deprecated and no longer
|
|
18
|
+
* displays tips, but the action remains for backward compatibility.
|
|
19
19
|
*
|
|
20
|
-
* @param {string} id The tip
|
|
20
|
+
* @param {string} id The tip that would have been dismissed.
|
|
21
21
|
*
|
|
22
22
|
* @return {Object} Action object.
|
|
23
23
|
*/
|
|
@@ -29,8 +29,8 @@ export function dismissTip( id ) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* Returns
|
|
33
|
-
*
|
|
32
|
+
* Returns a no-op action object. This package is deprecated and no longer
|
|
33
|
+
* displays tips, but the action remains for backward compatibility.
|
|
34
34
|
*
|
|
35
35
|
* @return {Object} Action object.
|
|
36
36
|
*/
|
|
@@ -41,7 +41,8 @@ export function disableTips() {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
* Returns
|
|
44
|
+
* Returns a no-op action object. This package is deprecated and no longer
|
|
45
|
+
* displays tips, but the action remains for backward compatibility.
|
|
45
46
|
*
|
|
46
47
|
* @return {Object} Action object.
|
|
47
48
|
*/
|
package/src/store/reducer.js
CHANGED
|
@@ -1,70 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Deprecated NUX store state kept only so the core/nux store can still be
|
|
3
|
+
* registered for backward compatibility.
|
|
3
4
|
*/
|
|
4
|
-
|
|
5
|
+
const DEFAULT_STATE = {
|
|
6
|
+
guides: [],
|
|
7
|
+
preferences: {
|
|
8
|
+
areTipsEnabled: false,
|
|
9
|
+
dismissedTips: {},
|
|
10
|
+
},
|
|
11
|
+
};
|
|
5
12
|
|
|
6
13
|
/**
|
|
7
|
-
* Reducer that
|
|
8
|
-
* an array which contains the tip identifiers contained within that guide.
|
|
14
|
+
* Reducer that preserves state without responding to actions.
|
|
9
15
|
*
|
|
10
|
-
* @param {
|
|
11
|
-
* @param {Object} action Dispatched action.
|
|
16
|
+
* @param {Object} state Current state.
|
|
12
17
|
*
|
|
13
|
-
* @return {
|
|
18
|
+
* @return {Object} Current state.
|
|
14
19
|
*/
|
|
15
|
-
export function
|
|
16
|
-
switch ( action.type ) {
|
|
17
|
-
case 'TRIGGER_GUIDE':
|
|
18
|
-
return [ ...state, action.tipIds ];
|
|
19
|
-
}
|
|
20
|
-
|
|
20
|
+
export default function reducer( state = DEFAULT_STATE ) {
|
|
21
21
|
return state;
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Reducer that tracks whether or not tips are globally enabled.
|
|
26
|
-
*
|
|
27
|
-
* @param {boolean} state Current state.
|
|
28
|
-
* @param {Object} action Dispatched action.
|
|
29
|
-
*
|
|
30
|
-
* @return {boolean} Updated state.
|
|
31
|
-
*/
|
|
32
|
-
export function areTipsEnabled( state = true, action ) {
|
|
33
|
-
switch ( action.type ) {
|
|
34
|
-
case 'DISABLE_TIPS':
|
|
35
|
-
return false;
|
|
36
|
-
|
|
37
|
-
case 'ENABLE_TIPS':
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return state;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Reducer that tracks which tips have been dismissed. If the state object
|
|
46
|
-
* contains a tip identifier, then that tip is dismissed.
|
|
47
|
-
*
|
|
48
|
-
* @param {Object} state Current state.
|
|
49
|
-
* @param {Object} action Dispatched action.
|
|
50
|
-
*
|
|
51
|
-
* @return {Object} Updated state.
|
|
52
|
-
*/
|
|
53
|
-
export function dismissedTips( state = {}, action ) {
|
|
54
|
-
switch ( action.type ) {
|
|
55
|
-
case 'DISMISS_TIP':
|
|
56
|
-
return {
|
|
57
|
-
...state,
|
|
58
|
-
[ action.id ]: true,
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
case 'ENABLE_TIPS':
|
|
62
|
-
return {};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return state;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const preferences = combineReducers( { areTipsEnabled, dismissedTips } );
|
|
69
|
-
|
|
70
|
-
export default combineReducers( { guides, preferences } );
|
package/src/store/selectors.js
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WordPress dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { createSelector } from '@wordpress/data';
|
|
5
|
-
|
|
6
1
|
/**
|
|
7
2
|
* An object containing information about a guide.
|
|
8
3
|
*
|
|
@@ -13,69 +8,28 @@ import { createSelector } from '@wordpress/data';
|
|
|
13
8
|
*/
|
|
14
9
|
|
|
15
10
|
/**
|
|
16
|
-
* Returns
|
|
17
|
-
* of.
|
|
11
|
+
* Returns null because the deprecated NUX package no longer displays guides.
|
|
18
12
|
*
|
|
19
|
-
* @
|
|
20
|
-
* @param {string} tipId The tip to query.
|
|
21
|
-
*
|
|
22
|
-
* @return {?NUXGuideInfo} Information about the associated guide.
|
|
13
|
+
* @return {null} No associated guide.
|
|
23
14
|
*/
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if ( tipIds.includes( tipId ) ) {
|
|
28
|
-
const nonDismissedTips = tipIds.filter(
|
|
29
|
-
( tId ) =>
|
|
30
|
-
! Object.keys(
|
|
31
|
-
state.preferences.dismissedTips
|
|
32
|
-
).includes( tId )
|
|
33
|
-
);
|
|
34
|
-
const [ currentTipId = null, nextTipId = null ] =
|
|
35
|
-
nonDismissedTips;
|
|
36
|
-
return { tipIds, currentTipId, nextTipId };
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return null;
|
|
41
|
-
},
|
|
42
|
-
( state ) => [ state.guides, state.preferences.dismissedTips ]
|
|
43
|
-
);
|
|
15
|
+
export function getAssociatedGuide() {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
44
18
|
|
|
45
19
|
/**
|
|
46
|
-
*
|
|
47
|
-
* are disabled, have been dismissed, or are not the current tip in any
|
|
48
|
-
* guide that they have been added to.
|
|
49
|
-
*
|
|
50
|
-
* @param {Object} state Global application state.
|
|
51
|
-
* @param {string} tipId The tip to query.
|
|
20
|
+
* Returns false because the deprecated NUX package no longer displays tips.
|
|
52
21
|
*
|
|
53
22
|
* @return {boolean} Whether or not the given tip is showing.
|
|
54
23
|
*/
|
|
55
|
-
export function isTipVisible(
|
|
56
|
-
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if ( state.preferences.dismissedTips?.hasOwnProperty( tipId ) ) {
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const associatedGuide = getAssociatedGuide( state, tipId );
|
|
65
|
-
if ( associatedGuide && associatedGuide.currentTipId !== tipId ) {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return true;
|
|
24
|
+
export function isTipVisible() {
|
|
25
|
+
return false;
|
|
70
26
|
}
|
|
71
27
|
|
|
72
28
|
/**
|
|
73
|
-
* Returns
|
|
74
|
-
*
|
|
75
|
-
* @param {Object} state Global application state.
|
|
29
|
+
* Returns false because the deprecated NUX package no longer displays tips.
|
|
76
30
|
*
|
|
77
31
|
* @return {boolean} Whether tips are globally enabled.
|
|
78
32
|
*/
|
|
79
|
-
export function areTipsEnabled(
|
|
80
|
-
return
|
|
33
|
+
export function areTipsEnabled() {
|
|
34
|
+
return false;
|
|
81
35
|
}
|
|
@@ -1,69 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
* Internal dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { guides, areTipsEnabled, dismissedTips } from '../reducer';
|
|
1
|
+
import reducer from '../reducer';
|
|
5
2
|
|
|
6
3
|
describe( 'reducer', () => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
type: 'TRIGGER_GUIDE',
|
|
15
|
-
tipIds: [ 'test/tip-1', 'test/tip-2' ],
|
|
16
|
-
} );
|
|
17
|
-
expect( state ).toEqual( [ [ 'test/tip-1', 'test/tip-2' ] ] );
|
|
18
|
-
} );
|
|
19
|
-
} );
|
|
20
|
-
|
|
21
|
-
describe( 'areTipsEnabled', () => {
|
|
22
|
-
it( 'should default to true', () => {
|
|
23
|
-
expect( areTipsEnabled( undefined, {} ) ).toBe( true );
|
|
24
|
-
} );
|
|
25
|
-
|
|
26
|
-
it( 'should flip when tips are disabled', () => {
|
|
27
|
-
const state = areTipsEnabled( true, {
|
|
28
|
-
type: 'DISABLE_TIPS',
|
|
29
|
-
} );
|
|
30
|
-
expect( state ).toBe( false );
|
|
31
|
-
} );
|
|
32
|
-
|
|
33
|
-
it( 'should flip when tips are enabled', () => {
|
|
34
|
-
const state = areTipsEnabled( false, {
|
|
35
|
-
type: 'ENABLE_TIPS',
|
|
36
|
-
} );
|
|
37
|
-
expect( state ).toBe( true );
|
|
4
|
+
it( 'defaults to disabled empty state', () => {
|
|
5
|
+
expect( reducer( undefined, {} ) ).toEqual( {
|
|
6
|
+
guides: [],
|
|
7
|
+
preferences: {
|
|
8
|
+
areTipsEnabled: false,
|
|
9
|
+
dismissedTips: {},
|
|
10
|
+
},
|
|
38
11
|
} );
|
|
39
12
|
} );
|
|
40
13
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
expect( dismissedTips( undefined, {} ) ).toEqual( {} );
|
|
44
|
-
} );
|
|
45
|
-
|
|
46
|
-
it( 'should mark tips as dismissed', () => {
|
|
47
|
-
const state = dismissedTips(
|
|
48
|
-
{},
|
|
49
|
-
{
|
|
50
|
-
type: 'DISMISS_TIP',
|
|
51
|
-
id: 'test/tip',
|
|
52
|
-
}
|
|
53
|
-
);
|
|
54
|
-
expect( state ).toEqual( {
|
|
55
|
-
'test/tip': true,
|
|
56
|
-
} );
|
|
57
|
-
} );
|
|
14
|
+
it( 'ignores legacy actions', () => {
|
|
15
|
+
const state = reducer( undefined, {} );
|
|
58
16
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
'test/tip': true,
|
|
62
|
-
};
|
|
63
|
-
const state = dismissedTips( initialState, {
|
|
17
|
+
expect(
|
|
18
|
+
reducer( state, {
|
|
64
19
|
type: 'ENABLE_TIPS',
|
|
65
|
-
} )
|
|
66
|
-
|
|
67
|
-
|
|
20
|
+
} )
|
|
21
|
+
).toBe( state );
|
|
22
|
+
expect(
|
|
23
|
+
reducer( state, {
|
|
24
|
+
type: 'TRIGGER_GUIDE',
|
|
25
|
+
tipIds: [ 'test/tip' ],
|
|
26
|
+
} )
|
|
27
|
+
).toBe( state );
|
|
68
28
|
} );
|
|
69
29
|
} );
|
|
@@ -1,146 +1,21 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Internal dependencies
|
|
3
|
-
*/
|
|
4
1
|
import { getAssociatedGuide, isTipVisible, areTipsEnabled } from '../selectors';
|
|
5
2
|
|
|
6
3
|
describe( 'selectors', () => {
|
|
7
4
|
describe( 'getAssociatedGuide', () => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
[ 'test/tip-1', 'test/tip-2', 'test/tip-3' ],
|
|
11
|
-
[ 'test/tip-a', 'test/tip-b', 'test/tip-c' ],
|
|
12
|
-
[ 'test/tip-α', 'test/tip-β', 'test/tip-γ' ],
|
|
13
|
-
],
|
|
14
|
-
preferences: {
|
|
15
|
-
dismissedTips: {
|
|
16
|
-
'test/tip-1': true,
|
|
17
|
-
'test/tip-a': true,
|
|
18
|
-
'test/tip-b': true,
|
|
19
|
-
'test/tip-α': true,
|
|
20
|
-
'test/tip-β': true,
|
|
21
|
-
'test/tip-γ': true,
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
it( 'should return null when there is no associated guide', () => {
|
|
27
|
-
expect( getAssociatedGuide( state, 'test/unknown' ) ).toBeNull();
|
|
28
|
-
} );
|
|
29
|
-
|
|
30
|
-
it( 'should return the associated guide', () => {
|
|
31
|
-
expect( getAssociatedGuide( state, 'test/tip-2' ) ).toEqual( {
|
|
32
|
-
tipIds: [ 'test/tip-1', 'test/tip-2', 'test/tip-3' ],
|
|
33
|
-
currentTipId: 'test/tip-2',
|
|
34
|
-
nextTipId: 'test/tip-3',
|
|
35
|
-
} );
|
|
36
|
-
} );
|
|
37
|
-
|
|
38
|
-
it( 'should indicate when there is no next tip', () => {
|
|
39
|
-
expect( getAssociatedGuide( state, 'test/tip-b' ) ).toEqual( {
|
|
40
|
-
tipIds: [ 'test/tip-a', 'test/tip-b', 'test/tip-c' ],
|
|
41
|
-
currentTipId: 'test/tip-c',
|
|
42
|
-
nextTipId: null,
|
|
43
|
-
} );
|
|
44
|
-
} );
|
|
45
|
-
|
|
46
|
-
it( 'should indicate when there is no current or next tip', () => {
|
|
47
|
-
expect( getAssociatedGuide( state, 'test/tip-β' ) ).toEqual( {
|
|
48
|
-
tipIds: [ 'test/tip-α', 'test/tip-β', 'test/tip-γ' ],
|
|
49
|
-
currentTipId: null,
|
|
50
|
-
nextTipId: null,
|
|
51
|
-
} );
|
|
5
|
+
it( 'returns null', () => {
|
|
6
|
+
expect( getAssociatedGuide( {}, 'test/tip' ) ).toBeNull();
|
|
52
7
|
} );
|
|
53
8
|
} );
|
|
54
9
|
|
|
55
10
|
describe( 'isTipVisible', () => {
|
|
56
|
-
it( '
|
|
57
|
-
|
|
58
|
-
const state = {
|
|
59
|
-
guides: [],
|
|
60
|
-
preferences: {},
|
|
61
|
-
};
|
|
62
|
-
expect( isTipVisible( state, 'test/tip' ) ).toBe( false );
|
|
63
|
-
} );
|
|
64
|
-
|
|
65
|
-
it( 'is tolerant to undefined dismissedTips', () => {
|
|
66
|
-
// See: https://github.com/WordPress/gutenberg/issues/14580
|
|
67
|
-
const state = {
|
|
68
|
-
guides: [],
|
|
69
|
-
preferences: {
|
|
70
|
-
areTipsEnabled: true,
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
expect( isTipVisible( state, 'test/tip' ) ).toBe( true );
|
|
74
|
-
} );
|
|
75
|
-
|
|
76
|
-
it( 'should return true by default', () => {
|
|
77
|
-
const state = {
|
|
78
|
-
guides: [],
|
|
79
|
-
preferences: {
|
|
80
|
-
areTipsEnabled: true,
|
|
81
|
-
dismissedTips: {},
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
expect( isTipVisible( state, 'test/tip' ) ).toBe( true );
|
|
85
|
-
} );
|
|
86
|
-
|
|
87
|
-
it( 'should return false if tips are disabled', () => {
|
|
88
|
-
const state = {
|
|
89
|
-
guides: [],
|
|
90
|
-
preferences: {
|
|
91
|
-
areTipsEnabled: false,
|
|
92
|
-
dismissedTips: {},
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
expect( isTipVisible( state, 'test/tip' ) ).toBe( false );
|
|
96
|
-
} );
|
|
97
|
-
|
|
98
|
-
it( 'should return false if the tip is dismissed', () => {
|
|
99
|
-
const state = {
|
|
100
|
-
guides: [],
|
|
101
|
-
preferences: {
|
|
102
|
-
areTipsEnabled: true,
|
|
103
|
-
dismissedTips: {
|
|
104
|
-
'test/tip': true,
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
};
|
|
108
|
-
expect( isTipVisible( state, 'test/tip' ) ).toBe( false );
|
|
109
|
-
} );
|
|
110
|
-
|
|
111
|
-
it( 'should return false if the tip is in a guide and it is not the current tip', () => {
|
|
112
|
-
const state = {
|
|
113
|
-
guides: [ [ 'test/tip-1', 'test/tip-2', 'test/tip-3' ] ],
|
|
114
|
-
preferences: {
|
|
115
|
-
areTipsEnabled: true,
|
|
116
|
-
dismissedTips: {},
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
expect( isTipVisible( state, 'test/tip-2' ) ).toBe( false );
|
|
11
|
+
it( 'returns false', () => {
|
|
12
|
+
expect( isTipVisible( {}, 'test/tip' ) ).toBe( false );
|
|
120
13
|
} );
|
|
121
14
|
} );
|
|
122
15
|
|
|
123
16
|
describe( 'areTipsEnabled', () => {
|
|
124
|
-
it( '
|
|
125
|
-
|
|
126
|
-
guides: [],
|
|
127
|
-
preferences: {
|
|
128
|
-
areTipsEnabled: true,
|
|
129
|
-
dismissedTips: {},
|
|
130
|
-
},
|
|
131
|
-
};
|
|
132
|
-
expect( areTipsEnabled( state ) ).toBe( true );
|
|
133
|
-
} );
|
|
134
|
-
|
|
135
|
-
it( 'should return false if tips are disabled', () => {
|
|
136
|
-
const state = {
|
|
137
|
-
guides: [],
|
|
138
|
-
preferences: {
|
|
139
|
-
areTipsEnabled: false,
|
|
140
|
-
dismissedTips: {},
|
|
141
|
-
},
|
|
142
|
-
};
|
|
143
|
-
expect( areTipsEnabled( state ) ).toBe( false );
|
|
17
|
+
it( 'returns false', () => {
|
|
18
|
+
expect( areTipsEnabled( {} ) ).toBe( false );
|
|
144
19
|
} );
|
|
145
20
|
} );
|
|
146
21
|
} );
|
package/src/style.scss
CHANGED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
@use "sass:math";
|
|
2
|
-
@use "@wordpress/base-styles/breakpoints" as *;
|
|
3
|
-
@use "@wordpress/base-styles/mixins" as *;
|
|
4
|
-
@use "@wordpress/base-styles/variables" as *;
|
|
5
|
-
@use "@wordpress/base-styles/z-index" as *;
|
|
6
|
-
|
|
7
|
-
$dot-size: 8px; // Size of the indicator dot
|
|
8
|
-
$dot-scale: 3; // How much the pulse animation should scale up by in size
|
|
9
|
-
|
|
10
|
-
.nux-dot-tip {
|
|
11
|
-
&::before,
|
|
12
|
-
&::after {
|
|
13
|
-
border-radius: 100%;
|
|
14
|
-
content: " ";
|
|
15
|
-
pointer-events: none;
|
|
16
|
-
position: absolute;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
&::before {
|
|
20
|
-
background: rgba(#00739c, 0.9);
|
|
21
|
-
opacity: 0.9;
|
|
22
|
-
height: $dot-size * $dot-scale;
|
|
23
|
-
left: -($dot-size * $dot-scale) * 0.5;
|
|
24
|
-
top: -($dot-size * $dot-scale) * 0.5;
|
|
25
|
-
transform: scale(math.div(1, $dot-scale));
|
|
26
|
-
width: $dot-size * $dot-scale;
|
|
27
|
-
|
|
28
|
-
@media not (prefers-reduced-motion) {
|
|
29
|
-
animation: nux-pulse 1.6s infinite cubic-bezier(0.17, 0.67, 0.92, 0.62);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
&::after {
|
|
34
|
-
background: #00739c;
|
|
35
|
-
height: $dot-size;
|
|
36
|
-
left: -$dot-size * 0.5;
|
|
37
|
-
top: -$dot-size * 0.5;
|
|
38
|
-
width: $dot-size;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@keyframes nux-pulse {
|
|
42
|
-
100% {
|
|
43
|
-
background: rgba(#00739c, 0);
|
|
44
|
-
transform: scale(1);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.components-popover__content {
|
|
49
|
-
width: 350px;
|
|
50
|
-
padding: 20px 18px;
|
|
51
|
-
|
|
52
|
-
@include break-small {
|
|
53
|
-
width: 450px;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.nux-dot-tip__disable {
|
|
57
|
-
position: absolute;
|
|
58
|
-
right: 0;
|
|
59
|
-
top: 0;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Position the dot right next to the edge of the button
|
|
64
|
-
&[data-y-axis="top"] {
|
|
65
|
-
margin-top: -$dot-size * 0.5;
|
|
66
|
-
}
|
|
67
|
-
&[data-y-axis="bottom"] {
|
|
68
|
-
margin-top: $dot-size * 0.5;
|
|
69
|
-
}
|
|
70
|
-
&[data-y-axis="middle"][data-y-axis="left"] {
|
|
71
|
-
margin-left: -$dot-size * 0.5;
|
|
72
|
-
}
|
|
73
|
-
&[data-y-axis="middle"][data-y-axis="right"] {
|
|
74
|
-
margin-left: $dot-size * 0.5;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Position the tip content away from the dot
|
|
78
|
-
&[data-y-axis="top"] .components-popover__content {
|
|
79
|
-
margin-bottom: 20px;
|
|
80
|
-
}
|
|
81
|
-
&[data-y-axis="bottom"] .components-popover__content {
|
|
82
|
-
margin-top: 20px;
|
|
83
|
-
}
|
|
84
|
-
&[data-y-axis="middle"][data-y-axis="left"] .components-popover__content {
|
|
85
|
-
margin-right: 20px;
|
|
86
|
-
}
|
|
87
|
-
&[data-y-axis="middle"][data-y-axis="right"] .components-popover__content {
|
|
88
|
-
margin-left: 20px;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Extra specificity so that we can override the styles in .component-popover
|
|
92
|
-
&[data-y-axis="left"],
|
|
93
|
-
&[data-y-axis="center"],
|
|
94
|
-
&[data-y-axis="right"] {
|
|
95
|
-
// Position tips above popovers
|
|
96
|
-
z-index: z-index(".nux-dot-tip");
|
|
97
|
-
|
|
98
|
-
// On mobile, always position the tip below the dot and fill the width of the viewport
|
|
99
|
-
@media (max-width: $break-small) {
|
|
100
|
-
.components-popover__content {
|
|
101
|
-
align-self: end;
|
|
102
|
-
left: 5px;
|
|
103
|
-
margin: 20px 0 0 0;
|
|
104
|
-
max-width: none !important; // Override the inline style set by <Popover>
|
|
105
|
-
position: fixed;
|
|
106
|
-
right: 5px;
|
|
107
|
-
width: auto;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
&.components-popover:not([data-y-axis="middle"])[data-y-axis="right"] .components-popover__content {
|
|
113
|
-
/*!rtl:ignore*/
|
|
114
|
-
margin-left: 0;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
&.components-popover:not([data-y-axis="middle"])[data-y-axis="left"] .components-popover__content {
|
|
118
|
-
/*!rtl:ignore*/
|
|
119
|
-
margin-right: 0;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
&.components-popover.interface-more-menu-dropdown__content:not([data-y-axis="middle"])[data-y-axis="right"] .components-popover__content {
|
|
123
|
-
/*!rtl:ignore*/
|
|
124
|
-
margin-left: -12px;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
&.components-popover.interface-more-menu-dropdown__content:not([data-y-axis="middle"])[data-y-axis="left"] .components-popover__content {
|
|
128
|
-
/*!rtl:ignore*/
|
|
129
|
-
margin-right: -12px;
|
|
130
|
-
}
|
|
131
|
-
}
|