satis 2.1.6 → 2.1.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b5d37ea4bc5bcbf39336bf85e880827d7431a601fde0a1ff08caf96f0fb52c3e
4
- data.tar.gz: 5d11ce8f1e7177d5b864230787a1804e65ce0d1245764c73142e20a23e50107d
3
+ metadata.gz: 3ea32c052f123438b8208bfd8fa7dccfa23f09021f9c7033c5432663dbf719e1
4
+ data.tar.gz: 73a82438192349081cc304038a73db04cb3b1a1fb503b5170e27c4e9c5568369
5
5
  SHA512:
6
- metadata.gz: 55ff583894557956618c0a183422c92e55ff2da16cfdf3e2757c63acb0e9f7b34fc92938efdfbd67e00fda47e88c93d132b9ad3971da067bad68a3358ca03c9c
7
- data.tar.gz: d16b710b624a602d9e5e5e77b4f3c1d280e6fc97b6e898bc0752b356dcd351498531028a6f3025ff11cc183e2b5a7cb1bdd370e39b6aec806e0079d7f1ba68f4
6
+ metadata.gz: 1521ccc6f5a19ac00f532b04ee1e794ba051e956bc95c9ca39b96919f81455130101e69fd09eb452fd51dbcc313041266da24abac4321955cc9b188303dd6e0e
7
+ data.tar.gz: b4d56886421bcd276828a103bf1611ebe4d3812aa997d5cac043303187cfd8d6846c5e24022f7d8330fb4f6e1e4a13a0975710dcc2ac0ffb510aabf41d174bc8
@@ -615,6 +615,32 @@ export default class DropdownComponentController extends ApplicationController {
615
615
  this.selectItem(dataDiv)
616
616
  this.setSelectedItem(dataDiv.getAttribute("data-satis-dropdown-item-value"))
617
617
  this.searchQueryValue = ""
618
+ } else if(this.searchQueryValue?.length > 0) {
619
+ // hide all items that don't match the search query
620
+ const searchValue = this.searchQueryValue
621
+ let matches = []
622
+ this.itemTargets.forEach((item) => {
623
+ const text = item.getAttribute("data-satis-dropdown-item-text")
624
+ const matched = this.needsExactMatchValue
625
+ ? searchValue.localeCompare(text, undefined, { sensitivity: "base" }) === 0
626
+ : new RegExp(searchValue, "i").test(text)
627
+
628
+ const isHidden = item.classList.contains("hidden")
629
+ if (!isHidden) {
630
+ if (matched) {
631
+ matches.push(item)
632
+ } else {
633
+ item.classList.toggle("hidden", true)
634
+ }
635
+ }
636
+ })
637
+
638
+ // don't show results
639
+ if (matches.length > 0) {
640
+ this.showResultsList(event)
641
+ } else {
642
+ if (!this.showSelectedItem()) this.hideResultsList(event)
643
+ }
618
644
  }
619
645
 
620
646
  if (itemCount > 0) {
@@ -9,6 +9,10 @@
9
9
  }
10
10
  }
11
11
 
12
+ &.active > [data-satis-sidebar-menu-item-target="link"] [data-satis-sidebar-menu-item-target="indicator"] {
13
+ @apply rotate-90;
14
+ }
15
+
12
16
  &__link {
13
17
  @apply text-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 hover:text-gray-900 w-full flex items-center pl-2 pr-1 py-2 text-left text-sm font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500
14
18
  }
@@ -1,87 +1,118 @@
1
1
  import ApplicationController from "satis/controllers/application_controller"
2
- import { debounce } from "satis/utils"
2
+ import {debounce} from "satis/utils"
3
3
 
