As discussed previously with @dgrammatiko, we need to remove jQuery minicolors (less SCSS to compile, and one less jQuery dependency) and replace it with something fresh, reliable and play nice with our repeatable fields via custom elements.
The new <color picker>
you are about to see.
<color-picker id="myColorPicker" value="rgb(20,120,150)" format="rgb"></color-picker>
...becomes something like this:
Codepen link right here. Updated with every change.
rgba()
to rgb()
or hsla()
to hsl()
when color alpha is 1, or transparent
to rgba(0,0,0,0)
and even color name like red
to rgb(255,0,0)
;joomla.colorpicker.change
event on every control change or every type inside inputs, but take effect after a 500ms delay, when TinyColor validates the input color and triggers the change;scroll
, mousemove
, keyup
, etc), no memory leaks are allowed.Event.prototype.path
is no longer required, the tabindex
attribute solved the original problem, however I had to change all the way event listeners are managed to be able to add/remove them easily and avoid memory leaks;color-dropdown
smaller on mobile, it's too hard to handle;observeInputs
method, I don't really know what's that all about; perhaps it's a custom-elements feature or perhaps what was originally intended was already implemented by me by any chance?<color-picker>
in Joomla, this section will be updated with changes and news, stay tuned.Test, play and provide feedback.
Cheers!
Labels |
Added:
?
|
@dgrammatiko if we don't implement some crazy stuff like hex8
or percentage rgba, we can actually include some utilities from tinycolor into our color-picker: we only need parse and 3-4 conversion functions + saturation, which should be, IDK, 250 bytes of code?
Please test on mobile.
I agree about the switch.
Based on the codepen the accessibility is better than the current option but should really be tested by the accessibility team
@brianteeman feel free to tag them in.
@brianteeman I've changed the mobile view of the color picker, please take a minute to test the demo. Also check the updated initial note for changes.
As for accessibility, it will all come together at the point where we have it implemented as is, a proof of concept design into PHP of Joomla 4, then we can speak about accessibility and probably ARIA.
@dgrammatiko I've started working on implementation in this repo. Couple of quick questions:
build/media_source/vendor/tinycolor
but then I realized that build/media_source/system/js/fields/tinycolor
is probably better;.ts
sources, or should we use the .ts
?Let me know.
Stupid question maybe, but what speaks against just using <input type="color">
? Looks to be good supported by browsers.
Or is there an important feature missing in the native element?
Stupid question maybe, but what speaks against just using
It doesn't support all 3 modes that Joomla has right now
build/media_source/system/js/fields/tinycolor.w-c.es6.js
mind the .w-c.es6.js
it's important for the tools!!It doesn't support all 3 modes that Joomla has right now
Chrome does support RGD, HEX and HSL. It even has a color picker to pick any color on your screen. Looks quite nice.
But yeah, haven't tested with other browsers. They may be different.
@dgrammatiko the <input type="color">
supports HSL, RGB, HEX.
@dgrammatiko the supports HSL, RGB, HEX.
Chrome does support RGD, HEX and HSL.
I meant the alpha part, too early here also according to MDN the returned value is ALWAYS hex: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/color
<input> elements of type color provide a user interface element that lets a user specify a color, either by using a visual color picker interface or by entering the color into a text field in #rrggbb hexadecimal format
I did a pr a long time ago to use html5 color but it was rejected because it doesnt support alpha/transparency
@Bakual my problem is the accuracy, aside from alpha control missing. The native color input is really small making it hard to really do some accurate color picking. With this component you can do it much easier, even on mobile devices.
Another limitation is the possibility to customize, it's just not possible to customize the color popup.
Plus stuff like tinycolor can really prove to be handy in front-end design!
@dgrammatiko I need a build script or at least a suggestion for tinycolor to concatenate all code into a single file.
Right, meanwhile I will start doing some PHP.
@Bakual you got me thinking of a combination of input color and an input type range combined into a custom element, but it still needs some work and utilities. It should work but won't give us much in terms of flexibility, accuracy and customization. It would be a hustle free with events though.
@dgrammatiko I've prepared the compiled files I need to work with, I'm now looking at the PHP side of libraries\src\Form\Field\ColorField.php
and the $layout = 'joomla.form.field.color'
is nowhere to be found.
Which files do we need to change in the PHP side? I'm thinking maybe creating a new layout for the existing ColorField.php
form field for now. Just to get to working.
@thednp the layouts are here https://github.com/joomla/joomla-cms/tree/4.0-dev/layouts/joomla/form/field/color
You're looking for https://github.com/joomla/joomla-cms/blob/4.0-dev/layouts/joomla/form/field/color/advanced.php in this case
Another quick one: (can I) / (should I) use parts of the color-picker template shadowroot in the PHP layout?
Another quick one: (can I) / (should I) use parts of the color-picker template shadowroot in the PHP layout?
What do you mean? Do you want to pretender the label and input? You could but you have to use named slots <slot name="lablel"></slot>
check https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot
If you're referring to css parts please don't, use css variables or https://developer.mozilla.org/en-US/docs/Web/CSS/::part
I will probably use a slot, I want to give the main input the value and its ID. Other suggestions? I can just let it go the way it is, our script will transfer the ID and value to the input already.
@dgrammatiko after some time tinkering to setup the wasm, I got the color picker working on my end, now I need to know what's the best to do in order to transfer the attributes to the <input>
in the shadowRoot.
I can cleanup the JS code, some labels are unnecessary within Joomla, and transfer all attributes to the main input, all via JS, with or without <slot>
which is something I don't quite understand. Is that something I can use to transfer data into the shadowRoot?
Try this code to expose the data to the parent form:
hiddenInput() {
if (!this.hiddenInput) {
this.hiddenInput = document.createElement('input');
this.hiddenInput.type = 'hidden';
this.hiddenInput.name = this.name;
this.hiddenInput.value = this.value;
this.form.appendChild(this.hiddenInput);
} else {
this.hiddenInput.name = this.name;
this.hiddenInput.value = this.value;
}
}
connectedCallback() {
// existing code, after render
this.form = this.closest('form');
if (this.form) {
this.form.addEventListener('submit', this.hiddenInput)
}
}
disconnectedCallback() {
if (this.form) {
this.form.removeEventListener('submit', this.hiddenInput)
}
}
He, it doesn't work because bind. However look what solution I found:
<color-picker<?php echo $format; ?>>
<input type="hidden" name="<?php echo $name; ?>" id="<?php echo $id; ?>" value="<?php echo $this->escape($color); ?>"
<?php
echo $hint,
$class,
$position,
$control,
$readonly,
$disabled,
$required,
$onchange,
$autocomplete,
$autofocus,
$format,
$keywords,
$direction,
$validate,
$dataAttribute;
?>/>
</color-picker>
Then I can just call
updateInputs() {
this.querySelector('input[type="hidden"]').value = newValue;
}
On form submit I get no error and the proper value coming from the db. Sweet.
I will now cleanup the JS code and commit to my git repo for review. There's a lot of unnecessary code now.
@dgrammatiko is it possible to set a single <template id="joomla-color-picker">
per document instance? We need a way to set all those labels for lightness, saturation and such.
Should be doable (maning I haven't tested it) with something like
$template = '<template id="joomla-color-picker">...</template>';
if (!parent::$cache['some-unique-key-like-joomla-form-filed-template']) {
echo $template;
parent::$cache['some-unique-key-like-joomla-form-filed-template'] = true;
}
// The rest of the layout output
@dgrammatiko what about creating a script that does that, with data fed via PHP? That method looks weird to me.
Update: disregard that, I'm lookin at core fields that use custom elements.
Update: disregard that, I'm lookin at core fields that use custom elements.
There's a fundamental difference here, this component is using Shadow Dom, the rest of the fields are all just custom elements (no shadow dom)
Correct, however, there's no need to create a unique template for each Document instance, nobody (in the DOM tree) complain, I'm just gonna populate the shadowRoot with a template defined inside the <color-picker>
element.
@dgrammatiko sorry to bother again. Can Joomla form read input fields from inside shadowRoot?
No, also not a Joomla problem it's a limitation of web components used with posting forms (the ancient way), read my comment here: #32494 (comment) I already gave you the answer there
tbh I can't follow without seeing the actual code
I'm going to add a hidden input as the one that Joomla actually checks, and I'm going to update it with every color-picker change.
Im going to use template for the color picker form [hue, saturation, red] etc labels and other probably ARIA stuff.
When I'm done I'm gonna let you know.
@dgrammatiko I'm looking at the language files and I see JFIELD_COLOR_VALUE
in 3 separate files
administrator/language/en-GB/joomla.ini
;language/en-GB/joomla.ini
;api/language/en-GB/joomla.ini
.Which one is it or all of them? My guess: the first two.
All of them ,althought I have no clue why the api
has the same strings as the others, probably you can skip this one
For now all three of those should ideally be in sync with each other
Roger that.
@thednp one thing as I was reading the code agian, the format could be any of
['rgb', 'hsl', 'hex', 'rgba', 'hsla', 'hexa']
meaning the alpha is dictated by the dev, not up to the user. Also we're missing thenone
andtransparent
values for the non alpha modes
Most of that is not correct.
rgba
, hsla
formats, in PHP layout I've added stuff like $format = $format === 'rgba' ? 'rgb' : $format
; also, when the extension developer sets format to something else than rgb
, hex
, hsl
, it will default to hex
;transparent
, red
) on its own to the specified format, except I don't know what will do when format is hex
and user sets transparent
, it will probably do #000
;<color-picker>
needs a valid color object from TinyColor to update its inputs and render the canvas elements.The extension developer will set navyblue
as default value for instance and TinyColor will do its thing on render.
I can confirm: when format is set to hex
the user input or default value set by extension developer of transparent
become #000
.
Basically you will never be able to add an invalid color value to the db.
once AGAIN: none
and transparent
are valid CSS colour values. If the current code disrepects that it's not an excuse to continue in the wrong path. Anyways my 2c
In my opinion that's not a problem. Here 2 strong args:
type="Color"
field with control="advanced"
and showon
linked to another option that sets none
OR custom
(here the color picker kicks in)$primary: none;
, it will mess up all possible calculations for its components; it will probably never compile something like darken('none',15%)
.Chill out.
Devs can set a color-picker field with showon linked to another option that sets none OR custom (here the color picker kicks in)
Telling devs to do workarounds is not an argument
In Bootstrap...
I'm not relegious about Bootstrap or any other CSS framework, all of them have there own caveats. The thing here is that you point out what SASS/Bootstrap is doing but I'm raising an issue about the accepable values according to CSS working draft: https://drafts.csswg.org/css-color-4/#resolving-other-colors (and actually I got the none
wrong, it's not a valid value). To recap: amongst the acceptable values are inherit
, transparent
and currentcolor
and saying that devs need to do hacks to get these values seems to me weird and not so helpful. Also code wise all you have to do is append 3 buttons that set directly the value to these strings and have a simple conditional when getting the value from the attribute (maybe have a second this.finalValue indipendent of the tinycolor and for these cases initialise the tinycolor with #000 so nothing breaks.)
Finally opinios are fine but at the end of the day as web devs we're coding against the platform standards so your or my opinion is kinda irrelevant, it's what the specs dictate...
@dgrammatiko you're point is taken. This is what a color picker is supposed to do: get you a color from the entire rainbow. You want me to change TinyColor or adapt our color-picker to work with inherit
, transparent
and currentColor
? I'm fine with either at this point.
I don't see the original advanced
layout to say anything about these. Does the $keywords
have anything to do with this?
BTW the none
value is valid for props like background
(or background-image
) or display
, not color
or background-color
.
I think you don't get it this time around. I'm not trying to find excuses, I'm pointing out the facts of a color picker. Nothing more or less. I also don't back down from a little more work.
In my templates if I set a color picker, I explicitly want my user to set a color because I want the compilers happy and layouts and color contrasts as I designed them to.
@dgrammatiko I can't create pull request to 4.0-dev
Can’t automatically merge. Don’t worry, you can still create the pull request.
... disregard that, solved partly.
Status | New | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2021-02-26 14:58:01 |
Closed_By | ⇒ | Quy |
I would say ship it as is but I think I need to ask for a switch of the tinycolor to this package: https://github.com/scttcper/tinycolor (reason is the one I used back when I was playing with this was/is ES5 but we'll be better if we use an ES Module)
Great job, let me know if you need any help bridging the PHP parts