react-native-custom-splash 2.0.2 → 2.1.1

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 (2) hide show
  1. package/package.json +1 -1
  2. package/plugin/src/index.js +123 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-custom-splash",
3
- "version": "2.0.2",
3
+ "version": "2.1.1",
4
4
  "description": "A custom splash screen module for React Native with native iOS and Android support, fully compatible with Expo",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -8,7 +8,6 @@ const {
8
8
  } = require('@expo/config-plugins');
9
9
  const path = require('path');
10
10
  const fs = require('fs');
11
- const { generateImageAsync } = require('@expo/image-utils');
12
11
 
13
12
  /**
14
13
  * Validate and normalize plugin configuration
@@ -355,20 +354,107 @@ const withSplashScreenAndroid = (config, pluginConfig) => {
355
354
  return config;
356
355
  };
357
356
 
357
+ /**
358
+ * Create LaunchScreen.storyboard with splash configuration
359
+ */
360
+ function createLaunchScreenStoryboard(hasImage, hasLogo, backgroundColor) {
361
+ const bgColor = backgroundColor.replace('#', '');
362
+ const r = parseInt(bgColor.substr(0, 2), 16) / 255;
363
+ const g = parseInt(bgColor.substr(2, 2), 16) / 255;
364
+ const b = parseInt(bgColor.substr(4, 2), 16) / 255;
365
+
366
+ const imageViewXML = hasImage ? `
367
+ <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="splash_image" translatesAutoresizingMaskIntoConstraints="NO" id="splashBgImage">
368
+ <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
369
+ </imageView>` : '';
370
+
371
+ const logoViewXML = hasLogo ? `
372
+ <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="splash_logo" translatesAutoresizingMaskIntoConstraints="NO" id="splashLogo">
373
+ <rect key="frame" x="132" y="348" width="150" height="150"/>
374
+ <constraints>
375
+ <constraint firstAttribute="width" constant="150" id="logoWidth"/>
376
+ <constraint firstAttribute="height" constant="150" id="logoHeight"/>
377
+ </constraints>
378
+ </imageView>` : '';
379
+
380
+ const imageConstraints = hasImage ? `
381
+ <constraint firstItem="splashBgImage" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="bgTop"/>
382
+ <constraint firstItem="splashBgImage" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="bgLeading"/>
383
+ <constraint firstItem="splashBgImage" firstAttribute="trailing" secondItem="Ze5-6b-2t3" secondAttribute="trailing" id="bgTrailing"/>
384
+ <constraint firstItem="splashBgImage" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="bgBottom"/>` : '';
385
+
386
+ const logoConstraints = hasLogo ? `
387
+ <constraint firstItem="splashLogo" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="logoCenterX"/>
388
+ <constraint firstItem="splashLogo" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="logoCenterY"/>` : '';
389
+
390
+ const imageResources = [];
391
+ if (hasImage) imageResources.push('<image name="splash_image" width="1242" height="2688"/>');
392
+ if (hasLogo) imageResources.push('<image name="splash_logo" width="512" height="512"/>');
393
+
394
+ return `<?xml version="1.0" encoding="UTF-8"?>
395
+ <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
396
+ <device id="retina6_1" orientation="portrait" appearance="light"/>
397
+ <dependencies>
398
+ <deployment identifier="iOS"/>
399
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
400
+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
401
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
402
+ </dependencies>
403
+ <scenes>
404
+ <!--View Controller-->
405
+ <scene sceneID="EHf-IW-A2E">
406
+ <objects>
407
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
408
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
409
+ <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
410
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
411
+ <subviews>${imageViewXML}${logoViewXML}
412
+ </subviews>
413
+ <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
414
+ <color key="backgroundColor" red="${r}" green="${g}" blue="${b}" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
415
+ <constraints>${imageConstraints}${logoConstraints}
416
+ </constraints>
417
+ </view>
418
+ </viewController>
419
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
420
+ </objects>
421
+ <point key="canvasLocation" x="53" y="375"/>
422
+ </scene>
423
+ </scenes>
424
+ <resources>${imageResources.join('\n ')}
425
+ </resources>
426
+ </document>`;
427
+ }
428
+
358
429
  /**
359
430
  * Plugin to configure iOS splash screen
360
431
  */
