active_admin_prism 0.1.2 → 0.1.4

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.
@@ -201,19 +201,36 @@ form.filter_form .filter_form_field.select_and_search .select2-container {
201
201
 
202
202
  // Main "fieldset.inputs" form: ActiveAdmin's own _forms.scss floats the
203
203
  // label left at 20% width and gives text inputs an explicit
204
- // width: calc(80% - padding) so they sit in the remaining space beside it
205
- // a value this gem has no access to at compile time (it's compiled
204
+ // width: calc(80% - 22px) so they sit in the remaining space beside it
205
+ // a value this gem has no access to at compile time (it's compiled
206
206
  // standalone, without AA's own SCSS variables/mixins in its load path; see
207
- // bin/build-css). Rather than hardcode an equivalent, giving the container
208
- // its own block formatting context (overflow: hidden, no explicit width)
209
- // gets the same result for free: per the CSS spec, a BFC-establishing box
210
- // must not overlap a preceding float's margin box, so the browser sizes it
211
- // to exactly the remaining space automatically. Without this, the default
212
- // 100% width above would render full-width *underneath* the floated
213
- // label, visually painting over it this is the fix for that, not just a
214
- // visual nicety.
215
- fieldset.inputs .select2-container {
216
- overflow: hidden;
207
+ // bin/build-css), so it's matched here as a literal instead.
208
+ //
209
+ // A block-formatting-context trick (overflow: hidden, no explicit width)
210
+ // looks like it should get the same result for free — per the CSS spec, a
211
+ // BFC-establishing box must not overlap a preceding float's margin box —
212
+ // but it only actually sizes the box when its width is auto. Select2 sets
213
+ // an inline `width: 100%` directly on `.select2-container` itself
214
+ // (prism.js's own auto-init passes `{ width: "100%" }`, and jQuery's
215
+ // .css("width", ...) call is what select2.js uses under the hood even for
216
+ // a host's own manual `.select2()` call left at its default width option),
217
+ // so that inline 100% is never auto and the BFC sizing never kicks in —
218
+ // the container renders full-width *underneath* the floated label instead
219
+ // of beside it. `!important` is required here to beat that inline style.
220
+ form fieldset.inputs li.select > .select2-container {
221
+ display: inline-block;
222
+ width: calc(80% - 22px) !important;
223
+ vertical-align: middle;
224
+ }
225
+
226
+ // Any select Select2 has not (yet) enhanced — it hides the real one via a
227
+ // 1px offscreen technique once active, so this only matches before that,
228
+ // or if it's disabled/skipped entirely — needs the same geometry so the
229
+ // row doesn't jump once Select2 does attach.
230
+ form fieldset.inputs li.select > select:not(.select2-hidden-accessible) {
231
+ display: inline-block;
232
+ width: calc(80% - 22px);
233
+ vertical-align: middle;
217
234
  }
218
235
 
219
236
  // The dropdown panel itself is appended to <body> (or wherever
@@ -242,8 +259,18 @@ fieldset.inputs .select2-container {
242
259
  }
243
260
  }
244
261
 
262
+ // Padding on the *list* (not .select2-dropdown itself, which also
263
+ // contains .select2-search--dropdown above with its own padding) is what
264
+ // keeps a highlighted option's square corners from touching the
265
+ // dropdown's own rounded ones — without it, a highlighted first/last
266
+ // option reads as flush, square-edged chrome rather than an inset row.
267
+ .select2-results__options {
268
+ padding: 4px;
269
+ }
270
+
245
271
  .select2-results__option {
246
272
  padding: 8px 12px;
273
+ border-radius: $prism-radius-sm;
247
274
  color: $prism-text-body;
248
275
 
249
276
  &--highlighted {
@@ -258,6 +285,52 @@ fieldset.inputs .select2-container {
258
285
  }
259
286
  }
260
287
 
288
+ // Shared look for this theme's own "jump menu" Select2 widgets — the
289
+ // consolidated action_items dropdown (lib/active_admin/views/title_bar.rb
290
+ // / js-src/prism.js, ".prism-action-items-dropdown") and the consolidated
291
+ // non-Filters sidebar section dropdown ("Sidebar Actions" —
292
+ // ".prism-sidebar-panel-select-wrapper"). Both fire a click on a real,
293
+ // hidden link/button and immediately reset rather than holding a
294
+ // persistent value, so they're styled to read as a highlighted
295
+ // button-like menu instead of a plain form field —
296
+ // consistent with each other, which a plain select2 reskin alone doesn't
297
+ // give them (its own text naturally comes out right-aligned here, not
298
+ // centered: "#titlebar_right { text-align: right }" in ActiveAdmin core's
299
+ // own _title_bar.scss is inherited all the way down to
300
+ // .select2-selection__rendered's own text otherwise, and the sidebar
301
+ // dropdown lives in the same inherited-alignment tree via #sidebar).
302
+ .prism-action-items-dropdown,
303
+ .prism-sidebar-panel-select-wrapper {
304
+ .select2-selection--single {
305
+ border-color: rgba($prism-color-primary, 0.4);
306
+ background: $prism-color-primary-light;
307
+ }
308
+
309
+ .select2-container--open .select2-selection--single,
310
+ .select2-container--focus .select2-selection--single {
311
+ border-color: $prism-color-primary;
312
+ }
313
+
314
+ // !important: the base ".select2-container .select2-selection--single
315
+ // .select2-selection__rendered" rule above this one is three classes
316
+ // deep (0,3,0) — more specific than this wrapper-scoped selector
317
+ // (0,2,0) alone, so color/font-weight here would otherwise lose
318
+ // regardless of source order.
319
+ .select2-selection__rendered {
320
+ text-align: center;
321
+ color: $prism-color-primary-dark !important;
322
+ font-weight: 700 !important;
323
+ }
324
+
325
+ .select2-selection__placeholder {
326
+ color: $prism-color-primary-dark !important;
327
+ }
328
+
329
+ .select2-selection__arrow b {
330
+ border-top-color: $prism-color-primary-dark !important;
331
+ }
332
+ }
333
+
261
334
  .select2-results__message {
262
335
  color: $prism-text-muted;
263
336
  padding: 8px 12px;
@@ -29,6 +29,30 @@ body:not(.logged_out).index #wrapper {
29
29
  grid-template-rows: auto auto auto 1fr auto;
30
30
  min-height: 100vh;
31
31
  width: 100%;
32
+ // Animates the reflow when ActiveAdminPrism.configuration#sidebar_collapsible's
33
+ // toggle fires (see "body.prism-sidebar-collapsed" below) — a no-op the
34
+ // rest of the time. Grid track sizes are animatable in every currently
35
+ // supported browser; where they aren't, this simply snaps instead of
36
+ // sliding, same graceful-degradation as the collapsible Filters panel's
37
+ // own reflow (scss-src/_panels.scss).
38
+ transition: grid-template-columns 280ms cubic-bezier(0.4, 0, 0.2, 1);
39
+ }
40
+
41
+ // Desktop sidebar rail-collapse (ActiveAdminPrism::Configuration
42
+ // #sidebar_collapsible, toggled by .prism-sidebar-collapse-toggle — see
43
+ // js-src/prism.js). Explicitly scoped to desktop widths (matching the
44
+ // "max-width: 900px" mobile breakpoint below): below that width the
45
+ // sidebar is already off-canvas (slid fully off-screen via `transform`,
46
+ // full width once opened) — .prism-sidebar-collapsed can still be present
47
+ // on <body> there (nothing clears it on resize), so without this guard a
48
+ // visitor who'd collapsed the rail on desktop and then opened the mobile
49
+ // off-canvas menu would get it stuck at rail width instead of a normal,
50
+ // readable full-width drawer.
51
+ @media (min-width: 901px) {
52
+ body.prism-sidebar-collapsed:not(.logged_out) #wrapper,
53
+ body.prism-sidebar-collapsed:not(.logged_out).index #wrapper {
54
+ grid-template-columns: $prism-sidebar-collapsed-width 1fr;
55
+ }
32
56
  }
33
57
 
34
58
  #header.prism-sidebar {
@@ -59,6 +83,7 @@ body:not(.logged_out).index #wrapper {
59
83
  max-height: 100vh;
60
84
  overflow: hidden;
61
85
  z-index: 100;
86
+ transition: width 280ms cubic-bezier(0.4, 0, 0.2, 1);
62
87
 
63
88
  // Reset the inherited primary-gradient/text-shadow look from AA's default
64
89
  // #header rule — this component owns its own visual language.
@@ -124,6 +149,9 @@ body:not(.prism-sidebar-footer-disabled) #footer {
124
149
 
125
150
  .prism-sidebar-brand {
126
151
  flex: 0 0 auto;
152
+ display: flex;
153
+ align-items: center;
154
+ gap: 12px;
127
155
  padding: 20px 24px;
128
156
  border-bottom: 1px solid $prism-border-color;
129
157
 
@@ -133,6 +161,8 @@ body:not(.prism-sidebar-footer-disabled) #footer {
133
161
  font-size: 1.15em;
134
162
  font-weight: 700;
135
163
  color: $prism-text-heading;
164
+ overflow: hidden;
165
+ white-space: nowrap;
136
166
 
137
167
  a {
138
168
  color: inherit;
@@ -141,6 +171,32 @@ body:not(.prism-sidebar-footer-disabled) #footer {
141
171
  }
142
172
  }
143
173
 
174
+ // Hamburger icon button, top of the sidebar (ActiveAdminPrism::Configuration
175
+ // #sidebar_collapsible) — see prism_sidebar.rb#render_collapse_toggle.
176
+ .prism-sidebar-collapse-toggle {
177
+ flex: 0 0 auto;
178
+ display: flex;
179
+ align-items: center;
180
+ justify-content: center;
181
+ width: 32px;
182
+ height: 32px;
183
+ margin: -6px 0;
184
+ border-radius: $prism-radius-sm;
185
+ color: $prism-text-muted;
186
+ cursor: pointer;
187
+ user-select: none;
188
+ transition: background $prism-transition-fast, color $prism-transition-fast;
189
+
190
+ &:hover {
191
+ background: $prism-bg-page;
192
+ color: $prism-text-heading;
193
+ }
194
+ }
195
+
196
+ .prism-sidebar-collapse-icon {
197
+ flex: 0 0 auto;
198
+ }
199
+
144
200
  // "Languages" dropdown (ActiveAdminPrismTheme::Configuration
145
201
  // #language_switcher/#languages) — sits between the brand and the Pages
146
202
  // nav list. Positioned relative so .prism-lang-menu (an absolutely
@@ -519,6 +575,84 @@ body:not(.prism-sidebar-footer-disabled) #footer {
519
575
  font-weight: 700;
520
576
  line-height: 20px;
521
577
  }
