funuicss 3.7.15 → 3.8.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 (45) hide show
  1. package/css/fun.css +560 -203
  2. package/demo/theme.tsx +1311 -0
  3. package/index.d.ts +3 -0
  4. package/index.js +7 -1
  5. package/package.json +1 -1
  6. package/ui/button/Button.d.ts +2 -1
  7. package/ui/button/Button.js +3 -3
  8. package/ui/components/ImageScaler.d.ts +6 -0
  9. package/ui/components/ImageScaler.js +17 -0
  10. package/ui/div/Div.d.ts +3 -1
  11. package/ui/div/Div.js +2 -2
  12. package/ui/empty/Empty.d.ts +17 -0
  13. package/ui/empty/Empty.js +66 -0
  14. package/ui/feature/Feature.d.ts +130 -0
  15. package/ui/feature/Feature.js +380 -0
  16. package/ui/flex/Flex.d.ts +2 -1
  17. package/ui/flex/Flex.js +3 -3
  18. package/ui/footer/Footer.d.ts +1 -0
  19. package/ui/footer/Footer.js +6 -1
  20. package/ui/icons/Dynamic.d.ts +12 -0
  21. package/ui/icons/Dynamic.js +163 -0
  22. package/ui/modal/Modal.d.ts +1 -1
  23. package/ui/products/CartModal.d.ts +20 -0
  24. package/ui/products/CartModal.js +85 -0
  25. package/ui/products/ProductCard.d.ts +13 -0
  26. package/ui/products/ProductCard.js +56 -0
  27. package/ui/products/ProductDetail.d.ts +14 -0
  28. package/ui/products/ProductDetail.js +249 -0
  29. package/ui/products/ProductDetailModal.d.ts +17 -0
  30. package/ui/products/ProductDetailModal.js +99 -0
  31. package/ui/products/Products.d.ts +60 -0
  32. package/ui/products/Products.js +312 -0
  33. package/ui/products/Store.d.ts +99 -0
  34. package/ui/products/Store.js +515 -0
  35. package/ui/sidebar/SideBar.d.ts +3 -1
  36. package/ui/sidebar/SideBar.js +50 -11
  37. package/ui/specials/Circle.d.ts +2 -1
  38. package/ui/specials/Circle.js +2 -2
  39. package/ui/table/Table.d.ts +15 -1
  40. package/ui/table/Table.js +143 -15
  41. package/ui/theme/theme.d.ts +91 -0
  42. package/ui/theme/theme.js +468 -25
  43. package/ui/vista/Vista.js +8 -12
  44. package/utils/Buckets.d.ts +0 -0
  45. package/utils/Buckets.js +1 -0
package/ui/theme/theme.js CHANGED
@@ -70,7 +70,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
70
70
  }
71
71
  };
72
72
  Object.defineProperty(exports, "__esModule", { value: true });
73
- exports.useDocumentAssets = exports.useAudioAssets = exports.useVideoAssets = exports.useImageAssets = exports.useAssetsByType = exports.useAssetInfo = exports.useAssetType = exports.useAssetValue = exports.useAsset = exports.useAssets = exports.getAssetInfo = exports.getAssetType = exports.getAssetValue = exports.getAllAssets = exports.getAsset = exports.useVariable = exports.useVariables = exports.useComponentVariant = exports.useTypographyValue = exports.useColor = exports.useProjectData = exports.useThemeConfig = exports.useTypography = exports.useColors = exports.useComponentConfig = exports.useThemeValue = exports.getAllVariables = exports.getVariable = exports.useVariant = exports.useTheme = void 0;
73
+ exports.getPaginatedRecords = exports.useBucketCache = exports.useAllJsonRecords = exports.usePaginatedRecords = exports.useBucketJsonFiles = exports.useBucketsByCategory = exports.useBucket = exports.useBuckets = exports.useDocumentAssets = exports.useAudioAssets = exports.useVideoAssets = exports.useImageAssets = exports.useAssetsByType = exports.useAssetInfo = exports.useAssetType = exports.useAssetValue = exports.useAsset = exports.useAssets = exports.getAssetInfo = exports.getAssetType = exports.getAssetValue = exports.getAllAssets = exports.getAsset = exports.useVariable = exports.useVariables = exports.useComponentVariant = exports.useTypographyValue = exports.useColor = exports.useProjectData = exports.useThemeConfig = exports.useTypography = exports.useColors = exports.useComponentConfig = exports.useThemeValue = exports.getAllVariables = exports.getVariable = exports.useVariant = exports.useTheme = void 0;
74
74
  var react_1 = __importStar(require("react"));
