@mks2508/mks-ui 0.2.1 → 0.3.2

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 (155) hide show
  1. package/dist/react-ui/hooks/Animation/UseAutoHeight.js +7 -7
  2. package/dist/react-ui/hooks/DOM/UseIsInView.js +3 -3
  3. package/dist/react-ui/hooks/Formatting/UseListFormat.d.ts +49 -0
  4. package/dist/react-ui/hooks/Formatting/UseListFormat.d.ts.map +1 -0
  5. package/dist/react-ui/hooks/Formatting/UseListFormat.js +105 -0
  6. package/dist/react-ui/hooks/State/UseControlledState.js +4 -4
  7. package/dist/react-ui/hooks/State/UseDataState.js +5 -5
  8. package/dist/react-ui/hooks/index.d.ts +2 -0
  9. package/dist/react-ui/hooks/index.d.ts.map +1 -1
  10. package/dist/react-ui/hooks/index.js +1 -0
  11. package/dist/react-ui/index.js +22 -1
  12. package/dist/react-ui/lib/get-strict-context.js +3 -3
  13. package/dist/react-ui/primitives/CountingNumber/index.js +3 -3
  14. package/dist/react-ui/primitives/Highlight/index.js +26 -26
  15. package/dist/react-ui/primitives/Slot/index.js +3 -3
  16. package/dist/react-ui/primitives/index.d.ts +1 -0
  17. package/dist/react-ui/primitives/index.d.ts.map +1 -1
  18. package/dist/react-ui/primitives/index.js +18 -0
  19. package/dist/react-ui/primitives/waapi/Morph/Morph.types.d.ts +76 -0
  20. package/dist/react-ui/primitives/waapi/Morph/Morph.types.d.ts.map +1 -0
  21. package/dist/react-ui/primitives/waapi/Morph/MorphContext.d.ts +11 -0
  22. package/dist/react-ui/primitives/waapi/Morph/MorphContext.d.ts.map +1 -0
  23. package/dist/react-ui/primitives/waapi/Morph/MorphContext.js +19 -0
  24. package/dist/react-ui/primitives/waapi/Morph/index.d.ts +23 -0
  25. package/dist/react-ui/primitives/waapi/Morph/index.d.ts.map +1 -0
  26. package/dist/react-ui/primitives/waapi/Morph/index.js +45 -0
  27. package/dist/react-ui/primitives/waapi/Morph/techniques/index.d.ts +12 -0
  28. package/dist/react-ui/primitives/waapi/Morph/techniques/index.d.ts.map +1 -0
  29. package/dist/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.d.ts +38 -0
  30. package/dist/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.d.ts.map +1 -0
  31. package/dist/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.js +78 -0
  32. package/dist/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.d.ts +23 -0
  33. package/dist/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.d.ts.map +1 -0
  34. package/dist/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.js +140 -0
  35. package/dist/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.d.ts +28 -0
  36. package/dist/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.d.ts.map +1 -0
  37. package/dist/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.js +77 -0
  38. package/dist/react-ui/primitives/waapi/Morph/useMorph.d.ts +27 -0
  39. package/dist/react-ui/primitives/waapi/Morph/useMorph.d.ts.map +1 -0
  40. package/dist/react-ui/primitives/waapi/Morph/useMorph.js +86 -0
  41. package/dist/react-ui/primitives/waapi/Reorder/Reorder.types.d.ts +168 -0
  42. package/dist/react-ui/primitives/waapi/Reorder/Reorder.types.d.ts.map +1 -0
  43. package/dist/react-ui/primitives/waapi/Reorder/index.d.ts +25 -0
  44. package/dist/react-ui/primitives/waapi/Reorder/index.d.ts.map +1 -0
  45. package/dist/react-ui/primitives/waapi/Reorder/index.js +186 -0
  46. package/dist/react-ui/primitives/waapi/Reorder/useReorder.d.ts +26 -0
  47. package/dist/react-ui/primitives/waapi/Reorder/useReorder.d.ts.map +1 -0
  48. package/dist/react-ui/primitives/waapi/Reorder/useReorder.js +48 -0
  49. package/dist/react-ui/primitives/waapi/Reorder/useReorderPresence.d.ts +33 -0
  50. package/dist/react-ui/primitives/waapi/Reorder/useReorderPresence.d.ts.map +1 -0
  51. package/dist/react-ui/primitives/waapi/Reorder/useReorderPresence.js +137 -0
  52. package/dist/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.d.ts +47 -0
  53. package/dist/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.d.ts.map +1 -0
  54. package/dist/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.js +72 -0
  55. package/dist/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.d.ts +10 -0
  56. package/dist/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.d.ts.map +1 -0
  57. package/dist/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.types.d.ts +74 -0
  58. package/dist/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.types.d.ts.map +1 -0
  59. package/dist/react-ui/primitives/waapi/SlidingNumber/index.d.ts +33 -0
  60. package/dist/react-ui/primitives/waapi/SlidingNumber/index.d.ts.map +1 -0
  61. package/dist/react-ui/primitives/waapi/SlidingNumber/index.js +354 -0
  62. package/dist/react-ui/primitives/waapi/SlidingText/SlidingText.styles.d.ts +25 -0
  63. package/dist/react-ui/primitives/waapi/SlidingText/SlidingText.styles.d.ts.map +1 -0
  64. package/dist/react-ui/primitives/waapi/SlidingText/SlidingText.types.d.ts +57 -0
  65. package/dist/react-ui/primitives/waapi/SlidingText/SlidingText.types.d.ts.map +1 -0
  66. package/dist/react-ui/primitives/waapi/SlidingText/index.d.ts +26 -0
  67. package/dist/react-ui/primitives/waapi/SlidingText/index.d.ts.map +1 -0
  68. package/dist/react-ui/primitives/waapi/SlidingText/index.js +105 -0
  69. package/dist/react-ui/primitives/waapi/core/animationConstants.d.ts +156 -0
  70. package/dist/react-ui/primitives/waapi/core/animationConstants.d.ts.map +1 -0
  71. package/dist/react-ui/primitives/waapi/core/animationConstants.js +180 -0
  72. package/dist/react-ui/primitives/waapi/core/index.d.ts +16 -0
  73. package/dist/react-ui/primitives/waapi/core/index.d.ts.map +1 -0
  74. package/dist/react-ui/primitives/waapi/core/index.js +5 -0
  75. package/dist/react-ui/primitives/waapi/core/types.d.ts +143 -0
  76. package/dist/react-ui/primitives/waapi/core/types.d.ts.map +1 -0
  77. package/dist/react-ui/primitives/waapi/core/useAnimationOrchestrator.d.ts +32 -0
  78. package/dist/react-ui/primitives/waapi/core/useAnimationOrchestrator.d.ts.map +1 -0
  79. package/dist/react-ui/primitives/waapi/core/useAnimationOrchestrator.js +322 -0
  80. package/dist/react-ui/primitives/waapi/core/useElementRegistry.d.ts +21 -0
  81. package/dist/react-ui/primitives/waapi/core/useElementRegistry.d.ts.map +1 -0
  82. package/dist/react-ui/primitives/waapi/core/useElementRegistry.js +65 -0
  83. package/dist/react-ui/primitives/waapi/core/useFLIPAnimation.d.ts +20 -0
  84. package/dist/react-ui/primitives/waapi/core/useFLIPAnimation.d.ts.map +1 -0
  85. package/dist/react-ui/primitives/waapi/core/useFLIPAnimation.js +99 -0
  86. package/dist/react-ui/primitives/waapi/core/usePositionCapture.d.ts +24 -0
  87. package/dist/react-ui/primitives/waapi/core/usePositionCapture.d.ts.map +1 -0
  88. package/dist/react-ui/primitives/waapi/core/usePositionCapture.js +75 -0
  89. package/dist/react-ui/primitives/waapi/index.d.ts +33 -0
  90. package/dist/react-ui/primitives/waapi/index.d.ts.map +1 -0
  91. package/dist/react-ui/primitives/waapi/index.js +18 -0
  92. package/dist/react-ui/ui/Accordion/index.js +3 -3
  93. package/dist/react-ui/ui/Button/index.js +8 -8
  94. package/dist/react-ui/ui/Combobox/index.js +2 -2
  95. package/dist/react-ui/ui/DataCard/DataCard.styles.d.ts +35 -0
  96. package/dist/react-ui/ui/DataCard/DataCard.styles.d.ts.map +1 -0
  97. package/dist/react-ui/ui/DataCard/DataCard.styles.js +114 -0
  98. package/dist/react-ui/ui/DataCard/DataCard.types.d.ts +135 -0
  99. package/dist/react-ui/ui/DataCard/DataCard.types.d.ts.map +1 -0
  100. package/dist/react-ui/ui/DataCard/index.d.ts +129 -0
  101. package/dist/react-ui/ui/DataCard/index.d.ts.map +1 -0
  102. package/dist/react-ui/ui/DataCard/index.js +276 -0
  103. package/dist/react-ui/ui/Menu/index.js +2 -2
  104. package/dist/react-ui/ui/Switch/index.js +3 -3
  105. package/dist/react-ui/ui/Tabs/index.js +3 -3
  106. package/dist/react-ui/ui/TextFlow/TextFlow.styles.d.ts +16 -0
  107. package/dist/react-ui/ui/TextFlow/TextFlow.styles.d.ts.map +1 -0
  108. package/dist/react-ui/ui/TextFlow/TextFlow.types.d.ts +101 -0
  109. package/dist/react-ui/ui/TextFlow/TextFlow.types.d.ts.map +1 -0
  110. package/dist/react-ui/ui/TextFlow/index.d.ts +26 -0
  111. package/dist/react-ui/ui/TextFlow/index.d.ts.map +1 -0
  112. package/dist/react-ui/ui/TextFlow/index.js +187 -0
  113. package/dist/react-ui/ui/index.d.ts +2 -0
  114. package/dist/react-ui/ui/index.d.ts.map +1 -1
  115. package/dist/react-ui/ui/index.js +3 -0
  116. package/package.json +6 -2
  117. package/src/react-ui/hooks/Formatting/UseListFormat.ts +134 -0
  118. package/src/react-ui/hooks/index.ts +3 -0
  119. package/src/react-ui/primitives/index.ts +3 -0
  120. package/src/react-ui/primitives/waapi/Morph/Morph.types.ts +106 -0
  121. package/src/react-ui/primitives/waapi/Morph/MorphContext.tsx +21 -0
  122. package/src/react-ui/primitives/waapi/Morph/index.tsx +56 -0
  123. package/src/react-ui/primitives/waapi/Morph/techniques/index.ts +12 -0
  124. package/src/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.ts +88 -0
  125. package/src/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.ts +175 -0
  126. package/src/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.ts +86 -0
  127. package/src/react-ui/primitives/waapi/Morph/useMorph.ts +100 -0
  128. package/src/react-ui/primitives/waapi/Reorder/Reorder.types.ts +177 -0
  129. package/src/react-ui/primitives/waapi/Reorder/index.tsx +260 -0
  130. package/src/react-ui/primitives/waapi/Reorder/useReorder.ts +46 -0
  131. package/src/react-ui/primitives/waapi/Reorder/useReorderPresence.ts +208 -0
  132. package/src/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.ts +104 -0
  133. package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.ts +14 -0
  134. package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.types.ts +84 -0
  135. package/src/react-ui/primitives/waapi/SlidingNumber/index.tsx +474 -0
  136. package/src/react-ui/primitives/waapi/SlidingText/SlidingText.styles.ts +32 -0
  137. package/src/react-ui/primitives/waapi/SlidingText/SlidingText.types.ts +69 -0
  138. package/src/react-ui/primitives/waapi/SlidingText/index.tsx +140 -0
  139. package/src/react-ui/primitives/waapi/core/animationConstants.ts +215 -0
  140. package/src/react-ui/primitives/waapi/core/index.ts +53 -0
  141. package/src/react-ui/primitives/waapi/core/types.ts +200 -0
  142. package/src/react-ui/primitives/waapi/core/useAnimationOrchestrator.ts +429 -0
  143. package/src/react-ui/primitives/waapi/core/useElementRegistry.ts +80 -0
  144. package/src/react-ui/primitives/waapi/core/useFLIPAnimation.ts +137 -0
  145. package/src/react-ui/primitives/waapi/core/usePositionCapture.ts +105 -0
  146. package/src/react-ui/primitives/waapi/index.ts +116 -0
  147. package/src/react-ui/styles/animations.css +369 -0
  148. package/src/react-ui/ui/DataCard/DataCard.styles.ts +150 -0
  149. package/src/react-ui/ui/DataCard/DataCard.types.ts +146 -0
  150. package/src/react-ui/ui/DataCard/index.tsx +406 -0
  151. package/src/react-ui/ui/TextFlow/TextFlow.styles.ts +36 -0
  152. package/src/react-ui/ui/TextFlow/TextFlow.types.ts +118 -0
  153. package/src/react-ui/ui/TextFlow/index.tsx +276 -0
  154. package/src/react-ui/ui/index.ts +4 -0
  155. /package/dist/react-ui/components/MorphingPopover/{morphing-popover.module-CgbYV_HS.css → morphing-popover.module-BycNI8nU.css} +0 -0
