diff --git a/docs/embedding-snacks.md b/docs/embedding-snacks.md index c2b01fcd2..aefb6c096 100644 --- a/docs/embedding-snacks.md +++ b/docs/embedding-snacks.md @@ -43,7 +43,8 @@ The `embed.js` script scans the DOM and populates any elements containing a `dat | `data-snack-platform`| The default platform to preview the Snack on. Defaults to `web` which will run as soon as your users see the Snack. Valid values: `ios`, `android`, `web`, `mydevice`. | | `data-snack-preview`| Shows or hides the preview pane. Defaults to `true` using `embed.js` Snacks. Valid values: `true`, `false`. | | `data-snack-sdkversion` | The Expo SDK version to use (eg. `38.0.0`). Defaults to the latest released Expo SDK version. | -| `data-snack-supportedplatforms` | The platforms available for previewing the Snack. Defaults to `mydevice,ios,android,web` when not specified. | +| `data-snack-supported-platforms` | The platforms available for previewing the Snack. Defaults to `mydevice,ios,android,web` when not specified. | +| `data-snack-initially-selected-file` | The filename of the file to show in the embedded snack. | | `data-snack-theme` | The theme to use, `light` or `dark`. When omitted uses the theme that was configured by the user (defaults to `light`). | | `data-snack-device-frame` | If the outline of the device should be rendered or not. Valid values: `true` or `false`. | | `data-snack-device-android` | The emulator used when running the Android device. Valid values: any of the [Appetize `device` Playback options](https://docs.appetize.io/core-features/playback-options). Note, this also has effect on the used Android version. | diff --git a/docs/url-query-parameters.md b/docs/url-query-parameters.md index 53f8d0df8..0b4eee2ed 100644 --- a/docs/url-query-parameters.md +++ b/docs/url-query-parameters.md @@ -30,6 +30,7 @@ The main Snack website is hosted at [https://snack.expo.dev](https://snack.expo. | `sdkVersion` | `&sdkVersion=38.0.0` | The Expo SDK version to use. Defaults to the latest released Expo SDK version. | | `sourceUrl` | `&sourceUrl=http://mysite.com/file.js` | Using `sourceUrl` you can host your own code for a Snack anywhere you like. Just provide a url for a publicly accessible resource to the sourceUrl attribute. When specified, causes the `code` and `files` attributes to be ignored. | | `supportedPlatforms` | `&supportedPlatforms=ios,web` | The platforms available for previewing the Snack. Defaults to `mydevice,ios,android,web` when not specified. | +| `initiallySelectedFile` | `&initiallySelectedFile=package.json` | The name of the file to have initially selected. Defaults to `App.js` or `App.tsx` or `app.js` or the first file when not specified. | | `theme` | `&theme=dark` | The theme to use, `light` or `dark`. When omitted uses the theme that was configured by the user (defaults to `light`). | | `verbose` | `&verbose=true` | Enables verbose logging in the console (defaults to `false`). This can be useful to diagnose problems with Snacks or packages. | diff --git a/website/README.md b/website/README.md index 4a385cb66..d126950cd 100644 --- a/website/README.md +++ b/website/README.md @@ -137,6 +137,7 @@ Here is a summary of all the parameter options that you can use: | **sdkVersion** | _[default SDK](../packages/snack-content/src/defaults.ts#L3)_ | The Expo SDK version that your Snack should use. | [SDKVersion](../packages/snack-content/src/sdks/types.ts#L4) | | **sourceUrl** | | One of two ways to send a file, via publicly-accessible URL of a JS file. | `string` | | **supportedPlatforms** | All platforms | Specify which platforms your Snack supports | `android \| ios \| mydevice \| web` | +| **initiallySelectedFile** | | The name of the file to have initially selected. | `string` | | **theme** | `light` | The visual theme of your Snack. | `light \| dark` | ### Examples of Snack URLs @@ -151,6 +152,7 @@ All of these examples should be prefixed with `https://snack.expo.dev/`. | **preview** | _[`?preview=false`](https://snack.expo.dev/?preview=false)_ | | **sdkVerion** | _[`?sdkVersion=45.0.0`](https://snack.expo.dev/?sdkVersion=45.0.0)_ | | **supportedPlatforms** | _[`?supportedPlatforms=android,ios`](https://snack.expo.dev/?supportedPlatforms=android,ios)_ | +| **initiallySelectedFile** | _[`?initiallySelectedFile=package.json`](https://snack.expo.dev/?initiallySelectedFile=package.json)_ | | **theme** | _[`?theme=dark`](https://snack.expo.dev/?theme=dark)_ | | **dependencies** | _[`?dependencies=%40expo%2Fvector-icons%40*%2C%40react-native-community%2Fmasked-view`](https://snack.expo.dev/?dependencies=%40expo%2Fvector-icons%40*%2C%40react-native-community%2Fmasked-view)_ | | **files** | _[`?files=%7B%22type%22%3A%20%22CODE%22%2C%20%22contents%22%3A%20%22alert%28%27hello%27%29%3B%22%20%7D`](https://snack.expo.dev/?files=%7B%22type%22%3A%20%22CODE%22%2C%20%22contents%22%3A%20%22alert%28%27hello%27%29%3B%22%20%7D)_ | diff --git a/website/src/client/components/App.tsx b/website/src/client/components/App.tsx index 05ceeb0cc..82bd21d5f 100644 --- a/website/src/client/components/App.tsx +++ b/website/src/client/components/App.tsx @@ -239,15 +239,24 @@ class Main extends React.Component { }, }; - const selectedFile = files['App.js'] - ? 'App.js' - : files['App.tsx'] - ? 'App.tsx' - : files['app.js'] - ? 'app.js' - : Object.keys(files).length - ? Object.keys(files)[0] - : ''; + const hasInitiallySelectedFile = Boolean( + props.query.initiallySelectedFile && + (files[props.query.initiallySelectedFile] || + props.query.initiallySelectedFile === 'package.json') + ); + + const selectedFile = + hasInitiallySelectedFile && props.query.initiallySelectedFile + ? props.query.initiallySelectedFile + : files['App.js'] + ? 'App.js' + : files['App.tsx'] + ? 'App.tsx' + : files['app.js'] + ? 'app.js' + : Object.keys(files).length + ? Object.keys(files)[0] + : ''; this.state = { session: this._snack.getState(), @@ -926,6 +935,7 @@ class Main extends React.Component { upgradedFromSDKVersion={ this.state.wasUpgraded ? this.state.initialSdkVersion : undefined } + initiallySelectedFile={this.props.query.initiallySelectedFile} /> ) : isEmbedded ? ( diff --git a/website/src/client/components/EditorViewProps.tsx b/website/src/client/components/EditorViewProps.tsx index 855b8bcfe..79e83c775 100644 --- a/website/src/client/components/EditorViewProps.tsx +++ b/website/src/client/components/EditorViewProps.tsx @@ -76,4 +76,5 @@ export type EditorViewProps = { devices: AppetizeDevices; verbose: boolean; snackagerURL: string; + initiallySelectedFile?: string; }; diff --git a/website/src/client/types.tsx b/website/src/client/types.tsx index 13bb674c5..d0692f894 100644 --- a/website/src/client/types.tsx +++ b/website/src/client/types.tsx @@ -96,6 +96,7 @@ export type QueryInitParams = { waitForData?: 'boolean'; saveToAccount?: 'true' | 'false'; testTransport?: 'snackpub' | 'trafficMirroring'; + initiallySelectedFile?: string; }; export type QueryStateParams = { diff --git a/website/src/client/utils/embeddedSession.tsx b/website/src/client/utils/embeddedSession.tsx index 40ac53ec7..e7da90f56 100644 --- a/website/src/client/utils/embeddedSession.tsx +++ b/website/src/client/utils/embeddedSession.tsx @@ -8,6 +8,7 @@ type SnackEmbeddedSession = { dependencies: SnackDependencies; sdkVersion: SDKVersion; platform: Platform; + initiallySelectedFile?: string; }; declare global { @@ -22,6 +23,7 @@ export function openEmbeddedSessionFullScreen(session: SnackEmbeddedSession) { name: session.name, description: session.description, platform: session.platform, + initiallySelectedFile: session.initiallySelectedFile, hideQueryParams: 'true', preview: undefined, // Use default preview setting theme: undefined, // Use default theme setting @@ -41,6 +43,7 @@ export function openEmbeddedSessionFullScreen(session: SnackEmbeddedSession) { dependencies: session.dependencies, sdkVersion: session.sdkVersion, platform: session.platform, + initiallySelectedFile: session.initiallySelectedFile, }; } else { throw new Error('No window');