newspack-components 4.7.0 → 4.8.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 +20 -0
- package/DEVELOPMENT.md +42 -21
- package/dist/cjs/_mixins.scss +13 -0
- package/dist/cjs/_variables.scss +12 -0
- package/dist/cjs/action-card/index.js +18 -10
- package/dist/cjs/action-card/index.test.js +91 -0
- package/dist/cjs/action-card/style.scss +2 -40
- package/dist/cjs/button/index.js +8 -3
- package/dist/cjs/button/index.test.js +61 -5
- package/dist/cjs/card/core-card.js +0 -2
- package/dist/cjs/card/style-core.scss +7 -5
- package/dist/cjs/card-feature/index.js +75 -61
- package/dist/cjs/card-feature/index.test.js +396 -54
- package/dist/cjs/card-feature/style.scss +20 -31
- package/dist/cjs/card-form/index.js +5 -5
- package/dist/cjs/card-sortable-list/index.js +5 -3
- package/dist/cjs/card-sortable-list/index.test.js +50 -0
- package/dist/cjs/collapsible-group/context.js +19 -0
- package/dist/cjs/collapsible-group/index.js +24 -0
- package/dist/cjs/collapsible-group/index.test.js +215 -0
- package/dist/cjs/collapsible-group/item.js +61 -0
- package/dist/cjs/collapsible-group/root.js +62 -0
- package/dist/cjs/collapsible-group/style.scss +47 -0
- package/dist/cjs/collapsible-group/types.js +5 -0
- package/dist/cjs/empty-state/actions.js +45 -0
- package/dist/cjs/empty-state/context.js +41 -0
- package/dist/cjs/empty-state/header.js +66 -0
- package/dist/cjs/empty-state/index.js +31 -0
- package/dist/cjs/empty-state/index.test.js +303 -0
- package/dist/cjs/empty-state/root.js +56 -0
- package/dist/cjs/empty-state/style.scss +51 -0
- package/dist/cjs/empty-state/types.js +5 -0
- package/dist/cjs/index.js +34 -20
- package/dist/cjs/info-button/index.js +59 -43
- package/dist/cjs/info-button/index.test.js +199 -0
- package/dist/cjs/info-button/style.scss +41 -9
- package/dist/cjs/modal/style.scss +12 -12
- package/dist/cjs/newspack-icon/style.scss +4 -4
- package/dist/cjs/notice/style.scss +3 -3
- package/dist/cjs/page/style.scss +16 -16
- package/dist/cjs/plugin-installer/index.js +5 -9
- package/dist/cjs/plugin-installer/style.scss +3 -14
- package/dist/cjs/section-header/index.js +31 -18
- package/dist/cjs/section-header/index.test.js +40 -0
- package/dist/cjs/section-header/style.scss +22 -6
- package/dist/cjs/settings/DateRangeSetting.js +309 -0
- package/dist/cjs/settings/SettingsSection.js +19 -5
- package/dist/cjs/settings/SettingsSection.test.js +49 -0
- package/dist/cjs/settings/index.js +3 -1
- package/dist/cjs/settings/style.scss +40 -7
- package/dist/cjs/stat-card/body.js +41 -0
- package/dist/cjs/stat-card/constants.js +11 -0
- package/dist/cjs/stat-card/context.js +54 -0
- package/dist/cjs/stat-card/delta.js +91 -0
- package/dist/cjs/stat-card/footer.js +72 -0
- package/dist/cjs/stat-card/index.js +47 -0
- package/dist/cjs/stat-card/index.test.js +938 -0
- package/dist/cjs/stat-card/label.js +66 -0
- package/dist/cjs/stat-card/root.js +69 -0
- package/dist/cjs/stat-card/secondary.js +38 -0
- package/dist/cjs/stat-card/style.scss +89 -0
- package/dist/cjs/stat-card/types.js +5 -0
- package/dist/cjs/stat-card/value.js +78 -0
- package/dist/cjs/status-indicator/index.js +66 -0
- package/dist/cjs/status-indicator/index.test.js +101 -0
- package/dist/cjs/status-indicator/statuses.js +39 -0
- package/dist/cjs/status-indicator/style.scss +9 -0
- package/dist/cjs/status-indicator/types.js +5 -0
- package/dist/cjs/style.scss +9 -9
- package/dist/cjs/tabbed-navigation/style.scss +6 -4
- package/dist/cjs/types.js +5 -0
- package/dist/cjs/web-preview/style.scss +11 -11
- package/dist/cjs/with-wizard/style.scss +10 -10
- package/dist/cjs/with-wizard-screen/style.scss +9 -9
- package/dist/cjs/wizard/index.js +33 -4
- package/dist/cjs/wizard/store/index.js +23 -1
- package/dist/esm/_mixins.scss +13 -0
- package/dist/esm/_variables.scss +12 -0
- package/dist/esm/action-card/index.js +18 -10
- package/dist/esm/action-card/index.test.js +89 -0
- package/dist/esm/action-card/style.scss +2 -40
- package/dist/esm/button/index.js +9 -4
- package/dist/esm/button/index.test.js +63 -5
- package/dist/esm/card/core-card.js +0 -2
- package/dist/esm/card/style-core.scss +7 -5
- package/dist/esm/card-feature/index.js +78 -62
- package/dist/esm/card-feature/index.test.js +397 -55
- package/dist/esm/card-feature/style.scss +20 -31
- package/dist/esm/card-form/index.js +5 -5
- package/dist/esm/card-sortable-list/index.js +6 -4
- package/dist/esm/card-sortable-list/index.test.js +46 -0
- package/dist/esm/collapsible-group/context.js +13 -0
- package/dist/esm/collapsible-group/index.js +17 -0
- package/dist/esm/collapsible-group/index.test.js +215 -0
- package/dist/esm/collapsible-group/item.js +53 -0
- package/dist/esm/collapsible-group/root.js +54 -0
- package/dist/esm/collapsible-group/style.scss +47 -0
- package/dist/esm/collapsible-group/types.js +1 -0
- package/dist/esm/empty-state/actions.js +37 -0
- package/dist/esm/empty-state/context.js +35 -0
- package/dist/esm/empty-state/header.js +58 -0
- package/dist/esm/empty-state/index.js +23 -0
- package/dist/esm/empty-state/index.test.js +299 -0
- package/dist/esm/empty-state/root.js +56 -0
- package/dist/esm/empty-state/style.scss +51 -0
- package/dist/esm/empty-state/types.js +1 -0
- package/dist/esm/index.js +4 -2
- package/dist/esm/info-button/index.js +54 -43
- package/dist/esm/info-button/index.test.js +195 -0
- package/dist/esm/info-button/style.scss +41 -9
- package/dist/esm/modal/style.scss +12 -12
- package/dist/esm/newspack-icon/style.scss +4 -4
- package/dist/esm/notice/style.scss +3 -3
- package/dist/esm/page/style.scss +16 -16
- package/dist/esm/plugin-installer/index.js +5 -9
- package/dist/esm/plugin-installer/style.scss +3 -14
- package/dist/esm/section-header/index.js +27 -14
- package/dist/esm/section-header/index.test.js +36 -0
- package/dist/esm/section-header/style.scss +22 -6
- package/dist/esm/settings/DateRangeSetting.js +304 -0
- package/dist/esm/settings/SettingsSection.js +16 -3
- package/dist/esm/settings/SettingsSection.test.js +45 -0
- package/dist/esm/settings/index.js +3 -1
- package/dist/esm/settings/style.scss +40 -7
- package/dist/esm/stat-card/body.js +36 -0
- package/dist/esm/stat-card/constants.js +5 -0
- package/dist/esm/stat-card/context.js +48 -0
- package/dist/esm/stat-card/delta.js +86 -0
- package/dist/esm/stat-card/footer.js +67 -0
- package/dist/esm/stat-card/index.js +33 -0
- package/dist/esm/stat-card/index.test.js +939 -0
- package/dist/esm/stat-card/label.js +61 -0
- package/dist/esm/stat-card/root.js +64 -0
- package/dist/esm/stat-card/secondary.js +33 -0
- package/dist/esm/stat-card/style.scss +89 -0
- package/dist/esm/stat-card/types.js +1 -0
- package/dist/esm/stat-card/value.js +73 -0
- package/dist/esm/status-indicator/index.js +52 -0
- package/dist/esm/status-indicator/index.test.js +96 -0
- package/dist/esm/status-indicator/statuses.js +33 -0
- package/dist/esm/status-indicator/style.scss +9 -0
- package/dist/esm/status-indicator/types.js +1 -0
- package/dist/esm/style.scss +9 -9
- package/dist/esm/tabbed-navigation/style.scss +6 -4
- package/dist/esm/types.js +1 -0
- package/dist/esm/web-preview/style.scss +11 -11
- package/dist/esm/with-wizard/style.scss +10 -10
- package/dist/esm/with-wizard-screen/style.scss +9 -9
- package/dist/esm/wizard/index.js +38 -7
- package/dist/esm/wizard/store/index.js +23 -1
- package/package.json +1 -1
- package/src/_mixins.scss +13 -0
- package/src/_variables.scss +12 -0
- package/src/action-card/action-card.d.ts +3 -2
- package/src/action-card/index.js +12 -12
- package/src/action-card/index.test.js +56 -0
- package/src/action-card/style.scss +2 -40
- package/src/button/index.test.js +52 -5
- package/src/button/index.tsx +9 -4
- package/src/card/core-card.js +0 -2
- package/src/card/style-core.scss +7 -5
- package/src/card-feature/README.md +68 -27
- package/src/card-feature/index.test.js +242 -27
- package/src/card-feature/index.tsx +77 -67
- package/src/card-feature/style.scss +20 -31
- package/src/card-form/README.md +10 -10
- package/src/card-form/index.tsx +4 -8
- package/src/card-sortable-list/README.md +4 -5
- package/src/card-sortable-list/index.test.js +29 -0
- package/src/card-sortable-list/index.tsx +7 -4
- package/src/collapsible-group/README.md +50 -0
- package/src/collapsible-group/context.ts +13 -0
- package/src/collapsible-group/index.test.js +168 -0
- package/src/collapsible-group/index.tsx +17 -0
- package/src/collapsible-group/item.tsx +42 -0
- package/src/collapsible-group/root.tsx +42 -0
- package/src/collapsible-group/style.scss +47 -0
- package/src/collapsible-group/types.ts +22 -0
- package/src/drawer/README.md +2 -2
- package/src/empty-state/README.md +165 -0
- package/src/empty-state/actions.tsx +37 -0
- package/src/empty-state/context.ts +40 -0
- package/src/empty-state/header.tsx +48 -0
- package/src/empty-state/index.test.js +247 -0
- package/src/empty-state/index.tsx +22 -0
- package/src/empty-state/root.tsx +39 -0
- package/src/empty-state/style.scss +51 -0
- package/src/empty-state/types.ts +33 -0
- package/src/index.js +4 -2
- package/src/info-button/README.md +115 -0
- package/src/info-button/index.test.js +163 -0
- package/src/info-button/index.tsx +64 -0
- package/src/info-button/style.scss +41 -9
- package/src/modal/style.scss +12 -12
- package/src/newspack-icon/style.scss +4 -4
- package/src/notice/style.scss +3 -3
- package/src/page/style.scss +16 -16
- package/src/plugin-installer/index.js +3 -9
- package/src/plugin-installer/style.scss +3 -14
- package/src/section-header/index.js +27 -14
- package/src/section-header/index.test.js +28 -0
- package/src/section-header/style.scss +22 -6
- package/src/settings/DateRangeSetting.js +266 -0
- package/src/settings/SettingsSection.js +24 -4
- package/src/settings/SettingsSection.test.js +45 -0
- package/src/settings/index.js +2 -0
- package/src/settings/style.scss +40 -7
- package/src/stat-card/README.md +434 -0
- package/src/stat-card/body.tsx +28 -0
- package/src/stat-card/constants.ts +5 -0
- package/src/stat-card/context.ts +53 -0
- package/src/stat-card/delta.tsx +88 -0
- package/src/stat-card/footer.tsx +68 -0
- package/src/stat-card/index.test.js +818 -0
- package/src/stat-card/index.tsx +48 -0
- package/src/stat-card/label.tsx +61 -0
- package/src/stat-card/root.tsx +40 -0
- package/src/stat-card/secondary.tsx +27 -0
- package/src/stat-card/style.scss +89 -0
- package/src/stat-card/types.ts +84 -0
- package/src/stat-card/value.tsx +72 -0
- package/src/status-indicator/README.md +123 -0
- package/src/status-indicator/index.test.js +70 -0
- package/src/status-indicator/index.tsx +39 -0
- package/src/status-indicator/statuses.ts +35 -0
- package/src/status-indicator/style.scss +9 -0
- package/src/status-indicator/types.ts +28 -0
- package/src/style.scss +9 -9
- package/src/tabbed-navigation/style.scss +6 -4
- package/src/types.ts +25 -0
- package/src/web-preview/style.scss +11 -11
- package/src/with-wizard/style.scss +10 -10
- package/src/with-wizard-screen/style.scss +9 -9
- package/src/wizard/index.js +49 -7
- package/src/wizard/store/index.js +26 -1
- package/dist/cjs/accordion/index.js +0 -72
- package/dist/cjs/accordion/index.test.js +0 -80
- package/dist/cjs/accordion/style.scss +0 -35
- package/dist/cjs/badge/index.js +0 -32
- package/dist/cjs/badge/style.scss +0 -36
- package/dist/esm/accordion/index.js +0 -63
- package/dist/esm/accordion/index.test.js +0 -79
- package/dist/esm/accordion/style.scss +0 -35
- package/dist/esm/badge/index.js +0 -24
- package/dist/esm/badge/style.scss +0 -36
- package/src/accordion/index.js +0 -46
- package/src/accordion/index.test.js +0 -62
- package/src/accordion/style.scss +0 -35
- package/src/badge/index.tsx +0 -26
- package/src/badge/style.scss +0 -36
- package/src/info-button/index.js +0 -38
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies.
|
|
3
|
+
*/
|
|
4
|
+
import { act, fireEvent, render, screen } from '@testing-library/react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies.
|
|
8
|
+
*/
|
|
9
|
+
import { createRef } from '@wordpress/element';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies.
|
|
13
|
+
*/
|
|
14
|
+
import InfoButton from './';
|
|
15
|
+
|
|
16
|
+
const DESCRIPTION = 'Number of articles read in the last 30 day period.';
|
|
17
|
+
|
|
18
|
+
const getTrigger = ( name = 'More information' ) => screen.getByRole( 'button', { name } );
|
|
19
|
+
|
|
20
|
+
describe( 'InfoButton', () => {
|
|
21
|
+
afterEach( () => {
|
|
22
|
+
jest.useRealTimers();
|
|
23
|
+
} );
|
|
24
|
+
|
|
25
|
+
it( 'names the trigger briefly rather than with the whole description', () => {
|
|
26
|
+
render( <InfoButton description={ DESCRIPTION } /> );
|
|
27
|
+
expect( getTrigger() ).toBeInTheDocument();
|
|
28
|
+
expect( screen.queryByRole( 'button', { name: DESCRIPTION } ) ).not.toBeInTheDocument();
|
|
29
|
+
} );
|
|
30
|
+
|
|
31
|
+
it( 'renders nothing at all without a description', () => {
|
|
32
|
+
const { container } = render( <InfoButton /> );
|
|
33
|
+
expect( screen.queryByRole( 'button' ) ).not.toBeInTheDocument();
|
|
34
|
+
expect( container.firstChild ).toBeNull();
|
|
35
|
+
} );
|
|
36
|
+
|
|
37
|
+
it( 'treats an empty description as nothing to explain', () => {
|
|
38
|
+
const { container } = render( <InfoButton description="" /> );
|
|
39
|
+
expect( screen.queryByRole( 'button' ) ).not.toBeInTheDocument();
|
|
40
|
+
expect( container.firstChild ).toBeNull();
|
|
41
|
+
} );
|
|
42
|
+
|
|
43
|
+
it( 'lets a consumer name the trigger for its own context', () => {
|
|
44
|
+
render( <InfoButton description={ DESCRIPTION } triggerLabel="More information about Articles read" /> );
|
|
45
|
+
expect( getTrigger( 'More information about Articles read' ) ).toBeInTheDocument();
|
|
46
|
+
} );
|
|
47
|
+
|
|
48
|
+
it( 'leaves the trigger in the tab order', () => {
|
|
49
|
+
render( <InfoButton description={ DESCRIPTION } /> );
|
|
50
|
+
expect( getTrigger().tabIndex ).toBeGreaterThanOrEqual( 0 );
|
|
51
|
+
} );
|
|
52
|
+
|
|
53
|
+
it( 'keeps the description hidden until the trigger is activated', () => {
|
|
54
|
+
render( <InfoButton description={ DESCRIPTION } /> );
|
|
55
|
+
expect( screen.queryByText( DESCRIPTION ) ).not.toBeInTheDocument();
|
|
56
|
+
expect( getTrigger() ).toHaveAttribute( 'aria-expanded', 'false' );
|
|
57
|
+
} );
|
|
58
|
+
|
|
59
|
+
it( 'reveals the description on click, so touch users can reach it', () => {
|
|
60
|
+
render( <InfoButton description={ DESCRIPTION } /> );
|
|
61
|
+
fireEvent.click( getTrigger() );
|
|
62
|
+
expect( screen.getByText( DESCRIPTION ) ).toBeInTheDocument();
|
|
63
|
+
expect( getTrigger() ).toHaveAttribute( 'aria-expanded', 'true' );
|
|
64
|
+
} );
|
|
65
|
+
|
|
66
|
+
it( 'reveals the description on hover, once the pointer has rested', () => {
|
|
67
|
+
jest.useFakeTimers();
|
|
68
|
+
render( <InfoButton description={ DESCRIPTION } /> );
|
|
69
|
+
const trigger = getTrigger();
|
|
70
|
+
|
|
71
|
+
fireEvent.mouseEnter( trigger );
|
|
72
|
+
fireEvent.mouseMove( trigger );
|
|
73
|
+
expect( screen.queryByText( DESCRIPTION ) ).not.toBeInTheDocument();
|
|
74
|
+
|
|
75
|
+
act( () => jest.advanceTimersByTime( 200 ) );
|
|
76
|
+
|
|
77
|
+
expect( screen.getByText( DESCRIPTION ) ).toBeInTheDocument();
|
|
78
|
+
} );
|
|
79
|
+
|
|
80
|
+
it( 'holds the description open long enough to overshoot the trigger', () => {
|
|
81
|
+
jest.useFakeTimers();
|
|
82
|
+
render( <InfoButton description={ DESCRIPTION } /> );
|
|
83
|
+
const trigger = getTrigger();
|
|
84
|
+
|
|
85
|
+
fireEvent.mouseEnter( trigger );
|
|
86
|
+
fireEvent.mouseMove( trigger );
|
|
87
|
+
act( () => jest.advanceTimersByTime( 200 ) );
|
|
88
|
+
expect( screen.getByText( DESCRIPTION ) ).toBeInTheDocument();
|
|
89
|
+
|
|
90
|
+
fireEvent.mouseLeave( trigger );
|
|
91
|
+
expect( screen.getByText( DESCRIPTION ) ).toBeInTheDocument();
|
|
92
|
+
|
|
93
|
+
act( () => jest.advanceTimersByTime( 200 ) );
|
|
94
|
+
|
|
95
|
+
expect( screen.queryByText( DESCRIPTION ) ).not.toBeInTheDocument();
|
|
96
|
+
} );
|
|
97
|
+
|
|
98
|
+
it( 'uses a native button, so Enter and Space activate it', () => {
|
|
99
|
+
render( <InfoButton description={ DESCRIPTION } /> );
|
|
100
|
+
const trigger = getTrigger();
|
|
101
|
+
expect( trigger.tagName ).toBe( 'BUTTON' );
|
|
102
|
+
expect( trigger ).toHaveAttribute( 'type', 'button' );
|
|
103
|
+
} );
|
|
104
|
+
|
|
105
|
+
it( 'closes on Escape and hands focus back to the trigger', () => {
|
|
106
|
+
render( <InfoButton description={ DESCRIPTION } /> );
|
|
107
|
+
const trigger = getTrigger();
|
|
108
|
+
trigger.focus();
|
|
109
|
+
fireEvent.click( trigger );
|
|
110
|
+
expect( screen.getByText( DESCRIPTION ) ).toBeInTheDocument();
|
|
111
|
+
|
|
112
|
+
fireEvent.keyDown( document.activeElement, { key: 'Escape' } );
|
|
113
|
+
|
|
114
|
+
expect( screen.queryByText( DESCRIPTION ) ).not.toBeInTheDocument();
|
|
115
|
+
expect( trigger ).toHaveFocus();
|
|
116
|
+
} );
|
|
117
|
+
|
|
118
|
+
it( 'gives the popup an accessible name of its own', () => {
|
|
119
|
+
render( <InfoButton description={ DESCRIPTION } /> );
|
|
120
|
+
fireEvent.click( getTrigger() );
|
|
121
|
+
expect( screen.getByRole( 'dialog', { name: 'More information' } ) ).toBeInTheDocument();
|
|
122
|
+
} );
|
|
123
|
+
|
|
124
|
+
it( 'describes the popup with the description rather than naming it', () => {
|
|
125
|
+
render( <InfoButton description={ DESCRIPTION } /> );
|
|
126
|
+
fireEvent.click( getTrigger() );
|
|
127
|
+
const paragraph = screen.getByText( DESCRIPTION );
|
|
128
|
+
expect( paragraph.id ).toBeTruthy();
|
|
129
|
+
expect( document.querySelector( `[aria-describedby="${ paragraph.id }"]` ) ).toBeInTheDocument();
|
|
130
|
+
} );
|
|
131
|
+
|
|
132
|
+
it( 'renders through its own portal and positioner', () => {
|
|
133
|
+
render( <InfoButton description={ DESCRIPTION } /> );
|
|
134
|
+
fireEvent.click( getTrigger() );
|
|
135
|
+
const paragraph = screen.getByText( DESCRIPTION );
|
|
136
|
+
expect( paragraph.closest( '.newspack-info-button__positioner' ) ).toBeInTheDocument();
|
|
137
|
+
expect( paragraph.closest( '.newspack-info-button__portal' ) ).toBeInTheDocument();
|
|
138
|
+
} );
|
|
139
|
+
|
|
140
|
+
it( 'forwards unknown props to the trigger', () => {
|
|
141
|
+
render( <InfoButton description={ DESCRIPTION } id="articles-read-info" data-testid="info" /> );
|
|
142
|
+
const trigger = getTrigger();
|
|
143
|
+
expect( trigger ).toHaveAttribute( 'id', 'articles-read-info' );
|
|
144
|
+
expect( trigger ).toHaveAttribute( 'data-testid', 'info' );
|
|
145
|
+
} );
|
|
146
|
+
|
|
147
|
+
it( 'keeps its own class alongside a consumer className', () => {
|
|
148
|
+
render( <InfoButton description={ DESCRIPTION } className="custom-class" /> );
|
|
149
|
+
expect( getTrigger() ).toHaveClass( 'newspack-info-button', 'custom-class' );
|
|
150
|
+
} );
|
|
151
|
+
|
|
152
|
+
it( 'hands a consumer ref the trigger itself', () => {
|
|
153
|
+
const ref = createRef();
|
|
154
|
+
render( <InfoButton description={ DESCRIPTION } ref={ ref } /> );
|
|
155
|
+
expect( ref.current ).toBe( getTrigger() );
|
|
156
|
+
} );
|
|
157
|
+
|
|
158
|
+
it( 'names the trigger and the popup alike when given an aria-label', () => {
|
|
159
|
+
render( <InfoButton description={ DESCRIPTION } aria-label="More information about Articles read" /> );
|
|
160
|
+
fireEvent.click( getTrigger( 'More information about Articles read' ) );
|
|
161
|
+
expect( screen.getByRole( 'dialog', { name: 'More information about Articles read' } ) ).toBeInTheDocument();
|
|
162
|
+
} );
|
|
163
|
+
} );
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies.
|
|
3
|
+
*/
|
|
4
|
+
import classnames from 'classnames';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WordPress dependencies.
|
|
8
|
+
*/
|
|
9
|
+
import { forwardRef } from '@wordpress/element';
|
|
10
|
+
import { __ } from '@wordpress/i18n';
|
|
11
|
+
import { Icon, info } from '@wordpress/icons';
|
|
12
|
+
import { getWpCompatOverlaySlot, Popover, VisuallyHidden } from '@wordpress/ui';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Internal dependencies.
|
|
16
|
+
*/
|
|
17
|
+
import './style.scss';
|
|
18
|
+
|
|
19
|
+
type InfoButtonProps = React.ComponentPropsWithoutRef< 'button' > & {
|
|
20
|
+
description?: string;
|
|
21
|
+
triggerLabel?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Uses `Popover` rather than `Tooltip`: a tooltip never opens from a touch
|
|
26
|
+
* pointer, and its popup is not exposed to assistive technology.
|
|
27
|
+
*/
|
|
28
|
+
const InfoButton = forwardRef< HTMLButtonElement, InfoButtonProps >( function InfoButton(
|
|
29
|
+
{ description, className, triggerLabel, 'aria-label': ariaLabel, ...rest },
|
|
30
|
+
ref
|
|
31
|
+
) {
|
|
32
|
+
if ( ! description ) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const name = triggerLabel || ariaLabel || __( 'More information', 'newspack-plugin' );
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<Popover.Root>
|
|
40
|
+
<Popover.Trigger
|
|
41
|
+
ref={ ref }
|
|
42
|
+
openOnHover
|
|
43
|
+
delay={ 200 }
|
|
44
|
+
closeDelay={ 200 }
|
|
45
|
+
aria-label={ name }
|
|
46
|
+
className={ classnames( 'newspack-info-button', className ) }
|
|
47
|
+
{ ...rest }
|
|
48
|
+
>
|
|
49
|
+
<Icon icon={ info } size={ 20 } />
|
|
50
|
+
</Popover.Trigger>
|
|
51
|
+
<Popover.Popup
|
|
52
|
+
variant="unstyled"
|
|
53
|
+
className="newspack-info-button__popup"
|
|
54
|
+
portal={ <Popover.Portal className="newspack-info-button__portal" container={ getWpCompatOverlaySlot() } /> }
|
|
55
|
+
positioner={ <Popover.Positioner className="newspack-info-button__positioner" side="top" sideOffset={ 4 } /> }
|
|
56
|
+
>
|
|
57
|
+
<VisuallyHidden render={ <Popover.Title /> }>{ name }</VisuallyHidden>
|
|
58
|
+
<Popover.Description>{ description }</Popover.Description>
|
|
59
|
+
</Popover.Popup>
|
|
60
|
+
</Popover.Root>
|
|
61
|
+
);
|
|
62
|
+
} );
|
|
63
|
+
|
|
64
|
+
export default InfoButton;
|
|
@@ -1,18 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
@use "~@wordpress/base-styles/colors" as wp-colors;
|
|
2
|
+
@use "~@wordpress/base-styles/variables" as wp-vars;
|
|
3
|
+
@use "~@wordpress/base-styles/z-index" as wp-z;
|
|
4
4
|
|
|
5
5
|
.newspack-info-button {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
align-items: center;
|
|
7
|
+
background: none;
|
|
8
|
+
border: none;
|
|
9
|
+
border-radius: var(--wpds-border-radius-sm, #{wp-vars.$radius-small});
|
|
10
|
+
color: inherit;
|
|
11
|
+
cursor: var(--wpds-cursor-control, pointer);
|
|
12
|
+
display: inline-flex;
|
|
13
|
+
flex: 0 0 auto;
|
|
14
|
+
height: wp-vars.$button-size-small;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
padding: 0;
|
|
12
17
|
vertical-align: middle;
|
|
18
|
+
width: wp-vars.$button-size-small;
|
|
13
19
|
|
|
14
20
|
svg {
|
|
15
21
|
display: block;
|
|
16
22
|
fill: currentcolor;
|
|
17
23
|
}
|
|
24
|
+
|
|
25
|
+
&:focus-visible {
|
|
26
|
+
outline: var(--wp-admin-border-width-focus, #{wp-vars.$border-width-focus-fallback}) solid var(--wp-admin-theme-color, #{wp-colors.$gray-900});
|
|
27
|
+
outline-offset: 0;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.newspack-info-button__portal {
|
|
32
|
+
--wp-ui-popover-z-index: #{wp-z.z-index(".components-popover")};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.newspack-info-button__positioner {
|
|
36
|
+
max-width: var(--wpds-dimension-surface-width-sm, calc(#{wp-vars.$grid-unit} * 40));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.newspack-info-button__popup {
|
|
40
|
+
background-color: wp-colors.$gray-900;
|
|
41
|
+
border-radius: var(--wpds-border-radius-md, #{wp-vars.$radius-medium});
|
|
42
|
+
box-shadow: var(--wpds-elevation-sm, #{wp-vars.$elevation-small});
|
|
43
|
+
color: wp-colors.$white;
|
|
44
|
+
outline: 0;
|
|
45
|
+
padding: var(--wpds-dimension-padding-xs, #{wp-vars.$grid-unit-05}) var(--wpds-dimension-padding-sm, #{wp-vars.$grid-unit-10});
|
|
46
|
+
|
|
47
|
+
@media (forced-colors: active) {
|
|
48
|
+
border: var(--wpds-border-width-xs, #{wp-vars.$border-width}) solid CanvasText;
|
|
49
|
+
}
|
|
18
50
|
}
|
package/src/modal/style.scss
CHANGED
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
* Modal
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
@use "../../../colors/colors.module" as colors;
|
|
5
|
+
@use "../../../colors/colors.module" as np-colors;
|
|
6
6
|
|
|
7
7
|
.newspack-modal {
|
|
8
8
|
// Color
|
|
9
|
-
--wp-admin-theme-color: #{colors.$primary-600};
|
|
10
|
-
--wp-admin-theme-color--rgb: #{colors.$primary-600--rgb};
|
|
11
|
-
--wp-admin-theme-color-darker-10: #{colors.$primary-700};
|
|
12
|
-
--wp-admin-theme-color-darker-10--rgb: #{colors.$primary-700--rgb};
|
|
13
|
-
--wp-admin-theme-color-darker-20: #{colors.$primary-800};
|
|
14
|
-
--wp-admin-theme-color-darker-20--rgb: #{colors.$primary-800--rgb};
|
|
15
|
-
--wp-admin-theme-color-lighter-10: #{colors.$primary-000};
|
|
16
|
-
--wp-admin-theme-color-lighter-10--rgb: #{colors.$primary-000--rgb};
|
|
9
|
+
--wp-admin-theme-color: #{np-colors.$primary-600};
|
|
10
|
+
--wp-admin-theme-color--rgb: #{np-colors.$primary-600--rgb};
|
|
11
|
+
--wp-admin-theme-color-darker-10: #{np-colors.$primary-700};
|
|
12
|
+
--wp-admin-theme-color-darker-10--rgb: #{np-colors.$primary-700--rgb};
|
|
13
|
+
--wp-admin-theme-color-darker-20: #{np-colors.$primary-800};
|
|
14
|
+
--wp-admin-theme-color-darker-20--rgb: #{np-colors.$primary-800--rgb};
|
|
15
|
+
--wp-admin-theme-color-lighter-10: #{np-colors.$primary-000};
|
|
16
|
+
--wp-admin-theme-color-lighter-10--rgb: #{np-colors.$primary-000--rgb};
|
|
17
17
|
|
|
18
18
|
border-radius: 8px;
|
|
19
19
|
margin: auto;
|
|
@@ -58,11 +58,11 @@
|
|
|
58
58
|
|
|
59
59
|
&--destructive {
|
|
60
60
|
.components-button.is-primary {
|
|
61
|
-
background-color: colors.$error-500;
|
|
62
|
-
color: colors.$neutral-000;
|
|
61
|
+
background-color: np-colors.$error-500;
|
|
62
|
+
color: np-colors.$neutral-000;
|
|
63
63
|
&:hover,
|
|
64
64
|
&:focus {
|
|
65
|
-
background-color: colors.$error-600;
|
|
65
|
+
background-color: np-colors.$error-600;
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
@use
|
|
1
|
+
@use "../../../colors/colors.module" as np-colors;
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Newspack Icon
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
.newspack-icon {
|
|
8
|
-
background: colors.$primary-600;
|
|
8
|
+
background: np-colors.$primary-600;
|
|
9
9
|
fill: white;
|
|
10
10
|
padding: 12px;
|
|
11
11
|
|
|
12
12
|
&--white {
|
|
13
13
|
background: white;
|
|
14
|
-
fill: colors.$primary-600;
|
|
14
|
+
fill: np-colors.$primary-600;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
&--simple {
|
|
18
18
|
background: none;
|
|
19
|
-
fill: colors.$primary-600;
|
|
19
|
+
fill: np-colors.$primary-600;
|
|
20
20
|
padding: 0;
|
|
21
21
|
}
|
|
22
22
|
|
package/src/notice/style.scss
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
@use "sass:color";
|
|
6
6
|
@use "~@wordpress/base-styles/colors" as wp-colors;
|
|
7
|
-
@use "../../../colors/colors.module" as colors;
|
|
7
|
+
@use "../../../colors/colors.module" as np-colors;
|
|
8
8
|
|
|
9
9
|
.newspack-notice {
|
|
10
10
|
align-items: center;
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
&__is-debug {
|
|
26
|
-
background: colors.$primary-600;
|
|
26
|
+
background: np-colors.$primary-600;
|
|
27
27
|
border-radius: 50%;
|
|
28
28
|
bottom: 16px;
|
|
29
29
|
box-shadow: 0 0 8px 4px rgba(black, 0.08);
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
&__is-help {
|
|
66
|
-
background: colors.$primary-050;
|
|
66
|
+
background: np-colors.$primary-050;
|
|
67
67
|
|
|
68
68
|
> svg {
|
|
69
69
|
fill: var(--wp-admin-theme-color);
|
package/src/page/style.scss
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@use "../../../colors/colors.module" as colors;
|
|
1
|
+
@use "../../../colors/colors.module" as np-colors;
|
|
2
2
|
@use "~@wordpress/base-styles/colors" as wp-colors;
|
|
3
3
|
@use "~@wordpress/base-styles/mixins" as wp-mixins;
|
|
4
4
|
@use "~@wordpress/base-styles/variables" as wp-vars;
|
|
@@ -20,21 +20,21 @@
|
|
|
20
20
|
// without per-component overrides.
|
|
21
21
|
/* stylelint-disable plugin-wpds/no-setting-wpds-custom-properties -- deliberate Newspack brand override of the wpds brand tokens. */
|
|
22
22
|
:root {
|
|
23
|
-
--wpds-color-background-interactive-brand-strong: #{colors.$primary-600};
|
|
24
|
-
--wpds-color-background-interactive-brand-strong-active: #{colors.$primary-800};
|
|
25
|
-
--wpds-color-background-interactive-brand-weak-active: #{colors.$primary-000};
|
|
26
|
-
--wpds-color-background-surface-brand: #{colors.$primary-000};
|
|
27
|
-
--wpds-color-background-thumb-brand: #{colors.$primary-600};
|
|
28
|
-
--wpds-color-background-thumb-brand-active: #{colors.$primary-600};
|
|
29
|
-
--wpds-color-foreground-interactive-brand: #{colors.$primary-600};
|
|
30
|
-
--wpds-color-foreground-interactive-brand-active: #{colors.$primary-800};
|
|
31
|
-
--wpds-color-foreground-interactive-brand-disabled: #{colors.$primary-400};
|
|
32
|
-
--wpds-color-stroke-focus: #{colors.$primary-600};
|
|
33
|
-
--wpds-color-stroke-interactive-brand: #{colors.$primary-600};
|
|
34
|
-
--wpds-color-stroke-interactive-brand-active: #{colors.$primary-800};
|
|
35
|
-
--wpds-color-stroke-interactive-brand-disabled: #{colors.$primary-100};
|
|
36
|
-
--wpds-color-stroke-surface-brand: #{colors.$primary-000};
|
|
37
|
-
--wpds-color-stroke-surface-brand-strong: #{colors.$primary-600};
|
|
23
|
+
--wpds-color-background-interactive-brand-strong: #{np-colors.$primary-600};
|
|
24
|
+
--wpds-color-background-interactive-brand-strong-active: #{np-colors.$primary-800};
|
|
25
|
+
--wpds-color-background-interactive-brand-weak-active: #{np-colors.$primary-000};
|
|
26
|
+
--wpds-color-background-surface-brand: #{np-colors.$primary-000};
|
|
27
|
+
--wpds-color-background-thumb-brand: #{np-colors.$primary-600};
|
|
28
|
+
--wpds-color-background-thumb-brand-active: #{np-colors.$primary-600};
|
|
29
|
+
--wpds-color-foreground-interactive-brand: #{np-colors.$primary-600};
|
|
30
|
+
--wpds-color-foreground-interactive-brand-active: #{np-colors.$primary-800};
|
|
31
|
+
--wpds-color-foreground-interactive-brand-disabled: #{np-colors.$primary-400};
|
|
32
|
+
--wpds-color-stroke-focus: #{np-colors.$primary-600};
|
|
33
|
+
--wpds-color-stroke-interactive-brand: #{np-colors.$primary-600};
|
|
34
|
+
--wpds-color-stroke-interactive-brand-active: #{np-colors.$primary-800};
|
|
35
|
+
--wpds-color-stroke-interactive-brand-disabled: #{np-colors.$primary-100};
|
|
36
|
+
--wpds-color-stroke-surface-brand: #{np-colors.$primary-000};
|
|
37
|
+
--wpds-color-stroke-surface-brand-strong: #{np-colors.$primary-600};
|
|
38
38
|
}
|
|
39
39
|
/* stylelint-enable plugin-wpds/no-setting-wpds-custom-properties */
|
|
40
40
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import apiFetch from '@wordpress/api-fetch';
|
|
9
9
|
import { Component } from '@wordpress/element';
|
|
10
10
|
import { __ } from '@wordpress/i18n';
|
|
11
|
-
import {
|
|
11
|
+
import { Badge } from '@wordpress/ui';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Internal dependencies.
|
|
@@ -227,14 +227,8 @@ class PluginInstaller extends Component {
|
|
|
227
227
|
</span>
|
|
228
228
|
);
|
|
229
229
|
} else if ( Status === 'active' ) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
{ __( 'Installed', 'newspack-plugin' ) }
|
|
233
|
-
<span className="newspack-checkbox-icon newspack-checkbox-icon--checked">
|
|
234
|
-
<Icon icon={ check } />
|
|
235
|
-
</span>
|
|
236
|
-
</span>
|
|
237
|
-
);
|
|
230
|
+
// Installed is a state, not an action, so the slot takes a badge.
|
|
231
|
+
actionText = <Badge intent="stable">{ __( 'Installed', 'newspack-plugin' ) }</Badge>;
|
|
238
232
|
}
|
|
239
233
|
|
|
240
234
|
const classes = classnames( 'newspack-action-card__plugin-installer', this.classForInstallationStatus( installationStatus ) );
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
* Plugin Installer
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
@use "~@wordpress/base-styles/colors" as wp-colors;
|
|
6
|
-
|
|
7
5
|
.newspack-card {
|
|
8
6
|
.newspack-plugin-installer__status {
|
|
9
7
|
align-items: center;
|
|
@@ -35,25 +33,16 @@
|
|
|
35
33
|
}
|
|
36
34
|
|
|
37
35
|
&.newspack-plugin-installer__status-active {
|
|
38
|
-
box-shadow: inset 4px 0 0
|
|
39
|
-
|
|
40
|
-
.newspack-plugin-installer__checkbox {
|
|
41
|
-
background: wp-colors.$alert-green;
|
|
42
|
-
box-shadow: none;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
svg {
|
|
46
|
-
fill: white;
|
|
47
|
-
}
|
|
36
|
+
box-shadow: inset 4px 0 0 var( --wpds-color-stroke-surface-success-strong, #008030 );
|
|
48
37
|
}
|
|
49
38
|
|
|
50
39
|
&.newspack-plugin-installer__status-error {
|
|
51
|
-
box-shadow: inset 4px 0 0
|
|
40
|
+
box-shadow: inset 4px 0 0 var( --wpds-color-stroke-surface-error-strong, #cc1818 );
|
|
52
41
|
}
|
|
53
42
|
|
|
54
43
|
&.newspack-plugin-installer__status-installing,
|
|
55
44
|
&.newspack-plugin-installer__status-none {
|
|
56
|
-
box-shadow: inset 4px 0 0
|
|
45
|
+
box-shadow: inset 4px 0 0 var( --wpds-color-stroke-surface-neutral-weak, #f0f0f0 );
|
|
57
46
|
}
|
|
58
47
|
|
|
59
48
|
// Is Small
|
|
@@ -9,11 +9,13 @@ import { __ } from '@wordpress/i18n';
|
|
|
9
9
|
import { useEffect, useRef } from '@wordpress/element';
|
|
10
10
|
import { DropdownMenu, MenuItem, Tooltip, __experimentalHStack as HStack } from '@wordpress/components'; // eslint-disable-line @wordpress/no-unsafe-wp-apis
|
|
11
11
|
import { Icon, chevronLeft, moreVertical } from '@wordpress/icons';
|
|
12
|
+
import { Badge } from '@wordpress/ui';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Internal dependencies
|
|
15
16
|
*/
|
|
16
|
-
import
|
|
17
|
+
import Button from '../button';
|
|
18
|
+
import Grid from '../grid';
|
|
17
19
|
import './style.scss';
|
|
18
20
|
|
|
19
21
|
/**
|
|
@@ -26,17 +28,19 @@ import classnames from 'classnames';
|
|
|
26
28
|
*
|
|
27
29
|
* @typedef {Object} SectionHeaderProps
|
|
28
30
|
* @property {string} [backNav=''] - URL to navigate back to.
|
|
29
|
-
* @property {
|
|
30
|
-
* @property {string} [badgeLevel] - Badge level, e.g., 'success', 'info', 'warning', 'error'.
|
|
31
|
+
* @property {Object[]} [badges] - Badges to display beside the title, each `{ label, intent }`.
|
|
31
32
|
* @property {boolean} [centered=false] - Indicates if the header is centered.
|
|
32
|
-
* @property {?string} [className=null] - Additional CSS class name.
|
|
33
|
+
* @property {?string} [className=null] - Additional CSS class name, applied to the outer container.
|
|
33
34
|
* @property {string|Function|*} [description] - Description of the section.
|
|
34
35
|
* @property {number} [heading=2] - HTML heading level, e.g., 1 for h1, 2 for h2, etc.
|
|
35
36
|
* @property {string|Function|*} [icon] - Icon to display in the header.
|
|
36
37
|
* @property {boolean} [isWhite=false] - Indicates if the header should use a white theme.
|
|
38
|
+
* @property {Object[]} [menu] - Overflow menu items.
|
|
37
39
|
* @property {boolean} [noMargin=false] - Indicates if the header should have no margin.
|
|
38
40
|
* @property {boolean} [pageHeader=false] - Indicates if the header is used as a page header.
|
|
39
|
-
* @property {
|
|
41
|
+
* @property {Object} [primaryAction] - Primary button, `{ label, href, action }`.
|
|
42
|
+
* @property {Object} [secondaryAction] - Secondary link, `{ label, href, action }`.
|
|
43
|
+
* @property {string} [size='default'] - Size variant: 'small', 'default', or 'hidden' to drop the title and description while the back nav stays visible.
|
|
40
44
|
* @property {string} title - The title of the section.
|
|
41
45
|
* @property {?string} [id=null] - Optional ID for the header element.
|
|
42
46
|
* @property {?string|Function|*} [children=null] - Optional children to display in the header.
|
|
@@ -85,7 +89,8 @@ const SectionHeader = ( {
|
|
|
85
89
|
isWhite && 'newspack-section-header--is-white',
|
|
86
90
|
noMargin && 'newspack-section-header--no-margin',
|
|
87
91
|
pageHeader && 'newspack-section-header--page-header',
|
|
88
|
-
size === 'small' && 'newspack-section-header--small'
|
|
92
|
+
size === 'small' && 'newspack-section-header--small',
|
|
93
|
+
size === 'hidden' && 'newspack-section-header--hidden'
|
|
89
94
|
);
|
|
90
95
|
|
|
91
96
|
// The breadcrumb `Page` owns the single page `<h1>`, so a `pageHeader` section
|
|
@@ -93,17 +98,23 @@ const SectionHeader = ( {
|
|
|
93
98
|
// controls only the enlarged, centered styling — not the tag. Pass `heading={ 1 }`
|
|
94
99
|
// on a headerless screen that needs the section header to be the page's h1.
|
|
95
100
|
const HeadingTag = `h${ heading }`;
|
|
101
|
+
// `hidden` drops the title rather than announcing a level no reader can see.
|
|
102
|
+
const hiddenText = size === 'hidden' ? 'newspack-section-header__hidden-text' : undefined;
|
|
96
103
|
|
|
97
104
|
let titleContent = null;
|
|
98
105
|
|
|
106
|
+
const renderBadge = ( badge, i ) => (
|
|
107
|
+
<Badge key={ i } className="newspack-section-header__badge" intent={ badge.intent || 'none' }>
|
|
108
|
+
{ badge.label }
|
|
109
|
+
</Badge>
|
|
110
|
+
);
|
|
111
|
+
|
|
99
112
|
if ( typeof title === 'string' ) {
|
|
100
113
|
titleContent = (
|
|
101
114
|
<div className="newspack-section-header__title-container">
|
|
102
|
-
<HeadingTag className=
|
|
115
|
+
<HeadingTag className={ classnames( 'newspack-section-header__title', hiddenText ) }>
|
|
103
116
|
{ title }
|
|
104
|
-
{ badges?.
|
|
105
|
-
? badges.map( ( badge, i ) => <Badge key={ i } text={ badge.label } level={ badge.level || 'default' } /> )
|
|
106
|
-
: null }
|
|
117
|
+
{ ( badges || [] ).filter( badge => badge?.label ).map( renderBadge ) }
|
|
107
118
|
</HeadingTag>
|
|
108
119
|
{ /* Secondary action before the overflow menu, so a promoted link reads as an action rather than sitting to the right of the kebab. */ }
|
|
109
120
|
{ secondaryAction && (
|
|
@@ -134,7 +145,7 @@ const SectionHeader = ( {
|
|
|
134
145
|
</div>
|
|
135
146
|
);
|
|
136
147
|
} else if ( typeof title === 'function' ) {
|
|
137
|
-
titleContent = <HeadingTag className=
|
|
148
|
+
titleContent = <HeadingTag className={ classnames( 'newspack-section-header__title', hiddenText ) }>{ title() }</HeadingTag>;
|
|
138
149
|
}
|
|
139
150
|
|
|
140
151
|
return (
|
|
@@ -166,9 +177,11 @@ const SectionHeader = ( {
|
|
|
166
177
|
) : (
|
|
167
178
|
titleContent
|
|
168
179
|
) }
|
|
169
|
-
{ description && typeof description === 'string' && <p>{ description }</p> }
|
|
170
|
-
{ typeof description === 'function' && <p>{ description() }</p> }
|
|
171
|
-
{ description && typeof description !== 'string' && typeof description !== 'function' &&
|
|
180
|
+
{ description && typeof description === 'string' && <p className={ hiddenText }>{ description }</p> }
|
|
181
|
+
{ typeof description === 'function' && <p className={ hiddenText }>{ description() }</p> }
|
|
182
|
+
{ description && typeof description !== 'string' && typeof description !== 'function' && (
|
|
183
|
+
<p className={ hiddenText }>{ description }</p>
|
|
184
|
+
) }
|
|
172
185
|
{ children && <div className="newspack-section-header__children">{ children }</div> }
|
|
173
186
|
</Grid>
|
|
174
187
|
{ primaryAction && (
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { envelope } from '@wordpress/icons';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* External dependencies
|
|
8
|
+
*/
|
|
9
|
+
import { render } from '@testing-library/react';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies
|
|
13
|
+
*/
|
|
14
|
+
import SectionHeader from '.';
|
|
15
|
+
|
|
16
|
+
describe( 'SectionHeader size', () => {
|
|
17
|
+
it( 'renders a 48px icon and no small modifier by default', () => {
|
|
18
|
+
const { container } = render( <SectionHeader title="Get started" icon={ envelope } /> );
|
|
19
|
+
expect( container.querySelector( '.newspack-section-header--small' ) ).not.toBeInTheDocument();
|
|
20
|
+
expect( container.querySelector( '.newspack-section-header__icon svg' ) ).toHaveAttribute( 'width', '48' );
|
|
21
|
+
} );
|
|
22
|
+
|
|
23
|
+
it( 'renders a 24px icon and the small modifier at size="small"', () => {
|
|
24
|
+
const { container } = render( <SectionHeader title="Get started" icon={ envelope } size="small" /> );
|
|
25
|
+
expect( container.querySelector( '.newspack-section-header--small' ) ).toBeInTheDocument();
|
|
26
|
+
expect( container.querySelector( '.newspack-section-header__icon svg' ) ).toHaveAttribute( 'width', '24' );
|
|
27
|
+
} );
|
|
28
|
+
} );
|