@shwfed/nuxt 0.7.9 → 0.7.11

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 (108) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/app.d.vue.ts +7 -56
  3. package/dist/runtime/components/app.vue +17 -404
  4. package/dist/runtime/components/app.vue.d.ts +7 -56
  5. package/dist/runtime/components/fields.d.vue.ts +154 -132
  6. package/dist/runtime/components/fields.vue +30 -295
  7. package/dist/runtime/components/fields.vue.d.ts +154 -132
  8. package/dist/runtime/components/table.d.vue.ts +129 -59
  9. package/dist/runtime/components/table.vue +51 -617
  10. package/dist/runtime/components/table.vue.d.ts +129 -59
  11. package/dist/runtime/components/ui/app/App.d.vue.ts +86 -0
  12. package/dist/runtime/components/ui/app/App.vue +414 -0
  13. package/dist/runtime/components/ui/app/App.vue.d.ts +86 -0
  14. package/dist/runtime/components/ui/checkbox/Checkbox.vue +6 -2
  15. package/dist/runtime/components/ui/dropdown-menu/DropdownMenuItem.vue +1 -1
  16. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.d.vue.ts +30 -0
  17. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue +87 -0
  18. package/dist/runtime/components/ui/expression-editor/ExpressionEditor.vue.d.ts +30 -0
  19. package/dist/runtime/components/ui/expression-editor/index.d.ts +1 -0
  20. package/dist/runtime/components/ui/expression-editor/index.js +1 -0
  21. package/dist/runtime/components/ui/field/FieldContent.vue +1 -1
  22. package/dist/runtime/components/ui/field/FieldError.vue +2 -2
  23. package/dist/runtime/components/ui/field/FieldLabel.vue +1 -1
  24. package/dist/runtime/components/ui/fields/Fields.d.vue.ts +376 -0
  25. package/dist/runtime/components/ui/fields/Fields.vue +441 -0
  26. package/dist/runtime/components/ui/fields/Fields.vue.d.ts +376 -0
  27. package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.d.vue.ts +163 -0
  28. package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.vue +363 -0
  29. package/dist/runtime/components/ui/fields-configurator/FieldsConfiguratorDialog.vue.d.ts +163 -0
  30. package/dist/runtime/components/ui/icon-picker/IconPicker.d.vue.ts +15 -0
  31. package/dist/runtime/components/ui/icon-picker/IconPicker.vue +178 -0
  32. package/dist/runtime/components/ui/icon-picker/IconPicker.vue.d.ts +15 -0
  33. package/dist/runtime/components/ui/icon-picker/index.d.ts +1 -0
  34. package/dist/runtime/components/ui/icon-picker/index.js +1 -0
  35. package/dist/runtime/components/ui/input/Input.d.vue.ts +1 -0
  36. package/dist/runtime/components/ui/input/Input.vue +2 -0
  37. package/dist/runtime/components/ui/input/Input.vue.d.ts +1 -0
  38. package/dist/runtime/components/ui/input-group/InputGroupAddon.vue +4 -1
  39. package/dist/runtime/components/ui/input-group/InputGroupCombobox.d.vue.ts +8 -3
  40. package/dist/runtime/components/ui/input-group/InputGroupCombobox.vue +8 -3
  41. package/dist/runtime/components/ui/input-group/InputGroupCombobox.vue.d.ts +8 -3
  42. package/dist/runtime/components/ui/input-group/InputGroupComboboxInput.d.vue.ts +8 -1
  43. package/dist/runtime/components/ui/input-group/InputGroupComboboxInput.vue +11 -2
  44. package/dist/runtime/components/ui/input-group/InputGroupComboboxInput.vue.d.ts +8 -1
  45. package/dist/runtime/components/ui/input-group/InputGroupInput.vue +1 -1
  46. package/dist/runtime/components/ui/input-group/InputGroupNumberField.d.vue.ts +5 -2
  47. package/dist/runtime/components/ui/input-group/InputGroupNumberField.vue +10 -4
  48. package/dist/runtime/components/ui/input-group/InputGroupNumberField.vue.d.ts +5 -2
  49. package/dist/runtime/components/ui/input-group/InputGroupTextarea.vue +1 -1
  50. package/dist/runtime/components/ui/input-group/index.js +1 -1
  51. package/dist/runtime/components/ui/locale/Locale.d.vue.ts +20 -0
  52. package/dist/runtime/components/ui/locale/Locale.vue +291 -0
  53. package/dist/runtime/components/ui/locale/Locale.vue.d.ts +20 -0
  54. package/dist/runtime/components/ui/locale/index.d.ts +1 -0
  55. package/dist/runtime/components/ui/locale/index.js +1 -0
  56. package/dist/runtime/components/ui/native-select/NativeSelect.d.vue.ts +2 -2
  57. package/dist/runtime/components/ui/native-select/NativeSelect.vue +1 -1
  58. package/dist/runtime/components/ui/native-select/NativeSelect.vue.d.ts +2 -2
  59. package/dist/runtime/components/ui/native-select/NativeSelectOption.d.vue.ts +1 -0
  60. package/dist/runtime/components/ui/native-select/NativeSelectOption.vue +4 -1
  61. package/dist/runtime/components/ui/native-select/NativeSelectOption.vue.d.ts +1 -0
  62. package/dist/runtime/components/ui/number-field/NumberFieldInput.vue +1 -1
  63. package/dist/runtime/components/ui/switch/Switch.vue +2 -2
  64. package/dist/runtime/components/ui/table/Table.d.vue.ts +147 -0
  65. package/dist/runtime/components/ui/table/Table.vue +952 -0
  66. package/dist/runtime/components/ui/table/Table.vue.d.ts +147 -0
  67. package/dist/runtime/components/ui/table/schema.d.ts +151 -0
  68. package/dist/runtime/components/ui/table/schema.js +142 -0
  69. package/dist/runtime/components/ui/table-configurator/TableConfiguratorDialog.d.vue.ts +128 -0
  70. package/dist/runtime/components/ui/table-configurator/TableConfiguratorDialog.vue +2719 -0
  71. package/dist/runtime/components/ui/table-configurator/TableConfiguratorDialog.vue.d.ts +128 -0
  72. package/dist/runtime/components/ui/table-configurator/menu.d.ts +37 -0
  73. package/dist/runtime/components/ui/table-configurator/menu.js +227 -0
  74. package/dist/runtime/components/ui/tabs/Tabs.d.vue.ts +24 -0
  75. package/dist/runtime/components/ui/tabs/Tabs.vue +30 -0
  76. package/dist/runtime/components/ui/tabs/Tabs.vue.d.ts +24 -0
  77. package/dist/runtime/components/ui/tabs/TabsContent.d.vue.ts +18 -0
  78. package/dist/runtime/components/ui/tabs/TabsContent.vue +23 -0
  79. package/dist/runtime/components/ui/tabs/TabsContent.vue.d.ts +18 -0
  80. package/dist/runtime/components/ui/tabs/TabsList.d.vue.ts +18 -0
  81. package/dist/runtime/components/ui/tabs/TabsList.vue +25 -0
  82. package/dist/runtime/components/ui/tabs/TabsList.vue.d.ts +18 -0
  83. package/dist/runtime/components/ui/tabs/TabsTrigger.d.vue.ts +18 -0
  84. package/dist/runtime/components/ui/tabs/TabsTrigger.vue +27 -0
  85. package/dist/runtime/components/ui/tabs/TabsTrigger.vue.d.ts +18 -0
  86. package/dist/runtime/components/ui/tabs/index.d.ts +4 -0
  87. package/dist/runtime/components/ui/tabs/index.js +4 -0
  88. package/dist/runtime/components/ui/textarea/Textarea.d.vue.ts +1 -0
  89. package/dist/runtime/components/ui/textarea/Textarea.vue +4 -2
  90. package/dist/runtime/components/ui/textarea/Textarea.vue.d.ts +1 -0
  91. package/dist/runtime/components/ui/toggle/Toggle.d.vue.ts +34 -0
  92. package/dist/runtime/components/ui/toggle/Toggle.vue +32 -0
  93. package/dist/runtime/components/ui/toggle/Toggle.vue.d.ts +34 -0
  94. package/dist/runtime/components/ui/toggle/index.d.ts +7 -0
  95. package/dist/runtime/components/ui/toggle/index.js +22 -0
  96. package/dist/runtime/composables/useTableRenderers.d.ts +2 -1
  97. package/dist/runtime/composables/useTableRenderers.js +2 -1
  98. package/dist/runtime/plugins/toast/index.d.ts +2 -2
  99. package/dist/runtime/style.css +1 -1
  100. package/dist/runtime/table-renderers/builtins.js +328 -137
  101. package/dist/runtime/table-renderers/registry.d.ts +2 -1
  102. package/dist/runtime/table-renderers/registry.js +3 -0
  103. package/dist/runtime/utils/coders.d.ts +29 -2
  104. package/dist/runtime/utils/coders.js +40 -2
  105. package/package.json +8 -6
  106. /package/dist/runtime/components/{logo.d.vue.ts → ui/logo/Logo.d.vue.ts} +0 -0
  107. /package/dist/runtime/components/{logo.vue → ui/logo/Logo.vue} +0 -0
  108. /package/dist/runtime/components/{logo.vue.d.ts → ui/logo/Logo.vue.d.ts} +0 -0
