tailwind-to-style 3.2.2 → 4.0.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 (52) hide show
  1. package/README.md +221 -666
  2. package/dist/animations/index.cjs +9391 -0
  3. package/dist/animations/index.d.ts +58 -0
  4. package/dist/animations/index.esm.js +9385 -0
  5. package/dist/animations/index.esm.js.map +1 -0
  6. package/dist/className/index.cjs +9080 -0
  7. package/dist/className/index.esm.js +9075 -0
  8. package/dist/className/index.esm.js.map +1 -0
  9. package/dist/core/tws.cjs +136 -114
  10. package/dist/core/tws.cjs.map +1 -0
  11. package/dist/core/tws.esm.js +136 -114
  12. package/dist/core/tws.esm.js.map +1 -1
  13. package/dist/core/twsx.cjs +2442 -4245
  14. package/dist/core/twsx.esm.js +2442 -4245
  15. package/dist/core/twsx.esm.js.map +1 -1
  16. package/dist/core/twsxVariants.cjs +2470 -4262
  17. package/dist/core/twsxVariants.esm.js +2470 -4262
  18. package/dist/core/twsxVariants.esm.js.map +1 -1
  19. package/dist/cx.cjs +2 -2
  20. package/dist/cx.cjs.map +1 -0
  21. package/dist/cx.esm.js +2 -2
  22. package/dist/index.cjs +5128 -6057
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.ts +993 -1
  25. package/dist/index.esm.js +5124 -6022
  26. package/dist/index.esm.js.map +1 -1
  27. package/dist/index.min.js +1 -1
  28. package/dist/index.min.js.map +1 -1
  29. package/dist/react/index.cjs +10177 -0
  30. package/dist/react/index.cjs.map +1 -0
  31. package/dist/react/index.d.ts +69 -0
  32. package/dist/react/index.esm.js +10173 -0
  33. package/dist/react/index.esm.js.map +1 -0
  34. package/dist/styled/index.cjs +9094 -0
  35. package/dist/styled/index.cjs.map +1 -0
  36. package/dist/styled/index.d.ts +17 -0
  37. package/dist/styled/index.esm.js +9087 -0
  38. package/dist/styled/index.esm.js.map +1 -0
  39. package/dist/tokens/index.cjs +359 -0
  40. package/dist/tokens/index.d.ts +33 -0
  41. package/dist/tokens/index.esm.js +355 -0
  42. package/dist/tokens/index.esm.js.map +1 -0
  43. package/dist/utils/index.cjs +313 -297
  44. package/dist/utils/index.esm.js +313 -297
  45. package/dist/utils/index.esm.js.map +1 -1
  46. package/package.json +38 -24
  47. package/types/animations/index.d.ts +58 -0
  48. package/types/className/index.d.ts +41 -0
  49. package/types/index.d.ts +993 -1
  50. package/types/react/index.d.ts +69 -0
  51. package/types/tokens/index.d.ts +33 -0
  52. package/types/v4.d.ts +191 -0
package/dist/index.d.ts CHANGED
@@ -1,7 +1,10 @@
1
- // Type definitions for tailwind-to-style
1
+ // Type definitions for tailwind-to-style v4
2
2
  // Project: https://github.com/Bigetion/tailwind-to-style
3
3
  // Definitions by: Bigetion
4
4
 
5
+ // v4 unified API re-exports
6
+ export { tw, tws, cx, createSSRCollector } from './v4';
7
+
5
8
  // ============================================================================
6
9
  // Environment Detection
7
10
  // ============================================================================
@@ -256,6 +259,104 @@ export interface VariantsDefinition {
256
259
  [variantName: string]: VariantOptions;
257
260
  }
258
261
 
