@shwfed/nuxt 0.1.29 → 0.1.31

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 (80) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/app.d.vue.ts +2 -0
  3. package/dist/runtime/components/app.vue +4 -0
  4. package/dist/runtime/components/app.vue.d.ts +2 -0
  5. package/dist/runtime/components/query.d.vue.ts +68 -8
  6. package/dist/runtime/components/query.vue +103 -42
  7. package/dist/runtime/components/query.vue.d.ts +68 -8
  8. package/dist/runtime/components/table.d.vue.ts +2 -2
  9. package/dist/runtime/components/table.vue +105 -15
  10. package/dist/runtime/components/table.vue.d.ts +2 -2
  11. package/dist/runtime/components/ui/field/index.js +3 -3
  12. package/dist/runtime/components/ui/input/Input.d.vue.ts +1 -0
  13. package/dist/runtime/components/ui/input/Input.vue +4 -3
  14. package/dist/runtime/components/ui/input/Input.vue.d.ts +1 -0
  15. package/dist/runtime/components/ui/input-group/InputGroup.d.vue.ts +1 -1
  16. package/dist/runtime/components/ui/input-group/InputGroup.vue +4 -0
  17. package/dist/runtime/components/ui/input-group/InputGroup.vue.d.ts +1 -1
  18. package/dist/runtime/components/ui/input-group/InputGroupCombobox.d.vue.ts +14 -0
  19. package/dist/runtime/components/ui/input-group/InputGroupCombobox.vue +84 -0
  20. package/dist/runtime/components/ui/input-group/InputGroupCombobox.vue.d.ts +14 -0
  21. package/dist/runtime/components/ui/input-group/InputGroupInput.d.vue.ts +1 -0
  22. package/dist/runtime/components/ui/input-group/InputGroupInput.vue +3 -1
  23. package/dist/runtime/components/ui/input-group/InputGroupInput.vue.d.ts +1 -0
  24. package/dist/runtime/components/ui/input-group/InputGroupNumberField.d.vue.ts +12 -0
  25. package/dist/runtime/components/ui/input-group/InputGroupNumberField.vue +45 -0
  26. package/dist/runtime/components/ui/input-group/InputGroupNumberField.vue.d.ts +12 -0
  27. package/dist/runtime/components/ui/input-group/index.d.ts +4 -1
  28. package/dist/runtime/components/ui/input-group/index.js +4 -1
  29. package/dist/runtime/components/ui/navigation-menu/NavigationMenu.d.vue.ts +27 -0
  30. package/dist/runtime/components/ui/navigation-menu/NavigationMenu.vue +41 -0
  31. package/dist/runtime/components/ui/navigation-menu/NavigationMenu.vue.d.ts +27 -0
  32. package/dist/runtime/components/ui/navigation-menu/NavigationMenuContent.d.vue.ts +28 -0
  33. package/dist/runtime/components/ui/navigation-menu/NavigationMenuContent.vue +32 -0
  34. package/dist/runtime/components/ui/navigation-menu/NavigationMenuContent.vue.d.ts +28 -0
  35. package/dist/runtime/components/ui/navigation-menu/NavigationMenuIndicator.d.vue.ts +8 -0
  36. package/dist/runtime/components/ui/navigation-menu/NavigationMenuIndicator.vue +23 -0
  37. package/dist/runtime/components/ui/navigation-menu/NavigationMenuIndicator.vue.d.ts +8 -0
  38. package/dist/runtime/components/ui/navigation-menu/NavigationMenuItem.d.vue.ts +18 -0
  39. package/dist/runtime/components/ui/navigation-menu/NavigationMenuItem.vue +22 -0
  40. package/dist/runtime/components/ui/navigation-menu/NavigationMenuItem.vue.d.ts +18 -0
  41. package/dist/runtime/components/ui/navigation-menu/NavigationMenuLink.d.vue.ts +26 -0
  42. package/dist/runtime/components/ui/navigation-menu/NavigationMenuLink.vue +27 -0
  43. package/dist/runtime/components/ui/navigation-menu/NavigationMenuLink.vue.d.ts +26 -0
  44. package/dist/runtime/components/ui/navigation-menu/NavigationMenuList.d.vue.ts +18 -0
  45. package/dist/runtime/components/ui/navigation-menu/NavigationMenuList.vue +27 -0
  46. package/dist/runtime/components/ui/navigation-menu/NavigationMenuList.vue.d.ts +18 -0
  47. package/dist/runtime/components/ui/navigation-menu/NavigationMenuTrigger.d.vue.ts +18 -0
  48. package/dist/runtime/components/ui/navigation-menu/NavigationMenuTrigger.vue +33 -0
  49. package/dist/runtime/components/ui/navigation-menu/NavigationMenuTrigger.vue.d.ts +18 -0
  50. package/dist/runtime/components/ui/navigation-menu/NavigationMenuViewport.d.vue.ts +8 -0
  51. package/dist/runtime/components/ui/navigation-menu/NavigationMenuViewport.vue +32 -0
  52. package/dist/runtime/components/ui/navigation-menu/NavigationMenuViewport.vue.d.ts +8 -0
  53. package/dist/runtime/components/ui/navigation-menu/index.d.ts +9 -0
  54. package/dist/runtime/components/ui/navigation-menu/index.js +12 -0
  55. package/dist/runtime/components/ui/number-field/NumberField.d.vue.ts +25 -0
  56. package/dist/runtime/components/ui/number-field/NumberField.vue +39 -0
  57. package/dist/runtime/components/ui/number-field/NumberField.vue.d.ts +25 -0
  58. package/dist/runtime/components/ui/number-field/NumberFieldContent.d.vue.ts +17 -0
  59. package/dist/runtime/components/ui/number-field/NumberFieldContent.vue +12 -0
  60. package/dist/runtime/components/ui/number-field/NumberFieldContent.vue.d.ts +17 -0
  61. package/dist/runtime/components/ui/number-field/NumberFieldDecrement.d.vue.ts +18 -0
  62. package/dist/runtime/components/ui/number-field/NumberFieldDecrement.vue +29 -0
  63. package/dist/runtime/components/ui/number-field/NumberFieldDecrement.vue.d.ts +18 -0
  64. package/dist/runtime/components/ui/number-field/NumberFieldIncrement.d.vue.ts +18 -0
  65. package/dist/runtime/components/ui/number-field/NumberFieldIncrement.vue +29 -0
  66. package/dist/runtime/components/ui/number-field/NumberFieldIncrement.vue.d.ts +18 -0
  67. package/dist/runtime/components/ui/number-field/NumberFieldInput.d.vue.ts +7 -0
  68. package/dist/runtime/components/ui/number-field/NumberFieldInput.vue +14 -0
  69. package/dist/runtime/components/ui/number-field/NumberFieldInput.vue.d.ts +7 -0
  70. package/dist/runtime/components/ui/number-field/index.d.ts +5 -0
  71. package/dist/runtime/components/ui/number-field/index.js +5 -0
  72. package/dist/runtime/components/ui/popover/PopoverContent.vue +1 -1
  73. package/dist/runtime/plugins/cel/index.js +2 -4
  74. package/package.json +2 -1
  75. package/dist/runtime/components/ui/input-group/InputCombobox.d.vue.ts +0 -13
  76. package/dist/runtime/components/ui/input-group/InputCombobox.vue +0 -56
  77. package/dist/runtime/components/ui/input-group/InputCombobox.vue.d.ts +0 -13
  78. /package/dist/runtime/components/ui/input-group/{InputComboboxInput.d.vue.ts → InputGroupComboboxInput.d.vue.ts} +0 -0
  79. /package/dist/runtime/components/ui/input-group/{InputComboboxInput.vue → InputGroupComboboxInput.vue} +0 -0
  80. /package/dist/runtime/components/ui/input-group/{InputComboboxInput.vue.d.ts → InputGroupComboboxInput.vue.d.ts} +0 -0
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shwfed/nuxt",
3
3
  "configKey": "shwfed",
