diff --git a/guides/assets/images/first-ios.png b/guides/assets/images/first-ios.png
new file mode 100644
index 00000000..c5f38851
Binary files /dev/null and b/guides/assets/images/first-ios.png differ
diff --git a/guides/assets/images/first-web.png b/guides/assets/images/first-web.png
new file mode 100644
index 00000000..7a0ecf50
Binary files /dev/null and b/guides/assets/images/first-web.png differ
diff --git a/guides/assets/images/hello-ipad.png b/guides/assets/images/hello-ipad.png
index fb3fad09..1ee738d9 100644
Binary files a/guides/assets/images/hello-ipad.png and b/guides/assets/images/hello-ipad.png differ
diff --git a/guides/assets/images/hello-iphone.png b/guides/assets/images/hello-iphone.png
index c5f38851..7c48ca30 100644
Binary files a/guides/assets/images/hello-iphone.png and b/guides/assets/images/hello-iphone.png differ
diff --git a/guides/assets/images/hello-mac.png b/guides/assets/images/hello-mac.png
index 80f26ff0..c5c8c2f3 100644
Binary files a/guides/assets/images/hello-mac.png and b/guides/assets/images/hello-mac.png differ
diff --git a/guides/assets/images/hello-watch.png b/guides/assets/images/hello-watch.png
new file mode 100644
index 00000000..8fff842a
Binary files /dev/null and b/guides/assets/images/hello-watch.png differ
diff --git a/guides/assets/images/hello-web.png b/guides/assets/images/hello-web.png
index 7a0ecf50..52021b6a 100644
Binary files a/guides/assets/images/hello-web.png and b/guides/assets/images/hello-web.png differ
diff --git a/guides/common-features/modifiers.md b/guides/common-features/modifiers.md
deleted file mode 100644
index a791e8df..00000000
--- a/guides/common-features/modifiers.md
+++ /dev/null
@@ -1,188 +0,0 @@
-# Modifiers
-
-Platform libraries may provide any number of modifiers for customizing the look and feel of native
-elements. These modifiers are automatically available as functions when rendering platform-specific
-templates in a module that uses one of the following macros:
-
-- `LiveViewNative.LiveView`
-- `LiveViewNative.LiveComponent`
-- `LiveViewNative.Component`
-
-Modifiers are typically used to adjust styling (colors, typography, etc.), presentation, interactivity
-and other properties of the native UI you're targeting.
-
-## Modifier functions
-
-Here's a simple example of calling modifier functions inline for elements with the `modifiers` attribute in SwiftUI:
-
-
-
-### Source
-
-```elixir
-defmodule MyAppWeb.ModifiersExampleLive do
- use Phoenix.LiveView
- use MyAppWeb, :live_view
-
- @impl true
- def render(%{format: :swiftui} = assigns) do
- # This UI renders on the iPhone / iPad app
- ~SWIFTUI"""
-
- This text is normal
- This text is bold
-
-
- foreground_style({:color, :white})
- }>
- foreground_style({:color, :red})
- } />
-
-
-
- """
- end
-end
-```
-
-### Result
-
-![Modifiers example](./assets/images/modifiers-example.png)
-
-
-
-Modifier functions may have different arities and take different types of arguments, which are generally based on the
-original APIs they're based on. All modifier functions return a `%LiveViewNativePlatform.Env{}` struct (same as the
-`@native` assign) which can be passed to other modifier functions, effectively allowing them to be chained together.
-
-For more information of which modifiers a platform supports and how to use them, check the documentation for that
-platform as well as the relevant source material for that platform.
-
-## Modifier Classes
-
-Using a lot of modifiers in your templates can cause them to become overly verbose and difficult to maintain over
-time. You also might want to share modifiers between many different views and elements instead of copying them
-across templates. Modifier classes solve both of these problems by letting you decouple your modifiers from your
-templates.
-
-Here's the previous example, adjusted to use modifier classes defined in a separate module:
-
-
-
-### modifiers_example_live.ex
-
-```elixir
-defmodule MyAppWeb.ModifiersExampleLive do
- use Phoenix.LiveView
- use MyAppWeb, :live_view
-
- import MyAppWeb.Modclasses, only: [modclass: 3]
-
- @impl true
- def render(%{format: :swiftui} = assigns) do
- ~SWIFTUI"""
-
- This text is normal
- This text is bold
-
-
-
-
-
-
-
- """
- end
-end
-```
-
-### modclasses.ex
-
-```elixir
-defmodule MyAppWeb.Modclasses do
- use LiveViewNative.Modclasses, platform: :swiftui
-
- def modclass(native, "bold", _assigns) do
- font_weight(native, :bold)
- end
-
- def modclass(native, "spacer", _assigns) do
- frame(native, height: 16)
- end
-
- def modclass(native, "heart", _assigns) do
- native
- |> background(alignment: :center, content: :heart_bg)
- |> foreground_style({:color, :white})
- end
-
- def modclass(native, "heart_bg", _assigns) do
- native
- |> frame(width: 32, height: 32)
- |> foreground_style({:color, :red})
- end
-end
-```
-
-### Result
-
-![Modifiers example](./assets/images/modifiers-example.png)
-
-
-
-An element can have any number of modifier classes, providing some composability for modifier functions:
-
-
-
-### modifiers_example_live.ex
-
-```elixir
-defmodule MyAppWeb.ModifiersExampleLive do
- use Phoenix.LiveView
- use MyAppWeb, :live_view
-
- import MyAppWeb.Modclasses, only: [modclass: 3]
-
- @impl true
- def render(%{format: :swiftui} = assigns) do
- ~SWIFTUI"""
-
- This text is normal
- This text is bold
- This text is bold
- This text is bold and italic
-
- """
- end
-end
-```
-
-### modclasses.ex
-
-```elixir
-defmodule MyAppWeb.Modclasses do
- use LiveViewNative.Modclasses, platform: :swiftui
-
- def modclass(native, "bold", _assigns) do
- font_weight(native, :bold)
- end
-
- def modclass(native, "italic", _assigns) do
- italic(native, %{})
- end
-end
-```
-
-### Result
-
-![Modclasses example](./assets/images/modclasses-example.png)
-
-
-
-Modclasses within templates are translated at compile-time to their inline counterparts, so passing an assign or other
-dynamic value to the `modclass` attribute won't work. To support dynamic modifier classes that reference assigns or the
-modifier name itself, define any conditional logic within `modclass/3`.
diff --git a/guides/common-features/render-patterns.md b/guides/common-features/render-patterns.md
index 7c72a826..216ecfdb 100644
--- a/guides/common-features/render-patterns.md
+++ b/guides/common-features/render-patterns.md
@@ -50,8 +50,6 @@ defmodule MyAppWeb.SharedComponents do
use Phoenix.Component
use LiveViewNative.Component
- import ElixirconfChatWeb.Modclasses.SwiftUi, only: [modclass: 3]
-
def logo(%{format: :swiftui} = assigns) do
~SWIFTUI"""
@@ -106,7 +104,7 @@ end
### hello_live.swiftui.heex
```heex
-
+ A SwiftUI template, courtesy of hello_live.swiftui.heex
@@ -125,19 +123,17 @@ defmodule MyAppWeb.SharedComponents do
use Phoenix.Component
use LiveViewNative.Component
- import ElixirconfChatWeb.Modclasses.SwiftUi, only: [modclass: 3]
-
def logo(%{format: :swiftui} = assigns) do
~SWIFTUI"""
- <%= case @native.platform_config.user_interface_idiom do %>
- <% "mac" -> %>
+ <%= case @target do %>
+ <% :mac -> %>
Hello macOS!
- <% "pad" -> %>
+ <% :pad -> %>
Hello iPadOS!
- <% "watch" -> %>
+ <% :watch -> %>
Hello watchOS!
- <% "tv" -> %>
+ <% :tv -> %>
Hello tvOS!
<% _ -> %>
Hello iOS!
diff --git a/guides/common-features/template-syntax.md b/guides/common-features/template-syntax.md
index 9fdfe02a..dbcdeb04 100644
--- a/guides/common-features/template-syntax.md
+++ b/guides/common-features/template-syntax.md
@@ -26,7 +26,7 @@ defmodule MyAppWeb.MyComponents do
- <%= song.title %>
+ <%= song.title %><%= song.artist.name %>
@@ -71,7 +71,6 @@ Here we can observe various semantic changes to port SwiftUI code to EEx:
2. The struct value `album` is an assign, `@album`, instead.
3. Instead of passing `album.songs` as an argument, we use a comprehension.
- `` elements take their arguments as values, similar to HTML.
-4. We can't call a function on an element like in SwiftUI, so the `.fontWeight(.bold)` modifier function is called as `font_weight(:bold)` and passed to the `modifiers` attribute.
These conventions can generally be applied to all sorts of examples when using LiveView Native to build SwiftUI views.
Because LiveView Native is modular, each platform library will have its own way of "bridging the gap" between the Elixir
diff --git a/guides/introduction/installation.md b/guides/introduction/installation.md
index d74452b9..7c285665 100644
--- a/guides/introduction/installation.md
+++ b/guides/introduction/installation.md
@@ -1,12 +1,12 @@
# Installation
-There are a few steps that must be completed before you can use LiveView Native. This document covers them, which are as follows:
+There are a number of steps that must be completed before you can use LiveView Native. This document covers them, which are as follows:
-1. Setup a Phoenix project with the minimum required versions of Elixir, Phoenix and LiveView.
-2. Add LiveView Native to your `mix.exs` dependencies.
-3. Add any number of platform libraries to enable support for native clients.
-4. Fetch dependencies.
-5. Enable LiveView Native within your app.
+1. Setup your Phoenix project with the minimum required versions of Elixir, Phoenix and LiveView
+2. Add LiveView Native to your `mix.exs` dependencies
+3. Add any number of platform libraries to enable support for native clients
+4. Configure your project to use LiveView Native
+5. Update your application's web module, router and layouts
## 1. Prepare your Phoenix app
@@ -46,16 +46,16 @@ Once you've met the requirements to use LiveView Native, simply add it to your l
def deps do
[
# other dependencies here...
- {:live_view_native, "~> 0.1"}
+ {:live_view_native, "~> 0.2"}
]
end
```
## 3. Add platform libraries
-The `:live_view_native` dependency isn't useful on its own. You'll also need to add any _platform libraries_ you want your project to be compatible with. Platform libraries provide the native implementations that allow those platforms' clients to connect to your app and render LiveView paths as native user interfaces.
+The `:live_view_native` dependency isn't useful on its own. You'll also need to add any _platform libraries_ you want your project to be compatible with. These libraries provide the platform-specific code that allows them to connect to your app and render LiveViews within their native environments.
-This guide only covers installation for the officially supported platforms, [SwiftUI](https://hexdocs.pm/live_view_native_swift_ui) (iOS, macOS and watchOS) and [Jetpack](https://hexdocs.pm/live_view_native_jetpack) (Android). For information on using a third-party platform, consult that library's documentation.
+This guide covers installation for the officially supported platforms, [SwiftUI](https://hexdocs.pm/live_view_native_swift_ui) (iOS, macOS and watchOS) and [Jetpack](https://hexdocs.pm/live_view_native_jetpack) (Android).
@@ -66,7 +66,7 @@ Adds compatibility for iOS 16+, macOS 13+ and watchOS 9+.
def deps do
[
# other dependencies here...
- {:live_view_native_swift_ui, "~> 0.1"}
+ {:live_view_native_swift_ui, "~> 0.2"}
]
end
```
@@ -90,21 +90,19 @@ end
-## 4. Fetch dependencies
-
-Next, fetch any new dependencies you added to your `mix.exs`.
+Make sure to fetch any dependencies you've added to your `mix.exs` before continuing:
```bash
mix deps.get
```
-## 5. Enable LiveView Native
+## 4. Configure LiveView Native
LiveView Native includes a Mix task that can automatically handle the process of configuring your project to support it. If that is not to your liking, manual setup is also an option. This guide includes instructions for both of these approaches.
-### Automatic
+### Guided (recommended)
Within your project directory, run the following command:
@@ -128,16 +126,179 @@ config :live_view_native,
LiveViewNative.SwiftUI,
LiveViewNative.Jetpack
]
+
+# LiveView Native Stylesheet support
+# Omit this if you're not using platforms that support LiveView
+# Native stylesheets
+config :live_view_native_stylesheet,
+ parsers: [
+ swiftui: LiveViewNative.SwiftUI.RulesParser
+ ]
```
Next, create a project for each platform's native client using the official tools provided by each platform.
+This step varies across platforms — for example, SwiftUI development uses [Xcode](https://developer.apple.com/xcode/)
+and so you'll need to know how to [create a new Xcode project](https://developer.apple.com/documentation/xcode/creating-an-xcode-project-for-an-app),
+add [`liveview-client-swiftui`](https://github.com/liveview-native/liveview-client-swiftui) as a [package dependency](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app), [configure your device targets](https://developer.apple.com/documentation/xcode/configuring-a-new-target-in-your-project)
+and write the glue code in Swift to connect to your Phoenix application. For Jetpack this process involves working with
+[Android Studio](https://developer.android.com/studio) and Kotlin to create the client, since those are the tools relevant
+to Android development.
+
+Manual configuration at this point is outside of the scope of these HexDocs but each platform library should have more
+information within its own documentation. To find that, consult the official repositories for each platform library
+that you need to create a native client app for.
+## 5. Update your application code
+
+After running `mix lvn.install` to configure the LiveView Native framework, you will need to integrate it with
+your application. This will involve making the following changes to your Phoenix application's code:
+
+- Using `LiveViewNative.LiveView` and `LiveViewNative.LiveComponent` in your web module
+- Adding the `LiveViewNative.SessionPlug` plug to your router's `:browser` pipeline
+- Allowing Phoenix to render native layouts by using `LiveViewNative.Layouts` in your layouts module and scoping `embed_templates/1` to `*.html` instead of `*`
+
+These changes are required to use LiveView Native. The following subsections describe these changes in more detail
+and how to properly apply them.
+
+### 5a. Use LiveView Native in your web module
+
+Most Phoenix-related modules in your application will `use` a web module that was automatically
+generated for you when running `mix phx.gen`. By default, this module might be named something like
+`MyAppWeb` and would be found at `lib/my_app_web/my_app_web.ex` (replacing `my_app` with the actual
+name of your app). This is your app's _web module_.
+
+Within the web module, you should find functions called `live_view` and `live_component`. Update these
+functions so that inside each function's `quote` block it contains `use LiveViewNative.LiveView` and
+`use LiveViewNative.LiveComponent` respectively. _Be sure to add only those two lines without changing
+or deleting anything else_:
+
+```elixir
+defmodule MyAppWeb do
+ @moduledoc """
+ The entrypoint for defining your web interface, such
+ as controllers, components, channels, and so on...
+ """
+
+ # (truncated for example purposes...)
+
+ def live_view do
+ quote do
+ use Phoenix.LiveView,
+ layout: {MyAppWeb.Layouts, :app}
+
+ # LiveView Native support
+ use LiveViewNative.LiveView
+
+ unquote(html_helpers())
+ end
+ end
+
+ def live_component do
+ quote do
+ use Phoenix.LiveComponent
+
+ # LiveView Native support
+ use LiveViewNative.LiveComponent
+
+ unquote(html_helpers())
+ end
+ end
+
+ # (truncated for example purposes...)
+end
+```
+
+These two lines upgrade LiveViews and LiveComponents in your app with the ability to render native
+UI code in addition to HTML. Once these changes are saved, move on to the second part of this section
+which is updating your app's router to be able to handle native sessions.
+
+### 5b. Add the LiveView Native session plug to your router.ex
+
+Your Phoenix router defines the various paths to resources within your app, such as
+API endpoints, static pages and of course LiveViews. Native clients that connect to
+your app also pass through the router and you need to ensure that it can properly
+handle these non-web connections.
+
+Update your router (located somewhere like `lib/my_app_web/router.ex`) so that the
+`:browser` pipeline near the top of the file contains the `LiveViewNative.SessionPlug`:
+
+```elixir
+defmodule MyAppWeb.Router do
+ use MyAppWeb, :router
+
+ pipeline :browser do
+ plug :accepts, ["html"]
+ plug :fetch_session
+ plug :fetch_live_flash
+
+ # (truncated for example purposes...)
+
+ # LiveView Native support
+ plug LiveViewNative.SessionPlug
+ end
+
+ # (truncated for example purposes...)
+end
+```
+
+With this plug, your router is now able to understand the initial request payloads that LiveView
+Native clients send when connecting to your app. With that change to your router saved, you can now
+move on to the third and final step of this installation guide, updating your layout module.
+
+### 5c. Allow your app to render native layouts
+
+Phoenix applications are made up of two layouts, a root layout and an app layout. Typically these
+layouts are HTML-based which only works in a web environment. To avoid layout templates for the web
+from rendering in non-web environments and to allow writing native layouts, you'll need to update
+Phoenix's root layout module so that it's compatible with LiveView Native.
+
+Open your app's main layout module, typically located at `lib/my_app_web/components/layouts.ex`,
+and change any `embed_templates` lines so that the catch-all wildcard `*` is replaced with one that
+only checks for files with the `*.html` extension. Also, add `use LiveViewNative.Layouts` near the
+top of the file to add support for native layouts:
+
+```elixir
+defmodule MyAppWeb.Layouts do
+ use MyAppWeb, :html
+ use LiveViewNative.Layouts
+
+ # changed from `embed_templates "layouts/*"`
+ embed_templates "layouts/*.html"
+end
+```
+
+If you have templates for other file extensions, like `.json` or `.txt`, you can add separate `embed_templates`
+lines for those as well. The important point is to avoid the catch-all `*` as it will cause the default Phoenix
+template system to try to compile HEEx templates with non-HTML syntax like files ending in `.swiftui.heex` and
+`.jetpack.heex`. This will cause an error like this which prevents your app from compiling:
+
+```
+== Compilation error in file lib/my_app_web/components/layouts.ex ==
+** (Phoenix.LiveView.Tokenizer.ParseError) lib/my_app_web/components/layouts/root.swiftui.heex:1:1: invalid tag
+ |
+1 |
+ | ^
+ (phoenix_live_view 0.19.5) lib/phoenix_live_view/tag_engine.ex:1391: Phoenix.LiveView.TagEngine.raise_syntax_error!/3
+ (phoenix_live_view 0.19.5) lib/phoenix_live_view/tag_engine.ex:452: Phoenix.LiveView.TagEngine.handle_token/2
+ (elixir 1.15.6) lib/enum.ex:2510: Enum."-reduce/3-lists^foldl/2-0-"/3
+ (phoenix_live_view 0.19.5) lib/phoenix_live_view/tag_engine.ex:182: Phoenix.LiveView.TagEngine.handle_body/1
+ (phoenix_live_view 0.19.5) expanding macro: Phoenix.LiveView.HTMLEngine.compile/1
+ lib/my_app_web/components/layouts/root.swiftui.heex: LvnExampleWeb.Layouts.root/1
+```
+
+Once your layout module has been updated appropriately, save the changes and continue.
+
## Post-Installation
-Once LiveView Native is installed and your application is properly configured, you should be able to run your
-Phoenix app in development as usual:
+If you've reached this section, you should have already done the following:
+
+- Added `:live_view_native` and any platform libraries to your list of dependencies in `mix.exs`.
+- Run `mix lvn.install` or configured LiveView Native manually.
+- Updated your web module, router and layouts module with LiveView Native specific code.
+
+If all of these steps have been completed properly, you should be able to run your Phoenix app in development as usual:
```bash
iex -S mix phx.server
diff --git a/guides/introduction/overview.md b/guides/introduction/overview.md
index 0de150bf..f0e229d3 100644
--- a/guides/introduction/overview.md
+++ b/guides/introduction/overview.md
@@ -1,67 +1,144 @@
# Overview
-LiveView Native is a framework for building native applications using Elixir and Phoenix LiveView. It allows a single application to serve a multitude of clients by transforming platform-specific template code into native user interfaces. Here's a basic example that serves web, iOS, iPadOS and macOS clients natively:
+LiveView Native is a framework for building native applications using Elixir and Phoenix LiveView.
+It upgrades your existing Phoenix project with the ability to write truly native user interfaces that
+run on devices and platforms beyond the web.
+
+Here's an example of a simple LiveView that renders both HTML and native SwiftUI views:
-### Source
+### hello_live.ex
```elixir
# lib/my_app_web/live/hello_live.ex
defmodule MyAppWeb.HelloLive do
use Phoenix.LiveView
use MyAppWeb, :live_view
+ use MyAppWeb.HelloStyles
@impl true
def render(%{format: :swiftui} = assigns) do
- # This UI renders on the iPhone / iPad app
+ # This render function serves native SwiftUI views
+ # It uses the `~SWIFTUI` sigil instead of `~H`
~SWIFTUI"""
-
-
- Hello native!
-
+
+
+
+ Hello world on <%= device_name(assigns) %>!
+
"""
end
@impl true
def render(%{} = assigns) do
- # This UI renders on the web
+ # This render function serves HTML
~H"""
-
- Hello web!
-
+
+
+
+
+
Hello world on <%= device_name(assigns) %>!
+
"""
end
+
+ @impl true
+ def handle_event("hello", _params, socket) do
+ # This event handler can be shared across all platforms
+ IO.puts "Hello world!"
+
+ {:noreply, socket}
+ end
+
+ ###
+
+ # This function can be called from both HTML and SwiftUI templates
+ # The native device type is available as the `@target` assign
+ defp device_name(%{target: :phone}), do: "iOS"
+ defp device_name(%{target: :pad}), do: "iPadOS"
+ defp device_name(%{target: :mac}), do: "macOS"
+ defp device_name(%{target: :watch}), do: "watchOS"
+ defp device_name(_), do: "the web"
+end
+```
+
+### hello_styles.ex
+
+```elixir
+# lib/my_app_web/live/hello_styles.ex
+defmodule MyAppWeb.HelloStyles do
+ use LiveViewNative.Stylesheet, :swiftui
+
+ ~SHEET"""
+ "bold" do
+ fontWeight(.bold)
+ end
+
+ "fg-color-" <> color do
+ foregroundStyle(to_ime(color))
+ end
+
+ "font-size-" <> font_size do
+ font(system(size: to_integer(font_size)))
+ end
+
+ "p-" <> padding do
+ padding(to_integer(padding))
+ end
+ """
+
+ def class(_other, _), do: {:unmatched, ""}
end
```
-### iOS
+
+
+This code serves users whether they're using a web browser or native app running on an iPhone,
+iPad, macOS desktop or Apple Watch. Each platform renders its own native widgets and UI elements,
+allowing state, event callbacks and business logic to be shared.
+
+
-![Hello World - iOS](./assets/images/hello-iphone.png)
+### iPhone
-### iPadOS
-![Hello World - iPadOS](./assets/images/hello-ipad.png)
+![Hello World - iPhone](./assets/images/hello-iphone.png)
-### macOS
+### iPad
+![Hello World - iPad](./assets/images/hello-ipad.png)
+
+### Watch
+![Hello World - macOS](./assets/images/hello-watch.png)
+
+### Desktop (macOS)
![Hello World - macOS](./assets/images/hello-mac.png)
-### Web
+### Desktop (Web)
![Hello World - Web](./assets/images/hello-web.png)
-By using LiveView Native in an existing Phoenix project, developers are able to deliver rich, real-time UIs for a multitude of web and non-web clients generated entirely by the server. Live sessions, state, event callbacks and glue code can be shared across all target platforms, with each platform having its own custom-tailored template or function component.
-
-LiveView Native officially supports using LiveView for the following native clients:
+The following native platforms are officially supported, and support for other platforms
+can be provided by third-party platform libraries.
- iOS 16+
- macOS 13+
- watchOS 9+
- Android
-LiveView Native requires some foundational knowledge to use. You should already be familiar with [Elixir](https://elixir-lang.org/), the [Phoenix Framework](https://www.phoenixframework.org/) and [Phoenix LiveView](https://github.com/phoenixframework/phoenix_live_view). If you're looking to learn more about any of these subjects, there are a lot of great resources available. Some recommended materials include the [Elixir guides](https://elixir-lang.org/getting-started/introduction.html), [Elixir learning resources page](https://elixir-lang.org/learning.html), [Phoenix guides](https://hexdocs.pm/phoenix/overview.html), [Phoenix community page](https://hexdocs.pm/phoenix/community.html) and the [Phoenix LiveView HexDocs](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html).
+LiveView Native requires some foundational knowledge to use. You should already be familiar with
+[Elixir](https://elixir-lang.org/), the [Phoenix Framework](https://www.phoenixframework.org/) and
+[Phoenix LiveView](https://github.com/phoenixframework/phoenix_live_view). If you're looking to learn
+more about any of these subjects, there are a lot of great resources available. Some recommended
+materials include the [Elixir guides](https://elixir-lang.org/getting-started/introduction.html),
+[Elixir learning resources page](https://elixir-lang.org/learning.html), [Phoenix guides](https://hexdocs.pm/phoenix/overview.html),
+[Phoenix community page](https://hexdocs.pm/phoenix/community.html) and the [Phoenix LiveView HexDocs](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html).
With those prerequisites out of the way, [let's get LiveView Native installed](./installation.md)!
\ No newline at end of file
diff --git a/guides/introduction/your-first-native-liveview.md b/guides/introduction/your-first-native-liveview.md
index 417b07a2..b4703926 100644
--- a/guides/introduction/your-first-native-liveview.md
+++ b/guides/introduction/your-first-native-liveview.md
@@ -59,7 +59,7 @@ end
Then, run your app and navigate to your local development server in a web browser.
You should see the LiveView you created.
-![Hello World - Web](./assets/images/hello-web.png)
+![Hello World - Web](./assets/images/first-web.png)
## A native LiveView
@@ -104,24 +104,9 @@ end
```
Loading the native project at `native/swiftui/MyApp/MyApp.xcodeproj` and running it in
-Simulator will render the native template in various devices for the SwiftUI platform:
+Simulator will render the native template as a native SwiftUI app:
-
-
-### iOS
-
-![Hello World - iOS](./assets/images/hello-iphone.png)
-
-### iPadOS
-![Hello World - iPadOS](./assets/images/hello-ipad.png)
-
-### macOS
-![Hello World - macOS](./assets/images/hello-mac.png)
-
-### Web
-![Hello World - Web](./assets/images/hello-web.png)
-
-
+![Hello World - iOS](./assets/images/first-ios.png)
If everything looks as it should, congratulations! Your app is now using LiveView Native to
serve multiple platform-specific templates to both web and non-web clients.
diff --git a/mix.exs b/mix.exs
index ed2adb38..b054b806 100644
--- a/mix.exs
+++ b/mix.exs
@@ -76,7 +76,6 @@ defmodule LiveViewNative.MixProject do
"guides/introduction/your-first-native-liveview.md",
"guides/introduction/troubleshooting.md",
"guides/common-features/template-syntax.md",
- "guides/common-features/modifiers.md",
"guides/common-features/render-patterns.md",
"guides/common-features/handling-events.md"
]
diff --git a/mix.lock b/mix.lock
index d464bb92..c6bd89bc 100644
--- a/mix.lock
+++ b/mix.lock
@@ -4,6 +4,7 @@
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
"cowlib": {:hex, :cowlib, "2.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"},
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
+ "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
"dialyxir": {:hex, :dialyxir, "1.4.1", "a22ed1e7bd3a3e3f197b68d806ef66acb61ee8f57b3ac85fc5d57354c5482a93", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "84b795d6d7796297cca5a3118444b80c7d94f7ce247d49886e7c291e1ae49801"},
"earmark_parser": {:hex, :earmark_parser, "1.4.37", "2ad73550e27c8946648b06905a57e4d454e4d7229c2dafa72a0348c99d8be5f7", [:mix], [], "hexpm", "6b19783f2802f039806f375610faa22da130b8edc21209d0bff47918bb48360e"},
"ecto": {:hex, :ecto, "3.11.1", "4b4972b717e7ca83d30121b12998f5fcdc62ba0ed4f20fd390f16f3270d85c3e", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ebd3d3772cd0dfcd8d772659e41ed527c28b2a8bde4b00fe03e0463da0f1983b"},