Skip to content

Commit

Permalink
Merge pull request #67 from liveview-native/next
Browse files Browse the repository at this point in the history
Merge `next` into `main`
  • Loading branch information
supernintendo authored Nov 20, 2023
2 parents d0c1e46 + f651dc5 commit a1aab01
Show file tree
Hide file tree
Showing 28 changed files with 307 additions and 142 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ defmodule MyAppWeb.HelloLive do
use LiveViewNative.LiveView

@impl true
def render(%{platform_id: :swiftui} = assigns) do
def render(%{format: :swiftui} = assigns) do
# This UI renders on iOS
~SWIFTUI"""
<VStack>
Expand Down
2 changes: 1 addition & 1 deletion guides/common-features/handling-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ defmodule MyAppWeb.HelloLive do
end

@impl true
def render(%{platform_id: :swiftui} = assigns) do
def render(%{format: :swiftui} = assigns) do
# This UI renders on the iPhone / iPad app
~SWIFTUI"""
<VStack>
Expand Down
6 changes: 3 additions & 3 deletions guides/common-features/modifiers.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ defmodule MyAppWeb.ModifiersExampleLive do
use LiveViewNative.LiveView

@impl true
def render(%{platform_id: :swiftui} = assigns) do
def render(%{format: :swiftui} = assigns) do
# This UI renders on the iPhone / iPad app
~SWIFTUI"""
<VStack>
Expand Down Expand Up @@ -83,7 +83,7 @@ defmodule MyAppWeb.ModifiersExampleLive do
import MyAppWeb.Modclasses, only: [modclass: 3]

@impl true
def render(%{platform_id: :swiftui} = assigns) do
def render(%{format: :swiftui} = assigns) do
~SWIFTUI"""
<VStack>
<Text>This text is normal</Text>
Expand Down Expand Up @@ -148,7 +148,7 @@ defmodule MyAppWeb.ModifiersExampleLive do
import MyAppWeb.Modclasses, only: [modclass: 3]

@impl true
def render(%{platform_id: :swiftui} = assigns) do
def render(%{format: :swiftui} = assigns) do
~SWIFTUI"""
<VStack>
<Text>This text is normal</Text>
Expand Down
10 changes: 5 additions & 5 deletions guides/common-features/render-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ patterns and when you might use them.
## `render/1` function clauses

The most common pattern that is often used throughout this guide is the function clause pattern.
Each function clause matches on the `:platform_id`, allowing each platform to define its own UI:
Each function clause matches on the `:format`, allowing each platform to define its own UI:

```elixir
# lib/my_app_web/live/hello_live.ex
Expand All @@ -15,7 +15,7 @@ defmodule MyAppWeb.HelloLive do
use LiveViewNative.LiveView

@impl true
def render(%{platform_id: :swiftui} = assigns) do
def render(%{format: :swiftui} = assigns) do
# This UI renders on the iPhone / iPad app
~SWIFTUI"""
<VStack>
Expand Down Expand Up @@ -52,7 +52,7 @@ defmodule MyAppWeb.SharedComponents do

import ElixirconfChatWeb.Modclasses.SwiftUi, only: [modclass: 3]

def logo(%{platform_id: :swiftui} = assigns) do
def logo(%{format: :swiftui} = assigns) do
~SWIFTUI"""
<VStack>
<Image name="Logo" />
Expand All @@ -76,7 +76,7 @@ end

If you would prefer to break your render function out into separate template files, you can
conditionally render platform-specific templates using the `render_native/1` macro. External
template files are namespaced according to their `:platform_id`:
template files are namespaced according to their `:format`:

<!-- tabs-open -->

Expand Down Expand Up @@ -127,7 +127,7 @@ defmodule MyAppWeb.SharedComponents do

import ElixirconfChatWeb.Modclasses.SwiftUi, only: [modclass: 3]

def logo(%{platform_id: :swiftui} = assigns) do
def logo(%{format: :swiftui} = assigns) do
~SWIFTUI"""
<VStack>
<%= case @native.platform_config.user_interface_idiom do %>
Expand Down
2 changes: 1 addition & 1 deletion guides/common-features/template-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ defmodule MyAppWeb.MyComponents do
use Phoenix.LiveView
use LiveViewNative.Component

