anchor_view_components 0.9.2 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +4 -1
- data/app/assets/images/icons/menu.svg +3 -0
- data/app/components/anchor/anchor_view_components.ts +5 -0
- data/app/components/anchor/dialog_component.html.erb +36 -38
- data/app/components/anchor/dialog_component.rb +9 -4
- data/app/components/anchor/dialog_controller.ts +3 -7
- data/app/components/anchor/invoker_controller.ts +12 -0
- data/app/components/anchor/table_component.html.erb +37 -0
- data/app/components/anchor/table_component.rb +90 -0
- data/app/helpers/anchor/view_helper.rb +1 -0
- data/lib/anchor/view_components/version.rb +1 -1
- data/previews/anchor/action_menu_component_preview/opens_a_dialog.html.erb +23 -0
- data/previews/anchor/action_menu_component_preview.rb +2 -0
- data/previews/anchor/dialog_component_preview/with_custom_show_button.html.erb +16 -0
- data/previews/anchor/dialog_component_preview/with_footer.html.erb +1 -0
- data/previews/anchor/dialog_component_preview.rb +9 -1
- data/previews/anchor/table_component_preview.rb +48 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc1868d9abc000e67ae9aa10f38a2d462cdcbf2894f96f76ef9f400f899f633c
|
4
|
+
data.tar.gz: 9c43abbcfc0e5e746878c90c6379ad3ad5496c26d90fbb0f2723bf581d8c2404
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f1201868d3abb571db947c49f8518a5bdee54b610a3c1282fe983e9deaa780ce24280c42fe514266e9640cc9135a6e8d1889aa99119a302e846bbc664ac24e1
|
7
|
+
data.tar.gz: 7cb9fdec805731bace8256159511575c9c36e525f26253253f5c849143784ea30636bf6921db368531db8e76a24c2be88f8c504d24001c06220cebe31a1e624b
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -3,14 +3,18 @@ import "@oddbird/popover-polyfill";
|
|
3
3
|
import ActionMenuController from "./action_menu_controller";
|
4
4
|
import AutocompleteController from "./autocomplete_controller";
|
5
5
|
import DialogController from "./dialog_controller";
|
6
|
+
import InvokerController from "./invoker_controller";
|
6
7
|
import ToastController from "./toast_controller";
|
7
8
|
import ToggleController from "./toggle_controller";
|
9
|
+
import Sortable from "stimulus-sortable";
|
8
10
|
import { Application } from "@hotwired/stimulus";
|
9
11
|
|
10
12
|
export function registerAnchorControllers(application: Application) {
|
11
13
|
application.register("action-menu", ActionMenuController);
|
12
14
|
application.register("autocomplete", AutocompleteController);
|
13
15
|
application.register("dialog", DialogController);
|
16
|
+
application.register("invoker", InvokerController);
|
17
|
+
application.register("sortable", Sortable)
|
14
18
|
application.register("toast", ToastController);
|
15
19
|
application.register("toggle", ToggleController);
|
16
20
|
}
|
@@ -19,6 +23,7 @@ export {
|
|
19
23
|
ActionMenuController,
|
20
24
|
AutocompleteController,
|
21
25
|
DialogController,
|
26
|
+
InvokerController,
|
22
27
|
ToastController,
|
23
28
|
ToggleController
|
24
29
|
};
|
@@ -1,45 +1,43 @@
|
|
1
|
-
<%=
|
2
|
-
|
3
|
-
|
1
|
+
<%= show_button if show_button? %>
|
2
|
+
|
3
|
+
<%= tag.dialog(
|
4
|
+
aria: { labelledby: title_id },
|
5
|
+
class: "w-[36rem] rounded-lg p-0 bg-white shadow-lg backdrop:bg-grey-100/50",
|
6
|
+
data: {
|
7
|
+
controller: "dialog",
|
8
|
+
testid: title_id,
|
9
|
+
},
|
4
10
|
id: id,
|
5
11
|
) do %>
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
<header class="p-6 flex gap-4 justify-between items-center">
|
14
|
-
<%= render Anchor::TextComponent.new(
|
15
|
-
variant: :heading_2xl,
|
16
|
-
tag: :h1,
|
17
|
-
id: title_id,
|
18
|
-
data: { testid: "#{title_id}-title" }
|
19
|
-
).with_content(title) %>
|
12
|
+
<header class="p-6 flex gap-4 justify-between items-center">
|
13
|
+
<%= render Anchor::TextComponent.new(
|
14
|
+
variant: :heading_2xl,
|
15
|
+
tag: :h1,
|
16
|
+
id: title_id,
|
17
|
+
data: { testid: "#{title_id}-title" }
|
18
|
+
).with_content(title) %>
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
20
|
+
<form class="contents" method="dialog">
|
21
|
+
<%= tag.button(
|
22
|
+
aria: { label: "Close" },
|
23
|
+
class: "text-grey-50 hover:text-grey-70",
|
24
|
+
data: { action: "dialog#close" },
|
25
|
+
) do %>
|
26
|
+
<%= render Anchor::IconComponent.new(icon: "cancel") %>
|
27
|
+
<% end %>
|
28
|
+
</form>
|
29
|
+
</header>
|
31
30
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
31
|
+
<div class="px-6 pb-6">
|
32
|
+
<%= render(Anchor::TextComponent.new(
|
33
|
+
variant: :body_base,
|
34
|
+
data: { testid: "#{title_id}-body" }
|
35
|
+
).with_content(body)) %>
|
36
|
+
</div>
|
38
37
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
<% end %>
|
38
|
+
<% if footer? %>
|
39
|
+
<footer class="sticky bottom-0 bg-white px-6 pb-6 flex gap-2 justify-end">
|
40
|
+
<%= footer %>
|
41
|
+
</footer>
|
44
42
|
<% end %>
|
45
43
|
<% end %>
|
@@ -2,15 +2,20 @@ module Anchor
|
|
2
2
|
class DialogComponent < Component
|
3
3
|
renders_one :show_button, ->(**kwargs) do
|
4
4
|
ButtonComponent.new(
|
5
|
-
data: {
|
6
|
-
|
5
|
+
data: {
|
6
|
+
action: "invoker#openDialog",
|
7
|
+
controller: "invoker",
|
8
|
+
invoker_dialog_outlet: "##{id}",
|
9
|
+
testid: "#{title.parameterize}-btn",
|
10
|
+
},
|
7
11
|
**kwargs
|
8
12
|
)
|
9
13
|
end
|
10
14
|
renders_one :body
|
11
15
|
renders_one :footer
|
12
16
|
|
13
|
-
def initialize(title:, **kwargs)
|
17
|
+
def initialize(id:, title:, **kwargs)
|
18
|
+
@id = id
|
14
19
|
@title = title
|
15
20
|
|
16
21
|
super
|
@@ -18,7 +23,7 @@ module Anchor
|
|
18
23
|
|
19
24
|
private
|
20
25
|
|
21
|
-
attr_reader :title
|
26
|
+
attr_reader :id, :title
|
22
27
|
|
23
28
|
def render?
|
24
29
|
body?
|
@@ -1,15 +1,11 @@
|
|
1
1
|
import { Controller } from "@hotwired/stimulus";
|
2
2
|
|
3
|
-
export default class extends Controller<
|
4
|
-
static targets = ["dialog"];
|
5
|
-
|
6
|
-
declare readonly dialogTarget: HTMLDialogElement;
|
7
|
-
|
3
|
+
export default class extends Controller<HTMLDialogElement> {
|
8
4
|
showModal(): void {
|
9
|
-
this.
|
5
|
+
this.element.showModal();
|
10
6
|
}
|
11
7
|
|
12
8
|
close(): void {
|
13
|
-
this.
|
9
|
+
this.element.close();
|
14
10
|
}
|
15
11
|
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
import DialogController from "./dialog_controller";
|
3
|
+
|
4
|
+
export default class extends Controller {
|
5
|
+
static outlets = ["dialog"];
|
6
|
+
|
7
|
+
declare readonly dialogOutlet: DialogController;
|
8
|
+
|
9
|
+
openDialog(): void {
|
10
|
+
this.dialogOutlet.showModal();
|
11
|
+
}
|
12
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<table class="w-full text-base text-left">
|
2
|
+
<thead>
|
3
|
+
<tr class="border-b">
|
4
|
+
<% columns.each do |column| %>
|
5
|
+
<%= tag.th(
|
6
|
+
column.header,
|
7
|
+
class: "px-2 py-3 font-semibold",
|
8
|
+
scope: "col",
|
9
|
+
) %>
|
10
|
+
<% end %>
|
11
|
+
</tr>
|
12
|
+
</thead>
|
13
|
+
|
14
|
+
<%= tag.tbody(data: tbody_data) do
|
15
|
+
data.each do |model| %>
|
16
|
+
<%= tag.tr(
|
17
|
+
class: row_classes,
|
18
|
+
data: {
|
19
|
+
sortable_update_url: sort_url(model),
|
20
|
+
testid: "tr-#{model.id}"
|
21
|
+
},
|
22
|
+
) do
|
23
|
+
columns.each.with_index do |column, index| %>
|
24
|
+
<%= tag.td(
|
25
|
+
maybe_link(model, column, index, self).to_s.html_safe,
|
26
|
+
class: class_names(
|
27
|
+
"relative",
|
28
|
+
"p-3 pl-8 bg-[url('assets/icons/menu.svg')] bg-[length:16px_16px] bg-[8px_center] bg-no-repeat": sortable? && index.zero?,
|
29
|
+
"px-2 py-3": !sortable? || index.positive?,
|
30
|
+
),
|
31
|
+
data: { testid: "tr-#{model.id}-td-#{index}" },
|
32
|
+
) %>
|
33
|
+
<% end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end %>
|
37
|
+
</table>
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Anchor
|
2
|
+
class TableComponent < Component
|
3
|
+
renders_many :columns, "ColumnComponent"
|
4
|
+
renders_one :link
|
5
|
+
|
6
|
+
attr_reader :data, :sortable
|
7
|
+
|
8
|
+
def initialize(data:, sortable: false, sort_url: nil)
|
9
|
+
@data = data
|
10
|
+
@sortable = sortable
|
11
|
+
@sort_url = sort_url
|
12
|
+
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def row_classes
|
19
|
+
row_classes = %w(border-b focus-within:bg-grey-10)
|
20
|
+
if link?
|
21
|
+
row_classes += %w(hover:bg-grey-10 hover:cursor-pointer)
|
22
|
+
end
|
23
|
+
if sortable?
|
24
|
+
row_classes += %w(hover:cursor-pointer)
|
25
|
+
end
|
26
|
+
row_classes.join(" ")
|
27
|
+
end
|
28
|
+
|
29
|
+
def maybe_link(model, column, index, view_context)
|
30
|
+
value = value_for(model, column)
|
31
|
+
if link?
|
32
|
+
path = "#{link}#{model.id}"
|
33
|
+
if index.zero?
|
34
|
+
text = view_context.link_to(value, path)
|
35
|
+
else
|
36
|
+
text = value
|
37
|
+
end
|
38
|
+
text + view_context.link_to(
|
39
|
+
"",
|
40
|
+
path,
|
41
|
+
aria: { hidden: true },
|
42
|
+
class: "absolute inset-0",
|
43
|
+
tabindex: "-1"
|
44
|
+
)
|
45
|
+
else
|
46
|
+
value
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def value_for(model, column)
|
51
|
+
if column.value.respond_to?(:call)
|
52
|
+
column.value.call(model)
|
53
|
+
else
|
54
|
+
model[column.value]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def tbody_data
|
59
|
+
if sortable?
|
60
|
+
{ controller: "sortable", testid: "sortable" }
|
61
|
+
else
|
62
|
+
{}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def sort_url(model)
|
67
|
+
if sortable?
|
68
|
+
@sort_url.call(model)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def sortable?
|
73
|
+
sortable
|
74
|
+
end
|
75
|
+
|
76
|
+
def render?
|
77
|
+
columns.present? && data.present?
|
78
|
+
end
|
79
|
+
|
80
|
+
class ColumnComponent < Anchor::Component
|
81
|
+
attr_reader :header, :value
|
82
|
+
|
83
|
+
def initialize(header:, value:)
|
84
|
+
@header = header
|
85
|
+
@value = value
|
86
|
+
super
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<%= render Anchor::ActionMenuComponent.new do |c| %>
|
2
|
+
<% c.with_show_button_content("Menu") %>
|
3
|
+
|
4
|
+
<% c.with_item do %>
|
5
|
+
<%= tag.button(
|
6
|
+
"Show dialog",
|
7
|
+
data: {
|
8
|
+
action: "invoker#openDialog",
|
9
|
+
controller: "invoker",
|
10
|
+
invoker_dialog_outlet: "#my-dialog",
|
11
|
+
},
|
12
|
+
) %>
|
13
|
+
<% end %>
|
14
|
+
<% end %>
|
15
|
+
|
16
|
+
<%= render Anchor::DialogComponent.new(
|
17
|
+
id: "my-dialog",
|
18
|
+
title: "Dialog Title",
|
19
|
+
) do |dialog| %>
|
20
|
+
<% dialog.with_body do %>
|
21
|
+
<%= tag.p "Content" %>
|
22
|
+
<% end %>
|
23
|
+
<% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<%= render Anchor::ButtonComponent.new(
|
2
|
+
data: {
|
3
|
+
action: "invoker#openDialog",
|
4
|
+
controller: "invoker",
|
5
|
+
invoker_dialog_outlet: "#my-dialog",
|
6
|
+
},
|
7
|
+
).with_content("Show dialog") %>
|
8
|
+
|
9
|
+
<%= render Anchor::DialogComponent.new(
|
10
|
+
id: "my-dialog",
|
11
|
+
title: "Dialog Title",
|
12
|
+
) do |dialog| %>
|
13
|
+
<% dialog.with_body do %>
|
14
|
+
<%= tag.p "Content" %>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
@@ -16,8 +16,16 @@ module Anchor
|
|
16
16
|
|
17
17
|
def with_footer; end
|
18
18
|
|
19
|
+
# The Dialog component has a `show_button` slot, but it’s optional and you
|
20
|
+
# can instead provide your own button to open the Dialog, as shown in this
|
21
|
+
# example.
|
22
|
+
def with_custom_show_button; end
|
23
|
+
|
19
24
|
def with_link
|
20
|
-
render Anchor::DialogComponent.new(
|
25
|
+
render Anchor::DialogComponent.new(
|
26
|
+
id: "my-dialog",
|
27
|
+
title: "Dialog Title"
|
28
|
+
) do |c|
|
21
29
|
c.with_show_button(classes: "all-unset underline")
|
22
30
|
.with_content("Show Dialog")
|
23
31
|
c.with_body.with_content("Content")
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Anchor
|
2
|
+
class TableComponentPreview < ViewComponent::Preview
|
3
|
+
class MockData
|
4
|
+
attr_reader :id, :name
|
5
|
+
|
6
|
+
def initialize(id, name)
|
7
|
+
@id = id
|
8
|
+
@name = name
|
9
|
+
end
|
10
|
+
|
11
|
+
def [](key)
|
12
|
+
public_send(key)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def playground
|
17
|
+
render Anchor::TableComponent.new(data:) do |table|
|
18
|
+
table.with_column(header: "Id", value: :id)
|
19
|
+
table.with_column(header: "Name", value: -> { _1.name.capitalize })
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def with_link
|
24
|
+
render Anchor::TableComponent.new(data:) do |table|
|
25
|
+
table.with_link { "#a_link/" }
|
26
|
+
table.with_column(header: "Id", value: :id)
|
27
|
+
table.with_column(header: "Name", value: -> { _1.name.capitalize })
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def sortable
|
32
|
+
render Anchor::TableComponent.new(
|
33
|
+
data:,
|
34
|
+
sortable: true,
|
35
|
+
sort_url: ->(data) { "/sort/#{data.id}" }
|
36
|
+
) do |table|
|
37
|
+
table.with_column(header: "Id", value: :id)
|
38
|
+
table.with_column(header: "Name", value: -> { _1.name.capitalize })
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def data
|
45
|
+
(1..4).map { MockData.new(_1, "name #{_1}") }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anchor_view_components
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Buoy Software
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-08-
|
11
|
+
date: 2023-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -51,6 +51,7 @@ files:
|
|
51
51
|
- app/assets/images/icons/actions-check-circle-base.svg
|
52
52
|
- app/assets/images/icons/cancel.svg
|
53
53
|
- app/assets/images/icons/fast-left-circle.svg
|
54
|
+
- app/assets/images/icons/menu.svg
|
54
55
|
- app/assets/images/icons/nav-arrow-down.svg
|
55
56
|
- app/assets/images/icons/nav-arrow-left.svg
|
56
57
|
- app/assets/images/icons/nav-arrow-right.svg
|
@@ -82,6 +83,7 @@ files:
|
|
82
83
|
- app/components/anchor/dialog_controller.ts
|
83
84
|
- app/components/anchor/icon_component.html.erb
|
84
85
|
- app/components/anchor/icon_component.rb
|
86
|
+
- app/components/anchor/invoker_controller.ts
|
85
87
|
- app/components/anchor/loading_indicator_component.html.erb
|
86
88
|
- app/components/anchor/loading_indicator_component.rb
|
87
89
|
- app/components/anchor/panel/body_component.html.erb
|
@@ -101,6 +103,8 @@ files:
|
|
101
103
|
- app/components/anchor/tab_bar/tab_component.rb
|
102
104
|
- app/components/anchor/tab_bar_component.html.erb
|
103
105
|
- app/components/anchor/tab_bar_component.rb
|
106
|
+
- app/components/anchor/table_component.html.erb
|
107
|
+
- app/components/anchor/table_component.rb
|
104
108
|
- app/components/anchor/text_component.html.erb
|
105
109
|
- app/components/anchor/text_component.rb
|
106
110
|
- app/components/anchor/toast_component.html.erb
|
@@ -115,11 +119,13 @@ files:
|
|
115
119
|
- lib/anchor/view_components/version.rb
|
116
120
|
- lib/anchor_view_components.rb
|
117
121
|
- previews/anchor/action_menu_component_preview.rb
|
122
|
+
- previews/anchor/action_menu_component_preview/opens_a_dialog.html.erb
|
118
123
|
- previews/anchor/badge_component_preview.rb
|
119
124
|
- previews/anchor/banner_component_preview.rb
|
120
125
|
- previews/anchor/breadcrumbs_component_preview.rb
|
121
126
|
- previews/anchor/button_component_preview.rb
|
122
127
|
- previews/anchor/dialog_component_preview.rb
|
128
|
+
- previews/anchor/dialog_component_preview/with_custom_show_button.html.erb
|
123
129
|
- previews/anchor/dialog_component_preview/with_footer.html.erb
|
124
130
|
- previews/anchor/icon_component_preview.rb
|
125
131
|
- previews/anchor/loading_indicator_component_preview.rb
|
@@ -128,6 +134,7 @@ files:
|
|
128
134
|
- previews/anchor/side_nav_component_preview.rb
|
129
135
|
- previews/anchor/side_nav_component_preview/default.html.erb
|
130
136
|
- previews/anchor/tab_bar_component_preview.rb
|
137
|
+
- previews/anchor/table_component_preview.rb
|
131
138
|
- previews/anchor/text_component_preview.rb
|
132
139
|
- previews/anchor/toast_component_preview.rb
|
133
140
|
homepage: https://github.com/BuoySoftware/anchor_view_components
|