pagy 7.0.11 → 8.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/gem/apps/calendar.ru +2196 -0
  3. data/gem/apps/demo.ru +452 -0
  4. data/gem/apps/rails.ru +205 -0
  5. data/gem/apps/repro.ru +168 -0
  6. data/gem/bin/pagy +83 -0
  7. data/{lib → gem}/config/pagy.rb +6 -17
  8. data/{lib → gem}/javascripts/pagy-dev.js +10 -10
  9. data/{lib → gem}/javascripts/pagy-module.js +9 -9
  10. data/gem/javascripts/pagy.js +1 -0
  11. data/gem/lib/optimist.rb +1022 -0
  12. data/gem/lib/pagy/extras/bootstrap.rb +97 -0
  13. data/gem/lib/pagy/extras/bulma.rb +89 -0
  14. data/gem/lib/pagy/extras/foundation.rb +93 -0
  15. data/{lib → gem/lib}/pagy/extras/items.rb +21 -18
  16. data/{lib/pagy/extras/frontend_helpers.rb → gem/lib/pagy/extras/js_tools.rb} +1 -1
  17. data/gem/lib/pagy/extras/materialize.rb +97 -0
  18. data/gem/lib/pagy/extras/pagy.rb +82 -0
  19. data/gem/lib/pagy/extras/semantic.rb +91 -0
  20. data/gem/lib/pagy/extras/trim.rb +29 -0
  21. data/gem/lib/pagy/extras/uikit.rb +96 -0
  22. data/gem/lib/pagy/frontend.rb +97 -0
  23. data/{lib → gem/lib}/pagy/url_helpers.rb +1 -2
  24. data/{lib → gem/lib}/pagy.rb +12 -11
  25. data/{lib → gem}/locales/ar.yml +2 -2
  26. data/{lib → gem}/locales/be.yml +4 -4
  27. data/{lib → gem}/locales/bg.yml +4 -4
  28. data/{lib → gem}/locales/bs.yml +4 -4
  29. data/{lib → gem}/locales/ca.yml +4 -4
  30. data/gem/locales/ckb.yml +18 -0
  31. data/{lib → gem}/locales/cs.yml +4 -4
  32. data/{lib → gem}/locales/da.yml +4 -4
  33. data/{lib → gem}/locales/de.yml +4 -4
  34. data/{lib → gem}/locales/en.yml +4 -4
  35. data/{lib → gem}/locales/es.yml +2 -2
  36. data/{lib → gem}/locales/fr.yml +4 -4
  37. data/{lib → gem}/locales/hr.yml +4 -4
  38. data/{lib → gem}/locales/id.yml +4 -4
  39. data/{lib → gem}/locales/it.yml +4 -4
  40. data/{lib → gem}/locales/ja.yml +4 -4
  41. data/{lib → gem}/locales/km.yml +4 -4
  42. data/{lib → gem}/locales/ko.yml +4 -4
  43. data/{lib → gem}/locales/nb.yml +4 -4
  44. data/{lib → gem}/locales/nl.yml +4 -4
  45. data/{lib → gem}/locales/nn.yml +4 -4
  46. data/{lib → gem}/locales/pl.yml +4 -4
  47. data/{lib → gem}/locales/pt-BR.yml +2 -2
  48. data/{lib → gem}/locales/pt.yml +2 -2
  49. data/{lib → gem}/locales/ru.yml +4 -4
  50. data/{lib → gem}/locales/sr.yml +4 -4
  51. data/{lib → gem}/locales/sv-SE.yml +4 -4
  52. data/{lib → gem}/locales/sv.yml +4 -4
  53. data/{lib → gem}/locales/sw.yml +4 -4
  54. data/{lib → gem}/locales/ta.yml +4 -4
  55. data/{lib → gem}/locales/tr.yml +4 -4
  56. data/{lib → gem}/locales/uk.yml +4 -4
  57. data/{lib → gem}/locales/vi.yml +4 -4
  58. data/{lib → gem}/locales/zh-CN.yml +4 -4
  59. data/{lib → gem}/locales/zh-HK.yml +4 -4
  60. data/{lib → gem}/locales/zh-TW.yml +4 -4
  61. data/{lib → gem}/stylesheets/pagy.css +19 -34
  62. data/{lib → gem}/stylesheets/pagy.scss +17 -19
  63. data/gem/stylesheets/pagy.tailwind.css +21 -0
  64. metadata +103 -90
  65. data/lib/javascripts/pagy.js +0 -1
  66. data/lib/locales/ckb.yml +0 -18
  67. data/lib/pagy/extras/bootstrap.rb +0 -108
  68. data/lib/pagy/extras/bulma.rb +0 -105
  69. data/lib/pagy/extras/foundation.rb +0 -105
  70. data/lib/pagy/extras/materialize.rb +0 -96
  71. data/lib/pagy/extras/navs.rb +0 -51
  72. data/lib/pagy/extras/semantic.rb +0 -95
  73. data/lib/pagy/extras/support.rb +0 -40
  74. data/lib/pagy/extras/trim.rb +0 -29
  75. data/lib/pagy/extras/uikit.rb +0 -97
  76. data/lib/pagy/frontend.rb +0 -114
  77. data/lib/stylesheets/pagy.tailwind.scss +0 -24
  78. /data/{lib → gem}/javascripts/pagy-module.d.ts +0 -0
  79. /data/{lib → gem/lib}/pagy/backend.rb +0 -0
  80. /data/{lib → gem/lib}/pagy/calendar/day.rb +0 -0
  81. /data/{lib → gem/lib}/pagy/calendar/helper.rb +0 -0
  82. /data/{lib → gem/lib}/pagy/calendar/month.rb +0 -0
  83. /data/{lib → gem/lib}/pagy/calendar/quarter.rb +0 -0
  84. /data/{lib → gem/lib}/pagy/calendar/week.rb +0 -0
  85. /data/{lib → gem/lib}/pagy/calendar/year.rb +0 -0
  86. /data/{lib → gem/lib}/pagy/calendar.rb +0 -0
  87. /data/{lib → gem/lib}/pagy/console.rb +0 -0
  88. /data/{lib → gem/lib}/pagy/countless.rb +0 -0
  89. /data/{lib → gem/lib}/pagy/exceptions.rb +0 -0
  90. /data/{lib → gem/lib}/pagy/extras/arel.rb +0 -0
  91. /data/{lib → gem/lib}/pagy/extras/array.rb +0 -0
  92. /data/{lib → gem/lib}/pagy/extras/calendar.rb +0 -0
  93. /data/{lib → gem/lib}/pagy/extras/countless.rb +0 -0
  94. /data/{lib → gem/lib}/pagy/extras/elasticsearch_rails.rb +0 -0
  95. /data/{lib → gem/lib}/pagy/extras/gearbox.rb +0 -0
  96. /data/{lib → gem/lib}/pagy/extras/headers.rb +0 -0
  97. /data/{lib → gem/lib}/pagy/extras/i18n.rb +0 -0
  98. /data/{lib → gem/lib}/pagy/extras/jsonapi.rb +0 -0
  99. /data/{lib → gem/lib}/pagy/extras/meilisearch.rb +0 -0
  100. /data/{lib → gem/lib}/pagy/extras/metadata.rb +0 -0
  101. /data/{lib → gem/lib}/pagy/extras/overflow.rb +0 -0
  102. /data/{lib → gem/lib}/pagy/extras/searchkick.rb +0 -0
  103. /data/{lib → gem/lib}/pagy/extras/standalone.rb +0 -0
  104. /data/{lib → gem/lib}/pagy/i18n.rb +0 -0
