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.
- package/lib/components/Input/ColorInput/Color.d.ts +3 -0
- package/lib/components/Input/ColorInput/Color.js +20 -0
- package/lib/components/Input/ColorInput/Color.js.map +1 -0
- package/lib/components/Input/ColorInput/ColorInput.d.ts +15 -0
- package/lib/components/Input/ColorInput/ColorInput.js +93 -0
- package/lib/components/Input/ColorInput/ColorInput.js.map +1 -0
- package/lib/components/Input/index.d.ts +1 -0
- package/lib/components/Input/index.js +1 -0
- package/lib/components/Input/index.js.map +1 -1
- package/lib/shared/key.d.ts +1 -0
- package/lib/shared/key.js +1 -0
- package/lib/shared/key.js.map +1 -1
- package/package.json +1 -1
- package/src/__image_snapshots__/all-visual-tsx-visual-tests-renders-components-inputs-color-input-invalid-correctly-1-snap.png +0 -0
- package/src/__image_snapshots__/all-visual-tsx-visual-tests-renders-components-inputs-color-input-read-only-correctly-1-snap.png +0 -0
- package/src/__image_snapshots__/all-visual-tsx-visual-tests-renders-components-inputs-color-input-standard-correctly-1-snap.png +0 -0
- package/src/components/Input/ColorInput/Color.ts +19 -0
- package/src/components/Input/ColorInput/Color.unit.ts +17 -0
- package/src/components/Input/ColorInput/ColorInput.stories.mdx +77 -0
- package/src/components/Input/ColorInput/ColorInput.tsx +146 -0
- package/src/components/Input/ColorInput/ColorInput.unit.tsx +69 -0
- package/src/components/Input/index.ts +1 -0
- package/src/shared/key.ts +1 -0
|
@@ -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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"}
|
|
@@ -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"}
|
package/lib/shared/key.d.ts
CHANGED
package/lib/shared/key.js
CHANGED
package/lib/shared/key.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"key.js","sourceRoot":"","sources":["../../src/shared/key.ts"],"names":[],"mappings":";;;AAAA,IAAK,
|
|
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
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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
|
+
});
|