@@ -1,17 +1,117 @@
1
1
  import { jsx, jsxs } from "vue/jsx-runtime";
2
2
  import { Icon } from "@iconify/vue";
3
3
  import { format as formatDate, isValid, toDate } from "date-fns";
4
- import { defineComponent } from "vue";
4
+ import { defineComponent, h, ref } from "vue";
5
+ import { useI18n } from "vue-i18n";
5
6
  import { z } from "zod";
6
7
  import { defineTableRenderer } from "./registry.js";
7
8
  import { useNuxtApp } from "#app";
9
+ import { expressionC, getLocalizedText, hasVisibleLocaleValue, localeC } from "../utils/coders.js";
8
10
  import { Button } from "../components/ui/button/index.js";
9
11
  import { Checkbox } from "../components/ui/checkbox/index.js";
12
+ import ExpressionEditor from "../components/ui/expression-editor/ExpressionEditor.vue";
13
+ import { Input } from "../components/ui/input/index.js";
14
+ import Locale from "../components/ui/locale/Locale.vue";
15
+ import { NativeSelect, NativeSelectOption } from "../components/ui/native-select/index.js";
16
+ import { Switch } from "../components/ui/switch/index.js";
10
17
  const JUSTIFY_CLASS = {
11
18
  left: "justify-start",
12
19
  center: "justify-center",
13
20
  right: "justify-end"
14
21
  };
