Use new ColorPicker in tag edit form (#16607)

* Use new ColorPicker in tag edit form

* use classnames, add comment
This commit is contained in:
Suzanne Aitchison 2022-02-17 14:59:09 +00:00 committed by GitHub
parent c76909a428
commit 2fd5de8383
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 88 additions and 8 deletions

View file

@ -285,7 +285,6 @@ textarea.crayons-textfield.crayons-textfield--ghost {
&__input {
padding-left: var(--input-padding-left);
max-width: calc(100% - var(--input-padding-left));
}
&__swatch {

View file

@ -1,5 +1,6 @@
import { h, Fragment } from 'preact';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { useState, useLayoutEffect } from 'preact/hooks';
import { HexColorPicker, HexColorInput } from 'react-colorful';
import { initializeDropdown } from '@utilities/dropdownUtils';
@ -35,7 +36,10 @@ export const ColorPicker = ({
/>
<HexColorInput
id={id}
className="c-color-picker__input crayons-textfield"
className={classNames(
'c-color-picker__input crayons-textfield',
inputProps?.class,
)}
color={color}
onChange={setColor}
prefixed

View file

@ -1,4 +1,4 @@
import { h, Fragment } from 'preact';
import { h } from 'preact';
import ColorPickerDoc from './ColorPicker.mdx';
import { ColorPicker } from '@crayons';
@ -33,14 +33,14 @@ export default {
};
export const Default = (args) => (
<Fragment>
<div className="crayons-field">
{/* Disabled as the ColorPicker component attaches the correct ID to the input */}
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
<label for={args.id} className="crayons-field__label">
Choose a color
</label>
<ColorPicker {...args} />
</Fragment>
</div>
);
Default.args = {

View file

@ -0,0 +1,30 @@
import { h, render } from 'preact';
import { ColorPicker } from '@crayons';
// Find any color picker inputs on the page and replace them with the Preact enhanced component
const colorInputs = document.querySelectorAll('[data-color-picker]');
for (const input of colorInputs) {
const { labelText } = input.dataset;
const inputProps = {};
// Copy any specific attributes to the new input
const { attributes: inputAttributes } = input;
for (const attr of inputAttributes) {
inputProps[attr.name] = attr.value;
}
// The third `replaceNode` argument here makes sure that the new picker is rendered in the correct position within the parentElement
// However, Preact is unable to do a VDOM diff that allows a straight replacement of one input for the other, so we also need to remove it manually on line 29
render(
<ColorPicker
id={inputProps.id}
defaultValue={input.value}
inputProps={inputProps}
buttonLabelText={labelText}
/>,
input.parentElement,
input,
);
input.remove();
}

View file

@ -39,8 +39,8 @@
</div>
<div class="flex gap-4">
<div class="crayons-field flex-1">
<%= label_tag :bg_color_hex, I18n.t("views.tags.edit.form.bg_color_hex.label"), class: "crayons-field__label" %>
<%= color_field_tag "tag[bg_color_hex]", @tag.bg_color_hex.presence || "#000000", placeholder: "#000000", class: "crayons-color-selector crayons-color-selector--full" %>
<%= label_tag :tag_bg_color_hex, I18n.t("views.tags.edit.form.bg_color_hex.label"), class: "crayons-field__label" %>
<%= text_field_tag "tag[bg_color_hex]", @tag.bg_color_hex.presence || "#000000", placeholder: "#000000", class: "crayons-textfield", data: { color_picker: true, label_text: I18n.t("views.tags.edit.form.bg_color_hex.label") } %>
</div>
</div>
<div class="crayons-field">
@ -60,3 +60,4 @@
</div>
<% end %>
</main>
<%= javascript_packs_with_chunks_tag "colorPicker", defer: true %>

View file

@ -0,0 +1,46 @@
describe('Edit tag', () => {
beforeEach(() => {
cy.testSetup();
cy.fixture('users/adminUser.json').as('user');
cy.get('@user').then((user) => {
cy.loginAndVisit(user, '/t/tag1/edit');
});
});
it('enhances the color input with the rich ColorPicker', () => {
// Both a button and an input should be available
cy.findByRole('button', { name: 'Tag color' }).as('popoverButton');
cy.findByRole('textbox', { name: 'Tag color' }).as('input');
// Input should be pre-filled with the current bg_color_hex
cy.get('@input').should('have.value', '#672c99');
// Button should open and close a picker
cy.get('@popoverButton')
.should('have.attr', 'aria-expanded', 'false')
.click()
.should('have.attr', 'aria-expanded', 'true');
cy.findByLabelText('Color').should('be.visible');
cy.get('@popoverButton')
.click()
.should('have.attr', 'aria-expanded', 'false');
cy.findByLabelText('Color').should('not.be.visible');
});
it('changes the tag color', () => {
// Make sure the enhanced component is now visible
cy.findByRole('button', { name: 'Tag color' });
cy.findByRole('textbox', { name: 'Tag color' }).clear().type('ababab');
cy.findByRole('button', { name: 'Save' }).click();
// Wait for confirmation
cy.findByText(/Tag successfully updated!/);
cy.findByRole('textbox', { name: 'Tag color' }).should(
'have.value',
'#ababab',
);
});
});

View file

@ -591,7 +591,7 @@ seeder.create_if_none(Tag) do
tags.each do |tagname|
tag = Tag.create!(
name: tagname,
bg_color_hex: Faker::Color.hex_color,
bg_color_hex: "#672c99",
text_color_hex: Faker::Color.hex_color,
supported: true,
)