@patternmode/swatch 0.7.1 → 0.8.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.
@@ -1,3 +1,3 @@
1
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, removeLabel, role: _role, selected, shape, showRing, size, style, unavailable, ...props }: SwatchProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function Swatch({ "aria-label": ariaLabel, background, children, className, color, colors, flat, icon: Icon, isLight, objectFit, objectPosition, onRemove, raised, removeLabel, role: _role, selected, shape, showRing, size, style, unavailable, ...props }: SwatchProps): import("react/jsx-runtime").JSX.Element;
3
3
  //# sourceMappingURL=SwatchRoot.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SwatchRoot.d.ts","sourceRoot":"","sources":["../../src/Swatch/SwatchRoot.tsx"],"names":[],"mappings":"AAIA,OAAO,EAA8B,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE7E,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,WAAW,EACX,IAAI,EAAE,KAAK,EACX,QAAgB,EAChB,KAAgB,EAChB,QAAe,EACf,IAAa,EACb,KAAK,EACL,WAAmB,EACnB,GAAG,KAAK,EACR,EAAE,WAAW,2CAgGb"}
1
+ {"version":3,"file":"SwatchRoot.d.ts","sourceRoot":"","sources":["../../src/Swatch/SwatchRoot.tsx"],"names":[],"mappings":"AAIA,OAAO,EAA8B,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAE7E,wBAAgB,MAAM,CAAC,EACtB,YAAY,EAAE,SAAS,EACvB,UAAU,EACV,QAAQ,EACR,SAAS,EACT,KAAK,EACL,MAAM,EACN,IAAY,EACZ,IAAI,EAAE,IAAI,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,QAAQ,EACR,MAAc,EACd,WAAW,EACX,IAAI,EAAE,KAAK,EACX,QAAgB,EAChB,KAAgB,EAChB,QAAe,EACf,IAAa,EACb,KAAK,EACL,WAAmB,EACnB,GAAG,KAAK,EACR,EAAE,WAAW,2CAoGb"}
@@ -28,6 +28,12 @@ export interface SwatchProps extends HTMLAttributes<HTMLElement> {
28
28
  background?: string;
29
29
  color?: string;
30
30
  colors?: SwatchColorStop[];
31
+ /**
32
+ * Render a precise, flat color block: no top-to-bottom scrim gradient and
33
+ * no drop shadow. Use for data visualisation where the fill must read as
34
+ * the exact color value.
35
+ */
36
+ flat?: boolean;
31
37
  icon?: SwatchIcon;
32
38
  isLight?: boolean;
33
39
  objectFit?: ObjectFit;
@@ -1 +1 @@
1
- {"version":3,"file":"SwatchTypes.d.ts","sourceRoot":"","sources":["../../src/Swatch/SwatchTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,SAAS,EAGd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAErE,eAAO,MAAM,YAAY,4FAMf,CAAC;AAEX,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;CAMgB,CAAC;AAEhD,eAAO,MAAM,aAAa,gDAAiD,CAAC;AAE5E,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AACvD,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,wBAAgB,0BAA0B,CACzC,IAAI,EAAE,UAAU,EAChB,YAAY,SAA8B,GACxC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIxB;AAED,MAAM,WAAW,WAAY,SAAQ,cAAc,CAAC,WAAW,CAAC;IAC/D,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,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,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"}
1
+ {"version":3,"file":"SwatchTypes.d.ts","sourceRoot":"","sources":["../../src/Swatch/SwatchTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,SAAS,EAGd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAErE,eAAO,MAAM,YAAY,4FAMf,CAAC;AAEX,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;CAMgB,CAAC;AAEhD,eAAO,MAAM,aAAa,gDAAiD,CAAC;AAE5E,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AACvD,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,wBAAgB,0BAA0B,CACzC,IAAI,EAAE,UAAU,EAChB,YAAY,SAA8B,GACxC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIxB;AAED,MAAM,WAAW,WAAY,SAAQ,cAAc,CAAC,WAAW,CAAC;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,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,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,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"}
package/dist/index.mjs CHANGED
@@ -354,7 +354,7 @@ function getSwatchSizeVariableStyle(size, variableName = "--patternmode-swatch-s
354
354
  }
355
355
  //#endregion
356
356
  //#region src/Swatch/SwatchRoot.tsx
357
- function Swatch({ "aria-label": ariaLabel, background, children, className, color, colors, icon: Icon, isLight, objectFit, objectPosition, onRemove, raised = false, removeLabel, role: _role, selected = false, shape = "circle", showRing = true, size = "base", style, unavailable = false, ...props }) {
357
+ function Swatch({ "aria-label": ariaLabel, background, children, className, color, colors, flat = false, icon: Icon, isLight, objectFit, objectPosition, onRemove, raised = false, removeLabel, role: _role, selected = false, shape = "circle", showRing = true, size = "base", style, unavailable = false, ...props }) {
358
358
  const colorsBackground = getSwatchColorsBackground(colors);
359
359
  const fill = background ?? colorsBackground ?? color;
360
360
  const light = isLight ?? (color && !background && !colorsBackground ? isLightColor(color) : false);
@@ -382,7 +382,7 @@ function Swatch({ "aria-label": ariaLabel, background, children, className, colo
382
382
  style: mediaStyle,
383
383
  children
384
384
  }) : null,
385
- /* @__PURE__ */ jsx("span", {
385
+ flat ? null : /* @__PURE__ */ jsx("span", {
386
386
  "aria-hidden": "true",
387
387
  className: "patternmode-swatch__scrim"
388
388
  }),
@@ -402,6 +402,7 @@ function Swatch({ "aria-label": ariaLabel, background, children, className, colo
402
402
  ...props,
403
403
  "aria-label": ariaLabel,
404
404
  className: joinClassNames("patternmode-swatch", className),
405
+ "data-flat": flat ? "true" : void 0,
405
406
  "data-raised": raised ? "true" : void 0,
406
407
  "data-selected": selected ? "true" : void 0,
407
408
  "data-shape": shape,
@@ -428,6 +429,7 @@ function Swatch({ "aria-label": ariaLabel, background, children, className, colo
428
429
  ...props,
429
430
  "aria-label": ariaLabel,
430
431
  className: joinClassNames("patternmode-swatch", className),
432
+ "data-flat": flat ? "true" : void 0,
431
433
  "data-raised": raised ? "true" : void 0,
432
434
  "data-selected": selected ? "true" : void 0,
433
435
  "data-shape": shape,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/DistributionBar/DistributionBarMath.ts","../src/DistributionBar/DistributionBarRoot.tsx","../src/Swatch/SwatchColors.ts","../src/Swatch/SwatchTypes.ts","../src/Swatch/SwatchRoot.tsx"],"sourcesContent":["export interface DistributionBarSegment {\n\tcolor: string;\n\tid: string;\n\tlabel?: string;\n\tvalue: number;\n}\n\nexport type DistributionBarSegmentUpdate = Partial<\n\tOmit<DistributionBarSegment, \"value\">\n> & {\n\tvalue?: never;\n};\n\nexport function getDistributionTotal(\n\tsegments: DistributionBarSegment[],\n): number {\n\treturn segments.reduce(\n\t\t(sum, segment) => sum + sanitizeValue(segment.value),\n\t\t0,\n\t);\n}\n\nexport function getDistributionBoundaryPercent(\n\tsegments: DistributionBarSegment[],\n\tboundaryIndex: number,\n): number {\n\tconst total = getDistributionTotal(segments);\n\tif (total <= 0) {\n\t\treturn 0;\n\t}\n\n\tconst boundaryValue = segments\n\t\t.slice(0, boundaryIndex + 1)\n\t\t.reduce((sum, segment) => sum + sanitizeValue(segment.value), 0);\n\treturn roundValue((boundaryValue / total) * 100);\n}\n\nexport function moveDistributionBoundary(\n\tsegments: DistributionBarSegment[],\n\tboundaryIndex: number,\n\tdeltaValue: number,\n\tminValue: number,\n): DistributionBarSegment[] {\n\tconst left = segments[boundaryIndex];\n\tconst right = segments[boundaryIndex + 1];\n\tif (!(left && right)) {\n\t\treturn segments;\n\t}\n\n\tconst pairTotal = sanitizeValue(left.value) + sanitizeValue(right.value);\n\tconst clampedMin = Math.max(0, Math.min(minValue, pairTotal / 2));\n\tconst nextLeft = clamp(\n\t\tsanitizeValue(left.value) + deltaValue,\n\t\tclampedMin,\n\t\tpairTotal - clampedMin,\n\t);\n\tconst nextRight = pairTotal - nextLeft;\n\n\treturn segments.map((segment, index) => {\n\t\tif (index === boundaryIndex) {\n\t\t\treturn { ...segment, value: roundValue(nextLeft) };\n\t\t}\n\t\tif (index === boundaryIndex + 1) {\n\t\t\treturn { ...segment, value: roundValue(nextRight) };\n\t\t}\n\t\treturn segment;\n\t});\n}\n\nexport function removeDistributionSegment(\n\tsegments: DistributionBarSegment[],\n\tsegmentId: string,\n): DistributionBarSegment[] {\n\tif (segments.length <= 1) {\n\t\treturn segments;\n\t}\n\n\tconst removed = segments.find((segment) => segment.id === segmentId);\n\tif (!removed) {\n\t\treturn segments;\n\t}\n\n\tconst remaining = segments.filter((segment) => segment.id !== segmentId);\n\tconst removedValue = sanitizeValue(removed.value);\n\tconst remainingTotal = getDistributionTotal(remaining);\n\tif (remainingTotal <= 0) {\n\t\tconst equalValue = removedValue / remaining.length;\n\t\treturn remaining.map((segment) => ({\n\t\t\t...segment,\n\t\t\tvalue: roundValue(equalValue),\n\t\t}));\n\t}\n\n\tlet assignedValue = 0;\n\tconst originalTotal = getDistributionTotal(segments);\n\treturn remaining.map((segment, index) => {\n\t\tif (index === remaining.length - 1) {\n\t\t\treturn { ...segment, value: roundValue(originalTotal - assignedValue) };\n\t\t}\n\n\t\tconst nextValue = roundValue(\n\t\t\tsanitizeValue(segment.value) +\n\t\t\t\t(removedValue * sanitizeValue(segment.value)) / remainingTotal,\n\t\t);\n\t\tassignedValue += nextValue;\n\t\treturn { ...segment, value: nextValue };\n\t});\n}\n\nexport function updateDistributionSegment(\n\tsegments: DistributionBarSegment[],\n\tsegmentId: string,\n\tupdate: DistributionBarSegmentUpdate,\n): DistributionBarSegment[] {\n\treturn segments.map((segment) =>\n\t\tsegment.id === segmentId ? { ...segment, ...update } : segment,\n\t);\n}\n\nfunction sanitizeValue(value: number): number {\n\treturn Number.isFinite(value) ? Math.max(0, value) : 0;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n\treturn Math.min(Math.max(value, min), max);\n}\n\nfunction roundValue(value: number): number {\n\treturn Number(value.toFixed(1));\n}\n","import { joinClassNames } from \"@patternmode/system\";\nimport { motion, type PanInfo } from \"motion/react\";\nimport type { CSSProperties, HTMLAttributes, KeyboardEvent } from \"react\";\nimport { useRef } from \"react\";\n\nimport {\n\ttype DistributionBarSegment,\n\tgetDistributionBoundaryPercent,\n\tgetDistributionTotal,\n\tmoveDistributionBoundary,\n} from \"./DistributionBarMath\";\n\nexport interface DistributionDisplayProps\n\textends Omit<HTMLAttributes<HTMLDivElement>, \"role\" | \"onSelect\"> {\n\tassignedLabel?: string;\n\temptyLabel?: string;\n\temptyValue?: number;\n\tlegend?: \"segments\" | \"summary\" | false;\n\t/**\n\t * When provided, each segment renders as a button and selecting one\n\t * invokes this callback. Pair with `selectedSegmentId` to mark a segment\n\t * as selected (renders a ring). Read-only by default.\n\t */\n\tonSegmentSelect?: (segment: DistributionBarSegment) => void;\n\tsegments: DistributionBarSegment[];\n\t/** Id of the selected segment — renders a ring on that segment. */\n\tselectedSegmentId?: string;\n}\n\nexport interface DistributionBarProps\n\textends Omit<HTMLAttributes<HTMLFieldSetElement>, \"onChange\"> {\n\t/** Show the per-segment legend below the bar, or hide it. Default \"segments\". */\n\tlegend?: \"segments\" | false;\n\tminValue?: number;\n\tonChange?: (segments: DistributionBarSegment[]) => void;\n\tsegments: DistributionBarSegment[];\n\tstep?: number;\n}\n\nexport function DistributionDisplay({\n\t\"aria-label\": ariaLabel,\n\tassignedLabel = \"assigned\",\n\tclassName,\n\temptyLabel = \"unassigned\",\n\temptyValue = 0,\n\tlegend = \"segments\",\n\tonSegmentSelect,\n\tsegments,\n\tselectedSegmentId,\n\t...props\n}: DistributionDisplayProps) {\n\tconst total = getDistributionDisplayTotal(segments, emptyValue);\n\tconst interactive = Boolean(onSegmentSelect);\n\tconst accessibleLabel =\n\t\tariaLabel ??\n\t\tgetDistributionDisplayAccessibleLabel(\n\t\t\tsegments,\n\t\t\temptyValue,\n\t\t\temptyLabel,\n\t\t\ttotal,\n\t\t);\n\n\tconst content = (\n\t\t<>\n\t\t\t<div className=\"patternmode-distribution-bar__track\">\n\t\t\t\t<DistributionSegments\n\t\t\t\t\temptyValue={emptyValue}\n\t\t\t\t\tonSegmentSelect={onSegmentSelect}\n\t\t\t\t\tsegments={segments}\n\t\t\t\t\tselectedSegmentId={selectedSegmentId}\n\t\t\t\t\ttotal={total}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t\t{legend === \"segments\" ? (\n\t\t\t\t<DistributionSegmentLegend\n\t\t\t\t\temptyLabel={emptyLabel}\n\t\t\t\t\temptyValue={emptyValue}\n\t\t\t\t\tsegments={segments}\n\t\t\t\t\ttotal={total}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t{legend === \"summary\" ? (\n\t\t\t\t<DistributionSummaryLegend\n\t\t\t\t\tassignedLabel={assignedLabel}\n\t\t\t\t\temptyLabel={emptyLabel}\n\t\t\t\t\temptyValue={emptyValue}\n\t\t\t\t\ttotal={total}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t</>\n\t);\n\tconst sharedClassName = joinClassNames(\n\t\t\"patternmode-distribution-display\",\n\t\tclassName,\n\t);\n\n\t// A selectable distribution is a group of buttons (fieldset → implicit\n\t// group role); a read-only one is an image. Static elements (not a ternary\n\t// role on one node) so a11y lint can verify aria support.\n\treturn interactive ? (\n\t\t<fieldset\n\t\t\t{...(props as HTMLAttributes<HTMLFieldSetElement>)}\n\t\t\taria-label={accessibleLabel}\n\t\t\tclassName={sharedClassName}\n\t\t\tdata-slot=\"distribution-display\"\n\t\t>\n\t\t\t{content}\n\t\t</fieldset>\n\t) : (\n\t\t<div\n\t\t\t{...props}\n\t\t\taria-label={accessibleLabel}\n\t\t\tclassName={sharedClassName}\n\t\t\tdata-slot=\"distribution-display\"\n\t\t\trole=\"img\"\n\t\t>\n\t\t\t{content}\n\t\t</div>\n\t);\n}\n\nexport function DistributionBar({\n\t\"aria-label\": ariaLabel,\n\tclassName,\n\tlegend = \"segments\",\n\tminValue = 4,\n\tonChange,\n\tsegments,\n\tstep = 1,\n\t...props\n}: DistributionBarProps) {\n\tconst trackRef = useRef<HTMLDivElement>(null);\n\tconst dragStartSegmentsRef = useRef<DistributionBarSegment[] | null>(null);\n\tconst total = getDistributionTotal(segments);\n\n\tfunction moveBoundary(\n\t\tboundaryIndex: number,\n\t\tdeltaValue: number,\n\t\tsourceSegments = segments,\n\t) {\n\t\tonChange?.(\n\t\t\tmoveDistributionBoundary(\n\t\t\t\tsourceSegments,\n\t\t\t\tboundaryIndex,\n\t\t\t\tdeltaValue,\n\t\t\t\tminValue,\n\t\t\t),\n\t\t);\n\t}\n\n\tfunction handleDragStart() {\n\t\tdragStartSegmentsRef.current = segments;\n\t}\n\n\tfunction handleDrag(boundaryIndex: number, info: PanInfo) {\n\t\tconst sourceSegments = dragStartSegmentsRef.current ?? segments;\n\t\tconst sourceTotal = getDistributionTotal(sourceSegments);\n\t\tconst trackWidth = trackRef.current?.getBoundingClientRect().width ?? 0;\n\t\tif (!(trackWidth > 0 && sourceTotal > 0)) {\n\t\t\treturn;\n\t\t}\n\n\t\tmoveBoundary(\n\t\t\tboundaryIndex,\n\t\t\t(info.offset.x / trackWidth) * sourceTotal,\n\t\t\tsourceSegments,\n\t\t);\n\t}\n\n\tfunction handleDragEnd(boundaryIndex: number, info: PanInfo) {\n\t\thandleDrag(boundaryIndex, info);\n\t\tdragStartSegmentsRef.current = null;\n\t}\n\n\tfunction handleKeyDown(\n\t\tevent: KeyboardEvent<HTMLButtonElement>,\n\t\tboundaryIndex: number,\n\t) {\n\t\tif (event.key === \"ArrowLeft\") {\n\t\t\tevent.preventDefault();\n\t\t\tmoveBoundary(boundaryIndex, -step);\n\t\t}\n\t\tif (event.key === \"ArrowRight\") {\n\t\t\tevent.preventDefault();\n\t\t\tmoveBoundary(boundaryIndex, step);\n\t\t}\n\t}\n\n\treturn (\n\t\t<fieldset\n\t\t\t{...props}\n\t\t\taria-label={ariaLabel}\n\t\t\tclassName={joinClassNames(\"patternmode-distribution-bar\", className)}\n\t\t\tdata-slot=\"distribution-bar\"\n\t\t>\n\t\t\t<div className=\"patternmode-distribution-bar__track\" ref={trackRef}>\n\t\t\t\t<DistributionSegments segments={segments} total={total} />\n\t\t\t\t{segments.slice(0, -1).map((segment, boundaryIndex) => {\n\t\t\t\t\tconst nextSegment = segments[boundaryIndex + 1];\n\t\t\t\t\tconst boundaryPercent = getDistributionBoundaryPercent(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tboundaryIndex,\n\t\t\t\t\t);\n\t\t\t\t\tconst label = `Adjust ${segment.label ?? segment.id} and ${\n\t\t\t\t\t\tnextSegment?.label ?? nextSegment?.id\n\t\t\t\t\t} distribution`;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<DistributionBarHandle\n\t\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\t\tboundaryPercent={boundaryPercent}\n\t\t\t\t\t\t\tkey={`${segment.id}-${nextSegment?.id ?? \"end\"}`}\n\t\t\t\t\t\t\tonDrag={(info) => handleDrag(boundaryIndex, info)}\n\t\t\t\t\t\t\tonDragEnd={(info) => handleDragEnd(boundaryIndex, info)}\n\t\t\t\t\t\t\tonDragStart={handleDragStart}\n\t\t\t\t\t\t\tonKeyDown={(event) => handleKeyDown(event, boundaryIndex)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t\t{legend === \"segments\" ? (\n\t\t\t\t<DistributionSegmentLegend segments={segments} total={total} />\n\t\t\t) : null}\n\t\t</fieldset>\n\t);\n}\n\ninterface DistributionSegmentsProps {\n\temptyValue?: number;\n\tonSegmentSelect?: (segment: DistributionBarSegment) => void;\n\tsegments: DistributionBarSegment[];\n\tselectedSegmentId?: string;\n\ttotal: number;\n}\n\nfunction DistributionSegments({\n\temptyValue = 0,\n\tonSegmentSelect,\n\tsegments,\n\tselectedSegmentId,\n\ttotal,\n}: DistributionSegmentsProps) {\n\treturn (\n\t\t<div className=\"patternmode-distribution-bar__segments\">\n\t\t\t{segments.map((segment) => {\n\t\t\t\tconst segmentStyle = {\n\t\t\t\t\t\"--patternmode-distribution-segment-color\": segment.color,\n\t\t\t\t\twidth:\n\t\t\t\t\t\ttotal > 0\n\t\t\t\t\t\t\t? `${(getRenderableDistributionValue(segment.value) / total) * 100}%`\n\t\t\t\t\t\t\t: \"0%\",\n\t\t\t\t} as CSSProperties;\n\t\t\t\tconst isSelected = selectedSegmentId === segment.id;\n\n\t\t\t\tif (onSegmentSelect) {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\taria-label={`${segment.label ?? segment.id} ${getDerivedDistributionPercentage(segment.value, total)}%`}\n\t\t\t\t\t\t\taria-pressed={isSelected}\n\t\t\t\t\t\t\tclassName=\"patternmode-distribution-bar__segment\"\n\t\t\t\t\t\t\tdata-selected={isSelected ? \"true\" : undefined}\n\t\t\t\t\t\t\tkey={segment.id}\n\t\t\t\t\t\t\tonClick={() => onSegmentSelect(segment)}\n\t\t\t\t\t\t\tstyle={segmentStyle}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\tclassName=\"patternmode-distribution-bar__segment\"\n\t\t\t\t\t\tdata-selected={isSelected ? \"true\" : undefined}\n\t\t\t\t\t\tkey={segment.id}\n\t\t\t\t\t\tstyle={segmentStyle}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\t})}\n\t\t\t{emptyValue > 0 ? (\n\t\t\t\t<div\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tclassName=\"patternmode-distribution-bar__segment patternmode-distribution-bar__segment--empty\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\twidth:\n\t\t\t\t\t\t\ttotal > 0\n\t\t\t\t\t\t\t\t? `${(getRenderableDistributionValue(emptyValue) / total) * 100}%`\n\t\t\t\t\t\t\t\t: \"0%\",\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n\ninterface DistributionSegmentLegendProps {\n\temptyLabel?: string;\n\temptyValue?: number;\n\tsegments: DistributionBarSegment[];\n\ttotal: number;\n}\n\nfunction DistributionSegmentLegend({\n\temptyLabel,\n\temptyValue = 0,\n\tsegments,\n\ttotal,\n}: DistributionSegmentLegendProps) {\n\treturn (\n\t\t<div className=\"patternmode-distribution-bar__legend\">\n\t\t\t{segments.map((segment) => (\n\t\t\t\t<span key={segment.id}>\n\t\t\t\t\t<span\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\tclassName=\"patternmode-distribution-bar__swatch\"\n\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"--patternmode-distribution-segment-color\": segment.color,\n\t\t\t\t\t\t\t} as CSSProperties\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t\t{segment.label ?? segment.id}{\" \"}\n\t\t\t\t\t{getDerivedDistributionPercentage(segment.value, total)}%\n\t\t\t\t</span>\n\t\t\t))}\n\t\t\t{emptyValue > 0 && emptyLabel ? (\n\t\t\t\t<span>\n\t\t\t\t\t<span\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\tclassName=\"patternmode-distribution-bar__swatch patternmode-distribution-bar__swatch--empty\"\n\t\t\t\t\t/>\n\t\t\t\t\t{emptyLabel} {getDerivedDistributionPercentage(emptyValue, total)}%\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n\ninterface DistributionSummaryLegendProps {\n\tassignedLabel: string;\n\temptyLabel: string;\n\temptyValue: number;\n\ttotal: number;\n}\n\nfunction DistributionSummaryLegend({\n\tassignedLabel,\n\temptyLabel,\n\temptyValue,\n\ttotal,\n}: DistributionSummaryLegendProps) {\n\tconst emptyPercentage = getDerivedDistributionPercentage(emptyValue, total);\n\n\treturn (\n\t\t<div className=\"patternmode-distribution-bar__legend\">\n\t\t\t<span>\n\t\t\t\t{Math.max(0, 100 - emptyPercentage)}% {assignedLabel}\n\t\t\t</span>\n\t\t\t{emptyValue > 0 ? (\n\t\t\t\t<span>\n\t\t\t\t\t{emptyPercentage}% {emptyLabel}\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n\nfunction getDistributionDisplayTotal(\n\tsegments: DistributionBarSegment[],\n\temptyValue: number,\n): number {\n\treturn (\n\t\tgetDistributionTotal(segments) + getRenderableDistributionValue(emptyValue)\n\t);\n}\n\nfunction getDistributionDisplayAccessibleLabel(\n\tsegments: DistributionBarSegment[],\n\temptyValue: number,\n\temptyLabel: string,\n\ttotal: number,\n): string {\n\tconst segmentLabels = segments.map(\n\t\t(segment) =>\n\t\t\t`${segment.label ?? segment.id} ${getDerivedDistributionPercentage(\n\t\t\t\tsegment.value,\n\t\t\t\ttotal,\n\t\t\t)}%`,\n\t);\n\tif (emptyValue > 0) {\n\t\tsegmentLabels.push(\n\t\t\t`${emptyLabel} ${getDerivedDistributionPercentage(emptyValue, total)}%`,\n\t\t);\n\t}\n\n\treturn segmentLabels.join(\", \");\n}\n\nfunction getDerivedDistributionPercentage(\n\tvalue: number,\n\ttotal: number,\n): number {\n\tif (!(total > 0 && Number.isFinite(value))) {\n\t\treturn 0;\n\t}\n\n\treturn Math.round((Math.max(0, value) / total) * 100);\n}\n\nfunction getRenderableDistributionValue(value: number): number {\n\treturn Number.isFinite(value) ? Math.max(0, value) : 0;\n}\n\ninterface DistributionBarHandleProps {\n\t\"aria-label\": string;\n\tboundaryPercent: number;\n\tonDrag: (info: PanInfo) => void;\n\tonDragEnd: (info: PanInfo) => void;\n\tonDragStart: () => void;\n\tonKeyDown: (event: KeyboardEvent<HTMLButtonElement>) => void;\n}\n\nfunction DistributionBarHandle({\n\t\"aria-label\": ariaLabel,\n\tboundaryPercent,\n\tonDrag,\n\tonDragEnd,\n\tonDragStart,\n\tonKeyDown,\n}: DistributionBarHandleProps) {\n\treturn (\n\t\t<motion.button\n\t\t\taria-label={ariaLabel}\n\t\t\tclassName=\"patternmode-distribution-bar__handle\"\n\t\t\tdrag=\"x\"\n\t\t\tdragElastic={0}\n\t\t\tdragMomentum={false}\n\t\t\tdragSnapToOrigin\n\t\t\tonDrag={(_event, info) => onDrag(info)}\n\t\t\tonDragEnd={(_event, info) => onDragEnd(info)}\n\t\t\tonDragStart={onDragStart}\n\t\t\tonKeyDown={onKeyDown}\n\t\t\tstyle={{ left: `calc(${boundaryPercent}% - 1.375rem)` }}\n\t\t\ttransformTemplate={() => \"none\"}\n\t\t\ttype=\"button\"\n\t\t/>\n\t);\n}\n","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\ttype ObjectFit,\n\tPATTERNMODE_SIZE_VALUES,\n\tPATTERNMODE_SIZES,\n} from \"@patternmode/system\";\nimport type { ComponentType, HTMLAttributes, SVGProps } from \"react\";\n\nexport const SWATCH_SIZES = [\n\t...PATTERNMODE_SIZES,\n\t\"4xl\",\n\t\"5xl\",\n\t\"6xl\",\n\t\"7xl\",\n] as const;\n\nexport const SWATCH_SIZE_VALUES = {\n\t...PATTERNMODE_SIZE_VALUES,\n\t\"4xl\": \"4.5rem\",\n\t\"5xl\": \"5rem\",\n\t\"6xl\": \"5.5rem\",\n\t\"7xl\": \"6rem\",\n} as const satisfies Record<SwatchSize, string>;\n\nexport const SWATCH_SHAPES = [\"circle\", \"pill\", \"square\", \"block\"] as const;\n\nexport type SwatchSize = (typeof SWATCH_SIZES)[number];\nexport type SwatchShape = (typeof SWATCH_SHAPES)[number];\nexport type SwatchColorStop = string | { color: string; ratio?: number };\ntype SwatchIcon = ComponentType<SVGProps<SVGSVGElement>>;\n\nexport function getSwatchSizeVariableStyle(\n\tsize: SwatchSize,\n\tvariableName = \"--patternmode-swatch-size\",\n): Record<string, string> {\n\treturn {\n\t\t[variableName]: SWATCH_SIZE_VALUES[size],\n\t};\n}\n\nexport interface SwatchProps extends HTMLAttributes<HTMLElement> {\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\tremoveLabel?: string;\n\tselected?: boolean;\n\tshape?: SwatchShape;\n\tshowRing?: boolean;\n\tsize?: SwatchSize;\n\tunavailable?: boolean;\n}\n","import { getObjectSizingStyle, joinClassNames } from \"@patternmode/system\";\nimport type { CSSProperties, MouseEvent } from \"react\";\n\nimport { getSwatchColorsBackground, isLightColor } from \"./SwatchColors\";\nimport { getSwatchSizeVariableStyle, 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\tremoveLabel,\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\tconst resolvedRemoveLabel =\n\t\tremoveLabel ?? (ariaLabel ? `Remove ${ariaLabel}` : \"Remove\");\n\n\tconst rootStyle = {\n\t\t...getSwatchSizeVariableStyle(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\tconst swatchContent = (\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</>\n\t);\n\n\tif (onRemove) {\n\t\treturn (\n\t\t\t<fieldset\n\t\t\t\t{...props}\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\tclassName={joinClassNames(\"patternmode-swatch\", className)}\n\t\t\t\tdata-raised={raised ? \"true\" : undefined}\n\t\t\t\tdata-selected={selected ? \"true\" : undefined}\n\t\t\t\tdata-shape={shape}\n\t\t\t\tdata-show-ring={showRing ? \"true\" : \"false\"}\n\t\t\t\tdata-size={size}\n\t\t\t\tdata-slot=\"swatch\"\n\t\t\t\tdata-tone={light ? \"light\" : \"dark\"}\n\t\t\t\tdata-unavailable={unavailable ? \"true\" : undefined}\n\t\t\t\tstyle={rootStyle}\n\t\t\t>\n\t\t\t\t{swatchContent}\n\t\t\t\t<button\n\t\t\t\t\taria-label={resolvedRemoveLabel}\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</fieldset>\n\t\t);\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{swatchContent}\n\t\t</span>\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/DistributionBar/DistributionBarMath.ts","../src/DistributionBar/DistributionBarRoot.tsx","../src/Swatch/SwatchColors.ts","../src/Swatch/SwatchTypes.ts","../src/Swatch/SwatchRoot.tsx"],"sourcesContent":["export interface DistributionBarSegment {\n\tcolor: string;\n\tid: string;\n\tlabel?: string;\n\tvalue: number;\n}\n\nexport type DistributionBarSegmentUpdate = Partial<\n\tOmit<DistributionBarSegment, \"value\">\n> & {\n\tvalue?: never;\n};\n\nexport function getDistributionTotal(\n\tsegments: DistributionBarSegment[],\n): number {\n\treturn segments.reduce(\n\t\t(sum, segment) => sum + sanitizeValue(segment.value),\n\t\t0,\n\t);\n}\n\nexport function getDistributionBoundaryPercent(\n\tsegments: DistributionBarSegment[],\n\tboundaryIndex: number,\n): number {\n\tconst total = getDistributionTotal(segments);\n\tif (total <= 0) {\n\t\treturn 0;\n\t}\n\n\tconst boundaryValue = segments\n\t\t.slice(0, boundaryIndex + 1)\n\t\t.reduce((sum, segment) => sum + sanitizeValue(segment.value), 0);\n\treturn roundValue((boundaryValue / total) * 100);\n}\n\nexport function moveDistributionBoundary(\n\tsegments: DistributionBarSegment[],\n\tboundaryIndex: number,\n\tdeltaValue: number,\n\tminValue: number,\n): DistributionBarSegment[] {\n\tconst left = segments[boundaryIndex];\n\tconst right = segments[boundaryIndex + 1];\n\tif (!(left && right)) {\n\t\treturn segments;\n\t}\n\n\tconst pairTotal = sanitizeValue(left.value) + sanitizeValue(right.value);\n\tconst clampedMin = Math.max(0, Math.min(minValue, pairTotal / 2));\n\tconst nextLeft = clamp(\n\t\tsanitizeValue(left.value) + deltaValue,\n\t\tclampedMin,\n\t\tpairTotal - clampedMin,\n\t);\n\tconst nextRight = pairTotal - nextLeft;\n\n\treturn segments.map((segment, index) => {\n\t\tif (index === boundaryIndex) {\n\t\t\treturn { ...segment, value: roundValue(nextLeft) };\n\t\t}\n\t\tif (index === boundaryIndex + 1) {\n\t\t\treturn { ...segment, value: roundValue(nextRight) };\n\t\t}\n\t\treturn segment;\n\t});\n}\n\nexport function removeDistributionSegment(\n\tsegments: DistributionBarSegment[],\n\tsegmentId: string,\n): DistributionBarSegment[] {\n\tif (segments.length <= 1) {\n\t\treturn segments;\n\t}\n\n\tconst removed = segments.find((segment) => segment.id === segmentId);\n\tif (!removed) {\n\t\treturn segments;\n\t}\n\n\tconst remaining = segments.filter((segment) => segment.id !== segmentId);\n\tconst removedValue = sanitizeValue(removed.value);\n\tconst remainingTotal = getDistributionTotal(remaining);\n\tif (remainingTotal <= 0) {\n\t\tconst equalValue = removedValue / remaining.length;\n\t\treturn remaining.map((segment) => ({\n\t\t\t...segment,\n\t\t\tvalue: roundValue(equalValue),\n\t\t}));\n\t}\n\n\tlet assignedValue = 0;\n\tconst originalTotal = getDistributionTotal(segments);\n\treturn remaining.map((segment, index) => {\n\t\tif (index === remaining.length - 1) {\n\t\t\treturn { ...segment, value: roundValue(originalTotal - assignedValue) };\n\t\t}\n\n\t\tconst nextValue = roundValue(\n\t\t\tsanitizeValue(segment.value) +\n\t\t\t\t(removedValue * sanitizeValue(segment.value)) / remainingTotal,\n\t\t);\n\t\tassignedValue += nextValue;\n\t\treturn { ...segment, value: nextValue };\n\t});\n}\n\nexport function updateDistributionSegment(\n\tsegments: DistributionBarSegment[],\n\tsegmentId: string,\n\tupdate: DistributionBarSegmentUpdate,\n): DistributionBarSegment[] {\n\treturn segments.map((segment) =>\n\t\tsegment.id === segmentId ? { ...segment, ...update } : segment,\n\t);\n}\n\nfunction sanitizeValue(value: number): number {\n\treturn Number.isFinite(value) ? Math.max(0, value) : 0;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n\treturn Math.min(Math.max(value, min), max);\n}\n\nfunction roundValue(value: number): number {\n\treturn Number(value.toFixed(1));\n}\n","import { joinClassNames } from \"@patternmode/system\";\nimport { motion, type PanInfo } from \"motion/react\";\nimport type { CSSProperties, HTMLAttributes, KeyboardEvent } from \"react\";\nimport { useRef } from \"react\";\n\nimport {\n\ttype DistributionBarSegment,\n\tgetDistributionBoundaryPercent,\n\tgetDistributionTotal,\n\tmoveDistributionBoundary,\n} from \"./DistributionBarMath\";\n\nexport interface DistributionDisplayProps\n\textends Omit<HTMLAttributes<HTMLDivElement>, \"role\" | \"onSelect\"> {\n\tassignedLabel?: string;\n\temptyLabel?: string;\n\temptyValue?: number;\n\tlegend?: \"segments\" | \"summary\" | false;\n\t/**\n\t * When provided, each segment renders as a button and selecting one\n\t * invokes this callback. Pair with `selectedSegmentId` to mark a segment\n\t * as selected (renders a ring). Read-only by default.\n\t */\n\tonSegmentSelect?: (segment: DistributionBarSegment) => void;\n\tsegments: DistributionBarSegment[];\n\t/** Id of the selected segment — renders a ring on that segment. */\n\tselectedSegmentId?: string;\n}\n\nexport interface DistributionBarProps\n\textends Omit<HTMLAttributes<HTMLFieldSetElement>, \"onChange\"> {\n\t/** Show the per-segment legend below the bar, or hide it. Default \"segments\". */\n\tlegend?: \"segments\" | false;\n\tminValue?: number;\n\tonChange?: (segments: DistributionBarSegment[]) => void;\n\tsegments: DistributionBarSegment[];\n\tstep?: number;\n}\n\nexport function DistributionDisplay({\n\t\"aria-label\": ariaLabel,\n\tassignedLabel = \"assigned\",\n\tclassName,\n\temptyLabel = \"unassigned\",\n\temptyValue = 0,\n\tlegend = \"segments\",\n\tonSegmentSelect,\n\tsegments,\n\tselectedSegmentId,\n\t...props\n}: DistributionDisplayProps) {\n\tconst total = getDistributionDisplayTotal(segments, emptyValue);\n\tconst interactive = Boolean(onSegmentSelect);\n\tconst accessibleLabel =\n\t\tariaLabel ??\n\t\tgetDistributionDisplayAccessibleLabel(\n\t\t\tsegments,\n\t\t\temptyValue,\n\t\t\temptyLabel,\n\t\t\ttotal,\n\t\t);\n\n\tconst content = (\n\t\t<>\n\t\t\t<div className=\"patternmode-distribution-bar__track\">\n\t\t\t\t<DistributionSegments\n\t\t\t\t\temptyValue={emptyValue}\n\t\t\t\t\tonSegmentSelect={onSegmentSelect}\n\t\t\t\t\tsegments={segments}\n\t\t\t\t\tselectedSegmentId={selectedSegmentId}\n\t\t\t\t\ttotal={total}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t\t{legend === \"segments\" ? (\n\t\t\t\t<DistributionSegmentLegend\n\t\t\t\t\temptyLabel={emptyLabel}\n\t\t\t\t\temptyValue={emptyValue}\n\t\t\t\t\tsegments={segments}\n\t\t\t\t\ttotal={total}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t{legend === \"summary\" ? (\n\t\t\t\t<DistributionSummaryLegend\n\t\t\t\t\tassignedLabel={assignedLabel}\n\t\t\t\t\temptyLabel={emptyLabel}\n\t\t\t\t\temptyValue={emptyValue}\n\t\t\t\t\ttotal={total}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t</>\n\t);\n\tconst sharedClassName = joinClassNames(\n\t\t\"patternmode-distribution-display\",\n\t\tclassName,\n\t);\n\n\t// A selectable distribution is a group of buttons (fieldset → implicit\n\t// group role); a read-only one is an image. Static elements (not a ternary\n\t// role on one node) so a11y lint can verify aria support.\n\treturn interactive ? (\n\t\t<fieldset\n\t\t\t{...(props as HTMLAttributes<HTMLFieldSetElement>)}\n\t\t\taria-label={accessibleLabel}\n\t\t\tclassName={sharedClassName}\n\t\t\tdata-slot=\"distribution-display\"\n\t\t>\n\t\t\t{content}\n\t\t</fieldset>\n\t) : (\n\t\t<div\n\t\t\t{...props}\n\t\t\taria-label={accessibleLabel}\n\t\t\tclassName={sharedClassName}\n\t\t\tdata-slot=\"distribution-display\"\n\t\t\trole=\"img\"\n\t\t>\n\t\t\t{content}\n\t\t</div>\n\t);\n}\n\nexport function DistributionBar({\n\t\"aria-label\": ariaLabel,\n\tclassName,\n\tlegend = \"segments\",\n\tminValue = 4,\n\tonChange,\n\tsegments,\n\tstep = 1,\n\t...props\n}: DistributionBarProps) {\n\tconst trackRef = useRef<HTMLDivElement>(null);\n\tconst dragStartSegmentsRef = useRef<DistributionBarSegment[] | null>(null);\n\tconst total = getDistributionTotal(segments);\n\n\tfunction moveBoundary(\n\t\tboundaryIndex: number,\n\t\tdeltaValue: number,\n\t\tsourceSegments = segments,\n\t) {\n\t\tonChange?.(\n\t\t\tmoveDistributionBoundary(\n\t\t\t\tsourceSegments,\n\t\t\t\tboundaryIndex,\n\t\t\t\tdeltaValue,\n\t\t\t\tminValue,\n\t\t\t),\n\t\t);\n\t}\n\n\tfunction handleDragStart() {\n\t\tdragStartSegmentsRef.current = segments;\n\t}\n\n\tfunction handleDrag(boundaryIndex: number, info: PanInfo) {\n\t\tconst sourceSegments = dragStartSegmentsRef.current ?? segments;\n\t\tconst sourceTotal = getDistributionTotal(sourceSegments);\n\t\tconst trackWidth = trackRef.current?.getBoundingClientRect().width ?? 0;\n\t\tif (!(trackWidth > 0 && sourceTotal > 0)) {\n\t\t\treturn;\n\t\t}\n\n\t\tmoveBoundary(\n\t\t\tboundaryIndex,\n\t\t\t(info.offset.x / trackWidth) * sourceTotal,\n\t\t\tsourceSegments,\n\t\t);\n\t}\n\n\tfunction handleDragEnd(boundaryIndex: number, info: PanInfo) {\n\t\thandleDrag(boundaryIndex, info);\n\t\tdragStartSegmentsRef.current = null;\n\t}\n\n\tfunction handleKeyDown(\n\t\tevent: KeyboardEvent<HTMLButtonElement>,\n\t\tboundaryIndex: number,\n\t) {\n\t\tif (event.key === \"ArrowLeft\") {\n\t\t\tevent.preventDefault();\n\t\t\tmoveBoundary(boundaryIndex, -step);\n\t\t}\n\t\tif (event.key === \"ArrowRight\") {\n\t\t\tevent.preventDefault();\n\t\t\tmoveBoundary(boundaryIndex, step);\n\t\t}\n\t}\n\n\treturn (\n\t\t<fieldset\n\t\t\t{...props}\n\t\t\taria-label={ariaLabel}\n\t\t\tclassName={joinClassNames(\"patternmode-distribution-bar\", className)}\n\t\t\tdata-slot=\"distribution-bar\"\n\t\t>\n\t\t\t<div className=\"patternmode-distribution-bar__track\" ref={trackRef}>\n\t\t\t\t<DistributionSegments segments={segments} total={total} />\n\t\t\t\t{segments.slice(0, -1).map((segment, boundaryIndex) => {\n\t\t\t\t\tconst nextSegment = segments[boundaryIndex + 1];\n\t\t\t\t\tconst boundaryPercent = getDistributionBoundaryPercent(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tboundaryIndex,\n\t\t\t\t\t);\n\t\t\t\t\tconst label = `Adjust ${segment.label ?? segment.id} and ${\n\t\t\t\t\t\tnextSegment?.label ?? nextSegment?.id\n\t\t\t\t\t} distribution`;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<DistributionBarHandle\n\t\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\t\tboundaryPercent={boundaryPercent}\n\t\t\t\t\t\t\tkey={`${segment.id}-${nextSegment?.id ?? \"end\"}`}\n\t\t\t\t\t\t\tonDrag={(info) => handleDrag(boundaryIndex, info)}\n\t\t\t\t\t\t\tonDragEnd={(info) => handleDragEnd(boundaryIndex, info)}\n\t\t\t\t\t\t\tonDragStart={handleDragStart}\n\t\t\t\t\t\t\tonKeyDown={(event) => handleKeyDown(event, boundaryIndex)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t\t{legend === \"segments\" ? (\n\t\t\t\t<DistributionSegmentLegend segments={segments} total={total} />\n\t\t\t) : null}\n\t\t</fieldset>\n\t);\n}\n\ninterface DistributionSegmentsProps {\n\temptyValue?: number;\n\tonSegmentSelect?: (segment: DistributionBarSegment) => void;\n\tsegments: DistributionBarSegment[];\n\tselectedSegmentId?: string;\n\ttotal: number;\n}\n\nfunction DistributionSegments({\n\temptyValue = 0,\n\tonSegmentSelect,\n\tsegments,\n\tselectedSegmentId,\n\ttotal,\n}: DistributionSegmentsProps) {\n\treturn (\n\t\t<div className=\"patternmode-distribution-bar__segments\">\n\t\t\t{segments.map((segment) => {\n\t\t\t\tconst segmentStyle = {\n\t\t\t\t\t\"--patternmode-distribution-segment-color\": segment.color,\n\t\t\t\t\twidth:\n\t\t\t\t\t\ttotal > 0\n\t\t\t\t\t\t\t? `${(getRenderableDistributionValue(segment.value) / total) * 100}%`\n\t\t\t\t\t\t\t: \"0%\",\n\t\t\t\t} as CSSProperties;\n\t\t\t\tconst isSelected = selectedSegmentId === segment.id;\n\n\t\t\t\tif (onSegmentSelect) {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\taria-label={`${segment.label ?? segment.id} ${getDerivedDistributionPercentage(segment.value, total)}%`}\n\t\t\t\t\t\t\taria-pressed={isSelected}\n\t\t\t\t\t\t\tclassName=\"patternmode-distribution-bar__segment\"\n\t\t\t\t\t\t\tdata-selected={isSelected ? \"true\" : undefined}\n\t\t\t\t\t\t\tkey={segment.id}\n\t\t\t\t\t\t\tonClick={() => onSegmentSelect(segment)}\n\t\t\t\t\t\t\tstyle={segmentStyle}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\tclassName=\"patternmode-distribution-bar__segment\"\n\t\t\t\t\t\tdata-selected={isSelected ? \"true\" : undefined}\n\t\t\t\t\t\tkey={segment.id}\n\t\t\t\t\t\tstyle={segmentStyle}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\t})}\n\t\t\t{emptyValue > 0 ? (\n\t\t\t\t<div\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tclassName=\"patternmode-distribution-bar__segment patternmode-distribution-bar__segment--empty\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\twidth:\n\t\t\t\t\t\t\ttotal > 0\n\t\t\t\t\t\t\t\t? `${(getRenderableDistributionValue(emptyValue) / total) * 100}%`\n\t\t\t\t\t\t\t\t: \"0%\",\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n\ninterface DistributionSegmentLegendProps {\n\temptyLabel?: string;\n\temptyValue?: number;\n\tsegments: DistributionBarSegment[];\n\ttotal: number;\n}\n\nfunction DistributionSegmentLegend({\n\temptyLabel,\n\temptyValue = 0,\n\tsegments,\n\ttotal,\n}: DistributionSegmentLegendProps) {\n\treturn (\n\t\t<div className=\"patternmode-distribution-bar__legend\">\n\t\t\t{segments.map((segment) => (\n\t\t\t\t<span key={segment.id}>\n\t\t\t\t\t<span\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\tclassName=\"patternmode-distribution-bar__swatch\"\n\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"--patternmode-distribution-segment-color\": segment.color,\n\t\t\t\t\t\t\t} as CSSProperties\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t\t{segment.label ?? segment.id}{\" \"}\n\t\t\t\t\t{getDerivedDistributionPercentage(segment.value, total)}%\n\t\t\t\t</span>\n\t\t\t))}\n\t\t\t{emptyValue > 0 && emptyLabel ? (\n\t\t\t\t<span>\n\t\t\t\t\t<span\n\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\tclassName=\"patternmode-distribution-bar__swatch patternmode-distribution-bar__swatch--empty\"\n\t\t\t\t\t/>\n\t\t\t\t\t{emptyLabel} {getDerivedDistributionPercentage(emptyValue, total)}%\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n\ninterface DistributionSummaryLegendProps {\n\tassignedLabel: string;\n\temptyLabel: string;\n\temptyValue: number;\n\ttotal: number;\n}\n\nfunction DistributionSummaryLegend({\n\tassignedLabel,\n\temptyLabel,\n\temptyValue,\n\ttotal,\n}: DistributionSummaryLegendProps) {\n\tconst emptyPercentage = getDerivedDistributionPercentage(emptyValue, total);\n\n\treturn (\n\t\t<div className=\"patternmode-distribution-bar__legend\">\n\t\t\t<span>\n\t\t\t\t{Math.max(0, 100 - emptyPercentage)}% {assignedLabel}\n\t\t\t</span>\n\t\t\t{emptyValue > 0 ? (\n\t\t\t\t<span>\n\t\t\t\t\t{emptyPercentage}% {emptyLabel}\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n\nfunction getDistributionDisplayTotal(\n\tsegments: DistributionBarSegment[],\n\temptyValue: number,\n): number {\n\treturn (\n\t\tgetDistributionTotal(segments) + getRenderableDistributionValue(emptyValue)\n\t);\n}\n\nfunction getDistributionDisplayAccessibleLabel(\n\tsegments: DistributionBarSegment[],\n\temptyValue: number,\n\temptyLabel: string,\n\ttotal: number,\n): string {\n\tconst segmentLabels = segments.map(\n\t\t(segment) =>\n\t\t\t`${segment.label ?? segment.id} ${getDerivedDistributionPercentage(\n\t\t\t\tsegment.value,\n\t\t\t\ttotal,\n\t\t\t)}%`,\n\t);\n\tif (emptyValue > 0) {\n\t\tsegmentLabels.push(\n\t\t\t`${emptyLabel} ${getDerivedDistributionPercentage(emptyValue, total)}%`,\n\t\t);\n\t}\n\n\treturn segmentLabels.join(\", \");\n}\n\nfunction getDerivedDistributionPercentage(\n\tvalue: number,\n\ttotal: number,\n): number {\n\tif (!(total > 0 && Number.isFinite(value))) {\n\t\treturn 0;\n\t}\n\n\treturn Math.round((Math.max(0, value) / total) * 100);\n}\n\nfunction getRenderableDistributionValue(value: number): number {\n\treturn Number.isFinite(value) ? Math.max(0, value) : 0;\n}\n\ninterface DistributionBarHandleProps {\n\t\"aria-label\": string;\n\tboundaryPercent: number;\n\tonDrag: (info: PanInfo) => void;\n\tonDragEnd: (info: PanInfo) => void;\n\tonDragStart: () => void;\n\tonKeyDown: (event: KeyboardEvent<HTMLButtonElement>) => void;\n}\n\nfunction DistributionBarHandle({\n\t\"aria-label\": ariaLabel,\n\tboundaryPercent,\n\tonDrag,\n\tonDragEnd,\n\tonDragStart,\n\tonKeyDown,\n}: DistributionBarHandleProps) {\n\treturn (\n\t\t<motion.button\n\t\t\taria-label={ariaLabel}\n\t\t\tclassName=\"patternmode-distribution-bar__handle\"\n\t\t\tdrag=\"x\"\n\t\t\tdragElastic={0}\n\t\t\tdragMomentum={false}\n\t\t\tdragSnapToOrigin\n\t\t\tonDrag={(_event, info) => onDrag(info)}\n\t\t\tonDragEnd={(_event, info) => onDragEnd(info)}\n\t\t\tonDragStart={onDragStart}\n\t\t\tonKeyDown={onKeyDown}\n\t\t\tstyle={{ left: `calc(${boundaryPercent}% - 1.375rem)` }}\n\t\t\ttransformTemplate={() => \"none\"}\n\t\t\ttype=\"button\"\n\t\t/>\n\t);\n}\n","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\ttype ObjectFit,\n\tPATTERNMODE_SIZE_VALUES,\n\tPATTERNMODE_SIZES,\n} from \"@patternmode/system\";\nimport type { ComponentType, HTMLAttributes, SVGProps } from \"react\";\n\nexport const SWATCH_SIZES = [\n\t...PATTERNMODE_SIZES,\n\t\"4xl\",\n\t\"5xl\",\n\t\"6xl\",\n\t\"7xl\",\n] as const;\n\nexport const SWATCH_SIZE_VALUES = {\n\t...PATTERNMODE_SIZE_VALUES,\n\t\"4xl\": \"4.5rem\",\n\t\"5xl\": \"5rem\",\n\t\"6xl\": \"5.5rem\",\n\t\"7xl\": \"6rem\",\n} as const satisfies Record<SwatchSize, string>;\n\nexport const SWATCH_SHAPES = [\"circle\", \"pill\", \"square\", \"block\"] as const;\n\nexport type SwatchSize = (typeof SWATCH_SIZES)[number];\nexport type SwatchShape = (typeof SWATCH_SHAPES)[number];\nexport type SwatchColorStop = string | { color: string; ratio?: number };\ntype SwatchIcon = ComponentType<SVGProps<SVGSVGElement>>;\n\nexport function getSwatchSizeVariableStyle(\n\tsize: SwatchSize,\n\tvariableName = \"--patternmode-swatch-size\",\n): Record<string, string> {\n\treturn {\n\t\t[variableName]: SWATCH_SIZE_VALUES[size],\n\t};\n}\n\nexport interface SwatchProps extends HTMLAttributes<HTMLElement> {\n\tbackground?: string;\n\tcolor?: string;\n\tcolors?: SwatchColorStop[];\n\t/**\n\t * Render a precise, flat color block: no top-to-bottom scrim gradient and\n\t * no drop shadow. Use for data visualisation where the fill must read as\n\t * the exact color value.\n\t */\n\tflat?: boolean;\n\ticon?: SwatchIcon;\n\tisLight?: boolean;\n\tobjectFit?: ObjectFit;\n\tobjectPosition?: string;\n\tonRemove?: () => void;\n\traised?: boolean;\n\tremoveLabel?: string;\n\tselected?: boolean;\n\tshape?: SwatchShape;\n\tshowRing?: boolean;\n\tsize?: SwatchSize;\n\tunavailable?: boolean;\n}\n","import { getObjectSizingStyle, joinClassNames } from \"@patternmode/system\";\nimport type { CSSProperties, MouseEvent } from \"react\";\n\nimport { getSwatchColorsBackground, isLightColor } from \"./SwatchColors\";\nimport { getSwatchSizeVariableStyle, type SwatchProps } from \"./SwatchTypes\";\n\nexport function Swatch({\n\t\"aria-label\": ariaLabel,\n\tbackground,\n\tchildren,\n\tclassName,\n\tcolor,\n\tcolors,\n\tflat = false,\n\ticon: Icon,\n\tisLight,\n\tobjectFit,\n\tobjectPosition,\n\tonRemove,\n\traised = false,\n\tremoveLabel,\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\tconst resolvedRemoveLabel =\n\t\tremoveLabel ?? (ariaLabel ? `Remove ${ariaLabel}` : \"Remove\");\n\n\tconst rootStyle = {\n\t\t...getSwatchSizeVariableStyle(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\tconst swatchContent = (\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{flat ? null : (\n\t\t\t\t<span aria-hidden=\"true\" className=\"patternmode-swatch__scrim\" />\n\t\t\t)}\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</>\n\t);\n\n\tif (onRemove) {\n\t\treturn (\n\t\t\t<fieldset\n\t\t\t\t{...props}\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\tclassName={joinClassNames(\"patternmode-swatch\", className)}\n\t\t\t\tdata-flat={flat ? \"true\" : undefined}\n\t\t\t\tdata-raised={raised ? \"true\" : undefined}\n\t\t\t\tdata-selected={selected ? \"true\" : undefined}\n\t\t\t\tdata-shape={shape}\n\t\t\t\tdata-show-ring={showRing ? \"true\" : \"false\"}\n\t\t\t\tdata-size={size}\n\t\t\t\tdata-slot=\"swatch\"\n\t\t\t\tdata-tone={light ? \"light\" : \"dark\"}\n\t\t\t\tdata-unavailable={unavailable ? \"true\" : undefined}\n\t\t\t\tstyle={rootStyle}\n\t\t\t>\n\t\t\t\t{swatchContent}\n\t\t\t\t<button\n\t\t\t\t\taria-label={resolvedRemoveLabel}\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</fieldset>\n\t\t);\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-flat={flat ? \"true\" : undefined}\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{swatchContent}\n\t\t</span>\n\t);\n}\n"],"mappings":"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"}
package/dist/styles.css CHANGED
@@ -1 +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;min-inline-size:0;width:var(--patternmode-swatch-size);border:0;justify-content:center;align-items:center;margin:0;padding:0;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-shape=block]{--patternmode-swatch-radius:.25rem;aspect-ratio:auto;width:100%;height:100%;display:block}.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{color:var(--surface,#fff);cursor:pointer;opacity:0;background:0 0;border:0;border-radius:999px;justify-content:center;align-items:center;width:2.75rem;height:2.75rem;padding:0;transition:opacity .14s;display:inline-flex;position:absolute;top:-1.1rem;right:-1.1rem}.patternmode-swatch__remove:before{background:var(--ink,#1d1d1b);border-radius:inherit;content:"";width:1.25rem;height:1.25rem;transition:background .14s;position:absolute}.patternmode-swatch__remove:focus-visible{opacity:1}@media (hover:hover){.patternmode-swatch:hover .patternmode-swatch__remove{opacity:1}.patternmode-swatch__remove:hover:before{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;z-index:1;width:.8rem;height:.8rem}@media (prefers-reduced-motion:reduce){.patternmode-swatch,.patternmode-swatch__remove,.patternmode-swatch__remove:before{transition:none}}.patternmode-distribution-bar,.patternmode-distribution-display{min-inline-size:0;border:0;gap:10px;width:100%;margin:0;padding:0;display:grid}.patternmode-distribution-bar__track{height:var(--patternmode-distribution-height,40px);width:100%;position:relative}.patternmode-distribution-bar .patternmode-distribution-bar__track{touch-action:none}.patternmode-distribution-bar__segments{border:1px solid var(--border-soft,#1118271f);border-radius:var(--patternmode-distribution-radius,999px);width:100%;height:100%;display:flex;overflow:hidden}.patternmode-distribution-bar__segment{background:var(--patternmode-distribution-segment-color);border:0;min-width:0;height:100%;margin:0;padding:0;transition:width .48s cubic-bezier(.2,0,0,1)}button.patternmode-distribution-bar__segment{cursor:pointer}button.patternmode-distribution-bar__segment:focus-visible{outline:2px solid var(--accent,#315c4b);outline-offset:-2px;z-index:2}.patternmode-distribution-bar__segment[data-selected=true]{box-shadow:inset 0 0 0 2px var(--accent,#315c4b);z-index:2}@media (prefers-reduced-motion:reduce){.patternmode-distribution-bar__segment{transition:none}}.patternmode-distribution-bar__segment--empty{background-color:var(--surface-soft,#f7f5f0);background-image:repeating-linear-gradient(45deg, transparent, transparent 3px, var(--border-soft,#1118271f) 3px, var(--border-soft,#1118271f) 4px)}.patternmode-distribution-bar__segment+.patternmode-distribution-bar__segment{box-shadow:inset 1px 0 #fff9}.patternmode-distribution-bar__handle{cursor:ew-resize;z-index:1;background:0 0;border:0;border-radius:999px;justify-content:center;align-items:center;width:2.75rem;height:2.75rem;padding:0;display:inline-flex;position:absolute;top:calc(50% - 1.375rem)}.patternmode-distribution-bar__handle:before{background:var(--surface,#fff);content:"";border-radius:999px;width:.62rem;height:.62rem;transition:box-shadow .12s,transform .12s;box-shadow:0 1px 4px #1118272e,0 0 0 1px #11182733}.patternmode-distribution-bar__handle:focus-visible{outline:2px solid var(--accent,#315c4b);outline-offset:-4px}@media (hover:hover){.patternmode-distribution-bar__handle:hover:before{transform:scale(1.15);box-shadow:0 5px 14px #1118274d,0 0 0 1px #11182738}}.patternmode-distribution-bar__legend{flex-wrap:wrap;gap:8px 14px;display:flex}.patternmode-distribution-bar__legend>span{color:var(--muted,#595853);align-items:center;gap:6px;font-size:.68rem;font-weight:500;display:inline-flex}.patternmode-distribution-bar__swatch{background:var(--patternmode-distribution-segment-color);border-radius:999px;width:.55rem;height:.55rem;display:inline-flex}.patternmode-distribution-bar__swatch--empty{background-color:var(--surface-soft,#f7f5f0);background-image:repeating-linear-gradient(45deg, transparent, transparent 2px, var(--border-soft,#1118271f) 2px, var(--border-soft,#1118271f) 3px);box-shadow:inset 0 0 0 1px var(--border-soft,#1118271f)}@media (prefers-reduced-motion:reduce){.patternmode-distribution-bar__handle:before{transition:none}}}
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;min-inline-size:0;width:var(--patternmode-swatch-size);border:0;justify-content:center;align-items:center;margin:0;padding:0;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-shape=block]{--patternmode-swatch-radius:.25rem;aspect-ratio:auto;width:100%;height:100%;display:block}.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[data-flat=true]{box-shadow:none}.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{color:var(--surface,#fff);cursor:pointer;opacity:0;background:0 0;border:0;border-radius:999px;justify-content:center;align-items:center;width:2.75rem;height:2.75rem;padding:0;transition:opacity .14s;display:inline-flex;position:absolute;top:-1.1rem;right:-1.1rem}.patternmode-swatch__remove:before{background:var(--ink,#1d1d1b);border-radius:inherit;content:"";width:1.25rem;height:1.25rem;transition:background .14s;position:absolute}.patternmode-swatch__remove:focus-visible{opacity:1}@media (hover:hover){.patternmode-swatch:hover .patternmode-swatch__remove{opacity:1}.patternmode-swatch__remove:hover:before{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;z-index:1;width:.8rem;height:.8rem}@media (prefers-reduced-motion:reduce){.patternmode-swatch,.patternmode-swatch__remove,.patternmode-swatch__remove:before{transition:none}}.patternmode-distribution-bar,.patternmode-distribution-display{min-inline-size:0;border:0;gap:10px;width:100%;margin:0;padding:0;display:grid}.patternmode-distribution-bar__track{height:var(--patternmode-distribution-height,40px);width:100%;position:relative}.patternmode-distribution-bar .patternmode-distribution-bar__track{touch-action:none}.patternmode-distribution-bar__segments{border:1px solid var(--border-soft,#1118271f);border-radius:var(--patternmode-distribution-radius,999px);width:100%;height:100%;display:flex;overflow:hidden}.patternmode-distribution-bar__segment{background:var(--patternmode-distribution-segment-color);border:0;min-width:0;height:100%;margin:0;padding:0;transition:width .48s cubic-bezier(.2,0,0,1)}button.patternmode-distribution-bar__segment{cursor:pointer}button.patternmode-distribution-bar__segment:focus-visible{outline:2px solid var(--accent,#315c4b);outline-offset:-2px;z-index:2}.patternmode-distribution-bar__segment[data-selected=true]{box-shadow:inset 0 0 0 2px var(--accent,#315c4b);z-index:2}@media (prefers-reduced-motion:reduce){.patternmode-distribution-bar__segment{transition:none}}.patternmode-distribution-bar__segment--empty{background-color:var(--surface-soft,#f7f5f0);background-image:repeating-linear-gradient(45deg, transparent, transparent 3px, var(--border-soft,#1118271f) 3px, var(--border-soft,#1118271f) 4px)}.patternmode-distribution-bar__segment+.patternmode-distribution-bar__segment{box-shadow:inset 1px 0 #fff9}.patternmode-distribution-bar__handle{cursor:ew-resize;z-index:1;background:0 0;border:0;border-radius:999px;justify-content:center;align-items:center;width:2.75rem;height:2.75rem;padding:0;display:inline-flex;position:absolute;top:calc(50% - 1.375rem)}.patternmode-distribution-bar__handle:before{background:var(--surface,#fff);content:"";border-radius:999px;width:.62rem;height:.62rem;transition:box-shadow .12s,transform .12s;box-shadow:0 1px 4px #1118272e,0 0 0 1px #11182733}.patternmode-distribution-bar__handle:focus-visible{outline:2px solid var(--accent,#315c4b);outline-offset:-4px}@media (hover:hover){.patternmode-distribution-bar__handle:hover:before{transform:scale(1.15);box-shadow:0 5px 14px #1118274d,0 0 0 1px #11182738}}.patternmode-distribution-bar__legend{flex-wrap:wrap;gap:8px 14px;display:flex}.patternmode-distribution-bar__legend>span{color:var(--muted,#595853);align-items:center;gap:6px;font-size:.68rem;font-weight:500;display:inline-flex}.patternmode-distribution-bar__swatch{background:var(--patternmode-distribution-segment-color);border-radius:999px;width:.55rem;height:.55rem;display:inline-flex}.patternmode-distribution-bar__swatch--empty{background-color:var(--surface-soft,#f7f5f0);background-image:repeating-linear-gradient(45deg, transparent, transparent 2px, var(--border-soft,#1118271f) 2px, var(--border-soft,#1118271f) 3px);box-shadow:inset 0 0 0 1px var(--border-soft,#1118271f)}@media (prefers-reduced-motion:reduce){.patternmode-distribution-bar__handle:before{transition:none}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternmode/swatch",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
4
  "private": false,
5
5
  "description": "Color, gradient, image, and palette swatch primitives for Patternmode interfaces.",
6
6
  "type": "module",