@@ -0,0 +1,150 @@
1
+ import { cva } from 'class-variance-authority';
2
+ import type { StyleSlots } from '@/core/types';
3
+
4
+ /**
5
+ * Visual regions for: DataCard component family.
6
+ * Each slot maps to: customizable visual region.
7
+ */
8
+ export type DataCardSlot =
9
+ | 'root' // Main card container
10
+ | 'bracket' // Corner bracket decoration
11
+ | 'header' // Top section with title/description
12
+ | 'value' // Animated number display
13
+ | 'label' // Text labels
14
+ | 'toggle' // Switch/checkbox control
15
+ | 'actions' // Action buttons container
16
+ | 'footer'; // Bottom section
17
+
18
+ /**
19
+ * Base style slots for: DataCard.
20
+ * Uses glassmorphism pattern from: Synthwave Dark design system.
21
+ */
22
+ export const dataCardStyles: StyleSlots<DataCardSlot> = {
23
+ root: 'group/data-card relative isolate rounded-xl transition-all duration-300',
24
+
25
+ bracket: 'absolute pointer-events-none transition-opacity duration-300',
26
+
27
+ header: 'flex flex-col gap-1.5 px-5 pt-5 pb-2',
28
+
29
+ value: 'flex items-baseline gap-1 tabular-nums tracking-tight',
30
+
31
+ label: 'text-sm font-medium',
32
+
33
+ toggle: 'flex items-center justify-between gap-3',
34
+
35
+ actions: 'flex items-center gap-2',
36
+
37
+ footer: 'mt-auto px-5 pb-4 pt-2',
38
+ };
39
+
40
+ /**
41
+ * CVA variants for: DataCard root.
42
+ * Combines glassmorphism with Synthwave Dark color scheme.
43
+ */
44
+ export const dataCardVariants = cva(dataCardStyles.root, {
45
+ variants: {
46
+ // Size variants - control padding and spacing
47
+ size: {
48
+ compact: {
49
+ root: 'p-3',
50
+ header: 'gap-1 px-3 pt-3 pb-1.5',
51
+ footer: 'px-3 pb-1.5 pt-1',
52
+ },
53
+ default: {
54
+ root: 'p-4',
55
+ header: 'gap-1.5 px-4 pt-4 pb-2',
56
+ footer: 'px-4 pb-2 pt-2',
57
+ },
58
+ spacious: {
59
+ root: 'p-6',
60
+ header: 'gap-2 px-6 pt-6 pb-3',
61
+ footer: 'px-6 pb-3 pt-2',
62
+ },
63
+ },
64
+
65
+ // Visual variants - control colors and borders
66
+ variant: {
67
+ default: [
68
+ 'bg-white/5',
69
+ 'backdrop-blur-lg',
70
+ 'border border-white/10',
71
+ 'hover:bg-white/10',
72
+ 'shadow-lg shadow-black/20',
73
+ ].join(' '),
74
+
75
+ accent: [
76
+ 'bg-cyan-500/10',
77
+ 'backdrop-blur-lg',
78
+ 'border border-cyan-400/30',
79
+ 'hover:bg-cyan-500/20',
80
+ 'shadow-cyan-500/20 shadow-lg',
81
+ ].join(' '),
82
+
83
+ success: [
84
+ 'bg-emerald-500/10',
85
+ 'backdrop-blur-lg',
86
+ 'border border-emerald-400/30',
87
+ 'hover:bg-emerald-500/20',
88
+ 'shadow-emerald-500/20 shadow-lg',
89
+ ].join(' '),
90
+
91
+ warning: [
92
+ 'bg-amber-500/10',
93
+ 'backdrop-blur-lg',
94
+ 'border border-amber-400/30',
95
+ 'hover:bg-amber-500/20',
96
+ 'shadow-amber-500/20 shadow-lg',
97
+ ].join(' '),
98
+
99
+ destructive: [
100
+ 'bg-red-500/10',
101
+ 'backdrop-blur-lg',
102
+ 'border border-red-400/30',
103
+ 'hover:bg-red-500/20',
104
+ 'shadow-red-500/20 shadow-lg',
105
+ ].join(' '),
106
+ },
107
+
108
+ // Glass effect toggle
109
+ glass: {
110
+ true: [
111
+ 'backdrop-blur-lg',
112
+ 'bg-white/10',
113
+ 'border border-white/20',
114
+ 'shadow-xl',
115
+ ].join(' '),
116
+ false: '',
117
+ },
118
+ },
119
+
120
+ defaultVariants: {
121
+ variant: 'default',
122
+ size: 'default',
123
+ glass: true,
124
+ },
125
+ });
126
+
127
+ /**
128
+ * CVA variants for bracket visibility animation.
129
+ */
130
+ export const bracketVariants = cva(dataCardStyles.bracket, {
131
+ variants: {
132
+ animate: {
133
+ true: 'opacity-60 group-hover/data-card:opacity-100 transition-opacity',
134
+ false: 'opacity-50',
135
+ },
136
+ },
137
+ defaultVariants: {
138
+ animate: true,
139
+ },
140
+ });
141
+
142
+ /**
143
+ * State-specific styles for DataCard interactions.
144
+ */
145
+ export const dataCardStateStyles = {
146
+ hovered: 'scale-[1.02]',
147
+ pressed: 'scale-[0.98]',
148
+ disabled: 'opacity-50 pointer-events-none',
149
+ };
150
+
@@ -0,0 +1,146 @@
1
+ import type { VariantProps } from 'class-variance-authority';
2
+ import type { SlotOverrides } from '@/core/types';
3
+ import type { dataCardVariants, DataCardSlot } from './DataCard.styles';
4
+ export type { DataCardSlot } from './DataCard.styles';
5
+
6
+ /**
7
+ * Available visual variants for DataCard.
8
+ * - 'default' - Standard glassmorphism with neutral borders
9
+ * - 'accent' - Cyan accent with primary glow
10
+ * - 'success' - Green accent for positive data
11
+ * - 'warning' - Amber accent for warnings
12
+ * - 'destructive' - Red accent for critical data
13
+ */
14
+ export type DataCardVariant = 'default' | 'accent' | 'success' | 'warning' | 'destructive';
15
+
16
+ /**
17
+ * Size variants affecting padding and spacing.
18
+ * - 'compact' - Dense layout for dashboards
19
+ * - 'default' - Standard balanced spacing
20
+ * - 'spacious' - More breathing room
21
+ */
22
+ export type DataCardSize = 'compact' | 'default' | 'spacious';
23
+
24
+ /**
25
+ * Interaction state for state-based styling.
26
+ * Similar to Button's IButtonState pattern.
27
+ */
28
+ export interface IDataCardState {
29
+ /** Whether card content is hovered. */
30
+ hovered: boolean;
31
+ /** Whether card is pressed/active. */
32
+ pressed: boolean;
33
+ /** Whether card is disabled. */
34
+ disabled: boolean;
35
+ }
36
+
37
+ /**
38
+ * Configuration for DataCard behavior and animation.
39
+ * Extends IBaseConfig with card-specific settings.
40
+ */
41
+ export interface IDataCardConfig {
42
+ /** Enable/disable corner bracket animations. */
43
+ animateBrackets?: boolean;
44
+ /** Spring stiffness for number counter. */
45
+ counterStiffness?: number;
46
+ /** Spring damping for number counter. */
47
+ counterDamping?: number;
48
+ }
49
+
50
+ /**
51
+ * Props for DataCard root component.
52
+ *
53
+ * @example
54
+ * ```tsx
55
+ * <DataCard variant="accent" size="default">
56
+ * <DataCardValue number={1234} />
57
+ * <DataCardToggle />
58
+ * </DataCard>
59
+ * ```
60
+ */
61
+ export interface IDataCardProps
62
+ extends VariantProps<typeof dataCardVariants> {
63
+ /** Visual style variant. */
64
+ variant?: DataCardVariant;
65
+ /** Size variant affecting spacing. */
66
+ size?: DataCardSize;
67
+ /** Whether card is disabled. */
68
+ disabled?: boolean;
69
+ /** Override classes for card visual regions. */
70
+ slots?: SlotOverrides<DataCardSlot>;
71
+ /** Behavioral and animation configuration. */
72
+ config?: IDataCardConfig;
73
+ /** CSS class or function returning class based on card state. */
74
+ className?: string | ((state: IDataCardState) => string | undefined);
75
+ /** CSS styles or function returning styles based on card state. */
76
+ style?: React.CSSProperties | ((state: IDataCardState) => React.CSSProperties | undefined);
77
+ /** Enable glassmorphism effect (default: true). */
78
+ glass?: boolean;
79
+ /** Show corner brackets (default: true). */
80
+ showBrackets?: boolean;
81
+ /** Child elements. */
82
+ children?: React.ReactNode;
83
+ }
84
+
85
+ /**
86
+ * Props for DataCardValue - displays animated number.
87
+ */
88
+ export interface IDataCardValueProps {
89
+ /** Target number to animate to. */
90
+ number: number;
91
+ /** Label displayed above: number. */
92
+ label?: string;
93
+ /** Unit/suffix displayed after: number. */
94
+ unit?: string;
95
+ /** Decimal places for precision. */
96
+ decimalPlaces?: number;
97
+ /** Pad number with leading zeros. */
98
+ padStart?: boolean;
99
+ }
100
+
101
+ /**
102
+ * Props for DataCardLabel - title/description text.
103
+ */
104
+ export interface IDataCardLabelProps extends React.ComponentProps<'div'> {
105
+ /** Primary title text. */
106
+ title?: string;
107
+ /** Secondary description text. */
108
+ description?: string;
109
+ }
110
+
111
+ /**
112
+ * Props for DataCardToggle - interactive switch element.
113
+ */
114
+ export interface IDataCardToggleProps {
115
+ /** Whether toggle is checked. */
116
+ checked?: boolean;
117
+ /** Callback when toggle state changes. */
118
+ onCheckedChange?: (checked: boolean) => void;
119
+ /** Icon to show when checked (on). */
120
+ checkedIcon?: React.ReactNode;
121
+ /** Icon to show when unchecked (off). */
122
+ uncheckedIcon?: React.ReactNode;
123
+ /** Label for: toggle. */
124
+ label?: string;
125
+ /** Override classes for toggle regions. */
126
+ slots?: SlotOverrides<DataCardSlot>;
127
+ }
128
+
129
+ /**
130
+ * Props for DataCardActions - action button container.
131
+ */
132
+ export interface IDataCardActionsProps extends React.ComponentProps<'div'> {
133
+ /** Alignment of action buttons. */
134
+ align?: 'start' | 'center' | 'end';
135
+ }
136
+
137
+ /**
138
+ * Props for DataCardBracket - decorative corner element.
139
+ */
140
+ export interface IDataCardBracketProps extends React.ComponentProps<'div'> {
141
+ /** Position of: bracket. */
142
+ position: 'tl' | 'tr' | 'bl' | 'br';
143
+ /** Optional variant override for: this bracket. */
144
+ variant?: 'default' | 'accent';
145
+ }
146
+
@@ -0,0 +1,406 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { motion, useMotionValue, useSpring } from 'motion/react';
5
+ import { cn } from '@/react-ui/lib/utils';
6
+ import { getStrictContext } from '@/react-ui/lib/get-strict-context';
7
+ import { useControlledState } from '@/react-ui/hooks/State/UseControlledState';
8
+
9
+ // Import from existing components
10
+ import { CornerBracket } from '@/react-ui/ui/CornerBracket';
11
+ import { CountingNumber } from '@/react-ui/primitives/CountingNumber';
12
+ import { Switch, SwitchThumb } from '@/react-ui/ui/Switch';
13
+
14
+ import { dataCardVariants, dataCardStyles, bracketVariants, dataCardStateStyles } from './DataCard.styles';
15
+ import type { SlotOverrides } from '@/core/types';
16
+ import type {
17
+ IDataCardProps,
18
+ IDataCardValueProps,
19
+ IDataCardLabelProps,
20
+ IDataCardToggleProps,
21
+ IDataCardActionsProps,
22
+ IDataCardBracketProps,
23
+ IDataCardState,
24
+ DataCardSlot,
25
+ } from './DataCard.types';
26
+
27
+ /**
28
+ * Context type for DataCard state management.
29
+ */
30
+ type DataCardContextType = {
31
+ /** Current variant of: card. */
32
+ variant: IDataCardProps['variant'];
33
+ /** Current size of: card. */
34
+ size: IDataCardProps['size'];
35
+ /** Whether card is disabled. */
36
+ disabled: boolean;
37
+ /** Whether glass effect is enabled. */
38
+ glass: boolean;
39
+ /** Slot overrides from parent. */
40
+ slots?: SlotOverrides<DataCardSlot>;
41
+ /** Update interaction state. */
42
+ setState: React.Dispatch<React.SetStateAction<IDataCardState>>;
43
+ };
44
+
45
+ const [DataCardProvider, useDataCard] =
46
+ getStrictContext<DataCardContextType>('DataCardContext');
47
+
48
+ /**
49
+ * DataCard — comprehensive showcase component demonstrating mks-ui patterns.
50
+ *
51
+ * Features:
52
+ * - Slot overrides for customization
53
+ * - State-based styling (hover, pressed, disabled)
54
+ * - CVA variants (size, color variant)
55
+ * - asChild composition pattern
56
+ * - Motion/animation integration
57
+ * - Custom render functions
58
+ * - Form field integration
59
+ * - Icon composition
60
+ * - Glassmorphism effects
61
+ *
62
+ * @example
63
+ * ```tsx
64
+ * <DataCard variant="accent" size="default">
65
+ * <DataCardValue number={1234} />
66
+ * <DataCardToggle />
67
+ * </DataCard>
68
+ * ```
69
+ */
70
+ function DataCard({
71
+ variant = 'default',
72
+ size = 'default',
73
+ disabled = false,
74
+ glass = true,
75
+ showBrackets = true,
76
+ className,
77
+ style,
78
+ slots,
79
+ config,
80
+ children,
81
+ ...props
82
+ }: IDataCardProps) {
83
+ const [state, setState] = React.useState<IDataCardState>({
84
+ hovered: false,
85
+ pressed: false,
86
+ disabled: disabled ?? false,
87
+ });
88
+
89
+ const contextValue: DataCardContextType = React.useMemo(
90
+ () => ({ variant, size, disabled: disabled ?? false, glass, slots, setState }),
91
+ [variant, size, disabled, glass, slots]
92
+ );
93
+
94
+ const computedClassName = React.useMemo(() => {
95
+ if (typeof className === 'function') {
96
+ return className(state);
97
+ }
98
+ return className;
99
+ }, [className, state]);
100
+
101
+ const computedStyle = React.useMemo(() => {
102
+ if (typeof style === 'function') {
103
+ return style(state);
104
+ }
105
+ return style;
106
+ }, [style, state]);
107
+
108
+ return (
109
+ <DataCardProvider value={contextValue}>
110
+ <motion.div
111
+ data-slot="data-card"
112
+ data-variant={variant}
113
+ data-size={size}
114
+ data-disabled={disabled || undefined}
115
+ aria-disabled={disabled || undefined}
116
+ className={cn(
117
+ dataCardVariants({ variant, size, glass }),
118
+ slots?.root,
119
+ computedClassName,
120
+ state.hovered && dataCardStateStyles.hovered,
121
+ state.pressed && dataCardStateStyles.pressed,
122
+ disabled && dataCardStateStyles.disabled
123
+ )}
124
+ style={computedStyle}
125
+ onHoverStart={() => setState((prev) => ({ ...prev, hovered: true }))}
126
+ onHoverEnd={() => setState((prev) => ({ ...prev, hovered: false }))}
127
+ onTapStart={() => setState((prev) => ({ ...prev, pressed: true }))}
128
+ onTap={() => setState((prev) => ({ ...prev, pressed: false }))}
129
+ onTapCancel={() => setState((prev) => ({ ...prev, pressed: false }))}
130
+ {...props}
131
+ >
132
+ {showBrackets && (
133
+ <>
134
+ <DataCardBracket
135
+ position="tl"
136
+ variant={variant === 'accent' ? 'accent' : 'default'}
137
+ />
138
+ <DataCardBracket
139
+ position="tr"
140
+ variant={variant === 'accent' ? 'accent' : 'default'}
141
+ />
142
+ <DataCardBracket
143
+ position="bl"
144
+ variant={variant === 'accent' ? 'accent' : 'default'}
145
+ />
146
+ <DataCardBracket
147
+ position="br"
148
+ variant={variant === 'accent' ? 'accent' : 'default'}
149
+ />
150
+ </>
151
+ )}
152
+ {children}
153
+ </motion.div>
154
+ </DataCardProvider>
155
+ );
156
+ }
157
+
158
+ /**
159
+ * DataCardValue — displays animated number with CountingNumber.
160
+ *
161
+ * @example
162
+ * ```tsx
163
+ * <DataCardValue
164
+ * number={1234}
165
+ * label="Active Users"
166
+ * unit="users"
167
+ * />
168
+ * ```
169
+ */
170
+ function DataCardValue({
171
+ number,
172
+ label,
173
+ unit,
174
+ decimalPlaces = 0,
175
+ padStart = false,
176
+ }: IDataCardValueProps) {
177
+ const { variant, size } = useDataCard();
178
+
179
+ return (
180
+ <div data-slot="data-card-value" className={cn(dataCardStyles.value)}>
181
+ {label && (
182
+ <span className="text-muted-foreground text-xs uppercase tracking-wider font-mono">
183
+ {label}
184
+ </span>
185
+ )}
186
+ <CountingNumber
187
+ number={number}
188
+ decimalPlaces={decimalPlaces}
189
+ padStart={padStart}
190
+ transition={{
191
+ stiffness: variant === 'accent' ? 150 : 90,
192
+ damping: variant === 'accent' ? 20 : 10,
193
+ }}
194
+ className={
195
+ size === 'compact'
196
+ ? 'text-3xl font-bold'
197
+ : size === 'spacious'
198
+ ? 'text-5xl font-bold'
199
+ : 'text-4xl font-bold'
200
+ }
201
+ />
202
+ {unit && (
203
+ <span className="text-muted-foreground text-lg ml-1">{unit}</span>
204
+ )}
205
+ </div>
206
+ );
207
+ }
208
+
209
+ /**
210
+ * DataCardLabel — displays title and description.
211
+ *
212
+ * @example
213
+ * ```tsx
214
+ * <DataCardLabel
215
+ * title="Revenue"
216
+ * description="This month"
217
+ * />
218
+ * ```
219
+ */
220
+ function DataCardLabel({
221
+ title,
222
+ description,
223
+ className,
224
+ ...props
225
+ }: IDataCardLabelProps) {
226
+ const { slots } = useDataCard();
227
+
228
+ return (
229
+ <div
230
+ data-slot="data-card-label"
231
+ className={cn(
232
+ dataCardStyles.label,
233
+ slots?.label,
234
+ className
235
+ )}
236
+ {...props}
237
+ >
238
+ {title && (
239
+ <h3 className="text-foreground font-semibold">{title}</h3>
240
+ )}
241
+ {description && (
242
+ <p className="text-muted-foreground text-sm">{description}</p>
243
+ )}
244
+ </div>
245
+ );
246
+ }
247
+
248
+ /**
249
+ * DataCardToggle — interactive switch element.
250
+ *
251
+ * Uses asChild pattern for composition with Switch component.
252
+ *
253
+ * @example
254
+ * ```tsx
255
+ * <DataCardToggle
256
+ * checked={enabled}
257
+ * onCheckedChange={setEnabled}
258
+ * label="Enable notifications"
259
+ * checkedIcon={<BellIcon />}
260
+ * uncheckedIcon={<BellOffIcon />}
261
+ * />
262
+ * ```
263
+ */
264
+ function DataCardToggle({
265
+ checked,
266
+ onCheckedChange,
267
+ checkedIcon,
268
+ uncheckedIcon,
269
+ label,
270
+ }: IDataCardToggleProps) {
271
+ const { disabled, variant, size, glass, slots } = useDataCard();
272
+
273
+ return (
274
+ <div data-slot="data-card-toggle" className={cn(dataCardStyles.toggle, slots?.toggle)}>
275
+ {label && <span className="text-sm text-muted-foreground">{label}</span>}
276
+ <Switch
277
+ checked={checked}
278
+ onCheckedChange={onCheckedChange}
279
+ disabled={disabled}
280
+ >
281
+ <SwitchThumb />
282
+ {checkedIcon && (
283
+ <div className="text-primary">{checkedIcon}</div>
284
+ )}
285
+ {!checkedIcon && (
286
+ <div className="text-muted-foreground">{uncheckedIcon}</div>
287
+ )}
288
+ </Switch>
289
+ </div>
290
+ );
291
+ }
292
+
293
+ /**
294
+ * DataCardActions — container for action buttons.
295
+ *
296
+ * @example
297
+ * ```tsx
298
+ * <DataCardActions align="end">
299
+ * <Button size="sm">Edit</Button>
300
+ * <Button size="sm" variant="ghost">Delete</Button>
301
+ * </DataCardActions>
302
+ * ```
303
+ */
304
+ function DataCardActions({
305
+ align = 'end',
306
+ className,
307
+ children,
308
+ ...props
309
+ }: IDataCardActionsProps) {
310
+ const { variant, size, glass, slots } = useDataCard();
311
+
312
+ return (
313
+ <div
314
+ data-slot="data-card-actions"
315
+ data-align={align}
316
+ className={cn(
317
+ dataCardStyles.actions,
318
+ align === 'center' && 'justify-center',
319
+ align === 'start' && 'justify-start',
320
+ align === 'end' && 'justify-end',
321
+ slots?.actions,
322
+ className
323
+ )}
324
+ {...props}
325
+ >
326
+ {children}
327
+ </div>
328
+ );
329
+ }
330
+
331
+ /**
332
+ * DataCardBracket — decorative corner bracket.
333
+ *
334
+ * Wraps CornerBracket with motion animations.
335
+ *
336
+ * @example
337
+ * ```tsx
338
+ * <DataCardBracket position="tl" variant="accent" />
339
+ * ```
340
+ */
341
+ function DataCardBracket({
342
+ position,
343
+ variant = 'default',
344
+ className,
345
+ }: IDataCardBracketProps) {
346
+ const { size, glass, slots } = useDataCard();
347
+
348
+ const sizeMap = {
349
+ compact: 16,
350
+ default: 20,
351
+ spacious: 24,
352
+ } as const;
353
+
354
+ return (
355
+ <div className={cn(dataCardStyles.bracket, slots?.bracket, className)}>
356
+ <CornerBracket
357
+ position={position}
358
+ variant={variant}
359
+ size={sizeMap[size ?? 'default']}
360
+ />
361
+ </div>
362
+ );
363
+ }
364
+
365
+ /**
366
+ * Hook to access DataCard context.
367
+ * Must be used within DataCard provider.
368
+ *
369
+ * @returns The current DataCard context
370
+ *
371
+ * @example
372
+ * ```tsx
373
+ * function MyComponent() {
374
+ * const { variant, size, disabled } = useDataCard();
375
+ * return <div>Current variant: {variant}</div>;
376
+ * }
377
+ * ```
378
+ */
379
+ export { useDataCard };
380
+
381
+ export {
382
+ DataCard,
383
+ DataCardValue,
384
+ DataCardLabel,
385
+ DataCardToggle,
386
+ DataCardActions,
387
+ DataCardBracket,
388
+ dataCardVariants,
389
+ };
390
+
391
+ // Re-export types
392
+ export type {
393
+ IDataCardProps,
394
+ IDataCardValueProps,
395
+ IDataCardLabelProps,
396
+ IDataCardToggleProps,
397
+ IDataCardActionsProps,
398
+ IDataCardBracketProps,
399
+ IDataCardState,
400
+ IDataCardConfig,
401
+ DataCardVariant,
402
+ DataCardSize,
403
+ DataCardSlot,
404
+ } from './DataCard.types';
405
+
406
+ export { dataCardStyles } from './DataCard.styles';