Skip to content

Commit

Permalink
Roll your own tab (mostly empty) (#6030)
Browse files Browse the repository at this point in the history
This is groundwork for
#6027.

The `Roll Your Own` floating thing made in the spike becomes a tab in
the right pane (in the future we might want to have it as a floating
panel, but we can incrementally extract it later on).

The `Grid` section is left deliberately empty so we can fill it in with
the other grid-related PRs.

**Context/history**

As part of the exploratory work on grid interactions
(#6027) I added a way to
test individual interaction/UI pieces in the spirit of [the classic
Steve Jobs calculator
story](https://www.reddit.com/r/mac/comments/o89l6i/the_apple_team_created_an_app_so_that_steve_jobs/)
- called `Roll Your Own Grid`

<img width="368" alt="Screenshot 2024-07-01 at 17 55 30"
src="https://github.com/concrete-utopia/utopia/assets/1081051/c99a46a8-60ba-4a7c-ae03-ed4145ea7c3a">

There's a good chance this stuff will be useful for more than Grid in
the future (e.g. the inspector, the canvas etc) so we can reuse this
idea in other contexts, while keeping the original concept.

**Note**
The PR includes a demo feature type for `Grid` for illustration purposes
only; it should be replaced with the actual features.
  • Loading branch information
ruggi authored and liady committed Dec 13, 2024
1 parent 608e326 commit 6b69b5b
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 0 deletions.
15 changes: 15 additions & 0 deletions editor/src/components/canvas/design-panel-root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import { EditorModes, isCommentMode } from '../editor/editor-modes'
import { useAllowedToEditProject } from '../editor/store/collaborative-editing'
import { useCanComment } from '../../core/commenting/comment-hooks'
import { ElementsOutsideVisibleAreaIndicator } from '../editor/elements-outside-visible-area-indicator'
import { isFeatureEnabled } from '../../utils/feature-switches'
import { RollYourOwnFeaturesPane } from '../navigator/left-pane/roll-your-own-pane'

function isCodeEditorEnabled(): boolean {
if (typeof window !== 'undefined') {
Expand Down Expand Up @@ -158,6 +160,10 @@ export const RightPane = React.memo<ResizableRightPaneProps>((props) => {
onClickTab(RightMenuTab.Settings)
}, [onClickTab])

const onClickRollYourOwnTab = React.useCallback(() => {
onClickTab(RightMenuTab.RollYourOwn)
}, [onClickTab])

const canComment = useCanComment()

const allowedToEdit = useAllowedToEditProject()
Expand Down Expand Up @@ -219,6 +225,14 @@ export const RightPane = React.memo<ResizableRightPaneProps>((props) => {
selected={selectedTab === RightMenuTab.Settings}
onClick={onClickSettingsTab}
/>
{when(
isFeatureEnabled('Roll Your Own'),
<MenuTab
label={'RYO'}
selected={selectedTab === RightMenuTab.RollYourOwn}
onClick={onClickRollYourOwnTab}
/>,
)}
</FlexRow>
<SimpleFlexRow
className='Inspector-entrypoint'
Expand All @@ -236,6 +250,7 @@ export const RightPane = React.memo<ResizableRightPaneProps>((props) => {
{when(selectedTab === RightMenuTab.Inspector, <InspectorEntryPoint />)}
{when(selectedTab === RightMenuTab.Settings, <SettingsPane />)}
{when(selectedTab === RightMenuTab.Comments, <CommentsPane />)}
{when(selectedTab === RightMenuTab.RollYourOwn, <RollYourOwnFeaturesPane />)}
</SimpleFlexRow>
<CanvasStrategyInspector />
</FlexColumn>
Expand Down
1 change: 1 addition & 0 deletions editor/src/components/editor/store/editor-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ export enum RightMenuTab {
Inspector = 'inspector',
Settings = 'settings',
Comments = 'comments',
RollYourOwn = 'roll-your-own',
}

// TODO: this should just contain an NpmDependency and a status
Expand Down
132 changes: 132 additions & 0 deletions editor/src/components/navigator/left-pane/roll-your-own-pane.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import React from 'react'
import { FlexColumn, FlexRow, Section } from '../../../uuiui'
import { when } from '../../../utils/react-conditionals'
import { atom, useAtom } from 'jotai'
import { UIGridRow } from '../../inspector/widgets/ui-grid-row'
import { atomWithStorage } from 'jotai/utils'
import { IS_TEST_ENVIRONMENT } from '../../../common/env-vars'

const sections = ['Grid'] as const
type Section = (typeof sections)[number]

type GridFeatures = {
foo: boolean
}

type RollYourOwnFeaturesTypes = {
Grid: GridFeatures
}

type RollYourOwnFeatures = {
[K in Section]: RollYourOwnFeaturesTypes[K]
}

let defaultRollYourOwnFeatures: RollYourOwnFeatures = {
Grid: {
foo: true,
},
}

const ROLL_YOUR_OWN_FEATURES_KEY: string = 'roll-your-own-features'

export const rollYourOwnFeatures = IS_TEST_ENVIRONMENT
? atom(defaultRollYourOwnFeatures)
: atomWithStorage(ROLL_YOUR_OWN_FEATURES_KEY, defaultRollYourOwnFeatures)

export const RollYourOwnFeaturesPane = React.memo(() => {
const [currentSection, setCurrentSection] = React.useState<Section | null>(null)

const onChangeSection = React.useCallback((e: React.ChangeEvent<HTMLSelectElement>) => {
const maybeSectionValue = e.target.value as Section
if (sections.includes(maybeSectionValue)) {
setCurrentSection(maybeSectionValue)
} else {
setCurrentSection(null)
}
}, [])

return (
<FlexColumn
id='leftPaneRollYourOwn'
key='leftPaneRollYourOwn'
style={{
display: 'relative',
alignItems: 'stretch',
paddingBottom: 50,
overflowY: 'scroll',
alignSelf: 'stretch',
}}
>
<Section>
<FlexRow
style={{
margin: 8,
gap: 12,
height: 22,
}}
>
<span style={{ fontWeight: 600 }}>Roll Your Own</span>
</FlexRow>
<FlexRow style={{ gap: 12, margin: 8 }}>
<select
value={currentSection ?? undefined}
style={{ flex: 1 }}
onChange={onChangeSection}
>
<option value=''></option>
{sections.map((section) => {
return (
<option key={`section-${section}`} value={section}>
{section}
</option>
)
})}
</select>
</FlexRow>

{when(currentSection === 'Grid', <GridSection />)}
</Section>
</FlexColumn>
)
})
RollYourOwnFeaturesPane.displayName = 'RollYourOwnFeaturesPane'

const GridSection = React.memo(() => {
const [features, setFeatures] = useAtom(rollYourOwnFeatures)

const onChange = React.useCallback(
(feat: keyof GridFeatures) => (e: React.ChangeEvent<HTMLInputElement>) => {
setFeatures((existing) => {
return {
...existing,
Grid: {
...existing.Grid,
[feat]: e.target.checked,
},
}
})
},
[setFeatures],
)

return (
<FlexColumn style={{ gap: 10 }}>
{Object.entries(features.Grid).map(([feat, value]) => {
return (
<UIGridRow padded variant='<--1fr--><--1fr-->' key={`feat-${feat}`}>
<div>{feat}</div>
{when(
typeof value === 'boolean',
<input
type='checkbox'
checked={value}
onChange={onChange(feat as keyof GridFeatures)}
/>,
)}
</UIGridRow>
)
})}
</FlexColumn>
)
})
GridSection.displayName = 'GridSection'
3 changes: 3 additions & 0 deletions editor/src/utils/feature-switches.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type FeatureName =
| 'Debug - Print UIDs'
| 'Debug – Connections'
| 'Condensed Navigator Entries'
| 'Roll Your Own'

export const AllFeatureNames: FeatureName[] = [
// 'Dragging Reparents By Default', // Removing this option so that we can experiment on this later
Expand All @@ -30,6 +31,7 @@ export const AllFeatureNames: FeatureName[] = [
'Debug - Print UIDs',
'Debug – Connections',
'Condensed Navigator Entries',
'Roll Your Own',
]

let FeatureSwitches: { [feature in FeatureName]: boolean } = {
Expand All @@ -45,6 +47,7 @@ let FeatureSwitches: { [feature in FeatureName]: boolean } = {
'Debug - Print UIDs': false,
'Debug – Connections': false,
'Condensed Navigator Entries': !IS_TEST_ENVIRONMENT,
'Roll Your Own': false,
}

export const STEGANOGRAPHY_ENABLED = false
Expand Down

0 comments on commit 6b69b5b

Please sign in to comment.