Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guided Tours: Add docs for our API #10007

Merged
merged 19 commits into from Jan 10, 2017
Merged

Guided Tours: Add docs for our API #10007

merged 19 commits into from Jan 10, 2017

Conversation

marekhrabe
Copy link
Contributor

@marekhrabe marekhrabe commented Dec 13, 2016

Our API consists mainly of JSX components that you compose to create a tour. This PR should add explanations for their usage.

@matticbot
Copy link
Contributor

@mcsf
Copy link
Member

mcsf commented Dec 14, 2016

As discussed in Slack, +1 to splitting this off into its own docs/API.md file or similar.

Meanwhile, my other observation, once that happens, would be to separate the API description into two sections: layout components and flow-control components. Although Tour and Step are arguably very special in that they do both, I would place them under layout, like so:

  • layout: Tour, Step, ButtonRow, Link
  • flow control: Next, Quit, Continue

Oh, and I would choose a more deliberate sorting of the items, like the one I suggested above, than something alphabetical. In this particular case, I think it creates an easier-to-follow sequence, from broad to narrow (Tour → Step → Row), from simple to flexible (Next → Continue).

Copy link
Member

@mcsf mcsf left a comment

Choose a reason for hiding this comment

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

Looks good so far! Added a few comments. The mini examples are very useful, IMO

@@ -0,0 +1,162 @@
# Guided Tours API

Guided Tours are declared as a tree of JSX components.
Copy link
Member

Choose a reason for hiding this comment

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

Since

  • JSX is just syntactic sugar;
  • I believe these are technically elements (as in: Foo is a component, <Foo /> is an element);

I think we could rephrase as

-Guided Tours are declared as a tree of JSX components.
+Guided Tours are declared in JSX as a tree of elements.

### Props

* `name`: (string) Unique identifier of the step.
* `target`: (string, optional) Target which this step belongs to and will be used for positioning. This prop is value is used to look up according `[data-tip-target]` in DOM. If omitted, `<body>` will be used as target. TODO: mention querySelector hack?, is body really default target?
Copy link
Member

Choose a reason for hiding this comment

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

querySelector hack

Even though it was intended as a secondary mechanism, we do use it a bit and has a few interesting strengths, like in when .some-container .some-state-like-is-valid .my-target. We should mention it.

<body> will be used

Well, in a way. positioning will grab body.getBoundingClientRect() in a few places if no target is found, but I wouldn't say that body is a "default target". Failing to provide a target will mess up positioning with most placement methods, unless they're meant for that.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, and the second sentence has a typo or omission somewhere — maybe s/is value/'s value/?

* `name`: (string) Unique identifier of the step.
* `target`: (string, optional) Target which this step belongs to and will be used for positioning. This prop is value is used to look up according `[data-tip-target]` in DOM. If omitted, `<body>` will be used as target. TODO: mention querySelector hack?, is body really default target?
* `placement`: (string, optional) Placement. Possible values: 'below', 'above', 'beside', 'center', 'middle', 'right'
* `arrow`: (string, optional) If defined, step will get arrow pointing to a direction. Available: 'top-left', 'top-center', 'top-right',
Copy link
Member

Choose a reason for hiding this comment

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

Should we explain what they are? The names are kind of meaningless. Same question for placement

Copy link
Member

Choose a reason for hiding this comment

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

Better yet, have a mini-gallery at the end of this paragraph with captions showing the arrows? :) Could be doable by tweaking props directly via React dev tools.

* `placement`: (string, optional) Placement. Possible values: 'below', 'above', 'beside', 'center', 'middle', 'right'
* `arrow`: (string, optional) If defined, step will get arrow pointing to a direction. Available: 'top-left', 'top-center', 'top-right',
'right-top', 'right-middle', 'right-bottom', 'bottom-left', 'bottom-center', 'bottom-right', 'left-top', 'left-middle', 'left-bottom'
* `style`: (object, optional) Will be used as step's inline style.
Copy link
Member

Choose a reason for hiding this comment

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

I would add a word of advice, like:

  • use sparingly;
  • avoid changing the look and feel of Guided Tours;
  • useful for minor positioning adjustments, z-index, etc.


Note that all text content needs to be wrapped in `<p>` so it gets proper styling.

