Add tag rules to article v2 editor (#4339)

* Add tag rules to article v2 editor

* Add bottom phrase to tag dropdown

* Remove console logs

* Remove empty space in css

* Remove commented code and clean up css

* Add type='button' for a11y
This commit is contained in:
Ben Halpern 2019-10-10 20:19:12 -04:00 committed by GitHub
parent 27a7a199d7
commit 0a60faec8c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 83 additions and 11 deletions

View file

@ -381,12 +381,17 @@
.listingform__tagoptionrow {
padding: 10px;
cursor: pointer;
position: relative;
&:hover {
background: lighten($green, 27%);
color: $black;
}
}
.listingform__tagsoptionsbottomrow, .listingform__tagsoptionrulesbutton, .listingform__tagrules--inactive {
display: none; //not yet fully functional or relevant
}
.listingform__tagoptionrow--active {
background: $green;
color: $black;

View file

@ -269,6 +269,7 @@
padding: 10px;
font-weight: bold;
cursor: pointer;
position: relative;
&:hover {
background: lighten($green, 27%);
background: var(--theme-container-background-hover, lighten($green, 27%));
@ -277,6 +278,44 @@
}
}
.articleform__tagsoptionsbottomrow {
padding: 12px 10px 10px;
font-weight: bold;
cursor: pointer;
position: relative;
font-size: 0.7em;
font-style: italic;
border-top: 1px solid $medium-gray;
color: var(--theme-secondary-color, $black);
}
.articleform__tagsoptionrulesbutton {
position: absolute;
right: 8px;
top: 9px;
border: 0;
border-radius: 3px;
background: var(--theme-anchor-color, $sky-blue);
color: var(--theme-container-background, white);
font-size: 0.8em;
width: 100px;
}
.articleform__tagrules--inactive {
display: none
}
.articleform__tagrules--active {
font-size: 0.76em;
max-height: 270px;
overflow: auto;
border: 1px solid $medium-gray;
border-radius: 3px;
margin-top: 8px;
padding: 0px 8px;
}
.articleform__tagoptionrow--active {
background: $green;
background: var(--theme-container-accent-background, $green);

View file

@ -31,7 +31,7 @@ exports[`<ArticleForm /> renders properly 1`] = `
class="articleform__tagswrapper"
>
<input
autoComplete="on"
autoComplete="off"
class="articleform__tags"
id="tag-input"
onBlur={[Function]}

View file

@ -416,7 +416,8 @@ export default class ArticleForm extends Component {
defaultValue={tagList}
onInput={linkState(this, 'tagList')}
maxTags={4}
classPrefix={`articleform`}
autoComplete='off'
classPrefix='articleform'
/>
{
setupImageButton({

View file

@ -7,6 +7,7 @@ Object {
"prevLen": 0,
"searchResults": Array [],
"selectedIndex": -1,
"showingRulesForTag": null,
}
`;
@ -15,7 +16,7 @@ exports[`<Tags /> renders properly 1`] = `
class="articleform__tagswrapper"
>
<input
autoComplete="on"
autoComplete="off"
class="articleform__tags"
id="tag-input"
onBlur={[Function]}
@ -37,6 +38,7 @@ Object {
"prevLen": 0,
"searchResults": Array [],
"selectedIndex": -1,
"showingRulesForTag": null,
}
`;
@ -47,6 +49,7 @@ Object {
"prevLen": 0,
"searchResults": Array [],
"selectedIndex": -1,
"showingRulesForTag": null,
}
`;
@ -86,6 +89,7 @@ Object {
},
],
"selectedIndex": 0,
"showingRulesForTag": null,
}
`;
@ -125,5 +129,6 @@ Object {
},
],
"selectedIndex": 0,
"showingRulesForTag": null,
}
`;

View file

@ -35,6 +35,7 @@ class Tags extends Component {
additionalTags: [],
cursorIdx: 0,
prevLen: 0,
showingRulesForTag: null,
};
const algoliaId = document.querySelector("meta[name='algolia-public-id']")
@ -128,15 +129,25 @@ class Tags extends Component {
data-content={tag.name}
>
{tag.name}
{(tag.rules_html && tag.rules_html.length > 0) ? <button
type='button'
className={`${this.props.classPrefix}__tagsoptionrulesbutton`}
onClick={this.handleRulesClick}
data-content={tag.name}
>
{this.state.showingRulesForTag === tag.name ? 'Hide Rules' : 'View Rules'}
</button> : ''}
<div className={`${this.props.classPrefix}__tagrules--${this.state.showingRulesForTag === tag.name ? 'active' : 'inactive'}`} dangerouslySetInnerHTML={{ __html: tag.rules_html }} />
</div>
));
if (
this.state.searchResults.length > 0 &&
document.activeElement.id === 'tag-input'
(document.activeElement.id === 'tag-input' || document.activeElement.className === 'articleform__tagsoptionrulesbutton')
) {
searchResultsHTML = (
<div className={`${this.props.classPrefix}__tagsoptions`}>
{searchResultsRows}
<div className={`${this.props.classPrefix}__tagsoptionsbottomrow`}>Some tags have rules and guidelines determined by community moderators</div>
</div>
);
}
@ -150,7 +161,7 @@ class Tags extends Component {
ref={t => (this.textArea = t)}
className={`${this.props.classPrefix}__tags`}
placeholder={`${this.props.maxTags} tags max, comma separated, no spaces or special characters`}
autoComplete={this.props.autoComplete || 'on'}
autoComplete='off'
value={this.props.defaultValue}
onInput={this.handleInput}
onKeyDown={this.handleKeyDown}
@ -162,10 +173,21 @@ class Tags extends Component {
);
}
handleRulesClick = e => {
e.preventDefault();
if (this.state.showingRulesForTag === e.target.dataset.content) {
this.setState({showingRulesForTag: null});
} else {
this.setState({showingRulesForTag: e.target.dataset.content});
}
}
handleTagClick = e => {
if (e.target.className === 'articleform__tagsoptionrulesbutton') {
return;
}
const input = document.getElementById('tag-input');
input.focus();
this.insertTag(e.target.dataset.content);
};
@ -199,7 +221,6 @@ class Tags extends Component {
cursorIdx: e.target.selectionStart,
prevLen: this.textArea.value.length,
});
return this.search(query);
};
@ -324,7 +345,7 @@ class Tags extends Component {
return;
}
component.forceUpdate();
}, 100);
}, 250);
};
insertSpace(value, position) {
@ -335,6 +356,7 @@ class Tags extends Component {
if (query === '') {
return new Promise(resolve => {
setTimeout(() => {
'search query'
this.resetSearchResults();
resolve();
}, 5);
@ -343,7 +365,7 @@ class Tags extends Component {
return this.index
.search(query, {
hitsPerPage: 10,
hitsPerPage: 8,
attributesToHighlight: [],
filters: 'supported:true',
})

View file

@ -37,7 +37,7 @@ class Tag < ActsAsTaggableOn::Tag
before_save :mark_as_updated
algoliasearch per_environment: true do
attribute :name, :bg_color_hex, :text_color_hex, :hotness_score, :supported, :short_summary
attribute :name, :bg_color_hex, :text_color_hex, :hotness_score, :supported, :short_summary, :rules_html
attributesForFaceting [:supported]
customRanking ["desc(hotness_score)"]
searchableAttributes %w[name short_summary]

View file

@ -21,7 +21,7 @@
<input class="articleform__title articleform__titlepreview" type="text" value="<%= article.title %>" placeholder="Title" />
<div class="articleform__detailfields">
<div class="articleform__tagswrapper">
<textarea type="text" class="articleform__tags" placeholder="tags"><%= article.cached_tag_list %></textarea>
<textarea type="text" class="articleform__tags" placeholder="4 tags max, comma separated, no spaces or special characters"><%= article.cached_tag_list %></textarea>
</div>
<button class="articleform__detailsButton articleform__detailsButton--image"></button>
<button class="articleform__detailsButton articleform__detailsButton--moreconfig"></button>