4
- "version": "0.1.29",
4
+ "version": "0.1.31",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -9,6 +9,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
9
9
  children: ReadonlyArray<Readonly<{
10
10
  id: string;
11
11
  title: string;
12
+ keywords?: ReadonlyArray<string>;
12
13
  icon?: string;
13
14
  effect: Effect.Effect<void, never, Scope.Scope>;
14
15
  }>>;
@@ -20,6 +21,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
20
21
  children: ReadonlyArray<Readonly<{
21
22
  id: string;
22
23
  title: string;
24
+ keywords?: ReadonlyArray<string>;
23
25
  icon?: string;
24
26
  effect: Effect.Effect<void, never, Scope.Scope>;
25
27
  }>>;
@@ -70,6 +70,10 @@ whenever(() => meta_k?.value, () => {
70
70
  :icon="child.icon"
71
71
  />
72
72
  <span>{{ child.title }}</span>
73
+ <span
74
+ v-if="child.keywords?.length"
75
+ class="sr-only"
76
+ >{{ child.keywords.join(" ") }}</span>
73
77
  </CommandItem>
74
78
  </CommandGroup>
75
79
  <CommandSeparator v-if="i !== Object.keys(commands ?? {}).length - 1" />
@@ -9,6 +9,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
9
9
  children: ReadonlyArray<Readonly<{
10
10
  id: string;
11
11
  title: string;
12
+ keywords?: ReadonlyArray<string>;
12
13
  icon?: string;
13
14
  effect: Effect.Effect<void, never, Scope.Scope>;
14
15
  }>>;
@@ -20,6 +21,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
20
21
  children: ReadonlyArray<Readonly<{
21
22
  id: string;
22
23
  title: string;
24
+ keywords?: ReadonlyArray<string>;
23
25
  icon?: string;
24
26
  effect: Effect.Effect<void, never, Scope.Scope>;
25
27
  }>>;
@@ -1,10 +1,70 @@
1
- type __VLS_Props = {
2
- fields: ReadonlyArray<{
3
- label: string;
4
- prop: string;
5
- initial?: string;
6
- }>;
7
- };
8
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
1
+ import { Field } from './ui/field/index.js';
2
+ import type { ClassValue } from 'clsx';
3
+ type Option = Readonly<{
4
+ label: Record<string, string>;
5
+ value: string | number;
6
+ icon?: string;
7
+ }>;
8
+ type OptionsGroup = Readonly<{
9
+ label: Record<string, string>;
10
+ value: string | number;
11
+ options: ReadonlyArray<Option>;
12
+ }>;
13
+ type TextField = Readonly<{
14
+ type: 'string';
15
+ path: string;
16
+ label: Record<string, string>;
17
+ intial?: string;
18
+ icon?: string;
19
+ class?: ClassValue;
20
+ treatEmptyAsDifferentStateFromNull?: boolean;
21
+ }>;
22
+ type SelectField = Readonly<{
23
+ type: 'select';
24
+ path: string;
25
+ label: Record<string, string>;
26
+ intial?: string;
27
+ icon?: string;
28
+ options: ReadonlyArray<OptionsGroup>;
29
+ class?: ClassValue;
30
+ }>;
31
+ type NumberField = Readonly<{
32
+ type: 'number';
33
+ path: string;
34
+ label: Record<string, string>;
35
+ intial?: string;
36
+ icon?: string;
37
+ class?: ClassValue;
38
+ min?: number;
39
+ max?: number;
40
+ step?: number;
41
+ }>;
42
+ type Field = TextField | SelectField | NumberField;
9
43
  declare const _default: typeof __VLS_export;
10
44
  export default _default;
45
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
46
+ fields: ReadonlyArray<Field>;
47
+ } & {
48
+ modelValue?: Record<string, unknown>;
49
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
50
+ "update:modelValue": (value: Record<string, unknown>) => any;
51
+ }, string, import("vue").PublicProps, Readonly<{
52
+ fields: ReadonlyArray<Field>;
53
+ } & {
54
+ modelValue?: Record<string, unknown>;
55
+ }> & Readonly<{
56
+ "onUpdate:modelValue"?: ((value: Record<string, unknown>) => any) | undefined;
57
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
58
+ option?: (props: {
59
+ option: Readonly<{
60
+ label: Record<string, string>;
61
+ value: string | number;
62
+ icon?: string;
63
+ }>;
64
+ }) => any;
65
+ }>;
66
+ type __VLS_WithSlots<T, S> = T & {
67
+ new (): {
68
+ $slots: S;
69
+ };
70
+ };
@@ -1,68 +1,129 @@
1
- <script setup>
1
+ <script>
2
2
  import { Icon } from "@iconify/vue";
3
3
  import { Field, FieldLabel } from "./ui/field";
4
- import { InputGroup, InputGroupAddon, InputGroupButton, InputCombobox } from "./ui/input-group";
5
- import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip";
4
+ import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupCombobox, InputGroupNumberField } from "./ui/input-group";
5
+ import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip";
6
6
  import { useI18n } from "vue-i18n";
