phlex_kit 0.6.1 → 0.7.0
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/components/phlex_kit/dropdown_menu/dropdown_menu.css +10 -0
- data/app/components/phlex_kit/dropdown_menu/dropdown_menu_content.rb +6 -3
- data/app/components/phlex_kit/menubar/menubar_controller.js +23 -1
- data/app/components/phlex_kit/navigation_menu/navigation_menu.rb +1 -1
- data/app/components/phlex_kit/navigation_menu/navigation_menu_content.rb +1 -1
- data/app/components/phlex_kit/navigation_menu/navigation_menu_link.rb +6 -2
- data/lib/phlex_kit/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 924514c45499b5f5d021cc5ec5416246c38ccfc0cb40bef9f65a9592e12960b3
|
|
4
|
+
data.tar.gz: 9531c44809a4b586547c41a45e2274acf24618436f10ca6d54f368f975ad199e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: edbe03d8c7b0eafca03b08f4da7e28b0f220be45e3725e18fcc82972d9737341180be65617bcfee479d67a150e3876da29551bf39a46d52459b9a0f794d1672f
|
|
7
|
+
data.tar.gz: a25b1d74ac3d5cfb12dfd0f72a20bf1fcf92b115a7f25602cb62dfd0c19c77987db2ee02ee6fd4efd97548306b75d70e188eea2c56bbb4564cb2503d41f592bb
|
|
@@ -20,6 +20,16 @@
|
|
|
20
20
|
position-try-fallbacks: flip-block;
|
|
21
21
|
}
|
|
22
22
|
.pk-dropdown-menu-content-up { position-area: block-start span-inline-end; margin: 0 0 4px; }
|
|
23
|
+
.pk-dropdown-menu-content-right {
|
|
24
|
+
position-area: inline-end span-block-end;
|
|
25
|
+
margin: 0 0 0 4px;
|
|
26
|
+
position-try-fallbacks: flip-inline;
|
|
27
|
+
}
|
|
28
|
+
.pk-dropdown-menu-content-left {
|
|
29
|
+
position-area: inline-start span-block-end;
|
|
30
|
+
margin: 0 4px 0 0;
|
|
31
|
+
position-try-fallbacks: flip-inline;
|
|
32
|
+
}
|
|
23
33
|
.pk-dropdown-menu-viewport {
|
|
24
34
|
min-width: 10rem;
|
|
25
35
|
border-radius: calc(var(--pk-radius) - 2px);
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
module PhlexKit
|
|
2
2
|
# The dropdown panel — a native [popover=manual] the trigger toggles,
|
|
3
3
|
# anchor-positioned with viewport-edge flipping. `side:` is :bottom
|
|
4
|
-
# (default, opens below)
|
|
5
|
-
# the viewport, e.g. the sidebar footer)
|
|
4
|
+
# (default, opens below), :top (opens above — for triggers near the bottom
|
|
5
|
+
# of the viewport, e.g. the sidebar footer), :right or :left (opens beside
|
|
6
|
+
# the trigger — shadcn's side prop). See dropdown_menu.rb.
|
|
6
7
|
class DropdownMenuContent < BaseComponent
|
|
8
|
+
SIDES = { bottom: nil, top: "pk-dropdown-menu-content-up", left: "pk-dropdown-menu-content-left", right: "pk-dropdown-menu-content-right" }.freeze
|
|
9
|
+
|
|
7
10
|
def initialize(side: :bottom, **attrs)
|
|
8
11
|
@side = side.to_sym
|
|
9
12
|
@attrs = attrs
|
|
@@ -18,7 +21,7 @@ module PhlexKit
|
|
|
18
21
|
private
|
|
19
22
|
|
|
20
23
|
def wrapper_classes
|
|
21
|
-
[ "pk-dropdown-menu-content", (
|
|
24
|
+
[ "pk-dropdown-menu-content", fetch_option(SIDES, @side, :side) ].compact.join(" ")
|
|
22
25
|
end
|
|
23
26
|
end
|
|
24
27
|
end
|
|
@@ -18,6 +18,10 @@ export default class extends Controller {
|
|
|
18
18
|
this.openMenu = null
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
disconnect() {
|
|
22
|
+
clearTimeout(this.graceTimer)
|
|
23
|
+
}
|
|
24
|
+
|
|
21
25
|
toggle(e) {
|
|
22
26
|
const menu = e.currentTarget.closest("[data-phlex-kit--menubar-target=\"menu\"]")
|
|
23
27
|
this.openMenu === menu ? this.close() : this.show(menu, true)
|
|
@@ -26,11 +30,28 @@ export default class extends Controller {
|
|
|
26
30
|
// Hover: switches between menus while one is open (menubar), or opens
|
|
27
31
|
// directly when the bar declares data-hover-open (navigation menu).
|
|
28
32
|
switch(e) {
|
|
33
|
+
clearTimeout(this.graceTimer)
|
|
29
34
|
const menu = e.currentTarget.closest("[data-phlex-kit--menubar-target=\"menu\"]")
|
|
30
|
-
if (this.element.dataset.hoverOpen !== undefined)
|
|
35
|
+
if (this.element.dataset.hoverOpen !== undefined) {
|
|
36
|
+
if (!menu || !this.panel(menu)) return this.closeSoon() // link, no panel
|
|
37
|
+
return this.show(menu)
|
|
38
|
+
}
|
|
39
|
+
if (!menu) return this.close()
|
|
31
40
|
if (this.openMenu && this.openMenu !== menu) this.show(menu)
|
|
32
41
|
}
|
|
33
42
|
|
|
43
|
+
// Hover closes go through a short grace period so a diagonal pointer path
|
|
44
|
+
// that clips a sibling link (or briefly exits the nav) on its way to the
|
|
45
|
+
// panel doesn't slam it shut; reaching the panel or a trigger cancels.
|
|
46
|
+
closeSoon() {
|
|
47
|
+
clearTimeout(this.graceTimer)
|
|
48
|
+
this.graceTimer = setTimeout(() => this.close(), 150)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
cancelClose() {
|
|
52
|
+
clearTimeout(this.graceTimer)
|
|
53
|
+
}
|
|
54
|
+
|
|
34
55
|
show(menu, focus = false) {
|
|
35
56
|
if (this.openMenu !== menu) {
|
|
36
57
|
this.close()
|
|
@@ -42,6 +63,7 @@ export default class extends Controller {
|
|
|
42
63
|
}
|
|
43
64
|
|
|
44
65
|
close(opts = {}) {
|
|
66
|
+
clearTimeout(this.graceTimer)
|
|
45
67
|
const menu = this.openMenu
|
|
46
68
|
if (!menu) return
|
|
47
69
|
const panel = this.panel(menu)
|
|
@@ -15,7 +15,7 @@ module PhlexKit
|
|
|
15
15
|
data: {
|
|
16
16
|
controller: "phlex-kit--menubar",
|
|
17
17
|
hover_open: true,
|
|
18
|
-
action: "click@window->phlex-kit--menubar#onClickOutside keydown.esc->phlex-kit--menubar#close mouseleave->phlex-kit--menubar#
|
|
18
|
+
action: "click@window->phlex-kit--menubar#onClickOutside keydown.esc->phlex-kit--menubar#close mouseleave->phlex-kit--menubar#closeSoon"
|
|
19
19
|
}
|
|
20
20
|
}, @attrs), &)
|
|
21
21
|
end
|
|
@@ -5,7 +5,7 @@ module PhlexKit
|
|
|
5
5
|
def view_template(&)
|
|
6
6
|
# No role="menu" here — the panel holds plain links, not menuitems
|
|
7
7
|
# (Radix/shadcn ship no menu role on NavigationMenu content either).
|
|
8
|
-
div(**mix({ class: "pk-navigation-menu-content", popover: "manual" }, @attrs), &)
|
|
8
|
+
div(**mix({ class: "pk-navigation-menu-content", popover: "manual", data: { action: "mouseenter->phlex-kit--menubar#cancelClose" } }, @attrs), &)
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
module PhlexKit
|
|
2
|
-
# Plain link item (top-level or inside a panel).
|
|
2
|
+
# Plain link item (top-level or inside a panel). Hover fires #switch like a
|
|
3
|
+
# trigger: for a TOP-LEVEL link the closest menu item has no panel, so an
|
|
4
|
+
# open sibling panel closes; for a link INSIDE a panel the closest item IS
|
|
5
|
+
# the open menu, so switch is a no-op and the panel stays. See
|
|
6
|
+
# navigation_menu.rb.
|
|
3
7
|
class NavigationMenuLink < BaseComponent
|
|
4
8
|
def initialize(href: "#", **attrs)
|
|
5
9
|
@href = href
|
|
@@ -7,7 +11,7 @@ module PhlexKit
|
|
|
7
11
|
end
|
|
8
12
|
|
|
9
13
|
def view_template(&)
|
|
10
|
-
a(**mix({ class: "pk-navigation-menu-link", href: @href }, @attrs), &)
|
|
14
|
+
a(**mix({ class: "pk-navigation-menu-link", href: @href, data: { action: "mouseenter->phlex-kit--menubar#switch" } }, @attrs), &)
|
|
11
15
|
end
|
|
12
16
|
end
|
|
13
17
|
end
|
data/lib/phlex_kit/version.rb
CHANGED