361
432
  const withSplashScreenIOS = (config, pluginConfig) => {
362
- return withDangerousMod(config, [
433
+ // Step 1: Update Info.plist to use our LaunchScreen
434
+ config = IOSConfig.InfoPlist.withInfoPlist(config, (config) => {
435
+ // Set our LaunchScreen as the launch storyboard
436
+ config.modResults.UILaunchStoryboardName = 'LaunchScreen';
437
+
438
+ // Remove Expo's default splash screen configuration
439
+ delete config.modResults.UILaunchScreen;
440
+
441
+ return config;
442
+ });
443
+
444
+ // Step 2: Create our custom LaunchScreen.storyboard and copy images
445
+ config = withDangerousMod(config, [
363
446
  'ios',
364
447
  async (config) => {
365
448
  const projectRoot = config.modRequest.projectRoot;
366
449
  const iosProjectPath = config.modRequest.platformProjectRoot;
367
450
  const projectName = config.modRequest.projectName;
368
451
 
452
+ let hasImage = false;
453
+ let hasLogo = false;
454
+
369
455
  // Copy images to iOS assets
370
456
  if (pluginConfig.image) {
371
- await copyImageToIOS(
457
+ hasImage = await copyImageToIOS(
372
458
  projectRoot,
373
459
  pluginConfig.image,
374
460
  'splash_image',
@@ -378,7 +464,7 @@ const withSplashScreenIOS = (config, pluginConfig) => {
378
464
  }
379
465
 
380
466
  if (pluginConfig.logo) {
381
- await copyImageToIOS(
467
+ hasLogo = await copyImageToIOS(
382
468
  projectRoot,
383
469
  pluginConfig.logo,
384
470
  'splash_logo',
@@ -387,9 +473,42 @@ const withSplashScreenIOS = (config, pluginConfig) => {
387
473
  );
388
474
  }
389
475
 
476
+ // Create LaunchScreen.storyboard
477
+ const launchScreenPath = path.join(
478
+ iosProjectPath,
479
+ projectName,
480
+ 'LaunchScreen.storyboard'
481
+ );
482
+
483
+ const storyboardContent = createLaunchScreenStoryboard(
484
+ hasImage,
485
+ hasLogo,
486
+ pluginConfig.backgroundColor
487
+ );
488
+
489
+ fs.writeFileSync(launchScreenPath, storyboardContent);
490
+
491
+ // Remove SplashScreenLegacy if it exists (from Expo's default splash)
492
+ const legacyPath = path.join(
493
+ iosProjectPath,
494
+ projectName,
495
+ 'Images.xcassets',
496
+ 'SplashScreenLegacy.imageset'
497
+ );
498
+
499
+ if (fs.existsSync(legacyPath)) {
500
+ fs.rmSync(legacyPath, { recursive: true, force: true });
501
+ console.log('🗑️ Removed SplashScreenLegacy');
502
+ }
503
+
504
+ console.log('✅ iOS LaunchScreen.storyboard created with YOUR images!');
505
+ console.log('✅ Info.plist configured to use LaunchScreen');
506
+
390
507
  return config;
391
508
  },
392
509
  ]);
510
+
511
+ return config;
393
512
  };
394
513
 
395
514
  /**
@@ -407,8 +526,6 @@ module.exports = (config, props = {}) => {
407
526
  pluginConfig = getPluginConfig(config);
408
527
  }
409
528
 
410
- console.log('✅ react-native-custom-splash configured with:', pluginConfig);
411
-
412
529
  return withPlugins(config, [
413
530
  [withSplashScreenAndroid, pluginConfig],
414
531
  [withSplashScreenIOS, pluginConfig],