@tenphi/tasty 1.3.0 → 1.4.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.
Files changed (51) hide show
  1. package/dist/compute-styles.js +2 -1
  2. package/dist/compute-styles.js.map +1 -1
  3. package/dist/config.d.ts +12 -18
  4. package/dist/config.js +1 -6
  5. package/dist/config.js.map +1 -1
  6. package/dist/core/index.d.ts +3 -3
  7. package/dist/core/index.js +2 -2
  8. package/dist/hooks/useCounterStyle.js +3 -4
  9. package/dist/hooks/useCounterStyle.js.map +1 -1
  10. package/dist/hooks/useFontFace.js +3 -4
  11. package/dist/hooks/useFontFace.js.map +1 -1
  12. package/dist/hooks/useGlobalStyles.js +3 -4
  13. package/dist/hooks/useGlobalStyles.js.map +1 -1
  14. package/dist/hooks/useKeyframes.js +3 -4
  15. package/dist/hooks/useKeyframes.js.map +1 -1
  16. package/dist/hooks/useProperty.js +3 -4
  17. package/dist/hooks/useProperty.js.map +1 -1
  18. package/dist/hooks/useRawCSS.js +3 -4
  19. package/dist/hooks/useRawCSS.js.map +1 -1
  20. package/dist/hooks/useStyles.d.ts +4 -4
  21. package/dist/hooks/useStyles.js +5 -7
  22. package/dist/hooks/useStyles.js.map +1 -1
  23. package/dist/index.d.ts +3 -3
  24. package/dist/index.js +2 -2
  25. package/dist/injector/index.d.ts +23 -2
  26. package/dist/injector/index.js +27 -1
  27. package/dist/injector/index.js.map +1 -1
  28. package/dist/injector/injector.d.ts +32 -3
  29. package/dist/injector/injector.js +130 -7
  30. package/dist/injector/injector.js.map +1 -1
  31. package/dist/injector/sheet-manager.d.ts +9 -13
  32. package/dist/injector/sheet-manager.js +30 -66
  33. package/dist/injector/sheet-manager.js.map +1 -1
  34. package/dist/injector/types.d.ts +50 -19
  35. package/dist/ssr/index.d.ts +1 -2
  36. package/dist/ssr/index.js +1 -2
  37. package/dist/ssr/index.js.map +1 -1
  38. package/dist/ssr/next.d.ts +1 -3
  39. package/dist/ssr/next.js +1 -2
  40. package/dist/ssr/next.js.map +1 -1
  41. package/dist/tasty.d.ts +1 -1
  42. package/dist/tasty.js +5 -2
  43. package/dist/tasty.js.map +1 -1
  44. package/docs/injector.md +33 -18
  45. package/docs/ssr.md +12 -42
  46. package/package.json +3 -3
  47. package/dist/hooks/resolve-ssr-collector.js +0 -14
  48. package/dist/hooks/resolve-ssr-collector.js.map +0 -1
  49. package/dist/ssr/context.d.ts +0 -8
  50. package/dist/ssr/context.js +0 -13
  51. package/dist/ssr/context.js.map +0 -1
package/dist/tasty.d.ts CHANGED
@@ -128,7 +128,7 @@ type TastyElementProps<K extends StyleList, V extends VariantMap, Tag extends ke
128
128
  type TastyComponentPropsWithDefaults<Props extends PropsWithStyles, DefaultProps extends Partial<Props>> = keyof DefaultProps extends never ? Props : { [key in Extract<keyof Props, keyof DefaultProps>]?: Props[key] } & { [key in keyof Omit<Props, keyof DefaultProps>]: Props[key] };
129
129
  declare function tasty<K extends StyleList, V extends VariantMap, E extends ElementsDefinition = Record<string, never>, Tag extends keyof JSX.IntrinsicElements = 'div', M extends ModPropsInput = readonly never[], TP extends TokenPropsInput = readonly never[]>(options: TastyElementOptions<K, V, E, Tag, M, TP>, secondArg?: never): ForwardRefExoticComponent<PropsWithoutRef<TastyElementProps<K, V, Tag, M, TP>> & RefAttributes<unknown>> & SubElementComponents<E>;
130
130
  declare function tasty<Props extends PropsWithStyles, DefaultProps extends Partial<Props> = Partial<Props>>(Component: ComponentType<Props>, options?: TastyProps<never, never, Record<string, never>, Props>): ComponentType<TastyComponentPropsWithDefaults<Props, DefaultProps>>;
