diff --git a/packages/app/src/app/pages/Sandbox/Editor/Content/Tabs/elements.js b/packages/app/src/app/pages/Sandbox/Editor/Content/Tabs/elements.ts
similarity index 88%
rename from packages/app/src/app/pages/Sandbox/Editor/Content/Tabs/elements.js
rename to packages/app/src/app/pages/Sandbox/Editor/Content/Tabs/elements.ts
index 0162e10b455..ba42f955326 100644
--- a/packages/app/src/app/pages/Sandbox/Editor/Content/Tabs/elements.js
+++ b/packages/app/src/app/pages/Sandbox/Editor/Content/Tabs/elements.ts
@@ -33,6 +33,9 @@ export const TabsContainer = styled.div`
}
`;
+interface IStyledPrettierIconProps {
+ disabled?: boolean;
+}
export const StyledPrettierIcon = styled(PrettierIcon)`
transition: 0.3s ease opacity;
width: 1.125rem;
@@ -47,7 +50,7 @@ export const StyledPrettierIcon = styled(PrettierIcon)`
opacity: 1;
}
- ${props =>
+ ${(props: IStyledPrettierIconProps) =>
props.disabled &&
css`
opacity: 0;
@@ -71,6 +74,11 @@ export const Line = styled.div`
props.theme['editorGroupHeader.tabsBorder'] || 'rgba(255, 255, 255, 0.3)'};
`;
+interface IIconWrapperProps {
+ active?: boolean;
+ disabled?: boolean;
+ theme: any;
+}
export const IconWrapper = styled.div`
svg {
transition: 0.3s ease opacity;
@@ -86,7 +94,7 @@ export const IconWrapper = styled.div`
opacity: 1;
}
- ${props =>
+ ${(props: IIconWrapperProps) =>
props.active &&
css`
opacity: 1;
diff --git a/packages/app/src/app/pages/Sandbox/Editor/Content/Tabs/index.js b/packages/app/src/app/pages/Sandbox/Editor/Content/Tabs/index.js
deleted file mode 100644
index 29091c8ed00..00000000000
--- a/packages/app/src/app/pages/Sandbox/Editor/Content/Tabs/index.js
+++ /dev/null
@@ -1,228 +0,0 @@
-import React from 'react';
-import { inject, observer } from 'app/componentConnectors';
-
-import { canPrettify } from 'app/utils/prettify';
-import Tooltip from '@codesandbox/common/lib/components/Tooltip';
-
-import TabContainer from './TabContainer';
-import PreviewIcon from './PreviewIcon';
-
-import {
- Container,
- TabsContainer,
- IconContainer,
- StyledPrettierIcon,
- IconWrapper,
- Line,
-} from './elements';
-
-import ModuleTab from './ModuleTab';
-
-class EditorTabs extends React.Component {
- componentDidUpdate(prevProps) {
- if (this.props.currentModuleId !== prevProps.currentModuleId) {
- const currentTab = this.tabEls[this.props.currentModuleId];
-
- // We need to scroll to the tab
- if (currentTab && this.container) {
- const { width } = this.container.getBoundingClientRect();
- const scroll = this.container.scrollLeft;
- const { left } = currentTab.getBoundingClientRect();
-
- if (left > scroll && left < scroll + width) {
- // if it's already in view
- return;
- }
-
- currentTab.scrollIntoView(false);
- }
- }
- }
-
- closeTab = tabIndex => {
- this.props.signals.editor.tabClosed({ tabIndex });
- };
-
- moveTab = (prevIndex, nextIndex) => {
- this.props.signals.editor.tabMoved({ prevIndex, nextIndex });
- };
-
- /**
- * Mark all tabs not dirty (not cursive)
- */
- markNotDirty = () => {
- this.props.signals.editor.moduleDoubleClicked();
- };
-
- setCurrentModule = moduleId => {
- this.props.signals.editor.moduleSelected({ id: moduleId });
- };
-
- discardModuleChanges = moduleShortid => {
- this.props.signals.editor.discardModuleChanges({ moduleShortid });
- };
-
- prettifyModule = () => {
- this.props.signals.editor.prettifyClicked({
- moduleShortid: this.props.store.editor.currentModuleShortid,
- });
- };
-
- canPrettify = module => {
- if (!module) {
- return false;
- }
-
- return canPrettify(module.title);
- };
-
- container;
- tabEls = {};
-
- render() {
- const { store, signals } = this.props;
- const sandbox = store.editor.currentSandbox;
- const moduleObject = {};
- // We keep this object to keep track if there are duplicate titles.
- // In that case we need to show which directory the module is in.
- const tabNamesObject = {};
-
- sandbox.modules.forEach(m => {
- moduleObject[m.shortid] = m;
- });
-
- store.editor.tabs
- .filter(tab => tab.type === 'MODULE')
- .filter(tab => moduleObject[tab.moduleShortid])
- .forEach(tab => {
- const module = moduleObject[tab.moduleShortid];
-
- tabNamesObject[module.title] = tabNamesObject[module.title] || [];
- tabNamesObject[module.title].push(module.shortid);
- });
-
- const { currentTab } = store.editor;
- const { currentModule } = store.editor;
-
- const previewVisible = store.editor.previewWindowVisible;
-
- return (
-
- {
- this.container = el;
- }}
- >
- {store.editor.tabs
- .map(tab => ({ ...tab, module: moduleObject[tab.moduleShortid] }))
- .map((tab, i) => {
- if (tab.type === 'MODULE') {
- if (tab.module == null) {
- return null;
- }
-
- const { module } = tab;
- const modulesWithName = tabNamesObject[module.title];
- const { id } = tab.module;
- let dirName = null;
-
- if (
- modulesWithName.length > 1 &&
- module.directoryShortid != null
- ) {
- const dir = sandbox.directories.find(
- d =>
- d.shortid === module.directoryShortid &&
- d.sourceId === module.sourceId
- );
-
- if (dir) {
- dirName = dir.title;
- }
- }
-
- return (
- error.moduleId === id)
- .length
- )}
- closeTab={this.closeTab}
- moveTab={this.moveTab}
- markNotDirty={this.markNotDirty}
- dirName={dirName}
- tabCount={store.editor.tabs.length}
- position={i}
- dirty={tab.dirty}
- isNotSynced={Boolean(
- store.editor.changedModuleShortids.includes(
- tab.module.shortid
- )
- )}
- ref={el => {
- this.tabEls[id] = el;
- }}
- />
- );
- }
- if (tab.type === 'DIFF') {
- return (
-
- signals.editor.currentTabChanged({ tabId: tab.id })
- }
- closeTab={this.closeTab}
- moveTab={this.moveTab}
- tabCount={store.editor.tabs.length}
- position={i}
- dirty={tab.dirty}
- ref={el => {
- this.tabEls[tab.id] = el;
- }}
- title={`Diff: ${tab.titleA} - ${tab.titleB}`}
- />
- );
- }
-
- return null;
- })}
-
-
-
-
-
-
-
-
-
-
-
- this.props.signals.editor.togglePreviewContent({})
- }
- />
-
-
-
-
- );
- }
-}
-
-export default inject('signals', 'store')(observer(EditorTabs));
diff --git a/packages/app/src/app/pages/Sandbox/Editor/Content/Tabs/index.tsx b/packages/app/src/app/pages/Sandbox/Editor/Content/Tabs/index.tsx
new file mode 100644
index 00000000000..301000b9e7c
--- /dev/null
+++ b/packages/app/src/app/pages/Sandbox/Editor/Content/Tabs/index.tsx
@@ -0,0 +1,233 @@
+import React, { useEffect } from 'react';
+import { useOvermind } from 'app/overmind';
+import Tooltip from '@codesandbox/common/lib/components/Tooltip';
+import TabContainer from './TabContainer';
+import PreviewIcon from './PreviewIcon';
+
+import {
+ Container,
+ TabsContainer,
+ IconContainer,
+ StyledPrettierIcon,
+ IconWrapper,
+ Line,
+} from './elements';
+
+import ModuleTab from './ModuleTab';
+
+interface IEditorTabsProps {
+ currentModuleId: string | number;
+}
+
+interface IOvermindProp {
+ state: any;
+ actions: any;
+}
+
+const EditorTabs: React.FunctionComponent = ({
+ currentModuleId,
+}) => {
+ const {
+ state: { editor: editorState },
+ actions: { editor: editorAction },
+ }: IOvermindProp = useOvermind();
+
+ let container = null;
+ const tabEls = {};
+
+ useEffect(() => {
+ const currentTab = tabEls[currentModuleId];
+
+ // We need to scroll to the tab
+ if (currentTab && container) {
+ const { width } = container.getBoundingClientRect();
+ const scroll = container.scrollLeft;
+ const { left } = currentTab.getBoundingClientRect();
+
+ if (left > scroll && left < scroll + width) {
+ // if it's already in view
+ return;
+ }
+
+ currentTab.scrollIntoView(false);
+ }
+ }, [container, currentModuleId, tabEls]);
+
+ const closeTab = tabIndex => {
+ editorAction.tabClosed({ tabIndex });
+ };
+
+ const moveTab = (prevIndex, nextIndex) => {
+ editorAction.tabMoved({ prevIndex, nextIndex });
+ };
+
+ /**
+ * Mark all tabs not dirty (not cursive)
+ */
+ const markNotDirty = () => {
+ editorAction.moduleDoubleClicked();
+ };
+
+ const setCurrentModule = moduleId => {
+ editorAction.moduleSelected({ id: moduleId });
+ };
+
+ const discardModuleChanges = moduleShortid => {
+ editorAction.discardModuleChanges({ moduleShortid });
+ };
+
+ const prettifyModule = () => {
+ editorAction.prettifyClicked({
+ moduleShortid: editorState.currentModuleShortid,
+ });
+ };
+
+ const canPrettify = module => {
+ if (!module) {
+ return false;
+ }
+
+ return canPrettify(module.title);
+ };
+
+ const sandbox = editorState.currentSandbox;
+ const moduleObject = {};
+ // We keep this object to keep track if there are duplicate titles.
+ // In that case we need to show which directory the module is in.
+ const tabNamesObject = {};
+
+ sandbox.modules.forEach(m => {
+ moduleObject[m.shortid] = m;
+ });
+
+ editorState.tabs
+ .filter(tab => tab.type === 'MODULE')
+ .filter(tab => moduleObject[tab.moduleShortid])
+ .forEach(tab => {
+ const module = moduleObject[tab.moduleShortid];
+
+ tabNamesObject[module.title] = tabNamesObject[module.title] || [];
+ tabNamesObject[module.title].push(module.shortid);
+ });
+
+ const { currentTab } = editorState;
+ const { currentModule } = editorState;
+
+ const previewVisible = editorState.previewWindowVisible;
+
+ return (
+
+ {
+ container = el;
+ }}
+ >
+ {editorState.tabs
+ .map(tab => ({ ...tab, module: moduleObject[tab.moduleShortid] }))
+ .map((tab, i) => {
+ if (tab.type === 'MODULE') {
+ if (tab.module == null) {
+ return null;
+ }
+
+ const { module } = tab;
+ const modulesWithName = tabNamesObject[module.title];
+ const { id } = tab.module;
+ let dirName = null;
+
+ if (
+ modulesWithName.length > 1 &&
+ module.directoryShortid != null
+ ) {
+ const dir = sandbox.directories.find(
+ d =>
+ d.shortid === module.directoryShortid &&
+ d.sourceId === module.sourceId
+ );
+
+ if (dir) {
+ dirName = dir.title;
+ }
+ }
+
+ return (
+ error.moduleId === id)
+ .length
+ )}
+ closeTab={closeTab}
+ moveTab={moveTab}
+ markNotDirty={markNotDirty}
+ dirName={dirName}
+ tabCount={editorState.tabs.length}
+ position={i}
+ dirty={tab.dirty}
+ isNotSynced={Boolean(
+ editorState.changedModuleShortids.includes(
+ tab.module.shortid
+ )
+ )}
+ ref={el => {
+ tabEls[id] = el;
+ }}
+ />
+ );
+ }
+ if (tab.type === 'DIFF') {
+ return (
+
+ editorAction.currentTabChanged({ tabId: tab.id })
+ }
+ closeTab={closeTab}
+ moveTab={moveTab}
+ tabCount={editorState.tabs.length}
+ position={i}
+ dirty={tab.dirty}
+ ref={el => {
+ tabEls[tab.id] = el;
+ }}
+ title={`Diff: ${tab.titleA} - ${tab.titleB}`}
+ />
+ );
+ }
+
+ return null;
+ })}
+
+
+
+
+
+
+
+
+
+
+ editorAction.togglePreviewContent({})}
+ />
+
+
+
+
+ );
+};
+
+export default EditorTabs;