organism-ui 0.2.1
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +35 -0
- data/app/assets/config/ui_manifest.js +1 -0
- data/app/assets/stylesheets/ui/application.css +15 -0
- data/app/controllers/ui/application_controller.rb +7 -0
- data/app/controllers/ui/style_guide_controller.rb +8 -0
- data/app/helpers/ui/application_helper.rb +4 -0
- data/app/javascript/ui/application.js +1 -0
- data/app/jobs/ui/application_job.rb +4 -0
- data/app/mailers/ui/application_mailer.rb +6 -0
- data/app/models/ui/application_record.rb +5 -0
- data/app/views/ui/style_guide/show.html.erb +1035 -0
- data/config/routes.rb +3 -0
- data/lib/tasks/ui_tasks.rake +4 -0
- data/lib/ui.rb +64 -0
- data/lib/ui/actionable.rb +19 -0
- data/lib/ui/breadcrumbs.rb +31 -0
- data/lib/ui/breadcrumbs/breadcrumb.rb +36 -0
- data/lib/ui/breadcrumbs/crumb.rb +15 -0
- data/lib/ui/buttons/base.rb +146 -0
- data/lib/ui/buttons/primary.rb +11 -0
- data/lib/ui/buttons/secondary.rb +11 -0
- data/lib/ui/buttons/tertiary.rb +11 -0
- data/lib/ui/card.rb +36 -0
- data/lib/ui/card/show.erb +16 -0
- data/lib/ui/collapse.rb +24 -0
- data/lib/ui/collapse/panel.rb +37 -0
- data/lib/ui/collapse/panel/show.erb +16 -0
- data/lib/ui/component.rb +23 -0
- data/lib/ui/descriptive_list.rb +50 -0
- data/lib/ui/descriptive_list/item.rb +24 -0
- data/lib/ui/descriptive_list/show.erb +7 -0
- data/lib/ui/dropdown.rb +22 -0
- data/lib/ui/dropdown/show.erb +13 -0
- data/lib/ui/empty.rb +36 -0
- data/lib/ui/empty/show.erb +11 -0
- data/lib/ui/engine.rb +13 -0
- data/lib/ui/list.rb +77 -0
- data/lib/ui/list/item.rb +9 -0
- data/lib/ui/list/show.erb +5 -0
- data/lib/ui/menu.rb +29 -0
- data/lib/ui/menu/callable.rb +11 -0
- data/lib/ui/menu/item.rb +39 -0
- data/lib/ui/menu/show.erb +4 -0
- data/lib/ui/menu/submenu.rb +55 -0
- data/lib/ui/notification.rb +37 -0
- data/lib/ui/notification/show.erb +19 -0
- data/lib/ui/page_header.rb +29 -0
- data/lib/ui/page_header/show.erb +18 -0
- data/lib/ui/pagination.rb +105 -0
- data/lib/ui/pagination/page_link.rb +24 -0
- data/lib/ui/pagination/show.erb +11 -0
- data/lib/ui/pagination/window.rb +85 -0
- data/lib/ui/step.rb +57 -0
- data/lib/ui/step/show.erb +13 -0
- data/lib/ui/steps.rb +67 -0
- data/lib/ui/steps/show.erb +5 -0
- data/lib/ui/stylable.rb +21 -0
- data/lib/ui/table.rb +162 -0
- data/lib/ui/table/header.rb +20 -0
- data/lib/ui/table/row.rb +25 -0
- data/lib/ui/table/select.rb +16 -0
- data/lib/ui/table/select/many.rb +38 -0
- data/lib/ui/table/select/one.rb +38 -0
- data/lib/ui/table/select_all.rb +36 -0
- data/lib/ui/table/show.erb +5 -0
- data/lib/ui/table/sort.rb +19 -0
- data/lib/ui/tooltip.rb +35 -0
- data/lib/ui/tooltip/show.erb +14 -0
- data/lib/ui/types.rb +7 -0
- data/lib/ui/value.rb +4 -0
- data/lib/ui/version.rb +3 -0
- data/lib/ui/wizard.rb +87 -0
- data/lib/ui/wizard/content.rb +20 -0
- data/lib/ui/wizard/show.erb +10 -0
- metadata +265 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
module Ui
|
2
|
+
class Menu < Component
|
3
|
+
class Submenu < Item
|
4
|
+
private
|
5
|
+
|
6
|
+
def render_item
|
7
|
+
content_tag(
|
8
|
+
:ul,
|
9
|
+
render_group(subitems),
|
10
|
+
data: {
|
11
|
+
controller: 'dropdown',
|
12
|
+
"dropdown-hidden-class": "hidden",
|
13
|
+
"dropdown-expanded-value": false,
|
14
|
+
"dropdown-mode-value": "click"
|
15
|
+
}
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def subitems
|
20
|
+
[
|
21
|
+
content_tag(
|
22
|
+
:div,
|
23
|
+
render_group([
|
24
|
+
cell(
|
25
|
+
Ui::Menu::Item,
|
26
|
+
model.first,
|
27
|
+
depth: depth
|
28
|
+
),
|
29
|
+
content_tag(:i, nil, class: 'fas fa-caret-down')
|
30
|
+
]),
|
31
|
+
class: 'ui-submenu__header',
|
32
|
+
data: {
|
33
|
+
action: "click->dropdown#toggle"
|
34
|
+
}
|
35
|
+
),
|
36
|
+
content_tag(
|
37
|
+
:div,
|
38
|
+
cell(
|
39
|
+
Ui::Menu::Item,
|
40
|
+
collection: model.last,
|
41
|
+
depth: depth + 1
|
42
|
+
),
|
43
|
+
data: {
|
44
|
+
"dropdown-target": "expandable"
|
45
|
+
}
|
46
|
+
)
|
47
|
+
]
|
48
|
+
end
|
49
|
+
|
50
|
+
def style
|
51
|
+
'ui-submenu'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Ui
|
2
|
+
class Notification < Component
|
3
|
+
include Actionable
|
4
|
+
include Stylable
|
5
|
+
|
6
|
+
def show
|
7
|
+
render
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def content
|
13
|
+
model
|
14
|
+
end
|
15
|
+
|
16
|
+
def notification_icon
|
17
|
+
content_tag(:span, class: 'ui-notification__icon') do
|
18
|
+
icon(options[:icon])
|
19
|
+
end if options[:icon]
|
20
|
+
end
|
21
|
+
|
22
|
+
def close_notification_link
|
23
|
+
content_tag(
|
24
|
+
:span,
|
25
|
+
icon('fas fa-times'),
|
26
|
+
class: 'ui-notification__close',
|
27
|
+
data: {
|
28
|
+
action: 'click->notification#toggle'
|
29
|
+
}
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def component_style
|
34
|
+
"ui-notification"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<article
|
2
|
+
class="<%= style %>"
|
3
|
+
data-controller="notification"
|
4
|
+
data-notification-hidden-class="hidden">
|
5
|
+
|
6
|
+
<%= notification_icon %>
|
7
|
+
|
8
|
+
<section class="ui-notification__content">
|
9
|
+
<%= content %>
|
10
|
+
|
11
|
+
<% if has_actions? %>
|
12
|
+
<nav class="ui-notification__actions">
|
13
|
+
<%= actions %>
|
14
|
+
</nav>
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<%= close_notification_link %>
|
18
|
+
</section>
|
19
|
+
</article>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Ui
|
2
|
+
class PageHeader < Component
|
3
|
+
include Ui::Actionable
|
4
|
+
|
5
|
+
def show(&block)
|
6
|
+
render(&block)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def title
|
12
|
+
content_tag(:h1, model)
|
13
|
+
end
|
14
|
+
|
15
|
+
def subheading
|
16
|
+
content_tag(:h2, options[:subheading]) if options[:subheading]
|
17
|
+
end
|
18
|
+
|
19
|
+
def back_button
|
20
|
+
link_to options[:back] do
|
21
|
+
content_tag(:i, nil, class: 'fas fa-arrow-left')
|
22
|
+
end if options[:back]
|
23
|
+
end
|
24
|
+
|
25
|
+
def breadcrumbs
|
26
|
+
options.fetch(:breadcrumbs, Proc.new{}).call
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<article class="ui-page-header">
|
2
|
+
<%= breadcrumbs %>
|
3
|
+
|
4
|
+
<header>
|
5
|
+
<%= back_button %>
|
6
|
+
|
7
|
+
<hgroup>
|
8
|
+
<%= title %>
|
9
|
+
<%= subheading %>
|
10
|
+
</hgroup>
|
11
|
+
|
12
|
+
<nav>
|
13
|
+
<%= actions %>
|
14
|
+
</nav>
|
15
|
+
</header>
|
16
|
+
|
17
|
+
<%= yield if block_given? %>
|
18
|
+
</article>
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Ui
|
2
|
+
class Pagination < Component
|
3
|
+
class Page < Value
|
4
|
+
attribute :position, Types::Strict::Integer
|
5
|
+
attribute :path, Types::Strict::String
|
6
|
+
attribute :current, Types::Strict::Bool
|
7
|
+
end
|
8
|
+
|
9
|
+
class PageGroup < Value
|
10
|
+
attribute :pages, Types::Array.of(Page)
|
11
|
+
attribute :position, Types::Strict::Integer
|
12
|
+
end
|
13
|
+
|
14
|
+
def show
|
15
|
+
render
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def previous_page_link
|
21
|
+
cell(
|
22
|
+
Ui::Buttons::Secondary,
|
23
|
+
nil,
|
24
|
+
path: previous_page_path,
|
25
|
+
disabled: previous_page.nil?,
|
26
|
+
icon: 'fas fa-chevron-left'
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def previous_page_path
|
31
|
+
previous_page.try(:path)
|
32
|
+
end
|
33
|
+
|
34
|
+
def next_page_link
|
35
|
+
cell(
|
36
|
+
Ui::Buttons::Secondary,
|
37
|
+
nil,
|
38
|
+
path: next_page_path,
|
39
|
+
disabled: next_page.nil?,
|
40
|
+
icon: 'fas fa-chevron-right'
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def next_page_path
|
45
|
+
next_page.try(:path)
|
46
|
+
end
|
47
|
+
|
48
|
+
def page_links
|
49
|
+
page_groups.inject('') do |content, page_group|
|
50
|
+
content += cell(
|
51
|
+
Ui::Pagination::Window,
|
52
|
+
page_group,
|
53
|
+
page_groups: page_groups
|
54
|
+
).()
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def page_groups
|
59
|
+
pages.each_slice(window_size).to_a.map.with_index do |slice, index|
|
60
|
+
PageGroup.new(
|
61
|
+
pages: slice,
|
62
|
+
position: index + 1
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def pages
|
68
|
+
model.map.with_index do |page, index|
|
69
|
+
Page.new(
|
70
|
+
position: index + 1,
|
71
|
+
path: page,
|
72
|
+
current: page == current_path
|
73
|
+
)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def current_page
|
78
|
+
pages.find(&:current)
|
79
|
+
end
|
80
|
+
|
81
|
+
def next_page
|
82
|
+
pages.find do |page|
|
83
|
+
page.position == current_page.position + 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def previous_page
|
88
|
+
pages.find do |page|
|
89
|
+
page.position == current_page.position - 1
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def current_path
|
94
|
+
options[:current_path]
|
95
|
+
end
|
96
|
+
|
97
|
+
def window_size
|
98
|
+
options.fetch(:window_size, 5)
|
99
|
+
end
|
100
|
+
|
101
|
+
def disabled(content)
|
102
|
+
content_tag(:button, content, disabled: true)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Ui
|
2
|
+
class Pagination < Component
|
3
|
+
class PageLink < Component
|
4
|
+
property :position
|
5
|
+
property :current
|
6
|
+
property :path
|
7
|
+
|
8
|
+
def show
|
9
|
+
cell(
|
10
|
+
Ui::Buttons::Secondary,
|
11
|
+
position,
|
12
|
+
path: path,
|
13
|
+
style: style
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def style
|
18
|
+
current ?
|
19
|
+
'ui-pagination__page--current' :
|
20
|
+
'ui-pagination__page'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<nav
|
2
|
+
data-controller="pagination"
|
3
|
+
data-pagination-window-position-value="1"
|
4
|
+
data-pagination-hidden-class="hidden"
|
5
|
+
class="ui-pagination"
|
6
|
+
aria-label="pager"
|
7
|
+
role="navigation">
|
8
|
+
<%= previous_page_link %>
|
9
|
+
<%= page_links %>
|
10
|
+
<%= next_page_link %>
|
11
|
+
</nav>
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Ui
|
2
|
+
class Pagination < Component
|
3
|
+
class Window < Component
|
4
|
+
property :pages
|
5
|
+
property :position
|
6
|
+
|
7
|
+
def show
|
8
|
+
content_tag(
|
9
|
+
:ul,
|
10
|
+
render_group([
|
11
|
+
previous_window,
|
12
|
+
page_links.html_safe,
|
13
|
+
next_window
|
14
|
+
]),
|
15
|
+
class: 'ui-pagination__window',
|
16
|
+
data: {
|
17
|
+
position: position,
|
18
|
+
"pagination-target": "windows"
|
19
|
+
}
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def next_window
|
26
|
+
unless last_window?
|
27
|
+
content_tag(:li, next_window_button)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def next_window_button
|
32
|
+
cell(
|
33
|
+
Ui::Buttons::Secondary,
|
34
|
+
nil,
|
35
|
+
icon: 'fas fa-ellipsis-h',
|
36
|
+
data: {
|
37
|
+
action: "click->pagination#next"
|
38
|
+
}
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
def previous_window
|
43
|
+
unless first_window?
|
44
|
+
content_tag(:li, previous_window_button)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def previous_window_button
|
49
|
+
cell(
|
50
|
+
Ui::Buttons::Secondary,
|
51
|
+
nil,
|
52
|
+
icon: 'fas fa-ellipsis-h',
|
53
|
+
data: {
|
54
|
+
action: "click->pagination#previous"
|
55
|
+
}
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def page_links
|
61
|
+
pages.inject('') do |content, page|
|
62
|
+
content += content_tag(
|
63
|
+
:li,
|
64
|
+
cell(
|
65
|
+
Ui::Pagination::PageLink,
|
66
|
+
page
|
67
|
+
).()
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def last_window?
|
73
|
+
position == page_groups.size
|
74
|
+
end
|
75
|
+
|
76
|
+
def first_window?
|
77
|
+
position == 1
|
78
|
+
end
|
79
|
+
|
80
|
+
def page_groups
|
81
|
+
options[:page_groups]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/ui/step.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Ui
|
2
|
+
class Step < Component
|
3
|
+
include Stylable
|
4
|
+
|
5
|
+
property :status
|
6
|
+
property :position
|
7
|
+
property :last?
|
8
|
+
property :current?
|
9
|
+
|
10
|
+
def show
|
11
|
+
render
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def title
|
17
|
+
content_tag(:p, model.title, class: 'ui-step__title')
|
18
|
+
end
|
19
|
+
|
20
|
+
def subtitle
|
21
|
+
content_tag(:p, model.subtitle, class: 'ui-step__subtitle')
|
22
|
+
end
|
23
|
+
|
24
|
+
def description
|
25
|
+
content_tag(:p, model.description, class: 'ui-step__description')
|
26
|
+
end
|
27
|
+
|
28
|
+
def step_icon
|
29
|
+
if model.icon.blank?
|
30
|
+
case status
|
31
|
+
when 'finished'
|
32
|
+
icon('fas fa-check')
|
33
|
+
when 'processing'
|
34
|
+
position
|
35
|
+
when 'error'
|
36
|
+
icon('fas fa-times')
|
37
|
+
when 'waiting'
|
38
|
+
position
|
39
|
+
end
|
40
|
+
else
|
41
|
+
icon(model.icon)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def render_icon
|
46
|
+
content_tag(:span, step_icon, class: 'ui-step__icon')
|
47
|
+
end
|
48
|
+
|
49
|
+
def component_style
|
50
|
+
['ui-step'].tap do |styles|
|
51
|
+
styles << 'ui-step--last' if last?
|
52
|
+
styles << 'ui-step--current' if current?
|
53
|
+
styles << "ui-step--#{status.downcase}"
|
54
|
+
end.join(' ')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|