pagy 7.0.11 → 8.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/apps/calendar.ru +745 -0
- data/apps/demo.ru +435 -0
- data/apps/rails.ru +212 -0
- data/apps/repro.ru +177 -0
- data/apps/tmp/calendar.sqlite3 +0 -0
- data/apps/tmp/calendar.sqlite3-shm +0 -0
- data/apps/tmp/calendar.sqlite3-wal +0 -0
- data/apps/tmp/local_secret.txt +1 -0
- data/apps/tmp/pagy-keyset.sqlite3 +0 -0
- data/apps/tmp/pagy-keyset.sqlite3-shm +0 -0
- data/apps/tmp/pagy-keyset.sqlite3-wal +0 -0
- data/bin/pagy +100 -0
- data/{lib/config → config}/pagy.rb +31 -73
- data/javascripts/pagy-module.js +100 -0
- data/javascripts/pagy.js +4 -0
- data/javascripts/pagy.min.js +4 -0
- data/javascripts/pagy.min.js.map +10 -0
- data/javascripts/pagy.mjs +100 -0
- data/lib/optimist.rb +1022 -0
- data/lib/pagy/backend.rb +8 -3
- data/lib/pagy/calendar/day.rb +4 -3
- data/lib/pagy/calendar/month.rb +4 -3
- data/lib/pagy/calendar/quarter.rb +4 -3
- data/lib/pagy/calendar/unit.rb +106 -0
- data/lib/pagy/calendar/week.rb +3 -3
- data/lib/pagy/calendar/year.rb +4 -3
- data/lib/pagy/calendar.rb +55 -99
- data/lib/pagy/console.rb +2 -2
- data/lib/pagy/countless.rb +15 -10
- data/lib/pagy/extras/arel.rb +1 -1
- data/lib/pagy/extras/array.rb +1 -1
- data/lib/pagy/extras/bootstrap.rb +52 -63
- data/lib/pagy/extras/bulma.rb +49 -64
- data/lib/pagy/extras/calendar.rb +35 -5
- data/lib/pagy/extras/countless.rb +2 -2
- data/lib/pagy/extras/foundation.rb +52 -62
- data/lib/pagy/extras/gearbox.rb +28 -27
- data/lib/pagy/extras/headers.rb +1 -1
- data/lib/pagy/extras/i18n.rb +1 -1
- data/lib/pagy/extras/items.rb +21 -18
- data/lib/pagy/extras/{frontend_helpers.rb → js_tools.rb} +9 -6
- data/lib/pagy/extras/jsonapi.rb +2 -2
- data/lib/pagy/extras/materialize.rb +56 -52
- data/lib/pagy/extras/metadata.rb +6 -2
- data/lib/pagy/extras/overflow.rb +5 -4
- data/lib/pagy/extras/pagy.rb +82 -0
- data/lib/pagy/extras/semantic.rb +50 -51
- data/lib/pagy/extras/size.rb +40 -0
- data/lib/pagy/extras/standalone.rb +2 -2
- data/lib/pagy/extras/trim.rb +12 -12
- data/lib/pagy/extras/uikit.rb +51 -50
- data/lib/pagy/frontend.rb +39 -53
- data/lib/pagy/url_helpers.rb +9 -10
- data/lib/pagy.rb +51 -82
- data/{lib/locales → locales}/ar.yml +10 -11
- data/{lib/locales → locales}/be.yml +5 -5
- data/{lib/locales → locales}/bg.yml +5 -5
- data/{lib/locales → locales}/bs.yml +5 -5
- data/locales/ca.yml +21 -0
- data/locales/ckb.yml +18 -0
- data/{lib/locales → locales}/cs.yml +5 -5
- data/locales/da.yml +21 -0
- data/{lib/locales → locales}/de.yml +5 -5
- data/{lib/locales → locales}/en.yml +5 -5
- data/{lib/locales → locales}/es.yml +3 -3
- data/{lib/locales → locales}/fr.yml +5 -5
- data/{lib/locales → locales}/hr.yml +5 -5
- data/{lib/locales → locales}/id.yml +5 -5
- data/{lib/locales → locales}/it.yml +5 -5
- data/{lib/locales → locales}/ja.yml +5 -5
- data/{lib/locales → locales}/km.yml +5 -5
- data/locales/ko.yml +17 -0
- data/{lib/locales → locales}/nb.yml +5 -5
- data/{lib/locales → locales}/nl.yml +5 -5
- data/{lib/locales → locales}/nn.yml +5 -5
- data/{lib/locales → locales}/pl.yml +5 -5
- data/{lib/locales → locales}/pt-BR.yml +3 -3
- data/{lib/locales → locales}/pt.yml +3 -3
- data/locales/ru.yml +25 -0
- data/{lib/locales → locales}/sr.yml +5 -5
- data/{lib/locales → locales}/sv-SE.yml +5 -5
- data/{lib/locales → locales}/sv.yml +5 -5
- data/{lib/locales → locales}/sw.yml +5 -5
- data/{lib/locales → locales}/ta.yml +5 -5
- data/{lib/locales → locales}/tr.yml +5 -5
- data/{lib/locales → locales}/uk.yml +5 -5
- data/locales/vi.yml +17 -0
- data/{lib/locales → locales}/zh-CN.yml +5 -5
- data/{lib/locales → locales}/zh-HK.yml +5 -5
- data/{lib/locales → locales}/zh-TW.yml +5 -5
- data/{lib/stylesheets → stylesheets}/pagy.css +19 -34
- data/{lib/stylesheets → stylesheets}/pagy.scss +17 -19
- data/stylesheets/pagy.tailwind.css +21 -0
- metadata +76 -53
- data/lib/javascripts/pagy-dev.js +0 -112
- data/lib/javascripts/pagy-module.js +0 -111
- data/lib/javascripts/pagy.js +0 -1
- data/lib/locales/ca.yml +0 -23
- data/lib/locales/ckb.yml +0 -18
- data/lib/locales/da.yml +0 -23
- data/lib/locales/ko.yml +0 -19
- data/lib/locales/ru.yml +0 -27
- data/lib/locales/vi.yml +0 -17
- data/lib/pagy/calendar/helper.rb +0 -65
- data/lib/pagy/extras/navs.rb +0 -51
- data/lib/pagy/extras/support.rb +0 -40
- data/lib/stylesheets/pagy.tailwind.scss +0 -24
- /data/{lib/javascripts/pagy-module.d.ts → javascripts/pagy.d.ts} +0 -0
data/lib/pagy/extras/semantic.rb
CHANGED
@@ -1,25 +1,25 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/semantic
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
warn '[PAGY WARNING] The semantic extra has been discontinued and it will be removed in v9 ' \
|
4
|
+
'(https://github.com/ddnexus/pagy/discussions/672#discussioncomment-9212328)'
|
5
|
+
|
6
|
+
require_relative 'js_tools'
|
5
7
|
|
6
8
|
class Pagy # :nodoc:
|
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 SemanticExtra
|
10
12
|
# Pagination for semantic: it returns the html with the series of links to the pages
|
11
|
-
def pagy_semantic_nav(pagy,
|
12
|
-
|
13
|
-
|
14
|
-
link = pagy_link_proc(pagy, link_extra:)
|
13
|
+
def pagy_semantic_nav(pagy, id: nil, aria_label: nil, **vars)
|
14
|
+
id = %( id="#{id}") if id
|
15
|
+
a = pagy_anchor(pagy)
|
15
16
|
|
16
|
-
html =
|
17
|
-
|
18
|
-
html << semantic_prev_html(pagy, link)
|
17
|
+
html = %(<div#{id} role="navigation" class="pagy-semantic nav ui pagination menu" #{
|
18
|
+
nav_aria_label(pagy, aria_label:)}>#{semantic_prev_html(pagy, a)})
|
19
19
|
pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
20
20
|
html << case item
|
21
21
|
when Integer
|
22
|
-
|
22
|
+
a.(item, pagy.label_for(item), classes: 'item')
|
23
23
|
when String
|
24
24
|
%(<a role="link" class="item active" aria-current="page" aria-disabled="true">#{pagy.label_for(item)}</a>)
|
25
25
|
when :gap
|
@@ -28,66 +28,65 @@ class Pagy # :nodoc:
|
|
28
28
|
raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
29
29
|
end
|
30
30
|
end
|
31
|
-
html << semantic_next_html(pagy,
|
32
|
-
html << %(</div>)
|
31
|
+
html << %(#{semantic_next_html(pagy, a)}</div>)
|
33
32
|
end
|
34
33
|
|
35
|
-
# Javascript pagination for semantic: it returns a nav
|
36
|
-
def pagy_semantic_nav_js(pagy,
|
37
|
-
nav_aria_label: nil, nav_i18n_key: nil, **vars)
|
34
|
+
# Javascript pagination for semantic: it returns a nav with a data-pagy attribute used by the pagy.js file
|
35
|
+
def pagy_semantic_nav_js(pagy, id: nil, aria_label: nil, **vars)
|
38
36
|
sequels = pagy.sequels(**vars)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
37
|
+
id = %( id="#{id}") if id
|
38
|
+
a = pagy_anchor(pagy)
|
39
|
+
tokens = { 'before' => semantic_prev_html(pagy, a),
|
40
|
+
'a' => a.(PAGE_TOKEN, LABEL_TOKEN, classes: 'item'),
|
41
|
+
'current' => %(<a role="link" class="item active" aria-current="page" aria-disabled="true">#{LABEL_TOKEN}</a>),
|
42
|
+
'gap' => %(<div class="disabled item">#{pagy_t('pagy.gap')}</div>),
|
43
|
+
'after' => semantic_next_html(pagy, a) }
|
46
44
|
|
47
|
-
%(<div#{
|
48
|
-
|
49
|
-
pagy_data(pagy, :nav,
|
45
|
+
%(<div#{id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-semantic nav-js ui pagination menu" role="navigation" #{
|
46
|
+
nav_aria_label(pagy, aria_label:)} #{
|
47
|
+
pagy_data(pagy, :nav, tokens, sequels, pagy.label_sequels(sequels))
|
48
|
+
}></div>)
|
50
49
|
end
|
51
50
|
|
52
|
-
# Combo pagination for semantic: it returns a nav
|
53
|
-
def pagy_semantic_combo_nav_js(pagy,
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
p_pages.to_s.length + 1}rem; margin: 0 0.3rem" aria-current="page">)
|
51
|
+
# Combo pagination for semantic: it returns a nav with a data-pagy attribute used by the pagy.js file
|
52
|
+
def pagy_semantic_combo_nav_js(pagy, id: nil, 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; padding: 0; margin: 0 0.3rem">) <<
|
59
|
+
JSTools::A_TAG
|
62
60
|
|
63
|
-
%(<div#{
|
64
|
-
|
65
|
-
pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
61
|
+
%(<div#{id} class="pagy-semantic combo-nav-js ui compact menu" role="navigation" #{
|
62
|
+
nav_aria_label(pagy, aria_label:)} #{
|
63
|
+
pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
|
64
|
+
}>#{
|
65
|
+
semantic_prev_html(pagy, a)
|
66
|
+
}<div class="item"><label>#{
|
67
|
+
pagy_t('pagy.combo_nav_js', page_input:, pages:)
|
68
|
+
}</label></div> #{
|
69
|
+
semantic_next_html(pagy, a)
|
71
70
|
}</div>)
|
72
71
|
end
|
73
72
|
|
74
73
|
private
|
75
74
|
|
76
|
-
def semantic_prev_html(pagy,
|
75
|
+
def semantic_prev_html(pagy, a)
|
77
76
|
if (p_prev = pagy.prev)
|
78
|
-
|
77
|
+
a.(p_prev, pagy_t('pagy.prev'), classes: 'item', aria_label: pagy_t('pagy.aria_label.prev'))
|
79
78
|
else
|
80
|
-
|
81
|
-
|
79
|
+
%(<div class="item disabled" role="a" aria-disabled="true" aria-label="#{
|
80
|
+
pagy_t('pagy.aria_label.prev')}">#{pagy_t('pagy.prev')}</div>)
|
82
81
|
end
|
83
82
|
end
|
84
83
|
|
85
|
-
def semantic_next_html(pagy,
|
84
|
+
def semantic_next_html(pagy, a)
|
86
85
|
if (p_next = pagy.next)
|
87
|
-
|
86
|
+
a.(p_next, pagy_t('pagy.next'), classes: 'item', aria_label: pagy_t('pagy.aria_label.next'))
|
88
87
|
else
|
89
|
-
|
90
|
-
|
88
|
+
%(<div class="item disabled" role="link" aria-disabled="true" aria=label="#{
|
89
|
+
pagy_t('pagy.aria_label.prev')}">#{pagy_t('pagy.next')}</div>)
|
91
90
|
end
|
92
91
|
end
|
93
92
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/size
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
class Pagy # :nodoc:
|
5
|
+
# Implement the legacy bar using the array size.
|
6
|
+
# Unless you have very specific requirements, use the faster and better looking default bar.
|
7
|
+
module SizeExtra
|
8
|
+
# Setup @items based on the :gearbox_items variable
|
9
|
+
def series(size: @vars[:size], **_)
|
10
|
+
return super unless size.is_a?(Array)
|
11
|
+
return [] if size == []
|
12
|
+
raise VariableError.new(self, :size, 'to be an Array of 4 Integers or []', size) \
|
13
|
+
unless size.is_a?(Array) && size.size == 4 && size.all? { |num| !num.negative? rescue false } # rubocop:disable Style/RescueModifier
|
14
|
+
|
15
|
+
[].tap do |series|
|
16
|
+
# This algorithm is up to ~5x faster and ~2.3x lighter than the previous one (pagy < 4.3)
|
17
|
+
# However the behavior of the legacy nav bar was taken straight from WillPaginate and Kaminari:
|
18
|
+
# it's ill-concieved and complicates the experience of devs and users.
|
19
|
+
left_gap_start = 1 + size[0]
|
20
|
+
left_gap_end = @page - size[1] - 1
|
21
|
+
right_gap_start = @page + size[2] + 1
|
22
|
+
right_gap_end = @last - size[3]
|
23
|
+
left_gap_end = right_gap_end if left_gap_end > right_gap_end
|
24
|
+
right_gap_start = left_gap_start if left_gap_start > right_gap_start
|
25
|
+
start = 1
|
26
|
+
if (left_gap_end - left_gap_start).positive?
|
27
|
+
series.push(*start...left_gap_start, :gap)
|
28
|
+
start = left_gap_end + 1
|
29
|
+
end
|
30
|
+
if (right_gap_end - right_gap_start).positive?
|
31
|
+
series.push(*start...right_gap_start, :gap)
|
32
|
+
start = right_gap_end + 1
|
33
|
+
end
|
34
|
+
series.push(*start..@last)
|
35
|
+
series[series.index(@page)] = @page.to_s
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
prepend SizeExtra
|
40
|
+
end
|
@@ -42,9 +42,9 @@ class Pagy # :nodoc:
|
|
42
42
|
return super unless pagy.vars[:url]
|
43
43
|
|
44
44
|
vars = pagy.vars
|
45
|
-
params =
|
45
|
+
params = vars[:params].is_a?(Hash) ? vars[:params].clone : {} # safe when it gets reused
|
46
46
|
pagy_set_query_params(page, vars, params)
|
47
|
-
params =
|
47
|
+
params = vars[:params].(params) if vars[:params].is_a?(Proc)
|
48
48
|
query_string = "?#{QueryUtils.build_nested_query(params)}"
|
49
49
|
"#{vars[:url]}#{query_string}#{vars[:fragment]}"
|
50
50
|
end
|
data/lib/pagy/extras/trim.rb
CHANGED
@@ -6,23 +6,23 @@ class Pagy # :nodoc:
|
|
6
6
|
|
7
7
|
# Remove the page=1 param from the first page link
|
8
8
|
module TrimExtra
|
9
|
-
# Override the original
|
10
|
-
# Call the pagy_trim method if the trim_extra is enabled
|
11
|
-
def
|
12
|
-
|
13
|
-
return
|
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
|
13
|
+
return a_proc unless pagy.vars[:trim_extra]
|
14
14
|
|
15
|
-
lambda do |page, text = pagy.label_for(page),
|
16
|
-
|
17
|
-
return
|
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
18
|
|
19
|
-
pagy_trim(pagy,
|
19
|
+
pagy_trim(pagy, a) # in method for isolated testing
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
# Remove the the :page_param param from the first page
|
24
|
-
def pagy_trim(pagy,
|
25
|
-
|
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
26
|
end
|
27
27
|
end
|
28
28
|
Frontend.prepend TrimExtra
|
data/lib/pagy/extras/uikit.rb
CHANGED
@@ -1,25 +1,26 @@
|
|
1
|
-
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/uikit
|
2
1
|
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
warn '[PAGY WARNING] The uikit extra has been discontinued and it will be removed in v9 ' \
|
4
|
+
'(https://github.com/ddnexus/pagy/discussions/672#discussioncomment-9212328)'
|
5
|
+
|
6
|
+
require_relative 'js_tools'
|
5
7
|
|
6
8
|
class Pagy # :nodoc:
|
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 UikitExtra
|
10
12
|
# Pagination for uikit: it returns the html with the series of links to the pages
|
11
|
-
def pagy_uikit_nav(pagy,
|
12
|
-
|
13
|
-
|
14
|
-
link = pagy_link_proc(pagy, link_extra:)
|
15
|
-
|
16
|
-
html = +%(<ul#{p_id} class="pagy-uikit-nav uk-pagination uk-flex-center" role="navigation" #{
|
13
|
+
def pagy_uikit_nav(pagy, id: nil, aria_label: nil, **vars)
|
14
|
+
id = %( id="#{id}") if id
|
15
|
+
a = pagy_anchor(pagy)
|
17
16
|
|
18
|
-
|
17
|
+
html = %(<ul#{id} class="pagy-uikit nav uk-pagination uk-flex-center" role="navigation" #{
|
18
|
+
nav_aria_label(pagy, aria_label:)}>#{
|
19
|
+
uikit_prev_html(pagy, a)})
|
19
20
|
pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
20
21
|
html << case item
|
21
22
|
when Integer
|
22
|
-
%(<li>#{
|
23
|
+
%(<li>#{a.(item)}</li>)
|
23
24
|
when String
|
24
25
|
%(<li class="uk-active"><span role="link" aria-current="page" aria-disabled="true">#{
|
25
26
|
pagy.label_for(item)}</span></li>)
|
@@ -29,67 +30,67 @@ class Pagy # :nodoc:
|
|
29
30
|
raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
30
31
|
end
|
31
32
|
end
|
32
|
-
html << uikit_next_html(pagy,
|
33
|
-
html << %(</ul>)
|
33
|
+
html << %(#{uikit_next_html(pagy, a)}</ul>)
|
34
34
|
end
|
35
35
|
|
36
|
-
# Javascript pagination for uikit: it returns a nav
|
37
|
-
def pagy_uikit_nav_js(pagy,
|
38
|
-
nav_aria_label: nil, nav_i18n_key: nil, **vars)
|
36
|
+
# Javascript pagination for uikit: it returns a nav with a data-pagy attribute used by the pagy.js file
|
37
|
+
def pagy_uikit_nav_js(pagy, id: nil, aria_label: nil, **vars)
|
39
38
|
sequels = pagy.sequels(**vars)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
39
|
+
id = %( id="#{id}") if id
|
40
|
+
a = pagy_anchor(pagy)
|
41
|
+
tokens = { 'before' => uikit_prev_html(pagy, a),
|
42
|
+
'a' => %(<li>#{a.(PAGE_TOKEN, LABEL_TOKEN)}</li>),
|
43
|
+
'current' => %(<li class="uk-active"><span role="link" aria-current="page" aria-disabled="true">#{
|
44
|
+
LABEL_TOKEN}</span></li>),
|
45
|
+
'gap' => %(<li class="uk-disabled"><span>#{pagy_t 'pagy.gap'}</span></li>),
|
46
|
+
'after' => uikit_next_html(pagy, a) }
|
48
47
|
|
49
|
-
%(<ul#{
|
50
|
-
|
51
|
-
pagy_data(pagy, :nav,
|
48
|
+
%(<ul#{id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-uikit nav-js uk-pagination uk-flex-center" role="navigation" #{
|
49
|
+
nav_aria_label(pagy, aria_label:)} #{
|
50
|
+
pagy_data(pagy, :nav, tokens, sequels, pagy.label_sequels(sequels))
|
51
|
+
}></ul>)
|
52
52
|
end
|
53
53
|
|
54
|
-
# Javascript combo pagination for uikit: it returns a nav
|
55
|
-
def pagy_uikit_combo_nav_js(pagy,
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
p_page}" style="text-align: center; width: #{p_pages.to_s.length + 1}rem;" aria-current="page">)
|
54
|
+
# Javascript combo pagination for uikit: it returns a nav with a data-pagy attribute used by the pagy.js file
|
55
|
+
def pagy_uikit_combo_nav_js(pagy, id: nil, aria_label: nil)
|
56
|
+
id = %( id="#{id}") if id
|
57
|
+
a = pagy_anchor(pagy)
|
58
|
+
pages = pagy.pages
|
59
|
+
|
60
|
+
page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page" ) <<
|
61
|
+
%(style="text-align: center; width: #{pages.to_s.length + 1}rem;">#{JSTools::A_TAG})
|
63
62
|
|
64
|
-
%(<ul#{
|
65
|
-
|
63
|
+
%(<ul#{id} class="pagy-uikit combo-nav-js uk-button-group uk-pagination uk-flex-center" role="navigation" #{
|
64
|
+
nav_aria_label(pagy, aria_label:)} #{
|
66
65
|
pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
|
67
66
|
}>#{
|
68
|
-
uikit_prev_html
|
69
|
-
}<li>#{
|
70
|
-
pagy_t
|
71
|
-
}</li>#{
|
72
|
-
uikit_next_html
|
67
|
+
uikit_prev_html(pagy, a)
|
68
|
+
}<li><label>#{
|
69
|
+
pagy_t('pagy.combo_nav_js', page_input:, pages:)
|
70
|
+
}</label></li>#{
|
71
|
+
uikit_next_html(pagy, a)
|
73
72
|
}</ul>)
|
74
73
|
end
|
75
74
|
|
76
75
|
private
|
77
76
|
|
78
|
-
def uikit_prev_html(pagy,
|
79
|
-
|
77
|
+
def uikit_prev_html(pagy, a)
|
78
|
+
span = %(<span uk-pagination-previous></span>)
|
80
79
|
if (p_prev = pagy.prev)
|
81
|
-
%(<li>#{
|
80
|
+
%(<li>#{a.(p_prev, span, aria_label: pagy_t('pagy.aria_label.prev'))}</li>)
|
82
81
|
else
|
83
|
-
%(<li class="uk-disabled"><
|
82
|
+
%(<li class="uk-disabled"><a role="link" aria-disabled="true" aria-label="#{
|
83
|
+
pagy_t('pagy.aria_label.prev')}">#{span}</a></li>)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
-
def uikit_next_html(pagy,
|
88
|
-
|
87
|
+
def uikit_next_html(pagy, a)
|
88
|
+
span = %(<span uk-pagination-next></span>)
|
89
89
|
if (p_next = pagy.next)
|
90
|
-
%(<li>#{
|
90
|
+
%(<li>#{a.(p_next, span, aria_label: pagy_t('pagy.aria_label.prev'))}</li>)
|
91
91
|
else
|
92
|
-
%(<li class="uk-disabled"><
|
92
|
+
%(<li class="uk-disabled"><a role="link" aria-disabled="true" aria-label="#{
|
93
|
+
pagy_t('pagy.aria_label.next')}">#{span}</a></li>)
|
93
94
|
end
|
94
95
|
end
|
95
96
|
end
|
data/lib/pagy/frontend.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# See Pagy::Frontend API documentation: https://ddnexus.github.io/pagy/docs/api/frontend
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
require_relative 'url_helpers'
|
5
|
+
require_relative 'i18n'
|
6
6
|
|
7
7
|
class Pagy
|
8
8
|
# Used for search and replace, hardcoded also in the pagy.js file
|
@@ -15,60 +15,56 @@ class Pagy
|
|
15
15
|
include UrlHelpers
|
16
16
|
|
17
17
|
# Generic pagination: it returns the html with the series of links to the pages
|
18
|
-
def pagy_nav(pagy,
|
19
|
-
|
20
|
-
|
21
|
-
link = pagy_link_proc(pagy, link_extra:)
|
18
|
+
def pagy_nav(pagy, id: nil, aria_label: nil, **vars)
|
19
|
+
id = %( id="#{id}") if id
|
20
|
+
a = pagy_anchor(pagy)
|
22
21
|
|
23
|
-
html =
|
24
|
-
|
22
|
+
html = %(<nav#{id} class="pagy nav" #{nav_aria_label(pagy, aria_label:)}>#{
|
23
|
+
prev_a(pagy, a)})
|
25
24
|
pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
26
25
|
html << case item
|
27
26
|
when Integer
|
28
|
-
|
27
|
+
a.(item)
|
29
28
|
when String
|
30
|
-
%(<
|
31
|
-
%(<a role="link" aria-disabled="true" aria-current="page">#{pagy.label_for(item)}</a></span>)
|
29
|
+
%(<a role="link" aria-disabled="true" aria-current="page" class="current">#{pagy.label_for(item)}</a>)
|
32
30
|
when :gap
|
33
|
-
%(<
|
31
|
+
%(<a role="link" aria-disabled="true" class="gap">#{pagy_t('pagy.gap')}</a>)
|
34
32
|
else
|
35
33
|
raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
36
34
|
end
|
37
35
|
end
|
38
|
-
html << %(#{
|
36
|
+
html << %(#{next_a(pagy, a)}</nav>)
|
39
37
|
end
|
40
38
|
|
41
39
|
# Return examples: "Displaying items 41-60 of 324 in total" or "Displaying Products 41-60 of 324 in total"
|
42
|
-
def pagy_info(pagy,
|
43
|
-
|
40
|
+
def pagy_info(pagy, id: nil, item_name: nil)
|
41
|
+
id = %( id="#{id}") if id
|
44
42
|
p_count = pagy.count
|
45
|
-
key = if
|
46
|
-
|
47
|
-
|
43
|
+
key = if p_count.zero?
|
44
|
+
'pagy.info.no_items'
|
45
|
+
elsif pagy.pages == 1
|
46
|
+
'pagy.info.single_page'
|
47
|
+
else
|
48
|
+
'pagy.info.multiple_pages'
|
48
49
|
end
|
49
50
|
|
50
|
-
%(<span#{
|
51
|
-
pagy_t key, item_name: item_name || pagy_t(
|
51
|
+
%(<span#{id} class="pagy info">#{
|
52
|
+
pagy_t key, item_name: item_name || pagy_t('pagy.item_name', count: p_count),
|
52
53
|
count: p_count, from: pagy.from, to: pagy.to
|
53
54
|
}</span>)
|
54
55
|
end
|
55
56
|
|
56
|
-
# Return a performance optimized lambda to generate the HTML
|
57
|
+
# Return a performance optimized lambda to generate the HTML anchor element (a tag)
|
57
58
|
# Benchmarked on a 20 link nav: it is ~22x faster and uses ~18x less memory than rails' link_to
|
58
|
-
def
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
left, right = %(<a href="#{pagy_url_for(pagy, PAGE_TOKEN)}" #{
|
63
|
-
pagy.vars[:link_extra]} #{link_extra}).split(PAGE_TOKEN, 2)
|
59
|
+
def pagy_anchor(pagy)
|
60
|
+
a_string = pagy.vars[:anchor_string]
|
61
|
+
a_string = %( #{a_string}) if a_string
|
62
|
+
left, right = %(<a#{a_string} href="#{pagy_url_for(pagy, PAGE_TOKEN)}").split(PAGE_TOKEN, 2)
|
64
63
|
# lambda used by all the helpers
|
65
|
-
lambda do |page, text = pagy.label_for(page),
|
66
|
-
%(#{
|
67
|
-
|
68
|
-
|
69
|
-
when p_page then ' aria-disabled="true" aria-current="page"'
|
70
|
-
else ''
|
71
|
-
end } #{extra_attrs}>#{text}</a>)
|
64
|
+
lambda do |page, text = pagy.label_for(page), classes: nil, aria_label: nil|
|
65
|
+
classes = %( class="#{classes}") if classes
|
66
|
+
aria_label = %( aria-label="#{aria_label}") if aria_label
|
67
|
+
%(#{left}#{page}#{right}#{classes}#{aria_label}>#{text}</a>)
|
72
68
|
end
|
73
69
|
end
|
74
70
|
|
@@ -80,34 +76,24 @@ class Pagy
|
|
80
76
|
|
81
77
|
private
|
82
78
|
|
83
|
-
def
|
84
|
-
|
85
|
-
%(aria-label="#{
|
86
|
-
end
|
87
|
-
|
88
|
-
def prev_aria_label_attr
|
89
|
-
%(aria-label="#{pagy_t('pagy.aria_label.prev')}")
|
90
|
-
end
|
91
|
-
|
92
|
-
def next_aria_label_attr
|
93
|
-
%(aria-label="#{pagy_t('pagy.aria_label.next')}")
|
79
|
+
def nav_aria_label(pagy, aria_label: nil)
|
80
|
+
aria_label ||= pagy_t('pagy.aria_label.nav', count: pagy.pages)
|
81
|
+
%(aria-label="#{aria_label}")
|
94
82
|
end
|
95
83
|
|
96
|
-
def
|
84
|
+
def prev_a(pagy, a, text: pagy_t('pagy.prev'), aria_label: pagy_t('pagy.aria_label.prev'))
|
97
85
|
if (p_prev = pagy.prev)
|
98
|
-
|
86
|
+
a.(p_prev, text, aria_label:)
|
99
87
|
else
|
100
|
-
%(<
|
101
|
-
prev_aria_label_attr}>#{text}</a></span>)
|
88
|
+
%(<a role="link" aria-disabled="true" aria-label="#{aria_label}">#{text}</a>)
|
102
89
|
end
|
103
90
|
end
|
104
91
|
|
105
|
-
def
|
92
|
+
def next_a(pagy, a, text: pagy_t('pagy.next'), aria_label: pagy_t('pagy.aria_label.next'))
|
106
93
|
if (p_next = pagy.next)
|
107
|
-
|
94
|
+
a.(p_next, text, aria_label:)
|
108
95
|
else
|
109
|
-
%(<
|
110
|
-
next_aria_label_attr}>#{text}</a></span>)
|
96
|
+
%(<a role="link" aria-disabled="true" aria-label="#{aria_label}">#{text}</a>)
|
111
97
|
end
|
112
98
|
end
|
113
99
|
end
|
data/lib/pagy/url_helpers.rb
CHANGED
@@ -8,20 +8,19 @@ class Pagy
|
|
8
8
|
# For non-rack environments you can use the standalone extra
|
9
9
|
def pagy_url_for(pagy, page, absolute: false, **_)
|
10
10
|
vars = pagy.vars
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
"#{request.base_url if absolute}#{request_path}#{query_string}#{vars[:fragment]}"
|
11
|
+
query_params = request.GET.clone
|
12
|
+
query_params.merge!(vars[:params].transform_keys(&:to_s)) if vars[:params].is_a?(Hash)
|
13
|
+
pagy_set_query_params(page, vars, query_params)
|
14
|
+
query_params = vars[:params].(query_params) if vars[:params].is_a?(Proc)
|
15
|
+
query_string = "?#{Rack::Utils.build_nested_query(query_params)}"
|
16
|
+
"#{request.base_url if absolute}#{vars[:request_path] || request.path}#{query_string}#{vars[:fragment]}"
|
18
17
|
end
|
19
18
|
|
20
19
|
# Add the page and items params
|
21
20
|
# Overridable by the jsonapi extra
|
22
|
-
def pagy_set_query_params(page, vars,
|
23
|
-
|
24
|
-
|
21
|
+
def pagy_set_query_params(page, vars, query_params)
|
22
|
+
query_params[vars[:page_param].to_s] = page
|
23
|
+
query_params[vars[:items_param].to_s] = vars[:items] if vars[:items_extra]
|
25
24
|
end
|
26
25
|
end
|
27
26
|
end
|