22
+ const MARKDOWN_EXPRESSION_EXAMPLE = "{{ expression }}";
23
+ const TABLE_RENDERER_CONFIG_MESSAGES = {
24
+ zh: {
25
+ "copyable": "\u53EF\u590D\u5236",
26
+ "copyable-description": "\u4E3A\u975E\u7A7A\u5355\u5143\u683C\u663E\u793A\u590D\u5236\u64CD\u4F5C\u3002",
27
+ "copy-cell-value": "\u590D\u5236\u5355\u5143\u683C\u5185\u5BB9",
28
+ "copy-expression": "\u590D\u5236\u8868\u8FBE\u5F0F",
29
+ "copy-expression-description": "\u590D\u5236\u65F6\u4F7F\u7528\u7684 CEL \u8868\u8FBE\u5F0F\u3002\u53D8\u91CF\uFF1Arow\u3001index\u3002",
30
+ "copy-expression-placeholder": "\u8F93\u5165\u590D\u5236 CEL \u8868\u8FBE\u5F0F",
31
+ "align": "\u5BF9\u9F50",
32
+ "align-left": "\u5DE6\u5BF9\u9F50",
33
+ "align-center": "\u5C45\u4E2D",
34
+ "align-right": "\u53F3\u5BF9\u9F50",
35
+ "selection-cross-page": "\u8DE8\u9875\u5168\u9009",
36
+ "format": "\u683C\u5F0F",
37
+ "preview": "\u9884\u89C8",
38
+ "markdown": "Markdown",
39
+ "markdown-description": "\u652F\u6301 Markdown \u7F16\u8F91\uFF0C\u652F\u6301\u5728 {expression} \u4E2D\u6C42\u503C\uFF1B\u5168\u90E8\u8BED\u8A00\u7559\u7A7A\u65F6\u56DE\u9000\u5230\u5355\u5143\u683C\u503C\u3002",
40
+ "no-options": "\u65E0\u53EF\u914D\u7F6E\u9879\u3002",
41
+ "select-all-rows-on-page": "\u9009\u62E9\u5F53\u524D\u9875\u5168\u90E8\u884C",
42
+ "select-all-rows": "\u9009\u62E9\u5168\u90E8\u884C",
43
+ "expand-row": "\u5C55\u5F00\u884C",
44
+ "collapse-row": "\u6536\u8D77\u884C",
45
+ "expand-all-rows": "\u5C55\u5F00\u5168\u90E8\u884C",
46
+ "collapse-all-rows": "\u6536\u8D77\u5168\u90E8\u884C"
47
+ },
48
+ ja: {
49
+ "copyable": "\u30B3\u30D4\u30FC\u53EF\u80FD",
50
+ "copyable-description": "\u7A7A\u3067\u306A\u3044\u30BB\u30EB\u306B\u30B3\u30D4\u30FC\u64CD\u4F5C\u3092\u8868\u793A\u3057\u307E\u3059\u3002",
51
+ "copy-cell-value": "\u30BB\u30EB\u306E\u5185\u5BB9\u3092\u30B3\u30D4\u30FC",
52
+ "copy-expression": "\u30B3\u30D4\u30FC\u5F0F",
53
+ "copy-expression-description": "\u30B3\u30D4\u30FC\u6642\u306B\u4F7F\u3046 CEL \u5F0F\u3067\u3059\u3002\u5909\u6570: row\u3001index\u3002",
54
+ "copy-expression-placeholder": "\u30B3\u30D4\u30FC\u7528 CEL \u5F0F\u3092\u5165\u529B",
55
+ "align": "\u914D\u7F6E",
56
+ "align-left": "\u5DE6\u5BC4\u305B",
57
+ "align-center": "\u4E2D\u592E\u63C3\u3048",
58
+ "align-right": "\u53F3\u5BC4\u305B",
59
+ "selection-cross-page": "\u30DA\u30FC\u30B8\u3092\u307E\u305F\u3044\u3067\u5168\u9078\u629E",
60
+ "format": "\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8",
61
+ "preview": "\u30D7\u30EC\u30D3\u30E5\u30FC",
62
+ "markdown": "Markdown",
63
+ "markdown-description": "Markdown \u3067\u7DE8\u96C6\u3067\u304D\u3001{expression} \u3082\u5229\u7528\u3067\u304D\u307E\u3059\u3002\u3059\u3079\u3066\u7A7A\u6B04\u306A\u3089\u30BB\u30EB\u5024\u306B\u623B\u308A\u307E\u3059\u3002",
64
+ "no-options": "\u8A2D\u5B9A\u53EF\u80FD\u306A\u9805\u76EE\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
65
+ "select-all-rows-on-page": "\u73FE\u5728\u306E\u30DA\u30FC\u30B8\u306E\u3059\u3079\u3066\u306E\u884C\u3092\u9078\u629E",
66
+ "select-all-rows": "\u3059\u3079\u3066\u306E\u884C\u3092\u9078\u629E",
67
+ "expand-row": "\u884C\u3092\u5C55\u958B",
68
+ "collapse-row": "\u884C\u3092\u6298\u308A\u305F\u305F\u3080",
69
+ "expand-all-rows": "\u3059\u3079\u3066\u306E\u884C\u3092\u5C55\u958B",
70
+ "collapse-all-rows": "\u3059\u3079\u3066\u306E\u884C\u3092\u6298\u308A\u305F\u305F\u3080"
71
+ },
72
+ en: {
73
+ "copyable": "Copyable",
74
+ "copyable-description": "Show a copy action for non-empty cells.",
75
+ "copy-cell-value": "Copy cell value",
76
+ "copy-expression": "Copy expression",
77
+ "copy-expression-description": "CEL expression used when copying. Variables: row, index.",
78
+ "copy-expression-placeholder": "Enter a copy CEL expression",
79
+ "align": "Align",
80
+ "align-left": "Left",
81
+ "align-center": "Center",
82
+ "align-right": "Right",
83
+ "selection-cross-page": "Cross page select-all",
84
+ "format": "Format",
85
+ "preview": "Preview",
86
+ "markdown": "Markdown",
87
+ "markdown-description": "Supports Markdown and {expression}; if every locale is blank, use the cell value.",
88
+ "no-options": "No options.",
89
+ "select-all-rows-on-page": "Select all rows on page",
90
+ "select-all-rows": "Select all rows",
91
+ "expand-row": "Expand row",
92
+ "collapse-row": "Collapse row",
93
+ "expand-all-rows": "Expand all rows",
94
+ "collapse-all-rows": "Collapse all rows"
95
+ }
96
+ };
97
+ function useTableRendererConfigI18n() {
98
+ return useI18n({
99
+ inheritLocale: true,
100
+ messages: TABLE_RENDERER_CONFIG_MESSAGES
101
+ });
102
+ }
103
+ function getTableRendererConfigText(key) {
104
+ const language = navigator?.language?.toLocaleLowerCase() ?? "zh";
105
+ if (language.startsWith("ja")) {
106
+ return TABLE_RENDERER_CONFIG_MESSAGES.ja[key];
107
+ }
108
+ if (language.startsWith("en")) {
109
+ return TABLE_RENDERER_CONFIG_MESSAGES.en[key];
110
+ }
111
+ return TABLE_RENDERER_CONFIG_MESSAGES.zh[key];
112
+ }
113
+ const TEXT_RENDERER_COPY_EXPRESSION_C = expressionC(/.+/, { row: "dyn", index: "int" }).optional();
114
+ const DATE_RENDERER_PREVIEW_DATE = new Date(2025, 8, 30, 13, 59, 43);
15
115
  const TableRendererTextConfig = defineComponent({
16
116
  name: "TableRendererTextConfig",
17
117
  props: {
@@ -21,62 +121,76 @@ const TableRendererTextConfig = defineComponent({
21
121
  }
22
122
  },
23
123
  emits: ["update:modelValue"],
24
- setup(props, { emit }) {
124
+ setup(props, { emit, expose }) {
125
+ const { t } = useTableRendererConfigI18n();
126
+ const copyExpressionEditor = ref(null);
25
127
  const value = () => props.modelValue ?? {};
26
128
  const update = (patch) => {
27
129
  emit("update:modelValue", { ...value(), ...patch });
28
130
  };
131
+ function clearValidation() {
132
+ copyExpressionEditor.value?.clearValidation();
133
+ }
134
+ function validate() {
135
+ return copyExpressionEditor.value ? copyExpressionEditor.value.validate() : true;
136
+ }
137
+ expose({
138
+ clearValidation,
139
+ validate
140
+ });
29
141
  return () => /* @__PURE__ */ jsxs("div", { class: "flex flex-col gap-3 text-sm text-zinc-700", children: [
30
- /* @__PURE__ */ jsxs("label", { class: "flex items-center gap-2 select-none", children: [
31
- /* @__PURE__ */ jsx(
32
- "input",
33
- {
34
- type: "checkbox",
35
- checked: Boolean(value().copyable),
36
- onInput: (e) => {
37
- if (e.target instanceof HTMLInputElement)
38
- update({ copyable: e.target.checked });
39
- }
40
- }
41
- ),
42
- /* @__PURE__ */ jsx("span", { children: "Copyable" })
43
- ] }),
142
+ /* @__PURE__ */ jsxs(
143
+ "label",
144
+ {
145
+ "data-field-key": "rendererCopyable",
146
+ class: "flex items-center justify-between gap-3 py-1",
147
+ children: [
148
+ /* @__PURE__ */ jsxs("div", { class: "flex flex-col gap-1", children: [
149
+ /* @__PURE__ */ jsx("span", { class: "text-sm font-medium text-zinc-800", children: t("copyable") }),
150
+ /* @__PURE__ */ jsx("span", { class: "text-xs text-zinc-500", children: t("copyable-description") })
151
+ ] }),
152
+ /* @__PURE__ */ jsx(
153
+ Switch,
154
+ {
155
+ modelValue: Boolean(value().copyable),
156
+ "onUpdate:modelValue": (...args) => update({ copyable: args[0] === true })
157
+ }
158
+ )
159
+ ]
160
+ }
161
+ ),
162
+ /* @__PURE__ */ jsx(
163
+ ExpressionEditor,
164
+ {
165
+ ref: copyExpressionEditor,
166
+ "data-field-key": "rendererCopyExpression",
167
+ modelValue: value().copyExpression ?? void 0,
168
+ label: t("copy-expression"),
169
+ description: t("copy-expression-description"),
170
+ placeholder: t("copy-expression-placeholder"),
171
+ schema: TEXT_RENDERER_COPY_EXPRESSION_C,
172
+ "onUpdate:modelValue": (nextValue) => update({ copyExpression: nextValue ?? null })
173
+ }
174
+ ),
44
175
  /* @__PURE__ */ jsxs("label", { class: "flex flex-col gap-1", children: [
45
- /* @__PURE__ */ jsx("span", { class: "text-xs text-zinc-500", children: "Copy expression" }),
46
- /* @__PURE__ */ jsx(
47
- "input",
48
- {
49
- class: "border border-zinc-200 rounded px-2 py-1 text-sm",
50
- placeholder: "CEL expression (row, index)",
51
- value: value().copyExpression ?? "",
52
- onInput: (e) => {
53
- if (e.target instanceof HTMLInputElement)
54
- update({ copyExpression: e.target.value || null });
176
+ /* @__PURE__ */ jsx("span", { class: "text-xs font-medium text-zinc-500", children: t("align") }),
177
+ h(NativeSelect, {
178
+ "data-field-key": "rendererAlign",
179
+ "modelValue": value().align ?? "left",
180
+ "class": "w-full",
181
+ "onUpdate:modelValue": (...args) => {
182
+ const nextValue = args[0];
183
+ if (nextValue === "left" || nextValue === "center" || nextValue === "right") {
184
+ update({ align: nextValue });
55
185
  }
56
186
  }
57
- )
58
- ] }),
59
- /* @__PURE__ */ jsxs("label", { class: "flex flex-col gap-1", children: [
60
- /* @__PURE__ */ jsx("span", { class: "text-xs text-zinc-500", children: "Align" }),
61
- /* @__PURE__ */ jsxs(
62
- "select",
63
- {
64
- class: "border border-zinc-200 rounded px-2 py-1 text-sm bg-white",
65
- value: value().align ?? "left",
66
- onChange: (e) => {
67
- if (e.target instanceof HTMLSelectElement) {
68
- const v = e.target.value;
69
- if (v === "left" || v === "center" || v === "right")
70
- update({ align: v });
71
- }
72
- },
73
- children: [
74
- /* @__PURE__ */ jsx("option", { value: "left", children: "left" }),
75
- /* @__PURE__ */ jsx("option", { value: "center", children: "center" }),
76
- /* @__PURE__ */ jsx("option", { value: "right", children: "right" })
77
- ]
78
- }
79
- )
187
+ }, {
188
+ default: () => [
189
+ h(NativeSelectOption, { value: "left" }, { default: () => t("align-left") }),
190
+ h(NativeSelectOption, { value: "center" }, { default: () => t("align-center") }),
191
+ h(NativeSelectOption, { value: "right" }, { default: () => t("align-right") })
192
+ ]
193
+ })
80
194
  ] })
81
195
  ] });
82
196
  }
@@ -91,24 +205,32 @@ const TableRendererSelectionConfig = defineComponent({
91
205
  },
92
206
  emits: ["update:modelValue"],
93
207
  setup(props, { emit }) {
208
+ const { t } = useTableRendererConfigI18n();
94
209
  const value = () => props.modelValue ?? {};
95
210
  const update = (patch) => {
96
211
  emit("update:modelValue", { ...value(), ...patch });
97
212
  };
98
- return () => /* @__PURE__ */ jsx("div", { class: "flex flex-col gap-3 text-sm text-zinc-700", children: /* @__PURE__ */ jsxs("label", { class: "flex items-center gap-2 select-none", children: [
99
- /* @__PURE__ */ jsx(
100
- "input",
101
- {
102
- type: "checkbox",
103
- checked: Boolean(value().crossPage),
104
- onInput: (e) => {
105
- if (e.target instanceof HTMLInputElement)
106
- update({ crossPage: e.target.checked });
107
- }
108
- }
109
- ),
110
- /* @__PURE__ */ jsx("span", { children: "Cross page select-all" })
111
- ] }) });
213
+ return () => /* @__PURE__ */ jsx("div", { class: "flex flex-col gap-3 text-sm text-zinc-700", children: /* @__PURE__ */ jsxs(
214
+ "label",
215
+ {
216
+ "data-field-key": "rendererSelectionCrossPage",
217
+ class: "flex items-center gap-2 select-none",
218
+ children: [
219
+ /* @__PURE__ */ jsx(
220
+ "input",
221
+ {
222
+ type: "checkbox",
223
+ checked: Boolean(value().crossPage),
224
+ onInput: (e) => {
225
+ if (e.target instanceof HTMLInputElement)
226
+ update({ crossPage: e.target.checked });
227
+ }
228
+ }
229
+ ),
230
+ /* @__PURE__ */ jsx("span", { children: t("selection-cross-page") })
231
+ ]
232
+ }
233
+ ) });
112
234
  }
113
235
  });
114
236
  const TableRendererDateConfig = defineComponent({
@@ -120,26 +242,35 @@ const TableRendererDateConfig = defineComponent({
120
242
  }
121
243
  },
122
244
  emits: ["update:modelValue"],
123
- setup(props, { emit }) {
245
+ setup(props, { emit, expose }) {
246
+ const { t } = useTableRendererConfigI18n();
124
247
  const value = () => props.modelValue ?? {};
125
248
  const update = (patch) => {
126
249
  emit("update:modelValue", { ...value(), ...patch });
127
250
  };
128
- return () => /* @__PURE__ */ jsx("div", { class: "flex flex-col gap-3 text-sm text-zinc-700", children: /* @__PURE__ */ jsxs("label", { class: "flex flex-col gap-1", children: [
129
- /* @__PURE__ */ jsx("span", { class: "text-xs text-zinc-500", children: "Format" }),
130
- /* @__PURE__ */ jsx(
131
- "input",
132
- {
133
- class: "border border-zinc-200 rounded px-2 py-1 text-sm",
134
- placeholder: "yyyy-MM-dd",
135
- value: value().format ?? "",
136
- onInput: (e) => {
137
- if (e.target instanceof HTMLInputElement)
138
- update({ format: e.target.value });
251
+ expose({
252
+ clearValidation: () => void 0,
253
+ validate: () => true
254
+ });
255
+ return () => /* @__PURE__ */ jsxs("div", { class: "flex flex-col gap-3 text-sm text-zinc-700", children: [
256
+ /* @__PURE__ */ jsxs("label", { class: "flex flex-col gap-1", children: [
257
+ /* @__PURE__ */ jsx("span", { class: "text-xs font-medium text-zinc-500", children: t("format") }),
258
+ /* @__PURE__ */ jsx(
259
+ Input,
260
+ {
261
+ "data-field-key": "rendererDateFormat",
262
+ placeholder: "yyyy-MM-dd",
263
+ modelValue: value().format ?? "",
264
+ "onUpdate:modelValue": (nextValue) => update({ format: String(nextValue) })
139
265
  }
140
- }
141
- )
142
- ] }) });
266
+ )
267
+ ] }),
268
+ /* @__PURE__ */ jsxs("div", { class: "rounded-md bg-zinc-50/70 px-3 py-2", children: [
269
+ /* @__PURE__ */ jsx("div", { class: "text-xs font-medium text-zinc-500", children: t("preview") }),
270
+ /* @__PURE__ */ jsx("div", { class: "mt-1 font-mono text-sm text-zinc-700", children: formatTableRendererDate(DATE_RENDERER_PREVIEW_DATE, value().format ?? "yyyy-MM-dd") }),
271
+ /* @__PURE__ */ jsx("div", { class: "mt-1 text-xs text-zinc-400", children: "2025-09-30 13:59:43" })
272
+ ] })
273
+ ] });
143
274
  }
144
275
  });
145
276
  const TableRendererMarkdownConfig = defineComponent({
@@ -151,35 +282,103 @@ const TableRendererMarkdownConfig = defineComponent({
151
282
  }
152
283
  },
153
284
  emits: ["update:modelValue"],
154
- setup(props, { emit }) {
285
+ setup(props, { emit, expose }) {
286
+ const { t } = useTableRendererConfigI18n();
155
287
  const value = () => props.modelValue ?? {};
156
288
  const update = (patch) => {
157
289
  emit("update:modelValue", { ...value(), ...patch });
158
290
  };
159
- return () => /* @__PURE__ */ jsx("div", { class: "flex flex-col gap-3 text-sm text-zinc-700", children: /* @__PURE__ */ jsxs("label", { class: "flex flex-col gap-1", children: [
160
- /* @__PURE__ */ jsx("span", { class: "text-xs text-zinc-500", children: "Source" }),
291
+ expose({
292
+ clearValidation: () => void 0,
293
+ validate: () => true
294
+ });
295
+ return () => /* @__PURE__ */ jsxs("div", { class: "flex flex-col gap-3 text-sm text-zinc-700", children: [
296
+ /* @__PURE__ */ jsxs("div", { class: "flex flex-col gap-1", children: [
297
+ /* @__PURE__ */ jsx("span", { class: "text-xs font-medium text-zinc-500", children: t("markdown") }),
298
+ /* @__PURE__ */ jsx("span", { class: "text-sm text-zinc-500", children: t("markdown-description", { expression: MARKDOWN_EXPRESSION_EXAMPLE }) })
299
+ ] }),
161
300
  /* @__PURE__ */ jsx(
162
- "textarea",
301
+ Locale,
163
302
  {
164
- class: "border border-zinc-200 rounded px-2 py-1 text-sm min-h-20",
165
- placeholder: "Markdown source (leave empty to use cell value)",
166
- value: value().source ?? "",
167
- onInput: (e) => {
168
- if (e.target instanceof HTMLTextAreaElement)
169
- update({ source: e.target.value || void 0 });
170
- }
303
+ "data-field-key": "rendererMarkdownSource",
304
+ "data-slot": "table-renderer-markdown-source-locale",
305
+ multiline: true,
306
+ modelValue: value().source,
307
+ "onUpdate:modelValue": (nextValue) => update({ source: hasVisibleLocaleValue(nextValue) ? nextValue : void 0 })
171
308
  }
172
309
  )
173
- ] }) });
310
+ ] });
311
+ }
312
+ });
313
+ const TableRendererMarkdownCell = defineComponent({
314
+ name: "TableRendererMarkdownCell",
315
+ props: {
316
+ source: {
317
+ type: Array,
318
+ default: void 0
319
+ },
320
+ fallbackSource: {
321
+ type: String,
322
+ required: true
323
+ },
324
+ row: {
325
+ default: void 0
326
+ },
327
+ index: {
328
+ type: Number,
329
+ required: true
330
+ },
331
+ id: {
332
+ type: String,
333
+ required: true
334
+ }
335
+ },
336
+ setup(props) {
337
+ const { locale } = useI18n();
338
+ const { $md } = useNuxtApp();
339
+ return () => {
340
+ const source = getLocalizedText(props.source, locale.value) ?? props.fallbackSource;
341
+ return /* @__PURE__ */ jsx("div", { class: "relative w-full py-2 px-1 flex items-center justify-center text-xs", children: /* @__PURE__ */ jsx(
342
+ "span",
343
+ {
344
+ class: "prose prose-zinc text-xs",
345
+ innerHTML: $md.inline`${source}`({
346
+ row: props.row,
347
+ index: BigInt(props.index),
348
+ id: props.id
349
+ })
350
+ }
351
+ ) });
352
+ };
174
353
  }
175
354
  });
176
355
  const NoOptionsConfig = defineComponent({
177
356
  name: "TableRendererNoOptionsConfig",
178
357
  emits: ["update:modelValue"],
179
- setup() {
180
- return () => /* @__PURE__ */ jsx("div", { class: "text-xs text-zinc-500", children: "No options." });
358
+ setup(_props, { expose }) {
359
+ const { t } = useTableRendererConfigI18n();
360
+ expose({
361
+ clearValidation: () => void 0,
362
+ validate: () => true
363
+ });
364
+ return () => /* @__PURE__ */ jsx("div", { class: "text-xs text-zinc-500", children: t("no-options") });
181
365
  }
182
366
  });
367
+ function formatTableRendererDate(value, formatPattern) {
368
+ let date = null;
369
+ try {
370
+ date = typeof value === "string" || typeof value === "number" || value instanceof Date ? toDate(value) : null;
371
+ } catch {
372
+ }
373
+ if (!date || !isValid(date)) {
374
+ return "-";
375
+ }
376
+ try {
377
+ return formatDate(date, formatPattern);
378
+ } catch {
379
+ return "-";
380
+ }
381
+ }
183
382
  defineTableRenderer(
184
383
  "table.renderer.text",
185
384
  {
@@ -222,6 +421,7 @@ defineTableRenderer(
222
421
  options.copyable && !isEmpty ? /* @__PURE__ */ jsx(
223
422
  Button,
224
423
  {
424
+ "aria-label": getTableRendererConfigText("copy-cell-value"),
225
425
  class: "p-1 w-6 h-6 flex items-center justify-center right-1 top-1/2 -translate-y-1/2 transform-3d group-hover:opacity-100 opacity-0 absolute transition-opacity duration-180",
226
426
  size: "xs",
227
427
  onClick: onCopy,
@@ -232,7 +432,10 @@ defineTableRenderer(
232
432
  }
233
433
  );
234
434
  },
235
- config: TableRendererTextConfig
435
+ config: TableRendererTextConfig,
436
+ columnDefOverrides: {
437
+ sortingFn: "alphanumeric"
438
+ }
236
439
  }
237
440
  );
238
441
  defineTableRenderer(
@@ -248,7 +451,7 @@ defineTableRenderer(
248
451
  id: `${ctx.column.id}-${ctx.row.id}`,
249
452
  disabled: !ctx.row.getCanSelect(),
250
453
  modelValue: ctx.row.getIsSelected(),
251
- "onUpdate:modelValue": ctx.row.getToggleSelectedHandler(),
454
+ "onUpdate:modelValue": (value) => ctx.row.toggleSelected(value === true),
252
455
  class: "w-4 h-4"
253
456
  }
254
457
  ) });
@@ -259,28 +462,23 @@ defineTableRenderer(
259
462
  const crossPage = options.crossPage ?? false;
260
463
  const indeterminate = crossPage ? ctx.table.getIsSomePageRowsSelected() : ctx.table.getIsSomeRowsSelected();
261
464
  const checked = crossPage ? ctx.table.getIsAllPageRowsSelected() : ctx.table.getIsAllRowsSelected();
262
- const onInput = crossPage ? ctx.table.getToggleAllPageRowsSelectedHandler() : ctx.table.getToggleAllRowsSelectedHandler();
263
- return /* @__PURE__ */ jsx("div", { class: "inline-flex items-center", children: /* @__PURE__ */ jsxs("label", { class: "flex items-center cursor-pointer relative", children: [
264
- /* @__PURE__ */ jsx(
265
- "input",
266
- {
267
- id: `${ctx.column.id}-header`,
268
- type: "checkbox",
269
- checked,
270
- class: [
271
- "peer h-4 w-4 cursor-pointer transition-colors duration-180 appearance-none rounded bg-white",
272
- "border border-[color-mix(in_srgb,var(--primary)_10%,#00000033)] not-checked-group-hover:border-[color-mix(in_srgb,var(--primary)_20%,#00000033)]",
273
- "not-checked-group-hover:bg-[color-mix(in_srgb,var(--primary)_5%,#00000011)] checked:border-(--primary) checked:bg-(--primary)"
274
- ],
275
- ref: (el) => {
276
- if (el instanceof HTMLInputElement)
277
- el.indeterminate = Boolean(indeterminate);
278
- },
279
- onInput: (e) => onInput(e)
280
- }
281
- ),
282
- /* @__PURE__ */ jsx("span", { class: "absolute text-white opacity-0 peer-checked:opacity-100 top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 pointer-events-none", children: /* @__PURE__ */ jsx(Icon, { icon: "fluent:checkmark-20-filled", class: "text-white text-xs" }) })
283
- ] }) });
465
+ const modelValue = checked ? true : indeterminate ? "indeterminate" : false;
466
+ return /* @__PURE__ */ jsx("div", { class: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx(
467
+ Checkbox,
468
+ {
469
+ id: `${ctx.column.id}-header`,
470
+ modelValue,
471
+ "aria-label": crossPage ? getTableRendererConfigText("select-all-rows-on-page") : getTableRendererConfigText("select-all-rows"),
472
+ "onUpdate:modelValue": (value) => {
473
+ if (crossPage) {
474
+ ctx.table.toggleAllPageRowsSelected(value === true);
475
+ return;
476
+ }
477
+ ctx.table.toggleAllRowsSelected(value === true);
478
+ },
479
+ class: "w-4 h-4 bg-white"
480
+ }
481
+ ) });
284
482
  },
285
483
  config: TableRendererSelectionConfig,
286
484
  columnDefOverrides: {
@@ -300,6 +498,7 @@ defineTableRenderer(
300
498
  {
301
499
  variant: "ghost",
302
500
  class: "cursor-pointer hover:bg-transparent text-lg",
501
+ "aria-label": ctx.row.getIsExpanded() ? getTableRendererConfigText("collapse-row") : getTableRendererConfigText("expand-row"),
303
502
  onClick: ctx.row.getToggleExpandedHandler(),
304
503
  children: /* @__PURE__ */ jsx(Icon, { icon: ctx.row.getIsExpanded() ? "fluent:subtract-square-20-regular" : "fluent:add-square-20-regular" })
305
504
  }
@@ -311,6 +510,7 @@ defineTableRenderer(
311
510
  variant: "ghost",
312
511
  size: "xs",
313
512
  class: "cursor-pointer hover:bg-transparent text-lg",
513
+ "aria-label": ctx.table.getIsAllRowsExpanded() ? getTableRendererConfigText("collapse-all-rows") : getTableRendererConfigText("expand-all-rows"),
314
514
  onClick: ctx.table.getToggleAllRowsExpandedHandler(),
315
515
  children: /* @__PURE__ */ jsx(Icon, { icon: ctx.table.getIsAllRowsExpanded() ? "fluent:subtract-square-20-regular" : "fluent:add-square-20-regular" })
316
516
  }
@@ -351,20 +551,14 @@ defineTableRenderer(
351
551
  },
352
552
  {
353
553
  cell: ({ ctx, options }) => {
354
- const value = ctx.cell.getValue();
355
- let d = null;
356
- try {
357
- d = typeof value === "string" || typeof value === "number" || value instanceof Date ? toDate(value) : null;
358
- } catch {
359
- }
360
- const date = isValid(d) ? d : null;
361
- const formatted = date ? formatDate(date, options.format ?? "yyyy-MM-dd") : "-";
554
+ const formatted = formatTableRendererDate(ctx.cell.getValue(), options.format ?? "yyyy-MM-dd");
555
+ const hasDate = formatted !== "-";
362
556
  return /* @__PURE__ */ jsx(
363
557
  "div",
364
558
  {
365
559
  class: [
366
560
  "relative w-full py-2 px-1 flex items-center justify-center text-xs",
367
- date ? "text-zinc-600" : "text-zinc-300 select-none"
561
+ hasDate ? "text-zinc-600" : "text-zinc-300 select-none"
368
562
  ],
369
563
  children: formatted
370
564
  }
@@ -376,23 +570,20 @@ defineTableRenderer(
376
570
  defineTableRenderer(
377
571
  "table.renderer.markdown",
378
572
  {
379
- source: z.string().optional()
573
+ source: localeC.optional()
380
574
  },
381
575
  {
382
576
  cell: ({ ctx, options }) => {
383
- const { $md } = useNuxtApp();
384
- const source = options.source ?? String(ctx.cell.getValue());
385
- return /* @__PURE__ */ jsx("div", { class: "relative w-full py-2 px-1 flex items-center justify-center text-xs", children: /* @__PURE__ */ jsx(
386
- "span",
577
+ return /* @__PURE__ */ jsx(
578
+ TableRendererMarkdownCell,
387
579
  {
388
- class: "prose prose-zinc text-xs",
389
- innerHTML: $md.inline`${source}`({
390
- row: ctx.row.original,
391
- index: BigInt(ctx.row.index),
392
- id: ctx.column.id
393
- })
580
+ source: options.source,
581
+ fallbackSource: String(ctx.cell.getValue()),
582
+ row: ctx.row.original,
583
+ index: ctx.row.index,
584
+ id: ctx.column.id
394
585
  }
395
- ) });
586
+ );
396
587
  },
397
588
  config: TableRendererMarkdownConfig
398
589
  }
@@ -2,7 +2,7 @@ import type { CellContext, ColumnDef, HeaderContext, RowData } from '@tanstack/v
2
2
  import type { VNodeChild } from 'vue';
3
3
  import { z } from 'zod';
4
4
  export type TableRendererId = string;
5
- export type TableRendererColumnDefOverrides<TData extends RowData = unknown> = Partial<Pick<ColumnDef<TData, unknown>, 'enableResizing' | 'enableSorting' | 'enableMultiSort' | 'enablePinning' | 'size' | 'meta'>>;
5
+ export type TableRendererColumnDefOverrides<TData extends RowData = unknown> = Partial<Pick<ColumnDef<TData, unknown>, 'enableResizing' | 'enableSorting' | 'enableMultiSort' | 'enablePinning' | 'sortingFn' | 'size' | 'meta'>>;
6
6
  export type TableRendererCellArgs<TData extends RowData, TValue, TOptions> = Readonly<{
7
7
  ctx: CellContext<TData, TValue>;
8
8
  options: TOptions;
@@ -34,4 +34,5 @@ export declare function defineTableRenderer<const TShape extends z.ZodRawShape,
34
34
  columnDefOverrides?: TableRenderer<TOptions>['columnDefOverrides'];
35
35
  }>): TableRenderer<TOptions>;
36
36
  export declare function getTableRenderer(id: TableRendererId): TableRenderer<unknown> | undefined;
37
+ export declare function listTableRenderers(): Array<TableRenderer<unknown>>;
37
38
  export declare function resolveTableRenderer(id: TableRendererId): TableRenderer<unknown>;
@@ -21,6 +21,9 @@ export function defineTableRenderer(id, shape, impl) {
21
21
  export function getTableRenderer(id) {
22
22
  return _renderers.get(id);
23
23
  }
24
+ export function listTableRenderers() {
25
+ return Array.from(_renderers.values());
26
+ }
24
27
  export function resolveTableRenderer(id) {
25
28
  return _renderers.get(id) ?? _renderers.get("table.renderer.text");
26
29
  }