diff --git a/packages/playground/website/src/components/browser-chrome/index.tsx b/packages/playground/website/src/components/browser-chrome/index.tsx index c156f42097..66e3814bde 100644 --- a/packages/playground/website/src/components/browser-chrome/index.tsx +++ b/packages/playground/website/src/components/browser-chrome/index.tsx @@ -10,7 +10,8 @@ import { useAppDispatch, } from '../../lib/state/redux/store'; import { SyncLocalFilesButton } from '../sync-local-files-button'; -import { Dropdown, Icon, Modal } from '@wordpress/components'; +import { Dropdown, Icon } from '@wordpress/components'; +import { Modal } from '../../components/modal'; import { cog } from '@wordpress/icons'; import Button from '../button'; import { ActiveSiteSettingsForm } from '../site-manager/site-settings-form'; diff --git a/packages/playground/website/src/components/error-report-modal/index.tsx b/packages/playground/website/src/components/error-report-modal/index.tsx index 186b6062c9..8be68dd90e 100644 --- a/packages/playground/website/src/components/error-report-modal/index.tsx +++ b/packages/playground/website/src/components/error-report-modal/index.tsx @@ -1,10 +1,6 @@ -import { useEffect, useState } from 'react'; -import Modal from '../modal'; +import React, { useEffect, useState } from 'react'; import { logger } from '@php-wasm/logger'; -import { Button, TextareaControl, TextControl } from '@wordpress/components'; - -import css from './style.module.css'; - +import { TextareaControl, TextControl } from '@wordpress/components'; import { Blueprint } from '@wp-playground/blueprints'; import { useDispatch } from 'react-redux'; import { @@ -13,6 +9,8 @@ import { useAppSelector, } from '../../lib/state/redux/store'; import { setActiveModal } from '../../lib/state/redux/slice-ui'; +import { Modal } from '../../components/modal'; +import ModalButtons from '../modal/modal-buttons'; export function ErrorReportModal(props: { blueprint: Blueprint }) { const activeModal = useAppSelector( @@ -157,49 +155,32 @@ export function ErrorReportModal(props: { blueprint: Blueprint }) { } return ( - -
-

{getTitle()}

-

{getContent()}

-
+ +

{getContent()}

{showForm() && ( <> -
- - - - -
-
- - -
+ + + + + + )}
diff --git a/packages/playground/website/src/components/error-report-modal/style.module.css b/packages/playground/website/src/components/error-report-modal/style.module.css deleted file mode 100644 index 45f82e7e16..0000000000 --- a/packages/playground/website/src/components/error-report-modal/style.module.css +++ /dev/null @@ -1,19 +0,0 @@ -.error-report-modal__header h2 { - font-size: 20px; -} - -.error-report-modal__header p { - font-size: 13px; -} - -.error-report-modal__textarea textarea { - resize: vertical; - width: 100% !important; -} - -.error-report-modal__footer { - margin-top: 20px; -} -.error-report-modal__error { - margin: 16px 0 0; -} diff --git a/packages/playground/website/src/components/import-form/modal.tsx b/packages/playground/website/src/components/import-form-modal/index.tsx similarity index 87% rename from packages/playground/website/src/components/import-form/modal.tsx rename to packages/playground/website/src/components/import-form-modal/index.tsx index 5861a60b98..2f786eb971 100644 --- a/packages/playground/website/src/components/import-form/modal.tsx +++ b/packages/playground/website/src/components/import-form-modal/index.tsx @@ -1,9 +1,10 @@ +import React from 'react'; +import { useDispatch } from 'react-redux'; import { usePlaygroundClient } from '../../lib/use-playground-client'; -import ImportForm from './index'; -import Modal from '../modal'; +import ImportForm from '../import-form/index'; +import { Modal } from '../../components/modal'; import { setActiveModal } from '../../lib/state/redux/slice-ui'; import { PlaygroundDispatch } from '../../lib/state/redux/store'; -import { useDispatch } from 'react-redux'; export const ImportFormModal = () => { const playground = usePlaygroundClient(); @@ -23,7 +24,7 @@ export const ImportFormModal = () => { return ( (); const fileInputRef = useRef(); const [file, setFile] = useState(null); const [error, setError] = useState(''); @@ -46,11 +43,8 @@ export default function ImportForm({ } return ( -
-

- Import Playground -

-

+ <> +

You may replace the current WordPress Playground site with a previously exported one.

@@ -64,17 +58,13 @@ export default function ImportForm({ accept="application/zip" /> -
- -
-
+ + + ); } diff --git a/packages/playground/website/src/components/layout/index.tsx b/packages/playground/website/src/components/layout/index.tsx index ee6906d1a5..25a6ee3211 100644 --- a/packages/playground/website/src/components/layout/index.tsx +++ b/packages/playground/website/src/components/layout/index.tsx @@ -32,7 +32,8 @@ import { setActiveModal, setSiteManagerOpen, } from '../../lib/state/redux/slice-ui'; -import { ImportFormModal } from '../import-form/modal'; +import { ImportFormModal } from '../import-form-modal'; +import { PreviewPRModal } from '../../github/preview-pr'; acquireOAuthTokenIfNeeded(); @@ -42,7 +43,9 @@ export const modalSlugs = { START_ERROR: 'start-error', IMPORT_FORM: 'import-form', GITHUB_IMPORT: 'github-import', - GITHUB_EXPORT: 'github-export' + GITHUB_EXPORT: 'github-export', + PREVIEW_PR_WP: 'preview-pr-wordpress', + PREVIEW_PR_GUTENBERG: 'preview-pr-gutenberg', } const displayMode = getDisplayModeFromQuery(); @@ -178,6 +181,10 @@ function Modals(blueprint: Blueprint) { return ; } else if (currentModal === modalSlugs.IMPORT_FORM) { return ; + } else if (currentModal === modalSlugs.PREVIEW_PR_WP) { + return ; + } else if (currentModal === modalSlugs.PREVIEW_PR_GUTENBERG) { + return ; } else if (currentModal === modalSlugs.GITHUB_IMPORT) { return -
-

{props.title || 'Error Logs'}

- {props.description} -
+ +
{props.description}
); @@ -91,7 +83,7 @@ export function SiteLogs({ className }: { className?: string }) { No matching logs found. ) : ( -
+
Error logs for Playground, WordPress, and PHP will show up here when something goes wrong.
diff --git a/packages/playground/website/src/components/log-modal/style.module.css b/packages/playground/website/src/components/log-modal/style.module.css index 6c78b1dbf3..34ca4513b6 100644 --- a/packages/playground/website/src/components/log-modal/style.module.css +++ b/packages/playground/website/src/components/log-modal/style.module.css @@ -25,16 +25,6 @@ flex-grow: 1; } -.log__list { - padding-bottom: 20px; - flex-grow: 1; - max-height: 100%; -} - -.log__empty_placeholder { - padding-bottom: 20px; -} - .log__entry { font-family: monospace; word-wrap: break-word; diff --git a/packages/playground/website/src/components/modal/index.tsx b/packages/playground/website/src/components/modal/index.tsx index 768aa6cf1d..44b56bfb9f 100644 --- a/packages/playground/website/src/components/modal/index.tsx +++ b/packages/playground/website/src/components/modal/index.tsx @@ -1,61 +1,24 @@ -import ReactModal from 'react-modal'; +import React from 'react'; +import { Modal as WordPressModal } from '@wordpress/components'; +import type { ModalProps as WordPressModalProps } from '@wordpress/components/build-types/modal/types'; +import classNames from 'classnames'; import css from './style.module.css'; -ReactModal.setAppElement('#root'); - -interface ModalProps extends ReactModal.Props { - styles?: ReactModal.Styles; +interface ModalProps extends WordPressModalProps { + small?: boolean; } -export const defaultStyles: ReactModal.Styles = { - content: { - top: '50%', - left: '50%', - right: 'auto', - bottom: 'auto', - marginRight: '-50%', - transform: 'translate(-50%, -50%)', - width: 400, - maxWidth: '100vw', - zIndex: 200, - textAlign: 'center', - color: '#000', - border: '#000 1px solid', - borderRadius: '6px', - background: '#fff', - }, - overlay: { - background: '#1e2327d0', - zIndex: 10, - }, -}; -export default function Modal(props: ModalProps) { - const styles = { - overlay: { ...defaultStyles.overlay, ...props.styles?.overlay }, - content: { ...defaultStyles.content, ...props.styles?.content }, - }; +export function Modal({ small, className, children, ...rest }: ModalProps) { + const modalClass = classNames( + css.modal, + { + [css.modalSmall]: small, + }, + className + ); + return ( - - - + + {children} + ); } diff --git a/packages/playground/website/src/components/modal/modal-buttons.tsx b/packages/playground/website/src/components/modal/modal-buttons.tsx new file mode 100644 index 0000000000..c9bbb0d9de --- /dev/null +++ b/packages/playground/website/src/components/modal/modal-buttons.tsx @@ -0,0 +1,36 @@ +import { Button, Flex } from '@wordpress/components'; +import React from 'react'; +import css from './style.module.css'; + +interface ModalButtonsProps { + submitText?: string; + areDisabled?: boolean; + areBusy?: boolean; + onCancel?: () => void; + onSubmit?: (e: any) => void; +} +export default function ModalButtons({ submitText = 'Submit', areDisabled = false, areBusy, onCancel, onSubmit }: ModalButtonsProps) { + return ( + + + + + ) +} diff --git a/packages/playground/website/src/components/modal/style.module.css b/packages/playground/website/src/components/modal/style.module.css index 23aa58deb3..ede172b58e 100644 --- a/packages/playground/website/src/components/modal/style.module.css +++ b/packages/playground/website/src/components/modal/style.module.css @@ -1,23 +1,17 @@ -.btn { - cursor: pointer; - background: none; - border: none; -} +.modal { + max-width: 600px; -.btn:hover, -.btn:active { - opacity: 0.8; + textarea { + resize: vertical; + width: 100% !important; + min-height: 3lh; + } } -.btn-close { - position: absolute; - top: -8px; - right: -13px; +.modal-small { + max-width: 350px; } -.modal-inner { - position: relative; - padding: 15px; - text-align: left; - max-height: 90vh; +.modal-buttons { + margin-top: 1.5rem; } diff --git a/packages/playground/website/src/components/site-manager/blueprints-panel/index.tsx b/packages/playground/website/src/components/site-manager/blueprints-panel/index.tsx index cea9ae6f27..231668de32 100644 --- a/packages/playground/website/src/components/site-manager/blueprints-panel/index.tsx +++ b/packages/playground/website/src/components/site-manager/blueprints-panel/index.tsx @@ -211,7 +211,8 @@ export function BlueprintsPanel({ ) : isError ? (

Could not load the Blueprints from the gallery. Try @@ -219,9 +220,7 @@ export function BlueprintsPanel({

) : ( - + data={indexEntries as BlueprintsIndexEntry[]} view={view} diff --git a/packages/playground/website/src/components/site-manager/sidebar/index.tsx b/packages/playground/website/src/components/site-manager/sidebar/index.tsx index 34521309fe..bcf13b953a 100644 --- a/packages/playground/website/src/components/site-manager/sidebar/index.tsx +++ b/packages/playground/website/src/components/site-manager/sidebar/index.tsx @@ -11,8 +11,9 @@ import { __experimentalItemGroup as ItemGroup, __experimentalItem as Item, Flex, + DropdownMenu, } from '@wordpress/components'; -import { page } from '@wordpress/icons'; +import { moreVertical, page } from '@wordpress/icons'; import { ClockIcon, WordPressIcon } from '@wp-playground/components'; import { setActiveSite, @@ -27,6 +28,10 @@ import { } from '../../../lib/state/redux/slice-sites'; import { PlaygroundRoute, redirectTo } from '../../../lib/state/url/router'; import { setSiteManagerSection } from '../../../lib/state/redux/slice-ui'; +import { WordPressPRMenuItem } from '../../toolbar-buttons/wordpress-pr-menu-item'; +import { GutenbergPRMenuItem } from '../../toolbar-buttons/gutenberg-pr-menu-item'; +import { RestoreFromZipMenuItem } from '../../toolbar-buttons/restore-from-zip'; +import { GithubImportMenuItem } from '../../toolbar-buttons/github-import-menu-item'; export function Sidebar({ className, @@ -35,6 +40,7 @@ export function Sidebar({ className?: string; afterSiteClick?: (slug: string) => void; }) { + const offline = useAppSelector((state) => state.ui.offline); const storedSites = useAppSelector(selectSortedSites).filter( (site) => site.metadata.storage !== 'none' ); @@ -86,11 +92,50 @@ export function Sidebar({ role="" aria-orientation={undefined} > -

WordPress Playground

-
- {/* Remove Playground logo because branding isn't finalized. */} - {/* */} -
+ {/* Padding 3px is because of focus on dropdown button */} + +

WordPress Playground

+
+ {/* Remove Playground logo because branding isn't finalized. */} + {/* */} +
+ + {({ onClose }) => ( + <> + + + + + + )} + +