578
+
579
+ }
580
+
581
+ // Collapsed rail state: shrink the sidebar itself (the #wrapper grid
582
+ // track already narrowed above) and hide every label/text element,
583
+ // leaving just the icon column. Every item keeps its native `title`
584
+ // attribute (see prism_sidebar.rb's render_leaf/render_group_toggle) as
585
+ // the only way left to identify it by hovering. Scoped to desktop widths —
586
+ // see the comment on the #wrapper override above for why this can't apply
587
+ // unconditionally.
588
+ @media (min-width: 901px) {
589
+ body.prism-sidebar-collapsed #header.prism-sidebar {
590
+ width: $prism-sidebar-collapsed-width;
591
+
592
+ .prism-sidebar-brand {
593
+ padding: 20px 0;
594
+ justify-content: center;
595
+ }
596
+
597
+ .prism-sidebar-brand #site_title,
598
+ .prism-sidebar-lang,
599
+ .prism-sidebar-search,
600
+ .prism-nav-section-label,
601
+ .prism-nav-label,
602
+ .prism-lang-current,
603
+ .prism-sidebar-lang .prism-chevron,
604
+ .prism-nav-item .prism-chevron,
605
+ .prism-sidebar-footer {
606
+ display: none;
607
+ }
608
+
609
+ // !important: `.prism-nav-item.open > .prism-nav-submenu { display:
610
+ // block; }` above (b=4 classes) is otherwise MORE specific than even
611
+ // this rule's `body.prism-sidebar-collapsed #header.prism-sidebar
612
+ // .prism-nav-submenu` (b=3 classes plus the body type selector, which
613
+ // only breaks a tie and doesn't offset a class-count deficit) — a
614
+ // group left open before collapsing would keep rendering its full
615
+ // submenu (every child's icon *and* label) spilling out past the 76px
616
+ // rail instead of collapsing down to just the parent's own icon.
617
+ .prism-nav-submenu {
618
+ display: none !important;
619
+ }
620
+
621
+ .prism-sidebar-scroll {
622
+ padding: 20px 8px;
623
+ }
624
+
625
+ .prism-nav-item {
626
+ > .prism-nav-link,
627
+ > .prism-nav-group-toggle {
628
+ justify-content: center;
629
+ padding: 9px;
630
+ }
631
+
632
+ // A menu item registered with no `icon:` (see [Sidebar navigation:
633
+ // icons & badges] in INTEGRATION.md) renders only its now-hidden
634
+ // .prism-nav-label — nothing at all while collapsed, which for an
635
+ // `.active` item is an empty color-highlighted box with no visible
636
+ // content to anchor it, and for any other item is a totally blank
637
+ // row indistinguishable from dead space. A small dot keeps every
638
+ // row visually non-empty without requiring every host to assign an
639
+ // icon to every single item just to look right once collapsed.
640
+ > .prism-nav-link:not(:has(.prism-nav-icon))::after,
641
+ > .prism-nav-group-toggle:not(:has(.prism-nav-icon))::after {
642
+ content: "";
643
+ width: 6px;
644
+ height: 6px;
645
+ border-radius: 50%;
646
+ background: currentColor;
647
+ opacity: 0.6;
648
+ }
649
+ }
650
+
651
+ .prism-sidebar-utility {
652
+ padding-left: 8px;
653
+ padding-right: 8px;
654
+ }
655
+ }
522
656
  }