def album_detail(%{platform_id: :swiftui} = assigns) do
def album_detail(%{format: :swiftui} = assigns) do
~SWIFTUI"""
<List>
<%= for song <- @album.songs do %>
Expand Down
4 changes: 2 additions & 2 deletions guides/introduction/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ After adding the `:live_view_native` Hex package and any platform libraries, def
config :live_view_native,
plugins: [
# other plugins here...
LiveViewNativeSwiftUi,
LiveViewNativeJetpack
LiveViewNative.SwiftUI,
LiveViewNative.Jetpack
]
```

Expand Down
2 changes: 1 addition & 1 deletion guides/introduction/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ defmodule MyAppWeb.HelloLive do
use LiveViewNative.LiveView

@impl true
def render(%{platform_id: :swiftui} = assigns) do
def render(%{format: :swiftui} = assigns) do
# This UI renders on the iPhone / iPad app
~SWIFTUI"""
<VStack>
Expand Down
4 changes: 2 additions & 2 deletions guides/introduction/your-first-native-liveview.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ You should see the LiveView you created.
To support non-web platforms using LiveView Native, simply provide a template for each
platform you want to support. This is done by extending LiveView's standard `render/1` callback.

Each platform will have its own custom `:platform_id`, render sigil and HEEx syntax, which are
Each platform will have its own custom `:format`, render sigil and HEEx syntax, which are
all pulled in by the `LiveViewNative.LiveView` macro inherited toward the top of your LiveView.
The following example demonstrates handling the `:swiftui` platform for LiveView Native apps
with the `:live_view_native_swift_ui` dependency, which covers iOS, iPadOS and macOS support:
Expand All @@ -78,7 +78,7 @@ defmodule MyAppWeb.HelloLive do
use LiveViewNative.LiveView

@impl true
def render(%{platform_id: :swiftui} = assigns) do
def render(%{format: :swiftui} = assigns) do
# This UI renders on the iPhone / iPad app
~SWIFTUI"""
<VStack>
Expand Down
12 changes: 12 additions & 0 deletions lib/live_view_native/assigns.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
defmodule LiveViewNative.Assigns do
defstruct [
:app_version,
:app_build,
:bundle_id,
:format,
:native,
:os,
:os_version,
:target
]
end
8 changes: 6 additions & 2 deletions lib/live_view_native/component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@ defmodule LiveViewNative.Component do
end
```
"""
defmacro __using__(_opts \\ []) do
defmacro __using__(opts \\ []) do
stylesheet = opts[:stylesheet]

quote do
use LiveViewNative.Extensions
use LiveViewNative.Extensions,
role: :component,
stylesheet: unquote(stylesheet)
end
end
end
9 changes: 7 additions & 2 deletions lib/live_view_native/extensions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ defmodule LiveViewNative.Extensions do
should use `LiveViewNative.LiveView` or `LiveViewNative.LiveComponent`
respectively.
"""
defmacro __using__(_opts \\ []) do
defmacro __using__(opts \\ []) do

Check warning on line 11 in lib/live_view_native/extensions.ex

View workflow job for this annotation

GitHub Actions / Build and test

variable "opts" is unused (if the variable is not meant to be used, prefix it with an underscore)
quote bind_quoted: [caller: Macro.escape(__CALLER__)] do
for {platform_id, platform_context} <- LiveViewNative.platforms() do
platform_module = Module.concat(__ENV__.module, platform_context.template_namespace)
Expand Down Expand Up @@ -38,10 +38,15 @@ defmodule LiveViewNative.Extensions do
use LiveViewNative.Extensions.RenderMacro,
platform_id: platform_id,
render_macro: platform_context.render_macro

use LiveViewNative.Extensions.InlineRender,
platform_id: platform_id
end

use LiveViewNative.Extensions.Render
use LiveViewNative.Extensions.InlineRender

use LiveViewNative.Extensions.Stylesheets,
module: __ENV__.module
end
end
end
25 changes: 15 additions & 10 deletions lib/live_view_native/extensions/inline_render.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ defmodule LiveViewNative.Extensions.InlineRender do
end
```
"""
defmacro __using__(_opts \\ []) do
quote bind_quoted: [] do
defmacro __using__(opts \\ []) do
quote bind_quoted: [
platform_id: opts[:platform_id],
stylesheet: opts[:stylesheet]
] do
require EEx

defmacro sigil_LVN({:<<>>, meta, [expr]}, modifiers) do
Expand All @@ -39,20 +42,22 @@ defmodule LiveViewNative.Extensions.InlineRender do
end

with %{} = platforms <- LiveViewNative.platforms(),
%LiveViewNativePlatform.Env{} = context <- Map.get(platforms, "#{modifiers}"),
platform_module <- Module.concat(__ENV__.module, context.template_namespace),
expr <- LiveViewNative.Templates.precompile(expr) do
options = [
%LiveViewNativePlatform.Env{} = context <- Map.get(platforms, unquote(platform_id)),
platform_module <- Module.concat(__ENV__.module, context.template_namespace) do
base_opts = [
caller: __CALLER__,
engine: Phoenix.LiveView.TagEngine,
file: __CALLER__.file,
line: __CALLER__.line + 1,
caller: __CALLER__,
indentation: meta[:indentation] || 0,
source: expr,
line: __CALLER__.line + 1,
stylesheet: unquote(stylesheet),
tag_handler: LiveViewNative.TagEngine
]

EEx.compile_string(expr, options)
expr = LiveViewNative.Templates.precompile(expr, unquote(platform_id), base_opts)
eex_opts = Keyword.put(base_opts, :source, expr)

EEx.compile_string(expr, eex_opts)
end
end
end
Expand Down
18 changes: 9 additions & 9 deletions lib/live_view_native/extensions/render_macro.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ defmodule LiveViewNative.Extensions.RenderMacro do
end

with %{} = platforms <- LiveViewNative.platforms(),
%LiveViewNativePlatform.Env{} = context <-
Map.get(platforms, unquote(platform_id)),
platform_module <- Module.concat(__ENV__.module, context.template_namespace),
expr <- LiveViewNative.Templates.precompile(expr) do
options = [
%LiveViewNativePlatform.Env{} = context <- Map.get(platforms, unquote(platform_id)),
platform_module <- Module.concat(__ENV__.module, context.template_namespace) do
base_opts = [
caller: __CALLER__,
engine: Phoenix.LiveView.TagEngine,
file: __CALLER__.file,
line: __CALLER__.line + 1,
caller: __CALLER__,
indentation: meta[:indentation] || 0,
source: expr,
line: __CALLER__.line + 1,
tag_handler: LiveViewNative.TagEngine
]

EEx.compile_string(expr, options)
expr = LiveViewNative.Templates.precompile(expr, unquote(platform_id), base_opts)
eex_opts = Keyword.put(base_opts, :source, expr)

EEx.compile_string(expr, eex_opts)
end
end
end
Expand Down
36 changes: 36 additions & 0 deletions lib/live_view_native/extensions/stylesheets.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
defmodule LiveViewNative.Extensions.Stylesheets do
@moduledoc false

@doc """
This macro adds support for LiveView Native's stylesheet DSL which
enables configuration of visual properties for native platforms
(i.e. SwiftUI modifiers, Jetpack Compose themes, etc.)
"""
defmacro __using__(opts \\ []) do
module = opts[:module]

quote bind_quoted: [module: module] do
def __compiled_stylesheet__ do
class_tree_module =
Module.safe_concat([LiveViewNative, Internal, ClassTree, unquote(module)])

class_tree = apply(class_tree_module, :class_tree, [])

class_names =
class_tree
|> Map.values()
|> List.flatten()

__stylesheet_modules__()
|> Enum.reduce(%{}, fn stylesheet_module, acc ->
compiled_stylesheet = apply(stylesheet_module, :compile_ast, [class_names])

Map.merge(acc, compiled_stylesheet)
end)
|> inspect(limit: :infinity, charlists: :as_list, printable_limit: :infinity)
end

def __stylesheet_modules__, do: []
end
end
end
1 change: 1 addition & 0 deletions lib/live_view_native/extensions/templates.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ defmodule LiveViewNative.Extensions.Templates do
caller: opts[:caller],
eex_engine: opts[:eex_engine],
platform_module: opts[:platform_module],
stylesheet: opts[:stylesheet],
tag_handler: opts[:tag_handler],
template_basename: opts[:template_basename],
template_directory: opts[:template_directory],
Expand Down
8 changes: 6 additions & 2 deletions lib/live_view_native/live_component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ defmodule LiveViewNative.LiveComponent do
end
```
"""
defmacro __using__(_opts \\ []) do
defmacro __using__(opts \\ []) do
stylesheet = opts[:stylesheet]

quote do
use LiveViewNative.Extensions
use LiveViewNative.Extensions,
role: :live_component,
stylesheet: unquote(stylesheet)
end
end
end
Loading

0 comments on commit a1aab01

Please sign in to comment.