@kws3/ui 1.6.9 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.mdx +17 -0
  2. package/buttons/SubmitButton.svelte +8 -8
  3. package/controls/Checkbox.svelte +5 -5
  4. package/controls/FileUpload.svelte +4 -4
  5. package/controls/NumberInput.svelte +2 -2
  6. package/controls/ToggleButtons.svelte +1 -1
  7. package/datagrid/DataSearch/DataSearch.svelte +7 -6
  8. package/datagrid/DataSearch/SearchFilter.svelte +25 -10
  9. package/datagrid/GridView/GridCell.svelte +1 -0
  10. package/datagrid/GridView/GridRow.svelte +1 -1
  11. package/datagrid/Pagination/Pagination.svelte +119 -55
  12. package/datagrid/TileView/TileViewItem.svelte +1 -0
  13. package/forms/MaskedInput.svelte +1 -1
  14. package/forms/PasswordValidator/validatePassword.js +2 -2
  15. package/forms/actions.js +11 -8
  16. package/forms/colorpicker/Colorpicker.js +18 -13
  17. package/forms/colorpicker/Colorpicker.svelte +2 -2
  18. package/forms/select/MultiSelect.svelte +11 -13
  19. package/helpers/Dialog/Dialog.svelte +13 -14
  20. package/helpers/Divider.svelte +55 -0
  21. package/helpers/FloatingUI/Floatie.svelte +11 -5
  22. package/helpers/FloatingUI/index.js +2 -2
  23. package/helpers/Icon.svelte +1 -1
  24. package/helpers/Loader.svelte +4 -4
  25. package/helpers/Message.svelte +4 -1
  26. package/helpers/Modal.svelte +10 -2
  27. package/helpers/Nl2br.svelte +1 -1
  28. package/helpers/Notification.svelte +1 -1
  29. package/helpers/Panel.svelte +3 -1
  30. package/helpers/Popover.svelte +5 -5
  31. package/helpers/Skeleton.svelte +66 -0
  32. package/index.js +2 -0
  33. package/package.json +2 -2
  34. package/sliding-panes/SlidingPaneSet.svelte +2 -2
  35. package/styles/DataSort.scss +5 -0
  36. package/styles/Divider.scss +102 -0
  37. package/styles/Loader.scss +35 -34
  38. package/styles/RangeSlider.scss +2 -1
  39. package/styles/Skeleton.scss +52 -0
  40. package/styles/Timeline.scss +2 -1
  41. package/utils/index.js +1 -1
  42. package/utils/keyboard-events.js +3 -3
package/CHANGELOG.mdx CHANGED
@@ -1,3 +1,20 @@
1
+ ## 1.7.2
2
+ - `DatePicker` component: fix initialisation bug on mobile
3
+ - `Pagination` component: rename property `breakThreshold` -> `maxVisiblePages` plus bugfix and documentation update
4
+
5
+ ## 1.7.1
6
+ - `Skeleton` component: Illustrate in example the use of empty string for `color` prop.
7
+ - `Pagination` component: Deprecate `meta` prop. And use separate props for `offset`, `limit`, `count` and `total` instead.
8
+ - `Pagination` component: Add methods `prev()`, `next()`, `first()`, `last()` and `goto(page)`.
9
+ - New `Divider` component.
10
+ - `Modal` component can now be opened and closed programatically via `open()` and `close()` methods.
11
+ - Added linting rules for ESLint. And corrected all resulting issues.
12
+
13
+ ## 1.7.0
14
+ - Ensure uniform usage of `$kws-theme-colors` across all components, this means `$kws-theme-colors` can be independent of the global `$colors` SCSS variable.
15
+ - `DataSearch` component: Expand filters to fill area when main search input is not present.
16
+ - `DataSort` component: Increase click area for activating dropdown, and provide visual segementation between label and dropdown.
17
+ - New `Skeleton` component.
1
18
 
2
19
  ## 1.6.9
