-
Notifications
You must be signed in to change notification settings - Fork 6
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
10267 add cornerstone toggle to sidebar #668
10267 add cornerstone toggle to sidebar #668
Conversation
app/KeywordExample.js
Outdated
@@ -5,6 +5,7 @@ import styled from "styled-components"; | |||
// Internal dependencies. | |||
import KeywordInput from "../composites/Plugin/Shared/components/KeywordInput"; | |||
import SynonymsSection from "../composites/Plugin/Synonyms/components/SynonymsSection"; | |||
import CornerstoneToggle from "../composites/Plugin/CornerstoneContent/CornerstoneToggle"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this path should be "../composites/Plugin/CornerstoneContent/components/CornerstoneToggle"
margin-right: 10px; | ||
flex-shrink: 0; | ||
max-width: 75%; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the indentation in all these lines is made of spaces. Should be tabs.
@@ -0,0 +1,81 @@ | |||
import React from "react"; | |||
import PropTypes from "prop-types"; | |||
import Styled from "styled-components"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Styled should be lowercase
|
||
import GutenbergToggle from "../../Shared/components/GutenbergToggle"; | ||
|
||
const Cornerstone = Styled.div` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Styled should be lowercase
key={this.props.key} | ||
checked={this.state.cornerstoneToggleState} | ||
onChange={this.handleChange} | ||
id={this.props.toggleId} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
coding standards: all these lines (57 and 59-62) miss spaces between brackets.
The label should be always correctly associated with the input ID, more details in the CR comment.
* External dependencies | ||
*/ | ||
import React from "react"; | ||
import classnames from "classnames"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
has the introduction of the classnames package been discussed with @atimmer ?
className, | ||
{ 'is-checked': checked }, | ||
); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so to my understanding, this gets properly styled only when in Gutenberg. When used outside Gutenberg, it will be completely unstyled (as in the standalone app example > "Keyword" tab). Is this what we want?
<svg className="components-form-toggle__on" width="2" height="6" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2 6"><path d="M0 0h2v6H0z" /></svg> : <svg className="components-form-toggle__off" width="6" height="6" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 6 6"><path d="M3 1.5c.8 0 1.5.7 1.5 1.5S3.8 4.5 3 4.5 1.5 3.8 1.5 3 2.2 1.5 3 1.5M3 0C1.3 0 0 1.3 0 3s1.3 3 3 3 3-1.3 3-3-1.3-3-3-3z" /></svg> | ||
} | ||
</span> | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check indentation from line 24 to line 31
`; | ||
|
||
class CornerstoneToggle extends React.Component { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eslint "warning Block must not be padded by blank lines", please remove this blank line
import classnames from "classnames"; | ||
import noop from "lodash/noop"; | ||
|
||
function GutenbergToggle( { className, checked, id, onChange = noop, ...props } ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eslint error Missing JSDoc comment for this function
eslint error 'className' is missing in props validation
eslint error 'checked' is missing in props validation
eslint error 'id' is missing in props validation
eslint error 'onChange' is missing in props validation
|
||
function GutenbergToggle( { className, checked, id, onChange = noop, ...props } ) { | ||
const wrapperClasses = classnames( | ||
'components-form-toggle', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eslint error Strings must use doublequote
const wrapperClasses = classnames( | ||
'components-form-toggle', | ||
className, | ||
{ 'is-checked': checked }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eslint error Strings must use doublequote
/> | ||
<span className="components-form-toggle__track"></span> | ||
<span className="components-form-toggle__thumb"></span> | ||
{ checked ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eslint error '?' should be placed at the beginning of the line
<span className="components-form-toggle__track"></span> | ||
<span className="components-form-toggle__thumb"></span> | ||
{ checked ? | ||
<svg className="components-form-toggle__on" width="2" height="6" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2 6"><path d="M0 0h2v6H0z" /></svg> : <svg className="components-form-toggle__off" width="6" height="6" aria-hidden="true" role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 6 6"><path d="M3 1.5c.8 0 1.5.7 1.5 1.5S3.8 4.5 3 4.5 1.5 3.8 1.5 3 2.2 1.5 3 1.5M3 0C1.3 0 0 1.3 0 3s1.3 3 3 3 3-1.3 3-3-1.3-3-3-3z" /></svg> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eslint error Line 28 exceeds the maximum line length of 150
CR 🚧 please see comments About associating the label: when clicking on the text the toggle should switch. Instead, nothing happens. Since the label is not associated, the toggle (the underlying checkbox) is unlabelled and announced by screen readers just as "checkbox". In the rendered markup there's no "for" attribute: nor the checkbox has an ID. Looking at the props, there's a while the checkbox uses the Instead of passing this value as a prop, since the for/id attributes must always be set, I'd suggest to handle their values internally using |
<Cornerstone> | ||
<label htmlFor={this.props.key}>Cornerstone</label> | ||
<GutenbergToggle | ||
key={this.props.key} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure why there's the need of a key?
Note about accessibility;
We've suggested a couple alternative options: 1 2 However, none of these 3 options is implemented in this component nor there's a way to change the inline label or use a description. I'd like to suggest this should be discussed, trying to find a good balance between accessibility and design. Of course, this can be addressed in a separate issue. |
@afercia For the Yoast sidebar, we intend to copy any components needed from their Gutenberg equivalents (if they exist). So the problem we face is really a problem we should fix in Gutenberg. I understand you'd rather not ship something not up to a11y standards, and neither do I, so let's build our version of this toggle to be compliant, and contribute that back as a PR at the same time. I'm a fan of the ON/OFF labels, they're simply the most efficient way of indicating state textually, I think we should try that first. Do you see any problems with this approach? |
@hedgefield we already proposed the on/off text to the Gutenberg team, they don't like it. In the linked Gutenberg issues above we've also proposed different positions for the on/off (to the side or underneath the toggle) but still they don't like it. |
@afercia That's too bad. Hmm. I'm not a fan of the help text, it adds a lot of bloat to the interface. But we can conditionally change the label text already? So let's do that. And then what do you think, use a variation on the original design and go for |
} | ||
} | ||
|
||
CornerstoneToggle.propTypes = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We usually set defaults for PropTypes that are not required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CR done 🚧
Have some (minor) requests / questions.
`; | ||
|
||
const ToggleVisualLabel = styled.span` | ||
padding: 0px 0 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems odd to define 0px
followed by two zeroes. I believe you can set all three to a simple 0
and be done with it.
Additionally, this means you're deliberately resetting all padding except for the one on the left-hand side. Not sure if this is intended or not.
margin: 0; | ||
outline: 0; | ||
&:focus > span { | ||
box-shadow: inset 0 0 0 1px ${colors.$color_white}, 0 0 0 1px #5b9dd9, 0 0 2px 1px rgba(30, 140, 190, .8); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unsure as to why the first color is variable, but the other two are not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This applies also to "#a5d6a7"
on line 8. When new colors are needed, please discuss with the design team: "our" colors should all be in the color palette (_colors.scss
). Of course this makes sense when a new color is going to be used extensively. For colors that are used only once, we should wonder if they're really needed in the first place. Please consider this is essential to be able to keep our color palette under control in the long run. /Cc @hedgefield
In a way, #5b9dd9
and rgba(30, 140, 190, .8)
are an exception, as they're the colors WordPress uses for the focus style. Normally, they're inherited on interactive elements. If we're going to use them extensively on non-natively interactive elements then we may want to consider to add them to the color palette. Worth noting Gutenberg uses slightly different colors 😬
} | ||
|
||
/** | ||
* Returns the current enablement state. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enablement
should be enabled
/** | ||
* Returns the current enablement state. | ||
* | ||
* @returns {boolean} The current enablement state. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See previous comment.
* Sets the state to the opposite of the current state. | ||
* | ||
* @param {object} evt React SyntheticEvent. | ||
* @returns {void} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing whitespace above this line.
const ToggleBullet = styled.span` | ||
background-color: ${ props => props.isEnabled ? colors.$color_green_medium_light : colors.$color_grey_medium_dark }; | ||
margin-left: ${ props => props.isEnabled ? "12px" : "-2px" }; | ||
box-shadow: 0 2px 2px 2px rgba(0, 0, 0, 0.1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here: this is a hardcoded color. We should use a color from the palette (not necessarily a rgba color)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Andrea, you are right. But we'll skip this for now to finish the component. We'll pick this up again during the polishing process.
<ToggleBullet isEnabled={this.isEnabled()} /> | ||
</ToggleBar> | ||
<ToggleVisualLabel aria-hidden="true"> | ||
{ this.isEnabled() ? __( "On", "yoast-components" ) : __( "Off", "yoast-components" ) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this component is going to be reusable, we should be able to pass a different visual label text.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. We will make a issue next week to "improve" the toggle: refactor, change how we use colors and add props for the custom on/off label text.
* @param {object} evt React SyntheticEvent. | ||
* @returns {void} | ||
*/ | ||
setEnabled( evt ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please avoid abbreviations: event
is fine
aria-checked={this.isEnabled()} | ||
id={this.props.id} | ||
> | ||
<ToggleBullet isEnabled={this.isEnabled()} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing space within braces here and in the lines above
*/ | ||
setEnabled( evt ) { | ||
// Makes the toggle actionable with the Space bar key. | ||
if ( evt.type === "keydown" && evt.which !== 32 ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think keycode is safer than which (which is non-standard, though in jQuery is a normalized property in JavaScript it is not)
return ( | ||
<Cornerstone> | ||
<Toggle ariaLabel="Mark this post as cornerstone content" id="Cornerstone Toggle" | ||
labelText={__( "Mark this as cornerstone content.", "yoast-components" )} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing spaces between brackets
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a side note, we shouldn't use mixed spaces and tabs for indentation
render() { | ||
return ( | ||
<Cornerstone> | ||
<Toggle ariaLabel="Mark this post as cornerstone content" id="Cornerstone Toggle" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the id should be lowercase and without spaces (it's used for HTML attributes). Also, it can't be hardcoded. IDs must be unique in a page, otherwise it's impossible to use more than one toggle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, in the toggle it is a prop we can set, but in the cornerstone toggle we keep it hard coded for now because there is only one cornerstone toggle.
…hub.com/Yoast/yoast-components into 10267-add-cornerstone-toggle-to-sidebar
<ToggleDiv> | ||
{ /* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions */ } | ||
<label | ||
htmlFor={ this.props.id } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not important enough for now, and also more a preference than an instruction.
but when props are used in multiple places, it's nice to extract props to local variables, this is done, for example, in SnippetEditorFields.js.
CR: no important comments. but merge conflicts. 😞 |
Summary
This PR can be summarized in the following changelog entry:
Relevant technical choices:
GutenbergToggle.js
. When the WP component becomes available we can remove this code and simply import the component.yoast_wpseo_is_cornerstone
value. For this we need the the finished container which houses the cornerstone toggle and is connected to the store.Test instructions
This PR can be tested by following these steps:
10267-add-cornerstone-toggle-to-sidebar
in both components as well as Wordpress SEO and yarn link them (not needed when this is an RC).define( 'YOAST_FEATURE_GUTENBERG_SIDEBAR', true );
is set in wp-config.php.Fixes #10267
Requires #10405