diff --git a/administrator/language/en-GB/joomla.ini b/administrator/language/en-GB/joomla.ini index b9e4e0c88e1dd..db5d787f4508d 100644 --- a/administrator/language/en-GB/joomla.ini +++ b/administrator/language/en-GB/joomla.ini @@ -220,8 +220,11 @@ JFIELD_COLOR_LABEL_SLIDER_HUE="Hue Slider" JFIELD_COLOR_LABEL_SLIDER_INPUT="Selected Colour Value" JFIELD_COLOR_LABEL_SLIDER_LIGHT="Light Slider" JFIELD_COLOR_LABEL_SLIDER_SATURATION="Saturation Slider" +; The following string is deprecated and will be removed with 7.0 JFIELD_COLOR_SELECT="Select a colour" +; The following string is deprecated and will be removed with 7.0 JFIELD_COLOR_TRANSPARENT="No colour, transparent" +; The following string is deprecated and will be removed with 7.0 JFIELD_COLOR_VALUE="Colour with hexadecimal value of" JFIELD_DISPLAY_READONLY_LABEL="Display When Read-Only" JFIELD_ENABLED_DESC="The enabled status of this item." diff --git a/api/language/en-GB/joomla.ini b/api/language/en-GB/joomla.ini index b1cf4418198cd..a29ec02964bbb 100644 --- a/api/language/en-GB/joomla.ini +++ b/api/language/en-GB/joomla.ini @@ -218,8 +218,11 @@ JFIELD_COLOR_LABEL_SLIDER_HUE="Hue Slider" JFIELD_COLOR_LABEL_SLIDER_INPUT="Selected Colour Value" JFIELD_COLOR_LABEL_SLIDER_LIGHT="Light Slider" JFIELD_COLOR_LABEL_SLIDER_SATURATION="Saturation Slider" +; The following string is deprecated and will be removed with 7.0 JFIELD_COLOR_SELECT="Select a colour" +; The following string is deprecated and will be removed with 7.0 JFIELD_COLOR_TRANSPARENT="No colour, transparent" +; The following string is deprecated and will be removed with 7.0 JFIELD_COLOR_VALUE="Colour with hexadecimal value of" JFIELD_DISPLAY_READONLY_LABEL="Display When Read-Only" JFIELD_ENABLED_DESC="The enabled status of this item." diff --git a/build/media_source/system/js/fields/joomla-field-simple-color.w-c.es6.js b/build/media_source/system/js/fields/joomla-field-simple-color.w-c.es6.js index 6ce1e67346ed6..347a3f696ef83 100644 --- a/build/media_source/system/js/fields/joomla-field-simple-color.w-c.es6.js +++ b/build/media_source/system/js/fields/joomla-field-simple-color.w-c.es6.js @@ -1,449 +1,192 @@ /** - * Based on: - * Very simple jQuery Color Picker - * Copyright (C) 2012 Tanguy Krotoff - * Licensed under the MIT license - * - * ADAPTED BY: Dimitris Grammatikogiannis - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * @copyright (C) 2024 Open Source Matters, Inc. + * @license GNU General Public License version 2 or later; see LICENSE.txt */ -((customElements) => { - const KEYCODE = { - TAB: 9, - ESC: 27, - }; - - const colorNames = { - aliceblue: '#f0f8ff', - antiquewhite: '#faebd7', - aqua: '#00ffff', - aquamarine: '#7fffd4', - azure: '#f0ffff', - beige: '#f5f5dc', - bisque: '#ffe4c4', - black: '#000000', - blanchedalmond: '#ffebcd', - blue: '#0000ff', - blueviolet: '#8a2be2', - brown: '#a52a2a', - burlywood: '#deb887', - cadetblue: '#5f9ea0', - chartreuse: '#7fff00', - chocolate: '#d2691e', - coral: '#ff7f50', - cornflowerblue: '#6495ed', - cornsilk: '#fff8dc', - crimson: '#dc143c', - cyan: '#00ffff', - darkblue: '#00008b', - darkcyan: '#008b8b', - darkgoldenrod: '#b8860b', - darkgray: '#a9a9a9', - darkgreen: '#006400', - darkgrey: '#a9a9a9', - darkkhaki: '#bdb76b', - darkmagenta: '#8b008b', - darkolivegreen: '#556b2f', - darkorange: '#ff8c00', - darkorchid: '#9932cc', - darkred: '#8b0000', - darksalmon: '#e9967a', - darkseagreen: '#8fbc8f', - darkslateblue: '#483d8b', - darkslategray: '#2f4f4f', - darkslategrey: '#2f4f4f', - darkturquoise: '#00ced1', - darkviolet: '#9400d3', - deeppink: '#ff1493', - deepskyblue: '#00bfff', - dimgray: '#696969', - dimgrey: '#696969', - dodgerblue: '#1e90ff', - firebrick: '#b22222', - floralwhite: '#fffaf0', - forestgreen: '#228b22', - fuchsia: '#ff00ff', - gainsboro: '#dcdcdc', - ghostwhite: '#f8f8ff', - gold: '#ffd700', - goldenrod: '#daa520', - gray: '#808080', - green: '#008000', - greenyellow: '#adff2f', - grey: '#808080', - honeydew: '#f0fff0', - hotpink: '#ff69b4', - indianred: '#cd5c5c', - indigo: '#4b0082', - ivory: '#fffff0', - khaki: '#f0e68c', - lavender: '#e6e6fa', - lavenderblush: '#fff0f5', - lawngreen: '#7cfc00', - lemonchiffon: '#fffacd', - lightblue: '#add8e6', - lightcoral: '#f08080', - lightcyan: '#e0ffff', - lightgoldenrodyellow: '#fafad2', - lightgray: '#d3d3d3', - lightgreen: '#90ee90', - lightgrey: '#d3d3d3', - lightpink: '#ffb6c1', - lightsalmon: '#ffa07a', - lightseagreen: '#20b2aa', - lightskyblue: '#87cefa', - lightslategray: '#778899', - lightslategrey: '#778899', - lightsteelblue: '#b0c4de', - lightyellow: '#ffffe0', - lime: '#00ff00', - limegreen: '#32cd32', - linen: '#faf0e6', - magenta: '#ff00ff', - maroon: '#800000', - mediumaquamarine: '#66cdaa', - mediumblue: '#0000cd', - mediumorchid: '#ba55d3', - mediumpurple: '#9370db', - mediumseagreen: '#3cb371', - mediumslateblue: '#7b68ee', - mediumspringgreen: '#00fa9a', - mediumturquoise: '#48d1cc', - mediumvioletred: '#c71585', - midnightblue: '#191970', - mintcream: '#f5fffa', - mistyrose: '#ffe4e1', - moccasin: '#ffe4b5', - navajowhite: '#ffdead', - navy: '#000080', - oldlace: '#fdf5e6', - olive: '#808000', - olivedrab: '#6b8e23', - orange: '#ffa500', - orangered: '#ff4500', - orchid: '#da70d6', - palegoldenrod: '#eee8aa', - palegreen: '#98fb98', - paleturquoise: '#afeeee', - palevioletred: '#db7093', - papayawhip: '#ffefd5', - peachpuff: '#ffdab9', - peru: '#cd853f', - pink: '#ffc0cb', - plum: '#dda0dd', - powderblue: '#b0e0e6', - purple: '#800080', - red: '#ff0000', - rosybrown: '#bc8f8f', - royalblue: '#4169e1', - saddlebrown: '#8b4513', - salmon: '#fa8072', - sandybrown: '#f4a460', - seagreen: '#2e8b57', - seashell: '#fff5ee', - sienna: '#a0522d', - silver: '#c0c0c0', - skyblue: '#87ceeb', - slateblue: '#6a5acd', - slategray: '#708090', - slategrey: '#708090', - snow: '#fffafa', - springgreen: '#00ff7f', - steelblue: '#4682b4', - tan: '#d2b48c', - teal: '#008080', - thistle: '#d8bfd8', - tomato: '#ff6347', - turquoise: '#40e0d0', - violet: '#ee82ee', - wheat: '#f5deb3', - white: '#ffffff', - whitesmoke: '#f5f5f5', - yellow: '#ffff00', - yellowgreen: '#9acd32', - }; - - class JoomlaFieldSimpleColor extends HTMLElement { - constructor() { - super(); - - // Define some variables - this.select = ''; - this.options = []; - this.icon = ''; - this.panel = ''; - this.buttons = []; - this.focusableElements = null; - this.focusableSelectors = [ - 'a[href]', - 'area[href]', - 'input:not([disabled])', - 'select:not([disabled])', - 'textarea:not([disabled])', - 'button:not([disabled])', - 'iframe', - 'object', - 'embed', - '[contenteditable]', - '[tabindex]:not([tabindex^="-"])']; - } - - connectedCallback() { - this.select = this.querySelector('select'); - - if (!this.select) { - throw new Error('Simple color field requires a select element'); - } - - this.options = this.select.querySelectorAll('option'); - this.select.classList.add('hidden'); - - // Build the pop up - this.options.forEach((option) => { - let color = option.value; - let clss = 'swatch'; +function getText(translatableText, fallbackText) { + const translatedText = typeof Joomla?.Text?._ === 'function' ? Joomla.Text._(translatableText) : ''; + + return translatedText !== translatableText ? translatedText : fallbackText; +} + +const texts = { + none: ['JNONE', 'None'], + close: ['JCLOSE', 'Close'], +}; + +const checker = 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3ggRDQENU0dyawAAACZJREFUGNNjPHXqDAMSMDY2ROYyMeAFNJVm/Pv3LzL/7Nnzg8VpAKebCGpIIxHBAAAAAElFTkSuQmCC")'; +const template = Object.assign(document.createElement('template'), { + innerHTML: ` + +
+ + +
`, +}); + +const sheet = new CSSStyleSheet(); +sheet.replaceSync('[part=close] svg { padding-block-start: .2rem; }'); + +// Expand any short code +function getColorName(value) { + let newValue = value; + if (newValue === 'none') return getText(texts.none[0], texts.none[1]); + if (value.startsWith('#') && value.length === 4) { + const tmpValue = value.split(''); + newValue = tmpValue[0] + tmpValue[1] + tmpValue[1] + tmpValue[2] + tmpValue[2] + tmpValue[3] + tmpValue[3]; + } - if (color === 'none') { - clss += ' nocolor'; - color = 'transparent'; - } - if (option.selected) { - clss += ' active'; - } + return newValue; +} - const el = document.createElement('button'); - el.setAttribute('class', clss); - el.style.backgroundColor = color; - el.setAttribute('type', 'button'); - const a11yColor = color === 'transparent' ? this.textTransp : this.getColorName(color); - el.innerHTML = Joomla.sanitizeHtml(`${a11yColor}`); +class JoomlaFieldSimpleColor extends HTMLElement { + static formAssociated = true; - this.buttons.push(el); - }); + get value() { return this.getAttribute('value'); } - // Add a close button - const close = document.createElement('button'); - close.setAttribute('class', 'btn-close'); - close.setAttribute('type', 'button'); - close.setAttribute('aria-label', this.textClose); + set value(value) { this.setAttribute('value', value); } - this.buttons.push(close); + constructor() { + super(); - let color = this.select.value; - let clss = ''; + this.attachShadow({ mode: 'open' }); + this.shadowRoot.appendChild(template.content.cloneNode(true)); + this.shadowRoot.adoptedStyleSheets = [sheet]; - if (color === 'none') { - clss += ' nocolor'; - color = 'transparent'; - } + this.internals = null; + this.show = this.show.bind(this); + this.hide = this.hide.bind(this); + this.keys = this.keys.bind(this); + this.colorSelect = this.colorSelect.bind(this); + this.getActiveElement = this.getActiveElement.bind(this); + this.onDocumentClick = this.onDocumentClick.bind(this); - this.icon = document.createElement('button'); - - if (clss) { - this.icon.setAttribute('class', clss); - } + // Create a dummy div for the validation of the colors + this.div = document.createElement('div'); + } - const uniqueId = `simple-color-${Math.random().toString(36).substring(2, 12)}`; - this.icon.setAttribute('type', 'button'); - this.icon.setAttribute('tabindex', '0'); - this.icon.style.backgroundColor = color; - this.icon.innerHTML = Joomla.sanitizeHtml(`${this.textSelect}`); - this.icon.id = uniqueId; - this.select.insertAdjacentElement('beforebegin', this.icon); - this.icon.addEventListener('click', this.show.bind(this)); - - this.panel = document.createElement('div'); - this.panel.classList.add('simplecolors-panel'); - this.panel.setAttribute('aria-labelledby', uniqueId); - this.hide = this.hide.bind(this); - this.colorSelect = this.colorSelect.bind(this); - - this.buttons.forEach((el) => { - if (el.classList.contains('btn-close')) { - el.addEventListener('click', this.hide); - } else { - el.addEventListener('click', this.colorSelect); - } - - this.panel.insertAdjacentElement('beforeend', el); - }); - - this.appendChild(this.panel); - - this.focusableElements = [].slice - .call(this.panel.querySelectorAll(this.focusableSelectors.join())); - - this.keys = this.keys.bind(this); - this.hide = this.hide.bind(this); - this.mousedown = this.mousedown.bind(this); + connectedCallback() { + try { + this.internals = this.attachInternals(); + this.form = this.internals.form; + } catch (error) { + throw new Error('Unsupported browser'); } - static get observedAttributes() { - return ['text-select', 'text-color', 'text-close', 'text-transparent']; + if (this.internals) { + this.querySelector('input[type=hidden]')?.remove(); } - get textSelect() { return this.getAttribute('text-select'); } - - get textColor() { return this.getAttribute('text-color'); } - - get textClose() { return this.getAttribute('text-close'); } - - get textTransp() { return this.getAttribute('text-transparent'); } + if (this.internals && this.internals.labels.length) { + this.internals.labels.forEach((label) => label.addEventListener('click', this.show)); + } - // Show the panel - show() { - document.addEventListener('mousedown', this.hide); - this.addEventListener('keydown', this.keys); - this.panel.addEventListener('mousedown', this.mousedown); - this.panel.setAttribute('data-open', ''); + this.button = this.shadowRoot.querySelector('[part=opener]'); + this.panel = this.shadowRoot.querySelector('[part=panel]'); + this.closeButton = this.panel.querySelector('[part=close]'); + this.panel.style.display = 'none'; + this.button.style.background = this.value === 'none' ? checker : this.value; - const focused = this.panel.querySelector('button'); + this.button.addEventListener('click', this.show); + this.internals.setFormValue(this.value); + } - if (focused) { - focused.focus(); + // Show the panel + show() { + let focused; + this.slotted = this.shadowRoot.querySelector('slot[name=colors]'); + this.addEventListener('keydown', this.keys); + this.closeButton.addEventListener('click', this.hide); + this.closeButton.setAttribute('aria-label', getText(texts.close[0], texts.close[1])); + this.slotted.assignedElements().forEach((element) => { + if (!this.validateColor(element.value)) { + element.remove(); } - } - - // Hide panel - hide() { - document.removeEventListener('mousedown', this.hide, false); - this.removeEventListener('keydown', this.keys); - if (this.panel.hasAttribute('data-open')) { - this.panel.removeAttribute('data-open'); + element.style.background = element.value === 'none' ? checker : element.value; + element.setAttribute('aria-label', getColorName(element.value)); + element.addEventListener('click', this.colorSelect); + if (element.getAttribute('aria-pressed') === 'true') { + focused = element; } - - this.icon.focus(); + }); + this.button.style.display = 'none'; + this.panel.style.display = 'flex'; + this.button.setAttribute('aria-expanded', 'true'); + + if (focused) { + focused.focus(); + } else { + this.closeButton.focus(); } + document.addEventListener('click', this.onDocumentClick); + } - colorSelect(e) { - let color = ''; - let bgcolor = ''; - let clss = ''; - - if (e.target.classList.contains('nocolor')) { - color = 'none'; - bgcolor = 'transparent'; - clss = 'nocolor'; - } else { - color = this.rgb2hex(e.target.style.backgroundColor); - bgcolor = color; - } - - // Reset the active class - this.buttons.forEach((el) => { - if (el.classList.contains('active')) { - el.classList.remove('active'); - } - }); - - // Add the active class to the selected button - e.target.classList.add('active'); - - this.icon.classList.remove('nocolor'); - this.icon.setAttribute('class', clss); - this.icon.style.backgroundColor = bgcolor; + // Hide the panel + hide() { + this.removeEventListener('keydown', this.keys); + document.removeEventListener('click', this.onDocumentClick); + this.button.setAttribute('aria-expanded', 'false'); + this.panel.style.display = 'none'; + this.button.style.display = 'block'; - // trigger change event both on the select and on the custom element - this.select.dispatchEvent(new Event('change')); - this.dispatchEvent(new CustomEvent('change', { - detail: { value: color }, - bubbles: true, - })); + this.slotted.assignedElements().forEach((element) => element.removeEventListener('click', this.colorSelect)); + this.button.focus(); + } - // Hide the panel + onDocumentClick(e) { + if ([...this.internals.labels].includes(e.target)) return; + if ((e.target.closest('joomla-field-simple-color') !== this) && this.panel.style.display === 'flex') { this.hide(); - - // Change select value - this.options.forEach((el) => { - if (el.selected) { - el.removeAttribute('selected'); - } - - if (el.value === bgcolor) { - el.setAttribute('selected', ''); - } - }); } + } - keys(e) { - if (e.keyCode === KEYCODE.ESC) { - this.hide(); - } - - if (e.keyCode === KEYCODE.TAB) { - // Get the index of the current active element - const focusedIndex = this.focusableElements.indexOf(document.activeElement); - - // If first element is focused and shiftkey is in use, focus last item within modal - if (e.shiftKey && (focusedIndex === 0 || focusedIndex === -1)) { - this.focusableElements[this.focusableElements.length - 1].focus(); - e.preventDefault(); - } - // If last element is focused and shiftkey is not in use, focus first item within modal - if (!e.shiftKey && focusedIndex === this.focusableElements.length - 1) { - this.focusableElements[0].focus(); - e.preventDefault(); - } - } - } + colorSelect(event) { + const { currentTarget } = event; + this.slotted.assignedElements().forEach((element) => element.setAttribute('aria-pressed', element !== currentTarget ? 'false' : 'true')); + this.button.style.background = currentTarget.value === 'none' ? checker : currentTarget.value; + this.hide(); + this.internals.setFormValue(currentTarget.value); + this.value = currentTarget.value; + this.dispatchEvent(new Event('change')); + } - // Prevents the mousedown event from "eating" the click event. - mousedown(e) { - e.stopPropagation(); - e.preventDefault(); + keys(e) { + if (e.code === 'Escape') { + this.hide(); } - getColorName(value) { - // Expand any short code - let newValue = value; - if (value.length === 4) { - const tmpValue = value.split(''); - newValue = tmpValue[0] + tmpValue[1] + tmpValue[1] + tmpValue[2] - + tmpValue[2] + tmpValue[3] + tmpValue[3]; + // Trap the focus + if (e.code === 'Tab') { + const focusableElements = [...this.slotted.assignedElements(), this.closeButton]; + const focusedIndex = focusableElements.indexOf(this.getActiveElement()); + + if (e.shiftKey && (focusedIndex === 0)) { + focusableElements[focusableElements.length - 1].focus(); + e.preventDefault(); + } else if (!e.shiftKey && focusedIndex === focusableElements.length - 1) { + focusableElements[0].focus(); + e.preventDefault(); } + } + } - for (const color in colorNames) { - if (colorNames.hasOwnProperty(color) && newValue.toLowerCase() === colorNames[color]) { - return color; - } - } + getActiveElement(root = document) { + const activeEl = root.activeElement; - return `${this.textColor} ${value.replace('#', '').split('').join(', ')}`; + if (!activeEl) { + return null; } - /** - * Converts a RGB color to its hexadecimal value. - * See http://stackoverflow.com/questions/1740700/get-hex-value-rather-than-rgb-value-using-$ - */ - rgb2hex(rgb) { - const hex = (x) => (`0${parseInt(x, 10).toString(16)}`).slice(-2); - const matches = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); + return activeEl.shadowRoot ? this.getActiveElement(activeEl.shadowRoot) : activeEl; + } - return `#${hex(matches[1])}${hex(matches[2])}${hex(matches[3])}`; - } + validateColor(color) { + this.div.style.color = color; + return this.div.style.color !== ''; } +} - customElements.define('joomla-field-simple-color', JoomlaFieldSimpleColor); -})(customElements); +customElements.define('joomla-field-simple-color', JoomlaFieldSimpleColor); diff --git a/build/media_source/system/scss/fields/joomla-field-simple-color.scss b/build/media_source/system/scss/fields/joomla-field-simple-color.scss index d7c9f3691eb35..21ba29cc28c97 100644 --- a/build/media_source/system/scss/fields/joomla-field-simple-color.scss +++ b/build/media_source/system/scss/fields/joomla-field-simple-color.scss @@ -1,69 +1,52 @@ joomla-field-simple-color { display: block; - .hidden { - display: none; + button { + width: 2rem; + height: 2rem; + appearance: none; + background: none; + border: var(--border-width, 1px) solid var(--input-border-color, #ccc); + border-radius: var(--border-radius, .25rem); + margin-inline: .5rem; + margin-block-end: .24rem; } - .visually-hidden { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0,0,0,0); + &::part(close) { + appearance: none; + background: none; border: 0; + margin-inline: .5rem; + margin-block-end: .2rem; } - button { - width: 20px; - height: 20px; + &::part(opener) { + width: 2rem; + height: 2rem; overflow: hidden; vertical-align: middle; - background: none; - border: solid 1px #ccc; - border-radius: 3px; + border: var(--border-width, 1px) solid var(--input-border-color, #ccc); + border-radius: var(--border-radius, .25rem); appearance: none; + margin-block: .7rem; } - .btn-close { - width: auto; - padding: 0 6px; - margin-top: -4px; - font-size: 1rem; - line-height: 1.5; - text-align: center; - vertical-align: middle; - } - - .nocolor { - background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3ggRDQENU0dyawAAACZJREFUGNNjPHXqDAMSMDY2ROYyMeAFNJVm/Pv3LzL/7Nnzg8VpAKebCGpIIxHBAAAAAElFTkSuQmCC") !important; - } - .simplecolors-panel .swatch { - margin: 0 4px 4px 0; + &::part(opener):focus, + &::part(opener):hover, + button[aria-pressed=true] { + border: 2px solid var(--template-link-color, rgba(82 168 236 / .8)); + box-shadow: 0 0 0 .25rem #2a69b740; } - .swatch:hover, - .swatch.active { - border-color: rgba(82, 168, 236, .8); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82, 168, 236, .6); - } - - .simplecolors-panel[data-open=""] { - display: block; - } - .simplecolors-panel { - position: absolute; - z-index: 12; - display: none; - float: left; - padding: 6px 2px 2px 6px; - margin: 1px 0 0; - background-color: #fff; + &::part(panel) { + flex-direction: row; + flex-wrap: wrap; + float: inline-start; + padding: .64rem 0 .4rem; + background-color: var(--body-bg, #fff); background-clip: padding-box; - border: 1px solid #ddd; - border-radius: 5px; - box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + border: var(--border-width, 1px) solid var(--input-border-color, #ccc); + border-radius: var(--border-radius, .25rem); + box-shadow: 0 5px 10px rgba(0 0 0 / .2); } } diff --git a/language/en-GB/joomla.ini b/language/en-GB/joomla.ini index e67786a11e636..85d8332a4a0fe 100644 --- a/language/en-GB/joomla.ini +++ b/language/en-GB/joomla.ini @@ -182,8 +182,11 @@ JFIELD_ALIAS_LABEL="Alias" JFIELD_ALIAS_PLACEHOLDER="Auto-generate from title" JFIELD_ALT_PAGE_TITLE_LABEL="Alternative Page Title" JFIELD_CATEGORY_DESC="Category" +; The following string is deprecated and will be removed with 7.0 JFIELD_COLOR_SELECT="Select a colour" +; The following string is deprecated and will be removed with 7.0 JFIELD_COLOR_TRANSPARENT="No colour, transparent" +; The following string is deprecated and will be removed with 7.0 JFIELD_COLOR_VALUE="Colour with hexadecimal value of" JFIELD_FIELDS_CATEGORY_DESC="Select the category that this field is assigned to." JFIELD_LANGUAGE_DESC="Assign a language to this article." diff --git a/layouts/joomla/form/field/color/simple.php b/layouts/joomla/form/field/color/simple.php index 2ed3e632ead10..73e443135eb3e 100644 --- a/layouts/joomla/form/field/color/simple.php +++ b/layouts/joomla/form/field/color/simple.php @@ -12,6 +12,7 @@ use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; +use Joomla\Utilities\ArrayHelper; extract($displayData); @@ -51,22 +52,34 @@ * @var string $dataAttribute Miscellaneous data attributes preprocessed for HTML output * @var array $dataAttributes Miscellaneous data attribute for eg, data-*. */ - -$class = ' class="form-select ' . trim($class) . '"'; -$disabled = $disabled ? ' disabled' : ''; -$readonly = $readonly ? ' readonly' : ''; - Factory::getDocument()->getWebAssetManager() ->useStyle('webcomponent.field-simple-color') ->useScript('webcomponent.field-simple-color'); +Text::script('JCLOSE'); +Text::script('JNONE'); + +$slots = []; +$attr = [ + 'name' => $name, + 'id' => $id, + 'class' => trim($class), + 'value' => trim($color), +]; + +if ($disabled) { + $attr['disabled'] = ''; +} + +if ($readonly) { + $attr['readonly'] = ''; +} + +foreach ($colors as $val) { + $slots[] = ''; +} ?> - - +> + +