75
75
  var themes_1 = require("./themes");
76
76
  var darkenUtils_1 = require("./darkenUtils");
@@ -82,6 +82,7 @@ var ThemeContext = (0, react_1.createContext)({
82
82
  isLoading: true,
83
83
  isInitialLoad: true,
84
84
  error: null,
85
+ projectId: undefined,
85
86
  });
86
87
  var useTheme = function () {
87
88
  var context = (0, react_1.useContext)(ThemeContext);
@@ -222,6 +223,95 @@ var loadThemeFromCDN = function (projectId) { return __awaiter(void 0, void 0, v
222
223
  });
223
224
  }); };
224
225
  /* -------------------------------------------------------------------------- */
226
+ /* BUCKET JSON LOADER */
227
+ /* -------------------------------------------------------------------------- */
228
+ var loadBucketJsonFromCDN = function (bucketSanitizedName, projectId, page) { return __awaiter(void 0, void 0, void 0, function () {
229
+ var pageNumber, publicUrl, response, data, error_4;
230
+ return __generator(this, function (_a) {
231
+ switch (_a.label) {
232
+ case 0:
233
+ if (!bucketSanitizedName || !projectId) {
234
+ console.error('❌ Missing parameters for JSON loading');
235
+ return [2 /*return*/, null];
236
+ }
237
+ _a.label = 1;
238
+ case 1:
239
+ _a.trys.push([1, 6, , 7]);
240
+ pageNumber = page.toString();
241
+ publicUrl = "https://firebasestorage.googleapis.com/v0/b/funui-4bcd1.firebasestorage.app/o/projects%2F".concat(projectId, "%2Fbuckets%2F").concat(bucketSanitizedName, "%2F").concat(pageNumber, ".json?alt=media");
242
+ return [4 /*yield*/, fetch(publicUrl, {
243
+ cache: 'no-cache',
244
+ })];
245
+ case 2:
246
+ response = _a.sent();
247
+ if (!response.ok) return [3 /*break*/, 4];
248
+ return [4 /*yield*/, response.json()];
249
+ case 3:
250
+ data = _a.sent();
251
+ console.log(data);
252
+ return [2 /*return*/, data];
253
+ case 4:
254
+ // File might not exist (e.g., page out of range)
255
+ return [2 /*return*/, null];
256
+ case 5: return [3 /*break*/, 7];
257
+ case 6:
258
+ error_4 = _a.sent();
259
+ console.error("\u274C Error loading JSON file for page ".concat(page, ":"), error_4);
260
+ return [2 /*return*/, null];
261
+ case 7: return [2 /*return*/];
262
+ }
263
+ });
264
+ }); };
265
+ var listBucketJsonFiles = function (bucketSanitizedName, projectId) { return __awaiter(void 0, void 0, void 0, function () {
266
+ var files, page, hasMoreFiles, paddedPage, publicUrl, response, error_5;
267
+ return __generator(this, function (_a) {
268
+ switch (_a.label) {
269
+ case 0:
270
+ if (!bucketSanitizedName || !projectId) {
271
+ console.error('❌ Missing parameters for listing JSON files');
272
+ return [2 /*return*/, []];
273
+ }
274
+ _a.label = 1;
275
+ case 1:
276
+ _a.trys.push([1, 5, , 6]);
277
+ files = [];
278
+ page = 1;
279
+ hasMoreFiles = true;
280
+ _a.label = 2;
281
+ case 2:
282
+ if (!(hasMoreFiles && page <= 100)) return [3 /*break*/, 4];
283
+ paddedPage = page.toString().padStart(3, '0');
284
+ publicUrl = "https://firebasestorage.googleapis.com/v0/b/funui-4bcd1.firebasestorage.app/o/projects%2F".concat(projectId, "%2Fbuckets%2F").concat(bucketSanitizedName, "%2Fpage_").concat(paddedPage, ".json?alt=media");
285
+ return [4 /*yield*/, fetch(publicUrl, {
286
+ method: 'HEAD',
287
+ cache: 'no-cache',
288
+ })];
289
+ case 3:
290
+ response = _a.sent();
291
+ if (response.ok) {
292
+ files.push({
293
+ name: "page_".concat(paddedPage, ".json"),
294
+ fullPath: "projects/".concat(projectId, "/buckets/").concat(bucketSanitizedName, "/page_").concat(paddedPage, ".json"),
295
+ url: publicUrl,
296
+ size: parseInt(response.headers.get('content-length') || '0', 10),
297
+ page: page
298
+ });
299
+ page++;
300
+ }
301
+ else {
302
+ hasMoreFiles = false;
303
+ }
304
+ return [3 /*break*/, 2];
305
+ case 4: return [2 /*return*/, files];
306
+ case 5:
307
+ error_5 = _a.sent();
308
+ console.error('❌ Error listing JSON files:', error_5);
309
+ return [2 /*return*/, []];
310
+ case 6: return [2 /*return*/];
311
+ }
312
+ });
313
+ }); };
314
+ /* -------------------------------------------------------------------------- */
225
315
  /* CSS VARIABLE APPLIER */
