@xwiki/cristal-dsvuetify 0.13.0 → 0.14.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.
Files changed (66) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/{index-UP1o6s9t.js → index-C4ioHAez.js} +3275 -3259
  3. package/dist/index-C4ioHAez.js.map +1 -0
  4. package/dist/index.es.js +6 -5
  5. package/dist/index.umd.js +10 -9
  6. package/dist/index.umd.js.map +1 -1
  7. package/dist/vue/form/x-checkbox.vue.d.ts +11 -0
  8. package/dist/vue/form/x-file-input.vue.d.ts +6 -6
  9. package/dist/vue/form/x-form.vue.d.ts +2 -1
  10. package/dist/vue/form/x-text-field.vue.d.ts +9 -1
  11. package/dist/vue/x-alert.vue.d.ts +2 -1
  12. package/dist/vue/x-avatar.vue.d.ts +2 -19
  13. package/dist/vue/x-btn.vue.d.ts +2 -1
  14. package/dist/vue/x-dialog.vue.d.ts +7 -8
  15. package/dist/vue/x-load.vue.d.ts +1 -1
  16. package/dist/vue/x-menu-item.vue.d.ts +6 -6
  17. package/dist/vue/x-menu-label.vue.d.ts +2 -1
  18. package/dist/vue/x-menu.vue.d.ts +2 -1
  19. package/dist/vue/x-navigation-tree.vue.d.ts +3 -5
  20. package/dist/vue/x-tab-group.vue.d.ts +4 -3
  21. package/dist/vue/x-tab-panel.vue.d.ts +2 -1
  22. package/dist/vue/x-tab.vue.d.ts +2 -1
  23. package/dist/x-alert-CTAhsN6L.js +46 -0
  24. package/dist/x-alert-CTAhsN6L.js.map +1 -0
  25. package/dist/x-avatar-Ds9aYRI9.js +28 -0
  26. package/dist/x-avatar-Ds9aYRI9.js.map +1 -0
  27. package/dist/{x-btn-DNlhiqjD.js → x-btn-BsiSIiiO.js} +9 -7
  28. package/dist/{x-btn-DNlhiqjD.js.map → x-btn-BsiSIiiO.js.map} +1 -1
  29. package/dist/x-checkbox-CJ3_IJ-Y.js +28 -0
  30. package/dist/x-checkbox-CJ3_IJ-Y.js.map +1 -0
  31. package/dist/x-dialog-C4gz0mOu.js +48 -0
  32. package/dist/x-dialog-C4gz0mOu.js.map +1 -0
  33. package/dist/{x-file-input-BsaodA0p.js → x-file-input-CMM5DWJc.js} +4 -3
  34. package/dist/{x-file-input-BsaodA0p.js.map → x-file-input-CMM5DWJc.js.map} +1 -1
  35. package/dist/{x-form-iQFXj1PW.js → x-form-BLg386BG.js} +2 -2
  36. package/dist/{x-form-iQFXj1PW.js.map → x-form-BLg386BG.js.map} +1 -1
  37. package/dist/x-navigation-tree-BW05Yivz.js +502 -0
  38. package/dist/x-navigation-tree-BW05Yivz.js.map +1 -0
  39. package/dist/{x-tab-group-ngNByee3.js → x-tab-group-Bp7V46k9.js} +5 -5
  40. package/dist/{x-tab-group-ngNByee3.js.map → x-tab-group-Bp7V46k9.js.map} +1 -1
  41. package/dist/x-text-field-BxSiyeFc.js +38 -0
  42. package/dist/x-text-field-BxSiyeFc.js.map +1 -0
  43. package/langs/translation-fr.json +4 -1
  44. package/package.json +13 -13
  45. package/src/components/vuetifyDesignSystemLoader.ts +5 -0
  46. package/src/vue/css/style.css +6 -0
  47. package/src/vue/form/x-checkbox.vue +35 -0
  48. package/src/vue/form/x-file-input.vue +2 -2
  49. package/src/vue/form/x-text-field.vue +2 -0
  50. package/src/vue/x-alert.vue +8 -0
  51. package/src/vue/x-avatar.vue +9 -9
  52. package/src/vue/x-dialog.vue +1 -7
  53. package/src/vue/x-navigation-tree.vue +43 -10
  54. package/src/vue/x-tab-group.vue +2 -2
  55. package/src/vue/x-tab-panel.vue +0 -2
  56. package/dist/index-UP1o6s9t.js.map +0 -1
  57. package/dist/x-alert-Bmt4mXHQ.js +0 -45
  58. package/dist/x-alert-Bmt4mXHQ.js.map +0 -1
  59. package/dist/x-avatar-But_Z7ic.js +0 -20
  60. package/dist/x-avatar-But_Z7ic.js.map +0 -1
  61. package/dist/x-dialog-C-dMkFJk.js +0 -49
  62. package/dist/x-dialog-C-dMkFJk.js.map +0 -1
  63. package/dist/x-navigation-tree-DN2Qz7Sm.js +0 -501
  64. package/dist/x-navigation-tree-DN2Qz7Sm.js.map +0 -1
  65. package/dist/x-text-field-CTsLZhLE.js +0 -31
  66. package/dist/x-text-field-CTsLZhLE.js.map +0 -1
