@patternmode/swatch 0.1.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/dist/Swatch/SwatchColors.d.ts +4 -0
- package/dist/Swatch/SwatchColors.d.ts.map +1 -0
- package/dist/Swatch/SwatchRoot.d.ts +3 -0
- package/dist/Swatch/SwatchRoot.d.ts.map +1 -0
- package/dist/Swatch/SwatchTypes.d.ts +29 -0
- package/dist/Swatch/SwatchTypes.d.ts.map +1 -0
- package/dist/Swatch/index.d.ts +4 -0
- package/dist/Swatch/index.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +129 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles.css +1 -0
- package/dist/swatch.d.ts +4 -0
- package/dist/swatch.d.ts.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SwatchColorStop } from "./SwatchTypes";
|
|
2
|
+
export declare function isLightColor(color: string): boolean;
|
|
3
|
+
export declare function getSwatchColorsBackground(colors: SwatchColorStop[] | undefined): string | undefined;
|
|
4
|
+
//# sourceMappingURL=SwatchColors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwatchColors.d.ts","sourceRoot":"","sources":["../../src/Swatch/SwatchColors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAWnD;AAED,wBAAgB,yBAAyB,CACxC,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,GACnC,MAAM,GAAG,SAAS,CAyBpB"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { SwatchProps } from "./SwatchTypes";
|
|
2
|
+
export declare function Swatch({ "aria-label": ariaLabel, background, children, className, color, colors, icon: Icon, isLight, objectFit, objectPosition, onRemove, raised, role: _role, selected, shape, showRing, size, style, unavailable, ...props }: SwatchProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
//# sourceMappingURL=SwatchRoot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwatchRoot.d.ts","sourceRoot":"","sources":["../../src/Swatch/SwatchRoot.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,wBAAgB,MAAM,CAAC,EACtB,YAAY,EAAE,SAAS,EACvB,UAAU,EACV,QAAQ,EACR,SAAS,EACT,KAAK,EACL,MAAM,EACN,IAAI,EAAE,IAAI,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,QAAQ,EACR,MAAc,EACd,IAAI,EAAE,KAAK,EACX,QAAgB,EAChB,KAAgB,EAChB,QAAe,EACf,IAAa,EACb,KAAK,EACL,WAAmB,EACnB,GAAG,KAAK,EACR,EAAE,WAAW,2CAqEb"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ObjectFit, type PatternmodeSize } from "@patternmode/system";
|
|
2
|
+
import type { ComponentType, HTMLAttributes, SVGProps } from "react";
|
|
3
|
+
export declare const SWATCH_SIZES: readonly ["2xs", "xs", "sm", "base", "lg", "xl", "2xl", "3xl"];
|
|
4
|
+
export declare const SWATCH_SHAPES: readonly ["circle", "pill", "square"];
|
|
5
|
+
export type SwatchSize = PatternmodeSize;
|
|
6
|
+
export type SwatchShape = (typeof SWATCH_SHAPES)[number];
|
|
7
|
+
export type SwatchColorStop = string | {
|
|
8
|
+
color: string;
|
|
9
|
+
ratio?: number;
|
|
10
|
+
};
|
|
11
|
+
type SwatchIcon = ComponentType<SVGProps<SVGSVGElement>>;
|
|
12
|
+
export interface SwatchProps extends HTMLAttributes<HTMLSpanElement> {
|
|
13
|
+
background?: string;
|
|
14
|
+
color?: string;
|
|
15
|
+
colors?: SwatchColorStop[];
|
|
16
|
+
icon?: SwatchIcon;
|
|
17
|
+
isLight?: boolean;
|
|
18
|
+
objectFit?: ObjectFit;
|
|
19
|
+
objectPosition?: string;
|
|
20
|
+
onRemove?: () => void;
|
|
21
|
+
raised?: boolean;
|
|
22
|
+
selected?: boolean;
|
|
23
|
+
shape?: SwatchShape;
|
|
24
|
+
showRing?: boolean;
|
|
25
|
+
size?: SwatchSize;
|
|
26
|
+
unavailable?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=SwatchTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwatchTypes.d.ts","sourceRoot":"","sources":["../../src/Swatch/SwatchTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,SAAS,EAEd,KAAK,eAAe,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAErE,eAAO,MAAM,YAAY,gEAAoB,CAAC;AAE9C,eAAO,MAAM,aAAa,uCAAwC,CAAC;AAEnE,MAAM,MAAM,UAAU,GAAG,eAAe,CAAC;AACzC,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AACzD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACzE,KAAK,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;AAEzD,MAAM,WAAW,WAAY,SAAQ,cAAc,CAAC,eAAe,CAAC;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { getSwatchColorsBackground } from "./SwatchColors";
|
|
2
|
+
export { Swatch } from "./SwatchRoot";
|
|
3
|
+
export { SWATCH_SHAPES, SWATCH_SIZES, type SwatchColorStop, type SwatchProps, type SwatchShape, type SwatchSize, } from "./SwatchTypes";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Swatch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EACN,aAAa,EACb,YAAY,EACZ,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,UAAU,GACf,MAAM,eAAe,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,yBAAyB,EACzB,aAAa,EACb,YAAY,EACZ,MAAM,EACN,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,UAAU,GACf,MAAM,UAAU,CAAC"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { PATTERNMODE_SIZES, getObjectSizingStyle, getSizeVariableStyle, joinClassNames } from "@patternmode/system";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
//#region src/Swatch/SwatchColors.ts
|
|
4
|
+
function isLightColor(color) {
|
|
5
|
+
const normalized = normalizeHex(color);
|
|
6
|
+
if (!normalized) return false;
|
|
7
|
+
const red = Number.parseInt(normalized.slice(0, 2), 16);
|
|
8
|
+
const green = Number.parseInt(normalized.slice(2, 4), 16);
|
|
9
|
+
const blue = Number.parseInt(normalized.slice(4, 6), 16);
|
|
10
|
+
return (.299 * red + .587 * green + .114 * blue) / 255 > .62;
|
|
11
|
+
}
|
|
12
|
+
function getSwatchColorsBackground(colors) {
|
|
13
|
+
if (!colors || colors.length === 0) return;
|
|
14
|
+
if (colors.length === 1) return toColorStop(colors[0]).color;
|
|
15
|
+
const stops = colors.map(toColorStop);
|
|
16
|
+
const weights = stops.map((stop) => getRatioWeight(stop.ratio));
|
|
17
|
+
const rawTotal = weights.reduce((sum, ratio) => sum + ratio, 0);
|
|
18
|
+
const useEqualWeights = rawTotal <= 0;
|
|
19
|
+
const total = useEqualWeights ? stops.length : rawTotal;
|
|
20
|
+
let cursor = 0;
|
|
21
|
+
return `linear-gradient(90deg, ${stops.map((stop, index) => {
|
|
22
|
+
const ratio = useEqualWeights ? 1 : weights[index] ?? 0;
|
|
23
|
+
const start = cursor;
|
|
24
|
+
const end = index === stops.length - 1 ? 100 : cursor + ratio / total * 100;
|
|
25
|
+
cursor = end;
|
|
26
|
+
return `${stop.color} ${formatPercent(start)} ${formatPercent(end)}`;
|
|
27
|
+
}).join(", ")})`;
|
|
28
|
+
}
|
|
29
|
+
function normalizeHex(hex) {
|
|
30
|
+
const value = hex.trim().replace(/^#/, "");
|
|
31
|
+
if (/^[\da-f]{3}$/i.test(value)) return value.split("").map((part) => part + part).join("");
|
|
32
|
+
if (/^[\da-f]{6}$/i.test(value)) return value;
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
function toColorStop(stop) {
|
|
36
|
+
return typeof stop === "string" ? { color: stop } : stop;
|
|
37
|
+
}
|
|
38
|
+
function getRatioWeight(ratio) {
|
|
39
|
+
if (ratio === void 0) return 1;
|
|
40
|
+
return Number.isFinite(ratio) ? Math.max(0, ratio) : 0;
|
|
41
|
+
}
|
|
42
|
+
function formatPercent(value) {
|
|
43
|
+
return `${Number.isInteger(value) ? value : Number(value.toFixed(2))}%`;
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/Swatch/SwatchRoot.tsx
|
|
47
|
+
function Swatch({ "aria-label": ariaLabel, background, children, className, color, colors, icon: Icon, isLight, objectFit, objectPosition, onRemove, raised = false, role: _role, selected = false, shape = "circle", showRing = true, size = "base", style, unavailable = false, ...props }) {
|
|
48
|
+
const colorsBackground = getSwatchColorsBackground(colors);
|
|
49
|
+
const fill = background ?? colorsBackground ?? color;
|
|
50
|
+
const light = isLight ?? (color && !background && !colorsBackground ? isLightColor(color) : false);
|
|
51
|
+
const rootStyle = {
|
|
52
|
+
...getSizeVariableStyle(size, "--patternmode-swatch-size"),
|
|
53
|
+
"--patternmode-swatch-fill": fill,
|
|
54
|
+
...style
|
|
55
|
+
};
|
|
56
|
+
const mediaStyle = getObjectSizingStyle({
|
|
57
|
+
fit: objectFit,
|
|
58
|
+
position: objectPosition
|
|
59
|
+
});
|
|
60
|
+
function handleRemove(event) {
|
|
61
|
+
event.stopPropagation();
|
|
62
|
+
onRemove?.();
|
|
63
|
+
}
|
|
64
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
65
|
+
...props,
|
|
66
|
+
"aria-label": ariaLabel,
|
|
67
|
+
className: joinClassNames("patternmode-swatch", className),
|
|
68
|
+
"data-raised": raised ? "true" : void 0,
|
|
69
|
+
"data-selected": selected ? "true" : void 0,
|
|
70
|
+
"data-shape": shape,
|
|
71
|
+
"data-show-ring": showRing ? "true" : "false",
|
|
72
|
+
"data-size": size,
|
|
73
|
+
"data-slot": "swatch",
|
|
74
|
+
"data-tone": light ? "light" : "dark",
|
|
75
|
+
"data-unavailable": unavailable ? "true" : void 0,
|
|
76
|
+
role: "img",
|
|
77
|
+
style: rootStyle,
|
|
78
|
+
children: [
|
|
79
|
+
/* @__PURE__ */ jsx("span", {
|
|
80
|
+
"aria-hidden": "true",
|
|
81
|
+
className: "patternmode-swatch__fill"
|
|
82
|
+
}),
|
|
83
|
+
children ? /* @__PURE__ */ jsx("span", {
|
|
84
|
+
className: "patternmode-swatch__media",
|
|
85
|
+
style: mediaStyle,
|
|
86
|
+
children
|
|
87
|
+
}) : null,
|
|
88
|
+
/* @__PURE__ */ jsx("span", {
|
|
89
|
+
"aria-hidden": "true",
|
|
90
|
+
className: "patternmode-swatch__scrim"
|
|
91
|
+
}),
|
|
92
|
+
selected && Icon ? /* @__PURE__ */ jsx("span", {
|
|
93
|
+
className: "patternmode-swatch__icon",
|
|
94
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
95
|
+
"aria-hidden": "true",
|
|
96
|
+
focusable: "false"
|
|
97
|
+
})
|
|
98
|
+
}) : null,
|
|
99
|
+
unavailable ? /* @__PURE__ */ jsx("span", {
|
|
100
|
+
"aria-hidden": "true",
|
|
101
|
+
className: "patternmode-swatch__slash"
|
|
102
|
+
}) : null,
|
|
103
|
+
onRemove ? /* @__PURE__ */ jsx("button", {
|
|
104
|
+
"aria-label": "Remove",
|
|
105
|
+
className: "patternmode-swatch__remove",
|
|
106
|
+
onClick: handleRemove,
|
|
107
|
+
type: "button",
|
|
108
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
109
|
+
"aria-hidden": "true",
|
|
110
|
+
fill: "none",
|
|
111
|
+
viewBox: "0 0 20 20",
|
|
112
|
+
children: /* @__PURE__ */ jsx("path", { d: "M5.5 5.5l9 9M14.5 5.5l-9 9" })
|
|
113
|
+
})
|
|
114
|
+
}) : null
|
|
115
|
+
]
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/Swatch/SwatchTypes.ts
|
|
120
|
+
const SWATCH_SIZES = PATTERNMODE_SIZES;
|
|
121
|
+
const SWATCH_SHAPES = [
|
|
122
|
+
"circle",
|
|
123
|
+
"pill",
|
|
124
|
+
"square"
|
|
125
|
+
];
|
|
126
|
+
//#endregion
|
|
127
|
+
export { SWATCH_SHAPES, SWATCH_SIZES, Swatch, getSwatchColorsBackground };
|
|
128
|
+
|
|
129
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/Swatch/SwatchColors.ts","../src/Swatch/SwatchRoot.tsx","../src/Swatch/SwatchTypes.ts"],"sourcesContent":["import type { SwatchColorStop } from \"./SwatchTypes\";\n\nexport function isLightColor(color: string): boolean {\n\tconst normalized = normalizeHex(color);\n\tif (!normalized) {\n\t\treturn false;\n\t}\n\n\tconst red = Number.parseInt(normalized.slice(0, 2), 16);\n\tconst green = Number.parseInt(normalized.slice(2, 4), 16);\n\tconst blue = Number.parseInt(normalized.slice(4, 6), 16);\n\tconst luminance = (0.299 * red + 0.587 * green + 0.114 * blue) / 255;\n\treturn luminance > 0.62;\n}\n\nexport function getSwatchColorsBackground(\n\tcolors: SwatchColorStop[] | undefined,\n): string | undefined {\n\tif (!colors || colors.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (colors.length === 1) {\n\t\treturn toColorStop(colors[0] as SwatchColorStop).color;\n\t}\n\n\tconst stops = colors.map(toColorStop);\n\tconst weights = stops.map((stop) => getRatioWeight(stop.ratio));\n\tconst rawTotal = weights.reduce((sum, ratio) => sum + ratio, 0);\n\tconst useEqualWeights = rawTotal <= 0;\n\tconst total = useEqualWeights ? stops.length : rawTotal;\n\tlet cursor = 0;\n\tconst parts = stops.map((stop, index) => {\n\t\tconst ratio = useEqualWeights ? 1 : (weights[index] ?? 0);\n\t\tconst start = cursor;\n\t\tconst end =\n\t\t\tindex === stops.length - 1 ? 100 : cursor + (ratio / total) * 100;\n\t\tcursor = end;\n\t\treturn `${stop.color} ${formatPercent(start)} ${formatPercent(end)}`;\n\t});\n\n\treturn `linear-gradient(90deg, ${parts.join(\", \")})`;\n}\n\nfunction normalizeHex(hex: string): string | null {\n\tconst value = hex.trim().replace(/^#/, \"\");\n\tif (/^[\\da-f]{3}$/i.test(value)) {\n\t\treturn value\n\t\t\t.split(\"\")\n\t\t\t.map((part) => part + part)\n\t\t\t.join(\"\");\n\t}\n\tif (/^[\\da-f]{6}$/i.test(value)) {\n\t\treturn value;\n\t}\n\treturn null;\n}\n\nfunction toColorStop(stop: SwatchColorStop): { color: string; ratio?: number } {\n\treturn typeof stop === \"string\" ? { color: stop } : stop;\n}\n\nfunction getRatioWeight(ratio: number | undefined): number {\n\tif (ratio === undefined) {\n\t\treturn 1;\n\t}\n\n\treturn Number.isFinite(ratio) ? Math.max(0, ratio) : 0;\n}\n\nfunction formatPercent(value: number): string {\n\treturn `${Number.isInteger(value) ? value : Number(value.toFixed(2))}%`;\n}\n","import {\n\tgetObjectSizingStyle,\n\tgetSizeVariableStyle,\n\tjoinClassNames,\n} from \"@patternmode/system\";\nimport type { CSSProperties, MouseEvent } from \"react\";\n\nimport { getSwatchColorsBackground, isLightColor } from \"./SwatchColors\";\nimport type { SwatchProps } from \"./SwatchTypes\";\n\nexport function Swatch({\n\t\"aria-label\": ariaLabel,\n\tbackground,\n\tchildren,\n\tclassName,\n\tcolor,\n\tcolors,\n\ticon: Icon,\n\tisLight,\n\tobjectFit,\n\tobjectPosition,\n\tonRemove,\n\traised = false,\n\trole: _role,\n\tselected = false,\n\tshape = \"circle\",\n\tshowRing = true,\n\tsize = \"base\",\n\tstyle,\n\tunavailable = false,\n\t...props\n}: SwatchProps) {\n\tconst colorsBackground = getSwatchColorsBackground(colors);\n\tconst fill = background ?? colorsBackground ?? color;\n\tconst light =\n\t\tisLight ??\n\t\t(color && !background && !colorsBackground\n\t\t\t? isLightColor(color as string)\n\t\t\t: false);\n\n\tconst rootStyle = {\n\t\t...getSizeVariableStyle(size, \"--patternmode-swatch-size\"),\n\t\t\"--patternmode-swatch-fill\": fill,\n\t\t...style,\n\t} as CSSProperties;\n\tconst mediaStyle = getObjectSizingStyle({\n\t\tfit: objectFit,\n\t\tposition: objectPosition,\n\t}) as CSSProperties;\n\n\tfunction handleRemove(event: MouseEvent<HTMLButtonElement>) {\n\t\tevent.stopPropagation();\n\t\tonRemove?.();\n\t}\n\n\treturn (\n\t\t<span\n\t\t\t{...props}\n\t\t\taria-label={ariaLabel}\n\t\t\tclassName={joinClassNames(\"patternmode-swatch\", className)}\n\t\t\tdata-raised={raised ? \"true\" : undefined}\n\t\t\tdata-selected={selected ? \"true\" : undefined}\n\t\t\tdata-shape={shape}\n\t\t\tdata-show-ring={showRing ? \"true\" : \"false\"}\n\t\t\tdata-size={size}\n\t\t\tdata-slot=\"swatch\"\n\t\t\tdata-tone={light ? \"light\" : \"dark\"}\n\t\t\tdata-unavailable={unavailable ? \"true\" : undefined}\n\t\t\trole=\"img\"\n\t\t\tstyle={rootStyle}\n\t\t>\n\t\t\t<span aria-hidden=\"true\" className=\"patternmode-swatch__fill\" />\n\t\t\t{children ? (\n\t\t\t\t<span className=\"patternmode-swatch__media\" style={mediaStyle}>\n\t\t\t\t\t{children}\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t\t<span aria-hidden=\"true\" className=\"patternmode-swatch__scrim\" />\n\t\t\t{selected && Icon ? (\n\t\t\t\t<span className=\"patternmode-swatch__icon\">\n\t\t\t\t\t<Icon aria-hidden=\"true\" focusable=\"false\" />\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t\t{unavailable ? (\n\t\t\t\t<span aria-hidden=\"true\" className=\"patternmode-swatch__slash\" />\n\t\t\t) : null}\n\t\t\t{onRemove ? (\n\t\t\t\t<button\n\t\t\t\t\taria-label=\"Remove\"\n\t\t\t\t\tclassName=\"patternmode-swatch__remove\"\n\t\t\t\t\tonClick={handleRemove}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t>\n\t\t\t\t\t<svg aria-hidden=\"true\" fill=\"none\" viewBox=\"0 0 20 20\">\n\t\t\t\t\t\t<path d=\"M5.5 5.5l9 9M14.5 5.5l-9 9\" />\n\t\t\t\t\t</svg>\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t</span>\n\t);\n}\n","import {\n\ttype ObjectFit,\n\tPATTERNMODE_SIZES,\n\ttype PatternmodeSize,\n} from \"@patternmode/system\";\nimport type { ComponentType, HTMLAttributes, SVGProps } from \"react\";\n\nexport const SWATCH_SIZES = PATTERNMODE_SIZES;\n\nexport const SWATCH_SHAPES = [\"circle\", \"pill\", \"square\"] as const;\n\nexport type SwatchSize = PatternmodeSize;\nexport type SwatchShape = (typeof SWATCH_SHAPES)[number];\nexport type SwatchColorStop = string | { color: string; ratio?: number };\ntype SwatchIcon = ComponentType<SVGProps<SVGSVGElement>>;\n\nexport interface SwatchProps extends HTMLAttributes<HTMLSpanElement> {\n\tbackground?: string;\n\tcolor?: string;\n\tcolors?: SwatchColorStop[];\n\ticon?: SwatchIcon;\n\tisLight?: boolean;\n\tobjectFit?: ObjectFit;\n\tobjectPosition?: string;\n\tonRemove?: () => void;\n\traised?: boolean;\n\tselected?: boolean;\n\tshape?: SwatchShape;\n\tshowRing?: boolean;\n\tsize?: SwatchSize;\n\tunavailable?: boolean;\n}\n"],"mappings":"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"}
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer components{.patternmode-swatch{--patternmode-swatch-size:2rem;--patternmode-swatch-fill:#e3e1dc;--patternmode-swatch-radius:999px;aspect-ratio:1;border-radius:var(--patternmode-swatch-radius);color:#fff;height:var(--patternmode-swatch-size);vertical-align:middle;width:var(--patternmode-swatch-size);justify-content:center;align-items:center;transition:box-shadow .14s,opacity .14s,transform .14s;display:inline-flex;position:relative;box-shadow:0 1px 2px #1118271a}.patternmode-swatch[data-tone=light]{color:#1d1d1b}.patternmode-swatch[data-shape=pill]{--patternmode-swatch-radius:999px;aspect-ratio:auto;width:calc(var(--patternmode-swatch-size) * 3)}.patternmode-swatch[data-shape=square]{--patternmode-swatch-radius:7px}.patternmode-swatch[data-raised=true]{box-shadow:0 1px 2px #1118271a, 0 0 0 2px var(--surface,#fff)}.patternmode-swatch[data-selected=true][data-show-ring=true]{box-shadow:0 1px 2px #1118271a, 0 0 0 2px var(--surface,#fff), 0 0 0 4px var(--accent,#315c4b)}.patternmode-swatch[data-unavailable=true]{opacity:.5}.patternmode-swatch__fill,.patternmode-swatch__media,.patternmode-swatch__scrim{border-radius:inherit;position:absolute;inset:0;overflow:hidden}.patternmode-swatch__fill{background:var(--patternmode-swatch-fill)}.patternmode-swatch__media>*{object-fit:inherit;object-position:inherit;width:100%;height:100%;display:block}.patternmode-swatch__scrim{pointer-events:none;background:linear-gradient(#0000 0%,#0003 100%)}.patternmode-swatch__icon{justify-content:center;align-items:center;display:inline-flex;position:absolute;inset:0}.patternmode-swatch__icon svg{stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:2.4px;width:48%;height:48%;display:block}.patternmode-swatch__slash{background:currentColor;border-radius:999px;width:112%;height:2px;position:absolute;transform:rotate(-45deg)}.patternmode-swatch__remove{background:var(--ink,#1d1d1b);color:var(--surface,#fff);cursor:pointer;opacity:0;border:0;border-radius:999px;justify-content:center;align-items:center;width:1.25rem;height:1.25rem;padding:0;transition:background .14s,opacity .14s;display:inline-flex;position:absolute;top:-.35rem;right:-.35rem}.patternmode-swatch:hover .patternmode-swatch__remove,.patternmode-swatch__remove:focus-visible{opacity:1}.patternmode-swatch__remove:hover{background:var(--accent,#315c4b)}.patternmode-swatch__remove:focus-visible{outline:2px solid var(--accent,#315c4b);outline-offset:2px}.patternmode-swatch__remove svg{stroke:currentColor;stroke-linecap:round;stroke-width:2px;width:.8rem;height:.8rem}}
|
package/dist/swatch.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { getSwatchColorsBackground } from "./Swatch/SwatchColors";
|
|
2
|
+
export { Swatch } from "./Swatch/SwatchRoot";
|
|
3
|
+
export { SWATCH_SHAPES, SWATCH_SIZES, type SwatchColorStop, type SwatchProps, type SwatchShape, type SwatchSize, } from "./Swatch/SwatchTypes";
|
|
4
|
+
//# sourceMappingURL=swatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swatch.d.ts","sourceRoot":"","sources":["../src/swatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EACN,aAAa,EACb,YAAY,EACZ,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,UAAU,GACf,MAAM,sBAAsB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@patternmode/swatch",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Color, gradient, image, and palette swatch primitives for Patternmode interfaces.",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": [
|
|
8
|
+
"**/*.css"
|
|
9
|
+
],
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"author": "Daniel Howells",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+ssh://git@github.com/howells/patternmode.git",
|
|
15
|
+
"directory": "packages/swatch"
|
|
16
|
+
},
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/howells/patternmode/issues"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/howells/patternmode/tree/main/packages/swatch#readme",
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"default": "./dist/index.mjs"
|
|
28
|
+
},
|
|
29
|
+
"./styles.css": "./dist/styles.css",
|
|
30
|
+
"./package.json": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=20"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"swatch",
|
|
40
|
+
"palette",
|
|
41
|
+
"color",
|
|
42
|
+
"react",
|
|
43
|
+
"component",
|
|
44
|
+
"patternmode"
|
|
45
|
+
],
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@patternmode/system": "0.2.0"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
51
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@howells/lint": "^0.1.7",
|
|
55
|
+
"@howells/typescript-config": "^0.1.2",
|
|
56
|
+
"@tailwindcss/cli": "^4.3.0",
|
|
57
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
58
|
+
"@testing-library/react": "^16.3.2",
|
|
59
|
+
"@testing-library/user-event": "^14.6.1",
|
|
60
|
+
"@types/react": "^19.2.14",
|
|
61
|
+
"@types/react-dom": "^19.2.3",
|
|
62
|
+
"concurrently": "^9.2.1",
|
|
63
|
+
"jsdom": "^29.1.1",
|
|
64
|
+
"tailwindcss": "^4.3.0",
|
|
65
|
+
"tsdown": "^0.22.0",
|
|
66
|
+
"typescript": "^6.0.3",
|
|
67
|
+
"vitest": "^4.1.6"
|
|
68
|
+
},
|
|
69
|
+
"scripts": {
|
|
70
|
+
"build": "tsdown && tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist --noEmit false && pnpm build:styles",
|
|
71
|
+
"build:styles": "tailwindcss -i ./src/styles.css -o ./dist/styles.css --minify",
|
|
72
|
+
"clean": "rm -rf dist .turbo",
|
|
73
|
+
"dev": "concurrently \"pnpm dev:js\" \"pnpm dev:types\" \"pnpm dev:styles\"",
|
|
74
|
+
"dev:js": "tsdown --watch",
|
|
75
|
+
"dev:styles": "tailwindcss -i ./src/styles.css -o ./dist/styles.css --watch",
|
|
76
|
+
"dev:types": "tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist --noEmit false --watch --preserveWatchOutput",
|
|
77
|
+
"lint:check": "find src -type f \\( -name '*.ts' -o -name '*.tsx' \\) -print0 | xargs -0 howells-biome check",
|
|
78
|
+
"test": "vitest run",
|
|
79
|
+
"typecheck": "tsc --noEmit"
|
|
80
|
+
}
|
|
81
|
+
}
|