funuicss 3.8.9 → 3.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/css/fun.css CHANGED
@@ -2294,7 +2294,6 @@ z-index: 9999 !important;
2294
2294
  padding-top: 1rem !important;
2295
2295
  height: var(--inputButtonHeight);
2296
2296
 
2297
-
2298
2297
  }
2299
2298
 
2300
2299
 
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.8.9",
2
+ "version": "3.8.10",
3
3
  "name": "funuicss",
4
4
  "description": "React and Next.js component UI Library for creating Easy and good looking websites with fewer lines of code. Elevate your web development experience with our cutting-edge React/Next.js component UI Library. Craft stunning websites effortlessly, boasting both seamless functionality and aesthetic appeal—all achieved with minimal lines of code. Unleash the power of simplicity and style in your projects!",
5
5
  "main": "index.js",
@@ -9,6 +9,9 @@ interface CarouselProps extends React.HTMLAttributes<HTMLDivElement> {
9
9
  itemPadding?: string;
10
10
  controlerSize?: number;
11
11
  controlerIconSize?: number;
12
+ infiniteScroll?: boolean;
13
+ infiniteScrollSpeed?: number;
14
+ infiniteScrollDirection?: 'left' | 'right' | 'alternate';
12
15
  }
13
16
  declare const Carousel: React.FC<CarouselProps>;
14
17
  export default Carousel;
@@ -65,11 +65,17 @@ var Circle_1 = __importDefault(require("../specials/Circle"));
65
65
  var RowFlex_1 = __importDefault(require("../specials/RowFlex"));
66
66
  var Functions_1 = require("../../utils/Functions");