@@ -0,0 +1,38 @@
1
+ import { defineComponent as n, mergeModels as m, useModel as d, computed as i, openBlock as p, createBlock as f, unref as c } from "vue";
2
+ import { t as V } from "./translations-BNEIsfPR.js";
3
+ import { useI18n as b } from "vue-i18n";
4
+ import { a as v } from "./index-C4ioHAez.js";
5
+ const g = /* @__PURE__ */ n({
6
+ __name: "x-text-field",
7
+ props: /* @__PURE__ */ m({
8
+ name: {},
9
+ label: {},
10
+ required: { type: Boolean },
11
+ autofocus: { type: Boolean },
12
+ modelValue: {}
13
+ }, {
14
+ modelValue: {},
15
+ modelModifiers: {}
16
+ }),
17
+ emits: ["update:modelValue"],
18
+ setup(l) {
19
+ const { t: u } = b({
20
+ messages: V
21
+ }), a = l, t = d(l, "modelValue"), r = i(() => {
22
+ const e = [];
23
+ return a.required && e.push((o) => o ? !0 : u("vuetify.text.input.mandatory")), e;
24
+ });
25
+ return (e, o) => (p(), f(c(v), {
26
+ modelValue: t.value,
27
+ "onUpdate:modelValue": o[0] || (o[0] = (s) => t.value = s),
28
+ label: e.label,
29
+ name: e.name,
30
+ autofocus: e.autofocus,
31
+ rules: r.value
32
+ }, null, 8, ["modelValue", "label", "name", "autofocus", "rules"]));
33
+ }
34
+ });
35
+ export {
36
+ g as default
37
+ };
38
+ //# sourceMappingURL=x-text-field-BxSiyeFc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-text-field-BxSiyeFc.js","sources":["../src/vue/form/x-text-field.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport messages from \"../../translations\";\nimport { computed } from \"vue\";\nimport { useI18n } from \"vue-i18n\";\nimport { VTextField } from \"vuetify/components/VTextField\";\nimport type { TextFieldProps } from \"@xwiki/cristal-dsapi\";\n\nconst { t } = useI18n({\n messages,\n});\nconst props = defineProps<TextFieldProps>();\nconst input = defineModel<string>();\n\nconst rules = computed(() => {\n const rulesList = [];\n if (props.required) {\n rulesList.push((value: unknown) => {\n if (value) {\n return true;\n } else {\n return t(\"vuetify.text.input.mandatory\");\n }\n });\n }\n return rulesList;\n});\n</script>\n\n<template>\n <v-text-field\n v-model=\"input\"\n :label=\"label\"\n :name=\"name\"\n :autofocus=\"autofocus\"\n :rules=\"rules\"\n ></v-text-field>\n</template>\n\n<style scoped></style>\n"],"names":["t","useI18n","messages","props","__props","input","_useModel","rules","computed","rulesList","value"],"mappings":";;;;;;;;;;;;;;;;;;AAOM,UAAA,EAAE,GAAAA,EAAE,IAAIC,EAAQ;AAAA,MACpBC,UAAAA;AAAAA,IAAA,CACD,GACKC,IAAQC,GACRC,IAAQC,EAAmBF,GAAA,YAAC,GAE5BG,IAAQC,EAAS,MAAM;AAC3B,YAAMC,IAAY,CAAC;AACnB,aAAIN,EAAM,YACEM,EAAA,KAAK,CAACC,MACVA,IACK,KAEAV,EAAE,8BAA8B,CAE1C,GAEIS;AAAA,IAAA,CACR;;;;;;;;;;;"}
@@ -1 +1,4 @@
1
- {}
1
+ {
2
+ "vuetify.file.input.mandatory": "Champ obligatoire",
3
+ "vuetify.text.input.mandatory": "Champ obligatoire"
4
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xwiki/cristal-dsvuetify",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "license": "LGPL 2.1",
5
5
  "author": "XWiki Org Community <contact@xwiki.org>",
6
6
  "homepage": "https://cristal.xwiki.org/",
@@ -22,15 +22,14 @@
22
22
  },