523
657
 
524
658
  .prism-sidebar-mobile-toggle {
@@ -550,13 +684,20 @@ body:not(.prism-sidebar-footer-disabled) #footer {
550
684
  grid-template-columns: 1fr;
551
685
  }
552
686
 
687
+ // "left" (not "transform: translateX(...)") is what actually slides this
688
+ // panel off/on screen — deliberately. A `transform` on this element
689
+ // would make IT the containing block for any `position: fixed`
690
+ // descendant (CSS Positioned Layout spec), which is exactly what
691
+ // .prism-sidebar-mobile-toggle above is: it'd slide off-screen right
692
+ // along with the (intentionally hidden) sidebar instead of staying
693
+ // fixed to the viewport corner where a visitor could actually reach it
694
+ // to open the menu back up. `left` carries no such side effect.
553
695
  #header.prism-sidebar {
554
696
  position: fixed;
555
- left: 0;
697
+ left: -#{$prism-sidebar-width};
556
698
  top: 0;
557
699
  bottom: 0;
558
- transform: translateX(-100%);
559
- transition: transform $prism-transition-fast;
700
+ transition: left $prism-transition-fast;
560
701
  box-shadow: $prism-shadow-popover;
561
702
  }
562
703
 
@@ -568,6 +709,6 @@ body:not(.prism-sidebar-footer-disabled) #footer {
568
709
  }
