@shwfed/config 2.10.11 → 2.11.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 (155) hide show
  1. package/dist/mcp.mjs +1085 -925
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{FieldGroup.vue_vue_type_script_setup_true_lang-DSupaUBQ.js → FieldGroup.vue_vue_type_script_setup_true_lang-UfhMyymD.js} +1 -1
  4. package/dist/preview/assets/{badge-BpMIBZb2.js → badge-CJ9IQ3Jx.js} +1 -1
  5. package/dist/preview/assets/{config-CM4nX_7y.js → config--Vx4fL61.js} +1 -1
  6. package/dist/preview/assets/{config-CujkaO8S.js → config-5PPug5mk.js} +1 -1
  7. package/dist/preview/assets/{config-c2iiXckz.js → config-7V1qHjUk.js} +1 -1
  8. package/dist/preview/assets/{config-DrkDnICQ.js → config-BYktCefJ.js} +1 -1
  9. package/dist/preview/assets/{config-Cc1ThF9T.js → config-BeRYF_cz.js} +1 -1
  10. package/dist/preview/assets/{config-DbtYnaaf.js → config-BldsYfGM.js} +1 -1
  11. package/dist/preview/assets/{config-BCCT-UCw.js → config-CQrDCzYN.js} +1 -1
  12. package/dist/preview/assets/{config-CY9L8__h.js → config-C_g-FYCR.js} +1 -1
  13. package/dist/preview/assets/{config-Bz643_RE.js → config-DIsAIc7H.js} +1 -1
  14. package/dist/preview/assets/{config-CNJS9Ncm.js → config-DPX7vGqV.js} +1 -1
  15. package/dist/preview/assets/{config-C7nJ8jl6.js → config-DpLMetys.js} +1 -1
  16. package/dist/preview/assets/{config-Bx4-IdW5.js → config-IMd4FZi8.js} +1 -1
  17. package/dist/preview/assets/{config-v7UFMF25.js → config-N-FdgfwK.js} +1 -1
  18. package/dist/preview/assets/{config-agH4hNej.js → config-uUF-UHPt.js} +1 -1
  19. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-B1dZHF9Z.js → definition.vue_vue_type_script_setup_true_lang-B_PKfe3G.js} +1 -1
  20. package/dist/preview/assets/index-8Ph-sFDI.css +1 -0
  21. package/dist/preview/assets/index-BCl1NN6k.js +763 -0
  22. package/dist/preview/assets/index-Core7vRW.js +1 -0
  23. package/dist/preview/assets/{index-B10aTz32.js → index-DKWp47QP.js} +1 -1
  24. package/dist/preview/assets/{item-DxWeqOxe.js → item-XsW7swFt.js} +1 -1
  25. package/dist/preview/assets/{runtime-CeItNJdF.js → runtime-B-ABO0r0.js} +1 -1
  26. package/dist/preview/assets/{runtime-C6oMTKIZ.js → runtime-BeHohaOZ.js} +1 -1
  27. package/dist/preview/assets/{runtime-rpKOBs2Q.js → runtime-BiFFwOIl.js} +1 -1
  28. package/dist/preview/assets/{runtime-BO_Ak4ly.js → runtime-ByArW-jJ.js} +1 -1
  29. package/dist/preview/assets/{runtime-3VPnK4Ve.js → runtime-CpVTGNFZ.js} +1 -1
  30. package/dist/preview/assets/{runtime-DQK6Vajf.js → runtime-DQ1TnQ7n.js} +1 -1
  31. package/dist/preview/assets/{runtime-P58D1JCj.js → runtime-DY7hr7v1.js} +1 -1
  32. package/dist/preview/assets/{runtime-BcWQ55Ub.js → runtime-Dn172S7t.js} +1 -1
  33. package/dist/preview/assets/{runtime-DwgCzoDf.js → runtime-JxBzvGnw.js} +1 -1
  34. package/dist/preview/assets/{runtime-D6jswLOt.js → runtime-bq0hmEXY.js} +1 -1
  35. package/dist/preview/assets/{schema-meta-BtDKldOy.js → schema-meta-CZ9yXnsa.js} +1 -1
  36. package/dist/preview/index.html +2 -2
  37. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.d.vue.ts +22 -22
  38. package/dist/runtime/components/form/fields/2026-05-23/com.shwfed.form.field.tree.multi/config.vue.d.ts +22 -22
  39. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +22 -22
  40. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +22 -22
  41. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +22 -22
  42. package/dist/runtime/components/form/fields/2026-05-26/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +22 -22
  43. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.d.vue.ts +22 -22
  44. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.multi/config.vue.d.ts +22 -22
  45. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.d.vue.ts +22 -22
  46. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.combobox.single/config.vue.d.ts +22 -22
  47. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.d.vue.ts +22 -22
  48. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.multi/config.vue.d.ts +22 -22
  49. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.d.vue.ts +22 -22
  50. package/dist/runtime/components/form/fields/2026-05-28/com.shwfed.form.field.tree.single/config.vue.d.ts +22 -22
  51. package/dist/runtime/components/form/fields/2026-06-09/com.shwfed.form.field.upload/runtime.vue +23 -1
  52. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.date/config.vue +30 -0
  53. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.date/schema.d.ts +2 -1
  54. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.date/schema.js +1 -1
  55. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.icon/config.vue +30 -0
  56. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.icon/schema.d.ts +2 -1
  57. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.icon/schema.js +7 -4
  58. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.number/config.vue +30 -0
  59. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.number/schema.d.ts +2 -1
  60. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.number/schema.js +1 -1
  61. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.text/config.vue +30 -0
  62. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.text/schema.d.ts +2 -1
  63. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.text/schema.js +1 -1
  64. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch/schema.d.ts +2 -1
  65. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch/schema.js +1 -0
  66. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/config.vue +30 -0
  67. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/schema.d.ts +2 -1
  68. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/schema.js +1 -1
  69. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/config.vue +143 -35
  70. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/runtime.vue +35 -9
  71. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/schema.d.ts +136 -1
  72. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/schema.js +20 -6
  73. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/config.vue +67 -32
  74. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/runtime.vue +6 -9
  75. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/schema.d.ts +4 -1
  76. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/schema.js +2 -5
  77. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/config.vue +148 -33
  78. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/runtime.vue +35 -9
  79. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/schema.d.ts +136 -1
  80. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/schema.js +20 -6
  81. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +2 -2
  82. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +2 -2
  83. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/schema.d.ts +1 -1
  84. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/schema.js +1 -0
  85. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.d.vue.ts +2 -2
  86. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.vue.d.ts +2 -2
  87. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/schema.d.ts +1 -1
  88. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/schema.js +1 -0
  89. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +2 -2
  90. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +2 -2
  91. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/schema.d.ts +1 -1
  92. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/schema.js +1 -0
  93. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.d.vue.ts +2 -2
  94. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.vue.d.ts +2 -2
  95. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/schema.d.ts +1 -1
  96. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/schema.js +1 -0
  97. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.d.vue.ts +2 -2
  98. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +2 -2
  99. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/schema.d.ts +1 -1
  100. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/schema.js +1 -0
  101. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.d.vue.ts +2 -2
  102. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +2 -2
  103. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/schema.d.ts +1 -1
  104. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/schema.js +1 -0
  105. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.d.vue.ts +4 -2
  106. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue +61 -22
  107. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue.d.ts +4 -2
  108. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/runtime.vue +6 -9
  109. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/schema.d.ts +4 -1
  110. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/schema.js +3 -4
  111. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.d.vue.ts +4 -2
  112. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue +61 -22
  113. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue.d.ts +4 -2
  114. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/runtime.vue +6 -9
  115. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/schema.d.ts +4 -1
  116. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/schema.js +3 -4
  117. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +4 -2
  118. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.vue +67 -23
  119. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +4 -2
  120. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/runtime.vue +6 -9
  121. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/schema.d.ts +4 -1
  122. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/schema.js +2 -4
  123. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +4 -2
  124. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.vue +67 -23
  125. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +4 -2
  126. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/runtime.vue +6 -9
  127. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/schema.d.ts +4 -1
  128. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/schema.js +2 -4
  129. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/config.vue +67 -32
  130. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/runtime.vue +14 -8
  131. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/schema.d.ts +4 -1
  132. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/schema.js +2 -5
  133. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/config.d.vue.ts +10 -0
  134. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/config.vue +752 -0
  135. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/config.vue.d.ts +10 -0
  136. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/runtime.d.vue.ts +9 -0
  137. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/runtime.vue +149 -0
  138. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/runtime.vue.d.ts +9 -0
  139. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/schema.d.ts +90 -0
  140. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/schema.js +119 -0
  141. package/dist/runtime/components/table/index.vue +46 -7
  142. package/dist/runtime/components/table/utils/runtime.d.ts +1 -0
  143. package/dist/runtime/components/table/utils/runtime.js +5 -0
  144. package/dist/runtime/components/table/utils/shared.d.ts +3 -1
  145. package/dist/runtime/components/table/utils/shared.js +17 -5
  146. package/dist/runtime/components/ui/date-picker/DatePicker.d.vue.ts +1 -0
  147. package/dist/runtime/components/ui/date-picker/DatePicker.vue +3 -0
  148. package/dist/runtime/components/ui/date-picker/DatePicker.vue.d.ts +1 -0
  149. package/dist/runtime/components/ui/date-range-picker/DateRangePicker.d.vue.ts +1 -0
  150. package/dist/runtime/components/ui/date-range-picker/DateRangePicker.vue +2 -0
  151. package/dist/runtime/components/ui/date-range-picker/DateRangePicker.vue.d.ts +1 -0
  152. package/package.json +1 -1
  153. package/dist/preview/assets/index-Cc4BT5dc.css +0 -1
  154. package/dist/preview/assets/index-DdySlgoq.js +0 -763
  155. package/dist/preview/assets/index-j5Pri4vN.js +0 -1
