Implement ToolbarIconButton

This commit is contained in:
Aria Minaei 2021-07-22 21:26:34 +02:00
parent a11918fc20
commit 20603afd40
8 changed files with 147 additions and 132 deletions

View file

@ -7,12 +7,10 @@ import {OrbitControls} from '@react-three/drei'
import shallow from 'zustand/shallow' import shallow from 'zustand/shallow'
import root from 'react-shadow/styled-components' import root from 'react-shadow/styled-components'
import ProxyManager from './ProxyManager' import ProxyManager from './ProxyManager'
import studio from '@theatre/studio' import studio, {ToolbarIconButton} from '@theatre/studio'
import {useVal} from '@theatre/dataverse-react' import {useVal} from '@theatre/dataverse-react'
import styled, {createGlobalStyle, StyleSheetManager} from 'styled-components' import styled, {createGlobalStyle, StyleSheetManager} from 'styled-components'
import IconButton from './Toolbar/utils/IconButton' import {IoCameraReverseOutline} from 'react-icons/all'
import {BiRefresh} from 'react-icons/bi'
import {PortalContext} from 'reakit'
const GlobalStyle = createGlobalStyle` const GlobalStyle = createGlobalStyle`
:host { :host {
@ -134,15 +132,15 @@ const SnapshotEditor: React.FC<{}> = () => {
<StyleSheetManager disableVendorPrefixes> <StyleSheetManager disableVendorPrefixes>
<> <>
<GlobalStyle /> <GlobalStyle />
<PortalContext.Provider value={overlay}> {/* <PortalContext.Provider value={overlay}> */}
<Wrapper> <Wrapper>
<Overlay ref={setOverlay}> <Overlay ref={setOverlay}>
<Tools> <Tools>
<IconButton <ToolbarIconButton
icon={<BiRefresh />} icon={<IoCameraReverseOutline />}
label="Refresh Snapshot" label="Refresh Snapshot"
onClick={createSnapshot} onClick={createSnapshot}
></IconButton> ></ToolbarIconButton>
</Tools> </Tools>
</Overlay> </Overlay>
@ -169,7 +167,7 @@ const SnapshotEditor: React.FC<{}> = () => {
</> </>
) : null} ) : null}
</Wrapper> </Wrapper>
</PortalContext.Provider> {/* </PortalContext.Provider> */}
</> </>
</StyleSheetManager> </StyleSheetManager>
</root.div> </root.div>

View file

