flikkui 0.2.0-beta.1 → 0.2.0-beta.4

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 (215) hide show
  1. package/README.md +12 -539
  2. package/dist/components/ai/PromptInput/PromptInput.js +94 -4
  3. package/dist/components/ai/PromptSuggestions/PromptSuggestion.d.ts +27 -0
  4. package/dist/components/ai/PromptSuggestions/PromptSuggestion.js +62 -0
  5. package/dist/components/ai/PromptSuggestions/PromptSuggestion.theme.d.ts +10 -0
  6. package/dist/components/ai/PromptSuggestions/PromptSuggestion.theme.js +12 -0
  7. package/dist/components/ai/PromptSuggestions/PromptSuggestion.types.d.ts +53 -0
  8. package/dist/components/ai/PromptSuggestions/index.d.ts +4 -2
  9. package/dist/components/ai/index.d.ts +2 -12
  10. package/dist/components/charts/ActivityRings/ActivityRings.js +70 -58
  11. package/dist/components/charts/ActivityRings/ActivityRings.theme.js +0 -1
  12. package/dist/components/charts/ActivityRings/ActivityRings.types.d.ts +17 -0
  13. package/dist/components/charts/BarChart/BarChart.js +8 -4
  14. package/dist/components/charts/BarChart/BarChart.types.d.ts +14 -0
  15. package/dist/components/charts/DonutChart/DonutChart.js +11 -8
  16. package/dist/components/charts/DonutChart/DonutChart.theme.d.ts +3 -0
  17. package/dist/components/charts/DonutChart/DonutChart.theme.js +5 -4
  18. package/dist/components/charts/DonutChart/donut-utils.d.ts +5 -0
  19. package/dist/components/charts/DonutChart/donut-utils.js +26 -1
  20. package/dist/components/charts/Heatmap/Heatmap.theme.js +2 -2
  21. package/dist/components/charts/shared/ChartAxis/XAxis.d.ts +2 -2
  22. package/dist/components/charts/shared/ChartAxis/XAxis.js +4 -4
  23. package/dist/components/charts/shared/ChartAxis/YAxis.d.ts +2 -2
  24. package/dist/components/charts/shared/ChartAxis/YAxis.js +8 -7
  25. package/dist/components/charts/shared/ChartGrid/HorizontalGrid.d.ts +1 -1
  26. package/dist/components/charts/shared/ChartGrid/HorizontalGrid.js +2 -2
  27. package/dist/components/charts/theme/chart.theme.d.ts +1 -1
  28. package/dist/components/charts/theme/chart.theme.js +39 -39
  29. package/dist/components/core/Accordion/Accordion.d.ts +1 -1
  30. package/dist/components/core/Accordion/Accordion.js +2 -2
  31. package/dist/components/core/Accordion/Accordion.types.d.ts +8 -0
  32. package/dist/components/core/Badge/Badge.js +11 -15
  33. package/dist/components/core/Badge/Badge.theme.js +7 -21
  34. package/dist/components/core/Badge/Badge.types.d.ts +9 -1
  35. package/dist/components/core/Button/Button.js +2 -2
  36. package/dist/components/core/Button/Button.theme.js +1 -1
  37. package/dist/components/core/Button/Button.types.d.ts +8 -0
  38. package/dist/components/core/Card/Card.js +8 -2
  39. package/dist/components/core/Card/Card.theme.js +1 -1
  40. package/dist/components/core/Card/Card.types.d.ts +24 -1
  41. package/dist/components/core/Drawer/Drawer.d.ts +1 -1
  42. package/dist/components/core/Drawer/Drawer.js +10 -40
  43. package/dist/components/core/Drawer/Drawer.theme.js +2 -1
  44. package/dist/components/core/Drawer/Drawer.types.d.ts +8 -0
  45. package/dist/components/core/Dropdown/Dropdown.d.ts +1 -1
  46. package/dist/components/core/Dropdown/Dropdown.js +2 -2
  47. package/dist/components/core/Dropdown/Dropdown.types.d.ts +8 -0
  48. package/dist/components/core/Metric/Metric.d.ts +1 -1
  49. package/dist/components/core/Metric/Metric.js +9 -5
  50. package/dist/components/core/Metric/Metric.theme.d.ts +1 -1
  51. package/dist/components/core/Metric/Metric.theme.js +38 -28
  52. package/dist/components/core/Metric/Metric.types.d.ts +27 -8
  53. package/dist/components/core/Modal/Modal.d.ts +1 -1
  54. package/dist/components/core/Modal/Modal.js +17 -40
  55. package/dist/components/core/Modal/Modal.theme.js +8 -3
  56. package/dist/components/core/Modal/Modal.types.d.ts +18 -0
  57. package/dist/components/core/Modal/index.d.ts +1 -1
  58. package/dist/components/core/Notification/Notification.js +67 -0
  59. package/dist/components/core/Pill/Pill.d.ts +6 -11
  60. package/dist/components/core/Pill/Pill.theme.d.ts +2 -2
  61. package/dist/components/core/Pill/Pill.types.d.ts +9 -22
  62. package/dist/components/core/Pill/index.d.ts +1 -1
  63. package/dist/components/core/Popover/Popover.d.ts +1 -1
  64. package/dist/components/core/Popover/Popover.js +2 -2
  65. package/dist/components/core/Popover/Popover.types.d.ts +8 -0
  66. package/dist/components/core/Progress/Progress.d.ts +28 -0
  67. package/dist/components/core/Progress/Progress.js +114 -0
  68. package/dist/components/core/Progress/Progress.theme.d.ts +5 -0
  69. package/dist/components/core/Progress/Progress.theme.js +33 -0
  70. package/dist/components/core/Progress/Progress.types.d.ts +92 -0
  71. package/dist/components/core/Progress/index.d.ts +2 -0
  72. package/dist/components/core/Tabs/Tabs.js +2 -2
  73. package/dist/components/core/Tabs/Tabs.types.d.ts +8 -0
  74. package/dist/components/core/Tag/Tag.animations.d.ts +3 -0
  75. package/dist/components/core/Tag/Tag.animations.js +31 -0
  76. package/dist/components/core/Tag/Tag.d.ts +14 -0
  77. package/dist/components/core/Tag/Tag.js +45 -0
  78. package/dist/components/core/Tag/Tag.theme.d.ts +2 -0
  79. package/dist/components/core/Tag/Tag.theme.js +21 -0
  80. package/dist/components/core/Tag/Tag.types.d.ts +40 -0
  81. package/dist/components/core/Tag/index.d.ts +3 -0
  82. package/dist/components/core/Tooltip/Tooltip.d.ts +1 -1
  83. package/dist/components/core/Tooltip/Tooltip.js +3 -3
  84. package/dist/components/core/Tooltip/Tooltip.theme.js +1 -1
  85. package/dist/components/core/Tooltip/Tooltip.types.d.ts +17 -0
  86. package/dist/components/core/index.d.ts +2 -1
  87. package/dist/components/core/index.js +3 -2
  88. package/dist/components/effects/CustomCursor/CustomCursor.d.ts +0 -13
  89. package/dist/components/effects/CustomCursor/CustomCursor.js +26 -2
  90. package/dist/components/effects/CustomCursor/CustomCursor.theme.js +12 -1
  91. package/dist/components/effects/CustomCursor/CustomCursor.types.d.ts +14 -1
  92. package/dist/components/forms/Combobox/Combobox.d.ts +25 -0
  93. package/dist/components/forms/Combobox/Combobox.js +412 -0
  94. package/dist/components/forms/Combobox/Combobox.theme.d.ts +6 -0
  95. package/dist/components/forms/Combobox/Combobox.theme.js +60 -0
  96. package/dist/components/forms/Combobox/Combobox.types.d.ts +111 -0
  97. package/dist/components/forms/Combobox/index.d.ts +3 -0
  98. package/dist/components/forms/FileUpload/FileUpload.js +68 -0
  99. package/dist/components/forms/Input/Input.js +25 -28
  100. package/dist/components/forms/Input/inputMasks.d.ts +15 -0
  101. package/dist/components/forms/Input/inputMasks.js +72 -1
  102. package/dist/components/forms/InputTag/InputTag.d.ts +40 -0
  103. package/dist/components/forms/InputTag/InputTag.js +491 -0
  104. package/dist/components/forms/InputTag/InputTag.theme.d.ts +2 -0
  105. package/dist/components/forms/InputTag/InputTag.theme.js +16 -0
  106. package/dist/components/forms/InputTag/InputTag.types.d.ts +107 -0
  107. package/dist/components/forms/InputTag/index.d.ts +3 -0
  108. package/dist/components/forms/Select/Select.d.ts +101 -2
  109. package/dist/components/forms/Select/Select.js +128 -132
  110. package/dist/components/forms/Select/Select.theme.js +10 -14
  111. package/dist/components/forms/Select/Select.types.d.ts +6 -2
  112. package/dist/components/forms/Select/index.d.ts +7 -4
  113. package/dist/components/forms/Select/useSelectState.d.ts +66 -0
  114. package/dist/components/forms/Select/useSelectState.js +134 -0
  115. package/dist/components/forms/SelectExpand/SelectExpand.animations.d.ts +20 -0
  116. package/dist/components/forms/SelectExpand/SelectExpand.animations.js +74 -0
  117. package/dist/components/forms/SelectExpand/SelectExpand.d.ts +9 -0
  118. package/dist/components/forms/SelectExpand/SelectExpand.js +223 -0
  119. package/dist/components/forms/SelectExpand/SelectExpand.theme.d.ts +5 -0
  120. package/dist/components/forms/SelectExpand/SelectExpand.theme.js +74 -0
  121. package/dist/components/forms/SelectExpand/SelectExpand.types.d.ts +126 -0
  122. package/dist/components/forms/SelectExpand/index.d.ts +4 -0
  123. package/dist/components/forms/Switch/Switch.js +3 -3
  124. package/dist/components/forms/Switch/Switch.theme.d.ts +1 -1
  125. package/dist/components/forms/Switch/Switch.theme.js +2 -2
  126. package/dist/components/forms/TimePicker/TimePicker.animations.d.ts +0 -46
  127. package/dist/components/forms/TimePicker/TimePicker.d.ts +15 -6
  128. package/dist/components/forms/TimePicker/TimePicker.js +285 -124
  129. package/dist/components/forms/TimePicker/TimePicker.theme.d.ts +1 -1
  130. package/dist/components/forms/TimePicker/TimePicker.theme.js +39 -22
  131. package/dist/components/forms/TimePicker/TimePicker.types.d.ts +88 -34
  132. package/dist/components/forms/TimePicker/TimePickerContent.d.ts +7 -10
  133. package/dist/components/forms/TimePicker/TimePickerContent.js +149 -16
  134. package/dist/components/forms/TimePicker/TimePickerTrigger.d.ts +3 -3
  135. package/dist/components/forms/TimePicker/TimePickerTrigger.js +22 -19
  136. package/dist/components/forms/TimePicker/WheelColumn.d.ts +14 -0
  137. package/dist/components/forms/TimePicker/WheelColumn.js +90 -0
  138. package/dist/components/forms/TimePicker/index.d.ts +4 -1
  139. package/dist/components/forms/TimePicker/useWheelPicker.d.ts +37 -0
  140. package/dist/components/forms/TimePicker/useWheelPicker.js +138 -0
  141. package/dist/components/forms/forms.theme.d.ts +14 -0
  142. package/dist/components/forms/forms.theme.js +31 -0
  143. package/dist/components/forms/index.d.ts +9 -3
  144. package/dist/components/forms/index.js +73 -2
  145. package/dist/hooks/index.d.ts +0 -4
  146. package/dist/icons/Icon.d.ts +7 -0
  147. package/dist/icons/Icon.js +6 -2
  148. package/dist/index.js +62 -63
  149. package/dist/styles.css +1 -1
  150. package/dist/utils/index.d.ts +0 -1
  151. package/dist/utils/optimisticErrors.js +1 -70
  152. package/package.json +1 -1
  153. package/dist/components/ai/EditingIndicator/EditingIndicator.animations.d.ts +0 -31
  154. package/dist/components/ai/EditingIndicator/EditingIndicator.animations.js +0 -115
  155. package/dist/components/ai/EditingIndicator/EditingIndicator.d.ts +0 -35
  156. package/dist/components/ai/EditingIndicator/EditingIndicator.js +0 -94
  157. package/dist/components/ai/EditingIndicator/EditingIndicator.theme.d.ts +0 -2
  158. package/dist/components/ai/EditingIndicator/EditingIndicator.theme.js +0 -13
  159. package/dist/components/ai/EditingIndicator/EditingIndicator.types.d.ts +0 -54
  160. package/dist/components/ai/EditingIndicator/index.d.ts +0 -9
  161. package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.d.ts +0 -3
  162. package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.js +0 -126
  163. package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.theme.d.ts +0 -2
  164. package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.theme.js +0 -8
  165. package/dist/components/ai/GenerativeRenderer/GenerativeRenderer.types.d.ts +0 -45
  166. package/dist/components/ai/GenerativeRenderer/index.d.ts +0 -3
  167. package/dist/components/ai/PresenceIndicator/PresenceIndicator.animations.d.ts +0 -17
  168. package/dist/components/ai/PresenceIndicator/PresenceIndicator.animations.js +0 -56
  169. package/dist/components/ai/PresenceIndicator/PresenceIndicator.d.ts +0 -38
  170. package/dist/components/ai/PresenceIndicator/PresenceIndicator.js +0 -110
  171. package/dist/components/ai/PresenceIndicator/PresenceIndicator.theme.d.ts +0 -2
  172. package/dist/components/ai/PresenceIndicator/PresenceIndicator.theme.js +0 -13
  173. package/dist/components/ai/PresenceIndicator/PresenceIndicator.types.d.ts +0 -53
  174. package/dist/components/ai/PresenceIndicator/index.d.ts +0 -8
  175. package/dist/components/ai/PresenceProvider/PresenceContext.d.ts +0 -24
  176. package/dist/components/ai/PresenceProvider/PresenceContext.js +0 -34
  177. package/dist/components/ai/PresenceProvider/PresenceProvider.d.ts +0 -32
  178. package/dist/components/ai/PresenceProvider/PresenceProvider.js +0 -321
  179. package/dist/components/ai/PresenceProvider/PresenceProvider.types.d.ts +0 -140
  180. package/dist/components/ai/PresenceProvider/adapters/MockAdapter.d.ts +0 -102
  181. package/dist/components/ai/PresenceProvider/adapters/MockAdapter.js +0 -331
  182. package/dist/components/ai/PresenceProvider/adapters/PresenceAdapter.d.ts +0 -93
  183. package/dist/components/ai/PresenceProvider/adapters/SupabaseAdapter.d.ts +0 -134
  184. package/dist/components/ai/PresenceProvider/adapters/WebSocketAdapter.d.ts +0 -149
  185. package/dist/components/ai/PresenceProvider/adapters/index.d.ts +0 -11
  186. package/dist/components/ai/PresenceProvider/index.d.ts +0 -10
  187. package/dist/components/ai/PromptSuggestions/PromptSuggestions.d.ts +0 -27
  188. package/dist/components/ai/PromptSuggestions/PromptSuggestions.js +0 -61
  189. package/dist/components/ai/PromptSuggestions/PromptSuggestions.types.d.ts +0 -65
  190. package/dist/components/ai/VersionSlider/VersionSlider.d.ts +0 -3
  191. package/dist/components/ai/VersionSlider/VersionSlider.js +0 -97
  192. package/dist/components/ai/VersionSlider/VersionSlider.theme.d.ts +0 -2
  193. package/dist/components/ai/VersionSlider/VersionSlider.theme.js +0 -18
  194. package/dist/components/ai/VersionSlider/VersionSlider.types.d.ts +0 -77
  195. package/dist/components/ai/VersionSlider/index.d.ts +0 -3
  196. package/dist/components/core/Pill/Pill.animations.js +0 -25
  197. package/dist/components/core/Pill/Pill.js +0 -145
  198. package/dist/components/core/Pill/Pill.theme.js +0 -65
  199. package/dist/components/core/RetryBoundary/RetryBoundary.d.ts +0 -35
  200. package/dist/components/core/RetryBoundary/RetryBoundary.js +0 -154
  201. package/dist/components/core/RetryBoundary/RetryBoundary.theme.d.ts +0 -2
  202. package/dist/components/core/RetryBoundary/RetryBoundary.theme.js +0 -7
  203. package/dist/components/core/RetryBoundary/RetryBoundary.types.d.ts +0 -51
  204. package/dist/components/core/RetryBoundary/index.d.ts +0 -3
  205. package/dist/components/forms/OptimisticForm/OptimisticForm.d.ts +0 -33
  206. package/dist/components/forms/OptimisticForm/OptimisticForm.js +0 -87
  207. package/dist/components/forms/OptimisticForm/OptimisticForm.theme.d.ts +0 -2
  208. package/dist/components/forms/OptimisticForm/OptimisticForm.theme.js +0 -8
  209. package/dist/components/forms/OptimisticForm/OptimisticForm.types.d.ts +0 -74
  210. package/dist/components/forms/OptimisticForm/index.d.ts +0 -3
  211. package/dist/hooks/useOptimisticMutation.d.ts +0 -109
  212. package/dist/hooks/useOptimisticMutation.js +0 -171
  213. package/dist/hooks/usePresence.d.ts +0 -88
  214. package/dist/utils/presenceUtils.d.ts +0 -66
  215. package/dist/utils/presenceUtils.js +0 -107