@@ -0,0 +1,97 @@
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/bootstrap
2
+ # frozen_string_literal: true
3
+
4
+ require 'pagy/extras/js_tools'
5
+
6
+ class Pagy # :nodoc:
7
+ # Frontend modules are specially optimized for performance.
8
+ # The resulting code may not look very elegant, but produces the best benchmarks
9
+ module BootstrapExtra
10
+ # Pagination for bootstrap: it returns the html with the series of links to the pages
11
+ def pagy_bootstrap_nav(pagy, id: nil, classes: 'pagination', aria_label: nil, **vars)
12
+ id = %( id="#{id}") if id
13
+ a = pagy_anchor(pagy)
14
+
15
+ html = %(<nav#{id} class="pagy-bootstrap nav" #{nav_aria_label(pagy, aria_label:)}><ul class="#{classes}">#{
16
+ bootstrap_prev_html(pagy, a)})
17
+ pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
18
+ html << case item
19
+ when Integer
20
+ %(<li class="page-item">#{a.(item, classes: 'page-link')}</li>)
21
+ when String
22
+ %(<li class="page-item active"><a role="link" class="page-link" aria-current="page" aria-disabled="true">#{
23
+ pagy.label_for(item)}</a></li>)
24
+ when :gap
25
+ %(<li class="page-item gap disabled"><a role="link" class="page-link" aria-disabled="true">#{
26
+ pagy_t('pagy.gap')}</a></li>)
27
+ else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
28
+ end
29
+ end
30
+ html << %(#{bootstrap_next_html(pagy, a)}</ul></nav>)
31
+ end
32
+
33
+ # Javascript pagination for bootstrap: it returns a nav with a data-pagy attribute used by the pagy.js file
34
+ def pagy_bootstrap_nav_js(pagy, id: nil, classes: 'pagination', aria_label: nil, **vars)
35
+ sequels = pagy.sequels(**vars)
36
+ id = %( id="#{id}") if id
37
+ a = pagy_anchor(pagy)
38
+ tokens = { 'before' => %(<ul class="#{classes}">#{bootstrap_prev_html(pagy, a)}),
39
+ 'a' => %(<li class="page-item">#{a.(PAGE_TOKEN, LABEL_TOKEN, classes: 'page-link')}</li>),
40
+ 'current' => %(<li class="page-item active"><a role="link" class="page-link" ) +
41
+ %(aria-current="page" aria-disabled="true">#{LABEL_TOKEN}</a></li>),
42
+ 'gap' => %(<li class="page-item gap disabled"><a role="link" class="page-link" aria-disabled="true">#{
43
+ pagy_t('pagy.gap')}</a></li>),
44
+ 'after' => %(#{bootstrap_next_html pagy, a}</ul>) }
45
+
46
+ %(<nav#{id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-bootstrap nav-js" #{
47
+ nav_aria_label(pagy, aria_label:)} #{
48
+ pagy_data(pagy, :nav, tokens, sequels, pagy.label_sequels(sequels))
49
+ }></nav>)
50
+ end
51
+
52
+ # Javascript combo pagination for bootstrap: it returns a nav with a data-pagy attribute used by the pagy.js file
53
+ def pagy_bootstrap_combo_nav_js(pagy, id: nil, classes: 'pagination', aria_label: nil)
54
+ id = %( id="#{id}") if id
55
+ a = pagy_anchor(pagy)
56
+ pages = pagy.pages
57
+
58
+ page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page" ) <<
59
+ %(style="text-align: center; width: #{pages.to_s.length + 1}rem; padding: 0; ) <<
60
+ %(border: none; display: inline-block;" class="page-link active">)
61
+
62
+ %(<nav#{id} class="pagy-bootstrap combo-nav-js" #{
63
+ nav_aria_label(pagy, aria_label:)} #{
64
+ pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
65
+ }><ul class="#{classes}">#{
66
+ bootstrap_prev_html(pagy, a)
67
+ }<li class="page-item pagy-bootstrap"><label class="page-link">#{
68
+ pagy_t('pagy.combo_nav_js', page_input:, pages:)
69
+ }</label></li>#{
70
+ bootstrap_next_html(pagy, a)
71
+ }</ul></nav>)
72
+ end
73
+
74
+ private
75
+
76
+ def bootstrap_prev_html(pagy, a)
77
+ if (p_prev = pagy.prev)
78
+ %(<li class="page-item prev">#{
79
+ a.(p_prev, pagy_t('pagy.prev'), classes: 'page-link', aria_label: pagy_t('pagy.aria_label.prev'))}</li>)
80
+ else
81
+ %(<li class="page-item prev disabled"><a role="link" class="page-link" aria-disabled="true" aria-label="#{
82
+ pagy_t('pagy.aria_label.prev')}">#{pagy_t('pagy.prev')}</a></li>)
83
+ end
84
+ end
85
+
86
+ def bootstrap_next_html(pagy, a)
87
+ if (p_next = pagy.next)
88
+ %(<li class="page-item next">#{
89
+ a.(p_next, pagy_t('pagy.next'), classes: 'page-link', aria_label: pagy_t('pagy.aria_label.next'))}</li>)
90
+ else
91
+ %(<li class="page-item next disabled"><a role="link" class="page-link" aria-disabled="true" aria-label="#{
92
+ pagy_t('pagy.aria_label.next')}">#{pagy_t('pagy.next')}</a></li>)
93
+ end
94
+ end
95
+ end
96
+ Frontend.prepend BootstrapExtra
97
+ end
@@ -0,0 +1,89 @@
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/bulma
2
+ # frozen_string_literal: true
3
+
4
+ require 'pagy/extras/js_tools'
5
+
6
+ class Pagy # :nodoc:
7
+ # Frontend modules are specially optimized for performance.
8
+ # The resulting code may not look very elegant, but produces the best benchmarks
9
+ module BulmaExtra
10
+ # Pagination for bulma: it returns the html with the series of links to the pages
11
+ def pagy_bulma_nav(pagy, id: nil, classes: 'pagy-bulma nav pagination is-centered', aria_label: nil, **vars)
12
+ id = %( id="#{id}") if id
13
+ a = pagy_anchor(pagy)
14
+
15
+ html = %(<nav#{id} class="#{classes}" #{nav_aria_label(pagy, aria_label:)}>)
16
+ html << bulma_prev_next_html(pagy, a)
17
+ html << %(<ul class="pagination-list">)
18
+ pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
19
+ html << case item
20
+ when Integer
21
+ %(<li>#{a.(item, pagy.label_for(item), classes: 'pagination-link')}</li>)
22
+ when String
23
+ %(<li><a role="link" class="pagination-link is-current" aria-current="page" aria-disabled="true">#{
24
+ pagy.label_for(item)}</a></li>)
25
+ when :gap
26
+ %(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.gap'}</span></li>)
27
+ else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
28
+ end
29
+ end
30
+ html << %(</ul></nav>)
31
+ end
32
+
33
+ # Javascript pagination for bulma: it returns a nav with a data-pagy attribute used by the Pagy.nav javascript
34
+ def pagy_bulma_nav_js(pagy, id: nil, classes: 'pagy-bulma nav-js pagination is-centered', aria_label: nil, **vars)
35
+ sequels = pagy.sequels(**vars)
36
+ id = %( id="#{id}") if id
37
+ a = pagy_anchor(pagy)
38
+ tokens = { 'before' => %(#{bulma_prev_next_html(pagy, a)}<ul class="pagination-list">),
39
+ 'a' => %(<li>#{a.(PAGE_TOKEN, LABEL_TOKEN, classes: 'pagination-link')}</li>),
40
+ 'current' => %(<li><a role="link" class="pagination-link is-current" aria-current="page" aria-disabled="true">#{
41
+ LABEL_TOKEN}</a></li>),
42
+ 'gap' => %(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.gap'}</span></li>),
43
+ 'after' => '</ul>' }
44
+
45
+ %(<nav#{id} class="#{'pagy-rjs ' if sequels.size > 1}#{classes}" #{
46
+ nav_aria_label(pagy, aria_label:)} #{
47
+ pagy_data(pagy, :nav, tokens, sequels, pagy.label_sequels(sequels))
48
+ }></nav>)
49
+ end
50
+
51
+ # Javascript combo pagination for bulma: it returns a nav with a data-pagy attribute used by the pagy.js file
52
+ def pagy_bulma_combo_nav_js(pagy, id: nil, classes: 'pagy-bulma combo-nav-js pagination is-centered', aria_label: nil)
53
+ id = %( id="#{id}") if id
54
+ a = pagy_anchor(pagy)
55
+ pages = pagy.pages
56
+
57
+ page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page") <<
58
+ %(style="text-align: center; width: #{pages.to_s.length + 1}rem; height: 1.7rem; margin:0 0.3rem; ) <<
59
+ %(border: none; border-radius: 4px; padding: 0; font-size: 1.1rem; color: white; background-color: #485fc7;">)
60
+
61
+ %(<nav#{id} class="#{classes}" #{
62
+ nav_aria_label(pagy, aria_label:)} #{
63
+ pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
64
+ }>#{
65
+ bulma_prev_next_html(pagy, a)
66
+ }<ul class="pagination-list"><li class="pagination-link"><label>#{
67
+ pagy_t('pagy.combo_nav_js', page_input:, pages:)
68
+ }</label></li></ul></nav>)
69
+ end
70
+
71
+ private
72
+
73
+ def bulma_prev_next_html(pagy, a)
74
+ html = if (p_prev = pagy.prev)
75
+ a.(p_prev, pagy_t('pagy.prev'), classes: 'pagination-previous', aria_label: pagy_t('pagy.aria_label.prev'))
76
+ else
77
+ %(<a role="link" class="pagination-previous" disabled aria-disabled="true" aria-label="#{
78
+ pagy_t('pagy.aria_label.prev')}">#{pagy_t 'pagy.prev'}</a>)
79
+ end
80
+ html << if (p_next = pagy.next)
81
+ a.(p_next, pagy_t('pagy.next'), classes: 'pagination-next', aria_label: pagy_t('pagy.aria_label.next'))
82
+ else
83
+ %(<a role="link" class="pagination-next" disabled aria-disabled="true" aria-label="#{
84
+ pagy_t('pagy.aria_label.next')}">#{pagy_t('pagy.next')}</a>)
85
+ end
86
+ end
87
+ end
88
+ Frontend.prepend BulmaExtra
89
+ end
@@ -0,0 +1,93 @@
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/foundation
2
+ # frozen_string_literal: true
3
+
4
+ require 'pagy/extras/js_tools'
5
+
6
+ class Pagy # :nodoc:
7
+ # Frontend modules are specially optimized for performance.
8
+ # The resulting code may not look very elegant, but produces the best benchmarks
9
+ module FoundationExtra
10
+ # Pagination for Foundation: it returns the html with the series of links to the pages
11
+ def pagy_foundation_nav(pagy, id: nil, aria_label: nil, **vars)
12
+ id = %( id="#{id}") if id
13
+ a = pagy_anchor(pagy)
14
+
15
+ html = +%(<nav#{id} class="pagy-foundation-nav" #{
16
+ nav_aria_label(pagy, aria_label:)}><ul class="pagination"> #{
17
+ foundation_prev_html(pagy, a)})
18
+ pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
19
+ html << case item
20
+ when Integer
21
+ %(<li>#{a.(item)}</li>)
22
+ when String
23
+ %(<li class="current" role="link" aria-current="page" aria-disabled="true">#{pagy.label_for(item)}</li>)
24
+ when :gap
25
+ %(<li class="ellipsis gap"></li>)
26
+ else
27
+ raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
28
+ end
29
+ end
30
+ html << %(#{foundation_next_html(pagy, a)}</ul></nav>)
31
+ end
32
+
33
+ # Javascript pagination for foundation: it returns a nav with a data-pagy attribute used by the pagy.js file
34
+ def pagy_foundation_nav_js(pagy, id: nil, aria_label: nil, **vars)
35
+ sequels = pagy.sequels(**vars)
36
+ id = %( id="#{id}") if id
37
+ a = pagy_anchor(pagy)
38
+ tokens = { 'before' => %(<ul class="pagination">#{foundation_prev_html pagy, a}),
39
+ 'a' => %(<li>#{a.(PAGE_TOKEN, LABEL_TOKEN)}</li>),
40
+ 'current' => %(<li class="current" role="link" aria-current="page" aria-disabled="true">#{LABEL_TOKEN}</li>),
41
+ 'gap' => %(<li class="ellipsis gap"></li>),
42
+ 'after' => %(#{foundation_next_html pagy, a}</ul>) }
43
+
44
+ %(<nav#{id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-foundation-nav-js" #{
45
+ nav_aria_label(pagy, aria_label:)} #{
46
+ pagy_data(pagy, :nav, tokens, sequels, pagy.label_sequels(sequels))
47
+ }></nav>)
48
+ end
49
+
50
+ # Javascript combo pagination for Foundation: it returns a nav with a data-pagy attribute used by the pagy.js file
51
+ def pagy_foundation_combo_nav_js(pagy, id: nil, aria_label: nil)
52
+ id = %( id="#{id}") if id
53
+ a = pagy_anchor(pagy)
54
+ pages = pagy.pages
55
+
56
+ page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page" ) <<
57
+ %(style="text-align: center; width: #{pages.to_s.length + 1}rem; ) <<
58
+ %(height: 1.5rem; padding: .5rem; margin: 0 .4rem; font-size: .875rem;" class="current">)
59
+
60
+ %(<nav#{id} class="pagy-foundation-combo-nav-js" #{
61
+ nav_aria_label(pagy, aria_label:)} #{
62
+ pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
63
+ }><ul class="pagination">#{
64
+ foundation_prev_html(pagy, a)
65
+ }<li style="padding: 0 .3rem"><label style="display: flex; align-items: center; white-space: nowrap">#{
66
+ pagy_t('pagy.combo_nav_js', page_input:, pages:)
67
+ }</label></li>#{
68
+ foundation_next_html(pagy, a)
69
+ }</ul></nav>)
70
+ end
71
+
72
+ private
73
+
74
+ def foundation_prev_html(pagy, a)
75
+ if (p_prev = pagy.prev)
76
+ %(<li class="prev">#{a.(p_prev, pagy_t('pagy.prev'), aria_label: pagy_t('pagy.aria_label.prev'))}</li>)
77
+ else
78
+ %(<li class="prev disabled" role="link" aria-disabled="true" #{
79
+ pagy_t('pagy.aria_label.prev')}>#{pagy_t('pagy.prev')}</li>)
80
+ end
81
+ end
82
+
83
+ def foundation_next_html(pagy, a)
84
+ if (p_next = pagy.next)
85
+ %(<li class="next">#{a.(p_next, pagy_t('pagy.next'), aria_label: pagy_t('pagy.aria_label.next'))}</li>)
86
+ else
87
+ %(<li class="next disabled" role="link" aria-disabled="true" #{
88
+ pagy_t('pagy.aria_label.next')}>#{pagy_t('pagy.next')}</li>)
89
+ end
90
+ end
91
+ end
92
+ Frontend.prepend FoundationExtra
93
+ end
@@ -1,7 +1,7 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/items
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'pagy/extras/frontend_helpers'
4
+ require 'pagy/extras/js_tools'
5
5
 
6
6
  class Pagy # :nodoc:
7
7
  DEFAULT[:items_param] = :items
@@ -33,27 +33,30 @@ class Pagy # :nodoc:
33
33
 
34
34
  # Additions for the Frontend module
35
35
  module FrontendAddOn
36
- ITEMS_PLACEHOLDER = '__pagy_items__'
36
+ ITEMS_TOKEN = '__pagy_items__'
37
37
 
38
38
  # Return the items selector HTML. For example "Show [20] items per page"
39
- def pagy_items_selector_js(pagy, pagy_id: nil, item_name: nil, item_i18n_key: nil)
39
+ def pagy_items_selector_js(pagy, id: nil, item_name: nil)
40
40
  return '' unless pagy.vars[:items_extra]
41
41
 
42
- p_id = %( id="#{pagy_id}") if pagy_id
43
- p_vars = pagy.vars
44
- p_items = p_vars[:items]
45
- p_vars[:items] = ITEMS_PLACEHOLDER
46
- url_token = pagy_url_for(pagy, PAGE_TOKEN)
47
- p_vars[:items] = p_items # restore the items
48
-
49
- html = +%(<span#{p_id} class="pagy pagy-items-selector-js" #{pagy_data(pagy, :selector, pagy.from, url_token)}>)
50
- input = %(<input name="items" type="number" min="1" max="#{p_vars[:max_items]}" value="#{
51
- p_items}" style="padding: 0; text-align: center; width: #{p_items.to_s.length + 1}rem;">)
52
- html << pagy_t('pagy.items_selector_js',
53
- item_name: item_name || pagy_t(item_i18n_key || p_vars[:item_i18n_key], count: p_items),
54
- items_input: input,
55
- count: p_items)
56
- html << %(</span>)
42
+ id = %( id="#{id}") if id
43
+ vars = pagy.vars
44
+ items = vars[:items]
45
+ vars[:items] = ITEMS_TOKEN
46
+ url_token = pagy_url_for(pagy, PAGE_TOKEN)
47
+ vars[:items] = items # restore the items
48
+
49
+ items_input = %(<input name="items" type="number" min="1" max="#{vars[:max_items]}" value="#{
50
+ items}" style="padding: 0; text-align: center; width: #{items.to_s.length + 1}rem;">)
51
+
52
+ %(<span#{id} class="pagy items-selector-js" #{
53
+ pagy_data(pagy, :selector, pagy.from, url_token)
54
+ }><label>#{
55
+ pagy_t('pagy.items_selector_js',
56
+ item_name: item_name || pagy_t('pagy.item_name', count: items),
57
+ items_input:,
58
+ count: items)
59
+ }</label></span>)
57
60
  end
58
61
  end
59
62
  Frontend.prepend ItemsExtra::FrontendAddOn
@@ -4,7 +4,7 @@ class Pagy # :nodoc:
4
4
  DEFAULT[:steps] = false # default false will use {0 => @vars[:size]}
5
5
 
6
6
  # Private module documented in the main classes
7
- module FrontendHelpers
7
+ module JSTools
8
8
  # Additions for the Pagy class
9
9
  module PagyAddOn
10
10
  # `Pagy` instance method used by the `pagy*_nav_js` helpers.
@@ -0,0 +1,97 @@
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/materialize
2
+ # frozen_string_literal: true
3
+
4
+ require 'pagy/extras/js_tools'
5
+
6
+ class Pagy # :nodoc:
7
+ # Frontend modules are specially optimized for performance.
8
+ # The resulting code may not look very elegant, but produces the best benchmarks
9
+ module MaterializeExtra
10
+ # Pagination for materialize: it returns the html with the series of links to the pages
11
+ def pagy_materialize_nav(pagy, id: nil, aria_label: nil, **vars)
12
+ id = %( id="#{id}") if id
13
+ a = pagy_anchor(pagy)
14
+
15
+ html = +%(<div#{id} class="pagy-materialize nav pagination" role="navigation" #{
16
+ nav_aria_label(pagy, aria_label:)}><ul class="pagination">#{
17
+ materialize_prev_html(pagy, a)})
18
+ pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
19
+ html << case item
20
+ when Integer
21
+ %(<li class="waves-effect">#{a.(item)}</li>)
22
+ when String
23
+ %(<li class="active"><a role="link" aria-current="page" aria-disabled="true">#{pagy.label_for(item)}</a></li>)
24
+ when :gap
25
+ %(<li class="gap disabled"><a role="link" aria-disabled="true">#{pagy_t 'pagy.gap'}</a></li>)
26
+ else
27
+ raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
28
+ end
29
+ end
30
+ html << %(#{materialize_next_html(pagy, a)}</ul></div>)
31
+ end
32
+
33
+ # Javascript pagination for materialize: it returns a nav with a data-pagy attribute used by the pagy.js file
34
+ def pagy_materialize_nav_js(pagy, id: nil, aria_label: nil, **vars)
35
+ sequels = pagy.sequels(**vars)
36
+ id = %( id="#{id}") if id
37
+ a = pagy_anchor(pagy)
38
+
39
+ tokens = { 'before' => %(<ul class="pagination">#{materialize_prev_html pagy, a}),
40
+ 'a' => %(<li class="waves-effect">#{a.(PAGE_TOKEN, LABEL_TOKEN)}</li>),
41
+ 'current' => %(<li class="active"><a role="link" aria-current="page" aria-disabled="true">#{
42
+ LABEL_TOKEN}</a></li>),
43
+ 'gap' => %(<li class="gap disabled"><a role="link" aria-disabled="true">#{pagy_t 'pagy.gap'}</a></li>),
44
+ 'after' => %(#{materialize_next_html pagy, a}</ul>) }
45
+
46
+ %(<div#{id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-materialize nav-js" role="navigation" #{
47
+ nav_aria_label(pagy, aria_label:)} #{
48
+ pagy_data(pagy, :nav, tokens, sequels, pagy.label_sequels(sequels))
49
+ }></div>)
50
+ end
51
+
52
+ # Javascript combo pagination for materialize: it returns a nav with a data-pagy attribute used by the pagy.js file
53
+ def pagy_materialize_combo_nav_js(pagy, id: nil, aria_label: nil)
54
+ id = %( id="#{id}") if id
55
+ a = pagy_anchor(pagy)
56
+ pages = pagy.pages
57
+
58
+ page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page" ) <<
59
+ %(style="text-align: center; width: #{pages.to_s.length + 1}rem; height: 1.5rem; font-size: 1.2rem; ) <<
60
+ %(border: none; border-radius: 2px; color: white; background-color: #ee6e73;" class="browser-default">)
61
+
62
+ %(<ul#{id} class="pagy-materialize combo-nav-js pagination" role="navigation" style="padding-right: 0;" #{
63
+ nav_aria_label(pagy, aria_label:)} #{
64
+ pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
65
+ }>#{
66
+ materialize_prev_html(pagy, a)
67
+ }<li style="vertical-align: -webkit-baseline-middle;"><label style="font-size: 1.2rem;">#{
68
+ pagy_t('pagy.combo_nav_js', page_input:, pages:)
69
+ }</label></li>#{
70
+ materialize_next_html(pagy, a)
71
+ }</ul>)
72
+ end
73
+
74
+ private
75
+
76
+ def materialize_prev_html(pagy, a)
77
+ if (p_prev = pagy.prev)
78
+ %(<li class="waves-effect prev">#{
79
+ a.(p_prev, '<i class="material-icons">chevron_left</i>', aria_label: pagy_t('pagy.aria_label.prev'))}</li>)
80
+ else
81
+ %(<li class="prev disabled"><a role="link" aria-disabled="true" aria-label="#{
82
+ pagy_t('pagy.aria_label.prev')}"><i class="material-icons">chevron_left</i></a></li>)
83
+ end
84
+ end
85
+
86
+ def materialize_next_html(pagy, a)
87
+ if (p_next = pagy.next)
88
+ %(<li class="waves-effect next">#{
89
+ a.(p_next, '<i class="material-icons">chevron_right</i>', aria_label: pagy_t('pagy.aria_label.next'))}</li>)
90
+ else
91
+ %(<li class="next disabled"#><a role="link" aria-disabled="true" aria-label="#{
92
+ pagy_t('pagy.aria_label.next')}><i class="material-icons">chevron_right</i></a></li>)
93
+ end
94
+ end
95
+ end
96
+ Frontend.prepend MaterializeExtra
97
+ end
@@ -0,0 +1,82 @@
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/pagy
2
+ # frozen_string_literal: true
3
+
4
+ require 'pagy/extras/js_tools'
5
+
6
+ class Pagy # :nodoc:
7
+ # Frontend modules are specially optimized for performance.
8
+ # The resulting code may not look very elegant, but produces the best benchmarks
9
+ module PagyExtra
10
+ # pagy_nav is defined in the Frontend itself
11
+ # Javascript pagination: it returns a nav with a data-pagy attribute used by the pagy.js file
12
+ def pagy_nav_js(pagy, id: nil, aria_label: nil, **vars)
13
+ sequels = pagy.sequels(**vars)
14
+ id = %( id="#{id}") if id
15
+ a = pagy_anchor(pagy)
16
+ tokens = { 'before' => prev_a(pagy, a),
17
+ 'a' => a.(PAGE_TOKEN, LABEL_TOKEN),
18
+ 'current' => %(<a class="current" role="link" aria-current="page" aria-disabled="true">#{
19
+ LABEL_TOKEN}</a>),
20
+ 'gap' => %(<a class="gap" role="link" aria-disabled="true">#{pagy_t('pagy.gap')}</a>),
21
+ 'after' => next_a(pagy, a) }
22
+
23
+ %(<nav#{id} class="#{'pagy-rjs ' if sequels.size > 1}pagy nav-js" #{
24
+ nav_aria_label(pagy, aria_label:)} #{
25
+ pagy_data(pagy, :nav, tokens, sequels, pagy.label_sequels(sequels))
26
+ }></nav>)
27
+ end
28
+
29
+ # Javascript combo pagination: it returns a nav with a data-pagy attribute used by the pagy.js file
30
+ def pagy_combo_nav_js(pagy, id: nil, aria_label: nil)
31
+ id = %( id="#{id}") if id
32
+ a = pagy_anchor(pagy)
33
+ pages = pagy.pages
34
+
35
+ page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page" ) <<
36
+ %(style="text-align: center; width: #{pages.to_s.length + 1}rem; padding: 0;">)
37
+
38
+ %(<nav#{id} class="pagy combo-nav-js" #{
39
+ nav_aria_label(pagy, aria_label:)} #{
40
+ pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))}>#{
41
+ prev_a(pagy, a)
42
+ }<label>#{
43
+ pagy_t('pagy.combo_nav_js', page_input:, pages:)
44
+ }</label>#{
45
+ next_a(pagy, a)
46
+ }</nav>)
47
+ end
48
+
49
+ # Return the previous page URL string or nil
50
+ def pagy_prev_url(pagy, absolute: false)
51
+ pagy_url_for(pagy, pagy.prev, absolute:) if pagy.prev
52
+ end
53
+
54
+ # Return the next page URL string or nil
55
+ def pagy_next_url(pagy, absolute: false)
56
+ pagy_url_for(pagy, pagy.next, absolute:) if pagy.next
57
+ end
58
+
59
+ # Return the enabled/disabled previous page anchor tag
60
+ def pagy_prev_a(pagy, text: pagy_t('pagy.prev'), aria_label: pagy_t('pagy.aria_label.prev'))
61
+ a = pagy_anchor(pagy)
62
+ prev_a(pagy, a, text:, aria_label:)
63
+ end
64
+
65
+ # Return the enabled/disabled next page anchor tag
66
+ def pagy_next_a(pagy, text: pagy_t('pagy.next'), aria_label: pagy_t('pagy.aria_label.prev'))
67
+ a = pagy_anchor(pagy)
68
+ next_a(pagy, a, text:, aria_label:)
69
+ end
70
+
71
+ # Conditionally return the previous page link tag
72
+ def pagy_prev_link(pagy, absolute: false)
73
+ %(<link href="#{pagy_url_for(pagy, pagy.prev, absolute:)}"/>) if pagy.prev
74
+ end
75
+
76
+ # Conditionally return the next page link tag
77
+ def pagy_next_link(pagy, absolute: false)
78
+ %(<link href="#{pagy_url_for(pagy, pagy.next, absolute:)}"/>) if pagy.next
79
+ end
80
+ end
81
+ Frontend.prepend PagyExtra
82
+ end
@@ -0,0 +1,91 @@
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/semantic
2
+ # frozen_string_literal: true
3
+
4
+ require 'pagy/extras/js_tools'
5
+
6
+ class Pagy # :nodoc:
7
+ # Frontend modules are specially optimized for performance.
8
+ # The resulting code may not look very elegant, but produces the best benchmarks
9
+ module SemanticExtra
10
+ # Pagination for semantic: it returns the html with the series of links to the pages
11
+ def pagy_semantic_nav(pagy, id: nil, aria_label: nil, **vars)
12
+ id = %( id="#{id}") if id
13
+ a = pagy_anchor(pagy)
14
+
15
+ html = %(<div#{id} role="navigation" class="pagy-semantic nav ui pagination menu" #{
16
+ nav_aria_label(pagy, aria_label:)}>#{semantic_prev_html(pagy, a)})
17
+ pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
18
+ html << case item
19
+ when Integer
20
+ a.(item, pagy.label_for(item), classes: 'item')
21
+ when String
22
+ %(<a role="link" class="item active" aria-current="page" aria-disabled="true">#{pagy.label_for(item)}</a>)
23
+ when :gap
24
+ %(<div class="disabled item">#{pagy_t 'pagy.gap'}</div>)
25
+ else
26
+ raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
27
+ end
28
+ end
29
+ html << %(#{semantic_next_html(pagy, a)}</div>)
30
+ end
31
+
32
+ # Javascript pagination for semantic: it returns a nav with a data-pagy attribute used by the pagy.js file
33
+ def pagy_semantic_nav_js(pagy, id: nil, aria_label: nil, **vars)
34
+ sequels = pagy.sequels(**vars)
35
+ id = %( id="#{id}") if id
36
+ a = pagy_anchor(pagy)
37
+ tokens = { 'before' => semantic_prev_html(pagy, a),
38
+ 'a' => a.(PAGE_TOKEN, LABEL_TOKEN, classes: 'item'),
39
+ 'current' => %(<a role="link" class="item active" aria-current="page" aria-disabled="true">#{LABEL_TOKEN}</a>),
40
+ 'gap' => %(<div class="disabled item">#{pagy_t('pagy.gap')}</div>),
41
+ 'after' => semantic_next_html(pagy, a) }
42
+
43
+ %(<div#{id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-semantic nav-js ui pagination menu" role="navigation" #{
44
+ nav_aria_label(pagy, aria_label:)} #{
45
+ pagy_data(pagy, :nav, tokens, sequels, pagy.label_sequels(sequels))
46
+ }></div>)
47
+ end
48
+
49
+ # Combo pagination for semantic: it returns a nav with a data-pagy attribute used by the pagy.js file
50
+ def pagy_semantic_combo_nav_js(pagy, id: nil, aria_label: nil)
51
+ id = %( id="#{id}") if id
52
+ a = pagy_anchor(pagy)
53
+ pages = pagy.pages
54
+
55
+ page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page") <<
56
+ %(style="text-align: center; width: #{pages.to_s.length + 1}rem; padding: 0; margin: 0 0.3rem">)
57
+
58
+ %(<div#{id} class="pagy-semantic combo-nav-js ui compact menu" role="navigation" #{
59
+ nav_aria_label(pagy, aria_label:)} #{
60
+ pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
61
+ }>#{
62
+ semantic_prev_html(pagy, a)
63
+ }<div class="item"><label>#{
64
+ pagy_t('pagy.combo_nav_js', page_input:, pages:)
65
+ }</label></div> #{
66
+ semantic_next_html(pagy, a)
67
+ }</div>)
68
+ end
69
+
70
+ private
71
+
72
+ def semantic_prev_html(pagy, a)
73
+ if (p_prev = pagy.prev)
74
+ a.(p_prev, pagy_t('pagy.prev'), classes: 'item', aria_label: pagy_t('pagy.aria_label.prev'))
75
+ else
76
+ %(<div class="item disabled" role="a" aria-disabled="true" aria-label="#{
77
+ pagy_t('pagy.aria_label.prev')}">#{pagy_t('pagy.prev')}</div>)
78
+ end
79
+ end
80
+
81
+ def semantic_next_html(pagy, a)
82
+ if (p_next = pagy.next)
83
+ a.(p_next, pagy_t('pagy.next'), classes: 'item', aria_label: pagy_t('pagy.aria_label.next'))
84
+ else
85
+ %(<div class="item disabled" role="link" aria-disabled="true" aria=label="#{
86
+ pagy_t('pagy.aria_label.prev')}">#{pagy_t('pagy.next')}</div>)
87
+ end
88
+ end
89
+ end
90
+ Frontend.prepend SemanticExtra
91
+ end
@@ -0,0 +1,29 @@
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/trim
2
+ # frozen_string_literal: true
3
+
4
+ class Pagy # :nodoc:
5
+ DEFAULT[:trim_extra] = true # extra enabled by default
6
+
7
+ # Remove the page=1 param from the first page link
8
+ module TrimExtra
9
+ # Override the original pagy_a_proc.
10
+ # Call the pagy_trim method for page 1 if the trim_extra is enabled
11
+ def pagy_anchor(pagy)
12
+ a_proc = super(pagy)
13
+ return a_proc unless pagy.vars[:trim_extra]
14
+
15
+ lambda do |page, text = pagy.label_for(page), **opts|
16
+ a = +a_proc.(page, text, **opts)
17
+ return a unless page.to_s == '1'
18
+
19
+ pagy_trim(pagy, a) # in method for isolated testing
20
+ end
21
+ end
22
+
23
+ # Remove the the :page_param param from the first page anchor
24
+ def pagy_trim(pagy, a)
25
+ a.sub!(/[?&]#{pagy.vars[:page_param]}=1\b(?!&)|\b#{pagy.vars[:page_param]}=1&/, '')
26
+ end
27
+ end
28
+ Frontend.prepend TrimExtra
29
+ end