active_admin_prism 0.1.1 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 856ce99225e35f41d012115c829406cb1de886ef7d36af3aa5b9e12978afe057
4
- data.tar.gz: f7698fb938f3ea46bb86496ce3f80cc7cfaa74fd887a9425b8b46b7711f38a13
3
+ metadata.gz: 34c64b9f9a4624ab0c6b5bcebd46bd4c65b220e86fa6b8095d26ee35acdb4af2
4
+ data.tar.gz: 72e3885c4e3f91874b6e6f99b629c3480eb4b1098de4044f12e3c6d50b95bf66
5
5
  SHA512:
6
- metadata.gz: add5ff5ce0bae255af731412b88af58dad8f9572323acf09f58ed8830253b44e13f269418a83ee796a50f0f19411ba7ea692893215e683379abd55acda003b9c
7
- data.tar.gz: 4f4554adf93c92eb6cc090b7b7116b54bad8fdab489dfa84d59c5aded4f3282a40c2d864b6b01011d78dd786178a2d27042fc260eb73aa68f37917a9c91cc10c
6
+ metadata.gz: 230e4441cbc71b105e1abe0b0e592fa7451c070ab4be8b2d32c5acdce55f9014b3f6c2918915bff637fe568e4299243dd9362c6a303725d977d3010ddf409e59
7
+ data.tar.gz: 052d8bfe74e598622c5922e0e1201ccfcf574d35937c1a6af17b71c9da06c8dbcf8311ab6df7edcd97cab957f0c70a9bf7205fdbfcf61ef63b576b230ab3a16c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.2
4
+
5
+ - Adds [Select2](https://select2.org) support (`config.select2`, default
6
+ `false` — the only opt-in-by-default flag in this gem) — reskinned to
7
+ match the theme, and now vendored inside the gem's own assets (no
8
+ separate gem/npm dependency, no JS of your own required). Turn it on to
9
+ auto-enhance *every* plain `<select>` (filters, form inputs, association
10
+ pickers) into a searchable widget with zero per-field setup; or leave it
11
+ off and opt individual fields in yourself the same way you would in any
12
+ other Rails app (`input_html: { class: "..." }` + your own `.select2()`
13
+ call) — both approaches coexist without double-initializing the same
14
+ element. Covers single-select, multi-select ("tags"/pill chips), and the
15
+ open dropdown/search box/results list — see
16
+ [Select2](INTEGRATION.md#select2) in INTEGRATION.md. Without the CSS
17
+ half of this, a Select2-enhanced select rendered at its tiny unstyled
18
+ default size, and its open dropdown could clash with the theme entirely.
19
+ - Fixed: the collapsible Filters sidebar panel kept `overflow: hidden`
20
+ even while expanded, clipping/garbling any dropdown (Select2 or AA's own
21
+ "select + search" filter widget) that needed to render outside its own
22
+ input's bounds. `&.open`/the `collapsible_filters: false` backstop now
23
+ reset `overflow` back to `visible`.
24
+ - Fixed: the Cancel button (and any other `fieldset.actions`/
25
+ `fieldset.buttons` link styled via `prism-button-secondary`) rendered
26
+ with ActiveAdmin's own pill-shaped `border-radius: 200px` instead of
27
+ Prism's — a more specific AA selector was winning on that one property
28
+ even though Prism's color/background already won via `!important`. Both
29
+ button mixins now mark `border-radius` `!important` too.
30
+ - Fixed: form action buttons (Create/Update + Cancel) could stack
31
+ vertically instead of sitting side by side. ActiveAdmin lays them out
32
+ via `float: left` on each `<li>`, which is fragile (a longer button
33
+ label, or a host's own CSS, can lose the float); the actions `<ol>` is
34
+ now a flex row instead, which floats have no effect on regardless of
35
+ specificity or content width.
36
+
3
37
  ## 0.1.1
4
38
 
5
39
  - A search box renders at the top of the sidebar's "Pages" nav
data/INTEGRATION.md CHANGED
@@ -131,6 +131,8 @@ ActiveAdminPrism.configure do |config|
131
131
  { label: "Español", locale: :es },
132
132
  { label: "Français", locale: :fr }
133
133
  ]
134
+ config.menu_search = true # default: true
135
+ config.select2 = false # default: false (opt-in — see below)
134
136
  end
135
137
 
136
138
  ActiveAdminPrism.enable!
@@ -153,6 +155,8 @@ ActiveAdminPrism.enable!
153
155
  | `login_tagline` | `"Sign in to your admin dashboard"` | `nil` renders no tagline at all. |
154
156
  | `language_switcher` | `true` | No "Languages" dropdown renders in the sidebar at all — see [Language switcher](#language-switcher). |
155
157
  | `languages` | 3 entries (English/Español/Français) | The list the dropdown renders; an empty array (`[]`) has the same effect as `language_switcher = false`. |
158
+ | `menu_search` | `true` | No search box renders above the sidebar's "Pages" nav — see [Menu search](#menu-search). |
159
+ | `select2` | `false` | **Opposite polarity from every other flag above — opt-in, not opt-out.** `false` (the default) leaves every `<select>` exactly as ActiveAdmin renders it. `true` auto-enhances *every* plain `<select>` (filters, form inputs, association pickers — no per-field setup) into a searchable Select2 widget — see [Select2](#select2). |
156
160
 
157
161
  **How this crosses the server/client boundary.** `sidebar`,
158
162
  `colorize_action_icons`, and the `login_*` flags are pure server-side
@@ -421,6 +425,40 @@ ActiveAdmin's own `Menu`/`MenuItem`/`build_menu` machinery — see
421
425
  [Language switcher markup](#language-switcher-markup) for why, and for the
422
426
  full class/id reference.
423
427
 
428
+ ### Menu search
429
+
430
+ A search box renders at the top of the sidebar, between the language
431
+ switcher (if any) and the "Pages" nav — no setup required beyond the
432
+ default `config.menu_search = true`. It filters your existing `menu do |m|
433
+ ... end` items by label as you type; there's no server round trip and no
434
+ change to how those blocks are authored in `app/admin/*.rb` — see
435
+ `lib/active_admin/views/prism_sidebar.rb#render_search_box` for the markup
436
+ and `js-src/prism.js` for the filtering logic itself.
437
+
438
+ Matching is case-insensitive and works at any nesting depth, since the
439
+ whole menu tree is already rendered up front and the filtering happens
440
+ purely client-side over the existing DOM:
441
+
442
+ - A submenu item that matches keeps its parent group visible **and
443
+ expanded**, even though the parent's own label doesn't match — so a
444
+ match buried a couple of levels deep is never hidden behind a collapsed
445
+ group.
446
+ - A parent whose own label matches reveals its **entire** submenu,
447
+ expanded, regardless of whether any individual child also matches.
448
+ - Items that don't match (and have no matching descendant) get
449
+ `.prism-nav-hidden`; if nothing in the whole nav matches, a
450
+ `.prism-nav-empty` "No matching menu items" message takes their place.
451
+
452
+ Clearing the input — via the "x" button (`data-prism-nav-search-clear`,
453
+ only shown while there's a query) or pressing <kbd>Escape</kbd> while the
454
+ input has focus and a value — resets the nav back to its normal
455
+ expand/collapse state (whatever `.open`/`.active` state it already had
456
+ from user-toggling or the current page, unrelated to search).
457
+
458
+ Turn it off with `config.menu_search = false` — no search box renders at
459
+ all, and the "Pages" nav starts directly below the brand/language
460
+ switcher, matching this gem's behavior before the feature existed.
461
+
424
462
  ### Icon helper
425
463
 
426
464
  Available anywhere in your admin views (not just the sidebar):
@@ -461,6 +499,92 @@ end
461
499
  Explicit opt-in per column/row — ActiveAdmin's default `status_tag`
462
500
  "Yes"/"No" pill is untouched everywhere you don't call it.
463
501
 
502
+ ### Select2
503
+
504
+ Prism reskins [Select2](https://select2.org) — the jQuery widget that makes
505
+ a `<select>` searchable — and ships it vendored inside its own assets
506
+ (`vendor/select2`, MIT licensed), so there's no separate gem/npm dependency
507
+ or JS of your own to add either way. Two ways to use it:
508
+
509
+ **1. Every select, automatically — `config.select2 = true`.** Opt-in
510
+ (default `false`, the only flag in this gem with that polarity — see
511
+ [Configuration reference](#configuration-reference)):
512
+
513
+ ```ruby
514
+ ActiveAdminPrism.configure do |config|
515
+ config.select2 = true
516
+ end
517
+ ```
518
+
519
+ With this on, *every* plain `<select>` ActiveAdmin renders — filters, form
520
+ inputs, association pickers, ransack predicate dropdowns, date-part
521
+ selects, all of it, no per-field setup — becomes a searchable Select2
522
+ widget. There's no way to exclude individual selects from this today; if
523
+ you only want it on specific fields, use the next approach instead.
524
+
525
+ **2. Specific fields only — bring your own `.select2()` call.** Leave
526
+ `config.select2` at its default `false` and initialize Select2 yourself,
527
+ the same way you would in any other Rails app (this still works whether or
528
+ not you also load your own separate copy of Select2 — Prism's vendored
529
+ copy and a host's own don't conflict, they just both define
530
+ `jQuery.fn.select2` and the last one loaded wins, harmlessly):
531
+
532
+ ```ruby
533
+ # app/admin/teachers.rb
534
+ filter :subject, input_html: { class: "your-select2-class" }
535
+
536
+ form do |f|
537
+ f.input :subject, input_html: { class: "your-select2-class" }
538
+ end
539
+ ```
540
+
541
+ ```js
542
+ $(".your-select2-class").select2({ width: "100%" })
543
+ ```
544
+
545
+ Either way, any element Select2 replaces picks up Prism's border/radius/
546
+ focus-ring styling automatically, matching every other input in the
547
+ theme; its open dropdown (search box, results list) is styled to match
548
+ Prism's popover look — see [Select2 markup](#select2-markup) for the
549
+ class reference. The auto-init (approach 1) skips any `<select>` a host
550
+ already initialized manually (approach 2) — see `js-src/prism.js` — so
551
+ the two can coexist: turn `config.select2` on globally and still hand-roll
552
+ one particular field's Select2 options (`tags: true`, a custom
553
+ `ajax:`, etc.) yourself, since your own `.select2()` call runs first and
554
+ the auto-init recognizes it's already initialized.
555
+
556
+ **Multi-select ("tags") mode** — e.g. a `has_many`/`has_and_belongs_to_many`
557
+ association — is themed too, as pill-shaped chips instead of Select2's own
558
+ default boxed/absolute-positioned look:
559
+
560
+ ```ruby
561
+ f.input :subjects, as: :select, multiple: true, input_html: { class: "your-select2-class" }, collection: Subject.all
562
+ ```
563
+
564
+ Everything above (width handling, dropdown styling) applies the same way
565
+ regardless of single/multiple mode, and regardless of which of the two
566
+ approaches initialized it.
567
+
568
+ **Why width behaves differently in the sidebar Filters panel vs. a form.**
569
+ The Filters panel and standalone filter forms stack each field's label
570
+ above it (no float), so Select2 renders at a flat `width: 100%` there,
571
+ matching `.sidebar_section select`'s own width rule. A `fieldset.inputs`
572
+ form (the main new/edit form) instead floats the label to the *left* and
573
+ gives text inputs an explicit `calc(80% - padding)` width so they sit
574
+ beside it — a padding value this gem has no access to at compile time
575
+ (its CSS is compiled standalone from `scss-src/*.scss`, without
576
+ ActiveAdmin's own Sass variables in its load path; see
577
+ [Customizing colors](#customizing-colors)). Rather than hardcode an
578
+ equivalent, Prism gives the field its own block formatting context
579
+ (`overflow: hidden`, no explicit width) there instead — the CSS spec
580
+ requires a box like that not to overlap a preceding float's box, so the
581
+ browser sizes it to exactly the remaining space automatically, no magic
582
+ number needed. If you render a Select2 field somewhere using neither of
583
+ these two layout conventions, you may need your own `width`/`overflow`
584
+ override alongside it — without one, a full-width Select2 box will render
585
+ *underneath* a floated label rather than beside it, visually hiding the
586
+ label.
587
+
464
588
  ### Row-level action icons
465
589
 
466
590
  View/Edit/Delete on index pages render as color-coded icon buttons (blue
@@ -643,13 +767,20 @@ Ruby view files under `lib/active_admin/views/`.
643
767
  div.prism-sidebar-brand
644
768
  #site_title <- AA's own site_title verb, unchanged
645
769
  div.prism-sidebar-lang <- only if config.language_switcher and #languages is non-empty
770
+ div.prism-sidebar-search <- only if config.menu_search
771
+ svg.prism-nav-icon.prism-search-icon
772
+ input.prism-nav-search-input[type=search][data-prism-nav-search]
773
+ span.prism-nav-search-clear[data-prism-nav-search-clear]
774
+ svg.prism-nav-icon <- the :x icon
646
775
  div.prism-sidebar-scroll
647
776
  div.prism-nav-section-label <- "PAGES"
648
777
  ul.prism-nav
649
778
  li.prism-nav-item[#prism_nav_<id>]
650
779
  [.has-children] <- item.items.any?
651
780
  [.active] <- item.current?(current_tab)
652
- [.open] <- has-children && active, or user-toggled
781
+ [.open] <- has-children && active, or user-toggled, or search match (see below)
782
+ [.prism-nav-hidden] <- filtered out by menu search, toggled client-side
783
+ [.prism-search-open] <- this item or a descendant matches the current search query
653
784
  span.prism-nav-group-toggle <- only when .has-children
654
785
  svg.prism-nav-icon
655
786
  span.prism-nav-label
@@ -658,6 +789,7 @@ Ruby view files under `lib/active_admin/views/`.
658
789
  svg.prism-nav-icon
659
790
  span.prism-nav-label
660
791
  ul.prism-nav-submenu <- only when .has-children, nested li.prism-nav-item...
792
+ div.prism-nav-empty[.prism-nav-empty-visible] <- "No matching menu items", shown when search yields zero results
661
793
  div.prism-sidebar-utility <- only if the utility menu has items
662
794
  ul.prism-nav.prism-nav-utility
663
795
  li#prism_nav_current_user
@@ -708,6 +840,37 @@ than being fixed at boot the way the sidebar's own header-swap
708
840
  registration is (see [Sign-in page](#sign-in-page) for the other example
709
841
  of that "built once at boot vs. re-read every request" distinction).
710
842
 
843
+ ### Menu search markup
844
+
845
+ ```
846
+ div.prism-sidebar-search
847
+ svg.prism-nav-icon.prism-search-icon
848
+ input.prism-nav-search-input[type=search][data-prism-nav-search][placeholder="Search menu"]
849
+ span.prism-nav-search-clear[data-prism-nav-search-clear][.prism-nav-search-clear-visible]
850
+ svg.prism-nav-icon <- the :x icon
851
+ ```
852
+
853
+ All filtering state lives on the existing `li.prism-nav-item` tree
854
+ rendered by [Sidebar](#sidebar-activeadminviewsprismsidebar) — `prism.js`
855
+ reads `[data-prism-nav-search]`'s value on every `input` event and, per
856
+ item, toggles:
857
+
858
+ - `.prism-nav-hidden` — item (and every descendant) doesn't match and has
859
+ no matching descendant; hidden via CSS.
860
+ - `.prism-search-open` — item itself matches, or has a matching
861
+ descendant; combined with `.has-children`, this is what keeps a group
862
+ expanded during a search independently of its own user-toggled `.open`
863
+ state.
864
+ - `.prism-nav-search-clear-visible` on the clear button, and
865
+ `.prism-nav-empty-visible` on `div.prism-nav-empty`, both mirroring
866
+ whether the query is non-empty / yields zero matches.
867
+
868
+ <kbd>Escape</kbd> while the input is focused and non-empty, or a click on
869
+ `[data-prism-nav-search-clear]`, clears the value and re-triggers the same
870
+ filtering pass (an empty query matches everything, restoring the nav's
871
+ prior expand/collapse state). None of this touches the server — the menu
872
+ tree itself is rendered once, same as without `config.menu_search`.
873
+
711
874
  ### Panels & cards
712
875
 
713
876
  Pure CSS reskin of AA's existing `Panel`/`Component` markup — no new
@@ -774,6 +937,39 @@ read-only tag — same pill/thumb CSS, driven by a sibling `:checked`
774
937
  selector in the form case and by the `.on`/`.off` class in the read-only
775
938
  case (there's no real `<input>` on an index/show page).
776
939
 
940
+ ### Select2 markup
941
+
942
+ Only rendered if your app's own JS actually calls `.select2()` on an
943
+ element — see [Select2](#select2). This is
944
+ Select2's own markup, reskinned by targeting its own class names, not
945
+ anything Prism itself renders:
946
+
947
+ ```
948
+ .select2-container <- replaces the original (now hidden) <select>
949
+ .select2-selection--single <- single-select: the visible closed-state box
950
+ .select2-selection__rendered <- selected option's text
951
+ .select2-selection__placeholder
952
+ .select2-selection__arrow
953
+ .select2-selection__clear <- the "x" clear button (allowClear: true)
954
+ .select2-selection--multiple <- multiple: true instead — a row of pill "chips"
955
+ .select2-selection__rendered
956
+ li.select2-selection__choice <- one per selected option
957
+ .select2-selection__choice__display <- its label text
958
+ .select2-selection__choice__remove <- its own "x" remove button
959
+ .select2-search--inline
960
+ input.select2-search__field <- the free-typing search box inline with the chips
961
+ [.select2-container--open] <- while its dropdown is open
962
+ [.select2-container--focus] <- multiple mode: while focused (not necessarily open)
963
+ [.select2-container--disabled]
964
+
965
+ .select2-dropdown <- the open dropdown, appended to <body> (or `dropdownParent`)
966
+ .select2-search--dropdown
967
+ input.select2-search__field <- the built-in search box
968
+ ul.select2-results
969
+ li.select2-results__option[.select2-results__option--highlighted][aria-selected="true"]
970
+ li.select2-results__message <- "No results found" etc.
971
+ ```
972
+
777
973
  ### Filters sidebar panel (`#filters_sidebar_section`)
778
974
 
779
975
  Only this specific `SidebarSection` (AA's built-in id for the Filters
data/README.md CHANGED
@@ -116,6 +116,8 @@ ActiveAdminPrism.configure do |config|
116
116
  { label: "Español", locale: :es },
117
117
  { label: "Français", locale: :fr }
118
118
  ]
119
+ config.menu_search = true # search box that filters the sidebar's Pages nav
120
+ config.select2 = false # default: false — auto-enhance every <select> into Select2
119
121
  end
120
122
 
121
123
  ActiveAdminPrism.enable!
@@ -178,6 +180,22 @@ endpoint that sets the locale server-side:
178
180
 
179
181
  Turn the whole thing off with `config.language_switcher = false`.
180
182
 
183
+ ## Menu search
184
+
185
+ A search box renders at the top of the sidebar's "Pages" nav, filtering
186
+ menu items by label as you type — pure client-side DOM filtering, no
187
+ server round trip, no change to how you write `menu do |m| ... end` in
188
+ `app/admin/*.rb`.
189
+
190
+ Matching works at any nesting depth: a submenu item that matches keeps its
191
+ parent group visible and expanded even though the parent's own label
192
+ doesn't match, and a parent whose own label matches reveals its entire
193
+ submenu, expanded. Clearing the box (the "x" button, or <kbd>Escape</kbd>)
194
+ resets everything back to its normal expand/collapse state. No matches
195
+ shows a "No matching menu items" message in place of the nav.
196
+
197
+ Turn it off with `config.menu_search = false`.
198
+
181
199
  ## Toggle switches
182
200
 
183
201
  Boolean fields render as regular (reskinned) checkboxes by default. Opt in
@@ -216,6 +234,35 @@ It's an explicit opt-in per column/row (like everything else in Prism) —
216
234
  ActiveAdmin's default boolean rendering is untouched everywhere you don't
217
235
  call it.
218
236
 
237
+ ## Select2
238
+
239
+ Prism reskins [Select2](https://select2.org) — the jQuery widget that makes
240
+ a `<select>` searchable — and ships it vendored inside its own assets, so
241
+ there's no separate gem/npm dependency to add. Turn it on for every select,
242
+ no per-field setup:
243
+
244
+ ```ruby
245
+ ActiveAdminPrism.configure do |config|
246
+ config.select2 = true # default: false — opt-in, unlike every other flag
247
+ end
248
+ ```
249
+
250
+ ...or leave that off and opt individual fields in yourself instead, same as
251
+ you would in any other Rails app:
252
+
253
+ ```ruby
254
+ filter :subject, input_html: { class: "your-select2-class" }
255
+ # or: f.input :subject, input_html: { class: "your-select2-class" }
256
+ ```
257
+
258
+ ```js
259
+ $(".your-select2-class").select2({ width: "100%" })
260
+ ```
261
+
262
+ See [INTEGRATION.md](INTEGRATION.md#select2) for how the two approaches
263
+ coexist, and why the sidebar Filters panel and a main form need different
264
+ `width` handling under the hood.
265
+
219
266
  ## Sign-in page
220
267
 
221
268
  Every Devise auth page (sign in, sign up, forgot/reset password, resend