akeneo-design-system 0.1.165 → 0.1.166

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ declare const convertColorToLongHexColor: (value: string) => string;
2
+ declare const isValidColor: (value: string) => boolean;
3
+ export { isValidColor, convertColorToLongHexColor };
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertColorToLongHexColor = exports.isValidColor = void 0;
4
+ var convertColorToLongHexColor = function (value) {
5
+ if (!isValidShortHexColor(value))
6
+ return value;
7
+ return "#" + value[1] + value[1] + value[2] + value[2] + value[3] + value[3];
8
+ };
9
+ exports.convertColorToLongHexColor = convertColorToLongHexColor;
10
+ var isValidShortHexColor = function (value) {
11
+ return /^#[A-Fa-f0-9]{3}$/.test(value);
12
+ };
13
+ var isValidLongHexColor = function (value) {
14
+ return /^#[A-Fa-f0-9]{6}$/.test(value);
15
+ };
16
+ var isValidColor = function (value) {
17
+ return isValidLongHexColor(value) || isValidShortHexColor(value);
18
+ };
19
+ exports.isValidColor = isValidColor;
20
+ //# sourceMappingURL=Color.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Color.js","sourceRoot":"","sources":["../../../../src/components/Input/ColorInput/Color.ts"],"names":[],"mappings":";;;AAAA,IAAM,0BAA0B,GAAG,UAAC,KAAa;IAC/C,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE/C,OAAO,MAAI,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAG,CAAC;AAC/E,CAAC,CAAC;AAcoB,gEAA0B;AAZhD,IAAM,oBAAoB,GAAG,UAAC,KAAa;IACzC,OAAO,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC,CAAC;AAEF,IAAM,mBAAmB,GAAG,UAAC,KAAa;IACxC,OAAO,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC,CAAC;AAEF,IAAM,YAAY,GAAG,UAAC,KAAa;IACjC,OAAO,mBAAmB,CAAC,KAAK,CAAC,IAAI,oBAAoB,CAAC,KAAK,CAAC,CAAC;AACnE,CAAC,CAAC;AAEM,oCAAY"}
@@ -0,0 +1,15 @@
1
+ import React, { InputHTMLAttributes } from 'react';
2
+ import { InputProps } from '../common/InputProps';
3
+ import { Override } from '../../../shared';
4
+ declare type ColorInputProps = Override<Override<InputHTMLAttributes<HTMLInputElement>, InputProps<string>>, ({
5
+ readOnly?: true;
6
+ } | {
7
+ readOnly?: false;
8
+ onChange: (newValue: string) => void;
9
+ }) & {
10
+ value: string;
11
+ placeholder?: string;
12
+ invalid?: boolean;
13
+ }>;
14
+ declare const ColorInput: React.ForwardRefExoticComponent<ColorInputProps & React.RefAttributes<HTMLInputElement>>;
15
+ export { ColorInput };
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
3
+ if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
4
+ return cooked;
5
+ };
6
+ var __assign = (this && this.__assign) || function () {
7
+ __assign = Object.assign || function(t) {
8
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
9
+ s = arguments[i];
10
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
11
+ t[p] = s[p];
12
+ }
13
+ return t;
14
+ };
15
+ return __assign.apply(this, arguments);
16
+ };
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || function (mod) {
30
+ if (mod && mod.__esModule) return mod;
31
+ var result = {};
32
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
33
+ __setModuleDefault(result, mod);
34
+ return result;
35
+ };
36
+ var __rest = (this && this.__rest) || function (s, e) {
37
+ var t = {};
38
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
39
+ t[p] = s[p];
40
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
41
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
42
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
43
+ t[p[i]] = s[p[i]];
44
+ }
45
+ return t;
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.ColorInput = void 0;
49
+ var react_1 = __importStar(require("react"));
50
+ var styled_components_1 = __importStar(require("styled-components"));
51
+ var icons_1 = require("../../../icons");
52
+ var theme_1 = require("../../../theme");
53
+ var Color_1 = require("./Color");
54
+ var ColorInputContainer = styled_components_1.default.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n display: flex;\n flex-direction: row;\n align-items: center;\n padding: 12px;\n border: 1px solid ", ";\n border-radius: 2px;\n height: 74px;\n gap: 10px;\n outline-style: none;\n box-sizing: border-box;\n background: ", ";\n cursor: ", ";\n overflow: hidden;\n ", "\n"], ["\n display: flex;\n flex-direction: row;\n align-items: center;\n padding: 12px;\n border: 1px solid ", ";\n border-radius: 2px;\n height: 74px;\n gap: 10px;\n outline-style: none;\n box-sizing: border-box;\n background: ", ";\n cursor: ", ";\n overflow: hidden;\n ", "\n"])), function (_a) {
55
+ var invalid = _a.invalid;
56
+ return (invalid ? (0, theme_1.getColor)('red', 100) : (0, theme_1.getColor)('grey', 80));
57
+ }, function (_a) {
58
+ var readOnly = _a.readOnly;
59
+ return (readOnly ? (0, theme_1.getColor)('grey', 20) : (0, theme_1.getColor)('white'));
60
+ }, function (_a) {
61
+ var readOnly = _a.readOnly;
62
+ return (readOnly ? 'not-allowed' : 'auto');
63
+ }, function (_a) {
64
+ var readOnly = _a.readOnly;
65
+ return !readOnly && (0, styled_components_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n &:focus-within {\n box-shadow: 0 0 0 2px ", ";\n }\n "], ["\n &:focus-within {\n box-shadow: 0 0 0 2px ", ";\n }\n "])), (0, theme_1.getColor)('blue', 40));
66
+ });
67
+ var ColorPicker = styled_components_1.default.input(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n width: 47px;\n height: 47px;\n border: none;\n padding: 0;\n ::-moz-color-swatch-wrapper {\n padding: 0;\n }\n ::-webkit-color-swatch-wrapper {\n padding: 0;\n }\n ::-webkit-color-swatch {\n border: none;\n }\n ::-moz-color-swatch {\n border: none;\n }\n"], ["\n width: 47px;\n height: 47px;\n border: none;\n padding: 0;\n ::-moz-color-swatch-wrapper {\n padding: 0;\n }\n ::-webkit-color-swatch-wrapper {\n padding: 0;\n }\n ::-webkit-color-swatch {\n border: none;\n }\n ::-moz-color-swatch {\n border: none;\n }\n"])));
68
+ var TextInput = styled_components_1.default.input(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n border: none;\n flex: 1;\n outline: none;\n color: ", ";\n background: transparent;\n cursor: ", ";\n height: 100%;\n\n &::placeholder {\n opacity: 1;\n color: ", ";\n }\n"], ["\n border: none;\n flex: 1;\n outline: none;\n color: ", ";\n background: transparent;\n cursor: ", ";\n height: 100%;\n\n &::placeholder {\n opacity: 1;\n color: ", ";\n }\n"])), function (_a) {
69
+ var readOnly = _a.readOnly;
70
+ return (readOnly ? (0, theme_1.getColor)('grey', 100) : (0, theme_1.getColor)('grey', 140));
71
+ }, function (_a) {
72
+ var readOnly = _a.readOnly;
73
+ return (readOnly ? 'not-allowed' : 'auto');
74
+ }, (0, theme_1.getColor)('grey', 100));
75
+ var ReadOnlyIcon = (0, styled_components_1.default)(icons_1.LockIcon)(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n margin-left: 4px;\n"], ["\n margin-left: 4px;\n"])));
76
+ var ErrorIcon = (0, styled_components_1.default)(icons_1.DangerIcon)(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n padding: 0 16px 0 15px;\n"], ["\n padding: 0 16px 0 15px;\n"])));
77
+ var ColorInput = (0, react_1.forwardRef)(function (_a, forwardedRef) {
78
+ var invalid = _a.invalid, onChange = _a.onChange, value = _a.value, readOnly = _a.readOnly, rest = __rest(_a, ["invalid", "onChange", "value", "readOnly"]);
79
+ var handleChange = (0, react_1.useCallback)(function (event) {
80
+ if (!readOnly && onChange)
81
+ onChange(event.currentTarget.value);
82
+ }, [readOnly, onChange]);
83
+ if (!value.startsWith('#')) {
84
+ value = "#" + value;
85
+ }
86
+ return (react_1.default.createElement(ColorInputContainer, { invalid: invalid || !(0, Color_1.isValidColor)(value), readOnly: readOnly },
87
+ (0, Color_1.isValidColor)(value) ? (react_1.default.createElement(ColorPicker, { type: "color", value: (0, Color_1.convertColorToLongHexColor)(value), onChange: handleChange, disabled: readOnly })) : (react_1.default.createElement(ErrorIcon, { role: "alert", size: 16 })),
88
+ react_1.default.createElement(TextInput, __assign({ ref: forwardedRef, value: value, onChange: handleChange, type: "text", readOnly: readOnly, disabled: readOnly, "aria-invalid": invalid || !(0, Color_1.isValidColor)(value) }, rest)),
89
+ readOnly && react_1.default.createElement(ReadOnlyIcon, { size: 16 })));
90
+ });
91
+ exports.ColorInput = ColorInput;
92
+ var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6;
93
+ //# sourceMappingURL=ColorInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ColorInput.js","sourceRoot":"","sources":["../../../../src/components/Input/ColorInput/ColorInput.tsx"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  export * from './BooleanInput/BooleanInput';
2
2
  export * from './common';
3
+ export * from './ColorInput/ColorInput';
3
4
  export * from './MediaFileInput/FileInfo';
4
5
  export * from './MediaFileInput/MediaFileInput';
5
6
  export * from './MediaLinkInput/MediaLinkInput';
@@ -12,6 +12,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  __exportStar(require("./BooleanInput/BooleanInput"), exports);
14
14
  __exportStar(require("./common"), exports);
15
+ __exportStar(require("./ColorInput/ColorInput"), exports);
15
16
  __exportStar(require("./MediaFileInput/FileInfo"), exports);
16
17
  __exportStar(require("./MediaFileInput/MediaFileInput"), exports);
17
18
  __exportStar(require("./MediaLinkInput/MediaLinkInput"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/Input/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8DAA4C;AAC5C,2CAAyB;AACzB,4DAA0C;AAC1C,kEAAgD;AAChD,kEAAgD;AAChD,sEAAoD;AACpD,4DAA0C;AAC1C,4DAA0C;AAC1C,0DAAwC;AACxC,sDAAoC;AACpC,gEAA8C;AAC9C,wDAAsC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/Input/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8DAA4C;AAC5C,2CAAyB;AACzB,0DAAwC;AACxC,4DAA0C;AAC1C,kEAAgD;AAChD,kEAAgD;AAChD,sEAAoD;AACpD,4DAA0C;AAC1C,4DAA0C;AAC1C,0DAAwC;AACxC,sDAAoC;AACpC,gEAA8C;AAC9C,wDAAsC"}
@@ -1,6 +1,7 @@
1
1
  declare enum Key {
2
2
  Space = " ",
3
3
  Enter = "Enter",
4
+ NumpadEnter = "NumpadEnter",
4
5
  Backspace = "Backspace",
5
6
  Escape = "Escape",
6
7
  ArrowLeft = "ArrowLeft",
package/lib/shared/key.js CHANGED
@@ -5,6 +5,7 @@ var Key;
5
5
  (function (Key) {
6
6
  Key["Space"] = " ";
7
7
  Key["Enter"] = "Enter";
8
+ Key["NumpadEnter"] = "NumpadEnter";
8
9
  Key["Backspace"] = "Backspace";
9
10
  Key["Escape"] = "Escape";
10
11
  Key["ArrowLeft"] = "ArrowLeft";
@@ -1 +1 @@
1
- {"version":3,"file":"key.js","sourceRoot":"","sources":["../../src/shared/key.ts"],"names":[],"mappings":";;;AAAA,IAAK,GAWJ;AAXD,WAAK,GAAG;IACN,kBAAW,CAAA;IACX,sBAAe,CAAA;IACf,8BAAuB,CAAA;IACvB,wBAAiB,CAAA;IACjB,8BAAuB,CAAA;IACvB,gCAAyB,CAAA;IACzB,8BAAuB,CAAA;IACvB,0BAAmB,CAAA;IACnB,wBAAiB,CAAA;IACjB,kBAAW,CAAA;AACb,CAAC,EAXI,GAAG,KAAH,GAAG,QAWP;AAEO,kBAAG"}
1
+ {"version":3,"file":"key.js","sourceRoot":"","sources":["../../src/shared/key.ts"],"names":[],"mappings":";;;AAAA,IAAK,GAYJ;AAZD,WAAK,GAAG;IACN,kBAAW,CAAA;IACX,sBAAe,CAAA;IACf,kCAA2B,CAAA;IAC3B,8BAAuB,CAAA;IACvB,wBAAiB,CAAA;IACjB,8BAAuB,CAAA;IACvB,gCAAyB,CAAA;IACzB,8BAAuB,CAAA;IACvB,0BAAmB,CAAA;IACnB,wBAAiB,CAAA;IACjB,kBAAW,CAAA;AACb,CAAC,EAZI,GAAG,KAAH,GAAG,QAYP;AAEO,kBAAG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akeneo-design-system",
3
- "version": "0.1.165",
3
+ "version": "0.1.166",
4
4
  "description": "Akeneo design system",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -0,0 +1,19 @@
1
+ const convertColorToLongHexColor = (value: string): string => {
2
+ if (!isValidShortHexColor(value)) return value;
3
+
4
+ return `#${value[1]}${value[1]}${value[2]}${value[2]}${value[3]}${value[3]}`;
5
+ };
6
+
7
+ const isValidShortHexColor = (value: string): boolean => {
8
+ return /^#[A-Fa-f0-9]{3}$/.test(value);
9
+ };
10
+
11
+ const isValidLongHexColor = (value: string): boolean => {
12
+ return /^#[A-Fa-f0-9]{6}$/.test(value);
13
+ };
14
+
15
+ const isValidColor = (value: string): boolean => {
16
+ return isValidLongHexColor(value) || isValidShortHexColor(value);
17
+ };
18
+
19
+ export {isValidColor, convertColorToLongHexColor};
@@ -0,0 +1,17 @@
1
+ import {convertColorToLongHexColor, isValidColor} from './Color';
2
+
3
+ test('it returns if the hex color is valid', () => {
4
+ expect(isValidColor('#f0f')).toBe(true);
5
+ expect(isValidColor('#F0F')).toBe(true);
6
+ expect(isValidColor('#ffffff')).toBe(true);
7
+ expect(isValidColor('#FFFF0F')).toBe(true);
8
+ expect(isValidColor('#FFFFFG')).toBe(false);
9
+ expect(isValidColor('#FFG')).toBe(false);
10
+ expect(isValidColor('#FFFF')).toBe(false);
11
+ expect(isValidColor('#FFFFFFF')).toBe(false);
12
+ });
13
+
14
+ test('it convert color to long hex color', () => {
15
+ expect(convertColorToLongHexColor('#ff00ff')).toBe('#ff00ff');
16
+ expect(convertColorToLongHexColor('#f0f')).toBe('#ff00ff');
17
+ });
@@ -0,0 +1,77 @@
1
+ import {useState} from 'react';
2
+ import {Meta, Story, ArgsTable, Canvas} from '@storybook/addon-docs/blocks';
3
+ import {ColorInput} from './ColorInput.tsx';
4
+
5
+ <Meta
6
+ title="Components/Inputs/Color input"
7
+ component={ColorInput}
8
+ argTypes={{
9
+ readOnly: {
10
+ control: {type: 'boolean'},
11
+ description:
12
+ 'Defines if the input should be read only. If defined so, the user cannot change the value of the input.',
13
+ table: {type: {summary: 'boolean'}},
14
+ },
15
+ onChange: {
16
+ description: 'The handler called when the value of the input changes.',
17
+ table: {type: {summary: '(newValue: string) => void'}},
18
+ },
19
+ }}
20
+ args={{
21
+ value: '#9452ba',
22
+ placeholder: 'Please enter a value in the ColorInput',
23
+ }}
24
+ />
25
+
26
+ # ColorInput (Beta)
27
+
28
+ ## Usage
29
+
30
+ Color input component allows the user to enter a color in hexadecimal format.
31
+
32
+ ### Placeholder text
33
+
34
+ The placeholder text provides tips or examples of items to enter. Placeholder text disappears when the user begins entering data.
35
+
36
+ ## Playground
37
+
38
+ <Canvas>
39
+ <Story name="Standard">
40
+ {args => {
41
+ const [value, setValue] = useState(args.value);
42
+ return <ColorInput {...args} value={value} onChange={setValue} />;
43
+ }}
44
+ </Story>
45
+ </Canvas>
46
+
47
+ <ArgsTable story="Standard" />
48
+
49
+ ## Variation on readOnly
50
+
51
+ <Canvas>
52
+ <Story name="Read only">
53
+ {args => {
54
+ return (
55
+ <>
56
+ <ColorInput value="#000" readOnly={false} />
57
+ <ColorInput value="#008542" readOnly={true} />
58
+ </>
59
+ );
60
+ }}
61
+ </Story>
62
+ </Canvas>
63
+
64
+ ## Variation on invalid
65
+
66
+ <Canvas>
67
+ <Story name="Invalid">
68
+ {args => {
69
+ return (
70
+ <>
71
+ <ColorInput value="#ffe000" invalid={false} />
72
+ <ColorInput value="not a color" invalid={true} />
73
+ </>
74
+ );
75
+ }}
76
+ </Story>
77
+ </Canvas>
@@ -0,0 +1,146 @@
1
+ import React, {ChangeEvent, forwardRef, InputHTMLAttributes, Ref, useCallback} from 'react';
2
+ import styled, {css} from 'styled-components';
3
+ import {InputProps} from '../common/InputProps';
4
+ import {DangerIcon, LockIcon} from '../../../icons';
5
+ import {Override} from '../../../shared';
6
+ import {AkeneoThemedProps, getColor} from '../../../theme';
7
+ import {isValidColor, convertColorToLongHexColor} from './Color';
8
+
9
+ const ColorInputContainer = styled.div<{readOnly: boolean} & AkeneoThemedProps>`
10
+ display: flex;
11
+ flex-direction: row;
12
+ align-items: center;
13
+ padding: 12px;
14
+ border: 1px solid ${({invalid}) => (invalid ? getColor('red', 100) : getColor('grey', 80))};
15
+ border-radius: 2px;
16
+ height: 74px;
17
+ gap: 10px;
18
+ outline-style: none;
19
+ box-sizing: border-box;
20
+ background: ${({readOnly}) => (readOnly ? getColor('grey', 20) : getColor('white'))};
21
+ cursor: ${({readOnly}) => (readOnly ? 'not-allowed' : 'auto')};
22
+ overflow: hidden;
23
+ ${({readOnly}) =>
24
+ !readOnly &&
25
+ css`
26
+ &:focus-within {
27
+ box-shadow: 0 0 0 2px ${getColor('blue', 40)};
28
+ }
29
+ `}
30
+ `;
31
+
32
+ const ColorPicker = styled.input`
33
+ width: 47px;
34
+ height: 47px;
35
+ border: none;
36
+ padding: 0;
37
+ ::-moz-color-swatch-wrapper {
38
+ padding: 0;
39
+ }
40
+ ::-webkit-color-swatch-wrapper {
41
+ padding: 0;
42
+ }
43
+ ::-webkit-color-swatch {
44
+ border: none;
45
+ }
46
+ ::-moz-color-swatch {
47
+ border: none;
48
+ }
49
+ `;
50
+
51
+ const TextInput = styled.input<{readOnly: boolean} & AkeneoThemedProps>`
52
+ border: none;
53
+ flex: 1;
54
+ outline: none;
55
+ color: ${({readOnly}) => (readOnly ? getColor('grey', 100) : getColor('grey', 140))};
56
+ background: transparent;
57
+ cursor: ${({readOnly}) => (readOnly ? 'not-allowed' : 'auto')};
58
+ height: 100%;
59
+
60
+ &::placeholder {
61
+ opacity: 1;
62
+ color: ${getColor('grey', 100)};
63
+ }
64
+ `;
65
+
66
+ const ReadOnlyIcon = styled(LockIcon)`
67
+ margin-left: 4px;
68
+ `;
69
+
70
+ const ErrorIcon = styled(DangerIcon)`
71
+ padding: 0 16px 0 15px;
72
+ `;
73
+
74
+ type ColorInputProps = Override<
75
+ Override<InputHTMLAttributes<HTMLInputElement>, InputProps<string>>,
76
+ (
77
+ | {
78
+ readOnly?: true;
79
+ }
80
+ | {
81
+ readOnly?: false;
82
+ onChange: (newValue: string) => void;
83
+ }
84
+ ) & {
85
+ /**
86
+ * Value of the input.
87
+ */
88
+ value: string;
89
+
90
+ /**
91
+ * Placeholder displayed when the input is empty.
92
+ */
93
+ placeholder?: string;
94
+
95
+ /**
96
+ * Defines if the input is valid or not.
97
+ */
98
+ invalid?: boolean;
99
+ }
100
+ >;
101
+
102
+ /**
103
+ * The ColorInput component allows the user to enter a color in hexadecimal format.
104
+ */
105
+ const ColorInput = forwardRef<HTMLInputElement, ColorInputProps>(
106
+ ({invalid, onChange, value, readOnly, ...rest}: ColorInputProps, forwardedRef: Ref<HTMLInputElement>) => {
107
+ const handleChange = useCallback(
108
+ (event: ChangeEvent<HTMLInputElement>) => {
109
+ if (!readOnly && onChange) onChange(event.currentTarget.value);
110
+ },
111
+ [readOnly, onChange]
112
+ );
113
+
114
+ if (!value.startsWith('#')) {
115
+ value = `#${value}`;
116
+ }
117
+
118
+ return (
119
+ <ColorInputContainer invalid={invalid || !isValidColor(value)} readOnly={readOnly}>
120
+ {isValidColor(value) ? (
121
+ <ColorPicker
122
+ type="color"
123
+ value={convertColorToLongHexColor(value)}
124
+ onChange={handleChange}
125
+ disabled={readOnly}
126
+ />
127
+ ) : (
128
+ <ErrorIcon role="alert" size={16} />
129
+ )}
130
+ <TextInput
131
+ ref={forwardedRef}
132
+ value={value}
133
+ onChange={handleChange}
134
+ type="text"
135
+ readOnly={readOnly}
136
+ disabled={readOnly}
137
+ aria-invalid={invalid || !isValidColor(value)}
138
+ {...rest}
139
+ />
140
+ {readOnly && <ReadOnlyIcon size={16} />}
141
+ </ColorInputContainer>
142
+ );
143
+ }
144
+ );
145
+
146
+ export {ColorInput};
@@ -0,0 +1,69 @@
1
+ import React from 'react';
2
+ import {ColorInput} from './ColorInput';
3
+ import {fireEvent, render, screen} from '../../../storybook/test-util';
4
+
5
+ test('it renders and handle changes', () => {
6
+ const handleChange = jest.fn();
7
+
8
+ render(
9
+ <>
10
+ <label htmlFor="myInput">My label</label>
11
+ <ColorInput id="myInput" value="#ff0000" onChange={handleChange} />
12
+ </>
13
+ );
14
+
15
+ fireEvent.change(screen.getByLabelText('My label'), {target: {value: '#00ff00'}});
16
+
17
+ expect(handleChange).toHaveBeenCalledWith('#00ff00');
18
+ });
19
+
20
+ test('it renders and does not call onChange if readOnly', () => {
21
+ const handleChange = jest.fn();
22
+
23
+ render(
24
+ <>
25
+ <label htmlFor="myInput">My label</label>
26
+ <ColorInput id="myInput" readOnly={true} value="#ff0000" onChange={handleChange} />
27
+ </>
28
+ );
29
+
30
+ fireEvent.change(screen.getByLabelText('My label'), {target: {value: '#00ff00'}});
31
+
32
+ expect(handleChange).not.toHaveBeenCalledWith('#00ff00');
33
+ });
34
+
35
+ test('it displays an error icon when the color is invalid', () => {
36
+ render(
37
+ <>
38
+ <label htmlFor="myInput">My label</label>
39
+ <ColorInput id="myInput" value="not a valid color" />
40
+ </>
41
+ );
42
+
43
+ expect(screen.getByRole('alert')).toBeInTheDocument();
44
+ });
45
+
46
+ test('it accepts color without a leading #', () => {
47
+ render(
48
+ <>
49
+ <label htmlFor="myInput">My label</label>
50
+ <ColorInput id="myInput" value="00ff00" />
51
+ </>
52
+ );
53
+
54
+ expect(screen.queryByRole('alert')).not.toBeInTheDocument();
55
+ });
56
+
57
+ test('ColorInput supports forwardRef', () => {
58
+ const ref = {current: null};
59
+
60
+ render(<ColorInput value="#ff0000" onChange={jest.fn()} ref={ref} />);
61
+
62
+ expect(ref.current).not.toBe(null);
63
+ });
64
+
65
+ test('ColorInput supports ...rest props', () => {
66
+ render(<ColorInput value="#ff0000" onChange={jest.fn()} data-testid="my_value" />);
67
+
68
+ expect(screen.getByTestId('my_value')).toBeInTheDocument();
69
+ });
@@ -1,5 +1,6 @@
1
1
  export * from './BooleanInput/BooleanInput';
2
2
  export * from './common';
3
+ export * from './ColorInput/ColorInput';
3
4
  export * from './MediaFileInput/FileInfo';
4
5
  export * from './MediaFileInput/MediaFileInput';
5
6
  export * from './MediaLinkInput/MediaLinkInput';
package/src/shared/key.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  enum Key {
2
2
  Space = ' ',
3
3
  Enter = 'Enter',
4
+ NumpadEnter = 'NumpadEnter',
4
5
  Backspace = 'Backspace',
5
6
  Escape = 'Escape',
6
7
  ArrowLeft = 'ArrowLeft',