This is just a quick and not very useful tour. You can see more examples in [TUTORIAL.md](TUTORIAL.md) or by exploring existing tours in client/layout/guided-tours/tours.
Copy link
Member

Choose a reason for hiding this comment

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

I'd make this shorter, skip the first sentence and open with For more comprehensive examples, …

* `hidden`: (bool, optional) If true, this will not render anything in Step, while functionality remains.
* `icon`: (string, optional) Name of Gridicon to show in custom message.
* `when`: (function, optional) Redux selector. Once it evaluates to true, tour will advance to `step`.

Copy link
Member

Choose a reason for hiding this comment

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

Missing prop is children. It's good to make it clear that it is possible to use children, but also (importantly) that it is not needed, as we have good defaults — with and without icon

- text
- text + props.icon
- custom content

Copy link
Member

Choose a reason for hiding this comment

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

With no introduction, I find this enumeration confusing

// continue when user clicks DOM element with html attribute `data-tip-target="my-sites"`
<Continue step="next-step" click target="my-sites" />
// continue when Redux selector evaluates to true (in this case after user opens preview)
<Continue step="next-step" when={ isPreviewShowing } />
Copy link
Member

Choose a reason for hiding this comment

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

Not sure what the place to say this is, but authors should be aware that when will only work if something triggers a re-render of the step and that the proper way to set this up is to add the relevant action types to actionLog's whitelist.

