head 0.0.2 → 0.0.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/app/assets/javascript/head/index.js +1 -0
- data/app/assets/javascript/head/knob.js +1 -1
- data/app/assets/javascript/head/sidebar.js +39 -0
- data/app/assets/stylesheets/head/components/knob.sass +14 -1
- data/app/assets/stylesheets/head/components/sidebar.sass +99 -0
- data/app/assets/stylesheets/head/components/theater.sass +3 -2
- data/app/assets/stylesheets/head/components/wing.sass +20 -24
- data/app/assets/stylesheets/head/generics/fonts.sass +1 -1
- data/app/assets/stylesheets/head/index.sass +1 -0
- data/app/assets/stylesheets/head/objects/headicon.sass +8 -0
- data/app/assets/stylesheets/head/settings/_colors.sass +1 -0
- data/app/components/head/knob.rb +8 -2
- data/app/components/head/sidebar.rb +34 -0
- data/app/components/head/sidebars/category.rb +51 -0
- data/app/components/head/sidebars/headline.rb +11 -0
- data/app/components/head/sidebars/link.rb +37 -0
- data/app/components/head/theater.rb +6 -1
- data/app/components/head/wing.rb +1 -1
- data/config/importmap.rb +1 -0
- data/lib/head/active.rb +61 -0
- data/lib/head/version.rb +1 -1
- metadata +8 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 64555f34c0083982a934eab9077ed59c080d25e5c30d649c45bb72f91d5a4d7d
|
|
4
|
+
data.tar.gz: 7d56527224c27361e457345eabeea6fedacda3d820608f50bd0e2afd2463f59a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d755be54df9724b2c9dea550f04bb10d3c211ea6d06028eb6dedee133f603ab80a614515f2e038a651ff6cd5c83c18598bbb14098b7f0032f7e5d52c61606629
|
|
7
|
+
data.tar.gz: 23c1c19da4691d95d45411ae3c13c15ddc847d0dfa9767d415569c2e994119015dcbe9e3daf47979d4340c1f9feaf33fdd57a377df5b5ad7238cc9a72f3402e3
|
|
@@ -14,7 +14,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|
|
14
14
|
|
|
15
15
|
// Check screen size
|
|
16
16
|
const mainMenuWing = document.querySelector(`.js-head-wing[data-identifier="mainmenu"]`)
|
|
17
|
-
const tight = getComputedStyle(mainMenuWing).getPropertyValue('position')
|
|
17
|
+
const tight = mainMenuWing ? getComputedStyle(mainMenuWing).getPropertyValue('position') === 'absolute' : false
|
|
18
18
|
|
|
19
19
|
// Handle current wing
|
|
20
20
|
const wing = document.querySelector(`.js-head-wing[data-identifier="${identifier}"]`)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
2
|
+
document.querySelectorAll('.js-head-sidebar__category').forEach(function (category) {
|
|
3
|
+
console.debug("Binding to Sidebar Category")
|
|
4
|
+
const href = category.getAttribute('href')
|
|
5
|
+
|
|
6
|
+
// If this category doesn't open a secondary sidebar, it is a standalone link.
|
|
7
|
+
if (href != '#') return
|
|
8
|
+
|
|
9
|
+
category.addEventListener('click', function(event) {
|
|
10
|
+
event.preventDefault()
|
|
11
|
+
const category = event.currentTarget
|
|
12
|
+
|
|
13
|
+
// The identifier of a category always matches that of its links list.
|
|
14
|
+
const identifier = category.dataset.identifier
|
|
15
|
+
const active = category.classList.contains('is-active')
|
|
16
|
+
const links = document.querySelector(`.js-head-sidebar__links[data-identifier="${identifier}"]`)
|
|
17
|
+
|
|
18
|
+
// Close all others
|
|
19
|
+
document.querySelectorAll('.js-head-sidebar__links').forEach((someLinks) => {
|
|
20
|
+
if (links == someLinks) return
|
|
21
|
+
|
|
22
|
+
someLinks.classList.remove('is-active')
|
|
23
|
+
const categoryClass = `.js-head-sidebar__category[data-identifier="${someLinks.dataset.identifier}"]`
|
|
24
|
+
document.querySelectorAll(categoryClass).forEach((someCategory) => {
|
|
25
|
+
someCategory.classList.remove('is-active')
|
|
26
|
+
})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// Now toggle the desired one.
|
|
30
|
+
if (active) {
|
|
31
|
+
category.classList.remove('is-active')
|
|
32
|
+
links.classList.remove('is-active')
|
|
33
|
+
} else {
|
|
34
|
+
category.classList.add('is-active')
|
|
35
|
+
links.classList.add('is-active')
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
})
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
@use "iglu/responsive"
|
|
1
2
|
@use "iglu/font-size"
|
|
2
3
|
@use "iglu/spacing"
|
|
3
4
|
@use "head/settings/colors"
|
|
@@ -9,7 +10,7 @@
|
|
|
9
10
|
padding-right: 0.25em
|
|
10
11
|
text-decoration: none
|
|
11
12
|
+spacing.padding-vertical--tiny
|
|
12
|
-
+font-size.
|
|
13
|
+
+font-size.gigantic
|
|
13
14
|
|
|
14
15
|
+link.states
|
|
15
16
|
color: colors.$steel-gray
|
|
@@ -20,6 +21,9 @@
|
|
|
20
21
|
&:active
|
|
21
22
|
color: colors.$white
|
|
22
23
|
|
|
24
|
+
&--mainmenu
|
|
25
|
+
display: grid
|
|
26
|
+
|
|
23
27
|
&--identicon
|
|
24
28
|
max-width: 1em
|
|
25
29
|
aspect-ratio: 1
|
|
@@ -48,3 +52,12 @@
|
|
|
48
52
|
object-fit: contain
|
|
49
53
|
clip-path: circle()
|
|
50
54
|
background-color: #fff
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
// Keep this breakpoint analogous to wing.sass
|
|
58
|
+
+responsive.xlarge
|
|
59
|
+
.c-head-knob
|
|
60
|
+
|
|
61
|
+
&--mainmenu
|
|
62
|
+
display: none
|
|
63
|
+
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
@use "iglu/spacing"
|
|
2
|
+
@use "iglu/font-size"
|
|
3
|
+
@use "head/settings/colors"
|
|
4
|
+
@use "head/tools/link"
|
|
5
|
+
|
|
6
|
+
.c-head-sidebar
|
|
7
|
+
display: grid
|
|
8
|
+
grid-template-columns: auto 1fr
|
|
9
|
+
height: 100%
|
|
10
|
+
align-items: start
|
|
11
|
+
+font-size.default
|
|
12
|
+
|
|
13
|
+
&__categories
|
|
14
|
+
display: grid
|
|
15
|
+
|
|
16
|
+
&--right
|
|
17
|
+
.c-head-sidebar__categories
|
|
18
|
+
order: 2
|
|
19
|
+
|
|
20
|
+
&__secondary
|
|
21
|
+
overflow: hidden
|
|
22
|
+
background-color: rgba(255, 255, 255, 0.14) // Corrsponds to 10% change in underlying color
|
|
23
|
+
height: 100%
|
|
24
|
+
|
|
25
|
+
&__category
|
|
26
|
+
display: grid
|
|
27
|
+
justify-content: center
|
|
28
|
+
grid-template-areas: "icon" "name"
|
|
29
|
+
padding-top: 0.2em
|
|
30
|
+
padding-bottom: 0.2em
|
|
31
|
+
position: relative
|
|
32
|
+
text-decoration: none
|
|
33
|
+
+spacing.padding-horizontal--tiny
|
|
34
|
+
|
|
35
|
+
@each $column in category-icon category-name
|
|
36
|
+
&__#{$column}
|
|
37
|
+
grid-area: #{$column}
|
|
38
|
+
|
|
39
|
+
+link.states
|
|
40
|
+
color: colors.$moon-gray
|
|
41
|
+
|
|
42
|
+
&:hover
|
|
43
|
+
color: colors.$white
|
|
44
|
+
|
|
45
|
+
&.is-active
|
|
46
|
+
color: colors.$white
|
|
47
|
+
background-color: rgba(255, 255, 255, 0.14) // Corrsponds to 10% change in underlying color
|
|
48
|
+
|
|
49
|
+
&-icon
|
|
50
|
+
text-align: center
|
|
51
|
+
+font-size.huge
|
|
52
|
+
|
|
53
|
+
&-name
|
|
54
|
+
+font-size.smaller
|
|
55
|
+
|
|
56
|
+
&__links
|
|
57
|
+
display: none
|
|
58
|
+
|
|
59
|
+
&.is-active
|
|
60
|
+
display: block
|
|
61
|
+
|
|
62
|
+
&__link
|
|
63
|
+
grid-column-gap: 0.6rem
|
|
64
|
+
display: grid
|
|
65
|
+
align-items: center
|
|
66
|
+
grid-template-columns: auto 1fr
|
|
67
|
+
grid-template-areas: "icon name"
|
|
68
|
+
padding-right: 0.5rem
|
|
69
|
+
padding-left: 0.5rem
|
|
70
|
+
text-decoration: none
|
|
71
|
+
height: 100%
|
|
72
|
+
+spacing.padding-vertical--tiny
|
|
73
|
+
|
|
74
|
+
@each $column in link-icon link-name
|
|
75
|
+
&__#{$column}
|
|
76
|
+
grid-area: #{$column}
|
|
77
|
+
|
|
78
|
+
+link.states
|
|
79
|
+
color: colors.$moon-gray
|
|
80
|
+
|
|
81
|
+
&:hover
|
|
82
|
+
color: colors.$white
|
|
83
|
+
|
|
84
|
+
&:active
|
|
85
|
+
color: colors.$white
|
|
86
|
+
|
|
87
|
+
&.is-active
|
|
88
|
+
color: colors.$white
|
|
89
|
+
background-color: rgba(255, 255, 255, 0.14)
|
|
90
|
+
|
|
91
|
+
&-name
|
|
92
|
+
white-space: nowrap
|
|
93
|
+
+font-size.small
|
|
94
|
+
|
|
95
|
+
&-icon
|
|
96
|
+
+font-size.larger
|
|
97
|
+
|
|
98
|
+
&-separator
|
|
99
|
+
+spacing.margin-top--smaller
|
|
@@ -8,11 +8,12 @@
|
|
|
8
8
|
grid-template-rows: auto 1fr
|
|
9
9
|
|
|
10
10
|
&__roof
|
|
11
|
-
background-color:
|
|
11
|
+
background-color: colors.$granite-gray
|
|
12
12
|
display: grid
|
|
13
13
|
line-height: 1 // Conformity of knobs
|
|
14
14
|
align-items: center
|
|
15
|
-
|
|
15
|
+
// Keep Logo centered even if left and right menus differ in width
|
|
16
|
+
grid-template-columns: 1fr 1fr 1fr
|
|
16
17
|
grid-template-areas: "knobs--left logo knobs--right"
|
|
17
18
|
|
|
18
19
|
@each $column in knobs--left logo knobs--right
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
.c-head-wing
|
|
5
5
|
display: none
|
|
6
6
|
// 320px is the min screen width we support.
|
|
7
|
-
//
|
|
8
|
-
//
|
|
7
|
+
// On devices that are that narrow, the sidebar needs to fit in,
|
|
8
|
+
// as well as a blank area on the right to close the sidebar with a tap.
|
|
9
|
+
// So the sidebar is limited to less than 320px on narrow devices.
|
|
9
10
|
max-width: 265px
|
|
10
11
|
height: 100%
|
|
11
12
|
z-index: 1000
|
|
@@ -13,22 +14,12 @@
|
|
|
13
14
|
background: colors.$granite-gray
|
|
14
15
|
color: colors.$white
|
|
15
16
|
|
|
16
|
-
&--left
|
|
17
|
-
// On rather large screens, always show the main menu in left sidebar
|
|
18
|
-
+responsive.xlarge-container
|
|
19
|
-
position: static
|
|
20
|
-
|
|
21
|
-
&[data-identifier="mainmenu"]
|
|
22
|
-
// We "force" this item to be active without having the `is-active` class.
|
|
23
|
-
display: block
|
|
24
|
-
// So we need some way to deactivate it again using JS.
|
|
25
|
-
&.is-force-deactive
|
|
26
|
-
display: none
|
|
27
|
-
|
|
28
17
|
&--right
|
|
29
18
|
right: 0
|
|
19
|
+
position: inherit
|
|
30
20
|
|
|
31
|
-
// On very very large screens, show notifications sidebar on the right.
|
|
21
|
+
// On very very large screens, permanently show notifications sidebar on the right.
|
|
22
|
+
// Using container queries for this, because the main menu on the left may affect the layout.
|
|
32
23
|
+responsive.xxlarge-container
|
|
33
24
|
position: static
|
|
34
25
|
|
|
@@ -57,14 +48,19 @@
|
|
|
57
48
|
+responsive.xlarge-container
|
|
58
49
|
display: none
|
|
59
50
|
|
|
51
|
+
// Keep this breakpoint analogous to knob.sass
|
|
52
|
+
+responsive.xlarge
|
|
53
|
+
.c-head-wing
|
|
60
54
|
|
|
61
|
-
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
// display: block
|
|
55
|
+
&--left
|
|
56
|
+
// On rather large screens, always show the main menu in left sidebar
|
|
57
|
+
position: static
|
|
58
|
+
// On wide screens, it's ok to have a wider sidebar to fit all text.
|
|
59
|
+
max-width: 350px
|
|
67
60
|
|
|
68
|
-
|
|
69
|
-
//
|
|
70
|
-
|
|
61
|
+
&[data-identifier="mainmenu"]
|
|
62
|
+
// We "force" this item to be active without having the `is-active` class.
|
|
63
|
+
display: block
|
|
64
|
+
// // So we need some way to deactivate it again using JS.
|
|
65
|
+
// &.is-force-deactive
|
|
66
|
+
// display: none
|
|
@@ -27,6 +27,14 @@
|
|
|
27
27
|
&:before
|
|
28
28
|
content: headicons.$bell
|
|
29
29
|
|
|
30
|
+
.o-headicon--bell-ringing
|
|
31
|
+
&:before
|
|
32
|
+
content: headicons.$bell-ringing
|
|
33
|
+
|
|
30
34
|
.o-headicon--gear
|
|
31
35
|
&:before
|
|
32
36
|
content: headicons.$gear
|
|
37
|
+
|
|
38
|
+
.o-headicon--question-mark
|
|
39
|
+
&:before
|
|
40
|
+
content: headicons.$question-mark
|
|
@@ -10,5 +10,6 @@ $jade-green: rgb(0, 190, 130)
|
|
|
10
10
|
$granite-gray: rgb(70, 70, 70)
|
|
11
11
|
$steel-gray: color.adjust($granite-gray, $lightness: 25%)
|
|
12
12
|
$silver-gray: color.adjust($granite-gray, $lightness: 50%)
|
|
13
|
+
$moon-gray: color.adjust($granite-gray, $lightness: 65%)
|
|
13
14
|
|
|
14
15
|
$transparent-gray: rgba(100, 100, 100, 0.5)
|
data/app/components/head/knob.rb
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Head
|
|
4
|
-
class Knob < ApplicationComponent
|
|
4
|
+
class Knob < ::Head::ApplicationComponent
|
|
5
5
|
erb_template <<~ERB
|
|
6
6
|
<%= link_to(url, class: classes, data: { identifier: id, group: group }, **options.except(:url)) do %>
|
|
7
7
|
<% if icon %>
|
|
8
|
-
<i class="o-headicon <%= icon_class
|
|
8
|
+
<i class="o-headicon <%= icon_class%>"></i>
|
|
9
9
|
<% end %>
|
|
10
10
|
|
|
11
11
|
<%= content %>
|
|
@@ -28,6 +28,7 @@ module Head
|
|
|
28
28
|
return :'bars-thin' if preset_mainmenu?
|
|
29
29
|
return :bell if preset_notifications?
|
|
30
30
|
return :gear if preset_settings?
|
|
31
|
+
return :'question-mark' if preset_help?
|
|
31
32
|
|
|
32
33
|
:magnifier if preset_search?
|
|
33
34
|
end
|
|
@@ -44,6 +45,7 @@ module Head
|
|
|
44
45
|
result = %w[c-head-knob js-head-knob]
|
|
45
46
|
result.push 'c-head-knob--identicon' if preset_identicon?
|
|
46
47
|
result.push 'c-head-knob--avatar' if preset_avatar?
|
|
48
|
+
result.push 'c-head-knob--mainmenu' if preset_mainmenu?
|
|
47
49
|
result
|
|
48
50
|
end
|
|
49
51
|
|
|
@@ -67,6 +69,10 @@ module Head
|
|
|
67
69
|
preset == :search
|
|
68
70
|
end
|
|
69
71
|
|
|
72
|
+
def preset_help?
|
|
73
|
+
preset == :help
|
|
74
|
+
end
|
|
75
|
+
|
|
70
76
|
def preset_identicon?
|
|
71
77
|
preset == :identicon
|
|
72
78
|
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Head
|
|
4
|
+
class Sidebar < ::Head::ApplicationComponent
|
|
5
|
+
erb_template <<~ERB
|
|
6
|
+
<div data-group="<%= right ? :right : :left %>" class="c-head-sidebar <%= 'c-head-sidebar--right' if right %> ">
|
|
7
|
+
<% if categories.any? %>
|
|
8
|
+
<div class="c-head-sidebar__categories">
|
|
9
|
+
<% categories.each do |category| %>
|
|
10
|
+
<%= category %>
|
|
11
|
+
<% end %>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div class="c-head-sidebar__secondary">
|
|
15
|
+
<% categories.select(&:submenu?).each do |category| %>
|
|
16
|
+
<div class="c-head-sidebar__links js-head-sidebar__links" data-identifier="<%= category.identifier %>">
|
|
17
|
+
<% category.links.each do |link| %>
|
|
18
|
+
<%= link %>
|
|
19
|
+
<% end %>
|
|
20
|
+
</div>
|
|
21
|
+
<% end %>
|
|
22
|
+
</div>
|
|
23
|
+
<% end %>
|
|
24
|
+
</div>
|
|
25
|
+
ERB
|
|
26
|
+
|
|
27
|
+
renders_many :categories, -> (**options) do
|
|
28
|
+
::Head::Sidebars::Category.new(icon_class_prefix:, **options)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
option :right, default: -> { false }
|
|
32
|
+
option :icon_class_prefix, default: -> {}
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Head
|
|
4
|
+
module Sidebars
|
|
5
|
+
class Category < ::Head::ApplicationComponent
|
|
6
|
+
erb_template <<~ERB
|
|
7
|
+
<%= link_to(url, data:,
|
|
8
|
+
class: 'c-head-sidebar__category js-head-sidebar__category', **link) do %>
|
|
9
|
+
<%= content_tag :i, nil, class: icon_classes %>
|
|
10
|
+
<%= content_tag :div, name, class: 'c-head-sidebar__category-name' %>
|
|
11
|
+
<% end %>
|
|
12
|
+
ERB
|
|
13
|
+
|
|
14
|
+
renders_many :links, -> (**options) do
|
|
15
|
+
::Head::Sidebars::Link.new(icon_class_prefix:, **options)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
option :url, default: -> { '#' }
|
|
19
|
+
option :icon_class_prefix, default: -> {}
|
|
20
|
+
option :name
|
|
21
|
+
option :icon
|
|
22
|
+
option :link, default: -> { {} }
|
|
23
|
+
|
|
24
|
+
def css_classes
|
|
25
|
+
"c-head-sidebar__category #{'js-head-sidebar__category' if submenu?}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def icon_classes
|
|
29
|
+
"#{icon_class_prefix}#{icon.to_s.gsub('_', '-')} c-head-sidebar__category-icon"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def data
|
|
33
|
+
return unless submenu?
|
|
34
|
+
|
|
35
|
+
{ identifier: }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def submenu?
|
|
39
|
+
url == '#'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def with_separator
|
|
43
|
+
with_link(name: nil, icon: nil)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def identifier
|
|
47
|
+
@identifier ||= SecureRandom.hex
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Head
|
|
4
|
+
module Sidebars
|
|
5
|
+
class Link < ::Head::ApplicationComponent
|
|
6
|
+
erb_template <<~ERB
|
|
7
|
+
<%= link_to(url, class: link_classess, **link) do %>
|
|
8
|
+
<% if icon %>
|
|
9
|
+
<%= content_tag :i, nil, class: icon_classes %>
|
|
10
|
+
<% end %>
|
|
11
|
+
<%= content_tag :div, name, class: 'c-head-sidebar__link-name' %>
|
|
12
|
+
<% end %>
|
|
13
|
+
ERB
|
|
14
|
+
|
|
15
|
+
option :url, default: -> { '#' }
|
|
16
|
+
option :name
|
|
17
|
+
option :icon
|
|
18
|
+
option :link, default: -> { {} }
|
|
19
|
+
option :icon_class_prefix, default: -> {}
|
|
20
|
+
option :active, default: -> {}
|
|
21
|
+
|
|
22
|
+
def link_classess
|
|
23
|
+
"c-head-sidebar__link #{'c-head-sidebar__link-separator' unless icon} #{active?}".squish
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def icon_classes
|
|
27
|
+
"#{icon_class_prefix}#{icon.to_s.gsub('_', '-')} c-head-sidebar__link-icon"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def active?
|
|
31
|
+
::Head::Active.call(url: url_for(url),
|
|
32
|
+
condition: active,
|
|
33
|
+
current_path: request.original_fullpath)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Head
|
|
4
|
-
class Theater < ApplicationComponent
|
|
4
|
+
class Theater < ::Head::ApplicationComponent
|
|
5
5
|
erb_template <<~ERB
|
|
6
6
|
<div class="c-head-theater">
|
|
7
7
|
<div class="c-head-theater__roof">
|
|
@@ -50,6 +50,11 @@ module Head
|
|
|
50
50
|
with_wing(id: :mainmenu, &)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
def with_help(&)
|
|
54
|
+
with_knob(preset: :help, right: true)
|
|
55
|
+
with_wing(id: :help, right: true, &)
|
|
56
|
+
end
|
|
57
|
+
|
|
53
58
|
def with_notifications(&)
|
|
54
59
|
with_knob(preset: :notifications, right: true)
|
|
55
60
|
with_wing(id: :notifications, right: true, &)
|
data/app/components/head/wing.rb
CHANGED
data/config/importmap.rb
CHANGED
data/lib/head/active.rb
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Head
|
|
4
|
+
class Active
|
|
5
|
+
include Calls
|
|
6
|
+
|
|
7
|
+
option :url
|
|
8
|
+
option :current_path
|
|
9
|
+
option :condition
|
|
10
|
+
|
|
11
|
+
def call
|
|
12
|
+
:'is-active' if active?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def linked_path
|
|
18
|
+
::URI.parse(url).path
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def active?
|
|
22
|
+
return false if url == '#'
|
|
23
|
+
|
|
24
|
+
# Adapted from https://github.com/comfy/active_link_to (MIT license)
|
|
25
|
+
case condition
|
|
26
|
+
|
|
27
|
+
when :inclusive, nil # default
|
|
28
|
+
!current_path.match(%r{^#{Regexp.escape(linked_path).chomp('/')}(/.*|\?.*)?$}).blank?
|
|
29
|
+
|
|
30
|
+
when :exclusive
|
|
31
|
+
!current_path.match(%r{^#{Regexp.escape(linked_path)}/?(\?.*)?$}).blank?
|
|
32
|
+
|
|
33
|
+
when :exact
|
|
34
|
+
current_path == linked_path
|
|
35
|
+
|
|
36
|
+
when Regexp
|
|
37
|
+
!current_path.match(condition).blank?
|
|
38
|
+
|
|
39
|
+
when Array
|
|
40
|
+
controllers = [*condition[0]]
|
|
41
|
+
actions = [*condition[1]]
|
|
42
|
+
((controllers.blank? || controllers.member?(params[:controller])) &&
|
|
43
|
+
(actions.blank? || actions.member?(params[:action]))) ||
|
|
44
|
+
controllers.any? do |controller, action|
|
|
45
|
+
params[:controller] == controller.to_s && params[:action] == action.to_s
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
when TrueClass
|
|
49
|
+
true
|
|
50
|
+
|
|
51
|
+
when FalseClass
|
|
52
|
+
false
|
|
53
|
+
|
|
54
|
+
when Hash
|
|
55
|
+
condition.all? do |key, value|
|
|
56
|
+
params[key].to_s == value.to_s
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
data/lib/head/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: head
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- halo
|
|
@@ -121,8 +121,10 @@ files:
|
|
|
121
121
|
- app/assets/fonts/head/icomoon.json
|
|
122
122
|
- app/assets/javascript/head/index.js
|
|
123
123
|
- app/assets/javascript/head/knob.js
|
|
124
|
+
- app/assets/javascript/head/sidebar.js
|
|
124
125
|
- app/assets/javascript/head/wing.js
|
|
125
126
|
- app/assets/stylesheets/head/components/knob.sass
|
|
127
|
+
- app/assets/stylesheets/head/components/sidebar.sass
|
|
126
128
|
- app/assets/stylesheets/head/components/theater.sass
|
|
127
129
|
- app/assets/stylesheets/head/components/wing.sass
|
|
128
130
|
- app/assets/stylesheets/head/generics/flip.sass
|
|
@@ -140,11 +142,16 @@ files:
|
|
|
140
142
|
- app/assets/stylesheets/head/utilities/smokescreen.sass
|
|
141
143
|
- app/components/head/application_component.rb
|
|
142
144
|
- app/components/head/knob.rb
|
|
145
|
+
- app/components/head/sidebar.rb
|
|
146
|
+
- app/components/head/sidebars/category.rb
|
|
147
|
+
- app/components/head/sidebars/headline.rb
|
|
148
|
+
- app/components/head/sidebars/link.rb
|
|
143
149
|
- app/components/head/theater.rb
|
|
144
150
|
- app/components/head/wing.rb
|
|
145
151
|
- config/importmap.rb
|
|
146
152
|
- config/locales/head.en.yml
|
|
147
153
|
- lib/head.rb
|
|
154
|
+
- lib/head/active.rb
|
|
148
155
|
- lib/head/css.rb
|
|
149
156
|
- lib/head/engine.rb
|
|
150
157
|
- lib/head/identicon.rb
|