131
- declare const Element: ForwardRefExoticComponent<Omit<AllBasePropsWithMods<StyleList, readonly never[], readonly never[]>, "slot" | "title" | "children" | "className" | "role" | "id" | "hidden" | "prefix" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "lang" | "nonce" | "spellCheck" | "tabIndex" | "radioGroup" | "about" | "datatype" | "inlist" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "popover" | "popoverTargetAction" | "popoverTarget" | "inert" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onScrollEnd" | "onScrollEndCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onToggle" | "onBeforeToggle" | "onTransitionCancel" | "onTransitionCancelCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "onTransitionRun" | "onTransitionRunCapture" | "onTransitionStart" | "onTransitionStartCapture" | "key"> & WithVariant<VariantMap> & Omit<Omit<AllHTMLAttributes<HTMLElement>, keyof _$react.ClassAttributes<HTMLDivElement> | keyof _$react.HTMLAttributes<HTMLDivElement>> & _$react.ClassAttributes<HTMLDivElement> & _$react.HTMLAttributes<HTMLDivElement>, "style" | "clipPath" | "filter" | "image" | "marker" | "mask" | "fill" | "display" | "font" | "preset" | "hide" | "whiteSpace" | "opacity" | "transition" | "gridArea" | "order" | "gridColumn" | "gridRow" | "placeSelf" | "alignSelf" | "justifySelf" | "zIndex" | "margin" | "inset" | "position" | "scrollMargin" | "padding" | "paddingInline" | "paddingBlock" | "overflow" | "scrollbar" | "textAlign" | "border" | "radius" | "shadow" | "outline" | "color" | "fade" | "textTransform" | "fontWeight" | "fontStyle" | "width" | "height" | "flexBasis" | "flexGrow" | "flexShrink" | "flex" | "flow" | "place" | "placeItems" | "placeContent" | "alignItems" | "alignContent" | "justifyItems" | "justifyContent" | "align" | "justify" | "gap" | "columnGap" | "rowGap" | "gridColumns" | "gridRows" | "gridTemplate" | "gridAreas" | "mods" | "css" | "content" | "translate" | "as" | "background" | "top" | "right" | "bottom" | "left" | "all" | "page" | "qa" | "qaVal" | "scrollMarginTop" | "scrollMarginRight" | "scrollMarginBottom" | "scrollMarginLeft" | "scrollMarginBlock" | "scrollMarginInline" | "accentColor" | "alignTracks" | "alignmentBaseline" | "anchorName" | "anchorScope" | "animationComposition" | "animationDelay" | "animationDirection" | "animationDuration" | "animationFillMode" | "animationIterationCount" | "animationName" | "animationPlayState" | "animationRangeEnd" | "animationRangeStart" | "animationTimeline" | "animationTimingFunction" | "appearance" | "aspectRatio" | "backdropFilter" | "backfaceVisibility" | "backgroundAttachment" | "backgroundBlendMode" | "backgroundClip" | "backgroundColor" | "backgroundImage" | "backgroundOrigin" | "backgroundPositionX" | "backgroundPositionY" | "backgroundRepeat" | "backgroundSize" | "baselineShift" | "blockSize" | "borderBlockEndColor" | "borderBlockEndStyle" | "borderBlockEndWidth" | "borderBlockStartColor" | "borderBlockStartStyle" | "borderBlockStartWidth" | "borderBottomColor" | "borderBottomLeftRadius" | "borderBottomRightRadius" | "borderBottomStyle" | "borderBottomWidth" | "borderCollapse" | "borderEndEndRadius" | "borderEndStartRadius" | "borderImageOutset" | "borderImageRepeat" | "borderImageSlice" | "borderImageSource" | "borderImageWidth" | "borderInlineEndColor" | "borderInlineEndStyle" | "borderInlineEndWidth" | "borderInlineStartColor" | "borderInlineStartStyle" | "borderInlineStartWidth" | "borderLeftColor" | "borderLeftStyle" | "borderLeftWidth" | "borderRightColor" | "borderRightStyle" | "borderRightWidth" | "borderSpacing" | "borderStartEndRadius" | "borderStartStartRadius" | "borderTopColor" | "borderTopLeftRadius" | "borderTopRightRadius" | "borderTopStyle" | "borderTopWidth" | "boxDecorationBreak" | "boxShadow" | "boxSizing" | "breakAfter" | "breakBefore" | "breakInside" | "captionSide" | "caretColor" | "caretShape" | "clear" | "clipRule" | "colorAdjust" | "colorInterpolationFilters" | "colorScheme" | "columnCount" | "columnFill" | "columnRuleColor" | "columnRuleStyle" | "columnRuleWidth" | "columnSpan" | "columnWidth" | "contain" | "containIntrinsicBlockSize" | "containIntrinsicHeight" | "containIntrinsicInlineSize" | "containIntrinsicWidth" | "containerName" | "containerType" | "contentVisibility" | "counterIncrement" | "counterReset" | "counterSet" | "cursor" | "cx" | "cy" | "d" | "direction" | "dominantBaseline" | "emptyCells" | "fieldSizing" | "fillOpacity" | "fillRule" | "flexDirection" | "flexWrap" | "float" | "floodColor" | "floodOpacity" | "fontFamily" | "fontFeatureSettings" | "fontKerning" | "fontLanguageOverride" | "fontOpticalSizing" | "fontPalette" | "fontSize" | "fontSizeAdjust" | "fontSmooth" | "fontSynthesis" | "fontSynthesisPosition" | "fontSynthesisSmallCaps" | "fontSynthesisStyle" | "fontSynthesisWeight" | "fontVariant" | "fontVariantAlternates" | "fontVariantCaps" | "fontVariantEastAsian" | "fontVariantEmoji" | "fontVariantLigatures" | "fontVariantNumeric" | "fontVariantPosition" | "fontVariationSettings" | "fontWidth" | "forcedColorAdjust" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridColumnEnd" | "gridColumnStart" | "gridRowEnd" | "gridRowStart" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "hangingPunctuation" | "hyphenateCharacter" | "hyphenateLimitChars" | "hyphens" | "imageOrientation" | "imageRendering" | "imageResolution" | "initialLetter" | "initialLetterAlign" | "inlineSize" | "insetBlockEnd" | "insetBlockStart" | "insetInlineEnd" | "insetInlineStart" | "interpolateSize" | "isolation" | "justifyTracks" | "letterSpacing" | "lightingColor" | "lineBreak" | "lineHeight" | "lineHeightStep" | "listStyleImage" | "listStylePosition" | "listStyleType" | "marginBlockEnd" | "marginBlockStart" | "marginBottom" | "marginInlineEnd" | "marginInlineStart" | "marginLeft" | "marginRight" | "marginTop" | "marginTrim" | "markerEnd" | "markerMid" | "markerStart" | "maskBorderMode" | "maskBorderOutset" | "maskBorderRepeat" | "maskBorderSlice" | "maskBorderSource" | "maskBorderWidth" | "maskClip" | "maskComposite" | "maskImage" | "maskMode" | "maskOrigin" | "maskPosition" | "maskRepeat" | "maskSize" | "maskType" | "masonryAutoFlow" | "mathDepth" | "mathShift" | "mathStyle" | "maxBlockSize" | "maxHeight" | "maxInlineSize" | "maxLines" | "maxWidth" | "minBlockSize" | "minHeight" | "minInlineSize" | "minWidth" | "mixBlendMode" | "motionDistance" | "motionPath" | "motionRotation" | "objectFit" | "objectPosition" | "objectViewBox" | "offsetAnchor" | "offsetDistance" | "offsetPath" | "offsetPosition" | "offsetRotate" | "offsetRotation" | "orphans" | "outlineColor" | "outlineOffset" | "outlineStyle" | "outlineWidth" | "overflowAnchor" | "overflowBlock" | "overflowClipBox" | "overflowClipMargin" | "overflowInline" | "overflowWrap" | "overflowX" | "overflowY" | "overlay" | "overscrollBehaviorBlock" | "overscrollBehaviorInline" | "overscrollBehaviorX" | "overscrollBehaviorY" | "paddingBlockEnd" | "paddingBlockStart" | "paddingBottom" | "paddingInlineEnd" | "paddingInlineStart" | "paddingLeft" | "paddingRight" | "paddingTop" | "paintOrder" | "perspective" | "perspectiveOrigin" | "pointerEvents" | "positionAnchor" | "positionArea" | "positionTryFallbacks" | "positionTryOrder" | "positionVisibility" | "printColorAdjust" | "quotes" | "r" | "resize" | "rotate" | "rubyAlign" | "rubyMerge" | "rubyOverhang" | "rubyPosition" | "rx" | "ry" | "scale" | "scrollBehavior" | "scrollInitialTarget" | "scrollMarginBlockEnd" | "scrollMarginBlockStart" | "scrollMarginInlineEnd" | "scrollMarginInlineStart" | "scrollPaddingBlockEnd" | "scrollPaddingBlockStart" | "scrollPaddingBottom" | "scrollPaddingInlineEnd" | "scrollPaddingInlineStart" | "scrollPaddingLeft" | "scrollPaddingRight" | "scrollPaddingTop" | "scrollSnapAlign" | "scrollSnapMarginBottom" | "scrollSnapMarginLeft" | "scrollSnapMarginRight" | "scrollSnapMarginTop" | "scrollSnapStop" | "scrollSnapType" | "scrollTimelineAxis" | "scrollTimelineName" | "scrollbarColor" | "scrollbarGutter" | "scrollbarWidth" | "shapeImageThreshold" | "shapeMargin" | "shapeOutside" | "shapeRendering" | "speakAs" | "stopColor" | "stopOpacity" | "stroke" | "strokeColor" | "strokeDasharray" | "strokeDashoffset" | "strokeLinecap" | "strokeLinejoin" | "strokeMiterlimit" | "strokeOpacity" | "strokeWidth" | "tabSize" | "tableLayout" | "textAlignLast" | "textAnchor" | "textAutospace" | "textBox" | "textBoxEdge" | "textBoxTrim" | "textCombineUpright" | "textDecorationColor" | "textDecorationLine" | "textDecorationSkip" | "textDecorationSkipInk" | "textDecorationStyle" | "textDecorationThickness" | "textEmphasisColor" | "textEmphasisPosition" | "textEmphasisStyle" | "textIndent" | "textJustify" | "textOrientation" | "textOverflow" | "textRendering" | "textShadow" | "textSizeAdjust" | "textSpacingTrim" | "textUnderlineOffset" | "textUnderlinePosition" | "textWrapMode" | "textWrapStyle" | "timelineScope" | "touchAction" | "transform" | "transformBox" | "transformOrigin" | "transformStyle" | "transitionBehavior" | "transitionDelay" | "transitionDuration" | "transitionProperty" | "transitionTimingFunction" | "unicodeBidi" | "userSelect" | "vectorEffect" | "verticalAlign" | "viewTimelineAxis" | "viewTimelineInset" | "viewTimelineName" | "viewTransitionClass" | "viewTransitionName" | "visibility" | "whiteSpaceCollapse" | "widows" | "willChange" | "wordBreak" | "wordSpacing" | "wordWrap" | "writingMode" | "x" | "y" | "zoom" | "animation" | "animationRange" | "backgroundPosition" | "borderBlock" | "borderBlockColor" | "borderBlockEnd" | "borderBlockStart" | "borderBlockStyle" | "borderBlockWidth" | "borderBottom" | "borderColor" | "borderImage" | "borderInline" | "borderInlineColor" | "borderInlineEnd" | "borderInlineStart" | "borderInlineStyle" | "borderInlineWidth" | "borderLeft" | "borderRadius" | "borderRight" | "borderStyle" | "borderTop" | "borderWidth" | "caret" | "columnRule" | "columns" | "containIntrinsicSize" | "container" | "flexFlow" | "grid" | "insetBlock" | "insetInline" | "lineClamp" | "listStyle" | "marginBlock" | "marginInline" | "maskBorder" | "motion" | "offset" | "overscrollBehavior" | "positionTry" | "scrollPadding" | "scrollPaddingBlock" | "scrollPaddingInline" | "scrollSnapMargin" | "scrollTimeline" | "textDecoration" | "textEmphasis" | "textWrap" | "viewTimeline" | "MozAnimationDelay" | "MozAnimationDirection" | "MozAnimationDuration" | "MozAnimationFillMode" | "MozAnimationIterationCount" | "MozAnimationName" | "MozAnimationPlayState" | "MozAnimationTimingFunction" | "MozAppearance" | "MozBackfaceVisibility" | "MozBinding" | "MozBorderBottomColors" | "MozBorderEndColor" | "MozBorderEndStyle" | "MozBorderEndWidth" | "MozBorderLeftColors" | "MozBorderRightColors" | "MozBorderStartColor" | "MozBorderStartStyle" | "MozBorderTopColors" | "MozBoxSizing" | "MozColumnRuleColor" | "MozColumnRuleStyle" | "MozColumnRuleWidth" | "MozColumnWidth" | "MozContextProperties" | "MozFontFeatureSettings" | "MozFontLanguageOverride" | "MozHyphens" | "MozMarginEnd" | "MozMarginStart" | "MozOrient" | "MozOsxFontSmoothing" | "MozOutlineRadiusBottomleft" | "MozOutlineRadiusBottomright" | "MozOutlineRadiusTopleft" | "MozOutlineRadiusTopright" | "MozPaddingEnd" | "MozPaddingStart" | "MozPerspective" | "MozPerspectiveOrigin" | "MozStackSizing" | "MozTabSize" | "MozTextBlink" | "MozTextSizeAdjust" | "MozTransform" | "MozTransformOrigin" | "MozTransformStyle" | "MozUserModify" | "MozUserSelect" | "MozWindowDragging" | "MozWindowShadow" | "msAccelerator" | "msBlockProgression" | "msContentZoomChaining" | "msContentZoomLimitMax" | "msContentZoomLimitMin" | "msContentZoomSnapPoints" | "msContentZoomSnapType" | "msContentZooming" | "msFilter" | "msFlexDirection" | "msFlexPositive" | "msFlowFrom" | "msFlowInto" | "msGridColumns" | "msGridRows" | "msHighContrastAdjust" | "msHyphenateLimitChars" | "msHyphenateLimitLines" | "msHyphenateLimitZone" | "msHyphens" | "msImeAlign" | "msLineBreak" | "msOrder" | "msOverflowStyle" | "msOverflowX" | "msOverflowY" | "msScrollChaining" | "msScrollLimitXMax" | "msScrollLimitXMin" | "msScrollLimitYMax" | "msScrollLimitYMin" | "msScrollRails" | "msScrollSnapPointsX" | "msScrollSnapPointsY" | "msScrollSnapType" | "msScrollTranslation" | "msScrollbar3dlightColor" | "msScrollbarArrowColor" | "msScrollbarBaseColor" | "msScrollbarDarkshadowColor" | "msScrollbarFaceColor" | "msScrollbarHighlightColor" | "msScrollbarShadowColor" | "msScrollbarTrackColor" | "msTextAutospace" | "msTextCombineHorizontal" | "msTextOverflow" | "msTouchAction" | "msTouchSelect" | "msTransform" | "msTransformOrigin" | "msTransitionDelay" | "msTransitionDuration" | "msTransitionProperty" | "msTransitionTimingFunction" | "msUserSelect" | "msWordBreak" | "msWrapFlow" | "msWrapMargin" | "msWrapThrough" | "msWritingMode" | "WebkitAlignContent" | "WebkitAlignItems" | "WebkitAlignSelf" | "WebkitAnimationDelay" | "WebkitAnimationDirection" | "WebkitAnimationDuration" | "WebkitAnimationFillMode" | "WebkitAnimationIterationCount" | "WebkitAnimationName" | "WebkitAnimationPlayState" | "WebkitAnimationTimingFunction" | "WebkitAppearance" | "WebkitBackdropFilter" | "WebkitBackfaceVisibility" | "WebkitBackgroundClip" | "WebkitBackgroundOrigin" | "WebkitBackgroundSize" | "WebkitBorderBeforeColor" | "WebkitBorderBeforeStyle" | "WebkitBorderBeforeWidth" | "WebkitBorderBottomLeftRadius" | "WebkitBorderBottomRightRadius" | "WebkitBorderImageSlice" | "WebkitBorderTopLeftRadius" | "WebkitBorderTopRightRadius" | "WebkitBoxDecorationBreak" | "WebkitBoxReflect" | "WebkitBoxShadow" | "WebkitBoxSizing" | "WebkitClipPath" | "WebkitColumnCount" | "WebkitColumnFill" | "WebkitColumnRuleColor" | "WebkitColumnRuleStyle" | "WebkitColumnRuleWidth" | "WebkitColumnSpan" | "WebkitColumnWidth" | "WebkitFilter" | "WebkitFlexBasis" | "WebkitFlexDirection" | "WebkitFlexGrow" | "WebkitFlexShrink" | "WebkitFlexWrap" | "WebkitFontFeatureSettings" | "WebkitFontKerning" | "WebkitFontSmoothing" | "WebkitFontVariantLigatures" | "WebkitHyphenateCharacter" | "WebkitHyphens" | "WebkitInitialLetter" | "WebkitJustifyContent" | "WebkitLineBreak" | "WebkitLineClamp" | "WebkitLogicalHeight" | "WebkitLogicalWidth" | "WebkitMarginEnd" | "WebkitMarginStart" | "WebkitMaskAttachment" | "WebkitMaskBoxImageOutset" | "WebkitMaskBoxImageRepeat" | "WebkitMaskBoxImageSlice" | "WebkitMaskBoxImageSource" | "WebkitMaskBoxImageWidth" | "WebkitMaskClip" | "WebkitMaskComposite" | "WebkitMaskImage" | "WebkitMaskOrigin" | "WebkitMaskPosition" | "WebkitMaskPositionX" | "WebkitMaskPositionY" | "WebkitMaskRepeat" | "WebkitMaskRepeatX" | "WebkitMaskRepeatY" | "WebkitMaskSize" | "WebkitMaxInlineSize" | "WebkitOrder" | "WebkitOverflowScrolling" | "WebkitPaddingEnd" | "WebkitPaddingStart" | "WebkitPerspective" | "WebkitPerspectiveOrigin" | "WebkitPrintColorAdjust" | "WebkitRubyPosition" | "WebkitScrollSnapType" | "WebkitShapeMargin" | "WebkitTapHighlightColor" | "WebkitTextCombine" | "WebkitTextDecorationColor" | "WebkitTextDecorationLine" | "WebkitTextDecorationSkip" | "WebkitTextDecorationStyle" | "WebkitTextEmphasisColor" | "WebkitTextEmphasisPosition" | "WebkitTextEmphasisStyle" | "WebkitTextFillColor" | "WebkitTextOrientation" | "WebkitTextSizeAdjust" | "WebkitTextStrokeColor" | "WebkitTextStrokeWidth" | "WebkitTextUnderlinePosition" | "WebkitTouchCallout" | "WebkitTransform" | "WebkitTransformOrigin" | "WebkitTransformStyle" | "WebkitTransitionDelay" | "WebkitTransitionDuration" | "WebkitTransitionProperty" | "WebkitTransitionTimingFunction" | "WebkitUserModify" | "WebkitUserSelect" | "WebkitWritingMode" | "MozAnimation" | "MozBorderImage" | "MozColumnRule" | "MozColumns" | "MozOutlineRadius" | "MozTransition" | "msContentZoomLimit" | "msContentZoomSnap" | "msFlex" | "msScrollLimit" | "msScrollSnapX" | "msScrollSnapY" | "msTransition" | "WebkitAnimation" | "WebkitBorderBefore" | "WebkitBorderImage" | "WebkitBorderRadius" | "WebkitColumnRule" | "WebkitColumns" | "WebkitFlex" | "WebkitFlexFlow" | "WebkitMask" | "WebkitMaskBoxImage" | "WebkitTextEmphasis" | "WebkitTextStroke" | "WebkitTransition" | "boxAlign" | "boxDirection" | "boxFlex" | "boxFlexGroup" | "boxLines" | "boxOrdinalGroup" | "boxOrient" | "boxPack" | "clip" | "fontStretch" | "gridColumnGap" | "gridGap" | "gridRowGap" | "imeMode" | "insetArea" | "offsetBlock" | "offsetBlockEnd" | "offsetBlockStart" | "offsetInline" | "offsetInlineEnd" | "offsetInlineStart" | "pageBreakAfter" | "pageBreakBefore" | "pageBreakInside" | "positionTryOptions" | "scrollSnapCoordinate" | "scrollSnapDestination" | "scrollSnapPointsX" | "scrollSnapPointsY" | "scrollSnapTypeX" | "scrollSnapTypeY" | "KhtmlBoxAlign" | "KhtmlBoxDirection" | "KhtmlBoxFlex" | "KhtmlBoxFlexGroup" | "KhtmlBoxLines" | "KhtmlBoxOrdinalGroup" | "KhtmlBoxOrient" | "KhtmlBoxPack" | "KhtmlLineBreak" | "KhtmlOpacity" | "KhtmlUserSelect" | "MozBackgroundClip" | "MozBackgroundOrigin" | "MozBackgroundSize" | "MozBorderRadius" | "MozBorderRadiusBottomleft" | "MozBorderRadiusBottomright" | "MozBorderRadiusTopleft" | "MozBorderRadiusTopright" | "MozBoxAlign" | "MozBoxDirection" | "MozBoxFlex" | "MozBoxOrdinalGroup" | "MozBoxOrient" | "MozBoxPack" | "MozBoxShadow" | "MozColumnCount" | "MozColumnFill" | "MozFloatEdge" | "MozForceBrokenImageIcon" | "MozOpacity" | "MozOutline" | "MozOutlineColor" | "MozOutlineStyle" | "MozOutlineWidth" | "MozTextAlignLast" | "MozTextDecorationColor" | "MozTextDecorationLine" | "MozTextDecorationStyle" | "MozTransitionDelay" | "MozTransitionDuration" | "MozTransitionProperty" | "MozTransitionTimingFunction" | "MozUserFocus" | "MozUserInput" | "msImeMode" | "OAnimation" | "OAnimationDelay" | "OAnimationDirection" | "OAnimationDuration" | "OAnimationFillMode" | "OAnimationIterationCount" | "OAnimationName" | "OAnimationPlayState" | "OAnimationTimingFunction" | "OBackgroundSize" | "OBorderImage" | "OObjectFit" | "OObjectPosition" | "OTabSize" | "OTextOverflow" | "OTransform" | "OTransformOrigin" | "OTransition" | "OTransitionDelay" | "OTransitionDuration" | "OTransitionProperty" | "OTransitionTimingFunction" | "WebkitBoxAlign" | "WebkitBoxDirection" | "WebkitBoxFlex" | "WebkitBoxFlexGroup" | "WebkitBoxLines" | "WebkitBoxOrdinalGroup" | "WebkitBoxOrient" | "WebkitBoxPack" | "colorInterpolation" | "colorRendering" | "glyphOrientationVertical" | "svgFill" | "boldFontWeight" | "@keyframes" | "@properties" | "@fontFace" | "@counterStyle" | "recipe" | "element" | "styles" | "breakpoints" | "block" | "inline" | "isHidden" | "isDisabled" | "theme" | "tokens" | "ref"> & RefAttributes<unknown>> & SubElementComponents<Record<string, never>>;
131
+ declare const Element: ForwardRefExoticComponent<Omit<AllBasePropsWithMods<StyleList, readonly never[], readonly never[]>, "children" | "slot" | "title" | "className" | "role" | "id" | "hidden" | "prefix" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "lang" | "nonce" | "spellCheck" | "tabIndex" | "radioGroup" | "about" | "datatype" | "inlist" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "popover" | "popoverTargetAction" | "popoverTarget" | "inert" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onScrollEnd" | "onScrollEndCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onToggle" | "onBeforeToggle" | "onTransitionCancel" | "onTransitionCancelCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "onTransitionRun" | "onTransitionRunCapture" | "onTransitionStart" | "onTransitionStartCapture" | "key"> & WithVariant<VariantMap> & Omit<Omit<AllHTMLAttributes<HTMLElement>, keyof _$react.ClassAttributes<HTMLDivElement> | keyof _$react.HTMLAttributes<HTMLDivElement>> & _$react.ClassAttributes<HTMLDivElement> & _$react.HTMLAttributes<HTMLDivElement>, "top" | "right" | "bottom" | "left" | "display" | "font" | "preset" | "hide" | "whiteSpace" | "opacity" | "transition" | "gridArea" | "order" | "gridColumn" | "gridRow" | "placeSelf" | "alignSelf" | "justifySelf" | "zIndex" | "margin" | "inset" | "position" | "scrollMargin" | "padding" | "paddingInline" | "paddingBlock" | "overflow" | "scrollbar" | "textAlign" | "border" | "radius" | "shadow" | "outline" | "color" | "fill" | "fade" | "image" | "textTransform" | "fontWeight" | "fontStyle" | "width" | "height" | "flexBasis" | "flexGrow" | "flexShrink" | "flex" | "flow" | "place" | "placeItems" | "placeContent" | "alignItems" | "alignContent" | "justifyItems" | "justifyContent" | "align" | "justify" | "gap" | "columnGap" | "rowGap" | "gridColumns" | "gridRows" | "gridTemplate" | "gridAreas" | "style" | "mods" | "css" | "content" | "translate" | "as" | "background" | "all" | "page" | "qa" | "qaVal" | "scrollMarginTop" | "scrollMarginRight" | "scrollMarginBottom" | "scrollMarginLeft" | "scrollMarginBlock" | "scrollMarginInline" | "accentColor" | "alignTracks" | "alignmentBaseline" | "anchorName" | "anchorScope" | "animationComposition" | "animationDelay" | "animationDirection" | "animationDuration" | "animationFillMode" | "animationIterationCount" | "animationName" | "animationPlayState" | "animationRangeEnd" | "animationRangeStart" | "animationTimeline" | "animationTimingFunction" | "appearance" | "aspectRatio" | "backdropFilter" | "backfaceVisibility" | "backgroundAttachment" | "backgroundBlendMode" | "backgroundClip" | "backgroundColor" | "backgroundImage" | "backgroundOrigin" | "backgroundPositionX" | "backgroundPositionY" | "backgroundRepeat" | "backgroundSize" | "baselineShift" | "blockSize" | "borderBlockEndColor" | "borderBlockEndStyle" | "borderBlockEndWidth" | "borderBlockStartColor" | "borderBlockStartStyle" | "borderBlockStartWidth" | "borderBottomColor" | "borderBottomLeftRadius" | "borderBottomRightRadius" | "borderBottomStyle" | "borderBottomWidth" | "borderCollapse" | "borderEndEndRadius" | "borderEndStartRadius" | "borderImageOutset" | "borderImageRepeat" | "borderImageSlice" | "borderImageSource" | "borderImageWidth" | "borderInlineEndColor" | "borderInlineEndStyle" | "borderInlineEndWidth" | "borderInlineStartColor" | "borderInlineStartStyle" | "borderInlineStartWidth" | "borderLeftColor" | "borderLeftStyle" | "borderLeftWidth" | "borderRightColor" | "borderRightStyle" | "borderRightWidth" | "borderSpacing" | "borderStartEndRadius" | "borderStartStartRadius" | "borderTopColor" | "borderTopLeftRadius" | "borderTopRightRadius" | "borderTopStyle" | "borderTopWidth" | "boxDecorationBreak" | "boxShadow" | "boxSizing" | "breakAfter" | "breakBefore" | "breakInside" | "captionSide" | "caretColor" | "caretShape" | "clear" | "clipPath" | "clipRule" | "colorAdjust" | "colorInterpolationFilters" | "colorScheme" | "columnCount" | "columnFill" | "columnRuleColor" | "columnRuleStyle" | "columnRuleWidth" | "columnSpan" | "columnWidth" | "contain" | "containIntrinsicBlockSize" | "containIntrinsicHeight" | "containIntrinsicInlineSize" | "containIntrinsicWidth" | "containerName" | "containerType" | "contentVisibility" | "counterIncrement" | "counterReset" | "counterSet" | "cursor" | "cx" | "cy" | "d" | "direction" | "dominantBaseline" | "emptyCells" | "fieldSizing" | "fillOpacity" | "fillRule" | "filter" | "flexDirection" | "flexWrap" | "float" | "floodColor" | "floodOpacity" | "fontFamily" | "fontFeatureSettings" | "fontKerning" | "fontLanguageOverride" | "fontOpticalSizing" | "fontPalette" | "fontSize" | "fontSizeAdjust" | "fontSmooth" | "fontSynthesis" | "fontSynthesisPosition" | "fontSynthesisSmallCaps" | "fontSynthesisStyle" | "fontSynthesisWeight" | "fontVariant" | "fontVariantAlternates" | "fontVariantCaps" | "fontVariantEastAsian" | "fontVariantEmoji" | "fontVariantLigatures" | "fontVariantNumeric" | "fontVariantPosition" | "fontVariationSettings" | "fontWidth" | "forcedColorAdjust" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridColumnEnd" | "gridColumnStart" | "gridRowEnd" | "gridRowStart" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "hangingPunctuation" | "hyphenateCharacter" | "hyphenateLimitChars" | "hyphens" | "imageOrientation" | "imageRendering" | "imageResolution" | "initialLetter" | "initialLetterAlign" | "inlineSize" | "insetBlockEnd" | "insetBlockStart" | "insetInlineEnd" | "insetInlineStart" | "interpolateSize" | "isolation" | "justifyTracks" | "letterSpacing" | "lightingColor" | "lineBreak" | "lineHeight" | "lineHeightStep" | "listStyleImage" | "listStylePosition" | "listStyleType" | "marginBlockEnd" | "marginBlockStart" | "marginBottom" | "marginInlineEnd" | "marginInlineStart" | "marginLeft" | "marginRight" | "marginTop" | "marginTrim" | "marker" | "markerEnd" | "markerMid" | "markerStart" | "maskBorderMode" | "maskBorderOutset" | "maskBorderRepeat" | "maskBorderSlice" | "maskBorderSource" | "maskBorderWidth" | "maskClip" | "maskComposite" | "maskImage" | "maskMode" | "maskOrigin" | "maskPosition" | "maskRepeat" | "maskSize" | "maskType" | "masonryAutoFlow" | "mathDepth" | "mathShift" | "mathStyle" | "maxBlockSize" | "maxHeight" | "maxInlineSize" | "maxLines" | "maxWidth" | "minBlockSize" | "minHeight" | "minInlineSize" | "minWidth" | "mixBlendMode" | "motionDistance" | "motionPath" | "motionRotation" | "objectFit" | "objectPosition" | "objectViewBox" | "offsetAnchor" | "offsetDistance" | "offsetPath" | "offsetPosition" | "offsetRotate" | "offsetRotation" | "orphans" | "outlineColor" | "outlineOffset" | "outlineStyle" | "outlineWidth" | "overflowAnchor" | "overflowBlock" | "overflowClipBox" | "overflowClipMargin" | "overflowInline" | "overflowWrap" | "overflowX" | "overflowY" | "overlay" | "overscrollBehaviorBlock" | "overscrollBehaviorInline" | "overscrollBehaviorX" | "overscrollBehaviorY" | "paddingBlockEnd" | "paddingBlockStart" | "paddingBottom" | "paddingInlineEnd" | "paddingInlineStart" | "paddingLeft" | "paddingRight" | "paddingTop" | "paintOrder" | "perspective" | "perspectiveOrigin" | "pointerEvents" | "positionAnchor" | "positionArea" | "positionTryFallbacks" | "positionTryOrder" | "positionVisibility" | "printColorAdjust" | "quotes" | "r" | "resize" | "rotate" | "rubyAlign" | "rubyMerge" | "rubyOverhang" | "rubyPosition" | "rx" | "ry" | "scale" | "scrollBehavior" | "scrollInitialTarget" | "scrollMarginBlockEnd" | "scrollMarginBlockStart" | "scrollMarginInlineEnd" | "scrollMarginInlineStart" | "scrollPaddingBlockEnd" | "scrollPaddingBlockStart" | "scrollPaddingBottom" | "scrollPaddingInlineEnd" | "scrollPaddingInlineStart" | "scrollPaddingLeft" | "scrollPaddingRight" | "scrollPaddingTop" | "scrollSnapAlign" | "scrollSnapMarginBottom" | "scrollSnapMarginLeft" | "scrollSnapMarginRight" | "scrollSnapMarginTop" | "scrollSnapStop" | "scrollSnapType" | "scrollTimelineAxis" | "scrollTimelineName" | "scrollbarColor" | "scrollbarGutter" | "scrollbarWidth" | "shapeImageThreshold" | "shapeMargin" | "shapeOutside" | "shapeRendering" | "speakAs" | "stopColor" | "stopOpacity" | "stroke" | "strokeColor" | "strokeDasharray" | "strokeDashoffset" | "strokeLinecap" | "strokeLinejoin" | "strokeMiterlimit" | "strokeOpacity" | "strokeWidth" | "tabSize" | "tableLayout" | "textAlignLast" | "textAnchor" | "textAutospace" | "textBox" | "textBoxEdge" | "textBoxTrim" | "textCombineUpright" | "textDecorationColor" | "textDecorationLine" | "textDecorationSkip" | "textDecorationSkipInk" | "textDecorationStyle" | "textDecorationThickness" | "textEmphasisColor" | "textEmphasisPosition" | "textEmphasisStyle" | "textIndent" | "textJustify" | "textOrientation" | "textOverflow" | "textRendering" | "textShadow" | "textSizeAdjust" | "textSpacingTrim" | "textUnderlineOffset" | "textUnderlinePosition" | "textWrapMode" | "textWrapStyle" | "timelineScope" | "touchAction" | "transform" | "transformBox" | "transformOrigin" | "transformStyle" | "transitionBehavior" | "transitionDelay" | "transitionDuration" | "transitionProperty" | "transitionTimingFunction" | "unicodeBidi" | "userSelect" | "vectorEffect" | "verticalAlign" | "viewTimelineAxis" | "viewTimelineInset" | "viewTimelineName" | "viewTransitionClass" | "viewTransitionName" | "visibility" | "whiteSpaceCollapse" | "widows" | "willChange" | "wordBreak" | "wordSpacing" | "wordWrap" | "writingMode" | "x" | "y" | "zoom" | "animation" | "animationRange" | "backgroundPosition" | "borderBlock" | "borderBlockColor" | "borderBlockEnd" | "borderBlockStart" | "borderBlockStyle" | "borderBlockWidth" | "borderBottom" | "borderColor" | "borderImage" | "borderInline" | "borderInlineColor" | "borderInlineEnd" | "borderInlineStart" | "borderInlineStyle" | "borderInlineWidth" | "borderLeft" | "borderRadius" | "borderRight" | "borderStyle" | "borderTop" | "borderWidth" | "caret" | "columnRule" | "columns" | "containIntrinsicSize" | "container" | "flexFlow" | "grid" | "insetBlock" | "insetInline" | "lineClamp" | "listStyle" | "marginBlock" | "marginInline" | "mask" | "maskBorder" | "motion" | "offset" | "overscrollBehavior" | "positionTry" | "scrollPadding" | "scrollPaddingBlock" | "scrollPaddingInline" | "scrollSnapMargin" | "scrollTimeline" | "textDecoration" | "textEmphasis" | "textWrap" | "viewTimeline" | "MozAnimationDelay" | "MozAnimationDirection" | "MozAnimationDuration" | "MozAnimationFillMode" | "MozAnimationIterationCount" | "MozAnimationName" | "MozAnimationPlayState" | "MozAnimationTimingFunction" | "MozAppearance" | "MozBackfaceVisibility" | "MozBinding" | "MozBorderBottomColors" | "MozBorderEndColor" | "MozBorderEndStyle" | "MozBorderEndWidth" | "MozBorderLeftColors" | "MozBorderRightColors" | "MozBorderStartColor" | "MozBorderStartStyle" | "MozBorderTopColors" | "MozBoxSizing" | "MozColumnRuleColor" | "MozColumnRuleStyle" | "MozColumnRuleWidth" | "MozColumnWidth" | "MozContextProperties" | "MozFontFeatureSettings" | "MozFontLanguageOverride" | "MozHyphens" | "MozMarginEnd" | "MozMarginStart" | "MozOrient" | "MozOsxFontSmoothing" | "MozOutlineRadiusBottomleft" | "MozOutlineRadiusBottomright" | "MozOutlineRadiusTopleft" | "MozOutlineRadiusTopright" | "MozPaddingEnd" | "MozPaddingStart" | "MozPerspective" | "MozPerspectiveOrigin" | "MozStackSizing" | "MozTabSize" | "MozTextBlink" | "MozTextSizeAdjust" | "MozTransform" | "MozTransformOrigin" | "MozTransformStyle" | "MozUserModify" | "MozUserSelect" | "MozWindowDragging" | "MozWindowShadow" | "msAccelerator" | "msBlockProgression" | "msContentZoomChaining" | "msContentZoomLimitMax" | "msContentZoomLimitMin" | "msContentZoomSnapPoints" | "msContentZoomSnapType" | "msContentZooming" | "msFilter" | "msFlexDirection" | "msFlexPositive" | "msFlowFrom" | "msFlowInto" | "msGridColumns" | "msGridRows" | "msHighContrastAdjust" | "msHyphenateLimitChars" | "msHyphenateLimitLines" | "msHyphenateLimitZone" | "msHyphens" | "msImeAlign" | "msLineBreak" | "msOrder" | "msOverflowStyle" | "msOverflowX" | "msOverflowY" | "msScrollChaining" | "msScrollLimitXMax" | "msScrollLimitXMin" | "msScrollLimitYMax" | "msScrollLimitYMin" | "msScrollRails" | "msScrollSnapPointsX" | "msScrollSnapPointsY" | "msScrollSnapType" | "msScrollTranslation" | "msScrollbar3dlightColor" | "msScrollbarArrowColor" | "msScrollbarBaseColor" | "msScrollbarDarkshadowColor" | "msScrollbarFaceColor" | "msScrollbarHighlightColor" | "msScrollbarShadowColor" | "msScrollbarTrackColor" | "msTextAutospace" | "msTextCombineHorizontal" | "msTextOverflow" | "msTouchAction" | "msTouchSelect" | "msTransform" | "msTransformOrigin" | "msTransitionDelay" | "msTransitionDuration" | "msTransitionProperty" | "msTransitionTimingFunction" | "msUserSelect" | "msWordBreak" | "msWrapFlow" | "msWrapMargin" | "msWrapThrough" | "msWritingMode" | "WebkitAlignContent" | "WebkitAlignItems" | "WebkitAlignSelf" | "WebkitAnimationDelay" | "WebkitAnimationDirection" | "WebkitAnimationDuration" | "WebkitAnimationFillMode" | "WebkitAnimationIterationCount" | "WebkitAnimationName" | "WebkitAnimationPlayState" | "WebkitAnimationTimingFunction" | "WebkitAppearance" | "WebkitBackdropFilter" | "WebkitBackfaceVisibility" | "WebkitBackgroundClip" | "WebkitBackgroundOrigin" | "WebkitBackgroundSize" | "WebkitBorderBeforeColor" | "WebkitBorderBeforeStyle" | "WebkitBorderBeforeWidth" | "WebkitBorderBottomLeftRadius" | "WebkitBorderBottomRightRadius" | "WebkitBorderImageSlice" | "WebkitBorderTopLeftRadius" | "WebkitBorderTopRightRadius" | "WebkitBoxDecorationBreak" | "WebkitBoxReflect" | "WebkitBoxShadow" | "WebkitBoxSizing" | "WebkitClipPath" | "WebkitColumnCount" | "WebkitColumnFill" | "WebkitColumnRuleColor" | "WebkitColumnRuleStyle" | "WebkitColumnRuleWidth" | "WebkitColumnSpan" | "WebkitColumnWidth" | "WebkitFilter" | "WebkitFlexBasis" | "WebkitFlexDirection" | "WebkitFlexGrow" | "WebkitFlexShrink" | "WebkitFlexWrap" | "WebkitFontFeatureSettings" | "WebkitFontKerning" | "WebkitFontSmoothing" | "WebkitFontVariantLigatures" | "WebkitHyphenateCharacter" | "WebkitHyphens" | "WebkitInitialLetter" | "WebkitJustifyContent" | "WebkitLineBreak" | "WebkitLineClamp" | "WebkitLogicalHeight" | "WebkitLogicalWidth" | "WebkitMarginEnd" | "WebkitMarginStart" | "WebkitMaskAttachment" | "WebkitMaskBoxImageOutset" | "WebkitMaskBoxImageRepeat" | "WebkitMaskBoxImageSlice" | "WebkitMaskBoxImageSource" | "WebkitMaskBoxImageWidth" | "WebkitMaskClip" | "WebkitMaskComposite" | "WebkitMaskImage" | "WebkitMaskOrigin" | "WebkitMaskPosition" | "WebkitMaskPositionX" | "WebkitMaskPositionY" | "WebkitMaskRepeat" | "WebkitMaskRepeatX" | "WebkitMaskRepeatY" | "WebkitMaskSize" | "WebkitMaxInlineSize" | "WebkitOrder" | "WebkitOverflowScrolling" | "WebkitPaddingEnd" | "WebkitPaddingStart" | "WebkitPerspective" | "WebkitPerspectiveOrigin" | "WebkitPrintColorAdjust" | "WebkitRubyPosition" | "WebkitScrollSnapType" | "WebkitShapeMargin" | "WebkitTapHighlightColor" | "WebkitTextCombine" | "WebkitTextDecorationColor" | "WebkitTextDecorationLine" | "WebkitTextDecorationSkip" | "WebkitTextDecorationStyle" | "WebkitTextEmphasisColor" | "WebkitTextEmphasisPosition" | "WebkitTextEmphasisStyle" | "WebkitTextFillColor" | "WebkitTextOrientation" | "WebkitTextSizeAdjust" | "WebkitTextStrokeColor" | "WebkitTextStrokeWidth" | "WebkitTextUnderlinePosition" | "WebkitTouchCallout" | "WebkitTransform" | "WebkitTransformOrigin" | "WebkitTransformStyle" | "WebkitTransitionDelay" | "WebkitTransitionDuration" | "WebkitTransitionProperty" | "WebkitTransitionTimingFunction" | "WebkitUserModify" | "WebkitUserSelect" | "WebkitWritingMode" | "MozAnimation" | "MozBorderImage" | "MozColumnRule" | "MozColumns" | "MozOutlineRadius" | "MozTransition" | "msContentZoomLimit" | "msContentZoomSnap" | "msFlex" | "msScrollLimit" | "msScrollSnapX" | "msScrollSnapY" | "msTransition" | "WebkitAnimation" | "WebkitBorderBefore" | "WebkitBorderImage" | "WebkitBorderRadius" | "WebkitColumnRule" | "WebkitColumns" | "WebkitFlex" | "WebkitFlexFlow" | "WebkitMask" | "WebkitMaskBoxImage" | "WebkitTextEmphasis" | "WebkitTextStroke" | "WebkitTransition" | "boxAlign" | "boxDirection" | "boxFlex" | "boxFlexGroup" | "boxLines" | "boxOrdinalGroup" | "boxOrient" | "boxPack" | "clip" | "fontStretch" | "gridColumnGap" | "gridGap" | "gridRowGap" | "imeMode" | "insetArea" | "offsetBlock" | "offsetBlockEnd" | "offsetBlockStart" | "offsetInline" | "offsetInlineEnd" | "offsetInlineStart" | "pageBreakAfter" | "pageBreakBefore" | "pageBreakInside" | "positionTryOptions" | "scrollSnapCoordinate" | "scrollSnapDestination" | "scrollSnapPointsX" | "scrollSnapPointsY" | "scrollSnapTypeX" | "scrollSnapTypeY" | "KhtmlBoxAlign" | "KhtmlBoxDirection" | "KhtmlBoxFlex" | "KhtmlBoxFlexGroup" | "KhtmlBoxLines" | "KhtmlBoxOrdinalGroup" | "KhtmlBoxOrient" | "KhtmlBoxPack" | "KhtmlLineBreak" | "KhtmlOpacity" | "KhtmlUserSelect" | "MozBackgroundClip" | "MozBackgroundOrigin" | "MozBackgroundSize" | "MozBorderRadius" | "MozBorderRadiusBottomleft" | "MozBorderRadiusBottomright" | "MozBorderRadiusTopleft" | "MozBorderRadiusTopright" | "MozBoxAlign" | "MozBoxDirection" | "MozBoxFlex" | "MozBoxOrdinalGroup" | "MozBoxOrient" | "MozBoxPack" | "MozBoxShadow" | "MozColumnCount" | "MozColumnFill" | "MozFloatEdge" | "MozForceBrokenImageIcon" | "MozOpacity" | "MozOutline" | "MozOutlineColor" | "MozOutlineStyle" | "MozOutlineWidth" | "MozTextAlignLast" | "MozTextDecorationColor" | "MozTextDecorationLine" | "MozTextDecorationStyle" | "MozTransitionDelay" | "MozTransitionDuration" | "MozTransitionProperty" | "MozTransitionTimingFunction" | "MozUserFocus" | "MozUserInput" | "msImeMode" | "OAnimation" | "OAnimationDelay" | "OAnimationDirection" | "OAnimationDuration" | "OAnimationFillMode" | "OAnimationIterationCount" | "OAnimationName" | "OAnimationPlayState" | "OAnimationTimingFunction" | "OBackgroundSize" | "OBorderImage" | "OObjectFit" | "OObjectPosition" | "OTabSize" | "OTextOverflow" | "OTransform" | "OTransformOrigin" | "OTransition" | "OTransitionDelay" | "OTransitionDuration" | "OTransitionProperty" | "OTransitionTimingFunction" | "WebkitBoxAlign" | "WebkitBoxDirection" | "WebkitBoxFlex" | "WebkitBoxFlexGroup" | "WebkitBoxLines" | "WebkitBoxOrdinalGroup" | "WebkitBoxOrient" | "WebkitBoxPack" | "colorInterpolation" | "colorRendering" | "glyphOrientationVertical" | "svgFill" | "boldFontWeight" | "@keyframes" | "@properties" | "@fontFace" | "@counterStyle" | "recipe" | "element" | "styles" | "breakpoints" | "block" | "inline" | "isHidden" | "isDisabled" | "theme" | "tokens" | "ref"> & RefAttributes<unknown>> & SubElementComponents<Record<string, never>>;
132
132
  //#endregion
