@shwfed/nuxt 0.7.11 → 0.8.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.
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shwfed/nuxt",
3
3
  "configKey": "shwfed",
4
- "version": "0.7.11",
4
+ "version": "0.8.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { execSync } from 'node:child_process';
2
- import { defineNuxtModule, createResolver, addVitePlugin, addPlugin, addImportsDir, addComponentsDir, addRouteMiddleware } from '@nuxt/kit';
2
+ import { defineNuxtModule, createResolver, addVitePlugin, addPlugin, addImportsDir, addComponentsDir, addRouteMiddleware, addLayout } from '@nuxt/kit';
3
3
  import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite';
4
4
  import TailwindCSS from '@tailwindcss/vite';
5
5
  import defu from 'defu';
@@ -75,6 +75,7 @@ const module$1 = defineNuxtModule({
75
75
  name: "token",
76
76
  global: true
77
77
  });
78
+ addLayout(resolver.resolve("runtime/layouts/default.vue"), "default");
78
79
  },
79
80
  hooks: {
80
81
  "build:error": (error) => {
@@ -1,7 +1,7 @@
1
1
  <script>
2
2
  import { Icon } from "@iconify/vue";
3
3
  import { useNuxtApp } from "#app";
4
- import { ref, toRaw, useId, watchEffect } from "vue";
4
+ import { ref, toRaw, useId, watch, watchEffect } from "vue";
5
5
  import { Field, FieldContent, FieldError, FieldLabel } from "../field";
6
6
  import { Button } from "../button";
7
7
  import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupCombobox, InputGroupInput, InputGroupNumberField } from "../input-group";
@@ -16,7 +16,7 @@ import { Skeleton } from "../skeleton";
16
16
  import z from "zod";
17
17
  import { Effect } from "effect";
18
18
  import { computedAsync } from "@vueuse/core";
19
- import { localeC, dotPropC, expressionC } from "../../../utils/coders";
19
+ import { getLocalizedText, localeC, dotPropC, expressionC } from "../../../utils/coders";
20
20
  import { CalendarDate, getLocalTimeZone } from "@internationalized/date";
21
21
  import { format, parse } from "date-fns";
22
22
  import { TZDate } from "@date-fns/tz";
@@ -102,6 +102,7 @@ const modelValue = defineModel("modelValue", { type: Object, ...{
102
102
  } });
103
103
  const isCheating = useCheating();
104
104
  const isConfiguratorOpen = ref(false);
105
+ const displayFields = ref([]);
105
106
  const validationErrors = ref({});
106
107
  const calendarOpen = ref({});
107
108
  function toCalendarDateValue(value, valueFormat) {
@@ -159,6 +160,9 @@ function validateField(field) {
159
160
  function isFieldInvalid(field) {
160
161
  return validationErrors.value[field.path] !== void 0;
161
162
  }
163
+ function getFieldLabel(field) {
164
+ return getLocalizedText(field.title, locale.value) ?? field.path;
165
+ }
162
166
  function renderValidationMessage(field) {
163
167
  const error = validationErrors.value[field.path];
164
168
  if (!error) return "";
@@ -180,11 +184,15 @@ function handleCalendarBlur(field) {
180
184
  }, 0);
181
185
  }
182
186
  function handleConfiguratorConfirm(nextFields) {
187
+ displayFields.value = nextFields.slice();
183
188
  emit("update:fields", nextFields);
184
189
  }
190
+ watch(fields, (value) => {
191
+ displayFields.value = (value ?? []).slice();
192
+ }, { immediate: true });
185
193
  watchEffect(() => {
186
194
  const activePaths = /* @__PURE__ */ new Set();
187
- for (const field of fields.value ?? []) {
195
+ for (const field of displayFields.value) {
188
196
  if (!isFieldHidden(field) && !isFieldDisabled(field)) {
189
197
  activePaths.add(field.path);
190
198
  }
@@ -224,7 +232,7 @@ watchEffect(() => {
224
232
  <FieldsConfiguratorDialog
225
233
  v-if="fields"
226
234
  v-model:open="isConfiguratorOpen"
227
- :fields="fields"
235
+ :fields="displayFields"
228
236
  @confirm="handleConfiguratorConfirm"
229
237
  />
230
238
 
@@ -234,7 +242,7 @@ watchEffect(() => {
234
242
  />
235
243
 
236
244
  <template
237
- v-for="field in fields"
245
+ v-for="field in displayFields"
238
246
  :key="field.path"
239
247
  >
240
248
  <Field
@@ -245,7 +253,7 @@ watchEffect(() => {
245
253
  :style="field.style ? $dsl.evaluate`${field.style}`() : {}"
246
254
  >
247
255
  <FieldLabel :for="['string', 'number'].includes(field.type) ? `${id}:${field.path}` : void 0">
248
- {{ field.title.find((r) => r.locale === locale)?.message ?? field.title[0]?.message }}
256
+ {{ getFieldLabel(field) }}
249
257
  <span v-if="isCheating">
250
258
  <span class="font-mono">{{ field.path }}</span>
251
259
  </span>
@@ -4,6 +4,7 @@ import { Icon } from "@iconify/vue";
4
4
  import { computed, nextTick, ref, watch } from "vue";
5
5
  import { useI18n } from "vue-i18n";
6
6
  import { cn } from "../../../utils/cn";
7
+ import { getLocalizedText } from "../../../utils/coders";
7
8
  import { Button } from "../button";
8
9
  import {
9
10
  Dialog,
@@ -13,6 +14,7 @@ import {
13
14
  DialogHeader,
14
15
  DialogTitle
15
16
  } from "../dialog";
17
+ import Locale from "../locale/Locale.vue";
16
18
  const props = defineProps({
17
19
  fields: { type: Array, required: true }
18
20
  });
@@ -30,8 +32,7 @@ const generalItem = computed(() => ({
30
32
  label: t("general")
31
33
  }));
32
34
  function getFieldLabel(field) {
33
- const localizedTitle = field.title.find((item) => item.locale === locale.value && item.message.trim().length > 0);
34
- return localizedTitle?.message ?? field.path;
35
+ return getLocalizedText(field.title, locale.value) ?? field.path;
35
36
  }
36
37
  const fieldItems = computed(() => draftFields.value.map((field) => ({
37
38
  itemId: field.path,
@@ -144,6 +145,12 @@ function deleteField(itemId) {
144
145
  const nextField = nextFields[deleteIndex] ?? nextFields[deleteIndex - 1];
145
146
  selectedItemId.value = nextField?.path ?? "general";
146
147
  }
148
+ function updateSelectedFieldTitle(value) {
149
+ if (!selectedField.value) {
150
+ return;
151
+ }
152
+ draftFields.value = draftFields.value.map((field) => field.path === selectedField.value?.path ? { ...field, title: value } : field);
153
+ }
147
154
  function confirmChanges() {
148
155
  emit("confirm", draftFields.value.slice());
149
156
  open.value = false;
@@ -230,12 +237,6 @@ function confirmChanges() {
230
237
  >
231
238
  {{ item.label }}
232
239
  </span>
233
- <span
234
- data-slot="fields-configurator-field-path"
235
- class="block truncate text-xs text-zinc-400"
236
- >
237
- {{ item.path }}
238
- </span>
239
240
  </button>
240
241
 
241
242
  <button
@@ -286,10 +287,23 @@ function confirmChanges() {
286
287
 
287
288
  <div
288
289
  v-else-if="selectedField"
289
- data-slot="fields-configurator-field-placeholder"
290
- class="mt-6 flex min-h-48 items-center justify-center rounded-lg border border-dashed border-zinc-200 bg-zinc-50/60 px-6 text-center text-sm text-zinc-400"
290
+ data-slot="fields-configurator-field-main"
291
+ class="mt-6 flex flex-col gap-6"
291
292
  >
292
- {{ t("field-placeholder", { field: selectedItemLabel }) }}
293
+ <section
294
+ data-slot="fields-configurator-field-label-section"
295
+ class="flex flex-col gap-2"
296
+ >
297
+ <p class="text-xs font-medium text-zinc-500">
298
+ {{ t("field-label") }}
299
+ </p>
300
+
301
+ <Locale
302
+ data-slot="fields-configurator-field-title-locale"
303
+ :model-value="selectedField.title"
304
+ @update:model-value="updateSelectedFieldTitle"
305
+ />
306
+ </section>
293
307
  </div>
294
308
  </section>
295
309
  </div>
@@ -326,7 +340,7 @@ function confirmChanges() {
326
340
  "general": "通用",
327
341
  "general-placeholder": "这里会放置字段集合的通用配置。",
328
342
  "general-empty": "通用配置区域预留中。",
329
- "field-placeholder": "字段“{field}”的配置区域预留中。",
343
+ "field-label": "Label",
330
344
  "no-fields": "还没有字段。",
331
345
  "drag-field": "拖拽调整字段顺序:{field}",
332
346
  "delete-field": "删除字段:{field}",
@@ -339,7 +353,7 @@ function confirmChanges() {
339
353
  "general": "共通",
340
354
  "general-placeholder": "ここにはフィールド群の共通設定を配置します。",
341
355
  "general-empty": "共通設定エリアはまだ準備中です。",
342
- "field-placeholder": "フィールド「{field}」の設定エリアはまだ準備中です。",
356
+ "field-label": "Label",
343
357
  "no-fields": "フィールドがありません。",
344
358
  "drag-field": "{field} の順序をドラッグで変更",
345
359
  "delete-field": "{field} を削除",
@@ -352,7 +366,7 @@ function confirmChanges() {
352
366
  "general": "General",
353
367
  "general-placeholder": "Shared settings for this field group will live here.",
354
368
  "general-empty": "The shared settings area is reserved for now.",
355
- "field-placeholder": "The configuration area for \"{field}\" is reserved for now.",
369
+ "field-label": "Label",
356
370
  "no-fields": "No fields yet.",
357
371
  "drag-field": "Drag to reorder field {field}",
358
372
  "delete-field": "Delete field {field}",
@@ -58,6 +58,7 @@ const GENERATED_COLUMN_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab]
58
58
  const TableConfiguratorColumnAccessorReadC = expressionC(/.+/, { row: "dyn", index: "int" });
59
59
  const TableConfiguratorColumnAccessorWriteC = z.string().trim().refine((value) => value.length > 0, { error: "\u5199\u5165\u8868\u8FBE\u5F0F\u4E0D\u80FD\u4E3A\u7A7A" });
60
60
  const TOOLTIP_EXPRESSION_EXAMPLE = "{{ expression }}";
61
+ const TABLE_CONFIGURATOR_INITIAL_STATE_SORTABLE_GROUP = "table-configurator-initial-state";
61
62
  const props = defineProps({
62
63
  config: { type: Object, required: true }
63
64
  });
@@ -497,6 +498,9 @@ function reorderItemIds(itemIds, oldIndex, newIndex) {
497
498
  nextItemIds.splice(newIndex, 0, movedItemId);
498
499
  return nextItemIds;
499
500
  }
501
+ function clampInsertionIndex(index, itemCount) {
502
+ return Math.min(Math.max(index, 0), itemCount);
503
+ }
500
504
  function areItemIdsEqual(left, right) {
501
505
  if (left.length !== right.length) {
502
506
  return false;
@@ -642,17 +646,87 @@ function normalizeInitialStateGroups() {
642
646
  centerRootItemIds.value = centerItemIds;
643
647
  rightPinnedRootItemIds.value = rightItemIds;
644
648
  }
649
+ function resolveInitialStateGroupByElement(element) {
650
+ if (!element) {
651
+ return void 0;
652
+ }
653
+ if (element === leftPinnedSortableListRef.value) {
654
+ return "left";
655
+ }
656
+ if (element === centerSortableListRef.value) {
657
+ return "center";
658
+ }
659
+ if (element === rightPinnedSortableListRef.value) {
660
+ return "right";
661
+ }
662
+ return void 0;
663
+ }
664
+ function getInitialStateGroupItemIds(group) {
665
+ if (group === "left") {
666
+ return leftPinnedRootItemIds.value.slice();
667
+ }
668
+ if (group === "center") {
669
+ return centerRootItemIds.value.slice();
670
+ }
671
+ return rightPinnedRootItemIds.value.slice();
672
+ }
673
+ function setInitialStateGroupItemIds(group, itemIds) {
674
+ if (group === "left") {
675
+ leftPinnedRootItemIds.value = itemIds;
676
+ return;
677
+ }
678
+ if (group === "center") {
679
+ centerRootItemIds.value = itemIds;
680
+ return;
681
+ }
682
+ rightPinnedRootItemIds.value = itemIds;
683
+ }
684
+ function reorderInitialStateGroup(group, oldIndex, newIndex) {
685
+ setInitialStateGroupItemIds(
686
+ group,
687
+ reorderItemIds(getInitialStateGroupItemIds(group), oldIndex, newIndex)
688
+ );
689
+ }
690
+ function canMoveInitialStateItemToGroup(itemId, group) {
691
+ if (group === "center") {
692
+ return true;
693
+ }
694
+ return rootInitialStateItems.value.some((item) => item.itemId === itemId && item.canManage);
695
+ }
696
+ function moveInitialStateItemBetweenGroups(fromGroup, toGroup, oldIndex, newIndex) {
697
+ if (fromGroup === toGroup) {
698
+ reorderInitialStateGroup(toGroup, oldIndex, newIndex);
699
+ return;
700
+ }
701
+ const sourceItemIds = getInitialStateGroupItemIds(fromGroup);
702
+ const targetItemIds = getInitialStateGroupItemIds(toGroup);
703
+ const movedItemId = sourceItemIds[oldIndex];
704
+ if (!movedItemId || !canMoveInitialStateItemToGroup(movedItemId, toGroup)) {
705
+ return;
706
+ }
707
+ const nextSourceItemIds = sourceItemIds.filter((_, index) => index !== oldIndex);
708
+ const nextTargetItemIds = targetItemIds.slice();
709
+ nextTargetItemIds.splice(clampInsertionIndex(newIndex, nextTargetItemIds.length), 0, movedItemId);
710
+ setInitialStateGroupItemIds(fromGroup, nextSourceItemIds);
711
+ setInitialStateGroupItemIds(toGroup, nextTargetItemIds);
712
+ }
713
+ function handleInitialStateSortableAdd(event) {
714
+ const oldIndex = event.oldIndex;
715
+ const newIndex = event.newIndex;
716
+ const fromGroup = resolveInitialStateGroupByElement(event.from);
717
+ const toGroup = resolveInitialStateGroupByElement(event.to);
718
+ if (selectedItemId.value !== "general" || oldIndex === void 0 || newIndex === void 0 || !fromGroup || !toGroup) {
719
+ return;
720
+ }
721
+ moveInitialStateItemBetweenGroups(fromGroup, toGroup, oldIndex, newIndex);
722
+ }
645
723
  function handleLeftPinnedSortableUpdate(event) {
646
724
  const oldIndex = event.oldIndex;
647
725
  const newIndex = event.newIndex;
648
726
  if (selectedItemId.value !== "general" || oldIndex === void 0 || newIndex === void 0 || oldIndex === newIndex) {
649
727
  return;
650
728
  }
651
- leftPinnedRootItemIds.value = reorderItemIds(
652
- leftPinnedRootItemIds.value,
653
- oldIndex,
654
- newIndex
655
- );
729
+ reorderInitialStateGroup("left", oldIndex, newIndex);
656
730
  }
657
731
  function handleCenterSortableUpdate(event) {
658
732
  const oldIndex = event.oldIndex;
@@ -660,11 +734,7 @@ function handleCenterSortableUpdate(event) {
660
734
  if (selectedItemId.value !== "general" || oldIndex === void 0 || newIndex === void 0 || oldIndex === newIndex) {
661
735
  return;
662
736
  }
663
- centerRootItemIds.value = reorderItemIds(
664
- centerRootItemIds.value,
665
- oldIndex,
666
- newIndex
667
- );
737
+ reorderInitialStateGroup("center", oldIndex, newIndex);
668
738
  }
669
739
  function handleRightPinnedSortableUpdate(event) {
670
740
  const oldIndex = event.oldIndex;
@@ -672,11 +742,7 @@ function handleRightPinnedSortableUpdate(event) {
672
742
  if (selectedItemId.value !== "general" || oldIndex === void 0 || newIndex === void 0 || oldIndex === newIndex) {
673
743
  return;
674
744
  }
675
- rightPinnedRootItemIds.value = reorderItemIds(
676
- rightPinnedRootItemIds.value,
677
- oldIndex,
678
- newIndex
679
- );
745
+ reorderInitialStateGroup("right", oldIndex, newIndex);
680
746
  }
681
747
  function handlePaginationPageSizesSortableUpdate(event) {
682
748
  const oldIndex = event.oldIndex;
@@ -711,18 +777,21 @@ function handleChildSortableUpdate(event) {
711
777
  }
712
778
  function configureLeftPinnedSortable() {
713
779
  leftPinnedSortable.option("animation", 150);
714
- leftPinnedSortable.option("handle", '[data-slot="table-configurator-initial-state-left-drag-handle"]');
780
+ leftPinnedSortable.option("group", TABLE_CONFIGURATOR_INITIAL_STATE_SORTABLE_GROUP);
715
781
  leftPinnedSortable.option("onUpdate", handleLeftPinnedSortableUpdate);
782
+ leftPinnedSortable.option("onAdd", handleInitialStateSortableAdd);
716
783
  }
717
784
  function configureCenterSortable() {
718
785
  centerSortable.option("animation", 150);
719
- centerSortable.option("handle", '[data-slot="table-configurator-initial-state-center-drag-handle"]');
786
+ centerSortable.option("group", TABLE_CONFIGURATOR_INITIAL_STATE_SORTABLE_GROUP);
720
787
  centerSortable.option("onUpdate", handleCenterSortableUpdate);
788
+ centerSortable.option("onAdd", handleInitialStateSortableAdd);
721
789
  }
722
790
  function configureRightPinnedSortable() {
723
791
  rightPinnedSortable.option("animation", 150);
724
- rightPinnedSortable.option("handle", '[data-slot="table-configurator-initial-state-right-drag-handle"]');
792
+ rightPinnedSortable.option("group", TABLE_CONFIGURATOR_INITIAL_STATE_SORTABLE_GROUP);
725
793
  rightPinnedSortable.option("onUpdate", handleRightPinnedSortableUpdate);
794
+ rightPinnedSortable.option("onAdd", handleInitialStateSortableAdd);
726
795
  }
727
796
  function configurePaginationPageSizesSortable() {
728
797
  paginationPageSizesSortable.option("animation", 150);
@@ -857,21 +926,6 @@ function selectGeneral() {
857
926
  function selectItem(itemId) {
858
927
  selectedItemId.value = itemId;
859
928
  }
860
- function moveRootItemToGroup(itemId, group) {
861
- const nextLeftItemIds = leftPinnedRootItemIds.value.filter((currentItemId) => currentItemId !== itemId);
862
- const nextCenterItemIds = centerRootItemIds.value.filter((currentItemId) => currentItemId !== itemId);
863
- const nextRightItemIds = rightPinnedRootItemIds.value.filter((currentItemId) => currentItemId !== itemId);
864
- if (group === "left") {
865
- nextLeftItemIds.push(itemId);
866
- } else if (group === "center") {
867
- nextCenterItemIds.push(itemId);
868
- } else {
869
- nextRightItemIds.push(itemId);
870
- }
871
- leftPinnedRootItemIds.value = nextLeftItemIds;
872
- centerRootItemIds.value = nextCenterItemIds;
873
- rightPinnedRootItemIds.value = nextRightItemIds;
874
- }
875
929
  function addColumn() {
876
930
  const nextNode = createTableConfiguratorDraftColumnNode({
877
931
  id: crypto.randomUUID()
@@ -1748,13 +1802,13 @@ function confirmChanges() {
1748
1802
 
1749
1803
  <section
1750
1804
  data-slot="table-configurator-pagination"
1751
- class="rounded-lg border border-zinc-200 p-4"
1805
+ class="border-t border-zinc-200 pt-4"
1752
1806
  >
1753
1807
  <h4 class="text-sm font-semibold text-zinc-800">
1754
1808
  {{ t("pagination") }}
1755
1809
  </h4>
1756
1810
 
1757
- <div class="mt-3 flex flex-col gap-4">
1811
+ <div class="mt-4 flex flex-col gap-4">
1758
1812
  <label
1759
1813
  data-field-key="paginationLeft"
1760
1814
  class="flex flex-col gap-1"
@@ -1874,181 +1928,134 @@ function confirmChanges() {
1874
1928
 
1875
1929
  <section
1876
1930
  data-slot="table-configurator-initial-state"
1877
- class="rounded-lg border border-zinc-200 p-4"
1931
+ class="border-t border-zinc-200 pt-4"
1878
1932
  >
1879
1933
  <h4 class="text-sm font-semibold text-zinc-800">
1880
1934
  {{ t("initial-state") }}
1881
1935
  </h4>
1882
1936
 
1883
- <div class="mt-3 flex flex-col gap-4">
1937
+ <div class="mt-4 grid gap-3 xl:grid-cols-3">
1884
1938
  <section
1885
1939
  data-slot="table-configurator-initial-state-left"
1886
- class="rounded-md border border-zinc-200/80 p-3"
1940
+ class="flex flex-col gap-3 rounded-md bg-zinc-50/80 px-4 py-3"
1887
1941
  >
1888
1942
  <p class="text-xs font-medium text-zinc-500">
1889
1943
  {{ t("pinned-left-group") }}
1890
1944
  </p>
1891
1945
 
1892
1946
  <div
1893
- v-if="leftPinnedInitialStateItems.length > 0"
1894
1947
  ref="leftPinnedSortableListRef"
1895
- class="mt-3 flex flex-col gap-1"
1948
+ data-slot="table-configurator-initial-state-left-list"
1949
+ class="mt-3 flex min-h-14 flex-col gap-1 rounded-md border border-dashed border-zinc-200/80 p-1"
1896
1950
  >
1897
1951
  <div
1898
1952
  v-for="item in leftPinnedInitialStateItems"
1899
1953
  :key="item.itemId"
1900
1954
  data-slot="table-configurator-initial-state-left-item"
1901
- class="flex items-center gap-2 rounded-md border border-transparent p-1"
1955
+ class="flex cursor-grab items-center gap-2 rounded-md border border-transparent p-1 text-left active:cursor-grabbing"
1956
+ :title="t('drag-initial-state-column', { column: item.label })"
1902
1957
  >
1903
- <button
1904
- type="button"
1958
+ <div
1905
1959
  data-slot="table-configurator-initial-state-left-drag-handle"
1906
- class="flex size-8 shrink-0 cursor-grab items-center justify-center rounded-sm text-zinc-400 active:cursor-grabbing"
1907
- :aria-label="t('drag-left-column', { column: item.label })"
1960
+ class="flex size-8 shrink-0 items-center justify-center rounded-sm text-zinc-400"
1961
+ aria-hidden="true"
1908
1962
  >
1909
1963
  <Icon icon="fluent:re-order-dots-vertical-20-regular" />
1910
- </button>
1964
+ </div>
1911
1965
 
1912
1966
  <span class="min-w-0 flex-1 truncate px-1 text-sm font-medium text-zinc-800">{{ item.label }}</span>
1913
-
1914
- <button
1915
- v-if="item.canManage"
1916
- type="button"
1917
- data-slot="table-configurator-unpin-from-left"
1918
- class="flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-sm text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700"
1919
- :aria-label="t('unpin-left-column', { column: item.label })"
1920
- @click="moveRootItemToGroup(item.itemId, 'center')"
1921
- >
1922
- <Icon icon="fluent:padding-right-20-regular" />
1923
- </button>
1924
1967
  </div>
1925
- </div>
1926
1968
 
1927
- <p
1928
- v-else
1929
- data-slot="table-configurator-initial-state-left-empty"
1930
- class="mt-3 text-xs text-zinc-400"
1931
- >
1932
- {{ t("no-pinned-left-columns") }}
1933
- </p>
1969
+ <p
1970
+ v-if="leftPinnedInitialStateItems.length === 0"
1971
+ data-slot="table-configurator-initial-state-left-empty"
1972
+ class="p-2 text-xs text-zinc-400"
1973
+ >
1974
+ {{ t("no-pinned-left-columns") }}
1975
+ </p>
1976
+ </div>
1934
1977
  </section>
1935
1978
 
1936
1979
  <section
1937
1980
  data-slot="table-configurator-initial-state-center"
1938
- class="rounded-md border border-zinc-200/80 p-3"
1981
+ class="flex flex-col gap-3 rounded-md bg-zinc-50/80 px-4 py-3"
1939
1982
  >
1940
1983
  <p class="text-xs font-medium text-zinc-500">
1941
1984
  {{ t("pinned-center-group") }}
1942
1985
  </p>
1943
1986
 
1944
1987
  <div
1945
- v-if="centerInitialStateItems.length > 0"
1946
1988
  ref="centerSortableListRef"
1947
- class="mt-3 flex flex-col gap-1"
1989
+ data-slot="table-configurator-initial-state-center-list"
1990
+ class="mt-3 flex min-h-14 flex-col gap-1 rounded-md border border-dashed border-zinc-200/80 p-1"
1948
1991
  >
1949
1992
  <div
1950
1993
  v-for="item in centerInitialStateItems"
1951
1994
  :key="item.itemId"
1952
1995
  data-slot="table-configurator-initial-state-center-item"
1953
- class="flex items-center gap-2 rounded-md border border-transparent p-1"
1996
+ class="flex cursor-grab items-center gap-2 rounded-md border border-transparent p-1 text-left active:cursor-grabbing"
1997
+ :title="t('drag-initial-state-column', { column: item.label })"
1954
1998
  >
1955
- <button
1956
- type="button"
1999
+ <div
1957
2000
  data-slot="table-configurator-initial-state-center-drag-handle"
1958
- class="flex size-8 shrink-0 cursor-grab items-center justify-center rounded-sm text-zinc-400 active:cursor-grabbing"
1959
- :aria-label="t('drag-center-column', { column: item.label })"
2001
+ class="flex size-8 shrink-0 items-center justify-center rounded-sm text-zinc-400"
2002
+ aria-hidden="true"
1960
2003
  >
1961
2004
  <Icon icon="fluent:re-order-dots-vertical-20-regular" />
1962
- </button>
2005
+ </div>
1963
2006
 
1964
2007
  <span class="min-w-0 flex-1 truncate px-1 text-sm font-medium text-zinc-800">{{ item.label }}</span>
1965
-
1966
- <div
1967
- v-if="item.canManage"
1968
- class="flex items-center gap-1"
1969
- >
1970
- <button
1971
- type="button"
1972
- data-slot="table-configurator-pin-left"
1973
- class="flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-sm text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700"
1974
- :aria-label="t('pin-left-column', { column: item.label })"
1975
- @click="moveRootItemToGroup(item.itemId, 'left')"
1976
- >
1977
- <Icon icon="fluent:padding-left-20-regular" />
1978
- </button>
1979
-
1980
- <button
1981
- type="button"
1982
- data-slot="table-configurator-pin-right"
1983
- class="flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-sm text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700"
1984
- :aria-label="t('pin-right-column', { column: item.label })"
1985
- @click="moveRootItemToGroup(item.itemId, 'right')"
1986
- >
1987
- <Icon icon="fluent:padding-right-20-regular" />
1988
- </button>
1989
- </div>
1990
2008
  </div>
1991
- </div>
1992
2009
 
1993
- <p
1994
- v-else
1995
- data-slot="table-configurator-initial-state-center-empty"
1996
- class="mt-3 text-xs text-zinc-400"
1997
- >
1998
- {{ t("no-pinned-center-columns") }}
1999
- </p>
2010
+ <p
2011
+ v-if="centerInitialStateItems.length === 0"
2012
+ data-slot="table-configurator-initial-state-center-empty"
2013
+ class="p-2 text-xs text-zinc-400"
2014
+ >
2015
+ {{ t("no-pinned-center-columns") }}
2016
+ </p>
2017
+ </div>
2000
2018
  </section>
2001
2019
 
2002
2020
  <section
2003
2021
  data-slot="table-configurator-initial-state-right"
2004
- class="rounded-md border border-zinc-200/80 p-3"
2022
+ class="flex flex-col gap-3 rounded-md bg-zinc-50/80 px-4 py-3"
2005
2023
  >
2006
2024
  <p class="text-xs font-medium text-zinc-500">
2007
2025
  {{ t("pinned-right-group") }}
2008
2026
  </p>
2009
2027
 
2010
2028
  <div
2011
- v-if="rightPinnedInitialStateItems.length > 0"
2012
2029
  ref="rightPinnedSortableListRef"
2013
- class="mt-3 flex flex-col gap-1"
2030
+ data-slot="table-configurator-initial-state-right-list"
2031
+ class="mt-3 flex min-h-14 flex-col gap-1 rounded-md border border-dashed border-zinc-200/80 p-1"
2014
2032
  >
2015
2033
  <div
2016
2034
  v-for="item in rightPinnedInitialStateItems"
2017
2035
  :key="item.itemId"
2018
2036
  data-slot="table-configurator-initial-state-right-item"
2019
- class="flex items-center gap-2 rounded-md border border-transparent p-1"
2037
+ class="flex cursor-grab items-center gap-2 rounded-md border border-transparent p-1 text-left active:cursor-grabbing"
2038
+ :title="t('drag-initial-state-column', { column: item.label })"
2020
2039
  >
2021
- <button
2022
- type="button"
2040
+ <div
2023
2041
  data-slot="table-configurator-initial-state-right-drag-handle"
2024
- class="flex size-8 shrink-0 cursor-grab items-center justify-center rounded-sm text-zinc-400 active:cursor-grabbing"
2025
- :aria-label="t('drag-right-column', { column: item.label })"
2042
+ class="flex size-8 shrink-0 items-center justify-center rounded-sm text-zinc-400"
2043
+ aria-hidden="true"
2026
2044
  >
2027
2045
  <Icon icon="fluent:re-order-dots-vertical-20-regular" />
2028
- </button>
2046
+ </div>
2029
2047
 
2030
2048
  <span class="min-w-0 flex-1 truncate px-1 text-sm font-medium text-zinc-800">{{ item.label }}</span>
2031
-
2032
- <button
2033
- v-if="item.canManage"
2034
- type="button"
2035
- data-slot="table-configurator-unpin-from-right"
2036
- class="flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-sm text-zinc-400 transition-colors hover:bg-zinc-100 hover:text-zinc-700"
2037
- :aria-label="t('unpin-right-column', { column: item.label })"
2038
- @click="moveRootItemToGroup(item.itemId, 'center')"
2039
- >
2040
- <Icon icon="fluent:padding-left-20-regular" />
2041
- </button>
2042
2049
  </div>
2043
- </div>
2044
2050
 
2045
- <p
2046
- v-else
2047
- data-slot="table-configurator-initial-state-right-empty"
2048
- class="mt-3 text-xs text-zinc-400"
2049
- >
2050
- {{ t("no-pinned-right-columns") }}
2051
- </p>
2051
+ <p
2052
+ v-if="rightPinnedInitialStateItems.length === 0"
2053
+ data-slot="table-configurator-initial-state-right-empty"
2054
+ class="p-2 text-xs text-zinc-400"
2055
+ >
2056
+ {{ t("no-pinned-right-columns") }}
2057
+ </p>
2058
+ </div>
2052
2059
  </section>
2053
2060
  </div>
2054
2061
  </section>
@@ -2503,13 +2510,7 @@ function confirmChanges() {
2503
2510
  "no-selected-children": "当前列还没有子列。",
2504
2511
  "no-available-columns": "没有可添加的列。",
2505
2512
  "add-column": "新增列",
2506
- "drag-left-column": "拖拽调整左侧组顺序:{column}",
2507
- "drag-center-column": "拖拽调整中间组顺序:{column}",
2508
- "drag-right-column": "拖拽调整右侧组顺序:{column}",
2509
- "pin-left-column": "固定到左侧组:{column}",
2510
- "pin-right-column": "固定到右侧组:{column}",
2511
- "unpin-left-column": "从左侧组释放到中间组:{column}",
2512
- "unpin-right-column": "从右侧组释放到中间组:{column}",
2513
+ "drag-initial-state-column": "拖拽调整列分组和顺序:{column}",
2513
2514
  "drag-child-column": "拖拽调整子列顺序:{column}",
2514
2515
  "delete-column": "删除列:{column}",
2515
2516
  "remove-child-column": "移出子列:{column}",
@@ -2602,13 +2603,7 @@ function confirmChanges() {
2602
2603
  "no-selected-children": "この列にはまだ子列がありません。",
2603
2604
  "no-available-columns": "追加できる列がありません。",
2604
2605
  "add-column": "列を追加",
2605
- "drag-left-column": "{column} の左側グループ順をドラッグで変更",
2606
- "drag-center-column": "{column} の中央グループ順をドラッグで変更",
2607
- "drag-right-column": "{column} の右側グループ順をドラッグで変更",
2608
- "pin-left-column": "{column} を左側グループに固定",
2609
- "pin-right-column": "{column} を右側グループに固定",
2610
- "unpin-left-column": "{column} を左側グループから中央グループに戻す",
2611
- "unpin-right-column": "{column} を右側グループから中央グループに戻す",
2606
+ "drag-initial-state-column": "{column} の列グループと順序をドラッグで変更",
2612
2607
  "drag-child-column": "{column} の子列順をドラッグで変更",
2613
2608
  "delete-column": "{column} を削除",
2614
2609
  "remove-child-column": "{column} を子列から外す",
@@ -2701,13 +2696,7 @@ function confirmChanges() {
2701
2696
  "no-selected-children": "This column has no child columns yet.",
2702
2697
  "no-available-columns": "No columns can be added here.",
2703
2698
  "add-column": "Add column",
2704
- "drag-left-column": "Drag to reorder left group column {column}",
2705
- "drag-center-column": "Drag to reorder center group column {column}",
2706
- "drag-right-column": "Drag to reorder right group column {column}",
2707
- "pin-left-column": "Pin {column} to the left group",
2708
- "pin-right-column": "Pin {column} to the right group",
2709
- "unpin-left-column": "Move {column} from the left group to the center group",
2710
- "unpin-right-column": "Move {column} from the right group to the center group",
2699
+ "drag-initial-state-column": "Drag to move and reorder column {column}",
2711
2700
  "drag-child-column": "Drag to reorder child column {column}",
2712
2701
  "delete-column": "Delete {column}",
2713
2702
  "remove-child-column": "Remove child column {column}",
@@ -0,0 +1,40 @@
1
+ import type { Scope } from 'effect';
2
+ import type { Sidebar as SidebarType } from '../composables/useNavigationTabs.js';
3
+ type CommandEffect = import('effect').Effect.Effect<void>;
4
+ type ProfileCommandInputItem = Readonly<{
5
+ id: string | number;
6
+ title: string;
7
+ icon?: string;
8
+ hidden?: boolean;
9
+ disabled?: boolean;
10
+ effect?: CommandEffect;
11
+ keywords?: Array<string>;
12
+ }>;
13
+ type ProfileCommandInputGroup = Readonly<{
14
+ id: string | number;
15
+ title: string;
16
+ icon?: string;
17
+ children: Array<ProfileCommandInputItem>;
18
+ }>;
19
+ type __VLS_Props = {
20
+ dsl?: import('effect').Effect.Effect<Record<string, unknown>, never, Scope.Scope>;
21
+ sidebar?: SidebarType;
22
+ commands?: Array<ProfileCommandInputItem | ProfileCommandInputGroup>;
23
+ };
24
+ declare var __VLS_9: {}, __VLS_12: {}, __VLS_14: {};
25
+ type __VLS_Slots = {} & {
26
+ menu?: (props: typeof __VLS_9) => any;
27
+ } & {
28
+ profile?: (props: typeof __VLS_12) => any;
29
+ } & {
30
+ default?: (props: typeof __VLS_14) => any;
31
+ };
32
+ declare const __VLS_base: 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>;
33
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
34
+ declare const _default: typeof __VLS_export;
35
+ export default _default;
36
+ type __VLS_WithSlots<T, S> = T & {
37
+ new (): {
38
+ $slots: S;
39
+ };
40
+ };
@@ -0,0 +1,19 @@
1
+ <script setup>
2
+ defineProps({
3
+ dsl: { type: null, required: false },
4
+ sidebar: { type: Array, required: false },
5
+ commands: { type: Array, required: false }
6
+ });
7
+ </script>
8
+
9
+ <template>
10
+ <ShwfedApp v-bind="$props">
11
+ <template #menu>
12
+ <slot name="menu" />
13
+ </template>
14
+ <template #profile>
15
+ <slot name="profile" />
16
+ </template>
17
+ <slot />
18
+ </ShwfedApp>
19
+ </template>
@@ -0,0 +1,40 @@
1
+ import type { Scope } from 'effect';
2
+ import type { Sidebar as SidebarType } from '../composables/useNavigationTabs.js';
3
+ type CommandEffect = import('effect').Effect.Effect<void>;
4
+ type ProfileCommandInputItem = Readonly<{
5
+ id: string | number;
6
+ title: string;
7
+ icon?: string;
8
+ hidden?: boolean;
9
+ disabled?: boolean;
10
+ effect?: CommandEffect;
11
+ keywords?: Array<string>;
12
+ }>;
13
+ type ProfileCommandInputGroup = Readonly<{
14
+ id: string | number;
15
+ title: string;
16
+ icon?: string;
17
+ children: Array<ProfileCommandInputItem>;
18
+ }>;
19
+ type __VLS_Props = {
20
+ dsl?: import('effect').Effect.Effect<Record<string, unknown>, never, Scope.Scope>;
21
+ sidebar?: SidebarType;
22
+ commands?: Array<ProfileCommandInputItem | ProfileCommandInputGroup>;
23
+ };
24
+ declare var __VLS_9: {}, __VLS_12: {}, __VLS_14: {};
25
+ type __VLS_Slots = {} & {
26
+ menu?: (props: typeof __VLS_9) => any;
27
+ } & {
28
+ profile?: (props: typeof __VLS_12) => any;
29
+ } & {
30
+ default?: (props: typeof __VLS_14) => any;
31
+ };
32
+ declare const __VLS_base: 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>;
33
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
34
+ declare const _default: typeof __VLS_export;
35
+ export default _default;
36
+ type __VLS_WithSlots<T, S> = T & {
37
+ new (): {
38
+ $slots: S;
39
+ };
40
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shwfed/nuxt",
3
- "version": "0.7.11",
3
+ "version": "0.8.0",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "type": "module",