pagy 3.10.0 → 5.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/lib/config/pagy.rb +121 -52
- data/lib/javascripts/pagy-dev.js +117 -0
- data/lib/javascripts/pagy.js +1 -106
- data/lib/javascripts/pagy.mjs +118 -0
- data/lib/locales/ar.yml +26 -0
- data/lib/locales/bg.yml +2 -2
- data/lib/locales/bs.yml +24 -0
- data/lib/locales/ca.yml +2 -2
- data/lib/locales/cs.yml +2 -2
- data/lib/locales/da.yml +2 -2
- data/lib/locales/de.yml +2 -2
- data/lib/locales/en.yml +2 -2
- data/lib/locales/es.yml +2 -2
- data/lib/locales/fr.yml +2 -2
- data/lib/locales/hr.yml +24 -0
- data/lib/locales/id.yml +2 -2
- data/lib/locales/it.yml +2 -2
- data/lib/locales/ja.yml +2 -2
- data/lib/locales/km.yml +2 -2
- data/lib/locales/ko.yml +2 -2
- data/lib/locales/nb.yml +2 -2
- data/lib/locales/nl.yml +2 -2
- data/lib/locales/pl.yml +2 -2
- data/lib/locales/pt-BR.yml +2 -2
- data/lib/locales/pt.yml +2 -2
- data/lib/locales/ru.yml +2 -2
- data/lib/locales/sr.yml +23 -0
- data/lib/locales/sv-SE.yml +2 -2
- data/lib/locales/sv.yml +2 -2
- data/lib/locales/sw.yml +22 -0
- data/lib/locales/ta.yml +22 -0
- data/lib/locales/tr.yml +2 -2
- data/lib/locales/uk.yml +24 -0
- data/lib/locales/zh-CN.yml +2 -2
- data/lib/locales/zh-HK.yml +2 -2
- data/lib/locales/zh-TW.yml +3 -3
- data/lib/pagy/backend.rb +11 -12
- data/lib/pagy/calendar/day.rb +29 -0
- data/lib/pagy/calendar/month.rb +16 -0
- data/lib/pagy/calendar/month_mixin.rb +49 -0
- data/lib/pagy/calendar/quarter.rb +23 -0
- data/lib/pagy/calendar/week.rb +39 -0
- data/lib/pagy/calendar/year.rb +29 -0
- data/lib/pagy/calendar.rb +90 -0
- data/lib/pagy/console.rb +23 -0
- data/lib/pagy/countless.rb +23 -19
- data/lib/pagy/exceptions.rb +16 -13
- data/lib/pagy/extras/arel.rb +12 -7
- data/lib/pagy/extras/array.rb +10 -9
- data/lib/pagy/extras/bootstrap.rb +77 -39
- data/lib/pagy/extras/bulma.rb +77 -43
- data/lib/pagy/extras/calendar.rb +66 -0
- data/lib/pagy/extras/countless.rb +17 -17
- data/lib/pagy/extras/elasticsearch_rails.rb +66 -37
- data/lib/pagy/extras/foundation.rb +74 -41
- data/lib/pagy/extras/frontend_helpers.rb +70 -0
- data/lib/pagy/extras/gearbox.rb +42 -0
- data/lib/pagy/extras/headers.rb +32 -18
- data/lib/pagy/extras/i18n.rb +18 -17
- data/lib/pagy/extras/items.rb +42 -53
- data/lib/pagy/extras/materialize.rb +68 -43
- data/lib/pagy/extras/meilisearch.rb +61 -0
- data/lib/pagy/extras/metadata.rb +27 -26
- data/lib/pagy/extras/navs.rb +54 -29
- data/lib/pagy/extras/overflow.rb +57 -52
- data/lib/pagy/extras/searchkick.rb +54 -36
- data/lib/pagy/extras/semantic.rb +66 -39
- data/lib/pagy/extras/standalone.rb +64 -0
- data/lib/pagy/extras/support.rb +34 -17
- data/lib/pagy/extras/trim.rb +18 -12
- data/lib/pagy/extras/uikit.rb +66 -44
- data/lib/pagy/frontend.rb +61 -53
- data/lib/pagy/i18n.rb +164 -0
- data/lib/pagy/url_helpers.rb +38 -0
- data/lib/pagy.rb +96 -30
- data/lib/templates/bootstrap_nav.html.erb +1 -1
- data/lib/templates/bootstrap_nav.html.haml +1 -1
- data/lib/templates/bootstrap_nav.html.slim +1 -1
- data/lib/templates/foundation_nav.html.erb +1 -1
- data/lib/templates/foundation_nav.html.haml +1 -1
- data/lib/templates/foundation_nav.html.slim +1 -1
- data/lib/templates/uikit_nav.html.erb +2 -2
- data/lib/templates/uikit_nav.html.haml +1 -1
- data/lib/templates/uikit_nav.html.slim +2 -2
- metadata +37 -16
- data/lib/locales/README.md +0 -35
- data/lib/locales/utils/i18n.rb +0 -25
- data/lib/locales/utils/loader.rb +0 -34
- data/lib/locales/utils/p11n.rb +0 -88
- data/lib/pagy/extras/pagy_search.rb +0 -18
- data/lib/pagy/extras/shared.rb +0 -53
- data/pagy.gemspec +0 -16
@@ -0,0 +1,90 @@
|
|
1
|
+
# See Pagy::Countless API documentation: https://ddnexus.github.io/pagy/api/calendar
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'pagy'
|
5
|
+
|
6
|
+
class Pagy # :nodoc:
|
7
|
+
# Base class for time units subclasses (Year, Quarter, Month, Week, Day)
|
8
|
+
class Calendar < Pagy
|
9
|
+
# List of units in desc order of duration. It can be used for custom units.
|
10
|
+
UNITS = %i[year quarter month week day] # rubocop:disable Style/MutableConstant
|
11
|
+
DAY = 60 * 60 * 24 # One day in seconds
|
12
|
+
WEEK = DAY * 7 # One week in seconds
|
13
|
+
|
14
|
+
attr_reader :order
|
15
|
+
|
16
|
+
# Merge and validate the options, do some simple arithmetic and set a few instance variables
|
17
|
+
def initialize(vars) # rubocop:disable Lint/MissingSuper
|
18
|
+
raise InternalError, 'Pagy::Calendar is a base class; use one of its subclasses' if instance_of?(Pagy::Calendar)
|
19
|
+
|
20
|
+
vars = self.class::DEFAULT.merge(vars) # subclass specific default
|
21
|
+
normalize_vars(vars) # general default
|
22
|
+
setup_vars(page: 1)
|
23
|
+
setup_unit_vars
|
24
|
+
setup_params_var
|
25
|
+
raise OverflowError.new(self, :page, "in 1..#{@last}", @page) if @page > @last
|
26
|
+
|
27
|
+
@prev = (@page - 1 unless @page == 1)
|
28
|
+
@next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
|
29
|
+
end
|
30
|
+
|
31
|
+
# The label for the current page (it can pass along the I18n gem opts when it's used with the i18n extra)
|
32
|
+
def label(opts = {})
|
33
|
+
label_for(@page, opts)
|
34
|
+
end
|
35
|
+
|
36
|
+
# The label for any page (it can pass along the I18n gem opts when it's used with the i18n extra)
|
37
|
+
def label_for(page, opts = {})
|
38
|
+
opts[:format] ||= @vars[:format]
|
39
|
+
localize(starting_time_for(page.to_i), opts) # page could be a string
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
# Base class method for the setup of the unit variables (subclasses must implement it and call super)
|
45
|
+
def setup_unit_vars
|
46
|
+
raise VariableError.new(self, :format, 'to be a strftime format', @vars[:format]) unless @vars[:format].is_a?(String)
|
47
|
+
raise VariableError.new(self, :order, 'to be in [:asc, :desc]', @order) \
|
48
|
+
unless %i[asc desc].include?(@order = @vars[:order])
|
49
|
+
|
50
|
+
@starting, @ending = @vars[:period]
|
51
|
+
raise VariableError.new(self, :period, 'to be a an Array of min and max local Time instances', @vars[:period]) \
|
52
|
+
unless @starting.is_a?(Time) && @ending.is_a?(Time) && !@starting.utc? && !@ending.utc? && @starting <= @ending \
|
53
|
+
&& (@utc_offset = @starting.utc_offset) == @ending.utc_offset
|
54
|
+
end
|
55
|
+
|
56
|
+
# Apply the strftime format to the time (overridden by the i18n extra when localization is required)
|
57
|
+
def localize(time, opts)
|
58
|
+
time.strftime(opts[:format])
|
59
|
+
end
|
60
|
+
|
61
|
+
# Number of units to offset from the @initial time, in order to get the ordered starting time for the page.
|
62
|
+
# Used in starting_time_for(page) with a logic equivalent to: @initial + (offset_units_for(page) * unit_time_length)
|
63
|
+
def offset_units_for(page)
|
64
|
+
@order == :asc ? page - 1 : @pages - page
|
65
|
+
end
|
66
|
+
|
67
|
+
# Create a new local time at the beginning of the day
|
68
|
+
def new_time(year, month = 1, day = 1)
|
69
|
+
Time.new(year, month, day, 0, 0, 0, @utc_offset)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Period of the active page (used internally for nested units)
|
73
|
+
def active_period
|
74
|
+
[[@starting, @from].max, [@to - 1, @ending].min] # -1 sec: include only last unit day
|
75
|
+
end
|
76
|
+
|
77
|
+
class << self
|
78
|
+
# Create a subclass instance by unit name (internal use)
|
79
|
+
def create(unit, vars)
|
80
|
+
raise InternalError, "unit must be in #{UNITS.inspect}; got #{unit}" unless UNITS.include?(unit)
|
81
|
+
|
82
|
+
name = unit.to_s
|
83
|
+
name[0] = name[0].capitalize
|
84
|
+
Object.const_get("Pagy::Calendar::#{name}").new(vars)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
# Require the subclass files in UNITS (no custom unit at this point yet)
|
89
|
+
Calendar::UNITS.each { |unit| require "pagy/calendar/#{unit}" }
|
90
|
+
end
|
data/lib/pagy/console.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# See Pagy::Console API documentation: https://ddnexus.github.io/pagy/api/console
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'pagy' # so you can require just the extra in the console
|
5
|
+
require 'pagy/extras/standalone'
|
6
|
+
|
7
|
+
class Pagy
|
8
|
+
# Provide a ready to use pagy environment when included in irb/rails console
|
9
|
+
module Console
|
10
|
+
# Include Backend, Frontend and set the default URL
|
11
|
+
def self.included(main)
|
12
|
+
main.include(Backend)
|
13
|
+
main.include(Frontend)
|
14
|
+
DEFAULT[:url] = 'http://www.example.com/subdir'
|
15
|
+
end
|
16
|
+
|
17
|
+
# Require the extras passed as arguments
|
18
|
+
def pagy_extras(*extras)
|
19
|
+
extras.each { |extra| require "pagy/extras/#{extra}" }
|
20
|
+
puts "Required extras: #{extras.map(&:inspect).join(', ')}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/pagy/countless.rb
CHANGED
@@ -1,33 +1,37 @@
|
|
1
|
-
#
|
1
|
+
# See Pagy::Countless API documentation: https://ddnexus.github.io/pagy/api/countless
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'pagy'
|
5
5
|
|
6
6
|
class Pagy
|
7
|
-
|
7
|
+
# No need to know the count to paginate
|
8
8
|
class Countless < Pagy
|
9
|
-
|
10
9
|
# Merge and validate the options, do some simple arithmetic and set a few instance variables
|
11
|
-
def initialize(vars={})
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
@offset = @items * (@page - 1) + @outset # pagination offset + outset (initial offset)
|
10
|
+
def initialize(vars = {}) # rubocop:disable Lint/MissingSuper
|
11
|
+
normalize_vars(vars)
|
12
|
+
setup_vars(page: 1, outset: 0)
|
13
|
+
setup_items_var
|
14
|
+
setup_params_var
|
15
|
+
@offset = (@items * (@page - 1)) + @outset
|
18
16
|
end
|
19
17
|
|
20
|
-
# Finalize the instance variables based on the fetched
|
21
|
-
def finalize(
|
22
|
-
|
23
|
-
|
24
|
-
@
|
25
|
-
@
|
26
|
-
@
|
27
|
-
@
|
28
|
-
@
|
18
|
+
# Finalize the instance variables based on the fetched size
|
19
|
+
def finalize(fetched_size)
|
20
|
+
raise OverflowError.new(self, :page, "to be < #{@page}", @page) if fetched_size.zero? && @page > 1
|
21
|
+
|
22
|
+
@pages = @last = (fetched_size > @items ? @page + 1 : @page)
|
23
|
+
@in = [fetched_size, @items].min
|
24
|
+
@from = @in.zero? ? 0 : @offset - @outset + 1
|
25
|
+
@to = @offset - @outset + @in
|
26
|
+
@prev = (@page - 1 unless @page == 1)
|
27
|
+
@next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
|
29
28
|
self
|
30
29
|
end
|
31
30
|
|
31
|
+
# Override the original series.
|
32
|
+
# Return nil if :countless_minimal is enabled
|
33
|
+
def series(*)
|
34
|
+
super unless @vars[:countless_minimal]
|
35
|
+
end
|
32
36
|
end
|
33
37
|
end
|
data/lib/pagy/exceptions.rb
CHANGED
@@ -1,22 +1,25 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
class Pagy
|
4
|
+
# Generic variable error
|
3
5
|
class VariableError < ArgumentError
|
4
|
-
attr_reader :pagy
|
5
|
-
|
6
|
-
def initialize(pagy)
|
7
|
-
@pagy = pagy
|
8
|
-
end
|
6
|
+
attr_reader :pagy, :variable, :value
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
pagy.vars[variable]
|
8
|
+
# Set the variables and prepare the message
|
9
|
+
def initialize(pagy, variable, description, value)
|
10
|
+
@pagy = pagy
|
11
|
+
@variable = variable
|
12
|
+
@value = value
|
13
|
+
super "expected :#{@variable} #{description}; got #{@value.inspect}"
|
17
14
|
end
|
18
15
|
end
|
19
16
|
|
17
|
+
# Specific overflow error
|
20
18
|
class OverflowError < VariableError; end
|
21
19
|
|
20
|
+
# I18n configuration error
|
21
|
+
class I18nError < StandardError; end
|
22
|
+
|
23
|
+
# Generic internal error
|
24
|
+
class InternalError < StandardError; end
|
22
25
|
end
|
data/lib/pagy/extras/arel.rb
CHANGED
@@ -1,21 +1,26 @@
|
|
1
1
|
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/arel
|
2
|
-
# encoding: utf-8
|
3
2
|
# frozen_string_literal: true
|
4
3
|
|
5
|
-
class Pagy
|
6
|
-
|
4
|
+
class Pagy # :nodoc:
|
5
|
+
# Better performance of grouped ActiveRecord collections
|
6
|
+
module ArelExtra
|
7
|
+
private
|
7
8
|
|
8
|
-
|
9
|
+
# Return Pagy object and paginated collection/results
|
10
|
+
def pagy_arel(collection, vars = {})
|
9
11
|
pagy = Pagy.new(pagy_arel_get_vars(collection, vars))
|
10
|
-
|
12
|
+
[pagy, pagy_get_items(collection, pagy)]
|
11
13
|
end
|
12
14
|
|
15
|
+
# Sub-method called only by #pagy_arel: here for easy customization of variables by overriding
|
13
16
|
def pagy_arel_get_vars(collection, vars)
|
17
|
+
pagy_set_items_from_params(vars) if defined?(ItemsExtra)
|
14
18
|
vars[:count] ||= pagy_arel_count(collection)
|
15
|
-
vars[:page] ||= params[
|
19
|
+
vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
|
16
20
|
vars
|
17
21
|
end
|
18
22
|
|
23
|
+
# Count using Arel when grouping
|
19
24
|
def pagy_arel_count(collection)
|
20
25
|
if collection.group_values.empty?
|
21
26
|
# COUNT(*)
|
@@ -26,6 +31,6 @@ class Pagy
|
|
26
31
|
collection.unscope(:order).limit(1).pluck(sql).first.to_i
|
27
32
|
end
|
28
33
|
end
|
29
|
-
|
30
34
|
end
|
35
|
+
Backend.prepend ArelExtra
|
31
36
|
end
|
data/lib/pagy/extras/array.rb
CHANGED
@@ -1,23 +1,24 @@
|
|
1
1
|
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/array
|
2
|
-
# encoding: utf-8
|
3
2
|
# frozen_string_literal: true
|
4
3
|
|
5
|
-
class Pagy
|
6
|
-
#
|
7
|
-
module
|
4
|
+
class Pagy # :nodoc:
|
5
|
+
# Paginate arrays efficiently, avoiding expensive array-wrapping and without overriding
|
6
|
+
module ArrayExtra
|
7
|
+
private
|
8
8
|
|
9
|
-
# Return Pagy object and items
|
10
|
-
def pagy_array(array, vars={})
|
9
|
+
# Return Pagy object and paginated items
|
10
|
+
def pagy_array(array, vars = {})
|
11
11
|
pagy = Pagy.new(pagy_array_get_vars(array, vars))
|
12
|
-
|
12
|
+
[pagy, array[pagy.offset, pagy.items]]
|
13
13
|
end
|
14
14
|
|
15
15
|
# Sub-method called only by #pagy_array: here for easy customization of variables by overriding
|
16
16
|
def pagy_array_get_vars(array, vars)
|
17
|
+
pagy_set_items_from_params(vars) if defined?(ItemsExtra)
|
17
18
|
vars[:count] ||= array.size
|
18
|
-
vars[:page] ||= params[
|
19
|
+
vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
|
19
20
|
vars
|
20
21
|
end
|
21
|
-
|
22
22
|
end
|
23
|
+
Backend.prepend ArrayExtra
|
23
24
|
end
|
@@ -1,55 +1,93 @@
|
|
1
1
|
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/bootstrap
|
2
|
-
# encoding: utf-8
|
3
2
|
# frozen_string_literal: true
|
4
3
|
|
5
|
-
require 'pagy/extras/
|
6
|
-
|
7
|
-
class Pagy
|
8
|
-
module Frontend
|
4
|
+
require 'pagy/extras/frontend_helpers'
|
9
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
10
|
# Pagination for bootstrap: it returns the html with the series of links to the pages
|
11
|
-
def pagy_bootstrap_nav(pagy)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
def pagy_bootstrap_nav(pagy, pagy_id: nil, link_extra: '', **vars)
|
12
|
+
p_id = %( id="#{pagy_id}") if pagy_id
|
13
|
+
link = pagy_link_proc(pagy, link_extra: %(class="page-link" #{link_extra}))
|
14
|
+
|
15
|
+
html = +%(<nav#{p_id} class="pagy-bootstrap-nav" aria-label="pager"><ul class="pagination">)
|
16
|
+
html << pagy_bootstrap_prev_html(pagy, link)
|
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">#{link.call item}</li>)
|
21
|
+
when String
|
22
|
+
%(<li class="page-item active">#{link.call item}</li>)
|
23
|
+
when :gap
|
24
|
+
%(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>)
|
25
|
+
else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
20
26
|
end
|
21
27
|
end
|
22
|
-
html << (
|
23
|
-
|
24
|
-
%(<nav class="pagy-bootstrap-nav" role="navigation" aria-label="pager"><ul class="pagination">#{html}</ul></nav>)
|
28
|
+
html << pagy_bootstrap_next_html(pagy, link)
|
29
|
+
html << %(</ul></nav>)
|
25
30
|
end
|
26
31
|
|
27
|
-
# Javascript pagination for bootstrap: it returns a nav and a JSON tag used by the
|
28
|
-
def pagy_bootstrap_nav_js(pagy,
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
# 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)
|
34
|
+
sequels = pagy.sequels(**vars)
|
35
|
+
p_id = %( id="#{pagy_id}") if pagy_id
|
36
|
+
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>),
|
33
39
|
'active' => %(<li class="page-item active">#{mark}</li>),
|
34
|
-
'gap' => %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t
|
35
|
-
'after' =>
|
36
|
-
|
37
|
-
%(<nav
|
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>) }
|
42
|
+
|
43
|
+
%(<nav#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-bootstrap-nav-js" aria-label="pager" #{
|
44
|
+
pagy_json_attr(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))}></nav>)
|
45
|
+
end
|
46
|
+
|
47
|
+
# 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: '')
|
49
|
+
p_id = %( id="#{pagy_id}") if pagy_id
|
50
|
+
link = pagy_link_proc(pagy, link_extra: link_extra)
|
51
|
+
p_page = pagy.page
|
52
|
+
p_pages = pagy.pages
|
53
|
+
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;">)
|
56
|
+
|
57
|
+
%(<nav#{p_id} class="pagy-bootstrap-combo-nav-js pagination" aria-label="pager"><div class="btn-group" role="group" #{
|
58
|
+
pagy_json_attr pagy, :combo, pagy_marked_link(link)}>#{
|
59
|
+
if (p_prev = pagy.prev)
|
60
|
+
link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous" class="prev btn btn-primary"'
|
61
|
+
else
|
62
|
+
%(<a class="prev btn btn-primary disabled" href="#">#{pagy_t('pagy.nav.prev')}</a>)
|
63
|
+
end
|
64
|
+
}<div class="pagy-combo-input btn btn-primary disabled" style="white-space: nowrap;">#{
|
65
|
+
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"'
|
68
|
+
else
|
69
|
+
%(<a class="next btn btn-primary disabled" href="#">#{pagy_t 'pagy.nav.next'}</a>)
|
70
|
+
end
|
71
|
+
}</div></nav>)
|
38
72
|
end
|
39
73
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
html << %(<div class="pagy-combo-input btn btn-primary disabled" style="white-space: nowrap;">#{pagy_t('pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages)}</div>)
|
49
|
-
html << (p_next ? link.call(p_next, pagy_t('pagy.nav.next'), 'aria-label="next" class="next btn btn-primary"')
|
50
|
-
: %(<a class="next btn btn-primary disabled" href="#">#{pagy_t('pagy.nav.next')}</a>))
|
51
|
-
html << %(</div></nav>#{pagy_json_tag(:combo_nav, id, p_page, pagy_marked_link(link), defined?(TRIM) && pagy.vars[:page_param])})
|
74
|
+
private
|
75
|
+
|
76
|
+
def pagy_bootstrap_prev_html(pagy, link)
|
77
|
+
if (p_prev = pagy.prev)
|
78
|
+
%(<li class="page-item prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</li>)
|
79
|
+
else
|
80
|
+
%(<li class="page-item prev disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.prev'}</a></li>)
|
81
|
+
end
|
52
82
|
end
|
53
83
|
|
84
|
+
def pagy_bootstrap_next_html(pagy, link)
|
85
|
+
if (p_next = pagy.next)
|
86
|
+
%(<li class="page-item next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</li>)
|
87
|
+
else
|
88
|
+
%(<li class="page-item next disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.next'}</a></li>)
|
89
|
+
end
|
90
|
+
end
|
54
91
|
end
|
92
|
+
Frontend.prepend BootstrapExtra
|
55
93
|
end
|
data/lib/pagy/extras/bulma.rb
CHANGED
@@ -1,60 +1,94 @@
|
|
1
1
|
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/bulma
|
2
|
-
# encoding: utf-8
|
3
2
|
# frozen_string_literal: true
|
4
3
|
|
5
|
-
require 'pagy/extras/
|
4
|
+
require 'pagy/extras/frontend_helpers'
|
6
5
|
|
7
|
-
class Pagy
|
8
|
-
|
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, pagy_id: nil, link_extra: '', **vars)
|
12
|
+
p_id = %( id="#{pagy_id}") if pagy_id
|
13
|
+
link = pagy_link_proc(pagy, link_extra: link_extra)
|
9
14
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
html = +%(<nav#{p_id} class="pagy-bulma-nav pagination is-centered" aria-label="pagination">)
|
16
|
+
html << pagy_bulma_prev_next_html(pagy, link)
|
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>#{link.call item, pagy.label_for(item), %(class="pagination-link" aria-label="goto page #{item}")}</li>)
|
22
|
+
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>)
|
25
|
+
when :gap
|
26
|
+
%(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.nav.gap'}</span></li>)
|
27
|
+
else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
23
28
|
end
|
24
29
|
end
|
25
|
-
html <<
|
26
|
-
%(<nav class="pagy-bulma-nav pagination is-centered" role="navigation" aria-label="pagination">#{html}</nav>)
|
30
|
+
html << %(</ul></nav>)
|
27
31
|
end
|
28
32
|
|
29
33
|
# Javascript pagination for bulma: it returns a nav and a JSON tag used by the Pagy.nav javascript
|
30
|
-
def pagy_bulma_nav_js(pagy,
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
'
|
38
|
-
|
39
|
-
|
34
|
+
def pagy_bulma_nav_js(pagy, pagy_id: nil, link_extra: '', **vars)
|
35
|
+
sequels = pagy.sequels(**vars)
|
36
|
+
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>),
|
40
45
|
'after' => '</ul>' }
|
41
|
-
|
46
|
+
|
47
|
+
%(<nav#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-bulma-nav-js pagination is-centered" aria-label="pagination" #{
|
48
|
+
pagy_json_attr(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))}></nav>)
|
42
49
|
end
|
43
50
|
|
44
|
-
# Javascript combo pagination for
|
45
|
-
def pagy_bulma_combo_nav_js(pagy,
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
html
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
# 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: '')
|
53
|
+
p_id = %( id="#{pagy_id}") if pagy_id
|
54
|
+
link = pagy_link_proc(pagy, link_extra: link_extra)
|
55
|
+
p_page = pagy.page
|
56
|
+
p_pages = pagy.pages
|
57
|
+
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;">)
|
59
|
+
|
60
|
+
html = %(<nav#{p_id} class="pagy-bulma-combo-nav-js" aria-label="pagination">)
|
61
|
+
%(#{html}<div class="field is-grouped is-grouped-centered" role="group" #{
|
62
|
+
pagy_json_attr pagy, :combo, pagy_marked_link(link)}>#{
|
63
|
+
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>)
|
65
|
+
else
|
66
|
+
%(<p class="control"><a class="button" disabled>#{pagy_t 'pagy.nav.prev'}</a></p>)
|
67
|
+
end
|
68
|
+
}<div class="pagy-combo-input control level is-mobile">#{
|
69
|
+
pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</div>#{
|
70
|
+
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>)
|
72
|
+
else
|
73
|
+
%(<p class="control"><a class="button" disabled>#{pagy_t 'pagy.nav.next'}</a></p>)
|
74
|
+
end
|
75
|
+
}</div></nav>)
|
57
76
|
end
|
58
77
|
|
78
|
+
private
|
79
|
+
|
80
|
+
def pagy_bulma_prev_next_html(pagy, link)
|
81
|
+
html = +if (p_prev = pagy.prev)
|
82
|
+
link.call p_prev, pagy_t('pagy.nav.prev'), 'class="pagination-previous" aria-label="previous page"'
|
83
|
+
else
|
84
|
+
%(<a class="pagination-previous" disabled>#{pagy_t 'pagy.nav.prev'}</a>)
|
85
|
+
end
|
86
|
+
html << if (p_next = pagy.next)
|
87
|
+
link.call p_next, pagy_t('pagy.nav.next'), 'class="pagination-next" aria-label="next page"'
|
88
|
+
else
|
89
|
+
%(<a class="pagination-next" disabled>#{pagy_t 'pagy.nav.next'}</a>)
|
90
|
+
end
|
91
|
+
end
|
59
92
|
end
|
93
|
+
Frontend.prepend BulmaExtra
|
60
94
|
end
|