7
- import { CommandItem, CommandGroup } from "./ui/command";
8
- const { t } = useI18n();
9
- defineProps({
7
+ import { deleteProperty, getProperty, hasProperty, setProperty } from "dot-prop";
8
+ import { CommandGroup, CommandItem } from "./ui/command";
9
+ import { useCheating, useId } from "#imports";
10
+ import { defu } from "defu";
11
+ </script>
12
+
13
+ <script setup>
14
+ const id = useId();
15
+ const props = defineProps({
10
16
  fields: { type: Array, required: true }
11
17
  });
18
+ const { t } = useI18n({
19
+ messages: props.fields.reduce((acc, field, i) => {
20
+ function t2(locales) {
21
+ return Object.fromEntries(Object.entries(locales).map(([locale, message]) => [locale, { [`${id}-${i}`]: message }]));
22
+ }
23
+ return defu(acc, t2(field.label));
24
+ }, {})
25
+ });
26
+ const modelValue = defineModel("modelValue", { type: Object, ...{
27
+ default: () => ({})
28
+ } });
29
+ const isCheating = useCheating();
12
30
  </script>
13
31
 
14
32
  <template>
15
- <div
16
- class="mx-auto"
17
- style="width: 400px;"
18
- >
19
- <Field>
33
+ <div>
34
+ <Field
35
+ v-for="(field, i) in fields"
36
+ :key="field.path"
37
+ :class="field.class"
38
+ >
20
39
  <InputGroup>
21
- <InputCombobox>
22
- <CommandGroup heading="Search">
23
- <CommandItem
24
- value="1"
25
- >
26
- <Icon
27
- icon="fluent:search-20-filled"
28
- />
29
- <span>
30
- Search
31
- </span>
32
- </CommandItem>
40
+ <InputGroupInput
41
+ v-if="field.type === 'string'"
42
+ :treat-empty-as-different-state-from-null="field.treatEmptyAsDifferentStateFromNull"
43
+ :model-value="getProperty(modelValue, field.path)"
44
+ @update:model-value="(value) => {
45
+ if (!value && !field.treatEmptyAsDifferentStateFromNull) {
46
+ deleteProperty(modelValue, field.path);
47
+ } else {
48
+ setProperty(modelValue, field.path, value);
49
+ }
50
+ }"
51
+ />
52
+ <InputGroupCombobox
53
+ v-if="field.type === 'select'"
54
+ >
55
+ <CommandGroup
56
+ v-for="group in field.options"
57
+ :key="group.value"
58
+ >
33
59
  <CommandItem
34
- value="2"
60
+ v-for="option in group.options"
61
+ :key="option.value"
62
+ :value="option.value"
35
63
  >
36
- <Icon
37
- icon="fluent:bookmark-20-filled"
38
- />
39
- <span>
40
- Bookmark
41
- </span>
64
+ <slot
65
+ name="option"
66
+ :option="option"
67
+ >
68
+ <Icon
69
+ v-if="option.icon"
70
+ :icon="option.icon"
71
+ />
72
+ <span>{{ option.label }}</span>
73
+ </slot>
42
74
  </CommandItem>
43
75
  </CommandGroup>
44
- </InputCombobox>
76
+ </InputGroupCombobox>
77
+ <InputGroupNumberField
78
+ v-if="field.type === 'number'"
79
+ :model-value="getProperty(modelValue, field.path) ?? null"
80
+ :min="field.min"
81
+ :max="field.max"
82
+ :step="field.step"
83
+ @update:model-value="(value) => {
84
+ if (!value) {
85
+ deleteProperty(modelValue, field.path);
86
+ } else {
87
+ setProperty(modelValue, field.path, value);
88
+ }
89
+ }"
90
+ />
91
+ <InputGroupAddon v-if="field.icon">
92
+ <Icon
93
+ :icon="field.icon"
94
+ />
95
+ </InputGroupAddon>
45
96
  <InputGroupAddon
