@hywax/cms-console 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/.nuxt/cms-console/button-copy-text.ts +19 -0
  2. package/.nuxt/cms-console/button-delete-confirm.ts +5 -0
  3. package/.nuxt/cms-console/editor/index.ts +0 -0
  4. package/.nuxt/cms-console/form-panel-aside-section.ts +9 -0
  5. package/.nuxt/cms-console/form-panel-section.ts +8 -0
  6. package/.nuxt/cms-console/form-panel.ts +15 -0
  7. package/.nuxt/cms-console/index.ts +11 -0
  8. package/.nuxt/cms-console/input-seo.ts +5 -0
  9. package/.nuxt/cms-console/input-slug.ts +5 -0
  10. package/.nuxt/cms-console/input-uplora-image.ts +27 -0
  11. package/.nuxt/cms-console/modal-confirm.ts +5 -0
  12. package/.nuxt/cms-console/table-panel.ts +8 -0
  13. package/.nuxt/cms-console/table-search-input.ts +6 -0
  14. package/.nuxt/cms-console.css +31 -0
  15. package/dist/module.d.mts +11 -0
  16. package/dist/module.json +9 -0
  17. package/dist/module.mjs +387 -0
  18. package/dist/runtime/components/AutocompleteSelect.d.vue.ts +56 -0
  19. package/dist/runtime/components/AutocompleteSelect.vue +225 -0
  20. package/dist/runtime/components/AutocompleteSelect.vue.d.ts +56 -0
  21. package/dist/runtime/components/ButtonCopyText.d.vue.ts +28 -0
  22. package/dist/runtime/components/ButtonCopyText.vue +70 -0
  23. package/dist/runtime/components/ButtonCopyText.vue.d.ts +28 -0
  24. package/dist/runtime/components/ButtonDeleteConfirm.d.vue.ts +38 -0
  25. package/dist/runtime/components/ButtonDeleteConfirm.vue +62 -0
  26. package/dist/runtime/components/ButtonDeleteConfirm.vue.d.ts +38 -0
  27. package/dist/runtime/components/DatePicker.d.vue.ts +43 -0
  28. package/dist/runtime/components/DatePicker.vue +232 -0
  29. package/dist/runtime/components/DatePicker.vue.d.ts +43 -0
  30. package/dist/runtime/components/EditorFull.d.vue.ts +13 -0
  31. package/dist/runtime/components/EditorFull.vue +139 -0
  32. package/dist/runtime/components/EditorFull.vue.d.ts +13 -0
  33. package/dist/runtime/components/EditorLinkPopover.d.vue.ts +8 -0
  34. package/dist/runtime/components/EditorLinkPopover.vue +137 -0
  35. package/dist/runtime/components/EditorLinkPopover.vue.d.ts +8 -0
  36. package/dist/runtime/components/FormPanel.d.vue.ts +47 -0
  37. package/dist/runtime/components/FormPanel.vue +73 -0
  38. package/dist/runtime/components/FormPanel.vue.d.ts +47 -0
  39. package/dist/runtime/components/FormPanelAsideSection.d.vue.ts +24 -0
  40. package/dist/runtime/components/FormPanelAsideSection.vue +41 -0
  41. package/dist/runtime/components/FormPanelAsideSection.vue.d.ts +24 -0
  42. package/dist/runtime/components/FormPanelSection.d.vue.ts +21 -0
  43. package/dist/runtime/components/FormPanelSection.vue +31 -0
  44. package/dist/runtime/components/FormPanelSection.vue.d.ts +21 -0
  45. package/dist/runtime/components/InputSeo.d.vue.ts +21 -0
  46. package/dist/runtime/components/InputSeo.vue +73 -0
  47. package/dist/runtime/components/InputSeo.vue.d.ts +21 -0
  48. package/dist/runtime/components/InputSlug.d.vue.ts +30 -0
  49. package/dist/runtime/components/InputSlug.vue +70 -0
  50. package/dist/runtime/components/InputSlug.vue.d.ts +30 -0
  51. package/dist/runtime/components/InputUploraImage.d.vue.ts +39 -0
  52. package/dist/runtime/components/InputUploraImage.vue +163 -0
  53. package/dist/runtime/components/InputUploraImage.vue.d.ts +39 -0
  54. package/dist/runtime/components/Layout.d.vue.ts +30 -0
  55. package/dist/runtime/components/Layout.vue +82 -0
  56. package/dist/runtime/components/Layout.vue.d.ts +30 -0
  57. package/dist/runtime/components/ModalConfirm.d.vue.ts +33 -0
  58. package/dist/runtime/components/ModalConfirm.vue +97 -0
  59. package/dist/runtime/components/ModalConfirm.vue.d.ts +33 -0
  60. package/dist/runtime/components/TableColumnSorting.d.vue.ts +17 -0
  61. package/dist/runtime/components/TableColumnSorting.vue +81 -0
  62. package/dist/runtime/components/TableColumnSorting.vue.d.ts +17 -0
  63. package/dist/runtime/components/TableColumnVisibility.d.vue.ts +24 -0
  64. package/dist/runtime/components/TableColumnVisibility.vue +110 -0
  65. package/dist/runtime/components/TableColumnVisibility.vue.d.ts +24 -0
  66. package/dist/runtime/components/TableFilters.d.vue.ts +90 -0
  67. package/dist/runtime/components/TableFilters.vue +199 -0
  68. package/dist/runtime/components/TableFilters.vue.d.ts +90 -0
  69. package/dist/runtime/components/TablePanel.d.vue.ts +95 -0
  70. package/dist/runtime/components/TablePanel.vue +297 -0
  71. package/dist/runtime/components/TablePanel.vue.d.ts +95 -0
  72. package/dist/runtime/components/TableSearchInput.d.vue.ts +33 -0
  73. package/dist/runtime/components/TableSearchInput.vue +97 -0
  74. package/dist/runtime/components/TableSearchInput.vue.d.ts +33 -0
  75. package/dist/runtime/composables/useAdmin.d.ts +6 -0
  76. package/dist/runtime/composables/useAdmin.js +14 -0
  77. package/dist/runtime/composables/useEditorDragHandle.d.ts +17 -0
  78. package/dist/runtime/composables/useEditorDragHandle.js +95 -0
  79. package/dist/runtime/composables/useEditorSuggestions.d.ts +74 -0
  80. package/dist/runtime/composables/useEditorSuggestions.js +25 -0
  81. package/dist/runtime/composables/useEditorToolbar.d.ts +121 -0
  82. package/dist/runtime/composables/useEditorToolbar.js +87 -0
  83. package/dist/runtime/composables/useQueryState.d.ts +28 -0
  84. package/dist/runtime/composables/useQueryState.js +105 -0
  85. package/dist/runtime/composables/useRouteQuery.d.ts +37 -0
  86. package/dist/runtime/composables/useRouteQuery.js +81 -0
  87. package/dist/runtime/composables/useSeoStats.d.ts +12 -0
  88. package/dist/runtime/composables/useSeoStats.js +44 -0
  89. package/dist/runtime/composables/useTable.d.ts +25 -0
  90. package/dist/runtime/composables/useTable.js +84 -0
  91. package/dist/runtime/composables/useTableColumns.d.ts +28 -0
  92. package/dist/runtime/composables/useTableColumns.js +54 -0
  93. package/dist/runtime/editor/uplora-image/EditorUploraImage.d.ts +18 -0
  94. package/dist/runtime/editor/uplora-image/EditorUploraImage.js +42 -0
  95. package/dist/runtime/editor/uplora-image/EditorUploraImageNode.d.vue.ts +4 -0
  96. package/dist/runtime/editor/uplora-image/EditorUploraImageNode.vue +23 -0
  97. package/dist/runtime/editor/uplora-image/EditorUploraImageNode.vue.d.ts +4 -0
  98. package/dist/runtime/index.css +1 -0
  99. package/dist/runtime/server/tsconfig.json +3 -0
  100. package/dist/runtime/tv.d.ts +1 -0
  101. package/dist/runtime/tv.js +4 -0
  102. package/dist/runtime/types/app.config.d.ts +6 -0
  103. package/dist/runtime/types/date.d.ts +5 -0
  104. package/dist/runtime/types/date.js +0 -0
  105. package/dist/runtime/types/dictionaries.d.ts +1 -0
  106. package/dist/runtime/types/dictionaries.js +0 -0
  107. package/dist/runtime/types/index.d.ts +30 -0
  108. package/dist/runtime/types/index.js +30 -0
  109. package/dist/runtime/types/seo.d.ts +4 -0
  110. package/dist/runtime/types/seo.js +0 -0
  111. package/dist/runtime/utils/auth.d.ts +2 -0
  112. package/dist/runtime/utils/auth.js +5 -0
  113. package/dist/runtime/utils/date.d.ts +5 -0
  114. package/dist/runtime/utils/date.js +15 -0
  115. package/dist/runtime/utils/formatters.d.ts +5 -0
  116. package/dist/runtime/utils/formatters.js +24 -0
  117. package/dist/runtime/utils/index.d.ts +4 -0
  118. package/dist/runtime/utils/index.js +4 -0
  119. package/dist/runtime/utils/slugify.d.ts +1 -0
  120. package/dist/runtime/utils/slugify.js +11 -0
  121. package/dist/types.d.mts +11 -0
  122. package/package.json +89 -0
