@automattic/jetpack-components 3.3.0 → 4.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.
Files changed (33) hide show
  1. package/CHANGELOG.md +13 -3
  2. package/build/components/admin-page/style.module.scss +2 -2
  3. package/build/components/copy-to-clipboard/index.js +1 -1
  4. package/build/components/diff-viewer/index.d.ts +2 -1
  5. package/build/components/gravatar/index.d.ts +1 -0
  6. package/build/components/jetpack-footer/style.scss +2 -5
  7. package/build/components/theme-provider/index.js +1 -1
  8. package/build/index.d.ts +0 -2
  9. package/build/index.js +0 -2
  10. package/components/admin-page/style.module.scss +2 -2
  11. package/components/copy-to-clipboard/index.tsx +2 -2
  12. package/components/diff-viewer/index.tsx +1 -0
  13. package/components/gravatar/index.tsx +1 -0
  14. package/components/jetpack-footer/style.scss +2 -5
  15. package/components/jitm-slot/index.tsx +1 -1
  16. package/components/theme-provider/index.tsx +1 -1
  17. package/index.ts +0 -2
  18. package/package.json +5 -5
  19. package/build/components/notice/index.d.ts +0 -29
  20. package/build/components/notice/index.js +0 -35
  21. package/build/components/notice/style.module.scss +0 -120
  22. package/build/components/zendesk-chat/constants.d.ts +0 -1
  23. package/build/components/zendesk-chat/constants.js +0 -2
  24. package/build/components/zendesk-chat/index.d.ts +0 -3
  25. package/build/components/zendesk-chat/index.js +0 -27
  26. package/build/components/zendesk-chat/types.d.ts +0 -11
  27. package/build/components/zendesk-chat/types.js +0 -1
  28. package/components/notice/index.tsx +0 -93
  29. package/components/notice/style.module.scss +0 -120
  30. package/components/zendesk-chat/README.md +0 -25
  31. package/components/zendesk-chat/constants.ts +0 -2
  32. package/components/zendesk-chat/index.tsx +0 -34
  33. package/components/zendesk-chat/types.ts +0 -14
package/CHANGELOG.md CHANGED
@@ -2,17 +2,26 @@
2
2
 
3
3
  ### This is a list detailing changes for the Jetpack RNA Components package releases.
4
4
 
5
+ ## [4.0.0] - 2026-10-05
6
+ ### Changed
7
+ - Update package dependencies. [#52999]
8
+
9
+ ### Removed
10
+ - Remove the Notice component; use Notice from @wordpress/ui instead. [#52932]
11
+ - Remove the unused ZendeskChat component. [#52074]
12
+
5
13
  ## [3.3.0] - 2026-09-28
6
14
  ### Added
7
- - Add a JitmSlot component so every dashboard renders the Jetpack in-dashboard message slot the same way, and keeps the message across route changes. [#52641]
15
+ - Add a `JitmSlot` component that renders the Jetpack in-dashboard message slot and keeps the message across route changes. [#52641]
8
16
  - IconTooltip: Add a `label` prop to give the icon trigger an accessible name. [#52800]
9
17
 
10
18
  ### Changed
11
- - IconTooltip: Keep focus on the trigger when a tooltip opens, announce its content to screen readers, and show the trigger's focus ring the way other WordPress buttons do. [#52736]
19
+ - IconTooltip: Keep focus on the trigger when a tooltip opens, and announce its content to screen readers. [#52736]
20
+ - IconTooltip: Show the trigger's focus ring the way other WordPress buttons do. [#52736]
12
21
  - Use logical CSS properties so layouts mirror in right-to-left languages. [#52749]
13
22
 
14
23
  ### Deprecated
15
- - Deprecate GlobalNotices and useGlobalNotices. Use SnackbarNotices from @wordpress/notices instead. [#52193]
24
+ - Deprecate `GlobalNotices` and `useGlobalNotices`. Use `SnackbarNotices` from `@wordpress/notices` instead. [#52193]
16
25
 
17
26
  ### Fixed
18
27
  - IconTooltip: Close a tooltip opened on hover when Escape is pressed, without moving focus. [#52799]
@@ -1978,6 +1987,7 @@
1978
1987
  ### Changed
1979
1988
  - Update node version requirement to 14.16.1
1980
1989
 
1990
+ [4.0.0]: https://github.com/Automattic/jetpack-components/compare/3.3.0...4.0.0
1981
1991
  [3.3.0]: https://github.com/Automattic/jetpack-components/compare/3.2.0...3.3.0
1982
1992
  [3.2.0]: https://github.com/Automattic/jetpack-components/compare/3.1.2...3.2.0
1983
1993
  [3.1.2]: https://github.com/Automattic/jetpack-components/compare/3.1.1...3.1.2
@@ -105,9 +105,9 @@
105
105
  // We override only the bits that need to differ from those defaults.
106
106
  float: none;
107
107
  text-align: end;
108
- background: var(--wpds-color-background-surface-neutral-strong, #fff);
108
+ background: var(--wpds-color-background-surface-neutral-strong);
109
109
  font-style: italic;
110
- color: var(--wpds-color-foreground-content-neutral-weak, #87a6bc);
110
+ color: var(--wpds-color-foreground-content-neutral-weak);
111
111
  border-bottom: none;
112
112
 
113
113
  @media (max-width: 659px) {
@@ -6,7 +6,7 @@ import Button from '../button/index.js';
6
6
  import { ClipboardIcon, CheckmarkIcon } from '../icons/index.js';
7
7
  export const CopyToClipboard = ({ buttonStyle = 'icon', textToCopy, onCopy, ...buttonProps }) => {
8
8
  const [hasCopied, setHasCopied] = useState(false);
9
- const copyTimer = useRef();
9
+ const copyTimer = useRef(undefined);
10
10
  const copyRef = useCopyToClipboard(textToCopy, () => {
11
11
  if (copyTimer.current) {
12
12
  clearTimeout(copyTimer.current);
@@ -1,4 +1,5 @@
1
+ import type { JSX } from 'react';
1
2
  export declare const DiffViewer: ({ diff }: {
2
3
  diff: any;
3
- }) => import("react").JSX.Element;
4
+ }) => JSX.Element;
4
5
  export default DiffViewer;
@@ -1,5 +1,6 @@
1
1
  import '@gravatar-com/hovercards/dist/style.css';
2
2
  import './style.scss';
3
+ import type { JSX } from 'react';
3
4
  /**
4
5
  * Gravatar `defaultImage` styles, mirroring https://docs.gravatar.com/sdk/images/#default-image
5
6
  */
@@ -1,10 +1,7 @@
1
- @use "sass:meta";
2
- @include meta.load-css("pkg:@wordpress/theme/design-tokens.css");
3
-
4
1
  .jetpack-footer {
5
- border-top: var(--wpds-border-width-xs, 1px) solid var(--wpds-color-stroke-surface-neutral-weak, #e0e0e0);
2
+ border-top: var(--wpds-border-width-xs) solid var(--wpds-color-stroke-surface-neutral-weak);
6
3
  box-sizing: border-box;
7
- font-size: var(--wpds-typography-font-size-md, 13px);
4
+ font-size: var(--wpds-typography-font-size-md);
8
5
  padding: var(--wpds-dimension-padding-xl) var(--wpds-dimension-padding-2xl);
9
6
  width: 100%;
10
7
  display: flex;
@@ -105,7 +105,7 @@ const setup = (root, id, withGlobalStyles) => {
105
105
  * @return {ReactNode} ThemeProvider component.
106
106
  */
107
107
  const ThemeProvider = ({ children = null, targetDom, id, withGlobalStyles = true, }) => {
108
- const themeWrapperRef = useRef();
108
+ const themeWrapperRef = useRef(undefined);
109
109
  // Check whether the theme provider instance is already registered.
110
110
  const isAlreadyProvided = globalThemeInstances?.[id]?.provided;
111
111
  useLayoutEffect(() => {
package/build/index.d.ts CHANGED
@@ -37,11 +37,9 @@ export { default as ProductPrice } from './components/product-price/index.tsx';
37
37
  export { default as DotPager } from './components/dot-pager/index.tsx';
38
38
  export { default as DonutMeter } from './components/donut-meter/index.tsx';
39
39
  export { default as RecordMeterBar } from './components/record-meter-bar/index.tsx';
40
- export { default as Notice } from './components/notice/index.tsx';
41
40
  export { default as Popover } from './components/popover/index.tsx';
42
41
  export { default as IndeterminateProgressBar } from './components/indeterminate-progress-bar/index.tsx';
43
42
  export { default as ActionPopover } from './components/action-popover/index.tsx';
44
- export { default as ZendeskChat } from './components/zendesk-chat/index.tsx';
45
43
  export { default as ProgressBar } from './components/progress-bar/index.tsx';
46
44
  export { default as UpsellBanner } from './components/upsell-banner/index.tsx';
47
45
  export { getUserLocale, cleanLocale } from './lib/locale/index.ts';
package/build/index.js CHANGED
@@ -49,11 +49,9 @@ export { default as ProductPrice } from './components/product-price/index.js';
49
49
  export { default as DotPager } from './components/dot-pager/index.js';
50
50
  export { default as DonutMeter } from './components/donut-meter/index.js';
51
51
  export { default as RecordMeterBar } from './components/record-meter-bar/index.js';
52
- export { default as Notice } from './components/notice/index.js';
53
52
  export { default as Popover } from './components/popover/index.js';
54
53
  export { default as IndeterminateProgressBar } from './components/indeterminate-progress-bar/index.js';
55
54
  export { default as ActionPopover } from './components/action-popover/index.js';
56
- export { default as ZendeskChat } from './components/zendesk-chat/index.js';
57
55
  export { default as ProgressBar } from './components/progress-bar/index.js';
58
56
  export { default as UpsellBanner } from './components/upsell-banner/index.js';
59
57
  export { getUserLocale, cleanLocale } from './lib/locale/index.js';
@@ -105,9 +105,9 @@
105
105
  // We override only the bits that need to differ from those defaults.
106
106
  float: none;
107
107
  text-align: end;
108
- background: var(--wpds-color-background-surface-neutral-strong, #fff);
108
+ background: var(--wpds-color-background-surface-neutral-strong);
109
109
  font-style: italic;
110
- color: var(--wpds-color-foreground-content-neutral-weak, #87a6bc);
110
+ color: var(--wpds-color-foreground-content-neutral-weak);
111
111
  border-bottom: none;
112
112
 
113
113
  @media (max-width: 659px) {
@@ -4,7 +4,7 @@ import { __ } from '@wordpress/i18n';
4
4
  import Button from '../button/index.tsx';
5
5
  import { ClipboardIcon, CheckmarkIcon } from '../icons/index.tsx';
6
6
  import { CopyToClipboardProps } from './types.ts';
7
- import type { FC } from 'react';
7
+ import type { JSX, FC } from 'react';
8
8
 
9
9
  export const CopyToClipboard: FC< CopyToClipboardProps > = ( {
10
10
  buttonStyle = 'icon',
@@ -14,7 +14,7 @@ export const CopyToClipboard: FC< CopyToClipboardProps > = ( {
14
14
  } ) => {
15
15
  const [ hasCopied, setHasCopied ] = useState( false );
16
16
 
17
- const copyTimer = useRef< ReturnType< typeof setTimeout > | undefined >();
17
+ const copyTimer = useRef< ReturnType< typeof setTimeout > | undefined >( undefined );
18
18
 
19
19
  const copyRef = useCopyToClipboard( textToCopy, () => {
20
20
  if ( copyTimer.current ) {
@@ -2,6 +2,7 @@ import { Fragment } from 'react';
2
2
  import parseFilename from './parse-filename.ts';
3
3
  import parsePatch from './parse-patch.ts';
4
4
  import styles from './styles.module.scss';
5
+ import type { JSX } from 'react';
5
6
 
6
7
  const filename = ( {
7
8
  oldFileName,
@@ -8,6 +8,7 @@ import { __ } from '@wordpress/i18n';
8
8
  import clsx from 'clsx';
9
9
  import { sha256 } from 'js-sha256';
10
10
  import './style.scss';
11
+ import type { JSX } from 'react';
11
12
 
12
13
  /**
13
14
  * Gravatar `defaultImage` styles, mirroring https://docs.gravatar.com/sdk/images/#default-image
@@ -1,10 +1,7 @@
1
- @use "sass:meta";
2
- @include meta.load-css("pkg:@wordpress/theme/design-tokens.css");
3
-
4
1
  .jetpack-footer {
5
- border-top: var(--wpds-border-width-xs, 1px) solid var(--wpds-color-stroke-surface-neutral-weak, #e0e0e0);
2
+ border-top: var(--wpds-border-width-xs) solid var(--wpds-color-stroke-surface-neutral-weak);
6
3
  box-sizing: border-box;
7
- font-size: var(--wpds-typography-font-size-md, 13px);
4
+ font-size: var(--wpds-typography-font-size-md);
8
5
  padding: var(--wpds-dimension-padding-xl) var(--wpds-dimension-padding-2xl);
9
6
  width: 100%;
10
7
  display: flex;
@@ -2,7 +2,7 @@ import clsx from 'clsx';
2
2
  import { useLayoutEffect, useRef } from 'react';
3
3
  import './style.scss';
4
4
  import type { JitmSlotProps } from './types.ts';
5
- import type { FC } from 'react';
5
+ import type { JSX, FC } from 'react';
6
6
 
7
7
  const NOTICES_ID = 'jp-admin-notices';
8
8
 
@@ -121,7 +121,7 @@ const ThemeProvider: FC< ThemeProviderProps > = ( {
121
121
  id,
122
122
  withGlobalStyles = true,
123
123
  } ) => {
124
- const themeWrapperRef = useRef< HTMLDivElement >();
124
+ const themeWrapperRef = useRef< HTMLDivElement >( undefined );
125
125
 
126
126
  // Check whether the theme provider instance is already registered.
127
127
  const isAlreadyProvided = globalThemeInstances?.[ id ]?.provided;
package/index.ts CHANGED
@@ -57,11 +57,9 @@ export { default as ProductPrice } from './components/product-price/index.tsx';
57
57
  export { default as DotPager } from './components/dot-pager/index.tsx';
58
58
  export { default as DonutMeter } from './components/donut-meter/index.tsx';
59
59
  export { default as RecordMeterBar } from './components/record-meter-bar/index.tsx';
60
- export { default as Notice } from './components/notice/index.tsx';
61
60
  export { default as Popover } from './components/popover/index.tsx';
62
61
  export { default as IndeterminateProgressBar } from './components/indeterminate-progress-bar/index.tsx';
63
62
  export { default as ActionPopover } from './components/action-popover/index.tsx';
64
- export { default as ZendeskChat } from './components/zendesk-chat/index.tsx';
65
63
  export { default as ProgressBar } from './components/progress-bar/index.tsx';
66
64
  export { default as UpsellBanner } from './components/upsell-banner/index.tsx';
67
65
  export { getUserLocale, cleanLocale } from './lib/locale/index.ts';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/jetpack-components",
3
- "version": "3.3.0",
3
+ "version": "4.0.0",
4
4
  "description": "Jetpack Components Package",
5
5
  "homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/components/#readme",
6
6
  "bugs": {
@@ -76,8 +76,8 @@
76
76
  "extends @wordpress/browserslist-config"
77
77
  ],
78
78
  "dependencies": {
79
- "@automattic/jetpack-api": "^2.0.0",
80
- "@automattic/jetpack-boost-score-api": "^1.1.0",
79
+ "@automattic/jetpack-api": "^2.1.0",
80
+ "@automattic/jetpack-boost-score-api": "^1.2.0",
81
81
  "@automattic/jetpack-script-data": "^0.6.8",
82
82
  "@automattic/number-formatters": "^1.2.10",
83
83
  "@babel/runtime": "^7",
@@ -105,7 +105,7 @@
105
105
  "uplot-react": "1.1.4"
106
106
  },
107
107
  "devDependencies": {
108
- "@automattic/jetpack-base-styles": "^1.2.15",
108
+ "@automattic/jetpack-base-styles": "^1.2.16",
109
109
  "@babel/core": "7.29.7",
110
110
  "@jest/globals": "30.5.1",
111
111
  "@storybook/addon-docs": "10.4.6",
@@ -124,7 +124,7 @@
124
124
  "storybook": "10.4.6",
125
125
  "ts-dedent": "2.2.0",
126
126
  "typescript": "6.0.3",
127
- "webpack": "5.107.2",
127
+ "webpack": "5.111.1",
128
128
  "webpack-cli": "7.2.1"
129
129
  },
130
130
  "peerDependencies": {
@@ -1,29 +0,0 @@
1
- import type { FC, ReactNode } from 'react';
2
- type NoticeProps = {
3
- /** The severity of the alert. */
4
- level?: 'error' | 'warning' | 'info' | 'success';
5
- /** The title of the notice */
6
- title?: string;
7
- /** A list of action elements to show across the bottom */
8
- actions?: ReactNode[];
9
- /** Hide close button */
10
- hideCloseButton?: boolean;
11
- /** Method to call when the close button is clicked */
12
- onClose?: () => void;
13
- /** Children to be rendered inside the alert. */
14
- children: ReactNode;
15
- };
16
- /**
17
- * Notice component
18
- *
19
- * @param {object} props - The component properties.
20
- * @param {string} props.level - The notice level: error, warning, info, success.
21
- * @param {boolean} props.hideCloseButton - Whether to hide the close button.
22
- * @param {Function} props.onClose - The function to call when the close button is clicked.
23
- * @param {string} props.title - The title of the notice.
24
- * @param {ReactNode[]} props.actions - Actions to show across the bottom of the bar.
25
- * @param {Component} props.children - The notice content.
26
- * @return {ReactElement} The `Notice` component.
27
- */
28
- declare const Notice: FC<NoticeProps>;
29
- export default Notice;
@@ -1,35 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Icon, cautionFilled as warning, info, check, close } from '@wordpress/icons';
3
- import clsx from 'clsx';
4
- import styles from './style.module.scss';
5
- const getIconByLevel = (level) => {
6
- switch (level) {
7
- case 'error':
8
- return warning;
9
- case 'warning':
10
- return warning;
11
- case 'info':
12
- return info;
13
- case 'success':
14
- return check;
15
- default:
16
- return warning;
17
- }
18
- };
19
- /**
20
- * Notice component
21
- *
22
- * @param {object} props - The component properties.
23
- * @param {string} props.level - The notice level: error, warning, info, success.
24
- * @param {boolean} props.hideCloseButton - Whether to hide the close button.
25
- * @param {Function} props.onClose - The function to call when the close button is clicked.
26
- * @param {string} props.title - The title of the notice.
27
- * @param {ReactNode[]} props.actions - Actions to show across the bottom of the bar.
28
- * @param {Component} props.children - The notice content.
29
- * @return {ReactElement} The `Notice` component.
30
- */
31
- const Notice = ({ level = 'info', title, children, actions, hideCloseButton = false, onClose, }) => {
32
- const classes = clsx(styles.container, styles[`is-${level}`]);
33
- return (_jsxs("div", { className: classes, children: [_jsx("div", { className: styles['icon-wrapper'], children: _jsx(Icon, { icon: getIconByLevel(level), className: styles.icon }) }), _jsxs("div", { className: styles['main-content'], children: [title && _jsx("div", { className: styles.title, children: title }), children, actions && actions.length > 0 && (_jsx("div", { className: styles['action-bar'], children: actions.map((action, index) => (_jsx("div", { className: styles.action, children: action }, index))) }))] }), !hideCloseButton && (_jsx("button", { "aria-label": "close", className: styles['close-button'], onClick: onClose, children: _jsx(Icon, { icon: close }) }))] }));
34
- };
35
- export default Notice;
@@ -1,120 +0,0 @@
1
- .container {
2
- display: flex;
3
- align-items: flex-start;
4
-
5
- font-size: var(--font-body);
6
-
7
- border: 1px solid var(--jp-black);
8
- border-radius: 4px;
9
- border-color: var(--jp-gray-5);
10
- border-left-width: 6px;
11
-
12
- padding: 24px 31px 27px 18px;
13
- }
14
-
15
- .icon-wrapper {
16
- margin-right: 20px;
17
- width: calc(var(--spacing-base) * 3);
18
- height: calc(var(--spacing-base) * 3);
19
- }
20
-
21
- .close-button {
22
- padding: 0;
23
- background-color: transparent;
24
- border: none;
25
- cursor: pointer;
26
- outline: none;
27
-
28
- svg {
29
- display: block;
30
- }
31
- }
32
-
33
- // Mobile layout differences.
34
- @media screen and ( max-width: 600px ) {
35
-
36
- .container {
37
- position: relative;
38
- padding-top: 68px;
39
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.03), 0 1px 2px rgba(0, 0, 0, 0.06);
40
- }
41
-
42
- .icon-wrapper {
43
- position: absolute;
44
- top: 24px;
45
- left: 24px;
46
- }
47
-
48
- .close-button {
49
- position: absolute;
50
- top: 24px;
51
- right: 24px;
52
- }
53
- }
54
-
55
- .main-content {
56
- flex-grow: 1;
57
- }
58
-
59
- .title {
60
- font-weight: 600;
61
- margin-bottom: 8px;
62
- }
63
-
64
- .action-bar {
65
- display: flex;
66
- align-items: center;
67
- margin-top: 20px;
68
- row-gap: 20px;
69
- flex-wrap: wrap;
70
-
71
- @media screen and ( max-width: 600px ) {
72
- justify-content: center;
73
- }
74
-
75
- a {
76
-
77
- &,
78
- &:hover,
79
- &:active,
80
- &:focus {
81
- color: var(--jp-black);
82
- }
83
- }
84
-
85
- > * {
86
- margin-right: 24px;
87
- }
88
- }
89
-
90
- .is-error {
91
- border-left-color: var(--jp-red);
92
-
93
- .icon {
94
- color: var(--jp-red);
95
- }
96
- }
97
-
98
- .is-warning {
99
- border-left-color: var(--jp-yellow-20);
100
-
101
- .icon {
102
- color: var(--jp-yellow-20);
103
- }
104
- }
105
-
106
- .is-info {
107
- border-left-color: var(--black);
108
-
109
- .icon {
110
- color: var(--black);
111
- }
112
- }
113
-
114
- .is-success {
115
- border-left-color: var(--jp-green);
116
-
117
- .icon {
118
- color: var(--jp-green);
119
- }
120
- }
@@ -1 +0,0 @@
1
- export declare const chatKey = "d729d42c-b547-4750-a6f6-8b30534a5f12";
@@ -1,2 +0,0 @@
1
- // This is not a secret, it can easily be found in the DOM
2
- export const chatKey = 'd729d42c-b547-4750-a6f6-8b30534a5f12';
@@ -1,3 +0,0 @@
1
- import type { ZendeskChatType } from './types.ts';
2
- export declare const ZendeskChat: ZendeskChatType;
3
- export default ZendeskChat;
@@ -1,27 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useEffect, useCallback } from 'react';
3
- import { chatKey } from './constants.js';
4
- export const ZendeskChat = ({ jwt_token }) => {
5
- const authenticateUser = useCallback(() => {
6
- if (typeof window !== 'undefined' && typeof window.zE === 'function') {
7
- window.zE('messenger', 'loginUser', function (callback) {
8
- callback(jwt_token);
9
- });
10
- }
11
- }, [jwt_token]);
12
- useEffect(() => {
13
- const script = document.createElement('script');
14
- const container = document.getElementById('zendesk-chat-container');
15
- script.src = 'https://static.zdassets.com/ekr/snippet.js?key=' + encodeURIComponent(chatKey);
16
- script.type = 'text/javascript';
17
- script.id = 'ze-snippet';
18
- script.onload = () => {
19
- authenticateUser();
20
- };
21
- if (container) {
22
- container.appendChild(script);
23
- }
24
- }, [authenticateUser]);
25
- return _jsx("div", { "data-testid": "zendesk-chat-container", id: "zendesk-chat-container" });
26
- };
27
- export default ZendeskChat;
@@ -1,11 +0,0 @@
1
- import type { FC } from 'react';
2
- declare global {
3
- interface Window {
4
- zE: Function;
5
- }
6
- }
7
- interface ZendeskChatProps {
8
- jwt_token: string;
9
- }
10
- export type ZendeskChatType = FC<ZendeskChatProps>;
11
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1,93 +0,0 @@
1
- import { Icon, cautionFilled as warning, info, check, close } from '@wordpress/icons';
2
- import clsx from 'clsx';
3
- import styles from './style.module.scss';
4
- import type { Component, FC, ReactElement, ReactNode } from 'react';
5
-
6
- type NoticeProps = {
7
- /** The severity of the alert. */
8
- level?: 'error' | 'warning' | 'info' | 'success';
9
-
10
- /** The title of the notice */
11
- title?: string;
12
-
13
- /** A list of action elements to show across the bottom */
14
- actions?: ReactNode[];
15
-
16
- /** Hide close button */
17
- hideCloseButton?: boolean;
18
-
19
- /** Method to call when the close button is clicked */
20
- onClose?: () => void;
21
-
22
- /** Children to be rendered inside the alert. */
23
- children: ReactNode;
24
- };
25
-
26
- const getIconByLevel = ( level: NoticeProps[ 'level' ] ) => {
27
- switch ( level ) {
28
- case 'error':
29
- return warning;
30
- case 'warning':
31
- return warning;
32
- case 'info':
33
- return info;
34
- case 'success':
35
- return check;
36
- default:
37
- return warning;
38
- }
39
- };
40
-
41
- /**
42
- * Notice component
43
- *
44
- * @param {object} props - The component properties.
45
- * @param {string} props.level - The notice level: error, warning, info, success.
46
- * @param {boolean} props.hideCloseButton - Whether to hide the close button.
47
- * @param {Function} props.onClose - The function to call when the close button is clicked.
48
- * @param {string} props.title - The title of the notice.
49
- * @param {ReactNode[]} props.actions - Actions to show across the bottom of the bar.
50
- * @param {Component} props.children - The notice content.
51
- * @return {ReactElement} The `Notice` component.
52
- */
53
- const Notice: FC< NoticeProps > = ( {
54
- level = 'info',
55
- title,
56
- children,
57
- actions,
58
- hideCloseButton = false,
59
- onClose,
60
- } ) => {
61
- const classes = clsx( styles.container, styles[ `is-${ level }` ] );
62
-
63
- return (
64
- <div className={ classes }>
65
- <div className={ styles[ 'icon-wrapper' ] }>
66
- <Icon icon={ getIconByLevel( level ) } className={ styles.icon } />
67
- </div>
68
-
69
- <div className={ styles[ 'main-content' ] }>
70
- { title && <div className={ styles.title }>{ title }</div> }
71
- { children }
72
-
73
- { actions && actions.length > 0 && (
74
- <div className={ styles[ 'action-bar' ] }>
75
- { actions.map( ( action, index ) => (
76
- <div key={ index } className={ styles.action }>
77
- { action }
78
- </div>
79
- ) ) }
80
- </div>
81
- ) }
82
- </div>
83
-
84
- { ! hideCloseButton && (
85
- <button aria-label="close" className={ styles[ 'close-button' ] } onClick={ onClose }>
86
- <Icon icon={ close } />
87
- </button>
88
- ) }
89
- </div>
90
- );
91
- };
92
-
93
- export default Notice;
@@ -1,120 +0,0 @@
1
- .container {
2
- display: flex;
3
- align-items: flex-start;
4
-
5
- font-size: var(--font-body);
6
-
7
- border: 1px solid var(--jp-black);
8
- border-radius: 4px;
9
- border-color: var(--jp-gray-5);
10
- border-left-width: 6px;
11
-
12
- padding: 24px 31px 27px 18px;
13
- }
14
-
15
- .icon-wrapper {
16
- margin-right: 20px;
17
- width: calc(var(--spacing-base) * 3);
18
- height: calc(var(--spacing-base) * 3);
19
- }
20
-
21
- .close-button {
22
- padding: 0;
23
- background-color: transparent;
24
- border: none;
25
- cursor: pointer;
26
- outline: none;
27
-
28
- svg {
29
- display: block;
30
- }
31
- }
32
-
33
- // Mobile layout differences.
34
- @media screen and ( max-width: 600px ) {
35
-
36
- .container {
37
- position: relative;
38
- padding-top: 68px;
39
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.03), 0 1px 2px rgba(0, 0, 0, 0.06);
40
- }
41
-
42
- .icon-wrapper {
43
- position: absolute;
44
- top: 24px;
45
- left: 24px;
46
- }
47
-
48
- .close-button {
49
- position: absolute;
50
- top: 24px;
51
- right: 24px;
52
- }
53
- }
54
-
55
- .main-content {
56
- flex-grow: 1;
57
- }
58
-
59
- .title {
60
- font-weight: 600;
61
- margin-bottom: 8px;
62
- }
63
-
64
- .action-bar {
65
- display: flex;
66
- align-items: center;
67
- margin-top: 20px;
68
- row-gap: 20px;
69
- flex-wrap: wrap;
70
-
71
- @media screen and ( max-width: 600px ) {
72
- justify-content: center;
73
- }
74
-
75
- a {
76
-
77
- &,
78
- &:hover,
79
- &:active,
80
- &:focus {
81
- color: var(--jp-black);
82
- }
83
- }
84
-
85
- > * {
86
- margin-right: 24px;
87
- }
88
- }
89
-
90
- .is-error {
91
- border-left-color: var(--jp-red);
92
-
93
- .icon {
94
- color: var(--jp-red);
95
- }
96
- }
97
-
98
- .is-warning {
99
- border-left-color: var(--jp-yellow-20);
100
-
101
- .icon {
102
- color: var(--jp-yellow-20);
103
- }
104
- }
105
-
106
- .is-info {
107
- border-left-color: var(--black);
108
-
109
- .icon {
110
- color: var(--black);
111
- }
112
- }
113
-
114
- .is-success {
115
- border-left-color: var(--jp-green);
116
-
117
- .icon {
118
- color: var(--jp-green);
119
- }
120
- }
@@ -1,25 +0,0 @@
1
- # Summary
2
-
3
- This component adds a Zendesk chat widget via <script> tag to any page the componet is added to
4
-
5
- WARNING: If you add this to a specific site, it will stay on the page until the browser reloads onto a page that does not load this widget. For example, if a section of the plugin is using `react-router`, and the widget is loaded onto one specific route, it will not go away when a new route is taken since the page is not reloaded
6
-
7
- ## Usage
8
-
9
- ```tsx
10
- import { ZendeskChat } from '@automattic/jetpack-components';
11
-
12
- const ExampleComponent = () => (
13
- <ZendeskChat />
14
- );
15
- ```
16
-
17
- ## Props
18
-
19
- None
20
-
21
- Because the chat is conditionally rendered based on Date and Time, no props are needed in order to render correctly.
22
-
23
- ## Note
24
-
25
- There is a wpcom/v2 API endpoint `/presales/chat?group=jp_presales` that returns whether or not chat is available at this time. This should be used when determining whether or not to render this component.
@@ -1,2 +0,0 @@
1
- // This is not a secret, it can easily be found in the DOM
2
- export const chatKey = 'd729d42c-b547-4750-a6f6-8b30534a5f12';
@@ -1,34 +0,0 @@
1
- import { useEffect, useCallback } from 'react';
2
- import { chatKey } from './constants.ts';
3
- import type { ZendeskChatType } from './types.ts';
4
-
5
- export const ZendeskChat: ZendeskChatType = ( { jwt_token } ) => {
6
- const authenticateUser = useCallback( () => {
7
- if ( typeof window !== 'undefined' && typeof window.zE === 'function' ) {
8
- window.zE( 'messenger', 'loginUser', function ( callback ) {
9
- callback( jwt_token );
10
- } );
11
- }
12
- }, [ jwt_token ] );
13
-
14
- useEffect( () => {
15
- const script = document.createElement( 'script' );
16
- const container = document.getElementById( 'zendesk-chat-container' );
17
-
18
- script.src = 'https://static.zdassets.com/ekr/snippet.js?key=' + encodeURIComponent( chatKey );
19
- script.type = 'text/javascript';
20
- script.id = 'ze-snippet';
21
-
22
- script.onload = () => {
23
- authenticateUser();
24
- };
25
-
26
- if ( container ) {
27
- container.appendChild( script );
28
- }
29
- }, [ authenticateUser ] );
30
-
31
- return <div data-testid="zendesk-chat-container" id="zendesk-chat-container" />;
32
- };
33
-
34
- export default ZendeskChat;
@@ -1,14 +0,0 @@
1
- import type { FC } from 'react';
2
-
3
- declare global {
4
- interface Window {
5
- // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
6
- zE: Function;
7
- }
8
- }
9
-
10
- interface ZendeskChatProps {
11
- jwt_token: string;
12
- }
13
-
14
- export type ZendeskChatType = FC< ZendeskChatProps >;