97
+ v-if="hasProperty(modelValue, field.path)"
46
98
  align="inline-end"
47
99
  >
48
100
  <Tooltip :delay-duration="800">
49
- <TooltipProvider>
50
- <TooltipTrigger as-child>
51
- <InputGroupButton>
101
+ <TooltipTrigger>
102
+ <InputGroupButton as-child>
103
+ <button
104
+ type="button"
105
+ @click="deleteProperty(modelValue, field.path)"
106
+ >
52
107
  <Icon
53
108
  icon="fluent:dismiss-20-regular"
54
109
  />
55
- </InputGroupButton>
56
- </TooltipTrigger>
57
- <TooltipContent>
58
- {{ t("clear") }}
59
- </TooltipContent>
60
- </TooltipProvider>
110
+ </button>
111
+ </InputGroupButton>
112
+ </TooltipTrigger>
113
+ <TooltipContent>
114
+ {{ t("clear") }}
115
+ </TooltipContent>
61
116
  </Tooltip>
62
117
  </InputGroupAddon>
63
118
  </InputGroup>
64
- <FieldLabel>
65
- Query
119
+ <FieldLabel
120
+ v-if="isCheating"
121
+ class="font-mono"
122
+ >
123
+ {{ field.path }}
124
+ </FieldLabel>
125
+ <FieldLabel v-else>
126
+ {{ t(`${id}-${i}`) }}
66
127
  </FieldLabel>