4
4
  export default class SidebarMenuItemComponentController extends ApplicationController {
5
5
  static targets = ["link", "indicator", "submenu"]
6
6
 
7
7
  connect() {
8
8
  super.connect()
9
-
10
- // Primitive, yes
11
- Array.from(this.element.querySelectorAll('[data-satis-sidebar-menu-item-target="link"]')).forEach((el) => {
12
- if (el.href.length > 0 && window.location.href.indexOf(el.href) >= 0) {
13
- let sidebar = el.closest("nav.sidebar")
14
- if(sidebar.querySelectorAll('.active').length > 0){
15
- sidebar.querySelectorAll('.active').forEach((ele) => {
16
- ele.classList.remove("active")
17
- ele.classList.remove("focus")
18
- })
19
- }
20
- el.classList.add("active")
21
- }
22
- })
23
-
24
- if (this.isActive) {
25
- this.linkTarget.classList.add("active")
26
-
27
- if (this.hasSubmenuTarget) {
28
- this.submenuTarget.classList.remove("hidden")
29
- if(!this.submenuTarget.classList.contains("hidden") && !this.indicatorTarget.hasAttribute("data-fa-transform")){
30
- this.indicatorTarget.setAttribute("data-fa-transform", "rotate-90")
31
- }
32
- if (this.linkTarget){
33
- this.linkTarget.classList.add("focus")
34
- }
35
- } else {
36
- this.linkTarget.classList.add("focus")
9
+ if (this.hasSubmenuTarget) {
10
+ const active = this.isActive
11
+ if (active) {
12
+ this.showSubmenu()
37
13
  }
38
14
  }
15
+
16
+ this.boundUpdateFocus = this.updateFocus.bind(this)
17
+ this.boundOpenListener = this.openListener.bind(this)
18
+
19
+ this.updateFocus(true)
20
+ this.element.addEventListener('sts-sidebar-menu-item:open', this.boundOpenListener)
21
+ window.addEventListener('popstate', debounce(this.boundUpdateFocus, 200))
22
+ }
23
+
24
+ disconnect() {
25
+ super.disconnect()
26
+ this.element.removeEventListener('sts-sidebar-menu-item:open', this.boundOpenListener)
27
+ window.removeEventListener('popstate', debounce(this.boundUpdateFocus, 200))
39
28
  }
40
29
 
41
30
  open(event) {
42
- if (!this.isActive && this.hasSubmenuTarget) {
43
- if (this.hasSubmenuTarget) {
44
- this.submenuTarget.classList.remove("hidden")
45
- this.indicatorTarget.setAttribute("data-fa-transform", "rotate-90")
31
+ if (this.hasSubmenuTarget) {
32
+ const sidebar = this.element.closest('nav.sidebar')
33
+ sidebar.dispatchEvent(new CustomEvent('sts-sidebar-menu-item:open', { detail: { element: this.element } }))
34
+
35
+ if (!this.isSubmenuVisible) {
36
+ this.showSubmenu()
37
+ event.preventDefault()
38
+ } else {
39
+ this.hideSubmenu()
40
+ }
41
+
42
+ if (this.linkTarget.classList.contains("focus")) {
43
+ event.preventDefault()
44
+ } else {
45
+ this.linkTarget.classList.toggle("focus", true)
46
46
  }
47
- event.preventDefault()
48
47
  }
49
- else {
50
- if(this.linkInUrl || (this.linkTarget.href.length <= 0 && !this.hasActiveLinks)){
51
- if (this.hasSubmenuTarget){
52
- this.submenuTarget.classList.toggle("hidden")
53
- if(!this.submenuTarget.classList.contains("hidden") && !this.indicatorTarget.hasAttribute("data-fa-transform")){
54
- this.indicatorTarget.setAttribute("data-fa-transform", "rotate-90")
55
- } else{
56
- this.indicatorTarget.removeAttribute("data-fa-transform", "rotate-90")
57
- }
58
- event.preventDefault()
59
-
60
- }
61
- }
48
+ }
49
+
50
+ openListener(event) {
51
+ if (event.detail.element !== this.element && !this.element.contains(event.detail.element)) {
52
+ this.hideSubmenu()
53
+ this.linkTarget.classList.toggle("focus", false)
62
54
  }
63
55
  }
64
56
 
65
- get linkInUrl() {
66
- return this.linkTarget.href.length > 0 && window.location.href.indexOf(this.linkTarget.href) >= 0
57
+ // This method is used to show the submenu
58
+ showSubmenu() {
59
+ if (!this.hasSubmenuTarget || this.isSubmenuVisible) return
60
+
61
+ this.submenuTarget.classList.toggle("hidden", false)
62
+ this.element.classList.toggle("active", true)
63
+ }
64
+
65
+ // This method is used to hide the submenu
66
+ hideSubmenu() {
67
+ if (!this.hasSubmenuTarget || !this.isSubmenuVisible) return
68
+
69
+ this.submenuTarget.classList.toggle("hidden", true)
70
+ this.element.classList.toggle("active", false)
71
+ }
72
+
73
+ updateFocus(scroll = false) {
74
+ if (!this.hasLinkTarget) return
75
+ const focusedItem = this.element.closest('nav.sidebar').querySelector('a.focus')
76
+ const linkInUrl = this.linkInUrl()
77
+ if (linkInUrl && (!focusedItem || linkInUrl > this.linkInUrl(focusedItem))) {
78
+ focusedItem?.classList.toggle("focus", false)
79
+ this.linkTarget.classList.toggle("focus", true)
80
+ if (scroll) this.linkTarget.scrollIntoView({ behavior: 'instant', block: 'nearest' })
81
+ } else
82
+ this.linkTarget.classList.toggle("focus", false)
83
+ }
84
+
85
+ linkInUrl(target = this.linkTarget) {
86
+ if(!target || target.href.length === 0 || target.pathname !== window.location.pathname || target.origin !== window.location.origin)
87
+ return 0
88
+
89
+ let c = 1;
90
+ if(target.hash === window.location.hash) c++
91
+ window.location.search.split('&').forEach((param) => {if (target.search.includes(param)) c+=2})
92
+ return c
67
93
  }
68
94
 
69
95
  get isActive() {
70
- return this.linkInUrl || this.hasOpenSubmenus || this.hasActiveLinks
96
+ return this.linkInUrl() || this.element.classList.contains("active")
97
+ || Array.from(this.element.querySelectorAll('a[data-satis-sidebar-menu-item-target="link"]'))
98
+ .some((link) => link.classList.contains("active") || this.linkInUrl(link))
99
+ }
100
+
101
+ get isSubmenuVisible() {
102
+ return !this.submenuTarget.classList.contains("hidden")
71
103
  }
72
104
 
73
105
  get hasOpenSubmenus() {
74
- return Array.from(this.element.querySelectorAll('[data-satis-sidebar-menu-item-target="submenu"]')).some((el) => {
75
- return !el.classList.contains("hidden")
76
- // return Array.from(el.querySelectorAll('[data-satis-sidebar-menu-item-target="submenu"]')).some((el) => {
77
- // return !el.classList.contains("hidden")
78
- // })
79
- })
106
+ return this.openSubmenus.length > 0
80
107
  }
81
108
 
82
- get hasActiveLinks() {
83
- return Array.from(this.element.querySelectorAll('[data-satis-sidebar-menu-item-target="link"]')).some((el) => {
84
- return el.classList.contains("active")
85
- })
109
+ /**
110
+ * Get a list of all open submenus
111
+ * @returns {NodeListOf<Element>}
112
+ */
113
+ get openSubmenus() {
114
+ // scope to first match. check if there are any submenus that are not hidden
115
+ return this.element.querySelectorAll('[data-satis-sidebar-menu-item-target="submenu"]:not([class*="hidden"])')
86
116
  }
117
+
87
118
  }
data/lib/satis/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Satis
2
- VERSION = "2.1.6"
2
+ VERSION = "2.1.8"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: satis
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.6
4
+ version: 2.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom de Grunt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-18 00:00:00.000000000 Z
11
+ date: 2024-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: browser