@@ -12,8 +12,15 @@ import {
12
12
  InputGroupInput,
13
13
  InputGroupNumberField
14
14
  } from "../../../../ui/input-group";
15
+ import {
16
+ DropdownMenu,
17
+ DropdownMenuContent,
18
+ DropdownMenuItem,
19
+ DropdownMenuTrigger
20
+ } from "../../../../ui/dropdown-menu";
15
21
  import { getStructFieldDescription, getStructFieldTitle } from "../../../utils/schema-meta";
16
22
  import { Markdown } from "../../../../ui/markdown";
23
+ import { Switch } from "../../../../ui/switch";
17
24
  import DerivedValueEditor from "../../../../form/DerivedValueEditor.vue";
18
25
  import { schema } from "./schema";
19
26
  defineOptions({ name: "ShwfedTableSwitchRendererConfig" });
@@ -22,6 +29,14 @@ const fieldSchema = schema(() => {
22
29
  });
23
30
  const fieldTitle = (field) => getStructFieldTitle(fieldSchema, field) ?? field;
24
31
  const fieldDescription = (field) => getStructFieldDescription(fieldSchema, field);
32
+ const ALIGN_OPTIONS = [
33
+ { value: "left", label: "\u5DE6\u5BF9\u9F50", icon: "fluent:text-align-left-20-regular" },
34
+ { value: "center", label: "\u5C45\u4E2D", icon: "fluent:text-align-center-20-regular" },
35
+ { value: "right", label: "\u53F3\u5BF9\u9F50", icon: "fluent:text-align-right-20-regular" }
36
+ ];
37
+ const currentAlignIcon = computed(
38
+ () => (ALIGN_OPTIONS.find((o) => o.value === (value.value.align ?? "center")) ?? ALIGN_OPTIONS[1]).icon
39
+ );
25
40
  const ROW_VARS = {
26
41
  row: { type: "dyn", label: "\u5F53\u524D\u884C\u6570\u636E" },
27
42
  index: { type: "number", label: "\u884C\u7D22\u5F15" }
@@ -38,17 +53,6 @@ const bindingText = computed({
38
53
  }
39
54
  }
40
55
  });