67
128
  </Field>
68
129
  </div>
@@ -1,10 +1,70 @@
1
- type __VLS_Props = {
2
- fields: ReadonlyArray<{
3
- label: string;
4
- prop: string;
5
- initial?: string;
6
- }>;
7
- };
8
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
1
+ import { Field } from './ui/field/index.js';
2
+ import type { ClassValue } from 'clsx';
3
+ type Option = Readonly<{
4
+ label: Record<string, string>;
5
+ value: string | number;
6
+ icon?: string;
7
+ }>;
8
+ type OptionsGroup = Readonly<{
9
+ label: Record<string, string>;
10
+ value: string | number;
11
+ options: ReadonlyArray<Option>;
12
+ }>;
13
+ type TextField = Readonly<{
14
+ type: 'string';
15
+ path: string;
16
+ label: Record<string, string>;
17
+ intial?: string;
18
+ icon?: string;
19
+ class?: ClassValue;
20
+ treatEmptyAsDifferentStateFromNull?: boolean;
21
+ }>;
22
+ type SelectField = Readonly<{
23
+ type: 'select';
24
+ path: string;
25
+ label: Record<string, string>;
26
+ intial?: string;
27
+ icon?: string;
28
+ options: ReadonlyArray<OptionsGroup>;
29
+ class?: ClassValue;
30
+ }>;
31
+ type NumberField = Readonly<{
32
+ type: 'number';
33
+ path: string;
34
+ label: Record<string, string>;
35
+ intial?: string;
36
+ icon?: string;
37
+ class?: ClassValue;
38
+ min?: number;
39
+ max?: number;
40
+ step?: number;
41
+ }>;
42
+ type Field = TextField | SelectField | NumberField;
9
43
  declare const _default: typeof __VLS_export;
10
44
  export default _default;
45
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
46
+ fields: ReadonlyArray<Field>;
47
+ } & {
48
+ modelValue?: Record<string, unknown>;
49
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
50
+ "update:modelValue": (value: Record<string, unknown>) => any;
51
+ }, string, import("vue").PublicProps, Readonly<{
52
+ fields: ReadonlyArray<Field>;
53
+ } & {
54
+ modelValue?: Record<string, unknown>;
55
+ }> & Readonly<{
56
+ "onUpdate:modelValue"?: ((value: Record<string, unknown>) => any) | undefined;
57
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
58
+ option?: (props: {
59
+ option: Readonly<{
60
+ label: Record<string, string>;
61
+ value: string | number;
62
+ icon?: string;
63
+ }>;
64
+ }) => any;
65
+ }>;
66
+ type __VLS_WithSlots<T, S> = T & {
67
+ new (): {
68
+ $slots: S;
69
+ };
70
+ };
@@ -11,11 +11,11 @@ export type Accessor = string | Readonly<{
11
11
  }>;
