Packages
phoenix_live_editable
0.0.1-alpha.2
Simple LiveView components for inline editing
Retired package: RETIRED
Current section
2 Versions
Jump to
Current section
2 Versions
Compare versions
16
files changed
+729
additions
-359
deletions
| @@ -3,3 +3,9 @@ | |
| 3 3 | ## 0.0.1-alpha.1 (2022-Jun-03) |
| 4 4 | |
| 5 5 | - Initial Checkin |
| 6 | + |
| 7 | + ## 0.0.1-alpha.2 (2022-Jun-15) |
| 8 | + |
| 9 | + - Settled on basic code organization (view and component layers) |
| 10 | + - Created the ViewCache to store configuration data |
| 11 | + - Created interfaces for Milligram and Tailwind3 |
| @@ -1,5 +1,132 @@ | |
| 1 | - # Phoenix.LiveEditable Readme |
| 1 | + # Phoenix.LiveEditable |
| 2 2 | |
| 3 | - LiveView components for inline editing. |
| 3 | + LiveView components for in-place editing. |
| 4 4 | |
| 5 | + LiveEditable provides helpers for your LiveView/HEEX templates. |
| 6 | + |
| 7 | + Example HEEX tag: |
| 8 | + |
| 9 | + <.live_editable id="MyField" ple_data="Click me to Edit" ple_action="save"/> |
| 10 | + |
| 11 | + Add a handler to your LiveView: |
| 12 | + |
| 13 | + def handle_event("save", value, socket) end |
| 14 | + ... do something ... |
| 15 | + end |
| 16 | + |
| 17 | + See the [online demo][ld] for running examples. |
| 18 | + |
| 19 | + LiveEditable is for admin interfaces to provide basic inline editing. It |
| 20 | + supports many CSS frameworks (Tailwind, Milligram, etc.) and field types (Text, |
| 21 | + Select, etc.). LiveEditable is inspired by [Vitaliy Potapov's][vp] |
| 22 | + [X-Editable][xe], and is designed to be extensible. |
| 23 | + |
| 24 | + LiveEditable is pre-alpha - not ready for production use. |
| 25 | + |
| 26 | + [xe]: http://vitalets.github.io/x-editable |
| 27 | + [ld]: http://phoenix-live-editable.fly.dev |
| 28 | + [vp]: https://github.com/vitalets |
| 29 | + |
| 30 | + ## Demonstration |
| 31 | + |
| 32 | + IN YOUR BROWSER: |
| 33 | + |
| 34 | + Try the [online demo][ld]. |
| 35 | + |
| 36 | + USING DOCKER ON YOUR DESKTOP: |
| 37 | + |
| 38 | + $ docker run -p 8080-8082:8080-8082 andyldk/phoenix_live_editable |
| 39 | + |
| 40 | + Now open a browser and visit `http://localhost:8080` |
| 41 | + |
| 42 | + CLONING THE SOURCE TO YOUR DESKTOP: |
| 43 | + |
| 44 | + $ git clone https://github.com/andyl/phoenix_live_editable |
| 45 | + $ cd phoenix_live_editable |
| 46 | + $ mix deps.get |
| 47 | + $ mix phx.server |
| 48 | + |
| 49 | + Now open a browser and visit `http://localhost:4040` |
| 50 | + |
| 51 | + ## Code Organization |
| 52 | + |
| 53 | + The [LiveEditable Repo][gh] is an umbrella project. This was done to make it |
| 54 | + easier to demo and test the LiveEditable components against a variety of CSS |
| 55 | + frameworks. |
| 56 | + |
| 57 | + | Umbrella Subapp | Description | |
| 58 | + |-------------------------|-----------------------------------------------| |
| 59 | + | `phoenix_live_editable` | LiveEditable components | |
| 60 | + | `ple_demo_base` | phoenix app with a landing page | |
| 61 | + | `ple_demo_milligram` | phoenix app with LiveEditable using Milligram | |
| 62 | + | `ple_demo_tailwind3` | phoenix app with LiveEditable using Tailwind3 | |
| 63 | + | `ple_util` | utility modules to support the demo apps | |
| 64 | + |
| 65 | + Note that the LiveEditable package on hex.pm contains only the |
| 66 | + `phoenix_live_editable` subapp, not the demo apps. |
| 67 | + |
| 68 | + [gh]: https://github.com/andyl/phoenix_live_editable |
| 69 | + |
| 70 | + ## Installation |
| 71 | + |
| 72 | + PhoenixLiveEditable can be installed in your own LV application by adding |
| 73 | + `phoenix_live_editable` to your list of dependencies in `mix.exs`: |
| 74 | + |
| 75 | + Using the path option: |
| 76 | + ```elixir |
| 77 | + def deps do |
| 78 | + [ |
| 79 | + {:phoenix_live_editable, |
| 80 | + path: "~/src_root/phoenix_live_editable/apps/phoenix_live_editable"} |
| 81 | + ] |
| 82 | + end |
| 83 | + ``` |
| 84 | + |
| 85 | + Using the github option: |
| 86 | + ```elixir |
| 87 | + def deps do |
| 88 | + [ |
| 89 | + {:phoenix_live_editable, |
| 90 | + github: "andyl/phoenix_live_editable", |
| 91 | + subdir: "apps/phoenix_live_editable"} |
| 92 | + ] |
| 93 | + end |
| 94 | + ``` |
| 95 | + |
| 96 | + Using the hex option: |
| 97 | + ```elixir |
| 98 | + def deps do |
| 99 | + [ |
| 100 | + {:phoenix_live_editable, "~> 0.0.1"} |
| 101 | + ] |
| 102 | + end |
| 103 | + ``` |
| 104 | + |
| 105 | + After that: |
| 106 | + |
| 107 | + $ mix deps.get && mix deps.compile |
| 108 | + |
| 109 | + Next add LiveEditable configuartion to your `config/config.exs`: |
| 110 | + |
| 111 | + config :<your_phoenix_app>, <your endpoint>, [ |
| 112 | + live_editable: [ple_interface: <YOUR_CSS_FRAMEWORK_MODULE>] |
| 113 | + ] |
| 114 | + |
| 115 | + Valid Framework Modules include: |
| 116 | + |
| 117 | + - Phoenix.LiveEditable.Interface.Milligram |
| 118 | + - Phoenix.LiveEditable.Interface.Tailwind3 |
| 119 | + |
| 120 | + Now you can use LiveEditable in your LiveViews and LiveComponents: |
| 121 | + |
| 122 | + defmodule MyApp.Live.Asdf do |
| 123 | + end |
| 124 | + |
| 125 | + ## Customizing LiveEditable |
| 126 | + |
| 127 | + Instructions on how to tweak LiveEditable CSS TBD. |
| 128 | + |
| 129 | + ## Extending LiveEditable |
| 130 | + |
| 131 | + Instruction on how to create new LiveEditable modules TBD. |
| @@ -5,15 +5,19 @@ | |
| 5 5 | {<<"files">>, |
| 6 6 | [<<"lib">>,<<"lib/phoenix">>,<<"lib/phoenix/live_editable">>, |
| 7 7 | <<"lib/phoenix/live_editable/application.ex">>, |
| 8 | + <<"lib/phoenix/live_editable/view_cache.ex">>, |
| 9 | + <<"lib/phoenix/live_editable/helpers.ex">>, |
| 8 10 | <<"lib/phoenix/live_editable/svg.ex">>, |
| 9 11 | <<"lib/phoenix/live_editable/interface">>, |
| 10 12 | <<"lib/phoenix/live_editable/interface/tailwind3.ex">>, |
| 11 13 | <<"lib/phoenix/live_editable/interface/milligram.ex">>, |
| 12 14 | <<"lib/phoenix/live_editable/interface/base.ex">>, |
| 13 15 | <<"lib/phoenix/live_editable/interface/bootstrap5.ex">>, |
| 14 | - <<"lib/phoenix/live_editable.ex">>,<<"lib/phoenix/live_editable_hooks.ex">>, |
| 15 | - <<"lib/phx">>,<<"lib/phx/demo">>,<<"lib/phx/demo/helpers.ex">>, |
| 16 | - <<".formatter.exs">>,<<"mix.exs">>,<<"README.md">>,<<"CHANGELOG.md">>]}. |
| 16 | + <<"lib/phoenix/live_editable/handler">>, |
| 17 | + <<"lib/phoenix/live_editable/handler/default.ex">>, |
| 18 | + <<"lib/phoenix/live_editable_component.ex">>, |
| 19 | + <<"lib/phoenix/live_editable_view.ex">>,<<".formatter.exs">>,<<"mix.exs">>, |
| 20 | + <<"README.md">>,<<"CHANGELOG.md">>]}. |
| 17 21 | {<<"licenses">>,[<<"MIT">>]}. |
| 18 22 | {<<"links">>, |
| 19 23 | [{<<"GitHub">>,<<"https://github.com/andyl/phoenix_live_editable">>}]}. |
| @@ -34,4 +38,4 @@ | |
| 34 38 | {<<"optional">>,false}, |
| 35 39 | {<<"repository">>,<<"hexpm">>}, |
| 36 40 | {<<"requirement">>,<<"~> 0.17">>}]]}. |
| 37 | - {<<"version">>,<<"0.0.1-alpha.1">>}. |
| 41 | + {<<"version">>,<<"0.0.1-alpha.2">>}. |
| @@ -1,72 +0,0 @@ | |
| 1 | - defmodule Phoenix.LiveEditable do |
| 2 | - import Phoenix.LiveView |
| 3 | - |
| 4 | - use Phoenix.LiveComponent |
| 5 | - |
| 6 | - # ----- lifecycle callbacks ----- |
| 7 | - |
| 8 | - def mount(socket) do |
| 9 | - # {:ok, assign(socket, :focusid, "NONE")} |
| 10 | - {:ok, socket} |
| 11 | - end |
| 12 | - |
| 13 | - def update(assigns, socket) do |
| 14 | - Map.has_key?(assigns, :id) || raise("Needs `:id` assign") |
| 15 | - Map.has_key?(assigns, :type) || raise("Needs `:type` assign ('text' | 'select')") |
| 16 | - |
| 17 | - assigns = set_env(assigns) |
| 18 | - |
| 19 | - # IO.inspect(assigns, label: "UPDATE ASSIG==>>") |
| 20 | - # IO.inspect(socket, label: "UPDATE SOCK==>>") |
| 21 | - |
| 22 | - {:ok, assign(socket, assigns)} |
| 23 | - end |
| 24 | - |
| 25 | - def render(assigns) do |
| 26 | - # IO.inspect(assigns, label: "RENDER ASSIG==>>") |
| 27 | - module = interface_module() |
| 28 | - module.render(assigns) |
| 29 | - end |
| 30 | - |
| 31 | - # ----- event handlers ----- |
| 32 | - |
| 33 | - # ----- view helpers ----- |
| 34 | - |
| 35 | - defp set_env(assigns) do |
| 36 | - mode = if assigns.id == assigns.focusid, do: "focus", else: "anchor" |
| 37 | - assigns |
| 38 | - |> Map.put(:mode, mode) |
| 39 | - # |> IO.inspect(label: "SETENV") |
| 40 | - end |
| 41 | - |
| 42 | - def interface_module do |
| 43 | - _app_name = Application.get_application(__MODULE__) # |> IO.inspect(label: "APPNAME ------->>>>") |
| 44 | - case Application.fetch_env(:phoenix_live_editable, :css_framework) do |
| 45 | - {:ok, module} -> |
| 46 | - module |
| 47 | - error -> |
| 48 | - IO.inspect "+++++++++++++++++++++++++++++++++++++++" |
| 49 | - IO.inspect "ERROR INTERFACE MODULE" |
| 50 | - IO.inspect error |
| 51 | - IO.inspect "+++++++++++++++++++++++++++++++++++++++" |
| 52 | - Phoenix.LiveEditable.Interface.Milligram |
| 53 | - end |
| 54 | - end |
| 55 | - |
| 56 | - defmacro __using__(_opts) do |
| 57 | - quote do |
| 58 | - |
| 59 | - on_mount Phoenix.LiveEditableHooks |
| 60 | - |
| 61 | - def handle_event("focus", %{"id" => id}, socket) do |
| 62 | - new_socket = assign(socket, :focusid, id) |
| 63 | - {:noreply, new_socket} |
| 64 | - end |
| 65 | - |
| 66 | - def handle_event("cancel", _payload, socket) do |
| 67 | - {:noreply, assign(socket, :focusid, "NONE")} |
| 68 | - end |
| 69 | - |
| 70 | - end |
| 71 | - end |
| 72 | - end |
| @@ -7,10 +7,8 @@ defmodule Phoenix.LiveEditable.Application do | |
| 7 7 | |
| 8 8 | def start(_type, _args) do |
| 9 9 | children = [ |
| 10 | - # Start the PubSub system |
| 11 | - {Phoenix.PubSub, name: Phoenix.LiveEditable.PubSub} |
| 12 | - # Start a worker by calling: LiveEditable.Worker.start_link(arg) |
| 13 | - # {LiveEditable.Worker, arg} |
| 10 | + {Phoenix.PubSub, name: Phoenix.LiveEditable.PubSub}, |
| 11 | + {Registry, keys: :unique, name: Phoenix.LiveEditable.Registry} |
| 14 12 | ] |
| 15 13 | |
| 16 14 | Supervisor.start_link(children, strategy: :one_for_one, name: Phoenix.LiveEditable.Supervisor) |
Loading more files…