react-iro-gradient-picker 1.1.6 → 1.2.1

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/README.md CHANGED
@@ -124,7 +124,67 @@ function App() {
124
124
  export default App;
125
125
  ```
126
126
 
127
- ### 🌙 With Dark Theme Support
127
+ ### **NEW: Enhanced Gradient Object Support**
128
+
129
+ **v1.2.0+ supports both CSS strings AND gradient objects for maximum flexibility!**
130
+
131
+ ```tsx
132
+ import React, { useState } from 'react';
133
+ import ColorPicker from 'react-iro-gradient-picker';
134
+ import 'react-iro-gradient-picker/dist/index.css';
135
+
136
+ function GradientObjectExample() {
137
+ // Define gradient as an object
138
+ const [gradientData, setGradientData] = useState({
139
+ type: 'linear',
140
+ angle: 120,
141
+ stops: [
142
+ { color: '#FF6B6B', position: 0 }, // Red at 0%
143
+ { color: '#FFD93D', position: 50 }, // Yellow at 50%
144
+ { color: '#6BCB77', position: 100 } // Green at 100%
145
+ ]
146
+ });
147
+
148
+ return (
149
+ <ColorPicker
150
+ value={gradientData} // 🎯 Pass object directly!
151
+ onChange={(cssGradient) => {
152
+ console.log('Generated CSS:', cssGradient);
153
+ // Component auto-switches to gradient tab
154
+ // Sets angle to 120°, creates 3 stops with exact colors/positions
155
+ }}
156
+ gradient={true}
157
+ solid={true}
158
+ showGradientAngle={true}
159
+ showGradientStops={true}
160
+ />
161
+ );
162
+ }
163
+ ```
164
+
165
+ **🚀 What happens when you pass a gradient object:**
166
+
167
+ - ✅ **Auto-switches to gradient tab**
168
+ - ✅ **Sets angle slider to specified degrees** (120° in example)
169
+ - ✅ **Creates gradient stops** at exact positions (0%, 50%, 100%)
170
+ - ✅ **Sets stop colors** to specified values (#FF6B6B, #FFD93D, #6BCB77)
171
+ - ✅ **Updates gradient preview** to match exactly
172
+ - ✅ **Returns CSS gradient string** in onChange callback
173
+
174
+ **📋 Gradient Object Structure:**
175
+
176
+ ```typescript
177
+ interface IGradientData {
178
+ type: 'linear' | 'radial';
179
+ angle?: number; // For linear gradients (0-360 degrees)
180
+ stops: Array<{
181
+ color: string; // Any valid CSS color
182
+ position: number; // 0-100 (percentage)
183
+ }>;
184
+ }
185
+ ```
186
+
187
+ ### �🌙 With Dark Theme Support
128
188
 
129
189
  ```tsx
130
190
  import React, { useState } from 'react';
@@ -1,4 +1,4 @@
1
1
  import { FC } from 'react';
2
- import { IPropsComp } from '../../../../lib/types';
3
- declare const IroGradient: FC<IPropsComp>;
2
+ import { IPropsGradient } from '../../../../lib/types';
3
+ declare const IroGradient: FC<IPropsGradient>;
4
4
  export default IroGradient;
@@ -1,4 +1,4 @@
1
1
  import { FC } from 'react';
2
- import { IPropsComp } from '../../../../lib/types';
3
- declare const IroSolidColorPicker: FC<IPropsComp>;
2
+ import { IPropsSolid } from '../../../../lib/types';
3
+ declare const IroSolidColorPicker: FC<IPropsSolid>;
4
4
  export default IroSolidColorPicker;
@@ -1,4 +1,5 @@
1
- export declare const getIndexActiveTag: (value: string) => string;
1
+ import { TValueProp } from '../../../lib/types';
2
+ export declare const getIndexActiveTag: (value: TValueProp) => string;
2
3
  export declare const checkValidColorsArray: (arr: string[], type: "solid" | "grad") => string[];
3
4
  export declare const arraysEqual: (a: Array<any>, b: Array<any>) => boolean;
4
5
  export declare const shallowEqual: (object1: any, object2: any) => boolean;
package/dist/index.es.js CHANGED
@@ -6574,6 +6574,94 @@ var parseGradient = (function (str) {
6574
6574
  }
6575
6575
  });
6576
6576
 
