Skip to content

Commit

Permalink
use form inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
sorax committed Sep 2, 2024
1 parent 713a20a commit a00d0c1
Show file tree
Hide file tree
Showing 9 changed files with 242 additions and 249 deletions.
17 changes: 0 additions & 17 deletions assets/js/hooks/events/listener/click.ts

This file was deleted.

13 changes: 0 additions & 13 deletions assets/js/hooks/events/listener/focus.ts

This file was deleted.

64 changes: 28 additions & 36 deletions assets/js/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
import { focusin, focusout } from "./events/listener/focus";
import { input } from "./events/listener/input";
import { keydown } from "./events/listener";
import { click } from "./events/listener/click";
import {
handleInsert,
handleContentChange,
handleDelete,
handleClean,
} from "./events/handler";
// import { input } from "./events/listener/input";
// import { keydown } from "./events/listener";
// import {
// handleInsert,
// handleContentChange,
// handleDelete,
// handleClean,
// } from "./events/handler";
import { getNodeByItem } from "./node";
import { getItemById, setAttribute } from "./item";

export const Hooks = {
outline: {
selector: '.item:not([data-processed="true"]',
mounted() {
const container: HTMLDivElement = this.el.querySelector(".nodes");
// const container: HTMLDivElement = this.el.querySelector(".nodes");

container.addEventListener("focusin", focusin.bind(this));
container.addEventListener("focusout", focusout.bind(this));
container.addEventListener("input", input.bind(this));
// container.addEventListener("input", input.bind(this));

container.addEventListener("keydown", keydown.bind(this));
// container.addEventListener("keyup", keyup.bind(this))
// container.addEventListener("keydown", keydown.bind(this));
// // container.addEventListener("keyup", keyup.bind(this))

container.addEventListener("click", click.bind(this));

this.handleEvent("insert", handleInsert.bind(this));
this.handleEvent("change_content", handleContentChange.bind(this));
this.handleEvent("delete", handleDelete.bind(this));
this.handleEvent("clean", handleClean.bind(this));
// this.handleEvent("insert", handleInsert.bind(this));
// this.handleEvent("change_content", handleContentChange.bind(this));
// this.handleEvent("delete", handleDelete.bind(this));
// this.handleEvent("clean", handleClean.bind(this));

const items = this.el.querySelectorAll(this.selector);
items.forEach((item: HTMLDivElement) => {
Expand All @@ -48,19 +42,17 @@ export const Hooks = {
},
},
updated() {
const items = this.el.querySelectorAll(this.selector);
items.forEach((item: HTMLDivElement) => {
const { parent_id, prev_id } = getNodeByItem(item);
const parentNode = getItemById(parent_id);
const prevNode = getItemById(prev_id);

if (prevNode) {
prevNode.after(item);
} else if (parentNode) {
parentNode.querySelector(".children")!.append(item);
}

setAttribute(item, "processed", true);
});
// const items = this.el.querySelectorAll(this.selector);
// items.forEach((item: HTMLDivElement) => {
// const { parent_id, prev_id } = getNodeByItem(item);
// const parentNode = getItemById(parent_id);
// const prevNode = getItemById(prev_id);
// if (prevNode) {
// prevNode.after(item);
// } else if (parentNode) {
// parentNode.querySelector(".children")!.append(item);
// }
// setAttribute(item, "processed", true);
// });
},
};
2 changes: 1 addition & 1 deletion assets/js/hooks/item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export function getItemByNode({ uuid }: Node) {
export function getItemById(uuid: string | undefined) {
if (!uuid) return null;

return document.getElementById(`outline-node-${uuid}`) as HTMLDivElement;
return document.getElementById(`nodes-form-${uuid}`) as HTMLDivElement;
}

export function getItemByEvent(event: Event) {
Expand Down
4 changes: 2 additions & 2 deletions assets/js/hooks/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ function getUUID(item: HTMLDivElement) {
}

function getContent(item: HTMLDivElement) {
const input = item.querySelector(".content") as HTMLDivElement;
return input.textContent || "";
const input = item.querySelector("input") as HTMLInputElement;
return input.value;
}

function getAttribute(item: HTMLDivElement, key: string) {
Expand Down
99 changes: 99 additions & 0 deletions lib/radiator_web/components/outline_components.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,105 @@ defmodule RadiatorWeb.OutlineComponents do
NodeMovedEvent
}

@doc """
Renders an outline form.
## Examples
<.outline_form for={@form} phx-change="validate" phx-submit="save">
<.input field={@form[:email]} label="Email"/>
<.input field={@form[:username]} label="Username" />
<:actions>
<.button>Save</.button>
</:actions>
</.outline_form>
"""
attr :for, :any, required: true, doc: "the data structure for the form"
attr :as, :any, default: nil, doc: "the server side parameter to collect all input under"

attr :rest, :global,
include: ~w(autocomplete name rel action enctype method novalidate target multipart),
doc: "the arbitrary HTML attributes to apply to the form tag"

slot :inner_block, required: true
slot :actions, doc: "the slot for form actions, such as a submit button"

def outline_form(assigns) do
~H"""
<.form :let={f} for={@for} as={@as} {@rest}>
<div class="bg-white">
<%= render_slot(@inner_block, f) %>
<div :for={action <- @actions} class="flex items-center justify-between gap-6 mt-2">
<%= render_slot(action, f) %>
</div>
</div>
</.form>
"""
end

@doc """
Renders the keyboard shortcuts.
## Examples
<.keyboard_shortcuts />
"""
def keyboard_shortcuts(assigns) do
~H"""
<aside>
<h3 class="text-base font-semibold leading-7 text-gray-600">Shortcuts</h3>
<dl class="divide-y divide-gray-100">
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Add note</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">
</dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Cursor up</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">
</dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Cursor down</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">
</dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Indent</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">
</dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Outdent</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">
⇧⇥
</dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Collapse</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700"></dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Expand</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700"></dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Move node up</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">⌥↑</dd>
</div>
<div class="grid grid-cols-3 gap-4 px-0 py-2">
<dt class="text-sm font-medium leading-6 text-gray-600">Move node down</dt>
<dd class="col-span-2 mt-0 text-sm leading-6 text-gray-700">⌥↓</dd>
</div>
</dl>
</aside>
"""
end

def event_logs(assigns) do
~H"""
<ul id="event_logs" class="" phx-update="stream" phx-page-loading>
Expand Down
38 changes: 5 additions & 33 deletions lib/radiator_web/live/episode_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -62,45 +62,17 @@ defmodule RadiatorWeb.EpisodeLive.Index do

@impl true
def handle_info(%{uuid: <<_::binary-size(36)>> <> ":" <> id} = event, %{id: id} = socket) do
id =
case event do
%{node: %{uuid: id}} -> id
%{node_id: id} -> id
end

payload = %{node: %{uuid: id}}

socket
|> push_event("clean", payload)
|> stream_event(event)
|> reply(:noreply)
end

def handle_info(%NodeInsertedEvent{} = event, socket) do
send_update(RadiatorWeb.OutlineComponent, id: "outline", event: event)

socket
|> stream_event(event)
|> reply(:noreply)
end

def handle_info(%NodeContentChangedEvent{} = event, socket) do
send_update(RadiatorWeb.OutlineComponent, id: "outline", event: event)

socket
|> stream_event(event)
|> reply(:noreply)
end

def handle_info(%NodeMovedEvent{} = event, socket) do
send_update(RadiatorWeb.OutlineComponent, id: "outline", event: event)

socket
|> stream_event(event)
|> reply(:noreply)
end
def handle_info(%NodeInsertedEvent{} = event, socket), do: proxy_event(event, socket)
def handle_info(%NodeContentChangedEvent{} = event, socket), do: proxy_event(event, socket)
def handle_info(%NodeMovedEvent{} = event, socket), do: proxy_event(event, socket)
def handle_info(%NodeDeletedEvent{} = event, socket), do: proxy_event(event, socket)

def handle_info(%NodeDeletedEvent{} = event, socket) do
defp proxy_event(event, socket) do
send_update(RadiatorWeb.OutlineComponent, id: "outline", event: event)

socket
Expand Down
Loading

0 comments on commit a00d0c1

Please sign in to comment.