23
23
  "main": "./dist/index.es.js",
24
24
  "dependencies": {
25
- "inversify": "6.2.0",
25
+ "inversify": "6.2.1",
26
26
  "vue": "3.5.13",
27
- "vue-i18n": "10.0.5",
28
- "vuetify": "3.7.5",
29
- "@xwiki/cristal-document-api": "0.13.0",
30
- "@xwiki/cristal-navigation-tree-api": "0.13.0",
31
- "@xwiki/cristal-api": "0.13.0",
32
- "@xwiki/cristal-dsapi": "0.13.0",
33
- "@xwiki/cristal-model-api": "0.13.0"
27
+ "vue-i18n": "11.0.1",
28
+ "vuetify": "3.7.6",
29
+ "@xwiki/cristal-api": "0.14.0",
30
+ "@xwiki/cristal-model-api": "0.14.0",
31
+ "@xwiki/cristal-document-api": "0.14.0",
32
+ "@xwiki/cristal-navigation-tree-api": "0.14.0"
34
33
  },
35
34
  "peerDependencies": {
36
35
  "reflect-metadata": "0.2.2"
@@ -38,10 +37,11 @@
38
37
  "devDependencies": {
39
38
  "@vue/test-utils": "2.4.6",
40
39
  "reflect-metadata": "0.2.2",
41
- "typescript": "5.6.3",
42
- "vite": "6.0.3",
43
- "vue-tsc": "2.1.10",
44
- "@xwiki/cristal-dev-config": "0.13.0"
40
+ "typescript": "5.7.3",
41
+ "vite": "6.0.11",
42
+ "vue-tsc": "2.2.0",
43
+ "@xwiki/cristal-dev-config": "0.14.0",
44
+ "@xwiki/cristal-dsapi": "0.14.0"
45
45
  },
46
46
  "scripts": {
47
47
  "build": "pnpm compile",
@@ -141,5 +141,10 @@ export class VuetifyDesignSystemLoader implements DesignSystemLoader {
141
141
  "XNavigationTree",
142
142
  () => import("../vue/x-navigation-tree.vue"),
143
143
  );
144
+ registerAsyncComponent(
145
+ app,
146
+ "XCheckbox",
147
+ () => import("../vue/form/x-checkbox.vue"),
148
+ );
144
149
  }
145
150
  }