6577
+ /**
6578
+ * Convert gradient object to CSS gradient string
6579
+ */
6580
+ function gradientObjectToCss(gradientData) {
6581
+ var type = gradientData.type, _a = gradientData.angle, angle = _a === void 0 ? 90 : _a, stops = gradientData.stops;
6582
+ // Convert stops to CSS format
6583
+ var cssStops = stops
6584
+ .sort(function (a, b) { return a.position - b.position; }) // Ensure stops are in order
6585
+ .map(function (stop) {
6586
+ var color = tinycolor(stop.color);
6587
+ return "".concat(color.toRgbString(), " ").concat(stop.position, "%");
6588
+ })
6589
+ .join(', ');
6590
+ if (type === 'linear') {
6591
+ return "linear-gradient(".concat(angle, "deg, ").concat(cssStops, ")");
6592
+ }
6593
+ else {
6594
+ return "radial-gradient(circle, ".concat(cssStops, ")");
6595
+ }
6596
+ }
6597
+ /**
6598
+ * Convert CSS gradient string to gradient object
6599
+ */
6600
+ function cssToGradientObject(cssGradient) {
6601
+ try {
6602
+ var parsed = parseGradient(cssGradient);
6603
+ if (!parsed) {
6604
+ return null;
6605
+ }
6606
+ var type = parsed.type, modifier = parsed.modifier, stops = parsed.stops;
6607
+ // Convert stops to object format
6608
+ var gradientStops = stops.map(function (stop) { return ({
6609
+ color: String(stop[0]), // Ensure it's a string
6610
+ position: Math.round(stop[1] * 100) // Convert to percentage
6611
+ }); });
6612
+ // Extract angle from modifier (for linear gradients)
6613
+ var angle = 90; // Default angle
6614
+ if (type === 'linear' && modifier && typeof modifier === 'string') {
6615
+ var angleMatch = modifier.match(/(\d+)deg/);
6616
+ if (angleMatch) {
6617
+ angle = parseInt(angleMatch[1], 10);
6618
+ }
6619
+ }
6620
+ return {
6621
+ type: type,
6622
+ angle: type === 'linear' ? angle : undefined,
6623
+ stops: gradientStops,
6624
+ defaultActiveTab: 'gradient'
6625
+ };
6626
+ }
6627
+ catch (error) {
6628
+ console.warn('Failed to parse CSS gradient:', error);
6629
+ return null;
6630
+ }
6631
+ }
6632
+ /**
6633
+ * Check if a value is a gradient object
6634
+ */
6635
+ function isGradientObject(value) {
6636
+ return (value &&
6637
+ typeof value === 'object' &&
6638
+ 'type' in value &&
6639
+ 'stops' in value &&
6640
+ Array.isArray(value.stops) &&
6641
+ value.stops.length > 0 &&
6642
+ value.stops.every(function (stop) {
6643
+ return stop &&
6644
+ typeof stop === 'object' &&
6645
+ 'color' in stop &&
6646
+ 'position' in stop &&
6647
+ typeof stop.position === 'number';
6648
+ }));
6649
+ }
6650
+ /**
6651
+ * Normalize value to always return a CSS gradient string
6652
+ */
6653
+ function normalizeGradientValue(value) {
6654
+ if (typeof value === 'string') {
6655
+ return value;
6656
+ }
6657
+ if (isGradientObject(value)) {
6658
+ return gradientObjectToCss(value);
6659
+ }
6660
+ // Fallback
6661
+ return 'linear-gradient(90deg, #ffffff 0%, #000000 100%)';
6662
+ }
6663
+ // End of file
6664
+
6577
6665
  var getAlphaValue = function (value) {
6578
6666
  value.replace(/%/i, '');
6579
6667
  if (value[0] === '0' && value.length > 1) {
@@ -6980,28 +7068,35 @@ IroColorPicker.displayName = 'IroColorPicker';
6980
7068
 
6981
7069
  var getIndexActiveTag = function (value) {
6982
7070
  var tab = 'solid';
6983
- var validValue = tinycolor(value).isValid();
6984
- if (value) {
6985
- if (value === 'transparent') {
6986
- tab = 'solid';
6987
- return tab;
6988
- }
6989
- if (validValue &&
6990
- !value.trim().startsWith('radial-gradient') &&
6991
- !value.trim().startsWith('linear-gradient')) {
6992
- tab = 'solid';
6993
- return tab;
6994
- }
6995
- var rgba = rgbaToArray(value);
6996
- if (rgba) {
6997
- if (isValidRgba([rgba[0], rgba[1], rgba[2]])) {
7071
+ // Handle gradient object
7072
+ if (isGradientObject(value)) {
7073
+ return 'gradient';
7074
+ }
7075
+ // Handle string value
7076
+ if (typeof value === 'string') {
7077
+ var validValue = tinycolor(value).isValid();
7078
+ if (value) {
7079
+ if (value === 'transparent') {
6998
7080
  tab = 'solid';
6999
7081
  return tab;
7000
7082
  }
7001
- }
7002
- else {
7003
- tab = 'gradient';
7004
- return tab;
7083
+ if (validValue &&
7084
+ !value.trim().startsWith('radial-gradient') &&
7085
+ !value.trim().startsWith('linear-gradient')) {
7086
+ tab = 'solid';
7087
+ return tab;
7088
+ }
7089
+ var rgba = rgbaToArray(value);
7090
+ if (rgba) {
7091
+ if (isValidRgba([rgba[0], rgba[1], rgba[2]])) {
7092
+ tab = 'solid';
7093
+ return tab;
7094
+ }
7095
+ }
7096
+ else {
7097
+ tab = 'gradient';
7098
+ return tab;
7099
+ }
7005
7100
  }
7006
7101
  }
7007
7102
  return tab;
@@ -7784,7 +7879,9 @@ var IroGradient = function (_a) {
7784
7879
  useEffect(function () {
7785
7880
  var initializeIroPicker = function () {
7786
7881
  var _a, _b;
7787
- if (((_b = (_a = iroPickerRef.current) === null || _a === void 0 ? void 0 : _a.colorPicker) === null || _b === void 0 ? void 0 : _b.color) && activeColor.hex) {
7882
+ if (((_b = (_a = iroPickerRef.current) === null || _a === void 0 ? void 0 : _a.colorPicker) === null || _b === void 0 ? void 0 : _b.color) &&
7883
+ activeColor.hex &&
7884
+ typeof activeColor.alpha === 'number') {
7788
7885
  console.log('🚀 Initializing iro picker with activeColor:', activeColor);
7789
7886
  // Wait a bit for the picker to be fully ready, then update
7790
7887
  setTimeout(function () {
@@ -7805,13 +7902,19 @@ var IroGradient = function (_a) {
7805
7902
  var handleSetActiveColor = useCallback(function (newActiveColor) {
7806
7903
  console.log('🎯 Gradient stop clicked, setting active color:', newActiveColor);
7807
7904
  setActiveColor(newActiveColor);
7808
- // Force immediate update of iro picker with longer delay for first-time reliability
7809
- setTimeout(function () {
7810
- updateIroPickerColor({
7811
- hex: newActiveColor.hex,
7812
- alpha: newActiveColor.alpha
7813
- });
7814
- }, 50); // Increased from 5ms to 50ms for better first-time success
7905
+ // Validate before updating iro picker
7906
+ if (newActiveColor.hex && typeof newActiveColor.alpha === 'number') {
7907
+ // Force immediate update of iro picker with longer delay for first-time reliability
7908
+ setTimeout(function () {
7909
+ updateIroPickerColor({
7910
+ hex: newActiveColor.hex,
7911
+ alpha: newActiveColor.alpha
7912
+ });
7913
+ }, 50); // Increased from 5ms to 50ms for better first-time success
7914
+ }
7915
+ else {
7916
+ console.log('⚠️ Skipping iro picker update in handleSetActiveColor - invalid data:', newActiveColor);
7917
+ }
7815
7918
  }, [updateIroPickerColor]);
7816
7919
  // Update iro picker when activeColor changes (e.g., clicking gradient stops)
7817
7920
  useEffect(function () {
@@ -7821,18 +7924,17 @@ var IroGradient = function (_a) {
7821
7924
  index: activeColor.index,
7822
7925
  loc: activeColor.loc
7823
7926
  });
7927
+ // Validate activeColor before proceeding
7928
+ if (!activeColor.hex || typeof activeColor.alpha !== 'number') {
7929
+ console.log('⚠️ Skipping iro picker update - invalid activeColor:', activeColor);
7930
+ return;
7931
+ }
7824
7932
  // Add a small delay to ensure the activeColor state has fully updated
7825
7933
  var timeoutId = setTimeout(function () {
7826
7934
  updateIroPickerColor({ hex: activeColor.hex, alpha: activeColor.alpha });
7827
7935
  }, 10);
7828
7936
  return function () { return clearTimeout(timeoutId); };
7829
- }, [
7830
- activeColor.hex,
7831
- activeColor.alpha,
7832
- activeColor.index,
7833
- activeColor.loc,
7834
- updateIroPickerColor
7835
- ]);
7937
+ }, [activeColor, updateIroPickerColor]);
7836
7938
  var updateGradient = useCallback(function (newColor) {
7837
7939
  if (Array.isArray(newColor)) {
7838
7940
  // Handle the case where it's called with stops array
@@ -8319,7 +8421,22 @@ var PopupTabsBodyItem = function (_a) {
8319
8421
 
8320
8422
  var ColorPicker = function (_a) {
8321
8423
  var _b = _a.value, value = _b === void 0 ? '#ffffff' : _b, _c = _a.format, format = _c === void 0 ? 'rgb' : _c, _d = _a.gradient, gradient = _d === void 0 ? false : _d, _e = _a.solid, solid = _e === void 0 ? true : _e, _f = _a.debounceMS, debounceMS = _f === void 0 ? 300 : _f, _g = _a.debounce, debounce = _g === void 0 ? true : _g, _h = _a.showAlpha, showAlpha = _h === void 0 ? true : _h, _j = _a.showInputs, showInputs = _j === void 0 ? true : _j, _k = _a.showGradientResult, showGradientResult = _k === void 0 ? true : _k, _l = _a.showGradientStops, showGradientStops = _l === void 0 ? true : _l, _m = _a.showGradientMode, showGradientMode = _m === void 0 ? true : _m, _o = _a.showGradientAngle, showGradientAngle = _o === void 0 ? true : _o, _p = _a.showGradientPosition, showGradientPosition = _p === void 0 ? true : _p, _q = _a.allowAddGradientStops, allowAddGradientStops = _q === void 0 ? true : _q, _r = _a.popupWidth, popupWidth = _r === void 0 ? 267 : _r, _s = _a.colorBoardHeight, colorBoardHeight = _s === void 0 ? 120 : _s, _t = _a.defaultColors, defaultColors = _t === void 0 ? DEFAULT_COLORS : _t, defaultActiveTab = _a.defaultActiveTab, onChangeTabs = _a.onChangeTabs, _u = _a.onChange, onChange = _u === void 0 ? function () { return ({}); } : _u, _v = _a.showReset, showReset = _v === void 0 ? false : _v, onReset = _a.onReset;
8322
- var _w = __read(useState(defaultActiveTab || getIndexActiveTag(value)), 2), activeTab = _w[0], setActiveTab = _w[1];
8424
+ // Convert object value to CSS string for internal use
8425
+ var cssValue = normalizeGradientValue(value);
8426
+ // Auto-switch to gradient tab if receiving gradient object
8427
+ var initialTab = isGradientObject(value)
8428
+ ? 'gradient'
8429
+ : defaultActiveTab || getIndexActiveTag(value);
8430
+ var _w = __read(useState(initialTab), 2), activeTab = _w[0], setActiveTab = _w[1];
8431
+ // Auto-switch tab when value changes from object to string or vice versa
8432
+ React.useEffect(function () {
8433
+ if (isGradientObject(value) && activeTab !== 'gradient') {
8434
+ setActiveTab('gradient');
8435
+ if (typeof onChangeTabs === 'function') {
8436
+ onChangeTabs('gradient');
8437
+ }
8438
+ }
8439
+ }, [value, activeTab, onChangeTabs]);
8323
8440
  var onChangeSolid = function (value) {
8324
8441
  onChange(value);
8325
8442
  };
@@ -8342,18 +8459,18 @@ var ColorPicker = function (_a) {
8342
8459
  React.createElement(PopupTabsHeaderLabel, { tabName: 'gradient', onClick: function () { return onChangeTab('gradient'); } }, "Gradient")),
8343
8460
  React.createElement(PopupTabsBody, null,
8344
8461
  React.createElement(PopupTabsBodyItem, { tabName: 'solid' },
8345
- React.createElement(IroSolidColorPicker, { onChange: onChangeSolid, value: value, format: format, defaultColors: defaultColors, debounceMS: debounceMS, debounce: debounce, showAlpha: showAlpha, showInputs: showInputs, colorBoardHeight: colorBoardHeight, showReset: showReset, onReset: onReset })),
8462
+ React.createElement(IroSolidColorPicker, { onChange: onChangeSolid, value: cssValue, format: format, defaultColors: defaultColors, debounceMS: debounceMS, debounce: debounce, showAlpha: showAlpha, showInputs: showInputs, colorBoardHeight: colorBoardHeight, showReset: showReset, onReset: onReset })),
8346
8463
  React.createElement(PopupTabsBodyItem, { tabName: 'gradient' },
8347
- React.createElement(IroGradient, { onChange: onChangeGradient, value: value, format: format, defaultColors: defaultColors, debounceMS: debounceMS, debounce: debounce, showAlpha: showAlpha, showInputs: showInputs, showGradientResult: showGradientResult, showGradientStops: showGradientStops, showGradientMode: showGradientMode, showGradientAngle: showGradientAngle, showGradientPosition: showGradientPosition, allowAddGradientStops: allowAddGradientStops, colorBoardHeight: colorBoardHeight, showReset: showReset, onReset: onReset })))))));
8464
+ React.createElement(IroGradient, { onChange: onChangeGradient, value: cssValue, format: format, defaultColors: defaultColors, debounceMS: debounceMS, debounce: debounce, showAlpha: showAlpha, showInputs: showInputs, showGradientResult: showGradientResult, showGradientStops: showGradientStops, showGradientMode: showGradientMode, showGradientAngle: showGradientAngle, showGradientPosition: showGradientPosition, allowAddGradientStops: allowAddGradientStops, colorBoardHeight: colorBoardHeight, showReset: showReset, onReset: onReset })))))));
8348
8465
  }
8349
8466
  return (React.createElement(ThemeProvider, null,
8350
8467
  React.createElement("div", { className: 'relative dark iro-gradient-picker', "data-color-picker-theme": true },
8351
8468
  React.createElement(ThemeToggle, null),
8352
8469
  solid || gradient ? (React.createElement(PopupTabs, { popupWidth: popupWidth },
8353
8470
  React.createElement(PopupTabsBody, null,
8354
- solid ? (React.createElement(IroSolidColorPicker, { onChange: onChangeSolid, value: value, format: format, defaultColors: defaultColors, debounceMS: debounceMS, debounce: debounce, showAlpha: showAlpha, showInputs: showInputs, colorBoardHeight: colorBoardHeight, showReset: showReset, onReset: onReset })) : (React.createElement(Fragment, null)),
8355
- gradient ? (React.createElement(IroGradient, { onChange: onChangeGradient, value: value, format: format, defaultColors: defaultColors, debounceMS: debounceMS, debounce: debounce, showAlpha: showAlpha, showInputs: showInputs, showGradientResult: showGradientResult, showGradientStops: showGradientStops, showGradientMode: showGradientMode, showGradientAngle: showGradientAngle, showGradientPosition: showGradientPosition, allowAddGradientStops: allowAddGradientStops, colorBoardHeight: colorBoardHeight, showReset: showReset, onReset: onReset })) : (React.createElement(Fragment, null))))) : null)));
8471
+ solid ? (React.createElement(IroSolidColorPicker, { onChange: onChangeSolid, value: cssValue, format: format, defaultColors: defaultColors, debounceMS: debounceMS, debounce: debounce, showAlpha: showAlpha, showInputs: showInputs, colorBoardHeight: colorBoardHeight, showReset: showReset, onReset: onReset })) : (React.createElement(Fragment, null)),
8472
+ gradient ? (React.createElement(IroGradient, { onChange: onChangeGradient, value: cssValue, format: format, defaultColors: defaultColors, debounceMS: debounceMS, debounce: debounce, showAlpha: showAlpha, showInputs: showInputs, showGradientResult: showGradientResult, showGradientStops: showGradientStops, showGradientMode: showGradientMode, showGradientAngle: showGradientAngle, showGradientPosition: showGradientPosition, allowAddGradientStops: allowAddGradientStops, colorBoardHeight: colorBoardHeight, showReset: showReset, onReset: onReset })) : (React.createElement(Fragment, null))))) : null)));
8356
8473
  };
8357
8474
 
8358
- export { ColorPicker, DEFAULT_COLORS, InputRgba, PopupTabs, PopupTabsBody, PopupTabsBodyItem, PopupTabsHeader, PopupTabsHeaderLabel, RADIALS_POS, ThemeProvider, ThemeToggle, TinyColor, checkFormat, cn, ColorPicker as default, getGradient, getHexAlpha, hexToRgba, isValidHex, isValidRgba, parseGradient, rgbaToArray, rgbaToHex, useDebounce, validGradient };
8475
+ export { ColorPicker, DEFAULT_COLORS, InputRgba, PopupTabs, PopupTabsBody, PopupTabsBodyItem, PopupTabsHeader, PopupTabsHeaderLabel, RADIALS_POS, ThemeProvider, ThemeToggle, TinyColor, checkFormat, cn, cssToGradientObject, ColorPicker as default, getGradient, getHexAlpha, gradientObjectToCss, hexToRgba, isGradientObject, isValidHex, isValidRgba, normalizeGradientValue, parseGradient, rgbaToArray, rgbaToHex, useDebounce, validGradient };
8359
8476
  //# sourceMappingURL=index.es.js.map