@bagelink/vue 1.15.65 → 1.15.71
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.
- package/dist/components/Pagination.vue.d.ts +6 -2
- package/dist/components/Pagination.vue.d.ts.map +1 -1
- package/dist/components/charts/ChartTooltip.vue.d.ts +0 -8
- package/dist/components/charts/ChartTooltip.vue.d.ts.map +1 -1
- package/dist/components/charts/Donut.vue.d.ts.map +1 -1
- package/dist/i18n/index.d.ts +10 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/index.cjs +31 -31
- package/dist/index.mjs +5995 -5965
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/Pagination.vue +65 -41
- package/src/components/charts/ChartTooltip.vue +5 -1
- package/src/components/charts/Donut.vue +3 -1
- package/src/components/layout/SidebarNavItem.vue +1 -1
- package/src/i18n/locales/en.json +6 -1
- package/src/i18n/locales/he.json +6 -1
package/package.json
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import type { Option } from '@bagelink/vue'
|
|
3
|
+
import { Btn, SelectInput, useI18n } from '@bagelink/vue'
|
|
3
4
|
import { computed, ref, watch, nextTick } from 'vue'
|
|
5
|
+
import { getOptionValue } from '../utils/options'
|
|
4
6
|
|
|
5
7
|
interface Range {
|
|
6
8
|
start: number
|
|
@@ -9,25 +11,38 @@ interface Range {
|
|
|
9
11
|
|
|
10
12
|
interface PaginationProps {
|
|
11
13
|
totalItems: number
|
|
12
|
-
perPage?: number
|
|
13
14
|
totalPages?: number
|
|
14
15
|
variant?: 'default' | 'simple'
|
|
15
16
|
rtl?: boolean
|
|
16
17
|
maxVisiblePages?: number
|
|
18
|
+
/** When set, renders a "per page" selector with these choices. */
|
|
19
|
+
perPageOptions?: number[]
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
const props = withDefaults(defineProps<PaginationProps>(), {
|
|
20
23
|
totalItems: 0,
|
|
21
|
-
perPage: 25,
|
|
22
24
|
totalPages: undefined,
|
|
23
25
|
variant: 'default',
|
|
24
26
|
rtl: false,
|
|
25
|
-
maxVisiblePages: 3
|
|
27
|
+
maxVisiblePages: 3,
|
|
28
|
+
perPageOptions: undefined,
|
|
26
29
|
})
|
|
27
30
|
|
|
31
|
+
const { $t } = useI18n()
|
|
32
|
+
|
|
28
33
|
const page = defineModel<number>('page', { default: 1 })
|
|
34
|
+
const perPage = defineModel<number>('perPage', { default: 25 })
|
|
29
35
|
const range = defineModel<Range>('range')
|
|
30
36
|
|
|
37
|
+
// Update how many items show per page, then jump back to the first page.
|
|
38
|
+
function onPerPageChange(opt: Option | Option[] | undefined) {
|
|
39
|
+
const v = Number(getOptionValue(Array.isArray(opt) ? opt[0] : opt))
|
|
40
|
+
if (!Number.isNaN(v) && v > 0) {
|
|
41
|
+
perPage.value = v
|
|
42
|
+
page.value = 1
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
31
46
|
const paginationContainer = ref<HTMLElement>()
|
|
32
47
|
const indicatorPosition = ref(0)
|
|
33
48
|
const indicatorWidth = ref(0)
|
|
@@ -35,18 +50,16 @@ const indicatorWidth = ref(0)
|
|
|
35
50
|
// Calculate totalPages from totalItems and perPage if not provided directly
|
|
36
51
|
const computedTotalPages = computed(() => {
|
|
37
52
|
if (props.totalPages !== undefined) { return props.totalPages }
|
|
38
|
-
|
|
39
|
-
return Math.max(1, Math.ceil(props.totalItems / perPage))
|
|
53
|
+
return Math.max(1, Math.ceil(props.totalItems / perPage.value))
|
|
40
54
|
})
|
|
41
55
|
|
|
42
56
|
watch(
|
|
43
|
-
[() => page.value, () =>
|
|
57
|
+
[() => page.value, () => perPage.value, () => props.totalItems],
|
|
44
58
|
() => {
|
|
45
59
|
if (range.value) {
|
|
46
|
-
const { perPage } = props
|
|
47
60
|
// Calculate zero-based indices
|
|
48
|
-
const start = (page.value - 1) * perPage
|
|
49
|
-
const end = Math.min(start + perPage - 1, props.totalItems - 1)
|
|
61
|
+
const start = (page.value - 1) * perPage.value
|
|
62
|
+
const end = Math.min(start + perPage.value - 1, props.totalItems - 1)
|
|
50
63
|
range.value = { start, end }
|
|
51
64
|
}
|
|
52
65
|
// Update indicator position when page changes
|
|
@@ -187,41 +200,52 @@ const renderPageButtons = computed(() => {
|
|
|
187
200
|
</script>
|
|
188
201
|
|
|
189
202
|
<template>
|
|
190
|
-
<div v-if="computedTotalPages > 1
|
|
191
|
-
<!--
|
|
192
|
-
<
|
|
193
|
-
<
|
|
194
|
-
|
|
195
|
-
:
|
|
196
|
-
|
|
197
|
-
width: `${indicatorWidth}px`,
|
|
198
|
-
}"
|
|
203
|
+
<div v-if="computedTotalPages > 1 || perPageOptions" class="flex gap-1 align-items-center justify-content-between">
|
|
204
|
+
<!-- Per-page selector -->
|
|
205
|
+
<label v-if="perPageOptions" class="flex gap-05 align-items-center txt14 nowrap">
|
|
206
|
+
<span class="color-gray">{{ $t('pagination.perPage') }}</span>
|
|
207
|
+
<SelectInput
|
|
208
|
+
thin border :options="perPageOptions" :model-value="perPage"
|
|
209
|
+
@update:model-value="onPerPageChange"
|
|
199
210
|
/>
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
211
|
+
</label>
|
|
212
|
+
|
|
213
|
+
<div v-if="computedTotalPages > 1" ref="paginationContainer" class="relative flex gap-1 justify-content">
|
|
214
|
+
<!-- Default pagination with page numbers -->
|
|
215
|
+
<template v-if="variant !== 'simple'">
|
|
216
|
+
<div
|
|
217
|
+
class="indicator radius-1"
|
|
218
|
+
:style="{
|
|
219
|
+
[rtl ? 'right' : 'left']: `${indicatorPosition}px`,
|
|
220
|
+
width: `${indicatorWidth}px`,
|
|
221
|
+
}"
|
|
208
222
|
/>
|
|
223
|
+
<!-- Render the page buttons and ellipses in order -->
|
|
224
|
+
<template v-for="item in renderPageButtons" :key="item.key">
|
|
225
|
+
<!-- Page button -->
|
|
226
|
+
<Btn
|
|
227
|
+
v-if="item.type === 'page'" flat thin
|
|
228
|
+
:class="{ selected: item.number === page }"
|
|
229
|
+
:value="item.number ? item.number.toString() : ''"
|
|
230
|
+
@click="item.number ? handleClick(item.number) : null"
|
|
231
|
+
/>
|
|
232
|
+
|
|
233
|
+
<!-- Ellipsis -->
|
|
234
|
+
<div v-else-if="item.type === 'ellipsis'" class="pagination-ellipsis">
|
|
235
|
+
...
|
|
236
|
+
</div>
|
|
237
|
+
</template>
|
|
238
|
+
</template>
|
|
209
239
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
240
|
+
<!-- Simple pagination with prev/next buttons -->
|
|
241
|
+
<template v-else>
|
|
242
|
+
<Btn flat thin :disabled="page <= 1" icon="chevron_left" @click="prev" />
|
|
243
|
+
<span class="pagination-info">
|
|
244
|
+
{{ displayIndex(range?.start) }}-{{ displayIndex(range?.end) }} / {{ props.totalItems }}
|
|
245
|
+
</span>
|
|
246
|
+
<Btn flat thin :disabled="page >= computedTotalPages" icon="chevron_right" @click="next" />
|
|
214
247
|
</template>
|
|
215
|
-
</
|
|
216
|
-
|
|
217
|
-
<!-- Simple pagination with prev/next buttons -->
|
|
218
|
-
<template v-else>
|
|
219
|
-
<Btn flat thin :disabled="page <= 1" icon="chevron_left" @click="prev" />
|
|
220
|
-
<span class="pagination-info">
|
|
221
|
-
{{ displayIndex(range?.start) }}-{{ displayIndex(range?.end) }} / {{ props.totalItems }}
|
|
222
|
-
</span>
|
|
223
|
-
<Btn flat thin :disabled="page >= computedTotalPages" icon="chevron_right" @click="next" />
|
|
224
|
-
</template>
|
|
248
|
+
</div>
|
|
225
249
|
</div>
|
|
226
250
|
</template>
|
|
227
251
|
|
|
@@ -7,11 +7,15 @@
|
|
|
7
7
|
* Positioned by the host via `style` (absolute left/top); the host owns
|
|
8
8
|
* mouse tracking. Non-interactive (pointer-events: none).
|
|
9
9
|
*/
|
|
10
|
+
import { useI18n } from '@bagelink/vue'
|
|
11
|
+
|
|
10
12
|
export interface TipRow { name: string; color?: string; value: string }
|
|
11
13
|
export interface TipStat { label: string; value: string }
|
|
12
14
|
|
|
13
15
|
defineOptions({ name: 'BglChartTooltip' })
|
|
14
16
|
|
|
17
|
+
const { $t } = useI18n()
|
|
18
|
+
|
|
15
19
|
withDefaults(defineProps<{
|
|
16
20
|
label?: string
|
|
17
21
|
/** Big focal number (used by single-value charts like the funnel). */
|
|
@@ -39,7 +43,7 @@ withDefaults(defineProps<{
|
|
|
39
43
|
</p>
|
|
40
44
|
|
|
41
45
|
<p v-if="total" class="bgl-tip__row bgl-tip__total flex align-items-center m-0">
|
|
42
|
-
<span class="bgl-tip__name">
|
|
46
|
+
<span class="bgl-tip__name">{{ $t('charts.total') }}</span>
|
|
43
47
|
<span class="bgl-tip__val tabular-nums">{{ total }}</span>
|
|
44
48
|
</p>
|
|
45
49
|
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* <Donut :data="segments" :legend-value="false" /> // legend shows only %
|
|
11
11
|
*/
|
|
12
12
|
import { computed, ref } from 'vue'
|
|
13
|
+
import { useI18n } from '@bagelink/vue'
|
|
13
14
|
import { ramp, resolveColor } from './core/palette'
|
|
14
15
|
import { formatValue, type ValueFormat } from './core/format'
|
|
15
16
|
import { useChartAnim } from './core/useChartAnim'
|
|
@@ -63,6 +64,7 @@ const props = withDefaults(defineProps<{
|
|
|
63
64
|
animated: true,
|
|
64
65
|
})
|
|
65
66
|
|
|
67
|
+
const { $t } = useI18n()
|
|
66
68
|
const el = ref<HTMLElement>()
|
|
67
69
|
const { progress } = useChartAnim({ el, enabled: props.animated, duration: 800 })
|
|
68
70
|
|
|
@@ -153,7 +155,7 @@ function onMove(e: MouseEvent) {
|
|
|
153
155
|
}
|
|
154
156
|
const hoverArc = computed(() => (hoverIdx.value == null ? null : arcs.value[hoverIdx.value]))
|
|
155
157
|
const hoverValue = computed(() => (hoverArc.value ? fmtValue(hoverArc.value.value) : ''))
|
|
156
|
-
const hoverStats = computed(() => (hoverArc.value ? [{ label: '
|
|
158
|
+
const hoverStats = computed(() => (hoverArc.value ? [{ label: $t('charts.share'), value: `${hoverArc.value.pct.toFixed(0)}%` }] : []))
|
|
157
159
|
const tooltipStyle = computed(() => ({ left: `${tipX.value}px`, top: `${tipY.value}px` }))
|
|
158
160
|
</script>
|
|
159
161
|
|
|
@@ -92,7 +92,7 @@ function onParentClick() {
|
|
|
92
92
|
>
|
|
93
93
|
<Icon :name="link.icon" size="1.2" />
|
|
94
94
|
<span class="nav-text flex-grow">{{ resolveI18n(link.label) }}</span>
|
|
95
|
-
<Icon name="expand_more" size="1.1" class="nav-text sidebar-chevron" :class="{ 'sidebar-chevron-open': expanded }" />
|
|
95
|
+
<Icon name="expand_more" size="1.1" class="nav-text sidebar-chevron line-height-1" :class="{ 'sidebar-chevron-open': expanded }" />
|
|
96
96
|
</Btn>
|
|
97
97
|
<div class="sidebar-children" :class="{ 'sidebar-children-open': expanded }">
|
|
98
98
|
<div class="sidebar-children-inner ps-1">
|
package/src/i18n/locales/en.json
CHANGED
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"pagination": {
|
|
18
18
|
"of": "of",
|
|
19
19
|
"prev": "Previous",
|
|
20
|
-
"next": "Next"
|
|
20
|
+
"next": "Next",
|
|
21
|
+
"perPage": "Per page"
|
|
21
22
|
},
|
|
22
23
|
"form": {
|
|
23
24
|
"required": "This field is required",
|
|
@@ -491,5 +492,9 @@
|
|
|
491
492
|
"office365": "Office 365",
|
|
492
493
|
"yahoo": "Yahoo Calendar",
|
|
493
494
|
"ics": "Calendar (ICS file)"
|
|
495
|
+
},
|
|
496
|
+
"charts": {
|
|
497
|
+
"total": "Total",
|
|
498
|
+
"share": "Share"
|
|
494
499
|
}
|
|
495
500
|
}
|
package/src/i18n/locales/he.json
CHANGED
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"pagination": {
|
|
18
18
|
"of": "מתוך",
|
|
19
19
|
"prev": "הקודם",
|
|
20
|
-
"next": "הבא"
|
|
20
|
+
"next": "הבא",
|
|
21
|
+
"perPage": "פריטים לעמוד"
|
|
21
22
|
},
|
|
22
23
|
"form": {
|
|
23
24
|
"required": "שדה זה נדרש",
|
|
@@ -512,5 +513,9 @@
|
|
|
512
513
|
"office365": "Office 365",
|
|
513
514
|
"yahoo": "יומן Yahoo",
|
|
514
515
|
"ics": "יומן (קובץ ICS)"
|
|
516
|
+
},
|
|
517
|
+
"charts": {
|
|
518
|
+
"total": "סה״כ",
|
|
519
|
+
"share": "חלק"
|
|
515
520
|
}
|
|
516
521
|
}
|