67
67
  var Carousel = function (_a) {
68
- var _b = _a.scrollNumber, scrollNumber = _b === void 0 ? 320 : _b, _c = _a.gap, gap = _c === void 0 ? 0.5 : _c, _d = _a.funcss, funcss = _d === void 0 ? '' : _d, _e = _a.showDashes, showDashes = _e === void 0 ? true : _e, _f = _a.allowVerticalOverflow, allowVerticalOverflow = _f === void 0 ? false : _f, _g = _a.itemPadding, itemPadding = _g === void 0 ? '0rem' : _g, children = _a.children, _h = _a.controlerSize, controlerSize = _h === void 0 ? 2.5 : _h, _j = _a.controlerIconSize, controlerIconSize = _j === void 0 ? 20 : _j, rest = __rest(_a, ["scrollNumber", "gap", "funcss", "showDashes", "allowVerticalOverflow", "itemPadding", "children", "controlerSize", "controlerIconSize"]);
68
+ var _b = _a.scrollNumber, scrollNumber = _b === void 0 ? 320 : _b, _c = _a.gap, gap = _c === void 0 ? 0.5 : _c, _d = _a.funcss, funcss = _d === void 0 ? '' : _d, _e = _a.showDashes, showDashes = _e === void 0 ? true : _e, _f = _a.allowVerticalOverflow, allowVerticalOverflow = _f === void 0 ? false : _f, _g = _a.itemPadding, itemPadding = _g === void 0 ? '0rem' : _g, children = _a.children, _h = _a.controlerSize, controlerSize = _h === void 0 ? 2.5 : _h, _j = _a.controlerIconSize, controlerIconSize = _j === void 0 ? 20 : _j, _k = _a.infiniteScroll, infiniteScroll = _k === void 0 ? false : _k, _l = _a.infiniteScrollSpeed, infiniteScrollSpeed = _l === void 0 ? 50 : _l, _m = _a.infiniteScrollDirection, infiniteScrollDirection = _m === void 0 ? 'left' : _m, rest = __rest(_a, ["scrollNumber", "gap", "funcss", "showDashes", "allowVerticalOverflow", "itemPadding", "children", "controlerSize", "controlerIconSize", "infiniteScroll", "infiniteScrollSpeed", "infiniteScrollDirection"]);
69
69
  var scrollRef = (0, react_1.useRef)(null);
70
- var _k = (0, react_1.useState)('start'), scrollPosition = _k[0], setScrollPosition = _k[1];
71
- var _l = (0, react_1.useState)(false), isPhone = _l[0], setIsPhone = _l[1];
72
- var _m = (0, react_1.useState)(false), isScrollable = _m[0], setIsScrollable = _m[1];
70
+ var containerRef = (0, react_1.useRef)(null);
71
+ var _o = (0, react_1.useState)('start'), scrollPosition = _o[0], setScrollPosition = _o[1];
72
+ var _p = (0, react_1.useState)(false), isPhone = _p[0], setIsPhone = _p[1];
73
+ var _q = (0, react_1.useState)(false), isScrollable = _q[0], setIsScrollable = _q[1];
74
+ var _r = (0, react_1.useState)(infiniteScrollDirection === 'right' ? 'right' : 'left'), autoScrollDirection = _r[0], setAutoScrollDirection = _r[1];
75
+ var _s = (0, react_1.useState)(false), isHovered = _s[0], setIsHovered = _s[1];
76
+ var animationRef = (0, react_1.useRef)(null);
77
+ var lastScrollTimeRef = (0, react_1.useRef)(0);
78
+ var isProgrammaticScrollRef = (0, react_1.useRef)(false);
73
79
  var checkScrollable = function () {
74
80
  var container = scrollRef.current;
75
81
  if (container) {
@@ -78,7 +84,7 @@ var Carousel = function (_a) {
78
84
  };
79
85
  (0, react_1.useEffect)(function () {
80
86
  checkScrollable();
81
- window.addEventListener('resize', checkScrollable); // Also listen to window resize
87
+ window.addEventListener('resize', checkScrollable);
82
88
  return function () { return window.removeEventListener('resize', checkScrollable); };
83
89
  }, [children]);
84
90
  (0, react_1.useEffect)(function () {
@@ -89,8 +95,11 @@ var Carousel = function (_a) {
89
95
  setIsPhone(false);
90
96
  }
91
97
  }, []);
92
- // Track scroll position
93
98
  var handleScroll = function () {
99
+ if (isProgrammaticScrollRef.current) {
100
+ isProgrammaticScrollRef.current = false;
101
+ return;
102
+ }
94
103
  var container = scrollRef.current;
95
104
  if (!container)
96
105
  return;
@@ -105,6 +114,7 @@ var Carousel = function (_a) {
105
114
  else {
106
115
  setScrollPosition('middle');
107
116
  }
117
+ lastScrollTimeRef.current = Date.now();
108
118
  };
109
119
  var scroll = function (direction) {
110
120
  var container = scrollRef.current;
@@ -115,6 +125,57 @@ var Carousel = function (_a) {
115
125
  behavior: 'smooth',
116
126
  });
117
127
  };
128
+ var infiniteScrollAnimation = function () {
129
+ if (!infiniteScroll || !scrollRef.current || isHovered || !isScrollable) {
130
+ if (animationRef.current) {
131
+ cancelAnimationFrame(animationRef.current);
132
+ animationRef.current = null;
133
+ }
134
+ return;
135
+ }
136
+ var container = scrollRef.current;
137
+ var scrollLeft = container.scrollLeft, scrollWidth = container.scrollWidth, clientWidth = container.clientWidth;
138
+ var maxScrollLeft = scrollWidth - clientWidth;
139
+ var newDirection = autoScrollDirection;
140
+ if (infiniteScrollDirection === 'alternate') {
141
+ if (scrollLeft <= 0) {
142
+ newDirection = 'right';
143
+ setAutoScrollDirection('right');
144
+ }
145
+ else if (scrollLeft >= maxScrollLeft - 1) {
146
+ newDirection = 'left';
147
+ setAutoScrollDirection('left');
148
+ }
149
+ }
150
+ var scrollAmount = infiniteScrollSpeed / 60;
151
+ isProgrammaticScrollRef.current = true;
152
+ if (newDirection === 'left') {
153
+ container.scrollLeft -= scrollAmount;
154
+ if (scrollLeft <= 0 && infiniteScrollDirection !== 'alternate') {
155
+ container.scrollLeft = maxScrollLeft;
156
+ }
157
+ }
158
+ else {
159
+ container.scrollLeft += scrollAmount;
160
+ if (scrollLeft >= maxScrollLeft - 1 && infiniteScrollDirection !== 'alternate') {
161
+ container.scrollLeft = 0;
162
+ }
163
+ }
164
+ animationRef.current = requestAnimationFrame(infiniteScrollAnimation);
165
+ };
166
+ (0, react_1.useEffect)(function () {
167
+ if (infiniteScroll) {
168
+ infiniteScrollAnimation();
169
+ }
170
+ return function () {
171
+ if (animationRef.current) {
172
+ cancelAnimationFrame(animationRef.current);
173
+ }
174
+ };
175
+ }, [infiniteScroll, infiniteScrollSpeed, infiniteScrollDirection, isHovered, isScrollable, autoScrollDirection]);
176
+ (0, react_1.useEffect)(function () {
177
+ setAutoScrollDirection(infiniteScrollDirection === 'right' ? 'right' : 'left');
178
+ }, [infiniteScrollDirection]);
118
179
  (0, react_1.useEffect)(function () {
119
180
  var container = scrollRef.current;
120
181
  if (container) {
@@ -122,9 +183,54 @@ var Carousel = function (_a) {
122
183
  return function () { return container.removeEventListener('scroll', handleScroll); };
123
184
  }
124
185
  }, []);
125
- return (react_1.default.createElement("div", __assign({ className: "carousel-wrapper ".concat(funcss) }, rest),
186
+ var cloneChildren = function () {
187
+ var childrenArray = react_1.default.Children.toArray(children);
188
+ if (childrenArray.length === 0)
189
+ return children;
190
+ // Clone enough items to create a seamless infinite effect
191
+ // We need enough clones to fill at least 3 times the viewport width
192
+ var container = scrollRef.current;
193
+ var clonesNeeded = container ? Math.ceil(container.clientWidth * 3 / (scrollNumber || 320)) : 3;
194
+ var clonedItems = [];
195
+ for (var i = 0; i < clonesNeeded; i++) {
196
+ clonedItems.push.apply(clonedItems, childrenArray);
197
+ }
198
+ return (react_1.default.createElement(react_1.default.Fragment, null, clonedItems.map(function (child, index) { return (react_1.default.createElement("div", { key: index, className: "carousel-item", style: { flexShrink: 0 } },
199
+ react_1.default.createElement("div", { className: "carousel-card" }, child))); })));
200
+ };
201
+ var handleMouseEnter = function () {
202
+ setIsHovered(true);
203
+ if (animationRef.current) {
204
+ cancelAnimationFrame(animationRef.current);
205
+ animationRef.current = null;
206
+ }
207
+ };
208
+ var handleMouseLeave = function () {
209
+ setIsHovered(false);
210
+ if (infiniteScroll && !isHovered) {
211
+ infiniteScrollAnimation();
212
+ }
213
+ };
214
+ // Handle touch events for mobile
215
+ var handleTouchStart = function () {
216
+ setIsHovered(true);
217
+ if (animationRef.current) {
218
+ cancelAnimationFrame(animationRef.current);
219
+ animationRef.current = null;
220
+ }
221
+ };
222
+ var handleTouchEnd = function () {
223
+ // Wait a bit before resuming to allow user to interact
224
+ setTimeout(function () {
225
+ setIsHovered(false);
226
+ if (infiniteScroll && !isHovered) {
227
+ infiniteScrollAnimation();
228
+ }
229
+ }, 1000); // Resume after 1 second of inactivity
230
+ };
231
+ return (react_1.default.createElement("div", __assign({ ref: containerRef, className: "carousel-wrapper ".concat(funcss), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onTouchStart: handleTouchStart, onTouchEnd: handleTouchEnd }, rest),
126
232
  react_1.default.createElement(react_1.default.Fragment, null,
127
- !isPhone && isScrollable && (react_1.default.createElement("div", { className: 'carouselLeft' },
233
+ !isPhone && isScrollable && !infiniteScroll && (react_1.default.createElement("div", { className: 'carouselLeft' },
128
234
  react_1.default.createElement(Circle_1.default, { bordered: true, size: controlerSize, onClick: function () { return scroll('left'); } },
129
235
  react_1.default.createElement(pi_1.PiCaretLeft, { className: 'text-primary', size: controlerIconSize })))),
130
236
  react_1.default.createElement("div", { ref: scrollRef, className: "carousel-container scrollbar-hide w-full", style: {
@@ -134,16 +240,17 @@ var Carousel = function (_a) {
134
240
  overflowY: 'visible',
135
241
  display: 'flex',
136
242
  justifyItems: (isScrollable || isPhone) ? 'flex-start' : 'center',
137
- scrollSnapType: 'x mandatory',
243
+ scrollSnapType: infiniteScroll ? 'none' : 'x mandatory',
138
244
  scrollBehavior: 'smooth',
139
- padding: itemPadding || "0.5rem"
140
- } }, react_1.default.Children.map(children, function (child) { return (react_1.default.createElement("div", { className: "carousel-item", style: { flexShrink: 0 } },
141
- react_1.default.createElement("div", { className: "carousel-card" }, child))); })),
142
- !isPhone && isScrollable && (react_1.default.createElement("div", { className: 'carouselRight' },
245
+ padding: itemPadding || "0.5rem",
246
+ cursor: infiniteScroll ? 'grab' : 'default'
247
+ }, onMouseDown: function () { return infiniteScroll && handleMouseEnter(); }, onMouseUp: function () { return infiniteScroll && handleMouseLeave(); }, onScroll: handleScroll }, infiniteScroll ? cloneChildren() : (react_1.default.Children.map(children, function (child, index) { return (react_1.default.createElement("div", { className: "carousel-item", style: { flexShrink: 0 } },
248
+ react_1.default.createElement("div", { className: "carousel-card" }, child))); }))),
249
+ !isPhone && isScrollable && !infiniteScroll && (react_1.default.createElement("div", { className: 'carouselRight' },
143
250
  react_1.default.createElement(Circle_1.default, { bordered: true, size: controlerSize, onClick: function () { return scroll('right'); } },
144
251
  react_1.default.createElement(pi_1.PiCaretRight, { className: 'text-primary', size: controlerIconSize }))))),
145
- (showDashes && isScrollable) && (react_1.default.createElement("div", { className: "center padding-top-10" },
146
- react_1.default.createElement(RowFlex_1.default, { gap: 0.5, justify: "center" }, ['start', 'middle', 'end'].map(function (pos) { return (react_1.default.createElement("div", { className: 'pointer ', key: pos, onClick: function () {
252
+ (showDashes && isScrollable && !infiniteScroll) && (react_1.default.createElement("div", { className: "center padding-top-10" },
253
+ react_1.default.createElement(RowFlex_1.default, { gap: 0.5, justify: "center" }, ['start', 'middle', 'end'].map(function (pos) { return (react_1.default.createElement("div", { className: 'pointer', key: pos, onClick: function () {
147
254
  var _a, _b;
148
255
  if (pos === 'start') {
149
256
  scroll('left');
@@ -164,6 +271,23 @@ var Carousel = function (_a) {
164
271
  borderRadius: '50%',
165
272
  transform: scrollPosition === pos ? 'scale(1.3)' : 'scale(0.9)',
166
273
  transition: 'transform 0.3s ease, background 0.3s ease',
167
- } })); }))))));
274
+ } })); })))),
275
+ infiniteScroll && isHovered && (react_1.default.createElement("div", { style: {
276
+ position: 'absolute',
277
+ top: '50%',
278
+ left: '50%',
279
+ transform: 'translate(-50%, -50%)',
280
+ background: 'rgba(0,0,0,0.7)',
281
+ color: 'white',
282
+ padding: '5px 10px',
283
+ borderRadius: '5px',
284
+ fontSize: '12px',
285
+ zIndex: 10,
286
+ pointerEvents: 'none',
287
+ opacity: 0,
288
+ animation: 'fadeInOut 2s ease'
289
+ } },
290
+ "Scroll paused",
291
+ react_1.default.createElement("style", null, "\n @keyframes fadeInOut {\n 0% { opacity: 0; }\n 10% { opacity: 1; }\n 90% { opacity: 1; }\n 100% { opacity: 0; }\n }\n ")))));
168
292
  };
169
293
  exports.default = Carousel;
@@ -27,6 +27,22 @@ type FeatureItem = {
27
27
  ctaClassName?: string;
28
28
  customRender?: () => React.ReactNode;
29
29
  };
30
+ interface CarouselOptions {
31
+ isCarousel?: boolean;
32
+ scrollNumber?: number;
33
+ gap?: number;
34
+ carouselFuncss?: string;
35
+ showDashes?: boolean;
36
+ allowVerticalOverflow?: boolean;
37
+ itemPadding?: string;
38
+ controlerSize?: number;
39
+ controlerIconSize?: number;
40
+ infiniteScroll?: boolean;
41
+ infiniteScrollSpeed?: number;
42
+ infiniteScrollDirection?: 'left' | 'right' | 'alternate';
43
+ carouselContainerClassName?: string;
44
+ carouselContainerStyle?: React.CSSProperties;
45
+ }
30
46
  type FeatureProps = {
31
47
  variant?: string;
32
48
  layout?: 'checklist' | 'centered' | 'grid';
@@ -96,6 +112,6 @@ type FeatureProps = {
96
112
  funcss?: string;
97
113
  sectionClass?: string;
98
114
  maxWidth?: string;
99
- };
115
+ } & CarouselOptions;
100
116
  declare const Feature: React.FC<FeatureProps>;
101
117
  export default Feature;
@@ -54,6 +54,7 @@ var componentUtils_1 = require("../../utils/componentUtils");
54
54
  var Text_1 = __importDefault(require("../text/Text"));
55
55
  var Button_1 = __importDefault(require("../button/Button"));
56
56
  var getDynamicIcon_1 = require("../../utils/getDynamicIcon");
57
+ var Carousel_1 = __importDefault(require("../carousel/Carousel")); // Import the Carousel component
57
58
  var useDynamicIcon = function (iconString) {
58
59
  var _a = (0, react_1.useState)(null), iconNode = _a[0], setIconNode = _a[1];
59
60
  var _b = (0, react_1.useState)(false), hasValidIcon = _b[0], setHasValidIcon = _b[1];
@@ -228,7 +229,7 @@ var Feature = function (localProps) {
228
229
  // Regular item without card
229
230
  return (react_1.default.createElement("div", { key: index, className: "feature-section__item-wrapper ".concat(item.className || ''), style: __assign({ maxWidth: final.itemMaxWidth || '100%' }, item.style) }, featureContent));
230
231
  };
231
- var renderFeaturesContent = function () {
232
+ var renderFlexFeatures = function () {
232
233
  if (featuresArray.length === 0)
233
234
  return null;
234
235
  var gapValue = final.gap !== undefined ? "".concat(final.gap * 0.25, "rem") : '2rem';
@@ -251,11 +252,34 @@ var Feature = function (localProps) {
251
252
  margin: '0 auto',
252
253
  } }, featuresArray.map(function (item, index) { return (react_1.default.createElement("div", { key: index, className: "feature-section__flex-item" }, renderFeatureItem(item, index))); })));
253
254
  };
255
+ var renderCarouselFeatures = function () {
256
+ if (featuresArray.length === 0)
257
+ return null;
258
+ // Prepare carousel items
259
+ var carouselItems = featuresArray.map(function (item, index) {
260
+ return renderFeatureItem(item, index);
261
+ });
262
+ return (react_1.default.createElement("div", { className: "feature-section__carousel-container ".concat(final.carouselContainerClassName || ''), style: final.carouselContainerStyle },
263
+ react_1.default.createElement(Carousel_1.default, { scrollNumber: final.scrollNumber, gap: final.gap || 1, funcss: final.carouselFuncss, showDashes: final.showDashes, allowVerticalOverflow: final.allowVerticalOverflow, itemPadding: final.itemPadding || '0.5rem', controlerSize: final.controlerSize, controlerIconSize: final.controlerIconSize, infiniteScroll: final.infiniteScroll, infiniteScrollSpeed: final.infiniteScrollSpeed, infiniteScrollDirection: final.infiniteScrollDirection }, carouselItems)));
264
+ };
265
+ var renderFeaturesContent = function () {
266
+ if (featuresArray.length === 0)
267
+ return null;
268
+ // Use carousel if isCarousel is true
269
+ if (final.isCarousel) {
270
+ return renderCarouselFeatures();
271
+ }
272
+ // Otherwise use flex layout
273
+ return renderFlexFeatures();
274
+ };
254
275
  var getLayoutClasses = function () {
255
276
  var classes = ['feature-section'];
256
277
  if (final.layout) {
257
278
  classes.push("feature-section--".concat(final.layout));
258
279
  }
280
+ if (final.isCarousel) {
281
+ classes.push('feature-section--carousel');
282
+ }
259
283
  if (final.className) {
260
284
  classes.push(final.className);
261
285
  }
package/ui/form/Form.d.ts CHANGED
@@ -46,7 +46,7 @@ export interface FormField {
46
46
  };
47
47
  }
48
48
  export interface FormProps {
49
- fields: FormField[] | string;
49
+ fields?: FormField[] | string;
50
50
  onSubmit?: (values: Record<string, any>, viaWhatsApp?: boolean) => void;
51
51
  defaultValues?: Record<string, any> | string;
52
52
  submitText?: string;
@@ -58,7 +58,7 @@ export interface FormProps {
58
58
  isLoading?: boolean;
59
59
  className?: string;
60
60
  layout?: 'vertical' | 'horizontal';
61
- gap?: number;
61
+ gap?: number | string;
62
62
  title?: string;
63
63
  titleSize?: string;
64
64
  titleColor?: string;