Skip to content

Commit

Permalink
View components
Browse files Browse the repository at this point in the history
  • Loading branch information
sfnelson committed Dec 13, 2023
1 parent 60cb9a3 commit 638bd8f
Show file tree
Hide file tree
Showing 50 changed files with 514 additions and 416 deletions.
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ gemspec

gem "dartsass-rails"
gem "importmap-rails"
gem "katalyst-tables"
gem "propshaft"
gem "rails"
gem "rake"
Expand Down
9 changes: 8 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ PATH
remote: .
specs:
katalyst-navigation (1.5.0.beta.1)
katalyst-html-attributes
katalyst-kpop
katalyst-tables
view_component

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -156,6 +160,10 @@ GEM
katalyst-html-attributes (1.0.0)
activesupport
html-attributes-utils
katalyst-kpop (3.0.1)
katalyst-html-attributes
turbo-rails
view_component
katalyst-tables (2.2.12)
katalyst-html-attributes
view_component
Expand Down Expand Up @@ -365,7 +373,6 @@ DEPENDENCIES
faker
importmap-rails
katalyst-navigation!
katalyst-tables
propshaft
puma
rails
Expand Down
48 changes: 48 additions & 0 deletions app/components/katalyst/navigation/editor/base_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

module Katalyst
module Navigation
module Editor
class BaseComponent < ViewComponent::Base
include Katalyst::HtmlAttributes

MENU_CONTROLLER = "navigation--editor--menu"
LIST_CONTROLLER = "navigation--editor--list"
ITEM_CONTROLLER = "navigation--editor--item"
STATUS_BAR_CONTROLLER = "navigation--editor--status-bar"
NEW_ITEM_CONTROLLER = "navigation--editor--new-item"

attr_accessor :menu, :item

delegate :config, to: ::Katalyst::Navigation

def initialize(menu:, item: nil, **)
super(**)

@menu = menu
@item = item
end

def call; end

def menu_form_id
dom_id(menu, :items)
end

private

def attributes_scope
"menu[items_attributes][]"
end

def inspect
if item.present?
"<#{self.class.name} menu: #{menu.inspect}, item: #{item.inspect}>"
else
"<#{self.class.name} menu: #{menu.inspect}>"
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<turbo-frame id="<%= dom_id(menu, :errors) %>">
<% if menu.errors.any? %>
<%= tag.div(class: "navigation-errors", **html_attributes) do %>
<h2>Errors in navigation</h2>
<ul class="errors">
<% menu.errors.each do |error| %>
<li class="error"><%= error.message %></li>
<% end %>
</ul>
<% end %>
<% end %>
</turbo-frame>
15 changes: 15 additions & 0 deletions app/components/katalyst/navigation/editor/errors_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module Katalyst
module Navigation
module Editor
class ErrorsComponent < BaseComponent
include Katalyst::Tables::TurboReplaceable

def id
dom_id(menu, :errors)
end
end
end
end
end
27 changes: 27 additions & 0 deletions app/components/katalyst/navigation/editor/item_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<%= tag.div(**html_attributes) do %>
<div class="tree" data-invisible="<%= !item.visible? %>">
<div role="toolbar" data-tree-accordion-controls>
<span role="button" value="collapse" data-action="click-><%= MENU_CONTROLLER %>#collapse" title="Collapse tree"></span>
<span role="button" value="expand" data-action="click-><%= MENU_CONTROLLER %>#expand" title="Expand tree"></span>
</div>

<span role="img" value="<%= item.model_name.param_key %>" title="Type"></span>
<h4 class="heading" title="<%= item.title %>"><%= item.title %></h4>
<span role="img" value="invisible" title="Hidden"></span>
</div>

<div class="url">
<%= link_to item.url || "", item.url || "", data: { turbo: false } %>
</div>

<div role="toolbar" data-tree-controls>
<span role="button" value="de-nest" data-action="click-><%= MENU_CONTROLLER %>#deNest" title="Outdent"></span>
<span role="button" value="nest" data-action="click-><%= MENU_CONTROLLER %>#nest" title="Indent"></span>
<%= kpop_link_to("", edit_item_link, role: "button", title: "Edit", value: "edit") %>
<span role="button" value="remove" data-action="click-><%= MENU_CONTROLLER %>#remove" title="Remove"></span>
</div>

<input autocomplete="off" type="hidden" name="<%= attributes_scope %>[id]" value="<%= item.id %>">
<input autocomplete="off" type="hidden" name="<%= attributes_scope %>[depth]" value="<%= item.depth %>">
<input autocomplete="off" type="hidden" name="<%= attributes_scope %>[index]" value="<%= item.index %>">
<% end %>
30 changes: 30 additions & 0 deletions app/components/katalyst/navigation/editor/item_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

module Katalyst
module Navigation
module Editor
class ItemComponent < BaseComponent
include KpopHelper

