Skip to content

Commit

Permalink
Merge pull request #4611 from nextcloud-libraries/feat/color-picker--…
Browse files Browse the repository at this point in the history
…labeled-colors

feat(NcColorPicker): palette now can have color names
  • Loading branch information
susnux authored Nov 17, 2023
2 parents 2f5bcb3 + c7c62e0 commit 06c251a
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 36 deletions.
12 changes: 12 additions & 0 deletions l10n/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ msgstr ""
msgid "{tag} (restricted)"
msgstr ""

msgid "A color with a HEX value {hex}"
msgstr ""

msgid "a few seconds ago"
msgstr ""

Expand Down Expand Up @@ -119,6 +122,9 @@ msgstr ""
msgid "Go back to the list"
msgstr ""

msgid "Gold"
msgstr ""

msgid "Hide password"
msgstr ""

Expand All @@ -137,6 +143,9 @@ msgstr ""
msgid "Next"
msgstr ""

msgid "Nextcloud blue"
msgstr ""

msgid "No emoji found"
msgstr ""

Expand Down Expand Up @@ -209,6 +218,9 @@ msgstr ""
msgid "Provider icon"
msgstr ""

msgid "Purple"
msgstr ""

msgid "Raw link {options}"
msgstr ""

Expand Down
76 changes: 57 additions & 19 deletions src/components/NcColorPicker/NcColorPicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
- @copyright Copyright (c) 2019 Marco Ambrosini <marcoambrosini@icloud.com>
-
- @author Marco Ambrosini <marcoambrosini@icloud.com>
- @author Grigorii K. Shartsev <me@shgk.me>
-
- @license GNU AGPL version 3 or any later version
-
Expand Down Expand Up @@ -165,26 +166,29 @@ export default {
</template>
<div class="color-picker"
:class="{ 'color-picker--advanced-fields': advanced && advancedFields }">
<transition name="slide" mode="out-in">
<Transition name="slide" mode="out-in">
<div v-if="!advanced" class="color-picker__simple">
<button v-for="(color, index) in palette"
<label v-for="({ color, name }, index) in normalizedPalette"
:key="index"
:style="{'background-color': color }"
:style="{ backgroundColor: color }"
class="color-picker__simple-color-circle"
:class="{ 'color-picker__simple-color-circle--active' : color === currentColor }"
type="button"
@click="pickColor(color)">
<Check v-if="color === currentColor"
:size="20" />
</button>
:aria-label="name">
<Check v-if="color === currentColor" :size="20" />
<input type="radio"
class="hidden-visually"
:name="`color-picker-${uid}`"
:checked="color === currentColor"
@click="pickColor(color)">
</label>
</div>
<Chrome v-if="advanced"
v-model="currentColor"
class="color-picker__advanced"
:disable-alpha="true"
:disable-fields="!advancedFields"
@input="pickColor" />
</transition>
</Transition>
<div class="color-picker__navigation">
<NcButton v-if="advanced"
type="tertiary"
Expand Down Expand Up @@ -217,18 +221,30 @@ import NcButton from '../NcButton/index.js'
import NcPopover from '../NcPopover/index.js'
import { t } from '../../l10n.js'
import GenColors from '../../utils/GenColors.js'
import GenRandomId from '../../utils/GenRandomId.js'
import ArrowLeft from 'vue-material-design-icons/ArrowLeft.vue'
import Check from 'vue-material-design-icons/Check.vue'
import DotsHorizontal from 'vue-material-design-icons/DotsHorizontal.vue'
import { Chrome } from 'vue-color'
const rgbToHex = function(color) {
const hex = color.toString(16)
return hex.length === 1 ? '0' + hex : hex
/**
* Convert RGB object to a HEX string color
*
* @param {object} color - The color to convert
* @param {string} [color.r] - Red value
* @param {string} [color.g] - Green value
* @param {string} [color.b] - Blue value
* @return {string} The hex value
*/
export function rgbToHex({ r, g, b }) {
const toHex = (number) => number.toString(16).padStart(2, '0')
return `#${toHex(r)}${toHex(g)}${toHex(b)}`
}
const HEX_REGEX = /^#([a-f0-9]{3}|[a-f0-9]{6})$/i
export default {
name: 'NcColorPicker',
Expand Down Expand Up @@ -259,16 +275,20 @@ export default {
},
/**
* Provide a custom array of hexadecimal colors to show
* Provide a custom array of colors to show.
* Can be either an array of string hexadecimal colors,
* or an array of object with a `color` property with hexadecimal color string,
* and a `name` property for accessibility.
*
* @type {string[] | {color: string, name: string}[]}
*/
palette: {
type: Array,
default: () => GenColors(4).map(color => {
return '#' + rgbToHex(color.r) + rgbToHex(color.g) + rgbToHex(color.b)
}),
validator(palette) {
return palette.every(color => /^#([a-f0-9]{3}|[a-f0-9]{6})$/i.test(color))
},
default: () => GenColors(4).map(item => ({ color: rgbToHex(item), name: item.name })),
validator: (palette) => palette.every(item =>
(typeof item === 'string' && HEX_REGEX.test(item))
|| (typeof item === 'object' && item.color && HEX_REGEX.test(item.color)),
),
},
},
Expand All @@ -289,6 +309,21 @@ export default {
}
},
computed: {
normalizedPalette() {
return this.palette.map((item) => ({
color: typeof item === 'object' ? item.color : item,
name: typeof item === 'object' && item.name
? item.name
: t('A color with a HEX value {hex}', { hex: item.color }),
}))
},
uid() {
return GenRandomId()
},
},
watch: {
value(color) {
this.currentColor = color
Expand Down Expand Up @@ -389,6 +424,9 @@ export default {
border: 1px solid rgba(0, 0, 0, 0.25);
border-radius: 50%;
font-size: 16px;
&:focus-within {
outline: 2px solid var(--color-main-text);
}
&:hover {
opacity: .6;
}
Expand Down
45 changes: 28 additions & 17 deletions src/utils/GenColors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
* @author Grigorii K. Shartsev <me@shgk.me>
*
* @license AGPL-3.0-or-later
*
Expand All @@ -24,15 +25,25 @@
* Originally taken from https://github.com/nextcloud/server/blob/master/core/js/placeholder.js
*/

/**
* @param {number} r The red value
* @param {number} g The green value
* @param {number} b The blue value
*/
function Color(r, g, b) {
this.r = r
this.g = g
this.b = b
import { t } from '../l10n.js'

class Color {

/**
* @param {number} r The red value
* @param {number} g The green value
* @param {number} b The blue value
* @param {string} [name] The name of the color
*/
constructor(r, g, b, name) {
this.r = r
this.g = g
this.b = b
if (name) {
this.name = name
}
}

}

/**
Expand All @@ -54,18 +65,18 @@ function stepCalc(steps, ends) {
* Create a color palette from two colors
*
* @param {number} steps The number of steps the palette has
* @param {string} color1 The first color
* @param {string} color2 The second color
* @param {Color} color1 The first color
* @param {Color} color2 The second color
* @return {Array} The created palette array
*/
function mixPalette(steps, color1, color2) {
const palette = []
palette.push(color1)
const step = stepCalc(steps, [color1, color2])
for (let i = 1; i < steps; i++) {
const r = parseInt(color1.r + step[0] * i, 10)
const g = parseInt(color1.g + step[1] * i, 10)
const b = parseInt(color1.b + step[2] * i, 10)
const r = Math.floor(color1.r + step[0] * i)
const g = Math.floor(color1.g + step[1] * i)
const b = Math.floor(color1.b + step[2] * i)
palette.push(new Color(r, g, b))
}
return palette
Expand All @@ -85,9 +96,9 @@ function GenColors(steps) {
steps = 6
}

const red = new Color(182, 70, 157)
const yellow = new Color(221, 203, 85)
const blue = new Color(0, 130, 201) // Nextcloud blue
const red = new Color(182, 70, 157, t('Purple'))
const yellow = new Color(221, 203, 85, t('Gold'))
const blue = new Color(0, 130, 201, t('Nextcloud blue'))

const palette1 = mixPalette(steps, red, yellow)
const palette2 = mixPalette(steps, yellow, blue)
Expand Down

0 comments on commit 06c251a

Please sign in to comment.