3
20
  - New `Timeline`, `TimelineItem` and `TimelineHeader` components.
@@ -15,9 +15,9 @@
15
15
  @param {number} [completion_timeout=600] - How long to wait before `saved` event is fired, and the UI state reverts back to normal, Default: `600`
16
16
  @param {number} [error_timeout=3000] - How long to wait before `error` event is fired, and the UI state reverts back to normal, Default: `3000`
17
17
  @param {string} [class=""] - CSS classes for Button container, Default: `""`
18
- @param {function} [saving()] - call this function on form saving state
19
- @param {function} [saved(callback, timeout)] - call this function after form saved
20
- @param {function} [error(callback, timeout)] - call this function on form error state
18
+ @method `saving()` - call this method on form saving state
19
+ @method `saved(callback, timeout)` - call this method after form saved
20
+ @method `error(callback, timeout)` - call this method on form error state
21
21
 
22
22
  ### Events
23
23
  - `saved` - Fired on successful submission
@@ -115,7 +115,7 @@
115
115
  export { klass as class };
116
116
 
117
117
  /**
118
- * call this function on form saving state
118
+ * call this method on form saving state
119
119
  */
120
120
  export function saving() {
121
121
  tracker = {
@@ -126,7 +126,7 @@
126
126
  }
127
127
 
128
128
  /**
129
- * call this function after form saved
129
+ * call this method after form saved
130
130
  */
131
131
  export function saved(callback, timeout = completion_timeout) {
132
132
  tracker = {
@@ -150,7 +150,7 @@
150
150
  }
151
151
 
152
152
  /**
153
- * call this function on form error state
153
+ * call this method on form error state
154
154
  */
155
155
  export function error(callback, timeout = error_timeout) {
156
156
  tracker = {
@@ -173,6 +173,6 @@
173
173
  }, timeout);
174
174
  }
175
175
 
176
- $: err_text = error_text == "" ? text : error_text;
177
- $: icon_size = size == "large" ? "" : "small";
176
+ $: err_text = error_text === "" ? text : error_text;
177
+ $: icon_size = size === "large" ? "" : "small";
178
178
  </script>
@@ -15,9 +15,9 @@ Checked\Not Checked, Default: `false`
15
15
  @param {string} [label_style=""] - Inline CSS for the Checkbox label, Default: `""`
16
16
  @param {''|'fa'|'lar'|'las'|'gg'|'unicons'} [icon_family="null"] - Icon family to be used
17
17
 
18
- Defaults to global family set via `Icon.setDefaultIconType()`
18
+ Defaults to global family set via `Icon.setDefaultIconType()`
19
19
 
20
- Ultimately defaults to `fa`, if family is not set anywhere, Default: `"null"`
20
+ Ultimately defaults to `fa`, if family is not set anywhere, Default: `"null"`
21
21
  @param {string} [class=""] - CSS classes of the Checkbox, Default: `""`
22
22
 
23
23
  ### Events
@@ -96,9 +96,9 @@ Ultimately defaults to `fa`, if family is not set anywhere, Default: `"null"`
96
96
  /**
97
97
  * Icon family to be used
98
98
  *
99
- * Defaults to global family set via `Icon.setDefaultIconType()`
99
+ * Defaults to global family set via `Icon.setDefaultIconType()`
100
100
  *
101
- * Ultimately defaults to `fa`, if family is not set anywhere
101
+ * Ultimately defaults to `fa`, if family is not set anywhere
102
102
  *
103
103
  * @type {''|'fa'|'lar'|'las'|'gg'|'unicons'}
104
104
  */
@@ -111,5 +111,5 @@ Ultimately defaults to `fa`, if family is not set anywhere, Default: `"null"`
111
111
  let klass = "";
112
112
  export { klass as class };
113
113
 
114
- $: has_icon = icon && icon != "";
114
+ $: has_icon = icon && icon !== "";
115
115
  </script>
@@ -170,7 +170,7 @@ The following functions are returned in `event.detail`:
170
170
 
171
171
  $: {
172
172
  fileTypes =
173
- allowed != "*" && Array.isArray(allowed) && allowed.length
173
+ allowed !== "*" && Array.isArray(allowed) && allowed.length
174
174
  ? allowed.join(", ")
175
175
  : "";
176
176
  _progress = Math.floor((_uploaded / _total) * 100);
@@ -256,18 +256,18 @@ The following functions are returned in `event.detail`:
256
256
  } else {
257
257
  size = 0;
258
258
  }
259
- val = val.split(/[\/\\]+/);
259
+ val = val.split(/[/\\]+/);
260
260
  val = val[val.length - 1];
261
261
  ext = val.split(/\./);
262
262
  ext = ext[ext.length - 1];
263
263
  ext = ext.toLowerCase();
264
- if (size == 0) {
264
+ if (size === 0) {
265
265
  valid = false;
266
266
  val = "No file selected";
267
267
  }
268
268
 
269
269
  //check if file extension is allowed
270
- if (allowed != "*") {
270
+ if (allowed !== "*") {
271
271
  if (typeof allowed.length != "undefined") {
272
272
  if (allowed.indexOf(ext) === -1) {
273
273
  valid = false;
@@ -183,7 +183,7 @@ This will be overridden if `min` is higher, or `max` is lower, Default: `0`
183
183
  const count = (i) => () => {
184
184
  if (typeof value == "undefined" || value === null) value = min;
185
185
  value = Number(value) + i * step;
186
- if (step % 1 != 0) value = value.toFixed(1);
186
+ if (step % 1 !== 0) value = value.toFixed(1);
187
187
  };
188
188
 
189
189
  function validateInput() {
@@ -194,7 +194,7 @@ This will be overridden if `min` is higher, or `max` is lower, Default: `0`
194
194
  if (value < min) value = min;
195
195
  if (value > max) value = max;
196
196
 
197
- if (_old_value != value) {
197
+ if (_old_value !== value) {
198
198
  _old_value = value;
199
199
  /**
200
200
  * Triggered when value changes
@@ -34,7 +34,7 @@ This property can be bound to, to fetch the current value, Default: `null`
34
34
  type="button"
35
35
  {disabled}
36
36
  on:click={setValue(option.value)}
37
- class="button is-{size} {fullwidth ? 'is-fullwidth' : ''} {value ==
37
+ class="button is-{size} {fullwidth ? 'is-fullwidth' : ''} {value ===
38
38
  option.value
39
39
  ? 'is-active ' +
40
40
  (option.active_class ? option.active_class : active_class)
@@ -23,7 +23,7 @@
23
23
  {#if hasSearch}
24
24
  <div class="control is-expanded main-search">
25
25
  <input
26
- class="input {query != '' && query != undefined
26
+ class="input {query !== '' && query !== undefined
27
27
  ? filter_in_use_class
28
28
  : filter_not_in_use_class}"
29
29
  type="text"
@@ -32,14 +32,14 @@
32
32
  </div>
33
33
  {/if}
34
34
  {#if hasFilters}
35
- {#each _filters as filter, i}
35
+ {#each _filters as filter}
36
36
  <svelte:component
37
37
  this={usedFilterComponent}
38
38
  {filterVals}
39
39
  {filter}
40
40
  {filterWidthStyle}
41
- hilightClass={filterVals[filter.name] != "" &&
42
- filterVals[filter.name] != undefined
41
+ hilightClass={filterVals[filter.name] !== "" &&
42
+ filterVals[filter.name] !== undefined
43
43
  ? filter_in_use_class
44
44
  : filter_not_in_use_class}
45
45
  {filter_label_map} />
@@ -117,7 +117,7 @@
117
117
  filterWidthStyle = "";
118
118
 
119
119
  $: usedFilterComponent = filterComponent ? filterComponent : SearchFilter;
120
- $: changed = q && q.trim() != "";
120
+ $: changed = q && q.trim() !== "";
121
121
  $: q, qHasChanged();
122
122
  $: filters, filtersHaveChanged();
123
123
 
@@ -152,7 +152,7 @@
152
152
  }
153
153
 
154
154
  function qHasChanged() {
155
- if (q == "") {
155
+ if (q === "") {
156
156
  //bail out early and reset all filters
157
157
  //this happens when using back/forward browser buttons
158
158
  return doresetSearch();
@@ -183,6 +183,7 @@
183
183
  filterVals[i] = "";
184
184
  }
185
185
  query = "";
186
+ // eslint-disable-next-line no-self-assign
186
187
  filterVals = filterVals;
187
188
 
188
189
  /**
@@ -10,8 +10,11 @@
10
10
 
11
11
  -->
12
12
 
13
- {#if filter.type == "multiselect"}
14
- <div class="control search-control" style={filterWidthStyle}>
13
+ {#if filter.type === "multiselect"}
14
+ <div
15
+ class="control search-control"
16
+ class:is-expanded={shouldExpandToFill}
17
+ style={filterWidthStyle}>
15
18
  <MultiSelect
16
19
  options={sanitizedOptions}
17
20
  placeholder={`Any ${name}`}
@@ -22,15 +25,21 @@
22
25
  summary_mode
23
26
  class={hilightClass} />
24
27
  </div>
25
- {:else if filter.type == "date"}
26
- <div class="control search-control" style={filterWidthStyle}>
28
+ {:else if filter.type === "date"}
29
+ <div
30
+ class="control search-control"
31
+ class:is-expanded={shouldExpandToFill}
32
+ style={filterWidthStyle}>
27
33
  <Datepicker
28
34
  class={hilightClass}
29
35
  bind:value={filterVals[filter.name]}
30
36
  placeholder="{capitaliseFirstLetter(name)} Date" />
31
37
  </div>
32
- {:else if filter.type == "daterange"}
33
- <div class="control search-control" style={filterWidthStyle}>
38
+ {:else if filter.type === "daterange"}
39
+ <div
40
+ class="control search-control"
41
+ class:is-expanded={shouldExpandToFill}
42
+ style={filterWidthStyle}>
34
43
  <Datepicker
35
44
  class={hilightClass}
36
45
  bind:value={filterVals[filter.name]}
@@ -38,7 +47,10 @@
38
47
  placeholder="{capitaliseFirstLetter(name)} Date Range" />
39
48
  </div>
40
49
  {:else if filter.options.length > 10}
41
- <div class="control search-control" style={filterWidthStyle}>
50
+ <div
51
+ class="control search-control"
52
+ class:is-expanded={shouldExpandToFill}
53
+ style={filterWidthStyle}>
42
54
  <SearchableSelect
43
55
  options={sanitizedOptions}
44
56
  placeholder={`Any ${name}`}
@@ -50,12 +62,13 @@
50
62
  {:else}
51
63
  <div
52
64
  class="select control search-control {hilightClass}"
65
+ class:is-expanded={shouldExpandToFill}
53
66
  style={filterWidthStyle}
54
67
  data-cy="select-container">
55
68
  <select
56
69
  bind:value={filterVals[filter.name]}
57
70
  class="is-radiusless {hilightClass}"
58
- style="max-width:100%"
71
+ style="max-width:100%;width:100%;"
59
72
  data-cy={cy}>
60
73
  {#each sanitizedOptions as option}
61
74
  {#if option}
@@ -103,6 +116,8 @@
103
116
 
104
117
  $: filterVals, filter, convertToValuesArray();
105
118
 
119
+ $: shouldExpandToFill = !filterWidthStyle || filterWidthStyle.trim() === "";
120
+
106
121
  function convertValuesToString() {
107
122
  tick().then(() => {
108
123
  filterVals[filter.name] = multiSelectValue
@@ -111,7 +126,7 @@
111
126
  });
112
127
  }
113
128
  function convertToValuesArray() {
114
- if (filter && filter.type == "multiselect") {
129
+ if (filter && filter.type === "multiselect") {
115
130
  multiSelectValue = filterVals[filter.name]
116
131
  ? filterVals[filter.name].split("|")
117
132
  : [];
@@ -122,7 +137,7 @@
122
137
  let options = filter.options || [];
123
138
  if (options.length) {
124
139
  options =
125
- filter.type == "multiselect"
140
+ filter.type === "multiselect"
126
141
  ? options
127
142
  : [{ id: "", name: `Any ${name}` }, ...options];
128
143
  options = options.map((el) => {
@@ -11,6 +11,7 @@
11
11
  -->
12
12
 
13
13
  <td class={classNames(column, row)} style={styles(column, row)}>
14
+ <!-- eslint-disable-next-line @ota-meshi/svelte/no-at-html-tags -->
14
15
  {@html transforms(column, row)}
15
16
  </td>
16
17
 
@@ -164,7 +164,7 @@
164
164
 
165
165
  function setCheckedValue() {
166
166
  checked = false;
167
- if (selectedIds.indexOf(row.id) != -1) {
167
+ if (selectedIds.indexOf(row.id) !== -1) {
168
168
  checked = true;
169
169
  }
170
170
  }
@@ -2,21 +2,36 @@
2
2
  @component
3
3
 
4
4
 
5
- @param {object} [meta={}] - Contains the total, count, limit, offset values, Default: `{}`
5
+ @param {object} [meta={}] - Object containing `total`, `count`, `limit` and `offset` values
6
+
7
+ **DEPRECATED**: Use `total`, `count`, `limit` and `offset` props instead, Default: `{}`
8
+ @param {number} [limit=0] - How many items are meant to be per page, Default: `0`
9
+ @param {number} [count=0] - How many items are actually in this page, Default: `0`
10
+ @param {number} [total=0] - Total number of items available, Default: `0`
11
+ @param {number} [offset=0] - Offset of the first item in this page, Default: `0`
6
12
  @param {boolean} [showTotal=true] - Determines whether to show total or not, Default: `true`
7
13
  @param {boolean} [showCurrent=true] - Determines whether to show current page details, Default: `true`
8
14
  @param {boolean} [showPerPage=true] - Determines whether to show per page options, Default: `true`
9
- @param {number} [breakThreshold=10] - Limit the number of visible pages in pagination, Default: `10`
15
+ @param {number} [maxVisiblePages=10] - Maximum number of consecutive pages to show in pagination after which a break is introduced in between them, Default: `10`
10
16
  @param {string} [entityName="entries"] - String to display total entries, Default: `"entries"`
11
- @param {string} [size="small"] - Size of the pagination, Default: `"small"`
17
+ @param {''|'small'|'medium'|'large'} [size="small"] - Size of the pagination elements, Default: `"small"`
12
18
  @param {boolean} [frame=false] - Determines whether to show pagination frame or not, Default: `false`
13
19
  @param {string} [iconRight="chevron-right"] - Right navigation icon, Default: `"chevron-right"`
14
20
  @param {string} [iconLeft="chevron-left"] - Left navigation icon, Default: `"chevron-left"`
15
- @param {array} [perPageOptions=[]] - Determines the number of rows displayed in a page., Default: `[]`
21
+ @param {array} [perPageOptions=[]] - Displays the options for how many items to show per page, Default: `[]`
22
+ @method `goto(targetPage)` - Go to an arbitrary page number
23
+ @method `prev()` - Go to the previous page
24
+ @method `next()` - Go to the next page
25
+ @method `first()` - Go to the first page
26
+ @method `last()` - Go to the last page
16
27
 
17
28
  ### Events
18
- - `setLimit` - Event used to set limit of pagination
19
- - `paginate` - Event triggered on paginate
29
+ - `setLimit` - Event used to set a new `limit`.
30
+
31
+ *Event Data:* `{currentPage, newLimit}`
32
+ - `paginate` - Event triggered on pagination change with new `offset` and current `limit` values.
33
+
34
+ *Event Data:* `{offset, limit}`
20
35
 
21
36
  -->
22
37
  <div
@@ -34,9 +49,7 @@
34
49
  <li>
35
50
  <button
36
51
  type="button"
37
- class="pagination-link {meta.limit == v
38
- ? 'is-current'
39
- : ''}"
52
+ class="pagination-link {_limit === v ? 'is-current' : ''}"
40
53
  on:click={() => setLimit(v)}>{k}</button>
41
54
  </li>
42
55
  {/each}
@@ -49,9 +62,8 @@
49
62
  {#if showTotal}
50
63
  <strong>Total {totalItems} {entityName}</strong>
51
64
  {:else if showCurrent}
52
- {#if meta.total > 0}Showing {meta.offset * 1 + 1} to {meta.offset *
53
- 1 +
54
- meta.count * 1}{/if}
65
+ {#if _total > 0}Showing {_offset * 1 + 1} to {_offset * 1 +
66
+ _count * 1}{/if}
55
67
  {/if}
56
68
  </div>
57
69
  {/if}
@@ -59,14 +71,14 @@
59
71
 
60
72
  {#if showCurrent && showTotal && !showPerPage}
61
73
  <div class="level-item pagination-showing">
62
- {#if meta.total > 0}
63
- Showing {meta.offset * 1 + 1} to {meta.offset * 1 + meta.count * 1}
74
+ {#if _total > 0}
75
+ Showing {_offset * 1 + 1} to {_offset * 1 + _count * 1}
64
76
  {/if}
65
77
  </div>
66
78
  {:else if showPerPage && showCurrent}
67
79
  <div class="level-item pagination-showing">
68
- {#if meta.total > 0}
69
- Showing {meta.offset * 1 + 1} to {meta.offset * 1 + meta.count * 1}
80
+ {#if _total > 0}
81
+ Showing {_offset * 1 + 1} to {_offset * 1 + _count * 1}
70
82
  {#if showTotal}
71
83
  |&nbsp;
72
84
  {/if}
@@ -82,25 +94,25 @@
82
94
  {/if}
83
95
 
84
96
  <div class="level-right">
85
- {#if meta.total > 0}
97
+ {#if _total > 0}
86
98
  <nav class="pagination is-centered {size ? 'is-' + size : ''}">
87
99
  <button
88
100
  type="button"
89
101
  on:click={prev}
90
- class="pagination-previous {meta.offset == 0 ? 'is-disabled' : ''}">
91
- <Icon {size} icon={iconLeft} />
102
+ class="pagination-previous {_offset === 0 ? 'is-disabled' : ''}">
103
+ <Icon icon={iconLeft} />
92
104
  </button>
93
105
  <button
94
106
  type="button"
95
107
  on:click={next}
96
- class="pagination-next {currentPage + 1 == totalPages
108
+ class="pagination-next {currentPage + 1 === totalPages
97
109
  ? 'is-disabled'
98
110
  : ''}">
99
- <Icon {size} icon={iconRight} />
111
+ <Icon icon={iconRight} />
100
112
  </button>
101
113
  <ul class="pagination-list" data-cy="pagination-list">
102
114
  {#each pages as page}
103
- {#if page.p == "sep"}
115
+ {#if page.p === "sep"}
104
116
  <li>
105
117
  <span class="pagination-ellipsis">&hellip;</span>
106
118
  </li>
@@ -108,7 +120,7 @@
108
120
  <li>
109
121
  <button
110
122
  type="button"
111
- class="pagination-link {page.p == currentPage
123
+ class="pagination-link {page.p === currentPage
112
124
  ? 'is-current'
113
125
  : ''}"
114
126
  on:click={() => goto(page.p + 1)}>{page.p + 1}</button>
@@ -129,15 +141,32 @@
129
141
  const fire = createEventDispatcher();
130
142
 
131
143
  /**
132
- * Contains the total, count, limit, offset values
144
+ * Object containing `total`, `count`, `limit` and `offset` values
145
+ *
146
+ * **DEPRECATED**: Use `total`, `count`, `limit` and `offset` props instead
133
147
  */
134
148
  export let meta = {
135
149
  limit: 0,
136
150
  total: 0,
137
151
  count: 0,
138
152
  offset: 0,
139
- status: "",
140
153
  },
154
+ /**
155
+ * How many items are meant to be per page
156
+ */
157
+ limit = 0,
158
+ /**
159
+ * How many items are actually in this page
160
+ */
161
+ count = 0,
162
+ /**
163
+ * Total number of items available
164
+ */
165
+ total = 0,
166
+ /**
167
+ * Offset of the first item in this page
168
+ */
169
+ offset = 0,
141
170
  /**
142
171
  * Determines whether to show total or not
143
172
  */
@@ -151,15 +180,16 @@
151
180
  */
152
181
  showPerPage = true,
153
182
  /**
154
- * Limit the number of visible pages in pagination
183
+ * Maximum number of consecutive pages to show in pagination after which a break is introduced in between them
155
184
  */
156
- breakThreshold = 10,
185
+ maxVisiblePages = 10,
157
186
  /**
158
187
  * String to display total entries
159
188
  */
160
189
  entityName = "entries",
161
190
  /**
162
- * Size of the pagination
191
+ * Size of the pagination elements
192
+ * @type {''|'small'|'medium'|'large'}
163
193
  */
164
194
  size = "small",
165
195
  /**
@@ -175,15 +205,20 @@
175
205
  */
176
206
  iconLeft = "chevron-left",
177
207
  /**
178
- * Determines the number of rows displayed in a page.
208
+ * Displays the options for how many items to show per page
179
209
  */
180
210
  perPageOptions = [20, 50, 100, 150, 200, 250];
181
211
 
182
212
  let pages = [],
183
213
  _perPageOptions = 0;
184
214
 
215
+ $: _total = total || meta.total || 0;
216
+ $: _count = count || meta.count || 0;
217
+ $: _offset = offset || meta.offset || 0;
218
+ $: _limit = limit || meta.limit || 0;
219
+
185
220
  $: {
186
- let max = meta.total,
221
+ let max = _total,
187
222
  ppo = perPageOptions || [],
188
223
  ppmax = Math.max(...ppo),
189
224
  ret = {};
@@ -204,10 +239,10 @@
204
239
  _perPageOptions = ret;
205
240
  }
206
241
 
207
- $: totalItems = meta && meta.total ? meta.total : 0;
208
- $: currentPage = Math.floor(meta.offset / meta.limit);
209
- $: totalPages = Math.ceil(meta.total / (meta.limit || 1));
210
- $: totalPages, currentPage, breakThreshold, calculatePages();
242
+ $: totalItems = meta && _total ? _total : 0;
243
+ $: currentPage = Math.floor(_offset / _limit);
244
+ $: totalPages = Math.ceil(_total / (_limit || 1));
245
+ $: totalPages, currentPage, maxVisiblePages, calculatePages();
211
246
 
212
247
  function calculatePages() {
213
248
  pages = new Array(totalPages || 0);
@@ -216,17 +251,21 @@
216
251
  ret = [];
217
252
 
218
253
  for (var i = 0; i < total; i++) {
219
- if (total > breakThreshold) {
220
- if (i < 3) {
254
+ if (total > maxVisiblePages) {
255
+ let threshold = Math.max(
256
+ Math.floor(maxVisiblePages / 3),
257
+ Math.min(3, maxVisiblePages - 3)
258
+ );
259
+ if (i < threshold) {
221
260
  ret.push({ p: i });
222
- } else if (i > total - 4) {
261
+ } else if (i >= total - threshold) {
223
262
  ret.push({ p: i });
224
- } else if (i == Math.floor(total / 2)) {
263
+ } else if (i === Math.floor(total / 2)) {
225
264
  ret.push({ p: i });
226
265
  } else if (
227
- i == currentPage ||
228
- i == currentPage - 1 ||
229
- i == currentPage + 1
266
+ i === currentPage ||
267
+ i === currentPage - 1 ||
268
+ i === currentPage + 1
230
269
  ) {
231
270
  ret.push({ p: i });
232
271
  }
@@ -237,10 +276,10 @@
237
276
 
238
277
  let _prev = 0,
239
278
  items = []; // _prev was prev
240
- if (total > breakThreshold) {
279
+ if (total > maxVisiblePages) {
241
280
  for (var j = 0; j < ret.length; j++) {
242
281
  var page = ret[j].p;
243
- if (page != _prev + 1 && page != 0) {
282
+ if (page !== _prev + 1 && page !== 0) {
244
283
  items.push({ p: "sep" });
245
284
  }
246
285
  items.push(ret[j]);
@@ -255,31 +294,56 @@
255
294
 
256
295
  function setLimit(limit) {
257
296
  /**
258
- * Event used to set limit of pagination
297
+ * Event used to set a new `limit`.
298
+ *
299
+ * *Event Data:* `{currentPage, newLimit}`
259
300
  */
260
301
  fire("setLimit", { currentPage, newLimit: limit });
261
302
  }
262
- function goto(pagenum) {
263
- let limit = meta.limit,
264
- i = pagenum - 1,
265
- offset = limit * i;
266
- if (offset >= 0 && offset != meta.offset && offset < meta.total) {
303
+
304
+ /**
305
+ * Go to an arbitrary page number
306
+ * @param {int} targetPage
307
+ */
308
+ export function goto(targetPage) {
309
+ let limit = _limit,
310
+ i = targetPage - 1,
311
+ __offset = limit * i;
312
+ if (__offset >= 0 && __offset !== _offset && __offset < _total) {
267
313
  /**
268
- * Event triggered on paginate
314
+ * Event triggered on pagination change with new `offset` and current `limit` values.
315
+ *
316
+ * *Event Data:* `{offset, limit}`
269
317
  */
270
- fire("paginate", { offset, limit });
318
+ fire("paginate", { offset: __offset, limit });
271
319
  }
272
320
  }
273
- function prev() {
321
+
322
+ /**
323
+ * Go to the previous page
324
+ */
325
+ export function prev() {
274
326
  goto(currentPage);
275
327
  }
276
- function next() {
328
+
329
+ /**
330
+ * Go to the next page
331
+ */
332
+ export function next() {
277
333
  goto(currentPage + 2);
278
334
  }
279
- function first() {
335
+
336
+ /**
337
+ * Go to the first page
338
+ */
339
+ export function first() {
280
340
  goto(1);
281
341
  }
282
- function last() {
342
+
343
+ /**
344
+ * Go to the last page
345
+ */
346
+ export function last() {
283
347
  goto(totalPages);
284
348
  }
285
349
  </script>
@@ -22,6 +22,7 @@
22
22
  {#each column_keys as column}
23
23
  {#if isVisible(column)}
24
24
  <div class={classNames(column, row)} style={styles(column, row)}>
25
+ <!-- eslint-disable-next-line @ota-meshi/svelte/no-at-html-tags -->
25
26
  {@html transforms(column, row)}
26
27
  </div>
27
28
  {/if}
@@ -32,7 +32,7 @@ Requires `guide` to be `true`, Default: `false`
32
32
  bind:this={inputElement} />
33
33
 
34
34
  <script>
35
- import { onMount, tick } from "svelte";
35
+ import { onMount } from "svelte";
36
36
  import {
37
37
  createTextMaskInputElement,
38
38
  conformToMask,