Skip to content

Commit

Permalink
react-resizable-panels
Browse files Browse the repository at this point in the history
  • Loading branch information
mischnic committed Nov 25, 2023
1 parent eaf22bc commit 439e69b
Show file tree
Hide file tree
Showing 9 changed files with 337 additions and 109 deletions.
5 changes: 1 addition & 4 deletions packages/dev/repl/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
"es6": true
},
"rules": {
"react/jsx-no-bind": "error",
"react/no-unknown-property": "off",
"react/prop-types": "off",
"react/react-in-jsx-scope": "off",
"react/jsx-no-bind": "off",
"no-console": "off"
},
"globals": {
Expand Down
2 changes: 2 additions & 0 deletions packages/dev/repl/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
"nullthrows": "^1.1.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-resizable-panels": "^0.0.61",
"react-use": "^17.4.0",
"semver": "^7.3.5"
},
"browserslist": "Chrome 75",
Expand Down
6 changes: 3 additions & 3 deletions packages/dev/repl/src/components/Options.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function Options({
<span>Output Format</span>
<select
onChange={e => onChange('outputFormat', e.target.value || null)}
value={values.outputFormat}
value={values.outputFormat ?? ''}
disabled={disabled || disablePackageJSON}
>
<option value="" />
Expand All @@ -83,8 +83,8 @@ export function Options({
</select>
<input
type="text"
value={values.targetEnv}
onInput={e => onChange('targetEnv', e.target.value)}
value={values.targetEnv ?? ''}
onInput={e => onChange('targetEnv', e.target.value || null)}
placeholder={getDefaultTargetEnv(values.targetType)}
disabled={disabled || disablePackageJSON}
/>
Expand Down
6 changes: 3 additions & 3 deletions packages/dev/repl/src/components/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export function Tabs({
selected,
setSelected,
mode = 'remove',
class: clazz,
className,
fallback,
...props
}: any): any {
Expand All @@ -125,7 +125,7 @@ export function Tabs({
}, [children, selected, setSelected]);

return (
<div {...props} className={'tabs ' + (clazz || '')}>
<div {...props} className={'tabs ' + (className || '')}>
<div className="switcher">
{names.map((n, i) => (
<div
Expand All @@ -145,7 +145,7 @@ export function Tabs({
<div
key={i}
className="content"
style={i !== selected && {display: 'none'}}
style={i !== selected ? {display: 'none'} : undefined}
>
{c}
</div>
Expand Down
160 changes: 102 additions & 58 deletions packages/dev/repl/src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// @flow
import {Fragment, useEffect, useState, useReducer, useRef} from 'react';
import {createRoot} from 'react-dom/client';
// $FlowFixMe
import {Panel, PanelGroup, PanelResizeHandle} from 'react-resizable-panels';
import {useMedia} from 'react-use';

// $FlowFixMe
import parcelLogo from 'url:./assets/logo.svg';
Expand Down Expand Up @@ -321,6 +324,8 @@ function Editors({state, dispatch}) {
function App() {
let [state, dispatch] = useReducer(reducer, null, getInitialState);

let isDesktop = useMedia('(min-width: 800px)');

useDebounce(() => saveState(state), 500, [state.files, state.options]);

useKeyboard(
Expand All @@ -336,68 +341,107 @@ function App() {
[dispatch],
);

const sidebar = (
<FileBrowser
files={state.files}
collapsed={state.browserCollapsed}
dispatch={dispatch}
isEditing={state.isEditing}
>
<header>
<a href="/">
<img
className="parcel"
src={parcelText}
height="30"
style={{marginTop: '5px'}}
alt=""
/>
<img
className="type"
src={parcelLogo}
style={{width: '120px'}}
alt=""
/>
<span style={{fontSize: '25px'}}>REPL</span>
</a>
</header>
<div>
<PresetSelector dispatch={dispatch} />
<div className="options">
<button
onClick={() =>
dispatch({
type: 'view.open',
name: 'Options',
component: Options,
})
}
>
Options
</button>
<button
title="Toggle view"
className={'view ' + (state.useTabs ? 'tabs' : '')}
onClick={() =>
dispatch({
type: 'toggleView',
})
}
>
<span></span>
</button>
</div>
</div>
</FileBrowser>
);

const editors = <Editors state={state} dispatch={dispatch} />;
const output = <Output state={state} dispatch={dispatch} />;

return (
<>
<main>
<FileBrowser
files={state.files}
collapsed={state.browserCollapsed}
dispatch={dispatch}
isEditing={state.isEditing}
>
<header>
<a href="/">
<img
className="parcel"
src={parcelText}
height="30"
style={{marginTop: '5px'}}
alt=""
/>
<img
className="type"
src={parcelLogo}
style={{width: '120px'}}
alt=""
/>
<span style={{fontSize: '25px'}}>REPL</span>
</a>
</header>
<div>
<PresetSelector dispatch={dispatch} />
<div className="options">
<button
onClick={() =>
dispatch({
type: 'view.open',
name: 'Options',
component: Options,
})
}
>
Options
</button>
<button
title="Toggle view"
className={'view ' + (state.useTabs ? 'tabs' : '')}
onClick={() =>
dispatch({
type: 'toggleView',
})
}
>
<span></span>
</button>
</div>
</div>
</FileBrowser>
<Editors state={state} dispatch={dispatch} />
<Output state={state} dispatch={dispatch} />
</main>
</>
<main>
{isDesktop ? (
<PanelGroup direction="horizontal" autoSaveId="repl-main-panels">
<Panel
defaultSizePercentage={20}
minSizePixels={60}
className="panel"
>
{sidebar}
</Panel>
<ResizeHandle />
<Panel
defaultSizePercentage={45}
minSizePixels={100}
className="panel"
>
{editors}
</Panel>
<ResizeHandle />
<Panel
defaultSizePercentage={35}
minSizePixels={200}
className="panel"
>
{output}
</Panel>
</PanelGroup>
) : (
<div style={{display: 'flex', flexDirection: 'column'}}>
{sidebar}
{editors}
{output}
</div>
)}
</main>
);
}

function ResizeHandle() {
return <PanelResizeHandle className="resize-handle"></PanelResizeHandle>;
}

let root = createRoot(document.getElementById('root'));
root.render(<App />);

Expand Down
56 changes: 21 additions & 35 deletions packages/dev/repl/src/styles/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,42 +17,33 @@ button:hover {
background: var(--background-dark);
}

.editor,
pre {
background-color: var(--background-editor);
.panel {
display: flex;
flex-direction: column;
align-items: stretch;
}
.panel > * {
flex: 1;
min-height: 0;
}

main {
display: grid;
align-items: stretch;
grid-template-columns: 16em minmax(20em, 1.2fr) minmax(10em, 1fr);
grid-template-areas: 'browser editor output';
}
@media (max-width: 850px) {
main {
grid-template-rows: min-content auto;
grid-template-columns: minmax(20em, 1.2fr) minmax(10em, 1fr);
grid-template-areas:
'browser browser'
'editor output';
}
}
@media (max-width: 550px) {
main {
grid-template-rows: min-content auto auto;
grid-template-columns: auto;
grid-template-areas:
'browser'
'editor'
'output';
}
.resize-handle {
width: 0.3rem;
transition: 200ms ease-in-out background-color;
background-color: var(--handle-color);
outline: none;
}
.resize-handle:hover,
.resize-handle[data-resize-handle-active] {
background-color: var(--handle-color-active);
}

main > div {
min-height: 0;
.editor,
pre {
background-color: var(--background-editor);
}

main > .output {
grid-area: output;
overflow: auto;
}

Expand All @@ -61,12 +52,7 @@ main > .output {
min-height: 25em;
}

.file-browser {
grid-area: browser;
}

.editors {
grid-area: editor;
background: var(--background-light);
display: flex;
flex-direction: column;
Expand Down
6 changes: 6 additions & 0 deletions packages/dev/repl/src/styles/file-browser.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
.file-browser {
background: var(--background-header);

min-width: 200px;
overflow: hidden;
}
.file-browser > div {
border-radius: var(--radius);
Expand All @@ -26,6 +29,9 @@
justify-content: space-between;
user-select: none;
}
.file-browser .presets > select {
min-width: 0;
}

.file-browser .options {
display: flex;
Expand Down
4 changes: 4 additions & 0 deletions packages/dev/repl/src/styles/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ html {
--gap: 0.5rem;
--radius: 0.3rem;

--parcel-color: #e7b37d;
--handle-color: rgba(0, 0, 0, 0.1);
--handle-color-active: var(--parcel-color);

background-color: var(--background-light);
color: var(--color);
}
Expand Down

0 comments on commit 439e69b

Please sign in to comment.