def edit_item_link
if item.persisted?
helpers.katalyst_navigation.edit_menu_item_path(menu, item)
else
helpers.katalyst_navigation.new_menu_item_path(item.menu, type: item.type)
end
end

private

def default_html_attributes
{
id: dom_id(item),
data: {
controller: ITEM_CONTROLLER,
},
}
end
end
end
end
end
51 changes: 51 additions & 0 deletions app/components/katalyst/navigation/editor/item_editor_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true

module Katalyst
module Navigation
module Editor
class ItemEditorComponent < BaseComponent
include ::Turbo::FramesHelper

module Helpers
def prefix_partial_path_with_controller_namespace
false
end
end

def call
tag.div(**html_attributes) do
helpers.extend(Helpers)
helpers.render(item.model_name.param_key, item:, path:)
end
end

def id
"item-editor-#{item.id}"
end

def title
if item.persisted?
"Edit #{item.model_name.human.downcase}"
else
"New #{item.model_name.human.downcase}"
end
end

def path
if item.persisted?
view_context.katalyst_navigation.menu_item_path(menu, item)
else
view_context.katalyst_navigation.menu_items_path(menu)
end
end

def default_html_attributes
{
id:,
class: "navigation--item-editor",
}
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<%= tag.div(**html_attributes) do %>
<label><%= label %></label>
<%#
# Template is stored inside the new item dom, and copied into drag
# events when the user initiates drag so that it can be copied into the
# editor list on drop.
#
%>
<template data-<%= NEW_ITEM_CONTROLLER %>-target="template">
<%= render row_component do %>
<%= render item_component %>
<% end %>
</template>
<% end %>
49 changes: 49 additions & 0 deletions app/components/katalyst/navigation/editor/new_item_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

module Katalyst
module Navigation
module Editor
class NewItemComponent < BaseComponent
ACTIONS = <<~ACTIONS.gsub(/\s+/, " ").freeze
dragstart->#{NEW_ITEM_CONTROLLER}#dragstart
ACTIONS

with_collection_parameter :item

def initialize(item:, menu: item.menu)
super(item:, menu:)
end

def item_component(**)
ItemComponent.new(item:, menu:, **)
end

def row_component(**)
RowComponent.new(item:, menu:, **)
end

def label
t("katalyst.navigation.editor.new_item.#{item_type}", default: item.model_name.human)
end

def item_type
item.model_name.param_key
end

private

def default_html_attributes
{
draggable: "true",
role: "listitem",
data: {
item_type:,
controller: NEW_ITEM_CONTROLLER,
action: ACTIONS,
},
}
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="content--editor--new-items" role="listbox">
<%= render Katalyst::Navigation::Editor::NewItemComponent.with_collection(items) %>
</div>
20 changes: 20 additions & 0 deletions app/components/katalyst/navigation/editor/new_items_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module Katalyst
module Navigation
module Editor
class NewItemsComponent < BaseComponent
include ::Turbo::FramesHelper

renders_many :items, Editor::NewItemComponent

def items
Katalyst::Navigation.config.items.map do |item_class|
item_class = item_class.safe_constantize if item_class.is_a?(String)
item_class.new(menu:)
end
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
data-deny-remove
data-deny-drag
data-deny-edit>
<%= yield %>
<%= content %>
</li>
10 changes: 10 additions & 0 deletions app/components/katalyst/navigation/editor/row_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

module Katalyst
module Navigation
module Editor
class RowComponent < BaseComponent
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
module Katalyst
module Navigation
module Editor
class StatusBar < Base
class StatusBarComponent < BaseComponent
ACTIONS = <<~ACTIONS.gsub(/\s+/, " ").freeze
navigation:change@document->#{STATUS_BAR_CONTROLLER}#change
ACTIONS

def build(**)
tag.div **default_options(**) do
attr_reader :container

def call
tag.div(**html_attributes) do
concat status(:published, last_update: l(menu.updated_at, format: :short))
concat status(:draft)
concat status(:dirty)
Expand Down Expand Up @@ -44,12 +46,14 @@ def action(action, **)

private

def default_options(**options)
add_option(options, :data, :controller, STATUS_BAR_CONTROLLER)
add_option(options, :data, :action, ACTIONS)
add_option(options, :data, :state, menu.state)

options
def default_html_attributes
{
data: {
controller: STATUS_BAR_CONTROLLER,
action: ACTIONS,
state: menu.state,
},
}
end
end
end
Expand Down
11 changes: 11 additions & 0 deletions app/components/katalyst/navigation/editor/table_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div role="rowheader">
<h4>Title</h4>
<h4>URL</h4>
<h4>Actions</h4>
</div>

<%= tag.ol(id: menu_form_id, **html_attributes) do %>
<% items.each do |item| %>
<%= item %>
<% end %>
<% end %>
Loading

0 comments on commit 638bd8f

Please sign in to comment.