krl-alfred 2.23.26 → 2.24.0

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,4 @@
1
+ import React from 'react';
2
+ import { ColorCardProps } from './props';
3
+ declare const ColorCard: ({ title, hint, value, placeholder, hasError, errorMessage, disabled, name, id, onChange, }: ColorCardProps) => React.JSX.Element;
4
+ export default ColorCard;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ var jsx_runtime_1 = require("react/jsx-runtime");
18
+ var react_1 = require("react");
19
+ var react_i18next_1 = require("react-i18next");
20
+ var props_1 = require("./props");
21
+ var ColorCard_styled_1 = require("./ColorCard.styled");
22
+ var Input_1 = __importDefault(require("../Input"));
23
+ var ColorPicker_1 = __importDefault(require("./ColorPicker"));
24
+ var useOnClickOutside_1 = __importDefault(require("../../hooks/useOnClickOutside"));
25
+ var color_1 = require("./utils/color");
26
+ var ColorCard = function (_a) {
27
+ var _b = _a.title, title = _b === void 0 ? props_1.ColorCardDefault.title : _b, _c = _a.hint, hint = _c === void 0 ? props_1.ColorCardDefault.hint : _c, _d = _a.value, value = _d === void 0 ? props_1.ColorCardDefault.value : _d, _e = _a.placeholder, placeholder = _e === void 0 ? props_1.ColorCardDefault.placeholder : _e, _f = _a.hasError, hasError = _f === void 0 ? props_1.ColorCardDefault.hasError : _f, _g = _a.errorMessage, errorMessage = _g === void 0 ? props_1.ColorCardDefault.errorMessage : _g, _h = _a.disabled, disabled = _h === void 0 ? props_1.ColorCardDefault.disabled : _h, _j = _a.name, name = _j === void 0 ? props_1.ColorCardDefault.name : _j, _k = _a.id, id = _k === void 0 ? props_1.ColorCardDefault.id : _k, _l = _a.onChange, onChange = _l === void 0 ? props_1.ColorCardDefault.onChange : _l;
28
+ var t = (0, react_i18next_1.useTranslation)().t;
29
+ var pickerRef = (0, react_1.useRef)(null);
30
+ var _m = (0, react_1.useState)(false), isOpen = _m[0], setIsOpen = _m[1];
31
+ var _o = (0, react_1.useState)(function () { return (0, color_1.formatHexInput)(value); }), hex = _o[0], setHex = _o[1];
32
+ var swatchColor = (0, color_1.toSwatchColor)(hex);
33
+ var pickerValue = (0, color_1.normalizeHex)(hex) || '#000000';
34
+ (0, useOnClickOutside_1.default)(pickerRef, function () { return setIsOpen(false); }, true);
35
+ (0, react_1.useEffect)(function () {
36
+ setHex((0, color_1.formatHexInput)(value));
37
+ }, [value]);
38
+ (0, react_1.useEffect)(function () {
39
+ if (!isOpen)
40
+ return undefined;
41
+ var handleKeyDown = function (event) {
42
+ if (event.key === 'Escape')
43
+ setIsOpen(false);
44
+ };
45
+ document.addEventListener('keydown', handleKeyDown);
46
+ return function () { return document.removeEventListener('keydown', handleKeyDown); };
47
+ }, [isOpen]);
48
+ var emitHex = function (next) {
49
+ var formatted = (0, color_1.nextHexInput)(hex, next);
50
+ setHex(formatted);
51
+ if (formatted === hex)
52
+ return;
53
+ onChange === null || onChange === void 0 ? void 0 : onChange({
54
+ target: { value: formatted, name: name, id: id },
55
+ currentTarget: { value: formatted, name: name, id: id },
56
+ });
57
+ };
58
+ var handleHexBlur = function (event) {
59
+ var _a;
60
+ var raw = (_a = event.target.value) !== null && _a !== void 0 ? _a : hex;
61
+ emitHex((0, color_1.formatHexInput)(raw).toUpperCase());
62
+ };
63
+ return ((0, jsx_runtime_1.jsxs)(ColorCard_styled_1.ColorCardStyled, { children: [(0, jsx_runtime_1.jsxs)(ColorCard_styled_1.SwatchWrap, __assign({ ref: pickerRef }, { children: [(0, jsx_runtime_1.jsx)(ColorCard_styled_1.ColorSwatch, { type: "button", "$color": swatchColor, "$disabled": disabled, disabled: disabled, "aria-label": title || t('pickColor'), "aria-expanded": isOpen, "aria-haspopup": "dialog", onClick: function () {
64
+ if (disabled)
65
+ return;
66
+ setIsOpen(function (open) { return !open; });
67
+ } }), isOpen && !disabled && ((0, jsx_runtime_1.jsx)(ColorCard_styled_1.ColorPickerPopover, __assign({ role: "dialog", "aria-label": t('pickColor') }, { children: (0, jsx_runtime_1.jsx)(ColorPicker_1.default, { value: pickerValue, onChange: emitHex }) })))] })), (0, jsx_runtime_1.jsx)(ColorCard_styled_1.ColorCardField, __assign({ onBlur: handleHexBlur }, { children: (0, jsx_runtime_1.jsx)(Input_1.default, { label: title, description: hint, value: hex, placeholder: placeholder, hasError: hasError, errorMessage: errorMessage, disabled: disabled, name: name, id: id, mask: null, format: null, maxLength: 7, onChange: function (event) { var _a; return emitHex((_a = event === null || event === void 0 ? void 0 : event.target) === null || _a === void 0 ? void 0 : _a.value); }, width: "100%" }) }))] }));
68
+ };
69
+ exports.default = ColorCard;
@@ -0,0 +1,21 @@
1
+ /// <reference types="react" />
2
+ import { ColorCardStyledProps } from './props';
3
+ export declare const ColorCardStyled: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
4
+ export declare const SwatchWrap: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
5
+ export declare const ColorSwatch: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, keyof ColorCardStyledProps> & ColorCardStyledProps, never> & Partial<Pick<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, keyof ColorCardStyledProps> & ColorCardStyledProps, never>>> & string;
6
+ export declare const ColorCardField: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
7
+ export declare const ColorPickerPopover: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
8
+ export declare const PickerBody: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
9
+ export declare const Saturation: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$hue"> & {
10
+ $hue: number;
11
+ }, never> & Partial<Pick<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "$hue"> & {
12
+ $hue: number;
13
+ }, never>>> & string;
14
+ export declare const HueSlider: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
15
+ export declare const Thumb: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "$x" | "$y"> & {
16
+ $x: number;
17
+ $y: number;
18
+ }, never> & Partial<Pick<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "$x" | "$y"> & {
19
+ $x: number;
20
+ $y: number;
21
+ }, never>>> & string;
@@ -0,0 +1,21 @@
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 __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.Thumb = exports.HueSlider = exports.Saturation = exports.PickerBody = exports.ColorPickerPopover = exports.ColorCardField = exports.ColorSwatch = exports.SwatchWrap = exports.ColorCardStyled = void 0;
11
+ var styled_components_1 = __importDefault(require("styled-components"));
12
+ exports.ColorCardStyled = styled_components_1.default.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n display: flex;\n align-items: center;\n gap: 1.5rem;\n padding: 1.5rem;\n border-radius: 0.5rem;\n border: 1px solid var(--dark-opacity-10);\n background: white;\n box-sizing: border-box;\n background: var(--dark-opacity-3);\n"], ["\n display: flex;\n align-items: center;\n gap: 1.5rem;\n padding: 1.5rem;\n border-radius: 0.5rem;\n border: 1px solid var(--dark-opacity-10);\n background: white;\n box-sizing: border-box;\n background: var(--dark-opacity-3);\n"])));
13
+ exports.SwatchWrap = styled_components_1.default.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n position: relative;\n flex-shrink: 0;\n width: 56px;\n height: 56px;\n border: 1px solid var(--dark-opacity-10);\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 0.5rem;\n"], ["\n position: relative;\n flex-shrink: 0;\n width: 56px;\n height: 56px;\n border: 1px solid var(--dark-opacity-10);\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 0.5rem;\n"])));
14
+ exports.ColorSwatch = styled_components_1.default.button(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n width: 40px;\n height: 40px;\n padding: 0;\n flex-shrink: 0;\n box-sizing: border-box;\n border-radius: 0.25rem;\n border: none;\n background-color: ", ";\n opacity: ", ";\n cursor: ", ";\n appearance: none;\n\n &:focus-visible {\n outline: 2px solid var(--primary);\n outline-offset: 2px;\n }\n"], ["\n width: 40px;\n height: 40px;\n padding: 0;\n flex-shrink: 0;\n box-sizing: border-box;\n border-radius: 0.25rem;\n border: none;\n background-color: ", ";\n opacity: ", ";\n cursor: ", ";\n appearance: none;\n\n &:focus-visible {\n outline: 2px solid var(--primary);\n outline-offset: 2px;\n }\n"])), function (props) { return props.$color || 'transparent'; }, function (props) { return props.$disabled ? 0.4 : 1; }, function (props) { return props.$disabled ? 'not-allowed' : 'pointer'; });
15
+ exports.ColorCardField = styled_components_1.default.div(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n flex: 1;\n min-width: 0;\n"], ["\n flex: 1;\n min-width: 0;\n"])));
16
+ exports.ColorPickerPopover = styled_components_1.default.div(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n position: absolute;\n top: calc(100% + 8px);\n left: 0;\n z-index: 9;\n padding: 1rem;\n border-radius: 0.5rem;\n border: 1px solid var(--dark-opacity-10);\n background: white;\n box-shadow: 0 6px 30px 0 var(--box-shadow-color);\n box-sizing: border-box;\n user-select: none;\n"], ["\n position: absolute;\n top: calc(100% + 8px);\n left: 0;\n z-index: 9;\n padding: 1rem;\n border-radius: 0.5rem;\n border: 1px solid var(--dark-opacity-10);\n background: white;\n box-shadow: 0 6px 30px 0 var(--box-shadow-color);\n box-sizing: border-box;\n user-select: none;\n"])));
17
+ exports.PickerBody = styled_components_1.default.div(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n display: flex;\n flex-direction: column;\n gap: 1rem;\n"], ["\n display: flex;\n flex-direction: column;\n gap: 1rem;\n"])));
18
+ exports.Saturation = styled_components_1.default.div(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n position: relative;\n width: 192px;\n height: 140px;\n border-radius: 0.5rem;\n cursor: crosshair;\n touch-action: none;\n background:\n linear-gradient(to top, #000, transparent),\n linear-gradient(to right, #fff, hsl(", ", 100%, 50%));\n"], ["\n position: relative;\n width: 192px;\n height: 140px;\n border-radius: 0.5rem;\n cursor: crosshair;\n touch-action: none;\n background:\n linear-gradient(to top, #000, transparent),\n linear-gradient(to right, #fff, hsl(", ", 100%, 50%));\n"])), function (props) { return props.$hue; });
19
+ exports.HueSlider = styled_components_1.default.div(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n position: relative;\n width: 192px;\n height: 12px;\n border-radius: 0.5rem;\n cursor: pointer;\n touch-action: none;\n background: linear-gradient(to right, #F00, #FF0, #0F0, #0FF, #00F, #F0F, #F00);\n"], ["\n position: relative;\n width: 192px;\n height: 12px;\n border-radius: 0.5rem;\n cursor: pointer;\n touch-action: none;\n background: linear-gradient(to right, #F00, #FF0, #0F0, #0FF, #00F, #F0F, #F00);\n"])));
20
+ exports.Thumb = styled_components_1.default.span(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n position: absolute;\n left: ", "%;\n top: ", "%;\n width: 16px;\n height: 16px;\n border: 2px solid white;\n border-radius: 50%;\n box-shadow: 0 0 0 1px var(--dark-opacity-25);\n transform: translate(-50%, -50%);\n pointer-events: none;\n box-sizing: border-box;\n"], ["\n position: absolute;\n left: ", "%;\n top: ", "%;\n width: 16px;\n height: 16px;\n border: 2px solid white;\n border-radius: 50%;\n box-shadow: 0 0 0 1px var(--dark-opacity-25);\n transform: translate(-50%, -50%);\n pointer-events: none;\n box-sizing: border-box;\n"])), function (props) { return props.$x * 100; }, function (props) { return props.$y * 100; });
21
+ var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __importDefault = (this && this.__importDefault) || function (mod) {
50
+ return (mod && mod.__esModule) ? mod : { "default": mod };
51
+ };
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ var jsx_runtime_1 = require("react/jsx-runtime");
54
+ var react_1 = require("@testing-library/react");
55
+ var user_event_1 = __importDefault(require("@testing-library/user-event"));
56
+ var ColorCard_1 = __importDefault(require("./ColorCard"));
57
+ var props_1 = require("./props");
58
+ jest.mock('react-i18next', function () { return ({
59
+ useTranslation: function () { return ({
60
+ t: function (key) { return key; },
61
+ }); },
62
+ }); });
63
+ var mockRect = function (element, width, height) {
64
+ jest.spyOn(element, 'getBoundingClientRect').mockReturnValue({
65
+ width: width,
66
+ height: height,
67
+ left: 0,
68
+ top: 0,
69
+ right: width,
70
+ bottom: height,
71
+ x: 0,
72
+ y: 0,
73
+ toJSON: function () { },
74
+ });
75
+ };
76
+ var renderColorCard = function (props) {
77
+ if (props === void 0) { props = {}; }
78
+ return (0, react_1.render)((0, jsx_runtime_1.jsx)(ColorCard_1.default, __assign({}, props_1.ColorCardDefault, { title: "Birincil renk", hint: "Ana buton ve vurgular", value: "#9763F6", id: "color-card-test", onChange: jest.fn() }, props)));
79
+ };
80
+ var hexField = function () { return react_1.screen.getByRole('textbox'); };
81
+ describe('ColorCard', function () {
82
+ it('renders title, hex value and hint through Input', function () {
83
+ renderColorCard();
84
+ expect(react_1.screen.getByText('Birincil renk')).toBeInTheDocument();
85
+ expect(hexField()).toHaveDisplayValue('#9763F6');
86
+ expect(react_1.screen.getByText('Ana buton ve vurgular')).toBeInTheDocument();
87
+ });
88
+ it('keeps the hex field editable', function () {
89
+ renderColorCard();
90
+ expect(hexField()).toBeEnabled();
91
+ expect(hexField()).toHaveProperty('readOnly', false);
92
+ });
93
+ it('paints the swatch from a valid hex value', function () {
94
+ renderColorCard({ value: '#0A103D' });
95
+ expect(react_1.screen.getByRole('button', { name: 'Birincil renk' })).toHaveStyle({
96
+ width: '40px',
97
+ height: '40px',
98
+ backgroundColor: 'rgb(10, 16, 61)',
99
+ });
100
+ });
101
+ it('keeps a hash prefix and at most 6 hex digits', function () {
102
+ renderColorCard();
103
+ react_1.fireEvent.change(hexField(), { target: { value: '##zz0a103dzzzz' } });
104
+ expect(hexField()).toHaveDisplayValue('#0a103d');
105
+ expect(hexField()).toHaveAttribute('maxLength', '7');
106
+ });
107
+ it('keeps a full 6-digit hex after blur', function () {
108
+ renderColorCard({ value: '#' });
109
+ react_1.fireEvent.change(hexField(), { target: { value: '#abcdef' } });
110
+ react_1.fireEvent.focusOut(hexField());
111
+ expect(hexField()).toHaveDisplayValue('#ABCDEF');
112
+ });
113
+ it('uppercases the hex field on blur', function () {
114
+ renderColorCard();
115
+ react_1.fireEvent.change(hexField(), { target: { value: '#aa11bb' } });
116
+ react_1.fireEvent.focusOut(hexField());
117
+ expect(hexField()).toHaveDisplayValue('#AA11BB');
118
+ });
119
+ it('ignores invalid letters while typing instead of deleting them on the next key', function () { return __awaiter(void 0, void 0, void 0, function () {
120
+ var user;
121
+ return __generator(this, function (_a) {
122
+ switch (_a.label) {
123
+ case 0:
124
+ user = user_event_1.default.setup();
125
+ renderColorCard({ value: '#' });
126
+ return [4 /*yield*/, user.type(hexField(), 'asd', { initialSelectionStart: 1, initialSelectionEnd: 1 })];
127
+ case 1:
128
+ _a.sent();
129
+ expect(hexField()).toHaveDisplayValue('#ad');
130
+ return [2 /*return*/];
131
+ }
132
+ });
133
+ }); });
134
+ it('keeps existing hex digits when an invalid letter is typed in the middle', function () { return __awaiter(void 0, void 0, void 0, function () {
135
+ var user, field;
136
+ return __generator(this, function (_a) {
137
+ switch (_a.label) {
138
+ case 0:
139
+ user = user_event_1.default.setup();
140
+ renderColorCard({ value: '#ACE' });
141
+ field = hexField();
142
+ field.focus();
143
+ field.setSelectionRange(2, 2);
144
+ return [4 /*yield*/, user.keyboard('sb')];
145
+ case 1:
146
+ _a.sent();
147
+ expect(field).toHaveDisplayValue('#AbCE');
148
+ return [2 /*return*/];
149
+ }
150
+ });
151
+ }); });
152
+ it('inserts a hex digit in the middle without shifting the rest', function () { return __awaiter(void 0, void 0, void 0, function () {
153
+ var user, field;
154
+ return __generator(this, function (_a) {
155
+ switch (_a.label) {
156
+ case 0:
157
+ user = user_event_1.default.setup();
158
+ renderColorCard({ value: '#ACE' });
159
+ field = hexField();
160
+ field.focus();
161
+ field.setSelectionRange(2, 2);
162
+ return [4 /*yield*/, user.keyboard('b')];
163
+ case 1:
164
+ _a.sent();
165
+ expect(field).toHaveDisplayValue('#AbCE');
166
+ return [2 /*return*/];
167
+ }
168
+ });
169
+ }); });
170
+ it('restores the hash and keeps digits when the hash is deleted', function () { return __awaiter(void 0, void 0, void 0, function () {
171
+ var user, field;
172
+ return __generator(this, function (_a) {
173
+ switch (_a.label) {
174
+ case 0:
175
+ user = user_event_1.default.setup();
176
+ renderColorCard({ value: '#ab' });
177
+ field = hexField();
178
+ field.focus();
179
+ field.setSelectionRange(0, 1);
180
+ return [4 /*yield*/, user.keyboard('{Backspace}')];
181
+ case 1:
182
+ _a.sent();
183
+ expect(field).toHaveDisplayValue('#ab');
184
+ return [2 /*return*/];
185
+ }
186
+ });
187
+ }); });
188
+ it('does not accept more than 6 hex digits', function () { return __awaiter(void 0, void 0, void 0, function () {
189
+ var user;
190
+ return __generator(this, function (_a) {
191
+ switch (_a.label) {
192
+ case 0:
193
+ user = user_event_1.default.setup();
194
+ renderColorCard({ value: '#ABCDEF' });
195
+ return [4 /*yield*/, user.type(hexField(), '1', { initialSelectionStart: 7, initialSelectionEnd: 7 })];
196
+ case 1:
197
+ _a.sent();
198
+ expect(hexField()).toHaveDisplayValue('#ABCDEF');
199
+ return [2 /*return*/];
200
+ }
201
+ });
202
+ }); });
203
+ it('replaces a fully selected value key by key without stripping later letters', function () {
204
+ renderColorCard({ value: '#9763F6' });
205
+ var field = hexField();
206
+ field.setSelectionRange(0, field.value.length);
207
+ react_1.fireEvent.select(field);
208
+ react_1.fireEvent.change(field, { target: { value: 'a' } });
209
+ expect(field).toHaveDisplayValue('#a');
210
+ react_1.fireEvent.change(field, { target: { value: '#as' } });
211
+ expect(field).toHaveDisplayValue('#a');
212
+ react_1.fireEvent.change(field, { target: { value: '#ad' } });
213
+ expect(field).toHaveDisplayValue('#ad');
214
+ });
215
+ it('updates the swatch when a valid hex is typed', function () {
216
+ renderColorCard();
217
+ react_1.fireEvent.change(hexField(), { target: { value: '#0A103D' } });
218
+ expect(react_1.screen.getByRole('button', { name: 'Birincil renk' })).toHaveStyle({
219
+ backgroundColor: 'rgb(10, 16, 61)',
220
+ });
221
+ });
222
+ it('updates the hex field when the picker changes', function () {
223
+ renderColorCard();
224
+ react_1.fireEvent.click(react_1.screen.getByRole('button', { name: 'Birincil renk' }));
225
+ var hue = react_1.screen.getByRole('slider', { name: 'colorHue' });
226
+ mockRect(hue, 360, 12);
227
+ react_1.fireEvent.pointerDown(hue, { clientX: 0, clientY: 6, buttons: 1, pointerId: 1 });
228
+ expect(hexField()).toHaveDisplayValue(/^#[0-9A-F]{6}$/);
229
+ expect(hexField()).not.toHaveDisplayValue('#9763F6');
230
+ });
231
+ it('opens the color picker from the swatch', function () {
232
+ renderColorCard();
233
+ react_1.fireEvent.click(react_1.screen.getByRole('button', { name: 'Birincil renk' }));
234
+ expect(react_1.screen.getByRole('dialog', { name: 'pickColor' })).toBeInTheDocument();
235
+ });
236
+ it('does not open the picker when disabled', function () {
237
+ renderColorCard({ disabled: true });
238
+ react_1.fireEvent.click(react_1.screen.getByRole('button', { name: 'Birincil renk' }));
239
+ expect(react_1.screen.queryByRole('dialog')).not.toBeInTheDocument();
240
+ });
241
+ it('renders error message when hasError is true', function () {
242
+ renderColorCard({ hasError: true, errorMessage: 'Geçersiz renk' });
243
+ expect(react_1.screen.getByText('Geçersiz renk')).toBeInTheDocument();
244
+ });
245
+ it('renders title, hint and value as text, not HTML', function () {
246
+ renderColorCard({
247
+ title: '<script>alert(1)</script>',
248
+ hint: '<img src=x onerror=alert(1)>',
249
+ value: '<script>alert(1)</script>',
250
+ });
251
+ expect(react_1.screen.getByText('<script>alert(1)</script>')).toBeInTheDocument();
252
+ expect(react_1.screen.getByText('<img src=x onerror=alert(1)>')).toBeInTheDocument();
253
+ expect(react_1.screen.getByDisplayValue(/^#[0-9A-Fa-f]{0,6}$/)).toBeInTheDocument();
254
+ expect(document.querySelector('script')).not.toBeInTheDocument();
255
+ expect(document.querySelector('img')).not.toBeInTheDocument();
256
+ });
257
+ });
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ type ColorPickerProps = {
3
+ value: string;
4
+ onChange(hex: string): void;
5
+ };
6
+ declare const ColorPicker: ({ value, onChange }: ColorPickerProps) => React.JSX.Element;
7
+ export default ColorPicker;
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ var jsx_runtime_1 = require("react/jsx-runtime");
15
+ var react_1 = require("react");
16
+ var react_i18next_1 = require("react-i18next");
17
+ var ColorCard_styled_1 = require("./ColorCard.styled");
18
+ var color_1 = require("./utils/color");
19
+ var FALLBACK_HSV = { h: 0, s: 0, v: 0 };
20
+ var toHsv = function (value, fallback) {
21
+ if (fallback === void 0) { fallback = FALLBACK_HSV; }
22
+ var next = (0, color_1.hexToHsv)(value);
23
+ if (!next)
24
+ return fallback;
25
+ if (next.s === 0)
26
+ return __assign(__assign({}, next), { h: fallback.h });
27
+ return next;
28
+ };
29
+ var ColorPicker = function (_a) {
30
+ var value = _a.value, onChange = _a.onChange;
31
+ var t = (0, react_i18next_1.useTranslation)().t;
32
+ var _b = (0, react_1.useState)(function () { return toHsv(value); }), hsv = _b[0], setHsv = _b[1];
33
+ (0, react_1.useEffect)(function () {
34
+ setHsv(function (current) {
35
+ var next = toHsv(value, current);
36
+ if (next.h === current.h && next.s === current.s && next.v === current.v)
37
+ return current;
38
+ return next;
39
+ });
40
+ }, [value]);
41
+ var commit = function (next) {
42
+ setHsv(next);
43
+ onChange((0, color_1.hsvToHex)(next.h, next.s, next.v));
44
+ };
45
+ var pointFromEvent = function (event) {
46
+ var rect = event.currentTarget.getBoundingClientRect();
47
+ var clientX = Number.isFinite(event.clientX) ? event.clientX : 0;
48
+ var clientY = Number.isFinite(event.clientY) ? event.clientY : 0;
49
+ return {
50
+ x: (0, color_1.clamp)((clientX - rect.left) / (rect.width || 1), 0, 1),
51
+ y: (0, color_1.clamp)((clientY - rect.top) / (rect.height || 1), 0, 1),
52
+ };
53
+ };
54
+ var handleSaturation = function (event) {
55
+ if (event.buttons !== 1 && event.type !== 'pointerdown')
56
+ return;
57
+ var _a = pointFromEvent(event), x = _a.x, y = _a.y;
58
+ commit(__assign(__assign({}, hsv), { s: x, v: 1 - y }));
59
+ };
60
+ var handleHue = function (event) {
61
+ if (event.buttons !== 1 && event.type !== 'pointerdown')
62
+ return;
63
+ commit(__assign(__assign({}, hsv), { h: pointFromEvent(event).x * 360 }));
64
+ };
65
+ var bindDrag = function (handler) { return ({
66
+ onPointerDown: function (event) {
67
+ var _a, _b;
68
+ (_b = (_a = event.currentTarget).setPointerCapture) === null || _b === void 0 ? void 0 : _b.call(_a, event.pointerId);
69
+ handler(event);
70
+ },
71
+ onPointerMove: handler,
72
+ }); };
73
+ return ((0, jsx_runtime_1.jsxs)(ColorCard_styled_1.PickerBody, { children: [(0, jsx_runtime_1.jsx)(ColorCard_styled_1.Saturation, __assign({ "$hue": hsv.h, role: "slider", "aria-label": t('colorSaturation'), "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(hsv.s * 100) }, bindDrag(handleSaturation), { children: (0, jsx_runtime_1.jsx)(ColorCard_styled_1.Thumb, { "$x": hsv.s, "$y": 1 - hsv.v }) })), (0, jsx_runtime_1.jsx)(ColorCard_styled_1.HueSlider, __assign({ role: "slider", "aria-label": t('colorHue'), "aria-valuemin": 0, "aria-valuemax": 360, "aria-valuenow": Math.round(hsv.h) }, bindDrag(handleHue), { children: (0, jsx_runtime_1.jsx)(ColorCard_styled_1.Thumb, { "$x": hsv.h / 360, "$y": 0.5 }) }))] }));
74
+ };
75
+ exports.default = ColorPicker;
@@ -0,0 +1 @@
1
+ export { default } from './ColorCard';
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = void 0;
7
+ var ColorCard_1 = require("./ColorCard");
8
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(ColorCard_1).default; } });
@@ -0,0 +1,18 @@
1
+ export interface ColorCard {
2
+ title?: string;
3
+ hint?: string;
4
+ value?: string;
5
+ placeholder?: string;
6
+ hasError?: boolean;
7
+ errorMessage?: string;
8
+ disabled?: boolean;
9
+ name?: string;
10
+ id?: string;
11
+ onChange?(e: any): void;
12
+ }
13
+ export interface ColorCardStyledProps {
14
+ $color?: string;
15
+ $disabled?: boolean;
16
+ }
17
+ export declare const ColorCardDefault: ColorCard;
18
+ export type ColorCardProps = typeof ColorCardDefault;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ColorCardDefault = void 0;
4
+ exports.ColorCardDefault = {
5
+ title: '',
6
+ hint: '',
7
+ value: '',
8
+ placeholder: '#000000',
9
+ hasError: false,
10
+ errorMessage: '',
11
+ disabled: false,
12
+ name: null,
13
+ id: null,
14
+ onChange: null,
15
+ };
@@ -0,0 +1,106 @@
1
+ import React from 'react';
2
+ declare const _default: {
3
+ title: string;
4
+ component: (props: any) => React.JSX.Element;
5
+ tags: string[];
6
+ argTypes: {
7
+ title: {
8
+ control: string;
9
+ };
10
+ hint: {
11
+ control: string;
12
+ };
13
+ value: {
14
+ control: string;
15
+ };
16
+ placeholder: {
17
+ control: string;
18
+ };
19
+ hasError: {
20
+ control: string;
21
+ };
22
+ errorMessage: {
23
+ control: string;
24
+ };
25
+ disabled: {
26
+ control: string;
27
+ };
28
+ onChange: {
29
+ action: string;
30
+ };
31
+ };
32
+ };
33
+ export default _default;
34
+ export declare const Default: {
35
+ args: {
36
+ title: string;
37
+ hint: string;
38
+ value: string;
39
+ placeholder: string;
40
+ hasError: boolean;
41
+ errorMessage: string;
42
+ disabled: boolean;
43
+ id: string;
44
+ name: string;
45
+ onChange: (e: any) => void;
46
+ };
47
+ };
48
+ export declare const TextColor: {
49
+ args: {
50
+ title: string;
51
+ hint: string;
52
+ value: string;
53
+ id: string;
54
+ name: string;
55
+ placeholder: string;
56
+ hasError: boolean;
57
+ errorMessage: string;
58
+ disabled: boolean;
59
+ onChange: (e: any) => void;
60
+ };
61
+ };
62
+ export declare const Empty: {
63
+ args: {
64
+ title: string;
65
+ hint: string;
66
+ value: string;
67
+ id: string;
68
+ name: string;
69
+ placeholder: string;
70
+ hasError: boolean;
71
+ errorMessage: string;
72
+ disabled: boolean;
73
+ onChange: (e: any) => void;
74
+ };
75
+ };
76
+ export declare const WithError: {
77
+ args: {
78
+ value: string;
79
+ hasError: boolean;
80
+ errorMessage: string;
81
+ id: string;
82
+ title: string;
83
+ hint: string;
84
+ placeholder: string;
85
+ disabled: boolean;
86
+ name: string;
87
+ onChange: (e: any) => void;
88
+ };
89
+ };
90
+ export declare const Disabled: {
91
+ args: {
92
+ disabled: boolean;
93
+ id: string;
94
+ title: string;
95
+ hint: string;
96
+ value: string;
97
+ placeholder: string;
98
+ hasError: boolean;
99
+ errorMessage: string;
100
+ name: string;
101
+ onChange: (e: any) => void;
102
+ };
103
+ };
104
+ export declare const Palette: {
105
+ render: () => React.JSX.Element;
106
+ };
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.Palette = exports.Disabled = exports.WithError = exports.Empty = exports.TextColor = exports.Default = void 0;
18
+ var jsx_runtime_1 = require("react/jsx-runtime");
19
+ var react_1 = require("react");
20
+ var ColorCard_1 = __importDefault(require("../ColorCard"));
21
+ var baseArgs = {
22
+ title: 'Birincil renk',
23
+ hint: 'Ana buton ve vurgular',
24
+ value: '#9763F6',
25
+ placeholder: '#000000',
26
+ hasError: false,
27
+ errorMessage: '',
28
+ disabled: false,
29
+ id: 'color-card-primary',
30
+ name: 'primaryColor',
31
+ onChange: function (e) {
32
+ var _a;
33
+ console.log((_a = e === null || e === void 0 ? void 0 : e.target) === null || _a === void 0 ? void 0 : _a.value, 'onChange');
34
+ },
35
+ };
36
+ exports.default = {
37
+ title: 'Components/Color Card',
38
+ component: function (props) { return ((0, jsx_runtime_1.jsx)("div", __assign({ style: { maxWidth: '480px' } }, { children: (0, jsx_runtime_1.jsx)(ColorCard_1.default, __assign({}, props)) }))); },
39
+ tags: ['autodocs'],
40
+ argTypes: {
41
+ title: { control: 'text' },
42
+ hint: { control: 'text' },
43
+ value: { control: 'text' },
44
+ placeholder: { control: 'text' },
45
+ hasError: { control: 'boolean' },
46
+ errorMessage: { control: 'text' },
47
+ disabled: { control: 'boolean' },
48
+ onChange: { action: 'changed' },
49
+ },
50
+ };
51
+ exports.Default = {
52
+ args: __assign({}, baseArgs),
53
+ };
54
+ exports.TextColor = {
55
+ args: __assign(__assign({}, baseArgs), { title: 'Metin rengi', hint: 'Ana metin ve başlıklar', value: '#0A103D', id: 'color-card-text', name: 'textColor' }),
56
+ };
57
+ exports.Empty = {
58
+ args: __assign(__assign({}, baseArgs), { title: 'Arka plan rengi', hint: 'Sayfa arka planı', value: '', id: 'color-card-empty', name: 'backgroundColor' }),
59
+ };
60
+ exports.WithError = {
61
+ args: __assign(__assign({}, baseArgs), { value: '9763F6', hasError: true, errorMessage: 'Geçerli bir hex renk kodu gir', id: 'color-card-error' }),
62
+ };
63
+ exports.Disabled = {
64
+ args: __assign(__assign({}, baseArgs), { disabled: true, id: 'color-card-disabled' }),
65
+ };
66
+ var PaletteStory = function () {
67
+ var _a = (0, react_1.useState)('#9763F6'), primary = _a[0], setPrimary = _a[1];
68
+ var _b = (0, react_1.useState)('#0A103D'), text = _b[0], setText = _b[1];
69
+ return ((0, jsx_runtime_1.jsxs)("div", __assign({ style: { display: 'flex', flexDirection: 'column', gap: '1rem', maxWidth: '480px' } }, { children: [(0, jsx_runtime_1.jsx)(ColorCard_1.default, { title: "Birincil renk", hint: "Ana buton ve vurgular", value: primary, id: "palette-primary", name: "primaryColor", onChange: function (e) { var _a, _b; return setPrimary((_b = (_a = e === null || e === void 0 ? void 0 : e.target) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : ''); } }), (0, jsx_runtime_1.jsx)(ColorCard_1.default, { title: "Metin rengi", hint: "Ana metin ve ba\u015Fl\u0131klar", value: text, id: "palette-text", name: "textColor", onChange: function (e) { var _a, _b; return setText((_b = (_a = e === null || e === void 0 ? void 0 : e.target) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : ''); } })] })));
70
+ };
71
+ exports.Palette = {
72
+ render: function () { return (0, jsx_runtime_1.jsx)(PaletteStory, {}); },
73
+ };
@@ -0,0 +1,17 @@
1
+ export type Hsv = {
2
+ h: number;
3
+ s: number;
4
+ v: number;
5
+ };
6
+ export declare const isHexInputValue: (value: string) => boolean;
7
+ export declare const clamp: (value: number, min: number, max: number) => number;
8
+ export declare const formatHexInput: (value?: string) => string;
9
+ export declare const nextHexInput: (previous: string, next?: string) => string;
10
+ export declare const toSwatchColor: (value?: string) => string;
11
+ export declare const normalizeHex: (value?: string) => string;
12
+ export declare const hexToRgb: (value?: string) => [number, number, number] | undefined;
13
+ export declare const rgbToHex: (r: number, g: number, b: number) => string;
14
+ export declare const rgbToHsv: (r: number, g: number, b: number) => Hsv;
15
+ export declare const hsvToRgb: (h: number, s: number, v: number) => [number, number, number];
16
+ export declare const hexToHsv: (value?: string) => Hsv;
17
+ export declare const hsvToHex: (h: number, s: number, v: number) => string;
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hsvToHex = exports.hexToHsv = exports.hsvToRgb = exports.rgbToHsv = exports.rgbToHex = exports.hexToRgb = exports.normalizeHex = exports.toSwatchColor = exports.nextHexInput = exports.formatHexInput = exports.clamp = exports.isHexInputValue = void 0;
4
+ var HEX_COLOR_PATTERN = /^#(?:[0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/;
5
+ var HEX_INPUT_PATTERN = /^#[0-9A-Fa-f]{0,6}$/;
6
+ var isHexInputValue = function (value) { return HEX_INPUT_PATTERN.test(value); };
7
+ exports.isHexInputValue = isHexInputValue;
8
+ var clamp = function (value, min, max) {
9
+ if (!Number.isFinite(value))
10
+ return min;
11
+ return Math.min(max, Math.max(min, value));
12
+ };
13
+ exports.clamp = clamp;
14
+ var formatHexInput = function (value) {
15
+ var raw = typeof value === 'string' ? value : '';
16
+ var digits = raw.replace(/#/g, '').replace(/[^0-9A-Fa-f]/g, '').slice(0, 6);
17
+ return "#".concat(digits);
18
+ };
19
+ exports.formatHexInput = formatHexInput;
20
+ var nextHexInput = function (previous, next) {
21
+ var prev = (0, exports.isHexInputValue)(previous) ? previous : (0, exports.formatHexInput)(previous);
22
+ var raw = typeof next === 'string' ? next : '';
23
+ if ((0, exports.isHexInputValue)(raw))
24
+ return raw;
25
+ var insertedOne = raw.length === prev.length + 1;
26
+ var replacedInPlace = raw.length === prev.length && raw.startsWith('#');
27
+ if ((insertedOne || replacedInPlace) && raw.startsWith('#'))
28
+ return prev;
29
+ return (0, exports.formatHexInput)(raw);
30
+ };
31
+ exports.nextHexInput = nextHexInput;
32
+ var toSwatchColor = function (value) {
33
+ if (typeof value !== 'string')
34
+ return undefined;
35
+ var color = value.trim();
36
+ return HEX_COLOR_PATTERN.test(color) ? color : undefined;
37
+ };
38
+ exports.toSwatchColor = toSwatchColor;
39
+ var normalizeHex = function (value) {
40
+ var color = (0, exports.toSwatchColor)(value);
41
+ if (!color)
42
+ return undefined;
43
+ if (color.length === 4) {
44
+ return "#".concat(color[1]).concat(color[1]).concat(color[2]).concat(color[2]).concat(color[3]).concat(color[3]).toUpperCase();
45
+ }
46
+ return color.toUpperCase();
47
+ };
48
+ exports.normalizeHex = normalizeHex;
49
+ var hexToRgb = function (value) {
50
+ var hex = (0, exports.normalizeHex)(value);
51
+ if (!hex)
52
+ return undefined;
53
+ return [
54
+ parseInt(hex.slice(1, 3), 16),
55
+ parseInt(hex.slice(3, 5), 16),
56
+ parseInt(hex.slice(5, 7), 16),
57
+ ];
58
+ };
59
+ exports.hexToRgb = hexToRgb;
60
+ var rgbToHex = function (r, g, b) {
61
+ var toHex = function (channel) { return (0, exports.clamp)(Math.round(channel), 0, 255).toString(16).padStart(2, '0'); };
62
+ return "#".concat(toHex(r)).concat(toHex(g)).concat(toHex(b)).toUpperCase();
63
+ };
64
+ exports.rgbToHex = rgbToHex;
65
+ var rgbToHsv = function (r, g, b) {
66
+ var red = r / 255;
67
+ var green = g / 255;
68
+ var blue = b / 255;
69
+ var max = Math.max(red, green, blue);
70
+ var min = Math.min(red, green, blue);
71
+ var delta = max - min;
72
+ var h = 0;
73
+ if (delta !== 0) {
74
+ if (max === red)
75
+ h = ((green - blue) / delta) % 6;
76
+ else if (max === green)
77
+ h = (blue - red) / delta + 2;
78
+ else
79
+ h = (red - green) / delta + 4;
80
+ h *= 60;
81
+ if (h < 0)
82
+ h += 360;
83
+ }
84
+ return {
85
+ h: h,
86
+ s: max === 0 ? 0 : delta / max,
87
+ v: max,
88
+ };
89
+ };
90
+ exports.rgbToHsv = rgbToHsv;
91
+ var hsvToRgb = function (h, s, v) {
92
+ var _a, _b, _c, _d, _e, _f;
93
+ var chroma = v * s;
94
+ var x = chroma * (1 - Math.abs(((h / 60) % 2) - 1));
95
+ var m = v - chroma;
96
+ var red = 0;
97
+ var green = 0;
98
+ var blue = 0;
99
+ if (h < 60)
100
+ _a = [chroma, x, 0], red = _a[0], green = _a[1], blue = _a[2];
101
+ else if (h < 120)
102
+ _b = [x, chroma, 0], red = _b[0], green = _b[1], blue = _b[2];
103
+ else if (h < 180)
104
+ _c = [0, chroma, x], red = _c[0], green = _c[1], blue = _c[2];
105
+ else if (h < 240)
106
+ _d = [0, x, chroma], red = _d[0], green = _d[1], blue = _d[2];
107
+ else if (h < 300)
108
+ _e = [x, 0, chroma], red = _e[0], green = _e[1], blue = _e[2];
109
+ else
110
+ _f = [chroma, 0, x], red = _f[0], green = _f[1], blue = _f[2];
111
+ return [(red + m) * 255, (green + m) * 255, (blue + m) * 255];
112
+ };
113
+ exports.hsvToRgb = hsvToRgb;
114
+ var hexToHsv = function (value) {
115
+ var rgb = (0, exports.hexToRgb)(value);
116
+ if (!rgb)
117
+ return undefined;
118
+ return (0, exports.rgbToHsv)(rgb[0], rgb[1], rgb[2]);
119
+ };
120
+ exports.hexToHsv = hexToHsv;
121
+ var hsvToHex = function (h, s, v) {
122
+ var rgb = (0, exports.hsvToRgb)(h, s, v);
123
+ return (0, exports.rgbToHex)(rgb[0], rgb[1], rgb[2]);
124
+ };
125
+ exports.hsvToHex = hsvToHex;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var color_1 = require("./color");
4
+ describe('formatHexInput', function () {
5
+ it('keeps a hash prefix and at most 6 hex digits', function () {
6
+ expect((0, color_1.formatHexInput)('')).toBe('#');
7
+ expect((0, color_1.formatHexInput)('abc')).toBe('#abc');
8
+ expect((0, color_1.formatHexInput)('##gg12abZZ')).toBe('#12ab');
9
+ expect((0, color_1.formatHexInput)('#9763F6extra')).toBe('#9763F6');
10
+ });
11
+ });
12
+ describe('nextHexInput', function () {
13
+ it('accepts a valid hex draft', function () {
14
+ expect((0, color_1.nextHexInput)('#', '#a')).toBe('#a');
15
+ expect((0, color_1.nextHexInput)('#a', '#ad')).toBe('#ad');
16
+ expect((0, color_1.nextHexInput)('#ad', '#ad1')).toBe('#ad1');
17
+ });
18
+ it('ignores a single invalid letter instead of stripping it', function () {
19
+ expect((0, color_1.nextHexInput)('#a', '#as')).toBe('#a');
20
+ expect((0, color_1.nextHexInput)('#ACE', '#AsCE')).toBe('#ACE');
21
+ expect((0, color_1.nextHexInput)('#ab', '#as')).toBe('#ab');
22
+ });
23
+ it('does not pull the next hex digit over an ignored letter', function () {
24
+ expect((0, color_1.nextHexInput)('#a', '#as')).toBe('#a');
25
+ expect((0, color_1.nextHexInput)('#a', '#ad')).toBe('#ad');
26
+ });
27
+ it('sanitizes paste and missing hash', function () {
28
+ expect((0, color_1.nextHexInput)('#9763F6', '##zz0a103dzzzz')).toBe('#0a103d');
29
+ expect((0, color_1.nextHexInput)('#ab', 'ab')).toBe('#ab');
30
+ expect((0, color_1.nextHexInput)('#a', '')).toBe('#');
31
+ });
32
+ });
33
+ describe('toSwatchColor', function () {
34
+ it('accepts 3 and 6 digit hex colors', function () {
35
+ expect((0, color_1.toSwatchColor)('#0Af')).toBe('#0Af');
36
+ expect((0, color_1.toSwatchColor)(' #9763F6 ')).toBe('#9763F6');
37
+ });
38
+ it('rejects values that are not hex colors', function () {
39
+ expect((0, color_1.toSwatchColor)('')).toBeUndefined();
40
+ expect((0, color_1.toSwatchColor)('red')).toBeUndefined();
41
+ expect((0, color_1.toSwatchColor)('#gggggg')).toBeUndefined();
42
+ expect((0, color_1.toSwatchColor)('#9763F6; background: red')).toBeUndefined();
43
+ });
44
+ });
45
+ describe('normalizeHex', function () {
46
+ it('expands 3 digit hex and uppercases', function () {
47
+ expect((0, color_1.normalizeHex)('#0Af')).toBe('#00AAFF');
48
+ expect((0, color_1.normalizeHex)(' #9763f6 ')).toBe('#9763F6');
49
+ });
50
+ });
51
+ describe('hsv hex roundtrip', function () {
52
+ it.each(['#000000', '#FFFFFF', '#FF0000', '#00FF00', '#0000FF', '#9763F6', '#0A103D'])('converts %s through HSV back to the same hex', function (hex) {
53
+ var hsv = (0, color_1.hexToHsv)(hex);
54
+ expect(hsv).toBeDefined();
55
+ expect((0, color_1.hsvToHex)(hsv.h, hsv.s, hsv.v)).toBe(hex);
56
+ });
57
+ });
@@ -13,7 +13,7 @@ exports.ColorPaletteStyled = styled_components_1.default.div(templateObject_1 ||
13
13
  exports.ColorItem = styled_components_1.default.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n border: 1px solid var(--dark-opacity-10);\n display: block;\n border-radius: 1rem;\n position: relative;\n overflow: hidden;\n"], ["\n border: 1px solid var(--dark-opacity-10);\n display: block;\n border-radius: 1rem;\n position: relative;\n overflow: hidden;\n"])));
14
14
  exports.Bg = styled_components_1.default.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n min-height: 120px;\n background: ", "};\n"], ["\n min-height: 120px;\n background: ", "};\n"])), function (props) {
15
15
  var _a;
16
- return ((_a = props === null || props === void 0 ? void 0 : props.gradient) === null || _a === void 0 ? void 0 : _a.length)
16
+ return ((_a = props === null || props === void 0 ? void 0 : props.gradient) === null || _a === void 0 ? void 0 : _a.length) > 0
17
17
  ? "linear-gradient(0deg, ".concat(props.gradient.join(","), ")")
18
18
  : props.data.hex;
19
19
  });
@@ -104,6 +104,50 @@ var Input = function (_a) {
104
104
  }, [dateInputRef, format, hasCopyButton, hasError, id, infoText, inputValue, isCalendarOpen, isClearable, type]);
105
105
  var handleFocus = function () { return setIsFocused(true); };
106
106
  var handleBlur = function () { return setIsFocused(false); };
107
+ var isControlled = value !== undefined;
108
+ var fieldValue = isControlled ? value : (inputValue !== null && inputValue !== void 0 ? inputValue : '');
109
+ var fieldValueRef = (0, react_1.useRef)(fieldValue);
110
+ fieldValueRef.current = fieldValue;
111
+ var selectionRef = (0, react_1.useRef)({ start: 0, end: 0 });
112
+ var rememberSelection = function (event) {
113
+ var _a, _b;
114
+ var input = event.currentTarget;
115
+ selectionRef.current = {
116
+ start: (_a = input.selectionStart) !== null && _a !== void 0 ? _a : 0,
117
+ end: (_b = input.selectionEnd) !== null && _b !== void 0 ? _b : 0,
118
+ };
119
+ };
120
+ var restoreField = function (input, nextValue, start, end) {
121
+ input.value = nextValue;
122
+ try {
123
+ input.setSelectionRange(start, end);
124
+ }
125
+ catch (_a) {
126
+ // jsdom can throw if the node is not focused
127
+ }
128
+ };
129
+ var handleTextChange = function (event) {
130
+ var next = event.currentTarget.value;
131
+ var prev = fieldValue !== null && fieldValue !== void 0 ? fieldValue : '';
132
+ var _a = selectionRef.current, start = _a.start, end = _a.end;
133
+ var replacedAll = prev.length > 1 && start === 0 && end === prev.length;
134
+ var collapsedByMaxLength = maxLength != null && prev.length >= maxLength && next.length <= 1 && !replacedAll;
135
+ if (collapsedByMaxLength) {
136
+ restoreField(event.currentTarget, prev, start, end);
137
+ return;
138
+ }
139
+ onChange === null || onChange === void 0 ? void 0 : onChange(event);
140
+ if (!isControlled) {
141
+ setInputValue(next);
142
+ return;
143
+ }
144
+ var input = event.currentTarget;
145
+ queueMicrotask(function () {
146
+ if (fieldValueRef.current !== prev)
147
+ return;
148
+ restoreField(input, prev, start, end);
149
+ });
150
+ };
107
151
  var handleClearValue = function () {
108
152
  var _a, _b;
109
153
  setInputValue('');
@@ -117,16 +161,13 @@ var Input = function (_a) {
117
161
  onChange === null || onChange === void 0 ? void 0 : onChange(null);
118
162
  onClear === null || onClear === void 0 ? void 0 : onClear();
119
163
  };
120
- var currentLength = (inputValue !== null && inputValue !== void 0 ? inputValue : '').length;
164
+ var currentLength = (fieldValue !== null && fieldValue !== void 0 ? fieldValue : '').length;
121
165
  var showCharCount = showMaxLengthCounter && maxLength != null;
122
166
  var showTopRow = Boolean(label || customLinkText || showCharCount);
123
- var hasInputIcon = (isClearable && inputValue) || ['password', 'date'].includes(type) || hasCopyButton || infoText;
167
+ var hasInputIcon = (isClearable && fieldValue) || ['password', 'date'].includes(type) || hasCopyButton || infoText;
124
168
  return ((0, jsx_runtime_1.jsxs)(Input_styled_1.Container, __assign({ "$width": width }, { children: [showTopRow && ((0, jsx_runtime_1.jsxs)(Input_styled_1.FieldTop, { children: [label ? (0, jsx_runtime_1.jsx)(Input_styled_1.FieldLabel, __assign({ htmlFor: id }, { children: label })) : (0, jsx_runtime_1.jsx)("span", {}), (0, jsx_runtime_1.jsxs)(Input_styled_1.FieldTopActions, { children: [showCharCount && ((0, jsx_runtime_1.jsxs)(Input_styled_1.CharCount, { children: [currentLength, "/", maxLength] })), customLinkText && ((0, jsx_runtime_1.jsx)(TextLink_1.default, __assign({}, (customLinkHref && { href: customLinkHref }), { onClick: onCustomLinkClick }, { children: customLinkText })))] })] })), (0, jsx_runtime_1.jsxs)("div", __assign({ className: "input" }, { children: [hasNumericFormat ? ((0, jsx_runtime_1.jsx)(react_number_format_1.NumericFormat, __assign({ "$hasError": hasError, disabled: disabled, onChange: onChange, name: name, placeholder: placeholder, readOnly: readOnly, autoFocus: autoFocus, value: inputValue, maxLength: maxLength }, other, { customInput: Input_styled_1.InputStyled, id: id, onFocus: handleFocus, onBlur: handleBlur }))) : mask && format ? ((0, jsx_runtime_1.jsx)(react_number_format_1.PatternFormat, __assign({ "$hasError": hasError, disabled: disabled, onChange: onChange, name: name, placeholder: placeholder, readOnly: readOnly, autoFocus: autoFocus, value: inputValue, maxLength: maxLength }, other, { format: format, mask: mask, customInput: Input_styled_1.InputStyled, id: id, onFocus: handleFocus, onBlur: handleBlur }))) : type === 'date' ? ((0, jsx_runtime_1.jsx)(Input_styled_1.DatePickerWrapperStyled, __assign({ "$inline": inline }, { children: (0, jsx_runtime_1.jsx)(react_datepicker_1.default, __assign({ placeholderText: placeholder, disabled: disabled, name: name, readOnly: readOnly, autoFocus: autoFocus, onChange: handleDateChange, selected: startDate, ref: datePickerRef, id: id, dateFormat: "yyyy-MM-dd", locale: language === 'tr' ? locale_1.tr : locale_1.enGB, customInput: (0, jsx_runtime_1.jsx)(CustomDateInput, {}), inline: inline, minDate: minDate, maxDate: maxDate, filterDate: filterDate, renderCustomHeader: function (_a) {
125
169
  var monthDate = _a.monthDate, decreaseMonth = _a.decreaseMonth, increaseMonth = _a.increaseMonth, decreaseYear = _a.decreaseYear, increaseYear = _a.increaseYear, prevMonthButtonDisabled = _a.prevMonthButtonDisabled, nextMonthButtonDisabled = _a.nextMonthButtonDisabled, prevYearButtonDisabled = _a.prevYearButtonDisabled, nextYearButtonDisabled = _a.nextYearButtonDisabled;
126
170
  return ((0, jsx_runtime_1.jsxs)("div", __assign({ className: "headerTopContent" }, { children: [(0, jsx_runtime_1.jsxs)("div", __assign({ className: "leftButtons" }, { children: [(0, jsx_runtime_1.jsx)("button", __assign({ "aria-label": "Previous Year", className: "react-datepicker__navigation react-datepicker__navigation--previous", onClick: decreaseYear, type: "button", disabled: prevYearButtonDisabled }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { name: "CalenderArrowleftsmall" }) })), (0, jsx_runtime_1.jsx)("button", __assign({ "aria-label": "Previous Month", className: "react-datepicker__navigation react-datepicker__navigation--previous", onClick: decreaseMonth, type: "button", disabled: prevMonthButtonDisabled }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { name: "ArrowSmallLeft" }) }))] })), (0, jsx_runtime_1.jsxs)("span", __assign({ className: "react-datepicker__current-month" }, { children: [monthDate.toLocaleString(language === 'tr' ? 'tr-TR' : 'en-GB', { month: 'long' }), ",", ' ', monthDate.toLocaleString(language === 'tr' ? 'tr-TR' : 'en-GB', { year: 'numeric' })] })), (0, jsx_runtime_1.jsxs)("div", __assign({ className: "rightButtons" }, { children: [(0, jsx_runtime_1.jsx)("button", __assign({ "aria-label": "Next Month", className: "react-datepicker__navigation react-datepicker__navigation--next", onClick: increaseMonth, type: "button", disabled: nextMonthButtonDisabled }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { name: "ArrowSmallRight" }) })), (0, jsx_runtime_1.jsx)("button", __assign({ "aria-label": "Next Year", className: "react-datepicker__navigation react-datepicker__navigation--next", onClick: increaseYear, type: "button", disabled: nextYearButtonDisabled }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { name: "Calenderarrowrightsmall" }) }))] }))] })));
127
- } }, calendarControlProps)) }))) : ((0, jsx_runtime_1.jsx)(Input_styled_1.InputStyled, __assign({ ref: inputRef, type: inputType, "$hasError": hasError, disabled: disabled, onChange: function (e) {
128
- onChange === null || onChange === void 0 ? void 0 : onChange(e);
129
- setInputValue(e.currentTarget.value);
130
- }, name: name, placeholder: placeholder, readOnly: readOnly, autoFocus: autoFocus, value: inputValue, id: id, maxLength: maxLength, "$hasIcon": hasInputIcon }, other, { onFocus: handleFocus, onBlur: handleBlur }))), isClearable && inputValue ? ((0, jsx_runtime_1.jsx)("div", __assign({ onClick: handleClearValue, className: "removeIcon" }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { color: "var(--dark)", name: "Closebig" }) }))) : type === 'password' ? ((0, jsx_runtime_1.jsx)("div", __assign({ onClick: toggleInputType, className: "inputIcon hasNoBg" }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { color: "var(--dark-opacity-50)", name: inputType === 'password' ? 'Show' : 'Hide' }) }))) : type === 'date' && !inline ? ((0, jsx_runtime_1.jsx)("div", __assign({ className: "inputIcon hasNoBg hasNoCursor" }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { color: "var(--grey-50)", name: "Calendar" }) }))) : (hasCopyButton && ((0, jsx_runtime_1.jsx)("div", __assign({ onClick: copyToClipboard, className: "inputIcon" }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { color: "var(--primary)", name: "Copy" }) })))), infoText && ((0, jsx_runtime_1.jsx)("div", __assign({ className: "inputIcon hasNoBg" }, { children: (0, jsx_runtime_1.jsx)(Tooltip_1.default, __assign({ popupSize: "small", position: "topRight", popupWidth: "160px", popupRight: "-10px", iconWidth: "24px", iconHeight: "24px" }, { children: (0, jsx_runtime_1.jsx)(Input_styled_1.PopupText, { dangerouslySetInnerHTML: { __html: infoText } }) })) }))), tooltipText && ((0, jsx_runtime_1.jsx)(Input_styled_1.FocusTooltip, __assign({ "$isOpen": isFocused, "$maxWidth": tooltipWidth }, { children: (0, jsx_runtime_1.jsx)(Input_styled_1.PopupText, { dangerouslySetInnerHTML: { __html: tooltipText } }) }))), (0, jsx_runtime_1.jsx)(Input_styled_1.AlertStyled, __assign({ "$visible": alert }, { children: t('copied') }))] })), hasError && errorMessage && ((0, jsx_runtime_1.jsxs)("div", __assign({ className: "error" }, { children: [(0, jsx_runtime_1.jsx)(Icon_1.default, { name: "SwitchPassive" }), (0, jsx_runtime_1.jsx)("p", { children: errorMessage })] }))), description && (0, jsx_runtime_1.jsx)(Input_styled_1.FieldDescription, { children: description })] })));
171
+ } }, calendarControlProps)) }))) : ((0, jsx_runtime_1.jsx)(Input_styled_1.InputStyled, __assign({ ref: inputRef, type: inputType, "$hasError": hasError, disabled: disabled, name: name, placeholder: placeholder, readOnly: readOnly, autoFocus: autoFocus, value: fieldValue, id: id, maxLength: maxLength, "$hasIcon": hasInputIcon }, other, { onKeyDown: rememberSelection, onSelect: rememberSelection, onMouseUp: rememberSelection, onFocus: handleFocus, onBlur: handleBlur, onChange: handleTextChange }))), isClearable && fieldValue ? ((0, jsx_runtime_1.jsx)("div", __assign({ onClick: handleClearValue, className: "removeIcon" }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { color: "var(--dark)", name: "Closebig" }) }))) : type === 'password' ? ((0, jsx_runtime_1.jsx)("div", __assign({ onClick: toggleInputType, className: "inputIcon hasNoBg" }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { color: "var(--dark-opacity-50)", name: inputType === 'password' ? 'Show' : 'Hide' }) }))) : type === 'date' && !inline ? ((0, jsx_runtime_1.jsx)("div", __assign({ className: "inputIcon hasNoBg hasNoCursor" }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { color: "var(--grey-50)", name: "Calendar" }) }))) : (hasCopyButton && ((0, jsx_runtime_1.jsx)("div", __assign({ onClick: copyToClipboard, className: "inputIcon" }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { color: "var(--primary)", name: "Copy" }) })))), infoText && ((0, jsx_runtime_1.jsx)("div", __assign({ className: "inputIcon hasNoBg" }, { children: (0, jsx_runtime_1.jsx)(Tooltip_1.default, __assign({ popupSize: "small", position: "topRight", popupWidth: "160px", popupRight: "-10px", iconWidth: "24px", iconHeight: "24px" }, { children: (0, jsx_runtime_1.jsx)(Input_styled_1.PopupText, { dangerouslySetInnerHTML: { __html: infoText } }) })) }))), tooltipText && ((0, jsx_runtime_1.jsx)(Input_styled_1.FocusTooltip, __assign({ "$isOpen": isFocused, "$maxWidth": tooltipWidth }, { children: (0, jsx_runtime_1.jsx)(Input_styled_1.PopupText, { dangerouslySetInnerHTML: { __html: tooltipText } }) }))), (0, jsx_runtime_1.jsx)(Input_styled_1.AlertStyled, __assign({ "$visible": alert }, { children: t('copied') }))] })), hasError && errorMessage && ((0, jsx_runtime_1.jsxs)("div", __assign({ className: "error" }, { children: [(0, jsx_runtime_1.jsx)(Icon_1.default, { name: "SwitchPassive" }), (0, jsx_runtime_1.jsx)("p", { children: errorMessage })] }))), description && (0, jsx_runtime_1.jsx)(Input_styled_1.FieldDescription, { children: description })] })));
131
172
  };