@@ -0,0 +1,73 @@
1
+ <template>
2
+ <UDashboardPanel
3
+ :ui="{
4
+ body: 'flex-row p-0 sm:p-0 gap-0 sm:gap-0'
5
+ }"
6
+ >
7
+ <template #header>
8
+ <UDashboardNavbar :title="title" :ui="{ right: 'gap-2' }">
9
+ <template v-if="toBack" #leading>
10
+ <UButton :to="toBack" variant="link" :icon="appConfig.ui.icons.arrowLeft" />
11
+ </template>
12
+ <template #right>
13
+ <slot name="actions" />
14
+
15
+ <UButton
16
+ type="submit"
17
+ label="Сохранить"
18
+ :form="formId"
19
+ :loading="loading"
20
+ loading-auto
21
+ />
22
+ </template>
23
+ </UDashboardNavbar>
24
+ </template>
25
+ <template #body>
26
+ <UForm
27
+ :id="formId"
28
+ :state="state"
29
+ :schema="schema"
30
+ :class="ui.form({ class: props.ui?.form })"
31
+ @submit="submitHandler"
32
+ >
33
+ <div :class="ui.body({ class: props.ui?.body })">
34
+ <slot />
35
+ </div>
36
+ <div v-if="$slots.sidebar" :class="ui.sidebar({ class: props.ui?.sidebar })">
37
+ <slot name="sidebar" />
38
+ </div>
39
+ </UForm>
40
+ </template>
41
+ </UDashboardPanel>
42
+ </template>
43
+
44
+ <script>
45
+ import theme from "#build/cms-console/form-panel";
46
+ import { useAppConfig } from "#imports";
47
+ import { computed, useId } from "vue";
48
+ import { tv } from "../tv";
49
+ </script>
50
+
51
+ <script setup>
52
+ const props = defineProps({
53
+ title: { type: String, required: false },
54
+ toBack: { type: null, required: false },
55
+ formId: { type: String, required: false },
56
+ schema: { type: null, required: true },
57
+ state: { type: Object, required: true },
58
+ loading: { type: Boolean, required: false },
59
+ handler: { type: Function, required: true },
60
+ asideDivide: { type: Boolean, required: false },
61
+ showReset: { type: Boolean, required: false },
62
+ class: { type: null, required: false },
63
+ ui: { type: null, required: false }
64
+ });
65
+ defineEmits(["update:state"]);
66
+ defineSlots();
67
+ const appConfig = useAppConfig();
68
+ const formId = computed(() => props.formId ?? `form-${useId()}`);
69
+ async function submitHandler(event) {
70
+ await props.handler?.(event);
71
+ }
72
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.formPanel || {} })());
73
+ </script>
@@ -0,0 +1,47 @@
1
+ import type { ComponentConfig } from '@hywax/cms-runtime';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import type { FormData, FormSchema, FormSubmitEvent } from '@nuxt/ui';
4
+ import type { RouteLocationRaw } from 'vue-router';
5
+ import theme from '#build/cms-console/form-panel';
6
+ type FormPanel = ComponentConfig<typeof theme, AppConfig, 'formPanel'>;
7
+ export interface FormPanelProps<S extends FormSchema, T extends FormData<S> = FormData<S>> {
8
+ title?: string;
9
+ toBack?: RouteLocationRaw;
10
+ formId?: string;
11
+ schema: S;
12
+ state: Partial<T>;
13
+ loading?: boolean;
14
+ handler: (event: FormSubmitEvent<T>) => Promise<void>;
15
+ asideDivide?: boolean;
16
+ showReset?: boolean;
17
+ class?: any;
18
+ ui?: FormPanel['slots'];
19
+ }
20
+ export interface FormPanelEmits<S extends FormSchema, T extends FormData<S> = FormData<S>> {
21
+ 'update:state': [value: T];
22
+ }
23
+ export interface FormPanelSlots {
24
+ default?: () => any;
25
+ sidebar?: () => any;
26
+ actions?: () => any;
27
+ }
28
+ declare const _default: typeof __VLS_export;
29
+ export default _default;
30
+ declare const __VLS_export: <S extends FormSchema, T extends FormData<S> = FormData<S>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
31
+ props: import("vue").PublicProps & __VLS_PrettifyLocal<FormPanelProps<S, T> & {
32
+ "onUpdate:state"?: ((value: T) => any) | undefined;
33
+ }> & (typeof globalThis extends {
34
+ __VLS_PROPS_FALLBACK: infer P;
35
+ } ? P : {});
36
+ expose: (exposed: {}) => void;
37
+ attrs: any;
38
+ slots: FormPanelSlots;
39
+ emit: (evt: "update:state", value: T) => void;
40
+ }>) => import("vue").VNode & {
41
+ __ctx?: Awaited<typeof __VLS_setup>;
42
+ };
43
+ type __VLS_PrettifyLocal<T> = (T extends any ? {
44
+ [K in keyof T]: T[K];
45
+ } : {
46
+ [K in keyof T as K]: T[K];
47
+ }) & {};
@@ -0,0 +1,24 @@
1
+ import type { ComponentConfig } from '@hywax/cms-runtime';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import theme from '#build/cms-console/form-panel-aside-section';
4
+ type FormPanelAsideSection = ComponentConfig<typeof theme, AppConfig, 'formPanelAsideSection'>;
5
+ export interface FormPanelAsideSectionProps {
6
+ title?: string;
7
+ icon?: string;
8
+ divide?: boolean;
9
+ class?: any;
10
+ ui?: FormPanelAsideSection['slots'];
11
+ }
12
+ export interface FormPanelAsideSectionSlots {
13
+ default?: () => any;
14
+ icon?: () => any;
15
+ title?: () => any;
16
+ }
17
+ declare const _default: typeof __VLS_export;
18
+ export default _default;
19
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormPanelAsideSectionProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormPanelAsideSectionProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, FormPanelAsideSectionSlots>;
20
+ type __VLS_WithSlots<T, S> = T & {
21
+ new (): {
22
+ $slots: S;
23
+ };
24
+ };
@@ -0,0 +1,41 @@
1
+ <template>
2
+ <UCollapsible :class="ui.root({ class: [props.ui?.root, props.class] })" default-open>
3
+ <div v-if="title || $slots.title || icon || $slots.icon" :class="ui.header({ class: props.ui?.header })">
4
+ <div v-if="icon || $slots.icon" :class="ui.icon({ class: props.ui?.icon })">
5
+ <slot name="icon">
6
+ <UIcon v-if="icon" :name="icon" />
7
+ </slot>
8
+ </div>
9
+ <div v-if="title || $slots.title" :class="ui.title({ class: props.ui?.title })">
10
+ <slot name="title">
11
+ {{ title }}
12
+ </slot>
13
+ </div>
14
+ </div>
15
+
16
+ <template #content>
17
+ <div :class="ui.body({ class: props.ui?.body })">
18
+ <slot />
19
+ </div>
20
+ </template>
21
+ </UCollapsible>
22
+ </template>
23
+
24
+ <script>
25
+ import theme from "#build/cms-console/form-panel-aside-section";
26
+ import { computed, useAppConfig } from "#imports";
27
+ import { tv } from "../tv";
28
+ </script>
29
+
30
+ <script setup>
31
+ const props = defineProps({
32
+ title: { type: String, required: false },
33
+ icon: { type: String, required: false },
34
+ divide: { type: Boolean, required: false },
35
+ class: { type: null, required: false },
36
+ ui: { type: null, required: false }
37
+ });
38
+ defineSlots();
39
+ const appConfig = useAppConfig();
40
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.formPanelAsideSection || {} })());
41
+ </script>
@@ -0,0 +1,24 @@
1
+ import type { ComponentConfig } from '@hywax/cms-runtime';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import theme from '#build/cms-console/form-panel-aside-section';
4
+ type FormPanelAsideSection = ComponentConfig<typeof theme, AppConfig, 'formPanelAsideSection'>;
5
+ export interface FormPanelAsideSectionProps {
6
+ title?: string;
7
+ icon?: string;
8
+ divide?: boolean;
9
+ class?: any;
10
+ ui?: FormPanelAsideSection['slots'];
11
+ }
12
+ export interface FormPanelAsideSectionSlots {
13
+ default?: () => any;
14
+ icon?: () => any;
15
+ title?: () => any;
16
+ }
17
+ declare const _default: typeof __VLS_export;
18
+ export default _default;
19
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormPanelAsideSectionProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormPanelAsideSectionProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, FormPanelAsideSectionSlots>;
20
+ type __VLS_WithSlots<T, S> = T & {
21
+ new (): {
22
+ $slots: S;
23
+ };
24
+ };
@@ -0,0 +1,21 @@
1
+ import type { ComponentConfig } from '@hywax/cms-runtime';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import theme from '#build/cms-console/form-panel-section';
4
+ type FormPanelSection = ComponentConfig<typeof theme, AppConfig, 'formPanelSection'>;
5
+ export interface FormPanelSectionProps {
6
+ title?: string;
7
+ description?: string;
8
+ class?: any;
9
+ ui?: FormPanelSection['slots'];
10
+ }
11
+ export interface FormPanelSectionSlots {
12
+ default?: () => any;
13
+ }
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
16
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormPanelSectionProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormPanelSectionProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, FormPanelSectionSlots>;
17
+ type __VLS_WithSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <div :class="ui.root({ class: [props.ui?.root, props.class] })">
3
+ <div v-if="title" :class="ui.title({ class: props.ui?.title })">
4
+ {{ title }}
5
+ </div>
6
+ <div v-if="description" :class="ui.description({ class: props.ui?.description })">
7
+ {{ description }}
8
+ </div>
9
+ <div :class="ui.body({ class: props.ui?.body })">
10
+ <slot />
11
+ </div>
12
+ </div>
13
+ </template>
14
+
15
+ <script>
16
+ import theme from "#build/cms-console/form-panel-section";
17
+ import { computed, useAppConfig } from "#imports";
18
+ import { tv } from "../tv";
19
+ </script>
20
+
21
+ <script setup>
22
+ const props = defineProps({
23
+ title: { type: String, required: false },
24
+ description: { type: String, required: false },
25
+ class: { type: null, required: false },
26
+ ui: { type: null, required: false }
27
+ });
28
+ defineSlots();
29
+ const appConfig = useAppConfig();
30
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.formPanelSection || {} })());
31
+ </script>
@@ -0,0 +1,21 @@
1
+ import type { ComponentConfig } from '@hywax/cms-runtime';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import theme from '#build/cms-console/form-panel-section';
4
+ type FormPanelSection = ComponentConfig<typeof theme, AppConfig, 'formPanelSection'>;
5
+ export interface FormPanelSectionProps {
6
+ title?: string;
7
+ description?: string;
8
+ class?: any;
9
+ ui?: FormPanelSection['slots'];
10
+ }
11
+ export interface FormPanelSectionSlots {
12
+ default?: () => any;
13
+ }
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
16
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FormPanelSectionProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormPanelSectionProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, FormPanelSectionSlots>;
17
+ type __VLS_WithSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
@@ -0,0 +1,21 @@
1
+ import type { ComponentConfig } from '@hywax/cms-runtime';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import type { SEO } from '../types';
4
+ import theme from '#build/cms-console/input-seo';
5
+ type InputSeo = ComponentConfig<typeof theme, AppConfig, 'inputSeo'>;
6
+ export interface InputSeoProps {
7
+ as?: any;
8
+ class?: any;
9
+ ui?: InputSeo['slots'];
10
+ }
11
+ declare const _default: typeof __VLS_export;
12
+ export default _default;
13
+ declare const __VLS_export: import("vue").DefineComponent<InputSeoProps & {
14
+ modelValue?: SEO;
15
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
16
+ "update:modelValue": (value: SEO) => any;
17
+ }, string, import("vue").PublicProps, Readonly<InputSeoProps & {
18
+ modelValue?: SEO;
19
+ }> & Readonly<{
20
+ "onUpdate:modelValue"?: ((value: SEO) => any) | undefined;
21
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -0,0 +1,73 @@
1
+ <template>
2
+ <Primitive :as="as" :class="ui.root({ class: [props.ui?.root, props.class] })">
3
+ <UFormField
4
+ name="seo.title"
5
+ label="Заголовок"
6
+ :hint="`${model.title.length}/60`"
7
+ :ui="{ hint: 'text-xs' }"
8
+ >
9
+ <UInput v-model="model.title" placeholder="Введите заголовок..." class="w-full" />
10
+
11
+ <template #help>
12
+ <p class="text-xs mb-2">
13
+ Рекомендуемая длина: 45-60 символов
14
+ </p>
15
+ <UProgress
16
+ :model-value="title.progress"
17
+ :color="title.color"
18
+ size="sm"
19
+ />
20
+ </template>
21
+ </UFormField>
22
+
23
+ <UFormField
24
+ name="seo.description"
25
+ label="Описание"
26
+ :hint="`${model.description.length}/160`"
27
+ :ui="{ hint: 'text-xs' }"
28
+ >
29
+ <UTextarea
30
+ v-model="model.description"
31
+ placeholder="Введите описание..."
32
+ class="w-full"
33
+ autoresize
34
+ />
35
+
36
+ <template #help>
37
+ <p class="text-xs mb-2">
38
+ Рекомендуемая длина: 130-160 символов
39
+ </p>
40
+ <UProgress
41
+ :model-value="description.progress"
42
+ :color="description.color"
43
+ size="sm"
44
+ />
45
+ </template>
46
+ </UFormField>
47
+ </Primitive>
48
+ </template>
49
+
50
+ <script>
51
+ import theme from "#build/cms-console/input-seo";
52
+ import { computed, useAppConfig } from "#imports";
53
+ import { Primitive } from "reka-ui";
54
+ import { useSeoStats } from "../composables/useSeoStats";
55
+ import { tv } from "../tv";
56
+ </script>
57
+
58
+ <script setup>
59
+ const props = defineProps({
60
+ as: { type: null, required: false },
61
+ class: { type: null, required: false },
62
+ ui: { type: null, required: false }
63
+ });
64
+ const model = defineModel({ type: Object, ...{
65
+ default: () => ({
66
+ title: "",
67
+ description: ""
68
+ })
69
+ } });
70
+ const appConfig = useAppConfig();
71
+ const { title, description } = useSeoStats(model);
72
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.inputSeo || {} })());
73
+ </script>
@@ -0,0 +1,21 @@
1
+ import type { ComponentConfig } from '@hywax/cms-runtime';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import type { SEO } from '../types';
4
+ import theme from '#build/cms-console/input-seo';
5
+ type InputSeo = ComponentConfig<typeof theme, AppConfig, 'inputSeo'>;
6
+ export interface InputSeoProps {
7
+ as?: any;
8
+ class?: any;
9
+ ui?: InputSeo['slots'];
10
+ }
11
+ declare const _default: typeof __VLS_export;
12
+ export default _default;
13
+ declare const __VLS_export: import("vue").DefineComponent<InputSeoProps & {
14
+ modelValue?: SEO;
15
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
16
+ "update:modelValue": (value: SEO) => any;
17
+ }, string, import("vue").PublicProps, Readonly<InputSeoProps & {
18
+ modelValue?: SEO;
19
+ }> & Readonly<{
20
+ "onUpdate:modelValue"?: ((value: SEO) => any) | undefined;
21
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -0,0 +1,30 @@
1
+ import type { ComponentConfig } from '@hywax/cms-runtime';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import type { InputProps } from '@nuxt/ui';
4
+ import theme from '#build/cms-console/input-slug';
5
+ type InputSlug = ComponentConfig<typeof theme, AppConfig, 'inputSlug'>;
6
+ export interface InputSlugProps {
7
+ regenerate?: boolean;
8
+ label?: string;
9
+ titleKey?: string;
10
+ slugKey?: string;
11
+ inputProps?: Omit<InputProps, 'modelModifiers'>;
12
+ as?: any;
13
+ class?: any;
14
+ ui?: InputSlug['slots'];
15
+ }
16
+ declare const _default: typeof __VLS_export;
17
+ export default _default;
18
+ declare const __VLS_export: import("vue").DefineComponent<InputSlugProps & {
19
+ title?: string;
20
+ slug?: string;
21
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
22
+ "update:title": (value: string | undefined) => any;
23
+ "update:slug": (value: string | undefined) => any;
24
+ }, string, import("vue").PublicProps, Readonly<InputSlugProps & {
25
+ title?: string;
26
+ slug?: string;
27
+ }> & Readonly<{
28
+ "onUpdate:title"?: ((value: string | undefined) => any) | undefined;
29
+ "onUpdate:slug"?: ((value: string | undefined) => any) | undefined;
30
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -0,0 +1,70 @@
1
+ <template>
2
+ <Primitive :as="as" :class="ui.root({ class: [props.ui?.root, props.class] })">
3
+ <UFormField
4
+ :label="label"
5
+ :name="titleKey"
6
+ >
7
+ <UInput
8
+ v-model="title"
9
+ v-bind="inputProps"
10
+ class="w-full"
11
+ />
12
+ </UFormField>
13
+ <UFormField :name="slugKey" class="-mt-3" eager-validation>
14
+ <UInput
15
+ v-model="slug"
16
+ class="w-full"
17
+ size="xs"
18
+ variant="none"
19
+ :placeholder="isRegenerate ? '\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A' : '\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043B\u0430\u0433'"
20
+ :disabled="isRegenerate"
21
+ :ui="{
22
+ base: 'text-muted'
23
+ }"
24
+ >
25
+ <template #leading>
26
+ <UButton
27
+ size="xs"
28
+ variant="link"
29
+ :icon="appConfig.ui.icons.link"
30
+ class="p-0"
31
+ :color="isRegenerate ? 'success' : 'neutral'"
32
+ @click="isRegenerate = !isRegenerate"
33
+ />
34
+ </template>
35
+ </UInput>
36
+ </UFormField>
37
+ </Primitive>
38
+ </template>
39
+
40
+ <script>
41
+ import theme from "#build/cms-console/input-slug";
42
+ import { computed, ref, useAppConfig, watch } from "#imports";
43
+ import { Primitive } from "reka-ui";
44
+ import { tv } from "../tv";
45
+ import { slugify } from "../utils/slugify";
46
+ </script>
47
+
48
+ <script setup>
49
+ const props = defineProps({
50
+ regenerate: { type: Boolean, required: false },
51
+ label: { type: String, required: false },
52
+ titleKey: { type: String, required: false },
53
+ slugKey: { type: String, required: false },
54
+ inputProps: { type: Object, required: false },
55
+ as: { type: null, required: false },
56
+ class: { type: null, required: false },
57
+ ui: { type: null, required: false }
58
+ });
59
+ const title = defineModel("title", { type: String });
60
+ const slug = defineModel("slug", { type: String });
61
+ const appConfig = useAppConfig();
62
+ const isRegenerate = ref(props.regenerate);
63
+ watch(title, () => {
64
+ if (!isRegenerate.value) {
65
+ return;
66
+ }
67
+ slug.value = slugify(title.value);
68
+ });
69
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.inputSlug || {} })());
70
+ </script>
@@ -0,0 +1,30 @@
1
+ import type { ComponentConfig } from '@hywax/cms-runtime';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import type { InputProps } from '@nuxt/ui';
4
+ import theme from '#build/cms-console/input-slug';
5
+ type InputSlug = ComponentConfig<typeof theme, AppConfig, 'inputSlug'>;
6
+ export interface InputSlugProps {
7
+ regenerate?: boolean;
8
+ label?: string;
9
+ titleKey?: string;
10
+ slugKey?: string;
11
+ inputProps?: Omit<InputProps, 'modelModifiers'>;
12
+ as?: any;
13
+ class?: any;
14
+ ui?: InputSlug['slots'];
15
+ }
16
+ declare const _default: typeof __VLS_export;
17
+ export default _default;
18
+ declare const __VLS_export: import("vue").DefineComponent<InputSlugProps & {
19
+ title?: string;
20
+ slug?: string;
21
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
22
+ "update:title": (value: string | undefined) => any;
23
+ "update:slug": (value: string | undefined) => any;
24
+ }, string, import("vue").PublicProps, Readonly<InputSlugProps & {
25
+ title?: string;
26
+ slug?: string;
27
+ }> & Readonly<{
28
+ "onUpdate:title"?: ((value: string | undefined) => any) | undefined;
29
+ "onUpdate:slug"?: ((value: string | undefined) => any) | undefined;
30
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -0,0 +1,39 @@
1
+ import type { ComponentConfig } from '@hywax/cms-runtime';
2
+ import type { AppConfig } from '@nuxt/schema';
3
+ import theme from '#build/cms-console/input-uplora-image';
4
+ type InputUploraImage = ComponentConfig<typeof theme, AppConfig, 'inputUploraImage'>;
5
+ export interface InputUploraImageProps {
6
+ showExtensions?: boolean;
7
+ id?: string;
8
+ name?: string;
9
+ disabled?: boolean;
10
+ as?: any;
11
+ class?: any;
12
+ ui?: InputUploraImage['slots'];
13
+ }
14
+ export interface InputUploraImageEmits {
15
+ upload: [InputUploraImageModelValue];
16
+ delete: [];
17
+ }
18
+ export interface InputUploraImageModelValue {
19
+ image: string;
20
+ alt: string;
21
+ lqip?: string;
22
+ }
23
+ declare const _default: typeof __VLS_export;
24
+ export default _default;
25
+ declare const __VLS_export: import("vue").DefineComponent<InputUploraImageProps & {
26
+ modelValue?: InputUploraImageModelValue;
27
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
28
+ delete: () => any;
29
+ "update:modelValue": (value: InputUploraImageModelValue) => any;
30
+ upload: (args_0: InputUploraImageModelValue) => any;
31
+ }, string, import("vue").PublicProps, Readonly<InputUploraImageProps & {
32
+ modelValue?: InputUploraImageModelValue;
33
+ }> & Readonly<{
34
+ onDelete?: (() => any) | undefined;
35
+ "onUpdate:modelValue"?: ((value: InputUploraImageModelValue) => any) | undefined;
36
+ onUpload?: ((args_0: InputUploraImageModelValue) => any) | undefined;
37
+ }>, {
38
+ showExtensions: boolean;
39
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;