Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

feat(popup): base implementation #150

Merged
merged 13 commits into from
Sep 11, 2018
Merged

feat(popup): base implementation #150

merged 13 commits into from
Sep 11, 2018

Conversation

bmdalex
Copy link
Collaborator

@bmdalex bmdalex commented Aug 28, 2018

Popup

This PR introduces the Popup, a component that displays additional information on top of a page at the end of the body DOM element. It comes with the following props:

  • basic?: boolean: when true, it introduces basic CSS styling for the popup (default false)
  • align?: 'top' | 'bottom' | 'start' | 'end' | 'center'
  • position?: 'above' | 'below' | 'before' | 'after': the position of the popup
  • trigger: JSX.Element: the React component that controls the popup; for now, clicking it toggles the visibility of the popup

TODO

  • Conformance test
  • Minimal doc site example
  • Stardust base theme
  • Teams Light theme
  • Teams Dark theme
  • Teams Contrast theme
  • Confirm RTL usage
  • W3 accessibility check
  • Stardust accessibility check
  • Update glossary props table
  • Update the CHANGELOG.md

API Proposal

Default

screen shot 2018-08-28 at 18 41 50

A default popup requires the trigger prop and renders a popup at the end of the body DOM element

<Popup trigger={<Button content="Add" />} content="Add users to your feed" />

generates

<button>Add</button>

and at the end of body DOM element:

<body>
  ...
  <div>Add users to your feed</div>
</body>

Basic

screen shot 2018-08-28 at 18 36 13

A basic popup renders a popup with very basic CSS.

<Popup basic trigger={<Button content="Add" />} content="Add users to your feed" />

generates

<button>Add</button>

and at the end of body DOM element:

<body>
  ...
  <div>Add users to your feed</div>
</body>

Alignment and Position

A popup can be rendered in 12 different combinations of align and position props around the trigger element:

  • position="above" align="start":
LTR RTL
screen shot 2018-09-11 at 01 55 02 screen shot 2018-09-11 at 01 58 00
  • position="above" align="center":
LTR RTL
screen shot 2018-09-11 at 01 55 19 screen shot 2018-09-11 at 01 58 08
  • position="above" align="end":
LTR RTL
screen shot 2018-09-11 at 01 55 31 screen shot 2018-09-11 at 01 58 17
  • position="below" align="start":
LTR RTL
screen shot 2018-09-11 at 01 55 44 screen shot 2018-09-11 at 01 58 27
  • position="below" align="center":
LTR RTL
screen shot 2018-09-11 at 01 55 54 screen shot 2018-09-11 at 01 58 36
  • position="below" align="end":
LTR RTL
screen shot 2018-09-11 at 01 56 01 screen shot 2018-09-11 at 01 58 47
  • position="before" align="top":
LTR RTL
screen shot 2018-09-11 at 01 56 09 screen shot 2018-09-11 at 01 59 46
  • position="before" align="center":
LTR RTL
screen shot 2018-09-11 at 01 56 16 screen shot 2018-09-11 at 01 59 55
  • position="before" align="bottom":
LTR RTL
screen shot 2018-09-11 at 01 56 23 screen shot 2018-09-11 at 02 00 03
  • position="after" align="top":
LTR RTL
screen shot 2018-09-11 at 01 56 31 screen shot 2018-09-11 at 02 00 11
  • position="after" align="center":
LTR RTL
screen shot 2018-09-11 at 01 56 38 screen shot 2018-09-11 at 02 00 18
  • position="after" align="bottom":
LTR RTL
screen shot 2018-09-11 at 01 56 51 screen shot 2018-09-11 at 02 00 27
<Popup
  align="start"
  position="above"
  trigger={<Button content="Add" />}
  content="Add users to your feed"
/>

generates

<button>Add</button>

and at the end of body DOM element:

<body>
  ...
  <div>Add users to your feed</div>
</body>

@layershifter
Copy link
Member

layershifter commented Aug 28, 2018

The positioning part of the Popup component is one of complicated things. Can we omit it and use PopperJS there?

/cc @levithomason

@codecov
Copy link

codecov bot commented Aug 28, 2018

Codecov Report

Merging #150 into master will increase coverage by 0.92%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #150      +/-   ##
==========================================
+ Coverage   90.17%   91.09%   +0.92%     
==========================================
  Files          55       59       +4     
  Lines         916     1011      +95     
  Branches      142      159      +17     
==========================================
+ Hits          826      921      +95     
  Misses         86       86              
  Partials        4        4
Impacted Files Coverage Δ
src/index.ts 100% <100%> (ø) ⬆️
src/components/Popup/PopupContent.tsx 100% <100%> (ø)
src/components/Popup/positioningHelper.ts 100% <100%> (ø)
src/components/Popup/index.ts 100% <100%> (ø)
src/components/Popup/Popup.tsx 100% <100%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7cde3dd...935d4ec. Read the comment docs.

@bmdalex
Copy link
Collaborator Author

bmdalex commented Aug 28, 2018

@layershifter
agreed, RTL and handling viewport limits do not work in this implementation; I took a look at react-popper package and looks pretty cool.

@levithomason this is definitely something we want to try; do we want to address it in this PR or should we iterate?

@bmdalex bmdalex added help wanted Extra attention is needed question Further information is requested, concerns that require additional thought are raised and removed help wanted Extra attention is needed labels Aug 28, 2018
@bmdalex bmdalex changed the title Feat/popup simple feat(popup): base implementation Aug 29, 2018
@levithomason
Copy link
Member

