pagy 6.0.0 → 7.0.0

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.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/lib/config/pagy.rb +56 -44
  4. data/lib/javascripts/pagy-dev.js +3 -3
  5. data/lib/javascripts/pagy-module.js +2 -2
  6. data/lib/javascripts/pagy.js +1 -1
  7. data/lib/locales/ar.yml +15 -11
  8. data/lib/locales/be.yml +25 -0
  9. data/lib/locales/bg.yml +10 -11
  10. data/lib/locales/bs.yml +12 -11
  11. data/lib/locales/ca.yml +12 -11
  12. data/lib/locales/cs.yml +13 -10
  13. data/lib/locales/da.yml +14 -13
  14. data/lib/locales/de.yml +10 -11
  15. data/lib/locales/en.yml +10 -11
  16. data/lib/locales/es.yml +10 -11
  17. data/lib/locales/fr.yml +10 -11
  18. data/lib/locales/hr.yml +12 -11
  19. data/lib/locales/id.yml +10 -11
  20. data/lib/locales/it.yml +10 -11
  21. data/lib/locales/ja.yml +10 -11
  22. data/lib/locales/km.yml +10 -10
  23. data/lib/locales/ko.yml +10 -11
  24. data/lib/locales/nb.yml +10 -11
  25. data/lib/locales/nl.yml +10 -11
  26. data/lib/locales/nn.yml +10 -11
  27. data/lib/locales/pl.yml +12 -11
  28. data/lib/locales/pt-BR.yml +10 -11
  29. data/lib/locales/pt.yml +10 -11
  30. data/lib/locales/ru.yml +14 -11
  31. data/lib/locales/sr.yml +12 -10
  32. data/lib/locales/sv-SE.yml +10 -12
  33. data/lib/locales/sv.yml +10 -12
  34. data/lib/locales/sw.yml +12 -11
  35. data/lib/locales/ta.yml +12 -11
  36. data/lib/locales/tr.yml +10 -11
  37. data/lib/locales/uk.yml +12 -11
  38. data/lib/locales/vi.yml +17 -0
  39. data/lib/locales/zh-CN.yml +10 -11
  40. data/lib/locales/zh-HK.yml +10 -11
  41. data/lib/locales/zh-TW.yml +10 -11
  42. data/lib/pagy/backend.rb +10 -4
  43. data/lib/pagy/calendar/day.rb +4 -3
  44. data/lib/pagy/calendar/helper.rb +15 -11
  45. data/lib/pagy/calendar/month.rb +4 -3
  46. data/lib/pagy/calendar/quarter.rb +4 -3
  47. data/lib/pagy/calendar/week.rb +1 -1
  48. data/lib/pagy/calendar/year.rb +3 -2
  49. data/lib/pagy/calendar.rb +33 -7
  50. data/lib/pagy/console.rb +1 -1
  51. data/lib/pagy/countless.rb +1 -1
  52. data/lib/pagy/exceptions.rb +1 -1
  53. data/lib/pagy/extras/arel.rb +1 -1
  54. data/lib/pagy/extras/array.rb +1 -1
  55. data/lib/pagy/extras/bootstrap.rb +45 -32
  56. data/lib/pagy/extras/bulma.rb +41 -32
  57. data/lib/pagy/extras/calendar.rb +17 -13
  58. data/lib/pagy/extras/countless.rb +1 -1
  59. data/lib/pagy/extras/elasticsearch_rails.rb +8 -8
  60. data/lib/pagy/extras/foundation.rb +48 -33
  61. data/lib/pagy/extras/frontend_helpers.rb +11 -11
  62. data/lib/pagy/extras/gearbox.rb +1 -1
  63. data/lib/pagy/extras/headers.rb +8 -8
  64. data/lib/pagy/extras/i18n.rb +5 -5
  65. data/lib/pagy/extras/items.rb +19 -12
  66. data/lib/pagy/extras/jsonapi.rb +79 -0
  67. data/lib/pagy/extras/materialize.rb +42 -30
  68. data/lib/pagy/extras/meilisearch.rb +12 -11
  69. data/lib/pagy/extras/metadata.rb +2 -2
  70. data/lib/pagy/extras/navs.rb +22 -34
  71. data/lib/pagy/extras/overflow.rb +9 -7
  72. data/lib/pagy/extras/searchkick.rb +8 -8
  73. data/lib/pagy/extras/semantic.rb +41 -28
  74. data/lib/pagy/extras/standalone.rb +10 -16
  75. data/lib/pagy/extras/support.rb +19 -33
  76. data/lib/pagy/extras/trim.rb +4 -4
  77. data/lib/pagy/extras/uikit.rb +44 -31
  78. data/lib/pagy/frontend.rb +57 -26
  79. data/lib/pagy/i18n.rb +3 -3
  80. data/lib/pagy/url_helpers.rb +15 -12
  81. data/lib/pagy.rb +57 -41
  82. metadata +7 -19
  83. data/lib/templates/bootstrap_nav.html.erb +0 -24
  84. data/lib/templates/bootstrap_nav.html.haml +0 -34
  85. data/lib/templates/bootstrap_nav.html.slim +0 -34
  86. data/lib/templates/bulma_nav.html.erb +0 -24
  87. data/lib/templates/bulma_nav.html.haml +0 -32
  88. data/lib/templates/bulma_nav.html.slim +0 -32
  89. data/lib/templates/foundation_nav.html.erb +0 -24
  90. data/lib/templates/foundation_nav.html.haml +0 -34
  91. data/lib/templates/foundation_nav.html.slim +0 -34
  92. data/lib/templates/nav.html.erb +0 -22
  93. data/lib/templates/nav.html.haml +0 -30
  94. data/lib/templates/nav.html.slim +0 -29
  95. data/lib/templates/uikit_nav.html.erb +0 -15
  96. data/lib/templates/uikit_nav.html.haml +0 -28
  97. data/lib/templates/uikit_nav.html.slim +0 -28