12
12
  export type Column = Readonly<{
13
13
  id?: string;
14
- title?: string;
14
+ title?: Record<string, string>;
15
15
  accessor?: Accessor;
16
16
  accessorKey?: string;
17
17
  renderer?: Render;
18
- tooltip?: string;
18
+ tooltip?: Record<string, string>;
19
19
  size?: number;
20
20
  enableSorting?: boolean;
21
21
  enableMultiSorting?: boolean;
@@ -4,12 +4,15 @@ import { useVirtualizer } from "@tanstack/vue-virtual";
4
4
  import { Icon } from "@iconify/vue";
5
5
  import { getProperty } from "dot-prop";
6
6
  import { Pagination } from "reka-ui/namespaced";
7
+ import { useI18n } from "vue-i18n";
7
8
  import { computed, ref } from "vue";
8
9
  import { useNuxtApp } from "#app";
9
10
  import { Button } from "./ui/button";
11
+ import { NumberField, NumberFieldInput } from "./ui/number-field";
10
12
  import { Tooltip, TooltipContent, TooltipTrigger } from "./ui/tooltip";
11
13
  import { useTableRenderers } from "../composables/useTableRenderers";
12
14
  import { useCheating } from "#imports";
15
+ import { defu } from "defu";
13
16
  </script>
14
17
 
15
18
  <script setup>
@@ -26,6 +29,23 @@ const props = defineProps({
26
29
  paginationLeft: { type: String, required: false },
27
30
  paginationRight: { type: String, required: false }
28
31
  });
32
+ const { t } = useI18n({
33
+ messages: props.columns.reduce((acc, column) => {
34
+ function f(column2) {
35
+ return defu(
36
+ acc,
37
+ Object.fromEntries(
38
+ Object.entries(
39
+ column2.title ?? {}
40
+ ).map(([locale, message]) => [locale, { [genColumnId(column2)]: message }])
41
+ ),
42
+ column2.tooltip ? Object.fromEntries(Object.entries(column2.tooltip).map(([locale, message]) => [locale, { [`${genColumnId(column2)}-tooltip`]: message }])) : {},
43
+ ...column2.columns?.map((column3) => f(column3)) ?? []
44
+ );
45
+ }
46
+ return f(column);
47
+ }, {})
48
+ });
29
49
  const slots = defineSlots();
30
50
  const { $dsl } = useNuxtApp();
31
51
  const isCheating = useCheating();
@@ -36,6 +56,8 @@ function genColumnId(column) {
36
56
  return column.accessor;
37
57
  } else if (column.accessor) {
38
58
  return column.accessor.read;
59
+ } else if (column.id) {
60
+ return column.id;
39
61
  }
40
62
  return crypto.randomUUID();
41
63
  }