// with default label
<Next step="next-step" />
// or with a custom one
<Next step="next-step">Custom Label</Next>`
Copy link
Member

Choose a reason for hiding this comment

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

Add translate( )

Copy link
Member

Choose a reason for hiding this comment

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

Same for Quit

@marekhrabe marekhrabe added [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. and removed [Status] Needs Author Reply labels Dec 23, 2016

## All-in example

Before we go into full details, let's look at this example. It includes most possible things you can use.
Copy link
Contributor

Choose a reason for hiding this comment

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

Make sure to say somewhere it's an example for a Step, and what a Step is. I first thought OK, I'll now get to see an example of a full tour.


## Tour

Tour is a React component that declares the top-level of a tour. It defines conditions for starting a tour and contains `<Step>` elements as children.
Copy link
Contributor

Choose a reason for hiding this comment

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

Tour doesn't appear in the example above. Again, somewhat confusing.


## Step

Step is a React component that defines a single Step of a tour. It is represented as dark box on top of Calypso UI. Step can be positioned in many ways in relation to any DOM node in Calypso that is marked with `[data-tip-target]` attribute.
Copy link
Contributor

Choose a reason for hiding this comment

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

target also accepts a CSS selector, we'll then use the first match.

Copy link
Contributor

Choose a reason for hiding this comment

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

ah, you say it below. maybe remove implementation details here and just say "DOM node in Calypso".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's mentioned in the prop list just few lines below. Should it also be here?

Copy link
Contributor

Choose a reason for hiding this comment

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

see my second comment. :)

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm still going through it, you know. :)


### Props

* `name`: (string) Unique identifier of the step.
Copy link
Contributor

Choose a reason for hiding this comment

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

, used for ... (next)

Copy link
Contributor

Choose a reason for hiding this comment

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

also, init and finish are magic step names I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

had no idea, thanks! btw: what if the tour has only one step? is it init?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it seems like the only magical name is init, isn't it? finish is not detected anywhere as far as I'm looking right

Copy link
Contributor

Choose a reason for hiding this comment

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

didn't I reply to this before? weird. in any case, you're right. finish was used previously for styling, but isn't used anymore.

### Props

* `name`: (string) Unique identifier of the step.
* `target`: (string, optional) Target which this step belongs to and will be used for positioning. Value of this prop is used to look up according `[data-tip-target]` in DOM. If you start this value with `.` (dot), it will be evaluated as a query selector, so you can select elements that have no `[data-tip-target]` defined.
Copy link
Contributor

Choose a reason for hiding this comment

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

also works as a selector if a space is in there. maybe add # to the check. the . is just an indicator for "hey, classname selector".

Copy link
Contributor

Choose a reason for hiding this comment

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

i.e. it's passed along as is. the . isn't removed.

### Props

* `name`: (string) Unique identifier of the step, used for addressing a step from `Next` or `Continue`.
* `target`: (string, optional) Target which this step belongs to and will be used for positioning. Value of this prop is used to look up according `[data-tip-target]` in DOM. If you start this value with `.` (dot), it will be evaluated as a query selector, so you can select elements that have no `[data-tip-target]` defined.
Copy link
Contributor

Choose a reason for hiding this comment

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

if you start with . or if it contains a space, those we use as indicators to figure out whether it's maybe a selector. we might also want to add # to that.


Guided Tours are declared in JSX as a tree of elements. All of them are available as named exports from `client/layout/guided-tours/config-elements`.

## All-in example
Copy link
Contributor

Choose a reason for hiding this comment

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

instead of having the Step here, move it to ## Step below.

here you might want to add some more general advice, like, a Tour is a series of Step elements. the tour gets triggered either if selectors match or when it's forced to start through a query argument. (document the query arg somewhere, maybe where you document the tour name prop) the user can then step through the tour and get Calypso aspects explained. can be interactive in that Step element can wait for a user to do certain actions such as clicking a menu item. we can also skip tour steps depending on selectors, e.g. skip a single Step if that one doesn't work well on mobile.

* `placement`: (string, optional) Placement. Possible values: 'below', 'above', 'beside', 'center', 'middle', 'right'
* `arrow`: (string, optional) If defined, step will get arrow pointing to a direction. Available: 'top-left', 'top-center', 'top-right',
'right-top', 'right-middle', 'right-bottom', 'bottom-left', 'bottom-center', 'bottom-right', 'left-top', 'left-middle', 'left-bottom'
* `style`: (object, optional) Will be used as step's inline style. Use sparingly and with caution for minor tweaks in positioning or z-indexes and avoid changing the look and feel of Guided Tours. If you use this is a way that could benefit all Guided Tours globally, please consider creating an issue.
Copy link
Contributor

Choose a reason for hiding this comment

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

give example so format becomes obvious

### Props

* `step`: (string) Name of the step the tour will advance to.
* `target`: (string, optional) Name of `[data-tip-target]` that would be watched.
Copy link
Contributor

Choose a reason for hiding this comment

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

or CSS selector

Copy link
Contributor

Choose a reason for hiding this comment

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

right?

Copy link
Contributor

Choose a reason for hiding this comment

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

not sure actually.

Copy link
Member

Choose a reason for hiding this comment

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

I expect so, as it's calling targetForSlug internally.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we might want to extract docs for targetForSlug somehow and link to it from several places, where we explain target

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, maybe just introduce something like a pseudo-datatype "Target" that we only use in the docs.

There are currently two ways to declare the condition to continue the tour.

- Binding an `onClick` listener to a DOM node marked as `[data-tip-target]`
- Redux selector function that evaluates to true in order to advance the tour
Copy link
Contributor

Choose a reason for hiding this comment

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

well, or just add a Next button

Copy link
Contributor Author

Choose a reason for hiding this comment

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

but is this really the right place to do that? this section explains how to use Continue in different ways and Next is not one of them

Copy link
Contributor

Choose a reason for hiding this comment

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

"There are currently two ways to declare the condition to continue the tour" is a more general statement than "here's how you use Continue", which is why I'd add the Next button (with mentioning the caveat that it's not for use with Continue, but an alternative) — or reword the "two ways" sentence.

Copy link
Member

@mcsf mcsf left a comment

Choose a reason for hiding this comment

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

Looks great! Highlighted a couple of things to fix.


### Props

* `primary` (bool, optional) If true, button will be rendered as primary. Use only if Quit is the only available action in that step.
Copy link
Member

Choose a reason for hiding this comment

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

While we're here, let's add Leif's subtle prop from #10035.

<Quit />

// with a custom label
<Quit>{ translate( 'Custom Label' ) }</Quit>`
Copy link
Member

Choose a reason for hiding this comment

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

There's a stray backtick at the end of the line


### Example

```
Copy link
Member

Choose a reason for hiding this comment

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

Minor: make that a ```js

@lsinger lsinger added [Status] Ready to Merge and removed [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Jan 10, 2017
@lsinger lsinger merged commit be177de into master Jan 10, 2017
@lsinger lsinger deleted the add/gt-component-docs branch January 10, 2017 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants