@shwfed/config 2.10.12 → 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 (131) hide show
  1. package/dist/mcp.mjs +46 -49
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{FieldGroup.vue_vue_type_script_setup_true_lang-BeqytPDr.js → FieldGroup.vue_vue_type_script_setup_true_lang-UfhMyymD.js} +1 -1
  4. package/dist/preview/assets/{badge-DkHwLDps.js → badge-CJ9IQ3Jx.js} +1 -1
  5. package/dist/preview/assets/{config-Cft-srKd.js → config--Vx4fL61.js} +1 -1
  6. package/dist/preview/assets/{config-DJQ2LOWo.js → config-5PPug5mk.js} +1 -1
  7. package/dist/preview/assets/{config-Dx1SXsSf.js → config-7V1qHjUk.js} +1 -1
  8. package/dist/preview/assets/{config-Cedm-E2H.js → config-BYktCefJ.js} +1 -1
  9. package/dist/preview/assets/{config-DAZ2Uj6B.js → config-BeRYF_cz.js} +1 -1
  10. package/dist/preview/assets/{config-DCANpbtq.js → config-BldsYfGM.js} +1 -1
  11. package/dist/preview/assets/{config-Uw4cvZGX.js → config-CQrDCzYN.js} +1 -1
  12. package/dist/preview/assets/{config-7KeAl8UU.js → config-C_g-FYCR.js} +1 -1
  13. package/dist/preview/assets/{config-CZ1e9utV.js → config-DIsAIc7H.js} +1 -1
  14. package/dist/preview/assets/{config-OPQWANCx.js → config-DPX7vGqV.js} +1 -1
  15. package/dist/preview/assets/{config-DQVKd54J.js → config-DpLMetys.js} +1 -1
  16. package/dist/preview/assets/{config-CVPVYMuh.js → config-IMd4FZi8.js} +1 -1
  17. package/dist/preview/assets/{config-Cy6Eix27.js → config-N-FdgfwK.js} +1 -1
  18. package/dist/preview/assets/{config-DbV3RlZz.js → config-uUF-UHPt.js} +1 -1
  19. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-D4Gh9PzS.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-Cum0oK9u.js → index-DKWp47QP.js} +1 -1
  24. package/dist/preview/assets/{item-H4QeOpnC.js → item-XsW7swFt.js} +1 -1
  25. package/dist/preview/assets/{runtime-CTnwTJlw.js → runtime-B-ABO0r0.js} +1 -1
  26. package/dist/preview/assets/{runtime-C3532B0Y.js → runtime-BeHohaOZ.js} +1 -1
  27. package/dist/preview/assets/{runtime-CNMjRr9Y.js → runtime-BiFFwOIl.js} +1 -1
  28. package/dist/preview/assets/{runtime-ibuFFD1K.js → runtime-ByArW-jJ.js} +1 -1
  29. package/dist/preview/assets/{runtime-DvCHNIPq.js → runtime-CpVTGNFZ.js} +1 -1
  30. package/dist/preview/assets/{runtime-sPGVp7yA.js → runtime-DQ1TnQ7n.js} +1 -1
  31. package/dist/preview/assets/{runtime-CwgX0PuH.js → runtime-DY7hr7v1.js} +1 -1
  32. package/dist/preview/assets/{runtime-BotFX6qJ.js → runtime-Dn172S7t.js} +1 -1
  33. package/dist/preview/assets/{runtime-D5HcLLLR.js → runtime-JxBzvGnw.js} +1 -1
  34. package/dist/preview/assets/{runtime-cKOD2A6u.js → runtime-bq0hmEXY.js} +1 -1
  35. package/dist/preview/assets/{schema-meta-DtZNwp3h.js → schema-meta-CZ9yXnsa.js} +1 -1
  36. package/dist/preview/index.html +2 -2
  37. package/dist/runtime/components/form/fields/2026-06-09/com.shwfed.form.field.upload/runtime.vue +23 -1
  38. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.date/config.vue +30 -0
  39. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.date/schema.d.ts +2 -1
  40. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.date/schema.js +1 -1
  41. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.icon/config.vue +30 -0
  42. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.icon/schema.d.ts +2 -1
  43. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.icon/schema.js +7 -4
  44. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.number/config.vue +30 -0
  45. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.number/schema.d.ts +2 -1
  46. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.number/schema.js +1 -1
  47. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.text/config.vue +30 -0
  48. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.text/schema.d.ts +2 -1
  49. package/dist/runtime/components/table/columns/2026-04-14/com.shwfed.table.column.text/schema.js +1 -1
  50. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch/schema.d.ts +2 -1
  51. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch/schema.js +1 -0
  52. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/config.vue +30 -0
  53. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/schema.d.ts +2 -1
  54. package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/schema.js +1 -1
  55. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/config.vue +60 -32
  56. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/runtime.vue +7 -9
  57. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/schema.d.ts +4 -1
  58. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.number-input/schema.js +2 -5
  59. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/config.vue +67 -32
  60. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/runtime.vue +6 -9
  61. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/schema.d.ts +4 -1
  62. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/schema.js +2 -5
  63. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/config.vue +66 -31
  64. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/runtime.vue +7 -9
  65. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/schema.d.ts +4 -1
  66. package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.text-input/schema.js +2 -5
  67. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +2 -2
  68. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +2 -2
  69. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/schema.d.ts +1 -1
  70. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/schema.js +1 -0
  71. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.d.vue.ts +2 -2
  72. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.vue.d.ts +2 -2
  73. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/schema.d.ts +1 -1
  74. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/schema.js +1 -0
  75. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +2 -2
  76. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +2 -2
  77. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/schema.d.ts +1 -1
  78. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/schema.js +1 -0
  79. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.d.vue.ts +2 -2
  80. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.vue.d.ts +2 -2
  81. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/schema.d.ts +1 -1
  82. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/schema.js +1 -0
  83. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.d.vue.ts +2 -2
  84. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +2 -2
  85. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/schema.d.ts +1 -1
  86. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/schema.js +1 -0
  87. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.d.vue.ts +2 -2
  88. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +2 -2
  89. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/schema.d.ts +1 -1
  90. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/schema.js +1 -0
  91. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.d.vue.ts +4 -2
  92. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue +61 -22
  93. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue.d.ts +4 -2
  94. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/runtime.vue +6 -9
  95. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/schema.d.ts +4 -1
  96. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/schema.js +3 -4
  97. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.d.vue.ts +4 -2
  98. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue +61 -22
  99. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue.d.ts +4 -2
  100. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/runtime.vue +6 -9
  101. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/schema.d.ts +4 -1
  102. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/schema.js +3 -4
  103. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.d.vue.ts +4 -2
  104. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.vue +67 -23
  105. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/config.vue.d.ts +4 -2
  106. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/runtime.vue +6 -9
  107. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/schema.d.ts +4 -1
  108. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-multi/schema.js +2 -4
  109. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.d.vue.ts +4 -2
  110. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.vue +67 -23
  111. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/config.vue.d.ts +4 -2
  112. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/runtime.vue +6 -9
  113. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/schema.d.ts +4 -1
  114. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.tree-combobox-single/schema.js +2 -4
  115. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/config.vue +67 -32
  116. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/runtime.vue +7 -9
  117. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/schema.d.ts +4 -1
  118. package/dist/runtime/components/table/columns/2026-06-17/com.shwfed.table.column.date-input/schema.js +2 -5
  119. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/config.vue +66 -31
  120. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/runtime.vue +5 -8
  121. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/schema.d.ts +4 -1
  122. package/dist/runtime/components/table/columns/2026-06-22/com.shwfed.table.column.date-range-input/schema.js +2 -5
  123. package/dist/runtime/components/table/index.vue +46 -7
  124. package/dist/runtime/components/table/utils/runtime.d.ts +1 -0
  125. package/dist/runtime/components/table/utils/runtime.js +5 -0
  126. package/dist/runtime/components/table/utils/shared.d.ts +3 -1
  127. package/dist/runtime/components/table/utils/shared.js +17 -5
  128. package/package.json +1 -1
  129. package/dist/preview/assets/index-B3HnlKis.js +0 -763
  130. package/dist/preview/assets/index-BAY6NLoo.css +0 -1
  131. package/dist/preview/assets/index-CxUuhfsO.js +0 -1
@@ -29,7 +29,7 @@ export declare function schema(configure: (env: Environment) => void): Schema.St
29
29
  locale: Schema.Literal<["ja", "en", "ko"]>;
30
30
  message: Schema.SchemaClass<string, string, never>;
31
31
  }>]>;
32
- accessor: Schema.Schema<string, string, never>;
32
+ accessor: Schema.optional<Schema.Schema<string, string, never>>;
33
33
  enableSorting: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
34
34
  sortKey: Schema.optional<Schema.refine<string, typeof Schema.String>>;
35
35
  size: Schema.optional<Schema.refine<number, Schema.filter<typeof Schema.Number>>>;
@@ -41,6 +41,7 @@ export declare function schema(configure: (env: Environment) => void): Schema.St
41
41
  locale: Schema.Literal<["ja", "en", "ko"]>;
42
42
  message: Schema.SchemaClass<string, string, never>;
43
43
  }>]>>;
44
+ hidden: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
44
45
  id: Schema.refine<string, typeof Schema.String>;
45
46
  groupId: Schema.optional<typeof Schema.UUID>;
46
47
  type: Schema.Literal<["com.shwfed.table.column.switch"]>;
@@ -52,6 +52,7 @@ export function toColumnDef(value, { getLocaleText, $cel, inheritedContext }) {
52
52
  return {
53
53
  header: getLocaleText(value.title),
54
54
  accessorFn: (row, index) => {
55
+ if (!value.accessor) return void 0;
55
56
  try {
56
57
  return Effect.runSync($cel(value.accessor, { ...inheritedContext, row, index }));
57
58
  } catch (e) {
@@ -3,6 +3,7 @@ import { computed } 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";
6
7
  import { Field, FieldLabel } from "../../../../ui/field";
7
8
  import { Locale } from "../../../../ui/locale";
8
9
  import {
@@ -47,6 +48,14 @@ const ROW_VALUE_VARS = {
47
48
  const JSON_VARS = {
48
49
  json: { type: "dyn", label: "HTTP \u54CD\u5E94\u4F53" }
49
50
  };
51
+ function onHiddenChange(v) {
52
+ if (v) {
53
+ value.value = { ...value.value, hidden: true };
54
+ } else {
55
+ const { hidden: _drop, ...rest } = value.value;
56
+ value.value = rest;
57
+ }
58
+ }
50
59
  const disabledModel = computed({
51
60
  get: () => value.value.disabled ?? "",
52
61
  set: (v) => {
@@ -334,6 +343,27 @@ function updateTriggers(next) {
334
343
  </InputGroupAddon>
335
344
  </InputGroup>
336
345
  </Field>
346
+ <Field orientation="vertical">
347
+ <FieldLabel class="text-xs text-zinc-500">
348
+ <template
349
+ v-if="fieldDescription('hidden')"
350
+ #tooltip
351
+ >
352
+ <Markdown
353
+ :source="fieldDescription('hidden')"
354
+ block
355
+ class="prose prose-sm prose-zinc"
356
+ />
357
+ </template>
358
+ {{ fieldTitle("hidden") }}
359
+ </FieldLabel>
360
+ <div>
361
+ <Switch
362
+ :model-value="value.hidden ?? false"
363
+ @update:model-value="onHiddenChange"
364
+ />
365
+ </div>
366
+ </Field>
337
367
  </div>
338
368
  </div>
339
369
  </template>
@@ -29,7 +29,7 @@ export declare function schema(configure: (env: Environment) => void): Schema.St
29
29
  locale: Schema.Literal<["ja", "en", "ko"]>;
30
30
  message: Schema.SchemaClass<string, string, never>;
31
31
  }>]>;
32
- accessor: Schema.Schema<string, string, never>;
32
+ accessor: Schema.optional<Schema.Schema<string, string, never>>;
33
33
  enableSorting: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
34
34
  sortKey: Schema.optional<Schema.refine<string, typeof Schema.String>>;
35
35
  size: Schema.optional<Schema.refine<number, Schema.filter<typeof Schema.Number>>>;
@@ -41,6 +41,7 @@ export declare function schema(configure: (env: Environment) => void): Schema.St
41
41
  locale: Schema.Literal<["ja", "en", "ko"]>;
42
42
  message: Schema.SchemaClass<string, string, never>;
43
43
  }>]>>;
44
+ hidden: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
44
45
  id: Schema.refine<string, typeof Schema.String>;
45
46
  groupId: Schema.optional<typeof Schema.UUID>;
46
47
  type: Schema.Literal<["com.shwfed.table.column.switch.remote"]>;
@@ -51,7 +51,6 @@ export function schema(configure) {
51
51
  export function defaults() {
52
52
  return {
53
53
  title: [{ locale: "zh", message: "" }],
54
- accessor: "",
55
54
  size: 120
56
55
  };
57
56
  }
@@ -71,6 +70,7 @@ export function toColumnDef(value, { getLocaleText, $cel, inheritedContext }) {
71
70
  return {
72
71
  header: getLocaleText(value.title),
73
72
  accessorFn: (row, index) => {
73
+ if (!value.accessor) return void 0;
74
74
  try {
75
75
  return Effect.runSync($cel(value.accessor, { ...inheritedContext, row, index }));
76
76
  } catch (e) {
@@ -34,6 +34,14 @@ const fieldSchema = schema(() => {
34
34
  });
35
35
  const fieldTitle = (field) => getStructFieldTitle(fieldSchema, field) ?? field;
36
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 ?? "right")) ?? ALIGN_OPTIONS[2]).icon
44
+ );
37
45
  const ROW_VARS = {
38
46
  row: { type: "dyn", label: "\u5F53\u524D\u884C\u6570\u636E" },
39
47
  index: { type: "number", label: "\u884C\u7D22\u5F15" }
@@ -96,17 +104,6 @@ const bindingText = computed({
96
104
  }
97
105
  }
98
106
  });
99
- const hiddenModel = computed({
100
- get: () => value.value.hidden ?? "",
101
- set: (v) => {
102
- if (v === "") {
103
- const { hidden: _drop, ...rest } = value.value;
104
- value.value = rest;
105
- } else {
106
- value.value = { ...value.value, hidden: v };
107
- }
108
- }
109
- });
110
107
  const disabledModel = computed({
111
108
  get: () => value.value.disabled ?? "",
112
109
  set: (v) => {
@@ -172,6 +169,14 @@ function onValueAsStringChange(next) {
172
169
  value.value = rest;
173
170
  }
174
171
  }
172
+ function onHiddenChange(v) {
173
+ if (v) {
174
+ value.value = { ...value.value, hidden: true };
175
+ } else {
176
+ const { hidden: _drop, ...rest } = value.value;
177
+ value.value = rest;
178
+ }
179
+ }
175
180
  function onMinChange(v) {
176
181
  if (v.length > 0) {
177
182
  value.value = { ...value.value, min: v };
@@ -300,6 +305,29 @@ function onMaxChange(v) {
300
305
  {{ fieldTitle("size") }}
301
306
  </FieldLabel>
302
307
  <InputGroup>
308
+ <InputGroupAddon align="inline-start">
309
+ <DropdownMenu>
310
+ <DropdownMenuTrigger as-child>
311
+ <InputGroupButton
312
+ variant="ghost"
313
+ size="xs"
314
+ :title="fieldTitle('align')"
315
+ >
316
+ <Icon :icon="currentAlignIcon" />
317
+ </InputGroupButton>
318
+ </DropdownMenuTrigger>
319
+ <DropdownMenuContent align="start">
320
+ <DropdownMenuItem
321
+ v-for="opt in ALIGN_OPTIONS"
322
+ :key="opt.value"
323
+ @select="value = { ...value, align: opt.value }"
324
+ >
325
+ <Icon :icon="opt.icon" />
326
+ {{ opt.label }}
327
+ </DropdownMenuItem>
328
+ </DropdownMenuContent>
329
+ </DropdownMenu>
330
+ </InputGroupAddon>
303
331
  <InputGroupNumberField
304
332
  :model-value="value.size"
305
333
  :disabled="value.grow"
@@ -461,27 +489,6 @@ function onMaxChange(v) {
461
489
  </Field>
462
490
  </div>
463
491
  <div class="grid grid-cols-2 gap-x-6 gap-y-4">
464
- <Field orientation="vertical">
465
- <FieldLabel class="text-xs text-zinc-500">
466
- <template
467
- v-if="fieldDescription('hidden')"
468
- #tooltip
469
- >
470
- <Markdown
471
- :source="fieldDescription('hidden')"
472
- block
473
- class="prose prose-sm prose-zinc"
474
- />
475
- </template>
476
- {{ fieldTitle("hidden") }}
477
- </FieldLabel>
478
- <ExpressionEditor
479
- v-model="hiddenModel"
480
- placeholder="例:row.archived"
481
- result-type="bool"
482
- :extra-vars="ROW_VARS"
483
- />
484
- </Field>
485
492
  <Field orientation="vertical">
486
493
  <FieldLabel class="text-xs text-zinc-500">
487
494
  <template
@@ -585,6 +592,27 @@ function onMaxChange(v) {
585
592
  </InputGroupAddon>
586
593
  </InputGroup>
587
594
  </Field>
595
+ <Field orientation="vertical">
596
+ <FieldLabel class="text-xs text-zinc-500">
597
+ <template
598
+ v-if="fieldDescription('hidden')"
599
+ #tooltip
600
+ >
601
+ <Markdown
602
+ :source="fieldDescription('hidden')"
603
+ block
604
+ class="prose prose-sm prose-zinc"
605
+ />
606
+ </template>
607
+ {{ fieldTitle("hidden") }}
608
+ </FieldLabel>
609
+ <div>
610
+ <Switch
611
+ :model-value="value.hidden ?? false"
612
+ @update:model-value="onHiddenChange"
613
+ />
614
+ </div>
615
+ </Field>
588
616
  </div>
589
617
  <Separator />
590
618
  <Field orientation="vertical">
@@ -10,6 +10,7 @@ import { getLocalizedText } from "../../../../../share/locale";
10
10
  import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupNumberField } from "../../../../ui/input-group";
11
11
  import ShwfedActions from "../../../../actions/components/group.vue";
12
12
  import { useFieldValue } from "../../../../form/utils/field-value";
13
+ import { JUSTIFY_CLASS, TEXT_ALIGN_CLASS } from "../../../utils/runtime";
13
14
  defineOptions({ name: "ShwfedTableNumberInputRendererRuntime" });
14
15
  const props = defineProps({
15
16
  column: { type: null, required: true },
@@ -40,7 +41,6 @@ function evalNumber(expression, label) {
40
41
  return void 0;
41
42
  }
42
43
  }
43
- const isHidden = computed(() => evalBool(props.column.hidden, "hidden"));
44
44
  const isDisabled = computed(() => evalBool(props.column.disabled, "disabled"));
45
45
  const formReadonly = useFormReadonly();
46
46
  const isReadonly = computed(
@@ -94,6 +94,8 @@ const addonConfig = computed(() => {
94
94
  };
95
95
  });
96
96
  const showClear = computed(() => !isDisabled.value && draft.value !== void 0);
97
+ const justifyClass = computed(() => JUSTIFY_CLASS[props.column.align ?? "right"] ?? JUSTIFY_CLASS.right);
98
+ const textAlignClass = computed(() => TEXT_ALIGN_CLASS[props.column.align ?? "right"] ?? TEXT_ALIGN_CLASS.right);
97
99
  function handleClear() {
98
100
  draft.value = void 0;
99
101
  commit();
@@ -115,16 +117,12 @@ async function onBlur() {
115
117
  <template>
116
118
  <!--
117
119
  Row budget matches the text-input cell: 2px outer inset around an `h-7`
118
- (28px) input — 32px total. Every branch (hidden / readonly / editable)
120
+ (28px) input — 32px total. Every branch (readonly / editable)
119
121
  is sized identically so rows do not jump when a CEL condition flips.
120
122
  Both `text-[0.75rem]` breakpoints are explicit so `Input`'s default
121
123
  `md:text-sm` cannot beat the override at md+.
122
124
  -->
123
125
  <div class="p-[0.125rem] w-full">
124
- <span
125
- v-if="isHidden"
126
- class="block h-7 w-full"
127
- />
128
126
  <!--
129
127
  Readonly empty state mirrors the `text` column exactly: a centered,
130
128
  faded, non-selectable `-` in `font-mono`, so a readonly grid reads
@@ -132,10 +130,10 @@ async function onBlur() {
132
130
  left-aligned dark text.
133
131
  -->
134
132
  <span
135
- v-else-if="effectiveReadonly"
133
+ v-if="effectiveReadonly"
136
134
  :class="[
137
135
  'flex items-center h-7 w-full px-2 text-[0.75rem] truncate',
138
- draft !== void 0 ? 'text-zinc-700' : 'justify-center font-mono text-zinc-300 select-none'
136
+ draft !== void 0 ? ['text-zinc-700', justifyClass] : 'justify-center font-mono text-zinc-300 select-none'
139
137
  ]"
140
138
  >
141
139
  {{ draft ?? "-" }}
@@ -154,7 +152,7 @@ async function onBlur() {
154
152
  :format-options="formatOptions"
155
153
  :disabled="isDisabled"
156
154
  :placeholder="placeholderText"
157
- input-class="h-7 text-[0.75rem] md:text-[0.75rem] px-2 text-left"
155
+ :input-class="['h-7 text-[0.75rem] md:text-[0.75rem] px-2', textAlignClass]"
158
156
  @update:model-value="(v) => draft = v"
159
157
  @blur="onBlur"
160
158
  />
@@ -9,6 +9,9 @@ export declare const metadata: {
9
9
  readonly icon: "fluent:number-symbol-20-regular";
10
10
  };
11
11
  export declare function schema(configure: (env: Environment) => void): Schema.Struct<{
12
+ align: Schema.optionalWith<Schema.Literal<["left", "center", "right"]>, {
13
+ default: () => "right";
14
+ }>;
12
15
  placeholder: Schema.optional<Schema.TupleType<readonly [Schema.Struct<{
13
16
  locale: Schema.Literal<["zh"]>;
14
17
  message: Schema.SchemaClass<string, string, never>;
@@ -16,7 +19,6 @@ export declare function schema(configure: (env: Environment) => void): Schema.St
16
19
  locale: Schema.Literal<["ja", "en", "ko"]>;
17
20
  message: Schema.SchemaClass<string, string, never>;
18
21
  }>]>>;
19
- hidden: Schema.optional<Schema.Schema<string, string, never>>;
20
22
  disabled: Schema.optional<Schema.Schema<string, string, never>>;
21
23
  readonly: Schema.optional<Schema.Schema<string, string, never>>;
22
24
  precision: Schema.optional<Schema.refine<number, Schema.filter<typeof Schema.Number>>>;
@@ -180,6 +182,7 @@ export declare function schema(configure: (env: Environment) => void): Schema.St
180
182
  locale: Schema.Literal<["ja", "en", "ko"]>;
181
183
  message: Schema.SchemaClass<string, string, never>;
182
184
  }>]>>;
185
+ hidden: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
183
186
  id: Schema.refine<string, typeof Schema.String>;
184
187
  groupId: Schema.optional<typeof Schema.UUID>;
185
188
  type: Schema.Literal<["com.shwfed.table.column.number-input"]>;
@@ -2,7 +2,7 @@ import { Schema } from "effect";
2
2
  import { getProperty } from "dot-prop";
3
3
  import { Locale } from "../../../../../share/locale.js";
4
4
  import { ActionSchemaFields } from "../../../../actions/schema.js";
5
- import { CelRowAccess, derivedRowField, editableColumnFields, editableHeader, registerRowVariablesIfAbsent } from "../../../utils/shared.js";
5
+ import { Align, CelRowAccess, derivedRowField, editableColumnFields, editableHeader, registerRowVariablesIfAbsent } from "../../../utils/shared.js";
6
6
  export const type = "com.shwfed.table.column.number-input";
7
7
  export const compatibilityDate = "2026-05-20";
8
8
  export const metadata = {
@@ -31,14 +31,11 @@ export function schema(configure) {
31
31
  type: Schema.Literal(type),
32
32
  compatibilityDate: Schema.Literal(compatibilityDate),
33
33
  ...editableColumnFields(),
34
+ align: Schema.optionalWith(Align.annotations({ title: "\u5BF9\u9F50" }), { default: () => "right" }),
34
35
  placeholder: Schema.optional(Locale.annotations({
35
36
  title: "\u5360\u4F4D\u7B26",
36
37
  description: "\u5355\u5143\u683C\u4E3A\u7A7A\u65F6\u663E\u793A\u7684\u63D0\u793A\u6587\u672C"
37
38
  })),
38
- hidden: Schema.optional(CelBool.annotations({
39
- title: "\u9690\u85CF\u6761\u4EF6",
40
- description: "\u8FD4\u56DE `true` \u65F6\u8BE5\u884C\u7684\u8F93\u5165\u6846\u4E0D\u6E32\u67D3\uFF08\u5176\u4F59\u884C\u4E0D\u53D7\u5F71\u54CD\uFF09"
41
- })),
42
39
  disabled: Schema.optional(CelBool.annotations({
43
40
  title: "\u7981\u7528\u6761\u4EF6",
44
41
  description: "\u8FD4\u56DE `true` \u65F6\u8F93\u5165\u6846\u4ECD\u7136\u6E32\u67D3\u4F46\u4E0D\u53EF\u7F16\u8F91"
@@ -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"