@@ -43,14 +65,14 @@ function translate(column) {
43
65
  if (Array.isArray(column.columns) && column.columns.length > 0) {
44
66
  return {
45
67
  id: column.id ?? genColumnId(column),
46
- header: column.title,
68
+ header: t(genColumnId(column)),
47
69
  columns: column.columns?.map((column2) => translate(column2)) ?? [],
48
70
  enableSorting: column.enableSorting ?? false,
49
71
  enableMultiSort: column.enableMultiSorting,
50
72
  enablePinning: column.enablePinning,
51
73
  size: column.size,
52
74
  meta: {
53
- tooltip: column.tooltip,
75
+ tooltip: column.tooltip ? `${genColumnId(column)}-tooltip` : void 0,
54
76
  grow: column.grow ?? false
55
77
  }
56
78
  };
@@ -59,7 +81,7 @@ function translate(column) {
59
81
  const options = renderer.parseOptions(column.renderer && typeof column.renderer === "object" && "props" in column.renderer ? column.renderer.props : null);
60
82
  return {
61
83
  id: column.id ?? genColumnId(column),
62
- header: (ctx) => renderer.header?.({ ctx, options }) ?? column.title,
84
+ header: (ctx) => renderer.header?.({ ctx, options }) ?? t(genColumnId(column)),
63
85
  cell: (ctx) => {
64
86
  if (ctx.column.id in slots) {
65
87
  return slots[ctx.column.id]?.({ cell: ctx });
@@ -89,7 +111,7 @@ function translate(column) {
89
111
  size: column.size,
90
112
  columns: column.columns?.map((column2) => translate(column2)) ?? [],
91
113
  meta: {
92
- tooltip: column.tooltip,
114
+ tooltip: column.tooltip ? `${genColumnId(column)}-tooltip` : void 0,
93
115
  grow: column.grow ?? false
94
116
  },
95
117
  ...renderer.columnDefOverrides
@@ -305,19 +327,38 @@ function getSortIcon(column) {
305
327
  align="center"
306
328
  side="top"
307
329
  >
308
- <span v-html="$md.inline`${header.column.columnDef.meta.tooltip}`()" />
330
+ <span v-html="$md.inline`${t(`${header.column.id}-tooltip`)}`()" />
309
331
  </TooltipContent>
310
332
  </Tooltip>
311
333
 
312
- <Button
334
+ <Tooltip
313
335
  v-if="!header.isPlaceholder && header.column.getCanSort()"
314
- variant="ghost"
315
- size="xs"
316
- class="absolute hover:bg-transparent right-1 top-1/2 -translate-y-1/2 transform-3d group-hover:opacity-100 opacity-60 transition-opacity duration-180"
317
- @click="(event) => header.column.getToggleSortingHandler()?.(event)"
336
+ :delay-duration="800"
318
337
  >
319
- <Icon :icon="getSortIcon(header.column)" />
320
- </Button>
338
+ <TooltipTrigger as-child>
339
+ <Button
340
+ variant="ghost"
341
+ size="xs"
342
+ :class="[
343
+ 'absolute hover:bg-transparent right-1 top-1/2 -translate-y-1/2 transform-3d transition-opacity duration-180',
344
+ !header.column.getIsSorted() ? 'opacity-30 hover:opacity-60' : 'text-(--primary)/80 hover:text-(--primary)'
345
+ ]"
346
+ as-child
347
+ >
348
+ <button
349
+ type="button"
350
+ @click="header.column.getToggleSortingHandler()?.($event)"
351
+ >
352
+ <Icon :icon="getSortIcon(header.column)" />
353
+ </button>
354
+ </Button>
355
+ </TooltipTrigger>
356
+ <TooltipContent>
357
+ {{
358
+ header.column.getIsSorted() ? t(`table-sort-${header.column.getIsSorted()}`) : t("table-sort-unsorted")
359
+ }}
360
+ </TooltipContent>
361
+ </Tooltip>
321
362
 
322
363
  <div
323
364
  v-if="!header.isPlaceholder && header.column.getCanResize() && (!header.column.getIsLastColumn('right') || !table.getIsSomeColumnsPinned('right') && !header.column.getIsLastColumn('center'))"
@@ -437,7 +478,15 @@ function getSortIcon(column) {
437
478
  &nbsp;
438
479
  </div>
439
480
  <div class="flex items-center gap-4">
440
- <span class="text-xs">{{ `\u5171 ${props.data.length} \u6761` }}</span>
481
+ <i18n-t
482
+ keypath="total"
483
+ tag="span"
484
+ class="text-xs"
485
+ >
486
+ <template #count>
487
+ <strong>{{ props.data.length }}</strong>
488
+ </template>
489
+ </i18n-t>
441
490
  <Pagination.Root
442
491
  show-edges
443
492
  :total="props.data.length"
@@ -480,7 +529,7 @@ function getSortIcon(column) {
480
529
  v-if="page.type === 'page'"
481
530
  :class="[
482
531
  'w-7 h-7 flex items-center justify-center rounded text-xs bg-transparent',
483
- 'data-selected:text-(--primary) data-selected:border-(--primary) hover:bg-zinc-100 transition cursor-pointer'
532
+ 'data-selected:text-(--primary) hover:bg-zinc-100 transition cursor-pointer'
484
533
  ]"
485
534
  :value="page.value"
486
535
  >
@@ -518,7 +567,22 @@ function getSortIcon(column) {
518
567
  </Pagination.Last>
519
568
  </Pagination.List>
520
569
  </Pagination.Root>
521
- <span class="text-xs">前往</span>
570
+ <i18n-t
571
+ keypath="goto"
572
+ tag="div"
573
+ class="text-xs flex items-center gap-2"
574
+ >
575
+ <template #page>
576
+ <NumberField
577
+ :model-value="table.getState().pagination.pageIndex + 1"
578
+ :min="1"
579
+ :max="Math.ceil(props.data.length / table.getState().pagination.pageSize)"
580
+ @update:model-value="(value) => table.setPageIndex(value - 1)"
581
+ >
582
+ <NumberFieldInput class="h-6 w-16 text-xs" />
583
+ </NumberField>
584
+ </template>
585
+ </i18n-t>
522
586
  </div>
523
587
  <div
524
588
  :class="[
@@ -541,3 +605,29 @@ function getSortIcon(column) {
541
605
  </div>
542
606
  </div>
543
607
  </template>
608
+
609
+ <i18n lang="json">
610
+ {
611
+ "zh": {
612
+ "total": "共 {count} 条",
613
+ "goto": "前往 {page} 页",
614
+ "table-sort-asc": "升序",
615
+ "table-sort-desc": "降序",
616
+ "table-sort-unsorted": "未排序"
617
+ },
618
+ "ja": {
619
+ "total": "合計 {count} 件",
620
+ "goto": "ページ {page} に移動",
621
+ "table-sort-asc": "昇順",
622
+ "table-sort-desc": "降順",
623
+ "table-sort-unsorted": "未排序"
624
+ },
625
+ "en": {
626
+ "total": "Total {count} items",
627
+ "goto": "Go to page {page}",
628
+ "table-sort-asc": "Ascending",
629
+ "table-sort-desc": "Descending",
630
+ "table-sort-unsorted": "Unsorted"
631
+ }
632
+ }
633
+ </i18n>
@@ -11,11 +11,11 @@ export type Accessor = string | Readonly<{
11
11
  }>;
12
12
  export type Column = Readonly<{
13
13
  id?: string;
14
- title?: string;
14
+ title?: Record<string, string>;
15
15
  accessor?: Accessor;
16
16
  accessorKey?: string;
17
17
  renderer?: Render;
18
- tooltip?: string;
18
+ tooltip?: Record<string, string>;
19
19
  size?: number;
20
20
  enableSorting?: boolean;
21
21
  enableMultiSorting?: boolean;
@@ -17,7 +17,7 @@ export const fieldVariants = cva(
17
17
  ],
18
18
  floating: [
19
19
  "relative *:data-[slot=field-label]:absolute *:data-[slot=field-label]:text-zinc-500",
20
- "*:data-[slot=field-label]:top-1/2 *:data-[slot=field-label]:-translate-1/2 *:data-[slot=field-label]:transition-all *:data-[slot=field-label]:duration-180",
20
+ "*:data-[slot=field-label]:top-1/2 *:data-[slot=field-label]:-translate-y-1/2 *:data-[slot=field-label]:transition-all *:data-[slot=field-label]:duration-180",
21
21
  "*:data-[slot=field-label]:pointer-events-none *:data-[slot=field-label]:select-none *:data-[slot=field-label]:cursor-text",
22
22
  "has-data-[value=true]:**:data-[slot=field-label]:top-0",
23
23
  "**:data-[slot=field-label]:bg-white",
@@ -30,8 +30,8 @@ export const fieldVariants = cva(
30
30
  "has-[[data-slot=input-group-control]:focus]:**:data-[slot=field-label]:text-zinc-700",
31
31
  "has-data-[state=open]:**:data-[slot=field-label]:text-zinc-700",
32
32
  "has-data-[value=true]:**:data-[slot=field-label]:text-zinc-700",
33
- "*:data-[slot=field-label]:left-7",
34
- "has-[[data-slot=input-group-addon][data-align=inline-start]]:**:data-[slot=field-label]:left-14"
33
+ "*:data-[slot=field-label]:left-3",
34
+ "has-[[data-slot=input-group-addon][data-align=inline-start]]:**:data-[slot=field-label]:left-7"
35
35
  ]
36
36
  }
37
37
  },
@@ -3,6 +3,7 @@ type __VLS_Props = {
3
3
  defaultValue?: string | number;
4
4
  modelValue?: string | number;
5
5
  class?: HTMLAttributes['class'];
6
+ treatEmptyAsDifferentStateFromNull?: boolean;
6
7
  };
7
8
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
8
9
  "update:modelValue": (payload: string | number) => any;