@shwfed/config 2.12.5 → 2.12.6

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 (105) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +5 -0
  3. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.d.vue.ts +68 -68
  4. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/config.vue.d.ts +68 -68
  5. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.d.vue.ts +68 -68
  6. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/runtime.vue.d.ts +68 -68
  7. package/dist/runtime/components/config/blocks/2026-05-06/com.shwfed.block.table/schema.d.ts +34 -34
  8. package/dist/runtime/components/config/index.vue +23 -3
  9. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.text/config.d.vue.ts +22 -22
  10. package/dist/runtime/components/form/fields/2026-04-22/com.shwfed.form.field.text/config.vue.d.ts +22 -22
  11. package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.combobox.single/config.d.vue.ts +16 -16
  12. package/dist/runtime/components/form/fields/2026-04-24/com.shwfed.form.field.combobox.single/config.vue.d.ts +16 -16
  13. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.date/config.d.vue.ts +16 -16
  14. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.date/config.vue.d.ts +16 -16
  15. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.d.vue.ts +18 -18
  16. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.daterange/config.vue.d.ts +18 -18
  17. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetime/config.d.vue.ts +16 -16
  18. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetime/config.vue.d.ts +16 -16
  19. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.d.vue.ts +18 -18
  20. package/dist/runtime/components/form/fields/2026-04-27/com.shwfed.form.field.datetimerange/config.vue.d.ts +18 -18
  21. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/config.d.vue.ts +28 -28
  22. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.number/config.vue.d.ts +28 -28
  23. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.numberrange/config.d.vue.ts +6 -6
  24. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.numberrange/config.vue.d.ts +6 -6
  25. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.switch/config.d.vue.ts +22 -22
  26. package/dist/runtime/components/form/fields/2026-04-28/com.shwfed.form.field.switch/config.vue.d.ts +22 -22
  27. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/config.d.vue.ts +16 -16
  28. package/dist/runtime/components/form/fields/2026-05-13/com.shwfed.form.field.combobox.single.remote/config.vue.d.ts +16 -16
  29. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.d.vue.ts +10 -10
  30. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.vue.d.ts +10 -10
  31. package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.month/config.d.vue.ts +16 -16
  32. package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.month/config.vue.d.ts +16 -16
  33. package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.d.vue.ts +18 -18
  34. package/dist/runtime/components/form/fields/2026-05-24/com.shwfed.form.field.monthrange/config.vue.d.ts +18 -18
  35. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.d.vue.ts +16 -16
  36. package/dist/runtime/components/form/fields/2026-05-25/com.shwfed.form.field.combobox.multi/config.vue.d.ts +16 -16
  37. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +10 -10
  38. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +10 -10
  39. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +10 -10
  40. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +10 -10
  41. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +10 -10
  42. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +10 -10
  43. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +10 -10
  44. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +10 -10
  45. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.d.vue.ts +10 -10
  46. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.vue.d.ts +10 -10
  47. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.d.vue.ts +10 -10
  48. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.vue.d.ts +10 -10
  49. package/dist/runtime/components/sidebar/index.d.vue.ts +22 -3
  50. package/dist/runtime/components/sidebar/index.vue +66 -5
  51. package/dist/runtime/components/sidebar/index.vue.d.ts +22 -3
  52. package/dist/runtime/components/sidebar/node.d.vue.ts +1 -1
  53. package/dist/runtime/components/sidebar/node.vue +33 -13
  54. package/dist/runtime/components/sidebar/node.vue.d.ts +1 -1
  55. package/dist/runtime/components/sidebar/tree.vue +113 -83
  56. package/dist/runtime/components/sidebar/types.d.ts +8 -0
  57. package/dist/runtime/components/sidebar/types.js +1 -0
  58. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
  59. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
  60. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +6 -6
  61. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +6 -6
  62. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
  63. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
  64. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +6 -6
  65. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +6 -6
  66. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
  67. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
  68. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
  69. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
  70. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +12 -12
  71. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +12 -12
  72. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +12 -12
  73. package/dist/runtime/components/table/columns/2026-05-27/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +12 -12
  74. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +12 -12
  75. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +12 -12
  76. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +12 -12
  77. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +12 -12
  78. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +12 -12
  79. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +12 -12
  80. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +12 -12
  81. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +12 -12
  82. package/dist/runtime/components/table/schema.d.ts +68 -68
  83. package/dist/runtime/components/table/utils/row-reorder.d.ts +3 -2
  84. package/dist/runtime/components/table/utils/row-reorder.js +1 -12
  85. package/dist/runtime/components/tabs/index.d.vue.ts +9 -0
  86. package/dist/runtime/components/tabs/index.vue +92 -0
  87. package/dist/runtime/components/tabs/index.vue.d.ts +9 -0
  88. package/dist/runtime/components/tabs/tab.d.vue.ts +22 -0
  89. package/dist/runtime/components/tabs/tab.vue +85 -0
  90. package/dist/runtime/components/tabs/tab.vue.d.ts +22 -0
  91. package/dist/runtime/components/tabs/types.d.ts +19 -0
  92. package/dist/runtime/components/tabs/types.js +0 -0
  93. package/dist/runtime/components/tabs/use-reorder.d.ts +10 -0
  94. package/dist/runtime/components/tabs/use-reorder.js +90 -0
  95. package/dist/runtime/components/tabs/use-tabs.d.ts +46 -0
  96. package/dist/runtime/components/tabs/use-tabs.js +101 -0
  97. package/dist/runtime/components/ui/sidebar/SidebarMenuAction.vue +1 -1
  98. package/dist/runtime/components/ui/sidebar/index.js +2 -2
  99. package/dist/runtime/share/reorder.d.ts +2 -0
  100. package/dist/runtime/share/reorder.js +12 -0
  101. package/dist/runtime/utils/nav-registry.d.ts +19 -0
  102. package/dist/runtime/utils/nav-registry.js +14 -0
  103. package/dist/runtime/utils/page-title-registry.d.ts +3 -0
  104. package/dist/runtime/utils/page-title-registry.js +11 -0
  105. package/package.json +1 -1