@ -1,17 +1,13 @@
import type {VFC} from 'react' import type {VFC} from 'react'
import React from 'react' import React from 'react'
import TransformControlsModeSelect from './TransformControlsModeSelect'
import {useEditorStore} from '../../store' import {useEditorStore} from '../../store'
import shallow from 'zustand/shallow' import shallow from 'zustand/shallow'
import TransformControlsSpaceSelect from './TransformControlsSpaceSelect' import {GiPocketBow, IoCameraOutline} from 'react-icons/all'
import ViewportShadingSelect from './ViewportShadingSelect'
import {GiPocketBow, RiFocus3Line} from 'react-icons/all'
import {Vector3} from 'three' import {Vector3} from 'three'
import type {$FixMe} from '@theatre/shared/utils/types' import type {$FixMe} from '@theatre/shared/utils/types'
import studio from '@theatre/studio' import studio, {ToolbarIconButton} from '@theatre/studio'
import {getSelected} from '../useSelected' import {getSelected} from '../useSelected'
import {usePrism, useVal} from '@theatre/dataverse-react' import {usePrism, useVal} from '@theatre/dataverse-react'
import IconButton from './utils/IconButton'
import styled from 'styled-components' import styled from 'styled-components'
const ToolGroup = styled.div` const ToolGroup = styled.div`
@ -40,15 +36,15 @@ const Toolbar: VFC = () => {
return ( return (
<> <>
<ToolGroup> <ToolGroup>
<button <ToolbarIconButton
onClick={() => { onClick={() => {
studio.createPane('snapshotEditor') studio.createPane('snapshotEditor')
}} }}
> icon={<IoCameraOutline />}
Create snapshot label="Create snapshot"
</button> />
</ToolGroup> </ToolGroup>
<ToolGroup> {/* <ToolGroup>
<TransformControlsModeSelect <TransformControlsModeSelect
value={transformControlsMode} value={transformControlsMode}
onChange={(value) => onChange={(value) =>
@ -103,9 +99,9 @@ const Toolbar: VFC = () => {
} }
}} }}
/> />
</ToolGroup> </ToolGroup> */}
<ToolGroup> <ToolGroup>
<IconButton <ToolbarIconButton
label="Align object to view" label="Align object to view"
icon={<GiPocketBow />} icon={<GiPocketBow />}
onClick={() => { onClick={() => {

View file

@ -1,73 +0,0 @@
import type {ReactElement} from 'react'
import React, {forwardRef} from 'react'
import type {ButtonProps} from 'reakit'
import {Button} from 'reakit'
import type {IconType} from 'react-icons'
import {Tooltip, TooltipReference, useTooltipState} from './Tooltip'
import styled from 'styled-components'
import {transparentize} from 'polished'
export interface IconButtonProps extends Exclude<ButtonProps, 'children'> {
icon: ReactElement<IconType>
label: string
}
const TheButton = styled(TooltipReference)`
display: flex;
position: relative;
align-items: center;
justify-content: center;
vertical-align: middle;
font-size: 11px;
line-height: 1.25em;
font-weight: 600;
height: 24px;
padding-left: 0.5em;
padding-right: 0.5em;
color: #e6e6e5;
background-color: #313131ba;
border: 0 transparent;
&:first-child {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
&:last-child {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
&:focus {
outline: none;
}
color: #e6e6e5;
background-color: #313131;
&:hover {
background-color: ${transparentize(0.5, '#313131')};
}
border: 0 transparent;
`
const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
({label, icon, className, ...props}, ref) => {
const tooltip = useTooltipState()
return (
<>
<TheButton
{...props}
{...tooltip}
forwardedAs={Button}
aria-label={label}
>
{icon}
</TheButton>
<Tooltip {...tooltip}>{label}</Tooltip>
</>
)
},
)
export default IconButton

View file

@ -19,6 +19,8 @@ const Container = styled(TooltipImpl)`
font-weight: 500; font-weight: 500;
` `
export const Tooltip: VFC<TooltipProps> = ({className, ...props}) => ( export const Tooltip: VFC<TooltipProps> = ({className, ...props}) => {
<Container {...props} className={className as string} /> console.log('deprecate tooltip')
)
return <Container {...props} className={className as string} />
}

View file

@ -40,9 +40,19 @@ const Container = styled.div`
pointer-events: none; pointer-events: none;
` `
const PortalLayer = styled.div`
z-index: 51;
position: fixed;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
pointer-events: none;
`
export default function UIRoot() { export default function UIRoot() {
const studio = getStudio() const studio = getStudio()
const [containerRef, container] = useRefAndState<HTMLDivElement>( const [portalLayerRef, portalLayer] = useRefAndState<HTMLDivElement>(
undefined as $IntentionalAny, undefined as $IntentionalAny,
) )
const inside = usePrism(() => { const inside = usePrism(() => {
@ -61,8 +71,9 @@ export default function UIRoot() {
<> <>
<GlobalStyle /> <GlobalStyle />
<ProvideTheme> <ProvideTheme>
<PortalContext.Provider value={container}> <PortalContext.Provider value={portalLayer}>
<Container ref={containerRef}> <PortalLayer ref={portalLayerRef} />
<Container>
{shouldShowGlobalToolbar && <GlobalToolbar />} {shouldShowGlobalToolbar && <GlobalToolbar />}
{shouldShowTrigger && <TheTrigger />} {shouldShowTrigger && <TheTrigger />}
{shouldShowPanels && <PanelsRoot />} {shouldShowPanels && <PanelsRoot />}
@ -72,7 +83,7 @@ export default function UIRoot() {
</> </>
</StyleSheetManager> </StyleSheetManager>
) )
}, [studio, containerRef, container]) }, [studio, portalLayerRef, portalLayer])
return inside return inside
} }

View file

@ -6,6 +6,7 @@ import * as globalVariableNames from '@theatre/shared/globalVariableNames'
import type {$FixMe} from '@theatre/shared/utils/types' import type {$FixMe} from '@theatre/shared/utils/types'
import StudioBundle from './StudioBundle' import StudioBundle from './StudioBundle'
import type CoreBundle from '@theatre/core/CoreBundle' import type CoreBundle from '@theatre/core/CoreBundle'
export {default as ToolbarIconButton} from './uiComponents/toolbar/ToolbarIconButton'
const studioPrivateAPI = new Studio() const studioPrivateAPI = new Studio()
setStudio(studioPrivateAPI) setStudio(studioPrivateAPI)

View file

@ -0,0 +1,23 @@
import type {VFC} from 'react'
import React from 'react'
import {Tooltip as TooltipImpl, TooltipReference, useTooltipState} from 'reakit'
import type {TooltipProps} from 'reakit'
import styled from 'styled-components'
export {TooltipReference, useTooltipState}
const Container = styled(TooltipImpl)`
padding: 8px 14px;
font-size: 11px;
line-height: 1.25em;
border-radius: 2px;
background-color: #201f20;
color: white;
pointer-events: none;
font-weight: 500;
`
export const Tooltip: VFC<TooltipProps> = ({className, ...props}) => (
<Container {...props} className={className as string} />
)

View file

@ -0,0 +1,57 @@
import type {ReactElement} from 'react'
import React from 'react'
import styled from 'styled-components'
import {Tooltip, TooltipReference} from '@theatre/studio/uiComponents/Tooltip'
import {lighten} from 'polished'
import type {ButtonProps} from 'reakit'
import {useTooltipState} from 'reakit'
import {Button} from 'reakit'
const TheButton = styled(TooltipReference)`
pointer-events: auto;
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 600;
width: 28px;
height: 28px;
outline: none;
&:hover {
background-color: ${lighten(0.02, '#313131')};
color: white;
}
color: #c0c0c0;
background-color: #313131;
border: 1px solid #272727;
border-radius: 3px;
box-shadow: 1px 1px 0px #0000001c;
`
const ToolbarIconButton: React.FC<
Exclude<ButtonProps, 'children'> & {
icon: ReactElement
label: string
}
> = (props) => {
const tooltip = useTooltipState()
return (
<>
<TheButton
{...tooltip}
forwardedAs={Button}
aria-label={props.label}
onClick={props.onClick}
className={props.className}
>
{props.icon}
</TheButton>
<Tooltip {...tooltip}>{props.label}</Tooltip>
</>
)
}
export default ToolbarIconButton