132
173
  exports.default = Input;
@@ -51,7 +51,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
51
51
  };
52
52
  Object.defineProperty(exports, "__esModule", { value: true });
53
53
  var jsx_runtime_1 = require("react/jsx-runtime");
54
- var react_1 = require("@testing-library/react");
54
+ var react_1 = __importDefault(require("react"));
55
+ var react_2 = require("@testing-library/react");
55
56
  var user_event_1 = __importDefault(require("@testing-library/user-event"));
56
57
  var Input_1 = __importDefault(require("./Input"));
57
58
  var props_1 = require("./props");
@@ -62,17 +63,17 @@ jest.mock('react-i18next', function () { return ({
62
63
  }); });
63
64
  var renderInput = function (props) {
64
65
  if (props === void 0) { props = {}; }
65
- return (0, react_1.render)((0, jsx_runtime_1.jsx)(Input_1.default, __assign({}, props_1.InputDefault, { id: "input-test", label: "Label", onChange: jest.fn() }, props)));
66
+ return (0, react_2.render)((0, jsx_runtime_1.jsx)(Input_1.default, __assign({}, props_1.InputDefault, { id: "input-test", label: "Label", onChange: jest.fn() }, props)));
66
67
  };
67
68
  describe('Input', function () {
68
69
  it('renders label and placeholder', function () {
69
70
  renderInput({ placeholder: 'Placeholder text' });
70
- expect(react_1.screen.getByText('Label')).toBeInTheDocument();
71
- expect(react_1.screen.getByPlaceholderText('Placeholder text')).toBeInTheDocument();
71
+ expect(react_2.screen.getByText('Label')).toBeInTheDocument();
72
+ expect(react_2.screen.getByPlaceholderText('Placeholder text')).toBeInTheDocument();
72
73
  });
73
74
  it('shows error message when hasError is true', function () {
74
75
  renderInput({ hasError: true, errorMessage: 'Invalid value' });
75
- expect(react_1.screen.getByText('Invalid value')).toBeInTheDocument();
76
+ expect(react_2.screen.getByText('Invalid value')).toBeInTheDocument();
76
77
  });
77
78
  it('toggles password visibility', function () { return __awaiter(void 0, void 0, void 0, function () {
78
79
  var container, input;
@@ -80,7 +81,7 @@ describe('Input', function () {
80
81
  switch (_a.label) {
81
82
  case 0:
82
83
  container = renderInput({ type: 'password', placeholder: 'Password' }).container;
83
- input = react_1.screen.getByPlaceholderText('Password');
84
+ input = react_2.screen.getByPlaceholderText('Password');
84
85
  expect(input).toHaveAttribute('type', 'password');
85
86
  return [4 /*yield*/, user_event_1.default.click(container.querySelector('.inputIcon'))];
86
87
  case 1:
@@ -120,7 +121,7 @@ describe('Input', function () {
120
121
  });
121
122
  it('applies tooltipWidth to the focus tooltip', function () {
122
123
  renderInput({ tooltipText: 'Hint', tooltipWidth: '200px' });
123
- expect(react_1.screen.getByText('Hint').parentElement).toHaveStyle({ maxWidth: '200px' });
124
+ expect(react_2.screen.getByText('Hint').parentElement).toHaveStyle({ maxWidth: '200px' });
124
125
  });
125
126
  it('shows tooltip on focus and hides it on blur', function () { return __awaiter(void 0, void 0, void 0, function () {
126
127
  var tooltip;
@@ -128,22 +129,59 @@ describe('Input', function () {
128
129
  switch (_a.label) {
129
130
  case 0:
130
131
  renderInput({ tooltipText: 'Focus hint', placeholder: 'Type here' });
131
- tooltip = react_1.screen.getByText('Focus hint');
132
+ tooltip = react_2.screen.getByText('Focus hint');
132
133
  expect(tooltip).not.toBeVisible();
133
- return [4 /*yield*/, user_event_1.default.click(react_1.screen.getByPlaceholderText('Type here'))];
134
+ return [4 /*yield*/, user_event_1.default.click(react_2.screen.getByPlaceholderText('Type here'))];
134
135
  case 1:
135
136
  _a.sent();
136
- return [4 /*yield*/, (0, react_1.waitFor)(function () { return expect(tooltip).toBeVisible(); })];
137
+ return [4 /*yield*/, (0, react_2.waitFor)(function () { return expect(tooltip).toBeVisible(); })];
137
138
  case 2:
138
139
  _a.sent();
139
140
  return [4 /*yield*/, user_event_1.default.tab()];
140
141
  case 3:
141
142
  _a.sent();
142
- return [4 /*yield*/, (0, react_1.waitFor)(function () { return expect(tooltip).not.toBeVisible(); })];
143
+ return [4 /*yield*/, (0, react_2.waitFor)(function () { return expect(tooltip).not.toBeVisible(); })];
143
144
  case 4:
144
145
  _a.sent();
145
146
  return [2 /*return*/];
146
147
  }
147
148
  });
148
149
  }); });
150
+ it('keeps a full maxLength value when a single character is typed', function () {
151
+ var onChange = jest.fn();
152
+ renderInput({ value: 'ABCDEFG', maxLength: 7, mask: null, onChange: onChange });
153
+ react_2.fireEvent.change(react_2.screen.getByDisplayValue('ABCDEFG'), { target: { value: '1' } });
154
+ expect(onChange).not.toHaveBeenCalled();
155
+ expect(react_2.screen.getByDisplayValue('ABCDEFG')).toBeInTheDocument();
156
+ });
157
+ it('keeps the value prop when the parent rejects the change', function () {
158
+ var onChange = jest.fn();
159
+ renderInput({ value: '#a', mask: null, onChange: onChange });
160
+ react_2.fireEvent.change(react_2.screen.getByDisplayValue('#a'), { target: { value: '#as' } });
161
+ expect(onChange).toHaveBeenCalled();
162
+ expect(react_2.screen.getByDisplayValue('#a')).toBeInTheDocument();
163
+ });
164
+ it('follows parent state for a controlled edit', function () {
165
+ var Harness = function () {
166
+ var _a = react_1.default.useState('#a'), value = _a[0], setValue = _a[1];
167
+ return ((0, jsx_runtime_1.jsx)(Input_1.default, __assign({}, props_1.InputDefault, { id: "controlled-input", mask: null, value: value, onChange: function (event) {
168
+ var _a, _b;
169
+ var next = (_b = (_a = event === null || event === void 0 ? void 0 : event.target) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '';
170
+ if (/^#[0-9A-Fa-f]{0,6}$/.test(next))
171
+ setValue(next);
172
+ } })));
173
+ };
174
+ (0, react_2.render)((0, jsx_runtime_1.jsx)(Harness, {}));
175
+ react_2.fireEvent.change(react_2.screen.getByDisplayValue('#a'), { target: { value: '#as' } });
176
+ expect(react_2.screen.getByDisplayValue('#a')).toBeInTheDocument();
177
+ react_2.fireEvent.change(react_2.screen.getByDisplayValue('#a'), { target: { value: '#ad' } });
178
+ expect(react_2.screen.getByDisplayValue('#ad')).toBeInTheDocument();
179
+ });
180
+ it('accepts a normal edit below maxLength when uncontrolled', function () {
181
+ var onChange = jest.fn();
182
+ renderInput({ mask: null, onChange: onChange });
183
+ react_2.fireEvent.change(react_2.screen.getByRole('textbox'), { target: { value: 'ABCD' } });
184
+ expect(onChange).toHaveBeenCalled();
185
+ expect(react_2.screen.getByDisplayValue('ABCD')).toBeInTheDocument();
186
+ });
149
187
  });
@@ -15,5 +15,8 @@
15
15
  "NO_OPTIONS_FOUND": "Not found",
16
16
  "GO": "Go",
17
17
  "OPTIONAL": "Optional",
18
- "back": "Back"
18
+ "back": "Back",
19
+ "pickColor": "Pick color",
20
+ "colorHue": "Hue",
21
+ "colorSaturation": "Saturation and brightness"
19
22
  }
@@ -18,5 +18,8 @@
18
18
  "ALL_RENTED": "Hepsi kiralandı",
19
19
  "POST_COMMENTS": "Yorumlarını yayınla",
20
20
  "REMOVE_COMMENTS": "Yorumlarını kaldır",
21
- "back": "Geri dön"
21
+ "back": "Geri dön",
22
+ "pickColor": "Renk seç",
23
+ "colorHue": "Renk tonu",
24
+ "colorSaturation": "Doygunluk ve parlaklık"
22
25
  }
package/dist/index.d.ts CHANGED
@@ -65,4 +65,5 @@ import QuantitySelector from "./components/QuantitySelector";
65
65
  import Tag from "./components/Tag";
66
66
  import TagInput from "./components/TagInput";
67
67
  import RichTextEditor from "./components/RichTextEditor";
68
- export { Button, Breadcrumbs, CategoryMenu, Checkbox, CircleProgress, Input, Modal, OtpInput, Stepper, Alert, Agreement, Icon, RadioButton, ActionButton, Textarea, SearchBox, Divider, Accordion, toast, Toaster, SuggestBox, Badges, SelectBox, TextLink, Tooltip, InsuranceBox, ListGroup, InfoBox, CouponCode, ShoppingCartProduct, Loader, InlineProgress, Dropdown, CampaignCard, initReactI18next, initi18n, enLocale, trLocale, useTranslation, ReviewCard, AddressCard, InstallmentBox, AutocompleteInput, BannerCard, ProductCardVertical, ProductCardHorizontal, ProductCardHorizontalSm, ProductCardHorizontalMd, ProductCardCheckbox, ProductCardRadio, Tabs, PaymentCart, OptionMenu, DropdownButton, Table, DescriptionCard, Pagination, SkeletonLoader, RadioScale, BlogCard, ReviewBlock, VideoCard, StepSlider, RadioGroup, CheckboxGroup, QuantitySelector, Tag, TagInput, RichTextEditor };
68
+ import ColorCard from "./components/ColorCard";
69
+ export { Button, Breadcrumbs, CategoryMenu, Checkbox, CircleProgress, Input, Modal, OtpInput, Stepper, Alert, Agreement, Icon, RadioButton, ActionButton, Textarea, SearchBox, Divider, Accordion, toast, Toaster, SuggestBox, Badges, SelectBox, TextLink, Tooltip, InsuranceBox, ListGroup, InfoBox, CouponCode, ShoppingCartProduct, Loader, InlineProgress, Dropdown, CampaignCard, initReactI18next, initi18n, enLocale, trLocale, useTranslation, ReviewCard, AddressCard, InstallmentBox, AutocompleteInput, BannerCard, ProductCardVertical, ProductCardHorizontal, ProductCardHorizontalSm, ProductCardHorizontalMd, ProductCardCheckbox, ProductCardRadio, Tabs, PaymentCart, OptionMenu, DropdownButton, Table, DescriptionCard, Pagination, SkeletonLoader, RadioScale, BlogCard, ReviewBlock, VideoCard, StepSlider, RadioGroup, CheckboxGroup, QuantitySelector, Tag, TagInput, RichTextEditor, ColorCard };
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ProductCardRadio = exports.ProductCardCheckbox = exports.ProductCardHorizontalMd = exports.ProductCardHorizontalSm = exports.ProductCardHorizontal = exports.ProductCardVertical = exports.BannerCard = exports.AutocompleteInput = exports.InstallmentBox = exports.AddressCard = exports.ReviewCard = exports.useTranslation = exports.trLocale = exports.enLocale = exports.initi18n = exports.initReactI18next = exports.CampaignCard = exports.Dropdown = exports.InlineProgress = exports.Loader = exports.ShoppingCartProduct = exports.CouponCode = exports.InfoBox = exports.ListGroup = exports.InsuranceBox = exports.Tooltip = exports.TextLink = exports.SelectBox = exports.Badges = exports.SuggestBox = exports.Toaster = exports.toast = exports.Accordion = exports.Divider = exports.SearchBox = exports.Textarea = exports.ActionButton = exports.RadioButton = exports.Icon = exports.Agreement = exports.Alert = exports.Stepper = exports.OtpInput = exports.Modal = exports.Input = exports.CircleProgress = exports.Checkbox = exports.CategoryMenu = exports.Breadcrumbs = exports.Button = void 0;
7
- exports.RichTextEditor = exports.TagInput = exports.Tag = exports.QuantitySelector = exports.CheckboxGroup = exports.RadioGroup = exports.StepSlider = exports.VideoCard = exports.ReviewBlock = exports.BlogCard = exports.RadioScale = exports.SkeletonLoader = exports.Pagination = exports.DescriptionCard = exports.Table = exports.DropdownButton = exports.OptionMenu = exports.PaymentCart = exports.Tabs = void 0;
7
+ exports.ColorCard = exports.RichTextEditor = exports.TagInput = exports.Tag = exports.QuantitySelector = exports.CheckboxGroup = exports.RadioGroup = exports.StepSlider = exports.VideoCard = exports.ReviewBlock = exports.BlogCard = exports.RadioScale = exports.SkeletonLoader = exports.Pagination = exports.DescriptionCard = exports.Table = exports.DropdownButton = exports.OptionMenu = exports.PaymentCart = exports.Tabs = void 0;
8
8
  var react_i18next_1 = require("react-i18next");
9
9
  Object.defineProperty(exports, "initReactI18next", { enumerable: true, get: function () { return react_i18next_1.initReactI18next; } });
10
10
  Object.defineProperty(exports, "useTranslation", { enumerable: true, get: function () { return react_i18next_1.useTranslation; } });
@@ -141,3 +141,5 @@ var TagInput_1 = __importDefault(require("./components/TagInput"));
141
141
  exports.TagInput = TagInput_1.default;
142
142
  var RichTextEditor_1 = __importDefault(require("./components/RichTextEditor"));
143
143
  exports.RichTextEditor = RichTextEditor_1.default;
144
+ var ColorCard_1 = __importDefault(require("./components/ColorCard"));
145
+ exports.ColorCard = ColorCard_1.default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "krl-alfred",
3
- "version": "2.23.26",
3
+ "version": "2.24.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],