262
+ // ============================================================================
263
+ // Type Inference Utilities
264
+ // ============================================================================
265
+
266
+ /**
267
+ * Infer variant props from a variant function or config.
268
+ * Use this when you need to type component props based on your variants.
269
+ *
270
+ * @example
271
+ * const button = twsxVariants('.btn', {
272
+ * variants: {
273
+ * size: { sm: 'text-sm', lg: 'text-lg' },
274
+ * variant: { primary: 'bg-blue-500', secondary: 'bg-gray-200' }
275
+ * }
276
+ * });
277
+ *
278
+ * // Extract props type
279
+ * type ButtonProps = InferVariantProps<typeof button>;
280
+ * // Result: { size?: 'sm' | 'lg'; variant?: 'primary' | 'secondary' }
281
+ */
282
+ export type InferVariantProps<T> = T extends VariantFunction<infer V>
283
+ ? VariantProps<V>
284
+ : T extends TwsxClassNameVariantFunction<infer V>
285
+ ? TwsxClassNameVariantProps<V>
286
+ : T extends TwsxVariantsConfig<infer V>
287
+ ? VariantProps<V>
288
+ : T extends TwsxClassNameVariantsConfig<infer V>
289
+ ? TwsxClassNameVariantProps<V>
290
+ : never;
291
+
292
+ /**
293
+ * Infer slot names from a slots function.
294
+ *
295
+ * @example
296
+ * const card = twsxClassName({
297
+ * slots: { root: 'card', header: 'card-header', body: 'card-body' },
298
+ * variants: {}
299
+ * });
300
+ *
301
+ * type CardSlots = InferSlotNames<typeof card>;
302
+ * // Result: 'root' | 'header' | 'body'
303
+ */
304
+ export type InferSlotNames<T> = T extends TwsxClassNameSlotsFunction<infer S, any>
305
+ ? keyof S
306
+ : never;
307
+
308
+ /**
309
+ * Extract variant names from a variants definition.
310
+ *
311
+ * @example
312
+ * const config = {
313
+ * variants: { size: { sm: '...', lg: '...' }, variant: { primary: '...' } }
314
+ * };
315
+ * type VariantNames = ExtractVariantNames<typeof config>;
316
+ * // Result: 'size' | 'variant'
317
+ */
318
+ export type ExtractVariantNames<T extends { variants?: VariantsDefinition }> =
319
+ T['variants'] extends VariantsDefinition ? keyof T['variants'] : never;
320
+
321
+ /**
322
+ * Extract variant options for a specific variant.
323
+ *
324
+ * @example
325
+ * const config = {
326
+ * variants: { size: { sm: '...', md: '...', lg: '...' } }
327
+ * };
328
+ * type SizeOptions = ExtractVariantOptions<typeof config, 'size'>;
329
+ * // Result: 'sm' | 'md' | 'lg'
330
+ */
331
+ export type ExtractVariantOptions<
332
+ T extends { variants?: VariantsDefinition },
333
+ K extends keyof NonNullable<T['variants']>
334
+ > = T['variants'] extends VariantsDefinition
335
+ ? keyof T['variants'][K]
336
+ : never;
337
+
338
+ /**
339
+ * Make all variant props required.
340
+ * Useful when you want to enforce all variants are specified.
341
+ */
342
+ export type RequiredVariantProps<V extends VariantsDefinition> = {
343
+ [K in keyof V]: keyof V[K];
344
+ };
345
+
346
+ /**
347
+ * Pick only specific variants from props.
348
+ */
349
+ export type PickVariantProps<V extends VariantsDefinition, K extends keyof V> = {
350
+ [P in K]?: keyof V[P];
351
+ };
352
+
353
+ /**
354
+ * Omit specific variants from props.
355
+ */
356
+ export type OmitVariantProps<V extends VariantsDefinition, K extends keyof V> = {
357
+ [P in Exclude<keyof V, K>]?: keyof V[P];
358
+ };
359
+
259
360
  /** * Compound variant definition - strict typing for better autocomplete
260
361
  */