@@ -37,6 +37,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
37
37
  readonly displayName?: string | undefined;
38
38
  readonly compatibilityDate: "2026-05-28";
39
39
  readonly readonly?: string | undefined;
40
+ readonly binding?: string | undefined;
41
+ readonly derived?: {
42
+ readonly mode: "formula" | "prefill";
43
+ readonly expression: string;
44
+ } | undefined;
40
45
  readonly dataSource: {
41
46
  readonly data: string;
42
47
  readonly request?: string | undefined;
@@ -50,11 +55,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
50
55
  readonly locale: "en" | "ja" | "ko";
51
56
  readonly message: string;
52
57
  }[]];
53
- readonly binding?: string | undefined;
54
- readonly derived?: {
55
- readonly mode: "formula" | "prefill";
56
- readonly expression: string;
57
- } | undefined;
58
58
  readonly cascade: "independent" | "cascade-down" | "cascade-both";
59
59
  readonly nodeTooltip?: readonly [{
60
60
  readonly locale: "zh";
@@ -112,6 +112,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
112
112
  readonly displayName?: string | undefined;
113
113
  readonly compatibilityDate: "2026-05-28";
114
114
  readonly readonly?: string | undefined;
115
+ readonly binding?: string | undefined;
116
+ readonly derived?: {
117
+ readonly mode: "formula" | "prefill";
118
+ readonly expression: string;
119
+ } | undefined;
115
120
  readonly dataSource: {
116
121
  readonly data: string;
117
122
  readonly request?: string | undefined;
@@ -125,11 +130,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
125
130
  readonly locale: "en" | "ja" | "ko";
126
131
  readonly message: string;
127
132
  }[]];
128
- readonly binding?: string | undefined;
129
- readonly derived?: {
130
- readonly mode: "formula" | "prefill";
131
- readonly expression: string;
132
- } | undefined;
133
133
  readonly cascade: "independent" | "cascade-down" | "cascade-both";
134
134
  readonly nodeTooltip?: readonly [{
135
135
  readonly locale: "zh";
@@ -37,6 +37,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
37
37
  readonly displayName?: string | undefined;
38
38
  readonly compatibilityDate: "2026-05-28";
39
39
  readonly readonly?: string | undefined;
40
+ readonly binding?: string | undefined;
41
+ readonly derived?: {
42
+ readonly mode: "formula" | "prefill";
43
+ readonly expression: string;
44
+ } | undefined;
40
45
  readonly dataSource: {
41
46
  readonly data: string;
42
47
  readonly request?: string | undefined;
@@ -50,11 +55,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
50
55
  readonly locale: "en" | "ja" | "ko";
51
56
  readonly message: string;
52
57
  }[]];
53
- readonly binding?: string | undefined;
54
- readonly derived?: {
55
- readonly mode: "formula" | "prefill";
56
- readonly expression: string;
57
- } | undefined;
58
58
  readonly cascade: "independent" | "cascade-down" | "cascade-both";
59
59
  readonly nodeTooltip?: readonly [{
60
60
  readonly locale: "zh";
@@ -112,6 +112,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
112
112
  readonly displayName?: string | undefined;
113
113
  readonly compatibilityDate: "2026-05-28";
114
114
  readonly readonly?: string | undefined;
115
+ readonly binding?: string | undefined;
116
+ readonly derived?: {
117
+ readonly mode: "formula" | "prefill";
118
+ readonly expression: string;
119
+ } | undefined;
115
120
  readonly dataSource: {
116
121
  readonly data: string;
117
122
  readonly request?: string | undefined;
@@ -125,11 +130,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
125
130
  readonly locale: "en" | "ja" | "ko";
126
131
  readonly message: string;
127
132
  }[]];
128
- readonly binding?: string | undefined;
129
- readonly derived?: {
130
- readonly mode: "formula" | "prefill";
131
- readonly expression: string;
132
- } | undefined;
133
133
  readonly cascade: "independent" | "cascade-down" | "cascade-both";
134
134
  readonly nodeTooltip?: readonly [{
135
135
  readonly locale: "zh";
@@ -37,6 +37,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
37
37
  readonly displayName?: string | undefined;
38
38
  readonly compatibilityDate: "2026-05-28";
39
39
  readonly readonly?: string | undefined;
40
+ readonly binding?: string | undefined;
41
+ readonly derived?: {
42
+ readonly mode: "formula" | "prefill";
43
+ readonly expression: string;
44
+ } | undefined;
40
45
  readonly dataSource: {
41
46
  readonly data: string;
42
47
  readonly request?: string | undefined;
@@ -50,11 +55,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
50
55
  readonly locale: "en" | "ja" | "ko";
51
56
  readonly message: string;
52
57
  }[]];
53
- readonly binding?: string | undefined;
54
- readonly derived?: {
55
- readonly mode: "formula" | "prefill";
56
- readonly expression: string;
57
- } | undefined;
58
58
  readonly nodeTooltip?: readonly [{
59
59
  readonly locale: "zh";
60
60
  readonly message: string;
@@ -111,6 +111,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
111
111
  readonly displayName?: string | undefined;
112
112
  readonly compatibilityDate: "2026-05-28";
113
113
  readonly readonly?: string | undefined;
114
+ readonly binding?: string | undefined;
115
+ readonly derived?: {
116
+ readonly mode: "formula" | "prefill";
117
+ readonly expression: string;
118
+ } | undefined;
114
119
  readonly dataSource: {
115
120
  readonly data: string;
116
121
  readonly request?: string | undefined;
@@ -124,11 +129,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
124
129
  readonly locale: "en" | "ja" | "ko";
125
130
  readonly message: string;
126
131
  }[]];
127
- readonly binding?: string | undefined;
128
- readonly derived?: {
129
- readonly mode: "formula" | "prefill";
130
- readonly expression: string;
131
- } | undefined;
132
132
  readonly nodeTooltip?: readonly [{
133
133
  readonly locale: "zh";
134
134
  readonly message: string;
@@ -37,6 +37,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
37
37
  readonly displayName?: string | undefined;
38
38
  readonly compatibilityDate: "2026-05-28";
39
39
  readonly readonly?: string | undefined;
40
+ readonly binding?: string | undefined;
41
+ readonly derived?: {
42
+ readonly mode: "formula" | "prefill";
43
+ readonly expression: string;
44
+ } | undefined;
40
45
  readonly dataSource: {
41
46
  readonly data: string;
42
47
  readonly request?: string | undefined;
@@ -50,11 +55,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
50
55
  readonly locale: "en" | "ja" | "ko";
51
56
  readonly message: string;
52
57
  }[]];
53
- readonly binding?: string | undefined;
54
- readonly derived?: {
55
- readonly mode: "formula" | "prefill";
56
- readonly expression: string;
57
- } | undefined;
58
58
  readonly nodeTooltip?: readonly [{
59
59
  readonly locale: "zh";
60
60
  readonly message: string;
@@ -111,6 +111,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
111
111
  readonly displayName?: string | undefined;
112
112
  readonly compatibilityDate: "2026-05-28";
113
113
  readonly readonly?: string | undefined;
114
+ readonly binding?: string | undefined;
115
+ readonly derived?: {
116
+ readonly mode: "formula" | "prefill";
117
+ readonly expression: string;
118
+ } | undefined;
114
119
  readonly dataSource: {
115
120
  readonly data: string;
116
121
  readonly request?: string | undefined;
@@ -124,11 +129,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
124
129
  readonly locale: "en" | "ja" | "ko";
125
130
  readonly message: string;
126
131
  }[]];
127
- readonly binding?: string | undefined;
128
- readonly derived?: {
129
- readonly mode: "formula" | "prefill";
130
- readonly expression: string;
131
- } | undefined;
132
132
  readonly nodeTooltip?: readonly [{
133
133
  readonly locale: "zh";
134
134
  readonly message: string;
@@ -15,7 +15,17 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
15
15
  "update:config": (value: Readonly<{
16
16
  kind: "shwfed.component.sidebar";
17
17
  dataSource: Readonly<{
18
- request?: string;
18
+ request
19
+ /**
20
+ * `ShwfedSidebar` — a standalone, data-driven navigation sidebar. A PEER of
21
+ * `ShwfedConfig` (the page body), not a block inside it: its own serializable
22
+ * config (`v-model:config`), its own ⌘/Ctrl-click editor modal, its own CEL
23
+ * context. The navigation tree is data-driven (see `schema.ts` / `tree.vue`).
24
+ *
25
+ * Wrapped in `<ClientOnly>`: the data fetch and localStorage-backed favorites /
26
+ * open-state are client concerns, so SSR would only hydrate-mismatch.
27
+ */
28
+ ?: string;
19
29
  data: string;
20
30
  }>;
21
31
  nodeKey: string;
@@ -30,7 +40,17 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
30
40
  "onUpdate:config"?: ((value: Readonly<{
31
41
  kind: "shwfed.component.sidebar";
32
42
  dataSource: Readonly<{
33
- request?: string;
43
+ request
44
+ /**
45
+ * `ShwfedSidebar` — a standalone, data-driven navigation sidebar. A PEER of
46
+ * `ShwfedConfig` (the page body), not a block inside it: its own serializable
47
+ * config (`v-model:config`), its own ⌘/Ctrl-click editor modal, its own CEL
48
+ * context. The navigation tree is data-driven (see `schema.ts` / `tree.vue`).
49
+ *
50
+ * Wrapped in `<ClientOnly>`: the data fetch and localStorage-backed favorites /
51
+ * open-state are client concerns, so SSR would only hydrate-mismatch.
52
+ */
53
+ ?: string;
34
54
  data: string;
35
55
  }>;
36
56
  nodeKey: string;
@@ -44,7 +64,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
44
64
  }>, {
45
65
  width: string;
46
66
  collapsible: "offcanvas" | "icon" | "none";
47
- storageKey: string;
48
67
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
49
68
  declare const _default: typeof __VLS_export;
50
69
  export default _default;
@@ -1,5 +1,7 @@
1
1
  <script setup>
2
2
  import { computed, ref, watch } from "vue";
3
+ import { useLocalStorage } from "@vueuse/core";
4
+ import { useRuntimeConfig } from "#app";
3
5
  import { injectCELContext } from "../../utils/cel-context";
4
6
  import { Sidebar, SidebarProvider } from "../ui/sidebar";
5
7
  import ShwfedModal from "../modal.vue";
@@ -19,10 +21,54 @@ const config = computed({
19
21
  const props = defineProps({
20
22
  configure: { type: Function, required: false },
21
23
  editable: { type: Boolean, required: false },
22
- storageKey: { type: String, required: false, default: "shwfed-sidebar" },
24
+ storageKey: { type: String, required: false },
23
25
  collapsible: { type: String, required: false, default: "none" },
24
26
  width: { type: String, required: false, default: "13rem" }
25
27
  });
28
+ const runtimeConfig = useRuntimeConfig();
29
+ const job = runtimeConfig.public.shwfed.ci.job;
30
+ const resolvedStorageKey = props.storageKey ?? `shwfed:sidebar:${job ?? "default"}`;
31
+ const MIN_WIDTH = 200;
32
+ const MAX_WIDTH = 480;
33
+ function toPx(w) {
34
+ const rem = /^([\d.]+)rem$/.exec(w);
35
+ if (rem?.[1]) return Math.round(Number.parseFloat(rem[1]) * 16);
36
+ const px = /^([\d.]+)px$/.exec(w);
37
+ if (px?.[1]) return Math.round(Number.parseFloat(px[1]));
38
+ return 240;
39
+ }
40
+ function clampWidth(px) {
41
+ return Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, Math.round(px)));
42
+ }
43
+ const sidebarWidth = useLocalStorage(`${resolvedStorageKey}:width`, clampWidth(toPx(props.width)));
44
+ const widthStyle = computed(() => `${clampWidth(sidebarWidth.value)}px`);
45
+ const dragging = ref(false);
46
+ const previewX = ref(0);
47
+ let sidebarLeft = 0;
48
+ function startResize(event) {
49
+ event.preventDefault();
50
+ const rect = event.currentTarget.getBoundingClientRect();
51
+ sidebarLeft = rect.left + rect.width / 2 - sidebarWidth.value;
52
+ previewX.value = clampWidth(event.clientX - sidebarLeft);
53
+ dragging.value = true;
54
+ const prevSelect = document.body.style.userSelect;
55
+ const prevCursor = document.body.style.cursor;
56
+ document.body.style.userSelect = "none";
57
+ document.body.style.cursor = "col-resize";
58
+ const onMove = (e) => {
59
+ previewX.value = clampWidth(e.clientX - sidebarLeft);
60
+ };
61
+ const onUp = () => {
62
+ window.removeEventListener("pointermove", onMove);
63
+ window.removeEventListener("pointerup", onUp);
64
+ document.body.style.userSelect = prevSelect;
65
+ document.body.style.cursor = prevCursor;
66
+ dragging.value = false;
67
+ sidebarWidth.value = previewX.value;
68
+ };
69
+ window.addEventListener("pointermove", onMove);
70
+ window.addEventListener("pointerup", onUp);
71
+ }
26
72
  const inheritedCEL = injectCELContext();
27
73
  const hostConfigure = props.configure ?? (() => {
28
74
  });
@@ -60,19 +106,34 @@ function onRootClick(event) {
60
106
  @click.capture="onRootClick"
61
107
  >
62
108
  <SidebarProvider
63
- class="w-fit"
64
- :style="{ '--sidebar-width': width }"
109
+ class="relative w-fit"
110
+ :style="{ '--sidebar-width': widthStyle }"
65
111
  >
66
112
  <Sidebar
67
113
  :collapsible="collapsible"
68
- class="sticky h-full"
114
+ class="sticky h-full border-r border-zinc-200"
69
115
  >
70
116
  <SidebarTree
71
117
  :config="config"
72
118
  :configure="mergedConfigure"
73
- :storage-key="storageKey"
119
+ :storage-key="resolvedStorageKey"
74
120
  />
121
+ <!-- Resize: a wide, invisible hit area straddling the border, with a
122
+ thin line that only faintly appears on hover. -->
123
+ <div
124
+ class="group/resize absolute inset-y-0 right-0 z-20 w-3 translate-x-1/2 cursor-col-resize touch-none"
125
+ @pointerdown="startResize"
126
+ >
127
+ <div class="mx-auto h-full w-px transition-colors group-hover/resize:bg-zinc-300" />
128
+ </div>
75
129
  </Sidebar>
130
+ <!-- Drag preview — moved purely via `transform` (no reflow); the real
131
+ width snaps to it on release. -->
132
+ <div
133
+ v-if="dragging"
134
+ class="pointer-events-none absolute inset-y-0 left-0 z-30 w-0.5 bg-(--primary) will-change-transform"
135
+ :style="{ transform: `translateX(${previewX}px)` }"
136
+ />
76
137
  </SidebarProvider>
77
138
  </div>
78
139
 
@@ -15,7 +15,17 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
15
15
  "update:config": (value: Readonly<{
16
16
  kind: "shwfed.component.sidebar";
17
17
  dataSource: Readonly<{
18
- request?: string;
18
+ request
19
+ /**
20
+ * `ShwfedSidebar` — a standalone, data-driven navigation sidebar. A PEER of
21
+ * `ShwfedConfig` (the page body), not a block inside it: its own serializable
22
+ * config (`v-model:config`), its own ⌘/Ctrl-click editor modal, its own CEL
23
+ * context. The navigation tree is data-driven (see `schema.ts` / `tree.vue`).
24
+ *
25
+ * Wrapped in `<ClientOnly>`: the data fetch and localStorage-backed favorites /
26
+ * open-state are client concerns, so SSR would only hydrate-mismatch.
27
+ */
28
+ ?: string;
19
29
  data: string;
20
30
  }>;
21
31
  nodeKey: string;
@@ -30,7 +40,17 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
30
40
  "onUpdate:config"?: ((value: Readonly<{
31
41
  kind: "shwfed.component.sidebar";
32
42
  dataSource: Readonly<{
33
- request?: string;
43
+ request
44
+ /**
45
+ * `ShwfedSidebar` — a standalone, data-driven navigation sidebar. A PEER of
46
+ * `ShwfedConfig` (the page body), not a block inside it: its own serializable
47
+ * config (`v-model:config`), its own ⌘/Ctrl-click editor modal, its own CEL
48
+ * context. The navigation tree is data-driven (see `schema.ts` / `tree.vue`).
49
+ *
50
+ * Wrapped in `<ClientOnly>`: the data fetch and localStorage-backed favorites /
51
+ * open-state are client concerns, so SSR would only hydrate-mismatch.
52
+ */
53
+ ?: string;
34
54
  data: string;
35
55
  }>;
36
56
  nodeKey: string;
@@ -44,7 +64,6 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
44
64
  }>, {
45
65
  width: string;
46
66
  collapsible: "offcanvas" | "icon" | "none";
47
- storageKey: string;
48
67
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
49
68
  declare const _default: typeof __VLS_export;
50
69
  export default _default;
@@ -1,4 +1,4 @@
1
- import type { NavNode } from './types.js';
1
+ import { type NavNode } from './types.js';
2
2
  import type { SidebarFavorites } from './favorites.js';
3
3
  type __VLS_Props = {
4
4
  node: NavNode;
@@ -1,4 +1,5 @@
1
1
  <script setup>
2
+ import { computed, inject } from "vue";
2
3
  import { Icon } from "@iconify/vue";
3
4
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../ui/collapsible";
4
5
  import {
@@ -7,35 +8,52 @@ import {
7
8
  SidebarMenuItem,
8
9
  SidebarMenuSub
9
10
  } from "../ui/sidebar";
11
+ import { SIDEBAR_ACTIVE_KEYS } from "./types";
10
12
  defineOptions({ name: "ShwfedSidebarNode" });
11
13
  const props = defineProps({
12
14
  node: { type: Object, required: true },
13
15
  favorites: { type: null, required: true }
14
16
  });
17
+ const activeKeys = inject(SIDEBAR_ACTIVE_KEYS, void 0);
18
+ const isActive = computed(() => {
19
+ const keys = activeKeys?.value;
20
+ if (!keys) return false;
21
+ if (keys.has(props.node.key)) return true;
22
+ const stack = [...props.node.children];
23
+ while (stack.length) {
24
+ const n = stack.pop();
25
+ if (keys.has(n.key)) return true;
26
+ for (const c of n.children) stack.push(c);
27
+ }
28
+ return false;
29
+ });
30
+ const isLeaf = computed(() => props.node.children.length === 0 && !!props.node.route);
15
31
  function onOpenUpdate(open) {
16
32
  props.favorites.setOpen(props.node.key, open);
17
33
  }
18
34
  </script>
19
35
 
20
36
  <template>
21
- <SidebarMenuItem>
37
+ <SidebarMenuItem :class="isLeaf ? 'group/nav-leaf' : void 0">
22
38
  <!-- Group: collapsible, recurses into a sub-menu -->
23
39
  <Collapsible
24
40
  v-if="node.children.length"
25
- class="group/collapsible"
26
- :open="favorites.isOpen(node.key, true)"
41
+ :open="favorites.isOpen(node.key, false)"
27
42
  @update:open="onOpenUpdate"
28
43
  >
29
44
  <CollapsibleTrigger as-child>
30
- <SidebarMenuButton>
45
+ <SidebarMenuButton
46
+ :is-active="isActive"
47
+ :data-nav-key="node.key"
48
+ >
31
49
  <Icon
32
50
  v-if="node.icon"
33
51
  :icon="node.icon"
34
52
  />
35
- <span>{{ node.label }}</span>
53
+ <span class="truncate">{{ node.label }}</span>
36
54
  <Icon
37
- icon="fluent:chevron-right-20-regular"
38
- class="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90"
55
+ icon="fluent:chevron-down-20-regular"
56
+ class="ml-auto shrink-0 text-zinc-400"
39
57
  />
40
58
  </SidebarMenuButton>
41
59
  </CollapsibleTrigger>
@@ -57,28 +75,30 @@ function onOpenUpdate(open) {
57
75
  :to="node.route"
58
76
  custom
59
77
  >
60
- <template #default="{ navigate, isExactActive }">
78
+ <template #default="{ navigate }">
61
79
  <SidebarMenuButton
62
80
  as-child
63
- :is-active="isExactActive"
81
+ :is-active="isActive"
82
+ :class="isActive ? void 0 : 'group-hover/nav-leaf:bg-zinc-100 group-hover/nav-leaf:text-zinc-900'"
64
83
  >
65
84
  <button
66
85
  type="button"
86
+ :data-nav-key="node.key"
67
87
  @click="navigate"
68
88
  >
69
89
  <Icon
70
90
  v-if="node.icon"
71
91
  :icon="node.icon"
72
92
  />
73
- <span>{{ node.label }}</span>
93
+ <span class="truncate">{{ node.label }}</span>
74
94
  </button>
75
95
  </SidebarMenuButton>
76
96
  </template>
77
97
  </NuxtLink>
78
98
  <SidebarMenuAction
79
99
  v-if="node.favoritable"
80
- :show-on-hover="!favorites.isFavorite(node.key)"
81
- class="text-yellow-500!"
100
+ class="text-yellow-500! transition-opacity"
101
+ :class="favorites.isFavorite(node.key) ? 'opacity-100' : 'md:opacity-0 group-hover/nav-leaf:opacity-100 group-focus-within/nav-leaf:opacity-100'"
82
102
  @click.stop="favorites.toggleFavorite(node.key)"
83
103
  >
84
104
  <Icon :icon="favorites.isFavorite(node.key) ? 'fluent:star-20-filled' : 'fluent:star-20-regular'" />
@@ -95,7 +115,7 @@ function onOpenUpdate(open) {
95
115
  v-if="node.icon"
96
116
  :icon="node.icon"
97
117
  />
98
- <span>{{ node.label }}</span>
118
+ <span class="truncate">{{ node.label }}</span>
99
119
  </span>
100
120
  </SidebarMenuButton>
101
121
  </SidebarMenuItem>
@@ -1,4 +1,4 @@
1
- import type { NavNode } from './types.js';
1
+ import { type NavNode } from './types.js';
2
2
  import type { SidebarFavorites } from './favorites.js';
3
3
  type __VLS_Props = {
4
4
  node: NavNode;