569
710
 
570
711
  body.prism-sidebar-open #header.prism-sidebar {
571
- transform: translateX(0);
712
+ left: 0;
572
713
  }
573
714
  }
@@ -1,8 +1,106 @@
1
- // ActiveAdmin wraps the index table + pagination in this container —
2
- // letting it scroll horizontally, rather than the columns visually
3
- // colliding, is the robust fallback on narrow viewports.
4
- .paginated_collection_contents {
1
+ // ActiveAdmin wraps the index table + pagination/download-links footer
2
+ // (`#index_footer`) together in ".paginated_collection_contents", but the
3
+ // table itself (or grid/block index, for `config.index_as :grid`/etc.)
4
+ // renders inside a narrower ".index_content" div nested inside that —
5
+ // a sibling of `#index_footer`, not an ancestor of it (see ActiveAdmin
6
+ // core's own lib/active_admin/views/pages/index.rb#render_index). Scoping
7
+ // the scroll to ".index_content" instead of the outer container means
8
+ // only the table itself scrolls horizontally on a narrow viewport/wide
9
+ // table, not the footer sitting under it, which has no columns to align
10
+ // with anything and would otherwise scroll off out of sync with what
11
+ // it's describing.
12
+ .index_content {
13
+ position: relative;
5
14
  overflow-x: auto;
15
+
16
+ // A native scrollbar is the one scroll affordance every visitor
17
+ // already recognizes on sight — thin/auto-hiding trackpad-style
18
+ // scrollbars (this gem's default OS/browser behavior otherwise) don't
19
+ // read that way until actively dragged. Made permanently visible,
20
+ // thick, and brand-colored instead, so its mere presence — not just
21
+ // the shadow/chevron below — already says "this scrolls".
22
+ scrollbar-width: auto;
23
+ scrollbar-color: $prism-color-primary rgba($prism-color-primary, 0.12);
24
+
25
+ &::-webkit-scrollbar {
26
+ height: 12px;
27
+ }
28
+
29
+ &::-webkit-scrollbar-track {
30
+ background: rgba($prism-color-primary, 0.12);
31
+ border-radius: $prism-radius-pill;
32
+ }
33
+
34
+ &::-webkit-scrollbar-thumb {
35
+ background: $prism-color-primary;
36
+ border-radius: $prism-radius-pill;
37
+ border: 2px solid $prism-bg-card;
38
+
39
+ &:hover {
40
+ background: $prism-color-primary-dark;
41
+ }
42
+ }
43
+
44
+ // Scroll-shadow-plus-chevron affordance (js-src/prism.js toggles the
45
+ // two classes below based on actual scroll position) — a table simply
46
+ // cut off flush at this wrapper's edge otherwise looks identical
47
+ // whether there's more hidden past it or not. A colored (not just
48
+ // gray) gradient, a bold bouncing chevron (`content` renders it as
49
+ // real generated text, no extra markup needed), and a
50
+ // `drop-shadow` for legibility over any cell content are deliberately
51
+ // more assertive than a plain subtle fade — paired with the scrollbar
52
+ // above, this is meant to be unmissable, not merely present if you
53
+ // look closely.
54
+ &::before,
55
+ &::after {
56
+ position: absolute;
57
+ top: 0;
58
+ bottom: 12px;
59
+ width: 56px;
60
+ display: flex;
61
+ align-items: center;
62
+ pointer-events: none;
63
+ opacity: 0;
64
+ transition: opacity $prism-transition-fast;
65
+ z-index: 2;
66
+ font-size: 26px;
67
+ font-weight: 700;
68
+ color: $prism-color-primary-dark;
69
+ filter: drop-shadow(0 1px 1px rgba(255, 255, 255, 0.9));
70
+ }
71
+
72
+ &::before {
73
+ content: "‹";
74
+ left: 0;
75
+ justify-content: flex-start;
76
+ padding-left: 4px;
77
+ background: linear-gradient(to right, rgba($prism-color-primary, 0.22), transparent);
78
+ animation: prism-scroll-hint-left 1.4s ease-in-out infinite;
79
+ }
80
+
81
+ &::after {
82
+ content: "›";
83
+ right: 0;
84
+ justify-content: flex-end;
85
+ padding-right: 4px;
86
+ background: linear-gradient(to left, rgba($prism-color-primary, 0.22), transparent);
87
+ animation: prism-scroll-hint-right 1.4s ease-in-out infinite;
88
+ }
89
+
90
+ &.prism-scroll-left::before,
91
+ &.prism-scroll-right::after {
92
+ opacity: 1;
93
+ }
94
+ }
95
+
96
+ @keyframes prism-scroll-hint-left {
97
+ 0%, 100% { transform: translateX(0); }
98
+ 50% { transform: translateX(-6px); }
99
+ }
100
+
101
+ @keyframes prism-scroll-hint-right {
102
+ 0%, 100% { transform: translateX(0); }
103
+ 50% { transform: translateX(6px); }
6
104
  }
7
105
 
8
106
  table.index_table {
@@ -12,7 +12,9 @@ $prism-color-success-light: #e8f9ee !default;
12
12
  $prism-color-danger: #ef4444 !default;
13
13
  $prism-color-danger-light: #fdecec !default;
14
14
  $prism-color-warning: #f59e0b !default;
15
+ $prism-color-warning-light: #fef3e2 !default;
15
16
  $prism-color-info: #3b82f6 !default;
17
+ $prism-color-info-light: #eaf2fe !default;
16
18
 
17
19
  $prism-bg-page: #f4f5f7 !default;
18
20
  $prism-bg-card: #ffffff !default;
@@ -27,6 +29,7 @@ $prism-border-color: #e6e8ec !default;
27
29
  $prism-border-color-strong: #d6d9e0 !default;
28
30
 
29
31
  $prism-sidebar-width: 264px !default;
32
+ $prism-sidebar-collapsed-width: 76px !default;
30
33
  $prism-radius: 10px !default;
31
34
  $prism-radius-sm: 6px !default;
32
35
  $prism-radius-pill: 999px !default;
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_admin_prism
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ram Laxman Yadav
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-07-22 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activeadmin
@@ -101,11 +100,15 @@ files:
101
100
  - app/views/active_admin/devise/sessions/new.html.erb
102
101
  - app/views/active_admin/devise/shared/_brand.html.erb
103
102
  - app/views/active_admin/devise/unlocks/new.html.erb
103
+ - app/views/layouts/active_admin_logged_out.html.erb
104
104
  - js-src/prism.js
105
+ - lib/active_admin/views/action_items.rb
106
+ - lib/active_admin/views/active_filters_bar.rb
105
107
  - lib/active_admin/views/filters_sidebar.rb
106
108
  - lib/active_admin/views/flash_messages.rb
107
109
  - lib/active_admin/views/index_table_actions.rb
108
110
  - lib/active_admin/views/prism_sidebar.rb
111
+ - lib/active_admin/views/title_bar.rb
109
112
  - lib/active_admin_prism.rb
110
113
  - lib/active_admin_prism/configuration.rb
111
114
  - lib/active_admin_prism/engine.rb
@@ -139,7 +142,6 @@ metadata:
139
142
  homepage_uri: https://github.com/ramlaxmanyadav/active_admin_prism
140
143
  source_code_uri: https://github.com/ramlaxmanyadav/active_admin_prism
141
144
  changelog_uri: https://github.com/ramlaxmanyadav/active_admin_prism/blob/main/CHANGELOG.md
142
- post_install_message:
143
145
  rdoc_options: []
144
146
  require_paths:
145
147
  - lib
@@ -154,8 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
156
  - !ruby/object:Gem::Version
155
157
  version: '0'
156
158
  requirements: []
157
- rubygems_version: 3.4.10
158
- signing_key:
159
+ rubygems_version: 3.6.9
159
160
  specification_version: 4
160
161
  summary: 'Prism: a plug-and-play sidebar theme for ActiveAdmin'
161
162
  test_files: []