@thednp/color-picker 0.0.1-alpha1 → 0.0.1-alpha2
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +1 -1
- package/README.md +40 -19
- package/dist/css/color-picker.css +481 -337
- package/dist/css/color-picker.min.css +2 -0
- package/dist/css/color-picker.rtl.css +506 -0
- package/dist/css/color-picker.rtl.min.css +2 -0
- package/dist/js/color-picker-element-esm.js +3810 -2
- package/dist/js/color-picker-element-esm.min.js +2 -0
- package/dist/js/color-picker-element.js +2009 -1242
- package/dist/js/color-picker-element.min.js +2 -2
- package/dist/js/color-picker-esm.js +3704 -0
- package/dist/js/color-picker-esm.min.js +2 -0
- package/dist/js/color-picker.js +1962 -1256
- package/dist/js/color-picker.min.js +2 -2
- package/package.json +18 -9
- package/src/js/color-palette.js +62 -0
- package/src/js/color-picker-element.js +55 -13
- package/src/js/color-picker.js +686 -595
- package/src/js/color.js +615 -349
- package/src/js/index.js +0 -9
- package/src/js/util/colorNames.js +2 -152
- package/src/js/util/colorPickerLabels.js +22 -0
- package/src/js/util/getColorControls.js +103 -0
- package/src/js/util/getColorForm.js +27 -19
- package/src/js/util/getColorMenu.js +95 -0
- package/src/js/util/isValidJSON.js +13 -0
- package/src/js/util/nonColors.js +5 -0
- package/src/js/util/templates.js +1 -0
- package/src/scss/color-picker.rtl.scss +23 -0
- package/src/scss/color-picker.scss +430 -0
- package/types/cp.d.ts +263 -160
- package/types/index.d.ts +9 -2
- package/types/source/source.ts +2 -1
- package/types/source/types.d.ts +28 -5
- package/dist/js/color-picker.esm.js +0 -2998
- package/dist/js/color-picker.esm.min.js +0 -2
- package/src/js/util/getColorControl.js +0 -49
- package/src/js/util/init.js +0 -14
package/src/js/index.js
CHANGED
@@ -1,12 +1,3 @@
|
|
1
|
-
import querySelectorAll from 'shorter-js/src/selectors/querySelectorAll';
|
2
1
|
import ColorPicker from './color-picker';
|
3
2
|
|
4
|
-
function initCallBack() {
|
5
|
-
const { init, selector } = ColorPicker;
|
6
|
-
[...querySelectorAll(selector)].forEach(init);
|
7
|
-
}
|
8
|
-
|
9
|
-
if (document.body) initCallBack();
|
10
|
-
else document.addEventListener('DOMContentLoaded', initCallBack, { once: true });
|
11
|
-
|
12
3
|
export default ColorPicker;
|
@@ -1,156 +1,6 @@
|
|
1
1
|
/**
|
2
|
-
* A
|
3
|
-
* @see https://github.com/bahamas10/css-color-names/blob/master/css-color-names.json
|
2
|
+
* A list of 17 color names used for WAI-ARIA compliance.
|
4
3
|
* @type {string[]}
|
5
4
|
*/
|
6
|
-
const colorNames = [
|
7
|
-
'aliceblue',
|
8
|
-
'antiquewhite',
|
9
|
-
'aqua',
|
10
|
-
'aquamarine',
|
11
|
-
'azure',
|
12
|
-
'beige',
|
13
|
-
'bisque',
|
14
|
-
'black',
|
15
|
-
'blanchedalmond',
|
16
|
-
'blue',
|
17
|
-
'blueviolet',
|
18
|
-
'brown',
|
19
|
-
'burlywood',
|
20
|
-
'cadetblue',
|
21
|
-
'chartreuse',
|
22
|
-
'chocolate',
|
23
|
-
'coral',
|
24
|
-
'cornflowerblue',
|
25
|
-
'cornsilk',
|
26
|
-
'crimson',
|
27
|
-
'cyan',
|
28
|
-
'darkblue',
|
29
|
-
'darkcyan',
|
30
|
-
'darkgoldenrod',
|
31
|
-
'darkgray',
|
32
|
-
'darkgreen',
|
33
|
-
'darkgrey',
|
34
|
-
'darkkhaki',
|
35
|
-
'darkmagenta',
|
36
|
-
'darkolivegreen',
|
37
|
-
'darkorange',
|
38
|
-
'darkorchid',
|
39
|
-
'darkred',
|
40
|
-
'darksalmon',
|
41
|
-
'darkseagreen',
|
42
|
-
'darkslateblue',
|
43
|
-
'darkslategray',
|
44
|
-
'darkslategrey',
|
45
|
-
'darkturquoise',
|
46
|
-
'darkviolet',
|
47
|
-
'deeppink',
|
48
|
-
'deepskyblue',
|
49
|
-
'dimgray',
|
50
|
-
'dimgrey',
|
51
|
-
'dodgerblue',
|
52
|
-
'firebrick',
|
53
|
-
'floralwhite',
|
54
|
-
'forestgreen',
|
55
|
-
'fuchsia',
|
56
|
-
'gainsboro',
|
57
|
-
'ghostwhite',
|
58
|
-
'goldenrod',
|
59
|
-
'gold',
|
60
|
-
'gray',
|
61
|
-
'green',
|
62
|
-
'greenyellow',
|
63
|
-
'grey',
|
64
|
-
'honeydew',
|
65
|
-
'hotpink',
|
66
|
-
'indianred',
|
67
|
-
'indigo',
|
68
|
-
'ivory',
|
69
|
-
'khaki',
|
70
|
-
'lavenderblush',
|
71
|
-
'lavender',
|
72
|
-
'lawngreen',
|
73
|
-
'lemonchiffon',
|
74
|
-
'lightblue',
|
75
|
-
'lightcoral',
|
76
|
-
'lightcyan',
|
77
|
-
'lightgoldenrodyellow',
|
78
|
-
'lightgray',
|
79
|
-
'lightgreen',
|
80
|
-
'lightgrey',
|
81
|
-
'lightpink',
|
82
|
-
'lightsalmon',
|
83
|
-
'lightseagreen',
|
84
|
-
'lightskyblue',
|
85
|
-
'lightslategray',
|
86
|
-
'lightslategrey',
|
87
|
-
'lightsteelblue',
|
88
|
-
'lightyellow',
|
89
|
-
'lime',
|
90
|
-
'limegreen',
|
91
|
-
'linen',
|
92
|
-
'magenta',
|
93
|
-
'maroon',
|
94
|
-
'mediumaquamarine',
|
95
|
-
'mediumblue',
|
96
|
-
'mediumorchid',
|
97
|
-
'mediumpurple',
|
98
|
-
'mediumseagreen',
|
99
|
-
'mediumslateblue',
|
100
|
-
'mediumspringgreen',
|
101
|
-
'mediumturquoise',
|
102
|
-
'mediumvioletred',
|
103
|
-
'midnightblue',
|
104
|
-
'mintcream',
|
105
|
-
'mistyrose',
|
106
|
-
'moccasin',
|
107
|
-
'navajowhite',
|
108
|
-
'navy',
|
109
|
-
'oldlace',
|
110
|
-
'olive',
|
111
|
-
'olivedrab',
|
112
|
-
'orange',
|
113
|
-
'orangered',
|
114
|
-
'orchid',
|
115
|
-
'palegoldenrod',
|
116
|
-
'palegreen',
|
117
|
-
'paleturquoise',
|
118
|
-
'palevioletred',
|
119
|
-
'papayawhip',
|
120
|
-
'peachpuff',
|
121
|
-
'peru',
|
122
|
-
'pink',
|
123
|
-
'plum',
|
124
|
-
'powderblue',
|
125
|
-
'purple',
|
126
|
-
'rebeccapurple',
|
127
|
-
'red',
|
128
|
-
'rosybrown',
|
129
|
-
'royalblue',
|
130
|
-
'saddlebrown',
|
131
|
-
'salmon',
|
132
|
-
'sandybrown',
|
133
|
-
'seagreen',
|
134
|
-
'seashell',
|
135
|
-
'sienna',
|
136
|
-
'silver',
|
137
|
-
'skyblue',
|
138
|
-
'slateblue',
|
139
|
-
'slategray',
|
140
|
-
'slategrey',
|
141
|
-
'snow',
|
142
|
-
'springgreen',
|
143
|
-
'steelblue',
|
144
|
-
'tan',
|
145
|
-
'teal',
|
146
|
-
'thistle',
|
147
|
-
'tomato',
|
148
|
-
'turquoise',
|
149
|
-
'violet',
|
150
|
-
'wheat',
|
151
|
-
'white',
|
152
|
-
'whitesmoke',
|
153
|
-
'yellow',
|
154
|
-
'yellowgreen',
|
155
|
-
];
|
5
|
+
const colorNames = ['white', 'black', 'grey', 'red', 'orange', 'brown', 'gold', 'olive', 'yellow', 'lime', 'green', 'teal', 'cyan', 'blue', 'violet', 'magenta', 'pink'];
|
156
6
|
export default colorNames;
|
@@ -0,0 +1,22 @@
|
|
1
|
+
/** @type {Record<string, string>} */
|
2
|
+
const colorPickerLabels = {
|
3
|
+
pickerLabel: 'Colour Picker',
|
4
|
+
appearanceLabel: 'Colour Appearance',
|
5
|
+
valueLabel: 'Colour Value',
|
6
|
+
toggleLabel: 'Select Colour',
|
7
|
+
presetsLabel: 'Colour Presets',
|
8
|
+
defaultsLabel: 'Colour Defaults',
|
9
|
+
formatLabel: 'Format',
|
10
|
+
alphaLabel: 'Alpha',
|
11
|
+
hexLabel: 'Hexadecimal',
|
12
|
+
hueLabel: 'Hue',
|
13
|
+
whitenessLabel: 'Whiteness',
|
14
|
+
blacknessLabel: 'Blackness',
|
15
|
+
saturationLabel: 'Saturation',
|
16
|
+
lightnessLabel: 'Lightness',
|
17
|
+
redLabel: 'Red',
|
18
|
+
greenLabel: 'Green',
|
19
|
+
blueLabel: 'Blue',
|
20
|
+
};
|
21
|
+
|
22
|
+
export default colorPickerLabels;
|
@@ -0,0 +1,103 @@
|
|
1
|
+
import ariaLabel from 'shorter-js/src/strings/ariaLabel';
|
2
|
+
import ariaValueMin from 'shorter-js/src/strings/ariaValueMin';
|
3
|
+
import ariaValueMax from 'shorter-js/src/strings/ariaValueMax';
|
4
|
+
import createElement from 'shorter-js/src/misc/createElement';
|
5
|
+
import setAttribute from 'shorter-js/src/attr/setAttribute';
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Returns all color controls for `ColorPicker`.
|
9
|
+
*
|
10
|
+
* @param {CP.ColorPicker} self the `ColorPicker` instance
|
11
|
+
* @returns {HTMLElement | Element} color controls
|
12
|
+
*/
|
13
|
+
export default function getColorControls(self) {
|
14
|
+
const { format, componentLabels } = self;
|
15
|
+
const {
|
16
|
+
hueLabel, alphaLabel, lightnessLabel, saturationLabel,
|
17
|
+
whitenessLabel, blacknessLabel,
|
18
|
+
} = componentLabels;
|
19
|
+
|
20
|
+
const max1 = format === 'hsl' ? 360 : 100;
|
21
|
+
const max2 = format === 'hsl' ? 100 : 360;
|
22
|
+
const max3 = 100;
|
23
|
+
|
24
|
+
let ctrl1Label = format === 'hsl'
|
25
|
+
? `${hueLabel} & ${lightnessLabel}`
|
26
|
+
: `${lightnessLabel} & ${saturationLabel}`;
|
27
|
+
|
28
|
+
ctrl1Label = format === 'hwb'
|
29
|
+
? `${whitenessLabel} & ${blacknessLabel}`
|
30
|
+
: ctrl1Label;
|
31
|
+
|
32
|
+
const ctrl2Label = format === 'hsl'
|
33
|
+
? `${saturationLabel}`
|
34
|
+
: `${hueLabel}`;
|
35
|
+
|
36
|
+
const colorControls = createElement({
|
37
|
+
tagName: 'div',
|
38
|
+
className: `color-controls ${format}`,
|
39
|
+
});
|
40
|
+
|
41
|
+
const colorPointer = 'color-pointer';
|
42
|
+
const colorSlider = 'color-slider';
|
43
|
+
|
44
|
+
const controls = [
|
45
|
+
{
|
46
|
+
i: 1,
|
47
|
+
c: colorPointer,
|
48
|
+
l: ctrl1Label,
|
49
|
+
min: 0,
|
50
|
+
max: max1,
|
51
|
+
},
|
52
|
+
{
|
53
|
+
i: 2,
|
54
|
+
c: colorSlider,
|
55
|
+
l: ctrl2Label,
|
56
|
+
min: 0,
|
57
|
+
max: max2,
|
58
|
+
},
|
59
|
+
{
|
60
|
+
i: 3,
|
61
|
+
c: colorSlider,
|
62
|
+
l: alphaLabel,
|
63
|
+
min: 0,
|
64
|
+
max: max3,
|
65
|
+
},
|
66
|
+
];
|
67
|
+
|
68
|
+
controls.forEach((template) => {
|
69
|
+
const {
|
70
|
+
i, c, l, min, max,
|
71
|
+
} = template;
|
72
|
+
// const hidden = i === 2 && format === 'hwb' ? ' v-hidden' : '';
|
73
|
+
const control = createElement({
|
74
|
+
tagName: 'div',
|
75
|
+
// className: `color-control${hidden}`,
|
76
|
+
className: 'color-control',
|
77
|
+
});
|
78
|
+
setAttribute(control, 'role', 'presentation');
|
79
|
+
|
80
|
+
control.append(
|
81
|
+
createElement({
|
82
|
+
tagName: 'div',
|
83
|
+
className: `visual-control visual-control${i}`,
|
84
|
+
}),
|
85
|
+
);
|
86
|
+
|
87
|
+
const knob = createElement({
|
88
|
+
tagName: 'div',
|
89
|
+
className: `${c} knob`,
|
90
|
+
ariaLive: 'polite',
|
91
|
+
});
|
92
|
+
|
93
|
+
setAttribute(knob, ariaLabel, l);
|
94
|
+
setAttribute(knob, 'role', 'slider');
|
95
|
+
setAttribute(knob, 'tabindex', '0');
|
96
|
+
setAttribute(knob, ariaValueMin, `${min}`);
|
97
|
+
setAttribute(knob, ariaValueMax, `${max}`);
|
98
|
+
control.append(knob);
|
99
|
+
colorControls.append(control);
|
100
|
+
});
|
101
|
+
|
102
|
+
return colorControls;
|
103
|
+
}
|
@@ -6,12 +6,13 @@ import toUpperCase from 'shorter-js/src/misc/toUpperCase';
|
|
6
6
|
import vHidden from './vHidden';
|
7
7
|
|
8
8
|
/**
|
9
|
-
* Returns the color form
|
9
|
+
* Returns the color form for `ColorPicker`.
|
10
|
+
*
|
10
11
|
* @param {CP.ColorPicker} self the `ColorPicker` instance
|
11
|
-
* @returns {HTMLElement | Element}
|
12
|
+
* @returns {HTMLElement | Element} a new `<div>` element with color component `<input>`
|
12
13
|
*/
|
13
14
|
export default function getColorForm(self) {
|
14
|
-
const { format, id } = self;
|
15
|
+
const { format, id, componentLabels } = self;
|
15
16
|
const colorForm = createElement({
|
16
17
|
tagName: 'div',
|
17
18
|
className: `color-form ${format}`,
|
@@ -20,38 +21,45 @@ export default function getColorForm(self) {
|
|
20
21
|
let components = ['hex'];
|
21
22
|
if (format === 'rgb') components = ['red', 'green', 'blue', 'alpha'];
|
22
23
|
else if (format === 'hsl') components = ['hue', 'saturation', 'lightness', 'alpha'];
|
24
|
+
else if (format === 'hwb') components = ['hue', 'whiteness', 'blackness', 'alpha'];
|
23
25
|
|
24
26
|
components.forEach((c) => {
|
25
27
|
const [C] = format === 'hex' ? ['#'] : toUpperCase(c).split('');
|
26
28
|
const cID = `color_${format}_${c}_${id}`;
|
29
|
+
const formatLabel = componentLabels[`${c}Label`];
|
27
30
|
const cInputLabel = createElement({ tagName: 'label' });
|
28
31
|
setAttribute(cInputLabel, 'for', cID);
|
29
32
|
cInputLabel.append(
|
30
33
|
createElement({ tagName: 'span', ariaHidden: 'true', innerText: `${C}:` }),
|
31
|
-
createElement({ tagName: 'span', className: vHidden, innerText:
|
34
|
+
createElement({ tagName: 'span', className: vHidden, innerText: formatLabel }),
|
32
35
|
);
|
33
36
|
const cInput = createElement({
|
34
37
|
tagName: 'input',
|
35
|
-
id: cID,
|
38
|
+
id: cID,
|
39
|
+
// name: cID, - prevent saving the value to a form
|
36
40
|
type: format === 'hex' ? 'text' : 'number',
|
37
|
-
value: c === 'alpha' ? '
|
41
|
+
value: c === 'alpha' ? '100' : '0',
|
38
42
|
className: `color-input ${c}`,
|
39
|
-
autocomplete: 'off',
|
40
|
-
spellcheck: 'false',
|
41
43
|
});
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
setAttribute(cInput, 'autocomplete', 'off');
|
45
|
+
setAttribute(cInput, 'spellcheck', 'false');
|
46
|
+
|
47
|
+
// alpha
|
48
|
+
let max = '100';
|
49
|
+
let step = '1';
|
50
|
+
if (c !== 'alpha') {
|
51
|
+
if (format === 'rgb') {
|
52
|
+
max = '255'; step = '1';
|
53
|
+
} else if (c === 'hue') {
|
54
|
+
max = '360'; step = '1';
|
48
55
|
}
|
49
|
-
ObjectAssign(cInput, {
|
50
|
-
min: '0',
|
51
|
-
max,
|
52
|
-
step,
|
53
|
-
});
|
54
56
|
}
|
57
|
+
ObjectAssign(cInput, {
|
58
|
+
min: '0',
|
59
|
+
max,
|
60
|
+
step,
|
61
|
+
});
|
62
|
+
// }
|
55
63
|
colorForm.append(cInputLabel, cInput);
|
56
64
|
});
|
57
65
|
return colorForm;
|
@@ -0,0 +1,95 @@
|
|
1
|
+
import ariaLabel from 'shorter-js/src/strings/ariaLabel';
|
2
|
+
import ariaSelected from 'shorter-js/src/strings/ariaSelected';
|
3
|
+
import setAttribute from 'shorter-js/src/attr/setAttribute';
|
4
|
+
import getAttribute from 'shorter-js/src/attr/getAttribute';
|
5
|
+
import createElement from 'shorter-js/src/misc/createElement';
|
6
|
+
import setElementStyle from 'shorter-js/src/misc/setElementStyle';
|
7
|
+
|
8
|
+
import Color from '../color';
|
9
|
+
import ColorPalette from '../color-palette';
|
10
|
+
|
11
|
+
/**
|
12
|
+
* Returns a color-defaults with given values and class.
|
13
|
+
* @param {CP.ColorPicker} self
|
14
|
+
* @param {CP.ColorPalette | string[]} colorsSource
|
15
|
+
* @param {string} menuClass
|
16
|
+
* @returns {HTMLElement | Element}
|
17
|
+
*/
|
18
|
+
export default function getColorMenu(self, colorsSource, menuClass) {
|
19
|
+
const { input, format, componentLabels } = self;
|
20
|
+
const { defaultsLabel, presetsLabel } = componentLabels;
|
21
|
+
const isOptionsMenu = menuClass === 'color-options';
|
22
|
+
const isPalette = colorsSource instanceof ColorPalette;
|
23
|
+
const menuLabel = isOptionsMenu ? presetsLabel : defaultsLabel;
|
24
|
+
let colorsArray = isPalette ? colorsSource.colors : colorsSource;
|
25
|
+
colorsArray = colorsArray instanceof Array ? colorsArray : [];
|
26
|
+
const colorsCount = colorsArray.length;
|
27
|
+
const { lightSteps } = isPalette ? colorsSource : { lightSteps: null };
|
28
|
+
let fit = lightSteps
|
29
|
+
|| Math.max(...[5, 6, 7, 8, 9, 10].filter((x) => colorsCount > (x * 2) && !(colorsCount % x)));
|
30
|
+
fit = Number.isFinite(fit) ? fit : 5;
|
31
|
+
const isMultiLine = isOptionsMenu && colorsCount > fit;
|
32
|
+
let rowCountHover = 1;
|
33
|
+
rowCountHover = isMultiLine && colorsCount < 27 ? 2 : rowCountHover;
|
34
|
+
rowCountHover = colorsCount >= 27 ? 3 : rowCountHover;
|
35
|
+
rowCountHover = colorsCount >= 36 ? 4 : rowCountHover;
|
36
|
+
rowCountHover = colorsCount >= 45 ? 5 : rowCountHover;
|
37
|
+
const rowCount = rowCountHover - (colorsCount < 27 ? 1 : 2);
|
38
|
+
const isScrollable = isMultiLine && colorsCount > rowCountHover * fit;
|
39
|
+
let finalClass = menuClass;
|
40
|
+
finalClass += isScrollable ? ' scrollable' : '';
|
41
|
+
finalClass += isMultiLine ? ' multiline' : '';
|
42
|
+
const gap = isMultiLine ? '1px' : '0.25rem';
|
43
|
+
let optionSize = isMultiLine ? 1.75 : 2;
|
44
|
+
optionSize = !(colorsCount % 10) && isMultiLine ? 1.5 : optionSize;
|
45
|
+
const menuHeight = `${(rowCount || 1) * optionSize}rem`;
|
46
|
+
const menuHeightHover = `calc(${rowCountHover} * ${optionSize}rem + ${rowCountHover - 1} * ${gap})`;
|
47
|
+
const gridTemplateColumns = `repeat(${fit}, ${optionSize}rem)`;
|
48
|
+
const gridTemplateRows = `repeat(auto-fill, ${optionSize}rem)`;
|
49
|
+
|
50
|
+
const menu = createElement({
|
51
|
+
tagName: 'ul',
|
52
|
+
className: finalClass,
|
53
|
+
});
|
54
|
+
setAttribute(menu, 'role', 'listbox');
|
55
|
+
setAttribute(menu, ariaLabel, `${menuLabel}`);
|
56
|
+
|
57
|
+
if (isOptionsMenu) {
|
58
|
+
if (isScrollable) {
|
59
|
+
const styleText = 'this.style.height=';
|
60
|
+
setAttribute(menu, 'onmouseout', `${styleText}'${menuHeight}'`);
|
61
|
+
setAttribute(menu, 'onmouseover', `${styleText}'${menuHeightHover}'`);
|
62
|
+
}
|
63
|
+
const menuStyle = {
|
64
|
+
height: isScrollable ? menuHeight : '', gridTemplateColumns, gridTemplateRows, gap,
|
65
|
+
};
|
66
|
+
setElementStyle(menu, menuStyle);
|
67
|
+
}
|
68
|
+
|
69
|
+
colorsArray.forEach((x) => {
|
70
|
+
const [value, label] = x.trim().split(':');
|
71
|
+
const xRealColor = new Color(value, format).toString();
|
72
|
+
const isActive = xRealColor === getAttribute(input, 'value');
|
73
|
+
const active = isActive ? ' active' : '';
|
74
|
+
|
75
|
+
const option = createElement({
|
76
|
+
tagName: 'li',
|
77
|
+
className: `color-option${active}`,
|
78
|
+
innerText: `${label || x}`,
|
79
|
+
});
|
80
|
+
|
81
|
+
setAttribute(option, 'tabindex', '0');
|
82
|
+
setAttribute(option, 'data-value', `${value}`);
|
83
|
+
setAttribute(option, 'role', 'option');
|
84
|
+
setAttribute(option, ariaSelected, isActive ? 'true' : 'false');
|
85
|
+
|
86
|
+
if (isOptionsMenu) {
|
87
|
+
setElementStyle(option, {
|
88
|
+
width: `${optionSize}rem`, height: `${optionSize}rem`, backgroundColor: x,
|
89
|
+
});
|
90
|
+
}
|
91
|
+
|
92
|
+
menu.append(option);
|
93
|
+
});
|
94
|
+
return menu;
|
95
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/**
|
2
|
+
* Check if a string is valid JSON string.
|
3
|
+
* @param {string} str the string input
|
4
|
+
* @returns {boolean} the query result
|
5
|
+
*/
|
6
|
+
export default function isValidJSON(str) {
|
7
|
+
try {
|
8
|
+
JSON.parse(str);
|
9
|
+
} catch (e) {
|
10
|
+
return false;
|
11
|
+
}
|
12
|
+
return true;
|
13
|
+
}
|
package/src/js/util/templates.js
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
@import "color-picker";
|
2
|
+
|
3
|
+
[dir="rtl"] {
|
4
|
+
.color-preview { text-align: right; }
|
5
|
+
|
6
|
+
.menu-toggle {
|
7
|
+
right: auto; left: 0;
|
8
|
+
border-radius: .25rem 0 0 .25rem;
|
9
|
+
}
|
10
|
+
.color-dropdown.picker {
|
11
|
+
right: 0; left: auto;
|
12
|
+
}
|
13
|
+
.color-dropdown.menu {
|
14
|
+
right: auto; left: 0;
|
15
|
+
}
|
16
|
+
.color-control + .color-control {
|
17
|
+
margin-right: .5rem;
|
18
|
+
margin-left: 0;
|
19
|
+
}
|
20
|
+
.color-options.scrollable {
|
21
|
+
margin: 0 0 0 -.5rem;
|
22
|
+
}
|
23
|
+
}
|