@@ -1,154 +0,0 @@
1
- import React__default, { Component, useState, useEffect } from 'react';
2
- import { XMarkIcon, ArrowPathIcon } from '@heroicons/react/24/outline';
3
- import { Button } from '../Button/Button.js';
4
- import { shouldRetry, calculateRetryDelay } from '../../../utils/retryUtils.js';
5
- import { normalizeError } from '../../../utils/streamingErrors.js';
6
- import { retryBoundaryTheme } from './RetryBoundary.theme.js';
7
-
8
- /**
9
- * RetryBoundary Component
10
- * Error boundary with exponential backoff retry
11
- */
12
- /**
13
- * Default fallback UI component
14
- */
15
- const DefaultFallback = ({ error, attempt, maxAttempts, retryIn, retry, reset, }) => {
16
- const theme = retryBoundaryTheme;
17
- const hasMoreRetries = attempt < maxAttempts;
18
- return (React__default.createElement("div", { className: theme.container },
19
- React__default.createElement("div", { className: "flex flex-col items-start gap-2 text-[var(--color-danger)]" },
20
- React__default.createElement("div", { className: "text-2xl rounded-full p-3 mb-3 w-fit glass-effect shadow-xl shadow-black/5" },
21
- React__default.createElement(XMarkIcon, { className: "size-5" })),
22
- React__default.createElement("span", { className: "text-base font-semibold" }, "Something went wrong")),
23
- React__default.createElement("p", { className: theme.errorMessage }, error.message),
24
- retryIn > 0 && hasMoreRetries && (React__default.createElement("p", { className: theme.countdown },
25
- "Retrying in ",
26
- retryIn,
27
- "s... (Attempt ",
28
- attempt + 1,
29
- " of ",
30
- maxAttempts,
31
- ")")),
32
- React__default.createElement("div", { className: "flex items-center gap-2 mt-6" },
33
- hasMoreRetries ? (React__default.createElement(Button, { onClick: retry, size: "sm", variant: "filled", color: "dark" },
34
- React__default.createElement(ArrowPathIcon, { className: "size-4" }),
35
- "Retry Now")) : (React__default.createElement("p", { className: "text-xs text-[var(--color-text-muted)]" }, "Max retries reached")),
36
- React__default.createElement(Button, { onClick: reset, size: "sm", color: "neutral" }, "Dismiss"))));
37
- };
38
- /**
39
- * Wrapper component to handle retry countdown and state
40
- */
41
- const RetryFallbackWrapper = ({ error, attempt, maxAttempts, retryDelay, onRetry, onReset, fallback, className, }) => {
42
- const [countdown, setCountdown] = useState(Math.ceil(retryDelay / 1000));
43
- const hasMoreRetries = attempt < maxAttempts;
44
- // Countdown timer
45
- useEffect(() => {
46
- if (!hasMoreRetries || retryDelay === 0)
47
- return;
48
- setCountdown(Math.ceil(retryDelay / 1000));
49
- const interval = setInterval(() => {
50
- setCountdown((prev) => {
51
- if (prev <= 1) {
52
- clearInterval(interval);
53
- onRetry();
54
- return 0;
55
- }
56
- return prev - 1;
57
- });
58
- }, 1000);
59
- return () => clearInterval(interval);
60
- }, [retryDelay, hasMoreRetries, onRetry]);
61
- const fallbackProps = {
62
- error,
63
- attempt,
64
- maxAttempts,
65
- retryIn: countdown,
66
- retry: onRetry,
67
- reset: onReset,
68
- };
69
- // Custom fallback
70
- if (fallback) {
71
- if (typeof fallback === "function") {
72
- return React__default.createElement("div", { className: className }, fallback(fallbackProps));
73
- }
74
- return React__default.createElement("div", { className: className }, fallback);
75
- }
76
- // Default fallback
77
- return (React__default.createElement("div", { className: className },
78
- React__default.createElement(DefaultFallback, { ...fallbackProps })));
79
- };
80
- /**
81
- * RetryBoundary - Error boundary with exponential backoff retry
82
- *
83
- * @example
84
- * <RetryBoundary
85
- * retry={{ maxAttempts: 3, initialDelay: 1000 }}
86
- * onMaxRetriesReached={(error) => logError(error)}
87
- * >
88
- * <AsyncComponent />
89
- * </RetryBoundary>
90
- */
91
- class RetryBoundary extends Component {
92
- constructor(props) {
93
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
94
- super(props);
95
- this.handleRetry = () => {
96
- const { onRetry } = this.props;
97
- const newAttempt = this.state.attempt + 1;
98
- onRetry === null || onRetry === void 0 ? void 0 : onRetry(newAttempt);
99
- this.setState({
100
- error: null,
101
- attempt: newAttempt,
102
- retryDelay: 0,
103
- });
104
- };
105
- this.handleReset = () => {
106
- this.setState({
107
- error: null,
108
- attempt: 0,
109
- retryDelay: 0,
110
- });
111
- };
112
- this.state = {
113
- error: null,
114
- attempt: 0,
115
- retryDelay: 0,
116
- };
117
- this.retryConfig = {
118
- maxAttempts: (_b = (_a = props.retry) === null || _a === void 0 ? void 0 : _a.maxAttempts) !== null && _b !== void 0 ? _b : 3,
119
- initialDelay: (_d = (_c = props.retry) === null || _c === void 0 ? void 0 : _c.initialDelay) !== null && _d !== void 0 ? _d : 1000,
120
- backoffMultiplier: (_f = (_e = props.retry) === null || _e === void 0 ? void 0 : _e.backoffMultiplier) !== null && _f !== void 0 ? _f : 2,
121
- maxDelay: (_h = (_g = props.retry) === null || _g === void 0 ? void 0 : _g.maxDelay) !== null && _h !== void 0 ? _h : 10000,
122
- shouldRetry: (_j = props.retry) === null || _j === void 0 ? void 0 : _j.shouldRetry,
123
- };
124
- }
125
- static getDerivedStateFromError(error) {
126
- return { error };
127
- }
128
- componentDidCatch(error, errorInfo) {
129
- const { attempt } = this.state;
130
- const { onError, onMaxRetriesReached } = this.props;
131
- // Normalize error for retry check
132
- const streamingError = normalizeError(error);
133
- const canRetry = shouldRetry(streamingError, attempt, this.retryConfig);
134
- onError === null || onError === void 0 ? void 0 : onError(error, attempt);
135
- if (canRetry) {
136
- const delay = calculateRetryDelay(attempt, this.retryConfig);
137
- this.setState({ retryDelay: delay });
138
- }
139
- else {
140
- onMaxRetriesReached === null || onMaxRetriesReached === void 0 ? void 0 : onMaxRetriesReached(error);
141
- }
142
- }
143
- render() {
144
- var _a;
145
- const { children, fallback, className } = this.props;
146
- const { error, attempt, retryDelay } = this.state;
147
- if (error) {
148
- return (React__default.createElement(RetryFallbackWrapper, { error: error, attempt: attempt, maxAttempts: (_a = this.retryConfig.maxAttempts) !== null && _a !== void 0 ? _a : 3, retryDelay: retryDelay, onRetry: this.handleRetry, onReset: this.handleReset, fallback: fallback, className: className }));
149
- }
150
- return children;
151
- }
152
- }
153
-
154
- export { RetryBoundary };
@@ -1,2 +0,0 @@
1
- import type { RetryBoundaryTheme } from "./RetryBoundary.types";
2
- export declare const retryBoundaryTheme: RetryBoundaryTheme;
@@ -1,7 +0,0 @@
1
- const retryBoundaryTheme = {
2
- container: "flex flex-col items-start justify-center p-6 rounded-[var(--form-rounded)] bg-[var(--color-danger-50)]/50 border border-[var(--color-danger-100)]",
3
- errorMessage: "text-sm text-[var(--color-text-secondary)] text-center max-w-md mt-1",
4
- countdown: "text-xs text-[var(--color-text-muted)] tabular-nums mt-3",
5
- };
6
-
7
- export { retryBoundaryTheme };
@@ -1,51 +0,0 @@
1
- import type { RetryConfig } from "../../../utils/retryUtils";
2
- /**
3
- * Props for custom retry fallback render function
4
- */
5
- export interface RetryFallbackProps {
6
- /** The error that was caught */
7
- error: Error;
8
- /** Current retry attempt (0-indexed) */
9
- attempt: number;
10
- /** Maximum retry attempts */
11
- maxAttempts: number;
12
- /** Seconds until auto-retry (0 if not auto-retrying) */
13
- retryIn: number;
14
- /** Manually trigger a retry */
15
- retry: () => void;
16
- /** Reset error state completely */
17
- reset: () => void;
18
- }
19
- /**
20
- * Props for RetryBoundary component
21
- */
22
- export interface RetryBoundaryProps {
23
- /** Content to render when no error */
24
- children: React.ReactNode;
25
- /**
26
- * Custom fallback UI or render function
27
- * If not provided, uses default retry UI
28
- */
29
- fallback?: React.ReactNode | ((props: RetryFallbackProps) => React.ReactNode);
30
- /** Retry configuration */
31
- retry?: RetryConfig;
32
- /** Called when an error is caught */
33
- onError?: (error: Error, attempt: number) => void;
34
- /** Called when a retry is triggered */
35
- onRetry?: (attempt: number) => void;
36
- /** Called when max retries is reached */
37
- onMaxRetriesReached?: (error: Error) => void;
38
- /** Additional class names */
39
- className?: string;
40
- }
41
- /**
42
- * Theme configuration for RetryBoundary
43
- */
44
- export interface RetryBoundaryTheme {
45
- /** Container styles */
46
- container?: string;
47
- /** Error message styles */
48
- errorMessage?: string;
49
- /** Retry countdown styles */
50
- countdown?: string;
51
- }
@@ -1,3 +0,0 @@
1
- export { RetryBoundary } from "./RetryBoundary";
2
- export type { RetryBoundaryProps, RetryFallbackProps, RetryBoundaryTheme, } from "./RetryBoundary.types";
3
- export { retryBoundaryTheme } from "./RetryBoundary.theme";
@@ -1,33 +0,0 @@
1
- /**
2
- * OptimisticForm Component
3
- * Form wrapper with optimistic updates and auto-rollback
4
- */
5
- import React from "react";
6
- import type { OptimisticFormProps } from "./OptimisticForm.types";
7
- /**
8
- * OptimisticForm - Form wrapper with optimistic updates and auto-rollback
9
- *
10
- * @example
11
- * // Basic usage
12
- * <OptimisticForm
13
- * onSubmit={async (data) => api.createUser(data)}
14
- * onOptimisticUpdate={(data) => addUserToList({ ...data, id: 'temp', isPending: true })}
15
- * onSuccess={(response) => updateUserInList(response)}
16
- * onError={() => removeUserFromList('temp')}
17
- * >
18
- * <Input name="name" />
19
- * <Button type="submit">Create User</Button>
20
- * </OptimisticForm>
21
- *
22
- * // With render prop for dynamic UI
23
- * <OptimisticForm onSubmit={handleSubmit}>
24
- * {({ isPending, isError, error }) => (
25
- * <>
26
- * <Input name="email" disabled={isPending} />
27
- * {isError && <Alert variant="error">{error?.message}</Alert>}
28
- * <Button type="submit" loading={isPending}>Submit</Button>
29
- * </>
30
- * )}
31
- * </OptimisticForm>
32
- */
33
- export declare function OptimisticForm<TData, TFormData extends Record<string, unknown>>({ onSubmit, onOptimisticUpdate, onSuccess, onError, onRollback, retry, offlineQueue, resetOnSuccess, children, className, id, disabled, }: OptimisticFormProps<TData, TFormData>): React.ReactElement;
@@ -1,87 +0,0 @@
1
- import React__default, { useRef, useCallback } from 'react';
2
- import { cn } from '../../../utils/cn.js';
3
- import { useOptimisticMutation } from '../../../hooks/useOptimisticMutation.js';
4
- import { optimisticFormTheme } from './OptimisticForm.theme.js';
5
-
6
- /**
7
- * OptimisticForm Component
8
- * Form wrapper with optimistic updates and auto-rollback
9
- */
10
- /**
11
- * OptimisticForm - Form wrapper with optimistic updates and auto-rollback
12
- *
13
- * @example
14
- * // Basic usage
15
- * <OptimisticForm
16
- * onSubmit={async (data) => api.createUser(data)}
17
- * onOptimisticUpdate={(data) => addUserToList({ ...data, id: 'temp', isPending: true })}
18
- * onSuccess={(response) => updateUserInList(response)}
19
- * onError={() => removeUserFromList('temp')}
20
- * >
21
- * <Input name="name" />
22
- * <Button type="submit">Create User</Button>
23
- * </OptimisticForm>
24
- *
25
- * // With render prop for dynamic UI
26
- * <OptimisticForm onSubmit={handleSubmit}>
27
- * {({ isPending, isError, error }) => (
28
- * <>
29
- * <Input name="email" disabled={isPending} />
30
- * {isError && <Alert variant="error">{error?.message}</Alert>}
31
- * <Button type="submit" loading={isPending}>Submit</Button>
32
- * </>
33
- * )}
34
- * </OptimisticForm>
35
- */
36
- function OptimisticForm({ onSubmit, onOptimisticUpdate, onSuccess, onError, onRollback, retry, offlineQueue = false, resetOnSuccess = false, children, className, id, disabled = false, }) {
37
- const theme = optimisticFormTheme;
38
- const formRef = useRef(null);
39
- // Use optimistic mutation hook
40
- const { mutate, status, error, isOptimistic, isRolledBack, isQueued } = useOptimisticMutation(onSubmit, {
41
- onMutate: (data) => data, // Pass form data as context
42
- onOptimisticUpdate: onOptimisticUpdate
43
- ? (data, _context) => onOptimisticUpdate(data)
44
- : undefined,
45
- onSuccess: (response, formData, _context) => {
46
- onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(response, formData);
47
- // Reset form if configured
48
- if (resetOnSuccess && formRef.current) {
49
- formRef.current.reset();
50
- }
51
- },
52
- onError: (err, formData, _context) => {
53
- onError === null || onError === void 0 ? void 0 : onError(err, formData);
54
- onRollback === null || onRollback === void 0 ? void 0 : onRollback(formData);
55
- },
56
- retry,
57
- offlineQueue,
58
- });
59
- // Handle form submission
60
- const handleSubmit = useCallback((event) => {
61
- event.preventDefault();
62
- if (disabled)
63
- return;
64
- const formElement = event.currentTarget;
65
- const formData = new FormData(formElement);
66
- // Convert FormData to object
67
- const data = Object.fromEntries(formData.entries());
68
- mutate(data);
69
- }, [mutate, disabled]);
70
- // Create form state for render prop
71
- const formState = {
72
- status,
73
- isPending: status === "pending",
74
- isOptimistic,
75
- isSuccess: status === "success",
76
- isError: status === "error",
77
- isRolledBack,
78
- isQueued,
79
- error,
80
- submittedData: null, // We don't track this currently
81
- };
82
- // Determine children to render
83
- const content = typeof children === "function" ? children(formState) : children;
84
- return (React__default.createElement("form", { ref: formRef, id: id, onSubmit: handleSubmit, className: cn(theme.base, status === "pending" && theme.pending, status === "error" && theme.error, status === "success" && theme.success, className), "aria-busy": status === "pending", "aria-disabled": disabled }, content));
85
- }
86
-
87
- export { OptimisticForm };
@@ -1,2 +0,0 @@
1
- import type { OptimisticFormTheme } from "./OptimisticForm.types";
2
- export declare const optimisticFormTheme: OptimisticFormTheme;
@@ -1,8 +0,0 @@
1
- const optimisticFormTheme = {
2
- base: "transition-opacity duration-200",
3
- pending: "opacity-70 pointer-events-none",
4
- error: "",
5
- success: "",
6
- };
7
-
8
- export { optimisticFormTheme };
@@ -1,74 +0,0 @@
1
- import type { RetryConfig } from "../../../utils/retryUtils";
2
- import type { OptimisticError } from "../../../utils/optimisticErrors";
3
- /**
4
- * Form submission status
5
- */
6
- export type OptimisticFormStatus = "idle" | "pending" | "success" | "error";
7
- /**
8
- * State passed to render prop children
9
- */
10
- export interface OptimisticFormState<TFormData = unknown> {
11
- /** Current form status */
12
- status: OptimisticFormStatus;
13
- /** True when form is submitting */
14
- isPending: boolean;
15
- /** True when showing optimistic state */
16
- isOptimistic: boolean;
17
- /** True when submission succeeded */
18
- isSuccess: boolean;
19
- /** True when submission failed */
20
- isError: boolean;
21
- /** True when rollback occurred */
22
- isRolledBack: boolean;
23
- /** True when queued for offline */
24
- isQueued: boolean;
25
- /** Error if submission failed */
26
- error: OptimisticError | null;
27
- /** Last submitted form data */
28
- submittedData: TFormData | null;
29
- }
30
- /**
31
- * Props for OptimisticForm component
32
- */
33
- export interface OptimisticFormProps<TData, TFormData> {
34
- /** Form submission handler - returns server response */
35
- onSubmit: (data: TFormData) => Promise<TData>;
36
- /** Called immediately to apply optimistic update */
37
- onOptimisticUpdate?: (data: TFormData) => void;
38
- /** Called on successful submission */
39
- onSuccess?: (response: TData, formData: TFormData) => void;
40
- /** Called when submission fails */
41
- onError?: (error: OptimisticError, formData: TFormData) => void;
42
- /** Called when rollback is executed */
43
- onRollback?: (formData: TFormData) => void;
44
- /** Retry configuration */
45
- retry?: RetryConfig;
46
- /** Queue submissions when offline */
47
- offlineQueue?: boolean;
48
- /** Reset form on successful submission */
49
- resetOnSuccess?: boolean;
50
- /**
51
- * Form content - can be static or render prop
52
- * Render prop receives current form state
53
- */
54
- children: React.ReactNode | ((state: OptimisticFormState<TFormData>) => React.ReactNode);
55
- /** Additional class names for form element */
56
- className?: string;
57
- /** Form ID */
58
- id?: string;
59
- /** Whether the form is disabled */
60
- disabled?: boolean;
61
- }
62
- /**
63
- * Theme configuration for OptimisticForm
64
- */
65
- export interface OptimisticFormTheme {
66
- /** Base form styles */
67
- base?: string;
68
- /** Styles when submitting */
69
- pending?: string;
70
- /** Styles when error */
71
- error?: string;
72
- /** Styles when success */
73
- success?: string;
74
- }
@@ -1,3 +0,0 @@
1
- export { OptimisticForm } from "./OptimisticForm";
2
- export type { OptimisticFormProps, OptimisticFormState, OptimisticFormStatus, OptimisticFormTheme, } from "./OptimisticForm.types";
3
- export { optimisticFormTheme } from "./OptimisticForm.theme";
@@ -1,109 +0,0 @@
1
- /**
2
- * useOptimisticMutation Hook
3
- * Provides instant UI updates with automatic rollback on error
4
- */
5
- import { OptimisticError } from "../utils/optimisticErrors";
6
- import { type RetryConfig } from "../utils/retryUtils";
7
- import { type ActionQueue, type AddActionOptions } from "../utils/actionQueue";
8
- /**
9
- * Mutation state
10
- */
11
- export type MutationStatus = "idle" | "pending" | "success" | "error";
12
- /**
13
- * Options for useOptimisticMutation hook
14
- */
15
- export interface OptimisticMutationOptions<TData, TVariables, TContext = unknown> {
16
- /**
17
- * Called before mutation - return context for rollback
18
- * Context is passed to onSuccess, onError, and onSettled
19
- */
20
- onMutate?: (variables: TVariables) => TContext | Promise<TContext>;
21
- /**
22
- * Apply optimistic update immediately
23
- * Called synchronously before the mutation starts
24
- */
25
- onOptimisticUpdate?: (variables: TVariables, context: TContext) => void;
26
- /**
27
- * Called on success - replace optimistic data with real data
28
- */
29
- onSuccess?: (data: TData, variables: TVariables, context: TContext) => void;
30
- /**
31
- * Called on error - rollback optimistic update
32
- * Use context to restore previous state
33
- */
34
- onError?: (error: OptimisticError, variables: TVariables, context: TContext) => void;
35
- /**
36
- * Called after success or error (cleanup)
37
- */
38
- onSettled?: (data: TData | undefined, error: OptimisticError | null, variables: TVariables, context: TContext) => void;
39
- /**
40
- * Retry configuration for failed mutations
41
- */
42
- retry?: RetryConfig;
43
- /**
44
- * Queue mutation when offline instead of failing immediately
45
- */
46
- offlineQueue?: boolean;
47
- /**
48
- * Custom action queue instance (defaults to global queue)
49
- */
50
- actionQueue?: ActionQueue;
51
- /**
52
- * Options for queued action (label, description)
53
- */
54
- queueOptions?: Omit<AddActionOptions, "maxRetries">;
55
- }
56
- /**
57
- * Return value from useOptimisticMutation hook
58
- */
59
- export interface OptimisticMutationReturn<TData, TVariables> {
60
- /** Trigger the mutation */
61
- mutate: (variables: TVariables) => void;
62
- /** Trigger the mutation and return a Promise */
63
- mutateAsync: (variables: TVariables) => Promise<TData>;
64
- /** Response data from the last successful mutation */
65
- data: TData | undefined;
66
- /** Error from the last failed mutation */
67
- error: OptimisticError | null;
68
- /** Current mutation status */
69
- status: MutationStatus;
70
- /** True when no mutation is in progress or completed */
71
- isIdle: boolean;
72
- /** True when mutation is in progress */
73
- isPending: boolean;
74
- /** True when showing optimistic data (mutation in progress) */
75
- isOptimistic: boolean;
76
- /** True when mutation completed successfully */
77
- isSuccess: boolean;
78
- /** True when mutation failed */
79
- isError: boolean;
80
- /** True when error occurred and rollback was applied */
81
- isRolledBack: boolean;
82
- /** True when mutation was queued for offline processing */
83
- isQueued: boolean;
84
- /** Reset the mutation state */
85
- reset: () => void;
86
- }
87
- /**
88
- * Hook for optimistic UI mutations with automatic rollback
89
- *
90
- * @example
91
- * const { mutate, isOptimistic, isPending } = useOptimisticMutation(
92
- * async (data) => api.createMessage(data),
93
- * {
94
- * onOptimisticUpdate: (newMessage) => {
95
- * setMessages(prev => [...prev, { ...newMessage, id: 'temp-id', isPending: true }]);
96
- * },
97
- * onSuccess: (response) => {
98
- * setMessages(prev => prev.map(m =>
99
- * m.id === 'temp-id' ? { ...response, isPending: false } : m
100
- * ));
101
- * },
102
- * onError: (error) => {
103
- * setMessages(prev => prev.filter(m => m.id !== 'temp-id'));
104
- * toast.error('Failed to send message');
105
- * }
106
- * }
107
- * );
108
- */
109
- export declare function useOptimisticMutation<TData, TVariables, TContext = unknown>(mutationFn: (variables: TVariables) => Promise<TData>, options?: OptimisticMutationOptions<TData, TVariables, TContext>): OptimisticMutationReturn<TData, TVariables>;