261
362
  export interface CompoundVariant<V extends VariantsDefinition = VariantsDefinition> {
@@ -369,14 +470,905 @@ export function twsxVariants(
369
470
  */
370
471
  export const performanceUtils: PerformanceUtils;
371
472
 
473
+ // ============================================================================
474
+ // twsxClassName - Advanced Unified CSS-in-JS API
475
+ // ============================================================================
476
+
477
+ /**
478
+ * Pseudo-class shorthands for twsxClassName
479
+ */
480
+ export type PseudoShorthand =
481
+ | "hover" | "focus" | "active" | "disabled" | "visited" | "checked"
482
+ | "required" | "invalid" | "valid" | "empty" | "enabled" | "indeterminate"
483
+ | "focus-within" | "focus-visible" | "first" | "last" | "odd" | "even"
484
+ | "first-of-type" | "last-of-type" | "only" | "only-of-type"
485
+ | "placeholder" | "before" | "after" | "selection" | "marker" | "file" | "backdrop"
486
+ // Dark/Light mode
487
+ | "dark" | "light"
488
+ // Motion preferences
489
+ | "motion-safe" | "motion-reduce"
490
+ // Print
491
+ | "print"
492
+ // Contrast
493
+ | "contrast-more" | "contrast-less"
494
+ // Orientation
495
+ | "portrait" | "landscape";
496
+
497
+ /**
498
+ * Group/Peer state shorthands
499
+ */
500
+ export type GroupPeerState =
501
+ | "group-hover" | "group-focus" | "group-active" | "group-focus-within"
502
+ | "group-focus-visible" | "group-disabled" | "group-checked" | "group-invalid" | "group-required"
503
+ | "peer-hover" | "peer-focus" | "peer-active" | "peer-focus-within"
504
+ | "peer-focus-visible" | "peer-disabled" | "peer-checked" | "peer-invalid"
505
+ | "peer-required" | "peer-placeholder-shown";
506
+
507
+ /**
508
+ * Responsive breakpoint shorthands
509
+ */
510
+ export type ResponsiveBreakpoint = "sm" | "md" | "lg" | "xl" | "2xl";
511
+
512
+ /**
513
+ * Animation preset names
514
+ */
515
+ export type AnimationPreset =
516
+ | "fadeIn" | "fadeOut" | "slideInUp" | "slideInDown" | "slideInLeft" | "slideInRight"
517
+ | "scaleIn" | "scaleOut" | "bounce" | "pulse" | "spin" | "ping" | "shake";
518
+
519
+ /**
520
+ * Custom animation configuration
521
+ */
522
+ export interface AnimationConfig {
523
+ keyframes: Record<string, string>;
524
+ duration?: string;
525
+ timing?: string;
526
+ delay?: string;
527
+ iteration?: string | number;
528
+ }
529
+
530
+ /**
531
+ * Design tokens structure
532
+ */
533
+ export interface DesignTokens {
534
+ colors?: Record<string, string | Record<string, string>>;
535
+ spacing?: Record<string, string>;
536
+ fontSize?: Record<string, string>;
537
+ fontWeight?: Record<string, string>;
538
+ borderRadius?: Record<string, string>;
539
+ shadow?: Record<string, string>;
540
+ animation?: Record<string, AnimationConfig>;
541
+ custom?: Record<string, string>;
542
+ }
543
+
544
+ /**
545
+ * Theme tokens
546
+ */
547
+ export interface ThemeTokens {
548
+ [key: string]: string | Record<string, string>;
549
+ }
550
+
551
+ /**
552
+ * Basic twsxClassName config (returns className string)
553
+ */
554
+ export interface TwsxClassNameBasicConfig {
555
+ /** Base Tailwind classes */
556
+ _?: string;
557
+ /** Component name (for readable className) */
558
+ name?: string;
559
+ /** Custom prefix (default: "twsx") */
560
+ prefix?: string;
561
+ /** Include hash in className (default: true) */
562
+ hash?: boolean;
563
+ /** Hash length (default: 8) */
564
+ hashLength?: number;
565
+ /** Auto-inject CSS to DOM (default: true) */
566
+ inject?: boolean;
567
+ /** Extend from another twsxClassName config */
568
+ extend?: TwsxClassNameVariantFunction<any> | TwsxClassNameBasicConfig;
569
+ /** Animation preset or custom config */
570
+ animation?: AnimationPreset | AnimationConfig;
571
+ /** Enter transition classes */
572
+ enter?: string;
573
+ /** Enter from state */
574
+ enterFrom?: string;
575
+ /** Enter to state */
576
+ enterTo?: string;
577
+ /** Exit/leave transition classes */
578
+ exit?: string;
579
+ /** Leave from state */
580
+ leaveFrom?: string;
581
+ /** Leave to state */
582
+ leaveTo?: string;
583
+ /** Pseudo-class shorthands, responsive, and custom selectors */
584
+ [key: string]: string | TwsxClassNameBasicConfig | AnimationPreset | AnimationConfig | boolean | number | undefined | any;
585
+ }
586
+
587
+ /**
588
+ * Variant value - string classes or nested object with pseudo states
589
+ */
590
+ export type TwsxClassNameVariantValue = string | {
591
+ _?: string;
592
+ [key: string]: string | undefined;
593
+ };
594
+
595
+ /**
596
+ * Variants definition for twsxClassName
597
+ */
598
+ export interface TwsxClassNameVariantsDefinition {
599
+ [variantName: string]: {
600
+ [optionKey: string]: TwsxClassNameVariantValue;
601
+ };
602
+ }
603
+
604
+ /**
605
+ * Compound variant for twsxClassName
606
+ */
607
+ export interface TwsxClassNameCompoundVariant<V extends TwsxClassNameVariantsDefinition = TwsxClassNameVariantsDefinition> {
608
+ class?: string;
609
+ className?: string;
610
+ [K: string]: string | string[] | boolean | undefined;
611
+ }
612
+
613
+ /**
614
+ * Responsive variant value - allows different values per breakpoint
615
+ */
616
+ export type ResponsiveVariantValue<T> = T | {
617
+ initial?: T;
618
+ sm?: T;
619
+ md?: T;
620
+ lg?: T;
621
+ xl?: T;
622
+ "2xl"?: T;
623
+ };
624
+
625
+ /**
626
+ * twsxClassName variants config
627
+ */
628
+ export interface TwsxClassNameVariantsConfig<V extends TwsxClassNameVariantsDefinition = TwsxClassNameVariantsDefinition> {
629
+ /** Component name */
630
+ name?: string;
631
+ /** Custom prefix */
632
+ prefix?: string;
633
+ /** Include hash */
634
+ hash?: boolean;
635
+ /** Hash length */
636
+ hashLength?: number;
637
+ /** Auto-inject CSS */
638
+ inject?: boolean;
639
+ /** Extend from another config */
640
+ extend?: TwsxClassNameVariantFunction<any> | TwsxClassNameVariantsConfig<any>;
641
+ /** Base Tailwind classes or nested object */
642
+ base?: string | { _?: string; [key: string]: string | undefined };
643
+ /** Variant definitions */
644
+ variants: V;
645
+ /** Compound variants */
646
+ compoundVariants?: TwsxClassNameCompoundVariant<V>[];
647
+ /** Default variant values */
648
+ defaultVariants?: { [K in keyof V]?: keyof V[K] | boolean };
649
+ /** Enable responsive variants for specified variant keys */
650
+ responsiveVariants?: (keyof V)[];
651
+ }
652
+
653
+ /**
654
+ * Slots definition for multi-part components
655
+ */
656
+ export interface TwsxClassNameSlotsDefinition {
657
+ [slotName: string]: string | { _?: string; [key: string]: string | undefined };
658
+ }
659
+
660
+ /**
661
+ * twsxClassName slots config
662
+ */
663
+ export interface TwsxClassNameSlotsConfig<
664
+ S extends TwsxClassNameSlotsDefinition = TwsxClassNameSlotsDefinition,
665
+ V extends TwsxClassNameVariantsDefinition = TwsxClassNameVariantsDefinition
666
+ > {
667
+ /** Component name */
668
+ name?: string;
669
+ /** Custom prefix */
670
+ prefix?: string;
671
+ /** Include hash */
672
+ hash?: boolean;
673
+ /** Hash length */
674
+ hashLength?: number;
675
+ /** Auto-inject CSS */
676
+ inject?: boolean;
677
+ /** Extend from another config */
678
+ extend?: TwsxClassNameSlotsFunction<any, any>;
679
+ /** Slot definitions */
680
+ slots: S;
681
+ /** Variant definitions (with slot-specific styles) */
682
+ variants?: V;
683
+ /** Compound variants */
684
+ compoundVariants?: TwsxClassNameCompoundVariant<V>[];
685
+ /** Default variant values */
686
+ defaultVariants?: { [K in keyof V]?: keyof V[K] | boolean };
687
+ }
688
+
689
+ /**
690
+ * Variant props with responsive support
691
+ */
692
+ export type TwsxClassNameVariantProps<V extends TwsxClassNameVariantsDefinition> = {
693
+ [K in keyof V]?: keyof V[K] | boolean | ResponsiveVariantValue<keyof V[K]>;
694
+ };
695
+
696
+ /**
697
+ * Variant selector function return type
698
+ */
699
+ export interface TwsxClassNameVariantFunction<V extends TwsxClassNameVariantsDefinition> {
700
+ (props?: TwsxClassNameVariantProps<V>): string;
701
+ /** Merge with additional classes */
702
+ merge(props?: TwsxClassNameVariantProps<V>, ...additionalClasses: ClassValue[]): string;
703
+ merge(...additionalClasses: ClassValue[]): string;
704
+ /** Get raw config */
705
+ raw(): TwsxClassNameVariantsConfig<V>;
706
+ }
707
+
708
+ /**
709
+ * Slots generator function return type
710
+ */
711
+ export interface TwsxClassNameSlotsFunction<
712
+ S extends TwsxClassNameSlotsDefinition,
713
+ V extends TwsxClassNameVariantsDefinition
714
+ > {
715
+ (props?: TwsxClassNameVariantProps<V>): { [K in keyof S]: string };
716
+ /** Merge with additional classes per slot */
717
+ merge(props?: TwsxClassNameVariantProps<V>, slotOverrides?: Partial<{ [K in keyof S]: string }>): { [K in keyof S]: string };
718
+ /** Get raw config */
719
+ raw(): TwsxClassNameSlotsConfig<S, V>;
720
+ }
721
+
722
+ /**
723
+ * Global configuration options
724
+ */
725
+ export interface TwsxClassNameGlobalConfig {
726
+ /** Default prefix (default: "twsx") */
727
+ prefix?: string;
728
+ /** Include hash by default (default: true) */
729
+ hash?: boolean;
730
+ /** Default hash length (default: 8) */
731
+ hashLength?: number;
732
+ /** Auto-inject CSS by default (default: true) */
733
+ inject?: boolean;
734
+ /** Deduplication (default: true) */
735
+ deduplicate?: boolean;
736
+ /** Custom breakpoints */
737
+ breakpoints?: Record<string, string>;
738
+ }
739
+
740
+ /**
741
+ * Unified CSS-in-JS API with smart mode detection.
742
+ *
743
+ * @example
744
+ * // Basic mode - returns className string
745
+ * const btn = twsxClassName({ _: 'bg-blue-500 p-4', hover: 'bg-blue-600' })
746
+ *
747
+ * // With dark mode
748
+ * const card = twsxClassName({ _: 'bg-white', dark: 'bg-gray-900' })
749
+ *
750
+ * // With group/peer states
751
+ * const icon = twsxClassName({ _: 'opacity-0', 'group-hover': 'opacity-100' })
752
+ *
753
+ * // Variants mode with boolean variants
754
+ * const btn = twsxClassName({
755
+ * base: 'px-4 py-2',
756
+ * variants: {
757
+ * disabled: { true: 'opacity-50', false: '' }
758
+ * }
759
+ * })
760
+ * btn({ disabled: true })
761
+ *
762
+ * // Responsive variants
763
+ * const btn = twsxClassName({
764
+ * variants: { size: { sm: '...', lg: '...' } },
765
+ * responsiveVariants: ['size']
766
+ * })
767
+ * btn({ size: { initial: 'sm', md: 'lg' } })
768
+ *
769
+ * // With design tokens
770
+ * twsxClassName.defineTokens({ colors: { primary: '#3b82f6' } })
771
+ * const btn = twsxClassName({ _: 'bg-$colors.primary' })
772
+ *
773
+ * // Extend existing config
774
+ * const primaryBtn = twsxClassName.extend(btn, { _: 'text-white' })
775
+ */
776
+ export function twsxClassName(config: TwsxClassNameBasicConfig): string;
777
+ export function twsxClassName(name: string, config: TwsxClassNameBasicConfig): string;
778
+ export function twsxClassName<V extends TwsxClassNameVariantsDefinition>(
779
+ config: TwsxClassNameVariantsConfig<V>
780
+ ): TwsxClassNameVariantFunction<V>;
781
+ export function twsxClassName<
782
+ S extends TwsxClassNameSlotsDefinition,
783
+ V extends TwsxClassNameVariantsDefinition
784
+ >(
785
+ config: TwsxClassNameSlotsConfig<S, V>
786
+ ): TwsxClassNameSlotsFunction<S, V>;
787
+
788
+ export namespace twsxClassName {
789
+ /**
790
+ * Configure global settings
791
+ */
792
+ function config(options: TwsxClassNameGlobalConfig): TwsxClassNameGlobalConfig;
793
+
794
+ /**
795
+ * Get current configuration
796
+ */
797
+ function getConfig(): TwsxClassNameGlobalConfig;
798
+
799
+ /**
800
+ * Extend an existing twsxClassName config
801
+ */
802
+ function extend<V extends TwsxClassNameVariantsDefinition>(
803
+ base: TwsxClassNameVariantFunction<V> | TwsxClassNameVariantsConfig<V>,
804
+ extension: Partial<TwsxClassNameVariantsConfig<V>>
805
+ ): TwsxClassNameVariantFunction<V>;
806
+
807
+ /**
808
+ * Define design tokens
809
+ */
810
+ function defineTokens(tokens: DesignTokens): DesignTokens;
811
+
812
+ /**
813
+ * Get all defined tokens
814
+ */
815
+ function getTokens(): DesignTokens;
816
+
817
+ /**
818
+ * Set a single token value
819
+ */
820
+ function setToken(path: string, value: string): void;
821
+
822
+ /**
823
+ * Create a named theme
824
+ */
825
+ function createTheme(name: string, tokens: ThemeTokens): ThemeTokens;
826
+
827
+ /**
828
+ * Set the active theme
829
+ */
830
+ function setTheme(name: string): string;
831
+
832
+ /**
833
+ * Get the active theme name
834
+ */
835
+ function getTheme(): string;
836
+
837
+ /**
838
+ * Get all defined themes
839
+ */
840
+ function getThemes(): Record<string, ThemeTokens>;
841
+
842
+ /**
843
+ * Define a custom animation preset
844
+ */
845
+ function defineAnimation(name: string, animation: AnimationConfig): void;
846
+
847
+ /**
848
+ * Get all animation presets
849
+ */
850
+ function getAnimations(): Record<string, AnimationConfig>;
851
+
852
+ /**
853
+ * Clear all caches
854
+ */
855
+ function clearCache(): void;
856
+
857
+ /**
858
+ * Get cache statistics
859
+ */
860
+ function getCacheStats(): {
861
+ classNameCacheSize: number;
862
+ cssCacheSize: number;
863
+ styleRegistrySize: number;
864
+ };
865
+
866
+ /**
867
+ * Get generated CSS for a className (useful for SSR)
868
+ */
869
+ function getCSS(className: string): string;
870
+
871
+ /**
872
+ * Get all generated CSS (useful for SSR)
873
+ */
874
+ function getAllCSS(): string;
875
+
876
+ /**
877
+ * Extract CSS as a style tag string (for SSR)
878
+ */
879
+ function extractCSS(): string;
880
+
881
+ /**
882
+ * Merge multiple class values (alias for cx)
883
+ */
884
+ function merge(...args: ClassValue[]): string;
885
+
886
+ /**
887
+ * Compose multiple configs into one
888
+ */
889
+ function compose<V extends TwsxClassNameVariantsDefinition>(
890
+ ...configs: (TwsxClassNameVariantFunction<any> | TwsxClassNameVariantsConfig<any>)[]
891
+ ): TwsxClassNameVariantsConfig<V>;
892
+
893
+ /**
894
+ * Atomic CSS class generator.
895
+ * Generates reusable atomic CSS classes from Tailwind utilities.
896
+ * Unlike tws() which returns inline styles, tw() returns class names
897
+ * with auto-injected CSS that supports pseudo-classes and responsive.
898
+ *
899
+ * @example
900
+ * tw('flex gap-3')
901
+ * // → "tw-flex tw-gap-3"
902
+ *
903
+ * tw('hover:bg-blue-500 md:flex-row')
904
+ * // → "tw-hover-bg-blue-500 tw-md-flex-row"
905
+ *
906
+ * // Usage in templates
907
+ * <div class="${tw('flex gap-3 hover:bg-gray-100')}">
908
+ */
909
+ function tw(classString: string): string;
910
+ }
911
+
912
+ // ============================================================================
913
+ // tw() - Atomic CSS Class Generator (standalone export)
914
+ // ============================================================================
915
+
916
+ /**
917
+ * Atomic CSS class generator.
918
+ * Generates reusable atomic CSS classes from Tailwind utilities.
919
+ * Unlike tws() which returns inline styles, tw() returns class names
920
+ * with auto-injected CSS that supports pseudo-classes and responsive breakpoints.
921
+ *
922
+ * @param classString - Space-separated Tailwind utility classes
923
+ * @returns Space-separated atomic class names (e.g., "tw-flex tw-gap-3")
924
+ *
925
+ * @example
926
+ * // Basic usage
927
+ * tw('flex gap-3 items-center')
928
+ * // → "tw-flex tw-gap-3 tw-items-center"
929
+ *
930
+ * // With pseudo-classes (unlike tws, these work!)
931
+ * tw('bg-gray-100 hover:bg-gray-200 focus:ring-2')
932
+ * // → "tw-bg-gray-100 tw-hover-bg-gray-200 tw-focus-ring-2"
933
+ *
934
+ * // With responsive breakpoints
935
+ * tw('flex flex-col md:flex-row lg:gap-8')
936
+ * // → "tw-flex tw-flex-col tw-md-flex-row tw-lg-gap-8"
937
+ *
938
+ * // Combined modifiers
939
+ * tw('md:hover:bg-blue-500')
940
+ * // → "tw-md-hover-bg-blue-500"
941
+ *
942
+ * // In HTML/JSX
943
+ * <div class={tw('flex gap-3 hover:bg-gray-100')}>...</div>
944
+ */
945
+ export function tw(classString: string): string;
946
+
947
+ // ============================================================================
948
+ // SSR Collector (Modern API)
949
+ // ============================================================================
950
+
951
+ /**
952
+ * SSR Collector options
953
+ */
954
+ export interface SSRCollectorOptions {
955
+ /** Enable CSS deduplication (default: true) */
956
+ dedupe?: boolean;
957
+ /** Enable CSS minification (default: false) */
958
+ minify?: boolean;
959
+ /** Sort CSS by specificity (default: true) */
960
+ sort?: boolean;
961
+ }
962
+
963
+ /**
964
+ * Extract options for SSR
965
+ */
966
+ export interface SSRExtractOptions {
967
+ /** Style tag ID (default: "twsx-ssr") */
968
+ id?: string;
969
+ /** CSP nonce value */
970
+ nonce?: string;
971
+ /** Minify output CSS */
972
+ minify?: boolean;
973
+ }
974
+
975
+ /**
976
+ * Critical CSS extraction result
977
+ */
978
+ export interface SSRCriticalResult {
979
+ /** Critical CSS wrapped in style tag */
980
+ critical: string;
981
+ /** Remaining non-critical CSS */
982
+ rest: string;
983
+ /** Extraction statistics */
984
+ stats: {
985
+ criticalSize: number;
986
+ criticalCount: number;
987
+ totalCount: number;
988
+ };
989
+ }
990
+
991
+ /**
992
+ * SSR statistics
993
+ */
994
+ export interface SSRStats {
995
+ ruleCount: number;
996
+ uniqueCount: number;
997
+ totalSize: number;
998
+ minifiedSize: number;
999
+ }
1000
+
1001
+ /**
1002
+ * SSR Collector instance
1003
+ */
1004
+ export interface SSRCollector {
1005
+ /** Check if currently collecting */
1006
+ readonly isCollecting: boolean;
1007
+ /** Get collected CSS rule count */
1008
+ readonly count: number;
1009
+ /** Get unique CSS rule count */
1010
+ readonly uniqueCount: number;
1011
+
1012
+ /** Peek at collected CSS without stopping */
1013
+ peek(): string;
1014
+ /** Extract CSS as raw string and stop collecting */
1015
+ extractRaw(options?: { shouldMinify?: boolean }): string;
1016
+ /** Extract CSS wrapped in <style> tag and stop collecting */
1017
+ extract(options?: SSRExtractOptions): string;
1018
+ /** Extract critical CSS (above-the-fold) */
1019
+ extractCritical(options?: { maxSize?: number; nonce?: string; id?: string }): SSRCriticalResult;
1020
+ /** Clear collected CSS and optionally restart */
1021
+ clear(restart?: boolean): void;
1022
+ /** Get collection statistics */
1023
+ getStats(): SSRStats;
1024
+ /** @internal Add CSS to collection */
1025
+ _collect(css: string): void;
1026
+ }
1027
+
1028
+ /**
1029
+ * Create an SSR collector for collecting CSS during server-side rendering.
1030
+ *
1031
+ * @example
1032
+ * const ssr = createSSRCollector({ dedupe: true, minify: true })
1033
+ * const html = renderToString(<App />)
1034
+ * const css = ssr.extract()
1035
+ *
1036
+ * // With critical CSS extraction
1037
+ * const { critical, rest } = ssr.extractCritical({ maxSize: 14000 })
1038
+ */
1039
+ export function createSSRCollector(options?: SSRCollectorOptions): SSRCollector;
1040
+
1041
+ // ============================================================================
1042
+ // Animation System (Unified API)
1043
+ // ============================================================================
1044
+
1045
+ /**
1046
+ * Animation keyframe definition
1047
+ */
1048
+ export interface AnimationKeyframe {
1049
+ [property: string]: string | number;
1050
+ }
1051
+
1052
+ /**
1053
+ * Animation options (Web Animations API compatible)
1054
+ */
1055
+ export interface AnimationOptions {
1056
+ duration?: number;
1057
+ easing?: string;
1058
+ delay?: number;
1059
+ iterations?: number | "infinite";
1060
+ fill?: "none" | "forwards" | "backwards" | "both" | "auto";
1061
+ direction?: "normal" | "reverse" | "alternate" | "alternate-reverse";
1062
+ /** Called when animation starts */
1063
+ onStart?: (animation: Animation) => void;
1064
+ /** Called when animation completes */
1065
+ onComplete?: (animation: Animation) => void;
1066
+ /** Called when animation is cancelled */
1067
+ onCancel?: (animation: Animation) => void;
1068
+ /** Custom animation ID */
1069
+ id?: string;
1070
+ }
1071
+
1072
+ /**
1073
+ * Animation preset configuration
1074
+ */
1075
+ export interface AnimationPresetConfig {
1076
+ keyframes: AnimationKeyframe[];
1077
+ options: AnimationOptions;
1078
+ }
1079
+
1080
+ /**
1081
+ * Animation controller returned by animate()
1082
+ */
1083
+ export interface AnimationController {
1084
+ /** Animation ID */
1085
+ readonly id: string | null;
1086
+ /** Native Animation object */
1087
+ readonly animation: Animation | null;
1088
+ /** Current play state */
1089
+ readonly playState: AnimationPlayState;
1090
+ /** Current time in milliseconds */
1091
+ currentTime: number;
1092
+ /** Promise that resolves when animation finishes */
1093
+ readonly finished: Promise<Animation>;
1094
+ /** Whether animation is pending */
1095
+ readonly pending: boolean;
1096
+
1097
+ /** Play the animation */
1098
+ play(): AnimationController;
1099
+ /** Pause the animation */
1100
+ pause(): AnimationController;
1101
+ /** Cancel the animation */
1102
+ cancel(): AnimationController;
1103
+ /** Finish the animation immediately */
1104
+ finish(): AnimationController;
1105
+ /** Reverse the animation */
1106
+ reverse(): AnimationController;
1107
+ /** Seek to specific progress (0-1) */
1108
+ seek(progress: number): AnimationController;
1109
+ /** Set playback speed */
1110
+ setSpeed(rate: number): AnimationController;
1111
+ /** Replay animation from start */
1112
+ replay(): AnimationController;
1113
+ /** Promise interface */
1114
+ then<T>(resolve?: (value: Animation) => T, reject?: (reason: any) => T): Promise<T>;
1115
+ }
1116
+
1117
+ /**
1118
+ * Chain controller for sequential animations
1119
+ */
1120
+ export interface ChainController {
1121
+ /** Current step index */
1122
+ readonly currentStep: number;
1123
+ /** Total number of steps */
1124
+ readonly totalSteps: number;
1125
+ /** Progress (0-1) */
1126
+ readonly progress: number;
1127
+ /** Cancel the chain */
1128
+ cancel(): void;
1129
+ /** Promise that resolves when chain completes */
1130
+ readonly finished: Promise<void>;
1131
+ then<T>(resolve?: () => T, reject?: (reason: any) => T): Promise<T>;
1132
+ }
1133
+
1134
+ /**
1135
+ * Stagger controller for parallel staggered animations
1136
+ */
1137
+ export interface StaggerController {
1138
+ /** Individual animation controllers */
1139
+ readonly controllers: AnimationController[];
1140
+ /** Number of elements */
1141
+ readonly count: number;
1142
+ /** Cancel all animations */
1143
+ cancelAll(): StaggerController;
1144
+ /** Pause all animations */
1145
+ pauseAll(): StaggerController;
1146
+ /** Play all animations */
1147
+ playAll(): StaggerController;
1148
+ /** Reverse all animations */
1149
+ reverseAll(): StaggerController;
1150
+ /** Set speed for all animations */
1151
+ setSpeedAll(rate: number): StaggerController;
1152
+ /** Wait for all animations to complete */
1153
+ waitAll(): Promise<void>;
1154
+ then<T>(resolve?: () => T, reject?: (reason: any) => T): Promise<T>;
1155
+ }
1156
+
1157
+ /**
1158
+ * Stagger options
1159
+ */
1160
+ export interface StaggerOptions extends AnimationOptions {
1161
+ /** Delay between each element (default: 50ms) */
1162
+ delay?: number;
1163
+ /** Direction to start stagger */
1164
+ from?: "start" | "end" | "center" | "random";
1165
+ /** Called for each element */
1166
+ onEach?: (index: number, element: HTMLElement) => void;
1167
+ /** Called when all animations complete */
1168
+ onAllComplete?: () => void;
1169
+ }
1170
+
1171
+ /**
1172
+ * Chain animation item
1173
+ */
1174
+ export type ChainAnimationItem =
1175
+ | string
1176
+ | { name: string; delay?: number; options?: AnimationOptions };
1177
+
1178
+ /**
1179
+ * Animation preset names
1180
+ */
1181
+ export type AnimationPresetName =
1182
+ | "fadeIn" | "fadeOut"
1183
+ | "slideUp" | "slideDown" | "slideLeft" | "slideRight"
1184
+ | "zoomIn" | "zoomOut"
1185
+ | "bounce" | "shake" | "pulse" | "spin"
1186
+ | "flipX" | "flipY"
1187
+ | "enterScale" | "exitScale"
1188
+ | "wiggle" | "heartbeat";
1189
+
1190
+ /**
1191
+ * Easing preset names
1192
+ */
1193
+ export type EasingPresetName =
1194
+ | "linear" | "ease" | "easeIn" | "easeOut" | "easeInOut"
1195
+ | "spring" | "springLight" | "springMedium" | "springHeavy"
1196
+ | "smooth" | "smoothIn" | "smoothOut"
1197
+ | "bounce" | "elastic"
1198
+ | "anticipate" | "overshoot";
1199
+
1200
+ /**
1201
+ * Animation presets object
1202
+ */
1203
+ export const ANIMATION_PRESETS: Record<AnimationPresetName, AnimationPresetConfig>;
1204
+
1205
+ /**
1206
+ * Easing presets object
1207
+ */
1208
+ export const EASING: Record<EasingPresetName, string>;
1209
+
1210
+ /**
1211
+ * Apply animation to an element
1212
+ *
1213
+ * @example
1214
+ * // Using preset
1215
+ * const ctrl = animate(element, 'fadeIn')
1216
+ *
1217
+ * // With options
1218
+ * animate(element, 'slideUp', { duration: 600, easing: 'spring' })
1219
+ *
1220
+ * // With callbacks
1221
+ * animate(element, 'bounce', {
1222
+ * onComplete: () => console.log('done!')
1223
+ * })
1224
+ *
1225
+ * // Control animation
1226
+ * ctrl.pause()
1227
+ * ctrl.reverse()
1228
+ * await ctrl.finished
1229
+ */
1230
+ export function animate(
1231
+ element: HTMLElement,
1232
+ animation: AnimationPresetName | { keyframes: AnimationKeyframe[]; options?: AnimationOptions },
1233
+ options?: AnimationOptions
1234
+ ): AnimationController;
1235
+
1236
+ /**
1237
+ * Chain multiple animations sequentially
1238
+ *
1239
+ * @example
1240
+ * await chain(element, ['fadeIn', 'pulse', 'fadeOut'])
1241
+ *
1242
+ * // With delays
1243
+ * chain(element, [
1244
+ * 'fadeIn',
1245
+ * { name: 'pulse', delay: 100 },
1246
+ * 'fadeOut'
1247
+ * ])
1248
+ */
1249
+ export function chain(
1250
+ element: HTMLElement,
1251
+ animations: ChainAnimationItem[],
1252
+ options?: { onStepComplete?: (step: number, name: string) => void; onComplete?: () => void; onCancel?: (step: number) => void }
1253
+ ): ChainController;
1254
+
1255
+ /**
1256
+ * Apply staggered animation to multiple elements
1257
+ *
1258
+ * @example
1259
+ * // Basic stagger
1260
+ * stagger(listItems, 'slideUp', { delay: 50 })
1261
+ *
1262
+ * // Wait for all
1263
+ * await stagger(items, 'fadeIn').waitAll()
1264
+ *
1265
+ * // From center
1266
+ * stagger(items, 'zoomIn', { from: 'center' })
1267
+ */
1268
+ export function stagger(
1269
+ elements: HTMLElement[] | NodeListOf<HTMLElement>,
1270
+ animation: AnimationPresetName | { keyframes: AnimationKeyframe[]; options?: AnimationOptions },
1271
+ options?: StaggerOptions
1272
+ ): StaggerController;
1273
+
1274
+ /**
1275
+ * Run multiple animations in parallel
1276
+ *
1277
+ * @example
1278
+ * await parallel([
1279
+ * { element: el1, animation: 'fadeIn' },
1280
+ * { element: el2, animation: 'slideUp' }
1281
+ * ])
1282
+ */
1283
+ export function parallel(
1284
+ configs: Array<{ element: HTMLElement; animation: AnimationPresetName | AnimationPresetConfig; options?: AnimationOptions }>
1285
+ ): Promise<AnimationController[]>;
1286
+
1287
+ /**
1288
+ * Apply CSS transition to element
1289
+ *
1290
+ * @example
1291
+ * await transition(element, { opacity: 0, transform: 'scale(0.9)' }, { duration: 300 })
1292
+ */
1293
+ export function transition(
1294
+ element: HTMLElement,
1295
+ properties: Record<string, string | number>,
1296
+ options?: { duration?: number; easing?: string; delay?: number }
1297
+ ): Promise<void>;
1298
+
1299
+ /**
1300
+ * Create CSS keyframes and return animation CSS value
1301
+ *
1302
+ * @example
1303
+ * const animation = createKeyframes('myAnim', {
1304
+ * '0%': { opacity: 0 },
1305
+ * '100%': { opacity: 1 }
1306
+ * })
1307
+ * // → "myAnim 500ms ease-out forwards"
1308
+ */
1309
+ export function createKeyframes(
1310
+ name: string,
1311
+ frames: Record<string, Record<string, string | number>>,
1312
+ options?: { duration?: number; easing?: string; fill?: string; iterations?: number | "infinite"; inject?: boolean }
1313
+ ): string;
1314
+
1315
+ /**
1316
+ * Clear all injected keyframes from document
1317
+ */
1318
+ export function clearKeyframes(): void;
1319
+
1320
+ /**
1321
+ * Cancel all active animations
1322
+ */
1323
+ export function cancelAllAnimations(): void;
1324
+
1325
+ /**
1326
+ * Get count of currently active animations
1327
+ */
1328
+ export function getActiveAnimationCount(): number;
1329
+
1330
+ /**
1331
+ * Register a custom animation preset
1332
+ *
1333
+ * @example
1334
+ * registerPreset('myFade', {
1335
+ * keyframes: [{ opacity: 0 }, { opacity: 1 }],
1336
+ * options: { duration: 400 }
1337
+ * })
1338
+ */
1339
+ export function registerPreset(name: string, config: AnimationPresetConfig): void;
1340
+
1341
+ /**
1342
+ * Get all available preset names
1343
+ */
1344
+ export function getPresetNames(): string[];
1345
+
1346
+ /**
1347
+ * Check if Web Animations API is supported
1348
+ */
1349
+ export function isAnimationSupported(): boolean;
1350
+
372
1351
  // Default export (if needed)
373
1352
  declare const tailwindToStyle: {
374
1353
  tws: typeof tws;
375
1354
  twsx: typeof twsx;
376
1355
  twsxVariants: typeof twsxVariants;
1356
+ twsxClassName: typeof twsxClassName;
1357
+ tw: typeof tw;
377
1358
  debouncedTws: typeof debouncedTws;
378
1359
  debouncedTwsx: typeof debouncedTwsx;
379
1360
  performanceUtils: typeof performanceUtils;
1361
+ // SSR
1362
+ createSSRCollector: typeof createSSRCollector;
1363
+ // Animation
1364
+ animate: typeof animate;
1365
+ chain: typeof chain;
1366
+ stagger: typeof stagger;
1367
+ parallel: typeof parallel;
1368
+ transition: typeof transition;
1369
+ createKeyframes: typeof createKeyframes;
1370
+ ANIMATION_PRESETS: typeof ANIMATION_PRESETS;
1371
+ EASING: typeof EASING;
380
1372
  };
381
1373
 
382
1374
  export default tailwindToStyle;