levithomason commented Aug 29, 2018

Popper looks extremely promising. It looks like the React wrapper is also gaining a lot of adoption:
https://www.npmjs.com/package/react-popper

Let's definitely do our due diligence here and compare what we'd gain and lose by switching. I would love nothing more than to off load the problem components, such as Popup, to a shared community work load.


Edit

Just saw your latest comment @Bugaa92, yes, let's try Popper now before merging.

@levithomason levithomason added needs author feedback Author's opinion is asked and removed question Further information is requested, concerns that require additional thought are raised labels Aug 29, 2018
@sophieH29
Copy link
Contributor

From the accessibility point of view, as a User, I would like to add Popup behavior which will have defined actions to open/close popup with specified keys

actionsDefinition: {
    trigger: {
      open: {
        keyCombinations: [{ keyCode: keyboardKey.Enter }, { keyCode: keyboardKey.Spacebar }, { keyCode: keyboardKey.ArrowDown }],
      },
    },
    portal: {
      close: {
        keyCombinations: [{ keyCode: keyboardKey.Escape }],
      },
    }
  }

And since as open/close logic is enclosed into the portal component, can we rethink its API to give a possibility to trigger open/close function from a popup? What your thoughts about it?

@Bugaa92 @levithomason @jurokapsiar

@miroslavstastny
Copy link
Member

Also we should think about screener tests for this. With current examples, there is no screener coverage for the examples, because these are the screenshots we compare:
image

So we either need to add examples with popup initially displayed (which will not work for some variants like fullscreen) or better introduce Test integrations for Screener tests.

@bmdalex
Copy link
Collaborator Author

bmdalex commented Sep 3, 2018

@levithomason
@kuzhelov
@mnajdova

what do you guys think about @miroslavstastny 's suggestions regarding visual tests? see his comment below, he has a very good point!

currently we don't seem to have the infrastructure to do this kind of scenario tests (that involve actions) and I'm afraid having the popups open by default are going to offer a bad UX

@bmdalex bmdalex force-pushed the feat/popup-simple branch 3 times, most recently from ee3da57 to ed34c98 Compare September 4, 2018 09:35
@bmdalex bmdalex force-pushed the feat/popup-simple branch 3 times, most recently from 597ff68 to 00f6ef0 Compare September 6, 2018 11:58
Copy link
Member

@miroslavstastny miroslavstastny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

top-* and bottom-* positions are not flipped in RTL:
image
image

package.json Outdated Show resolved Hide resolved
src/components/Ref/Ref.tsx Outdated Show resolved Hide resolved

type ReactMouseEvent = React.MouseEvent<HTMLElement>

export interface IPortalProps {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The interface does not match propTypes - as, children, styles, variables

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed

after = 'after',
}

type Position =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's just me, but I am still confused with the naming here. Let's discuss what the two parts of the position name mean in both RTL and LTR and agree on the naming in broader group.
I guess the main source of confusion is start/end meaning something different in combination with top/bottom vs before/after. I can see the inspiration in flexbox'es main/cross axis, but still...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea, I'll add this to your meeting notes to discuss it with everybody

src/components/Popup/PopupContent.tsx Outdated Show resolved Hide resolved
}

componentDidMount() {
_.invoke(this.props, 'innerRef', findDOMNode(this))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was a condition in SUIR code, let's use it there, too

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure it's necessary since _.invoke invokes innerRef function only if it's defined; isn't it the same as SUIR?

@miroslavstastny miroslavstastny added needs author changes Author needs to implement changes before merge and removed 💥 blocked help wanted Extra attention is needed labels Sep 7, 2018
@bmdalex
Copy link
Collaborator Author

bmdalex commented Sep 7, 2018

@miroslavstastny

  • I fixed RTL for all positions
  • I added UTs to cover these properly
  • I updated screenshots with new popup styles and RTL examples to make things more obvious

test/specs/components/Popup/Popup-test.tsx Outdated Show resolved Hide resolved
test/specs/components/Popup/Popup-test.tsx Show resolved Hide resolved
const computedStyle = rtl ? rtlCSSJS(style) : style

return (
<Popup.Content innerRef={ref} basic={basic} styles={{ root: computedStyle }}>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RTL is broken in docsite as dir="rtl" is not set on body which is a parent of Popup.Content.
Do we want to add something like {...rtl && {dir:"rtl"}} here? @jurokapsiar

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, very good catch; I missed it because of using simple text as content (with no punctuation)

@bmdalex bmdalex mentioned this pull request Sep 10, 2018
const alignedVertically = a === 'top' || a === 'bottom'

return (
(isPositionedVertically && alignedVertically) || (!isPositionedVertically && !alignedVertically)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

isPositionedVertically === alignedVertically

@sophieH29
Copy link
Contributor

@Bugaa92 I would add a description to each button in the example (with used props align="start" position="start") as you did in the PR's description. Because currently you're just guessing what position you'll get when clicking on a button :)
popup _ stardust 2018-09-11 14-54-47

What do you think?

@bmdalex bmdalex merged commit b851b3d into master Sep 11, 2018
@bmdalex bmdalex deleted the feat/popup-simple branch September 11, 2018 15:38
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
needs author changes Author needs to implement changes before merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants