@automattic/jetpack-components 0.39.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/.gitattributes +8 -0
- package/CHANGELOG.md +747 -0
- package/LICENSE.txt +357 -0
- package/README.md +11 -0
- package/SECURITY.md +38 -0
- package/components/action-button/index.jsx +70 -0
- package/components/action-button/stories/index.stories.jsx +38 -0
- package/components/action-button/style.module.scss +11 -0
- package/components/action-button/test/component.jsx +16 -0
- package/components/action-popover/index.tsx +105 -0
- package/components/action-popover/stories/index.stories.jsx +115 -0
- package/components/action-popover/stories/styles.module.scss +7 -0
- package/components/action-popover/styles.module.scss +49 -0
- package/components/action-popover/types.ts +20 -0
- package/components/admin-page/index.tsx +58 -0
- package/components/admin-page/stories/index.stories.tsx +35 -0
- package/components/admin-page/stories/style.module.scss +13 -0
- package/components/admin-page/style.module.scss +11 -0
- package/components/admin-page/types.ts +41 -0
- package/components/admin-section/basic/index.tsx +15 -0
- package/components/admin-section/basic/style.module.scss +3 -0
- package/components/admin-section/hero/index.tsx +15 -0
- package/components/admin-section/hero/style.module.scss +3 -0
- package/components/admin-section/stories/index.stories.tsx +60 -0
- package/components/admin-section/types.ts +6 -0
- package/components/alert/index.tsx +61 -0
- package/components/alert/stories/index.stories.jsx +24 -0
- package/components/alert/style.module.scss +43 -0
- package/components/automattic-byline-logo/README.md +16 -0
- package/components/automattic-byline-logo/index.tsx +38 -0
- package/components/automattic-byline-logo/stories/index.stories.tsx +20 -0
- package/components/automattic-byline-logo/test/component.tsx +28 -0
- package/components/automattic-byline-logo/types.ts +18 -0
- package/components/boost-score-bar/index.tsx +103 -0
- package/components/boost-score-bar/stories/index.stories.tsx +39 -0
- package/components/boost-score-bar/style.scss +184 -0
- package/components/boost-score-bar/test/component.tsx +102 -0
- package/components/boost-score-bar/types.ts +9 -0
- package/components/button/index.tsx +84 -0
- package/components/button/stories/index.mdx +90 -0
- package/components/button/stories/index.stories.tsx +400 -0
- package/components/button/stories/style.module.scss +20 -0
- package/components/button/style.module.scss +212 -0
- package/components/button/types.ts +21 -0
- package/components/contextual-upgrade-trigger/README.md +81 -0
- package/components/contextual-upgrade-trigger/index.tsx +44 -0
- package/components/contextual-upgrade-trigger/stories/index.stories.tsx +25 -0
- package/components/contextual-upgrade-trigger/style.module.scss +75 -0
- package/components/contextual-upgrade-trigger/types.ts +9 -0
- package/components/decorative-card/index.tsx +44 -0
- package/components/decorative-card/stories/index.stories.tsx +18 -0
- package/components/decorative-card/style.scss +116 -0
- package/components/decorative-card/types.ts +16 -0
- package/components/dialog/index.tsx +69 -0
- package/components/dialog/stories/boost.png +0 -0
- package/components/dialog/stories/declaration.d.ts +1 -0
- package/components/dialog/stories/index.stories.tsx +118 -0
- package/components/dialog/stories/js-components.components.dialog.mdx +62 -0
- package/components/dialog/stories/js-components.components.dialog.stories.js +37 -0
- package/components/dialog/stories/style.module.scss +21 -0
- package/components/dialog/style.module.scss +30 -0
- package/components/donut-meter/index.tsx +147 -0
- package/components/donut-meter/stories/index.stories.tsx +51 -0
- package/components/donut-meter/style.scss +11 -0
- package/components/donut-meter/test/component.tsx +24 -0
- package/components/gridicon/index.tsx +298 -0
- package/components/gridicon/stories/index.stories.tsx +18 -0
- package/components/gridicon/style.scss +16 -0
- package/components/gridicon/types.ts +48 -0
- package/components/icon-tooltip/index.tsx +96 -0
- package/components/icon-tooltip/stories/index.stories.tsx +108 -0
- package/components/icon-tooltip/stories/style.scss +36 -0
- package/components/icon-tooltip/style.scss +121 -0
- package/components/icon-tooltip/test/component.tsx +15 -0
- package/components/icon-tooltip/types.ts +76 -0
- package/components/icons/README.md +98 -0
- package/components/icons/index.tsx +369 -0
- package/components/icons/stories/index.stories.tsx +65 -0
- package/components/icons/stories/style.module.scss +33 -0
- package/components/icons/style.module.scss +40 -0
- package/components/icons/types.ts +38 -0
- package/components/indeterminate-progress-bar/index.tsx +28 -0
- package/components/indeterminate-progress-bar/stories/index.stories.tsx +14 -0
- package/components/indeterminate-progress-bar/style.module.scss +34 -0
- package/components/indeterminate-progress-bar/types.ts +6 -0
- package/components/jetpack-footer/README.md +21 -0
- package/components/jetpack-footer/index.tsx +94 -0
- package/components/jetpack-footer/stories/index.stories.tsx +40 -0
- package/components/jetpack-footer/style.scss +116 -0
- package/components/jetpack-footer/test/component.tsx +45 -0
- package/components/jetpack-footer/types.ts +36 -0
- package/components/jetpack-logo/README.md +20 -0
- package/components/jetpack-logo/index.tsx +46 -0
- package/components/jetpack-logo/stories/index.stories.tsx +20 -0
- package/components/jetpack-logo/test/component.tsx +16 -0
- package/components/jetpack-logo/types.ts +7 -0
- package/components/jetpack-search-logo/README.md +20 -0
- package/components/jetpack-search-logo/index.tsx +93 -0
- package/components/jetpack-search-logo/stories/index.stories.tsx +21 -0
- package/components/jetpack-search-logo/test/component.tsx +16 -0
- package/components/jetpack-search-logo/types.ts +7 -0
- package/components/jetpack-vaultpress-backup-logo/README.md +19 -0
- package/components/jetpack-vaultpress-backup-logo/index.tsx +113 -0
- package/components/jetpack-vaultpress-backup-logo/stories/index.stories.tsx +20 -0
- package/components/jetpack-vaultpress-backup-logo/test/component.tsx +18 -0
- package/components/jetpack-vaultpress-backup-logo/types.ts +6 -0
- package/components/jetpack-videopress-logo/README.md +19 -0
- package/components/jetpack-videopress-logo/index.tsx +93 -0
- package/components/jetpack-videopress-logo/stories/index.stories.tsx +20 -0
- package/components/jetpack-videopress-logo/test/component.tsx +16 -0
- package/components/jetpack-videopress-logo/types.tsx +6 -0
- package/components/layout/README.md +9 -0
- package/components/layout/breakpoints.module.scss +20 -0
- package/components/layout/col/README.md +81 -0
- package/components/layout/col/index.tsx +49 -0
- package/components/layout/col/style.module.scss +28 -0
- package/components/layout/container/README.md +77 -0
- package/components/layout/container/index.tsx +42 -0
- package/components/layout/container/style.module.scss +35 -0
- package/components/layout/stories/index.stories.tsx +145 -0
- package/components/layout/stories/styles.module.scss +22 -0
- package/components/layout/types.ts +55 -0
- package/components/layout/use-breakpoint-match/README.md +43 -0
- package/components/layout/use-breakpoint-match/declaration.d.ts +9 -0
- package/components/layout/use-breakpoint-match/index.ts +79 -0
- package/components/loading-placeholder/README.md +22 -0
- package/components/loading-placeholder/index.tsx +23 -0
- package/components/loading-placeholder/stories/index.stories.tsx +78 -0
- package/components/loading-placeholder/style.module.scss +18 -0
- package/components/notice/index.tsx +98 -0
- package/components/notice/stories/index.stories.jsx +90 -0
- package/components/notice/style.module.scss +107 -0
- package/components/number-format/README.md +25 -0
- package/components/number-format/index.ts +16 -0
- package/components/pricing-card/index.tsx +127 -0
- package/components/pricing-card/stories/index.stories.tsx +55 -0
- package/components/pricing-card/style.scss +112 -0
- package/components/pricing-card/test/component.tsx +89 -0
- package/components/pricing-card/types.ts +52 -0
- package/components/pricing-slider/index.tsx +53 -0
- package/components/pricing-slider/stories/index.stories.tsx +44 -0
- package/components/pricing-slider/style.scss +55 -0
- package/components/pricing-slider/test/component.tsx +14 -0
- package/components/pricing-slider/types.ts +58 -0
- package/components/pricing-table/index.tsx +200 -0
- package/components/pricing-table/stories/index.stories.tsx +74 -0
- package/components/pricing-table/styles.module.scss +160 -0
- package/components/pricing-table/test/component.tsx +41 -0
- package/components/pricing-table/types.ts +84 -0
- package/components/product-offer/icons-card.tsx +47 -0
- package/components/product-offer/index.tsx +115 -0
- package/components/product-offer/product-offer-header.tsx +23 -0
- package/components/product-offer/stories/index.stories.tsx +104 -0
- package/components/product-offer/style.module.scss +93 -0
- package/components/product-offer/types.ts +125 -0
- package/components/product-price/index.tsx +90 -0
- package/components/product-price/price.tsx +35 -0
- package/components/product-price/stories/index.stories.tsx +33 -0
- package/components/product-price/style.module.scss +69 -0
- package/components/product-price/test/component.tsx +26 -0
- package/components/product-price/types.ts +73 -0
- package/components/qr-code/Readme.md +5 -0
- package/components/qr-code/index.tsx +78 -0
- package/components/qr-code/stories/index.stories.tsx +32 -0
- package/components/record-meter-bar/index.tsx +135 -0
- package/components/record-meter-bar/stories/index.stories.tsx +39 -0
- package/components/record-meter-bar/style.scss +38 -0
- package/components/record-meter-bar/test/component.tsx +52 -0
- package/components/spinner/README.md +28 -0
- package/components/spinner/index.jsx +45 -0
- package/components/spinner/stories/index.stories.jsx +20 -0
- package/components/spinner/style.scss +31 -0
- package/components/spinner/test/component.jsx +17 -0
- package/components/split-button/index.tsx +39 -0
- package/components/split-button/stories/index.stories.tsx +35 -0
- package/components/split-button/style.module.scss +21 -0
- package/components/split-button/types.ts +14 -0
- package/components/stat-card/index.tsx +49 -0
- package/components/stat-card/stories/index.mdx +35 -0
- package/components/stat-card/stories/index.stories.tsx +41 -0
- package/components/stat-card/style.module.scss +49 -0
- package/components/stat-card/test/component.tsx +24 -0
- package/components/stat-card/types.ts +28 -0
- package/components/status/README.md +42 -0
- package/components/status/index.tsx +40 -0
- package/components/status/stories/index.stories.tsx +44 -0
- package/components/status/style.module.scss +72 -0
- package/components/terms-of-service/index.tsx +63 -0
- package/components/terms-of-service/styles.scss +10 -0
- package/components/terms-of-service/test/index.test.jsx +52 -0
- package/components/terms-of-service/types.ts +30 -0
- package/components/testimonials/index.tsx +58 -0
- package/components/testimonials/style.scss +127 -0
- package/components/testimonials/test/component.tsx +103 -0
- package/components/testimonials/testimonial.tsx +47 -0
- package/components/testimonials/types.ts +17 -0
- package/components/text/constants.ts +30 -0
- package/components/text/index.tsx +91 -0
- package/components/text/stories/headings.index.stories.tsx +80 -0
- package/components/text/stories/index.mdx +195 -0
- package/components/text/stories/index.stories.tsx +69 -0
- package/components/text/stories/style.module.scss +64 -0
- package/components/text/stories/title.index.stories.tsx +34 -0
- package/components/text/style.module.scss +125 -0
- package/components/text/types.ts +53 -0
- package/components/theme-provider/Readme.md +49 -0
- package/components/theme-provider/globals.module.scss +6 -0
- package/components/theme-provider/index.tsx +151 -0
- package/components/theme-provider/stories/index.stories.tsx +164 -0
- package/components/theme-provider/stories/style.module.scss +79 -0
- package/components/theme-provider/types.ts +25 -0
- package/components/toggle-control/README.md +5 -0
- package/components/toggle-control/index.tsx +67 -0
- package/components/toggle-control/stories/index.stories.tsx +83 -0
- package/components/toggle-control/styles.module.scss +41 -0
- package/components/zendesk-chat/README.md +26 -0
- package/components/zendesk-chat/constants.ts +2 -0
- package/components/zendesk-chat/index.tsx +22 -0
- package/components/zendesk-chat/stories/index.stories.tsx +15 -0
- package/components/zendesk-chat/test/component.tsx +16 -0
- package/components/zendesk-chat/types.ts +3 -0
- package/index.ts +69 -0
- package/lib/locale/index.ts +48 -0
- package/lib/locale/test/index.ts +21 -0
- package/package.json +80 -0
- package/tools/get-product-checkout-url/Readme.md +32 -0
- package/tools/get-product-checkout-url/index.ts +31 -0
- package/tools/jp-redirect/README.md +61 -0
- package/tools/jp-redirect/index.ts +62 -0
- package/tools/jp-redirect/test/index.tsx +89 -0
- package/tools/jp-redirect/types.ts +49 -0
- package/tools/pricing-utils/README.md +16 -0
- package/tools/pricing-utils/index.ts +11 -0
- package/tools/pricing-utils/test/index.ts +39 -0
- package/tools/pricing-utils/types.ts +12 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import React, { useLayoutEffect, useRef } from 'react';
|
|
2
|
+
import styles from './globals.module.scss';
|
|
3
|
+
import { ThemeInstance, ThemeProviderProps } from './types';
|
|
4
|
+
|
|
5
|
+
export const typography = {
|
|
6
|
+
// Headline
|
|
7
|
+
'--font-headline-medium': '48px',
|
|
8
|
+
'--font-headline-small': '36px',
|
|
9
|
+
'--font-title-medium': '24px',
|
|
10
|
+
'--font-title-small': '20px',
|
|
11
|
+
'--font-body': '16px',
|
|
12
|
+
'--font-body-small': '14px',
|
|
13
|
+
'--font-body-extra-small': '12px',
|
|
14
|
+
// Deprecated
|
|
15
|
+
'--font-title-large': 'var(--font-headline-small)',
|
|
16
|
+
'--font-label': 'var(--font-body-extra-small)',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const colors = {
|
|
20
|
+
'--jp-black': '#000000',
|
|
21
|
+
'--jp-black-80': '#2c3338',
|
|
22
|
+
// White
|
|
23
|
+
'--jp-white': '#ffffff',
|
|
24
|
+
'--jp-white-off': '#f9f9f6',
|
|
25
|
+
// Gray
|
|
26
|
+
'--jp-gray': '#dcdcde',
|
|
27
|
+
'--jp-gray-0': '#F6F7F7',
|
|
28
|
+
'--jp-gray-10': '#C3C4C7',
|
|
29
|
+
'--jp-gray-20': '#A7AAAD',
|
|
30
|
+
'--jp-gray-40': '#787C82',
|
|
31
|
+
'--jp-gray-50': '#646970',
|
|
32
|
+
'--jp-gray-60': '#50575E',
|
|
33
|
+
'--jp-gray-70': '#3C434A',
|
|
34
|
+
'--jp-gray-80': '#2C3338',
|
|
35
|
+
'--jp-gray-90': '#1d2327',
|
|
36
|
+
'--jp-gray-off': '#e2e2df',
|
|
37
|
+
// Red
|
|
38
|
+
'--jp-red-0': '#F7EBEC',
|
|
39
|
+
'--jp-red-5': '#FACFD2',
|
|
40
|
+
'--jp-red-40': '#E65054',
|
|
41
|
+
'--jp-red-50': '#D63638',
|
|
42
|
+
'--jp-red-60': '#B32D2E',
|
|
43
|
+
'--jp-red-70': '#8A2424',
|
|
44
|
+
'--jp-red-80': '#691C1C',
|
|
45
|
+
'--jp-red': '#d63639',
|
|
46
|
+
// Yellow
|
|
47
|
+
'--jp-yellow-5': '#F5E6B3',
|
|
48
|
+
'--jp-yellow-10': '#F2CF75',
|
|
49
|
+
'--jp-yellow-20': '#F0C930',
|
|
50
|
+
'--jp-yellow-30': '#DEB100',
|
|
51
|
+
'--jp-yellow-40': '#C08C00',
|
|
52
|
+
'--jp-yellow-50': '#9D6E00',
|
|
53
|
+
'--jp-yellow-60': '#7D5600',
|
|
54
|
+
// Blue
|
|
55
|
+
'--jp-blue-20': '#68B3E8',
|
|
56
|
+
'--jp-blue-40': '#1689DB',
|
|
57
|
+
// Pink
|
|
58
|
+
'--jp-pink': '#C9356E',
|
|
59
|
+
// Green
|
|
60
|
+
'--jp-green-0': '#f0f2eb',
|
|
61
|
+
'--jp-green-5': '#d0e6b8',
|
|
62
|
+
'--jp-green-10': '#9dd977',
|
|
63
|
+
'--jp-green-20': '#64ca43',
|
|
64
|
+
'--jp-green-30': '#2fb41f',
|
|
65
|
+
'--jp-green-40': '#069e08',
|
|
66
|
+
'--jp-green-50': '#008710',
|
|
67
|
+
'--jp-green-60': '#007117',
|
|
68
|
+
'--jp-green-70': '#005b18',
|
|
69
|
+
'--jp-green-80': '#004515',
|
|
70
|
+
'--jp-green-90': '#003010',
|
|
71
|
+
'--jp-green-100': '#001c09',
|
|
72
|
+
'--jp-green': '#069e08',
|
|
73
|
+
'--jp-green-primary': 'var( --jp-green-40 )',
|
|
74
|
+
'--jp-green-secondary': 'var( --jp-green-30 )',
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const borders = {
|
|
78
|
+
'--jp-border-radius': '4px',
|
|
79
|
+
'--jp-menu-border-height': '1px',
|
|
80
|
+
'--jp-underline-thickness': '2px',
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const spacing = {
|
|
84
|
+
'--spacing-base': '8px',
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const globalThemeInstances: Record< string, ThemeInstance > = {};
|
|
88
|
+
|
|
89
|
+
const setup = ( root: HTMLElement, id: string, withGlobalStyles?: boolean ) => {
|
|
90
|
+
const tokens = { ...typography, ...colors, ...borders, ...spacing };
|
|
91
|
+
for ( const key in tokens ) {
|
|
92
|
+
root.style.setProperty( key, tokens[ key ] );
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if ( withGlobalStyles ) {
|
|
96
|
+
root.classList.add( styles.global );
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if ( ! id ) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Register theme provider instance.
|
|
104
|
+
globalThemeInstances[ id ] = {
|
|
105
|
+
provided: true,
|
|
106
|
+
root,
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* ThemeProvider React component.
|
|
112
|
+
*
|
|
113
|
+
* @param {ThemeProviderProps} props - Component properties.
|
|
114
|
+
* @returns {React.ReactNode} ThemeProvider component.
|
|
115
|
+
*/
|
|
116
|
+
const ThemeProvider: React.FC< ThemeProviderProps > = ( {
|
|
117
|
+
children = null,
|
|
118
|
+
targetDom,
|
|
119
|
+
id,
|
|
120
|
+
withGlobalStyles = true,
|
|
121
|
+
} ) => {
|
|
122
|
+
const themeWrapperRef = useRef< HTMLDivElement >();
|
|
123
|
+
|
|
124
|
+
// Check whether the theme provider instance is already registered.
|
|
125
|
+
const isAlreadyProvided = globalThemeInstances?.[ id ]?.provided;
|
|
126
|
+
|
|
127
|
+
useLayoutEffect( () => {
|
|
128
|
+
if ( isAlreadyProvided ) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if ( targetDom ) {
|
|
133
|
+
return setup( targetDom, id, withGlobalStyles );
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if ( ! themeWrapperRef?.current ) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
setup( themeWrapperRef.current, id, withGlobalStyles );
|
|
141
|
+
}, [ targetDom, themeWrapperRef, isAlreadyProvided, id, withGlobalStyles ] );
|
|
142
|
+
|
|
143
|
+
// Do not wrap when the DOM element target is defined.
|
|
144
|
+
if ( targetDom ) {
|
|
145
|
+
return children;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return <div ref={ themeWrapperRef }>{ children }</div>;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export default ThemeProvider;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { Button } from '@wordpress/components';
|
|
2
|
+
import { useCopyToClipboard } from '@wordpress/compose';
|
|
3
|
+
import Col from '../../layout/col';
|
|
4
|
+
import Container from '../../layout/container';
|
|
5
|
+
import ThemeProvider, { typography, colors, borders, spacing } from '../index';
|
|
6
|
+
import styles from './style.module.scss';
|
|
7
|
+
import type { ComponentStory, ComponentMeta } from '@storybook/react';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get the contrasting color for any hex color
|
|
11
|
+
* (c) 2019 Chris Ferdinandi, MIT License, https://gomakethings.com
|
|
12
|
+
* Derived from work by Brian Suda, https://24ways.org/2010/calculating-color-contrast/
|
|
13
|
+
*
|
|
14
|
+
* @param {string} hexcolor - hexcolor value
|
|
15
|
+
* @returns {string} The contrasting color (black or white)
|
|
16
|
+
*/
|
|
17
|
+
function getContrast( hexcolor ) {
|
|
18
|
+
// If a leading # is provided, remove it
|
|
19
|
+
if ( hexcolor.slice( 0, 1 ) === '#' ) {
|
|
20
|
+
hexcolor = hexcolor.slice( 1 );
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// If a three-character hexcode, make six-character
|
|
24
|
+
if ( hexcolor.length === 3 ) {
|
|
25
|
+
hexcolor = hexcolor
|
|
26
|
+
.split( '' )
|
|
27
|
+
.map( function ( hex ) {
|
|
28
|
+
return hex + hex;
|
|
29
|
+
} )
|
|
30
|
+
.join( '' );
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Convert to RGB value
|
|
34
|
+
const r = parseInt( hexcolor.substring( 0, 2 ), 16 );
|
|
35
|
+
const g = parseInt( hexcolor.substring( 2, 4 ), 16 );
|
|
36
|
+
const b = parseInt( hexcolor.substring( 4, 6 ), 16 );
|
|
37
|
+
|
|
38
|
+
// Get YIQ ratio
|
|
39
|
+
const yiq = ( r * 299 + g * 587 + b * 114 ) / 1000;
|
|
40
|
+
|
|
41
|
+
// Check contrast
|
|
42
|
+
return yiq >= 128 ? 'black' : 'white';
|
|
43
|
+
}
|
|
44
|
+
export default {
|
|
45
|
+
title: 'JS Packages/Components/Theme Provider',
|
|
46
|
+
} as ComponentMeta< typeof ThemeProvider >;
|
|
47
|
+
|
|
48
|
+
const noop = () => {
|
|
49
|
+
//
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const ClipboardButton: React.FC< React.ComponentProps< typeof Button > > = ( {
|
|
53
|
+
text,
|
|
54
|
+
...buttonProps
|
|
55
|
+
} ) => {
|
|
56
|
+
const ref = useCopyToClipboard( text, noop );
|
|
57
|
+
return <Button { ...buttonProps } ref={ ref } />;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const Section = ( { title, data, children = null } ) => (
|
|
61
|
+
<div className={ styles.section }>
|
|
62
|
+
<h1 className={ styles.title }>{ title }</h1>
|
|
63
|
+
<Container fluid>
|
|
64
|
+
{ Object.keys( data ).map( key => (
|
|
65
|
+
<Col lg={ 3 } className={ styles.box }>
|
|
66
|
+
<Container fluid horizontalGap={ 2 }>
|
|
67
|
+
<Col className={ styles.key }>{ key }</Col>
|
|
68
|
+
{ children && <Col className={ styles.example }>{ children( data[ key ] ) }</Col> }
|
|
69
|
+
<Col>
|
|
70
|
+
<div className={ styles[ 'value-label' ] }>Value</div>
|
|
71
|
+
<input
|
|
72
|
+
type="text"
|
|
73
|
+
value={ data[ key ] }
|
|
74
|
+
readOnly={ true }
|
|
75
|
+
className={ styles.value }
|
|
76
|
+
/>
|
|
77
|
+
</Col>
|
|
78
|
+
</Container>
|
|
79
|
+
</Col>
|
|
80
|
+
) ) }
|
|
81
|
+
</Container>
|
|
82
|
+
</div>
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
export const Tokens = () => (
|
|
86
|
+
<>
|
|
87
|
+
<Section title="Typography" data={ typography }>
|
|
88
|
+
{ value => <div style={ { fontSize: value } }>Text</div> }
|
|
89
|
+
</Section>
|
|
90
|
+
<Section title="Colors" data={ colors }>
|
|
91
|
+
{ value => (
|
|
92
|
+
<div className={ styles[ 'colors-example' ] } style={ { backgroundColor: value } } />
|
|
93
|
+
) }
|
|
94
|
+
</Section>
|
|
95
|
+
<Section title="Borders" data={ borders } />
|
|
96
|
+
<Section title="Spacing" data={ spacing } />
|
|
97
|
+
</>
|
|
98
|
+
);
|
|
99
|
+
Tokens.parameters = {
|
|
100
|
+
docs: { source: { code: null } },
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const Typographies = args => (
|
|
104
|
+
<div className={ styles[ 'instances-wrapper' ] }>
|
|
105
|
+
{ Object.keys( typography ).map( key => (
|
|
106
|
+
<div className={ styles[ 'font-instance' ] } style={ { fontSize: typography[ key ] } }>
|
|
107
|
+
{ args?.[ 'Text Instance' ] || `${ key } (${ typography[ key ] } )` }
|
|
108
|
+
|
|
109
|
+
<ClipboardButton variant="tertiary" text={ key } className={ styles[ 'copy-button' ] }>
|
|
110
|
+
Copy
|
|
111
|
+
</ClipboardButton>
|
|
112
|
+
</div>
|
|
113
|
+
) ) }
|
|
114
|
+
</div>
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
Typographies.args = {
|
|
118
|
+
[ 'Text Instance' ]: '',
|
|
119
|
+
};
|
|
120
|
+
Typographies.parameters = {
|
|
121
|
+
docs: { source: { code: null } },
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export const Colors = () => (
|
|
125
|
+
<div className={ styles[ 'instances-wrapper' ] }>
|
|
126
|
+
{ Object.keys( colors ).map( key => (
|
|
127
|
+
<div
|
|
128
|
+
className={ styles[ 'color-instance' ] }
|
|
129
|
+
style={ { backgroundColor: colors[ key ], color: getContrast( colors[ key ] ) } }
|
|
130
|
+
>
|
|
131
|
+
{ `${ key } (${ colors[ key ].toUpperCase() } )` }
|
|
132
|
+
|
|
133
|
+
<ClipboardButton
|
|
134
|
+
variant="tertiary"
|
|
135
|
+
text={ key }
|
|
136
|
+
className={ styles[ 'copy-button' ] }
|
|
137
|
+
style={ { color: getContrast( colors[ key ] ) } }
|
|
138
|
+
>
|
|
139
|
+
Copy
|
|
140
|
+
</ClipboardButton>
|
|
141
|
+
</div>
|
|
142
|
+
) ) }
|
|
143
|
+
</div>
|
|
144
|
+
);
|
|
145
|
+
Colors.parameters = {
|
|
146
|
+
docs: { source: { code: null } },
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const Template: ComponentStory< typeof ThemeProvider > = args => (
|
|
150
|
+
<ThemeProvider { ...args }>
|
|
151
|
+
<div
|
|
152
|
+
style={ {
|
|
153
|
+
color: 'var( --jp-white )',
|
|
154
|
+
backgroundColor: 'var( --jp-pink )',
|
|
155
|
+
fontSize: 'var( --font-title-small )',
|
|
156
|
+
padding: 'var( --spacing-base ) calc( var( --spacing-base ) * 2 )',
|
|
157
|
+
borderRadius: 'var( --jp-border-radius )',
|
|
158
|
+
} }
|
|
159
|
+
>
|
|
160
|
+
Pink Jetpack Show
|
|
161
|
+
</div>
|
|
162
|
+
</ThemeProvider>
|
|
163
|
+
);
|
|
164
|
+
export const BasicUsage = Template.bind( {} );
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
.section {
|
|
2
|
+
width: 100%;
|
|
3
|
+
margin: auto;
|
|
4
|
+
padding: 8px 32px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.key {
|
|
8
|
+
background-color: var(--jp-green-80);
|
|
9
|
+
border-radius: var(--jp-border-radius);
|
|
10
|
+
padding: 8px;
|
|
11
|
+
color: var(--jp-white);
|
|
12
|
+
font-weight: 600;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.box {
|
|
16
|
+
border: 1px solid var(--jp-gray);
|
|
17
|
+
border-radius: var(--jp-border-radius);
|
|
18
|
+
padding: 16px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.example {
|
|
22
|
+
height: 40px;
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
border: 1px solid var(--jp-gray);
|
|
26
|
+
border-radius: var(--jp-border-radius);
|
|
27
|
+
padding: 8px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.value-label {
|
|
31
|
+
font-weight: 600;
|
|
32
|
+
font-size: var(--font-label);
|
|
33
|
+
margin: 8px 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.value {
|
|
37
|
+
width: 100%;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.colors-example {
|
|
41
|
+
width: 100%;
|
|
42
|
+
height: 100%;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.instances-wrapper {
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-direction: column;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.font-instance {
|
|
51
|
+
margin: 10px 0;
|
|
52
|
+
padding: 20px 30px;
|
|
53
|
+
background-color: var( --jp-white );
|
|
54
|
+
border: 1px dotted var( --jp-gray-10 );
|
|
55
|
+
position: relative;
|
|
56
|
+
&:hover .copy-button {
|
|
57
|
+
opacity: 1;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.color-instance {
|
|
62
|
+
font-size: var( --font-title-small );
|
|
63
|
+
border: 1px dotted var( --jp-gray-10 );
|
|
64
|
+
min-height: 60px;
|
|
65
|
+
line-height: 60px;
|
|
66
|
+
padding: 10px;
|
|
67
|
+
margin: 10px 0;
|
|
68
|
+
position: relative;
|
|
69
|
+
&:hover .copy-button {
|
|
70
|
+
opacity: 1;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.copy-button {
|
|
75
|
+
opacity: 0.3;
|
|
76
|
+
position: absolute;
|
|
77
|
+
top: 5px;
|
|
78
|
+
right: 5px;
|
|
79
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type ThemeProviderProps = {
|
|
2
|
+
/**
|
|
3
|
+
* An optional id to register and identify the provider instance.
|
|
4
|
+
*/
|
|
5
|
+
id?: string;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Target DOM element to store theme styles. Optional.
|
|
9
|
+
*/
|
|
10
|
+
targetDom?: HTMLElement;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Content
|
|
14
|
+
*/
|
|
15
|
+
children?: React.ReactElement;
|
|
16
|
+
/**
|
|
17
|
+
* Inser global/reset styles
|
|
18
|
+
*/
|
|
19
|
+
withGlobalStyles?: boolean;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type ThemeInstance = {
|
|
23
|
+
provided: boolean;
|
|
24
|
+
root: HTMLElement;
|
|
25
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Toggle Control
|
|
2
|
+
|
|
3
|
+
A wrapper component for applying Jetpack Emerald styles to the [ToggleControl](https://github.com/WordPress/gutenberg/tree/trunk/packages/components/src/form-toggle) component from `@wordpress/components`.
|
|
4
|
+
|
|
5
|
+
The documentation for the base `ToggleControl` component can be found via the [Gutenberg Handbook](https://developer.wordpress.org/block-editor/components/toggle-control/).
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ToggleControl as WPToggleControl } from '@wordpress/components';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import { useCallback } from 'react';
|
|
4
|
+
import styles from './styles.module.scss';
|
|
5
|
+
|
|
6
|
+
interface ToggleControlProps {
|
|
7
|
+
/** Whether or not the toggle is currently enabled. */
|
|
8
|
+
checked?: boolean;
|
|
9
|
+
|
|
10
|
+
/** Custom class name to append to the component. */
|
|
11
|
+
className?: string;
|
|
12
|
+
|
|
13
|
+
/** Whether or not the toggle is currently disabled. */
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
|
|
16
|
+
/** Additional information to display below the toggle. */
|
|
17
|
+
help?: React.ReactNode;
|
|
18
|
+
|
|
19
|
+
/** Whether or not the toggling is currently toggling. */
|
|
20
|
+
toggling?: boolean;
|
|
21
|
+
|
|
22
|
+
/** The label for the toggle. */
|
|
23
|
+
label?: React.ReactNode;
|
|
24
|
+
|
|
25
|
+
/** A callback function invoked when the toggle is clicked. */
|
|
26
|
+
onChange: ( value: boolean ) => void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const ToggleControl: React.FC< ToggleControlProps > = ( {
|
|
30
|
+
checked,
|
|
31
|
+
className,
|
|
32
|
+
disabled,
|
|
33
|
+
help,
|
|
34
|
+
toggling,
|
|
35
|
+
label,
|
|
36
|
+
onChange,
|
|
37
|
+
} ) => {
|
|
38
|
+
const showChecked =
|
|
39
|
+
toggling !== undefined ? ( checked && ! toggling ) || ( ! checked && toggling ) : checked;
|
|
40
|
+
|
|
41
|
+
const handleOnChange = useCallback(
|
|
42
|
+
( value: boolean ) => {
|
|
43
|
+
// Don't toggle if the toggle is already toggling.
|
|
44
|
+
if ( toggling ) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
onChange( value );
|
|
49
|
+
},
|
|
50
|
+
[ toggling, onChange ]
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<WPToggleControl
|
|
55
|
+
checked={ showChecked }
|
|
56
|
+
className={ classNames( styles.toggle, className, {
|
|
57
|
+
[ styles[ 'is-toggling' ] ]: toggling,
|
|
58
|
+
} ) }
|
|
59
|
+
disabled={ disabled }
|
|
60
|
+
help={ help }
|
|
61
|
+
label={ label }
|
|
62
|
+
onChange={ handleOnChange }
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default ToggleControl;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import React, { useCallback, useState } from 'react';
|
|
2
|
+
import ToggleControl from '..';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'JS Packages/Components/Toggle Control',
|
|
6
|
+
component: ToggleControl,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: 'centered',
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
13
|
+
export const Default = args => {
|
|
14
|
+
const [ checked, setChecked ] = useState( false );
|
|
15
|
+
|
|
16
|
+
const handleChecked = useCallback( () => {
|
|
17
|
+
setChecked( ! checked );
|
|
18
|
+
}, [ checked ] );
|
|
19
|
+
|
|
20
|
+
return <ToggleControl checked={ checked } onChange={ handleChecked } label="Code is poetry." />;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
24
|
+
export const Slow = args => {
|
|
25
|
+
const [ loading, setLoading ] = useState( false );
|
|
26
|
+
const [ checked, setChecked ] = useState( false );
|
|
27
|
+
|
|
28
|
+
const handleChecked = useCallback( () => {
|
|
29
|
+
setLoading( true );
|
|
30
|
+
setTimeout( () => {
|
|
31
|
+
setLoading( false );
|
|
32
|
+
setChecked( ! checked );
|
|
33
|
+
}, 2000 );
|
|
34
|
+
}, [ checked ] );
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<ToggleControl
|
|
38
|
+
checked={ checked }
|
|
39
|
+
toggling={ loading }
|
|
40
|
+
onChange={ handleChecked }
|
|
41
|
+
label="Code is poetry."
|
|
42
|
+
/>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
47
|
+
export const Disabled = args => {
|
|
48
|
+
const [ checked, setChecked ] = useState( false );
|
|
49
|
+
|
|
50
|
+
const handleChecked = useCallback( () => {
|
|
51
|
+
setChecked( ! checked );
|
|
52
|
+
}, [ checked ] );
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<>
|
|
56
|
+
<ToggleControl checked={ true } disabled label="Code is poetry." onChange={ handleChecked } />
|
|
57
|
+
<ToggleControl
|
|
58
|
+
checked={ false }
|
|
59
|
+
disabled
|
|
60
|
+
label="Code is poetry."
|
|
61
|
+
onChange={ handleChecked }
|
|
62
|
+
/>
|
|
63
|
+
</>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
68
|
+
export const HelpText = args => {
|
|
69
|
+
const [ checked, setChecked ] = useState( false );
|
|
70
|
+
|
|
71
|
+
const handleChecked = useCallback( () => {
|
|
72
|
+
setChecked( ! checked );
|
|
73
|
+
}, [ checked ] );
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<ToggleControl
|
|
77
|
+
checked={ checked }
|
|
78
|
+
label="Code is poetry."
|
|
79
|
+
help="Code is poetry. Code is poetry. Code is poetry."
|
|
80
|
+
onChange={ handleChecked }
|
|
81
|
+
/>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/// Toggle Control
|
|
2
|
+
///
|
|
3
|
+
/// Overrides the @wordpress/components ToggleControl component.
|
|
4
|
+
/// @link https://github.com/WordPress/gutenberg/tree/trunk/packages/components/src/form-toggle
|
|
5
|
+
.toggle {
|
|
6
|
+
:global {
|
|
7
|
+
.components-form-toggle {
|
|
8
|
+
--wp-admin-theme-color: var( --jp-green-40 );
|
|
9
|
+
|
|
10
|
+
&__input:focus + .components-form-toggle__track {
|
|
11
|
+
box-shadow: 0 0 0 2px var( --jp-white ), 0 0 0 4px var( --jp-green-50 );
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.components-form-toggle__track {
|
|
15
|
+
width: 48px;
|
|
16
|
+
height: 24px;
|
|
17
|
+
border-radius: 12px;
|
|
18
|
+
border-width: 2px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.components-form-toggle__thumb {
|
|
22
|
+
width: 16px;
|
|
23
|
+
height: 16px;
|
|
24
|
+
top: 4px;
|
|
25
|
+
left: 4px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&.is-checked .components-form-toggle__thumb {
|
|
29
|
+
transform: translateX( 24px );
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.toggle.is-toggling {
|
|
36
|
+
:global {
|
|
37
|
+
.components-form-toggle {
|
|
38
|
+
opacity: .6;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
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-dom`, 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 React from 'react';
|
|
11
|
+
import { ZendeskChat } from '@automattic/jetpack-components';
|
|
12
|
+
|
|
13
|
+
const ExampleComponent = () => (
|
|
14
|
+
<ZendeskChat />
|
|
15
|
+
);
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Props
|
|
19
|
+
|
|
20
|
+
None
|
|
21
|
+
|
|
22
|
+
Because the chat is conditionally rendered based on Date and Time, no props are needed in order to render correctly.
|
|
23
|
+
|
|
24
|
+
## Note
|
|
25
|
+
|
|
26
|
+
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.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { chatKey } from './constants';
|
|
3
|
+
import type { ZendeskChatType } from './types';
|
|
4
|
+
|
|
5
|
+
export const ZendeskChat: ZendeskChatType = () => {
|
|
6
|
+
useEffect( () => {
|
|
7
|
+
const script = document.createElement( 'script' );
|
|
8
|
+
const container = document.getElementById( 'zendesk-chat-container' );
|
|
9
|
+
|
|
10
|
+
script.src = 'https://static.zdassets.com/ekr/snippet.js?key=' + encodeURIComponent( chatKey );
|
|
11
|
+
script.type = 'text/javascript';
|
|
12
|
+
script.id = 'ze-snippet';
|
|
13
|
+
|
|
14
|
+
if ( container ) {
|
|
15
|
+
container.appendChild( script );
|
|
16
|
+
}
|
|
17
|
+
}, [] );
|
|
18
|
+
|
|
19
|
+
return <div data-testid="zendesk-chat-container" id="zendesk-chat-container" />;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default ZendeskChat;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import ZendeskChat from '../index';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
title: 'JS Packages/Components/Zendesk Chat',
|
|
5
|
+
component: ZendeskChat,
|
|
6
|
+
parameters: {
|
|
7
|
+
backgrounds: {
|
|
8
|
+
default: 'dark',
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const Template = args => <ZendeskChat { ...args } />;
|
|
14
|
+
|
|
15
|
+
export const _default = Template.bind( {} );
|