133
133
  export { AllBasePropsWithMods, Element, ElementsDefinition, ModPropDef, ModPropsInput, ResolveModPropDef, ResolveModProps, ResolveTokenProps, SubElementDefinition, SubElementProps, TastyElementOptions, TastyElementProps, TastyProps, TokenPropsInput, VariantMap, WithVariant, tasty };
134
134
  //# sourceMappingURL=tasty.d.ts.map
package/dist/tasty.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { isSelector } from "./pipeline/index.js";
2
2
  import { BASE_STYLES } from "./styles/list.js";
3
+ import { touch } from "./injector/index.js";
3
4
  import { hasKeys } from "./utils/has-keys.js";
4
5
  import { mergeStyles } from "./utils/merge-styles.js";
5
6
  import { computeStyles } from "./compute-styles.js";
@@ -176,8 +177,10 @@ function tastyElement(tastyOptions) {
176
177
  const allStyles = hasInstanceStyles || hasPropStyles ? mergeStyles(baseStyles, styles, propStyles) : baseStyles;
177
178
  const useFactoryCache = typeof document !== "undefined";
178
179
  let stylesResult;
179
- if (useFactoryCache && allStyles === baseStyles && classNameCache.has(allStyles)) stylesResult = { className: classNameCache.get(allStyles) };
180
- else {
180
+ if (useFactoryCache && allStyles === baseStyles && classNameCache.has(allStyles)) {
181
+ stylesResult = { className: classNameCache.get(allStyles) };
182
+ touch(stylesResult.className);
183
+ } else {
181
184
  stylesResult = computeStyles(allStyles);
182
185
  if (useFactoryCache && allStyles === baseStyles) classNameCache.set(allStyles, stylesResult.className);
183
186
  }
package/dist/tasty.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tasty.js","names":["modAttrs"],"sources":["../src/tasty.tsx"],"sourcesContent":["import type {\n AllHTMLAttributes,\n ComponentType,\n ForwardRefExoticComponent,\n JSX,\n PropsWithoutRef,\n RefAttributes,\n} from 'react';\nimport { createElement, forwardRef, Fragment } from 'react';\nimport type { ComputeStylesResult } from './compute-styles';\nimport { computeStyles } from './compute-styles';\nimport { BASE_STYLES } from './styles/list';\nimport type { Styles, StylesInterface } from './styles/types';\nimport type {\n AllBaseProps,\n BaseProps,\n BaseStyleProps,\n ModValue,\n Mods,\n Props,\n TokenValue,\n Tokens,\n} from './types';\nimport { getDisplayName } from './utils/get-display-name';\nimport { isValidElementType } from './utils/is-valid-element-type';\nimport { mergeStyles } from './utils/merge-styles';\nimport { isSelector } from './pipeline';\nimport { hasKeys } from './utils/has-keys';\nimport { modAttrs } from './utils/mod-attrs';\nimport { processTokens } from './utils/process-tokens';\n\nimport type { StyleValue, StyleValueStateMap } from './utils/styles';\n\n/**\n * Mapping of is* properties to their corresponding HTML attributes\n */\nconst IS_PROPERTIES_MAP = {\n isDisabled: 'disabled',\n isHidden: 'hidden',\n isChecked: 'checked',\n} as const;\n\n/**\n * Precalculated entries for performance optimization\n */\nconst IS_PROPERTIES_ENTRIES = Object.entries(IS_PROPERTIES_MAP);\n\n/**\n * Helper function to handle is* properties consistently\n * Transforms is* props to HTML attributes and adds corresponding data-* attributes\n */\nfunction handleIsProperties(props: Record<string, unknown>) {\n for (const [isProperty, targetAttribute] of IS_PROPERTIES_ENTRIES) {\n if (isProperty in props) {\n props[targetAttribute] = props[isProperty];\n delete props[isProperty];\n }\n\n // Add data-* attribute if target attribute is truthy and doesn't already exist\n const dataAttribute = `data-${targetAttribute}`;\n if (!(dataAttribute in props) && props[targetAttribute]) {\n props[dataAttribute] = '';\n }\n }\n}\n\n/**\n * Creates a sub-element component for compound component patterns.\n * Sub-elements are lightweight components with data-element attribute for CSS targeting.\n */\nfunction createSubElement<Tag extends keyof JSX.IntrinsicElements>(\n elementName: string,\n definition: SubElementDefinition<Tag>,\n): ForwardRefExoticComponent<\n PropsWithoutRef<SubElementProps<Tag>> & RefAttributes<unknown>\n> {\n // Normalize definition to object form\n const config =\n typeof definition === 'string'\n ? { as: definition as Tag }\n : (definition as { as?: Tag; qa?: string; qaVal?: string | number });\n\n const tag = config.as ?? ('div' as Tag);\n const defaultQa = config.qa;\n const defaultQaVal = config.qaVal;\n\n const SubElement = forwardRef<unknown, SubElementProps<Tag>>((props, ref) => {\n const {\n qa,\n qaVal,\n mods,\n tokens,\n isDisabled,\n isHidden,\n isChecked,\n className,\n style,\n ...htmlProps\n } = props as SubElementProps<Tag> & {\n className?: string;\n style?: Record<string, unknown>;\n };\n\n // Build mod attributes\n let modDataAttrs: Record<string, unknown> | undefined;\n if (mods) {\n modDataAttrs = modAttrs(mods as Mods) as Record<string, unknown>;\n }\n\n // Process tokens into inline style properties\n const tokenStyle = tokens\n ? (processTokens(tokens) as Record<string, unknown>)\n : undefined;\n\n // Merge token styles with explicit style prop (style has priority)\n let mergedStyle: Record<string, unknown> | undefined;\n if (tokenStyle || style) {\n mergedStyle =\n tokenStyle && style\n ? { ...tokenStyle, ...style }\n : ((tokenStyle ?? style) as Record<string, unknown>);\n }\n\n const elementProps = {\n 'data-element': elementName,\n 'data-qa': qa ?? defaultQa,\n 'data-qaval': qaVal ?? defaultQaVal,\n ...(modDataAttrs || {}),\n ...htmlProps,\n className,\n style: mergedStyle,\n isDisabled,\n isHidden,\n isChecked,\n ref,\n } as Record<string, unknown>;\n\n // Handle is* properties (isDisabled -> disabled + data-disabled, etc.)\n handleIsProperties(elementProps);\n\n // Clean up undefined data attributes\n if (elementProps['data-qa'] === undefined) delete elementProps['data-qa'];\n if (elementProps['data-qaval'] === undefined)\n delete elementProps['data-qaval'];\n\n return createElement(tag, elementProps);\n });\n\n SubElement.displayName = `SubElement(${elementName})`;\n\n return SubElement as ForwardRefExoticComponent<\n PropsWithoutRef<SubElementProps<Tag>> & RefAttributes<unknown>\n >;\n}\n\ntype StyleList = readonly (keyof {\n [key in keyof StylesInterface]: StylesInterface[key];\n})[];\n\n// ============================================================================\n// Mod props types — expose modifier keys as top-level component props\n// ============================================================================\n\n/** Type descriptor for a single mod prop: a JS constructor or an enum array. */\nexport type ModPropDef =\n | BooleanConstructor\n | StringConstructor\n | NumberConstructor\n | readonly string[];\n\n/** Array form: list of mod key names (types default to ModValue). */\ntype ModPropsList = readonly string[];\n\n/** Object form: map of mod key names to type descriptors. */\ntype ModPropsMap = Readonly<Record<string, ModPropDef>>;\n\n/** Either array or object form accepted by `modProps` option. */\nexport type ModPropsInput = ModPropsList | ModPropsMap;\n\n/** Resolve a single ModPropDef to its TypeScript type. */\nexport type ResolveModPropDef<T> = T extends BooleanConstructor\n ? boolean\n : T extends StringConstructor\n ? string\n : T extends NumberConstructor\n ? number\n : T extends readonly (infer U)[]\n ? U\n : ModValue;\n\n/** Resolve an entire `modProps` definition to the component prop types it adds. */\nexport type ResolveModProps<M extends ModPropsInput> =\n M extends readonly (infer K)[]\n ? Partial<Record<K & string, ModValue>>\n : M extends Record<string, ModPropDef>\n ? { [key in keyof M & string]?: ResolveModPropDef<M[key]> }\n : // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {};\n\n// ============================================================================\n// Token props types — expose token keys as top-level component props\n// ============================================================================\n\n/** A token key with `$` or `#` prefix. */\ntype TokenPropKey = `$${string}` | `#${string}`;\n\n/** Array form: list of prop names. Names ending in `Color` map to `#` color tokens. */\ntype TokenPropsList = readonly string[];\n\n/** Object form: prop name -> token key with explicit `$`/`#` prefix. */\ntype TokenPropsMap = Readonly<Record<string, TokenPropKey>>;\n\n/** Either array or object form accepted by `tokenProps` option. */\nexport type TokenPropsInput = TokenPropsList | TokenPropsMap;\n\n/** Resolve a `tokenProps` definition to the component prop types it adds. */\nexport type ResolveTokenProps<TP extends TokenPropsInput> =\n TP extends readonly (infer K)[]\n ? Partial<Record<K & string, TokenValue>>\n : TP extends Record<string, TokenPropKey>\n ? Partial<Record<keyof TP & string, TokenValue>>\n : // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {};\n\n/**\n * Pre-compute the mapping from prop name to token key at component-creation time.\n * Array form: `'progress'` -> `'$progress'`, `'accentColor'` -> `'#accent'`.\n * Object form: entries used as-is.\n */\nfunction buildTokenPropsMapping(\n def: TokenPropsInput,\n): [propName: string, tokenKey: string][] {\n if (Array.isArray(def)) {\n return (def as string[]).map((propName) => {\n if (propName.endsWith('Color') && propName.length > 5) {\n return [propName, `#${propName.slice(0, -5)}`];\n }\n return [propName, `$${propName}`];\n });\n }\n return Object.entries(def);\n}\n\nexport type PropsWithStyles = {\n styles?: Styles;\n} & Omit<Props, 'styles'>;\n\nexport type VariantMap = Record<string, Styles>;\n\nexport interface WithVariant<V extends VariantMap> {\n variant?: keyof V;\n}\n\n// ============================================================================\n// Sub-element types for compound components\n// ============================================================================\n\n/**\n * Definition for a sub-element. Can be either:\n * - A tag name string (e.g., 'div', 'span')\n * - An object with configuration options\n */\nexport type SubElementDefinition<\n Tag extends keyof JSX.IntrinsicElements = 'div',\n> =\n | Tag\n | {\n as?: Tag;\n qa?: string;\n qaVal?: string | number;\n };\n\n/**\n * Map of sub-element definitions.\n * Keys become the sub-component names (e.g., { Icon: 'span' } -> Component.Icon)\n */\nexport type ElementsDefinition = Record<\n string,\n SubElementDefinition<keyof JSX.IntrinsicElements>\n>;\n\n/**\n * Resolves the tag from a SubElementDefinition\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ResolveElementTag<T extends SubElementDefinition<any>> = T extends string\n ? T\n : T extends { as?: infer Tag }\n ? Tag extends keyof JSX.IntrinsicElements\n ? Tag\n : 'div'\n : 'div';\n\n/**\n * Props for sub-element components.\n * Combines HTML attributes with tasty-specific props (qa, qaVal, mods, tokens, isDisabled, etc.)\n */\nexport type SubElementProps<Tag extends keyof JSX.IntrinsicElements = 'div'> =\n Omit<\n JSX.IntrinsicElements[Tag],\n 'ref' | 'color' | 'content' | 'translate'\n > & {\n qa?: string;\n qaVal?: string | number;\n mods?: Mods;\n tokens?: Tokens;\n isDisabled?: boolean;\n isHidden?: boolean;\n isChecked?: boolean;\n };\n\n/**\n * Generates the sub-element component types from an ElementsDefinition\n */\ntype SubElementComponents<E extends ElementsDefinition> = {\n [K in keyof E]: ForwardRefExoticComponent<\n PropsWithoutRef<SubElementProps<ResolveElementTag<E[K]>>> &\n RefAttributes<\n ResolveElementTag<E[K]> extends keyof HTMLElementTagNameMap\n ? HTMLElementTagNameMap[ResolveElementTag<E[K]>]\n : Element\n >\n >;\n};\n\n/**\n * Base type containing common properties shared between TastyProps and TastyElementOptions.\n * Separated to avoid code duplication while allowing different type constraints.\n */\ntype TastyBaseProps<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = {\n /** Default styles of the element. */\n styles?: Styles;\n /** The list of styles that can be provided by props */\n styleProps?: K;\n /** Modifier keys exposed as top-level component props (array or typed object form). */\n modProps?: M;\n /** Token keys exposed as top-level component props (array or typed object form). */\n tokenProps?: TP;\n element?: BaseProps['element'];\n variants?: V;\n /** Default tokens for inline CSS custom properties */\n tokens?: Tokens;\n /** Sub-element definitions for compound components */\n elements?: E;\n} & Pick<BaseProps, 'qa' | 'qaVal'> &\n WithVariant<V>;\n\nexport type TastyProps<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n DefaultProps = Props,\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = TastyBaseProps<K, V, E, M, TP> & {\n /** The tag name of the element or a React component. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n as?: string | ComponentType<any>;\n} & Partial<\n Omit<\n DefaultProps,\n 'as' | 'styles' | 'styleProps' | 'modProps' | 'tokenProps' | 'tokens'\n >\n >;\n\n/**\n * TastyElementOptions is used for the element-creation overload of tasty().\n * It includes a Tag generic that allows TypeScript to infer the correct\n * HTML element type from the `as` prop.\n *\n * Note: Uses a separate index signature with `unknown` instead of inheriting\n * from Props (which has `any`) to ensure strict type checking for styles.\n */\nexport type TastyElementOptions<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n Tag extends keyof JSX.IntrinsicElements = 'div',\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = TastyBaseProps<K, V, E, M, TP> & {\n /** The tag name of the element or a React component. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n as?: Tag | ComponentType<any>;\n} & Record<string, unknown>;\n\nexport type AllBasePropsWithMods<\n K extends StyleList,\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = AllBaseProps & {\n [key in K[number]]?:\n | StyleValue<StylesInterface[key]>\n | StyleValueStateMap<StylesInterface[key]>;\n} & BaseStyleProps &\n ResolveModProps<M> &\n ResolveTokenProps<TP>;\n\n/**\n * Keys from BasePropsWithoutChildren that should be omitted from HTML attributes.\n * This excludes event handlers so they can be properly typed from JSX.IntrinsicElements.\n */\ntype TastySpecificKeys =\n | 'as'\n | 'qa'\n | 'qaVal'\n | 'element'\n | 'styles'\n | 'breakpoints'\n | 'block'\n | 'inline'\n | 'mods'\n | 'isHidden'\n | 'isDisabled'\n | 'css'\n | 'style'\n | 'theme'\n | 'tokens'\n | 'ref'\n | 'color';\n\n/** Extract prop key names from a ModPropsInput (array elements or object keys). */\ntype ModPropsKeys<M extends ModPropsInput> = M extends readonly (infer K)[]\n ? K & string\n : keyof M & string;\n\n/** Extract prop key names from a TokenPropsInput (array elements or object keys). */\ntype TokenPropsKeys<TP extends TokenPropsInput> =\n TP extends readonly (infer K)[] ? K & string : keyof TP & string;\n\n/**\n * Props type for tasty elements that combines:\n * - AllBasePropsWithMods for style props with strict tokens type\n * - HTML attributes for flexibility (properly typed based on tag)\n * - Variant support\n *\n * AllBasePropsWithMods carries generic AllHTMLAttributes which can conflict\n * with tag-specific types from JSX.IntrinsicElements (e.g. `src` is `string`\n * in AllHTMLAttributes but `string | Blob` in ImgHTMLAttributes). To avoid\n * intersection-narrowing, we Omit tag-specific keys from AllBasePropsWithMods\n * (keeping TastySpecificKeys, style props, mod props, and token props) and let\n * JSX.IntrinsicElements supply the authoritative HTML attribute types.\n */\nexport type TastyElementProps<\n K extends StyleList,\n V extends VariantMap,\n Tag extends keyof JSX.IntrinsicElements = 'div',\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = Omit<\n AllBasePropsWithMods<K, M, TP>,\n Exclude<\n keyof JSX.IntrinsicElements[Tag],\n TastySpecificKeys | K[number] | ModPropsKeys<M> | TokenPropsKeys<TP>\n >\n> &\n WithVariant<V> &\n Omit<\n Omit<AllHTMLAttributes<HTMLElement>, keyof JSX.IntrinsicElements[Tag]> &\n JSX.IntrinsicElements[Tag],\n TastySpecificKeys | K[number] | ModPropsKeys<M> | TokenPropsKeys<TP>\n >;\n\ntype TastyComponentPropsWithDefaults<\n Props extends PropsWithStyles,\n DefaultProps extends Partial<Props>,\n> = keyof DefaultProps extends never\n ? Props\n : {\n [key in Extract<keyof Props, keyof DefaultProps>]?: Props[key];\n } & {\n [key in keyof Omit<Props, keyof DefaultProps>]: Props[key];\n };\n\nexport function tasty<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n Tag extends keyof JSX.IntrinsicElements = 'div',\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n>(\n options: TastyElementOptions<K, V, E, Tag, M, TP>,\n secondArg?: never,\n): ForwardRefExoticComponent<\n PropsWithoutRef<TastyElementProps<K, V, Tag, M, TP>> & RefAttributes<unknown>\n> &\n SubElementComponents<E>;\nexport function tasty<\n Props extends PropsWithStyles,\n DefaultProps extends Partial<Props> = Partial<Props>,\n>(\n Component: ComponentType<Props>,\n options?: TastyProps<never, never, Record<string, never>, Props>,\n): ComponentType<TastyComponentPropsWithDefaults<Props, DefaultProps>>;\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n// Implementation\nexport function tasty<\n K extends StyleList,\n V extends VariantMap,\n _C = Record<string, unknown>,\n>(Component: any, options?: any) {\n if (isValidElementType(Component)) {\n return tastyWrap(Component as ComponentType<any>, options);\n }\n\n return tastyElement(Component as TastyProps<K, V>);\n}\n\nfunction tastyWrap<\n P extends PropsWithStyles,\n DefaultProps extends Partial<P> = Partial<P>,\n>(\n Component: ComponentType<P>,\n options?: TastyProps<never, never, P>,\n): ComponentType<TastyComponentPropsWithDefaults<P, DefaultProps>> {\n const {\n as: extendTag,\n element: extendElement,\n ...defaultProps\n } = (options ?? {}) as TastyProps<never, never, P>;\n\n const propsWithStyles = ['styles'].concat(\n Object.keys(defaultProps).filter((prop) => prop.endsWith('Styles')),\n );\n\n const _WrappedComponent = forwardRef<any, any>((props, ref) => {\n const { as, element, ...restProps } = props as Record<string, unknown>;\n\n const mergedStylesMap = propsWithStyles.reduce(\n (map, prop) => {\n const restValue = (restProps as any)[prop];\n const defaultValue = (defaultProps as any)[prop];\n\n if (restValue != null && defaultValue != null) {\n (map as any)[prop] = mergeStyles(defaultValue, restValue);\n } else {\n (map as any)[prop] = restValue ?? defaultValue;\n }\n\n return map;\n },\n {} as Record<string, unknown>,\n );\n\n const elementProps = {\n ...(defaultProps as unknown as Record<string, unknown>),\n ...(restProps as unknown as Record<string, unknown>),\n ...mergedStylesMap,\n as: (as as string | undefined) ?? extendTag,\n element: (element as string | undefined) || extendElement,\n ref,\n } as unknown as P;\n\n return createElement(Component as ComponentType<P>, elementProps);\n });\n\n _WrappedComponent.displayName = `TastyWrappedComponent(${getDisplayName(\n Component,\n (defaultProps as any).qa ?? (extendTag as any) ?? 'Anonymous',\n )})`;\n\n return _WrappedComponent as unknown as ComponentType<\n TastyComponentPropsWithDefaults<P, DefaultProps>\n >;\n}\n\nfunction tastyElement<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition,\n>(tastyOptions: TastyProps<K, V, E>) {\n const {\n as: originalAs = 'div',\n element: defaultElement,\n styles: defaultStyles,\n styleProps,\n modProps: modPropsDef,\n tokenProps: tokenPropsDef,\n variants,\n tokens: defaultTokens,\n elements,\n ...defaultProps\n } = tastyOptions;\n\n // Pre-compute merged styles for each variant (if variants are defined)\n // This avoids creating separate component instances per variant\n let variantStylesMap: Record<string, Styles | undefined> | undefined;\n if (variants) {\n // Split defaultStyles: extend-mode state maps (no '' key, non-selector)\n // are pulled out and applied AFTER variant merge so they survive\n // replace-mode maps in variants.\n let baseStyles = defaultStyles;\n let extensionStyles: Styles | undefined;\n\n if (defaultStyles) {\n for (const key of Object.keys(defaultStyles)) {\n if (isSelector(key)) continue;\n\n const value = (defaultStyles as Record<string, unknown>)[key];\n\n if (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n !('' in value)\n ) {\n if (!extensionStyles) {\n baseStyles = { ...defaultStyles } as Styles;\n extensionStyles = {} as Styles;\n }\n (extensionStyles as Record<string, unknown>)[key] = value;\n delete (baseStyles as Record<string, unknown>)[key];\n }\n }\n }\n\n const variantEntries = Object.entries(variants) as [string, Styles][];\n variantStylesMap = variantEntries.reduce(\n (map, [variant, variantStyles]) => {\n map[variant] = extensionStyles\n ? mergeStyles(baseStyles, variantStyles, extensionStyles)\n : mergeStyles(baseStyles, variantStyles);\n return map;\n },\n {} as Record<string, Styles | undefined>,\n );\n // Ensure 'default' variant always exists\n if (!variantStylesMap['default']) {\n variantStylesMap['default'] = defaultStyles;\n }\n }\n\n const {\n qa: defaultQa,\n qaVal: defaultQaVal,\n ...otherDefaultProps\n } = defaultProps ?? {};\n\n const propsToCheck = styleProps\n ? (styleProps as StyleList).concat(BASE_STYLES)\n : BASE_STYLES;\n\n const modPropsKeys: string[] | undefined = modPropsDef\n ? ((Array.isArray(modPropsDef)\n ? modPropsDef\n : Object.keys(modPropsDef)) as string[])\n : undefined;\n\n const tokenPropsMapping: [string, string][] | undefined = tokenPropsDef\n ? buildTokenPropsMapping(tokenPropsDef as TokenPropsInput)\n : undefined;\n\n // Factory-level cache: maps stable style references to computed classNames.\n // For the common case (no instance overrides), this avoids recomputation.\n const classNameCache = new Map<Styles | undefined, string>();\n\n const _TastyComponent = forwardRef<\n unknown,\n AllBasePropsWithMods<K> & WithVariant<V>\n >((allProps, ref) => {\n const {\n as,\n styles: rawStyles,\n variant,\n mods,\n element,\n qa,\n qaVal,\n className: userClassName,\n tokens,\n style,\n ...otherProps\n } = allProps as Record<string, unknown> as AllBasePropsWithMods<K> &\n WithVariant<V> & {\n className?: string;\n tokens?: Tokens;\n style?: Record<string, unknown>;\n };\n\n let styles = rawStyles;\n\n let propStyles: Styles | null = null;\n\n for (const prop of propsToCheck) {\n const key = prop as unknown as string;\n\n if (key in otherProps) {\n if (!propStyles) propStyles = {};\n const value = (otherProps as any)[key];\n (propStyles as any)[key] = value;\n delete (otherProps as any)[key];\n }\n }\n\n if (!styles || (styles && !hasKeys(styles as Record<string, unknown>))) {\n styles = undefined as unknown as Styles;\n }\n\n let propMods: Record<string, ModValue> | undefined;\n if (modPropsKeys) {\n for (const key of modPropsKeys) {\n if (key in otherProps) {\n if (!propMods) propMods = {};\n propMods[key] = (otherProps as Record<string, unknown>)[\n key\n ] as ModValue;\n delete (otherProps as Record<string, unknown>)[key];\n }\n }\n }\n\n let propTokens: Tokens | undefined;\n if (tokenPropsMapping) {\n for (const [propName, tokenKey] of tokenPropsMapping) {\n if (propName in otherProps) {\n if (!propTokens) propTokens = {} as Tokens;\n (propTokens as Record<string, TokenValue>)[tokenKey] = (\n otherProps as Record<string, unknown>\n )[propName] as TokenValue;\n delete (otherProps as Record<string, unknown>)[propName];\n }\n }\n }\n\n const baseStyles = variantStylesMap\n ? (variantStylesMap[(variant as string) || 'default'] ??\n variantStylesMap['default'])\n : defaultStyles;\n\n const hasInstanceStyles =\n styles && hasKeys(styles as Record<string, unknown>);\n const hasPropStyles = propStyles && hasKeys(propStyles);\n\n const allStyles =\n hasInstanceStyles || hasPropStyles\n ? mergeStyles(baseStyles, styles as Styles, propStyles as Styles)\n : baseStyles;\n\n // Use factory-level cache for stable style references (client only).\n // On the server the cache must be skipped: both the SSR collector and\n // the RSC inline-style paths are per-request, so every request must\n // call computeStyles() to ensure CSS is actually collected/emitted.\n const useFactoryCache = typeof document !== 'undefined';\n let stylesResult: ComputeStylesResult;\n if (\n useFactoryCache &&\n allStyles === baseStyles &&\n classNameCache.has(allStyles)\n ) {\n stylesResult = { className: classNameCache.get(allStyles)! };\n } else {\n stylesResult = computeStyles(allStyles);\n if (useFactoryCache && allStyles === baseStyles) {\n classNameCache.set(allStyles, stylesResult.className);\n }\n }\n\n // Merge tokens: default -> instance -> tokenProps\n let mergedTokens: Tokens | undefined;\n if (defaultTokens || tokens || propTokens) {\n if (!defaultTokens && !propTokens) {\n mergedTokens = tokens as Tokens;\n } else if (!tokens && !propTokens) {\n mergedTokens = defaultTokens;\n } else {\n mergedTokens = {\n ...defaultTokens,\n ...(tokens as Tokens),\n ...propTokens,\n } as Tokens;\n }\n }\n\n const processedTokenStyle = processTokens(mergedTokens);\n\n let mergedStyle: Record<string, unknown> | undefined;\n if (processedTokenStyle || style) {\n if (!processedTokenStyle) {\n mergedStyle = style;\n } else if (!style) {\n mergedStyle = processedTokenStyle as Record<string, unknown>;\n } else {\n mergedStyle = {\n ...(processedTokenStyle as Record<string, unknown>),\n ...style,\n };\n }\n }\n\n const mergedMods = propMods\n ? { ...(mods as Record<string, ModValue>), ...propMods }\n : (mods as Record<string, ModValue> | undefined);\n\n let modDataAttrs: Record<string, unknown> | undefined;\n if (mergedMods) {\n modDataAttrs = modAttrs(mergedMods as unknown as Mods) as Record<\n string,\n unknown\n >;\n }\n\n const finalClassName = [\n (userClassName as string) || '',\n stylesResult.className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const elementProps = {\n 'data-element': (element as string | undefined) || defaultElement,\n 'data-qa': (qa as string | undefined) || defaultQa,\n 'data-qaval': (qaVal as string | undefined) || defaultQaVal,\n ...(otherDefaultProps as unknown as Record<string, unknown>),\n ...(modDataAttrs || {}),\n ...(otherProps as unknown as Record<string, unknown>),\n className: finalClassName,\n style: mergedStyle,\n ref,\n } as Record<string, unknown>;\n\n handleIsProperties(elementProps);\n\n const el = createElement(\n (as as string | 'div') ?? originalAs,\n elementProps,\n );\n\n // RSC mode: wrap element with inline <style> for server-rendered CSS\n if (stylesResult.css) {\n return createElement(\n Fragment,\n null,\n createElement('style', {\n 'data-tasty-rsc': '',\n dangerouslySetInnerHTML: { __html: stylesResult.css },\n }),\n el,\n );\n }\n\n return el;\n });\n\n _TastyComponent.displayName = `TastyComponent(${\n (defaultProps as any).qa || originalAs\n })`;\n\n // Attach sub-element components if elements are defined\n if (elements) {\n const subElements = Object.entries(elements).reduce(\n (acc, [name, definition]) => {\n acc[name] = createSubElement(\n name,\n definition as SubElementDefinition<keyof JSX.IntrinsicElements>,\n );\n return acc;\n },\n {} as Record<string, ForwardRefExoticComponent<any>>,\n );\n\n return Object.assign(_TastyComponent, subElements);\n }\n\n return _TastyComponent;\n}\n\nexport const Element = tasty({});\n"],"mappings":"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"}
1
+ {"version":3,"file":"tasty.js","names":["modAttrs"],"sources":["../src/tasty.tsx"],"sourcesContent":["import type {\n AllHTMLAttributes,\n ComponentType,\n ForwardRefExoticComponent,\n JSX,\n PropsWithoutRef,\n RefAttributes,\n} from 'react';\nimport { createElement, forwardRef, Fragment } from 'react';\nimport type { ComputeStylesResult } from './compute-styles';\nimport { computeStyles } from './compute-styles';\nimport { BASE_STYLES } from './styles/list';\nimport type { Styles, StylesInterface } from './styles/types';\nimport type {\n AllBaseProps,\n BaseProps,\n BaseStyleProps,\n ModValue,\n Mods,\n Props,\n TokenValue,\n Tokens,\n} from './types';\nimport { getDisplayName } from './utils/get-display-name';\nimport { isValidElementType } from './utils/is-valid-element-type';\nimport { mergeStyles } from './utils/merge-styles';\nimport { isSelector } from './pipeline';\nimport { hasKeys } from './utils/has-keys';\nimport { modAttrs } from './utils/mod-attrs';\nimport { processTokens } from './utils/process-tokens';\nimport { touch } from './injector';\n\nimport type { StyleValue, StyleValueStateMap } from './utils/styles';\n\n/**\n * Mapping of is* properties to their corresponding HTML attributes\n */\nconst IS_PROPERTIES_MAP = {\n isDisabled: 'disabled',\n isHidden: 'hidden',\n isChecked: 'checked',\n} as const;\n\n/**\n * Precalculated entries for performance optimization\n */\nconst IS_PROPERTIES_ENTRIES = Object.entries(IS_PROPERTIES_MAP);\n\n/**\n * Helper function to handle is* properties consistently\n * Transforms is* props to HTML attributes and adds corresponding data-* attributes\n */\nfunction handleIsProperties(props: Record<string, unknown>) {\n for (const [isProperty, targetAttribute] of IS_PROPERTIES_ENTRIES) {\n if (isProperty in props) {\n props[targetAttribute] = props[isProperty];\n delete props[isProperty];\n }\n\n // Add data-* attribute if target attribute is truthy and doesn't already exist\n const dataAttribute = `data-${targetAttribute}`;\n if (!(dataAttribute in props) && props[targetAttribute]) {\n props[dataAttribute] = '';\n }\n }\n}\n\n/**\n * Creates a sub-element component for compound component patterns.\n * Sub-elements are lightweight components with data-element attribute for CSS targeting.\n */\nfunction createSubElement<Tag extends keyof JSX.IntrinsicElements>(\n elementName: string,\n definition: SubElementDefinition<Tag>,\n): ForwardRefExoticComponent<\n PropsWithoutRef<SubElementProps<Tag>> & RefAttributes<unknown>\n> {\n // Normalize definition to object form\n const config =\n typeof definition === 'string'\n ? { as: definition as Tag }\n : (definition as { as?: Tag; qa?: string; qaVal?: string | number });\n\n const tag = config.as ?? ('div' as Tag);\n const defaultQa = config.qa;\n const defaultQaVal = config.qaVal;\n\n const SubElement = forwardRef<unknown, SubElementProps<Tag>>((props, ref) => {\n const {\n qa,\n qaVal,\n mods,\n tokens,\n isDisabled,\n isHidden,\n isChecked,\n className,\n style,\n ...htmlProps\n } = props as SubElementProps<Tag> & {\n className?: string;\n style?: Record<string, unknown>;\n };\n\n // Build mod attributes\n let modDataAttrs: Record<string, unknown> | undefined;\n if (mods) {\n modDataAttrs = modAttrs(mods as Mods) as Record<string, unknown>;\n }\n\n // Process tokens into inline style properties\n const tokenStyle = tokens\n ? (processTokens(tokens) as Record<string, unknown>)\n : undefined;\n\n // Merge token styles with explicit style prop (style has priority)\n let mergedStyle: Record<string, unknown> | undefined;\n if (tokenStyle || style) {\n mergedStyle =\n tokenStyle && style\n ? { ...tokenStyle, ...style }\n : ((tokenStyle ?? style) as Record<string, unknown>);\n }\n\n const elementProps = {\n 'data-element': elementName,\n 'data-qa': qa ?? defaultQa,\n 'data-qaval': qaVal ?? defaultQaVal,\n ...(modDataAttrs || {}),\n ...htmlProps,\n className,\n style: mergedStyle,\n isDisabled,\n isHidden,\n isChecked,\n ref,\n } as Record<string, unknown>;\n\n // Handle is* properties (isDisabled -> disabled + data-disabled, etc.)\n handleIsProperties(elementProps);\n\n // Clean up undefined data attributes\n if (elementProps['data-qa'] === undefined) delete elementProps['data-qa'];\n if (elementProps['data-qaval'] === undefined)\n delete elementProps['data-qaval'];\n\n return createElement(tag, elementProps);\n });\n\n SubElement.displayName = `SubElement(${elementName})`;\n\n return SubElement as ForwardRefExoticComponent<\n PropsWithoutRef<SubElementProps<Tag>> & RefAttributes<unknown>\n >;\n}\n\ntype StyleList = readonly (keyof {\n [key in keyof StylesInterface]: StylesInterface[key];\n})[];\n\n// ============================================================================\n// Mod props types — expose modifier keys as top-level component props\n// ============================================================================\n\n/** Type descriptor for a single mod prop: a JS constructor or an enum array. */\nexport type ModPropDef =\n | BooleanConstructor\n | StringConstructor\n | NumberConstructor\n | readonly string[];\n\n/** Array form: list of mod key names (types default to ModValue). */\ntype ModPropsList = readonly string[];\n\n/** Object form: map of mod key names to type descriptors. */\ntype ModPropsMap = Readonly<Record<string, ModPropDef>>;\n\n/** Either array or object form accepted by `modProps` option. */\nexport type ModPropsInput = ModPropsList | ModPropsMap;\n\n/** Resolve a single ModPropDef to its TypeScript type. */\nexport type ResolveModPropDef<T> = T extends BooleanConstructor\n ? boolean\n : T extends StringConstructor\n ? string\n : T extends NumberConstructor\n ? number\n : T extends readonly (infer U)[]\n ? U\n : ModValue;\n\n/** Resolve an entire `modProps` definition to the component prop types it adds. */\nexport type ResolveModProps<M extends ModPropsInput> =\n M extends readonly (infer K)[]\n ? Partial<Record<K & string, ModValue>>\n : M extends Record<string, ModPropDef>\n ? { [key in keyof M & string]?: ResolveModPropDef<M[key]> }\n : // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {};\n\n// ============================================================================\n// Token props types — expose token keys as top-level component props\n// ============================================================================\n\n/** A token key with `$` or `#` prefix. */\ntype TokenPropKey = `$${string}` | `#${string}`;\n\n/** Array form: list of prop names. Names ending in `Color` map to `#` color tokens. */\ntype TokenPropsList = readonly string[];\n\n/** Object form: prop name -> token key with explicit `$`/`#` prefix. */\ntype TokenPropsMap = Readonly<Record<string, TokenPropKey>>;\n\n/** Either array or object form accepted by `tokenProps` option. */\nexport type TokenPropsInput = TokenPropsList | TokenPropsMap;\n\n/** Resolve a `tokenProps` definition to the component prop types it adds. */\nexport type ResolveTokenProps<TP extends TokenPropsInput> =\n TP extends readonly (infer K)[]\n ? Partial<Record<K & string, TokenValue>>\n : TP extends Record<string, TokenPropKey>\n ? Partial<Record<keyof TP & string, TokenValue>>\n : // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n {};\n\n/**\n * Pre-compute the mapping from prop name to token key at component-creation time.\n * Array form: `'progress'` -> `'$progress'`, `'accentColor'` -> `'#accent'`.\n * Object form: entries used as-is.\n */\nfunction buildTokenPropsMapping(\n def: TokenPropsInput,\n): [propName: string, tokenKey: string][] {\n if (Array.isArray(def)) {\n return (def as string[]).map((propName) => {\n if (propName.endsWith('Color') && propName.length > 5) {\n return [propName, `#${propName.slice(0, -5)}`];\n }\n return [propName, `$${propName}`];\n });\n }\n return Object.entries(def);\n}\n\nexport type PropsWithStyles = {\n styles?: Styles;\n} & Omit<Props, 'styles'>;\n\nexport type VariantMap = Record<string, Styles>;\n\nexport interface WithVariant<V extends VariantMap> {\n variant?: keyof V;\n}\n\n// ============================================================================\n// Sub-element types for compound components\n// ============================================================================\n\n/**\n * Definition for a sub-element. Can be either:\n * - A tag name string (e.g., 'div', 'span')\n * - An object with configuration options\n */\nexport type SubElementDefinition<\n Tag extends keyof JSX.IntrinsicElements = 'div',\n> =\n | Tag\n | {\n as?: Tag;\n qa?: string;\n qaVal?: string | number;\n };\n\n/**\n * Map of sub-element definitions.\n * Keys become the sub-component names (e.g., { Icon: 'span' } -> Component.Icon)\n */\nexport type ElementsDefinition = Record<\n string,\n SubElementDefinition<keyof JSX.IntrinsicElements>\n>;\n\n/**\n * Resolves the tag from a SubElementDefinition\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ResolveElementTag<T extends SubElementDefinition<any>> = T extends string\n ? T\n : T extends { as?: infer Tag }\n ? Tag extends keyof JSX.IntrinsicElements\n ? Tag\n : 'div'\n : 'div';\n\n/**\n * Props for sub-element components.\n * Combines HTML attributes with tasty-specific props (qa, qaVal, mods, tokens, isDisabled, etc.)\n */\nexport type SubElementProps<Tag extends keyof JSX.IntrinsicElements = 'div'> =\n Omit<\n JSX.IntrinsicElements[Tag],\n 'ref' | 'color' | 'content' | 'translate'\n > & {\n qa?: string;\n qaVal?: string | number;\n mods?: Mods;\n tokens?: Tokens;\n isDisabled?: boolean;\n isHidden?: boolean;\n isChecked?: boolean;\n };\n\n/**\n * Generates the sub-element component types from an ElementsDefinition\n */\ntype SubElementComponents<E extends ElementsDefinition> = {\n [K in keyof E]: ForwardRefExoticComponent<\n PropsWithoutRef<SubElementProps<ResolveElementTag<E[K]>>> &\n RefAttributes<\n ResolveElementTag<E[K]> extends keyof HTMLElementTagNameMap\n ? HTMLElementTagNameMap[ResolveElementTag<E[K]>]\n : Element\n >\n >;\n};\n\n/**\n * Base type containing common properties shared between TastyProps and TastyElementOptions.\n * Separated to avoid code duplication while allowing different type constraints.\n */\ntype TastyBaseProps<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = {\n /** Default styles of the element. */\n styles?: Styles;\n /** The list of styles that can be provided by props */\n styleProps?: K;\n /** Modifier keys exposed as top-level component props (array or typed object form). */\n modProps?: M;\n /** Token keys exposed as top-level component props (array or typed object form). */\n tokenProps?: TP;\n element?: BaseProps['element'];\n variants?: V;\n /** Default tokens for inline CSS custom properties */\n tokens?: Tokens;\n /** Sub-element definitions for compound components */\n elements?: E;\n} & Pick<BaseProps, 'qa' | 'qaVal'> &\n WithVariant<V>;\n\nexport type TastyProps<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n DefaultProps = Props,\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = TastyBaseProps<K, V, E, M, TP> & {\n /** The tag name of the element or a React component. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n as?: string | ComponentType<any>;\n} & Partial<\n Omit<\n DefaultProps,\n 'as' | 'styles' | 'styleProps' | 'modProps' | 'tokenProps' | 'tokens'\n >\n >;\n\n/**\n * TastyElementOptions is used for the element-creation overload of tasty().\n * It includes a Tag generic that allows TypeScript to infer the correct\n * HTML element type from the `as` prop.\n *\n * Note: Uses a separate index signature with `unknown` instead of inheriting\n * from Props (which has `any`) to ensure strict type checking for styles.\n */\nexport type TastyElementOptions<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n Tag extends keyof JSX.IntrinsicElements = 'div',\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = TastyBaseProps<K, V, E, M, TP> & {\n /** The tag name of the element or a React component. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n as?: Tag | ComponentType<any>;\n} & Record<string, unknown>;\n\nexport type AllBasePropsWithMods<\n K extends StyleList,\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = AllBaseProps & {\n [key in K[number]]?:\n | StyleValue<StylesInterface[key]>\n | StyleValueStateMap<StylesInterface[key]>;\n} & BaseStyleProps &\n ResolveModProps<M> &\n ResolveTokenProps<TP>;\n\n/**\n * Keys from BasePropsWithoutChildren that should be omitted from HTML attributes.\n * This excludes event handlers so they can be properly typed from JSX.IntrinsicElements.\n */\ntype TastySpecificKeys =\n | 'as'\n | 'qa'\n | 'qaVal'\n | 'element'\n | 'styles'\n | 'breakpoints'\n | 'block'\n | 'inline'\n | 'mods'\n | 'isHidden'\n | 'isDisabled'\n | 'css'\n | 'style'\n | 'theme'\n | 'tokens'\n | 'ref'\n | 'color';\n\n/** Extract prop key names from a ModPropsInput (array elements or object keys). */\ntype ModPropsKeys<M extends ModPropsInput> = M extends readonly (infer K)[]\n ? K & string\n : keyof M & string;\n\n/** Extract prop key names from a TokenPropsInput (array elements or object keys). */\ntype TokenPropsKeys<TP extends TokenPropsInput> =\n TP extends readonly (infer K)[] ? K & string : keyof TP & string;\n\n/**\n * Props type for tasty elements that combines:\n * - AllBasePropsWithMods for style props with strict tokens type\n * - HTML attributes for flexibility (properly typed based on tag)\n * - Variant support\n *\n * AllBasePropsWithMods carries generic AllHTMLAttributes which can conflict\n * with tag-specific types from JSX.IntrinsicElements (e.g. `src` is `string`\n * in AllHTMLAttributes but `string | Blob` in ImgHTMLAttributes). To avoid\n * intersection-narrowing, we Omit tag-specific keys from AllBasePropsWithMods\n * (keeping TastySpecificKeys, style props, mod props, and token props) and let\n * JSX.IntrinsicElements supply the authoritative HTML attribute types.\n */\nexport type TastyElementProps<\n K extends StyleList,\n V extends VariantMap,\n Tag extends keyof JSX.IntrinsicElements = 'div',\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n> = Omit<\n AllBasePropsWithMods<K, M, TP>,\n Exclude<\n keyof JSX.IntrinsicElements[Tag],\n TastySpecificKeys | K[number] | ModPropsKeys<M> | TokenPropsKeys<TP>\n >\n> &\n WithVariant<V> &\n Omit<\n Omit<AllHTMLAttributes<HTMLElement>, keyof JSX.IntrinsicElements[Tag]> &\n JSX.IntrinsicElements[Tag],\n TastySpecificKeys | K[number] | ModPropsKeys<M> | TokenPropsKeys<TP>\n >;\n\ntype TastyComponentPropsWithDefaults<\n Props extends PropsWithStyles,\n DefaultProps extends Partial<Props>,\n> = keyof DefaultProps extends never\n ? Props\n : {\n [key in Extract<keyof Props, keyof DefaultProps>]?: Props[key];\n } & {\n [key in keyof Omit<Props, keyof DefaultProps>]: Props[key];\n };\n\nexport function tasty<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition = Record<string, never>,\n Tag extends keyof JSX.IntrinsicElements = 'div',\n M extends ModPropsInput = readonly never[],\n TP extends TokenPropsInput = readonly never[],\n>(\n options: TastyElementOptions<K, V, E, Tag, M, TP>,\n secondArg?: never,\n): ForwardRefExoticComponent<\n PropsWithoutRef<TastyElementProps<K, V, Tag, M, TP>> & RefAttributes<unknown>\n> &\n SubElementComponents<E>;\nexport function tasty<\n Props extends PropsWithStyles,\n DefaultProps extends Partial<Props> = Partial<Props>,\n>(\n Component: ComponentType<Props>,\n options?: TastyProps<never, never, Record<string, never>, Props>,\n): ComponentType<TastyComponentPropsWithDefaults<Props, DefaultProps>>;\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n// Implementation\nexport function tasty<\n K extends StyleList,\n V extends VariantMap,\n _C = Record<string, unknown>,\n>(Component: any, options?: any) {\n if (isValidElementType(Component)) {\n return tastyWrap(Component as ComponentType<any>, options);\n }\n\n return tastyElement(Component as TastyProps<K, V>);\n}\n\nfunction tastyWrap<\n P extends PropsWithStyles,\n DefaultProps extends Partial<P> = Partial<P>,\n>(\n Component: ComponentType<P>,\n options?: TastyProps<never, never, P>,\n): ComponentType<TastyComponentPropsWithDefaults<P, DefaultProps>> {\n const {\n as: extendTag,\n element: extendElement,\n ...defaultProps\n } = (options ?? {}) as TastyProps<never, never, P>;\n\n const propsWithStyles = ['styles'].concat(\n Object.keys(defaultProps).filter((prop) => prop.endsWith('Styles')),\n );\n\n const _WrappedComponent = forwardRef<any, any>((props, ref) => {\n const { as, element, ...restProps } = props as Record<string, unknown>;\n\n const mergedStylesMap = propsWithStyles.reduce(\n (map, prop) => {\n const restValue = (restProps as any)[prop];\n const defaultValue = (defaultProps as any)[prop];\n\n if (restValue != null && defaultValue != null) {\n (map as any)[prop] = mergeStyles(defaultValue, restValue);\n } else {\n (map as any)[prop] = restValue ?? defaultValue;\n }\n\n return map;\n },\n {} as Record<string, unknown>,\n );\n\n const elementProps = {\n ...(defaultProps as unknown as Record<string, unknown>),\n ...(restProps as unknown as Record<string, unknown>),\n ...mergedStylesMap,\n as: (as as string | undefined) ?? extendTag,\n element: (element as string | undefined) || extendElement,\n ref,\n } as unknown as P;\n\n return createElement(Component as ComponentType<P>, elementProps);\n });\n\n _WrappedComponent.displayName = `TastyWrappedComponent(${getDisplayName(\n Component,\n (defaultProps as any).qa ?? (extendTag as any) ?? 'Anonymous',\n )})`;\n\n return _WrappedComponent as unknown as ComponentType<\n TastyComponentPropsWithDefaults<P, DefaultProps>\n >;\n}\n\nfunction tastyElement<\n K extends StyleList,\n V extends VariantMap,\n E extends ElementsDefinition,\n>(tastyOptions: TastyProps<K, V, E>) {\n const {\n as: originalAs = 'div',\n element: defaultElement,\n styles: defaultStyles,\n styleProps,\n modProps: modPropsDef,\n tokenProps: tokenPropsDef,\n variants,\n tokens: defaultTokens,\n elements,\n ...defaultProps\n } = tastyOptions;\n\n // Pre-compute merged styles for each variant (if variants are defined)\n // This avoids creating separate component instances per variant\n let variantStylesMap: Record<string, Styles | undefined> | undefined;\n if (variants) {\n // Split defaultStyles: extend-mode state maps (no '' key, non-selector)\n // are pulled out and applied AFTER variant merge so they survive\n // replace-mode maps in variants.\n let baseStyles = defaultStyles;\n let extensionStyles: Styles | undefined;\n\n if (defaultStyles) {\n for (const key of Object.keys(defaultStyles)) {\n if (isSelector(key)) continue;\n\n const value = (defaultStyles as Record<string, unknown>)[key];\n\n if (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n !('' in value)\n ) {\n if (!extensionStyles) {\n baseStyles = { ...defaultStyles } as Styles;\n extensionStyles = {} as Styles;\n }\n (extensionStyles as Record<string, unknown>)[key] = value;\n delete (baseStyles as Record<string, unknown>)[key];\n }\n }\n }\n\n const variantEntries = Object.entries(variants) as [string, Styles][];\n variantStylesMap = variantEntries.reduce(\n (map, [variant, variantStyles]) => {\n map[variant] = extensionStyles\n ? mergeStyles(baseStyles, variantStyles, extensionStyles)\n : mergeStyles(baseStyles, variantStyles);\n return map;\n },\n {} as Record<string, Styles | undefined>,\n );\n // Ensure 'default' variant always exists\n if (!variantStylesMap['default']) {\n variantStylesMap['default'] = defaultStyles;\n }\n }\n\n const {\n qa: defaultQa,\n qaVal: defaultQaVal,\n ...otherDefaultProps\n } = defaultProps ?? {};\n\n const propsToCheck = styleProps\n ? (styleProps as StyleList).concat(BASE_STYLES)\n : BASE_STYLES;\n\n const modPropsKeys: string[] | undefined = modPropsDef\n ? ((Array.isArray(modPropsDef)\n ? modPropsDef\n : Object.keys(modPropsDef)) as string[])\n : undefined;\n\n const tokenPropsMapping: [string, string][] | undefined = tokenPropsDef\n ? buildTokenPropsMapping(tokenPropsDef as TokenPropsInput)\n : undefined;\n\n // Factory-level cache: maps stable style references to computed classNames.\n // For the common case (no instance overrides), this avoids recomputation.\n const classNameCache = new Map<Styles | undefined, string>();\n\n const _TastyComponent = forwardRef<\n unknown,\n AllBasePropsWithMods<K> & WithVariant<V>\n >((allProps, ref) => {\n const {\n as,\n styles: rawStyles,\n variant,\n mods,\n element,\n qa,\n qaVal,\n className: userClassName,\n tokens,\n style,\n ...otherProps\n } = allProps as Record<string, unknown> as AllBasePropsWithMods<K> &\n WithVariant<V> & {\n className?: string;\n tokens?: Tokens;\n style?: Record<string, unknown>;\n };\n\n let styles = rawStyles;\n\n let propStyles: Styles | null = null;\n\n for (const prop of propsToCheck) {\n const key = prop as unknown as string;\n\n if (key in otherProps) {\n if (!propStyles) propStyles = {};\n const value = (otherProps as any)[key];\n (propStyles as any)[key] = value;\n delete (otherProps as any)[key];\n }\n }\n\n if (!styles || (styles && !hasKeys(styles as Record<string, unknown>))) {\n styles = undefined as unknown as Styles;\n }\n\n let propMods: Record<string, ModValue> | undefined;\n if (modPropsKeys) {\n for (const key of modPropsKeys) {\n if (key in otherProps) {\n if (!propMods) propMods = {};\n propMods[key] = (otherProps as Record<string, unknown>)[\n key\n ] as ModValue;\n delete (otherProps as Record<string, unknown>)[key];\n }\n }\n }\n\n let propTokens: Tokens | undefined;\n if (tokenPropsMapping) {\n for (const [propName, tokenKey] of tokenPropsMapping) {\n if (propName in otherProps) {\n if (!propTokens) propTokens = {} as Tokens;\n (propTokens as Record<string, TokenValue>)[tokenKey] = (\n otherProps as Record<string, unknown>\n )[propName] as TokenValue;\n delete (otherProps as Record<string, unknown>)[propName];\n }\n }\n }\n\n const baseStyles = variantStylesMap\n ? (variantStylesMap[(variant as string) || 'default'] ??\n variantStylesMap['default'])\n : defaultStyles;\n\n const hasInstanceStyles =\n styles && hasKeys(styles as Record<string, unknown>);\n const hasPropStyles = propStyles && hasKeys(propStyles);\n\n const allStyles =\n hasInstanceStyles || hasPropStyles\n ? mergeStyles(baseStyles, styles as Styles, propStyles as Styles)\n : baseStyles;\n\n // Use factory-level cache for stable style references (client only).\n // On the server the cache must be skipped: both the SSR collector and\n // the RSC inline-style paths are per-request, so every request must\n // call computeStyles() to ensure CSS is actually collected/emitted.\n const useFactoryCache = typeof document !== 'undefined';\n let stylesResult: ComputeStylesResult;\n if (\n useFactoryCache &&\n allStyles === baseStyles &&\n classNameCache.has(allStyles)\n ) {\n stylesResult = { className: classNameCache.get(allStyles)! };\n touch(stylesResult.className);\n } else {\n stylesResult = computeStyles(allStyles);\n if (useFactoryCache && allStyles === baseStyles) {\n classNameCache.set(allStyles, stylesResult.className);\n }\n }\n\n // Merge tokens: default -> instance -> tokenProps\n let mergedTokens: Tokens | undefined;\n if (defaultTokens || tokens || propTokens) {\n if (!defaultTokens && !propTokens) {\n mergedTokens = tokens as Tokens;\n } else if (!tokens && !propTokens) {\n mergedTokens = defaultTokens;\n } else {\n mergedTokens = {\n ...defaultTokens,\n ...(tokens as Tokens),\n ...propTokens,\n } as Tokens;\n }\n }\n\n const processedTokenStyle = processTokens(mergedTokens);\n\n let mergedStyle: Record<string, unknown> | undefined;\n if (processedTokenStyle || style) {\n if (!processedTokenStyle) {\n mergedStyle = style;\n } else if (!style) {\n mergedStyle = processedTokenStyle as Record<string, unknown>;\n } else {\n mergedStyle = {\n ...(processedTokenStyle as Record<string, unknown>),\n ...style,\n };\n }\n }\n\n const mergedMods = propMods\n ? { ...(mods as Record<string, ModValue>), ...propMods }\n : (mods as Record<string, ModValue> | undefined);\n\n let modDataAttrs: Record<string, unknown> | undefined;\n if (mergedMods) {\n modDataAttrs = modAttrs(mergedMods as unknown as Mods) as Record<\n string,\n unknown\n >;\n }\n\n const finalClassName = [\n (userClassName as string) || '',\n stylesResult.className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const elementProps = {\n 'data-element': (element as string | undefined) || defaultElement,\n 'data-qa': (qa as string | undefined) || defaultQa,\n 'data-qaval': (qaVal as string | undefined) || defaultQaVal,\n ...(otherDefaultProps as unknown as Record<string, unknown>),\n ...(modDataAttrs || {}),\n ...(otherProps as unknown as Record<string, unknown>),\n className: finalClassName,\n style: mergedStyle,\n ref,\n } as Record<string, unknown>;\n\n handleIsProperties(elementProps);\n\n const el = createElement(\n (as as string | 'div') ?? originalAs,\n elementProps,\n );\n\n // RSC mode: wrap element with inline <style> for server-rendered CSS\n if (stylesResult.css) {\n return createElement(\n Fragment,\n null,\n createElement('style', {\n 'data-tasty-rsc': '',\n dangerouslySetInnerHTML: { __html: stylesResult.css },\n }),\n el,\n );\n }\n\n return el;\n });\n\n _TastyComponent.displayName = `TastyComponent(${\n (defaultProps as any).qa || originalAs\n })`;\n\n // Attach sub-element components if elements are defined\n if (elements) {\n const subElements = Object.entries(elements).reduce(\n (acc, [name, definition]) => {\n acc[name] = createSubElement(\n name,\n definition as SubElementDefinition<keyof JSX.IntrinsicElements>,\n );\n return acc;\n },\n {} as Record<string, ForwardRefExoticComponent<any>>,\n );\n\n return Object.assign(_TastyComponent, subElements);\n }\n\n return _TastyComponent;\n}\n\nexport const Element = tasty({});\n"],"mappings":"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"}
package/docs/injector.md CHANGED
@@ -207,13 +207,15 @@ import { configure } from '@tenphi/tasty';
207
207
  configure({
208
208
  devMode: true, // Enable development features (auto-detected)
209
209
  maxRulesPerSheet: 8192, // Cap rules per stylesheet (default: 8192)
210
- unusedStylesThreshold: 500, // Trigger cleanup threshold (CSS rules only)
211
- bulkCleanupDelay: 5000, // Cleanup delay (ms) - ignored if idleCleanup is true
212
- idleCleanup: true, // Use requestIdleCallback for cleanup
213
- bulkCleanupBatchRatio: 0.5, // Clean up oldest 50% per batch
214
- unusedStylesMinAgeMs: 10000, // Minimum age before cleanup (ms)
215
210
  forceTextInjection: false, // Force textContent insertion (auto-detected for tests)
216
211
  nonce: 'csp-nonce', // CSP nonce for security
212
+ gc: { // Garbage collection for unused styles
213
+ auto: true, // Enable automatic background sweep
214
+ baseMaxAge: 60000, // Base TTL (ms) for single-use styles
215
+ cooldown: 30000, // Minimum time between GC runs
216
+ autoInterval: 300000, // Background sweep interval (ms)
217
+ cacheCapacity: 5000, // Hard cap on cached styles (optional)
218
+ },
217
219
  states: { // Global predefined states for advanced state mapping
218
220
  '@mobile': '@media(w < 768px)',
219
221
  '@dark': '@root(schema=dark)',
@@ -229,7 +231,9 @@ configure({
229
231
  - Most options have sensible defaults and auto-detection
230
232
  - `configure()` is optional - the injector works with defaults
231
233
  - **Configuration is locked after styles are generated** - calling `configure()` after first render will emit a warning and be ignored
232
- - `unusedStylesMinAgeMs`: Minimum time (ms) a style must remain unused before being eligible for cleanup. Helps prevent removal of styles that might be quickly reactivated.
234
+ - `gc.baseMaxAge`: Base TTL for a style rendered only once. Popular styles get longer TTLs via logarithmic scaling (`baseMaxAge * log2(hitCount + 1)`).
235
+ - `gc.auto`: When true, runs a periodic background sweep at `gc.autoInterval` intervals using `requestIdleCallback`.
236
+ - `gc.cooldown`: Minimum time between GC runs to avoid thrashing.
233
237
 
234
238
  ---
235
239
 
@@ -291,21 +295,31 @@ comp3.dispose(); // refCount: 1 → 0, eligible for bulk cleanup
291
295
  // Next inject() with same styles will increment refCount and reuse immediately
292
296
  ```
293
297
 
294
- ### Smart Cleanup System
298
+ ### Garbage Collection
295
299
 
296
300
  ```typescript
297
- import { configure } from '@tenphi/tasty';
301
+ import { configure, gc, maybeGC } from '@tenphi/tasty';
298
302
 
299
- // CSS rules: Not immediately deleted, marked for bulk cleanup (refCount = 0)
300
303
  // Keyframes: Disposed immediately when refCount = 0 (safer for global scope)
304
+ // CSS rules: Tracked by popularity and cleaned up via gc()
301
305
 
302
306
  configure({
303
- unusedStylesThreshold: 100, // Cleanup when 100+ unused CSS rules
304
- bulkCleanupBatchRatio: 0.3, // Remove oldest 30% each time
307
+ gc: {
308
+ auto: true, // Enable background sweep
309
+ baseMaxAge: 60000, // 1-minute base TTL
310
+ cooldown: 30000, // 30s between runs
311
+ },
305
312
  });
306
313
 
314
+ // Manual GC (synchronous, returns number of swept styles):
315
+ gc();
316
+
317
+ // Event-driven GC with cooldown (e.g. on route change):
318
+ maybeGC();
319
+
307
320
  // Benefits:
308
- // - CSS rules: Batch cleanup prevents DOM manipulation overhead
321
+ // - Popularity-aware: frequently used styles survive longer
322
+ // - DOM-safe: styles currently in the DOM are never evicted
309
323
  // - Keyframes: Immediate cleanup prevents global namespace pollution
310
324
  // - Unused styles can be instantly reactivated (just increment refCount)
311
325
  ```
@@ -462,13 +476,14 @@ injectGlobal([
462
476
  { selector: '.container', declarations: 'max-width: 1200px;' }
463
477
  ]);
464
478
 
465
- // ✅ Configure appropriate thresholds for your app (BEFORE first render!)
479
+ // ✅ Configure GC for your app (BEFORE first render!)
466
480
  import { configure } from '@tenphi/tasty';
467
481
 
468
482
  configure({
469
- unusedStylesThreshold: 500, // Default threshold (adjust based on app size)
470
- bulkCleanupBatchRatio: 0.5, // Default: clean oldest 50% per batch
471
- unusedStylesMinAgeMs: 10000, // Wait 10s before cleanup eligibility
483
+ gc: {
484
+ auto: true, // Enable background sweep for long-lived pages
485
+ baseMaxAge: 60000, // Default base TTL (adjust based on app size)
486
+ },
472
487
  });
473
488
  ```
474
489
 
@@ -480,8 +495,8 @@ configure({
480
495
  // 1. Hash-based deduplication - same CSS = same className
481
496
  // 2. Reference counting - styles stay alive while in use (refCount > 0)
482
497
  // 3. Immediate keyframes cleanup - disposed instantly when refCount = 0
483
- // 4. Batch CSS cleanup - unused CSS rules (refCount = 0) cleaned in batches
484
- // 5. Non-stacking cleanups - prevents timeout accumulation
498
+ // 4. Popularity-aware GC - unused CSS rules are scored by hitCount and age
499
+ // 5. DOM safety guard - styles visible in the DOM are never evicted
485
500
 
486
501
  // Manual cleanup is rarely needed but available:
487
502
  cleanup(); // Force immediate cleanup of all unused CSS rules (refCount = 0)
package/docs/ssr.md CHANGED
@@ -82,15 +82,15 @@ That's it. All `tasty()` components inside the tree automatically get SSR suppor
82
82
 
83
83
  ### How it works
84
84
 
85
- - `TastyRegistry` is a `'use client'` component, but Next.js still server-renders it on initial page load.
86
- - During SSR, `computeStyles()` finds the collector (registered globally by `TastyRegistry`) and collects CSS rules into it.
87
- - `TastyRegistry` uses `useServerInsertedHTML` to flush collected CSS into the HTML stream as `<style data-tasty-ssr>` tags. This is fully streaming-compatible -- styles are injected alongside each Suspense boundary as it resolves.
85
+ - `TastyRegistry` is a `'use client'` component, but Next.js still server-renders it on initial page load. The `'use client'` boundary is required solely to access `useServerInsertedHTML` — **not** because `tasty()` components need the client.
86
+ - During SSR, `TastyRegistry` creates a `ServerStyleCollector` and registers it via a module-level global getter. All style computation — whether from `tasty()` components, `computeStyles()`, `useStyles()`, or other hooks like `useGlobalStyles()` — discovers the collector through this single global getter. No React context is involved.
87
+ - `TastyRegistry` uses `useServerInsertedHTML` to flush collected CSS into the HTML stream as `<style data-tasty-ssr>` tags. This is fully streaming-compatible styles are injected alongside each Suspense boundary as it resolves.
88
88
  - A companion `<script>` tag transfers the `cacheKey → className` mapping to the client.
89
89
  - When the module loads on the client, `hydrateTastyCache()` runs automatically and pre-populates the injector cache. During hydration, `computeStyles()` hits the cache and skips the entire pipeline.
90
90
 
91
91
  ### Using tasty() in Server Components
92
92
 
93
- `tasty()` components are hook-free and do not require `'use client'`. They can be used directly in React Server Components. Dynamic `styleProps` like `<Grid flow="column">` work normally in server components. During SSR, the `TastyRegistry` registers its collector globally so that `computeStyles()` can discover it without React context.
93
+ `tasty()` components are hook-free and do not require `'use client'`. They can be used directly in React Server Components. Dynamic `styleProps` like `<Grid flow="column">` work normally in server components. During SSR, `computeStyles()` discovers the collector via the same global getter registered by `TastyRegistry` no React context or client boundary needed for this path.
94
94
 
95
95
  ### Options
96
96
 
@@ -197,12 +197,12 @@ Same as Next.js -- call `configure({ nonce: '...' })` before any rendering happe
197
197
 
198
198
  ## Generic Framework Integration
199
199
 
200
- Any React-based framework can integrate using the core SSR API:
200
+ Any React-based framework can integrate using `runWithCollector`, which binds a `ServerStyleCollector` to the current async context via `AsyncLocalStorage`. All `computeStyles()` and hook calls within the render automatically discover the collector.
201
201
 
202
202
  ```tsx
203
203
  import {
204
204
  ServerStyleCollector,
205
- TastySSRContext,
205
+ runWithCollector,
206
206
  hydrateTastyCache,
207
207
  } from '@tenphi/tasty/ssr';
208
208
  import { renderToString } from 'react-dom/server';
@@ -212,10 +212,8 @@ import { hydrateRoot } from 'react-dom/client';
212
212
 
213
213
  const collector = new ServerStyleCollector();
214
214
 
215
- const html = renderToString(
216
- <TastySSRContext.Provider value={collector}>
217
- <App />
218
- </TastySSRContext.Provider>
215
+ const html = await runWithCollector(collector, () =>
216
+ renderToString(<App />)
219
217
  );
220
218
 
221
219
  const css = collector.getCSS();
@@ -251,11 +249,8 @@ For streaming with `renderToPipeableStream`, use `flushCSS()` instead of `getCSS
251
249
  ```tsx
252
250
  const collector = new ServerStyleCollector();
253
251
 
254
- const stream = renderToPipeableStream(
255
- <TastySSRContext.Provider value={collector}>
256
- <App />
257
- </TastySSRContext.Provider>,
258
- {
252
+ const stream = await runWithCollector(collector, () =>
253
+ renderToPipeableStream(<App />, {
259
254
  onShellReady() {
260
255
  // Flush styles collected so far
261
256
  const css = collector.flushCSS();
@@ -270,31 +265,10 @@ const stream = renderToPipeableStream(
270
265
  const state = collector.getCacheState();
271
266
  res.write(`<script data-tasty-cache type="application/json">${JSON.stringify(state)}</script>`);
272
267
  },
273
- }
268
+ })
274
269
  );
275
270
  ```
276
271
 
277
- ### AsyncLocalStorage (no React context)
278
-
279
- If your framework doesn't support wrapping the React tree with a provider, use `runWithCollector`:
280
-
281
- ```tsx
282
- import {
283
- ServerStyleCollector,
284
- runWithCollector,
285
- hydrateTastyCache,
286
- } from '@tenphi/tasty/ssr';
287
-
288
- const collector = new ServerStyleCollector();
289
-
290
- const html = await runWithCollector(collector, () =>
291
- renderToString(<App />)
292
- );
293
-
294
- const css = collector.getCSS();
295
- // ... inject into HTML as above
296
- ```
297
-
298
272
  ---
299
273
 
300
274
  ## API Reference
@@ -303,7 +277,7 @@ const css = collector.getCSS();
303
277
 
304
278
  | Import path | Description |
305
279
  |---|---|
306
- | `@tenphi/tasty/ssr` | Core SSR API: `ServerStyleCollector`, `TastySSRContext`, `runWithCollector`, `hydrateTastyCache` |
280
+ | `@tenphi/tasty/ssr` | Core SSR API: `ServerStyleCollector`, `runWithCollector`, `hydrateTastyCache` |
307
281
  | `@tenphi/tasty/ssr/next` | Next.js App Router: `TastyRegistry` component |
308
282
  | `@tenphi/tasty/ssr/astro` | Astro: `tastyMiddleware`, auto-hydration on import |
309
283
 
@@ -323,10 +297,6 @@ Server-safe style collector. One instance per request.
323
297
  | `flushCSS()` | Get only CSS collected since the last flush. For streaming SSR. |
324
298
  | `getCacheState()` | Serialize `{ entries: Record<cacheKey, className>, classCounter }` for client hydration. |
325
299
 
326
- ### `TastySSRContext`
327
-
328
- React context (`createContext<ServerStyleCollector | null>(null)`). Used by the `useStyles()` hook to find the collector during SSR. Not needed when using `computeStyles()` directly (which discovers the collector via `AsyncLocalStorage` or the global getter registered by `TastyRegistry`).
329
-
330
300
  ### `TastyRegistry`
331
301
 
332
302
  Next.js App Router component. Props:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenphi/tasty",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "A design-system-integrated styling system and DSL for concise, state-aware UI styling",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -156,7 +156,7 @@
156
156
  "name": "core (import *)",
157
157
  "path": "dist/core/index.js",
158
158
  "import": "*",
159
- "limit": "45 kB"
159
+ "limit": "46 kB"
160
160
  },
161
161
  {
162
162
  "name": "static",
@@ -184,7 +184,7 @@
184
184
  "path",
185
185
  "crypto"
186
186
  ],
187
- "limit": "41 kB"
187
+ "limit": "42 kB"
188
188
  }
189
189
  ],
190
190
  "scripts": {
@@ -1,14 +0,0 @@
1
- import { getRegisteredSSRCollector } from "../ssr/ssr-collector-ref.js";
2
- //#region src/hooks/resolve-ssr-collector.ts
3
- /**
4
- * Resolve the SSR collector from React context or AsyncLocalStorage.
5
- * Returns null on the client (no collector available).
6
- */
7
- function resolveSSRCollector(reactContext) {
8
- if (reactContext) return reactContext;
9
- return getRegisteredSSRCollector();
10
- }
11
- //#endregion
12
- export { resolveSSRCollector };
13
-
14
- //# sourceMappingURL=resolve-ssr-collector.js.map