41
- const hiddenModel = computed({
42
- get: () => value.value.hidden ?? "",
43
- set: (v) => {
44
- if (v === "") {
45
- const { hidden: _drop, ...rest } = value.value;
46
- value.value = rest;
47
- } else {
48
- value.value = { ...value.value, hidden: v };
49
- }
50
- }
51
- });
52
56
  const disabledModel = computed({
53
57
  get: () => value.value.disabled ?? "",
54
58
  set: (v) => {
@@ -71,6 +75,14 @@ const readonlyModel = computed({
71
75
  }
72
76
  }
73
77
  });
78
+ function onHiddenChange(v) {
79
+ if (v) {
80
+ value.value = { ...value.value, hidden: true };
81
+ } else {
82
+ const { hidden: _drop, ...rest } = value.value;
83
+ value.value = rest;
84
+ }
85
+ }
74
86
  const derivedModel = computed({
75
87
  get: () => value.value.derived,
76
88
  set: (v) => {
@@ -165,6 +177,29 @@ const derivedModel = computed({
165
177
  {{ fieldTitle("size") }}
166
178
  </FieldLabel>
167
179
  <InputGroup>
180
+ <InputGroupAddon align="inline-start">
181
+ <DropdownMenu>
182
+ <DropdownMenuTrigger as-child>
183
+ <InputGroupButton
184
+ variant="ghost"
185
+ size="xs"
186
+ :title="fieldTitle('align')"
187
+ >
188
+ <Icon :icon="currentAlignIcon" />
189
+ </InputGroupButton>
190
+ </DropdownMenuTrigger>
191
+ <DropdownMenuContent align="start">
192
+ <DropdownMenuItem
193
+ v-for="opt in ALIGN_OPTIONS"
194
+ :key="opt.value"
195
+ @select="value = { ...value, align: opt.value }"
196
+ >
197
+ <Icon :icon="opt.icon" />
198
+ {{ opt.label }}
199
+ </DropdownMenuItem>
200
+ </DropdownMenuContent>
201
+ </DropdownMenu>
202
+ </InputGroupAddon>
168
203
  <InputGroupNumberField
169
204
  :model-value="value.size"
170
205
  :disabled="value.grow"
@@ -223,27 +258,6 @@ const derivedModel = computed({
223
258
  </Field>
224
259
  </div>
225
260
  <div class="grid grid-cols-2 gap-x-6 gap-y-4">
226
- <Field orientation="vertical">
227
- <FieldLabel class="text-xs text-zinc-500">
228
- <template
229
- v-if="fieldDescription('hidden')"
230
- #tooltip
231
- >
232
- <Markdown
233
- :source="fieldDescription('hidden')"
234
- block
235
- class="prose prose-sm prose-zinc"
236
- />
237
- </template>
238
- {{ fieldTitle("hidden") }}
239
- </FieldLabel>
240
- <ExpressionEditor
241
- v-model="hiddenModel"
242
- placeholder="例:row.archived"
243
- result-type="bool"
244
- :extra-vars="ROW_VARS"
245
- />
246
- </Field>
247
261
  <Field orientation="vertical">
248
262
  <FieldLabel class="text-xs text-zinc-500">
249
263
  <template
@@ -347,6 +361,27 @@ const derivedModel = computed({
347
361
  </InputGroupAddon>
348
362
  </InputGroup>
349
363
  </Field>
364
+ <Field orientation="vertical">
365
+ <FieldLabel class="text-xs text-zinc-500">
366
+ <template
367
+ v-if="fieldDescription('hidden')"
368
+ #tooltip
369
+ >
370
+ <Markdown
371
+ :source="fieldDescription('hidden')"
372
+ block
373
+ class="prose prose-sm prose-zinc"
374
+ />
375
+ </template>
376
+ {{ fieldTitle("hidden") }}
377
+ </FieldLabel>
378
+ <div>
379
+ <Switch
380
+ :model-value="value.hidden ?? false"
381
+ @update:model-value="onHiddenChange"
382
+ />
383
+ </div>
384
+ </Field>
350
385
  </div>
351
386
  </div>
352
387
  </template>
@@ -8,6 +8,7 @@ import { useFormReadonly } from "../../../../form/utils/readonly";
8
8
  import { getLocalizedText } from "../../../../../share/locale";
9
9
  import { Switch } from "../../../../ui/switch";
10
10
  import { useFieldValue } from "../../../../form/utils/field-value";
11
+ import { JUSTIFY_CLASS } from "../../../utils/runtime";
11
12
  defineOptions({ name: "ShwfedTableSwitchRendererRuntime" });
12
13
  const props = defineProps({
13
14
  column: { type: null, required: true },
@@ -25,7 +26,6 @@ function evalBool(expression, label) {
25
26
  return false;
26
27
  }
27
28
  }
28
- const isHidden = computed(() => evalBool(props.column.hidden, "hidden"));
29
29
  const isDisabled = computed(() => evalBool(props.column.disabled, "disabled"));
30
30
  const formReadonly = useFormReadonly();
31
31
  const isReadonly = computed(
@@ -40,6 +40,7 @@ const trueText = computed(
40
40
  const falseText = computed(
41
41
  () => getLocalizedText(props.column.falseLabel, locale.value) || "\u5426"
42
42
  );
43
+ const justifyClass = computed(() => JUSTIFY_CLASS[props.column.align ?? "center"] ?? JUSTIFY_CLASS.center);
43
44
  const { draft, commit } = useFieldValue({
44
45
  binding: () => props.column.binding,
45
46
  fromState: (raw) => raw === true,
@@ -56,23 +57,19 @@ function onUpdate(next) {
56
57
  Row budget matches the editable text/number cells: 2px outer inset around
57
58
  an `h-7` (28px) row — 32px total. The switch is centered inside that row;
58
59
  `sm` size (h-3.5) keeps it visually compact against the surrounding cells.
59
- Every branch (hidden / readonly / editable) is sized identically so rows
60
+ Every branch (readonly / editable) is sized identically so rows
60
61
  do not jump when a CEL condition flips.
61
62
  -->
62
63
  <div class="p-[0.125rem] w-full">
63
64
  <span
64
- v-if="isHidden"
65
- class="block h-7 w-full"
66
- />
67
- <span
68
- v-else-if="effectiveReadonly"
69
- class="flex items-center justify-center h-7 w-full px-2 text-[0.75rem] text-zinc-700 truncate"
65
+ v-if="effectiveReadonly"
66
+ :class="['flex items-center h-7 w-full px-2 text-[0.75rem] text-zinc-700 truncate', justifyClass]"
70
67
  >
71
68
  {{ draft ? trueText : falseText }}
72
69
  </span>
73
70
  <span
74
71
  v-else
75
- class="flex items-center justify-center h-7 w-full"
72
+ :class="['flex items-center h-7 w-full', justifyClass]"
76
73
  >
77
74
  <Switch
78
75
  size="sm"
@@ -9,7 +9,9 @@ export declare const metadata: {
9
9
  readonly icon: "fluent:toggle-left-20-regular";
10
10
  };
11
11
  export declare function schema(configure: (env: Environment) => void): Schema.Struct<{
12
- hidden: Schema.optional<Schema.Schema<string, string, never>>;
12
+ align: Schema.optionalWith<Schema.Literal<["left", "center", "right"]>, {
13
+ default: () => "center";
14
+ }>;
13
15
  disabled: Schema.optional<Schema.Schema<string, string, never>>;
14
16
  readonly: Schema.optional<Schema.Schema<string, string, never>>;
15
17
  trueLabel: Schema.optional<Schema.TupleType<readonly [Schema.Struct<{
@@ -49,6 +51,7 @@ export declare function schema(configure: (env: Environment) => void): Schema.St
49
51
  locale: Schema.Literal<["ja", "en", "ko"]>;
50
52
  message: Schema.SchemaClass<string, string, never>;
51
53
  }>]>>;
54
+ hidden: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
52
55
  id: Schema.refine<string, typeof Schema.String>;
53
56
  groupId: Schema.optional<typeof Schema.UUID>;
54
57
  type: Schema.Literal<["com.shwfed.table.column.switch.local"]>;
@@ -1,7 +1,7 @@
1
1
  import { Effect, Schema } from "effect";
2
2
  import { getProperty } from "dot-prop";
3
3
  import { Locale } from "../../../../../share/locale.js";
4
- import { CelRowAccess, derivedRowField, editableColumnFields, editableHeader } from "../../../utils/shared.js";
4
+ import { Align, CelRowAccess, derivedRowField, editableColumnFields, editableHeader } from "../../../utils/shared.js";
5
5
  export const type = "com.shwfed.table.column.switch.local";
6
6
  export const compatibilityDate = "2026-05-20";
7
7
  export const metadata = {
@@ -14,10 +14,7 @@ export function schema(configure) {
14
14
  type: Schema.Literal(type),
15
15
  compatibilityDate: Schema.Literal(compatibilityDate),
16
16
  ...editableColumnFields(),
17
- hidden: Schema.optional(CelBool.annotations({
18
- title: "\u9690\u85CF\u6761\u4EF6",
19
- description: "\u8FD4\u56DE `true` \u65F6\u8BE5\u884C\u7684\u5F00\u5173\u4E0D\u6E32\u67D3\uFF08\u5176\u4F59\u884C\u4E0D\u53D7\u5F71\u54CD\uFF09"
20
- })),
17
+ align: Schema.optionalWith(Align.annotations({ title: "\u5BF9\u9F50" }), { default: () => "center" }),
21
18
  disabled: Schema.optional(CelBool.annotations({
22
19
  title: "\u7981\u7528\u6761\u4EF6",
23
20
  description: "\u8FD4\u56DE `true` \u65F6\u5F00\u5173\u4ECD\u7136\u6E32\u67D3\u4F46\u4E0D\u53EF\u5207\u6362"
@@ -1,8 +1,10 @@
1
1
  <script setup>
2
- import { computed } from "vue";
2
+ import { computed, inject, onBeforeUnmount, ref, watch } from "vue";
3
3
  import { Icon } from "@iconify/vue";
4
4
  import { ExpressionEditor } from "../../../../ui/expression-editor";
5
5
  import { Separator } from "../../../../ui/separator";
6
+ import { Switch } from "../../../../ui/switch";
7
+ import { Button } from "../../../../ui/button";
6
8
  import { Field, FieldLabel } from "../../../../ui/field";
7
9
  import { Locale } from "../../../../ui/locale";
8
10
  import {
@@ -12,9 +14,19 @@ import {
12
14
  InputGroupInput,
13
15
  InputGroupNumberField
14
16
  } from "../../../../ui/input-group";
17
+ import {
18
+ DropdownMenu,
19
+ DropdownMenuContent,
20
+ DropdownMenuItem,
21
+ DropdownMenuTrigger
22
+ } from "../../../../ui/dropdown-menu";
23
+ import ActionsConfigEditor from "../../../../actions/config.vue";
15
24
  import { getStructFieldDescription, getStructFieldTitle } from "../../../utils/schema-meta";
16
25
  import { Markdown } from "../../../../ui/markdown";
17
26
  import DerivedValueEditor from "../../../../form/DerivedValueEditor.vue";
27
+ import { TABLE_COLUMN_LAYOUT_KEY } from "../../../column-layout";
28
+ import { BREADCRUMB_EXTENSION_KEY } from "../../../../config/breadcrumb-extension";
29
+ import { registerRowVariablesIfAbsent } from "../../../utils/shared";
18
30
  import { schema } from "./schema";
19
31
  defineOptions({ name: "ShwfedTableTextInputRendererConfig" });
20
32
  const value = defineModel({ type: Object, ...{ required: true } });
@@ -22,10 +34,59 @@ const fieldSchema = schema(() => {
22
34
  });
23
35
  const fieldTitle = (field) => getStructFieldTitle(fieldSchema, field) ?? field;
24
36
  const fieldDescription = (field) => getStructFieldDescription(fieldSchema, field);
37
+ const ALIGN_OPTIONS = [
38
+ { value: "left", label: "\u5DE6\u5BF9\u9F50", icon: "fluent:text-align-left-20-regular" },
39
+ { value: "center", label: "\u5C45\u4E2D", icon: "fluent:text-align-center-20-regular" },
40
+ { value: "right", label: "\u53F3\u5BF9\u9F50", icon: "fluent:text-align-right-20-regular" }
41
+ ];
42
+ const currentAlignIcon = computed(
43
+ () => (ALIGN_OPTIONS.find((o) => o.value === (value.value.align ?? "left")) ?? ALIGN_OPTIONS[0]).icon
44
+ );
25
45
  const ROW_VARS = {
26
46
  row: { type: "dyn", label: "\u5F53\u524D\u884C\u6570\u636E" },
27
47
  index: { type: "number", label: "\u884C\u7D22\u5F15" }
28
48
  };
49
+ const layout = inject(TABLE_COLUMN_LAYOUT_KEY, null);
50
+ const breadcrumbExt = inject(BREADCRUMB_EXTENSION_KEY, null);
51
+ const editingAddon = ref(false);
52
+ function closeAddon() {
53
+ editingAddon.value = false;
54
+ }
55
+ const addonCrumb = breadcrumbExt?.add();
56
+ watch(editingAddon, (on) => {
57
+ if (layout) layout.fullPane.value = on;
58
+ if (addonCrumb) {
59
+ addonCrumb.label.value = on ? "\u8F93\u5165\u6846\u5185\u6309\u94AE" : null;
60
+ addonCrumb.back.value = on ? closeAddon : null;
61
+ }
62
+ });
63
+ onBeforeUnmount(() => {
64
+ if (layout) layout.fullPane.value = false;
65
+ addonCrumb?.dispose();
66
+ });
67
+ const addonItemCount = computed(() => value.value.addon?.items.length ?? 0);
68
+ const addonValue = computed({
69
+ get: () => ({
70
+ kind: "shwfed.component.action",
71
+ size: value.value.addon?.size ?? "xs",
72
+ gap: value.value.addon?.gap ?? 4,
73
+ style: value.value.addon?.style,
74
+ groups: value.value.addon?.groups ?? [],
75
+ items: value.value.addon?.items ?? []
76
+ }),
77
+ set: (next) => {
78
+ const { size, gap, style, groups, items } = next;
79
+ if (groups.length === 0 && items.length === 0) {
80
+ const { addon: _omit, ...rest } = value.value;
81
+ value.value = rest;
82
+ return;
83
+ }
84
+ value.value = {
85
+ ...value.value,
86
+ addon: { size, gap, groups, items, ...style === void 0 ? {} : { style } }
87
+ };
88
+ }
89
+ });
29
90
  const bindingText = computed({
30
91
  get: () => value.value.binding ?? "",
31
92
  set: (v) => {
@@ -38,17 +99,14 @@ const bindingText = computed({
38
99
  }
39
100
  }
40
101
  });
41
- const hiddenModel = computed({
42
- get: () => value.value.hidden ?? "",
43
- set: (v) => {
44
- if (v === "") {
45
- const { hidden: _drop, ...rest } = value.value;
46
- value.value = rest;
47
- } else {
48
- value.value = { ...value.value, hidden: v };
49
- }
102
+ function onHiddenChange(v) {
103
+ if (v) {
104
+ value.value = { ...value.value, hidden: true };
105
+ } else {
106
+ const { hidden: _drop, ...rest } = value.value;
107
+ value.value = rest;
50
108
  }
51
- });
109
+ }
52
110
  const disabledModel = computed({
53
111
  get: () => value.value.disabled ?? "",
54
112
  set: (v) => {
@@ -85,7 +143,17 @@ const derivedModel = computed({
85
143
  </script>
86
144
 
87
145
  <template>
88
- <div class="space-y-5">
146
+ <ActionsConfigEditor
147
+ v-if="editingAddon"
148
+ v-model="addonValue"
149
+ :configure="registerRowVariablesIfAbsent"
150
+ hide-size
151
+ />
152
+
153
+ <div
154
+ v-else
155
+ class="space-y-5"
156
+ >
89
157
  <div class="grid grid-cols-2 gap-x-6 gap-y-4">
90
158
  <Field orientation="vertical">
91
159
  <FieldLabel class="text-xs text-zinc-500">
@@ -184,6 +252,29 @@ const derivedModel = computed({
184
252
  {{ fieldTitle("size") }}
185
253
  </FieldLabel>
186
254
  <InputGroup>
255
+ <InputGroupAddon align="inline-start">
256
+ <DropdownMenu>
257
+ <DropdownMenuTrigger as-child>
258
+ <InputGroupButton
259
+ variant="ghost"
260
+ size="xs"
261
+ :title="fieldTitle('align')"
262
+ >
263
+ <Icon :icon="currentAlignIcon" />
264
+ </InputGroupButton>
265
+ </DropdownMenuTrigger>
266
+ <DropdownMenuContent align="start">
267
+ <DropdownMenuItem
268
+ v-for="opt in ALIGN_OPTIONS"
269
+ :key="opt.value"
270
+ @select="value = { ...value, align: opt.value }"
271
+ >
272
+ <Icon :icon="opt.icon" />
273
+ {{ opt.label }}
274
+ </DropdownMenuItem>
275
+ </DropdownMenuContent>
276
+ </DropdownMenu>
277
+ </InputGroupAddon>
187
278
  <InputGroupNumberField
188
279
  :model-value="value.size"
189
280
  :disabled="value.grow"
@@ -202,27 +293,6 @@ const derivedModel = computed({
202
293
  </InputGroupAddon>
203
294
  </InputGroup>
204
295
  </Field>
205
- <Field orientation="vertical">
206
- <FieldLabel class="text-xs text-zinc-500">
207
- <template
208
- v-if="fieldDescription('hidden')"
209
- #tooltip
210
- >
211
- <Markdown
212
- :source="fieldDescription('hidden')"
213
- block
214
- class="prose prose-sm prose-zinc"
215
- />
216
- </template>
217
- {{ fieldTitle("hidden") }}
218
- </FieldLabel>
219
- <ExpressionEditor
220
- v-model="hiddenModel"
221
- placeholder="例:row.archived"
222
- result-type="bool"
223
- :extra-vars="ROW_VARS"
224
- />
225
- </Field>
226
296
  <Field orientation="vertical">
227
297
  <FieldLabel class="text-xs text-zinc-500">
228
298
  <template
@@ -326,6 +396,51 @@ const derivedModel = computed({
326
396
  </InputGroupAddon>
327
397
  </InputGroup>
328
398
  </Field>
399
+ <Field orientation="vertical">
400
+ <FieldLabel class="text-xs text-zinc-500">
401
+ <template
402
+ v-if="fieldDescription('hidden')"
403
+ #tooltip
404
+ >
405
+ <Markdown
406
+ :source="fieldDescription('hidden')"
407
+ block
408
+ class="prose prose-sm prose-zinc"
409
+ />
410
+ </template>
411
+ {{ fieldTitle("hidden") }}
412
+ </FieldLabel>
413
+ <div>
414
+ <Switch
415
+ :model-value="value.hidden ?? false"
416
+ @update:model-value="onHiddenChange"
417
+ />
418
+ </div>
419
+ </Field>
329
420
  </div>
421
+ <Separator />
422
+ <Field orientation="vertical">
423
+ <FieldLabel class="text-xs text-zinc-500">
424
+ <template
425
+ v-if="fieldDescription('addon')"
426
+ #tooltip
427
+ >
428
+ <Markdown
429
+ :source="fieldDescription('addon')"
430
+ block
431
+ class="prose prose-sm prose-zinc"
432
+ />
433
+ </template>
434
+ {{ fieldTitle("addon") }}
435
+ </FieldLabel>
436
+ <Button
437
+ type="button"
438
+ class="w-full justify-center"
439
+ @click="editingAddon = true"
440
+ >
441
+ <Icon icon="fluent:add-20-regular" />
442
+ <span>{{ addonItemCount > 0 ? "\u914D\u7F6E\u6309\u94AE" : "\u6DFB\u52A0\u6309\u94AE" }}</span>
443
+ </Button>
444
+ </Field>
330
445
  </div>
331
446
  </template>
@@ -13,7 +13,9 @@ import {
13
13
  InputGroupButton,
14
14
  InputGroupInput
15
15
  } from "../../../../ui/input-group";
16
+ import ShwfedActions from "../../../../actions/components/group.vue";
16
17
  import { useFormState } from "../../../../form/utils/state";
18
+ import { JUSTIFY_CLASS, TEXT_ALIGN_CLASS } from "../../../utils/runtime";
17
19
  defineOptions({ name: "ShwfedTableTextInputRendererRuntime" });
18
20
  const props = defineProps({
19
21
  column: { type: null, required: true },
@@ -34,7 +36,6 @@ function evalBool(expression, label) {
34
36
  return false;
35
37
  }
36
38
  }
37
- const isHidden = computed(() => evalBool(props.column.hidden, "hidden"));
38
39
  const isDisabled = computed(() => evalBool(props.column.disabled, "disabled"));
39
40
  const formReadonly = useFormReadonly();
40
41
  const isReadonly = computed(
@@ -64,7 +65,21 @@ function onBlur() {
64
65
  isFocused.value = false;
65
66
  commit();
66
67
  }
68
+ const addonConfig = computed(() => {
69
+ const addon = props.column.addon;
70
+ if (!addon || addon.items.length === 0) return null;
71
+ return {
72
+ kind: "shwfed.component.action",
73
+ size: addon.size ?? "xs",
74
+ gap: addon.gap,
75
+ style: addon.style,
76
+ groups: addon.groups.map((group) => ({ ...group, variant: group.variant ?? "ghost" })),
77
+ items: addon.items
78
+ };
79
+ });
67
80
  const showClear = computed(() => !isDisabled.value && draft.value.length > 0);
81
+ const justifyClass = computed(() => JUSTIFY_CLASS[props.column.align ?? "left"] ?? JUSTIFY_CLASS.left);
82
+ const textAlignClass = computed(() => TEXT_ALIGN_CLASS[props.column.align ?? "left"] ?? TEXT_ALIGN_CLASS.left);
68
83
  function handleClear() {
69
84
  draft.value = "";
70
85
  commit();
@@ -76,7 +91,7 @@ function handleClear() {
76
91
  Row budget: 2px outer inset (`p-[0.125rem]`) on each side around a 28px
77
92
  (`h-7`) input — total 32px. The inset is the deliberate gap between the
78
93
  input border and the td borders; the 28px input gives the 12px text some
79
- vertical breathing room. Every branch (hidden / readonly / editable) is
94
+ vertical breathing room. Every branch (readonly / editable) is
80
95
  sized identically so rows do not jump when a CEL condition flips. The
81
96
  default `Input` ships `h-9` + `text-base` + `md:text-sm` — we override
82
97
  each at the same breakpoint or `md:text-sm` would beat our unprefixed
@@ -89,10 +104,6 @@ function handleClear() {
89
104
  oversized.
90
105
  -->
91
106
  <div class="p-[0.125rem] w-full">
92
- <span
93
- v-if="isHidden"
94
- class="block h-7 w-full"
95
- />
96
107
  <!--
97
108
  Readonly empty state mirrors the `text` column exactly: a centered,
98
109
  faded, non-selectable `-` rendered in `font-mono`, so a readonly grid
@@ -101,10 +112,10 @@ function handleClear() {
101
112
  text.
102
113
  -->
103
114
  <span
104
- v-else-if="effectiveReadonly"
115
+ v-if="effectiveReadonly"
105
116
  :class="[
106
117
  'flex items-center h-7 w-full px-2 text-[0.75rem] truncate',
107
- draft ? 'text-zinc-700' : 'justify-center font-mono text-zinc-300 select-none'
118
+ draft ? ['text-zinc-700', justifyClass] : 'justify-center font-mono text-zinc-300 select-none'
108
119
  ]"
109
120
  >
110
121
  {{ draft || "-" }}
@@ -125,7 +136,7 @@ function handleClear() {
125
136
  v-model="draft"
126
137
  :placeholder="placeholderText"
127
138
  :disabled="isDisabled"
128
- class="h-7 text-[0.75rem] md:text-[0.75rem] px-2"
139
+ :class="['h-7 text-[0.75rem] md:text-[0.75rem] px-2', textAlignClass]"
129
140
  @focus="onFocus"
130
141
  @blur="onBlur"
131
142
  @keydown.enter="commit"
@@ -149,6 +160,21 @@ function handleClear() {
149
160
  />
150
161
  </InputGroupButton>
151
162
  </InputGroupAddon>
163
+ <!-- `mr-[-0.45rem]` mirrors the clear addon's `has-[>button]:mr-[-0.45rem]`
164
+ pull-back: that compensation only fires when the addon's direct child
165
+ is a `<button>`, but `ShwfedActions` roots a `<div>`, so without it the
166
+ `inline-end` `pr-3` would leave a ~12px dead gap before the border. -->
167
+ <InputGroupAddon
168
+ v-if="addonConfig"
169
+ align="inline-end"
170
+ class="field-addon-actions mr-[-0.45rem]"
171
+ >
172
+ <ShwfedActions :config="addonConfig" />
173
+ </InputGroupAddon>
152
174
  </InputGroup>
153
175
  </div>
154
176
  </template>
177
+
178
+ <style scoped>
179
+ .field-addon-actions :deep([data-slot=buttons]){align-items:center;gap:.125rem}.field-addon-actions :deep([data-slot=buttons-dropdown-trigger]),.field-addon-actions :deep([data-slot=buttons-item]){border-radius:.125rem;color:#71717a;height:1rem;min-width:1rem;padding:0}.field-addon-actions :deep([data-slot=buttons-dropdown-trigger] svg),.field-addon-actions :deep([data-slot=buttons-item] svg){height:.75rem;width:.75rem}.field-addon-actions :deep([data-slot=buttons-dropdown-trigger]:hover:not(:disabled)),.field-addon-actions :deep([data-slot=buttons-item]:hover:not(:disabled)){color:#3f3f46}
180
+ </style>