newspack-components 4.1.0 → 4.3.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.
Files changed (135) hide show
  1. package/colors/colors.module.scss +1 -1
  2. package/dist/cjs/action-card/index.js +21 -12
  3. package/dist/cjs/action-card/style.scss +32 -14
  4. package/dist/cjs/autocomplete-tokenfield/index.js +2 -2
  5. package/dist/cjs/autocomplete-with-latest-posts/index.js +289 -0
  6. package/dist/cjs/autocomplete-with-latest-posts/style.scss +150 -0
  7. package/dist/cjs/badge/index.js +32 -0
  8. package/dist/cjs/badge/style.scss +36 -0
  9. package/dist/cjs/button/index.js +2 -0
  10. package/dist/cjs/card/core-card.js +141 -0
  11. package/dist/cjs/card/index.js +33 -0
  12. package/dist/cjs/card/style-core.scss +227 -0
  13. package/dist/cjs/card/style.scss +2 -2
  14. package/dist/cjs/card-settings-group/index.js +49 -0
  15. package/dist/cjs/card-settings-group/style.scss +33 -0
  16. package/dist/cjs/card-sortable-list/index.js +390 -0
  17. package/dist/cjs/card-sortable-list/style.scss +48 -0
  18. package/dist/cjs/confirm-dialog/index.js +59 -0
  19. package/dist/cjs/divider/index.js +42 -0
  20. package/dist/cjs/divider/style.scss +51 -0
  21. package/dist/cjs/form-token-field/style.scss +0 -5
  22. package/dist/cjs/grid/index.js +2 -1
  23. package/dist/cjs/grid/style.scss +63 -9
  24. package/dist/cjs/index.js +42 -0
  25. package/dist/cjs/modal/index.js +11 -4
  26. package/dist/cjs/modal/style.scss +43 -13
  27. package/dist/cjs/newspack-icon/style.scss +5 -3
  28. package/dist/cjs/popover/style.scss +1 -1
  29. package/dist/cjs/section-header/index.js +76 -17
  30. package/dist/cjs/section-header/style.scss +109 -4
  31. package/dist/cjs/style.scss +2 -0
  32. package/dist/cjs/waiting/index.js +3 -1
  33. package/dist/cjs/waiting/style.scss +4 -0
  34. package/dist/cjs/web-preview/index.js +98 -39
  35. package/dist/cjs/web-preview/style.scss +20 -53
  36. package/dist/cjs/with-wizard/index.js +1 -1
  37. package/dist/cjs/with-wizard/style.scss +24 -6
  38. package/dist/cjs/with-wizard-screen/style.scss +39 -10
  39. package/dist/cjs/wizard/components/WizardSnackbar.js +70 -0
  40. package/dist/cjs/wizard/components/style.scss +48 -0
  41. package/dist/cjs/wizard/index.js +97 -16
  42. package/dist/cjs/wizard/store/index.js +46 -0
  43. package/dist/esm/action-card/index.js +21 -12
  44. package/dist/esm/action-card/style.scss +32 -14
  45. package/dist/esm/autocomplete-tokenfield/index.js +2 -2
  46. package/dist/esm/autocomplete-with-latest-posts/index.js +281 -0
  47. package/dist/esm/autocomplete-with-latest-posts/style.scss +150 -0
  48. package/dist/esm/badge/index.js +24 -0
  49. package/dist/esm/badge/style.scss +36 -0
  50. package/dist/esm/button/index.js +2 -0
  51. package/dist/esm/card/core-card.js +133 -0
  52. package/dist/esm/card/index.js +33 -0
  53. package/dist/esm/card/style-core.scss +227 -0
  54. package/dist/esm/card/style.scss +2 -2
  55. package/dist/esm/card-settings-group/index.js +42 -0
  56. package/dist/esm/card-settings-group/style.scss +33 -0
  57. package/dist/esm/card-sortable-list/index.js +381 -0
  58. package/dist/esm/card-sortable-list/style.scss +48 -0
  59. package/dist/esm/confirm-dialog/index.js +49 -0
  60. package/dist/esm/divider/index.js +34 -0
  61. package/dist/esm/divider/style.scss +51 -0
  62. package/dist/esm/form-token-field/style.scss +0 -5
  63. package/dist/esm/grid/index.js +2 -1
  64. package/dist/esm/grid/style.scss +63 -9
  65. package/dist/esm/index.js +6 -0
  66. package/dist/esm/modal/index.js +11 -4
  67. package/dist/esm/modal/style.scss +43 -13
  68. package/dist/esm/newspack-icon/style.scss +5 -3
  69. package/dist/esm/popover/style.scss +1 -1
  70. package/dist/esm/section-header/index.js +75 -18
  71. package/dist/esm/section-header/style.scss +109 -4
  72. package/dist/esm/style.scss +2 -0
  73. package/dist/esm/waiting/index.js +3 -1
  74. package/dist/esm/waiting/style.scss +4 -0
  75. package/dist/esm/web-preview/index.js +101 -42
  76. package/dist/esm/web-preview/style.scss +20 -53
  77. package/dist/esm/with-wizard/index.js +1 -1
  78. package/dist/esm/with-wizard/style.scss +24 -6
  79. package/dist/esm/with-wizard-screen/style.scss +39 -10
  80. package/dist/esm/wizard/components/WizardSnackbar.js +64 -0
  81. package/dist/esm/wizard/components/style.scss +48 -0
  82. package/dist/esm/wizard/index.js +101 -20
  83. package/dist/esm/wizard/store/index.js +46 -0
  84. package/package.json +5 -6
  85. package/shared/author-context.js +26 -0
  86. package/shared/hooks/use-coauthors.js +220 -0
  87. package/shared/hooks/use-coauthors.test.js +624 -0
  88. package/shared/hooks/use-custom-byline.js +47 -0
  89. package/shared/hooks/use-custom-byline.test.js +133 -0
  90. package/shared/scss/_mixins.scss +46 -0
  91. package/src/action-card/action-card.d.ts +7 -3
  92. package/src/action-card/index.js +24 -11
  93. package/src/action-card/style.scss +32 -14
  94. package/src/autocomplete-tokenfield/index.js +2 -2
  95. package/src/autocomplete-with-latest-posts/index.js +290 -0
  96. package/src/autocomplete-with-latest-posts/style.scss +150 -0
  97. package/src/badge/index.tsx +24 -0
  98. package/src/badge/style.scss +36 -0
  99. package/src/button/index.tsx +3 -2
  100. package/src/card/core-card.js +147 -0
  101. package/src/card/index.js +39 -1
  102. package/src/card/style-core.scss +227 -0
  103. package/src/card/style.scss +2 -2
  104. package/src/card-settings-group/README.md +43 -0
  105. package/src/card-settings-group/index.tsx +53 -0
  106. package/src/card-settings-group/style.scss +33 -0
  107. package/src/card-sortable-list/README.md +51 -0
  108. package/src/card-sortable-list/index.tsx +412 -0
  109. package/src/card-sortable-list/style.scss +48 -0
  110. package/src/confirm-dialog/index.tsx +64 -0
  111. package/src/divider/README.md +25 -0
  112. package/src/divider/index.js +31 -0
  113. package/src/divider/style.scss +51 -0
  114. package/src/form-token-field/style.scss +0 -5
  115. package/src/grid/index.tsx +2 -1
  116. package/src/grid/style.scss +63 -9
  117. package/src/index.js +6 -0
  118. package/src/modal/index.js +12 -3
  119. package/src/modal/style.scss +43 -13
  120. package/src/newspack-icon/style.scss +5 -3
  121. package/src/popover/style.scss +1 -1
  122. package/src/section-header/index.js +72 -13
  123. package/src/section-header/style.scss +109 -4
  124. package/src/style.scss +2 -0
  125. package/src/waiting/index.js +2 -1
  126. package/src/waiting/style.scss +4 -0
  127. package/src/web-preview/index.js +90 -35
  128. package/src/web-preview/style.scss +20 -53
  129. package/src/with-wizard/index.js +1 -1
  130. package/src/with-wizard/style.scss +24 -6
  131. package/src/with-wizard-screen/style.scss +39 -10
  132. package/src/wizard/components/WizardSnackbar.js +58 -0
  133. package/src/wizard/components/style.scss +48 -0
  134. package/src/wizard/index.js +108 -14
  135. package/src/wizard/store/index.js +26 -0