@@ -25,6 +25,10 @@
25
25
  height: 64px;
26
26
  }
27
27
 
28
+ main ul {
29
+ padding-inline-start: var(--cr-spacing-x-large);
30
+ }
31
+
28
32
  :root {
29
33
  --cr-sizes-max-page-width: 960px; /*This value controls the width of the main content. It should be 100% for spanning text along the whole width or an arbitraty value*/
30
34
  --cr-sizes-main-sidebar-width: 15%; /*The default width of the main sidebar*/
@@ -39,6 +43,8 @@
39
43
  * Typography
40
44
  */
41
45
 
46
+
47
+
42
48
  /* Fonts */
43
49
  --cr-font-mono: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace;
44
50
  --cr-font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,
@@ -0,0 +1,35 @@
1
+ <!--
2
+ See the LICENSE file distributed with this work for additional
3
+ information regarding copyright ownership.
4
+
5
+ This is free software; you can redistribute it and/or modify it
6
+ under the terms of the GNU Lesser General Public License as
7
+ published by the Free Software Foundation; either version 2.1 of
8
+ the License, or (at your option) any later version.
9
+
10
+ This software is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this software; if not, write to the Free
17
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18
+ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19
+ -->
20
+ <script lang="ts" setup>
21
+ import { VCheckbox } from "vuetify/components/VCheckbox";
22
+ import type { CheckboxProps } from "@xwiki/cristal-dsapi";
23
+
24
+ defineProps<CheckboxProps>();
25
+
26
+ const checked = defineModel<boolean>();
27
+ </script>
28
+ <template>
29
+ <v-checkbox
30
+ v-model="checked"
31
+ :label="label"
32
+ :messages="help"
33
+ density="compact"
34
+ ></v-checkbox>
35
+ </template>
@@ -3,13 +3,13 @@ import messages from "../../translations";
3
3
  import { computed, defineModel } from "vue";
4
4
  import { useI18n } from "vue-i18n";
5
5
  import { VFileInput } from "vuetify/components/VFileInput";
6
- import type { TextFieldModel, TextFieldProps } from "@xwiki/cristal-dsapi";
6
+ import type { FileInputModel, TextFieldProps } from "@xwiki/cristal-dsapi";
7
7
 
8
8
  const { t } = useI18n({
9
9
  messages,
10
10
  });
11
11
 
12
- const model = defineModel<TextFieldModel>();
12
+ const model = defineModel<FileInputModel>();
13
13
  const props = defineProps<TextFieldProps>();
14
14
 
15
15
  const rules = computed(() => {
@@ -9,6 +9,7 @@ const { t } = useI18n({
9
9
  messages,
10
10
  });
11
11
  const props = defineProps<TextFieldProps>();
12
+ const input = defineModel<string>();
12
13
 
13
14
  const rules = computed(() => {
14
15
  const rulesList = [];
@@ -27,6 +28,7 @@ const rules = computed(() => {
27
28
 
28
29
  <template>
29
30
  <v-text-field
31
+ v-model="input"
30
32
  :label="label"
31
33
  :name="name"
32
34
  :autofocus="autofocus"
@@ -37,3 +37,11 @@ defineProps<AlertProps>();
37
37
  <slot />
38
38
  </v-alert>
39
39
  </template>
40
+
41
+ <style scoped>
42
+ :deep(.v-alert__content a.router-link-active),
43
+ :deep(.v-alert__content a.router-link-active:visited) {
44
+ color: inherit;
45
+ text-decoration-color: inherit;
46
+ }
47
+ </style>
@@ -17,14 +17,14 @@ License along with this software; if not, write to the Free
17
17
  Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18
18
  02110-1301 USA, or see the FSF site: http://www.fsf.org.
19
19
  -->
20
+ <script lang="ts" setup>
21
+ import type { AvatarProps } from "@xwiki/cristal-dsapi";
22
+
23
+ defineProps<AvatarProps>();
24
+ </script>
20
25
  <template>
21
- <v-avatar :image="image" :size="size"></v-avatar>
26
+ <v-avatar :size="size">
27
+ <v-img v-if="image" :alt="name" :src="image"></v-img>
28
+ <span v-else>{{ name }}</span>
29
+ </v-avatar>
22
30
  </template>
23
- <script lang="ts">
24
- export default {
25
- props: {
26
- image: { type: String, required: true },
27
- size: { type: String, required: true },
28
- },
29
- };
30
- </script>
@@ -18,16 +18,10 @@ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18
18
  02110-1301 USA, or see the FSF site: http://www.fsf.org.
19
19
  -->
20
20
  <script lang="ts" setup>
21
- import { useSlots } from "vue";
22
-
23
21
  defineProps<{
24
22
  title: string;
25
23
  width: string | number | undefined;
26
24
  }>();
27
-
28
- const slots = useSlots();
29
-
30
- // const innerIsActive = ref(props.isActive);
31
25
  </script>
32
26
 
33
27
  <template>
@@ -42,7 +36,7 @@ const slots = useSlots();
42
36
  <v-card-text>
43
37
  <slot name="default" />
44
38
  </v-card-text>
45
- <v-card-actions v-if="slots.footer">
39
+ <v-card-actions v-if="$slots.footer">
46
40
  <slot name="footer" />
47
41
  </v-card-actions>
48
42
  </v-card>
@@ -61,7 +61,6 @@ const treeSource: NavigationTreeSource = cristal
61
61
  .get();
62
62
 
63
63
  const rootNodes: Ref<Array<TreeItem>> = ref([]);
64
- const tree: Ref<VTreeview | undefined> = ref(undefined);
65
64
 
66
65
  const activatedNodes: Ref<Array<string>> = ref(new Array<string>());
67
66
  const expandedNodes: Ref<Array<string>> = ref(new Array<string>());
@@ -166,20 +165,28 @@ function clearSelection() {
166
165
  // eslint-disable-next-line max-statements
167
166
  async function onDocumentDelete(page: PageData) {
168
167
  const parents = treeSource.getParentNodesId(page);
169
- let currentItems: TreeItem[] | undefined = rootNodes.value;
170
- while (currentItems) {
171
- for (const i of currentItems.keys()) {
172
- if (currentItems[i].id == parents[0]) {
168
+ let currentItem: TreeItem | undefined = undefined;
169
+ let currentItemChildren: TreeItem[] | undefined = rootNodes.value;
170
+ let notFound = false;
171
+
172
+ currentItemsLoop: while (currentItemChildren && !notFound) {
173
+ for (const i of currentItemChildren.keys()) {
174
+ if (currentItemChildren[i].id == parents[0]) {
173
175
  if (parents.length == 1) {
174
- currentItems.splice(i, 1);
176
+ currentItemChildren.splice(i, 1);
177
+ if (currentItem && currentItemChildren.length == 0) {
178
+ currentItem!.children = undefined;
179
+ }
175
180
  return;
176
181
  } else {
177
- currentItems = currentItems[i].children;
182
+ currentItem = currentItemChildren[i];
183
+ currentItemChildren = currentItem.children;
178
184
  parents.shift();
179
- break;
185
+ continue currentItemsLoop;
180
186
  }
181
187
  }
182
188
  }
189
+ notFound = true;
183
190
  }
184
191
  }
185
192
 
@@ -190,6 +197,7 @@ async function onDocumentUpdate(page: PageData) {
190
197
  let currentParent: string | undefined = undefined;
191
198
  let currentItems: TreeItem[] | undefined = rootNodes.value;
192
199
  let notFound = false;
200
+ let isRoot = true;
193
201
 
194
202
  currentItemsLoop: while (currentItems && !notFound) {
195
203
  for (const i of currentItems.keys()) {
@@ -208,10 +216,13 @@ async function onDocumentUpdate(page: PageData) {
208
216
  } else {
209
217
  currentParent = currentItems[i].id;
210
218
  if (!currentItems[i].children) {
219
+ // This node had no children, we reset this so new ones can be
220
+ // loaded lazily.
211
221
  currentItems[i].children = [];
212
222
  }
213
223
  currentItems = currentItems[i].children;
214
224
  parents.shift();
225
+ isRoot = false;
215
226
  continue currentItemsLoop;
216
227
  }
217
228
  }
@@ -220,9 +231,14 @@ async function onDocumentUpdate(page: PageData) {
220
231
  }
221
232
 
222
233
  // New page
234
+ if (currentItems.length == 0 && !isRoot) {
235
+ // We don't do anything because this node will be loaded lazily anyway.
236
+ return;
237
+ }
223
238
  const newItems = await treeSource.getChildNodes(
224
239
  currentParent ? currentParent : "",
225
240
  );
241
+ const currentPageParents = treeSource.getParentNodesId(props.currentPage);
226
242
  newItemsLoop: for (const newItem of newItems) {
227
243
  for (const i of currentItems!.keys()) {
228
244
  if (newItem.id == currentItems![i].id) {
@@ -236,13 +252,19 @@ async function onDocumentUpdate(page: PageData) {
236
252
  children: newItem.has_children ? [] : undefined,
237
253
  _location: newItem.location,
238
254
  });
255
+ if (
256
+ currentPageParents.length > 0 &&
257
+ currentPageParents[currentPageParents.length - 1] === newItem.id
258
+ ) {
259
+ // If we add a node, and it's the current page, it should be activated.
260
+ activatedNodes.value = [newItem.id];
261
+ }
239
262
  }
240
263
  }
241
264
  </script>
242
265
 
243
266
  <template>
244
267
  <v-treeview
245
- ref="tree"
246
268
  v-model:opened="expandedNodes"
247
269
  density="compact"
248
270
  :activated="activatedNodes"
@@ -251,7 +273,6 @@ async function onDocumentUpdate(page: PageData) {
251
273
  activatable
252
274
  active-strategy="independent"
253
275
  item-value="id"
254
- open-strategy="multiple"
255
276
  @update:activated="clearSelection"
256
277
  >
257
278
  <template #title="{ item }: { item: any }">
@@ -291,4 +312,16 @@ async function onDocumentUpdate(page: PageData) {
291
312
  :deep(.v-list-item--link) {
292
313
  cursor: default;
293
314
  }
315
+ /*TODO: This section needs to be removed when the oficial fix is released on Vuetify
316
+ https://github.com/vuetifyjs/vuetify/issues/20421#event-16001533054
317
+ START FIX
318
+ */
319
+ :deep(.v-treeview-item:not(.v-list-group__header)) {
320
+ padding-inline-start: calc(39px + 6px) !important;
321
+ }
322
+
323
+ :deep(.v-treeview-item .v-list-item__spacer) {
324
+ width: 4px !important;
325
+ }
326
+ /*END FIX*/
294
327
  </style>
@@ -21,11 +21,11 @@ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21
21
  import { ref } from "vue";
22
22
  const tab = ref(null);
23
23
 
24
- const emits = defineEmits(["change"]);
24
+ const emits = defineEmits(["tab-change"]);
25
25
 
26
26
  function change(tabId: unknown) {
27
27
  if (typeof tabId == "string") {
28
- emits("change", tabId);
28
+ emits("tab-change", tabId);
29
29
  }
30
30
  }
31
31
  </script>
@@ -26,5 +26,3 @@ defineProps<TabPanelProps>();
26
26
  <template>
27
27
  <v-tabs-window-item :value="tabId"><slot></slot></v-tabs-window-item>
28
28
  </template>
29
-
30
- <style scoped></style>