Skip to content

Commit

Permalink
[base] Improve ChangeBar UI
Browse files Browse the repository at this point in the history
  • Loading branch information
mariuslundgard authored and rexxars committed Oct 6, 2020
1 parent b8e83a8 commit 2eeebcc
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 47 deletions.
85 changes: 72 additions & 13 deletions packages/@sanity/base/src/change-indicators/ChangeBar.css
Original file line number Diff line number Diff line change
@@ -1,31 +1,90 @@
@import 'part:@sanity/base/theme/variables-style';

:root {
--change-bar-changed-color: var(--state-warning-color);
}

.root {
display: flex;
position: relative;
}

.field {
flex-grow: 1;
min-width: 0;
}

.hoverArea {
position: absolute;
right: -4px;
width: 8px;
height: 100%;
.wrapper {
position: relative;
opacity: 1;
transition: opacity 100ms;

@nest .root:not([data-changed]) {
opacity: 0;
}
}

.changeBar {
height: 100%;
.bar {
position: absolute;
right: -1px;
top: 0;
left: -1px;
width: 2px;
border-bottom-right-radius: 4px;
border-top-right-radius: 4px;
bottom: 0;
background: var(--change-bar-changed-color);
border-bottom-right-radius: 2px;
border-top-right-radius: 2px;
}

.tooltip {
display: flex;
align-items: center;
.badge {
position: absolute;
background: var(--change-bar-changed-color);
top: 50%;
left: -9px;
width: 19px;
height: 19px;
border-radius: 9.5px;
transform: translate3d(-0.5px, -10px, 0) scale(0, 1);
transition: transform 100ms;

@nest .root[data-hover] & {
transform: translate3d(-0.5px, -10px, 0) scale(1);
}
}

.badge__shape {
display: block;
position: absolute;
width: 20px;
height: 27px;
transform: translate3d(-0.5px, -4px, 0);
color: var(--change-bar-changed-color);
}

.badge__icon {
display: block;
position: relative;
margin: 1px;
font-size: calc(17 / 16 * 1rem);
color: var(--component-bg);
}

.hitArea {
position: absolute;
left: calc(0 - var(--extra-small-padding));
width: calc(var(--extra-small-padding) + 2px + var(--medium-padding));
height: 100%;
cursor: pointer;
}

.tooltipContent {
padding: var(--small-padding);
font-size: var(--font-size-small);
line-height: var(--line-height-small);
white-space: nowrap;
color: var(--text-color-secondary);

@nest & > span {
display: block;
margin: -4px 0 -3px;
}
}
92 changes: 60 additions & 32 deletions packages/@sanity/base/src/change-indicators/ChangeBar.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,80 @@
import {Popover} from 'part:@sanity/components/popover'
import React, {useCallback} from 'react'
import RestoreIcon from '../components/icons/History'
import {Tooltip} from 'part:@sanity/components/tooltip'
import React, {useCallback, useState} from 'react'
import {ConnectorContext} from './ChangeIndicatorContext'

import styles from './ChangeBar.css'

function Shape(props: Omit<React.SVGProps<SVGElement>, 'ref'>) {
return (
<svg {...props} viewBox="0 0 20 27" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M9 0.448608C9 2.49663 7.38382 4.13678 5.57253 5.09261C2.55605 6.68443 0.5 9.8521 0.5 13.5C0.5 17.1479 2.55605 20.3155 5.57253 21.9074C7.38382 22.8632 9 24.5033 9 26.5514V27H11V26.5514C11 24.5033 12.6162 22.8632 14.4275 21.9074C17.4439 20.3155 19.5 17.1479 19.5 13.5C19.5 9.8521 17.4439 6.68443 14.4275 5.09261C12.6162 4.13678 11 2.49663 11 0.448608V0H9V0.448608Z"
fill="currentColor"
/>
</svg>
)
}

function EditIconSmall(props: Omit<React.SVGProps<SVGElement>, 'ref'>) {
return (
<svg
{...props}
width="1em"
height="1em"
viewBox="0 0 17 17"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4.5 10.5L4 13L6.5 12.5L14 5L12 3L4.5 10.5Z"
stroke="currentColor"
strokeWidth="1.2"
/>
<path d="M10 5L12 7" stroke="currentColor" strokeWidth="1.2" />
</svg>
)
}

export const ChangeBar = React.forwardRef(
(props: {isChanged: boolean; children: React.ReactNode}, ref: any) => {
const [isPopoverOpen, setPopoverOpen] = React.useState(false)
const [hover, setHover] = useState(false)
const {onOpenReviewChanges, isReviewChangesOpen} = React.useContext(ConnectorContext)

const handleMouseEnter = useCallback(() => setPopoverOpen(true), [])
const handleMouseLeave = useCallback(() => setPopoverOpen(false), [])
const handleMouseEnter = useCallback(() => setHover(true), [])
const handleMouseLeave = useCallback(() => setHover(false), [])

const tooltipContent = (
<div className={styles.tooltip}>
<RestoreIcon /> Review changes
<div className={styles.tooltipContent}>
<span>Review changes</span>
</div>
)

return (
<div ref={ref} className={styles.root}>
<div
ref={ref}
className={styles.root}
data-changed={props.isChanged ? '' : undefined}
data-hover={hover ? '' : undefined}
>
<div className={styles.field}>{props.children}</div>
{props.isChanged && (
<Popover
content={tooltipContent}
placement="top"
open={!isReviewChangesOpen && isPopoverOpen}
>

<Tooltip content={tooltipContent} placement="top">
<div className={styles.wrapper}>
<div className={styles.bar} />

<div className={styles.badge}>
<Shape className={styles.badge__shape} />
<EditIconSmall className={styles.badge__icon} />
</div>

<div
onClick={isReviewChangesOpen ? null : onOpenReviewChanges}
className={styles.changeBarWrapper}
>
<div
className={styles.changeBar}
style={{
backgroundColor: props.isChanged ? '#2276fc' : ''
}}
/>
<div
onClick={isReviewChangesOpen ? null : onOpenReviewChanges}
className={styles.hoverArea}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
/>
</div>
</Popover>
)}
className={styles.hitArea}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
/>
</div>
</Tooltip>
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react'
import {ChangeIndicatorContext} from './ChangeIndicatorContext'
import {useReporter} from './tracker'
import isEqual from 'react-fast-compare'
import * as PathUtils from '@sanity/util/paths'
import {Path} from '@sanity/types'
import {useReporter} from './tracker'
import {ChangeIndicatorContext} from './ChangeIndicatorContext'
import {ChangeBar} from './ChangeBar'

const isPrimitive = value =>
Expand Down Expand Up @@ -32,6 +32,7 @@ const ChangeBarWrapper = (
hasFocus: props.hasFocus,
hasHover: hasHover
}))

return (
<div ref={ref} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
<ChangeBar isChanged={props.isChanged}>{props.children}</ChangeBar>
Expand Down

0 comments on commit 2eeebcc

Please sign in to comment.