satis 2.2.1 → 2.2.2
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/README.md +5 -1
- data/app/assets/config/satis_manifest.js +0 -1
- data/app/components/satis/card/component.css +8 -0
- data/app/components/satis/card/component.html.slim +20 -13
- data/app/components/satis/card/component.rb +49 -2
- data/app/components/satis/card/component_controller.js +78 -0
- data/app/components/satis/dropdown/component.html.slim +3 -3
- data/app/components/satis/dropdown/component.rb +31 -1
- data/app/components/satis/dropdown/component_controller.js +7 -5
- data/app/components/satis/sidebar/component.css +52 -74
- data/app/components/satis/sidebar_menu_item/component.css +94 -115
- data/app/components/satis/sidebar_menu_item/component_controller.js +113 -9
- data/app/javascript/satis/controllers/fields_for_controller.js +1 -1
- data/app/javascript/satis/controllers/index.js +3 -0
- data/app/javascript/satis/utility_controllers/show_hide_controller.js +1 -1
- data/lib/satis/version.rb +1 -1
- metadata +3 -5
- data/app/assets/fontawesome/brands.js +0 -6
- data/app/assets/fontawesome/fontawesome.js +0 -6
- data/app/assets/fontawesome/solid.js +0 -6
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
/* ── Base menu item ── */
|
|
1
2
|
.sts-sidebar-menu-item {
|
|
2
3
|
@apply pt-1;
|
|
4
|
+
position: relative;
|
|
5
|
+
|
|
3
6
|
& a.focus {
|
|
4
7
|
background: rgba(1, 1, 1, 0.1);
|
|
5
8
|
|
|
@@ -15,9 +18,8 @@
|
|
|
15
18
|
@apply rotate-90;
|
|
16
19
|
}
|
|
17
20
|
|
|
18
|
-
|
|
19
21
|
&__link {
|
|
20
|
-
@apply text-gray-800 dark:text-gray-300 hover:bg-gray-50 dark:text-gray-100 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
|
|
22
|
+
@apply text-gray-800 dark:text-gray-300 hover:bg-gray-50 dark:text-gray-100 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;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
&__icon {
|
|
@@ -34,166 +36,143 @@
|
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
.sidebar
|
|
39
|
+
/* submenu-label always hidden in expanded sidebar */
|
|
40
|
+
.sidebar .sts-sidebar-menu-item .submenu-label {
|
|
39
41
|
display: none;
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
/* ===================================
|
|
45
|
+
COLLAPSED SIDEBAR (.sidebar.close)
|
|
46
|
+
=================================== */
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
opacity: 0;
|
|
48
|
+
/* Center icons in collapsed sidebar */
|
|
49
|
+
.sidebar.close .icon-link > .sts-sidebar-menu-item {
|
|
50
|
+
margin-left: 6px;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
/* Hide labels and chevrons */
|
|
54
|
+
.sidebar.close .sts-sidebar-menu-item__label {
|
|
55
55
|
display: none;
|
|
56
|
-
visibility: hidden;
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
.sidebar.close .sts-sidebar-menu-item .sts-sidebar-menu-item__link .sts-sidebar-menu-item__menu-icon{
|
|
58
|
+
.sidebar.close .sts-sidebar-menu-item__menu-icon {
|
|
61
59
|
display: none;
|
|
62
|
-
visibility: hidden;
|
|
63
|
-
opacity: 0;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.sidebar.close .icon-link > .sts-sidebar-menu-item:hover:not(:has([data-satis-sidebar-menu-item-target="submenu"])) .sts-sidebar-menu-item__label {
|
|
67
|
-
@apply rounded-md bg-gray-50 dark:bg-gray-900 shadow-md py-2;
|
|
68
|
-
text-decoration-thickness: 2px;
|
|
69
|
-
display: block;
|
|
70
|
-
position: absolute;
|
|
71
|
-
padding-right: 20px;
|
|
72
|
-
padding-left: 20px;
|
|
73
|
-
margin-left: 40px;
|
|
74
60
|
}
|
|
75
61
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
62
|
+
/* ── Flyout panel (shown via JS .flyout-visible) ── */
|
|
63
|
+
.sidebar.close .sts-sidebar-menu-item > [data-satis-sidebar-menu-item-target="submenu"].flyout-visible {
|
|
64
|
+
@apply bg-white dark:bg-gray-800 shadow-lg ring-1 ring-black/5 dark:ring-white/10;
|
|
65
|
+
display: block !important;
|
|
79
66
|
position: absolute;
|
|
80
|
-
|
|
81
|
-
padding: 5px 10px;
|
|
82
|
-
border-radius: 4px;
|
|
67
|
+
left: 54px;
|
|
83
68
|
width: 220px;
|
|
84
|
-
|
|
85
|
-
|
|
69
|
+
padding: 4px 0;
|
|
70
|
+
z-index: 1100;
|
|
71
|
+
border-radius: 0 0.5rem 0.5rem 0.5rem;
|
|
86
72
|
}
|
|
87
73
|
|
|
88
|
-
|
|
89
|
-
.sidebar.close .
|
|
90
|
-
|
|
91
|
-
|
|
74
|
+
/* Invisible bridge: prevents hover gap between sidebar icon and flyout */
|
|
75
|
+
.sidebar.close .sts-sidebar-menu-item > [data-satis-sidebar-menu-item-target="submenu"].flyout-visible::before {
|
|
76
|
+
content: '';
|
|
77
|
+
position: absolute;
|
|
78
|
+
top: -10px;
|
|
79
|
+
left: -20px;
|
|
80
|
+
width: 20px;
|
|
81
|
+
bottom: 0;
|
|
92
82
|
}
|
|
93
83
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
opacity: 1;
|
|
84
|
+
/* Nested flyout panels (level 3+) */
|
|
85
|
+
.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible [data-satis-sidebar-menu-item-target="submenu"].flyout-visible {
|
|
86
|
+
@apply bg-white dark:bg-gray-800 shadow-lg ring-1 ring-black/5 dark:ring-white/10 rounded-lg;
|
|
87
|
+
display: block !important;
|
|
99
88
|
position: absolute;
|
|
100
|
-
|
|
101
|
-
margin-top: -45px;
|
|
102
|
-
|
|
89
|
+
left: 100%;
|
|
103
90
|
width: 220px;
|
|
104
|
-
|
|
91
|
+
padding: 4px 0;
|
|
92
|
+
z-index: 1100;
|
|
105
93
|
}
|
|
106
94
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
width:
|
|
114
|
-
|
|
115
|
-
|
|
95
|
+
/* Nested bridge */
|
|
96
|
+
.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible [data-satis-sidebar-menu-item-target="submenu"].flyout-visible::before {
|
|
97
|
+
content: '';
|
|
98
|
+
position: absolute;
|
|
99
|
+
top: 0;
|
|
100
|
+
left: -8px;
|
|
101
|
+
width: 8px;
|
|
102
|
+
bottom: 0;
|
|
116
103
|
}
|
|
117
104
|
|
|
118
|
-
|
|
105
|
+
/* Items inside a visible flyout */
|
|
106
|
+
.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible > .sts-sidebar-menu-item {
|
|
119
107
|
@apply py-0 px-0;
|
|
108
|
+
display: block;
|
|
120
109
|
margin-left: 0;
|
|
121
110
|
}
|
|
122
111
|
|
|
123
|
-
|
|
124
|
-
|
|
112
|
+
/* Flyout item links: Tailwind UI dropdown style */
|
|
113
|
+
.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible .sts-sidebar-menu-item__link {
|
|
114
|
+
@apply rounded-none px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-white;
|
|
125
115
|
}
|
|
126
116
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
.h-screen.flex .sidebar.close .icon-link .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item.pl-4 {
|
|
132
|
-
@apply py-0 px-0 ;
|
|
117
|
+
/* Show regular labels inside flyout (not submenu-label) */
|
|
118
|
+
.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible .sts-sidebar-menu-item__label:not(.submenu-label) {
|
|
133
119
|
display: block;
|
|
134
|
-
visibility: visible;
|
|
135
|
-
opacity: 100;
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.sidebar.close .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item .sts-sidebar-menu-item__label {
|
|
140
120
|
background: none;
|
|
141
|
-
display:block;
|
|
142
|
-
overflow: visible;
|
|
143
121
|
padding: 0;
|
|
144
122
|
}
|
|
145
123
|
|
|
146
|
-
|
|
147
|
-
.
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
.h-screen.flex .sidebar.close .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] .sts-sidebar-menu-item:hover > [data-satis-sidebar-menu-item-target="submenu"] {
|
|
152
|
-
position: fixed;
|
|
153
|
-
margin-left: 185px;
|
|
154
|
-
margin-top: -80px;
|
|
124
|
+
/* Reset focus style inside flyout */
|
|
125
|
+
.sidebar.close .icon-link .sts-sidebar-menu-item a.focus {
|
|
126
|
+
@apply bg-white dark:bg-gray-800;
|
|
155
127
|
}
|
|
156
128
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
display: none;
|
|
129
|
+
.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible .sts-sidebar-menu-item a.focus {
|
|
130
|
+
@apply bg-gray-100 dark:bg-gray-700;
|
|
160
131
|
}
|
|
161
132
|
|
|
162
|
-
|
|
163
|
-
|
|
133
|
+
/* ── Tooltip label for items without submenus (shown via JS .tooltip-visible) ── */
|
|
134
|
+
.sidebar.close .sts-sidebar-menu-item__label.tooltip-visible {
|
|
135
|
+
@apply bg-gray-900 dark:bg-gray-700 text-white text-xs font-medium shadow-lg ring-1 ring-black/5 rounded-md;
|
|
136
|
+
display: block !important;
|
|
137
|
+
position: absolute;
|
|
138
|
+
left: 54px;
|
|
139
|
+
padding: 6px 12px;
|
|
140
|
+
white-space: nowrap;
|
|
141
|
+
z-index: 1100;
|
|
164
142
|
}
|
|
165
143
|
|
|
166
|
-
|
|
167
|
-
|
|
144
|
+
/* Invisible bridge for tooltip */
|
|
145
|
+
.sidebar.close .sts-sidebar-menu-item__label.tooltip-visible::before {
|
|
146
|
+
content: '';
|
|
147
|
+
position: absolute;
|
|
148
|
+
top: 0;
|
|
149
|
+
left: -20px;
|
|
150
|
+
width: 20px;
|
|
151
|
+
bottom: 0;
|
|
168
152
|
}
|
|
169
153
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
154
|
+
/* ── Submenu-label header (shown via JS .tooltip-visible) — flush with flyout ── */
|
|
155
|
+
.sidebar.close .submenu-label.tooltip-visible {
|
|
156
|
+
@apply bg-gray-900 dark:bg-gray-700 text-white text-xs font-semibold;
|
|
157
|
+
display: block !important;
|
|
173
158
|
position: absolute;
|
|
174
|
-
|
|
175
|
-
padding:
|
|
176
|
-
|
|
177
|
-
z-index:
|
|
159
|
+
left: 54px;
|
|
160
|
+
padding: 6px 12px;
|
|
161
|
+
white-space: nowrap;
|
|
162
|
+
z-index: 1100;
|
|
178
163
|
width: 220px;
|
|
179
|
-
|
|
180
|
-
margin-top: 0;
|
|
181
|
-
margin-bottom: 150px;
|
|
164
|
+
border-radius: 0.5rem 0.5rem 0 0;
|
|
182
165
|
}
|
|
183
166
|
|
|
184
|
-
|
|
185
|
-
|
|
167
|
+
/* Nested submenu-label tooltips position off the flyout edge */
|
|
168
|
+
.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible .submenu-label.tooltip-visible {
|
|
169
|
+
@apply rounded-lg;
|
|
170
|
+
left: 100%;
|
|
171
|
+
width: max-content;
|
|
172
|
+
max-width: 220px;
|
|
186
173
|
}
|
|
187
174
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
display:
|
|
191
|
-
position: absolute;
|
|
192
|
-
background-color: rgba(0, 0, 0, 1);
|
|
193
|
-
padding: 5px 10px;
|
|
194
|
-
border-radius: 4px;
|
|
195
|
-
z-index: 10;
|
|
196
|
-
width: 220px;
|
|
197
|
-
margin-left: 177px;
|
|
198
|
-
margin-bottom: 150px;
|
|
175
|
+
/* Nested tooltip labels shouldn't show (already visible in flyout) */
|
|
176
|
+
.sidebar.close [data-satis-sidebar-menu-item-target="submenu"].flyout-visible .sts-sidebar-menu-item__label.tooltip-visible {
|
|
177
|
+
display: none !important;
|
|
199
178
|
}
|
|
@@ -15,18 +15,131 @@ export default class SidebarMenuItemComponentController extends ApplicationContr
|
|
|
15
15
|
|
|
16
16
|
this.boundUpdateFocus = this.updateFocus.bind(this)
|
|
17
17
|
this.boundOpenListener = this.openListener.bind(this)
|
|
18
|
+
this.boundShowFlyout = this.showFlyout.bind(this)
|
|
19
|
+
this.boundHideFlyout = this.hideFlyout.bind(this)
|
|
20
|
+
this.hideTimer = null
|
|
18
21
|
|
|
19
22
|
this.updateFocus(true)
|
|
20
23
|
this.element.addEventListener('sts-sidebar-menu-item:open', this.boundOpenListener)
|
|
24
|
+
this.element.addEventListener('mouseenter', this.boundShowFlyout)
|
|
25
|
+
this.element.addEventListener('mouseleave', this.boundHideFlyout)
|
|
21
26
|
window.addEventListener('popstate', debounce(this.boundUpdateFocus, 200))
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
disconnect() {
|
|
25
30
|
super.disconnect()
|
|
31
|
+
clearTimeout(this.hideTimer)
|
|
26
32
|
this.element.removeEventListener('sts-sidebar-menu-item:open', this.boundOpenListener)
|
|
33
|
+
this.element.removeEventListener('mouseenter', this.boundShowFlyout)
|
|
34
|
+
this.element.removeEventListener('mouseleave', this.boundHideFlyout)
|
|
27
35
|
window.removeEventListener('popstate', debounce(this.boundUpdateFocus, 200))
|
|
28
36
|
}
|
|
29
37
|
|
|
38
|
+
// ── Collapsed sidebar flyout logic ──
|
|
39
|
+
|
|
40
|
+
get isSidebarClosed() {
|
|
41
|
+
const sidebar = this.element.closest('.sidebar')
|
|
42
|
+
return sidebar?.classList.contains('close')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get isInsideFlyout() {
|
|
46
|
+
return !!this.element.closest('[data-satis-sidebar-menu-item-target="submenu"].flyout-visible')
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
showFlyout() {
|
|
50
|
+
if (!this.isSidebarClosed) return
|
|
51
|
+
|
|
52
|
+
// Cancel any pending hide
|
|
53
|
+
clearTimeout(this.hideTimer)
|
|
54
|
+
|
|
55
|
+
if (this.hasSubmenuTarget) {
|
|
56
|
+
const submenuLabel = this.element.querySelector(':scope > .sts-sidebar-menu-item__link > .submenu-label')
|
|
57
|
+
|
|
58
|
+
this.submenuTarget.classList.add('flyout-visible')
|
|
59
|
+
if (submenuLabel) submenuLabel.classList.add('tooltip-visible')
|
|
60
|
+
|
|
61
|
+
this.positionFlyout(this.submenuTarget, submenuLabel)
|
|
62
|
+
} else if (!this.isInsideFlyout) {
|
|
63
|
+
const label = this.element.querySelector(':scope > .sts-sidebar-menu-item__link > .sts-sidebar-menu-item__label:not(.submenu-label)')
|
|
64
|
+
if (label) {
|
|
65
|
+
label.classList.add('tooltip-visible')
|
|
66
|
+
this.positionWithinViewport(label)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
hideFlyout() {
|
|
72
|
+
if (!this.isSidebarClosed) return
|
|
73
|
+
|
|
74
|
+
// Delay hiding so the user can move to the flyout without it disappearing
|
|
75
|
+
this.hideTimer = setTimeout(() => {
|
|
76
|
+
if (this.hasSubmenuTarget) {
|
|
77
|
+
this.submenuTarget.classList.remove('flyout-visible')
|
|
78
|
+
this.submenuTarget.style.top = ''
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
this.element.querySelectorAll('.tooltip-visible').forEach(el => {
|
|
82
|
+
el.classList.remove('tooltip-visible')
|
|
83
|
+
el.style.top = ''
|
|
84
|
+
})
|
|
85
|
+
}, 150)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
positionFlyout(flyout, label) {
|
|
89
|
+
requestAnimationFrame(() => {
|
|
90
|
+
const flyoutRect = flyout.getBoundingClientRect()
|
|
91
|
+
if (flyoutRect.height === 0) return
|
|
92
|
+
|
|
93
|
+
const viewportHeight = window.innerHeight
|
|
94
|
+
const margin = 8
|
|
95
|
+
const labelHeight = label ? label.getBoundingClientRect().height : 0
|
|
96
|
+
|
|
97
|
+
let flyoutTop = parseFloat(getComputedStyle(flyout).top) || 0
|
|
98
|
+
|
|
99
|
+
// Check if flyout overflows bottom
|
|
100
|
+
if (flyoutRect.bottom > viewportHeight - margin) {
|
|
101
|
+
const overflow = flyoutRect.bottom - viewportHeight + margin
|
|
102
|
+
flyoutTop -= overflow
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Check if label above flyout would overflow top
|
|
106
|
+
const parentRect = flyout.offsetParent?.getBoundingClientRect()
|
|
107
|
+
const parentTop = parentRect?.top || 0
|
|
108
|
+
if (parentTop + flyoutTop - labelHeight < margin) {
|
|
109
|
+
flyoutTop = margin - parentTop + labelHeight
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
flyout.style.top = `${flyoutTop}px`
|
|
113
|
+
|
|
114
|
+
// Position label flush against the top of the flyout panel (no gap)
|
|
115
|
+
if (label) {
|
|
116
|
+
label.style.top = `${flyoutTop - labelHeight}px`
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
positionWithinViewport(el) {
|
|
122
|
+
requestAnimationFrame(() => {
|
|
123
|
+
const rect = el.getBoundingClientRect()
|
|
124
|
+
if (rect.height === 0) return
|
|
125
|
+
|
|
126
|
+
const viewportHeight = window.innerHeight
|
|
127
|
+
const margin = 8
|
|
128
|
+
|
|
129
|
+
if (rect.bottom > viewportHeight - margin) {
|
|
130
|
+
const overflow = rect.bottom - viewportHeight + margin
|
|
131
|
+
const currentTop = parseFloat(getComputedStyle(el).top) || 0
|
|
132
|
+
el.style.top = `${currentTop - overflow}px`
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (rect.top < margin) {
|
|
136
|
+
el.style.top = `${margin - el.parentElement.getBoundingClientRect().top}px`
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// ── Submenu expand/collapse (expanded sidebar) ──
|
|
142
|
+
|
|
30
143
|
open(event) {
|
|
31
144
|
if (this.hasSubmenuTarget) {
|
|
32
145
|
const sidebar = this.element.closest('.sidebar')
|
|
@@ -43,8 +156,6 @@ export default class SidebarMenuItemComponentController extends ApplicationContr
|
|
|
43
156
|
event.preventDefault()
|
|
44
157
|
}
|
|
45
158
|
}
|
|
46
|
-
// This breaks turbo, so we need to keep the propagation.
|
|
47
|
-
// event.stopPropagation();
|
|
48
159
|
}
|
|
49
160
|
|
|
50
161
|
openListener(event) {
|
|
@@ -54,7 +165,6 @@ export default class SidebarMenuItemComponentController extends ApplicationContr
|
|
|
54
165
|
}
|
|
55
166
|
}
|
|
56
167
|
|
|
57
|
-
// This method is used to show the submenu
|
|
58
168
|
showSubmenu() {
|
|
59
169
|
if (!this.hasSubmenuTarget || this.isSubmenuVisible) return
|
|
60
170
|
|
|
@@ -62,7 +172,6 @@ export default class SidebarMenuItemComponentController extends ApplicationContr
|
|
|
62
172
|
this.element.classList.toggle("active", true)
|
|
63
173
|
}
|
|
64
174
|
|
|
65
|
-
// This method is used to hide the submenu
|
|
66
175
|
hideSubmenu() {
|
|
67
176
|
if (!this.hasSubmenuTarget || !this.isSubmenuVisible) return
|
|
68
177
|
|
|
@@ -110,12 +219,7 @@ export default class SidebarMenuItemComponentController extends ApplicationContr
|
|
|
110
219
|
return this.openSubmenus.length > 0
|
|
111
220
|
}
|
|
112
221
|
|
|
113
|
-
/**
|
|
114
|
-
* Get a list of all open submenus
|
|
115
|
-
* @returns {NodeListOf<Element>}
|
|
116
|
-
*/
|
|
117
222
|
get openSubmenus() {
|
|
118
|
-
// scope to first match. check if there are any submenus that are not hidden
|
|
119
223
|
return this.element.querySelectorAll('[data-satis-sidebar-menu-item-target="submenu"]:not([class*="hidden"])')
|
|
120
224
|
}
|
|
121
225
|
|
|
@@ -132,7 +132,7 @@ export default class FieldsForController extends ApplicationController {
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
monitorChanges(event) {
|
|
135
|
-
if (event?.detail?.src == "satis-dropdown") {
|
|
135
|
+
if (event?.detail?.src == "satis-dropdown" || event?.detail?.src == "prepopulate" ) {
|
|
136
136
|
// Skip events caused by the initial load of a satis-dropdown
|
|
137
137
|
return
|
|
138
138
|
}
|
|
@@ -6,6 +6,9 @@ application.register("satis-appearance-switcher", AppearanceSwitcherComponentCon
|
|
|
6
6
|
import DateTimePickerComponentController from "satis/components/date_time_picker/component_controller";
|
|
7
7
|
application.register("satis-date-time-picker", DateTimePickerComponentController);
|
|
8
8
|
|
|
9
|
+
import CardComponentController from "satis/components/card/component_controller";
|
|
10
|
+
application.register("satis-card", CardComponentController);
|
|
11
|
+
|
|
9
12
|
import DropdownComponentController from "satis/components/dropdown/component_controller";
|
|
10
13
|
application.register("satis-dropdown", DropdownComponentController);
|
|
11
14
|
|
|
@@ -20,7 +20,7 @@ export default class extends ApplicationController {
|
|
|
20
20
|
this.boundUpdate = this.update.bind(this)
|
|
21
21
|
|
|
22
22
|
this.watchOn = "input"
|
|
23
|
-
if (this.inputTarget.type == "hidden") {
|
|
23
|
+
if (this.inputTarget.type == "hidden" || this.inputTarget.type == "select-one") {
|
|
24
24
|
this.watchOn = "change"
|
|
25
25
|
}
|
|
26
26
|
|
data/lib/satis/version.rb
CHANGED
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.2.
|
|
4
|
+
version: 2.2.2
|
|
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:
|
|
11
|
+
date: 2026-05-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: browser
|
|
@@ -196,10 +196,7 @@ files:
|
|
|
196
196
|
- Rakefile
|
|
197
197
|
- TODO.md
|
|
198
198
|
- app/assets/config/satis_manifest.js
|
|
199
|
-
- app/assets/fontawesome/brands.js
|
|
200
|
-
- app/assets/fontawesome/fontawesome.js
|
|
201
199
|
- app/assets/fontawesome/regular.js
|
|
202
|
-
- app/assets/fontawesome/solid.js
|
|
203
200
|
- app/assets/images/satis/.keep
|
|
204
201
|
- app/assets/images/satis/flags/1x1/ac.svg
|
|
205
202
|
- app/assets/images/satis/flags/1x1/ad.svg
|
|
@@ -770,6 +767,7 @@ files:
|
|
|
770
767
|
- app/components/satis/card/component.css
|
|
771
768
|
- app/components/satis/card/component.html.slim
|
|
772
769
|
- app/components/satis/card/component.rb
|
|
770
|
+
- app/components/satis/card/component_controller.js
|
|
773
771
|
- app/components/satis/color_picker/component.css
|
|
774
772
|
- app/components/satis/color_picker/component.rb
|
|
775
773
|
- app/components/satis/color_picker/component.slim
|