package/src/card/index.js CHANGED
@@ -10,6 +10,7 @@ import { Component } from '@wordpress/element';
10
10
  /**
11
11
  * Internal dependencies
12
12
  */
13
+ import CoreCard from './core-card';
13
14
  import './style.scss';
14
15
 
15
16
  /**
@@ -22,7 +23,44 @@ class Card extends Component {
22
23
  * Render
23
24
  */
24
25
  render() {
25
- const { buttonsCard, className, headerActions, isNarrow, isMedium, isSmall, isWhite, noBorder, ...otherProps } = this.props;
26
+ const {
27
+ buttonsCard,
28
+ className,
29
+ headerActions,
30
+ isNarrow,
31
+ isMedium,
32
+ isSmall,
33
+ isWhite,
34
+ noBorder,
35
+ // Pass as `true` to render using WP Core's Card component: https://wordpress.github.io/gutenberg/?path=/docs/components-card--docs
36
+ __experimentalCoreCard,
37
+ // Pass props supported by WP Core's Card component in this single prop.
38
+ __experimentalCoreProps = {
39
+ actionType: null, // chevron | toggle | button | link | none
40
+ header: null, // Pass a React component to render in a CardHeader component.
41
+ icon: null,
42
+ footer: null, // Pass a React component to render in a CardFooter component.
43
+ noMargin: false,
44
+ isDraggable: false,
45
+ dragIndex: null,
46
+ onDragCallback: () => {},
47
+ },
48
+ ...otherProps
49
+ } = this.props;
50
+ if ( __experimentalCoreCard ) {
51
+ const props = {
52
+ buttonsCard,
53
+ className,
54
+ isMedium,
55
+ isNarrow,
56
+ isSmall,
57
+ isWhite,
58
+ noBorder,
59
+ ...otherProps,
60
+ ...__experimentalCoreProps,
61
+ };
62
+ return <CoreCard { ...props } />;
63
+ }
26
64
  const classes = classNames(
27
65
  'newspack-card',
28
66
  className,
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Card using WP Core component
3
+ */
4
+
5
+ @use "~@wordpress/base-styles/colors" as wp-colors;
6
+ @use "../../../colors/colors.module" as colors;
7
+
8
+ .newspack-card--core,
9
+ .newspack-wizard .newspack-card--core {
10
+ background: white;
11
+ position: relative;
12
+ transition: background-color 125ms ease-in-out, box-shadow 125ms ease-in-out, color 125ms ease-in-out;
13
+ svg {
14
+ transition: fill 125ms ease-in-out;
15
+ }
16
+ &__icon {
17
+ border-radius: 50%;
18
+ display: grid;
19
+ height: 48px;
20
+ place-items: center;
21
+ width: 48px;
22
+ svg {
23
+ fill: var(--wp-admin-theme-color);
24
+ height: 40px;
25
+ width: 40px;
26
+ }
27
+ .newspack-card--core__has-icon-background-color & {
28
+ background: var(--wp-admin-theme-color-lighter-10);
29
+ }
30
+ }
31
+ &__is-small {
32
+ h1,
33
+ h2,
34
+ h3,
35
+ h4,
36
+ h5,
37
+ h6 {
38
+ font-size: 14px;
39
+ font-weight: 500;
40
+ }
41
+ .newspack-card--core__icon {
42
+ height: 40px;
43
+ width: 40px;
44
+ svg {
45
+ height: 24px;
46
+ width: 24px;
47
+ }
48
+ }
49
+ }
50
+ &__no-margin .components-card__body {
51
+ padding: 0 !important;
52
+ }
53
+ &__header {
54
+ color: wp-colors.$gray-700;
55
+ column-gap: 16px;
56
+ position: relative;
57
+ .newspack-card--core__action {
58
+ margin: 0;
59
+ label {
60
+ border: 0;
61
+ clip-path: inset(50%);
62
+ height: 1px;
63
+ margin: -1px;
64
+ overflow: hidden;
65
+ padding: 0;
66
+ position: absolute !important;
67
+ width: 1px;
68
+ word-wrap: normal !important;
69
+ }
70
+ }
71
+ .components-dropdown-menu {
72
+ aspect-ratio: 1;
73
+ border-left: 1px solid wp-colors.$gray-200;
74
+ display: grid;
75
+ height: 100%;
76
+ padding: 4px;
77
+ place-items: center;
78
+ position: absolute;
79
+ right: 0;
80
+ top: 0;
81
+ }
82
+ }
83
+ &__header--is-draggable {
84
+ .newspack-card--core__header-content {
85
+ padding-left: 65px;
86
+ }
87
+ .newspack-card--core__header__draggable-controls {
88
+ align-items: center;
89
+ border-right: 1px solid wp-colors.$gray-200;
90
+ display: flex;
91
+ height: 100%;
92
+ justify-content: space-between;
93
+ left: 0;
94
+ padding: 0 8px;
95
+ position: absolute;
96
+ top: 0;
97
+ }
98
+ .newspack-card--core__header__draggable-controls__drag-handle {
99
+ cursor: grab;
100
+ display: grid;
101
+ place-items: center;
102
+ }
103
+ .newspack-card--core__header__draggable-controls__move-buttons {
104
+ display: flex;
105
+ flex-direction: column;
106
+ .components-button.has-icon {
107
+ height: 16px;
108
+ padding: 0;
109
+ width: 100%;
110
+ }
111
+ }
112
+ }
113
+ button.newspack-card--core__header {
114
+ appearance: none;
115
+ background-color: white;
116
+ border: none;
117
+ cursor: pointer;
118
+ text-align: left;
119
+ }
120
+ &__header-content {
121
+ display: grid;
122
+ flex: 1;
123
+ grid-gap: 8px;
124
+ h1,
125
+ h2,
126
+ h3,
127
+ h4,
128
+ h5,
129
+ h6,
130
+ p {
131
+ margin-bottom: 0;
132
+ margin-top: 0;
133
+ transition: color 125ms ease-in-out;
134
+ }
135
+ h1,
136
+ h2,
137
+ h3,
138
+ h4,
139
+ h5,
140
+ h6 {
141
+ align-items: center;
142
+ color: wp-colors.$gray-900;
143
+ font-weight: 500;
144
+ display: flex;
145
+ gap: 8px;
146
+ .newspack-badge {
147
+ font-weight: 400;
148
+ }
149
+ }
150
+ }
151
+ &__is-active {
152
+ border-color: var(--wp-admin-theme-color);
153
+ box-shadow: var(--wp-admin-theme-color) 0 0 0 1px;
154
+ button.newspack-card--core__header {
155
+ background-color: rgba( var(--wp-admin-theme-color--rgb), 0.04 );
156
+ color: var(--wp-admin-theme-color);
157
+ h1,
158
+ h2,
159
+ h3,
160
+ h4,
161
+ h5,
162
+ h6 {
163
+ color: var(--wp-admin-theme-color);
164
+ }
165
+ svg {
166
+ fill: var(--wp-admin-theme-color);
167
+ }
168
+ }
169
+
170
+ &.newspack-card--core__has-children {
171
+ button.newspack-card--core__header {
172
+ border-bottom-left-radius: 0;
173
+ border-bottom-right-radius: 0;
174
+ }
175
+ .newspack-card--core__body {
176
+ border-top: 1px solid var(--wp-admin-theme-color);
177
+ }
178
+ .components-card__divider {
179
+ background: wp-colors.$gray-100;
180
+ }
181
+ }
182
+ }
183
+ &__buttons-card {
184
+ display: block;
185
+ text-decoration: none;
186
+ &:active,
187
+ &:hover {
188
+ border-color: var(--wp-admin-theme-color);
189
+ box-shadow: var(--wp-admin-theme-color) 0 0 0 1px;
190
+ .newspack-card--core__header {
191
+ color: var(--wp-admin-theme-color);
192
+ h1,
193
+ h2,
194
+ h3,
195
+ h4,
196
+ h5,
197
+ h6 {
198
+ color: var(--wp-admin-theme-color);
199
+ }
200
+ svg {
201
+ fill: var(--wp-admin-theme-color);
202
+ }
203
+ }
204
+ }
205
+ }
206
+ hr.components-card__divider {
207
+ margin: 0;
208
+ }
209
+ &__is-narrow {
210
+ margin-left: auto;
211
+ margin-right: auto;
212
+ @media screen and ( min-width: 608px ) {
213
+ max-width: 576px;
214
+ }
215
+ }
216
+ &__body {
217
+ > div:not(.components-card__body):not(.components-card__media):not(.components-card__divider) {
218
+ padding: 16px 24px;
219
+ .newspack-card--core__is-small & {
220
+ padding: 16px;
221
+ }
222
+ .newspack-card--core__no-margin & {
223
+ padding: 0;
224
+ }
225
+ }
226
+ }
227
+ }
@@ -133,11 +133,11 @@
133
133
 
134
134
  // Thematic Break
135
135
 
136
- hr {
136
+ hr:not(.newspack-divider) {
137
137
  background: wp-colors.$gray-300;
138
138
  border: 0;
139
139
  height: 1px;
140
- margin: 48px 0;
140
+ margin: 32px 0;
141
141
 
142
142
  @media screen and ( min-width: 744px ) {
143
143
  margin: 64px 0;
@@ -0,0 +1,43 @@
1
+ # CardSettingsGroup
2
+
3
+ A collapsible settings card that renders a title, optional description, and optional icon in the header. Children are rendered only when the card is active.
4
+
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `actionType` | `'chevron'` \| `'toggle'` \| `'button'` \| `'link'` \| `'none'` | `'chevron'` | Controls the interactive element rendered in the card header. |
10
+ | `children` | `React.ReactNode` | — | Content displayed inside the card body. Only rendered when `isActive` is `true`. |
11
+ | `description` | `string` | `''` | Optional description rendered below the title in the card header. |
12
+ | `icon` | `React.ReactNode` | `null` | Optional icon rendered in the card header with a colored background. |
13
+ | `isActive` | `boolean` | `false` | When `true`, the card is expanded and children are visible. |
14
+ | `onEnable` | `() => void` | `() => {}` | Callback fired when the card header is clicked. Typically used to toggle `isActive`. |
15
+ | `title` | `string` | — | (**Required**) Title rendered in the card header. |
16
+
17
+ ## Usage
18
+
19
+ ```jsx
20
+ import { CardSettingsGroup } from 'newspack-components';
21
+ import { megaphone } from '@wordpress/icons';
22
+
23
+ // Basic collapsible settings group
24
+ <CardSettingsGroup
25
+ title="Email Notifications"
26
+ description="Configure how readers are notified."
27
+ isActive={ isEnabled }
28
+ onEnable={ () => setIsEnabled( ! isEnabled ) }
29
+ >
30
+ <p>Settings content shown when active.</p>
31
+ </CardSettingsGroup>
32
+
33
+ // With an icon and toggle action type
34
+ <CardSettingsGroup
35
+ actionType="toggle"
36
+ icon={ megaphone }
37
+ title="Push Notifications"
38
+ isActive={ isEnabled }
39
+ onEnable={ () => setIsEnabled( ! isEnabled ) }
40
+ >
41
+ <p>Settings content shown when active.</p>
42
+ </CardSettingsGroup>
43
+ ```
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Card - Settings group component.
3
+ */
4
+
5
+ /**
6
+ * Internal dependencies
7
+ */
8
+ import { Card } from '../';
9
+ import './style.scss';
10
+
11
+ const CardSettingsGroup = ( {
12
+ actionType = 'chevron',
13
+ children,
14
+ icon = null,
15
+ title = '',
16
+ description = '',
17
+ isActive = false,
18
+ onEnable = () => {},
19
+ }: {
20
+ actionType?: 'chevron' | 'toggle' | 'button' | 'link' | 'none';
21
+ children?: React.ReactNode;
22
+ icon?: React.ReactNode;
23
+ title: string;
24
+ description?: string;
25
+ isActive?: boolean;
26
+ onEnable?: () => void;
27
+ } ) => {
28
+ return (
29
+ <Card
30
+ className="newspack-card--core--settings-group"
31
+ actionType={ actionType }
32
+ isSmall
33
+ __experimentalCoreCard
34
+ __experimentalCoreProps={ {
35
+ header: (
36
+ <>
37
+ <h3>{ title }</h3>
38
+ { description && <p>{ description }</p> }
39
+ </>
40
+ ),
41
+ onHeaderClick: onEnable,
42
+ icon,
43
+ iconBackgroundColor: true,
44
+ isActive,
45
+ title,
46
+ } }
47
+ >
48
+ { isActive && children }
49
+ </Card>
50
+ );
51
+ };
52
+
53
+ export default CardSettingsGroup;
@@ -0,0 +1,33 @@
1
+ .newspack-card--core--settings-group {
2
+ .components-card__body {
3
+ > .newspack-notice {
4
+ margin: 16px 0;
5
+ }
6
+ > .components-base-control {
7
+ &:first-child {
8
+ margin-top: 0;
9
+ }
10
+ + .components-base-control,
11
+ + .newspack-form-token-field {
12
+ margin-top: 16px;
13
+ }
14
+ }
15
+
16
+ /** ToggleControl switch should appear after the label. */
17
+ > .components-toggle-control {
18
+ .components-h-stack {
19
+ .components-form-toggle {
20
+ order: 2;
21
+ }
22
+ }
23
+ .components-toggle-control__help {
24
+ margin-inline-start: auto;
25
+ }
26
+ }
27
+ .newspack-grid:last-child,
28
+ .components-base-control:last-child,
29
+ p:last-child {
30
+ margin-bottom: 0;
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,51 @@
1
+ # CardSortableList
2
+
3
+ A drag-and-drop sortable list of cards. Each item displays a title and a status badge. Items can be reordered by dragging with a pointer or by using the up/down chevron buttons (keyboard accessible). The list locks its height during a drag to prevent layout shifts.
4
+
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ |------|------|---------|-------------|
9
+ | `disabled` | `boolean` | `false` | When `true`, all drag and button controls are disabled via `Disabled`. |
10
+ | `items` | `DraggableItem[]` | `[]` | Array of items to render. See the `DraggableItem` shape below. |
11
+ | `onDragCallback` | `(index: number, targetIndex: number) => void` | `() => {}` | Callback fired after a reorder completes (drag-and-drop or button move). Receives the original index and the new index. |
12
+
13
+ ### `DraggableItem`
14
+
15
+ | Field | Type | Description |
16
+ |-------|------|-------------|
17
+ | `id` | `string` \| `number` | Unique identifier for the item. Used as the React `key`. |
18
+ | `title` | `string` | Label rendered in the card header. |
19
+ | `badgeLevel` | `'default'` \| `'success'` \| `'info'` \| `'warning'` \| `'error'` | Visual style of the status badge. |
20
+ | `badgeText` | `string` | Text displayed inside the badge. |
21
+
22
+ ## Usage
23
+
24
+ ```jsx
25
+ import { CardSortableList } from 'newspack-components';
26
+
27
+ const [ items, setItems ] = useState( [
28
+ { id: 1, title: 'Homepage', badgeLevel: 'success', badgeText: 'Active' },
29
+ { id: 2, title: 'About', badgeLevel: 'default', badgeText: 'Draft' },
30
+ { id: 3, title: 'Contact', badgeLevel: 'warning', badgeText: 'Review' },
31
+ ] );
32
+
33
+ const handleReorder = ( fromIndex, toIndex ) => {
34
+ const reordered = [ ...items ];
35
+ const [ moved ] = reordered.splice( fromIndex, 1 );
36
+ reordered.splice( toIndex, 0, moved );
37
+ setItems( reordered );
38
+ };
39
+
40
+ <CardSortableList
41
+ items={ items }
42
+ onDragCallback={ handleReorder }
43
+ />
44
+
45
+ // Disabled state (controls are rendered but non-interactive)
46
+ <CardSortableList
47
+ items={ items }
48
+ disabled={ true }
49
+ onDragCallback={ handleReorder }
50
+ />
51
+ ```