@impulse-ui-native/color-picker 9.0.0 → 9.1.2
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 +7 -4
- package/dist/components/color-picker.js +2 -1
- package/dist/components/color-picker.js.map +1 -1
- package/dist/components/gradient.js +16 -11
- package/dist/components/gradient.js.map +1 -1
- package/dist/components/hex-input.js +2 -1
- package/dist/components/hex-input.js.map +1 -1
- package/dist/components/motion-gradient.js +2 -1
- package/dist/components/motion-gradient.js.map +1 -1
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -8,12 +8,13 @@ A modular full-spectrum color picker for native iOS and Android. Reuses ImpulseU
|
|
|
8
8
|
pnpm add @impulse-ui-native/color-picker react-native-svg react-native-gesture-handler react-native-reanimated react-native-worklets
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
Requires React >=18, React Native >=0.73, react-native-svg >=13.9.0, Gesture Handler >=2, Reanimated >=4, and Worklets >=0.5. Complete Gesture Handler and
|
|
11
|
+
Requires React >=18, React Native >=0.73, react-native-svg >=13.9.0, Gesture Handler >=2, Reanimated >=4, and Worklets >=0.5. Complete Gesture Handler, Reanimated, and Worklets native setup. Render inside `GestureHandlerRootView` and `ThemeProvider` from `@impulse-ui-native/theme` and load the theme's fonts, as for other ImpulseUI controls. ColorPicker also requires react-native-svg for gradients and transparency previews. No overlay providers are required for this inline picker.
|
|
12
12
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
15
15
|
```tsx
|
|
16
16
|
import { useState } from "react";
|
|
17
|
+
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
|
17
18
|
|
|
18
19
|
import { ColorPicker } from "@impulse-ui-native/color-picker";
|
|
19
20
|
import { ThemeProvider } from "@impulse-ui-native/theme";
|
|
@@ -22,9 +23,11 @@ export function BrandColor() {
|
|
|
22
23
|
const [color, setColor] = useState("#F55D6B");
|
|
23
24
|
|
|
24
25
|
return (
|
|
25
|
-
<
|
|
26
|
-
<
|
|
27
|
-
|
|
26
|
+
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
27
|
+
<ThemeProvider>
|
|
28
|
+
<ColorPicker value={color} onChange={setColor} commitMode="confirm" />
|
|
29
|
+
</ThemeProvider>
|
|
30
|
+
</GestureHandlerRootView>
|
|
28
31
|
);
|
|
29
32
|
}
|
|
30
33
|
```
|
|
@@ -25,6 +25,7 @@ const ColorPickerComponent = memo(function ColorPicker({
|
|
|
25
25
|
const tokens = useComponentsTokens().colorPicker;
|
|
26
26
|
const styles = useThemedStyles(themedStyles);
|
|
27
27
|
const palette = presets ?? tokens.presets;
|
|
28
|
+
const hasPresets = showPresets && palette.length > 0;
|
|
28
29
|
return /* @__PURE__ */ jsxs(ColorPickerRoot, { ...props, commitMode, children: [
|
|
29
30
|
/* @__PURE__ */ jsx(Typography.Title4, { color: tokens.labelColor, children: "Choose color" }),
|
|
30
31
|
/* @__PURE__ */ jsx(ColorPickerSpectrum, {}),
|
|
@@ -46,7 +47,7 @@ const ColorPickerComponent = memo(function ColorPicker({
|
|
|
46
47
|
/* @__PURE__ */ jsx(View, { style: styles.field, children: /* @__PURE__ */ jsx(ColorPickerChannelInput, { channel: "g", label: "G" }) }),
|
|
47
48
|
/* @__PURE__ */ jsx(View, { style: styles.field, children: /* @__PURE__ */ jsx(ColorPickerChannelInput, { channel: "b", label: "B" }) })
|
|
48
49
|
] }),
|
|
49
|
-
|
|
50
|
+
hasPresets ? /* @__PURE__ */ jsxs(View, { gap: tokens.presetsLabelGap, children: [
|
|
50
51
|
/* @__PURE__ */ jsx(Typography.Label, { children: presetsLabel }),
|
|
51
52
|
/* @__PURE__ */ jsx(View, { style: styles.palette, children: palette.map((preset, index) => /* @__PURE__ */ jsx(
|
|
52
53
|
ColorPickerPresetEntry,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/color-picker.tsx"],"sourcesContent":["import { memo } from \"react\";\nimport { StyleSheet } from \"react-native\";\n\nimport type { AppTheme } from \"@impulse-ui-native/theme\";\nimport { Typography, View } from \"@impulse-ui-native/primitives\";\nimport { useComponentsTokens, useThemedStyles } from \"@impulse-ui-native/theme\";\n\nimport type { ColorPickerProps } from \"../types\";\nimport { ColorPickerAlphaInput } from \"./alpha-input\";\nimport { ColorPickerAlphaSlider } from \"./alpha-slider\";\nimport { ColorPickerApply } from \"./apply\";\nimport { ColorPickerCancel } from \"./cancel\";\nimport { ColorPickerChannelInput } from \"./channel-input\";\nimport { ColorPickerHexInput } from \"./hex-input\";\nimport { ColorPickerHueSlider } from \"./hue-slider\";\nimport { ColorPickerPresetEntry } from \"./preset\";\nimport { ColorPickerPreview } from \"./preview\";\nimport { ColorPickerRoot } from \"./root\";\nimport { ColorPickerSpectrum } from \"./spectrum\";\n\nexport const ColorPickerComponent = memo(function ColorPicker({\n showAlpha = true,\n showPresets = true,\n presets,\n presetsLabel = \"Theme colors\",\n commitMode = \"immediate\",\n ...props\n}: ColorPickerProps) {\n const tokens = useComponentsTokens().colorPicker;\n const styles = useThemedStyles(themedStyles);\n const palette = presets ?? tokens.presets;\n\n return (\n <ColorPickerRoot {...props} commitMode={commitMode}>\n <Typography.Title4 color={tokens.labelColor}>\n Choose color\n </Typography.Title4>\n <ColorPickerSpectrum />\n <View gap={tokens.sliderLabelGap}>\n <Typography.Caption>Hue</Typography.Caption>\n <ColorPickerHueSlider />\n </View>\n {showAlpha ? (\n <View gap={tokens.sliderLabelGap}>\n <Typography.Caption>Opacity</Typography.Caption>\n <ColorPickerAlphaSlider />\n </View>\n ) : null}\n <View style={styles.row}>\n <ColorPickerPreview />\n <View style={styles.field}>\n <ColorPickerHexInput label=\"HEX\" />\n </View>\n {showAlpha ? (\n <View style={styles.alphaField}>\n <ColorPickerAlphaInput label=\"Opacity (%)\" />\n </View>\n ) : null}\n </View>\n <View style={styles.row}>\n <View style={styles.field}>\n <ColorPickerChannelInput channel=\"r\" label=\"R\" />\n </View>\n <View style={styles.field}>\n <ColorPickerChannelInput channel=\"g\" label=\"G\" />\n </View>\n <View style={styles.field}>\n <ColorPickerChannelInput channel=\"b\" label=\"B\" />\n </View>\n </View>\n {
|
|
1
|
+
{"version":3,"sources":["../../src/components/color-picker.tsx"],"sourcesContent":["import { memo } from \"react\";\nimport { StyleSheet } from \"react-native\";\n\nimport type { AppTheme } from \"@impulse-ui-native/theme\";\nimport { Typography, View } from \"@impulse-ui-native/primitives\";\nimport { useComponentsTokens, useThemedStyles } from \"@impulse-ui-native/theme\";\n\nimport type { ColorPickerProps } from \"../types\";\nimport { ColorPickerAlphaInput } from \"./alpha-input\";\nimport { ColorPickerAlphaSlider } from \"./alpha-slider\";\nimport { ColorPickerApply } from \"./apply\";\nimport { ColorPickerCancel } from \"./cancel\";\nimport { ColorPickerChannelInput } from \"./channel-input\";\nimport { ColorPickerHexInput } from \"./hex-input\";\nimport { ColorPickerHueSlider } from \"./hue-slider\";\nimport { ColorPickerPresetEntry } from \"./preset\";\nimport { ColorPickerPreview } from \"./preview\";\nimport { ColorPickerRoot } from \"./root\";\nimport { ColorPickerSpectrum } from \"./spectrum\";\n\nexport const ColorPickerComponent = memo(function ColorPicker({\n showAlpha = true,\n showPresets = true,\n presets,\n presetsLabel = \"Theme colors\",\n commitMode = \"immediate\",\n ...props\n}: ColorPickerProps) {\n const tokens = useComponentsTokens().colorPicker;\n const styles = useThemedStyles(themedStyles);\n const palette = presets ?? tokens.presets;\n\n const hasPresets = showPresets && palette.length > 0;\n\n return (\n <ColorPickerRoot {...props} commitMode={commitMode}>\n <Typography.Title4 color={tokens.labelColor}>\n Choose color\n </Typography.Title4>\n <ColorPickerSpectrum />\n <View gap={tokens.sliderLabelGap}>\n <Typography.Caption>Hue</Typography.Caption>\n <ColorPickerHueSlider />\n </View>\n {showAlpha ? (\n <View gap={tokens.sliderLabelGap}>\n <Typography.Caption>Opacity</Typography.Caption>\n <ColorPickerAlphaSlider />\n </View>\n ) : null}\n <View style={styles.row}>\n <ColorPickerPreview />\n <View style={styles.field}>\n <ColorPickerHexInput label=\"HEX\" />\n </View>\n {showAlpha ? (\n <View style={styles.alphaField}>\n <ColorPickerAlphaInput label=\"Opacity (%)\" />\n </View>\n ) : null}\n </View>\n <View style={styles.row}>\n <View style={styles.field}>\n <ColorPickerChannelInput channel=\"r\" label=\"R\" />\n </View>\n <View style={styles.field}>\n <ColorPickerChannelInput channel=\"g\" label=\"G\" />\n </View>\n <View style={styles.field}>\n <ColorPickerChannelInput channel=\"b\" label=\"B\" />\n </View>\n </View>\n {hasPresets ? (\n <View gap={tokens.presetsLabelGap}>\n <Typography.Label>{presetsLabel}</Typography.Label>\n <View style={styles.palette}>\n {palette.map((preset, index) => (\n <ColorPickerPresetEntry\n key={preset.label + index}\n preset={preset}\n />\n ))}\n </View>\n </View>\n ) : null}\n {commitMode === \"confirm\" ? (\n <View style={styles.row}>\n <ColorPickerCancel style={styles.action}>Cancel</ColorPickerCancel>\n <ColorPickerApply style={styles.action}>Apply color</ColorPickerApply>\n </View>\n ) : null}\n </ColorPickerRoot>\n );\n});\n\nfunction themedStyles(theme: AppTheme) {\n const tokens = theme.components.colorPicker;\n\n return StyleSheet.create({\n row: { flexDirection: \"row\", alignItems: \"flex-end\", gap: tokens.rowGap },\n field: { flex: 1, minWidth: 0 },\n alphaField: { flex: tokens.alphaFieldFlex, minWidth: 0 },\n palette: { flexDirection: \"row\", flexWrap: \"wrap\", gap: tokens.presetsGap },\n action: { flex: 1 },\n });\n}\n"],"mappings":"AAoCM,cAIA,YAJA;AApCN,SAAS,YAAY;AACrB,SAAS,kBAAkB;AAG3B,SAAS,YAAY,YAAY;AACjC,SAAS,qBAAqB,uBAAuB;AAGrD,SAAS,6BAA6B;AACtC,SAAS,8BAA8B;AACvC,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;AAClC,SAAS,+BAA+B;AACxC,SAAS,2BAA2B;AACpC,SAAS,4BAA4B;AACrC,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC,SAAS,uBAAuB;AAChC,SAAS,2BAA2B;AAE7B,MAAM,uBAAuB,KAAK,SAAS,YAAY;AAAA,EAC5D,YAAY;AAAA,EACZ,cAAc;AAAA,EACd;AAAA,EACA,eAAe;AAAA,EACf,aAAa;AAAA,EACb,GAAG;AACL,GAAqB;AACnB,QAAM,SAAS,oBAAoB,EAAE;AACrC,QAAM,SAAS,gBAAgB,YAAY;AAC3C,QAAM,UAAU,WAAW,OAAO;AAElC,QAAM,aAAa,eAAe,QAAQ,SAAS;AAEnD,SACE,qBAAC,mBAAiB,GAAG,OAAO,YAC1B;AAAA,wBAAC,WAAW,QAAX,EAAkB,OAAO,OAAO,YAAY,0BAE7C;AAAA,IACA,oBAAC,uBAAoB;AAAA,IACrB,qBAAC,QAAK,KAAK,OAAO,gBAChB;AAAA,0BAAC,WAAW,SAAX,EAAmB,iBAAG;AAAA,MACvB,oBAAC,wBAAqB;AAAA,OACxB;AAAA,IACC,YACC,qBAAC,QAAK,KAAK,OAAO,gBAChB;AAAA,0BAAC,WAAW,SAAX,EAAmB,qBAAO;AAAA,MAC3B,oBAAC,0BAAuB;AAAA,OAC1B,IACE;AAAA,IACJ,qBAAC,QAAK,OAAO,OAAO,KAClB;AAAA,0BAAC,sBAAmB;AAAA,MACpB,oBAAC,QAAK,OAAO,OAAO,OAClB,8BAAC,uBAAoB,OAAM,OAAM,GACnC;AAAA,MACC,YACC,oBAAC,QAAK,OAAO,OAAO,YAClB,8BAAC,yBAAsB,OAAM,eAAc,GAC7C,IACE;AAAA,OACN;AAAA,IACA,qBAAC,QAAK,OAAO,OAAO,KAClB;AAAA,0BAAC,QAAK,OAAO,OAAO,OAClB,8BAAC,2BAAwB,SAAQ,KAAI,OAAM,KAAI,GACjD;AAAA,MACA,oBAAC,QAAK,OAAO,OAAO,OAClB,8BAAC,2BAAwB,SAAQ,KAAI,OAAM,KAAI,GACjD;AAAA,MACA,oBAAC,QAAK,OAAO,OAAO,OAClB,8BAAC,2BAAwB,SAAQ,KAAI,OAAM,KAAI,GACjD;AAAA,OACF;AAAA,IACC,aACC,qBAAC,QAAK,KAAK,OAAO,iBAChB;AAAA,0BAAC,WAAW,OAAX,EAAkB,wBAAa;AAAA,MAChC,oBAAC,QAAK,OAAO,OAAO,SACjB,kBAAQ,IAAI,CAAC,QAAQ,UACpB;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA;AAAA,QADK,OAAO,QAAQ;AAAA,MAEtB,CACD,GACH;AAAA,OACF,IACE;AAAA,IACH,eAAe,YACd,qBAAC,QAAK,OAAO,OAAO,KAClB;AAAA,0BAAC,qBAAkB,OAAO,OAAO,QAAQ,oBAAM;AAAA,MAC/C,oBAAC,oBAAiB,OAAO,OAAO,QAAQ,yBAAW;AAAA,OACrD,IACE;AAAA,KACN;AAEJ,CAAC;AAED,SAAS,aAAa,OAAiB;AACrC,QAAM,SAAS,MAAM,WAAW;AAEhC,SAAO,WAAW,OAAO;AAAA,IACvB,KAAK,EAAE,eAAe,OAAO,YAAY,YAAY,KAAK,OAAO,OAAO;AAAA,IACxE,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE;AAAA,IAC9B,YAAY,EAAE,MAAM,OAAO,gBAAgB,UAAU,EAAE;AAAA,IACvD,SAAS,EAAE,eAAe,OAAO,UAAU,QAAQ,KAAK,OAAO,WAAW;AAAA,IAC1E,QAAQ,EAAE,MAAM,EAAE;AAAA,EACpB,CAAC;AACH;","names":[]}
|
|
@@ -26,6 +26,8 @@ const ColorGradient = memo(function ColorGradient2({
|
|
|
26
26
|
}),
|
|
27
27
|
[colors]
|
|
28
28
|
);
|
|
29
|
+
const checkerFill = "url(#" + id + "-checker)";
|
|
30
|
+
const gradientFill = "url(#" + id + ")";
|
|
29
31
|
return /* @__PURE__ */ jsxs(Svg, { width: "100%", height: "100%", children: [
|
|
30
32
|
/* @__PURE__ */ jsxs(Defs, { children: [
|
|
31
33
|
/* @__PURE__ */ jsx(
|
|
@@ -36,15 +38,18 @@ const ColorGradient = memo(function ColorGradient2({
|
|
|
36
38
|
y1: "0%",
|
|
37
39
|
x2: vertical ? "0%" : "100%",
|
|
38
40
|
y2: vertical ? "100%" : "0%",
|
|
39
|
-
children: stops.map((stop, index) =>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
children: stops.map((stop, index) => {
|
|
42
|
+
const offset = index / Math.max(1, stops.length - 1);
|
|
43
|
+
return /* @__PURE__ */ jsx(
|
|
44
|
+
Stop,
|
|
45
|
+
{
|
|
46
|
+
offset,
|
|
47
|
+
stopColor: stop.color,
|
|
48
|
+
stopOpacity: stop.opacity
|
|
49
|
+
},
|
|
50
|
+
index
|
|
51
|
+
);
|
|
52
|
+
})
|
|
48
53
|
}
|
|
49
54
|
),
|
|
50
55
|
checkerboard ? /* @__PURE__ */ jsxs(
|
|
@@ -85,8 +90,8 @@ const ColorGradient = memo(function ColorGradient2({
|
|
|
85
90
|
}
|
|
86
91
|
) : null
|
|
87
92
|
] }),
|
|
88
|
-
checkerboard ? /* @__PURE__ */ jsx(Rect, { width: "100%", height: "100%", fill:
|
|
89
|
-
/* @__PURE__ */ jsx(Rect, { width: "100%", height: "100%", fill:
|
|
93
|
+
checkerboard ? /* @__PURE__ */ jsx(Rect, { width: "100%", height: "100%", fill: checkerFill }) : null,
|
|
94
|
+
/* @__PURE__ */ jsx(Rect, { width: "100%", height: "100%", fill: gradientFill })
|
|
90
95
|
] });
|
|
91
96
|
});
|
|
92
97
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/gradient.tsx"],"sourcesContent":["import { memo, useId, useMemo } from \"react\";\nimport Svg, {\n Defs,\n LinearGradient,\n Pattern,\n Rect,\n Stop,\n} from \"react-native-svg\";\n\nimport { useComponentsTokens } from \"@impulse-ui-native/theme\";\n\nimport type { ColorGradientProps } from \"../types/color-gradient.types\";\nimport { parseHexColor, rgbaToHex } from \"../utils/color.utils\";\n\nexport const ColorGradient = memo(function ColorGradient({\n colors,\n checkerboard = false,\n vertical = false,\n}: ColorGradientProps) {\n const id = useId().replace(/:/g, \"\");\n const tokens = useComponentsTokens().colorPicker;\n const stops = useMemo(\n () =>\n colors.map((color) => {\n const rgba = parseHexColor(color);\n\n return {\n color: rgba ? rgbaToHex({ ...rgba, a: 1 }) : color,\n opacity: rgba?.a ?? 1,\n };\n }),\n [colors],\n );\n\n return (\n <Svg width=\"100%\" height=\"100%\">\n <Defs>\n <LinearGradient\n id={id}\n x1=\"0%\"\n y1=\"0%\"\n x2={vertical ? \"0%\" : \"100%\"}\n y2={vertical ? \"100%\" : \"0%\"}\n >\n {stops.map((stop, index) =>
|
|
1
|
+
{"version":3,"sources":["../../src/components/gradient.tsx"],"sourcesContent":["import { memo, useId, useMemo } from \"react\";\nimport Svg, {\n Defs,\n LinearGradient,\n Pattern,\n Rect,\n Stop,\n} from \"react-native-svg\";\n\nimport { useComponentsTokens } from \"@impulse-ui-native/theme\";\n\nimport type { ColorGradientProps } from \"../types/color-gradient.types\";\nimport { parseHexColor, rgbaToHex } from \"../utils/color.utils\";\n\nexport const ColorGradient = memo(function ColorGradient({\n colors,\n checkerboard = false,\n vertical = false,\n}: ColorGradientProps) {\n const id = useId().replace(/:/g, \"\");\n const tokens = useComponentsTokens().colorPicker;\n const stops = useMemo(\n () =>\n colors.map((color) => {\n const rgba = parseHexColor(color);\n\n return {\n color: rgba ? rgbaToHex({ ...rgba, a: 1 }) : color,\n opacity: rgba?.a ?? 1,\n };\n }),\n [colors],\n );\n\n const checkerFill = \"url(#\" + id + \"-checker)\";\n const gradientFill = \"url(#\" + id + \")\";\n\n return (\n <Svg width=\"100%\" height=\"100%\">\n <Defs>\n <LinearGradient\n id={id}\n x1=\"0%\"\n y1=\"0%\"\n x2={vertical ? \"0%\" : \"100%\"}\n y2={vertical ? \"100%\" : \"0%\"}\n >\n {stops.map((stop, index) => {\n const offset = index / Math.max(1, stops.length - 1);\n\n return (\n <Stop\n key={index}\n offset={offset}\n stopColor={stop.color}\n stopOpacity={stop.opacity}\n />\n );\n })}\n </LinearGradient>\n {checkerboard ? (\n <Pattern\n id={id + \"-checker\"}\n width={tokens.checkerSize * 2}\n height={tokens.checkerSize * 2}\n patternUnits=\"userSpaceOnUse\"\n >\n <Rect\n width={tokens.checkerSize * 2}\n height={tokens.checkerSize * 2}\n fill={tokens.checkerLightColor}\n />\n <Rect\n width={tokens.checkerSize}\n height={tokens.checkerSize}\n fill={tokens.checkerDarkColor}\n />\n <Rect\n x={tokens.checkerSize}\n y={tokens.checkerSize}\n width={tokens.checkerSize}\n height={tokens.checkerSize}\n fill={tokens.checkerDarkColor}\n />\n </Pattern>\n ) : null}\n </Defs>\n {checkerboard ? (\n <Rect width=\"100%\" height=\"100%\" fill={checkerFill} />\n ) : null}\n <Rect width=\"100%\" height=\"100%\" fill={gradientFill} />\n </Svg>\n );\n});\n"],"mappings":"AAmDc,cAUJ,YAVI;AAnDd,SAAS,MAAM,OAAO,eAAe;AACrC,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,2BAA2B;AAGpC,SAAS,eAAe,iBAAiB;AAElC,MAAM,gBAAgB,KAAK,SAASA,eAAc;AAAA,EACvD;AAAA,EACA,eAAe;AAAA,EACf,WAAW;AACb,GAAuB;AACrB,QAAM,KAAK,MAAM,EAAE,QAAQ,MAAM,EAAE;AACnC,QAAM,SAAS,oBAAoB,EAAE;AACrC,QAAM,QAAQ;AAAA,IACZ,MACE,OAAO,IAAI,CAAC,UAAU;AACpB,YAAM,OAAO,cAAc,KAAK;AAEhC,aAAO;AAAA,QACL,OAAO,OAAO,UAAU,EAAE,GAAG,MAAM,GAAG,EAAE,CAAC,IAAI;AAAA,QAC7C,SAAS,MAAM,KAAK;AAAA,MACtB;AAAA,IACF,CAAC;AAAA,IACH,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,cAAc,UAAU,KAAK;AACnC,QAAM,eAAe,UAAU,KAAK;AAEpC,SACE,qBAAC,OAAI,OAAM,QAAO,QAAO,QACvB;AAAA,yBAAC,QACC;AAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,IAAG;AAAA,UACH,IAAG;AAAA,UACH,IAAI,WAAW,OAAO;AAAA,UACtB,IAAI,WAAW,SAAS;AAAA,UAEvB,gBAAM,IAAI,CAAC,MAAM,UAAU;AAC1B,kBAAM,SAAS,QAAQ,KAAK,IAAI,GAAG,MAAM,SAAS,CAAC;AAEnD,mBACE;AAAA,cAAC;AAAA;AAAA,gBAEC;AAAA,gBACA,WAAW,KAAK;AAAA,gBAChB,aAAa,KAAK;AAAA;AAAA,cAHb;AAAA,YAIP;AAAA,UAEJ,CAAC;AAAA;AAAA,MACH;AAAA,MACC,eACC;AAAA,QAAC;AAAA;AAAA,UACC,IAAI,KAAK;AAAA,UACT,OAAO,OAAO,cAAc;AAAA,UAC5B,QAAQ,OAAO,cAAc;AAAA,UAC7B,cAAa;AAAA,UAEb;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,OAAO,cAAc;AAAA,gBAC5B,QAAQ,OAAO,cAAc;AAAA,gBAC7B,MAAM,OAAO;AAAA;AAAA,YACf;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,OAAO;AAAA,gBACd,QAAQ,OAAO;AAAA,gBACf,MAAM,OAAO;AAAA;AAAA,YACf;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,GAAG,OAAO;AAAA,gBACV,GAAG,OAAO;AAAA,gBACV,OAAO,OAAO;AAAA,gBACd,QAAQ,OAAO;AAAA,gBACf,MAAM,OAAO;AAAA;AAAA,YACf;AAAA;AAAA;AAAA,MACF,IACE;AAAA,OACN;AAAA,IACC,eACC,oBAAC,QAAK,OAAM,QAAO,QAAO,QAAO,MAAM,aAAa,IAClD;AAAA,IACJ,oBAAC,QAAK,OAAM,QAAO,QAAO,QAAO,MAAM,cAAc;AAAA,KACvD;AAEJ,CAAC;","names":["ColorGradient"]}
|
|
@@ -36,6 +36,7 @@ const ColorPickerHexInput = memo(function ColorPickerHexInput2({
|
|
|
36
36
|
input.onCommit();
|
|
37
37
|
onSubmitEditing?.(event);
|
|
38
38
|
});
|
|
39
|
+
const inputError = error ?? (input.invalid ? "Enter a valid hex color" : void 0);
|
|
39
40
|
return /* @__PURE__ */ jsx(
|
|
40
41
|
Input,
|
|
41
42
|
{
|
|
@@ -49,7 +50,7 @@ const ColorPickerHexInput = memo(function ColorPickerHexInput2({
|
|
|
49
50
|
onChangeText: input.onChangeText,
|
|
50
51
|
onBlur: handleBlur,
|
|
51
52
|
onSubmitEditing: handleSubmit,
|
|
52
|
-
error:
|
|
53
|
+
error: inputError
|
|
53
54
|
}
|
|
54
55
|
);
|
|
55
56
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/hex-input.tsx"],"sourcesContent":["import { memo } from \"react\";\n\nimport { useEventCallback } from \"@impulse-ui-native/core\";\nimport { Input } from \"@impulse-ui-native/input\";\n\nimport type { ColorPickerHexInputProps } from \"../types/color-input.types\";\nimport { useColorInput } from \"../hooks/use-color-input.hook\";\nimport { useColorPickerContext } from \"../hooks/use-color-picker-context.hook\";\nimport { parseHexColor, rgbaToHex } from \"../utils/color.utils\";\n\nexport const ColorPickerHexInput = memo(function ColorPickerHexInput({\n disabled: disabledProp,\n onBlur,\n onSubmitEditing,\n error,\n ...props\n}: ColorPickerHexInputProps) {\n const {\n value,\n disabled: rootDisabled,\n size,\n setColor,\n resetKey,\n } = useColorPickerContext();\n const disabled = rootDisabled || disabledProp === true;\n const commit = useEventCallback((text: string): string | undefined => {\n const parsed = parseHexColor(text);\n\n if (!parsed || !setColor(text)) {\n return undefined;\n }\n\n return rgbaToHex(parsed);\n });\n const input = useColorInput({ value, disabled, commit, resetKey });\n const handleBlur = useEventCallback<\n NonNullable<ColorPickerHexInputProps[\"onBlur\"]>\n >((event) => {\n input.onCommit();\n onBlur?.(event);\n });\n const handleSubmit = useEventCallback<\n NonNullable<ColorPickerHexInputProps[\"onSubmitEditing\"]>\n >((event) => {\n input.onCommit();\n onSubmitEditing?.(event);\n });\n\n return (\n <Input\n size={size}\n autoCapitalize=\"characters\"\n autoCorrect={false}\n maxLength={9}\n {...props}\n disabled={disabled}\n value={input.text}\n onChangeText={input.onChangeText}\n onBlur={handleBlur}\n onSubmitEditing={handleSubmit}\n error={
|
|
1
|
+
{"version":3,"sources":["../../src/components/hex-input.tsx"],"sourcesContent":["import { memo } from \"react\";\n\nimport { useEventCallback } from \"@impulse-ui-native/core\";\nimport { Input } from \"@impulse-ui-native/input\";\n\nimport type { ColorPickerHexInputProps } from \"../types/color-input.types\";\nimport { useColorInput } from \"../hooks/use-color-input.hook\";\nimport { useColorPickerContext } from \"../hooks/use-color-picker-context.hook\";\nimport { parseHexColor, rgbaToHex } from \"../utils/color.utils\";\n\nexport const ColorPickerHexInput = memo(function ColorPickerHexInput({\n disabled: disabledProp,\n onBlur,\n onSubmitEditing,\n error,\n ...props\n}: ColorPickerHexInputProps) {\n const {\n value,\n disabled: rootDisabled,\n size,\n setColor,\n resetKey,\n } = useColorPickerContext();\n const disabled = rootDisabled || disabledProp === true;\n const commit = useEventCallback((text: string): string | undefined => {\n const parsed = parseHexColor(text);\n\n if (!parsed || !setColor(text)) {\n return undefined;\n }\n\n return rgbaToHex(parsed);\n });\n const input = useColorInput({ value, disabled, commit, resetKey });\n const handleBlur = useEventCallback<\n NonNullable<ColorPickerHexInputProps[\"onBlur\"]>\n >((event) => {\n input.onCommit();\n onBlur?.(event);\n });\n const handleSubmit = useEventCallback<\n NonNullable<ColorPickerHexInputProps[\"onSubmitEditing\"]>\n >((event) => {\n input.onCommit();\n onSubmitEditing?.(event);\n });\n\n const inputError =\n error ?? (input.invalid ? \"Enter a valid hex color\" : undefined);\n\n return (\n <Input\n size={size}\n autoCapitalize=\"characters\"\n autoCorrect={false}\n maxLength={9}\n {...props}\n disabled={disabled}\n value={input.text}\n onChangeText={input.onChangeText}\n onBlur={handleBlur}\n onSubmitEditing={handleSubmit}\n error={inputError}\n />\n );\n});\n"],"mappings":"AAoDI;AApDJ,SAAS,YAAY;AAErB,SAAS,wBAAwB;AACjC,SAAS,aAAa;AAGtB,SAAS,qBAAqB;AAC9B,SAAS,6BAA6B;AACtC,SAAS,eAAe,iBAAiB;AAElC,MAAM,sBAAsB,KAAK,SAASA,qBAAoB;AAAA,EACnE,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA6B;AAC3B,QAAM;AAAA,IACJ;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,sBAAsB;AAC1B,QAAM,WAAW,gBAAgB,iBAAiB;AAClD,QAAM,SAAS,iBAAiB,CAAC,SAAqC;AACpE,UAAM,SAAS,cAAc,IAAI;AAEjC,QAAI,CAAC,UAAU,CAAC,SAAS,IAAI,GAAG;AAC9B,aAAO;AAAA,IACT;AAEA,WAAO,UAAU,MAAM;AAAA,EACzB,CAAC;AACD,QAAM,QAAQ,cAAc,EAAE,OAAO,UAAU,QAAQ,SAAS,CAAC;AACjE,QAAM,aAAa,iBAEjB,CAAC,UAAU;AACX,UAAM,SAAS;AACf,aAAS,KAAK;AAAA,EAChB,CAAC;AACD,QAAM,eAAe,iBAEnB,CAAC,UAAU;AACX,UAAM,SAAS;AACf,sBAAkB,KAAK;AAAA,EACzB,CAAC;AAED,QAAM,aACJ,UAAU,MAAM,UAAU,4BAA4B;AAExD,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,gBAAe;AAAA,MACf,aAAa;AAAA,MACb,WAAW;AAAA,MACV,GAAG;AAAA,MACJ;AAAA,MACA,OAAO,MAAM;AAAA,MACb,cAAc,MAAM;AAAA,MACpB,QAAQ;AAAA,MACR,iBAAiB;AAAA,MACjB,OAAO;AAAA;AAAA,EACT;AAEJ,CAAC;","names":["ColorPickerHexInput"]}
|
|
@@ -16,6 +16,7 @@ const ColorMotionGradient = memo(function ColorMotionGradient2({
|
|
|
16
16
|
const rectProps = useAnimatedProps(() => ({
|
|
17
17
|
color: rgbaToNativeColor(rgba.get(), true)
|
|
18
18
|
}));
|
|
19
|
+
const gradientFill = "url(#" + id + ")";
|
|
19
20
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
20
21
|
/* @__PURE__ */ jsx(ColorGradient, { colors: TransparentStops, checkerboard: true }),
|
|
21
22
|
/* @__PURE__ */ jsxs(
|
|
@@ -31,7 +32,7 @@ const ColorMotionGradient = memo(function ColorMotionGradient2({
|
|
|
31
32
|
/* @__PURE__ */ jsx(Stop, { offset: 0, stopColor: "#FFFFFF", stopOpacity: 0 }),
|
|
32
33
|
/* @__PURE__ */ jsx(Stop, { offset: 1, stopColor: "#FFFFFF", stopOpacity: 1 })
|
|
33
34
|
] }),
|
|
34
|
-
/* @__PURE__ */ jsx(Mask, { id: id + "-mask", x: "0%", y: "0%", width: "100%", height: "100%", children: /* @__PURE__ */ jsx(Rect, { width: "100%", height: "100%", fill:
|
|
35
|
+
/* @__PURE__ */ jsx(Mask, { id: id + "-mask", x: "0%", y: "0%", width: "100%", height: "100%", children: /* @__PURE__ */ jsx(Rect, { width: "100%", height: "100%", fill: gradientFill }) })
|
|
35
36
|
] }),
|
|
36
37
|
/* @__PURE__ */ jsx(
|
|
37
38
|
AnimatedColorRect,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/motion-gradient.tsx"],"sourcesContent":["import { memo, useId } from \"react\";\nimport { StyleSheet } from \"react-native\";\nimport { useAnimatedProps } from \"react-native-reanimated\";\nimport Svg, { Defs, LinearGradient, Mask, Rect, Stop } from \"react-native-svg\";\n\nimport type { ColorMotionSurfaceProps } from \"../types/color-motion.types\";\nimport {\n AnimatedColorRect,\n TransparentStops,\n} from \"../constants/motion.constants\";\nimport { rgbaToNativeColor } from \"../utils/color.utils\";\nimport { ColorGradient } from \"./gradient\";\n\nexport const ColorMotionGradient = memo(function ColorMotionGradient({\n rgba,\n}: ColorMotionSurfaceProps) {\n const id = useId().replace(/:/g, \"\");\n const rectProps = useAnimatedProps(() => ({\n color: rgbaToNativeColor(rgba.get(), true),\n }));\n\n return (\n <>\n <ColorGradient colors={TransparentStops} checkerboard />\n <Svg\n pointerEvents=\"none\"\n width=\"100%\"\n height=\"100%\"\n style={StyleSheet.absoluteFill}\n >\n <Defs>\n <LinearGradient id={id} x1=\"0%\" x2=\"100%\" y1=\"0%\" y2=\"0%\">\n <Stop offset={0} stopColor=\"#FFFFFF\" stopOpacity={0} />\n <Stop offset={1} stopColor=\"#FFFFFF\" stopOpacity={1} />\n </LinearGradient>\n <Mask id={id + \"-mask\"} x=\"0%\" y=\"0%\" width=\"100%\" height=\"100%\">\n <Rect width=\"100%\" height=\"100%\" fill={
|
|
1
|
+
{"version":3,"sources":["../../src/components/motion-gradient.tsx"],"sourcesContent":["import { memo, useId } from \"react\";\nimport { StyleSheet } from \"react-native\";\nimport { useAnimatedProps } from \"react-native-reanimated\";\nimport Svg, { Defs, LinearGradient, Mask, Rect, Stop } from \"react-native-svg\";\n\nimport type { ColorMotionSurfaceProps } from \"../types/color-motion.types\";\nimport {\n AnimatedColorRect,\n TransparentStops,\n} from \"../constants/motion.constants\";\nimport { rgbaToNativeColor } from \"../utils/color.utils\";\nimport { ColorGradient } from \"./gradient\";\n\nexport const ColorMotionGradient = memo(function ColorMotionGradient({\n rgba,\n}: ColorMotionSurfaceProps) {\n const id = useId().replace(/:/g, \"\");\n const rectProps = useAnimatedProps(() => ({\n color: rgbaToNativeColor(rgba.get(), true),\n }));\n\n const gradientFill = \"url(#\" + id + \")\";\n\n return (\n <>\n <ColorGradient colors={TransparentStops} checkerboard />\n <Svg\n pointerEvents=\"none\"\n width=\"100%\"\n height=\"100%\"\n style={StyleSheet.absoluteFill}\n >\n <Defs>\n <LinearGradient id={id} x1=\"0%\" x2=\"100%\" y1=\"0%\" y2=\"0%\">\n <Stop offset={0} stopColor=\"#FFFFFF\" stopOpacity={0} />\n <Stop offset={1} stopColor=\"#FFFFFF\" stopOpacity={1} />\n </LinearGradient>\n <Mask id={id + \"-mask\"} x=\"0%\" y=\"0%\" width=\"100%\" height=\"100%\">\n <Rect width=\"100%\" height=\"100%\" fill={gradientFill} />\n </Mask>\n </Defs>\n <AnimatedColorRect\n fill=\"currentColor\"\n width=\"100%\"\n height=\"100%\"\n mask={\"url(#\" + id + \"-mask)\"}\n animatedProps={rectProps}\n />\n </Svg>\n </>\n );\n});\n"],"mappings":"AAwBI,mBACE,KAQI,YATN;AAxBJ,SAAS,MAAM,aAAa;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,wBAAwB;AACjC,OAAO,OAAO,MAAM,gBAAgB,MAAM,MAAM,YAAY;AAG5D;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,yBAAyB;AAClC,SAAS,qBAAqB;AAEvB,MAAM,sBAAsB,KAAK,SAASA,qBAAoB;AAAA,EACnE;AACF,GAA4B;AAC1B,QAAM,KAAK,MAAM,EAAE,QAAQ,MAAM,EAAE;AACnC,QAAM,YAAY,iBAAiB,OAAO;AAAA,IACxC,OAAO,kBAAkB,KAAK,IAAI,GAAG,IAAI;AAAA,EAC3C,EAAE;AAEF,QAAM,eAAe,UAAU,KAAK;AAEpC,SACE,iCACE;AAAA,wBAAC,iBAAc,QAAQ,kBAAkB,cAAY,MAAC;AAAA,IACtD;AAAA,MAAC;AAAA;AAAA,QACC,eAAc;AAAA,QACd,OAAM;AAAA,QACN,QAAO;AAAA,QACP,OAAO,WAAW;AAAA,QAElB;AAAA,+BAAC,QACC;AAAA,iCAAC,kBAAe,IAAQ,IAAG,MAAK,IAAG,QAAO,IAAG,MAAK,IAAG,MACnD;AAAA,kCAAC,QAAK,QAAQ,GAAG,WAAU,WAAU,aAAa,GAAG;AAAA,cACrD,oBAAC,QAAK,QAAQ,GAAG,WAAU,WAAU,aAAa,GAAG;AAAA,eACvD;AAAA,YACA,oBAAC,QAAK,IAAI,KAAK,SAAS,GAAE,MAAK,GAAE,MAAK,OAAM,QAAO,QAAO,QACxD,8BAAC,QAAK,OAAM,QAAO,QAAO,QAAO,MAAM,cAAc,GACvD;AAAA,aACF;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,OAAM;AAAA,cACN,QAAO;AAAA,cACP,MAAM,UAAU,KAAK;AAAA,cACrB,eAAe;AAAA;AAAA,UACjB;AAAA;AAAA;AAAA,IACF;AAAA,KACF;AAEJ,CAAC;","names":["ColorMotionGradient"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@impulse-ui-native/color-picker",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.1.2",
|
|
4
4
|
"description": "Modular spectrum color picker with custom hex/RGB entry and theme presets for React Native.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
"source": "src/index.ts",
|
|
14
14
|
"module": "dist/index.js",
|
|
15
15
|
"types": "dist/index.d.mts",
|
|
16
|
-
"react-native": "
|
|
16
|
+
"react-native": "dist/index.js",
|
|
17
17
|
"exports": {
|
|
18
18
|
".": {
|
|
19
19
|
"types": "./dist/index.d.mts",
|
|
20
|
-
"react-native": "./
|
|
20
|
+
"react-native": "./dist/index.js",
|
|
21
21
|
"import": "./dist/index.js"
|
|
22
22
|
}
|
|
23
23
|
},
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
],
|
|
29
29
|
"sideEffects": false,
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@impulse-ui-native/
|
|
32
|
-
"@impulse-ui-native/input": "9.
|
|
33
|
-
"@impulse-ui-native/primitives": "9.
|
|
34
|
-
"@impulse-ui-native/
|
|
35
|
-
"@impulse-ui-native/
|
|
36
|
-
"@impulse-ui-native/
|
|
31
|
+
"@impulse-ui-native/icon": "9.1.2",
|
|
32
|
+
"@impulse-ui-native/input": "9.1.2",
|
|
33
|
+
"@impulse-ui-native/primitives": "9.1.2",
|
|
34
|
+
"@impulse-ui-native/slider": "9.1.2",
|
|
35
|
+
"@impulse-ui-native/core": "9.1.2",
|
|
36
|
+
"@impulse-ui-native/theme": "9.1.2"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/react": "~19.2.14",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"react-native-reanimated": "4.5.1",
|
|
48
48
|
"react-native-worklets": "0.10.1",
|
|
49
49
|
"@impulse-ui-native/eslint-config": "1.0.0",
|
|
50
|
-
"@impulse-ui-native/
|
|
51
|
-
"@impulse-ui-native/
|
|
50
|
+
"@impulse-ui-native/tsconfig": "1.0.0",
|
|
51
|
+
"@impulse-ui-native/prettier-config": "1.0.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"react": ">=18",
|