@conduction/nextcloud-vue 2.93.0 → 2.94.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.
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js +1 -1
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js +2 -1
- package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue.js +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js +28 -8
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +37 -2
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
- package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue.js +1 -1
- package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js +139 -3
- package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue3.js +60 -12
- package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +91 -36
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +115 -72
- package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +32 -3
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +7 -7
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +141 -7
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +5 -2
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue.js +8 -0
- package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue.js.map +1 -0
- package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue2.js +114 -0
- package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue2.js.map +1 -0
- package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue3.js +45 -0
- package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue3.js.map +1 -0
- package/dist/esm/components/CnPageHeader/CnPageHeader.vue2.js +38 -2
- package/dist/esm/components/CnPageHeader/CnPageHeader.vue2.js.map +1 -1
- package/dist/esm/components/CnPageHeader/CnPageHeader.vue3.js +12 -2
- package/dist/esm/components/CnPageHeader/CnPageHeader.vue3.js.map +1 -1
- package/dist/esm/components/CnPagination/CnPagination.vue2.js.map +1 -1
- package/dist/esm/components/CnPagination/CnPagination.vue3.js +56 -51
- package/dist/esm/components/CnPagination/CnPagination.vue3.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +3 -3
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue.js +1 -1
- package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js +24 -0
- package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js.map +1 -1
- package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js +3 -1
- package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue.js +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue2.js +39 -2
- package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
- package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +85 -8
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +37 -9
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue.js +1 -1
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue2.js.map +1 -1
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js +4 -3
- package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue.js +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +20 -0
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js +31 -20
- package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
- package/dist/esm/composables/indexSources.js +9 -0
- package/dist/esm/composables/indexSources.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +402 -262
- package/dist/esm/utils/dueText.js +49 -8
- package/dist/esm/utils/dueText.js.map +1 -1
- package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +5779 -4827
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +402 -262
- package/package.json +1 -1
- package/src/components/CnActionsMenu/CnActionsMenu.vue +3 -1
- package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +39 -1
- package/src/components/CnCountdownWidget/CnCountdownWidget.vue +222 -6
- package/src/components/CnDashboardPage/CnDashboardPage.vue +96 -2
- package/src/components/CnDataTable/CnDataTable.md +1 -0
- package/src/components/CnDataTable/CnDataTable.vue +39 -10
- package/src/components/CnIndexPage/CnIndexPage.vue +144 -7
- package/src/components/CnPageHeader/CnHeaderTrail.vue +140 -0
- package/src/components/CnPageHeader/CnPageHeader.md +11 -0
- package/src/components/CnPageHeader/CnPageHeader.vue +42 -0
- package/src/components/CnPagination/CnPagination.vue +10 -2
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +3 -3
- package/src/components/CnSettingsPage/CnSettingsPage.vue +26 -0
- package/src/components/CnTabs/CnTabs.vue +39 -2
- package/src/components/CnTabsWidget/CnTabsWidget.vue +106 -13
- package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +4 -3
- package/src/components/CnWidgetWrapper/CnWidgetWrapper.md +8 -0
- package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +31 -2
- package/src/composables/indexSources.js +9 -0
- package/src/css/dialog.css +14 -0
- package/src/css/look-board-index.css +27 -1
- package/src/css/look-board.css +27 -0
- package/src/css/page-header.css +16 -0
- package/src/schemas/app-manifest-v2.schema.json +22 -15
- package/src/utils/dueText.js +49 -8
- package/src/utils/validateManifestV2.compiled.js +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnHeaderTrail.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import __sfc_main from '../CnBreadcrumbs/CnBreadcrumbs.vue.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The breadcrumb and meta line under a page title: "Instellingen / Zaaktypen
|
|
5
|
+
* · 12 zaaktypen". It draws the same markup and classes as the board look's
|
|
6
|
+
* detail header row, so a list, dashboard or settings page carries the
|
|
7
|
+
* detail page's breadcrumb style rather than one of its own.
|
|
8
|
+
*
|
|
9
|
+
* `breadcrumb` is one crumb or a list, each `{ label, route?, params?, href?,
|
|
10
|
+
* icon?, separator? }`. The page title follows as the current crumb.
|
|
11
|
+
*/
|
|
12
|
+
var script = {
|
|
13
|
+
name: 'CnHeaderTrail',
|
|
14
|
+
|
|
15
|
+
components: { CnBreadcrumbs: __sfc_main },
|
|
16
|
+
|
|
17
|
+
inject: {
|
|
18
|
+
cnTranslate: { default: () => (key) => key },
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
props: {
|
|
22
|
+
/**
|
|
23
|
+
* The crumbs before the current page, one object or a list.
|
|
24
|
+
*
|
|
25
|
+
* @type {object|Array<object>|null}
|
|
26
|
+
* @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note
|
|
27
|
+
*/
|
|
28
|
+
breadcrumb: {
|
|
29
|
+
type: [Object, Array],
|
|
30
|
+
default: null,
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
/** The current crumb: the page title, already translated. */
|
|
34
|
+
current: {
|
|
35
|
+
type: String,
|
|
36
|
+
default: '',
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The note after the crumbs and a middle dot, already resolved.
|
|
41
|
+
*
|
|
42
|
+
* @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note
|
|
43
|
+
*/
|
|
44
|
+
meta: {
|
|
45
|
+
type: String,
|
|
46
|
+
default: '',
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Translate function for the crumb labels; falls back to the injected
|
|
51
|
+
* `cnTranslate`.
|
|
52
|
+
*
|
|
53
|
+
* @type {((key: string) => string)|null}
|
|
54
|
+
*/
|
|
55
|
+
translate: {
|
|
56
|
+
type: Function,
|
|
57
|
+
default: null,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
computed: {
|
|
62
|
+
/**
|
|
63
|
+
* The declared crumbs that carry a label.
|
|
64
|
+
*
|
|
65
|
+
* @return {Array<object>}
|
|
66
|
+
*/
|
|
67
|
+
declared() {
|
|
68
|
+
const list = Array.isArray(this.breadcrumb) ? this.breadcrumb : (this.breadcrumb ? [this.breadcrumb] : []);
|
|
69
|
+
return list.filter((crumb) => crumb && typeof crumb.label === 'string' && crumb.label !== '')
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The crumbs for CnBreadcrumbs: each declared crumb as a link, then the
|
|
74
|
+
* current page. Empty without a declared crumb.
|
|
75
|
+
*
|
|
76
|
+
* @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note
|
|
77
|
+
* @return {Array<object>}
|
|
78
|
+
*/
|
|
79
|
+
crumbs() {
|
|
80
|
+
if (this.declared.length === 0) {
|
|
81
|
+
return []
|
|
82
|
+
}
|
|
83
|
+
const out = this.declared.map((crumb) => {
|
|
84
|
+
const entry = { label: (this.translate ?? this.cnTranslate)(crumb.label) };
|
|
85
|
+
if (typeof crumb.icon === 'string' && crumb.icon !== '') {
|
|
86
|
+
entry.icon = crumb.icon;
|
|
87
|
+
}
|
|
88
|
+
if (crumb.route) {
|
|
89
|
+
entry.to = { name: crumb.route, ...(crumb.params ? { params: crumb.params } : {}) };
|
|
90
|
+
} else if (crumb.href) {
|
|
91
|
+
entry.href = crumb.href;
|
|
92
|
+
}
|
|
93
|
+
return entry
|
|
94
|
+
});
|
|
95
|
+
if (this.current) {
|
|
96
|
+
out.push({ label: this.current });
|
|
97
|
+
}
|
|
98
|
+
return out
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* The text between the crumbs: the first crumb's `separator`, else `/`.
|
|
103
|
+
*
|
|
104
|
+
* @return {string}
|
|
105
|
+
*/
|
|
106
|
+
separator() {
|
|
107
|
+
const declared = this.declared[0] && this.declared[0].separator;
|
|
108
|
+
return typeof declared === 'string' && declared !== '' ? declared : '/'
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export { script as default };
|
|
114
|
+
//# sourceMappingURL=CnHeaderTrail.vue2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnHeaderTrail.vue2.js","sources":["../../../../src/components/CnPageHeader/CnHeaderTrail.vue"],"sourcesContent":["<!--\n SPDX-FileCopyrightText: 2026 Conduction B.V.\n SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<div\n\t\tv-if=\"crumbs.length > 0 || meta\"\n\t\tclass=\"cn-header-trail cn-detail-page__header-row2\"\n\t\tdata-testid=\"cn-header-trail\">\n\t\t<CnBreadcrumbs\n\t\t\tv-if=\"crumbs.length > 0\"\n\t\t\tclass=\"cn-detail-page__breadcrumbs cn-detail-page__breadcrumbs--row2\"\n\t\t\t:crumbs=\"crumbs\"\n\t\t\t:rootText=\"crumbs[0].icon === undefined\"\n\t\t\t:separator=\"separator\"\n\t\t\tdata-testid=\"cn-header-trail-breadcrumbs\" />\n\t\t<span\n\t\t\tv-if=\"crumbs.length > 0 && meta\"\n\t\t\tclass=\"cn-detail-page__header-dot\"\n\t\t\taria-hidden=\"true\">·</span>\n\t\t<span\n\t\t\tv-if=\"meta\"\n\t\t\tclass=\"cn-detail-page__header-meta\"\n\t\t\tdata-testid=\"cn-header-trail-meta\">{{ meta }}</span>\n\t</div>\n</template>\n\n<script>\nimport { CnBreadcrumbs } from '../CnBreadcrumbs/index.js'\n\n/**\n * The breadcrumb and meta line under a page title: \"Instellingen / Zaaktypen\n * · 12 zaaktypen\". It draws the same markup and classes as the board look's\n * detail header row, so a list, dashboard or settings page carries the\n * detail page's breadcrumb style rather than one of its own.\n *\n * `breadcrumb` is one crumb or a list, each `{ label, route?, params?, href?,\n * icon?, separator? }`. The page title follows as the current crumb.\n */\nexport default {\n\tname: 'CnHeaderTrail',\n\n\tcomponents: { CnBreadcrumbs },\n\n\tinject: {\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The crumbs before the current page, one object or a list.\n\t\t *\n\t\t * @type {object|Array<object>|null}\n\t\t * @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note\n\t\t */\n\t\tbreadcrumb: {\n\t\t\ttype: [Object, Array],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** The current crumb: the page title, already translated. */\n\t\tcurrent: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The note after the crumbs and a middle dot, already resolved.\n\t\t *\n\t\t * @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note\n\t\t */\n\t\tmeta: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Translate function for the crumb labels; falls back to the injected\n\t\t * `cnTranslate`.\n\t\t *\n\t\t * @type {((key: string) => string)|null}\n\t\t */\n\t\ttranslate: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The declared crumbs that carry a label.\n\t\t *\n\t\t * @return {Array<object>}\n\t\t */\n\t\tdeclared() {\n\t\t\tconst list = Array.isArray(this.breadcrumb) ? this.breadcrumb : (this.breadcrumb ? [this.breadcrumb] : [])\n\t\t\treturn list.filter((crumb) => crumb && typeof crumb.label === 'string' && crumb.label !== '')\n\t\t},\n\n\t\t/**\n\t\t * The crumbs for CnBreadcrumbs: each declared crumb as a link, then the\n\t\t * current page. Empty without a declared crumb.\n\t\t *\n\t\t * @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note\n\t\t * @return {Array<object>}\n\t\t */\n\t\tcrumbs() {\n\t\t\tif (this.declared.length === 0) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst out = this.declared.map((crumb) => {\n\t\t\t\tconst entry = { label: (this.translate ?? this.cnTranslate)(crumb.label) }\n\t\t\t\tif (typeof crumb.icon === 'string' && crumb.icon !== '') {\n\t\t\t\t\tentry.icon = crumb.icon\n\t\t\t\t}\n\t\t\t\tif (crumb.route) {\n\t\t\t\t\tentry.to = { name: crumb.route, ...(crumb.params ? { params: crumb.params } : {}) }\n\t\t\t\t} else if (crumb.href) {\n\t\t\t\t\tentry.href = crumb.href\n\t\t\t\t}\n\t\t\t\treturn entry\n\t\t\t})\n\t\t\tif (this.current) {\n\t\t\t\tout.push({ label: this.current })\n\t\t\t}\n\t\t\treturn out\n\t\t},\n\n\t\t/**\n\t\t * The text between the crumbs: the first crumb's `separator`, else `/`.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tseparator() {\n\t\t\tconst declared = this.declared[0] && this.declared[0].separator\n\t\t\treturn typeof declared === 'string' && declared !== '' ? declared : '/'\n\t\t},\n\t},\n}\n</script>\n"],"names":["CnBreadcrumbs"],"mappings":";;AA8BA;AACC;;;;AAIA;AACA;;;AAGD,aAAe;AACd,CAAA,IAAI,EAAE,eAAe;;CAErB,UAAU,EAAE,iBAAEA,UAAY,EAAG;;AAE7B,CAAA,MAAM,EAAE;AACP,EAAA,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,KAAK,KAAK;EAC5C;;AAED,CAAA,KAAK,EAAE;AACN;;AAEC;AACA;AACA;;EAED,UAAU,EAAE;AACX,GAAA,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC;GACrB,OAAO,EAAE,IAAI;GACb;;;AAGD,EAAA,OAAO,EAAE;GACR,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;AAED;;AAEC;AACA;;EAED,IAAI,EAAE;GACL,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;AAED;;AAEC;AACA;AACA;;EAED,SAAS,EAAE;GACV,IAAI,EAAE,QAAQ;GACd,OAAO,EAAE,IAAI;GACb;EACD;;AAED,CAAA,QAAQ,EAAE;AACT;AACC;AACA;;;EAGD,QAAQ,GAAG;GACV,MAAM,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAE,GAAE,IAAI,CAAC,UAAS,IAAK,IAAI,CAAC,UAAW,GAAE,CAAC,IAAI,CAAC,UAAU,CAAE,GAAE,EAAE,EAAA;AACzG,GAAA,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,SAAS,OAAO,KAAK,CAAC,KAAM,KAAI,QAAO,IAAK,KAAK,CAAC,KAAI,KAAM,EAAE,CAAA;GAC5F;;AAED;;AAEC;AACA;AACA;;;AAGD,EAAA,MAAM,GAAG;GACR,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAK,KAAM,CAAC,EAAE;AAC/B,IAAA,OAAO,EAAC;AACT,IAAA;AACA,GAAA,MAAM,GAAE,GAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK;AACxC,IAAA,MAAM,KAAM,GAAE,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,SAAU,IAAG,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAE,GAAA;IACzE,IAAI,OAAO,KAAK,CAAC,IAAK,KAAI,QAAO,IAAK,KAAK,CAAC,IAAG,KAAM,EAAE,EAAE;AACxD,KAAA,KAAK,CAAC,IAAG,GAAI,KAAK,CAAC,KAAG;AACvB,KAAA;AACA,IAAA,IAAI,KAAK,CAAC,KAAK,EAAE;AAChB,KAAA,KAAK,CAAC,EAAG,GAAE,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,KAAK,CAAC,MAAK,GAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAO,EAAA,GAAI,EAAE,CAAE,GAAA;AACnF,KAAA,MAAO,IAAI,KAAK,CAAC,IAAI,EAAE;AACtB,KAAA,KAAK,CAAC,IAAG,GAAI,KAAK,CAAC,KAAG;AACvB,KAAA;IACA,OAAO,KAAI;IACX,EAAA;AACD,GAAA,IAAI,IAAI,CAAC,OAAO,EAAE;IACjB,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,OAAM,EAAG,EAAA;AACjC,IAAA;AACA,GAAA,OAAO,GAAE;GACT;;AAED;;AAEC;AACA;;EAED,SAAS,GAAG;GACX,MAAM,QAAO,GAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAE,IAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAQ;GAC9D,OAAO,OAAO,QAAS,KAAI,QAAS,IAAG,QAAS,KAAI,EAAG,GAAE,QAAO,GAAI,GAAE;GACtE;EACD;AACF;;;;"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { resolveComponent, openBlock, createElementBlock, createBlock, createCommentVNode, toDisplayString } from 'vue';
|
|
2
|
+
|
|
3
|
+
const _hoisted_1 = {
|
|
4
|
+
key: 0,
|
|
5
|
+
class: "cn-header-trail cn-detail-page__header-row2",
|
|
6
|
+
"data-testid": "cn-header-trail"
|
|
7
|
+
};
|
|
8
|
+
const _hoisted_2 = {
|
|
9
|
+
key: 1,
|
|
10
|
+
class: "cn-detail-page__header-dot",
|
|
11
|
+
"aria-hidden": "true"
|
|
12
|
+
};
|
|
13
|
+
const _hoisted_3 = {
|
|
14
|
+
key: 2,
|
|
15
|
+
class: "cn-detail-page__header-meta",
|
|
16
|
+
"data-testid": "cn-header-trail-meta"
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
20
|
+
const _component_CnBreadcrumbs = resolveComponent("CnBreadcrumbs");
|
|
21
|
+
|
|
22
|
+
return ($options.crumbs.length > 0 || $props.meta)
|
|
23
|
+
? (openBlock(), createElementBlock("div", _hoisted_1, [
|
|
24
|
+
($options.crumbs.length > 0)
|
|
25
|
+
? (openBlock(), createBlock(_component_CnBreadcrumbs, {
|
|
26
|
+
key: 0,
|
|
27
|
+
class: "cn-detail-page__breadcrumbs cn-detail-page__breadcrumbs--row2",
|
|
28
|
+
crumbs: $options.crumbs,
|
|
29
|
+
rootText: $options.crumbs[0].icon === undefined,
|
|
30
|
+
separator: $options.separator,
|
|
31
|
+
"data-testid": "cn-header-trail-breadcrumbs"
|
|
32
|
+
}, null, 8 /* PROPS */, ["crumbs", "rootText", "separator"]))
|
|
33
|
+
: createCommentVNode("v-if", true),
|
|
34
|
+
($options.crumbs.length > 0 && $props.meta)
|
|
35
|
+
? (openBlock(), createElementBlock("span", _hoisted_2, "·"))
|
|
36
|
+
: createCommentVNode("v-if", true),
|
|
37
|
+
($props.meta)
|
|
38
|
+
? (openBlock(), createElementBlock("span", _hoisted_3, toDisplayString($props.meta), 1 /* TEXT */))
|
|
39
|
+
: createCommentVNode("v-if", true)
|
|
40
|
+
]))
|
|
41
|
+
: createCommentVNode("v-if", true)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { render };
|
|
45
|
+
//# sourceMappingURL=CnHeaderTrail.vue3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CnHeaderTrail.vue3.js","sources":["../../../../src/components/CnPageHeader/CnHeaderTrail.vue?vue&type=template&id=34f48930&lang.js"],"sourcesContent":["<!--\n SPDX-FileCopyrightText: 2026 Conduction B.V.\n SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<div\n\t\tv-if=\"crumbs.length > 0 || meta\"\n\t\tclass=\"cn-header-trail cn-detail-page__header-row2\"\n\t\tdata-testid=\"cn-header-trail\">\n\t\t<CnBreadcrumbs\n\t\t\tv-if=\"crumbs.length > 0\"\n\t\t\tclass=\"cn-detail-page__breadcrumbs cn-detail-page__breadcrumbs--row2\"\n\t\t\t:crumbs=\"crumbs\"\n\t\t\t:rootText=\"crumbs[0].icon === undefined\"\n\t\t\t:separator=\"separator\"\n\t\t\tdata-testid=\"cn-header-trail-breadcrumbs\" />\n\t\t<span\n\t\t\tv-if=\"crumbs.length > 0 && meta\"\n\t\t\tclass=\"cn-detail-page__header-dot\"\n\t\t\taria-hidden=\"true\">·</span>\n\t\t<span\n\t\t\tv-if=\"meta\"\n\t\t\tclass=\"cn-detail-page__header-meta\"\n\t\t\tdata-testid=\"cn-header-trail-meta\">{{ meta }}</span>\n\t</div>\n</template>\n\n<script>\nimport { CnBreadcrumbs } from '../CnBreadcrumbs/index.js'\n\n/**\n * The breadcrumb and meta line under a page title: \"Instellingen / Zaaktypen\n * · 12 zaaktypen\". It draws the same markup and classes as the board look's\n * detail header row, so a list, dashboard or settings page carries the\n * detail page's breadcrumb style rather than one of its own.\n *\n * `breadcrumb` is one crumb or a list, each `{ label, route?, params?, href?,\n * icon?, separator? }`. The page title follows as the current crumb.\n */\nexport default {\n\tname: 'CnHeaderTrail',\n\n\tcomponents: { CnBreadcrumbs },\n\n\tinject: {\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/**\n\t\t * The crumbs before the current page, one object or a list.\n\t\t *\n\t\t * @type {object|Array<object>|null}\n\t\t * @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note\n\t\t */\n\t\tbreadcrumb: {\n\t\t\ttype: [Object, Array],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/** The current crumb: the page title, already translated. */\n\t\tcurrent: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * The note after the crumbs and a middle dot, already resolved.\n\t\t *\n\t\t * @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note\n\t\t */\n\t\tmeta: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * Translate function for the crumb labels; falls back to the injected\n\t\t * `cnTranslate`.\n\t\t *\n\t\t * @type {((key: string) => string)|null}\n\t\t */\n\t\ttranslate: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The declared crumbs that carry a label.\n\t\t *\n\t\t * @return {Array<object>}\n\t\t */\n\t\tdeclared() {\n\t\t\tconst list = Array.isArray(this.breadcrumb) ? this.breadcrumb : (this.breadcrumb ? [this.breadcrumb] : [])\n\t\t\treturn list.filter((crumb) => crumb && typeof crumb.label === 'string' && crumb.label !== '')\n\t\t},\n\n\t\t/**\n\t\t * The crumbs for CnBreadcrumbs: each declared crumb as a link, then the\n\t\t * current page. Empty without a declared crumb.\n\t\t *\n\t\t * @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note\n\t\t * @return {Array<object>}\n\t\t */\n\t\tcrumbs() {\n\t\t\tif (this.declared.length === 0) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst out = this.declared.map((crumb) => {\n\t\t\t\tconst entry = { label: (this.translate ?? this.cnTranslate)(crumb.label) }\n\t\t\t\tif (typeof crumb.icon === 'string' && crumb.icon !== '') {\n\t\t\t\t\tentry.icon = crumb.icon\n\t\t\t\t}\n\t\t\t\tif (crumb.route) {\n\t\t\t\t\tentry.to = { name: crumb.route, ...(crumb.params ? { params: crumb.params } : {}) }\n\t\t\t\t} else if (crumb.href) {\n\t\t\t\t\tentry.href = crumb.href\n\t\t\t\t}\n\t\t\t\treturn entry\n\t\t\t})\n\t\t\tif (this.current) {\n\t\t\t\tout.push({ label: this.current })\n\t\t\t}\n\t\t\treturn out\n\t\t},\n\n\t\t/**\n\t\t * The text between the crumbs: the first crumb's `separator`, else `/`.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tseparator() {\n\t\t\tconst declared = this.declared[0] && this.declared[0].separator\n\t\t\treturn typeof declared === 'string' && declared !== '' ? declared : '/'\n\t\t},\n\t},\n}\n</script>\n"],"names":["_createBlock","_createElementBlock"],"mappings":";;;;AAWG,EAAA,KAAI,EAAC,6CAA6C;AAClD,EAAA,aAAU,EAAC,iBAAI;;;;AAUf,EAAA,KAAK,EAAC,4BAA4B;AAClC,EAAA,aAAW,EAAC,MAAM;;;;;;;;;;;UAbb,QAAM,CAAA,MAAA,CAAC,MAAM,GAAA,CAAA,IAAK,MAAA,CAAA,IAAA;;AAIjB,QAAA,CAAA,QAAA,CAAA,MAAM,CAAC,MAAM,GAAA,CAAA;0BADnBA,WAMiC,CAAA,wBAAA,EAAA;;AAJjC,cAAA,KAAK,EAAC,+DAAqC;AAC1C,cAAA,MAAE,EAAA,QAAA,CAAA,MAAA;AACF,cAAA,QAAQ,EAAE,QAAA,CAAA,MAAM,CAAG,CAAA,CAAA,CAAA,IAAK,KAAK,SAAC;AAC9B,cAAA,SAAS,EAAE,QAAS,CAAA,SAAA;AACrB,cAAA,aAAW,EAAC,6BAAqB;;;SAE3B,QAAI,CAAA,MAAA,CAAA,MAAA,GAAA,CAAA,IAAA,MAAA,CAAA,IAAA;0BADXC,kBAGmC,CAAA,MAAA,EAHnC,UAGmC,EAAf,GAAQ,CAAA;;;0BAC5BA,2BAAA;;;;;;;;"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import __sfc_main from '
|
|
1
|
+
import __sfc_main from './CnHeaderTrail.vue.js';
|
|
2
|
+
import __sfc_main$1 from '../CnIcon/CnIcon.vue.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* CnPageHeader — Reusable page header with optional icon, title, and description.
|
|
@@ -40,7 +41,8 @@ var script = {
|
|
|
40
41
|
name: 'CnPageHeader',
|
|
41
42
|
|
|
42
43
|
components: {
|
|
43
|
-
|
|
44
|
+
CnHeaderTrail: __sfc_main,
|
|
45
|
+
CnIcon: __sfc_main$1,
|
|
44
46
|
},
|
|
45
47
|
|
|
46
48
|
inject: {
|
|
@@ -66,6 +68,31 @@ var script = {
|
|
|
66
68
|
default: '',
|
|
67
69
|
},
|
|
68
70
|
|
|
71
|
+
/**
|
|
72
|
+
* A breadcrumb under the title: one crumb or a list, each
|
|
73
|
+
* `{ label, route?, params?, href?, icon?, separator? }`. The title
|
|
74
|
+
* follows as the current crumb. Drawn as the board look's detail
|
|
75
|
+
* header row.
|
|
76
|
+
*
|
|
77
|
+
* @type {object|Array<object>|null}
|
|
78
|
+
* @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note
|
|
79
|
+
*/
|
|
80
|
+
breadcrumb: {
|
|
81
|
+
type: [Object, Array],
|
|
82
|
+
default: null,
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* A note after the breadcrumb and a middle dot, such as "12 open". Run
|
|
87
|
+
* through the host translate function.
|
|
88
|
+
*
|
|
89
|
+
* @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note
|
|
90
|
+
*/
|
|
91
|
+
meta: {
|
|
92
|
+
type: String,
|
|
93
|
+
default: '',
|
|
94
|
+
},
|
|
95
|
+
|
|
69
96
|
/** Optional MDI icon name (rendered via CnIcon) */
|
|
70
97
|
icon: {
|
|
71
98
|
type: String,
|
|
@@ -129,6 +156,15 @@ var script = {
|
|
|
129
156
|
resolvedDescription() {
|
|
130
157
|
return this.description ? this.effectiveTranslate(this.description) : this.description
|
|
131
158
|
},
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* The meta note run through the host translate function.
|
|
162
|
+
*
|
|
163
|
+
* @return {string}
|
|
164
|
+
*/
|
|
165
|
+
resolvedMeta() {
|
|
166
|
+
return this.meta ? this.effectiveTranslate(this.meta) : ''
|
|
167
|
+
},
|
|
132
168
|
},
|
|
133
169
|
};
|
|
134
170
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnPageHeader.vue2.js","sources":["../../../../src/components/CnPageHeader/CnPageHeader.vue"],"sourcesContent":["<template>\n\t<div\n\t\tclass=\"cn-page-header\"\n\t\t:class=\"[{ 'cn-page-header--visually-hidden': visuallyHidden }]\"\n\t\tdata-testid=\"cn-page-header\"\n\t\t:data-visually-hidden=\"visuallyHidden ? 'true' : null\">\n\t\t<div v-if=\"!visuallyHidden && (icon || $slots.icon)\" class=\"cn-page-header__icon\">\n\t\t\t<slot name=\"icon\">\n\t\t\t\t<CnIcon :name=\"icon\" :size=\"iconSize\" />\n\t\t\t</slot>\n\t\t</div>\n\t\t<div class=\"cn-page-header__text\">\n\t\t\t<h1 class=\"cn-page-header__title\" data-testid=\"cn-page-title\">\n\t\t\t\t{{ resolvedTitle }}\n\t\t\t</h1>\n\t\t\t<p v-if=\"description && !visuallyHidden\" class=\"cn-page-header__description\" data-testid=\"cn-page-description\">\n\t\t\t\t{{ resolvedDescription }}\n\t\t\t</p>\n\t\t</div>\n\t\t<slot v-if=\"!visuallyHidden\" name=\"extra\" />\n\t</div>\n</template>\n\n<script>\nimport { CnIcon } from '../CnIcon/index.js'\n\n/**\n * CnPageHeader — Reusable page header with optional icon, title, and description.\n *\n * ```vue\n * <CnPageHeader title=\"Clients\" description=\"Manage your clients\" icon=\"AccountGroup\" />\n * ```\n *\n * ## `visuallyHidden` — the accessible-heading mode\n *\n * Several page primitives (CnIndexPage, CnSettingsPage, CnChatPage,\n * CnFilesPage, CnLogsPage) hide their inline header by default because the\n * design surfaces the page title in the app sidebar/navigation instead. That\n * sidebar heading lives OUTSIDE the `<main>` landmark, so suppressing the\n * header entirely left the main content region with no heading at all: a\n * screen-reader user gets no announcement of which list they are on, and a\n * \"skip to main content\" jump lands on an unlabelled region (WCAG 2.4.6\n * Headings and Labels, 1.3.1 Info and Relationships).\n *\n * `visuallyHidden` resolves that without a visual change: the `<h1>` stays in\n * the DOM and in the accessibility tree, clipped to a 1px box that is removed\n * from layout flow. The decorative icon, the description and the `extra` slot\n * are NOT rendered in this mode — the icon is decorative, and the `extra` slot\n * may contain focusable controls, which must never be clipped-but-tabbable.\n *\n * ```vue\n * <CnPageHeader :title=\"title\" :visually-hidden=\"!showTitle\" />\n * ```\n *\n * ## Translation\n *\n * `title` and `description` are manifest-authored English source strings. They\n * are rendered through the host translate function — the `translate` prop when\n * given, else the `cnTranslate` provided by CnAppRoot — so a page heading\n * follows the user's language. With no translator (or a catalogue that lacks\n * the key) the source string renders unchanged.\n */\nexport default {\n\tname: 'CnPageHeader',\n\n\tcomponents: {\n\t\tCnIcon,\n\t},\n\n\tinject: {\n\t\t/**\n\t\t * Host translate function provided by CnAppRoot as\n\t\t * `cnTranslate: this.translate` (bound to the host app's id).\n\t\t * Defaults to an identity function so the component stays usable\n\t\t * standalone and an untranslated key renders as itself.\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** Page title text */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** Optional description shown below the title */\n\t\tdescription: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Optional MDI icon name (rendered via CnIcon) */\n\t\ticon: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Icon size in pixels */\n\t\ticonSize: {\n\t\t\ttype: Number,\n\t\t\tdefault: 28,\n\t\t},\n\n\t\t/**\n\t\t * Render the `<h1>` for assistive technology only — clipped to a 1px\n\t\t * box and removed from layout flow, so the page looks exactly as it\n\t\t * does with no header at all while the main landmark still carries a\n\t\t * heading. See the component docblock for the full rationale.\n\t\t */\n\t\tvisuallyHidden: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Translate function. Falls back to the injected `cnTranslate`,\n\t\t * which itself defaults to an identity function.\n\t\t *\n\t\t * @type {((key: string) => string)|null}\n\t\t */\n\t\ttranslate: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * Effective translate function: the explicit `translate` prop when\n\t\t * given, else the injected `cnTranslate` (identity by default).\n\t\t *\n\t\t * @return {(key: string) => string}\n\t\t */\n\t\teffectiveTranslate() {\n\t\t\treturn this.translate ?? this.cnTranslate\n\t\t},\n\n\t\t/**\n\t\t * The page title run through the host translate function.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedTitle() {\n\t\t\treturn this.title ? this.effectiveTranslate(this.title) : this.title\n\t\t},\n\n\t\t/**\n\t\t * The page description run through the host translate function.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedDescription() {\n\t\t\treturn this.description ? this.effectiveTranslate(this.description) : this.description\n\t\t},\n\t},\n}\n</script>\n\n<!-- Styles in css/page-header.css -->\n"],"names":["CnIcon"],"mappings":"
|
|
1
|
+
{"version":3,"file":"CnPageHeader.vue2.js","sources":["../../../../src/components/CnPageHeader/CnPageHeader.vue"],"sourcesContent":["<template>\n\t<div\n\t\tclass=\"cn-page-header\"\n\t\t:class=\"[{ 'cn-page-header--visually-hidden': visuallyHidden }]\"\n\t\tdata-testid=\"cn-page-header\"\n\t\t:data-visually-hidden=\"visuallyHidden ? 'true' : null\">\n\t\t<div v-if=\"!visuallyHidden && (icon || $slots.icon)\" class=\"cn-page-header__icon\">\n\t\t\t<slot name=\"icon\">\n\t\t\t\t<CnIcon :name=\"icon\" :size=\"iconSize\" />\n\t\t\t</slot>\n\t\t</div>\n\t\t<div class=\"cn-page-header__text\">\n\t\t\t<h1 class=\"cn-page-header__title\" data-testid=\"cn-page-title\">\n\t\t\t\t{{ resolvedTitle }}\n\t\t\t</h1>\n\t\t\t<CnHeaderTrail\n\t\t\t\tv-if=\"!visuallyHidden\"\n\t\t\t\t:breadcrumb=\"breadcrumb\"\n\t\t\t\t:current=\"resolvedTitle\"\n\t\t\t\t:meta=\"resolvedMeta\"\n\t\t\t\t:translate=\"effectiveTranslate\" />\n\t\t\t<p v-if=\"description && !visuallyHidden\" class=\"cn-page-header__description\" data-testid=\"cn-page-description\">\n\t\t\t\t{{ resolvedDescription }}\n\t\t\t</p>\n\t\t</div>\n\t\t<slot v-if=\"!visuallyHidden\" name=\"extra\" />\n\t</div>\n</template>\n\n<script>\nimport CnHeaderTrail from './CnHeaderTrail.vue'\nimport { CnIcon } from '../CnIcon/index.js'\n\n/**\n * CnPageHeader — Reusable page header with optional icon, title, and description.\n *\n * ```vue\n * <CnPageHeader title=\"Clients\" description=\"Manage your clients\" icon=\"AccountGroup\" />\n * ```\n *\n * ## `visuallyHidden` — the accessible-heading mode\n *\n * Several page primitives (CnIndexPage, CnSettingsPage, CnChatPage,\n * CnFilesPage, CnLogsPage) hide their inline header by default because the\n * design surfaces the page title in the app sidebar/navigation instead. That\n * sidebar heading lives OUTSIDE the `<main>` landmark, so suppressing the\n * header entirely left the main content region with no heading at all: a\n * screen-reader user gets no announcement of which list they are on, and a\n * \"skip to main content\" jump lands on an unlabelled region (WCAG 2.4.6\n * Headings and Labels, 1.3.1 Info and Relationships).\n *\n * `visuallyHidden` resolves that without a visual change: the `<h1>` stays in\n * the DOM and in the accessibility tree, clipped to a 1px box that is removed\n * from layout flow. The decorative icon, the description and the `extra` slot\n * are NOT rendered in this mode — the icon is decorative, and the `extra` slot\n * may contain focusable controls, which must never be clipped-but-tabbable.\n *\n * ```vue\n * <CnPageHeader :title=\"title\" :visually-hidden=\"!showTitle\" />\n * ```\n *\n * ## Translation\n *\n * `title` and `description` are manifest-authored English source strings. They\n * are rendered through the host translate function — the `translate` prop when\n * given, else the `cnTranslate` provided by CnAppRoot — so a page heading\n * follows the user's language. With no translator (or a catalogue that lacks\n * the key) the source string renders unchanged.\n */\nexport default {\n\tname: 'CnPageHeader',\n\n\tcomponents: {\n\t\tCnHeaderTrail,\n\t\tCnIcon,\n\t},\n\n\tinject: {\n\t\t/**\n\t\t * Host translate function provided by CnAppRoot as\n\t\t * `cnTranslate: this.translate` (bound to the host app's id).\n\t\t * Defaults to an identity function so the component stays usable\n\t\t * standalone and an untranslated key renders as itself.\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** Page title text */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** Optional description shown below the title */\n\t\tdescription: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * A breadcrumb under the title: one crumb or a list, each\n\t\t * `{ label, route?, params?, href?, icon?, separator? }`. The title\n\t\t * follows as the current crumb. Drawn as the board look's detail\n\t\t * header row.\n\t\t *\n\t\t * @type {object|Array<object>|null}\n\t\t * @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note\n\t\t */\n\t\tbreadcrumb: {\n\t\t\ttype: [Object, Array],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * A note after the breadcrumb and a middle dot, such as \"12 open\". Run\n\t\t * through the host translate function.\n\t\t *\n\t\t * @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note\n\t\t */\n\t\tmeta: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Optional MDI icon name (rendered via CnIcon) */\n\t\ticon: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Icon size in pixels */\n\t\ticonSize: {\n\t\t\ttype: Number,\n\t\t\tdefault: 28,\n\t\t},\n\n\t\t/**\n\t\t * Render the `<h1>` for assistive technology only — clipped to a 1px\n\t\t * box and removed from layout flow, so the page looks exactly as it\n\t\t * does with no header at all while the main landmark still carries a\n\t\t * heading. See the component docblock for the full rationale.\n\t\t */\n\t\tvisuallyHidden: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Translate function. Falls back to the injected `cnTranslate`,\n\t\t * which itself defaults to an identity function.\n\t\t *\n\t\t * @type {((key: string) => string)|null}\n\t\t */\n\t\ttranslate: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * Effective translate function: the explicit `translate` prop when\n\t\t * given, else the injected `cnTranslate` (identity by default).\n\t\t *\n\t\t * @return {(key: string) => string}\n\t\t */\n\t\teffectiveTranslate() {\n\t\t\treturn this.translate ?? this.cnTranslate\n\t\t},\n\n\t\t/**\n\t\t * The page title run through the host translate function.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedTitle() {\n\t\t\treturn this.title ? this.effectiveTranslate(this.title) : this.title\n\t\t},\n\n\t\t/**\n\t\t * The page description run through the host translate function.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedDescription() {\n\t\t\treturn this.description ? this.effectiveTranslate(this.description) : this.description\n\t\t},\n\n\t\t/**\n\t\t * The meta note run through the host translate function.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedMeta() {\n\t\t\treturn this.meta ? this.effectiveTranslate(this.meta) : ''\n\t\t},\n\t},\n}\n</script>\n\n<!-- Styles in css/page-header.css -->\n"],"names":["CnHeaderTrail","CnIcon"],"mappings":";;;AAiCA;AACC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;;AAIA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAED,aAAe;AACd,CAAA,IAAI,EAAE,cAAc;;CAEpB,UAAU,EAAE;iBACXA,UAAa;AACb,UAAAC,YAAM;EACN;;AAED,CAAA,MAAM,EAAE;AACP;AACC;;;;;AAKD,EAAA,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,KAAK,KAAK;EAC5C;;AAED,CAAA,KAAK,EAAE;AACN;AACA,EAAA,KAAK,EAAE;GACN,IAAI,EAAE,MAAM;GACZ,QAAQ,EAAE,IAAI;GACd;;AAED;EACA,WAAW,EAAE;GACZ,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;AAED;AACC;;;;AAIA;AACA;AACA;;EAED,UAAU,EAAE;AACX,GAAA,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC;GACrB,OAAO,EAAE,IAAI;GACb;;AAED;;AAEC;AACA;AACA;;EAED,IAAI,EAAE;GACL,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;AAED;EACA,IAAI,EAAE;GACL,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;AAED;AACA,EAAA,QAAQ,EAAE;GACT,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;;AAED;;;;;;AAMA,EAAA,cAAc,EAAE;GACf,IAAI,EAAE,OAAO;GACb,OAAO,EAAE,KAAK;GACd;;AAED;;AAEC;AACA;AACA;;EAED,SAAS,EAAE;GACV,IAAI,EAAE,QAAQ;GACd,OAAO,EAAE,IAAI;GACb;EACD;;AAED,CAAA,QAAQ,EAAE;AACT;;;AAGC;;;AAGD,EAAA,kBAAkB,GAAG;AACpB,GAAA,OAAO,IAAI,CAAC,SAAQ,IAAK,IAAI,CAAC,WAAU;GACxC;;AAED;;AAEC;AACA;;AAED,EAAA,aAAa,GAAG;AACf,GAAA,OAAO,IAAI,CAAC,KAAM,GAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAE,GAAE,IAAI,CAAC,KAAI;GACnE;;AAED;;AAEC;AACA;;AAED,EAAA,mBAAmB,GAAG;AACrB,GAAA,OAAO,IAAI,CAAC,cAAc,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAE,GAAE,IAAI,CAAC,WAAU;GACrF;;AAED;;AAEC;AACA;;AAED,EAAA,YAAY,GAAG;GACd,OAAO,IAAI,CAAC,IAAG,GAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAE,GAAE,EAAC;GACzD;EACD;AACF;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveComponent, openBlock, createElementBlock, normalizeClass, renderSlot, createVNode, createCommentVNode, createElementVNode, toDisplayString } from 'vue';
|
|
1
|
+
import { resolveComponent, openBlock, createElementBlock, normalizeClass, renderSlot, createVNode, createCommentVNode, createElementVNode, toDisplayString, createBlock } from 'vue';
|
|
2
2
|
|
|
3
3
|
const _hoisted_1 = ["data-visually-hidden"];
|
|
4
4
|
const _hoisted_2 = {
|
|
@@ -11,13 +11,14 @@ const _hoisted_4 = {
|
|
|
11
11
|
"data-testid": "cn-page-title"
|
|
12
12
|
};
|
|
13
13
|
const _hoisted_5 = {
|
|
14
|
-
key:
|
|
14
|
+
key: 1,
|
|
15
15
|
class: "cn-page-header__description",
|
|
16
16
|
"data-testid": "cn-page-description"
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
20
20
|
const _component_CnIcon = resolveComponent("CnIcon");
|
|
21
|
+
const _component_CnHeaderTrail = resolveComponent("CnHeaderTrail");
|
|
21
22
|
|
|
22
23
|
return (openBlock(), createElementBlock("div", {
|
|
23
24
|
class: normalizeClass(["cn-page-header", [{ 'cn-page-header--visually-hidden': $props.visuallyHidden }]]),
|
|
@@ -36,6 +37,15 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
36
37
|
: createCommentVNode("v-if", true),
|
|
37
38
|
createElementVNode("div", _hoisted_3, [
|
|
38
39
|
createElementVNode("h1", _hoisted_4, toDisplayString($options.resolvedTitle), 1 /* TEXT */),
|
|
40
|
+
(!$props.visuallyHidden)
|
|
41
|
+
? (openBlock(), createBlock(_component_CnHeaderTrail, {
|
|
42
|
+
key: 0,
|
|
43
|
+
breadcrumb: $props.breadcrumb,
|
|
44
|
+
current: $options.resolvedTitle,
|
|
45
|
+
meta: $options.resolvedMeta,
|
|
46
|
+
translate: $options.effectiveTranslate
|
|
47
|
+
}, null, 8 /* PROPS */, ["breadcrumb", "current", "meta", "translate"]))
|
|
48
|
+
: createCommentVNode("v-if", true),
|
|
39
49
|
($props.description && !$props.visuallyHidden)
|
|
40
50
|
? (openBlock(), createElementBlock("p", _hoisted_5, toDisplayString($options.resolvedDescription), 1 /* TEXT */))
|
|
41
51
|
: createCommentVNode("v-if", true)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnPageHeader.vue3.js","sources":["../../../../src/components/CnPageHeader/CnPageHeader.vue?vue&type=template&id=
|
|
1
|
+
{"version":3,"file":"CnPageHeader.vue3.js","sources":["../../../../src/components/CnPageHeader/CnPageHeader.vue?vue&type=template&id=3b593788&lang.js"],"sourcesContent":["<template>\n\t<div\n\t\tclass=\"cn-page-header\"\n\t\t:class=\"[{ 'cn-page-header--visually-hidden': visuallyHidden }]\"\n\t\tdata-testid=\"cn-page-header\"\n\t\t:data-visually-hidden=\"visuallyHidden ? 'true' : null\">\n\t\t<div v-if=\"!visuallyHidden && (icon || $slots.icon)\" class=\"cn-page-header__icon\">\n\t\t\t<slot name=\"icon\">\n\t\t\t\t<CnIcon :name=\"icon\" :size=\"iconSize\" />\n\t\t\t</slot>\n\t\t</div>\n\t\t<div class=\"cn-page-header__text\">\n\t\t\t<h1 class=\"cn-page-header__title\" data-testid=\"cn-page-title\">\n\t\t\t\t{{ resolvedTitle }}\n\t\t\t</h1>\n\t\t\t<CnHeaderTrail\n\t\t\t\tv-if=\"!visuallyHidden\"\n\t\t\t\t:breadcrumb=\"breadcrumb\"\n\t\t\t\t:current=\"resolvedTitle\"\n\t\t\t\t:meta=\"resolvedMeta\"\n\t\t\t\t:translate=\"effectiveTranslate\" />\n\t\t\t<p v-if=\"description && !visuallyHidden\" class=\"cn-page-header__description\" data-testid=\"cn-page-description\">\n\t\t\t\t{{ resolvedDescription }}\n\t\t\t</p>\n\t\t</div>\n\t\t<slot v-if=\"!visuallyHidden\" name=\"extra\" />\n\t</div>\n</template>\n\n<script>\nimport CnHeaderTrail from './CnHeaderTrail.vue'\nimport { CnIcon } from '../CnIcon/index.js'\n\n/**\n * CnPageHeader — Reusable page header with optional icon, title, and description.\n *\n * ```vue\n * <CnPageHeader title=\"Clients\" description=\"Manage your clients\" icon=\"AccountGroup\" />\n * ```\n *\n * ## `visuallyHidden` — the accessible-heading mode\n *\n * Several page primitives (CnIndexPage, CnSettingsPage, CnChatPage,\n * CnFilesPage, CnLogsPage) hide their inline header by default because the\n * design surfaces the page title in the app sidebar/navigation instead. That\n * sidebar heading lives OUTSIDE the `<main>` landmark, so suppressing the\n * header entirely left the main content region with no heading at all: a\n * screen-reader user gets no announcement of which list they are on, and a\n * \"skip to main content\" jump lands on an unlabelled region (WCAG 2.4.6\n * Headings and Labels, 1.3.1 Info and Relationships).\n *\n * `visuallyHidden` resolves that without a visual change: the `<h1>` stays in\n * the DOM and in the accessibility tree, clipped to a 1px box that is removed\n * from layout flow. The decorative icon, the description and the `extra` slot\n * are NOT rendered in this mode — the icon is decorative, and the `extra` slot\n * may contain focusable controls, which must never be clipped-but-tabbable.\n *\n * ```vue\n * <CnPageHeader :title=\"title\" :visually-hidden=\"!showTitle\" />\n * ```\n *\n * ## Translation\n *\n * `title` and `description` are manifest-authored English source strings. They\n * are rendered through the host translate function — the `translate` prop when\n * given, else the `cnTranslate` provided by CnAppRoot — so a page heading\n * follows the user's language. With no translator (or a catalogue that lacks\n * the key) the source string renders unchanged.\n */\nexport default {\n\tname: 'CnPageHeader',\n\n\tcomponents: {\n\t\tCnHeaderTrail,\n\t\tCnIcon,\n\t},\n\n\tinject: {\n\t\t/**\n\t\t * Host translate function provided by CnAppRoot as\n\t\t * `cnTranslate: this.translate` (bound to the host app's id).\n\t\t * Defaults to an identity function so the component stays usable\n\t\t * standalone and an untranslated key renders as itself.\n\t\t */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** Page title text */\n\t\ttitle: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\n\t\t/** Optional description shown below the title */\n\t\tdescription: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/**\n\t\t * A breadcrumb under the title: one crumb or a list, each\n\t\t * `{ label, route?, params?, href?, icon?, separator? }`. The title\n\t\t * follows as the current crumb. Drawn as the board look's detail\n\t\t * header row.\n\t\t *\n\t\t * @type {object|Array<object>|null}\n\t\t * @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note\n\t\t */\n\t\tbreadcrumb: {\n\t\t\ttype: [Object, Array],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * A note after the breadcrumb and a middle dot, such as \"12 open\". Run\n\t\t * through the host translate function.\n\t\t *\n\t\t * @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note\n\t\t */\n\t\tmeta: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Optional MDI icon name (rendered via CnIcon) */\n\t\ticon: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Icon size in pixels */\n\t\ticonSize: {\n\t\t\ttype: Number,\n\t\t\tdefault: 28,\n\t\t},\n\n\t\t/**\n\t\t * Render the `<h1>` for assistive technology only — clipped to a 1px\n\t\t * box and removed from layout flow, so the page looks exactly as it\n\t\t * does with no header at all while the main landmark still carries a\n\t\t * heading. See the component docblock for the full rationale.\n\t\t */\n\t\tvisuallyHidden: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Translate function. Falls back to the injected `cnTranslate`,\n\t\t * which itself defaults to an identity function.\n\t\t *\n\t\t * @type {((key: string) => string)|null}\n\t\t */\n\t\ttranslate: {\n\t\t\ttype: Function,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * Effective translate function: the explicit `translate` prop when\n\t\t * given, else the injected `cnTranslate` (identity by default).\n\t\t *\n\t\t * @return {(key: string) => string}\n\t\t */\n\t\teffectiveTranslate() {\n\t\t\treturn this.translate ?? this.cnTranslate\n\t\t},\n\n\t\t/**\n\t\t * The page title run through the host translate function.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedTitle() {\n\t\t\treturn this.title ? this.effectiveTranslate(this.title) : this.title\n\t\t},\n\n\t\t/**\n\t\t * The page description run through the host translate function.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedDescription() {\n\t\t\treturn this.description ? this.effectiveTranslate(this.description) : this.description\n\t\t},\n\n\t\t/**\n\t\t * The meta note run through the host translate function.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tresolvedMeta() {\n\t\t\treturn this.meta ? this.effectiveTranslate(this.meta) : ''\n\t\t},\n\t},\n}\n</script>\n\n<!-- Styles in css/page-header.css -->\n"],"names":["_createElementBlock","_normalizeClass","_openBlock","_renderSlot","_createVNode","_createElementVNode","_toDisplayString","_createBlock"],"mappings":";;;;;AAMuD,EAAA,KAAK,EAAC,sBAAsB;;AAK5E,MAAA,UAAA,GAAA,EAAA,KAAK,EAAC,sBAAsB,GAAA;;AAC5B,EAAA,KAAK,EAAC,uBAAsB;AAAE,EAAA,aAAW,EAAC,eAAe;;;;AASpB,EAAA,KAAK,EAAC,6BAA4B;AAAE,EAAA,aAAW,EAAC,qBAAqB;;;;;;;uBApBhHA,kBAyBK,CAAA,KAAA,EAAA;IAxBJ,KAAK,EAAAC,cAAA,CAAA,CAAC,gBAAe,EAAA,CAAA,EAAA,iCAAA,EACyB,MAAe,CAAA,cAAA,EAAA,CAAA,CAAA,CAAA;AAC7D,IAAA,aAAW,EAAC,gBAAe;AAC1B,IAAA,sBAAoB,EAAE,MAAe,CAAA,cAAA,GAAA,MAAA,GAAA,IAAA;;AAC1B,IAAA,CAAA,CAAA,MAAA,CAAA,mBAAmB,MAAA,CAAA,IAAG,IAAK,IAAA,CAAA,MAAM,CAAC,IAAI,CAAA;AAAlD,SAAAC,SAAA,EAAA,EAAAF,kBAAA,CAIK,OAJL,UAIK,EAAA;AAHJ,UAAAG,UAAA,CAEM,yBAFN,MAEM;YADLC,WAAuC,CAAA,iBAAA,EAAA;AAA9B,cAAA,IAAI,EAAE,MAAI,CAAA,IAAA;AAAG,cAAA,IAAI,EAAE,MAAQ,CAAA,QAAA;;;;;AAGtC,IAAAC,kBAAA,CAaK,OAbL,UAaK,EAAA;MAZJA,kBAEI,CAAA,IAAA,EAFJ,UAEI,EAAAC,eAAA,CADA;QAGI,MAAc,CAAA,cAAA;wBADtBC,WAKkC,CAAA,wBAAA,EAAA;;AAHhC,YAAA,UAAU,EAAE,MAAU,CAAA,UAAA;AACtB,YAAA,OAAO,EAAE,QAAa,CAAA,aAAA;AACtB,YAAA,IAAI,EAAE,QAAY,CAAA,YAAA;AAClB,YAAA,SAAS,EAAE,QAAkB,CAAA,kBAAA;;;AACtB,MAAA,CAAA,MAAA,CAAA,gBAAgB,MAAc,CAAA,cAAA;wBAAvCP,kBAEG,CAAA,GAAA,EAFH,UAEG,EAAAM,eAAA,CADC;;;MAGQ,MAAc,CAAA,cAAA;QAA3BH,UAA2C,CAAA,IAAA,CAAA,MAAA,EAAA,OAAA,EAAA,EAAA,EAAA,SAAA,EAAA,SAAA,EAAA,CAAA,CAAA;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CnPagination.vue2.js","sources":["../../../../src/components/CnPagination/CnPagination.vue"],"sourcesContent":["<template>\n\t<div\n\t\tv-if=\"totalPages > 1 || totalItems > minItemsToShow || (isBoardVariant && totalItems > 0)\"\n\t\tclass=\"cn-pagination\"\n\t\t:class=\"{ 'cn-pagination--compact': compact, 'cn-pagination--board': isBoardVariant }\"\n\t\tdata-testid=\"cn-pagination\">\n\t\t<!--\n\t\t Board variant (`variant: \"board\"`): the footer of the table card as the\n\t\t screens draw it. The count text at the start, numbered 34px links at\n\t\t the end, \"Previous\" only after the first page and \"Next\" only before\n\t\t the last. No First, no Last, no page-size select.\n\t\t-->\n\t\t<template v-if=\"isBoardVariant\">\n\t\t\t<span class=\"cn-pagination__page-info cn-pagination__board-count\" data-testid=\"cn-pagination-board-count\">\n\t\t\t\t{{ boardCountText }}\n\t\t\t</span>\n\t\t\t<nav v-if=\"totalPages > 1\" class=\"cn-pagination__board-pages\" :aria-label=\"t('nextcloud-vue', 'Pagination')\">\n\t\t\t\t<button\n\t\t\t\t\tv-if=\"currentPage > 1\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-pagination__board-link cn-pagination__board-link--wide\"\n\t\t\t\t\tdata-testid=\"cn-pagination-prev\"\n\t\t\t\t\t@click=\"changePage(currentPage - 1)\">\n\t\t\t\t\t{{ previousLabel }}\n\t\t\t\t</button>\n\t\t\t\t<template v-for=\"page in visiblePages\" :key=\"'board-' + page\">\n\t\t\t\t\t<span v-if=\"page === '...'\" class=\"cn-pagination__ellipsis\">...</span>\n\t\t\t\t\t<button\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-pagination__board-link\"\n\t\t\t\t\t\t:class=\"{ 'cn-pagination__board-link--current': page === currentPage }\"\n\t\t\t\t\t\t:aria-current=\"page === currentPage ? 'page' : null\"\n\t\t\t\t\t\t@click=\"changePage(page)\">\n\t\t\t\t\t\t{{ page }}\n\t\t\t\t\t</button>\n\t\t\t\t</template>\n\t\t\t\t<button\n\t\t\t\t\tv-if=\"currentPage < totalPages\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-pagination__board-link cn-pagination__board-link--wide\"\n\t\t\t\t\tdata-testid=\"cn-pagination-next\"\n\t\t\t\t\t@click=\"changePage(currentPage + 1)\">\n\t\t\t\t\t{{ nextLabel }}\n\t\t\t\t</button>\n\t\t\t</nav>\n\t\t</template>\n\n\t\t<!-- Page info -->\n\t\t<div v-if=\"!isBoardVariant\" class=\"cn-pagination__info\">\n\t\t\t<span class=\"cn-pagination__page-info\">\n\t\t\t\t{{ pageInfoText }}\n\t\t\t</span>\n\t\t</div>\n\n\t\t<!--\n\t\t Compact navigation — a single Previous / Next pair, for the inside of\n\t\t a dashboard widget. The full control (First/Last, numbered pages, a\n\t\t page-size select) is an index-page affordance; dropped into a widget\n\t\t card it is wider than the card and taller than the rows it pages.\n\t\t-->\n\t\t<div v-if=\"!isBoardVariant && compact && totalPages > 1\" class=\"cn-pagination__nav cn-pagination__nav--compact\">\n\t\t\t<NcButton\n\t\t\t\t:aria-label=\"previousLabel\"\n\t\t\t\t:disabled=\"currentPage === 1\"\n\t\t\t\tdata-testid=\"cn-pagination-prev\"\n\t\t\t\t@click=\"changePage(currentPage - 1)\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<ChevronLeft :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t</NcButton>\n\t\t\t<NcButton\n\t\t\t\t:aria-label=\"nextLabel\"\n\t\t\t\t:disabled=\"currentPage === totalPages\"\n\t\t\t\tdata-testid=\"cn-pagination-next\"\n\t\t\t\t@click=\"changePage(currentPage + 1)\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<ChevronRight :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t</NcButton>\n\t\t</div>\n\n\t\t<!-- Page navigation -->\n\t\t<div v-else-if=\"!isBoardVariant && totalPages > 1\" class=\"cn-pagination__nav\">\n\t\t\t<NcButton\n\t\t\t\t:disabled=\"currentPage === 1\"\n\t\t\t\t@click=\"changePage(1)\">\n\t\t\t\t{{ firstLabel }}\n\t\t\t</NcButton>\n\n\t\t\t<NcButton\n\t\t\t\t:disabled=\"currentPage === 1\"\n\t\t\t\t@click=\"changePage(currentPage - 1)\">\n\t\t\t\t{{ previousLabel }}\n\t\t\t</NcButton>\n\n\t\t\t<div class=\"cn-pagination__numbers\">\n\t\t\t\t<template v-for=\"page in visiblePages\">\n\t\t\t\t\t<span v-if=\"page === '...'\" :key=\"'ellipsis-' + page\" class=\"cn-pagination__ellipsis\">...</span>\n\t\t\t\t\t<NcButton\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\t:key=\"page\"\n\t\t\t\t\t\t:variant=\"page === currentPage ? 'primary' : 'secondary'\"\n\t\t\t\t\t\t:disabled=\"page === currentPage\"\n\t\t\t\t\t\t@click=\"changePage(page)\">\n\t\t\t\t\t\t{{ page }}\n\t\t\t\t\t</NcButton>\n\t\t\t\t</template>\n\t\t\t</div>\n\n\t\t\t<NcButton\n\t\t\t\t:disabled=\"currentPage === totalPages\"\n\t\t\t\t@click=\"changePage(currentPage + 1)\">\n\t\t\t\t{{ nextLabel }}\n\t\t\t</NcButton>\n\n\t\t\t<NcButton\n\t\t\t\t:disabled=\"currentPage === totalPages\"\n\t\t\t\t@click=\"changePage(totalPages)\">\n\t\t\t\t{{ lastLabel }}\n\t\t\t</NcButton>\n\t\t</div>\n\n\t\t<!-- Page size selector -->\n\t\t<div v-if=\"!compact && !isBoardVariant\" class=\"cn-pagination__page-size\">\n\t\t\t<label :for=\"pageSizeId\">{{ itemsPerPageLabel }}</label>\n\t\t\t<NcSelect\n\t\t\t\t:inputId=\"pageSizeId\"\n\t\t\t\tclass=\"cn-pagination__page-size-select\"\n\t\t\t\t:modelValue=\"currentPageSizeOption\"\n\t\t\t\t:options=\"pageSizeOptions\"\n\t\t\t\t:clearable=\"false\"\n\t\t\t\t:inputLabel=\"itemsPerPageLabel\"\n\t\t\t\t@option:selected=\"changePageSize\" />\n\t\t</div>\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcSelect } from '@nextcloud/vue'\nimport ChevronLeft from 'vue-material-design-icons/ChevronLeft.vue'\nimport ChevronRight from 'vue-material-design-icons/ChevronRight.vue'\nimport { nextUid } from '../../utils/uid.js'\n\n/**\n * CnPagination — Full pagination with page numbers, navigation, and page size selector.\n *\n * Extracted from OpenRegister's PaginationComponent. Zero store dependencies.\n * Supports First/Previous/Next/Last buttons, smart page number display with\n * ellipsis, and configurable page size.\n *\n * NL Design tokens used:\n * - Inherits from cn-pagination CSS class (see css/pagination.css)\n *\n * ```vue\n * <CnPagination\n * :current-page=\"page\"\n * :total-pages=\"totalPages\"\n * :total-items=\"totalItems\"\n * :current-page-size=\"limit\"\n * @page-changed=\"onPageChange\"\n * @page-size-changed=\"onPageSizeChange\" />\n * ```\n */\nexport default {\n\tname: 'CnPagination',\n\n\tcomponents: {\n\t\tNcButton,\n\t\tNcSelect,\n\t\tChevronLeft,\n\t\tChevronRight,\n\t},\n\n\tprops: {\n\t\t/** Current page number (1-based) */\n\t\tcurrentPage: {\n\t\t\ttype: Number,\n\t\t\tdefault: 1,\n\t\t},\n\n\t\t/** Total number of pages */\n\t\ttotalPages: {\n\t\t\ttype: Number,\n\t\t\tdefault: 1,\n\t\t},\n\n\t\t/** Total number of items across all pages */\n\t\ttotalItems: {\n\t\t\ttype: Number,\n\t\t\tdefault: 0,\n\t\t},\n\n\t\t/** Current items per page */\n\t\tcurrentPageSize: {\n\t\t\ttype: Number,\n\t\t\tdefault: 20,\n\t\t},\n\n\t\t/** Available page size options */\n\t\tpageSizeOptions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [\n\t\t\t\t{ value: 10, label: '10' },\n\t\t\t\t{ value: 20, label: '20' },\n\t\t\t\t{ value: 50, label: '50' },\n\t\t\t\t{ value: 100, label: '100' },\n\t\t\t\t{ value: 250, label: '250' },\n\t\t\t\t{ value: 500, label: '500' },\n\t\t\t\t{ value: 1000, label: '1000' },\n\t\t\t],\n\t\t},\n\n\t\t/**\n\t\t * Compact mode — one Previous / Next pair and the item range, sized to\n\t\t * sit inside a dashboard widget's footer. Drops the First/Last\n\t\t * buttons, the numbered pages and the page-size select, none of which\n\t\t * fit in a widget card.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tcompact: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * `board` draws the footer of the board look's table card: count text\n\t\t * at the start, numbered pages with Previous and Next at the end, no\n\t\t * First, Last or page-size select. The default (`''`) renders as before.\n\t\t *\n\t\t * @type {('' | 'board')}\n\t\t * @spec openspec/changes/screens-index-list-parity/specs/index-list-board-look/spec.md#requirement-the-footer-sits-inside-the-card\n\t\t */\n\t\tvariant: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t\tvalidator: (value) => value === '' || value === 'board',\n\t\t},\n\n\t\t/**\n\t\t * Free text appended to the board variant's count text (\"20 of 48 ·\n\t\t * click a column header to sort\"). Manifest key `config.footerNote`.\n\t\t */\n\t\tfooterNote: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Minimum items before pagination is shown */\n\t\tminItemsToShow: {\n\t\t\ttype: Number,\n\t\t\tdefault: 10,\n\t\t},\n\n\t\t/** Label for \"First\" button */\n\t\tfirstLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'First'),\n\t\t},\n\n\t\t/** Label for \"Previous\" button */\n\t\tpreviousLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Previous'),\n\t\t},\n\n\t\t/** Label for \"Next\" button */\n\t\tnextLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Next'),\n\t\t},\n\n\t\t/** Label for \"Last\" button */\n\t\tlastLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Last'),\n\t\t},\n\n\t\t/** Label for \"Items per page:\" */\n\t\titemsPerPageLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Items per page:'),\n\t\t},\n\n\t\t/**\n\t\t * Page info format string. Use {current} and {total} as placeholders.\n\t\t * \"Page {current} of {total}\"\n\t\t */\n\t\tpageInfoFormat: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Page {current} of {total}'),\n\t\t},\n\n\t\t/**\n\t\t * Page info format used in `compact` mode. Placeholders: {from}, {to},\n\t\t * {total} — the item range rather than the page number.\n\t\t */\n\t\tcompactInfoFormat: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', '{from}–{to} of {total}'),\n\t\t},\n\t},\n\n\temits: ['page-changed', 'page-size-changed'],\n\n\tdata() {\n\t\treturn {\n\t\t\t// Per-instance id suffix. In `data()` rather than a computed so it is\n\t\t\t// fixed for the instance's lifetime — the value is referenced by a\n\t\t\t// `<label for>`, which breaks if the id changes between renders.\n\t\t\tuid: nextUid(),\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * Whether the board variant is drawn.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisBoardVariant() {\n\t\t\treturn this.variant === 'board'\n\t\t},\n\n\t\t/**\n\t\t * The board variant's count text: the rows on this page of the total,\n\t\t * `\"{shown} of {total}\"`, plus the page's footer note when it has one.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tboardCountText() {\n\t\t\tconst before = (this.currentPage - 1) * this.currentPageSize\n\t\t\tconst shown = Math.max(0, Math.min(this.currentPageSize, this.totalItems - before))\n\t\t\tconst base = t('nextcloud-vue', '{shown} of {total}', { shown, total: this.totalItems })\n\t\t\treturn this.footerNote ? `${base} · ${this.footerNote}` : base\n\t\t},\n\n\t\tpageSizeId() {\n\t\t\treturn 'cn-page-size-' + this.uid\n\t\t},\n\n\t\tcurrentPageSizeOption() {\n\t\t\treturn this.pageSizeOptions.find((option) => option.value === this.currentPageSize) || this.pageSizeOptions[1]\n\t\t},\n\n\t\tpageInfoText() {\n\t\t\t// Compact mode names the ITEMS, not the pages: in a widget the row\n\t\t\t// range (\"1–5 of 137\") is what the reader is actually looking at,\n\t\t\t// and it is the only honest statement of how much is off-screen.\n\t\t\tif (this.compact) {\n\t\t\t\tconst from = this.totalItems === 0 ? 0 : ((this.currentPage - 1) * this.currentPageSize) + 1\n\t\t\t\tconst to = Math.min(this.currentPage * this.currentPageSize, this.totalItems)\n\t\t\t\treturn this.compactInfoFormat\n\t\t\t\t\t.replace('{from}', from)\n\t\t\t\t\t.replace('{to}', to)\n\t\t\t\t\t.replace('{total}', this.totalItems)\n\t\t\t}\n\t\t\treturn this.pageInfoFormat\n\t\t\t\t.replace('{current}', this.currentPage)\n\t\t\t\t.replace('{total}', this.totalPages)\n\t\t},\n\n\t\t/**\n\t\t * Calculate visible page numbers with ellipsis for large page counts.\n\t\t * Shows up to 7 page numbers at a time.\n\t\t */\n\t\tvisiblePages() {\n\t\t\tconst current = this.currentPage\n\t\t\tconst total = this.totalPages\n\t\t\tconst pages = []\n\n\t\t\tif (total <= 7) {\n\t\t\t\tfor (let i = 1; i <= total; i++) {\n\t\t\t\t\tpages.push(i)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpages.push(1)\n\n\t\t\t\tif (current <= 4) {\n\t\t\t\t\tfor (let i = 2; i <= 5; i++) {\n\t\t\t\t\t\tpages.push(i)\n\t\t\t\t\t}\n\t\t\t\t\tpages.push('...')\n\t\t\t\t\tpages.push(total)\n\t\t\t\t} else if (current >= total - 3) {\n\t\t\t\t\tpages.push('...')\n\t\t\t\t\tfor (let i = total - 4; i <= total; i++) {\n\t\t\t\t\t\tpages.push(i)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpages.push('...')\n\t\t\t\t\tfor (let i = current - 1; i <= current + 1; i++) {\n\t\t\t\t\t\tpages.push(i)\n\t\t\t\t\t}\n\t\t\t\t\tpages.push('...')\n\t\t\t\t\tpages.push(total)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn pages\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Navigate to a specific page.\n\t\t *\n\t\t * @param {number} page Target page number\n\t\t */\n\t\tchangePage(page) {\n\t\t\tif (page !== this.currentPage && page >= 1 && page <= this.totalPages) {\n\t\t\t\t/** @event page-changed Emitted when page changes. Payload: new page number. */\n\t\t\t\tthis.$emit('page-changed', page)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Change the page size.\n\t\t *\n\t\t * @param {object} option Selected page size option { value, label }\n\t\t */\n\t\tchangePageSize(option) {\n\t\t\tif (option.value !== this.currentPageSize) {\n\t\t\t\t/** @event page-size-changed Emitted when page size changes. Payload: new page size. */\n\t\t\t\tthis.$emit('page-size-changed', option.value)\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n"],"names":["t"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CnPagination.vue2.js","sources":["../../../../src/components/CnPagination/CnPagination.vue"],"sourcesContent":["<template>\n\t<div\n\t\tv-if=\"totalPages > 1 || totalItems > minItemsToShow || (isBoardVariant && totalItems > 0)\"\n\t\tclass=\"cn-pagination\"\n\t\t:class=\"{ 'cn-pagination--compact': compact, 'cn-pagination--board': isBoardVariant }\"\n\t\tdata-testid=\"cn-pagination\">\n\t\t<!--\n\t\t Board variant (`variant: \"board\"`): the footer of the table card as the\n\t\t screens draw it. The count text at the start, numbered 34px links at\n\t\t the end, \"Previous\" only after the first page and \"Next\" only before\n\t\t the last (inert on a single page). No First, no Last, no page-size select.\n\t\t-->\n\t\t<template v-if=\"isBoardVariant\">\n\t\t\t<span class=\"cn-pagination__page-info cn-pagination__board-count\" data-testid=\"cn-pagination-board-count\">\n\t\t\t\t{{ boardCountText }}\n\t\t\t</span>\n\t\t\t<nav class=\"cn-pagination__board-pages\" :aria-label=\"t('nextcloud-vue', 'Pagination')\">\n\t\t\t\t<button\n\t\t\t\t\tv-if=\"currentPage > 1\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-pagination__board-link cn-pagination__board-link--wide\"\n\t\t\t\t\tdata-testid=\"cn-pagination-prev\"\n\t\t\t\t\t@click=\"changePage(currentPage - 1)\">\n\t\t\t\t\t{{ previousLabel }}\n\t\t\t\t</button>\n\t\t\t\t<template v-for=\"page in visiblePages\" :key=\"'board-' + page\">\n\t\t\t\t\t<span v-if=\"page === '...'\" class=\"cn-pagination__ellipsis\">...</span>\n\t\t\t\t\t<button\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"cn-pagination__board-link\"\n\t\t\t\t\t\t:class=\"{ 'cn-pagination__board-link--current': page === currentPage }\"\n\t\t\t\t\t\t:aria-current=\"page === currentPage ? 'page' : null\"\n\t\t\t\t\t\t@click=\"changePage(page)\">\n\t\t\t\t\t\t{{ page }}\n\t\t\t\t\t</button>\n\t\t\t\t</template>\n\t\t\t\t<button\n\t\t\t\t\tv-if=\"currentPage < totalPages\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"cn-pagination__board-link cn-pagination__board-link--wide\"\n\t\t\t\t\tdata-testid=\"cn-pagination-next\"\n\t\t\t\t\t@click=\"changePage(currentPage + 1)\">\n\t\t\t\t\t{{ nextLabel }}\n\t\t\t\t</button>\n\t\t\t\t<!-- A single page still draws its \"1\" and an inert Next, as the boards do. -->\n\t\t\t\t<span\n\t\t\t\t\tv-else-if=\"totalPages <= 1\"\n\t\t\t\t\tclass=\"cn-pagination__board-link cn-pagination__board-link--wide cn-pagination__board-link--disabled\"\n\t\t\t\t\taria-disabled=\"true\"\n\t\t\t\t\tdata-testid=\"cn-pagination-next\">\n\t\t\t\t\t{{ nextLabel }}\n\t\t\t\t</span>\n\t\t\t</nav>\n\t\t</template>\n\n\t\t<!-- Page info -->\n\t\t<div v-if=\"!isBoardVariant\" class=\"cn-pagination__info\">\n\t\t\t<span class=\"cn-pagination__page-info\">\n\t\t\t\t{{ pageInfoText }}\n\t\t\t</span>\n\t\t</div>\n\n\t\t<!--\n\t\t Compact navigation — a single Previous / Next pair, for the inside of\n\t\t a dashboard widget. The full control (First/Last, numbered pages, a\n\t\t page-size select) is an index-page affordance; dropped into a widget\n\t\t card it is wider than the card and taller than the rows it pages.\n\t\t-->\n\t\t<div v-if=\"!isBoardVariant && compact && totalPages > 1\" class=\"cn-pagination__nav cn-pagination__nav--compact\">\n\t\t\t<NcButton\n\t\t\t\t:aria-label=\"previousLabel\"\n\t\t\t\t:disabled=\"currentPage === 1\"\n\t\t\t\tdata-testid=\"cn-pagination-prev\"\n\t\t\t\t@click=\"changePage(currentPage - 1)\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<ChevronLeft :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t</NcButton>\n\t\t\t<NcButton\n\t\t\t\t:aria-label=\"nextLabel\"\n\t\t\t\t:disabled=\"currentPage === totalPages\"\n\t\t\t\tdata-testid=\"cn-pagination-next\"\n\t\t\t\t@click=\"changePage(currentPage + 1)\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<ChevronRight :size=\"20\" />\n\t\t\t\t</template>\n\t\t\t</NcButton>\n\t\t</div>\n\n\t\t<!-- Page navigation -->\n\t\t<div v-else-if=\"!isBoardVariant && totalPages > 1\" class=\"cn-pagination__nav\">\n\t\t\t<NcButton\n\t\t\t\t:disabled=\"currentPage === 1\"\n\t\t\t\t@click=\"changePage(1)\">\n\t\t\t\t{{ firstLabel }}\n\t\t\t</NcButton>\n\n\t\t\t<NcButton\n\t\t\t\t:disabled=\"currentPage === 1\"\n\t\t\t\t@click=\"changePage(currentPage - 1)\">\n\t\t\t\t{{ previousLabel }}\n\t\t\t</NcButton>\n\n\t\t\t<div class=\"cn-pagination__numbers\">\n\t\t\t\t<template v-for=\"page in visiblePages\">\n\t\t\t\t\t<span v-if=\"page === '...'\" :key=\"'ellipsis-' + page\" class=\"cn-pagination__ellipsis\">...</span>\n\t\t\t\t\t<NcButton\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\t:key=\"page\"\n\t\t\t\t\t\t:variant=\"page === currentPage ? 'primary' : 'secondary'\"\n\t\t\t\t\t\t:disabled=\"page === currentPage\"\n\t\t\t\t\t\t@click=\"changePage(page)\">\n\t\t\t\t\t\t{{ page }}\n\t\t\t\t\t</NcButton>\n\t\t\t\t</template>\n\t\t\t</div>\n\n\t\t\t<NcButton\n\t\t\t\t:disabled=\"currentPage === totalPages\"\n\t\t\t\t@click=\"changePage(currentPage + 1)\">\n\t\t\t\t{{ nextLabel }}\n\t\t\t</NcButton>\n\n\t\t\t<NcButton\n\t\t\t\t:disabled=\"currentPage === totalPages\"\n\t\t\t\t@click=\"changePage(totalPages)\">\n\t\t\t\t{{ lastLabel }}\n\t\t\t</NcButton>\n\t\t</div>\n\n\t\t<!-- Page size selector -->\n\t\t<div v-if=\"!compact && !isBoardVariant\" class=\"cn-pagination__page-size\">\n\t\t\t<label :for=\"pageSizeId\">{{ itemsPerPageLabel }}</label>\n\t\t\t<NcSelect\n\t\t\t\t:inputId=\"pageSizeId\"\n\t\t\t\tclass=\"cn-pagination__page-size-select\"\n\t\t\t\t:modelValue=\"currentPageSizeOption\"\n\t\t\t\t:options=\"pageSizeOptions\"\n\t\t\t\t:clearable=\"false\"\n\t\t\t\t:inputLabel=\"itemsPerPageLabel\"\n\t\t\t\t@option:selected=\"changePageSize\" />\n\t\t</div>\n\t</div>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcSelect } from '@nextcloud/vue'\nimport ChevronLeft from 'vue-material-design-icons/ChevronLeft.vue'\nimport ChevronRight from 'vue-material-design-icons/ChevronRight.vue'\nimport { nextUid } from '../../utils/uid.js'\n\n/**\n * CnPagination — Full pagination with page numbers, navigation, and page size selector.\n *\n * Extracted from OpenRegister's PaginationComponent. Zero store dependencies.\n * Supports First/Previous/Next/Last buttons, smart page number display with\n * ellipsis, and configurable page size.\n *\n * NL Design tokens used:\n * - Inherits from cn-pagination CSS class (see css/pagination.css)\n *\n * ```vue\n * <CnPagination\n * :current-page=\"page\"\n * :total-pages=\"totalPages\"\n * :total-items=\"totalItems\"\n * :current-page-size=\"limit\"\n * @page-changed=\"onPageChange\"\n * @page-size-changed=\"onPageSizeChange\" />\n * ```\n */\nexport default {\n\tname: 'CnPagination',\n\n\tcomponents: {\n\t\tNcButton,\n\t\tNcSelect,\n\t\tChevronLeft,\n\t\tChevronRight,\n\t},\n\n\tprops: {\n\t\t/** Current page number (1-based) */\n\t\tcurrentPage: {\n\t\t\ttype: Number,\n\t\t\tdefault: 1,\n\t\t},\n\n\t\t/** Total number of pages */\n\t\ttotalPages: {\n\t\t\ttype: Number,\n\t\t\tdefault: 1,\n\t\t},\n\n\t\t/** Total number of items across all pages */\n\t\ttotalItems: {\n\t\t\ttype: Number,\n\t\t\tdefault: 0,\n\t\t},\n\n\t\t/** Current items per page */\n\t\tcurrentPageSize: {\n\t\t\ttype: Number,\n\t\t\tdefault: 20,\n\t\t},\n\n\t\t/** Available page size options */\n\t\tpageSizeOptions: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [\n\t\t\t\t{ value: 10, label: '10' },\n\t\t\t\t{ value: 20, label: '20' },\n\t\t\t\t{ value: 50, label: '50' },\n\t\t\t\t{ value: 100, label: '100' },\n\t\t\t\t{ value: 250, label: '250' },\n\t\t\t\t{ value: 500, label: '500' },\n\t\t\t\t{ value: 1000, label: '1000' },\n\t\t\t],\n\t\t},\n\n\t\t/**\n\t\t * Compact mode — one Previous / Next pair and the item range, sized to\n\t\t * sit inside a dashboard widget's footer. Drops the First/Last\n\t\t * buttons, the numbered pages and the page-size select, none of which\n\t\t * fit in a widget card.\n\t\t *\n\t\t * @type {boolean}\n\t\t */\n\t\tcompact: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * `board` draws the footer of the board look's table card: count text\n\t\t * at the start, numbered pages with Previous and Next at the end, no\n\t\t * First, Last or page-size select. The default (`''`) renders as before.\n\t\t *\n\t\t * @type {('' | 'board')}\n\t\t * @spec openspec/changes/screens-index-list-parity/specs/index-list-board-look/spec.md#requirement-the-footer-sits-inside-the-card\n\t\t */\n\t\tvariant: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t\tvalidator: (value) => value === '' || value === 'board',\n\t\t},\n\n\t\t/**\n\t\t * Free text appended to the board variant's count text (\"20 of 48 ·\n\t\t * click a column header to sort\"). Manifest key `config.footerNote`.\n\t\t */\n\t\tfooterNote: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Minimum items before pagination is shown */\n\t\tminItemsToShow: {\n\t\t\ttype: Number,\n\t\t\tdefault: 10,\n\t\t},\n\n\t\t/** Label for \"First\" button */\n\t\tfirstLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'First'),\n\t\t},\n\n\t\t/** Label for \"Previous\" button */\n\t\tpreviousLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Previous'),\n\t\t},\n\n\t\t/** Label for \"Next\" button */\n\t\tnextLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Next'),\n\t\t},\n\n\t\t/** Label for \"Last\" button */\n\t\tlastLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Last'),\n\t\t},\n\n\t\t/** Label for \"Items per page:\" */\n\t\titemsPerPageLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Items per page:'),\n\t\t},\n\n\t\t/**\n\t\t * Page info format string. Use {current} and {total} as placeholders.\n\t\t * \"Page {current} of {total}\"\n\t\t */\n\t\tpageInfoFormat: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Page {current} of {total}'),\n\t\t},\n\n\t\t/**\n\t\t * Page info format used in `compact` mode. Placeholders: {from}, {to},\n\t\t * {total} — the item range rather than the page number.\n\t\t */\n\t\tcompactInfoFormat: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', '{from}–{to} of {total}'),\n\t\t},\n\t},\n\n\temits: ['page-changed', 'page-size-changed'],\n\n\tdata() {\n\t\treturn {\n\t\t\t// Per-instance id suffix. In `data()` rather than a computed so it is\n\t\t\t// fixed for the instance's lifetime — the value is referenced by a\n\t\t\t// `<label for>`, which breaks if the id changes between renders.\n\t\t\tuid: nextUid(),\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * Whether the board variant is drawn.\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisBoardVariant() {\n\t\t\treturn this.variant === 'board'\n\t\t},\n\n\t\t/**\n\t\t * The board variant's count text: the rows on this page of the total,\n\t\t * `\"{shown} of {total}\"`, plus the page's footer note when it has one.\n\t\t *\n\t\t * @return {string}\n\t\t */\n\t\tboardCountText() {\n\t\t\tconst before = (this.currentPage - 1) * this.currentPageSize\n\t\t\tconst shown = Math.max(0, Math.min(this.currentPageSize, this.totalItems - before))\n\t\t\tconst base = t('nextcloud-vue', '{shown} of {total}', { shown, total: this.totalItems })\n\t\t\treturn this.footerNote ? `${base} · ${this.footerNote}` : base\n\t\t},\n\n\t\tpageSizeId() {\n\t\t\treturn 'cn-page-size-' + this.uid\n\t\t},\n\n\t\tcurrentPageSizeOption() {\n\t\t\treturn this.pageSizeOptions.find((option) => option.value === this.currentPageSize) || this.pageSizeOptions[1]\n\t\t},\n\n\t\tpageInfoText() {\n\t\t\t// Compact mode names the ITEMS, not the pages: in a widget the row\n\t\t\t// range (\"1–5 of 137\") is what the reader is actually looking at,\n\t\t\t// and it is the only honest statement of how much is off-screen.\n\t\t\tif (this.compact) {\n\t\t\t\tconst from = this.totalItems === 0 ? 0 : ((this.currentPage - 1) * this.currentPageSize) + 1\n\t\t\t\tconst to = Math.min(this.currentPage * this.currentPageSize, this.totalItems)\n\t\t\t\treturn this.compactInfoFormat\n\t\t\t\t\t.replace('{from}', from)\n\t\t\t\t\t.replace('{to}', to)\n\t\t\t\t\t.replace('{total}', this.totalItems)\n\t\t\t}\n\t\t\treturn this.pageInfoFormat\n\t\t\t\t.replace('{current}', this.currentPage)\n\t\t\t\t.replace('{total}', this.totalPages)\n\t\t},\n\n\t\t/**\n\t\t * Calculate visible page numbers with ellipsis for large page counts.\n\t\t * Shows up to 7 page numbers at a time.\n\t\t */\n\t\tvisiblePages() {\n\t\t\tconst current = this.currentPage\n\t\t\tconst total = this.totalPages\n\t\t\tconst pages = []\n\n\t\t\tif (total <= 7) {\n\t\t\t\tfor (let i = 1; i <= total; i++) {\n\t\t\t\t\tpages.push(i)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpages.push(1)\n\n\t\t\t\tif (current <= 4) {\n\t\t\t\t\tfor (let i = 2; i <= 5; i++) {\n\t\t\t\t\t\tpages.push(i)\n\t\t\t\t\t}\n\t\t\t\t\tpages.push('...')\n\t\t\t\t\tpages.push(total)\n\t\t\t\t} else if (current >= total - 3) {\n\t\t\t\t\tpages.push('...')\n\t\t\t\t\tfor (let i = total - 4; i <= total; i++) {\n\t\t\t\t\t\tpages.push(i)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpages.push('...')\n\t\t\t\t\tfor (let i = current - 1; i <= current + 1; i++) {\n\t\t\t\t\t\tpages.push(i)\n\t\t\t\t\t}\n\t\t\t\t\tpages.push('...')\n\t\t\t\t\tpages.push(total)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn pages\n\t\t},\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * Navigate to a specific page.\n\t\t *\n\t\t * @param {number} page Target page number\n\t\t */\n\t\tchangePage(page) {\n\t\t\tif (page !== this.currentPage && page >= 1 && page <= this.totalPages) {\n\t\t\t\t/** @event page-changed Emitted when page changes. Payload: new page number. */\n\t\t\t\tthis.$emit('page-changed', page)\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Change the page size.\n\t\t *\n\t\t * @param {object} option Selected page size option { value, label }\n\t\t */\n\t\tchangePageSize(option) {\n\t\t\tif (option.value !== this.currentPageSize) {\n\t\t\t\t/** @event page-size-changed Emitted when page size changes. Payload: new page size. */\n\t\t\t\tthis.$emit('page-size-changed', option.value)\n\t\t\t}\n\t\t},\n\t},\n}\n</script>\n"],"names":["t"],"mappings":"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"}
|