@xsolla/xui-gradient-picker 0.204.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.
- package/README.md +280 -0
- package/native/index.d.mts +243 -0
- package/native/index.d.ts +243 -0
- package/native/index.js +1063 -0
- package/native/index.js.map +1 -0
- package/native/index.mjs +1033 -0
- package/native/index.mjs.map +1 -0
- package/package.json +62 -0
- package/web/index.d.mts +243 -0
- package/web/index.d.ts +243 -0
- package/web/index.js +1096 -0
- package/web/index.js.map +1 -0
- package/web/index.mjs +1049 -0
- package/web/index.mjs.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/GradientPicker.tsx","../../../../foundation/primitives-web/src/Box.tsx","../../../../foundation/primitives-web/src/filterDOMProps.ts","../../../../../node_modules/@emotion/memoize/dist/memoize.esm.js","../../../../../node_modules/@emotion/is-prop-valid/dist/is-prop-valid.esm.js","../../../../foundation/primitives-web/src/Text.tsx","../../../../foundation/primitives-web/src/textTruncation.ts","../../../../foundation/primitives-web/src/index.tsx","../../src/GradientStopMarker.tsx","../../src/utils.ts","../../src/icons.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport { Input } from \"@xsolla/xui-input\";\nimport { InputColor } from \"@xsolla/xui-input-color\";\nimport { Select } from \"@xsolla/xui-select\";\nimport { IconButton } from \"@xsolla/xui-button\";\nimport { ColorPicker } from \"@xsolla/xui-color-picker\";\nimport { GradientStopMarker } from \"./GradientStopMarker\";\nimport { AngleGlyph, MinusGlyph, PercentGlyph, PlusGlyph } from \"./icons\";\nimport {\n DEFAULT_GRADIENT,\n addStopAt,\n clampOpacity,\n clampPosition,\n normalizeHex,\n removeStop,\n sortStops,\n supportsAngle,\n toCssGradient,\n toPreviewCssGradient,\n updateStop,\n} from \"./utils\";\nimport type {\n GradientPickerProps,\n GradientStop,\n GradientType,\n GradientValue,\n} from \"./types\";\n\nconst DEFAULT_TYPE_LABELS: Record<GradientType, string> = {\n linear: \"Linear gradient\",\n radial: \"Radial gradient\",\n angular: \"Angular gradient\",\n};\n\nconst ALL_TYPES: GradientType[] = [\"linear\", \"radial\", \"angular\"];\n\n/**\n * Vertical distance (px) a stop must be dragged away from the track before it\n * is dropped, per the Figma behaviour note: \"a stop can be removed by dragging\n * it off the track (up or down beyond a threshold)\".\n */\nconst DRAG_OFF_THRESHOLD = 32;\n\nconst TRACK_HEIGHT = 16;\n\n/**\n * Horizontal padding around the track so a marker parked at 0% / 100% — which\n * is centred on the track edge — is not clipped by the panel padding.\n */\nconst MARKER_INSET = 9;\n\n/**\n * Combines a stop's hex + opacity into the `#RRGGBBAA` string that ColorPicker\n * and InputColor expect when the alpha channel is enabled.\n */\nconst toHexa = (color: string, opacity: number): string => {\n const alpha = Math.round((clampOpacity(opacity) / 100) * 255)\n .toString(16)\n .padStart(2, \"0\")\n .toUpperCase();\n return `${normalizeHex(color)}${alpha}`;\n};\n\n/**\n * Splits a `#RRGGBB` / `#RRGGBBAA` string back into a stop's hex + opacity\n * percent. The alpha pair is omitted by ColorPicker when fully opaque.\n */\nconst fromHexa = (value: string): { color: string; opacity: number } => {\n const raw = String(value ?? \"\")\n .trim()\n .replace(/^#/, \"\");\n if (/^[0-9a-fA-F]{8}$/.test(raw)) {\n return {\n color: normalizeHex(raw.slice(0, 6)),\n opacity: clampOpacity((parseInt(raw.slice(6, 8), 16) / 255) * 100),\n };\n }\n return { color: normalizeHex(raw), opacity: 100 };\n};\n\n/**\n * A compound control for defining a CSS gradient.\n *\n * Combines a live preview track carrying draggable stop markers with a per-stop\n * row editor (position, colour, opacity) and an integrated `ColorPicker` for\n * the active stop. Supports linear, radial and angular (CSS `conic`) gradients\n * and 1–5 colour stops.\n *\n * Every interaction updates the preview immediately — there is no confirm step —\n * and the gradient is emitted both as structured data and as a ready-to-apply\n * CSS string.\n *\n * @example\n * ```tsx\n * const [gradient, setGradient] = useState<GradientValue>();\n *\n * <GradientPicker\n * value={gradient}\n * onChange={({ value, css }) => {\n * setGradient(value);\n * setBackground(css); // e.g. \"linear-gradient(0deg, #D9D9D9 0%, #22A8C3 100%)\"\n * }}\n * />\n * ```\n */\nexport const GradientPicker: React.FC<GradientPickerProps> = ({\n value: propValue,\n defaultValue,\n onChange,\n gradientTypes = ALL_TYPES,\n typeLabels,\n minStops = 1,\n maxStops = 5,\n disabled = false,\n typeAriaLabel = \"Gradient type\",\n angleAriaLabel = \"Gradient angle\",\n stopsLabel = \"Stops\",\n testID,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n // Token bags are widened the same way Select does — the shipped theme carries\n // more leaves than the published type.\n const contentColors = theme.colors.content as any;\n\n /**\n * Every themeable child has to receive the override explicitly. Without this\n * the panel resolves `themeMode` but Select / Input / IconButton fall back to\n * the provider theme, so a light-mode picker renders white-on-white text and\n * invisible +/− glyphs.\n */\n const themeProps = { themeMode, themeProductContext };\n\n const isControlled = propValue !== undefined;\n const [innerValue, setInnerValue] = useState<GradientValue>(\n () => propValue ?? defaultValue ?? DEFAULT_GRADIENT\n );\n const value = isControlled ? (propValue as GradientValue) : innerValue;\n\n const [activeStopId, setActiveStopId] = useState<string | null>(null);\n const [draggingStopId, setDraggingStopId] = useState<string | null>(null);\n\n const trackRef = useRef<any>(null);\n const rootRef = useRef<any>(null);\n\n const stops = sortStops(value.stops);\n const activeStop = stops.find((stop) => stop.id === activeStopId) ?? null;\n const canAdd = !disabled && stops.length < maxStops;\n const canRemove = !disabled && stops.length > minStops;\n\n const emit = useCallback(\n (next: GradientValue) => {\n if (!isControlled) setInnerValue(next);\n onChange?.({ value: next, css: toCssGradient(next) });\n },\n [isControlled, onChange]\n );\n\n const patchStops = useCallback(\n (nextStops: GradientStop[]) => {\n if (nextStops === value.stops) return;\n emit({ ...value, stops: nextStops });\n },\n [emit, value]\n );\n\n /**\n * Returns focus to a stop marker — required when the ColorPicker closes\n * (\"focus must return to the stop marker\").\n */\n const focusMarker = useCallback((stopId: string) => {\n if (!isWeb) return;\n const node = rootRef.current?.querySelector?.(\n `[data-testid=\"gradient-stop-${stopId}\"]`\n ) as HTMLElement | null;\n node?.focus?.();\n }, []);\n\n const closeColorPicker = useCallback(() => {\n const previous = activeStopId;\n setActiveStopId(null);\n if (previous) focusMarker(previous);\n }, [activeStopId, focusMarker]);\n\n // Escape closes the ColorPicker and deactivates the stop.\n useEffect(() => {\n if (!isWeb || !activeStopId) return undefined;\n const onKey = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") closeColorPicker();\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [activeStopId, closeColorPicker]);\n\n const positionFromClientX = useCallback((clientX: number): number => {\n const rect = trackRef.current?.getBoundingClientRect?.();\n if (!rect || !rect.width) return 0;\n return clampPosition(((clientX - rect.left) / rect.width) * 100);\n }, []);\n\n /**\n * Adds a stop and activates it, so the ColorPicker opens on the new stop.\n * No-ops silently once `maxStops` is reached.\n */\n const addStop = (position: number) => {\n const before = value.stops;\n const after = addStopAt(before, position, maxStops);\n if (after === before) return;\n patchStops(after);\n const added = after.find(\n (stop) => !before.some((existing) => existing.id === stop.id)\n );\n if (added) setActiveStopId(added.id);\n };\n\n const handleTrackPress = (event: React.MouseEvent) => {\n if (!canAdd) return;\n addStop(positionFromClientX(event.clientX));\n };\n\n /**\n * Keyboard-accessible alternative to clicking the track: drops the new stop\n * in the widest gap so it never lands exactly on top of an existing one.\n */\n const handleAddStopPress = () => {\n if (!canAdd) return;\n const sorted = sortStops(value.stops);\n let position = 50;\n let widest = -1;\n for (let index = 0; index < sorted.length - 1; index += 1) {\n const gap = sorted[index + 1].position - sorted[index].position;\n if (gap > widest) {\n widest = gap;\n position = sorted[index].position + gap / 2;\n }\n }\n addStop(position);\n };\n\n const handleRemoveStop = (stopId: string) => {\n const after = removeStop(value.stops, stopId, minStops);\n if (after === value.stops) return;\n if (activeStopId === stopId) setActiveStopId(null);\n patchStops(after);\n };\n\n const handleDragStart = (stop: GradientStop) => (event: React.MouseEvent) => {\n if (disabled) return;\n event.preventDefault();\n event.stopPropagation();\n\n const startY = event.clientY;\n setDraggingStopId(stop.id);\n setActiveStopId(stop.id);\n\n let latest = value.stops;\n let removed = false;\n\n const onMouseMove = (moveEvent: MouseEvent) => {\n if (removed) return;\n\n if (Math.abs(moveEvent.clientY - startY) > DRAG_OFF_THRESHOLD) {\n const after = removeStop(latest, stop.id, minStops);\n if (after !== latest) {\n latest = after;\n removed = true;\n patchStops(after);\n }\n return;\n }\n\n latest = updateStop(latest, stop.id, {\n position: positionFromClientX(moveEvent.clientX),\n });\n patchStops(latest);\n };\n\n const onMouseUp = () => {\n setDraggingStopId(null);\n if (removed) setActiveStopId(null);\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n };\n\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n };\n\n const handleMarkerKeyDown =\n (stop: GradientStop) => (event: React.KeyboardEvent) => {\n if (disabled) return;\n\n const step = event.shiftKey ? 10 : 1;\n let handled = true;\n\n switch (event.key) {\n case \"ArrowRight\":\n case \"ArrowUp\":\n patchStops(\n updateStop(value.stops, stop.id, { position: stop.position + step })\n );\n break;\n case \"ArrowLeft\":\n case \"ArrowDown\":\n patchStops(\n updateStop(value.stops, stop.id, { position: stop.position - step })\n );\n break;\n case \"Home\":\n patchStops(updateStop(value.stops, stop.id, { position: 0 }));\n break;\n case \"End\":\n patchStops(updateStop(value.stops, stop.id, { position: 100 }));\n break;\n case \"Enter\":\n case \" \":\n setActiveStopId((current) => (current === stop.id ? null : stop.id));\n break;\n case \"Delete\":\n case \"Backspace\":\n handleRemoveStop(stop.id);\n break;\n default:\n handled = false;\n }\n\n if (handled) event.preventDefault();\n };\n\n const typeOptions = gradientTypes.map((type) => ({\n label: typeLabels?.[type] ?? DEFAULT_TYPE_LABELS[type],\n value: type,\n }));\n\n const showAngle = supportsAngle(value.type);\n\n return (\n <Box\n ref={rootRef}\n testID={testID}\n data-testid={testID}\n backgroundColor={theme.colors.layer.float}\n borderRadius={theme.shape.contextMenu.lg.borderRadius}\n padding={16}\n gap={12}\n width={344}\n style={{ boxShadow: \"0px 4px 16px 0px rgba(7, 7, 8, 0.1)\" }}\n >\n {/* Header — gradient type + (linear / angular only) rotation.\n The group wrapper carries the accessible name because SelectProps has\n no `aria-label` today; see the \"Known gaps\" note in the API doc. */}\n <Box flexDirection=\"row\" gap={8} alignItems=\"center\">\n <Box flex={1} role=\"group\" aria-label={typeAriaLabel}>\n <Select\n {...themeProps}\n size=\"sm\"\n options={typeOptions}\n value={value.type}\n disabled={disabled}\n onChange={(next: string) =>\n emit({ ...value, type: next as GradientType })\n }\n />\n </Box>\n\n {showAngle && (\n <Box width={88}>\n <Input\n {...themeProps}\n size=\"sm\"\n inputMode=\"numeric\"\n disabled={disabled}\n aria-label={angleAriaLabel}\n iconLeft={<AngleGlyph />}\n value={`${Math.round(value.angle)}`}\n onChange={(event: React.ChangeEvent<HTMLInputElement>) => {\n const parsed = parseInt(event.target.value, 10);\n emit({\n ...value,\n angle: Number.isNaN(parsed)\n ? 0\n : ((parsed % 360) + 360) % 360,\n });\n }}\n />\n </Box>\n )}\n </Box>\n\n {/* Preview track.\n The gradient fill is decorative and carries `aria-hidden` — the\n numeric position fields and each marker's `aria-valuetext` carry the\n same information for users who cannot perceive the colour ramp.\n The markers must be SIBLINGS of that fill, never children: anything\n inside an `aria-hidden` subtree is pruned from the accessibility\n tree, which would hide every `role=\"slider\"` handle from assistive\n technology. The bare positioning box below exists to give the markers\n a percentage origin that matches the fill exactly. */}\n <Box\n height={TRACK_HEIGHT}\n justifyContent=\"center\"\n paddingHorizontal={MARKER_INSET}\n >\n <Box\n ref={trackRef}\n width=\"100%\"\n height={TRACK_HEIGHT}\n position=\"relative\"\n cursor={canAdd ? \"copy\" : \"default\"}\n onMouseDown={isWeb && canAdd ? handleTrackPress : undefined}\n >\n <Box\n testID=\"gradient-track\"\n data-testid=\"gradient-track\"\n aria-hidden={true}\n position=\"absolute\"\n width=\"100%\"\n height={TRACK_HEIGHT}\n borderRadius={999}\n style={{\n top: 0,\n left: 0,\n backgroundImage: toPreviewCssGradient(value),\n }}\n />\n {stops.map((stop, index) => (\n <GradientStopMarker\n key={stop.id}\n stop={stop}\n index={index + 1}\n disabled={disabled}\n active={activeStopId === stop.id || draggingStopId === stop.id}\n onDragStart={handleDragStart(stop)}\n onKeyDown={handleMarkerKeyDown(stop)}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n ))}\n </Box>\n </Box>\n\n {/* Stop list header */}\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n >\n <Text color={contentColors.primary} fontSize={14}>\n {stopsLabel}\n </Text>\n <IconButton\n {...themeProps}\n size=\"sm\"\n variant=\"tertiary\"\n tone=\"mono\"\n disabled={!canAdd}\n onPress={handleAddStopPress}\n icon={<PlusGlyph />}\n aria-label=\"Add stop\"\n />\n </Box>\n\n {/* Stop rows */}\n <Box gap={8}>\n {stops.map((stop, index) => (\n <Box\n key={stop.id}\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={8}\n testID={`gradient-stop-row-${stop.id}`}\n data-testid={`gradient-stop-row-${stop.id}`}\n >\n <Box width={72}>\n <Input\n {...themeProps}\n size=\"sm\"\n inputMode=\"numeric\"\n disabled={disabled}\n aria-label={`Stop ${index + 1} position percent`}\n iconRight={<PercentGlyph />}\n value={`${stop.position}`}\n onChange={(event: React.ChangeEvent<HTMLInputElement>) => {\n const parsed = parseInt(event.target.value, 10);\n if (Number.isNaN(parsed)) return;\n patchStops(\n updateStop(value.stops, stop.id, { position: parsed })\n );\n }}\n />\n </Box>\n\n <Box flex={1}>\n <InputColor\n size=\"sm\"\n type=\"color-hex\"\n transparency\n aria-label={`Stop ${index + 1} colour`}\n testID={`gradient-stop-color-${stop.id}`}\n value={toHexa(stop.color, stop.opacity)}\n onChange={(next: string) => {\n const { color, opacity } = fromHexa(next);\n patchStops(\n updateStop(value.stops, stop.id, { color, opacity })\n );\n }}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n </Box>\n\n <IconButton\n {...themeProps}\n size=\"sm\"\n variant=\"tertiary\"\n tone=\"mono\"\n disabled={!canRemove}\n onPress={() => handleRemoveStop(stop.id)}\n icon={<MinusGlyph />}\n aria-label={`Remove stop ${index + 1}`}\n />\n </Box>\n ))}\n </Box>\n\n {/* Active-stop editor. Rendered inline below the stop list; a floating\n popover with viewport flipping is a follow-up (see the API doc). */}\n {activeStop && !disabled && (\n <ColorPicker\n alpha\n colorFormat=\"hex\"\n value={toHexa(activeStop.color, activeStop.opacity)}\n onChange={({\n valueInInitialFormat,\n }: {\n valueInInitialFormat: string;\n }) => {\n const { color, opacity } = fromHexa(valueInInitialFormat);\n patchStops(\n updateStop(value.stops, activeStop.id, { color, opacity })\n );\n }}\n themeMode={themeMode}\n themeProductContext={themeProductContext}\n />\n )}\n </Box>\n );\n};\n\nGradientPicker.displayName = \"GradientPicker\";\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport type { BoxProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\n\nconst FilteredDiv = createFilteredElement(\"div\");\n\nconst StyledBox = styled(FilteredDiv)<BoxProps>`\n display: flex;\n box-sizing: border-box;\n background-color: ${(props) => props.backgroundColor || \"transparent\"};\n border-color: ${(props) => props.borderColor || \"transparent\"};\n border-width: ${(props) =>\n typeof props.borderWidth === \"number\"\n ? `${props.borderWidth}px`\n : props.borderWidth || 0};\n\n ${(props) =>\n props.borderBottomWidth !== undefined &&\n `\n border-bottom-width: ${typeof props.borderBottomWidth === \"number\" ? `${props.borderBottomWidth}px` : props.borderBottomWidth};\n border-bottom-color: ${props.borderBottomColor || props.borderColor || \"transparent\"};\n border-bottom-style: solid;\n `}\n ${(props) =>\n props.borderTopWidth !== undefined &&\n `\n border-top-width: ${typeof props.borderTopWidth === \"number\" ? `${props.borderTopWidth}px` : props.borderTopWidth};\n border-top-color: ${props.borderTopColor || props.borderColor || \"transparent\"};\n border-top-style: solid;\n `}\n ${(props) =>\n props.borderLeftWidth !== undefined &&\n `\n border-left-width: ${typeof props.borderLeftWidth === \"number\" ? `${props.borderLeftWidth}px` : props.borderLeftWidth};\n border-left-color: ${props.borderLeftColor || props.borderColor || \"transparent\"};\n border-left-style: solid;\n `}\n ${(props) =>\n props.borderRightWidth !== undefined &&\n `\n border-right-width: ${typeof props.borderRightWidth === \"number\" ? `${props.borderRightWidth}px` : props.borderRightWidth};\n border-right-color: ${props.borderRightColor || props.borderColor || \"transparent\"};\n border-right-style: solid;\n `}\n\n border-style: ${(props) =>\n props.borderStyle ||\n (props.borderWidth ||\n props.borderBottomWidth ||\n props.borderTopWidth ||\n props.borderLeftWidth ||\n props.borderRightWidth\n ? \"solid\"\n : \"none\")};\n border-radius: ${(props) =>\n typeof props.borderRadius === \"number\"\n ? `${props.borderRadius}px`\n : props.borderRadius || 0};\n height: ${(props) =>\n typeof props.height === \"number\"\n ? `${props.height}px`\n : props.height || \"auto\"};\n width: ${(props) =>\n typeof props.width === \"number\"\n ? `${props.width}px`\n : props.width || \"auto\"};\n min-width: ${(props) =>\n typeof props.minWidth === \"number\"\n ? `${props.minWidth}px`\n : props.minWidth || \"auto\"};\n min-height: ${(props) =>\n typeof props.minHeight === \"number\"\n ? `${props.minHeight}px`\n : props.minHeight || \"auto\"};\n max-width: ${(props) =>\n typeof props.maxWidth === \"number\"\n ? `${props.maxWidth}px`\n : props.maxWidth || \"none\"};\n max-height: ${(props) =>\n typeof props.maxHeight === \"number\"\n ? `${props.maxHeight}px`\n : props.maxHeight || \"none\"};\n\n padding: ${(props) =>\n typeof props.padding === \"number\"\n ? `${props.padding}px`\n : props.padding || 0};\n ${(props) =>\n props.paddingHorizontal &&\n `\n padding-left: ${typeof props.paddingHorizontal === \"number\" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};\n padding-right: ${typeof props.paddingHorizontal === \"number\" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};\n `}\n ${(props) =>\n props.paddingVertical &&\n `\n padding-top: ${typeof props.paddingVertical === \"number\" ? `${props.paddingVertical}px` : props.paddingVertical};\n padding-bottom: ${typeof props.paddingVertical === \"number\" ? `${props.paddingVertical}px` : props.paddingVertical};\n `}\n ${(props) =>\n props.paddingTop !== undefined &&\n `padding-top: ${typeof props.paddingTop === \"number\" ? `${props.paddingTop}px` : props.paddingTop};`}\n ${(props) =>\n props.paddingBottom !== undefined &&\n `padding-bottom: ${typeof props.paddingBottom === \"number\" ? `${props.paddingBottom}px` : props.paddingBottom};`}\n ${(props) =>\n props.paddingLeft !== undefined &&\n `padding-left: ${typeof props.paddingLeft === \"number\" ? `${props.paddingLeft}px` : props.paddingLeft};`}\n ${(props) =>\n props.paddingRight !== undefined &&\n `padding-right: ${typeof props.paddingRight === \"number\" ? `${props.paddingRight}px` : props.paddingRight};`}\n\n margin: ${(props) =>\n typeof props.margin === \"number\" ? `${props.margin}px` : props.margin || 0};\n ${(props) =>\n props.marginTop !== undefined &&\n `margin-top: ${typeof props.marginTop === \"number\" ? `${props.marginTop}px` : props.marginTop};`}\n ${(props) =>\n props.marginBottom !== undefined &&\n `margin-bottom: ${typeof props.marginBottom === \"number\" ? `${props.marginBottom}px` : props.marginBottom};`}\n ${(props) =>\n props.marginLeft !== undefined &&\n `margin-left: ${typeof props.marginLeft === \"number\" ? `${props.marginLeft}px` : props.marginLeft};`}\n ${(props) =>\n props.marginRight !== undefined &&\n `margin-right: ${typeof props.marginRight === \"number\" ? `${props.marginRight}px` : props.marginRight};`}\n\n flex-direction: ${(props) => props.flexDirection || \"column\"};\n flex-wrap: ${(props) => props.flexWrap || \"nowrap\"};\n align-items: ${(props) => props.alignItems || \"stretch\"};\n justify-content: ${(props) => props.justifyContent || \"flex-start\"};\n cursor: ${(props) =>\n props.cursor\n ? props.cursor\n : props.onClick || props.onPress\n ? \"pointer\"\n : \"inherit\"};\n position: ${(props) => props.position || \"static\"};\n top: ${(props) =>\n typeof props.top === \"number\" ? `${props.top}px` : props.top};\n bottom: ${(props) =>\n typeof props.bottom === \"number\" ? `${props.bottom}px` : props.bottom};\n left: ${(props) =>\n typeof props.left === \"number\" ? `${props.left}px` : props.left};\n right: ${(props) =>\n typeof props.right === \"number\" ? `${props.right}px` : props.right};\n flex: ${(props) => props.flex};\n flex-shrink: ${(props) => props.flexShrink ?? 1};\n gap: ${(props) =>\n typeof props.gap === \"number\" ? `${props.gap}px` : props.gap || 0};\n align-self: ${(props) => props.alignSelf || \"auto\"};\n /* Only emit overflow-x/y when explicitly set. Defaulting them to\n visible after overflow would override the shorthand and break\n clipping (e.g. OtherCard bottom-right promo image). */\n overflow: ${(props) => props.overflow || \"visible\"};\n ${(props) =>\n props.overflowX != null ? `overflow-x: ${props.overflowX};` : \"\"}\n ${(props) =>\n props.overflowY != null ? `overflow-y: ${props.overflowY};` : \"\"}\n z-index: ${(props) => props.zIndex};\n opacity: ${(props) =>\n props.opacity != null ? props.opacity : props.disabled ? 0.5 : 1};\n pointer-events: ${(props) => (props.disabled ? \"none\" : \"auto\")};\n\n &:hover {\n ${(props) =>\n props.hoverStyle?.backgroundColor &&\n `background-color: ${props.hoverStyle.backgroundColor};`}\n ${(props) =>\n props.hoverStyle?.borderColor &&\n `border-color: ${props.hoverStyle.borderColor};`}\n }\n\n &:active {\n ${(props) =>\n props.pressStyle?.backgroundColor &&\n `background-color: ${props.pressStyle.backgroundColor};`}\n }\n`;\n\nexport const Box = React.forwardRef<\n HTMLDivElement | HTMLButtonElement,\n BoxProps\n>(\n (\n {\n children,\n onPress,\n onKeyDown,\n onKeyUp,\n role,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-current\": ariaCurrent,\n \"aria-disabled\": ariaDisabled,\n \"aria-live\": ariaLive,\n \"aria-busy\": ariaBusy,\n \"aria-describedby\": ariaDescribedBy,\n \"aria-expanded\": ariaExpanded,\n \"aria-haspopup\": ariaHasPopup,\n \"aria-pressed\": ariaPressed,\n \"aria-controls\": ariaControls,\n tabIndex,\n as,\n src,\n alt,\n onError,\n onLoad,\n type,\n disabled,\n id,\n testID,\n \"data-testid\": dataTestId,\n ...props\n },\n ref\n ) => {\n // Handle as=\"img\" for rendering images with proper border-radius\n if (as === \"img\" && src) {\n return (\n <img\n src={src}\n alt={alt || \"\"}\n onError={onError}\n onLoad={onLoad}\n data-testid={dataTestId || testID}\n style={{\n display: \"block\",\n objectFit: \"cover\",\n width:\n typeof props.width === \"number\"\n ? `${props.width}px`\n : props.width,\n height:\n typeof props.height === \"number\"\n ? `${props.height}px`\n : props.height,\n borderRadius:\n typeof props.borderRadius === \"number\"\n ? `${props.borderRadius}px`\n : props.borderRadius,\n position: props.position,\n top: typeof props.top === \"number\" ? `${props.top}px` : props.top,\n left:\n typeof props.left === \"number\" ? `${props.left}px` : props.left,\n right:\n typeof props.right === \"number\"\n ? `${props.right}px`\n : props.right,\n bottom:\n typeof props.bottom === \"number\"\n ? `${props.bottom}px`\n : props.bottom,\n ...props.style,\n }}\n />\n );\n }\n\n return (\n <StyledBox\n ref={ref}\n elementType={as}\n id={id}\n type={as === \"button\" ? type || \"button\" : undefined}\n disabled={as === \"button\" ? disabled : undefined}\n onClick={onPress}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n role={role}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-current={ariaCurrent}\n aria-disabled={ariaDisabled}\n aria-busy={ariaBusy}\n aria-describedby={ariaDescribedBy}\n aria-expanded={ariaExpanded}\n aria-haspopup={ariaHasPopup}\n aria-pressed={ariaPressed}\n aria-controls={ariaControls}\n aria-live={ariaLive}\n tabIndex={tabIndex !== undefined ? tabIndex : undefined}\n data-testid={dataTestId || testID}\n {...props}\n >\n {children}\n </StyledBox>\n );\n }\n);\n\nBox.displayName = \"Box\";\n","import React from \"react\";\nimport isPropValid from \"@emotion/is-prop-valid\";\n\n// Props that @emotion/is-prop-valid incorrectly treats as valid HTML.\n// These are React Native or component-specific props that match\n// valid HTML patterns (on* event handlers, SVG attributes).\nexport const ADDITIONAL_BLOCKED_PROPS = new Set([\n // RN-only event handlers (pass isPropValid's on* pattern)\n \"onPress\",\n \"onChangeText\",\n \"onLayout\",\n \"onMoveShouldSetResponder\",\n \"onResponderGrant\",\n \"onResponderMove\",\n \"onResponderRelease\",\n \"onResponderTerminate\",\n // SVG attributes that pass isPropValid\n \"strokeWidth\",\n // CSS properties that pass isPropValid but are used as component props\n \"overflow\",\n \"opacity\",\n \"cursor\",\n \"fontSize\",\n \"fontWeight\",\n \"fontFamily\",\n \"textDecoration\",\n // Cross-platform layout prop that Text consumes as CSS, never as an\n // attribute. Pinned explicitly because it is now spread into the styled\n // component rather than destructured away before it can reach the DOM.\n \"numberOfLines\",\n]);\n\nfunction shouldForwardProp(key: string): boolean {\n if (ADDITIONAL_BLOCKED_PROPS.has(key)) return false;\n return isPropValid(key);\n}\n\n/**\n * Creates a React component that renders the given HTML tag\n * but filters out non-HTML props before they reach the DOM.\n *\n * Uses @emotion/is-prop-valid (same library styled-components v4\n * uses internally) to automatically block invalid HTML attributes,\n * plus a small blocklist for false positives (RN on* handlers, SVG attrs).\n *\n * Usage: `const FilteredDiv = createFilteredElement(\"div\");`\n * Then: `const StyledBox = styled(FilteredDiv)<BoxProps>\\`...\\`;`\n *\n * styled-components can still read ALL props for CSS interpolation,\n * but only valid HTML attributes are forwarded to the DOM element.\n */\nexport function createFilteredElement(defaultTag: string) {\n const Component = React.forwardRef<HTMLElement, Record<string, unknown>>(\n ({ children, elementType, ...props }, ref) => {\n const Tag = (elementType as string) || defaultTag;\n const htmlProps: Record<string, unknown> = {};\n for (const key of Object.keys(props)) {\n if (shouldForwardProp(key)) {\n htmlProps[key] = props[key];\n }\n }\n return React.createElement(\n Tag,\n { ref, ...htmlProps },\n children as React.ReactNode\n );\n }\n );\n Component.displayName = `Filtered(${defaultTag})`;\n return Component;\n}\n","function memoize(fn) {\n var cache = {};\n return function (arg) {\n if (cache[arg] === undefined) cache[arg] = fn(arg);\n return cache[arg];\n };\n}\n\nexport default memoize;\n","import memoize from '@emotion/memoize';\n\nvar reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|inert|itemProp|itemScope|itemType|itemID|itemRef|on|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/; // https://esbench.com/bench/5bfee68a4cd7e6009ef61d23\n\nvar index = memoize(function (prop) {\n return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111\n /* o */\n && prop.charCodeAt(1) === 110\n /* n */\n && prop.charCodeAt(2) < 91;\n}\n/* Z+1 */\n);\n\nexport default index;\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\nimport { createFilteredElement } from \"./filterDOMProps\";\nimport { truncationStyles } from \"./textTruncation\";\n\nconst FilteredSpan = createFilteredElement(\"span\");\n\nconst StyledText = styled(FilteredSpan)<TextProps>`\n color: ${(props) => props.color || \"inherit\"};\n font-size: ${(props) =>\n typeof props.fontSize === \"number\"\n ? `${props.fontSize}px`\n : props.fontSize || \"inherit\"};\n font-weight: ${(props) => props.fontWeight || \"normal\"};\n font-family: ${(props) =>\n props.fontFamily ||\n '\"Aktiv Grotesk\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif'};\n line-height: ${(props) =>\n typeof props.lineHeight === \"number\"\n ? `${props.lineHeight}px`\n : props.lineHeight || \"inherit\"};\n white-space: ${(props) => props.whiteSpace || \"normal\"};\n text-align: ${(props) => props.textAlign || \"inherit\"};\n text-decoration: ${(props) => props.textDecoration || \"none\"};\n\n /* Keep last: single-line truncation has to win over white-space above. */\n ${(props) => truncationStyles(props.numberOfLines)}\n`;\n\nexport const Text: React.FC<TextProps> = ({\n style,\n className,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n ...props\n}) => {\n return (\n <StyledText\n {...props}\n style={style}\n className={className}\n id={id}\n role={role}\n data-testid={dataTestId || testID}\n />\n );\n};\n","/**\n * Web implementation of the cross-platform `numberOfLines` text prop.\n *\n * Native maps `numberOfLines` straight onto `RNText`. A web `<span>` has no\n * equivalent, so emit the CSS that produces the same result.\n *\n * Two details matter for the single-line case:\n * - `text-overflow` only takes effect on a block container, so the inline\n * `<span>` is promoted to `display: block` and capped at `max-width: 100%`.\n * - `min-width: 0` lets the text shrink below its own content width when it\n * sits in a flex row. Without it a `nowrap` label keeps its full intrinsic\n * width and pushes its siblings (icons, chevrons) out of a fixed-width field.\n *\n * Returns an empty string when there is nothing to clamp, so the declaration\n * block stays untouched for the majority of callers.\n */\nexport const truncationStyles = (numberOfLines?: number): string => {\n if (!numberOfLines || numberOfLines < 1) return \"\";\n\n if (numberOfLines === 1) {\n return `\n display: block;\n max-width: 100%;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n `;\n }\n\n return `\n display: -webkit-box;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: ${numberOfLines};\n line-clamp: ${numberOfLines};\n max-width: 100%;\n min-width: 0;\n overflow: hidden;\n `;\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = true;\nexport const isNative = false;\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { MAX_POSITION, MIN_POSITION, stopToCssColor } from \"./utils\";\nimport type { GradientStop } from \"./types\";\n\nexport interface GradientStopMarkerProps extends ThemeOverrideProps {\n /**\n * The stop this marker represents.\n */\n stop: GradientStop;\n /**\n * 1-based index used to build the accessible name (`\"Stop 2 position\"`).\n */\n index: number;\n /**\n * Whether this stop is the one currently being edited in the ColorPicker.\n */\n active?: boolean;\n /**\n * Whether the whole picker is disabled.\n */\n disabled?: boolean;\n /**\n * Pointer-down on the marker — the parent owns the drag because it owns the\n * track geometry.\n */\n onDragStart?: (event: React.MouseEvent) => void;\n /**\n * Keyboard interaction on the marker. Handled by the parent so that arrow\n * keys, Home/End, Enter/Space and Delete/Backspace share one implementation.\n */\n onKeyDown?: (event: React.KeyboardEvent) => void;\n}\n\n/**\n * A single draggable handle on the gradient preview track.\n *\n * Exposed as `role=\"slider\"` over the `0`–`100` position range so the stop can\n * be moved with the keyboard alone, and so its numeric position is announced —\n * the visual gradient must never be the only carrier of that information.\n */\nexport const GradientStopMarker: React.FC<GradientStopMarkerProps> = ({\n stop,\n index,\n active = false,\n disabled = false,\n onDragStart,\n onKeyDown,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const size = active ? 18 : 16;\n\n return (\n <Box\n role=\"slider\"\n tabIndex={disabled ? -1 : 0}\n aria-label={`Stop ${index} position`}\n aria-valuenow={stop.position}\n aria-valuemin={MIN_POSITION}\n aria-valuemax={MAX_POSITION}\n aria-valuetext={`${stop.position}%`}\n aria-orientation=\"horizontal\"\n aria-disabled={disabled || undefined}\n testID={`gradient-stop-${stop.id}`}\n data-testid={`gradient-stop-${stop.id}`}\n position=\"absolute\"\n left={`${stop.position}%`}\n width={size}\n height={size}\n borderRadius={999}\n zIndex={active ? 3 : 2}\n cursor={disabled ? \"not-allowed\" : \"grab\"}\n onMouseDown={isWeb && !disabled ? onDragStart : undefined}\n onKeyDown={disabled ? undefined : onKeyDown}\n style={{\n top: \"50%\",\n transform: \"translate(-50%, -50%)\",\n boxSizing: \"border-box\",\n borderStyle: \"solid\",\n borderWidth: 3,\n borderColor: theme.colors.background.primary,\n backgroundColor: stopToCssColor(stop),\n boxShadow: active\n ? \"0px 0px 0px 2px rgba(7, 7, 8, 0.25)\"\n : \"0px 1px 2px rgba(7, 7, 8, 0.2), 0px 1px 3px 1px rgba(7, 7, 8, 0.1)\",\n transition: \"width 0.1s ease, height 0.1s ease, box-shadow 0.1s ease\",\n outline: \"none\",\n }}\n />\n );\n};\n\nGradientStopMarker.displayName = \"GradientStopMarker\";\n","import type { GradientStop, GradientValue } from \"./types\";\n\n/**\n * Lowest stop position, in percent.\n */\nexport const MIN_POSITION = 0;\n\n/**\n * Highest stop position, in percent.\n */\nexport const MAX_POSITION = 100;\n\n/**\n * Clamps a stop position into `0`–`100` and rounds it to a whole percent.\n */\nexport const clampPosition = (position: number): number => {\n if (!Number.isFinite(position)) return MIN_POSITION;\n return Math.min(MAX_POSITION, Math.max(MIN_POSITION, Math.round(position)));\n};\n\n/**\n * Clamps a stop opacity into `0`–`100` and rounds it to a whole percent.\n */\nexport const clampOpacity = (opacity: number): number => {\n if (!Number.isFinite(opacity)) return 100;\n return Math.min(100, Math.max(0, Math.round(opacity)));\n};\n\n/**\n * Normalises any accepted hex form (`#abc`, `abc`, `#AABBCC`) to upper-case\n * `#RRGGBB`. Unparseable input falls back to `#000000` so serialisation never\n * emits an invalid CSS colour.\n */\nexport const normalizeHex = (hex: string): string => {\n const raw = String(hex ?? \"\")\n .trim()\n .replace(/^#/, \"\");\n\n if (/^[0-9a-fA-F]{3}$/.test(raw)) {\n return `#${raw\n .split(\"\")\n .map((char) => char + char)\n .join(\"\")}`.toUpperCase();\n }\n\n if (/^[0-9a-fA-F]{6}$/.test(raw)) return `#${raw}`.toUpperCase();\n\n // 8-digit hex: drop the alpha pair, opacity lives on the stop.\n if (/^[0-9a-fA-F]{8}$/.test(raw)) return `#${raw.slice(0, 6)}`.toUpperCase();\n\n return \"#000000\";\n};\n\n/**\n * Converts a hex colour to its `r` / `g` / `b` channels (`0`–`255`).\n */\nexport const hexToRgb = (hex: string): { r: number; g: number; b: number } => {\n const normalized = normalizeHex(hex).slice(1);\n return {\n r: parseInt(normalized.slice(0, 2), 16),\n g: parseInt(normalized.slice(2, 4), 16),\n b: parseInt(normalized.slice(4, 6), 16),\n };\n};\n\n/**\n * Converts `r` / `g` / `b` channels back to an upper-case `#RRGGBB` string.\n */\nexport const rgbToHex = (r: number, g: number, b: number): string => {\n const toChannel = (channel: number) =>\n Math.min(255, Math.max(0, Math.round(channel)))\n .toString(16)\n .padStart(2, \"0\");\n return `#${toChannel(r)}${toChannel(g)}${toChannel(b)}`.toUpperCase();\n};\n\n/**\n * Returns the stops ordered by position without mutating the input array.\n * Ties keep their original relative order, so two stops parked on the same\n * percent do not flicker while one of them is being dragged.\n */\nexport const sortStops = (stops: GradientStop[]): GradientStop[] =>\n stops\n .map((stop, index) => ({ stop, index }))\n .sort((a, b) =>\n a.stop.position === b.stop.position\n ? a.index - b.index\n : a.stop.position - b.stop.position\n )\n .map(({ stop }) => stop);\n\n/**\n * Serialises one stop to a CSS colour — hex while fully opaque, `rgba()` once\n * opacity drops below 100%.\n */\nexport const stopToCssColor = (stop: GradientStop): string => {\n const opacity = clampOpacity(stop.opacity);\n if (opacity >= 100) return normalizeHex(stop.color);\n const { r, g, b } = hexToRgb(stop.color);\n return `rgba(${r}, ${g}, ${b}, ${Number((opacity / 100).toFixed(2))})`;\n};\n\n/**\n * Serialises the stop list to the `<color> <position>%` sequence shared by every\n * CSS gradient function. A single stop is emitted twice (`0%` and `100%`)\n * because CSS gradients require at least two colour stops.\n */\nexport const stopsToCssStopList = (stops: GradientStop[]): string => {\n if (stops.length === 0) return \"transparent 0%, transparent 100%\";\n\n if (stops.length === 1) {\n const color = stopToCssColor(stops[0]);\n return `${color} 0%, ${color} 100%`;\n }\n\n return sortStops(stops)\n .map((stop) => `${stopToCssColor(stop)} ${clampPosition(stop.position)}%`)\n .join(\", \");\n};\n\n/**\n * Serialises the gradient to a CSS-compatible string usable as a `background`\n * or `background-image` value.\n */\nexport const toCssGradient = (value: GradientValue): string => {\n const stopList = stopsToCssStopList(value.stops);\n const angle = Number.isFinite(value.angle) ? Math.round(value.angle) : 0;\n\n switch (value.type) {\n case \"radial\":\n return `radial-gradient(circle, ${stopList})`;\n case \"angular\":\n return `conic-gradient(from ${angle}deg, ${stopList})`;\n case \"linear\":\n default:\n return `linear-gradient(${angle}deg, ${stopList})`;\n }\n};\n\n/**\n * The gradient rendered inside the horizontal preview track. The track always\n * reads left-to-right regardless of gradient type, so the user can see stop\n * ordering while dragging — the type-specific rendering is what `toCssGradient`\n * produces for the consuming surface.\n */\nexport const toPreviewCssGradient = (value: GradientValue): string =>\n `linear-gradient(90deg, ${stopsToCssStopList(value.stops)})`;\n\n/**\n * Whether the given gradient type exposes an angle control. Radial gradients\n * have no rotation, so the angle field is hidden for them.\n */\nexport const supportsAngle = (value: GradientValue[\"type\"]): boolean =>\n value === \"linear\" || value === \"angular\";\n\n/**\n * Samples the gradient at `position` (`0`–`100`) and returns the interpolated\n * colour + opacity. Used to give a newly added stop the colour the gradient\n * already had at that point, so adding a stop never visibly changes the ramp.\n */\nexport const interpolateColorAt = (\n stops: GradientStop[],\n position: number\n): { color: string; opacity: number } => {\n if (stops.length === 0) return { color: \"#000000\", opacity: 100 };\n\n const sorted = sortStops(stops);\n const target = clampPosition(position);\n\n const first = sorted[0];\n if (target <= first.position) {\n return {\n color: normalizeHex(first.color),\n opacity: clampOpacity(first.opacity),\n };\n }\n\n const last = sorted[sorted.length - 1];\n if (target >= last.position) {\n return {\n color: normalizeHex(last.color),\n opacity: clampOpacity(last.opacity),\n };\n }\n\n for (let index = 0; index < sorted.length - 1; index += 1) {\n const from = sorted[index];\n const to = sorted[index + 1];\n if (target < from.position || target > to.position) continue;\n\n const span = to.position - from.position;\n const ratio = span === 0 ? 0 : (target - from.position) / span;\n\n const fromRgb = hexToRgb(from.color);\n const toRgb = hexToRgb(to.color);\n\n return {\n color: rgbToHex(\n fromRgb.r + (toRgb.r - fromRgb.r) * ratio,\n fromRgb.g + (toRgb.g - fromRgb.g) * ratio,\n fromRgb.b + (toRgb.b - fromRgb.b) * ratio\n ),\n opacity: clampOpacity(\n clampOpacity(from.opacity) +\n (clampOpacity(to.opacity) - clampOpacity(from.opacity)) * ratio\n ),\n };\n }\n\n return {\n color: normalizeHex(last.color),\n opacity: clampOpacity(last.opacity),\n };\n};\n\n/**\n * Produces the next `stop-N` id that does not collide with an existing one.\n * Deterministic (no randomness) so stories, tests and SSR stay stable.\n */\nexport const createStopId = (stops: GradientStop[]): string => {\n const highest = stops.reduce((max, stop) => {\n const match = /^stop-(\\d+)$/.exec(stop.id);\n return match ? Math.max(max, Number(match[1])) : max;\n }, 0);\n return `stop-${highest + 1}`;\n};\n\n/**\n * Adds a stop at `position`, taking its colour from the gradient at that point.\n * Returns the original array untouched when `maxStops` is already reached, so\n * callers can compare by reference to detect a no-op.\n */\nexport const addStopAt = (\n stops: GradientStop[],\n position: number,\n maxStops: number\n): GradientStop[] => {\n if (stops.length >= maxStops) return stops;\n\n const target = clampPosition(position);\n const { color, opacity } = interpolateColorAt(stops, target);\n\n return sortStops([\n ...stops,\n { id: createStopId(stops), color, position: target, opacity },\n ]);\n};\n\n/**\n * Removes a stop by id. Returns the original array when the removal would drop\n * below `minStops`, or when the id is unknown.\n */\nexport const removeStop = (\n stops: GradientStop[],\n id: string,\n minStops: number\n): GradientStop[] => {\n if (stops.length <= minStops) return stops;\n const next = stops.filter((stop) => stop.id !== id);\n return next.length === stops.length ? stops : next;\n};\n\n/**\n * Applies a partial update to a single stop, clamping position and opacity and\n * normalising the hex colour.\n */\nexport const updateStop = (\n stops: GradientStop[],\n id: string,\n patch: Partial<Omit<GradientStop, \"id\">>\n): GradientStop[] =>\n stops.map((stop) => {\n if (stop.id !== id) return stop;\n return {\n ...stop,\n ...patch,\n color: patch.color === undefined ? stop.color : normalizeHex(patch.color),\n position:\n patch.position === undefined\n ? stop.position\n : clampPosition(patch.position),\n opacity:\n patch.opacity === undefined\n ? stop.opacity\n : clampOpacity(patch.opacity),\n };\n });\n\n/**\n * The default gradient — the two-stop `#D9D9D9 → #22A8C3` linear ramp from the\n * Figma component.\n */\nexport const DEFAULT_GRADIENT: GradientValue = {\n type: \"linear\",\n angle: 0,\n stops: [\n { id: \"stop-1\", color: \"#D9D9D9\", position: 0, opacity: 100 },\n { id: \"stop-2\", color: \"#22A8C3\", position: 100, opacity: 100 },\n ],\n};\n","import React from \"react\";\n\ninterface GlyphProps {\n /**\n * Rendered edge length in px. Injected by `IconButton` / `Icon` from the\n * resolved size token, so callers normally omit it.\n */\n size?: number;\n /**\n * Stroke colour. Injected by `IconButton` / `Icon` from the resolved content\n * colour.\n */\n color?: string;\n}\n\n/**\n * \"Add stop\" glyph.\n */\nexport const PlusGlyph: React.FC<GlyphProps> = ({\n size = 18,\n color = \"currentColor\",\n}) => (\n <svg\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M12 5v14M5 12h14\" />\n </svg>\n);\n\n/**\n * \"Remove stop\" glyph.\n */\nexport const MinusGlyph: React.FC<GlyphProps> = ({\n size = 18,\n color = \"currentColor\",\n}) => (\n <svg\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M5 12h14\" />\n </svg>\n);\n\n/**\n * Angle glyph shown inside the rotation field.\n */\nexport const AngleGlyph: React.FC<GlyphProps> = ({\n size = 16,\n color = \"currentColor\",\n}) => (\n <svg\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M4 20h16L4 4z\" />\n </svg>\n);\n\n/**\n * Percent suffix glyph used inside the numeric position field.\n */\nexport const PercentGlyph: React.FC<GlyphProps> = ({\n size = 16,\n color = \"currentColor\",\n}) => (\n <svg\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"none\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <circle cx=\"6.5\" cy=\"6.5\" r=\"2.5\" />\n <circle cx=\"17.5\" cy=\"17.5\" r=\"2.5\" />\n <path d=\"M19 5 5 19\" />\n </svg>\n);\n"],"mappings":"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","names":["React","React","styled","jsx","styled","useResolvedTheme","index","jsx","index","jsx","jsx","jsxs","useResolvedTheme","index"]}
|