226
316
  /* -------------------------------------------------------------------------- */
227
317
  var applyTypographyVariables = function (typography, root) {
@@ -277,10 +367,45 @@ var getAllVariables = function () {
277
367
  };
278
368
  exports.getAllVariables = getAllVariables;
279
369
  /* -------------------------------------------------------------------------- */
370
+ /* BUCKET UTILITIES */
371
+ /* -------------------------------------------------------------------------- */
372
+ // Cache for buckets and JSON files
373
+ var cachedBuckets = [];
374
+ var cachedJsonFiles = {};
375
+ var cachedJsonData = {};
376
+ var sanitizeBucketName = function (name) {
377
+ return name
378
+ .trim()
379
+ .replace(/\s+/g, '_')
380
+ .replace(/[^a-zA-Z0-9_-]/g, '')
381
+ .toLowerCase();
382
+ };
383
+ var transformProjectBucket = function (bucket, projectId) {
384
+ return {
385
+ id: bucket.id || bucket._id || '',
386
+ // projectId: bucket.projectId || projectId || '',
387
+ name: bucket.name || '',
388
+ displayName: bucket.displayName || bucket.name || '',
389
+ category: bucket.category || 'uncategorized',
390
+ fields: Array.isArray(bucket.fields) ? bucket.fields : [],
391
+ createdBy: bucket.createdBy || bucket.userId || '',
392
+ createdAt: typeof bucket.createdAt === 'number' ? bucket.createdAt : Date.now(),
393
+ updatedAt: typeof bucket.updatedAt === 'number' ? bucket.updatedAt : Date.now(),
394
+ updatedBy: bucket.updatedBy || bucket.createdBy || '',
395
+ recordCount: bucket.recordCount || 0,
396
+ jsonFilesCount: bucket.jsonFilesCount || 0,
397
+ totalRecordsInJson: bucket.totalRecordsInJson || 0,
398
+ lastJsonExport: bucket.lastJsonExport,
399
+ userId: bucket.userId,
400
+ createdAtString: bucket.createdAt,
401
+ updatedAtString: bucket.updatedAt
402
+ };
403
+ };
404
+ /* -------------------------------------------------------------------------- */
280
405
  /* COMPONENT */
281
406
  /* -------------------------------------------------------------------------- */
282
407
  var ThemeProvider = function (_a) {
283
- var theme = _a.theme, children = _a.children, _b = _a.funcss, funcss = _b === void 0 ? '' : _b, _c = _a.minHeight, minHeight = _c === void 0 ? '100vh' : _c, projectId = _a.projectId;
408
+ var theme = _a.theme, children = _a.children, _b = _a.funcss, funcss = _b === void 0 ? '' : _b, _c = _a.minHeight, minHeight = _c === void 0 ? '100vh' : _c, projectId = _a.projectId, providedProject = _a.project;
284
409
  var _d = (0, react_1.useState)('standard'), variant = _d[0], setVariant = _d[1];
285
410
  var _e = (0, react_1.useState)({}), themeConfig = _e[0], setThemeConfig = _e[1];
286
411
  var _f = (0, react_1.useState)(null), projectData = _f[0], setProjectData = _f[1];
@@ -323,20 +448,25 @@ var ThemeProvider = function (_a) {
323
448
  return __generator(this, function (_a) {
324
449
  switch (_a.label) {
325
450
  case 0:
326
- _a.trys.push([0, 8, 9, 10]);
451
+ _a.trys.push([0, 9, 10, 11]);
327
452
  finalTheme = null;
328
453
  finalVersion = null;
329
- return [4 /*yield*/, loadLocalTheme()];
330
- case 1:
454
+ if (!providedProject) return [3 /*break*/, 1];
455
+ console.log('✅ Using provided project data directly');
456
+ finalTheme = providedProject;
457
+ finalVersion = providedProject.version || 0;
458
+ return [3 /*break*/, 8];
459
+ case 1: return [4 /*yield*/, loadLocalTheme()];
460
+ case 2:
331
461
  localTheme = _a.sent();
332
462
  localVersion = (localTheme === null || localTheme === void 0 ? void 0 : localTheme.version) || 0;
333
- if (!projectId) return [3 /*break*/, 6];
463
+ if (!projectId) return [3 /*break*/, 7];
334
464
  return [4 /*yield*/, validateOriginAccess(projectId)];
335
- case 2:
465
+ case 3:
336
466
  hasAccess = _a.sent();
337
- if (!hasAccess) return [3 /*break*/, 4];
467
+ if (!hasAccess) return [3 /*break*/, 5];
338
468
  return [4 /*yield*/, loadThemeFromCDN(projectId)];
339
- case 3:
469
+ case 4:
340
470
  cdnTheme = _a.sent();
341
471
  cdnVersion = (cdnTheme === null || cdnTheme === void 0 ? void 0 : cdnTheme.version) || 0;
342
472
  if (cdnTheme) {
@@ -359,8 +489,8 @@ var ThemeProvider = function (_a) {
359
489
  console.warn('⚠️ No theme found (CDN unavailable and no local theme)');
360
490
  setError('Theme not found');
361
491
  }
362
- return [3 /*break*/, 5];
363
- case 4:
492
+ return [3 /*break*/, 6];
493
+ case 5:
364
494
  // Origin validation failed
365
495
  if (localTheme) {
366
496
  console.log('⚠️ Origin validation failed, using local theme');
@@ -371,9 +501,9 @@ var ThemeProvider = function (_a) {
371
501
  console.error('❌ Origin validation failed and no local theme available');
372
502
  setError('Access denied and no local theme available');
373
503
  }
374
- _a.label = 5;
375
- case 5: return [3 /*break*/, 7];
376
- case 6:
504
+ _a.label = 6;
505
+ case 6: return [3 /*break*/, 8];
506
+ case 7:
377
507
  // No project ID provided - only use local theme
378
508
  console.log('ℹ️ No project ID provided, using local theme only');
379
509
  if (localTheme) {
@@ -385,8 +515,8 @@ var ThemeProvider = function (_a) {
385
515
  console.log('ℹ️ No local theme file found - using base theme only');
386
516
  // No error here - it's valid to use only base theme
387
517
  }
388
- _a.label = 7;
389
- case 7:
518
+ _a.label = 8;
519
+ case 8:
390
520
  // Apply the theme if we have one
391
521
  if (finalTheme && (!currentVersion || finalVersion !== currentVersion)) {
392
522
  applyThemeData(finalTheme, root);
@@ -396,24 +526,24 @@ var ThemeProvider = function (_a) {
396
526
  else if (finalTheme) {
397
527
  console.log('✓ Theme up to date');
398
528
  }
399
- return [3 /*break*/, 10];
400
- case 8:
529
+ return [3 /*break*/, 11];
530
+ case 9:
401
531
  err_1 = _a.sent();
402
532
  console.error('❌ Error loading theme:', err_1);
403
533
  setError('Failed to load theme');
404
- return [3 /*break*/, 10];
405
- case 9:
534
+ return [3 /*break*/, 11];
535
+ case 10:
406
536
  setIsLoading(false);
407
537
  setIsInitialLoad(false);
408
538
  return [7 /*endfinally*/];
409
- case 10: return [2 /*return*/];
539
+ case 11: return [2 /*return*/];
410
540
  }
411
541
  });
412
542
  }); };
413
543
  // Initial load
414
544
  loadTheme();
415
- // Only poll for updates if we have a project ID
416
- if (projectId) {
545
+ // Only poll for updates if we have a project ID AND no provided project
546
+ if (projectId && !providedProject) {
417
547
  pollTimer = setInterval(function () {
418
548
  loadTheme();
419
549
  }, 5 * 60 * 1000);
@@ -423,7 +553,7 @@ var ThemeProvider = function (_a) {
423
553
  clearInterval(pollTimer);
424
554
  }
425
555
  };
426
- }, [projectId, currentVersion, theme]);
556
+ }, [projectId, currentVersion, theme, providedProject]); // Added providedProject to dependencies
427
557
  var applyThemeData = function (data, root) {
428
558
  var _a;
429
559
  var themeConfig = (_a = data.theme_config) !== null && _a !== void 0 ? _a : {};
@@ -435,6 +565,11 @@ var ThemeProvider = function (_a) {
435
565
  cachedProjectData = data;
436
566
  // Cache for asset access
437
567
  cachedAssets = data.assets || [];
568
+ // Cache for bucket access
569
+ var projectBuckets = data.buckets || [];
570
+ cachedBuckets = projectBuckets.map(function (bucket) {
571
+ return transformProjectBucket(bucket, data.project_id || '');
572
+ });
438
573
  // Apply all theme config to CSS variables
439
574
  applyThemeConfig(themeConfig, root);
440
575
  };
@@ -446,7 +581,8 @@ var ThemeProvider = function (_a) {
446
581
  isLoading: isLoading,
447
582
  isInitialLoad: isInitialLoad,
448
583
  error: error,
449
- }); }, [variant, themeConfig, projectData, isLoading, isInitialLoad, error]);
584
+ projectId: projectId,
585
+ }); }, [variant, themeConfig, projectData, isLoading, isInitialLoad, error, projectId]);
450
586
  return (react_1.default.createElement(ThemeContext.Provider, { value: contextValue },
451
587
  react_1.default.createElement("div", { className: "theme-".concat(theme, " ").concat(funcss), style: {
452
588
  backgroundColor: 'var(--page-bg)',
@@ -619,3 +755,310 @@ var useDocumentAssets = function () {
619
755
  return (0, exports.useAssetsByType)('document');
620
756
  };
621
757
  exports.useDocumentAssets = useDocumentAssets;
758
+ /* -------------------------------------------------------------------------- */
759
+ /* BUCKET HOOKS */
760
+ /* -------------------------------------------------------------------------- */
761
+ // Helper function to get bucket
762
+ var getBucketFromCache = function (bucketIdOrName) {
763
+ if (!cachedBuckets.length) {
764
+ console.warn('No buckets available. Make sure ThemeProvider is mounted.');
765
+ return undefined;
766
+ }
767
+ return cachedBuckets.find(function (b) {
768
+ var _a;
769
+ return b.id === bucketIdOrName ||
770
+ b.name.toLowerCase() === bucketIdOrName.toLowerCase() ||
771
+ ((_a = b.displayName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === bucketIdOrName.toLowerCase();
772
+ });
773
+ };
774
+ // Hook to access all buckets
775
+ var useBuckets = function () {
776
+ var projectData = (0, exports.useTheme)().projectData;
777
+ var _a = (0, react_1.useState)([]), buckets = _a[0], setBuckets = _a[1];
778
+ (0, react_1.useEffect)(function () {
779
+ if (projectData === null || projectData === void 0 ? void 0 : projectData.buckets) {
780
+ var transformedBuckets = projectData.buckets.map(function (bucket) {
781
+ return transformProjectBucket(bucket, projectData.project_id || '');
782
+ });
783
+ setBuckets(transformedBuckets);
784
+ cachedBuckets = transformedBuckets;
785
+ }
786
+ else {
787
+ setBuckets([]);
788
+ }
789
+ }, [projectData]);
790
+ return buckets;
791
+ };
792
+ exports.useBuckets = useBuckets;
793
+ // Hook to get a specific bucket
794
+ var useBucket = function (bucketIdOrName) {
795
+ var buckets = (0, exports.useBuckets)();
796
+ return buckets.find(function (b) {
797
+ var _a;
798
+ return b.id === bucketIdOrName ||
799
+ b.name.toLowerCase() === bucketIdOrName.toLowerCase() ||
800
+ ((_a = b.displayName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === bucketIdOrName.toLowerCase();
801
+ });
802
+ };
803
+ exports.useBucket = useBucket;
804
+ // Hook to get buckets by category
805
+ var useBucketsByCategory = function (category) {
806
+ var buckets = (0, exports.useBuckets)();
807
+ if (category === 'all' || category === 'uncategorized') {
808
+ return buckets.filter(function (b) { return !b.category || b.category === 'uncategorized'; });
809
+ }
810
+ return buckets.filter(function (b) { return b.category === category; });
811
+ };
812
+ exports.useBucketsByCategory = useBucketsByCategory;
813
+ // Hook to get bucket JSON files
814
+ var useBucketJsonFiles = function (bucketIdOrName) {
815
+ var _a = (0, react_1.useState)([]), files = _a[0], setFiles = _a[1];
816
+ var _b = (0, react_1.useState)(true), loading = _b[0], setLoading = _b[1];
817
+ var _c = (0, react_1.useState)(null), error = _c[0], setError = _c[1];
818
+ var bucket = (0, exports.useBucket)(bucketIdOrName);
819
+ var projectId = (0, exports.useTheme)().projectId;
820
+ var loadFiles = (0, react_1.useCallback)(function () { return __awaiter(void 0, void 0, void 0, function () {
821
+ var bucketSanitizedName, jsonFiles, cacheKey, err_2;
822
+ return __generator(this, function (_a) {
823
+ switch (_a.label) {
824
+ case 0:
825
+ if (!bucket || !projectId) {
826
+ setFiles([]);
827
+ setLoading(false);
828
+ return [2 /*return*/];
829
+ }
830
+ _a.label = 1;
831
+ case 1:
832
+ _a.trys.push([1, 3, 4, 5]);
833
+ setLoading(true);
834
+ setError(null);
835
+ bucketSanitizedName = sanitizeBucketName(bucket.displayName || bucket.name);
836
+ return [4 /*yield*/, listBucketJsonFiles(bucketSanitizedName, projectId)];
837
+ case 2:
838
+ jsonFiles = _a.sent();
839
+ setFiles(jsonFiles);
840
+ cacheKey = "".concat(bucket.id, "_").concat(projectId);
841
+ cachedJsonFiles[cacheKey] = jsonFiles;
842
+ return [3 /*break*/, 5];
843
+ case 3:
844
+ err_2 = _a.sent();
845
+ console.error('Error loading JSON files:', err_2);
846
+ setError(err_2 instanceof Error ? err_2.message : 'Failed to load JSON files');
847
+ return [3 /*break*/, 5];
848
+ case 4:
849
+ setLoading(false);
850
+ return [7 /*endfinally*/];
851
+ case 5: return [2 /*return*/];
852
+ }
853
+ });
854
+ }); }, [bucket, projectId]);
855
+ (0, react_1.useEffect)(function () {
856
+ loadFiles();
857
+ }, [loadFiles]);
858
+ return {
859
+ files: files,
860
+ loading: loading,
861
+ error: error,
862
+ refresh: loadFiles
863
+ };
864
+ };
865
+ exports.useBucketJsonFiles = useBucketJsonFiles;
866
+ // Hook to get paginated records (YOU ONLY NEED TO PASS PAGE NUMBER!)
867
+ var usePaginatedRecords = function (bucketIdOrName, page, pageSize) {
868
+ var _a = (0, react_1.useState)([]), records = _a[0], setRecords = _a[1];
869
+ var _b = (0, react_1.useState)(null), metadata = _b[0], setMetadata = _b[1];
870
+ var _c = (0, react_1.useState)(true), loading = _c[0], setLoading = _c[1];
871
+ var _d = (0, react_1.useState)(null), error = _d[0], setError = _d[1];
872
+ var bucket = (0, exports.useBucket)(bucketIdOrName);
873
+ var projectId = (0, exports.useTheme)().projectId;
874
+ var loadRecords = (0, react_1.useCallback)(function () { return __awaiter(void 0, void 0, void 0, function () {
875
+ var bucketSanitizedName, jsonData, recordsToSet, cacheKey, err_3;
876
+ return __generator(this, function (_a) {
877
+ switch (_a.label) {
878
+ case 0:
879
+ if (!bucket || !projectId) {
880
+ setRecords([]);
881
+ setMetadata(null);
882
+ setLoading(false);
883
+ return [2 /*return*/];
884
+ }
885
+ _a.label = 1;
886
+ case 1:
887
+ _a.trys.push([1, 3, 4, 5]);
888
+ setLoading(true);
889
+ setError(null);
890
+ bucketSanitizedName = sanitizeBucketName(bucket.displayName || bucket.name);
891
+ return [4 /*yield*/, loadBucketJsonFromCDN(bucketSanitizedName, projectId, page)];
892
+ case 2:
893
+ jsonData = _a.sent();
894
+ if (jsonData) {
895
+ recordsToSet = jsonData.records || [];
896
+ // If pageSize is specified, limit the records
897
+ if (pageSize && recordsToSet.length > pageSize) {
898
+ recordsToSet = recordsToSet.slice(0, pageSize);
899
+ }
900
+ setRecords(recordsToSet);
901
+ setMetadata(jsonData.metadata);
902
+ cacheKey = "".concat(bucket.id, "_").concat(projectId);
903
+ if (!cachedJsonData[cacheKey]) {
904
+ cachedJsonData[cacheKey] = {};
905
+ }
906
+ cachedJsonData[cacheKey][page] = jsonData;
907
+ }
908
+ else {
909
+ setRecords([]);
910
+ setMetadata(null);
911
+ }
912
+ return [3 /*break*/, 5];
913
+ case 3:
914
+ err_3 = _a.sent();
915
+ console.error("Error loading records for page ".concat(page, ":"), err_3);
916
+ setError(err_3 instanceof Error ? err_3.message : 'Failed to load records');
917
+ return [3 /*break*/, 5];
918
+ case 4:
919
+ setLoading(false);
920
+ return [7 /*endfinally*/];
921
+ case 5: return [2 /*return*/];
922
+ }
923
+ });
924
+ }); }, [bucket, projectId, page, pageSize]);
925
+ (0, react_1.useEffect)(function () {
926
+ loadRecords();
927
+ }, [loadRecords]);
928
+ return {
929
+ records: records,
930
+ metadata: metadata,
931
+ loading: loading,
932
+ error: error,
933
+ refresh: loadRecords
934
+ };
935
+ };
936
+ exports.usePaginatedRecords = usePaginatedRecords;
937
+ // Hook to get all records from JSON files
938
+ var useAllJsonRecords = function (bucketIdOrName) {
939
+ var _a = (0, react_1.useState)([]), records = _a[0], setRecords = _a[1];
940
+ var _b = (0, react_1.useState)(true), loading = _b[0], setLoading = _b[1];
941
+ var _c = (0, react_1.useState)(null), error = _c[0], setError = _c[1];
942
+ var bucket = (0, exports.useBucket)(bucketIdOrName);
943
+ var projectId = (0, exports.useTheme)().projectId;
944
+ var _d = (0, exports.useBucketJsonFiles)(bucketIdOrName), files = _d.files, filesLoading = _d.loading;
945
+ var loadAllRecords = (0, react_1.useCallback)(function () { return __awaiter(void 0, void 0, void 0, function () {
946
+ var allRecords, _i, files_1, file, bucketSanitizedName, jsonData, err_4;
947
+ return __generator(this, function (_a) {
948
+ switch (_a.label) {
949
+ case 0:
950
+ if (!bucket || !projectId || filesLoading) {
951
+ return [2 /*return*/];
952
+ }
953
+ _a.label = 1;
954
+ case 1:
955
+ _a.trys.push([1, 6, 7, 8]);
956
+ setLoading(true);
957
+ setError(null);
958
+ allRecords = [];
959
+ _i = 0, files_1 = files;
960
+ _a.label = 2;
961
+ case 2:
962
+ if (!(_i < files_1.length)) return [3 /*break*/, 5];
963
+ file = files_1[_i];
964
+ bucketSanitizedName = sanitizeBucketName(bucket.displayName || bucket.name);
965
+ return [4 /*yield*/, loadBucketJsonFromCDN(bucketSanitizedName, projectId, file.page)];
966
+ case 3:
967
+ jsonData = _a.sent();
968
+ if (jsonData && jsonData.records) {
969
+ allRecords.push.apply(allRecords, jsonData.records);
970
+ }
971
+ _a.label = 4;
972
+ case 4:
973
+ _i++;
974
+ return [3 /*break*/, 2];
975
+ case 5:
976
+ setRecords(allRecords);
977
+ return [3 /*break*/, 8];
978
+ case 6:
979
+ err_4 = _a.sent();
980
+ console.error('Error loading all records:', err_4);
981
+ setError(err_4 instanceof Error ? err_4.message : 'Failed to load records');
982
+ return [3 /*break*/, 8];
983
+ case 7:
984
+ setLoading(false);
985
+ return [7 /*endfinally*/];
986
+ case 8: return [2 /*return*/];
987
+ }
988
+ });
989
+ }); }, [bucket, projectId, files, filesLoading]);
990
+ (0, react_1.useEffect)(function () {
991
+ if (!filesLoading) {
992
+ loadAllRecords();
993
+ }
994
+ }, [loadAllRecords, filesLoading]);
995
+ return {
996
+ records: records,
997
+ loading: loading || filesLoading,
998
+ error: error,
999
+ refresh: loadAllRecords
1000
+ };
1001
+ };
1002
+ exports.useAllJsonRecords = useAllJsonRecords;
1003
+ // Hook for cache management
1004
+ var useBucketCache = function () {
1005
+ var clearCache = (0, react_1.useCallback)(function (bucketIdOrName) {
1006
+ if (bucketIdOrName) {
1007
+ var bucket = getBucketFromCache(bucketIdOrName);
1008
+ if (bucket) {
1009
+ var projectId = (0, react_1.useContext)(ThemeContext).projectId;
1010
+ if (projectId) {
1011
+ var cacheKey = "".concat(bucket.id, "_").concat(projectId);
1012
+ delete cachedJsonFiles[cacheKey];
1013
+ delete cachedJsonData[cacheKey];
1014
+ }
1015
+ }
1016
+ }
1017
+ else {
1018
+ cachedJsonFiles = {};
1019
+ cachedJsonData = {};
1020
+ }
1021
+ }, []);
1022
+ var refresh = (0, react_1.useCallback)(function () {
1023
+ // This will be handled by the ThemeProvider when project data changes
1024
+ console.log('Buckets will refresh when project data updates');
1025
+ }, []);
1026
+ return {
1027
+ clearCache: clearCache,
1028
+ refresh: refresh
1029
+ };
1030
+ };
1031
+ exports.useBucketCache = useBucketCache;
1032
+ // Helper function to get bucket records (for non-hook usage)
1033
+ var getPaginatedRecords = function (bucketIdOrName, page, pageSize) { return __awaiter(void 0, void 0, void 0, function () {
1034
+ var bucket, projectId, bucketSanitizedName, jsonData, records;
1035
+ return __generator(this, function (_a) {
1036
+ switch (_a.label) {
1037
+ case 0:
1038
+ bucket = getBucketFromCache(bucketIdOrName);
1039
+ if (!bucket) {
1040
+ throw new Error("Bucket not found: ".concat(bucketIdOrName));
1041
+ }
1042
+ projectId = (0, react_1.useContext)(ThemeContext).projectId;
1043
+ if (!projectId) {
1044
+ throw new Error('Project ID not available');
1045
+ }
1046
+ bucketSanitizedName = sanitizeBucketName(bucket.displayName || bucket.name);
1047
+ return [4 /*yield*/, loadBucketJsonFromCDN(bucketSanitizedName, projectId, page)];
1048
+ case 1:
1049
+ jsonData = _a.sent();
1050
+ if (!jsonData) {
1051
+ return [2 /*return*/, { records: [], metadata: null }];
1052
+ }
1053
+ records = jsonData.records || [];
1054
+ if (pageSize && records.length > pageSize) {
1055
+ records = records.slice(0, pageSize);
1056
+ }
1057
+ return [2 /*return*/, {
1058
+ records: records,
1059
+ metadata: jsonData.metadata
1060
+ }];
1061
+ }
1062
+ });
1063
+ }); };
1064
+ exports.getPaginatedRecords = getPaginatedRecords;
package/ui/vista/Vista.js CHANGED
@@ -186,23 +186,19 @@ var Vista = function (localProps) {
186
186
  position: 'relative',
187
187
  width: '100%',
188
188
  maxWidth: mediaSize || '100%',
189
- aspectRatio: '16/9',
190
189
  margin: '0 auto',
190
+ height: 'fit-content',
191
191
  } },
192
- react_1.default.createElement("div", { style: {
193
- position: 'relative',
192
+ react_1.default.createElement("iframe", { src: final.iframeUrl, className: "vista-iframe ".concat(final.mediaCss || ''), style: {
194
193
  width: '100%',
195
- height: '100%',
194
+ height: 'auto',
195
+ aspectRatio: '16/9',
196
+ border: 'none',
197
+ display: 'block', // Crucial for 'height: auto' to work reliably
196
198
  filter: getFilterStyle(final.mediaFilter, final.mediaFilterValue),
197
199
  mixBlendMode: final.mediaBlendMode,
198
- } },
199
- react_1.default.createElement("iframe", { src: final.iframeUrl, className: "vista-iframe ".concat(final.mediaCss || ''), style: {
200
- width: '100%',
201
- height: '100%',
202
- border: 'none',
203
- display: 'block',
204
- }, allowFullScreen: true, allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture", title: "Vista media content" }),
205
- final.mediaOverlay && react_1.default.createElement("div", { style: overlayStyle })))),
200
+ }, allowFullScreen: true, allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture", title: "Vista media content" }),
201
+ final.mediaOverlay && react_1.default.createElement("div", { style: overlayStyle }))),
206
202
  mediaType === 'image' && (final.media || final.mediaUrl) && (react_1.default.createElement("div", { style: { position: 'relative', width: '100%' } },
207
203
  final.media ? (react_1.default.createElement("div", { style: { width: '100%', maxWidth: mediaSize, margin: '0 auto' } }, final.media)) : (react_1.default.createElement("img", { src: final.mediaUrl, alt: final.mediaAlt || 'Vista media', className: final.mediaCss || '', style: mediaStyle, loading: "lazy" })),
208
204
  final.mediaOverlay && react_1.default.createElement("div", { style: overlayStyle })))));
File without changes
@@ -0,0 +1 @@
1
+ "use strict";