From 8d8fa4c3225af538e4ca3ad8ddeceb53a363bad8 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Thu, 28 Jan 2021 09:33:20 -0800 Subject: [PATCH] chore: move trace viewer to the src/web (#5199) --- .storybook/main.js | 3 +- .storybook/preview.js | 6 +- src/cli/traceViewer/traceViewer.ts | 4 +- .../web/styles.tsx => web/common.css} | 17 +- src/web/components/source.css | 36 ++ src/web/components/source.stories.tsx | 100 ++++ src/web/components/source.tsx | 46 ++ src/web/components/toolbar.css | 23 + src/web/components/toolbar.stories.tsx | 458 ++++++++++++++++++ src/web/components/toolbar.tsx | 31 ++ src/web/components/toolbarButton.css | 30 ++ src/web/components/toolbarButton.stories.tsx | 33 ++ src/web/components/toolbarButton.tsx | 34 ++ src/web/recorder/index.html | 27 ++ src/web/recorder/index.tsx | 32 ++ src/web/recorder/webpack.config.js | 41 ++ src/{cli/traceViewer => }/web/theme.ts | 11 - .../web/third_party/vscode/LICENSE.txt | 0 .../web/third_party/vscode/codicon.css | 0 .../web/third_party/vscode/codicon.ttf | Bin 61024 -> 62564 bytes .../web => web/traceViewer}/geometry.ts | 0 .../web => web/traceViewer}/index.html | 0 .../web => web/traceViewer}/index.tsx | 5 +- .../web => web/traceViewer}/ui/actionList.css | 0 .../traceViewer}/ui/actionList.stories.tsx | 0 .../web => web/traceViewer}/ui/actionList.tsx | 2 +- .../ui/assets/action-thumbnail-click.png | Bin .../ui/assets/action-thumbnail-goto.png | Bin .../traceViewer}/ui/contextSelector.css | 0 .../traceViewer}/ui/contextSelector.tsx | 2 +- .../web => web/traceViewer}/ui/helpers.tsx | 0 .../web => web/traceViewer}/ui/logsTab.css | 0 .../web => web/traceViewer}/ui/logsTab.tsx | 2 +- .../ui/networkResourceDetails.css | 0 .../ui/networkResourceDetails.tsx | 2 +- .../web => web/traceViewer}/ui/networkTab.css | 0 .../web => web/traceViewer}/ui/networkTab.tsx | 2 +- .../traceViewer}/ui/propertiesTabbedPane.css | 0 .../traceViewer}/ui/propertiesTabbedPane.tsx | 2 +- .../web => web/traceViewer}/ui/sourceTab.css | 0 .../web => web/traceViewer}/ui/sourceTab.tsx | 6 +- .../web => web/traceViewer}/ui/timeline.css | 0 .../web => web/traceViewer}/ui/timeline.tsx | 2 +- .../web => web/traceViewer}/ui/workbench.css | 0 .../web => web/traceViewer}/ui/workbench.tsx | 4 +- .../traceViewer/webpack.config.js} | 2 +- src/{cli/traceViewer => }/web/types.d.ts | 0 utils/build/build.js | 3 +- utils/check_deps.js | 5 +- 49 files changed, 919 insertions(+), 52 deletions(-) rename src/{cli/traceViewer/web/styles.tsx => web/common.css} (85%) create mode 100644 src/web/components/source.css create mode 100644 src/web/components/source.stories.tsx create mode 100644 src/web/components/source.tsx create mode 100644 src/web/components/toolbar.css create mode 100644 src/web/components/toolbar.stories.tsx create mode 100644 src/web/components/toolbar.tsx create mode 100644 src/web/components/toolbarButton.css create mode 100644 src/web/components/toolbarButton.stories.tsx create mode 100644 src/web/components/toolbarButton.tsx create mode 100644 src/web/recorder/index.html create mode 100644 src/web/recorder/index.tsx create mode 100644 src/web/recorder/webpack.config.js rename src/{cli/traceViewer => }/web/theme.ts (74%) rename src/{cli/traceViewer => }/web/third_party/vscode/LICENSE.txt (100%) rename src/{cli/traceViewer => }/web/third_party/vscode/codicon.css (100%) rename src/{cli/traceViewer => }/web/third_party/vscode/codicon.ttf (74%) rename src/{cli/traceViewer/web => web/traceViewer}/geometry.ts (100%) rename src/{cli/traceViewer/web => web/traceViewer}/index.html (100%) rename src/{cli/traceViewer/web => web/traceViewer}/index.tsx (91%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/actionList.css (100%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/actionList.stories.tsx (100%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/actionList.tsx (97%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/assets/action-thumbnail-click.png (100%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/assets/action-thumbnail-goto.png (100%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/contextSelector.css (100%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/contextSelector.tsx (95%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/helpers.tsx (100%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/logsTab.css (100%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/logsTab.tsx (94%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/networkResourceDetails.css (100%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/networkResourceDetails.tsx (98%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/networkTab.css (100%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/networkTab.tsx (94%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/propertiesTabbedPane.css (100%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/propertiesTabbedPane.tsx (98%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/sourceTab.css (100%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/sourceTab.tsx (96%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/timeline.css (100%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/timeline.tsx (99%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/workbench.css (100%) rename src/{cli/traceViewer/web => web/traceViewer}/ui/workbench.tsx (96%) rename src/{cli/traceViewer/web/web.webpack.config.js => web/traceViewer/webpack.config.js} (92%) rename src/{cli/traceViewer => }/web/types.d.ts (100%) diff --git a/.storybook/main.js b/.storybook/main.js index 29b99c383c..f421c92473 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,6 +1,7 @@ module.exports = { "stories": [ - "../src/cli/traceViewer/web/ui/*.stories.tsx", + "../src/web/traceViewer/ui/*.stories.tsx", + "../src/web/components/*.stories.tsx", ], "addons": [ "@storybook/addon-links", diff --git a/.storybook/preview.js b/.storybook/preview.js index f94984aa88..62e070a21c 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,16 +1,14 @@ import { addDecorator } from '@storybook/react'; -import { GlobalStyles } from '../src/cli/traceViewer/web/styles'; -import { applyTheme } from '../src/cli/traceViewer/web/theme'; +import '../src/web/common.css'; +import { applyTheme } from '../src/web/theme'; export const parameters = { actions: { argTypesRegex: "^on[A-Z].*" }, } - addDecorator(storyFn => { applyTheme(); return
- {storyFn()}
}); diff --git a/src/cli/traceViewer/traceViewer.ts b/src/cli/traceViewer/traceViewer.ts index b3a168c62b..5b6fcd75f8 100644 --- a/src/cli/traceViewer/traceViewer.ts +++ b/src/cli/traceViewer/traceViewer.ts @@ -81,13 +81,13 @@ class TraceViewer { async show() { const browser = await playwright.chromium.launch({ headless: false }); const server = await SnapshotServer.create( - path.join(__dirname, 'web'), + path.join(__dirname, '..', '..', 'web'), this._document ? this._document.resourcesDir : undefined, this._document ? this._document.model : emptyModel, this._document ? new ScreenshotGenerator(this._document.resourcesDir, this._document.model) : undefined); const uiPage = await browser.newPage({ viewport: null }); uiPage.on('close', () => process.exit(0)); - await uiPage.goto(server.traceViewerUrl('index.html')); + await uiPage.goto(server.traceViewerUrl('traceViewer/index.html')); } } diff --git a/src/cli/traceViewer/web/styles.tsx b/src/web/common.css similarity index 85% rename from src/cli/traceViewer/web/styles.tsx rename to src/web/common.css index dcc0aa488c..eb8ba18809 100644 --- a/src/cli/traceViewer/web/styles.tsx +++ b/src/web/common.css @@ -14,9 +14,6 @@ limitations under the License. */ -import * as React from 'react'; - -export const GlobalStyles = () => ; diff --git a/src/web/components/source.css b/src/web/components/source.css new file mode 100644 index 0000000000..eed5a34625 --- /dev/null +++ b/src/web/components/source.css @@ -0,0 +1,36 @@ +/* + Copyright (c) Microsoft Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +.pw-source { + white-space: pre; + overflow: auto; + font-family: var(--monospace-font); + font-size: 11px; + line-height: 16px; + background: white; +} + +.pw-source-line { + display: flex; +} + +.pw-source-line-number { + padding: 0 8px; + width: 30px; + text-align: right; + background: #edebe9; + user-select: none; +} diff --git a/src/web/components/source.stories.tsx b/src/web/components/source.stories.tsx new file mode 100644 index 0000000000..4d723bcb28 --- /dev/null +++ b/src/web/components/source.stories.tsx @@ -0,0 +1,100 @@ +/* + Copyright (c) Microsoft Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import { Story, Meta } from '@storybook/react/types-6-0'; +import React from 'react'; +import { Source, SourceProps } from './source'; + +export default { + title: 'Components/Source', + component: Source, +} as Meta; + +const Template: Story = args => ; + +export const Primary = Template.bind({}); +Primary.args = { + text: `const { chromium, devices } = require('.'); + +(async () => { + const browser = await chromium.launch({ + headless: false + }); + const context = await browser.newContext({ + // ...devices['iPhone 11'] + }); + + // Open new page + const page = await context.newPage(); + + // Go to https://github.com/microsoft + await page.goto('https://github.com/microsoft'); + await page._pause(); + + // Click input[aria-label="Find a repository…"] + await page.click('input[aria-label="Find a repository…"]'); + + // Fill input[aria-label="Find a repository…"] + await Promise.all([ + page.waitForNavigation(/*{ url: 'https://github.com/microsoft?q=playwright&type=&language=' }*/), + page.fill('input[aria-label="Find a repository…"]', 'playwright') + ]); + + // Click //a[normalize-space(.)='playwright'] + await page.click('//a[normalize-space(.)=\'playwright\']'); + // assert.equal(page.url(), 'https://github.com/microsoft/playwright'); + + // Click text="Issues" + await Promise.all([ + page.waitForNavigation(/*{ url: 'https://github.com/microsoft/playwright/issues' }*/), + page.click('text="Issues"') + ]); + + // Click text="triaging" + await Promise.all([ + page.waitForNavigation(/*{ url: 'https://github.com/microsoft/playwright/issues?q=is:issue+is:open+label:triaging' }*/), + page.click('text="triaging"') + ]); + + // Click text=/.*\[BUG\]\[Electron\] page\.waitForSe.*/ + await Promise.all([ + page.waitForNavigation(/*{ url: 'https://github.com/microsoft/playwright/issues/4961' }*/), + page.click('text=/.*\\\[BUG\\\]\\\[Electron\\\] page\.waitForSe.*/') + ]); + await page._pause(); + + // Click div[id="partial-users-participants"] img[alt="@pavelfeldman"] + await page.click('div[id="partial-users-participants"] img[alt="@pavelfeldman"]'); + // assert.equal(page.url(), 'https://github.com/pavelfeldman'); + await page._pause(); + + // Click text=/.*Repositories.*/ + await Promise.all([ + page.waitForNavigation(/*{ url: 'https://github.com/pavelfeldman?tab=repositories' }*/), + page.click('text=/.*Repositories.*/') + ]); + await page._pause(); + + // Click text=/.*playwright.*/ + await page.click('text=/.*playwright.*/'); + // assert.equal(page.url(), 'https://github.com/pavelfeldman/playwright'); + await page._pause(); + + // --------------------- + await context.close(); + await browser.close(); +})();` +}; diff --git a/src/web/components/source.tsx b/src/web/components/source.tsx new file mode 100644 index 0000000000..9f2ec8b518 --- /dev/null +++ b/src/web/components/source.tsx @@ -0,0 +1,46 @@ +/* + Copyright (c) Microsoft Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import './source.css'; +import * as React from 'react'; +import highlightjs from '../../third_party/highlightjs/highlightjs'; +import '../../third_party/highlightjs/highlightjs/tomorrow.css'; + +export interface SourceProps { + text: string, + targetLine: number +} + +export const Source: React.FC = ({ + text = '', +}) => { + const result = []; + let continuation: any; + for (const line of text.split('\n')) { + const highlighted = highlightjs.highlight('javascript', line, true, continuation); + continuation = highlighted.top; + result.push(highlighted.value); + } + + return
{ + result.map((markup, index) => { + return
+
{index + 1}
+
+
; + }) + }
+}; diff --git a/src/web/components/toolbar.css b/src/web/components/toolbar.css new file mode 100644 index 0000000000..b3143b10df --- /dev/null +++ b/src/web/components/toolbar.css @@ -0,0 +1,23 @@ +/* + Copyright (c) Microsoft Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +.pw-toolbar { + box-shadow: rgba(0, 0, 0, 0.1) 0px -1px 0px 0px inset; + background: rgb(255, 255, 255); + height: 40px; + align-items: center; + padding-right: 10px; +} diff --git a/src/web/components/toolbar.stories.tsx b/src/web/components/toolbar.stories.tsx new file mode 100644 index 0000000000..6c5ca3918f --- /dev/null +++ b/src/web/components/toolbar.stories.tsx @@ -0,0 +1,458 @@ +/* + Copyright (c) Microsoft Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import { Story, Meta } from '@storybook/react/types-6-0'; +import React from 'react'; +import { Toolbar, ToolbarProps } from './toolbar'; + +export default { + title: 'Components/Toolbar', + component: Toolbar, +} as Meta; + +const Template: Story = args => ; + +export const Primary = Template.bind({}); +Primary.args = { + buttons: [ + { title: 'Copy', icon: 'clone', onClick: () => {} }, + { title: 'Erase', icon: 'trashcan', onClick: () => {} }, + { title: 'Close', icon: 'close', onClick: () => {} }, + ] +}; + +export const All = Template.bind({}); +All.args = { + buttons: [ + { title: 'Close', icon: 'add', onClose: () => {} }, + { title: 'Close', icon: 'plus', onClose: () => {} }, + { title: 'Close', icon: 'gist-new', onClose: () => {} }, + { title: 'Close', icon: 'repo-create', onClose: () => {} }, + { title: 'Close', icon: 'lightbulb', onClose: () => {} }, + { title: 'Close', icon: 'light-bulb', onClose: () => {} }, + { title: 'Close', icon: 'repo', onClose: () => {} }, + { title: 'Close', icon: 'repo-delete', onClose: () => {} }, + { title: 'Close', icon: 'gist-fork', onClose: () => {} }, + { title: 'Close', icon: 'repo-forked', onClose: () => {} }, + { title: 'Close', icon: 'git-pull-request', onClose: () => {} }, + { title: 'Close', icon: 'git-pull-request-abandoned', onClose: () => {} }, + { title: 'Close', icon: 'record-keys', onClose: () => {} }, + { title: 'Close', icon: 'keyboard', onClose: () => {} }, + { title: 'Close', icon: 'tag', onClose: () => {} }, + { title: 'Close', icon: 'tag-add', onClose: () => {} }, + { title: 'Close', icon: 'tag-remove', onClose: () => {} }, + { title: 'Close', icon: 'person', onClose: () => {} }, + { title: 'Close', icon: 'person-add', onClose: () => {} }, + { title: 'Close', icon: 'person-follow', onClose: () => {} }, + { title: 'Close', icon: 'person-outline', onClose: () => {} }, + { title: 'Close', icon: 'person-filled', onClose: () => {} }, + { title: 'Close', icon: 'git-branch', onClose: () => {} }, + { title: 'Close', icon: 'git-branch-create', onClose: () => {} }, + { title: 'Close', icon: 'git-branch-delete', onClose: () => {} }, + { title: 'Close', icon: 'source-control', onClose: () => {} }, + { title: 'Close', icon: 'mirror', onClose: () => {} }, + { title: 'Close', icon: 'mirror-public', onClose: () => {} }, + { title: 'Close', icon: 'star', onClose: () => {} }, + { title: 'Close', icon: 'star-add', onClose: () => {} }, + { title: 'Close', icon: 'star-delete', onClose: () => {} }, + { title: 'Close', icon: 'star-empty', onClose: () => {} }, + { title: 'Close', icon: 'comment', onClose: () => {} }, + { title: 'Close', icon: 'comment-add', onClose: () => {} }, + { title: 'Close', icon: 'alert', onClose: () => {} }, + { title: 'Close', icon: 'warning', onClose: () => {} }, + { title: 'Close', icon: 'search', onClose: () => {} }, + { title: 'Close', icon: 'search-save', onClose: () => {} }, + { title: 'Close', icon: 'log-out', onClose: () => {} }, + { title: 'Close', icon: 'sign-out', onClose: () => {} }, + { title: 'Close', icon: 'log-in', onClose: () => {} }, + { title: 'Close', icon: 'sign-in', onClose: () => {} }, + { title: 'Close', icon: 'eye', onClose: () => {} }, + { title: 'Close', icon: 'eye-unwatch', onClose: () => {} }, + { title: 'Close', icon: 'eye-watch', onClose: () => {} }, + { title: 'Close', icon: 'circle-filled', onClose: () => {} }, + { title: 'Close', icon: 'primitive-dot', onClose: () => {} }, + { title: 'Close', icon: 'close-dirty', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-disabled', onClose: () => {} }, + { title: 'Close', icon: 'debug-hint', onClose: () => {} }, + { title: 'Close', icon: 'primitive-square', onClose: () => {} }, + { title: 'Close', icon: 'edit', onClose: () => {} }, + { title: 'Close', icon: 'pencil', onClose: () => {} }, + { title: 'Close', icon: 'info', onClose: () => {} }, + { title: 'Close', icon: 'issue-opened', onClose: () => {} }, + { title: 'Close', icon: 'gist-private', onClose: () => {} }, + { title: 'Close', icon: 'git-fork-private', onClose: () => {} }, + { title: 'Close', icon: 'lock', onClose: () => {} }, + { title: 'Close', icon: 'mirror-private', onClose: () => {} }, + { title: 'Close', icon: 'close', onClose: () => {} }, + { title: 'Close', icon: 'remove-close', onClose: () => {} }, + { title: 'Close', icon: 'x', onClose: () => {} }, + { title: 'Close', icon: 'repo-sync', onClose: () => {} }, + { title: 'Close', icon: 'sync', onClose: () => {} }, + { title: 'Close', icon: 'clone', onClose: () => {} }, + { title: 'Close', icon: 'desktop-download', onClose: () => {} }, + { title: 'Close', icon: 'beaker', onClose: () => {} }, + { title: 'Close', icon: 'microscope', onClose: () => {} }, + { title: 'Close', icon: 'vm', onClose: () => {} }, + { title: 'Close', icon: 'device-desktop', onClose: () => {} }, + { title: 'Close', icon: 'file', onClose: () => {} }, + { title: 'Close', icon: 'file-text', onClose: () => {} }, + { title: 'Close', icon: 'more', onClose: () => {} }, + { title: 'Close', icon: 'ellipsis', onClose: () => {} }, + { title: 'Close', icon: 'kebab-horizontal', onClose: () => {} }, + { title: 'Close', icon: 'mail-reply', onClose: () => {} }, + { title: 'Close', icon: 'reply', onClose: () => {} }, + { title: 'Close', icon: 'organization', onClose: () => {} }, + { title: 'Close', icon: 'organization-filled', onClose: () => {} }, + { title: 'Close', icon: 'organization-outline', onClose: () => {} }, + { title: 'Close', icon: 'new-file', onClose: () => {} }, + { title: 'Close', icon: 'file-add', onClose: () => {} }, + { title: 'Close', icon: 'new-folder', onClose: () => {} }, + { title: 'Close', icon: 'file-directory-create', onClose: () => {} }, + { title: 'Close', icon: 'trash', onClose: () => {} }, + { title: 'Close', icon: 'trashcan', onClose: () => {} }, + { title: 'Close', icon: 'history', onClose: () => {} }, + { title: 'Close', icon: 'clock', onClose: () => {} }, + { title: 'Close', icon: 'folder', onClose: () => {} }, + { title: 'Close', icon: 'file-directory', onClose: () => {} }, + { title: 'Close', icon: 'symbol-folder', onClose: () => {} }, + { title: 'Close', icon: 'logo-github', onClose: () => {} }, + { title: 'Close', icon: 'mark-github', onClose: () => {} }, + { title: 'Close', icon: 'github', onClose: () => {} }, + { title: 'Close', icon: 'terminal', onClose: () => {} }, + { title: 'Close', icon: 'console', onClose: () => {} }, + { title: 'Close', icon: 'repl', onClose: () => {} }, + { title: 'Close', icon: 'zap', onClose: () => {} }, + { title: 'Close', icon: 'symbol-event', onClose: () => {} }, + { title: 'Close', icon: 'error', onClose: () => {} }, + { title: 'Close', icon: 'stop', onClose: () => {} }, + { title: 'Close', icon: 'variable', onClose: () => {} }, + { title: 'Close', icon: 'symbol-variable', onClose: () => {} }, + { title: 'Close', icon: 'array', onClose: () => {} }, + { title: 'Close', icon: 'symbol-array', onClose: () => {} }, + { title: 'Close', icon: 'symbol-module', onClose: () => {} }, + { title: 'Close', icon: 'symbol-package', onClose: () => {} }, + { title: 'Close', icon: 'symbol-namespace', onClose: () => {} }, + { title: 'Close', icon: 'symbol-object', onClose: () => {} }, + { title: 'Close', icon: 'symbol-method', onClose: () => {} }, + { title: 'Close', icon: 'symbol-function', onClose: () => {} }, + { title: 'Close', icon: 'symbol-constructor', onClose: () => {} }, + { title: 'Close', icon: 'symbol-boolean', onClose: () => {} }, + { title: 'Close', icon: 'symbol-null', onClose: () => {} }, + { title: 'Close', icon: 'symbol-numeric', onClose: () => {} }, + { title: 'Close', icon: 'symbol-number', onClose: () => {} }, + { title: 'Close', icon: 'symbol-structure', onClose: () => {} }, + { title: 'Close', icon: 'symbol-struct', onClose: () => {} }, + { title: 'Close', icon: 'symbol-parameter', onClose: () => {} }, + { title: 'Close', icon: 'symbol-type-parameter', onClose: () => {} }, + { title: 'Close', icon: 'symbol-key', onClose: () => {} }, + { title: 'Close', icon: 'symbol-text', onClose: () => {} }, + { title: 'Close', icon: 'symbol-reference', onClose: () => {} }, + { title: 'Close', icon: 'go-to-file', onClose: () => {} }, + { title: 'Close', icon: 'symbol-enum', onClose: () => {} }, + { title: 'Close', icon: 'symbol-value', onClose: () => {} }, + { title: 'Close', icon: 'symbol-ruler', onClose: () => {} }, + { title: 'Close', icon: 'symbol-unit', onClose: () => {} }, + { title: 'Close', icon: 'activate-breakpoints', onClose: () => {} }, + { title: 'Close', icon: 'archive', onClose: () => {} }, + { title: 'Close', icon: 'arrow-both', onClose: () => {} }, + { title: 'Close', icon: 'arrow-down', onClose: () => {} }, + { title: 'Close', icon: 'arrow-left', onClose: () => {} }, + { title: 'Close', icon: 'arrow-right', onClose: () => {} }, + { title: 'Close', icon: 'arrow-small-down', onClose: () => {} }, + { title: 'Close', icon: 'arrow-small-left', onClose: () => {} }, + { title: 'Close', icon: 'arrow-small-right', onClose: () => {} }, + { title: 'Close', icon: 'arrow-small-up', onClose: () => {} }, + { title: 'Close', icon: 'arrow-up', onClose: () => {} }, + { title: 'Close', icon: 'bell', onClose: () => {} }, + { title: 'Close', icon: 'bold', onClose: () => {} }, + { title: 'Close', icon: 'book', onClose: () => {} }, + { title: 'Close', icon: 'bookmark', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-conditional-unverified', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-conditional', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-conditional-disabled', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-data-unverified', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-data', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-data-disabled', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-log-unverified', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-log', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-log-disabled', onClose: () => {} }, + { title: 'Close', icon: 'briefcase', onClose: () => {} }, + { title: 'Close', icon: 'broadcast', onClose: () => {} }, + { title: 'Close', icon: 'browser', onClose: () => {} }, + { title: 'Close', icon: 'bug', onClose: () => {} }, + { title: 'Close', icon: 'calendar', onClose: () => {} }, + { title: 'Close', icon: 'case-sensitive', onClose: () => {} }, + { title: 'Close', icon: 'check', onClose: () => {} }, + { title: 'Close', icon: 'checklist', onClose: () => {} }, + { title: 'Close', icon: 'chevron-down', onClose: () => {} }, + { title: 'Close', icon: 'chevron-left', onClose: () => {} }, + { title: 'Close', icon: 'chevron-right', onClose: () => {} }, + { title: 'Close', icon: 'chevron-up', onClose: () => {} }, + { title: 'Close', icon: 'chrome-close', onClose: () => {} }, + { title: 'Close', icon: 'chrome-maximize', onClose: () => {} }, + { title: 'Close', icon: 'chrome-minimize', onClose: () => {} }, + { title: 'Close', icon: 'chrome-restore', onClose: () => {} }, + { title: 'Close', icon: 'circle-outline', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-unverified', onClose: () => {} }, + { title: 'Close', icon: 'circle-slash', onClose: () => {} }, + { title: 'Close', icon: 'circuit-board', onClose: () => {} }, + { title: 'Close', icon: 'clear-all', onClose: () => {} }, + { title: 'Close', icon: 'clippy', onClose: () => {} }, + { title: 'Close', icon: 'close-all', onClose: () => {} }, + { title: 'Close', icon: 'cloud-download', onClose: () => {} }, + { title: 'Close', icon: 'cloud-upload', onClose: () => {} }, + { title: 'Close', icon: 'code', onClose: () => {} }, + { title: 'Close', icon: 'collapse-all', onClose: () => {} }, + { title: 'Close', icon: 'color-mode', onClose: () => {} }, + { title: 'Close', icon: 'comment-discussion', onClose: () => {} }, + { title: 'Close', icon: 'compare-changes', onClose: () => {} }, + { title: 'Close', icon: 'credit-card', onClose: () => {} }, + { title: 'Close', icon: 'dash', onClose: () => {} }, + { title: 'Close', icon: 'dashboard', onClose: () => {} }, + { title: 'Close', icon: 'database', onClose: () => {} }, + { title: 'Close', icon: 'debug-continue', onClose: () => {} }, + { title: 'Close', icon: 'debug-disconnect', onClose: () => {} }, + { title: 'Close', icon: 'debug-pause', onClose: () => {} }, + { title: 'Close', icon: 'debug-restart', onClose: () => {} }, + { title: 'Close', icon: 'debug-start', onClose: () => {} }, + { title: 'Close', icon: 'debug-step-into', onClose: () => {} }, + { title: 'Close', icon: 'debug-step-out', onClose: () => {} }, + { title: 'Close', icon: 'debug-step-over', onClose: () => {} }, + { title: 'Close', icon: 'debug-stop', onClose: () => {} }, + { title: 'Close', icon: 'debug', onClose: () => {} }, + { title: 'Close', icon: 'device-camera-video', onClose: () => {} }, + { title: 'Close', icon: 'device-camera', onClose: () => {} }, + { title: 'Close', icon: 'device-mobile', onClose: () => {} }, + { title: 'Close', icon: 'diff-added', onClose: () => {} }, + { title: 'Close', icon: 'diff-ignored', onClose: () => {} }, + { title: 'Close', icon: 'diff-modified', onClose: () => {} }, + { title: 'Close', icon: 'diff-removed', onClose: () => {} }, + { title: 'Close', icon: 'diff-renamed', onClose: () => {} }, + { title: 'Close', icon: 'diff', onClose: () => {} }, + { title: 'Close', icon: 'discard', onClose: () => {} }, + { title: 'Close', icon: 'editor-layout', onClose: () => {} }, + { title: 'Close', icon: 'empty-window', onClose: () => {} }, + { title: 'Close', icon: 'exclude', onClose: () => {} }, + { title: 'Close', icon: 'extensions', onClose: () => {} }, + { title: 'Close', icon: 'eye-closed', onClose: () => {} }, + { title: 'Close', icon: 'file-binary', onClose: () => {} }, + { title: 'Close', icon: 'file-code', onClose: () => {} }, + { title: 'Close', icon: 'file-media', onClose: () => {} }, + { title: 'Close', icon: 'file-pdf', onClose: () => {} }, + { title: 'Close', icon: 'file-submodule', onClose: () => {} }, + { title: 'Close', icon: 'file-symlink-directory', onClose: () => {} }, + { title: 'Close', icon: 'file-symlink-file', onClose: () => {} }, + { title: 'Close', icon: 'file-zip', onClose: () => {} }, + { title: 'Close', icon: 'files', onClose: () => {} }, + { title: 'Close', icon: 'filter', onClose: () => {} }, + { title: 'Close', icon: 'flame', onClose: () => {} }, + { title: 'Close', icon: 'fold-down', onClose: () => {} }, + { title: 'Close', icon: 'fold-up', onClose: () => {} }, + { title: 'Close', icon: 'fold', onClose: () => {} }, + { title: 'Close', icon: 'folder-active', onClose: () => {} }, + { title: 'Close', icon: 'folder-opened', onClose: () => {} }, + { title: 'Close', icon: 'gear', onClose: () => {} }, + { title: 'Close', icon: 'gift', onClose: () => {} }, + { title: 'Close', icon: 'gist-secret', onClose: () => {} }, + { title: 'Close', icon: 'gist', onClose: () => {} }, + { title: 'Close', icon: 'git-commit', onClose: () => {} }, + { title: 'Close', icon: 'git-compare', onClose: () => {} }, + { title: 'Close', icon: 'git-merge', onClose: () => {} }, + { title: 'Close', icon: 'github-action', onClose: () => {} }, + { title: 'Close', icon: 'github-alt', onClose: () => {} }, + { title: 'Close', icon: 'globe', onClose: () => {} }, + { title: 'Close', icon: 'grabber', onClose: () => {} }, + { title: 'Close', icon: 'graph', onClose: () => {} }, + { title: 'Close', icon: 'gripper', onClose: () => {} }, + { title: 'Close', icon: 'heart', onClose: () => {} }, + { title: 'Close', icon: 'home', onClose: () => {} }, + { title: 'Close', icon: 'horizontal-rule', onClose: () => {} }, + { title: 'Close', icon: 'hubot', onClose: () => {} }, + { title: 'Close', icon: 'inbox', onClose: () => {} }, + { title: 'Close', icon: 'issue-closed', onClose: () => {} }, + { title: 'Close', icon: 'issue-reopened', onClose: () => {} }, + { title: 'Close', icon: 'issues', onClose: () => {} }, + { title: 'Close', icon: 'italic', onClose: () => {} }, + { title: 'Close', icon: 'jersey', onClose: () => {} }, + { title: 'Close', icon: 'json', onClose: () => {} }, + { title: 'Close', icon: 'kebab-vertical', onClose: () => {} }, + { title: 'Close', icon: 'key', onClose: () => {} }, + { title: 'Close', icon: 'law', onClose: () => {} }, + { title: 'Close', icon: 'lightbulb-autofix', onClose: () => {} }, + { title: 'Close', icon: 'link-external', onClose: () => {} }, + { title: 'Close', icon: 'link', onClose: () => {} }, + { title: 'Close', icon: 'list-ordered', onClose: () => {} }, + { title: 'Close', icon: 'list-unordered', onClose: () => {} }, + { title: 'Close', icon: 'live-share', onClose: () => {} }, + { title: 'Close', icon: 'loading', onClose: () => {} }, + { title: 'Close', icon: 'location', onClose: () => {} }, + { title: 'Close', icon: 'mail-read', onClose: () => {} }, + { title: 'Close', icon: 'mail', onClose: () => {} }, + { title: 'Close', icon: 'markdown', onClose: () => {} }, + { title: 'Close', icon: 'megaphone', onClose: () => {} }, + { title: 'Close', icon: 'mention', onClose: () => {} }, + { title: 'Close', icon: 'milestone', onClose: () => {} }, + { title: 'Close', icon: 'mortar-board', onClose: () => {} }, + { title: 'Close', icon: 'move', onClose: () => {} }, + { title: 'Close', icon: 'multiple-windows', onClose: () => {} }, + { title: 'Close', icon: 'mute', onClose: () => {} }, + { title: 'Close', icon: 'no-newline', onClose: () => {} }, + { title: 'Close', icon: 'note', onClose: () => {} }, + { title: 'Close', icon: 'octoface', onClose: () => {} }, + { title: 'Close', icon: 'open-preview', onClose: () => {} }, + { title: 'Close', icon: 'package', onClose: () => {} }, + { title: 'Close', icon: 'paintcan', onClose: () => {} }, + { title: 'Close', icon: 'pin', onClose: () => {} }, + { title: 'Close', icon: 'play', onClose: () => {} }, + { title: 'Close', icon: 'run', onClose: () => {} }, + { title: 'Close', icon: 'plug', onClose: () => {} }, + { title: 'Close', icon: 'preserve-case', onClose: () => {} }, + { title: 'Close', icon: 'preview', onClose: () => {} }, + { title: 'Close', icon: 'project', onClose: () => {} }, + { title: 'Close', icon: 'pulse', onClose: () => {} }, + { title: 'Close', icon: 'question', onClose: () => {} }, + { title: 'Close', icon: 'quote', onClose: () => {} }, + { title: 'Close', icon: 'radio-tower', onClose: () => {} }, + { title: 'Close', icon: 'reactions', onClose: () => {} }, + { title: 'Close', icon: 'references', onClose: () => {} }, + { title: 'Close', icon: 'refresh', onClose: () => {} }, + { title: 'Close', icon: 'regex', onClose: () => {} }, + { title: 'Close', icon: 'remote-explorer', onClose: () => {} }, + { title: 'Close', icon: 'remote', onClose: () => {} }, + { title: 'Close', icon: 'remove', onClose: () => {} }, + { title: 'Close', icon: 'replace-all', onClose: () => {} }, + { title: 'Close', icon: 'replace', onClose: () => {} }, + { title: 'Close', icon: 'repo-clone', onClose: () => {} }, + { title: 'Close', icon: 'repo-force-push', onClose: () => {} }, + { title: 'Close', icon: 'repo-pull', onClose: () => {} }, + { title: 'Close', icon: 'repo-push', onClose: () => {} }, + { title: 'Close', icon: 'report', onClose: () => {} }, + { title: 'Close', icon: 'request-changes', onClose: () => {} }, + { title: 'Close', icon: 'rocket', onClose: () => {} }, + { title: 'Close', icon: 'root-folder-opened', onClose: () => {} }, + { title: 'Close', icon: 'root-folder', onClose: () => {} }, + { title: 'Close', icon: 'rss', onClose: () => {} }, + { title: 'Close', icon: 'ruby', onClose: () => {} }, + { title: 'Close', icon: 'save-all', onClose: () => {} }, + { title: 'Close', icon: 'save-as', onClose: () => {} }, + { title: 'Close', icon: 'save', onClose: () => {} }, + { title: 'Close', icon: 'screen-full', onClose: () => {} }, + { title: 'Close', icon: 'screen-normal', onClose: () => {} }, + { title: 'Close', icon: 'search-stop', onClose: () => {} }, + { title: 'Close', icon: 'server', onClose: () => {} }, + { title: 'Close', icon: 'settings-gear', onClose: () => {} }, + { title: 'Close', icon: 'settings', onClose: () => {} }, + { title: 'Close', icon: 'shield', onClose: () => {} }, + { title: 'Close', icon: 'smiley', onClose: () => {} }, + { title: 'Close', icon: 'sort-precedence', onClose: () => {} }, + { title: 'Close', icon: 'split-horizontal', onClose: () => {} }, + { title: 'Close', icon: 'split-vertical', onClose: () => {} }, + { title: 'Close', icon: 'squirrel', onClose: () => {} }, + { title: 'Close', icon: 'star-full', onClose: () => {} }, + { title: 'Close', icon: 'star-half', onClose: () => {} }, + { title: 'Close', icon: 'symbol-class', onClose: () => {} }, + { title: 'Close', icon: 'symbol-color', onClose: () => {} }, + { title: 'Close', icon: 'symbol-constant', onClose: () => {} }, + { title: 'Close', icon: 'symbol-enum-member', onClose: () => {} }, + { title: 'Close', icon: 'symbol-field', onClose: () => {} }, + { title: 'Close', icon: 'symbol-file', onClose: () => {} }, + { title: 'Close', icon: 'symbol-interface', onClose: () => {} }, + { title: 'Close', icon: 'symbol-keyword', onClose: () => {} }, + { title: 'Close', icon: 'symbol-misc', onClose: () => {} }, + { title: 'Close', icon: 'symbol-operator', onClose: () => {} }, + { title: 'Close', icon: 'symbol-property', onClose: () => {} }, + { title: 'Close', icon: 'wrench', onClose: () => {} }, + { title: 'Close', icon: 'wrench-subaction', onClose: () => {} }, + { title: 'Close', icon: 'symbol-snippet', onClose: () => {} }, + { title: 'Close', icon: 'tasklist', onClose: () => {} }, + { title: 'Close', icon: 'telescope', onClose: () => {} }, + { title: 'Close', icon: 'text-size', onClose: () => {} }, + { title: 'Close', icon: 'three-bars', onClose: () => {} }, + { title: 'Close', icon: 'thumbsdown', onClose: () => {} }, + { title: 'Close', icon: 'thumbsup', onClose: () => {} }, + { title: 'Close', icon: 'tools', onClose: () => {} }, + { title: 'Close', icon: 'triangle-down', onClose: () => {} }, + { title: 'Close', icon: 'triangle-left', onClose: () => {} }, + { title: 'Close', icon: 'triangle-right', onClose: () => {} }, + { title: 'Close', icon: 'triangle-up', onClose: () => {} }, + { title: 'Close', icon: 'twitter', onClose: () => {} }, + { title: 'Close', icon: 'unfold', onClose: () => {} }, + { title: 'Close', icon: 'unlock', onClose: () => {} }, + { title: 'Close', icon: 'unmute', onClose: () => {} }, + { title: 'Close', icon: 'unverified', onClose: () => {} }, + { title: 'Close', icon: 'verified', onClose: () => {} }, + { title: 'Close', icon: 'versions', onClose: () => {} }, + { title: 'Close', icon: 'vm-active', onClose: () => {} }, + { title: 'Close', icon: 'vm-outline', onClose: () => {} }, + { title: 'Close', icon: 'vm-running', onClose: () => {} }, + { title: 'Close', icon: 'watch', onClose: () => {} }, + { title: 'Close', icon: 'whitespace', onClose: () => {} }, + { title: 'Close', icon: 'whole-word', onClose: () => {} }, + { title: 'Close', icon: 'window', onClose: () => {} }, + { title: 'Close', icon: 'word-wrap', onClose: () => {} }, + { title: 'Close', icon: 'zoom-in', onClose: () => {} }, + { title: 'Close', icon: 'zoom-out', onClose: () => {} }, + { title: 'Close', icon: 'list-filter', onClose: () => {} }, + { title: 'Close', icon: 'list-flat', onClose: () => {} }, + { title: 'Close', icon: 'list-selection', onClose: () => {} }, + { title: 'Close', icon: 'selection', onClose: () => {} }, + { title: 'Close', icon: 'list-tree', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-function-unverified', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-function', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-function-disabled', onClose: () => {} }, + { title: 'Close', icon: 'debug-stackframe-active', onClose: () => {} }, + { title: 'Close', icon: 'debug-stackframe-dot', onClose: () => {} }, + { title: 'Close', icon: 'debug-stackframe', onClose: () => {} }, + { title: 'Close', icon: 'debug-stackframe-focused', onClose: () => {} }, + { title: 'Close', icon: 'debug-breakpoint-unsupported', onClose: () => {} }, + { title: 'Close', icon: 'symbol-string', onClose: () => {} }, + { title: 'Close', icon: 'debug-reverse-continue', onClose: () => {} }, + { title: 'Close', icon: 'debug-step-back', onClose: () => {} }, + { title: 'Close', icon: 'debug-restart-frame', onClose: () => {} }, + { title: 'Close', icon: 'call-incoming', onClose: () => {} }, + { title: 'Close', icon: 'call-outgoing', onClose: () => {} }, + { title: 'Close', icon: 'menu', onClose: () => {} }, + { title: 'Close', icon: 'expand-all', onClose: () => {} }, + { title: 'Close', icon: 'feedback', onClose: () => {} }, + { title: 'Close', icon: 'group-by-ref-type', onClose: () => {} }, + { title: 'Close', icon: 'ungroup-by-ref-type', onClose: () => {} }, + { title: 'Close', icon: 'account', onClose: () => {} }, + { title: 'Close', icon: 'bell-dot', onClose: () => {} }, + { title: 'Close', icon: 'debug-console', onClose: () => {} }, + { title: 'Close', icon: 'library', onClose: () => {} }, + { title: 'Close', icon: 'output', onClose: () => {} }, + { title: 'Close', icon: 'run-all', onClose: () => {} }, + { title: 'Close', icon: 'sync-ignored', onClose: () => {} }, + { title: 'Close', icon: 'pinned', onClose: () => {} }, + { title: 'Close', icon: 'github-inverted', onClose: () => {} }, + { title: 'Close', icon: 'debug-alt', onClose: () => {} }, + { title: 'Close', icon: 'server-process', onClose: () => {} }, + { title: 'Close', icon: 'server-environment', onClose: () => {} }, + { title: 'Close', icon: 'pass', onClose: () => {} }, + { title: 'Close', icon: 'stop-circle', onClose: () => {} }, + { title: 'Close', icon: 'play-circle', onClose: () => {} }, + { title: 'Close', icon: 'record', onClose: () => {} }, + { title: 'Close', icon: 'debug-alt-small', onClose: () => {} }, + { title: 'Close', icon: 'vm-connect', onClose: () => {} }, + { title: 'Close', icon: 'cloud', onClose: () => {} }, + { title: 'Close', icon: 'merge', onClose: () => {} }, + { title: 'Close', icon: 'export', onClose: () => {} }, + { title: 'Close', icon: 'graph-left', onClose: () => {} }, + { title: 'Close', icon: 'magnet', onClose: () => {} }, + + ] +}; diff --git a/src/web/components/toolbar.tsx b/src/web/components/toolbar.tsx new file mode 100644 index 0000000000..520d3ade6b --- /dev/null +++ b/src/web/components/toolbar.tsx @@ -0,0 +1,31 @@ +/* + Copyright (c) Microsoft Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import './toolbar.css'; +import * as React from 'react'; +import { ToolbarButton, ToolbarButtonProps } from './toolbarButton'; + +export interface ToolbarProps { + buttons: ToolbarButtonProps[], + icon: string, + onClick: () => void +} + +export const Toolbar: React.FC = ({ + buttons = [], +}) => { + return
{buttons.map(props => )}
; +}; diff --git a/src/web/components/toolbarButton.css b/src/web/components/toolbarButton.css new file mode 100644 index 0000000000..9ca70ce279 --- /dev/null +++ b/src/web/components/toolbarButton.css @@ -0,0 +1,30 @@ +/* + Copyright (c) Microsoft Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +.pw-toolbar-button { + border: none; + outline: none; + color: #999; + background: transparent; + padding: 0; + margin-left: 10px; + height: 40px; + cursor: pointer; +} + +.pw-toolbar-button:hover { + color: #1ea7fd; +} diff --git a/src/web/components/toolbarButton.stories.tsx b/src/web/components/toolbarButton.stories.tsx new file mode 100644 index 0000000000..dd2dd22f88 --- /dev/null +++ b/src/web/components/toolbarButton.stories.tsx @@ -0,0 +1,33 @@ +/* + Copyright (c) Microsoft Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import { Story, Meta } from '@storybook/react/types-6-0'; +import React from 'react'; +import { ToolbarButton, ToolbarButtonProps } from './toolbarButton'; + +export default { + title: 'Components/ToolbarButton', + component: ToolbarButton, +} as Meta; + +const Template: Story = args => ; + +export const Primary = Template.bind({}); +Primary.args = { + title: 'Close', + icon: 'close', + onClick: () => {} +}; diff --git a/src/web/components/toolbarButton.tsx b/src/web/components/toolbarButton.tsx new file mode 100644 index 0000000000..c80515363a --- /dev/null +++ b/src/web/components/toolbarButton.tsx @@ -0,0 +1,34 @@ +/* + Copyright (c) Microsoft Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import './toolbarButton.css'; +import '../third_party/vscode/codicon.css'; +import * as React from 'react'; + +export interface ToolbarButtonProps { + title: string, + icon: string, + onClick: () => void +} + +export const ToolbarButton: React.FC = ({ + title = '', + icon = '', + onClick = () => {}, +}) => { + const className = `pw-toolbar-button codicon codicon-${icon}`; + return ; +}; diff --git a/src/web/recorder/index.html b/src/web/recorder/index.html new file mode 100644 index 0000000000..f49a3eaab2 --- /dev/null +++ b/src/web/recorder/index.html @@ -0,0 +1,27 @@ + + + + + + + + Playwright Recorder + + +
+ + diff --git a/src/web/recorder/index.tsx b/src/web/recorder/index.tsx new file mode 100644 index 0000000000..1d7379a97e --- /dev/null +++ b/src/web/recorder/index.tsx @@ -0,0 +1,32 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import '../third_party/vscode/codicon.css'; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { applyTheme } from '../theme'; +import '../common.css'; + +declare global { + interface Window { + } +} + +(async () => { + applyTheme(); + ReactDOM.render(
+
, document.querySelector('#root')); +})(); diff --git a/src/web/recorder/webpack.config.js b/src/web/recorder/webpack.config.js new file mode 100644 index 0000000000..89a35bc76a --- /dev/null +++ b/src/web/recorder/webpack.config.js @@ -0,0 +1,41 @@ +const path = require('path'); +const HtmlWebPackPlugin = require('html-webpack-plugin'); + +module.exports = { + mode: process.env.NODE_ENV === 'production' ? 'production' : 'development', + entry: { + app: path.join(__dirname, 'index.tsx'), + }, + resolve: { + extensions: ['.ts', '.js', '.tsx', '.jsx'] + }, + devtool: 'source-map', + output: { + globalObject: 'self', + filename: '[name].bundle.js', + path: path.resolve(__dirname, '../../../lib/web/recorder') + }, + module: { + rules: [ + { + test: /\.(j|t)sx?$/, + use: 'ts-loader', + exclude: /node_modules/ + }, + { + test: /\.css$/, + use: ['style-loader', 'css-loader'] + }, + { + test: /\.ttf$/, + use: ['file-loader'] + } + ] + }, + plugins: [ + new HtmlWebPackPlugin({ + title: 'Playwright Recorder', + template: path.join(__dirname, 'index.html'), + }) + ] +}; diff --git a/src/cli/traceViewer/web/theme.ts b/src/web/theme.ts similarity index 74% rename from src/cli/traceViewer/web/theme.ts rename to src/web/theme.ts index c7677d3f1c..9a1537e950 100644 --- a/src/cli/traceViewer/web/theme.ts +++ b/src/web/theme.ts @@ -14,16 +14,6 @@ * limitations under the License. */ -function platformName(): string { - if (window.navigator.userAgent.includes('Linux')) - return 'platform-linux'; - if (window.navigator.userAgent.includes('Windows')) - return 'platform-windows'; - if (window.navigator.userAgent.includes('Mac')) - return 'platform-mac'; - return 'platform-generic'; -} - export function applyTheme() { if ((document as any).playwrightThemeInitialized) return; @@ -35,5 +25,4 @@ export function applyTheme() { document!.defaultView!.addEventListener('blur', event => { document.body.classList.add('inactive'); }, false); - document.documentElement.classList.add(platformName()); } diff --git a/src/cli/traceViewer/web/third_party/vscode/LICENSE.txt b/src/web/third_party/vscode/LICENSE.txt similarity index 100% rename from src/cli/traceViewer/web/third_party/vscode/LICENSE.txt rename to src/web/third_party/vscode/LICENSE.txt diff --git a/src/cli/traceViewer/web/third_party/vscode/codicon.css b/src/web/third_party/vscode/codicon.css similarity index 100% rename from src/cli/traceViewer/web/third_party/vscode/codicon.css rename to src/web/third_party/vscode/codicon.css diff --git a/src/cli/traceViewer/web/third_party/vscode/codicon.ttf b/src/web/third_party/vscode/codicon.ttf similarity index 74% rename from src/cli/traceViewer/web/third_party/vscode/codicon.ttf rename to src/web/third_party/vscode/codicon.ttf index 82acc8995b8d7ee0338bc65547844f5f99b953ce..533199b8275168740ffd29558bd59698feea4e0b 100644 GIT binary patch delta 7873 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 delta 6330 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 N?=}T@e)nR?{{kh&i#q@S diff --git a/src/cli/traceViewer/web/geometry.ts b/src/web/traceViewer/geometry.ts similarity index 100% rename from src/cli/traceViewer/web/geometry.ts rename to src/web/traceViewer/geometry.ts diff --git a/src/cli/traceViewer/web/index.html b/src/web/traceViewer/index.html similarity index 100% rename from src/cli/traceViewer/web/index.html rename to src/web/traceViewer/index.html diff --git a/src/cli/traceViewer/web/index.tsx b/src/web/traceViewer/index.tsx similarity index 91% rename from src/cli/traceViewer/web/index.tsx rename to src/web/traceViewer/index.tsx index c2c7ccf418..240171b10e 100644 --- a/src/cli/traceViewer/web/index.tsx +++ b/src/web/traceViewer/index.tsx @@ -14,11 +14,12 @@ * limitations under the License. */ -import './third_party/vscode/codicon.css'; +import '../third_party/vscode/codicon.css'; import { Workbench } from './ui/workbench'; import * as React from 'react'; import * as ReactDOM from 'react-dom'; -import { applyTheme } from './theme'; +import { applyTheme } from '../theme'; +import '../common.css'; (async () => { navigator.serviceWorker.register('/service-worker.js'); diff --git a/src/cli/traceViewer/web/ui/actionList.css b/src/web/traceViewer/ui/actionList.css similarity index 100% rename from src/cli/traceViewer/web/ui/actionList.css rename to src/web/traceViewer/ui/actionList.css diff --git a/src/cli/traceViewer/web/ui/actionList.stories.tsx b/src/web/traceViewer/ui/actionList.stories.tsx similarity index 100% rename from src/cli/traceViewer/web/ui/actionList.stories.tsx rename to src/web/traceViewer/ui/actionList.stories.tsx diff --git a/src/cli/traceViewer/web/ui/actionList.tsx b/src/web/traceViewer/ui/actionList.tsx similarity index 97% rename from src/cli/traceViewer/web/ui/actionList.tsx rename to src/web/traceViewer/ui/actionList.tsx index c4c756e73d..17b6fd5a57 100644 --- a/src/cli/traceViewer/web/ui/actionList.tsx +++ b/src/web/traceViewer/ui/actionList.tsx @@ -14,7 +14,7 @@ limitations under the License. */ -import { ActionEntry } from '../../traceModel'; +import { ActionEntry } from '../../../cli/traceViewer/traceModel'; import './actionList.css'; import * as React from 'react'; diff --git a/src/cli/traceViewer/web/ui/assets/action-thumbnail-click.png b/src/web/traceViewer/ui/assets/action-thumbnail-click.png similarity index 100% rename from src/cli/traceViewer/web/ui/assets/action-thumbnail-click.png rename to src/web/traceViewer/ui/assets/action-thumbnail-click.png diff --git a/src/cli/traceViewer/web/ui/assets/action-thumbnail-goto.png b/src/web/traceViewer/ui/assets/action-thumbnail-goto.png similarity index 100% rename from src/cli/traceViewer/web/ui/assets/action-thumbnail-goto.png rename to src/web/traceViewer/ui/assets/action-thumbnail-goto.png diff --git a/src/cli/traceViewer/web/ui/contextSelector.css b/src/web/traceViewer/ui/contextSelector.css similarity index 100% rename from src/cli/traceViewer/web/ui/contextSelector.css rename to src/web/traceViewer/ui/contextSelector.css diff --git a/src/cli/traceViewer/web/ui/contextSelector.tsx b/src/web/traceViewer/ui/contextSelector.tsx similarity index 95% rename from src/cli/traceViewer/web/ui/contextSelector.tsx rename to src/web/traceViewer/ui/contextSelector.tsx index cf83feb526..eaf81c89ac 100644 --- a/src/cli/traceViewer/web/ui/contextSelector.tsx +++ b/src/web/traceViewer/ui/contextSelector.tsx @@ -15,7 +15,7 @@ */ import * as React from 'react'; -import { ContextEntry } from '../../traceModel'; +import { ContextEntry } from '../../../cli/traceViewer/traceModel'; import './contextSelector.css'; export const ContextSelector: React.FunctionComponent<{ diff --git a/src/cli/traceViewer/web/ui/helpers.tsx b/src/web/traceViewer/ui/helpers.tsx similarity index 100% rename from src/cli/traceViewer/web/ui/helpers.tsx rename to src/web/traceViewer/ui/helpers.tsx diff --git a/src/cli/traceViewer/web/ui/logsTab.css b/src/web/traceViewer/ui/logsTab.css similarity index 100% rename from src/cli/traceViewer/web/ui/logsTab.css rename to src/web/traceViewer/ui/logsTab.css diff --git a/src/cli/traceViewer/web/ui/logsTab.tsx b/src/web/traceViewer/ui/logsTab.tsx similarity index 94% rename from src/cli/traceViewer/web/ui/logsTab.tsx rename to src/web/traceViewer/ui/logsTab.tsx index 2385d810b5..0c74cf67f8 100644 --- a/src/cli/traceViewer/web/ui/logsTab.tsx +++ b/src/web/traceViewer/ui/logsTab.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ActionEntry } from '../../traceModel'; +import { ActionEntry } from '../../../cli/traceViewer/traceModel'; import * as React from 'react'; import './logsTab.css'; diff --git a/src/cli/traceViewer/web/ui/networkResourceDetails.css b/src/web/traceViewer/ui/networkResourceDetails.css similarity index 100% rename from src/cli/traceViewer/web/ui/networkResourceDetails.css rename to src/web/traceViewer/ui/networkResourceDetails.css diff --git a/src/cli/traceViewer/web/ui/networkResourceDetails.tsx b/src/web/traceViewer/ui/networkResourceDetails.tsx similarity index 98% rename from src/cli/traceViewer/web/ui/networkResourceDetails.tsx rename to src/web/traceViewer/ui/networkResourceDetails.tsx index 1e9f28c882..2e444fed59 100644 --- a/src/cli/traceViewer/web/ui/networkResourceDetails.tsx +++ b/src/web/traceViewer/ui/networkResourceDetails.tsx @@ -17,7 +17,7 @@ import './networkResourceDetails.css'; import * as React from 'react'; import { Expandable } from './helpers'; -import { NetworkResourceTraceEvent } from '../../../../trace/traceTypes'; +import { NetworkResourceTraceEvent } from '../../../trace/traceTypes'; export const NetworkResourceDetails: React.FunctionComponent<{ diff --git a/src/cli/traceViewer/web/ui/networkTab.css b/src/web/traceViewer/ui/networkTab.css similarity index 100% rename from src/cli/traceViewer/web/ui/networkTab.css rename to src/web/traceViewer/ui/networkTab.css diff --git a/src/cli/traceViewer/web/ui/networkTab.tsx b/src/web/traceViewer/ui/networkTab.tsx similarity index 94% rename from src/cli/traceViewer/web/ui/networkTab.tsx rename to src/web/traceViewer/ui/networkTab.tsx index 5462ab2ed3..2d41c69e22 100644 --- a/src/cli/traceViewer/web/ui/networkTab.tsx +++ b/src/web/traceViewer/ui/networkTab.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ActionEntry } from '../../traceModel'; +import { ActionEntry } from '../../../cli/traceViewer/traceModel'; import './networkTab.css'; import * as React from 'react'; import { NetworkResourceDetails } from './networkResourceDetails'; diff --git a/src/cli/traceViewer/web/ui/propertiesTabbedPane.css b/src/web/traceViewer/ui/propertiesTabbedPane.css similarity index 100% rename from src/cli/traceViewer/web/ui/propertiesTabbedPane.css rename to src/web/traceViewer/ui/propertiesTabbedPane.css diff --git a/src/cli/traceViewer/web/ui/propertiesTabbedPane.tsx b/src/web/traceViewer/ui/propertiesTabbedPane.tsx similarity index 98% rename from src/cli/traceViewer/web/ui/propertiesTabbedPane.tsx rename to src/web/traceViewer/ui/propertiesTabbedPane.tsx index f5846c2e2c..48f4110fa3 100644 --- a/src/cli/traceViewer/web/ui/propertiesTabbedPane.tsx +++ b/src/web/traceViewer/ui/propertiesTabbedPane.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ActionEntry } from '../../traceModel'; +import { ActionEntry } from '../../../cli/traceViewer/traceModel'; import { Boundaries, Size } from '../geometry'; import { NetworkTab } from './networkTab'; import { SourceTab } from './sourceTab'; diff --git a/src/cli/traceViewer/web/ui/sourceTab.css b/src/web/traceViewer/ui/sourceTab.css similarity index 100% rename from src/cli/traceViewer/web/ui/sourceTab.css rename to src/web/traceViewer/ui/sourceTab.css diff --git a/src/cli/traceViewer/web/ui/sourceTab.tsx b/src/web/traceViewer/ui/sourceTab.tsx similarity index 96% rename from src/cli/traceViewer/web/ui/sourceTab.tsx rename to src/web/traceViewer/ui/sourceTab.tsx index 4f8a28bf5d..0f47f90b04 100644 --- a/src/cli/traceViewer/web/ui/sourceTab.tsx +++ b/src/web/traceViewer/ui/sourceTab.tsx @@ -14,12 +14,12 @@ * limitations under the License. */ -import { ActionEntry } from '../../traceModel'; +import { ActionEntry } from '../../../cli/traceViewer/traceModel'; import * as React from 'react'; import { useAsyncMemo } from './helpers'; import './sourceTab.css'; -import '../../../../third_party/highlightjs/highlightjs/tomorrow.css'; -import * as highlightjs from '../../../../third_party/highlightjs/highlightjs'; +import '../../../third_party/highlightjs/highlightjs/tomorrow.css'; +import * as highlightjs from '../../../third_party/highlightjs/highlightjs'; type StackInfo = string | { frames: { diff --git a/src/cli/traceViewer/web/ui/timeline.css b/src/web/traceViewer/ui/timeline.css similarity index 100% rename from src/cli/traceViewer/web/ui/timeline.css rename to src/web/traceViewer/ui/timeline.css diff --git a/src/cli/traceViewer/web/ui/timeline.tsx b/src/web/traceViewer/ui/timeline.tsx similarity index 99% rename from src/cli/traceViewer/web/ui/timeline.tsx rename to src/web/traceViewer/ui/timeline.tsx index 90a2d3d63d..5abccf5f63 100644 --- a/src/cli/traceViewer/web/ui/timeline.tsx +++ b/src/web/traceViewer/ui/timeline.tsx @@ -15,7 +15,7 @@ limitations under the License. */ -import { ContextEntry, InterestingPageEvent, ActionEntry, trace } from '../../traceModel'; +import { ContextEntry, InterestingPageEvent, ActionEntry, trace } from '../../../cli/traceViewer/traceModel'; import './timeline.css'; import { Boundaries } from '../geometry'; import * as React from 'react'; diff --git a/src/cli/traceViewer/web/ui/workbench.css b/src/web/traceViewer/ui/workbench.css similarity index 100% rename from src/cli/traceViewer/web/ui/workbench.css rename to src/web/traceViewer/ui/workbench.css diff --git a/src/cli/traceViewer/web/ui/workbench.tsx b/src/web/traceViewer/ui/workbench.tsx similarity index 96% rename from src/cli/traceViewer/web/ui/workbench.tsx rename to src/web/traceViewer/ui/workbench.tsx index bf7ddf4877..a489831a40 100644 --- a/src/cli/traceViewer/web/ui/workbench.tsx +++ b/src/web/traceViewer/ui/workbench.tsx @@ -14,14 +14,13 @@ limitations under the License. */ -import { ActionEntry, TraceModel } from '../../traceModel'; +import { ActionEntry, TraceModel } from '../../../cli/traceViewer/traceModel'; import { ActionList } from './actionList'; import { PropertiesTabbedPane } from './propertiesTabbedPane'; import { Timeline } from './timeline'; import './workbench.css'; import * as React from 'react'; import { ContextSelector } from './contextSelector'; -import { GlobalStyles } from '../styles'; export const Workbench: React.FunctionComponent<{ traceModel: TraceModel, @@ -42,7 +41,6 @@ export const Workbench: React.FunctionComponent<{ const boundaries = { minimum: context.startTime, maximum: context.endTime }; return
-
🎭
Playwright
diff --git a/src/cli/traceViewer/web/web.webpack.config.js b/src/web/traceViewer/webpack.config.js similarity index 92% rename from src/cli/traceViewer/web/web.webpack.config.js rename to src/web/traceViewer/webpack.config.js index 1707c02f55..9220f51aad 100644 --- a/src/cli/traceViewer/web/web.webpack.config.js +++ b/src/web/traceViewer/webpack.config.js @@ -13,7 +13,7 @@ module.exports = { output: { globalObject: 'self', filename: '[name].bundle.js', - path: path.resolve(__dirname, '../../../../lib/cli/traceViewer/web') + path: path.resolve(__dirname, '../../../lib/web/traceViewer') }, module: { rules: [ diff --git a/src/cli/traceViewer/web/types.d.ts b/src/web/types.d.ts similarity index 100% rename from src/cli/traceViewer/web/types.d.ts rename to src/web/types.d.ts diff --git a/utils/build/build.js b/utils/build/build.js index 5a38d8a49b..6d772ddb4a 100644 --- a/utils/build/build.js +++ b/utils/build/build.js @@ -70,7 +70,8 @@ const webPackFiles = [ 'src/server/injected/utilityScript.webpack.config.js', 'src/server/supplements/injected/consoleApi.webpack.config.js', 'src/server/supplements/injected/recorder.webpack.config.js', - 'src/cli/traceViewer/web/web.webpack.config.js', + 'src/web/traceViewer/webpack.config.js', + 'src/web/recorder/webpack.config.js', ]; for (const file of webPackFiles) { steps.push({ diff --git a/utils/check_deps.js b/utils/check_deps.js index 52836d051a..235b0d21e9 100644 --- a/utils/check_deps.js +++ b/utils/check_deps.js @@ -143,7 +143,10 @@ DEPS['src/cli/driver.ts'] = DEPS['src/inprocess.ts'] = DEPS['src/browserServerIm // Tracing is a client/server plugin, nothing should depend on it. DEPS['src/trace/'] = ['src/utils/', 'src/client/**', 'src/server/**']; - +DEPS['src/web/'] = []; +DEPS['src/web/recorder/'] = ['src/web/']; +DEPS['src/web/traceViewer/'] = ['src/web/', 'src/cli/traceViewer/']; +DEPS['src/web/traceViewer/ui/'] = ['src/web/traceViewer/', 'src/web/', 'src/cli/traceViewer/', 'src/trace/']; // The service is a cross-cutting feature, and so it depends on a bunch of things. DEPS['src/remote/'] = ['src/client/', 'src/debug/', 'src/dispatchers/', 'src/server/', 'src/server/supplements/', 'src/server/electron/', 'src/trace/']; DEPS['src/service.ts'] = ['src/remote/'];