@@ -1,4 +1,4 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/bootstrap
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/bootstrap
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'pagy/extras/frontend_helpers'
@@ -8,84 +8,97 @@ class Pagy # :nodoc:
8
8
  # The resulting code may not look very elegant, but produces the best benchmarks
9
9
  module BootstrapExtra
10
10
  # Pagination for bootstrap: it returns the html with the series of links to the pages
11
- def pagy_bootstrap_nav(pagy, pagy_id: nil, link_extra: '', **vars)
11
+ def pagy_bootstrap_nav(pagy, pagy_id: nil, link_extra: '',
12
+ nav_aria_label: nil, nav_i18n_key: nil, **vars)
12
13
  p_id = %( id="#{pagy_id}") if pagy_id
13
14
  link = pagy_link_proc(pagy, link_extra: %(class="page-link" #{link_extra}))
14
15
 
15
- html = +%(<nav#{p_id} class="pagy-bootstrap-nav"><ul class="pagination">)
16
- html << pagy_bootstrap_prev_html(pagy, link)
16
+ html = +%(<nav#{p_id} class="pagy-bootstrap-nav" #{
17
+ nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)}><ul class="pagination">)
18
+ html << bootstrap_prev_html(pagy, link)
17
19
  pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
18
20
  html << case item
19
21
  when Integer
20
- %(<li class="page-item">#{link.call item}</li>)
22
+ %(<li class="page-item">#{link.call(item)}</li>)
21
23
  when String
22
- %(<li class="page-item active">#{link.call item}</li>)
24
+ %(<li class="page-item active">#{link.call(item)}</li>)
23
25
  when :gap
24
- %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>)
26
+ %(<li class="page-item gap disabled"><a href="#" class="page-link" aria-disabled="true">#{
27
+ pagy_t 'pagy.gap'}</a></li>)
25
28
  else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
26
29
  end
27
30
  end
28
- html << pagy_bootstrap_next_html(pagy, link)
31
+ html << bootstrap_next_html(pagy, link)
29
32
  html << %(</ul></nav>)
30
33
  end
31
34
 
32
35
  # Javascript pagination for bootstrap: it returns a nav and a JSON tag used by the pagy.js file
33
- def pagy_bootstrap_nav_js(pagy, pagy_id: nil, link_extra: '', **vars)
36
+ def pagy_bootstrap_nav_js(pagy, pagy_id: nil, link_extra: '',
37
+ nav_aria_label: nil, nav_i18n_key: nil, **vars)
34
38
  sequels = pagy.sequels(**vars)
35
39
  p_id = %( id="#{pagy_id}") if pagy_id
36
40
  link = pagy_link_proc(pagy, link_extra: %(class="page-link" #{link_extra}))
37
- tags = { 'before' => %(<ul class="pagination">#{pagy_bootstrap_prev_html pagy, link}),
38
- 'link' => %(<li class="page-item">#{mark = link.call(PAGE_PLACEHOLDER, LABEL_PLACEHOLDER)}</li>),
39
- 'active' => %(<li class="page-item active">#{mark}</li>),
40
- 'gap' => %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>),
41
- 'after' => %(#{pagy_bootstrap_next_html pagy, link}</ul>) }
41
+ tags = { 'before' => %(<ul class="pagination">#{bootstrap_prev_html pagy, link}),
42
+ 'link' => %(<li class="page-item">#{html = link.call(PAGE_PLACEHOLDER, LABEL_PLACEHOLDER)}</li>),
43
+ 'active' => %(<li class="page-item active">#{html}</li>),
44
+ 'gap' => %(<li class="page-item gap disabled"><a href="#" class="page-link" aria-disabled="true">#{
45
+ pagy_t 'pagy.gap'}</a></li>),
46
+ 'after' => %(#{bootstrap_next_html pagy, link}</ul>) }
42
47
 
43
48
  %(<nav#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-bootstrap-nav-js" #{
44
- pagy_data(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))}></nav>)
49
+ nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)} #{
50
+ pagy_data(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))
51
+ }></nav>)
45
52
  end
46
53
 
47
54
  # Javascript combo pagination for bootstrap: it returns a nav and a JSON tag used by the pagy.js file
48
- def pagy_bootstrap_combo_nav_js(pagy, pagy_id: nil, link_extra: '')
55
+ def pagy_bootstrap_combo_nav_js(pagy, pagy_id: nil, link_extra: '',
56
+ nav_aria_label: nil, nav_i18n_key: nil)
49
57
  p_id = %( id="#{pagy_id}") if pagy_id
50
- link = pagy_link_proc(pagy, link_extra: link_extra)
58
+ link = pagy_link_proc(pagy, link_extra:)
51
59
  p_page = pagy.page
52
60
  p_pages = pagy.pages
53
61
  input = %(<input type="number" min="1" max="#{p_pages}" value="#{
54
- p_page}" class="text-primary" style="padding: 0; border: none; text-align: center; width: #{
55
- p_pages.to_s.length + 1}rem;">)
62
+ p_page}" style="padding: 0; border: none; text-align: center; width: #{
63
+ p_pages.to_s.length + 1}rem;" aria-current="page">)
56
64
 
57
- %(<nav#{p_id} class="pagy-bootstrap-combo-nav-js pagination"><div class="btn-group" role="group" #{
65
+ %(<nav#{p_id} class="pagy-bootstrap-combo-nav-js pagination" #{
66
+ nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)}><div class="btn-group" role="group" #{
58
67
  pagy_data(pagy, :combo, pagy_marked_link(link))}>#{
59
68
  if (p_prev = pagy.prev)
60
- link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous" class="prev btn btn-primary"'
69
+ link.call(p_prev, pagy_t('pagy.prev'), %(class="prev btn btn-primary" #{prev_aria_label_attr}))
61
70
  else
62
- %(<a class="prev btn btn-primary disabled" href="#">#{pagy_t('pagy.nav.prev')}</a>)
71
+ %(<a class="prev btn btn-primary disabled" href="#" aria-disabled="true" #{
72
+ prev_aria_label_attr}>#{pagy_t('pagy.prev')}</a>)
63
73
  end
64
- }<div class="pagy-combo-input btn btn-primary disabled" style="white-space: nowrap;">#{
74
+ }<div class="pagy-combo-input btn btn-secondary" style="white-space: nowrap;">#{
65
75
  pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</div>#{
66
- if (p_next = pagy.next)
67
- link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next" class="next btn btn-primary"'
76
+ if (p_next = pagy.next)
77
+ link.call(p_next, pagy_t('pagy.next'), %(class="next btn btn-primary" #{next_aria_label_attr}))
68
78
  else
69
- %(<a class="next btn btn-primary disabled" href="#">#{pagy_t 'pagy.nav.next'}</a>)
79
+ %(<a class="next btn btn-primary disabled" href="#" aria-disabled="true" #{
80
+ next_aria_label_attr}>#{pagy_t 'pagy.next'}</a>)
70
81
  end
71
82
  }</div></nav>)
72
83
  end
73
84
 
74
85
  private
75
86
 
76
- def pagy_bootstrap_prev_html(pagy, link)
87
+ def bootstrap_prev_html(pagy, link)
77
88
  if (p_prev = pagy.prev)
78
- %(<li class="page-item prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</li>)
89
+ %(<li class="page-item prev">#{link.call(p_prev, pagy_t('pagy.prev'), prev_aria_label_attr)}</li>)
79
90
  else
80
- %(<li class="page-item prev disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.prev'}</a></li>)
91
+ %(<li class="page-item prev disabled"><a href="#" class="page-link" aria-disabled="true" #{
92
+ prev_aria_label_attr}>#{pagy_t('pagy.prev')}</a></li>)
81
93
  end
82
94
  end
83
95
 
84
- def pagy_bootstrap_next_html(pagy, link)
96
+ def bootstrap_next_html(pagy, link)
85
97
  if (p_next = pagy.next)
86
- %(<li class="page-item next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</li>)
98
+ %(<li class="page-item next">#{link.call p_next, pagy_t('pagy.next'), next_aria_label_attr}</li>)
87
99
  else
88
- %(<li class="page-item next disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.next'}</a></li>)
100
+ %(<li class="page-item next disabled"><a href="#" class="page-link" aria-disabled="true" #{
101
+ next_aria_label_attr}>#{pagy_t('pagy.next')}</a></li>)
89
102
  end
90
103
  end
91
104
  end
@@ -1,29 +1,32 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/bulma
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/bulma
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'pagy/extras/frontend_helpers'
5
5
 
6
6
  class Pagy # :nodoc:
7
+ DEFAULT[:bulma_nav_classes] = 'is-centered'
8
+
7
9
  # Frontend modules are specially optimized for performance.
8
10
  # The resulting code may not look very elegant, but produces the best benchmarks
9
11
  module BulmaExtra
10
12
  # Pagination for bulma: it returns the html with the series of links to the pages
11
- def pagy_bulma_nav(pagy, pagy_id: nil, link_extra: '', **vars)
13
+ def pagy_bulma_nav(pagy, pagy_id: nil, link_extra: '',
14
+ nav_aria_label: nil, nav_i18n_key: nil, **vars)
12
15
  p_id = %( id="#{pagy_id}") if pagy_id
13
- link = pagy_link_proc(pagy, link_extra: link_extra)
16
+ link = pagy_link_proc(pagy, link_extra:)
14
17
 
15
- html = +%(<nav#{p_id} class="pagy-bulma-nav pagination is-centered" aria-label="pagination">)
16
- html << pagy_bulma_prev_next_html(pagy, link)
18
+ html = +%(<nav#{p_id} class="pagy-bulma-nav pagination #{DEFAULT[:bulma_nav_classes]}" #{
19
+ nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)}>)
20
+ html << bulma_prev_next_html(pagy, link)
17
21
  html << %(<ul class="pagination-list">)
18
22
  pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
19
23
  html << case item
20
24
  when Integer
21
- %(<li>#{link.call item, pagy.label_for(item), %(class="pagination-link" aria-label="goto page #{item}")}</li>)
25
+ %(<li>#{link.call(item, pagy.label_for(item), %(class="pagination-link"))}</li>)
22
26
  when String
23
- %(<li>#{link.call item, pagy.label_for(item),
24
- %(class="pagination-link is-current" aria-label="page #{item}" aria-current="page")}</li>)
27
+ %(<li>#{link.call(item, pagy.label_for(item), %(class="pagination-link is-current"))}</li>)
25
28
  when :gap
26
- %(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.nav.gap'}</span></li>)
29
+ %(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.gap'}</span></li>)
27
30
  else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
28
31
  end
29
32
  end
@@ -31,62 +34,68 @@ class Pagy # :nodoc:
31
34
  end
32
35
 
33
36
  # Javascript pagination for bulma: it returns a nav and a JSON tag used by the Pagy.nav javascript
34
- def pagy_bulma_nav_js(pagy, pagy_id: nil, link_extra: '', **vars)
37
+ def pagy_bulma_nav_js(pagy, pagy_id: nil, link_extra: '',
38
+ nav_aria_label: nil, nav_i18n_key: nil, **vars)
35
39
  sequels = pagy.sequels(**vars)
36
40
  p_id = %( id="#{pagy_id}") if pagy_id
37
- link = pagy_link_proc(pagy, link_extra: link_extra)
38
- tags = { 'before' => %(#{pagy_bulma_prev_next_html(pagy, link)}<ul class="pagination-list">),
39
- 'link' => %(<li>#{link.call PAGE_PLACEHOLDER, LABEL_PLACEHOLDER,
40
- %(class="pagination-link" aria-label="goto page #{PAGE_PLACEHOLDER}")}</li>),
41
- 'active' => %(<li>#{link.call PAGE_PLACEHOLDER, LABEL_PLACEHOLDER,
42
- %(class="pagination-link is-current" aria-current="page" aria-label="page #{
43
- PAGE_PLACEHOLDER}")}</li>),
44
- 'gap' => %(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.nav.gap'}</span></li>),
41
+ link = pagy_link_proc(pagy, link_extra:)
42
+ tags = { 'before' => %(#{bulma_prev_next_html(pagy, link)}<ul class="pagination-list">),
43
+ 'link' => %(<li>#{link.call(PAGE_PLACEHOLDER, LABEL_PLACEHOLDER, %(class="pagination-link"))}</li>),
44
+ 'active' => %(<li>#{link.call(PAGE_PLACEHOLDER, LABEL_PLACEHOLDER, %(class="pagination-link is-current"))}</li>),
45
+ 'gap' => %(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.gap'}</span></li>),
45
46
  'after' => '</ul>' }
46
47
 
47
- %(<nav#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-bulma-nav-js pagination is-centered" aria-label="pagination" #{
48
+ %(<nav#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-bulma-nav-js pagination #{DEFAULT[:bulma_nav_classes]}" #{
49
+ nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)}#{
48
50
  pagy_data(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))}></nav>)
49
51
  end
50
52
 
51
53
  # Javascript combo pagination for bulma: it returns a nav and a JSON tag used by the pagy.js file
52
- def pagy_bulma_combo_nav_js(pagy, pagy_id: nil, link_extra: '')
54
+ def pagy_bulma_combo_nav_js(pagy, pagy_id: nil, link_extra: '',
55
+ nav_aria_label: nil, nav_i18n_key: nil)
53
56
  p_id = %( id="#{pagy_id}") if pagy_id
54
- link = pagy_link_proc(pagy, link_extra: link_extra)
57
+ link = pagy_link_proc(pagy, link_extra:)
55
58
  p_page = pagy.page
56
59
  p_pages = pagy.pages
57
60
  input = %(<input class="input" type="number" min="1" max="#{p_pages}" value="#{
58
- p_page}" style="padding: 0; text-align: center; width: #{p_pages.to_s.length + 1}rem; margin:0 0.3rem;">)
61
+ p_page}" style="padding: 0; text-align: center; width: #{
62
+ p_pages.to_s.length + 1}rem; margin:0 0.3rem;" aria-current="page">)
59
63
 
60
- html = %(<nav#{p_id} class="pagy-bulma-combo-nav-js" aria-label="pagination">)
64
+ html = %(<nav#{p_id} class="pagy-bulma-combo-nav-js #{DEFAULT[:bulma_nav_classes]}" #{
65
+ nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)}>)
61
66
  %(#{html}<div class="field is-grouped is-grouped-centered" role="group" #{
62
67
  pagy_data(pagy, :combo, pagy_marked_link(link))}>#{
63
68
  if (p_prev = pagy.prev)
64
- %(<p class="control">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'class="button" aria-label="previous page"'}</p>)
69
+ %(<p class="control">#{link.call(p_prev, pagy_t('pagy.prev'), %(class="button" #{prev_aria_label_attr}))}</p>)
65
70
  else
66
- %(<p class="control"><a class="button" disabled>#{pagy_t 'pagy.nav.prev'}</a></p>)
71
+ %(<p class="control"><a class="button" disabled aria-disabled="true" #{
72
+ prev_aria_label_attr}>#{pagy_t 'pagy.prev'}</a></p>)
67
73
  end
68
74
  }<div class="pagy-combo-input control level is-mobile">#{
69
75
  pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</div>#{
70
76
  if (p_next = pagy.next)
71
- %(<p class="control">#{link.call p_next, pagy_t('pagy.nav.next'), 'class="button" aria-label="next page"'}</p>)
77
+ %(<p class="control">#{link.call(p_next, pagy_t('pagy.next'), %(class="button" #{next_aria_label_attr}))}</p>)
72
78
  else
73
- %(<p class="control"><a class="button" disabled>#{pagy_t 'pagy.nav.next'}</a></p>)
79
+ %(<p class="control"><a class="button" disabled aria-disabled="true"#{
80
+ next_aria_label_attr}>#{pagy_t 'pagy.next'}</a></p>)
74
81
  end
75
82
  }</div></nav>)
76
83
  end
77
84
 
78
85
  private
79
86
 
80
- def pagy_bulma_prev_next_html(pagy, link)
87
+ def bulma_prev_next_html(pagy, link)
81
88
  html = +if (p_prev = pagy.prev)
82
- link.call p_prev, pagy_t('pagy.nav.prev'), 'class="pagination-previous" aria-label="previous page"'
89
+ link.call(p_prev, pagy_t('pagy.prev'), %(#{prev_aria_label_attr} class="pagination-previous"))
83
90
  else
84
- %(<a class="pagination-previous" disabled>#{pagy_t 'pagy.nav.prev'}</a>)
91
+ %(<a class="pagination-previous" disabled aria-disabled="true" #{
92
+ prev_aria_label_attr}>#{pagy_t 'pagy.prev'}</a>)
85
93
  end
86
94
  html << if (p_next = pagy.next)
87
- link.call p_next, pagy_t('pagy.nav.next'), 'class="pagination-next" aria-label="next page"'
95
+ link.call(p_next, pagy_t('pagy.next'), %(#{next_aria_label_attr} class="pagination-next"))
88
96
  else
89
- %(<a class="pagination-next" disabled>#{pagy_t 'pagy.nav.next'}</a>)
97
+ %(<a class="pagination-next" disabled aria-disabled="true" #{
98
+ next_aria_label_attr}>#{pagy_t('pagy.next')}</a>)
90
99
  end
91
100
  end
92
101
  end
@@ -1,4 +1,4 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/calendar
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/calendar
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'pagy/calendar'
@@ -8,18 +8,17 @@ class Pagy # :nodoc:
8
8
  # Add pagination filtering by calendar unit (:year, :quarter, :month, :week, :day) to the regular pagination
9
9
  module CalendarExtra
10
10
  # Additions for the Backend module
11
- module Backend
11
+ module BackendAddOn
12
12
  CONF_KEYS = (Calendar::UNITS + %i[pagy active]).freeze
13
13
 
14
14
  private
15
15
 
16
16
  # Take a collection and a conf Hash with keys in CONF_KEYS and return an array with 3 items: [calendar, pagy, results]
17
17
  def pagy_calendar(collection, conf)
18
- unless conf.is_a?(Hash) && (conf.keys - CONF_KEYS).empty? && conf.all? { |k, v| v.is_a?(Hash) || k == :active }
19
- raise ArgumentError, "keys must be in #{CONF_KEYS.inspect} and object values must be Hashes; got #{conf.inspect}"
20
- end
18
+ raise ArgumentError, "keys must be in #{CONF_KEYS.inspect}" \
19
+ unless conf.is_a?(Hash) && (conf.keys - CONF_KEYS).empty?
21
20
 
22
- conf[:pagy] = {} unless conf[:pagy] # use default Pagy object when omitted
21
+ conf[:pagy] ||= {}
23
22
  unless conf.key?(:active) && !conf[:active]
24
23
  calendar, from, to = Calendar::Helper.send(:init, conf, pagy_calendar_period(collection), params)
25
24
  collection = pagy_calendar_filter(collection, from, to)
@@ -28,22 +27,27 @@ class Pagy # :nodoc:
28
27
  [calendar, pagy, results]
29
28
  end
30
29
 
31
- def pagy_calendar_url_at(calendar, time)
32
- pagy_url_for(calendar.send(:last_object_at, time), 1)
33
- end
34
-
35
30
  # This method must be implemented by the application
36
31
  def pagy_calendar_period(*)
37
32
  raise NoMethodError, 'the pagy_calendar_period method must be implemented by the application ' \
38
- '(see https://ddnexus.github.io/pagy/extras/calendar#pagy_calendar_periodcollection)'
33
+ '(see https://ddnexus.github.io/pagy/docs/extras/calendar/#pagy-calendar-period-collection)'
39
34
  end
40
35
 
41
36
  # This method must be implemented by the application
42
37
  def pagy_calendar_filter(*)
43
38
  raise NoMethodError, 'the pagy_calendar_filter method must be implemented by the application ' \
44
- '(see https://ddnexus.github.io/pagy/extras/calendar#pagy_calendar_filtercollection-from-to)'
39
+ '(see https://ddnexus.github.io/pagy/docs/extras/calendar/#pagy-calendar-filter-collection-from-to)'
40
+ end
41
+ end
42
+
43
+ # Additions for the Frontend module
44
+ module UrlHelperAddOn
45
+ # Return the url for the calendar page at time
46
+ def pagy_calendar_url_at(calendar, time, **opts)
47
+ pagy_url_for(calendar.send(:calendar_at, time, **opts), 1, **opts)
45
48
  end
46
49
  end
47
50
  end
48
- Backend.prepend CalendarExtra::Backend
51
+ Backend.prepend CalendarExtra::BackendAddOn, CalendarExtra::UrlHelperAddOn
52
+ Frontend.prepend CalendarExtra::UrlHelperAddOn
49
53
  end
@@ -1,4 +1,4 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/countless
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/countless
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'pagy/countless'
@@ -1,4 +1,4 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/elasticsearch_rails
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/elasticsearch_rails
2
2
  # frozen_string_literal: true
3
3
 
4
4
  class Pagy # :nodoc:
@@ -19,7 +19,7 @@ class Pagy # :nodoc:
19
19
  total.is_a?(Hash) ? total['value'] : total
20
20
  end
21
21
 
22
- module ElasticsearchRails # :nodoc:
22
+ module ModelExtension # :nodoc:
23
23
  # Return an array used to delay the call of #search
24
24
  # after the pagination variables are merged to the options.
25
25
  # It also pushes to the same array an optional method call.
@@ -30,9 +30,10 @@ class Pagy # :nodoc:
30
30
  end
31
31
  alias_method Pagy::DEFAULT[:elasticsearch_rails_pagy_search], :pagy_elasticsearch_rails
32
32
  end
33
+ Pagy::ElasticsearchRails = ModelExtension
33
34
 
34
35
  # Additions for the Pagy class
35
- module Pagy
36
+ module PagyAddOn
36
37
  # Create a Pagy object from an Elasticsearch::Model::Response::Response object
37
38
  def new_from_elasticsearch_rails(response, vars = {})
38
39
  vars[:items] = response.search.options[:size] || 10
@@ -41,9 +42,10 @@ class Pagy # :nodoc:
41
42
  new(vars)
42
43
  end
43
44
  end
45
+ Pagy.extend PagyAddOn
44
46
 
45
47
  # Add specialized backend methods to paginate ElasticsearchRails searches
46
- module Backend
48
+ module BackendAddOn
47
49
  private
48
50
 
49
51
  # Return Pagy object and items
@@ -69,12 +71,10 @@ class Pagy # :nodoc:
69
71
  def pagy_elasticsearch_rails_get_vars(_collection, vars)
70
72
  pagy_set_items_from_params(vars) if defined?(ItemsExtra)
71
73
  vars[:items] ||= DEFAULT[:items]
72
- vars[:page] ||= (params[vars[:page_param] || DEFAULT[:page_param]] || 1).to_i
74
+ vars[:page] ||= pagy_get_page(vars)
73
75
  vars
74
76
  end
75
77
  end
78
+ Backend.prepend BackendAddOn
76
79
  end
77
- ElasticsearchRails = ElasticsearchRailsExtra::ElasticsearchRails
78
- extend ElasticsearchRailsExtra::Pagy
79
- Backend.prepend ElasticsearchRailsExtra::Backend
80
80
  end
@@ -1,4 +1,4 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/foundation
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/foundation
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'pagy/extras/frontend_helpers'
@@ -8,18 +8,24 @@ class Pagy # :nodoc:
8
8
  # The resulting code may not look very elegant, but produces the best benchmarks
9
9
  module FoundationExtra
10
10
  # Pagination for Foundation: it returns the html with the series of links to the pages
11
- def pagy_foundation_nav(pagy, pagy_id: nil, link_extra: '', **vars)
11
+ def pagy_foundation_nav(pagy, pagy_id: nil, link_extra: '',
12
+ nav_aria_label: nil, nav_i18n_key: nil, **vars)
12
13
  p_id = %( id="#{pagy_id}") if pagy_id
13
- link = pagy_link_proc(pagy, link_extra: link_extra)
14
+ link = pagy_link_proc(pagy, link_extra:)
14
15
 
15
- html = +%(<nav#{p_id} class="pagy-foundation-nav" aria-label="Pagination"><ul class="pagination">)
16
- html << pagy_foundation_prev_html(pagy, link)
16
+ html = +%(<nav#{p_id} class="pagy-foundation-nav" #{
17
+ nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)}><ul class="pagination">)
18
+ html << foundation_prev_html(pagy, link)
17
19
  pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
18
20
  html << case item
19
- when Integer then %(<li>#{link.call item}</li>) # page link
20
- when String then %(<li class="current">#{pagy.label_for(item)}</li>) # active page
21
- when :gap then %(<li class="ellipsis gap" aria-hidden="true"></li>) # page gap
22
- else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
21
+ when Integer
22
+ %(<li>#{link.call item}</li>)
23
+ when String
24
+ %(<li class="current" role="link" aria-current="page" aria-disabled="true">#{pagy.label_for(item)}</li>)
25
+ when :gap
26
+ %(<li class="ellipsis gap"></li>)
27
+ else
28
+ raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
23
29
  end
24
30
  end
25
31
  html << pagy_foundation_next_html(pagy, link)
@@ -27,62 +33,71 @@ class Pagy # :nodoc:
27
33
  end
28
34
 
29
35
  # Javascript pagination for foundation: it returns a nav and a JSON tag used by the pagy.js file
30
- def pagy_foundation_nav_js(pagy, pagy_id: nil, link_extra: '', **vars)
36
+ def pagy_foundation_nav_js(pagy, pagy_id: nil, link_extra: '',
37
+ nav_aria_label: nil, nav_i18n_key: nil, **vars)
31
38
  sequels = pagy.sequels(**vars)
32
39
  p_id = %( id="#{pagy_id}") if pagy_id
33
- link = pagy_link_proc(pagy, link_extra: link_extra)
34
- tags = { 'before' => %(<ul class="pagination">#{pagy_foundation_prev_html pagy, link}),
40
+ link = pagy_link_proc(pagy, link_extra:)
41
+ tags = { 'before' => %(<ul class="pagination">#{foundation_prev_html pagy, link}),
35
42
  'link' => %(<li>#{link.call(PAGE_PLACEHOLDER, LABEL_PLACEHOLDER)}</li>),
36
- 'active' => %(<li class="current">#{LABEL_PLACEHOLDER}</li>),
37
- 'gap' => %(<li class="ellipsis gap" aria-hidden="true"></li>),
43
+ 'active' => %(<li class="current" role="link" aria-current="page" aria-disabled="true">#{LABEL_PLACEHOLDER}</li>),
44
+ 'gap' => %(<li class="ellipsis gap"></li>),
38
45
  'after' => %(#{pagy_foundation_next_html pagy, link}</ul>) }
39
46
 
40
- %(<nav#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-foundation-nav-js" aria-label="Pagination" #{
41
- pagy_data(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))}></nav>)
47
+ %(<nav#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-foundation-nav-js" #{
48
+ nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)} #{
49
+ pagy_data(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))}></nav>)
42
50
  end
43
51
 
44
52
  # Javascript combo pagination for Foundation: it returns a nav and a JSON tag used by the pagy.js file
45
- def pagy_foundation_combo_nav_js(pagy, pagy_id: nil, link_extra: '')
53
+ def pagy_foundation_combo_nav_js(pagy, pagy_id: nil, link_extra: '',
54
+ nav_aria_label: nil, nav_i18n_key: nil)
46
55
  p_id = %( id="#{pagy_id}") if pagy_id
47
- link = pagy_link_proc(pagy, link_extra: link_extra)
56
+ link = pagy_link_proc(pagy, link_extra:)
48
57
  p_page = pagy.page
49
58
  p_pages = pagy.pages
50
59
  input = %(<input class="input-group-field cell shrink" type="number" min="1" max="#{
51
60
  p_pages}" value="#{p_page}" style="width: #{
52
- p_pages.to_s.length + 1}rem; padding: 0 0.3rem; margin: 0 0.3rem;">)
61
+ p_pages.to_s.length + 1}rem; padding: 0 0.3rem; margin: 0 0.3rem;" aria-current="page">)
53
62
 
54
- %(<nav#{p_id} class="pagy-foundation-combo-nav-js" aria-label="Pagination"><div class="input-group" #{
63
+ %(<nav#{p_id} class="pagy-foundation-combo-nav-js" #{
64
+ nav_aria_label_attr(pagy, nav_aria_label, nav_i18n_key)}><div class="input-group" #{
55
65
  pagy_data(pagy, :combo, pagy_marked_link(link))}>#{
56
- if (p_prev = pagy.prev)
57
- link.call p_prev, pagy_t('pagy.nav.prev'),
58
- 'style="margin-bottom: 0" aria-label="previous" class="prev button primary"'
66
+ if (p_prev = pagy.prev)
67
+ link.call(p_prev, pagy_t('pagy.prev'),
68
+ %(style="margin-bottom: 0" class="prev button primary" #{prev_aria_label_attr}))
59
69
  else
60
- %(<a style="margin-bottom: 0" class="prev button primary disabled" href="#">#{pagy_t 'pagy.nav.prev'}</a>)
70
+ %(<a style="margin-bottom: 0" class="prev button primary disabled" role="link" aria-disabled="true" #{
71
+ prev_aria_label_attr}>#{pagy_t('pagy.prev')}</a>)
61
72
  end
62
- }<span class="input-group-label">#{pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</span>#{
63
- if (p_next = pagy.next)
64
- link.call p_next, pagy_t('pagy.nav.next'), 'style="margin-bottom: 0" aria-label="next" class="next button primary"'
73
+ }#{
74
+ pagy_t('pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages)
75
+ .sub!('<label>', '<label class="input-group-label">')}#{ # add the class to the official dictionary string
76
+ if (p_next = pagy.next)
77
+ link.call(p_next, pagy_t('pagy.next'),
78
+ %(style="margin-bottom: 0" class="next button primary" #{next_aria_label_attr}))
65
79
  else
66
- %(<a style="margin-bottom: 0" class="next button primary disabled" href="#">#{pagy_t 'pagy.nav.next'}</a>)
80
+ %(<a style="margin-bottom: 0" class="next button primary disabled" role="link" aria-disabled="true" #{
81
+ next_aria_label_attr}>#{pagy_t 'pagy.next'}</a>)
67
82
  end
68
83
  }</div></nav>)
69
84
  end
70
85
 
71
86
  private
72
87
 
73
- def pagy_foundation_prev_html(pagy, link)
88
+ def foundation_prev_html(pagy, link)
74
89
  if (p_prev = pagy.prev)
75
- %(<li class="prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</li>)
90
+ %(<li class="prev">#{link.call(p_prev, pagy_t('pagy.prev'), prev_aria_label_attr)}</li>)
76
91
  else
77
- %(<li class="prev disabled">#{pagy_t 'pagy.nav.prev'}</li>)
92
+ %(<li class="prev disabled" role="link" aria-disabled="true" #{prev_aria_label_attr}>#{pagy_t('pagy.prev')}</li>)
78
93
  end
79
94
  end
80
95
 
81
96
  def pagy_foundation_next_html(pagy, link)
82
97
  if (p_next = pagy.next)
83
- %(<li class="next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</li>)
98
+ %(<li class="next">#{link.call(p_next, pagy_t('pagy.next'), next_aria_label_attr)}</li>)
84
99
  else
85
- %(<li class="next disabled">#{pagy_t 'pagy.nav.next'}</li>)
100
+ %(<li class="next disabled" role="link" aria-disabled="true" #{next_aria_label_attr}>#{pagy_t('pagy.next')}</li>)
86
101
  end
87
102
  end
88
103
  end
@@ -1,14 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'base64'
4
-
5
3
  class Pagy # :nodoc:
6
4
  DEFAULT[:steps] = false # default false will use {0 => @vars[:size]}
7
5
 
8
6
  # Private module documented in the main classes
9
7
  module FrontendHelpers
10
8
  # Additions for the Pagy class
11
- module Pagy
9
+ module PagyAddOn
12
10
  # `Pagy` instance method used by the `pagy*_nav_js` helpers.
13
11
  # It returns the sequels of width/series generated from the :steps hash
14
12
  # Example:
@@ -29,9 +27,10 @@ class Pagy # :nodoc:
29
27
  # Support for the Calendar API
30
28
  def label_sequels(*); end
31
29
  end
30
+ Pagy.prepend PagyAddOn
32
31
 
33
32
  # Additions for Calendar class
34
- module Calendar
33
+ module CalendarOverride
35
34
  def label_sequels(sequels = self.sequels)
36
35
  {}.tap do |label_sequels|
37
36
  sequels.each do |width, series|
@@ -40,15 +39,17 @@ class Pagy # :nodoc:
40
39
  end
41
40
  end
42
41
  end
42
+ Calendar.prepend CalendarOverride if defined?(Calendar)
43
43
 
44
44
  # Additions for the Frontend
45
- module Frontend
45
+ module FrontendAddOn
46
46
  if defined?(Oj)
47
47
  # Return a data tag with the base64 encoded JSON-serialized args generated with the faster oj gem
48
48
  # Base64 encoded JSON is smaller than HTML escaped JSON
49
49
  def pagy_data(pagy, *args)
50
50
  args << pagy.vars[:page_param] if pagy.vars[:trim_extra]
51
- %(data-pagy="#{Base64.strict_encode64(Oj.dump(args, mode: :strict))}")
51
+ strict_base64_encoded = [Oj.dump(args, mode: :strict)].pack('m0')
52
+ %(data-pagy="#{strict_base64_encoded}")
52
53
  end
53
54
  else
54
55
  require 'json'
@@ -56,17 +57,16 @@ class Pagy # :nodoc:
56
57
  # Base64 encoded JSON is smaller than HTML escaped JSON
57
58
  def pagy_data(pagy, *args)
58
59
  args << pagy.vars[:page_param] if pagy.vars[:trim_extra]
59
- %(data-pagy="#{Base64.strict_encode64(args.to_json)}")
60
+ strict_base64_encoded = [args.to_json].pack('m0')
61
+ %(data-pagy="#{strict_base64_encoded}")
60
62
  end
61
63
  end
62
64
 
63
- # Return the marked link to used by pagy.js
65
+ # Return the marked link used by pagy.js
64
66
  def pagy_marked_link(link)
65
67
  link.call PAGE_PLACEHOLDER, '', 'style="display: none;"'
66
68
  end
67
69
  end
70
+ Frontend.prepend FrontendAddOn
68
71
  end
69
- prepend FrontendHelpers::Pagy
70
- Calendar.prepend FrontendHelpers::Calendar if defined?(Calendar)
71
- Frontend.prepend FrontendHelpers::Frontend
72
72
  end
@@ -1,4 +1,4 @@
1
- # See the Pagy documentation: https://ddnexus.github.io/pagy/extras/gearbox
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/gearbox
2
2
  # frozen_string_literal: true
3
3
 
4
4
  class Pagy # :nodoc: